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;