Merge tag 'drm-intel-next-fixes-2014-12-17' of git://anongit.freedesktop.org/drm-intel into drm-fixes
misc i915 fixes. * tag 'drm-intel-next-fixes-2014-12-17' of git://anongit.freedesktop.org/drm-intel: drm/i915: Disable PSMI sleep messages on all rings around context switches drm/i915: Force the CS stall for invalidate flushes drm/i915: Invalidate media caches on gen7 drm/i915: sanitize RPS resetting during GPU reset drm/i915: move RPS PM_IER enabling to gen6_enable_rps_interrupts drm/i915: vlv: fix IRQ masking when uninstalling interrupts
This commit is contained in:
commit
a548a838a1
|
@ -811,6 +811,8 @@ int i915_reset(struct drm_device *dev)
|
||||||
if (!i915.reset)
|
if (!i915.reset)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
intel_reset_gt_powersave(dev);
|
||||||
|
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
|
|
||||||
i915_gem_reset(dev);
|
i915_gem_reset(dev);
|
||||||
|
@ -880,7 +882,7 @@ int i915_reset(struct drm_device *dev)
|
||||||
* of re-init after reset.
|
* of re-init after reset.
|
||||||
*/
|
*/
|
||||||
if (INTEL_INFO(dev)->gen > 5)
|
if (INTEL_INFO(dev)->gen > 5)
|
||||||
intel_reset_gt_powersave(dev);
|
intel_enable_gt_powersave(dev);
|
||||||
} else {
|
} else {
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,7 +473,12 @@ mi_set_context(struct intel_engine_cs *ring,
|
||||||
u32 hw_flags)
|
u32 hw_flags)
|
||||||
{
|
{
|
||||||
u32 flags = hw_flags | MI_MM_SPACE_GTT;
|
u32 flags = hw_flags | MI_MM_SPACE_GTT;
|
||||||
int ret;
|
const int num_rings =
|
||||||
|
/* Use an extended w/a on ivb+ if signalling from other rings */
|
||||||
|
i915_semaphore_is_enabled(ring->dev) ?
|
||||||
|
hweight32(INTEL_INFO(ring->dev)->ring_mask) - 1 :
|
||||||
|
0;
|
||||||
|
int len, i, ret;
|
||||||
|
|
||||||
/* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB
|
/* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB
|
||||||
* invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value
|
* invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value
|
||||||
|
@ -490,15 +495,31 @@ mi_set_context(struct intel_engine_cs *ring,
|
||||||
if (!IS_HASWELL(ring->dev) && INTEL_INFO(ring->dev)->gen < 8)
|
if (!IS_HASWELL(ring->dev) && INTEL_INFO(ring->dev)->gen < 8)
|
||||||
flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN);
|
flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN);
|
||||||
|
|
||||||
ret = intel_ring_begin(ring, 6);
|
|
||||||
|
len = 4;
|
||||||
|
if (INTEL_INFO(ring->dev)->gen >= 7)
|
||||||
|
len += 2 + (num_rings ? 4*num_rings + 2 : 0);
|
||||||
|
|
||||||
|
ret = intel_ring_begin(ring, len);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */
|
/* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */
|
||||||
if (INTEL_INFO(ring->dev)->gen >= 7)
|
if (INTEL_INFO(ring->dev)->gen >= 7) {
|
||||||
intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE);
|
intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE);
|
||||||
else
|
if (num_rings) {
|
||||||
intel_ring_emit(ring, MI_NOOP);
|
struct intel_engine_cs *signaller;
|
||||||
|
|
||||||
|
intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings));
|
||||||
|
for_each_ring(signaller, to_i915(ring->dev), i) {
|
||||||
|
if (signaller == ring)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base));
|
||||||
|
intel_ring_emit(ring, _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
intel_ring_emit(ring, MI_NOOP);
|
intel_ring_emit(ring, MI_NOOP);
|
||||||
intel_ring_emit(ring, MI_SET_CONTEXT);
|
intel_ring_emit(ring, MI_SET_CONTEXT);
|
||||||
|
@ -510,10 +531,21 @@ mi_set_context(struct intel_engine_cs *ring,
|
||||||
*/
|
*/
|
||||||
intel_ring_emit(ring, MI_NOOP);
|
intel_ring_emit(ring, MI_NOOP);
|
||||||
|
|
||||||
if (INTEL_INFO(ring->dev)->gen >= 7)
|
if (INTEL_INFO(ring->dev)->gen >= 7) {
|
||||||
|
if (num_rings) {
|
||||||
|
struct intel_engine_cs *signaller;
|
||||||
|
|
||||||
|
intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings));
|
||||||
|
for_each_ring(signaller, to_i915(ring->dev), i) {
|
||||||
|
if (signaller == ring)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base));
|
||||||
|
intel_ring_emit(ring, _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
|
||||||
|
}
|
||||||
|
}
|
||||||
intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE);
|
intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE);
|
||||||
else
|
}
|
||||||
intel_ring_emit(ring, MI_NOOP);
|
|
||||||
|
|
||||||
intel_ring_advance(ring);
|
intel_ring_advance(ring);
|
||||||
|
|
||||||
|
|
|
@ -281,10 +281,14 @@ void gen6_enable_rps_interrupts(struct drm_device *dev)
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
spin_lock_irq(&dev_priv->irq_lock);
|
spin_lock_irq(&dev_priv->irq_lock);
|
||||||
|
|
||||||
WARN_ON(dev_priv->rps.pm_iir);
|
WARN_ON(dev_priv->rps.pm_iir);
|
||||||
WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events);
|
WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events);
|
||||||
dev_priv->rps.interrupts_enabled = true;
|
dev_priv->rps.interrupts_enabled = true;
|
||||||
|
I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) |
|
||||||
|
dev_priv->pm_rps_events);
|
||||||
gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
|
gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
|
||||||
|
|
||||||
spin_unlock_irq(&dev_priv->irq_lock);
|
spin_unlock_irq(&dev_priv->irq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3307,8 +3311,10 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
|
||||||
GEN5_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs);
|
GEN5_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs);
|
||||||
|
|
||||||
if (INTEL_INFO(dev)->gen >= 6) {
|
if (INTEL_INFO(dev)->gen >= 6) {
|
||||||
pm_irqs |= dev_priv->pm_rps_events;
|
/*
|
||||||
|
* RPS interrupts will get enabled/disabled on demand when RPS
|
||||||
|
* itself is enabled/disabled.
|
||||||
|
*/
|
||||||
if (HAS_VEBOX(dev))
|
if (HAS_VEBOX(dev))
|
||||||
pm_irqs |= PM_VEBOX_USER_INTERRUPT;
|
pm_irqs |= PM_VEBOX_USER_INTERRUPT;
|
||||||
|
|
||||||
|
@ -3520,7 +3526,11 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv)
|
||||||
dev_priv->pm_irq_mask = 0xffffffff;
|
dev_priv->pm_irq_mask = 0xffffffff;
|
||||||
GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]);
|
GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]);
|
||||||
GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]);
|
GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]);
|
||||||
GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, dev_priv->pm_rps_events);
|
/*
|
||||||
|
* RPS interrupts will get enabled/disabled on demand when RPS itself
|
||||||
|
* is enabled/disabled.
|
||||||
|
*/
|
||||||
|
GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, 0);
|
||||||
GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]);
|
GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3609,7 +3619,7 @@ static void vlv_display_irq_uninstall(struct drm_i915_private *dev_priv)
|
||||||
|
|
||||||
vlv_display_irq_reset(dev_priv);
|
vlv_display_irq_reset(dev_priv);
|
||||||
|
|
||||||
dev_priv->irq_mask = 0;
|
dev_priv->irq_mask = ~0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void valleyview_irq_uninstall(struct drm_device *dev)
|
static void valleyview_irq_uninstall(struct drm_device *dev)
|
||||||
|
|
|
@ -395,6 +395,7 @@
|
||||||
#define PIPE_CONTROL_STORE_DATA_INDEX (1<<21)
|
#define PIPE_CONTROL_STORE_DATA_INDEX (1<<21)
|
||||||
#define PIPE_CONTROL_CS_STALL (1<<20)
|
#define PIPE_CONTROL_CS_STALL (1<<20)
|
||||||
#define PIPE_CONTROL_TLB_INVALIDATE (1<<18)
|
#define PIPE_CONTROL_TLB_INVALIDATE (1<<18)
|
||||||
|
#define PIPE_CONTROL_MEDIA_STATE_CLEAR (1<<16)
|
||||||
#define PIPE_CONTROL_QW_WRITE (1<<14)
|
#define PIPE_CONTROL_QW_WRITE (1<<14)
|
||||||
#define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14)
|
#define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14)
|
||||||
#define PIPE_CONTROL_DEPTH_STALL (1<<13)
|
#define PIPE_CONTROL_DEPTH_STALL (1<<13)
|
||||||
|
@ -1128,6 +1129,7 @@ enum punit_power_well {
|
||||||
#define GEN6_VERSYNC (RING_SYNC_1(VEBOX_RING_BASE))
|
#define GEN6_VERSYNC (RING_SYNC_1(VEBOX_RING_BASE))
|
||||||
#define GEN6_VEVSYNC (RING_SYNC_2(VEBOX_RING_BASE))
|
#define GEN6_VEVSYNC (RING_SYNC_2(VEBOX_RING_BASE))
|
||||||
#define GEN6_NOSYNC 0
|
#define GEN6_NOSYNC 0
|
||||||
|
#define RING_PSMI_CTL(base) ((base)+0x50)
|
||||||
#define RING_MAX_IDLE(base) ((base)+0x54)
|
#define RING_MAX_IDLE(base) ((base)+0x54)
|
||||||
#define RING_HWS_PGA(base) ((base)+0x80)
|
#define RING_HWS_PGA(base) ((base)+0x80)
|
||||||
#define RING_HWS_PGA_GEN6(base) ((base)+0x2080)
|
#define RING_HWS_PGA_GEN6(base) ((base)+0x2080)
|
||||||
|
@ -1458,6 +1460,7 @@ enum punit_power_well {
|
||||||
#define GEN6_BLITTER_FBC_NOTIFY (1<<3)
|
#define GEN6_BLITTER_FBC_NOTIFY (1<<3)
|
||||||
|
|
||||||
#define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050
|
#define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050
|
||||||
|
#define GEN6_PSMI_SLEEP_MSG_DISABLE (1 << 0)
|
||||||
#define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12)
|
#define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12)
|
||||||
#define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10)
|
#define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10)
|
||||||
|
|
||||||
|
|
|
@ -6191,6 +6191,20 @@ void intel_cleanup_gt_powersave(struct drm_device *dev)
|
||||||
valleyview_cleanup_gt_powersave(dev);
|
valleyview_cleanup_gt_powersave(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gen6_suspend_rps(struct drm_device *dev)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
|
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: disable RPS interrupts on GEN9+ too once RPS support
|
||||||
|
* is added for it.
|
||||||
|
*/
|
||||||
|
if (INTEL_INFO(dev)->gen < 9)
|
||||||
|
gen6_disable_rps_interrupts(dev);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* intel_suspend_gt_powersave - suspend PM work and helper threads
|
* intel_suspend_gt_powersave - suspend PM work and helper threads
|
||||||
* @dev: drm device
|
* @dev: drm device
|
||||||
|
@ -6206,14 +6220,7 @@ void intel_suspend_gt_powersave(struct drm_device *dev)
|
||||||
if (INTEL_INFO(dev)->gen < 6)
|
if (INTEL_INFO(dev)->gen < 6)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
|
gen6_suspend_rps(dev);
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: disable RPS interrupts on GEN9+ too once RPS support
|
|
||||||
* is added for it.
|
|
||||||
*/
|
|
||||||
if (INTEL_INFO(dev)->gen < 9)
|
|
||||||
gen6_disable_rps_interrupts(dev);
|
|
||||||
|
|
||||||
/* Force GPU to min freq during suspend */
|
/* Force GPU to min freq during suspend */
|
||||||
gen6_rps_idle(dev_priv);
|
gen6_rps_idle(dev_priv);
|
||||||
|
@ -6316,8 +6323,11 @@ void intel_reset_gt_powersave(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
|
if (INTEL_INFO(dev)->gen < 6)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gen6_suspend_rps(dev);
|
||||||
dev_priv->rps.enabled = false;
|
dev_priv->rps.enabled = false;
|
||||||
intel_enable_gt_powersave(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ibx_init_clock_gating(struct drm_device *dev)
|
static void ibx_init_clock_gating(struct drm_device *dev)
|
||||||
|
|
|
@ -362,12 +362,15 @@ gen7_render_ring_flush(struct intel_engine_cs *ring,
|
||||||
flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
|
flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
|
||||||
flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
|
flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
|
||||||
flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
|
flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
|
||||||
|
flags |= PIPE_CONTROL_MEDIA_STATE_CLEAR;
|
||||||
/*
|
/*
|
||||||
* TLB invalidate requires a post-sync write.
|
* TLB invalidate requires a post-sync write.
|
||||||
*/
|
*/
|
||||||
flags |= PIPE_CONTROL_QW_WRITE;
|
flags |= PIPE_CONTROL_QW_WRITE;
|
||||||
flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
|
flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
|
||||||
|
|
||||||
|
flags |= PIPE_CONTROL_STALL_AT_SCOREBOARD;
|
||||||
|
|
||||||
/* Workaround: we must issue a pipe_control with CS-stall bit
|
/* Workaround: we must issue a pipe_control with CS-stall bit
|
||||||
* set before a pipe_control command that has the state cache
|
* set before a pipe_control command that has the state cache
|
||||||
* invalidate bit set. */
|
* invalidate bit set. */
|
||||||
|
|
Loading…
Reference in New Issue