1 /*
2  * drivers/video/fbdev/sunxi/disp2/disp/lcd/s2003t46/s2003t46g.c
3  *
4  * Copyright (c) 2007-2018 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  *
17 lcd_used            = <1>;
18 
19 lcd_driver_name     = "st7789v_cpu";
20 
21 lcd_backlight       = <150>;
22 
23 lcd_if              = <1>;
24 lcd_x               = <240>;
25 lcd_y               = <320>;
26 lcd_width           = <108>;
27 lcd_height          = <64>;
28 lcd_dclk_freq       = <18>;
29 
30 lcd_pwm_used        = <1>;
31 lcd_pwm_ch          = <8>;
32 lcd_pwm_freq        = <50000>;
33 lcd_pwm_pol         = <1>;
34 lcd_pwm_max_limit   = <255>;
35 
36 lcd_hbp             = <60>;
37 lcd_ht              = <298>;
38 lcd_hspw            = <30>;
39 lcd_vbp             = <340>;
40 lcd_vt              = <336>;
41 lcd_vspw            = <2>;
42 
43 lcd_frm             = <1>;
44 lcd_io_phase        = <0x0000>;
45 lcd_hv_clk_phase    = <0>;
46 lcd_hv_sync_polarity= <0>;
47 lcd_hv_data_polarity = <1>;
48 lcd_gamma_en        = <0>;
49 lcd_bright_curve_en = <0>;
50 lcd_cmap_en         = <0>;
51 
52 lcdgamma4iep        = <22>;
53 lcd_cpu_mode        = <1>;
54 lcd_cpu_te          = <1>;
55 lcd_cpu_if      = <12>;
56 lcd_hv_if           = <0>;
57 lcd_hv_srgb_seq     = <0>;
58 lcd_rb_swap         = <0>;
59 
60 lcd_gpio_0 = <&pio PE 16 1 0 3 0>;
61 lcd_gpio_1 = <&pio PE 17 1 0 3 0>;
62 
63 pinctrl-0 = <&rgb8_pins_a>;
64 pinctrl-1 = <&rgb8_pins_b>;
65 
66  */
67 
68 #include "st7789v_cpu.h"
69 
70 #define CPU_TRI_MODE
71 
72 #define DBG_INFO(format, args...) (printk("[ST7789V LCD INFO] LINE:%04d-->%s:"format, __LINE__, __func__, ##args))
73 #define DBG_ERR(format, args...) (printk("[ST7789V LCD ERR] LINE:%04d-->%s:"format, __LINE__, __func__, ##args))
74 #define panel_reset(val) sunxi_lcd_gpio_set_value(sel, 0, val)
75 #define lcd_cs(val)  sunxi_lcd_gpio_set_value(sel, 1, val)
76 
77 static void lcd_panel_st7789v_init(u32 sel, struct disp_panel_para *info);
78 static void LCD_power_on(u32 sel);
79 static void LCD_power_off(u32 sel);
80 static void LCD_bl_open(u32 sel);
81 static void LCD_bl_close(u32 sel);
82 
83 static void LCD_panel_init(u32 sel);
84 static void LCD_panel_exit(u32 sel);
85 
LCD_cfg_panel_info(struct panel_extend_para * info)86 static void LCD_cfg_panel_info(struct panel_extend_para *info)
87 {
88 #if 0
89     u32 i = 0, j = 0;
90     u32 items;
91     u8 lcd_gamma_tbl[][2] = {
92         //{input value, corrected value}
93         {0, 0},     {15, 15},   {30, 30},   {45, 45},   {60, 60},
94         {75, 75},   {90, 90},   {105, 105}, {120, 120}, {135, 135},
95         {150, 150}, {165, 165}, {180, 180}, {195, 195}, {210, 210},
96         {225, 225}, {240, 240}, {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 =
120                 lcd_gamma_tbl[i][1] +
121                 ((lcd_gamma_tbl[i + 1][1] - lcd_gamma_tbl[i][1]) *
122                  j) /
123                 num;
124             info->lcd_gamma_tbl[lcd_gamma_tbl[i][0] + j] =
125                 (value << 16) + (value << 8) + value;
126         }
127     }
128     info->lcd_gamma_tbl[255] = (lcd_gamma_tbl[items - 1][1] << 16) +
129                    (lcd_gamma_tbl[items - 1][1] << 8) +
130                    lcd_gamma_tbl[items - 1][1];
131 
132     memcpy(info->lcd_cmap_tbl, lcd_cmap_tbl, sizeof(lcd_cmap_tbl));
133 #endif
134 }
135 
LCD_open_flow(u32 sel)136 static s32 LCD_open_flow(u32 sel)
137 {
138     LCD_OPEN_FUNC(sel, LCD_power_on, 120);
139 #ifdef CPU_TRI_MODE
140     LCD_OPEN_FUNC(sel, LCD_panel_init, 100);
141     LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable, 50);
142 #else
143     LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable, 100);
144     LCD_OPEN_FUNC(sel, LCD_panel_init, 50);
145 #endif
146     LCD_OPEN_FUNC(sel, LCD_bl_open, 0);
147 
148     return 0;
149 }
150 
LCD_close_flow(u32 sel)151 static s32 LCD_close_flow(u32 sel)
152 {
153     LCD_CLOSE_FUNC(sel, LCD_bl_close, 20);
154 #ifdef CPU_TRI_MODE
155     LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable, 10);
156     LCD_CLOSE_FUNC(sel, LCD_panel_exit, 50);
157 #else
158     LCD_CLOSE_FUNC(sel, LCD_panel_exit, 10);
159     LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable, 10);
160 #endif
161     LCD_CLOSE_FUNC(sel, LCD_power_off, 0);
162 
163     return 0;
164 }
165 
LCD_power_on(u32 sel)166 static void LCD_power_on(u32 sel)
167 {
168     /*config lcd_power pin to open lcd power0 */
169     sunxi_lcd_power_enable(sel, 0);
170     sunxi_lcd_pin_cfg(sel, 1);
171 
172 }
173 
LCD_power_off(u32 sel)174 static void LCD_power_off(u32 sel)
175 {
176     /*lcd_cs, active low */
177     lcd_cs(1);
178     sunxi_lcd_delay_ms(10);
179     /*lcd_rst, active hight */
180     panel_reset(1);
181     sunxi_lcd_delay_ms(10);
182 
183     sunxi_lcd_pin_cfg(sel, 0);
184     /*config lcd_power pin to close lcd power0 */
185     sunxi_lcd_power_disable(sel, 0);
186 }
187 
LCD_bl_open(u32 sel)188 static void LCD_bl_open(u32 sel)
189 {
190     sunxi_lcd_pwm_enable(sel);
191     /*config lcd_bl_en pin to open lcd backlight */
192     sunxi_lcd_backlight_enable(sel);
193 }
194 
LCD_bl_close(u32 sel)195 static void LCD_bl_close(u32 sel)
196 {
197     /*config lcd_bl_en pin to close lcd backlight */
198     sunxi_lcd_backlight_disable(sel);
199     sunxi_lcd_pwm_disable(sel);
200 }
201 
202 /*static int bootup_flag = 0;*/
LCD_panel_init(u32 sel)203 static void LCD_panel_init(u32 sel)
204 {
205     struct disp_panel_para *info =
206         kmalloc(sizeof(struct disp_panel_para), GFP_KERNEL);
207 
208     DBG_INFO("\n");
209     bsp_disp_get_panel_info(sel, info);
210     lcd_panel_st7789v_init(sel, info);
211 
212     disp_sys_free(info);
213     return;
214 }
215 
LCD_panel_exit(u32 sel)216 static void LCD_panel_exit(u32 sel)
217 {
218     sunxi_lcd_cpu_write_index(0, 0x28);
219     sunxi_lcd_cpu_write_index(0, 0x10);
220 }
221 
222 
lcd_panel_st7789v_init(u32 sel,struct disp_panel_para * info)223 static void lcd_panel_st7789v_init(u32 sel, struct disp_panel_para *info)
224 {
225     DBG_INFO("\n");
226     /*lcd_cs, active low */
227     lcd_cs(0);
228     sunxi_lcd_delay_ms(10);
229     panel_reset(1);
230     sunxi_lcd_delay_ms(20);
231     panel_reset(0);
232     sunxi_lcd_delay_ms(20);
233     panel_reset(1);
234     sunxi_lcd_delay_ms(20);
235     sunxi_lcd_cpu_write_index(0, 0x11);
236     sunxi_lcd_delay_ms(120);
237     sunxi_lcd_cpu_write_index(0, 0x36);
238     sunxi_lcd_cpu_write_data(0, 0x00);
239     sunxi_lcd_cpu_write_index(0, 0x3a);
240     sunxi_lcd_cpu_write_data(0, 0x06);
241     sunxi_lcd_cpu_write_index(0, 0x21);
242     sunxi_lcd_cpu_write_index(0, 0xb2);
243     sunxi_lcd_cpu_write_data(0, 0x05);
244     sunxi_lcd_cpu_write_data(0, 0x05);
245     sunxi_lcd_cpu_write_data(0, 0x00);
246     sunxi_lcd_cpu_write_data(0, 0x33);
247     sunxi_lcd_cpu_write_data(0, 0x33);
248     sunxi_lcd_cpu_write_index(0, 0xb7);
249     sunxi_lcd_cpu_write_data(0, 0x35);
250     /*ST7789V Power setting */
251     sunxi_lcd_cpu_write_index(0, 0xb8);
252     sunxi_lcd_cpu_write_data(0, 0x2f);
253     sunxi_lcd_cpu_write_data(0, 0x2b);
254     sunxi_lcd_cpu_write_data(0, 0x2f);
255     sunxi_lcd_cpu_write_index(0, 0xbb);
256     sunxi_lcd_cpu_write_data(0, 0x20);
257     sunxi_lcd_cpu_write_index(0, 0xc0);
258     sunxi_lcd_cpu_write_data(0, 0x2c);
259     sunxi_lcd_cpu_write_index(0, 0xc2);
260     sunxi_lcd_cpu_write_data(0, 0x01);
261     sunxi_lcd_cpu_write_index(0, 0xc3);
262     sunxi_lcd_cpu_write_data(0, 0x0b);
263     sunxi_lcd_cpu_write_index(0, 0xc4);
264     sunxi_lcd_cpu_write_data(0, 0x20);
265     sunxi_lcd_cpu_write_index(0, 0xc6);
266     sunxi_lcd_cpu_write_data(0, 0x11);
267     sunxi_lcd_cpu_write_index(0, 0xd0);
268     sunxi_lcd_cpu_write_data(0, 0xa4);
269     sunxi_lcd_cpu_write_data(0, 0xa1);
270     sunxi_lcd_cpu_write_index(0, 0xe8);
271     sunxi_lcd_cpu_write_data(0, 0x03);
272     sunxi_lcd_cpu_write_index(0, 0xe9);
273     sunxi_lcd_cpu_write_data(0, 0x0d);
274     sunxi_lcd_cpu_write_data(0, 0x12);
275     sunxi_lcd_cpu_write_data(0, 0x00);
276     /*ST7789V gamma setting */
277     sunxi_lcd_cpu_write_index(0, 0xe0);
278     sunxi_lcd_cpu_write_data(0, 0xd0);
279     sunxi_lcd_cpu_write_data(0, 0x06);
280     sunxi_lcd_cpu_write_data(0, 0x0b);
281     sunxi_lcd_cpu_write_data(0, 0x0a);
282     sunxi_lcd_cpu_write_data(0, 0x09);
283     sunxi_lcd_cpu_write_data(0, 0x05);
284     sunxi_lcd_cpu_write_data(0, 0x2e);
285     sunxi_lcd_cpu_write_data(0, 0x43);
286     sunxi_lcd_cpu_write_data(0, 0x44);
287     sunxi_lcd_cpu_write_data(0, 0x09);
288     sunxi_lcd_cpu_write_data(0, 0x16);
289     sunxi_lcd_cpu_write_data(0, 0x15);
290     sunxi_lcd_cpu_write_data(0, 0x23);
291     sunxi_lcd_cpu_write_data(0, 0x27);
292     sunxi_lcd_cpu_write_index(0, 0xe1);
293     sunxi_lcd_cpu_write_data(0, 0xd0);
294     sunxi_lcd_cpu_write_data(0, 0x06);
295     sunxi_lcd_cpu_write_data(0, 0x0b);
296     sunxi_lcd_cpu_write_data(0, 0x09);
297     sunxi_lcd_cpu_write_data(0, 0x08);
298     sunxi_lcd_cpu_write_data(0, 0x06);
299     sunxi_lcd_cpu_write_data(0, 0x2e);
300     sunxi_lcd_cpu_write_data(0, 0x44);
301     sunxi_lcd_cpu_write_data(0, 0x44);
302     sunxi_lcd_cpu_write_data(0, 0x3a);
303     sunxi_lcd_cpu_write_data(0, 0x15);
304     sunxi_lcd_cpu_write_data(0, 0x15);
305     sunxi_lcd_cpu_write_data(0, 0x23);
306     sunxi_lcd_cpu_write_data(0, 0x26);
307 
308 #if defined(CPU_TRI_MODE)
309     /* enable te, mode 0 */
310 
311     sunxi_lcd_cpu_write_index(0, 0x35);
312     sunxi_lcd_cpu_write_data(0, 0x00);
313 
314     sunxi_lcd_cpu_write_index(0, 0x44);
315     sunxi_lcd_cpu_write_data(0, 0x00);
316     sunxi_lcd_cpu_write_data(0, 0x80);
317 #endif
318     sunxi_lcd_cpu_write_index(0, 0x29);
319     sunxi_lcd_cpu_write_index(0, 0x2c);
320 
321 }
322 
323 
324 /* panel driver name, must mach the name of lcd_drv_name in sys_config.fex */
325 struct __lcd_panel st7789v_cpu_panel = {
326     .name = "st7789v_cpu",
327     .func = {
328         .cfg_panel_info = LCD_cfg_panel_info,
329         .cfg_open_flow = LCD_open_flow,
330         .cfg_close_flow = LCD_close_flow,
331     },
332 };
333