Skip to content

Commit e34e57a

Browse files
author
Jyri Sarha
committed
drm/tilcdc: Write DMA base and ceiling address with single instruction
commit 7eb9f06 upstream. 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 <[email protected]> Reviewed-by: Tomi Valkeinen <[email protected]>
1 parent dccd567 commit e34e57a

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

drivers/gpu/drm/tilcdc/tilcdc_crtc.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
6969
struct drm_gem_cma_object *gem;
7070
unsigned int depth, bpp;
7171
dma_addr_t start, end;
72+
u64 dma_base_and_ceiling;
7273

7374
drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
7475
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)
7980

8081
end = start + (crtc->mode.vdisplay * fb->pitches[0]);
8182

82-
tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, start);
83-
tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, end - 1);
83+
/* Write LCDC_DMA_FB_BASE_ADDR_0_REG and LCDC_DMA_FB_CEILING_ADDR_0_REG
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);
8490

8591
if (tilcdc_crtc->curr_fb)
8692
drm_flip_work_queue(&tilcdc_crtc->unref_work,

drivers/gpu/drm/tilcdc/tilcdc_regs.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,20 @@ static inline void tilcdc_write(struct drm_device *dev, u32 reg, u32 data)
119119
iowrite32(data, priv->mmio + reg);
120120
}
121121

122+
static 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+
122136
static inline u32 tilcdc_read(struct drm_device *dev, u32 reg)
123137
{
124138
struct tilcdc_drm_private *priv = dev->dev_private;

0 commit comments

Comments
 (0)