Commit 47705eff7a822105dfddaa03aadfe95f05849892
Committed by
Tom Rini
1 parent
3207d8fc9c
Exists in
v2017.01-smarct4x
and in
37 other branches
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 |