diff --git a/msm/dsi/dsi_catalog.c b/msm/dsi/dsi_catalog.c index a43470b14e..1bc14666da 100644 --- a/msm/dsi/dsi_catalog.c +++ b/msm/dsi/dsi_catalog.c @@ -262,6 +262,7 @@ static void dsi_catalog_phy_4_0_init(struct dsi_phy_hw *phy) phy->ops.dyn_refresh_ops.cache_phy_timings = dsi_phy_hw_v4_0_cache_phy_timings; phy->ops.set_continuous_clk = dsi_phy_hw_v4_0_set_continuous_clk; + phy->ops.commit_phy_timing = dsi_phy_hw_v4_0_commit_phy_timing; } /** diff --git a/msm/dsi/dsi_catalog.h b/msm/dsi/dsi_catalog.h index c4e47d878a..2e946ab37b 100644 --- a/msm/dsi/dsi_catalog.h +++ b/msm/dsi/dsi_catalog.h @@ -116,6 +116,8 @@ int dsi_phy_hw_v4_0_lane_reset(struct dsi_phy_hw *phy); void dsi_phy_hw_v4_0_toggle_resync_fifo(struct dsi_phy_hw *phy); void dsi_phy_hw_v4_0_reset_clk_en_sel(struct dsi_phy_hw *phy); void dsi_phy_hw_v4_0_set_continuous_clk(struct dsi_phy_hw *phy, bool enable); +void dsi_phy_hw_v4_0_commit_phy_timing(struct dsi_phy_hw *phy, + struct dsi_phy_per_lane_cfgs *timing); /* DSI controller common ops */ u32 dsi_ctrl_hw_cmn_get_interrupt_status(struct dsi_ctrl_hw *ctrl); diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 02749c2b19..612e9de9fb 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -4419,6 +4419,7 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, int i; struct dsi_display_ctrl *ctrl; struct dsi_display_mode_priv_info *priv_info; + bool commit_phy_timing = false; priv_info = mode->priv_info; if (!priv_info) { @@ -4488,6 +4489,7 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, if ((mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) && (display->panel->panel_mode == DSI_OP_CMD_MODE)) { + commit_phy_timing = true; atomic_set(&display->clkrate_change_pending, 1); dsi_display_validate_dms_fps(display->panel->cur_mode, mode); @@ -4498,7 +4500,8 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, ctrl = &display->ctrl[i]; rc = dsi_phy_set_timing_params(ctrl->phy, priv_info->phy_timing_val, - priv_info->phy_timing_len); + priv_info->phy_timing_len, + commit_phy_timing); if (rc) DSI_ERR("failed to add DSI PHY timing params\n"); } diff --git a/msm/dsi/dsi_phy.c b/msm/dsi/dsi_phy.c index a682f2c6e9..3ca8699fbf 100644 --- a/msm/dsi/dsi_phy.c +++ b/msm/dsi/dsi_phy.c @@ -1071,6 +1071,8 @@ int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy, * @phy: DSI PHY handle * @timing: array holding timing params. * @size: size of the array. + * @commit: boolean to indicate if programming PHY HW registers is + * required * * When PHY timing calculator is not implemented, this array will be used to * pass PHY timing information. @@ -1078,7 +1080,7 @@ int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy, * Return: error code. */ int dsi_phy_set_timing_params(struct msm_dsi_phy *phy, - u32 *timing, u32 size) + u32 *timing, u32 size, bool commit) { int rc = 0; @@ -1091,9 +1093,13 @@ int dsi_phy_set_timing_params(struct msm_dsi_phy *phy, if (phy->hw.ops.phy_timing_val) rc = phy->hw.ops.phy_timing_val(&phy->cfg.timing, timing, size); + if (!rc) phy->cfg.is_phy_timing_present = true; + if (phy->hw.ops.commit_phy_timing && commit) + phy->hw.ops.commit_phy_timing(&phy->hw, &phy->cfg.timing); + mutex_unlock(&phy->phy_lock); return rc; } diff --git a/msm/dsi/dsi_phy.h b/msm/dsi/dsi_phy.h index 3cbc892bb9..e2e5efd97d 100644 --- a/msm/dsi/dsi_phy.h +++ b/msm/dsi/dsi_phy.h @@ -244,6 +244,8 @@ int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy, * @phy: DSI PHY handle * @timing: array holding timing params. * @size: size of the array. + * @commit: boolean to indicate if programming PHY HW registers is + * required * * When PHY timing calculator is not implemented, this array will be used to * pass PHY timing information. @@ -251,7 +253,7 @@ int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy, * Return: error code. */ int dsi_phy_set_timing_params(struct msm_dsi_phy *phy, - u32 *timing, u32 size); + u32 *timing, u32 size, bool commit); /** * dsi_phy_lane_reset() - Reset DSI PHY lanes in case of error diff --git a/msm/dsi/dsi_phy_hw.h b/msm/dsi/dsi_phy_hw.h index 5f4d4bce61..2f5f23920e 100644 --- a/msm/dsi/dsi_phy_hw.h +++ b/msm/dsi/dsi_phy_hw.h @@ -321,6 +321,14 @@ struct dsi_phy_hw_ops { */ void (*set_continuous_clk)(struct dsi_phy_hw *phy, bool enable); + /** + * commit_phy_timing() - Commit PHY timing + * @phy: Pointer to DSI PHY hardware object. + * @timing: Pointer to PHY timing array + */ + void (*commit_phy_timing)(struct dsi_phy_hw *phy, + struct dsi_phy_per_lane_cfgs *timing); + void *timing_ops; struct phy_ulps_config_ops ulps_ops; struct phy_dyn_refresh_ops dyn_refresh_ops; diff --git a/msm/dsi/dsi_phy_hw_v4_0.c b/msm/dsi/dsi_phy_hw_v4_0.c index c3cb9776a1..ac5e7b0e6e 100644 --- a/msm/dsi/dsi_phy_hw_v4_0.c +++ b/msm/dsi/dsi_phy_hw_v4_0.c @@ -183,6 +183,26 @@ static void dsi_phy_hw_v4_0_lane_settings(struct dsi_phy_hw *phy, } +void dsi_phy_hw_v4_0_commit_phy_timing(struct dsi_phy_hw *phy, + struct dsi_phy_per_lane_cfgs *timing) +{ + /* Commit DSI PHY timings */ + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_0, timing->lane_v4[0]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_1, timing->lane_v4[1]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_2, timing->lane_v4[2]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_3, timing->lane_v4[3]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_4, timing->lane_v4[4]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_5, timing->lane_v4[5]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_6, timing->lane_v4[6]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_7, timing->lane_v4[7]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_8, timing->lane_v4[8]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_9, timing->lane_v4[9]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_10, timing->lane_v4[10]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_11, timing->lane_v4[11]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_12, timing->lane_v4[12]); + DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_13, timing->lane_v4[13]); +} + /** * enable() - Enable PHY hardware * @phy: Pointer to DSI PHY hardware object. @@ -290,20 +310,7 @@ void dsi_phy_hw_v4_0_enable(struct dsi_phy_hw *phy, DSI_W32(phy, DSIPHY_CMN_CLK_CFG1, (data << 2)); /* set PLL src */ /* DSI PHY timings */ - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_0, timing->lane_v4[0]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_1, timing->lane_v4[1]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_2, timing->lane_v4[2]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_3, timing->lane_v4[3]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_4, timing->lane_v4[4]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_5, timing->lane_v4[5]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_6, timing->lane_v4[6]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_7, timing->lane_v4[7]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_8, timing->lane_v4[8]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_9, timing->lane_v4[9]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_10, timing->lane_v4[10]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_11, timing->lane_v4[11]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_12, timing->lane_v4[12]); - DSI_W32(phy, DSIPHY_CMN_TIMING_CTRL_13, timing->lane_v4[13]); + dsi_phy_hw_v4_0_commit_phy_timing(phy, timing); /* DSI lane settings */ dsi_phy_hw_v4_0_lane_settings(phy, cfg);