brcm2708: add linux 4.1 support
[openwrt.git] / target / linux / brcm2708 / patches-4.1 / 0003-mailbox-bcm2708-Add-bcm2708-vcio.patch
1 From 6f5003498da677a660cbdfaf9be78d3c0aff2e4c Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
3 Date: Fri, 1 May 2015 19:11:03 +0200
4 Subject: [PATCH 003/121] mailbox: bcm2708: Add bcm2708-vcio
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Signed-off-by: popcornmix <popcornmix@gmail.com>
10
11 Copy the arch vcio.c driver to drivers/mailbox.
12 This is done to make it available on ARCH_BCM2835.
13
14 Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
15
16 mailbox: bcm2708-vcio: Allocation does not need to be atomic
17
18 No need to do atomic allocation in a context that can sleep.
19
20 Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
21
22 mailbox: bcm2708-vcio: Check the correct status register before writing
23
24 With the VC reader blocked and the ARM writing, MAIL0_STA reads
25 empty permanently while MAIL1_STA goes from empty (0x40000000)
26 to non-empty (0x00000001-0x00000007) to full (0x80000008).
27
28 Suggested-by: Phil Elwell <phil@raspberrypi.org>
29 Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
30 ---
31  drivers/mailbox/Kconfig                       |   6 +
32  drivers/mailbox/Makefile                      |   2 +
33  drivers/mailbox/bcm2708-vcio.c                | 427 ++++++++++++++++++++++++++
34  include/linux/platform_data/mailbox-bcm2708.h | 126 ++++++++
35  4 files changed, 561 insertions(+)
36  create mode 100644 drivers/mailbox/bcm2708-vcio.c
37  create mode 100644 include/linux/platform_data/mailbox-bcm2708.h
38
39 --- a/drivers/mailbox/Kconfig
40 +++ b/drivers/mailbox/Kconfig
41 @@ -7,6 +7,12 @@ menuconfig MAILBOX
42  
43  if MAILBOX
44  
45 +config BCM2708_MBOX
46 +       bool "Broadcom BCM2708 Mailbox (vcio)"
47 +       depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835
48 +       help
49 +         Broadcom BCM2708 Mailbox (vcio)
50 +
51  config ARM_MHU
52         tristate "ARM MHU Mailbox"
53         depends on ARM_AMBA
54 --- a/drivers/mailbox/Makefile
55 +++ b/drivers/mailbox/Makefile
56 @@ -2,6 +2,8 @@
57  
58  obj-$(CONFIG_MAILBOX)          += mailbox.o
59  
60 +obj-$(CONFIG_BCM2708_MBOX)     += bcm2708-vcio.o
61 +
62  obj-$(CONFIG_ARM_MHU)  += arm_mhu.o
63  
64  obj-$(CONFIG_PL320_MBOX)       += pl320-ipc.o
65 --- /dev/null
66 +++ b/drivers/mailbox/bcm2708-vcio.c
67 @@ -0,0 +1,427 @@
68 +/*
69 + *  linux/arch/arm/mach-bcm2708/vcio.c
70 + *
71 + *  Copyright (C) 2010 Broadcom
72 + *
73 + * This program is free software; you can redistribute it and/or modify
74 + * it under the terms of the GNU General Public License version 2 as
75 + * published by the Free Software Foundation.
76 + *
77 + * This device provides a shared mechanism for writing to the mailboxes,
78 + * semaphores, doorbells etc. that are shared between the ARM and the
79 + * VideoCore processor
80 + */
81 +
82 +#include <linux/device.h>
83 +#include <linux/dma-mapping.h>
84 +#include <linux/module.h>
85 +#include <linux/errno.h>
86 +#include <linux/fs.h>
87 +#include <linux/init.h>
88 +#include <linux/interrupt.h>
89 +#include <linux/io.h>
90 +#include <linux/ioctl.h>
91 +#include <linux/platform_data/mailbox-bcm2708.h>
92 +#include <linux/platform_device.h>
93 +#include <linux/uaccess.h>
94 +
95 +#define DRIVER_NAME "bcm2708_vcio"
96 +#define DEVICE_FILE_NAME "vcio"
97 +
98 +/* offsets from a mail box base address */
99 +#define MAIL0_RD       0x00    /* read - and next 4 words */
100 +#define MAIL0_POL      0x10    /* read without popping the fifo */
101 +#define MAIL0_SND      0x14    /* sender ID (bottom two bits) */
102 +#define MAIL0_STA      0x18    /* status */
103 +#define MAIL0_CNF      0x1C    /* configuration */
104 +#define MAIL1_WRT      0x20    /* write - and next 4 words */
105 +#define MAIL1_STA      0x38    /* status */
106 +
107 +/* On MACH_BCM270x these come through <linux/interrupt.h> (arm_control.h ) */
108 +#ifndef ARM_MS_EMPTY
109 +#define ARM_MS_EMPTY   BIT(30)
110 +#define ARM_MS_FULL    BIT(31)
111 +
112 +#define ARM_MC_IHAVEDATAIRQEN  BIT(0)
113 +#endif
114 +
115 +#define MBOX_MSG(chan, data28)         (((data28) & ~0xf) | ((chan) & 0xf))
116 +#define MBOX_MSG_LSB(chan, data28)     (((data28) << 4) | ((chan) & 0xf))
117 +#define MBOX_CHAN(msg)                 ((msg) & 0xf)
118 +#define MBOX_DATA28(msg)               ((msg) & ~0xf)
119 +#define MBOX_DATA28_LSB(msg)           (((uint32_t)msg) >> 4)
120 +
121 +#define MBOX_MAGIC 0xd0d0c0de
122 +
123 +#define MAJOR_NUM 100
124 +#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *)
125 +
126 +static struct class *vcio_class;
127 +
128 +struct vc_mailbox {
129 +       void __iomem *regs;
130 +       uint32_t msg[MBOX_CHAN_COUNT];
131 +       struct semaphore sema[MBOX_CHAN_COUNT];
132 +       uint32_t magic;
133 +};
134 +
135 +static void mbox_init(struct vc_mailbox *mbox_out)
136 +{
137 +       int i;
138 +
139 +       for (i = 0; i < MBOX_CHAN_COUNT; i++) {
140 +               mbox_out->msg[i] = 0;
141 +               sema_init(&mbox_out->sema[i], 0);
142 +       }
143 +
144 +       /* Enable the interrupt on data reception */
145 +       writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF);
146 +
147 +       mbox_out->magic = MBOX_MAGIC;
148 +}
149 +
150 +static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28)
151 +{
152 +       if (mbox->magic != MBOX_MAGIC)
153 +               return -EINVAL;
154 +
155 +       /* wait for the mailbox FIFO to have some space in it */
156 +       while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL))
157 +               cpu_relax();
158 +
159 +       writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT);
160 +
161 +       return 0;
162 +}
163 +
164 +static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28)
165 +{
166 +       if (mbox->magic != MBOX_MAGIC)
167 +               return -EINVAL;
168 +
169 +       down(&mbox->sema[chan]);
170 +       *data28 = MBOX_DATA28(mbox->msg[chan]);
171 +       mbox->msg[chan] = 0;
172 +
173 +       return 0;
174 +}
175 +
176 +static irqreturn_t mbox_irq_handler(int irq, void *dev_id)
177 +{
178 +       /* wait for the mailbox FIFO to have some data in it */
179 +       struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id;
180 +       int status = readl(mbox->regs + MAIL0_STA);
181 +       int ret = IRQ_NONE;
182 +
183 +       while (!(status & ARM_MS_EMPTY)) {
184 +               uint32_t msg = readl(mbox->regs + MAIL0_RD);
185 +               int chan = MBOX_CHAN(msg);
186 +
187 +               if (chan < MBOX_CHAN_COUNT) {
188 +                       if (mbox->msg[chan]) {
189 +                               pr_err(DRIVER_NAME
190 +                                      ": mbox chan %d overflow - drop %08x\n",
191 +                                      chan, msg);
192 +                       } else {
193 +                               mbox->msg[chan] = (msg | 0xf);
194 +                               up(&mbox->sema[chan]);
195 +                       }
196 +               } else {
197 +                       pr_err(DRIVER_NAME
198 +                              ": invalid channel selector (msg %08x)\n", msg);
199 +               }
200 +               ret = IRQ_HANDLED;
201 +               status = readl(mbox->regs + MAIL0_STA);
202 +       }
203 +       return ret;
204 +}
205 +
206 +/* Mailbox Methods */
207 +
208 +static struct device *mbox_dev;        /* we assume there's only one! */
209 +
210 +static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28)
211 +{
212 +       struct vc_mailbox *mailbox = dev_get_drvdata(dev);
213 +       int rc;
214 +
215 +       device_lock(dev);
216 +       rc = mbox_write(mailbox, chan, data28);
217 +       device_unlock(dev);
218 +
219 +       return rc;
220 +}
221 +
222 +static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28)
223 +{
224 +       struct vc_mailbox *mailbox = dev_get_drvdata(dev);
225 +       int rc;
226 +
227 +       device_lock(dev);
228 +       rc = mbox_read(mailbox, chan, data28);
229 +       device_unlock(dev);
230 +
231 +       return rc;
232 +}
233 +
234 +extern int bcm_mailbox_write(unsigned chan, uint32_t data28)
235 +{
236 +       if (!mbox_dev)
237 +               return -ENODEV;
238 +
239 +       return dev_mbox_write(mbox_dev, chan, data28);
240 +}
241 +EXPORT_SYMBOL_GPL(bcm_mailbox_write);
242 +
243 +extern int bcm_mailbox_read(unsigned chan, uint32_t *data28)
244 +{
245 +       if (!mbox_dev)
246 +               return -ENODEV;
247 +
248 +       return dev_mbox_read(mbox_dev, chan, data28);
249 +}
250 +EXPORT_SYMBOL_GPL(bcm_mailbox_read);
251 +
252 +static int mbox_copy_from_user(void *dst, const void *src, int size)
253 +{
254 +       if ((uint32_t)src < TASK_SIZE)
255 +               return copy_from_user(dst, src, size);
256 +
257 +       memcpy(dst, src, size);
258 +
259 +       return 0;
260 +}
261 +
262 +static int mbox_copy_to_user(void *dst, const void *src, int size)
263 +{
264 +       if ((uint32_t)dst < TASK_SIZE)
265 +               return copy_to_user(dst, src, size);
266 +
267 +       memcpy(dst, src, size);
268 +
269 +       return 0;
270 +}
271 +
272 +static DEFINE_MUTEX(mailbox_lock);
273 +extern int bcm_mailbox_property(void *data, int size)
274 +{
275 +       uint32_t success;
276 +       dma_addr_t mem_bus; /* the memory address accessed from videocore */
277 +       void *mem_kern;     /* the memory address accessed from driver */
278 +       int s = 0;
279 +
280 +       mutex_lock(&mailbox_lock);
281 +       /* allocate some memory for the messages communicating with GPU */
282 +       mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus,
283 +                                     GFP_KERNEL);
284 +       if (mem_kern) {
285 +               /* create the message */
286 +               mbox_copy_from_user(mem_kern, data, size);
287 +
288 +               /* send the message */
289 +               wmb();
290 +               s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus);
291 +               if (s == 0)
292 +                       s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success);
293 +               if (s == 0) {
294 +                       /* copy the response */
295 +                       rmb();
296 +                       mbox_copy_to_user(data, mem_kern, size);
297 +               }
298 +               dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus);
299 +       } else {
300 +               s = -ENOMEM;
301 +       }
302 +       if (s != 0)
303 +               pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s);
304 +
305 +       mutex_unlock(&mailbox_lock);
306 +       return s;
307 +}
308 +EXPORT_SYMBOL_GPL(bcm_mailbox_property);
309 +
310 +/* Platform Device for Mailbox */
311 +
312 +/*
313 + * Is the device open right now? Used to prevent
314 + * concurent access into the same device
315 + */
316 +static bool device_is_open;
317 +
318 +/* This is called whenever a process attempts to open the device file */
319 +static int device_open(struct inode *inode, struct file *file)
320 +{
321 +       /* We don't want to talk to two processes at the same time */
322 +       if (device_is_open)
323 +               return -EBUSY;
324 +
325 +       device_is_open = true;
326 +       try_module_get(THIS_MODULE);
327 +
328 +       return 0;
329 +}
330 +
331 +static int device_release(struct inode *inode, struct file *file)
332 +{
333 +       /* We're now ready for our next caller */
334 +       device_is_open = false;
335 +
336 +       module_put(THIS_MODULE);
337 +
338 +       return 0;
339 +}
340 +
341 +/*
342 + * This function is called whenever a process tries to do an ioctl on our
343 + * device file. We get two extra parameters (additional to the inode and file
344 + * structures, which all device functions get): the number of the ioctl called
345 + * and the parameter given to the ioctl function.
346 + *
347 + * If the ioctl is write or read/write (meaning output is returned to the
348 + * calling process), the ioctl call returns the output of this function.
349 + *
350 + */
351 +static long device_ioctl(struct file *file, unsigned int ioctl_num,
352 +                        unsigned long ioctl_param)
353 +{
354 +       unsigned size;
355 +
356 +       switch (ioctl_num) {
357 +       case IOCTL_MBOX_PROPERTY:
358 +               /*
359 +                * Receive a pointer to a message (in user space) and set that
360 +                * to be the device's message.  Get the parameter given to
361 +                * ioctl by the process.
362 +                */
363 +               mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size));
364 +               return bcm_mailbox_property((void *)ioctl_param, size);
365 +       default:
366 +               pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num);
367 +               return -EINVAL;
368 +       }
369 +
370 +       return 0;
371 +}
372 +
373 +/* Module Declarations */
374 +
375 +/*
376 + * This structure will hold the functions to be called
377 + * when a process does something to the device we
378 + * created. Since a pointer to this structure is kept in
379 + * the devices table, it can't be local to
380 + * init_module. NULL is for unimplemented functios.
381 + */
382 +const struct file_operations fops = {
383 +       .unlocked_ioctl = device_ioctl,
384 +       .open = device_open,
385 +       .release = device_release,      /* a.k.a. close */
386 +};
387 +
388 +static int bcm_vcio_probe(struct platform_device *pdev)
389 +{
390 +       struct device *dev = &pdev->dev;
391 +       struct device *vdev;
392 +       struct vc_mailbox *mailbox;
393 +       struct resource *res;
394 +       int irq, ret;
395 +
396 +       mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL);
397 +       if (!mailbox)
398 +               return -ENOMEM;
399 +
400 +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
401 +       mailbox->regs = devm_ioremap_resource(dev, res);
402 +       if (IS_ERR(mailbox->regs))
403 +               return PTR_ERR(mailbox->regs);
404 +
405 +       irq = platform_get_irq(pdev, 0);
406 +       ret = devm_request_irq(dev, irq, mbox_irq_handler,
407 +                              IRQF_IRQPOLL,
408 +                              dev_name(dev), mailbox);
409 +       if (ret) {
410 +               dev_err(dev, "Interrupt request failed %d\n", ret);
411 +               return ret;
412 +       }
413 +
414 +       ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops);
415 +       if (ret < 0) {
416 +               pr_err("Character device registration failed %d\n", ret);
417 +               return ret;
418 +       }
419 +
420 +       vcio_class = class_create(THIS_MODULE, DRIVER_NAME);
421 +       if (IS_ERR(vcio_class)) {
422 +               ret = PTR_ERR(vcio_class);
423 +               pr_err("Class creation failed %d\n", ret);
424 +               goto err_class;
425 +       }
426 +
427 +       vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL,
428 +                            "vcio");
429 +       if (IS_ERR(vdev)) {
430 +               ret = PTR_ERR(vdev);
431 +               pr_err("Device creation failed %d\n", ret);
432 +               goto err_dev;
433 +       }
434 +
435 +       mbox_init(mailbox);
436 +       platform_set_drvdata(pdev, mailbox);
437 +       mbox_dev = dev;
438 +
439 +       dev_info(dev, "mailbox at %p\n", mailbox->regs);
440 +
441 +       return 0;
442 +
443 +err_dev:
444 +       class_destroy(vcio_class);
445 +err_class:
446 +       unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME);
447 +
448 +       return ret;
449 +}
450 +
451 +static int bcm_vcio_remove(struct platform_device *pdev)
452 +{
453 +       mbox_dev = NULL;
454 +       platform_set_drvdata(pdev, NULL);
455 +       device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0));
456 +       class_destroy(vcio_class);
457 +       unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME);
458 +
459 +       return 0;
460 +}
461 +
462 +static const struct of_device_id bcm_vcio_of_match_table[] = {
463 +       { .compatible = "brcm,bcm2708-vcio", },
464 +       {},
465 +};
466 +MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table);
467 +
468 +static struct platform_driver bcm_mbox_driver = {
469 +       .probe = bcm_vcio_probe,
470 +       .remove = bcm_vcio_remove,
471 +
472 +       .driver = {
473 +                  .name = DRIVER_NAME,
474 +                  .owner = THIS_MODULE,
475 +                  .of_match_table = bcm_vcio_of_match_table,
476 +                  },
477 +};
478 +
479 +static int __init bcm_mbox_init(void)
480 +{
481 +       return platform_driver_register(&bcm_mbox_driver);
482 +}
483 +
484 +static void __exit bcm_mbox_exit(void)
485 +{
486 +       platform_driver_unregister(&bcm_mbox_driver);
487 +}
488 +
489 +arch_initcall(bcm_mbox_init);  /* Initialize early */
490 +module_exit(bcm_mbox_exit);
491 +
492 +MODULE_AUTHOR("Gray Girling");
493 +MODULE_DESCRIPTION("ARM I/O to VideoCore processor");
494 +MODULE_LICENSE("GPL");
495 --- /dev/null
496 +++ b/include/linux/platform_data/mailbox-bcm2708.h
497 @@ -0,0 +1,126 @@
498 +/*
499 + *  Copyright (C) 2010 Broadcom
500 + *
501 + * This program is free software; you can redistribute it and/or modify
502 + * it under the terms of the GNU General Public License as published by
503 + * the Free Software Foundation; either version 2 of the License, or
504 + * (at your option) any later version.
505 + *
506 + * This program is distributed in the hope that it will be useful,
507 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
508 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
509 + * GNU General Public License for more details.
510 + */
511 +#ifndef _PLAT_MAILBOX_BCM2708_H
512 +#define _PLAT_MAILBOX_BCM2708_H
513 +
514 +/* Routines to handle I/O via the VideoCore "ARM control" registers
515 + * (semaphores, doorbells, mailboxes)
516 + */
517 +
518 +/* Constants shared with the ARM identifying separate mailbox channels */
519 +#define MBOX_CHAN_POWER    0 /* for use by the power management interface */
520 +#define MBOX_CHAN_FB       1 /* for use by the frame buffer */
521 +#define MBOX_CHAN_VCHIQ    3 /* for use by the VCHIQ interface */
522 +#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */
523 +#define MBOX_CHAN_COUNT    9
524 +
525 +enum {
526 +       VCMSG_PROCESS_REQUEST           = 0x00000000
527 +};
528 +
529 +enum {
530 +       VCMSG_REQUEST_SUCCESSFUL        = 0x80000000,
531 +       VCMSG_REQUEST_FAILED            = 0x80000001
532 +};
533 +
534 +/* Mailbox property tags */
535 +enum {
536 +       VCMSG_PROPERTY_END               = 0x00000000,
537 +       VCMSG_GET_FIRMWARE_REVISION      = 0x00000001,
538 +       VCMSG_GET_BOARD_MODEL            = 0x00010001,
539 +       VCMSG_GET_BOARD_REVISION         = 0x00010002,
540 +       VCMSG_GET_BOARD_MAC_ADDRESS      = 0x00010003,
541 +       VCMSG_GET_BOARD_SERIAL           = 0x00010004,
542 +       VCMSG_GET_ARM_MEMORY             = 0x00010005,
543 +       VCMSG_GET_VC_MEMORY              = 0x00010006,
544 +       VCMSG_GET_CLOCKS                 = 0x00010007,
545 +       VCMSG_GET_COMMAND_LINE           = 0x00050001,
546 +       VCMSG_GET_DMA_CHANNELS           = 0x00060001,
547 +       VCMSG_GET_POWER_STATE            = 0x00020001,
548 +       VCMSG_GET_TIMING                 = 0x00020002,
549 +       VCMSG_SET_POWER_STATE            = 0x00028001,
550 +       VCMSG_GET_CLOCK_STATE            = 0x00030001,
551 +       VCMSG_SET_CLOCK_STATE            = 0x00038001,
552 +       VCMSG_GET_CLOCK_RATE             = 0x00030002,
553 +       VCMSG_SET_CLOCK_RATE             = 0x00038002,
554 +       VCMSG_GET_VOLTAGE                = 0x00030003,
555 +       VCMSG_SET_VOLTAGE                = 0x00038003,
556 +       VCMSG_GET_MAX_CLOCK              = 0x00030004,
557 +       VCMSG_GET_MAX_VOLTAGE            = 0x00030005,
558 +       VCMSG_GET_TEMPERATURE            = 0x00030006,
559 +       VCMSG_GET_MIN_CLOCK              = 0x00030007,
560 +       VCMSG_GET_MIN_VOLTAGE            = 0x00030008,
561 +       VCMSG_GET_TURBO                  = 0x00030009,
562 +       VCMSG_GET_MAX_TEMPERATURE        = 0x0003000a,
563 +       VCMSG_GET_STC                    = 0x0003000b,
564 +       VCMSG_SET_TURBO                  = 0x00038009,
565 +       VCMSG_SET_ALLOCATE_MEM           = 0x0003000c,
566 +       VCMSG_SET_LOCK_MEM               = 0x0003000d,
567 +       VCMSG_SET_UNLOCK_MEM             = 0x0003000e,
568 +       VCMSG_SET_RELEASE_MEM            = 0x0003000f,
569 +       VCMSG_SET_EXECUTE_CODE           = 0x00030010,
570 +       VCMSG_SET_EXECUTE_QPU            = 0x00030011,
571 +       VCMSG_SET_ENABLE_QPU             = 0x00030012,
572 +       VCMSG_GET_RESOURCE_HANDLE        = 0x00030014,
573 +       VCMSG_GET_EDID_BLOCK             = 0x00030020,
574 +       VCMSG_GET_CUSTOMER_OTP           = 0x00030021,
575 +       VCMSG_SET_CUSTOMER_OTP           = 0x00038021,
576 +       VCMSG_SET_ALLOCATE_BUFFER        = 0x00040001,
577 +       VCMSG_SET_RELEASE_BUFFER         = 0x00048001,
578 +       VCMSG_SET_BLANK_SCREEN           = 0x00040002,
579 +       VCMSG_TST_BLANK_SCREEN           = 0x00044002,
580 +       VCMSG_GET_PHYSICAL_WIDTH_HEIGHT  = 0x00040003,
581 +       VCMSG_TST_PHYSICAL_WIDTH_HEIGHT  = 0x00044003,
582 +       VCMSG_SET_PHYSICAL_WIDTH_HEIGHT  = 0x00048003,
583 +       VCMSG_GET_VIRTUAL_WIDTH_HEIGHT   = 0x00040004,
584 +       VCMSG_TST_VIRTUAL_WIDTH_HEIGHT   = 0x00044004,
585 +       VCMSG_SET_VIRTUAL_WIDTH_HEIGHT   = 0x00048004,
586 +       VCMSG_GET_DEPTH                  = 0x00040005,
587 +       VCMSG_TST_DEPTH                  = 0x00044005,
588 +       VCMSG_SET_DEPTH                  = 0x00048005,
589 +       VCMSG_GET_PIXEL_ORDER            = 0x00040006,
590 +       VCMSG_TST_PIXEL_ORDER            = 0x00044006,
591 +       VCMSG_SET_PIXEL_ORDER            = 0x00048006,
592 +       VCMSG_GET_ALPHA_MODE             = 0x00040007,
593 +       VCMSG_TST_ALPHA_MODE             = 0x00044007,
594 +       VCMSG_SET_ALPHA_MODE             = 0x00048007,
595 +       VCMSG_GET_PITCH                  = 0x00040008,
596 +       VCMSG_TST_PITCH                  = 0x00044008,
597 +       VCMSG_SET_PITCH                  = 0x00048008,
598 +       VCMSG_GET_VIRTUAL_OFFSET         = 0x00040009,
599 +       VCMSG_TST_VIRTUAL_OFFSET         = 0x00044009,
600 +       VCMSG_SET_VIRTUAL_OFFSET         = 0x00048009,
601 +       VCMSG_GET_OVERSCAN               = 0x0004000a,
602 +       VCMSG_TST_OVERSCAN               = 0x0004400a,
603 +       VCMSG_SET_OVERSCAN               = 0x0004800a,
604 +       VCMSG_GET_PALETTE                = 0x0004000b,
605 +       VCMSG_TST_PALETTE                = 0x0004400b,
606 +       VCMSG_SET_PALETTE                = 0x0004800b,
607 +       VCMSG_GET_LAYER                  = 0x0004000c,
608 +       VCMSG_TST_LAYER                  = 0x0004400c,
609 +       VCMSG_SET_LAYER                  = 0x0004800c,
610 +       VCMSG_GET_TRANSFORM              = 0x0004000d,
611 +       VCMSG_TST_TRANSFORM              = 0x0004400d,
612 +       VCMSG_SET_TRANSFORM              = 0x0004800d,
613 +       VCMSG_TST_VSYNC                  = 0x0004400e,
614 +       VCMSG_SET_VSYNC                  = 0x0004800e,
615 +       VCMSG_SET_CURSOR_INFO            = 0x00008010,
616 +       VCMSG_SET_CURSOR_STATE           = 0x00008011,
617 +};
618 +
619 +int bcm_mailbox_read(unsigned chan, uint32_t *data28);
620 +int bcm_mailbox_write(unsigned chan, uint32_t data28);
621 +int bcm_mailbox_property(void *data, int size);
622 +
623 +#endif