summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Widawsky <ben@bwidawsk.net>2013-04-05 13:12:41 -0700
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-08 20:53:00 +0200
commitab5c608b2d96c8db80b9c7df072f18f3a4226b55 (patch)
treef25192e8a98fafcc3e1481feb53e985594e05692
parent40c7ead980945ac96eadbd6d99b050458d797e2b (diff)
downloadlinux-stable-ab5c608b2d96c8db80b9c7df072f18f3a4226b55.tar.gz
linux-stable-ab5c608b2d96c8db80b9c7df072f18f3a4226b55.tar.bz2
linux-stable-ab5c608b2d96c8db80b9c7df072f18f3a4226b55.zip
drm/i915: Don't touch South Display when PCH_NOP
Interrupts, clock gating, LVDS, and GMBUS are all within the, "this will be bad for CPU" range when we have PCH_NOP. There is a bit of a hack in init clock gating. We want to do most of the clock gating, but the part we skip will hang the system. It could probably be abstracted a bit better, but I don't feel it's too unsightly. v2: Use inverse HAS_PCH_NOP check (Jani) v3: Actually do what I claimed in v2 (spotted by Daniel) Merge Ivybridge IRQ handler PCH check to decrease whitespace (Daniel) Move LVDS bail into this patch (Ben) v4: logical rebase conflict resolution with SDEIIR (Ben) Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Brush up patch a bit and resolve conflicts: - Adjust PCH_NOP checks due to Egbert's hpd handling rework. - Addd a PCH_NOP check in the irq uninstall code. - Resolve conflicts with Paulo's SDE irq handling race fix. v5: Drop the added hunks in the ilk irq handler again, they're bogus. OOps. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c28
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c3
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c4
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c3
4 files changed, 29 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4c5bdd037388..b4e237d9927d 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -758,7 +758,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
{
struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier;
+ u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier = 0;
irqreturn_t ret = IRQ_NONE;
int i;
@@ -773,9 +773,11 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
* able to process them after we restore SDEIER (as soon as we restore
* it, we'll get an interrupt if SDEIIR still has something to process
* due to its back queue). */
- sde_ier = I915_READ(SDEIER);
- I915_WRITE(SDEIER, 0);
- POSTING_READ(SDEIER);
+ if (!HAS_PCH_NOP(dev)) {
+ sde_ier = I915_READ(SDEIER);
+ I915_WRITE(SDEIER, 0);
+ POSTING_READ(SDEIER);
+ }
gt_iir = I915_READ(GTIIR);
if (gt_iir) {
@@ -802,7 +804,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
}
/* check event from PCH */
- if (de_iir & DE_PCH_EVENT_IVB) {
+ if (!HAS_PCH_NOP(dev) && (de_iir & DE_PCH_EVENT_IVB)) {
u32 pch_iir = I915_READ(SDEIIR);
cpt_irq_handler(dev, pch_iir);
@@ -825,8 +827,10 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
I915_WRITE(DEIER, de_ier);
POSTING_READ(DEIER);
- I915_WRITE(SDEIER, sde_ier);
- POSTING_READ(SDEIER);
+ if (!HAS_PCH_NOP(dev)) {
+ I915_WRITE(SDEIER, sde_ier);
+ POSTING_READ(SDEIER);
+ }
return ret;
}
@@ -2027,6 +2031,9 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
I915_WRITE(GTIER, 0x0);
POSTING_READ(GTIER);
+ if (HAS_PCH_NOP(dev))
+ return;
+
/* south display irq */
I915_WRITE(SDEIMR, 0xffffffff);
/*
@@ -2112,6 +2119,10 @@ static void ibx_irq_postinstall(struct drm_device *dev)
mask = SDE_GMBUS | SDE_AUX_MASK;
else
mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
+
+ if (HAS_PCH_NOP(dev))
+ return;
+
I915_WRITE(SDEIIR, I915_READ(SDEIIR));
I915_WRITE(SDEIMR, ~mask);
}
@@ -2306,6 +2317,9 @@ static void ironlake_irq_uninstall(struct drm_device *dev)
I915_WRITE(GTIER, 0x0);
I915_WRITE(GTIIR, I915_READ(GTIIR));
+ if (HAS_PCH_NOP(dev))
+ return;
+
I915_WRITE(SDEIMR, 0xffffffff);
I915_WRITE(SDEIER, 0x0);
I915_WRITE(SDEIIR, I915_READ(SDEIIR));
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 55ffba1f5818..194df27c89eb 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -692,6 +692,9 @@ intel_parse_bios(struct drm_device *dev)
struct bdb_header *bdb = NULL;
u8 __iomem *bios = NULL;
+ if (HAS_PCH_NOP(dev))
+ return -ENODEV;
+
init_vbt_defaults(dev_priv);
/* XXX Should this validation be moved to intel_opregion.c? */
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index ef4744e1bf0b..5d245031e391 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -522,7 +522,9 @@ int intel_setup_gmbus(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
int ret, i;
- if (HAS_PCH_SPLIT(dev))
+ if (HAS_PCH_NOP(dev))
+ return 0;
+ else if (HAS_PCH_SPLIT(dev))
dev_priv->gpio_mmio_base = PCH_GPIOA - GPIOA;
else if (IS_VALLEYVIEW(dev))
dev_priv->gpio_mmio_base = VLV_DISPLAY_BASE;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 13a0666a53b4..17f157a7b640 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3890,7 +3890,8 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
snpcr |= GEN6_MBC_SNPCR_MED;
I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);
- cpt_init_clock_gating(dev);
+ if (!HAS_PCH_NOP(dev))
+ cpt_init_clock_gating(dev);
gen6_check_mch_setup(dev);
}