From dc4f43aa5d47330539198870136632cfd2334381 Mon Sep 17 00:00:00 2001 From: Benjamin Chan Date: Thu, 26 Jan 2017 14:11:22 -0500 Subject: [PATCH] msm: mdss: Correct video interface setup for AVR feature When DFPS is not being used and AVR is enabled, it is necessary to program the video interface with correct setting, including a timing engine flush and DSI video control. CRs-Fixed: 1109202 Change-Id: Iadb24da27715353ac3d4825ad053a1c039bd2ee6 Signed-off-by: Benjamin Chan --- drivers/video/fbdev/msm/mdss_dsi.c | 18 ++++++++++ drivers/video/fbdev/msm/mdss_mdp_intf_video.c | 36 ++++++++++++++++--- drivers/video/fbdev/msm/mdss_panel.h | 5 +++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 51745a9a59ac..c66d9f3b3a65 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -2183,6 +2183,21 @@ static int mdss_dsi_check_params(struct mdss_dsi_ctrl_pdata *ctrl, void *arg) return rc; } +static void mdss_dsi_avr_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata, + int enabled) +{ + u32 data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x10); + + /* DSI_VIDEO_MODE_CTRL */ + if (enabled) + data |= BIT(29); /* AVR_SUPPORT_ENABLED */ + else + data &= ~BIT(29); + + MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x10, data); + MDSS_XLOG(ctrl_pdata->ndx, enabled, data); +} + static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) { int rc = 0; @@ -2700,6 +2715,9 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, case MDSS_EVENT_DSI_TIMING_DB_CTRL: mdss_dsi_timing_db_ctrl(ctrl_pdata, (int)(unsigned long)arg); break; + case MDSS_EVENT_AVR_MODE: + mdss_dsi_avr_config(ctrl_pdata, (int)(unsigned long) arg); + break; default: pr_debug("%s: unhandled event=%d\n", __func__, event); break; diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 4efa38093557..663d63092ebf 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -106,6 +106,9 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, static void mdss_mdp_fetch_end_config(struct mdss_mdp_video_ctx *ctx, struct mdss_mdp_ctl *ctl); +static void mdss_mdp_video_timegen_flush(struct mdss_mdp_ctl *ctl, + struct mdss_mdp_video_ctx *sctx); + 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); @@ -411,6 +414,8 @@ static void mdss_mdp_video_avr_vtotal_setup(struct mdss_mdp_ctl *ctl, 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; @@ -435,6 +440,17 @@ static void mdss_mdp_video_avr_vtotal_setup(struct mdss_mdp_ctl *ctl, mdp_video_write(ctx, MDSS_MDP_REG_INTF_AVR_VTOTAL, avr_vtotal); + /* + * Make sure config goes through + */ + 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, ctx); + MDSS_XLOG(pinfo->min_fps, pinfo->default_fps, avr_vtotal); } } @@ -461,8 +477,9 @@ 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, - struct mdss_mdp_avr_info *avr_info, bool is_master, bool enable) + struct mdss_mdp_ctl *ctl, bool is_master, bool enable) { + struct mdss_mdp_avr_info *avr_info = &ctl->avr_info; u32 avr_ctrl = 0; u32 avr_mode = 0; @@ -475,9 +492,18 @@ static void mdss_mdp_video_avr_ctrl_setup(struct mdss_mdp_video_ctx *ctx, if (avr_mode == MDSS_MDP_AVR_ONE_SHOT) avr_mode |= (1 << 8); - if (is_master) + if (is_master) { mdp_video_write(ctx, MDSS_MDP_REG_INTF_AVR_CONTROL, avr_ctrl); + /* + * When AVR is enabled, need to setup DSI Video mode control + */ + mdss_mdp_ctl_intf_event(ctl, + MDSS_EVENT_AVR_MODE, + (void *)(unsigned long) avr_ctrl, + CTL_INTF_EVENT_FLAG_DEFAULT); + } + mdp_video_write(ctx, MDSS_MDP_REG_INTF_AVR_MODE, avr_mode); pr_debug("intf:%d avr_mode:%x avr_ctrl:%x\n", @@ -1435,7 +1461,6 @@ static int mdss_mdp_video_config_fps(struct mdss_mdp_ctl *ctl, int new_fps) } mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); - /* * Need to disable AVR during DFPS update period. * Next commit will restore the AVR settings. @@ -1844,6 +1869,7 @@ static void mdss_mdp_handoff_programmable_fetch(struct mdss_mdp_ctl *ctl, struct mdss_mdp_video_ctx *ctx) { struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; + u32 fetch_start_handoff, v_total_handoff, h_total_handoff; pinfo->prg_fet = 0; if (mdp_video_read(ctx, MDSS_MDP_REG_INTF_CONFIG) & BIT(31)) { @@ -2269,7 +2295,7 @@ static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl, bool enable) pr_err("invalid master ctx\n"); return -EINVAL; } - mdss_mdp_video_avr_ctrl_setup(ctx, &ctl->avr_info, ctl->is_master, + mdss_mdp_video_avr_ctrl_setup(ctx, ctl, ctl->is_master, enable); if (is_pingpong_split(ctl->mfd)) { @@ -2278,7 +2304,7 @@ static int mdss_mdp_video_avr_ctrl(struct mdss_mdp_ctl *ctl, bool enable) pr_err("invalid slave ctx\n"); return -EINVAL; } - mdss_mdp_video_avr_ctrl_setup(sctx, &ctl->avr_info, false, + mdss_mdp_video_avr_ctrl_setup(sctx, ctl, false, enable); } diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 3fc5b2226b3e..d73416e311b5 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -265,6 +265,10 @@ struct mdss_intf_recovery { * Argument provided is bits per pixel (8/10/12) * @MDSS_EVENT_UPDATE_PANEL_PPM: update pixel clock by input PPM. * Argument provided is parts per million. + * @MDSS_EVENT_AVR_MODE: Setup DSI Video mode to support AVR based on the + * avr mode passed as argument + * 0 - disable AVR support + * 1 - enable AVR support */ enum mdss_intf_events { MDSS_EVENT_RESET = 1, @@ -299,6 +303,7 @@ enum mdss_intf_events { MDSS_EVENT_DISABLE_PANEL, MDSS_EVENT_UPDATE_PANEL_PPM, MDSS_EVENT_DSI_TIMING_DB_CTRL, + MDSS_EVENT_AVR_MODE, MDSS_EVENT_MAX, };