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