Skip to content

Commit

Permalink
drm/i915/skl: Restore pipe interrupt registers after power well enabling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Damien Lespiau authored and danvet committed Mar 17, 2015
1 parent 510e6fd commit d14c034
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -3175,6 +3175,10 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv,
uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN;

spin_lock_irq(&dev_priv->irq_lock);
if (pipe_mask & 1 << PIPE_A)
GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_A,
dev_priv->de_irq_mask[PIPE_A],
~dev_priv->de_irq_mask[PIPE_A] | extra_ier);
if (pipe_mask & 1 << PIPE_B)
GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B,
dev_priv->de_irq_mask[PIPE_B],
Expand Down
31 changes: 31 additions & 0 deletions drivers/gpu/drm/i915/intel_runtime_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,34 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
1 << PIPE_C | 1 << PIPE_B);
}

static void skl_power_well_post_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
struct drm_device *dev = dev_priv->dev;

/*
* After we re-enable the power well, if we touch VGA register 0x3d5
* we'll get unclaimed register interrupts. This stops after we write
* anything to the VGA MSR register. The vgacon module uses this
* register all the time, so if we unbind our driver and, as a
* consequence, bind vgacon, we'll get stuck in an infinite loop at
* console_unlock(). So make here we touch the VGA MSR register, making
* sure vgacon can keep working normally without triggering interrupts
* and error messages.
*/
if (power_well->data == SKL_DISP_PW_2) {
vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);

gen8_irq_power_well_post_enable(dev_priv,
1 << PIPE_C | 1 << PIPE_B);
}

if (power_well->data == SKL_DISP_PW_1)
gen8_irq_power_well_post_enable(dev_priv, 1 << PIPE_A);
}

static void hsw_set_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well, bool enable)
{
Expand Down Expand Up @@ -361,6 +389,9 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
DRM_ERROR("PG2 distributing status timeout\n");
}
}

if (enable && !is_enabled)
skl_power_well_post_enable(dev_priv, power_well);
}

static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
Expand Down

0 comments on commit d14c034

Please sign in to comment.