summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c88
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 *