disp: msm: dsi: unify dynamic clk support for command mode
Currently the dynamic bit clock switch trigger for command mode is supported via sysfs node. This might lead to unnecessary race conditions, when dsi driver is enabling the dsi bit clock as part of commit and at the same time if bit rate change via sysfs happens. So make the trigger happens via kernel mode set call as done for video mode. Change-Id: I17acb408d2b6dbd6fa41994e56262e31e43d088b Signed-off-by: Ritesh Kumar <riteshk@codeaurora.org> Signed-off-by: Yujun Zhang <yujunzhang@codeaurora.org>
このコミットが含まれているのは:
@@ -2987,7 +2987,10 @@ static int dsi_display_clocks_init(struct dsi_display *display)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dyn_clk_caps->dyn_clk_support) {
|
||||
if (dyn_clk_caps->dyn_clk_support &&
|
||||
(display->panel->panel_mode ==
|
||||
DSI_OP_VIDEO_MODE)) {
|
||||
|
||||
if (dsi_display_check_prefix(src_byte,
|
||||
clk_name))
|
||||
src->byte_clk = NULL;
|
||||
@@ -4016,7 +4019,7 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_dynamic_clk_switch(struct dsi_display *display,
|
||||
static int dsi_display_dynamic_clk_switch_vid(struct dsi_display *display,
|
||||
struct dsi_display_mode *mode)
|
||||
{
|
||||
int rc = 0, mask, i;
|
||||
@@ -4085,6 +4088,39 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_dynamic_clk_configure_cmd(struct dsi_display *display,
|
||||
int clk_rate)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (clk_rate <= 0) {
|
||||
pr_err("%s: bitrate should be greater than 0\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (clk_rate == display->cached_clk_rate) {
|
||||
pr_info("%s: ignore duplicated DSI clk setting\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
display->cached_clk_rate = clk_rate;
|
||||
|
||||
rc = dsi_display_update_dsi_bitrate(display, clk_rate);
|
||||
if (!rc) {
|
||||
pr_info("%s: bit clk is ready to be configured to '%d'\n",
|
||||
__func__, clk_rate);
|
||||
atomic_set(&display->clkrate_change_pending, 1);
|
||||
} else {
|
||||
pr_err("%s: Failed to prepare to configure '%d'. rc = %d\n",
|
||||
__func__, clk_rate, rc);
|
||||
/* Caching clock failed, so don't go on doing so. */
|
||||
atomic_set(&display->clkrate_change_pending, 0);
|
||||
display->cached_clk_rate = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_dfps_update(struct dsi_display *display,
|
||||
struct dsi_display_mode *dsi_mode)
|
||||
{
|
||||
@@ -4318,7 +4354,7 @@ static int dsi_display_set_mode_sub(struct dsi_display *display,
|
||||
struct dsi_display_mode *mode,
|
||||
u32 flags)
|
||||
{
|
||||
int rc = 0;
|
||||
int rc = 0, clk_rate = 0;
|
||||
int i;
|
||||
struct dsi_display_ctrl *ctrl;
|
||||
struct dsi_display_mode_priv_info *priv_info;
|
||||
@@ -4355,15 +4391,25 @@ static int dsi_display_set_mode_sub(struct dsi_display *display,
|
||||
goto error;
|
||||
}
|
||||
} else if (mode->dsi_mode_flags & DSI_MODE_FLAG_DYN_CLK) {
|
||||
rc = dsi_display_dynamic_clk_switch(display, mode);
|
||||
if (rc)
|
||||
pr_err("dynamic clk change failed %d\n", rc);
|
||||
/*
|
||||
* skip rest of the opearations since
|
||||
* dsi_display_dynamic_clk_switch() already takes
|
||||
* care of them.
|
||||
*/
|
||||
return rc;
|
||||
if (display->panel->panel_mode == DSI_OP_VIDEO_MODE) {
|
||||
rc = dsi_display_dynamic_clk_switch_vid(display, mode);
|
||||
if (rc)
|
||||
pr_err("dynamic clk change failed %d\n", rc);
|
||||
/*
|
||||
* skip rest of the opearations since
|
||||
* dsi_display_dynamic_clk_switch_vid() already takes
|
||||
* care of them.
|
||||
*/
|
||||
return rc;
|
||||
} else if (display->panel->panel_mode == DSI_OP_CMD_MODE) {
|
||||
clk_rate = mode->timing.clk_rate_hz;
|
||||
rc = dsi_display_dynamic_clk_configure_cmd(display,
|
||||
clk_rate);
|
||||
if (rc) {
|
||||
pr_err("Failed to configure dynamic clk\n");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
display_for_each_ctrl(i, display) {
|
||||
|
新しいイシューから参照
ユーザーをブロックする