disp: msm: dsi: add support for dsi dynamic clock switch

This change adds support for dynamic switching of dsi clocks
to avoid RF interference issues. Also with dynamic dsi clock
switch feature coming into picture, now populate the supported
refresh rate as list instead of providing a range. Modify the
logic to enumerate all the modes in dsi driver, taking dynamic
bit clocks, resolutions and refresh rates into account.

Change-Id: I5b6e62bc935cf2234bdd96fcb3c7537b4e735fff
Signed-off-by: Sandeep Panda <spanda@codeaurora.org>
Signed-off-by: Ritesh Kumar <riteshk@codeaurora.org>
Signed-off-by: Yujun Zhang <yujunzhang@codeaurora.org>
This commit is contained in:
Yujun Zhang
2018-10-25 15:49:16 +05:30
parent 6ec69969e2
commit b0f2e2222e
27 changed files with 1331 additions and 446 deletions

View File

@@ -105,8 +105,9 @@ int dsi_clk_set_link_frequencies(void *client, struct link_clk_freq freq,
/**
* dsi_clk_set_pixel_clk_rate() - set frequency for pixel clock
* @clks: DSI link clock information.
* @pixel_clk: Pixel clock rate in KHz.
* @clks: DSI link clock information.
* @pixel_clk: Pixel clock rate in KHz.
* @index: Index of the DSI controller.
*
* return: error code in case of failure or 0 for success.
*/
@@ -128,9 +129,9 @@ int dsi_clk_set_pixel_clk_rate(void *client, u64 pixel_clk, u32 index)
/**
* dsi_clk_set_byte_clk_rate() - set frequency for byte clock
* @client: DSI clock client pointer.
* @byte_clk: Pixel clock rate in Hz.
* @index: Index of the DSI controller.
* @client: DSI clock client pointer.
* @byte_clk: Byte clock rate in Hz.
* @index: Index of the DSI controller.
* return: error code in case of failure or 0 for success.
*/
int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk, u32 index)
@@ -138,6 +139,7 @@ int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk, u32 index)
int rc = 0;
struct dsi_clk_client_info *c = client;
struct dsi_clk_mngr *mngr;
u64 byte_intf_rate;
mngr = c->mngr;
rc = clk_set_rate(mngr->link_clks[index].hs_clks.byte_clk, byte_clk);
@@ -146,8 +148,16 @@ int dsi_clk_set_byte_clk_rate(void *client, u64 byte_clk, u32 index)
else
mngr->link_clks[index].freq.byte_clk_rate = byte_clk;
return rc;
if (mngr->link_clks[index].hs_clks.byte_intf_clk) {
byte_intf_rate = mngr->link_clks[index].freq.byte_clk_rate / 2;
rc = clk_set_rate(mngr->link_clks[index].hs_clks.byte_intf_clk,
byte_intf_rate);
if (rc)
pr_err("failed to set clk rate for byte intf clk=%d\n",
rc);
}
return rc;
}
/**
@@ -175,6 +185,41 @@ error:
return rc;
}
/**
* dsi_clk_prepare_enable() - prepare and enable dsi src clocks
* @clk: list of src clocks.
*
* @return: Zero on success and err no on failure.
*/
int dsi_clk_prepare_enable(struct dsi_clk_link_set *clk)
{
int rc;
rc = clk_prepare_enable(clk->byte_clk);
if (rc) {
pr_err("failed to enable byte src clk %d\n", rc);
return rc;
}
rc = clk_prepare_enable(clk->pixel_clk);
if (rc) {
pr_err("failed to enable pixel src clk %d\n", rc);
return rc;
}
return 0;
}
/**
* dsi_clk_disable_unprepare() - disable and unprepare dsi src clocks
* @clk: list of src clocks.
*/
void dsi_clk_disable_unprepare(struct dsi_clk_link_set *clk)
{
clk_disable_unprepare(clk->pixel_clk);
clk_disable_unprepare(clk->byte_clk);
}
int dsi_core_clk_start(struct dsi_core_clks *c_clks)
{
int rc = 0;