References: https://bugs.freedesktop.org/show_bug.cgi?id=104975 Signed-off-by: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_sprite.c | 16 ++++++++++++++++ 4 files changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d5e695da2fc4..11251e0107f4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1967,6 +1967,8 @@ struct drm_i915_private { /* Display functions */ struct drm_i915_display_funcs display; + spinlock_t display_evasion_lock; + /* PCH chipset type */ enum intel_pch pch_type; unsigned short pch_id; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 93f6ec2ea8f2..20af56644844 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6594,6 +6594,9 @@ enum { #define DIGITAL_PORTA_HOTPLUG_SHORT_DETECT (1 << 0) #define DIGITAL_PORTA_HOTPLUG_LONG_DETECT (2 << 0) +#define DOUBLE_BUFFER_CTL _MMIO(0x44500) +#define DOUBLE_BUFFER_CTL_GLOBAL_DISABLE (1 << 0) + /* refresh rate hardware control */ #define RR_HW_CTL _MMIO(0x45300) #define RR_HW_LOW_POWER_FRAMES_MASK 0xff diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 707406d1bf57..81087722bc49 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14476,6 +14476,7 @@ int intel_modeset_init(struct drm_device *dev) dev_priv->modeset_wq = alloc_ordered_workqueue("i915_modeset", 0); drm_mode_config_init(dev); + spin_lock_init(&dev_priv->display_evasion_lock); dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index ac0a4f9c1954..4d1e9b166d57 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -98,6 +98,13 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI); DEFINE_WAIT(wait); + if (INTEL_GEN(dev_priv) >= 9) { + spin_lock_irq(&dev_priv->display_evasion_lock); + I915_WRITE(DOUBLE_BUFFER_CTL, DOUBLE_BUFFER_CTL_GLOBAL_DISABLE); + scanline = intel_get_crtc_scanline(crtc); + goto done; + } + vblank_start = adjusted_mode->crtc_vblank_start; if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) vblank_start = DIV_ROUND_UP(vblank_start, 2); @@ -166,6 +173,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) while (need_vlv_dsi_wa && scanline == vblank_start) scanline = intel_get_crtc_scanline(crtc); +done: crtc->debug.scanline_start = scanline; crtc->debug.start_vbl_time = ktime_get(); crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc); @@ -192,6 +200,9 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end); + if (INTEL_GEN(dev_priv) >= 9) + I915_WRITE(DOUBLE_BUFFER_CTL, 0); + /* We're still in the vblank-evade critical section, this can't race. * Would be slightly nice to just grab the vblank count and arm the * event outside of the critical section - the spinlock might spin for a @@ -206,6 +217,11 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) new_crtc_state->base.event = NULL; } + if (INTEL_GEN(dev_priv) >= 9) { + spin_unlock_irq(&dev_priv->display_evasion_lock); + return; + } + local_irq_enable(); if (intel_vgpu_active(dev_priv)) -- 2.16.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx