]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/include/asm/arch-bcm2835/mbox.h
ARM: bcm2835: add mailbox driver
[karo-tx-uboot.git] / arch / arm / include / asm / arch-bcm2835 / mbox.h
1 /*
2  * (C) Copyright 2012 Stephen Warren
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  */
17
18 #ifndef _BCM2835_MBOX_H
19 #define _BCM2835_MBOX_H
20
21 #include <linux/compiler.h>
22
23 /*
24  * The BCM2835 SoC contains (at least) two CPUs; the VideoCore (a/k/a "GPU")
25  * and the ARM CPU. The ARM CPU is often thought of as the main CPU.
26  * However, the VideoCore actually controls the initial SoC boot, and hides
27  * much of the hardware behind a protocol. This protocol is transported
28  * using the SoC's mailbox hardware module.
29  *
30  * The mailbox hardware supports passing 32-bit values back and forth.
31  * Presumably by software convention of the firmware, the bottom 4 bits of the
32  * value are used to indicate a logical channel, and the upper 28 bits are the
33  * actual payload. Various channels exist using these simple raw messages. See
34  * https://github.com/raspberrypi/firmware/wiki/Mailboxes for a list. As an
35  * example, the messages on the power management channel are a bitmask of
36  * devices whose power should be enabled.
37  *
38  * The property mailbox channel passes messages that contain the (16-byte
39  * aligned) ARM physical address of a memory buffer. This buffer is passed to
40  * the VC for processing, is modified in-place by the VC, and the address then
41  * passed back to the ARM CPU as the response mailbox message to indicate
42  * request completion. The buffers have a generic and extensible format; each
43  * buffer contains a standard header, a list of "tags", and a terminating zero
44  * entry. Each tag contains an ID indicating its type, and length fields for
45  * generic parsing. With some limitations, an arbitrary set of tags may be
46  * combined together into a single message buffer. This file defines structs
47  * representing the header and many individual tag layouts and IDs.
48  */
49
50 /* Raw mailbox HW */
51
52 #define BCM2835_MBOX_PHYSADDR   0x2000b880
53
54 struct bcm2835_mbox_regs {
55         u32 read;
56         u32 rsvd0[5];
57         u32 status;
58         u32 config;
59         u32 write;
60 };
61
62 #define BCM2835_MBOX_STATUS_WR_FULL     0x80000000
63 #define BCM2835_MBOX_STATUS_RD_EMPTY    0x40000000
64
65 /* Lower 4-bits are channel ID */
66 #define BCM2835_CHAN_MASK               0xf
67 #define BCM2835_MBOX_PACK(chan, data)   (((data) & (~BCM2835_CHAN_MASK)) | \
68                                          (chan & BCM2835_CHAN_MASK))
69 #define BCM2835_MBOX_UNPACK_CHAN(val)   ((val) & BCM2835_CHAN_MASK)
70 #define BCM2835_MBOX_UNPACK_DATA(val)   ((val) & (~BCM2835_CHAN_MASK))
71
72 /* Property mailbox buffer structures */
73
74 #define BCM2835_MBOX_PROP_CHAN          8
75
76 /* All message buffers must start with this header */
77 struct bcm2835_mbox_hdr {
78         u32 buf_size;
79         u32 code;
80 };
81
82 #define BCM2835_MBOX_REQ_CODE           0
83 #define BCM2835_MBOX_RESP_CODE_SUCCESS  0x80000000
84
85 #define BCM2835_MBOX_INIT_HDR(_m_) { \
86                 memset((_m_), 0, sizeof(*(_m_))); \
87                 (_m_)->hdr.buf_size = sizeof(*(_m_)); \
88                 (_m_)->hdr.code = 0; \
89                 (_m_)->end_tag = 0; \
90         }
91
92 /*
93  * A message buffer contains a list of tags. Each tag must also start with
94  * a standardized header.
95  */
96 struct bcm2835_mbox_tag_hdr {
97         u32 tag;
98         u32 val_buf_size;
99         u32 val_len;
100 };
101
102 #define BCM2835_MBOX_INIT_TAG(_t_, _id_) { \
103                 (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
104                 (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
105                 (_t_)->tag_hdr.val_len = sizeof((_t_)->body.req); \
106         }
107
108 #define BCM2835_MBOX_INIT_TAG_NO_REQ(_t_, _id_) { \
109                 (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
110                 (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
111                 (_t_)->tag_hdr.val_len = 0; \
112         }
113
114 /* When responding, the VC sets this bit in val_len to indicate a response */
115 #define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE       0x80000000
116
117 /*
118  * Below we define the ID and struct for many possible tags. This header only
119  * defines individual tag structs, not entire message structs, since in
120  * general an arbitrary set of tags may be combined into a single message.
121  * Clients of the mbox API are expected to define their own overall message
122  * structures by combining the header, a set of tags, and a terminating
123  * entry. For example,
124  *
125  * struct msg {
126  *     struct bcm2835_mbox_hdr hdr;
127  *     struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
128  *     ... perhaps other tags here ...
129  *     u32 end_tag;
130  * };
131  */
132
133 #define BCM2835_MBOX_TAG_GET_ARM_MEMORY         0x00010005
134
135 struct bcm2835_mbox_tag_get_arm_mem {
136         struct bcm2835_mbox_tag_hdr tag_hdr;
137         union {
138                 struct {
139                 } req;
140                 struct {
141                         u32 mem_base;
142                         u32 mem_size;
143                 } resp;
144         } body;
145 };
146
147 #define BCM2835_MBOX_TAG_ALLOCATE_BUFFER        0x00040001
148
149 struct bcm2835_mbox_tag_allocate_buffer {
150         struct bcm2835_mbox_tag_hdr tag_hdr;
151         union {
152                 struct {
153                         u32 alignment;
154                 } req;
155                 struct {
156                         u32 fb_address;
157                         u32 fb_size;
158                 } resp;
159         } body;
160 };
161
162 #define BCM2835_MBOX_TAG_RELEASE_BUFFER         0x00048001
163
164 struct bcm2835_mbox_tag_release_buffer {
165         struct bcm2835_mbox_tag_hdr tag_hdr;
166         union {
167                 struct {
168                 } req;
169                 struct {
170                 } resp;
171         } body;
172 };
173
174 #define BCM2835_MBOX_TAG_BLANK_SCREEN           0x00040002
175
176 struct bcm2835_mbox_tag_blank_screen {
177         struct bcm2835_mbox_tag_hdr tag_hdr;
178         union {
179                 struct {
180                         /* bit 0 means on, other bots reserved */
181                         u32 state;
182                 } req;
183                 struct {
184                         u32 state;
185                 } resp;
186         } body;
187 };
188
189 /* Physical means output signal */
190 #define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H       0x00040003
191 #define BCM2835_MBOX_TAG_TEST_PHYSICAL_W_H      0x00044003
192 #define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H       0x00048003
193
194 struct bcm2835_mbox_tag_physical_w_h {
195         struct bcm2835_mbox_tag_hdr tag_hdr;
196         union {
197                 /* req not used for get */
198                 struct {
199                         u32 width;
200                         u32 height;
201                 } req;
202                 struct {
203                         u32 width;
204                         u32 height;
205                 } resp;
206         } body;
207 };
208
209 /* Virtual means display buffer */
210 #define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H        0x00040004
211 #define BCM2835_MBOX_TAG_TEST_VIRTUAL_W_H       0x00044004
212 #define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H        0x00048004
213
214 struct bcm2835_mbox_tag_virtual_w_h {
215         struct bcm2835_mbox_tag_hdr tag_hdr;
216         union {
217                 /* req not used for get */
218                 struct {
219                         u32 width;
220                         u32 height;
221                 } req;
222                 struct {
223                         u32 width;
224                         u32 height;
225                 } resp;
226         } body;
227 };
228
229 #define BCM2835_MBOX_TAG_GET_DEPTH              0x00040005
230 #define BCM2835_MBOX_TAG_TEST_DEPTH             0x00044005
231 #define BCM2835_MBOX_TAG_SET_DEPTH              0x00048005
232
233 struct bcm2835_mbox_tag_depth {
234         struct bcm2835_mbox_tag_hdr tag_hdr;
235         union {
236                 /* req not used for get */
237                 struct {
238                         u32 bpp;
239                 } req;
240                 struct {
241                         u32 bpp;
242                 } resp;
243         } body;
244 };
245
246 #define BCM2835_MBOX_TAG_GET_PIXEL_ORDER        0x00040006
247 #define BCM2835_MBOX_TAG_TEST_PIXEL_ORDER       0x00044005
248 #define BCM2835_MBOX_TAG_SET_PIXEL_ORDER        0x00048006
249
250 #define BCM2835_MBOX_PIXEL_ORDER_BGR            0
251 #define BCM2835_MBOX_PIXEL_ORDER_RGB            1
252
253 struct bcm2835_mbox_tag_pixel_order {
254         struct bcm2835_mbox_tag_hdr tag_hdr;
255         union {
256                 /* req not used for get */
257                 struct {
258                         u32 order;
259                 } req;
260                 struct {
261                         u32 order;
262                 } resp;
263         } body;
264 };
265
266 #define BCM2835_MBOX_TAG_GET_ALPHA_MODE         0x00040007
267 #define BCM2835_MBOX_TAG_TEST_ALPHA_MODE        0x00044007
268 #define BCM2835_MBOX_TAG_SET_ALPHA_MODE         0x00048007
269
270 #define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE        0
271 #define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT   1
272 #define BCM2835_MBOX_ALPHA_MODE_IGNORED         2
273
274 struct bcm2835_mbox_tag_alpha_mode {
275         struct bcm2835_mbox_tag_hdr tag_hdr;
276         union {
277                 /* req not used for get */
278                 struct {
279                         u32 alpha;
280                 } req;
281                 struct {
282                         u32 alpha;
283                 } resp;
284         } body;
285 };
286
287 #define BCM2835_MBOX_TAG_GET_PITCH              0x00040008
288
289 struct bcm2835_mbox_tag_pitch {
290         struct bcm2835_mbox_tag_hdr tag_hdr;
291         union {
292                 struct {
293                 } req;
294                 struct {
295                         u32 pitch;
296                 } resp;
297         } body;
298 };
299
300 /* Offset of display window within buffer */
301 #define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET     0x00040009
302 #define BCM2835_MBOX_TAG_TEST_VIRTUAL_OFFSET    0x00044009
303 #define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET     0x00048009
304
305 struct bcm2835_mbox_tag_virtual_offset {
306         struct bcm2835_mbox_tag_hdr tag_hdr;
307         union {
308                 /* req not used for get */
309                 struct {
310                         u32 x;
311                         u32 y;
312                 } req;
313                 struct {
314                         u32 x;
315                         u32 y;
316                 } resp;
317         } body;
318 };
319
320 #define BCM2835_MBOX_TAG_GET_OVERSCAN           0x0004000a
321 #define BCM2835_MBOX_TAG_TEST_OVERSCAN          0x0004400a
322 #define BCM2835_MBOX_TAG_SET_OVERSCAN           0x0004800a
323
324 struct bcm2835_mbox_tag_overscan {
325         struct bcm2835_mbox_tag_hdr tag_hdr;
326         union {
327                 /* req not used for get */
328                 struct {
329                         u32 top;
330                         u32 bottom;
331                         u32 left;
332                         u32 right;
333                 } req;
334                 struct {
335                         u32 top;
336                         u32 bottom;
337                         u32 left;
338                 } resp;
339         } body;
340 };
341
342 #define BCM2835_MBOX_TAG_GET_PALETTE            0x0004000b
343
344 struct bcm2835_mbox_tag_get_palette {
345         struct bcm2835_mbox_tag_hdr tag_hdr;
346         union {
347                 struct {
348                 } req;
349                 struct {
350                         u32 data[1024];
351                 } resp;
352         } body;
353 };
354
355 #define BCM2835_MBOX_TAG_TEST_PALETTE           0x0004400b
356
357 struct bcm2835_mbox_tag_test_palette {
358         struct bcm2835_mbox_tag_hdr tag_hdr;
359         union {
360                 struct {
361                         u32 offset;
362                         u32 num_entries;
363                         u32 data[256];
364                 } req;
365                 struct {
366                         u32 is_invalid;
367                 } resp;
368         } body;
369 };
370
371 #define BCM2835_MBOX_TAG_SET_PALETTE            0x0004800b
372
373 struct bcm2835_mbox_tag_set_palette {
374         struct bcm2835_mbox_tag_hdr tag_hdr;
375         union {
376                 struct {
377                         u32 offset;
378                         u32 num_entries;
379                         u32 data[256];
380                 } req;
381                 struct {
382                         u32 is_invalid;
383                 } resp;
384         } body;
385 };
386
387 /*
388  * Pass a raw u32 message to the VC, and receive a raw u32 back.
389  *
390  * Returns 0 for success, any other value for error.
391  */
392 int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv);
393
394 /*
395  * Pass a complete property-style buffer to the VC, and wait until it has
396  * been processed.
397  *
398  * This function expects a pointer to the mbox_hdr structure in an attempt
399  * to ensure some degree of type safety. However, some number of tags and
400  * a termination value are expected to immediately follow the header in
401  * memory, as required by the property protocol.
402  *
403  * Returns 0 for success, any other value for error.
404  */
405 int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer);
406
407 #endif