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