8888#define DSI_HSA_WC 0x50
8989#define DSI_HBP_WC 0x54
9090#define DSI_HFP_WC 0x58
91+ #define HFP_HS_VB_PS_WC GENMASK(30, 16)
92+ #define HFP_HS_EN BIT(31)
9193
9294#define DSI_CMDQ_SIZE 0x60
9395#define CMDQ_SIZE 0x3f
9496#define CMDQ_SIZE_SEL BIT(15)
9597
9698#define DSI_HSTX_CKL_WC 0x64
99+ #define HSTX_CKL_WC GENMASK(15, 2)
97100
98101#define DSI_RX_DATA0 0x74
99102#define DSI_RX_DATA1 0x78
@@ -187,6 +190,7 @@ struct mtk_dsi_driver_data {
187190 bool has_shadow_ctl ;
188191 bool has_size_ctl ;
189192 bool cmdq_long_packet_ctl ;
193+ bool support_per_frame_lp ;
190194};
191195
192196struct mtk_dsi {
@@ -426,7 +430,75 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
426430 writel (ps_val , dsi -> regs + DSI_PSCTRL );
427431}
428432
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 )
430502{
431503 u32 horizontal_sync_active_byte ;
432504 u32 horizontal_backporch_byte ;
@@ -436,24 +508,13 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
436508 u32 dsi_tmp_buf_bpp , data_phy_cycles ;
437509 u32 delta ;
438510 struct mtk_phy_timing * timing = & dsi -> phy_timing ;
439-
440511 struct videomode * vm = & dsi -> vm ;
441512
442513 if (dsi -> format == MIPI_DSI_FMT_RGB565 )
443514 dsi_tmp_buf_bpp = 2 ;
444515 else
445516 dsi_tmp_buf_bpp = 3 ;
446517
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-
457518 horizontal_sync_active_byte = (vm -> hsync_len * dsi_tmp_buf_bpp - 10 );
458519
459520 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)
499560 writel (horizontal_sync_active_byte , dsi -> regs + DSI_HSA_WC );
500561 writel (horizontal_backporch_byte , dsi -> regs + DSI_HBP_WC );
501562 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 );
502583
503584 mtk_dsi_ps_control (dsi , false);
504585}
@@ -1197,6 +1278,7 @@ static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
11971278 .has_shadow_ctl = true,
11981279 .has_size_ctl = true,
11991280 .cmdq_long_packet_ctl = true,
1281+ .support_per_frame_lp = true,
12001282};
12011283
12021284static const struct of_device_id mtk_dsi_of_match [] = {
0 commit comments