diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt index 53f95a82fba4..a481be44203e 100644 --- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt +++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt @@ -332,14 +332,23 @@ Optional properties: sw_reset register bitmap. Number of offsets defined should match the number of offsets defined in property: qcom,mdss-pipe-dma-off -- qcom,mdss-rotator-ot-limit: This integer value indicates maximum number of pending - writes that can be allowed from rotator client. Default - value is 16 which is the maximum. This value can be - used to reduce the pending writes limit dynamically - and can be tuned to match performance requirements - depending upon system state. -- qcom,mdss-default-ot-limit: This integer value indicates the default number of pending +- qcom,mdss-default-ot-wr-limit: This integer value indicates maximum number of pending + writes that can be allowed from non real time client. + This value can be used to reduce the pending writes + limit and can be tuned to match performance + requirements depending upon system state. + Some platforms require a dynamic ot limiting in + some cases. Setting this default ot write limit + will enable this dynamic limiting for the write + operations in the platforms that require these + limits. +- qcom,mdss-default-ot-rd-limit: This integer value indicates the default number of pending reads that can be allowed for the real time clients. + Some platforms require a dynamic ot limiting in + some cases. Setting this default ot read limit + will enable this dynamic limiting for the read + operations in the platforms that require these + limits. - qcom,mdss-default-pipe-qos-lut: This value is used to program the default qos lut register for the rt clients and nrt rotator read clients. - qcom,mdss-clk-levels: This array indicates the mdp core clock level selection diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index a3b17bb67ba1..0b6c5fc5e5b5 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -251,9 +251,10 @@ struct mdss_data_type { bool has_pixel_ram; bool needs_hist_vote; - u32 rotator_ot_limit; - u32 default_ot_limit; + u32 default_ot_rd_limit; + u32 default_ot_wr_limit; u32 default_pipe_qos_lut; + u32 mdp_irq_mask; u32 mdp_hist_irq_mask; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index def97ca009d2..d43cc68d87be 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -2706,12 +2706,12 @@ static int mdss_mdp_parse_dt_misc(struct platform_device *pdev) mdata->rot_block_size = (!rc ? data : 128); rc = of_property_read_u32(pdev->dev.of_node, - "qcom,mdss-rotator-ot-limit", &data); - mdata->rotator_ot_limit = (!rc ? data : 0); + "qcom,mdss-default-ot-rd-limit", &data); + mdata->default_ot_rd_limit = (!rc ? data : 0); rc = of_property_read_u32(pdev->dev.of_node, - "qcom,mdss-default-ot-limit", &data); - mdata->default_ot_limit = (!rc ? data : 0); + "qcom,mdss-default-ot-wr-limit", &data); + mdata->default_ot_wr_limit = (!rc ? data : 0); rc = of_property_read_u32(pdev->dev.of_node, "qcom,mdss-default-pipe-qos-lut", &data); @@ -3155,39 +3155,59 @@ bool force_on_xin_clk(u32 bit_off, u32 clk_ctl_reg_off, bool enable) return clk_forced_on; } -static bool limit_rotator_ot(bool is_yuv, u32 width, u32 height) -{ - return (true == is_yuv) && - (width * height <= 1080 * 1920); -} - -static int limit_wb_ot(u32 width, u32 height) -{ - - return width * height <= 1080 * 1920; -} - -static u32 get_ot_limit(u32 reg_off, u32 bit_off, bool is_rot, - bool is_wb, bool is_yuv, u32 width, u32 height) +static void apply_dynamic_ot_limit(u32 *ot_lim, + struct mdss_mdp_set_ot_params *params) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - u32 ot_lim = mdata->default_ot_limit; + u32 res; + + if (!is_dynamic_ot_limit_required(mdata->mdp_rev)) + return; + + res = params->width * params->height; + + pr_debug("w:%d h:%d rot:%d yuv:%d wb:%d res:%d\n", + params->width, params->height, params->is_rot, + params->is_yuv, params->is_wb, res); + + if ((params->is_rot && params->is_yuv) || + params->is_wb) { + if (res <= 1080 * 1920) { + *ot_lim = 2; + } else if (res <= 3840 * 2160) { + if (params->is_rot && params->is_yuv) + *ot_lim = 8; + else + *ot_lim = 16; + } + } +} + +static u32 get_ot_limit(u32 reg_off, u32 bit_off, + struct mdss_mdp_set_ot_params *params) +{ + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + u32 ot_lim = 0; u32 is_vbif_nrt, val; + if (mdata->default_ot_wr_limit && + (params->reg_off_vbif_lim_conf == MMSS_VBIF_WR_LIM_CONF)) + ot_lim = mdata->default_ot_wr_limit; + else if (mdata->default_ot_rd_limit && + (params->reg_off_vbif_lim_conf == MMSS_VBIF_RD_LIM_CONF)) + ot_lim = mdata->default_ot_rd_limit; + /* - * If default ot limit is not set from dt, - * then ot limiting is disabled. + * If default ot is not set from dt, + * then do not configure it. */ if (ot_lim == 0) goto exit; + /* Modify the limits if the target and the use case requires it */ + apply_dynamic_ot_limit(&ot_lim, params); + is_vbif_nrt = mdss_mdp_is_vbif_nrt(mdata->mdp_rev); - - if ((is_rot && limit_rotator_ot(is_yuv, width, height)) || - (is_wb && limit_wb_ot(width, height))) { - ot_lim = MDSS_OT_LIMIT; - } - val = MDSS_VBIF_READ(mdata, reg_off, is_vbif_nrt); val &= (0xFF << bit_off); val = val >> bit_off; @@ -3196,11 +3216,11 @@ static u32 get_ot_limit(u32 reg_off, u32 bit_off, bool is_rot, ot_lim = 0; exit: + pr_debug("ot_lim=%d\n", ot_lim); return ot_lim; } -void mdss_mdp_set_ot_limit(struct mdss_mdp_set_ot_params *params, - bool is_rot, bool is_wb, bool is_yuv) +void mdss_mdp_set_ot_limit(struct mdss_mdp_set_ot_params *params) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); u32 ot_lim; @@ -3211,15 +3231,10 @@ void mdss_mdp_set_ot_limit(struct mdss_mdp_set_ot_params *params, u32 reg_val; bool forced_on; - if (!mdss_mdp_apply_ot_limit(mdata->mdp_rev)) - goto exit; - ot_lim = get_ot_limit( reg_off_vbif_lim_conf, bit_off_vbif_lim_conf, - is_rot, is_wb, is_yuv, - params->width, - params->height) & 0xFF; + params) & 0xFF; if (ot_lim == 0) goto exit; diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 6d51d89e9190..742af28db28a 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -83,12 +83,6 @@ #define MASTER_CTX 0 #define SLAVE_CTX 1 -/* - * Recommendation is to have different ot depending on the fps - * and resolution, but since current SW doesn't support different - * fps for non-real time, we are hard-coding the ot limit to 2 for now - */ -#define MDSS_OT_LIMIT 2 #define XIN_HALT_TIMEOUT_US 0x4000 enum mdss_mdp_perf_state_type { @@ -601,6 +595,9 @@ struct mdss_mdp_set_ot_params { u32 num; u32 width; u32 height; + bool is_rot; + bool is_wb; + bool is_yuv; u32 reg_off_vbif_lim_conf; u32 reg_off_mdp_clk_ctrl; u32 bit_off_mdp_clk_ctrl; @@ -716,7 +713,7 @@ static inline bool mdss_mdp_is_vbif_nrt(u32 mdp_rev) MDSS_MDP_HW_REV_107); } -static inline bool mdss_mdp_apply_ot_limit(u32 mdp_rev) +static inline bool is_dynamic_ot_limit_required(u32 mdp_rev) { return mdp_rev == MDSS_MDP_HW_REV_105 || mdp_rev == MDSS_MDP_HW_REV_109 || @@ -1150,8 +1147,7 @@ int mdss_mdp_wb_get_secure(struct msm_fb_data_type *mfd, uint8_t *enable); void mdss_mdp_ctl_restore(void); int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl); int mdss_mdp_wait_for_xin_halt(u32 xin_id, bool is_vbif_nrt); -void mdss_mdp_set_ot_limit(struct mdss_mdp_set_ot_params *params, - bool is_rot, bool is_wb, bool is_yuv); +void mdss_mdp_set_ot_limit(struct mdss_mdp_set_ot_params *params); int mdss_mdp_cmd_set_autorefresh_mode(struct mdss_mdp_ctl *ctl, int frame_cnt); int mdss_mdp_ctl_cmd_autorefresh_enable(struct mdss_mdp_ctl *ctl, diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c index f55bb9fc2f09..393e1ebe51ee 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c @@ -705,19 +705,20 @@ static void mdss_mdp_set_ot_limit_wb(struct mdss_mdp_writeback_ctx *ctx) ot_params.reg_off_vbif_lim_conf = MMSS_VBIF_WR_LIM_CONF; ot_params.reg_off_mdp_clk_ctrl = ctx->clk_ctrl.reg_off; ot_params.bit_off_mdp_clk_ctrl = ctx->clk_ctrl.bit_off; + ot_params.is_rot = (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR); + ot_params.is_wb = (ctx->type == MDSS_MDP_WRITEBACK_TYPE_WFD) || + (ctx->type == MDSS_MDP_WRITEBACK_TYPE_LINE); + ot_params.is_yuv = ctx->dst_fmt->is_yuv; + + mdss_mdp_set_ot_limit(&ot_params); - mdss_mdp_set_ot_limit(&ot_params, - ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR, - (ctx->type == MDSS_MDP_WRITEBACK_TYPE_WFD) || - (ctx->type == MDSS_MDP_WRITEBACK_TYPE_LINE), - ctx->dst_fmt->is_yuv); } static int mdss_mdp_writeback_display(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_writeback_ctx *ctx; struct mdss_mdp_writeback_arg *wb_args; - u32 flush_bits = 0, val, bit_off, reg_off; + u32 flush_bits = 0; int ret; if (!ctl || !ctl->mdata) @@ -733,24 +734,9 @@ static int mdss_mdp_writeback_display(struct mdss_mdp_ctl *ctl, void *arg) return -EPERM; } - if (ctl->mdata->rotator_ot_limit) { - if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR) - ctx->wr_lim = ctl->mdata->rotator_ot_limit; - else - ctx->wr_lim = MDSS_DEFAULT_OT_SETTING; - - reg_off = (ctx->xin_id / 4) * 4; - bit_off = (ctx->xin_id % 4) * 8; - - val = MDSS_VBIF_READ(ctl->mdata, MMSS_VBIF_WR_LIM_CONF + - reg_off, ctx->is_vbif_nrt); - val &= ~(0xFF << bit_off); - val |= (ctx->wr_lim) << bit_off; - MDSS_VBIF_WRITE(ctl->mdata, MMSS_VBIF_WR_LIM_CONF + reg_off, - val, ctx->is_vbif_nrt); - } else { + if (ctl->mdata->default_ot_wr_limit || + ctl->mdata->default_ot_rd_limit) mdss_mdp_set_ot_limit_wb(ctx); - } wb_args = (struct mdss_mdp_writeback_arg *) arg; if (!wb_args) diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index c2f159f1bc7d..7835162d222f 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -1857,11 +1857,11 @@ static void mdss_mdp_set_ot_limit_pipe(struct mdss_mdp_pipe *pipe) ot_params.reg_off_mdp_clk_ctrl = pipe->clk_ctrl.reg_off; ot_params.bit_off_mdp_clk_ctrl = pipe->clk_ctrl.bit_off + CLK_FORCE_ON_OFFSET; + ot_params.is_rot = pipe->mixer_left->rotator_mode; + ot_params.is_wb = ctl->intf_num == MDSS_MDP_NO_INTF; + ot_params.is_yuv = pipe->src_fmt->is_yuv; - mdss_mdp_set_ot_limit(&ot_params, - pipe->mixer_left->rotator_mode, - ctl->intf_num == MDSS_MDP_NO_INTF, - pipe->src_fmt->is_yuv); + mdss_mdp_set_ot_limit(&ot_params); } int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe,