diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index a24df3559867..07c7753284df 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -300,7 +300,7 @@ struct mdss_mdp_ctl { void *priv_data; void *intf_ctx[2]; u32 wb_type; - bool prg_fet; + u32 prg_fet; struct mdss_mdp_writeback *wb; diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 4453e08f2206..36c933d5241c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -969,8 +969,7 @@ static u32 mdss_mdp_get_vbp_factor(struct mdss_mdp_ctl *ctl) fps = mdss_panel_get_framerate(pinfo); v_total = mdss_panel_get_vtotal(pinfo); vbp = pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width; - if (ctl->prg_fet) - vbp += mdss_mdp_max_fetch_lines(pinfo); + vbp += ctl->prg_fet; vbp_fac = (vbp) ? fps * v_total / vbp : 0; pr_debug("vbp_fac=%d vbp=%d v_total=%d\n", vbp_fac, vbp, v_total); diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 0c4973a8750b..360c1aa9eace 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -1175,7 +1175,7 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, if (!mdss_mdp_fetch_programable(ctl)) { pr_debug("programmable fetch is not needed/supported\n"); - ctl->prg_fet = false; + ctl->prg_fet = 0; return; } @@ -1185,15 +1185,16 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, */ v_total = mdss_panel_get_vtotal(pinfo); h_total = mdss_panel_get_htotal(pinfo, true); - fetch_start = (v_total - mdss_mdp_max_fetch_lines(pinfo)) * h_total + 1; + ctl->prg_fet = pinfo->lcdc.v_front_porch; + if (ctl->prg_fet > MDSS_MDP_MAX_FETCH) + ctl->prg_fet = MDSS_MDP_MAX_FETCH; + fetch_start = (v_total - ctl->prg_fet) * h_total + 1; fetch_enable = BIT(31); if (pinfo->dynamic_fps && (pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE)) fetch_enable |= BIT(23); - ctl->prg_fet = true; - pr_debug("ctl:%d, fetch start=%d\n", ctl->num, fetch_start); mdp_video_write(ctx, MDSS_MDP_REG_INTF_PROG_FETCH_START, fetch_start); mdp_video_write(ctx, MDSS_MDP_REG_INTF_CONFIG, fetch_enable); @@ -1243,6 +1244,24 @@ static int mdss_mdp_video_cdm_setup(struct mdss_mdp_cdm *cdm, return mdss_mdp_cdm_setup(cdm, &setup); } +static void mdss_mdp_handoff_programmable_fetch(struct mdss_mdp_ctl *ctl, + struct mdss_mdp_video_ctx *ctx) +{ + u32 fetch_start_handoff, v_total_handoff, h_total_handoff; + ctl->prg_fet = 0; + if (mdp_video_read(ctx, MDSS_MDP_REG_INTF_CONFIG) & BIT(31)) { + fetch_start_handoff = mdp_video_read(ctx, + MDSS_MDP_REG_INTF_PROG_FETCH_START); + h_total_handoff = mdp_video_read(ctx, + MDSS_MDP_REG_INTF_HSYNC_CTL) >> 16; + v_total_handoff = mdp_video_read(ctx, + MDSS_MDP_REG_INTF_VSYNC_PERIOD_F0)/h_total_handoff; + ctl->prg_fet = v_total_handoff - + ((fetch_start_handoff - 1)/h_total_handoff); + pr_debug("programmable fetch lines %d\n", ctl->prg_fet); + } +} + static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_video_ctx *ctx, struct mdss_panel_info *pinfo) { @@ -1338,6 +1357,8 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, return -EINVAL; } mdss_mdp_fetch_start_config(ctx, ctl); + } else { + mdss_mdp_handoff_programmable_fetch(ctl, ctx); } mdp_video_write(ctx, MDSS_MDP_REG_INTF_PANEL_FORMAT, ctl->dst_format); diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 0f91011be254..f91965e89bd7 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -571,33 +571,6 @@ static inline int mdss_panel_get_htotal(struct mdss_panel_info *pinfo, bool pinfo->lcdc.h_pulse_width; } -/** - * mdss_mdp_max_fetch_lines: - Number of fetch lines in vertical front porch - * @pinfo: Pointer to panel info containing all panel information - * - * Returns the number of fetch lines in vertical front porch at which mdp - * can start fetching the next frame. - * - * In some cases, vertical front porch is too high. In such cases limit - * the mdp fetch lines as the last 12 lines of vertical front porch. - */ -static inline int mdss_mdp_max_fetch_lines(struct mdss_panel_info *pinfo) -{ - int fetch_lines; - int v_total, vfp_start; - - v_total = mdss_panel_get_vtotal(pinfo); - vfp_start = (pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width + - pinfo->yres); - - fetch_lines = v_total - vfp_start; - - if (fetch_lines > MDSS_MDP_MAX_FETCH) - fetch_lines = MDSS_MDP_MAX_FETCH; - - return fetch_lines; -} - int mdss_register_panel(struct platform_device *pdev, struct mdss_panel_data *pdata);