xf86-video-intel: Branch 'modesetting' - 7 commits - man/i810.man src/i810_reg.h src/i830_display.c src/i830_display.h src/i830_driver.c src/i830.h

Eric Anholt anholt at kemper.freedesktop.org
Wed Jun 21 01:13:58 EEST 2006


 man/i810.man       |    6 --
 src/i810_reg.h     |    5 +
 src/i830.h         |    1 
 src/i830_display.c |  148 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/i830_display.h |    2 
 src/i830_driver.c  |   60 ++++++++-------------
 6 files changed, 170 insertions(+), 52 deletions(-)

New commits:
diff-tree 896ffe78fe96469cdd3ade77c8e68e1503967223 (from parents)
Merge: 89c2c4bc40b8c032915ccb3ed4f3c143c3d8db12 52243d407cad93283956660de4771097ac0b4b2d
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jun 20 15:10:35 2006 -0700

    Merge branch 'modesetting-origin' into modesetting

diff --cc src/i810_reg.h
index c45368d,8fd6022..b95f795
@@@ -746,12 -753,9 +753,13 @@@
  #define PORT_HOTPLUG_STAT	0x61114
  # define CRT_HOTPLUG_INT_STATUS			(1 << 11)
  # define TV_HOTPLUG_INT_STATUS			(1 << 10)
 +# define CRT_HOTPLUG_MONITOR_MASK		(3 << 8)
 +# define CRT_HOTPLUG_MONITOR_COLOR		(3 << 8)
 +# define CRT_HOTPLUG_MONITOR_MONO		(2 << 8)
 +# define CRT_HOTPLUG_MONITOR_NONE		(0 << 8)
  # define SDVOC_HOTPLUG_INT_STATUS		(1 << 7)
  # define SDVOB_HOTPLUG_INT_STATUS		(1 << 6)
+ #define SDVOB_PRESERVE_MASK			((1 << 17) | (1 << 16) | (1 << 14))
  
  #define SDVOB			0x61140
  #define SDVOC			0x61160
diff-tree 89c2c4bc40b8c032915ccb3ed4f3c143c3d8db12 (from be08661e3126907c50c54485042fcde00b0da2b4)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jun 20 15:10:19 2006 -0700

    Add #if 0-ed code I've been using for CRT detection debugging.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index dd3122e..bc375e7 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -4545,6 +4545,20 @@ I830CheckDevicesTimer(OsTimerPtr timer, 
    ScrnInfoPtr pScrn = (ScrnInfoPtr) arg;
    I830Ptr pI830 = I830PTR(pScrn);
    int cloned = 0;
+#if 0
+   Bool found_crt;
+   int start, finish;
+
+   if (!pScrn->vtSema)
+      return 1000;
+
+   start = GetTimeInMillis();
+   found_crt = i830DetectCRT(pScrn, FALSE);
+   finish = GetTimeInMillis();
+
+   xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Detected CRT as %s in %dms\n",
+	      found_crt ? "connected" : "disconnected", finish - start);
+#endif
 
    if (pScrn->vtSema) {
       /* Check for monitor lid being closed/opened and act accordingly */
diff-tree be08661e3126907c50c54485042fcde00b0da2b4 (from b454c9601f005c69c11556a558150403378d34d9)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jun 20 14:48:03 2006 -0700

    Only default to enabling CRT or LVDS output if they're actually detected.
    
    Still, if we haven't detected any outputs automatically (including CRT through
    DDC), default to CRT anyway.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index a4fde94..dd3122e 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1952,26 +1952,17 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
 	 pI830->MonType2 |= PIPE_LFP;
       }
 
-      for (i=0; i<pI830->num_outputs; i++) {
-	 if (pI830->output[i].MonInfo == NULL)
-	    continue;
-
-	 switch (pI830->output[i].type) {
-	 case I830_OUTPUT_ANALOG:
-	 case I830_OUTPUT_DVO:
-	    pI830->MonType1 |= PIPE_CRT;
-	    break;
-	 case I830_OUTPUT_LVDS:
-	    pI830->MonType2 |= PIPE_LFP;
-	    break;
-	 case I830_OUTPUT_SDVO:
-	    /* XXX DVO */
-	    break;
-	 case I830_OUTPUT_UNUSED:
-	    break;
-	 }
+      if (i830DetectCRT(pScrn, TRUE)) {
+	 pI830->MonType1 |= PIPE_CRT;
       }
 
+      /* And, if we haven't found anything (including CRT through DDC), assume
+       * that there's a CRT and that the user has set up some appropriate modes
+       * or something.
+       */
+      if (pI830->MonType1 == PIPE_NONE && pI830->MonType2 == PIPE_NONE)
+	 pI830->MonType1 |= PIPE_CRT;
+
       if (pI830->MonType1 != PIPE_NONE)
 	 pI830->pipe = 0;
       else
diff-tree b454c9601f005c69c11556a558150403378d34d9 (from 0b76646666e9d330e77c6f81af8b91e34623be92)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jun 20 14:32:40 2006 -0700

    Add support for CRT detection using DDC.
    
    This method is slower (~5ms), but works on older chipsets.  Also, load-based
    detection is disabled, as it can be fooled by other outputs on the pipe being
    active, such as LVDS.

diff --git a/src/i830_display.c b/src/i830_display.c
index 6146933..3a4833e 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -737,15 +737,57 @@ i830LoadDetectCRT(ScrnInfoPtr pScrn)
 	return FALSE;
 }
 
+/**
+ * Detects CRT presence by probing for a response on the DDC address.
+ *
+ * This takes approximately 5ms in testing on an i915GM, with CRT connected or
+ * not.
+ */
 Bool
-i830DetectCRT(ScrnInfoPtr pScrn)
+i830DDCDetectCRT(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
+    struct _I830OutputRec *output;
+
+    output = &pI830->output[0];
+    /* CRT should always be at 0, but check anyway */
+    if (output->type != I830_OUTPUT_ANALOG)
+	return FALSE;
+
+    return xf86I2CProbeAddress(output->pDDCBus, 0x00A0);
+}
+
+/**
+ * Attempts to detect CRT presence through any method available.
+ *
+ * @param allow_disturb enables detection methods that may cause flickering
+ *        on active displays.
+ */
+Bool
+i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    Bool found_ddc;
 
     if (IS_I945G(pI830) || IS_I945GM(pI830))
 	return i830HotplugDetectCRT(pScrn);
 
-    return i830LoadDetectCRT(pScrn);
+    found_ddc = i830DDCDetectCRT(pScrn);
+    if (found_ddc)
+	return TRUE;
+
+    /* Use the load-detect method if we're not currently outputting to the CRT,
+     * or we don't care.
+     *
+     * Actually, the method is unreliable currently.  We need to not share a
+     * pipe, as it seems having other outputs on that pipe will result in a
+     * false positive.
+     */
+    if (0 && (allow_disturb || !(INREG(ADPA) & !ADPA_DAC_ENABLE))) {
+	return i830LoadDetectCRT(pScrn);
+    }
+
+    return FALSE;
 }
 
 /**
diff --git a/src/i830_display.h b/src/i830_display.h
index aecf8dc..2e61afc 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -27,7 +27,7 @@
 
 /* i830_display.c */
 Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
-Bool i830DetectCRT(ScrnInfoPtr pScrn);
+Bool i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb);
 void i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on);
 void i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y);
 
diff-tree 0b76646666e9d330e77c6f81af8b91e34623be92 (from e4584a4f44a70d746396ed48b8e40033504d68b2)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jun 20 13:57:26 2006 -0700

    Add CRT detection function by testing for load, and clean up hotplug version.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 53c65bb..c45368d 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -746,6 +746,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define PORT_HOTPLUG_STAT	0x61114
 # define CRT_HOTPLUG_INT_STATUS			(1 << 11)
 # define TV_HOTPLUG_INT_STATUS			(1 << 10)
+# define CRT_HOTPLUG_MONITOR_MASK		(3 << 8)
+# define CRT_HOTPLUG_MONITOR_COLOR		(3 << 8)
+# define CRT_HOTPLUG_MONITOR_MONO		(2 << 8)
+# define CRT_HOTPLUG_MONITOR_NONE		(0 << 8)
 # define SDVOC_HOTPLUG_INT_STATUS		(1 << 7)
 # define SDVOB_HOTPLUG_INT_STATUS		(1 << 6)
 
