diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.c | 88 |
1 files changed, 50 insertions, 38 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index aff09589521b..270e762c2438 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -338,7 +338,8 @@ static int pp_hist_disable(struct pp_hist_col_info *hist_info); static void pp_update_pcc_regs(char __iomem *addr, struct mdp_pcc_cfg_data *cfg_ptr); static void pp_update_igc_lut(struct mdp_igc_lut_data *cfg, - char __iomem *addr, u32 blk_idx); + char __iomem *addr, u32 blk_idx, + u32 total_idx); static void pp_update_gc_one_lut(char __iomem *addr, struct mdp_ar_gc_lut_data *lut_data, uint8_t num_stages); @@ -363,7 +364,7 @@ static void pp_pcc_config(unsigned long flags, char __iomem *addr, static void pp_igc_config(unsigned long flags, char __iomem *addr, struct pp_sts_type *pp_sts, struct mdp_igc_lut_data *igc_config, - u32 pipe_num); + u32 pipe_num, u32 pipe_cnt); static void pp_enhist_config(unsigned long flags, char __iomem *addr, struct pp_sts_type *pp_sts, struct mdp_hist_lut_data *enhist_cfg); @@ -764,12 +765,13 @@ static void pp_pcc_config(unsigned long flags, char __iomem *addr, static void pp_igc_config(unsigned long flags, char __iomem *addr, struct pp_sts_type *pp_sts, struct mdp_igc_lut_data *igc_config, - u32 pipe_num) + u32 pipe_num, u32 pipe_cnt) { u32 tbl_idx; if (flags & PP_FLAGS_DIRTY_IGC) { if (igc_config->ops & MDP_PP_OPS_WRITE) - pp_update_igc_lut(igc_config, addr, pipe_num); + pp_update_igc_lut(igc_config, addr, pipe_num, + pipe_cnt); if (igc_config->ops & MDP_PP_IGC_FLAG_ROM0) { pp_sts->pcc_sts |= PP_STS_ENABLE; @@ -1318,7 +1320,7 @@ int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op) int ret = 0; unsigned long flags = 0; char __iomem *pipe_base; - u32 pipe_num; + u32 pipe_num, pipe_cnt; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); u32 current_opmode; u32 dcm_state = DCM_UNINIT; @@ -1344,6 +1346,7 @@ int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op) switch (pipe->type) { case MDSS_MDP_PIPE_TYPE_VIG: pipe_base = mdata->mdp_base + MDSS_MDP_REG_IGC_VIG_BASE; + pipe_cnt = mdata->nvig_pipes; switch (pipe->num) { case MDSS_MDP_SSPP_VIG0: pipe_num = 0; @@ -1365,6 +1368,7 @@ int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op) break; case MDSS_MDP_PIPE_TYPE_RGB: pipe_base = mdata->mdp_base + MDSS_MDP_REG_IGC_RGB_BASE; + pipe_cnt = mdata->nrgb_pipes; switch (pipe->num) { case MDSS_MDP_SSPP_RGB0: pipe_num = 0; @@ -1387,6 +1391,7 @@ int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op) case MDSS_MDP_PIPE_TYPE_DMA: pipe_base = mdata->mdp_base + MDSS_MDP_REG_IGC_DMA_BASE; pipe_num = pipe->num - MDSS_MDP_SSPP_DMA0; + pipe_cnt = mdata->ndma_pipes; break; default: pr_err("Invalid pipe type %d\n", pipe->type); @@ -1396,7 +1401,7 @@ int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op) if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_IGC_CFG) { flags |= PP_FLAGS_DIRTY_IGC; pp_igc_config(flags, pipe_base, &pipe->pp_res.pp_sts, - &pipe->pp_cfg.igc_cfg, pipe_num); + &pipe->pp_cfg.igc_cfg, pipe_num, pipe_cnt); } if (pipe->pp_res.pp_sts.igc_sts & PP_STS_ENABLE) @@ -1422,7 +1427,7 @@ static int pp_mixer_setup(u32 disp_num, /* no corresponding dspp */ if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) || - (dspp_num >= mdata->nmixers_intf)) + (dspp_num >= mdata->ndspp)) return 0; if (disp_num < MDSS_BLOCK_DISP_NUM) flags = mdss_pp_res->pp_disp_flags[disp_num]; @@ -1466,7 +1471,7 @@ static char __iomem *mdss_mdp_get_mixer_addr_off(u32 dspp_num) struct mdss_mdp_mixer *mixer; mdata = mdss_mdp_get_mdata(); - if (mdata->nmixers_intf <= dspp_num) { + if (mdata->ndspp <= dspp_num) { pr_err("Invalid dspp_num=%d\n", dspp_num); return ERR_PTR(-EINVAL); } @@ -1480,11 +1485,9 @@ static char __iomem *mdss_mdp_get_dspp_addr_off(u32 dspp_num) struct mdss_mdp_mixer *mixer; mdata = mdss_mdp_get_mdata(); - if (mdata->nmixers_intf <= dspp_num) { - pr_err("Invalid dspp_num=%d\n", dspp_num); - return ERR_PTR(-EINVAL); - } else if (mdata->ndspp <= dspp_num) { - pr_err("destination not supported dspp_num=%d", dspp_num); + if (mdata->ndspp <= dspp_num) { + pr_debug("destination not supported dspp_num=%d\n", + dspp_num); return ERR_PTR(-EINVAL); } mixer = mdata->mixer_intf + dspp_num; @@ -1669,7 +1672,7 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer) dspp_num = mixer->num; /* no corresponding dspp */ if ((mixer->type != MDSS_MDP_MIXER_TYPE_INTF) || - (dspp_num >= mdata->nmixers_intf)) + (dspp_num >= mdata->ndspp)) return -EINVAL; base = mdss_mdp_get_dspp_addr_off(dspp_num); if (IS_ERR(base)) @@ -1719,7 +1722,7 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer) pp_igc_config(flags, mdata->mdp_base + MDSS_MDP_REG_IGC_DSPP_BASE, pp_sts, &mdss_pp_res->igc_disp_cfg[disp_num], - dspp_num); + dspp_num, mdata->ndspp); pp_enhist_config(flags, base + MDSS_MDP_REG_DSPP_HIST_LUT_BASE, pp_sts, &mdss_pp_res->enhist_disp_cfg[disp_num]); @@ -1914,8 +1917,8 @@ int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 dspp_num) if (!mdata) return -EPERM; - if (dspp_num >= mdata->nmixers_intf) { - pr_warn("invalid dspp_num\n"); + if (dspp_num >= mdata->ndspp) { + pr_err("invalid dspp_num %d\n", dspp_num); return -EINVAL; } disp_num = ctl->mfd->index; @@ -2170,14 +2173,14 @@ int mdss_mdp_pp_init(struct device *dev) hist = devm_kzalloc(dev, sizeof(struct pp_hist_col_info) * - mdata->nmixers_intf, + mdata->ndspp, GFP_KERNEL); if (hist == NULL) { pr_err("dspp histogram allocation failed!\n"); ret = -ENOMEM; devm_kfree(dev, mdss_pp_res); } else { - for (i = 0; i < mdata->nmixers_intf; i++) { + for (i = 0; i < mdata->ndspp; i++) { mutex_init(&hist[i].hist_mutex); spin_lock_init(&hist[i].hist_lock); hist[i].intr_shift = (i * 4) + 12; @@ -2188,7 +2191,7 @@ int mdss_mdp_pp_init(struct device *dev) init_completion(&hist[i].comp); init_completion(&hist[i].first_kick); } - if (mdata->nmixers_intf == 4) + if (mdata->ndspp == 4) hist[3].intr_shift = 22; mdss_pp_res->dspp_hist = hist; @@ -2326,7 +2329,7 @@ static int pp_get_dspp_num(u32 disp_num, u32 *dspp_num) if (mixer_id[i] < mdata->nmixers_intf) break; } - if (i >= mixer_cnt || mixer_id[i] > mdata->ndspp) + if (i >= mixer_cnt || mixer_id[i] >= mdata->ndspp) return -EPERM; *dspp_num = mixer_id[i]; return 0; @@ -2737,16 +2740,15 @@ static void pp_read_igc_lut_cached(struct mdp_igc_lut_data *cfg) } static void pp_read_igc_lut(struct mdp_igc_lut_data *cfg, - char __iomem *addr, u32 blk_idx) + char __iomem *addr, u32 blk_idx, int32_t total_idx) { int i; u32 data; - struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - int32_t mask = 0, n_mixers = mdata->nmixers_intf; + int32_t mask = 0, idx = total_idx; - while (n_mixers > 0) { + while (idx > 0) { mask = (mask << 1) + 1; - n_mixers--; + idx--; } /* INDEX_UPDATE & VALUE_UPDATEN */ data = (3 << 24) | (((~(1 << blk_idx)) & mask) << 28); @@ -2767,16 +2769,16 @@ static void pp_read_igc_lut(struct mdp_igc_lut_data *cfg, } static void pp_update_igc_lut(struct mdp_igc_lut_data *cfg, - char __iomem *addr, u32 blk_idx) + char __iomem *addr, u32 blk_idx, + u32 total_idx) { int i; u32 data; - struct mdss_data_type *mdata = mdss_mdp_get_mdata(); - int32_t mask = 0, n_mixers = mdata->nmixers_intf; + int32_t mask = 0, idx = total_idx; - while (n_mixers > 0) { + while (idx > 0) { mask = (mask << 1) + 1; - n_mixers--; + idx--; } /* INDEX_UPDATE */ @@ -2873,7 +2875,8 @@ int mdss_mdp_igc_lut_config(struct mdp_igc_lut_data *config, if (mdata->has_no_lut_read) pp_read_igc_lut_cached(&local_cfg); else - pp_read_igc_lut(&local_cfg, igc_addr, dspp_num); + pp_read_igc_lut(&local_cfg, igc_addr, dspp_num, + mdata->ndspp); if (copy_to_user(config->c0_c1_data, local_cfg.c0_c1_data, config->len * sizeof(u32))) { ret = -EFAULT; @@ -3597,6 +3600,11 @@ int mdss_mdp_hist_start(struct mdp_histogram_start_req *req) } else if (PP_LOCAT(req->block) == MDSS_PP_DSPP_CFG) { for (i = 0; i < mixer_cnt; i++) { dspp_num = mixer_id[i]; + if (dspp_num >= mdata->ndspp) { + ret = -EINVAL; + pr_warn("Invalid dspp num %d\n", dspp_num); + goto hist_stop_clk; + } hist_info = &mdss_pp_res->dspp_hist[dspp_num]; ret = pp_hist_enable(hist_info, req); mdss_pp_res->pp_disp_flags[disp_num] |= @@ -3703,6 +3711,11 @@ int mdss_mdp_hist_stop(u32 block) } else if (PP_LOCAT(block) == MDSS_PP_DSPP_CFG) { for (i = 0; i < mixer_cnt; i++) { dspp_num = mixer_id[i]; + if (dspp_num >= mdata->ndspp) { + ret = -EINVAL; + pr_warn("Invalid dspp num %d\n", dspp_num); + goto hist_stop_clk; + } hist_info = &mdss_pp_res->dspp_hist[dspp_num]; ret = pp_hist_disable(hist_info); if (ret) @@ -4011,6 +4024,11 @@ int mdss_mdp_hist_collect(struct mdp_histogram_data *hist) if (PP_LOCAT(hist->block) == MDSS_PP_DSPP_CFG) { for (i = 0; i < hist_cnt; i++) { dspp_num = mixer_id[i]; + if (dspp_num >= mdata->ndspp) { + ret = -EINVAL; + pr_warn("Invalid dspp num %d\n", dspp_num); + goto hist_collect_exit; + } hists[i] = &mdss_pp_res->dspp_hist[dspp_num]; } for (i = 0; i < hist_cnt; i++) { @@ -4021,12 +4039,6 @@ int mdss_mdp_hist_collect(struct mdp_histogram_data *hist) } for (i = 0; i < hist_cnt; i++) { dspp_num = mixer_id[i]; - if (dspp_num > mdata->ndspp) { - pr_err("%s, hist destination not supported", - __func__); - ret = -EPERM; - goto hist_collect_exit; - } ctl_base = mdss_mdp_get_dspp_addr_off(dspp_num) + MDSS_MDP_REG_DSPP_HIST_CTL_BASE; exp_sum = (mdata->mixer_intf[dspp_num].width * |
