Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7a772c49 authored by Adam Jackson's avatar Adam Jackson Committed by Eric Anholt
Browse files

drm/i915/gen4: Extra CRT hotplug paranoia



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: default avatarAdam Jackson <ajax@redhat.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 734b4157
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -1067,7 +1067,6 @@
#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV	(0 << 2)
#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV	(0 << 2)
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV	(1 << 2)
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV	(1 << 2)
#define CRT_HOTPLUG_MASK			(0x3fc) /* Bits 9-2 */
#define CRT_HOTPLUG_MASK			(0x3fc) /* Bits 9-2 */
#define CRT_FORCE_HOTPLUG_MASK			0xfffffe1f


#define PORT_HOTPLUG_STAT	0x61114
#define PORT_HOTPLUG_STAT	0x61114
#define   HDMIB_HOTPLUG_INT_STATUS		(1 << 29)
#define   HDMIB_HOTPLUG_INT_STATUS		(1 << 29)
+14 −7
Original line number Original line Diff line number Diff line
@@ -217,7 +217,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
{
{
	struct drm_device *dev = connector->dev;
	struct drm_device *dev = connector->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 hotplug_en;
	u32 hotplug_en, orig, stat;
	bool ret = false;
	int i, tries = 0;
	int i, tries = 0;


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


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


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


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

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

	return ret;
}
}


static bool intel_crt_detect_ddc(struct drm_encoder *encoder)
static bool intel_crt_detect_ddc(struct drm_encoder *encoder)