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