]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-upstream/hdlcd' of git://linux-arm.org/linux-ld into drm-fixes
authorDave Airlie <airlied@redhat.com>
Fri, 19 May 2017 20:00:49 +0000 (06:00 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 19 May 2017 20:00:49 +0000 (06:00 +1000)
single hdlcd fix
* 'for-upstream/hdlcd' of git://linux-arm.org/linux-ld:
  drm: hdlcd: Fix the calculation of the scanout start address

1  2 
drivers/gpu/drm/arm/hdlcd_crtc.c

index 798a3cc480a2eefc8510417a883dcded6dedc741,c651163482814351de9f719e9af1edac34a31320..1a3359c0f6cd2e80441977114ca55aea85c19cb8
@@@ -10,6 -10,7 +10,7 @@@
   */
  
  #include <drm/drmP.h>
+ #include <drm/drm_atomic.h>
  #include <drm/drm_atomic_helper.h>
  #include <drm/drm_crtc.h>
  #include <drm/drm_crtc_helper.h>
@@@ -42,24 -43,6 +43,24 @@@ static void hdlcd_crtc_cleanup(struct d
        drm_crtc_cleanup(crtc);
  }
  
 +static int hdlcd_crtc_enable_vblank(struct drm_crtc *crtc)
 +{
 +      struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 +      unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
 +
 +      hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask | HDLCD_INTERRUPT_VSYNC);
 +
 +      return 0;
 +}
 +
 +static void hdlcd_crtc_disable_vblank(struct drm_crtc *crtc)
 +{
 +      struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 +      unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
 +
 +      hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask & ~HDLCD_INTERRUPT_VSYNC);
 +}
 +
  static const struct drm_crtc_funcs hdlcd_crtc_funcs = {
        .destroy = hdlcd_crtc_cleanup,
        .set_config = drm_atomic_helper_set_config,
@@@ -67,8 -50,6 +68,8 @@@
        .reset = drm_atomic_helper_crtc_reset,
        .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
        .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 +      .enable_vblank = hdlcd_crtc_enable_vblank,
 +      .disable_vblank = hdlcd_crtc_disable_vblank,
  };
  
  static struct simplefb_format supported_formats[] = SIMPLEFB_FORMATS;
@@@ -226,16 -207,33 +227,33 @@@ static const struct drm_crtc_helper_fun
  static int hdlcd_plane_atomic_check(struct drm_plane *plane,
                                    struct drm_plane_state *state)
  {
-       u32 src_w, src_h;
+       struct drm_rect clip = { 0 };
+       struct drm_crtc_state *crtc_state;
+       u32 src_h = state->src_h >> 16;
  
-       src_w = state->src_w >> 16;
-       src_h = state->src_h >> 16;
+       /* only the HDLCD_REG_FB_LINE_COUNT register has a limit */
+       if (src_h >= HDLCD_MAX_YRES) {
+               DRM_DEBUG_KMS("Invalid source width: %d\n", src_h);
+               return -EINVAL;
+       }
+       if (!state->fb || !state->crtc)
+               return 0;
  
-       /* we can't do any scaling of the plane source */
-       if ((src_w != state->crtc_w) || (src_h != state->crtc_h))
+       crtc_state = drm_atomic_get_existing_crtc_state(state->state,
+                                                       state->crtc);
+       if (!crtc_state) {
+               DRM_DEBUG_KMS("Invalid crtc state\n");
                return -EINVAL;
+       }
  
-       return 0;
+       clip.x2 = crtc_state->adjusted_mode.hdisplay;
+       clip.y2 = crtc_state->adjusted_mode.vdisplay;
+       return drm_plane_helper_check_state(state, &clip,
+                                           DRM_PLANE_HELPER_NO_SCALING,
+                                           DRM_PLANE_HELPER_NO_SCALING,
+                                           false, true);
  }
  
  static void hdlcd_plane_atomic_update(struct drm_plane *plane,
        struct drm_framebuffer *fb = plane->state->fb;
        struct hdlcd_drm_private *hdlcd;
        struct drm_gem_cma_object *gem;
-       u32 src_w, src_h, dest_w, dest_h;
+       u32 src_x, src_y, dest_h;
        dma_addr_t scanout_start;
  
        if (!fb)
                return;
  
-       src_w = plane->state->src_w >> 16;
-       src_h = plane->state->src_h >> 16;
-       dest_w = plane->state->crtc_w;
-       dest_h = plane->state->crtc_h;
+       src_x = plane->state->src.x1 >> 16;
+       src_y = plane->state->src.y1 >> 16;
+       dest_h = drm_rect_height(&plane->state->dst);
        gem = drm_fb_cma_get_gem_obj(fb, 0);
        scanout_start = gem->paddr + fb->offsets[0] +
-               plane->state->crtc_y * fb->pitches[0] +
-               plane->state->crtc_x *
-               fb->format->cpp[0];
+                       src_y * fb->pitches[0] +
+                       src_x * fb->format->cpp[0];
  
        hdlcd = plane->dev->dev_private;
        hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, fb->pitches[0]);
@@@ -305,7 -302,6 +322,6 @@@ static struct drm_plane *hdlcd_plane_in
                                       formats, ARRAY_SIZE(formats),
                                       DRM_PLANE_TYPE_PRIMARY, NULL);
        if (ret) {
-               devm_kfree(drm->dev, plane);
                return ERR_PTR(ret);
        }
  
@@@ -329,7 -325,6 +345,6 @@@ int hdlcd_setup_crtc(struct drm_device 
                                        &hdlcd_crtc_funcs, NULL);
        if (ret) {
                hdlcd_plane_destroy(primary);
-               devm_kfree(drm->dev, primary);
                return ret;
        }