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 "tm_dsi_panel.h"
12 #include "panels.h"
13
14 extern s32 bsp_disp_get_panel_info(u32 screen_id,
15 struct disp_panel_para *info);
16 static void LCD_power_on(u32 sel);
17 static void LCD_power_off(u32 sel);
18 static void LCD_bl_open(u32 sel);
19 static void LCD_bl_close(u32 sel);
20
21 static void LCD_panel_init(u32 sel);
22 static void LCD_panel_exit(u32 sel);
23
24 static u8 const mipi_dcs_pixel_format[4] = {0x77, 0x66, 0x66, 0x55};
25 #define panel_reset(val) sunxi_lcd_gpio_set_value(sel, 1, val)
26 #define power_en(val) sunxi_lcd_gpio_set_value(sel, 0, val)
27
LCD_cfg_panel_info(struct panel_extend_para * info)28 static void LCD_cfg_panel_info(struct panel_extend_para *info)
29 {
30 u32 i = 0, j = 0;
31 u32 items;
32 u8 lcd_gamma_tbl[][2] = {
33 /*{input value, corrected value} */
34 {0, 0}, {15, 15}, {30, 30}, {45, 45}, {60, 60},
35 {75, 75}, {90, 90}, {105, 105}, {120, 120}, {135, 135},
36 {150, 150}, {165, 165}, {180, 180}, {195, 195}, {210, 210},
37 {225, 225}, {240, 240}, {255, 255},
38 };
39
40 u32 lcd_cmap_tbl[2][3][4] = {
41 {
42 {LCD_CMAP_G0, LCD_CMAP_B1, LCD_CMAP_G2, LCD_CMAP_B3},
43 {LCD_CMAP_B0, LCD_CMAP_R1, LCD_CMAP_B2, LCD_CMAP_R3},
44 {LCD_CMAP_R0, LCD_CMAP_G1, LCD_CMAP_R2, LCD_CMAP_G3},
45 },
46 {
47 {LCD_CMAP_B3, LCD_CMAP_G2, LCD_CMAP_B1, LCD_CMAP_G0},
48 {LCD_CMAP_R3, LCD_CMAP_B2, LCD_CMAP_R1, LCD_CMAP_B0},
49 {LCD_CMAP_G3, LCD_CMAP_R2, LCD_CMAP_G1, LCD_CMAP_R0},
50 },
51 };
52
53 items = sizeof(lcd_gamma_tbl) / 2;
54 for (i = 0; i < items - 1; i++) {
55 u32 num = lcd_gamma_tbl[i + 1][0] - lcd_gamma_tbl[i][0];
56
57 for (j = 0; j < num; j++) {
58 u32 value = 0;
59
60 value =
61 lcd_gamma_tbl[i][1] +
62 ((lcd_gamma_tbl[i + 1][1] - lcd_gamma_tbl[i][1]) *
63 j) /
64 num;
65 info->lcd_gamma_tbl[lcd_gamma_tbl[i][0] + j] =
66 (value << 16) + (value << 8) + value;
67 }
68 }
69 info->lcd_gamma_tbl[255] = (lcd_gamma_tbl[items - 1][1] << 16) +
70 (lcd_gamma_tbl[items - 1][1] << 8) +
71 lcd_gamma_tbl[items - 1][1];
72
73 memcpy(info->lcd_cmap_tbl, lcd_cmap_tbl, sizeof(lcd_cmap_tbl));
74 }
75
LCD_open_flow(u32 sel)76 static s32 LCD_open_flow(u32 sel)
77 {
78 LCD_OPEN_FUNC(sel, LCD_power_on,
79 100); /* open lcd power, and delay 50ms */
80 LCD_OPEN_FUNC(sel, LCD_panel_init,
81 200); /* open lcd power, than delay 200ms */
82 LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable,
83 50); /* open lcd controller, and delay 100ms */
84 LCD_OPEN_FUNC(sel, LCD_bl_open,
85 0); /* open lcd backlight, and delay 0ms */
86
87 return 0;
88 }
89
LCD_close_flow(u32 sel)90 static s32 LCD_close_flow(u32 sel)
91 {
92 LCD_CLOSE_FUNC(sel, LCD_bl_close,
93 200); /* close lcd backlight, and delay 0ms */
94 LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable,
95 20); /* close lcd controller, and delay 0ms */
96 LCD_CLOSE_FUNC(sel, LCD_panel_exit,
97 10); /* open lcd power, than delay 200ms */
98 LCD_CLOSE_FUNC(sel, LCD_power_off,
99 500); /* close lcd power, and delay 500ms */
100
101 return 0;
102 }
103
LCD_power_on(u32 sel)104 static void LCD_power_on(u32 sel)
105 {
106 sunxi_lcd_pin_cfg(sel, 1);
107 sunxi_lcd_power_enable(sel, 0);
108 sunxi_lcd_delay_ms(5);
109 sunxi_lcd_power_enable(sel, 1);
110 sunxi_lcd_delay_ms(5);
111 sunxi_lcd_power_enable(sel, 2);
112 sunxi_lcd_delay_ms(5);
113 power_en(1);
114 sunxi_lcd_delay_ms(20);
115 panel_reset(0);
116 sunxi_lcd_delay_ms(10);
117 panel_reset(1);
118 }
119
LCD_power_off(u32 sel)120 static void LCD_power_off(u32 sel)
121 {
122 sunxi_lcd_pin_cfg(sel, 0);
123 power_en(0);
124 sunxi_lcd_delay_ms(20);
125 panel_reset(0);
126 sunxi_lcd_delay_ms(5);
127 sunxi_lcd_power_disable(
128 sel, 2); /* config lcd_power pin to close lcd power2 */
129 sunxi_lcd_delay_ms(5);
130 sunxi_lcd_power_disable(
131 sel, 1); /* config lcd_power pin to close lcd power1 */
132 sunxi_lcd_delay_ms(5);
133 sunxi_lcd_power_disable(
134 sel, 0); /* config lcd_power pin to close lcd power */
135 }
136
LCD_bl_open(u32 sel)137 static void LCD_bl_open(u32 sel)
138 {
139 sunxi_lcd_pwm_enable(sel);
140 sunxi_lcd_delay_ms(50);
141 sunxi_lcd_backlight_enable(
142 sel); /* config lcd_bl_en pin to open lcd backlight */
143 }
144
LCD_bl_close(u32 sel)145 static void LCD_bl_close(u32 sel)
146 {
147 sunxi_lcd_backlight_disable(
148 sel); /* config lcd_bl_en pin to close lcd backlight */
149 sunxi_lcd_delay_ms(20);
150 sunxi_lcd_pwm_disable(sel);
151 }
152
153 #define REGFLAG_DELAY 0XFE
154 #define REGFLAG_END_OF_TABLE 0xFF /* END OF REGISTERS MARKER */
155
156 struct LCM_setting_table {
157 u8 cmd;
158 u32 count;
159 u8 para_list[64];
160 };
161
162 /*add panel initialization code*/
163 static struct LCM_setting_table LCM_TM040YVZG31_setting[] = {
164 {0xB9, 3, {0xFF, 0x83, 0x69} },
165 /*Set Power*/
166 {0xB1, 19, {0x01, 0x00, 0x34, 0x0A,
167 0x00, 0x11, 0x11, 0x2F, 0x37,
168 0x3F, 0x3F, 0x07, 0x3A, 0x01,
169 0xE6, 0xE6, 0xE6, 0xE6, 0xE6} },
170 /* set display,0x2B DSI video mode
171 * 0x20 DSI command mod
172 */
173 {0xB2, 15, {0x00, 0x2B, 0x03, 0x03,
174 0x70, 0x00, 0xFF, 0x00, 0x00,
175 0x00, 0x00, 0x03, 0x03, 0x00,
176 0x01} },
177 /*set display 480*800
178 *0x00 column inversion, 0x01 1-dot inversion
179 *0x02 2-dot inversion, 0x3 zig-zag inversion
180 */
181 {0xB4, 5, {0x00, 0x18, 0x70, 0x00, 0x00} },
182 /*Set VCOM*/
183 {0xB6, 2, {0x4a, 0x4a} },
184 /*set enable chopper function*/
185 {0x36, 1, {0x00} },
186 /*set GIP*/
187 {0xD5, 26, {0x00, 0x00, 0x03, 0x37,
188 0x01, 0x02, 0x00, 0x70, 0x11,
189 0x13, 0x00, 0x00, 0x60, 0x24,
190 0x71, 0x35, 0x00, 0x00, 0x60,
191 0x24, 0x71, 0x35, 0x07, 0x0F,
192 0x00, 0x04 } },
193 /*R Gamma*/
194 {0xE0, 34, {0x04, 0x1F, 0x25, 0x2B,
195 0X3E, 0x35, 0x34, 0x4A, 0x08,
196 0x0E, 0x0F, 0x14, 0x16, 0x14,
197 0x15, 0x14, 0x1F, 0x04, 0x1F,
198 0x25, 0x2B, 0x3E, 0x35, 0x34,
199 0x4A, 0x08, 0x0E, 0x0F, 0x14,
200 0x16, 0x14, 0x15, 0x14, 0x1F} },
201 {0xCC, 1, {0x02 } },
202 {0x3A, 1, {0x77 } },
203 /*set mipi, 0x11 two lanes, 0x10 one lane*/
204 {0xBA, 13, {0x00, 0xA0, 0xC6, 0x00,
205 0x0A, 0x00, 0x10, 0x30, 0x6F,
206 0x02, 0x11, 0x18, 0x40} },
207 /*sleep exit*/
208 {0x11, 0, {0x00 } },
209 {REGFLAG_DELAY, REGFLAG_DELAY, {120} },
210 /*display on*/
211 {0x29, 0, {0x00 } },
212 {REGFLAG_DELAY, REGFLAG_DELAY, {10} },
213 {REGFLAG_END_OF_TABLE, REGFLAG_END_OF_TABLE, {} }
214 };
215
LCD_panel_init(u32 sel)216 static void LCD_panel_init(u32 sel)
217 {
218 __u32 i;
219 char model_name[25];
220
221 disp_sys_script_get_item("lcd0", "lcd_model_name",
222 (int *)model_name, 25);
223 sunxi_lcd_dsi_clk_enable(sel);
224 sunxi_lcd_delay_ms(20);
225
226 for (i = 0;; i++) {
227 if (LCM_TM040YVZG31_setting[i].count == REGFLAG_END_OF_TABLE)
228 break;
229 else if (LCM_TM040YVZG31_setting[i].count == REGFLAG_DELAY)
230 sunxi_lcd_delay_ms(
231 LCM_TM040YVZG31_setting[i].para_list[0]);
232 #ifdef SUPPORT_DSI
233 else
234 dsi_dcs_wr(sel, LCM_TM040YVZG31_setting[i].cmd,
235 LCM_TM040YVZG31_setting[i].para_list,
236 LCM_TM040YVZG31_setting[i].count);
237 #endif
238 }
239 }
240
LCD_panel_exit(u32 sel)241 static void LCD_panel_exit(u32 sel)
242 {
243 sunxi_lcd_dsi_dcs_write_0para(sel, DSI_DCS_SET_DISPLAY_OFF);
244 sunxi_lcd_delay_ms(20);
245 sunxi_lcd_dsi_dcs_write_0para(sel, DSI_DCS_ENTER_SLEEP_MODE);
246 sunxi_lcd_delay_ms(80);
247 }
248
249 /* sel: 0:lcd0; 1:lcd1 */
LCD_user_defined_func(u32 sel,u32 para1,u32 para2,u32 para3)250 static s32 LCD_user_defined_func(u32 sel, u32 para1, u32 para2, u32 para3)
251 {
252 return 0;
253 }
254
255 /* sel: 0:lcd0; 1:lcd1 */
256 /*static s32 LCD_set_bright(u32 sel, u32 bright)*/
257 /*{*/
258 /*sunxi_lcd_dsi_dcs_write_1para(sel,0x51,bright);*/
259 /*return 0;*/
260 /*}*/
261
262 struct __lcd_panel tm_dsi_panel = {
263 /* panel driver name, must mach the name of
264 * lcd_drv_name in sys_config.fex
265 */
266 .name = "tm_dsi_panel",
267 .func = {
268 .cfg_panel_info = LCD_cfg_panel_info,
269 .cfg_open_flow = LCD_open_flow,
270 .cfg_close_flow = LCD_close_flow,
271 .lcd_user_defined_func = LCD_user_defined_func,
272 /*.set_bright = LCD_set_bright, */
273 },
274 };
275