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
41struct bcm2835_mbox_hdr {
42	uint32_t	buf_size;
43	uint32_t	code;
44};
45
46struct 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
76struct 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
91struct 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 */
108int bcm2835_mbox_set_power_state(uint32_t, boolean_t);
109
110#define BCM2835_MBOX_TAG_NOTIFY_XHCI_RESET	0x00030058
111
112struct 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. */
126int 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
133struct 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
148int 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
156struct 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
171struct 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
197struct 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
212struct 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
228struct 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
243struct 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
261struct 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
276struct 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
296struct 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
313struct 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
332struct 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
347struct 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
363struct 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
376struct 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
391struct 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
403struct 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
416struct 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
429struct 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
435int bcm2835_mbox_fb_get_w_h(struct bcm2835_fb_config *);
436
437struct msg_fb_get_bpp {
438	struct bcm2835_mbox_hdr hdr;
439	struct bcm2835_mbox_tag_depth bpp;
440	uint32_t end_tag;
441};
442
443int bcm2835_mbox_fb_get_bpp(struct bcm2835_fb_config *);
444
445struct 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
457int bcm2835_mbox_fb_init(struct bcm2835_fb_config *);
458
459int bcm2835_mbox_property(void *, size_t);
460
461#endif /* _BCM2835_MBOX_PROP_H_ */
462