Replace I830VESASetMode with simpler i830SetMode, which is all native and

doesn't have BIOS-setup workarounds.  Multihead behavior may be wrong, and it is
all untested.
This commit is contained in:
Eric Anholt 2006-03-02 09:05:13 -08:00 committed by Eric Anholt
parent 7edb25789b
commit a09d9cf27a
3 changed files with 81 additions and 352 deletions

View File

@ -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

View File

@ -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);

View File

@ -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");
}