ark_driver.c revision 3e51e026
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 "mibstore.h" 43943345d3Smrg#include "fb.h" 44943345d3Smrg#include "ark.h" 45943345d3Smrg 465e695a52Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 475e695a52Smrg#include "xf86Resources.h" 485e695a52Smrg#endif 495e695a52Smrg 503e51e026Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12 513e51e026Smrg#define PIOOFFSET hwp->PIOOffset 523e51e026Smrg#else 533e51e026Smrg#define PIOOFFSET 0 543e51e026Smrg#endif 553e51e026Smrg 56943345d3Smrg#include <string.h> 57943345d3Smrg 58943345d3Smrg/* 59943345d3Smrg * prototypes 60943345d3Smrg */ 61943345d3Smrgstatic const OptionInfoRec * ARKAvailableOptions(int chipid, int busid); 62943345d3Smrgstatic void ARKIdentify(int flags); 63943345d3Smrgstatic Bool ARKProbe(DriverPtr drv, int flags); 64943345d3Smrgstatic Bool ARKPreInit(ScrnInfoPtr pScrn, int flags); 653e51e026Smrgstatic Bool ARKEnterVT(VT_FUNC_ARGS_DECL); 663e51e026Smrgstatic void ARKLeaveVT(VT_FUNC_ARGS_DECL); 67943345d3Smrgstatic void ARKSave(ScrnInfoPtr pScrn); 683e51e026Smrgstatic Bool ARKScreenInit(SCREEN_INIT_ARGS_DECL); 69943345d3Smrgstatic Bool ARKMapMem(ScrnInfoPtr pScrn); 70943345d3Smrgstatic void ARKUnmapMem(ScrnInfoPtr pScrn); 71943345d3Smrgstatic Bool ARKModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 723e51e026Smrgstatic void ARKAdjustFrame(ADJUST_FRAME_ARGS_DECL); 733e51e026SmrgBool ARKSwitchMode(SWITCH_MODE_ARGS_DECL); 743e51e026SmrgBool ARKCloseScreen(CLOSE_SCREEN_ARGS_DECL); 75943345d3SmrgBool ARKSaveScreen(ScreenPtr pScreen, int mode); 763e51e026Smrgstatic void ARKFreeScreen(FREE_SCREEN_ARGS_DECL); 77943345d3Smrgstatic void ARKLoadPalette(ScrnInfoPtr pScrn, int numColors, 78943345d3Smrg int *indicies, LOCO *colors, 79943345d3Smrg VisualPtr pVisual); 80943345d3Smrgstatic void ARKWriteMode(ScrnInfoPtr pScrn, vgaRegPtr pVga, ARKRegPtr new); 81943345d3Smrg 82943345d3Smrg/* helpers */ 833e51e026Smrgstatic unsigned char get_daccomm(unsigned long); 843e51e026Smrgstatic unsigned char set_daccom(unsigned long, unsigned char comm); 85943345d3Smrg 86943345d3Smrg 87943345d3Smrg_X_EXPORT DriverRec ARK = 88943345d3Smrg{ 89943345d3Smrg ARK_VERSION, 90943345d3Smrg DRIVER_NAME, 91943345d3Smrg ARKIdentify, 92943345d3Smrg ARKProbe, 93943345d3Smrg ARKAvailableOptions, 94943345d3Smrg NULL, 95943345d3Smrg 0 96943345d3Smrg}; 97943345d3Smrg 98943345d3Smrg/* supported chipsets */ 99943345d3Smrgstatic SymTabRec ARKChipsets[] = { 100943345d3Smrg { PCI_CHIP_1000PV, "ark1000pv" }, 101943345d3Smrg { PCI_CHIP_2000PV, "ark2000pv" }, 102943345d3Smrg { PCI_CHIP_2000MT, "ark2000mt" }, 103943345d3Smrg { -1, NULL } 104943345d3Smrg}; 105943345d3Smrg 106943345d3Smrgstatic PciChipsets ARKPciChipsets[] = { 107943345d3Smrg { PCI_CHIP_1000PV, PCI_CHIP_1000PV, RES_SHARED_VGA }, 108943345d3Smrg { PCI_CHIP_2000PV, PCI_CHIP_2000PV, RES_SHARED_VGA }, 109943345d3Smrg { PCI_CHIP_2000MT, PCI_CHIP_2000MT, RES_SHARED_VGA }, 110943345d3Smrg { -1, -1, RES_UNDEFINED } 111943345d3Smrg}; 112943345d3Smrg 113943345d3Smrgtypedef enum { 114943345d3Smrg OPTION_NOACCEL 115943345d3Smrg} ARKOpts; 116943345d3Smrg 117943345d3Smrgstatic const OptionInfoRec ARKOptions[] = { 118943345d3Smrg { OPTION_NOACCEL, "noaccel", OPTV_BOOLEAN, {0}, FALSE }, 119943345d3Smrg { -1, NULL, OPTV_NONE, {0}, FALSE } 120943345d3Smrg}; 121943345d3Smrg 122943345d3Smrg#ifdef XFree86LOADER 123943345d3Smrg 124943345d3SmrgMODULESETUPPROTO(ARKSetup); 125943345d3Smrg 126943345d3Smrgstatic XF86ModuleVersionInfo ARKVersRec = { 127943345d3Smrg "ark", 128943345d3Smrg MODULEVENDORSTRING, 129943345d3Smrg MODINFOSTRING1, 130943345d3Smrg MODINFOSTRING2, 131943345d3Smrg XORG_VERSION_CURRENT, 132943345d3Smrg VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, 133943345d3Smrg ABI_CLASS_VIDEODRV, 134943345d3Smrg ABI_VIDEODRV_VERSION, 135943345d3Smrg MOD_CLASS_VIDEODRV, 136943345d3Smrg {0, 0, 0, 0} 137943345d3Smrg}; 138943345d3Smrg 139943345d3Smrg_X_EXPORT XF86ModuleData arkModuleData = { &ARKVersRec, ARKSetup, NULL }; 140943345d3Smrg 141943345d3Smrgpointer ARKSetup(pointer module, pointer opts, int *errmaj, int *errmin) 142943345d3Smrg{ 143943345d3Smrg static Bool setupDone = FALSE; 144943345d3Smrg 145943345d3Smrg if (!setupDone) { 146943345d3Smrg setupDone = TRUE; 147943345d3Smrg xf86AddDriver(&ARK, module, 0); 148943345d3Smrg return (pointer) 1; 149943345d3Smrg } else { 150943345d3Smrg if (errmaj) 151943345d3Smrg *errmaj = LDR_ONCEONLY; 152943345d3Smrg return NULL; 153943345d3Smrg } 154943345d3Smrg} 155943345d3Smrg 156943345d3Smrg#endif /* XFree86LOADER */ 157943345d3Smrg 158943345d3Smrg 159943345d3Smrgstatic Bool ARKGetRec(ScrnInfoPtr pScrn) 160943345d3Smrg{ 161943345d3Smrg if (pScrn->driverPrivate) 162943345d3Smrg return TRUE; 163943345d3Smrg 164943345d3Smrg pScrn->driverPrivate = xnfcalloc(sizeof(ARKRec), 1); 165943345d3Smrg 166943345d3Smrg return TRUE; 167943345d3Smrg} 168943345d3Smrg 169943345d3Smrgstatic void ARKFreeRec(ScrnInfoPtr pScrn) 170943345d3Smrg{ 1713e51e026Smrg free(pScrn->driverPrivate); 172943345d3Smrg pScrn->driverPrivate = NULL; 173943345d3Smrg} 174943345d3Smrg 175943345d3Smrgstatic const OptionInfoRec * ARKAvailableOptions(int chipid, int busid) 176943345d3Smrg{ 177943345d3Smrg return ARKOptions; 178943345d3Smrg} 179943345d3Smrg 180943345d3Smrgstatic void ARKIdentify(int flags) 181943345d3Smrg{ 182943345d3Smrg xf86PrintChipsets("ARK", "driver (version " DRIVER_VERSION " for ARK Logic chipset", 183943345d3Smrg ARKChipsets); 184943345d3Smrg} 185943345d3Smrg 186943345d3Smrgstatic Bool ARKProbe(DriverPtr drv, int flags) 187943345d3Smrg{ 188943345d3Smrg int i; 189943345d3Smrg GDevPtr *devSections; 190943345d3Smrg int *usedChips; 191943345d3Smrg int numDevSections; 192943345d3Smrg int numUsed; 193943345d3Smrg Bool foundScreen = FALSE; 194943345d3Smrg 195943345d3Smrg /* sanity check */ 196943345d3Smrg if ((numDevSections = xf86MatchDevice("ark", &devSections)) <= 0) 197943345d3Smrg return FALSE; 198943345d3Smrg 199943345d3Smrg /* do ISA later */ 200943345d3Smrg numUsed = xf86MatchPciInstances("ark", PCI_VENDOR_ARK, 201943345d3Smrg ARKChipsets, ARKPciChipsets, 202943345d3Smrg devSections, numDevSections, drv, 203943345d3Smrg &usedChips); 204943345d3Smrg 2053e51e026Smrg free(devSections); 206943345d3Smrg 207943345d3Smrg if (numUsed <= 0) 208943345d3Smrg return FALSE; 209943345d3Smrg 210943345d3Smrg if (flags & PROBE_DETECT) 211943345d3Smrg foundScreen = TRUE; 212943345d3Smrg else for (i=0; i<numUsed; i++) { 2135e695a52Smrg ScrnInfoPtr pScrn = NULL; 2145e695a52Smrg 2155e695a52Smrg pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], ARKPciChipsets, 2165e695a52Smrg NULL, NULL, NULL, NULL, NULL); 217943345d3Smrg 218943345d3Smrg pScrn->driverVersion = VERSION_MAJOR; 219943345d3Smrg pScrn->driverName = DRIVER_NAME; 220943345d3Smrg pScrn->name = "ark"; 221943345d3Smrg pScrn->Probe = ARKProbe; 222943345d3Smrg pScrn->PreInit = ARKPreInit; 223943345d3Smrg pScrn->ScreenInit = ARKScreenInit; 224943345d3Smrg pScrn->SwitchMode = ARKSwitchMode; 225943345d3Smrg pScrn->AdjustFrame = ARKAdjustFrame; 226943345d3Smrg pScrn->EnterVT = ARKEnterVT; 227943345d3Smrg pScrn->LeaveVT = ARKLeaveVT; 228943345d3Smrg pScrn->FreeScreen = ARKFreeScreen; 229943345d3Smrg foundScreen = TRUE; 230943345d3Smrg } 231943345d3Smrg 2323e51e026Smrg free(usedChips); 233943345d3Smrg 234943345d3Smrg return foundScreen; 235943345d3Smrg} 236943345d3Smrg 237943345d3Smrg 238943345d3Smrgstatic Bool ARKPreInit(ScrnInfoPtr pScrn, int flags) 239943345d3Smrg{ 240943345d3Smrg EntityInfoPtr pEnt; 241943345d3Smrg ARKPtr pARK; 242943345d3Smrg vgaHWPtr hwp; 243943345d3Smrg int i; 244943345d3Smrg ClockRangePtr clockRanges; 245943345d3Smrg rgb zeros = {0, 0, 0}; 246943345d3Smrg Gamma gzeros = {0.0, 0.0, 0.0}; 247943345d3Smrg unsigned char tmp; 248943345d3Smrg 249943345d3Smrg if (flags & PROBE_DETECT) 250943345d3Smrg return FALSE; 251943345d3Smrg 252943345d3Smrg if (!xf86LoadSubModule(pScrn, "vgahw")) 253943345d3Smrg return FALSE; 254943345d3Smrg 255943345d3Smrg if (!vgaHWGetHWRec(pScrn)) 256943345d3Smrg return FALSE; 257943345d3Smrg 258943345d3Smrg hwp = VGAHWPTR(pScrn); 2593e51e026Smrg vgaHWSetStdFuncs(hwp); 260943345d3Smrg vgaHWGetIOBase(hwp); 261943345d3Smrg 262943345d3Smrg pScrn->monitor = pScrn->confScreen->monitor; 263943345d3Smrg 264943345d3Smrg if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb)) 265943345d3Smrg return FALSE; 266943345d3Smrg else { 267943345d3Smrg switch (pScrn->depth) { 268943345d3Smrg case 8: 269943345d3Smrg case 16: 270943345d3Smrg case 24: 271943345d3Smrg case 32: 272943345d3Smrg /* OK */ 273943345d3Smrg break; 274943345d3Smrg default: 275943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 276943345d3Smrg "Given depth (%d) is not supported by this driver\n", 277943345d3Smrg pScrn->depth); 278943345d3Smrg return FALSE; 279943345d3Smrg } 280943345d3Smrg } 281943345d3Smrg 282943345d3Smrg xf86PrintDepthBpp(pScrn); 283943345d3Smrg 284943345d3Smrg if (pScrn->depth > 8) { 285943345d3Smrg if (!xf86SetWeight(pScrn, zeros, zeros)) 286943345d3Smrg return FALSE; 287943345d3Smrg } 288943345d3Smrg 289943345d3Smrg if (pScrn->depth == 8) 290943345d3Smrg pScrn->rgbBits = 8; 291943345d3Smrg 292943345d3Smrg if (!xf86SetDefaultVisual(pScrn, -1)) 293943345d3Smrg return FALSE; 294943345d3Smrg 295943345d3Smrg pScrn->progClock = TRUE; 296943345d3Smrg 297943345d3Smrg if (!ARKGetRec(pScrn)) 298943345d3Smrg return FALSE; 299943345d3Smrg 300943345d3Smrg pARK = ARKPTR(pScrn); 301943345d3Smrg 302943345d3Smrg xf86CollectOptions(pScrn, NULL); 3033e51e026Smrg if (!(pARK->Options = malloc(sizeof(ARKOptions)))) 304943345d3Smrg return FALSE; 305943345d3Smrg memcpy(pARK->Options, ARKOptions, sizeof(ARKOptions)); 306943345d3Smrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pARK->Options); 307943345d3Smrg 308943345d3Smrg if (xf86ReturnOptValBool(pARK->Options, OPTION_NOACCEL, FALSE)) { 309943345d3Smrg pARK->NoAccel = TRUE; 310943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - acceleration disabled\n"); 311943345d3Smrg } else 312943345d3Smrg pARK->NoAccel = FALSE; 313943345d3Smrg 314943345d3Smrg if (pScrn->numEntities > 1) { 315943345d3Smrg ARKFreeRec(pScrn); 316943345d3Smrg return FALSE; 317943345d3Smrg } 318943345d3Smrg 319943345d3Smrg pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 320943345d3Smrg pARK->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 321943345d3Smrg 322943345d3Smrg if (pEnt->device->chipset && *pEnt->device->chipset) { 323943345d3Smrg pScrn->chipset = pEnt->device->chipset; 324943345d3Smrg pARK->Chipset = xf86StringToToken(ARKChipsets, pScrn->chipset); 325943345d3Smrg } else if (pEnt->device->chipID >= 0) { 326943345d3Smrg pARK->Chipset = pEnt->device->chipID; 327943345d3Smrg pScrn->chipset = (char *)xf86TokenToString(ARKChipsets, 328943345d3Smrg pARK->Chipset); 329943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 330943345d3Smrg pARK->Chipset); 331943345d3Smrg } else { 332f67b85aaSmrg#ifndef XSERVER_LIBPCIACCESS 333943345d3Smrg pARK->Chipset = pARK->PciInfo->chipType; 334f67b85aaSmrg#else 335f67b85aaSmrg pARK->Chipset = pARK->PciInfo->device_id; 336f67b85aaSmrg#endif 337943345d3Smrg pScrn->chipset = (char *)xf86TokenToString(ARKChipsets, 338943345d3Smrg pARK->Chipset); 339943345d3Smrg } 340943345d3Smrg 341943345d3Smrg if (pEnt->device->chipRev >= 0) { 342943345d3Smrg pARK->ChipRev = pEnt->device->chipRev; 343943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 344943345d3Smrg pARK->ChipRev); 345f67b85aaSmrg } else { 346f67b85aaSmrg#ifndef XSERVER_LIBPCIACCESS 347943345d3Smrg pARK->ChipRev = pARK->PciInfo->chipRev; 348f67b85aaSmrg#else 349f67b85aaSmrg pARK->ChipRev = pARK->PciInfo->revision; 350f67b85aaSmrg#endif 351f67b85aaSmrg } 3523e51e026Smrg free(pEnt); 353943345d3Smrg 354943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", pScrn->chipset); 355943345d3Smrg 356f67b85aaSmrg#ifndef XSERVER_LIBPCIACCESS 357943345d3Smrg pARK->PciTag = pciTag(pARK->PciInfo->bus, pARK->PciInfo->device, 358943345d3Smrg pARK->PciInfo->func); 359f67b85aaSmrg#endif 360943345d3Smrg 361943345d3Smrg /* unlock CRTC[0-7] */ 3623e51e026Smrg outb(PIOOFFSET + hwp->IOBase + 4, 0x11); 3633e51e026Smrg tmp = inb(PIOOFFSET + hwp->IOBase + 5); 3643e51e026Smrg outb(PIOOFFSET + hwp->IOBase + 5, tmp & 0x7f); 3653e51e026Smrg modinx(PIOOFFSET + 0x3c4, 0x1d, 0x01, 0x01); 366943345d3Smrg 3673e51e026Smrg#ifndef XSERVER_LIBPCIACCESS 3683e51e026Smrg pScrn->memPhysBase = pARK->PciInfo->memBase[0]; 3693e51e026Smrg#else 3703e51e026Smrg pScrn->memPhysBase = pARK->PciInfo->regions[0].base_addr; 3713e51e026Smrg#endif 372943345d3Smrg 373943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Framebuffer @ 0x%lx\n", 3743e51e026Smrg (unsigned long)pScrn->memPhysBase); 375943345d3Smrg 376943345d3Smrg if (!xf86SetGamma(pScrn, gzeros)) 377943345d3Smrg return FALSE; 378943345d3Smrg 379943345d3Smrg if (!pScrn->videoRam) { 380943345d3Smrg unsigned char sr10; 381943345d3Smrg 3823e51e026Smrg sr10 = rdinx(PIOOFFSET + 0x3c4, 0x10); 383943345d3Smrg if (pARK->Chipset == PCI_CHIP_1000PV) { 384943345d3Smrg if ((sr10 & 0x40) == 0) 385943345d3Smrg pScrn->videoRam = 1024; 386943345d3Smrg else 387943345d3Smrg pScrn->videoRam = 2048; 388943345d3Smrg } 389943345d3Smrg if (pARK->Chipset == PCI_CHIP_2000PV || 390943345d3Smrg pARK->Chipset == PCI_CHIP_2000MT) { 391943345d3Smrg if ((sr10 & 0xc0) == 0) 392943345d3Smrg pScrn->videoRam = 1024; 393943345d3Smrg else if ((sr10 & 0xc0) == 0x40) 394943345d3Smrg pScrn->videoRam = 2048; 395943345d3Smrg else 396943345d3Smrg pScrn->videoRam = 4096; 397943345d3Smrg } 398943345d3Smrg 399943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected %d bytes video ram\n", 400943345d3Smrg pScrn->videoRam); 401943345d3Smrg } 402943345d3Smrg 403943345d3Smrg /* try to detect the RAMDAC */ 404943345d3Smrg { 405943345d3Smrg int man_id, dev_id; 406943345d3Smrg 4073e51e026Smrg inb(PIOOFFSET + 0x3c6); /* skip cmd register */ 4083e51e026Smrg man_id = inb(PIOOFFSET + 0x3c6); /* manufacturer id */ 4093e51e026Smrg dev_id = inb(PIOOFFSET + 0x3c6); /* device id */ 410943345d3Smrg if (man_id == 0x84 && dev_id == 0x98) { 411943345d3Smrg pARK->ramdac = ZOOMDAC; 412943345d3Smrg pARK->dac_width = 16; 413943345d3Smrg pARK->multiplex_threshold = 40000; 414943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 415943345d3Smrg "Detected ZOOMDAC\n"); 416943345d3Smrg } 417943345d3Smrg } 418943345d3Smrg 419943345d3Smrg /* hack for this Bali32 */ 420943345d3Smrg pARK->ramdac = ATT490; 421943345d3Smrg pARK->dac_width = 8; 422943345d3Smrg 423943345d3Smrg pARK->clock_mult = 1; 424943345d3Smrg if (pARK->dac_width == 16) { 425943345d3Smrg if (pScrn->bitsPerPixel == 32) 426943345d3Smrg pARK->clock_mult = 2; 427943345d3Smrg } 428943345d3Smrg 429943345d3Smrg clockRanges = xnfcalloc(sizeof(ClockRange), 1); 430943345d3Smrg clockRanges->next = NULL; 431943345d3Smrg clockRanges->minClock = 20000; 432943345d3Smrg clockRanges->maxClock = 80000; 433943345d3Smrg clockRanges->clockIndex = -1; 434943345d3Smrg clockRanges->interlaceAllowed = FALSE; /* ? */ 435943345d3Smrg clockRanges->doubleScanAllowed = FALSE; /* ? */ 436943345d3Smrg 437943345d3Smrg i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 438943345d3Smrg pScrn->display->modes, clockRanges, 439943345d3Smrg NULL, 256, 2048, pScrn->bitsPerPixel, 440943345d3Smrg 128, 2048, pScrn->display->virtualX, 441943345d3Smrg pScrn->display->virtualY, pARK->videoRam * 1024, 442943345d3Smrg LOOKUP_BEST_REFRESH); 443943345d3Smrg if (i == -1) { 444943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n"); 445943345d3Smrg ARKFreeRec(pScrn); 446943345d3Smrg return FALSE; 447943345d3Smrg } 448943345d3Smrg 449943345d3Smrg xf86PruneDriverModes(pScrn); 450943345d3Smrg 451943345d3Smrg if (i == 0 || pScrn->modes == NULL) { 452943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes found\n"); 453943345d3Smrg ARKFreeRec(pScrn); 454943345d3Smrg return FALSE; 455943345d3Smrg } 456943345d3Smrg 457943345d3Smrg xf86SetCrtcForModes(pScrn, 0); 458943345d3Smrg pScrn->currentMode = pScrn->modes; 459943345d3Smrg xf86PrintModes(pScrn); 460943345d3Smrg xf86SetDpi(pScrn, 0, 0); 461943345d3Smrg 462943345d3Smrg if (!xf86LoadSubModule(pScrn, "fb")) { 463943345d3Smrg ARKFreeRec(pScrn); 464943345d3Smrg return FALSE; 465943345d3Smrg } 466943345d3Smrg 467943345d3Smrg if (!pARK->NoAccel) { 468943345d3Smrg if (!xf86LoadSubModule(pScrn, "xaa")) { 4693e51e026Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 4703e51e026Smrg "XAA not available\n"); 4713e51e026Smrg pARK->NoAccel = 1; 472943345d3Smrg } 473943345d3Smrg } 474943345d3Smrg 475943345d3Smrg return TRUE; 476943345d3Smrg} 477943345d3Smrg 4783e51e026Smrgstatic Bool ARKScreenInit(SCREEN_INIT_ARGS_DECL) 479943345d3Smrg{ 4803e51e026Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 481943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 482943345d3Smrg 483943345d3Smrg pScrn->fbOffset = 0; 484943345d3Smrg 485943345d3Smrg if (!ARKMapMem(pScrn)) { 486943345d3Smrg ARKFreeRec(pScrn); 487943345d3Smrg return FALSE; 488943345d3Smrg } 489943345d3Smrg 490943345d3Smrg ARKSave(pScrn); 491943345d3Smrg 492943345d3Smrg vgaHWBlankScreen(pScrn, TRUE); 493943345d3Smrg 494943345d3Smrg if (!ARKModeInit(pScrn, pScrn->currentMode)) 495943345d3Smrg return FALSE; 496943345d3Smrg 497943345d3Smrg ARKSaveScreen(pScreen, SCREEN_SAVER_ON); 498943345d3Smrg 4993e51e026Smrg pScrn->AdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 500943345d3Smrg 501943345d3Smrg miClearVisualTypes(); 502943345d3Smrg if (pScrn->bitsPerPixel > 8) { 503943345d3Smrg if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 504943345d3Smrg pScrn->rgbBits, pScrn->defaultVisual)) 505943345d3Smrg return FALSE; 506943345d3Smrg } else { 507943345d3Smrg if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 508943345d3Smrg pScrn->rgbBits, pScrn->defaultVisual)) 509943345d3Smrg return FALSE; 510943345d3Smrg } 511943345d3Smrg 512943345d3Smrg miSetPixmapDepths (); 513943345d3Smrg 514943345d3Smrg if (!fbScreenInit(pScreen, pARK->FBBase, pScrn->virtualX, 515943345d3Smrg pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 516943345d3Smrg pScrn->displayWidth, pScrn->bitsPerPixel)) 517943345d3Smrg return FALSE; 518943345d3Smrg 519943345d3Smrg xf86SetBlackWhitePixels(pScreen); 520943345d3Smrg 521943345d3Smrg if (pScrn->bitsPerPixel > 8) { 522943345d3Smrg VisualPtr pVis; 523943345d3Smrg 524943345d3Smrg pVis = pScreen->visuals + pScreen->numVisuals; 525943345d3Smrg while (--pVis >= pScreen->visuals) { 526943345d3Smrg if ((pVis->class | DynamicClass) == DirectColor) { 527943345d3Smrg pVis->offsetRed = pScrn->offset.red; 528943345d3Smrg pVis->offsetGreen = pScrn->offset.green; 529943345d3Smrg pVis->offsetBlue = pScrn->offset.blue; 530943345d3Smrg pVis->redMask = pScrn->mask.red; 531943345d3Smrg pVis->greenMask = pScrn->mask.green; 532943345d3Smrg pVis->blueMask = pScrn->mask.blue; 533943345d3Smrg } 534943345d3Smrg } 535943345d3Smrg } 536943345d3Smrg 537943345d3Smrg /* must be after RGB order fixed */ 538943345d3Smrg 539943345d3Smrg fbPictureInit (pScreen, 0, 0); 540943345d3Smrg 541943345d3Smrg miInitializeBackingStore(pScreen); 542943345d3Smrg xf86SetBackingStore(pScreen); 543943345d3Smrg 544943345d3Smrg if (!pARK->NoAccel) { 545943345d3Smrg if (ARKAccelInit(pScreen)) { 5463e51e026Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration enabled\n"); 547943345d3Smrg } else { 5483e51e026Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration initialization failed\n"); 5493e51e026Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n"); 550943345d3Smrg } 551943345d3Smrg } else { 5523e51e026Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n"); 553943345d3Smrg } 554943345d3Smrg 555943345d3Smrg miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 556943345d3Smrg 557943345d3Smrg if (!miCreateDefColormap(pScreen)) 558943345d3Smrg return FALSE; 559943345d3Smrg 560943345d3Smrg if (!xf86HandleColormaps(pScreen, 256, 8, ARKLoadPalette, NULL, 561943345d3Smrg CMAP_RELOAD_ON_MODE_SWITCH)) 562943345d3Smrg return FALSE; 563943345d3Smrg 564943345d3Smrg vgaHWBlankScreen(pScrn, FALSE); 565943345d3Smrg 566943345d3Smrg pScreen->SaveScreen = ARKSaveScreen; 567943345d3Smrg pARK->CloseScreen = pScreen->CloseScreen; 568943345d3Smrg pScreen->CloseScreen = ARKCloseScreen; 569943345d3Smrg 570943345d3Smrg return TRUE; 571943345d3Smrg} 572943345d3Smrg 573943345d3Smrg 574943345d3Smrg 575943345d3Smrgstatic void ARKSave(ScrnInfoPtr pScrn) 576943345d3Smrg{ 577943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 578943345d3Smrg ARKRegPtr save = &pARK->SavedRegs; 579943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 5803e51e026Smrg unsigned long isaIOBase = PIOOFFSET; 5813e51e026Smrg unsigned long vgaIOBase = isaIOBase + hwp->IOBase; 582943345d3Smrg 583943345d3Smrg vgaHWUnlock(hwp); 584943345d3Smrg vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); 585943345d3Smrg vgaHWLock(hwp); 586943345d3Smrg 587943345d3Smrg /* set read and write aperture index to 0 */ 588943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x15, 0x00); 589943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x16, 0x00); 590943345d3Smrg outb(isaIOBase + 0x3c8, 0); /* reset DAC register access mode */ 591943345d3Smrg 592943345d3Smrg save->sr10 = rdinx(isaIOBase + 0x3c4, 0x10); 593943345d3Smrg save->sr11 = rdinx(isaIOBase + 0x3c4, 0x11); 594943345d3Smrg save->sr12 = rdinx(isaIOBase + 0x3c4, 0x12); 595943345d3Smrg save->sr13 = rdinx(isaIOBase + 0x3c4, 0x13); 596943345d3Smrg save->sr14 = rdinx(isaIOBase + 0x3c4, 0x14); 597943345d3Smrg save->sr15 = rdinx(isaIOBase + 0x3c4, 0x15); 598943345d3Smrg save->sr16 = rdinx(isaIOBase + 0x3c4, 0x16); 599943345d3Smrg save->sr17 = rdinx(isaIOBase + 0x3c4, 0x17); 600943345d3Smrg save->sr18 = rdinx(isaIOBase + 0x3c4, 0x18); 601943345d3Smrg 602943345d3Smrg#if 0 603943345d3Smrg save->sr1d = rdinx(isaIOBase + 0x3c4, 0x1d); 604943345d3Smrg save->sr1c = rdinx(isaIOBase + 0x3c4, 0x1c); 605943345d3Smrg 606943345d3Smrg save->sr20 = rdinx(isaIOBase + 0x3c4, 0x20); 607943345d3Smrg save->sr21 = rdinx(isaIOBase + 0x3c4, 0x21); 608943345d3Smrg save->sr22 = rdinx(isaIOBase + 0x3c4, 0x22); 609943345d3Smrg save->sr23 = rdinx(isaIOBase + 0x3c4, 0x23); 610943345d3Smrg save->sr24 = rdinx(isaIOBase + 0x3c4, 0x24); 611943345d3Smrg save->sr25 = rdinx(isaIOBase + 0x3c4, 0x25); 612943345d3Smrg save->sr26 = rdinx(isaIOBase + 0x3c4, 0x26); 613943345d3Smrg save->sr27 = rdinx(isaIOBase + 0x3c4, 0x27); 614943345d3Smrg save->sr29 = rdinx(isaIOBase + 0x3c4, 0x29); 615943345d3Smrg save->sr2a = rdinx(isaIOBase + 0x3c4, 0x2a); 616943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 617943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 618943345d3Smrg save->sr28 = rdinx(isaIOBase + 0x3c4, 0x28); 619943345d3Smrg save->sr2b = rdinx(isaIOBase + 0x3c4, 0x2b); 620943345d3Smrg } 621943345d3Smrg#endif 622943345d3Smrg 623943345d3Smrg save->cr40 = rdinx(vgaIOBase + 4, 0x40); 624943345d3Smrg save->cr41 = rdinx(vgaIOBase + 4, 0x41); 625943345d3Smrg save->cr42 = rdinx(vgaIOBase + 4, 0x42); 626943345d3Smrg save->cr44 = rdinx(vgaIOBase + 4, 0x44); 627943345d3Smrg 628943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 629943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) 630943345d3Smrg save->cr46 = rdinx(vgaIOBase + 4, 0x46); 631943345d3Smrg 632943345d3Smrg /* save RAMDAC regs here, based on type */ 633943345d3Smrg save->dac_command = get_daccomm(isaIOBase); 634943345d3Smrg} 635943345d3Smrg 636943345d3Smrg 637943345d3Smrg 638943345d3Smrgstatic Bool ARKModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 639943345d3Smrg{ 640943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 641943345d3Smrg ARKRegPtr new = &pARK->ModeRegs; 642943345d3Smrg int multiplexing, dac16, modepitch; 643943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 644943345d3Smrg vgaRegPtr pVga = &hwp->ModeReg; 6453e51e026Smrg unsigned long isaIOBase = PIOOFFSET; 6463e51e026Smrg unsigned long vgaIOBase = isaIOBase + hwp->IOBase; 647943345d3Smrg unsigned char tmp; 648943345d3Smrg int offset; 649943345d3Smrg 650943345d3Smrg multiplexing = 0; 651943345d3Smrg 652943345d3Smrg if ((pScrn->bitsPerPixel == 8) && (pARK->dac_width == 16) && 653943345d3Smrg (mode->Clock > pARK->multiplex_threshold)) 654943345d3Smrg multiplexing = 1; 655943345d3Smrg 656943345d3Smrg if (pARK->clock_mult == 2) { 657943345d3Smrg if (!mode->CrtcHAdjusted) { 658943345d3Smrg mode->CrtcHDisplay <<= 1; 659943345d3Smrg mode->CrtcHSyncStart <<= 1; 660943345d3Smrg mode->CrtcHSyncEnd <<= 1; 661943345d3Smrg mode->CrtcHTotal <<= 1; 662943345d3Smrg mode->CrtcHSkew <<= 1; 663943345d3Smrg mode->CrtcHAdjusted = TRUE; 664943345d3Smrg } 665943345d3Smrg } 666943345d3Smrg 667943345d3Smrg if (multiplexing) { 668943345d3Smrg if (!mode->CrtcHAdjusted) { 669943345d3Smrg mode->CrtcHDisplay >>= 1; 670943345d3Smrg mode->CrtcHSyncStart >>= 1; 671943345d3Smrg mode->CrtcHSyncEnd >>= 1; 672943345d3Smrg mode->CrtcHTotal >>= 1; 673943345d3Smrg mode->CrtcHSkew >>= 1; 674943345d3Smrg mode->CrtcHAdjusted = TRUE; 675943345d3Smrg } 676943345d3Smrg } 677943345d3Smrg 678943345d3Smrg if (!vgaHWInit(pScrn, mode)) 679943345d3Smrg return FALSE; 680943345d3Smrg 681943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 682943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 683943345d3Smrg new->cr46 = rdinx(vgaIOBase + 4, 0x46) & ~0x04; 684943345d3Smrg dac16 = 0; 685943345d3Smrg if (pScrn->bitsPerPixel > 8) 686943345d3Smrg dac16 = 1; 687943345d3Smrg if (dac16) 688943345d3Smrg new->cr46 |= 0x04; 689943345d3Smrg } 690943345d3Smrg 691943345d3Smrg offset = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3; 692943345d3Smrg pVga->CRTC[0x13] = offset; 693943345d3Smrg new->cr41 = (offset & 0x100) >> 5; 694943345d3Smrg 695943345d3Smrg new->sr11 = 0x90; 696943345d3Smrg switch (pScrn->bitsPerPixel) { 697943345d3Smrg case 8: 698943345d3Smrg new->sr11 |= 0x06; 699943345d3Smrg break; 700943345d3Smrg case 16: 701943345d3Smrg new->sr11 |= 0x0a; 702943345d3Smrg break; 703943345d3Smrg case 24: 704943345d3Smrg new->sr11 |= 0x06; 705943345d3Smrg break; 706943345d3Smrg case 32: 707943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 708943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) 709943345d3Smrg new->sr11 |= 0x0e; 710943345d3Smrg else 711943345d3Smrg new->sr11 |= 0x0a; 712943345d3Smrg break; 713943345d3Smrg default: 714943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 715943345d3Smrg "Unsupported screen depth %d\n", 716943345d3Smrg pScrn->bitsPerPixel); 717943345d3Smrg return FALSE; 718943345d3Smrg } 719943345d3Smrg 720943345d3Smrg switch (pScrn->displayWidth) { 721943345d3Smrg case 640: 722943345d3Smrg modepitch = 0; 723943345d3Smrg break; 724943345d3Smrg case 800: 725943345d3Smrg modepitch = 1; 726943345d3Smrg break; 727943345d3Smrg case 1024: 728943345d3Smrg modepitch = 2; 729943345d3Smrg break; 730943345d3Smrg case 1280: 731943345d3Smrg modepitch = 4; 732943345d3Smrg break; 733943345d3Smrg case 1600: 734943345d3Smrg modepitch = 5; 735943345d3Smrg break; 736943345d3Smrg case 2048: 737943345d3Smrg modepitch = 6; 738943345d3Smrg break; 739943345d3Smrg default: 740943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 741943345d3Smrg "Unsupported screen width %d\n", 742943345d3Smrg pScrn->displayWidth); 743943345d3Smrg return FALSE; 744943345d3Smrg } 745943345d3Smrg 746943345d3Smrg new->sr17 &= ~0xc7; 747943345d3Smrg new->sr17 |= modepitch; 748943345d3Smrg 749943345d3Smrg new->sr10 = rdinx(isaIOBase + 0x3c4, 0x10) & ~0x1f; 750943345d3Smrg new->sr10 |= 0x1f; 751943345d3Smrg 7523e51e026Smrg#ifndef XSERVER_LIBPCIACCESS 7533e51e026Smrg new->sr13 = pARK->PciInfo->memBase[0] >> 16; 7543e51e026Smrg new->sr14 = pARK->PciInfo->memBase[0] >> 24; 7553e51e026Smrg#else 7563e51e026Smrg new->sr13 = pARK->PciInfo->regions[0].base_addr >> 16; 7573e51e026Smrg new->sr14 = pARK->PciInfo->regions[0].base_addr >> 24; 7583e51e026Smrg#endif 759943345d3Smrg 760943345d3Smrg new->sr12 = rdinx(isaIOBase + 0x3c4, 0x12) & ~0x03; 761943345d3Smrg switch (pScrn->videoRam) { 762943345d3Smrg case 1024: 763943345d3Smrg new->sr12 |= 0x01; 764943345d3Smrg break; 765943345d3Smrg case 2048: 766943345d3Smrg new->sr12 |= 0x02; 767943345d3Smrg break; 768943345d3Smrg case 4096: 769943345d3Smrg new->sr12 |= 0x03; 770943345d3Smrg break; 771943345d3Smrg default: 772943345d3Smrg new->sr12 |= 0x01; 773943345d3Smrg break; 774943345d3Smrg } 775943345d3Smrg 776943345d3Smrg new->sr15 = new->sr16 = 0; 777943345d3Smrg 778943345d3Smrg tmp = 0; 779943345d3Smrg if ((mode->CrtcVTotal - 2) & 0x400) 780943345d3Smrg tmp |= 0x80; 781943345d3Smrg if ((mode->CrtcVDisplay - 1) & 0x400) 782943345d3Smrg tmp |= 0x40; 783943345d3Smrg if (mode->CrtcVSyncStart & 0x400) 784943345d3Smrg tmp |= 0x10; 785943345d3Smrg new->cr40 = tmp; 786943345d3Smrg 787943345d3Smrg tmp = new->cr41; /* initialized earlier */ 788943345d3Smrg if ((mode->CrtcHTotal / 8 - 5) & 0x100) 789943345d3Smrg tmp |= 0x80; 790943345d3Smrg if ((mode->CrtcHDisplay / 8 - 1) & 0x100) 791943345d3Smrg tmp |= 0x40; 792943345d3Smrg if ((mode->CrtcHSyncStart / 8 - 1) & 0x100) 793943345d3Smrg tmp |= 0x20; 794943345d3Smrg if ((mode->CrtcHSyncStart / 8) & 0x100) 795943345d3Smrg tmp |= 0x10; 796943345d3Smrg new->cr41 |= tmp; 797943345d3Smrg 798943345d3Smrg new->cr44 = rdinx(vgaIOBase + 4, 0x44) & ~0x34; 799943345d3Smrg new->cr44 &= ~0x01; 800943345d3Smrg new->cr42 = 0; 801943345d3Smrg 802943345d3Smrg /* check interlace here later */ 803943345d3Smrg 804943345d3Smrg /* set display FIFO threshold */ 805943345d3Smrg { 806943345d3Smrg int threshold; 807943345d3Smrg int bandwidthused, percentused; 808943345d3Smrg 809943345d3Smrg /* mostly guesses here as I would need to know more about 810943345d3Smrg * and from the ramdac... 811943345d3Smrg */ 812943345d3Smrg bandwidthused = (mode->Clock / pARK->clock_mult) * 813943345d3Smrg (pScrn->bitsPerPixel / 8); 814943345d3Smrg /* 120000 is another guess */ 815943345d3Smrg percentused = (bandwidthused * 100) / 120000; 816943345d3Smrg tmp = rdinx(isaIOBase + 0x3c4, 0x18); 817943345d3Smrg if (pARK->Chipset == PCI_CHIP_1000PV) { 818943345d3Smrg threshold = 4; 819943345d3Smrg tmp |= 0x08; /* enable full FIFO (8 deep) */ 820943345d3Smrg tmp &= ~0x07; 821943345d3Smrg tmp |= threshold; 822943345d3Smrg } 823943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 824943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 825943345d3Smrg threshold = 12; 826943345d3Smrg if (percentused >= 45) 827943345d3Smrg threshold = 8; 828943345d3Smrg if (percentused >= 70) 829943345d3Smrg threshold = 4; 830943345d3Smrg tmp &= 0x40; 831943345d3Smrg tmp |= 0x10; 832943345d3Smrg tmp |= (threshold & 0x0e) >> 1; 833943345d3Smrg if (threshold & 0x01) 834943345d3Smrg tmp |= 0x80; 835943345d3Smrg if (threshold & 0x10) 836943345d3Smrg tmp |= 0x20; 837943345d3Smrg } 838943345d3Smrg new->sr18 = tmp; 839943345d3Smrg } 840943345d3Smrg 841943345d3Smrg /* setup the RAMDAC regs */ 842943345d3Smrg if (pARK->ramdac == ZOOMDAC) { 843943345d3Smrg new->dac_command = 0x04; 844943345d3Smrg if ((pScrn->bitsPerPixel == 8) && multiplexing) 845943345d3Smrg new->dac_command = 0x24; 846943345d3Smrg if ((pScrn->bitsPerPixel == 16) && (pARK->dac_width == 16)) 847943345d3Smrg /* assuming green weight is not 5 */ 848943345d3Smrg new->dac_command = 0x34; 849943345d3Smrg if ((pScrn->bitsPerPixel == 16) && (pARK->dac_width == 8)) 850943345d3Smrg new->dac_command = 0x64; 851943345d3Smrg if ((pScrn->bitsPerPixel == 24) && (pARK->dac_width == 16)) 852943345d3Smrg new->dac_command = 0xb4; /* packed */ 853943345d3Smrg if ((pScrn->bitsPerPixel == 32) && (pARK->dac_width == 16)) 854943345d3Smrg new->dac_command = 0x54; 855943345d3Smrg } else if (pARK->ramdac == ATT490) { 856943345d3Smrg new->dac_command = 0x00; 857943345d3Smrg if (pScrn->bitsPerPixel == 16) 858943345d3Smrg /* assuming green weight is 6 */ 859943345d3Smrg new->dac_command = 0xc0; 860943345d3Smrg if (pScrn->bitsPerPixel == 24) 861943345d3Smrg new->dac_command = 0xe0; 862943345d3Smrg } 863943345d3Smrg 864943345d3Smrg#if 0 865943345d3Smrg /* hw cursor regs */ 866943345d3Smrg new->sr20 = rdinx(isaIOBase + 0x3c4, 0x20); 867943345d3Smrg new->sr21 = rdinx(isaIOBase + 0x3c4, 0x21); 868943345d3Smrg new->sr22 = rdinx(isaIOBase + 0x3c4, 0x22); 869943345d3Smrg new->sr23 = rdinx(isaIOBase + 0x3c4, 0x23); 870943345d3Smrg new->sr24 = rdinx(isaIOBase + 0x3c4, 0x24); 871943345d3Smrg new->sr25 = rdinx(isaIOBase + 0x3c4, 0x25); 872943345d3Smrg new->sr26 = rdinx(isaIOBase + 0x3c4, 0x26); 873943345d3Smrg new->sr27 = rdinx(isaIOBase + 0x3c4, 0x27); 874943345d3Smrg new->sr29 = rdinx(isaIOBase + 0x3c4, 0x29); 875943345d3Smrg new->sr2a = rdinx(isaIOBase + 0x3c4, 0x2a); 876943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 877943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 878943345d3Smrg new->sr28 = rdinx(isaIOBase + 0x3c4, 0x28); 879943345d3Smrg new->sr2b = rdinx(isaIOBase + 0x3c4, 0x3b); 880943345d3Smrg } 881943345d3Smrg#endif 882943345d3Smrg 883943345d3Smrg 884943345d3Smrg ARKWriteMode(pScrn, pVga, new); 885943345d3Smrg 886943345d3Smrg return TRUE; 887943345d3Smrg} 888943345d3Smrg 889943345d3Smrg 8903e51e026Smrgstatic void ARKAdjustFrame(ADJUST_FRAME_ARGS_DECL) 891943345d3Smrg{ 8923e51e026Smrg SCRN_INFO_PTR(arg); 893943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 894943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 8953e51e026Smrg unsigned long vgaIOBase = PIOOFFSET + hwp->IOBase; 896943345d3Smrg int base; 897943345d3Smrg 898943345d3Smrg base = ((y * pScrn->displayWidth + x) * 899943345d3Smrg (pScrn->bitsPerPixel / 8)); 900943345d3Smrg 901943345d3Smrg if (((pARK->Chipset == PCI_CHIP_2000PV) || 902943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) && 903943345d3Smrg (pScrn->videoRam >= 2048)) 904943345d3Smrg base >>= 3; 905943345d3Smrg else 906943345d3Smrg base >>= 2; 907943345d3Smrg if (pScrn->bitsPerPixel == 24) 908943345d3Smrg base -= base % 3; 909943345d3Smrg 910943345d3Smrg outw(vgaIOBase + 4, (base & 0x00ff00) | 0x0c); 911943345d3Smrg outw(vgaIOBase + 4, ((base & 0x00ff) << 8) | 0x0d); 912943345d3Smrg 913943345d3Smrg modinx(vgaIOBase + 4, 0x40, 0x07, (base & 0x070000) >> 16); 914943345d3Smrg} 915943345d3Smrg 916943345d3Smrg 917943345d3Smrg 918943345d3Smrgstatic void ARKWriteMode(ScrnInfoPtr pScrn, vgaRegPtr pVga, ARKRegPtr new) 919943345d3Smrg{ 920943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 921943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 9223e51e026Smrg unsigned long isaIOBase = PIOOFFSET; 9233e51e026Smrg unsigned long vgaIOBase = isaIOBase + hwp->IOBase; 924943345d3Smrg 925943345d3Smrg vgaHWProtect(pScrn, TRUE); 926943345d3Smrg 927943345d3Smrg /* set read and write aperture index to 0 */ 928943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x15, 0x00); 929943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x16, 0x00); 930943345d3Smrg 931943345d3Smrg /* write the extended registers first so that textmode font 932943345d3Smrg * restoration can suceed 933943345d3Smrg */ 934943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x10, new->sr10); 935943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x11, new->sr11); 936943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x12, new->sr12); 937943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x13, new->sr13); 938943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x14, new->sr14); 939943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x15, new->sr15); 940943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x16, new->sr16); 941943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x17, new->sr17); 942943345d3Smrg 943943345d3Smrg#if 0 944943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x1c, new->sr1c); 945943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x1d, new->sr1d); 946943345d3Smrg 947943345d3Smrg /* hw cursor regs */ 948943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x20, new->sr20); 949943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x21, new->sr21); 950943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x22, new->sr22); 951943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x23, new->sr23); 952943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x24, new->sr24); 953943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x25, new->sr25); 954943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x26, new->sr26); 955943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x27, new->sr27); 956943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x29, new->sr29); 957943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x2a, new->sr2a); 958943345d3Smrg#endif 959943345d3Smrg 960943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 961943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) { 962943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x28, new->sr28); 963943345d3Smrg wrinx(isaIOBase + 0x3c4, 0x2B, new->sr2b); 964943345d3Smrg } 965943345d3Smrg 966943345d3Smrg wrinx(vgaIOBase + 4, 0x40, new->cr40); 967943345d3Smrg wrinx(vgaIOBase + 4, 0x41, new->cr41); 968943345d3Smrg wrinx(vgaIOBase + 4, 0x42, new->cr42); 969943345d3Smrg wrinx(vgaIOBase + 4, 0x44, new->cr44); 970943345d3Smrg 971943345d3Smrg if ((pARK->Chipset == PCI_CHIP_2000PV) || 972943345d3Smrg (pARK->Chipset == PCI_CHIP_2000MT)) 973943345d3Smrg wrinx(vgaIOBase + 4, 0x46, new->cr46); 974943345d3Smrg 975943345d3Smrg /* RAMDAC regs */ 976943345d3Smrg if (pARK->ramdac == ZOOMDAC) { 977943345d3Smrg set_daccom(isaIOBase, new->dac_command); 978943345d3Smrg } 979943345d3Smrg 980943345d3Smrg if (xf86IsPrimaryPci(pARK->PciInfo)) 981943345d3Smrg vgaHWRestore(pScrn, pVga, VGA_SR_ALL); 982943345d3Smrg else 983943345d3Smrg vgaHWRestore(pScrn, pVga, VGA_SR_MODE); 984943345d3Smrg 985943345d3Smrg vgaHWProtect(pScrn, FALSE); 986943345d3Smrg} 987943345d3Smrg 988943345d3Smrg 9893e51e026Smrgstatic Bool ARKEnterVT(VT_FUNC_ARGS_DECL) 990943345d3Smrg{ 9913e51e026Smrg SCRN_INFO_PTR(arg); 992943345d3Smrg 993943345d3Smrg if (!ARKModeInit(pScrn, pScrn->currentMode)) 994943345d3Smrg return FALSE; 995943345d3Smrg 9963e51e026Smrg ARKAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 997943345d3Smrg 998943345d3Smrg return TRUE; 999943345d3Smrg} 1000943345d3Smrg 1001943345d3Smrg 1002943345d3Smrg 10033e51e026Smrgstatic void ARKLeaveVT(VT_FUNC_ARGS_DECL) 1004943345d3Smrg{ 10053e51e026Smrg SCRN_INFO_PTR(arg); 1006943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 1007943345d3Smrg ARKRegPtr old = &pARK->SavedRegs; 1008943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1009943345d3Smrg 1010943345d3Smrg ARKWriteMode(pScrn, &hwp->ModeReg, old); 1011943345d3Smrg 1012943345d3Smrg vgaHWUnlock(hwp); 1013943345d3Smrg vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); 1014943345d3Smrg vgaHWLock(hwp); 1015943345d3Smrg} 1016943345d3Smrg 1017943345d3Smrg 1018943345d3Smrgstatic Bool ARKMapMem(ScrnInfoPtr pScrn) 1019943345d3Smrg{ 1020943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 1021943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1022943345d3Smrg 1023943345d3Smrg /* extended to cover MMIO space at 0xB8000 */ 1024943345d3Smrg hwp->MapSize = 0x20000; 1025943345d3Smrg 1026f67b85aaSmrg#ifndef XSERVER_LIBPCIACCESS 1027943345d3Smrg pARK->MMIOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO, 1028943345d3Smrg pARK->PciTag, 0xb8000, 0x8000); 1029943345d3Smrg 1030943345d3Smrg pARK->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 10313e51e026Smrg pARK->PciTag, pARK->PciInfo->memBase[0], 1032943345d3Smrg pScrn->videoRam * 1024); 1033f67b85aaSmrg#else 1034f67b85aaSmrg 10353e51e026Smrg (void) pci_device_map_legacy(pARK->PciInfo, 0xb8000, 0x8000, 10363e51e026Smrg PCI_DEV_MAP_FLAG_WRITABLE, 10373e51e026Smrg &pARK->MMIOBase); 1038f67b85aaSmrg 1039f67b85aaSmrg { 10403e51e026Smrg void** result = &pARK->FBBase; 1041f67b85aaSmrg int err = pci_device_map_range(pARK->PciInfo, 10423e51e026Smrg pARK->PciInfo->regions[0].base_addr, 1043f67b85aaSmrg pScrn->videoRam * 1024, 1044f67b85aaSmrg PCI_DEV_MAP_FLAG_WRITABLE | 1045f67b85aaSmrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 1046f67b85aaSmrg result); 1047f67b85aaSmrg 10483e51e026Smrg if (err) { 10493e51e026Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 10503e51e026Smrg "Cound not map framebuffer: %d\n", err); 1051f67b85aaSmrg return FALSE; 10523e51e026Smrg } 1053f67b85aaSmrg } 1054f67b85aaSmrg#endif 1055f67b85aaSmrg 1056943345d3Smrg if (!pARK->FBBase) { 1057943345d3Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1058943345d3Smrg "Cound not map framebuffer\n"); 1059943345d3Smrg return FALSE; 1060943345d3Smrg } 1061943345d3Smrg 1062943345d3Smrg return TRUE; 1063943345d3Smrg} 1064943345d3Smrg 1065943345d3Smrg 1066943345d3Smrgstatic void ARKUnmapMem(ScrnInfoPtr pScrn) 1067943345d3Smrg{ 1068943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 1069943345d3Smrg 1070943345d3Smrg /* XXX vgaHWMapMem() isn't called explicitly, so is this correct? */ 1071943345d3Smrg vgaHWUnmapMem(pScrn); 1072943345d3Smrg 1073f67b85aaSmrg#ifndef XSERVER_LIBPCIACCESS 10743e51e026Smrg xf86UnMapVidMem(pScrn->scrnIndex, pARK->FBBase, 1075943345d3Smrg pScrn->videoRam * 1024); 1076f67b85aaSmrg#else 1077f67b85aaSmrg pci_device_unmap_range(pARK->PciInfo, pARK->FBBase, pScrn->videoRam * 1024); 1078f67b85aaSmrg#endif 1079943345d3Smrg} 1080943345d3Smrg 1081943345d3Smrg 10823e51e026SmrgBool ARKCloseScreen(CLOSE_SCREEN_ARGS_DECL) 1083943345d3Smrg{ 10843e51e026Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1085943345d3Smrg ARKPtr pARK = ARKPTR(pScrn); 1086943345d3Smrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1087943345d3Smrg 1088943345d3Smrg if (pScrn->vtSema) { 1089943345d3Smrg vgaHWUnlock(hwp); 1090943345d3Smrg ARKWriteMode(pScrn, &hwp->SavedReg, &pARK->SavedRegs); 1091943345d3Smrg vgaHWLock(hwp); 1092943345d3Smrg ARKUnmapMem(pScrn); 1093943345d3Smrg } 1094943345d3Smrg 1095943345d3Smrg pScrn->vtSema = FALSE; 1096943345d3Smrg pScreen->CloseScreen = pARK->CloseScreen; 1097943345d3Smrg 1098943345d3Smrg /* XXX Shouldn't XAADestroyInfoRec() be called? */ 1099943345d3Smrg 11003e51e026Smrg return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 1101943345d3Smrg} 1102943345d3Smrg 1103943345d3Smrg 1104943345d3SmrgBool ARKSaveScreen(ScreenPtr pScreen, int mode) 1105943345d3Smrg{ 1106943345d3Smrg return vgaHWSaveScreen(pScreen, mode); 1107943345d3Smrg} 1108943345d3Smrg 1109943345d3Smrg 11103e51e026SmrgBool ARKSwitchMode(SWITCH_MODE_ARGS_DECL) 1111943345d3Smrg{ 11123e51e026Smrg SCRN_INFO_PTR(arg); 11133e51e026Smrg return ARKModeInit(pScrn, mode); 1114943345d3Smrg} 1115943345d3Smrg 1116943345d3Smrg 1117943345d3Smrgstatic void ARKLoadPalette(ScrnInfoPtr pScrn, int numColors, 1118943345d3Smrg int *indicies, LOCO *colors, 1119943345d3Smrg VisualPtr pVisual) 1120943345d3Smrg{ 11213e51e026Smrg unsigned long isaIOBase = 0; 11223e51e026Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12 11233e51e026Smrg isaIOBase += pScrn->domainIOBase; 11243e51e026Smrg#endif 1125943345d3Smrg int i, index; 1126943345d3Smrg 1127943345d3Smrg for (i=0; i<numColors; i++) { 1128943345d3Smrg index = indicies[i]; 1129943345d3Smrg outb(isaIOBase + 0x3c8, index); 1130943345d3Smrg outb(isaIOBase + 0x3c9, colors[index].red); 1131943345d3Smrg outb(isaIOBase + 0x3c9, colors[index].green); 1132943345d3Smrg outb(isaIOBase + 0x3c9, colors[index].blue); 1133943345d3Smrg } 1134943345d3Smrg} 1135943345d3Smrg 1136943345d3Smrg 11373e51e026Smrgstatic void ARKFreeScreen(FREE_SCREEN_ARGS_DECL) 1138943345d3Smrg{ 11393e51e026Smrg SCRN_INFO_PTR(arg); 1140943345d3Smrg 1141943345d3Smrg vgaHWFreeHWRec(pScrn); 1142943345d3Smrg 1143943345d3Smrg ARKFreeRec(pScrn); 1144943345d3Smrg} 1145943345d3Smrg 1146943345d3Smrg 11473e51e026Smrgstatic unsigned char get_daccomm(unsigned long isaIOBase) 1148943345d3Smrg{ 1149943345d3Smrg unsigned char tmp; 1150943345d3Smrg 1151943345d3Smrg outb(isaIOBase + 0x3c8, 0); 1152943345d3Smrg inb(isaIOBase + 0x3c6); 1153943345d3Smrg inb(isaIOBase + 0x3c6); 1154943345d3Smrg inb(isaIOBase + 0x3c6); 1155943345d3Smrg inb(isaIOBase + 0x3c6); 1156943345d3Smrg tmp = inb(isaIOBase + 0x3c6); 1157943345d3Smrg outb(isaIOBase + 0x3c8, 0); 1158943345d3Smrg 1159943345d3Smrg return tmp; 1160943345d3Smrg} 1161943345d3Smrg 1162943345d3Smrg 11633e51e026Smrgstatic unsigned char set_daccom(unsigned long isaIOBase, unsigned char comm) 1164943345d3Smrg{ 1165943345d3Smrg#if 0 1166943345d3Smrg outb(isaIOBase + 0x3c8, 0); 1167943345d3Smrg#else 1168943345d3Smrg inb(isaIOBase + 0x3c8); 1169943345d3Smrg#endif 1170943345d3Smrg inb(isaIOBase + 0x3c6); 1171943345d3Smrg inb(isaIOBase + 0x3c6); 1172943345d3Smrg inb(isaIOBase + 0x3c6); 1173943345d3Smrg inb(isaIOBase + 0x3c6); 1174943345d3Smrg outb(isaIOBase + 0x3c6, comm); 1175943345d3Smrg#if 0 1176943345d3Smrg outb(isaIOBase + 0x3c8, 0); 1177943345d3Smrg#else 1178943345d3Smrg inb(isaIOBase + 0x3c8); 1179943345d3Smrg#endif 1180943345d3Smrg 1181943345d3Smrg return inb(isaIOBase + 0x3c6); 1182943345d3Smrg} 1183