drm/i915: Replace vblank PM QoS with "Interrupt-Based AGPBUSY#"
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 5 Feb 2011 10:08:21 +0000 (10:08 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 1 Mar 2011 17:33:38 +0000 (17:33 +0000)
I stumbled over this magic bit in the gen3 INSTPM:

Bit11 Interrupt-Based AGPBUSY# Enable:

‘0’ = Pending GMCH interrupts will not cause AGPBUSY# assertion.
‘1’ = Pending GMCH interrupts will cause AGPBUSY# assertion and hence
      can cause the CPU to exit C3.  There is no suppression of cacheable
      writes.

Note that in either case in C3 the interrupts are not lost. They will be
forwarded to the ICH when the GMCH is out of C3.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Tested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@kernel.org
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h

index 39d7cd3bcfc7376065ddbb8bbc46fb8ae3196441..188b497e50768d56a3a93f2422000c03a0bcaddf 100644 (file)
@@ -1353,7 +1353,12 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
        else
                i915_enable_pipestat(dev_priv, pipe,
                                     PIPE_VBLANK_INTERRUPT_ENABLE);
+
+       /* maintain vblank delivery even in deep C-states */
+       if (dev_priv->info->gen == 3)
+               I915_WRITE(INSTPM, INSTPM_AGPBUSY_DIS << 16);
        spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
        return 0;
 }
 
@@ -1366,6 +1371,10 @@ void i915_disable_vblank(struct drm_device *dev, int pipe)
        unsigned long irqflags;
 
        spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+       if (dev_priv->info->gen == 3)
+               I915_WRITE(INSTPM,
+                          INSTPM_AGPBUSY_DIS << 16 | INSTPM_AGPBUSY_DIS);
+
        if (HAS_PCH_SPLIT(dev))
                ironlake_disable_display_irq(dev_priv, (pipe == 0) ?
                                             DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
index e1be98f799d83d21907a5febb3e38f67ba0566ed..368819a23f73ef6eb850e678a1bf1132c6697a34 100644 (file)
 #define   I915_ERROR_INSTRUCTION                       (1<<0)
 #define INSTPM         0x020c0
 #define   INSTPM_SELF_EN (1<<12) /* 915GM only */
+#define   INSTPM_AGPBUSY_DIS (1<<11) /* gen3: when disabled, pending interrupts
+                                       will not assert AGPBUSY# and will only
+                                       be delivered when out of C3. */
 #define ACTHD          0x020c8
 #define FW_BLC         0x020d8
-#define FW_BLC2                0x020dc
+#define FW_BLC2                0x020dc
 #define FW_BLC_SELF    0x020e0 /* 915+ only */
 #define   FW_BLC_SELF_EN_MASK      (1<<31)
 #define   FW_BLC_SELF_FIFO_MASK    (1<<16) /* 945 only */