aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tilcdc
diff options
context:
space:
mode:
authorJyri Sarha <jsarha@ti.com>2016-08-26 08:10:14 -0400
committerJyri Sarha <jsarha@ti.com>2016-09-01 15:31:59 -0400
commit7eb9f069ff5dd39d44d7ecdf63eb99b429c7dad0 (patch)
tree7e19fda5f1a9830b3ce48117a3793832fd2565f8 /drivers/gpu/drm/tilcdc
parent63b07a8d8177675c5a4297de477fd511e9be7896 (diff)
drm/tilcdc: Write DMA base and ceiling address with single instruction
Write DMA base and ceiling address with a single instruction, if available. This should make it more unlikely that LCDC would fetch the DMA addresses in the middle of an update. Having bad combination of addresses in dma base and ceiling (e.g base > ceiling) can cause unpredictaple behavior in LCDC. Signed-off-by: Jyri Sarha <jsarha@ti.com> Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c10
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_regs.h14
2 files changed, 22 insertions, 2 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 163f111cd481..208768922030 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -69,6 +69,7 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
69 struct drm_gem_cma_object *gem; 69 struct drm_gem_cma_object *gem;
70 unsigned int depth, bpp; 70 unsigned int depth, bpp;
71 dma_addr_t start, end; 71 dma_addr_t start, end;
72 u64 dma_base_and_ceiling;
72 73
73 drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp); 74 drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
74 gem = drm_fb_cma_get_gem_obj(fb, 0); 75 gem = drm_fb_cma_get_gem_obj(fb, 0);
@@ -79,8 +80,13 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
79 80
80 end = start + (crtc->mode.vdisplay * fb->pitches[0]); 81 end = start + (crtc->mode.vdisplay * fb->pitches[0]);
81 82
82 tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, start); 83 /* Write LCDC_DMA_FB_BASE_ADDR_0_REG and LCDC_DMA_FB_CEILING_ADDR_0_REG
83 tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, end - 1); 84 * with a single insruction, if available. This should make it more
85 * unlikely that LCDC would fetch the DMA addresses in the middle of
86 * an update.
87 */
88 dma_base_and_ceiling = (u64)(end - 1) << 32 | start;
89 tilcdc_write64(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_base_and_ceiling);
84 90
85 if (tilcdc_crtc->curr_fb) 91 if (tilcdc_crtc->curr_fb)
86 drm_flip_work_queue(&tilcdc_crtc->unref_work, 92 drm_flip_work_queue(&tilcdc_crtc->unref_work,
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
index 1bf5e2553acc..f57c0d62c76a 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
+++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
@@ -119,6 +119,20 @@ static inline void tilcdc_write(struct drm_device *dev, u32 reg, u32 data)
119 iowrite32(data, priv->mmio + reg); 119 iowrite32(data, priv->mmio + reg);
120} 120}
121 121
122static inline void tilcdc_write64(struct drm_device *dev, u32 reg, u64 data)
123{
124 struct tilcdc_drm_private *priv = dev->dev_private;
125 volatile void __iomem *addr = priv->mmio + reg;
126
127#ifdef iowrite64
128 iowrite64(data, addr);
129#else
130 __iowmb();
131 /* This compiles to strd (=64-bit write) on ARM7 */
132 *(volatile u64 __force *)addr = __cpu_to_le64(data);
133#endif
134}
135
122static inline u32 tilcdc_read(struct drm_device *dev, u32 reg) 136static inline u32 tilcdc_read(struct drm_device *dev, u32 reg)
123{ 137{
124 struct tilcdc_drm_private *priv = dev->dev_private; 138 struct tilcdc_drm_private *priv = dev->dev_private;