disp: msm: dsi: Add support for C-PHY dynamic clock switch

This change adds support for C-PHY dynamic clock switch feature.
Also add support for phy ver 4.0 C-PHY timing parameters calculation
to be used for clock switch.

Change-Id: I8292860fd8c93a7ba7988ec8c44ea9683f45b6e6
Signed-off-by: Ritesh Kumar <riteshk@codeaurora.org>
Signed-off-by: Harigovindan P <harigovi@codeaurora.org>
Signed-off-by: Steve Cohen <cohens@codeaurora.org>
此提交包含在:
Harigovindan P
2020-05-06 15:31:55 +05:30
提交者 Steve Cohen
父節點 d8ffbf3d39
當前提交 662ac3ab89
共有 8 個檔案被更改,包括 366 行新增74 行删除

查看文件

@@ -3306,11 +3306,15 @@ static int dsi_display_clocks_init(struct dsi_display *display)
const char *mux_byte = "mux_byte", *mux_pixel = "mux_pixel";
const char *cphy_byte = "cphy_byte", *cphy_pixel = "cphy_pixel";
const char *shadow_byte = "shadow_byte", *shadow_pixel = "shadow_pixel";
const char *shadow_cphybyte = "shadow_cphybyte",
*shadow_cphypixel = "shadow_cphypixel";
struct clk *dsi_clk;
struct dsi_clk_link_set *src = &display->clock_info.src_clks;
struct dsi_clk_link_set *mux = &display->clock_info.mux_clks;
struct dsi_clk_link_set *cphy = &display->clock_info.cphy_clks;
struct dsi_clk_link_set *shadow = &display->clock_info.shadow_clks;
struct dsi_clk_link_set *shadow_cphy =
&display->clock_info.shadow_cphy_clks;
struct dsi_dyn_clk_caps *dyn_clk_caps = &(display->panel->dyn_clk_caps);
char *dsi_clock_name;
@@ -3369,6 +3373,12 @@ static int dsi_display_clocks_init(struct dsi_display *display)
if (dsi_display_check_prefix(shadow_pixel,
clk_name))
shadow->pixel_clk = NULL;
if (dsi_display_check_prefix(shadow_cphybyte,
clk_name))
shadow_cphy->byte_clk = NULL;
if (dsi_display_check_prefix(shadow_cphypixel,
clk_name))
shadow_cphy->pixel_clk = NULL;
dyn_clk_caps->dyn_clk_support = false;
}
@@ -3413,6 +3423,16 @@ static int dsi_display_clocks_init(struct dsi_display *display)
shadow->pixel_clk = dsi_clk;
continue;
}
if (dsi_display_check_prefix(shadow_cphybyte, clk_name)) {
shadow_cphy->byte_clk = dsi_clk;
continue;
}
if (dsi_display_check_prefix(shadow_cphypixel, clk_name)) {
shadow_cphy->pixel_clk = dsi_clk;
continue;
}
}
return 0;
@@ -4278,12 +4298,12 @@ static int dsi_display_update_dsi_bitrate(struct dsi_display *display,
byte_intf_clk_div = host_cfg->byte_intf_clk_div;
do_div(byte_intf_clk_rate, byte_intf_clk_div);
} else {
do_div(bit_rate, bits_per_symbol);
bit_rate *= num_of_symbols;
bit_rate_per_lane = bit_rate;
do_div(bit_rate_per_lane, num_of_lanes);
byte_clk_rate = bit_rate_per_lane;
do_div(byte_clk_rate, 7);
bit_rate_per_lane = bit_clk_rate;
pclk_rate *= bits_per_symbol;
do_div(pclk_rate, num_of_symbols);
byte_clk_rate = bit_clk_rate;
do_div(byte_clk_rate, num_of_symbols);
/* For CPHY, byte_intf_clk is same as byte_clk */
byte_intf_clk_rate = byte_clk_rate;
}
@@ -4367,6 +4387,17 @@ static void _dsi_display_calc_pipe_delay(struct dsi_display *display,
delay->pll_delay = ((130 * esc_clk_rate_hz) / 1000000) * 2;
}
/*
* dsi_display_is_type_cphy - check if panel type is cphy
* @display: Pointer to private display structure
* Returns: True if panel type is cphy
*/
static inline bool dsi_display_is_type_cphy(struct dsi_display *display)
{
return (display->panel->host_config.phy_type ==
DSI_PHY_TYPE_CPHY) ? true : false;
}
static int _dsi_display_dyn_update_clks(struct dsi_display *display,
struct link_clk_freq *bkp_freq)
{
@@ -4374,17 +4405,26 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
u8 ctrl_version;
struct dsi_display_ctrl *m_ctrl, *ctrl;
struct dsi_dyn_clk_caps *dyn_clk_caps;
struct dsi_clk_link_set *parent_clk, *enable_clk;
m_ctrl = &display->ctrl[display->clk_master_idx];
dyn_clk_caps = &(display->panel->dyn_clk_caps);
ctrl_version = m_ctrl->ctrl->version;
dsi_clk_prepare_enable(&display->clock_info.src_clks);
if (dsi_display_is_type_cphy(display)) {
enable_clk = &display->clock_info.cphy_clks;
parent_clk = &display->clock_info.shadow_cphy_clks;
} else {
enable_clk = &display->clock_info.src_clks;
parent_clk = &display->clock_info.shadow_clks;
}
rc = dsi_clk_update_parent(&display->clock_info.shadow_clks,
&display->clock_info.mux_clks);
dsi_clk_prepare_enable(enable_clk);
rc = dsi_clk_update_parent(parent_clk,
&display->clock_info.mux_clks);
if (rc) {
DSI_ERR("failed update mux parent to shadow\n");
DSI_ERR("failed to update mux parent\n");
goto exit;
}
@@ -4443,12 +4483,12 @@ static int _dsi_display_dyn_update_clks(struct dsi_display *display,
}
defer_dfps_wait:
rc = dsi_clk_update_parent(&display->clock_info.src_clks,
&display->clock_info.mux_clks);
rc = dsi_clk_update_parent(enable_clk,
&display->clock_info.mux_clks);
if (rc)
DSI_ERR("could not switch back to src clks %d\n", rc);
dsi_clk_disable_unprepare(&display->clock_info.src_clks);
dsi_clk_disable_unprepare(enable_clk);
return rc;