blob: af94dff2ac639f11303a349f8afad0413e10e60b [file] [log] [blame]
Stephen Warren91ea2882013-01-29 16:37:36 +00001/*
Stephen Warren8780f222015-02-16 12:16:14 -07002 * (C) Copyright 2012,2015 Stephen Warren
Stephen Warren91ea2882013-01-29 16:37:36 +00003 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
Stephen Warren91ea2882013-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 Warren8780f222015-02-16 12:16:14 -070041#ifdef CONFIG_BCM2836
42#define BCM2835_MBOX_PHYSADDR 0x3f00b880
43#else
Stephen Warren91ea2882013-01-29 16:37:36 +000044#define BCM2835_MBOX_PHYSADDR 0x2000b880
Stephen Warren8780f222015-02-16 12:16:14 -070045#endif
Stephen Warren91ea2882013-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 Warrencd210c12014-11-18 21:40:21 -0700126#define BCM2835_MBOX_TAG_GET_BOARD_REV 0x00010002
127
Stephen Warrencd210c12014-11-18 21:40:21 -0700128struct 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
Stephen Warrenaf6e20d2014-09-26 20:51:39 -0600139#define BCM2835_MBOX_TAG_GET_MAC_ADDRESS 0x00010003
140
141struct 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
Stephen Warren91ea2882013-01-29 16:37:36 +0000153#define BCM2835_MBOX_TAG_GET_ARM_MEMORY 0x00010005
154
155struct bcm2835_mbox_tag_get_arm_mem {
156 struct bcm2835_mbox_tag_hdr tag_hdr;
157 union {
158 struct {
159 } req;
160 struct {
161 u32 mem_base;
162 u32 mem_size;
163 } resp;
164 } body;
165};
166
Stephen Warren8672d202014-01-13 19:50:11 -0700167#define BCM2835_MBOX_POWER_DEVID_SDHCI 0
168#define BCM2835_MBOX_POWER_DEVID_UART0 1
169#define BCM2835_MBOX_POWER_DEVID_UART1 2
170#define BCM2835_MBOX_POWER_DEVID_USB_HCD 3
171#define BCM2835_MBOX_POWER_DEVID_I2C0 4
172#define BCM2835_MBOX_POWER_DEVID_I2C1 5
173#define BCM2835_MBOX_POWER_DEVID_I2C2 6
174#define BCM2835_MBOX_POWER_DEVID_SPI 7
175#define BCM2835_MBOX_POWER_DEVID_CCP2TX 8
176
Stephen Warren41523682014-02-05 20:42:25 -0700177#define BCM2835_MBOX_POWER_STATE_RESP_ON (1 << 0)
Stephen Warren8672d202014-01-13 19:50:11 -0700178/* Device doesn't exist */
179#define BCM2835_MBOX_POWER_STATE_RESP_NODEV (1 << 1)
180
181#define BCM2835_MBOX_TAG_GET_POWER_STATE 0x00020001
182
183struct bcm2835_mbox_tag_get_power_state {
184 struct bcm2835_mbox_tag_hdr tag_hdr;
185 union {
186 struct {
187 u32 device_id;
188 } req;
189 struct {
190 u32 device_id;
191 u32 state;
192 } resp;
193 } body;
194};
195
196#define BCM2835_MBOX_TAG_SET_POWER_STATE 0x00028001
197
198#define BCM2835_MBOX_SET_POWER_STATE_REQ_ON (1 << 0)
199#define BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT (1 << 1)
200
201struct bcm2835_mbox_tag_set_power_state {
202 struct bcm2835_mbox_tag_hdr tag_hdr;
203 union {
204 struct {
205 u32 device_id;
206 u32 state;
207 } req;
208 struct {
209 u32 device_id;
210 u32 state;
211 } resp;
212 } body;
213};
214
Stephen Warrenc4ab9712013-01-29 16:37:42 +0000215#define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002
216
217#define BCM2835_MBOX_CLOCK_ID_EMMC 1
218#define BCM2835_MBOX_CLOCK_ID_UART 2
219#define BCM2835_MBOX_CLOCK_ID_ARM 3
220#define BCM2835_MBOX_CLOCK_ID_CORE 4
221#define BCM2835_MBOX_CLOCK_ID_V3D 5
222#define BCM2835_MBOX_CLOCK_ID_H264 6
223#define BCM2835_MBOX_CLOCK_ID_ISP 7
224#define BCM2835_MBOX_CLOCK_ID_SDRAM 8
225#define BCM2835_MBOX_CLOCK_ID_PIXEL 9
226#define BCM2835_MBOX_CLOCK_ID_PWM 10
227
228struct bcm2835_mbox_tag_get_clock_rate {
229 struct bcm2835_mbox_tag_hdr tag_hdr;
230 union {
231 struct {
232 u32 clock_id;
233 } req;
234 struct {
235 u32 clock_id;
236 u32 rate_hz;
237 } resp;
238 } body;
239};
240
Stephen Warren91ea2882013-01-29 16:37:36 +0000241#define BCM2835_MBOX_TAG_ALLOCATE_BUFFER 0x00040001
242
243struct bcm2835_mbox_tag_allocate_buffer {
244 struct bcm2835_mbox_tag_hdr tag_hdr;
245 union {
246 struct {
247 u32 alignment;
248 } req;
249 struct {
250 u32 fb_address;
251 u32 fb_size;
252 } resp;
253 } body;
254};
255
256#define BCM2835_MBOX_TAG_RELEASE_BUFFER 0x00048001
257
258struct bcm2835_mbox_tag_release_buffer {
259 struct bcm2835_mbox_tag_hdr tag_hdr;
260 union {
261 struct {
262 } req;
263 struct {
264 } resp;
265 } body;
266};
267
268#define BCM2835_MBOX_TAG_BLANK_SCREEN 0x00040002
269
270struct bcm2835_mbox_tag_blank_screen {
271 struct bcm2835_mbox_tag_hdr tag_hdr;
272 union {
273 struct {
274 /* bit 0 means on, other bots reserved */
275 u32 state;
276 } req;
277 struct {
278 u32 state;
279 } resp;
280 } body;
281};
282
283/* Physical means output signal */
284#define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H 0x00040003
285#define BCM2835_MBOX_TAG_TEST_PHYSICAL_W_H 0x00044003
286#define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H 0x00048003
287
288struct bcm2835_mbox_tag_physical_w_h {
289 struct bcm2835_mbox_tag_hdr tag_hdr;
290 union {
291 /* req not used for get */
292 struct {
293 u32 width;
294 u32 height;
295 } req;
296 struct {
297 u32 width;
298 u32 height;
299 } resp;
300 } body;
301};
302
303/* Virtual means display buffer */
304#define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H 0x00040004
305#define BCM2835_MBOX_TAG_TEST_VIRTUAL_W_H 0x00044004
306#define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H 0x00048004
307
308struct bcm2835_mbox_tag_virtual_w_h {
309 struct bcm2835_mbox_tag_hdr tag_hdr;
310 union {
311 /* req not used for get */
312 struct {
313 u32 width;
314 u32 height;
315 } req;
316 struct {
317 u32 width;
318 u32 height;
319 } resp;
320 } body;
321};
322
323#define BCM2835_MBOX_TAG_GET_DEPTH 0x00040005
324#define BCM2835_MBOX_TAG_TEST_DEPTH 0x00044005
325#define BCM2835_MBOX_TAG_SET_DEPTH 0x00048005
326
327struct bcm2835_mbox_tag_depth {
328 struct bcm2835_mbox_tag_hdr tag_hdr;
329 union {
330 /* req not used for get */
331 struct {
332 u32 bpp;
333 } req;
334 struct {
335 u32 bpp;
336 } resp;
337 } body;
338};
339
340#define BCM2835_MBOX_TAG_GET_PIXEL_ORDER 0x00040006
341#define BCM2835_MBOX_TAG_TEST_PIXEL_ORDER 0x00044005
342#define BCM2835_MBOX_TAG_SET_PIXEL_ORDER 0x00048006
343
344#define BCM2835_MBOX_PIXEL_ORDER_BGR 0
345#define BCM2835_MBOX_PIXEL_ORDER_RGB 1
346
347struct bcm2835_mbox_tag_pixel_order {
348 struct bcm2835_mbox_tag_hdr tag_hdr;
349 union {
350 /* req not used for get */
351 struct {
352 u32 order;
353 } req;
354 struct {
355 u32 order;
356 } resp;
357 } body;
358};
359
360#define BCM2835_MBOX_TAG_GET_ALPHA_MODE 0x00040007
361#define BCM2835_MBOX_TAG_TEST_ALPHA_MODE 0x00044007
362#define BCM2835_MBOX_TAG_SET_ALPHA_MODE 0x00048007
363
364#define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE 0
365#define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT 1
366#define BCM2835_MBOX_ALPHA_MODE_IGNORED 2
367
368struct bcm2835_mbox_tag_alpha_mode {
369 struct bcm2835_mbox_tag_hdr tag_hdr;
370 union {
371 /* req not used for get */
372 struct {
373 u32 alpha;
374 } req;
375 struct {
376 u32 alpha;
377 } resp;
378 } body;
379};
380
381#define BCM2835_MBOX_TAG_GET_PITCH 0x00040008
382
383struct bcm2835_mbox_tag_pitch {
384 struct bcm2835_mbox_tag_hdr tag_hdr;
385 union {
386 struct {
387 } req;
388 struct {
389 u32 pitch;
390 } resp;
391 } body;
392};
393
394/* Offset of display window within buffer */
395#define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET 0x00040009
396#define BCM2835_MBOX_TAG_TEST_VIRTUAL_OFFSET 0x00044009
397#define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET 0x00048009
398
399struct bcm2835_mbox_tag_virtual_offset {
400 struct bcm2835_mbox_tag_hdr tag_hdr;
401 union {
402 /* req not used for get */
403 struct {
404 u32 x;
405 u32 y;
406 } req;
407 struct {
408 u32 x;
409 u32 y;
410 } resp;
411 } body;
412};
413
414#define BCM2835_MBOX_TAG_GET_OVERSCAN 0x0004000a
415#define BCM2835_MBOX_TAG_TEST_OVERSCAN 0x0004400a
416#define BCM2835_MBOX_TAG_SET_OVERSCAN 0x0004800a
417
418struct bcm2835_mbox_tag_overscan {
419 struct bcm2835_mbox_tag_hdr tag_hdr;
420 union {
421 /* req not used for get */
422 struct {
423 u32 top;
424 u32 bottom;
425 u32 left;
426 u32 right;
427 } req;
428 struct {
429 u32 top;
430 u32 bottom;
431 u32 left;
Andre Heider952ad9e2013-10-22 22:27:20 +0200432 u32 right;
Stephen Warren91ea2882013-01-29 16:37:36 +0000433 } resp;
434 } body;
435};
436
437#define BCM2835_MBOX_TAG_GET_PALETTE 0x0004000b
438
439struct bcm2835_mbox_tag_get_palette {
440 struct bcm2835_mbox_tag_hdr tag_hdr;
441 union {
442 struct {
443 } req;
444 struct {
445 u32 data[1024];
446 } resp;
447 } body;
448};
449
450#define BCM2835_MBOX_TAG_TEST_PALETTE 0x0004400b
451
452struct bcm2835_mbox_tag_test_palette {
453 struct bcm2835_mbox_tag_hdr tag_hdr;
454 union {
455 struct {
456 u32 offset;
457 u32 num_entries;
458 u32 data[256];
459 } req;
460 struct {
461 u32 is_invalid;
462 } resp;
463 } body;
464};
465
466#define BCM2835_MBOX_TAG_SET_PALETTE 0x0004800b
467
468struct bcm2835_mbox_tag_set_palette {
469 struct bcm2835_mbox_tag_hdr tag_hdr;
470 union {
471 struct {
472 u32 offset;
473 u32 num_entries;
474 u32 data[256];
475 } req;
476 struct {
477 u32 is_invalid;
478 } resp;
479 } body;
480};
481
482/*
483 * Pass a raw u32 message to the VC, and receive a raw u32 back.
484 *
485 * Returns 0 for success, any other value for error.
486 */
487int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv);
488
489/*
490 * Pass a complete property-style buffer to the VC, and wait until it has
491 * been processed.
492 *
493 * This function expects a pointer to the mbox_hdr structure in an attempt
494 * to ensure some degree of type safety. However, some number of tags and
495 * a termination value are expected to immediately follow the header in
496 * memory, as required by the property protocol.
497 *
Alexander Steinfbeb89d2015-07-24 09:22:13 +0200498 * Each struct bcm2835_mbox_hdr passed must be allocated with
499 * ALLOC_CACHE_ALIGN_BUFFER(x, y, z) to ensure proper cache flush/invalidate.
500 *
Stephen Warren91ea2882013-01-29 16:37:36 +0000501 * Returns 0 for success, any other value for error.
502 */
503int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer);
504
505#endif