import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / video / mt8127 / mtkfb.c
CommitLineData
6fa3eb70
S
1#include <generated/autoconf.h>
2#include <linux/module.h>
3#include <linux/mm.h>
4#include <linux/init.h>
5#include <linux/fb.h>
6#include <linux/delay.h>
7#include <linux/device.h>
8#include <linux/platform_device.h>
9#include <linux/dma-mapping.h>
10#include <linux/earlysuspend.h>
11#include <linux/kthread.h>
12#include <linux/rtpm_prio.h>
13#include <linux/vmalloc.h>
14#include <linux/disp_assert_layer.h>
15#include <linux/semaphore.h>
16#include <linux/xlog.h>
17#include <linux/mutex.h>
18#include <linux/leds-mt65xx.h>
19#include <linux/file.h>
20#include <linux/ion_drv.h>
21#include <linux/list.h>
22
23
24#include <asm/uaccess.h>
25#include <asm/atomic.h>
26#include <asm/mach-types.h>
27#include <asm/cacheflush.h>
28#include <asm/io.h>
29
30#include <mach/dma.h>
31#include <mach/irqs.h>
32#include <mach/m4u_port.h>
33#include <linux/dma-mapping.h>
34
35#include "mach/mt_boot.h"
36
37#include "debug.h"
38#include "disp_drv.h"
39#include "ddp_hal.h"
40#include "disp_drv_log.h"
41#include "disp_hal.h"
42
43#include "mtkfb.h"
44#include "mtkfb_console.h"
45#include "mtkfb_info.h"
46#include "ddp_ovl.h"
47#include "mtkfb_priv.h"
48#if defined(MTK_OVERLAY_ENGINE_SUPPORT)
49#include "disp_ovl_engine_api.h"
50#include "disp_ovl_engine_hw.h"
51#include "disp_ovl_engine_core.h"
52#endif
53
54// for MTK_HDMI_MAIN_PATH
55#include "disp_drv_platform.h"
56
57#define NONFLUSH
58
59
60#define MTK_FB_ALIGNMENT 16
61#define ALIGN_TO(x, n) \
62 (((x) + ((n) - 1)) & ~((n) - 1))
63
64//#undef pr_info
65//#define pr_info printk
66
67unsigned int EnableVSyncLog = 0;
68
69static u32 MTK_FB_XRES = 0;
70static u32 MTK_FB_YRES = 0;
71static u32 MTK_FB_BPP = 0;
72static u32 MTK_FB_PAGES = 0;
73static u32 fb_xres_update = 0;
74static u32 fb_yres_update = 0;
75
76#define MTK_FB_XRESV (ALIGN_TO(MTK_FB_XRES, disphal_get_fb_alignment()))
77#define MTK_FB_YRESV (ALIGN_TO(MTK_FB_YRES, disphal_get_fb_alignment()) * MTK_FB_PAGES) /* For page flipping */
78#define MTK_FB_BYPP ((MTK_FB_BPP + 7) >> 3)
79#define MTK_FB_LINE (ALIGN_TO(MTK_FB_XRES, disphal_get_fb_alignment()) * MTK_FB_BYPP)
80#define MTK_FB_SIZE (MTK_FB_LINE * ALIGN_TO(MTK_FB_YRES, disphal_get_fb_alignment()))
81
82#define MTK_FB_SIZEV (MTK_FB_LINE * ALIGN_TO(MTK_FB_YRES, disphal_get_fb_alignment()) * MTK_FB_PAGES)
83
84#define CHECK_RET(expr) \
85 do { \
86 int ret = (expr); \
87 ASSERT(0 == ret); \
88 } while (0)
89
90
91static size_t mtkfb_log_on = false;
92#define MTKFB_LOG(fmt, arg...) \
93 do { \
94 if (mtkfb_log_on) DISP_LOG_PRINT(ANDROID_LOG_WARN, "MTKFB", fmt, ##arg); \
95 }while (0)
96
97#define MTKFB_FUNC() \
98 do { \
99 if(mtkfb_log_on) DISP_LOG_PRINT(ANDROID_LOG_INFO, "MTKFB", "[Func]%s\n", __func__); \
100 }while (0)
101
102
103#define MTKFB_MSG(fmt, arg...) \
104 do { \
105 pr_err("[MTKFB] mt8127 "fmt, ##arg); \
106 }while (0)
107#define PRNERR(fmt, args...) DISP_LOG_PRINT(ANDROID_LOG_INFO, "MTKFB", fmt, ## args);
108/* [PLATFORM]-Add-BEGIN by TCTSZ.yaohui.zeng, 2015/04/15,MTK patch,fix FB suspend/resume DSI issue*/
109extern BOOL _IsEngineBusy(void);
110extern wait_queue_head_t _dsi_wait_vm_done_queue;
111/* [PLATFORM]-Add-END by TCTSZ.yaohui.zeng, 2015/04/15*/
112
113void mtkfb_log_enable(int enable)
114{
115 mtkfb_log_on = enable;
116 MTKFB_LOG("mtkfb log %s\n", enable?"enabled":"disabled");
117}
118
119void mtkfb_clear_lcm(void);
120
121//int ion_handle_note[1024] = {0}; //mtk02420
122
123// ---------------------------------------------------------------------------
124// local variables
125// ---------------------------------------------------------------------------
126
127unsigned int fb_pa = 0;
128static BOOL mtkfb_enable_mmu = TRUE;
129
130static const struct timeval FRAME_INTERVAL = {0, 30000}; // 33ms
131
132atomic_t has_pending_update = ATOMIC_INIT(0);
133struct fb_overlay_layer video_layerInfo;
134UINT32 dbr_backup = 0;
135UINT32 dbg_backup = 0;
136UINT32 dbb_backup = 0;
137bool fblayer_dither_needed = false;
138static unsigned int video_rotation = 0;
139static UINT32 mtkfb_using_layer_type = LAYER_2D;
140static bool hwc_force_fb_enabled = true;
141bool is_ipoh_bootup = false;
142struct fb_info *mtkfb_fbi;
143struct fb_overlay_layer fb_layer_context;
144
145unsigned int decouple_addr = 0; // It's PA = MVA after m4u mapping
146unsigned int decouple_size = 0;
147
148extern unsigned int g_fb_pattern_en;
149extern int fb_pattern(struct mtkfb_device *fbdev, struct fb_overlay_config *fb_config);
150extern wait_queue_head_t _dsi_wait_vm_done_queue;
151extern BOOL _IsEngineBusy(void);
152/* This mutex is used to prevent tearing due to page flipping when adbd is
153 reading the front buffer
154*/
155DEFINE_SEMAPHORE(sem_flipping);
156DEFINE_SEMAPHORE(sem_early_suspend);
157DEFINE_SEMAPHORE(sem_overlay_buffer);
158
159#if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
160extern OVL_CONFIG_STRUCT cached_layer_config[DDP_OVL_LAYER_MUN];
161#endif
162DEFINE_MUTEX(OverlaySettingMutex);
163atomic_t OverlaySettingDirtyFlag = ATOMIC_INIT(0);
164atomic_t OverlaySettingApplied = ATOMIC_INIT(0);
165unsigned int PanDispSettingPending = 0;
166unsigned int PanDispSettingDirty = 0;
167unsigned int PanDispSettingApplied = 0;
168
169DECLARE_WAIT_QUEUE_HEAD(reg_update_wq);
170
171unsigned int need_esd_check = 0;
172DECLARE_WAIT_QUEUE_HEAD(esd_check_wq);
173
174extern unsigned int disp_running;
175extern wait_queue_head_t disp_done_wq;
176
177DEFINE_MUTEX(ScreenCaptureMutex);
178
179BOOL is_early_suspended = FALSE;
180static int sem_flipping_cnt = 1;
181static int sem_early_suspend_cnt = 1;
182static int sem_overlay_buffer_cnt = 1;
183static int vsync_cnt = 0;
184
185#if defined(MTK_OVERLAY_ENGINE_SUPPORT)
186DISP_OVL_ENGINE_INSTANCE_HANDLE mtkfb_instance = 0xff;
187#endif
188extern BOOL is_engine_in_suspend_mode;
189extern BOOL is_lcm_in_suspend_mode;
190
191// ---------------------------------------------------------------------------
192// local function declarations
193// ---------------------------------------------------------------------------
194
195static int init_framebuffer(struct fb_info *info);
196//static int mtkfb_set_overlay_config(struct mtkfb_device *fbdev,
197// struct fb_overlay_config* config, struct sync_fence* fences[]);
198int mtkfb_queue_overlay_config(struct mtkfb_device *fbdev,
199 struct fb_overlay_config* config);
200static int mtkfb_set_overlay_layer(struct mtkfb_device *fbdev,
201 struct fb_overlay_layer* layerInfo);
202static int mtkfb_get_overlay_layer_info(struct fb_overlay_layer_info* layerInfo);
203static int mtkfb_update_screen(struct fb_info *info);
204static void mtkfb_update_screen_impl(void);
205
206#if defined(MTK_HDMI_SUPPORT)
207extern void hdmi_setorientation(int orientation);
208extern void MTK_HDMI_Set_Security_Output(int enable);
209/* temporary solution for hdmi svp p1, always mute hdmi for svp */
210void MTK_HDMI_Set_Security_Output_SVP_P1(int enable);
211#endif
212
213// ---------------------------------------------------------------------------
214// Timer Routines
215// ---------------------------------------------------------------------------
216static struct task_struct *screen_update_task = NULL;
217static struct task_struct *esd_recovery_task = NULL;
218unsigned int lcd_fps = 6000;
219wait_queue_head_t screen_update_wq;
220extern BOOL dal_shown;
221
222/* Grallc extra bit type */
223enum {
224 GRALLOC_EXTRA_BIT_TYPE_CPU = 0x00000000,
225 GRALLOC_EXTRA_BIT_TYPE_GPU = 0x00000001,
226 GRALLOC_EXTRA_BIT_TYPE_VIDEO = 0x00000002,
227 GRALLOC_EXTRA_BIT_TYPE_CAMERA = 0x00000003,
228 GRALLOC_EXTRA_MASK_TYPE = 0x00000003,
229};
230
231
232#if defined(DFO_USE_NEW_API)
233#if 1
234extern int dfo_query(const char *s, unsigned long *v);
235#endif
236#else
237 #include <mach/dfo_boot.h>
238static disp_dfo_item_t disp_dfo_setting[] =
239{
240 {"LCM_FAKE_WIDTH", 0},
241 {"LCM_FAKE_HEIGHT", 0},
242 {"DISP_DEBUG_SWITCH", 0}
243};
244
245#define MT_DISP_DFO_DEBUG
246#ifdef MT_DISP_DFO_DEBUG
247#define disp_dfo_printf(string, args...) printk("[DISP/DFO]"string, ##args)
248#else
249#define disp_dfo_printf(string, args...) ()
250#endif
251
252// this function will be called in mt_fixup()@mt_devs.c. which will send DFO information organized as tag_dfo_boot struct.
253// because lcm_params isn't inited here, so we will change lcm_params later in mtkfb_probe.
254unsigned int mtkfb_parse_dfo_setting(void *dfo_tbl, int num)
255{
256 char *disp_name = NULL;
257 //int *disp_value;
258 char *tag_name;
259 int tag_value;
260 int i, j;
261 tag_dfo_boot *dfo_data;
262
263 disp_dfo_printf("enter mtkfb_parse_dfo_setting\n");
264
265 if(dfo_tbl == NULL)
266 return -1;
267
268 dfo_data = (tag_dfo_boot *)dfo_tbl;
269 for (i=0; i<(sizeof(disp_dfo_setting)/sizeof(disp_dfo_item_t)); i++)
270 {
271 disp_name = disp_dfo_setting[i].name;
272
273 for (j=0; j<num; j++)
274 {
275 tag_name = dfo_data->name[j];
276 tag_value = dfo_data->value[j];
277 if(!strcmp(disp_name, tag_name))
278 {
279 disp_dfo_setting[i].value = tag_value;
280 disp_dfo_printf("%s = [DEC]%d [HEX]0x%08x\n", disp_dfo_setting[i].name, disp_dfo_setting[i].value, disp_dfo_setting[i].value);
281 }
282 }
283 }
284
285 disp_dfo_printf("leave mtkfb_parse_dfo_setting\n");
286
287 return 0;
288}
289
290int mtkfb_get_dfo_setting(const char *string, unsigned int *value)
291{
292 char *disp_name;
293 int disp_value;
294 int i;
295
296 if(string == NULL)
297 return -1;
298
299 for (i=0; i<(sizeof(disp_dfo_setting)/sizeof(disp_dfo_item_t)); i++)
300 {
301 disp_name = disp_dfo_setting[i].name;
302 disp_value = disp_dfo_setting[i].value;
303 if(!strcmp(disp_name, string))
304 {
305 *value = disp_value;
306 disp_dfo_printf("%s = [DEC]%d [HEX]0x%08x\n", disp_name, disp_value, disp_value);
307 return 0;
308 }
309 }
310
311 return 0;
312}
313#endif
314
315
316void mtkfb_pan_disp_test(void)
317{
318 MTKFB_FUNC();
319 if (down_interruptible(&sem_flipping)) {
320 pr_info("[fb driver] can't get semaphore:%d\n", __LINE__);
321 return;
322 }
323 sem_flipping_cnt--;
324 DISP_LOG_PRINT(ANDROID_LOG_WARN, "MTKFB", "wait sem_flipping\n");
325 if (down_interruptible(&sem_early_suspend)) {
326 pr_info("[fb driver] can't get semaphore:%d\n", __LINE__);
327 sem_flipping_cnt++;
328 up(&sem_flipping);
329 return;
330 }
331 sem_early_suspend_cnt--;
332
333 DISP_LOG_PRINT(ANDROID_LOG_WARN, "MTKFB", "wait sem_early_suspend\n");
334 if (down_interruptible(&sem_overlay_buffer)) {
335 pr_info("[fb driver] can't get semaphore,%d\n", __LINE__);
336 sem_early_suspend_cnt++;
337 up(&sem_early_suspend);
338
339 sem_flipping_cnt++;
340 up(&sem_flipping);
341 return;
342 }
343 sem_overlay_buffer_cnt--;
344 DISP_LOG_PRINT(ANDROID_LOG_WARN, "MTKFB", "wait sem_overlay_buffer\n");
345 if (is_early_suspended) goto end;
346
347end:
348 sem_overlay_buffer_cnt++;
349 sem_early_suspend_cnt++;
350 sem_flipping_cnt++;
351 up(&sem_overlay_buffer);
352 up(&sem_early_suspend);
353 up(&sem_flipping);
354}
355
356void mtkfb_show_sem_cnt(void)
357{
358 pr_info("[FB driver: sem cnt = %d, %d, %d. fps = %d, vsync_cnt = %d\n", sem_overlay_buffer_cnt, sem_early_suspend_cnt, sem_flipping_cnt, lcd_fps, vsync_cnt);
359 pr_info("[FB driver: sem cnt = %d, %d, %d\n", sem_overlay_buffer.count, sem_early_suspend.count, sem_flipping.count);
360}
361
362void mtkfb_hang_test(bool en)
363{
364 MTKFB_FUNC();
365 if(en){
366 if (down_interruptible(&sem_flipping)) {
367 pr_info("[fb driver] can't get semaphore:%d\n", __LINE__);
368 return;
369 }
370 sem_flipping_cnt--;
371 }
372 else{
373 sem_flipping_cnt++;
374 up(&sem_flipping);
375 }
376}
377
378BOOL esd_kthread_pause = TRUE;
379
380void esd_recovery_pause(BOOL en)
381{
382 esd_kthread_pause = en;
383}
384
385static int esd_recovery_kthread(void *data)
386{
387 //struct sched_param param = { .sched_priority = RTPM_PRIO_SCRN_UPDATE };
388 //sched_setscheduler(current, SCHED_RR, &param);
389 MTKFB_LOG("enter esd_recovery_kthread()\n");
390 for( ;; ) {
391
392 if (kthread_should_stop())
393 break;
394
395 MTKFB_LOG("sleep start in esd_recovery_kthread()\n");
396 msleep(2000); //2s
397 MTKFB_LOG("sleep ends in esd_recovery_kthread()\n");
398
399 if(!esd_kthread_pause)
400 {
401 if(is_early_suspended)
402 {
403 MTKFB_LOG("is_early_suspended in esd_recovery_kthread()\n");
404 continue;
405 }
406 ///execute ESD check and recover flow
407 MTKFB_LOG("DISP_EsdCheck starts\n");
408 need_esd_check = 1;
409 wait_event_interruptible(esd_check_wq, !need_esd_check);
410 MTKFB_LOG("DISP_EsdCheck ends\n");
411 }
412 }
413
414
415 MTKFB_LOG("exit esd_recovery_kthread()\n");
416 return 0;
417}
418
419
420/*
421 * ---------------------------------------------------------------------------
422 * mtkfb_set_lcm_inited() will be called in mt6516_board_init()
423 * ---------------------------------------------------------------------------
424 */
425static BOOL is_lcm_inited = FALSE;
426void mtkfb_set_lcm_inited(BOOL inited)
427{
428 is_lcm_inited = inited;
429}
430
431/*
432 * ---------------------------------------------------------------------------
433 * fbdev framework callbacks and the ioctl interface
434 * ---------------------------------------------------------------------------
435 */
436/* Called each time the mtkfb device is opened */
437#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
438static int mtkfb_open(struct file *file, struct fb_info *info, int user)
439#else
440static int mtkfb_open(struct fb_info *info, int user)
441#endif
442{
443 NOT_REFERENCED(info);
444 NOT_REFERENCED(user);
445
446 MTKFB_FUNC();
447
448 MSG_FUNC_ENTER();
449 MSG_FUNC_LEAVE();
450 return 0;
451}
452
453/* Called when the mtkfb device is closed. We make sure that any pending
454 * gfx DMA operations are ended, before we return. */
455#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)
456static int mtkfb_release(struct file *file, struct fb_info *info, int user)
457#else
458static int mtkfb_release(struct fb_info *info, int user)
459#endif
460
461{
462
463 NOT_REFERENCED(info);
464 NOT_REFERENCED(user);
465
466 MTKFB_FUNC();
467
468 MSG_FUNC_ENTER();
469 MSG_FUNC_LEAVE();
470 return 0;
471}
472
473/* Store a single color palette entry into a pseudo palette or the hardware
474 * palette if one is available. For now we support only 16bpp and thus store
475 * the entry only to the pseudo palette.
476 */
477static int mtkfb_setcolreg(u_int regno, u_int red, u_int green,
478 u_int blue, u_int transp,
479 struct fb_info *info)
480{
481 int r = 0;
482 unsigned bpp, m;
483
484 NOT_REFERENCED(transp);
485
486 MSG_FUNC_ENTER();
487
488 bpp = info->var.bits_per_pixel;
489 m = 1 << bpp;
490 if (regno >= m)
491 {
492 r = -EINVAL;
493 goto exit;
494 }
495
496 switch (bpp)
497 {
498 case 16:
499 /* RGB 565 */
500 ((u32 *)(info->pseudo_palette))[regno] =
501 ((red & 0xF800) |
502 ((green & 0xFC00) >> 5) |
503 ((blue & 0xF800) >> 11));
504 break;
505 case 32:
506 /* ARGB8888 */
507 ((u32 *)(info->pseudo_palette))[regno] =
508 (0xff000000) |
509 ((red & 0xFF00) << 8) |
510 ((green & 0xFF00) ) |
511 ((blue & 0xFF00) >> 8);
512 break;
513
514 // TODO: RGB888, BGR888, ABGR8888
515
516 default:
517 ASSERT(0);
518 }
519
520exit:
521 MSG_FUNC_LEAVE();
522 return r;
523}
524
525static void mtkfb_update_screen_impl(void)
526{
527 BOOL down_sem = FALSE;
528 MTKFB_FUNC();
529 MMProfileLog(MTKFB_MMP_Events.UpdateScreenImpl, MMProfileFlagStart);
530 if (down_interruptible(&sem_overlay_buffer)) {
531 pr_info("[FB Driver] can't get semaphore in mtkfb_update_screen_impl()\n");
532 }
533 else{
534 down_sem = TRUE;
535 sem_overlay_buffer_cnt--;
536 }
537
538 DISP_CHECK_RET(DISP_UpdateScreen(0, 0, fb_xres_update, fb_yres_update));
539
540 if(down_sem){
541 sem_overlay_buffer_cnt++;
542 up(&sem_overlay_buffer);
543 }
544 MMProfileLog(MTKFB_MMP_Events.UpdateScreenImpl, MMProfileFlagEnd);
545}
546
547
548static int mtkfb_update_screen(struct fb_info *info)
549{
550 MTKFB_FUNC();
551 if (down_interruptible(&sem_early_suspend)) {
552 pr_info("[FB Driver] can't get semaphore in mtkfb_update_screen()\n");
553 return -ERESTARTSYS;
554 }
555 sem_early_suspend_cnt--;
556 if (is_early_suspended) goto End;
557 mtkfb_update_screen_impl();
558
559End:
560 sem_early_suspend_cnt++;
561 up(&sem_early_suspend);
562 return 0;
563}
564static unsigned int BL_level = 0;
565static BOOL BL_set_level_resume = FALSE;
566int mtkfb_set_backlight_level(unsigned int level)
567{
568 MTKFB_FUNC();
569 pr_info("mtkfb_set_backlight_level:%d\n", level);
570 if (down_interruptible(&sem_flipping)) {
571 pr_info("[FB Driver] can't get semaphore:%d\n", __LINE__);
572 return -ERESTARTSYS;
573 }
574 sem_flipping_cnt--;
575 if (down_interruptible(&sem_early_suspend)) {
576 pr_info("[FB Driver] can't get semaphore:%d\n", __LINE__);
577 sem_flipping_cnt++;
578 up(&sem_flipping);
579 return -ERESTARTSYS;
580 }
581
582 sem_early_suspend_cnt--;
583 if (is_early_suspended){
584 BL_level = level;
585 BL_set_level_resume = TRUE;
586 pr_info("[FB driver] set backlight level but FB has been suspended\n");
587 goto End;
588 }
589 DISP_SetBacklight(level);
590 BL_set_level_resume = FALSE;
591End:
592 sem_flipping_cnt++;
593 sem_early_suspend_cnt++;
594 up(&sem_early_suspend);
595 up(&sem_flipping);
596 return 0;
597}
598
599EXPORT_SYMBOL(mtkfb_set_backlight_level);
600
601int mtkfb_set_backlight_mode(unsigned int mode)
602{
603 MTKFB_FUNC();
604 if (down_interruptible(&sem_flipping)) {
605 pr_info("[FB Driver] can't get semaphore:%d\n", __LINE__);
606 return -ERESTARTSYS;
607 }
608 sem_flipping_cnt--;
609 if (down_interruptible(&sem_early_suspend)) {
610 pr_info("[FB Driver] can't get semaphore:%d\n", __LINE__);
611 sem_flipping_cnt++;
612 up(&sem_flipping);
613 return -ERESTARTSYS;
614 }
615
616 sem_early_suspend_cnt--;
617 if (is_early_suspended) goto End;
618
619 DISP_SetBacklight_mode(mode);
620End:
621 sem_flipping_cnt++;
622 sem_early_suspend_cnt++;
623 up(&sem_early_suspend);
624 up(&sem_flipping);
625 return 0;
626}
627
628EXPORT_SYMBOL(mtkfb_set_backlight_mode);
629
630
631int mtkfb_set_backlight_pwm(int div)
632{
633 MTKFB_FUNC();
634 if (down_interruptible(&sem_flipping)) {
635 pr_info("[FB Driver] can't get semaphore:%d\n", __LINE__);
636 return -ERESTARTSYS;
637 }
638 sem_flipping_cnt--;
639 if (down_interruptible(&sem_early_suspend)) {
640 pr_info("[FB Driver] can't get semaphore:%d\n", __LINE__);
641 sem_flipping_cnt++;
642 up(&sem_flipping);
643 return -ERESTARTSYS;
644 }
645 sem_early_suspend_cnt--;
646 if (is_early_suspended) goto End;
647 DISP_SetPWM(div);
648End:
649 sem_flipping_cnt++;
650 sem_early_suspend_cnt++;
651 up(&sem_early_suspend);
652 up(&sem_flipping);
653 return 0;
654}
655
656EXPORT_SYMBOL(mtkfb_set_backlight_pwm);
657
658int mtkfb_get_backlight_pwm(int div, unsigned int *freq)
659{
660 DISP_GetPWM(div, freq);
661 return 0;
662}
663
664EXPORT_SYMBOL(mtkfb_get_backlight_pwm);
665
666void mtkfb_waitVsync(void)
667{
668 if(is_early_suspended){
669 pr_info("[MTKFB_VSYNC]:mtkfb has suspend, return directly\n");
670 msleep(20);
671 return;
672 }
673 vsync_cnt++;
674 DISP_WaitVSYNC();
675 vsync_cnt--;
676 return;
677}
678
679EXPORT_SYMBOL(mtkfb_waitVsync);
680/* Used for HQA test */
681/*-------------------------------------------------------------
682 Note: The using scenario must be
683 1. switch normal mode to factory mode when LCD screen is on
684 2. switch factory mode to normal mode(optional)
685-------------------------------------------------------------*/
686static struct fb_var_screeninfo fbi_var_backup;
687static struct fb_fix_screeninfo fbi_fix_backup;
688static BOOL need_restore = FALSE;
689static int mtkfb_set_par(struct fb_info *fbi);
690void mtkfb_switch_normal_to_factory(void)
691{
692 if (down_interruptible(&sem_flipping)) {
693 pr_info("[FB Driver] can't get semaphore:%d\n", __LINE__);
694 return;
695 }
696 sem_flipping_cnt--;
697 if (down_interruptible(&sem_early_suspend)) {
698 pr_info("[FB Driver] can't get semaphore:%d\n", __LINE__);
699 sem_flipping_cnt++;
700 up(&sem_flipping);
701 return;
702 }
703 sem_early_suspend_cnt--;
704 if (is_early_suspended) {
705 goto EXIT;
706 }
707
708 if (mtkfb_fbi)
709 {
710 memcpy(&fbi_var_backup, &mtkfb_fbi->var, sizeof(fbi_var_backup));
711 memcpy(&fbi_fix_backup, &mtkfb_fbi->fix, sizeof(fbi_fix_backup));
712 need_restore = TRUE;
713 }
714
715EXIT:
716 sem_early_suspend_cnt++;
717 sem_flipping_cnt++;
718 up(&sem_early_suspend);
719 up(&sem_flipping);
720}
721
722/* Used for HQA test */
723void mtkfb_switch_factory_to_normal(void)
724{
725 BOOL need_set_par = FALSE;
726 if (down_interruptible(&sem_flipping)) {
727 pr_info("[FB Driver] can't get semaphore in mtkfb_switch_factory_to_normal()\n");
728 return;
729 }
730 sem_flipping_cnt--;
731 if (down_interruptible(&sem_early_suspend)) {
732 pr_info("[FB Driver] can't get semaphore in mtkfb_switch_factory_to_normal()\n");
733 sem_flipping_cnt++;
734 up(&sem_flipping);
735 return;
736 }
737
738 sem_early_suspend_cnt--;
739 if (is_early_suspended) {
740 goto EXIT;
741 }
742
743 if ((mtkfb_fbi) && (need_restore))
744 {
745 memcpy(&mtkfb_fbi->var, &fbi_var_backup, sizeof(fbi_var_backup));
746 memcpy(&mtkfb_fbi->fix, &fbi_fix_backup, sizeof(fbi_fix_backup));
747 need_restore = FALSE;
748 need_set_par = TRUE;
749 }
750
751EXIT:
752 sem_early_suspend_cnt++;
753 sem_flipping_cnt++;
754 up(&sem_early_suspend);
755 up(&sem_flipping);
756 if (need_set_par)
757 {
758 int ret;
759 ret = mtkfb_set_par(mtkfb_fbi);
760 if (ret != 0)
761 PRNERR("failed to mtkfb_set_par\n");
762 }
763}
764
765static bool first_update = true;
766static bool first_enable_esd = true;
767static bool no_update = false;
768static int cnt=3;
769static int mtkfb_pan_display_impl(struct fb_var_screeninfo *var, struct fb_info *info)
770{
771 UINT32 offset;
772 UINT32 paStart;
773 char *vaStart, *vaEnd;
774 int ret = 0;
775 int wait_ret = 0;
776 if(first_update && no_update){
777 first_update = false;
778 return ret;
779 }
780 MMProfileLogStructure(MTKFB_MMP_Events.PanDisplay, MMProfileFlagStart, var, struct fb_var_screeninfo);
781 if(0!=cnt){
782 pr_info("LCD:%dx%d\n",MTK_FB_XRES,MTK_FB_YRES);
783 cnt--;
784 }
785 MTKFB_FUNC();
786
787 MSG_FUNC_ENTER();
788
789 MSG(ARGU, "xoffset=%u, yoffset=%u, xres=%u, yres=%u, xresv=%u, yresv=%u\n",
790 var->xoffset, var->yoffset,
791 info->var.xres, info->var.yres,
792 info->var.xres_virtual,
793 info->var.yres_virtual);
794
795 if (down_interruptible(&sem_flipping)) {
796 pr_info("[FB Driver] can't get semaphore in mtkfb_pan_display_impl()\n");
797 MMProfileLogMetaString(MTKFB_MMP_Events.PanDisplay, MMProfileFlagEnd, "Can't get semaphore in mtkfb_pan_display_impl()");
798 return -ERESTARTSYS;
799 }
800 sem_flipping_cnt--;
801
802 info->var.yoffset = var->yoffset;
803
804 offset = var->yoffset * info->fix.line_length;
805 paStart = fb_pa + offset;
806 vaStart = info->screen_base + offset;
807 vaEnd = vaStart + info->var.yres * info->fix.line_length;
808
809 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
810 {
811 struct fb_overlay_layer layerInfo = {0};
812 layerInfo.layer_id = 0;//FB_LAYER;
813 layerInfo.layer_enable = TRUE;
814 layerInfo.src_base_addr = (void *)((unsigned int)vaStart);
815 layerInfo.src_phy_addr = (void *)paStart;
816 layerInfo.src_direct_link = 0;
817 switch(var->bits_per_pixel)
818 {
819 case 16:
820 layerInfo.src_fmt = MTK_FB_FORMAT_RGB565;
821 break;
822 case 24:
823 layerInfo.src_fmt = MTK_FB_FORMAT_RGB888;
824 break;
825 case 32:
826 layerInfo.src_fmt = MTK_FB_FORMAT_ARGB8888;
827 break;
828 default:
829 PRNERR("Invalid color format bpp: 0x%d\n", var->bits_per_pixel);
830 return -1;
831 }
832 layerInfo.src_use_color_key = 0;
833 layerInfo.src_color_key = 0xFF;
834 layerInfo.src_pitch = ALIGN_TO(var->xres, disphal_get_fb_alignment());
835 layerInfo.src_offset_x = 0;
836 layerInfo.src_offset_y = 0;
837 layerInfo.src_width = var->xres;
838 layerInfo.src_height = var->yres;
839 layerInfo.tgt_offset_x = 0;
840 layerInfo.tgt_offset_y = 0;
841 layerInfo.tgt_width = var->xres;
842 layerInfo.tgt_height = var->yres;
843 layerInfo.layer_rotation = MTK_FB_ORIENTATION_0;
844 layerInfo.layer_type = LAYER_2D;
845 layerInfo.video_rotation = MTK_FB_ORIENTATION_0;
846 layerInfo.isTdshp = TRUE; // set to 1, will go through tdshp first, then layer blending, then to color
847 layerInfo.next_buff_idx = -1;
848 layerInfo.identity = 0;
849 layerInfo.connected_type = 0;
850 layerInfo.security = 0;
851 pr_info("[mtkfb] pan display set va=0x%x, pa=0x%x \n",(unsigned int)vaStart,paStart);
852 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, &layerInfo);
853
4b9e9796
S
854 if(get_boot_mode() != FACTORY_BOOT)
855 {
856 layerInfo.layer_id = 1;
857 layerInfo.layer_enable = FALSE;
858 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, &layerInfo);
859 layerInfo.layer_id = 2;
860 layerInfo.layer_enable = FALSE;
861 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, &layerInfo);
862 layerInfo.layer_id = 3;
863 layerInfo.layer_enable = FALSE;
864 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, &layerInfo);
865 }
6fa3eb70
S
866 }
867 #else
868 mutex_lock(&OverlaySettingMutex);
869 DISP_CHECK_RET(DISP_SetFrameBufferAddr(paStart));
870 cached_layer_config[FB_LAYER].vaddr = (unsigned int)vaStart;
871 cached_layer_config[FB_LAYER].layer_en = 1;
872 cached_layer_config[FB_LAYER].src_x = 0;
873 cached_layer_config[FB_LAYER].src_y = 0;
874 cached_layer_config[FB_LAYER].src_w = var->xres;
875 cached_layer_config[FB_LAYER].src_h = var->yres;
876 cached_layer_config[FB_LAYER].dst_x = 0;
877 cached_layer_config[FB_LAYER].dst_y = 0;
878 cached_layer_config[FB_LAYER].dst_w = var->xres;
879 cached_layer_config[FB_LAYER].dst_h = var->yres;
880 {
881 unsigned int layerpitch;
882 unsigned int src_pitch = ALIGN_TO(var->xres, disphal_get_fb_alignment());
883 switch(var->bits_per_pixel)
884 {
885 case 16:
886 cached_layer_config[FB_LAYER].fmt = eRGB565;
887 layerpitch = 2;
888 cached_layer_config[FB_LAYER].aen = FALSE;
889 break;
890 case 24:
891 cached_layer_config[FB_LAYER].fmt = eRGB888;
892 layerpitch = 3;
893 cached_layer_config[FB_LAYER].aen = FALSE;
894 break;
895 case 32:
896 cached_layer_config[FB_LAYER].fmt = ePARGB8888;
897 layerpitch = 4;
898 cached_layer_config[FB_LAYER].aen = TRUE;
899 break;
900 default:
901 PRNERR("Invalid color format bpp: 0x%d\n", var->bits_per_pixel);
902 return -1;
903 }
904 cached_layer_config[FB_LAYER].alpha = 0xFF;
905 cached_layer_config[FB_LAYER].buff_idx = -1;
906 cached_layer_config[FB_LAYER].src_pitch = src_pitch * layerpitch;
907 }
908
909 atomic_set(&OverlaySettingDirtyFlag, 1);
910 atomic_set(&OverlaySettingApplied, 0);
911 #endif
912 PanDispSettingPending = 1;
913 PanDispSettingDirty = 1;
914 PanDispSettingApplied = 0;
915 is_ipoh_bootup = false;
916 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
917 mutex_unlock(&OverlaySettingMutex);
918 #endif
919
920 ret = mtkfb_update_screen(info);
921 //#if defined(MTK_OVERLAY_ENGINE_SUPPORT)
922 //Disp_Ovl_Engine_Trigger_Overlay(mtkfb_instance);
923 //#endif
924 // NOTICE: un-interruptible wait here for m4u callback
925#if defined(MTK_OVERLAY_ENGINE_SUPPORT)
926 Disp_Ovl_Engine_Wait_Overlay_Complete(mtkfb_instance, 1000);
927#else
928 wait_ret = wait_event_timeout(reg_update_wq, PanDispSettingApplied, HZ/10);
929 MTKFB_LOG("[WaitQ] wait_event_interruptible() ret = %d, %d\n", wait_ret, __LINE__);
930#endif
931
932 sem_flipping_cnt++;
933 up(&sem_flipping);
934 if(first_enable_esd)
935 {
936 esd_recovery_pause(FALSE);
937 first_enable_esd = false;
938 }
939 MMProfileLog(MTKFB_MMP_Events.PanDisplay, MMProfileFlagEnd);
940
941 return ret;
942}
943
944
945static int mtkfb_pan_display_proxy(struct fb_var_screeninfo *var, struct fb_info *info)
946{
947#ifdef CONFIG_MTPROF_APPLAUNCH // eng enable, user disable
948 LOG_PRINT(ANDROID_LOG_INFO, "AppLaunch", "mtkfb_pan_display_proxy.\n");
949#endif
950 return mtkfb_pan_display_impl(var, info);
951}
952
953
954/* Set fb_info.fix fields and also updates fbdev.
955 * When calling this fb_info.var must be set up already.
956 */
957static void set_fb_fix(struct mtkfb_device *fbdev)
958{
959 struct fb_info *fbi = fbdev->fb_info;
960 struct fb_fix_screeninfo *fix = &fbi->fix;
961 struct fb_var_screeninfo *var = &fbi->var;
962 struct fb_ops *fbops = fbi->fbops;
963
964 strncpy(fix->id, MTKFB_DRIVER, sizeof(fix->id));
965 fix->type = FB_TYPE_PACKED_PIXELS;
966
967 switch (var->bits_per_pixel)
968 {
969 case 16:
970 case 24:
971 case 32:
972 fix->visual = FB_VISUAL_TRUECOLOR;
973 break;
974 case 1:
975 case 2:
976 case 4:
977 case 8:
978 fix->visual = FB_VISUAL_PSEUDOCOLOR;
979 break;
980 default:
981 ASSERT(0);
982 }
983
984 fix->accel = FB_ACCEL_NONE;
985 fix->line_length = ALIGN_TO(var->xres_virtual, disphal_get_fb_alignment()) * var->bits_per_pixel / 8;
986 fix->smem_len = fbdev->fb_size_in_byte;
987 fix->smem_start = fbdev->fb_pa_base;
988
989 fix->xpanstep = 0;
990 fix->ypanstep = 1;
991
992 fbops->fb_fillrect = cfb_fillrect;
993 fbops->fb_copyarea = cfb_copyarea;
994 fbops->fb_imageblit = cfb_imageblit;
995}
996
997
998/* Check values in var, try to adjust them in case of out of bound values if
999 * possible, or return error.
1000 */
1001static int mtkfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
1002{
1003 unsigned int bpp;
1004 unsigned long max_frame_size;
1005 unsigned long line_size;
1006
1007 struct mtkfb_device *fbdev = (struct mtkfb_device *)fbi->par;
1008
1009 MSG_FUNC_ENTER();
1010
1011 MSG(ARGU, "xres=%u, yres=%u, xres_virtual=%u, yres_virtual=%u, "
1012 "xoffset=%u, yoffset=%u, bits_per_pixel=%u)\n",
1013 var->xres, var->yres, var->xres_virtual, var->yres_virtual,
1014 var->xoffset, var->yoffset, var->bits_per_pixel);
1015
1016 bpp = var->bits_per_pixel;
1017
1018 if (bpp != 16 && bpp != 24 && bpp != 32) {
1019 MTKFB_LOG("[%s]unsupported bpp: %d", __func__, bpp);
1020 return -1;
1021 }
1022
1023 switch (var->rotate) {
1024 case 0:
1025 case 180:
1026 var->xres = MTK_FB_XRES;
1027 var->yres = MTK_FB_YRES;
1028 break;
1029 case 90:
1030 case 270:
1031 var->xres = MTK_FB_YRES;
1032 var->yres = MTK_FB_XRES;
1033 break;
1034 default:
1035 return -1;
1036 }
1037
1038 if (var->xres_virtual < var->xres)
1039 var->xres_virtual = var->xres;
1040 if (var->yres_virtual < var->yres)
1041 var->yres_virtual = var->yres;
1042
1043 max_frame_size = fbdev->fb_size_in_byte;
1044 line_size = var->xres_virtual * bpp / 8;
1045
1046 if (line_size * var->yres_virtual > max_frame_size) {
1047 /* Try to keep yres_virtual first */
1048 line_size = max_frame_size / var->yres_virtual;
1049 var->xres_virtual = line_size * 8 / bpp;
1050 if (var->xres_virtual < var->xres) {
1051 /* Still doesn't fit. Shrink yres_virtual too */
1052 var->xres_virtual = var->xres;
1053 line_size = var->xres * bpp / 8;
1054 var->yres_virtual = max_frame_size / line_size;
1055 }
1056 }
1057 if (var->xres + var->xoffset > var->xres_virtual)
1058 var->xoffset = var->xres_virtual - var->xres;
1059 if (var->yres + var->yoffset > var->yres_virtual)
1060 var->yoffset = var->yres_virtual - var->yres;
1061
1062 if (16 == bpp) {
1063 var->red.offset = 11; var->red.length = 5;
1064 var->green.offset = 5; var->green.length = 6;
1065 var->blue.offset = 0; var->blue.length = 5;
1066 var->transp.offset = 0; var->transp.length = 0;
1067 }
1068 else if (24 == bpp)
1069 {
1070 var->red.length = var->green.length = var->blue.length = 8;
1071 var->transp.length = 0;
1072
1073 // Check if format is RGB565 or BGR565
1074
1075 ASSERT(8 == var->green.offset);
1076 ASSERT(16 == var->red.offset + var->blue.offset);
1077 ASSERT(16 == var->red.offset || 0 == var->red.offset);
1078 }
1079 else if (32 == bpp)
1080 {
1081 var->red.length = var->green.length =
1082 var->blue.length = var->transp.length = 8;
1083
1084 // Check if format is ARGB565 or ABGR565
1085
1086 ASSERT(8 == var->green.offset && 24 == var->transp.offset);
1087 ASSERT(16 == var->red.offset + var->blue.offset);
1088 ASSERT(16 == var->red.offset || 0 == var->red.offset);
1089 }
1090
1091 var->red.msb_right = var->green.msb_right =
1092 var->blue.msb_right = var->transp.msb_right = 0;
1093
1094 if(var->activate & FB_ACTIVATE_NO_UPDATE)
1095 no_update = true;
1096 else
1097 no_update = false;
1098
1099 var->activate = FB_ACTIVATE_NOW;
1100
1101 var->height = UINT_MAX;
1102 var->width = UINT_MAX;
1103 var->grayscale = 0;
1104 var->nonstd = 0;
1105
1106 var->pixclock = UINT_MAX;
1107 var->left_margin = UINT_MAX;
1108 var->right_margin = UINT_MAX;
1109 var->upper_margin = UINT_MAX;
1110 var->lower_margin = UINT_MAX;
1111 var->hsync_len = UINT_MAX;
1112 var->vsync_len = UINT_MAX;
1113
1114 var->vmode = FB_VMODE_NONINTERLACED;
1115 var->sync = 0;
1116
1117 MSG_FUNC_LEAVE();
1118 return 0;
1119}
1120
1121
1122/* Switch to a new mode. The parameters for it has been check already by
1123 * mtkfb_check_var.
1124 */
1125static int mtkfb_set_par(struct fb_info *fbi)
1126{
1127 struct fb_var_screeninfo *var = &fbi->var;
1128 struct mtkfb_device *fbdev = (struct mtkfb_device *)fbi->par;
1129 struct fb_overlay_layer fb_layer;
1130 u32 bpp = var->bits_per_pixel;
1131
1132 MSG_FUNC_ENTER();
1133 memset(&fb_layer, 0, sizeof(struct fb_overlay_layer));
1134 switch(bpp)
1135 {
1136 case 16 :
1137 fb_layer.src_fmt = MTK_FB_FORMAT_RGB565;
1138 fb_layer.src_use_color_key = 1;
1139 fb_layer.src_color_key = 0xFF000000;
1140 break;
1141
1142 case 24 :
1143 fb_layer.src_use_color_key = 1;
1144 fb_layer.src_fmt = (0 == var->blue.offset) ?
1145 MTK_FB_FORMAT_RGB888 :
1146 MTK_FB_FORMAT_BGR888;
1147 fb_layer.src_color_key = 0xFF000000;
1148 break;
1149
1150 case 32 :
1151 fb_layer.src_use_color_key = 0;
1152 fb_layer.src_fmt = (0 == var->blue.offset) ?
1153 MTK_FB_FORMAT_ARGB8888 :
1154 MTK_FB_FORMAT_ABGR8888;
1155 fb_layer.src_color_key = 0;
1156 break;
1157
1158 default :
1159 fb_layer.src_fmt = MTK_FB_FORMAT_UNKNOWN;
1160 MTKFB_LOG("[%s]unsupported bpp: %d", __func__, bpp);
1161 return -1;
1162 }
1163
1164 // If the framebuffer format is NOT changed, nothing to do
1165 //
1166 if (fb_layer.src_fmt == fbdev->layer_format[0]) {
1167 goto Done;
1168 }
1169
1170 // else, begin change display mode
1171 //
1172 set_fb_fix(fbdev);
1173
1174 //fb_layer.layer_id = FB_LAYER; //fix batterary disappearing
1175 fb_layer.layer_id = 0;
1176 fb_layer.layer_enable = 1;
1177 fb_layer.src_base_addr = (void *)((unsigned long)fbdev->fb_va_base + var->yoffset * fbi->fix.line_length);
1178 fb_layer.src_phy_addr = (void *)(fb_pa + var->yoffset * fbi->fix.line_length);
1179 fb_layer.src_direct_link = 0;
1180 fb_layer.src_offset_x = fb_layer.src_offset_y = 0;
1181// fb_layer.src_width = fb_layer.tgt_width = fb_layer.src_pitch = var->xres;
1182#if defined(HWGPU_SUPPORT)
1183 fb_layer.src_pitch = ALIGN_TO(var->xres, MTK_FB_ALIGNMENT);
1184#else
1185 if(get_boot_mode() == META_BOOT || get_boot_mode() == FACTORY_BOOT
1186 || get_boot_mode() == ADVMETA_BOOT || get_boot_mode() == RECOVERY_BOOT)
1187 fb_layer.src_pitch = ALIGN_TO(var->xres, MTK_FB_ALIGNMENT);
1188 else
1189 fb_layer.src_pitch = var->xres;
1190#endif
1191 fb_layer.src_width = fb_layer.tgt_width = var->xres;
1192 fb_layer.src_height = fb_layer.tgt_height = var->yres;
1193 fb_layer.tgt_offset_x = fb_layer.tgt_offset_y = 0;
1194
1195// fb_layer.src_color_key = 0;
1196 fb_layer.layer_rotation = MTK_FB_ORIENTATION_0;
1197 fb_layer.layer_type = LAYER_2D;
1198
1199 mutex_lock(&OverlaySettingMutex);
1200 mtkfb_set_overlay_layer((struct mtkfb_device *)fbi->par, &fb_layer);
1201 atomic_set(&OverlaySettingDirtyFlag, 1);
1202 atomic_set(&OverlaySettingApplied, 0);
1203 mutex_unlock(&OverlaySettingMutex);
1204
1205 // backup fb_layer information.
1206 memcpy(&fb_layer_context, &fb_layer, sizeof(fb_layer));
1207
1208Done:
1209 MSG_FUNC_LEAVE();
1210 return 0;
1211}
1212
1213
1214static int mtkfb_soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
1215{
1216 NOT_REFERENCED(info);
1217 NOT_REFERENCED(cursor);
1218
1219 return 0;
1220}
1221void mtkfb_ion_cpu_cache_flush(struct ion_client *client, struct ion_handle *handle)
1222{
1223 struct ion_sys_data sys_data;
1224
1225 sys_data.sys_cmd = ION_SYS_CACHE_SYNC;
1226 sys_data.cache_sync_param.kernel_handle = handle;
1227 sys_data.cache_sync_param.sync_type = ION_CACHE_FLUSH_BY_RANGE;
1228
1229 if (ion_kernel_ioctl(client, ION_CMD_SYSTEM, (unsigned long)&sys_data)) {
1230 pr_err("ion cache flush failed!\n");
1231 }
1232}
1233static void mtkfb_update_ovls_handler(struct work_struct* _work)
1234{
1235 /* Wait for a whole second for config to apply so it's obvious when something's wrong */
1236#ifdef MTK_OVERLAY_ENGINE_SUPPORT
1237 const unsigned long wait_time = 1000;
1238#else
1239 const unsigned long wait_time = msecs_to_jiffies(1000);
1240#endif
1241
1242 update_ovls_work_t *work = (update_ovls_work_t *) _work;
1243 struct mtkfb_device *fbdev = (struct mtkfb_device *)work->dev;
1244 struct fb_overlay_config *config = &work->config;
1245 struct sync_fence **fences = work->fences;
1246 struct ion_handle **ion_handles = work->ion_handles;
1247 int ret, i, suspended = 0;
1248
1249 update_ovls_work_t *curr, *tmp;
1250 struct list_head tmp_list;
1251 u32 inc = 0;
1252
1253 MMProfileLog(MTKFB_MMP_Events.WrokHandler, MMProfileFlagStart);
1254
1255 /* ion handle to mva */
1256 for (i = 0; i < HW_OVERLAY_COUNT; i++) {
1257 ion_mm_data_t data;
1258 size_t _unused;
1259 ion_phys_addr_t mva;
1260
1261 if (!ion_handles[i])
1262 continue; /* Use mva from userspace */
1263
1264 /* configure buffer */
1265 memset(&data, 0, sizeof(ion_mm_data_t));
1266 data.mm_cmd = ION_MM_CONFIG_BUFFER;
1267 data.config_buffer_param.kernel_handle = ion_handles[i];
1268 data.config_buffer_param.eModuleID = DISP_OVL_0;
1269 ion_kernel_ioctl(fbdev->ion_client, ION_CMD_MULTIMEDIA, (unsigned long)&data);
1270
1271 /* Get "physical" address (mva) */
1272 if (ion_phys(fbdev->ion_client, ion_handles[i], &mva, &_unused)) {
1273 dev_err(fbdev->dev, "ion_phys failed, disable ovl %d\n", i);
1274 config->layers[i].layer_enable = 0;
1275 config->layers[i].src_phy_addr = 0;
1276 ion_free(fbdev->ion_client, ion_handles[i]);
1277 ion_handles[i] = NULL;
1278 continue;
1279 }
1280
1281 if (!g_fb_pattern_en)
1282 config->layers[i].src_phy_addr = (void *)mva;
1283 //pr_err("[02420] update_ovls_handler[%d] ion_handle=%x src_phy_addr = %x \n", i,data.config_buffer_param.handle, mva);
1284 }
1285
1286 /* Wait on input fences, unref when done */
1287 if (down_interruptible(&sem_early_suspend)) {
1288 dev_err(fbdev->dev, "semaphore down failed in %s\n", __func__);
1289 goto out;
1290 }
1291 for (i = 0; i < HW_OVERLAY_COUNT; i++) {
1292 if (!fences[i])
1293 continue; /* Nothing to wait on */
1294
1295#ifndef NONFLUSH
1296 if (is_early_suspended)
1297 continue; /* Don't wait if suspended */
1298 /* Wait for the fence to signal */
1299 up(&sem_early_suspend);
1300 if (sync_fence_wait(fences[i], 1000) < 0)
1301 {
1302 config->layers[i].layer_enable = 0;
1303 config->layers[i].src_phy_addr = 0;
1304 //ion_free(fbdev->ion_client, ion_handles[i]);
1305 //ion_handles[i] = NULL;
1306 pr_err(" error waiting for fence to signal fences[%d]= 0x%x\n",i,(unsigned int)fences[i]);
1307 }
1308 if (down_interruptible(&sem_early_suspend)) {
1309 dev_err(fbdev->dev, "semaphore down failed in %s\n", __func__);
1310 goto out;
1311 }
1312#else
1313 /* Don't wait if suspended */
1314 if (!is_early_suspended) { /* Wait for the fence to signal */
1315 up(&sem_early_suspend);
1316 if (sync_fence_wait(fences[i], 1000) < 0){
1317 config->layers[i].layer_enable = 0;
1318 config->layers[i].src_phy_addr = 0;
1319 //ion_free(fbdev->ion_client, ion_handles[i]);
1320 //ion_handles[i] = NULL;
1321 pr_err(" error waiting for fence to signal fences[%d]= 0x%x\n",i,(unsigned int)fences[i]);
1322 goto out;
1323 }
1324 if (down_interruptible(&sem_early_suspend)) {
1325 dev_err(fbdev->dev, "semaphore down failed in %s\n", __func__);
1326 goto out;
1327 }
1328 }
1329#endif
1330 MMProfileLogEx(MTKFB_MMP_Events.HWCFence[i], MMProfileFlagEnd, 0, (unsigned int)fences[i]);
1331 /* Unref the fence */
1332 sync_fence_put(fences[i]);
1333 fences[i] = NULL;
1334 }
1335 suspended = is_early_suspended;
1336 up(&sem_early_suspend);
1337
1338 /* if suspended, skip application */
1339 //if (suspended)
1340 // goto out;
1341
1342 /* Flush CPU cache */
1343 for (i = 0; i < HW_OVERLAY_COUNT; i++) {
1344 ion_mm_data_t data;
1345
1346 if (!work->ion_handles[i])
1347 continue;
1348
1349 /* configure buffer */
1350 memset(&data, 0, sizeof(ion_mm_data_t));
1351 data.mm_cmd = ION_MM_GET_DEBUG_INFO;
1352 data.config_buffer_param.kernel_handle = ion_handles[i];
1353 ion_kernel_ioctl(fbdev->ion_client, ION_CMD_MULTIMEDIA, (unsigned long)&data);
1354
1355 if ((data.buf_debug_info_param.value4 & GRALLOC_EXTRA_MASK_TYPE) !=
1356 GRALLOC_EXTRA_BIT_TYPE_CPU)
1357 continue;
1358
1359 mtkfb_ion_cpu_cache_flush(fbdev->ion_client, work->ion_handles[i]);
1360 }
1361 /* By locking OverlaySettingMutex here we prevent the update thread from commiting the
1362 * frame configuration, even though we make several calls to mtkfb_set_overlay_layer */
1363 mutex_lock(&OverlaySettingMutex);
1364
1365 for (i = 0; i < HW_OVERLAY_COUNT; i++) {
1366 //pr_err("[02420]go config ovl[%d] src_phy_addr = %x \n", i,config->layers[i].src_phy_addr);
1367 if (!isAEEEnabled || (i < (HW_OVERLAY_COUNT - 1)))
1368 mtkfb_set_overlay_layer(fbdev, &config->layers[i]);
1369 }
1370
1371#ifndef MTK_OVERLAY_ENGINE_SUPPORT
1372 /* These flags should flip back when config is applied */
1373 atomic_set(&OverlaySettingDirtyFlag, 1);
1374 atomic_set(&OverlaySettingApplied, 0);
1375#endif
1376
1377 mutex_unlock(&OverlaySettingMutex);
1378
1379 /* Trigger an update */
1380 DISP_StartConfigUpdate();
1381
1382 /* We can't really recover from wait errors so just log and soldier on */
1383#ifdef MTK_OVERLAY_ENGINE_SUPPORT
1384 ret = Disp_Ovl_Engine_Wait_Overlay_Complete(mtkfb_instance, wait_time);
1385 if (ret < 0) {
1386 pr_warn(" Disp_Ovl_Engine_Wait_Overlay_Complete timed out, tearing risk\n");
1387 }
1388#else
1389 /* We can't *really* rely on just OverlaySettingApplied
1390 * since it's triggered not only by us but by AAL and others. */
1391 ret = wait_event_interruptible_timeout(reg_update_wq, atomic_read(&OverlaySettingApplied)
1392 && !atomic_read(&OverlaySettingDirtyFlag),
1393 wait_time);
1394
1395 if (ret < 0) {
1396 pr_warn(" wait for OverlaySettingApplied interrupted, tearing risk\n");
1397 } else if (ret == 0) {
1398 pr_warn(" wait for OverlaySettingApplied timed out, tearing risk\n");
1399 }
1400#endif
1401
1402out:
1403 /* Free old configs & inc timeline */
1404 #if 0
1405 tmp_list = fbdev->pending_configs;
1406 list_replace_init(&fbdev->pending_configs, &tmp_list);
1407 list_for_each_entry_safe(curr, tmp, &tmp_list, list)
1408 {
1409 //pr_err("[02420][0] free ion handle = %x signal fence = %x \n", curr->ion_handles[0], curr->fences[0], curr->ion_handles[1], curr->fences[1], curr->ion_handles[2], curr->fences[2], curr->ion_handles[3], curr->fences[3]);
1410 for (i = 0; i < HW_OVERLAY_COUNT; i++)
1411 {
1412 /* ion handles */
1413 if (curr->ion_handles[i]) {
1414 ion_free(fbdev->ion_client, curr->ion_handles[i]);
1415 curr->ion_handles[i] = NULL;
1416 }
1417 /* fences */
1418 if (curr->fences[i]) {
1419 MMProfileLogEx(MTKFB_MMP_Events.HWCFence[i], MMProfileFlagPulse, 1, (unsigned int)curr->fences[i]);
1420 sync_fence_put(curr->fences[i]);
1421 curr->fences[i] = NULL;
1422 }
1423 }
1424 list_del(&curr->list);
1425 kfree(curr);
1426 inc++;
1427 }
1428
1429 /* This work, and (possibly) its ion handles can't be freed
1430 until next config is applied */
1431 list_add_tail(&work->list, &fbdev->pending_configs);
1432
1433 mutex_lock(&fbdev->timeline_lock);
1434 sw_sync_timeline_inc(fbdev->timeline, inc);
1435 MMProfileLogEx(MTKFB_MMP_Events.FBTimeline, MMProfileFlagEnd, fbdev->timeline->value, inc);
1436 //pr_err("[02420]step into out label in update_ovls_handler inc=%d fbdev->timeline->value = %d", inc, fbdev->timeline->value);
1437 mutex_unlock(&fbdev->timeline_lock);
1438
1439 #else
1440
1441 for (i = 0; i < HW_OVERLAY_COUNT; i++)
1442 {
1443 /* ion handles */
1444 if (ion_handles[i]) {
1445 ion_free(fbdev->ion_client, ion_handles[i]);
1446 ion_handles[i] = NULL;
1447 }
1448 /* fences */
1449 if (fences[i]) {
1450 MMProfileLogEx(MTKFB_MMP_Events.HWCFence[i], MMProfileFlagPulse, 1, (unsigned int)fences[i]);
1451 sync_fence_put(fences[i]);
1452 fences[i] = NULL;
1453 }
1454 }
1455
1456 kfree(work);
1457
1458 mutex_lock(&fbdev->timeline_lock);
1459 sw_sync_timeline_inc(fbdev->timeline, 1);
1460 MMProfileLogEx(MTKFB_MMP_Events.FBTimeline, MMProfileFlagEnd, fbdev->timeline->value, 1);
1461 //pr_err("[02420]step into out label in update_ovls_handler inc=%d fbdev->timeline->value = %d", inc, fbdev->timeline->value);
1462 mutex_unlock(&fbdev->timeline_lock);
1463
1464 #endif
1465
1466 MMProfileLog(MTKFB_MMP_Events.WrokHandler, MMProfileFlagEnd);
1467}
1468
1469int mtkfb_queue_overlay_config(struct mtkfb_device *fbdev, struct fb_overlay_config* config)
1470{
1471 update_ovls_work_t *work;
1472 struct sync_fence *fence;
1473 struct sync_pt *pt;
1474 int i, fd = -1, ret = 0;
1475
1476 if (down_interruptible(&sem_early_suspend)) {
1477 dev_err(fbdev->dev, "semaphore down failed in %s\n", __func__);
1478 return -ERESTARTSYS;
1479 }
1480
1481 MMProfileLogStructure(MTKFB_MMP_Events.QueueWork, MMProfileFlagStart, config, struct fb_overlay_config);
1482
1483 fd = get_unused_fd();
1484 if (fd < 0) {
1485 dev_err(fbdev->dev, "could not get a file descriptor\n");
1486 ret = -ENOMEM;
1487 goto err;
1488 }
1489
1490#if 0
1491 if (is_early_suspended) {
1492 MTKFB_LOG("[FB]: is_early_suspended\n");
1493
1494 /* Create fake sync point and inc timeline */
1495 mutex_lock(&fbdev->timeline_lock);
1496 fbdev->timeline_max++;
1497 pt = sw_sync_pt_create(fbdev->timeline, fbdev->timeline_max);
1498 fence = sync_fence_create("display", pt);
1499 sync_fence_install(fence, fd);
1500 config->fence = fd;
1501 sw_sync_timeline_inc(fbdev->timeline, 1);
1502 mutex_unlock(&fbdev->timeline_lock);
1503
1504 goto out;
1505 }
1506#endif
1507
1508 work = kzalloc(sizeof(update_ovls_work_t), GFP_KERNEL);
1509 if (!work) {
1510 dev_err(fbdev->dev, "could not allocate update_ovls_work_t\n");
1511 ret = -ENOMEM;
1512 goto err;
1513 }
1514 INIT_WORK((struct work_struct*)work, mtkfb_update_ovls_handler);
1515 work->dev = (void*)fbdev;
1516
1517 /* Copy configs */
1518 memcpy(&work->config, config, sizeof(struct fb_overlay_config));
1519
1520 /* Import fences so userspace can close (deref) them after ioctl */
1521 for (i = 0; i < HW_OVERLAY_COUNT; i++) {
1522 struct fb_overlay_layer* layer = &config->layers[i];
1523
1524 if (layer->fence_fd < 0) {
1525 work->fences[i] = NULL;
1526 continue; /* Nothing to wait on */
1527 }
1528 work->fences[i] = sync_fence_fdget(layer->fence_fd);
1529 MMProfileLogEx(MTKFB_MMP_Events.HWCFence[i], MMProfileFlagStart, layer->fence_fd, (unsigned int)work->fences[i]);
1530 //pr_err("[02420] mtkfb (ion_import_dma_buf) layer[%d]->fence_fd=%d fences=%x layer->ion_fd=%x",i,layer->fence_fd, work->fences[i], layer->ion_fd);
1531 if (!work->fences[i]) {
1532 /* This is bad, but we just log an error and continue */
1533 pr_err(" failed to import sync fence\n");
1534 work->fences[i] = NULL;
1535 continue;
1536 }
1537 }
1538 /* Import ion handles so userspace (hwc) doesn't need to have a ref to them */
1539 for (i = 0; i < HW_OVERLAY_COUNT; i++) {
1540 struct fb_overlay_layer *layer = &config->layers[i];
1541 if (layer->ion_fd < 0||layer->layer_enable == 0) { //[02420] if (!work->fences[i] || layer->ion_fd <= 0) {
1542 work->ion_handles[i] = NULL;
1543 continue; /* worker will use mva from userspace */
1544 }
1545 work->ion_handles[i] = ion_import_dma_buf(fbdev->ion_client, layer->ion_fd);
1546
1547#if 0/*monica debug use start*/
1548
1549 int counter = 0;
1550 int counter_1 = 0;
1551 int statistics = 0;
1552 for(counter_1=0; counter_1 < 1024 ; counter_1++){
1553 if(ion_handle_note[counter_1] == 0){
1554 ion_handle_note[counter_1] = work->ion_handles[i];
1555 break;
1556 }
1557 }
1558 if(counter_1 >= 1023){
1559 pr_err("[02420] Queue full");
1560 }
1561
1562 for(counter=0; counter < 1024 ; counter++){
1563 if(ion_handle_note[counter] != 0)
1564 statistics++;
1565 }
1566 pr_err("[02420] import[%d] put at [%d] layer->ion_fd = %x tablet_entry_cnt = %d\n", i, counter_1, work->ion_handles[i], statistics);
1567
1568#endif/*monica debug use end*/
1569
1570 if (IS_ERR(work->ion_handles[i])) {
1571 dev_err(fbdev->dev, "failed to import ion fd, disable ovl %d\n", i);
1572 work->ion_handles[i] = NULL;
1573 layer->layer_enable = 0;
1574 continue;
1575 }
1576 }
1577 /* Create sync point */
1578 mutex_lock(&fbdev->timeline_lock);
1579 fbdev->timeline_max++;
1580 pt = sw_sync_pt_create(fbdev->timeline, fbdev->timeline_max);
1581 if(pt == NULL) {
1582 pr_err(" sw_sync_pt_create NULL\n");
1583 goto err;
1584 }
1585 fence = sync_fence_create("display", pt);
1586 if(fence == NULL) {
1587 sync_pt_free(pt);
1588 pr_err(" sync_fence_create NULL\n");
1589 goto err;
1590 }
1591
1592 sync_fence_install(fence, fd);
1593 config->fence = fd;
1594 MMProfileLogEx(MTKFB_MMP_Events.FBFence, MMProfileFlagPulse, config->fence, fbdev->timeline->value);
1595 MMProfileLogEx(MTKFB_MMP_Events.FBTimeline, MMProfileFlagStart, fbdev->timeline->value, fbdev->timeline_max);
1596 //pr_err("[02420]output fence=%x fbdev->timeline_max=%d",fd, fbdev->timeline_max);
1597 mutex_unlock(&fbdev->timeline_lock);
1598
1599 /* Queue work */
1600 queue_work(fbdev->update_ovls_wq, (struct work_struct*)work);
1601 goto out;
1602
1603err:
1604 pr_warn("mtkfb_queue_overlay_config fd=%d failed\n", fd);
1605 config->fence = -1;
1606 if (fd >=0)
1607 put_unused_fd(fd);
1608 kfree(work);
1609
1610out:
1611 up(&sem_early_suspend);
1612 MMProfileLog(MTKFB_MMP_Events.QueueWork, MMProfileFlagEnd);
1613
1614 return ret;
1615}
1616
1617static int mtkfb_set_overlay_layer(struct mtkfb_device *fbdev, struct fb_overlay_layer* layerInfo)
1618{
1619#if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1620 unsigned int layerpitch;
1621 unsigned int layerbpp;
1622#endif
1623 unsigned int id = layerInfo->layer_id;
1624 int enable = layerInfo->layer_enable ? 1 : 0;
1625 int ret = 0;
1626
1627 MTKFB_FUNC();
1628 MSG_FUNC_ENTER();
1629 MMProfileLogEx(MTKFB_MMP_Events.SetOverlayLayer, MMProfileFlagStart, (id<<16)|enable, (unsigned int)layerInfo->src_phy_addr);
1630
4b9e9796
S
1631 // Check id is valid
1632 if ((id < 0) || (id >= DDP_OVL_LAYER_MUN))
1633 {
1634 MTKFB_LOG("Invalid layer id:%d\n", id);
1635 ret = -EFAULT;
1636 goto LeaveOverlayMode;
1637 }
1638
6fa3eb70
S
1639 //BUG: check layer 3 format
1640 if((layerInfo->layer_id == 3) && (layerInfo->src_fmt != MTK_FB_FORMAT_ARGB8888))
1641 {
1642 //pr_info("ERROR!!!Layer 3 format error!!!\n");
1643 }
1644
1645 MTKFB_LOG("[FB Driver] mtkfb_set_overlay_layer():id=%u, en=%u, next_idx=%u, vaddr=0x%x, paddr=0x%x, fmt=%u, d-link=%u, pitch=%u, xoff=%u, yoff=%u, w=%u, h=%u\n",
1646 layerInfo->layer_id,
1647 layerInfo->layer_enable,
1648 layerInfo->next_buff_idx,
1649 (unsigned int)(layerInfo->src_base_addr),
1650 (unsigned int)(layerInfo->src_phy_addr),
1651 layerInfo->src_fmt,
1652 (unsigned int)(layerInfo->src_direct_link),
1653 layerInfo->src_pitch,
1654 layerInfo->src_offset_x,
1655 layerInfo->src_offset_y,
1656 layerInfo->src_width,
1657 layerInfo->src_height);
1658 MTKFB_LOG("[FB Driver] mtkfb_set_overlay_layer():target xoff=%u, target yoff=%u, target w=%u, target h=%u\n",
1659 layerInfo->tgt_offset_x,
1660 layerInfo->tgt_offset_y,
1661 layerInfo->tgt_width,
1662 layerInfo->tgt_height);
1663
1664 // Update Layer Enable Bits and Layer Config Dirty Bits
1665 if ((((fbdev->layer_enable >> id) & 1) ^ enable)) {
1666 fbdev->layer_enable ^= (1 << id);
1667 fbdev->layer_config_dirty |= MTKFB_LAYER_ENABLE_DIRTY;
1668 }
1669
1670 // Update Layer Format and Layer Config Dirty Bits
1671 if (fbdev->layer_format[id] != layerInfo->src_fmt) {
1672 fbdev->layer_format[id] = layerInfo->src_fmt;
1673 fbdev->layer_config_dirty |= MTKFB_LAYER_FORMAT_DIRTY;
1674 }
1675
1676 // Enter Overlay Mode if any layer is enabled except the FB layer
1677
1678 if(fbdev->layer_enable & ((1 << VIDEO_LAYER_COUNT)-1)){
1679 if (DISP_STATUS_OK == DISP_EnterOverlayMode()) {
1680 MTKFB_LOG("mtkfb_ioctl(MTKFB_ENABLE_OVERLAY)\n");
1681 }
1682 }
1683
1684 if (!enable)
1685 {
1686 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1687 {
1688 struct fb_overlay_layer layer = {0};
1689 layer.layer_id = layerInfo->layer_id;
1690 Disp_Ovl_Engine_Get_layer_info(mtkfb_instance,&layer);
1691 layer.layer_enable = enable;
1692 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance,&layer);
1693 }
1694 #else
1695 cached_layer_config[id].layer_en = enable;
1696 cached_layer_config[id].isDirty = true;
1697 cached_layer_config[id].security = false;
1698 #endif
1699 ret = 0;
1700 goto LeaveOverlayMode;
1701 }
1702#if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1703 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, layerInfo);
1704#endif
1705#if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1706
1707 switch (layerInfo->src_fmt)
1708 {
1709 case MTK_FB_FORMAT_YUV422:
1710 cached_layer_config[id].fmt = eYUY2;
1711 layerpitch = 2;
1712 layerbpp = 24;
1713 break;
1714
1715 case MTK_FB_FORMAT_RGB565:
1716 cached_layer_config[id].fmt = eRGB565;
1717 layerpitch = 2;
1718 layerbpp = 16;
1719 break;
1720
1721 case MTK_FB_FORMAT_RGB888:
1722 cached_layer_config[id].fmt = eRGB888;
1723 layerpitch = 3;
1724 layerbpp = 24;
1725 break;
1726 case MTK_FB_FORMAT_BGR888:
1727 cached_layer_config[id].fmt = eBGR888;
1728 layerpitch = 3;
1729 layerbpp = 24;
1730 break;
1731
1732 case MTK_FB_FORMAT_ARGB8888:
1733 cached_layer_config[id].fmt = ePARGB8888;
1734 layerpitch = 4;
1735 layerbpp = 32;
1736 break;
1737 case MTK_FB_FORMAT_ABGR8888:
1738 cached_layer_config[id].fmt = ePABGR8888;
1739 layerpitch = 4;
1740 layerbpp = 32;
1741 break;
1742 case MTK_FB_FORMAT_XRGB8888:
1743 cached_layer_config[id].fmt = eARGB8888;
1744 layerpitch = 4;
1745 layerbpp = 32;
1746 break;
1747 case MTK_FB_FORMAT_XBGR8888:
1748 cached_layer_config[id].fmt = eABGR8888;
1749 layerpitch = 4;
1750 layerbpp = 32;
1751 break;
1752 default:
1753 PRNERR("Invalid color format: 0x%x\n", layerInfo->src_fmt);
1754 ret = -EFAULT;
1755 goto LeaveOverlayMode;
1756 }
1757 cached_layer_config[id].vaddr = (unsigned int)layerInfo->src_base_addr;
1758 cached_layer_config[id].security = layerInfo->security;
1759 cached_layer_config[id].addr = (unsigned int)layerInfo->src_phy_addr;
1760 cached_layer_config[id].isTdshp = layerInfo->isTdshp;
1761 cached_layer_config[id].buff_idx = layerInfo->next_buff_idx;
1762#endif
1763
1764{
1765#if defined(MTK_HDMI_SUPPORT)
1766
1767#define SUPPORT_HMDI_SVP_P1 1
1768
1769#if SUPPORT_HMDI_SVP_P1
1770 /* temporary solution for hdmi svp p1, always mute hdmi for svp */
1771 int tl = 0;
1772 int has_prot_layer = 0;
1773 int has_sec_layer = 0;
1774
1775#if defined(MTK_OVERLAY_ENGINE_SUPPORT)
1776
1777 OVL_CONFIG_STRUCT cached_layer[DDP_OVL_LAYER_MUN] = {{0}, {0}, {0}, {0}};
1778 Disp_Ovl_Engine_Dump_layer_info(mtkfb_instance, &cached_layer[0], NULL, NULL);
1779
1780 for(tl=0;tl<HW_OVERLAY_COUNT;tl++)
1781 {
1782 if( OVL_LAYER_SECURE_BUFFER == cached_layer[tl].security )
1783 {
1784 has_sec_layer = 1;
1785 break;
1786 }
1787
1788 if( OVL_LAYER_PROTECTED_BUFFER == cached_layer[tl].security )
1789 {
1790 has_prot_layer = 1;
1791 break;
1792 }
1793 }
1794#else
1795
1796 for(tl=0;tl<HW_OVERLAY_COUNT;tl++)
1797 {
1798 if( OVL_LAYER_SECURE_BUFFER == cached_layer_config[tl].security )
1799 {
1800 has_sec_layer = 1;
1801 break;
1802 }
1803
1804 if( OVL_LAYER_PROTECTED_BUFFER == cached_layer_config[tl].security )
1805 {
1806 has_prot_layer = 1;
1807 break;
1808 }
1809 }
1810#endif
1811
1812 /*if( 1 == has_sec_layer )
1813 {
1814 MTKFB_LOG("Mute hdmi video for secure video buffer\n");
1815 MTK_HDMI_Set_Security_Output_SVP_P1(1);
1816 }
1817 else if( 1 == has_prot_layer )
1818 {
1819 MTKFB_LOG("Mute hdmi video for protected video buffer\n");
1820 MTK_HDMI_Set_Security_Output(1);
1821 }
1822 else
1823 {
1824 MTKFB_LOG("Un-mute hdmi video for secure video buffer\n");
1825 MTK_HDMI_Set_Security_Output(0);
1826 MTK_HDMI_Set_Security_Output_SVP_P1(0);
1827 }*/
1828#else
1829 int tl = 0;
1830 int cnt_security_layer = 0;
1831 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1832 for(tl=0;tl<HW_OVERLAY_COUNT;tl++)
1833 {
1834 cnt_security_layer += cached_layer_config[tl].security;
1835 }
1836 #endif
1837 MTKFB_LOG("Totally %d security layer is set now\n", cnt_security_layer);
1838 //MTK_HDMI_Set_Security_Output(!!cnt_security_layer);
1839#endif /* SUPPORT_HMDI_SVP_P1 */
1840#endif
1841}
1842 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1843 cached_layer_config[id].identity = layerInfo->identity;
1844 cached_layer_config[id].connected_type = layerInfo->connected_type;
1845
1846 //set Alpha blending
1847 cached_layer_config[id].alpha = 0xFF;
1848 if (layerInfo->alpha_enable) {
1849 cached_layer_config[id].aen = TRUE;
1850 cached_layer_config[id].alpha = layerInfo->alpha;
1851 } else {
1852 cached_layer_config[id].aen = FALSE;
1853 }
1854 if (MTK_FB_FORMAT_ARGB8888 == layerInfo->src_fmt ||
1855 MTK_FB_FORMAT_ABGR8888 == layerInfo->src_fmt) {
1856 cached_layer_config[id].aen = TRUE;
1857 }
1858
1859 //set src width, src height
1860 cached_layer_config[id].src_x = layerInfo->src_offset_x;
1861 cached_layer_config[id].src_y = layerInfo->src_offset_y;
1862 cached_layer_config[id].src_w = layerInfo->src_width;
1863 cached_layer_config[id].src_h = layerInfo->src_height;
1864 cached_layer_config[id].dst_x = layerInfo->tgt_offset_x;
1865 cached_layer_config[id].dst_y = layerInfo->tgt_offset_y;
1866 cached_layer_config[id].dst_w = layerInfo->tgt_width;
1867 cached_layer_config[id].dst_h = layerInfo->tgt_height;
1868 if (cached_layer_config[id].dst_w > cached_layer_config[id].src_w)
1869 cached_layer_config[id].dst_w = cached_layer_config[id].src_w;
1870 if (cached_layer_config[id].dst_h > cached_layer_config[id].src_h)
1871 cached_layer_config[id].dst_h = cached_layer_config[id].src_h;
1872
1873 cached_layer_config[id].src_pitch = layerInfo->src_pitch*layerpitch;
1874 #endif
1875
1876#if 0 //defined(DITHERING_SUPPORT) // for build warning temp fix!!
1877 {
1878 bool ditherenabled = false;
1879 UINT32 ditherbpp = DISP_GetOutputBPPforDithering();
1880 UINT32 dbr = 0;
1881 UINT32 dbg = 0;
1882 UINT32 dbb = 0;
1883
1884 if(ditherbpp < layerbpp)
1885 {
1886 if(ditherbpp == 16)
1887 {
1888 if(layerbpp == 18)
1889 {
1890 dbr = 1;
1891 dbg = 0;
1892 dbb = 1;
1893 ditherenabled = true;
1894 }
1895 else if(layerbpp == 24 || layerbpp == 32)
1896 {
1897 dbr = 2;
1898 dbg = 1;
1899 dbb = 2;
1900 ditherenabled = true;
1901 }
1902 else
1903 {
1904 MTKFB_LOG("ERROR, error dithring bpp settings\n");
1905 }
1906 }
1907 else if(ditherbpp == 18)
1908 {
1909 if(layerbpp == 24 || layerbpp == 32)
1910 {
1911 dbr = 1;
1912 dbg = 1;
1913 dbb = 1;
1914 ditherenabled = true;
1915 }
1916 else
1917 {
1918 MTKFB_LOG("ERROR, error dithring bpp settings\n");
1919 ASSERT(0);
1920 }
1921 }
1922 else if(ditherbpp == 24)
1923 {
1924 // do nothing here.
1925 }
1926 else
1927 {
1928 MTKFB_LOG("ERROR, error dithering bpp settings, diterbpp = %d\n",ditherbpp);
1929 ASSERT(0);
1930 }
1931
1932 if(ditherenabled)
1933 {
1934 //LCD_CHECK_RET(LCD_LayerEnableDither(id, true));
1935 DISP_ConfigDither(14, 14, 14, dbr, dbg, dbb);
1936 if(FB_LAYER == id){
1937 dbr_backup = dbr;dbg_backup = dbg;dbb_backup = dbb;
1938 fblayer_dither_needed = ditherenabled;
1939 MTKFB_LOG("[FB driver] dither enabled:%d, dither bit(%d,%d,%d)\n", fblayer_dither_needed, dbr_backup, dbg_backup, dbb_backup);
1940 }
1941 }
1942 }
1943 else
1944 {
1945 // no dithering needed.
1946 }
1947
1948 }
1949#endif
1950
1951 #if defined(MTK_LCM_PHYSICAL_ROTATION)
1952 if(0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "180", 3))
1953 {
1954 layerInfo->layer_rotation = (layerInfo->layer_rotation + MTK_FB_ORIENTATION_180) % 4;
1955 layerInfo->tgt_offset_x = MTK_FB_XRES - (layerInfo->tgt_offset_x + layerInfo->tgt_width);
1956 layerInfo->tgt_offset_y = MTK_FB_YRES - (layerInfo->tgt_offset_y + layerInfo->tgt_height);
1957 }
1958 #endif
1959
1960 video_rotation = layerInfo->video_rotation;
1961
1962 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
1963 //set color key
1964 cached_layer_config[id].key = layerInfo->src_color_key;
1965 cached_layer_config[id].keyEn = layerInfo->src_use_color_key;
1966
1967 //data transferring is triggerred in MTKFB_TRIG_OVERLAY_OUT
1968 cached_layer_config[id].layer_en= enable;
1969 cached_layer_config[id].isDirty = true;
1970
1971 #endif
1972LeaveOverlayMode:
1973
1974 // Leave Overlay Mode if only FB layer is enabled
1975 if ((fbdev->layer_enable & ((1 << VIDEO_LAYER_COUNT)-1)) == 0)
1976 {
1977 if (DISP_STATUS_OK == DISP_LeaveOverlayMode())
1978 {
1979 MTKFB_LOG("mtkfb_ioctl(MTKFB_DISABLE_OVERLAY)\n");
1980 if(fblayer_dither_needed)
1981 {
1982 DISP_ConfigDither(14, 14, 14, dbr_backup, dbg_backup, dbb_backup);
1983 }
1984 }
1985 }
1986
1987 MSG_FUNC_LEAVE();
1988 MMProfileLog(MTKFB_MMP_Events.SetOverlayLayer, MMProfileFlagEnd);
1989
1990 return ret;
1991}
1992
1993static int mtkfb_get_overlay_layer_info(struct fb_overlay_layer_info* layerInfo)
1994{
1995 DISP_LAYER_INFO layer;
4b9e9796 1996 if ((layerInfo->layer_id < 0) || (layerInfo->layer_id >= DDP_OVL_LAYER_MUN))
6fa3eb70
S
1997 {
1998 return 0;
1999 }
2000 layer.id = layerInfo->layer_id;
2001 DISP_GetLayerInfo(&layer);
2002 layerInfo->layer_enabled = layer.hw_en;
2003 layerInfo->curr_en = layer.curr_en;
2004 layerInfo->next_en = layer.next_en;
2005 layerInfo->hw_en = layer.hw_en;
2006 layerInfo->curr_idx = layer.curr_idx;
2007 layerInfo->next_idx = layer.next_idx;
2008 layerInfo->hw_idx = layer.hw_idx;
2009 layerInfo->curr_identity = layer.curr_identity;
2010 layerInfo->next_identity = layer.next_identity;
2011 layerInfo->hw_identity = layer.hw_identity;
2012 layerInfo->curr_conn_type = layer.curr_conn_type;
2013 layerInfo->next_conn_type = layer.next_conn_type;
2014 layerInfo->hw_conn_type = layer.hw_conn_type;
2015
2016 MTKFB_LOG("[FB Driver] mtkfb_get_overlay_layer_info():id=%u, layer en=%u, next_en=%u, curr_en=%u, hw_en=%u, next_idx=%u, curr_idx=%u, hw_idx=%u \n",
2017 layerInfo->layer_id,
2018 layerInfo->layer_enabled,
2019 layerInfo->next_en,
2020 layerInfo->curr_en,
2021 layerInfo->hw_en,
2022 layerInfo->next_idx,
2023 layerInfo->curr_idx,
2024 layerInfo->hw_idx);
2025
2026 MMProfileLogEx(MTKFB_MMP_Events.LayerInfo[layerInfo->layer_id], MMProfileFlagPulse, (layerInfo->next_idx<<16)+((layerInfo->curr_idx)&0xFFFF), (layerInfo->hw_idx<<16)+(layerInfo->next_en<<8)+(layerInfo->curr_en<<4)+layerInfo->hw_en);
2027 return 0;
2028}
2029
2030
2031static atomic_t capture_ui_layer_only = ATOMIC_INIT(0); /* when capturing framebuffer ,whether capture ui layer only */
2032void mtkfb_capture_fb_only(bool enable)
2033{
2034 atomic_set(&capture_ui_layer_only, enable);
2035}
2036
2037static int mtkfb_capture_framebuffer(struct fb_info *info, unsigned int pvbuf)
2038{
2039 int ret = 0;
2040 MMProfileLogEx(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagStart, pvbuf, 0);
2041 MTKFB_FUNC();
2042 if (down_interruptible(&sem_flipping)) {
2043 pr_info("[FB Driver] can't get semaphore:%d\n", __LINE__);
2044 MMProfileLogEx(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagEnd, 0, 1);
2045 return -ERESTARTSYS;
2046 }
2047 sem_flipping_cnt--;
2048 mutex_lock(&ScreenCaptureMutex);
2049
2050 /** LCD registers can't be R/W when its clock is gated in early suspend
2051 mode; power on/off LCD to modify register values before/after func.
2052 */
2053 if (is_early_suspended)
2054 {
2055 // Turn on engine clock.
2056 disp_path_clock_on("mtkfb");
2057 }
2058
2059 if (atomic_read(&capture_ui_layer_only))
2060 {
2061 unsigned int w_xres = (unsigned short)fb_layer_context.src_width;
2062 unsigned int h_yres = (unsigned short)fb_layer_context.src_height;
2063 unsigned int pixel_bpp = info->var.bits_per_pixel / 8; // bpp is either 32 or 16, can not be other value
2064 unsigned int w_fb = (unsigned int)fb_layer_context.src_pitch;
2065 unsigned int fbsize = w_fb * h_yres * pixel_bpp; // frame buffer size
2066 unsigned int fbaddress = info->fix.smem_start + info->var.yoffset * info->fix.line_length; //physical address
2067 unsigned int mem_off_x = (unsigned short)fb_layer_context.src_offset_x;
2068 unsigned int mem_off_y = (unsigned short)fb_layer_context.src_offset_y;
2069 unsigned int fbv = 0;
2070 fbaddress += (mem_off_y * w_fb + mem_off_x) * pixel_bpp;
2071 fbv = (unsigned int)ioremap_nocache(fbaddress, fbsize);
2072 MTKFB_LOG("[FB Driver], w_xres = %d, h_yres = %d, w_fb = %d, pixel_bpp = %d, fbsize = %d, fbaddress = 0x%08x\n", w_xres, h_yres, w_fb, pixel_bpp, fbsize, fbaddress);
2073 if (!fbv)
2074 {
2075 MTKFB_LOG("[FB Driver], Unable to allocate memory for frame buffer: address=0x%08x, size=0x%08x\n", \
2076 fbaddress, fbsize);
2077 goto EXIT;
2078 }
2079 {
2080 unsigned int i;
2081 for(i = 0;i < h_yres; i++)
2082 {
2083 memcpy((void *)(pvbuf + i * w_xres * pixel_bpp), (void *)(fbv + i * w_fb * pixel_bpp), w_xres * pixel_bpp);
2084 }
2085 }
2086 iounmap((void *)fbv);
2087 }
2088 else
2089 DISP_Capture_Framebuffer(pvbuf, info->var.bits_per_pixel, is_early_suspended);
2090
2091
2092EXIT:
2093 if (is_early_suspended)
2094 {
2095 // Turn off engine clock.
2096 //DISP_CHECK_RET(DISP_PowerEnable(FALSE));
2097 disp_path_clock_off("mtkfb");
2098 }
2099
2100 mutex_unlock(&ScreenCaptureMutex);
2101 sem_flipping_cnt++;
2102 up(&sem_flipping);
2103 MSG_FUNC_LEAVE();
2104 MMProfileLogEx(MTKFB_MMP_Events.CaptureFramebuffer, MMProfileFlagEnd, 0, 0);
2105
2106 return ret;
2107}
2108
2109
2110#include <linux/aee.h>
2111extern OVL_CONFIG_STRUCT* captured_layer_config;
2112extern OVL_CONFIG_STRUCT* realtime_layer_config;
2113#define mtkfb_aee_print(string, args...) do{\
2114 aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_MMPROFILE_BUFFER, "sf-mtkfb blocked", string, ##args); \
2115}while(0)
2116
2117void mtkfb_dump_layer_info(void)
2118{
2119 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
2120 unsigned int i;
2121 OVL_CONFIG_STRUCT cached_layer[DDP_OVL_LAYER_MUN] = {{0}, {0}, {0}, {0}};
2122 OVL_CONFIG_STRUCT captured_layer[DDP_OVL_LAYER_MUN] = {{0}, {0}, {0}, {0}};
2123 OVL_CONFIG_STRUCT realtime_layer[DDP_OVL_LAYER_MUN] = {{0}, {0}, {0}, {0}};
2124 Disp_Ovl_Engine_Dump_layer_info(mtkfb_instance, &cached_layer[0], &captured_layer[0], &realtime_layer[0]);
2125 pr_info("[mtkfb] start dump layer info, early_suspend=%d \n", is_early_suspended);
2126 pr_info("[mtkfb] cache(next): \n");
2127 for(i=0;i<DDP_OVL_LAYER_MUN;i++)
2128 {
2129 pr_info("[mtkfb] layer=%d, layer_en=%d, idx=%d, fmt=%d, addr=0x%x, %d, %d, %d \n ",
2130 cached_layer[i].layer, // layer
2131 cached_layer[i].layer_en,
2132 cached_layer[i].buff_idx,
2133 cached_layer[i].fmt,
2134 cached_layer[i].addr, // addr
2135 cached_layer[i].identity,
2136 cached_layer[i].connected_type,
2137 cached_layer[i].security);
2138 }
2139 pr_info("[mtkfb] captured(current): \n");
2140 for(i=0;i<DDP_OVL_LAYER_MUN;i++)
2141 {
2142 pr_info("[mtkfb] layer=%d, layer_en=%d, idx=%d, fmt=%d, addr=0x%x, %d, %d, %d \n ",
2143 captured_layer[i].layer, // layer
2144 captured_layer[i].layer_en,
2145 captured_layer[i].buff_idx,
2146 captured_layer[i].fmt,
2147 captured_layer[i].addr, // addr
2148 captured_layer[i].identity,
2149 captured_layer[i].connected_type,
2150 captured_layer[i].security);
2151 }
2152 pr_info("[mtkfb] realtime(hw): \n");
2153 for(i=0;i<DDP_OVL_LAYER_MUN;i++)
2154 {
2155 pr_info("[mtkfb] layer=%d, layer_en=%d, idx=%d, fmt=%d, addr=0x%x, %d, %d, %d \n ",
2156 realtime_layer[i].layer, // layer
2157 realtime_layer[i].layer_en,
2158 realtime_layer[i].buff_idx,
2159 realtime_layer[i].fmt,
2160 realtime_layer[i].addr, // addr
2161 realtime_layer[i].identity,
2162 realtime_layer[i].connected_type,
2163 realtime_layer[i].security);
2164 }
2165 #else
2166 unsigned int i;
2167 pr_info("[mtkfb] start dump layer info, early_suspend=%d \n", is_early_suspended);
2168 pr_info("[mtkfb] cache(next): \n");
2169 for(i=0;i<4;i++)
2170 {
2171 pr_info("[mtkfb] layer=%d, layer_en=%d, idx=%d, fmt=%d, addr=0x%x, %d, %d, %d \n ",
2172 cached_layer_config[i].layer, // layer
2173 cached_layer_config[i].layer_en,
2174 cached_layer_config[i].buff_idx,
2175 cached_layer_config[i].fmt,
2176 cached_layer_config[i].addr, // addr
2177 cached_layer_config[i].identity,
2178 cached_layer_config[i].connected_type,
2179 cached_layer_config[i].security);
2180 }
2181
2182 pr_info("[mtkfb] captured(current): \n");
2183 for(i=0;i<4;i++)
2184 {
2185 pr_info("[mtkfb] layer=%d, layer_en=%d, idx=%d, fmt=%d, addr=0x%x, %d, %d, %d \n ",
2186 captured_layer_config[i].layer, // layer
2187 captured_layer_config[i].layer_en,
2188 captured_layer_config[i].buff_idx,
2189 captured_layer_config[i].fmt,
2190 captured_layer_config[i].addr, // addr
2191 captured_layer_config[i].identity,
2192 captured_layer_config[i].connected_type,
2193 captured_layer_config[i].security);
2194 }
2195 pr_info("[mtkfb] realtime(hw): \n");
2196 for(i=0;i<4;i++)
2197 {
2198 pr_info("[mtkfb] layer=%d, layer_en=%d, idx=%d, fmt=%d, addr=0x%x, %d, %d, %d \n ",
2199 realtime_layer_config[i].layer, // layer
2200 realtime_layer_config[i].layer_en,
2201 realtime_layer_config[i].buff_idx,
2202 realtime_layer_config[i].fmt,
2203 realtime_layer_config[i].addr, // addr
2204 realtime_layer_config[i].identity,
2205 realtime_layer_config[i].connected_type,
2206 realtime_layer_config[i].security);
2207 }
2208 #endif
2209 // dump mmp data
2210 //mtkfb_aee_print("surfaceflinger-mtkfb blocked");
2211
2212}
2213
2214static char *_mtkfb_ioctl_spy(unsigned int cmd)
2215{
2216 switch(cmd)
2217 {
2218 case MTKFB_SET_OVERLAY_LAYER:
2219 return "MTKFB_SET_OVERLAY_LAYER";
2220 case MTKFB_TRIG_OVERLAY_OUT:
2221 return "MTKFB_TRIG_OVERLAY_OUT";
2222 case MTKFB_SET_VIDEO_LAYERS:
2223 return "MTKFB_SET_VIDEO_LAYERS";
2224 case MTKFB_CAPTURE_FRAMEBUFFER:
2225 return "MTKFB_CAPTURE_FRAMEBUFFER";
2226 case MTKFB_CONFIG_IMMEDIATE_UPDATE:
2227 return "MTKFB_CONFIG_IMMEDIATE_UPDATE";
2228 case MTKFB_SET_MULTIPLE_LAYERS:
2229 return "MTKFB_SET_MULTIPLE_LAYERS";
2230 case MTKFB_REGISTER_OVERLAYBUFFER:
2231 return "MTKFB_REGISTER_OVERLAYBUFFER";
2232 case MTKFB_UNREGISTER_OVERLAYBUFFER:
2233 return "MTKFB_UNREGISTER_OVERLAYBUFFER";
2234 case MTKFB_SET_ORIENTATION:
2235 return "MTKFB_SET_ORIENTATION";
2236 case MTKFB_FBLAYER_ENABLE:
2237 return "MTKFB_FBLAYER_ENABLE";
2238 case MTKFB_LOCK_FRONT_BUFFER:
2239 return "MTKFB_LOCK_FRONT_BUFFER";
2240 case MTKFB_UNLOCK_FRONT_BUFFER:
2241 return "MTKFB_UNLOCK_FRONT_BUFFER";
2242 case MTKFB_POWERON:
2243 return "MTKFB_POWERON";
2244 case MTKFB_POWEROFF:
2245 return "MTKFB_POWEROFF";
2246 case MTKFB_PREPARE_OVERLAY_BUFFER:
2247 return "MTKFB_PREPARE_OVERLAY_BUFFER";
2248 case MTKFB_SET_COMPOSING3D:
2249 return "MTKFB_SET_COMPOSING3D";
2250 case MTKFB_SET_S3D_FTM:
2251 return "MTKFB_SET_S3D_FTM";
2252 case MTKFB_GET_DEFAULT_UPDATESPEED:
2253 return "MTKFB_GET_DEFAULT_UPDATESPEED";
2254 case MTKFB_GET_CURR_UPDATESPEED:
2255 return "MTKFB_GET_CURR_UPDATESPEED";
2256 case MTKFB_CHANGE_UPDATESPEED:
2257 return "MTKFB_CHANGE_UPDATESPEED";
2258 case MTKFB_GET_INTERFACE_TYPE:
2259 return "MTKFB_GET_INTERFACE_TYPE";
2260 case MTKFB_GET_POWERSTATE:
2261 return "MTKFB_GET_POWERSTATE";
2262 case MTKFB_GET_DISPLAY_IF_INFORMATION:
2263 return "MTKFB_GET_DISPLAY_IF_INFORMATION";
2264 case MTKFB_AEE_LAYER_EXIST:
2265 return "MTKFB_AEE_LAYER_EXIST";
2266 case MTKFB_GET_OVERLAY_LAYER_INFO:
2267 return "MTKFB_GET_OVERLAY_LAYER_INFO";
2268 case MTKFB_FACTORY_AUTO_TEST:
2269 return "MTKFB_FACTORY_AUTO_TEST";
2270 case MTKFB_GET_FRAMEBUFFER_MVA:
2271 return "MTKFB_GET_FRAMEBUFFER_MVA";
2272 case MTKFB_SLT_AUTO_CAPTURE:
2273 return "MTKFB_SLT_AUTO_CAPTURE";
2274 case MTKFB_GETVFRAMEPHYSICAL:
2275 return "MTKFB_GETVFRAMEPHYSICAL";
2276 case MTKFB_WAIT_OVERLAY_READY:
2277 return "MTKFB_WAIT_OVERLAY_READY";
2278 case MTKFB_GET_OVERLAY_LAYER_COUNT:
2279 return "MTKFB_GET_OVERLAY_LAYER_COUNT";
2280 case MTKFB_GET_VIDEOLAYER_SIZE:
2281 return "MTKFB_GET_VIDEOLAYER_SIZE";
2282 case MTKFB_CAPTURE_VIDEOBUFFER:
2283 return "MTKFB_CAPTURE_VIDEOBUFFER";
2284 case MTKFB_TV_POST_VIDEO_BUFFER:
2285 return "MTKFB_TV_POST_VIDEO_BUFFER";
2286 case MTKFB_TV_LEAVE_VIDEO_PLAYBACK_MODE:
2287 return "MTKFB_TV_LEAVE_VIDEO_PLAYBACK_MODE";
2288 case MTKFB_IS_TV_CABLE_PLUG_IN:
2289 return "MTKFB_IS_TV_CABLE_PLUG_IN";
2290 case MTKFB_BOOTANIMATION:
2291 return "MTKFB_BOOTANIMATION";
2292 case MTKFB_GETFPS:
2293 return "MTKFB_GETFPS";
2294 case MTKFB_VSYNC:
2295 return "MTKFB_VSYNC";
2296 case MTKFB_FM_NOTIFY_FREQ:
2297 return "MTKFB_FM_NOTIFY_FREQ";
2298 case MTKFB_RESET_UPDATESPEED:
2299 return "MTKFB_RESET_UPDATESPEED";
2300 case MTKFB_SET_UI_LAYER_ALPHA:
2301 return "MTKFB_SET_UI_LAYER_ALPHA";
2302 case MTKFB_SET_UI_LAYER_SRCKEY:
2303 return "MTKFB_SET_UI_LAYER_SRCKEY";
2304 case MTKFB_GET_MAX_DISPLAY_COUNT:
2305 return "MTKFB_GET_MAX_DISPLAY_COUNT";
2306 case MTKFB_SET_FB_LAYER_SECURE:
2307 return "MTKFB_SET_FB_LAYER_SECURE";
2308 case MTKFB_META_RESTORE_SCREEN:
2309 return "MTKFB_META_RESTORE_SCREEN";
2310 case MTKFB_ERROR_INDEX_UPDATE_TIMEOUT:
2311 return "MTKFB_ERROR_INDEX_UPDATE_TIMEOUT";
2312 case MTKFB_ERROR_INDEX_UPDATE_TIMEOUT_AEE:
2313 return "MTKFB_ERROR_INDEX_UPDATE_TIMEOUT_AEE";
2314 case MTKFB_QUEUE_OVERLAY_CONFIG:
2315 return "MTKFB_QUEUE_OVERLAY_CONFIG";
2316 default:
2317 return "Invalid";
2318 }
2319}
2320
2321
2322mtk_dispif_info_t dispif_info[MTKFB_MAX_DISPLAY_COUNT];
2323extern unsigned int isAEEEnabled;
2324
2325#if LINUX_VERSION_CODE > KERNEL_VERSION(3,7,0)
2326static int mtkfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
2327#else
2328static int mtkfb_ioctl(struct file *file, struct fb_info *info, unsigned int cmd, unsigned long arg)
2329#endif
2330{
2331 void __user *argp = (void __user *)arg;
2332 DISP_STATUS ret = 0;
2333 int r = 0, i;
2334
2335 MTKFB_FUNC();
2336 /// M: dump debug mmprofile log info
2337 MMProfileLogEx(MTKFB_MMP_Events.IOCtrl, MMProfileFlagPulse, _IOC_NR(cmd), arg);
2338 pr_info("mtkfb_ioctl, info=0x%08x, cmd=0x%08x(%s), arg=0x%08x\n", (unsigned int)info,
2339 (unsigned int)cmd, _mtkfb_ioctl_spy(cmd), (unsigned int)arg);
2340
2341 switch (cmd)
2342 {
2343 case MTKFB_QUEUE_OVERLAY_CONFIG:
2344 {
2345 struct fb_overlay_config config;
2346 if (copy_from_user(&config, (void __user *)arg, sizeof(config))) {
2347 MTKFB_LOG("[FB]: copy_from_user failed! line: %d \n", __LINE__);
2348 return -EFAULT;
2349 }
2350
2351 for (i = 0; i < HW_OVERLAY_COUNT; i++)
2352 {
2353 MTKFB_LOG("MTKFB_QUEUE_OVERLAY_CONFIG: fence:%d, time: 0x%x, layer%d en%d, next_idx=0x%x, vaddr=0x%x, paddr=0x%x, fmt=%u,"
2354 " d-link=%u, pitch=%u, xoff=%u, yoff=%u, w=%u, h=%u, alpha_en=%d, alpha=%d, fence_fd=%d, ion_fd=%d, security=%d\n",
2355 config.fence,
2356 config.time,
2357 config.layers[i].layer_id,
2358 config.layers[i].layer_enable,
2359 config.layers[i].next_buff_idx,
2360 (unsigned int)(config.layers[i].src_base_addr),
2361 (unsigned int)(config.layers[i].src_phy_addr),
2362 config.layers[i].src_fmt,
2363 (unsigned int)(config.layers[i].src_direct_link),
2364 config.layers[i].src_pitch,
2365 config.layers[i].src_offset_x,
2366 config.layers[i].src_offset_y,
2367 config.layers[i].src_width,
2368 config.layers[i].src_height,
2369 config.layers[i].alpha_enable,
2370 config.layers[i].alpha,
2371 config.layers[i].fence_fd,
2372 config.layers[i].ion_fd,
2373 config.layers[i].security);
2374 }
2375
2376 if (!g_fb_pattern_en)
2377 r = mtkfb_queue_overlay_config((struct mtkfb_device *)info->par, &config);
2378 else
2379 r = fb_pattern((struct mtkfb_device *)info->par, &config);
2380
2381 if (copy_to_user((void __user *)arg, &config, sizeof(config))) {
2382 MTKFB_LOG("[FB]: copy_to_user failed! line:%d \n", __LINE__);
2383 r = -EFAULT;
2384 }
2385 return (r);
2386 }
2387 case MTKFB_SET_OVERLAY_LAYER:
2388 {
2389 struct fb_overlay_layer layerInfo;
2390 MTKFB_LOG(" mtkfb_ioctl():MTKFB_SET_OVERLAY_LAYER\n");
2391
2392 if (copy_from_user(&layerInfo, (void __user *)arg, sizeof(layerInfo))) {
2393 MTKFB_LOG("[FB]: copy_from_user failed! line:%d \n", __LINE__);
2394 r = -EFAULT;
2395 }
2396 else
2397 {
2398 //in early suspend mode ,will not update buffer index, info SF by return value
2399 if(is_early_suspended == TRUE)
2400 {
2401 pr_info("[FB] error, set overlay in early suspend ,skip! \n");
2402 return MTKFB_ERROR_IS_EARLY_SUSPEND;
2403 }
2404
2405 mutex_lock(&OverlaySettingMutex);
2406 mtkfb_set_overlay_layer((struct mtkfb_device *)info->par, &layerInfo);
2407 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
2408 if (is_ipoh_bootup)
2409 {
2410 int i;
2411 for (i=0; i<DDP_OVL_LAYER_MUN; i++)
2412 cached_layer_config[i].isDirty = 1;
2413 is_ipoh_bootup = false;
2414 }
2415 atomic_set(&OverlaySettingDirtyFlag, 1);
2416 atomic_set(&OverlaySettingApplied, 0);
2417 #endif
2418 mutex_unlock(&OverlaySettingMutex);
2419 }
2420 return (r);
2421 }
2422 case MTKFB_GET_FRAMEBUFFER_MVA:
2423 if (copy_to_user(argp, &fb_pa, sizeof(fb_pa))) {
2424 MTKFB_LOG("[FB]: copy_to_user failed! line:%d \n", __LINE__);
2425 r = -EFAULT;
2426 }
2427 return (r);
2428 case MTKFB_GET_DISPLAY_IF_INFORMATION:
2429 {
2430 int displayid = 0;
2431 if (copy_from_user(&displayid, (void __user *)arg, sizeof(displayid))) {
2432 MTKFB_LOG("[FB]: copy_from_user failed! line:%d \n", __LINE__);
2433 return -EFAULT;
2434 }
2435 MTKFB_LOG("MTKFB_GET_DISPLAY_IF_INFORMATION display_id=%d\n", displayid);
4b9e9796 2436 if ((displayid < 0) || (displayid >= MTKFB_MAX_DISPLAY_COUNT)) {
6fa3eb70
S
2437 MTKFB_LOG("[FB]: invalid display id:%d \n", displayid);
2438 return -EFAULT;
2439 }
2440 dispif_info[displayid].physicalHeight = DISP_GetActiveHeight();
2441 dispif_info[displayid].physicalWidth = DISP_GetActiveWidth() ;
2442 if (copy_to_user((void __user *)arg, &(dispif_info[displayid]), sizeof(mtk_dispif_info_t))) {
2443 MTKFB_LOG("[FB]: copy_to_user failed! line:%d \n", __LINE__);
2444 r = -EFAULT;
2445 }
2446 return (r);
2447 }
2448 case MTKFB_POWEROFF:
2449 {
2450 MTKFB_FUNC();
2451
2452 mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, LED_OFF);
2453
2454 if (!lcd_fps)
2455 msleep(30);
2456 else
2457 msleep(2*100000/lcd_fps); // Delay 2 frames.
2458
2459 if(is_early_suspended)
2460 {
2461 MTKFB_LOG("[FB driver] MTKFB_POWEROFF ioctl,device had been suspended\n");
2462 return r;
2463 }
2464 if (down_interruptible(&sem_early_suspend))
2465 {
2466 pr_info("[FB Driver] can't get semaphore in mtkfb_early_suspend()\n");
2467 return -ERESTARTSYS;
2468 }
2469
2470 is_early_suspended = TRUE;
2471 up(&sem_early_suspend);
2472#ifndef NONFLUSH
2473 /* Wait until queued compositions are applied */
2474 flush_workqueue(((struct mtkfb_device *)info->par)->update_ovls_wq);
2475#else
2476 /* Do not flush work queue, becuase this will cause fence disorder */
2477 /* disable all layer */
2478 {
2479 struct fb_overlay_config config;
2480 struct sync_fence *fence;
2481
2482 config.layers[0].layer_id = 0;
2483 config.layers[0].layer_enable = 0;
2484 config.layers[0].fence_fd = -1;
2485 config.layers[0].ion_fd = -1;
2486 config.layers[1].layer_id = 1;
2487 config.layers[1].layer_enable = 0;
2488 config.layers[1].fence_fd = -1;
2489 config.layers[1].ion_fd = -1;
2490 config.layers[2].layer_id = 2;
2491 config.layers[2].layer_enable = 0;
2492 config.layers[2].fence_fd = -1;
2493 config.layers[2].ion_fd = -1;
2494 config.layers[3].layer_id = 3;
2495 config.layers[3].layer_enable = 0;
2496 config.layers[3].fence_fd = -1;
2497 config.layers[3].ion_fd = -1;
2498
2499 mtkfb_queue_overlay_config((struct mtkfb_device *)info->par, &config);
2500
2501 if (config.fence != -1) {
2502 fence = sync_fence_fdget(config.fence);
2503 if (sync_fence_wait(fence, 1000) < 0)
2504 pr_err("MTKFB_POWEROFF error waiting for fence to signal\n");
2505 sync_fence_put(fence);
2506 put_unused_fd(config.fence);
2507 }
2508 }
2509#endif
2510 if (down_interruptible(&sem_early_suspend))
2511 {
2512 pr_info("[FB Driver] can't get semaphore in mtkfb_early_suspend()\n");
2513 return -ERESTARTSYS;
2514 }
2515
2516 DISP_PrepareSuspend();
2517 // Wait for disp finished.
2518 /* [PLATFORM]-Mod-BEGIN by TCTSZ.yaohui.zeng, 2015/04/15,MTK patch,fix FB suspend/resume DSI issue*/
2519 if(wait_event_interruptible_timeout(_dsi_wait_vm_done_queue, !_IsEngineBusy(), HZ/10)==0 )
2520 {
2521 pr_info("[FB Driver] Wait disp finished timeout in early_suspend\n");
2522 }
2523 /* [PLATFORM]-Mod-END by TCTSZ.yaohui.zeng, 2015/04/15*/
2524 DISP_CHECK_RET(DISP_PauseVsync(TRUE));
2525 DISP_CHECK_RET(DISP_PanelEnable(FALSE));
2526 DISP_CHECK_RET(DISP_PowerEnable(FALSE));
2527 disp_path_clock_off("mtkfb");
2528
2529 MMProfileLog(MTKFB_MMP_Events.EarlySuspend, MMProfileFlagStart);
2530
2531 up(&sem_early_suspend);
2532
2533 return r;
2534 }
2535
2536 case MTKFB_POWERON:
2537 {
2538 MTKFB_FUNC();
2539 if(!is_early_suspended) return r;
2540 if (down_interruptible(&sem_early_suspend))
2541 {
2542 pr_info("[FB Driver] can't get semaphore in mtkfb_late_resume()\n");
2543 return -ERESTARTSYS;
2544 }
2545 disp_path_clock_on("mtkfb");
2546 DISP_CHECK_RET(DISP_PauseVsync(FALSE));
2547 DISP_CHECK_RET(DISP_PowerEnable(TRUE));
2548 DISP_CHECK_RET(DISP_PanelEnable(TRUE));
2549
2550 is_early_suspended = FALSE;
2551
2552 if (is_ipoh_bootup) { //ALPS01279263 CL2317283
2553 DISP_StartConfigUpdate();
2554 } else {
2555 mtkfb_clear_lcm();
2556 }
2557
2558 MMProfileLog(MTKFB_MMP_Events.EarlySuspend, MMProfileFlagEnd);
2559 up(&sem_early_suspend);
2560
2561 return r;
2562 }
2563 case MTKFB_GET_POWERSTATE:
2564 {
2565 unsigned long power_state;
2566
2567 if(is_early_suspended == TRUE)
2568 power_state = 0;
2569 else
2570 power_state = 1;
2571
2572 return copy_to_user(argp, &power_state, sizeof(power_state)) ? -EFAULT : 0;
2573 }
2574
2575 case MTKFB_CONFIG_IMMEDIATE_UPDATE:
2576 {
2577 MTKFB_LOG("[%s] MTKFB_CONFIG_IMMEDIATE_UPDATE, enable = %lu\n",
2578 __func__, arg);
2579 if (down_interruptible(&sem_early_suspend)) {
2580 MTKFB_LOG("[mtkfb_ioctl] can't get semaphore:%d\n", __LINE__);
2581 return -ERESTARTSYS;
2582 }
2583 sem_early_suspend_cnt--;
2584 DISP_WaitForLCDNotBusy();
2585 ret = DISP_ConfigImmediateUpdate((BOOL)arg);
2586 sem_early_suspend_cnt++;
2587 up(&sem_early_suspend);
2588 return (r);
2589 }
2590
2591 case MTKFB_CAPTURE_FRAMEBUFFER:
2592 {
2593 unsigned int pbuf = 0;
2594 if (copy_from_user(&pbuf, (void __user *)arg, sizeof(pbuf)))
2595 {
2596 MTKFB_LOG("[FB]: copy_from_user failed! line:%d \n", __LINE__);
2597 r = -EFAULT;
2598 }
2599 else
2600 {
2601 mtkfb_capture_framebuffer(info, pbuf);
2602 }
2603
2604 return (r);
2605 }
2606
2607 case MTKFB_GET_OVERLAY_LAYER_INFO:
2608 {
2609 struct fb_overlay_layer_info layerInfo;
2610 MTKFB_LOG(" mtkfb_ioctl():MTKFB_GET_OVERLAY_LAYER_INFO\n");
2611
2612 if (copy_from_user(&layerInfo, (void __user *)arg, sizeof(layerInfo))) {
2613 MTKFB_LOG("[FB]: copy_from_user failed! line:%d \n", __LINE__);
2614 return -EFAULT;
2615 }
2616 if (mtkfb_get_overlay_layer_info(&layerInfo) < 0)
2617 {
2618 MTKFB_LOG("[FB]: Failed to get overlay layer info\n");
2619 return -EFAULT;
2620 }
2621 if (copy_to_user((void __user *)arg, &layerInfo, sizeof(layerInfo))) {
2622 MTKFB_LOG("[FB]: copy_to_user failed! line:%d \n", __LINE__);
2623 r = -EFAULT;
2624 }
2625 return (r);
2626 }
2627
2628 case MTKFB_ERROR_INDEX_UPDATE_TIMEOUT:
2629 {
2630 pr_info("[DDP] mtkfb_ioctl():MTKFB_ERROR_INDEX_UPDATE_TIMEOUT \n");
2631 // call info dump function here
2632 mtkfb_dump_layer_info();
2633 return (r);
2634 }
2635
2636 case MTKFB_ERROR_INDEX_UPDATE_TIMEOUT_AEE:
2637 {
2638 pr_info("[DDP] mtkfb_ioctl():MTKFB_ERROR_INDEX_UPDATE_TIMEOUT \n");
2639 // call info dump function here
2640 mtkfb_dump_layer_info();
2641 mtkfb_aee_print("surfaceflinger-mtkfb blocked");
2642 return (r);
2643 }
2644
2645 case MTKFB_SET_VIDEO_LAYERS:
2646 {
2647 struct mmp_fb_overlay_layers
2648 {
2649 struct fb_overlay_layer Layer0;
2650 struct fb_overlay_layer Layer1;
2651 struct fb_overlay_layer Layer2;
2652 struct fb_overlay_layer Layer3;
2653 };
2654 struct fb_overlay_layer layerInfo[VIDEO_LAYER_COUNT];
2655 MTKFB_LOG(" mtkfb_ioctl():MTKFB_SET_VIDEO_LAYERS\n");
2656 MMProfileLog(MTKFB_MMP_Events.SetOverlayLayers, MMProfileFlagStart);
2657 if (copy_from_user(&layerInfo, (void __user *)arg, sizeof(layerInfo))) {
2658 MTKFB_LOG("[FB]: copy_from_user failed! line:%d \n", __LINE__);
2659 MMProfileLogMetaString(MTKFB_MMP_Events.SetOverlayLayers, MMProfileFlagEnd, "Copy_from_user failed!");
2660 r = -EFAULT;
2661 } else {
2662 int32_t i;
2663 mutex_lock(&OverlaySettingMutex);
2664 for (i = 0; i < VIDEO_LAYER_COUNT; ++i) {
2665 mtkfb_set_overlay_layer((struct mtkfb_device *)info->par, &layerInfo[i]);
2666 }
2667 is_ipoh_bootup = false;
2668 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
2669 atomic_set(&OverlaySettingDirtyFlag, 1);
2670 atomic_set(&OverlaySettingApplied, 0);
2671 #endif
2672 mutex_unlock(&OverlaySettingMutex);
2673 MMProfileLogStructure(MTKFB_MMP_Events.SetOverlayLayers, MMProfileFlagEnd, layerInfo, struct mmp_fb_overlay_layers);
2674 }
2675
2676 return (r);
2677 }
2678
2679 case MTKFB_TRIG_OVERLAY_OUT:
2680 {
2681 MTKFB_LOG(" mtkfb_ioctl():MTKFB_TRIG_OVERLAY_OUT\n");
2682 MMProfileLog(MTKFB_MMP_Events.TrigOverlayOut, MMProfileFlagPulse);
2683 return mtkfb_update_screen(info);
2684 }
2685
2686//#endif // MTK_FB_OVERLAY_SUPPORT
2687
2688 case MTKFB_SET_ORIENTATION:
2689 {
2690 MTKFB_LOG("[MTKFB] Set Orientation: %lu\n", arg);
2691 // surface flinger orientation definition of 90 and 270
2692 // is different than DISP_TV_ROT
2693 if (arg & 0x1) arg ^= 0x2;
2694 arg *=90;
2695#if defined(MTK_HDMI_SUPPORT)
2696 //for MT6589, the orientation of DDPK is changed from 0123 to 0/90/180/270
2697 hdmi_setorientation((int)arg);
2698#endif
2699 return 0;
2700 }
2701 case MTKFB_META_RESTORE_SCREEN:
2702 {
2703 struct fb_var_screeninfo var;
2704
2705 if (copy_from_user(&var, argp, sizeof(var)))
2706 return -EFAULT;
2707
2708 info->var.yoffset = var.yoffset;
2709 init_framebuffer(info);
2710
2711 return mtkfb_pan_display_impl(&var, info);
2712 }
2713
2714 case MTKFB_GET_INTERFACE_TYPE:
2715 {
2716 extern LCM_PARAMS *lcm_params;
2717 unsigned long lcm_type = lcm_params->type;
2718
2719 MTKFB_LOG("[MTKFB] MTKFB_GET_INTERFACE_TYPE\n");
2720
2721 pr_info("[MTKFB EM]MTKFB_GET_INTERFACE_TYPE is %ld\n", lcm_type);
2722
2723 return copy_to_user(argp, &lcm_type, sizeof(lcm_type)) ? -EFAULT : 0;
2724 }
2725 case MTKFB_GET_DEFAULT_UPDATESPEED:
2726 {
2727 unsigned int speed;
2728 MTKFB_LOG("[MTKFB] get default update speed\n");
2729 DISP_Get_Default_UpdateSpeed(&speed);
2730
2731 pr_info("[MTKFB EM]MTKFB_GET_DEFAULT_UPDATESPEED is %d\n", speed);
2732 return copy_to_user(argp, &speed,
2733 sizeof(speed)) ? -EFAULT : 0;
2734 }
2735
2736 case MTKFB_GET_CURR_UPDATESPEED:
2737 {
2738 unsigned int speed;
2739 MTKFB_LOG("[MTKFB] get current update speed\n");
2740 DISP_Get_Current_UpdateSpeed(&speed);
2741
2742 pr_info("[MTKFB EM]MTKFB_GET_CURR_UPDATESPEED is %d\n", speed);
2743 return copy_to_user(argp, &speed,
2744 sizeof(speed)) ? -EFAULT : 0;
2745 }
2746
2747 case MTKFB_CHANGE_UPDATESPEED:
2748 {
2749 unsigned int speed;
2750 MTKFB_LOG("[MTKFB] change update speed\n");
2751
2752 if (copy_from_user(&speed, (void __user *)arg, sizeof(speed))) {
2753 MTKFB_LOG("[FB]: copy_from_user failed! line:%d \n", __LINE__);
2754 r = -EFAULT;
2755 } else {
2756 DISP_Change_Update(speed);
2757
2758 pr_info("[MTKFB EM]MTKFB_CHANGE_UPDATESPEED is %d\n", speed);
2759
2760 }
2761 return (r);
2762 }
2763
2764 case MTKFB_FBLAYER_ENABLE:
2765 {
2766 BOOL enable;
2767 if(copy_from_user(&enable,(void __user*)argp,sizeof(BOOL))){
2768 MTKFB_LOG("[FB]: copy_from_user failed! line:%d \n", __LINE__);
2769 r = -EFAULT;
2770 }
2771 else{
2772 MTKFB_LOG("[FB]: FDLAYER_ENABLE:%d \n",enable);
2773
2774 hwc_force_fb_enabled = (enable ? true : false);
2775
2776 mutex_lock(&OverlaySettingMutex);
2777 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
2778 {
2779 struct fb_overlay_layer layer = {0};
2780 layer.layer_id = 0;
2781 Disp_Ovl_Engine_Get_layer_info(mtkfb_instance, &layer);
2782 layer.layer_enable = enable;
2783 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, &layer);
2784 }
2785 #else
2786 cached_layer_config[FB_LAYER].layer_en = enable;
2787 #endif
2788 if (mtkfb_using_layer_type != LAYER_2D)
2789 {
2790 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
2791 {
2792 struct fb_overlay_layer layer = {0};
2793 layer.layer_id = FB_LAYER+1;
2794 Disp_Ovl_Engine_Get_layer_info(mtkfb_instance, &layer);
2795 layer.layer_enable = enable;
2796 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, &layer);
2797 }
2798 #else
2799 cached_layer_config[FB_LAYER+1].layer_en = enable;
2800 #endif
2801 }
2802 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
2803 cached_layer_config[FB_LAYER].isDirty= true;
2804 atomic_set(&OverlaySettingDirtyFlag, 1);
2805 atomic_set(&OverlaySettingApplied, 0);
2806 #endif
2807 mutex_unlock(&OverlaySettingMutex);
2808
2809
2810 }
2811
2812 return (r);
2813 }
2814 case MTKFB_AEE_LAYER_EXIST:
2815 {
2816 //pr_info("[MTKFB] isAEEEnabled=%d \n", isAEEEnabled);
2817 return copy_to_user(argp, &isAEEEnabled,
2818 sizeof(isAEEEnabled)) ? -EFAULT : 0;
2819 }
2820 case MTKFB_LOCK_FRONT_BUFFER:
2821 return 0;
2822 case MTKFB_UNLOCK_FRONT_BUFFER:
2823 return 0;
2824////////////////////////////////////////////////
2825 default:
2826 pr_info("mtkfb_ioctl 0x%08x(%s) Not support", (unsigned int)cmd, _mtkfb_ioctl_spy(cmd));
2827 //pr_info("mtkfb_ioctl Not support,MTKFB_QUEUE_OVERLAY_CONFIG=0x%08x info=0x%08x, cmd=0x%08x, arg=0x%08x\n",MTKFB_QUEUE_OVERLAY_CONFIG, (unsigned int)info, (unsigned int)cmd, (unsigned int)arg);
2828 return -EINVAL;
2829 }
2830}
2831
2832
2833/* Callback table for the frame buffer framework. Some of these pointers
2834 * will be changed according to the current setting of fb_info->accel_flags.
2835 */
2836static struct fb_ops mtkfb_ops = {
2837 .owner = THIS_MODULE,
2838 .fb_open = mtkfb_open,
2839 .fb_release = mtkfb_release,
2840 .fb_setcolreg = mtkfb_setcolreg,
2841 .fb_pan_display = mtkfb_pan_display_proxy,
2842 .fb_fillrect = cfb_fillrect,
2843 .fb_copyarea = cfb_copyarea,
2844 .fb_imageblit = cfb_imageblit,
2845 .fb_cursor = mtkfb_soft_cursor,
2846 .fb_check_var = mtkfb_check_var,
2847 .fb_set_par = mtkfb_set_par,
2848 .fb_ioctl = mtkfb_ioctl,
2849};
2850
2851/*
2852 * ---------------------------------------------------------------------------
2853 * Sysfs interface
2854 * ---------------------------------------------------------------------------
2855 */
2856
2857static int mtkfb_register_sysfs(struct mtkfb_device *fbdev)
2858{
2859 NOT_REFERENCED(fbdev);
2860
2861 return 0;
2862}
2863
2864static void mtkfb_unregister_sysfs(struct mtkfb_device *fbdev)
2865{
2866 NOT_REFERENCED(fbdev);
2867}
2868
2869/*
2870 * ---------------------------------------------------------------------------
2871 * LDM callbacks
2872 * ---------------------------------------------------------------------------
2873 */
2874/* Initialize system fb_info object and set the default video mode.
2875 * The frame buffer memory already allocated by lcddma_init
2876 */
2877static int mtkfb_fbinfo_init(struct fb_info *info)
2878{
2879 struct mtkfb_device *fbdev = (struct mtkfb_device *)info->par;
2880 struct fb_var_screeninfo var;
2881 int r = 0;
2882
2883 MSG_FUNC_ENTER();
2884
2885 BUG_ON(!fbdev->fb_va_base);
2886 info->fbops = &mtkfb_ops;
2887 info->flags = FBINFO_FLAG_DEFAULT;
2888 info->screen_base = (char *) fbdev->fb_va_base;
2889 info->screen_size = fbdev->fb_size_in_byte;
2890 info->pseudo_palette = fbdev->pseudo_palette;
2891
2892 r = fb_alloc_cmap(&info->cmap, 16, 0);
2893 if (r != 0)
2894 PRNERR("unable to allocate color map memory\n");
2895
2896 // setup the initial video mode (RGB565)
2897
2898 memset(&var, 0, sizeof(var));
2899
2900 var.xres = MTK_FB_XRES;
2901 var.yres = MTK_FB_YRES;
2902 var.xres_virtual = MTK_FB_XRESV;
2903 var.yres_virtual = MTK_FB_YRESV;
2904
2905 var.bits_per_pixel = 16;
2906
2907 var.red.offset = 11; var.red.length = 5;
2908 var.green.offset = 5; var.green.length = 6;
2909 var.blue.offset = 0; var.blue.length = 5;
2910
2911 var.width = DISP_GetActiveWidth();
2912 var.height = DISP_GetActiveHeight();
2913
2914 var.activate = FB_ACTIVATE_NOW;
2915
2916 r = mtkfb_check_var(&var, info);
2917 if (r != 0)
2918 PRNERR("failed to mtkfb_check_var\n");
2919
2920 info->var = var;
2921
2922 r = mtkfb_set_par(info);
2923 if (r != 0)
2924 PRNERR("failed to mtkfb_set_par\n");
2925
2926 MSG_FUNC_LEAVE();
2927 return r;
2928}
2929
2930/* Release the fb_info object */
2931static void mtkfb_fbinfo_cleanup(struct mtkfb_device *fbdev)
2932{
2933 MSG_FUNC_ENTER();
2934
2935 fb_dealloc_cmap(&fbdev->fb_info->cmap);
2936
2937 MSG_FUNC_LEAVE();
2938}
2939
2940void mtkfb_disable_non_fb_layer(void)
2941{
2942 int id;
2943 unsigned int dirty = 0;
2944 for (id = 0; id < DDP_OVL_LAYER_MUN; id++)
2945 {
2946 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
2947 {
2948 struct fb_overlay_layer layer = {0};
2949 layer.layer_id = id;
2950 Disp_Ovl_Engine_Get_layer_info(mtkfb_instance, &layer);
2951 layer.layer_enable = 0;
2952 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, &layer);
2953 }
2954 #else
2955 if (cached_layer_config[id].layer_en == 0)
2956 continue;
2957
2958 if (cached_layer_config[id].addr >= fb_pa &&
2959 cached_layer_config[id].addr < (fb_pa+DISP_GetVRamSize()))
2960 continue;
2961
2962 DISP_LOG_PRINT(ANDROID_LOG_INFO, "LCD", " disable(%d)\n", id);
2963 cached_layer_config[id].layer_en = 0;
2964 cached_layer_config[id].isDirty = true;
2965 #endif
2966 dirty = 1;
2967 }
2968 if (dirty)
2969 {
2970 memset(mtkfb_fbi->screen_base, 0, DISP_GetVRamSize());
2971 mtkfb_pan_display_impl(&mtkfb_fbi->var, mtkfb_fbi);
2972 }
2973}
2974
2975int m4u_reclaim_mva_callback_ovl(int moduleID, unsigned int va, unsigned int size, unsigned int mva)
2976{
2977 int id;
2978 unsigned int dirty = 0;
2979 MMProfileLogEx(MTKFB_MMP_Events.Debug, MMProfileFlagStart, mva, size);
2980 for (id = 0; id < DDP_OVL_LAYER_MUN; id++)
2981 {
2982 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
2983 if (cached_layer_config[id].layer_en == 0)
2984 continue;
2985
2986 if (cached_layer_config[id].addr >= mva &&
2987 cached_layer_config[id].addr < (mva+size))
2988 {
2989 pr_info("Warning: m4u required to disable layer id=%d\n", id);
2990 cached_layer_config[id].layer_en = 0;
2991 cached_layer_config[id].isDirty = 1;
2992 dirty = 1;
2993 }
2994 #endif
2995 }
2996 pr_info("Warning: m4u_reclaim_mva_callback_ovl. mva=0x%08X size=0x%X dirty=%d\n", mva, size, dirty);
2997 if (dirty)
2998 {
2999 memset(mtkfb_fbi->screen_base, 0, DISP_GetVRamSize());
3000 mtkfb_pan_display_impl(&mtkfb_fbi->var, mtkfb_fbi);
3001 }
3002 MMProfileLogEx(MTKFB_MMP_Events.Debug, MMProfileFlagEnd, dirty, 0);
3003 return 0;
3004}
3005
3006#define RGB565_TO_ARGB8888(x) \
3007 ((((x) & 0x1F) << 3) | \
3008 (((x) & 0x7E0) << 5) | \
3009 (((x) & 0xF800) << 8) | \
3010 (0xFF << 24)) // opaque
3011
3012/* Init frame buffer content as 3 R/G/B color bars for debug */
3013static int init_framebuffer(struct fb_info *info)
3014{
3015 void *buffer = info->screen_base +
3016 info->var.yoffset * info->fix.line_length;
3017
3018 // clean whole frame buffer as black
3019 memset(buffer, 0, info->screen_size);
3020
3021 return 0;
3022}
3023
3024
3025/* Free driver resources. Can be called to rollback an aborted initialization
3026 * sequence.
3027 */
3028static void mtkfb_free_resources(struct mtkfb_device *fbdev, int state)
3029{
3030 int r = 0;
3031
3032 switch (state) {
3033 case MTKFB_ACTIVE:
3034 r = unregister_framebuffer(fbdev->fb_info);
3035 ASSERT(0 == r);
3036 //lint -fallthrough
3037 case 5:
3038 mtkfb_unregister_sysfs(fbdev);
3039 //lint -fallthrough
3040 case 4:
3041 mtkfb_fbinfo_cleanup(fbdev);
3042 //lint -fallthrough
3043 case 3:
3044 DISP_CHECK_RET(DISP_Deinit());
3045 //lint -fallthrough
3046 case 2:
3047 dma_free_coherent(0, fbdev->fb_size_in_byte,
3048 fbdev->fb_va_base, fbdev->fb_pa_base);
3049 //lint -fallthrough
3050 case 1:
3051 dev_set_drvdata(fbdev->dev, NULL);
3052 framebuffer_release(fbdev->fb_info);
3053 //lint -fallthrough
3054 case 0:
3055 /* nothing to free */
3056 break;
3057 default:
3058 BUG();
3059 }
3060}
3061
3062extern char* saved_command_line;
3063char mtkfb_lcm_name[256] = {0};
3064BOOL mtkfb_find_lcm_driver(void)
3065{
3066 BOOL ret = FALSE;
3067 char *p, *q;
3068
3069 p = strstr(saved_command_line, "lcm=");
3070 if(p == NULL)
3071 {
3072 // we can't find lcm string in the command line, the uboot should be old version
3073 return DISP_SelectDevice(NULL);
3074 }
3075
3076 p += 4;
3077 if((p - saved_command_line) > strlen(saved_command_line+1))
3078 {
3079 ret = FALSE;
3080 goto done;
3081 }
3082
3083 pr_info("%s, %s\n", __func__, p);
3084 q = p;
3085 while(*q != ' ' && *q != '\0')
3086 q++;
3087
3088 memset((void*)mtkfb_lcm_name, 0, sizeof(mtkfb_lcm_name));
3089 strncpy((char*)mtkfb_lcm_name, (const char*)p, (int)(q-p));
3090
3091 pr_info("%s, %s\n", __func__, mtkfb_lcm_name);
3092 if(DISP_SelectDevice(mtkfb_lcm_name))
3093 ret = TRUE;
3094
3095done:
3096 return ret;
3097}
3098
3099void disp_get_fb_address(UINT32 *fbVirAddr, UINT32 *fbPhysAddr)
3100{
3101 struct mtkfb_device *fbdev = (struct mtkfb_device *)mtkfb_fbi->par;
3102
3103 *fbVirAddr = (UINT32)fbdev->fb_va_base + mtkfb_fbi->var.yoffset * mtkfb_fbi->fix.line_length;
3104 *fbPhysAddr =(UINT32)fbdev->fb_pa_base + mtkfb_fbi->var.yoffset * mtkfb_fbi->fix.line_length;
3105}
3106
3107static int mtkfb_fbinfo_modify(struct fb_info *info)
3108{
3109 struct fb_var_screeninfo var;
3110 int r = 0;
3111
3112 memcpy(&var, &(info->var), sizeof(var));
3113 var.activate = FB_ACTIVATE_NOW;
3114 var.bits_per_pixel = 32;
3115 var.transp.offset = 24;
3116 var.transp.length = 8;
3117 var.red.offset = 16; var.red.length = 8;
3118 var.green.offset = 8; var.green.length = 8;
3119 var.blue.offset = 0; var.blue.length = 8;
3120 var.yoffset = var.yres;
3121
3122 r = mtkfb_check_var(&var, info);
3123 if (r != 0)
3124 PRNERR("failed to mtkfb_check_var\n");
3125
3126 info->var = var;
3127
3128 r = mtkfb_set_par(info);
3129 if (r != 0)
3130 PRNERR("failed to mtkfb_set_par\n");
3131
3132 return r;
3133}
3134
3135static void mtkfb_fb_565_to_8888(struct fb_info *fb_info)
3136{
3137 unsigned int xres = fb_info->var.xres;
3138 unsigned int yres = fb_info->var.yres;
3139 unsigned int x_virtual = ALIGN_TO(xres,disphal_get_fb_alignment());
3140
3141 unsigned int fbsize = x_virtual * yres * 2;
3142
3143 unsigned short *s = (unsigned short*) fb_info->screen_base;
3144 unsigned int *d = (unsigned int*) (fb_info->screen_base + fbsize * 2);
3145 unsigned short src_rgb565 = 0;
3146 int j = 0;
3147 int k = 0;
3148 int wait_ret = 0;
3149
3150 // return; //fix battery disappearing
3151
3152 PRNERR("mtkfb_fb_565_to_8888 xres=%d yres=%d fbsize=0x%X x_virtual=%d s=0x%08X d=0x%08X\n",
3153 xres, yres, fbsize, x_virtual, s, d);
3154 //printf("[boot_logo_updater]normal\n");
3155 for (j = 0; j < yres; ++ j){
3156 for(k = 0; k < xres; ++ k)
3157 {
3158 src_rgb565 = *s++;
3159 *d++ = RGB565_TO_ARGB8888(src_rgb565);
3160 }
3161 d += (ALIGN_TO(xres, MTK_FB_ALIGNMENT)-xres);
3162#if 0
3163 for(k = xres; k < x_virtual; ++ k){
3164 *d++ = 0xFFFFFFFF;
3165 *s++;
3166 }
3167#endif
3168 s += (ALIGN_TO(xres, disphal_get_fb_alignment()) - xres);
3169 }
3170 //printf("[boot_logo_updater] loop copy color over\n");
3171
3172 mtkfb_fbinfo_modify(fb_info);
3173 wait_ret = wait_event_interruptible_timeout(reg_update_wq, atomic_read(&OverlaySettingApplied), HZ/10);
3174 MTKFB_LOG("[WaitQ] wait_event_interruptible() ret = %d, %d\n", wait_ret, __LINE__);
3175
3176 s = (unsigned short *)fb_info->screen_base;
3177 d = (unsigned int *) (fb_info->screen_base + fbsize * 2);
3178 memcpy(s,d,fbsize*2);
3179}
3180
3181
3182/* Called by LDM binding to probe and attach a new device.
3183 * Initialization sequence:
3184 * 1. allocate system fb_info structure
3185 * select panel type according to machine type
3186 * 2. init LCD panel
3187 * 3. init LCD controller and LCD DMA
3188 * 4. init system fb_info structure
3189 * 5. init gfx DMA
3190 * 6. enable LCD panel
3191 * start LCD frame transfer
3192 * 7. register system fb_info structure
3193 */
3194static int mtkfb_probe(struct device *dev)
3195{
3196 struct platform_device *pdev;
3197 struct mtkfb_device *fbdev = NULL;
3198 struct fb_info *fbi;
3199 int init_state;
3200 int r = 0;
3201 char *p = NULL;
3202 MSG_FUNC_ENTER();
3203
3204
3205 if(get_boot_mode() == META_BOOT || get_boot_mode() == FACTORY_BOOT
3206 || get_boot_mode() == ADVMETA_BOOT || get_boot_mode() == RECOVERY_BOOT)
3207 first_update = false;
3208
3209 MTKFB_MSG("%s, %s\n", __func__, saved_command_line);
3210 p = strstr(saved_command_line, "fps=");
3211 if(p == NULL){
3212 lcd_fps = 6000;
3213 pr_info("[FB driver]can not get fps from uboot\n");
3214 }
3215 else{
3216 p += 4;
3217 lcd_fps = simple_strtol(p, NULL, 10);
3218 if(0 == lcd_fps) lcd_fps = 6000;
3219 }
3220
3221 if(DISP_IsContextInited() == FALSE)
3222 {
3223 if(mtkfb_find_lcm_driver())
3224 {
3225 pr_info("%s, we have found the lcm - %s\n", __func__, mtkfb_lcm_name);
3226
3227 is_lcm_inited = TRUE;
3228 }
3229 else if(DISP_DetectDevice() != DISP_STATUS_OK)
3230 {
3231 pr_info("[mtkfb] detect device fail, maybe caused by the two reasons below:\n");
3232 pr_info("\t\t1.no lcm connected\n");
3233 pr_info("\t\t2.we can't support this lcm\n");
3234 }
3235 }
3236
3237 MTK_FB_XRES = DISP_GetScreenWidth();
3238 MTK_FB_YRES = DISP_GetScreenHeight();
3239 fb_xres_update = MTK_FB_XRES;
3240 fb_yres_update = MTK_FB_YRES;
3241
3242 MTKFB_MSG("[MTKFB] XRES=%d, YRES=%d\n", MTK_FB_XRES, MTK_FB_YRES);
3243
3244 MTK_FB_BPP = DISP_GetScreenBpp();
3245 MTK_FB_PAGES = DISP_GetPages();
3246
3247
3248 init_waitqueue_head(&screen_update_wq);
3249
3250 if(DISP_EsdRecoverCapbility())
3251 {
3252 esd_recovery_task = kthread_create(
3253 esd_recovery_kthread, NULL, "esd_recovery_kthread");
3254
3255 if (IS_ERR(esd_recovery_task)) {
3256 MTKFB_LOG("ESD recovery task create fail\n");
3257 }
3258 else {
3259 wake_up_process(esd_recovery_task);
3260 }
3261 }
3262 init_state = 0;
3263
3264 pdev = to_platform_device(dev);
3265 if (pdev->num_resources != 1) {
3266 PRNERR("probed for an unknown device\n");
3267 r = -ENODEV;
3268 goto cleanup;
3269 }
3270
3271 fbi = framebuffer_alloc(sizeof(struct mtkfb_device), dev);
3272 if (!fbi) {
3273 PRNERR("unable to allocate memory for device info\n");
3274 r = -ENOMEM;
3275 goto cleanup;
3276 }
3277 mtkfb_fbi = fbi;
3278
3279 fbdev = (struct mtkfb_device *)fbi->par;
3280 fbdev->fb_info = fbi;
3281 fbdev->dev = dev;
3282
3283 fbdev->layer_format = (MTK_FB_FORMAT*)vmalloc(sizeof(MTK_FB_FORMAT) * HW_OVERLAY_COUNT);
3284 if(!fbdev->layer_format){
3285 printk("[mtkfb.c FB driver] vmalloc failed, %d\n", __LINE__);
3286 r = -ENOMEM;
3287 goto cleanup;
3288 }
3289 memset(fbdev->layer_format, 0, sizeof(MTK_FB_FORMAT) * HW_OVERLAY_COUNT);
3290
3291 dev_set_drvdata(dev, fbdev);
3292
3293 init_state++; // 1
3294
3295 /* Allocate and initialize video frame buffer */
3296
3297 fbdev->fb_size_in_byte = MTK_FB_SIZEV;
3298 {
3299 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3300 ASSERT(DISP_GetVRamSize() <= (res->end - res->start + 1));
3301 disphal_enable_mmu(mtkfb_enable_mmu);
3302 disphal_allocate_fb(res, &fbdev->fb_pa_base, (unsigned int*)&fbdev->fb_va_base, &fb_pa);
3303 }
3304
3305 MTKFB_MSG("[FB Driver] fbdev->fb_pa_base = %x, fbdev->fb_va_base = %x\n", fbdev->fb_pa_base, (unsigned int)(fbdev->fb_va_base));
3306
3307 if (!fbdev->fb_va_base) {
3308 PRNERR("unable to allocate memory for frame buffer\n");
3309 r = -ENOMEM;
3310 goto cleanup;
3311 }
3312 init_state++; // 2
3313
3314 /* Initialize Display Driver PDD Layer */
3315 if (DISP_STATUS_OK != DISP_Init((DWORD)fbdev->fb_va_base,
3316 (DWORD)fb_pa,
3317 is_lcm_inited))
3318 {
3319 r = -1;
3320 goto cleanup;
3321 }
3322
3323 init_state++; // 3
3324#if defined(MTK_OVERLAY_ENGINE_SUPPORT)
3325 disp_ovl_engine_init();
3326
3327 Disp_Ovl_Engine_GetInstance(&mtkfb_instance,COUPLE_MODE);
3328 if (0xFF == mtkfb_instance)
3329 {
3330 PRNERR("allocate overlay engine fail \n");
3331 goto cleanup;
3332 }
3333
3334 disp_ovl_engine_indirect_link_overlay(fbdev->fb_va_base, fbdev->fb_pa_base);
3335#endif //defined(MTK_OVERLAY_ENGINE_SUPPORT)
3336
3337 /* Android native fence support */
3338 fbdev->update_ovls_wq = alloc_workqueue("mtkfb_ovls_wq",
3339 WQ_HIGHPRI | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
3340
3341 if (!fbdev->update_ovls_wq) {
3342 dev_err(dev, "failed to create update_ovls_wq\n");
3343 return -ENODEV;
3344 }
3345 mutex_init(&fbdev->timeline_lock);
3346 fbdev->timeline = sw_sync_timeline_create("mtkfb");
3347 fbdev->timeline_max = 0;
3348 INIT_LIST_HEAD(&fbdev->pending_configs);
3349 fbdev->ion_client = ion_client_create(g_ion_device, "mtkfb");
3350 if (IS_ERR(fbdev->ion_client)) {
3351 dev_err(dev, "failed to create ion client\n");
3352 return -ENODEV;
3353 }
3354
3355 /* Register to system */
3356
3357 r = mtkfb_fbinfo_init(fbi);
3358 if (r)
3359 goto cleanup;
3360 init_state++; // 4
3361
3362 r = mtkfb_register_sysfs(fbdev);
3363 if (r)
3364 goto cleanup;
3365 init_state++; // 5
3366
3367 r = register_framebuffer(fbi);
3368 if (r != 0) {
3369 PRNERR("register_framebuffer failed\n");
3370 goto cleanup;
3371 }
3372
3373 fbdev->state = MTKFB_ACTIVE;
3374
3375 /********************************************/
3376
3377 mtkfb_fb_565_to_8888(fbi);
3378
3379 /********************************************/
3380 MSG(INFO, "MTK framebuffer initialized vram=%lu\n", fbdev->fb_size_in_byte);
3381
3382 MSG_FUNC_LEAVE();
3383 return 0;
3384
3385cleanup:
3386 mtkfb_free_resources(fbdev, init_state);
3387
3388 MSG_FUNC_LEAVE();
3389 return r;
3390}
3391
3392/* Called when the device is being detached from the driver */
3393static int mtkfb_remove(struct device *dev)
3394{
3395 struct mtkfb_device *fbdev = dev_get_drvdata(dev);
3396 enum mtkfb_state saved_state = fbdev->state;
3397
3398 MSG_FUNC_ENTER();
3399 /* FIXME: wait till completion of pending events */
3400
3401 fbdev->state = MTKFB_DISABLED;
3402 mtkfb_free_resources(fbdev, saved_state);
3403
3404 MSG_FUNC_LEAVE();
3405 return 0;
3406}
3407
3408/* PM suspend */
3409static int mtkfb_suspend(struct device *pdev, pm_message_t mesg)
3410{
3411 NOT_REFERENCED(pdev);
3412 MSG_FUNC_ENTER();
3413 MTKFB_LOG("[FB Driver] mtkfb_suspend(): 0x%x\n", mesg.event);
3414 MSG_FUNC_LEAVE();
3415 return 0;
3416}
3417bool mtkfb_is_suspend(void)
3418{
3419 return is_early_suspended;
3420}
3421
3422EXPORT_SYMBOL(mtkfb_is_suspend);
3423
3424static void mtkfb_shutdown(struct device *pdev)
3425{
3426 MTKFB_LOG("[FB Driver] mtkfb_shutdown()\n");
3427 mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, LED_OFF);
3428 if (!lcd_fps)
3429 msleep(30);
3430 else
3431 msleep(2*100000/lcd_fps); // Delay 2 frames.
3432
3433 if(is_early_suspended){
3434 MTKFB_LOG("mtkfb has been power off\n");
3435 return;
3436 }
3437
3438 if (down_interruptible(&sem_early_suspend)) {
3439 pr_info("[FB Driver] can't get semaphore in mtkfb_shutdown()\n");
3440 return;
3441 }
3442 sem_early_suspend_cnt--;
3443
3444 is_early_suspended = TRUE;
4b9e9796
S
3445
3446 /* [FIXBUG]-Mod-BEGIN by TCTSZ.leo.guo, PR#1000254 2015/05/18, Fix FB suspend/resume DSI cause recovery reboot failed issue*/
6fa3eb70 3447 DISP_PrepareSuspend();
4b9e9796
S
3448 if(wait_event_interruptible_timeout(_dsi_wait_vm_done_queue, !_IsEngineBusy(), HZ/10) == 0)
3449 pr_err("[FB Driver] Wait disp finished timeout in early_suspend\n");
3450 /* [FIXBUG]-Mod-END by TCTSZ.leo.guo, 2015/05/18*/
6fa3eb70 3451
6fa3eb70
S
3452 DISP_CHECK_RET(DISP_PanelEnable(FALSE));
3453 DISP_CHECK_RET(DISP_PowerEnable(FALSE));
3454
3455 DISP_CHECK_RET(DISP_PauseVsync(TRUE));
3456 sem_early_suspend_cnt++;
3457 up(&sem_early_suspend);
3458
3459 MTKFB_LOG("[FB Driver] leave mtkfb_shutdown\n");
3460}
3461
3462void mtkfb_clear_lcm(void)
3463{
3464 int i;
3465 unsigned int layer_status[DDP_OVL_LAYER_MUN]={0};
3466 mutex_lock(&OverlaySettingMutex);
3467 for(i=0;i<DDP_OVL_LAYER_MUN;i++)
3468 {
3469 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
3470 // TODO save status
3471 {
3472 struct fb_overlay_layer layer= {0};
3473
3474 layer_status[i] = disp_ovl_engine.Instance[mtkfb_instance].cached_layer_config[i].layer_en;
3475 layer.layer_id = i;
3476 Disp_Ovl_Engine_Get_layer_info(mtkfb_instance, &layer);
3477 layer.layer_enable = 0;
3478 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, &layer);
3479
3480 }
3481 #else
3482 layer_status[i] = cached_layer_config[i].layer_en;
3483 cached_layer_config[i].layer_en = 0;
3484 cached_layer_config[i].isDirty = 1;
3485 #endif
3486 }
3487 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
3488 atomic_set(&OverlaySettingDirtyFlag, 1);
3489 atomic_set(&OverlaySettingApplied, 0);
3490 #endif
3491 mutex_unlock(&OverlaySettingMutex);
3492
3493 DISP_CHECK_RET(DISP_UpdateScreen(0, 0, fb_xres_update, fb_yres_update));
3494 DISP_CHECK_RET(DISP_UpdateScreen(0, 0, fb_xres_update, fb_yres_update));
3495
3496 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
3497 Disp_Ovl_Engine_Wait_Overlay_Complete(mtkfb_instance, 1000);
3498 #endif
3499 if (!lcd_fps)
3500 msleep(60);
3501 else
3502 msleep(400000/lcd_fps);
3503 DISP_WaitForLCDNotBusy();
3504
3505 mutex_lock(&OverlaySettingMutex);
3506 for(i=0;i<DDP_OVL_LAYER_MUN;i++)
3507 {
3508 #if defined(MTK_OVERLAY_ENGINE_SUPPORT)
3509 {
3510 struct fb_overlay_layer layer= {0};
3511 layer.layer_id = i;
3512 Disp_Ovl_Engine_Get_layer_info(mtkfb_instance, &layer);
3513 layer.layer_enable = layer_status[i];
3514 Disp_Ovl_Engine_Set_layer_info(mtkfb_instance, &layer);
3515 }
3516 #else
3517 cached_layer_config[i].layer_en = layer_status[i];
3518 cached_layer_config[i].isDirty = 1;
3519 #endif
3520 }
3521 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
3522 atomic_set(&OverlaySettingDirtyFlag, 1);
3523 atomic_set(&OverlaySettingApplied, 0);
3524 #endif
3525 mutex_unlock(&OverlaySettingMutex);
3526}
3527
3528
3529#ifdef CONFIG_HAS_EARLYSUSPEND
3530static void mtkfb_early_suspend(struct early_suspend *h)
3531{
3532 MSG_FUNC_ENTER();
3533
3534 pr_info("[FB Driver] enter early_suspend\n");
3535
3536
3537 mutex_lock(&ScreenCaptureMutex);
3538
3539
3540 mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, LED_OFF);
3541 if (down_interruptible(&sem_early_suspend)) {
3542 pr_info("[FB Driver] can't get semaphore in mtkfb_early_suspend()\n");
3543 mutex_unlock(&ScreenCaptureMutex);
3544 return;
3545 }
3546
3547 sem_early_suspend_cnt--;
3548
3549 if(is_early_suspended){
3550 is_early_suspended = TRUE;
3551 sem_early_suspend_cnt++;
3552 up(&sem_early_suspend);
3553 MTKFB_LOG("[FB driver] has been suspended\n");
3554 mutex_unlock(&ScreenCaptureMutex);
3555 return;
3556 }
3557
3558 MMProfileLog(MTKFB_MMP_Events.EarlySuspend, MMProfileFlagStart);
3559 is_early_suspended = TRUE;
3560
3561 if (!lcd_fps)
3562 msleep(30);
3563 else
3564 msleep(2*100000/lcd_fps); // Delay 2 frames.
3565
3566 DISP_PrepareSuspend();
3567
3568 // Wait for disp finished.
3569 if (wait_event_interruptible_timeout(_dsi_wait_vm_done_queue, !_IsEngineBusy(), HZ/10) == 0)
3570 {
3571 pr_info("[FB Driver] Wait disp finished timeout in early_suspend\n");
3572 }
3573 DISP_CHECK_RET(DISP_PanelEnable(FALSE));
3574 DISP_CHECK_RET(DISP_PowerEnable(FALSE));
3575 DISP_CHECK_RET(DISP_PauseVsync(TRUE));
3576
3577 disp_path_clock_off("mtkfb");
3578
3579 sem_early_suspend_cnt++;
3580 up(&sem_early_suspend);
3581 mutex_unlock(&ScreenCaptureMutex);
3582
3583 /* Here we should flush composition workqueue but there's no
3584 * clean and easy way to get the device handle. Because early suspend
3585 * struct is not a member of fbdev, and global variables are used instead,
3586 * we can't just use container_of ...
3587 * As we flush in blank/POWEROFF IOCTL from HWC, this is not a practical issue.
3588 *
3589 * flush_workqueue(((struct mtkfb_device *)dev)->update_ovls_wq);
3590 */
3591
3592 pr_info("[FB Driver] leave early_suspend\n");
3593
3594 MSG_FUNC_LEAVE();
3595}
3596#endif
3597
3598/* PM resume */
3599static int mtkfb_resume(struct device *pdev)
3600{
3601 NOT_REFERENCED(pdev);
3602 MSG_FUNC_ENTER();
3603 MTKFB_LOG("[FB Driver] mtkfb_resume()\n");
3604 MSG_FUNC_LEAVE();
3605 return 0;
3606}
3607
3608#ifdef CONFIG_HAS_EARLYSUSPEND
3609static void mtkfb_late_resume(struct early_suspend *h)
3610{
3611 MSG_FUNC_ENTER();
3612
3613 pr_info("[FB Driver] enter late_resume\n");
3614
3615 mutex_lock(&ScreenCaptureMutex);
3616 if (down_interruptible(&sem_early_suspend)) {
3617 pr_info("[FB Driver] can't get semaphore in mtkfb_late_resume()\n");
3618 mutex_unlock(&ScreenCaptureMutex);
3619 return;
3620 }
3621 sem_early_suspend_cnt--;
3622 if(!is_early_suspended){
3623 is_early_suspended = false;
3624 sem_early_suspend_cnt++;
3625 up(&sem_early_suspend);
3626 MTKFB_LOG("[FB driver] has been resumed\n");
3627 mutex_unlock(&ScreenCaptureMutex);
3628 return;
3629 }
3630
3631 MMProfileLog(MTKFB_MMP_Events.EarlySuspend, MMProfileFlagEnd);
3632 if (is_ipoh_bootup)
3633 {
3634 atomic_set(&OverlaySettingDirtyFlag, 0);
3635 disp_path_clock_on("ipoh_mtkfb");
3636 }
3637 else
3638 disp_path_clock_on("mtkfb");
3639 pr_info("[FB LR] 1\n");
3640 DISP_CHECK_RET(DISP_PauseVsync(FALSE));
3641 pr_info("[FB LR] 2\n");
3642 DISP_CHECK_RET(DISP_PowerEnable(TRUE));
3643 pr_info("[FB LR] 3\n");
3644 DISP_CHECK_RET(DISP_PanelEnable(TRUE));
3645 pr_info("[FB LR] 4\n");
3646
3647 is_early_suspended = FALSE;
3648
3649 if (is_ipoh_bootup)
3650 {
3651 DISP_StartConfigUpdate();
3652 is_ipoh_bootup =false;
3653 }
3654 else
3655 {
3656 mtkfb_clear_lcm();
3657 }
3658
3659 sem_early_suspend_cnt++;
3660 up(&sem_early_suspend);
3661 mutex_unlock(&ScreenCaptureMutex);
3662
3663 if(BL_set_level_resume){
3664 mtkfb_set_backlight_level(BL_level);
3665 BL_set_level_resume = FALSE;
3666 }
3667#if defined(MTK_OVERLAY_ENGINE_SUPPORT)
3668#ifdef CONFIG_MTK_LEDS
3669 if (!disp_ovl_engine.bCouple)
3670 mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, LED_HALF);
3671#endif
3672#endif
3673 pr_info("[FB Driver] leave late_resume\n");
3674
3675 MSG_FUNC_LEAVE();
3676}
3677#endif
3678
3679/*---------------------------------------------------------------------------*/
3680#ifdef CONFIG_PM
3681/*---------------------------------------------------------------------------*/
3682int mtkfb_pm_suspend(struct device *device)
3683{
3684 //pr_debug("calling %s()\n", __func__);
3685
3686 struct platform_device *pdev = to_platform_device(device);
3687 BUG_ON(pdev == NULL);
3688
3689 return mtkfb_suspend((struct device *)pdev, PMSG_SUSPEND);
3690}
3691
3692int mtkfb_pm_resume(struct device *device)
3693{
3694 //pr_debug("calling %s()\n", __func__);
3695
3696 struct platform_device *pdev = to_platform_device(device);
3697 BUG_ON(pdev == NULL);
3698
3699 return mtkfb_resume((struct device *)pdev);
3700}
3701
3702#ifdef DEFAULT_MMP_ENABLE
3703void MMProfileStart(int start);
3704#endif
3705int mtkfb_pm_restore_noirq(struct device *device)
3706{
3707
3708#ifdef DEFAULT_MMP_ENABLE
3709 MMProfileStart(0);
3710 MMProfileStart(1);
3711#endif
3712
3713 disphal_pm_restore_noirq(device);
3714
3715 is_ipoh_bootup = true;
3716 return 0;
3717
3718}
3719/*---------------------------------------------------------------------------*/
3720#else /*CONFIG_PM*/
3721/*---------------------------------------------------------------------------*/
3722#define mtkfb_pm_suspend NULL
3723#define mtkfb_pm_resume NULL
3724#define mtkfb_pm_restore_noirq NULL
3725/*---------------------------------------------------------------------------*/
3726#endif /*CONFIG_PM*/
3727/*---------------------------------------------------------------------------*/
3728struct dev_pm_ops mtkfb_pm_ops = {
3729 .suspend = mtkfb_pm_suspend,
3730 .resume = mtkfb_pm_resume,
3731 .freeze = mtkfb_pm_suspend,
3732 .thaw = mtkfb_pm_resume,
3733 .poweroff = mtkfb_pm_suspend,
3734 .restore = mtkfb_pm_resume,
3735 .restore_noirq = mtkfb_pm_restore_noirq,
3736};
3737
3738static struct platform_driver mtkfb_driver =
3739{
3740 .driver = {
3741 .name = MTKFB_DRIVER,
3742#ifdef CONFIG_PM
3743 .pm = &mtkfb_pm_ops,
3744#endif
3745 .bus = &platform_bus_type,
3746 .probe = mtkfb_probe,
3747 .remove = mtkfb_remove,
3748 .suspend = mtkfb_suspend,
3749 .resume = mtkfb_resume,
3750 .shutdown = mtkfb_shutdown,
3751 },
3752};
3753
3754#ifdef CONFIG_HAS_EARLYSUSPEND
3755static struct early_suspend mtkfb_early_suspend_handler =
3756{
3757 .level = EARLY_SUSPEND_LEVEL_DISABLE_FB,
3758 .suspend = mtkfb_early_suspend,
3759 .resume = mtkfb_late_resume,
3760};
3761#endif
3762
3763#ifdef DEFAULT_MMP_ENABLE
3764void MMProfileEnable(int enable);
3765void MMProfileStart(int start);
3766void init_mtkfb_mmp_events(void);
3767void init_ddp_mmp_events(void);
3768#endif
3769
3770/* Register both the driver and the device */
3771int __init mtkfb_init(void)
3772{
3773 int r = 0;
3774
3775 MSG_FUNC_ENTER();
3776
3777#ifdef DEFAULT_MMP_ENABLE
3778 MMProfileEnable(1);
3779 init_mtkfb_mmp_events();
3780 init_ddp_mmp_events();
3781 MMProfileStart(0);
3782 MMProfileStart(1);
3783#endif
3784
3785 /* Register the driver with LDM */
3786
3787 if (platform_driver_register(&mtkfb_driver)) {
3788 PRNERR("failed to register mtkfb driver\n");
3789 r = -ENODEV;
3790 goto exit;
3791 }
3792
3793#ifdef CONFIG_HAS_EARLYSUSPEND
3794 register_early_suspend(&mtkfb_early_suspend_handler);
3795#endif
3796
3797 DBG_Init();
3798
3799exit:
3800 MSG_FUNC_LEAVE();
3801 return r;
3802}
3803
3804
3805static void __exit mtkfb_cleanup(void)
3806{
3807 MSG_FUNC_ENTER();
3808
3809 platform_driver_unregister(&mtkfb_driver);
3810
3811#ifdef CONFIG_HAS_EARLYSUSPEND
3812 unregister_early_suspend(&mtkfb_early_suspend_handler);
3813#endif
3814
3815 kthread_stop(screen_update_task);
3816 if(esd_recovery_task)
3817 kthread_stop(esd_recovery_task);
3818
3819 DBG_Deinit();
3820
3821 MSG_FUNC_LEAVE();
3822}
3823
3824late_initcall(mtkfb_init);
3825module_exit(mtkfb_cleanup);
3826
3827MODULE_DESCRIPTION("MEDIATEK framebuffer driver");
3828MODULE_AUTHOR("Zaikuo Wang <zaikuo.wang@mediatek.com>");
3829MODULE_LICENSE("GPL");