Merge branch 'drm-armada-devel' of git://git.armlinux.org.uk/~rmk/linux-arm into...
authorDave Airlie <airlied@redhat.com>
Thu, 24 Nov 2016 23:03:27 +0000 (09:03 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 24 Nov 2016 23:03:27 +0000 (09:03 +1000)
Building on top of the MALI change previously merged, these changes:
* add tracing support for overlay updates
* refactor some of the plane support code
* de-midlayer the driver
* cleanups from other folk reviewing the code

* 'drm-armada-devel' of git://git.armlinux.org.uk/~rmk/linux-arm:
  drm/armada: fix NULL pointer comparison warning
  drm/armada: use DRM_FB_HELPER_DEFAULT_OPS for fb_ops
  drm/armada: remove some dead code
  drm/armada: mark symbols static where possible
  drm/armada: de-midlayer armada
  drm/armada: use common helper for plane base address
  drm/armada: move setting primary plane position to armada_drm_primary_set()
  drm/armada: split out primary plane update
  drm/armada: move plane state to struct armada_plane
  drm/armada: clean up armada_drm_plane_work_run()
  drm/armada: add tracing support

1  2 
drivers/gpu/drm/armada/armada_crtc.c
drivers/gpu/drm/armada/armada_drv.c
drivers/gpu/drm/armada/armada_gem.c
drivers/gpu/drm/armada/armada_overlay.c

index a51f8cbcfe26d9d4d5d52d2037ed94292533c41e,ceec930696dce198162a9143285f654d8e712a06..95cb3966b2ca9ba9eb437cbeaa3d89c5f0f50b87
@@@ -18,6 -18,7 +18,7 @@@
  #include "armada_fb.h"
  #include "armada_gem.h"
  #include "armada_hw.h"
+ #include "armada_trace.h"
  
  struct armada_frame_work {
        struct armada_plane_work work;
@@@ -164,19 -165,37 +165,37 @@@ static void armada_drm_crtc_update(stru
        }
  }
  
+ void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb,
+       int x, int y)
+ {
+       u32 addr = drm_fb_obj(fb)->dev_addr;
+       u32 pixel_format = fb->pixel_format;
+       int num_planes = drm_format_num_planes(pixel_format);
+       int i;
+       if (num_planes > 3)
+               num_planes = 3;
+       for (i = 0; i < num_planes; i++)
+               addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] +
+                            x * drm_format_plane_cpp(pixel_format, i);
+       for (; i < 3; i++)
+               addrs[i] = 0;
+ }
  static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb,
        int x, int y, struct armada_regs *regs, bool interlaced)
  {
-       struct armada_gem_object *obj = drm_fb_obj(fb);
        unsigned pitch = fb->pitches[0];
-       unsigned offset = y * pitch + x * fb->bits_per_pixel / 8;
-       uint32_t addr_odd, addr_even;
+       u32 addrs[3], addr_odd, addr_even;
        unsigned i = 0;
  
        DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n",
                pitch, x, y, fb->bits_per_pixel);
  
-       addr_odd = addr_even = obj->dev_addr + offset;
+       armada_drm_plane_calc_addrs(addrs, fb, x, y);
+       addr_odd = addr_even = addrs[0];
  
        if (interlaced) {
                addr_even += pitch;
  }
  
  static void armada_drm_plane_work_run(struct armada_crtc *dcrtc,
-       struct armada_plane *plane)
+       struct drm_plane *plane)
  {
-       struct armada_plane_work *work = xchg(&plane->work, NULL);
+       struct armada_plane *dplane = drm_to_armada_plane(plane);
+       struct armada_plane_work *work = xchg(&dplane->work, NULL);
  
        /* Handle any pending frame work. */
        if (work) {
-               work->fn(dcrtc, plane, work);
+               work->fn(dcrtc, dplane, work);
                drm_crtc_vblank_put(&dcrtc->crtc);
        }
  
-       wake_up(&plane->frame_wait);
+       wake_up(&dplane->frame_wait);
  }
  
  int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
