diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index d6e8a213c215..5548f0f09f8a 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -547,6 +547,7 @@ struct mdss_data_type { u32 sec_session_cnt; wait_queue_head_t secure_waitq; struct cx_ipeak_client *mdss_cx_ipeak; + struct mult_factor bus_throughput_factor; }; extern struct mdss_data_type *mdss_res; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index 6936c4c1f3cc..6fb32761a767 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -4527,6 +4527,15 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) mdss_mdp_parse_dt_fudge_factors(pdev, "qcom,mdss-clk-factor", &mdata->clk_factor); + /* + * Bus throughput factor will be used during high downscale cases. + * The recommended default factor is 1.1. + */ + mdata->bus_throughput_factor.numer = 11; + mdata->bus_throughput_factor.denom = 10; + mdss_mdp_parse_dt_fudge_factors(pdev, "qcom,mdss-bus-througput-factor", + &mdata->bus_throughput_factor); + rc = of_property_read_u32(pdev->dev.of_node, "qcom,max-bandwidth-low-kbps", &mdata->max_bw_low); if (rc) diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index efd681a5d954..0165c48a0467 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -31,6 +31,7 @@ #define MDSS_MDP_QSEED3_VER_DOWNSCALE_LIM 2 #define NUM_MIXERCFG_REGS 3 #define MDSS_MDP_WB_OUTPUT_BPP 3 +#define MIN_BUS_THROUGHPUT_SCALE_FACTOR 35 struct mdss_mdp_mixer_cfg { u32 config_masks[NUM_MIXERCFG_REGS]; bool border_enabled; @@ -622,11 +623,21 @@ static u32 __calc_qseed3_mdp_clk_rate(struct mdss_mdp_pipe *pipe, } static inline bool __is_vert_downscaling(u32 src_h, - struct mdss_rect dst){ - + struct mdss_rect dst) +{ return (src_h > dst.h); } +static inline bool __is_bus_throughput_factor_required(u32 src_h, + struct mdss_rect dst) +{ + u32 scale_factor = src_h * 10; + + do_div(scale_factor, dst.h); + return (__is_vert_downscaling(src_h, dst) && + (scale_factor >= MIN_BUS_THROUGHPUT_SCALE_FACTOR)); +} + static u32 get_pipe_mdp_clk_rate(struct mdss_mdp_pipe *pipe, struct mdss_rect src, struct mdss_rect dst, u32 fps, u32 v_total, u32 flags) @@ -673,6 +684,15 @@ static u32 get_pipe_mdp_clk_rate(struct mdss_mdp_pipe *pipe, } } + /* + * If the downscale factor is >= 3.5 for a 32 BPP surface, + * it is recommended to add a 10% bus throughput factor to + * the clock rate. + */ + if ((pipe->src_fmt->bpp == 4) && + __is_bus_throughput_factor_required(src_h, dst)) + rate = apply_fudge_factor(rate, &mdata->bus_throughput_factor); + if (flags & PERF_CALC_PIPE_APPLY_CLK_FUDGE) rate = mdss_mdp_clk_fudge_factor(mixer, rate);