1 /* drivers/video/sunxi/disp2/disp/lcd/tft08006.c
2 *
3 * Copyright (c) 2017 Allwinnertech Co., Ltd.
4 * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
5 *
6 * tft08006 panel driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 &lcd0 {
12 lcd_used = <1>;
13
14 lcd_driver_name = "tft08006";
15 lcd_backlight = <50>;
16 lcd_if = <4>;
17
18 lcd_x = <800>;
19 lcd_y = <1280>;
20 lcd_width = <52>;
21 lcd_height = <52>;
22 lcd_dclk_freq = <68>;
23
24 lcd_pwm_used = <1>;
25 lcd_pwm_ch = <2>;
26 lcd_pwm_freq = <50000>;
27 lcd_pwm_pol = <1>;
28 lcd_pwm_max_limit = <255>;
29
30 lcd_hbp = <40>;
31 lcd_ht = <860>;
32 lcd_hspw = <20>;
33 lcd_vbp = <24>;
34 lcd_vt = <1330>;
35 lcd_vspw = <4>;
36
37 lcd_dsi_if = <0>;
38 lcd_dsi_lane = <4>;
39 lcd_lvds_if = <0>;
40 lcd_lvds_colordepth = <0>;
41 lcd_lvds_mode = <0>;
42 lcd_frm = <0>;
43 lcd_hv_clk_phase = <0>;
44 lcd_hv_sync_polarity= <0>;
45 lcd_gamma_en = <0>;
46 lcd_bright_curve_en = <0>;
47 lcd_cmap_en = <0>;
48 lcd_fsync_en = <0>;
49 lcd_fsync_act_time = <1000>;
50 lcd_fsync_dis_time = <1000>;
51 lcd_fsync_pol = <0>;
52
53 deu_mode = <0>;
54 lcdgamma4iep = <22>;
55 smart_color = <90>;
56
57 lcd_gpio_0 = <&pio PG 13 GPIO_ACTIVE_HIGH>;
58 pinctrl-0 = <&dsi4lane_pins_a>;
59 pinctrl-1 = <&dsi4lane_pins_b>;
60 };
61 */
62 #include "tft08006.h"
63
64 static void lcd_power_on(u32 sel);
65 static void lcd_power_off(u32 sel);
66 static void lcd_bl_open(u32 sel);
67 static void lcd_bl_close(u32 sel);
68
69 static void lcd_panel_init(u32 sel);
70 static void lcd_panel_exit(u32 sel);
71
72 #define panel_reset(sel, val) sunxi_lcd_gpio_set_value(sel, 0, val)
73
lcd_cfg_panel_info(struct panel_extend_para * info)74 static void lcd_cfg_panel_info(struct panel_extend_para *info)
75 {
76 u32 i = 0, j = 0;
77 u32 items;
78 u8 lcd_gamma_tbl[][2] = {
79 {0, 0},
80 {15, 15},
81 {30, 30},
82 {45, 45},
83 {60, 60},
84 {75, 75},
85 {90, 90},
86 {105, 105},
87 {120, 120},
88 {135, 135},
89 {150, 150},
90 {165, 165},
91 {180, 180},
92 {195, 195},
93 {210, 210},
94 {225, 225},
95 {240, 240},
96 {255, 255},
97 };
98
99 u32 lcd_cmap_tbl[2][3][4] = {
100 {
101 {LCD_CMAP_G0, LCD_CMAP_B1, LCD_CMAP_G2, LCD_CMAP_B3},
102 {LCD_CMAP_B0, LCD_CMAP_R1, LCD_CMAP_B2, LCD_CMAP_R3},
103 {LCD_CMAP_R0, LCD_CMAP_G1, LCD_CMAP_R2, LCD_CMAP_G3},
104 },
105 {
106 {LCD_CMAP_B3, LCD_CMAP_G2, LCD_CMAP_B1, LCD_CMAP_G0},
107 {LCD_CMAP_R3, LCD_CMAP_B2, LCD_CMAP_R1, LCD_CMAP_B0},
108 {LCD_CMAP_G3, LCD_CMAP_R2, LCD_CMAP_G1, LCD_CMAP_R0},
109 },
110 };
111
112 items = sizeof(lcd_gamma_tbl) / 2;
113 for (i = 0; i < items - 1; i++) {
114 u32 num = lcd_gamma_tbl[i + 1][0] - lcd_gamma_tbl[i][0];
115
116 for (j = 0; j < num; j++) {
117 u32 value = 0;
118
119 value = lcd_gamma_tbl[i][1] +
120 ((lcd_gamma_tbl[i + 1][1] - lcd_gamma_tbl[i][1])
121 * j) / num;
122 info->lcd_gamma_tbl[lcd_gamma_tbl[i][0] + j] =
123 (value << 16)
124 + (value << 8) + value;
125 }
126 }
127 info->lcd_gamma_tbl[255] = (lcd_gamma_tbl[items - 1][1] << 16) +
128 (lcd_gamma_tbl[items - 1][1] << 8)
129 + lcd_gamma_tbl[items - 1][1];
130
131 memcpy(info->lcd_cmap_tbl, lcd_cmap_tbl, sizeof(lcd_cmap_tbl));
132
133 }
134
lcd_open_flow(u32 sel)135 static s32 lcd_open_flow(u32 sel)
136 {
137 LCD_OPEN_FUNC(sel, lcd_power_on, 10);
138 LCD_OPEN_FUNC(sel, lcd_panel_init, 10);
139 LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable, 50);
140 LCD_OPEN_FUNC(sel, lcd_bl_open, 0);
141
142 return 0;
143 }
144
lcd_close_flow(u32 sel)145 static s32 lcd_close_flow(u32 sel)
146 {
147 LCD_CLOSE_FUNC(sel, lcd_bl_close, 0);
148 LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable, 0);
149 LCD_CLOSE_FUNC(sel, lcd_panel_exit, 200);
150 LCD_CLOSE_FUNC(sel, lcd_power_off, 500);
151
152 return 0;
153 }
154
lcd_power_on(u32 sel)155 static void lcd_power_on(u32 sel)
156 {
157 sunxi_lcd_pin_cfg(sel, 1);
158 sunxi_lcd_delay_ms(50);
159 panel_reset(sel, 1);
160 sunxi_lcd_delay_ms(5);
161 panel_reset(sel, 0);
162 sunxi_lcd_delay_ms(10);
163 panel_reset(sel, 1);
164 sunxi_lcd_delay_ms(120);
165
166 }
167
lcd_power_off(u32 sel)168 static void lcd_power_off(u32 sel)
169 {
170 sunxi_lcd_pin_cfg(sel, 0);
171 sunxi_lcd_delay_ms(20);
172 panel_reset(sel, 0);
173 sunxi_lcd_delay_ms(5);
174 }
175
lcd_bl_open(u32 sel)176 static void lcd_bl_open(u32 sel)
177 {
178 sunxi_lcd_pwm_enable(sel);
179 }
180
lcd_bl_close(u32 sel)181 static void lcd_bl_close(u32 sel)
182 {
183 sunxi_lcd_pwm_disable(sel);
184 }
185
186 #define REGFLAG_DELAY 0XFC
187 #define REGFLAG_END_OF_TABLE 0xFD /* END OF REGISTERS MARKER */
188
189 struct LCM_setting_table {
190 u8 cmd;
191 u32 count;
192 u8 para_list[32];
193 };
194
195 static struct LCM_setting_table lcm_tft08006_setting[] = {
196 #if 0
197 {0xFF, 3, {0x98, 0x81, 0x03} },
198 {0x01, 1, {0x00} },
199 {0x02, 1, {0x00} },
200 {0x03, 1, {0x53} },
201 {0x04, 1, {0x53} },
202 {0x05, 1, {0x13} },
203 {0x06, 1, {0x04} },
204 {0x07, 1, {0x02} },
205 {0x08, 1, {0x02} },
206 {0x09, 1, {0x00} },
207 {0x0a, 1, {0x00} },
208 {0x0b, 1, {0x00} },
209 {0x0c, 1, {0x00} },
210 {0x0d, 1, {0x00} },
211 {0x0e, 1, {0x00} },
212 {0x0f, 1, {0x00} },
213 {0x10, 1, {0x00} },
214 {0x11, 1, {0x00} },
215 {0x12, 1, {0x00} },
216 {0x13, 1, {0x00} },
217 {0x14, 1, {0x00} },
218 {0x15, 1, {0x00} },
219 {0x16, 1, {0x00} },
220 {0x17, 1, {0x00} },
221 {0x18, 1, {0x00} },
222 {0x19, 1, {0x00} },
223 {0x1a, 1, {0x00} },
224 {0x1b, 1, {0x00} },
225 {0x1c, 1, {0x00} },
226 {0x1d, 1, {0x00} },
227 {0x1e, 1, {0xc0} },
228 {0x1f, 1, {0x80} },
229 {0x20, 1, {0x02} },
230 {0x21, 1, {0x09} },
231 {0x22, 1, {0x00} },
232 {0x23, 1, {0x00} },
233 {0x24, 1, {0x00} },
234 {0x25, 1, {0x00} },
235 {0x26, 1, {0x00} },
236 {0x27, 1, {0x00} },
237 {0x28, 1, {0x55} },
238 {0x29, 1, {0x03} },
239 {0x2a, 1, {0x00} },
240 {0x2b, 1, {0x00} },
241 {0x2c, 1, {0x00} },
242 {0x2d, 1, {0x00} },
243 {0x2e, 1, {0x00} },
244 {0x2f, 1, {0x00} },
245 {0x30, 1, {0x00} },
246 {0x31, 1, {0x00} },
247 {0x32, 1, {0x00} },
248 {0x33, 1, {0x00} },
249 {0x34, 1, {0x00} },
250 {0x35, 1, {0x00} },
251 {0x36, 1, {0x00} },
252 {0x37, 1, {0x00} },
253 {0x38, 1, {0x3C} },
254 {0x39, 1, {0x00} },
255 {0x3a, 1, {0x00} },
256 {0x3b, 1, {0x00} },
257 {0x3c, 1, {0x00} },
258 {0x3d, 1, {0x00} },
259 {0x3e, 1, {0x00} },
260 {0x3f, 1, {0x00} },
261 {0x40, 1, {0x00} },
262 {0x41, 1, {0x00} },
263 {0x42, 1, {0x00} },
264 {0x43, 1, {0x00} },
265 {0x44, 1, {0x00} },
266 {0x50, 1, {0x01} },
267 {0x51, 1, {0x23} },
268 {0x52, 1, {0x45} },
269 {0x53, 1, {0x67} },
270 {0x54, 1, {0x89} },
271 {0x55, 1, {0xab} },
272 {0x56, 1, {0x01} },
273 {0x57, 1, {0x23} },
274 {0x58, 1, {0x45} },
275 {0x59, 1, {0x67} },
276 {0x5a, 1, {0x89} },
277 {0x5b, 1, {0xab} },
278 {0x5c, 1, {0xcd} },
279 {0x5d, 1, {0xef} },
280 {0x5e, 1, {0x01} },
281 {0x5f, 1, {0x08} },
282 {0x60, 1, {0x02} },
283 {0x61, 1, {0x02} },
284 {0x62, 1, {0x0A} },
285 {0x63, 1, {0x15} },
286 {0x64, 1, {0x14} },
287 {0x65, 1, {0x02} },
288 {0x66, 1, {0x11} },
289 {0x67, 1, {0x10} },
290 {0x68, 1, {0x02} },
291 {0x69, 1, {0x0F} },
292 {0x6a, 1, {0x0E} },
293 {0x6b, 1, {0x02} },
294 {0x6c, 1, {0x0D} },
295 {0x6d, 1, {0x0C} },
296 {0x6e, 1, {0x06} },
297 {0x6f, 1, {0x02} },
298 {0x70, 1, {0x02} },
299 {0x71, 1, {0x02} },
300 {0x72, 1, {0x02} },
301 {0x73, 1, {0x02} },
302 {0x74, 1, {0x02} },
303 {0x75, 1, {0x06} },
304 {0x76, 1, {0x02} },
305 {0x77, 1, {0x02} },
306 {0x78, 1, {0x0A} },
307 {0x79, 1, {0x15} },
308 {0x7a, 1, {0x14} },
309 {0x7b, 1, {0x02} },
310 {0x7c, 1, {0x10} },
311 {0x7d, 1, {0x11} },
312 {0x7e, 1, {0x02} },
313 {0x7f, 1, {0x0C} },
314 {0x80, 1, {0x0D} },
315 {0x81, 1, {0x02} },
316 {0x82, 1, {0x0E} },
317 {0x83, 1, {0x0F} },
318 {0x84, 1, {0x08} },
319 {0x85, 1, {0x02} },
320 {0x86, 1, {0x02} },
321 {0x87, 1, {0x02} },
322 {0x88, 1, {0x02} },
323 {0x89, 1, {0x02} },
324 {0x8A, 1, {0x02} },
325
326 {0xFF, 3, {0x98, 0x81, 0x04} },
327 {0x6C, 1, {0x15} },
328 {0x6E, 1, {0x30} },
329 {0x6F, 1, {0x37} }, //3VSP 3VSN
330 {0x8D, 1, {0x1F} },
331 {0x87, 1, {0xBA} },
332 {0x26, 1, {0x76} },
333 {0xB2, 1, {0xD1} },
334 {0xB5, 1, {0x07} },
335 {0x35, 1, {0x17} },
336 {0x33, 1, {0x14} },
337 {0x31, 1, {0x75} },
338 {0x3A, 1, {0x85} },
339 {0x3B, 1, {0x98} },
340 {0x38, 1, {0x01} },
341 {0x39, 1, {0x00} },
342 {0x7A, 1, {0x10} },
343
344 {0xFF, 3, {0x98, 0x81, 0x01} },
345 {0x22, 1, {0x0A} },
346 {0x31, 1, {0x00} },
347 {0x50, 1, {0xCF} }, //5.2V
348 {0x51, 1, {0xCA} }, //-5.2V
349 {0x53, 1, {0x45} }, //45 41
350 {0x55, 1, {0x48} },
351 {0x60, 1, {0x28} },
352 {0x2E, 1, {0xC8} },
353 {0x34, 1, {0x01} },
354
355 //{0x56, 1, {0x00} },
356
357 {0xA0, 1, {0x00} }, //VP255 Gamma P
358 {0xA1, 1, {0x08} }, //VP251
359 {0xA2, 1, {0x18} }, //VP247
360 {0xA3, 1, {0x15} }, //VP243
361 {0xA4, 1, {0x19} }, //VP239
362 {0xA5, 1, {0x2D} }, //VP231
363 {0xA6, 1, {0x21} }, //VP219
364 {0xA7, 1, {0x23} }, //VP203
365 {0xA8, 1, {0x74} }, //VP175
366 {0xA9, 1, {0x1C} }, //VP144
367 {0xAA, 1, {0x26} }, //VP111
368 {0xAB, 1, {0x64} }, //VP80
369 {0xAC, 1, {0x1A} }, //VP52
370 {0xAD, 1, {0x1C} }, //VP36
371 {0xAE, 1, {0x50} }, //VP24
372 {0xAF, 1, {0x25} }, //VP16
373 {0xB0, 1, {0x2A} }, //VP12
374 {0xB1, 1, {0x4C} }, //VP8
375 {0xB2, 1, {0x5D} }, //VP4
376 {0xB3, 1, {0x23} }, //VP0
377
378 {0xC0, 1, {0x00} }, //VN255 GAMMA N
379 {0xC1, 1, {0x1B} }, //VN251
380 {0xC2, 1, {0x27} }, //VN247
381 {0xC3, 1, {0x13} }, //VN243
382 {0xC4, 1, {0x16} }, //VN239
383 {0xC5, 1, {0x28} }, //VN231
384 {0xC6, 1, {0x1E} }, //VN219
385 {0xC7, 1, {0x20} }, //VN203
386 {0xC8, 1, {0x7D} }, //VN175
387 {0xC9, 1, {0x19} }, //VN144
388 {0xCA, 1, {0x27} }, //VN111
389 {0xCB, 1, {0x65} }, //VN80
390 {0xCC, 1, {0x1D} }, //VN52
391 {0xCD, 1, {0x1D} }, //VN36
392 {0xCE, 1, {0x52} }, //VN24
393 {0xCF, 1, {0x26} }, //VN16
394 {0xD0, 1, {0x2C} }, //VN12
395 {0xD1, 1, {0x4E} }, //VN8
396 {0xD2, 1, {0x59} }, //VN4
397 {0xD3, 1, {0x23} }, //VN0
398
399 //{0xFF, 3, {0x98, 0x81, 0x04} },
400 //{0x2F, 1, {0x01} },
401
402 {0xFF, 3, {0x98, 0x81, 0x00} },
403 {0x35, 1, {0x00} },
404 #endif
405
406 {0x11, 0, {} },
407 {REGFLAG_DELAY, REGFLAG_DELAY, {120} },
408
409 {0x29, 0, {} },
410 {REGFLAG_DELAY, REGFLAG_DELAY, {120} },
411
412 {REGFLAG_END_OF_TABLE, REGFLAG_END_OF_TABLE, {} }
413 };
414
lcd_panel_init(u32 sel)415 static void lcd_panel_init(u32 sel)
416 {
417 __u32 i;
418 sunxi_lcd_dsi_clk_enable(sel);
419 sunxi_lcd_delay_ms(100);
420 for (i = 0;; i++) {
421 if (lcm_tft08006_setting[i].count == REGFLAG_END_OF_TABLE)
422 break;
423 else if (lcm_tft08006_setting[i].count == REGFLAG_DELAY) {
424 sunxi_lcd_delay_ms(lcm_tft08006_setting[i].para_list[0]);
425 } else {
426 dsi_gen_wr(sel, lcm_tft08006_setting[i].cmd,
427 lcm_tft08006_setting[i].para_list,
428 lcm_tft08006_setting[i].count);
429 }
430 /* break; */
431 }
432 }
433
lcd_panel_exit(u32 sel)434 static void lcd_panel_exit(u32 sel)
435 {
436 sunxi_lcd_dsi_dcs_write_0para(sel, 0x10);
437 sunxi_lcd_delay_ms(80);
438 sunxi_lcd_dsi_dcs_write_0para(sel, 0x28);
439 sunxi_lcd_delay_ms(50);
440 }
441
442 /*sel: 0:lcd0; 1:lcd1*/
lcd_user_defined_func(u32 sel,u32 para1,u32 para2,u32 para3)443 static s32 lcd_user_defined_func(u32 sel, u32 para1, u32 para2, u32 para3)
444 {
445 return 0;
446 }
447
448 struct __lcd_panel tft08006_panel = {
449 /* panel driver name, must mach the name of
450 * lcd_drv_name in sys_config.fex
451 */
452 .name = "tft08006",
453 .func = {
454 .cfg_panel_info = lcd_cfg_panel_info,
455 .cfg_open_flow = lcd_open_flow,
456 .cfg_close_flow = lcd_close_flow,
457 .lcd_user_defined_func = lcd_user_defined_func,
458 },
459 };
460