Loading drivers/video/msm/mdss/mdss_mdp.h +1 −0 Original line number Diff line number Diff line Loading @@ -285,6 +285,7 @@ struct mdss_mdp_ad { struct mdss_ad_info { u8 num; u8 calc_hw_num; u32 ops; u32 sts; u32 reg_sts; u32 state; Loading drivers/video/msm/mdss/mdss_mdp_pp.c +172 −24 Original line number Diff line number Diff line Loading @@ -214,6 +214,10 @@ static u32 igc_limited[IGC_LUT_ENTRIES] = { #define PP_AD_BAD_HW_NUM 255 #define MDSS_SIDE_NONE 0 #define MDSS_SIDE_LEFT 1 #define MDSS_SIDE_RIGHT 2 #define PP_AD_STATE_INIT 0x2 #define PP_AD_STATE_CFG 0x4 #define PP_AD_STATE_DATA 0x8 Loading Loading @@ -302,8 +306,8 @@ struct mdss_pp_res_type { struct mdp_gamut_cfg_data gamut_disp_cfg[MDSS_BLOCK_DISP_NUM]; uint16_t gamut_tbl[MDSS_BLOCK_DISP_NUM][GAMUT_TOTAL_TABLE_SIZE]; u32 hist_data[MDSS_BLOCK_DISP_NUM][HIST_V_SIZE]; /* physical info */ struct pp_sts_type pp_disp_sts[MDSS_BLOCK_DISP_NUM]; /* physical info */ struct pp_hist_col_info dspp_hist[MDSS_MDP_MAX_DSPP]; }; Loading Loading @@ -350,8 +354,9 @@ static void pp_enhist_config(unsigned long flags, char __iomem *addr, static void pp_dither_config(char __iomem *addr, struct pp_sts_type *pp_sts, struct mdp_dither_cfg_data *dither_cfg); static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode, int mdp_rev); static void pp_dspp_opmode_config(struct mdss_mdp_ctl *ctl, u32 num, struct pp_sts_type *pp_sts, int mdp_rev, u32 *opmode); static void pp_sharp_config(char __iomem *addr, struct pp_sts_type *pp_sts, struct mdp_sharp_cfg *sharp_config); Loading Loading @@ -385,11 +390,15 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl); static void pp_ad_input_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad); static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode); static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd, struct mdss_ad_info *ad); static void pp_ad_bypass_config(struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode); static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd); static void pp_ad_cfg_lut(char __iomem *addr, u32 *data); static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num); static inline bool pp_sts_is_enabled(u32 sts, int side); static inline void pp_sts_set_split_bits(u32 *sts, u32 bits); static u32 last_sts, last_state; Loading Loading @@ -528,6 +537,7 @@ static void pp_gamut_config(struct mdp_gamut_cfg_data *gamut_cfg, pp_sts->gamut_sts &= ~PP_STS_ENABLE; else if (gamut_cfg->flags & MDP_PP_OPS_ENABLE) pp_sts->gamut_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->gamut_sts, gamut_cfg->flags); } static void pp_pa_config(unsigned long flags, char __iomem *addr, Loading Loading @@ -696,6 +706,7 @@ static void pp_update_pa_v2_sts(struct pp_sts_type *pp_sts, if (pa_v2_config->flags & MDP_PP_PA_SIX_ZONE_VAL_MASK) pp_sts->pa_sts |= PP_STS_PA_SIX_ZONE_VAL_MASK; pp_sts_set_split_bits(&pp_sts->pa_sts, pa_v2_config->flags); } static void pp_pcc_config(unsigned long flags, char __iomem *addr, Loading @@ -710,6 +721,7 @@ static void pp_pcc_config(unsigned long flags, char __iomem *addr, pp_sts->pcc_sts &= ~PP_STS_ENABLE; else if (pcc_config->ops & MDP_PP_OPS_ENABLE) pp_sts->pcc_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->pcc_sts, pcc_config->ops); } } Loading Loading @@ -737,6 +749,7 @@ static void pp_igc_config(unsigned long flags, char __iomem *addr, pp_sts->igc_sts &= ~PP_STS_ENABLE; else if (igc_config->ops & MDP_PP_OPS_ENABLE) pp_sts->igc_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->igc_sts, igc_config->ops); } } Loading Loading @@ -1348,12 +1361,20 @@ static void pp_dither_config(char __iomem *addr, pp_sts->dither_sts &= ~PP_STS_ENABLE; else if (dither_cfg->flags & MDP_PP_OPS_ENABLE) pp_sts->dither_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->dither_sts, dither_cfg->flags); } static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode, int mdp_rev) static void pp_dspp_opmode_config(struct mdss_mdp_ctl *ctl, u32 num, struct pp_sts_type *pp_sts, int mdp_rev, u32 *opmode) { if (pp_sts->pa_sts & PP_STS_ENABLE) int side; side = pp_num_to_side(ctl, num); if (side < 0) return; if (pp_sts_is_enabled(pp_sts->pa_sts, side)) *opmode |= MDSS_MDP_DSPP_OP_PA_EN; /* PA_EN */ if (mdp_rev >= MDSS_MDP_HW_REV_103) { if (pp_sts->pa_sts & PP_STS_PA_HUE_MASK) Loading Loading @@ -1381,10 +1402,10 @@ static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode, if (pp_sts->pa_sts & PP_STS_PA_SIX_ZONE_VAL_MASK) *opmode |= MDSS_MDP_DSPP_OP_PA_SIX_ZONE_VAL_MASK; } if (pp_sts->pcc_sts & PP_STS_ENABLE) if (pp_sts_is_enabled(pp_sts->pcc_sts, side)) *opmode |= MDSS_MDP_DSPP_OP_PCC_EN; /* PCC_EN */ if (pp_sts->igc_sts & PP_STS_ENABLE) { if (pp_sts_is_enabled(pp_sts->igc_sts, side)) { *opmode |= MDSS_MDP_DSPP_OP_IGC_LUT_EN | /* IGC_LUT_EN */ (pp_sts->igc_tbl_idx << 1); } Loading @@ -1392,14 +1413,14 @@ static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode, *opmode |= MDSS_MDP_DSPP_OP_HIST_LUTV_EN | /* HIST_LUT_EN */ MDSS_MDP_DSPP_OP_PA_EN; /* PA_EN */ } if (pp_sts->dither_sts & PP_STS_ENABLE) if (pp_sts_is_enabled(pp_sts->dither_sts, side)) *opmode |= MDSS_MDP_DSPP_OP_DST_DITHER_EN; /* DITHER_EN */ if (pp_sts->gamut_sts & PP_STS_ENABLE) { if (pp_sts_is_enabled(pp_sts->gamut_sts, side)) { *opmode |= MDSS_MDP_DSPP_OP_GAMUT_EN; /* GAMUT_EN */ if (pp_sts->gamut_sts & PP_STS_GAMUT_FIRST) *opmode |= MDSS_MDP_DSPP_OP_GAMUT_PCC_ORDER; } if (pp_sts->pgc_sts & PP_STS_ENABLE) if (pp_sts_is_enabled(pp_sts->pgc_sts, side)) *opmode |= MDSS_MDP_DSPP_OP_ARGC_LUT_EN; } Loading Loading @@ -1505,6 +1526,7 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer) pp_sts->pgc_sts &= ~PP_STS_ENABLE; else if (pgc_config->flags & MDP_PP_OPS_ENABLE) pp_sts->pgc_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->pgc_sts, pgc_config->flags); } if (ad_hw) { Loading @@ -1516,12 +1538,12 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer) pp_ad_init_write(ad_hw, ad, ctl); if (ad_flags & PP_AD_STS_DIRTY_CFG) pp_ad_cfg_write(ad_hw, ad); pp_ad_bypass_config(ad, &ad_bypass); pp_ad_bypass_config(ad, ctl, ad_hw->num, &ad_bypass); writel_relaxed(ad_bypass, ad_hw->base); mutex_unlock(&ad->lock); } pp_dspp_opmode_config(pp_sts, &opmode, mdata->mdp_rev); pp_dspp_opmode_config(ctl, dspp_num, pp_sts, mdata->mdp_rev, &opmode); flush_exit: writel_relaxed(opmode, base + MDSS_MDP_REG_DSPP_OP_MODE); Loading Loading @@ -1868,6 +1890,12 @@ int mdss_mdp_pa_v2_config(struct mdp_pa_v2_cfg_data *config, (config->block >= MDP_BLOCK_MAX)) return -EINVAL; if ((config->pa_v2_data.flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -2157,6 +2185,11 @@ int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *config, (config->block >= MDP_BLOCK_MAX)) return -EINVAL; if ((config->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -2276,6 +2309,11 @@ int mdss_mdp_igc_lut_config(struct mdp_igc_lut_data *config, if (config->len != IGC_LUT_ENTRIES) return -EINVAL; if ((config->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -2475,6 +2513,11 @@ int mdss_mdp_argc_config(struct mdp_pgc_lut_data *config, (PP_BLOCK(config->block) >= MDP_BLOCK_MAX)) return -EINVAL; if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = PP_BLOCK(config->block) - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -2646,6 +2689,11 @@ int mdss_mdp_dither_config(struct mdp_dither_cfg_data *config, if (config->flags & MDP_PP_OPS_READ) return -ENOTSUPP; if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; mdss_pp_res->dither_disp_cfg[disp_num] = *config; Loading Loading @@ -2696,6 +2744,11 @@ int mdss_mdp_gamut_config(struct mdp_gamut_cfg_data *config, if (pp_gm_has_invalid_lut_size(config)) return -EINVAL; if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -3543,6 +3596,53 @@ static struct msm_fb_data_type *mdss_get_mfd_from_index(int index) return out; } static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num) { u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; u32 mixer_num; if (!ctl || !ctl->mfd) return -EINVAL; mixer_num = mdss_mdp_get_ctl_mixers(ctl->mfd->index, mixer_id); if (mixer_num < 2) return MDSS_SIDE_NONE; else if (mixer_id[1] == num) return MDSS_SIDE_RIGHT; else if (mixer_id[0] == num) return MDSS_SIDE_LEFT; else pr_err("invalid, not on any side"); return -EINVAL; } static inline void pp_sts_set_split_bits(u32 *sts, u32 bits) { u32 tmp = *sts; tmp &= ~MDSS_PP_SPLIT_MASK; tmp |= bits & MDSS_PP_SPLIT_MASK; *sts = tmp; } static inline bool pp_sts_is_enabled(u32 sts, int side) { bool ret = false; /* * If there are no sides, or if there are no split mode bits set, the * side can't be disabled via split mode. * * Otherwise, if the side being checked opposes the split mode * configuration, the side is disabled. */ if ((side == MDSS_SIDE_NONE) || !(sts & MDSS_PP_SPLIT_MASK)) ret = true; else if ((sts & MDSS_PP_SPLIT_RIGHT_ONLY) && (side == MDSS_SIDE_RIGHT)) ret = true; else if ((sts & MDSS_PP_SPLIT_LEFT_ONLY) && (side == MDSS_SIDE_LEFT)) ret = true; return ret && (sts & PP_STS_ENABLE); } static int mdss_ad_init_checks(struct msm_fb_data_type *mfd) { u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; Loading Loading @@ -3638,7 +3738,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, struct mdss_ad_info *ad; struct msm_fb_data_type *bl_mfd; int lin_ret = -1, inv_ret = -1, ret = 0; u32 ratio_temp, shift = 0; u32 ratio_temp, shift = 0, last_ops; ret = mdss_mdp_get_ad(mfd, &ad); if (ret) Loading @@ -3651,6 +3751,11 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, bl_mfd = mfd; } if ((init_cfg->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&ad->lock); if (init_cfg->ops & MDP_PP_AD_INIT) { memcpy(&ad->init, &init_cfg->params.init, Loading Loading @@ -3693,6 +3798,22 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, ad->sts |= PP_AD_STS_DIRTY_CFG; } last_ops = ad->ops & MDSS_PP_SPLIT_MASK; ad->ops = init_cfg->ops & MDSS_PP_SPLIT_MASK; /* * if there is a change in the split mode config, the init values * need to be re-written to hardware (if they have already been * written or if there is data pending to be written). Check for * pending data (DIRTY_INIT) is not checked here since it will not * affect the outcome of this conditional (i.e. if init hasn't * already been written (*_STATE_INIT is set), this conditional will * only evaluate to true (and set the DIRTY bit) if the DIRTY bit has * already been set). */ if ((last_ops ^ ad->ops) && (ad->state & PP_AD_STATE_INIT)) ad->sts |= PP_AD_STS_DIRTY_INIT; if (!ret && (init_cfg->ops & MDP_PP_OPS_DISABLE)) { ad->sts &= ~PP_STS_ENABLE; mutex_unlock(&ad->lock); Loading Loading @@ -3847,8 +3968,9 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, u32 temp; u32 frame_start, frame_end, procs_start, procs_end, tile_ctrl; u32 num; int side; char __iomem *base; bool is_calc, is_dual_pipe; bool is_calc, is_dual_pipe, split_mode; u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; u32 mixer_num; mixer_num = mdss_mdp_get_ctl_mixers(ctl->mfd->index, mixer_id); Loading @@ -3859,6 +3981,7 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, base = ad_hw->base; is_calc = ad->calc_hw_num == ad_hw->num; split_mode = !!(ad->ops & MDSS_PP_SPLIT_MASK); writel_relaxed(ad->init.i_control[0] & 0x1F, base + MDSS_MDP_REG_AD_CON_CTRL_0); Loading @@ -3884,6 +4007,9 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, writel_relaxed(ad->init.format, base + MDSS_MDP_REG_AD_CTRL_0); writel_relaxed(ad->init.auto_size, base + MDSS_MDP_REG_AD_CTRL_1); if (split_mode) temp = mdata->mixer_intf[ad_hw->num].width << 16; else temp = ad->init.frame_w << 16; temp |= ad->init.frame_h & 0xFFFF; writel_relaxed(temp, base + MDSS_MDP_REG_AD_FRAME_SIZE); Loading @@ -3896,17 +4022,26 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, pp_ad_cfg_lut(base + MDSS_MDP_REG_AD_LUT_CC, ad->init.color_corr_lut); if (mdata->mdp_rev >= MDSS_MDP_HW_REV_103) { if (is_dual_pipe) { if (is_dual_pipe && !split_mode) { num = ad_hw->num; side = pp_num_to_side(ctl, num); tile_ctrl = 0x5; if (is_calc) { if ((ad->calc_hw_num + 1) == num) tile_ctrl |= 0x10; if (side <= MDSS_SIDE_NONE) { WARN(1, "error finding sides, %d", side); frame_start = 0; procs_start = frame_start; frame_end = 0; procs_end = frame_end; } else if (side == MDSS_SIDE_LEFT) { frame_start = 0; procs_start = 0; frame_end = mdata->mixer_intf[num].width + MDSS_AD_MERGED_WIDTH; procs_end = mdata->mixer_intf[num].width; } else { tile_ctrl |= 0x10; procs_start = ad->init.frame_w - (mdata->mixer_intf[num].width); procs_end = ad->init.frame_w; Loading @@ -3921,8 +4056,13 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, frame_end = 0xFFFF; procs_start = 0x0; procs_end = 0xFFFF; if (split_mode) tile_ctrl = 0x0; else tile_ctrl = 0x1; } writel_relaxed(frame_start, base + MDSS_MDP_REG_AD_FRAME_START); writel_relaxed(frame_end, base + MDSS_MDP_REG_AD_FRAME_END); writel_relaxed(procs_start, base + MDSS_MDP_REG_AD_PROCS_START); Loading Loading @@ -3986,13 +4126,18 @@ static void pp_ad_vsync_handler(struct mdss_mdp_ctl *ctl, ktime_t t) } #define MDSS_PP_AD_BYPASS_DEF 0x101 static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode) static void pp_ad_bypass_config(struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode) { if (ad->reg_sts & PP_STS_ENABLE) int side = pp_num_to_side(ctl, num); if (pp_sts_is_enabled(ad->reg_sts | (ad->ops & MDSS_PP_SPLIT_MASK), side)) { *opmode = 0; else } else { *opmode = MDSS_PP_AD_BYPASS_DEF; } } static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd, struct mdss_ad_info *ad) Loading @@ -4006,6 +4151,8 @@ static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd, /* default to left mixer */ ad->calc_hw_num = mixer_id[0]; if ((mixer_num > 1) && (ad->ops & MDSS_PP_SPLIT_RIGHT_ONLY)) ad->calc_hw_num = mixer_id[1]; return 0; } Loading Loading @@ -4313,6 +4460,7 @@ int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets) mdata->ad_off[i].base = mdata->mdp_base + ad_offsets[i]; mdata->ad_off[i].num = i; mdata->ad_cfgs[i].num = i; mdata->ad_cfgs[i].ops = 0; mdata->ad_cfgs[i].reg_sts = 0; mdata->ad_cfgs[i].calc_itr = 0; mdata->ad_cfgs[i].last_str = 0xFFFFFFFF; Loading include/uapi/linux/msm_mdp.h +4 −0 Original line number Diff line number Diff line Loading @@ -791,6 +791,10 @@ enum { DTM_EXIT, }; #define MDSS_PP_SPLIT_LEFT_ONLY 0x10000000 #define MDSS_PP_SPLIT_RIGHT_ONLY 0x20000000 #define MDSS_PP_SPLIT_MASK 0x30000000 #define MDSS_MAX_BL_BRIGHTNESS 255 #define AD_BL_LIN_LEN 256 Loading Loading
drivers/video/msm/mdss/mdss_mdp.h +1 −0 Original line number Diff line number Diff line Loading @@ -285,6 +285,7 @@ struct mdss_mdp_ad { struct mdss_ad_info { u8 num; u8 calc_hw_num; u32 ops; u32 sts; u32 reg_sts; u32 state; Loading
drivers/video/msm/mdss/mdss_mdp_pp.c +172 −24 Original line number Diff line number Diff line Loading @@ -214,6 +214,10 @@ static u32 igc_limited[IGC_LUT_ENTRIES] = { #define PP_AD_BAD_HW_NUM 255 #define MDSS_SIDE_NONE 0 #define MDSS_SIDE_LEFT 1 #define MDSS_SIDE_RIGHT 2 #define PP_AD_STATE_INIT 0x2 #define PP_AD_STATE_CFG 0x4 #define PP_AD_STATE_DATA 0x8 Loading Loading @@ -302,8 +306,8 @@ struct mdss_pp_res_type { struct mdp_gamut_cfg_data gamut_disp_cfg[MDSS_BLOCK_DISP_NUM]; uint16_t gamut_tbl[MDSS_BLOCK_DISP_NUM][GAMUT_TOTAL_TABLE_SIZE]; u32 hist_data[MDSS_BLOCK_DISP_NUM][HIST_V_SIZE]; /* physical info */ struct pp_sts_type pp_disp_sts[MDSS_BLOCK_DISP_NUM]; /* physical info */ struct pp_hist_col_info dspp_hist[MDSS_MDP_MAX_DSPP]; }; Loading Loading @@ -350,8 +354,9 @@ static void pp_enhist_config(unsigned long flags, char __iomem *addr, static void pp_dither_config(char __iomem *addr, struct pp_sts_type *pp_sts, struct mdp_dither_cfg_data *dither_cfg); static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode, int mdp_rev); static void pp_dspp_opmode_config(struct mdss_mdp_ctl *ctl, u32 num, struct pp_sts_type *pp_sts, int mdp_rev, u32 *opmode); static void pp_sharp_config(char __iomem *addr, struct pp_sts_type *pp_sts, struct mdp_sharp_cfg *sharp_config); Loading Loading @@ -385,11 +390,15 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl); static void pp_ad_input_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad); static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode); static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd, struct mdss_ad_info *ad); static void pp_ad_bypass_config(struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode); static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd); static void pp_ad_cfg_lut(char __iomem *addr, u32 *data); static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num); static inline bool pp_sts_is_enabled(u32 sts, int side); static inline void pp_sts_set_split_bits(u32 *sts, u32 bits); static u32 last_sts, last_state; Loading Loading @@ -528,6 +537,7 @@ static void pp_gamut_config(struct mdp_gamut_cfg_data *gamut_cfg, pp_sts->gamut_sts &= ~PP_STS_ENABLE; else if (gamut_cfg->flags & MDP_PP_OPS_ENABLE) pp_sts->gamut_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->gamut_sts, gamut_cfg->flags); } static void pp_pa_config(unsigned long flags, char __iomem *addr, Loading Loading @@ -696,6 +706,7 @@ static void pp_update_pa_v2_sts(struct pp_sts_type *pp_sts, if (pa_v2_config->flags & MDP_PP_PA_SIX_ZONE_VAL_MASK) pp_sts->pa_sts |= PP_STS_PA_SIX_ZONE_VAL_MASK; pp_sts_set_split_bits(&pp_sts->pa_sts, pa_v2_config->flags); } static void pp_pcc_config(unsigned long flags, char __iomem *addr, Loading @@ -710,6 +721,7 @@ static void pp_pcc_config(unsigned long flags, char __iomem *addr, pp_sts->pcc_sts &= ~PP_STS_ENABLE; else if (pcc_config->ops & MDP_PP_OPS_ENABLE) pp_sts->pcc_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->pcc_sts, pcc_config->ops); } } Loading Loading @@ -737,6 +749,7 @@ static void pp_igc_config(unsigned long flags, char __iomem *addr, pp_sts->igc_sts &= ~PP_STS_ENABLE; else if (igc_config->ops & MDP_PP_OPS_ENABLE) pp_sts->igc_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->igc_sts, igc_config->ops); } } Loading Loading @@ -1348,12 +1361,20 @@ static void pp_dither_config(char __iomem *addr, pp_sts->dither_sts &= ~PP_STS_ENABLE; else if (dither_cfg->flags & MDP_PP_OPS_ENABLE) pp_sts->dither_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->dither_sts, dither_cfg->flags); } static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode, int mdp_rev) static void pp_dspp_opmode_config(struct mdss_mdp_ctl *ctl, u32 num, struct pp_sts_type *pp_sts, int mdp_rev, u32 *opmode) { if (pp_sts->pa_sts & PP_STS_ENABLE) int side; side = pp_num_to_side(ctl, num); if (side < 0) return; if (pp_sts_is_enabled(pp_sts->pa_sts, side)) *opmode |= MDSS_MDP_DSPP_OP_PA_EN; /* PA_EN */ if (mdp_rev >= MDSS_MDP_HW_REV_103) { if (pp_sts->pa_sts & PP_STS_PA_HUE_MASK) Loading Loading @@ -1381,10 +1402,10 @@ static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode, if (pp_sts->pa_sts & PP_STS_PA_SIX_ZONE_VAL_MASK) *opmode |= MDSS_MDP_DSPP_OP_PA_SIX_ZONE_VAL_MASK; } if (pp_sts->pcc_sts & PP_STS_ENABLE) if (pp_sts_is_enabled(pp_sts->pcc_sts, side)) *opmode |= MDSS_MDP_DSPP_OP_PCC_EN; /* PCC_EN */ if (pp_sts->igc_sts & PP_STS_ENABLE) { if (pp_sts_is_enabled(pp_sts->igc_sts, side)) { *opmode |= MDSS_MDP_DSPP_OP_IGC_LUT_EN | /* IGC_LUT_EN */ (pp_sts->igc_tbl_idx << 1); } Loading @@ -1392,14 +1413,14 @@ static void pp_dspp_opmode_config(struct pp_sts_type *pp_sts, u32 *opmode, *opmode |= MDSS_MDP_DSPP_OP_HIST_LUTV_EN | /* HIST_LUT_EN */ MDSS_MDP_DSPP_OP_PA_EN; /* PA_EN */ } if (pp_sts->dither_sts & PP_STS_ENABLE) if (pp_sts_is_enabled(pp_sts->dither_sts, side)) *opmode |= MDSS_MDP_DSPP_OP_DST_DITHER_EN; /* DITHER_EN */ if (pp_sts->gamut_sts & PP_STS_ENABLE) { if (pp_sts_is_enabled(pp_sts->gamut_sts, side)) { *opmode |= MDSS_MDP_DSPP_OP_GAMUT_EN; /* GAMUT_EN */ if (pp_sts->gamut_sts & PP_STS_GAMUT_FIRST) *opmode |= MDSS_MDP_DSPP_OP_GAMUT_PCC_ORDER; } if (pp_sts->pgc_sts & PP_STS_ENABLE) if (pp_sts_is_enabled(pp_sts->pgc_sts, side)) *opmode |= MDSS_MDP_DSPP_OP_ARGC_LUT_EN; } Loading Loading @@ -1505,6 +1526,7 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer) pp_sts->pgc_sts &= ~PP_STS_ENABLE; else if (pgc_config->flags & MDP_PP_OPS_ENABLE) pp_sts->pgc_sts |= PP_STS_ENABLE; pp_sts_set_split_bits(&pp_sts->pgc_sts, pgc_config->flags); } if (ad_hw) { Loading @@ -1516,12 +1538,12 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer) pp_ad_init_write(ad_hw, ad, ctl); if (ad_flags & PP_AD_STS_DIRTY_CFG) pp_ad_cfg_write(ad_hw, ad); pp_ad_bypass_config(ad, &ad_bypass); pp_ad_bypass_config(ad, ctl, ad_hw->num, &ad_bypass); writel_relaxed(ad_bypass, ad_hw->base); mutex_unlock(&ad->lock); } pp_dspp_opmode_config(pp_sts, &opmode, mdata->mdp_rev); pp_dspp_opmode_config(ctl, dspp_num, pp_sts, mdata->mdp_rev, &opmode); flush_exit: writel_relaxed(opmode, base + MDSS_MDP_REG_DSPP_OP_MODE); Loading Loading @@ -1868,6 +1890,12 @@ int mdss_mdp_pa_v2_config(struct mdp_pa_v2_cfg_data *config, (config->block >= MDP_BLOCK_MAX)) return -EINVAL; if ((config->pa_v2_data.flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -2157,6 +2185,11 @@ int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *config, (config->block >= MDP_BLOCK_MAX)) return -EINVAL; if ((config->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -2276,6 +2309,11 @@ int mdss_mdp_igc_lut_config(struct mdp_igc_lut_data *config, if (config->len != IGC_LUT_ENTRIES) return -EINVAL; if ((config->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -2475,6 +2513,11 @@ int mdss_mdp_argc_config(struct mdp_pgc_lut_data *config, (PP_BLOCK(config->block) >= MDP_BLOCK_MAX)) return -EINVAL; if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = PP_BLOCK(config->block) - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -2646,6 +2689,11 @@ int mdss_mdp_dither_config(struct mdp_dither_cfg_data *config, if (config->flags & MDP_PP_OPS_READ) return -ENOTSUPP; if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; mdss_pp_res->dither_disp_cfg[disp_num] = *config; Loading Loading @@ -2696,6 +2744,11 @@ int mdss_mdp_gamut_config(struct mdp_gamut_cfg_data *config, if (pp_gm_has_invalid_lut_size(config)) return -EINVAL; if ((config->flags & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&mdss_pp_mutex); disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0; Loading Loading @@ -3543,6 +3596,53 @@ static struct msm_fb_data_type *mdss_get_mfd_from_index(int index) return out; } static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num) { u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; u32 mixer_num; if (!ctl || !ctl->mfd) return -EINVAL; mixer_num = mdss_mdp_get_ctl_mixers(ctl->mfd->index, mixer_id); if (mixer_num < 2) return MDSS_SIDE_NONE; else if (mixer_id[1] == num) return MDSS_SIDE_RIGHT; else if (mixer_id[0] == num) return MDSS_SIDE_LEFT; else pr_err("invalid, not on any side"); return -EINVAL; } static inline void pp_sts_set_split_bits(u32 *sts, u32 bits) { u32 tmp = *sts; tmp &= ~MDSS_PP_SPLIT_MASK; tmp |= bits & MDSS_PP_SPLIT_MASK; *sts = tmp; } static inline bool pp_sts_is_enabled(u32 sts, int side) { bool ret = false; /* * If there are no sides, or if there are no split mode bits set, the * side can't be disabled via split mode. * * Otherwise, if the side being checked opposes the split mode * configuration, the side is disabled. */ if ((side == MDSS_SIDE_NONE) || !(sts & MDSS_PP_SPLIT_MASK)) ret = true; else if ((sts & MDSS_PP_SPLIT_RIGHT_ONLY) && (side == MDSS_SIDE_RIGHT)) ret = true; else if ((sts & MDSS_PP_SPLIT_LEFT_ONLY) && (side == MDSS_SIDE_LEFT)) ret = true; return ret && (sts & PP_STS_ENABLE); } static int mdss_ad_init_checks(struct msm_fb_data_type *mfd) { u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; Loading Loading @@ -3638,7 +3738,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, struct mdss_ad_info *ad; struct msm_fb_data_type *bl_mfd; int lin_ret = -1, inv_ret = -1, ret = 0; u32 ratio_temp, shift = 0; u32 ratio_temp, shift = 0, last_ops; ret = mdss_mdp_get_ad(mfd, &ad); if (ret) Loading @@ -3651,6 +3751,11 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, bl_mfd = mfd; } if ((init_cfg->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) { pr_warn("Can't set both split bits\n"); return -EINVAL; } mutex_lock(&ad->lock); if (init_cfg->ops & MDP_PP_AD_INIT) { memcpy(&ad->init, &init_cfg->params.init, Loading Loading @@ -3693,6 +3798,22 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, ad->sts |= PP_AD_STS_DIRTY_CFG; } last_ops = ad->ops & MDSS_PP_SPLIT_MASK; ad->ops = init_cfg->ops & MDSS_PP_SPLIT_MASK; /* * if there is a change in the split mode config, the init values * need to be re-written to hardware (if they have already been * written or if there is data pending to be written). Check for * pending data (DIRTY_INIT) is not checked here since it will not * affect the outcome of this conditional (i.e. if init hasn't * already been written (*_STATE_INIT is set), this conditional will * only evaluate to true (and set the DIRTY bit) if the DIRTY bit has * already been set). */ if ((last_ops ^ ad->ops) && (ad->state & PP_AD_STATE_INIT)) ad->sts |= PP_AD_STS_DIRTY_INIT; if (!ret && (init_cfg->ops & MDP_PP_OPS_DISABLE)) { ad->sts &= ~PP_STS_ENABLE; mutex_unlock(&ad->lock); Loading Loading @@ -3847,8 +3968,9 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, u32 temp; u32 frame_start, frame_end, procs_start, procs_end, tile_ctrl; u32 num; int side; char __iomem *base; bool is_calc, is_dual_pipe; bool is_calc, is_dual_pipe, split_mode; u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; u32 mixer_num; mixer_num = mdss_mdp_get_ctl_mixers(ctl->mfd->index, mixer_id); Loading @@ -3859,6 +3981,7 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, base = ad_hw->base; is_calc = ad->calc_hw_num == ad_hw->num; split_mode = !!(ad->ops & MDSS_PP_SPLIT_MASK); writel_relaxed(ad->init.i_control[0] & 0x1F, base + MDSS_MDP_REG_AD_CON_CTRL_0); Loading @@ -3884,6 +4007,9 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, writel_relaxed(ad->init.format, base + MDSS_MDP_REG_AD_CTRL_0); writel_relaxed(ad->init.auto_size, base + MDSS_MDP_REG_AD_CTRL_1); if (split_mode) temp = mdata->mixer_intf[ad_hw->num].width << 16; else temp = ad->init.frame_w << 16; temp |= ad->init.frame_h & 0xFFFF; writel_relaxed(temp, base + MDSS_MDP_REG_AD_FRAME_SIZE); Loading @@ -3896,17 +4022,26 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, pp_ad_cfg_lut(base + MDSS_MDP_REG_AD_LUT_CC, ad->init.color_corr_lut); if (mdata->mdp_rev >= MDSS_MDP_HW_REV_103) { if (is_dual_pipe) { if (is_dual_pipe && !split_mode) { num = ad_hw->num; side = pp_num_to_side(ctl, num); tile_ctrl = 0x5; if (is_calc) { if ((ad->calc_hw_num + 1) == num) tile_ctrl |= 0x10; if (side <= MDSS_SIDE_NONE) { WARN(1, "error finding sides, %d", side); frame_start = 0; procs_start = frame_start; frame_end = 0; procs_end = frame_end; } else if (side == MDSS_SIDE_LEFT) { frame_start = 0; procs_start = 0; frame_end = mdata->mixer_intf[num].width + MDSS_AD_MERGED_WIDTH; procs_end = mdata->mixer_intf[num].width; } else { tile_ctrl |= 0x10; procs_start = ad->init.frame_w - (mdata->mixer_intf[num].width); procs_end = ad->init.frame_w; Loading @@ -3921,8 +4056,13 @@ static void pp_ad_init_write(struct mdss_mdp_ad *ad_hw, struct mdss_ad_info *ad, frame_end = 0xFFFF; procs_start = 0x0; procs_end = 0xFFFF; if (split_mode) tile_ctrl = 0x0; else tile_ctrl = 0x1; } writel_relaxed(frame_start, base + MDSS_MDP_REG_AD_FRAME_START); writel_relaxed(frame_end, base + MDSS_MDP_REG_AD_FRAME_END); writel_relaxed(procs_start, base + MDSS_MDP_REG_AD_PROCS_START); Loading Loading @@ -3986,13 +4126,18 @@ static void pp_ad_vsync_handler(struct mdss_mdp_ctl *ctl, ktime_t t) } #define MDSS_PP_AD_BYPASS_DEF 0x101 static void pp_ad_bypass_config(struct mdss_ad_info *ad, u32 *opmode) static void pp_ad_bypass_config(struct mdss_ad_info *ad, struct mdss_mdp_ctl *ctl, u32 num, u32 *opmode) { if (ad->reg_sts & PP_STS_ENABLE) int side = pp_num_to_side(ctl, num); if (pp_sts_is_enabled(ad->reg_sts | (ad->ops & MDSS_PP_SPLIT_MASK), side)) { *opmode = 0; else } else { *opmode = MDSS_PP_AD_BYPASS_DEF; } } static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd, struct mdss_ad_info *ad) Loading @@ -4006,6 +4151,8 @@ static int pp_ad_setup_hw_nums(struct msm_fb_data_type *mfd, /* default to left mixer */ ad->calc_hw_num = mixer_id[0]; if ((mixer_num > 1) && (ad->ops & MDSS_PP_SPLIT_RIGHT_ONLY)) ad->calc_hw_num = mixer_id[1]; return 0; } Loading Loading @@ -4313,6 +4460,7 @@ int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets) mdata->ad_off[i].base = mdata->mdp_base + ad_offsets[i]; mdata->ad_off[i].num = i; mdata->ad_cfgs[i].num = i; mdata->ad_cfgs[i].ops = 0; mdata->ad_cfgs[i].reg_sts = 0; mdata->ad_cfgs[i].calc_itr = 0; mdata->ad_cfgs[i].last_str = 0xFFFFFFFF; Loading
include/uapi/linux/msm_mdp.h +4 −0 Original line number Diff line number Diff line Loading @@ -791,6 +791,10 @@ enum { DTM_EXIT, }; #define MDSS_PP_SPLIT_LEFT_ONLY 0x10000000 #define MDSS_PP_SPLIT_RIGHT_ONLY 0x20000000 #define MDSS_PP_SPLIT_MASK 0x30000000 #define MDSS_MAX_BL_BRIGHTNESS 255 #define AD_BL_LIN_LEN 256 Loading