• Neil Armstrong's avatar
    drm/meson: Fixes for drm_crtc_vblank_on/off support · 2bcd3eca
    Neil Armstrong authored
    Since Linux 4.17, calls to drm_crtc_vblank_on/off are mandatory, and we get
    a warning when ctrc is disabled :
    " driver forgot to call drm_crtc_vblank_off()"
    
    But, the vsync IRQ was not totally disabled due the transient hardware
    state and specific interrupt line, thus adding proper IRQ masking from
    the HHI system control registers.
    
    The last change fixes a race condition introduced by calling the added
    drm_crtc_vblank_on/off when an HPD event occurs from the HDMI connector,
    triggering a WARN_ON() in the _atomic_begin() callback when the CRTC
    is disabled, thus also triggering a WARN_ON() in drm_vblank_put() :
    
    WARNING: CPU: 0 PID: 1185 at drivers/gpu/drm/meson/meson_crtc.c:157 meson_crtc_atomic_begin+0x78/0x80
    [...]
    Call trace:
      meson_crtc_atomic_begin+0x78/0x80
      drm_atomic_helper_commit_planes+0x140/0x218
      drm_atomic_helper_commit_tail+0x38/0x80
      commit_tail+0x7c/0x80
      drm_atomic_helper_commit+0xdc/0x150
      drm_atomic_commit+0x54/0x60
      restore_fbdev_mode_atomic+0x198/0x238
      restore_fbdev_mode+0x6c/0x1c0
      drm_fb_helper_restore_fbdev_mode_unlocked+0x7c/0xf0
      drm_fb_helper_set_par+0x34/0x60
      drm_fb_helper_hotplug_event.part.28+0xb8/0xc8
      drm_fbdev_client_hotplug+0xa4/0xe0
      drm_client_dev_hotplug+0x90/0xe0
      drm_kms_helper_hotplug_event+0x3c/0x48
      drm_helper_hpd_irq_event+0x134/0x168
      dw_hdmi_top_thread_irq+0x3c/0x50
    [...]
    WARNING: CPU: 0 PID: 1185 at drivers/gpu/drm/drm_vblank.c:1026 drm_vblank_put+0xb4/0xc8
    [...]
     Call trace:
      drm_vblank_put+0xb4/0xc8
      drm_crtc_vblank_put+0x24/0x30
      drm_atomic_helper_wait_for_vblanks.part.9+0x130/0x2b8
      drm_atomic_helper_commit_tail+0x68/0x80
    [...]
    
    The issue is that vblank need to be enabled in any occurrence of :
    - atomic_enable()
    - atomic_begin() and state->enable == true, which was not the case
    
    Moving the CRTC enable code to a common function and calling in one of
    these occurrence solves this race condition and makes sure vblank is
    enabled in each call to _atomic_begin() from the HPD event leading to
    drm_atomic_helper_commit_planes().
    
    To Summarize :
    - Make sure that the CRTC code will call the drm_crtc_vblank_on()/off()
    - *Really* mask the Vsync IRQ
    - Initialize and enable vblank at the first
      atomic_begin()/_atomic_enable()
    
    Cc: stable@vger.kernel.org # 4.17+
    Signed-off-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
    Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
    [fixed typos+added cc for stable]
    Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
    Link: https://patchwork.freedesktop.org/patch/msgid/20181122160103.10993-1-narmstrong@baylibre.comSigned-off-by: default avatarSean Paul <seanpaul@chromium.org>
    2bcd3eca
meson_crtc.c 7.32 KB