xf86-video-intel: src/i810_reg.h src/i830_crt.c

Keith Packard keithp at kemper.freedesktop.org
Thu Nov 6 15:06:42 PST 2008


 src/i810_reg.h |   15 ++++++++++++++
 src/i830_crt.c |   58 ++++++++++++++++++++++++++++++++++++---------------------
 2 files changed, 52 insertions(+), 21 deletions(-)

New commits:
commit 9942cfa6dcc70a09ea38f738b1e73e3f005080b9
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Nov 6 15:04:27 2008 -0800

    Use long crt hotplug activation time on GM45.
    
    The GM45 b-spec requires the use of the longer hotplug activation period,
    but does not require looping twice over the detection logic. With this
    patch, CRT detection appears solid on my GM45.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/src/i810_reg.h b/src/i810_reg.h
index e9c03e5..b391d55 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1242,7 +1242,22 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 # define SDVOC_HOTPLUG_INT_EN			(1 << 25)
 # define TV_HOTPLUG_INT_EN			(1 << 18)
 # define CRT_HOTPLUG_INT_EN			(1 << 9)
+# define CRT_HOTPLUG_ACTIVATION_PERIOD_32	(0 << 8)
+/* must use period 64 on GM45 according to docs */
+# define CRT_HOTPLUG_ACTIVATION_PERIOD_64	(1 << 8)
+# define CRT_HOTPLUG_DAC_ON_TIME_2M		(0 << 7)
+# define CRT_HOTPLUG_DAC_ON_TIME_4M		(1 << 7)
+# define CRT_HOTPLUG_VOLTAGE_COMPARE_40		(0 << 5)
+# define CRT_HOTPLUG_VOLTAGE_COMPARE_50		(1 << 5)
+# define CRT_HOTPLUG_VOLTAGE_COMPARE_60		(2 << 5)
+# define CRT_HOTPLUG_VOLTAGE_COMPARE_70		(3 << 5)
+# define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK	(3 << 5)
+# define CRT_HOTPLUG_DETECT_DELAY_1G		(0 << 4)
+# define CRT_HOTPLUG_DETECT_DELAY_2G		(1 << 4)
 # define CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
+# 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/src/i830_crt.c b/src/i830_crt.c
index 479fbe5..ad81fbb 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -158,39 +158,55 @@ i830_crt_detect_hotplug(xf86OutputPtr output)
 {
     ScrnInfoPtr	pScrn = output->scrn;
     I830Ptr	pI830 = I830PTR(pScrn);
-    uint32_t	temp;
+    uint32_t	hotplug_en, temp;
     const int	timeout_ms = 1000;
     int		starttime, curtime;
     int		tries = 1;
+    int		try;
 
-    /* On 4 series, CRT detect sequence need to be done twice for safe. */
-    if (IS_G4X(pI830))
+    /* On 4 series desktop, CRT detect sequence need to be done twice
+     * to get a reliable result. */
+    if (IS_G4X(pI830) && !IS_GM45(pI830))
 	tries = 2;
+    else
+	tries = 1;
 
-retry:
-    tries--;
+    hotplug_en = INREG(PORT_HOTPLUG_EN);
 
-    temp = INREG(PORT_HOTPLUG_EN);
+    hotplug_en &= ~CRT_HOTPLUG_MASK;
 
-    OUTREG(PORT_HOTPLUG_EN, temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
+    /* This starts the detection sequence */
+    hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
 
-    for (curtime = starttime = GetTimeInMillis();
-	 (curtime - starttime) < timeout_ms; curtime = GetTimeInMillis())
-    {
-	if ((INREG(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT) == 0)
-	    break;
-    }
+    /* GM45 requires a longer activation period to reliably
+     * detect CRT
+     */
+    if (IS_GM45(pI830))
+	hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
 
-    if (tries > 0)
-	goto retry;
+    /* Use the default voltage value */
+    hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
 
-    if ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
-	CRT_HOTPLUG_MONITOR_COLOR)
-    {
-	return TRUE;
-    } else {
-	return FALSE;
+    for (try = 0; try < tries; try++) {
+	/* turn FORCE_DETECT on */
+	OUTREG(PORT_HOTPLUG_EN, hotplug_en);
+
+	/* wait for FORCE_DETECT to go off */
+	for (curtime = starttime = GetTimeInMillis();
+	     (curtime - starttime) < timeout_ms;
+	     curtime = GetTimeInMillis())
+	{
+	    temp = INREG(PORT_HOTPLUG_EN);
+
+	    if ((temp & CRT_HOTPLUG_FORCE_DETECT) == 0)
+		break;
+	}
     }
+
+    /* Check the status to see if both blue and green are on now */
+    temp = INREG(PORT_HOTPLUG_STAT);
+    return ((temp & CRT_HOTPLUG_MONITOR_MASK) ==
+	    CRT_HOTPLUG_MONITOR_COLOR);
 }
 
 /**


More information about the xorg-commit mailing list