cb9a977dd956d96f5230b2c17ff0f1e7ce43cdf0
[profile/mobile/platform/kernel/u-boot-tm1.git] / drivers / video / sprdfb / sprdfb_panel.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  */
5
6 #include <common.h>
7 #include <lcd.h>
8 #include <asm/arch/sprd_lcd.h>
9 #include <asm/arch/dispc_reg.h>
10
11 #include "sprdfb.h"
12
13 extern struct panel_if_ctrl sprdfb_mcu_ctrl;
14 extern struct panel_if_ctrl sprdfb_rgb_ctrl;
15 extern struct panel_if_ctrl sprdfb_mipi_ctrl;
16
17 extern struct panel_spec lcd_s6e8aa5x01_mipi_spec;
18 extern struct panel_spec lcd_s6e88oa_mipi_spec;
19 extern struct panel_spec lcd_nt35510_mipi_spec;
20 extern struct panel_spec lcd_nt35516_mipi_spec;
21 extern struct panel_spec lcd_nt35516_mcu_spec;
22 extern struct panel_spec lcd_nt35516_rgb_spi_spec;
23 extern struct panel_spec lcd_otm8018b_mipi_spec;
24 extern struct panel_spec lcd_hx8363_mcu_spec;
25 extern struct panel_spec lcd_panel_hx8363_rgb_spi_spec;
26 extern struct panel_spec lcd_panel_hx8363_rgb_spi_spec_viva;
27 extern struct panel_spec lcd_s6d0139_spec;
28 extern struct panel_spec lcd_otm1283a_mipi_spec;
29 extern struct panel_spec lcd_ssd2075_mipi_spec;
30 extern struct panel_spec lcd_panel_st7789v;
31 extern struct panel_spec lcd_panel_sc7798_rgb_spi;
32 extern struct panel_spec lcd_hx8369b_mipi_spec;
33 extern struct panel_spec lcd_sd7798d_mipi_spec;
34 extern struct panel_spec lcd_nt35502_mipi_spec;
35 extern struct panel_spec lcd_panel_ili9341;
36 extern struct panel_spec lcd_panel_ili9486;
37 extern struct panel_spec lcd_panel_ili9486_rgb_spi;
38 extern struct panel_spec lcd_ili9486s1_mipi_spec;
39 extern struct panel_spec lcd_nt51017_mipi_lvds_spec;
40 extern struct panel_spec lcd_t8861_mipi_spec;
41 extern struct panel_spec lcd_hx8379a_mipi_spec;
42 extern struct panel_spec lcd_hx8389c_mipi_spec;
43 extern struct panel_spec ili6150_lvds_spec;
44 extern struct panel_spec lcd_rm68180_mipi_spec;
45 extern struct panel_spec lcd_ili9806e_mipi_spec;
46 extern struct panel_spec lcd_ili9806e_2_mipi_spec;
47 extern struct panel_spec lcd_otm8019a_mipi_spec;
48 extern struct panel_spec lcd_fl10802_mipi_spec;
49 extern struct panel_spec lcd_jd9161_mipi_spec;
50 extern struct panel_spec lcd_hx8369b_mipi_vivaltoVE_spec;
51 extern struct panel_spec lcd_vx5b3d_mipi_spec;
52 extern struct panel_spec lcd_hx8369b_grandneo_mipi_spec;
53 extern struct panel_spec lcd_hx8369b_tshark2_j3_mipi_spec;
54 extern struct panel_spec lcd_sd7798d_mipi_spec;
55 extern struct panel_spec lcd_s6d77a1_mipi_spec;
56 extern struct panel_spec lcd_nt51017_mipi_spec;
57 extern struct panel_spec lcd_hx8394d_mipi_spec;
58
59 void sprdfb_panel_remove(struct sprdfb_device *dev);
60
61 static ushort colormap[256];
62
63 static struct panel_cfg panel_cfg[] = {
64 #ifdef CONFIG_FB_LCD_S6E8AA5X01_MIPI
65 {
66         .lcd_id = 0x400002,
67         .panel = &lcd_s6e8aa5x01_mipi_spec,
68 },
69 #endif
70 #ifdef CONFIG_FB_LCD_S6E88OA_MIPI
71 {
72         .lcd_id = 0x6e880a,
73         .panel = &lcd_s6e88oa_mipi_spec,
74 },
75 #endif
76 #ifdef CONFIG_FB_LCD_NT35510_MIPI
77         {
78                 .lcd_id = 0x10,
79                 .panel = &lcd_nt35510_mipi_spec,
80         },
81 #endif
82
83 #ifdef CONFIG_FB_LCD_NT35516_MIPI
84         {
85                 .lcd_id = 0x16,
86                 .panel = &lcd_nt35516_mipi_spec,
87         },
88 #endif
89
90 #ifdef CONFIG_FB_LCD_HX8394D_MIPI
91         {
92                 .lcd_id = 0x8394,
93                 .panel = &lcd_hx8394d_mipi_spec,
94         },
95 #endif
96
97 #ifdef CONFIG_FB_LCD_NT35516_MCU
98         {
99                 .lcd_id = 0x16,
100                 .panel = &lcd_nt35516_mcu_spec,
101         },
102 #endif
103
104 #ifdef CONFIG_FB_LCD_NT35516_RGB_SPI
105         {
106                 .lcd_id = 0x16,
107                 .panel = &lcd_nt35516_rgb_spi_spec,
108         },
109 #endif
110
111 #ifdef CONFIG_FB_LCD_OTM8018B_MIPI
112         {
113                 .lcd_id = 0x18,
114                 .panel = &lcd_otm8018b_mipi_spec,
115         },
116 #endif
117
118 #ifdef CONFIG_FB_LCD_HX8363_MCU
119         {
120                 .lcd_id = 0x18,
121                 .panel = &lcd_hx8363_mcu_spec,
122         },
123 #endif
124
125 #ifdef CONFIG_FB_LCD_VIVA_RGB_SPI
126         {
127                 .lcd_id = 0x63,
128                 .panel = &lcd_panel_hx8363_rgb_spi_spec_viva,
129         },
130 #endif
131
132 #ifdef CONFIG_FB_LCD_RM68180_MIPI
133         {
134                 .lcd_id = 0x80,
135                 .panel = &lcd_rm68180_mipi_spec,
136         },
137 #endif
138
139 #ifdef CONFIG_FB_LCD_HX8363_RGB_SPI
140         {
141                 .lcd_id = 0x84,
142                 .panel = &lcd_panel_hx8363_rgb_spi_spec,
143         },
144 #endif
145
146 #ifdef CONFIG_FB_LCD_S6D0139
147         {
148                 .lcd_id = 0x139,
149                 .panel = &lcd_s6d0139_spec,
150         },
151 #endif
152
153 #ifdef CONFIG_FB_LCD_OTM1283A_MIPI
154         {
155                 .lcd_id = 0x1283,
156                 .panel = &lcd_otm1283a_mipi_spec,
157         },
158 #endif
159
160 #ifdef CONFIG_FB_LCD_SSD2075_MIPI
161         {
162                 .lcd_id = 0x2075,
163                 .panel = &lcd_ssd2075_mipi_spec,
164         },
165 #endif
166
167 #ifdef CONFIG_FB_LCD_ST7789V_MCU
168         {
169                 .lcd_id = 0x7789,
170                 .panel = &lcd_panel_st7789v,
171         },
172 #endif
173
174 #ifdef CONFIG_FB_LCD_SC7798_RGB_SPI
175         {
176                 .lcd_id = 0x7798,
177                 .panel = &lcd_panel_sc7798_rgb_spi,
178         },
179 #endif
180
181 #if defined(CONFIG_FB_LCD_HX8369B_MIPI) || defined(CONFIG_FB_LCD_HX8369B_MIPI_COREPRIMELITE)
182         {
183                 .lcd_id = 0x8369,
184                 .panel = &lcd_hx8369b_mipi_spec,
185         },
186 #endif
187
188 #if defined (CONFIG_FB_LCD_HX8369B_MIPI) ||defined (CONFIG_FB_LCD_HX8369B_MIPI_KIRAN3G)
189         {
190                 .lcd_id = 0x8369,
191                 .panel = &lcd_hx8369b_mipi_spec,
192         },
193 #endif
194
195 #if defined(CONFIG_FB_LCD_SD7798D_MIPI_COREPRIMELITE)
196         {
197                 .lcd_id = 0x55b8f0,
198                 .panel = &lcd_sd7798d_mipi_spec,
199         },
200 #endif
201
202 #ifdef CONFIG_FB_LCD_NT35502_MIPI
203         {
204                 .lcd_id = 0x8370,
205                 .panel = &lcd_nt35502_mipi_spec,
206         },
207 #endif
208
209 #ifdef CONFIG_FB_LCD_NT51017_MIPI
210         {
211                 .lcd_id = 0x51017,
212                 .panel = &lcd_nt51017_mipi_spec,
213         },
214 #endif
215
216
217 #ifdef CONFIG_FB_LCD_ILI9341
218         {
219                 .lcd_id = 0x9341,
220                 .panel = &lcd_panel_ili9341,
221         },
222 #endif
223
224 #ifdef CONFIG_FB_LCD_ILI9486
225         {
226                 .lcd_id = 0x9486,
227                 .panel = &lcd_panel_ili9486,
228         },
229 #endif
230
231 #ifdef CONFIG_FB_LCD_ILI9486_RGB_SPI
232         {
233                 .lcd_id = 0x9486,
234                 .panel = &lcd_panel_ili9486_rgb_spi,
235         },
236 #endif
237
238 #ifdef CONFIG_FB_LCD_ILI9486S1_MIPI
239         {
240                 .lcd_id = 0x8370,
241                 .panel = &lcd_ili9486s1_mipi_spec,
242         },
243 #endif
244
245 #ifdef CONFIG_FB_LCD_HX8369B_MIPI_VIVALTO_VE
246         {
247                 .lcd_id = 0x8369,
248                 .panel = &lcd_hx8369b_mipi_vivaltoVE_spec,
249         },
250 #endif
251
252 #ifdef CONFIG_FB_LCD_VX5B3D_MIPI
253         {
254                 .lcd_id = 0x8282,
255                 .panel = &lcd_vx5b3d_mipi_spec,
256         },
257 #endif
258
259 #ifdef CONFIG_FB_LCD_GRANDNEO_MIPI
260         {
261                 .lcd_id = 0x8369,
262                 .panel = &lcd_hx8369b_grandneo_mipi_spec,
263         },
264 #endif
265
266 #ifdef CONFIG_FB_LCD_TSHARK2_J3_MIPI
267         {
268                 .lcd_id = 0x8369,
269                 .panel = &lcd_hx8369b_tshark2_j3_mipi_spec,
270         },
271 #endif
272
273 #ifdef CONFIG_FB_LCD_SD7798D_MIPI
274         {
275                 .lcd_id = 0x55b8f0,
276                 .panel = &lcd_sd7798d_mipi_spec,
277         },
278 #endif
279
280 #ifdef CONFIG_FB_LCD_S6D77A1_MIPI_PIKEA_J1
281         {
282                 .lcd_id = 0x55b810,
283                 .panel = &lcd_s6d77a1_mipi_spec,
284         },
285 #endif
286
287 #ifdef CONFIG_FB_LCD_NT51017_LVDS
288         {
289                 .lcd_id = 0xC749,
290                 .panel = &lcd_nt51017_mipi_lvds_spec,
291         },
292 #endif
293 #ifdef CONFIG_FB_LCD_T8861_MIPI
294         {
295                 .lcd_id = 0x04,
296                 .panel = &lcd_t8861_mipi_spec,
297         },
298 #endif
299 #ifdef CONFIG_FB_LCD_HX8379A_MIPI
300         {
301                 .lcd_id = 0x8379,
302                 .panel = &lcd_hx8379a_mipi_spec,
303         },
304 #endif
305 #ifdef CONFIG_FB_LCD_HX8389C_MIPI
306 {
307         .lcd_id = 0x8389,
308         .panel = &lcd_hx8389c_mipi_spec,
309 },
310 #endif
311 #ifdef CONFIG_FB_LCD_ILI6150_LVDS
312 {
313     .lcd_id = 0x1806,
314     .panel = &ili6150_lvds_spec,
315 },
316 #endif
317 #ifdef CONFIG_FB_LCD_ILI9806E_MIPI
318 {
319     .lcd_id = 0x4,
320     .panel = &lcd_ili9806e_mipi_spec,
321 },
322 #endif
323 #ifdef CONFIG_FB_LCD_ILI9806E_2_MIPI
324 {
325     .lcd_id = 0x980602,
326     .panel = &lcd_ili9806e_2_mipi_spec,
327 },
328 #endif
329 #ifdef CONFIG_FB_LCD_OTM8019A_MIPI
330         {
331                 .lcd_id = 0x8019,
332                 .panel = &lcd_otm8019a_mipi_spec,
333         },
334 #endif
335 #ifdef CONFIG_FB_LCD_FL10802_MIPI
336         {
337                 .lcd_id = 0x1080,
338                 .panel = &lcd_fl10802_mipi_spec,
339         },
340 #endif
341 #ifdef CONFIG_FB_LCD_JD9161_MIPI
342         {
343                 .lcd_id = 0x916100,
344                 .panel = &lcd_jd9161_mipi_spec,
345         },
346 #endif
347
348 #ifdef CONFIG_FB_LCD_HX8394D_MIPI
349 {
350         .lcd_id = 0x8394,
351         .panel = &lcd_hx8394d_mipi_spec,
352 },
353 #endif
354 };
355
356 #ifdef CONFIG_LCD_FWVGA
357 vidinfo_t panel_info = {
358         .vl_col = 480,
359         .vl_bpix = 4,
360         .vl_row = 854,
361         .cmap = colormap,
362 };
363 #endif
364
365 #ifdef CONFIG_LCD_WVGA
366 vidinfo_t panel_info = {
367         .vl_col = 480,
368         .vl_bpix = 4,
369         .vl_row = 800,
370         .cmap = colormap,
371 };
372 #endif
373
374 #ifdef CONFIG_LCD_HVGA
375 vidinfo_t panel_info = {
376         .vl_col = 320,
377         .vl_bpix = 4,
378         .vl_row = 480,
379         .cmap = colormap,
380 };
381 #endif
382
383 #ifdef CONFIG_LCD_QVGA
384 vidinfo_t panel_info = {
385         .vl_col = 240,
386         .vl_bpix = 4,
387         .vl_row = 320,
388         .cmap = colormap,
389 };
390 #endif
391
392 #ifdef CONFIG_LCD_QHD
393 vidinfo_t panel_info = {
394         .vl_col = 540,
395         .vl_bpix = 4,
396         .vl_row = 960,
397         .cmap = colormap,
398 };
399 #endif
400
401 #ifdef CONFIG_LCD_PAD_1024
402 vidinfo_t panel_info = {
403         .vl_col = 1024,
404         .vl_bpix = 4,
405         .vl_row = 600,
406         .cmap = colormap,
407 };
408 #endif
409 #ifdef CONFIG_LCD_720P  //thomaszhang@20130412
410 vidinfo_t panel_info = {
411         .vl_col = 720,
412         .vl_bpix = 4,
413         .vl_row = 1280,
414         .cmap = colormap,
415 };
416 #endif
417
418 #ifdef CONFIG_LCD_HD  //LiWei
419 vidinfo_t panel_info = {
420         .vl_col = 768,
421         .vl_bpix = 4,
422         .vl_row = 1024,
423         .cmap = colormap,
424 };
425 #endif
426 #ifdef CONFIG_LCD_PAD_WXGA
427 vidinfo_t panel_info = {
428         .vl_col = 800,
429         .vl_bpix = 4,
430         .vl_row = 1280,
431         .cmap = colormap,
432 };
433 #endif
434
435
436 static int32_t panel_reset_dispc(struct panel_spec *self)
437 {
438         sprd_gpio_request(NULL, 103);
439         sprd_gpio_direction_output(NULL, 103, 0);
440         sprd_gpio_set(NULL, 103, 1);
441         mdelay(10);
442         sprd_gpio_set(NULL, 103, 0);
443         mdelay(5);
444         sprd_gpio_set(NULL, 103, 1);
445         mdelay(5);
446
447         return 0;
448 }
449
450 static void panel_reset(struct sprdfb_device *dev)
451 {
452         FB_PRINT("sprdfb: [%s]\n",__FUNCTION__);
453
454         //clk/data lane enter LP
455         if(NULL != dev->if_ctrl->panel_if_before_panel_reset){
456                 dev->if_ctrl->panel_if_before_panel_reset(dev);
457                 mdelay(5);
458         }
459
460         //reset panel
461         panel_reset_dispc(dev->panel);
462 }
463
464 static int panel_mount(struct sprdfb_device *dev, struct panel_spec *panel)
465 {
466         uint16_t rval = 1;
467
468         printf("sprdfb: [%s], type = %d\n",__FUNCTION__, panel->type);
469
470         switch(panel->type){
471         case SPRDFB_PANEL_TYPE_MCU:
472                 dev->if_ctrl = &sprdfb_mcu_ctrl;
473                 break;
474         case SPRDFB_PANEL_TYPE_RGB:
475         case SPRDFB_PANEL_TYPE_LVDS:
476                 dev->if_ctrl = &sprdfb_rgb_ctrl;
477                 break;
478 #if ((!defined(CONFIG_SC7710G2)) && (!defined(CONFIG_SPX15)))
479         case SPRDFB_PANEL_TYPE_MIPI:
480                 dev->if_ctrl = &sprdfb_mipi_ctrl;
481                 break;
482 #endif
483         default:
484                 printf("sprdfb: [%s]: erro panel type.(%d)",__FUNCTION__, panel->type);
485                 dev->if_ctrl = NULL;
486                 rval = 0 ;
487                 break;
488         };
489
490         if(NULL == dev->if_ctrl){
491                 return -1;
492         }
493
494         if(dev->if_ctrl->panel_if_check){
495                 rval = dev->if_ctrl->panel_if_check(panel);
496         }
497
498         if(0 == rval){
499                 printf("sprdfb: [%s] check panel fail!\n", __FUNCTION__);
500                 dev->if_ctrl = NULL;
501                 return -1;
502         }
503
504         dev->panel = panel;
505
506         if(NULL == dev->panel->ops->panel_reset){
507                 dev->panel->ops->panel_reset = panel_reset_dispc;
508         }
509
510         dev->if_ctrl->panel_if_mount(dev);
511
512         return 0;
513 }
514
515
516 int panel_init(struct sprdfb_device *dev)
517 {
518         if((NULL == dev) || (NULL == dev->panel)){
519                 printf("sprdfb: [%s]: Invalid param\n", __FUNCTION__);
520                 return -1;
521         }
522
523         FB_PRINT("sprdfb: [%s], type = %d\n",__FUNCTION__, dev->panel->type);
524
525         if(NULL != dev->if_ctrl->panel_if_init){
526                 dev->if_ctrl->panel_if_init(dev);
527         }
528         return 0;
529 }
530
531 int panel_ready(struct sprdfb_device *dev)
532 {
533         if((NULL == dev) || (NULL == dev->panel)){
534                 printf("sprdfb: [%s]: Invalid param\n", __FUNCTION__);
535                 return -1;
536         }
537
538         FB_PRINT("sprdfb: [%s],  type = %d\n",__FUNCTION__, dev->panel->type);
539
540         if(NULL != dev->if_ctrl->panel_if_ready){
541                 dev->if_ctrl->panel_if_ready(dev);
542         }
543
544         return 0;
545 }
546
547
548 static struct panel_spec *adapt_panel_from_readid(struct sprdfb_device *dev)
549 {
550         int id, i, ret, b_panel_reset=0;
551
552         FB_PRINT("sprdfb: [%s]\n",__FUNCTION__);
553
554         for(i = 0;i<(sizeof(panel_cfg))/(sizeof(panel_cfg[0]));i++) {
555                 printf("sprdfb: [%s]: try panel 0x%x\n", __FUNCTION__, panel_cfg[i].lcd_id);
556                 ret = panel_mount(dev, panel_cfg[i].panel);
557                 if(ret < 0){
558                         printf("sprdfb: panel_mount failed!\n");
559                         continue;
560                 }
561                 dev->ctrl->update_clk(dev);
562                 panel_init(dev);
563                 if ((b_panel_reset==0) || (1 == dev->panel->is_need_reset))
564                 {
565                         panel_reset(dev);
566                         b_panel_reset=1;
567                 }
568                 id = dev->panel->ops->panel_readid(dev->panel);
569                 if(id == panel_cfg[i].lcd_id) {
570                         printf("sprdfb: [%s]: LCD Panel 0x%x is attached!\n", __FUNCTION__, panel_cfg[i].lcd_id);
571
572                         dev->panel->ops->panel_init(dev->panel);                //zxdebug modify for LCD adaptor 
573                         save_lcd_id_to_kernel(id);
574                         dev->panel->ops->panel_check_mtp(dev->panel);
575                         dev->panel->ops->panel_check_elvss(dev->panel);
576                         dev->panel->ops->panel_check_hbm(dev->panel);
577
578                         panel_ready(dev);
579                         return panel_cfg[i].panel;
580                 } else {                                                        //zxdbg for LCD adaptor
581                         printf("sprdfb: [%s]: LCD Panel 0x%x attached fail!go next\n", __FUNCTION__, panel_cfg[i].lcd_id);
582                         sprdfb_panel_remove(dev);                               //zxdebug modify for LCD adaptor 
583                 }
584         }
585         
586         printf("sprdfb:  [%s]: final failed to attach LCD Panel!\n", __FUNCTION__);
587         return NULL;
588 }
589
590 uint16_t sprdfb_panel_probe(struct sprdfb_device *dev)
591 {
592         struct panel_spec *panel;
593
594         if(NULL == dev){
595                 printf("sprdfb: [%s]: Invalid param\n", __FUNCTION__);
596                 return -1;
597         }
598
599         FB_PRINT("sprdfb: [%s]\n",__FUNCTION__);
600
601         /* can not be here in normal; we should get correct device id from uboot */
602         panel = adapt_panel_from_readid(dev);
603
604         if (panel) {
605                 FB_PRINT("sprdfb: [%s] got panel\n", __FUNCTION__);
606                 return 0;
607         }
608
609         printf("sprdfb: [%s] can not got panel\n", __FUNCTION__);
610
611         return -1;
612 }
613
614 void sprdfb_panel_invalidate_rect(struct panel_spec *self,
615                                 uint16_t left, uint16_t top,
616                                 uint16_t right, uint16_t bottom)
617 {
618         FB_PRINT("sprdfb: [%s]\n, (%d, %d, %d,%d)",__FUNCTION__, left, top, right, bottom);
619
620         if(NULL != self->ops->panel_invalidate_rect){
621                 self->ops->panel_invalidate_rect(self, left, top, right, bottom);
622         }
623 }
624
625 void sprdfb_panel_invalidate(struct panel_spec *self)
626 {
627         FB_PRINT("sprdfb: [%s]\n",__FUNCTION__);
628
629         if(NULL != self->ops->panel_invalidate){
630                 self->ops->panel_invalidate(self);
631         }
632 }
633
634 void sprdfb_panel_before_refresh(struct sprdfb_device *dev)
635 {
636         FB_PRINT("sprdfb: [%s]\n",__FUNCTION__);
637
638         if(NULL != dev->if_ctrl->panel_if_before_refresh)
639                 dev->if_ctrl->panel_if_before_refresh(dev);
640 }
641
642 void sprdfb_panel_after_refresh(struct sprdfb_device *dev)
643 {
644         FB_PRINT("sprdfb: [%s]\n",__FUNCTION__);
645
646         if(NULL != dev->if_ctrl->panel_if_after_refresh)
647                 dev->if_ctrl->panel_if_after_refresh(dev);
648 }
649
650 void sprdfb_panel_remove(struct sprdfb_device *dev)
651 {
652         FB_PRINT("sprdfb: [%s]\n",__FUNCTION__);
653
654         if((NULL != dev->if_ctrl) && (NULL != dev->if_ctrl->panel_if_uninit)){
655                 dev->if_ctrl->panel_if_uninit(dev);
656         }
657         dev->panel = NULL;
658 }
659