diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 21 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_hwio.h | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 25 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.c | 68 |
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) { |
