• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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