drm/i915: fix VGA plane disable for Ironlake+
We need to use I/O port instructions to access VGA registers on
Ironlake+, and it doesn't hurt on other platforms, so switch the VGA
plane disable function over to using them. Move it to init time as well
while we're at it, no need to repeatedly disable the VGA plane with
every mode set and DPMS event.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 149c18b..fbe42f0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -29,6 +29,7 @@
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/vgaarb.h>
#include "drmP.h"
#include "intel_drv.h"
#include "i915_drm.h"
@@ -1621,29 +1622,6 @@
return 0;
}
-/* Disable the VGA plane that we never use */
-static void i915_disable_vga (struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- u8 sr1;
- u32 vga_reg;
-
- if (HAS_PCH_SPLIT(dev))
- vga_reg = CPU_VGACNTRL;
- else
- vga_reg = VGACNTRL;
-
- if (I915_READ(vga_reg) & VGA_DISP_DISABLE)
- return;
-
- I915_WRITE8(VGA_SR_INDEX, 1);
- sr1 = I915_READ8(VGA_SR_DATA);
- I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5));
- udelay(100);
-
- I915_WRITE(vga_reg, VGA_DISP_DISABLE);
-}
-
static void ironlake_disable_pll_edp (struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -2156,8 +2134,6 @@
dev_priv->display.disable_fbc)
dev_priv->display.disable_fbc(dev);
- i915_disable_vga(dev);
-
/* disable cpu pipe, disable after all planes disabled */
temp = I915_READ(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) != 0) {
@@ -2391,9 +2367,6 @@
dev_priv->display.disable_fbc)
dev_priv->display.disable_fbc(dev);
- /* Disable the VGA plane that we never use */
- i915_disable_vga(dev);
-
/* Disable display plane */
temp = I915_READ(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
@@ -6002,6 +5975,29 @@
}
}
+/* Disable the VGA plane that we never use */
+static void i915_disable_vga(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u8 sr1;
+ u32 vga_reg;
+
+ if (HAS_PCH_SPLIT(dev))
+ vga_reg = CPU_VGACNTRL;
+ else
+ vga_reg = VGACNTRL;
+
+ vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
+ outb(1, VGA_SR_INDEX);
+ sr1 = inb(VGA_SR_DATA);
+ outb(sr1 | 1<<5, VGA_SR_DATA);
+ vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
+ udelay(300);
+
+ I915_WRITE(vga_reg, VGA_DISP_DISABLE);
+ POSTING_READ(vga_reg);
+}
+
void intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6050,6 +6046,9 @@
intel_init_clock_gating(dev);
+ /* Just disable it once at startup */
+ i915_disable_vga(dev);
+
if (IS_IRONLAKE_M(dev)) {
ironlake_enable_drps(dev);
intel_init_emon(dev);