4a143917f0f8ed4a7b53345dfe4b040ad635abb5
[oweals/u-boot.git] / arch / arm / mach-bcm283x / include / mach / mbox.h
1 /*
2  * (C) Copyright 2012,2015 Stephen Warren
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #ifndef _BCM2835_MBOX_H
8 #define _BCM2835_MBOX_H
9
10 #include <linux/compiler.h>
11
12 /*
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.
15  * However, the VideoCore actually controls the initial SoC boot, and hides
16  * much of the hardware behind a protocol. This protocol is transported
17  * using the SoC's mailbox hardware module.
18  *
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
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
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
25  * devices whose power should be enabled.
26  *
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
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
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
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
35  * combined together into a single message buffer. This file defines structs
36  * representing the header and many individual tag layouts and IDs.
37  */
38
39 /* Raw mailbox HW */
40
41 #ifdef CONFIG_BCM2836
42 #define BCM2835_MBOX_PHYSADDR   0x3f00b880
43 #else
44 #define BCM2835_MBOX_PHYSADDR   0x2000b880
45 #endif
46
47 struct bcm2835_mbox_regs {
48         u32 read;
49         u32 rsvd0[5];
50         u32 status;
51         u32 config;
52         u32 write;
53 };
54
55 #define BCM2835_MBOX_STATUS_WR_FULL     0x80000000
56 #define BCM2835_MBOX_STATUS_RD_EMPTY    0x40000000
57
58 /* Lower 4-bits are channel ID */
59 #define BCM2835_CHAN_MASK               0xf
60 #define BCM2835_MBOX_PACK(chan, data)   (((data) & (~BCM2835_CHAN_MASK)) | \
61                                          (chan & BCM2835_CHAN_MASK))
62 #define BCM2835_MBOX_UNPACK_CHAN(val)   ((val) & BCM2835_CHAN_MASK)
63 #define BCM2835_MBOX_UNPACK_DATA(val)   ((val) & (~BCM2835_CHAN_MASK))
64
65 /* Property mailbox buffer structures */
66
67 #define BCM2835_MBOX_PROP_CHAN          8
68
69 /* All message buffers must start with this header */
70 struct bcm2835_mbox_hdr {
71         u32 buf_size;
72         u32 code;
73 };
74
75 #define BCM2835_MBOX_REQ_CODE           0
76 #define BCM2835_MBOX_RESP_CODE_SUCCESS  0x80000000
77
78 #define BCM2835_MBOX_INIT_HDR(_m_) { \
79                 memset((_m_), 0, sizeof(*(_m_))); \
80                 (_m_)->hdr.buf_size = sizeof(*(_m_)); \
81                 (_m_)->hdr.code = 0; \
82                 (_m_)->end_tag = 0; \
83         }
84
85 /*
86  * A message buffer contains a list of tags. Each tag must also start with
87  * a standardized header.
88  */
89 struct bcm2835_mbox_tag_hdr {
90         u32 tag;
91         u32 val_buf_size;
92         u32 val_len;
93 };
94
95 #define BCM2835_MBOX_INIT_TAG(_t_, _id_) { \
96                 (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
97                 (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
98                 (_t_)->tag_hdr.val_len = sizeof((_t_)->body.req); \
99         }
100
101 #define BCM2835_MBOX_INIT_TAG_NO_REQ(_t_, _id_) { \
102                 (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
103                 (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
104                 (_t_)->tag_hdr.val_len = 0; \
105         }
106
107 /* When responding, the VC sets this bit in val_len to indicate a response */
108 #define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE       0x80000000
109
110 /*
111  * Below we define the ID and struct for many possible tags. This header only
112  * defines individual tag structs, not entire message structs, since in
113  * general an arbitrary set of tags may be combined into a single message.
114  * Clients of the mbox API are expected to define their own overall message
115  * structures by combining the header, a set of tags, and a terminating
116  * entry. For example,
117  *
118  * struct msg {
119  *     struct bcm2835_mbox_hdr hdr;
120  *     struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
121  *     ... perhaps other tags here ...
122  *     u32 end_tag;
123  * };
124  */
125
126 #define BCM2835_MBOX_TAG_GET_BOARD_REV  0x00010002
127
128 struct bcm2835_mbox_tag_get_board_rev {
129         struct bcm2835_mbox_tag_hdr tag_hdr;
130         union {
131                 struct {
132                 } req;
133                 struct {
134                         u32 rev;
135                 } resp;
136         } body;
137 };
138
139 #define BCM2835_MBOX_TAG_GET_MAC_ADDRESS        0x00010003
140
141 struct bcm2835_mbox_tag_get_mac_address {
142         struct bcm2835_mbox_tag_hdr tag_hdr;
143         union {
144                 struct {
145                 } req;
146                 struct {
147                         u8 mac[6];
148                         u8 pad[2];
149                 } resp;
150         } body;
151 };
152
153 #define BCM2835_MBOX_TAG_GET_BOARD_SERIAL       0x00010004
154
155 struct bcm2835_mbox_tag_get_board_serial {
156         struct bcm2835_mbox_tag_hdr tag_hdr;
157         union {
158                 struct __packed {
159                         u64 serial;
160                 } resp;
161         } body;
162 };
163
164 #define BCM2835_MBOX_TAG_GET_ARM_MEMORY         0x00010005
165
166 struct bcm2835_mbox_tag_get_arm_mem {
167         struct bcm2835_mbox_tag_hdr tag_hdr;
168         union {
169                 struct {
170                 } req;
171                 struct {
172                         u32 mem_base;
173                         u32 mem_size;
174                 } resp;
175         } body;
176 };
177
178 #define BCM2835_MBOX_POWER_DEVID_SDHCI          0
179 #define BCM2835_MBOX_POWER_DEVID_UART0          1
180 #define BCM2835_MBOX_POWER_DEVID_UART1          2
181 #define BCM2835_MBOX_POWER_DEVID_USB_HCD        3
182 #define BCM2835_MBOX_POWER_DEVID_I2C0           4
183 #define BCM2835_MBOX_POWER_DEVID_I2C1           5
184 #define BCM2835_MBOX_POWER_DEVID_I2C2           6
185 #define BCM2835_MBOX_POWER_DEVID_SPI            7
186 #define BCM2835_MBOX_POWER_DEVID_CCP2TX         8
187
188 #define BCM2835_MBOX_POWER_STATE_RESP_ON        (1 << 0)
189 /* Device doesn't exist */
190 #define BCM2835_MBOX_POWER_STATE_RESP_NODEV     (1 << 1)
191
192 #define BCM2835_MBOX_TAG_GET_POWER_STATE        0x00020001
193
194 struct bcm2835_mbox_tag_get_power_state {
195         struct bcm2835_mbox_tag_hdr tag_hdr;
196         union {
197                 struct {
198                         u32 device_id;
199                 } req;
200                 struct {
201                         u32 device_id;
202                         u32 state;
203                 } resp;
204         } body;
205 };
206
207 #define BCM2835_MBOX_TAG_SET_POWER_STATE        0x00028001
208
209 #define BCM2835_MBOX_SET_POWER_STATE_REQ_ON     (1 << 0)
210 #define BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT   (1 << 1)
211
212 struct bcm2835_mbox_tag_set_power_state {
213         struct bcm2835_mbox_tag_hdr tag_hdr;
214         union {
215                 struct {
216                         u32 device_id;
217                         u32 state;
218                 } req;
219                 struct {
220                         u32 device_id;
221                         u32 state;
222                 } resp;
223         } body;
224 };
225
226 #define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002
227
228 #define BCM2835_MBOX_CLOCK_ID_EMMC      1
229 #define BCM2835_MBOX_CLOCK_ID_UART      2
230 #define BCM2835_MBOX_CLOCK_ID_ARM       3
231 #define BCM2835_MBOX_CLOCK_ID_CORE      4
232 #define BCM2835_MBOX_CLOCK_ID_V3D       5
233 #define BCM2835_MBOX_CLOCK_ID_H264      6
234 #define BCM2835_MBOX_CLOCK_ID_ISP       7
235 #define BCM2835_MBOX_CLOCK_ID_SDRAM     8
236 #define BCM2835_MBOX_CLOCK_ID_PIXEL     9
237 #define BCM2835_MBOX_CLOCK_ID_PWM       10
238
239 struct bcm2835_mbox_tag_get_clock_rate {
240         struct bcm2835_mbox_tag_hdr tag_hdr;
241         union {
242                 struct {
243                         u32 clock_id;
244                 } req;
245                 struct {
246                         u32 clock_id;
247                         u32 rate_hz;
248                 } resp;
249         } body;
250 };
251
252 #define BCM2835_MBOX_TAG_ALLOCATE_BUFFER        0x00040001
253
254 struct bcm2835_mbox_tag_allocate_buffer {
255         struct bcm2835_mbox_tag_hdr tag_hdr;
256         union {
257                 struct {
258                         u32 alignment;
259                 } req;
260                 struct {
261                         u32 fb_address;
262                         u32 fb_size;
263                 } resp;
264         } body;
265 };
266
267 #define BCM2835_MBOX_TAG_RELEASE_BUFFER         0x00048001
268
269 struct bcm2835_mbox_tag_release_buffer {
270         struct bcm2835_mbox_tag_hdr tag_hdr;
271         union {
272                 struct {
273                 } req;
274                 struct {
275                 } resp;
276         } body;
277 };
278
279 #define BCM2835_MBOX_TAG_BLANK_SCREEN           0x00040002
280
281 struct bcm2835_mbox_tag_blank_screen {
282         struct bcm2835_mbox_tag_hdr tag_hdr;
283         union {
284                 struct {
285                         /* bit 0 means on, other bots reserved */
286                         u32 state;
287                 } req;
288                 struct {
289                         u32 state;
290                 } resp;
291         } body;
292 };
293
294 /* Physical means output signal */
295 #define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H       0x00040003
296 #define BCM2835_MBOX_TAG_TEST_PHYSICAL_W_H      0x00044003
297 #define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H       0x00048003
298
299 struct bcm2835_mbox_tag_physical_w_h {
300         struct bcm2835_mbox_tag_hdr tag_hdr;
301         union {
302                 /* req not used for get */
303                 struct {
304                         u32 width;
305                         u32 height;
306                 } req;
307                 struct {
308                         u32 width;
309                         u32 height;
310                 } resp;
311         } body;
312 };
313
314 /* Virtual means display buffer */
315 #define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H        0x00040004
316 #define BCM2835_MBOX_TAG_TEST_VIRTUAL_W_H       0x00044004
317 #define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H        0x00048004
318
319 struct bcm2835_mbox_tag_virtual_w_h {
320         struct bcm2835_mbox_tag_hdr tag_hdr;
321         union {
322                 /* req not used for get */
323                 struct {
324                         u32 width;
325                         u32 height;
326                 } req;
327                 struct {
328                         u32 width;
329                         u32 height;
330                 } resp;
331         } body;
332 };
333
334 #define BCM2835_MBOX_TAG_GET_DEPTH              0x00040005
335 #define BCM2835_MBOX_TAG_TEST_DEPTH             0x00044005
336 #define BCM2835_MBOX_TAG_SET_DEPTH              0x00048005
337
338 struct bcm2835_mbox_tag_depth {
339         struct bcm2835_mbox_tag_hdr tag_hdr;
340         union {
341                 /* req not used for get */
342                 struct {
343                         u32 bpp;
344                 } req;
345                 struct {
346                         u32 bpp;
347                 } resp;
348         } body;
349 };
350
351 #define BCM2835_MBOX_TAG_GET_PIXEL_ORDER        0x00040006
352 #define BCM2835_MBOX_TAG_TEST_PIXEL_ORDER       0x00044005
353 #define BCM2835_MBOX_TAG_SET_PIXEL_ORDER        0x00048006
354
355 #define BCM2835_MBOX_PIXEL_ORDER_BGR            0
356 #define BCM2835_MBOX_PIXEL_ORDER_RGB            1
357
358 struct bcm2835_mbox_tag_pixel_order {
359         struct bcm2835_mbox_tag_hdr tag_hdr;
360         union {
361                 /* req not used for get */
362                 struct {
363                         u32 order;
364                 } req;
365                 struct {
366                         u32 order;
367                 } resp;
368         } body;
369 };
370
371 #define BCM2835_MBOX_TAG_GET_ALPHA_MODE         0x00040007
372 #define BCM2835_MBOX_TAG_TEST_ALPHA_MODE        0x00044007
373 #define BCM2835_MBOX_TAG_SET_ALPHA_MODE         0x00048007
374
375 #define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE        0
376 #define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT   1
377 #define BCM2835_MBOX_ALPHA_MODE_IGNORED         2
378
379 struct bcm2835_mbox_tag_alpha_mode {
380         struct bcm2835_mbox_tag_hdr tag_hdr;
381         union {
382                 /* req not used for get */
383                 struct {
384                         u32 alpha;
385                 } req;
386                 struct {
387                         u32 alpha;
388                 } resp;
389         } body;
390 };
391
392 #define BCM2835_MBOX_TAG_GET_PITCH              0x00040008
393
394 struct bcm2835_mbox_tag_pitch {
395         struct bcm2835_mbox_tag_hdr tag_hdr;
396         union {
397                 struct {
398                 } req;
399                 struct {
400                         u32 pitch;
401                 } resp;
402         } body;
403 };
404
405 /* Offset of display window within buffer */
406 #define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET     0x00040009
407 #define BCM2835_MBOX_TAG_TEST_VIRTUAL_OFFSET    0x00044009
408 #define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET     0x00048009
409
410 struct bcm2835_mbox_tag_virtual_offset {
411         struct bcm2835_mbox_tag_hdr tag_hdr;
412         union {
413                 /* req not used for get */
414                 struct {
415                         u32 x;
416                         u32 y;
417                 } req;
418                 struct {
419                         u32 x;
420                         u32 y;
421                 } resp;
422         } body;
423 };
424
425 #define BCM2835_MBOX_TAG_GET_OVERSCAN           0x0004000a
426 #define BCM2835_MBOX_TAG_TEST_OVERSCAN          0x0004400a
427 #define BCM2835_MBOX_TAG_SET_OVERSCAN           0x0004800a
428
429 struct bcm2835_mbox_tag_overscan {
430         struct bcm2835_mbox_tag_hdr tag_hdr;
431         union {
432                 /* req not used for get */
433                 struct {
434                         u32 top;
435                         u32 bottom;
436                         u32 left;
437                         u32 right;
438                 } req;
439                 struct {
440                         u32 top;
441                         u32 bottom;
442                         u32 left;
443                         u32 right;
444                 } resp;
445         } body;
446 };
447
448 #define BCM2835_MBOX_TAG_GET_PALETTE            0x0004000b
449
450 struct bcm2835_mbox_tag_get_palette {
451         struct bcm2835_mbox_tag_hdr tag_hdr;
452         union {
453                 struct {
454                 } req;
455                 struct {
456                         u32 data[1024];
457                 } resp;
458         } body;
459 };
460
461 #define BCM2835_MBOX_TAG_TEST_PALETTE           0x0004400b
462
463 struct bcm2835_mbox_tag_test_palette {
464         struct bcm2835_mbox_tag_hdr tag_hdr;
465         union {
466                 struct {
467                         u32 offset;
468                         u32 num_entries;
469                         u32 data[256];
470                 } req;
471                 struct {
472                         u32 is_invalid;
473                 } resp;
474         } body;
475 };
476
477 #define BCM2835_MBOX_TAG_SET_PALETTE            0x0004800b
478
479 struct bcm2835_mbox_tag_set_palette {
480         struct bcm2835_mbox_tag_hdr tag_hdr;
481         union {
482                 struct {
483                         u32 offset;
484                         u32 num_entries;
485                         u32 data[256];
486                 } req;
487                 struct {
488                         u32 is_invalid;
489                 } resp;
490         } body;
491 };
492
493 /*
494  * Pass a raw u32 message to the VC, and receive a raw u32 back.
495  *
496  * Returns 0 for success, any other value for error.
497  */
498 int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv);
499
500 /*
501  * Pass a complete property-style buffer to the VC, and wait until it has
502  * been processed.
503  *
504  * This function expects a pointer to the mbox_hdr structure in an attempt
505  * to ensure some degree of type safety. However, some number of tags and
506  * a termination value are expected to immediately follow the header in
507  * memory, as required by the property protocol.
508  *
509  * Each struct bcm2835_mbox_hdr passed must be allocated with
510  * ALLOC_CACHE_ALIGN_BUFFER(x, y, z) to ensure proper cache flush/invalidate.
511  *
512  * Returns 0 for success, any other value for error.
513  */
514 int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer);
515
516 #endif