diff --git a/msm/dsi/dsi_defs.h b/msm/dsi/dsi_defs.h index 6c78879913a6..b863cc95f808 100644 --- a/msm/dsi/dsi_defs.h +++ b/msm/dsi/dsi_defs.h @@ -638,6 +638,7 @@ struct dsi_display_mode_priv_info { u32 dsi_transfer_time_us; u64 clk_rate_hz; u64 min_dsi_clk_hz; + u32 phy_drive_strength; struct msm_display_topology topology; struct msm_display_dsc_info dsc; diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 559741819121..7d517d3f36e4 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -5783,6 +5783,16 @@ static int dsi_display_set_mode_sub(struct dsi_display *display, dsi_display_validate_dms_fps(display->panel->cur_mode, mode); } + if (priv_info->phy_drive_strength) { + display_for_each_ctrl(i, display) { + ctrl = &display->ctrl[i]; + rc = dsi_phy_set_drive_strength_params(ctrl->phy, + priv_info->phy_drive_strength); + if (rc) + DSI_ERR("Fail to add drive strength params\n"); + } + } + if (priv_info->phy_timing_len) { display_for_each_ctrl(i, display) { ctrl = &display->ctrl[i]; diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 012a797f82b0..359102ed7b77 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -2911,6 +2911,28 @@ error: return rc; } +static int dsi_panel_parse_phy_ldo(struct dsi_display_mode *mode, + struct dsi_parser_utils *utils) +{ + u32 data; + int rc = 0; + struct dsi_display_mode_priv_info *priv_info; + + if (!mode || !mode->priv_info) + return -EINVAL; + + priv_info = mode->priv_info; + + rc = utils->read_u32(utils->data, + "qcom,mdss-dsi-panel-phy-drive-strength", &data); + if (rc) + DSI_DEBUG("Unsupport to set Phy Driver Strength\n"); + else + priv_info->phy_drive_strength = data; + + return rc; +} + static int dsi_panel_parse_phy_timing(struct dsi_display_mode *mode, struct dsi_parser_utils *utils) { @@ -4744,6 +4766,12 @@ int dsi_panel_get_mode(struct dsi_panel *panel, DSI_ERR( "failed to parse panel jitter config, rc=%d\n", rc); + rc = dsi_panel_parse_phy_ldo(mode, utils); + if (rc) { + DSI_ERR( + "failed to parse panel phy ldo rc=%d\n", rc); + } + rc = dsi_panel_parse_phy_timing(mode, utils); if (rc) { DSI_ERR( diff --git a/msm/dsi/dsi_phy.c b/msm/dsi/dsi_phy.c index f57b4245ecce..3ae158db391e 100644 --- a/msm/dsi/dsi_phy.c +++ b/msm/dsi/dsi_phy.c @@ -1114,6 +1114,32 @@ int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy, return 0; } +/** + * dsi_phy_set_drive_strength_params - drive strength parameters for the panel + * @phy: DSI PHY handle + * @drive strength: array holding timing params. + * + * Return: error code. + */ +int dsi_phy_set_drive_strength_params(struct msm_dsi_phy *phy, + u32 drive_strength) +{ + int rc = 0; + + if (!phy || !drive_strength) { + DSI_PHY_ERR(phy, "Invalid params\n"); + return -EINVAL; + } + + mutex_lock(&phy->phy_lock); + + + phy->cfg.phy_drive_strength = drive_strength; + + mutex_unlock(&phy->phy_lock); + return rc; +} + /** * dsi_phy_set_timing_params() - timing parameters for the panel * @phy: DSI PHY handle @@ -1147,7 +1173,6 @@ int dsi_phy_set_timing_params(struct msm_dsi_phy *phy, 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 7fe7c060c8bf..0615d4a23adf 100644 --- a/msm/dsi/dsi_phy.h +++ b/msm/dsi/dsi_phy.h @@ -256,6 +256,16 @@ int dsi_phy_set_clamp_state(struct msm_dsi_phy *phy, bool enable); int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy, struct link_clk_freq *clk_freq); +/** + * dsi_phy_set_drive_strength_params() - drive strength parameters for the panel + * @phy: DSI PHY handle + * @drive_strength: DSI PHY Drive Strength + * + * Return: error code. + */ +int dsi_phy_set_drive_strength_params(struct msm_dsi_phy *phy, + u32 drive_strength); + /** * dsi_phy_set_timing_params() - timing parameters for the panel * @phy: DSI PHY handle diff --git a/msm/dsi/dsi_phy_hw.h b/msm/dsi/dsi_phy_hw.h index 97d3f86db3c4..dd78008470c9 100644 --- a/msm/dsi/dsi_phy_hw.h +++ b/msm/dsi/dsi_phy_hw.h @@ -103,6 +103,7 @@ struct dsi_phy_per_lane_cfgs { * @force_clk_lane_hs:Boolean whether to force clock lane in HS mode. * @phy_type: Phy-type (Dphy/Cphy). * @bit_clk_rate_hz: DSI bit clk rate in HZ. + * @drive_strength: DSI PHY drive strength. */ struct dsi_phy_cfg { struct dsi_phy_per_lane_cfgs lanecfg; @@ -115,6 +116,7 @@ struct dsi_phy_cfg { bool force_clk_lane_hs; enum dsi_phy_type phy_type; unsigned long bit_clk_rate_hz; + u32 phy_drive_strength; }; struct dsi_phy_hw; diff --git a/msm/dsi/dsi_phy_hw_v4_0.c b/msm/dsi/dsi_phy_hw_v4_0.c index ae50b70dbeef..14bc5448f417 100644 --- a/msm/dsi/dsi_phy_hw_v4_0.c +++ b/msm/dsi/dsi_phy_hw_v4_0.c @@ -349,6 +349,11 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 : 0x3c; glbl_str_swi_cal_sel_ctrl = 0x00; glbl_hstx_str_ctrl_0 = 0x88; + + if (cfg->phy_drive_strength != glbl_hstx_str_ctrl_0) { + glbl_str_swi_cal_sel_ctrl = 0x03; + glbl_hstx_str_ctrl_0 = cfg->phy_drive_strength; + } } else { vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59; glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;