Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/meson: fix vsync buffer update

The plane buffer address/stride/height was incorrectly updated in the
plane_atomic_update operation instead of the vsync irq.
This patch delays this operation in the vsync irq along with the
other plane delayed setup.

This issue was masked using legacy framebuffer and X11 modesetting, but
is clearly visible using gbm rendering when buffer is submitted late after
vblank, like using software decoding and OpenGL rendering in Kodi.
With this patch, tearing and other artifacts disappears completely.

Cc: Michal Lazo <michal.lazo@gmail.com>
Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/1518689976-23292-1-git-send-email-narmstrong@baylibre.com

+12 -4
+6
drivers/gpu/drm/meson/meson_crtc.c
··· 36 36 #include "meson_venc.h" 37 37 #include "meson_vpp.h" 38 38 #include "meson_viu.h" 39 + #include "meson_canvas.h" 39 40 #include "meson_registers.h" 40 41 41 42 /* CRTC definition */ ··· 192 191 meson_vpp_setup_interlace_vscaler_osd1(priv, &dest); 193 192 } else 194 193 meson_vpp_disable_interlace_vscaler_osd1(priv); 194 + 195 + meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1, 196 + priv->viu.osd1_addr, priv->viu.osd1_stride, 197 + priv->viu.osd1_height, MESON_CANVAS_WRAP_NONE, 198 + MESON_CANVAS_BLKMODE_LINEAR); 195 199 196 200 /* Enable OSD1 */ 197 201 writel_bits_relaxed(VPP_OSD1_POSTBLEND, VPP_OSD1_POSTBLEND,
+3
drivers/gpu/drm/meson/meson_drv.h
··· 43 43 bool osd1_commit; 44 44 uint32_t osd1_ctrl_stat; 45 45 uint32_t osd1_blk0_cfg[5]; 46 + uint32_t osd1_addr; 47 + uint32_t osd1_stride; 48 + uint32_t osd1_height; 46 49 } viu; 47 50 48 51 struct {
+3 -4
drivers/gpu/drm/meson/meson_plane.c
··· 164 164 /* Update Canvas with buffer address */ 165 165 gem = drm_fb_cma_get_gem_obj(fb, 0); 166 166 167 - meson_canvas_setup(priv, MESON_CANVAS_ID_OSD1, 168 - gem->paddr, fb->pitches[0], 169 - fb->height, MESON_CANVAS_WRAP_NONE, 170 - MESON_CANVAS_BLKMODE_LINEAR); 167 + priv->viu.osd1_addr = gem->paddr; 168 + priv->viu.osd1_stride = fb->pitches[0]; 169 + priv->viu.osd1_height = fb->height; 171 170 172 171 spin_unlock_irqrestore(&priv->drm->event_lock, flags); 173 172 }