1 /*-
2  * Copyright (C) 2013-2014 Daisuke Aoyama <aoyama@peach.ne.jp>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #ifndef _BCM2835_MBOX_PROP_H_
28 #define _BCM2835_MBOX_PROP_H_
29 
30 #include <sys/types.h>
31 
32 /*
33  * Mailbox property interface:
34  * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
35  */
36 #define BCM2835_MBOX_CODE_REQ			0
37 #define BCM2835_MBOX_CODE_RESP_SUCCESS		0x80000000
38 #define BCM2835_MBOX_CODE_RESP_ERROR		0x80000001
39 #define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE	0x80000000
40 
41 struct bcm2835_mbox_hdr {
42 	uint32_t	buf_size;
43 	uint32_t	code;
44 };
45 
46 struct bcm2835_mbox_tag_hdr {
47 	uint32_t	tag;
48 	uint32_t	val_buf_size;
49 	uint32_t	val_len;
50 };
51 
52 #define	BCM2835_MBOX_INIT_TAG(tag_, tagid_) do {		\
53 	(tag_)->tag_hdr.tag = BCM2835_MBOX_TAG_##tagid_;	\
54 	(tag_)->tag_hdr.val_buf_size = sizeof((tag_)->body);	\
55 	(tag_)->tag_hdr.val_len = sizeof((tag_)->body.req);	\
56 } while (0)
57 
58 #define BCM2835_MBOX_TAG_FIRMWARE_REVISION	0x00000001
59 
60 #define BCM2835_MBOX_POWER_ID_EMMC		0x00000000
61 #define BCM2835_MBOX_POWER_ID_UART0		0x00000001
62 #define BCM2835_MBOX_POWER_ID_UART1		0x00000002
63 #define BCM2835_MBOX_POWER_ID_USB_HCD		0x00000003
64 #define BCM2835_MBOX_POWER_ID_I2C0		0x00000004
65 #define BCM2835_MBOX_POWER_ID_I2C1		0x00000005
66 #define BCM2835_MBOX_POWER_ID_I2C2		0x00000006
67 #define BCM2835_MBOX_POWER_ID_SPI		0x00000007
68 #define BCM2835_MBOX_POWER_ID_CCP2TX		0x00000008
69 
70 #define BCM2835_MBOX_POWER_ON			(1 << 0)
71 #define BCM2835_MBOX_POWER_WAIT			(1 << 1)
72 
73 #define BCM2835_MBOX_TAG_GET_POWER_STATE	0x00020001
74 #define BCM2835_MBOX_TAG_SET_POWER_STATE	0x00028001
75 
76 struct msg_get_power_state {
77 	struct bcm2835_mbox_hdr hdr;
78 	struct bcm2835_mbox_tag_hdr tag_hdr;
79 	union {
80 		struct {
81 			uint32_t device_id;
82 		} req;
83 		struct {
84 			uint32_t device_id;
85 			uint32_t state;
86 		} resp;
87 	} body;
88 	uint32_t end_tag;
89 };
90 
91 struct msg_set_power_state {
92 	struct bcm2835_mbox_hdr hdr;
93 	struct bcm2835_mbox_tag_hdr tag_hdr;
94 	union {
95 		struct {
96 			uint32_t device_id;
97 			uint32_t state;
98 		} req;
99 		struct {
100 			uint32_t device_id;
101 			uint32_t state;
102 		} resp;
103 	} body;
104 	uint32_t end_tag;
105 };
106 
107 /* Sets the power state for a given device */
108 int bcm2835_mbox_set_power_state(uint32_t, boolean_t);
109 
110 #define BCM2835_MBOX_TAG_NOTIFY_XHCI_RESET	0x00030058
111 
112 struct msg_notify_xhci_reset {
113 	struct bcm2835_mbox_hdr hdr;
114 	struct bcm2835_mbox_tag_hdr tag_hdr;
115 	union {
116 		struct {
117 			uint32_t pci_device_addr;
118 		} req;
119 		struct {
120 		} resp;
121 	} body;
122 	uint32_t end_tag;
123 };
124 
125 /* Prompts the VideoCore processor to reload the xhci firmware. */
126 int bcm2835_mbox_notify_xhci_reset(uint32_t);
127 
128 #define BCM2835_MBOX_CLOCK_ID_EMMC		0x00000001
129 #define BCM2838_MBOX_CLOCK_ID_EMMC2		0x0000000c
130 
131 #define BCM2835_MBOX_TAG_GET_CLOCK_RATE		0x00030002
132 
133 struct msg_get_clock_rate {
134 	struct bcm2835_mbox_hdr hdr;
135 	struct bcm2835_mbox_tag_hdr tag_hdr;
136 	union {
137 		struct {
138 			uint32_t clock_id;
139 		} req;
140 		struct {
141 			uint32_t clock_id;
142 			uint32_t rate_hz;
143 		} resp;
144 	} body;
145 	uint32_t end_tag;
146 };
147 
148 int bcm2835_mbox_get_clock_rate(uint32_t, uint32_t *);
149 
150 #define BCM2835_MBOX_TURBO_ON			1
151 #define BCM2835_MBOX_TURBO_OFF			0
152 
153 #define BCM2835_MBOX_TAG_GET_TURBO		0x00030009
154 #define BCM2835_MBOX_TAG_SET_TURBO		0x00038009
155 
156 struct msg_get_turbo {
157 	struct bcm2835_mbox_hdr hdr;
158 	struct bcm2835_mbox_tag_hdr tag_hdr;
159 	union {
160 		struct {
161 			uint32_t id;
162 		} req;
163 		struct {
164 			uint32_t id;
165 			uint32_t level;
166 		} resp;
167 	} body;
168 	uint32_t end_tag;
169 };
170 
171 struct msg_set_turbo {
172 	struct bcm2835_mbox_hdr hdr;
173 	struct bcm2835_mbox_tag_hdr tag_hdr;
174 	union {
175 		struct {
176 			uint32_t id;
177 			uint32_t level;
178 		} req;
179 		struct {
180 			uint32_t id;
181 			uint32_t level;
182 		} resp;
183 	} body;
184 	uint32_t end_tag;
185 };
186 
187 #define BCM2835_MBOX_VOLTAGE_ID_CORE		0x00000001
188 #define BCM2835_MBOX_VOLTAGE_ID_SDRAM_C		0x00000002
189 #define BCM2835_MBOX_VOLTAGE_ID_SDRAM_P		0x00000003
190 #define BCM2835_MBOX_VOLTAGE_ID_SDRAM_I		0x00000004
191 
192 #define BCM2835_MBOX_TAG_GET_VOLTAGE		0x00030003
193 #define BCM2835_MBOX_TAG_SET_VOLTAGE		0x00038003
194 #define BCM2835_MBOX_TAG_GET_MAX_VOLTAGE	0x00030005
195 #define BCM2835_MBOX_TAG_GET_MIN_VOLTAGE	0x00030008
196 
197 struct msg_get_voltage {
198 	struct bcm2835_mbox_hdr hdr;
199 	struct bcm2835_mbox_tag_hdr tag_hdr;
200 	union {
201 		struct {
202 			uint32_t voltage_id;
203 		} req;
204 		struct {
205 			uint32_t voltage_id;
206 			uint32_t value;
207 		} resp;
208 	} body;
209 	uint32_t end_tag;
210 };
211 
212 struct msg_set_voltage {
213 	struct bcm2835_mbox_hdr hdr;
214 	struct bcm2835_mbox_tag_hdr tag_hdr;
215 	union {
216 		struct {
217 			uint32_t voltage_id;
218 			uint32_t value;
219 		} req;
220 		struct {
221 			uint32_t voltage_id;
222 			uint32_t value;
223 		} resp;
224 	} body;
225 	uint32_t end_tag;
226 };
227 
228 struct msg_get_max_voltage {
229 	struct bcm2835_mbox_hdr hdr;
230 	struct bcm2835_mbox_tag_hdr tag_hdr;
231 	union {
232 		struct {
233 			uint32_t voltage_id;
234 		} req;
235 		struct {
236 			uint32_t voltage_id;
237 			uint32_t value;
238 		} resp;
239 	} body;
240 	uint32_t end_tag;
241 };
242 
243 struct msg_get_min_voltage {
244 	struct bcm2835_mbox_hdr hdr;
245 	struct bcm2835_mbox_tag_hdr tag_hdr;
246 	union {
247 		struct {
248 			uint32_t voltage_id;
249 		} req;
250 		struct {
251 			uint32_t voltage_id;
252 			uint32_t value;
253 		} resp;
254 	} body;
255 	uint32_t end_tag;
256 };
257 
258 #define BCM2835_MBOX_TAG_GET_TEMPERATURE	0x00030006
259 #define BCM2835_MBOX_TAG_GET_MAX_TEMPERATURE	0x0003000a
260 
261 struct msg_get_temperature {
262 	struct bcm2835_mbox_hdr hdr;
263 	struct bcm2835_mbox_tag_hdr tag_hdr;
264 	union {
265 		struct {
266 			uint32_t temperature_id;
267 		} req;
268 		struct {
269 			uint32_t temperature_id;
270 			uint32_t value;
271 		} resp;
272 	} body;
273 	uint32_t end_tag;
274 };
275 
276 struct msg_get_max_temperature {
277 	struct bcm2835_mbox_hdr hdr;
278 	struct bcm2835_mbox_tag_hdr tag_hdr;
279 	union {
280 		struct {
281 			uint32_t temperature_id;
282 		} req;
283 		struct {
284 			uint32_t temperature_id;
285 			uint32_t value;
286 		} resp;
287 	} body;
288 	uint32_t end_tag;
289 };
290 
291 #define	BCM2835_MBOX_TAG_GET_PHYSICAL_W_H	0x00040003
292 #define	BCM2835_MBOX_TAG_SET_PHYSICAL_W_H	0x00048003
293 #define	BCM2835_MBOX_TAG_GET_VIRTUAL_W_H	0x00040004
294 #define	BCM2835_MBOX_TAG_SET_VIRTUAL_W_H	0x00048004
295 
296 struct bcm2835_mbox_tag_fb_w_h {
297 	struct bcm2835_mbox_tag_hdr tag_hdr;
298 	union {
299 		struct {
300 			uint32_t width;
301 			uint32_t height;
302 		} req;
303 		struct {
304 			uint32_t width;
305 			uint32_t height;
306 		} resp;
307 	} body;
308 };
309 
310 #define	BCM2835_MBOX_TAG_GET_DEPTH		0x00040005
311 #define	BCM2835_MBOX_TAG_SET_DEPTH		0x00048005
312 
313 struct bcm2835_mbox_tag_depth {
314 	struct bcm2835_mbox_tag_hdr tag_hdr;
315 	union {
316 		struct {
317 			uint32_t bpp;
318 		} req;
319 		struct {
320 			uint32_t bpp;
321 		} resp;
322 	} body;
323 };
324 
325 #define	BCM2835_MBOX_TAG_GET_ALPHA_MODE		0x00040007
326 #define	BCM2835_MBOX_TAG_SET_ALPHA_MODE		0x00048007
327 
328 #define	BCM2835_MBOX_ALPHA_MODE_0_OPAQUE	0
329 #define	BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT	1
330 #define	BCM2835_MBOX_ALPHA_MODE_IGNORED		2
331 
332 struct bcm2835_mbox_tag_alpha_mode {
333 	struct bcm2835_mbox_tag_hdr tag_hdr;
334 	union {
335 		struct {
336 			uint32_t alpha;
337 		} req;
338 		struct {
339 			uint32_t alpha;
340 		} resp;
341 	} body;
342 };
343 
344 #define	BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET	0x00040009
345 #define	BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET	0x00048009
346 
347 struct bcm2835_mbox_tag_virtual_offset {
348 	struct bcm2835_mbox_tag_hdr tag_hdr;
349 	union {
350 		struct {
351 			uint32_t x;
352 			uint32_t y;
353 		} req;
354 		struct {
355 			uint32_t x;
356 			uint32_t y;
357 		} resp;
358 	} body;
359 };
360 
361 #define	BCM2835_MBOX_TAG_GET_PITCH		0x00040008
362 
363 struct bcm2835_mbox_tag_pitch {
364 	struct bcm2835_mbox_tag_hdr tag_hdr;
365 	union {
366 		struct {
367 		} req;
368 		struct {
369 			uint32_t pitch;
370 		} resp;
371 	} body;
372 };
373 
374 #define	BCM2835_MBOX_TAG_ALLOCATE_BUFFER	0x00040001
375 
376 struct bcm2835_mbox_tag_allocate_buffer {
377 	struct bcm2835_mbox_tag_hdr tag_hdr;
378 	union {
379 		struct {
380 			uint32_t alignment;
381 		} req;
382 		struct {
383 			uint32_t fb_address;
384 			uint32_t fb_size;
385 		} resp;
386 	} body;
387 };
388 
389 #define	BCM2835_MBOX_TAG_RELEASE_BUFFER		0x00048001
390 
391 struct bcm2835_mbox_tag_release_buffer {
392 	struct bcm2835_mbox_tag_hdr tag_hdr;
393 	union {
394 		struct {
395 		} req;
396 		struct {
397 		} resp;
398 	} body;
399 };
400 
401 #define	BCM2835_MBOX_TAG_GET_TOUCHBUF		0x0004000f
402 
403 struct bcm2835_mbox_tag_touchbuf {
404 	struct bcm2835_mbox_hdr hdr;
405 	struct bcm2835_mbox_tag_hdr tag_hdr;
406 	union {
407 		struct {
408 		} req;
409 		struct {
410 			uint32_t address;
411 		} resp;
412 	} body;
413 	uint32_t end_tag;
414 };
415 
416 struct bcm2835_fb_config {
417 	uint32_t xres;
418 	uint32_t yres;
419 	uint32_t vxres;
420 	uint32_t vyres;
421 	uint32_t xoffset;
422 	uint32_t yoffset;
423 	uint32_t bpp;
424 	uint32_t pitch;
425 	uint32_t base;
426 	uint32_t size;
427 };
428 
429 struct msg_fb_get_w_h {
430 	struct bcm2835_mbox_hdr hdr;
431 	struct bcm2835_mbox_tag_fb_w_h physical_w_h;
432 	uint32_t end_tag;
433 };
434 
435 int bcm2835_mbox_fb_get_w_h(struct bcm2835_fb_config *);
436 
437 struct msg_fb_get_bpp {
438 	struct bcm2835_mbox_hdr hdr;
439 	struct bcm2835_mbox_tag_depth bpp;
440 	uint32_t end_tag;
441 };
442 
443 int bcm2835_mbox_fb_get_bpp(struct bcm2835_fb_config *);
444 
445 struct msg_fb_setup {
446 	struct bcm2835_mbox_hdr hdr;
447 	struct bcm2835_mbox_tag_fb_w_h physical_w_h;
448 	struct bcm2835_mbox_tag_fb_w_h virtual_w_h;
449 	struct bcm2835_mbox_tag_virtual_offset offset;
450 	struct bcm2835_mbox_tag_depth depth;
451 	struct bcm2835_mbox_tag_alpha_mode alpha;
452 	struct bcm2835_mbox_tag_allocate_buffer buffer;
453 	struct bcm2835_mbox_tag_pitch pitch;
454 	uint32_t end_tag;
455 };
456 
457 int bcm2835_mbox_fb_init(struct bcm2835_fb_config *);
458 
459 int bcm2835_mbox_property(void *, size_t);
460 
461 #endif /* _BCM2835_MBOX_PROP_H_ */
462