1
0

drv_fb.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-08-29 zdzn first version
  9. */
  10. #include <rthw.h>
  11. #include <stdint.h>
  12. #include <rtthread.h>
  13. #include "mbox.h"
  14. #include "drv_fb.h"
  15. #include "mmu.h"
  16. #define LCD_WIDTH (800)
  17. #define LCD_HEIGHT (480)
  18. #define LCD_DEPTH (32)
  19. #define LCD_BPP (32)
  20. #define TAG_ALLOCATE_BUFFER 0x00040001
  21. #define TAG_SET_PHYS_WIDTH_HEIGHT 0x00048003
  22. #define TAG_SET_VIRT_WIDTH_HEIGHT 0x00048004
  23. #define TAG_SET_DEPTH 0x00048005
  24. #define TAG_SET_PIXEL_ORDER 0x00048006
  25. #define TAG_GET_PITCH 0x00040008
  26. #define TAG_SET_VIRT_OFFSET 0x00048009
  27. #define TAG_END 0x00000000
  28. enum {
  29. MBOX_TAG_FB_GET_GPIOVIRT = 0x00040010,
  30. MBOX_TAG_FB_ALLOCATE_BUFFER = 0x00040001,
  31. MBOX_TAG_FB_RELEASE_BUFFER = 0x00048001,
  32. MBOX_TAG_FB_BLANK_SCREEN = 0x00040002,
  33. MBOX_TAG_FB_GET_PHYS_WH = 0x00040003,
  34. MBOX_TAG_FB_TEST_PHYS_WH = 0x00044003,
  35. MBOX_TAG_FB_SET_PHYS_WH = 0x00048003,
  36. MBOX_TAG_FB_GET_VIRT_WH = 0x00040004,
  37. MBOX_TAG_FB_TEST_VIRT_WH = 0x00044004,
  38. MBOX_TAG_FB_SET_VIRT_WH = 0x00048004,
  39. MBOX_TAG_FB_GET_DEPTH = 0x00040005,
  40. MBOX_TAG_FB_TEST_DEPTH = 0x00044005,
  41. MBOX_TAG_FB_SET_DEPTH = 0x00048005,
  42. MBOX_TAG_FB_GET_PIXEL_ORDER = 0x00040006,
  43. MBOX_TAG_FB_TEST_PIXEL_ORDER = 0x00044006,
  44. MBOX_TAG_FB_SET_PIXEL_ORDER = 0x00048006,
  45. MBOX_TAG_FB_GET_ALPHA_MODE = 0x00040007,
  46. MBOX_TAG_FB_TEST_ALPHA_MODE = 0x00044007,
  47. MBOX_TAG_FB_SET_ALPHA_MODE = 0x00048007,
  48. MBOX_TAG_FB_GET_PITCH = 0x00040008,
  49. MBOX_TAG_FB_GET_VIRT_OFFSET = 0x00040009,
  50. MBOX_TAG_FB_TEST_VIRT_OFFSET = 0x00044009,
  51. MBOX_TAG_FB_SET_VIRT_OFFSET = 0x00048009,
  52. MBOX_TAG_FB_GET_OVERSCAN = 0x0004000a,
  53. MBOX_TAG_FB_TEST_OVERSCAN = 0x0004400a,
  54. MBOX_TAG_FB_SET_OVERSCAN = 0x0004800a,
  55. MBOX_TAG_FB_GET_PALETTE = 0x0004000b,
  56. MBOX_TAG_FB_TEST_PALETTE = 0x0004400b,
  57. MBOX_TAG_FB_SET_PALETTE = 0x0004800b,
  58. };
  59. #define LCD_DEVICE(dev) (struct rt_hdmi_fb_device*)(dev)
  60. static struct rt_hdmi_fb_device _hdmi;
  61. typedef rt_uint16_t color_t;
  62. rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag)
  63. {
  64. return RT_EOK;
  65. }
  66. rt_err_t hdmi_fb_close(rt_device_t dev)
  67. {
  68. return RT_EOK;
  69. }
  70. rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
  71. {
  72. return 0;
  73. }
  74. rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  75. {
  76. return size;
  77. }
  78. rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
  79. {
  80. struct rt_hdmi_fb_device *lcd = LCD_DEVICE(dev);
  81. switch (cmd)
  82. {
  83. case RTGRAPHIC_CTRL_RECT_UPDATE:
  84. {
  85. struct rt_device_rect_info *info = (struct rt_device_rect_info*)args;
  86. info = info;
  87. }
  88. break;
  89. case RTGRAPHIC_CTRL_GET_INFO:
  90. {
  91. struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args;
  92. RT_ASSERT(info != RT_NULL);
  93. info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
  94. info->bits_per_pixel= LCD_DEPTH;
  95. info->width = lcd->width;
  96. info->height = lcd->height;
  97. info->framebuffer = lcd->fb;
  98. }
  99. break;
  100. }
  101. return RT_EOK;
  102. }
  103. const static struct rt_device_ops hdmi_fb_ops =
  104. {
  105. RT_NULL,
  106. hdmi_fb_open,
  107. hdmi_fb_close,
  108. hdmi_fb_read,
  109. hdmi_fb_write,
  110. hdmi_fb_control
  111. };
  112. rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name)
  113. {
  114. struct rt_device *device;
  115. RT_ASSERT(hdmi_fb != RT_NULL);
  116. device = &hdmi_fb->parent;
  117. /* set device type */
  118. device->type = RT_Device_Class_Graphic;
  119. /* initialize device interface */
  120. #ifdef RT_USING_DEVICE_OPS
  121. device->ops = &hdmi_fb_ops;
  122. #else
  123. device->init = RT_NULL;
  124. device->open = hdmi_fb_open;
  125. device->close = hdmi_fb_close;
  126. device->read = hdmi_fb_read;
  127. device->write = hdmi_fb_write;
  128. device->control = hdmi_fb_control;
  129. #endif
  130. /* register to device manager */
  131. rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
  132. return RT_EOK;
  133. }
  134. rt_uint32_t bcm283x_mbox_fb_get_gpiovirt(void)
  135. {
  136. mbox[0] = 8*4; // length of the message
  137. mbox[1] = MBOX_REQUEST; // this is a request message
  138. mbox[2] = MBOX_TAG_FB_GET_GPIOVIRT;
  139. mbox[3] = 4; // buffer size
  140. mbox[4] = 0; // len
  141. mbox[5] = 0; // id
  142. mbox[6] = 0;
  143. mbox[7] = MBOX_TAG_LAST;
  144. mbox_call(8, MMU_DISABLE);
  145. return (mbox[5] & 0x3fffffff);
  146. }
  147. rt_uint32_t bcm283x_mbox_fb_get_pitch(void)
  148. {
  149. mbox[0] = 8*4; // length of the message
  150. mbox[1] = MBOX_REQUEST; // this is a request message
  151. mbox[2] = MBOX_TAG_FB_GET_PITCH;
  152. mbox[3] = 4; // buffer size
  153. mbox[4] = 0; // len
  154. mbox[5] = 0; // id
  155. mbox[6] = 0;
  156. mbox[7] = MBOX_TAG_LAST;
  157. mbox_call(8, MMU_DISABLE);
  158. return mbox[5];
  159. }
  160. void bcm283x_mbox_fb_set_porder(int rgb)
  161. {
  162. mbox[0] = 8*4; // length of the message
  163. mbox[1] = MBOX_REQUEST; // this is a request message
  164. mbox[2] = MBOX_TAG_FB_SET_PIXEL_ORDER;
  165. mbox[3] = 4; // buffer size
  166. mbox[4] = 4; // len
  167. mbox[5] = rgb; // id
  168. mbox[6] = 0;
  169. mbox[7] = MBOX_TAG_LAST;
  170. mbox_call(8, MMU_DISABLE);
  171. }
  172. void bcm283x_mbox_fb_setoffset(int xoffset, int yoffset)
  173. {
  174. mbox[0] = 8*4; // length of the message
  175. mbox[1] = MBOX_REQUEST; // this is a request message
  176. mbox[2] = MBOX_TAG_FB_SET_VIRT_OFFSET;
  177. mbox[3] = 8; // buffer size
  178. mbox[4] = 8; // len
  179. mbox[5] = xoffset; // id
  180. mbox[6] = yoffset;
  181. mbox[7] = MBOX_TAG_LAST;
  182. mbox_call(8, MMU_DISABLE);
  183. }
  184. void bcm283x_mbox_fb_setalpha(int alpha)
  185. {
  186. mbox[0] = 8*4; // length of the message
  187. mbox[1] = MBOX_REQUEST; // this is a request message
  188. mbox[2] = MBOX_TAG_FB_SET_ALPHA_MODE;
  189. mbox[3] = 4; // buffer size
  190. mbox[4] = 4; // len
  191. mbox[5] = alpha; // id
  192. mbox[6] = 0;
  193. mbox[7] = MBOX_TAG_LAST;
  194. mbox_call(8, MMU_DISABLE);
  195. }
  196. void *bcm283x_mbox_fb_alloc(int width, int height, int bpp, int nrender)
  197. {
  198. mbox[0] = 4 * 35;
  199. mbox[1] = MBOX_REQUEST;
  200. mbox[2] = TAG_ALLOCATE_BUFFER;//get framebuffer, gets alignment on request
  201. mbox[3] = 8; //size
  202. mbox[4] = 4; //len
  203. mbox[5] = 4096; //The design of MBOX driver forces us to give the virtual address 0x3C100000
  204. mbox[6] = 0; //FrameBufferInfo.size
  205. mbox[7] = TAG_SET_PHYS_WIDTH_HEIGHT;
  206. mbox[8] = 8;
  207. mbox[9] = 8;
  208. mbox[10] = width;
  209. mbox[11] = height;
  210. mbox[12] = TAG_SET_VIRT_WIDTH_HEIGHT;
  211. mbox[13] = 8;
  212. mbox[14] = 8;
  213. mbox[15] = width;
  214. mbox[16] = height * nrender;
  215. mbox[17] = TAG_SET_DEPTH;
  216. mbox[18] = 4;
  217. mbox[19] = 4;
  218. mbox[20] = bpp;
  219. mbox[21] = TAG_SET_PIXEL_ORDER;
  220. mbox[22] = 4;
  221. mbox[23] = 0;
  222. mbox[24] = 0; //RGB, not BGR preferably
  223. mbox[25] = TAG_GET_PITCH;
  224. mbox[26] = 4;
  225. mbox[27] = 0;
  226. mbox[28] = 0;
  227. mbox[29] = TAG_SET_VIRT_OFFSET;
  228. mbox[30] = 8;
  229. mbox[31] = 8;
  230. mbox[32] = 0;
  231. mbox[33] = 0;
  232. mbox[34] = TAG_END;
  233. mbox_call(MBOX_CH_PROP, MMU_DISABLE);
  234. return (void *)((rt_uint64_t)(mbox[5] & 0x3fffffff));
  235. }
  236. int hdmi_fb_init(void)
  237. {
  238. _hdmi.fb = (rt_uint8_t *)bcm283x_mbox_fb_alloc(LCD_WIDTH, LCD_HEIGHT, LCD_BPP, 1);
  239. bcm283x_mbox_fb_setoffset(0, 0);
  240. bcm283x_mbox_fb_set_porder(0);
  241. _hdmi.width = LCD_WIDTH;
  242. _hdmi.height = LCD_HEIGHT;
  243. _hdmi.depth = LCD_DEPTH;
  244. _hdmi.pitch = 0;
  245. _hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
  246. armv8_map((unsigned long)_hdmi.fb, (unsigned long)_hdmi.fb, 0x200000, MEM_ATTR_IO);
  247. rt_hw_dcache_invalidate_range((unsigned long)_hdmi.fb,LCD_WIDTH * LCD_HEIGHT * 3);
  248. //rt_kprintf("_hdmi.fb is %p\n", _hdmi.fb);
  249. rt_hdmi_fb_device_init(&_hdmi, "lcd");
  250. return 0;
  251. }
  252. INIT_DEVICE_EXPORT(hdmi_fb_init);