MLK-15748 drm/imx: dpu: plane: Correct the way we do framebuffer cropping
authorLiu Ying <victor.liu@nxp.com>
Fri, 7 Jul 2017 08:39:59 +0000 (16:39 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:33:27 +0000 (15:33 -0500)
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 <jared.hu@nxp.com>
Tested-by: Jared Hu <jared.hu@nxp.com>
Signed-off-by: Liu Ying <victor.liu@nxp.com>
drivers/gpu/drm/imx/dpu/dpu-plane.c
drivers/gpu/imx/dpu/dpu-fetchdecode.c

index 258f37f..b51fe1b 100644 (file)
@@ -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);
index d0eaf66..39f9cba 100644 (file)
@@ -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;