mbox.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /*
  2. * Copyright (C) 2018 bzt (bztsrc@github)
  3. *
  4. * Permission is hereby granted, free of charge, to any person
  5. * obtaining a copy of this software and associated documentation
  6. * files (the "Software"), to deal in the Software without
  7. * restriction, including without limitation the rights to use, copy,
  8. * modify, merge, publish, distribute, sublicense, and/or sell copies
  9. * of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be
  13. * included in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. * DEALINGS IN THE SOFTWARE.
  23. *
  24. */
  25. #include "gpio.h"
  26. /* mailbox message buffer */
  27. volatile unsigned int __attribute__((aligned(16))) mbox[36];
  28. #define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
  29. #define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
  30. #define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
  31. #define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
  32. #define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
  33. #define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
  34. #define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
  35. #define MBOX_RESPONSE 0x80000000
  36. #define MBOX_FULL 0x80000000
  37. #define MBOX_EMPTY 0x40000000
  38. /**
  39. * Make a mailbox call. Returns 0 on failure, non-zero on success
  40. */
  41. int mbox_call(unsigned char ch)
  42. {
  43. unsigned int r = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
  44. /* wait until we can write to the mailbox */
  45. do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
  46. /* write the address of our message to the mailbox with channel identifier */
  47. *MBOX_WRITE = r;
  48. /* now wait for the response */
  49. while(1) {
  50. /* is there a response? */
  51. do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
  52. /* is it a response to our message? */
  53. if(r == *MBOX_READ)
  54. /* is it a valid successful response? */
  55. return mbox[1]==MBOX_RESPONSE;
  56. }
  57. return 0;
  58. }