mc10128007_31b.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * Copyright (c) 2023 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include "hpm_panel.h"
  8. #include "hpm_pixelmux_drv.h"
  9. #include "hpm_mipi_dsi_drv.h"
  10. #include "hpm_mipi_dsi_phy_drv.h"
  11. #include <stdio.h>
  12. typedef struct mipi_cmd_list {
  13. uint16_t len;
  14. uint8_t cmd[4];
  15. } mipi_cmd_list_t;
  16. static const mipi_cmd_list_t mipi_panel_cmd[] = {
  17. {4, {0xFF, 0x98, 0x81, 0x03}},
  18. {2, {0x01, 0x00}},
  19. {2, {0x02, 0x00}},
  20. {2, {0x03, 0x55}},
  21. {2, {0x04, 0x55}},
  22. {2, {0x05, 0x03}},
  23. {2, {0x06, 0x06}},
  24. {2, {0x07, 0x00}},
  25. {2, {0x08, 0x07}},
  26. {2, {0x09, 0x00}},
  27. {2, {0x0A, 0x00}},
  28. {2, {0x0B, 0x00}},
  29. {2, {0x0C, 0x00}},
  30. {2, {0x0D, 0x00}},
  31. {2, {0x0E, 0x00}},
  32. {2, {0x0F, 0x00}},
  33. {2, {0x10, 0x00}},
  34. {2, {0x11, 0x00}},
  35. {2, {0x12, 0x00}},
  36. {2, {0x13, 0x00}},
  37. {2, {0x14, 0x00}},
  38. {2, {0x15, 0x00}},
  39. {2, {0x16, 0x00}},
  40. {2, {0x17, 0x00}},
  41. {2, {0x18, 0x00}},
  42. {2, {0x19, 0x00}},
  43. {2, {0x1A, 0x00}},
  44. {2, {0x1B, 0x00}},
  45. {2, {0x1C, 0x00}},
  46. {2, {0x1D, 0x00}},
  47. {2, {0x1E, 0xC0}},
  48. {2, {0x1F, 0x80}},
  49. {2, {0x20, 0x04}},
  50. {2, {0x21, 0x03}},
  51. {2, {0x22, 0x00}},
  52. {2, {0x23, 0x00}},
  53. {2, {0x24, 0x00}},
  54. {2, {0x25, 0x00}},
  55. {2, {0x26, 0x00}},
  56. {2, {0x27, 0x00}},
  57. {2, {0x28, 0x33}},
  58. {2, {0x29, 0x33}},
  59. {2, {0x2A, 0x00}},
  60. {2, {0x2B, 0x00}},
  61. {2, {0x2C, 0x00}},
  62. {2, {0x2D, 0x00}},
  63. {2, {0x2E, 0x00}},
  64. {2, {0x2F, 0x00}},
  65. {2, {0x30, 0x00}},
  66. {2, {0x31, 0x00}},
  67. {2, {0x32, 0x00}},
  68. {2, {0x33, 0x00}},
  69. {2, {0x34, 0x04}},
  70. {2, {0x35, 0x00}},
  71. {2, {0x36, 0x00}},
  72. {2, {0x37, 0x00}},
  73. {2, {0x38, 0x3C}},
  74. {2, {0x39, 0x00}},
  75. {2, {0x3A, 0x00}},
  76. {2, {0x3B, 0x00}},
  77. {2, {0x3C, 0x00}},
  78. {2, {0x3D, 0x00}},
  79. {2, {0x3E, 0x00}},
  80. {2, {0x3F, 0x00}},
  81. {2, {0x40, 0x00}},
  82. {2, {0x41, 0x00}},
  83. {2, {0x42, 0x00}},
  84. {2, {0x43, 0x00}},
  85. {2, {0x44, 0x00}},
  86. {2, {0x50, 0x00}},
  87. {2, {0x51, 0x11}},
  88. {2, {0x52, 0x44}},
  89. {2, {0x53, 0x55}},
  90. {2, {0x54, 0x88}},
  91. {2, {0x55, 0xAB}},
  92. {2, {0x56, 0x00}},
  93. {2, {0x57, 0x11}},
  94. {2, {0x58, 0x22}},
  95. {2, {0x59, 0x33}},
  96. {2, {0x5A, 0x44}},
  97. {2, {0x5B, 0x55}},
  98. {2, {0x5C, 0x66}},
  99. {2, {0x5D, 0x77}},
  100. {2, {0x5E, 0x00}},
  101. {2, {0x5F, 0x02}},
  102. {2, {0x60, 0x02}},
  103. {2, {0x61, 0x0A}},
  104. {2, {0x62, 0x09}},
  105. {2, {0x63, 0x08}},
  106. {2, {0x64, 0x13}},
  107. {2, {0x65, 0x12}},
  108. {2, {0x66, 0x11}},
  109. {2, {0x67, 0x10}},
  110. {2, {0x68, 0x0F}},
  111. {2, {0x69, 0x0E}},
  112. {2, {0x6A, 0x0D}},
  113. {2, {0x6B, 0x0C}},
  114. {2, {0x6C, 0x06}},
  115. {2, {0x6D, 0x07}},
  116. {2, {0x6E, 0x02}},
  117. {2, {0x6F, 0x02}},
  118. {2, {0x70, 0x02}},
  119. {2, {0x71, 0x02}},
  120. {2, {0x72, 0x02}},
  121. {2, {0x73, 0x02}},
  122. {2, {0x74, 0x02}},
  123. {2, {0x75, 0x02}},
  124. {2, {0x76, 0x02}},
  125. {2, {0x77, 0x0A}},
  126. {2, {0x78, 0x06}},
  127. {2, {0x79, 0x07}},
  128. {2, {0x7A, 0x10}},
  129. {2, {0x7B, 0x11}},
  130. {2, {0x7C, 0x12}},
  131. {2, {0x7D, 0x13}},
  132. {2, {0x7E, 0x0C}},
  133. {2, {0x7F, 0x0D}},
  134. {2, {0x80, 0x0E}},
  135. {2, {0x81, 0x0F}},
  136. {2, {0x82, 0x09}},
  137. {2, {0x83, 0x08}},
  138. {2, {0x84, 0x02}},
  139. {2, {0x85, 0x02}},
  140. {2, {0x86, 0x02}},
  141. {2, {0x87, 0x02}},
  142. {2, {0x88, 0x02}},
  143. {2, {0x89, 0x02}},
  144. {2, {0x8A, 0x02}},
  145. {4, {0xFF, 0x98, 0x81, 0x04}},
  146. {2, {0x6E, 0x2A}},
  147. {2, {0x6F, 0x37}},
  148. {2, {0x3A, 0x24}},
  149. {2, {0x8D, 0x19}},
  150. {2, {0x87, 0xBA}},
  151. {2, {0xB2, 0xD1}},
  152. {2, {0x88, 0x0B}},
  153. {2, {0x38, 0x01}},
  154. {2, {0x39, 0x00}},
  155. {2, {0xB5, 0x02}},
  156. {2, {0x31, 0x25}},
  157. {2, {0x3B, 0x98}},
  158. {4, {0xFF, 0x98, 0x81, 0x01}},
  159. {2, {0x22, 0x0A}},
  160. {2, {0x31, 0x0C}},
  161. {2, {0x53, 0x40}},
  162. {2, {0x55, 0x45}},
  163. {2, {0x50, 0xB7}},
  164. {2, {0x51, 0xB2}},
  165. {2, {0x60, 0x07}},
  166. {2, {0xA0, 0x22}},
  167. {2, {0xA1, 0x3F}},
  168. {2, {0xA2, 0x4E}},
  169. {2, {0xA3, 0x17}},
  170. {2, {0xA4, 0x1A}},
  171. {2, {0xA5, 0x2D}},
  172. {2, {0xA6, 0x21}},
  173. {2, {0xA7, 0x22}},
  174. {2, {0xA8, 0xC4}},
  175. {2, {0xA9, 0x1B}},
  176. {2, {0xAA, 0x25}},
  177. {2, {0xAB, 0xA7}},
  178. {2, {0xAC, 0x1A}},
  179. {2, {0xAD, 0x19}},
  180. {2, {0xAE, 0x4B}},
  181. {2, {0xAF, 0x1F}},
  182. {2, {0xB0, 0x2A}},
  183. {2, {0xB1, 0x59}},
  184. {2, {0xB2, 0x64}},
  185. {2, {0xB3, 0x3F}},
  186. {2, {0xC0, 0x22}},
  187. {2, {0xC1, 0x48}},
  188. {2, {0xC2, 0x59}},
  189. {2, {0xC3, 0x15}},
  190. {2, {0xC4, 0x15}},
  191. {2, {0xC5, 0x28}},
  192. {2, {0xC6, 0x1C}},
  193. {2, {0xC7, 0x1E}},
  194. {2, {0xC8, 0xC4}},
  195. {2, {0xC9, 0x1C}},
  196. {2, {0xCA, 0x2B}},
  197. {2, {0xCB, 0xA3}},
  198. {2, {0xCC, 0x1F}},
  199. {2, {0xCD, 0x1E}},
  200. {2, {0xCE, 0x52}},
  201. {2, {0xCF, 0x24}},
  202. {2, {0xD0, 0x2A}},
  203. {2, {0xD1, 0x58}},
  204. {2, {0xD2, 0x68}},
  205. {2, {0xD3, 0x3F}},
  206. {4, {0xFF, 0x98, 0x81, 0x00}},
  207. {1, {0x11}},
  208. {1, {0x29}},
  209. };
  210. static void mipi_panel_init_cmd_send(hpm_panel_t *panel)
  211. {
  212. int ret;
  213. uint8_t page_cmd[4] = {0xFF, 0x98, 0x81, 0x01};
  214. uint8_t panel_id[2] = {0x98, 0x81};
  215. uint8_t rdata;
  216. MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
  217. mipi_dsi_dcs_write_buffer(mipi_host, 0, page_cmd, 4);
  218. for (int i = 0; i < 2; i++) {
  219. mipi_dsi_set_maximum_return_packet_size(mipi_host, 0, 1);
  220. ret = mipi_dsi_dcs_read(mipi_host, 0, i, &rdata, 1);
  221. if (ret <= 0 || rdata != panel_id[i]) {
  222. printf("read id[%d]: 0x%02X -- failed\n", i, rdata);
  223. while (1) {
  224. }
  225. } else {
  226. printf("read id[%d]: 0x%02X -- ok\n", i, rdata);
  227. }
  228. hpm_panel_delay_ms(10);
  229. }
  230. int mipi_cmd_num = sizeof(mipi_panel_cmd) / sizeof(mipi_panel_cmd[0]);
  231. for (int i = 0; i < mipi_cmd_num; i++) {
  232. ret = mipi_dsi_dcs_write_buffer(mipi_host, 0, mipi_panel_cmd[i].cmd, mipi_panel_cmd[i].len);
  233. if (ret <= 0)
  234. printf("mipi_cmd[%d].cmd: 0x%02X -- failed\n", i, mipi_panel_cmd[i].cmd[0]);
  235. }
  236. hpm_panel_delay_ms(10);
  237. }
  238. static void mipi_panel_host_init(hpm_panel_t *panel)
  239. {
  240. MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
  241. const hpm_panel_timing_t *timing = &panel->timing;
  242. mipi_dsi_config_t mipi_cfg;
  243. mipi_dsi_get_defconfig_on_video(&mipi_cfg);
  244. mipi_cfg.channel = 0;
  245. mipi_cfg.lanes = 4;
  246. mipi_cfg.video_para.pixel_clock_khz = panel->hw_if.lcdc_pixel_clk_khz;
  247. mipi_cfg.video_para.hactive = timing->hactive;
  248. mipi_cfg.video_para.hsync_len = timing->hsync_len;
  249. mipi_cfg.video_para.hback_porch = timing->hback_porch;
  250. mipi_cfg.video_para.hfront_porch = timing->hfront_porch;
  251. mipi_cfg.video_para.vsync_len = timing->vsync_len;
  252. mipi_cfg.video_para.vactive = timing->vactive;
  253. mipi_cfg.video_para.vback_porch = timing->vback_porch;
  254. mipi_cfg.video_para.vfront_porch = timing->vfront_porch;
  255. mipi_dsi_init(mipi_host, &mipi_cfg);
  256. }
  257. static void mipi_panel_phy_init(hpm_panel_t *panel)
  258. {
  259. MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
  260. MIPI_DSI_PHY_Type *mipi_phy = panel->hw_if.video.mipi.mipi_phy_base;
  261. mipi_dsi_phy_config_t mipi_phy_cfg = {
  262. .lanes = 4,
  263. .lane_mbps = 500
  264. };
  265. mipi_dsi_phy_powerdown(mipi_host);
  266. mipi_dsi_phy_init(mipi_phy, &mipi_phy_cfg);
  267. mipi_dsi_phy_poweron(mipi_host);
  268. }
  269. static void reset(hpm_panel_t *panel)
  270. {
  271. if (!panel->hw_if.set_reset_pin_level)
  272. return;
  273. panel->hw_if.set_reset_pin_level(0);
  274. hpm_panel_delay_ms(20);
  275. panel->hw_if.set_reset_pin_level(1);
  276. hpm_panel_delay_ms(15);
  277. }
  278. static void init(hpm_panel_t *panel)
  279. {
  280. if (panel->hw_if.set_video_router)
  281. panel->hw_if.set_video_router();
  282. mipi_panel_host_init(panel);
  283. mipi_panel_phy_init(panel);
  284. mipi_panel_init_cmd_send(panel);
  285. }
  286. static void power_on(hpm_panel_t *panel)
  287. {
  288. MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
  289. if (panel->state.power_state != HPM_PANEL_STATE_POWER_ON) {
  290. mipi_dsi_video_mode_hs_transfer_enable(mipi_host);
  291. if (panel->hw_if.set_backlight) {
  292. if (panel->state.backlight_percent == 0)
  293. panel->state.backlight_percent = 100;
  294. panel->hw_if.set_backlight(panel->state.backlight_percent);
  295. }
  296. panel->state.power_state = HPM_PANEL_STATE_POWER_ON;
  297. }
  298. }
  299. static void power_off(hpm_panel_t *panel)
  300. {
  301. MIPI_DSI_Type *mipi_host = panel->hw_if.video.mipi.mipi_host_base;
  302. if (panel->state.power_state != HPM_PANEL_STATE_POWER_OFF) {
  303. if (panel->hw_if.set_backlight)
  304. panel->hw_if.set_backlight(0);
  305. mipi_dsi_video_mode_hs_transfer_disable(mipi_host);
  306. panel->state.power_state = HPM_PANEL_STATE_POWER_OFF;
  307. }
  308. }
  309. hpm_panel_t panel_mc10128007_31b = {
  310. .name = "mc10128007_31b",
  311. .if_type = HPM_PANEL_IF_TYPE_MIPI,
  312. .timing = {
  313. .pixel_clock_khz = 60000,
  314. .hactive = 800,
  315. .hfront_porch = 52,
  316. .hback_porch = 48,
  317. .hsync_len = 8,
  318. .vactive = 1280,
  319. .vfront_porch = 15,
  320. .vback_porch = 16,
  321. .vsync_len = 6,
  322. },
  323. .funcs = {
  324. .reset = reset,
  325. .init = init,
  326. .power_on = power_on,
  327. .power_off = power_off,
  328. },
  329. };