@@@ -307,14 -327,12 +327,12 @@@ static void armada_drm_crtc_finish_fb(s
  
  static void armada_drm_vblank_off(struct armada_crtc *dcrtc)
  {
-       struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
        /*
         * Tell the DRM core that vblank IRQs aren't going to happen for
         * a while.  This cleans up any pending vblank events for us.
         */
        drm_crtc_vblank_off(&dcrtc->crtc);
-       armada_drm_plane_work_run(dcrtc, plane);
+       armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
  }
  
  void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
@@@ -332,19 -350,17 +350,19 @@@ static void armada_drm_crtc_dpms(struc
  {
        struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
  
 -      if (dcrtc->dpms != dpms) {
 -              dcrtc->dpms = dpms;
 -              if (!IS_ERR(dcrtc->clk) && !dpms_blanked(dpms))
 -                      WARN_ON(clk_prepare_enable(dcrtc->clk));
 -              armada_drm_crtc_update(dcrtc);
 -              if (!IS_ERR(dcrtc->clk) && dpms_blanked(dpms))
 -                      clk_disable_unprepare(dcrtc->clk);
 +      if (dpms_blanked(dcrtc->dpms) != dpms_blanked(dpms)) {
                if (dpms_blanked(dpms))
                        armada_drm_vblank_off(dcrtc);
 -              else
 +              else if (!IS_ERR(dcrtc->clk))
 +                      WARN_ON(clk_prepare_enable(dcrtc->clk));
 +              dcrtc->dpms = dpms;
 +              armada_drm_crtc_update(dcrtc);
 +              if (!dpms_blanked(dpms))
                        drm_crtc_vblank_on(&dcrtc->crtc);
 +              else if (!IS_ERR(dcrtc->clk))
 +                      clk_disable_unprepare(dcrtc->clk);
 +      } else if (dcrtc->dpms != dpms) {
 +              dcrtc->dpms = dpms;
        }
  }
  
@@@ -416,10 -432,8 +434,8 @@@ static void armada_drm_crtc_irq(struct 
  
        spin_lock(&dcrtc->irq_lock);
        ovl_plane = dcrtc->plane;
-       if (ovl_plane) {
-               struct armada_plane *plane = drm_to_armada_plane(ovl_plane);
-               armada_drm_plane_work_run(dcrtc, plane);
-       }
+       if (ovl_plane)
+               armada_drm_plane_work_run(dcrtc, ovl_plane);
  
        if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) {
                int i = stat & GRA_FRAME_IRQ0 ? 0 : 1;
  
        spin_unlock(&dcrtc->irq_lock);
  
-       if (stat & GRA_FRAME_IRQ) {
-               struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary);
-               armada_drm_plane_work_run(dcrtc, plane);
-       }
+       if (stat & GRA_FRAME_IRQ)
+               armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
  }
  
  static irqreturn_t armada_drm_irq(int irq, void *arg)
         */
        writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
  
+       trace_armada_drm_irq(&dcrtc->crtc, stat);
        /* Mask out those interrupts we haven't enabled */
        v = stat & dcrtc->irq_ena;
  
@@@ -531,6 -545,35 +547,35 @@@ static uint32_t armada_drm_crtc_calcula
        return val;
  }
  
+ static void armada_drm_primary_set(struct drm_crtc *crtc,
+       struct drm_plane *plane, int x, int y)
+ {
+       struct armada_plane_state *state = &drm_to_armada_plane(plane)->state;
+       struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
+       struct armada_regs regs[8];
+       bool interlaced = dcrtc->interlaced;
+       unsigned i;
+       u32 ctrl0;
+       i = armada_drm_crtc_calc_fb(plane->fb, x, y, regs, interlaced);
+       armada_reg_queue_set(regs, i, state->dst_yx, LCD_SPU_GRA_OVSA_HPXL_VLN);
+       armada_reg_queue_set(regs, i, state->src_hw, LCD_SPU_GRA_HPXL_VLN);
+       armada_reg_queue_set(regs, i, state->dst_hw, LCD_SPU_GZM_HPXL_VLN);
+       ctrl0 = state->ctrl0;
+       if (interlaced)
+               ctrl0 |= CFG_GRA_FTOGGLE;
+       armada_reg_queue_mod(regs, i, ctrl0, CFG_GRAFORMAT |
+                            CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
+                                        CFG_SWAPYU | CFG_YUV2RGB) |
+                            CFG_PALETTE_ENA | CFG_GRA_FTOGGLE,
+                            LCD_SPU_DMA_CTRL0);
+       armada_reg_queue_end(regs, i);
+       armada_drm_crtc_update_regs(dcrtc, regs);
+ }
  /* The mode_config.mutex will be held for this call */
  static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
        struct drm_display_mode *mode, struct drm_display_mode *adj,
  
        interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE);
  
-       i = armada_drm_crtc_calc_fb(dcrtc->crtc.primary->fb,
-                                   x, y, regs, interlaced);
+       val = CFG_GRA_ENA | CFG_GRA_HSMOOTH;
+       val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt);
+       val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod);
+       if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420)
+               val |= CFG_PALETTE_ENA;
+       drm_to_armada_plane(crtc->primary)->state.ctrl0 = val;
+       drm_to_armada_plane(crtc->primary)->state.src_hw =
+       drm_to_armada_plane(crtc->primary)->state.dst_hw =
+               adj->crtc_vdisplay << 16 | adj->crtc_hdisplay;
+       drm_to_armada_plane(crtc->primary)->state.dst_yx = 0;
  
+       i = 0;
        rm = adj->crtc_hsync_start - adj->crtc_hdisplay;
        lm = adj->crtc_htotal - adj->crtc_hsync_end;
        bm = adj->crtc_vsync_start - adj->crtc_vdisplay;
        val = adj->crtc_vdisplay << 16 | adj->crtc_hdisplay;
  
        armada_reg_queue_set(regs, i, val, LCD_SPU_V_H_ACTIVE);
-       armada_reg_queue_set(regs, i, val, LCD_SPU_GRA_HPXL_VLN);
-       armada_reg_queue_set(regs, i, val, LCD_SPU_GZM_HPXL_VLN);
        armada_reg_queue_set(regs, i, (lm << 16) | rm, LCD_SPU_H_PORCH);
        armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_porch, LCD_SPU_V_PORCH);
        armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total,
                                     ADV_VSYNCOFFEN, LCD_SPU_ADV_REG);
        }
  
-       val = CFG_GRA_ENA | CFG_GRA_HSMOOTH;
-       val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt);
-       val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod);
-       if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420)
-               val |= CFG_PALETTE_ENA;
-       if (interlaced)
-               val |= CFG_GRA_FTOGGLE;
-       armada_reg_queue_mod(regs, i, val, CFG_GRAFORMAT |
-                            CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV |
-                                        CFG_SWAPYU | CFG_YUV2RGB) |
-                            CFG_PALETTE_ENA | CFG_GRA_FTOGGLE,
-                            LCD_SPU_DMA_CTRL0);
        val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0;
        armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1);
  
        armada_reg_queue_end(regs, i);
  
        armada_drm_crtc_update_regs(dcrtc, regs);
+       armada_drm_primary_set(crtc, crtc->primary, x, y);
        spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
  
        armada_drm_crtc_update(dcrtc);
@@@ -1038,7 -1076,7 +1078,7 @@@ static int armada_drm_crtc_page_flip(st
         * interrupt, so complete it now.
         */
        if (dpms_blanked(dcrtc->dpms))
-               armada_drm_plane_work_run(dcrtc, drm_to_armada_plane(dcrtc->crtc.primary));
+               armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary);
  
        return 0;
  }
@@@ -1172,7 -1210,6 +1212,6 @@@ static int armada_drm_crtc_create(struc
                       CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 |
                       CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1);
        writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1);
-       writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_GRA_OVSA_HPXL_VLN);
        writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA);
        writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR);
  
index 94e46da9a758f7f4496941f3f51534e782b56107,e79d1a7b6047d9e8b176ec87ca5d6061e0c4d2da..07086b427c22ea76ac26ddf45efb38369b7f59a4
@@@ -49,106 -49,6 +49,6 @@@ void armada_drm_queue_unref_work(struc
        spin_unlock_irqrestore(&dev->event_lock, flags);
  }
  
- static int armada_drm_load(struct drm_device *dev, unsigned long flags)
- {
-       struct armada_private *priv;
-       struct resource *mem = NULL;
-       int ret, n;
-       for (n = 0; ; n++) {
-               struct resource *r = platform_get_resource(dev->platformdev,
-                                                          IORESOURCE_MEM, n);
-               if (!r)
-                       break;
-               /* Resources above 64K are graphics memory */
-               if (resource_size(r) > SZ_64K)
-                       mem = r;
-               else
-                       return -EINVAL;
-       }
-       if (!mem)
-               return -ENXIO;
-       if (!devm_request_mem_region(dev->dev, mem->start,
-                       resource_size(mem), "armada-drm"))
-               return -EBUSY;
-       priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv) {
-               DRM_ERROR("failed to allocate private\n");
-               return -ENOMEM;
-       }
-       platform_set_drvdata(dev->platformdev, dev);
-       dev->dev_private = priv;
-       INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
-       INIT_KFIFO(priv->fb_unref);
-       /* Mode setting support */
-       drm_mode_config_init(dev);
-       dev->mode_config.min_width = 320;
-       dev->mode_config.min_height = 200;
-       /*
-        * With vscale enabled, the maximum width is 1920 due to the
-        * 1920 by 3 lines RAM
-        */
-       dev->mode_config.max_width = 1920;
-       dev->mode_config.max_height = 2048;
-       dev->mode_config.preferred_depth = 24;
-       dev->mode_config.funcs = &armada_drm_mode_config_funcs;
-       drm_mm_init(&priv->linear, mem->start, resource_size(mem));
-       mutex_init(&priv->linear_lock);
-       ret = component_bind_all(dev->dev, dev);
-       if (ret)
-               goto err_kms;
-       ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
-       if (ret)
-               goto err_comp;
-       dev->irq_enabled = true;
-       ret = armada_fbdev_init(dev);
-       if (ret)
-               goto err_comp;
-       drm_kms_helper_poll_init(dev);
-       return 0;
-  err_comp:
-       component_unbind_all(dev->dev, dev);
-  err_kms:
-       drm_mode_config_cleanup(dev);
-       drm_mm_takedown(&priv->linear);
-       flush_work(&priv->fb_unref_work);
-       return ret;
- }
- static int armada_drm_unload(struct drm_device *dev)
- {
-       struct armada_private *priv = dev->dev_private;
-       drm_kms_helper_poll_fini(dev);
-       armada_fbdev_fini(dev);
-       component_unbind_all(dev->dev, dev);
-       drm_mode_config_cleanup(dev);
-       drm_mm_takedown(&priv->linear);
-       flush_work(&priv->fb_unref_work);
-       dev->dev_private = NULL;
-       return 0;
- }
  /* These are called under the vbl_lock. */
  static int armada_drm_enable_vblank(struct drm_device *dev, unsigned int pipe)
  {
@@@ -186,16 -86,10 +86,10 @@@ static const struct file_operations arm
  };
  
  static struct drm_driver armada_drm_driver = {
-       .load                   = armada_drm_load,
        .lastclose              = armada_drm_lastclose,
-       .unload                 = armada_drm_unload,
        .get_vblank_counter     = drm_vblank_no_hw_counter,
        .enable_vblank          = armada_drm_enable_vblank,
        .disable_vblank         = armada_drm_disable_vblank,
- #ifdef CONFIG_DEBUG_FS
-       .debugfs_init           = armada_drm_debugfs_init,
-       .debugfs_cleanup        = armada_drm_debugfs_cleanup,
- #endif
        .gem_free_object_unlocked = armada_gem_free_object,
        .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
        .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
        .desc                   = "Armada SoC DRM",
        .date                   = "20120730",
        .driver_features        = DRIVER_GEM | DRIVER_MODESET |
 -                                DRIVER_HAVE_IRQ | DRIVER_PRIME,
 +                                DRIVER_PRIME,
        .ioctls                 = armada_ioctls,
        .fops                   = &armada_drm_fops,
  };
  
  static int armada_drm_bind(struct device *dev)
  {
-       return drm_platform_init(&armada_drm_driver, to_platform_device(dev));
+       struct armada_private *priv;
+       struct resource *mem = NULL;
+       int ret, n;
+       for (n = 0; ; n++) {
+               struct resource *r = platform_get_resource(to_platform_device(dev),
+                                                          IORESOURCE_MEM, n);
+               if (!r)
+                       break;
+               /* Resources above 64K are graphics memory */
+               if (resource_size(r) > SZ_64K)
+                       mem = r;
+               else
+                       return -EINVAL;
+       }
+       if (!mem)
+               return -ENXIO;
+       if (!devm_request_mem_region(dev, mem->start, resource_size(mem),
+                                    "armada-drm"))
+               return -EBUSY;
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       /*
+        * The drm_device structure must be at the start of
+        * armada_private for drm_dev_unref() to work correctly.
+        */
+       BUILD_BUG_ON(offsetof(struct armada_private, drm) != 0);
+       ret = drm_dev_init(&priv->drm, &armada_drm_driver, dev);
+       if (ret) {
+               dev_err(dev, "[" DRM_NAME ":%s] drm_dev_init failed: %d\n",
+                       __func__, ret);
+               kfree(priv);
+               return ret;
+       }
+       priv->drm.platformdev = to_platform_device(dev);
+       priv->drm.dev_private = priv;
+       platform_set_drvdata(priv->drm.platformdev, &priv->drm);
+       INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
+       INIT_KFIFO(priv->fb_unref);
+       /* Mode setting support */
+       drm_mode_config_init(&priv->drm);
+       priv->drm.mode_config.min_width = 320;
+       priv->drm.mode_config.min_height = 200;
+       /*
+        * With vscale enabled, the maximum width is 1920 due to the
+        * 1920 by 3 lines RAM
+        */
+       priv->drm.mode_config.max_width = 1920;
+       priv->drm.mode_config.max_height = 2048;
+       priv->drm.mode_config.preferred_depth = 24;
+       priv->drm.mode_config.funcs = &armada_drm_mode_config_funcs;
+       drm_mm_init(&priv->linear, mem->start, resource_size(mem));
+       mutex_init(&priv->linear_lock);
+       ret = component_bind_all(dev, &priv->drm);
+       if (ret)
+               goto err_kms;
+       ret = drm_vblank_init(&priv->drm, priv->drm.mode_config.num_crtc);
+       if (ret)
+               goto err_comp;
+       priv->drm.irq_enabled = true;
+       ret = armada_fbdev_init(&priv->drm);
+       if (ret)
+               goto err_comp;
+       drm_kms_helper_poll_init(&priv->drm);
+       ret = drm_dev_register(&priv->drm, 0);
+       if (ret)
+               goto err_poll;
+ #ifdef CONFIG_DEBUG_FS
+       armada_drm_debugfs_init(priv->drm.primary);
+ #endif
+       DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
+                armada_drm_driver.name, armada_drm_driver.major,
+                armada_drm_driver.minor, armada_drm_driver.patchlevel,
+                armada_drm_driver.date, dev_name(dev),
+                priv->drm.primary->index);
+       return 0;
+  err_poll:
+       drm_kms_helper_poll_fini(&priv->drm);
+       armada_fbdev_fini(&priv->drm);
+  err_comp:
+       component_unbind_all(dev, &priv->drm);
+  err_kms:
+       drm_mode_config_cleanup(&priv->drm);
+       drm_mm_takedown(&priv->linear);
+       flush_work(&priv->fb_unref_work);
+       drm_dev_unref(&priv->drm);
+       return ret;
  }
  
  static void armada_drm_unbind(struct device *dev)
  {
-       drm_put_dev(dev_get_drvdata(dev));
+       struct drm_device *drm = dev_get_drvdata(dev);
+       struct armada_private *priv = drm->dev_private;
+       drm_kms_helper_poll_fini(&priv->drm);
+       armada_fbdev_fini(&priv->drm);
+ #ifdef CONFIG_DEBUG_FS
+       armada_drm_debugfs_cleanup(priv->drm.primary);
+ #endif
+       drm_dev_unregister(&priv->drm);
+       component_unbind_all(dev, &priv->drm);
+       drm_mode_config_cleanup(&priv->drm);
+       drm_mm_takedown(&priv->linear);
+       flush_work(&priv->fb_unref_work);
+       drm_dev_unref(&priv->drm);
  }
  
  static int compare_of(struct device *dev, void *data)
@@@ -254,7 -274,7 +274,7 @@@ static void armada_add_endpoints(struc
                        continue;
                }
  
 -              component_match_add(dev, match, compare_of, remote);
 +              drm_of_component_match_add(dev, match, compare_of, remote);
                of_node_put(remote);
        }
  }
index 8067918973046a14441ecef699f5b3337f17ecbf,fd92446f9cce682964e50c45494fafe24f07555f..768087ddb046d1b483eb2eebafcd1298b80541fa
@@@ -212,7 -212,7 +212,7 @@@ armada_gem_alloc_private_object(struct 
        return obj;
  }
  
- struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev,
+ static struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev,
        size_t size)
  {
        struct armada_gem_object *obj;
@@@ -387,7 -387,7 +387,7 @@@ int armada_gem_pwrite_ioctl(struct drm_
        if (!access_ok(VERIFY_READ, ptr, args->size))
                return -EFAULT;
  
 -      ret = fault_in_multipages_readable(ptr, args->size);
 +      ret = fault_in_pages_readable(ptr, args->size);
        if (ret)
                return ret;
  
  }
  
  /* Prime support */
- struct sg_table *
+ static struct sg_table *
  armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
        enum dma_data_direction dir)
  {
@@@ -547,7 -547,7 +547,7 @@@ armada_gem_prime_export(struct drm_devi
        exp_info.flags = O_RDWR;
        exp_info.priv = obj;
  
 -      return dma_buf_export(&exp_info);
 +      return drm_gem_dmabuf_export(dev, &exp_info);
  }
  
  struct drm_gem_object *
@@@ -594,11 -594,7 +594,7 @@@ int armada_gem_map_import(struct armada
        int ret;
  
        dobj->sgt = dma_buf_map_attachment(dobj->obj.import_attach,
-                                         DMA_TO_DEVICE);
-       if (!dobj->sgt) {
-               DRM_ERROR("dma_buf_map_attachment() returned NULL\n");
-               return -EINVAL;
-       }
+                                          DMA_TO_DEVICE);
        if (IS_ERR(dobj->sgt)) {
                ret = PTR_ERR(dobj->sgt);
                dobj->sgt = NULL;
index 152b4e716269c4a2482d697fddb1398c0ff811f6,41fc28b1e7d133e30e220933c013fe6afd6cf314..6743615232f5c6b4da32dd4296c01f9966ebf756
@@@ -15,6 -15,7 +15,7 @@@
  #include "armada_hw.h"
  #include <drm/armada_drm.h>
  #include "armada_ioctlP.h"
+ #include "armada_trace.h"
  
  struct armada_ovl_plane_properties {
        uint32_t colorkey_yr;
  struct armada_ovl_plane {
        struct armada_plane base;
        struct drm_framebuffer *old_fb;
-       uint32_t src_hw;
-       uint32_t dst_hw;
-       uint32_t dst_yx;
-       uint32_t ctrl0;
        struct {
                struct armada_plane_work work;
                struct armada_regs regs[13];
@@@ -87,6 -84,8 +84,8 @@@ static void armada_ovl_plane_work(struc
  {
        struct armada_ovl_plane *dplane = container_of(plane, struct armada_ovl_plane, base);
  
+       trace_armada_ovl_plane_work(&dcrtc->crtc, &plane->base);
        armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs);
        armada_ovl_retire_fb(dplane, NULL);
  }
@@@ -120,8 -119,12 +119,12 @@@ armada_ovl_plane_update(struct drm_plan
        bool visible;
        int ret;
  
+       trace_armada_ovl_plane_update(plane, crtc, fb,
+                                crtc_x, crtc_y, crtc_w, crtc_h,
+                                src_x, src_y, src_w, src_h);
        ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip,
 -                                          BIT(DRM_ROTATE_0),
 +                                          DRM_ROTATE_0,
                                            0, INT_MAX, true, false, &visible);
        if (ret)
                return ret;
  
        /* FIXME: overlay on an interlaced display */
        /* Just updating the position/size? */
-       if (plane->fb == fb && dplane->ctrl0 == ctrl0) {
+       if (plane->fb == fb && dplane->base.state.ctrl0 == ctrl0) {
                val = (drm_rect_height(&src) & 0xffff0000) |
                      drm_rect_width(&src) >> 16;
-               dplane->src_hw = val;
+               dplane->base.state.src_hw = val;
                writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN);
  
                val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest);
-               dplane->dst_hw = val;
+               dplane->base.state.dst_hw = val;
                writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN);
  
                val = dest.y1 << 16 | dest.x1;
-               dplane->dst_yx = val;
+               dplane->base.state.dst_yx = val;
                writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN);
  
                return 0;
-       } else if (~dplane->ctrl0 & ctrl0 & CFG_DMA_ENA) {
+       } else if (~dplane->base.state.ctrl0 & ctrl0 & CFG_DMA_ENA) {
                /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */
                armada_updatel(0, CFG_PDWN16x66 | CFG_PDWN32x66,
                               dcrtc->base + LCD_SPU_SRAM_PARA1);
                armada_drm_plane_work_cancel(dcrtc, &dplane->base);
  
        if (plane->fb != fb) {
-               struct armada_gem_object *obj = drm_fb_obj(fb);
-               uint32_t addr[3], pixel_format;
-               int i, num_planes, hsub;
+               u32 addrs[3], pixel_format;
+               int num_planes, hsub;
  
                /*
                 * Take a reference on the new framebuffer - we want to
                src_y = src.y1 >> 16;
                src_x = src.x1 >> 16;
  
+               armada_drm_plane_calc_addrs(addrs, fb, src_x, src_y);
                pixel_format = fb->pixel_format;
                hsub = drm_format_horz_chroma_subsampling(pixel_format);
                num_planes = drm_format_num_planes(pixel_format);
                if (src_x & (hsub - 1) && num_planes == 1)
                        ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV);
  
-               for (i = 0; i < num_planes; i++)
-                       addr[i] = obj->dev_addr + fb->offsets[i] +
-                                 src_y * fb->pitches[i] +
-                                 src_x * drm_format_plane_cpp(pixel_format, i);
-               for (; i < ARRAY_SIZE(addr); i++)
-                       addr[i] = 0;
-               armada_reg_queue_set(dplane->vbl.regs, idx, addr[0],
+               armada_reg_queue_set(dplane->vbl.regs, idx, addrs[0],
                                     LCD_SPU_DMA_START_ADDR_Y0);
-               armada_reg_queue_set(dplane->vbl.regs, idx, addr[1],
+               armada_reg_queue_set(dplane->vbl.regs, idx, addrs[1],
                                     LCD_SPU_DMA_START_ADDR_U0);
-               armada_reg_queue_set(dplane->vbl.regs, idx, addr[2],
+               armada_reg_queue_set(dplane->vbl.regs, idx, addrs[2],
                                     LCD_SPU_DMA_START_ADDR_V0);
-               armada_reg_queue_set(dplane->vbl.regs, idx, addr[0],
+               armada_reg_queue_set(dplane->vbl.regs, idx, addrs[0],
                                     LCD_SPU_DMA_START_ADDR_Y1);
-               armada_reg_queue_set(dplane->vbl.regs, idx, addr[1],
+               armada_reg_queue_set(dplane->vbl.regs, idx, addrs[1],
                                     LCD_SPU_DMA_START_ADDR_U1);
-               armada_reg_queue_set(dplane->vbl.regs, idx, addr[2],
+               armada_reg_queue_set(dplane->vbl.regs, idx, addrs[2],
                                     LCD_SPU_DMA_START_ADDR_V1);
  
                val = fb->pitches[0] << 16 | fb->pitches[0];
        }
  
        val = (drm_rect_height(&src) & 0xffff0000) | drm_rect_width(&src) >> 16;
-       if (dplane->src_hw != val) {
-               dplane->src_hw = val;
+       if (dplane->base.state.src_hw != val) {
+               dplane->base.state.src_hw = val;
                armada_reg_queue_set(dplane->vbl.regs, idx, val,
                                     LCD_SPU_DMA_HPXL_VLN);
        }
  
        val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest);
-       if (dplane->dst_hw != val) {
-               dplane->dst_hw = val;
+       if (dplane->base.state.dst_hw != val) {
+               dplane->base.state.dst_hw = val;
                armada_reg_queue_set(dplane->vbl.regs, idx, val,
                                     LCD_SPU_DZM_HPXL_VLN);
        }
  
        val = dest.y1 << 16 | dest.x1;
-       if (dplane->dst_yx != val) {
-               dplane->dst_yx = val;
+       if (dplane->base.state.dst_yx != val) {
+               dplane->base.state.dst_yx = val;
                armada_reg_queue_set(dplane->vbl.regs, idx, val,
                                     LCD_SPU_DMA_OVSA_HPXL_VLN);
        }
  
-       if (dplane->ctrl0 != ctrl0) {
-               dplane->ctrl0 = ctrl0;
+       if (dplane->base.state.ctrl0 != ctrl0) {
+               dplane->base.state.ctrl0 = ctrl0;
                armada_reg_queue_mod(dplane->vbl.regs, idx, ctrl0,
                        CFG_CBSH_ENA | CFG_DMAFORMAT | CFG_DMA_FTOGGLE |
                        CFG_DMA_HSMOOTH | CFG_DMA_TSTMODE |
@@@ -275,7 -272,7 +272,7 @@@ static int armada_ovl_plane_disable(str
        armada_drm_crtc_plane_disable(dcrtc, plane);
  
        dcrtc->plane = NULL;
-       dplane->ctrl0 = 0;
+       dplane->base.state.ctrl0 = 0;
  
        fb = xchg(&dplane->old_fb, NULL);
        if (fb)