summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i830.h3
-rw-r--r--src/i830_display.c6
-rw-r--r--src/i830_driver.c43
-rw-r--r--src/i830_video.c138
4 files changed, 72 insertions, 118 deletions
diff --git a/src/i830.h b/src/i830.h
index 9809f352..64a32dc3 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -517,8 +517,7 @@ extern Bool I830DGAInit(ScreenPtr pScreen);
#ifdef I830_XV
extern void I830InitVideo(ScreenPtr pScreen);
-extern void I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode);
-extern void I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode);
+extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on);
#endif
extern Bool I830AllocateRotatedBuffer(ScrnInfoPtr pScrn, const int flags);
diff --git a/src/i830_display.c b/src/i830_display.c
index b2d9e351..f05b5c73 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -511,8 +511,14 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
/* Enable the plane */
temp = INREG(dspcntr_reg);
OUTREG(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
+
+ /* Give the overlay scaler a chance to enable if it's on this pipe */
+ i830_crtc_dpms_video(crtc, TRUE);
break;
case DPMSModeOff:
+ /* Give the overlay scaler a chance to disable if it's on this pipe */
+ i830_crtc_dpms_video(crtc, FALSE);
+
/* Disable display plane */
temp = INREG(dspcntr_reg);
OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 19f94260..46973e77 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2244,7 +2244,6 @@ RestoreHWState(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
vgaHWPtr hwp = VGAHWPTR(pScrn);
vgaRegPtr vgaReg = &hwp->SavedReg;
- CARD32 temp;
int i;
DPRINTF(PFX, "RestoreHWState\n");
@@ -2259,19 +2258,11 @@ RestoreHWState(ScrnInfoPtr pScrn)
output->funcs->dpms(output, DPMSModeOff);
}
- /* Disable display planes */
- temp = INREG(DSPACNTR);
- OUTREG(DSPACNTR, temp & ~DISPLAY_PLANE_ENABLE);
- temp = INREG(DSPBCNTR);
- OUTREG(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
-
- /* Next, disable display pipes */
- temp = INREG(PIPEACONF);
- OUTREG(PIPEACONF, temp & ~PIPEACONF_ENABLE);
- temp = INREG(PIPEBCONF);
- OUTREG(PIPEBCONF, temp & ~PIPEBCONF_ENABLE);
-
- i830WaitForVblank(pScrn);
+ /* Disable pipes */
+ for (i = 0; i < pI830->xf86_config.num_crtc; i++) {
+ xf86CrtcPtr crtc = pI830->xf86_config.crtc[i];
+ crtc->funcs->dpms(crtc, DPMSModeOff);
+ }
OUTREG(FPA0, pI830->saveFPA0);
OUTREG(FPA1, pI830->saveFPA1);
@@ -3214,11 +3205,6 @@ I830LeaveVT(int scrnIndex, int flags)
i830SetHotkeyControl(pScrn, HOTKEY_BIOS_SWITCH);
-#ifdef I830_XV
- /* Give the video overlay code a chance to shutdown. */
- I830VideoSwitchModeBefore(pScrn, NULL);
-#endif
-
if (!I830IsPrimary(pScrn)) {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
if (!pI8301->GttBound) {
@@ -3319,10 +3305,6 @@ I830EnterVT(int scrnIndex, int flags)
#ifdef XF86DRI
I830DRISetVBlankInterrupt (pScrn, TRUE);
#endif
-
-#ifdef I830_XV
- I830VideoSwitchModeAfter(pScrn, pScrn->currentMode);
-#endif
ResetState(pScrn, TRUE);
SetHWOperatingState(pScrn);
@@ -3396,11 +3378,6 @@ I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
DPRINTF(PFX, "I830SwitchMode: mode == %p\n", mode);
-#ifdef I830_XV
- /* Give the video overlay code a chance to see the new mode. */
- I830VideoSwitchModeBefore(pScrn, mode);
-#endif
-
/* Sync the engine before mode switch */
i830WaitSync(pScrn);
@@ -3434,18 +3411,8 @@ I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
xf86DrvMsg(scrnIndex, X_INFO,
"Failed to restore previous mode (SwitchMode)\n");
}
-
-#ifdef I830_XV
- /* Give the video overlay code a chance to see the new mode. */
- I830VideoSwitchModeAfter(pScrn, pI830->currentMode);
-#endif
} else {
pI830->currentMode = mode;
-
-#ifdef I830_XV
- /* Give the video overlay code a chance to see the new mode. */
- I830VideoSwitchModeAfter(pScrn, mode);
-#endif
}
return ret;
diff --git a/src/i830_video.c b/src/i830_video.c
index 3aad1aa5..986d36a1 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -738,10 +738,10 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen)
/*
* Initialise pPriv->overlayOK. Set it to TRUE here so that a warning will
- * be generated if I830VideoSwitchModeAfter() sets it to FALSE.
+ * be generated if i830_crtc_dpms_video() sets it to FALSE during mode
+ * setup.
*/
pPriv->overlayOK = TRUE;
- I830VideoSwitchModeAfter(pScrn, pScrn->currentMode);
pI830->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = I830BlockHandler;
@@ -3511,95 +3511,77 @@ I830InitOffscreenImages(ScreenPtr pScreen)
}
void
-I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode)
+i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- if (!pI830->adaptor) {
+ if (pI830->adaptor == NULL)
return;
- }
-
- pPriv = GET_PORT_PRIVATE(pScrn);
- if (!pPriv) {
- xf86ErrorF("pPriv isn't set\n");
+ /* No overlay scaler on the 965. */
+ if (IS_I965G(pI830))
return;
- }
-
- /* We stop the video when mode switching, just so we don't lockup
- * the engine. The overlayOK will determine whether we can re-enable
- * with the current video on completion of the mode switch.
- */
- I830StopVideo(pScrn, pPriv, TRUE);
-
- pPriv->overlayOK = FALSE;
-
- pPriv->oneLineMode = FALSE;
-}
-void
-I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- I830PortPrivPtr pPriv;
- int size, hsize, vsize, active;
-
- if (!pI830->adaptor) {
- return;
- }
pPriv = GET_PORT_PRIVATE(pScrn);
- if (!pPriv)
- return;
-
- pPriv->overlayOK = TRUE;
- if (!IS_I965G(pI830)) {
- if (pPriv->pipe == 0) {
- if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Disabling XVideo output because Pipe A is in double-wide mode.\n");
- pPriv->overlayOK = FALSE;
- } else if (!pPriv->overlayOK) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Re-enabling XVideo output because Pipe A is now in single-wide mode.\n");
- pPriv->overlayOK = TRUE;
- }
- }
+ /* Check if it's the pipe the overlay is on */
+ if (intel_crtc->pipe != pPriv->pipe)
+ return;
- if (pPriv->pipe == 1) {
- if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Disabling XVideo output because Pipe B is in double-wide mode.\n");
- pPriv->overlayOK = FALSE;
- } else if (!pPriv->overlayOK) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Re-enabling XVideo output because Pipe B is now in single-wide mode.\n");
- pPriv->overlayOK = TRUE;
- }
+ if (on) {
+ int size, hsize, vsize, active;
+ int pipeconf_reg = pPriv->pipe == 0 ? PIPEACONF : PIPEBCONF;
+ char pipename = pPriv->pipe == 0 ? 'A' : 'B';
+
+ pPriv->overlayOK = TRUE;
+
+ if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling XVideo output because Pipe %c is in "
+ "double-wide mode.\n", pipename);
+ pPriv->overlayOK = FALSE;
+ } else if (!pPriv->overlayOK) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Re-enabling XVideo output because Pipe %c is now in "
+ "single-wide mode.\n", pipename);
+ pPriv->overlayOK = TRUE;
}
- }
- /* Check we have an LFP connected */
- if (i830PipeHasType (pI830->xf86_config.crtc[pPriv->pipe], I830_OUTPUT_LVDS))
- {
- size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
- hsize = (size >> 16) & 0x7FF;
- vsize = size & 0x7FF;
- active = pPriv->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
-
- if (vsize < active && hsize > 1024)
- I830SetOneLineModeRatio(pScrn);
-
- if (pPriv->scaleRatio & 0xFFFE0000) {
- /* Possible bogus ratio, using in-accurate fallback */
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Bogus panel fit register, Xvideo positioning may not be accurate.\n");
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Using fallback ratio - was 0x%x, now 0x%x\n", pPriv->scaleRatio, (int)(((float)active * 65536)/(float)vsize));
-
-
- pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
+ /* Check we have an LFP connected */
+ if (i830PipeHasType(pI830->xf86_config.crtc[pPriv->pipe],
+ I830_OUTPUT_LVDS)) {
+ size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
+ hsize = (size >> 16) & 0x7FF;
+ vsize = size & 0x7FF;
+ int vtotal_reg = pPriv->pipe ? VTOTAL_A : VTOTAL_B;
+ active = INREG(vtotal_reg) & 0x7FF;
+
+ if (vsize < active && hsize > 1024)
+ I830SetOneLineModeRatio(pScrn);
+
+ if (pPriv->scaleRatio & 0xFFFE0000) {
+ /* Possible bogus ratio, using in-accurate fallback */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Bogus panel fit register, Xvideo positioning may not "
+ "be accurate.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Using fallback ratio - was 0x%x, now 0x%x\n",
+ pPriv->scaleRatio,
+ (int)(((float)active * 65536)/(float)vsize));
+
+ pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
+ }
}
+ } else {
+ /* We stop the video when mode switching, so we don't lock up
+ * the engine. The overlayOK will determine whether we can re-enable
+ * with the current video on completion of the mode switch.
+ */
+ I830StopVideo(pScrn, pPriv, TRUE);
+ pPriv->overlayOK = FALSE;
+ pPriv->oneLineMode = FALSE;
}
}