summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c94
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c107
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c38
5 files changed, 194 insertions, 48 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index a6900c283df7..bee66c41ecb7 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -427,6 +427,7 @@ struct mdss_pipe_pp_res {
void *pa_cfg_payload;
void *pcc_cfg_payload;
void *igc_cfg_payload;
+ void *hist_lut_cfg_payload;
};
struct mdss_mdp_pipe_smp_map {
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c
index 07e132100a55..3f4684a6c800 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c
@@ -858,20 +858,26 @@ static int pp_vig_pipe_setup(struct mdss_mdp_pipe *pipe, u32 *op)
}
if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_HIST_LUT_CFG) {
- pp_enhist_config(PP_FLAGS_DIRTY_ENHIST,
+ flags = PP_FLAGS_DIRTY_ENHIST;
+ if (!pp_ops[HIST_LUT].pp_set_config) {
+ pp_enhist_config(flags,
pipe->base + MDSS_MDP_REG_VIG_HIST_LUT_BASE,
&pipe->pp_res.pp_sts,
&pipe->pp_cfg.hist_lut_cfg);
- }
-
- if (pipe->pp_res.pp_sts.enhist_sts & PP_STS_ENABLE) {
- if (!(pipe->pp_res.pp_sts.pa_sts & PP_STS_ENABLE)) {
- /* Program default value */
- offset = pipe->base + MDSS_MDP_REG_VIG_PA_BASE;
- writel_relaxed(0, offset);
- writel_relaxed(0, offset + 4);
- writel_relaxed(0, offset + 8);
- writel_relaxed(0, offset + 12);
+ if ((pipe->pp_res.pp_sts.enhist_sts & PP_STS_ENABLE) &&
+ !(pipe->pp_res.pp_sts.pa_sts & PP_STS_ENABLE)) {
+ /* Program default value */
+ offset = pipe->base + MDSS_MDP_REG_VIG_PA_BASE;
+ writel_relaxed(0, offset);
+ writel_relaxed(0, offset + 4);
+ writel_relaxed(0, offset + 8);
+ writel_relaxed(0, offset + 12);
+ }
+ } else {
+ pp_ops[HIST_LUT].pp_set_config(pipe->base,
+ &pipe->pp_res.pp_sts,
+ &pipe->pp_cfg.hist_lut_cfg,
+ SSPP_VIG);
}
}
@@ -1264,6 +1270,7 @@ void mdss_mdp_pipe_sspp_term(struct mdss_mdp_pipe *pipe)
kfree(pipe->pp_res.pa_cfg_payload);
kfree(pipe->pp_res.igc_cfg_payload);
kfree(pipe->pp_res.pcc_cfg_payload);
+ kfree(pipe->pp_res.hist_lut_cfg_payload);
memset(&pipe->pp_cfg, 0, sizeof(struct mdp_overlay_pp_params));
memset(&pipe->pp_res, 0, sizeof(struct mdss_pipe_pp_res));
}
@@ -1762,6 +1769,16 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
base + MDSS_MDP_REG_DSPP_HIST_LUT_BASE,
pp_sts,
&mdss_pp_res->enhist_disp_cfg[disp_num]);
+
+ if ((pp_sts->enhist_sts & PP_STS_ENABLE) &&
+ !(pp_sts->pa_sts & PP_STS_ENABLE)) {
+ /* Program default value */
+ addr = base + MDSS_MDP_REG_DSPP_PA_BASE;
+ writel_relaxed(0, addr);
+ writel_relaxed(0, addr + 4);
+ writel_relaxed(0, addr + 8);
+ writel_relaxed(0, addr + 12);
+ }
} else {
/* Pass dspp num using block */
mdss_pp_res->enhist_disp_cfg[disp_num].block = dspp_num;
@@ -1770,15 +1787,6 @@ static int pp_dspp_setup(u32 disp_num, struct mdss_mdp_mixer *mixer)
}
}
- if (pp_sts->enhist_sts & PP_STS_ENABLE &&
- !(pp_sts->pa_sts & PP_STS_ENABLE)) {
- /* Program default value */
- addr = base + MDSS_MDP_REG_DSPP_PA_BASE;
- writel_relaxed(0, addr);
- writel_relaxed(0, addr + 4);
- writel_relaxed(0, addr + 8);
- writel_relaxed(0, addr + 12);
- }
if (flags & PP_FLAGS_DIRTY_DITHER) {
if (!pp_ops[DITHER].pp_set_config) {
pp_dither_config(addr, pp_sts,
@@ -3482,6 +3490,7 @@ int mdss_mdp_hist_lut_config(struct mdp_hist_lut_data *config,
int i, ret = 0;
u32 disp_num, dspp_num = 0;
char __iomem *hist_addr = NULL, *base_addr = NULL;
+ struct mdp_pp_cache_res res_cache;
if ((PP_BLOCK(config->block) < MDP_LOGICAL_BLOCK_DISP_0) ||
(PP_BLOCK(config->block) >= MDP_BLOCK_MAX))
@@ -3529,7 +3538,10 @@ hist_lut_clk_off:
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
} else {
if (pp_ops[HIST_LUT].pp_set_config) {
- ret = pp_hist_lut_cache_params(config, mdss_pp_res);
+ res_cache.block = DSPP;
+ res_cache.mdss_pp_res = mdss_pp_res;
+ res_cache.pipe_res = NULL;
+ ret = pp_hist_lut_cache_params(config, &res_cache);
if (ret) {
pr_err("hist_lut config failed version %d ret %d\n",
config->version, ret);
@@ -6201,18 +6213,36 @@ int mdss_mdp_pp_sspp_config(struct mdss_mdp_pipe *pipe)
mdss_mdp_hist_stop(pipe->pp_cfg.hist_cfg.block);
}
}
- len = pipe->pp_cfg.hist_lut_cfg.len;
- if ((pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_HIST_LUT_CFG) &&
- (len == ENHIST_LUT_ENTRIES)) {
- ret = copy_from_user(pipe->pp_res.hist_lut,
- pipe->pp_cfg.hist_lut_cfg.data,
- sizeof(uint32_t) * len);
- if (ret) {
- ret = -EFAULT;
- pr_err("failed to copy the hist lut\n");
- goto exit_fail;
+ if (pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_HIST_LUT_CFG) {
+ if (!pp_ops[HIST_LUT].pp_set_config) {
+ len = pipe->pp_cfg.hist_lut_cfg.len;
+ if (len != ENHIST_LUT_ENTRIES) {
+ ret = -EINVAL;
+ pr_err("Invalid hist lut len: %d\n", len);
+ goto exit_fail;
+ }
+ ret = copy_from_user(pipe->pp_res.hist_lut,
+ pipe->pp_cfg.hist_lut_cfg.data,
+ sizeof(uint32_t) * len);
+ if (ret) {
+ ret = -EFAULT;
+ pr_err("failed to copy the hist lut\n");
+ goto exit_fail;
+ }
+ pipe->pp_cfg.hist_lut_cfg.data = pipe->pp_res.hist_lut;
+ } else {
+ cache_res.block = SSPP_VIG;
+ cache_res.mdss_pp_res = NULL;
+ cache_res.pipe_res = pipe;
+ ret = pp_hist_lut_cache_params(
+ &pipe->pp_cfg.hist_lut_cfg,
+ &cache_res);
+ if (ret) {
+ pr_err("Failed to cache Hist LUT params on pipe %d, ret %d\n",
+ pipe->num, ret);
+ goto exit_fail;
+ }
}
- pipe->pp_cfg.hist_lut_cfg.data = pipe->pp_res.hist_lut;
}
if ((pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_PA_V2_CFG) &&
(pp_ops[PA].pp_set_config)) {
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
index 9a4b037b35f5..633527ed790c 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.c
@@ -134,18 +134,115 @@ static int pp_hist_lut_cache_params_v1_7(struct mdp_hist_lut_data *config,
return ret;
}
+static int pp_hist_lut_cache_params_pipe_v1_7(struct mdp_hist_lut_data *config,
+ struct mdss_mdp_pipe *pipe)
+{
+ struct mdp_hist_lut_data_v1_7 *hist_lut_cache_data;
+ struct mdp_hist_lut_data_v1_7 hist_lut_usr_config;
+ int ret = 0;
+
+ if (!config || !pipe) {
+ pr_err("Invalid param config %p pipe %p\n",
+ config, pipe);
+ return -EINVAL;
+ }
+
+ if (config->ops & MDP_PP_OPS_DISABLE) {
+ pr_debug("Disable Hist LUT on pipe %d\n", pipe->num);
+ goto hist_lut_cache_pipe_exit;
+ }
+
+ if (config->ops & MDP_PP_OPS_READ) {
+ pr_err("Read op is not supported\n");
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&hist_lut_usr_config,
+ config->cfg_payload,
+ sizeof(struct mdp_hist_lut_data_v1_7))) {
+ pr_err("Failed to copy usr cfg_payload\n");
+ ret = -EFAULT;
+ goto hist_lut_cache_pipe_exit;
+ }
+
+ hist_lut_cache_data = pipe->pp_res.hist_lut_cfg_payload;
+ if (!hist_lut_cache_data) {
+ hist_lut_cache_data = kzalloc(
+ sizeof(struct mdp_hist_lut_data_v1_7),
+ GFP_KERNEL);
+ if (!hist_lut_cache_data) {
+ pr_err("failed to allocate cache_data\n");
+ ret = -ENOMEM;
+ goto hist_lut_cache_pipe_exit;
+ } else
+ pipe->pp_res.hist_lut_cfg_payload = hist_lut_cache_data;
+ }
+
+ *hist_lut_cache_data = hist_lut_usr_config;
+
+ if (hist_lut_cache_data->len != ENHIST_LUT_ENTRIES) {
+ pr_err("Invalid Hist LUT length %d\n",
+ hist_lut_cache_data->len);
+ ret = -EINVAL;
+ goto hist_lut_cache_pipe_exit;
+ }
+
+ if (copy_from_user(pipe->pp_res.hist_lut,
+ hist_lut_usr_config.data,
+ sizeof(uint32_t) * hist_lut_cache_data->len)) {
+ pr_err("Failed to copy usr Hist LUT data\n");
+ ret = -EFAULT;
+ goto hist_lut_cache_pipe_exit;
+ }
+
+ hist_lut_cache_data->data = pipe->pp_res.hist_lut;
+
+hist_lut_cache_pipe_exit:
+ if (ret || (config->ops & MDP_PP_OPS_DISABLE)) {
+ kfree(pipe->pp_res.hist_lut_cfg_payload);
+ pipe->pp_res.hist_lut_cfg_payload = NULL;
+ }
+ pipe->pp_cfg.hist_lut_cfg.cfg_payload =
+ pipe->pp_res.hist_lut_cfg_payload;
+ return ret;
+}
+
int pp_hist_lut_cache_params(struct mdp_hist_lut_data *config,
- struct mdss_pp_res_type *mdss_pp_res)
+ struct mdp_pp_cache_res *res_cache)
{
int ret = 0;
- if (!config || !mdss_pp_res) {
- pr_err("invalid param config %p pp_res %p\n",
- config, mdss_pp_res);
+
+ if (!config || !res_cache) {
+ pr_err("invalid param config %p res_cache %p\n",
+ config, res_cache);
+ return -EINVAL;
+ }
+ if (res_cache->block != SSPP_VIG && res_cache->block != DSPP) {
+ pr_err("invalid block for Hist LUT %d\n", res_cache->block);
return -EINVAL;
}
+ if (!res_cache->mdss_pp_res && !res_cache->pipe_res) {
+ pr_err("NULL payload for block %d mdss_pp_res %p pipe_res %p\n",
+ res_cache->block, res_cache->mdss_pp_res,
+ res_cache->pipe_res);
+ return -EINVAL;
+ }
+
switch (config->version) {
case mdp_hist_lut_v1_7:
- ret = pp_hist_lut_cache_params_v1_7(config, mdss_pp_res);
+ if (res_cache->block == DSPP) {
+ ret = pp_hist_lut_cache_params_v1_7(config,
+ res_cache->mdss_pp_res);
+ if (ret)
+ pr_err("failed to cache Hist LUT params for DSPP ret %d\n",
+ ret);
+ } else {
+ ret = pp_hist_lut_cache_params_pipe_v1_7(config,
+ res_cache->pipe_res);
+ if (ret)
+ pr_err("failed to cache Hist LUT params for SSPP ret %d\n",
+ ret);
+ }
break;
default:
pr_err("unsupported hist_lut version %d\n",
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.h b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.h
index 5f6956b782ce..8e5661371bf6 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp_cache_config.h
@@ -23,7 +23,7 @@ struct mdp_pp_cache_res {
};
int pp_hist_lut_cache_params(struct mdp_hist_lut_data *config,
- struct mdss_pp_res_type *mdss_pp_res);
+ struct mdp_pp_cache_res *res_cache);
int pp_dither_cache_params(struct mdp_dither_cfg_data *config,
struct mdss_pp_res_type *mdss_pp_res);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c b/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c
index 5213bbdfde46..e23e9d6143c4 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c
@@ -62,10 +62,13 @@
#define IGC_DATA_MASK (BIT(12) - 1)
#define IGC_DSPP_OP_MODE_EN BIT(0)
-#define MDSS_MDP_DSPP_OP_PA_LUTV_FIRST_EN BIT(21)
-#define REG_SSPP_VIG_HIST_LUT_BASE 0x1200
+#define HIST_LUT_VIG_OP_FIRST_EN BIT(21)
+#define HIST_LUT_DSPP_OP_FIRST_EN BIT(21)
+#define HIST_LUT_VIG_OP_ENABLE BIT(10)
+#define HIST_LUT_DSPP_OP_ENABLE BIT(19)
+#define REG_SSPP_VIG_HIST_LUT_BASE 0x1400
#define REG_DSPP_HIST_LUT_BASE 0x1400
-#define REG_SSPP_VIG_HIST_SWAP_BASE 0x100
+#define REG_SSPP_VIG_HIST_SWAP_BASE 0x300
#define REG_DSPP_HIST_SWAP_BASE 0x234
#define ENHIST_LOWER_VALUE_MASK 0x3FF
#define ENHIST_UPPER_VALUE_MASK 0x3FF0000
@@ -314,6 +317,12 @@ static void pp_opmode_config(int location, struct pp_sts_type *pp_sts,
case SSPP_VIG:
if (pp_sts->pa_sts & PP_STS_ENABLE)
pp_pa_update_vig_opmode(pp_sts->pa_sts, opmode);
+ if (pp_sts->enhist_sts & PP_STS_ENABLE) {
+ *opmode |= HIST_LUT_VIG_OP_ENABLE |
+ PA_VIG_OP_ENABLE;
+ if (pp_sts->enhist_sts & PP_STS_PA_LUT_FIRST)
+ *opmode |= HIST_LUT_VIG_OP_FIRST_EN;
+ }
break;
case DSPP:
if (pp_sts_is_enabled(pp_sts->pa_sts, side))
@@ -321,10 +330,10 @@ static void pp_opmode_config(int location, struct pp_sts_type *pp_sts,
if (pp_sts_is_enabled(pp_sts->igc_sts, side))
*opmode |= IGC_DSPP_OP_MODE_EN;
if (pp_sts->enhist_sts & PP_STS_ENABLE) {
- *opmode |= MDSS_MDP_DSPP_OP_HIST_LUTV_EN |
- MDSS_MDP_DSPP_OP_PA_EN;
+ *opmode |= HIST_LUT_DSPP_OP_ENABLE |
+ PA_DSPP_OP_ENABLE;
if (pp_sts->enhist_sts & PP_STS_PA_LUT_FIRST)
- *opmode |= MDSS_MDP_DSPP_OP_PA_LUTV_FIRST_EN;
+ *opmode |= HIST_LUT_DSPP_OP_FIRST_EN;
}
if (pp_sts_is_enabled(pp_sts->dither_sts, side))
*opmode |= MDSS_MDP_DSPP_OP_DST_DITHER_EN;
@@ -434,12 +443,16 @@ static int pp_hist_lut_set_config(char __iomem *base_addr,
}
lut_cfg_data = (struct mdp_hist_lut_data *) cfg_data;
- if (lut_cfg_data->version != mdp_hist_lut_v1_7 ||
- !lut_cfg_data->cfg_payload) {
- pr_err("invalid hist_lut version %d payload %p\n",
- lut_cfg_data->version, lut_cfg_data->cfg_payload);
+ if (lut_cfg_data->version != mdp_hist_lut_v1_7) {
+ pr_err("invalid hist_lut version %d\n", lut_cfg_data->version);
return -EINVAL;
}
+
+ if (lut_cfg_data->ops & MDP_PP_OPS_DISABLE) {
+ pr_debug("Disable Hist LUT\n");
+ goto bail_out;
+ }
+
if (!(lut_cfg_data->ops & ~(MDP_PP_OPS_READ))) {
pr_err("only read ops set for lut\n");
return ret;
@@ -449,6 +462,11 @@ static int pp_hist_lut_set_config(char __iomem *base_addr,
goto bail_out;
}
lut_data = lut_cfg_data->cfg_payload;
+ if (!lut_data) {
+ pr_err("invalid hist_lut cfg_payload %p\n", lut_data);
+ return -EINVAL;
+ }
+
if (lut_data->len != ENHIST_LUT_ENTRIES || !lut_data->data) {
pr_err("invalid hist_lut len %d data %p\n",
lut_data->len, lut_data->data);