diff options
author | Deepak S <deepak.s@linux.intel.com> | 2014-03-15 10:53:22 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-03-28 13:31:58 -0400 |
commit | a6706b45a57a23a613b34793e1414991b60a09c1 (patch) | |
tree | 36b1707d2a687103de2ab8617313278fed9c5dff | |
parent | 4cc314893064dd3166708242dd0836ef47805d5c (diff) |
drm/i915: Track the enabled PM interrupts in dev_priv.
When we use different rps events for different platforms or due to wa,
we might end up needing this logic in a lot of places. Instead of
this let's use a variable in dev_priv to track the enabled PM
interrupts.
v2: Initialize pm_rps_events in intel_irq_init() (Ville).
Signed-off-by: Deepak S <deepak.s@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
[danvet: Frob the commit message a bit since the English was a bit too
garbled ;-) ]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 11 |
3 files changed, 17 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3f62be0fb5c5..7b344c5300f0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1468,6 +1468,7 @@ typedef struct drm_i915_private { | |||
1468 | }; | 1468 | }; |
1469 | u32 gt_irq_mask; | 1469 | u32 gt_irq_mask; |
1470 | u32 pm_irq_mask; | 1470 | u32 pm_irq_mask; |
1471 | u32 pm_rps_events; | ||
1471 | u32 pipestat_irq_mask[I915_MAX_PIPES]; | 1472 | u32 pipestat_irq_mask[I915_MAX_PIPES]; |
1472 | 1473 | ||
1473 | struct work_struct hotplug_work; | 1474 | struct work_struct hotplug_work; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9ef241fb86b3..df2f3007d8c5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1119,13 +1119,13 @@ static void gen6_pm_rps_work(struct work_struct *work) | |||
1119 | pm_iir = dev_priv->rps.pm_iir; | 1119 | pm_iir = dev_priv->rps.pm_iir; |
1120 | dev_priv->rps.pm_iir = 0; | 1120 | dev_priv->rps.pm_iir = 0; |
1121 | /* Make sure not to corrupt PMIMR state used by ringbuffer code */ | 1121 | /* Make sure not to corrupt PMIMR state used by ringbuffer code */ |
1122 | snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); | 1122 | snb_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
1123 | spin_unlock_irq(&dev_priv->irq_lock); | 1123 | spin_unlock_irq(&dev_priv->irq_lock); |
1124 | 1124 | ||
1125 | /* Make sure we didn't queue anything we're not going to process. */ | 1125 | /* Make sure we didn't queue anything we're not going to process. */ |
1126 | WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS); | 1126 | WARN_ON(pm_iir & ~dev_priv->pm_rps_events); |
1127 | 1127 | ||
1128 | if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0) | 1128 | if ((pm_iir & dev_priv->pm_rps_events) == 0) |
1129 | return; | 1129 | return; |
1130 | 1130 | ||
1131 | mutex_lock(&dev_priv->rps.hw_lock); | 1131 | mutex_lock(&dev_priv->rps.hw_lock); |
@@ -1543,10 +1543,10 @@ static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe) | |||
1543 | * the work queue. */ | 1543 | * the work queue. */ |
1544 | static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) | 1544 | static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) |
1545 | { | 1545 | { |
1546 | if (pm_iir & GEN6_PM_RPS_EVENTS) { | 1546 | if (pm_iir & dev_priv->pm_rps_events) { |
1547 | spin_lock(&dev_priv->irq_lock); | 1547 | spin_lock(&dev_priv->irq_lock); |
1548 | dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; | 1548 | dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; |
1549 | snb_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RPS_EVENTS); | 1549 | snb_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); |
1550 | spin_unlock(&dev_priv->irq_lock); | 1550 | spin_unlock(&dev_priv->irq_lock); |
1551 | 1551 | ||
1552 | queue_work(dev_priv->wq, &dev_priv->rps.work); | 1552 | queue_work(dev_priv->wq, &dev_priv->rps.work); |
@@ -2986,7 +2986,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) | |||
2986 | POSTING_READ(GTIER); | 2986 | POSTING_READ(GTIER); |
2987 | 2987 | ||
2988 | if (INTEL_INFO(dev)->gen >= 6) { | 2988 | if (INTEL_INFO(dev)->gen >= 6) { |
2989 | pm_irqs |= GEN6_PM_RPS_EVENTS; | 2989 | pm_irqs |= dev_priv->pm_rps_events; |
2990 | 2990 | ||
2991 | if (HAS_VEBOX(dev)) | 2991 | if (HAS_VEBOX(dev)) |
2992 | pm_irqs |= PM_VEBOX_USER_INTERRUPT; | 2992 | pm_irqs |= PM_VEBOX_USER_INTERRUPT; |
@@ -4034,6 +4034,9 @@ void intel_irq_init(struct drm_device *dev) | |||
4034 | INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); | 4034 | INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); |
4035 | INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); | 4035 | INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); |
4036 | 4036 | ||
4037 | /* Let's track the enabled rps events */ | ||
4038 | dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; | ||
4039 | |||
4037 | setup_timer(&dev_priv->gpu_error.hangcheck_timer, | 4040 | setup_timer(&dev_priv->gpu_error.hangcheck_timer, |
4038 | i915_hangcheck_elapsed, | 4041 | i915_hangcheck_elapsed, |
4039 | (unsigned long) dev); | 4042 | (unsigned long) dev); |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index fd68f93671bb..faa059a902a1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -3160,7 +3160,8 @@ static void gen6_disable_rps_interrupts(struct drm_device *dev) | |||
3160 | struct drm_i915_private *dev_priv = dev->dev_private; | 3160 | struct drm_i915_private *dev_priv = dev->dev_private; |
3161 | 3161 | ||
3162 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); | 3162 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); |
3163 | I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) & ~GEN6_PM_RPS_EVENTS); | 3163 | I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) & |
3164 | ~dev_priv->pm_rps_events); | ||
3164 | /* Complete PM interrupt masking here doesn't race with the rps work | 3165 | /* Complete PM interrupt masking here doesn't race with the rps work |
3165 | * item again unmasking PM interrupts because that is using a different | 3166 | * item again unmasking PM interrupts because that is using a different |
3166 | * register (PMIMR) to mask PM interrupts. The only risk is in leaving | 3167 | * register (PMIMR) to mask PM interrupts. The only risk is in leaving |
@@ -3170,7 +3171,7 @@ static void gen6_disable_rps_interrupts(struct drm_device *dev) | |||
3170 | dev_priv->rps.pm_iir = 0; | 3171 | dev_priv->rps.pm_iir = 0; |
3171 | spin_unlock_irq(&dev_priv->irq_lock); | 3172 | spin_unlock_irq(&dev_priv->irq_lock); |
3172 | 3173 | ||
3173 | I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); | 3174 | I915_WRITE(GEN6_PMIIR, dev_priv->pm_rps_events); |
3174 | } | 3175 | } |
3175 | 3176 | ||
3176 | static void gen6_disable_rps(struct drm_device *dev) | 3177 | static void gen6_disable_rps(struct drm_device *dev) |
@@ -3232,12 +3233,12 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) | |||
3232 | 3233 | ||
3233 | spin_lock_irq(&dev_priv->irq_lock); | 3234 | spin_lock_irq(&dev_priv->irq_lock); |
3234 | WARN_ON(dev_priv->rps.pm_iir); | 3235 | WARN_ON(dev_priv->rps.pm_iir); |
3235 | snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); | 3236 | snb_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
3236 | I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS); | 3237 | I915_WRITE(GEN6_PMIIR, dev_priv->pm_rps_events); |
3237 | spin_unlock_irq(&dev_priv->irq_lock); | 3238 | spin_unlock_irq(&dev_priv->irq_lock); |
3238 | 3239 | ||
3239 | /* only unmask PM interrupts we need. Mask all others. */ | 3240 | /* only unmask PM interrupts we need. Mask all others. */ |
3240 | enabled_intrs = GEN6_PM_RPS_EVENTS; | 3241 | enabled_intrs = dev_priv->pm_rps_events; |
3241 | 3242 | ||
3242 | /* IVB and SNB hard hangs on looping batchbuffer | 3243 | /* IVB and SNB hard hangs on looping batchbuffer |
3243 | * if GEN6_PM_UP_EI_EXPIRED is masked. | 3244 | * if GEN6_PM_UP_EI_EXPIRED is masked. |