xf86-video-intel: Branch 'modesetting' - 6 commits - src/i830_crt.c src/i830_display.c src/i830_display.h src/i830_driver.c src/i830.h src/i830_randr.c src/i830_xf86Modes.c
Eric Anholt
anholt at kemper.freedesktop.org
Sat Nov 4 02:46:56 EET 2006
src/i830.h | 5 +
src/i830_crt.c | 20 +++----
src/i830_display.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++---
src/i830_display.h | 5 +
src/i830_driver.c | 4 -
src/i830_randr.c | 3 -
src/i830_xf86Modes.c | 2
7 files changed, 153 insertions(+), 24 deletions(-)
New commits:
diff-tree 27df2ff7908ea7ea2943a5f3445e12dbc24d97c9 (from ecbe73b940b2d642115de4b73c2f757eb46ff956)
Author: Eric Anholt <eric at anholt.net>
Date: Fri Nov 3 15:55:10 2006 -0800
Report pipe status (and status mismatches) in i830DescribeOutputConfiguration()
diff --git a/src/i830_display.c b/src/i830_display.c
index e3db8ad..e36b5ef 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -796,12 +796,32 @@ i830DescribeOutputConfiguration(ScrnInfo
for (i = 0; i < pI830->availablePipes; i++) {
CARD32 dspcntr = INREG(DSPACNTR + (DSPBCNTR - DSPACNTR) * i);
+ CARD32 pipeconf = INREG(PIPEACONF + (PIPEBCONF - PIPEACONF) * i);
+ Bool hw_plane_enable = (dspcntr & DISPLAY_PLANE_ENABLE) != 0;
+ Bool hw_pipe_enable = (pipeconf & PIPEACONF_ENABLE) != 0;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " Pipe %c is %s\n",
+ 'A' + i, pI830->pipes[i].planeEnabled ? "on" : "off");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
" Display plane %c is now %s and connected to pipe %c.\n",
'A' + i,
pI830->pipes[i].planeEnabled ? "enabled" : "disabled",
dspcntr & DISPPLANE_SEL_PIPE_MASK ? 'B' : 'A');
+ if (hw_pipe_enable != pI830->pipes[i].planeEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " Hardware claims pipe %c is %s while software "
+ "believes it is %s\n",
+ 'A' + i, hw_pipe_enable ? "on" : "off",
+ pI830->pipes[i].planeEnabled ? "on" : "off");
+ }
+ if (hw_plane_enable != pI830->pipes[i].planeEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " Hardware claims plane %c is %s while software "
+ "believes it is %s\n",
+ 'A' + i, hw_plane_enable ? "on" : "off",
+ pI830->pipes[i].planeEnabled ? "on" : "off");
+ }
}
for (i = 0; i < pI830->num_outputs; i++) {
diff-tree ecbe73b940b2d642115de4b73c2f757eb46ff956 (from parents)
Merge: 561af007974b8cdad1eea907fb73ed9d430c21ac 9681602177124e84a817a1e1d428f1779f2a45c9
Author: Eric Anholt <eric at anholt.net>
Date: Fri Nov 3 15:59:59 2006 -0800
Merge branch 'modesetting-origin' into modesetting
Conflicts:
src/i830_display.c
diff --cc src/i830_display.c
index 6107c47,1175cf1..e3db8ad
@@@ -356,18 -357,14 +357,19 @@@
}
/**
- * Sets the given video mode on the given pipe. Assumes that plane A feeds
- * pipe A, and plane B feeds pipe B. Should not affect the other planes/pipes.
+ * Sets the given video mode on the given pipe.
+ *
+ * Plane A is always output to pipe A, and plane B to pipe B. The plane
+ * will not be enabled if plane_enable is FALSE, which is used for
+ * load detection, when something else will be output to the pipe other than
+ * display data.
*/
Bool
-i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
+i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
+ Bool plane_enable)
{
I830Ptr pI830 = I830PTR(pScrn);
+ I830PipePtr pI830Pipe = &pI830->pipes[pipe];
int m1 = 0, m2 = 0, n = 0, p1 = 0, p2 = 0;
CARD32 dpll = 0, fp = 0, temp;
CARD32 htot, hblank, hsync, vtot, vblank, vsync, dspcntr;
@@@ -628,12 -635,10 +640,12 @@@
temp = INREG(pipeconf_reg);
OUTREG(pipeconf_reg, temp | PIPEACONF_ENABLE);
- /* And then turn the plane on */
- OUTREG(dspcntr_reg, dspcntr);
+ if (plane_enable) {
+ /* And then turn the plane on */
+ OUTREG(dspcntr_reg, dspcntr);
+ }
- pI830->pipeCurMode[pipe] = *pMode;
+ pI830Pipe->curMode = *pMode;
return TRUE;
}
@@@ -729,31 -720,17 +727,18 @@@
didLock = I830DRILock(pScrn);
#endif
- if (pI830->operatingDevices & 0xff) {
- pI830->planeEnabled[0] = 1;
- } else {
- pI830->planeEnabled[0] = 0;
- }
-
- if (pI830->operatingDevices & 0xff00) {
- pI830->planeEnabled[1] = 1;
- } else {
- pI830->planeEnabled[1] = 0;
- }
+ pI830->pipes[0].planeEnabled = (pI830->operatingDevices & 0xff) != 0;
+ pI830->pipes[1].planeEnabled = (pI830->operatingDevices & 0xff00) != 0;
- for (i = 0; i < pI830->num_outputs; i++) {
+ for (i = 0; i < pI830->num_outputs; i++)
pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
- }
- if (pI830->planeEnabled[0]) {
- ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, 0, pMode),
- 0, TRUE);
- if (!ok)
- goto done;
- }
- if (pI830->planeEnabled[1]) {
- ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, 1, pMode),
- 1, TRUE);
+ for (i = 0; i < MAX_DISPLAY_PIPES; i++)
+ {
+ if (pI830->pipes[i].planeEnabled)
- ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i, pMode),
- i);
++ ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i,
++ pMode),
++ i, TRUE);
if (!ok)
goto done;
}
diff --cc src/i830_randr.c
index 5b02a53,67641d6..8b6ad49
@@@ -560,10 -562,10 +562,10 @@@
if (display_mode != randrp->modes[pipe])
{
- pI830->planeEnabled[pipe] = mode != NULL;
+ pI830Pipe->planeEnabled = mode != NULL;
if (display_mode)
{
- if (!i830PipeSetMode (pScrn, display_mode, pipe))
+ if (!i830PipeSetMode (pScrn, display_mode, pipe, TRUE))
return FALSE;
/* XXX need I830SDVOPostSetMode here */
}
diff-tree 561af007974b8cdad1eea907fb73ed9d430c21ac (from e416b426d83de031441ada7a77b6bd66cec8b5c9)
Author: Eric Anholt <eric at anholt.net>
Date: Fri Nov 3 15:26:14 2006 -0800
Add support for load-based CRT detection.
diff --git a/src/i830.h b/src/i830.h
index a07ba8e..4ce1a55 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -205,6 +205,11 @@ struct _I830OutputRec {
int type;
int pipe;
Bool disabled;
+ /**
+ * Marks that the output and associated pipe is temporarily enabled for
+ * load detection.
+ */
+ Bool load_detect_temp;
/**
* Turns the output on/off, or sets intermediate power levels if available.
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 0225727..4c704b2 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -32,6 +32,7 @@
#include "xf86.h"
#include "i830.h"
#include "i830_xf86Modes.h"
+#include "i830_display.h"
static void
i830_crt_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
@@ -166,7 +167,7 @@ i830_crt_detect_hotplug(ScrnInfoPtr pScr
* \return FALSE if CRT is disconnected.
*/
static Bool
-i830_crt_detect_load(ScrnInfoPtr pScrn)
+i830_crt_detect_load(ScrnInfoPtr pScrn, I830OutputPtr output)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 adpa, pipeconf;
@@ -174,7 +175,7 @@ i830_crt_detect_load(ScrnInfoPtr pScrn)
int pipeconf_reg, bclrpat_reg, dpll_reg;
int pipe;
- pipe = pI830->pipe;
+ pipe = output->pipe;
if (pipe == 0) {
bclrpat_reg = BCLRPAT_A;
pipeconf_reg = PIPEACONF;
@@ -263,15 +264,12 @@ i830_crt_detect(ScrnInfoPtr pScrn, I830O
if (i830_crt_detect_ddc(pScrn))
return OUTPUT_STATUS_CONNECTED;
- /* 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) {
- if (i830_crt_detect_load(pScrn))
+ /* Use the load-detect method if we have no other way of telling. */
+ if (i830GetLoadDetectPipe(pScrn, output) != -1) {
+ Bool connected = i830_crt_detect_load(pScrn, output);
+
+ i830ReleaseLoadDetectPipe(pScrn, output);
+ if (connected)
return OUTPUT_STATUS_CONNECTED;
else
return OUTPUT_STATUS_DISCONNECTED;
diff --git a/src/i830_display.c b/src/i830_display.c
index b3019f8..6107c47 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -356,11 +356,16 @@ i830PipeFindClosestMode(ScrnInfoPtr pScr
}
/**
- * Sets the given video mode on the given pipe. Assumes that plane A feeds
- * pipe A, and plane B feeds pipe B. Should not affect the other planes/pipes.
+ * Sets the given video mode on the given pipe.
+ *
+ * Plane A is always output to pipe A, and plane B to pipe B. The plane
+ * will not be enabled if plane_enable is FALSE, which is used for
+ * load detection, when something else will be output to the pipe other than
+ * display data.
*/
Bool
-i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
+i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
+ Bool plane_enable)
{
I830Ptr pI830 = I830PTR(pScrn);
int m1 = 0, m2 = 0, n = 0, p1 = 0, p2 = 0;
@@ -623,8 +628,10 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
temp = INREG(pipeconf_reg);
OUTREG(pipeconf_reg, temp | PIPEACONF_ENABLE);
- /* And then turn the plane on */
- OUTREG(dspcntr_reg, dspcntr);
+ if (plane_enable) {
+ /* And then turn the plane on */
+ OUTREG(dspcntr_reg, dspcntr);
+ }
pI830->pipeCurMode[pipe] = *pMode;
@@ -740,13 +747,13 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayMo
if (pI830->planeEnabled[0]) {
ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, 0, pMode),
- 0);
+ 0, TRUE);
if (!ok)
goto done;
}
if (pI830->planeEnabled[1]) {
ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, 1, pMode),
- 1);
+ 1, TRUE);
if (!ok)
goto done;
}
@@ -842,3 +849,99 @@ i830DescribeOutputConfiguration(ScrnInfo
pI830->output[i].pipe == 0 ? 'A' : 'B');
}
}
+
+/**
+ * Get a pipe with a simple mode set on it for doing load-based monitor
+ * detection.
+ *
+ * It will be up to the load-detect code to adjust the pipe as appropriate for
+ * its requirements. The pipe will be connected to no other outputs.
+ *
+ * Currently this code will only succeed if there is a pipe with no outputs
+ * configured for it. In the future, it could choose to temporarily disable
+ * some outputs to free up a pipe for its use.
+ *
+ * \return monitor number, or -1 if no pipes are available.
+ */
+int
+i830GetLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ Bool pipe_available[MAX_DISPLAY_PIPES];
+ int i;
+ /* VESA 640x480x72Hz mode to set on the pipe */
+ DisplayModeRec mode = {
+ NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
+ 31500,
+ 640, 664, 704, 832, 0,
+ 480, 489, 491, 520, 0,
+ V_NHSYNC | V_NVSYNC,
+ 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
+ };
+
+ /* If the output is not marked disabled, check if it's already assigned
+ * to an active pipe, and is alone on that pipe. If so, we're done.
+ */
+ if (!output->disabled) {
+ int pipeconf_reg = (output->pipe == 0) ? PIPEACONF : PIPEBCONF;
+
+ if (INREG(pipeconf_reg) & PIPEACONF_ENABLE) {
+ /* Actually, maybe we don't need to be all alone on the pipe.
+ * The worst that should happen is false positives. Need to test,
+ * but actually fixing this during server startup is messy.
+ */
+#if 0
+ for (i = 0; i < pI830->num_outputs; i++) {
+ if (&pI830->output[i] != output &&
+ pI830->output[i].pipe == output->pipe)
+ {
+ return -1;
+ }
+ }
+#endif
+ return output->pipe;
+ }
+ }
+
+ for (i = 0; i < pI830->availablePipes; i++) {
+ pipe_available[i] = TRUE;
+ }
+
+ for (i = 0; i < pI830->num_outputs; i++) {
+ if (!pI830->output[i].disabled)
+ {
+ pipe_available[pI830->output[i].pipe] = FALSE;
+ }
+ }
+
+ for (i = 0; i < pI830->availablePipes; i++) {
+ if (pipe_available[i])
+ break;
+ }
+
+ if (i == pI830->availablePipes) {
+ return -1;
+ }
+ output->load_detect_temp = TRUE;
+ output->pipe = i;
+ output->disabled = FALSE;
+
+ I830xf86SetModeCrtc(&mode, INTERLACE_HALVE_V);
+
+ i830PipeSetMode(pScrn, &mode, i, FALSE);
+
+ return i;
+}
+
+void
+i830ReleaseLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+ if (output->load_detect_temp) {
+ output->disabled = TRUE;
+ i830DisableUnusedFunctions(pScrn);
+ output->load_detect_temp = FALSE;
+ }
+}
diff --git a/src/i830_display.h b/src/i830_display.h
index 8a6e9e9..5c0f133 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -26,9 +26,12 @@
*/
/* i830_display.c */
-Bool i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe);
+Bool i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
+ Bool plane_enable);
void i830DisableUnusedFunctions(ScrnInfoPtr pScrn);
Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
void i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y);
void i830WaitForVblank(ScrnInfoPtr pScrn);
void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
+int i830GetLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output);
+void i830ReleaseLoadDetectPipe(ScrnInfoPtr pScrn, I830OutputPtr output);
diff --git a/src/i830_randr.c b/src/i830_randr.c
index e4ae9d0..5b02a53 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -563,7 +563,7 @@ I830RandRCrtcSet (ScreenPtr pScreen,
pI830->planeEnabled[pipe] = mode != NULL;
if (display_mode)
{
- if (!i830PipeSetMode (pScrn, display_mode, pipe))
+ if (!i830PipeSetMode (pScrn, display_mode, pipe, TRUE))
return FALSE;
/* XXX need I830SDVOPostSetMode here */
}
diff-tree e416b426d83de031441ada7a77b6bd66cec8b5c9 (from 282a9e073ea985cbf0d0f3f296d593af1426bad5)
Author: Eric Anholt <eric at anholt.net>
Date: Fri Nov 3 15:25:41 2006 -0800
Print out modelines as info, not error (which had been used for debugging).
diff --git a/src/i830_xf86Modes.c b/src/i830_xf86Modes.c
index 166f41a..ca92e4d 100644
--- a/src/i830_xf86Modes.c
+++ b/src/i830_xf86Modes.c
@@ -317,7 +317,7 @@ PrintModeline(int scrnIndex,DisplayModeP
#if 0
if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2");
#endif
- xf86DrvMsg(scrnIndex, X_ERROR,
+ xf86DrvMsg(scrnIndex, X_INFO,
"Modeline \"%s\"x%.01f %6.2f %i %i %i %i %i %i %i %i%s "
"(%.01f kHz)\n",
mode->name, mode->VRefresh, mode->Clock/1000., mode->HDisplay,
diff-tree 282a9e073ea985cbf0d0f3f296d593af1426bad5 (from 0510671a6c5233468ac20f0ec8096e084df03ce6)
Author: Eric Anholt <eric at anholt.net>
Date: Fri Nov 3 13:46:09 2006 -0800
Don't memset the modes pointer on init, which was dereferencing NULL.
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 59ebcc0..e4ae9d0 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -874,7 +874,6 @@ I830RandRInit12 (ScreenPtr pScreen)
rp->rrCrtcSet = I830RandRCrtcSet;
rp->rrCrtcSetGamma = I830RandRCrtcSetGamma;
rp->rrSetConfig = NULL;
- memset (rp->modes, '\0', sizeof (rp->modes));
pScrn->PointerMoved = I830RandRPointerMoved;
return TRUE;
}
diff-tree 0510671a6c5233468ac20f0ec8096e084df03ce6 (from ffbd6ca09bc2300bf967d7c248a559d85b8706e0)
Author: Eric Anholt <eric at anholt.net>
Date: Fri Nov 3 10:58:23 2006 -0800
Fix a pasteo in I965 register restore.
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 3612af7..d996bcd 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2404,8 +2404,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
}
if (IS_I965G(pI830)) {
- OUTREG(DSPASURF, pI830->saveDSPABASE);
- OUTREG(DSPBSURF, pI830->saveDSPBBASE);
+ OUTREG(DSPASURF, pI830->saveDSPASURF);
+ OUTREG(DSPBSURF, pI830->saveDSPBSURF);
}
OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0);
More information about the xorg-commit
mailing list