ark_driver.c revision 943345d3
1943345d3Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ark/ark_driver.c,v 1.22 2003/08/23 15:02:53 dawes Exp $ */ 2943345d3Smrg/* 3943345d3Smrg * Copyright 2000 Ani Joshi <ajoshi@unixbox.com> 4943345d3Smrg * 5943345d3Smrg * XFree86 4.x driver for ARK Logic chipset 6943345d3Smrg * 7943345d3Smrg * Permission to use, copy, modify, distribute, and sell this software and its 8943345d3Smrg * documentation for any purpose is hereby granted without fee, provided that 9943345d3Smrg * the above copyright notice appear in all copies and that both that copyright 10943345d3Smrg * notice and this permission notice appear in supporting documentation and 11943345d3Smrg * that the name of Ani Joshi not be used in advertising or 12943345d3Smrg * publicity pertaining to distribution of the software without specific, 13943345d3Smrg * written prior permission. Ani Joshi makes no representations 14943345d3Smrg * about the suitability of this software for any purpose. It is provided 15943345d3Smrg * "as-is" without express or implied warranty. 16943345d3Smrg * 17943345d3Smrg * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18943345d3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19943345d3Smrg * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20943345d3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21943345d3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22943345d3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23943345d3Smrg * PERFORMANCE OF THIS SOFTWARE. 24943345d3Smrg * 25943345d3Smrg * 26943345d3Smrg * Based on the 3.3.x driver by: 27943345d3Smrg * Harm Hanemaayer <H.Hanemaayer@inter.nl.net> 28943345d3Smrg * 29943345d3Smrg */ 30943345d3Smrg 31943345d3Smrg#ifdef HAVE_CONFIG_H 32943345d3Smrg#include "config.h" 33943345d3Smrg#endif 34943345d3Smrg 35943345d3Smrg#include "xf86.h" 36943345d3Smrg#include "xf86_OSproc.h" 37943345d3Smrg#include "xf86Pci.h" 38943345d3Smrg#include "xf86PciInfo.h" 39943345d3Smrg#include "xf86Version.h" 40943345d3Smrg#include "xf86Resources.h" 41943345d3Smrg#include "xf86fbman.h" 42943345d3Smrg#include "xf86cmap.h" 43943345d3Smrg#include "compiler.h" 44943345d3Smrg#include "xaa.h" 45943345d3Smrg#include "mipointer.h" 46943345d3Smrg#include "micmap.h" 47943345d3Smrg#include "mibstore.h" 48943345d3Smrg#include "fb.h" 49943345d3Smrg#include "ark.h" 50943345d3Smrg 51943345d3Smrg#include <string.h> 52943345d3Smrg 53943345d3Smrg/* 54943345d3Smrg * prototypes 55943345d3Smrg */ 56943345d3Smrgstatic const OptionInfoRec * ARKAvailableOptions(int chipid, int busid); 57943345d3Smrgstatic void ARKIdentify(int flags); 58943345d3Smrgstatic Bool ARKProbe(DriverPtr drv, int flags); 59943345d3Smrgstatic Bool ARKPreInit(ScrnInfoPtr pScrn, int flags); 60943345d3Smrgstatic Bool ARKEnterVT(int scrnIndex, int flags); 61943345d3Smrgstatic void ARKLeaveVT(int scrnIndex, int flags); 62943345d3Smrgstatic void ARKSave(ScrnInfoPtr pScrn); 63943345d3Smrgstatic Bool ARKScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 64943345d3Smrg char **argv); 65943345d3Smrgstatic Bool ARKMapMem(ScrnInfoPtr pScrn); 66943345d3Smrgstatic void ARKUnmapMem(ScrnInfoPtr pScrn); 67943345d3Smrgstatic Bool ARKModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 68943345d3Smrgstatic void ARKAdjustFrame(int scrnIndex, int x, int y, int flags); 69943345d3SmrgBool ARKSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); 70943345d3SmrgBool ARKCloseScreen(int scrnIndex, ScreenPtr pScreen); 71943345d3SmrgBool ARKSaveScreen(ScreenPtr pScreen, int mode); 72943345d3Smrgstatic void ARKFreeScreen(int scrnIndex, int flags); 73943345d3Smrgstatic void ARKLoadPalette(ScrnInfoPtr pScrn, int numColors, 74943345d3Smrg int *indicies, LOCO *colors, 75943345d3Smrg VisualPtr pVisual); 76943345d3Smrgstatic void ARKWriteMode(ScrnInfoPtr pScrn, vgaRegPtr pVga, ARKRegPtr new); 77943345d3Smrg 78943345d3Smrg/* helpers */ 79943345d3Smrgstatic unsigned char get_daccomm(IOADDRESS); 80943345d3Smrgstatic unsigned char set_daccom(IOADDRESS, unsigned char comm); 81943345d3Smrg 82943345d3Smrg 83943345d3Smrg_X_EXPORT DriverRec ARK = 84943345d3Smrg{ 85943345d3Smrg ARK_VERSION, 86943345d3Smrg DRIVER_NAME, 87943345d3Smrg ARKIdentify, 88943345d3Smrg ARKProbe, 89943345d3Smrg ARKAvailableOptions, 90943345d3Smrg NULL, 91943345d3Smrg 0 92943345d3Smrg}; 93943345d3Smrg 94943345d3Smrg/* supported chipsets */ 95943345d3Smrgstatic SymTabRec ARKChipsets[] = { 96943345d3Smrg { PCI_CHIP_1000PV, "ark1000pv" }, 97943345d3Smrg { PCI_CHIP_2000PV, "ark2000pv" }, 98943345d3Smrg { PCI_CHIP_2000MT, "ark2000mt" }, 99943345d3Smrg { -1, NULL } 100943345d3Smrg}; 101943345d3Smrg 102943345d3Smrgstatic PciChipsets ARKPciChipsets[] = { 103943345d3Smrg { PCI_CHIP_1000PV, PCI_CHIP_1000PV, RES_SHARED_VGA }, 104943345d3Smrg { PCI_CHIP_2000PV, PCI_CHIP_2000PV, RES_SHARED_VGA }, 105943345d3Smrg { PCI_CHIP_2000MT, PCI_CHIP_2000MT, RES_SHARED_VGA }, 106943345d3Smrg { -1, -1, RES_UNDEFINED } 107943345d3Smrg}; 108943345d3Smrg 109943345d3Smrgtypedef enum { 110943345d3Smrg OPTION_NOACCEL 111943345d3Smrg} ARKOpts; 112943345d3Smrg 113943345d3Smrgstatic const OptionInfoRec ARKOptions[] = { 114943345d3Smrg { OPTION_NOACCEL, "noaccel", OPTV_BOOLEAN, {0}, FALSE }, 115943345d3Smrg { -1, NULL, OPTV_NONE, {0}, FALSE } 116943345d3Smrg}; 117943345d3Smrg 118943345d3Smrgstatic const char *fbSymbols[] = { 119943345d3Smrg "fbPictureInit", 120943345d3Smrg "fbScreenInit", 121943345d3Smrg NULL 122943345d3Smrg}; 123943345d3Smrg 124943345d3Smrgstatic const char *vgaHWSymbols[] = { 125943345d3Smrg "vgaHWFreeHWRec", 126943345d3Smrg "vgaHWGetHWRec", 127943345d3Smrg "vgaHWGetIOBase", 128943345d3Smrg "vgaHWGetIndex", 129943345d3Smrg "vgaHWInit", 130943345d3Smrg "vgaHWLock", 131943345d3Smrg "vgaHWProtect", 132943345d3Smrg "vgaHWRestore", 133943345d3Smrg "vgaHWSave", 134943345d3Smrg "vgaHWSaveScreen", 135943345d3Smrg "vgaHWUnlock", 136943345d3Smrg "vgaHWUnmapMem", 137943345d3Smrg NULL 138943345d3Smrg}; 139943345d3Smrg 140943345d3Smrgstatic const char *xaaSymbols[] = { 141943345d3Smrg "XAACreateInfoRec", 142943345d3Smrg "XAAInit", 143943345d3Smrg NULL 144943345d3Smrg}; 145943345d3Smrg 146943345d3Smrg#ifdef XFree86LOADER 147943345d3Smrg 148943345d3SmrgMODULESETUPPROTO(ARKSetup); 149943345d3Smrg 150943345d3Smrgstatic XF86ModuleVersionInfo ARKVersRec = { 151943345d3Smrg "ark", 152943345d3Smrg MODULEVENDORSTRING, 153943345d3Smrg MODINFOSTRING1, 154943345d3Smrg MODINFOSTRING2, 155943345d3Smrg XORG_VERSION_CURRENT, 156943345d3Smrg VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, 157943345d3Smrg ABI_CLASS_VIDEODRV, 158943345d3Smrg ABI_VIDEODRV_VERSION, 159943345d3Smrg MOD_CLASS_VIDEODRV, 160943345d3Smrg {0, 0, 0, 0} 161943345d3Smrg}; 162943345d3Smrg 163943345d3Smrg_X_EXPORT XF86ModuleData arkModuleData = { &ARKVersRec, ARKSetup, NULL }; 164943345d3Smrg 165943345d3Smrgpointer ARKSetup(pointer module, pointer opts, int *errmaj, int *errmin) 166943345d3Smrg{ 167943345d3Smrg static Bool setupDone = FALSE; 168943345d3Smrg 169943345d3Smrg if (!setupDone) { 170943345d3Smrg setupDone = TRUE; 171943345d3Smrg xf86AddDriver(&ARK, module, 0); 172943345d3Smrg LoaderRefSymLists(fbSymbols, vgaHWSymbols, xaaSymbols, NULL); 173943345d3Smrg return (pointer) 1; 174943345d3Smrg } else { 175943345d3Smrg if (errmaj) 176943345d3Smrg *errmaj = LDR_ONCEONLY; 177943345d3Smrg return NULL; 178943345d3Smrg } 179943345d3Smrg} 180943345d3Smrg 181943345d3Smrg#endif /* XFree86LOADER */ 182943345d3Smrg 183943345d3Smrg 184943345d3Smrgstatic Bool ARKGetRec(ScrnInfoPtr pScrn) 185943345d3Smrg{ 186943345d3Smrg if (pScrn->driverPrivate) 187943345d3Smrg return TRUE; 188943345d3Smrg 189943345d3Smrg pScrn->driverPrivate = xnfcalloc(sizeof(ARKRec), 1); 190943345d3Smrg 191943345d3Smrg return TRUE; 192943345d3Smrg} 193943345d3Smrg 194943345d3Smrgstatic void ARKFreeRec(ScrnInfoPtr pScrn) 195943345d3Smrg{ 196943345d3Smrg if (!pScrn->driverPrivate) 197943345d3Smrg return; 198943345d3Smrg 199943345d3Smrg xfree(pScrn->driverPrivate); 200943345d3Smrg pScrn->driverPrivate = NULL; 201943345d3Smrg} 202943345d3Smrg 203943345d3Smrgstatic const OptionInfoRec * ARKAvailableOptions(int chipid, int busid) 204943345d3Smrg{ 205943345d3Smrg return ARKOptions; 206943345d3Smrg} 207943345d3Smrg 208943345d3Smrgstatic void ARKIdentify(int flags) 209943345d3Smrg{ 210943345d3Smrg xf86PrintChipsets("ARK", "driver (version " DRIVER_VERSION " for ARK Logic chipset", 211943345d3Smrg ARKChipsets); 212943345d3Smrg} 213943345d3Smrg 214943345d3Smrgstatic Bool ARKProbe(DriverPtr drv, int flags) 215943345d3Smrg{ 216943345d3Smrg int i; 217943345d3Smrg GDevPtr *devSections; 218943345d3Smrg int *usedChips; 219943345d3Smrg int numDevSections; 220943345d3Smrg int numUsed; 221943345d3Smrg Bool foundScreen = FALSE; 222943345d3Smrg 223943345d3Smrg /* sanity check */ 224943345d3Smrg if ((numDevSections = xf86MatchDevice("ark", &devSections)) <= 0) 225943345d3Smrg return FALSE; 226943345d3Smrg 227943345d3Smrg /* do ISA later */ 228943345d3Smrg numUsed = xf86MatchPciInstances("ark", PCI_VENDOR_ARK, 229943345d3Smrg ARKChipsets, ARKPciChipsets, 230943345d3Smrg devSections, numDevSections, drv, 231943345d3Smrg &usedChips); 232943345d3Smrg 233943345d3Smrg xfree(devSections); 234943345d3Smrg 235943345d3Smrg if (numUsed <= 0) 236943345d3Smrg return FALSE; 237943345d3Smrg 238943345d3Smrg if (flags & PROBE_DETECT) 239943345d3Smrg foundScreen = TRUE; 240943345d3Smrg else for (i=0; i<numUsed; i++) { 241943345d3Smrg ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); 242943345d3Smrg 243943345d3Smrg pScrn->driverVersion = VERSION_MAJOR; 244943345d3Smrg pScrn->driverName = DRIVER_NAME; 245943345d3Smrg pScrn->name = "ark"; 246943345d3Smrg pScrn->Probe = ARKProbe; 247943345d3Smrg pScrn->PreInit = ARKPreInit; 248943345d3Smrg pScrn->ScreenInit = ARKScreenInit; 249943345d3Smrg pScrn->SwitchMode = ARKSwitchMode; 250943345d3Smrg pScrn->AdjustFrame = ARKAdjustFrame; 251943345d3Smrg pScrn->EnterVT = ARKEnterVT; 252943345d3Smrg pScrn->LeaveVT = ARKLeaveVT; 253943345d3Smrg pScrn->FreeScreen = ARKFreeScreen; 254943345d3Smrg foundScreen = TRUE; 255943345d3Smrg xf86ConfigActivePciEntity(pScrn, usedChips[i], ARKPciChipsets, 256943345d3Smrg NULL, NULL, NULL, NULL, NULL); 257943345d3Smrg } 258943345d3Smrg 259943345d3Smrg xfree(usedChips); 260943345d3Smrg 261943345d3Smrg return foundScreen; 262943345d3Smrg} 263943345d3Smrg 264943345d3Smrg 265943345d3Smrgstatic Bool ARKPreInit(ScrnInfoPtr pScrn, int flags) 266943345d3Smrg{ 267943345d3Smrg EntityInfoPtr pEnt; 268943345d3Smrg ARKPtr pARK; 269943345d3Smrg vgaHWPtr hwp; 270943345d3Smrg int i; 271943345d3Smrg ClockRangePtr clockRanges; 272943345d3Smrg rgb zeros = {0, 0, 0}; 273943345d3Smrg Gamma gzeros = {0.0, 0.0, 0.0}; 274943345d3Smrg unsigned char tmp; 275943345d3Smrg 276943345d3Smrg if (flags & PROBE_DETECT) 277943345d3Smrg return FALSE; 278943345d3Smrg 279943345d3Smrg if (!xf86LoadSubModule(pScrn, "vgahw")) 280943345d3Smrg return FALSE; 281943345d3Smrg 282943345d3Smrg xf86LoaderReqSymLists(vgaHWSymbols, NULL); 283943345d3Smrg 284943345d3Smrg if (!vgaHWGetHWRec(pScrn)) 285943345d3Smrg return FALSE; 286943345d3Smrg 287943345d3Smrg hwp = VGAHWPTR(pScrn); 288943345d3Smrg vgaHWGetIOBase(hwp); 289943345d3Smrg 290943345d3Smrg pScrn->monitor = pScrn->confScreen->monitor; 291943345d3Smrg 292943345d3Smrg if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb)) 293943345d3Smrg return FALSE; 294943345d3Smrg else { 295943345d3Smrg switch (pScrn->depth) { 296943345d3Smrg case 8: 297943345d3Smrg case 16: 298943345d3Smrg case 24: 299943345d3Smrg case 32: 300943345d3Smrg /* OK */ 301943345d3Smrg break; 302943345d3Smrg default: 303943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 304943345d3Smrg "Given depth (%d) is not supported by this driver\n", 305943345d3Smrg pScrn->depth); 306943345d3Smrg return FALSE; 307943345d3Smrg } 308943345d3Smrg } 309943345d3Smrg 310943345d3Smrg xf86PrintDepthBpp(pScrn); 311943345d3Smrg 312943345d3Smrg if (pScrn->depth > 8) { 313943345d3Smrg if (!xf86SetWeight(pScrn, zeros, zeros)) 314943345d3Smrg return FALSE; 315943345d3Smrg } 316943345d3Smrg 317943345d3Smrg if (pScrn->depth == 8) 318943345d3Smrg pScrn->rgbBits = 8; 319943345d3Smrg 320943345d3Smrg if (!xf86SetDefaultVisual(pScrn, -1)) 321943345d3Smrg return FALSE; 322943345d3Smrg 323943345d3Smrg pScrn->progClock = TRUE; 324943345d3Smrg 325943345d3Smrg if (!ARKGetRec(pScrn)) 326943345d3Smrg return FALSE; 327943345d3Smrg 328943345d3Smrg pARK = ARKPTR(pScrn); 329943345d3Smrg 330943345d3Smrg xf86CollectOptions(pScrn, NULL); 331943345d3Smrg if (!(pARK->Options = xalloc(sizeof(ARKOptions)))) 332943345d3Smrg return FALSE; 333943345d3Smrg memcpy(pARK->Options, ARKOptions, sizeof(ARKOptions)); 334943345d3Smrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pARK->Options); 335943345d3Smrg 336943345d3Smrg if (xf86ReturnOptValBool(pARK->Options, OPTION_NOACCEL, FALSE)) { 337943345d3Smrg pARK->NoAccel = TRUE; 338943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - acceleration disabled\n"); 339943345d3Smrg } else 340943345d3Smrg pARK->NoAccel = FALSE; 341943345d3Smrg 342943345d3Smrg if (pScrn->numEntities > 1) { 343943345d3Smrg ARKFreeRec(pScrn); 344943345d3Smrg return FALSE; 345943345d3Smrg } 346943345d3Smrg 347943345d3Smrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 348943345d3Smrg if (pEnt->resources) { 349943345d3Smrg xfree(pEnt); 350943345d3Smrg ARKFreeRec(pScrn); 351943345d3Smrg return FALSE; 352943345d3Smrg } 353943345d3Smrg 354943345d3Smrg pARK->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 355943345d3Smrg xf86RegisterResources(pEnt->index, NULL, ResNone); 356943345d3Smrg xf86SetOperatingState(resVgaIo, pEnt->index, ResUnusedOpr); 357943345d3Smrg xf86SetOperatingState(resVgaMem, pEnt->index, ResDisableOpr); 358943345d3Smrg 359943345d3Smrg if (pEnt->device->chipset && *pEnt->device->chipset) { 360943345d3Smrg pScrn->chipset = pEnt->device->chipset; 361943345d3Smrg pARK->Chipset = xf86StringToToken(ARKChipsets, pScrn->chipset); 362943345d3Smrg } else if (pEnt->device->chipID >= 0) { 363943345d3Smrg pARK->Chipset = pEnt->device->chipID; 364943345d3Smrg pScrn->chipset = (char *)xf86TokenToString(ARKChipsets, 365943345d3Smrg pARK->Chipset); 366943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 367943345d3Smrg pARK->Chipset); 368943345d3Smrg } else { 369943345d3Smrg pARK->Chipset = pARK->PciInfo->chipType; 370943345d3Smrg pScrn->chipset = (char *)xf86TokenToString(ARKChipsets, 371943345d3Smrg pARK->Chipset); 372943345d3Smrg } 373943345d3Smrg 374943345d3Smrg if (pEnt->device->chipRev >= 0) { 375943345d3Smrg pARK->ChipRev = pEnt->device->chipRev; 376943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 377943345d3Smrg pARK->ChipRev); 378943345d3Smrg } else 379943345d3Smrg pARK->ChipRev = pARK->PciInfo->chipRev; 380943345d3Smrg 381943345d3Smrg xfree(pEnt); 382943345d3Smrg 383943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", pScrn->chipset); 384943345d3Smrg 385943345d3Smrg pARK->PciTag = pciTag(pARK->PciInfo->bus, pARK->PciInfo->device, 386943345d3Smrg pARK->PciInfo->func); 387943345d3Smrg 388943345d3Smrg /* unlock CRTC[0-7] */ 389943345d3Smrg outb(hwp->PIOOffset + hwp->IOBase + 4, 0x11); 390943345d3Smrg tmp = inb(hwp->PIOOffset + hwp->IOBase + 5); 391943345d3Smrg outb(hwp->PIOOffset + hwp->IOBase + 5, tmp & 0x7f); 392943345d3Smrg modinx(hwp->PIOOffset + 0x3c4, 0x1d, 0x01, 0x01); 393943345d3Smrg 394943345d3Smrg /* use membase's later on ??? */ 395943345d3Smrg pARK->FBAddress = (rdinx(hwp->PIOOffset + 0x3c4, 0x13) << 16) + 396943345d3Smrg (rdinx(hwp->PIOOffset + 0x3c4, 0x14) << 24); 397943345d3Smrg 398943345d3Smrg pScrn->memPhysBase = pARK->FBAddress; 399943345d3Smrg 400943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Framebuffer @ 0x%lx\n", 401943345d3Smrg (unsigned long)pARK->FBAddress); 402943345d3Smrg 403943345d3Smrg if (!xf86SetGamma(pScrn, gzeros)) 404943345d3Smrg return FALSE; 405943345d3Smrg 406943345d3Smrg if (!pScrn->videoRam) { 407943345d3Smrg unsigned char sr10; 408943345d3Smrg 409943345d3Smrg sr10 = rdinx(hwp->PIOOffset + 0x3c4, 0x10); 410943345d3Smrg if (pARK->Chipset == PCI_CHIP_1000PV) { 411943345d3Smrg if ((sr10 & 0x40) == 0) 412943345d3Smrg pScrn->videoRam = 1024; 413943345d3Smrg else 414943345d3Smrg pScrn->videoRam = 2048; 415943345d3Smrg } 416943345d3Smrg if (pARK->Chipset == PCI_CHIP_2000PV || 417943345d3Smrg pARK->Chipset == PCI_CHIP_2000MT) { 418943345d3Smrg if ((sr10 & 0xc0) == 0) 419943345d3Smrg pScrn->videoRam = 1024; 420943345d3Smrg else if ((sr10 & 0xc0) == 0x40) 421943345d3Smrg pScrn->videoRam = 2048; 422943345d3Smrg else 423943345d3Smrg pScrn->videoRam = 4096; 424943345d3Smrg } 425943345d3Smrg 426943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected %d bytes video ram\n", 427943345d3Smrg pScrn->videoRam); 428943345d3Smrg } 429943345d3Smrg 430943345d3Smrg /* try to detect the RAMDAC */ 431943345d3Smrg { 432943345d3Smrg int man_id, dev_id; 433943345d3Smrg 434943345d3Smrg inb(hwp->PIOOffset + 0x3c6); /* skip cmd register */ 435943345d3Smrg man_id = inb(hwp->PIOOffset + 0x3c6); /* manufacturer id */ 436943345d3Smrg dev_id = inb(hwp->PIOOffset + 0x3c6); /* device id */ 437943345d3Smrg if (man_id == 0x84 && dev_id == 0x98) { 438943345d3Smrg pARK->ramdac = ZOOMDAC; 439943345d3Smrg pARK->dac_width = 16; 440943345d3Smrg pARK->multiplex_threshold = 40000; 441943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 442943345d3Smrg "Detected ZOOMDAC\n"); 443943345d3Smrg } 444943345d3Smrg } 445943345d3Smrg 446943345d3Smrg /* hack for this Bali32 */ 447943345d3Smrg pARK->ramdac = ATT490; 448943345d3Smrg pARK->dac_width = 8; 449943345d3Smrg 450943345d3Smrg pARK->clock_mult = 1; 451943345d3Smrg if (pARK->dac_width == 16) { 452943345d3Smrg if (pScrn->bitsPerPixel == 32) 453943345d3Smrg pARK->clock_mult = 2; 454943345d3Smrg } 455943345d3Smrg 456943345d3Smrg clockRanges = xnfcalloc(sizeof(ClockRange), 1); 457943345d3Smrg clockRanges->next = NULL; 458943345d3Smrg clockRanges->minClock = 20000; 459943345d3Smrg clockRanges->maxClock = 80000; 460943345d3Smrg clockRanges->clockIndex = -1; 461943345d3Smrg clockRanges->interlaceAllowed = FALSE; /* ? */ 462943345d3Smrg clockRanges->doubleScanAllowed = FALSE; /* ? */ 463943345d3Smrg 464943345d3Smrg i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 465943345d3Smrg pScrn->display->modes, clockRanges, 466943345d3Smrg NULL, 256, 2048, pScrn->bitsPerPixel, 467943345d3Smrg 128, 2048, pScrn->display->virtualX, 468943345d3Smrg pScrn->display->virtualY, pARK->videoRam * 1024, 469943345d3Smrg LOOKUP_BEST_REFRESH); 470943345d3Smrg if (i == -1) { 471943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n"); 472943345d3Smrg ARKFreeRec(pScrn); 473943345d3Smrg return FALSE; 474943345d3Smrg } 475943345d3Smrg 476943345d3Smrg xf86PruneDriverModes(pScrn); 477943345d3Smrg 478943345d3Smrg if (i == 0 || pScrn->modes == NULL) { 479943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes found\n"); 480943345d3Smrg ARKFreeRec(pScrn); 481943345d3Smrg return FALSE; 482943345d3Smrg } 483943345d3Smrg 484943345d3Smrg xf86SetCrtcForModes(pScrn, 0); 485943345d3Smrg pScrn->currentMode = pScrn->modes; 486943345d3Smrg xf86PrintModes(pScrn); 487943345d3Smrg xf86SetDpi(pScrn, 0, 0); 488943345d3Smrg 489943345d3Smrg if (!xf86LoadSubModule(pScrn, "fb")) { 490943345d3Smrg ARKFreeRec(pScrn); 491943345d3Smrg return FALSE; 492943345d3Smrg } 493943345d3Smrg 494943345d3Smrg xf86LoaderReqSymLists(fbSymbols, NULL); 495943345d3Smrg 496943345d3Smrg if (!pARK->NoAccel) { 497943345d3Smrg if (!xf86LoadSubModule(pScrn, "xaa")) { 498943345d3Smrg ARKFreeRec(pScrn); 499943345d3Smrg return FALSE; 500943345d3Smrg } 501943345d3Smrg xf86LoaderReqSymLists(xaaSymbols, NULL); 502943345d3Smrg } 503943345d3Smrg 504943345d3Smrg return TRUE; 505943345d3Smrg} 506943345d3Smrg 507943345d3Smrgstatic Bool ARKScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 508943345d3Smrg char **argv) 509943345d3Smrg{ 510943345d3Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 511943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 512943345d3Smrg 513943345d3Smrg pScrn->fbOffset = 0; 514943345d3Smrg 515943345d3Smrg if (!ARKMapMem(pScrn)) { 516943345d3Smrg ARKFreeRec(pScrn); 517943345d3Smrg return FALSE; 518943345d3Smrg } 519943345d3Smrg 520943345d3Smrg ARKSave(pScrn); 521943345d3Smrg 522943345d3Smrg vgaHWBlankScreen(pScrn, TRUE); 523943345d3Smrg 524943345d3Smrg if (!ARKModeInit(pScrn, pScrn->currentMode)) 525943345d3Smrg return FALSE; 526943345d3Smrg 527943345d3Smrg ARKSaveScreen(pScreen, SCREEN_SAVER_ON); 528943345d3Smrg 529943345d3Smrg pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 530943345d3Smrg 531943345d3Smrg miClearVisualTypes(); 532943345d3Smrg if (pScrn->bitsPerPixel > 8) { 533943345d3Smrg if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 534943345d3Smrg pScrn->rgbBits, pScrn->defaultVisual)) 535943345d3Smrg return FALSE; 536943345d3Smrg } else { 537943345d3Smrg if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 538943345d3Smrg pScrn->rgbBits, pScrn->defaultVisual)) 539943345d3Smrg return FALSE; 540943345d3Smrg } 541943345d3Smrg 542943345d3Smrg miSetPixmapDepths (); 543943345d3Smrg 544943345d3Smrg if (!fbScreenInit(pScreen, pARK->FBBase, pScrn->virtualX, 545943345d3Smrg pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 546943345d3Smrg pScrn->displayWidth, pScrn->bitsPerPixel)) 547943345d3Smrg return FALSE; 548943345d3Smrg 549943345d3Smrg xf86SetBlackWhitePixels(pScreen); 550943345d3Smrg 551943345d3Smrg if (pScrn->bitsPerPixel > 8) { 552943345d3Smrg VisualPtr pVis; 553943345d3Smrg 554943345d3Smrg pVis = pScreen->visuals + pScreen->numVisuals; 555943345d3Smrg while (--pVis >= pScreen->visuals) { 556943345d3Smrg if ((pVis->class | DynamicClass) == DirectColor) { 557943345d3Smrg pVis->offsetRed = pScrn->offset.red; 558943345d3Smrg pVis->offsetGreen = pScrn->offset.green; 559943345d3Smrg pVis->offsetBlue = pScrn->offset.blue; 560943345d3Smrg pVis->redMask = pScrn->mask.red; 561943345d3Smrg pVis->greenMask = pScrn->mask.green; 562943345d3Smrg pVis->blueMask = pScrn->mask.blue; 563943345d3Smrg } 564943345d3Smrg } 565943345d3Smrg } 566943345d3Smrg 567943345d3Smrg /* must be after RGB order fixed */ 568943345d3Smrg 569943345d3Smrg fbPictureInit (pScreen, 0, 0); 570943345d3Smrg 571943345d3Smrg miInitializeBackingStore(pScreen); 572943345d3Smrg xf86SetBackingStore(pScreen); 573943345d3Smrg 574943345d3Smrg if (!pARK->NoAccel) { 575943345d3Smrg if (ARKAccelInit(pScreen)) { 576943345d3Smrg xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); 577943345d3Smrg } else { 578943345d3Smrg xf86DrvMsg(scrnIndex, X_ERROR, "Acceleration initialization failed\n"); 579943345d3Smrg xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); 580943345d3Smrg } 581943345d3Smrg } else { 582943345d3Smrg xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); 583943345d3Smrg } 584943345d3Smrg 585943345d3Smrg miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 586943345d3Smrg 587943345d3Smrg if (!miCreateDefColormap(pScreen)) 588943345d3Smrg return FALSE; 589943345d3Smrg 590943345d3Smrg if (!xf86HandleColormaps(pScreen, 256, 8, ARKLoadPalette, NULL, 591943345d3Smrg CMAP_RELOAD_ON_MODE_SWITCH)) 592943345d3Smrg return FALSE; 593943345d3Smrg 594943345d3Smrg vgaHWBlankScreen(pScrn, FALSE); 595943345d3Smrg 596943345d3Smrg pScreen->SaveScreen = ARKSaveScreen; 597943345d3Smrg pARK->CloseScreen = pScreen->CloseScreen; 598943345d3Smrg pScreen->CloseScreen = ARKCloseScreen; 599943345d3Smrg 600943345d3Smrg return TRUE; 601943345d3Smrg} 602943345d3Smrg 603943345d3Smrg 604943345d3Smrg 605943345d3Smrgstatic void ARKSave(ScrnInfoPtr pScrn) 606943345d3Smrg{ 607943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 608943345d3Smrg ARKRegPtr save = &pARK->SavedRegs; 609943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 610943345d3Smrg IOADDRESS isaIOBase = hwp->PIOOffset; 611943345d3Smrg IOADDRESS vgaIOBase = isaIOBase + hwp->IOBase; 612943345d3Smrg 613943345d3Smrg vgaHWUnlock(hwp); 614943345d3Smrg vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); 615943345d3Smrg vgaHWLock(hwp); 616943345d3Smrg 617943345d3Smrg /* set read and write aperture index to 0 */ 618943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x15, 0x00); 619943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x16, 0x00); 620943345d3Smrg outb(isaIOBase + 0x3c8, 0); /* reset DAC register access mode */ 621943345d3Smrg 622943345d3Smrg save->sr10 = rdinx(isaIOBase + 0x3c4, 0x10); 623943345d3Smrg save->sr11 = rdinx(isaIOBase + 0x3c4, 0x11); 624943345d3Smrg save->sr12 = rdinx(isaIOBase + 0x3c4, 0x12); 625943345d3Smrg save->sr13 = rdinx(isaIOBase + 0x3c4, 0x13); 626943345d3Smrg save->sr14 = rdinx(isaIOBase + 0x3c4, 0x14); 627943345d3Smrg save->sr15 = rdinx(isaIOBase + 0x3c4, 0x15); 628943345d3Smrg save->sr16 = rdinx(isaIOBase + 0x3c4, 0x16); 629943345d3Smrg save->sr17 = rdinx(isaIOBase + 0x3c4, 0x17); 630943345d3Smrg save->sr18 = rdinx(isaIOBase + 0x3c4, 0x18); 631943345d3Smrg 632943345d3Smrg#if 0 633943345d3Smrg save->sr1d = rdinx(isaIOBase + 0x3c4, 0x1d); 634943345d3Smrg save->sr1c = rdinx(isaIOBase + 0x3c4, 0x1c); 635943345d3Smrg 636943345d3Smrg save->sr20 = rdinx(isaIOBase + 0x3c4, 0x20); 637943345d3Smrg save->sr21 = rdinx(isaIOBase + 0x3c4, 0x21); 638943345d3Smrg save->sr22 = rdinx(isaIOBase + 0x3c4, 0x22); 639943345d3Smrg save->sr23 = rdinx(isaIOBase + 0x3c4, 0x23); 640943345d3Smrg save->sr24 = rdinx(isaIOBase + 0x3c4, 0x24); 641943345d3Smrg save->sr25 = rdinx(isaIOBase + 0x3c4, 0x25); 642943345d3Smrg save->sr26 = rdinx(isaIOBase + 0x3c4, 0x26); 643943345d3Smrg save->sr27 = rdinx(isaIOBase + 0x3c4, 0x27); 644943345d3Smrg save->sr29 = rdinx(isaIOBase + 0x3c4, 0x29); 645943345d3Smrg save->sr2a = rdinx(isaIOBase + 0x3c4, 0x2a); 646943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 647943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 648943345d3Smrg save->sr28 = rdinx(isaIOBase + 0x3c4, 0x28); 649943345d3Smrg save->sr2b = rdinx(isaIOBase + 0x3c4, 0x2b); 650943345d3Smrg } 651943345d3Smrg#endif 652943345d3Smrg 653943345d3Smrg save->cr40 = rdinx(vgaIOBase + 4, 0x40); 654943345d3Smrg save->cr41 = rdinx(vgaIOBase + 4, 0x41); 655943345d3Smrg save->cr42 = rdinx(vgaIOBase + 4, 0x42); 656943345d3Smrg save->cr44 = rdinx(vgaIOBase + 4, 0x44); 657943345d3Smrg 658943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 659943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) 660943345d3Smrg save->cr46 = rdinx(vgaIOBase + 4, 0x46); 661943345d3Smrg 662943345d3Smrg /* save RAMDAC regs here, based on type */ 663943345d3Smrg save->dac_command = get_daccomm(isaIOBase); 664943345d3Smrg} 665943345d3Smrg 666943345d3Smrg 667943345d3Smrg 668943345d3Smrgstatic Bool ARKModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 669943345d3Smrg{ 670943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 671943345d3Smrg ARKRegPtr new = &pARK->ModeRegs; 672943345d3Smrg int multiplexing, dac16, modepitch; 673943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 674943345d3Smrg vgaRegPtr pVga = &hwp->ModeReg; 675943345d3Smrg IOADDRESS isaIOBase = hwp->PIOOffset; 676943345d3Smrg IOADDRESS vgaIOBase = isaIOBase + hwp->IOBase; 677943345d3Smrg unsigned char tmp; 678943345d3Smrg int offset; 679943345d3Smrg 680943345d3Smrg multiplexing = 0; 681943345d3Smrg 682943345d3Smrg if ((pScrn->bitsPerPixel == 8) && (pARK->dac_width == 16) && 683943345d3Smrg (mode->Clock > pARK->multiplex_threshold)) 684943345d3Smrg multiplexing = 1; 685943345d3Smrg 686943345d3Smrg if (pARK->clock_mult == 2) { 687943345d3Smrg if (!mode->CrtcHAdjusted) { 688943345d3Smrg mode->CrtcHDisplay <<= 1; 689943345d3Smrg mode->CrtcHSyncStart <<= 1; 690943345d3Smrg mode->CrtcHSyncEnd <<= 1; 691943345d3Smrg mode->CrtcHTotal <<= 1; 692943345d3Smrg mode->CrtcHSkew <<= 1; 693943345d3Smrg mode->CrtcHAdjusted = TRUE; 694943345d3Smrg } 695943345d3Smrg } 696943345d3Smrg 697943345d3Smrg if (multiplexing) { 698943345d3Smrg if (!mode->CrtcHAdjusted) { 699943345d3Smrg mode->CrtcHDisplay >>= 1; 700943345d3Smrg mode->CrtcHSyncStart >>= 1; 701943345d3Smrg mode->CrtcHSyncEnd >>= 1; 702943345d3Smrg mode->CrtcHTotal >>= 1; 703943345d3Smrg mode->CrtcHSkew >>= 1; 704943345d3Smrg mode->CrtcHAdjusted = TRUE; 705943345d3Smrg } 706943345d3Smrg } 707943345d3Smrg 708943345d3Smrg if (!vgaHWInit(pScrn, mode)) 709943345d3Smrg return FALSE; 710943345d3Smrg 711943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 712943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 713943345d3Smrg new->cr46 = rdinx(vgaIOBase + 4, 0x46) & ~0x04; 714943345d3Smrg dac16 = 0; 715943345d3Smrg if (pScrn->bitsPerPixel > 8) 716943345d3Smrg dac16 = 1; 717943345d3Smrg if (dac16) 718943345d3Smrg new->cr46 |= 0x04; 719943345d3Smrg } 720943345d3Smrg 721943345d3Smrg offset = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3; 722943345d3Smrg pVga->CRTC[0x13] = offset; 723943345d3Smrg new->cr41 = (offset & 0x100) >> 5; 724943345d3Smrg 725943345d3Smrg new->sr11 = 0x90; 726943345d3Smrg switch (pScrn->bitsPerPixel) { 727943345d3Smrg case 8: 728943345d3Smrg new->sr11 |= 0x06; 729943345d3Smrg break; 730943345d3Smrg case 16: 731943345d3Smrg new->sr11 |= 0x0a; 732943345d3Smrg break; 733943345d3Smrg case 24: 734943345d3Smrg new->sr11 |= 0x06; 735943345d3Smrg break; 736943345d3Smrg case 32: 737943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 738943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) 739943345d3Smrg new->sr11 |= 0x0e; 740943345d3Smrg else 741943345d3Smrg new->sr11 |= 0x0a; 742943345d3Smrg break; 743943345d3Smrg default: 744943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 745943345d3Smrg "Unsupported screen depth %d\n", 746943345d3Smrg pScrn->bitsPerPixel); 747943345d3Smrg return FALSE; 748943345d3Smrg } 749943345d3Smrg 750943345d3Smrg switch (pScrn->displayWidth) { 751943345d3Smrg case 640: 752943345d3Smrg modepitch = 0; 753943345d3Smrg break; 754943345d3Smrg case 800: 755943345d3Smrg modepitch = 1; 756943345d3Smrg break; 757943345d3Smrg case 1024: 758943345d3Smrg modepitch = 2; 759943345d3Smrg break; 760943345d3Smrg case 1280: 761943345d3Smrg modepitch = 4; 762943345d3Smrg break; 763943345d3Smrg case 1600: 764943345d3Smrg modepitch = 5; 765943345d3Smrg break; 766943345d3Smrg case 2048: 767943345d3Smrg modepitch = 6; 768943345d3Smrg break; 769943345d3Smrg default: 770943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 771943345d3Smrg "Unsupported screen width %d\n", 772943345d3Smrg pScrn->displayWidth); 773943345d3Smrg return FALSE; 774943345d3Smrg } 775943345d3Smrg 776943345d3Smrg new->sr17 &= ~0xc7; 777943345d3Smrg new->sr17 |= modepitch; 778943345d3Smrg 779943345d3Smrg new->sr10 = rdinx(isaIOBase + 0x3c4, 0x10) & ~0x1f; 780943345d3Smrg new->sr10 |= 0x1f; 781943345d3Smrg 782943345d3Smrg new->sr13 = pARK->FBAddress >> 16; 783943345d3Smrg new->sr14 = pARK->FBAddress >> 24; 784943345d3Smrg 785943345d3Smrg new->sr12 = rdinx(isaIOBase + 0x3c4, 0x12) & ~0x03; 786943345d3Smrg switch (pScrn->videoRam) { 787943345d3Smrg case 1024: 788943345d3Smrg new->sr12 |= 0x01; 789943345d3Smrg break; 790943345d3Smrg case 2048: 791943345d3Smrg new->sr12 |= 0x02; 792943345d3Smrg break; 793943345d3Smrg case 4096: 794943345d3Smrg new->sr12 |= 0x03; 795943345d3Smrg break; 796943345d3Smrg default: 797943345d3Smrg new->sr12 |= 0x01; 798943345d3Smrg break; 799943345d3Smrg } 800943345d3Smrg 801943345d3Smrg new->sr15 = new->sr16 = 0; 802943345d3Smrg 803943345d3Smrg tmp = 0; 804943345d3Smrg if ((mode->CrtcVTotal - 2) & 0x400) 805943345d3Smrg tmp |= 0x80; 806943345d3Smrg if ((mode->CrtcVDisplay - 1) & 0x400) 807943345d3Smrg tmp |= 0x40; 808943345d3Smrg if (mode->CrtcVSyncStart & 0x400) 809943345d3Smrg tmp |= 0x10; 810943345d3Smrg new->cr40 = tmp; 811943345d3Smrg 812943345d3Smrg tmp = new->cr41; /* initialized earlier */ 813943345d3Smrg if ((mode->CrtcHTotal / 8 - 5) & 0x100) 814943345d3Smrg tmp |= 0x80; 815943345d3Smrg if ((mode->CrtcHDisplay / 8 - 1) & 0x100) 816943345d3Smrg tmp |= 0x40; 817943345d3Smrg if ((mode->CrtcHSyncStart / 8 - 1) & 0x100) 818943345d3Smrg tmp |= 0x20; 819943345d3Smrg if ((mode->CrtcHSyncStart / 8) & 0x100) 820943345d3Smrg tmp |= 0x10; 821943345d3Smrg new->cr41 |= tmp; 822943345d3Smrg 823943345d3Smrg new->cr44 = rdinx(vgaIOBase + 4, 0x44) & ~0x34; 824943345d3Smrg new->cr44 &= ~0x01; 825943345d3Smrg new->cr42 = 0; 826943345d3Smrg 827943345d3Smrg /* check interlace here later */ 828943345d3Smrg 829943345d3Smrg /* set display FIFO threshold */ 830943345d3Smrg { 831943345d3Smrg int threshold; 832943345d3Smrg int bandwidthused, percentused; 833943345d3Smrg 834943345d3Smrg /* mostly guesses here as I would need to know more about 835943345d3Smrg * and from the ramdac... 836943345d3Smrg */ 837943345d3Smrg bandwidthused = (mode->Clock / pARK->clock_mult) * 838943345d3Smrg (pScrn->bitsPerPixel / 8); 839943345d3Smrg /* 120000 is another guess */ 840943345d3Smrg percentused = (bandwidthused * 100) / 120000; 841943345d3Smrg tmp = rdinx(isaIOBase + 0x3c4, 0x18); 842943345d3Smrg if (pARK->Chipset == PCI_CHIP_1000PV) { 843943345d3Smrg threshold = 4; 844943345d3Smrg tmp |= 0x08; /* enable full FIFO (8 deep) */ 845943345d3Smrg tmp &= ~0x07; 846943345d3Smrg tmp |= threshold; 847943345d3Smrg } 848943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 849943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 850943345d3Smrg threshold = 12; 851943345d3Smrg if (percentused >= 45) 852943345d3Smrg threshold = 8; 853943345d3Smrg if (percentused >= 70) 854943345d3Smrg threshold = 4; 855943345d3Smrg tmp &= 0x40; 856943345d3Smrg tmp |= 0x10; 857943345d3Smrg tmp |= (threshold & 0x0e) >> 1; 858943345d3Smrg if (threshold & 0x01) 859943345d3Smrg tmp |= 0x80; 860943345d3Smrg if (threshold & 0x10) 861943345d3Smrg tmp |= 0x20; 862943345d3Smrg } 863943345d3Smrg new->sr18 = tmp; 864943345d3Smrg } 865943345d3Smrg 866943345d3Smrg /* setup the RAMDAC regs */ 867943345d3Smrg if (pARK->ramdac == ZOOMDAC) { 868943345d3Smrg new->dac_command = 0x04; 869943345d3Smrg if ((pScrn->bitsPerPixel == 8) && multiplexing) 870943345d3Smrg new->dac_command = 0x24; 871943345d3Smrg if ((pScrn->bitsPerPixel == 16) && (pARK->dac_width == 16)) 872943345d3Smrg /* assuming green weight is not 5 */ 873943345d3Smrg new->dac_command = 0x34; 874943345d3Smrg if ((pScrn->bitsPerPixel == 16) && (pARK->dac_width == 8)) 875943345d3Smrg new->dac_command = 0x64; 876943345d3Smrg if ((pScrn->bitsPerPixel == 24) && (pARK->dac_width == 16)) 877943345d3Smrg new->dac_command = 0xb4; /* packed */ 878943345d3Smrg if ((pScrn->bitsPerPixel == 32) && (pARK->dac_width == 16)) 879943345d3Smrg new->dac_command = 0x54; 880943345d3Smrg } else if (pARK->ramdac == ATT490) { 881943345d3Smrg new->dac_command = 0x00; 882943345d3Smrg if (pScrn->bitsPerPixel == 16) 883943345d3Smrg /* assuming green weight is 6 */ 884943345d3Smrg new->dac_command = 0xc0; 885943345d3Smrg if (pScrn->bitsPerPixel == 24) 886943345d3Smrg new->dac_command = 0xe0; 887943345d3Smrg } 888943345d3Smrg 889943345d3Smrg#if 0 890943345d3Smrg /* hw cursor regs */ 891943345d3Smrg new->sr20 = rdinx(isaIOBase + 0x3c4, 0x20); 892943345d3Smrg new->sr21 = rdinx(isaIOBase + 0x3c4, 0x21); 893943345d3Smrg new->sr22 = rdinx(isaIOBase + 0x3c4, 0x22); 894943345d3Smrg new->sr23 = rdinx(isaIOBase + 0x3c4, 0x23); 895943345d3Smrg new->sr24 = rdinx(isaIOBase + 0x3c4, 0x24); 896943345d3Smrg new->sr25 = rdinx(isaIOBase + 0x3c4, 0x25); 897943345d3Smrg new->sr26 = rdinx(isaIOBase + 0x3c4, 0x26); 898943345d3Smrg new->sr27 = rdinx(isaIOBase + 0x3c4, 0x27); 899943345d3Smrg new->sr29 = rdinx(isaIOBase + 0x3c4, 0x29); 900943345d3Smrg new->sr2a = rdinx(isaIOBase + 0x3c4, 0x2a); 901943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 902943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 903943345d3Smrg new->sr28 = rdinx(isaIOBase + 0x3c4, 0x28); 904943345d3Smrg new->sr2b = rdinx(isaIOBase + 0x3c4, 0x3b); 905943345d3Smrg } 906943345d3Smrg#endif 907943345d3Smrg 908943345d3Smrg 909943345d3Smrg ARKWriteMode(pScrn, pVga, new); 910943345d3Smrg 911943345d3Smrg return TRUE; 912943345d3Smrg} 913943345d3Smrg 914943345d3Smrg 915943345d3Smrgstatic void ARKAdjustFrame(int scrnIndex, int x, int y, int flags) 916943345d3Smrg{ 917943345d3Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 918943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 919943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 920943345d3Smrg IOADDRESS vgaIOBase = hwp->PIOOffset + hwp->IOBase; 921943345d3Smrg int base; 922943345d3Smrg 923943345d3Smrg base = ((y * pScrn->displayWidth + x) * 924943345d3Smrg (pScrn->bitsPerPixel / 8)); 925943345d3Smrg 926943345d3Smrg if (((pARK->Chipset == PCI_CHIP_2000PV) || 927943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) && 928943345d3Smrg (pScrn->videoRam >= 2048)) 929943345d3Smrg base >>= 3; 930943345d3Smrg else 931943345d3Smrg base >>= 2; 932943345d3Smrg if (pScrn->bitsPerPixel == 24) 933943345d3Smrg base -= base % 3; 934943345d3Smrg 935943345d3Smrg outw(vgaIOBase + 4, (base & 0x00ff00) | 0x0c); 936943345d3Smrg outw(vgaIOBase + 4, ((base & 0x00ff) << 8) | 0x0d); 937943345d3Smrg 938943345d3Smrg modinx(vgaIOBase + 4, 0x40, 0x07, (base & 0x070000) >> 16); 939943345d3Smrg} 940943345d3Smrg 941943345d3Smrg 942943345d3Smrg 943943345d3Smrgstatic void ARKWriteMode(ScrnInfoPtr pScrn, vgaRegPtr pVga, ARKRegPtr new) 944943345d3Smrg{ 945943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 946943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 947943345d3Smrg IOADDRESS isaIOBase = hwp->PIOOffset; 948943345d3Smrg IOADDRESS vgaIOBase = isaIOBase + hwp->IOBase; 949943345d3Smrg 950943345d3Smrg vgaHWProtect(pScrn, TRUE); 951943345d3Smrg 952943345d3Smrg /* set read and write aperture index to 0 */ 953943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x15, 0x00); 954943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x16, 0x00); 955943345d3Smrg 956943345d3Smrg /* write the extended registers first so that textmode font 957943345d3Smrg * restoration can suceed 958943345d3Smrg */ 959943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x10, new->sr10); 960943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x11, new->sr11); 961943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x12, new->sr12); 962943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x13, new->sr13); 963943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x14, new->sr14); 964943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x15, new->sr15); 965943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x16, new->sr16); 966943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x17, new->sr17); 967943345d3Smrg 968943345d3Smrg#if 0 969943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x1c, new->sr1c); 970943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x1d, new->sr1d); 971943345d3Smrg 972943345d3Smrg /* hw cursor regs */ 973943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x20, new->sr20); 974943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x21, new->sr21); 975943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x22, new->sr22); 976943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x23, new->sr23); 977943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x24, new->sr24); 978943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x25, new->sr25); 979943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x26, new->sr26); 980943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x27, new->sr27); 981943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x29, new->sr29); 982943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x2a, new->sr2a); 983943345d3Smrg#endif 984943345d3Smrg 985943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 986943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 987943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x28, new->sr28); 988943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x2B, new->sr2b); 989943345d3Smrg } 990943345d3Smrg 991943345d3Smrg wrinx(vgaIOBase + 4, 0x40, new->cr40); 992943345d3Smrg wrinx(vgaIOBase + 4, 0x41, new->cr41); 993943345d3Smrg wrinx(vgaIOBase + 4, 0x42, new->cr42); 994943345d3Smrg wrinx(vgaIOBase + 4, 0x44, new->cr44); 995943345d3Smrg 996943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 997943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) 998943345d3Smrg wrinx(vgaIOBase + 4, 0x46, new->cr46); 999943345d3Smrg 1000943345d3Smrg /* RAMDAC regs */ 1001943345d3Smrg if (pARK->ramdac == ZOOMDAC) { 1002943345d3Smrg set_daccom(isaIOBase, new->dac_command); 1003943345d3Smrg } 1004943345d3Smrg 1005943345d3Smrg if (xf86IsPrimaryPci(pARK->PciInfo)) 1006943345d3Smrg vgaHWRestore(pScrn, pVga, VGA_SR_ALL); 1007943345d3Smrg else 1008943345d3Smrg vgaHWRestore(pScrn, pVga, VGA_SR_MODE); 1009943345d3Smrg 1010943345d3Smrg vgaHWProtect(pScrn, FALSE); 1011943345d3Smrg} 1012943345d3Smrg 1013943345d3Smrg 1014943345d3Smrgstatic Bool ARKEnterVT(int scrnIndex, int flags) 1015943345d3Smrg{ 1016943345d3Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1017943345d3Smrg 1018943345d3Smrg if (!ARKModeInit(pScrn, pScrn->currentMode)) 1019943345d3Smrg return FALSE; 1020943345d3Smrg 1021943345d3Smrg ARKAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 1022943345d3Smrg 1023943345d3Smrg return TRUE; 1024943345d3Smrg} 1025943345d3Smrg 1026943345d3Smrg 1027943345d3Smrg 1028943345d3Smrgstatic void ARKLeaveVT(int scrnIndex, int flags) 1029943345d3Smrg{ 1030943345d3Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1031943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 1032943345d3Smrg ARKRegPtr old = &pARK->SavedRegs; 1033943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1034943345d3Smrg 1035943345d3Smrg ARKWriteMode(pScrn, &hwp->ModeReg, old); 1036943345d3Smrg 1037943345d3Smrg vgaHWUnlock(hwp); 1038943345d3Smrg vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); 1039943345d3Smrg vgaHWLock(hwp); 1040943345d3Smrg} 1041943345d3Smrg 1042943345d3Smrg 1043943345d3Smrgstatic Bool ARKMapMem(ScrnInfoPtr pScrn) 1044943345d3Smrg{ 1045943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 1046943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1047943345d3Smrg 1048943345d3Smrg /* extended to cover MMIO space at 0xB8000 */ 1049943345d3Smrg hwp->MapSize = 0x20000; 1050943345d3Smrg 1051943345d3Smrg pARK->MMIOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO, 1052943345d3Smrg pARK->PciTag, 0xb8000, 0x8000); 1053943345d3Smrg 1054943345d3Smrg pARK->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 1055943345d3Smrg pARK->PciTag, pARK->FBAddress, 1056943345d3Smrg pScrn->videoRam * 1024); 1057943345d3Smrg if (!pARK->FBBase) { 1058943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1059943345d3Smrg "Cound not map framebuffer\n"); 1060943345d3Smrg return FALSE; 1061943345d3Smrg } 1062943345d3Smrg 1063943345d3Smrg return TRUE; 1064943345d3Smrg} 1065943345d3Smrg 1066943345d3Smrg 1067943345d3Smrgstatic void ARKUnmapMem(ScrnInfoPtr pScrn) 1068943345d3Smrg{ 1069943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 1070943345d3Smrg 1071943345d3Smrg /* XXX vgaHWMapMem() isn't called explicitly, so is this correct? */ 1072943345d3Smrg vgaHWUnmapMem(pScrn); 1073943345d3Smrg 1074943345d3Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pARK->FBBase, 1075943345d3Smrg pScrn->videoRam * 1024); 1076943345d3Smrg} 1077943345d3Smrg 1078943345d3Smrg 1079943345d3SmrgBool ARKCloseScreen(int scrnIndex, ScreenPtr pScreen) 1080943345d3Smrg{ 1081943345d3Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1082943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 1083943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1084943345d3Smrg 1085943345d3Smrg if (pScrn->vtSema) { 1086943345d3Smrg vgaHWUnlock(hwp); 1087943345d3Smrg ARKWriteMode(pScrn, &hwp->SavedReg, &pARK->SavedRegs); 1088943345d3Smrg vgaHWLock(hwp); 1089943345d3Smrg ARKUnmapMem(pScrn); 1090943345d3Smrg } 1091943345d3Smrg 1092943345d3Smrg pScrn->vtSema = FALSE; 1093943345d3Smrg pScreen->CloseScreen = pARK->CloseScreen; 1094943345d3Smrg 1095943345d3Smrg /* XXX Shouldn't XAADestroyInfoRec() be called? */ 1096943345d3Smrg 1097943345d3Smrg return (*pScreen->CloseScreen)(scrnIndex, pScreen); 1098943345d3Smrg} 1099943345d3Smrg 1100943345d3Smrg 1101943345d3SmrgBool ARKSaveScreen(ScreenPtr pScreen, int mode) 1102943345d3Smrg{ 1103943345d3Smrg return vgaHWSaveScreen(pScreen, mode); 1104943345d3Smrg} 1105943345d3Smrg 1106943345d3Smrg 1107943345d3SmrgBool ARKSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 1108943345d3Smrg{ 1109943345d3Smrg return ARKModeInit(xf86Screens[scrnIndex], mode); 1110943345d3Smrg} 1111943345d3Smrg 1112943345d3Smrg 1113943345d3Smrgstatic void ARKLoadPalette(ScrnInfoPtr pScrn, int numColors, 1114943345d3Smrg int *indicies, LOCO *colors, 1115943345d3Smrg VisualPtr pVisual) 1116943345d3Smrg{ 1117943345d3Smrg IOADDRESS isaIOBase = pScrn->domainIOBase; 1118943345d3Smrg int i, index; 1119943345d3Smrg 1120943345d3Smrg for (i=0; i<numColors; i++) { 1121943345d3Smrg index = indicies[i]; 1122943345d3Smrg outb(isaIOBase + 0x3c8, index); 1123943345d3Smrg outb(isaIOBase + 0x3c9, colors[index].red); 1124943345d3Smrg outb(isaIOBase + 0x3c9, colors[index].green); 1125943345d3Smrg outb(isaIOBase + 0x3c9, colors[index].blue); 1126943345d3Smrg } 1127943345d3Smrg} 1128943345d3Smrg 1129943345d3Smrg 1130943345d3Smrgstatic void ARKFreeScreen(int scrnIndex, int flags) 1131943345d3Smrg{ 1132943345d3Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1133943345d3Smrg 1134943345d3Smrg vgaHWFreeHWRec(pScrn); 1135943345d3Smrg 1136943345d3Smrg ARKFreeRec(pScrn); 1137943345d3Smrg} 1138943345d3Smrg 1139943345d3Smrg 1140943345d3Smrgstatic unsigned char get_daccomm(IOADDRESS isaIOBase) 1141943345d3Smrg{ 1142943345d3Smrg unsigned char tmp; 1143943345d3Smrg 1144943345d3Smrg outb(isaIOBase + 0x3c8, 0); 1145943345d3Smrg inb(isaIOBase + 0x3c6); 1146943345d3Smrg inb(isaIOBase + 0x3c6); 1147943345d3Smrg inb(isaIOBase + 0x3c6); 1148943345d3Smrg inb(isaIOBase + 0x3c6); 1149943345d3Smrg tmp = inb(isaIOBase + 0x3c6); 1150943345d3Smrg outb(isaIOBase + 0x3c8, 0); 1151943345d3Smrg 1152943345d3Smrg return tmp; 1153943345d3Smrg} 1154943345d3Smrg 1155943345d3Smrg 1156943345d3Smrgstatic unsigned char set_daccom(IOADDRESS isaIOBase, unsigned char comm) 1157943345d3Smrg{ 1158943345d3Smrg#if 0 1159943345d3Smrg outb(isaIOBase + 0x3c8, 0); 1160943345d3Smrg#else 1161943345d3Smrg inb(isaIOBase + 0x3c8); 1162943345d3Smrg#endif 1163943345d3Smrg inb(isaIOBase + 0x3c6); 1164943345d3Smrg inb(isaIOBase + 0x3c6); 1165943345d3Smrg inb(isaIOBase + 0x3c6); 1166943345d3Smrg inb(isaIOBase + 0x3c6); 1167943345d3Smrg outb(isaIOBase + 0x3c6, comm); 1168943345d3Smrg#if 0 1169943345d3Smrg outb(isaIOBase + 0x3c8, 0); 1170943345d3Smrg#else 1171943345d3Smrg inb(isaIOBase + 0x3c8); 1172943345d3Smrg#endif 1173943345d3Smrg 1174943345d3Smrg return inb(isaIOBase + 0x3c6); 1175943345d3Smrg} 1176