Loading drivers/video/msm/mdss/mdss.h +2 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,8 @@ struct mdss_data_type { bool mixer_switched; struct mdss_panel_cfg pan_cfg; struct mdss_prefill_data prefill_data; u32 min_prefill_lines; /* this changes within different chipsets */ u32 props; int handoff_pending; bool idle_pc; Loading drivers/video/msm/mdss/mdss_mdp.c +23 −0 Original line number Diff line number Diff line Loading @@ -1158,8 +1158,22 @@ static int mdss_mdp_debug_init(struct platform_device *pdev, return 0; } static u32 mdss_get_props(void) { u32 props = 0; void __iomem *props_base = ioremap(0xFC4B8114, 4); if (props_base) { props = readl_relaxed(props_base); iounmap(props_base); } return props; } static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) { /* prevent disable of prefill calculations */ mdata->min_prefill_lines = 0xffff; switch (mdata->mdp_rev) { case MDSS_MDP_HW_REV_105: case MDSS_MDP_HW_REV_109: Loading @@ -1171,6 +1185,13 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) mdss_set_quirk(mdata, MDSS_QUIRK_BWCPANIC); mdata->max_target_zorder = 4; /* excluding base layer */ mdata->max_cursor_size = 128; mdata->min_prefill_lines = 12; mdata->props = mdss_get_props(); break; case MDSS_MDP_HW_REV_107: mdata->max_target_zorder = 4; /* excluding base layer */ mdata->max_cursor_size = 64; mdata->min_prefill_lines = 21; break; default: mdata->max_target_zorder = 4; /* excluding base layer */ Loading Loading @@ -1470,6 +1491,8 @@ static ssize_t mdss_mdp_show_capabilities(struct device *dev, SPRINT("smp_mb_per_pipe=%d\n", mdata->smp_mb_per_pipe); SPRINT("max_downscale_ratio=%d\n", MAX_DOWNSCALE_RATIO); SPRINT("max_upscale_ratio=%d\n", MAX_UPSCALE_RATIO); if (mdata->props) SPRINT("props=%d", mdata->props); if (mdata->max_bw_low) SPRINT("max_bandwidth_low=%u\n", mdata->max_bw_low); if (mdata->max_bw_high) Loading drivers/video/msm/mdss/mdss_mdp.h +2 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ #define HORSCALER_NUM_FILTER_TAPS 8 #define HORSCALER_COEFF_NUM 17 #define MDP_MIN_VBP 4 #define MDP_MIN_FETCH 9 #define MAX_FREE_LIST_SIZE 12 #define OVERLAY_MAX 10 Loading Loading @@ -258,6 +257,7 @@ struct mdss_mdp_ctl { u32 perf_transaction_status; bool perf_release_ctl_bw; u64 bw_pending; bool disable_prefill; bool traffic_shaper_enabled; u32 traffic_shaper_mdp_clk; Loading Loading @@ -922,6 +922,7 @@ int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl); 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); int mdss_mdp_get_prefetch_lines(struct mdss_mdp_ctl *ctl); 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, Loading drivers/video/msm/mdss/mdss_mdp_ctl.c +63 −0 Original line number Diff line number Diff line Loading @@ -631,6 +631,7 @@ int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe, if (mixer->ctl->intf_num == MDSS_MDP_NO_INTF || mdata->disable_prefill || mixer->ctl->disable_prefill || (pipe->flags & MDP_SOLID_FILL)) { perf->prefill_bytes = 0; goto exit; Loading Loading @@ -859,6 +860,67 @@ exit: *(perf->bw_vote_mode)); } static bool is_mdp_prefetch_needed(struct mdss_mdp_ctl *ctl) { struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; struct mdss_data_type *mdata = ctl->mdata; bool enable_prefetch = false; if (mdata->mdp_rev >= MDSS_MDP_HW_REV_105) { if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width + pinfo->lcdc.v_front_porch) < mdata->min_prefill_lines) pr_warn_once("low vbp+vfp may lead to perf issues in some cases\n"); enable_prefetch = true; if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width) >= MDSS_MDP_MAX_PREFILL_FETCH) enable_prefetch = false; } else { if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width) < mdata->min_prefill_lines) pr_warn_once("low vbp may lead to display performance issues"); } return enable_prefetch; } /** * mdss_mdp_get_prefetch_lines: - Number of fetch lines in vertical front porch * @ctl: Pointer to controller where prefetch lines will be calculated * * 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 (25 - vbp - vpw) lines of vertical * front porch. */ int mdss_mdp_get_prefetch_lines(struct mdss_mdp_ctl *ctl) { int prefetch_avail = 0; int v_total, vfp_start; u32 prefetch_needed; struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; if (!is_mdp_prefetch_needed(ctl)) return 0; v_total = mdss_panel_get_vtotal(pinfo); vfp_start = (pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width + pinfo->yres); prefetch_avail = v_total - vfp_start; prefetch_needed = MDSS_MDP_MAX_PREFILL_FETCH - pinfo->lcdc.v_back_porch - pinfo->lcdc.v_pulse_width; if (prefetch_avail > prefetch_needed) prefetch_avail = prefetch_needed; return prefetch_avail; } static u32 mdss_mdp_get_vbp_factor(struct mdss_mdp_ctl *ctl) { u32 fps, v_total, vbp, vbp_fac; Loading Loading @@ -2153,6 +2215,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata, ctl->perf_release_ctl_bw = false; ctl->border_x_off = pinfo->lcdc.border_left; ctl->border_y_off = pinfo->lcdc.border_top; ctl->disable_prefill = false; switch (pdata->panel_info.type) { case EDP_PANEL: Loading drivers/video/msm/mdss/mdss_mdp_intf_video.c +19 −28 Original line number Diff line number Diff line Loading @@ -1119,30 +1119,18 @@ int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl, return ret; } static bool mdss_mdp_fetch_programable(struct mdss_mdp_ctl *ctl) static void mdss_mdp_disable_prefill(struct mdss_mdp_ctl *ctl) { struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; struct mdss_data_type *mdata; bool ret; mdata = ctl->mdata; struct mdss_data_type *mdata = ctl->mdata; if (mdata->mdp_rev >= MDSS_MDP_HW_REV_105) { if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_front_porch) < MDP_MIN_FETCH) { pr_warn_once("low vbp+vfp may lead to perf issues in some cases\n"); } ret = true; if (pinfo->lcdc.v_back_porch > MDP_MIN_FETCH) ret = false; } else { if (pinfo->lcdc.v_back_porch < MDP_MIN_FETCH) pr_warn_once("low vbp may lead to display performance issues"); ret = false; if ((ctl->prg_fet + pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width) > mdata->min_prefill_lines) { ctl->disable_prefill = true; pr_debug("disable prefill vbp:%d vpw:%d prg_fet:%d\n", pinfo->lcdc.v_back_porch, pinfo->lcdc.v_pulse_width, ctl->prg_fet); } return ret; } static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, Loading @@ -1154,9 +1142,9 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, mdata = ctl->mdata; if (!mdss_mdp_fetch_programable(ctl)) { ctl->prg_fet = mdss_mdp_get_prefetch_lines(ctl); if (!ctl->prg_fet) { pr_debug("programmable fetch is not needed/supported\n"); ctl->prg_fet = 0; return; } Loading @@ -1166,9 +1154,7 @@ 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); 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); Loading @@ -1176,7 +1162,9 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, DFPS_IMMEDIATE_CLK_UPDATE_MODE)) fetch_enable |= BIT(23); pr_debug("ctl:%d, fetch start=%d\n", ctl->num, fetch_start); pr_debug("ctl:%d fetch_start:%d lines:%d\n", ctl->num, fetch_start, ctl->prg_fet); mdp_video_write(ctx, MDSS_MDP_REG_INTF_PROG_FETCH_START, fetch_start); mdp_video_write(ctx, MDSS_MDP_REG_INTF_CONFIG, fetch_enable); } Loading @@ -1195,7 +1183,8 @@ static void mdss_mdp_handoff_programmable_fetch(struct mdss_mdp_ctl *ctl, 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); pr_debug("programmable fetch lines %d start:%d\n", ctl->prg_fet, fetch_start_handoff); } } Loading Loading @@ -1269,6 +1258,8 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, mdss_mdp_handoff_programmable_fetch(ctl, ctx); } mdss_mdp_disable_prefill(ctl); mdp_video_write(ctx, MDSS_MDP_REG_INTF_PANEL_FORMAT, ctl->dst_format); return 0; Loading Loading
drivers/video/msm/mdss/mdss.h +2 −0 Original line number Diff line number Diff line Loading @@ -277,6 +277,8 @@ struct mdss_data_type { bool mixer_switched; struct mdss_panel_cfg pan_cfg; struct mdss_prefill_data prefill_data; u32 min_prefill_lines; /* this changes within different chipsets */ u32 props; int handoff_pending; bool idle_pc; Loading
drivers/video/msm/mdss/mdss_mdp.c +23 −0 Original line number Diff line number Diff line Loading @@ -1158,8 +1158,22 @@ static int mdss_mdp_debug_init(struct platform_device *pdev, return 0; } static u32 mdss_get_props(void) { u32 props = 0; void __iomem *props_base = ioremap(0xFC4B8114, 4); if (props_base) { props = readl_relaxed(props_base); iounmap(props_base); } return props; } static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) { /* prevent disable of prefill calculations */ mdata->min_prefill_lines = 0xffff; switch (mdata->mdp_rev) { case MDSS_MDP_HW_REV_105: case MDSS_MDP_HW_REV_109: Loading @@ -1171,6 +1185,13 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) mdss_set_quirk(mdata, MDSS_QUIRK_BWCPANIC); mdata->max_target_zorder = 4; /* excluding base layer */ mdata->max_cursor_size = 128; mdata->min_prefill_lines = 12; mdata->props = mdss_get_props(); break; case MDSS_MDP_HW_REV_107: mdata->max_target_zorder = 4; /* excluding base layer */ mdata->max_cursor_size = 64; mdata->min_prefill_lines = 21; break; default: mdata->max_target_zorder = 4; /* excluding base layer */ Loading Loading @@ -1470,6 +1491,8 @@ static ssize_t mdss_mdp_show_capabilities(struct device *dev, SPRINT("smp_mb_per_pipe=%d\n", mdata->smp_mb_per_pipe); SPRINT("max_downscale_ratio=%d\n", MAX_DOWNSCALE_RATIO); SPRINT("max_upscale_ratio=%d\n", MAX_UPSCALE_RATIO); if (mdata->props) SPRINT("props=%d", mdata->props); if (mdata->max_bw_low) SPRINT("max_bandwidth_low=%u\n", mdata->max_bw_low); if (mdata->max_bw_high) Loading
drivers/video/msm/mdss/mdss_mdp.h +2 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ #define HORSCALER_NUM_FILTER_TAPS 8 #define HORSCALER_COEFF_NUM 17 #define MDP_MIN_VBP 4 #define MDP_MIN_FETCH 9 #define MAX_FREE_LIST_SIZE 12 #define OVERLAY_MAX 10 Loading Loading @@ -258,6 +257,7 @@ struct mdss_mdp_ctl { u32 perf_transaction_status; bool perf_release_ctl_bw; u64 bw_pending; bool disable_prefill; bool traffic_shaper_enabled; u32 traffic_shaper_mdp_clk; Loading Loading @@ -922,6 +922,7 @@ int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl); 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); int mdss_mdp_get_prefetch_lines(struct mdss_mdp_ctl *ctl); 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, Loading
drivers/video/msm/mdss/mdss_mdp_ctl.c +63 −0 Original line number Diff line number Diff line Loading @@ -631,6 +631,7 @@ int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe, if (mixer->ctl->intf_num == MDSS_MDP_NO_INTF || mdata->disable_prefill || mixer->ctl->disable_prefill || (pipe->flags & MDP_SOLID_FILL)) { perf->prefill_bytes = 0; goto exit; Loading Loading @@ -859,6 +860,67 @@ exit: *(perf->bw_vote_mode)); } static bool is_mdp_prefetch_needed(struct mdss_mdp_ctl *ctl) { struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; struct mdss_data_type *mdata = ctl->mdata; bool enable_prefetch = false; if (mdata->mdp_rev >= MDSS_MDP_HW_REV_105) { if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width + pinfo->lcdc.v_front_porch) < mdata->min_prefill_lines) pr_warn_once("low vbp+vfp may lead to perf issues in some cases\n"); enable_prefetch = true; if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width) >= MDSS_MDP_MAX_PREFILL_FETCH) enable_prefetch = false; } else { if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width) < mdata->min_prefill_lines) pr_warn_once("low vbp may lead to display performance issues"); } return enable_prefetch; } /** * mdss_mdp_get_prefetch_lines: - Number of fetch lines in vertical front porch * @ctl: Pointer to controller where prefetch lines will be calculated * * 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 (25 - vbp - vpw) lines of vertical * front porch. */ int mdss_mdp_get_prefetch_lines(struct mdss_mdp_ctl *ctl) { int prefetch_avail = 0; int v_total, vfp_start; u32 prefetch_needed; struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; if (!is_mdp_prefetch_needed(ctl)) return 0; v_total = mdss_panel_get_vtotal(pinfo); vfp_start = (pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width + pinfo->yres); prefetch_avail = v_total - vfp_start; prefetch_needed = MDSS_MDP_MAX_PREFILL_FETCH - pinfo->lcdc.v_back_porch - pinfo->lcdc.v_pulse_width; if (prefetch_avail > prefetch_needed) prefetch_avail = prefetch_needed; return prefetch_avail; } static u32 mdss_mdp_get_vbp_factor(struct mdss_mdp_ctl *ctl) { u32 fps, v_total, vbp, vbp_fac; Loading Loading @@ -2153,6 +2215,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata, ctl->perf_release_ctl_bw = false; ctl->border_x_off = pinfo->lcdc.border_left; ctl->border_y_off = pinfo->lcdc.border_top; ctl->disable_prefill = false; switch (pdata->panel_info.type) { case EDP_PANEL: Loading
drivers/video/msm/mdss/mdss_mdp_intf_video.c +19 −28 Original line number Diff line number Diff line Loading @@ -1119,30 +1119,18 @@ int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl, return ret; } static bool mdss_mdp_fetch_programable(struct mdss_mdp_ctl *ctl) static void mdss_mdp_disable_prefill(struct mdss_mdp_ctl *ctl) { struct mdss_panel_info *pinfo = &ctl->panel_data->panel_info; struct mdss_data_type *mdata; bool ret; mdata = ctl->mdata; struct mdss_data_type *mdata = ctl->mdata; if (mdata->mdp_rev >= MDSS_MDP_HW_REV_105) { if ((pinfo->lcdc.v_back_porch + pinfo->lcdc.v_front_porch) < MDP_MIN_FETCH) { pr_warn_once("low vbp+vfp may lead to perf issues in some cases\n"); } ret = true; if (pinfo->lcdc.v_back_porch > MDP_MIN_FETCH) ret = false; } else { if (pinfo->lcdc.v_back_porch < MDP_MIN_FETCH) pr_warn_once("low vbp may lead to display performance issues"); ret = false; if ((ctl->prg_fet + pinfo->lcdc.v_back_porch + pinfo->lcdc.v_pulse_width) > mdata->min_prefill_lines) { ctl->disable_prefill = true; pr_debug("disable prefill vbp:%d vpw:%d prg_fet:%d\n", pinfo->lcdc.v_back_porch, pinfo->lcdc.v_pulse_width, ctl->prg_fet); } return ret; } static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, Loading @@ -1154,9 +1142,9 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, mdata = ctl->mdata; if (!mdss_mdp_fetch_programable(ctl)) { ctl->prg_fet = mdss_mdp_get_prefetch_lines(ctl); if (!ctl->prg_fet) { pr_debug("programmable fetch is not needed/supported\n"); ctl->prg_fet = 0; return; } Loading @@ -1166,9 +1154,7 @@ 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); 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); Loading @@ -1176,7 +1162,9 @@ static void mdss_mdp_fetch_start_config(struct mdss_mdp_video_ctx *ctx, DFPS_IMMEDIATE_CLK_UPDATE_MODE)) fetch_enable |= BIT(23); pr_debug("ctl:%d, fetch start=%d\n", ctl->num, fetch_start); pr_debug("ctl:%d fetch_start:%d lines:%d\n", ctl->num, fetch_start, ctl->prg_fet); mdp_video_write(ctx, MDSS_MDP_REG_INTF_PROG_FETCH_START, fetch_start); mdp_video_write(ctx, MDSS_MDP_REG_INTF_CONFIG, fetch_enable); } Loading @@ -1195,7 +1183,8 @@ static void mdss_mdp_handoff_programmable_fetch(struct mdss_mdp_ctl *ctl, 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); pr_debug("programmable fetch lines %d start:%d\n", ctl->prg_fet, fetch_start_handoff); } } Loading Loading @@ -1269,6 +1258,8 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl, mdss_mdp_handoff_programmable_fetch(ctl, ctx); } mdss_mdp_disable_prefill(ctl); mdp_video_write(ctx, MDSS_MDP_REG_INTF_PANEL_FORMAT, ctl->dst_format); return 0; Loading