summaryrefslogtreecommitdiff
path: root/src/i830_driver.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@work.jf.intel.com>2007-05-12 20:04:31 -0700
committerKeith Packard <keithp@work.jf.intel.com>2007-05-12 20:04:31 -0700
commitb31bef1a8effa9acb6de7edd206b9d8c48d88144 (patch)
tree63bc8b328c3c7303c4ceaf81392da90f621ef2f5 /src/i830_driver.c
parent3b769af53e0ef6ef9b56afd679446c73a0e63ea5 (diff)
Deal with i830 CRT load detection which cannot use FORCE_BORDER.
Chips newer than the i830 can force the border color for the active period of the screen, allowing the load detection to easily see the right data. In addition, newer chips appear to have more sensible load detection hardware which either ignores inactive periods on the screen or performs some longer-term averaging. The i830 appears to provide unfiltered samples of the detected load. For the i830, then, emit a border at the bottom of the screen and, for load detection, simply turn it purple and wait for the current line to be within the border. Sample an entire scanline, counting the number of times the load detection sees a monitor. In my testing, the presence of a monitor will cause the detection to succeed every time, while the absense will cause it to fail about 75% of the time. The code here, checks for presence at least 75% of the time, which should be adequate. Also, as the new mode configuration code has already taken care to enable the CRT output, eliminate much of the load detection code which is simply duplicating functionality from the general mode setting code. This should result in faster load detection as this code will now run in no more than one frame time. It does burn the CPU the whole time though, polling the displayed scanline register.
Diffstat (limited to 'src/i830_driver.c')
-rw-r--r--src/i830_driver.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 1d8b7f8f..b4d9d086 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -744,6 +744,12 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
break;
case I830_OUTPUT_ANALOG:
crtc_mask = ((1 << 0));
+ /*
+ * 915 cannot do double-wide on pipe B
+ * 830 cannot put CRT on pipe B
+ */
+ if (!IS_I915G(pI830) && !IS_I915GM (pI830) && !IS_I830(pI830))
+ crtc_mask |= ((1 << 1));
clone_mask = ((1 << I830_OUTPUT_ANALOG) |
(1 << I830_OUTPUT_DVO) |
(1 << I830_OUTPUT_SDVO));
@@ -1735,6 +1741,7 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->saveVTOTAL_A = INREG(VTOTAL_A);
pI830->saveVBLANK_A = INREG(VBLANK_A);
pI830->saveVSYNC_A = INREG(VSYNC_A);
+ pI830->saveBCLRPAT_A = INREG(BCLRPAT_A);
pI830->saveDSPASTRIDE = INREG(DSPASTRIDE);
pI830->saveDSPASIZE = INREG(DSPASIZE);
pI830->saveDSPAPOS = INREG(DSPAPOS);
@@ -1759,6 +1766,7 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->saveVTOTAL_B = INREG(VTOTAL_B);
pI830->saveVBLANK_B = INREG(VBLANK_B);
pI830->saveVSYNC_B = INREG(VSYNC_B);
+ pI830->saveBCLRPAT_B = INREG(BCLRPAT_B);
pI830->saveDSPBSTRIDE = INREG(DSPBSTRIDE);
pI830->saveDSPBSIZE = INREG(DSPBSIZE);
pI830->saveDSPBPOS = INREG(DSPBPOS);
@@ -1857,6 +1865,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(VTOTAL_A, pI830->saveVTOTAL_A);
OUTREG(VBLANK_A, pI830->saveVBLANK_A);
OUTREG(VSYNC_A, pI830->saveVSYNC_A);
+ OUTREG(BCLRPAT_A, pI830->saveBCLRPAT_A);
OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE);
OUTREG(DSPASIZE, pI830->saveDSPASIZE);
@@ -1894,6 +1903,7 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(VTOTAL_B, pI830->saveVTOTAL_B);
OUTREG(VBLANK_B, pI830->saveVBLANK_B);
OUTREG(VSYNC_B, pI830->saveVSYNC_B);
+ OUTREG(BCLRPAT_B, pI830->saveBCLRPAT_B);
OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE);
OUTREG(DSPBSIZE, pI830->saveDSPBSIZE);
OUTREG(DSPBPOS, pI830->saveDSPBPOS);