From 3541eafcc8eb6506eed4299dfc3b01ddf1d4dc14 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Fri, 7 Jul 2017 16:39:59 +0800 Subject: [PATCH] MLK-15748 drm/imx: dpu: plane: Correct the way we do framebuffer cropping We should not use fetchdecode clip feature to do framebuffer cropping since the hardware hehavior differs from what we expected. According to the spec, it seems that the clip feature will keep the source frame resolution and fill pixels in the clipped area. So, let's take the usual way to do the cropping and just simply tweak the buffer start address. Reported-by: Jared Hu Tested-by: Jared Hu Signed-off-by: Liu Ying --- drivers/gpu/drm/imx/dpu/dpu-plane.c | 35 ++++++++++++++++----------- drivers/gpu/imx/dpu/dpu-fetchdecode.c | 2 +- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/imx/dpu/dpu-plane.c b/drivers/gpu/drm/imx/dpu/dpu-plane.c index 258f37f68b35..b51fe1bca4ed 100644 --- a/drivers/gpu/drm/imx/dpu/dpu-plane.c +++ b/drivers/gpu/drm/imx/dpu/dpu-plane.c @@ -111,13 +111,27 @@ static const struct drm_plane_funcs dpu_plane_funcs = { .atomic_destroy_state = dpu_drm_atomic_plane_destroy_state, }; +static inline dma_addr_t +drm_plane_state_to_baseaddr(struct drm_plane_state *state) +{ + struct drm_framebuffer *fb = state->fb; + struct drm_gem_cma_object *cma_obj; + + cma_obj = drm_fb_cma_get_gem_obj(fb, 0); + BUG_ON(!cma_obj); + + return cma_obj->paddr + fb->offsets[0] + + fb->pitches[0] * (state->src_y >> 16) + + (fb->bits_per_pixel >> 3) * (state->src_x >> 16); +} + static int dpu_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { struct dpu_plane_state *dpstate = to_dpu_plane_state(state); struct drm_crtc_state *crtc_state; struct drm_framebuffer *fb = state->fb; - struct drm_gem_cma_object *cma_obj; + dma_addr_t baseaddr; unsigned int depth; int bpp; @@ -166,15 +180,15 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, } /* base address alignment check */ - cma_obj = drm_fb_cma_get_gem_obj(fb, 0); + baseaddr = drm_plane_state_to_baseaddr(state); drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp); switch (bpp) { case 32: - if (cma_obj->paddr & 0x3) + if (baseaddr & 0x3) return -EINVAL; break; case 16: - if (cma_obj->paddr & 0x1) + if (baseaddr & 0x1) return -EINVAL; break; } @@ -197,9 +211,8 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, struct dpu_layerblend *lb; struct dpu_constframe *cf; struct dpu_extdst *ed; - struct drm_gem_cma_object *cma_obj; struct device *dev = plane->dev->dev; - unsigned int depth, src_x, src_y, src_w, src_h; + unsigned int depth, src_w, src_h; int bpp, fd_id, lb_id; /* @@ -220,10 +233,6 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, fd = res->fd[fd_id]; lb = res->lb[lb_id]; - cma_obj = drm_fb_cma_get_gem_obj(fb, 0); - - src_x = state->src_x >> 16; - src_y = state->src_y >> 16; src_w = state->src_w >> 16; src_h = state->src_h >> 16; @@ -233,11 +242,9 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, fetchdecode_source_stride(fd, fb->pitches[0]); fetchdecode_src_buf_dimensions(fd, src_w, src_h); fetchdecode_set_fmt(fd, fb->pixel_format); - fetchdecode_clipoffset(fd, src_x, src_y); - fetchdecode_clipdimensions(fd, src_w, src_h); fetchdecode_layerproperty(fd, true); - fetchdecode_framedimensions(fd, state->crtc_w, state->crtc_h); - fetchdecode_baseaddress(fd, cma_obj->paddr); + fetchdecode_framedimensions(fd, src_w, src_h); + fetchdecode_baseaddress(fd, drm_plane_state_to_baseaddr(state)); layerblend_pixengcfg_dynamic_prim_sel(lb, dpstate->stage); layerblend_pixengcfg_dynamic_sec_sel(lb, dpstate->source); diff --git a/drivers/gpu/imx/dpu/dpu-fetchdecode.c b/drivers/gpu/imx/dpu/dpu-fetchdecode.c index d0eaf668b0e8..39f9cba2d1b9 100644 --- a/drivers/gpu/imx/dpu/dpu-fetchdecode.c +++ b/drivers/gpu/imx/dpu/dpu-fetchdecode.c @@ -256,7 +256,7 @@ void fetchdecode_layerproperty(struct dpu_fetchdecode *fd, bool enable) u32 val; if (enable) - val = SOURCEBUFFERENABLE | CLIPWINDOWENABLE; + val = SOURCEBUFFERENABLE; else val = 0; -- 2.17.1