| 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 |
| |
| |
| @@ -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 |
| |
| |
| @@ -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 |
| |
| |
| @@ -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 |
| |