diff options
| author | Jeevan Shriram <jshriram@codeaurora.org> | 2015-01-30 17:10:35 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:38:14 -0700 |
| commit | 6304466734a0423398e244fa54978a000366f8b5 (patch) | |
| tree | 75541346099bdabe7961a282d0af3939385cbcaa | |
| parent | c3410a9b8eac3908399e4d937edf3aa3c81bb2a1 (diff) | |
msm: mdss: calculate software scalar pixel extensions
When there is no data available for pixel extensions from user end,
calculate software pixel extensions with zero initial phase.
Change-Id: I8876b27e4265b39374d5520684028aaaf005d7e8
Signed-off-by: Jeevan Shriram <jshriram@codeaurora.org>
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 176 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.c | 5 |
4 files changed, 185 insertions, 2 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 60536d172ce4..7b98dbefcb80 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -35,6 +35,8 @@ #define MDSS_MDP_PIXEL_RAM_SIZE (50 * 1024) #define PHASE_STEP_SHIFT 21 +#define PHASE_STEP_UNIT_SCALE ((int) (1 << PHASE_STEP_SHIFT)) +#define PHASE_RESIDUAL 15 #define MAX_LINE_BUFFER_WIDTH 2048 #define MAX_MIXER_HEIGHT 0xFFFF #define MAX_IMG_WIDTH 0x3FFF @@ -1105,6 +1107,7 @@ int mdss_mdp_wb_get_format(struct msm_fb_data_type *mfd, struct mdp_mixer_cfg *mixer_cfg); int mdss_mdp_pipe_program_pixel_extn(struct mdss_mdp_pipe *pipe); +void mdss_mdp_pipe_calc_pixel_extn(struct mdss_mdp_pipe *pipe); int mdss_mdp_wb_set_secure(struct msm_fb_data_type *mfd, int enable); int mdss_mdp_wb_get_secure(struct msm_fb_data_type *mfd, uint8_t *enable); void mdss_mdp_ctl_restore(void); diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index a495ecbd21c4..58598ebb538b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -551,6 +551,9 @@ int mdss_mdp_overlay_setup_scaling(struct mdss_mdp_pipe *pipe) pr_err("Vertical scaling calculation failed=%d! %d->%d\n", rc, src, pipe->dst.h); } + + mdss_mdp_pipe_calc_pixel_extn(pipe); + return rc; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index 2292a0f1e974..4539c6f065ca 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -1942,3 +1942,179 @@ int mdss_mdp_pipe_program_pixel_extn(struct mdss_mdp_pipe *pipe) __mdss_mdp_pipe_program_pixel_extn_helper(pipe, 3, 32); return 0; } + + +static int __pxl_extn_helper(int residue) +{ + int tmp = 0; + if (residue == 0) { + return tmp; + } else if (residue > 0) { + tmp = (uint32_t) residue; + tmp >>= PHASE_STEP_SHIFT; + return -tmp; + } else { + tmp = (uint32_t)(-residue); + tmp >>= PHASE_STEP_SHIFT; + if ((tmp << PHASE_STEP_SHIFT) != (-residue)) + tmp++; + return tmp; + } +} + +/** + * mdss_mdp_calc_pxl_extn - Calculate source pipe's sw pixel extension + * + * @pipe: Source pipe struct containing pixel extn values + * + * Function calculates the pixel extn values during scale setup. + */ +void mdss_mdp_pipe_calc_pixel_extn(struct mdss_mdp_pipe *pipe) +{ + int caf, i; + uint32_t src_h; + uint32_t unity_scale = 0, upscale = 0; + + if (!(pipe->src_fmt->is_yuv)) + unity_scale = (pipe->src.w == pipe->dst.w); + + if (!unity_scale) + upscale = (pipe->src.w <= pipe->dst.w); + + pr_debug("pipe=%d, src(%d, %d, %d, %d), dest(%d, %d, %d, %d)\n", + pipe->num, + pipe->src.x, pipe->src.y, pipe->src.w, pipe->src.h, + pipe->dst.x, pipe->dst.y, pipe->dst.w, pipe->dst.h); + + for (i = 0; i < MAX_PLANES; i++) { + int64_t left = 0, right = 0, top = 0, bottom = 0; + caf = 0; + + /* + * phase step x,y for 0 plane should be calculated before + * this + */ + if (pipe->src_fmt->is_yuv) { + if (i == 1 || i == 2) { + pipe->scale.phase_step_x[i] = + pipe->scale.phase_step_x[0] / 2; + pipe->scale.phase_step_y[i] = + pipe->scale.phase_step_y[0] / 2; + } else { + pipe->scale.phase_step_x[i] = + pipe->scale.phase_step_x[0]; + pipe->scale.phase_step_y[i] = + pipe->scale.phase_step_y[0]; + } + } else { + pipe->scale.phase_step_x[i] = + pipe->scale.phase_step_x[0]; + pipe->scale.phase_step_y[i] = + pipe->scale.phase_step_y[0]; + } + /* Pixel extension calculations for X direction */ + pipe->scale.roi_w[i] = DECIMATED_DIMENSION(pipe->src.w, + pipe->horz_deci); + + if (pipe->src_fmt->is_yuv) + pipe->scale.roi_w[i] &= ~0x1; + + /* CAF filtering on only luma plane */ + if (i == 0 && pipe->src_fmt->is_yuv) + caf = 1; + if (i == 1 || i == 2) + pipe->scale.roi_w[i] >>= pipe->chroma_sample_h; + + pr_debug("roi_w[%d]=%d, caf=%d\n", i, pipe->scale.roi_w[i], + caf); + if (unity_scale) { + left = 0; + right = 0; + } else if (!upscale) { + left = 0; + right = (pipe->dst.w - 1) * + pipe->scale.phase_step_x[i]; + right -= (pipe->scale.roi_w[i] - 1) * + PHASE_STEP_UNIT_SCALE; + right += pipe->scale.phase_step_x[i]; + right = -(right); + } else { + left = (1 << PHASE_RESIDUAL); + left -= (caf * PHASE_STEP_UNIT_SCALE); + + right = (1 << PHASE_RESIDUAL); + right += (pipe->dst.w - 1) * + pipe->scale.phase_step_x[i]; + right -= ((pipe->scale.roi_w[i] - 1) * + PHASE_STEP_UNIT_SCALE); + right += (caf * PHASE_STEP_UNIT_SCALE); + right = -(right); + } + pr_debug("left=%lld, right=%lld\n", left, right); + pipe->scale.num_ext_pxls_left[i] = __pxl_extn_helper(left); + pipe->scale.num_ext_pxls_right[i] = __pxl_extn_helper(right); + + /* Pixel extension calculations for Y direction */ + unity_scale = 0; + upscale = 0; + src_h = DECIMATED_DIMENSION(pipe->src.h, pipe->vert_deci); + + /* Subsampling of chroma components is factored */ + if (i == 1 || i == 2) + src_h >>= pipe->chroma_sample_v; + + if (!(pipe->src_fmt->is_yuv)) + unity_scale = (src_h == pipe->dst.h); + + if (!unity_scale) + upscale = (src_h <= pipe->dst.h); + + if (unity_scale) { + top = 0; + bottom = 0; + } else if (!upscale) { + top = 0; + bottom = (pipe->dst.h - 1) * + pipe->scale.phase_step_y[i]; + bottom -= (src_h - 1) * PHASE_STEP_UNIT_SCALE; + bottom += pipe->scale.phase_step_y[i]; + bottom = -(bottom); + } else { + top = (1 << PHASE_RESIDUAL); + top -= (caf * PHASE_STEP_UNIT_SCALE); + + bottom = (1 << PHASE_RESIDUAL); + bottom += (pipe->dst.h - 1) * + pipe->scale.phase_step_y[i]; + bottom -= (src_h - 1) * PHASE_STEP_UNIT_SCALE; + bottom += (caf * PHASE_STEP_UNIT_SCALE); + bottom = -(bottom); + } + + pipe->scale.num_ext_pxls_top[i] = __pxl_extn_helper(top); + pipe->scale.num_ext_pxls_btm[i] = __pxl_extn_helper(bottom); + + /* Single pixel rgb scale adjustment */ + if ((!(pipe->src_fmt->is_yuv)) && + ((pipe->src.h - pipe->dst.h) == 1)) { + + uint32_t residue = pipe->scale.phase_step_y[i] - + PHASE_STEP_UNIT_SCALE; + uint32_t result = (pipe->dst.h * residue) + residue; + if (result < PHASE_STEP_UNIT_SCALE) + pipe->scale.num_ext_pxls_btm[i] -= 1; + } + + pipe->scale.left_rpt[i] = pipe->scale.num_ext_pxls_left[i]; + pipe->scale.right_rpt[i] = pipe->scale.num_ext_pxls_right[i]; + pipe->scale.top_rpt[i] = pipe->scale.num_ext_pxls_top[i]; + pipe->scale.btm_rpt[i] = pipe->scale.num_ext_pxls_btm[i]; + pr_debug("plane=%d, left=%d, right=%d, top=%d, btm=%d\n", + i, pipe->scale.left_rpt[i], + pipe->scale.right_rpt[i], + pipe->scale.top_rpt[i], + pipe->scale.btm_rpt[i]); + } + + pipe->scale.enable_pxl_ext = 1; +} diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index 08e3ceba56bb..3cbcef6e85c3 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -979,6 +979,9 @@ static int mdss_mdp_scale_setup(struct mdss_mdp_pipe *pipe) else filter_mode = MDSS_MDP_SCALE_FILTER_BIL; + if (pipe->scale.enable_pxl_ext) + mdss_mdp_pipe_program_pixel_extn(pipe); + if (pipe->type == MDSS_MDP_PIPE_TYPE_DMA) { if (pipe->dst.h != pipe->src.h || pipe->dst.w != pipe->src.w) { pr_err("no scaling supported on dma pipe\n"); @@ -1172,8 +1175,6 @@ static int mdss_mdp_scale_setup(struct mdss_mdp_pipe *pipe) pipe->base + MDSS_MDP_REG_SCALE_INIT_PHASE_Y); } - /*program pixel extn values for the SSPP*/ - mdss_mdp_pipe_program_pixel_extn(pipe); } else { if (pipe->type == MDSS_MDP_PIPE_TYPE_VIG) { /*program x,y initial phase and phase step*/ |
