According to bspec, with ring mode scheduling on gen >= 8, we need to disable ring idle message before writing zero to Ring Buffer Enable. Signed-off-by: Mika Kuoppala <mika.kuoppala@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.c | 28 +++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_uncore.c | 12 ++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1038f5c..564c593 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2609,6 +2609,8 @@ void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv, void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv, enum forcewake_domains domains); void assert_forcewakes_inactive(struct drm_i915_private *dev_priv); +void assert_forcewakes_active(struct drm_i915_private *dev_priv); + static inline bool intel_vgpu_active(struct drm_device *dev) { return to_i915(dev)->vgpu.active; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6eeba63..9bead93 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1643,6 +1643,8 @@ enum skl_disp_power_wells { #define GFX_PSMI_GRANULARITY (1<<10) #define GFX_PPGTT_ENABLE (1<<9) +#define CSPWRFSM 0x022AC + #define VLV_DISPLAY_BASE 0x180000 #define VLV_MIPI_BASE VLV_DISPLAY_BASE diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d934f85..c06dc76 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -531,6 +531,31 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *ring) } } +static void disable_ring(struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = to_i915(ring->dev); + const bool need_idle_disable = ring->id == RCS && + INTEL_INFO(ring->dev)->gen > 7; + + assert_forcewakes_active(dev_priv); + + if (need_idle_disable) { + I915_WRITE(RING_PSMI_CTL(ring->mmio_base), + _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); + + if (wait_for((I915_READ(CSPWRFSM) & ((1 << 6) - 1)) == 0x30, + 1000)) + DRM_ERROR("%s: disable idle msg timeout\n", + ring->name); + } + + I915_WRITE_CTL(ring, 0); + + if (need_idle_disable) + I915_WRITE(GEN6_RC_SLEEP_PSMI_CONTROL, + _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); +} + static bool stop_ring(struct intel_engine_cs *ring) { struct drm_i915_private *dev_priv = to_i915(ring->dev); @@ -548,7 +573,8 @@ static bool stop_ring(struct intel_engine_cs *ring) } } - I915_WRITE_CTL(ring, 0); + disable_ring(ring); + I915_WRITE_HEAD(ring, 0); ring->write_tail(ring, 0); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index a6d8a3e..4e070e0 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -525,6 +525,18 @@ void assert_forcewakes_inactive(struct drm_i915_private *dev_priv) WARN_ON(domain->wake_count); } +void assert_forcewakes_active(struct drm_i915_private *dev_priv) +{ + struct intel_uncore_forcewake_domain *domain; + enum forcewake_domain_id id; + + if (!dev_priv->uncore.funcs.force_wake_get) + return; + + for_each_fw_domain(domain, dev_priv, id) + WARN_ON(domain->wake_count == 0); +} + /* We give fast paths for the really cool registers */ #define NEEDS_FORCE_WAKE(dev_priv, reg) \ ((reg) < 0x40000 && (reg) != FORCEWAKE) -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx