1 /*
2 * drivers/video/fbdev/sunxi/disp2/disp/lcd/rt13qv005d.c
3 *
4 * Copyright (c) 2007-2019 Allwinnertech Co., Ltd.
5 * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 [lcd0]
17 lcd_used = 1
18 lcd_driver_name = "rt13qv005d"
19 lcd_if = 1
20 lcd_x = 240
21 lcd_y = 240
22 lcd_width = 26
23 lcd_height = 29
24 lcd_dclk_freq = 16
25 lcd_pwm_used = 1
26 lcd_pwm_ch = 8
27 lcd_pwm_freq = 50000
28 lcd_pwm_pol = 1
29 lcd_pwm_max_limit = 255
30 lcd_hbp = 20
31 lcd_ht = 288
32 lcd_hspw = 10
33 lcd_vbp = 8
34 lcd_vt = 256
35 lcd_vspw = 4
36 lcd_frm = 1
37 lcd_hv_clk_phase = 0
38 lcd_hv_sync_polarity = 0
39 lcd_gamma_en = 0
40 lcd_bright_curve_en = 1
41 lcd_cmap_en = 0
42 lcd_cpu_mode = 1
43 lcd_cpu_te = 1
44 lcd_cpu_if = 12
45 lcd_hv_if = 0
46 lcd_hv_srgb_seq = 0
47 lcd_rb_swap = 0
48
49 lcdgamma4iep = 22
50
51 lcd_power = "vcc-lcd"
52 lcd_pin_power = "vcc-pd"
53
54 ;reset pin
55 lcd_gpio_0 = port:PD09<1><0><2><1>
56 ;cs pin
57 lcd_gpio_1 = port:PD10<1><0><2><0>
58
59 lcdd3 = port:PD1<2><0><2><default>
60 lcdd4 = port:PD2<2><0><2><default>
61 lcdd5 = port:PD3<2><0><2><default>
62 lcdd6 = port:PD4<2><0><2><default>
63 lcdd7 = port:PD5<2><0><2><default>
64 lcdd10 = port:PD6<2><0><2><default>
65 lcdd11 = port:PD7<2><0><2><default>
66 lcdd12 = port:PD8<2><0><2><default>
67 lcdclk = port:PD18<2><0><3><default>
68 lcdde = port:PD19<2><0><3><default>
69 lcdhsync = port:PD20<2><0><3><default>
70 lcdvsync = port:PD21<2><0><3><default>
71 [lcd0_suspend]
72 lcdd3 = port:PD1<7><0><2><default>
73 lcdd4 = port:PD2<7><0><2><default>
74 lcdd5 = port:PD3<7><0><2><default>
75 lcdd6 = port:PD4<7><0><2><default>
76 lcdd7 = port:PD5<7><0><2><default>
77 lcdd10 = port:PD6<7><0><2><default>
78 lcdd11 = port:PD7<7><0><2><default>
79 lcdd12 = port:PD8<7><0><2><default>
80 lcdclk = port:PD18<7><0><3><default>
81 lcdde = port:PD19<7><0><3><default>
82 lcdhsync = port:PD20<7><0><3><default>
83 lcdvsync = port:PD21<7><0><3><default>
84 */
85 #include "rt13qv005d.h"
86
87 #define TCON_DEBUG (0)
88
89 static void lcd_panel_st7789v_init(u32 sel, struct disp_panel_para *info);
90 static void lcd_cpu_panel_fr(__u32 sel, __u32 w, __u32 h, __u32 x, __u32 y);
91 static void LCD_power_on(u32 sel);
92 static void LCD_power_off(u32 sel);
93 static void LCD_bl_open(u32 sel);
94 static void LCD_bl_close(u32 sel);
95
96 static void LCD_panel_init(u32 sel);
97 static void LCD_panel_exit(u32 sel);
98
LCD_cfg_panel_info(struct panel_extend_para * info)99 static void LCD_cfg_panel_info(struct panel_extend_para *info)
100 {
101 #if 0
102 u32 i = 0, j = 0;
103 u32 items;
104 u8 lcd_gamma_tbl[][2] = {
105 //{input value, corrected value}
106 {0, 0}, {15, 15}, {30, 30}, {45, 45}, {60, 60},
107 {75, 75}, {90, 90}, {105, 105}, {120, 120}, {135, 135},
108 {150, 150}, {165, 165}, {180, 180}, {195, 195}, {210, 210},
109 {225, 225}, {240, 240}, {255, 255},
110 };
111
112 u32 lcd_cmap_tbl[2][3][4] = {
113 {
114 {LCD_CMAP_G0, LCD_CMAP_B1, LCD_CMAP_G2, LCD_CMAP_B3},
115 {LCD_CMAP_B0, LCD_CMAP_R1, LCD_CMAP_B2, LCD_CMAP_R3},
116 {LCD_CMAP_R0, LCD_CMAP_G1, LCD_CMAP_R2, LCD_CMAP_G3},
117 },
118 {
119 {LCD_CMAP_B3, LCD_CMAP_G2, LCD_CMAP_B1, LCD_CMAP_G0},
120 {LCD_CMAP_R3, LCD_CMAP_B2, LCD_CMAP_R1, LCD_CMAP_B0},
121 {LCD_CMAP_G3, LCD_CMAP_R2, LCD_CMAP_G1, LCD_CMAP_R0},
122 },
123 };
124
125 items = sizeof(lcd_gamma_tbl) / 2;
126 for (i = 0; i < items - 1; i++) {
127 u32 num = lcd_gamma_tbl[i + 1][0] - lcd_gamma_tbl[i][0];
128
129 for (j = 0; j < num; j++) {
130 u32 value = 0;
131
132 value =
133 lcd_gamma_tbl[i][1] +
134 ((lcd_gamma_tbl[i + 1][1] - lcd_gamma_tbl[i][1]) *
135 j) /
136 num;
137 info->lcd_gamma_tbl[lcd_gamma_tbl[i][0] + j] =
138 (value << 16) + (value << 8) + value;
139 }
140 }
141 info->lcd_gamma_tbl[255] = (lcd_gamma_tbl[items - 1][1] << 16) +
142 (lcd_gamma_tbl[items - 1][1] << 8) +
143 lcd_gamma_tbl[items - 1][1];
144
145 memcpy(info->lcd_cmap_tbl, lcd_cmap_tbl, sizeof(lcd_cmap_tbl));
146 #endif
147 }
148
LCD_open_flow(u32 sel)149 static s32 LCD_open_flow(u32 sel)
150 {
151 LCD_OPEN_FUNC(sel, LCD_power_on, 120);
152 LCD_OPEN_FUNC(sel, LCD_panel_init, 100);
153 LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable, 50);
154 LCD_OPEN_FUNC(sel, LCD_bl_open, 0);
155
156 return 0;
157 }
158
LCD_close_flow(u32 sel)159 static s32 LCD_close_flow(u32 sel)
160 {
161 LCD_CLOSE_FUNC(sel, LCD_bl_close, 20);
162 LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable, 10);
163 LCD_CLOSE_FUNC(sel, LCD_panel_exit, 50);
164 LCD_CLOSE_FUNC(sel, LCD_power_off, 0);
165
166 return 0;
167 }
168
LCD_power_on(u32 sel)169 static void LCD_power_on(u32 sel)
170 {
171 /*config lcd_power pin to open lcd power0 */
172 sunxi_lcd_power_enable(sel, 0);
173 sunxi_lcd_pin_cfg(sel, 1);
174
175 /*lcd_rst, active hight */
176 sunxi_lcd_delay_ms(10);
177 sunxi_lcd_gpio_set_value(sel, 1, 1);
178 sunxi_lcd_gpio_set_value(sel, 0, 0);
179 sunxi_lcd_delay_ms(10);
180 sunxi_lcd_gpio_set_value(sel, 0, 1);
181 }
182
LCD_power_off(u32 sel)183 static void LCD_power_off(u32 sel)
184 {
185 /*lcd_cs, active low */
186 sunxi_lcd_gpio_set_value(sel, 1, 1);
187 sunxi_lcd_delay_ms(10);
188 /*lcd_rst, active hight */
189 sunxi_lcd_gpio_set_value(sel, 0, 0);
190 sunxi_lcd_delay_ms(10);
191
192 sunxi_lcd_pin_cfg(sel, 0);
193 /*config lcd_power pin to close lcd power0 */
194 sunxi_lcd_power_disable(sel, 0);
195 }
196
LCD_bl_open(u32 sel)197 static void LCD_bl_open(u32 sel)
198 {
199 sunxi_lcd_pwm_enable(sel);
200 /*config lcd_bl_en pin to open lcd backlight */
201 sunxi_lcd_backlight_enable(sel);
202 }
203
LCD_bl_close(u32 sel)204 static void LCD_bl_close(u32 sel)
205 {
206 /*config lcd_bl_en pin to close lcd backlight */
207 sunxi_lcd_backlight_disable(sel);
208 sunxi_lcd_pwm_disable(sel);
209 }
210
211 /*static int bootup_flag = 0;*/
LCD_panel_init(u32 sel)212 static void LCD_panel_init(u32 sel)
213 {
214 struct disp_panel_para *info =
215 kmalloc(sizeof(struct disp_panel_para), GFP_KERNEL);
216
217 bsp_disp_get_panel_info(sel, info);
218 lcd_panel_st7789v_init(sel, info);
219
220 if (LCD_CPU_AUTO_MODE == info->lcd_cpu_mode)
221 sunxi_lcd_cpu_set_auto_mode(sel);
222 /*else */
223 /* tcon0_cpu_set_tri_mode(sel); */
224
225 disp_sys_free(info);
226 return;
227 }
228
LCD_panel_exit(u32 sel)229 static void LCD_panel_exit(u32 sel)
230 {
231 sunxi_lcd_cpu_write_index(0, 0x28);
232 sunxi_lcd_cpu_write_index(0, 0x10);
233 }
234
lcd_dbi_wr_dcs(__u32 sel,__u8 cmd,__u8 * para,__u32 para_num)235 static void lcd_dbi_wr_dcs(__u32 sel, __u8 cmd, __u8 *para, __u32 para_num)
236 {
237 __u8 index = cmd;
238 __u8 *data_p = para;
239 __u16 i;
240 sunxi_lcd_cpu_write_index(sel, index);
241 for (i = 0; i < para_num; i++) {
242 sunxi_lcd_cpu_write_data(sel, *(data_p++));
243 }
244 }
245
lcd_cpu_panel_fr(__u32 sel,__u32 w,__u32 h,__u32 x,__u32 y)246 static void lcd_cpu_panel_fr(__u32 sel, __u32 w, __u32 h, __u32 x, __u32 y)
247 {
248 __u8 para[4];
249 __u32 para_num;
250 para[0] = (x >> 8) & 0xff;
251 para[1] = (x >> 0) & 0xff;
252 para[2] = ((x + w - 1) >> 8) & 0xff;
253 para[3] = ((x + w - 1) >> 0) & 0xff;
254 para_num = 4;
255 lcd_dbi_wr_dcs(sel, DSI_DCS_SET_COLUMN_ADDRESS, para, para_num);
256
257 para[0] = (y >> 8) & 0xff;
258 para[1] = (y >> 0) & 0xff;
259 para[2] = ((y + h - 1) >> 8) & 0xff;
260 para[3] = ((y + h - 1) >> 0) & 0xff;
261 para_num = 4;
262 lcd_dbi_wr_dcs(sel, DSI_DCS_SET_PAGE_ADDRESS, para, para_num);
263 }
264
lcd_panel_st7789v_init(u32 sel,struct disp_panel_para * info)265 static void lcd_panel_st7789v_init(u32 sel, struct disp_panel_para *info)
266 {
267
268 /*lcd_cs, active low */
269 sunxi_lcd_gpio_set_value(sel, 1, 0);
270 sunxi_lcd_delay_ms(10);
271
272
273 sunxi_lcd_cpu_write_index(0, 0x11);
274 sunxi_lcd_delay_ms(120);
275
276 /* Memory Data Access Control */
277 sunxi_lcd_cpu_write_index(0, 0x36);
278 sunxi_lcd_cpu_write_data(0, 0x00); /* 0x20 */
279
280 sunxi_lcd_cpu_write_index(0, 0x3A);
281 /* 06 ---->262K(RGB666);05---->65K(RGB565) */
282 sunxi_lcd_cpu_write_data(0, 0x06);
283
284 sunxi_lcd_cpu_write_index(0, 0xB2);
285 sunxi_lcd_cpu_write_data(0, 0x0C);
286 sunxi_lcd_cpu_write_data(0, 0x0C);
287 sunxi_lcd_cpu_write_data(0, 0x00);
288 sunxi_lcd_cpu_write_data(0, 0x33);
289 sunxi_lcd_cpu_write_data(0, 0x33);
290
291 sunxi_lcd_cpu_write_index(0, 0xB7);
292 sunxi_lcd_cpu_write_data(0, 0x75);
293
294 sunxi_lcd_cpu_write_index(0, 0xBB);
295 /* 0x20);//0x3C);//0x0E);//0x20); //vcom 0x20 */
296 sunxi_lcd_cpu_write_data(0, 0x3D);
297
298 sunxi_lcd_cpu_write_index(0, 0xC2);
299 sunxi_lcd_cpu_write_data(0, 0x01);
300 /* VRH--->值越大越暗,反之越白 */
301 sunxi_lcd_cpu_write_index(0, 0xC3);
302 /* 0x0b);//0x0b); 0x0B 0x06 */
303 sunxi_lcd_cpu_write_data(0, 0x19);
304
305 sunxi_lcd_cpu_write_index(0, 0xC4);
306 sunxi_lcd_cpu_write_data(0, 0x20);
307
308 sunxi_lcd_cpu_write_index(0, 0xC6);
309 /* frame */
310 sunxi_lcd_cpu_write_data(0, 0x0F);
311
312 sunxi_lcd_cpu_write_index(0, 0xD0);
313 sunxi_lcd_cpu_write_data(0, 0xA4);
314 sunxi_lcd_cpu_write_data(0, 0xA1);
315
316 sunxi_lcd_cpu_write_index(0, 0xD6);
317 sunxi_lcd_cpu_write_data(0, 0xA1);
318
319 /*[> gamma <]*/
320 sunxi_lcd_cpu_write_index(0, 0xE0);
321 sunxi_lcd_cpu_write_data(0, 0x70);
322 sunxi_lcd_cpu_write_data(0, 0x04);
323 sunxi_lcd_cpu_write_data(0, 0x08);
324 sunxi_lcd_cpu_write_data(0, 0x09);
325 sunxi_lcd_cpu_write_data(0, 0x09);
326 sunxi_lcd_cpu_write_data(0, 0x05);
327 sunxi_lcd_cpu_write_data(0, 0x2a);
328 sunxi_lcd_cpu_write_data(0, 0x33);
329 sunxi_lcd_cpu_write_data(0, 0x41);
330 sunxi_lcd_cpu_write_data(0, 0x07);
331 sunxi_lcd_cpu_write_data(0, 0x13);
332 sunxi_lcd_cpu_write_data(0, 0x13);
333 sunxi_lcd_cpu_write_data(0, 0x29);
334 sunxi_lcd_cpu_write_data(0, 0x2f);
335
336 sunxi_lcd_cpu_write_index(0, 0xE1); /* gamma */
337 sunxi_lcd_cpu_write_data(0, 0x70);
338 sunxi_lcd_cpu_write_data(0, 0x03);
339 sunxi_lcd_cpu_write_data(0, 0x09);
340 sunxi_lcd_cpu_write_data(0, 0x0A);
341 sunxi_lcd_cpu_write_data(0, 0x09);
342 sunxi_lcd_cpu_write_data(0, 0x06);
343 sunxi_lcd_cpu_write_data(0, 0x2B);
344 sunxi_lcd_cpu_write_data(0, 0x34);
345 sunxi_lcd_cpu_write_data(0, 0x41);
346 sunxi_lcd_cpu_write_data(0, 0x07);
347 sunxi_lcd_cpu_write_data(0, 0x12);
348 sunxi_lcd_cpu_write_data(0, 0x14);
349 sunxi_lcd_cpu_write_data(0, 0x28);
350 sunxi_lcd_cpu_write_data(0, 0x2E);
351 /*inversion on */
352 sunxi_lcd_cpu_write_index(0, 0x21);
353 /*te on*/
354 sunxi_lcd_cpu_write_index(0, 0x35);
355 sunxi_lcd_cpu_write_data(0, 0x00);
356
357 sunxi_lcd_cpu_write_index(0, 0x29); /* Display on */
358
359 lcd_cpu_panel_fr(0, info->lcd_x, info->lcd_y, 0, 0);
360
361 sunxi_lcd_cpu_write_index(0, 0x2C); /* start memory write */
362
363 }
364
365 /* sel: 0:lcd0; 1:lcd1 */
LCD_user_defined_func(u32 sel,u32 para1,u32 para2,u32 para3)366 static s32 LCD_user_defined_func(u32 sel, u32 para1, u32 para2, u32 para3)
367 {
368 return 0;
369 }
370
371 /* panel driver name, must mach the name of lcd_drv_name in sys_config.fex */
372 struct __lcd_panel rt13qv005d_panel = {
373 .name = "rt13qv005d",
374 .func = {
375 .cfg_panel_info = LCD_cfg_panel_info,
376 .cfg_open_flow = LCD_open_flow,
377 .cfg_close_flow = LCD_close_flow,
378 .lcd_user_defined_func = LCD_user_defined_func,
379 },
380 };
381