summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c11
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c57
2 files changed, 46 insertions, 22 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 2c911ff566d2..f7bde6f1371c 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -5775,6 +5775,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
if (ctl->ops.avr_ctrl_fnc) {
+ /* avr_ctrl_fnc will configure both master & slave */
ret = ctl->ops.avr_ctrl_fnc(ctl, true);
if (ret) {
pr_err("error configuring avr ctrl registers ctl=%d err=%d\n",
@@ -5784,16 +5785,6 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
}
}
- if (sctl && sctl->ops.avr_ctrl_fnc) {
- ret = sctl->ops.avr_ctrl_fnc(sctl, true);
- if (ret) {
- pr_err("error configuring avr ctrl registers sctl=%d err=%d\n",
- sctl->num, ret);
- mutex_unlock(&ctl->lock);
- return ret;
- }
- }
-
mutex_lock(&ctl->flush_lock);
/*
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
index 13c70822e266..0c6678b81224 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -72,6 +72,7 @@ struct mdss_mdp_video_ctx {
u8 ref_cnt;
u8 timegen_en;
+ bool timegen_flush_pending;
bool polling_en;
u32 poll_cnt;
struct completion vsync_comp;
@@ -451,13 +452,32 @@ static int mdss_mdp_video_intf_recovery(void *data, int event)
}
}
+static int mdss_mdp_video_wait_one_frame(struct mdss_mdp_ctl *ctl)
+{
+ u32 frame_time, frame_rate;
+ int ret = 0;
+ struct mdss_panel_data *pdata = ctl->panel_data;
+
+ if (pdata == NULL) {
+ frame_rate = DEFAULT_FRAME_RATE;
+ } else {
+ frame_rate = mdss_panel_get_framerate(&pdata->panel_info);
+ if (!(frame_rate >= 24 && frame_rate <= 240))
+ frame_rate = 24;
+ }
+
+ frame_time = ((1000/frame_rate) + 1);
+
+ msleep(frame_time);
+
+ return ret;
+}
+
static void mdss_mdp_video_avr_vtotal_setup(struct mdss_mdp_ctl *ctl,
struct intf_timing_params *p,
struct mdss_mdp_video_ctx *ctx)
{
struct mdss_data_type *mdata = ctl->mdata;
- struct mdss_mdp_ctl *sctl = NULL;
- struct mdss_mdp_video_ctx *sctx = NULL;
if (test_bit(MDSS_CAPS_AVR_SUPPORTED, mdata->mdss_caps_map)) {
struct mdss_panel_data *pdata = ctl->panel_data;
@@ -484,14 +504,11 @@ static void mdss_mdp_video_avr_vtotal_setup(struct mdss_mdp_ctl *ctl,
/*
* Make sure config goes through
+ * and queue timegen flush
*/
wmb();
- sctl = mdss_mdp_get_split_ctl(ctl);
- if (sctl)
- sctx = (struct mdss_mdp_video_ctx *)
- sctl->intf_ctx[MASTER_CTX];
- mdss_mdp_video_timegen_flush(ctl, sctx);
+ ctx->timegen_flush_pending = true;
MDSS_XLOG(pinfo->min_fps, pinfo->default_fps, avr_vtotal);
}
@@ -2464,25 +2481,41 @@ static int mdss_mdp_video_early_wake_up(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_ctl *sctl;
ctx = (struct mdss_mdp_video_ctx *) ctl->intf_ctx[MASTER_CTX];
if (!ctx || !ctx->ref_cnt) {
pr_err("invalid master ctx\n");
return -EINVAL;
}
- mdss_mdp_video_avr_ctrl_setup(ctx, ctl, ctl->is_master,
- enable);
- if (is_pingpong_split(ctl->mfd)) {
+ sctl = mdss_mdp_get_split_ctl(ctl);
+ if (sctl) {
+ sctx = (struct mdss_mdp_video_ctx *) sctl->intf_ctx[MASTER_CTX];
+ } else if (is_pingpong_split(ctl->mfd)) {
sctx = (struct mdss_mdp_video_ctx *) ctl->intf_ctx[SLAVE_CTX];
if (!sctx || !sctx->ref_cnt) {
pr_err("invalid slave ctx\n");
return -EINVAL;
}
- mdss_mdp_video_avr_ctrl_setup(sctx, ctl, false,
- enable);
}
+ if (ctx->timegen_flush_pending) {
+ mdss_mdp_video_timegen_flush(ctl, sctx);
+
+ /* wait a frame for flush to be completed */
+ mdss_mdp_video_wait_one_frame(ctl);
+
+ ctx->timegen_flush_pending = false;
+ if (sctx)
+ sctx->timegen_flush_pending = false;
+ }
+
+ mdss_mdp_video_avr_ctrl_setup(ctx, ctl, ctl->is_master, enable);
+
+ if (sctx)
+ mdss_mdp_video_avr_ctrl_setup(sctx, ctl, false, enable);
+
return 0;
}