? Makefile ? diff.txt ? douview.diff ? duoview.diff Index: savage_accel.c =================================================================== RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v retrieving revision 1.11.4.7 diff -u -r1.11.4.7 savage_accel.c --- savage_accel.c 20 Feb 2004 18:16:02 -0000 1.11.4.7 +++ savage_accel.c 26 Feb 2004 20:33:06 -0000 @@ -651,19 +651,19 @@ * = 0 standard VGA address and stride registers * are used t control the primary streams */ + OUTREG8(CRT_ADDRESS_REG,0x67); byte = INREG8(CRT_DATA_REG) | 0x08; OUTREG8(CRT_DATA_REG,byte); - - /* IGA 2 */ - OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES); + if (psav->IsSecondary) { + /* IGA 2 */ + SelectIGA2(); OUTREG8(CRT_ADDRESS_REG,0x67); byte = INREG8(CRT_DATA_REG) | 0x08; OUTREG8(CRT_DATA_REG,byte); - - OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1); - + SelectIGA1(); + } /* Set primary stream to bank 0 */ OUTREG8(CRT_ADDRESS_REG, MEMORY_CTRL0_REG);/* CRCA */ byte = INREG8(CRT_DATA_REG) & ~(MEM_PS1 + MEM_PS2) ; @@ -680,10 +680,11 @@ } /* MM81C0 and 81C4 are used to control primary stream. */ - OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000); - OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000); - OUTREG32(PRI_STREAM2_FBUF_ADDR0,0x00000000); - OUTREG32(PRI_STREAM2_FBUF_ADDR1,0x00000000); + OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset); + OUTREG32(PRI_STREAM_FBUF_ADDR1,pScrn->fbOffset); + OUTREG32(PRI_STREAM2_FBUF_ADDR0,pScrn->fbOffset); + OUTREG32(PRI_STREAM2_FBUF_ADDR1,pScrn->fbOffset); + /* * Program Primary Stream Stride Register. @@ -789,7 +790,7 @@ /* HW uses width */ psav->GlobalBD.bd1.HighPart.Stride = (ushort)(psav->lDelta / (pScrn->bitsPerPixel >> 3)); psav->GlobalBD.bd1.HighPart.Bpp = (uchar) (pScrn->bitsPerPixel); - psav->GlobalBD.bd1.Offset = 0; + psav->GlobalBD.bd1.Offset = pScrn->fbOffset; /* was 0 */ /* @@ -801,6 +802,7 @@ byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000)); OUTREG8(CRT_DATA_REG,byte); + /* program the GBD and SBD's */ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart ); /* 8: bci enable */ @@ -851,13 +853,13 @@ OUTREG8(CRT_DATA_REG,byte); /* IGA 2 */ - OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES); + SelectIGA2(); OUTREG8(CRT_ADDRESS_REG,0x67); byte = INREG8(CRT_DATA_REG) | 0x08; OUTREG8(CRT_DATA_REG,byte); - OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1); + SelectIGA1(); /* * load ps1 active registers as determined by MM81C0/81C4 Index: savage_cursor.c =================================================================== RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c,v retrieving revision 1.1.1.6.14.2 diff -u -r1.1.1.6.14.2 savage_cursor.c --- savage_cursor.c 9 Feb 2004 14:17:15 -0000 1.1.1.6.14.2 +++ savage_cursor.c 26 Feb 2004 20:33:07 -0000 @@ -95,7 +95,11 @@ void SavageShowCursor(ScrnInfoPtr pScrn) { + SavagePtr psav = SAVPTR(pScrn); /* Turn cursor on. */ + if (psav->IsSecondary) + outCRReg( 0x45, inCRReg(0x45) | 0x08 ); + else outCRReg( 0x45, inCRReg(0x45) | 0x01 ); } @@ -103,12 +107,16 @@ void SavageHideCursor(ScrnInfoPtr pScrn) { + SavagePtr psav = SAVPTR(pScrn); /* Turn cursor off. */ if( S3_SAVAGE4_SERIES( SAVPTR(pScrn)->Chipset ) ) { waitHSync(5); } + if (psav->IsSecondary) + outCRReg( 0x45, inCRReg(0x45) & 0xfb ); + else outCRReg( 0x45, inCRReg(0x45) & 0xfe ); } @@ -118,11 +126,13 @@ unsigned char* src) { SavagePtr psav = SAVPTR(pScrn); - + if (psav->IsSecondary) + SelectIGA2(); /* Set cursor location in frame buffer. */ outCRReg( 0x4d, (0xff & psav->CursorKByte)); outCRReg( 0x4c, (0xff00 & psav->CursorKByte) >> 8); - + if (psav->IsSecondary) + SelectIGA1(); /* Upload the cursor image to the frame buffer. */ memcpy(psav->FBBase + psav->CursorKByte * 1024, src, 1024); @@ -143,8 +153,9 @@ int y) { unsigned char xoff, yoff; + SavagePtr psav = SAVPTR(pScrn); - if( S3_SAVAGE4_SERIES( SAVPTR(pScrn)->Chipset ) ) + if( S3_SAVAGE4_SERIES( psav->Chipset ) ) { waitHSync(5); } @@ -176,7 +187,8 @@ } else { yoff = 0; } - + if (psav->IsSecondary) + SelectIGA2(); /* This is the recomended order to move the cursor */ outCRReg( 0x46, (x & 0xff00)>>8 ); outCRReg( 0x47, (x & 0xff) ); @@ -184,6 +196,8 @@ outCRReg( 0x4e, xoff ); outCRReg( 0x4f, yoff ); outCRReg( 0x48, (y & 0xff00)>>8 ); + if (psav->IsSecondary) + SelectIGA1(); } @@ -196,6 +210,9 @@ SavagePtr psav = SAVPTR(pScrn); Bool bNeedExtra = FALSE; + if (psav->IsSecondary) + SelectIGA2(); + /* Clock doubled modes need an extra cursor stack write. */ bNeedExtra = @@ -272,4 +289,6 @@ outCRReg(0x4b, bg); outCRReg(0x4b, bg); } + if (psav->IsSecondary) + SelectIGA1(); } Index: savage_driver.c =================================================================== RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v retrieving revision 1.11.4.15 diff -u -r1.11.4.15 savage_driver.c --- savage_driver.c 21 Feb 2004 15:28:45 -0000 1.11.4.15 +++ savage_driver.c 26 Feb 2004 20:33:08 -0000 @@ -48,7 +48,9 @@ static Bool SavageEnterVT(int scrnIndex, int flags); static void SavageLeaveVT(int scrnIndex, int flags); static void SavageSave(ScrnInfoPtr pScrn); +static void SavageSaveCRTC2(ScrnInfoPtr pScrn); static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr, SavageRegPtr, Bool); +static void SavageWriteModeCRTC2(ScrnInfoPtr pScrn, vgaRegPtr, SavageRegPtr, Bool); static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv); @@ -61,6 +63,7 @@ static Bool SavageMapFB(ScrnInfoPtr pScrn); static void SavageUnmapMem(ScrnInfoPtr pScrn, int All); static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static Bool SavageModeInitCRTC2(ScrnInfoPtr pScrn, DisplayModePtr mode); static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool SavageSaveScreen(ScreenPtr pScreen, int mode); static void SavageLoadPalette(ScrnInfoPtr pScrn, int numColors, @@ -185,6 +188,17 @@ { -1, -1, RES_UNDEFINED } }; +int gSavageEntityIndex = -1; + +static SavageEntPtr SavageEntPriv(ScrnInfoPtr pScrn) +{ + DevUnion *pPriv; + SavagePtr psav = SAVPTR(pScrn); + pPriv = xf86GetEntityPrivate(psav->pEnt->index, + gSavageEntityIndex); + return pPriv->ptr; +} + typedef enum { OPTION_PCI_BURST ,OPTION_PCI_RETRY @@ -322,9 +336,9 @@ static const char *vbeSymbols[] = { "VBEInit", "vbeDoEDID", -#if 0 +/*#if 0*/ "vbeFree", -#endif +/*#endif*/ NULL }; @@ -723,8 +737,14 @@ foundScreen = TRUE; else for (i=0; idriverVersion = (int)DRIVER_VERSION; pScrn->driverName = DRIVER_NAME; pScrn->name = "SAVAGE"; @@ -738,8 +758,44 @@ pScrn->FreeScreen = NULL; pScrn->ValidMode = SavageValidMode; foundScreen = TRUE; - xf86ConfigActivePciEntity(pScrn, usedChips[i], SavagePciChipsets, - NULL, NULL, NULL, NULL, NULL); + /* xf86ConfigActivePciEntity(pScrn, usedChips[i], SavagePciChipsets, + NULL, NULL, NULL, NULL, NULL); */ + /* removal of the above lines may fix the entity error */ + } + + pEnt = xf86GetEntityInfo(usedChips[i]); + + /* MX, IX, SuperSavage cards support Dual-Head, mark the entity as sharable*/ + if(pEnt->chipset == S3_SAVAGE_MX || pEnt->chipset == S3_SUPERSAVAGE) + { + DevUnion *pPriv; + SavageEntPtr pSavageEnt; + + xf86SetEntitySharable(usedChips[i]); + + if (gSavageEntityIndex == -1) + gSavageEntityIndex = xf86AllocateEntityPrivateIndex(); + + pPriv = xf86GetEntityPrivate(pEnt->index, + gSavageEntityIndex); + + if (!pPriv->ptr) { + int j; + int instance = xf86GetNumEntityInstances(pEnt->index); + + for (j = 0; j < instance; j++) + xf86SetEntityInstanceForScreen(pScrn, pEnt->index, j); + + pPriv->ptr = xnfcalloc(sizeof(SavageEntRec), 1); + pSavageEnt = pPriv->ptr; + pSavageEnt->HasSecondary = FALSE; + pSavageEnt->IsSecondaryRestored = FALSE; + } else { + pSavageEnt = pPriv->ptr; + pSavageEnt->HasSecondary = TRUE; + } + } + xfree(pEnt); } xfree(usedChips); @@ -1054,6 +1110,7 @@ return FALSE; } + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); if (pEnt->resources) { xfree(pEnt); @@ -1062,6 +1119,7 @@ } psav->EntityIndex = pEnt->index; + if (xf86LoadSubModule(pScrn, "int10")) { xf86LoaderReqSymLists(int10Symbols, NULL); psav->pInt10 = xf86InitInt10(pEnt->index); @@ -1112,6 +1170,47 @@ xfree(pEnt); + + psav = SAVPTR(pScrn); + psav->IsSecondary = FALSE; + psav->IsSwitching = FALSE; + psav->pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]); + + if (xf86IsEntityShared(psav->pEnt->index)) { + if (xf86IsPrimInitDone(psav->pEnt->index)) { + + SavageEntPtr pSavageEnt = SavageEntPriv(pScrn); + + psav->IsSecondary = TRUE; +#if 0 + if (!pSavageEnt->HasSecondary) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Only one monitor detected, Second screen " + "will NOT be created\n"); + goto fail2; + } +#endif + pSavageEnt->pSecondaryScrn = pScrn; + } else { + SavageEntPtr pSavageEnt = SavageEntPriv(pScrn); + + xf86SetPrimInitDone(psav->pEnt->index); + + pSavageEnt->pPrimaryScrn = pScrn; + pSavageEnt->RestorePrimary = FALSE; + pSavageEnt->IsSecondaryRestored = FALSE; + } + } + + switch(psav->Chipset) { + case S3_SAVAGE_MX: + case S3_SUPERSAVAGE: + psav->HasCRTC2 = TRUE; + break; + default: + psav->HasCRTC2 = FALSE; + } + /* maybe throw in some more sanity checks here */ xf86DrvMsg(pScrn->scrnIndex, from, "Engine: \"%s\"\n", pScrn->chipset); @@ -1129,6 +1228,10 @@ vgaCRReg = psav->vgaIOBase + 5; xf86EnableIO(); + + UnLockExtRegs(); + SelectIGA1(); + /* unprotect CRTC[0-7] */ VGAOUT8(vgaCRIndex, 0x11); tmp = VGAIN8(vgaCRReg); @@ -1241,6 +1344,28 @@ psav->videoRambytes = pScrn->videoRam * 1024; } + + if(psav->IsSecondary) + { + /*FIXME: For now, split FB into two equal sections. This should + be able to be adjusted by user with a config option*/ + DevUnion* pPriv; + SavageEntPtr pSavEnt; + SavagePtr psav1; + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gSavageEntityIndex); + pSavEnt = pPriv->ptr; + pScrn->videoRam /= 2; + psav->videoRambytes = pScrn->videoRam * 1024; + pSavEnt->pPrimaryScrn->videoRam = pScrn->videoRam; + psav1 = SAVPTR(pSavEnt->pPrimaryScrn); + /* psav1->FbMapSize = pScrn->videoRam * 1024; */ + psav1->videoRambytes = pScrn->videoRam * 1024; + psav->FrameBufferBase += pScrn->videoRam * 1024; + } + + TRACE(("SavagePreInit(%d)\n", flags)); + #if 0 /* reserved 128K for HWICON and DSTN buffer */ endfb = psav->videoRambytes - 0x20000 - 1; @@ -1470,7 +1595,7 @@ /* Check LCD panel information */ if( (S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || - S3_MOBILE_TWISTER_SERIES(psav->Chipset)) && !psav->CrtOnly ) + S3_MOBILE_TWISTER_SERIES(psav->Chipset)) && !psav->CrtOnly && !psav->IsSecondary) { unsigned char cr6b = hwp->readCrtc( hwp, 0x6b ); @@ -1723,9 +1848,14 @@ TRACE(("SavageSave()\n")); - VGAOUT16(vgaCRIndex, 0x4838); - VGAOUT16(vgaCRIndex, 0xa039); - VGAOUT16(0x3c4, 0x0608); + if (psav->IsSecondary) { + SavageSaveCRTC2(pScrn); + return; + } + + UnLockExtRegs(); + + SelectIGA1(); VGAOUT8(vgaCRIndex, 0x66); cr66 = VGAIN8(vgaCRReg); @@ -1823,10 +1953,12 @@ save->CR65 = VGAIN8(vgaCRReg); /* save seq extended regs for DCLK PLL programming */ +#if 0 VGAOUT8(0x3c4, 0x0e); save->SR0E = VGAIN8(0x3c5); VGAOUT8(0x3c4, 0x0f); save->SR0F = VGAIN8(0x3c5); +#endif VGAOUT8(0x3c4, 0x10); save->SR10 = VGAIN8(0x3c5); VGAOUT8(0x3c4, 0x11); @@ -1835,13 +1967,20 @@ save->SR12 = VGAIN8(0x3c5); VGAOUT8(0x3c4, 0x13); save->SR13 = VGAIN8(0x3c5); +#if 0 VGAOUT8(0x3c4, 0x29); save->SR29 = VGAIN8(0x3c5); - + VGAOUT8(0x3c4, 0x0E); + save->SR0E = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x0F); + save->SR0F = VGAIN8(0x3c5); +#endif VGAOUT8(0x3c4, 0x15); save->SR15 = VGAIN8(0x3c5); VGAOUT8(0x3c4, 0x30); save->SR30 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x31); + save->SR31 = VGAIN8(0x3c5); VGAOUT8(0x3c4, 0x18); save->SR18 = VGAIN8(0x3c5); VGAOUT8(0x3c4, 0x1b); @@ -1878,11 +2017,99 @@ VGAOUT8(vgaCRIndex, 0x66); VGAOUT8(vgaCRReg, cr66); + /* active output reg */ + VGAOUT8(vgaCRIndex, 0x6b); + save->CR6B = VGAIN8(vgaCRReg); + + if (!psav->ModeStructInit) { + vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr); + memcpy(&psav->ModeReg, save, sizeof(SavageRegRec)); + psav->ModeStructInit = TRUE; + } + +#if 0 + if (xf86GetVerbosity() > 1) + SavagePrintRegs(pScrn); +#endif + + return; +} + +static void SavageSaveCRTC2(ScrnInfoPtr pScrn) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + vgaRegPtr vgaSavePtr = &hwp->SavedReg; + SavagePtr psav = SAVPTR(pScrn); + SavageRegPtr save = &psav->SavedReg; + unsigned short vgaCRReg = psav->vgaIOBase + 5; + unsigned short vgaCRIndex = psav->vgaIOBase + 4; + int i; + + TRACE(("SavageSaveCRTC2()\n")); + + UnLockExtRegs(); + + SelectIGA2(); + + for (i = 0; i < vgaSavePtr->numCRTC; i++) { + vgaSavePtr->CRTC[i] = hwp->readCrtc(hwp, i); + } + + /* now save all the extended regs we need */ + VGAOUT8(vgaCRIndex, 0x42); + save->CR42 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x51); + save->CR51 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x67); + save->CR67 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x69); + save->CR69 = VGAIN8(vgaCRReg); + + VGAOUT8(vgaCRIndex, 0x33); + save->CR33 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x90); + save->CR90 = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x91); + save->CR91 = VGAIN8(vgaCRReg); + + /* extended mode timing regs */ + VGAOUT8(vgaCRIndex, 0x3b); + save->CR3B = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x3c); + save->CR3C = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x5d); + save->CR5D = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x5e); + save->CR5E = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRIndex, 0x65); + save->CR65 = VGAIN8(vgaCRReg); + + /* save seq extended regs for DCLK PLL programming */ + UnLockExtRegs(); + SelectIGA1(); + + VGAOUT8(0x3c4, 0x29); + save->SR29 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x0E); + save->SR0E = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x0F); + save->SR0F = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x30); + save->SR30 = VGAIN8(0x3c5); + VGAOUT8(0x3c4, 0x31); + save->SR31 = VGAIN8(0x3c5); + + /* active output reg */ + VGAOUT8(vgaCRIndex, 0x6b); + save->CR6B = VGAIN8(vgaCRReg); + + SelectIGA2(); if (!psav->ModeStructInit) { vgaHWCopyReg(&hwp->ModeReg, vgaSavePtr); memcpy(&psav->ModeReg, save, sizeof(SavageRegRec)); psav->ModeStructInit = TRUE; } + SelectIGA1(); #if 0 if (xf86GetVerbosity() > 1) @@ -1908,6 +2135,14 @@ TRACE(("SavageWriteMode(%x)\n", restore->mode)); + if (psav->IsSecondary) { + SavageWriteModeCRTC2(pScrn, vgaSavePtr, restore, Entering); + return; + } + + UnLockExtRegs(); + SelectIGA1(); + #ifdef XF86DRI if (psav->directRenderingEnabled) { DRILock(screenInfo.screens[pScrn->scrnIndex], 0); @@ -1946,9 +2181,7 @@ hwp->writeSeq( hwp, 0x08, 0x06 ); #endif - VGAOUT16(vgaCRIndex, 0x4838); - VGAOUT16(vgaCRIndex, 0xA039); - VGAOUT16(0x3c4, 0x0608); + UnLockExtRegs(); /* Enable linear addressing. */ @@ -2042,11 +2275,11 @@ VGAOUT8(vgaCRIndex, 0x50); VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1); -#if 0 + width = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3; VGAOUT16(vgaCRIndex, ((width & 0xff) << 8) | 0x13 ); VGAOUT16(vgaCRIndex, ((width & 0x300) << 4) | 0x51 ); -#endif + /* Some non-S3 BIOSes enable block write even on non-SGRAM devices. */ switch( psav->Chipset ) @@ -2099,9 +2332,9 @@ } VGAOUT8(0x3c2, 0x23); - VGAOUT16(vgaCRIndex, 0x4838); - VGAOUT16(vgaCRIndex, 0xa039); - VGAOUT16(0x3c4, 0x0608); + /*VGAOUT8(0x3c2, 0x2f);*/ + + UnLockExtRegs(); vgaHWProtect(pScrn, TRUE); @@ -2119,7 +2352,6 @@ * haven't been able to find what causes it, but a non-destructive * switch to mode 3 here seems to eliminate the issue. */ - if( ((restore->CR31 & 0x0a) == 0) && psav->pInt10 ) { SavageSetTextMode( psav ); } @@ -2152,8 +2384,6 @@ VGAOUT8(0x3c5, restore->SR0F); VGAOUT8(0x3c4, 0x29); VGAOUT8(0x3c5, restore->SR29); - VGAOUT8(0x3c4, 0x15); - VGAOUT8(0x3c5, restore->SR15); /* Restore flat panel expansion regsters. */ if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || @@ -2171,6 +2401,7 @@ else vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_MODE); + /* extended mode timing registers */ VGAOUT8(vgaCRIndex, 0x53); VGAOUT8(vgaCRReg, restore->CR53); @@ -2250,11 +2481,9 @@ VGAOUT8(0x3c5, restore->SR11); } + /*VGAOUT8(0x3c2, 0x2f);*/ + /* restore extended seq regs for dclk */ - VGAOUT8(0x3c4, 0x0e); - VGAOUT8(0x3c5, restore->SR0E); - VGAOUT8(0x3c4, 0x0f); - VGAOUT8(0x3c5, restore->SR0F); VGAOUT8(0x3c4, 0x12); VGAOUT8(0x3c5, restore->SR12); VGAOUT8(0x3c4, 0x13); @@ -2270,6 +2499,21 @@ else VGAOUT8(0x3c5, restore->SR1B); + VGAOUT8(0x3c4, 0x30); + VGAOUT8(0x3c5, restore->SR30); + VGAOUT8(0x3c4, 0x31); + VGAOUT8(0x3c5, restore->SR31); + VGAOUT8(0x3c4, 0x08); + VGAOUT8(0x3c5, restore->SR08); + /* make sure crtc2 is on */ + VGAOUT8(0x3c4, 0x0b); + VGAOUT8(0x3c5, 0x50); +#if 0 + VGAOUT8(0x3c4, 0x20); + VGAOUT8(0x3c5, 0xff); + VGAOUT8(0x3c4, 0x21); + VGAOUT8(0x3c4, 0x88); +#endif /* load new m, n pll values for dclk & mclk */ VGAOUT8(0x3c4, 0x15); tmp = VGAIN8(0x3c5) & ~0x21; @@ -2279,14 +2523,17 @@ VGAOUT8(0x3c5, tmp | 0x03); VGAOUT8(0x3c5, restore->SR15); usleep( 100 ); - +#if 0 VGAOUT8(0x3c4, 0x30); VGAOUT8(0x3c5, restore->SR30); + VGAOUT8(0x3c4, 0x31); + VGAOUT8(0x3c5, restore->SR31); VGAOUT8(0x3c4, 0x08); VGAOUT8(0x3c5, restore->SR08); - +#endif /* now write out cr67 in full, possibly starting STREAMS */ VerticalRetraceWait(); + VGAOUT8(vgaCRIndex, 0x67); #if 0 VGAOUT8(vgaCRReg, 0x50); @@ -2348,82 +2595,235 @@ psav->LockHeld = 0; #endif + SavagePrintRegs(pScrn); + return; } - -static Bool SavageMapMMIO(ScrnInfoPtr pScrn) +static void SavageWriteModeCRTC2(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, + SavageRegPtr restore, Bool Entering) { - SavagePtr psav; + unsigned char tmp, cr67; + vgaHWPtr hwp = VGAHWPTR(pScrn); + SavagePtr psav = SAVPTR(pScrn); + int vgaCRIndex, vgaCRReg, vgaIOBase; + int i, width; - TRACE(("SavageMapMMIO()\n")); + vgaIOBase = hwp->IOBase; + vgaCRIndex = vgaIOBase + 4; + vgaCRReg = vgaIOBase + 5; + + TRACE(("SavageWriteModeCRTC2(%x)\n", restore->mode)); - psav = SAVPTR(pScrn); + UnLockExtRegs(); + SelectIGA1(); - if( S3_SAVAGE3D_SERIES(psav->Chipset) ) { - psav->MmioBase = psav->PciInfo->memBase[0] + SAVAGE_NEWMMIO_REGBASE_S3; - psav->FrameBufferBase = psav->PciInfo->memBase[0]; - } - else { - psav->MmioBase = psav->PciInfo->memBase[0] + SAVAGE_NEWMMIO_REGBASE_S4; - psav->FrameBufferBase = psav->PciInfo->memBase[1]; +#ifdef XF86DRI + if (psav->directRenderingEnabled) { + DRILock(screenInfo.screens[pScrn->scrnIndex], 0); + psav->LockHeld = 1; } - - xf86DrvMsg( pScrn->scrnIndex, X_PROBED, - "mapping MMIO @ 0x%x with size 0x%x\n", - psav->MmioBase, SAVAGE_NEWMMIO_REGSIZE); - - psav->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, psav->PciTag, - psav->MmioBase, - SAVAGE_NEWMMIO_REGSIZE); -#if 0 - psav->MapBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, - psav->PciTag, - psav->PciInfo->memBase[0], - 0x8000); #endif - if (!psav->MapBase) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal error: cound not map registers\n"); - return FALSE; - } - psav->BciMem = psav->MapBase + 0x10000; - SavageEnableMMIO(pScrn); + vgaHWProtect(pScrn, TRUE); + /* restore the desired video mode with cr67 */ + VGAOUT8(vgaCRIndex, 0x67); + VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c); /* no STREAMS yet */ - return TRUE; -} + VGAOUT16(0x3c4, 0x0608); -static Bool SavageMapFB(ScrnInfoPtr pScrn) -{ - SavagePtr psav = SAVPTR(pScrn); + /* Restore DCLK registers. */ + VGAOUT8(0x3c4, 0x0e); + VGAOUT8(0x3c5, restore->SR0E); + VGAOUT8(0x3c4, 0x0f); + VGAOUT8(0x3c5, restore->SR0F); + VGAOUT8(0x3c4, 0x29); + VGAOUT8(0x3c5, restore->SR29); - TRACE(("SavageMapFB()\n")); + UnLockExtRegs(); + SelectIGA2(); + /*UnProtectCRTC();*/ - xf86DrvMsg( pScrn->scrnIndex, X_PROBED, - "mapping framebuffer @ 0x%x with size 0x%x\n", - psav->FrameBufferBase, psav->videoRambytes); + /*hwp->writeCrtc(hwp, 17, vgaSavePtr->CRTC[17] & ~0x80);*/ + for (i = 0; i < vgaSavePtr->numCRTC; i++) + hwp->writeCrtc(hwp, i, vgaSavePtr->CRTC[i]); + + width = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3; + VGAOUT16(vgaCRIndex, ((width & 0xff) << 8) | 0x13 ); + VGAOUT16(vgaCRIndex, ((width & 0x300) << 4) | 0x51 ); - if (psav->videoRambytes) { - psav->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, - psav->PciTag, psav->FrameBufferBase, - psav->videoRambytes); - if (!psav->FBBase) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal error: could not map framebuffer\n"); - return FALSE; - } - psav->FBStart = psav->FBBase; - } + /* extended mode timing registers */ + VGAOUT8(vgaCRIndex, 0x5d); + VGAOUT8(vgaCRReg, restore->CR5D); + VGAOUT8(vgaCRIndex, 0x5e); + VGAOUT8(vgaCRReg, restore->CR5E); + VGAOUT8(vgaCRIndex, 0x3b); + VGAOUT8(vgaCRReg, restore->CR3B); + VGAOUT8(vgaCRIndex, 0x3c); + VGAOUT8(vgaCRReg, restore->CR3C); + VGAOUT8(vgaCRIndex, 0x65); + VGAOUT8(vgaCRReg, restore->CR65); - if (psav->Chipset == S3_SUPERSAVAGE) - /* paramount aperture 0 is pci base 2 */ - psav->ApertureBase = psav->PciInfo->memBase[2]; - else - psav->ApertureBase = psav->FrameBufferBase + 0x02000000; - + /* restore the desired video mode with cr67 */ + VGAOUT8(vgaCRIndex, 0x67); + VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c); /* no STREAMS yet */ + /* other mode timing and extended regs */ + + VGAOUT8(vgaCRIndex, 0x42); + VGAOUT8(vgaCRReg, restore->CR42); + VGAOUT8(vgaCRIndex, 0x45); + VGAOUT8(vgaCRReg, restore->CR45); + VGAOUT8(vgaCRIndex, 0x51); + VGAOUT8(vgaCRReg, restore->CR51); + + /* memory timings */ + VGAOUT8(vgaCRIndex, 0x69); + VGAOUT8(vgaCRReg, restore->CR69); + + VGAOUT8(vgaCRIndex, 0x33); + VGAOUT8(vgaCRReg, restore->CR33); + VGAOUT8(vgaCRIndex, 0x90); + VGAOUT8(vgaCRReg, restore->CR90); + VGAOUT8(vgaCRIndex, 0x91); + VGAOUT8(vgaCRReg, restore->CR91); + + SelectIGA1(); + /* unlock extended seq regs */ + VGAOUT8(0x3c4, 0x08); + VGAOUT8(0x3c5, 0x06); + + /*VGAOUT8(0x3c2, 0x2f);*/ /* use SR12,13 SR0e,0f for DCLK */ + + /* restore extended seq regs for dclk */ + VGAOUT8(0x3c4, 0x0E); + VGAOUT8(0x3c5, restore->SR0E); + VGAOUT8(0x3c4, 0x0F); + VGAOUT8(0x3c5, restore->SR0F); + VGAOUT8(0x3c4, 0x29); + VGAOUT8(0x3c5, restore->SR29); + + /* load new m, n pll values for dclk & mclk */ + VGAOUT8(0x3c4, 0x15); + tmp = VGAIN8(0x3c5) & ~0x21; + + VGAOUT8(0x3c5, tmp | 0x03); + VGAOUT8(0x3c5, tmp | 0x23); + VGAOUT8(0x3c5, tmp | 0x03); + VGAOUT8(0x3c5, restore->SR15); + usleep( 100 ); + + VGAOUT8(0x3c4, 0x30); + VGAOUT8(0x3c5, restore->SR30); + VGAOUT8(0x3c4, 0x31); + VGAOUT8(0x3c5, restore->SR31); + + /* now write out cr67 in full, possibly starting STREAMS */ + VerticalRetraceWait(); + SelectIGA2(); + VGAOUT8(vgaCRIndex, 0x67); + VGAOUT8(vgaCRReg, restore->CR67); + SelectIGA1(); + + VGAOUT8(vgaCRIndex, 0x67); + VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0x0c); /* start streams */ + + if( Entering ) { + /*SavageInitialize2DEngine(pScrn);*/ + + VGAOUT16(vgaCRIndex, 0x0140); + + SavageSetGBD(pScrn); + } + + vgaHWProtect(pScrn, FALSE); + + +#ifdef XF86DRI + if (psav->directRenderingEnabled) + DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); + psav->LockHeld = 0; +#endif + + SavagePrintRegs(pScrn); + + return; +} + + +static Bool SavageMapMMIO(ScrnInfoPtr pScrn) +{ + SavagePtr psav; + + TRACE(("SavageMapMMIO()\n")); + + psav = SAVPTR(pScrn); + + if( S3_SAVAGE3D_SERIES(psav->Chipset) ) { + psav->MmioBase = psav->PciInfo->memBase[0] + SAVAGE_NEWMMIO_REGBASE_S3; + psav->FrameBufferBase = psav->PciInfo->memBase[0]; + } + else { + psav->MmioBase = psav->PciInfo->memBase[0] + SAVAGE_NEWMMIO_REGBASE_S4; + psav->FrameBufferBase = psav->PciInfo->memBase[1]; + } + + xf86DrvMsg( pScrn->scrnIndex, X_PROBED, + "mapping MMIO @ 0x%x with size 0x%x\n", + psav->MmioBase, SAVAGE_NEWMMIO_REGSIZE); + + psav->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, psav->PciTag, + psav->MmioBase, + SAVAGE_NEWMMIO_REGSIZE); +#if 0 + psav->MapBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, + psav->PciTag, + psav->PciInfo->memBase[0], + 0x8000); +#endif + if (!psav->MapBase) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: cound not map registers\n"); + return FALSE; + } + + psav->BciMem = psav->MapBase + 0x10000; + + SavageEnableMMIO(pScrn); + + return TRUE; +} + + +static Bool SavageMapFB(ScrnInfoPtr pScrn) +{ + SavagePtr psav = SAVPTR(pScrn); + + TRACE(("SavageMapFB()\n")); + + xf86DrvMsg( pScrn->scrnIndex, X_PROBED, + "mapping framebuffer @ 0x%x with size 0x%x\n", + psav->FrameBufferBase, psav->videoRambytes); + + if (psav->videoRambytes) { + psav->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + psav->PciTag, psav->FrameBufferBase, + psav->videoRambytes); + if (!psav->FBBase) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error: could not map framebuffer\n"); + return FALSE; + } + psav->FBStart = psav->FBBase; + } + + if (psav->Chipset == S3_SUPERSAVAGE) + /* paramount aperture 0 is pci base 2 */ + psav->ApertureBase = psav->PciInfo->memBase[2]; + else + psav->ApertureBase = psav->FrameBufferBase + 0x02000000; + psav->ApertureMap = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, psav->PciTag, psav->ApertureBase, 0x01000000 * 5); @@ -2440,7 +2840,10 @@ } pScrn->memPhysBase = psav->PciInfo->memBase[0]; - pScrn->fbOffset = 0; + if (psav->IsSecondary) + pScrn->fbOffset = pScrn->videoRam * 1024; + else + pScrn->fbOffset = 0; return TRUE; } @@ -2679,6 +3082,9 @@ if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + ErrorF("\nEnd of ScreenInit\n"); + SavagePrintRegs(pScrn); + return TRUE; } @@ -2795,7 +3201,12 @@ mode->CrtcVTotal); #endif + if (psav->IsSecondary) { + return SavageModeInitCRTC2(pScrn, mode); + } + UnLockExtRegs(); + SelectIGA1(); if (pScrn->bitsPerPixel == 8) psav->HorizScaleFactor = 1; @@ -2814,6 +3225,7 @@ mode->CrtcHAdjusted = TRUE; } + if (!vgaHWInit(pScrn, mode)) return FALSE; @@ -2959,6 +3371,8 @@ else new->SR1B = 0x00; + new->SR1B |= 0x80; + new->CR43 = new->CR45 = new->CR65 = 0x00; @@ -2988,8 +3402,40 @@ &m, &n, &r); new->SR12 = (r << 6) | (n & 0x3f); new->SR13 = m & 0xff; + new->SR0E = (r << 6) | (n & 0x3f); + new->SR0F = m & 0xff; + /*new->SR29 = (r & 4);*/ new->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2; + /*new->SR29 = (r & 4) | (r & 4) << 2 | (m & 0x100) >> 5 | (n & 0x40) >> 2; */ +#if 1 + new->SR30 = 0x10; /*0x10*/ + new->SR31 = 0x14; /*0x10*/ +#endif +#if 0 + VGAOUT8(0x3c4, 0x30); + new->SR30 = VGAIN8(0x3c5) & ~0x0f; /* bits 0-4, 7? should be 0 - 0x0f or 0x8f */ + /*new->SR30 = VGAIN8(0x3c5) | (0x0c) & (~0x03);*/ /* swap clocks */ + VGAOUT8(0x3c4, 0x31); + new->SR31 = VGAIN8(0x3c5) | (CRTC2_IS_CRT_SOURCE) + /*| (FP_ENABLE)*/ + & ~(CRTC2_IS_FP_SOURCE) /* crtc1 is FP source */ + & ~(0x01); /* bit 0 - 0 standard FP operation */ + VGAOUT8(vgaCRIndex, 0x6B); /* which of these should be active for dualhead? */ + new->CR6B = VGAIN8(vgaCRReg) | 0x80; /* activeDUO */ +#endif +#if 0 + VGAOUT8(vgaCRIndex, 0x6B); /* which of these should be active for dualhead? */ + new->CR6B = VGAIN8(vgaCRReg) | 0x02 /* activeLCD */ + | 0x20 /* activeCRT2 */ + | 0x80 /* activeDUO */ + & ~0x01 /* activeCRT */ + & ~0x04 /* activeTV */ + ; + new->CR6B = 0xa2; /* active LCD, CRT2, DUO */ + /*new->CR6B = 0x22;*/ /* active LCD, crt2 */ + /*new->CR6B = 0x83;*/ /* active LCD, CRT, DUO */ +#endif if (psav->fifo_moderate) { if (pScrn->bitsPerPixel < 24) new->MMPR0 -= 0x8000; @@ -3080,8 +3526,8 @@ VGAOUT8(vgaCRIndex, 0x68); new->CR68 = VGAIN8(vgaCRReg); - new->CR69 = 0x80; - /*new->CR69 = 0;*/ + /*new->CR69 = 0x80;*/ + new->CR69 = 0; VGAOUT8(vgaCRIndex, 0x6f); new->CR6F = VGAIN8(vgaCRReg); VGAOUT8(vgaCRIndex, 0x86); @@ -3090,18 +3536,244 @@ new->CR88 = VGAIN8(vgaCRReg) | DISABLE_BLOCK_WRITE_2D; VGAOUT8(vgaCRIndex, 0xb0); new->CRB0 = VGAIN8(vgaCRReg) | 0x80; - } + } +#if 0 + new->SR10 = 0x41; + new->SR11 = 0x52; + new->SR15 = 0x02; + new->SR1B = 0x07; +#endif pScrn->vtSema = TRUE; /* do it! */ SavageWriteMode(pScrn, vganew, new, TRUE); + SavageAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, +0); + + return TRUE; +} + +static Bool SavageModeInitCRTC2(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + vgaHWPtr hwp = VGAHWPTR(pScrn); + SavagePtr psav = SAVPTR(pScrn); + int width, dclk, i, j; /*, refresh; */ + unsigned int m, n, r; + unsigned char tmp = 0; + SavageRegPtr new = &psav->ModeReg; + vgaRegPtr vganew = &hwp->ModeReg; + int vgaCRIndex, vgaCRReg, vgaIOBase; + + vgaIOBase = hwp->IOBase; + vgaCRIndex = vgaIOBase + 4; + vgaCRReg = vgaIOBase + 5; + + TRACE(("SavageModeInitCRTC2(%dx%d, %dHz)\n", + mode->HDisplay, mode->VDisplay, mode->Clock)); + +#if 0 + ErrorF("Clock = %d, HDisplay = %d, HSStart = %d\n", + mode->Clock, mode->HDisplay, mode->HSyncStart); + ErrorF("HSEnd = %d, HSkew = %d\n", + mode->HSyncEnd, mode->HSkew); + ErrorF("VDisplay - %d, VSStart = %d, VSEnd = %d\n", + mode->VDisplay, mode->VSyncStart, mode->VSyncEnd); + ErrorF("VTotal = %d\n", + mode->VTotal); + ErrorF("HDisplay = %d, HSStart = %d\n", + mode->CrtcHDisplay, mode->CrtcHSyncStart); + ErrorF("HSEnd = %d, HSkey = %d\n", + mode->CrtcHSyncEnd, mode->CrtcHSkew); + ErrorF("VDisplay - %d, VSStart = %d, VSEnd = %d\n", + mode->CrtcVDisplay, mode->CrtcVSyncStart, mode->CrtcVSyncEnd); + ErrorF("VTotal = %d\n", + mode->CrtcVTotal); +#endif + + UnLockExtRegs(); + SelectIGA2(); + + if (pScrn->bitsPerPixel == 8) + psav->HorizScaleFactor = 1; + else if (pScrn->bitsPerPixel == 16) + psav->HorizScaleFactor = 1; /* I don't think we ever want 2 */ + else + psav->HorizScaleFactor = 1; + + if (psav->HorizScaleFactor == 2) + if (!mode->CrtcHAdjusted) { + mode->CrtcHDisplay *= 2; + mode->CrtcHSyncStart *= 2; + mode->CrtcHSyncEnd *= 2; + mode->CrtcHTotal *= 2; + mode->CrtcHSkew *= 2; + mode->CrtcHAdjusted = TRUE; + } + + + if (!vgaHWInit(pScrn, mode)) + return FALSE; + + new->mode = 0; + + /* We need to set CR67 whether or not we use the BIOS. */ + + dclk = mode->Clock; + new->CR67 = 0x00; + + switch( pScrn->depth ) { + case 8: + if( (psav->Chipset == S3_SAVAGE2000) && (dclk >= 230000) ) + new->CR67 = 0x10; /* 8bpp, 2 pixels/clock */ + else + new->CR67 = 0x00; /* 8bpp, 1 pixel/clock */ + break; + case 15: + if( + S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || + ((psav->Chipset == S3_SAVAGE2000) && (dclk >= 230000)) + ) + new->CR67 = 0x30; /* 15bpp, 2 pixel/clock */ + else + new->CR67 = 0x20; /* 15bpp, 1 pixels/clock */ + break; + case 16: + if( + S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || + ((psav->Chipset == S3_SAVAGE2000) && (dclk >= 230000)) + ) + new->CR67 = 0x50; /* 16bpp, 2 pixel/clock */ + else + new->CR67 = 0x40; /* 16bpp, 1 pixels/clock */ + break; + case 24: + if (pScrn->bitsPerPixel == 24 ) + new->CR67 = 0x70; + else + new->CR67 = 0xd0; + break; + } + + if( !new->mode ) { + /* + * Either BIOS use is disabled, or we failed to find a suitable + * match. Fall back to traditional register-crunching. + */ + + new->CR45 = new->CR65 = 0x00; + + psav->NeedSTREAMS = FALSE; + + SavageCalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000, + &m, &n, &r); + new->SR0E = (r << 6) | (n & 0x3f); + new->SR0F = m & 0xff; + new->SR29 = (r & 4) << 2 | (m & 0x100) >> 5 | (n & 0x40) >> 2; + + new->SR15 = 0x03 | 0x80; + + VGAOUT8(0x3c4, 0x30); + new->SR30 = VGAIN8(0x3c5) & ~0x0f; /* bits 0-4, 7? should be 0 - 0x0f or 0x8f */ + /*new->SR30 = VGAIN8(0x3c5) | (0x0c) & (~0x03);*/ /* swap clocks */ + VGAOUT8(0x3c4, 0x31); + new->SR31 = VGAIN8(0x3c5) | (CRTC2_IS_CRT_SOURCE) + /*| (FP_ENABLE)*/ + & ~(CRTC2_IS_FP_SOURCE) /* crtc1 is FP source */ + & ~(0x01); /* bit 0 - 0 standard FP operation */ + + VGAOUT8(vgaCRIndex, 0x6B); /* which of these should be active for dualhead? */ + new->CR6B = VGAIN8(vgaCRReg) | 0x80; /* activeDUO */ + + + if (mode->Flags & V_INTERLACE) + new->CR42 = 0x20; + else + new->CR42 = 0x00; + + i = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) | + ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) | + ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) | + ((mode->CrtcHSyncStart & 0x800) >> 7); + + if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 64) + i |= 0x08; + if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 32) + i |= 0x20; + j = (vganew->CRTC[0] + ((i & 0x01) << 8) + + vganew->CRTC[4] + ((i & 0x10) << 4) + 1) / 2; + if (j - (vganew->CRTC[4] + ((i & 0x10) << 4)) < 4) { + if (vganew->CRTC[4] + ((i & 0x10) << 4) + 4 <= + vganew->CRTC[0] + ((i & 0x01) << 8)) + j = vganew->CRTC[4] + ((i & 0x10) << 4) + 4; + else + j = vganew->CRTC[0] + ((i & 0x01) << 8) + 1; + } + + new->CR3B = j & 0xff; + i |= (j & 0x100) >> 2; + new->CR3C = (vganew->CRTC[0] + ((i & 0x01) << 8)) / 2; + new->CR5D = i; + new->CR5E = (((mode->CrtcVTotal - 2) & 0x400) >> 10) | + (((mode->CrtcVDisplay - 1) & 0x400) >> 9) | + (((mode->CrtcVSyncStart) & 0x400) >> 8) | + (((mode->CrtcVSyncStart) & 0x400) >> 6) | 0x40; + width = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3; + new->CR91 = vganew->CRTC[19] = 0xff & width; + new->CR51 = (0x300 & width) >> 4; + new->CR90 = 0x80 | (width >> 8); + + /* Set frame buffer description. */ +#if 0 + if (pScrn->bitsPerPixel <= 8) + new->CR50 = 0; + else if (pScrn->bitsPerPixel <= 16) + new->CR50 = 0x10; + else + new->CR50 = 0x30; + + if (pScrn->displayWidth == 640) + new->CR50 |= 0x40; + else if (pScrn->displayWidth == 800) + new->CR50 |= 0x80; + else if (pScrn->displayWidth == 1024) + new->CR50 |= 0x00; + else if (pScrn->displayWidth == 1152) + new->CR50 |= 0x01; + else if (pScrn->displayWidth == 1280) + new->CR50 |= 0xc0; + else if (pScrn->displayWidth == 1600) + new->CR50 |= 0x81; + else + new->CR50 |= 0xc1; /* Use GBD */ +#endif + if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) + new->CR33 = 0x00; + else + new->CR33 = 0x08; + + vganew->CRTC[0x17] = 0xeb; + + new->CR67 |= 1; + + /*new->CR69 = 0x80;*/ + new->CR69 = 0; + + } + + SelectIGA1(); + + pScrn->vtSema = TRUE; + + /* do it! */ + SavageWriteModeCRTC2(pScrn, vganew, new, TRUE); SavageAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); return TRUE; } + static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; @@ -3162,7 +3834,7 @@ #endif return vgaHWSaveScreen(pScreen, mode); } - +#if 0 void SavageAdjustFrame(int scrnIndex, int x, int y, int flags) { @@ -3198,8 +3870,12 @@ pScrn->frameX1 = left + currentMode->HDisplay - 1; pScrn->frameY1 = top+ currentMode->VDisplay - 1; + address += pScrn->fbOffset; + if (psav->Chipset == S3_SAVAGE_MX) { + if (!psav->IsSecondary) OUTREG32(PRI_STREAM_FBUF_ADDR1, address & 0xFFFFFFFC);/* IGA1 */ + else OUTREG32(PRI_STREAM2_FBUF_ADDR0, address & 0xFFFFFFFC);/* IGA2 */ } else if (psav->Chipset == S3_SUPERSAVAGE) { /* IGA1 */ @@ -3214,8 +3890,8 @@ return; } - -#if 0 +#endif +#if 1 void SavageAdjustFrame(int scrnIndex, int x, int y, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; @@ -3234,11 +3910,24 @@ Base = ((y * pScrn->displayWidth + (x&~1)) * (pScrn->bitsPerPixel / 8)) >> 2; + + Base += pScrn->fbOffset; + /* now program the start address registers */ + if (!psav->IsSecondary) { + VGAOUT16(vgaCRIndex, (Base & 0x00ff00) | 0x0c); + VGAOUT16(vgaCRIndex, ((Base & 0x00ff) << 8) | 0x0d); + VGAOUT8(vgaCRIndex, 0x69); + VGAOUT8(vgaCRReg, (Base & 0x7f0000) >> 16); + /*VGAOUT8(vgaCRReg, (Base & 0x0f0000) >> 16);*/ + } else { + SelectIGA2(); VGAOUT16(vgaCRIndex, (Base & 0x00ff00) | 0x0c); VGAOUT16(vgaCRIndex, ((Base & 0x00ff) << 8) | 0x0d); VGAOUT8(vgaCRIndex, 0x69); VGAOUT8(vgaCRReg, (Base & 0x7f0000) >> 16); + SelectIGA1(); + } return; } @@ -3510,7 +4199,14 @@ int vgaCRIndex = 0x3d4; int vgaCRReg = 0x3d5; - ErrorF( "SR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF" ); + UnLockExtRegs(); + + if (psav->IsSecondary) + ErrorF("\n\nScreen1"); + else + ErrorF("\n\nScreen0"); + + ErrorF( "\n\nSR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF" ); for( i = 0; i < 0x70; i++ ) { if( !(i % 16) ) @@ -3518,15 +4214,26 @@ VGAOUT8( 0x3c4, i ); ErrorF( " %02x", VGAIN8(0x3c5) ); } + ErrorF("\n\ncrtc1"); + ErrorF( "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF" ); + for( i = 0; i < 0xB7; i++ ) { + if( !(i % 16) ) + ErrorF( "\nCR%xx ", i >> 4 ); + VGAOUT8( vgaCRIndex, i ); + ErrorF( " %02x", VGAIN8(vgaCRReg) ); + } + ErrorF("\n\ncrtc2"); ErrorF( "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF" ); + SelectIGA2(); for( i = 0; i < 0xB7; i++ ) { if( !(i % 16) ) ErrorF( "\nCR%xx ", i >> 4 ); VGAOUT8( vgaCRIndex, i ); ErrorF( " %02x", VGAIN8(vgaCRReg) ); } + SelectIGA1(); ErrorF("\n\n"); } @@ -3565,10 +4272,10 @@ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", mode); break; } - +#if 0 if( !psav->CrtOnly ) SavageSetPanelEnabled(psav, (mode == DPMSModeOn)); - +#endif VGAOUT8(0x3c4, 0x0d); VGAOUT8(0x3c5, srd); Index: savage_driver.h =================================================================== RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v retrieving revision 1.9.4.9 diff -u -r1.9.4.9 savage_driver.h --- savage_driver.h 21 Feb 2004 15:28:45 -0000 1.9.4.9 +++ savage_driver.h 26 Feb 2004 20:33:08 -0000 @@ -97,7 +97,8 @@ typedef struct { unsigned int mode, refresh; unsigned char SR08, SR0E, SR0F; - unsigned char SR10, SR11, SR12, SR13, SR15, SR18, SR1B, SR29, SR30; + unsigned char SR10, SR11, SR12, SR13, SR15, SR18, SR1B, SR29, SR30, SR31; + unsigned char CR6B; unsigned char SR54[8]; unsigned char Clock; unsigned char CR31, CR32, CR33, CR34, CR36, CR3A, CR3B, CR3C; @@ -122,6 +123,35 @@ #define TILEWIDTH_16BPP 64 /* TILEWIDTH_BYTES/2-BYTES-PER-PIXEL */ #define TILEWIDTH_32BPP 32 /* TILEWIDTH_BYTES/4-BYTES-PER-PIXEL */ +typedef enum { + MT_NONE, + MT_CRT, + MT_LCD, + MT_DFP, + MT_CTV, + MT_STV +} SavageMonitorType; + +typedef struct +{ + Bool HasSecondary; + + /* + * The next two are used to make sure CRTC2 is restored before CRTC_EXT, + * otherwise it could lead to blank screens. + */ + Bool IsSecondaryRestored; + Bool RestorePrimary; + + ScrnInfoPtr pSecondaryScrn; + ScrnInfoPtr pPrimaryScrn; + + int MonType1; + int MonType2; + xf86MonPtr MonInfo1; + xf86MonPtr MonInfo2; +} SavageEntRec, *SavageEntPtr; + /* Bitmap descriptor structures for BCI */ typedef struct _HIGH { ushort Stride; @@ -344,6 +374,13 @@ StatInfoRec StatInfo; /* save the SVGA state */ + /* DuoView stuff */ + Bool HasCRTC2; /* MX, IX, Supersavage */ + Bool IsSecondary; /* second Screen */ + SavageMonitorType DisplayType; /* Monitor connected on */ + Bool IsSwitching; /* Flag for switching mode */ + EntityInfoPtr pEnt; + } SavageRec, *SavagePtr; /* Video flags. */ Index: savage_regs.h =================================================================== RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h,v retrieving revision 1.8.4.5 diff -u -r1.8.4.5 savage_regs.h --- savage_regs.h 20 Feb 2004 19:29:33 -0000 1.8.4.5 +++ savage_regs.h 26 Feb 2004 20:33:09 -0000 @@ -185,9 +185,25 @@ /* CR69[0] = 1 : Mem-mapped regs */ #define USE_MM_FOR_PRI_STREAM_OLD 0x01 +#define SelectIGA1() \ +do { \ + OUTREG16(SEQ_ADDRESS_REG,0x4026); \ +} while (0) + +#define SelectIGA2() \ +do { \ + OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES); \ +} while (0) #define SELECT_IGA1 0x4026 #define SELECT_IGA2_READS_WRITES 0x4f26 +/* SR30 */ +#define CRTC1_USE_DCLK2 0x08 +#define CRTC2_USE_DCLK1 0x10 +/* SR31 */ +#define CRTC2_IS_FP_SOURCE 0x02 +#define CRTC2_IS_CRT_SOURCE 0x04 +#define FP_ENABLE 0x10 #define MEM_PS1 0x10 /*CRCA_4 :Primary stream 1*/ #define MEM_PS2 0x20 /*CRCA_5 :Primary stream 2*/ Index: savage_vbe.c =================================================================== RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c,v retrieving revision 1.2.4.7 diff -u -r1.2.4.7 savage_vbe.c --- savage_vbe.c 21 Feb 2004 15:28:45 -0000 1.2.4.7 +++ savage_vbe.c 26 Feb 2004 20:33:09 -0000 @@ -319,3 +319,4 @@ return iModeCount; } +