diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index 87810fe086b7..e740f026da01 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -144,12 +144,14 @@ struct mdss_pp_block_off { enum mdss_hw_quirk { MDSS_QUIRK_BWCPANIC, + MDSS_QUIRK_ROTCDP, MDSS_QUIRK_MAX, }; enum mdss_qos_settings { MDSS_QOS_PER_PIPE_IB, MDSS_QOS_OVERHEAD_FACTOR, + MDSS_QOS_CDP, MDSS_QOS_MAX, }; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index 28f1c8233b1c..888fce38bd76 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1009,6 +1009,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) switch (mdata->mdp_rev) { case MDSS_MDP_HW_REV_107: mdata->ubwc_comp_ratio_factors_row = 0; + mdss_set_quirk(mdata, MDSS_QUIRK_ROTCDP); case MDSS_MDP_HW_REV_107_1: case MDSS_MDP_HW_REV_107_2: mdss_set_quirk(mdata, MDSS_QUIRK_BWCPANIC); @@ -1018,6 +1019,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) mdata->per_pipe_ib_factor.denom = 2; set_bit(MDSS_QOS_PER_PIPE_IB, mdata->mdss_qos_map); set_bit(MDSS_QOS_OVERHEAD_FACTOR, mdata->mdss_qos_map); + set_bit(MDSS_QOS_CDP, mdata->mdss_qos_map); break; case MDSS_MDP_HW_REV_105: case MDSS_MDP_HW_REV_109: diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 76b487f80c31..1299f04f31a7 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -64,6 +64,11 @@ #define OVERFETCH_DISABLE_LEFT BIT(2) #define OVERFETCH_DISABLE_RIGHT BIT(3) +#define MDSS_MDP_CDP_ENABLE BIT(0) +#define MDSS_MDP_CDP_ENABLE_UBWCMETA BIT(1) +#define MDSS_MDP_CDP_AMORTIZED BIT(2) +#define MDSS_MDP_CDP_AHEAD_64 BIT(3) + #define PERF_STATUS_DONE 0 #define PERF_STATUS_BUSY 1 diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h index 919c5b2c98ff..47f14c2ec96c 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h +++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h @@ -204,6 +204,7 @@ enum mdss_mdp_sspp_chroma_samp_type { #define MDSS_MDP_REG_SSPP_SAFE_LUT 0x064 #define MDSS_MDP_REG_SSPP_CREQ_LUT 0x068 #define MDSS_MDP_REG_SSPP_QOS_CTRL 0x06C +#define MDSS_MDP_REG_SSPP_CDP_CTRL 0x134 #define MDSS_MDP_REG_SSPP_UBWC_ERROR_STATUS 0x138 #define MDSS_MDP_REG_SSPP_SRC_OP_MODE 0x038 @@ -404,6 +405,7 @@ enum mdss_mdp_writeback_index { #define MDSS_MDP_REG_WB_ALPHA_X_VALUE 0x078 #define MDSS_MDP_REG_WB_CSC_BASE 0x260 #define MDSS_MDP_REG_WB_DST_ADDR_SW_STATUS 0x2B0 +#define MDSS_MDP_REG_WB_CDP_CTRL 0x2B4 #define MDSS_MDP_MAX_AD_AL 65535 #define MDSS_MDP_MAX_AD_STR 255 diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c index 08c94f0a28ab..bf48bba7f577 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c @@ -189,6 +189,30 @@ static int mdss_mdp_writeback_cdm_setup(struct mdss_mdp_writeback_ctx *ctx, return mdss_mdp_cdm_setup(cdm, &setup); } +void mdss_mdp_set_wb_cdp(struct mdss_mdp_writeback_ctx *ctx, + struct mdss_mdp_format_params *fmt) +{ + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + u32 cdp_settings = 0x0; + + /* Disable CDP for rotator in v1 */ + if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR && + mdss_has_quirk(mdata, MDSS_QUIRK_ROTCDP)) + goto exit; + + cdp_settings = MDSS_MDP_CDP_ENABLE; + + if (!mdss_mdp_is_linear_format(fmt)) + cdp_settings |= MDSS_MDP_CDP_ENABLE_UBWCMETA; + + /* 64-transactions for line mode otherwise we keep 32 */ + if (ctx->type != MDSS_MDP_WRITEBACK_TYPE_ROTATOR) + cdp_settings |= MDSS_MDP_CDP_AHEAD_64; + +exit: + mdp_wb_write(ctx, MDSS_MDP_REG_WB_CDP_CTRL, cdp_settings); +} + static int mdss_mdp_writeback_format_setup(struct mdss_mdp_writeback_ctx *ctx, u32 format, struct mdss_mdp_ctl *ctl) { @@ -316,6 +340,10 @@ static int mdss_mdp_writeback_format_setup(struct mdss_mdp_writeback_ctx *ctx, mdp_wb_write(ctx, MDSS_MDP_REG_WB_DST_YSTRIDE1, ystride1); mdp_wb_write(ctx, MDSS_MDP_REG_WB_OUT_SIZE, outsize); + /* configure CDP */ + if (test_bit(MDSS_QOS_CDP, mdata->mdss_qos_map)) + mdss_mdp_set_wb_cdp(ctx, fmt); + return 0; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index a457d28678ea..1971860f79b6 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -1618,6 +1618,32 @@ static int mdss_mdp_image_setup(struct mdss_mdp_pipe *pipe, return 0; } +static void mdss_mdp_set_pipe_cdp(struct mdss_mdp_pipe *pipe) +{ + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + u32 cdp_settings = 0x0; + bool is_rotator = (pipe->mixer_left && pipe->mixer_left->rotator_mode); + + /* Disable CDP for rotator pipe in v1 */ + if (is_rotator && mdss_has_quirk(mdata, MDSS_QUIRK_ROTCDP)) + goto exit; + + cdp_settings = MDSS_MDP_CDP_ENABLE; + + if (!mdss_mdp_is_linear_format(pipe->src_fmt)) { + /* Enable Amortized for non-linear formats */ + cdp_settings |= MDSS_MDP_CDP_ENABLE_UBWCMETA; + cdp_settings |= MDSS_MDP_CDP_AMORTIZED; + } else { + /* 64-transactions for line mode otherwise we keep 32 */ + if (!is_rotator) + cdp_settings |= MDSS_MDP_CDP_AHEAD_64; + } + +exit: + mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_CDP_CTRL, cdp_settings); +} + static int mdss_mdp_format_setup(struct mdss_mdp_pipe *pipe) { struct mdss_mdp_format_params *fmt; @@ -1698,6 +1724,10 @@ static int mdss_mdp_format_setup(struct mdss_mdp_pipe *pipe) /* clear UBWC error */ mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_UBWC_ERROR_STATUS, BIT(31)); + /* configure CDP */ + if (test_bit(MDSS_QOS_CDP, mdata->mdss_qos_map)) + mdss_mdp_set_pipe_cdp(pipe); + return 0; }