@@ -830,6 +834,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define PIPEACONF_PIPE_LOCKED	(1<<25)
 #define PIPEACONF_PALETTE	0
 #define PIPEACONF_GAMMA 	(1<<24)
+#define PIPECONF_FORCE_BORDER	(1<<25)
 
 #define PIPEBCONF 0x71008
 #define PIPEBCONF_ENABLE	(1<<31)
diff --git a/src/i830_display.c b/src/i830_display.c
index 73e976f..6146933 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -643,20 +643,109 @@ done:
     return ok;
 }
 
-Bool
-i830DetectCRT(ScrnInfoPtr pScrn)
+/**
+ * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
+ *
+ * Only for I945G/GM.
+ */
+static Bool
+i830HotplugDetectCRT(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
     CARD32 temp;
+    const int timeout_ms = 1000;
+    int starttime, curtime;
 
     temp = INREG(PORT_HOTPLUG_EN);
-    OUTREG(PORT_HOTPLUG_EN, temp | CRT_HOTPLUG_FORCE_DETECT);
 
-    /* Wait for the bit to clear to signal detection finished. */
-    while (INREG(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT)
-	;
+    OUTREG(PORT_HOTPLUG_EN, temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
+
+    for (curtime = starttime = GetTimeInMillis();
+	 (curtime - starttime) < timeout_ms; curtime = GetTimeInMillis())
+    {
+	if ((INREG(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT) == 0)
+	    break;
+    }
+
+    if ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
+	CRT_HOTPLUG_MONITOR_COLOR)
+    {
+	return TRUE;
+    } else {
+	return FALSE;
+    }
+}
+
+/**
+ * Detects CRT presence by checking for load.
+ *
+ * Requires that the current pipe's DPLL is active.  This will cause flicker
+ * on the CRT, so it should not be used while the display is being used.  Only
+ * color (not monochrome) displays are detected.
+ */
+static Bool
+i830LoadDetectCRT(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    CARD32 adpa, pipeconf;
+    CARD8 st00;
+    int pipeconf_reg, bclrpat_reg, dpll_reg;
+    int pipe;
+
+    pipe = pI830->pipe;
+    if (pipe == 0) {
+	bclrpat_reg = BCLRPAT_A;
+	pipeconf_reg = PIPEACONF;
+	dpll_reg = DPLL_A;
+    } else {
+	bclrpat_reg = BCLRPAT_B;
+	pipeconf_reg = PIPEBCONF;
+	dpll_reg = DPLL_B;
+    }
+
+    /* Don't try this if the DPLL isn't running. */
+    if (!(INREG(dpll_reg) & DPLL_VCO_ENABLE))
+	return FALSE;
+
+    adpa = INREG(ADPA);
+
+    /* Enable CRT output if disabled. */
+    if (!(adpa & ADPA_DAC_ENABLE)) {
+	OUTREG(ADPA, adpa | ADPA_DAC_ENABLE |
+	       ((pipe == 1) ? ADPA_PIPE_B_SELECT : 0));
+    }
+
+    /* Set the border color to red, green.  Maybe we should save/restore this
+     * reg.
+     */
+    OUTREG(bclrpat_reg, 0x00500050);
+
+    /* Force the border color through the active region */
+    pipeconf = INREG(pipeconf_reg);
+    OUTREG(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
+
+    /* Read the ST00 VGA status register */
+    st00 = pI830->readStandard(pI830, 0x3c2);
+
+    /* Restore previous settings */
+    OUTREG(pipeconf_reg, pipeconf);
+    OUTREG(ADPA, adpa);
+
+    if (st00 & (1 << 4))
+	return TRUE;
+    else
+	return FALSE;
+}
+
+Bool
+i830DetectCRT(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    if (IS_I945G(pI830) || IS_I945GM(pI830))
+	return i830HotplugDetectCRT(pScrn);
 
-    return ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_INT_STATUS));
+    return i830LoadDetectCRT(pScrn);
 }
 
 /**
diff-tree e4584a4f44a70d746396ed48b8e40033504d68b2 (from ab60e34dcfc52ab5f22a82145d5b4db51b4c62c5)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jun 20 10:39:28 2006 -0700

    Remove dead DisplayInfo option.

diff --git a/man/i810.man b/man/i810.man
index 099e1f8..f6b7368 100644
--- a/man/i810.man
+++ b/man/i810.man
@@ -179,12 +179,6 @@ NOTE: Using this option may cause text m
 and thus should be used with caution.
 Default: disabled.
 .TP
-.BI "Option \*qDisplayInfo\*q \*q" boolean \*q
-It has been found that a certain BIOS call can lockup the Xserver because
-of a problem in the Video BIOS. The log file will identify if you are
-suffering from this problem and tell you to turn this option off.
-Default: enabled
-.TP
 .BI "Option \*qDevicePresence\*q \*q" boolean \*q
 Tell the driver to perform an active detect of the currently connected
 monitors. This option is useful if the monitor was not connected when
diff --git a/src/i830.h b/src/i830.h
index c60bfbe..efd9f6d 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -416,7 +416,6 @@ typedef struct _I830Rec {
 
    unsigned int SaveGeneration;
    Bool vbeRestoreWorkaround;
-   Bool displayInfo;
    Bool devicePresence;
 
    OsTimerPtr devicesTimer;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 425ddd5..a4fde94 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -261,7 +261,6 @@ static OptionInfoRec I830BIOSOptions[] =
    {OPTION_COLOR_KEY,	"ColorKey",	OPTV_INTEGER,	{0},	FALSE},
    {OPTION_VIDEO_KEY,	"VideoKey",	OPTV_INTEGER,	{0},	FALSE},
    {OPTION_VBE_RESTORE,	"VBERestore",	OPTV_BOOLEAN,	{0},	FALSE},
-   {OPTION_DISPLAY_INFO,"DisplayInfo",	OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_DEVICE_PRESENCE,"DevicePresence",OPTV_BOOLEAN,{0},	FALSE},
    {OPTION_MONITOR_LAYOUT, "MonitorLayout", OPTV_ANYSTR,{0},	FALSE},
    {OPTION_CLONE,	"Clone",	OPTV_BOOLEAN,	{0},	FALSE},
@@ -2252,24 +2251,6 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int f
       }
    }
 
-   /* Buggy BIOS 3066 is known to cause this, so turn this off */
-   if (pI830->bios_version == 3066) {
-      pI830->displayInfo = FALSE;
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Detected Broken Video BIOS, turning off displayInfo.\n");
-   } else
-      pI830->displayInfo = TRUE;
-   from = X_DEFAULT;
-   if (!xf86ReturnOptValBool(pI830->Options, OPTION_DISPLAY_INFO, TRUE)) {
-      pI830->displayInfo = FALSE;
-      from = X_CONFIG;
-   }
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_DISPLAY_INFO, FALSE)) {
-      pI830->displayInfo = TRUE;
-      from = X_CONFIG;
-   }
-   xf86DrvMsg(pScrn->scrnIndex, from, "Display Info: %s.\n",
-	      pI830->displayInfo ? "enabled" : "disabled");
-
    PrintDisplayDeviceInfo(pScrn);
 
    if (xf86IsEntityShared(pScrn->entityList[0])) {
diff-tree ab60e34dcfc52ab5f22a82145d5b4db51b4c62c5 (from c1c46f882f9a11c383c8d1d1ce393be8fda55ed0)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Tue Jun 20 10:07:47 2006 -0700

    Add debugging info for pipe/display plane size.

diff --git a/src/i830_display.c b/src/i830_display.c
index 95fa936..73e976f 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -411,6 +411,9 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	(int)(vtot & 0xffff) + 1, (int)(vtot >> 16) + 1,
 	(int)(vblank & 0xffff) + 1, (int)(vblank >> 16) + 1,
 	(int)(vsync & 0xffff) + 1, (int)(vsync >> 16) + 1);
+    ErrorF("pipesrc: %dx%d, dspsize: %dx%d\n",
+	(int)(pipesrc >> 16) + 1, (int)(pipesrc & 0xffff) + 1,
+	(int)(dspsize & 0xffff) + 1, (int)(dspsize >> 16) + 1);
 #endif
 
     i830PrintPll("chosen", refclk, m1, m2, n, p1, p2);



More information about the xorg-commit mailing list