summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h21
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_hwio.h8
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c25
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c68
5 files changed, 97 insertions, 27 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index d87ab8e240c5..6d408d1758cb 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -212,6 +212,24 @@ struct mdss_mdp_data {
struct mdss_mdp_img_data p[MAX_PLANES];
};
+struct pp_sts_type {
+ u32 pa_sts;
+ u32 pcc_sts;
+ u32 igc_sts;
+ u32 igc_tbl_idx;
+ u32 argc_sts;
+ u32 enhist_sts;
+ u32 dither_sts;
+ u32 gamut_sts;
+ u32 pgc_sts;
+};
+
+struct mdss_pipe_pp_res {
+ u32 igc_c0_c1[IGC_LUT_ENTRIES];
+ u32 igc_c2[IGC_LUT_ENTRIES];
+ struct pp_sts_type pp_sts;
+};
+
struct mdss_mdp_pipe {
u32 num;
u32 type;
@@ -252,6 +270,7 @@ struct mdss_mdp_pipe {
struct list_head cleanup_list;
struct mdp_overlay_pp_params pp_cfg;
+ struct mdss_pipe_pp_res pp_res;
};
struct mdss_mdp_writeback_arg {
@@ -318,8 +337,10 @@ int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx,
int mdss_mdp_pp_init(struct device *dev);
void mdss_mdp_pp_term(struct device *dev);
int mdss_mdp_pp_resume(u32 mixer_num);
+
int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl);
int mdss_mdp_pipe_pp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
+int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback);
int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *cfg_ptr, u32 *copyback);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
index dd0d998aee11..270b42779fa4 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
@@ -16,6 +16,11 @@
#include <linux/bitops.h>
+#define IGC_LUT_ENTRIES 256
+#define GC_LUT_SEGMENTS 16
+#define ENHIST_LUT_ENTRIES 256
+#define HIST_V_SIZE 256
+
#define MDSS_REG_HW_VERSION 0x0
#define MDSS_REG_HW_INTR_STATUS 0x10
@@ -160,6 +165,9 @@ enum mdss_mdp_sspp_chroma_samp_type {
#define MDSS_MDP_REG_SSPP_SRC_OP_MODE 0x038
#define MDSS_MDP_OP_DEINTERLACE BIT(22)
#define MDSS_MDP_OP_DEINTERLACE_ODD BIT(23)
+#define MDSS_MDP_OP_IGC_ROM_1 BIT(18)
+#define MDSS_MDP_OP_IGC_ROM_0 BIT(17)
+#define MDSS_MDP_OP_IGC_EN BIT(16)
#define MDSS_MDP_OP_FLIP_UD BIT(14)
#define MDSS_MDP_OP_FLIP_LR BIT(13)
#define MDSS_MDP_OP_BWC_EN BIT(0)
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 0bc506b756e2..c5ccbc945a28 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -232,7 +232,7 @@ static int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
struct mdss_mdp_format_params *fmt;
struct mdss_mdp_pipe *pipe;
struct mdss_mdp_mixer *mixer = NULL;
- u32 pipe_type, mixer_mux;
+ u32 pipe_type, mixer_mux, len;
int ret;
if (mfd == NULL || mfd->ctl == NULL)
@@ -337,12 +337,25 @@ static int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd,
pipe->req_data = *req;
if (pipe->flags & MDP_OVERLAY_PP_CFG_EN) {
- if (pipe->num <= MDSS_MDP_SSPP_VIG2)
- memcpy(&pipe->pp_cfg, &req->overlay_pp_cfg,
+ memcpy(&pipe->pp_cfg, &req->overlay_pp_cfg,
sizeof(struct mdp_overlay_pp_params));
- else
- pr_debug("%s: RGB Pipes don't support CSC/QSEED\n",
- __func__);
+ len = pipe->pp_cfg.igc_cfg.len;
+ if ((pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_IGC_CFG) &&
+ (len == IGC_LUT_ENTRIES)) {
+ ret = copy_from_user(pipe->pp_res.igc_c0_c1,
+ pipe->pp_cfg.igc_cfg.c0_c1_data,
+ sizeof(uint32_t) * len);
+ if (ret)
+ return -ENOMEM;
+ ret = copy_from_user(pipe->pp_res.igc_c2,
+ pipe->pp_cfg.igc_cfg.c2_data,
+ sizeof(uint32_t) * len);
+ if (ret)
+ return -ENOMEM;
+ pipe->pp_cfg.igc_cfg.c0_c1_data =
+ pipe->pp_res.igc_c0_c1;
+ pipe->pp_cfg.igc_cfg.c2_data = pipe->pp_res.igc_c2;
+ }
}
if (pipe->flags & MDP_DEINTERLACE) {
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
index 1f381e173f00..8efd00eecf88 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c
@@ -584,6 +584,8 @@ static int mdss_mdp_format_setup(struct mdss_mdp_pipe *pipe)
unpack = 0;
}
+ mdss_mdp_pipe_sspp_setup(pipe, &opmode);
+
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_FORMAT, src_format);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN, unpack);
mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_OP_MODE, opmode);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c
index 21f7f776f5da..96596e1c1f6d 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c
@@ -78,11 +78,6 @@ struct mdp_csc_cfg mdp_csc_convert[MDSS_MDP_MAX_CSC] = {
#define MDSS_BLOCK_DISP_NUM (MDP_BLOCK_MAX - MDP_LOGICAL_BLOCK_DISP_0)
-#define IGC_LUT_ENTRIES 256
-#define GC_LUT_SEGMENTS 16
-#define ENHIST_LUT_ENTRIES 256
-#define HIST_V_SIZE 256
-
#define HIST_WAIT_TIMEOUT(frame) ((60 * HZ * (frame)) / 1000)
/* hist collect state */
enum {
@@ -122,18 +117,6 @@ static u32 dither_depth_map[9] = {
GAMUT_T2_SIZE + GAMUT_T3_SIZE + GAMUT_T4_SIZE + \
GAMUT_T5_SIZE + GAMUT_T6_SIZE + GAMUT_T7_SIZE)
-struct pp_sts_type {
- u32 pa_sts;
- u32 pcc_sts;
- u32 igc_sts;
- u32 igc_tbl_idx;
- u32 argc_sts;
- u32 enhist_sts;
- u32 dither_sts;
- u32 gamut_sts;
- u32 pgc_sts;
-};
-
#define PP_FLAGS_DIRTY_PA 0x1
#define PP_FLAGS_DIRTY_PCC 0x2
#define PP_FLAGS_DIRTY_IGC 0x4
@@ -409,7 +392,6 @@ static void pp_enhist_config(unsigned long flags, u32 base,
static int pp_vig_pipe_setup(struct mdss_mdp_pipe *pipe, u32 *op)
{
- struct pp_sts_type pp_sts;
u32 opmode = 0, base = 0;
unsigned long flags = 0;
@@ -450,10 +432,10 @@ static int pp_vig_pipe_setup(struct mdss_mdp_pipe *pipe, u32 *op)
flags = PP_FLAGS_DIRTY_PA;
base = MDSS_MDP_REG_SSPP_OFFSET(pipe->num) +
MDSS_MDP_REG_VIG_PA_BASE;
- pp_sts.pa_sts = 0;
- pp_pa_config(flags, base, &pp_sts,
+ pp_pa_config(flags, base, &pipe->pp_res.pp_sts,
&pipe->pp_cfg.pa_cfg);
- if (pp_sts.pa_sts & PP_STS_ENABLE)
+
+ if (pipe->pp_res.pp_sts.pa_sts & PP_STS_ENABLE)
opmode |= (1 << 4); /* PA_EN */
}
}
@@ -479,6 +461,50 @@ int mdss_mdp_pipe_pp_setup(struct mdss_mdp_pipe *pipe, u32 *op)
return ret;
}
+int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op)
+{
+ int ret = 0;
+ unsigned long flags = 0;
+ u32 pipe_base;
+ u32 pipe_num;
+
+ if (pipe == NULL)
+ return -EINVAL;
+
+ /*
+ * TODO: should this function be responsible for masking multiple
+ * pipes to be written in dual pipe case?
+ * if so, requires rework of update_igc_lut
+ */
+ switch (pipe->type) {
+ case MDSS_MDP_PIPE_TYPE_VIG:
+ pipe_base = MDSS_MDP_REG_IGC_VIG_BASE;
+ pipe_num = pipe->num - MDSS_MDP_SSPP_VIG0;
+ break;
+ case MDSS_MDP_PIPE_TYPE_RGB:
+ pipe_base = MDSS_MDP_REG_IGC_RGB_BASE;
+ pipe_num = pipe->num - MDSS_MDP_SSPP_RGB0;
+ break;
+ case MDSS_MDP_PIPE_TYPE_DMA:
+ pipe_base = MDSS_MDP_REG_IGC_DMA_BASE;
+ pipe_num = pipe->num - MDSS_MDP_SSPP_DMA0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ 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);
+ }
+
+ if (pipe->pp_res.pp_sts.igc_sts & PP_STS_ENABLE)
+ *op |= (1 << 16); /* IGC_LUT_EN */
+
+ return ret;
+}
+
static int pp_mixer_setup(u32 disp_num, struct mdss_mdp_ctl *ctl,
struct mdss_mdp_mixer *mixer)
{