diff options
-rw-r--r-- | src/i830.h | 3 | ||||
-rw-r--r-- | src/i830_display.c | 6 | ||||
-rw-r--r-- | src/i830_driver.c | 43 | ||||
-rw-r--r-- | src/i830_video.c | 138 |
4 files changed, 72 insertions, 118 deletions
@@ -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; } } |