Jesse Keating 3494df0
From dec23057518b7035117a1a732aa48be6d34f1be8 Mon Sep 17 00:00:00 2001
Jesse Keating 3494df0
From: Andrew Lutomirski <luto@mit.edu>
Jesse Keating 3494df0
Date: Sat, 12 Jun 2010 09:21:18 +0000
Jesse Keating 3494df0
Subject: i915: Fix CRT hotplug regression in 2.6.35-rc1
Jesse Keating 3494df0
Jesse Keating 3494df0
Commit 7a772c492fcfffae812ffca78a628e76fa57fe58 has two bugs which
Jesse Keating 3494df0
made the hotplug problems on my laptop worse instead of better.
Jesse Keating 3494df0
Jesse Keating 3494df0
First, it did not, in fact, disable the CRT plug interrupt -- it
Jesse Keating 3494df0
disabled all the other hotplug interrupts.  It seems rather doubtful
Jesse Keating 3494df0
that that bit of the patch fixed anything, so let's just remove it.
Jesse Keating 3494df0
(If you want to add it back, you probably meant ~CRT_HOTPLUG_INT_EN.)
Jesse Keating 3494df0
Jesse Keating 3494df0
Second, on at least my GM45, setting CRT_HOTPLUG_ACTIVATION_PERIOD_64
Jesse Keating 3494df0
and CRT_HOTPLUG_VOLTAGE_COMPARE_50 (when they were previously unset)
Jesse Keating 3494df0
causes a hotplug interrupt about three seconds later.  The old code
Jesse Keating 3494df0
never restored PORT_HOTPLUG_EN so this could only happen once, but
Jesse Keating 3494df0
they new code restores those registers.  So just set those bits when
Jesse Keating 3494df0
we set up the interrupt in the first place.
Jesse Keating 3494df0
Jesse Keating 3494df0
Signed-off-by: Andy Lutomirski <luto@mit.edu>
Jesse Keating 3494df0
---
Jesse Keating 3494df0
 drivers/gpu/drm/i915/i915_irq.c  |   12 +++++++++++-
Jesse Keating 3494df0
 drivers/gpu/drm/i915/i915_reg.h  |    1 -
Jesse Keating 3494df0
 drivers/gpu/drm/i915/intel_crt.c |    6 ------
Jesse Keating 3494df0
 3 files changed, 11 insertions(+), 8 deletions(-)
Jesse Keating 3494df0
Jesse Keating 3494df0
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
Jesse Keating 3494df0
index 2479be0..7acb1a6 100644
Jesse Keating 3494df0
--- a/drivers/gpu/drm/i915/i915_irq.c
Jesse Keating 3494df0
+++ b/drivers/gpu/drm/i915/i915_irq.c
Jesse Keating 3494df0
@@ -1400,8 +1400,18 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
Jesse Keating 3494df0
 			hotplug_en |= SDVOC_HOTPLUG_INT_EN;
Jesse Keating 3494df0
 		if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS)
Jesse Keating 3494df0
 			hotplug_en |= SDVOB_HOTPLUG_INT_EN;
Jesse Keating 3494df0
-		if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS)
Jesse Keating 3494df0
+		if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) {
Jesse Keating 3494df0
 			hotplug_en |= CRT_HOTPLUG_INT_EN;
Jesse Keating 3494df0
+
Jesse Keating 3494df0
+			/* Programming the CRT detection parameters tends
Jesse Keating 3494df0
+			   to generate a spurious hotplug event about three
Jesse Keating 3494df0
+			   seconds later.  So just do it once.
Jesse Keating 3494df0
+			*/
Jesse Keating 3494df0
+			if (IS_G4X(dev))
Jesse Keating 3494df0
+				hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
Jesse Keating 3494df0
+			hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
Jesse Keating 3494df0
+		}
Jesse Keating 3494df0
+
Jesse Keating 3494df0
 		/* Ignore TV since it's buggy */
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 		I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
Jesse Keating 3494df0
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
Jesse Keating 3494df0
index 64b0a3a..d390b17 100644
Jesse Keating 3494df0
--- a/drivers/gpu/drm/i915/i915_reg.h
Jesse Keating 3494df0
+++ b/drivers/gpu/drm/i915/i915_reg.h
Jesse Keating 3494df0
@@ -1130,7 +1130,6 @@
Jesse Keating 3494df0
 #define CRT_HOTPLUG_DETECT_DELAY_2G		(1 << 4)
Jesse Keating 3494df0
 #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV	(0 << 2)
Jesse Keating 3494df0
 #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV	(1 << 2)
Jesse Keating 3494df0
-#define CRT_HOTPLUG_MASK			(0x3fc) /* Bits 9-2 */
Jesse Keating 3494df0
 
Jesse Keating 3494df0
 #define PORT_HOTPLUG_STAT	0x61114
Jesse Keating 3494df0
 #define   HDMIB_HOTPLUG_INT_STATUS		(1 << 29)
Jesse Keating 3494df0
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
Jesse Keating 3494df0
index 22ff384..ee0732b 100644
Jesse Keating 3494df0
--- a/drivers/gpu/drm/i915/intel_crt.c
Jesse Keating 3494df0
+++ b/drivers/gpu/drm/i915/intel_crt.c
Jesse Keating 3494df0
@@ -234,14 +234,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
Jesse Keating 3494df0
 	else
Jesse Keating 3494df0
 		tries = 1;
Jesse Keating 3494df0
 	hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN);
Jesse Keating 3494df0
-	hotplug_en &= CRT_HOTPLUG_MASK;
Jesse Keating 3494df0
 	hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
Jesse Keating 3494df0
 
Jesse Keating 3494df0
-	if (IS_G4X(dev))
Jesse Keating 3494df0
-		hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
Jesse Keating 3494df0
-
Jesse Keating 3494df0
-	hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
Jesse Keating 3494df0
-
Jesse Keating 3494df0
 	for (i = 0; i < tries ; i++) {
Jesse Keating 3494df0
 		unsigned long timeout;
Jesse Keating 3494df0
 		/* turn on the FORCE_DETECT */
Jesse Keating 3494df0
-- 
Jesse Keating 3494df0
1.7.0.1
Jesse Keating 3494df0