diff options
author | Damien Lespiau <damien.lespiau@intel.com> | 2015-03-06 13:50:51 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-03-17 17:30:07 -0400 |
commit | d14c03431340d0913f067ab18b6444e0f41d4f80 (patch) | |
tree | 5358e700e45e1d23fb29ad92f8e926267847d556 | |
parent | 510e6fdd8f796666ec6a8539b01b5e5e72913046 (diff) |
drm/i915/skl: Restore pipe interrupt registers after power well enabling
The pipe interrupt registers are in the actual pipe power well, so we
need to restore them when re-enable the corresponding power well.
I've also copied what we do on HSW/BDW for VGA, even if the we haven't
enabled unclaimed registers just yet.
v2: Don't run skl_power_well_post_enable() if the power well is already
enabled (Paulo)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_runtime_pm.c | 31 |
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d77a4b6ee74b..92e1ee44f07b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -3175,6 +3175,10 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, | |||
3175 | uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; | 3175 | uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; |
3176 | 3176 | ||
3177 | spin_lock_irq(&dev_priv->irq_lock); | 3177 | spin_lock_irq(&dev_priv->irq_lock); |
3178 | if (pipe_mask & 1 << PIPE_A) | ||
3179 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_A, | ||
3180 | dev_priv->de_irq_mask[PIPE_A], | ||
3181 | ~dev_priv->de_irq_mask[PIPE_A] | extra_ier); | ||
3178 | if (pipe_mask & 1 << PIPE_B) | 3182 | if (pipe_mask & 1 << PIPE_B) |
3179 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, | 3183 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, |
3180 | dev_priv->de_irq_mask[PIPE_B], | 3184 | dev_priv->de_irq_mask[PIPE_B], |
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 46ffb259d7cb..87a449cf5475 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
@@ -199,6 +199,34 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv) | |||
199 | 1 << PIPE_C | 1 << PIPE_B); | 199 | 1 << PIPE_C | 1 << PIPE_B); |
200 | } | 200 | } |
201 | 201 | ||
202 | static void skl_power_well_post_enable(struct drm_i915_private *dev_priv, | ||
203 | struct i915_power_well *power_well) | ||
204 | { | ||
205 | struct drm_device *dev = dev_priv->dev; | ||
206 | |||
207 | /* | ||
208 | * After we re-enable the power well, if we touch VGA register 0x3d5 | ||
209 | * we'll get unclaimed register interrupts. This stops after we write | ||
210 | * anything to the VGA MSR register. The vgacon module uses this | ||
211 | * register all the time, so if we unbind our driver and, as a | ||
212 | * consequence, bind vgacon, we'll get stuck in an infinite loop at | ||
213 | * console_unlock(). So make here we touch the VGA MSR register, making | ||
214 | * sure vgacon can keep working normally without triggering interrupts | ||
215 | * and error messages. | ||
216 | */ | ||
217 | if (power_well->data == SKL_DISP_PW_2) { | ||
218 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
219 | outb(inb(VGA_MSR_READ), VGA_MSR_WRITE); | ||
220 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
221 | |||
222 | gen8_irq_power_well_post_enable(dev_priv, | ||
223 | 1 << PIPE_C | 1 << PIPE_B); | ||
224 | } | ||
225 | |||
226 | if (power_well->data == SKL_DISP_PW_1) | ||
227 | gen8_irq_power_well_post_enable(dev_priv, 1 << PIPE_A); | ||
228 | } | ||
229 | |||
202 | static void hsw_set_power_well(struct drm_i915_private *dev_priv, | 230 | static void hsw_set_power_well(struct drm_i915_private *dev_priv, |
203 | struct i915_power_well *power_well, bool enable) | 231 | struct i915_power_well *power_well, bool enable) |
204 | { | 232 | { |
@@ -361,6 +389,9 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, | |||
361 | DRM_ERROR("PG2 distributing status timeout\n"); | 389 | DRM_ERROR("PG2 distributing status timeout\n"); |
362 | } | 390 | } |
363 | } | 391 | } |
392 | |||
393 | if (enable && !is_enabled) | ||
394 | skl_power_well_post_enable(dev_priv, power_well); | ||
364 | } | 395 | } |
365 | 396 | ||
366 | static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, | 397 | static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, |