Loading drivers/video/msm/mdss/mdss.h +10 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,14 @@ struct mdss_intr { spinlock_t lock; }; struct simplified_prefill_factors { u32 fmt_mt_nv12_factor; u32 fmt_mt_factor; u32 fmt_linear_factor; u32 scale_factor; u32 xtra_ff_factor; }; struct mdss_prefill_data { u32 ot_bytes; u32 y_buf_bytes; Loading @@ -105,6 +113,7 @@ struct mdss_prefill_data { u32 post_scaler_pixels; u32 pp_pixels; u32 fbc_lines; struct simplified_prefill_factors prefill_factors; }; struct mdss_mdp_ppb { Loading Loading @@ -163,6 +172,7 @@ enum mdss_qos_settings { MDSS_QOS_CDP, MDSS_QOS_OTLIM, MDSS_QOS_PER_PIPE_LUT, MDSS_QOS_SIMPLIFIED_PREFILL, MDSS_QOS_MAX, }; Loading drivers/video/msm/mdss/mdss_fb.c +15 −2 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ #define CREATE_TRACE_POINTS #include "mdss_debug.h" #include "mdss_smmu.h" #include "mdss_mdp.h" #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER #define MDSS_FB_NUM 3 Loading Loading @@ -1448,6 +1449,9 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd) } if (mfd->mdp.on_fnc) { struct mdss_panel_info *panel_info = mfd->panel_info; struct fb_var_screeninfo *var = &mfd->fbi->var; ret = mfd->mdp.on_fnc(mfd); if (ret) { mdss_fb_stop_disp_thread(mfd); Loading @@ -1461,6 +1465,13 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd) mfd->update.is_suspend = 0; mutex_unlock(&mfd->update.lock); /* * Panel info can change depending in the information * programmed in the controller. * Update this info in the upstream structs. */ mdss_panelinfo_to_fb_var(panel_info, var); /* Start the work thread to signal idle time */ if (mfd->idle_time) schedule_delayed_work(&mfd->idle_notify_work, Loading Loading @@ -3096,8 +3107,10 @@ static void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo, var->xres = mdss_fb_get_panel_xres(&pdata->panel_info); var->yres = pinfo->yres; var->lower_margin = pinfo->lcdc.v_front_porch; var->upper_margin = pinfo->lcdc.v_back_porch; var->lower_margin = pinfo->lcdc.v_front_porch - pinfo->prg_fet; var->upper_margin = pinfo->lcdc.v_back_porch + pinfo->prg_fet; var->vsync_len = pinfo->lcdc.v_pulse_width; var->right_margin = pinfo->lcdc.h_front_porch; var->left_margin = pinfo->lcdc.h_back_porch; Loading drivers/video/msm/mdss/mdss_mdp.c +25 −0 Original line number Diff line number Diff line Loading @@ -1051,6 +1051,15 @@ static u32 mdss_get_props(void) return props; } void mdss_mdp_init_default_prefill_factors(struct mdss_data_type *mdata) { mdata->prefill_data.prefill_factors.fmt_mt_nv12_factor = 8; mdata->prefill_data.prefill_factors.fmt_mt_factor = 4; mdata->prefill_data.prefill_factors.fmt_linear_factor = 1; mdata->prefill_data.prefill_factors.scale_factor = 1; mdata->prefill_data.prefill_factors.xtra_ff_factor = 2; } static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) { Loading Loading @@ -1078,9 +1087,11 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) set_bit(MDSS_QOS_CDP, mdata->mdss_qos_map); set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map); set_bit(MDSS_QOS_PER_PIPE_LUT, mdata->mdss_qos_map); set_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map); set_bit(MDSS_CAPS_YUV_CONFIG, mdata->mdss_caps_map); set_bit(MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED, mdata->mdss_caps_map); mdss_mdp_init_default_prefill_factors(mdata); break; case MDSS_MDP_HW_REV_105: case MDSS_MDP_HW_REV_109: Loading Loading @@ -1398,6 +1409,20 @@ 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 (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) { SPRINT("fmt_mt_nv12_factor=%d\n", mdata->prefill_data.prefill_factors.fmt_mt_nv12_factor); SPRINT("fmt_mt_factor=%d\n", mdata->prefill_data.prefill_factors.fmt_mt_factor); SPRINT("fmt_linear_factor=%d\n", mdata->prefill_data.prefill_factors.fmt_linear_factor); SPRINT("scale_factor=%d\n", mdata->prefill_data.prefill_factors.scale_factor); SPRINT("xtra_ff_factor=%d\n", mdata->prefill_data.prefill_factors.xtra_ff_factor); } if (mdata->props) SPRINT("props=%d", mdata->props); if (mdata->max_bw_low) Loading drivers/video/msm/mdss/mdss_mdp.h +0 −1 Original line number Diff line number Diff line Loading @@ -304,7 +304,6 @@ struct mdss_mdp_ctl { void *priv_data; void *intf_ctx[2]; u32 wb_type; u32 prg_fet; struct mdss_mdp_writeback *wb; Loading drivers/video/msm/mdss/mdss_mdp_ctl.c +100 −13 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ static inline u64 apply_inverse_fudge_factor(u64 val, static DEFINE_MUTEX(mdss_mdp_ctl_lock); static inline int __mdss_mdp_ctl_get_mixer_off(struct mdss_mdp_mixer *mixer); static u32 mdss_mdp_get_vbp_factor_max(struct mdss_mdp_ctl *ctl); static inline u32 mdss_mdp_get_pclk_rate(struct mdss_mdp_ctl *ctl) { Loading Loading @@ -623,6 +624,59 @@ u32 mdss_apply_overhead_factors(u32 quota, bool is_nrt, return quota; } u64 mdss_mdp_perf_calc_simplified_prefill(struct mdss_mdp_pipe *pipe, u32 v_total, u32 fps, struct mdss_mdp_ctl *ctl) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); struct simplified_prefill_factors *pfactors = &mdata->prefill_data.prefill_factors; u64 prefill_per_pipe = 0; u32 prefill_lines = pfactors->xtra_ff_factor; /* do not calculate prefill for command mode */ if (!ctl->is_video_mode) goto exit; prefill_per_pipe = pipe->src.w * pipe->src_fmt->bpp; /* format factors */ if (mdss_mdp_is_tile_format(pipe->src_fmt)) { if (mdss_mdp_is_nv12_format(pipe->src_fmt)) prefill_lines += pfactors->fmt_mt_nv12_factor; else prefill_lines += pfactors->fmt_mt_factor; } else { prefill_lines += pfactors->fmt_linear_factor; } /* scaling factors */ if (pipe->src.h > pipe->dst.h) { prefill_lines += pfactors->scale_factor; prefill_per_pipe = fudge_factor(prefill_per_pipe, DECIMATED_DIMENSION(pipe->src.h, pipe->vert_deci), pipe->dst.h); } prefill_per_pipe *= prefill_lines * mdss_mdp_get_vbp_factor_max(ctl); pr_debug("pipe src: %dx%d bpp:%d\n", pipe->src.w, pipe->src.h, pipe->src_fmt->bpp); pr_debug("ff_factor:%d mt_nv12:%d mt:%d\n", pfactors->xtra_ff_factor, (mdss_mdp_is_tile_format(pipe->src_fmt) && mdss_mdp_is_nv12_format(pipe->src_fmt)) ? pfactors->fmt_mt_nv12_factor : 0, mdss_mdp_is_tile_format(pipe->src_fmt) ? pfactors->fmt_mt_factor : 0); pr_debug("pipe prefill:%llu lines:%d\n", prefill_per_pipe, prefill_lines); exit: return prefill_per_pipe; } /** * mdss_mdp_perf_calc_pipe() - calculate performance numbers required by pipe * @pipe: Source pipe struct containing updated pipe params Loading Loading @@ -773,6 +827,13 @@ int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe, mixer->ctl->disable_prefill || (pipe->flags & MDP_SOLID_FILL)) { perf->prefill_bytes = 0; perf->bw_prefill = 0; goto exit; } if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) { perf->bw_prefill = mdss_mdp_perf_calc_simplified_prefill(pipe, v_total, fps, mixer->ctl); goto exit; } Loading Loading @@ -810,9 +871,9 @@ int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe, mdss_mdp_perf_calc_pipe_prefill_cmd(&prefill_params); exit: pr_debug("mixer=%d pnum=%d clk_rate=%u bw_overlap=%llu prefill=%d %s\n", pr_debug("mixer=%d pnum=%d clk_rate=%u bw_overlap=%llu bw_prefill=%llu (%d) %s\n", mixer->num, pipe->num, perf->mdp_clk_rate, perf->bw_overlap, perf->prefill_bytes, mdata->disable_prefill ? perf->bw_prefill, perf->prefill_bytes, mdata->disable_prefill ? "prefill is disabled" : ""); return 0; Loading Loading @@ -843,7 +904,7 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, u64 bw_overlap[MAX_PIPES_PER_LM] = { 0 }; u64 bw_overlap_async = 0; u32 v_region[MAX_PIPES_PER_LM * 2] = { 0 }; u32 prefill_bytes = 0; u32 prefill_val = 0; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); bool apply_fudge = true; struct mdss_mdp_format_params *fmt; Loading Loading @@ -965,8 +1026,6 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, bitmap_or(perf->bw_vote_mode, perf->bw_vote_mode, tmp.bw_vote_mode, MDSS_MDP_BW_MODE_MAX); prefill_bytes += tmp.prefill_bytes; /* * for async layers, the overlap calculation is skipped * and the bandwidth is added at the end, accounting for Loading @@ -986,6 +1045,11 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, if (tmp.mdp_clk_rate > max_clk_rate) max_clk_rate = tmp.mdp_clk_rate; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) prefill_val += tmp.bw_prefill; else prefill_val += tmp.prefill_bytes; } /* Loading Loading @@ -1020,7 +1084,11 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, } perf->bw_overlap += bw_overlap_max + bw_overlap_async; perf->prefill_bytes += prefill_bytes; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) perf->bw_prefill += prefill_val; else perf->prefill_bytes += prefill_val; if (max_clk_rate > perf->mdp_clk_rate) perf->mdp_clk_rate = max_clk_rate; Loading @@ -1028,7 +1096,7 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, exit: pr_debug("final mixer=%d video=%d clk_rate=%u bw=%llu prefill=%d mode=0x%lx\n", mixer->num, mixer->ctl->is_video_mode, perf->mdp_clk_rate, perf->bw_overlap, perf->prefill_bytes, perf->bw_overlap, prefill_val, *(perf->bw_vote_mode)); } Loading Loading @@ -1105,7 +1173,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; vbp += ctl->prg_fet; vbp += pinfo->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); Loading @@ -1127,6 +1195,11 @@ static u32 mdss_mdp_get_vbp_factor_max(struct mdss_mdp_ctl *ctl) struct mdss_mdp_ctl *ctl = mdata->ctl_off + i; u32 vbp_fac; /* skip command mode interfaces */ if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map) && !ctl->is_video_mode) continue; if (mdss_mdp_ctl_is_power_on(ctl)) { vbp_fac = mdss_mdp_get_vbp_factor(ctl); vbp_max = max(vbp_max, vbp_fac); Loading Loading @@ -1165,6 +1238,7 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, u32 flags) { struct mdss_mdp_perf_params tmp; struct mdss_data_type *mdata = ctl->mdata; memset(perf, 0, sizeof(*perf)); Loading @@ -1177,9 +1251,13 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, perf->max_per_pipe_ib = tmp.max_per_pipe_ib; perf->bw_overlap += tmp.bw_overlap; perf->prefill_bytes += tmp.prefill_bytes; perf->mdp_clk_rate = tmp.mdp_clk_rate; perf->bw_writeback += tmp.bw_writeback; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) perf->bw_prefill += tmp.bw_prefill; else perf->prefill_bytes += tmp.prefill_bytes; } if (ctl->mixer_right) { Loading @@ -1192,11 +1270,15 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, perf->max_per_pipe_ib = max(perf->max_per_pipe_ib, tmp.max_per_pipe_ib); perf->bw_overlap += tmp.bw_overlap; perf->prefill_bytes += tmp.prefill_bytes; perf->bw_writeback += tmp.bw_writeback; if (tmp.mdp_clk_rate > perf->mdp_clk_rate) perf->mdp_clk_rate = tmp.mdp_clk_rate; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) perf->bw_prefill += tmp.bw_prefill; else perf->prefill_bytes += tmp.prefill_bytes; if (ctl->intf_type) { u32 clk_rate = mdss_mdp_get_pclk_rate(ctl); /* minimum clock rate due to inefficiency in 3dmux */ Loading @@ -1210,7 +1292,8 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, if (perf->bw_overlap == 0) perf->bw_overlap = SZ_16M; if (ctl->intf_type != MDSS_MDP_NO_INTF) { if (!test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map) && (ctl->intf_type != MDSS_MDP_NO_INTF)) { u32 vbp_fac = mdss_mdp_get_vbp_factor_max(ctl); perf->bw_prefill = perf->prefill_bytes; Loading Loading @@ -1368,8 +1451,12 @@ int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, if (ctl->intf_type == MDSS_MDP_NO_INTF) return 0; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) { prefill_bw = perf->bw_prefill; } else { vbp_fac = mdss_mdp_get_vbp_factor_max(ctl); prefill_bw = perf->prefill_bytes * vbp_fac; } pipe_bw = max(prefill_bw, perf->bw_overlap); pr_debug("prefill=%llu, vbp_fac=%u, overlap=%llu\n", prefill_bw, vbp_fac, perf->bw_overlap); Loading Loading
drivers/video/msm/mdss/mdss.h +10 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,14 @@ struct mdss_intr { spinlock_t lock; }; struct simplified_prefill_factors { u32 fmt_mt_nv12_factor; u32 fmt_mt_factor; u32 fmt_linear_factor; u32 scale_factor; u32 xtra_ff_factor; }; struct mdss_prefill_data { u32 ot_bytes; u32 y_buf_bytes; Loading @@ -105,6 +113,7 @@ struct mdss_prefill_data { u32 post_scaler_pixels; u32 pp_pixels; u32 fbc_lines; struct simplified_prefill_factors prefill_factors; }; struct mdss_mdp_ppb { Loading Loading @@ -163,6 +172,7 @@ enum mdss_qos_settings { MDSS_QOS_CDP, MDSS_QOS_OTLIM, MDSS_QOS_PER_PIPE_LUT, MDSS_QOS_SIMPLIFIED_PREFILL, MDSS_QOS_MAX, }; Loading
drivers/video/msm/mdss/mdss_fb.c +15 −2 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ #define CREATE_TRACE_POINTS #include "mdss_debug.h" #include "mdss_smmu.h" #include "mdss_mdp.h" #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER #define MDSS_FB_NUM 3 Loading Loading @@ -1448,6 +1449,9 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd) } if (mfd->mdp.on_fnc) { struct mdss_panel_info *panel_info = mfd->panel_info; struct fb_var_screeninfo *var = &mfd->fbi->var; ret = mfd->mdp.on_fnc(mfd); if (ret) { mdss_fb_stop_disp_thread(mfd); Loading @@ -1461,6 +1465,13 @@ static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd) mfd->update.is_suspend = 0; mutex_unlock(&mfd->update.lock); /* * Panel info can change depending in the information * programmed in the controller. * Update this info in the upstream structs. */ mdss_panelinfo_to_fb_var(panel_info, var); /* Start the work thread to signal idle time */ if (mfd->idle_time) schedule_delayed_work(&mfd->idle_notify_work, Loading Loading @@ -3096,8 +3107,10 @@ static void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo, var->xres = mdss_fb_get_panel_xres(&pdata->panel_info); var->yres = pinfo->yres; var->lower_margin = pinfo->lcdc.v_front_porch; var->upper_margin = pinfo->lcdc.v_back_porch; var->lower_margin = pinfo->lcdc.v_front_porch - pinfo->prg_fet; var->upper_margin = pinfo->lcdc.v_back_porch + pinfo->prg_fet; var->vsync_len = pinfo->lcdc.v_pulse_width; var->right_margin = pinfo->lcdc.h_front_porch; var->left_margin = pinfo->lcdc.h_back_porch; Loading
drivers/video/msm/mdss/mdss_mdp.c +25 −0 Original line number Diff line number Diff line Loading @@ -1051,6 +1051,15 @@ static u32 mdss_get_props(void) return props; } void mdss_mdp_init_default_prefill_factors(struct mdss_data_type *mdata) { mdata->prefill_data.prefill_factors.fmt_mt_nv12_factor = 8; mdata->prefill_data.prefill_factors.fmt_mt_factor = 4; mdata->prefill_data.prefill_factors.fmt_linear_factor = 1; mdata->prefill_data.prefill_factors.scale_factor = 1; mdata->prefill_data.prefill_factors.xtra_ff_factor = 2; } static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) { Loading Loading @@ -1078,9 +1087,11 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) set_bit(MDSS_QOS_CDP, mdata->mdss_qos_map); set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map); set_bit(MDSS_QOS_PER_PIPE_LUT, mdata->mdss_qos_map); set_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map); set_bit(MDSS_CAPS_YUV_CONFIG, mdata->mdss_caps_map); set_bit(MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED, mdata->mdss_caps_map); mdss_mdp_init_default_prefill_factors(mdata); break; case MDSS_MDP_HW_REV_105: case MDSS_MDP_HW_REV_109: Loading Loading @@ -1398,6 +1409,20 @@ 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 (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) { SPRINT("fmt_mt_nv12_factor=%d\n", mdata->prefill_data.prefill_factors.fmt_mt_nv12_factor); SPRINT("fmt_mt_factor=%d\n", mdata->prefill_data.prefill_factors.fmt_mt_factor); SPRINT("fmt_linear_factor=%d\n", mdata->prefill_data.prefill_factors.fmt_linear_factor); SPRINT("scale_factor=%d\n", mdata->prefill_data.prefill_factors.scale_factor); SPRINT("xtra_ff_factor=%d\n", mdata->prefill_data.prefill_factors.xtra_ff_factor); } if (mdata->props) SPRINT("props=%d", mdata->props); if (mdata->max_bw_low) Loading
drivers/video/msm/mdss/mdss_mdp.h +0 −1 Original line number Diff line number Diff line Loading @@ -304,7 +304,6 @@ struct mdss_mdp_ctl { void *priv_data; void *intf_ctx[2]; u32 wb_type; u32 prg_fet; struct mdss_mdp_writeback *wb; Loading
drivers/video/msm/mdss/mdss_mdp_ctl.c +100 −13 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ static inline u64 apply_inverse_fudge_factor(u64 val, static DEFINE_MUTEX(mdss_mdp_ctl_lock); static inline int __mdss_mdp_ctl_get_mixer_off(struct mdss_mdp_mixer *mixer); static u32 mdss_mdp_get_vbp_factor_max(struct mdss_mdp_ctl *ctl); static inline u32 mdss_mdp_get_pclk_rate(struct mdss_mdp_ctl *ctl) { Loading Loading @@ -623,6 +624,59 @@ u32 mdss_apply_overhead_factors(u32 quota, bool is_nrt, return quota; } u64 mdss_mdp_perf_calc_simplified_prefill(struct mdss_mdp_pipe *pipe, u32 v_total, u32 fps, struct mdss_mdp_ctl *ctl) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); struct simplified_prefill_factors *pfactors = &mdata->prefill_data.prefill_factors; u64 prefill_per_pipe = 0; u32 prefill_lines = pfactors->xtra_ff_factor; /* do not calculate prefill for command mode */ if (!ctl->is_video_mode) goto exit; prefill_per_pipe = pipe->src.w * pipe->src_fmt->bpp; /* format factors */ if (mdss_mdp_is_tile_format(pipe->src_fmt)) { if (mdss_mdp_is_nv12_format(pipe->src_fmt)) prefill_lines += pfactors->fmt_mt_nv12_factor; else prefill_lines += pfactors->fmt_mt_factor; } else { prefill_lines += pfactors->fmt_linear_factor; } /* scaling factors */ if (pipe->src.h > pipe->dst.h) { prefill_lines += pfactors->scale_factor; prefill_per_pipe = fudge_factor(prefill_per_pipe, DECIMATED_DIMENSION(pipe->src.h, pipe->vert_deci), pipe->dst.h); } prefill_per_pipe *= prefill_lines * mdss_mdp_get_vbp_factor_max(ctl); pr_debug("pipe src: %dx%d bpp:%d\n", pipe->src.w, pipe->src.h, pipe->src_fmt->bpp); pr_debug("ff_factor:%d mt_nv12:%d mt:%d\n", pfactors->xtra_ff_factor, (mdss_mdp_is_tile_format(pipe->src_fmt) && mdss_mdp_is_nv12_format(pipe->src_fmt)) ? pfactors->fmt_mt_nv12_factor : 0, mdss_mdp_is_tile_format(pipe->src_fmt) ? pfactors->fmt_mt_factor : 0); pr_debug("pipe prefill:%llu lines:%d\n", prefill_per_pipe, prefill_lines); exit: return prefill_per_pipe; } /** * mdss_mdp_perf_calc_pipe() - calculate performance numbers required by pipe * @pipe: Source pipe struct containing updated pipe params Loading Loading @@ -773,6 +827,13 @@ int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe, mixer->ctl->disable_prefill || (pipe->flags & MDP_SOLID_FILL)) { perf->prefill_bytes = 0; perf->bw_prefill = 0; goto exit; } if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) { perf->bw_prefill = mdss_mdp_perf_calc_simplified_prefill(pipe, v_total, fps, mixer->ctl); goto exit; } Loading Loading @@ -810,9 +871,9 @@ int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe, mdss_mdp_perf_calc_pipe_prefill_cmd(&prefill_params); exit: pr_debug("mixer=%d pnum=%d clk_rate=%u bw_overlap=%llu prefill=%d %s\n", pr_debug("mixer=%d pnum=%d clk_rate=%u bw_overlap=%llu bw_prefill=%llu (%d) %s\n", mixer->num, pipe->num, perf->mdp_clk_rate, perf->bw_overlap, perf->prefill_bytes, mdata->disable_prefill ? perf->bw_prefill, perf->prefill_bytes, mdata->disable_prefill ? "prefill is disabled" : ""); return 0; Loading Loading @@ -843,7 +904,7 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, u64 bw_overlap[MAX_PIPES_PER_LM] = { 0 }; u64 bw_overlap_async = 0; u32 v_region[MAX_PIPES_PER_LM * 2] = { 0 }; u32 prefill_bytes = 0; u32 prefill_val = 0; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); bool apply_fudge = true; struct mdss_mdp_format_params *fmt; Loading Loading @@ -965,8 +1026,6 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, bitmap_or(perf->bw_vote_mode, perf->bw_vote_mode, tmp.bw_vote_mode, MDSS_MDP_BW_MODE_MAX); prefill_bytes += tmp.prefill_bytes; /* * for async layers, the overlap calculation is skipped * and the bandwidth is added at the end, accounting for Loading @@ -986,6 +1045,11 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, if (tmp.mdp_clk_rate > max_clk_rate) max_clk_rate = tmp.mdp_clk_rate; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) prefill_val += tmp.bw_prefill; else prefill_val += tmp.prefill_bytes; } /* Loading Loading @@ -1020,7 +1084,11 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, } perf->bw_overlap += bw_overlap_max + bw_overlap_async; perf->prefill_bytes += prefill_bytes; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) perf->bw_prefill += prefill_val; else perf->prefill_bytes += prefill_val; if (max_clk_rate > perf->mdp_clk_rate) perf->mdp_clk_rate = max_clk_rate; Loading @@ -1028,7 +1096,7 @@ static void mdss_mdp_perf_calc_mixer(struct mdss_mdp_mixer *mixer, exit: pr_debug("final mixer=%d video=%d clk_rate=%u bw=%llu prefill=%d mode=0x%lx\n", mixer->num, mixer->ctl->is_video_mode, perf->mdp_clk_rate, perf->bw_overlap, perf->prefill_bytes, perf->bw_overlap, prefill_val, *(perf->bw_vote_mode)); } Loading Loading @@ -1105,7 +1173,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; vbp += ctl->prg_fet; vbp += pinfo->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); Loading @@ -1127,6 +1195,11 @@ static u32 mdss_mdp_get_vbp_factor_max(struct mdss_mdp_ctl *ctl) struct mdss_mdp_ctl *ctl = mdata->ctl_off + i; u32 vbp_fac; /* skip command mode interfaces */ if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map) && !ctl->is_video_mode) continue; if (mdss_mdp_ctl_is_power_on(ctl)) { vbp_fac = mdss_mdp_get_vbp_factor(ctl); vbp_max = max(vbp_max, vbp_fac); Loading Loading @@ -1165,6 +1238,7 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, u32 flags) { struct mdss_mdp_perf_params tmp; struct mdss_data_type *mdata = ctl->mdata; memset(perf, 0, sizeof(*perf)); Loading @@ -1177,9 +1251,13 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, perf->max_per_pipe_ib = tmp.max_per_pipe_ib; perf->bw_overlap += tmp.bw_overlap; perf->prefill_bytes += tmp.prefill_bytes; perf->mdp_clk_rate = tmp.mdp_clk_rate; perf->bw_writeback += tmp.bw_writeback; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) perf->bw_prefill += tmp.bw_prefill; else perf->prefill_bytes += tmp.prefill_bytes; } if (ctl->mixer_right) { Loading @@ -1192,11 +1270,15 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, perf->max_per_pipe_ib = max(perf->max_per_pipe_ib, tmp.max_per_pipe_ib); perf->bw_overlap += tmp.bw_overlap; perf->prefill_bytes += tmp.prefill_bytes; perf->bw_writeback += tmp.bw_writeback; if (tmp.mdp_clk_rate > perf->mdp_clk_rate) perf->mdp_clk_rate = tmp.mdp_clk_rate; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) perf->bw_prefill += tmp.bw_prefill; else perf->prefill_bytes += tmp.prefill_bytes; if (ctl->intf_type) { u32 clk_rate = mdss_mdp_get_pclk_rate(ctl); /* minimum clock rate due to inefficiency in 3dmux */ Loading @@ -1210,7 +1292,8 @@ static void __mdss_mdp_perf_calc_ctl_helper(struct mdss_mdp_ctl *ctl, if (perf->bw_overlap == 0) perf->bw_overlap = SZ_16M; if (ctl->intf_type != MDSS_MDP_NO_INTF) { if (!test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map) && (ctl->intf_type != MDSS_MDP_NO_INTF)) { u32 vbp_fac = mdss_mdp_get_vbp_factor_max(ctl); perf->bw_prefill = perf->prefill_bytes; Loading Loading @@ -1368,8 +1451,12 @@ int mdss_mdp_perf_bw_check_pipe(struct mdss_mdp_perf_params *perf, if (ctl->intf_type == MDSS_MDP_NO_INTF) return 0; if (test_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map)) { prefill_bw = perf->bw_prefill; } else { vbp_fac = mdss_mdp_get_vbp_factor_max(ctl); prefill_bw = perf->prefill_bytes * vbp_fac; } pipe_bw = max(prefill_bw, perf->bw_overlap); pr_debug("prefill=%llu, vbp_fac=%u, overlap=%llu\n", prefill_bw, vbp_fac, perf->bw_overlap); Loading