diff --git a/src/i830_display.c b/src/i830_display.c index aa02a42a..78a44efd 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -225,8 +225,8 @@ i830WaitForVblank(ScrnInfoPtr pScreen) * 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. */ -void -i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) +static Bool +i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) { I830Ptr pI830 = I830PTR(pScrn); int m1, m2, n, p1, p2; @@ -239,8 +239,11 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) ErrorF("Requested pix clock: %d\n", pMode->Clock); ok = i830FindBestPLL(pScrn, pMode->Clock, refclk, &m1, &m2, &n, &p1, &p2); - if (!ok) - FatalError("Couldn't find PLL settings for mode!\n"); + if (!ok) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't find PLL settings for mode!\n"); + return FALSE; + } dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS; dpll |= DPLLB_MODE_DAC_SERIAL; /* XXX: LVDS */ @@ -377,6 +380,76 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) /* And then turn the plane on */ OUTREG(DSPBCNTR, dspcntr); } + + return TRUE; +} + +/** + * This function sets the given mode on the active pipes. + */ +Bool +i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) +{ + I830Ptr pI830 = I830PTR(pScrn); + Bool ok = TRUE; + CARD32 planeA, planeB; +#ifdef XF86DRI + Bool didLock = FALSE; +#endif + + DPRINTF(PFX, "i830SetMode\n"); + +#ifdef XF86DRI + 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; + } + + if (pI830->planeEnabled[0]) { + ok = i830PipeSetMode(pScrn, pMode, 0); + if (!ok) + goto done; + } + if (pI830->planeEnabled[1]) { + ok = i830PipeSetMode(pScrn, pMode, 1); + if (!ok) + goto done; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n", + (int)(pMode->HDisplay * pMode->VDisplay * + pMode->VRefresh / 1000000)); + + planeA = INREG(DSPACNTR); + planeB = INREG(DSPBCNTR); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Display plane A is now %s and connected to %s.\n", + pI830->planeEnabled[0] ? "enabled" : "disabled", + planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); + if (pI830->availablePipes == 2) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Display plane B is now %s and connected to %s.\n", + pI830->planeEnabled[1] ? "enabled" : "disabled", + planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); + +done: +#ifdef XF86DRI + if (didLock) + I830DRIUnlock(pScrn); +#endif + + return ok; } Bool diff --git a/src/i830_display.h b/src/i830_display.h index 66811ae0..823e27c8 100644 --- a/src/i830_display.h +++ b/src/i830_display.h @@ -1,3 +1,3 @@ -void i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe); +Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode); Bool i830DetectCRT(ScreenPtr pScrn); void i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on); diff --git a/src/i830_driver.c b/src/i830_driver.c index 2dd545e0..1e556562 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -4096,350 +4096,6 @@ I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode, VbeCRTCInfoBlock * block) } #endif -static Bool -I830VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) -{ - I830Ptr pI830 = I830PTR(pScrn); -#if 0 - vbeInfoPtr pVbe = pI830->pVbe; -#endif - VbeModeInfoData *data = (VbeModeInfoData *) pMode->Private; - int mode, i; - CARD32 planeA, planeB, temp; - int refresh = 60; -#ifdef XF86DRI - Bool didLock = FALSE; -#endif - - DPRINTF(PFX, "I830VESASetMode\n"); - - /* Always Enable Linear Addressing */ - mode = data->mode | (1 << 15) | (1 << 14); - -#ifdef XF86DRI - didLock = I830DRILock(pScrn); -#endif - - if (pI830->Clone) { - pI830->CloneHDisplay = pMode->HDisplay; - pI830->CloneVDisplay = pMode->VDisplay; - } - -#ifndef MODESWITCH_RESET_STATE -#define MODESWITCH_RESET_STATE 0 -#endif -#if MODESWITCH_RESET_STATE - ResetState(pScrn, TRUE); -#endif - - SetPipeAccess(pScrn); - -#if 0 - if (I830VESASetVBEMode(pScrn, mode, data->block) == FALSE) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n"); - return FALSE; - } - - /* - * The BIOS may not set a scanline pitch that would require more video - * memory than it's aware of. We check for this later, and set it - * explicitly if necessary. - */ - if (data->data->XResolution != pI830->displayWidth) { - if (pI830->Clone) { - SetBIOSPipe(pScrn, !pI830->pipe); - VBESetLogicalScanline(pVbe, pI830->displayWidth); - } - SetPipeAccess(pScrn); - VBESetLogicalScanline(pVbe, pI830->displayWidth); - } - - if (pScrn->bitsPerPixel >= 8 && pI830->vbeInfo->Capabilities[0] & 0x01) { - if (pI830->Clone) { - SetBIOSPipe(pScrn, !pI830->pipe); - VBESetGetDACPaletteFormat(pVbe, 8); - } - SetPipeAccess(pScrn); - VBESetGetDACPaletteFormat(pVbe, 8); - } -#endif - - /* XXX Fix plane A with pipe A, and plane B with pipe B. */ - planeA = INREG(DSPACNTR); - planeB = INREG(DSPBCNTR); - - pI830->planeEnabled[0] = ((planeA & DISPLAY_PLANE_ENABLE) != 0); - pI830->planeEnabled[1] = ((planeB & DISPLAY_PLANE_ENABLE) != 0); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane A is %s and connected to %s.\n", - pI830->planeEnabled[0] ? "enabled" : "disabled", - planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); - if (pI830->availablePipes == 2) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane B is %s and connected to %s.\n", - pI830->planeEnabled[1] ? "enabled" : "disabled", - planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); - - 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; - } - - if (pI830->planeEnabled[0]) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane A.\n"); - planeA |= DISPLAY_PLANE_ENABLE; - planeA &= ~DISPPLANE_SEL_PIPE_MASK; - planeA |= DISPPLANE_SEL_PIPE_A; - OUTREG(DSPACNTR, planeA); - /* flush the change. */ - temp = INREG(DSPABASE); - OUTREG(DSPABASE, temp); - } - if (pI830->planeEnabled[1]) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling plane B.\n"); - planeB |= DISPLAY_PLANE_ENABLE; - planeB &= ~DISPPLANE_SEL_PIPE_MASK; - planeB |= DISPPLANE_SEL_PIPE_B; - OUTREG(DSPBCNTR, planeB); - /* flush the change. */ - temp = INREG(DSPBADDR); - OUTREG(DSPBADDR, temp); - } - - planeA = INREG(DSPACNTR); - planeB = INREG(DSPBCNTR); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane A is now %s and connected to %s.\n", - pI830->planeEnabled[0] ? "enabled" : "disabled", - planeA & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); - if (pI830->availablePipes == 2) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Display plane B is now %s and connected to %s.\n", - pI830->planeEnabled[1] ? "enabled" : "disabled", - planeB & DISPPLANE_SEL_PIPE_MASK ? "Pipe B" : "Pipe A"); - - /* XXX Plane C is ignored for now (overlay). */ - - /* - * Print out the PIPEACONF and PIPEBCONF registers. - */ - temp = INREG(PIPEACONF); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n", temp); - if (pI830->availablePipes == 2) { - temp = INREG(PIPEBCONF); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n", temp); - } - - if (xf86IsEntityShared(pScrn->entityList[0])) { - /* Clean this up !! */ - if (I830IsPrimary(pScrn)) { - CARD32 stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE; - CARD32 basereg = !pI830->pipe ? DSPABASE : DSPBBASE; - CARD32 sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE; - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - - temp = INREG(stridereg); - if (temp / pI8301->cpp != (CARD32)(pI830->displayWidth)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe), - (int)(temp / pI8301->cpp), pI830->displayWidth); - OUTREG(stridereg, pI830->displayWidth * pI8301->cpp); - } - OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); - stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE; - basereg = pI830->pipe ? DSPABASE : DSPBBASE; - sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE; - - temp = INREG(stridereg); - if (temp / pI8302->cpp != (CARD32)(pI8302->displayWidth)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe), - (int)(temp / pI8302->cpp), pI8302->displayWidth); - OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp); - } - OUTREG(sizereg, (pI830->entityPrivate->pScrn_2->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_2->currentMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - } - } else { - CARD32 stridereg = pI830->pipe ? DSPASTRIDE : DSPBSTRIDE; - CARD32 basereg = pI830->pipe ? DSPABASE : DSPBBASE; - CARD32 sizereg = pI830->pipe ? DSPASIZE : DSPBSIZE; - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - I830Ptr pI8302 = I830PTR(pI830->entityPrivate->pScrn_2); - - temp = INREG(stridereg); - if (temp / pI8301->cpp != (CARD32)(pI8301->displayWidth)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(pI830->pipe), - (int)(temp / pI8301->cpp), pI8301->displayWidth); - OUTREG(stridereg, pI8301->displayWidth * pI8301->cpp); - } - OUTREG(sizereg, (pI830->entityPrivate->pScrn_1->currentMode->HDisplay - 1) | ((pI830->entityPrivate->pScrn_1->currentMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - - stridereg = !pI830->pipe ? DSPASTRIDE : DSPBSTRIDE; - basereg = !pI830->pipe ? DSPABASE : DSPBBASE; - sizereg = !pI830->pipe ? DSPASIZE : DSPBSIZE; - - temp = INREG(stridereg); - if (temp / pI8302->cpp != ((CARD32)pI8302->displayWidth)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(!pI830->pipe), - (int)(temp / pI8302->cpp), pI8302->displayWidth); - OUTREG(stridereg, pI8302->displayWidth * pI8302->cpp); - } - OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - } - } else { - for (i = 0; i < pI830->availablePipes; i++) { - CARD32 stridereg = i ? DSPBSTRIDE : DSPASTRIDE; - CARD32 basereg = i ? DSPBBASE : DSPABASE; - CARD32 sizereg = i ? DSPBSIZE : DSPASIZE; - - if (!pI830->planeEnabled[i]) - continue; - - temp = INREG(stridereg); - if (temp / pI830->cpp != (CARD32)pI830->displayWidth) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Correcting plane %c stride (%d -> %d)\n", PIPE_NAME(i), - (int)(temp / pI830->cpp), pI830->displayWidth); - OUTREG(stridereg, pI830->displayWidth * pI830->cpp); - } - OUTREG(sizereg, (pMode->HDisplay - 1) | ((pMode->VDisplay - 1) << 16)); - /* Trigger update */ - temp = INREG(basereg); - OUTREG(basereg, temp); - } - } - -#if 0 - /* Print out some CRTC/display information. */ - temp = INREG(HTOTAL_A); - ErrorF("Horiz active: %d, Horiz total: %d\n", temp & 0x7ff, - (temp >> 16) & 0xfff); - temp = INREG(HBLANK_A); - ErrorF("Horiz blank start: %d, Horiz blank end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(HSYNC_A); - ErrorF("Horiz sync start: %d, Horiz sync end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(VTOTAL_A); - ErrorF("Vert active: %d, Vert total: %d\n", temp & 0x7ff, - (temp >> 16) & 0xfff); - temp = INREG(VBLANK_A); - ErrorF("Vert blank start: %d, Vert blank end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(VSYNC_A); - ErrorF("Vert sync start: %d, Vert sync end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(PIPEASRC); - ErrorF("Image size: %dx%d (%dx%d)\n", - (temp >> 16) & 0x7ff, temp & 0x7ff, - (((temp >> 16) & 0x7ff) + 1), ((temp & 0x7ff) + 1)); - ErrorF("Pixel multiply is %d\n", (planeA >> 20) & 0x3); - temp = INREG(DSPABASE); - ErrorF("Plane A start offset is %d\n", temp); - temp = INREG(DSPASTRIDE); - ErrorF("Plane A stride is %d bytes (%d pixels)\n", temp, temp / pI830->cpp); - temp = INREG(DSPAPOS); - ErrorF("Plane A position %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16); - temp = INREG(DSPASIZE); - ErrorF("Plane A size %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16); - - /* Print out some CRTC/display information. */ - temp = INREG(HTOTAL_B); - ErrorF("Horiz active: %d, Horiz total: %d\n", temp & 0x7ff, - (temp >> 16) & 0xfff); - temp = INREG(HBLANK_B); - ErrorF("Horiz blank start: %d, Horiz blank end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(HSYNC_B); - ErrorF("Horiz sync start: %d, Horiz sync end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(VTOTAL_B); - ErrorF("Vert active: %d, Vert total: %d\n", temp & 0x7ff, - (temp >> 16) & 0xfff); - temp = INREG(VBLANK_B); - ErrorF("Vert blank start: %d, Vert blank end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(VSYNC_B); - ErrorF("Vert sync start: %d, Vert sync end: %d\n", temp & 0xfff, - (temp >> 16) & 0xfff); - temp = INREG(PIPEBSRC); - ErrorF("Image size: %dx%d (%dx%d)\n", - (temp >> 16) & 0x7ff, temp & 0x7ff, - (((temp >> 16) & 0x7ff) + 1), ((temp & 0x7ff) + 1)); - ErrorF("Pixel multiply is %d\n", (planeA >> 20) & 0x3); - temp = INREG(DSPBBASE); - ErrorF("Plane B start offset is %d\n", temp); - temp = INREG(DSPBSTRIDE); - ErrorF("Plane B stride is %d bytes (%d pixels)\n", temp, temp / pI830->cpp); - temp = INREG(DSPBPOS); - ErrorF("Plane B position %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16); - temp = INREG(DSPBSIZE); - ErrorF("Plane B size %d %d\n", temp & 0xffff, (temp & 0xffff0000) >> 16); -#endif - - i830SetMode(pScrn, pMode, pI830->pipe); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n", - pMode->HDisplay * pMode->VDisplay * refresh / 1000000); - - { - int maxBandwidth, bandwidthA, bandwidthB; - - if (GetModeSupport(pScrn, 0x80, 0x80, 0x80, 0x80, - &maxBandwidth, &bandwidthA, &bandwidthB)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "maxBandwidth is %d Mbyte/s, " - "pipe bandwidths are %d Mbyte/s, %d Mbyte/s\n", - maxBandwidth, bandwidthA, bandwidthB); - } - } - -#if 0 - { - int ret; - - ret = GetLFPCompMode(pScrn); - if (ret != -1) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "LFP compensation mode: 0x%x\n", ret); - } - } -#endif - -#if MODESWITCH_RESET_STATE - ResetState(pScrn, TRUE); - SetHWOperatingState(pScrn); -#endif - -#ifdef XF86DRI - if (didLock) - I830DRIUnlock(pScrn); -#endif - - pScrn->vtSema = TRUE; - return TRUE; -} - static void InitRegisterRec(ScrnInfoPtr pScrn) { @@ -5616,7 +5272,7 @@ I830BIOSEnterVT(int scrnIndex, int flags) if (!pI830->starting) I830DetectMonitorChange(pScrn); - if (!I830VESASetMode(pScrn, pScrn->currentMode)) + if (!I830SetMode(pScrn, pScrn->currentMode)) return FALSE; #ifdef I830_XV @@ -5686,7 +5342,7 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) * are rotating, we don't need to call the mode setup again. */ if (pI830->currentMode != mode) { - if (!I830VESASetMode(pScrn, mode)) + if (!I830SetMode(pScrn, mode)) ret = FALSE; } @@ -5707,7 +5363,7 @@ I830BIOSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) * video mode here, as we'll have already re-instated the original rotation. */ if (!ret) { - if (!I830VESASetMode(pScrn, pI830->currentMode)) { + if (!I830SetMode(pScrn, pI830->currentMode)) { xf86DrvMsg(scrnIndex, X_INFO, "Failed to restore previous mode (SwitchMode)\n"); }