import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / video / mt8127 / disp_drv.c
1 #include <linux/delay.h>
2 #include <linux/fb.h>
3 #include "mtkfb.h"
4 #include <asm/uaccess.h>
5
6 #include "disp_drv.h"
7 #include "ddp_hal.h"
8 #include "disp_drv_log.h"
9 #include "lcm_drv.h"
10 #include "debug.h"
11
12 #include <linux/disp_assert_layer.h>
13
14 #include <linux/interrupt.h>
15 #include <linux/sched.h>
16 #include <linux/semaphore.h>
17 #include <linux/module.h>
18 #include <linux/wait.h>
19 #include <linux/kthread.h>
20 #include <linux/mutex.h>
21 #include "mach/mt_clkmgr.h"
22 #include <linux/vmalloc.h>
23 #include "mtkfb_info.h"
24 #include <linux/dma-mapping.h>
25 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
26 #include "disp_ovl_engine_api.h"
27 #include "disp_ovl_engine_core.h"
28 #endif
29 extern unsigned int lcd_fps;
30 extern BOOL is_early_suspended;
31 extern struct semaphore sem_early_suspend;
32
33 extern unsigned int EnableVSyncLog;
34
35 #define LCM_ESD_CHECK_MAX_COUNT 5
36
37 #define ALIGN_TO(x, n) \
38 (((x) + ((n) - 1)) & ~((n) - 1))
39
40 //#undef pr_info
41 //#define pr_info printk
42
43 // ---------------------------------------------------------------------------
44 // Local Variables
45 // ---------------------------------------------------------------------------
46 unsigned int FB_LAYER = DISP_DEFAULT_UI_LAYER_ID;
47 static const DISP_IF_DRIVER *disp_if_drv = NULL;
48 const LCM_DRIVER *lcm_drv = NULL;
49 extern LCM_PARAMS *lcm_params;
50
51 static volatile int direct_link_layer = -1;
52 static UINT32 disp_fb_bpp = 32; ///ARGB8888
53 static UINT32 disp_fb_pages = 3; ///double buffer
54
55 BOOL is_engine_in_suspend_mode = FALSE;
56 BOOL is_lcm_in_suspend_mode = FALSE;
57 static UINT32 dal_layerPA;
58 static UINT32 dal_layerVA;
59
60 static unsigned long u4IndexOfLCMList = 0;
61
62 static wait_queue_head_t config_update_wq;
63 static struct task_struct *config_update_task = NULL;
64 static int config_update_task_wakeup = 0;
65 extern atomic_t OverlaySettingDirtyFlag;
66 extern atomic_t OverlaySettingApplied;
67 extern unsigned int PanDispSettingPending;
68 extern unsigned int PanDispSettingDirty;
69 extern unsigned int PanDispSettingApplied;
70
71 extern unsigned int fb_pa;
72
73 extern bool is_ipoh_bootup;
74
75 extern struct mutex OverlaySettingMutex;
76 extern wait_queue_head_t reg_update_wq;
77 static wait_queue_head_t vsync_wq;
78 static bool vsync_wq_flag = false;
79
80 static struct hrtimer cmd_mode_update_timer;
81 static ktime_t cmd_mode_update_timer_period;
82
83 static bool needStartEngine = true;
84
85 extern unsigned int need_esd_check;
86 extern wait_queue_head_t esd_check_wq;
87 extern BOOL esd_kthread_pause;
88
89 DEFINE_MUTEX(MemOutSettingMutex);
90 static struct disp_path_config_mem_out_struct MemOutConfig;
91 static BOOL is_immediateupdate = false;
92
93 DEFINE_MUTEX(LcmCmdMutex);
94
95 unsigned int disp_running = 0;
96 DECLARE_WAIT_QUEUE_HEAD(disp_done_wq);
97
98 #if 1//!defined(MTK_OVERLAY_ENGINE_SUPPORT)
99 OVL_CONFIG_STRUCT cached_layer_config[DDP_OVL_LAYER_MUN] =
100 {
101 {.layer = 0, .isDirty = 1},
102 {.layer = 1, .isDirty = 1},
103 {.layer = 2, .isDirty = 1},
104 {.layer = 3, .isDirty = 1}
105 };
106 #endif
107
108 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
109 static OVL_CONFIG_STRUCT _layer_config[2][DDP_OVL_LAYER_MUN];
110 static unsigned int layer_config_index = 0;
111 OVL_CONFIG_STRUCT* captured_layer_config = _layer_config[0];
112 OVL_CONFIG_STRUCT* realtime_layer_config = _layer_config[0];
113 #endif
114 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
115 extern DISP_OVL_ENGINE_INSTANCE_HANDLE mtkfb_instance;
116 #endif
117
118 struct DBG_OVL_CONFIGS
119 {
120 OVL_CONFIG_STRUCT Layer0;
121 OVL_CONFIG_STRUCT Layer1;
122 OVL_CONFIG_STRUCT Layer2;
123 OVL_CONFIG_STRUCT Layer3;
124 };
125
126 unsigned int gCaptureLayerEnable = 0;
127 unsigned int gCaptureLayerDownX = 10;
128 unsigned int gCaptureLayerDownY = 10;
129
130 struct task_struct *captureovl_task = NULL;
131 static int _DISP_CaptureOvlKThread(void *data);
132 static unsigned int gWakeupCaptureOvlThread = 0;
133 unsigned int gCaptureOvlThreadEnable = 0;
134 unsigned int gCaptureOvlDownX = 10;
135 unsigned int gCaptureOvlDownY = 10;
136
137 struct task_struct *capturefb_task = NULL;
138 static int _DISP_CaptureFBKThread(void *data);
139 unsigned int gCaptureFBEnable = 0;
140 unsigned int gCaptureFBDownX = 10;
141 unsigned int gCaptureFBDownY = 10;
142 unsigned int gCaptureFBPeriod = 100;
143 DECLARE_WAIT_QUEUE_HEAD(gCaptureFBWQ);
144
145 extern struct fb_info *mtkfb_fbi;
146
147 unsigned int is_video_mode_running = 0;
148
149 DEFINE_SEMAPHORE(sem_update_screen);//linux 3.0 porting
150 static BOOL isLCMFound = FALSE;
151 /// Some utilities
152 #define ALIGN_TO_POW_OF_2(x, n) \
153 (((x) + ((n) - 1)) & ~((n) - 1))
154
155 #define ALIGN_TO(x, n) \
156 (((x) + ((n) - 1)) & ~((n) - 1))
157
158
159
160 static size_t disp_log_on = false;
161 #define DISP_LOG(fmt, arg...) \
162 do { \
163 if (disp_log_on) DISP_LOG_PRINT(ANDROID_LOG_WARN, "COMMON", fmt, ##arg); \
164 }while (0)
165
166 #define DISP_FUNC() \
167 do { \
168 if(disp_log_on) DISP_LOG_PRINT(ANDROID_LOG_INFO, "COMMON", "[Func]%s\n", __func__); \
169 }while (0)
170
171 void disp_log_enable(int enable)
172 {
173 disp_log_on = enable;
174 DISP_LOG("disp common log %s\n", enable?"enabled":"disabled");
175 }
176 // ---------------------------------------------------------------------------
177 // Local Functions
178 // ---------------------------------------------------------------------------
179
180 extern LCM_DRIVER* lcm_driver_list[];
181 extern unsigned int lcm_count;
182
183 static void disp_dump_lcm_parameters(LCM_PARAMS *lcm_params)
184 {
185 unsigned char *LCM_TYPE_NAME[] = {"DBI", "DPI", "DSI"};
186 unsigned char *LCM_CTRL_NAME[] = {"NONE", "SERIAL", "PARALLEL", "GPIO"};
187
188 if(lcm_params == NULL)
189 return;
190
191 pr_info("[mtkfb] LCM TYPE: %s\n", LCM_TYPE_NAME[lcm_params->type]);
192 pr_info("[mtkfb] LCM INTERFACE: %s\n", LCM_CTRL_NAME[lcm_params->ctrl]);
193 pr_info("[mtkfb] LCM resolution: %d x %d\n", lcm_params->width, lcm_params->height);
194
195 return;
196 }
197
198 char disp_lcm_name[256] = {0};
199 BOOL disp_get_lcm_name_boot(char *cmdline)
200 {
201 BOOL ret = FALSE;
202 char *p, *q;
203
204 p = strstr(cmdline, "lcm=");
205 if(p == NULL)
206 {
207 // we can't find lcm string in the command line,
208 // the uboot should be old version, or the kernel is loaded by ICE debugger
209 return DISP_SelectDeviceBoot(NULL);
210 }
211
212 p += 4;
213 if((p - cmdline) > strlen(cmdline+1))
214 {
215 ret = FALSE;
216 goto done;
217 }
218
219 isLCMFound = strcmp(p, "0");
220 pr_info("[mtkfb] LCM is %sconnected\n", ((isLCMFound)?"":"not "));
221 p += 2;
222 q = p;
223 while(*q != ' ' && *q != '\0')
224 q++;
225
226 memset((void*)disp_lcm_name, 0, sizeof(disp_lcm_name));
227 strncpy((char*)disp_lcm_name, (const char*)p, (int)(q-p));
228
229 if(DISP_SelectDeviceBoot(disp_lcm_name))
230 ret = TRUE;
231
232 done:
233 return ret;
234 }
235
236 static BOOL disp_drv_init_context(void)
237 {
238 if (disp_if_drv != NULL && lcm_drv != NULL){
239 return TRUE;
240 }
241
242 if(!isLCMFound)
243 DISP_DetectDevice();
244
245 disphal_init_ctrl_if();
246
247 disp_if_drv = disphal_get_if_driver();
248
249 if (!disp_if_drv) return FALSE;
250
251 return TRUE;
252 }
253
254 BOOL DISP_IsLcmFound(void)
255 {
256 return isLCMFound;
257 }
258
259 BOOL DISP_IsContextInited(void)
260 {
261 if(lcm_params && disp_if_drv && lcm_drv)
262 return TRUE;
263 else
264 return FALSE;
265 }
266
267 BOOL DISP_SelectDeviceBoot(const char* lcm_name)
268 {
269 //LCM_DRIVER *lcm = NULL;
270
271 pr_info("%s\n", __func__);
272
273 if(lcm_name == NULL)
274 {
275 // we can't do anything in boot stage if lcm_name is NULL
276 return false;
277 }
278 lcm_drv = disphal_get_lcm_driver(lcm_name, &u4IndexOfLCMList);
279
280 if (NULL == lcm_drv)
281 {
282 pr_info("%s, get_lcm_driver returns NULL\n", __func__);
283 return FALSE;
284 }
285 isLCMFound = TRUE;
286
287 disp_if_drv = disphal_get_if_driver();
288
289 disp_dump_lcm_parameters(lcm_params);
290 return TRUE;
291 }
292
293 BOOL DISP_SelectDevice(const char* lcm_name)
294 {
295 lcm_drv = disphal_get_lcm_driver(lcm_name, &u4IndexOfLCMList);
296 if (NULL == lcm_drv)
297 {
298 pr_info("%s, disphal_get_lcm_driver() returns NULL\n", __func__);
299 return FALSE;
300 }
301 isLCMFound = TRUE;
302
303 disp_dump_lcm_parameters(lcm_params);
304 return disp_drv_init_context();
305 }
306
307 BOOL DISP_DetectDevice(void)
308 {
309 lcm_drv = disphal_get_lcm_driver(NULL, &u4IndexOfLCMList);
310 if (NULL == lcm_drv)
311 {
312 pr_info("%s, disphal_get_lcm_driver() returns NULL\n", __func__);
313 return FALSE;
314 }
315 isLCMFound = TRUE;
316
317 disp_dump_lcm_parameters(lcm_params);
318
319 return TRUE;
320 }
321
322 // ---------------------------------------------------------------------------
323 // DISP Driver Implementations
324 // ---------------------------------------------------------------------------
325 extern mtk_dispif_info_t dispif_info[MTKFB_MAX_DISPLAY_COUNT];
326
327 DISP_STATUS DISP_Init(UINT32 fbVA, UINT32 fbPA, BOOL isLcmInited)
328 {
329 DISP_STATUS r = DISP_STATUS_OK;
330
331 captureovl_task = kthread_create(_DISP_CaptureOvlKThread, NULL, "disp_captureovl_kthread");
332 if (IS_ERR(captureovl_task))
333 {
334 DISP_LOG("DISP_InitVSYNC(): Cannot create capture ovl kthread\n");
335 }
336 if (gWakeupCaptureOvlThread)
337 wake_up_process(captureovl_task);
338
339 capturefb_task = kthread_create(_DISP_CaptureFBKThread, mtkfb_fbi, "disp_capturefb_kthread");
340 if (IS_ERR(capturefb_task))
341 {
342 DISP_LOG("DISP_InitVSYNC(): Cannot create capture fb kthread\n");
343 }
344 wake_up_process(capturefb_task);
345
346 if (!disp_drv_init_context()) {
347 return DISP_STATUS_NOT_IMPLEMENTED;
348 }
349
350 disphal_init_ctrl_if();
351 disp_path_clock_on("mtkfb");
352 // TODO: Fixit!!!!!
353 //xuecheng's workaround for 82 video mode
354 //if(lcm_params->type==LCM_TYPE_DSI && lcm_params->dsi.mode!=CMD_MODE)
355 // isLcmInited = 0;
356
357 r = (disp_if_drv->init) ?
358 (disp_if_drv->init(fbVA, fbPA, isLcmInited)) :
359 DISP_STATUS_NOT_IMPLEMENTED;
360
361 DISP_InitVSYNC((100000000/lcd_fps) + 1);//us
362
363 {
364 DAL_STATUS ret;
365
366 /// DAL init here
367 fbVA += DISP_GetFBRamSize();
368 fbPA += DISP_GetFBRamSize();
369 ret = DAL_Init(fbVA, fbPA);
370 ASSERT(DAL_STATUS_OK == ret);
371 dal_layerPA = fbPA;
372 dal_layerVA = fbVA;
373 }
374 // check lcm status
375 if(lcm_drv->check_status)
376 lcm_drv->check_status();
377
378 memset((void*)(&dispif_info[MTKFB_DISPIF_PRIMARY_LCD]), 0, sizeof(mtk_dispif_info_t));
379
380 switch(lcm_params->type)
381 {
382 case LCM_TYPE_DBI:
383 {
384 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayType = DISPIF_TYPE_DBI;
385 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayMode = DISPIF_MODE_COMMAND;
386 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].isHwVsyncAvailable = 1;
387 pr_info("DISP Info: DBI, CMD Mode, HW Vsync enable\n");
388 break;
389 }
390 case LCM_TYPE_DPI:
391 {
392 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayType = DISPIF_TYPE_DPI;
393 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayMode = DISPIF_MODE_VIDEO;
394 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].isHwVsyncAvailable = 1;
395 pr_info("DISP Info: DPI, VDO Mode, HW Vsync enable\n");
396 break;
397 }
398 case LCM_TYPE_DSI:
399 {
400 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayType = DISPIF_TYPE_DSI;
401 if(lcm_params->dsi.mode == CMD_MODE)
402 {
403 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayMode = DISPIF_MODE_COMMAND;
404 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].isHwVsyncAvailable = 1;
405 pr_info("DISP Info: DSI, CMD Mode, HW Vsync enable\n");
406 }
407 else
408 {
409 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayMode = DISPIF_MODE_VIDEO;
410 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].isHwVsyncAvailable = 1;
411 pr_info("DISP Info: DSI, VDO Mode, HW Vsync enable\n");
412 }
413
414 break;
415 }
416 default:
417 break;
418 }
419
420
421 if(disp_if_drv->get_panel_color_format())
422 {
423 switch(disp_if_drv->get_panel_color_format())
424 {
425 case PANEL_COLOR_FORMAT_RGB565:
426 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayFormat = DISPIF_FORMAT_RGB565;
427 case PANEL_COLOR_FORMAT_RGB666:
428 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayFormat = DISPIF_FORMAT_RGB666;
429 case PANEL_COLOR_FORMAT_RGB888:
430 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayFormat = DISPIF_FORMAT_RGB888;
431 default:
432 break;
433 }
434 }
435
436 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayWidth = DISP_GetScreenWidth();
437 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayHeight = DISP_GetScreenHeight();
438 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].vsyncFPS = lcd_fps;
439
440 if(dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayWidth * dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayHeight <= 240*432)
441 {
442 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].physicalHeight= dispif_info[MTKFB_DISPIF_PRIMARY_LCD].physicalWidth= 0;
443 }
444 else if(dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayWidth * dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayHeight <= 320*480)
445 {
446 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].physicalHeight= dispif_info[MTKFB_DISPIF_PRIMARY_LCD].physicalWidth= 0;
447 }
448 else if(dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayWidth * dispif_info[MTKFB_DISPIF_PRIMARY_LCD].displayHeight <= 480*854)
449 {
450 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].physicalHeight= dispif_info[MTKFB_DISPIF_PRIMARY_LCD].physicalWidth= 0;
451 }
452 else
453 {
454 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].physicalHeight= dispif_info[MTKFB_DISPIF_PRIMARY_LCD].physicalWidth= 0;
455 }
456
457 dispif_info[MTKFB_DISPIF_PRIMARY_LCD].isConnected = 1;
458
459
460 return r;
461 }
462
463
464 DISP_STATUS DISP_Deinit(void)
465 {
466 DISP_CHECK_RET(DISP_PanelEnable(FALSE));
467 DISP_CHECK_RET(DISP_PowerEnable(FALSE));
468
469 return DISP_STATUS_OK;
470 }
471
472 // -----
473
474 DISP_STATUS DISP_PowerEnable(BOOL enable)
475 {
476 DISP_STATUS ret = DISP_STATUS_OK;
477
478 static BOOL s_enabled = TRUE;
479
480 if (enable != s_enabled)
481 s_enabled = enable;
482 else
483 return ret;
484
485 if (down_interruptible(&sem_update_screen)) {
486 pr_info("ERROR: Can't get sem_update_screen in DISP_PowerEnable()\n");
487 return DISP_STATUS_ERROR;
488 }
489
490 disp_drv_init_context();
491
492 is_engine_in_suspend_mode = enable ? FALSE : TRUE;
493
494 if (!is_ipoh_bootup)
495 needStartEngine = true;
496
497 if (enable && lcm_drv && lcm_drv->resume_power)
498 {
499 lcm_drv->resume_power();
500 }
501
502 ret = (disp_if_drv->enable_power) ?
503 (disp_if_drv->enable_power(enable)) :
504 DISP_STATUS_NOT_IMPLEMENTED;
505
506 if (enable) {
507 DAL_OnDispPowerOn();
508 }
509 else if (lcm_drv && lcm_drv->suspend_power)
510 {
511 lcm_drv->suspend_power();
512 }
513
514 up(&sem_update_screen);
515
516
517 return ret;
518 }
519
520
521 DISP_STATUS DISP_PanelEnable(BOOL enable)
522 {
523 static BOOL s_enabled = TRUE;
524 DISP_STATUS ret = DISP_STATUS_OK;
525
526 DISP_LOG("panel is %s\n", enable?"enabled":"disabled");
527
528 if (down_interruptible(&sem_update_screen))
529 {
530 pr_info("ERROR: Can't get sem_update_screen in DISP_PanelEnable()\n");
531 return DISP_STATUS_ERROR;
532 }
533
534 disp_drv_init_context();
535
536 is_lcm_in_suspend_mode = enable ? FALSE : TRUE;
537
538 if (is_ipoh_bootup)
539 s_enabled = TRUE;
540
541 if (!lcm_drv->suspend || !lcm_drv->resume)
542 {
543 ret = DISP_STATUS_NOT_IMPLEMENTED;
544 goto End;
545 }
546
547 if (enable && !s_enabled)
548 {
549 s_enabled = TRUE;
550 disphal_panel_enable(lcm_drv, &LcmCmdMutex, TRUE);
551 }
552 else if (!enable && s_enabled)
553 {
554 s_enabled = FALSE;
555 disphal_panel_enable(lcm_drv, &LcmCmdMutex, FALSE);
556 }
557
558 End:
559 up(&sem_update_screen);
560
561 return ret;
562 }
563
564 DISP_STATUS DISP_SetBacklight(UINT32 level)
565 {
566 DISP_STATUS ret = DISP_STATUS_OK;
567
568 if (down_interruptible(&sem_update_screen)) {
569 pr_info("ERROR: Can't get sem_update_screen in DISP_SetBacklight()\n");
570 return DISP_STATUS_ERROR;
571 }
572
573 disp_drv_init_context();
574
575 disphal_wait_not_busy();
576
577 if (!lcm_drv->set_backlight) {
578 ret = DISP_STATUS_NOT_IMPLEMENTED;
579 goto End;
580 }
581
582 disphal_set_backlight(lcm_drv, &LcmCmdMutex, level);
583 End:
584
585 up(&sem_update_screen);
586
587 return ret;
588 }
589
590 DISP_STATUS DISP_SetBacklight_mode(UINT32 mode)
591 {
592 DISP_STATUS ret = DISP_STATUS_OK;
593
594 if (down_interruptible(&sem_update_screen)) {
595 pr_info("ERROR: Can't get sem_update_screen in DISP_SetBacklight_mode()\n");
596 return DISP_STATUS_ERROR;
597 }
598
599 disp_drv_init_context();
600
601 disphal_wait_not_busy();
602
603 if (!lcm_drv->set_backlight) {
604 ret = DISP_STATUS_NOT_IMPLEMENTED;
605 goto End;
606 }
607
608 disphal_set_backlight_mode(lcm_drv, &LcmCmdMutex, mode);
609 End:
610
611 up(&sem_update_screen);
612
613 return ret;
614
615 }
616
617 DISP_STATUS DISP_SetPWM(UINT32 divider)
618 {
619 DISP_STATUS ret = DISP_STATUS_OK;
620
621 if (down_interruptible(&sem_update_screen)) {
622 pr_info("ERROR: Can't get sem_update_screen in DISP_SetPWM()\n");
623 return DISP_STATUS_ERROR;
624 }
625
626 disp_drv_init_context();
627
628 disphal_wait_not_busy();
629
630 if (!lcm_drv->set_pwm) {
631 ret = DISP_STATUS_NOT_IMPLEMENTED;
632 goto End;
633 }
634
635 disphal_set_pwm(lcm_drv, &LcmCmdMutex, divider);
636 End:
637
638 up(&sem_update_screen);
639
640 return ret;
641 }
642
643 DISP_STATUS DISP_GetPWM(UINT32 divider, unsigned int *freq)
644 {
645 DISP_STATUS ret = DISP_STATUS_OK;
646
647 disp_drv_init_context();
648
649 if (!lcm_drv->get_pwm) {
650 ret = DISP_STATUS_NOT_IMPLEMENTED;
651 goto End;
652 }
653
654 disphal_get_pwm(lcm_drv, &LcmCmdMutex, divider, freq);
655 End:
656 return ret;
657 }
658
659
660 // -----
661
662 DISP_STATUS DISP_SetFrameBufferAddr(UINT32 fbPhysAddr)
663 {
664 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
665 cached_layer_config[FB_LAYER].addr = fbPhysAddr;
666 cached_layer_config[FB_LAYER].isDirty = true;
667 #endif
668 return DISP_STATUS_OK;
669 }
670
671 // -----
672
673 static BOOL is_overlaying = FALSE;
674
675 DISP_STATUS DISP_EnterOverlayMode(void)
676 {
677 DISP_FUNC();
678 if (is_overlaying) {
679 return DISP_STATUS_ALREADY_SET;
680 } else {
681 is_overlaying = TRUE;
682 }
683
684 return DISP_STATUS_OK;
685 }
686
687
688 DISP_STATUS DISP_LeaveOverlayMode(void)
689 {
690 DISP_FUNC();
691 if (!is_overlaying) {
692 return DISP_STATUS_ALREADY_SET;
693 } else {
694 is_overlaying = FALSE;
695 }
696
697 return DISP_STATUS_OK;
698 }
699
700 DISP_STATUS DISP_UpdateScreen(UINT32 x, UINT32 y, UINT32 width, UINT32 height)
701 {
702 unsigned int is_video_mode;
703
704 // return DISP_STATUS_OK;
705 DISP_LOG("update screen, (%d,%d),(%d,%d)\n", x, y, width, height);
706
707 if ((lcm_params->type==LCM_TYPE_DPI) ||
708 ((lcm_params->type==LCM_TYPE_DSI) && (lcm_params->dsi.mode != CMD_MODE)))
709 is_video_mode = 1;
710 else
711 is_video_mode = 0;
712
713 if (down_interruptible(&sem_update_screen)) {
714 pr_info("ERROR: Can't get sem_update_screen in DISP_UpdateScreen()\n");
715 return DISP_STATUS_ERROR;
716 }
717 // if LCM is powered down, LCD would never recieve the TE signal
718 //
719 if (is_lcm_in_suspend_mode || is_engine_in_suspend_mode) goto End;
720 if (is_video_mode && is_video_mode_running)
721 needStartEngine = false;
722 if (needStartEngine)
723 {
724 disphal_update_screen(lcm_drv, &LcmCmdMutex, x, y, width, height);
725 }
726 if (-1 != direct_link_layer) {
727 }
728 else
729 {
730 if (needStartEngine)
731 {
732 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
733 Disp_Ovl_Engine_Trigger_Overlay(mtkfb_instance);
734 #endif
735 disp_if_drv->update_screen(FALSE);
736 }
737 }
738 needStartEngine = false;
739 End:
740 up(&sem_update_screen);
741
742 return DISP_STATUS_OK;
743 }
744
745 DISP_STATUS DISP_WaitForLCDNotBusy(void)
746 {
747 disphal_wait_not_busy();
748 return DISP_STATUS_OK;
749 }
750
751 DISP_STATUS _DISP_ConfigUpdateScreen(UINT32 x, UINT32 y, UINT32 width, UINT32 height)
752 {
753 // if LCM is powered down, LCD would never recieve the TE signal
754 //
755 if (is_lcm_in_suspend_mode || is_engine_in_suspend_mode) return DISP_STATUS_ERROR;
756 disphal_update_screen(lcm_drv, &LcmCmdMutex, x, y, width, height);
757 disp_if_drv->update_screen(TRUE);
758
759 return DISP_STATUS_OK;
760 }
761
762 #define DISP_CB_MAXCNT 2
763 typedef struct {
764 DISP_EXTRA_CHECKUPDATE_PTR checkupdate_cb[DISP_CB_MAXCNT];
765 DISP_EXTRA_CONFIG_PTR config_cb[DISP_CB_MAXCNT];
766 } CONFIG_CB_ARRAY;
767 CONFIG_CB_ARRAY g_CB_Array = { {NULL , NULL},{NULL , NULL}};//if DISP_CB_MAXCNT == 2
768 DEFINE_MUTEX(UpdateRegMutex);
769 void GetUpdateMutex(void)
770 {
771 mutex_lock(&UpdateRegMutex);
772 }
773 int TryGetUpdateMutex(void)
774 {
775 return mutex_trylock(&UpdateRegMutex);
776 }
777 void ReleaseUpdateMutex(void)
778 {
779 mutex_unlock(&UpdateRegMutex);
780 }
781
782 int DISP_RegisterExTriggerSource(DISP_EXTRA_CHECKUPDATE_PTR pCheckUpdateFunc , DISP_EXTRA_CONFIG_PTR pConfFunc)
783 {
784 int index = 0;
785 int hit = 0;
786 if((NULL == pCheckUpdateFunc) || (NULL == pConfFunc))
787 {
788 pr_info("Warnning! [Func]%s register NULL function : %p,%p\n", __func__ , pCheckUpdateFunc , pConfFunc);
789 return -1;
790 }
791
792 GetUpdateMutex();
793
794 for(index = 0 ; index < DISP_CB_MAXCNT ; index += 1)
795 {
796 if(NULL == g_CB_Array.checkupdate_cb[index])
797 {
798 g_CB_Array.checkupdate_cb[index] = pCheckUpdateFunc;
799 g_CB_Array.config_cb[index] = pConfFunc;
800 hit = 1;
801 break;
802 }
803 }
804
805 ReleaseUpdateMutex();
806
807 return (hit ? index : (-1));
808 }
809
810 void DISP_UnRegisterExTriggerSource(int u4ID)
811 {
812 if(DISP_CB_MAXCNT < (u4ID+1))
813 {
814 pr_info("Warnning! [Func]%s unregister a never registered function : %d\n", __func__ , u4ID);
815 return;
816 }
817
818 GetUpdateMutex();
819
820 g_CB_Array.checkupdate_cb[u4ID] = NULL;
821 g_CB_Array.config_cb[u4ID] = NULL;
822
823 ReleaseUpdateMutex();
824 }
825 #if defined (MTK_HDMI_SUPPORT)
826 extern bool is_hdmi_active(void);
827 #endif
828
829
830 static int _DISP_CaptureFBKThread(void *data)
831 {
832 struct fb_info* pInfo = (struct fb_info*) data;
833 MMP_MetaDataBitmap_t Bitmap;
834
835 while(1)
836 {
837 wait_event_interruptible(gCaptureFBWQ, gCaptureFBEnable);
838 Bitmap.data1 = pInfo->var.yoffset;
839 Bitmap.width = DISP_GetScreenWidth();
840 Bitmap.height = DISP_GetScreenHeight() * 2;
841 Bitmap.bpp = pInfo->var.bits_per_pixel;
842
843 switch (pInfo->var.bits_per_pixel)
844 {
845 case 16:
846 Bitmap.format = MMProfileBitmapRGB565;
847 break;
848 case 32:
849 Bitmap.format = MMProfileBitmapBGRA8888;
850 break;
851 default:
852 Bitmap.format = MMProfileBitmapRGB565;
853 Bitmap.bpp = 16;
854 break;
855 }
856
857 Bitmap.start_pos = 0;
858 Bitmap.pitch = pInfo->fix.line_length;
859 if (Bitmap.pitch == 0)
860 {
861 Bitmap.pitch = ALIGN_TO(Bitmap.width, 1) * Bitmap.bpp / 8;
862 }
863 Bitmap.data_size = Bitmap.pitch * Bitmap.height;
864 Bitmap.down_sample_x = gCaptureFBDownX;
865 Bitmap.down_sample_y = gCaptureFBDownY;
866 Bitmap.pData = ((struct mtkfb_device*)pInfo->par)->fb_va_base;
867 MMProfileLogMetaBitmap(MTKFB_MMP_Events.FBDump, MMProfileFlagPulse, &Bitmap);
868 msleep(gCaptureFBPeriod);
869 }
870 return 0;
871 }
872
873 static int _DISP_CaptureOvlKThread(void *data)
874 {
875 unsigned int index = 0;
876 unsigned int mva[2];
877 void* va[2];
878 unsigned int buf_size;
879 unsigned int init = 0;
880 unsigned int enabled = 0;
881 int wait_ret = 0;
882 MMP_MetaDataBitmap_t Bitmap;
883 buf_size = DISP_GetScreenWidth() * DISP_GetScreenHeight() * 4;
884
885 while(1)
886 {
887 wait_ret = wait_event_interruptible(reg_update_wq, gWakeupCaptureOvlThread);
888 DISP_LOG("[WaitQ] wait_event_interruptible() ret = %d, %d\n", wait_ret, __LINE__);
889 gWakeupCaptureOvlThread = 0;
890
891 if (init == 0)
892 {
893 va[0] = vmalloc(buf_size);
894 va[1] = vmalloc(buf_size);
895 memset(va[0], 0, buf_size);
896 memset(va[1], 0, buf_size);
897 disphal_map_overlay_out_buffer((unsigned int)va[0], buf_size, &(mva[0]));
898 disphal_map_overlay_out_buffer((unsigned int)va[1], buf_size, &(mva[1]));
899 disphal_init_overlay_to_memory();
900 init = 1;
901 }
902 if (!gCaptureOvlThreadEnable)
903 {
904 if (enabled)
905 {
906 DISP_Config_Overlay_to_Memory(mva[index], 0);
907 enabled = 0;
908 }
909 continue;
910 }
911 DISP_Config_Overlay_to_Memory(mva[index], 1);
912 enabled = 1;
913
914 disphal_sync_overlay_out_buffer((unsigned int)va[index], DISP_GetScreenHeight()*DISP_GetScreenWidth()*24/8);
915
916 Bitmap.data1 = index;
917 Bitmap.data2 = mva[index];
918 Bitmap.width = DISP_GetScreenWidth();
919 Bitmap.height = DISP_GetScreenHeight();
920 Bitmap.format = MMProfileBitmapBGR888;
921 Bitmap.start_pos = 0;
922 Bitmap.bpp = 24;
923 Bitmap.pitch = DISP_GetScreenWidth()*3;
924 Bitmap.data_size = Bitmap.pitch * Bitmap.height;
925 Bitmap.down_sample_x = gCaptureOvlDownX;
926 Bitmap.down_sample_y = gCaptureOvlDownY;
927 Bitmap.pData = va[index];
928 MMProfileLogMetaBitmap(MTKFB_MMP_Events.OvlDump, MMProfileFlagPulse, &Bitmap);
929 index = 1 - index;
930 }
931 return 0;
932 }
933
934 void _DISP_DumpLayer(OVL_CONFIG_STRUCT* pLayer)
935 {
936 if (gCaptureLayerEnable && pLayer->layer_en)
937 {
938 MMP_MetaDataBitmap_t Bitmap;
939 Bitmap.data1 = pLayer->vaddr;
940 Bitmap.width = pLayer->dst_w;
941 Bitmap.height = pLayer->dst_h;
942 switch (pLayer->fmt)
943 {
944 case eRGB565: Bitmap.format = MMProfileBitmapRGB565; Bitmap.bpp = 16; break;
945 case eRGB888: Bitmap.format = MMProfileBitmapBGR888; Bitmap.bpp = 24; break;
946 case eARGB8888:
947 case ePARGB8888:
948 Bitmap.format = MMProfileBitmapBGRA8888; Bitmap.bpp = 32; break;
949 case eBGR888: Bitmap.format = MMProfileBitmapRGB888; Bitmap.bpp = 24; break;
950 case eABGR8888:
951 case ePABGR8888:
952 Bitmap.format = MMProfileBitmapRGBA8888; Bitmap.bpp = 32; break;
953 default: pr_info("error: _DISP_DumpLayer(), unknow format=%d \n", pLayer->fmt); return;
954 }
955 Bitmap.start_pos = 0;
956 Bitmap.pitch = pLayer->src_pitch;
957 Bitmap.data_size = Bitmap.pitch * Bitmap.height;
958 Bitmap.down_sample_x = gCaptureLayerDownX;
959 Bitmap.down_sample_y = gCaptureLayerDownY;
960 if (pLayer->addr >= fb_pa &&
961 pLayer->addr < (fb_pa+DISP_GetVRamSize()) &&
962 pLayer->vaddr != 0)
963 {
964 Bitmap.pData = (void*) pLayer->vaddr;
965 MMProfileLogMetaBitmap(MTKFB_MMP_Events.Layer[pLayer->layer], MMProfileFlagPulse, &Bitmap);
966 }
967 else
968 {
969 disphal_dma_map_kernel(pLayer->addr, Bitmap.data_size, (unsigned int*)&Bitmap.pData, &Bitmap.data_size);
970 MMProfileLogMetaBitmap(MTKFB_MMP_Events.Layer[pLayer->layer], MMProfileFlagPulse, &Bitmap);
971 disphal_dma_unmap_kernel(pLayer->addr, Bitmap.data_size, (unsigned int)Bitmap.pData);
972 }
973 }
974 }
975
976 static void _DISP_VSyncCallback(void* pParam);
977
978 void DISP_StartConfigUpdate(void)
979 {
980 //if(((LCM_TYPE_DSI == lcm_params->type) && (CMD_MODE == lcm_params->dsi.mode)) || (LCM_TYPE_DBI == lcm_params->type))
981 {
982 config_update_task_wakeup = 1;
983 wake_up_interruptible(&config_update_wq);
984 }
985 }
986
987 static int _DISP_ESD_Check(int* dirty)
988 {
989 unsigned int esd_check_count;
990 if (need_esd_check && (!is_early_suspended))
991 {
992 esd_check_count = 0;
993 disp_running = 1;
994 MMProfileLog(MTKFB_MMP_Events.EsdCheck, MMProfileFlagStart);
995 while (esd_check_count < LCM_ESD_CHECK_MAX_COUNT)
996 {
997 if(DISP_EsdCheck())
998 {
999 MMProfileLogEx(MTKFB_MMP_Events.EsdCheck, MMProfileFlagPulse, 0, 0);
1000 DISP_EsdRecover();
1001 }
1002 else
1003 {
1004 break;
1005 }
1006 /* [PLATFORM]-Mod-BEGIN by TCTSZ.yaohui.zeng, 2015/05/04, modify for ESD fast shoot*/
1007 //esd_check_count++;
1008 esd_check_count=1;
1009 /* [PLATFORM]-Mod-END by TCTSZ.yaohui.zeng, 2015/05/04*/
1010 }
1011 if (esd_check_count >= LCM_ESD_CHECK_MAX_COUNT)
1012 {
1013 MMProfileLogEx(MTKFB_MMP_Events.EsdCheck, MMProfileFlagPulse, 2, 0);
1014 esd_kthread_pause = TRUE;
1015 }
1016 if (esd_check_count)
1017 {
1018 disphal_update_screen(lcm_drv, &LcmCmdMutex, 0, 0, DISP_GetScreenWidth(), DISP_GetScreenHeight());
1019 *dirty = 1;
1020 }
1021 need_esd_check = 0;
1022 wake_up_interruptible(&esd_check_wq);
1023 MMProfileLog(MTKFB_MMP_Events.EsdCheck, MMProfileFlagEnd);
1024 return 1;
1025 }
1026 return 0;
1027 }
1028
1029 static int _DISP_ConfigUpdateKThread(void *data)
1030 {
1031 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1032 int i;
1033 #endif
1034 int dirty = 0;
1035 int overlay_dirty = 0;
1036 int aal_dirty = 0;
1037 int index = 0;
1038 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1039 int memout_dirty = 0;
1040 #endif
1041 struct disp_path_config_mem_out_struct mem_out_config;
1042 struct sched_param param = { .sched_priority = RTPM_PRIO_SCRN_UPDATE };
1043 sched_setscheduler(current, SCHED_RR, &param);
1044 while(1)
1045 {
1046 wait_event_interruptible(config_update_wq, config_update_task_wakeup);
1047 config_update_task_wakeup = 0;
1048 MMProfileLog(MTKFB_MMP_Events.UpdateConfig, MMProfileFlagStart);
1049 dirty = 0;
1050 overlay_dirty = 0;
1051 aal_dirty = 0;
1052
1053 if (down_interruptible(&sem_early_suspend)) {
1054 pr_info("[FB Driver] can't get semaphore in mtkfb_early_suspend()\n");
1055 continue;
1056 }
1057 //MMProfileLogEx(MTKFB_MMP_Events.EarlySuspend, MMProfileFlagStart, 1, 0);
1058
1059 if (!((lcm_params->type == LCM_TYPE_DSI) && (lcm_params->dsi.mode != CMD_MODE)))
1060 {
1061 if (_DISP_ESD_Check(&dirty))
1062 {
1063 disp_running = 0;
1064 }
1065 }
1066
1067 if (!is_early_suspended)
1068 {
1069 if (mutex_trylock(&OverlaySettingMutex))
1070 {
1071 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1072 overlay_dirty = atomic_read(&OverlaySettingDirtyFlag);
1073 if (overlay_dirty)
1074 {
1075 layer_config_index = 1 - layer_config_index;
1076 captured_layer_config = _layer_config[layer_config_index];
1077 DISP_LOG("========= cached --> captured ===========\n");
1078 memcpy(captured_layer_config, cached_layer_config, sizeof(OVL_CONFIG_STRUCT)*DDP_OVL_LAYER_MUN);
1079 for (i=0; i<DDP_OVL_LAYER_MUN; i++)
1080 cached_layer_config[i].isDirty = false;
1081 MMProfileLogStructure(MTKFB_MMP_Events.ConfigOVL, MMProfileFlagPulse, captured_layer_config, struct DBG_OVL_CONFIGS);
1082 atomic_set(&OverlaySettingDirtyFlag, 0);
1083 PanDispSettingDirty = 0;
1084 dirty = 1;
1085 }
1086 #else
1087 Disp_Ovl_Engine_Get_Dirty_info(mtkfb_instance, &overlay_dirty, &memout_dirty);
1088 if (overlay_dirty)
1089 {
1090 Disp_Ovl_Engine_Sync_Captured_layer_info(mtkfb_instance);
1091 }
1092 if ((overlay_dirty) || memout_dirty)
1093 {
1094 dirty = 1;
1095 MMProfileLogEx(MTKFB_MMP_Events.ConfigOVL, MMProfileFlagPulse, overlay_dirty, memout_dirty);
1096 }
1097 if (overlay_dirty)
1098 PanDispSettingDirty = 0;
1099 #endif
1100 mutex_unlock(&OverlaySettingMutex);
1101 }
1102 aal_dirty = overlay_dirty;//overlay refresh means AAL also needs refresh
1103 //GetUpdateMutex();
1104 if(1 == TryGetUpdateMutex())
1105 {
1106 for(index = 0 ; index < DISP_CB_MAXCNT ; index += 1)
1107 {
1108 if((NULL != g_CB_Array.checkupdate_cb[index]) && g_CB_Array.checkupdate_cb[index](overlay_dirty))
1109 {
1110 dirty = 1;
1111 aal_dirty = 1;
1112 break;
1113 }
1114 }
1115 ReleaseUpdateMutex();
1116 }
1117
1118 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1119 if (mutex_trylock(&MemOutSettingMutex))
1120 #endif
1121 {
1122 if (MemOutConfig.dirty)
1123 {
1124 memcpy(&mem_out_config, &MemOutConfig, sizeof(MemOutConfig));
1125 MemOutConfig.dirty = 0;
1126 dirty = 1;
1127 }
1128 else
1129 mem_out_config.dirty = 0;
1130 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1131 mutex_unlock(&MemOutSettingMutex);
1132 #endif
1133 }
1134 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1135 if (mem_out_config.dirty)
1136 {
1137 Disp_Ovl_Engine_Set_Overlayed_Buffer(mtkfb_instance, (struct disp_ovl_engine_config_mem_out_struct *)&mem_out_config);
1138 }
1139 #endif
1140 }
1141 if(((LCM_TYPE_DSI == lcm_params->type) && (CMD_MODE == lcm_params->dsi.mode)) || (LCM_TYPE_DBI == lcm_params->type))
1142 {
1143 _DISP_VSyncCallback(NULL);
1144 }
1145
1146 if (dirty)
1147 {
1148 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1149 // Apply AAL config here.
1150 if (aal_dirty)
1151 {
1152 MMProfileLog(MTKFB_MMP_Events.ConfigAAL, MMProfileFlagStart);
1153 if(1 == TryGetUpdateMutex())
1154 {
1155 for(index = 0 ; index < DISP_CB_MAXCNT ; index += 1)
1156 {
1157 if((NULL != g_CB_Array.checkupdate_cb[index]) && g_CB_Array.checkupdate_cb[index](overlay_dirty))
1158 {
1159 if (!overlay_dirty)
1160 disp_path_get_mutex();
1161 g_CB_Array.config_cb[index](overlay_dirty);
1162 if (!overlay_dirty)
1163 disp_path_release_mutex();
1164 }
1165 }
1166 ReleaseUpdateMutex();
1167 }
1168 MMProfileLog(MTKFB_MMP_Events.ConfigAAL, MMProfileFlagEnd);
1169 }
1170 if ((overlay_dirty) || (mem_out_config.dirty))
1171 {
1172 //pr_info("[OVL] overlay_dirty = %d, mem_out dirty = %d \n", overlay_dirty, mem_out_config.dirty);
1173 Disp_Ovl_Engine_Trigger_Overlay(mtkfb_instance);
1174 if ((lcm_params->type == LCM_TYPE_DBI) ||
1175 ((lcm_params->type == LCM_TYPE_DSI) && (lcm_params->dsi.mode == CMD_MODE)))
1176 {
1177 if ((PanDispSettingPending==1) && (PanDispSettingDirty==0))
1178 {
1179 PanDispSettingApplied = 1;
1180 PanDispSettingPending = 0;
1181 }
1182 atomic_set(&OverlaySettingApplied, 1);
1183 wake_up(&reg_update_wq);
1184 }
1185 }
1186 #if defined(MTK_HDMI_SUPPORT)
1187 if(is_hdmi_active() && !DISP_IsVideoMode())
1188 {
1189 MMProfileLogEx(MTKFB_MMP_Events.ConfigMemOut, MMProfileFlagStart, mem_out_config.enable, mem_out_config.dstAddr);
1190 memcpy(&mem_out_config, &MemOutConfig, sizeof(MemOutConfig));
1191 Disp_Ovl_Engine_Set_Overlayed_Buffer(mtkfb_instance, (struct disp_ovl_engine_config_mem_out_struct *)&mem_out_config);
1192 MMProfileLogEx(MTKFB_MMP_Events.ConfigMemOut, MMProfileFlagEnd, 1, 0);
1193 }
1194 #endif //defined(MTK_HDMI_SUPPORT)
1195 if ((lcm_params->type == LCM_TYPE_DBI) ||
1196 ((lcm_params->type == LCM_TYPE_DSI) && (lcm_params->dsi.mode == CMD_MODE)))
1197 {
1198 DISP_STATUS ret = _DISP_ConfigUpdateScreen(0, 0, DISP_GetScreenWidth(), DISP_GetScreenHeight());
1199 if ((ret != DISP_STATUS_OK) && (is_early_suspended == 0))
1200 hrtimer_start(&cmd_mode_update_timer, cmd_mode_update_timer_period, HRTIMER_MODE_REL);
1201 }
1202 #else
1203 // Apply configuration here.
1204 disp_running = 1;
1205 disp_path_get_mutex();
1206 if (overlay_dirty)
1207 {
1208 MMProfileLog(MTKFB_MMP_Events.ConfigOVL, MMProfileFlagStart);
1209 for (i=0; i<DDP_OVL_LAYER_MUN; i++)
1210 {
1211 if (captured_layer_config[i].isDirty)
1212 {
1213 _DISP_DumpLayer(&captured_layer_config[i]);
1214 disp_path_config_layer(&captured_layer_config[i]);
1215 captured_layer_config[i].isDirty = false;
1216 }
1217 }
1218 if ((lcm_params->type == LCM_TYPE_DBI) ||
1219 ((lcm_params->type == LCM_TYPE_DSI) && (lcm_params->dsi.mode == CMD_MODE)))
1220 {
1221 if ((PanDispSettingPending==1) && (PanDispSettingDirty==0))
1222 {
1223 PanDispSettingApplied = 1;
1224 PanDispSettingPending = 0;
1225 }
1226 atomic_set(&OverlaySettingApplied, 1);
1227 wake_up(&reg_update_wq);
1228 }
1229 MMProfileLog(MTKFB_MMP_Events.ConfigOVL, MMProfileFlagEnd);
1230
1231
1232 }
1233
1234 // Apply AAL config here.
1235 if (aal_dirty)
1236 {
1237 MMProfileLog(MTKFB_MMP_Events.ConfigAAL, MMProfileFlagStart);
1238
1239 //GetUpdateMutex();
1240 if(1 == TryGetUpdateMutex())
1241 {
1242 for(index = 0 ; index < DISP_CB_MAXCNT ; index += 1)
1243 {
1244 if((NULL != g_CB_Array.checkupdate_cb[index]) && g_CB_Array.checkupdate_cb[index](overlay_dirty))
1245 {
1246 g_CB_Array.config_cb[index](overlay_dirty);
1247 }
1248 }
1249 ReleaseUpdateMutex();
1250 }
1251 MMProfileLog(MTKFB_MMP_Events.ConfigAAL, MMProfileFlagEnd);
1252 }
1253
1254 // Apply memory out config here.
1255 if (mem_out_config.dirty)
1256 {
1257 MMProfileLogEx(MTKFB_MMP_Events.ConfigMemOut, MMProfileFlagStart, mem_out_config.enable, mem_out_config.dstAddr);
1258 disp_path_config_mem_out(&mem_out_config);
1259 MMProfileLogEx(MTKFB_MMP_Events.ConfigMemOut, MMProfileFlagEnd, 0, 0);
1260 }
1261 #if defined(MTK_HDMI_SUPPORT)
1262 if(is_hdmi_active() && !DISP_IsVideoMode())
1263 {
1264 MMProfileLogEx(MTKFB_MMP_Events.ConfigMemOut, MMProfileFlagStart, mem_out_config.enable, mem_out_config.dstAddr);
1265 memcpy(&mem_out_config, &MemOutConfig, sizeof(MemOutConfig));
1266 disp_path_config_mem_out(&mem_out_config);
1267 MMProfileLogEx(MTKFB_MMP_Events.ConfigMemOut, MMProfileFlagEnd, 1, 0);
1268 }
1269 #endif
1270 // Trigger interface engine for cmd mode.
1271 if ((lcm_params->type == LCM_TYPE_DBI) ||
1272 ((lcm_params->type == LCM_TYPE_DSI) && (lcm_params->dsi.mode == CMD_MODE)))
1273 {
1274 DISP_STATUS ret = _DISP_ConfigUpdateScreen(0, 0, DISP_GetScreenWidth(), DISP_GetScreenHeight());
1275 if ((ret != DISP_STATUS_OK) && (is_early_suspended == 0))
1276 hrtimer_start(&cmd_mode_update_timer, cmd_mode_update_timer_period, HRTIMER_MODE_REL);
1277 }
1278 disp_path_release_mutex();
1279 #endif //MTK_OVERLAY_ENGINE_SUPPORT
1280 }
1281 else
1282 {
1283 if ((lcm_params->type == LCM_TYPE_DBI) ||
1284 ((lcm_params->type == LCM_TYPE_DSI) && (lcm_params->dsi.mode == CMD_MODE)))
1285 {
1286 // Start update timer.
1287 if (!is_early_suspended)
1288 {
1289 if (is_immediateupdate)
1290 hrtimer_start(&cmd_mode_update_timer, ktime_set(0 , 5000000), HRTIMER_MODE_REL);
1291 else
1292 hrtimer_start(&cmd_mode_update_timer, cmd_mode_update_timer_period, HRTIMER_MODE_REL);
1293 }
1294 }
1295 }
1296 if ((lcm_params->type == LCM_TYPE_DSI) && (lcm_params->dsi.mode != CMD_MODE))
1297 {
1298 if (_DISP_ESD_Check(&dirty))
1299 {
1300 disp_running = 1;
1301 }
1302 }
1303
1304 MMProfileLog(MTKFB_MMP_Events.UpdateConfig, MMProfileFlagEnd);
1305 //MMProfileLogEx(MTKFB_MMP_Events.EarlySuspend, MMProfileFlagEnd, 1, 0);
1306 up(&sem_early_suspend);
1307 if (kthread_should_stop())
1308 break;
1309 }
1310
1311 return 0;
1312 }
1313
1314 static void _DISP_HWDoneCallback(void* pParam)
1315 {
1316 MMProfileLogEx(MTKFB_MMP_Events.DispDone, MMProfileFlagPulse, is_early_suspended, 0);
1317 disp_running = 0;
1318 wake_up_interruptible(&disp_done_wq);
1319 }
1320
1321 static void _DISP_VSyncCallback(void* pParam)
1322 {
1323 MMProfileLog(MTKFB_MMP_Events.VSync, MMProfileFlagPulse);
1324 vsync_wq_flag = 1;
1325 wake_up_interruptible(&vsync_wq);
1326 }
1327
1328 static void _DISP_RegUpdateCallback(void* pParam)
1329 {
1330 MMProfileLog(MTKFB_MMP_Events.RegUpdate, MMProfileFlagPulse);
1331 DISP_LOG("========= captured --> realtime ===========\n");
1332 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1333 Disp_Ovl_Engine_Sync_Realtime_layer_info(mtkfb_instance);
1334 #else
1335 realtime_layer_config = captured_layer_config;
1336 #endif
1337 if ((lcm_params->type == LCM_TYPE_DPI) ||
1338 ((lcm_params->type == LCM_TYPE_DSI) && (lcm_params->dsi.mode != CMD_MODE)))
1339 {
1340 if ((PanDispSettingPending==1) && (PanDispSettingDirty==0))
1341 {
1342 PanDispSettingApplied = 1;
1343 PanDispSettingPending = 0;
1344 }
1345 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1346 atomic_set(&OverlaySettingApplied, 1);
1347 #endif
1348 }
1349 gWakeupCaptureOvlThread = 1;
1350 wake_up(&reg_update_wq);
1351 }
1352
1353 static void _DISP_TargetLineCallback(void* pParam)
1354 {
1355 //tasklet_hi_schedule(&ConfigUpdateTask);
1356 MMProfileLogEx(MTKFB_MMP_Events.UpdateConfig, MMProfileFlagPulse, 0, 0);
1357 config_update_task_wakeup = 1;
1358 wake_up_interruptible(&config_update_wq);
1359 }
1360
1361 static void _DISP_CmdDoneCallback(void* pParam)
1362 {
1363 //tasklet_hi_schedule(&ConfigUpdateTask);
1364 MMProfileLogEx(MTKFB_MMP_Events.UpdateConfig, MMProfileFlagPulse, 1, 0);
1365 config_update_task_wakeup = 1;
1366 wake_up_interruptible(&config_update_wq);
1367 _DISP_HWDoneCallback(NULL);
1368 }
1369
1370 static enum hrtimer_restart _DISP_CmdModeTimer_handler(struct hrtimer *timer)
1371 {
1372 MMProfileLogEx(MTKFB_MMP_Events.UpdateConfig, MMProfileFlagPulse, 2, 0);
1373 config_update_task_wakeup = 1;
1374 wake_up_interruptible(&config_update_wq);
1375 return HRTIMER_NORESTART;
1376 }
1377
1378 void DISP_InitVSYNC(unsigned int vsync_interval)
1379 {
1380 init_waitqueue_head(&config_update_wq);
1381 init_waitqueue_head(&vsync_wq);
1382 config_update_task = kthread_create(
1383 _DISP_ConfigUpdateKThread, NULL, "disp_config_update_kthread");
1384
1385 if (IS_ERR(config_update_task))
1386 {
1387 DISP_LOG("DISP_InitVSYNC(): Cannot create config update kthread\n");
1388 return;
1389 }
1390 wake_up_process(config_update_task);
1391
1392 disphal_register_event("DISP_CmdDone", _DISP_CmdDoneCallback);
1393 disphal_register_event("DISP_RegUpdate", _DISP_RegUpdateCallback);
1394 disphal_register_event("DISP_VSync", _DISP_VSyncCallback);
1395 disphal_register_event("DISP_TargetLine", _DISP_TargetLineCallback);
1396 disphal_register_event("DISP_HWDone", _DISP_HWDoneCallback);
1397 if ((LCM_TYPE_DBI == lcm_params->type) ||
1398 ((LCM_TYPE_DSI == lcm_params->type) && (CMD_MODE == lcm_params->dsi.mode)))
1399 {
1400 cmd_mode_update_timer_period = ktime_set(0 , vsync_interval*1000);
1401 hrtimer_init(&cmd_mode_update_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
1402 cmd_mode_update_timer.function = _DISP_CmdModeTimer_handler;
1403 config_update_task_wakeup = 1;
1404 wake_up_interruptible(&config_update_wq);
1405 }
1406
1407 }
1408
1409 void DISP_WaitVSYNC(void)
1410 {
1411 MMProfileLog(MTKFB_MMP_Events.WaitVSync, MMProfileFlagStart);
1412 vsync_wq_flag = 0;
1413 if (wait_event_interruptible_timeout(vsync_wq, vsync_wq_flag, HZ/10) == 0)
1414 {
1415 pr_info("[DISP] Wait VSync timeout. early_suspend=%d\n", is_early_suspended);
1416 }
1417 MMProfileLog(MTKFB_MMP_Events.WaitVSync, MMProfileFlagEnd);
1418 }
1419
1420 DISP_STATUS DISP_PauseVsync(BOOL enable)
1421 {
1422 if((LCM_TYPE_DBI == lcm_params->type) ||
1423 (LCM_TYPE_DSI == lcm_params->type && lcm_params->dsi.mode == CMD_MODE))
1424 {
1425 if (enable)
1426 hrtimer_cancel(&cmd_mode_update_timer);
1427 }
1428 else if((LCM_TYPE_DPI == lcm_params->type) ||
1429 (LCM_TYPE_DSI == lcm_params->type && lcm_params->dsi.mode != CMD_MODE))
1430 {
1431 }
1432 else
1433 {
1434 DISP_LOG("DISP_PauseVSYNC():unknown interface\n");
1435 }
1436 return DISP_STATUS_OK;
1437 }
1438
1439 DISP_STATUS DISP_ConfigDither(int lrs, int lgs, int lbs, int dbr, int dbg, int dbb)
1440 {
1441 DISP_LOG("DISP_ConfigDither lrs:0x%x, lgs:0x%x, lbs:0x%x, dbr:0x%x, dbg:0x%x, dbb:0x%x \n", lrs, lgs, lbs, dbr, dbg, dbb);
1442
1443 return DISP_STATUS_OK;
1444 }
1445
1446
1447 // ---------------------------------------------------------------------------
1448 // Retrieve Information
1449 // ---------------------------------------------------------------------------
1450
1451 BOOL DISP_IsVideoMode(void)
1452 {
1453 disp_drv_init_context();
1454 if(lcm_params)
1455 return lcm_params->type==LCM_TYPE_DPI || (lcm_params->type==LCM_TYPE_DSI && lcm_params->dsi.mode != CMD_MODE);
1456 else
1457 {
1458 pr_info("WARNING!! DISP_IsVideoMode is called before display driver inited!\n");
1459 return 0;
1460 }
1461 }
1462
1463 UINT32 DISP_GetScreenWidth(void)
1464 {
1465 disp_drv_init_context();
1466 if(lcm_params)
1467 return lcm_params->width;
1468 else
1469 {
1470 pr_info("WARNING!! get screen width before display driver inited!\n");
1471 return 0;
1472 }
1473 }
1474 EXPORT_SYMBOL(DISP_GetScreenWidth);
1475
1476 UINT32 DISP_GetScreenHeight(void)
1477 {
1478 disp_drv_init_context();
1479 if(lcm_params)
1480 return lcm_params->height;
1481 else
1482 {
1483 pr_info("WARNING!! get screen height before display driver inited!\n");
1484 return 0;
1485 }
1486 }
1487 UINT32 DISP_GetActiveHeight(void)
1488 {
1489 disp_drv_init_context();
1490 if(lcm_params)
1491 {
1492 pr_info("[wwy]lcm_parms->active_height = %d\n",lcm_params->physical_height);
1493 return lcm_params->physical_height;
1494 }
1495 else
1496 {
1497 pr_info("WARNING!! get physical_height before display driver inited!\n");
1498 return 0;
1499 }
1500 }
1501
1502 UINT32 DISP_GetActiveWidth(void)
1503 {
1504 disp_drv_init_context();
1505 if(lcm_params)
1506 {
1507 pr_info("[wwy]lcm_parms->active_width = %d\n",lcm_params->physical_width);
1508 return lcm_params->physical_width;
1509 }
1510 else
1511 {
1512 pr_info("WARNING!! get physical_width before display driver inited!\n");
1513 return 0;
1514 }
1515 }
1516
1517 DISP_STATUS DISP_SetScreenBpp(UINT32 bpp)
1518 {
1519 ASSERT(bpp != 0);
1520
1521 if( bpp != 16 && \
1522 bpp != 24 && \
1523 bpp != 32 && \
1524 1 )
1525 {
1526 DISP_LOG("DISP_SetScreenBpp error, not support %d bpp\n", bpp);
1527 return DISP_STATUS_ERROR;
1528 }
1529
1530 disp_fb_bpp = bpp;
1531 DISP_LOG("DISP_SetScreenBpp %d bpp\n", bpp);
1532
1533 return DISP_STATUS_OK;
1534 }
1535
1536 UINT32 DISP_GetScreenBpp(void)
1537 {
1538 return disp_fb_bpp;
1539 }
1540
1541 DISP_STATUS DISP_SetPages(UINT32 pages)
1542 {
1543 ASSERT(pages != 0);
1544
1545 disp_fb_pages = pages;
1546 DISP_LOG("DISP_SetPages %d pages\n", pages);
1547
1548 return DISP_STATUS_OK;
1549 }
1550
1551 UINT32 DISP_GetPages(void)
1552 {
1553 return disp_fb_pages; // Double Buffers
1554 }
1555
1556
1557 BOOL DISP_IsDirectLinkMode(void)
1558 {
1559 return (-1 != direct_link_layer) ? TRUE : FALSE;
1560 }
1561
1562
1563 BOOL DISP_IsInOverlayMode(void)
1564 {
1565 return is_overlaying;
1566 }
1567
1568 UINT32 DISP_GetFBRamSize(void)
1569 {
1570 return ALIGN_TO(DISP_GetScreenWidth(), disphal_get_fb_alignment()) *
1571 ALIGN_TO(DISP_GetScreenHeight(), disphal_get_fb_alignment()) *
1572 ((DISP_GetScreenBpp() + 7) >> 3) *
1573 DISP_GetPages();
1574 }
1575
1576 #define MAX_BUFFER_COUNT 4
1577 #define BPP 3
1578
1579 /**
1580 * eRGB888 triple buffer for 0VL->WDMA->MEM, MEM->RDMA->LCM
1581 */
1582 UINT32 DISP_GetOVLRamSize(void)
1583 {
1584 return ALIGN_TO(DISP_GetScreenWidth(), disphal_get_fb_alignment()) *
1585 ALIGN_TO(DISP_GetScreenHeight(), disphal_get_fb_alignment()) *
1586 MAX_BUFFER_COUNT * BPP;
1587 }
1588
1589 UINT32 DISP_GetVRamSize(void)
1590 {
1591 // Use a local static variable to cache the calculated vram size
1592 //
1593 static UINT32 vramSize = 0;
1594
1595 if (0 == vramSize)
1596 {
1597 disp_drv_init_context();
1598
1599 ///get framebuffer size
1600 vramSize = DISP_GetFBRamSize();
1601
1602 ///get DXI working buffer size
1603 vramSize += disp_if_drv->get_working_buffer_size();
1604
1605 // get assertion layer buffer size
1606 vramSize += DAL_GetLayerSize();
1607
1608 // get ovl-wdma buffer size
1609 vramSize += DISP_GetOVLRamSize();
1610
1611 // Align vramSize to 1MB
1612 //
1613 vramSize = ALIGN_TO_POW_OF_2(vramSize, 0x100000);
1614
1615 DISP_LOG("DISP_GetVRamSize: %u bytes\n", vramSize);
1616 }
1617
1618 return vramSize;
1619 }
1620
1621 UINT32 DISP_GetVRamSizeBoot(char *cmdline)
1622 {
1623 static UINT32 vramSize = 0;
1624
1625 if(vramSize)
1626 {
1627 return vramSize;
1628 }
1629
1630 disp_get_lcm_name_boot(cmdline);
1631
1632 // if can't get the lcm type from uboot, we will return 0x800000 for a safe value
1633 if(disp_if_drv)
1634 vramSize = DISP_GetVRamSize();
1635 else
1636 {
1637 pr_info("%s, can't get lcm type, reserved memory size will be set as 0x800000\n", __func__);
1638 return 0x1400000;
1639 }
1640 // Align vramSize to 1MB
1641 //
1642 vramSize = ALIGN_TO_POW_OF_2(vramSize, 0x100000);
1643
1644 pr_info("DISP_GetVRamSizeBoot: %u bytes[%dMB]\n", vramSize, (vramSize>>20));
1645
1646 return vramSize;
1647 }
1648
1649 PANEL_COLOR_FORMAT DISP_GetPanelColorFormat(void)
1650 {
1651 disp_drv_init_context();
1652
1653 return (disp_if_drv->get_panel_color_format) ?
1654 (disp_if_drv->get_panel_color_format()) :
1655 DISP_STATUS_NOT_IMPLEMENTED;
1656 }
1657
1658 UINT32 DISP_GetPanelBPP(void)
1659 {
1660 PANEL_COLOR_FORMAT fmt;
1661 disp_drv_init_context();
1662
1663 if(disp_if_drv->get_panel_color_format == NULL)
1664 {
1665 return DISP_STATUS_NOT_IMPLEMENTED;
1666 }
1667
1668 fmt = disp_if_drv->get_panel_color_format();
1669 switch(fmt)
1670 {
1671 case PANEL_COLOR_FORMAT_RGB332:
1672 return 8;
1673 case PANEL_COLOR_FORMAT_RGB444:
1674 return 12;
1675 case PANEL_COLOR_FORMAT_RGB565:
1676 return 16;
1677 case PANEL_COLOR_FORMAT_RGB666:
1678 return 18;
1679 case PANEL_COLOR_FORMAT_RGB888:
1680 return 24;
1681 default:
1682 return 0;
1683 }
1684 }
1685
1686 UINT32 DISP_GetOutputBPPforDithering(void)
1687 {
1688 disp_drv_init_context();
1689
1690 return (disp_if_drv->get_dithering_bpp) ?
1691 (disp_if_drv->get_dithering_bpp()) :
1692 DISP_STATUS_NOT_IMPLEMENTED;
1693 }
1694
1695 DISP_STATUS DISP_Config_Overlay_to_Memory(unsigned int mva, int enable)
1696 {
1697 int wait_ret = 0;
1698
1699 // struct disp_path_config_mem_out_struct mem_out = {0};
1700
1701 if(enable)
1702 {
1703 MemOutConfig.outFormat = eRGB888;
1704
1705 MemOutConfig.enable = 1;
1706 MemOutConfig.dstAddr = mva;
1707 MemOutConfig.srcROI.x = 0;
1708 MemOutConfig.srcROI.y = 0;
1709 MemOutConfig.srcROI.height= DISP_GetScreenHeight();
1710 MemOutConfig.srcROI.width= DISP_GetScreenWidth();
1711
1712 #if !defined(MTK_HDMI_SUPPORT)
1713 mutex_lock(&MemOutSettingMutex);
1714 MemOutConfig.dirty = 1;
1715 mutex_unlock(&MemOutSettingMutex);
1716 #endif
1717 }
1718 else
1719 {
1720 MemOutConfig.outFormat = eRGB888;
1721 MemOutConfig.enable = 0;
1722 MemOutConfig.dstAddr = mva;
1723 MemOutConfig.srcROI.x = 0;
1724 MemOutConfig.srcROI.y = 0;
1725 MemOutConfig.srcROI.height= DISP_GetScreenHeight();
1726 MemOutConfig.srcROI.width= DISP_GetScreenWidth();
1727
1728 mutex_lock(&MemOutSettingMutex);
1729 MemOutConfig.dirty = 1;
1730 mutex_unlock(&MemOutSettingMutex);
1731
1732 // Wait for reg update.
1733 wait_ret = wait_event_interruptible(reg_update_wq, !MemOutConfig.dirty);
1734 DISP_LOG("[WaitQ] wait_event_interruptible() ret = %d, %d\n", wait_ret, __LINE__);
1735 }
1736
1737 return DISP_STATUS_OK;
1738 }
1739
1740
1741 DISP_STATUS DISP_Capture_Framebuffer( unsigned int pvbuf, unsigned int bpp, unsigned int is_early_suspended )
1742 {
1743 unsigned int mva;
1744 unsigned int ret = 0;
1745 int wait_ret = 0;
1746 int i = 0; // temp fix for build error !!!!!!
1747 BOOL deinit_o2m = TRUE;
1748
1749 DISP_FUNC();
1750 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1751 for (i=0; i<DDP_OVL_LAYER_MUN; i++)
1752 {
1753 if (disp_ovl_engine.Instance[mtkfb_instance].cached_layer_config[i].layer_en &&
1754 disp_ovl_engine.Instance[mtkfb_instance].cached_layer_config[i].security)
1755 break;
1756 }
1757 #else
1758 for (i=0; i<DDP_OVL_LAYER_MUN; i++)
1759 {
1760 if (cached_layer_config[i].layer_en && cached_layer_config[i].security)
1761 break;
1762 }
1763 #endif
1764 if (i < DDP_OVL_LAYER_MUN || is_early_suspended == 1)
1765 {
1766 // There is security layer.
1767 memset((void*)pvbuf, 0, DISP_GetScreenHeight()*DISP_GetScreenWidth()*bpp/8);
1768 return DISP_STATUS_OK;
1769 }
1770 disp_drv_init_context();
1771
1772 MMProfileLogEx(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagPulse, 0, pvbuf);
1773 MMProfileLogEx(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagPulse, 1, bpp);\
1774
1775 ret = disphal_map_overlay_out_buffer(pvbuf, DISP_GetScreenHeight()*DISP_GetScreenWidth()*bpp/8, &mva);
1776 if(ret!=0)
1777 {
1778 pr_info("disphal_map_overlay_out_buffer fail! \n");
1779 return DISP_STATUS_OK;
1780 }
1781 disphal_init_overlay_to_memory();
1782
1783 mutex_lock(&MemOutSettingMutex);
1784 if(bpp == 32)
1785 MemOutConfig.outFormat = eARGB8888;
1786 else if(bpp == 16)
1787 MemOutConfig.outFormat = eRGB565;
1788 else if(bpp == 24)
1789 MemOutConfig.outFormat = eRGB888;
1790 else
1791 {
1792 pr_info("DSI_Capture_FB, fb color format not support\n");
1793 MemOutConfig.outFormat = eRGB888;
1794 }
1795
1796 MemOutConfig.enable = 1;
1797 MemOutConfig.dstAddr = mva;
1798 MemOutConfig.srcROI.x = 0;
1799 MemOutConfig.srcROI.y = 0;
1800 MemOutConfig.srcROI.height= DISP_GetScreenHeight();
1801 MemOutConfig.srcROI.width= DISP_GetScreenWidth();
1802
1803 DISP_LOG("DISP_Capture_Framebuffer, dst addr pvbuf: 0x%x, bpp: %d\n", pvbuf, bpp);
1804
1805 if (is_early_suspended == 0)
1806 {
1807 disp_path_clear_mem_out_done_flag(); // clear last time mem_out_done flag
1808 MemOutConfig.dirty = 1;
1809 }
1810
1811 mutex_unlock(&MemOutSettingMutex);
1812 MMProfileLogEx(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagPulse, 2, mva);
1813 if (is_early_suspended)
1814 {
1815 disp_path_get_mutex();
1816 disp_path_config_mem_out_without_lcd(&MemOutConfig);
1817 disp_path_release_mutex();
1818 // Wait for mem out done.
1819 disp_path_wait_mem_out_done();
1820 MMProfileLogEx(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagPulse, 3, 0);
1821 MemOutConfig.enable = 0;
1822 disp_path_get_mutex();
1823 disp_path_config_mem_out_without_lcd(&MemOutConfig);
1824 disp_path_release_mutex();
1825 }
1826 else
1827 {
1828 MMP_MetaDataBitmap_t Bitmap;
1829
1830 // Wait for mem out done.
1831 disp_path_wait_mem_out_done();
1832 MMProfileLogEx(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagPulse, 3, 0);
1833 DISP_LOG("DISP_Capture_Framebuffer, mem out done\n");
1834
1835 Bitmap.data1 = DISP_GetScreenWidth();
1836 Bitmap.data2 = DISP_GetScreenHeight();
1837 Bitmap.width = DISP_GetScreenWidth();
1838 Bitmap.height = DISP_GetScreenHeight();
1839 Bitmap.format = MMProfileBitmapRGBA8888;
1840 Bitmap.start_pos = 0;
1841 Bitmap.pitch = DISP_GetScreenWidth()*bpp/8;
1842 Bitmap.data_size = Bitmap.pitch * Bitmap.height;
1843 Bitmap.down_sample_x = 10;
1844 Bitmap.down_sample_y = 10;
1845 Bitmap.pData = pvbuf;
1846 Bitmap.bpp = 32;
1847 MMProfileLogMetaBitmap(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagPulse, &Bitmap);
1848
1849 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1850 mutex_lock(&MemOutSettingMutex);
1851 MemOutConfig.enable = 0;
1852 MemOutConfig.dirty = 1;
1853 mutex_unlock(&MemOutSettingMutex);
1854 // Wait for reg update.
1855 wait_ret = wait_event_interruptible(reg_update_wq, !MemOutConfig.dirty);
1856 DISP_LOG("[WaitQ] wait_event_interruptible() ret = %d, %d\n", wait_ret, __LINE__);
1857 MMProfileLogEx(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagPulse, 4, 0);
1858 #else
1859 MemOutConfig.enable = 0;
1860 disp_path_config_mem_out(&MemOutConfig);
1861 #endif
1862
1863 DISP_LOG("DISP_Capture_Framebuffer, reg update done\n");
1864 }
1865
1866 disphal_unmap_overlay_out_buffer(pvbuf, DISP_GetScreenHeight()*DISP_GetScreenWidth()*bpp/8, mva);
1867
1868 return DISP_STATUS_OK;
1869 }
1870
1871 // xuecheng, 2010-09-19
1872 // this api is for mATV signal interfere workaround.
1873 // immediate update == (TE disabled + delay update in overlay mode disabled)
1874 DISP_STATUS DISP_ConfigImmediateUpdate(BOOL enable)
1875 {
1876 disp_drv_init_context();
1877 if(enable == TRUE)
1878 {
1879 disphal_enable_te(FALSE);
1880 }
1881 else
1882 {
1883 if(disp_if_drv->init_te_control)
1884 disp_if_drv->init_te_control();
1885 else
1886 return DISP_STATUS_NOT_IMPLEMENTED;
1887 }
1888
1889 is_immediateupdate = enable;
1890
1891 return DISP_STATUS_OK;
1892 }
1893
1894 BOOL DISP_IsImmediateUpdate(void)
1895 {
1896 return is_immediateupdate;
1897 }
1898
1899
1900 DISP_STATUS DISP_Get_Default_UpdateSpeed(unsigned int *speed)
1901 {
1902 return disphal_get_default_updatespeed(speed);
1903 }
1904
1905 DISP_STATUS DISP_Get_Current_UpdateSpeed(unsigned int *speed)
1906 {
1907 return disphal_get_current_updatespeed(speed);
1908 }
1909
1910 DISP_STATUS DISP_Change_Update(unsigned int speed)
1911 {
1912 DISP_STATUS ret = DISP_STATUS_OK;
1913
1914 if (down_interruptible(&sem_update_screen)) {
1915 DISP_LOG("ERROR: Can't get sem_update_screen in DISP_Change_Update()\n");
1916 return DISP_STATUS_ERROR;
1917 }
1918
1919 ret = disphal_change_updatespeed(speed);
1920
1921 up(&sem_update_screen);
1922
1923 return ret;
1924 }
1925
1926
1927 const char* DISP_GetLCMId(void)
1928 {
1929 if(lcm_drv)
1930 return lcm_drv->name;
1931 else
1932 return NULL;
1933 }
1934
1935
1936 BOOL DISP_EsdCheck(void)
1937 {
1938 BOOL result = FALSE;
1939
1940 disp_drv_init_context();
1941 MMProfileLogEx(MTKFB_MMP_Events.EsdCheck, MMProfileFlagPulse, 0x10, 0);
1942
1943 if(lcm_drv->esd_check == NULL && disp_if_drv->esd_check == NULL)
1944 {
1945 return FALSE;
1946 }
1947
1948 if (down_interruptible(&sem_update_screen)) {
1949 pr_info("ERROR: Can't get sem_update_screen in DISP_EsdCheck()\n");
1950 return FALSE;
1951 }
1952 MMProfileLogEx(MTKFB_MMP_Events.EsdCheck, MMProfileFlagPulse, 0x11, 0);
1953
1954 if(is_lcm_in_suspend_mode)
1955 {
1956 up(&sem_update_screen);
1957 return FALSE;
1958 }
1959
1960 if(disp_if_drv->esd_check)
1961 result |= disp_if_drv->esd_check();
1962 MMProfileLogEx(MTKFB_MMP_Events.EsdCheck, MMProfileFlagPulse, 0x12, 0);
1963
1964 up(&sem_update_screen);
1965
1966 return result;
1967 }
1968
1969
1970 BOOL DISP_EsdRecoverCapbility(void)
1971 {
1972 if(!disp_drv_init_context())
1973 return FALSE;
1974
1975 if((lcm_drv->esd_check && lcm_drv->esd_recover) || (lcm_params->dsi.lcm_ext_te_monitor) || (lcm_params->dsi.lcm_int_te_monitor))
1976 {
1977 return TRUE;
1978 }
1979 else
1980 {
1981 return FALSE;
1982 }
1983 }
1984
1985 BOOL DISP_EsdRecover(void)
1986 {
1987 BOOL result = FALSE;
1988 DISP_LOG("DISP_EsdRecover enter");
1989
1990 if(lcm_drv->esd_recover == NULL)
1991 {
1992 return FALSE;
1993 }
1994
1995 if (down_interruptible(&sem_update_screen)) {
1996 pr_info("ERROR: Can't get sem_update_screen in DISP_EsdRecover()\n");
1997 return FALSE;
1998 }
1999
2000 if(is_lcm_in_suspend_mode)
2001 {
2002 up(&sem_update_screen);
2003 return FALSE;
2004 }
2005
2006 disphal_wait_not_busy();
2007
2008 DISP_LOG("DISP_EsdRecover do LCM recover");
2009
2010 // do necessary configuration reset for LCM re-init
2011 if(disp_if_drv->esd_reset)
2012 disp_if_drv->esd_reset();
2013
2014 /// LCM recover
2015 mutex_lock(&LcmCmdMutex);
2016 result = lcm_drv->esd_recover();
2017 mutex_unlock(&LcmCmdMutex);
2018
2019 if ((lcm_params->type == LCM_TYPE_DSI) && (lcm_params->dsi.mode != CMD_MODE))
2020 {
2021 is_video_mode_running = false;
2022 needStartEngine = true;
2023 }
2024
2025 up(&sem_update_screen);
2026
2027 return result;
2028 }
2029
2030 unsigned long DISP_GetLCMIndex(void)
2031 {
2032 return u4IndexOfLCMList;
2033 }
2034
2035 DISP_STATUS DISP_PrepareSuspend(void)
2036 {
2037 disphal_prepare_suspend();
2038 return DISP_STATUS_OK;
2039 }
2040
2041 DISP_STATUS DISP_GetLayerInfo(DISP_LAYER_INFO *pLayer)
2042 {
2043 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
2044 int id = pLayer->id;
2045 #endif
2046 mutex_lock(&OverlaySettingMutex);
2047 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
2048 Disp_Ovl_Engine_Get_Ovl_layer_info(mtkfb_instance, pLayer);
2049 #else
2050 pLayer->curr_en = captured_layer_config[id].layer_en;
2051 pLayer->next_en = cached_layer_config[id].layer_en;
2052 pLayer->hw_en = realtime_layer_config[id].layer_en;
2053 pLayer->curr_idx = captured_layer_config[id].buff_idx;
2054 pLayer->next_idx = cached_layer_config[id].buff_idx;
2055 pLayer->hw_idx = realtime_layer_config[id].buff_idx;
2056 pLayer->curr_identity = captured_layer_config[id].identity;
2057 pLayer->next_identity = cached_layer_config[id].identity;
2058 pLayer->hw_identity = realtime_layer_config[id].identity;
2059 pLayer->curr_conn_type = captured_layer_config[id].connected_type;
2060 pLayer->next_conn_type = cached_layer_config[id].connected_type;
2061 pLayer->hw_conn_type = realtime_layer_config[id].connected_type;
2062 #endif
2063 mutex_unlock(&OverlaySettingMutex);
2064 return DISP_STATUS_OK;
2065 }
2066 void DISP_Change_LCM_Resolution(unsigned int width, unsigned int height)
2067 {
2068 if(lcm_params)
2069 {
2070 pr_info("LCM Resolution will be changed, original: %dx%d, now: %dx%d\n", lcm_params->width, lcm_params->height, width, height);
2071 if(width >lcm_params->width || height > lcm_params->height || width == 0 || height == 0)
2072 pr_info("Invalid resolution: %dx%d\n", width, height);
2073 lcm_params->width = width;
2074 lcm_params->height = height;
2075 }
2076 }
2077
2078 BOOL DISP_IsDecoupleMode(void)
2079 {
2080 BOOL ret = false;
2081
2082 return ret;
2083 }
2084