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 <linux/reset.h>
12 #include "disp_lcd.h"
13 #include "../dev_disp.h"
14 #include "../lcd/panels.h"
15
16 extern void lcd_set_panel_funs(void);
17 #define DISP_LCD_MODE_DIRTY_MASK 0x80000000
18
19 struct disp_lcd_private_data {
20 struct disp_lcd_flow open_flow;
21 struct disp_lcd_flow close_flow;
22 struct disp_panel_para panel_info;
23 struct panel_extend_para panel_extend_info;
24 struct panel_extend_para panel_extend_info_set;
25 u32 panel_extend_dirty;
26 struct disp_lcd_cfg lcd_cfg;
27 struct disp_lcd_panel_fun lcd_panel_fun;
28 bool enabling;
29 bool disabling;
30 bool bl_enabled;
31 u32 irq_no;
32 u32 irq_no_dsi;
33 u32 irq_no_edp;
34 u32 enabled;
35 u32 power_enabled;
36 u32 bl_need_enabled;
37 u32 frame_per_sec;
38 u32 usec_per_line;
39 u32 judge_line;
40 u32 tri_finish_fail;
41 s32 color_temperature;
42 u32 color_inverse;
43 /*0:reset all module, 1:reset panel only*/
44 u32 esd_reset_level;
45 struct {
46 uintptr_t dev;
47 u32 channel;
48 u32 polarity;
49 u32 period_ns;
50 u32 duty_ns;
51 u32 enabled;
52 } pwm_info;
53
54 struct clk *clk_tcon_lcd;
55 struct clk *clk_bus_tcon_lcd;
56 struct clk *clk_lvds;
57 struct clk *clk_edp;
58 struct clk *clk_parent;
59
60 struct reset_control *rst;
61 struct reset_control *rst_bus_lvds;
62 struct reset_control *rst_bus_tcon_lcd;
63 #if defined(SUPPORT_DSI)
64 struct clk *clk_mipi_dsi[CLK_NUM_PER_DSI];
65 struct clk *clk_bus_mipi_dsi[CLK_NUM_PER_DSI];
66 struct reset_control *rst_bus_mipi_dsi;
67 #endif
68
69 /*0:no reset process;1:reset request;2:resetting*/
70 atomic_t lcd_resetting;
71 struct work_struct reflush_work;
72 struct disp_lcd_esd_info esd_inf;
73 struct disp_device_config config;
74 };
75 static spinlock_t lcd_data_lock;
76
77 static struct disp_device *lcds;
78 static struct disp_lcd_private_data *lcd_private;
79
disp_get_lcd(u32 disp)80 struct disp_device *disp_get_lcd(u32 disp)
81 {
82 u32 num_screens;
83
84 num_screens = bsp_disp_feat_get_num_screens();
85 if (disp >= num_screens
86 || !bsp_disp_feat_is_supported_output_types(disp,
87 DISP_OUTPUT_TYPE_LCD)) {
88 DE_INF("disp %d not support lcd output\n", disp);
89 return NULL;
90 }
91
92 return &lcds[disp];
93 }
disp_lcd_get_priv(struct disp_device * lcd)94 static struct disp_lcd_private_data *disp_lcd_get_priv(struct disp_device *lcd)
95 {
96 if (lcd == NULL) {
97 DE_WRN("param is NULL!\n");
98 return NULL;
99 }
100
101 return (struct disp_lcd_private_data *)lcd->priv_data;
102 }
103
disp_lcd_is_used(struct disp_device * lcd)104 static s32 disp_lcd_is_used(struct disp_device *lcd)
105 {
106 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
107 s32 ret = 0;
108
109 if ((lcd == NULL) || (lcdp == NULL))
110 ret = 0;
111 else
112 ret = (s32)lcdp->lcd_cfg.lcd_used;
113
114 return ret;
115 }
116
lcd_parse_panel_para(u32 disp,struct disp_panel_para * info)117 static s32 lcd_parse_panel_para(u32 disp, struct disp_panel_para *info)
118 {
119 s32 ret = 0;
120 char primary_key[25];
121 s32 value = 0;
122
123 sprintf(primary_key, "lcd%d", disp);
124 memset(info, 0, sizeof(struct disp_panel_para));
125
126 ret = disp_sys_script_get_item(primary_key, "lcd_x", &value, 1);
127 if (ret == 1)
128 info->lcd_x = value;
129
130 ret = disp_sys_script_get_item(primary_key, "lcd_y", &value, 1);
131 if (ret == 1)
132 info->lcd_y = value;
133
134 ret = disp_sys_script_get_item(primary_key, "lcd_width", &value, 1);
135 if (ret == 1)
136 info->lcd_width = value;
137
138 ret = disp_sys_script_get_item(primary_key, "lcd_height", &value, 1);
139 if (ret == 1)
140 info->lcd_height = value;
141
142 ret = disp_sys_script_get_item(primary_key, "lcd_dclk_freq", &value, 1);
143 if (ret == 1)
144 info->lcd_dclk_freq = value;
145
146 ret = disp_sys_script_get_item(primary_key, "lcd_pwm_used", &value, 1);
147 if (ret == 1)
148 info->lcd_pwm_used = value;
149
150 ret = disp_sys_script_get_item(primary_key, "lcd_pwm_ch", &value, 1);
151 if (ret == 1)
152 info->lcd_pwm_ch = value;
153
154 ret = disp_sys_script_get_item(primary_key, "lcd_pwm_freq", &value, 1);
155 if (ret == 1)
156 info->lcd_pwm_freq = value;
157
158 ret = disp_sys_script_get_item(primary_key, "lcd_pwm_pol", &value, 1);
159 if (ret == 1)
160 info->lcd_pwm_pol = value;
161
162 ret = disp_sys_script_get_item(primary_key, "lcd_if", &value, 1);
163 if (ret == 1)
164 info->lcd_if = value;
165
166 ret = disp_sys_script_get_item(primary_key, "lcd_hbp", &value, 1);
167 if (ret == 1)
168 info->lcd_hbp = value;
169
170 ret = disp_sys_script_get_item(primary_key, "lcd_ht", &value, 1);
171 if (ret == 1)
172 info->lcd_ht = value;
173
174 ret = disp_sys_script_get_item(primary_key, "lcd_vbp", &value, 1);
175 if (ret == 1)
176 info->lcd_vbp = value;
177
178 ret = disp_sys_script_get_item(primary_key, "lcd_vt", &value, 1);
179 if (ret == 1)
180 info->lcd_vt = value;
181
182 ret = disp_sys_script_get_item(primary_key, "lcd_gsensor_detect", &value, 1);
183 if (ret == 1)
184 info->lcd_gsensor_detect = value;
185
186 ret = disp_sys_script_get_item(primary_key, "lcd_hv_if", &value, 1);
187 if (ret == 1)
188 info->lcd_hv_if = value;
189
190 ret = disp_sys_script_get_item(primary_key, "lcd_vspw", &value, 1);
191 if (ret == 1)
192 info->lcd_vspw = value;
193
194 ret = disp_sys_script_get_item(primary_key, "lcd_hspw", &value, 1);
195 if (ret == 1)
196 info->lcd_hspw = value;
197
198 ret = disp_sys_script_get_item(primary_key, "lcd_lvds_if", &value, 1);
199 if (ret == 1)
200 info->lcd_lvds_if = value;
201
202 ret = disp_sys_script_get_item(primary_key, "lcd_lvds_mode", &value, 1);
203 if (ret == 1)
204 info->lcd_lvds_mode = value;
205
206 ret =
207 disp_sys_script_get_item(primary_key, "lcd_lvds_colordepth", &value,
208 1);
209 if (ret == 1)
210 info->lcd_lvds_colordepth = value;
211
212 ret =
213 disp_sys_script_get_item(primary_key, "lcd_lvds_io_polarity",
214 &value, 1);
215 if (ret == 1)
216 info->lcd_lvds_io_polarity = value;
217
218 ret = disp_sys_script_get_item(primary_key, "lcd_cpu_if", &value, 1);
219 if (ret == 1)
220 info->lcd_cpu_if = value;
221
222 ret = disp_sys_script_get_item(primary_key, "lcd_cpu_te", &value, 1);
223 if (ret == 1)
224 info->lcd_cpu_te = value;
225
226 ret = disp_sys_script_get_item(primary_key, "lcd_cpu_mode", &value, 1);
227 if (ret == 1)
228 info->lcd_cpu_mode = value;
229
230 ret = disp_sys_script_get_item(primary_key, "lcd_frm", &value, 1);
231 if (ret == 1)
232 info->lcd_frm = value;
233
234 ret = disp_sys_script_get_item(primary_key, "lcd_dsi_if", &value, 1);
235 if (ret == 1)
236 info->lcd_dsi_if = value;
237
238 ret = disp_sys_script_get_item(primary_key, "lcd_dsi_lane", &value, 1);
239 if (ret == 1)
240 info->lcd_dsi_lane = value;
241
242 ret =
243 disp_sys_script_get_item(primary_key, "lcd_dsi_format", &value, 1);
244 if (ret == 1)
245 info->lcd_dsi_format = value;
246
247
248 ret = disp_sys_script_get_item(primary_key, "lcd_dsi_eotp", &value, 1);
249 if (ret == 1)
250 info->lcd_dsi_eotp = value;
251
252 ret = disp_sys_script_get_item(primary_key, "lcd_dsi_te", &value, 1);
253 if (ret == 1)
254 info->lcd_dsi_te = value;
255
256 ret = disp_sys_script_get_item(primary_key, "lcd_dsi_port_num",
257 &value, 1);
258 if (ret == 1)
259 info->lcd_dsi_port_num = value;
260
261 ret = disp_sys_script_get_item(primary_key, "lcd_tcon_mode", &value, 1);
262 if (ret == 1)
263 info->lcd_tcon_mode = value;
264
265 ret = disp_sys_script_get_item(primary_key, "lcd_slave_tcon_num",
266 &value, 1);
267 if (ret == 1)
268 info->lcd_slave_tcon_num = value;
269
270 ret = disp_sys_script_get_item(primary_key, "lcd_slave_stop_pos",
271 &value, 1);
272 if (ret == 1)
273 info->lcd_slave_stop_pos = value;
274
275 ret = disp_sys_script_get_item(primary_key, "lcd_sync_pixel_num",
276 &value, 1);
277 if (ret == 1)
278 info->lcd_sync_pixel_num = value;
279
280 ret = disp_sys_script_get_item(primary_key, "lcd_sync_line_num",
281 &value, 1);
282 if (ret == 1)
283 info->lcd_sync_line_num = value;
284
285 ret = disp_sys_script_get_item(primary_key, "lcd_tcon_en_odd_even_div",
286 &value, 1);
287 if (ret == 1)
288 info->lcd_tcon_en_odd_even = value;
289
290 ret = disp_sys_script_get_item(primary_key, "lcd_fsync_en", &value, 1);
291 if (ret == 1)
292 info->lcd_fsync_en = value;
293
294 ret = disp_sys_script_get_item(primary_key, "lcd_fsync_act_time", &value, 1);
295 if (ret == 1)
296 info->lcd_fsync_act_time = value;
297
298 ret = disp_sys_script_get_item(primary_key, "lcd_fsync_dis_time", &value, 1);
299 if (ret == 1)
300 info->lcd_fsync_dis_time = value;
301
302 ret =
303 disp_sys_script_get_item(primary_key, "lcd_fsync_pol", &value,
304 1);
305 if (ret == 1)
306 info->lcd_fsync_pol = value;
307
308 ret =
309 disp_sys_script_get_item(primary_key, "lcd_hv_clk_phase", &value,
310 1);
311 if (ret == 1)
312 info->lcd_hv_clk_phase = value;
313
314 ret =
315 disp_sys_script_get_item(primary_key, "lcd_hv_sync_polarity",
316 &value, 1);
317 if (ret == 1)
318 info->lcd_hv_sync_polarity = value;
319
320 ret =
321 disp_sys_script_get_item(primary_key, "lcd_hv_data_polarity",
322 &value, 1);
323 if (ret == 1)
324 info->lcd_hv_data_polarity = value;
325
326 ret =
327 disp_sys_script_get_item(primary_key, "lcd_hv_srgb_seq", &value, 1);
328 if (ret == 1)
329 info->lcd_hv_srgb_seq = value;
330
331 ret = disp_sys_script_get_item(primary_key, "lcd_rb_swap", &value, 1);
332 if (ret == 1)
333 info->lcd_rb_swap = value;
334
335 ret =
336 disp_sys_script_get_item(primary_key, "lcd_hv_syuv_seq", &value, 1);
337 if (ret == 1)
338 info->lcd_hv_syuv_seq = value;
339
340 ret =
341 disp_sys_script_get_item(primary_key, "lcd_hv_syuv_fdly", &value,
342 1);
343 if (ret == 1)
344 info->lcd_hv_syuv_fdly = value;
345
346 ret = disp_sys_script_get_item(primary_key, "lcd_gamma_en", &value, 1);
347 if (ret == 1)
348 info->lcd_gamma_en = value;
349
350 ret = disp_sys_script_get_item(primary_key, "lcd_cmap_en", &value, 1);
351 if (ret == 1)
352 info->lcd_cmap_en = value;
353
354 ret = disp_sys_script_get_item(primary_key, "lcd_xtal_freq", &value, 1);
355 if (ret == 1)
356 info->lcd_xtal_freq = value;
357
358 ret =
359 disp_sys_script_get_item(primary_key, "lcd_size",
360 (int *)info->lcd_size, 2);
361 ret =
362 disp_sys_script_get_item(primary_key, "lcd_model_name",
363 (int *)info->lcd_model_name, 2);
364 ret =
365 disp_sys_script_get_item(primary_key, "lcd_driver_name",
366 (int *)info->lcd_driver_name, 2);
367
368 return 0;
369 }
370
lcd_get_sys_config(u32 disp,struct disp_lcd_cfg * lcd_cfg)371 static void lcd_get_sys_config(u32 disp, struct disp_lcd_cfg *lcd_cfg)
372 {
373 struct disp_gpio_info *gpio_info;
374 int value = 1;
375 char primary_key[20], sub_name[25];
376 int i = 0;
377 int ret;
378
379 sprintf(primary_key, "lcd%d", disp);
380 /* lcd_used */
381 ret = disp_sys_script_get_item(primary_key, "lcd_used", &value, 1);
382 if (ret == 1)
383 lcd_cfg->lcd_used = value;
384
385 if (lcd_cfg->lcd_used == 0)
386 return;
387
388 /* lcd_bl_en */
389 lcd_cfg->lcd_bl_en_used = 0;
390 gpio_info = &(lcd_cfg->lcd_bl_en);
391 ret = disp_sys_script_get_item(primary_key, "lcd_bl_en", (int *)gpio_info, 3);
392 if (!ret)
393 lcd_cfg->lcd_bl_en_used = 1;
394
395 sprintf(sub_name, "lcd_bl_en_power");
396 ret = disp_sys_script_get_item(primary_key, "lcd_bl_en_power", (int *)lcd_cfg->lcd_bl_en_power, 2);
397 if (ret)
398 return;
399
400 /* lcd_power */
401 for (i = 0; i < LCD_POWER_NUM; i++) {
402 if (i == 0)
403 sprintf(sub_name, "lcd_power");
404 else
405 sprintf(sub_name, "lcd_power%d", i);
406 lcd_cfg->lcd_power_used[i] = 0;
407 ret =
408 disp_sys_script_get_item(primary_key, sub_name,
409 (int *)(lcd_cfg->lcd_power[i]), 2);
410 if (ret == 2)
411 /* str */
412 lcd_cfg->lcd_power_used[i] = 1;
413 }
414
415 /* lcd_gpio */
416 for (i = 0; i < 6; i++) {
417 sprintf(sub_name, "lcd_gpio_%d", i);
418
419 gpio_info = &(lcd_cfg->lcd_gpio[i]);
420 ret = disp_sys_script_get_item(primary_key, sub_name, (int *)gpio_info, 3);
421 if (!ret)
422 lcd_cfg->lcd_gpio_used[i] = 1;
423 }
424
425 /* lcd_gpio_scl,lcd_gpio_sda */
426 gpio_info = &(lcd_cfg->lcd_gpio[LCD_GPIO_SCL]);
427 ret = disp_sys_script_get_item(primary_key, "lcd_gpio_scl", (int *)gpio_info, 3);
428 if (ret == 3)
429 lcd_cfg->lcd_gpio_used[LCD_GPIO_SCL] = 1;
430
431 gpio_info = &(lcd_cfg->lcd_gpio[LCD_GPIO_SDA]);
432 ret = disp_sys_script_get_item(primary_key, "lcd_gpio_sda", (int *)gpio_info, 3);
433 if (ret == 3)
434 lcd_cfg->lcd_gpio_used[LCD_GPIO_SDA] = 1;
435
436 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
437 sprintf(sub_name, "lcd_gpio_power%d", i);
438
439 ret =
440 disp_sys_script_get_item(primary_key, sub_name,
441 (int *)lcd_cfg->lcd_gpio_power[i],
442 2);
443 }
444
445 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
446 if (i == 0)
447 sprintf(sub_name, "lcd_pin_power");
448 else
449 sprintf(sub_name, "lcd_pin_power%d", i);
450 ret =
451 disp_sys_script_get_item(primary_key, sub_name,
452 (int *)lcd_cfg->lcd_pin_power[i],
453 2);
454 }
455
456 /* backlight adjust */
457 for (i = 0; i < 101; i++) {
458 sprintf(sub_name, "lcd_bl_%d_percent", i);
459 lcd_cfg->backlight_curve_adjust[i] = 0;
460
461 if (i == 100)
462 lcd_cfg->backlight_curve_adjust[i] = 255;
463
464 ret =
465 disp_sys_script_get_item(primary_key, sub_name, &value, 1);
466 if (ret == 1) {
467 value = (value > 100) ? 100 : value;
468 value = value * 255 / 100;
469 lcd_cfg->backlight_curve_adjust[i] = value;
470 }
471 }
472
473 sprintf(sub_name, "lcd_backlight");
474 ret = disp_sys_script_get_item(primary_key, sub_name, &value, 1);
475 if (ret == 1) {
476 value = (value > 256) ? 256 : value;
477 lcd_cfg->backlight_bright = value;
478 } else {
479 lcd_cfg->backlight_bright = 197;
480 }
481
482 }
483
lcd_clk_init(struct disp_device * lcd)484 static s32 lcd_clk_init(struct disp_device *lcd)
485 {
486 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
487
488 if ((lcd == NULL) || (lcdp == NULL)) {
489 DE_WRN("NULL hdl!\n");
490 return -1;
491 }
492
493 DE_INF("lcd %d clk init\n", lcd->disp);
494
495 lcdp->clk_parent = clk_get_parent(lcdp->clk_tcon_lcd);
496
497 return DIS_SUCCESS;
498 }
499
lcd_clk_exit(struct disp_device * lcd)500 static s32 lcd_clk_exit(struct disp_device *lcd)
501 {
502 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
503
504 if ((lcd == NULL) || (lcdp == NULL)) {
505 DE_WRN("NULL hdl!\n");
506 return -1;
507 }
508
509 if (lcdp->clk_parent)
510 clk_put(lcdp->clk_parent);
511
512 return DIS_SUCCESS;
513 }
514
lcd_regulator_get_wrap(struct disp_lcd_cfg * lcd_cfg)515 static int lcd_regulator_get_wrap(struct disp_lcd_cfg *lcd_cfg)
516 {
517 int i;
518 struct device *dev = g_disp_drv.dev;
519 struct regulator *regulator;
520
521 if (strlen(lcd_cfg->lcd_bl_en_power)) {
522 regulator = regulator_get(dev, lcd_cfg->lcd_bl_en_power);
523 if (!regulator)
524 DE_WRN("regulator_get for %s failed\n", lcd_cfg->lcd_bl_en_power);
525 else
526 lcd_cfg->bl_regulator = regulator;
527 }
528
529 for (i = 0; i < LCD_POWER_NUM; i++) {
530 if (strlen(lcd_cfg->lcd_power[i])) {
531 regulator = regulator_get(dev, lcd_cfg->lcd_power[i]);
532 if (!regulator) {
533 DE_WRN("regulator_get for %s failed\n", lcd_cfg->lcd_power[i]);
534 continue;
535 }
536 lcd_cfg->regulator[i] = regulator;
537 }
538 }
539
540 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
541 if (strlen(lcd_cfg->lcd_gpio_power[i])) {
542 regulator = regulator_get(dev, lcd_cfg->lcd_gpio_power[i]);
543 if (!regulator) {
544 DE_WRN("regulator_get for %s failed\n", lcd_cfg->lcd_gpio_power[i]);
545 continue;
546 }
547 lcd_cfg->gpio_regulator[i] = regulator;
548 }
549 }
550
551 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
552 if (strlen(lcd_cfg->lcd_pin_power[i])) {
553 regulator = regulator_get(dev, lcd_cfg->lcd_pin_power[i]);
554 if (!regulator) {
555 DE_WRN("regulator_get for %s failed\n", lcd_cfg->lcd_pin_power[i]);
556 continue;
557 }
558 lcd_cfg->pin_regulator[i] = regulator;
559 }
560 }
561
562 return 0;
563 }
564
lcd_regulator_put_wrap(struct disp_lcd_cfg * lcd_cfg)565 static void lcd_regulator_put_wrap(struct disp_lcd_cfg *lcd_cfg)
566 {
567 int i;
568
569 if (lcd_cfg->bl_regulator)
570 regulator_put(lcd_cfg->bl_regulator);
571
572 for (i = 0; i < LCD_POWER_NUM; i++) {
573 if (lcd_cfg->regulator[i])
574 regulator_put(lcd_cfg->regulator[i]);
575 }
576
577 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
578 if (lcd_cfg->gpio_regulator[i])
579 regulator_put(lcd_cfg->gpio_regulator[i]);
580 }
581
582 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
583 if (lcd_cfg->pin_regulator[i])
584 regulator_put(lcd_cfg->pin_regulator[i]);
585 }
586 }
587
588 /**
589 * @name :cal_real_frame_period
590 * @brief :set lcd->timings.frame_period (nsec)
591 * ,lcd->timings.start_delay (line)
592 * and lcd->timings.dclk_rate_set(hz)
593 * @param :lcd:pointer of disp_device
594 * @return :0 if success, other fail
595 */
cal_real_frame_period(struct disp_device * lcd)596 static s32 cal_real_frame_period(struct disp_device *lcd)
597 {
598 s32 ret = -1;
599 struct disp_lcd_private_data *lcdp;
600 struct lcd_clk_info clk_info;
601 unsigned long long temp = 0;
602
603 if (!lcd) {
604 DE_WRN("NULL hdl!\n");
605 goto OUT;
606 }
607
608 lcdp = disp_lcd_get_priv(lcd);
609
610 if (!lcdp) {
611 DE_WRN("NULL hdl!\n");
612 goto OUT;
613 }
614
615 memset(&clk_info, 0, sizeof(struct lcd_clk_info));
616 disp_al_lcd_get_clk_info(lcd->hwdev_index, &clk_info,
617 &lcdp->panel_info);
618
619 if (!lcdp->clk_tcon_lcd) {
620 DE_WRN("clk is NULL!\n");
621 goto OUT;
622 }
623
624 #if defined(SUPPORT_DSI)
625 if (lcdp->panel_info.lcd_if == LCD_IF_DSI)
626 lcd->timings.dclk_rate_set = clk_get_rate(lcdp->clk_mipi_dsi[0]) / clk_info.dsi_div;
627 #endif
628
629 if (lcdp->panel_info.lcd_if != LCD_IF_DSI)
630 lcd->timings.dclk_rate_set = clk_get_rate(lcdp->clk_tcon_lcd) / clk_info.tcon_div;
631
632 if (lcd->timings.dclk_rate_set == 0) {
633 DE_WRN("lcd dclk_rate_set is 0!\n");
634 ret = -2;
635 goto OUT;
636 }
637
638 temp = ONE_SEC * lcdp->panel_info.lcd_ht * lcdp->panel_info.lcd_vt;
639
640 do_div(temp, lcd->timings.dclk_rate_set);
641
642 lcd->timings.frame_period = temp;
643
644 lcd->timings.start_delay =
645 disp_al_lcd_get_start_delay(lcd->hwdev_index, &lcdp->panel_info);
646
647 DE_INF("lcd frame period:%llu\n", lcd->timings.frame_period);
648
649 ret = 0;
650 OUT:
651 return ret;
652 }
653
lcd_clk_config(struct disp_device * lcd)654 static s32 lcd_clk_config(struct disp_device *lcd)
655 {
656 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
657 struct lcd_clk_info clk_info;
658 unsigned long pll_rate = 297000000, lcd_rate = 33000000;
659 unsigned long dclk_rate = 33000000, dsi_rate = 0; /* hz */
660 unsigned long pll_rate_set = 297000000, lcd_rate_set = 33000000;
661 unsigned long dclk_rate_set = 33000000, dsi_rate_set = 0; /* hz */
662 #if defined(SUPPORT_DSI)
663 u32 i = 0, j = 0;
664 u32 dsi_num = 0;
665 #endif
666 if ((lcd == NULL) || (lcdp == NULL)) {
667 DE_WRN("NULL hdl!\n");
668 return -1;
669 }
670 memset(&clk_info, 0, sizeof(struct lcd_clk_info));
671 disp_al_lcd_get_clk_info(lcd->hwdev_index, &clk_info,
672 &lcdp->panel_info);
673 dclk_rate = lcdp->panel_info.lcd_dclk_freq * 1000000; /* Mhz -> hz */
674 if (lcdp->panel_info.lcd_if == LCD_IF_DSI) {
675 lcd_rate = dclk_rate * clk_info.dsi_div;
676 pll_rate = lcd_rate * clk_info.lcd_div;
677 } else {
678 lcd_rate = dclk_rate * clk_info.tcon_div;
679 pll_rate = lcd_rate * clk_info.lcd_div;
680 }
681 dsi_rate = pll_rate / clk_info.dsi_div;
682
683 if (lcdp->clk_parent) {
684 clk_set_rate(lcdp->clk_parent, pll_rate);
685 pll_rate_set = clk_get_rate(lcdp->clk_parent);
686 }
687
688 if (clk_info.lcd_div)
689 lcd_rate_set = pll_rate_set / clk_info.lcd_div;
690 else
691 lcd_rate_set = pll_rate_set;
692
693 clk_set_rate(lcdp->clk_tcon_lcd, lcd_rate_set);
694 lcd_rate_set = clk_get_rate(lcdp->clk_tcon_lcd);
695 #if defined(SUPPORT_DSI)
696 if (lcdp->panel_info.lcd_if == LCD_IF_DSI) {
697 if (lcdp->panel_info.lcd_dsi_if == LCD_DSI_IF_COMMAND_MODE)
698 dsi_rate_set = pll_rate_set;
699 else
700 dsi_rate_set = pll_rate_set / clk_info.dsi_div;
701 dsi_rate_set =
702 (clk_info.dsi_rate == 0) ? dsi_rate_set : clk_info.dsi_rate;
703 dsi_num = (lcdp->panel_info.lcd_tcon_mode == DISP_TCON_DUAL_DSI)
704 ? 2
705 : 1;
706 dsi_rate_set /= dsi_num;
707 /* total number of dsi clk for current disp device*/
708 dsi_num *= CLK_NUM_PER_DSI;
709 /*In the case of CLK_NUM_PER_DSI equal to 2*/
710 /*even index mean hs clk which need to be seted*/
711 /*odd index mean lp clk which no need to be seted*/
712 for (i = dsi_num * lcd->disp, j = 0; i < CLK_DSI_NUM;
713 i += CLK_NUM_PER_DSI) {
714 if (lcdp->clk_mipi_dsi[i]) {
715 clk_set_rate(lcdp->clk_mipi_dsi[i], dsi_rate_set);
716 DE_INF(
717 "clk_set_rate:dsi's %d th clk with %ld\n",
718 i, dsi_rate_set);
719 j += CLK_NUM_PER_DSI;
720 }
721 if (j == dsi_num)
722 break;
723 }
724 /*FIXME, dsi clk0 = dsi clk1(rate)*/
725 /*disp_sys_clk_set_rate(lcdp->clk_dsi[1], dsi_rate_set);*/
726 }
727 #endif
728
729 dclk_rate_set = lcd_rate_set / clk_info.tcon_div;
730 if ((pll_rate_set != pll_rate) || (lcd_rate_set != lcd_rate)
731 || (dclk_rate_set != dclk_rate)) {
732 DE_WRN
733 ("disp %d, clk: pll(%ld),clk(%ld),dclk(%ld) dsi_rate(%ld)\n clk real:pll(%ld),clk(%ld),dclk(%ld) dsi_rate(%ld)\n",
734 lcd->disp, pll_rate, lcd_rate, dclk_rate, dsi_rate,
735 pll_rate_set, lcd_rate_set, dclk_rate_set, dsi_rate_set);
736 }
737
738 return 0;
739 }
740
lcd_clk_enable(struct disp_device * lcd)741 static s32 lcd_clk_enable(struct disp_device *lcd)
742 {
743 #if (defined SUPPORT_COMBO_DPHY) || (defined SUPPORT_DSI)
744 int enable_mipi = 0;
745 u32 i = 0;
746 #endif
747 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
748 int ret = 0;
749
750 if ((lcd == NULL) || (lcdp == NULL)) {
751 DE_WRN("NULL hdl!\n");
752 return -1;
753 }
754 lcd_clk_config(lcd);
755
756 ret = reset_control_deassert(lcdp->rst_bus_tcon_lcd);
757 if (ret) {
758 DE_WRN("%s: reset_control_deassert for rst_bus_tcon_lcd failed\n", __func__);
759 return ret;
760 }
761
762 ret = clk_prepare_enable(lcdp->clk_tcon_lcd);
763 if (ret) {
764 DE_WRN("%s: clk_prepare_enable for clk_tcon_lcd failed\n", __func__);
765 return ret;
766 }
767
768 ret = clk_prepare_enable(lcdp->clk_bus_tcon_lcd);
769 if (ret) {
770 DE_WRN("%s: clk_prepare_enable for clk_bus_tcon_lcd failed\n", __func__);
771 return ret;
772 }
773
774 if (lcdp->panel_info.lcd_if == LCD_IF_LVDS) {
775 ret = reset_control_deassert(lcdp->rst_bus_lvds);
776 if (ret) {
777 DE_WRN("%s: reset_control_deassert for rst_lvds failed\n", __func__);
778 return ret;
779 }
780 ret = clk_prepare_enable(lcdp->clk_lvds);
781 if (ret) {
782 DE_WRN("%s: clk_prepare_enable for clk_lvds failed\n", __func__);
783 return ret;
784 }
785 #ifdef SUPPORT_COMBO_DPHY
786 enable_mipi = 1;
787 #endif
788 } else if (lcdp->panel_info.lcd_if == LCD_IF_DSI) {
789 #if defined(SUPPORT_DSI)
790 enable_mipi = 1;
791 #endif
792 } else if (lcdp->panel_info.lcd_if == LCD_IF_EDP) {
793 ret = clk_prepare_enable(lcdp->clk_edp);
794 if (ret) {
795 DE_WRN("%s: clk_prepare_enable for clk_edp failed\n", __func__);
796 return ret;
797 }
798 }
799
800 #if defined(SUPPORT_DSI)
801 if (enable_mipi) {
802 for (i = 0; i < CLK_DSI_NUM; i++) {
803 ret = reset_control_deassert(lcdp->rst_bus_mipi_dsi);
804 if (ret) {
805 DE_WRN("%s: reset_control_deassert for rst_bus_mipi_dsi[%d] failed\n", __func__, i);
806 return ret;
807 }
808
809 ret = clk_prepare_enable(lcdp->clk_mipi_dsi[i]);
810 if (ret) {
811 DE_WRN("%s: clk_prepare_enable for clk_mipi_dsi[%d] failed\n", __func__, lcd->hwdev_index);
812 return ret;
813 }
814
815 ret = clk_prepare_enable(lcdp->clk_bus_mipi_dsi[i]);
816 if (ret) {
817 DE_WRN("%s: clk_prepare_enable for clk_bus_mipi_dsi[%d] failed\n", __func__, lcd->hwdev_index);
818 return ret;
819 }
820 }
821 }
822 #endif
823
824 return ret;
825 }
826
lcd_clk_disable(struct disp_device * lcd)827 static s32 lcd_clk_disable(struct disp_device *lcd)
828 {
829 int ret;
830 #if defined(SUPPORT_DSI)
831 int disable_mipi = 0;
832 u32 i = 0;
833 #endif
834
835 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
836
837 if ((lcd == NULL) || (lcdp == NULL)) {
838 DE_WRN("NULL hdl!\n");
839 return -1;
840 }
841
842 if (lcdp->panel_info.lcd_if == LCD_IF_LVDS) {
843 clk_disable(lcdp->clk_lvds);
844 #ifdef SUPPORT_COMBO_DPHY
845 if (lcd->hwdev_index == 0)
846 clk_disable(lcdp->clk_mipi_dsi[0]);
847
848 ret = reset_control_assert(lcdp->rst_bus_lvds);
849 if (ret) {
850 DE_WRN("%s: reset_control_assert for rst_bus_lvds failed\n", __func__);
851 return ret;
852 }
853 #if defined(SUPPORT_DSI)
854 disable_mipi = 1;
855 #endif
856 #endif
857 #if defined(SUPPORT_DSI)
858 } else if (lcdp->panel_info.lcd_if == LCD_IF_DSI) {
859 disable_mipi = 1;
860 #endif
861 } else if (lcdp->panel_info.lcd_if == LCD_IF_EDP) {
862 clk_disable_unprepare(lcdp->clk_edp);
863 }
864
865 #if defined(SUPPORT_DSI)
866 if (disable_mipi) {
867 for (i = 0; i < CLK_NUM_PER_DSI; i++) {
868 clk_disable_unprepare(lcdp->clk_bus_mipi_dsi[i]);
869 clk_disable_unprepare(lcdp->clk_mipi_dsi[i]);
870 }
871
872 ret = reset_control_assert(lcdp->rst_bus_mipi_dsi);
873 if (ret) {
874 DE_WRN("%s: reset_control_assert for rst_bus_mipi_dsi failed\n", __func__);
875 return ret;
876 }
877 }
878 #endif
879
880 clk_disable_unprepare(lcdp->clk_bus_tcon_lcd);
881 clk_disable_unprepare(lcdp->clk_tcon_lcd);
882
883 ret = reset_control_assert(lcdp->rst);
884 if (ret) {
885 DE_WRN("%s: reset_control_assert for rst failed\n", __func__);
886 return ret;
887 }
888
889 return 0;
890 }
891
lcd_calc_judge_line(struct disp_device * lcd)892 static int lcd_calc_judge_line(struct disp_device *lcd)
893 {
894 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
895
896 if ((lcd == NULL) || (lcdp == NULL)) {
897 DE_WRN("NULL hdl!\n");
898 return -1;
899 }
900
901 if (lcdp->usec_per_line == 0) {
902 struct disp_panel_para *panel_info = &lcdp->panel_info;
903 /*
904 * usec_per_line = 1 / fps / vt * 1000000
905 * = 1 / (dclk * 1000000 / vt / ht) / vt * 1000000
906 * = ht / dclk(Mhz)
907 */
908 lcdp->usec_per_line = panel_info->lcd_ht
909 / panel_info->lcd_dclk_freq;
910 }
911
912 if (lcdp->judge_line == 0) {
913 int start_delay = disp_al_lcd_get_start_delay(lcd->hwdev_index,
914 &lcdp->panel_info);
915 int usec_start_delay = start_delay * lcdp->usec_per_line;
916 int usec_judge_point;
917
918 if (usec_start_delay <= 200)
919 usec_judge_point = usec_start_delay * 3 / 7;
920 else if (usec_start_delay <= 400)
921 usec_judge_point = usec_start_delay / 2;
922 else
923 usec_judge_point = 200;
924 lcdp->judge_line = usec_judge_point / lcdp->usec_per_line;
925 }
926
927 return 0;
928 }
929
930 #ifdef EINK_FLUSH_TIME_TEST
931 struct timeval lcd_start, lcd_mid, lcd_mid1, lcd_mid2, lcd_end, t5_b, t5_e;
932 struct timeval pin_b, pin_e, po_b, po_e, tocn_b, tcon_e;
933 unsigned int lcd_t1 = 0, lcd_t2 = 0, lcd_t3 = 0, lcd_t4 = 0, lcd_t5 = 0;
934 unsigned int lcd_pin, lcd_po, lcd_tcon;
935 #endif
936
937 #if defined(CONFIG_ARCH_SUN50IW10)
938 struct qareg_iomap_data {
939 int initialized;
940 void *qa_addr;
941 void *ic_ver_addr;
942 void *disp_cfg_addr;
943 };
944 static struct qareg_iomap_data iomap_data;
945 #endif
946
947 extern int sunxi_get_soc_chipid_str(char *serial);
948
disp_lcd_speed_limit(struct disp_panel_para * panel,u32 * min_dclk,u32 * max_dclk)949 static s32 disp_lcd_speed_limit(struct disp_panel_para *panel, u32 *min_dclk,
950 u32 *max_dclk)
951 {
952 #if defined(CONFIG_ARCH_SUN50IW10)
953 char id[17] = "";
954 unsigned long value = 0;
955 unsigned int qa_val = 0;
956 unsigned int ic_ver = 0, display_cfg_flag = 0;
957
958 if (!iomap_data.initialized) {
959 iomap_data.qa_addr = ioremap(0x0300621c, 4);
960 iomap_data.ic_ver_addr = ioremap(0x03000024, 4);
961 iomap_data.disp_cfg_addr = ioremap(0x03006218, 4);
962 iomap_data.initialized = 1;
963 }
964 #endif
965
966 /*init unlimit*/
967 *min_dclk = 0;
968 *max_dclk = 9999;
969
970 #if defined(CONFIG_ARCH_SUN50IW10)
971 if (!iomap_data.qa_addr || !iomap_data.ic_ver_addr || !iomap_data.disp_cfg_addr) {
972 DE_WRN("ioremap fail!%p %p %p\n", iomap_data.qa_addr, iomap_data.ic_ver_addr,
973 iomap_data.disp_cfg_addr);
974 goto OUT;
975 }
976 qa_val = readl(iomap_data.qa_addr);
977 qa_val = (qa_val >> 28) & 0x00000003;
978 ic_ver = readl(iomap_data.ic_ver_addr) & 0x00000007;
979 display_cfg_flag = (readl(iomap_data.disp_cfg_addr) >> 12) & 0x00000001;
980 // FIXME
981 // sunxi_get_soc_chipid_str(id);
982 strcpy(id, "0x1400");
983
984 if (qa_val >= 2 && panel->lcd_if == LCD_IF_DSI) {
985 /*bad IC not support DSI*/
986 *min_dclk = 9999;
987 *max_dclk = 0;
988 goto OUT;
989 }
990
991 if (!kstrtoul(id, 16, &value)) {
992 switch (value) {
993 case 0x3c00: /*A530*/
994 {
995 /*ic version e*/
996 if ((ic_ver >= 4) && (!display_cfg_flag) &&
997 (panel->lcd_if != LCD_IF_DSI)) {
998 /*only support DSI*/
999 *min_dclk = 9999;
1000 *max_dclk = 0;
1001 goto OUT;
1002 }
1003
1004 if ((ic_ver == 0) && (panel->lcd_if == LCD_IF_DSI)) {
1005 /*not support DSI*/
1006 *min_dclk = 9999;
1007 *max_dclk = 0;
1008 goto OUT;
1009 }
1010
1011 if (panel->lcd_if == LCD_IF_DSI) {
1012 if (qa_val == 0)
1013 *min_dclk = 40; /*1024*600@60*/
1014 /* normal qa and B/C ic */
1015 if (qa_val == 1 && ic_ver == 0) {
1016 *min_dclk = 64; /*1280*720@60*/
1017 }
1018 } else {
1019 /*LVDS or RGB*/
1020 *min_dclk = 40; /*1024*600@60*/
1021 }
1022
1023 *max_dclk = 85; /*1280*720@60*/
1024 } break;
1025 case 0x0400: /*A100*/
1026 {
1027 if (panel->lcd_if == LCD_IF_DSI) {
1028 if (qa_val == 0)
1029 *min_dclk = 40; /*1024*600@60*/
1030 /* normal qa and B/C ic */
1031 if (qa_val == 1 && ic_ver == 0) {
1032 *min_dclk = 64; /*1280*720@60*/
1033 }
1034 } else {
1035 /*LVDS or RGB*/
1036 *min_dclk = 40; /*1024*600@60*/
1037 }
1038
1039 *max_dclk = 85; /*1280*720@60*/
1040 } break;
1041 case 0x1400: /*A133*/
1042 {
1043 if (panel->lcd_if == LCD_IF_DSI) {
1044 if ((qa_val == 0 && ic_ver == 0) ||
1045 (qa_val == 1 && ic_ver == 3)) {
1046 /*D 01 or B/C 00*/
1047 *min_dclk = 40;
1048 } else if (qa_val == 1 && ic_ver == 0) {
1049 /*B/C 01*/
1050 *min_dclk = 64; /*1280*720@60*/
1051 }
1052 }
1053 *max_dclk = 200; /*1920*1200@60*/
1054 } break;
1055 case 0x1000: /*R818/MR813*/
1056 case 0x2000: {
1057 /*not bad ic*/
1058 *max_dclk = 200; /*1920*1200@60*/
1059 } break;
1060 case 0x0800: { /*T509*/
1061 if (panel->lcd_if == LCD_IF_DSI) {
1062 if (qa_val == 0 && ic_ver == 0)
1063 *min_dclk = 40;/*1024*600@60*/
1064 else
1065 *min_dclk = 0;
1066 }
1067 *max_dclk = 200; /*1920*1200@60*/
1068 } break;
1069 case 0x4000: { /*not support*/
1070 *min_dclk = 9999;
1071 *max_dclk = 0;
1072 }
1073 break;
1074 default:
1075 break;
1076 }
1077 }
1078 OUT:
1079 #endif
1080
1081 /*unlimit */
1082 return 0;
1083 }
1084
disp_lcd_tcon_enable(struct disp_device * lcd)1085 static s32 disp_lcd_tcon_enable(struct disp_device *lcd)
1086 {
1087 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1088 u32 min_dclk = 0, max_dclk = 0;
1089
1090 if ((lcd == NULL) || (lcdp == NULL)) {
1091 DE_WRN("NULL hdl!\n");
1092 return -1;
1093 }
1094
1095 disp_lcd_speed_limit(&lcdp->panel_info, &min_dclk, &max_dclk);
1096
1097 if (lcdp->panel_info.lcd_dclk_freq < min_dclk ||
1098 lcdp->panel_info.lcd_dclk_freq > max_dclk) {
1099 return 0;
1100 }
1101
1102 return disp_al_lcd_enable(lcd->hwdev_index, &lcdp->panel_info);
1103 }
1104
disp_lcd_tcon_disable(struct disp_device * lcd)1105 s32 disp_lcd_tcon_disable(struct disp_device *lcd)
1106 {
1107 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1108
1109 if ((lcd == NULL) || (lcdp == NULL)) {
1110 DE_WRN("NULL hdl!\n");
1111 return -1;
1112 }
1113
1114 return disp_al_lcd_disable(lcd->hwdev_index, &lcdp->panel_info);
1115 }
1116
disp_lcd_pin_cfg(struct disp_device * lcd,u32 bon)1117 static s32 disp_lcd_pin_cfg(struct disp_device *lcd, u32 bon)
1118 {
1119 int i, ret;
1120 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1121 char dev_name[25];
1122
1123 if ((lcd == NULL) || (lcdp == NULL)) {
1124 DE_WRN("NULL hdl!\n");
1125 return DIS_FAIL;
1126 }
1127 DE_INF("lcd %d pin config, state %s, %d\n", lcd->disp,
1128 (bon) ? "on" : "off", bon);
1129
1130 /* io-pad */
1131 if (bon == 1) {
1132 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
1133 ret = disp_sys_power_enable(lcdp->lcd_cfg.pin_regulator[i]);
1134 if (ret)
1135 return DIS_FAIL;
1136 }
1137 }
1138
1139 sprintf(dev_name, "lcd%d", lcd->disp);
1140 disp_sys_pin_set_state(dev_name,
1141 (bon == 1) ?
1142 DISP_PIN_STATE_ACTIVE : DISP_PIN_STATE_SLEEP);
1143
1144 disp_al_lcd_io_cfg(lcd->hwdev_index, bon, &lcdp->panel_info);
1145
1146 if (bon)
1147 return DIS_SUCCESS;
1148
1149 for (i = LCD_GPIO_REGU_NUM - 1; i >= 0; i--) {
1150 ret = disp_sys_power_disable(lcdp->lcd_cfg.pin_regulator[i]);
1151 if (ret)
1152 return DIS_FAIL;
1153 }
1154
1155 return DIS_SUCCESS;
1156 }
1157
1158 #if defined(CONFIG_FPGA_V4_PLATFORM) && defined(SUPPORT_EINK)
disp_lcd_pwm_enable(struct disp_device * lcd)1159 static s32 disp_lcd_pwm_enable(struct disp_device *lcd)
1160 {
1161 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1162
1163 unsigned long reg = 0;
1164 unsigned long val = 0;
1165
1166 if ((lcd == NULL) || (lcdp == NULL)) {
1167 DE_WRN("NULL hdl!\n");
1168 return DIS_FAIL;
1169 }
1170 if (disp_lcd_is_used(lcd) && lcdp->pwm_info.dev) {
1171 reg = ((unsigned long)0xf1c20878);
1172 val = readl(reg);
1173 val = val & 0xfff0ffff;
1174 val = val | 0x10000;
1175 writel(val, reg);
1176 reg = ((unsigned long)0xf1c2087C);
1177 val = readl(reg);
1178 val = val & 0xefffffff;
1179 val = val | 0x10000000;
1180 writel(val, reg);
1181 return 0;
1182 }
1183 DE_WRN("pwm device hdl is NULL\n");
1184 return DIS_FAIL;
1185 }
disp_lcd_pwm_disable(struct disp_device * lcd)1186 static s32 disp_lcd_pwm_disable(struct disp_device *lcd)
1187 {
1188 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1189 unsigned long reg = 0;
1190 unsigned long val = 0;
1191
1192 if ((lcd == NULL) || (lcdp == NULL)) {
1193 DE_WRN("NULL hdl!\n");
1194 return DIS_FAIL;
1195 }
1196 if (disp_lcd_is_used(lcd) && lcdp->pwm_info.dev) {
1197 reg = ((unsigned long)0xf1c20878);
1198 val = readl(reg);
1199 val = val & 0xfff0ffff;
1200 val = val | 0x10000;
1201 writel(val, reg);
1202 reg = ((unsigned long)0xf1c2087C);
1203 val = readl(reg);
1204 val = val & 0xefffffff;
1205 val = val | 0x00000000;
1206 writel(val, reg);
1207 return 0;
1208 }
1209 DE_WRN("pwm device hdl is NULL\n");
1210 return DIS_FAIL;
1211 }
1212 #else
disp_lcd_pwm_enable(struct disp_device * lcd)1213 static s32 disp_lcd_pwm_enable(struct disp_device *lcd)
1214 {
1215 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1216
1217 if ((lcd == NULL) || (lcdp == NULL)) {
1218 DE_WRN("NULL hdl!\n");
1219 return DIS_FAIL;
1220 }
1221
1222 if (lcdp->panel_info.lcd_pwm_used && !lcdp->pwm_info.dev) {
1223 lcdp->pwm_info.dev =
1224 disp_sys_pwm_request(lcdp->panel_info.lcd_pwm_ch);
1225 }
1226
1227 if (disp_lcd_is_used(lcd) && lcdp->pwm_info.dev)
1228 return disp_sys_pwm_enable(lcdp->pwm_info.dev);
1229 DE_WRN("pwm device hdl is NULL\n");
1230
1231 return DIS_FAIL;
1232 }
1233
disp_lcd_pwm_disable(struct disp_device * lcd)1234 static s32 disp_lcd_pwm_disable(struct disp_device *lcd)
1235 {
1236 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1237 s32 ret = -1;
1238 struct pwm_device *pwm_dev;
1239
1240 if ((lcd == NULL) || (lcdp == NULL)) {
1241 DE_WRN("NULL hdl!\n");
1242 return DIS_FAIL;
1243 }
1244
1245 if (disp_lcd_is_used(lcd) && lcdp->pwm_info.dev) {
1246 ret = disp_sys_pwm_disable(lcdp->pwm_info.dev);
1247 pwm_dev = (struct pwm_device *)lcdp->pwm_info.dev;
1248 /*following is for reset pwm state purpose*/
1249 disp_sys_pwm_config(lcdp->pwm_info.dev,
1250 pwm_dev->state.duty_cycle - 1,
1251 pwm_dev->state.period);
1252 disp_sys_pwm_set_polarity(lcdp->pwm_info.dev,
1253 !lcdp->pwm_info.polarity);
1254
1255 disp_sys_pwm_free(lcdp->pwm_info.dev);
1256 lcdp->pwm_info.dev = 0;
1257
1258 return ret;
1259 }
1260 DE_WRN("pwm device hdl is NULL\n");
1261
1262 return DIS_FAIL;
1263 }
1264 #endif
1265
disp_lcd_backlight_enable(struct disp_device * lcd)1266 static s32 disp_lcd_backlight_enable(struct disp_device *lcd)
1267 {
1268 int ret;
1269 struct disp_gpio_info gpio_info;
1270 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1271 unsigned long flags;
1272
1273 if ((lcd == NULL) || (lcdp == NULL)) {
1274 DE_WRN("NULL hdl!\n");
1275 return DIS_FAIL;
1276 }
1277
1278 spin_lock_irqsave(&lcd_data_lock, flags);
1279 if (lcdp->bl_enabled) {
1280 spin_unlock_irqrestore(&lcd_data_lock, flags);
1281 return -EBUSY;
1282 }
1283
1284 lcdp->bl_need_enabled = 1;
1285 lcdp->bl_enabled = true;
1286 spin_unlock_irqrestore(&lcd_data_lock, flags);
1287
1288 if (disp_lcd_is_used(lcd)) {
1289 unsigned bl;
1290
1291 if (lcdp->lcd_cfg.lcd_bl_en_used) {
1292 /* io-pad */
1293 ret = disp_sys_power_enable(lcdp->lcd_cfg.bl_regulator);
1294 if (ret)
1295 return DIS_FAIL;
1296
1297 memcpy(&gpio_info, &(lcdp->lcd_cfg.lcd_bl_en),
1298 sizeof(struct disp_gpio_info));
1299
1300 disp_sys_gpio_request(&gpio_info);
1301 }
1302 bl = disp_lcd_get_bright(lcd);
1303 disp_lcd_set_bright(lcd, bl);
1304 }
1305
1306 return 0;
1307 }
1308
disp_lcd_backlight_disable(struct disp_device * lcd)1309 static s32 disp_lcd_backlight_disable(struct disp_device *lcd)
1310 {
1311 int ret;
1312 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1313 unsigned long flags;
1314
1315 if ((lcd == NULL) || (lcdp == NULL)) {
1316 DE_WRN("NULL hdl!\n");
1317 return DIS_FAIL;
1318 }
1319
1320 spin_lock_irqsave(&lcd_data_lock, flags);
1321 if (!lcdp->bl_enabled) {
1322 spin_unlock_irqrestore(&lcd_data_lock, flags);
1323 return -EBUSY;
1324 }
1325
1326 lcdp->bl_enabled = false;
1327 spin_unlock_irqrestore(&lcd_data_lock, flags);
1328
1329 if (!disp_lcd_is_used(lcd))
1330 return DIS_SUCCESS;
1331
1332 if (!lcdp->lcd_cfg.lcd_bl_en_used)
1333 return DIS_SUCCESS;
1334
1335 ret = disp_sys_power_disable(lcdp->lcd_cfg.bl_regulator);
1336 if (ret)
1337 return DIS_FAIL;
1338
1339 return DIS_SUCCESS;
1340 }
1341
1342 #if defined(CONFIG_FPGA_V4_PLATFORM) && defined(SUPPORT_EINK)
disp_lcd_power_enable(struct disp_device * lcd,u32 power_id)1343 static s32 disp_lcd_power_enable(struct disp_device *lcd, u32 power_id)
1344 {
1345 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1346 unsigned long reg = 0;
1347 unsigned long val = 0;
1348
1349 if ((lcd == NULL) || (lcdp == NULL)) {
1350 DE_WRN("NULL hdl!\n");
1351 return DIS_FAIL;
1352 }
1353 if (disp_lcd_is_used(lcd)) {
1354 reg = ((unsigned long)0xf1c20878);
1355 val = readl(reg);
1356 val = val & 0x000fffff;
1357 val = val | 0x11100000;
1358 writel(val, reg);
1359 reg = ((unsigned long)0xf1c2087C);
1360 val = readl(reg);
1361 val = val & 0x1fffffff;
1362 val = val | 0xe0000000;
1363 writel(val, reg);
1364 return 0;
1365 }
1366 return DIS_FAIL;
1367 }
disp_lcd_power_disable(struct disp_device * lcd,u32 power_id)1368 static s32 disp_lcd_power_disable(struct disp_device *lcd, u32 power_id)
1369 {
1370 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1371 unsigned long reg = 0;
1372 unsigned long val = 0;
1373
1374 if ((lcd == NULL) || (lcdp == NULL)) {
1375 DE_WRN("NULL hdl!\n");
1376 return DIS_FAIL;
1377 }
1378 if (disp_lcd_is_used(lcd)) {
1379 reg = ((unsigned long)0xf1c20878);
1380 val = readl(reg);
1381 val = val & 0x000fffff;
1382 val = val | 0x77700000;
1383 writel(val, reg);
1384 return 0;
1385 }
1386 return DIS_FAIL;
1387 }
1388 #else
disp_lcd_power_enable(struct disp_device * lcd,u32 power_id)1389 static s32 disp_lcd_power_enable(struct disp_device *lcd, u32 power_id)
1390 {
1391 int ret;
1392 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1393
1394 if (!disp_lcd_is_used(lcd))
1395 return DIS_SUCCESS;
1396
1397 if (!lcdp->lcd_cfg.regulator[power_id])
1398 return DIS_SUCCESS;
1399
1400 ret = disp_sys_power_enable(lcdp->lcd_cfg.regulator[power_id]);
1401 if (ret)
1402 return DIS_FAIL;
1403
1404 return DIS_SUCCESS;
1405 }
1406
disp_lcd_power_disable(struct disp_device * lcd,u32 power_id)1407 static s32 disp_lcd_power_disable(struct disp_device *lcd, u32 power_id)
1408 {
1409 int ret;
1410 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1411
1412 if ((lcd == NULL) || (lcdp == NULL)) {
1413 DE_WRN("NULL hdl!\n");
1414 return DIS_FAIL;
1415 }
1416
1417 ret = disp_sys_power_disable(lcdp->lcd_cfg.regulator[power_id]);
1418 if (ret)
1419 return DIS_FAIL;
1420
1421 return DIS_SUCCESS;
1422 }
1423 #endif
1424
disp_lcd_bright_get_adjust_value(struct disp_device * lcd,u32 bright)1425 static s32 disp_lcd_bright_get_adjust_value(struct disp_device *lcd, u32 bright)
1426 {
1427 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1428
1429 if ((lcd == NULL) || (lcdp == NULL)) {
1430 DE_WRN("NULL hdl!\n");
1431 return DIS_FAIL;
1432 }
1433 bright = (bright > 255) ? 255 : bright;
1434 return lcdp->panel_extend_info.lcd_bright_curve_tbl[bright];
1435 }
1436
disp_lcd_bright_curve_init(struct disp_device * lcd)1437 static s32 disp_lcd_bright_curve_init(struct disp_device *lcd)
1438 {
1439 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1440 u32 i = 0, j = 0;
1441 u32 items = 0;
1442 u32 lcd_bright_curve_tbl[101][2];
1443
1444 if ((lcd == NULL) || (lcdp == NULL)) {
1445 DE_WRN("NULL hdl!\n");
1446 return DIS_FAIL;
1447 }
1448
1449 for (i = 0; i < 101; i++) {
1450 if (lcdp->lcd_cfg.backlight_curve_adjust[i] == 0) {
1451 if (i == 0) {
1452 lcd_bright_curve_tbl[items][0] = 0;
1453 lcd_bright_curve_tbl[items][1] = 0;
1454 items++;
1455 }
1456 } else {
1457 lcd_bright_curve_tbl[items][0] = 255 * i / 100;
1458 lcd_bright_curve_tbl[items][1] =
1459 lcdp->lcd_cfg.backlight_curve_adjust[i];
1460 items++;
1461 }
1462 }
1463
1464 for (i = 0; i < items - 1; i++) {
1465 u32 num =
1466 lcd_bright_curve_tbl[i + 1][0] - lcd_bright_curve_tbl[i][0];
1467
1468 for (j = 0; j < num; j++) {
1469 u32 value = 0;
1470
1471 value =
1472 lcd_bright_curve_tbl[i][1] +
1473 ((lcd_bright_curve_tbl[i + 1][1] -
1474 lcd_bright_curve_tbl[i][1]) * j) / num;
1475 lcdp->panel_extend_info.
1476 lcd_bright_curve_tbl[lcd_bright_curve_tbl[i][0] +
1477 j] = value;
1478 }
1479 }
1480 lcdp->panel_extend_info.lcd_bright_curve_tbl[255] =
1481 lcd_bright_curve_tbl[items - 1][1];
1482
1483 return 0;
1484 }
1485
disp_lcd_set_bright(struct disp_device * lcd,u32 bright)1486 s32 disp_lcd_set_bright(struct disp_device *lcd, u32 bright)
1487 {
1488 u32 duty_ns;
1489 __u64 backlight_bright = bright;
1490 __u64 backlight_dimming;
1491 __u64 period_ns;
1492 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1493 unsigned long flags;
1494 bool bright_update = false;
1495 struct disp_manager *mgr = NULL;
1496 struct disp_smbl *smbl = NULL;
1497
1498 if ((lcd == NULL) || (lcdp == NULL)) {
1499 DE_WRN("NULL hdl!\n");
1500 return DIS_FAIL;
1501 }
1502 mgr = lcd->manager;
1503 if (mgr == NULL) {
1504 DE_WRN("NULL hdl!\n");
1505 return DIS_FAIL;
1506 }
1507 smbl = mgr->smbl;
1508
1509 spin_lock_irqsave(&lcd_data_lock, flags);
1510 backlight_bright = (backlight_bright > 255) ? 255 : backlight_bright;
1511 if (lcdp->lcd_cfg.backlight_bright != backlight_bright) {
1512 bright_update = true;
1513 lcdp->lcd_cfg.backlight_bright = backlight_bright;
1514 }
1515 spin_unlock_irqrestore(&lcd_data_lock, flags);
1516 if (bright_update && smbl)
1517 smbl->update_backlight(smbl, backlight_bright);
1518
1519 if (lcdp->pwm_info.dev) {
1520 if (backlight_bright != 0)
1521 backlight_bright += 1;
1522 backlight_bright =
1523 disp_lcd_bright_get_adjust_value(lcd, backlight_bright);
1524
1525 lcdp->lcd_cfg.backlight_dimming =
1526 (lcdp->lcd_cfg.backlight_dimming ==
1527 0) ? 256 : lcdp->lcd_cfg.backlight_dimming;
1528 backlight_dimming = lcdp->lcd_cfg.backlight_dimming;
1529 period_ns = lcdp->pwm_info.period_ns;
1530 duty_ns =
1531 (backlight_bright * backlight_dimming * period_ns / 256 +
1532 128) / 256;
1533 lcdp->pwm_info.duty_ns = duty_ns;
1534 disp_sys_pwm_config(lcdp->pwm_info.dev, duty_ns, period_ns);
1535 }
1536
1537 if (lcdp->lcd_panel_fun.set_bright && lcdp->enabled) {
1538 lcdp->lcd_panel_fun.set_bright(lcd->disp,
1539 disp_lcd_bright_get_adjust_value
1540 (lcd, bright));
1541 }
1542
1543 return DIS_SUCCESS;
1544 }
1545
disp_lcd_get_bright(struct disp_device * lcd)1546 s32 disp_lcd_get_bright(struct disp_device *lcd)
1547 {
1548 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1549
1550 if ((lcd == NULL) || (lcdp == NULL)) {
1551 DE_WRN("NULL hdl!\n");
1552 return DIS_FAIL;
1553 }
1554
1555 return lcdp->lcd_cfg.backlight_bright;
1556 }
1557
disp_lcd_set_bright_dimming(struct disp_device * lcd,u32 dimming)1558 static s32 disp_lcd_set_bright_dimming(struct disp_device *lcd, u32 dimming)
1559 {
1560 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1561 u32 bl = 0;
1562
1563 if ((lcd == NULL) || (lcdp == NULL)) {
1564 DE_WRN("NULL hdl!\n");
1565 return DIS_FAIL;
1566 }
1567
1568 dimming = dimming > 256 ? 256 : dimming;
1569 lcdp->lcd_cfg.backlight_dimming = dimming;
1570 bl = disp_lcd_get_bright(lcd);
1571 disp_lcd_set_bright(lcd, bl);
1572
1573 return DIS_SUCCESS;
1574 }
1575
disp_lcd_get_panel_info(struct disp_device * lcd,struct disp_panel_para * info)1576 static s32 disp_lcd_get_panel_info(struct disp_device *lcd,
1577 struct disp_panel_para *info)
1578 {
1579 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1580
1581 if ((lcd == NULL) || (lcdp == NULL)) {
1582 DE_WRN("NULL hdl!\n");
1583 return DIS_FAIL;
1584 }
1585
1586 memcpy(info, (struct disp_panel_para *) (&(lcdp->panel_info)),
1587 sizeof(struct disp_panel_para));
1588 return 0;
1589 }
1590
1591 #if defined(__LINUX_PLAT__)
disp_lcd_event_proc(int irq,void * parg)1592 static irqreturn_t disp_lcd_event_proc(int irq, void *parg)
1593 #else
1594 static irqreturn_t disp_lcd_event_proc(void *parg)
1595 #endif
1596 {
1597 struct disp_device *lcd = (struct disp_device *)parg;
1598 struct disp_lcd_private_data *lcdp = NULL;
1599 struct disp_manager *mgr = NULL;
1600 #if defined(SUPPORT_EINK) && defined(CONFIG_EINK_PANEL_USED)
1601 struct disp_eink_manager *eink_manager = NULL;
1602 #endif
1603 u32 hwdev_index;
1604 u32 irq_flag = 0;
1605 unsigned int panel_extend_dirty;
1606 unsigned long flags;
1607
1608 if (lcd == NULL)
1609 return DISP_IRQ_RETURN;
1610
1611 hwdev_index = lcd->hwdev_index;
1612 lcdp = disp_lcd_get_priv(lcd);
1613
1614 if (lcdp == NULL)
1615 return DISP_IRQ_RETURN;
1616
1617 #if defined(SUPPORT_EINK) && defined(CONFIG_EINK_PANEL_USED)
1618 eink_manager = disp_get_eink_manager(0);
1619 if (eink_manager == NULL)
1620 return DISP_IRQ_RETURN;
1621 #endif
1622
1623 if (disp_al_lcd_query_irq
1624 (hwdev_index, LCD_IRQ_TCON0_VBLK, &lcdp->panel_info)) {
1625 #if defined(SUPPORT_EINK) && defined(CONFIG_EINK_PANEL_USED)
1626
1627 eink_display_one_frame(eink_manager);
1628 #else
1629 int cur_line =
1630 disp_al_lcd_get_cur_line(hwdev_index, &lcdp->panel_info);
1631 int start_delay =
1632 disp_al_lcd_get_start_delay(hwdev_index, &lcdp->panel_info);
1633 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
1634 if (lcdp->lcd_panel_fun.esd_check &&
1635 lcdp->lcd_panel_fun.reset_panel) {
1636 ++lcdp->esd_inf.cnt;
1637 if (cur_line < 2 &&
1638 !atomic_read(&lcdp->lcd_resetting) &&
1639 lcdp->esd_inf.cnt >= lcdp->esd_inf.freq) {
1640 if (!lcdp->esd_inf.esd_check_func_pos ||
1641 lcdp->lcd_panel_fun.esd_check(lcd->disp)) {
1642 /*request reset*/
1643 atomic_set(&lcdp->lcd_resetting, 1);
1644 schedule_work(&lcdp->reflush_work);
1645 }
1646 lcdp->esd_inf.cnt = 0;
1647 }
1648 }
1649 #endif
1650
1651 mgr = lcd->manager;
1652 if (mgr == NULL)
1653 return DISP_IRQ_RETURN;
1654
1655 if (cur_line <= (start_delay - lcdp->judge_line))
1656 sync_event_proc(mgr->disp, false);
1657 else
1658 sync_event_proc(mgr->disp, true);
1659 #endif
1660 } else {
1661 irq_flag = disp_al_lcd_query_irq(hwdev_index, LCD_IRQ_TCON0_CNTR,
1662 &lcdp->panel_info);
1663 irq_flag |=
1664 disp_al_lcd_query_irq(hwdev_index, LCD_IRQ_TCON0_TRIF,
1665 &lcdp->panel_info);
1666
1667 if (irq_flag == 0)
1668 goto exit;
1669
1670 if (disp_al_lcd_tri_busy(hwdev_index, &lcdp->panel_info)) {
1671 /* if lcd is still busy when tri/cnt irq coming,
1672 * take it as failture, record failture times,
1673 * when it reach 2 times, clear counter
1674 */
1675 lcdp->tri_finish_fail++;
1676 lcdp->tri_finish_fail = (lcdp->tri_finish_fail == 2) ?
1677 0 : lcdp->tri_finish_fail;
1678 } else
1679 lcdp->tri_finish_fail = 0;
1680
1681 mgr = lcd->manager;
1682 if (mgr == NULL)
1683 return DISP_IRQ_RETURN;
1684
1685 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
1686 if (lcdp->lcd_panel_fun.esd_check &&
1687 lcdp->lcd_panel_fun.reset_panel) {
1688 ++lcdp->esd_inf.cnt;
1689 if (!atomic_read(&lcdp->lcd_resetting) &&
1690 lcdp->esd_inf.cnt >= lcdp->esd_inf.freq) {
1691 if (!lcdp->esd_inf.esd_check_func_pos ||
1692 lcdp->lcd_panel_fun.esd_check(lcd->disp)) {
1693 /*request reset*/
1694 atomic_set(&lcdp->lcd_resetting, 1);
1695 schedule_work(&lcdp->reflush_work);
1696 }
1697 lcdp->esd_inf.cnt = 0;
1698 }
1699 }
1700 #endif
1701
1702 if (lcdp->tri_finish_fail == 0) {
1703 sync_event_proc(mgr->disp, false);
1704 disp_al_lcd_tri_start(hwdev_index, &lcdp->panel_info);
1705 } else
1706 sync_event_proc(mgr->disp, true);
1707 }
1708
1709 spin_lock_irqsave(&lcd_data_lock, flags);
1710 panel_extend_dirty = lcdp->panel_extend_dirty;
1711 lcdp->panel_extend_dirty = 0;
1712 spin_unlock_irqrestore(&lcd_data_lock, flags);
1713 if (panel_extend_dirty == 1)
1714 disp_al_lcd_cfg_ext(lcd->disp, &lcdp->panel_extend_info_set);
1715
1716 exit:
1717 return DISP_IRQ_RETURN;
1718 }
1719
1720 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
disp_lcd_reflush_work(struct work_struct * work)1721 static void disp_lcd_reflush_work(struct work_struct *work)
1722 {
1723 struct disp_lcd_private_data *lcdp =
1724 container_of(work, struct disp_lcd_private_data, reflush_work);
1725 struct disp_device *lcd = disp_device_get_from_priv((void *)lcdp);
1726 unsigned long flags;
1727
1728 if (!lcdp || !lcd) {
1729 DE_WRN("lcdp is null\n");
1730 return;
1731 }
1732
1733 /*lcd is not enabled or is enabling*/
1734 if (disp_lcd_is_enabled(lcd) == 0 || lcdp->enabling == 1)
1735 return;
1736
1737 /*lcd is resetting*/
1738 if (atomic_read(&lcdp->lcd_resetting) == 2)
1739 return;
1740
1741 if (!lcdp->esd_inf.esd_check_func_pos)
1742 if (lcdp->lcd_panel_fun.esd_check)
1743 if (!lcdp->lcd_panel_fun.esd_check(lcd->disp)) {
1744 atomic_set(&lcdp->lcd_resetting, 0);
1745 return; /*everything is just fine*/
1746 }
1747
1748 if (lcdp->esd_inf.level == 1) {
1749 spin_lock_irqsave(&lcd_data_lock, flags);
1750 lcdp->enabled = 0;
1751 lcdp->enabling = 1;
1752 spin_unlock_irqrestore(&lcd_data_lock, flags);
1753
1754 atomic_set(&lcdp->lcd_resetting, 2);
1755
1756 disp_lcd_tcon_disable(lcd);
1757 disp_al_lcd_cfg(lcd->hwdev_index, &lcdp->panel_info,
1758 &lcdp->panel_extend_info_set);
1759 } else
1760 atomic_set(&lcdp->lcd_resetting, 2);
1761
1762
1763 ++lcdp->esd_inf.rst_cnt;
1764 if (lcdp->lcd_panel_fun.reset_panel)
1765 lcdp->lcd_panel_fun.reset_panel(lcd->disp);
1766
1767 if (lcdp->esd_inf.level == 1) {
1768 disp_lcd_tcon_enable(lcd);
1769
1770 spin_lock_irqsave(&lcd_data_lock, flags);
1771 lcdp->enabled = 1;
1772 lcdp->enabling = 0;
1773 spin_unlock_irqrestore(&lcd_data_lock, flags);
1774 }
1775
1776 disp_delay_ms(300);
1777
1778 /*lcd reset finish*/
1779 atomic_set(&lcdp->lcd_resetting, 0);
1780 }
1781 #endif
1782
disp_lcd_cal_fps(struct disp_device * lcd)1783 static s32 disp_lcd_cal_fps(struct disp_device *lcd)
1784 {
1785 s32 ret = -1;
1786 struct disp_lcd_private_data *lcdp = NULL;
1787 struct disp_panel_para *panel_info = NULL;
1788
1789 if (!lcd)
1790 goto OUT;
1791 lcdp = disp_lcd_get_priv(lcd);
1792 if (!lcdp)
1793 goto OUT;
1794 panel_info = &lcdp->panel_info;
1795
1796
1797 lcdp->frame_per_sec =
1798 DIV_ROUND_CLOSEST(panel_info->lcd_dclk_freq * 1000000 *
1799 (panel_info->lcd_interlace + 1),
1800 panel_info->lcd_ht * panel_info->lcd_vt);
1801
1802 ret = 0;
1803 OUT:
1804 return ret;
1805 }
1806
1807 /* lcd enable except for backlight */
disp_lcd_fake_enable(struct disp_device * lcd)1808 static s32 disp_lcd_fake_enable(struct disp_device *lcd)
1809 {
1810 unsigned long flags;
1811 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1812 int i, ret;
1813 struct disp_manager *mgr = NULL;
1814
1815 if ((lcd == NULL) || (lcdp == NULL)) {
1816 DE_WRN("NULL hdl!\n");
1817 return DIS_FAIL;
1818 }
1819 DE_INF("lcd %d\n", lcd->disp);
1820 mgr = lcd->manager;
1821 if (mgr == NULL) {
1822 DE_WRN("mgr is NULL!\n");
1823 return DIS_FAIL;
1824 }
1825 if (disp_lcd_is_enabled(lcd) == 1)
1826 return 0;
1827
1828 disp_lcd_cal_fps(lcd);
1829 if (mgr->enable)
1830 mgr->enable(mgr);
1831
1832 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
1833 if ((lcdp->panel_info.lcd_if == LCD_IF_DSI) &&
1834 (lcdp->irq_no_dsi != 0)) {
1835 if (lcdp->panel_info.lcd_dsi_if == LCD_DSI_IF_COMMAND_MODE) {
1836 disp_sys_register_irq(lcdp->irq_no, 0,
1837 disp_lcd_event_proc, (void *)lcd,
1838 0, 0);
1839 disp_sys_enable_irq(lcdp->irq_no);
1840 } else {
1841 disp_sys_register_irq(lcdp->irq_no_dsi, 0,
1842 disp_lcd_event_proc, (void *)lcd,
1843 0, 0);
1844 disp_sys_enable_irq(lcdp->irq_no_dsi);
1845 }
1846 } else
1847 #endif
1848 {
1849 disp_sys_register_irq(lcdp->irq_no, 0, disp_lcd_event_proc,
1850 (void *)lcd, 0, 0);
1851 disp_sys_enable_irq(lcdp->irq_no);
1852 }
1853 spin_lock_irqsave(&lcd_data_lock, flags);
1854 lcdp->enabling = 1;
1855 lcdp->bl_need_enabled = 0;
1856 spin_unlock_irqrestore(&lcd_data_lock, flags);
1857 disp_lcd_gpio_init(lcd);
1858 lcd_clk_enable(lcd);
1859 ret = cal_real_frame_period(lcd);
1860 if (ret)
1861 DE_WRN("cal_real_frame_period fail:%d\n", ret);
1862 if (lcdp->panel_info.lcd_pwm_used && !lcdp->pwm_info.dev)
1863 lcdp->pwm_info.dev =
1864 disp_sys_pwm_request(lcdp->panel_info.lcd_pwm_ch);
1865 disp_sys_pwm_config(lcdp->pwm_info.dev, lcdp->pwm_info.duty_ns,
1866 lcdp->pwm_info.period_ns);
1867 disp_sys_pwm_set_polarity(lcdp->pwm_info.dev, lcdp->pwm_info.polarity);
1868 disp_al_lcd_cfg(lcd->hwdev_index, &lcdp->panel_info,
1869 &lcdp->panel_extend_info_set);
1870 lcdp->open_flow.func_num = 0;
1871 if (lcdp->lcd_panel_fun.cfg_open_flow)
1872 lcdp->lcd_panel_fun.cfg_open_flow(lcd->disp);
1873 else
1874 DE_WRN("lcd_panel_fun[%d].cfg_open_flow is NULL\n", lcd->disp);
1875
1876 for (i = 0; i < lcdp->open_flow.func_num - 1; i++) {
1877 if (lcdp->open_flow.func[i].func) {
1878 lcdp->open_flow.func[i].func(lcd->disp);
1879 DE_INF("open flow:step %d finish, to delay %d\n", i,
1880 lcdp->open_flow.func[i].delay);
1881 if (lcdp->open_flow.func[i].delay != 0)
1882 disp_delay_ms(lcdp->open_flow.func[i].delay);
1883 }
1884 }
1885 spin_lock_irqsave(&lcd_data_lock, flags);
1886 lcdp->enabled = 1;
1887 lcdp->enabling = 0;
1888 spin_unlock_irqrestore(&lcd_data_lock, flags);
1889 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
1890 atomic_set(&lcdp->lcd_resetting, 0);
1891 #endif
1892
1893 return 0;
1894 }
1895
1896 static int skip_open_backlight;
1897 #ifndef MODULE
early_bootreason(char * str)1898 static int __init early_bootreason(char *str)
1899 {
1900 skip_open_backlight = 0;
1901 if (!str) {
1902 skip_open_backlight = 0;
1903 goto OUT;
1904 }
1905
1906 if (parse_option_str("irq", str) == true) {
1907 skip_open_backlight = 1;
1908 pr_warn("get irq bootreason:%s\n", str);
1909 } else {
1910 skip_open_backlight = 0;
1911 }
1912
1913 OUT:
1914 return 0;
1915 }
1916 early_param("bootreason", early_bootreason);
1917 #endif
1918
1919 #if defined(SUPPORT_EINK) && defined(CONFIG_EINK_PANEL_USED)
disp_lcd_enable(struct disp_device * lcd)1920 static s32 disp_lcd_enable(struct disp_device *lcd)
1921 {
1922 unsigned long flags;
1923 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1924 struct disp_manager *mgr = NULL;
1925 int ret = 0;
1926 int i;
1927
1928 if ((lcd == NULL) || (lcdp == NULL)) {
1929 DE_WRN("NULL hdl!\n");
1930 return DIS_FAIL;
1931 }
1932
1933 if (!disp_lcd_is_used(lcd)) {
1934 return ret;
1935 }
1936
1937 flush_work(&lcd->close_eink_panel_work);
1938 DE_INF("lcd %d\n", lcd->disp);
1939 mgr = lcd->manager;
1940 if (mgr == NULL) {
1941 DE_WRN("mgr is NULL!\n");
1942 return DIS_FAIL;
1943 }
1944 if (disp_lcd_is_enabled(lcd) == 1)
1945 return 0;
1946
1947 disp_sys_register_irq(lcdp->irq_no, 0, disp_lcd_event_proc, (void *)lcd,
1948 0, 0);
1949 disp_sys_enable_irq(lcdp->irq_no);
1950
1951 spin_lock_irqsave(&lcd_data_lock, flags);
1952 lcdp->enabling = 1;
1953 lcdp->bl_need_enabled = 0;
1954 spin_unlock_irqrestore(&lcd_data_lock, flags);
1955 if (lcdp->lcd_panel_fun.cfg_panel_info)
1956 lcdp->lcd_panel_fun.cfg_panel_info(&lcdp->panel_extend_info);
1957 else
1958 DE_WRN("lcd_panel_fun[%d].cfg_panel_info is NULL\n", lcd->disp);
1959
1960 disp_lcd_gpio_init(lcd);
1961 ret = lcd_clk_enable(lcd);
1962 if (ret != 0)
1963 return DIS_FAIL;
1964 ret = cal_real_frame_period(lcd);
1965 if (ret)
1966 DE_WRN("cal_real_frame_period fail:%d\n", ret);
1967
1968 disp_al_lcd_cfg(lcd->hwdev_index, &lcdp->panel_info,
1969 &lcdp->panel_extend_info);/* init tcon_lcd regs */
1970 lcdp->open_flow.func_num = 0;
1971 if (lcdp->lcd_panel_fun.cfg_open_flow)
1972 lcdp->lcd_panel_fun.cfg_open_flow(lcd->disp);
1973 else
1974 DE_WRN("lcd_panel_fun[%d].cfg_open_flow is NULL\n", lcd->disp);
1975
1976 for (i = 0; i < lcdp->open_flow.func_num; i++) {
1977 if (lcdp->open_flow.func[i].func) {
1978 lcdp->open_flow.func[i].func(lcd->disp);
1979 DE_INF("open flow:step %d finish, to delay %d\n", i,
1980 lcdp->open_flow.func[i].delay);
1981 if (lcdp->open_flow.func[i].delay != 0)
1982 disp_delay_ms(lcdp->open_flow.func[i].delay);
1983 }
1984 }
1985
1986 spin_lock_irqsave(&lcd_data_lock, flags);
1987 lcdp->enabled = 1;
1988 lcdp->enabling = 0;
1989 spin_unlock_irqrestore(&lcd_data_lock, flags);
1990
1991 return 0;
1992 }
1993
disp_lcd_disable(struct disp_device * lcd)1994 static s32 disp_lcd_disable(struct disp_device *lcd)
1995 {
1996 unsigned long flags;
1997 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
1998 struct disp_manager *mgr = NULL;
1999 int i;
2000
2001 if ((lcd == NULL) || (lcdp == NULL)) {
2002 DE_WRN("NULL hdl!\n");
2003 return DIS_FAIL;
2004 }
2005 DE_INF("lcd %d\n", lcd->disp);
2006 mgr = lcd->manager;
2007 if (mgr == NULL) {
2008 DE_WRN("mgr is NULL!\n");
2009 return DIS_FAIL;
2010 }
2011 if (disp_lcd_is_enabled(lcd) == 0)
2012 return 0;
2013
2014 spin_lock_irqsave(&lcd_data_lock, flags);
2015 lcdp->enabled = 0;
2016 spin_unlock_irqrestore(&lcd_data_lock, flags);
2017
2018 lcdp->bl_need_enabled = 0;
2019 lcdp->close_flow.func_num = 0;
2020 if (lcdp->lcd_panel_fun.cfg_close_flow)
2021 lcdp->lcd_panel_fun.cfg_close_flow(lcd->disp);
2022 else
2023 DE_WRN("lcd_panel_fun[%d].cfg_close_flow is NULL\n", lcd->disp);
2024
2025 for (i = 0; i < lcdp->close_flow.func_num; i++) {
2026 if (lcdp->close_flow.func[i].func) {
2027 lcdp->close_flow.func[i].func(lcd->disp);
2028 DE_INF("close flow:step %d finish, to delay %d\n", i,
2029 lcdp->close_flow.func[i].delay);
2030 if (lcdp->close_flow.func[i].delay != 0)
2031 disp_delay_ms(lcdp->close_flow.func[i].delay);
2032 }
2033 }
2034
2035 lcd_clk_disable(lcd);
2036 disp_lcd_gpio_exit(lcd);
2037
2038 disp_sys_disable_irq(lcdp->irq_no);
2039 disp_sys_unregister_irq(lcdp->irq_no, disp_lcd_event_proc, (void *)lcd);
2040
2041 return 0;
2042 }
2043
2044 #else
disp_lcd_enable(struct disp_device * lcd)2045 static s32 disp_lcd_enable(struct disp_device *lcd)
2046 {
2047 unsigned long flags;
2048 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2049 int i;
2050 struct disp_manager *mgr = NULL;
2051 unsigned bl;
2052 int ret = 0;
2053
2054 if ((lcd == NULL) || (lcdp == NULL)) {
2055 DE_WRN("NULL hdl!\n");
2056 return DIS_FAIL;
2057 }
2058
2059 if (!disp_lcd_is_used(lcd)) {
2060 return ret;
2061 }
2062
2063 __inf("lcd %d\n", lcd->disp);
2064 mgr = lcd->manager;
2065 if (mgr == NULL) {
2066 DE_WRN("mgr is NULL!\n");
2067 return DIS_FAIL;
2068 }
2069 if (disp_lcd_is_enabled(lcd) == 1)
2070 return 0;
2071
2072 disp_lcd_cal_fps(lcd);
2073 if (mgr->enable)
2074 mgr->enable(mgr);
2075
2076 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
2077 if ((lcdp->panel_info.lcd_if == LCD_IF_DSI)
2078 && (lcdp->irq_no_dsi != 0)) {
2079 if (lcdp->panel_info.lcd_dsi_if == LCD_DSI_IF_COMMAND_MODE) {
2080 disp_sys_register_irq(lcdp->irq_no, 0, disp_lcd_event_proc,
2081 (void *)lcd, 0, 0);
2082 disp_sys_enable_irq(lcdp->irq_no);
2083 } else {
2084 disp_sys_register_irq(lcdp->irq_no_dsi, 0, disp_lcd_event_proc,
2085 (void *)lcd, 0, 0);
2086 disp_sys_enable_irq(lcdp->irq_no_dsi);
2087 }
2088 } else
2089 #endif
2090 {
2091 disp_sys_register_irq(lcdp->irq_no, 0, disp_lcd_event_proc,
2092 (void *)lcd, 0, 0);
2093 disp_sys_enable_irq(lcdp->irq_no);
2094 }
2095 spin_lock_irqsave(&lcd_data_lock, flags);
2096 lcdp->enabling = 1;
2097 lcdp->bl_need_enabled = 0;
2098 spin_unlock_irqrestore(&lcd_data_lock, flags);
2099
2100 lcdp->panel_extend_info.lcd_gamma_en = lcdp->panel_info.lcd_gamma_en;
2101 disp_lcd_gpio_init(lcd);
2102 ret = lcd_clk_enable(lcd);
2103 if (ret != 0)
2104 return DIS_FAIL;
2105 ret = cal_real_frame_period(lcd);
2106 if (ret)
2107 DE_WRN("cal_real_frame_period fail:%d\n", ret);
2108
2109 if (lcdp->panel_info.lcd_pwm_used && !lcdp->pwm_info.dev)
2110 lcdp->pwm_info.dev =
2111 disp_sys_pwm_request(lcdp->panel_info.lcd_pwm_ch);
2112
2113 disp_sys_pwm_config(lcdp->pwm_info.dev, lcdp->pwm_info.duty_ns,
2114 lcdp->pwm_info.period_ns);
2115 disp_sys_pwm_set_polarity(lcdp->pwm_info.dev, lcdp->pwm_info.polarity);
2116 disp_al_lcd_cfg(lcd->hwdev_index, &lcdp->panel_info,
2117 &lcdp->panel_extend_info_set);
2118 lcd_calc_judge_line(lcd);
2119 lcdp->open_flow.func_num = 0;
2120 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
2121 if (lcdp->lcd_panel_fun.set_esd_info) {
2122 lcdp->lcd_panel_fun.set_esd_info(&lcdp->esd_inf);
2123 } else {
2124 /*default value*/
2125 lcdp->esd_inf.level = 0;
2126 lcdp->esd_inf.freq = 60;
2127 lcdp->esd_inf.esd_check_func_pos = 0;
2128 lcdp->esd_inf.cnt = 0;
2129 }
2130 #endif
2131 if (lcdp->lcd_panel_fun.cfg_open_flow)
2132 lcdp->lcd_panel_fun.cfg_open_flow(lcd->disp);
2133 else
2134 DE_WRN("lcd_panel_fun[%d].cfg_open_flow is NULL\n", lcd->disp);
2135
2136 if (lcdp->panel_info.lcd_gsensor_detect == 0)
2137 skip_open_backlight = 0;
2138
2139 for (i = 0; i < lcdp->open_flow.func_num - skip_open_backlight; i++) {
2140 if (lcdp->open_flow.func[i].func) {
2141 lcdp->open_flow.func[i].func(lcd->disp);
2142 DE_INF("open flow:step %d finish, to delay %d\n", i,
2143 lcdp->open_flow.func[i].delay);
2144 if (lcdp->open_flow.func[i].delay != 0)
2145 disp_delay_ms(lcdp->open_flow.func[i].delay);
2146 }
2147 }
2148 skip_open_backlight = 0; /*only skip one time*/
2149
2150 spin_lock_irqsave(&lcd_data_lock, flags);
2151 lcdp->enabled = 1;
2152 lcdp->enabling = 0;
2153 spin_unlock_irqrestore(&lcd_data_lock, flags);
2154 bl = disp_lcd_get_bright(lcd);
2155 disp_lcd_set_bright(lcd, bl);
2156 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
2157 atomic_set(&lcdp->lcd_resetting, 0);
2158 #endif
2159
2160 return 0;
2161 }
2162
disp_lcd_disable(struct disp_device * lcd)2163 static s32 disp_lcd_disable(struct disp_device *lcd)
2164 {
2165 unsigned long flags;
2166 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2167 struct disp_manager *mgr = NULL;
2168 int i;
2169
2170 if ((lcd == NULL) || (lcdp == NULL)) {
2171 DE_WRN("NULL hdl!\n");
2172 return DIS_FAIL;
2173 }
2174 DE_INF("lcd %d\n", lcd->disp);
2175 mgr = lcd->manager;
2176 if (mgr == NULL) {
2177 DE_WRN("mgr is NULL!\n");
2178 return DIS_FAIL;
2179 }
2180 if (disp_lcd_is_enabled(lcd) == 0)
2181 return 0;
2182
2183 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
2184 atomic_set(&lcdp->lcd_resetting, 2);
2185 #endif
2186 spin_lock_irqsave(&lcd_data_lock, flags);
2187 lcdp->enabled = 0;
2188 spin_unlock_irqrestore(&lcd_data_lock, flags);
2189
2190 lcdp->bl_need_enabled = 0;
2191 lcdp->close_flow.func_num = 0;
2192 if (lcdp->lcd_panel_fun.cfg_close_flow)
2193 lcdp->lcd_panel_fun.cfg_close_flow(lcd->disp);
2194 else
2195 DE_WRN("lcd_panel_fun[%d].cfg_close_flow is NULL\n", lcd->disp);
2196
2197 for (i = 0; i < lcdp->close_flow.func_num; i++) {
2198 if (lcdp->close_flow.func[i].func) {
2199 lcdp->close_flow.func[i].func(lcd->disp);
2200 DE_INF("close flow:step %d finish, to delay %d\n", i,
2201 lcdp->close_flow.func[i].delay);
2202 if (lcdp->close_flow.func[i].delay != 0)
2203 disp_delay_ms(lcdp->close_flow.func[i].delay);
2204 }
2205 }
2206
2207 disp_lcd_gpio_exit(lcd);
2208
2209 lcd_clk_disable(lcd);
2210 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
2211 if ((lcdp->panel_info.lcd_if == LCD_IF_DSI) &&
2212 (lcdp->irq_no_dsi != 0)) {
2213 if (lcdp->panel_info.lcd_dsi_if == LCD_DSI_IF_COMMAND_MODE) {
2214 disp_sys_disable_irq(lcdp->irq_no);
2215 disp_sys_unregister_irq(
2216 lcdp->irq_no, disp_lcd_event_proc, (void *)lcd);
2217 } else {
2218 disp_sys_disable_irq(lcdp->irq_no_dsi);
2219 disp_sys_unregister_irq(
2220 lcdp->irq_no_dsi, disp_lcd_event_proc, (void *)lcd);
2221 }
2222 } else
2223 #endif
2224 {
2225 disp_sys_disable_irq(lcdp->irq_no);
2226 disp_sys_unregister_irq(lcdp->irq_no, disp_lcd_event_proc,
2227 (void *)lcd);
2228 }
2229
2230 if (mgr->disable)
2231 mgr->disable(mgr);
2232
2233 return 0;
2234 }
2235 #endif
disp_lcd_sw_enable(struct disp_device * lcd)2236 static s32 disp_lcd_sw_enable(struct disp_device *lcd)
2237 {
2238 unsigned long flags;
2239 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2240 int i, ret;
2241 struct disp_manager *mgr = NULL;
2242
2243 if ((lcd == NULL) || (lcdp == NULL)) {
2244 DE_WRN("NULL hdl!\n");
2245 return DIS_FAIL;
2246 }
2247
2248 mgr = lcd->manager;
2249 if (mgr == NULL) {
2250 DE_WRN("mgr is NULL!\n");
2251 return DIS_FAIL;
2252 }
2253 disp_lcd_cal_fps(lcd);
2254 lcd_calc_judge_line(lcd);
2255 if (mgr->sw_enable)
2256 mgr->sw_enable(mgr);
2257
2258 #if !defined(CONFIG_COMMON_CLK_ENABLE_SYNCBOOT)
2259 if (lcd_clk_enable(lcd) != 0)
2260 return DIS_FAIL;
2261 #endif
2262 ret = cal_real_frame_period(lcd);
2263 if (ret)
2264 DE_WRN("cal_real_frame_period fail:%d\n", ret);
2265
2266 /* init lcd power */
2267 for (i = 0; i < LCD_POWER_NUM; i++) {
2268 ret = disp_sys_power_enable(lcdp->lcd_cfg.regulator[i]);
2269 if (ret)
2270 return DIS_FAIL;
2271 }
2272
2273 /* init gpio */
2274 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
2275 ret = disp_sys_power_enable(lcdp->lcd_cfg.gpio_regulator[i]);
2276 if (ret)
2277 return DIS_FAIL;
2278 }
2279
2280 /* init lcd pin */
2281 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
2282 ret = disp_sys_power_enable(lcdp->lcd_cfg.pin_regulator[i]);
2283 if (ret)
2284 return DIS_FAIL;
2285 }
2286
2287 /* init bl */
2288 if (lcdp->lcd_cfg.lcd_bl_en_used) {
2289 ret = disp_sys_power_enable(lcdp->lcd_cfg.bl_regulator);
2290 if (ret)
2291 return DIS_FAIL;
2292 disp_sys_gpio_request(&lcdp->lcd_cfg.lcd_bl_en);
2293 }
2294
2295 if (lcdp->panel_info.lcd_pwm_used) {
2296 if (!lcdp->pwm_info.dev) {
2297 lcdp->pwm_info.dev = disp_sys_pwm_request(
2298 lcdp->panel_info.lcd_pwm_ch);
2299 }
2300 if (lcdp->pwm_info.dev) {
2301 disp_sys_pwm_config(lcdp->pwm_info.dev,
2302 lcdp->pwm_info.duty_ns,
2303 lcdp->pwm_info.period_ns);
2304 disp_sys_pwm_set_polarity(lcdp->pwm_info.dev,
2305 lcdp->pwm_info.polarity);
2306 disp_sys_pwm_enable(lcdp->pwm_info.dev);
2307 }
2308 }
2309
2310 spin_lock_irqsave(&lcd_data_lock, flags);
2311 lcdp->enabled = 1;
2312 lcdp->enabling = 0;
2313 lcdp->bl_need_enabled = 1;
2314 lcdp->bl_enabled = true;
2315 spin_unlock_irqrestore(&lcd_data_lock, flags);
2316
2317 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
2318 if (lcdp->lcd_panel_fun.set_esd_info) {
2319 lcdp->lcd_panel_fun.set_esd_info(&lcdp->esd_inf);
2320 } else {
2321 /*default value*/
2322 lcdp->esd_inf.level = 0;
2323 lcdp->esd_inf.freq = 60;
2324 lcdp->esd_inf.esd_check_func_pos = 0;
2325 lcdp->esd_inf.cnt = 0;
2326 }
2327 #endif
2328 disp_al_lcd_disable_irq(lcd->hwdev_index, LCD_IRQ_TCON0_VBLK,
2329 &lcdp->panel_info);
2330 #if defined(SUPPORT_DSI) && defined(DSI_VERSION_40)
2331 if ((lcdp->panel_info.lcd_if == LCD_IF_DSI) &&
2332 (lcdp->irq_no_dsi != 0)) {
2333 if (lcdp->panel_info.lcd_dsi_if == LCD_DSI_IF_COMMAND_MODE) {
2334 disp_sys_register_irq(lcdp->irq_no, 0,
2335 disp_lcd_event_proc, (void *)lcd,
2336 0, 0);
2337 disp_sys_enable_irq(lcdp->irq_no);
2338 } else {
2339 disp_sys_register_irq(lcdp->irq_no_dsi, 0,
2340 disp_lcd_event_proc, (void *)lcd,
2341 0, 0);
2342 disp_sys_enable_irq(lcdp->irq_no_dsi);
2343 }
2344 } else
2345 #endif
2346 {
2347 disp_sys_register_irq(lcdp->irq_no, 0, disp_lcd_event_proc,
2348 (void *)lcd, 0, 0);
2349 disp_sys_enable_irq(lcdp->irq_no);
2350 }
2351 disp_al_lcd_enable_irq(lcd->hwdev_index, LCD_IRQ_TCON0_VBLK,
2352 &lcdp->panel_info);
2353
2354 return 0;
2355 }
2356
disp_lcd_is_enabled(struct disp_device * lcd)2357 s32 disp_lcd_is_enabled(struct disp_device *lcd)
2358 {
2359 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2360
2361 if ((lcd == NULL) || (lcdp == NULL)) {
2362 DE_WRN("NULL hdl!\n");
2363 return DIS_FAIL;
2364 }
2365
2366 return (s32)lcdp->enabled;
2367 }
2368
2369 /**
2370 * disp_lcd_check_if_enabled - check lcd if be enabled status
2371 *
2372 * this function only be used by bsp_disp_sync_with_hw to check
2373 * the device enabled status when driver init
2374 */
disp_lcd_check_if_enabled(struct disp_device * lcd)2375 s32 disp_lcd_check_if_enabled(struct disp_device *lcd)
2376 {
2377 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2378 int ret = 1;
2379
2380 if ((lcd == NULL) || (lcdp == NULL)) {
2381 DE_WRN("NULL hdl!\n");
2382 return DIS_FAIL;
2383 }
2384
2385 #if !defined(CONFIG_COMMON_CLK_ENABLE_SYNCBOOT)
2386 if (lcdp->clk_tcon_lcd &&
2387 (__clk_is_enabled(lcdp->clk_tcon_lcd) == 0))
2388 ret = 0;
2389 #endif
2390
2391 return ret;
2392 }
2393
disp_lcd_set_open_func(struct disp_device * lcd,LCD_FUNC func,u32 delay)2394 static s32 disp_lcd_set_open_func(struct disp_device *lcd, LCD_FUNC func,
2395 u32 delay)
2396 {
2397 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2398
2399 if ((lcd == NULL) || (lcdp == NULL)) {
2400 DE_WRN("NULL hdl!\n");
2401 return -1;
2402 }
2403
2404 if (func) {
2405 lcdp->open_flow.func[lcdp->open_flow.func_num].func = func;
2406 lcdp->open_flow.func[lcdp->open_flow.func_num].delay = delay;
2407 lcdp->open_flow.func_num++;
2408 }
2409
2410 return DIS_SUCCESS;
2411 }
2412
disp_lcd_set_close_func(struct disp_device * lcd,LCD_FUNC func,u32 delay)2413 static s32 disp_lcd_set_close_func(struct disp_device *lcd, LCD_FUNC func,
2414 u32 delay)
2415 {
2416 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2417
2418 if ((lcd == NULL) || (lcdp == NULL)) {
2419 DE_WRN("NULL hdl!\n");
2420 return -1;
2421 }
2422
2423 if (func) {
2424 lcdp->close_flow.func[lcdp->close_flow.func_num].func = func;
2425 lcdp->close_flow.func[lcdp->close_flow.func_num].delay = delay;
2426 lcdp->close_flow.func_num++;
2427 }
2428
2429 return DIS_SUCCESS;
2430 }
2431
disp_lcd_set_panel_funs(struct disp_device * lcd,char * name,struct disp_lcd_panel_fun * lcd_cfg)2432 static s32 disp_lcd_set_panel_funs(struct disp_device *lcd, char *name,
2433 struct disp_lcd_panel_fun *lcd_cfg)
2434 {
2435 s32 ret = -1;
2436 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2437
2438 if ((lcd == NULL) || (lcdp == NULL)) {
2439 DE_WRN("NULL hdl!\n");
2440 return DIS_FAIL;
2441 }
2442
2443
2444 DE_INF("lcd %d, driver_name %s, panel_name %s\n", lcd->disp, lcdp->panel_info.lcd_driver_name,
2445 name);
2446 if (!strcmp(lcdp->panel_info.lcd_driver_name, name)) {
2447 memset(&lcdp->lcd_panel_fun,
2448 0,
2449 sizeof(struct disp_lcd_panel_fun));
2450 lcdp->lcd_panel_fun.cfg_panel_info = lcd_cfg->cfg_panel_info;
2451 lcdp->lcd_panel_fun.cfg_open_flow = lcd_cfg->cfg_open_flow;
2452 lcdp->lcd_panel_fun.cfg_close_flow = lcd_cfg->cfg_close_flow;
2453 lcdp->lcd_panel_fun.esd_check = lcd_cfg->esd_check;
2454 lcdp->lcd_panel_fun.reset_panel = lcd_cfg->reset_panel;
2455 lcdp->lcd_panel_fun.set_esd_info = lcd_cfg->set_esd_info;
2456 lcdp->lcd_panel_fun.lcd_user_defined_func =
2457 lcd_cfg->lcd_user_defined_func;
2458 lcdp->lcd_panel_fun.set_bright = lcd_cfg->set_bright;
2459 if (lcdp->lcd_panel_fun.cfg_panel_info) {
2460 lcdp->lcd_panel_fun.cfg_panel_info(&lcdp->panel_extend_info);
2461 memcpy(&lcdp->panel_extend_info_set,
2462 &lcdp->panel_extend_info, sizeof(struct panel_extend_para));
2463 } else {
2464 DE_WRN("lcd_panel_fun[%d].cfg_panel_info is NULL\n", lcd->disp);
2465 }
2466
2467 ret = 0;
2468 }
2469
2470 return ret;
2471 }
2472
disp_lcd_gpio_init(struct disp_device * lcd)2473 s32 disp_lcd_gpio_init(struct disp_device *lcd)
2474 {
2475 int ret;
2476 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2477 int i = 0;
2478
2479 if ((lcd == NULL) || (lcdp == NULL)) {
2480 DE_WRN("NULL hdl!\n");
2481 return DIS_FAIL;
2482 }
2483
2484 /* io-pad */
2485 for (i = 0; i < LCD_GPIO_REGU_NUM; i++) {
2486 ret = disp_sys_power_enable(lcdp->lcd_cfg.gpio_regulator[i]);
2487 if (ret)
2488 return DIS_FAIL;
2489 }
2490
2491
2492 return 0;
2493 }
2494
disp_lcd_gpio_exit(struct disp_device * lcd)2495 s32 disp_lcd_gpio_exit(struct disp_device *lcd)
2496 {
2497 int ret;
2498 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2499 int i = 0;
2500
2501 if ((lcd == NULL) || (lcdp == NULL)) {
2502 DE_WRN("NULL hdl!\n");
2503 return DIS_FAIL;
2504 }
2505
2506
2507 /* io-pad */
2508 for (i = LCD_GPIO_REGU_NUM - 1; i >= 0; i--) {
2509 ret = disp_sys_power_disable(lcdp->lcd_cfg.gpio_regulator[i]);
2510 if (ret)
2511 return DIS_FAIL;
2512 }
2513
2514 return DIS_SUCCESS;
2515 }
2516
2517 /* direction: input(0), output(1) */
disp_lcd_gpio_set_direction(struct disp_device * lcd,u32 io_index,u32 direction)2518 s32 disp_lcd_gpio_set_direction(struct disp_device *lcd, u32 io_index,
2519 u32 direction)
2520 {
2521 int gpio, value, ret;
2522 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2523 char gpio_name[20];
2524 struct device_node *node = g_disp_drv.node;
2525
2526 if ((lcd == NULL) || (lcdp == NULL)) {
2527 DE_WRN("NULL hdl!\n");
2528 return DIS_FAIL;
2529 }
2530
2531 sprintf(gpio_name, "lcd_gpio_%d", io_index);
2532
2533 gpio = of_get_named_gpio(node, gpio_name, 0);
2534 if (!gpio_is_valid(gpio)) {
2535 DE_WRN("of_get_named_gpio_flags for %s failed\n", gpio_name);
2536 return DIS_FAIL;
2537 }
2538
2539 if (direction) {
2540 value = __gpio_get_value(gpio);
2541 ret = gpio_direction_output(gpio, value);
2542 if (ret) {
2543 DE_WRN("gpio_direction_output for %s failed\n", gpio_name);
2544 return DIS_FAIL;
2545 }
2546 } else {
2547 ret = gpio_direction_input(gpio);
2548 if (ret) {
2549 DE_WRN("gpio_direction_input for %s failed\n", gpio_name);
2550 return DIS_FAIL;
2551 }
2552 }
2553
2554 return DIS_SUCCESS;
2555 }
2556
disp_lcd_gpio_get_value(struct disp_device * lcd,u32 io_index)2557 s32 disp_lcd_gpio_get_value(struct disp_device *lcd, u32 io_index)
2558 {
2559 int gpio;
2560 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2561 char gpio_name[20];
2562 struct device_node *node = g_disp_drv.node;
2563
2564 if ((lcd == NULL) || (lcdp == NULL)) {
2565 DE_WRN("NULL hdl!\n");
2566 return DIS_FAIL;
2567 }
2568
2569 sprintf(gpio_name, "lcd_gpio_%d", io_index);
2570
2571 gpio = of_get_named_gpio(node, gpio_name, 0);
2572 if (!gpio_is_valid(gpio)) {
2573 DE_WRN("of_get_named_gpio_flags for %s failed\n", gpio_name);
2574 return DIS_FAIL;
2575 }
2576
2577 return __gpio_get_value(gpio);
2578 }
2579
disp_lcd_gpio_set_value(struct disp_device * lcd,u32 io_index,u32 data)2580 s32 disp_lcd_gpio_set_value(struct disp_device *lcd, u32 io_index, u32 data)
2581 {
2582 int gpio;
2583 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2584 char gpio_name[20];
2585
2586 if ((lcd == NULL) || (lcdp == NULL)) {
2587 DE_WRN("NULL hdl!\n");
2588 return DIS_FAIL;
2589 }
2590
2591 if (io_index >= LCD_GPIO_NUM) {
2592 DE_WRN("gpio num out of range\n");
2593 return DIS_FAIL;
2594 }
2595 sprintf(gpio_name, "lcd_gpio_%d", io_index);
2596
2597 gpio = lcdp->lcd_cfg.lcd_gpio[io_index].gpio;
2598 if (!gpio_is_valid(gpio)) {
2599 DE_WRN("of_get_named_gpio_flags for %s failed\n", gpio_name);
2600 return DIS_FAIL;
2601 }
2602
2603 __gpio_set_value(gpio, data);
2604
2605 return DIS_SUCCESS;
2606 }
2607
disp_lcd_get_dimensions(struct disp_device * lcd,u32 * width,u32 * height)2608 static s32 disp_lcd_get_dimensions(struct disp_device *lcd, u32 *width,
2609 u32 *height)
2610 {
2611 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2612
2613 if ((lcd == NULL) || (lcdp == NULL)) {
2614 DE_WRN("NULL hdl!\n");
2615 return DIS_FAIL;
2616 }
2617
2618 *width = lcdp->panel_info.lcd_width;
2619 *height = lcdp->panel_info.lcd_height;
2620 return 0;
2621 }
2622
disp_lcd_get_status(struct disp_device * lcd)2623 static s32 disp_lcd_get_status(struct disp_device *lcd)
2624 {
2625 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2626
2627 if ((lcd == NULL) || (lcdp == NULL)) {
2628 DE_WRN("NULL hdl!\n");
2629 return 0;
2630 }
2631
2632 return disp_al_lcd_get_status(lcd->hwdev_index, &lcdp->panel_info);
2633 }
2634
disp_lcd_is_in_safe_period(struct disp_device * lcd)2635 static bool disp_lcd_is_in_safe_period(struct disp_device *lcd)
2636 {
2637 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2638 int start_delay;
2639 int cur_line;
2640 bool ret = true;
2641
2642 if ((lcd == NULL) || (lcdp == NULL)) {
2643 DE_WRN("NULL hdl!\n");
2644 goto exit;
2645 }
2646
2647 start_delay =
2648 disp_al_lcd_get_start_delay(lcd->hwdev_index, &lcdp->panel_info);
2649 cur_line =
2650 disp_al_lcd_get_cur_line(lcd->hwdev_index, &lcdp->panel_info);
2651 if (cur_line >= start_delay)
2652 ret = false;
2653
2654 exit:
2655 return ret;
2656 }
2657
disp_lcd_update_gamma_tbl_set(struct disp_device * lcd)2658 static s32 disp_lcd_update_gamma_tbl_set(struct disp_device *lcd)
2659 {
2660 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2661 int i;
2662 unsigned int *gamma, *gamma_set;
2663 unsigned int r, g, b;
2664 s32 color_temperature;
2665 u32 color_inverse;
2666
2667 color_temperature = lcdp->color_temperature;
2668 color_inverse = lcdp->color_inverse;
2669 memcpy(&lcdp->panel_extend_info_set, &lcdp->panel_extend_info,
2670 sizeof(struct panel_extend_para));
2671 gamma = lcdp->panel_extend_info.lcd_gamma_tbl;
2672 gamma_set = lcdp->panel_extend_info_set.lcd_gamma_tbl;
2673 if (color_temperature > 0) {
2674 /* warm color */
2675 for (i = 0; i < 256; i++) {
2676 r = (gamma[i] >> 16) & 0xff;
2677 g = (gamma[i] >> 8) & 0xff;
2678 b = gamma[i] & 0xff;
2679
2680 g = g * (512 - color_temperature) / 512;
2681 b = b * (256 - color_temperature) / 256;
2682 r = r << 16;
2683
2684 g = g << 8;
2685 gamma_set[i] = r | g | b;
2686 }
2687 } else if (color_temperature < 0) {
2688 /* cool color */
2689 for (i = 0; i < 256; i++) {
2690 r = (gamma[i] >> 16) & 0xff;
2691 g = (gamma[i] >> 8) & 0xff;
2692 b = gamma[i] & 0xff;
2693
2694 r = r * (256 + color_temperature) / 256;
2695 g = g * (512 + color_temperature) / 512;
2696
2697 r = r << 16;
2698 g = g << 8;
2699
2700 gamma_set[i] = r | g | b;
2701 }
2702 }
2703 if (color_inverse == 1) {
2704 for (i = 0; i < 256; i++)
2705 gamma_set[i] = 0xffffffff - gamma_set[i];
2706 }
2707 if (color_inverse != 0)
2708 lcdp->panel_extend_info_set.lcd_gamma_en = 1;
2709 if (color_temperature != 0)
2710 lcdp->panel_extend_info_set.lcd_gamma_en = 1;
2711
2712 return 0;
2713 }
2714
2715
disp_lcd_set_gamma_tbl(struct disp_device * lcd,unsigned int * gamma_table,unsigned int size)2716 static s32 disp_lcd_set_gamma_tbl(struct disp_device *lcd,
2717 unsigned int *gamma_table, unsigned int size)
2718 {
2719 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2720 unsigned long flags;
2721
2722 if ((lcd == NULL) || (lcdp == NULL)
2723 || (gamma_table == NULL)) {
2724 DE_WRN("NULL hdl!\n");
2725 return 0;
2726 }
2727
2728 size = (size > LCD_GAMMA_TABLE_SIZE) ?
2729 LCD_GAMMA_TABLE_SIZE : size;
2730 spin_lock_irqsave(&lcd_data_lock, flags);
2731 memcpy(lcdp->panel_extend_info.lcd_gamma_tbl, gamma_table, size);
2732 disp_lcd_update_gamma_tbl_set(lcd);
2733 lcdp->panel_extend_dirty = 1;
2734 spin_unlock_irqrestore(&lcd_data_lock, flags);
2735
2736 return 0;
2737 }
2738
disp_lcd_enable_gamma(struct disp_device * lcd)2739 static s32 disp_lcd_enable_gamma(struct disp_device *lcd)
2740 {
2741 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2742 unsigned long flags;
2743
2744 if ((lcd == NULL) || (lcdp == NULL)) {
2745 DE_WRN("NULL hdl!\n");
2746 return 0;
2747 }
2748
2749 spin_lock_irqsave(&lcd_data_lock, flags);
2750 if (lcdp->panel_extend_info.lcd_gamma_en == 0) {
2751 lcdp->panel_extend_info.lcd_gamma_en = 1;
2752 disp_lcd_update_gamma_tbl_set(lcd);
2753 lcdp->panel_extend_dirty = 1;
2754 }
2755 spin_unlock_irqrestore(&lcd_data_lock, flags);
2756
2757 return 0;
2758 }
2759
disp_lcd_disable_gamma(struct disp_device * lcd)2760 static s32 disp_lcd_disable_gamma(struct disp_device *lcd)
2761 {
2762 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2763 int ret;
2764
2765 if ((lcd == NULL) || (lcdp == NULL)) {
2766 DE_WRN("NULL hdl!\n");
2767 return 0;
2768 }
2769
2770 if (lcdp->panel_extend_info.lcd_gamma_en == 1) {
2771 lcdp->panel_extend_info.lcd_gamma_en = 0;
2772 ret = disp_al_lcd_cfg_ext(lcd->disp,
2773 &lcdp->panel_extend_info);
2774 } else {
2775 ret = 0;
2776 }
2777
2778 return ret;
2779 }
2780
disp_lcd_get_fps(struct disp_device * lcd)2781 static s32 disp_lcd_get_fps(struct disp_device *lcd)
2782 {
2783 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2784
2785 if ((lcd == NULL) || (lcdp == NULL)) {
2786 DE_WRN("NULL hdl!\n");
2787 return 0;
2788 }
2789
2790 return lcdp->frame_per_sec;
2791 }
2792
disp_lcd_set_color_temperature(struct disp_device * lcd,s32 color_temperature)2793 static s32 disp_lcd_set_color_temperature(struct disp_device *lcd,
2794 s32 color_temperature)
2795 {
2796 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2797 unsigned long flags;
2798
2799 if ((NULL == lcd) || (NULL == lcdp)) {
2800 DE_WRN("NULL hdl!\n");
2801 return -1;
2802 }
2803
2804 spin_lock_irqsave(&lcd_data_lock, flags);
2805 lcdp->color_temperature = color_temperature;
2806 disp_lcd_update_gamma_tbl_set(lcd);
2807 lcdp->panel_extend_dirty = 1;
2808 spin_unlock_irqrestore(&lcd_data_lock, flags);
2809
2810 return 0;
2811 }
2812
disp_lcd_get_color_temperature(struct disp_device * lcd)2813 static s32 disp_lcd_get_color_temperature(struct disp_device *lcd)
2814 {
2815 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2816 unsigned long flags;
2817 s32 color_temperature = 0;
2818
2819 if ((NULL == lcd) || (NULL == lcdp)) {
2820 DE_WRN("NULL hdl!\n");
2821 return 0;
2822 }
2823
2824 spin_lock_irqsave(&lcd_data_lock, flags);
2825 color_temperature = lcdp->color_temperature;
2826 spin_unlock_irqrestore(&lcd_data_lock, flags);
2827
2828 return color_temperature;
2829 }
2830
disp_lcd_init(struct disp_device * lcd,int lcd_index)2831 static s32 disp_lcd_init(struct disp_device *lcd, int lcd_index)
2832 {
2833 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2834 struct disp_gpio_info gpio_info;
2835 int i;
2836
2837 if ((lcd == NULL) || (lcdp == NULL)) {
2838 DE_WRN("NULL hdl!\n");
2839 return DIS_FAIL;
2840 }
2841
2842 lcd_get_sys_config(lcd_index, &lcdp->lcd_cfg);
2843
2844 lcd_regulator_get_wrap(&lcdp->lcd_cfg);
2845
2846 if (disp_lcd_is_used(lcd)) {
2847 struct disp_video_timings *timmings;
2848 struct disp_panel_para *panel_info;
2849
2850 lcd_parse_panel_para(lcd_index, &lcdp->panel_info);
2851 lcdp->panel_extend_info.lcd_cmap_en = lcdp->panel_info.lcd_cmap_en;
2852 lcdp->panel_extend_info.lcd_gamma_en = lcdp->panel_info.lcd_gamma_en;
2853 if (lcdp->panel_extend_info.lcd_gamma_en ||
2854 lcdp->panel_extend_info.lcd_cmap_en)
2855 lcdp->panel_extend_dirty = 1;
2856 if (lcdp->panel_info.lcd_if == LCD_IF_DSI &&
2857 lcdp->panel_info.lcd_tcon_mode == DISP_TCON_DUAL_DSI &&
2858 lcdp->panel_info.lcd_dsi_port_num ==
2859 DISP_LCD_DSI_SINGLE_PORT) {
2860 lcdp->panel_info.lcd_ht *= 2;
2861 lcdp->panel_info.lcd_hspw *= 2;
2862 lcdp->panel_info.lcd_x *= 2;
2863 lcdp->panel_info.lcd_hbp *= 2;
2864 lcdp->panel_info.lcd_dclk_freq *= 2;
2865 }
2866 timmings = &lcd->timings;
2867 panel_info = &lcdp->panel_info;
2868 timmings->pixel_clk = panel_info->lcd_dclk_freq * 1000;
2869 timmings->x_res = panel_info->lcd_x;
2870 timmings->y_res = panel_info->lcd_y;
2871 timmings->hor_total_time = panel_info->lcd_ht;
2872 timmings->hor_sync_time = panel_info->lcd_hspw;
2873 timmings->hor_back_porch =
2874 panel_info->lcd_hbp - panel_info->lcd_hspw;
2875 timmings->hor_front_porch =
2876 panel_info->lcd_ht - panel_info->lcd_hbp -
2877 panel_info->lcd_x;
2878 timmings->ver_total_time = panel_info->lcd_vt;
2879 timmings->ver_sync_time = panel_info->lcd_vspw;
2880 timmings->ver_back_porch =
2881 panel_info->lcd_vbp - panel_info->lcd_vspw;
2882 timmings->ver_front_porch =
2883 panel_info->lcd_vt - panel_info->lcd_vbp -
2884 panel_info->lcd_y;
2885 }
2886 disp_lcd_bright_curve_init(lcd);
2887
2888 if (disp_lcd_is_used(lcd)) {
2889 __u64 backlight_bright;
2890 __u64 period_ns, duty_ns;
2891
2892 if (lcdp->panel_info.lcd_pwm_used) {
2893 lcdp->pwm_info.channel = lcdp->panel_info.lcd_pwm_ch;
2894 lcdp->pwm_info.polarity = lcdp->panel_info.lcd_pwm_pol;
2895 lcdp->pwm_info.dev = disp_sys_pwm_request(
2896 lcdp->panel_info.lcd_pwm_ch);
2897
2898 if (lcdp->panel_info.lcd_pwm_freq != 0) {
2899 period_ns =
2900 1000 * 1000 * 1000 /
2901 lcdp->panel_info.lcd_pwm_freq;
2902 } else {
2903 DE_WRN("lcd%d.lcd_pwm_freq is ZERO\n",
2904 lcd->disp);
2905 /* default 1khz */
2906 period_ns = 1000 * 1000 * 1000 / 1000;
2907 }
2908
2909 backlight_bright = lcdp->lcd_cfg.backlight_bright;
2910
2911 duty_ns = (backlight_bright * period_ns) / 256;
2912 lcdp->pwm_info.duty_ns = duty_ns;
2913 lcdp->pwm_info.period_ns = period_ns;
2914 disp_sys_pwm_config(lcdp->pwm_info.dev, duty_ns, period_ns);
2915 }
2916 lcd_clk_init(lcd);
2917 for (i = 0; i < 256; i++) {
2918 lcdp->panel_extend_info.lcd_gamma_tbl[i] =
2919 (i << 24) | (i << 16) | (i << 8) | (i);
2920 }
2921 for (i = 0; i < LCD_GPIO_NUM; i++) {
2922 if (!lcdp->lcd_cfg.lcd_gpio_used[i])
2923 continue;
2924
2925 memcpy(&gpio_info, &(lcdp->lcd_cfg.lcd_gpio[i]),
2926 sizeof(struct disp_gpio_info));
2927 disp_sys_gpio_request(&gpio_info);
2928 }
2929 }
2930
2931 /* lcd_panel_parameter_check(lcd->disp, lcd); */
2932 return 0;
2933 }
2934
2935 #if defined(SUPPORT_EINK) && defined(CONFIG_EINK_PANEL_USED)
disp_close_eink_panel_task(struct work_struct * work)2936 static void disp_close_eink_panel_task(struct work_struct *work)
2937 { /* (unsigned long parg) */
2938 struct disp_device *plcd = NULL;
2939
2940 plcd = disp_device_find(0, DISP_OUTPUT_TYPE_LCD);
2941 plcd->disable(plcd);
2942 display_finish_flag = 1;
2943 }
2944 #endif
2945
disp_lcd_check_config_dirty(struct disp_device * lcd,struct disp_device_config * config)2946 static disp_config_update_t disp_lcd_check_config_dirty(struct disp_device *lcd,
2947 struct disp_device_config *config)
2948 {
2949 disp_config_update_t ret = DISP_NOT_UPDATE;
2950 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
2951
2952 if ((lcd == NULL) || (lcdp == NULL)) {
2953 DE_WRN("NULL hdl!\n");
2954 goto exit;
2955 }
2956
2957 if (lcdp->enabled == 0 ||
2958 ((config->reserve1 & DISP_LCD_MODE_DIRTY_MASK) &&
2959 config->reserve1 != lcdp->config.reserve1))
2960 ret = DISP_NORMAL_UPDATE;
2961
2962 exit:
2963 return ret;
2964 }
2965
disp_lcd_set_static_config(struct disp_device * lcd,struct disp_device_config * config)2966 static s32 disp_lcd_set_static_config(struct disp_device *lcd,
2967 struct disp_device_config *config)
2968 {
2969 int ret = -1;
2970 struct disp_lcd_private_data *lcdp = NULL;
2971
2972 if (!lcd || !config) {
2973 DE_WRN("NULL hdl!\n");
2974 goto OUT;
2975 }
2976
2977 lcdp = disp_lcd_get_priv(lcd);
2978 if (!lcdp) {
2979 DE_WRN("NULL lcdp!\n");
2980 goto OUT;
2981 }
2982
2983 if ((config->reserve1 & DISP_LCD_MODE_DIRTY_MASK) &&
2984 config->reserve1 != lcdp->config.reserve1) {
2985 ret = disp_lcd_init(lcd, config->reserve1 & 0xf);
2986 lcd_set_panel_funs();
2987 lcdp->config.reserve1 = config->reserve1;
2988 } else
2989 ret = 0;
2990
2991 OUT:
2992 return ret;
2993 }
2994
disp_lcd_get_static_config(struct disp_device * lcd,struct disp_device_config * config)2995 static s32 disp_lcd_get_static_config(struct disp_device *lcd,
2996 struct disp_device_config *config)
2997 {
2998 int ret = 0;
2999 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
3000
3001 if ((lcd == NULL) || (lcdp == NULL)) {
3002 DE_WRN("NULL hdl!\n");
3003 ret = -1;
3004 goto exit;
3005 }
3006
3007 config->type = lcd->type;
3008 config->format = DISP_CSC_TYPE_RGB;
3009 exit:
3010 return ret;
3011 }
3012
disp_lcd_exit(struct disp_device * lcd)3013 static s32 disp_lcd_exit(struct disp_device *lcd)
3014 {
3015 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd);
3016 struct disp_gpio_info gpio_info;
3017 s32 i = 0;
3018
3019 if ((lcd == NULL) || (lcdp == NULL)) {
3020 DE_WRN("NULL hdl!\n");
3021 return DIS_FAIL;
3022 }
3023
3024 lcd_regulator_put_wrap(&lcdp->lcd_cfg);
3025
3026 for (i = 0; i < LCD_GPIO_NUM; i++) {
3027 memcpy(&gpio_info, &(lcdp->lcd_cfg.lcd_gpio[i]), sizeof(struct disp_gpio_info));
3028 gpio_info.value = 0;
3029 disp_sys_gpio_release(&gpio_info);
3030 }
3031 lcd_clk_exit(lcd);
3032
3033 return 0;
3034 }
3035
3036 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
disp_lcd_get_esd_info(struct disp_device * dispdev,struct disp_lcd_esd_info * p_esd_info)3037 static s32 disp_lcd_get_esd_info(struct disp_device *dispdev,
3038 struct disp_lcd_esd_info *p_esd_info)
3039 {
3040 s32 ret = -1;
3041 struct disp_lcd_private_data *lcdp = NULL;
3042
3043 if (!dispdev || !p_esd_info)
3044 goto OUT;
3045 lcdp = disp_lcd_get_priv(dispdev);
3046 if (!lcdp)
3047 goto OUT;
3048
3049 memcpy(p_esd_info, &lcdp->esd_inf, sizeof(struct disp_lcd_esd_info));
3050 ret = 0;
3051 OUT:
3052 return ret;
3053 }
3054 #endif
3055
disp_lcd_usec_before_vblank(struct disp_device * dispdev)3056 static u32 disp_lcd_usec_before_vblank(struct disp_device *dispdev)
3057 {
3058 int cur_line;
3059 int start_delay;
3060 u32 usec = 0;
3061 struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(dispdev);
3062
3063 if (!dispdev || !lcdp) {
3064 DE_WRN("NULL hdl!\n");
3065 goto exit;
3066 }
3067
3068 start_delay = disp_al_lcd_get_start_delay(dispdev->hwdev_index,
3069 &lcdp->panel_info);
3070 cur_line =
3071 disp_al_lcd_get_cur_line(dispdev->hwdev_index, &lcdp->panel_info);
3072 if (cur_line > (start_delay - lcdp->judge_line)) {
3073 usec =
3074 (lcdp->panel_info.lcd_vt - cur_line + 1) * lcdp->usec_per_line;
3075 }
3076
3077 exit:
3078 return usec;
3079 }
3080
disp_init_lcd(struct disp_bsp_init_para * para)3081 s32 disp_init_lcd(struct disp_bsp_init_para *para)
3082 {
3083 u32 num_devices;
3084 u32 disp = 0;
3085 struct disp_device *lcd;
3086 struct disp_lcd_private_data *lcdp;
3087 u32 hwdev_index = 0;
3088 u32 num_devices_support_lcd = 0;
3089 #if defined(SUPPORT_DSI)
3090 u32 i = 0, index_base;
3091 #endif
3092 #if defined(CONFIG_ARCH_SUN8IW17P1)
3093 char primary_key[20];
3094 int ret = 0, value = 1;
3095 s32 use_dsi_flag = 0;
3096 #endif
3097
3098 DE_INF("disp_init_lcd\n");
3099
3100 spin_lock_init(&lcd_data_lock);
3101 num_devices = bsp_disp_feat_get_num_devices();
3102 for (hwdev_index = 0; hwdev_index < num_devices; hwdev_index++) {
3103 if (bsp_disp_feat_is_supported_output_types
3104 (hwdev_index, DISP_OUTPUT_TYPE_LCD))
3105 num_devices_support_lcd++;
3106 }
3107 lcds =
3108 kmalloc_array(num_devices_support_lcd, sizeof(struct disp_device),
3109 GFP_KERNEL | __GFP_ZERO);
3110 if (lcds == NULL) {
3111 DE_WRN("malloc memory(%d bytes) fail!\n",
3112 (unsigned int)sizeof(struct disp_device) *
3113 num_devices_support_lcd);
3114 goto malloc_err;
3115 }
3116 lcd_private =
3117 (struct disp_lcd_private_data *)
3118 kmalloc(sizeof(struct disp_lcd_private_data)
3119 * num_devices_support_lcd, GFP_KERNEL | __GFP_ZERO);
3120 if (lcd_private == NULL) {
3121 DE_WRN("malloc memory(%d bytes) fail!\n",
3122 (unsigned int)sizeof(struct disp_lcd_private_data) *
3123 num_devices_support_lcd);
3124 goto malloc_err;
3125 }
3126
3127 disp = 0;
3128 for (hwdev_index = 0; hwdev_index < num_devices; hwdev_index++) {
3129 if (!bsp_disp_feat_is_supported_output_types
3130 (hwdev_index, DISP_OUTPUT_TYPE_LCD)) {
3131 continue;
3132 }
3133
3134 lcd = &lcds[disp];
3135 lcdp = &lcd_private[disp];
3136 lcd->priv_data = (void *)lcdp;
3137
3138 sprintf(lcd->name, "lcd%d", disp);
3139 lcd->disp = disp;
3140 #if defined(CONFIG_ARCH_SUN8IW17P1)
3141 value = 0;
3142 ret = disp_sys_script_get_item(primary_key, "lcd_if", &value,
3143 1);
3144 if (value == 4) {
3145 lcd->hwdev_index = 1;
3146 use_dsi_flag = 1;
3147 } else
3148 lcd->hwdev_index = (use_dsi_flag == 1) ? 0 : hwdev_index;
3149 #else
3150 lcd->hwdev_index = hwdev_index;
3151 #endif
3152 lcd->type = DISP_OUTPUT_TYPE_LCD;
3153 lcdp->irq_no = para->irq_no[DISP_MOD_LCD0 + lcd->hwdev_index];
3154 lcdp->clk_tcon_lcd = para->clk_tcon[lcd->hwdev_index];
3155 lcdp->clk_bus_tcon_lcd = para->clk_bus_tcon[lcd->hwdev_index];
3156 lcdp->clk_lvds = para->clk_tcon[lcd->hwdev_index];
3157 lcdp->rst_bus_tcon_lcd = para->rst_bus_tcon[lcd->hwdev_index];
3158 lcdp->rst_bus_lvds = para->rst_bus_lvds[lcd->hwdev_index];
3159 #if defined(SUPPORT_DSI)
3160 lcdp->irq_no_dsi = para->irq_no[DISP_MOD_DSI0 + disp];
3161
3162 index_base = CLK_NUM_PER_DSI * lcd->hwdev_index;
3163 for (i = 0; i < CLK_NUM_PER_DSI; i++) {
3164 lcdp->clk_mipi_dsi[i] = para->clk_mipi_dsi[index_base + i];
3165 lcdp->clk_bus_mipi_dsi[i] = para->clk_bus_mipi_dsi[index_base + i];
3166 }
3167 DE_INF("total number of clk in dsi:%d\n", CLK_DSI_NUM);
3168
3169 lcdp->rst_bus_mipi_dsi = para->rst_bus_mipi_dsi[lcd->hwdev_index];
3170 #endif
3171 DE_INF("lcd %d, irq_no=%d, irq_no_dsi=%d\n", disp, lcdp->irq_no,
3172 lcdp->irq_no_dsi);
3173
3174 lcd->set_manager = disp_device_set_manager;
3175 lcd->unset_manager = disp_device_unset_manager;
3176 lcd->get_resolution = disp_device_get_resolution;
3177 lcd->get_timings = disp_device_get_timings;
3178 lcd->enable = disp_lcd_enable;
3179 lcd->sw_enable = disp_lcd_sw_enable;
3180 lcd->fake_enable = disp_lcd_fake_enable;
3181 lcd->disable = disp_lcd_disable;
3182 lcd->is_enabled = disp_lcd_is_enabled;
3183 lcd->check_if_enabled = disp_lcd_check_if_enabled;
3184 lcd->set_bright = disp_lcd_set_bright;
3185 lcd->get_bright = disp_lcd_get_bright;
3186 lcd->set_bright_dimming = disp_lcd_set_bright_dimming;
3187 lcd->get_panel_info = disp_lcd_get_panel_info;
3188 lcd->set_static_config = disp_lcd_set_static_config;
3189 lcd->get_static_config = disp_lcd_get_static_config;
3190 lcd->check_config_dirty = disp_lcd_check_config_dirty;
3191
3192 lcd->set_panel_func = disp_lcd_set_panel_funs;
3193 lcd->set_open_func = disp_lcd_set_open_func;
3194 lcd->set_close_func = disp_lcd_set_close_func;
3195 lcd->backlight_enable = disp_lcd_backlight_enable;
3196 lcd->backlight_disable = disp_lcd_backlight_disable;
3197 lcd->pwm_enable = disp_lcd_pwm_enable;
3198 lcd->pwm_disable = disp_lcd_pwm_disable;
3199 lcd->power_enable = disp_lcd_power_enable;
3200 lcd->power_disable = disp_lcd_power_disable;
3201 lcd->pin_cfg = disp_lcd_pin_cfg;
3202 lcd->tcon_enable = disp_lcd_tcon_enable;
3203 lcd->tcon_disable = disp_lcd_tcon_disable;
3204 lcd->gpio_set_value = disp_lcd_gpio_set_value;
3205 lcd->gpio_set_direction = disp_lcd_gpio_set_direction;
3206 lcd->get_dimensions = disp_lcd_get_dimensions;
3207 lcd->get_status = disp_lcd_get_status;
3208 lcd->is_in_safe_period = disp_lcd_is_in_safe_period;
3209 lcd->usec_before_vblank = disp_lcd_usec_before_vblank;
3210 lcd->set_gamma_tbl = disp_lcd_set_gamma_tbl;
3211 lcd->enable_gamma = disp_lcd_enable_gamma;
3212 lcd->disable_gamma = disp_lcd_disable_gamma;
3213 lcd->get_fps = disp_lcd_get_fps;
3214 lcd->set_color_temperature = disp_lcd_set_color_temperature;
3215 lcd->get_color_temperature = disp_lcd_get_color_temperature;
3216 lcd->show_builtin_patten = disp_device_show_builtin_patten;
3217 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
3218 lcd->get_esd_info = disp_lcd_get_esd_info;
3219 #endif
3220
3221 /*lcd->init = disp_lcd_init;*/
3222 lcd->exit = disp_lcd_exit;
3223
3224 #if defined(SUPPORT_EINK) && defined(CONFIG_EINK_PANEL_USED)
3225 INIT_WORK(&lcd->close_eink_panel_work,
3226 disp_close_eink_panel_task);
3227 #endif
3228 disp_lcd_init(lcd, lcd->disp);
3229 disp_device_register(lcd);
3230 #if defined(CONFIG_DISP2_LCD_ESD_DETECT)
3231 INIT_WORK(&lcdp->reflush_work, disp_lcd_reflush_work);
3232 atomic_set(&lcdp->lcd_resetting, 0);
3233 #endif
3234
3235 disp++;
3236 }
3237
3238 return 0;
3239
3240 malloc_err:
3241 kfree(lcds);
3242 kfree(lcd_private);
3243 lcds = NULL;
3244 lcd_private = NULL;
3245
3246 return -1;
3247 }
3248
disp_exit_lcd(void)3249 s32 disp_exit_lcd(void)
3250 {
3251 u32 num_devices;
3252 u32 disp = 0;
3253 struct disp_device *lcd;
3254 u32 hwdev_index = 0;
3255
3256 if (!lcds)
3257 return 0;
3258
3259 num_devices = bsp_disp_feat_get_num_devices();
3260
3261 disp = 0;
3262 for (hwdev_index = 0; hwdev_index < num_devices; hwdev_index++) {
3263 if (!bsp_disp_feat_is_supported_output_types
3264 (hwdev_index, DISP_OUTPUT_TYPE_LCD)) {
3265 continue;
3266 }
3267 lcd = &lcds[disp];
3268 disp_device_unregister(lcd);
3269 lcd->exit(lcd);
3270 disp++;
3271 }
3272
3273 kfree(lcds);
3274 kfree(lcd_private);
3275 lcds = NULL;
3276 lcd_private = NULL;
3277
3278 #if defined(CONFIG_ARCH_SUN50IW10)
3279 if (iomap_data.initialized) {
3280 iounmap(iomap_data.qa_addr);
3281 iounmap(iomap_data.ic_ver_addr);
3282 iounmap(iomap_data.disp_cfg_addr);
3283
3284 iomap_data.initialized = 0;
3285 iomap_data.qa_addr = NULL;
3286 iomap_data.ic_ver_addr = NULL;
3287 iomap_data.disp_cfg_addr = NULL;
3288 }
3289 #endif
3290
3291 return 0;
3292 }
3293
3294 extern struct disp_drv_info g_disp_drv;
3295 extern s32 disp_exit(void);
reload_lcd(void)3296 void reload_lcd(void)
3297 {
3298 int disp;
3299 struct disp_lcd_private_data *lcdp;
3300
3301 disp = 0;
3302 printk("lcd%d reloading\n", disp);
3303 disp_lcd_disable(&lcds[disp]);
3304 msleep(5000);
3305 lcdp = disp_lcd_get_priv(&lcds[disp]);
3306 memset(&lcdp->lcd_cfg, 0, sizeof(lcdp->lcd_cfg));
3307 disp_lcd_init(&lcds[disp], disp);
3308 disp_lcd_set_panel_funs(&lcds[disp], "super_lcd_driver", &super_lcd_panel.func);
3309 disp_lcd_enable(&lcds[disp]);
3310 printk("lcd%d reload finish\n", disp);
3311 }
3312