summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeevan Shriram <jshriram@codeaurora.org>2015-01-30 17:10:35 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:38:14 -0700
commit6304466734a0423398e244fa54978a000366f8b5 (patch)
tree75541346099bdabe7961a282d0af3939385cbcaa
parentc3410a9b8eac3908399e4d937edf3aa3c81bb2a1 (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.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pipe.c176
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c5
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*/