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