[Intel-gfx] [PATCH]DRM/IGD: Support IGD EOS

Shaohua Li shaohua.li at intel.com
Mon Aug 24 04:25:23 CEST 2009


In the event that any one of the DAC analog outputs (R,G,B) were driven
at full-scale (white video) or some analog level close to full-scale
voltage, and if the video cable were then disconnected, the analog video
voltage level would exceed the maximum electrical overstress limit of the
native (thin-oxide) transistors thus causing a long-term reliability concern.
The electrical overstress condition occurs in this particular case.

This patch address the IGD EOS (electrical overstress condition) issue.
When the EOS interrupt occurs, OS should disable DAC and then disable EOS,
then the normal hotplug operation follows.

TODO: it appears the normal unplug interrupt is missed as reported by Li Peng,
need more checks here.

Signed-off-by: Shaohua Li <shaohua.li at intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c  |   21 +++++++++++++++++++++
 drivers/gpu/drm/i915/i915_reg.h  |    2 ++
 drivers/gpu/drm/i915/intel_crt.c |   28 ++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+)

Index: linux/drivers/gpu/drm/i915/i915_reg.h
===================================================================
--- linux.orig/drivers/gpu/drm/i915/i915_reg.h	2009-08-24 09:42:34.000000000 +0800
+++ linux/drivers/gpu/drm/i915/i915_reg.h	2009-08-24 09:43:57.000000000 +0800
@@ -683,6 +683,7 @@
 #define   SDVOB_HOTPLUG_INT_EN			(1 << 26)
 #define   SDVOC_HOTPLUG_INT_EN			(1 << 25)
 #define   TV_HOTPLUG_INT_EN			(1 << 18)
+#define   CRT_EOS_INT_EN			(1 << 10)
 #define   CRT_HOTPLUG_INT_EN			(1 << 9)
 #define   CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
 #define CRT_HOTPLUG_ACTIVATION_PERIOD_32	(0 << 8)
@@ -717,6 +718,7 @@
 #define   DPC_HOTPLUG_INT_STATUS		(1 << 28)
 #define   HDMID_HOTPLUG_INT_STATUS		(1 << 27)
 #define   DPD_HOTPLUG_INT_STATUS		(1 << 27)
+#define   CRT_EOS_INT_STATUS			(1 << 12)
 #define   CRT_HOTPLUG_INT_STATUS		(1 << 11)
 #define   TV_HOTPLUG_INT_STATUS			(1 << 10)
 #define   CRT_HOTPLUG_MONITOR_MASK		(3 << 8)
Index: linux/drivers/gpu/drm/i915/i915_irq.c
===================================================================
--- linux.orig/drivers/gpu/drm/i915/i915_irq.c	2009-08-24 09:42:34.000000000 +0800
+++ linux/drivers/gpu/drm/i915/i915_irq.c	2009-08-24 09:43:57.000000000 +0800
@@ -565,6 +565,27 @@ irqreturn_t i915_driver_irq_handler(DRM_
 
 			I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
 			I915_READ(PORT_HOTPLUG_STAT);
+
+			/* EOS interrupts occurs */
+			if (IS_IGD(dev) &&
+				(hotplug_status & CRT_EOS_INT_STATUS)) {
+				u32 temp;
+
+				DRM_DEBUG("EOS interrupt occurs\n");
+				/* status is already cleared */
+				temp = I915_READ(ADPA);
+				temp &= ~ADPA_DAC_ENABLE;
+				I915_WRITE(ADPA, temp);
+
+				temp = I915_READ(PORT_HOTPLUG_EN);
+				temp &= ~CRT_EOS_INT_EN;
+				I915_WRITE(PORT_HOTPLUG_EN, temp);
+
+				temp = I915_READ(PORT_HOTPLUG_STAT);
+				if (temp & CRT_EOS_INT_STATUS)
+					I915_WRITE(PORT_HOTPLUG_STAT,
+						CRT_EOS_INT_STATUS);
+			}
 		}
 
 		I915_WRITE(IIR, iir);
Index: linux/drivers/gpu/drm/i915/intel_crt.c
===================================================================
--- linux.orig/drivers/gpu/drm/i915/intel_crt.c	2009-08-24 09:42:34.000000000 +0800
+++ linux/drivers/gpu/drm/i915/intel_crt.c	2009-08-24 09:43:57.000000000 +0800
@@ -64,6 +64,34 @@ static void intel_crt_dpms(struct drm_en
 	}
 
 	I915_WRITE(reg, temp);
+
+	if (IS_IGD(dev)) {
+		if (mode == DRM_MODE_DPMS_OFF) {
+			/* turn off DAC */
+			temp = I915_READ(PORT_HOTPLUG_EN);
+			temp &= ~CRT_EOS_INT_EN;
+			I915_WRITE(PORT_HOTPLUG_EN, temp);
+
+			temp = I915_READ(PORT_HOTPLUG_STAT);
+			if (temp & CRT_EOS_INT_STATUS)
+				I915_WRITE(PORT_HOTPLUG_STAT,
+					CRT_EOS_INT_STATUS);
+		} else {
+			/* turn on DAC. EOS interrupt must be enabled after DAC
+			 * is enabled, so it sounds not good to enable it in
+			 * i915_driver_irq_postinstall()
+			 * wait 12.5ms after DAC is enabled
+			 */
+			msleep(13);
+			temp = I915_READ(PORT_HOTPLUG_STAT);
+			if (temp & CRT_EOS_INT_STATUS)
+				I915_WRITE(PORT_HOTPLUG_STAT,
+					CRT_EOS_INT_STATUS);
+			temp = I915_READ(PORT_HOTPLUG_EN);
+			temp |= CRT_EOS_INT_EN;
+			I915_WRITE(PORT_HOTPLUG_EN, temp);
+		}
+	}
 }
 
 static int intel_crt_mode_valid(struct drm_connector *connector,



More information about the Intel-gfx mailing list