import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / video / mt8127 / mt8127 / disp_drv_dsi.c
CommitLineData
6fa3eb70
S
1#include <linux/delay.h>
2#include <linux/kernel.h>
3#include <linux/string.h>
4#include <linux/semaphore.h>
5#include "disp_drv_log.h"
6#include <mach/mt_boot.h>
7#include "disp_drv_platform.h"
8#include "lcd_drv.h"
9#include "dsi_drv.h"
10#include "dpi_drv.h"
11
12#include "lcm_drv.h"
13#include "disp_hal.h"
14#include "debug.h"
15#include "mach/mt_spm_idle.h"
16#define ALIGN_TO(x, n) \
17 (((x) + ((n) - 1)) & ~((n) - 1))
18
19#define MTK_FB_ALIGNMENT 16
20// ---------------------------------------------------------------------------
21// Private Variables
22// ---------------------------------------------------------------------------
23static UINT32 dsiTmpBufBpp = 3;
24extern LCM_DRIVER *lcm_drv;
25extern LCM_PARAMS *lcm_params;
26extern unsigned int is_video_mode_running;
27extern BOOL DISP_IsDecoupleMode(void);
28typedef struct
29{
30 UINT32 pa;
31 UINT32 pitchInBytes;
32} TempBuffer;
33
34#ifndef MT65XX_NEW_DISP
35static TempBuffer s_tmpBuffers[3];
36#endif
37static bool needStartDSI = false;
38
39// ---------------------------------------------------------------------------
40// Private Functions
41// ---------------------------------------------------------------------------
42
43static void init_lcd_te_control(void)
44{
45 const LCM_DBI_PARAMS *dbi = &(lcm_params->dbi);
46
47 LCD_CHECK_RET(LCD_TE_Enable(FALSE));
48#ifdef BUILD_UBOOT
49 {
50 extern BOOTMODE g_boot_mode;
51 printf("boot_mode = %d\n",g_boot_mode);
52 if(g_boot_mode == META_BOOT)
53 return;
54 }
55#endif
56 if (LCM_DBI_TE_MODE_DISABLED == dbi->te_mode) {
57 LCD_CHECK_RET(LCD_TE_Enable(FALSE));
58 return;
59 }
60
61 if (LCM_DBI_TE_MODE_VSYNC_ONLY == dbi->te_mode) {
62 LCD_CHECK_RET(LCD_TE_SetMode(LCD_TE_MODE_VSYNC_ONLY));
63 } else if (LCM_DBI_TE_MODE_VSYNC_OR_HSYNC == dbi->te_mode) {
64 LCD_CHECK_RET(LCD_TE_SetMode(LCD_TE_MODE_VSYNC_OR_HSYNC));
65 LCD_CHECK_RET(LCD_TE_ConfigVHSyncMode(dbi->te_hs_delay_cnt,
66 dbi->te_vs_width_cnt,
67 (LCD_TE_VS_WIDTH_CNT_DIV)dbi->te_vs_width_cnt_div));
68 } else ASSERT(0);
69
70 LCD_CHECK_RET(LCD_TE_SetEdgePolarity(dbi->te_edge_polarity));
71 LCD_CHECK_RET(LCD_TE_Enable(TRUE));
72}
73static __inline LCD_IF_WIDTH to_lcd_if_width(LCM_DBI_DATA_WIDTH data_width)
74{
75 switch(data_width)
76 {
77 case LCM_DBI_DATA_WIDTH_8BITS : return LCD_IF_WIDTH_8_BITS;
78 case LCM_DBI_DATA_WIDTH_9BITS : return LCD_IF_WIDTH_9_BITS;
79 case LCM_DBI_DATA_WIDTH_16BITS : return LCD_IF_WIDTH_16_BITS;
80 case LCM_DBI_DATA_WIDTH_18BITS : return LCD_IF_WIDTH_18_BITS;
81 case LCM_DBI_DATA_WIDTH_24BITS : return LCD_IF_WIDTH_24_BITS;
82 default : ASSERT(0);
83 }
84 return LCD_IF_WIDTH_18_BITS;
85}
86
87static BOOL disp_drv_dsi_init_context(void)
88{
89 if (lcm_drv != NULL && lcm_params != NULL){
90 return TRUE;
91 }
92
93 if (NULL == lcm_drv) {
94 return FALSE;
95 }
96
97 lcm_drv->get_params(lcm_params);
98
99
100 return TRUE;
101}
102
103static void dsi_IsGlitchWorkaroundEnabled(void)
104{
105 // get chip version first, 82 E2 has fixed glitch bug
106 CHIP_SW_VER ver = mt_get_chip_sw_ver();
107 // check whether chip version is E2 or later
108 if(ver >= CHIP_SW_VER_02 )
109 {
110 printk("this is 6582 E2 chip, disable glitch detect!\n");
111 lcm_params->dsi.compatibility_for_nvk = 0;
112 }
113}
114
115void init_dsi(BOOL isDsiPoweredOn)
116{
117 //xuecheng's workaround for 82 dsi video mode
118 if (lcm_params->dsi.mode == CMD_MODE)
119 {
120 DSI_PHY_clk_setting(lcm_params);
121 }
122
123 // DISP_LOG_PRINT(ANDROID_LOG_INFO, "DSI", "%s, line:%d\n", __func__, __LINE__);
124 DSI_CHECK_RET(DSI_Init(isDsiPoweredOn));
125 dsi_IsGlitchWorkaroundEnabled();
126
127 if(0 < lcm_params->dsi.compatibility_for_nvk)
128 {
129 DSI_CHECK_RET(DSI_TXRX_Control(TRUE, //cksm_en
130 TRUE, //ecc_en
131 lcm_params->dsi.LANE_NUM, //ecc_en
132 0, //vc_num
133 FALSE, //null_packet_en
134 FALSE, //err_correction_en
135 FALSE, //dis_eotp_en
136 FALSE,
137 0)); //max_return_size
138// DSI_set_noncont_clk(false,0);
139// DSI_Detect_glitch_enable(true);
140 }
141 else
142 {
143 DSI_CHECK_RET(DSI_TXRX_Control(TRUE, //cksm_en
144 TRUE, //ecc_en
145 lcm_params->dsi.LANE_NUM, //ecc_en
146 0, //vc_num
147 FALSE, //null_packet_en
148 FALSE, //err_correction_en
149 FALSE, //dis_eotp_en
150 (BOOL)(1 - lcm_params->dsi.cont_clock),
151 0)); //max_return_size
152 }
153
154 //initialize DSI_PHY
155 DSI_PHY_clk_switch(TRUE);
156 DSI_PHY_TIMCONFIG(lcm_params);
157
158 DSI_CHECK_RET(DSI_PS_Control(lcm_params->dsi.PS, lcm_params->height, lcm_params->width * dsiTmpBufBpp));
159
160 if(lcm_params->dsi.mode != CMD_MODE)
161 {
162 DSI_Config_VDO_Timing(lcm_params);
163 DSI_Set_VM_CMD(lcm_params);
164// if(0 < lcm_params->dsi.compatibility_for_nvk)
165// DSI_Config_VDO_FRM_Mode();
166 }
167
168 DSI_CHECK_RET(DSI_enable_MIPI_txio(TRUE));
169
170
171}
172
173#if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
174// ---------------------------------------------------------------------------
175// DBI Display Driver Public Functions
176// ---------------------------------------------------------------------------
177static DISP_STATUS dsi_config_ddp(UINT32 fbPA)
178{
179 struct disp_path_config_struct config = {0};
180 if (DISP_IsDecoupleMode()) {
181 config.srcModule = DISP_MODULE_RDMA0;
182 } else {
183 config.srcModule = DISP_MODULE_OVL;
184 }
185
186 config.bgROI.x = 0;
187 config.bgROI.y = 0;
188 config.bgROI.width = lcm_params->width;
189 config.bgROI.height = lcm_params->height;
190 config.bgColor = 0x0; // background color
191
192 config.pitch = lcm_params->width*2;
193 config.srcROI.x = 0;config.srcROI.y = 0;
194 config.srcROI.height= lcm_params->height;
195 config.srcROI.width= lcm_params->width;
196 config.ovl_config.source = OVL_LAYER_SOURCE_MEM;
197
198 if(lcm_params->dsi.mode != CMD_MODE)
199 {
200 config.ovl_config.layer = DDP_OVL_LAYER_MUN-1;
201 config.ovl_config.layer_en = 0;
202 //disp_path_get_mutex();
203 disp_path_config_layer(&config.ovl_config);
204 //disp_path_release_mutex();
205 //disp_path_wait_reg_update();
206 }
207#if 1
208 // Disable LK UI layer (Layer2)
209 if(lcm_params->dsi.mode != CMD_MODE)
210 {
211 config.ovl_config.layer = DDP_OVL_LAYER_MUN-1-1;
212 config.ovl_config.layer_en = 0;
213 //disp_path_get_mutex();
214 disp_path_config_layer(&config.ovl_config);
215 //disp_path_release_mutex();
216 //disp_path_wait_reg_update();
217 }
218#endif
219 config.ovl_config.layer = DDP_OVL_LAYER_MUN-1;
220 config.ovl_config.layer_en = 1;
221 config.ovl_config.fmt = eRGB565;
222 config.ovl_config.addr = fbPA;
223 config.ovl_config.source = OVL_LAYER_SOURCE_MEM;
224 config.ovl_config.src_x = 0;
225 config.ovl_config.src_y = 0;
226 config.ovl_config.dst_x = 0; // ROI
227 config.ovl_config.dst_y = 0;
228 config.ovl_config.dst_w = lcm_params->width;
229 config.ovl_config.dst_h = lcm_params->height;
230 config.ovl_config.src_pitch = ALIGN_TO(lcm_params->width, MTK_FB_ALIGNMENT)*2; //pixel number
231 config.ovl_config.keyEn = 0;
232 config.ovl_config.key = 0xFF; // color key
233 config.ovl_config.aen = 0; // alpha enable
234 config.ovl_config.alpha = 0;
235
236 LCD_LayerSetAddress(DDP_OVL_LAYER_MUN-1, fbPA);
237 LCD_LayerSetFormat(DDP_OVL_LAYER_MUN-1, LCD_LAYER_FORMAT_RGB565);
238 LCD_LayerSetOffset(DDP_OVL_LAYER_MUN-1, 0, 0);
239 LCD_LayerSetSize(DDP_OVL_LAYER_MUN-1,lcm_params->width,lcm_params->height);
240 LCD_LayerSetPitch(DDP_OVL_LAYER_MUN-1, ALIGN_TO(lcm_params->width, MTK_FB_ALIGNMENT) * 2);
241 LCD_LayerEnable(DDP_OVL_LAYER_MUN-1, TRUE);
242
243 if(lcm_params->dsi.mode == CMD_MODE)
244 config.dstModule = DISP_MODULE_DSI_CMD;// DISP_MODULE_WDMA1
245 else
246 config.dstModule = DISP_MODULE_DSI_VDO;// DISP_MODULE_WDMA1
247 config.outFormat = RDMA_OUTPUT_FORMAT_ARGB;
248 disp_path_config(&config);
249
250 if(lcm_params->dsi.mode != CMD_MODE)
251 {
252 //DSI_Wait_VDO_Idle();
253 disp_path_get_mutex();
254 }
255
256 // Config FB_Layer port to be physical.
257 {
258 M4U_PORT_STRUCT portStruct;
259
260 portStruct.ePortID = DISP_OVL_0; //hardware port ID, defined in M4U_PORT_ID_ENUM
261 portStruct.Virtuality = 1;
262 portStruct.Security = 0;
263 portStruct.domain = 3; //domain : 0 1 2 3
264 portStruct.Distance = 1;
265 portStruct.Direction = 0;
266 m4u_config_port(&portStruct);
267 }
268
269 if(lcm_params->dsi.mode != CMD_MODE)
270 {
271 disp_path_release_mutex();
272 //if(1 == lcm_params->dsi.ufoe_enable)
273 // UFOE_Start();
274 //DSI_Start();
275 }
276 printk("%s, config done\n", __func__);
277 return DISP_STATUS_OK;
278}
279#endif
280
281bool DDMS_capturing=0;
282
283static DISP_STATUS dsi_init(UINT32 fbVA, UINT32 fbPA, BOOL isLcmInited)
284{
285 if (!disp_drv_dsi_init_context())
286 return DISP_STATUS_NOT_IMPLEMENTED;
287
288 if(lcm_params->dsi.mode == CMD_MODE)
289 {
290 init_dsi(isLcmInited);
291 MASKREG32(DSI_BASE + 0x10, 0x2, 0x2);
292 if (NULL != lcm_drv->init && !isLcmInited)
293 {
294 lcm_drv->init();
295 DSI_LP_Reset();
296 }
297
298 DSI_clk_HS_mode(1);
299
300 DSI_SetMode(lcm_params->dsi.mode);
301 }
302 else {
303 if (!isLcmInited)
304 {
305 //DSI_SetMode(0);
306 //mdelay(100);
307 //DSI_Stop();
308 }
309 else
310 {
311 is_video_mode_running = true;
312 }
313
314 init_dsi(isLcmInited);
315
316 MASKREG32(DSI_BASE + 0x10, 0x2, 0x2);
317 if (NULL != lcm_drv->init && !isLcmInited)
318 {
319 lcm_drv->init();
320 DSI_LP_Reset();
321 }
322
323 DSI_SetMode(lcm_params->dsi.mode);
324 }
325
326 #if !defined(MTK_OVERLAY_ENGINE_SUPPORT)
327 RDMASetTargetLine(0, lcm_params->height*4/5);
328 dsi_config_ddp(fbPA);
329 #endif
330
331 DPI_PowerOn();
332 DPI_PowerOff();
333#ifdef SPM_SODI_ENABLED
334 if(lcm_params->dsi.mode == CMD_MODE)
335 {
336 spm_sodi_lcm_video_mode(FALSE);
337 }
338 else
339 {
340 spm_sodi_lcm_video_mode(TRUE);
341 }
342#endif
343 return DISP_STATUS_OK;
344}
345
346
347// protected by sem_early_suspend, sem_update_screen
348static DISP_STATUS dsi_enable_power(BOOL enable)
349{
350 disp_drv_dsi_init_context();
351
352 if(lcm_params->dsi.mode == CMD_MODE)
353 {
354 if (enable)
355 {
356 // enable MMSYS CG
357 DSI_CHECK_RET(DSI_PowerOn());
358
359 // initialize clock setting
360 DSI_PHY_clk_setting(lcm_params);
361
362 // restore dsi register
363 DSI_CHECK_RET(DSI_RestoreRegisters());
364
365 // enable sleep-out mode
366 DSI_CHECK_RET(DSI_SleepOut());
367
368 // enter HS mode
369 DSI_PHY_clk_switch(1);
370
371 // enter wakeup
372 DSI_CHECK_RET(DSI_Wakeup());
373
374 // enable clock
375 DSI_CHECK_RET(DSI_EnableClk());
376
377 DSI_CHECK_RET(DSI_enable_MIPI_txio(TRUE));
378 DSI_Reset();
379 }
380 else
381 {
382 // backup dsi register
383 DSI_CHECK_RET(DSI_WaitForNotBusy());
384 DSI_CHECK_RET(DSI_BackupRegisters());
385
386 // enter ULPS mode
387 DSI_clk_ULP_mode(1);
388 DSI_lane0_ULP_mode(1);
389 DSI_clk_HS_mode(0);
390 // disable clock
391 DSI_CHECK_RET(DSI_DisableClk());
392 DSI_CHECK_RET(DSI_PowerOff());
393
394 // disable mipi pll
395 DSI_PHY_clk_switch(0);
396
397 // Switch bus to GPIO, then power level will be decided by GPIO setting.
398 DSI_CHECK_RET(DSI_enable_MIPI_txio(FALSE));
399 }
400 }
401 else
402 {
403 if (enable)
404 {
405 // enable MMSYS CG
406 DSI_CHECK_RET(DSI_PowerOn());
407
408 // initialize clock setting
409 DSI_PHY_clk_setting(lcm_params);
410
411 // restore dsi register
412 DSI_CHECK_RET(DSI_RestoreRegisters());
413
414 // enable sleep-out mode
415 DSI_CHECK_RET(DSI_SleepOut());
416
417 // enter HS mode
418 DSI_PHY_clk_switch(1);
419
420 // enter wakeup
421 DSI_CHECK_RET(DSI_Wakeup());
422 DSI_clk_HS_mode(0);
423 // enable clock
424 DSI_CHECK_RET(DSI_EnableClk());
425
426 DSI_CHECK_RET(DSI_enable_MIPI_txio(TRUE));
427 DSI_Reset();
428 needStartDSI = true;
429 }
430 else
431 {
432 is_video_mode_running = false;
433
434 // backup dsi register
435 DSI_CHECK_RET(DSI_WaitForNotBusy());
436 DSI_CHECK_RET(DSI_BackupRegisters());
437
438 // enter ULPS mode
439 DSI_clk_ULP_mode(1);
440 DSI_lane0_ULP_mode(1);
441
442 // disable clock
443 DSI_CHECK_RET(DSI_DisableClk());
444 DSI_CHECK_RET(DSI_PowerOff());
445
446 // disable mipi pll
447 DSI_PHY_clk_switch(0);
448
449 // Switch bus to GPIO, then power level will be decided by GPIO setting.
450 DSI_CHECK_RET(DSI_enable_MIPI_txio(FALSE));
451 }
452 }
453
454 return DISP_STATUS_OK;
455}
456
457
458// protected by sem_flipping, sem_early_suspend, sem_overlay_buffer, sem_update_screen
459static DISP_STATUS dsi_update_screen(BOOL isMuextLocked)
460{
461 disp_drv_dsi_init_context();
462
463 DSI_CHECK_RET(DSI_enable_MIPI_txio(TRUE));
464
465 //DSI_CHECK_RET(DSI_handle_TE());
466
467 DSI_SetMode(lcm_params->dsi.mode);
468#ifndef MT65XX_NEW_DISP
469 LCD_CHECK_RET(LCD_StartTransfer(FALSE));
470#endif
471 if (lcm_params->type==LCM_TYPE_DSI && lcm_params->dsi.mode == CMD_MODE && !DDMS_capturing) {
472// DSI_clk_HS_mode(1);
473#ifdef MT65XX_NEW_DISP
474 DSI_CHECK_RET(DSI_StartTransfer(isMuextLocked));
475#else
476 DSI_CHECK_RET(DSI_Start());
477#endif
478 }
479 else if (lcm_params->type==LCM_TYPE_DSI && lcm_params->dsi.mode != CMD_MODE && !DDMS_capturing)
480 {
481 DSI_clk_HS_mode(1);
482 DSI_CHECK_RET(DSI_StartTransfer(isMuextLocked));
483#ifndef BUILD_UBOOT
484 is_video_mode_running = true;
485#ifndef MT65XX_NEW_DISP
486 if(lcm_params->dsi.noncont_clock)
487 DSI_set_noncont_clk(true, lcm_params->dsi.noncont_clock_period);
488
489 if(lcm_params->dsi.lcm_int_te_monitor)
490 DSI_set_int_TE(true, lcm_params->dsi.lcm_int_te_period);
491#endif
492#endif
493 }
494
495 if (DDMS_capturing)
496 DISP_LOG_PRINT(ANDROID_LOG_INFO, "DSI", "[DISP] kernel - dsi_update_screen. DDMS is capturing. Skip one frame. \n");
497
498 return DISP_STATUS_OK;
499}
500
501
502static UINT32 dsi_get_working_buffer_size(void)
503{
504 disp_drv_dsi_init_context();
505
506 if(lcm_params->dsi.mode != CMD_MODE) {
507
508 return
509 lcm_params->width *
510 lcm_params->height *
511 dsiTmpBufBpp *
512 lcm_params->dsi.intermediat_buffer_num;
513 }
514
515 return 0;
516}
517
518static UINT32 dsi_get_working_buffer_bpp(void)
519{
520 disp_drv_dsi_init_context();
521
522 if(lcm_params->dsi.mode != CMD_MODE)
523 {
524 return dsiTmpBufBpp;
525 }
526
527 return 0;
528}
529
530static PANEL_COLOR_FORMAT dsi_get_panel_color_format(void)
531{
532 disp_drv_dsi_init_context();
533
534 {
535
536 switch(lcm_params->dsi.data_format.format)
537 {
538 case LCM_DSI_FORMAT_RGB565 : return PANEL_COLOR_FORMAT_RGB565;
539 case LCM_DSI_FORMAT_RGB666 : return PANEL_COLOR_FORMAT_RGB666;
540 case LCM_DSI_FORMAT_RGB888 : return PANEL_COLOR_FORMAT_RGB888;
541 default : ASSERT(0);
542 }
543
544 }
545}
546
547static UINT32 dsi_get_dithering_bpp(void)
548{
549 return PANEL_COLOR_FORMAT_TO_BPP(dsi_get_panel_color_format());
550}
551
552
553// protected by sem_early_suspend
554DISP_STATUS dsi_capture_framebuffer(UINT32 pvbuf, UINT32 bpp)
555{
556 DSI_CHECK_RET(DSI_WaitForNotBusy());
557
558 DDMS_capturing=1;
559
560 if(lcm_params->dsi.mode == CMD_MODE)
561 {
562 LCD_CHECK_RET(LCD_EnableDCtoDsi(FALSE));
563#ifndef MT65XX_NEW_DISP
564 LCD_CHECK_RET(LCD_Capture_Framebuffer(pvbuf, bpp));
565#else
566 DSI_CHECK_RET(DSI_Capture_Framebuffer(pvbuf, bpp, true));//cmd mode
567#endif
568 }
569 else
570 {
571 DSI_CHECK_RET(DSI_Capture_Framebuffer(pvbuf, bpp, false));//video mode
572 }
573
574
575 if(lcm_params->dsi.mode == CMD_MODE)
576 {
577 LCD_CHECK_RET(LCD_EnableDCtoDsi(TRUE));
578 }
579
580 DDMS_capturing=0;
581
582 return DISP_STATUS_OK;
583}
584
585
586// called by "esd_recovery_kthread"
587// protected by sem_early_suspend, sem_update_screen
588BOOL dsi_esd_check(void)
589{
590 BOOL result = false;
591
592 if(lcm_params->dsi.mode == CMD_MODE){
593 result = lcm_drv->esd_check();
594 return result;
595 }
596 else
597 {
598#ifndef BUILD_UBOOT
599#ifndef MT65XX_NEW_DISP
600 if(lcm_params->dsi.lcm_int_te_monitor)
601 result = DSI_esd_check();
602
603 if(result)
604 return true;
605
606 if(lcm_params->dsi.lcm_ext_te_monitor)
607 result = LCD_esd_check();
608#else
609 result = DSI_esd_check();
610 DSI_LP_Reset();
611 needStartDSI = true;
612 if(!result)
613 dsi_update_screen(true);
614#endif
615 return result;
616#endif
617 }
618
619}
620void disp_dsi_late_prepare(void)
621{
622fbconfig_set_cmd_mode();//backup registers and set cmd mode;
623
624}
625
626
627void disp_dsi_post(void)
628{
629
630fbconfig_set_vdo_mode();
631needStartDSI = true;
632DSI_StartTransfer(true);
633//dsi_update_screen(true);
634}
635
636int fbconfig_mipi_clk_set(unsigned int clk)
637{
638DSI_STATUS ret = DSI_STATUS_ERROR;
639
640ret = fbconfig_DSI_set_CLK(clk);
641return ret ;
642}
643
644void fbconfig_mipi_lane_set(unsigned int lane_num)
645{
646 fbconfig_DSI_set_lane_num(lane_num);
647
648}
649
650// called by "esd_recovery_kthread"
651// protected by sem_early_suspend, sem_update_screen
652void dsi_esd_reset(void)
653{
654 /// we assume the power is on here
655 /// what we need is some setting for LCM init
656 if(lcm_params->dsi.mode == CMD_MODE)
657 {
658 DSI_clk_HS_mode(0);
659 DSI_clk_ULP_mode(0);
660 DSI_lane0_ULP_mode(0);
661 }
662 else
663 {
664 DSI_SetMode(CMD_MODE);
665 DSI_clk_HS_mode(0);
666 // clock/data lane go to Ideal
667 DSI_Reset();
668 }
669
670}
671
672const DISP_IF_DRIVER *DISP_GetDriverDSI(void)
673{
674 static const DISP_IF_DRIVER DSI_DISP_DRV =
675 {
676 .init = dsi_init,
677 .enable_power = dsi_enable_power,
678 .update_screen = dsi_update_screen,
679 .get_working_buffer_size = dsi_get_working_buffer_size,
680
681 .get_panel_color_format = dsi_get_panel_color_format,
682 .get_working_buffer_bpp = dsi_get_working_buffer_bpp,
683 .init_te_control = init_lcd_te_control,
684 .get_dithering_bpp = dsi_get_dithering_bpp,
685 .capture_framebuffer = dsi_capture_framebuffer,
686 .esd_reset = dsi_esd_reset,
687 .esd_check = dsi_esd_check,
688 };
689
690 return &DSI_DISP_DRV;
691}
692