Commit 47705eff7a822105dfddaa03aadfe95f05849892

Authored by Stephen Warren
Committed by Tom Rini
1 parent 3207d8fc9c

ARM: rpi: support model A+

Add a board rev entry for the new model A+, and augment the board
rev error handling code to be a bit more verbose.

Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>

Showing 2 changed files with 13 additions and 2 deletions Inline Diff

arch/arm/include/asm/arch-bcm2835/mbox.h
1 /* 1 /*
2 * (C) Copyright 2012 Stephen Warren 2 * (C) Copyright 2012 Stephen Warren
3 * 3 *
4 * SPDX-License-Identifier: GPL-2.0+ 4 * SPDX-License-Identifier: GPL-2.0+
5 */ 5 */
6 6
7 #ifndef _BCM2835_MBOX_H 7 #ifndef _BCM2835_MBOX_H
8 #define _BCM2835_MBOX_H 8 #define _BCM2835_MBOX_H
9 9
10 #include <linux/compiler.h> 10 #include <linux/compiler.h>
11 11
12 /* 12 /*
13 * The BCM2835 SoC contains (at least) two CPUs; the VideoCore (a/k/a "GPU") 13 * The BCM2835 SoC contains (at least) two CPUs; the VideoCore (a/k/a "GPU")
14 * and the ARM CPU. The ARM CPU is often thought of as the main CPU. 14 * and the ARM CPU. The ARM CPU is often thought of as the main CPU.
15 * However, the VideoCore actually controls the initial SoC boot, and hides 15 * However, the VideoCore actually controls the initial SoC boot, and hides
16 * much of the hardware behind a protocol. This protocol is transported 16 * much of the hardware behind a protocol. This protocol is transported
17 * using the SoC's mailbox hardware module. 17 * using the SoC's mailbox hardware module.
18 * 18 *
19 * The mailbox hardware supports passing 32-bit values back and forth. 19 * The mailbox hardware supports passing 32-bit values back and forth.
20 * Presumably by software convention of the firmware, the bottom 4 bits of the 20 * Presumably by software convention of the firmware, the bottom 4 bits of the
21 * value are used to indicate a logical channel, and the upper 28 bits are the 21 * value are used to indicate a logical channel, and the upper 28 bits are the
22 * actual payload. Various channels exist using these simple raw messages. See 22 * actual payload. Various channels exist using these simple raw messages. See
23 * https://github.com/raspberrypi/firmware/wiki/Mailboxes for a list. As an 23 * https://github.com/raspberrypi/firmware/wiki/Mailboxes for a list. As an
24 * example, the messages on the power management channel are a bitmask of 24 * example, the messages on the power management channel are a bitmask of
25 * devices whose power should be enabled. 25 * devices whose power should be enabled.
26 * 26 *
27 * The property mailbox channel passes messages that contain the (16-byte 27 * The property mailbox channel passes messages that contain the (16-byte
28 * aligned) ARM physical address of a memory buffer. This buffer is passed to 28 * aligned) ARM physical address of a memory buffer. This buffer is passed to
29 * the VC for processing, is modified in-place by the VC, and the address then 29 * the VC for processing, is modified in-place by the VC, and the address then
30 * passed back to the ARM CPU as the response mailbox message to indicate 30 * passed back to the ARM CPU as the response mailbox message to indicate
31 * request completion. The buffers have a generic and extensible format; each 31 * request completion. The buffers have a generic and extensible format; each
32 * buffer contains a standard header, a list of "tags", and a terminating zero 32 * buffer contains a standard header, a list of "tags", and a terminating zero
33 * entry. Each tag contains an ID indicating its type, and length fields for 33 * entry. Each tag contains an ID indicating its type, and length fields for
34 * generic parsing. With some limitations, an arbitrary set of tags may be 34 * generic parsing. With some limitations, an arbitrary set of tags may be
35 * combined together into a single message buffer. This file defines structs 35 * combined together into a single message buffer. This file defines structs
36 * representing the header and many individual tag layouts and IDs. 36 * representing the header and many individual tag layouts and IDs.
37 */ 37 */
38 38
39 /* Raw mailbox HW */ 39 /* Raw mailbox HW */
40 40
41 #define BCM2835_MBOX_PHYSADDR 0x2000b880 41 #define BCM2835_MBOX_PHYSADDR 0x2000b880
42 42
43 struct bcm2835_mbox_regs { 43 struct bcm2835_mbox_regs {
44 u32 read; 44 u32 read;
45 u32 rsvd0[5]; 45 u32 rsvd0[5];
46 u32 status; 46 u32 status;
47 u32 config; 47 u32 config;
48 u32 write; 48 u32 write;
49 }; 49 };
50 50
51 #define BCM2835_MBOX_STATUS_WR_FULL 0x80000000 51 #define BCM2835_MBOX_STATUS_WR_FULL 0x80000000
52 #define BCM2835_MBOX_STATUS_RD_EMPTY 0x40000000 52 #define BCM2835_MBOX_STATUS_RD_EMPTY 0x40000000
53 53
54 /* Lower 4-bits are channel ID */ 54 /* Lower 4-bits are channel ID */
55 #define BCM2835_CHAN_MASK 0xf 55 #define BCM2835_CHAN_MASK 0xf
56 #define BCM2835_MBOX_PACK(chan, data) (((data) & (~BCM2835_CHAN_MASK)) | \ 56 #define BCM2835_MBOX_PACK(chan, data) (((data) & (~BCM2835_CHAN_MASK)) | \
57 (chan & BCM2835_CHAN_MASK)) 57 (chan & BCM2835_CHAN_MASK))
58 #define BCM2835_MBOX_UNPACK_CHAN(val) ((val) & BCM2835_CHAN_MASK) 58 #define BCM2835_MBOX_UNPACK_CHAN(val) ((val) & BCM2835_CHAN_MASK)
59 #define BCM2835_MBOX_UNPACK_DATA(val) ((val) & (~BCM2835_CHAN_MASK)) 59 #define BCM2835_MBOX_UNPACK_DATA(val) ((val) & (~BCM2835_CHAN_MASK))
60 60
61 /* Property mailbox buffer structures */ 61 /* Property mailbox buffer structures */
62 62
63 #define BCM2835_MBOX_PROP_CHAN 8 63 #define BCM2835_MBOX_PROP_CHAN 8
64 64
65 /* All message buffers must start with this header */ 65 /* All message buffers must start with this header */
66 struct bcm2835_mbox_hdr { 66 struct bcm2835_mbox_hdr {
67 u32 buf_size; 67 u32 buf_size;
68 u32 code; 68 u32 code;
69 }; 69 };
70 70
71 #define BCM2835_MBOX_REQ_CODE 0 71 #define BCM2835_MBOX_REQ_CODE 0
72 #define BCM2835_MBOX_RESP_CODE_SUCCESS 0x80000000 72 #define BCM2835_MBOX_RESP_CODE_SUCCESS 0x80000000
73 73
74 #define BCM2835_MBOX_INIT_HDR(_m_) { \ 74 #define BCM2835_MBOX_INIT_HDR(_m_) { \
75 memset((_m_), 0, sizeof(*(_m_))); \ 75 memset((_m_), 0, sizeof(*(_m_))); \
76 (_m_)->hdr.buf_size = sizeof(*(_m_)); \ 76 (_m_)->hdr.buf_size = sizeof(*(_m_)); \
77 (_m_)->hdr.code = 0; \ 77 (_m_)->hdr.code = 0; \
78 (_m_)->end_tag = 0; \ 78 (_m_)->end_tag = 0; \
79 } 79 }
80 80
81 /* 81 /*
82 * A message buffer contains a list of tags. Each tag must also start with 82 * A message buffer contains a list of tags. Each tag must also start with
83 * a standardized header. 83 * a standardized header.
84 */ 84 */
85 struct bcm2835_mbox_tag_hdr { 85 struct bcm2835_mbox_tag_hdr {
86 u32 tag; 86 u32 tag;
87 u32 val_buf_size; 87 u32 val_buf_size;
88 u32 val_len; 88 u32 val_len;
89 }; 89 };
90 90
91 #define BCM2835_MBOX_INIT_TAG(_t_, _id_) { \ 91 #define BCM2835_MBOX_INIT_TAG(_t_, _id_) { \
92 (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \ 92 (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
93 (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \ 93 (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
94 (_t_)->tag_hdr.val_len = sizeof((_t_)->body.req); \ 94 (_t_)->tag_hdr.val_len = sizeof((_t_)->body.req); \
95 } 95 }
96 96
97 #define BCM2835_MBOX_INIT_TAG_NO_REQ(_t_, _id_) { \ 97 #define BCM2835_MBOX_INIT_TAG_NO_REQ(_t_, _id_) { \
98 (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \ 98 (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
99 (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \ 99 (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
100 (_t_)->tag_hdr.val_len = 0; \ 100 (_t_)->tag_hdr.val_len = 0; \
101 } 101 }
102 102
103 /* When responding, the VC sets this bit in val_len to indicate a response */ 103 /* When responding, the VC sets this bit in val_len to indicate a response */
104 #define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE 0x80000000 104 #define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE 0x80000000
105 105
106 /* 106 /*
107 * Below we define the ID and struct for many possible tags. This header only 107 * Below we define the ID and struct for many possible tags. This header only
108 * defines individual tag structs, not entire message structs, since in 108 * defines individual tag structs, not entire message structs, since in
109 * general an arbitrary set of tags may be combined into a single message. 109 * general an arbitrary set of tags may be combined into a single message.
110 * Clients of the mbox API are expected to define their own overall message 110 * Clients of the mbox API are expected to define their own overall message
111 * structures by combining the header, a set of tags, and a terminating 111 * structures by combining the header, a set of tags, and a terminating
112 * entry. For example, 112 * entry. For example,
113 * 113 *
114 * struct msg { 114 * struct msg {
115 * struct bcm2835_mbox_hdr hdr; 115 * struct bcm2835_mbox_hdr hdr;
116 * struct bcm2835_mbox_tag_get_arm_mem get_arm_mem; 116 * struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
117 * ... perhaps other tags here ... 117 * ... perhaps other tags here ...
118 * u32 end_tag; 118 * u32 end_tag;
119 * }; 119 * };
120 */ 120 */
121 121
122 #define BCM2835_MBOX_TAG_GET_BOARD_REV 0x00010002 122 #define BCM2835_MBOX_TAG_GET_BOARD_REV 0x00010002
123 123
124 /* 124 /*
125 * 0x2..0xf from: 125 * 0x2..0xf from:
126 * http://raspberryalphaomega.org.uk/2013/02/06/automatic-raspberry-pi-board-revision-detection-model-a-b1-and-b2/ 126 * http://raspberryalphaomega.org.uk/2013/02/06/automatic-raspberry-pi-board-revision-detection-model-a-b1-and-b2/
127 * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=32733 127 * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=32733
128 * 0x10, 0x11 from swarren's testing 128 * 0x10, 0x11 from swarren's testing
129 */ 129 */
130 #define BCM2835_BOARD_REV_B_I2C0_2 0x2 130 #define BCM2835_BOARD_REV_B_I2C0_2 0x2
131 #define BCM2835_BOARD_REV_B_I2C0_3 0x3 131 #define BCM2835_BOARD_REV_B_I2C0_3 0x3
132 #define BCM2835_BOARD_REV_B_I2C1_4 0x4 132 #define BCM2835_BOARD_REV_B_I2C1_4 0x4
133 #define BCM2835_BOARD_REV_B_I2C1_5 0x5 133 #define BCM2835_BOARD_REV_B_I2C1_5 0x5
134 #define BCM2835_BOARD_REV_B_I2C1_6 0x6 134 #define BCM2835_BOARD_REV_B_I2C1_6 0x6
135 #define BCM2835_BOARD_REV_A_7 0x7 135 #define BCM2835_BOARD_REV_A_7 0x7
136 #define BCM2835_BOARD_REV_A_8 0x8 136 #define BCM2835_BOARD_REV_A_8 0x8
137 #define BCM2835_BOARD_REV_A_9 0x9 137 #define BCM2835_BOARD_REV_A_9 0x9
138 #define BCM2835_BOARD_REV_B_REV2_d 0xd 138 #define BCM2835_BOARD_REV_B_REV2_d 0xd
139 #define BCM2835_BOARD_REV_B_REV2_e 0xe 139 #define BCM2835_BOARD_REV_B_REV2_e 0xe
140 #define BCM2835_BOARD_REV_B_REV2_f 0xf 140 #define BCM2835_BOARD_REV_B_REV2_f 0xf
141 #define BCM2835_BOARD_REV_B_PLUS 0x10 141 #define BCM2835_BOARD_REV_B_PLUS 0x10
142 #define BCM2835_BOARD_REV_CM 0x11 142 #define BCM2835_BOARD_REV_CM 0x11
143 #define BCM2835_BOARD_REV_A_PLUS 0x12
143 144
144 struct bcm2835_mbox_tag_get_board_rev { 145 struct bcm2835_mbox_tag_get_board_rev {
145 struct bcm2835_mbox_tag_hdr tag_hdr; 146 struct bcm2835_mbox_tag_hdr tag_hdr;
146 union { 147 union {
147 struct { 148 struct {
148 } req; 149 } req;
149 struct { 150 struct {
150 u32 rev; 151 u32 rev;
151 } resp; 152 } resp;
152 } body; 153 } body;
153 }; 154 };
154 155
155 #define BCM2835_MBOX_TAG_GET_MAC_ADDRESS 0x00010003 156 #define BCM2835_MBOX_TAG_GET_MAC_ADDRESS 0x00010003
156 157
157 struct bcm2835_mbox_tag_get_mac_address { 158 struct bcm2835_mbox_tag_get_mac_address {
158 struct bcm2835_mbox_tag_hdr tag_hdr; 159 struct bcm2835_mbox_tag_hdr tag_hdr;
159 union { 160 union {
160 struct { 161 struct {
161 } req; 162 } req;
162 struct { 163 struct {
163 u8 mac[6]; 164 u8 mac[6];
164 u8 pad[2]; 165 u8 pad[2];
165 } resp; 166 } resp;
166 } body; 167 } body;
167 }; 168 };
168 169
169 #define BCM2835_MBOX_TAG_GET_ARM_MEMORY 0x00010005 170 #define BCM2835_MBOX_TAG_GET_ARM_MEMORY 0x00010005
170 171
171 struct bcm2835_mbox_tag_get_arm_mem { 172 struct bcm2835_mbox_tag_get_arm_mem {
172 struct bcm2835_mbox_tag_hdr tag_hdr; 173 struct bcm2835_mbox_tag_hdr tag_hdr;
173 union { 174 union {
174 struct { 175 struct {
175 } req; 176 } req;
176 struct { 177 struct {
177 u32 mem_base; 178 u32 mem_base;
178 u32 mem_size; 179 u32 mem_size;
179 } resp; 180 } resp;
180 } body; 181 } body;
181 }; 182 };
182 183
183 #define BCM2835_MBOX_POWER_DEVID_SDHCI 0 184 #define BCM2835_MBOX_POWER_DEVID_SDHCI 0
184 #define BCM2835_MBOX_POWER_DEVID_UART0 1 185 #define BCM2835_MBOX_POWER_DEVID_UART0 1
185 #define BCM2835_MBOX_POWER_DEVID_UART1 2 186 #define BCM2835_MBOX_POWER_DEVID_UART1 2
186 #define BCM2835_MBOX_POWER_DEVID_USB_HCD 3 187 #define BCM2835_MBOX_POWER_DEVID_USB_HCD 3
187 #define BCM2835_MBOX_POWER_DEVID_I2C0 4 188 #define BCM2835_MBOX_POWER_DEVID_I2C0 4
188 #define BCM2835_MBOX_POWER_DEVID_I2C1 5 189 #define BCM2835_MBOX_POWER_DEVID_I2C1 5
189 #define BCM2835_MBOX_POWER_DEVID_I2C2 6 190 #define BCM2835_MBOX_POWER_DEVID_I2C2 6
190 #define BCM2835_MBOX_POWER_DEVID_SPI 7 191 #define BCM2835_MBOX_POWER_DEVID_SPI 7
191 #define BCM2835_MBOX_POWER_DEVID_CCP2TX 8 192 #define BCM2835_MBOX_POWER_DEVID_CCP2TX 8
192 193
193 #define BCM2835_MBOX_POWER_STATE_RESP_ON (1 << 0) 194 #define BCM2835_MBOX_POWER_STATE_RESP_ON (1 << 0)
194 /* Device doesn't exist */ 195 /* Device doesn't exist */
195 #define BCM2835_MBOX_POWER_STATE_RESP_NODEV (1 << 1) 196 #define BCM2835_MBOX_POWER_STATE_RESP_NODEV (1 << 1)
196 197
197 #define BCM2835_MBOX_TAG_GET_POWER_STATE 0x00020001 198 #define BCM2835_MBOX_TAG_GET_POWER_STATE 0x00020001
198 199
199 struct bcm2835_mbox_tag_get_power_state { 200 struct bcm2835_mbox_tag_get_power_state {
200 struct bcm2835_mbox_tag_hdr tag_hdr; 201 struct bcm2835_mbox_tag_hdr tag_hdr;
201 union { 202 union {
202 struct { 203 struct {
203 u32 device_id; 204 u32 device_id;
204 } req; 205 } req;
205 struct { 206 struct {
206 u32 device_id; 207 u32 device_id;
207 u32 state; 208 u32 state;
208 } resp; 209 } resp;
209 } body; 210 } body;
210 }; 211 };
211 212
212 #define BCM2835_MBOX_TAG_SET_POWER_STATE 0x00028001 213 #define BCM2835_MBOX_TAG_SET_POWER_STATE 0x00028001
213 214
214 #define BCM2835_MBOX_SET_POWER_STATE_REQ_ON (1 << 0) 215 #define BCM2835_MBOX_SET_POWER_STATE_REQ_ON (1 << 0)
215 #define BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT (1 << 1) 216 #define BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT (1 << 1)
216 217
217 struct bcm2835_mbox_tag_set_power_state { 218 struct bcm2835_mbox_tag_set_power_state {
218 struct bcm2835_mbox_tag_hdr tag_hdr; 219 struct bcm2835_mbox_tag_hdr tag_hdr;
219 union { 220 union {
220 struct { 221 struct {
221 u32 device_id; 222 u32 device_id;
222 u32 state; 223 u32 state;
223 } req; 224 } req;
224 struct { 225 struct {
225 u32 device_id; 226 u32 device_id;
226 u32 state; 227 u32 state;
227 } resp; 228 } resp;
228 } body; 229 } body;
229 }; 230 };
230 231
231 #define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002 232 #define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002
232 233
233 #define BCM2835_MBOX_CLOCK_ID_EMMC 1 234 #define BCM2835_MBOX_CLOCK_ID_EMMC 1
234 #define BCM2835_MBOX_CLOCK_ID_UART 2 235 #define BCM2835_MBOX_CLOCK_ID_UART 2
235 #define BCM2835_MBOX_CLOCK_ID_ARM 3 236 #define BCM2835_MBOX_CLOCK_ID_ARM 3
236 #define BCM2835_MBOX_CLOCK_ID_CORE 4 237 #define BCM2835_MBOX_CLOCK_ID_CORE 4
237 #define BCM2835_MBOX_CLOCK_ID_V3D 5 238 #define BCM2835_MBOX_CLOCK_ID_V3D 5
238 #define BCM2835_MBOX_CLOCK_ID_H264 6 239 #define BCM2835_MBOX_CLOCK_ID_H264 6
239 #define BCM2835_MBOX_CLOCK_ID_ISP 7 240 #define BCM2835_MBOX_CLOCK_ID_ISP 7
240 #define BCM2835_MBOX_CLOCK_ID_SDRAM 8 241 #define BCM2835_MBOX_CLOCK_ID_SDRAM 8
241 #define BCM2835_MBOX_CLOCK_ID_PIXEL 9 242 #define BCM2835_MBOX_CLOCK_ID_PIXEL 9
242 #define BCM2835_MBOX_CLOCK_ID_PWM 10 243 #define BCM2835_MBOX_CLOCK_ID_PWM 10
243 244
244 struct bcm2835_mbox_tag_get_clock_rate { 245 struct bcm2835_mbox_tag_get_clock_rate {
245 struct bcm2835_mbox_tag_hdr tag_hdr; 246 struct bcm2835_mbox_tag_hdr tag_hdr;
246 union { 247 union {
247 struct { 248 struct {
248 u32 clock_id; 249 u32 clock_id;
249 } req; 250 } req;
250 struct { 251 struct {
251 u32 clock_id; 252 u32 clock_id;
252 u32 rate_hz; 253 u32 rate_hz;
253 } resp; 254 } resp;
254 } body; 255 } body;
255 }; 256 };
256 257
257 #define BCM2835_MBOX_TAG_ALLOCATE_BUFFER 0x00040001 258 #define BCM2835_MBOX_TAG_ALLOCATE_BUFFER 0x00040001
258 259
259 struct bcm2835_mbox_tag_allocate_buffer { 260 struct bcm2835_mbox_tag_allocate_buffer {
260 struct bcm2835_mbox_tag_hdr tag_hdr; 261 struct bcm2835_mbox_tag_hdr tag_hdr;
261 union { 262 union {
262 struct { 263 struct {
263 u32 alignment; 264 u32 alignment;
264 } req; 265 } req;
265 struct { 266 struct {
266 u32 fb_address; 267 u32 fb_address;
267 u32 fb_size; 268 u32 fb_size;
268 } resp; 269 } resp;
269 } body; 270 } body;
270 }; 271 };
271 272
272 #define BCM2835_MBOX_TAG_RELEASE_BUFFER 0x00048001 273 #define BCM2835_MBOX_TAG_RELEASE_BUFFER 0x00048001
273 274
274 struct bcm2835_mbox_tag_release_buffer { 275 struct bcm2835_mbox_tag_release_buffer {
275 struct bcm2835_mbox_tag_hdr tag_hdr; 276 struct bcm2835_mbox_tag_hdr tag_hdr;
276 union { 277 union {
277 struct { 278 struct {
278 } req; 279 } req;
279 struct { 280 struct {
280 } resp; 281 } resp;
281 } body; 282 } body;
282 }; 283 };
283 284
284 #define BCM2835_MBOX_TAG_BLANK_SCREEN 0x00040002 285 #define BCM2835_MBOX_TAG_BLANK_SCREEN 0x00040002
285 286
286 struct bcm2835_mbox_tag_blank_screen { 287 struct bcm2835_mbox_tag_blank_screen {
287 struct bcm2835_mbox_tag_hdr tag_hdr; 288 struct bcm2835_mbox_tag_hdr tag_hdr;
288 union { 289 union {
289 struct { 290 struct {
290 /* bit 0 means on, other bots reserved */ 291 /* bit 0 means on, other bots reserved */
291 u32 state; 292 u32 state;
292 } req; 293 } req;
293 struct { 294 struct {
294 u32 state; 295 u32 state;
295 } resp; 296 } resp;
296 } body; 297 } body;
297 }; 298 };
298 299
299 /* Physical means output signal */ 300 /* Physical means output signal */
300 #define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H 0x00040003 301 #define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H 0x00040003
301 #define BCM2835_MBOX_TAG_TEST_PHYSICAL_W_H 0x00044003 302 #define BCM2835_MBOX_TAG_TEST_PHYSICAL_W_H 0x00044003
302 #define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H 0x00048003 303 #define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H 0x00048003
303 304
304 struct bcm2835_mbox_tag_physical_w_h { 305 struct bcm2835_mbox_tag_physical_w_h {
305 struct bcm2835_mbox_tag_hdr tag_hdr; 306 struct bcm2835_mbox_tag_hdr tag_hdr;
306 union { 307 union {
307 /* req not used for get */ 308 /* req not used for get */
308 struct { 309 struct {
309 u32 width; 310 u32 width;
310 u32 height; 311 u32 height;
311 } req; 312 } req;
312 struct { 313 struct {
313 u32 width; 314 u32 width;
314 u32 height; 315 u32 height;
315 } resp; 316 } resp;
316 } body; 317 } body;
317 }; 318 };
318 319
319 /* Virtual means display buffer */ 320 /* Virtual means display buffer */
320 #define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H 0x00040004 321 #define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H 0x00040004
321 #define BCM2835_MBOX_TAG_TEST_VIRTUAL_W_H 0x00044004 322 #define BCM2835_MBOX_TAG_TEST_VIRTUAL_W_H 0x00044004
322 #define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H 0x00048004 323 #define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H 0x00048004
323 324
324 struct bcm2835_mbox_tag_virtual_w_h { 325 struct bcm2835_mbox_tag_virtual_w_h {
325 struct bcm2835_mbox_tag_hdr tag_hdr; 326 struct bcm2835_mbox_tag_hdr tag_hdr;
326 union { 327 union {
327 /* req not used for get */ 328 /* req not used for get */
328 struct { 329 struct {
329 u32 width; 330 u32 width;
330 u32 height; 331 u32 height;
331 } req; 332 } req;
332 struct { 333 struct {
333 u32 width; 334 u32 width;
334 u32 height; 335 u32 height;
335 } resp; 336 } resp;
336 } body; 337 } body;
337 }; 338 };
338 339
339 #define BCM2835_MBOX_TAG_GET_DEPTH 0x00040005 340 #define BCM2835_MBOX_TAG_GET_DEPTH 0x00040005
340 #define BCM2835_MBOX_TAG_TEST_DEPTH 0x00044005 341 #define BCM2835_MBOX_TAG_TEST_DEPTH 0x00044005
341 #define BCM2835_MBOX_TAG_SET_DEPTH 0x00048005 342 #define BCM2835_MBOX_TAG_SET_DEPTH 0x00048005
342 343
343 struct bcm2835_mbox_tag_depth { 344 struct bcm2835_mbox_tag_depth {
344 struct bcm2835_mbox_tag_hdr tag_hdr; 345 struct bcm2835_mbox_tag_hdr tag_hdr;
345 union { 346 union {
346 /* req not used for get */ 347 /* req not used for get */
347 struct { 348 struct {
348 u32 bpp; 349 u32 bpp;
349 } req; 350 } req;
350 struct { 351 struct {
351 u32 bpp; 352 u32 bpp;
352 } resp; 353 } resp;
353 } body; 354 } body;
354 }; 355 };
355 356
356 #define BCM2835_MBOX_TAG_GET_PIXEL_ORDER 0x00040006 357 #define BCM2835_MBOX_TAG_GET_PIXEL_ORDER 0x00040006
357 #define BCM2835_MBOX_TAG_TEST_PIXEL_ORDER 0x00044005 358 #define BCM2835_MBOX_TAG_TEST_PIXEL_ORDER 0x00044005
358 #define BCM2835_MBOX_TAG_SET_PIXEL_ORDER 0x00048006 359 #define BCM2835_MBOX_TAG_SET_PIXEL_ORDER 0x00048006
359 360
360 #define BCM2835_MBOX_PIXEL_ORDER_BGR 0 361 #define BCM2835_MBOX_PIXEL_ORDER_BGR 0
361 #define BCM2835_MBOX_PIXEL_ORDER_RGB 1 362 #define BCM2835_MBOX_PIXEL_ORDER_RGB 1
362 363
363 struct bcm2835_mbox_tag_pixel_order { 364 struct bcm2835_mbox_tag_pixel_order {
364 struct bcm2835_mbox_tag_hdr tag_hdr; 365 struct bcm2835_mbox_tag_hdr tag_hdr;
365 union { 366 union {
366 /* req not used for get */ 367 /* req not used for get */
367 struct { 368 struct {
368 u32 order; 369 u32 order;
369 } req; 370 } req;
370 struct { 371 struct {
371 u32 order; 372 u32 order;
372 } resp; 373 } resp;
373 } body; 374 } body;
374 }; 375 };
375 376
376 #define BCM2835_MBOX_TAG_GET_ALPHA_MODE 0x00040007 377 #define BCM2835_MBOX_TAG_GET_ALPHA_MODE 0x00040007
377 #define BCM2835_MBOX_TAG_TEST_ALPHA_MODE 0x00044007 378 #define BCM2835_MBOX_TAG_TEST_ALPHA_MODE 0x00044007
378 #define BCM2835_MBOX_TAG_SET_ALPHA_MODE 0x00048007 379 #define BCM2835_MBOX_TAG_SET_ALPHA_MODE 0x00048007
379 380
380 #define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE 0 381 #define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE 0
381 #define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT 1 382 #define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT 1
382 #define BCM2835_MBOX_ALPHA_MODE_IGNORED 2 383 #define BCM2835_MBOX_ALPHA_MODE_IGNORED 2
383 384
384 struct bcm2835_mbox_tag_alpha_mode { 385 struct bcm2835_mbox_tag_alpha_mode {
385 struct bcm2835_mbox_tag_hdr tag_hdr; 386 struct bcm2835_mbox_tag_hdr tag_hdr;
386 union { 387 union {
387 /* req not used for get */ 388 /* req not used for get */
388 struct { 389 struct {
389 u32 alpha; 390 u32 alpha;
390 } req; 391 } req;
391 struct { 392 struct {
392 u32 alpha; 393 u32 alpha;
393 } resp; 394 } resp;
394 } body; 395 } body;
395 }; 396 };
396 397
397 #define BCM2835_MBOX_TAG_GET_PITCH 0x00040008 398 #define BCM2835_MBOX_TAG_GET_PITCH 0x00040008
398 399
399 struct bcm2835_mbox_tag_pitch { 400 struct bcm2835_mbox_tag_pitch {
400 struct bcm2835_mbox_tag_hdr tag_hdr; 401 struct bcm2835_mbox_tag_hdr tag_hdr;
401 union { 402 union {
402 struct { 403 struct {
403 } req; 404 } req;
404 struct { 405 struct {
405 u32 pitch; 406 u32 pitch;
406 } resp; 407 } resp;
407 } body; 408 } body;
408 }; 409 };
409 410
410 /* Offset of display window within buffer */ 411 /* Offset of display window within buffer */
411 #define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET 0x00040009 412 #define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET 0x00040009
412 #define BCM2835_MBOX_TAG_TEST_VIRTUAL_OFFSET 0x00044009 413 #define BCM2835_MBOX_TAG_TEST_VIRTUAL_OFFSET 0x00044009
413 #define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET 0x00048009 414 #define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET 0x00048009
414 415
415 struct bcm2835_mbox_tag_virtual_offset { 416 struct bcm2835_mbox_tag_virtual_offset {
416 struct bcm2835_mbox_tag_hdr tag_hdr; 417 struct bcm2835_mbox_tag_hdr tag_hdr;
417 union { 418 union {
418 /* req not used for get */ 419 /* req not used for get */
419 struct { 420 struct {
420 u32 x; 421 u32 x;
421 u32 y; 422 u32 y;
422 } req; 423 } req;
423 struct { 424 struct {
424 u32 x; 425 u32 x;
425 u32 y; 426 u32 y;
426 } resp; 427 } resp;
427 } body; 428 } body;
428 }; 429 };
429 430
430 #define BCM2835_MBOX_TAG_GET_OVERSCAN 0x0004000a 431 #define BCM2835_MBOX_TAG_GET_OVERSCAN 0x0004000a
431 #define BCM2835_MBOX_TAG_TEST_OVERSCAN 0x0004400a 432 #define BCM2835_MBOX_TAG_TEST_OVERSCAN 0x0004400a
432 #define BCM2835_MBOX_TAG_SET_OVERSCAN 0x0004800a 433 #define BCM2835_MBOX_TAG_SET_OVERSCAN 0x0004800a
433 434
434 struct bcm2835_mbox_tag_overscan { 435 struct bcm2835_mbox_tag_overscan {
435 struct bcm2835_mbox_tag_hdr tag_hdr; 436 struct bcm2835_mbox_tag_hdr tag_hdr;
436 union { 437 union {
437 /* req not used for get */ 438 /* req not used for get */
438 struct { 439 struct {
439 u32 top; 440 u32 top;
440 u32 bottom; 441 u32 bottom;
441 u32 left; 442 u32 left;
442 u32 right; 443 u32 right;
443 } req; 444 } req;
444 struct { 445 struct {
445 u32 top; 446 u32 top;
446 u32 bottom; 447 u32 bottom;
447 u32 left; 448 u32 left;
448 u32 right; 449 u32 right;
449 } resp; 450 } resp;
450 } body; 451 } body;
451 }; 452 };
452 453
453 #define BCM2835_MBOX_TAG_GET_PALETTE 0x0004000b 454 #define BCM2835_MBOX_TAG_GET_PALETTE 0x0004000b
454 455
455 struct bcm2835_mbox_tag_get_palette { 456 struct bcm2835_mbox_tag_get_palette {
456 struct bcm2835_mbox_tag_hdr tag_hdr; 457 struct bcm2835_mbox_tag_hdr tag_hdr;
457 union { 458 union {
458 struct { 459 struct {
459 } req; 460 } req;
460 struct { 461 struct {
461 u32 data[1024]; 462 u32 data[1024];
462 } resp; 463 } resp;
463 } body; 464 } body;
464 }; 465 };
465 466
466 #define BCM2835_MBOX_TAG_TEST_PALETTE 0x0004400b 467 #define BCM2835_MBOX_TAG_TEST_PALETTE 0x0004400b
467 468
468 struct bcm2835_mbox_tag_test_palette { 469 struct bcm2835_mbox_tag_test_palette {
469 struct bcm2835_mbox_tag_hdr tag_hdr; 470 struct bcm2835_mbox_tag_hdr tag_hdr;
470 union { 471 union {
471 struct { 472 struct {
472 u32 offset; 473 u32 offset;
473 u32 num_entries; 474 u32 num_entries;
474 u32 data[256]; 475 u32 data[256];
475 } req; 476 } req;
476 struct { 477 struct {
477 u32 is_invalid; 478 u32 is_invalid;
478 } resp; 479 } resp;
479 } body; 480 } body;
480 }; 481 };
481 482
482 #define BCM2835_MBOX_TAG_SET_PALETTE 0x0004800b 483 #define BCM2835_MBOX_TAG_SET_PALETTE 0x0004800b
483 484
484 struct bcm2835_mbox_tag_set_palette { 485 struct bcm2835_mbox_tag_set_palette {
485 struct bcm2835_mbox_tag_hdr tag_hdr; 486 struct bcm2835_mbox_tag_hdr tag_hdr;
486 union { 487 union {
487 struct { 488 struct {
488 u32 offset; 489 u32 offset;
489 u32 num_entries; 490 u32 num_entries;
490 u32 data[256]; 491 u32 data[256];
491 } req; 492 } req;
492 struct { 493 struct {
493 u32 is_invalid; 494 u32 is_invalid;
494 } resp; 495 } resp;
495 } body; 496 } body;
496 }; 497 };
497 498
498 /* 499 /*
499 * Pass a raw u32 message to the VC, and receive a raw u32 back. 500 * Pass a raw u32 message to the VC, and receive a raw u32 back.
500 * 501 *
501 * Returns 0 for success, any other value for error. 502 * Returns 0 for success, any other value for error.
502 */ 503 */
503 int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv); 504 int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv);
504 505
505 /* 506 /*
506 * Pass a complete property-style buffer to the VC, and wait until it has 507 * Pass a complete property-style buffer to the VC, and wait until it has
507 * been processed. 508 * been processed.
508 * 509 *
509 * This function expects a pointer to the mbox_hdr structure in an attempt 510 * This function expects a pointer to the mbox_hdr structure in an attempt
510 * to ensure some degree of type safety. However, some number of tags and 511 * to ensure some degree of type safety. However, some number of tags and
511 * a termination value are expected to immediately follow the header in 512 * a termination value are expected to immediately follow the header in
512 * memory, as required by the property protocol. 513 * memory, as required by the property protocol.
513 * 514 *
514 * Returns 0 for success, any other value for error. 515 * Returns 0 for success, any other value for error.
515 */ 516 */
516 int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer); 517 int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer);
517 518
518 #endif 519 #endif
519 520
board/raspberrypi/rpi/rpi.c
1 /* 1 /*
2 * (C) Copyright 2012-2013 Stephen Warren 2 * (C) Copyright 2012-2013 Stephen Warren
3 * 3 *
4 * See file CREDITS for list of people who contributed to this 4 * See file CREDITS for list of people who contributed to this
5 * project. 5 * project.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation. 9 * version 2 as published by the Free Software Foundation.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, but 11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 */ 15 */
16 16
17 #include <common.h> 17 #include <common.h>
18 #include <config.h> 18 #include <config.h>
19 #include <dm.h> 19 #include <dm.h>
20 #include <fdt_support.h> 20 #include <fdt_support.h>
21 #include <lcd.h> 21 #include <lcd.h>
22 #include <mmc.h> 22 #include <mmc.h>
23 #include <asm/gpio.h> 23 #include <asm/gpio.h>
24 #include <asm/arch/mbox.h> 24 #include <asm/arch/mbox.h>
25 #include <asm/arch/sdhci.h> 25 #include <asm/arch/sdhci.h>
26 #include <asm/global_data.h> 26 #include <asm/global_data.h>
27 #include <dm/platform_data/serial_pl01x.h> 27 #include <dm/platform_data/serial_pl01x.h>
28 28
29 DECLARE_GLOBAL_DATA_PTR; 29 DECLARE_GLOBAL_DATA_PTR;
30 30
31 static const struct bcm2835_gpio_platdata gpio_platdata = { 31 static const struct bcm2835_gpio_platdata gpio_platdata = {
32 .base = BCM2835_GPIO_BASE, 32 .base = BCM2835_GPIO_BASE,
33 }; 33 };
34 34
35 U_BOOT_DEVICE(bcm2835_gpios) = { 35 U_BOOT_DEVICE(bcm2835_gpios) = {
36 .name = "gpio_bcm2835", 36 .name = "gpio_bcm2835",
37 .platdata = &gpio_platdata, 37 .platdata = &gpio_platdata,
38 }; 38 };
39 39
40 static const struct pl01x_serial_platdata serial_platdata = { 40 static const struct pl01x_serial_platdata serial_platdata = {
41 .base = 0x20201000, 41 .base = 0x20201000,
42 .type = TYPE_PL011, 42 .type = TYPE_PL011,
43 .clock = 3000000, 43 .clock = 3000000,
44 }; 44 };
45 45
46 U_BOOT_DEVICE(bcm2835_serials) = { 46 U_BOOT_DEVICE(bcm2835_serials) = {
47 .name = "serial_pl01x", 47 .name = "serial_pl01x",
48 .platdata = &serial_platdata, 48 .platdata = &serial_platdata,
49 }; 49 };
50 50
51 struct msg_get_arm_mem { 51 struct msg_get_arm_mem {
52 struct bcm2835_mbox_hdr hdr; 52 struct bcm2835_mbox_hdr hdr;
53 struct bcm2835_mbox_tag_get_arm_mem get_arm_mem; 53 struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
54 u32 end_tag; 54 u32 end_tag;
55 }; 55 };
56 56
57 struct msg_get_board_rev { 57 struct msg_get_board_rev {
58 struct bcm2835_mbox_hdr hdr; 58 struct bcm2835_mbox_hdr hdr;
59 struct bcm2835_mbox_tag_get_board_rev get_board_rev; 59 struct bcm2835_mbox_tag_get_board_rev get_board_rev;
60 u32 end_tag; 60 u32 end_tag;
61 }; 61 };
62 62
63 struct msg_get_mac_address { 63 struct msg_get_mac_address {
64 struct bcm2835_mbox_hdr hdr; 64 struct bcm2835_mbox_hdr hdr;
65 struct bcm2835_mbox_tag_get_mac_address get_mac_address; 65 struct bcm2835_mbox_tag_get_mac_address get_mac_address;
66 u32 end_tag; 66 u32 end_tag;
67 }; 67 };
68 68
69 struct msg_set_power_state { 69 struct msg_set_power_state {
70 struct bcm2835_mbox_hdr hdr; 70 struct bcm2835_mbox_hdr hdr;
71 struct bcm2835_mbox_tag_set_power_state set_power_state; 71 struct bcm2835_mbox_tag_set_power_state set_power_state;
72 u32 end_tag; 72 u32 end_tag;
73 }; 73 };
74 74
75 struct msg_get_clock_rate { 75 struct msg_get_clock_rate {
76 struct bcm2835_mbox_hdr hdr; 76 struct bcm2835_mbox_hdr hdr;
77 struct bcm2835_mbox_tag_get_clock_rate get_clock_rate; 77 struct bcm2835_mbox_tag_get_clock_rate get_clock_rate;
78 u32 end_tag; 78 u32 end_tag;
79 }; 79 };
80 80
81 /* See comments in mbox.h for data source */ 81 /* See comments in mbox.h for data source */
82 static const struct { 82 static const struct {
83 const char *name; 83 const char *name;
84 const char *fdtfile; 84 const char *fdtfile;
85 bool has_onboard_eth; 85 bool has_onboard_eth;
86 } models[] = { 86 } models[] = {
87 [BCM2835_BOARD_REV_B_I2C0_2] = { 87 [BCM2835_BOARD_REV_B_I2C0_2] = {
88 "Model B (no P5)", 88 "Model B (no P5)",
89 "bcm2835-rpi-b-i2c0.dtb", 89 "bcm2835-rpi-b-i2c0.dtb",
90 true, 90 true,
91 }, 91 },
92 [BCM2835_BOARD_REV_B_I2C0_3] = { 92 [BCM2835_BOARD_REV_B_I2C0_3] = {
93 "Model B (no P5)", 93 "Model B (no P5)",
94 "bcm2835-rpi-b-i2c0.dtb", 94 "bcm2835-rpi-b-i2c0.dtb",
95 true, 95 true,
96 }, 96 },
97 [BCM2835_BOARD_REV_B_I2C1_4] = { 97 [BCM2835_BOARD_REV_B_I2C1_4] = {
98 "Model B", 98 "Model B",
99 "bcm2835-rpi-b.dtb", 99 "bcm2835-rpi-b.dtb",
100 true, 100 true,
101 }, 101 },
102 [BCM2835_BOARD_REV_B_I2C1_5] = { 102 [BCM2835_BOARD_REV_B_I2C1_5] = {
103 "Model B", 103 "Model B",
104 "bcm2835-rpi-b.dtb", 104 "bcm2835-rpi-b.dtb",
105 true, 105 true,
106 }, 106 },
107 [BCM2835_BOARD_REV_B_I2C1_6] = { 107 [BCM2835_BOARD_REV_B_I2C1_6] = {
108 "Model B", 108 "Model B",
109 "bcm2835-rpi-b.dtb", 109 "bcm2835-rpi-b.dtb",
110 true, 110 true,
111 }, 111 },
112 [BCM2835_BOARD_REV_A_7] = { 112 [BCM2835_BOARD_REV_A_7] = {
113 "Model A", 113 "Model A",
114 "bcm2835-rpi-a.dtb", 114 "bcm2835-rpi-a.dtb",
115 false, 115 false,
116 }, 116 },
117 [BCM2835_BOARD_REV_A_8] = { 117 [BCM2835_BOARD_REV_A_8] = {
118 "Model A", 118 "Model A",
119 "bcm2835-rpi-a.dtb", 119 "bcm2835-rpi-a.dtb",
120 false, 120 false,
121 }, 121 },
122 [BCM2835_BOARD_REV_A_9] = { 122 [BCM2835_BOARD_REV_A_9] = {
123 "Model A", 123 "Model A",
124 "bcm2835-rpi-a.dtb", 124 "bcm2835-rpi-a.dtb",
125 false, 125 false,
126 }, 126 },
127 [BCM2835_BOARD_REV_B_REV2_d] = { 127 [BCM2835_BOARD_REV_B_REV2_d] = {
128 "Model B rev2", 128 "Model B rev2",
129 "bcm2835-rpi-b-rev2.dtb", 129 "bcm2835-rpi-b-rev2.dtb",
130 true, 130 true,
131 }, 131 },
132 [BCM2835_BOARD_REV_B_REV2_e] = { 132 [BCM2835_BOARD_REV_B_REV2_e] = {
133 "Model B rev2", 133 "Model B rev2",
134 "bcm2835-rpi-b-rev2.dtb", 134 "bcm2835-rpi-b-rev2.dtb",
135 true, 135 true,
136 }, 136 },
137 [BCM2835_BOARD_REV_B_REV2_f] = { 137 [BCM2835_BOARD_REV_B_REV2_f] = {
138 "Model B rev2", 138 "Model B rev2",
139 "bcm2835-rpi-b-rev2.dtb", 139 "bcm2835-rpi-b-rev2.dtb",
140 true, 140 true,
141 }, 141 },
142 [BCM2835_BOARD_REV_B_PLUS] = { 142 [BCM2835_BOARD_REV_B_PLUS] = {
143 "Model B+", 143 "Model B+",
144 "bcm2835-rpi-b-plus.dtb", 144 "bcm2835-rpi-b-plus.dtb",
145 true, 145 true,
146 }, 146 },
147 [BCM2835_BOARD_REV_CM] = { 147 [BCM2835_BOARD_REV_CM] = {
148 "Compute Module", 148 "Compute Module",
149 "bcm2835-rpi-cm.dtb", 149 "bcm2835-rpi-cm.dtb",
150 false, 150 false,
151 }, 151 },
152 [BCM2835_BOARD_REV_A_PLUS] = {
153 "Model A+",
154 "bcm2835-rpi-a-plus.dtb",
155 false,
156 },
152 }; 157 };
153 158
154 u32 rpi_board_rev = 0; 159 u32 rpi_board_rev = 0;
155 160
156 int dram_init(void) 161 int dram_init(void)
157 { 162 {
158 ALLOC_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1, 16); 163 ALLOC_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1, 16);
159 int ret; 164 int ret;
160 165
161 BCM2835_MBOX_INIT_HDR(msg); 166 BCM2835_MBOX_INIT_HDR(msg);
162 BCM2835_MBOX_INIT_TAG(&msg->get_arm_mem, GET_ARM_MEMORY); 167 BCM2835_MBOX_INIT_TAG(&msg->get_arm_mem, GET_ARM_MEMORY);
163 168
164 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); 169 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
165 if (ret) { 170 if (ret) {
166 printf("bcm2835: Could not query ARM memory size\n"); 171 printf("bcm2835: Could not query ARM memory size\n");
167 return -1; 172 return -1;
168 } 173 }
169 174
170 gd->ram_size = msg->get_arm_mem.body.resp.mem_size; 175 gd->ram_size = msg->get_arm_mem.body.resp.mem_size;
171 176
172 return 0; 177 return 0;
173 } 178 }
174 179
175 static void set_fdtfile(void) 180 static void set_fdtfile(void)
176 { 181 {
177 const char *fdtfile; 182 const char *fdtfile;
178 183
179 if (getenv("fdtfile")) 184 if (getenv("fdtfile"))
180 return; 185 return;
181 186
182 fdtfile = models[rpi_board_rev].fdtfile; 187 fdtfile = models[rpi_board_rev].fdtfile;
183 if (!fdtfile) 188 if (!fdtfile)
184 fdtfile = "bcm2835-rpi-other.dtb"; 189 fdtfile = "bcm2835-rpi-other.dtb";
185 190
186 setenv("fdtfile", fdtfile); 191 setenv("fdtfile", fdtfile);
187 } 192 }
188 193
189 static void set_usbethaddr(void) 194 static void set_usbethaddr(void)
190 { 195 {
191 ALLOC_ALIGN_BUFFER(struct msg_get_mac_address, msg, 1, 16); 196 ALLOC_ALIGN_BUFFER(struct msg_get_mac_address, msg, 1, 16);
192 int ret; 197 int ret;
193 198
194 if (!models[rpi_board_rev].has_onboard_eth) 199 if (!models[rpi_board_rev].has_onboard_eth)
195 return; 200 return;
196 201
197 if (getenv("usbethaddr")) 202 if (getenv("usbethaddr"))
198 return; 203 return;
199 204
200 BCM2835_MBOX_INIT_HDR(msg); 205 BCM2835_MBOX_INIT_HDR(msg);
201 BCM2835_MBOX_INIT_TAG(&msg->get_mac_address, GET_MAC_ADDRESS); 206 BCM2835_MBOX_INIT_TAG(&msg->get_mac_address, GET_MAC_ADDRESS);
202 207
203 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); 208 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
204 if (ret) { 209 if (ret) {
205 printf("bcm2835: Could not query MAC address\n"); 210 printf("bcm2835: Could not query MAC address\n");
206 /* Ignore error; not critical */ 211 /* Ignore error; not critical */
207 return; 212 return;
208 } 213 }
209 214
210 eth_setenv_enetaddr("usbethaddr", msg->get_mac_address.body.resp.mac); 215 eth_setenv_enetaddr("usbethaddr", msg->get_mac_address.body.resp.mac);
211 216
212 return; 217 return;
213 } 218 }
214 219
215 int misc_init_r(void) 220 int misc_init_r(void)
216 { 221 {
217 set_fdtfile(); 222 set_fdtfile();
218 set_usbethaddr(); 223 set_usbethaddr();
219 return 0; 224 return 0;
220 } 225 }
221 226
222 static int power_on_module(u32 module) 227 static int power_on_module(u32 module)
223 { 228 {
224 ALLOC_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1, 16); 229 ALLOC_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1, 16);
225 int ret; 230 int ret;
226 231
227 BCM2835_MBOX_INIT_HDR(msg_pwr); 232 BCM2835_MBOX_INIT_HDR(msg_pwr);
228 BCM2835_MBOX_INIT_TAG(&msg_pwr->set_power_state, 233 BCM2835_MBOX_INIT_TAG(&msg_pwr->set_power_state,
229 SET_POWER_STATE); 234 SET_POWER_STATE);
230 msg_pwr->set_power_state.body.req.device_id = module; 235 msg_pwr->set_power_state.body.req.device_id = module;
231 msg_pwr->set_power_state.body.req.state = 236 msg_pwr->set_power_state.body.req.state =
232 BCM2835_MBOX_SET_POWER_STATE_REQ_ON | 237 BCM2835_MBOX_SET_POWER_STATE_REQ_ON |
233 BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT; 238 BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT;
234 239
235 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, 240 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN,
236 &msg_pwr->hdr); 241 &msg_pwr->hdr);
237 if (ret) { 242 if (ret) {
238 printf("bcm2835: Could not set module %u power state\n", 243 printf("bcm2835: Could not set module %u power state\n",
239 module); 244 module);
240 return -1; 245 return -1;
241 } 246 }
242 247
243 return 0; 248 return 0;
244 } 249 }
245 250
246 static void get_board_rev(void) 251 static void get_board_rev(void)
247 { 252 {
248 ALLOC_ALIGN_BUFFER(struct msg_get_board_rev, msg, 1, 16); 253 ALLOC_ALIGN_BUFFER(struct msg_get_board_rev, msg, 1, 16);
249 int ret; 254 int ret;
250 const char *name; 255 const char *name;
251 256
252 BCM2835_MBOX_INIT_HDR(msg); 257 BCM2835_MBOX_INIT_HDR(msg);
253 BCM2835_MBOX_INIT_TAG(&msg->get_board_rev, GET_BOARD_REV); 258 BCM2835_MBOX_INIT_TAG(&msg->get_board_rev, GET_BOARD_REV);
254 259
255 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); 260 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
256 if (ret) { 261 if (ret) {
257 printf("bcm2835: Could not query board revision\n"); 262 printf("bcm2835: Could not query board revision\n");
258 /* Ignore error; not critical */ 263 /* Ignore error; not critical */
259 return; 264 return;
260 } 265 }
261 266
262 rpi_board_rev = msg->get_board_rev.body.resp.rev; 267 rpi_board_rev = msg->get_board_rev.body.resp.rev;
263 if (rpi_board_rev >= ARRAY_SIZE(models)) 268 if (rpi_board_rev >= ARRAY_SIZE(models)) {
269 printf("RPI: Board rev %u outside known range\n",
270 rpi_board_rev);
264 rpi_board_rev = 0; 271 rpi_board_rev = 0;
272 }
265 273
266 name = models[rpi_board_rev].name; 274 name = models[rpi_board_rev].name;
267 if (!name) 275 if (!name) {
276 printf("RPI: Board rev %u unknown\n", rpi_board_rev);
268 name = "Unknown model"; 277 name = "Unknown model";
278 }
269 printf("RPI model: %s\n", name); 279 printf("RPI model: %s\n", name);
270 } 280 }
271 281
272 int board_init(void) 282 int board_init(void)
273 { 283 {
274 get_board_rev(); 284 get_board_rev();
275 285
276 gd->bd->bi_boot_params = 0x100; 286 gd->bd->bi_boot_params = 0x100;
277 287
278 return power_on_module(BCM2835_MBOX_POWER_DEVID_USB_HCD); 288 return power_on_module(BCM2835_MBOX_POWER_DEVID_USB_HCD);
279 } 289 }
280 290
281 int board_mmc_init(bd_t *bis) 291 int board_mmc_init(bd_t *bis)
282 { 292 {
283 ALLOC_ALIGN_BUFFER(struct msg_get_clock_rate, msg_clk, 1, 16); 293 ALLOC_ALIGN_BUFFER(struct msg_get_clock_rate, msg_clk, 1, 16);
284 int ret; 294 int ret;
285 295
286 power_on_module(BCM2835_MBOX_POWER_DEVID_SDHCI); 296 power_on_module(BCM2835_MBOX_POWER_DEVID_SDHCI);
287 297
288 BCM2835_MBOX_INIT_HDR(msg_clk); 298 BCM2835_MBOX_INIT_HDR(msg_clk);
289 BCM2835_MBOX_INIT_TAG(&msg_clk->get_clock_rate, GET_CLOCK_RATE); 299 BCM2835_MBOX_INIT_TAG(&msg_clk->get_clock_rate, GET_CLOCK_RATE);
290 msg_clk->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC; 300 msg_clk->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC;
291 301
292 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_clk->hdr); 302 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_clk->hdr);
293 if (ret) { 303 if (ret) {
294 printf("bcm2835: Could not query eMMC clock rate\n"); 304 printf("bcm2835: Could not query eMMC clock rate\n");
295 return -1; 305 return -1;
296 } 306 }
297 307
298 return bcm2835_sdhci_init(BCM2835_SDHCI_BASE, 308 return bcm2835_sdhci_init(BCM2835_SDHCI_BASE,
299 msg_clk->get_clock_rate.body.resp.rate_hz); 309 msg_clk->get_clock_rate.body.resp.rate_hz);
300 } 310 }
301 311
302 int ft_board_setup(void *blob, bd_t *bd) 312 int ft_board_setup(void *blob, bd_t *bd)
303 { 313 {
304 /* 314 /*
305 * For now, we simply always add the simplefb DT node. Later, we 315 * For now, we simply always add the simplefb DT node. Later, we
306 * should be more intelligent, and e.g. only do this if no enabled DT 316 * should be more intelligent, and e.g. only do this if no enabled DT
307 * node exists for the "real" graphics driver. 317 * node exists for the "real" graphics driver.
308 */ 318 */
309 lcd_dt_simplefb_add_node(blob); 319 lcd_dt_simplefb_add_node(blob);
310 320
311 return 0; 321 return 0;
312 } 322 }
313 323