1 /*
2  * Allwinner SoCs display driver.
3  *
4  * Copyright (C) 2016 Allwinner.
5  *
6  * This file is licensed under the terms of the GNU General Public
7  * License version 2.  This program is licensed "as is" without any
8  * warranty of any kind, whether express or implied.
9  */
10 
11 #include "inet_dsi_panel.h"
12 #include "panels.h"
13 
14 extern s32 bsp_disp_get_panel_info(u32 screen_id, struct disp_panel_para *info);
15 static void LCD_power_on(u32 sel);
16 static void LCD_power_off(u32 sel);
17 static void LCD_bl_open(u32 sel);
18 static void LCD_bl_close(u32 sel);
19 
20 static void LCD_panel_init(u32 sel);
21 static void LCD_panel_exit(u32 sel);
22 
23 static u8 const mipi_dcs_pixel_format[4] = {0x77, 0x66, 0x66, 0x55};
24 #define panel_reset(val) sunxi_lcd_gpio_set_value(sel, 1, val)
25 #define power_en(val) sunxi_lcd_gpio_set_value(sel, 0, val)
26 
LCD_cfg_panel_info(struct panel_extend_para * info)27 static void LCD_cfg_panel_info(struct panel_extend_para *info)
28 {
29     u32 i = 0, j = 0;
30     u32 items;
31     u8 lcd_gamma_tbl[][2] = {
32         /*{input value, corrected value} */
33         {0, 0},     {15, 15},   {30, 30},   {45, 45},   {60, 60},
34         {75, 75},   {90, 90},   {105, 105}, {120, 120}, {135, 135},
35         {150, 150}, {165, 165}, {180, 180}, {195, 195}, {210, 210},
36         {225, 225}, {240, 240}, {255, 255},
37     };
38 
39     u32 lcd_cmap_tbl[2][3][4] = {
40         {
41         {LCD_CMAP_G0, LCD_CMAP_B1, LCD_CMAP_G2, LCD_CMAP_B3},
42         {LCD_CMAP_B0, LCD_CMAP_R1, LCD_CMAP_B2, LCD_CMAP_R3},
43         {LCD_CMAP_R0, LCD_CMAP_G1, LCD_CMAP_R2, LCD_CMAP_G3},
44         },
45         {
46         {LCD_CMAP_B3, LCD_CMAP_G2, LCD_CMAP_B1, LCD_CMAP_G0},
47         {LCD_CMAP_R3, LCD_CMAP_B2, LCD_CMAP_R1, LCD_CMAP_B0},
48         {LCD_CMAP_G3, LCD_CMAP_R2, LCD_CMAP_G1, LCD_CMAP_R0},
49         },
50     };
51 
52     items = sizeof(lcd_gamma_tbl) / 2;
53     for (i = 0; i < items - 1; i++) {
54         u32 num = lcd_gamma_tbl[i + 1][0] - lcd_gamma_tbl[i][0];
55 
56         for (j = 0; j < num; j++) {
57             u32 value = 0;
58 
59             value =
60                 lcd_gamma_tbl[i][1] +
61                 ((lcd_gamma_tbl[i + 1][1] - lcd_gamma_tbl[i][1]) *
62                  j) /
63                 num;
64             info->lcd_gamma_tbl[lcd_gamma_tbl[i][0] + j] =
65                 (value << 16) + (value << 8) + value;
66         }
67     }
68     info->lcd_gamma_tbl[255] = (lcd_gamma_tbl[items - 1][1] << 16) +
69                    (lcd_gamma_tbl[items - 1][1] << 8) +
70                    lcd_gamma_tbl[items - 1][1];
71 
72     memcpy(info->lcd_cmap_tbl, lcd_cmap_tbl, sizeof(lcd_cmap_tbl));
73 }
74 
LCD_open_flow(u32 sel)75 static s32 LCD_open_flow(u32 sel)
76 {
77     LCD_OPEN_FUNC(sel, LCD_power_on,
78               100); /* open lcd power, and delay 50ms */
79     LCD_OPEN_FUNC(sel, LCD_panel_init,
80               200); /* open lcd power, than delay 200ms */
81     LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable,
82               50); /* open lcd controller, and delay 100ms */
83     LCD_OPEN_FUNC(sel, LCD_bl_open,
84               0); /* open lcd backlight, and delay 0ms */
85 
86     return 0;
87 }
88 
LCD_close_flow(u32 sel)89 static s32 LCD_close_flow(u32 sel)
90 {
91     LCD_CLOSE_FUNC(sel, LCD_bl_close,
92                200); /* close lcd backlight, and delay 0ms */
93     LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable,
94                20); /* close lcd controller, and delay 0ms */
95     LCD_CLOSE_FUNC(sel, LCD_panel_exit,
96                10); /* open lcd power, than delay 200ms */
97     LCD_CLOSE_FUNC(sel, LCD_power_off,
98                500); /* close lcd power, and delay 500ms */
99 
100     return 0;
101 }
102 
LCD_power_on(u32 sel)103 static void LCD_power_on(u32 sel)
104 {
105     sunxi_lcd_power_enable(sel, 0); /* config lcd_power pin to open lcd */
106                     /* power */
107     sunxi_lcd_delay_ms(5);
108     sunxi_lcd_power_enable(sel,
109                    1); /* config lcd_power pin to open lcd power1 */
110     sunxi_lcd_delay_ms(5);
111     sunxi_lcd_power_enable(sel,
112                    2); /* config lcd_power pin to open lcd power2 */
113     sunxi_lcd_delay_ms(5);
114     power_en(1);
115     sunxi_lcd_delay_ms(20);
116     panel_reset(1);
117     sunxi_lcd_delay_ms(5);
118     sunxi_lcd_pin_cfg(sel, 1);
119 }
120 
LCD_power_off(u32 sel)121 static void LCD_power_off(u32 sel)
122 {
123     sunxi_lcd_pin_cfg(sel, 0);
124     power_en(0);
125     sunxi_lcd_delay_ms(20);
126     panel_reset(0);
127     sunxi_lcd_delay_ms(5);
128     sunxi_lcd_power_disable(
129         sel, 2); /* config lcd_power pin to close lcd power2 */
130     sunxi_lcd_delay_ms(5);
131     sunxi_lcd_power_disable(
132         sel, 1); /* config lcd_power pin to close lcd power1 */
133     sunxi_lcd_delay_ms(5);
134     sunxi_lcd_power_disable(
135         sel, 0); /* config lcd_power pin to close lcd power */
136 }
137 
LCD_bl_open(u32 sel)138 static void LCD_bl_open(u32 sel)
139 {
140     sunxi_lcd_pwm_enable(sel);
141     sunxi_lcd_delay_ms(50);
142     sunxi_lcd_backlight_enable(
143         sel); /* config lcd_bl_en pin to open lcd backlight */
144 }
145 
LCD_bl_close(u32 sel)146 static void LCD_bl_close(u32 sel)
147 {
148     sunxi_lcd_backlight_disable(
149         sel); /* config lcd_bl_en pin to close lcd backlight */
150     sunxi_lcd_delay_ms(20);
151     sunxi_lcd_pwm_disable(sel);
152 }
153 
154 #define REGFLAG_DELAY 0XFE
155 #define REGFLAG_END_OF_TABLE 0xFF /* END OF REGISTERS MARKER */
156 
157 struct LCM_setting_table {
158     u8 cmd;
159     u32 count;
160     u8 para_list[64];
161 };
162 
163 /*add panel initialization below*/
164 
165 static struct LCM_setting_table LCM_LT080B21BA94_setting[] = {
166     {0xE0, 1, { 0x00 } },
167     {0xE1, 1, { 0x93 } },
168     {0xE2, 1, { 0x65 } },
169     {0xE3, 1, { 0xF8 } },
170     {0xE0, 1, { 0x00 } },
171     {0x70, 1, { 0x02 } },
172     {0x71, 1, { 0x23 } },
173     {0x72, 1, { 0x06 } },
174     {0xE0, 1, { 0x01 } },
175     {0x00, 1, { 0x00 } },
176     {0x01, 1, { 0xA0 } },
177     {0x03, 1, { 0x00 } },
178     {0x04, 1, { 0xA0 } },
179     {0x17, 1, { 0x00 } },
180     {0x18, 1, { 0xB1 } },
181     {0x19, 1, { 0x00 } },
182     {0x1A, 1, { 0x00 } },
183     {0x1B, 1, { 0xB1 } },
184     {0x1C, 1, { 0x00 } },
185     {0x1F, 1, { 0x48 } },
186     {0x20, 1, { 0x23 } },
187     {0x21, 1, { 0x23 } },
188     {0x22, 1, { 0x0E } },
189     {0x23, 1, { 0x00 } },
190     {0x24, 1, { 0x38 } },
191     {0x26, 1, { 0xD3 } },
192     {0x37, 1, { 0x59 } },
193     {0x38, 1, { 0x05 } },
194     {0x39, 1, { 0x08 } },
195     {0x3A, 1, { 0x12 } },
196     {0x3C, 1, { 0x78 } },
197     {0x3E, 1, { 0x80 } },
198     {0x3F, 1, { 0x80 } },
199     {0x40, 1, { 0x06 } },
200     {0x41, 1, { 0xA0 } },
201     {0x55, 1, { 0x0F } },
202     {0x56, 1, { 0x01 } },
203     {0x57, 1, { 0x85 } },
204     {0x58, 1, { 0x0A } },
205     {0x59, 1, { 0x0A } },
206     {0x5A, 1, { 0x32 } },
207     {0x5B, 1, { 0x0F } },
208     {0x5D, 1, { 0x7C } },
209     {0x5E, 1, { 0x62 } },
210     {0x5F, 1, { 0x50 } },
211     {0x60, 1, { 0x42 } },
212     {0x61, 1, { 0x3D } },
213     {0x62, 1, { 0x2D } },
214     {0x63, 1, { 0x30 } },
215     {0x64, 1, { 0x19 } },
216     {0x65, 1, { 0x30 } },
217     {0x66, 1, { 0x2E } },
218     {0x67, 1, { 0x2D } },
219     {0x68, 1, { 0x4A } },
220     {0x69, 1, { 0x3A } },
221     {0x6A, 1, { 0x43 } },
222     {0x6B, 1, { 0x37 } },
223     {0x6C, 1, { 0x37 } },
224     {0x6D, 1, { 0x2D } },
225     {0x6E, 1, { 0x1F } },
226     {0x6F, 1, { 0x00 } },
227     {0x70, 1, { 0x7C } },
228     {0x71, 1, { 0x62 } },
229     {0x72, 1, { 0x50 } },
230     {0x73, 1, { 0x42 } },
231     {0x74, 1, { 0x3D } },
232     {0x75, 1, { 0x2D } },
233     {0x76, 1, { 0x30 } },
234     {0x77, 1, { 0x19 } },
235     {0x78, 1, { 0x30 } },
236     {0x79, 1, { 0x2E } },
237     {0x7A, 1, { 0x2D } },
238     {0x7B, 1, { 0x4A } },
239     {0x7C, 1, { 0x3A } },
240     {0x7D, 1, { 0x43 } },
241     {0x7E, 1, { 0x37 } },
242     {0x7F, 1, { 0x37 } },
243     {0x80, 1, { 0x2D } },
244     {0x81, 1, { 0x1F } },
245     {0x82, 1, { 0x00 } },
246     {0xE0, 1, { 0x02 } },
247     {0x00, 1, { 0x1F } },
248     {0x01, 1, { 0x1F } },
249     {0x02, 1, { 0x13 } },
250     {0x03, 1, { 0x11 } },
251     {0x04, 1, { 0x0B } },
252     {0x05, 1, { 0x0B } },
253     {0x06, 1, { 0x09 } },
254     {0x07, 1, { 0x09 } },
255     {0x08, 1, { 0x07 } },
256     {0x09, 1, { 0x1F } },
257     {0x0A, 1, { 0x1F } },
258     {0x0B, 1, { 0x1F } },
259     {0x0C, 1, { 0x1F } },
260     {0x0D, 1, { 0x1F } },
261     {0x0E, 1, { 0x1F } },
262     {0x0F, 1, { 0x07 } },
263     {0x10, 1, { 0x05 } },
264     {0x11, 1, { 0x05 } },
265     {0x12, 1, { 0x01 } },
266     {0x13, 1, { 0x03 } },
267     {0x14, 1, { 0x1F } },
268     {0x15, 1, { 0x1F } },
269     {0x16, 1, { 0x1F } },
270     {0x17, 1, { 0x1F } },
271     {0x18, 1, { 0x12 } },
272     {0x19, 1, { 0x10 } },
273     {0x1A, 1, { 0x0A } },
274     {0x1B, 1, { 0x0A } },
275     {0x1C, 1, { 0x08 } },
276     {0x1D, 1, { 0x08 } },
277     {0x1E, 1, { 0x06 } },
278     {0x1F, 1, { 0x1F } },
279     {0x20, 1, { 0x1F } },
280     {0x21, 1, { 0x1F } },
281     {0x22, 1, { 0x1F } },
282     {0x23, 1, { 0x1F } },
283     {0x24, 1, { 0x1F } },
284     {0x25, 1, { 0x06 } },
285     {0x26, 1, { 0x04 } },
286     {0x27, 1, { 0x04 } },
287     {0x28, 1, { 0x00 } },
288     {0x29, 1, { 0x02 } },
289     {0x2A, 1, { 0x1F } },
290     {0x2B, 1, { 0x1F } },
291     {0x2C, 1, { 0x1F } },
292     {0x2D, 1, { 0x1F } },
293     {0x2E, 1, { 0x00 } },
294     {0x2F, 1, { 0x02 } },
295     {0x30, 1, { 0x08 } },
296     {0x31, 1, { 0x08 } },
297     {0x32, 1, { 0x0A } },
298     {0x33, 1, { 0x0A } },
299     {0x34, 1, { 0x04 } },
300     {0x35, 1, { 0x1F } },
301     {0x36, 1, { 0x1F } },
302     {0x37, 1, { 0x1F } },
303     {0x38, 1, { 0x1F } },
304     {0x39, 1, { 0x1F } },
305     {0x3A, 1, { 0x1F } },
306     {0x3B, 1, { 0x04 } },
307     {0x3C, 1, { 0x06 } },
308     {0x3D, 1, { 0x06 } },
309     {0x3E, 1, { 0x12 } },
310     {0x3F, 1, { 0x10 } },
311     {0x40, 1, { 0x1F } },
312     {0x41, 1, { 0x1F } },
313     {0x42, 1, { 0x1F } },
314     {0x43, 1, { 0x1F } },
315     {0x44, 1, { 0x01 } },
316     {0x45, 1, { 0x03 } },
317     {0x46, 1, { 0x09 } },
318     {0x47, 1, { 0x09 } },
319     {0x48, 1, { 0x0B } },
320     {0x49, 1, { 0x0B } },
321     {0x4A, 1, { 0x05 } },
322     {0x4B, 1, { 0x1F } },
323     {0x4C, 1, { 0x1F } },
324     {0x4D, 1, { 0x1F } },
325     {0x4E, 1, { 0x1F } },
326     {0x4F, 1, { 0x1F } },
327     {0x50, 1, { 0x1F } },
328     {0x51, 1, { 0x05 } },
329     {0x52, 1, { 0x07 } },
330     {0x53, 1, { 0x07 } },
331     {0x54, 1, { 0x13 } },
332     {0x55, 1, { 0x11 } },
333     {0x56, 1, { 0x1F } },
334     {0x57, 1, { 0x1F } },
335     {0x58, 1, { 0x40 } },
336     {0x59, 1, { 0x00 } },
337     {0x5A, 1, { 0x00 } },
338     {0x5B, 1, { 0x30 } },
339     {0x5C, 1, { 0x02 } },
340     {0x5D, 1, { 0x30 } },
341     {0x5E, 1, { 0x01 } },
342     {0x5F, 1, { 0x02 } },
343     {0x60, 1, { 0x30 } },
344     {0x61, 1, { 0x01 } },
345     {0x62, 1, { 0x02 } },
346     {0x63, 1, { 0x03 } },
347     {0x64, 1, { 0x6B } },
348     {0x65, 1, { 0x75 } },
349     {0x66, 1, { 0x08 } },
350     {0x67, 1, { 0x73 } },
351     {0x68, 1, { 0x02 } },
352     {0x69, 1, { 0x03 } },
353     {0x6A, 1, { 0x6B } },
354     {0x6B, 1, { 0x07 } },
355     {0x6C, 1, { 0x00 } },
356     {0x6D, 1, { 0x04 } },
357     {0x6E, 1, { 0x04 } },
358     {0x6F, 1, { 0x88 } },
359     {0x70, 1, { 0x00 } },
360     {0x71, 1, { 0x00 } },
361     {0x72, 1, { 0x06 } },
362     {0x73, 1, { 0x7B } },
363     {0x74, 1, { 0x00 } },
364     {0x75, 1, { 0x3C } },
365     {0x76, 1, { 0x00 } },
366     {0x77, 1, { 0x0D } },
367     {0x78, 1, { 0x2C } },
368     {0x79, 1, { 0x00 } },
369     {0x7A, 1, { 0x00 } },
370     {0x7B, 1, { 0x00 } },
371     {0x7C, 1, { 0x00 } },
372     {0x7D, 1, { 0x03 } },
373     {0x7E, 1, { 0x7B } },
374     {0xE0, 1, { 0x01 } },
375     {0x0E, 1, { 0x01 } },
376     {0xE0, 1, { 0x03 } },
377     {0x98, 1, { 0x2F } },
378     {0xE0, 1, { 0x00 } },
379     {0x11, 0, { 0x00 } },
380     {REGFLAG_DELAY, REGFLAG_DELAY, { 200 } },
381     {0x29, 0, { 0x00 } },
382     {REGFLAG_DELAY, REGFLAG_DELAY, { 5 } },
383     {REGFLAG_END_OF_TABLE, REGFLAG_END_OF_TABLE, {} }
384 };
385 
LCD_panel_init(u32 sel)386 static void LCD_panel_init(u32 sel)
387 {
388     __u32 i;
389     char model_name[25];
390     disp_sys_script_get_item("lcd0", "lcd_model_name", (int *)model_name,
391                  25);
392     sunxi_lcd_dsi_clk_enable(sel);
393     sunxi_lcd_delay_ms(20);
394     sunxi_lcd_dsi_dcs_write_0para(sel, DSI_DCS_SOFT_RESET);
395     sunxi_lcd_delay_ms(10);
396 
397     for (i = 0;; i++) {
398         if (LCM_LT080B21BA94_setting[i].count == REGFLAG_END_OF_TABLE)
399             break;
400         else if (LCM_LT080B21BA94_setting[i].count == REGFLAG_DELAY)
401             sunxi_lcd_delay_ms(
402                 LCM_LT080B21BA94_setting[i].para_list[0]);
403 #ifdef SUPPORT_DSI
404         else
405             dsi_dcs_wr(sel, LCM_LT080B21BA94_setting[i].cmd,
406                    LCM_LT080B21BA94_setting[i].para_list,
407                    LCM_LT080B21BA94_setting[i].count);
408 #endif
409         /* break; */
410     }
411 
412     return;
413 }
414 
LCD_panel_exit(u32 sel)415 static void LCD_panel_exit(u32 sel)
416 {
417     sunxi_lcd_dsi_dcs_write_0para(sel, DSI_DCS_SET_DISPLAY_OFF);
418     sunxi_lcd_delay_ms(20);
419     sunxi_lcd_dsi_dcs_write_0para(sel, DSI_DCS_ENTER_SLEEP_MODE);
420     sunxi_lcd_delay_ms(80);
421 
422     return;
423 }
424 
425 /* sel: 0:lcd0; 1:lcd1 */
LCD_user_defined_func(u32 sel,u32 para1,u32 para2,u32 para3)426 static s32 LCD_user_defined_func(u32 sel, u32 para1, u32 para2, u32 para3)
427 {
428     return 0;
429 }
430 
431 /* sel: 0:lcd0; 1:lcd1 */
432 /*static s32 LCD_set_bright(u32 sel, u32 bright)*/
433 /*{*/
434     /*sunxi_lcd_dsi_dcs_write_1para(sel,0x51,bright);*/
435     /*return 0;*/
436 /*}*/
437 
438 struct __lcd_panel inet_dsi_panel = {
439     /* panel driver name, must mach the name of lcd_drv_name in sys_config.fex
440     */
441     .name = "inet_dsi_panel",
442     .func = {
443     .cfg_panel_info = LCD_cfg_panel_info,
444     .cfg_open_flow = LCD_open_flow,
445     .cfg_close_flow = LCD_close_flow,
446     .lcd_user_defined_func = LCD_user_defined_func,
447     /*.set_bright = LCD_set_bright, */
448     },
449 };
450