mbox.h 10 KB

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