diff options
Diffstat (limited to 'src/sis_driver.c')
-rw-r--r-- | src/sis_driver.c | 955 |
1 files changed, 699 insertions, 256 deletions
diff --git a/src/sis_driver.c b/src/sis_driver.c index 5abdda6..baba1d2 100644 --- a/src/sis_driver.c +++ b/src/sis_driver.c @@ -1,4 +1,5 @@ /* $XFree86$ */ +/* $XdotOrg$ */ /* * SiS driver main code * @@ -34,7 +35,7 @@ * * This notice covers the entire driver code unless otherwise indicated. * - * Formerly based on code which is + * Formerly based on code which was * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England. * Written by: * Alan Hourihane <alanh@fairlite.demon.co.uk>, @@ -154,6 +155,7 @@ static SymTabRec SISChipsets[] = { { PCI_CHIP_SIS650, "SIS650/M650/651/740" }, { PCI_CHIP_SIS330, "SIS330(Xabre)" }, { PCI_CHIP_SIS660, "SIS660/661FX/M661FX/M661MX/741/741GX/M741/760/M760" }, + { PCI_CHIP_SIS340, "SIS340" }, { -1, NULL } }; @@ -171,6 +173,7 @@ static PciChipsets SISPciChipsets[] = { { PCI_CHIP_SIS650, PCI_CHIP_SIS650, RES_SHARED_VGA }, { PCI_CHIP_SIS330, PCI_CHIP_SIS330, RES_SHARED_VGA }, { PCI_CHIP_SIS660, PCI_CHIP_SIS660, RES_SHARED_VGA }, + { PCI_CHIP_SIS340, PCI_CHIP_SIS340, RES_SHARED_VGA }, { -1, -1, RES_UNDEFINED } }; @@ -178,10 +181,6 @@ static const char *xaaSymbols[] = { "XAACopyROP", "XAACreateInfoRec", "XAADestroyInfoRec", -#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) - "XAAFillSolidRects", -#endif - "XAAFillMono8x8PatternRects", "XAAHelpPatternROP", "XAAInit", NULL @@ -269,6 +268,11 @@ static const char *drmSymbols[] = { "drmCtlInstHandler", "drmGetInterruptFromBusID", "drmSiSAgpInit", +#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,3,0,0,0) + "drmGetVersion", + "drmFreeVersion", + "drmCommandWrite", +#endif NULL }; @@ -282,10 +286,10 @@ static const char *driSymbols[] = { "DRIQueryVersion", "DRIScreenInit", "DRIUnlock", +#if 0 /* Wait for DRI update */ + "DRICreatePCIBusID", +#endif "GlxSetVisualConfigs", -#ifdef SISNEWDRI2 - "DRICreatePCIBusID" -#endif NULL }; #endif @@ -300,7 +304,11 @@ static XF86ModuleVersionInfo sisVersRec = MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, +#ifdef XORG_VERSION_CURRENT XORG_VERSION_CURRENT, +#else + XF86_VERSION_CURRENT, +#endif SIS_MAJOR_VERSION, SIS_MINOR_VERSION, SIS_PATCHLEVEL, ABI_CLASS_VIDEODRV, /* This is a video driver */ ABI_VIDEODRV_VERSION, @@ -592,10 +600,10 @@ SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int fla } if(docrt1) { - setSISIDXREG(SISSR, 0x01, ~0x20, sr1); /* Set/Clear "Display On" bit */ switch(pSiS->VGAEngine) { case SIS_OLD_VGA: case SIS_530_VGA: + setSISIDXREG(SISSR, 0x01, ~0x20, sr1); /* Set/Clear "Display On" bit */ inSISIDXREG(SISSR, 0x11, oldpmreg); setSISIDXREG(SISCR, 0x17, 0x7f, cr17); setSISIDXREG(SISSR, 0x11, 0x3f, pmreg); @@ -607,15 +615,15 @@ SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int fla } /* fall through */ default: + if(!SiSBridgeIsInSlaveMode(pScrn)) { + setSISIDXREG(SISSR, 0x01, ~0x20, sr1); /* Set/Clear "Display On" bit */ + } if((!(pSiS->VBFlags & CRT1_LCDA)) || (pSiS->VBFlags & VB_301C)) { inSISIDXREG(SISSR, 0x1f, oldpmreg); - if(!pSiS->CRT1off) { + if((!pSiS->CRT1off) && (!SiSBridgeIsInSlaveMode(pScrn))) { setSISIDXREG(SISSR, 0x1f, 0x3f, pmreg); } } - /* TODO: Check if Chrontel TV is active and in slave mode, - * don't go into power-saving mode this in this case! - */ } oldpmreg &= 0xc0; } @@ -741,6 +749,23 @@ SISErrorLog(ScrnInfoPtr pScrn, const char *format, ...) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str); } +static void +SiS_SiSFB_Lock(ScrnInfoPtr pScrn, Bool lock) +{ + SISPtr pSiS = SISPTR(pScrn); + int fd; + CARD32 parm; + + if(!pSiS->sisfbfound) return; + if(!pSiS->sisfb_havelock) return; + + if((fd = open(pSiS->sisfbdevname, 'r')) != -1) { + parm = lock ? 1 : 0; + ioctl(fd, SISFB_SET_LOCK, &parm); + close(fd); + } +} + /* Mandatory */ static Bool SISProbe(DriverPtr drv, int flags) @@ -842,7 +867,8 @@ SISProbe(DriverPtr drv, int flags) pEnt->chipset == PCI_CHIP_SIS650 || pEnt->chipset == PCI_CHIP_SIS550 || pEnt->chipset == PCI_CHIP_SIS315 || pEnt->chipset == PCI_CHIP_SIS315H || pEnt->chipset == PCI_CHIP_SIS315PRO || pEnt->chipset == PCI_CHIP_SIS330 || - pEnt->chipset == PCI_CHIP_SIS300 || pEnt->chipset == PCI_CHIP_SIS660) { + pEnt->chipset == PCI_CHIP_SIS300 || pEnt->chipset == PCI_CHIP_SIS660 || + pEnt->chipset == PCI_CHIP_SIS340) { SISEntPtr pSiSEnt = NULL; DevUnion *pPriv; @@ -2247,6 +2273,51 @@ SiSMakeOwnModeList(ScrnInfoPtr pScrn, BOOLEAN acceptcustommodes, BOOLEAN include return FALSE; } +void SISDetermineLCDACap(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + + if( ((pSiS->sishw_ext.jChipType == SIS_650) || + (pSiS->sishw_ext.jChipType >= SIS_661)) && + (pSiS->VBFlags & (VB_301C | VB_302B | VB_301LV | VB_302LV)) && + (pSiS->VESA != 1) ) { + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTLCDA; + } else { + pSiS->SiS_SD_Flags &= ~SiS_SD_SUPPORTLCDA; + } +} + +void SISSaveDetectedDevices(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + /* Backup detected CRT2 devices */ + pSiS->detectedCRT2Devices = pSiS->VBFlags & (CRT2_LCD|CRT2_TV|CRT2_VGA|TV_AVIDEO|TV_SVIDEO| + TV_SCART|TV_HIVISION|TV_YPBPR); +} + +static BOOLEAN +SISCheckBIOS(SISPtr pSiS, unsigned short mypciid) +{ + unsigned short romptr, pciid; + + if(!pSiS->BIOS) return FALSE; + + if((pSiS->BIOS[0] != 0x55) || (pSiS->BIOS[1] != 0xaa)) return FALSE; + + romptr = pSiS->BIOS[0x18] | (pSiS->BIOS[0x19] << 8); + if(romptr > (BIOS_SIZE - 8)) return FALSE; + if((pSiS->BIOS[romptr] != 'P') || (pSiS->BIOS[romptr+1] != 'C') || + (pSiS->BIOS[romptr+2] != 'I') || (pSiS->BIOS[romptr+3] != 'R')) return FALSE; + + pciid = pSiS->BIOS[romptr+4] | (pSiS->BIOS[romptr+5] << 8); + if(pciid != 0x1039) return FALSE; + + pciid = pSiS->BIOS[romptr+6] | (pSiS->BIOS[romptr+7] << 8); + if(pciid != mypciid) return FALSE; + + return TRUE; +} + /* Mandatory */ static Bool SISPreInit(ScrnInfoPtr pScrn, int flags) @@ -2326,7 +2397,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - /* The vgahw module should be loaded here when needed */ + /* Load the vgahw module */ if(!xf86LoadSubModule(pScrn, "vgahw")) { SISErrorLog(pScrn, "Could not load vgahw module\n"); return FALSE; @@ -2347,13 +2418,13 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Copyright (C) 2001-2004 Thomas Winischhofer <thomas@winischhofer.net> and others\n"); xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Compiled for X.Org %d.%d.%d.%d\n", + "Compiled for " SISMYSERVERNAME " version %d.%d.%d.%d\n", XF86_VERSION_MAJOR, XF86_VERSION_MINOR, XF86_VERSION_PATCH, XF86_VERSION_SNAP); #if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0) if(xf86GetVersion() != XF86_VERSION_CURRENT) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "This version of the driver is not compiled for this version of X.Org!\n"); + "This version of the driver is not compiled for this version of " SISMYSERVERNAME "\n"); } #endif xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -2413,22 +2484,57 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "This adapter is %s display adapter\n", (pSiS->Primary ? "primary" : "secondary")); - + + /* "Patch" the PIOOffset inside vgaHW in order to force + * the vgaHW module to use our relocated i/o ports. + */ + VGAHWPTR(pScrn)->PIOOffset = pSiS->MyPIOOffset = pSiS->IODBase + pSiS->PciInfo->ioBase[2] - 0x380; + +#ifdef SIS_NEED_MAP_IOP + /********************************************/ + /* THIS IS BROKEN AND WON'T WORK */ + /* Reasons: */ + /* 1) MIPS and ARM have no i/o ports but */ + /* use memory mapped i/o only. The inX/outX */ + /* macros in compiler.h are smart enough to */ + /* add "IOPortBase" to the port number, but */ + /* "IOPortBase" is never initialized. */ + /* 2) IOPortBase is declared in compiler.h */ + /* itself. So until somebody fixes all */ + /* modules (eg vgahw) to set IOPortBase, */ + /* vga support for MIPS and ARM is unusable.*/ + /********************************************/ + pSiS->IOPAddress = pSiS->IODBase + pSiS->PciInfo->ioBase[2]; + if(!SISMapIOPMem(pScrn)) { + SISErrorLog(pScrn, "Could not map I/O port area at 0x%x\n", pSiS->IOPAddress); + SISFreeRec(pScrn); + return FALSE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I/O port area mapped to %p, size 128\n", pSiS->IOPBase); +#if defined(__mips__) || defined(__arm32__) + /* inX/outX macros on these use IOPortBase as offset */ + /* This is entirely skrewed. */ + IOPortBase = (unsigned int)pSiS->IOPBase; +#else + /* Others might not... */ + VGAHWPTR(pScrn)->PIOOffset = pSiS->MyPIOOffset = (IOADDRESS)pSiS->IOPBase - 0x380; +#endif + } +#endif + + /* Map 64k VGA window for saving/restoring CGA fonts */ +#ifdef SIS_PC_PLATFORM if(pSiS->Primary) { - VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */ + VGAHWPTR(pScrn)->MapSize = 0x10000; if(!vgaHWMapMem(pScrn)) { - SISErrorLog(pScrn, "Could not map VGA memory\n"); SISFreeRec(pScrn); return FALSE; } } +#endif + vgaHWGetIOBase(VGAHWPTR(pScrn)); - /* We "patch" the PIOOffset inside vgaHW in order to force - * the vgaHW module to use our relocated i/o ports. - */ - VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380; - pSiS->pInt = NULL; if(!pSiS->Primary) { #if !defined(__alpha__) @@ -2482,7 +2588,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) * Set the Chipset and ChipRev, allowing config file entries to * override. DANGEROUS! */ - if(pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) { + if(pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) { pScrn->chipset = pSiS->pEnt->device->chipset; pSiS->Chipset = xf86StringToToken(SISChipsets, pScrn->chipset); from = X_CONFIG; @@ -2561,6 +2667,8 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->ChipFlags = 0; pSiS->SiS_SD_Flags = 0; pSiS->HWCursorMBufNum = pSiS->HWCursorCBufNum = 0; + pSiS->NeedFlush = FALSE; + pSiS->NewCRLayout = FALSE; switch(pSiS->Chipset) { case PCI_CHIP_SIS300: @@ -2636,7 +2744,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->VGAEngine = SIS_315_VGA; pSiS->ChipFlags |= SiSCF_XabreCore; pSiS->SiS_SD_Flags |= SiS_SD_IS330SERIES; - pSiS->myCR63 = 0x63; + pSiS->myCR63 = 0x53; /* sic! */ pSiS->mmioSize = 256; break; case PCI_CHIP_SIS660: /* 660, 661, 741, 760 */ @@ -2647,11 +2755,13 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->sishw_ext.jChipType = SIS_660; pSiS->ChipFlags |= SiSCF_Ultra256Core; pSiS->mmioSize = 256; + pSiS->NeedFlush = TRUE; break; case 0x07601039: pSiS->sishw_ext.jChipType = SIS_760; pSiS->ChipFlags |= SiSCF_Ultra256Core; pSiS->mmioSize = 256; + pSiS->NeedFlush = TRUE; break; case 0x07411039: pSiS->sishw_ext.jChipType = SIS_741; @@ -2673,9 +2783,19 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->VGAEngine = SIS_315_VGA; pSiS->ChipFlags |= SiSCF_Integrated; pSiS->SiS_SD_Flags |= SiS_SD_IS330SERIES; - pSiS->myCR63 = 0x53; /* Yes, 0x53 */ + pSiS->myCR63 = 0x53; /* sic! */ + pSiS->NewCRLayout = TRUE; } break; + case PCI_CHIP_SIS340: + pSiS->sishw_ext.jChipType = SIS_340; + pSiS->VGAEngine = SIS_315_VGA; + pSiS->ChipFlags |= SiSCF_XabreCore; + pSiS->SiS_SD_Flags |= SiS_SD_IS340SERIES; + pSiS->myCR63 = 0x53; /* sic! */ + pSiS->mmioSize = 256; + pSiS->NewCRLayout = TRUE; + break; case PCI_CHIP_SIS530: pSiS->sishw_ext.jChipType = SIS_530; pSiS->VGAEngine = SIS_530_VGA; @@ -2693,9 +2813,9 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) * We use this for checking where sisfb starts its memory * heap in order to automatically detect the correct MaxXFBMem * setting (which normally is given by the option of the same name). - * Under kernel 2.4.y, that only works if sisfb is completely + * Under a 2.4 kernel, that only works if sisfb is completely * running, ie with a video mode because the fbdev will not be - * installed otherwise. Under 2.5 and later, sisfb will install + * installed otherwise. Under 2.6 and later, sisfb will install * the framebuffer device in any way and running it with mode=none * is no longer supported (or necessary). */ @@ -2709,132 +2829,181 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->sisfb_haveemi = FALSE; pSiS->OldMode = 0; pSiS->sisfbfound = FALSE; + pSiS->sisfb_tvposvalid = FALSE; + pSiS->sisfbdevname[0] = 0; + pSiS->sisfb_havelock = FALSE; if(pSiS->VGAEngine == SIS_300_VGA || pSiS->VGAEngine == SIS_315_VGA) { - int fd, i; - sisfb_info mysisfbinfo; - char name[10]; - CARD32 sisfbversion; + int fd, i; + CARD32 sisfbinfosize = 0; + sisfb_info *mysisfbinfo; + CARD32 sisfbversion; + char name[16]; - { - i=0; - do { + i=0; + do { + + if(i <= 7) { sprintf(name, "/dev/fb%1d", i); - if((fd = open(name, 'r')) != -1) { - - if(!ioctl(fd, SISFB_GET_INFO, &mysisfbinfo)) { - - if(mysisfbinfo.sisfb_id == SISFB_ID) { - - sisfbversion = (mysisfbinfo.sisfb_version << 16) | - (mysisfbinfo.sisfb_revision << 8) | - (mysisfbinfo.sisfb_patchlevel); - - if(sisfbversion >= 0x010508) { - /* Added PCI bus/slot/func into in sisfb Version 1.5.08. - Check this to make sure we run on the same card as sisfb - */ - if((mysisfbinfo.sisfb_pcibus == pSiS->PciInfo->bus) && - (mysisfbinfo.sisfb_pcislot == pSiS->PciInfo->device) && - (mysisfbinfo.sisfb_pcifunc == pSiS->PciInfo->func) ) { - pSiS->sisfbfound = TRUE; - } - } else pSiS->sisfbfound = TRUE; + } else { + sprintf(name, "/dev/fb/%1d", i-8); + } + + if((fd = open(name, 'r')) != -1) { + + Bool gotit = FALSE; + + if(!ioctl(fd, SISFB_GET_INFO_SIZE, &sisfbinfosize)) { + if((mysisfbinfo = xalloc(sisfbinfosize))) { + if(!ioctl(fd, (SISFB_GET_INFO | (sisfbinfosize << 16)), mysisfbinfo)) { + gotit = TRUE; + } else { + xfree(mysisfbinfo); + mysisfbinfo = NULL; + } + } + } else { + if((mysisfbinfo = xalloc(sizeof(*mysisfbinfo)+16))) { + if(!ioctl(fd, SISFB_GET_INFO_OLD, mysisfbinfo)) { + gotit = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Possibly old version of sisfb detected. Please update.\n"); + } else { + xfree(mysisfbinfo); + mysisfbinfo = NULL; + } + } + } + + if(gotit) { + + if(mysisfbinfo->sisfb_id == SISFB_ID) { + + sisfbversion = (mysisfbinfo->sisfb_version << 16) | + (mysisfbinfo->sisfb_revision << 8) | + (mysisfbinfo->sisfb_patchlevel); + + if(sisfbversion >= 0x010508) { + /* Added PCI bus/slot/func into in sisfb Version 1.5.08. + * Check this to make sure we run on the same card as sisfb + */ + if((mysisfbinfo->sisfb_pcibus == pSiS->PciInfo->bus) && + (mysisfbinfo->sisfb_pcislot == pSiS->PciInfo->device) && + (mysisfbinfo->sisfb_pcifunc == pSiS->PciInfo->func) ) { + pSiS->sisfbfound = TRUE; + } + } else pSiS->sisfbfound = TRUE; - if(pSiS->sisfbfound) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + if(pSiS->sisfbfound) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s: SiS kernel fb driver (sisfb) %d.%d.%d detected (PCI: %02d:%02d.%d)\n", &name[5], - mysisfbinfo.sisfb_version, - mysisfbinfo.sisfb_revision, - mysisfbinfo.sisfb_patchlevel, + mysisfbinfo->sisfb_version, + mysisfbinfo->sisfb_revision, + mysisfbinfo->sisfb_patchlevel, pSiS->PciInfo->bus, pSiS->PciInfo->device, pSiS->PciInfo->func); - /* Added version/rev/pl in sisfb 1.4.0 */ - if(mysisfbinfo.sisfb_version == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Old version of sisfb found. Please update\n"); - } - pSiS->sisfbMem = mysisfbinfo.heapstart; - /* Basically, we can't trust the pdc register if sisfb is loaded */ - pSiS->donttrustpdc = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "sisfb: memory heap starts at %dKB\n", (int)pSiS->sisfbMem); + /* Added version/rev/pl in sisfb 1.4.0 */ + if(mysisfbinfo->sisfb_version == 0) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Old version of sisfb found. Please update.\n"); + } + pSiS->sisfbMem = mysisfbinfo->heapstart; + /* Basically, we can't trust the pdc register if sisfb is loaded */ + pSiS->donttrustpdc = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "sisfb: memory heap starts at %dKB\n", (int)pSiS->sisfbMem); + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "sisfb: using video mode 0x%02x\n", mysisfbinfo->fbvidmode); + pSiS->OldMode = mysisfbinfo->fbvidmode; + if(sisfbversion >= 0x010506) { xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "sisfb: using video mode 0x%02x\n", mysisfbinfo.fbvidmode); - pSiS->OldMode = mysisfbinfo.fbvidmode; - if(sisfbversion >= 0x010506) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "sisfb: %sreserved hardware cursor, using %s command queue\n", - (mysisfbinfo.sisfb_caps & 0x80) ? "" : "not ", - (mysisfbinfo.sisfb_caps & 0x40) ? "SiS300 Turbo" : - (mysisfbinfo.sisfb_caps & 0x20) ? "SiS315/330 AGP" : - (mysisfbinfo.sisfb_caps & 0x10) ? "SiS315/330 VRAM" : - (mysisfbinfo.sisfb_caps & 0x08) ? "SiS315/330 MMIO" : + "sisfb: %sreserved HW cursor, using %s cmd queue\n", + (mysisfbinfo->sisfb_caps & 0x80) ? "" : "not ", + (mysisfbinfo->sisfb_caps & 0x40) ? "SiS300 Turbo" : + (mysisfbinfo->sisfb_caps & 0x20) ? "SiS315/330/340 AGP" : + (mysisfbinfo->sisfb_caps & 0x10) ? "SiS315/330/340 VRAM" : + (mysisfbinfo->sisfb_caps & 0x08) ? "SiS315/330/340 MMIO" : "no"); - } - if(sisfbversion >= 0x01050A) { - /* We can trust the pdc value if sisfb is of recent version */ - if(pSiS->VGAEngine == SIS_300_VGA) pSiS->donttrustpdc = FALSE; - if(sisfbversion >= 0x01050B) { - if(pSiS->VGAEngine == SIS_300_VGA) { - /* As of 1.5.11, sisfb saved the register for us (300 series) */ - pSiS->sisfbpdc = mysisfbinfo.sisfb_lcdpdc; - if(!pSiS->sisfbpdc) pSiS->sisfbpdc = 0xff; - } - } - if(sisfbversion >= 0x01050E) { - if(pSiS->VGAEngine == SIS_315_VGA) { - pSiS->sisfblcda = mysisfbinfo.sisfb_lcda; - } - if(sisfbversion >= 0x01060D) { - pSiS->sisfbscalelcd = mysisfbinfo.sisfb_scalelcd; - pSiS->sisfbspecialtiming = mysisfbinfo.sisfb_specialtiming; - } - if(sisfbversion >= 0x010610) { - if(pSiS->VGAEngine == SIS_315_VGA) { - pSiS->donttrustpdc = FALSE; - pSiS->sisfbpdc = mysisfbinfo.sisfb_lcdpdc; - if(sisfbversion >= 0x010618) { - pSiS->sisfb_haveemi = mysisfbinfo.sisfb_haveemi ? TRUE : FALSE; - pSiS->sisfb_haveemilcd = TRUE; /* will match most cases */ - pSiS->sisfb_emi30 = mysisfbinfo.sisfb_emi30; - pSiS->sisfb_emi31 = mysisfbinfo.sisfb_emi31; - pSiS->sisfb_emi32 = mysisfbinfo.sisfb_emi32; - pSiS->sisfb_emi33 = mysisfbinfo.sisfb_emi33; - } - if(sisfbversion >= 0x010619) { - pSiS->sisfb_haveemilcd = mysisfbinfo.sisfb_haveemilcd ? TRUE : FALSE; - } - if(sisfbversion >= 0x01061f) { - pSiS->sisfbpdca = mysisfbinfo.sisfb_lcdpdca; - } else { - if(pSiS->sisfbpdc) { - pSiS->sisfbpdca = (pSiS->sisfbpdc & 0xf0) >> 3; - pSiS->sisfbpdc = (pSiS->sisfbpdc & 0x0f) << 1; - } else { - pSiS->sisfbpdca = pSiS->sisfbpdc = 0xff; - } - } - } + } + if(sisfbversion >= 0x01050A) { + /* We can trust the pdc value if sisfb is of recent version */ + if(pSiS->VGAEngine == SIS_300_VGA) pSiS->donttrustpdc = FALSE; + } + if(sisfbversion >= 0x01050B) { + if(pSiS->VGAEngine == SIS_300_VGA) { + /* As of 1.5.11, sisfb saved the register for us (300 series) */ + pSiS->sisfbpdc = mysisfbinfo->sisfb_lcdpdc; + if(!pSiS->sisfbpdc) pSiS->sisfbpdc = 0xff; + } + } + if(sisfbversion >= 0x01050E) { + if(pSiS->VGAEngine == SIS_315_VGA) { + pSiS->sisfblcda = mysisfbinfo->sisfb_lcda; + } + } + if(sisfbversion >= 0x01060D) { + pSiS->sisfbscalelcd = mysisfbinfo->sisfb_scalelcd; + pSiS->sisfbspecialtiming = mysisfbinfo->sisfb_specialtiming; + } + if(sisfbversion >= 0x010610) { + if(pSiS->VGAEngine == SIS_315_VGA) { + pSiS->donttrustpdc = FALSE; + pSiS->sisfbpdc = mysisfbinfo->sisfb_lcdpdc; + if(sisfbversion >= 0x010618) { + pSiS->sisfb_haveemi = mysisfbinfo->sisfb_haveemi ? TRUE : FALSE; + pSiS->sisfb_haveemilcd = TRUE; /* will match most cases */ + pSiS->sisfb_emi30 = mysisfbinfo->sisfb_emi30; + pSiS->sisfb_emi31 = mysisfbinfo->sisfb_emi31; + pSiS->sisfb_emi32 = mysisfbinfo->sisfb_emi32; + pSiS->sisfb_emi33 = mysisfbinfo->sisfb_emi33; + } + if(sisfbversion >= 0x010619) { + pSiS->sisfb_haveemilcd = mysisfbinfo->sisfb_haveemilcd ? TRUE : FALSE; + } + if(sisfbversion >= 0x01061f) { + pSiS->sisfbpdca = mysisfbinfo->sisfb_lcdpdca; + } else { + if(pSiS->sisfbpdc) { + pSiS->sisfbpdca = (pSiS->sisfbpdc & 0xf0) >> 3; + pSiS->sisfbpdc = (pSiS->sisfbpdc & 0x0f) << 1; + } else { + pSiS->sisfbpdca = pSiS->sisfbpdc = 0xff; } - } - } + } + } } - } + if(sisfbversion >= 0x010700) { + pSiS->sisfb_havelock = TRUE; + if(sisfbversion >= 0x010701) { + pSiS->sisfb_tvxpos = mysisfbinfo->sisfb_tvxpos; + pSiS->sisfb_tvypos = mysisfbinfo->sisfb_tvypos; + pSiS->sisfb_tvposvalid = TRUE; + } + } + } } - close (fd); - } - i++; - } while((i <= 7) && (!pSiS->sisfbfound)); - if(!pSiS->sisfbfound) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "sisfb not found\n"); + xfree(mysisfbinfo); + mysisfbinfo = NULL; + } + close (fd); + } + i++; + } while((i <= 15) && (!pSiS->sisfbfound)); + + if(pSiS->sisfbfound) { + strncpy(pSiS->sisfbdevname, name, 15); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "sisfb not found\n"); } } - + /* * The first thing we should figure out is the depth, bpp, etc. + * Set SupportConvert... flags since we use the fb layer which + * supports this conversion. (24to32 seems not implemented though) * Additionally, determine the size of the HWCursor memory area. */ switch(pSiS->VGAEngine) { @@ -2848,12 +3017,15 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) break; case SIS_530_VGA: pSiS->CursorSize = 2048; - pix24flags = Support32bppFb | - Support24bppFb; + pix24flags = Support32bppFb | + Support24bppFb | + SupportConvert32to24; break; default: pSiS->CursorSize = 2048; - pix24flags = Support24bppFb; + pix24flags = Support24bppFb | + SupportConvert32to24 | + PreferConvert32to24; break; } @@ -2942,7 +3114,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } /* Get our relocated IO registers */ - pSiS->RelIO = (SISIOADDRESS)((pSiS->PciInfo->ioBase[2] & 0xFFFC) + pSiS->IODBase); + pSiS->RelIO = (SISIOADDRESS)(pSiS->PciInfo->ioBase[2] + pSiS->IODBase); pSiS->sishw_ext.ulIOAddress = (SISIOADDRESS)(pSiS->RelIO + 0x30); xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n", (unsigned long)pSiS->RelIO); @@ -3168,7 +3340,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) /* Unlock registers */ sisSaveUnlockExtRegisterLock(pSiS, &srlockReg, &crlockReg); - /* Read BIOS for 300 and 315/330 series customization */ + /* Read BIOS for 300 and 315/330/340 series customization */ pSiS->sishw_ext.pjVirtualRomBase = NULL; pSiS->BIOS = NULL; pSiS->sishw_ext.UseROM = FALSE; @@ -3190,33 +3362,37 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) "Could not allocate memory for video BIOS image\n"); } else { unsigned long segstart; - unsigned short romptr, pciid; - BOOLEAN found; - - found = FALSE; - for(segstart=BIOS_BASE; segstart<0x000f0000; segstart+=0x00001000) { + unsigned short mypciid = pSiS->Chipset; + BOOLEAN found = FALSE, readpci = FALSE; + + switch(pSiS->sishw_ext.jChipType) { + case SIS_300: readpci = TRUE; break; + case SIS_315: mypciid = PCI_CHIP_SIS315; readpci = TRUE; break; + case SIS_315PRO: mypciid = PCI_CHIP_SIS315PRO; readpci = TRUE; break; + case SIS_315H: readpci = TRUE; break; + case SIS_330: readpci = TRUE; break; + case SIS_340: readpci = TRUE; break; + } + + if(readpci) { + xf86ReadPciBIOS(0, pSiS->PciTag, 0, pSiS->BIOS, BIOS_SIZE); + if(SISCheckBIOS(pSiS, mypciid)) found = TRUE; + } + + if(!found) { + for(segstart=BIOS_BASE; segstart<0x000f0000; segstart+=0x00001000) { #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) - if(xf86ReadBIOS(segstart, 0, pSiS->BIOS, BIOS_SIZE) != BIOS_SIZE) continue; + if(xf86ReadBIOS(segstart, 0, pSiS->BIOS, BIOS_SIZE) != BIOS_SIZE) continue; #else - if(xf86ReadDomainMemory(pSiS->PciTag, segstart, BIOS_SIZE, pSiS->BIOS) != BIOS_SIZE) continue; + if(xf86ReadDomainMemory(pSiS->PciTag, segstart, BIOS_SIZE, pSiS->BIOS) != BIOS_SIZE) continue; #endif - if((pSiS->BIOS[0] != 0x55) || (pSiS->BIOS[1] != 0xaa)) continue; - - romptr = pSiS->BIOS[0x18] | (pSiS->BIOS[0x19] << 8); - if(romptr > (BIOS_SIZE - 8)) continue; - if((pSiS->BIOS[romptr] != 'P') || (pSiS->BIOS[romptr+1] != 'C') || - (pSiS->BIOS[romptr+2] != 'I') || (pSiS->BIOS[romptr+3] != 'R')) continue; - - pciid = pSiS->BIOS[romptr+4] | (pSiS->BIOS[romptr+5] << 8); - if(pciid != 0x1039) continue; + if(!SISCheckBIOS(pSiS, mypciid)) continue; - pciid = pSiS->BIOS[romptr+6] | (pSiS->BIOS[romptr+7] << 8); - if(pciid != pSiS->Chipset) continue; - - found = TRUE; - break; + found = TRUE; + break; + } } if(!found) { @@ -3225,12 +3401,13 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) xfree(pSiS->BIOS); pSiS->BIOS = NULL; } else { + unsigned short romptr; pSiS->sishw_ext.pjVirtualRomBase = pSiS->BIOS; pSiS->ROM661New = SiSDetermineROMLayout661(pSiS->SiS_Pr,&pSiS->sishw_ext); romptr = pSiS->BIOS[0x16] | (pSiS->BIOS[0x17] << 8); xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Video BIOS version \"%7s\" found at 0x%lx (%s data layout)\n", - &pSiS->BIOS[romptr], segstart, pSiS->ROM661New ? "new" : "old"); + "Video BIOS version \"%7s\" found (%s data layout)\n", + &pSiS->BIOS[romptr], pSiS->ROM661New ? "new" : "old"); #ifdef SISDUALHEAD if(pSiSEnt) { pSiSEnt->BIOS = pSiS->BIOS; @@ -3311,6 +3488,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiSEnt->AllowHotkey = pSiS->AllowHotkey; pSiSEnt->enablesisctrl = pSiS->enablesisctrl; pSiSEnt->SenseYPbPr = pSiS->SenseYPbPr; + pSiSEnt->XvDefAdaptorBlit = pSiS->XvDefAdaptorBlit; #ifdef SIS_CP SIS_CP_DRIVER_COPYOPTIONSENT #endif @@ -3391,7 +3569,8 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } pSiS->XvOnCRT2 = pSiSEnt->XvOnCRT2; pSiS->enablesisctrl = pSiSEnt->enablesisctrl; - /* Copy gamma brightness to Ent for Xinerama */ + pSiS->XvDefAdaptorBlit = pSiSEnt->XvDefAdaptorBlit; + /* Copy gamma brightness to Ent (sic!) for Xinerama */ pSiSEnt->GammaBriR = pSiS->GammaBriR; pSiSEnt->GammaBriG = pSiS->GammaBriG; pSiSEnt->GammaBriB = pSiS->GammaBriB; @@ -3513,7 +3692,6 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->FbMapSize = pSiS->availMem = pScrn->videoRam * 1024; pSiS->sishw_ext.ulVideoMemorySize = pScrn->videoRam * 1024; - pSiS->sishw_ext.bSkipDramSizing = TRUE; /* Calculate real availMem according to Accel/TurboQueue and * HWCursur setting. Also, initialize some variables used @@ -3692,8 +3870,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->ChipFlags |= SiSCF_LARGEOVERLAY; break; case PCI_CHIP_SIS330: - pSiS->ChipFlags |= SiSCF_LARGEOVERLAY; pSiS->ChipFlags |= SiSCF_CRT2HWCKaputt; + /* Fall through */ + case PCI_CHIP_SIS340: + pSiS->ChipFlags |= SiSCF_LARGEOVERLAY; break; case PCI_CHIP_SIS660: { @@ -3849,7 +4029,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) int i = 0, j; unsigned short bversptr = 0; BOOLEAN footprint; - unsigned long chksum = 0; + CARD32 chksum = 0; if(pSiS->sishw_ext.UseROM) { bversptr = pSiS->BIOS[0x16] | (pSiS->BIOS[0x17] << 8); @@ -3907,7 +4087,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) SISCRT1PreInit(pScrn); /* Detect LCD (connected via CRT2, regardless of LCDA) and LCD resolution */ - SISLCDPreInit(pScrn); + SISLCDPreInit(pScrn, FALSE); /* LCDA only supported under these conditions: */ if(pSiS->ForceCRT1Type == CRT1_LCDA) { @@ -3944,28 +4124,32 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } #endif - if(pSiS->VBFlags & CRT2_LCD) { - if((pSiS->VGAEngine != SIS_300_VGA) || (!(pSiS->VBFlags & VB_TRUMPION))) { - pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTSCALE; - if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B|VB_301C)) { - pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTCENTER; - } + if((pSiS->VGAEngine != SIS_300_VGA) || (!(pSiS->VBFlags & VB_TRUMPION))) { + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTSCALE; + if(pSiS->VBFlags & (VB_301|VB_301B|VB_302B|VB_301C)) { + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTCENTER; } } + +#ifdef SISDUALHEAD + if(!pSiS->DualHeadMode) { + pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTREDETECT; + } +#endif -#ifdef TWDEBUG /* @@@ TEST @@@ */ +#ifdef TWDEBUG /* FOR TESTING */ pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTYPBPRAR; xf86DrvMsg(0, X_INFO, "TEST: Support Aspect Ratio\n"); #endif /* Detect CRT2-TV and PAL/NTSC mode */ - SISTVPreInit(pScrn); + SISTVPreInit(pScrn, FALSE); /* Detect CRT2-VGA */ - SISCRT2PreInit(pScrn); + SISCRT2PreInit(pScrn, FALSE); /* Backup detected CRT2 devices */ - pSiS->detectedCRT2Devices = pSiS->VBFlags & (CRT2_LCD|CRT2_TV|CRT2_VGA|TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR); + SISSaveDetectedDevices(pScrn); if(!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTYPBPR)) { if((pSiS->ForceTVType != -1) && (pSiS->ForceTVType & TV_YPBPR)) { @@ -3999,14 +4183,10 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } } - if( ((pSiS->sishw_ext.jChipType == SIS_650) || - (pSiS->sishw_ext.jChipType >= SIS_661)) && - (pSiS->VBFlags & (VB_301C | VB_302B | VB_301LV | VB_302LV)) && - (pSiS->VBFlags & CRT2_LCD) && - (pSiS->VESA != 1) ) { - pSiS->SiS_SD_Flags |= SiS_SD_SUPPORTLCDA; - } else { - /* Paranoia */ + SISDetermineLCDACap(pScrn); + if((!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTLCDA)) || + (!(pSiS->VBFlags & CRT2_LCD))) { + /* No LCDA if not supported or no LCD panel found */ pSiS->ForceCRT1Type = CRT1_VGA; } @@ -4028,7 +4208,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) pSiS->ForceCRT2Type = CRT2_LCD; else if(pSiS->VBFlags & CRT2_TV) pSiS->ForceCRT2Type = CRT2_TV; - else if(pSiS->VBFlags & CRT2_VGA) + else if((pSiS->VBFlags & CRT2_VGA) && (pSiS->ForceCRT1Type == CRT1_VGA)) pSiS->ForceCRT2Type = CRT2_VGA; } @@ -4086,7 +4266,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) (float)((float)pSiS->XvGammaBlue / 1000)); if(!pSiS->CRT1gamma) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Separate Xv gamma corr. only effective if CRT1 gamma corr. is enabled\n"); + "Xv gamma correction only effective if CRT1 gamma corr. is enabled\n"); } } } @@ -4689,7 +4869,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) } /* Now for something completely different: DDC. - * For 300 and 315/330 series, we provide our + * For 300 and 315/330/340 series, we provide our * own functions (in order to probe CRT2 as well) * If these fail, use the VBE. * All other chipsets will use VBE. No need to re-invent @@ -4925,7 +5105,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) clockRanges->doubleScanAllowed = TRUE; /* - * Since we have lots of built-in modes for 300/315/330 series + * Since we have lots of built-in modes for 300/315/330/340 series * with vb support, we replace the given default mode list with our * own. In case the video bridge is to be used, we only allow other * modes if @@ -4996,7 +5176,7 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) #endif } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Building list of built-in modes failed, using X.Org defaults\n"); + "Building list of built-in modes failed, using server defaults\n"); } } else { pSiS->HaveCustomModes = TRUE; @@ -5499,9 +5679,74 @@ SISPreInit(ScrnInfoPtr pScrn, int flags) return TRUE; } +/* + * Map I/O port area for non-PC platforms + */ +#ifdef SIS_NEED_MAP_IOP +static Bool +SISMapIOPMem(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + + if(pSiS->DualHeadMode) { + pSiSEnt->MapCountIOPBase++; + if(!(pSiSEnt->IOPBase)) { + /* Only map if not mapped previously */ + pSiSEnt->IOPBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pSiS->PciTag, pSiS->IOPAddress, 128); + } + pSiS->IOPBase = pSiSEnt->IOPBase; + } else +#endif + pSiS->IOPBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, + pSiS->PciTag, pSiS->IOPAddress, 128); + + if(pSiS->IOPBase == NULL) { + SISErrorLog(pScrn, "Could not map I/O port area\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +SISUnmapIOPMem(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate;; +#endif + +/* In dual head mode, we must not unmap if the other head still + * assumes memory as mapped + */ +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) { + if(pSiSEnt->MapCountIOPBase) { + pSiSEnt->MapCountIOPBase--; + if((pSiSEnt->MapCountIOPBase == 0) || (pSiSEnt->forceUnmapIOPBase)) { + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->IOPBase, 2048); + pSiSEnt->IOPBase = NULL; + pSiSEnt->MapCountIOPBase = 0; + pSiSEnt->forceUnmapIOPBase = FALSE; + } + pSiS->IOPBase = NULL; + } + } else { +#endif + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOPBase, 2048); + pSiS->IOPBase = NULL; +#ifdef SISDUALHEAD + } +#endif + return TRUE; +} +#endif /* - * Map the framebuffer and MMIO memory. + * Map the framebuffer and MMIO memory */ static Bool @@ -5700,21 +5945,24 @@ SISSave(ScrnInfoPtr pScrn) vgaReg = &VGAHWPTR(pScrn)->SavedReg; sisReg = &pSiS->SavedReg; - if((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) { - if((pSiS->VBFlags & VB_VIDEOBRIDGE) && (SiSBridgeIsInSlaveMode(pScrn))) { - vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE); - SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30); - SiSSetLVDSetc(pSiS->SiS_Pr, &pSiS->sishw_ext, 0); - SiS_GetVBType(pSiS->SiS_Pr, &pSiS->sishw_ext); - SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); - vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS); - SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); - } else { - vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); - } + if( ((pSiS->VGAEngine == SIS_300_VGA) || (pSiS->VGAEngine == SIS_315_VGA)) && + ((pSiS->VBFlags & VB_VIDEOBRIDGE) && (SiSBridgeIsInSlaveMode(pScrn))) ) { + vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE); +#ifdef SIS_PC_PLATFORM + SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30); + SiSSetLVDSetc(pSiS->SiS_Pr, &pSiS->sishw_ext, 0); + SiS_GetVBType(pSiS->SiS_Pr, &pSiS->sishw_ext); + SiS_DisableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); + vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS); + SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); +#endif } else { +#ifdef SIS_PC_PLATFORM vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); - } +#else + vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE); +#endif + } sisSaveUnlockExtRegisterLock(pSiS,&sisReg->sisRegs3C4[0x05],&sisReg->sisRegs3D4[0x80]); @@ -5736,6 +5984,7 @@ SISSave(ScrnInfoPtr pScrn) } } +#ifdef SIS_PC_PLATFORM static void SiS_WriteAttr(SISPtr pSiS, int index, int value) { @@ -5753,12 +6002,14 @@ SiS_ReadAttr(SISPtr pSiS, int index) outb(pSiS->IODBase + VGA_ATTR_INDEX, index); return(inb(pSiS->IODBase + VGA_ATTR_DATA_R)); } +#endif #define SIS_FONTS_SIZE (8 * 8192) static void SiS_SaveFonts(ScrnInfoPtr pScrn) { +#ifdef SIS_PC_PLATFORM SISPtr pSiS = SISPTR(pScrn); unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4, scrn; #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) @@ -5826,11 +6077,13 @@ SiS_SaveFonts(ScrnInfoPtr pScrn) outSISIDXREG(SISGR, 0x05, gr5); outSISIDXREG(SISGR, 0x06, gr6); outSISREG(SISMISCW, miscOut); +#endif } static void SiS_RestoreFonts(ScrnInfoPtr pScrn) { +#ifdef SIS_PC_PLATFORM SISPtr pSiS = SISPTR(pScrn); unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4, scrn; #if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,99,0,0) @@ -5897,6 +6150,7 @@ SiS_RestoreFonts(ScrnInfoPtr pScrn) outSISIDXREG(SISGR, 0x08, gr8); outSISIDXREG(SISSR, 0x02, seq2); outSISIDXREG(SISSR, 0x04, seq4); +#endif } #undef SIS_FONTS_SIZE @@ -6141,7 +6395,7 @@ SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) } /* Reset our PIOOffset as vgaHWInit might have reset it */ - VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380; + VGAHWPTR(pScrn)->PIOOffset = pSiS->MyPIOOffset; /* Prepare the register contents */ if(!(*pSiS->ModeInit)(pScrn, mode)) { @@ -6285,6 +6539,70 @@ SISSpecialRestore(ScrnInfoPtr pScrn) } } +/* Fix SR11 for 661 and later */ +static void +SiSFixupSR11(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + CARD8 tmpreg; + +#ifdef UNLOCK_ALWAYS + sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); +#endif + + if(pSiS->sishw_ext.jChipType >= SIS_661) { + inSISIDXREG(SISSR,0x11,tmpreg); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SiSFixupSR11(): SR11 reads %02x\n", tmpreg); +#endif + if(tmpreg & 0x20) { + inSISIDXREG(SISSR,0x3e,tmpreg); +#ifdef TWDEBUG + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SiSFixupSR11(): SR3e reads %02x\n", tmpreg); +#endif + tmpreg = (tmpreg + 1) & 0xff; + outSISIDXREG(SISSR,0x3e,tmpreg); +#ifdef TWDEBUG + inSISIDXREG(SISSR,0x3e,tmpreg); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SiSFixupSR11(): SR3e reads %02x after writing\n", tmpreg); +#endif + } + + inSISIDXREG(SISSR,0x11,tmpreg); + if(tmpreg & 0xf0) { + andSISIDXREG(SISSR,0x11,0x0f); + } +#ifdef TWDEBUG + inSISIDXREG(SISSR,0x11,tmpreg); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "SiSFixupSR11(): SR11 reads %02x after AND 0x0f\n", tmpreg); +#endif + } +} + +/* Subroutine for restoring sisfb's TV parameters (used by SiSRestore()) */ + +static void +SiSRestore_SiSFB_TVParms(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + int fd; + CARD32 parm; + + if(!pSiS->sisfbfound) return; + if(!pSiS->sisfb_tvposvalid) return; + if(!(pSiS->sisfbdevname[0])) return; + + if((fd = open(pSiS->sisfbdevname, 'r')) != -1) { + parm = (CARD32)((pSiS->sisfb_tvxpos << 16) | (pSiS->sisfb_tvypos & 0xffff)); + ioctl(fd, SISFB_SET_TVPOSOFFSET, &parm); + close(fd); + } +} + /* * Restore the initial mode. To be used internally only! */ @@ -6416,6 +6734,9 @@ SISRestore(ScrnInfoPtr pScrn) pSiS->SiS_Pr->UsePanelScaler = backupscaler; pSiS->SiS_Pr->CenterScreen = backupcenter; pSiS->SiS_Pr->SiS_CustomT = backupspecialtiming; + SiS_SiSFB_Lock(pScrn, FALSE); + SiSRestore_SiSFB_TVParms(pScrn); + SiS_SiSFB_Lock(pScrn, TRUE); } @@ -6426,7 +6747,7 @@ SISRestore(ScrnInfoPtr pScrn) outSISIDXREG(SISSR, 0x1f, pSiS->oldSR1F); #ifdef SISVRAMQ - /* Restore queue mode registers on 315/330 series */ + /* Restore queue mode registers on 315/330/340 series */ /* (This became necessary due to the switch to VRAM queue) */ if(pSiS->VGAEngine == SIS_315_VGA) { unsigned char tempCR55=0; @@ -6467,7 +6788,7 @@ SISRestore(ScrnInfoPtr pScrn) } if(doitlater) { - outSISIDXREG(SISCR, 0x17, pSiS->oldCR17); + outSISIDXREG(SISCR, 0x17, pSiS->oldCR17); } if(pSiS->Primary) { @@ -6477,6 +6798,7 @@ SISRestore(ScrnInfoPtr pScrn) * so this is the only safe way: Disable the bridge ONLY if * in Slave Mode, and don't bother if not. */ +#ifdef SIS_PC_PLATFORM SiSRegInit(pSiS->SiS_Pr, pSiS->RelIO+0x30); SiSSetLVDSetc(pSiS->SiS_Pr, &pSiS->sishw_ext, 0); SiS_GetVBType(pSiS->SiS_Pr, &pSiS->sishw_ext); @@ -6485,22 +6807,32 @@ SISRestore(ScrnInfoPtr pScrn) vgaHWProtect(pScrn, TRUE); /* We now restore ALL to overcome the vga=extended problem */ + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); - + vgaHWProtect(pScrn, FALSE); SiS_EnableBridge(pSiS->SiS_Pr, &pSiS->sishw_ext); andSISIDXREG(SISSR, 0x01, ~0x20); /* Display on */ +#else + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP); +#endif } else { vgaHWProtect(pScrn, TRUE); /* We now restore ALL to overcome the vga=extended problem */ +#ifdef SIS_PC_PLATFORM vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); +#else + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP); +#endif vgaHWProtect(pScrn, FALSE); } } - + + SiSFixupSR11(pScrn); + #ifdef TWDEBUG { SISRegPtr pReg = &pSiS->ModeReg; @@ -6524,7 +6856,11 @@ SISRestore(ScrnInfoPtr pScrn) vgaHWProtect(pScrn, TRUE); if(pSiS->Primary) { - vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); +#ifdef SIS_PC_PLATFORM + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); +#else + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP); +#endif } /* Restore TV. This is rather complicated, but if we don't do it, @@ -6573,7 +6909,7 @@ SISVESARestore(ScrnInfoPtr pScrn) if(pSiS->UseVESA) { SISVESASaveRestore(pScrn, MODE_RESTORE); #ifdef SISVRAMQ - /* Restore queue mode registers on 315/330 series */ + /* Restore queue mode registers on 315/330/340 series */ /* (This became necessary due to the switch to VRAM queue) */ if(pSiS->VGAEngine == SIS_315_VGA) { SISRegPtr sisReg = &pSiS->SavedReg; @@ -6659,6 +6995,9 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) hwp = VGAHWPTR(pScrn); pSiS = SISPTR(pScrn); + + /* Patch the PIOOffset inside vgaHW to use our relocated IO ports */ + VGAHWPTR(pScrn)->PIOOffset = pSiS->MyPIOOffset; #ifdef SISDUALHEAD if((!pSiS->DualHeadMode) || (!pSiS->SecondHead)) { @@ -6685,7 +7024,8 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif - /* Map the VGA memory and get the VGA IO base */ + /* Map the 64k VGA memory */ +#ifdef SIS_PC_PLATFORM if(pSiS->Primary) { hwp->MapSize = 0x10000; /* Standard 64k VGA window */ if(!vgaHWMapMem(pScrn)) { @@ -6693,18 +7033,18 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } } +#endif + + /* Get the VGA IO base (relocated) */ vgaHWGetIOBase(hwp); - - /* Patch the PIOOffset inside vgaHW to use - * our relocated IO ports. - */ - VGAHWPTR(pScrn)->PIOOffset = pSiS->IODBase + (pSiS->PciInfo->ioBase[2] & 0xFFFC) - 0x380; /* Map the SIS memory and MMIO areas */ if(!SISMapMem(pScrn)) { SISErrorLog(pScrn, "SiSMapMem() failed\n"); return FALSE; } + + SiS_SiSFB_Lock(pScrn, TRUE); #ifdef UNLOCK_ALWAYS sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); @@ -6721,7 +7061,6 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if(pSiS->VGAEngine != SIS_315_VGA) #endif SiSEnableTurboQueue(pScrn); - } /* Save the current state */ @@ -7024,7 +7363,7 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using SiS300/315 series HW Xv on CRT%d\n", + "Using SiS300/315/330/340 series HW Xv on CRT%d\n", (pSiS->SecondHead ? 1 : 2)); if(!pSiS->hasTwoOverlays) { if( (pSiS->XvOnCRT2 && pSiS->SecondHead) || @@ -7039,15 +7378,20 @@ SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif if(pSiS->hasTwoOverlays) xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using SiS300/315/330 series HW Xv\n" ); + "Using SiS300/315/330/340 series HW Xv\n" ); else xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using SiS300/315/330 series HW Xv by default on CRT%d\n", + "Using SiS300/315/330/340 series HW Xv by default on CRT%d\n", (pSiS->XvOnCRT2 ? 2 : 1)); SISInitVideo(pScreen); #ifdef SISDUALHEAD } #endif + if(pSiS->blitadaptor) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Default Xv adaptor is %s\n", + pSiS->XvDefAdaptorBlit ? "Video Blitter" : "Video Overlay"); + } } else if( pSiS->Chipset == PCI_CHIP_SIS6326 || pSiS->Chipset == PCI_CHIP_SIS530 || pSiS->Chipset == PCI_CHIP_SIS5597 ) { @@ -7209,8 +7553,21 @@ SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags) DisplayModePtr mode = pScrn->currentMode; /* Do NOT use this to switch from CRT2_LCD to CRT1_LCDA */ + /* Switching CRT2 to LCD or VGA will switch CRT1 to VGA if + * previously LCD-via-CRT1 + */ + /* For usability reasons, the user should not simply "lose" one + * of his output devices in MergedFB mode. Therefore, a switch + * which might lead to this situation will not be performed in + * MergedFB mode. (For example: If CRT1 is LCD-via-CRT1, don't + * let the user switch CRT2 to LCD or VGA mode, because he + * would lose one output device since LCD-via-CRT1 is only + * supported together with TV, not any other CRT2 type.) + * In Non-MergedFB mode, losing one output device is not + * considered that harmful. + */ - /* Only on 300 and 315/330 series */ + /* Only on 300 and 315/330/340 series */ if(pSiS->VGAEngine != SIS_300_VGA && pSiS->VGAEngine != SIS_315_VGA) return FALSE; @@ -7242,9 +7599,14 @@ SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags) if(pSiS->MergedFB) { if(!(newvbflags & CRT2_ENABLE)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "CRT2 can't be switched off in MergedFB mode\n"); + "CRT2 can't be switched off in MergedFB mode\n"); return FALSE; } + if((newvbflags & (CRT2_LCD|CRT2_VGA)) && (newvbflags & CRT1_LCDA)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "CRT2 type can only be TV while in LCD-via-CRT1 mode\n"); + return FALSE; + } hcm = pSiS->HaveCustomModes2; if(mode->Private) { mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2; @@ -7258,9 +7620,9 @@ SISSwitchCRT2Type(ScrnInfoPtr pScrn, unsigned long newvbflags) "CRT2 can't be switched off while CRT1 is off\n"); return FALSE; } - - /* CRT2_LCD overrules LCDA */ - if(newvbflags & CRT2_LCD) { + + /* CRT2_LCD and CRT2_VGA overrule LCDA (in non-MergedFB mode) */ + if(newvbflags & (CRT2_LCD|CRT2_VGA)) { newvbflags &= ~CRT1_LCDA; } @@ -7436,6 +7798,47 @@ SISCheckModeIndexForCRT2Type(ScrnInfoPtr pScrn, unsigned short cond, unsigned sh } Bool +SISRedetectCRT2Devices(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + + if((pSiS->VGAEngine != SIS_300_VGA) && (pSiS->VGAEngine != SIS_315_VGA)) { + return FALSE; + } + +#ifdef SISDUALHEAD + if(pSiS->DualHeadMode) return FALSE; +#endif + + /* Sync the accelerators */ + if(!pSiS->NoAccel) { + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->Sync)(pScrn); + } + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Redetection of CRT2 devices initiated...\n"); + + if(SISRedetectCRT2Type(pScrn)) { + /* If this returns TRUE, we need to reset the display mode */ + /* Sync the accelerators */ + if(!pSiS->NoAccel) { + if(pSiS->AccelInfoPtr) { + (*pSiS->AccelInfoPtr->Sync)(pScrn); + } + } + if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) return FALSE; + SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Redetection of CRT2 devices finished\n"); + + return TRUE; +} + +Bool SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) { SISPtr pSiS = SISPTR(pScrn); @@ -7444,11 +7847,21 @@ SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) int crt1off; /* onoff: 0=OFF, 1=ON(VGA), 2=ON(LCDA) */ - /* Switching to LCDA will disable CRT2 if previously LCD */ + /* Switching to LCDA will disable CRT2 if previously LCD or VGA */ + /* For usability reasons, the user should not simply "lose" one + * of his output devices in MergedFB mode. Therefore, a switch + * which might lead to this situation will not be performed in + * MergedFB mode. (For example: If CRT2 is either LCD or VGA, + * don't let the user switch to LCD-via-CRT1 mode, because he + * would lose one output device since LCD-via-CRT1 is only + * supported together with TV, not any other CRT2 type.) + * In Non-MergedFB mode, losing one output device is not + * considered that harmful. + */ /* Do NOT use this to switch from CRT1_LCDA to CRT2_LCD */ - /* Only on 300 and 315/330 series */ + /* Only on 300 and 315/330/340 series */ if(pSiS->VGAEngine != SIS_300_VGA && pSiS->VGAEngine != SIS_315_VGA) return FALSE; @@ -7463,7 +7876,7 @@ SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) if(!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTLCDA)) { if(onoff == 2) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "LCD-via-CRT1 not supported on this hardware\n"); + "LCD-via-CRT1 not supported by hardware or no panel detected\n"); return FALSE; } } @@ -7472,12 +7885,12 @@ SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) if(pSiS->MergedFB) { if(!onoff) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "CRT1 can't be switched off in MergedFB mode\n"); + "CRT1 can't be switched off in MergedFB mode\n"); return FALSE; } else if(onoff == 2) { - if(vbflags & CRT2_LCD) { + if(vbflags & (CRT2_LCD|CRT2_VGA)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "CRT2 type can't be LCD while CRT1 is LCD-via-CRT1\n"); + "CRT1 type can only be VGA while CRT2 is LCD or VGA\n"); return FALSE; } } @@ -7494,7 +7907,7 @@ SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff) crt1off = 0; if(onoff == 2) { vbflags |= CRT1_LCDA; - vbflags &= ~CRT2_LCD; + vbflags &= ~(CRT2_LCD|CRT2_VGA); } /* Remember: Dualhead not supported */ if(vbflags & CRT2_ENABLE) vbflags |= MIRROR_MODE; @@ -7901,6 +8314,8 @@ SISEnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; SISPtr pSiS = SISPTR(pScrn); + + SiS_SiSFB_Lock(pScrn, TRUE); sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); @@ -8005,6 +8420,8 @@ SISLeaveVT(int scrnIndex, int flags) } vgaHWLock(hwp); + + SiS_SiSFB_Lock(pScrn, FALSE); } @@ -8073,6 +8490,8 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen) vgaHWLock(hwp); } + + SiS_SiSFB_Lock(pScrn, FALSE); /* We should restore the mode number in case vtsema = false as well, * but since we haven't register access then we can't do it. I think @@ -8082,7 +8501,9 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen) */ SISUnmapMem(pScrn); +#ifdef SIS_PC_PLATFORM vgaHWUnmapMem(pScrn); +#endif #ifdef SISDUALHEAD if(pSiS->DualHeadMode) { @@ -8126,6 +8547,11 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen) pSiS->adaptor = NULL; pSiS->ResetXv = pSiS->ResetXvGamma = NULL; } + + if(pSiS->blitadaptor) { + xfree(pSiS->blitadaptor); + pSiS->blitadaptor = NULL; + } pScrn->vtSema = FALSE; @@ -8144,6 +8570,21 @@ SISCloseScreen(int scrnIndex, ScreenPtr pScreen) static void SISFreeScreen(int scrnIndex, int flags) { +#ifdef SIS_NEED_MAP_IOP + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + SISPtr pSiS = SISPTR(pScrn); + + if(pSiS) { +#ifdef SISDUALHEAD + SISEntPtr pSiSEnt = pSiS->entityPrivate; + if(pSiSEnt) { + pSiSEnt->forceUnmapIOPBase = TRUE; + } +#endif + SISUnmapIOPMem(pScrn); + } +#endif + if(xf86LoaderCheckSymbol("vgaHWFreeHWRec")) { vgaHWFreeHWRec(xf86Screens[scrnIndex]); } @@ -8430,7 +8871,7 @@ SISModifyModeInfo(DisplayModePtr mode) mode->CrtcVBlankEnd--; } -/* Enable the Turboqueue/Commandqueue (For 300 and 315/330 series only) */ +/* Enable the Turboqueue/Commandqueue (For 300 and 315/330/340 series only) */ void SiSEnableTurboQueue(ScrnInfoPtr pScrn) { @@ -8454,7 +8895,7 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn) case SIS_315_VGA: if(!pSiS->NoAccel) { - /* On 315/330 series, there are three queue modes available + /* On 315/330/340 series, there are three queue modes available * which are chosen by setting bits 7:5 in SR26: * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep * track of the queue, the FIFO, command parsing and so @@ -8488,7 +8929,7 @@ SiSEnableTurboQueue(ScrnInfoPtr pScrn) /* Set Command Queue Threshold to max value 11111b (?) */ outSISIDXREG(SISSR, 0x27, 0x1F); - /* No idea what this does */ + /* Disable queue flipping */ if(pSiS->sishw_ext.jChipType <= SIS_330) { inSISIDXREG(SISCR, 0x55, tempCR55) ; andSISIDXREG(SISCR, 0x55, 0x33) ; @@ -8695,7 +9136,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) CR32 = pSiS->newCR32; inSISIDXREG(SISCR, 0x33, CR33); - if(pSiS->Chipset == PCI_CHIP_SIS660) { + if(pSiS->NewCRLayout) { inSISIDXREG(SISCR, 0x35, CR35); inSISIDXREG(SISCR, 0x38, CR38); @@ -8732,7 +9173,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) CR31 |= 0x04; /* Set VB_NotSimuMode (not for 30xB/1400x1050?) */ CR35 = 0x00; - if(pSiS->Chipset != PCI_CHIP_SIS660) { + if(!pSiS->NewCRLayout) { if(!pSiS->AllowHotkey) { CR31 |= 0x80; /* Disable hotkey-switch */ } @@ -8764,7 +9205,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) CR38 &= ~0x04; CR31 &= ~0x01; } else if(vbflag & TV_HIVISION) { /* SiS bridge */ - if(pSiS->Chipset == PCI_CHIP_SIS660) { + if(pSiS->NewCRLayout) { CR38 |= 0x04; CR35 |= 0x60; } else { @@ -8778,7 +9219,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) CR31 |= 0x01; CR35 |= 0x01; } else if(vbflag & TV_YPBPR) { /* SiS bridge */ - if(pSiS->Chipset == PCI_CHIP_SIS660) { + if(pSiS->NewCRLayout) { CR38 |= 0x04; if(vbflag & TV_YPBPR525P) CR35 |= 0x20; else if(vbflag & TV_YPBPR750P) CR35 |= 0x40; @@ -8961,7 +9402,7 @@ void SiSPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode) } } - if(pSiS->Chipset == PCI_CHIP_SIS660) { + if(pSiS->NewCRLayout) { CR31 &= 0xfe; /* Clear PAL flag (now in CR35) */ CR38 &= 0x07; /* Use only LCDA and HiVision/YPbPr bits */ @@ -10512,6 +10953,13 @@ void SiS_SetTVyscale(ScrnInfoPtr pScrn, int val) case 0x31: /* 720x480 */ case 0x33: case 0x35: + if(pSiS->VGAEngine == SIS_315_VGA) { + if(!usentsc) { + srindex = 21; + break; + } + } + /* fall through */ case 0x32: /* 720x576 */ case 0x34: case 0x36: @@ -10630,7 +11078,7 @@ void SiS_SetTVyscale(ScrnInfoPtr pScrn, int val) if(pSiS->VBFlags & (VB_301C|VB_302ELV)) { #ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "301C scaler: Table index %d\n"); + xf86DrvMsg(0, X_INFO, "301C scaler: Table index %d\n", srindex301c); #endif for(j=0; j<64; j++) { outSISIDXREG(SISPART2,(0xc0 + j), SiS301CScaling[srindex301c + j]); @@ -10733,14 +11181,7 @@ SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) sisSaveUnlockExtRegisterLock(pSiS, NULL, NULL); #endif - if(pSiS->sishw_ext.jChipType >= SIS_661) { - inSISIDXREG(SISSR,0x11,tmpreg); - if(tmpreg & 0x20) { - inSISIDXREG(SISSR,0x3e,tmpreg); - tmpreg = (tmpreg + 1) & 0xff; - outSISIDXREG(SISSR,0x3e,tmpreg); - } - } + SiSFixupSR11(pScrn); if((!pSiS->UseVESA) && (pSiS->VBFlags & CRT2_ENABLE)) { @@ -10850,6 +11291,7 @@ SiSPostSetMode(ScrnInfoPtr pScrn, SISRegPtr sisReg) case SIS_741: case SIS_660: case SIS_760: + case SIS_340: if(myclock < 180) { pSiS->MiscFlags |= MISC_CRT1OVERLAY; if(myclock < 166) { @@ -11379,7 +11821,7 @@ SiS_CheckCalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBF int j; #ifdef TWDEBUG - xf86DrvMsg(0, X_INFO, "Inside CheckCalcModeIndex (VBFlags %x, mode %dx%d)\n", + xf86DrvMsg(0, X_INFO, "Inside CheckCalcModeIndex (VBFlags %lx, mode %dx%d)\n", VBFlags,mode->HDisplay, mode->VDisplay); #endif @@ -11655,7 +12097,7 @@ unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value) { unsigned char ret = 0; -#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__)) +#ifdef SIS_USE_BIOS_SCRATCH unsigned char *base; base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000); @@ -11667,8 +12109,9 @@ SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value) ret = *(base + offset); /* value != 0xff means: set register */ - if(value != 0xff) + if(value != 0xff) { *(base + offset) = value; + } xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000); #endif @@ -11705,7 +12148,7 @@ sisSaveUnlockExtRegisterLock(SISPtr pSiS, unsigned char *reg1, unsigned char *re inSISIDXREG(SISSR, i, val1); inSISIDXREG(0x3c4, i, val2); xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, - "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n", + "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%ld)\n", i, val1, val2, mylockcalls); } #endif |