drm/i915: Don't touch South Display when PCH_NOP
authorBen Widawsky <ben@bwidawsk.net>
Fri, 5 Apr 2013 20:12:41 +0000 (13:12 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 8 Apr 2013 18:53:00 +0000 (20:53 +0200)
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>
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_pm.c

index 4c5bdd03738819f348c6fc8c441fdc9b50a5d819..b4e237d9927dde4266a9673f2a53b8c4bccf2888 100644 (file)
@@ -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));
index 55ffba1f5818d933227c0ea5344afb491da295a9..194df27c89ebd04e49cd481997441a5416d44267 100644 (file)
@@ -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? */
index ef4744e1bf0bc44be8424a2cb936c26ff716da28..5d245031e391a464fbe8eb6fb6031e70e1ac6770 100644 (file)
@@ -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;
index 13a0666a53b42e9645179a30a3f3a2a69df09809..17f157a7b640109b1db6af7a157cdf6eae6863ce 100644 (file)
@@ -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);
 }