1 #include <linux/delay.h>
4 #include <asm/uaccess.h>
8 #include "disp_drv_log.h"
12 #include <linux/disp_assert_layer.h>
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"
29 extern unsigned int lcd_fps
;
30 extern BOOL is_early_suspended
;
31 extern struct semaphore sem_early_suspend
;
33 extern unsigned int EnableVSyncLog
;
35 #define LCM_ESD_CHECK_MAX_COUNT 5
37 #define ALIGN_TO(x, n) \
38 (((x) + ((n) - 1)) & ~((n) - 1))
41 //#define pr_info printk
43 // ---------------------------------------------------------------------------
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
;
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
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
;
60 static unsigned long u4IndexOfLCMList
= 0;
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
;
71 extern unsigned int fb_pa
;
73 extern bool is_ipoh_bootup
;
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;
80 static struct hrtimer cmd_mode_update_timer
;
81 static ktime_t cmd_mode_update_timer_period
;
83 static bool needStartEngine
= true;
85 extern unsigned int need_esd_check
;
86 extern wait_queue_head_t esd_check_wq
;
87 extern BOOL esd_kthread_pause
;
89 DEFINE_MUTEX(MemOutSettingMutex
);
90 static struct disp_path_config_mem_out_struct MemOutConfig
;
91 static BOOL is_immediateupdate
= false;
93 DEFINE_MUTEX(LcmCmdMutex
);
95 unsigned int disp_running
= 0;
96 DECLARE_WAIT_QUEUE_HEAD(disp_done_wq
);
98 #if 1//!defined(MTK_OVERLAY_ENGINE_SUPPORT)
99 OVL_CONFIG_STRUCT cached_layer_config
[DDP_OVL_LAYER_MUN
] =
101 {.layer
= 0, .isDirty
= 1},
102 {.layer
= 1, .isDirty
= 1},
103 {.layer
= 2, .isDirty
= 1},
104 {.layer
= 3, .isDirty
= 1}
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];
114 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
115 extern DISP_OVL_ENGINE_INSTANCE_HANDLE mtkfb_instance
;
118 struct DBG_OVL_CONFIGS
120 OVL_CONFIG_STRUCT Layer0
;
121 OVL_CONFIG_STRUCT Layer1
;
122 OVL_CONFIG_STRUCT Layer2
;
123 OVL_CONFIG_STRUCT Layer3
;
126 unsigned int gCaptureLayerEnable
= 0;
127 unsigned int gCaptureLayerDownX
= 10;
128 unsigned int gCaptureLayerDownY
= 10;
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;
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
);
145 extern struct fb_info
*mtkfb_fbi
;
147 unsigned int is_video_mode_running
= 0;
149 DEFINE_SEMAPHORE(sem_update_screen
);//linux 3.0 porting
150 static BOOL isLCMFound
= FALSE
;
152 #define ALIGN_TO_POW_OF_2(x, n) \
153 (((x) + ((n) - 1)) & ~((n) - 1))
155 #define ALIGN_TO(x, n) \
156 (((x) + ((n) - 1)) & ~((n) - 1))
160 static size_t disp_log_on
= false;
161 #define DISP_LOG(fmt, arg...) \
163 if (disp_log_on) DISP_LOG_PRINT(ANDROID_LOG_WARN, "COMMON", fmt, ##arg); \
166 #define DISP_FUNC() \
168 if(disp_log_on) DISP_LOG_PRINT(ANDROID_LOG_INFO, "COMMON", "[Func]%s\n", __func__); \
171 void disp_log_enable(int enable
)
173 disp_log_on
= enable
;
174 DISP_LOG("disp common log %s\n", enable
?"enabled":"disabled");
176 // ---------------------------------------------------------------------------
178 // ---------------------------------------------------------------------------
180 extern LCM_DRIVER
* lcm_driver_list
[];
181 extern unsigned int lcm_count
;
183 static void disp_dump_lcm_parameters(LCM_PARAMS
*lcm_params
)
185 unsigned char *LCM_TYPE_NAME
[] = {"DBI", "DPI", "DSI"};
186 unsigned char *LCM_CTRL_NAME
[] = {"NONE", "SERIAL", "PARALLEL", "GPIO"};
188 if(lcm_params
== NULL
)
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
);
198 char disp_lcm_name
[256] = {0};
199 BOOL
disp_get_lcm_name_boot(char *cmdline
)
204 p
= strstr(cmdline
, "lcm=");
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
);
213 if((p
- cmdline
) > strlen(cmdline
+1))
219 isLCMFound
= strcmp(p
, "0");
220 pr_info("[mtkfb] LCM is %sconnected\n", ((isLCMFound
)?"":"not "));
223 while(*q
!= ' ' && *q
!= '\0')
226 memset((void*)disp_lcm_name
, 0, sizeof(disp_lcm_name
));
227 strncpy((char*)disp_lcm_name
, (const char*)p
, (int)(q
-p
));
229 if(DISP_SelectDeviceBoot(disp_lcm_name
))
236 static BOOL
disp_drv_init_context(void)
238 if (disp_if_drv
!= NULL
&& lcm_drv
!= NULL
){
245 disphal_init_ctrl_if();
247 disp_if_drv
= disphal_get_if_driver();
249 if (!disp_if_drv
) return FALSE
;
254 BOOL
DISP_IsLcmFound(void)
259 BOOL
DISP_IsContextInited(void)
261 if(lcm_params
&& disp_if_drv
&& lcm_drv
)
267 BOOL
DISP_SelectDeviceBoot(const char* lcm_name
)
269 //LCM_DRIVER *lcm = NULL;
271 pr_info("%s\n", __func__
);
275 // we can't do anything in boot stage if lcm_name is NULL
278 lcm_drv
= disphal_get_lcm_driver(lcm_name
, &u4IndexOfLCMList
);
282 pr_info("%s, get_lcm_driver returns NULL\n", __func__
);
287 disp_if_drv
= disphal_get_if_driver();
289 disp_dump_lcm_parameters(lcm_params
);
293 BOOL
DISP_SelectDevice(const char* lcm_name
)
295 lcm_drv
= disphal_get_lcm_driver(lcm_name
, &u4IndexOfLCMList
);
298 pr_info("%s, disphal_get_lcm_driver() returns NULL\n", __func__
);
303 disp_dump_lcm_parameters(lcm_params
);
304 return disp_drv_init_context();
307 BOOL
DISP_DetectDevice(void)
309 lcm_drv
= disphal_get_lcm_driver(NULL
, &u4IndexOfLCMList
);
312 pr_info("%s, disphal_get_lcm_driver() returns NULL\n", __func__
);
317 disp_dump_lcm_parameters(lcm_params
);
322 // ---------------------------------------------------------------------------
323 // DISP Driver Implementations
324 // ---------------------------------------------------------------------------
325 extern mtk_dispif_info_t dispif_info
[MTKFB_MAX_DISPLAY_COUNT
];
327 DISP_STATUS
DISP_Init(UINT32 fbVA
, UINT32 fbPA
, BOOL isLcmInited
)
329 DISP_STATUS r
= DISP_STATUS_OK
;
331 captureovl_task
= kthread_create(_DISP_CaptureOvlKThread
, NULL
, "disp_captureovl_kthread");
332 if (IS_ERR(captureovl_task
))
334 DISP_LOG("DISP_InitVSYNC(): Cannot create capture ovl kthread\n");
336 if (gWakeupCaptureOvlThread
)
337 wake_up_process(captureovl_task
);
339 capturefb_task
= kthread_create(_DISP_CaptureFBKThread
, mtkfb_fbi
, "disp_capturefb_kthread");
340 if (IS_ERR(capturefb_task
))
342 DISP_LOG("DISP_InitVSYNC(): Cannot create capture fb kthread\n");
344 wake_up_process(capturefb_task
);
346 if (!disp_drv_init_context()) {
347 return DISP_STATUS_NOT_IMPLEMENTED
;
350 disphal_init_ctrl_if();
351 disp_path_clock_on("mtkfb");
353 //xuecheng's workaround for 82 video mode
354 //if(lcm_params->type==LCM_TYPE_DSI && lcm_params->dsi.mode!=CMD_MODE)
357 r
= (disp_if_drv
->init
) ?
358 (disp_if_drv
->init(fbVA
, fbPA
, isLcmInited
)) :
359 DISP_STATUS_NOT_IMPLEMENTED
;
361 DISP_InitVSYNC((100000000/lcd_fps
) + 1);//us
367 fbVA
+= DISP_GetFBRamSize();
368 fbPA
+= DISP_GetFBRamSize();
369 ret
= DAL_Init(fbVA
, fbPA
);
370 ASSERT(DAL_STATUS_OK
== ret
);
375 if(lcm_drv
->check_status
)
376 lcm_drv
->check_status();
378 memset((void*)(&dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
]), 0, sizeof(mtk_dispif_info_t
));
380 switch(lcm_params
->type
)
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");
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");
400 dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].displayType
= DISPIF_TYPE_DSI
;
401 if(lcm_params
->dsi
.mode
== CMD_MODE
)
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");
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");
421 if(disp_if_drv
->get_panel_color_format())
423 switch(disp_if_drv
->get_panel_color_format())
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
;
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
;
440 if(dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].displayWidth
* dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].displayHeight
<= 240*432)
442 dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].physicalHeight
= dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].physicalWidth
= 0;
444 else if(dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].displayWidth
* dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].displayHeight
<= 320*480)
446 dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].physicalHeight
= dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].physicalWidth
= 0;
448 else if(dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].displayWidth
* dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].displayHeight
<= 480*854)
450 dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].physicalHeight
= dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].physicalWidth
= 0;
454 dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].physicalHeight
= dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].physicalWidth
= 0;
457 dispif_info
[MTKFB_DISPIF_PRIMARY_LCD
].isConnected
= 1;
464 DISP_STATUS
DISP_Deinit(void)
466 DISP_CHECK_RET(DISP_PanelEnable(FALSE
));
467 DISP_CHECK_RET(DISP_PowerEnable(FALSE
));
469 return DISP_STATUS_OK
;
474 DISP_STATUS
DISP_PowerEnable(BOOL enable
)
476 DISP_STATUS ret
= DISP_STATUS_OK
;
478 static BOOL s_enabled
= TRUE
;
480 if (enable
!= s_enabled
)
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
;
490 disp_drv_init_context();
492 is_engine_in_suspend_mode
= enable
? FALSE
: TRUE
;
495 needStartEngine
= true;
497 if (enable
&& lcm_drv
&& lcm_drv
->resume_power
)
499 lcm_drv
->resume_power();
502 ret
= (disp_if_drv
->enable_power
) ?
503 (disp_if_drv
->enable_power(enable
)) :
504 DISP_STATUS_NOT_IMPLEMENTED
;
509 else if (lcm_drv
&& lcm_drv
->suspend_power
)
511 lcm_drv
->suspend_power();
514 up(&sem_update_screen
);
521 DISP_STATUS
DISP_PanelEnable(BOOL enable
)
523 static BOOL s_enabled
= TRUE
;
524 DISP_STATUS ret
= DISP_STATUS_OK
;
526 DISP_LOG("panel is %s\n", enable
?"enabled":"disabled");
528 if (down_interruptible(&sem_update_screen
))
530 pr_info("ERROR: Can't get sem_update_screen in DISP_PanelEnable()\n");
531 return DISP_STATUS_ERROR
;
534 disp_drv_init_context();
536 is_lcm_in_suspend_mode
= enable
? FALSE
: TRUE
;
541 if (!lcm_drv
->suspend
|| !lcm_drv
->resume
)
543 ret
= DISP_STATUS_NOT_IMPLEMENTED
;
547 if (enable
&& !s_enabled
)
550 disphal_panel_enable(lcm_drv
, &LcmCmdMutex
, TRUE
);
552 else if (!enable
&& s_enabled
)
555 disphal_panel_enable(lcm_drv
, &LcmCmdMutex
, FALSE
);
559 up(&sem_update_screen
);
564 DISP_STATUS
DISP_SetBacklight(UINT32 level
)
566 DISP_STATUS ret
= DISP_STATUS_OK
;
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
;
573 disp_drv_init_context();
575 disphal_wait_not_busy();
577 if (!lcm_drv
->set_backlight
) {
578 ret
= DISP_STATUS_NOT_IMPLEMENTED
;
582 disphal_set_backlight(lcm_drv
, &LcmCmdMutex
, level
);
585 up(&sem_update_screen
);
590 DISP_STATUS
DISP_SetBacklight_mode(UINT32 mode
)
592 DISP_STATUS ret
= DISP_STATUS_OK
;
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
;
599 disp_drv_init_context();
601 disphal_wait_not_busy();
603 if (!lcm_drv
->set_backlight
) {
604 ret
= DISP_STATUS_NOT_IMPLEMENTED
;
608 disphal_set_backlight_mode(lcm_drv
, &LcmCmdMutex
, mode
);
611 up(&sem_update_screen
);
617 DISP_STATUS
DISP_SetPWM(UINT32 divider
)
619 DISP_STATUS ret
= DISP_STATUS_OK
;
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
;
626 disp_drv_init_context();
628 disphal_wait_not_busy();
630 if (!lcm_drv
->set_pwm
) {
631 ret
= DISP_STATUS_NOT_IMPLEMENTED
;
635 disphal_set_pwm(lcm_drv
, &LcmCmdMutex
, divider
);
638 up(&sem_update_screen
);
643 DISP_STATUS
DISP_GetPWM(UINT32 divider
, unsigned int *freq
)
645 DISP_STATUS ret
= DISP_STATUS_OK
;
647 disp_drv_init_context();
649 if (!lcm_drv
->get_pwm
) {
650 ret
= DISP_STATUS_NOT_IMPLEMENTED
;
654 disphal_get_pwm(lcm_drv
, &LcmCmdMutex
, divider
, freq
);
662 DISP_STATUS
DISP_SetFrameBufferAddr(UINT32 fbPhysAddr
)
664 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
665 cached_layer_config
[FB_LAYER
].addr
= fbPhysAddr
;
666 cached_layer_config
[FB_LAYER
].isDirty
= true;
668 return DISP_STATUS_OK
;
673 static BOOL is_overlaying
= FALSE
;
675 DISP_STATUS
DISP_EnterOverlayMode(void)
679 return DISP_STATUS_ALREADY_SET
;
681 is_overlaying
= TRUE
;
684 return DISP_STATUS_OK
;
688 DISP_STATUS
DISP_LeaveOverlayMode(void)
691 if (!is_overlaying
) {
692 return DISP_STATUS_ALREADY_SET
;
694 is_overlaying
= FALSE
;
697 return DISP_STATUS_OK
;
700 DISP_STATUS
DISP_UpdateScreen(UINT32 x
, UINT32 y
, UINT32 width
, UINT32 height
)
702 unsigned int is_video_mode
;
704 // return DISP_STATUS_OK;
705 DISP_LOG("update screen, (%d,%d),(%d,%d)\n", x
, y
, width
, height
);
707 if ((lcm_params
->type
==LCM_TYPE_DPI
) ||
708 ((lcm_params
->type
==LCM_TYPE_DSI
) && (lcm_params
->dsi
.mode
!= CMD_MODE
)))
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
;
717 // if LCM is powered down, LCD would never recieve the TE signal
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;
724 disphal_update_screen(lcm_drv
, &LcmCmdMutex
, x
, y
, width
, height
);
726 if (-1 != direct_link_layer
) {
732 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
733 Disp_Ovl_Engine_Trigger_Overlay(mtkfb_instance
);
735 disp_if_drv
->update_screen(FALSE
);
738 needStartEngine
= false;
740 up(&sem_update_screen
);
742 return DISP_STATUS_OK
;
745 DISP_STATUS
DISP_WaitForLCDNotBusy(void)
747 disphal_wait_not_busy();
748 return DISP_STATUS_OK
;
751 DISP_STATUS
_DISP_ConfigUpdateScreen(UINT32 x
, UINT32 y
, UINT32 width
, UINT32 height
)
753 // if LCM is powered down, LCD would never recieve the TE signal
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
);
759 return DISP_STATUS_OK
;
762 #define DISP_CB_MAXCNT 2
764 DISP_EXTRA_CHECKUPDATE_PTR checkupdate_cb
[DISP_CB_MAXCNT
];
765 DISP_EXTRA_CONFIG_PTR config_cb
[DISP_CB_MAXCNT
];
767 CONFIG_CB_ARRAY g_CB_Array
= { {NULL
, NULL
},{NULL
, NULL
}};//if DISP_CB_MAXCNT == 2
768 DEFINE_MUTEX(UpdateRegMutex
);
769 void GetUpdateMutex(void)
771 mutex_lock(&UpdateRegMutex
);
773 int TryGetUpdateMutex(void)
775 return mutex_trylock(&UpdateRegMutex
);
777 void ReleaseUpdateMutex(void)
779 mutex_unlock(&UpdateRegMutex
);
782 int DISP_RegisterExTriggerSource(DISP_EXTRA_CHECKUPDATE_PTR pCheckUpdateFunc
, DISP_EXTRA_CONFIG_PTR pConfFunc
)
786 if((NULL
== pCheckUpdateFunc
) || (NULL
== pConfFunc
))
788 pr_info("Warnning! [Func]%s register NULL function : %p,%p\n", __func__
, pCheckUpdateFunc
, pConfFunc
);
794 for(index
= 0 ; index
< DISP_CB_MAXCNT
; index
+= 1)
796 if(NULL
== g_CB_Array
.checkupdate_cb
[index
])
798 g_CB_Array
.checkupdate_cb
[index
] = pCheckUpdateFunc
;
799 g_CB_Array
.config_cb
[index
] = pConfFunc
;
805 ReleaseUpdateMutex();
807 return (hit
? index
: (-1));
810 void DISP_UnRegisterExTriggerSource(int u4ID
)
812 if(DISP_CB_MAXCNT
< (u4ID
+1))
814 pr_info("Warnning! [Func]%s unregister a never registered function : %d\n", __func__
, u4ID
);
820 g_CB_Array
.checkupdate_cb
[u4ID
] = NULL
;
821 g_CB_Array
.config_cb
[u4ID
] = NULL
;
823 ReleaseUpdateMutex();
825 #if defined (MTK_HDMI_SUPPORT)
826 extern bool is_hdmi_active(void);
830 static int _DISP_CaptureFBKThread(void *data
)
832 struct fb_info
* pInfo
= (struct fb_info
*) data
;
833 MMP_MetaDataBitmap_t Bitmap
;
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
;
843 switch (pInfo
->var
.bits_per_pixel
)
846 Bitmap
.format
= MMProfileBitmapRGB565
;
849 Bitmap
.format
= MMProfileBitmapBGRA8888
;
852 Bitmap
.format
= MMProfileBitmapRGB565
;
857 Bitmap
.start_pos
= 0;
858 Bitmap
.pitch
= pInfo
->fix
.line_length
;
859 if (Bitmap
.pitch
== 0)
861 Bitmap
.pitch
= ALIGN_TO(Bitmap
.width
, 1) * Bitmap
.bpp
/ 8;
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
);
873 static int _DISP_CaptureOvlKThread(void *data
)
875 unsigned int index
= 0;
878 unsigned int buf_size
;
879 unsigned int init
= 0;
880 unsigned int enabled
= 0;
882 MMP_MetaDataBitmap_t Bitmap
;
883 buf_size
= DISP_GetScreenWidth() * DISP_GetScreenHeight() * 4;
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;
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();
902 if (!gCaptureOvlThreadEnable
)
906 DISP_Config_Overlay_to_Memory(mva
[index
], 0);
911 DISP_Config_Overlay_to_Memory(mva
[index
], 1);
914 disphal_sync_overlay_out_buffer((unsigned int)va
[index
], DISP_GetScreenHeight()*DISP_GetScreenWidth()*24/8);
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;
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
);
934 void _DISP_DumpLayer(OVL_CONFIG_STRUCT
* pLayer
)
936 if (gCaptureLayerEnable
&& pLayer
->layer_en
)
938 MMP_MetaDataBitmap_t Bitmap
;
939 Bitmap
.data1
= pLayer
->vaddr
;
940 Bitmap
.width
= pLayer
->dst_w
;
941 Bitmap
.height
= pLayer
->dst_h
;
944 case eRGB565
: Bitmap
.format
= MMProfileBitmapRGB565
; Bitmap
.bpp
= 16; break;
945 case eRGB888
: Bitmap
.format
= MMProfileBitmapBGR888
; Bitmap
.bpp
= 24; break;
948 Bitmap
.format
= MMProfileBitmapBGRA8888
; Bitmap
.bpp
= 32; break;
949 case eBGR888
: Bitmap
.format
= MMProfileBitmapRGB888
; Bitmap
.bpp
= 24; break;
952 Bitmap
.format
= MMProfileBitmapRGBA8888
; Bitmap
.bpp
= 32; break;
953 default: pr_info("error: _DISP_DumpLayer(), unknow format=%d \n", pLayer
->fmt
); return;
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()) &&
964 Bitmap
.pData
= (void*) pLayer
->vaddr
;
965 MMProfileLogMetaBitmap(MTKFB_MMP_Events
.Layer
[pLayer
->layer
], MMProfileFlagPulse
, &Bitmap
);
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
);
976 static void _DISP_VSyncCallback(void* pParam
);
978 void DISP_StartConfigUpdate(void)
980 //if(((LCM_TYPE_DSI == lcm_params->type) && (CMD_MODE == lcm_params->dsi.mode)) || (LCM_TYPE_DBI == lcm_params->type))
982 config_update_task_wakeup
= 1;
983 wake_up_interruptible(&config_update_wq
);
987 static int _DISP_ESD_Check(int* dirty
)
989 unsigned int esd_check_count
;
990 if (need_esd_check
&& (!is_early_suspended
))
994 MMProfileLog(MTKFB_MMP_Events
.EsdCheck
, MMProfileFlagStart
);
995 while (esd_check_count
< LCM_ESD_CHECK_MAX_COUNT
)
999 MMProfileLogEx(MTKFB_MMP_Events
.EsdCheck
, MMProfileFlagPulse
, 0, 0);
1006 /* [PLATFORM]-Mod-BEGIN by TCTSZ.yaohui.zeng, 2015/05/04, modify for ESD fast shoot*/
1007 //esd_check_count++;
1009 /* [PLATFORM]-Mod-END by TCTSZ.yaohui.zeng, 2015/05/04*/
1011 if (esd_check_count
>= LCM_ESD_CHECK_MAX_COUNT
)
1013 MMProfileLogEx(MTKFB_MMP_Events
.EsdCheck
, MMProfileFlagPulse
, 2, 0);
1014 esd_kthread_pause
= TRUE
;
1016 if (esd_check_count
)
1018 disphal_update_screen(lcm_drv
, &LcmCmdMutex
, 0, 0, DISP_GetScreenWidth(), DISP_GetScreenHeight());
1022 wake_up_interruptible(&esd_check_wq
);
1023 MMProfileLog(MTKFB_MMP_Events
.EsdCheck
, MMProfileFlagEnd
);
1029 static int _DISP_ConfigUpdateKThread(void *data
)
1031 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1035 int overlay_dirty
= 0;
1038 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1039 int memout_dirty
= 0;
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
, ¶m
);
1046 wait_event_interruptible(config_update_wq
, config_update_task_wakeup
);
1047 config_update_task_wakeup
= 0;
1048 MMProfileLog(MTKFB_MMP_Events
.UpdateConfig
, MMProfileFlagStart
);
1053 if (down_interruptible(&sem_early_suspend
)) {
1054 pr_info("[FB Driver] can't get semaphore in mtkfb_early_suspend()\n");
1057 //MMProfileLogEx(MTKFB_MMP_Events.EarlySuspend, MMProfileFlagStart, 1, 0);
1059 if (!((lcm_params
->type
== LCM_TYPE_DSI
) && (lcm_params
->dsi
.mode
!= CMD_MODE
)))
1061 if (_DISP_ESD_Check(&dirty
))
1067 if (!is_early_suspended
)
1069 if (mutex_trylock(&OverlaySettingMutex
))
1071 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1072 overlay_dirty
= atomic_read(&OverlaySettingDirtyFlag
);
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;
1087 Disp_Ovl_Engine_Get_Dirty_info(mtkfb_instance
, &overlay_dirty
, &memout_dirty
);
1090 Disp_Ovl_Engine_Sync_Captured_layer_info(mtkfb_instance
);
1092 if ((overlay_dirty
) || memout_dirty
)
1095 MMProfileLogEx(MTKFB_MMP_Events
.ConfigOVL
, MMProfileFlagPulse
, overlay_dirty
, memout_dirty
);
1098 PanDispSettingDirty
= 0;
1100 mutex_unlock(&OverlaySettingMutex
);
1102 aal_dirty
= overlay_dirty
;//overlay refresh means AAL also needs refresh
1104 if(1 == TryGetUpdateMutex())
1106 for(index
= 0 ; index
< DISP_CB_MAXCNT
; index
+= 1)
1108 if((NULL
!= g_CB_Array
.checkupdate_cb
[index
]) && g_CB_Array
.checkupdate_cb
[index
](overlay_dirty
))
1115 ReleaseUpdateMutex();
1118 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1119 if (mutex_trylock(&MemOutSettingMutex
))
1122 if (MemOutConfig
.dirty
)
1124 memcpy(&mem_out_config
, &MemOutConfig
, sizeof(MemOutConfig
));
1125 MemOutConfig
.dirty
= 0;
1129 mem_out_config
.dirty
= 0;
1130 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1131 mutex_unlock(&MemOutSettingMutex
);
1134 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1135 if (mem_out_config
.dirty
)
1137 Disp_Ovl_Engine_Set_Overlayed_Buffer(mtkfb_instance
, (struct disp_ovl_engine_config_mem_out_struct
*)&mem_out_config
);
1141 if(((LCM_TYPE_DSI
== lcm_params
->type
) && (CMD_MODE
== lcm_params
->dsi
.mode
)) || (LCM_TYPE_DBI
== lcm_params
->type
))
1143 _DISP_VSyncCallback(NULL
);
1148 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1149 // Apply AAL config here.
1152 MMProfileLog(MTKFB_MMP_Events
.ConfigAAL
, MMProfileFlagStart
);
1153 if(1 == TryGetUpdateMutex())
1155 for(index
= 0 ; index
< DISP_CB_MAXCNT
; index
+= 1)
1157 if((NULL
!= g_CB_Array
.checkupdate_cb
[index
]) && g_CB_Array
.checkupdate_cb
[index
](overlay_dirty
))
1160 disp_path_get_mutex();
1161 g_CB_Array
.config_cb
[index
](overlay_dirty
);
1163 disp_path_release_mutex();
1166 ReleaseUpdateMutex();
1168 MMProfileLog(MTKFB_MMP_Events
.ConfigAAL
, MMProfileFlagEnd
);
1170 if ((overlay_dirty
) || (mem_out_config
.dirty
))
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
)))
1177 if ((PanDispSettingPending
==1) && (PanDispSettingDirty
==0))
1179 PanDispSettingApplied
= 1;
1180 PanDispSettingPending
= 0;
1182 atomic_set(&OverlaySettingApplied
, 1);
1183 wake_up(®_update_wq
);
1186 #if defined(MTK_HDMI_SUPPORT)
1187 if(is_hdmi_active() && !DISP_IsVideoMode())
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);
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
)))
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
);
1203 // Apply configuration here.
1205 disp_path_get_mutex();
1208 MMProfileLog(MTKFB_MMP_Events
.ConfigOVL
, MMProfileFlagStart
);
1209 for (i
=0; i
<DDP_OVL_LAYER_MUN
; i
++)
1211 if (captured_layer_config
[i
].isDirty
)
1213 _DISP_DumpLayer(&captured_layer_config
[i
]);
1214 disp_path_config_layer(&captured_layer_config
[i
]);
1215 captured_layer_config
[i
].isDirty
= false;
1218 if ((lcm_params
->type
== LCM_TYPE_DBI
) ||
1219 ((lcm_params
->type
== LCM_TYPE_DSI
) && (lcm_params
->dsi
.mode
== CMD_MODE
)))
1221 if ((PanDispSettingPending
==1) && (PanDispSettingDirty
==0))
1223 PanDispSettingApplied
= 1;
1224 PanDispSettingPending
= 0;
1226 atomic_set(&OverlaySettingApplied
, 1);
1227 wake_up(®_update_wq
);
1229 MMProfileLog(MTKFB_MMP_Events
.ConfigOVL
, MMProfileFlagEnd
);
1234 // Apply AAL config here.
1237 MMProfileLog(MTKFB_MMP_Events
.ConfigAAL
, MMProfileFlagStart
);
1240 if(1 == TryGetUpdateMutex())
1242 for(index
= 0 ; index
< DISP_CB_MAXCNT
; index
+= 1)
1244 if((NULL
!= g_CB_Array
.checkupdate_cb
[index
]) && g_CB_Array
.checkupdate_cb
[index
](overlay_dirty
))
1246 g_CB_Array
.config_cb
[index
](overlay_dirty
);
1249 ReleaseUpdateMutex();
1251 MMProfileLog(MTKFB_MMP_Events
.ConfigAAL
, MMProfileFlagEnd
);
1254 // Apply memory out config here.
1255 if (mem_out_config
.dirty
)
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);
1261 #if defined(MTK_HDMI_SUPPORT)
1262 if(is_hdmi_active() && !DISP_IsVideoMode())
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);
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
)))
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
);
1278 disp_path_release_mutex();
1279 #endif //MTK_OVERLAY_ENGINE_SUPPORT
1283 if ((lcm_params
->type
== LCM_TYPE_DBI
) ||
1284 ((lcm_params
->type
== LCM_TYPE_DSI
) && (lcm_params
->dsi
.mode
== CMD_MODE
)))
1286 // Start update timer.
1287 if (!is_early_suspended
)
1289 if (is_immediateupdate
)
1290 hrtimer_start(&cmd_mode_update_timer
, ktime_set(0 , 5000000), HRTIMER_MODE_REL
);
1292 hrtimer_start(&cmd_mode_update_timer
, cmd_mode_update_timer_period
, HRTIMER_MODE_REL
);
1296 if ((lcm_params
->type
== LCM_TYPE_DSI
) && (lcm_params
->dsi
.mode
!= CMD_MODE
))
1298 if (_DISP_ESD_Check(&dirty
))
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())
1314 static void _DISP_HWDoneCallback(void* pParam
)
1316 MMProfileLogEx(MTKFB_MMP_Events
.DispDone
, MMProfileFlagPulse
, is_early_suspended
, 0);
1318 wake_up_interruptible(&disp_done_wq
);
1321 static void _DISP_VSyncCallback(void* pParam
)
1323 MMProfileLog(MTKFB_MMP_Events
.VSync
, MMProfileFlagPulse
);
1325 wake_up_interruptible(&vsync_wq
);
1328 static void _DISP_RegUpdateCallback(void* pParam
)
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
);
1335 realtime_layer_config
= captured_layer_config
;
1337 if ((lcm_params
->type
== LCM_TYPE_DPI
) ||
1338 ((lcm_params
->type
== LCM_TYPE_DSI
) && (lcm_params
->dsi
.mode
!= CMD_MODE
)))
1340 if ((PanDispSettingPending
==1) && (PanDispSettingDirty
==0))
1342 PanDispSettingApplied
= 1;
1343 PanDispSettingPending
= 0;
1345 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1346 atomic_set(&OverlaySettingApplied
, 1);
1349 gWakeupCaptureOvlThread
= 1;
1350 wake_up(®_update_wq
);
1353 static void _DISP_TargetLineCallback(void* pParam
)
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
);
1361 static void _DISP_CmdDoneCallback(void* pParam
)
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
);
1370 static enum hrtimer_restart
_DISP_CmdModeTimer_handler(struct hrtimer
*timer
)
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
;
1378 void DISP_InitVSYNC(unsigned int vsync_interval
)
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");
1385 if (IS_ERR(config_update_task
))
1387 DISP_LOG("DISP_InitVSYNC(): Cannot create config update kthread\n");
1390 wake_up_process(config_update_task
);
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
)))
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
);
1409 void DISP_WaitVSYNC(void)
1411 MMProfileLog(MTKFB_MMP_Events
.WaitVSync
, MMProfileFlagStart
);
1413 if (wait_event_interruptible_timeout(vsync_wq
, vsync_wq_flag
, HZ
/10) == 0)
1415 pr_info("[DISP] Wait VSync timeout. early_suspend=%d\n", is_early_suspended
);
1417 MMProfileLog(MTKFB_MMP_Events
.WaitVSync
, MMProfileFlagEnd
);
1420 DISP_STATUS
DISP_PauseVsync(BOOL enable
)
1422 if((LCM_TYPE_DBI
== lcm_params
->type
) ||
1423 (LCM_TYPE_DSI
== lcm_params
->type
&& lcm_params
->dsi
.mode
== CMD_MODE
))
1426 hrtimer_cancel(&cmd_mode_update_timer
);
1428 else if((LCM_TYPE_DPI
== lcm_params
->type
) ||
1429 (LCM_TYPE_DSI
== lcm_params
->type
&& lcm_params
->dsi
.mode
!= CMD_MODE
))
1434 DISP_LOG("DISP_PauseVSYNC():unknown interface\n");
1436 return DISP_STATUS_OK
;
1439 DISP_STATUS
DISP_ConfigDither(int lrs
, int lgs
, int lbs
, int dbr
, int dbg
, int dbb
)
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
);
1443 return DISP_STATUS_OK
;
1447 // ---------------------------------------------------------------------------
1448 // Retrieve Information
1449 // ---------------------------------------------------------------------------
1451 BOOL
DISP_IsVideoMode(void)
1453 disp_drv_init_context();
1455 return lcm_params
->type
==LCM_TYPE_DPI
|| (lcm_params
->type
==LCM_TYPE_DSI
&& lcm_params
->dsi
.mode
!= CMD_MODE
);
1458 pr_info("WARNING!! DISP_IsVideoMode is called before display driver inited!\n");
1463 UINT32
DISP_GetScreenWidth(void)
1465 disp_drv_init_context();
1467 return lcm_params
->width
;
1470 pr_info("WARNING!! get screen width before display driver inited!\n");
1474 EXPORT_SYMBOL(DISP_GetScreenWidth
);
1476 UINT32
DISP_GetScreenHeight(void)
1478 disp_drv_init_context();
1480 return lcm_params
->height
;
1483 pr_info("WARNING!! get screen height before display driver inited!\n");
1487 UINT32
DISP_GetActiveHeight(void)
1489 disp_drv_init_context();
1492 pr_info("[wwy]lcm_parms->active_height = %d\n",lcm_params
->physical_height
);
1493 return lcm_params
->physical_height
;
1497 pr_info("WARNING!! get physical_height before display driver inited!\n");
1502 UINT32
DISP_GetActiveWidth(void)
1504 disp_drv_init_context();
1507 pr_info("[wwy]lcm_parms->active_width = %d\n",lcm_params
->physical_width
);
1508 return lcm_params
->physical_width
;
1512 pr_info("WARNING!! get physical_width before display driver inited!\n");
1517 DISP_STATUS
DISP_SetScreenBpp(UINT32 bpp
)
1526 DISP_LOG("DISP_SetScreenBpp error, not support %d bpp\n", bpp
);
1527 return DISP_STATUS_ERROR
;
1531 DISP_LOG("DISP_SetScreenBpp %d bpp\n", bpp
);
1533 return DISP_STATUS_OK
;
1536 UINT32
DISP_GetScreenBpp(void)
1541 DISP_STATUS
DISP_SetPages(UINT32 pages
)
1545 disp_fb_pages
= pages
;
1546 DISP_LOG("DISP_SetPages %d pages\n", pages
);
1548 return DISP_STATUS_OK
;
1551 UINT32
DISP_GetPages(void)
1553 return disp_fb_pages
; // Double Buffers
1557 BOOL
DISP_IsDirectLinkMode(void)
1559 return (-1 != direct_link_layer
) ? TRUE
: FALSE
;
1563 BOOL
DISP_IsInOverlayMode(void)
1565 return is_overlaying
;
1568 UINT32
DISP_GetFBRamSize(void)
1570 return ALIGN_TO(DISP_GetScreenWidth(), disphal_get_fb_alignment()) *
1571 ALIGN_TO(DISP_GetScreenHeight(), disphal_get_fb_alignment()) *
1572 ((DISP_GetScreenBpp() + 7) >> 3) *
1576 #define MAX_BUFFER_COUNT 4
1580 * eRGB888 triple buffer for 0VL->WDMA->MEM, MEM->RDMA->LCM
1582 UINT32
DISP_GetOVLRamSize(void)
1584 return ALIGN_TO(DISP_GetScreenWidth(), disphal_get_fb_alignment()) *
1585 ALIGN_TO(DISP_GetScreenHeight(), disphal_get_fb_alignment()) *
1586 MAX_BUFFER_COUNT
* BPP
;
1589 UINT32
DISP_GetVRamSize(void)
1591 // Use a local static variable to cache the calculated vram size
1593 static UINT32 vramSize
= 0;
1597 disp_drv_init_context();
1599 ///get framebuffer size
1600 vramSize
= DISP_GetFBRamSize();
1602 ///get DXI working buffer size
1603 vramSize
+= disp_if_drv
->get_working_buffer_size();
1605 // get assertion layer buffer size
1606 vramSize
+= DAL_GetLayerSize();
1608 // get ovl-wdma buffer size
1609 vramSize
+= DISP_GetOVLRamSize();
1611 // Align vramSize to 1MB
1613 vramSize
= ALIGN_TO_POW_OF_2(vramSize
, 0x100000);
1615 DISP_LOG("DISP_GetVRamSize: %u bytes\n", vramSize
);
1621 UINT32
DISP_GetVRamSizeBoot(char *cmdline
)
1623 static UINT32 vramSize
= 0;
1630 disp_get_lcm_name_boot(cmdline
);
1632 // if can't get the lcm type from uboot, we will return 0x800000 for a safe value
1634 vramSize
= DISP_GetVRamSize();
1637 pr_info("%s, can't get lcm type, reserved memory size will be set as 0x800000\n", __func__
);
1640 // Align vramSize to 1MB
1642 vramSize
= ALIGN_TO_POW_OF_2(vramSize
, 0x100000);
1644 pr_info("DISP_GetVRamSizeBoot: %u bytes[%dMB]\n", vramSize
, (vramSize
>>20));
1649 PANEL_COLOR_FORMAT
DISP_GetPanelColorFormat(void)
1651 disp_drv_init_context();
1653 return (disp_if_drv
->get_panel_color_format
) ?
1654 (disp_if_drv
->get_panel_color_format()) :
1655 DISP_STATUS_NOT_IMPLEMENTED
;
1658 UINT32
DISP_GetPanelBPP(void)
1660 PANEL_COLOR_FORMAT fmt
;
1661 disp_drv_init_context();
1663 if(disp_if_drv
->get_panel_color_format
== NULL
)
1665 return DISP_STATUS_NOT_IMPLEMENTED
;
1668 fmt
= disp_if_drv
->get_panel_color_format();
1671 case PANEL_COLOR_FORMAT_RGB332
:
1673 case PANEL_COLOR_FORMAT_RGB444
:
1675 case PANEL_COLOR_FORMAT_RGB565
:
1677 case PANEL_COLOR_FORMAT_RGB666
:
1679 case PANEL_COLOR_FORMAT_RGB888
:
1686 UINT32
DISP_GetOutputBPPforDithering(void)
1688 disp_drv_init_context();
1690 return (disp_if_drv
->get_dithering_bpp
) ?
1691 (disp_if_drv
->get_dithering_bpp()) :
1692 DISP_STATUS_NOT_IMPLEMENTED
;
1695 DISP_STATUS
DISP_Config_Overlay_to_Memory(unsigned int mva
, int enable
)
1699 // struct disp_path_config_mem_out_struct mem_out = {0};
1703 MemOutConfig
.outFormat
= eRGB888
;
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();
1712 #if !defined(MTK_HDMI_SUPPORT)
1713 mutex_lock(&MemOutSettingMutex
);
1714 MemOutConfig
.dirty
= 1;
1715 mutex_unlock(&MemOutSettingMutex
);
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();
1728 mutex_lock(&MemOutSettingMutex
);
1729 MemOutConfig
.dirty
= 1;
1730 mutex_unlock(&MemOutSettingMutex
);
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__
);
1737 return DISP_STATUS_OK
;
1741 DISP_STATUS
DISP_Capture_Framebuffer( unsigned int pvbuf
, unsigned int bpp
, unsigned int is_early_suspended
)
1744 unsigned int ret
= 0;
1746 int i
= 0; // temp fix for build error !!!!!!
1747 BOOL deinit_o2m
= TRUE
;
1750 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1751 for (i
=0; i
<DDP_OVL_LAYER_MUN
; i
++)
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
)
1758 for (i
=0; i
<DDP_OVL_LAYER_MUN
; i
++)
1760 if (cached_layer_config
[i
].layer_en
&& cached_layer_config
[i
].security
)
1764 if (i
< DDP_OVL_LAYER_MUN
|| is_early_suspended
== 1)
1766 // There is security layer.
1767 memset((void*)pvbuf
, 0, DISP_GetScreenHeight()*DISP_GetScreenWidth()*bpp
/8);
1768 return DISP_STATUS_OK
;
1770 disp_drv_init_context();
1772 MMProfileLogEx(MTKFB_MMP_Events
.CaptureFramebuffer
, MMProfileFlagPulse
, 0, pvbuf
);
1773 MMProfileLogEx(MTKFB_MMP_Events
.CaptureFramebuffer
, MMProfileFlagPulse
, 1, bpp
);\
1775 ret
= disphal_map_overlay_out_buffer(pvbuf
, DISP_GetScreenHeight()*DISP_GetScreenWidth()*bpp
/8, &mva
);
1778 pr_info("disphal_map_overlay_out_buffer fail! \n");
1779 return DISP_STATUS_OK
;
1781 disphal_init_overlay_to_memory();
1783 mutex_lock(&MemOutSettingMutex
);
1785 MemOutConfig
.outFormat
= eARGB8888
;
1787 MemOutConfig
.outFormat
= eRGB565
;
1789 MemOutConfig
.outFormat
= eRGB888
;
1792 pr_info("DSI_Capture_FB, fb color format not support\n");
1793 MemOutConfig
.outFormat
= eRGB888
;
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();
1803 DISP_LOG("DISP_Capture_Framebuffer, dst addr pvbuf: 0x%x, bpp: %d\n", pvbuf
, bpp
);
1805 if (is_early_suspended
== 0)
1807 disp_path_clear_mem_out_done_flag(); // clear last time mem_out_done flag
1808 MemOutConfig
.dirty
= 1;
1811 mutex_unlock(&MemOutSettingMutex
);
1812 MMProfileLogEx(MTKFB_MMP_Events
.CaptureFramebuffer
, MMProfileFlagPulse
, 2, mva
);
1813 if (is_early_suspended
)
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();
1828 MMP_MetaDataBitmap_t Bitmap
;
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");
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
;
1847 MMProfileLogMetaBitmap(MTKFB_MMP_Events
.CaptureFramebuffer
, MMProfileFlagPulse
, &Bitmap
);
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);
1859 MemOutConfig
.enable
= 0;
1860 disp_path_config_mem_out(&MemOutConfig
);
1863 DISP_LOG("DISP_Capture_Framebuffer, reg update done\n");
1866 disphal_unmap_overlay_out_buffer(pvbuf
, DISP_GetScreenHeight()*DISP_GetScreenWidth()*bpp
/8, mva
);
1868 return DISP_STATUS_OK
;
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
)
1876 disp_drv_init_context();
1879 disphal_enable_te(FALSE
);
1883 if(disp_if_drv
->init_te_control
)
1884 disp_if_drv
->init_te_control();
1886 return DISP_STATUS_NOT_IMPLEMENTED
;
1889 is_immediateupdate
= enable
;
1891 return DISP_STATUS_OK
;
1894 BOOL
DISP_IsImmediateUpdate(void)
1896 return is_immediateupdate
;
1900 DISP_STATUS
DISP_Get_Default_UpdateSpeed(unsigned int *speed
)
1902 return disphal_get_default_updatespeed(speed
);
1905 DISP_STATUS
DISP_Get_Current_UpdateSpeed(unsigned int *speed
)
1907 return disphal_get_current_updatespeed(speed
);
1910 DISP_STATUS
DISP_Change_Update(unsigned int speed
)
1912 DISP_STATUS ret
= DISP_STATUS_OK
;
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
;
1919 ret
= disphal_change_updatespeed(speed
);
1921 up(&sem_update_screen
);
1927 const char* DISP_GetLCMId(void)
1930 return lcm_drv
->name
;
1936 BOOL
DISP_EsdCheck(void)
1938 BOOL result
= FALSE
;
1940 disp_drv_init_context();
1941 MMProfileLogEx(MTKFB_MMP_Events
.EsdCheck
, MMProfileFlagPulse
, 0x10, 0);
1943 if(lcm_drv
->esd_check
== NULL
&& disp_if_drv
->esd_check
== NULL
)
1948 if (down_interruptible(&sem_update_screen
)) {
1949 pr_info("ERROR: Can't get sem_update_screen in DISP_EsdCheck()\n");
1952 MMProfileLogEx(MTKFB_MMP_Events
.EsdCheck
, MMProfileFlagPulse
, 0x11, 0);
1954 if(is_lcm_in_suspend_mode
)
1956 up(&sem_update_screen
);
1960 if(disp_if_drv
->esd_check
)
1961 result
|= disp_if_drv
->esd_check();
1962 MMProfileLogEx(MTKFB_MMP_Events
.EsdCheck
, MMProfileFlagPulse
, 0x12, 0);
1964 up(&sem_update_screen
);
1970 BOOL
DISP_EsdRecoverCapbility(void)
1972 if(!disp_drv_init_context())
1975 if((lcm_drv
->esd_check
&& lcm_drv
->esd_recover
) || (lcm_params
->dsi
.lcm_ext_te_monitor
) || (lcm_params
->dsi
.lcm_int_te_monitor
))
1985 BOOL
DISP_EsdRecover(void)
1987 BOOL result
= FALSE
;
1988 DISP_LOG("DISP_EsdRecover enter");
1990 if(lcm_drv
->esd_recover
== NULL
)
1995 if (down_interruptible(&sem_update_screen
)) {
1996 pr_info("ERROR: Can't get sem_update_screen in DISP_EsdRecover()\n");
2000 if(is_lcm_in_suspend_mode
)
2002 up(&sem_update_screen
);
2006 disphal_wait_not_busy();
2008 DISP_LOG("DISP_EsdRecover do LCM recover");
2010 // do necessary configuration reset for LCM re-init
2011 if(disp_if_drv
->esd_reset
)
2012 disp_if_drv
->esd_reset();
2015 mutex_lock(&LcmCmdMutex
);
2016 result
= lcm_drv
->esd_recover();
2017 mutex_unlock(&LcmCmdMutex
);
2019 if ((lcm_params
->type
== LCM_TYPE_DSI
) && (lcm_params
->dsi
.mode
!= CMD_MODE
))
2021 is_video_mode_running
= false;
2022 needStartEngine
= true;
2025 up(&sem_update_screen
);
2030 unsigned long DISP_GetLCMIndex(void)
2032 return u4IndexOfLCMList
;
2035 DISP_STATUS
DISP_PrepareSuspend(void)
2037 disphal_prepare_suspend();
2038 return DISP_STATUS_OK
;
2041 DISP_STATUS
DISP_GetLayerInfo(DISP_LAYER_INFO
*pLayer
)
2043 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
2044 int id
= pLayer
->id
;
2046 mutex_lock(&OverlaySettingMutex
);
2047 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
2048 Disp_Ovl_Engine_Get_Ovl_layer_info(mtkfb_instance
, pLayer
);
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
;
2063 mutex_unlock(&OverlaySettingMutex
);
2064 return DISP_STATUS_OK
;
2066 void DISP_Change_LCM_Resolution(unsigned int width
, unsigned int height
)
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
;
2078 BOOL
DISP_IsDecoupleMode(void)