Commit 9e4fc22a authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-fixes-2015-01-15' of git://anongit.freedesktop.org/drm-intel into drm-fixes

misc i915 fixes

* tag 'drm-intel-fixes-2015-01-15' of git://anongit.freedesktop.org/drm-intel:
  drm/i915: Fix mutex->owner inspection race under DEBUG_MUTEXES
  drm/i915: Ban Haswell from using RCS flips
  drm/i915: vlv: sanitize RPS interrupt mask during GPU idling
  drm/i915: fix HW lockup due to missing RPS IRQ workaround on GEN6
  drm/i915: gen9: fix RPS interrupt routing to CPU vs. GT
parents 9aa609e1 226e5ae9
...@@ -5155,7 +5155,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) ...@@ -5155,7 +5155,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
if (!mutex_is_locked(mutex)) if (!mutex_is_locked(mutex))
return false; return false;
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES) #if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES)
return mutex->owner == task; return mutex->owner == task;
#else #else
/* Since UP may be pre-empted, we cannot assume that we own the lock */ /* Since UP may be pre-empted, we cannot assume that we own the lock */
......
...@@ -292,6 +292,23 @@ void gen6_enable_rps_interrupts(struct drm_device *dev) ...@@ -292,6 +292,23 @@ void gen6_enable_rps_interrupts(struct drm_device *dev)
spin_unlock_irq(&dev_priv->irq_lock); spin_unlock_irq(&dev_priv->irq_lock);
} }
u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask)
{
/*
* SNB,IVB can while VLV,CHV may hard hang on looping batchbuffer
* if GEN6_PM_UP_EI_EXPIRED is masked.
*
* TODO: verify if this can be reproduced on VLV,CHV.
*/
if (INTEL_INFO(dev_priv)->gen <= 7 && !IS_HASWELL(dev_priv))
mask &= ~GEN6_PM_RP_UP_EI_EXPIRED;
if (INTEL_INFO(dev_priv)->gen >= 8)
mask &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP;
return mask;
}
void gen6_disable_rps_interrupts(struct drm_device *dev) void gen6_disable_rps_interrupts(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -304,8 +321,7 @@ void gen6_disable_rps_interrupts(struct drm_device *dev) ...@@ -304,8 +321,7 @@ void gen6_disable_rps_interrupts(struct drm_device *dev)
spin_lock_irq(&dev_priv->irq_lock); spin_lock_irq(&dev_priv->irq_lock);
I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0));
~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0);
__gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events);
I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) &
......
...@@ -9815,7 +9815,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -9815,7 +9815,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
if (obj->tiling_mode != work->old_fb_obj->tiling_mode) if (obj->tiling_mode != work->old_fb_obj->tiling_mode)
/* vlv: DISPLAY_FLIP fails to change tiling */ /* vlv: DISPLAY_FLIP fails to change tiling */
ring = NULL; ring = NULL;
} else if (IS_IVYBRIDGE(dev)) { } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
ring = &dev_priv->ring[BCS]; ring = &dev_priv->ring[BCS];
} else if (INTEL_INFO(dev)->gen >= 7) { } else if (INTEL_INFO(dev)->gen >= 7) {
ring = obj->ring; ring = obj->ring;
......
...@@ -794,6 +794,7 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); ...@@ -794,6 +794,7 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask);
void gen6_reset_rps_interrupts(struct drm_device *dev); void gen6_reset_rps_interrupts(struct drm_device *dev);
void gen6_enable_rps_interrupts(struct drm_device *dev); void gen6_enable_rps_interrupts(struct drm_device *dev);
void gen6_disable_rps_interrupts(struct drm_device *dev); void gen6_disable_rps_interrupts(struct drm_device *dev);
u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask);
void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv);
void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv); void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv);
static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv)
......
...@@ -4363,16 +4363,7 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) ...@@ -4363,16 +4363,7 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
mask |= dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED); mask |= dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED);
mask &= dev_priv->pm_rps_events; mask &= dev_priv->pm_rps_events;
/* IVB and SNB hard hangs on looping batchbuffer return gen6_sanitize_rps_pm_mask(dev_priv, ~mask);
* if GEN6_PM_UP_EI_EXPIRED is masked.
*/
if (INTEL_INFO(dev_priv->dev)->gen <= 7 && !IS_HASWELL(dev_priv->dev))
mask |= GEN6_PM_RP_UP_EI_EXPIRED;
if (IS_GEN8(dev_priv->dev))
mask |= GEN8_PMINTR_REDIRECT_TO_NON_DISP;
return ~mask;
} }
/* gen6_set_rps is called to update the frequency request, but should also be /* gen6_set_rps is called to update the frequency request, but should also be
...@@ -4441,7 +4432,8 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) ...@@ -4441,7 +4432,8 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
return; return;
/* Mask turbo interrupt so that they will not come in between */ /* Mask turbo interrupt so that they will not come in between */
I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); I915_WRITE(GEN6_PMINTRMSK,
gen6_sanitize_rps_pm_mask(dev_priv, ~0));
vlv_force_gfx_clock(dev_priv, true); vlv_force_gfx_clock(dev_priv, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment