From: Animesh Kishore Date: Tue, 24 Jul 2018 06:29:14 +0000 (+0530) Subject: msm: mdss: Constant fetch across dfps X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=43af76ad096644a650c9b4b165636fb498297f1d;p=sagit-ice-cold%2Fkernel_xiaomi_msm8998.git msm: mdss: Constant fetch across dfps Timing engine HW restricts changing programmable fetch start when off. Program constant fetch start in SW drivers. Fix fetch start is calculated based on panel DT timings. Change-Id: I2124c92b2f83d9c963e05c14421f61a08878d63b Signed-off-by: Animesh Kishore --- diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 54b792305eb5..43fc5eafb047 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1762,7 +1762,7 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff); int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl, int panel_power_mode); int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg, u32 flags); -int mdss_mdp_get_prefetch_lines(struct mdss_panel_info *pinfo); +int mdss_mdp_get_prefetch_lines(struct mdss_panel_info *pinfo, bool is_fixed); int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, struct mdss_mdp_pipe **left_plist, int left_cnt, struct mdss_mdp_pipe **right_plist, int right_cnt); diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 632d73e909a3..ec56bcf6e64e 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -1525,7 +1525,7 @@ static bool is_mdp_prefetch_needed(struct mdss_panel_info *pinfo) * the mdp fetch lines as the last (25 - vbp - vpw) lines of vertical * front porch. */ -int mdss_mdp_get_prefetch_lines(struct mdss_panel_info *pinfo) +int mdss_mdp_get_prefetch_lines(struct mdss_panel_info *pinfo, bool is_fixed) { int prefetch_avail = 0; int v_total, vfp_start; @@ -1534,7 +1534,11 @@ int mdss_mdp_get_prefetch_lines(struct mdss_panel_info *pinfo) if (!is_mdp_prefetch_needed(pinfo)) return 0; - v_total = mdss_panel_get_vtotal(pinfo); + if (is_fixed) + v_total = mdss_panel_get_vtotal_fixed(pinfo); + else + v_total = mdss_panel_get_vtotal(pinfo); + vfp_start = (pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width + pinfo->yres); diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c index 607c0647b505..e27f6bc49892 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c @@ -1120,6 +1120,7 @@ static void mdss_mdp_video_vsync_intr_done(void *arg) struct mdss_mdp_video_ctx *ctx = ctl->intf_ctx[MASTER_CTX]; struct mdss_mdp_vsync_handler *tmp; ktime_t vsync_time; + u32 ctl_flush_bits = 0; if (!ctx) { pr_err("invalid ctx\n"); @@ -1129,10 +1130,13 @@ static void mdss_mdp_video_vsync_intr_done(void *arg) vsync_time = ktime_get(); ctl->vsync_cnt++; - MDSS_XLOG(ctl->num, ctl->vsync_cnt, ctl->vsync_cnt); + ctl_flush_bits = mdss_mdp_ctl_read(ctl, MDSS_MDP_REG_CTL_FLUSH); - pr_debug("intr ctl=%d vsync cnt=%u vsync_time=%d\n", - ctl->num, ctl->vsync_cnt, (int)ktime_to_ms(vsync_time)); + MDSS_XLOG(ctl->num, ctl->vsync_cnt, ctl_flush_bits); + + pr_debug("intr ctl=%d vsync cnt=%u vsync_time=%d ctl_flush=%d\n", + ctl->num, ctl->vsync_cnt, (int)ktime_to_ms(vsync_time), + ctl_flush_bits); ctx->polling_en = false; complete_all(&ctx->vsync_comp); @@ -1901,6 +1905,7 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, mdata = ctl->mdata; + pinfo->prg_fet = mdss_mdp_get_prefetch_lines(pinfo, true); if (!pinfo->prg_fet) { pr_debug("programmable fetch is not needed/supported\n"); @@ -1919,7 +1924,7 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, * Fetch should always be outside the active lines. If the fetching * is programmed within active region, hardware behavior is unknown. */ - v_total = mdss_panel_get_vtotal(pinfo); + v_total = mdss_panel_get_vtotal_fixed(pinfo); h_total = mdss_panel_get_htotal(pinfo, true); fetch_start = (v_total - pinfo->prg_fet) * h_total + 1; @@ -2206,8 +2211,6 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, ctx->intf_num); return -EINVAL; } - - pinfo->prg_fet = mdss_mdp_get_prefetch_lines(pinfo); mdss_mdp_fetch_start_config(ctx, ctl); if (test_bit(MDSS_QOS_VBLANK_PANIC_CTRL, mdata->mdss_qos_map)) diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index 2f5b45638cdb..0000a1fec459 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -3367,9 +3367,6 @@ static void cache_initial_timings(struct mdss_panel_data *pdata) { if (!pdata->panel_info.default_fps) { - pdata->panel_info.default_prg_fet = - mdss_mdp_get_prefetch_lines(&pdata->panel_info); - /* * This value will change dynamically once the * actual dfps update happen in hw. @@ -3442,13 +3439,8 @@ static void dfps_update_panel_params(struct mdss_panel_data *pdata, dfps_update_fps(&pdata->panel_info, new_fps); - /* - * Fetch start is pinned to default fps. - * Adjust programmable fetch accordingly. - */ pdata->panel_info.prg_fet = - (pdata->panel_info.default_prg_fet) ? - (pdata->panel_info.default_prg_fet + add_v_lines) : 0; + mdss_mdp_get_prefetch_lines(&pdata->panel_info, false); } else if (pdata->panel_info.dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP) { diff --git a/drivers/video/fbdev/msm/mdss_panel.c b/drivers/video/fbdev/msm/mdss_panel.c index 31cf74274131..ffe9b19c3859 100644 --- a/drivers/video/fbdev/msm/mdss_panel.c +++ b/drivers/video/fbdev/msm/mdss_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -630,6 +630,7 @@ void mdss_panel_info_from_timing(struct mdss_panel_timing *pt, pinfo->yres = pt->yres; pinfo->lcdc.v_front_porch = pt->v_front_porch; + pinfo->lcdc.v_front_porch_fixed = pt->v_front_porch; pinfo->lcdc.v_back_porch = pt->v_back_porch; pinfo->lcdc.v_pulse_width = pt->v_pulse_width; diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 7085a9fd7200..acac672662c1 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -392,6 +392,7 @@ struct lcd_panel_info { u32 h_active_low; u32 v_back_porch; u32 v_front_porch; + u32 v_front_porch_fixed; u32 v_pulse_width; u32 v_active_low; u32 border_clr; @@ -814,8 +815,6 @@ struct mdss_panel_info { int new_fps; /* stores initial fps after boot */ u32 default_fps; - /* store programmable fetch corresponding to default fps */ - u32 default_prg_fet; /* stores initial vtotal (vfp-method) or htotal (hfp-method) */ u32 saved_total; /* stores initial vfp (vfp-method) or hfp (hfp-method) */ @@ -1063,6 +1062,23 @@ static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info) } /* + * mdss_panel_get_vtotal_fixed() - return panel device tree vertical height + * @pinfo: Pointer to panel info containing all panel information + * + * Returns the total height as defined in panel device tree including any + * blanking regions which are not visible to user but used to calculate + * panel clock. + */ +static inline int mdss_panel_get_vtotal_fixed(struct mdss_panel_info *pinfo) +{ + return pinfo->yres + pinfo->lcdc.v_back_porch + + pinfo->lcdc.v_front_porch_fixed + + pinfo->lcdc.v_pulse_width+ + pinfo->lcdc.border_top + + pinfo->lcdc.border_bottom; +} + +/* * mdss_panel_get_vtotal() - return panel vertical height * @pinfo: Pointer to panel info containing all panel information *