Skip to content

Commit

Permalink
drm/i915/gen4: Extra CRT hotplug paranoia
Browse files Browse the repository at this point in the history
Disable the CRT plug interrupt while doing the force cycle, explicitly
clear any CRT interrupt we may have generated, and restore when done.
Should mitigate interrupt storms from hotplug detection.

Signed-off-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
  • Loading branch information
Adam Jackson authored and Eric Anholt committed May 26, 2010
1 parent 734b415 commit 7a772c4
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 8 deletions.
1 change: 0 additions & 1 deletion drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,6 @@
#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 CRT_FORCE_HOTPLUG_MASK 0xfffffe1f

#define PORT_HOTPLUG_STAT 0x61114
#define HDMIB_HOTPLUG_INT_STATUS (1 << 29)
Expand Down
21 changes: 14 additions & 7 deletions drivers/gpu/drm/i915/intel_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 hotplug_en;
u32 hotplug_en, orig, stat;
bool ret = false;
int i, tries = 0;

if (HAS_PCH_SPLIT(dev))
Expand All @@ -232,8 +233,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
tries = 2;
else
tries = 1;
hotplug_en = I915_READ(PORT_HOTPLUG_EN);
hotplug_en &= CRT_FORCE_HOTPLUG_MASK;
hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN);
hotplug_en &= CRT_HOTPLUG_MASK;
hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;

if (IS_G4X(dev))
Expand All @@ -255,11 +256,17 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
} while (time_after(timeout, jiffies));
}

if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
CRT_HOTPLUG_MONITOR_NONE)
return true;
stat = I915_READ(PORT_HOTPLUG_STAT);
if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE)
ret = true;

/* clear the interrupt we just generated, if any */
I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS);

return false;
/* and put the bits back */
I915_WRITE(PORT_HOTPLUG_EN, orig);

return ret;
}

static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
Expand Down

0 comments on commit 7a772c4

Please sign in to comment.