88
88
#define DSI_HSA_WC 0x50
89
89
#define DSI_HBP_WC 0x54
90
90
#define DSI_HFP_WC 0x58
91
+ #define HFP_HS_VB_PS_WC GENMASK(30, 16)
92
+ #define HFP_HS_EN BIT(31)
91
93
92
94
#define DSI_CMDQ_SIZE 0x60
93
95
#define CMDQ_SIZE 0x3f
94
96
#define CMDQ_SIZE_SEL BIT(15)
95
97
96
98
#define DSI_HSTX_CKL_WC 0x64
99
+ #define HSTX_CKL_WC GENMASK(15, 2)
97
100
98
101
#define DSI_RX_DATA0 0x74
99
102
#define DSI_RX_DATA1 0x78
@@ -187,6 +190,7 @@ struct mtk_dsi_driver_data {
187
190
bool has_shadow_ctl ;
188
191
bool has_size_ctl ;
189
192
bool cmdq_long_packet_ctl ;
193
+ bool support_per_frame_lp ;
190
194
};
191
195
192
196
struct mtk_dsi {
@@ -426,7 +430,75 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
426
430
writel (ps_val , dsi -> regs + DSI_PSCTRL );
427
431
}
428
432
429
- static void mtk_dsi_config_vdo_timing (struct mtk_dsi * dsi )
433
+ static void mtk_dsi_config_vdo_timing_per_frame_lp (struct mtk_dsi * dsi )
434
+ {
435
+ u32 horizontal_sync_active_byte ;
436
+ u32 horizontal_backporch_byte ;
437
+ u32 horizontal_frontporch_byte ;
438
+ u32 hfp_byte_adjust , v_active_adjust ;
439
+ u32 cklp_wc_min_adjust , cklp_wc_max_adjust ;
440
+ u32 dsi_tmp_buf_bpp ;
441
+ unsigned int da_hs_trail ;
442
+ unsigned int ps_wc , hs_vb_ps_wc ;
443
+ u32 v_active_roundup , hstx_cklp_wc ;
444
+ u32 hstx_cklp_wc_max , hstx_cklp_wc_min ;
445
+ struct videomode * vm = & dsi -> vm ;
446
+
447
+ if (dsi -> format == MIPI_DSI_FMT_RGB565 )
448
+ dsi_tmp_buf_bpp = 2 ;
449
+ else
450
+ dsi_tmp_buf_bpp = 3 ;
451
+
452
+ da_hs_trail = dsi -> phy_timing .da_hs_trail ;
453
+ ps_wc = vm -> hactive * dsi_tmp_buf_bpp ;
454
+
455
+ if (dsi -> mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE ) {
456
+ horizontal_sync_active_byte =
457
+ vm -> hsync_len * dsi_tmp_buf_bpp - 10 ;
458
+ horizontal_backporch_byte =
459
+ vm -> hback_porch * dsi_tmp_buf_bpp - 10 ;
460
+ hfp_byte_adjust = 12 ;
461
+ v_active_adjust = 32 + horizontal_sync_active_byte ;
462
+ cklp_wc_min_adjust = 12 + 2 + 4 + horizontal_sync_active_byte ;
463
+ cklp_wc_max_adjust = 20 + 6 + 4 + horizontal_sync_active_byte ;
464
+ } else {
465
+ horizontal_sync_active_byte = vm -> hsync_len * dsi_tmp_buf_bpp - 4 ;
466
+ horizontal_backporch_byte = (vm -> hback_porch + vm -> hsync_len ) *
467
+ dsi_tmp_buf_bpp - 10 ;
468
+ cklp_wc_min_adjust = 4 ;
469
+ cklp_wc_max_adjust = 12 + 4 + 4 ;
470
+ if (dsi -> mode_flags & MIPI_DSI_MODE_VIDEO_BURST ) {
471
+ hfp_byte_adjust = 18 ;
472
+ v_active_adjust = 28 ;
473
+ } else {
474
+ hfp_byte_adjust = 12 ;
475
+ v_active_adjust = 22 ;
476
+ }
477
+ }
478
+ horizontal_frontporch_byte = vm -> hfront_porch * dsi_tmp_buf_bpp - hfp_byte_adjust ;
479
+ v_active_roundup = (v_active_adjust + horizontal_backporch_byte + ps_wc +
480
+ horizontal_frontporch_byte ) % dsi -> lanes ;
481
+ if (v_active_roundup )
482
+ horizontal_backporch_byte += dsi -> lanes - v_active_roundup ;
483
+ hstx_cklp_wc_min = (DIV_ROUND_UP (cklp_wc_min_adjust , dsi -> lanes ) + da_hs_trail + 1 )
484
+ * dsi -> lanes / 6 - 1 ;
485
+ hstx_cklp_wc_max = (DIV_ROUND_UP ((cklp_wc_max_adjust + horizontal_backporch_byte +
486
+ ps_wc ), dsi -> lanes ) + da_hs_trail + 1 ) * dsi -> lanes / 6 - 1 ;
487
+
488
+ hstx_cklp_wc = FIELD_PREP (HSTX_CKL_WC , (hstx_cklp_wc_min + hstx_cklp_wc_max ) / 2 );
489
+ writel (hstx_cklp_wc , dsi -> regs + DSI_HSTX_CKL_WC );
490
+
491
+ hs_vb_ps_wc = ps_wc - (dsi -> phy_timing .lpx + dsi -> phy_timing .da_hs_exit +
492
+ dsi -> phy_timing .da_hs_prepare + dsi -> phy_timing .da_hs_zero + 2 ) * dsi -> lanes ;
493
+ horizontal_frontporch_byte |= FIELD_PREP (HFP_HS_EN , 1 ) |
494
+ FIELD_PREP (HFP_HS_VB_PS_WC , hs_vb_ps_wc );
495
+
496
+ writel (horizontal_sync_active_byte , dsi -> regs + DSI_HSA_WC );
497
+ writel (horizontal_backporch_byte , dsi -> regs + DSI_HBP_WC );
498
+ writel (horizontal_frontporch_byte , dsi -> regs + DSI_HFP_WC );
499
+ }
500
+
501
+ static void mtk_dsi_config_vdo_timing_per_line_lp (struct mtk_dsi * dsi )
430
502
{
431
503
u32 horizontal_sync_active_byte ;
432
504
u32 horizontal_backporch_byte ;
@@ -436,24 +508,13 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
436
508
u32 dsi_tmp_buf_bpp , data_phy_cycles ;
437
509
u32 delta ;
438
510
struct mtk_phy_timing * timing = & dsi -> phy_timing ;
439
-
440
511
struct videomode * vm = & dsi -> vm ;
441
512
442
513
if (dsi -> format == MIPI_DSI_FMT_RGB565 )
443
514
dsi_tmp_buf_bpp = 2 ;
444
515
else
445
516
dsi_tmp_buf_bpp = 3 ;
446
517
447
- writel (vm -> vsync_len , dsi -> regs + DSI_VSA_NL );
448
- writel (vm -> vback_porch , dsi -> regs + DSI_VBP_NL );
449
- writel (vm -> vfront_porch , dsi -> regs + DSI_VFP_NL );
450
- writel (vm -> vactive , dsi -> regs + DSI_VACT_NL );
451
-
452
- if (dsi -> driver_data -> has_size_ctl )
453
- writel (FIELD_PREP (DSI_HEIGHT , vm -> vactive ) |
454
- FIELD_PREP (DSI_WIDTH , vm -> hactive ),
455
- dsi -> regs + DSI_SIZE_CON );
456
-
457
518
horizontal_sync_active_byte = (vm -> hsync_len * dsi_tmp_buf_bpp - 10 );
458
519
459
520
if (dsi -> mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE )
@@ -499,6 +560,26 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
499
560
writel (horizontal_sync_active_byte , dsi -> regs + DSI_HSA_WC );
500
561
writel (horizontal_backporch_byte , dsi -> regs + DSI_HBP_WC );
501
562
writel (horizontal_frontporch_byte , dsi -> regs + DSI_HFP_WC );
563
+ }
564
+
565
+ static void mtk_dsi_config_vdo_timing (struct mtk_dsi * dsi )
566
+ {
567
+ struct videomode * vm = & dsi -> vm ;
568
+
569
+ writel (vm -> vsync_len , dsi -> regs + DSI_VSA_NL );
570
+ writel (vm -> vback_porch , dsi -> regs + DSI_VBP_NL );
571
+ writel (vm -> vfront_porch , dsi -> regs + DSI_VFP_NL );
572
+ writel (vm -> vactive , dsi -> regs + DSI_VACT_NL );
573
+
574
+ if (dsi -> driver_data -> has_size_ctl )
575
+ writel (FIELD_PREP (DSI_HEIGHT , vm -> vactive ) |
576
+ FIELD_PREP (DSI_WIDTH , vm -> hactive ),
577
+ dsi -> regs + DSI_SIZE_CON );
578
+
579
+ if (dsi -> driver_data -> support_per_frame_lp )
580
+ mtk_dsi_config_vdo_timing_per_frame_lp (dsi );
581
+ else
582
+ mtk_dsi_config_vdo_timing_per_line_lp (dsi );
502
583
503
584
mtk_dsi_ps_control (dsi , false);
504
585
}
@@ -1197,6 +1278,7 @@ static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
1197
1278
.has_shadow_ctl = true,
1198
1279
.has_size_ctl = true,
1199
1280
.cmdq_long_packet_ctl = true,
1281
+ .support_per_frame_lp = true,
1200
1282
};
1201
1283
1202
1284
static const struct of_device_id mtk_dsi_of_match [] = {
0 commit comments