msm: mdss: fix issue in calculating decimated dimensions
Width and height are not properly calculated when decimation
is involved. When there is scaling on a pipe, the required number
of pixels are wrongly programmed resulting in pipe hangs and
leading to TLB SYNC issues. This change handles proper
calculation of decimated width and height.
Change-Id: Iadc4b201b32dda3dba6afe23070f349677be417c
Signed-off-by: Jeevan Shriram <jshriram@codeaurora.org>
Signed-off-by: Raghavendra Ambadas <rambad@codeaurora.org>
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 0b02ed6..b0b5a61 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -364,7 +364,7 @@
* no need to account for these lines in MDP clock or request bus
* bandwidth to fetch them.
*/
- src_h = src.h >> pipe->vert_deci;
+ src_h = DECIMATED_DIMENSION(src.h, pipe->vert_deci);
quota = fps * src.w * src_h;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 449943b..5b99105 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -245,8 +245,8 @@
dst_h = req->dst_rect.h;
}
- src_w = req->src_rect.w >> req->horz_deci;
- src_h = req->src_rect.h >> req->vert_deci;
+ src_w = DECIMATED_DIMENSION(req->src_rect.w, req->horz_deci);
+ src_h = DECIMATED_DIMENSION(req->src_rect.h, req->vert_deci);
if (src_w > MAX_MIXER_WIDTH) {
pr_err("invalid source width=%d HDec=%d\n",
@@ -359,8 +359,8 @@
u32 hor_req_pixels, hor_fetch_pixels;
u32 hor_ov_fetch, vert_ov_fetch;
u32 vert_req_pixels, vert_fetch_pixels;
- u32 src_w = pipe->src.w >> pipe->horz_deci;
- u32 src_h = pipe->src.h >> pipe->vert_deci;
+ u32 src_w = DECIMATED_DIMENSION(pipe->src.w, pipe->horz_deci);
+ u32 src_h = DECIMATED_DIMENSION(pipe->src.h, pipe->vert_deci);
/*
* plane 1 and 2 are for chroma and are same. While configuring
@@ -391,33 +391,38 @@
pipe->scale.num_ext_pxls_right[plane];
hor_fetch_pixels = src_w +
- pipe->scale.left_ftch[plane] +
+ (pipe->scale.left_ftch[plane] >> pipe->horz_deci) +
pipe->scale.left_rpt[plane] +
- pipe->scale.right_ftch[plane] +
+ (pipe->scale.right_ftch[plane] >> pipe->horz_deci) +
pipe->scale.right_rpt[plane];
- hor_ov_fetch = src_w + pipe->scale.left_ftch[plane] +
- pipe->scale.right_ftch[plane];
+ hor_ov_fetch = src_w +
+ (pipe->scale.left_ftch[plane] >> pipe->horz_deci)+
+ (pipe->scale.right_ftch[plane] >> pipe->horz_deci);
vert_req_pixels = pipe->scale.num_ext_pxls_top[plane] +
pipe->scale.num_ext_pxls_btm[plane];
- vert_fetch_pixels = pipe->scale.top_ftch[plane] +
+ vert_fetch_pixels =
+ (pipe->scale.top_ftch[plane] >> pipe->vert_deci) +
pipe->scale.top_rpt[plane] +
- pipe->scale.btm_ftch[plane] +
+ (pipe->scale.btm_ftch[plane] >> pipe->vert_deci)+
pipe->scale.btm_rpt[plane];
- vert_ov_fetch = src_h + pipe->scale.top_ftch[plane] +
- pipe->scale.btm_ftch[plane];
+ vert_ov_fetch = src_h +
+ (pipe->scale.top_ftch[plane] >> pipe->vert_deci)+
+ (pipe->scale.btm_ftch[plane] >> pipe->vert_deci);
if ((hor_req_pixels != hor_fetch_pixels) ||
(hor_ov_fetch > pipe->img_width) ||
(vert_req_pixels != vert_fetch_pixels) ||
(vert_ov_fetch > pipe->img_height)) {
- pr_err("err: plane=%d h_req:%d h_fetch:%d v_req:%d v_fetch:%d src_img:[%d,%d]\n",
+ pr_err("err: plane=%d h_req:%d h_fetch:%d v_req:%d v_fetch:%d\n",
plane,
hor_req_pixels, hor_fetch_pixels,
- vert_req_pixels, vert_fetch_pixels,
+ vert_req_pixels, vert_fetch_pixels);
+ pr_err("roi_w[%d]=%d, src_img:[%d, %d]\n",
+ plane, pipe->scale.roi_w[plane],
pipe->img_width, pipe->img_height);
pipe->scale.enable_pxl_ext = 0;
return -EINVAL;
@@ -432,7 +437,7 @@
u32 src;
int rc;
- src = pipe->src.w >> pipe->horz_deci;
+ src = DECIMATED_DIMENSION(pipe->src.w, pipe->horz_deci);
if (pipe->scale.enable_pxl_ext) {
rc = __mdss_mdp_validate_pxl_extn(pipe);
@@ -451,7 +456,7 @@
return rc;
}
- src = pipe->src.h >> pipe->vert_deci;
+ src = DECIMATED_DIMENSION(pipe->src.h, pipe->vert_deci);
rc = mdss_mdp_calc_phase_step(src, pipe->dst.h,
&pipe->scale.phase_step_y[0]);
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 2823e78..134a3d9 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -220,7 +220,7 @@
u32 nlines, format, seg_w;
u16 width;
- width = pipe->src.w >> pipe->horz_deci;
+ width = DECIMATED_DIMENSION(pipe->src.w, pipe->horz_deci);
if (pipe->bwc_mode) {
rc = mdss_mdp_get_rau_strides(pipe->src.w, pipe->src.h,
@@ -1250,8 +1250,9 @@
static inline void __mdss_mdp_pipe_program_pixel_extn_helper(
struct mdss_mdp_pipe *pipe, u32 plane, u32 off)
{
- u32 src_h = pipe->src.h >> pipe->vert_deci;
+ u32 src_h = DECIMATED_DIMENSION(pipe->src.h, pipe->vert_deci);
u32 mask = 0xFF;
+ u32 lr_pe, tb_pe, tot_req_pixels;
/*
* CB CR plane required pxls need to be accounted
@@ -1259,23 +1260,33 @@
*/
if (plane == 1)
src_h >>= pipe->chroma_sample_v;
- writel_relaxed(((pipe->scale.right_ftch[plane] & mask) << 24)|
+
+ lr_pe = ((pipe->scale.right_ftch[plane] & mask) << 24)|
((pipe->scale.right_rpt[plane] & mask) << 16)|
((pipe->scale.left_ftch[plane] & mask) << 8)|
- (pipe->scale.left_rpt[plane] & mask), pipe->base +
- MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_LR + off);
- writel_relaxed(((pipe->scale.btm_ftch[plane] & mask) << 24)|
+ (pipe->scale.left_rpt[plane] & mask);
+
+ tb_pe = ((pipe->scale.btm_ftch[plane] & mask) << 24)|
((pipe->scale.btm_rpt[plane] & mask) << 16)|
((pipe->scale.top_ftch[plane] & mask) << 8)|
- (pipe->scale.top_rpt[plane] & mask), pipe->base +
+ (pipe->scale.top_rpt[plane] & mask);
+
+ writel_relaxed(lr_pe, pipe->base +
+ MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_LR + off);
+ writel_relaxed(tb_pe, pipe->base +
MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_TB + off);
+
mask = 0xFFFF;
- writel_relaxed((((src_h + pipe->scale.num_ext_pxls_top[plane] +
+ tot_req_pixels = (((src_h + pipe->scale.num_ext_pxls_top[plane] +
pipe->scale.num_ext_pxls_btm[plane]) & mask) << 16) |
((pipe->scale.roi_w[plane] +
pipe->scale.num_ext_pxls_left[plane] +
- pipe->scale.num_ext_pxls_right[plane]) & mask), pipe->base +
+ pipe->scale.num_ext_pxls_right[plane]) & mask);
+ writel_relaxed(tot_req_pixels, pipe->base +
MDSS_MDP_REG_SSPP_SW_PIX_EXT_C0_REQ_PIXELS + off);
+
+ pr_debug("pipe num=%d, plane=%d, LR PE=0x%x, TB PE=0x%x, req_pixels=0x0%x\n",
+ pipe->num, plane, lr_pe, tb_pe, tot_req_pixels);
}
/**
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index dc8f4dd..3192b52 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -970,8 +970,8 @@
}
}
- src_w = pipe->src.w >> pipe->horz_deci;
- src_h = pipe->src.h >> pipe->vert_deci;
+ src_w = DECIMATED_DIMENSION(pipe->src.w, pipe->horz_deci);
+ src_h = DECIMATED_DIMENSION(pipe->src.h, pipe->vert_deci);
chroma_sample = pipe->src_fmt->chroma_sample;
if (pipe->flags & MDP_SOURCE_ROTATED_90) {
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 4be3260..1045f14 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -529,6 +529,7 @@
BLEND_OP_MAX,
};
+#define DECIMATED_DIMENSION(dim, deci) (((dim) + ((1 << (deci)) - 1)) >> (deci))
#define MAX_PLANES 4
struct mdp_scale_data {
uint8_t enable_pxl_ext;