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