msm: mdss: Avoid adaptive variable refresh during dynaminc FPS
Both dynamic FPS (DFPS) and adaptive variable refresh (AVR) depend and modify the programmable fetch. During DFPS update period, which is between 2 VSYNC, it is necessary to disable the AVR during this period, otherwise it will cause the timing engine hangs. CRs-Fixed: 1073650 Change-Id: I2836ef5b7f37f627a32a0b4332dc299a60012704 Signed-off-by: Benjamin Chan <bkchan@codeaurora.org>
This commit is contained in:
parent
1ff56658f3
commit
c2f50e72dd
3 changed files with 44 additions and 10 deletions
|
@ -404,7 +404,7 @@ struct mdss_mdp_ctl_intfs_ops {
|
||||||
|
|
||||||
/* to update lineptr, [1..yres] - enable, 0 - disable */
|
/* to update lineptr, [1..yres] - enable, 0 - disable */
|
||||||
int (*update_lineptr)(struct mdss_mdp_ctl *ctl, bool enable);
|
int (*update_lineptr)(struct mdss_mdp_ctl *ctl, bool enable);
|
||||||
int (*avr_ctrl_fnc)(struct mdss_mdp_ctl *);
|
int (*avr_ctrl_fnc)(struct mdss_mdp_ctl *, bool enable);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mdss_mdp_cwb {
|
struct mdss_mdp_cwb {
|
||||||
|
|
|
@ -5593,7 +5593,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
|
||||||
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
|
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
|
||||||
|
|
||||||
if (ctl->ops.avr_ctrl_fnc) {
|
if (ctl->ops.avr_ctrl_fnc) {
|
||||||
ret = ctl->ops.avr_ctrl_fnc(ctl);
|
ret = ctl->ops.avr_ctrl_fnc(ctl, true);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("error configuring avr ctrl registers ctl=%d err=%d\n",
|
pr_err("error configuring avr ctrl registers ctl=%d err=%d\n",
|
||||||
ctl->num, ret);
|
ctl->num, ret);
|
||||||
|
@ -5603,7 +5603,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sctl && sctl->ops.avr_ctrl_fnc) {
|
if (sctl && sctl->ops.avr_ctrl_fnc) {
|
||||||
ret = sctl->ops.avr_ctrl_fnc(sctl);
|
ret = sctl->ops.avr_ctrl_fnc(sctl, true);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("error configuring avr ctrl registers sctl=%d err=%d\n",
|
pr_err("error configuring avr ctrl registers sctl=%d err=%d\n",
|
||||||
sctl->num, ret);
|
sctl->num, ret);
|
||||||
|
|
|
@ -108,6 +108,8 @@ static void mdss_mdp_fetch_end_config(struct mdss_mdp_video_ctx *ctx,
|
||||||
|
|
||||||
static void early_wakeup_dfps_update_work(struct work_struct *work);
|
static void early_wakeup_dfps_update_work(struct work_struct *work);
|
||||||
|
|
||||||
|
static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl, bool enable);
|
||||||
|
|
||||||
static inline void mdp_video_write(struct mdss_mdp_video_ctx *ctx,
|
static inline void mdp_video_write(struct mdss_mdp_video_ctx *ctx,
|
||||||
u32 reg, u32 val)
|
u32 reg, u32 val)
|
||||||
{
|
{
|
||||||
|
@ -459,13 +461,15 @@ static int mdss_mdp_video_avr_trigger_setup(struct mdss_mdp_ctl *ctl)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mdss_mdp_video_avr_ctrl_setup(struct mdss_mdp_video_ctx *ctx,
|
static void mdss_mdp_video_avr_ctrl_setup(struct mdss_mdp_video_ctx *ctx,
|
||||||
struct mdss_mdp_avr_info *avr_info, bool is_master)
|
struct mdss_mdp_avr_info *avr_info, bool is_master, bool enable)
|
||||||
{
|
{
|
||||||
u32 avr_ctrl = 0;
|
u32 avr_ctrl = 0;
|
||||||
u32 avr_mode = 0;
|
u32 avr_mode = 0;
|
||||||
|
|
||||||
avr_ctrl = avr_info->avr_enabled;
|
if (enable) {
|
||||||
avr_mode = avr_info->avr_mode;
|
avr_ctrl = avr_info->avr_enabled;
|
||||||
|
avr_mode = avr_info->avr_mode;
|
||||||
|
}
|
||||||
|
|
||||||
/* Enable avr_vsync_clear_en bit to clear avr in next vsync */
|
/* Enable avr_vsync_clear_en bit to clear avr in next vsync */
|
||||||
if (avr_mode == MDSS_MDP_AVR_ONE_SHOT)
|
if (avr_mode == MDSS_MDP_AVR_ONE_SHOT)
|
||||||
|
@ -1429,6 +1433,20 @@ static int mdss_mdp_video_config_fps(struct mdss_mdp_ctl *ctl, int new_fps)
|
||||||
}
|
}
|
||||||
|
|
||||||
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
|
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to disable AVR during DFPS update period.
|
||||||
|
* Next commit will restore the AVR settings.
|
||||||
|
*/
|
||||||
|
if (test_bit(MDSS_CAPS_AVR_SUPPORTED,
|
||||||
|
mdata->mdss_caps_map) &&
|
||||||
|
ctl->avr_info.avr_enabled) {
|
||||||
|
mdss_mdp_video_avr_ctrl(ctl, false);
|
||||||
|
rc = mdss_mdp_video_dfps_wait4vsync(ctl);
|
||||||
|
if (rc < 0)
|
||||||
|
pr_err("Error in dfps_wait: %d\n", rc);
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&ctx->dfps_lock, flags);
|
spin_lock_irqsave(&ctx->dfps_lock, flags);
|
||||||
|
|
||||||
if (mdata->mdp_rev < MDSS_MDP_HW_REV_105) {
|
if (mdata->mdp_rev < MDSS_MDP_HW_REV_105) {
|
||||||
|
@ -2112,6 +2130,7 @@ static void early_wakeup_dfps_update_work(struct work_struct *work)
|
||||||
struct mdss_panel_info *pinfo;
|
struct mdss_panel_info *pinfo;
|
||||||
struct msm_fb_data_type *mfd;
|
struct msm_fb_data_type *mfd;
|
||||||
struct mdss_mdp_ctl *ctl;
|
struct mdss_mdp_ctl *ctl;
|
||||||
|
struct mdss_data_type *mdata;
|
||||||
struct dynamic_fps_data data = {0};
|
struct dynamic_fps_data data = {0};
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int dfps;
|
int dfps;
|
||||||
|
@ -2123,7 +2142,8 @@ static void early_wakeup_dfps_update_work(struct work_struct *work)
|
||||||
|
|
||||||
ctl = ctx->ctl;
|
ctl = ctx->ctl;
|
||||||
|
|
||||||
if (!ctl || !ctl->panel_data || !ctl->mfd || !ctl->mfd->fbi) {
|
if (!ctl || !ctl->panel_data || !ctl->mfd || !ctl->mfd->fbi ||
|
||||||
|
!ctl->mdata) {
|
||||||
pr_err("%s: invalid ctl\n", __func__);
|
pr_err("%s: invalid ctl\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2131,6 +2151,7 @@ static void early_wakeup_dfps_update_work(struct work_struct *work)
|
||||||
pdata = ctl->panel_data;
|
pdata = ctl->panel_data;
|
||||||
pinfo = &ctl->panel_data->panel_info;
|
pinfo = &ctl->panel_data->panel_info;
|
||||||
mfd = ctl->mfd;
|
mfd = ctl->mfd;
|
||||||
|
mdata = ctl->mdata;
|
||||||
|
|
||||||
if (!pinfo->dynamic_fps || !ctl->ops.config_fps_fnc ||
|
if (!pinfo->dynamic_fps || !ctl->ops.config_fps_fnc ||
|
||||||
!pdata->panel_info.default_fps) {
|
!pdata->panel_info.default_fps) {
|
||||||
|
@ -2138,6 +2159,17 @@ static void early_wakeup_dfps_update_work(struct work_struct *work)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bypass DFPS update when AVR is enabled because
|
||||||
|
* AVR will take control of the programmable fetch
|
||||||
|
*/
|
||||||
|
if (test_bit(MDSS_CAPS_AVR_SUPPORTED,
|
||||||
|
mdata->mdss_caps_map) &&
|
||||||
|
ctl->avr_info.avr_enabled) {
|
||||||
|
pr_debug("Bypass DFPS update when AVR is enabled\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* get the default fps that was cached before any dfps update */
|
/* get the default fps that was cached before any dfps update */
|
||||||
dfps = pdata->panel_info.default_fps;
|
dfps = pdata->panel_info.default_fps;
|
||||||
|
|
||||||
|
@ -2213,7 +2245,7 @@ static int mdss_mdp_video_early_wake_up(struct mdss_mdp_ctl *ctl)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl)
|
static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl, bool enable)
|
||||||
{
|
{
|
||||||
struct mdss_mdp_video_ctx *ctx = NULL, *sctx = NULL;
|
struct mdss_mdp_video_ctx *ctx = NULL, *sctx = NULL;
|
||||||
|
|
||||||
|
@ -2222,7 +2254,8 @@ static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl)
|
||||||
pr_err("invalid master ctx\n");
|
pr_err("invalid master ctx\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
mdss_mdp_video_avr_ctrl_setup(ctx, &ctl->avr_info, ctl->is_master);
|
mdss_mdp_video_avr_ctrl_setup(ctx, &ctl->avr_info, ctl->is_master,
|
||||||
|
enable);
|
||||||
|
|
||||||
if (is_pingpong_split(ctl->mfd)) {
|
if (is_pingpong_split(ctl->mfd)) {
|
||||||
sctx = (struct mdss_mdp_video_ctx *) ctl->intf_ctx[SLAVE_CTX];
|
sctx = (struct mdss_mdp_video_ctx *) ctl->intf_ctx[SLAVE_CTX];
|
||||||
|
@ -2230,7 +2263,8 @@ static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl)
|
||||||
pr_err("invalid slave ctx\n");
|
pr_err("invalid slave ctx\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
mdss_mdp_video_avr_ctrl_setup(sctx, &ctl->avr_info, false);
|
mdss_mdp_video_avr_ctrl_setup(sctx, &ctl->avr_info, false,
|
||||||
|
enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue