struct drm_gem_cma_object *gem;
        unsigned int depth, bpp;
        dma_addr_t start, end;
+       u64 dma_base_and_ceiling;
 
        drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
        gem = drm_fb_cma_get_gem_obj(fb, 0);
 
        end = start + (crtc->mode.vdisplay * fb->pitches[0]);
 
-       tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, start);
-       tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, end - 1);
+       /* Write LCDC_DMA_FB_BASE_ADDR_0_REG and LCDC_DMA_FB_CEILING_ADDR_0_REG
+        * with a single insruction, if available. This should make it more
+        * unlikely that LCDC would fetch the DMA addresses in the middle of
+        * an update.
+        */
+       dma_base_and_ceiling = (u64)(end - 1) << 32 | start;
+       tilcdc_write64(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_base_and_ceiling);
 
        if (tilcdc_crtc->curr_fb)
                drm_flip_work_queue(&tilcdc_crtc->unref_work,
 
        iowrite32(data, priv->mmio + reg);
 }
 
+static inline void tilcdc_write64(struct drm_device *dev, u32 reg, u64 data)
+{
+       struct tilcdc_drm_private *priv = dev->dev_private;
+       volatile void __iomem *addr = priv->mmio + reg;
+
+#ifdef iowrite64
+       iowrite64(data, addr);
+#else
+       __iowmb();
+       /* This compiles to strd (=64-bit write) on ARM7 */
+       *(volatile u64 __force *)addr = __cpu_to_le64(data);
+#endif
+}
+
 static inline u32 tilcdc_read(struct drm_device *dev, u32 reg)
 {
        struct tilcdc_drm_private *priv = dev->dev_private;