blob: 9260ee2df76c245ad1952064a55527d7940bea4e [file] [log] [blame]
Stephen Warren88077282013-01-29 16:37:36 +00001/*
Stephen Warrendb753562015-02-16 12:16:14 -07002 * (C) Copyright 2012,2015 Stephen Warren
Stephen Warren88077282013-01-29 16:37:36 +00003 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
Stephen Warren88077282013-01-29 16:37:36 +00005 */
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
Stephen Warrendb753562015-02-16 12:16:14 -070041#ifdef CONFIG_BCM2836
42#define BCM2835_MBOX_PHYSADDR 0x3f00b880
43#else
Stephen Warren88077282013-01-29 16:37:36 +000044#define BCM2835_MBOX_PHYSADDR 0x2000b880
Stephen Warrendb753562015-02-16 12:16:14 -070045#endif
Stephen Warren88077282013-01-29 16:37:36 +000046
47struct 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 */
70struct 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 */
89struct 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
Stephen Warren6fe78452014-11-18 21:40:21 -0700126#define BCM2835_MBOX_TAG_GET_BOARD_REV 0x00010002
127
Stephen Warren46414292015-02-16 12:16:15 -0700128#ifdef CONFIG_BCM2836
129#define BCM2836_BOARD_REV_2_B 0x4
130#else
Stephen Warren6fe78452014-11-18 21:40:21 -0700131/*
132 * 0x2..0xf from:
133 * http://raspberryalphaomega.org.uk/2013/02/06/automatic-raspberry-pi-board-revision-detection-model-a-b1-and-b2/
134 * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=32733
Stephen Warren787affb2015-04-12 21:43:25 -0600135 * http://git.drogon.net/?p=wiringPi;a=blob_plain;f=wiringPi/wiringPi.c;hb=5edd177112c99416f68ba3e8c6c4db6ed942e796
Stephen Warren6fe78452014-11-18 21:40:21 -0700136 */
137#define BCM2835_BOARD_REV_B_I2C0_2 0x2
138#define BCM2835_BOARD_REV_B_I2C0_3 0x3
139#define BCM2835_BOARD_REV_B_I2C1_4 0x4
140#define BCM2835_BOARD_REV_B_I2C1_5 0x5
141#define BCM2835_BOARD_REV_B_I2C1_6 0x6
142#define BCM2835_BOARD_REV_A_7 0x7
143#define BCM2835_BOARD_REV_A_8 0x8
144#define BCM2835_BOARD_REV_A_9 0x9
145#define BCM2835_BOARD_REV_B_REV2_d 0xd
146#define BCM2835_BOARD_REV_B_REV2_e 0xe
147#define BCM2835_BOARD_REV_B_REV2_f 0xf
148#define BCM2835_BOARD_REV_B_PLUS 0x10
149#define BCM2835_BOARD_REV_CM 0x11
Stephen Warren47705ef2014-12-23 20:01:43 -0700150#define BCM2835_BOARD_REV_A_PLUS 0x12
Stephen Warren787affb2015-04-12 21:43:25 -0600151#define BCM2835_BOARD_REV_B_PLUS_13 0x13
152#define BCM2835_BOARD_REV_CM_14 0x14
Lubomir Rintel79ad5ce2015-10-14 17:17:54 +0200153#define BCM2835_BOARD_REV_A_PLUS_15 0x15
Stephen Warren46414292015-02-16 12:16:15 -0700154#endif
Stephen Warren6fe78452014-11-18 21:40:21 -0700155
156struct bcm2835_mbox_tag_get_board_rev {
157 struct bcm2835_mbox_tag_hdr tag_hdr;
158 union {
159 struct {
160 } req;
161 struct {
162 u32 rev;
163 } resp;
164 } body;
165};
166
Stephen Warren4f80a062014-09-26 20:51:39 -0600167#define BCM2835_MBOX_TAG_GET_MAC_ADDRESS 0x00010003
168
169struct bcm2835_mbox_tag_get_mac_address {
170 struct bcm2835_mbox_tag_hdr tag_hdr;
171 union {
172 struct {
173 } req;
174 struct {
175 u8 mac[6];
176 u8 pad[2];
177 } resp;
178 } body;
179};
180
Stephen Warren88077282013-01-29 16:37:36 +0000181#define BCM2835_MBOX_TAG_GET_ARM_MEMORY 0x00010005
182
183struct bcm2835_mbox_tag_get_arm_mem {
184 struct bcm2835_mbox_tag_hdr tag_hdr;
185 union {
186 struct {
187 } req;
188 struct {
189 u32 mem_base;
190 u32 mem_size;
191 } resp;
192 } body;
193};
194
Stephen Warrenf66f2aa2014-01-13 19:50:11 -0700195#define BCM2835_MBOX_POWER_DEVID_SDHCI 0
196#define BCM2835_MBOX_POWER_DEVID_UART0 1
197#define BCM2835_MBOX_POWER_DEVID_UART1 2
198#define BCM2835_MBOX_POWER_DEVID_USB_HCD 3
199#define BCM2835_MBOX_POWER_DEVID_I2C0 4
200#define BCM2835_MBOX_POWER_DEVID_I2C1 5
201#define BCM2835_MBOX_POWER_DEVID_I2C2 6
202#define BCM2835_MBOX_POWER_DEVID_SPI 7
203#define BCM2835_MBOX_POWER_DEVID_CCP2TX 8
204
Stephen Warren5e77a742014-02-05 20:42:25 -0700205#define BCM2835_MBOX_POWER_STATE_RESP_ON (1 << 0)
Stephen Warrenf66f2aa2014-01-13 19:50:11 -0700206/* Device doesn't exist */
207#define BCM2835_MBOX_POWER_STATE_RESP_NODEV (1 << 1)
208
209#define BCM2835_MBOX_TAG_GET_POWER_STATE 0x00020001
210
211struct bcm2835_mbox_tag_get_power_state {
212 struct bcm2835_mbox_tag_hdr tag_hdr;
213 union {
214 struct {
215 u32 device_id;
216 } req;
217 struct {
218 u32 device_id;
219 u32 state;
220 } resp;
221 } body;
222};
223
224#define BCM2835_MBOX_TAG_SET_POWER_STATE 0x00028001
225
226#define BCM2835_MBOX_SET_POWER_STATE_REQ_ON (1 << 0)
227#define BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT (1 << 1)
228
229struct bcm2835_mbox_tag_set_power_state {
230 struct bcm2835_mbox_tag_hdr tag_hdr;
231 union {
232 struct {
233 u32 device_id;
234 u32 state;
235 } req;
236 struct {
237 u32 device_id;
238 u32 state;
239 } resp;
240 } body;
241};
242
Stephen Warren131a1e62013-01-29 16:37:42 +0000243#define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002
244
245#define BCM2835_MBOX_CLOCK_ID_EMMC 1
246#define BCM2835_MBOX_CLOCK_ID_UART 2
247#define BCM2835_MBOX_CLOCK_ID_ARM 3
248#define BCM2835_MBOX_CLOCK_ID_CORE 4
249#define BCM2835_MBOX_CLOCK_ID_V3D 5
250#define BCM2835_MBOX_CLOCK_ID_H264 6
251#define BCM2835_MBOX_CLOCK_ID_ISP 7
252#define BCM2835_MBOX_CLOCK_ID_SDRAM 8
253#define BCM2835_MBOX_CLOCK_ID_PIXEL 9
254#define BCM2835_MBOX_CLOCK_ID_PWM 10
255
256struct bcm2835_mbox_tag_get_clock_rate {
257 struct bcm2835_mbox_tag_hdr tag_hdr;
258 union {
259 struct {
260 u32 clock_id;
261 } req;
262 struct {
263 u32 clock_id;
264 u32 rate_hz;
265 } resp;
266 } body;
267};
268
Stephen Warren88077282013-01-29 16:37:36 +0000269#define BCM2835_MBOX_TAG_ALLOCATE_BUFFER 0x00040001
270
271struct bcm2835_mbox_tag_allocate_buffer {
272 struct bcm2835_mbox_tag_hdr tag_hdr;
273 union {
274 struct {
275 u32 alignment;
276 } req;
277 struct {
278 u32 fb_address;
279 u32 fb_size;
280 } resp;
281 } body;
282};
283
284#define BCM2835_MBOX_TAG_RELEASE_BUFFER 0x00048001
285
286struct bcm2835_mbox_tag_release_buffer {
287 struct bcm2835_mbox_tag_hdr tag_hdr;
288 union {
289 struct {
290 } req;
291 struct {
292 } resp;
293 } body;
294};
295
296#define BCM2835_MBOX_TAG_BLANK_SCREEN 0x00040002
297
298struct bcm2835_mbox_tag_blank_screen {
299 struct bcm2835_mbox_tag_hdr tag_hdr;
300 union {
301 struct {
302 /* bit 0 means on, other bots reserved */
303 u32 state;
304 } req;
305 struct {
306 u32 state;
307 } resp;
308 } body;
309};
310
311/* Physical means output signal */
312#define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H 0x00040003
313#define BCM2835_MBOX_TAG_TEST_PHYSICAL_W_H 0x00044003
314#define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H 0x00048003
315
316struct bcm2835_mbox_tag_physical_w_h {
317 struct bcm2835_mbox_tag_hdr tag_hdr;
318 union {
319 /* req not used for get */
320 struct {
321 u32 width;
322 u32 height;
323 } req;
324 struct {
325 u32 width;
326 u32 height;
327 } resp;
328 } body;
329};
330
331/* Virtual means display buffer */
332#define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H 0x00040004
333#define BCM2835_MBOX_TAG_TEST_VIRTUAL_W_H 0x00044004
334#define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H 0x00048004
335
336struct bcm2835_mbox_tag_virtual_w_h {
337 struct bcm2835_mbox_tag_hdr tag_hdr;
338 union {
339 /* req not used for get */
340 struct {
341 u32 width;
342 u32 height;
343 } req;
344 struct {
345 u32 width;
346 u32 height;
347 } resp;
348 } body;
349};
350
351#define BCM2835_MBOX_TAG_GET_DEPTH 0x00040005
352#define BCM2835_MBOX_TAG_TEST_DEPTH 0x00044005
353#define BCM2835_MBOX_TAG_SET_DEPTH 0x00048005
354
355struct bcm2835_mbox_tag_depth {
356 struct bcm2835_mbox_tag_hdr tag_hdr;
357 union {
358 /* req not used for get */
359 struct {
360 u32 bpp;
361 } req;
362 struct {
363 u32 bpp;
364 } resp;
365 } body;
366};
367
368#define BCM2835_MBOX_TAG_GET_PIXEL_ORDER 0x00040006
369#define BCM2835_MBOX_TAG_TEST_PIXEL_ORDER 0x00044005
370#define BCM2835_MBOX_TAG_SET_PIXEL_ORDER 0x00048006
371
372#define BCM2835_MBOX_PIXEL_ORDER_BGR 0
373#define BCM2835_MBOX_PIXEL_ORDER_RGB 1
374
375struct bcm2835_mbox_tag_pixel_order {
376 struct bcm2835_mbox_tag_hdr tag_hdr;
377 union {
378 /* req not used for get */
379 struct {
380 u32 order;
381 } req;
382 struct {
383 u32 order;
384 } resp;
385 } body;
386};
387
388#define BCM2835_MBOX_TAG_GET_ALPHA_MODE 0x00040007
389#define BCM2835_MBOX_TAG_TEST_ALPHA_MODE 0x00044007
390#define BCM2835_MBOX_TAG_SET_ALPHA_MODE 0x00048007
391
392#define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE 0
393#define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT 1
394#define BCM2835_MBOX_ALPHA_MODE_IGNORED 2
395
396struct bcm2835_mbox_tag_alpha_mode {
397 struct bcm2835_mbox_tag_hdr tag_hdr;
398 union {
399 /* req not used for get */
400 struct {
401 u32 alpha;
402 } req;
403 struct {
404 u32 alpha;
405 } resp;
406 } body;
407};
408
409#define BCM2835_MBOX_TAG_GET_PITCH 0x00040008
410
411struct bcm2835_mbox_tag_pitch {
412 struct bcm2835_mbox_tag_hdr tag_hdr;
413 union {
414 struct {
415 } req;
416 struct {
417 u32 pitch;
418 } resp;
419 } body;
420};
421
422/* Offset of display window within buffer */
423#define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET 0x00040009
424#define BCM2835_MBOX_TAG_TEST_VIRTUAL_OFFSET 0x00044009
425#define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET 0x00048009
426
427struct bcm2835_mbox_tag_virtual_offset {
428 struct bcm2835_mbox_tag_hdr tag_hdr;
429 union {
430 /* req not used for get */
431 struct {
432 u32 x;
433 u32 y;
434 } req;
435 struct {
436 u32 x;
437 u32 y;
438 } resp;
439 } body;
440};
441
442#define BCM2835_MBOX_TAG_GET_OVERSCAN 0x0004000a
443#define BCM2835_MBOX_TAG_TEST_OVERSCAN 0x0004400a
444#define BCM2835_MBOX_TAG_SET_OVERSCAN 0x0004800a
445
446struct bcm2835_mbox_tag_overscan {
447 struct bcm2835_mbox_tag_hdr tag_hdr;
448 union {
449 /* req not used for get */
450 struct {
451 u32 top;
452 u32 bottom;
453 u32 left;
454 u32 right;
455 } req;
456 struct {
457 u32 top;
458 u32 bottom;
459 u32 left;
Andre Heidere2788af2013-10-22 22:27:20 +0200460 u32 right;
Stephen Warren88077282013-01-29 16:37:36 +0000461 } resp;
462 } body;
463};
464
465#define BCM2835_MBOX_TAG_GET_PALETTE 0x0004000b
466
467struct bcm2835_mbox_tag_get_palette {
468 struct bcm2835_mbox_tag_hdr tag_hdr;
469 union {
470 struct {
471 } req;
472 struct {
473 u32 data[1024];
474 } resp;
475 } body;
476};
477
478#define BCM2835_MBOX_TAG_TEST_PALETTE 0x0004400b
479
480struct bcm2835_mbox_tag_test_palette {
481 struct bcm2835_mbox_tag_hdr tag_hdr;
482 union {
483 struct {
484 u32 offset;
485 u32 num_entries;
486 u32 data[256];
487 } req;
488 struct {
489 u32 is_invalid;
490 } resp;
491 } body;
492};
493
494#define BCM2835_MBOX_TAG_SET_PALETTE 0x0004800b
495
496struct bcm2835_mbox_tag_set_palette {
497 struct bcm2835_mbox_tag_hdr tag_hdr;
498 union {
499 struct {
500 u32 offset;
501 u32 num_entries;
502 u32 data[256];
503 } req;
504 struct {
505 u32 is_invalid;
506 } resp;
507 } body;
508};
509
510/*
511 * Pass a raw u32 message to the VC, and receive a raw u32 back.
512 *
513 * Returns 0 for success, any other value for error.
514 */
515int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv);
516
517/*
518 * Pass a complete property-style buffer to the VC, and wait until it has
519 * been processed.
520 *
521 * This function expects a pointer to the mbox_hdr structure in an attempt
522 * to ensure some degree of type safety. However, some number of tags and
523 * a termination value are expected to immediately follow the header in
524 * memory, as required by the property protocol.
525 *
Alexander Stein4342557f2015-07-24 09:22:13 +0200526 * Each struct bcm2835_mbox_hdr passed must be allocated with
527 * ALLOC_CACHE_ALIGN_BUFFER(x, y, z) to ensure proper cache flush/invalidate.
528 *
Stephen Warren88077282013-01-29 16:37:36 +0000529 * Returns 0 for success, any other value for error.
530 */
531int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer);
532
533#endif