ark_driver.c revision f67b85aa
1/* 2 * Copyright 2000 Ani Joshi <ajoshi@unixbox.com> 3 * 4 * XFree86 4.x driver for ARK Logic chipset 5 * 6 * Permission to use, copy, modify, distribute, and sell this software and its 7 * documentation for any purpose is hereby granted without fee, provided that 8 * the above copyright notice appear in all copies and that both that copyright 9 * notice and this permission notice appear in supporting documentation and 10 * that the name of Ani Joshi not be used in advertising or 11 * publicity pertaining to distribution of the software without specific, 12 * written prior permission. Ani Joshi makes no representations 13 * about the suitability of this software for any purpose. It is provided 14 * "as-is" without express or implied warranty. 15 * 16 * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18 * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22 * PERFORMANCE OF THIS SOFTWARE. 23 * 24 * 25 * Based on the 3.3.x driver by: 26 * Harm Hanemaayer <H.Hanemaayer@inter.nl.net> 27 * 28 */ 29 30#ifdef HAVE_CONFIG_H 31#include "config.h" 32#endif 33 34#include "xf86.h" 35#include "xf86_OSproc.h" 36#include "xf86Pci.h" 37#include "xf86PciInfo.h" 38#include "xf86Resources.h" 39#include "xf86fbman.h" 40#include "xf86cmap.h" 41#include "compiler.h" 42#include "xaa.h" 43#include "mipointer.h" 44#include "micmap.h" 45#include "mibstore.h" 46#include "fb.h" 47#include "ark.h" 48 49#include <string.h> 50 51/* 52 * prototypes 53 */ 54static const OptionInfoRec * ARKAvailableOptions(int chipid, int busid); 55static void ARKIdentify(int flags); 56static Bool ARKProbe(DriverPtr drv, int flags); 57static Bool ARKPreInit(ScrnInfoPtr pScrn, int flags); 58static Bool ARKEnterVT(int scrnIndex, int flags); 59static void ARKLeaveVT(int scrnIndex, int flags); 60static void ARKSave(ScrnInfoPtr pScrn); 61static Bool ARKScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 62 char **argv); 63static Bool ARKMapMem(ScrnInfoPtr pScrn); 64static void ARKUnmapMem(ScrnInfoPtr pScrn); 65static Bool ARKModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 66static void ARKAdjustFrame(int scrnIndex, int x, int y, int flags); 67Bool ARKSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); 68Bool ARKCloseScreen(int scrnIndex, ScreenPtr pScreen); 69Bool ARKSaveScreen(ScreenPtr pScreen, int mode); 70static void ARKFreeScreen(int scrnIndex, int flags); 71static void ARKLoadPalette(ScrnInfoPtr pScrn, int numColors, 72 int *indicies, LOCO *colors, 73 VisualPtr pVisual); 74static void ARKWriteMode(ScrnInfoPtr pScrn, vgaRegPtr pVga, ARKRegPtr new); 75 76/* helpers */ 77static unsigned char get_daccomm(IOADDRESS); 78static unsigned char set_daccom(IOADDRESS, unsigned char comm); 79 80 81_X_EXPORT DriverRec ARK = 82{ 83 ARK_VERSION, 84 DRIVER_NAME, 85 ARKIdentify, 86 ARKProbe, 87 ARKAvailableOptions, 88 NULL, 89 0 90}; 91 92/* supported chipsets */ 93static SymTabRec ARKChipsets[] = { 94 { PCI_CHIP_1000PV, "ark1000pv" }, 95 { PCI_CHIP_2000PV, "ark2000pv" }, 96 { PCI_CHIP_2000MT, "ark2000mt" }, 97 { -1, NULL } 98}; 99 100static PciChipsets ARKPciChipsets[] = { 101 { PCI_CHIP_1000PV, PCI_CHIP_1000PV, RES_SHARED_VGA }, 102 { PCI_CHIP_2000PV, PCI_CHIP_2000PV, RES_SHARED_VGA }, 103 { PCI_CHIP_2000MT, PCI_CHIP_2000MT, RES_SHARED_VGA }, 104 { -1, -1, RES_UNDEFINED } 105}; 106 107typedef enum { 108 OPTION_NOACCEL 109} ARKOpts; 110 111static const OptionInfoRec ARKOptions[] = { 112 { OPTION_NOACCEL, "noaccel", OPTV_BOOLEAN, {0}, FALSE }, 113 { -1, NULL, OPTV_NONE, {0}, FALSE } 114}; 115 116static const char *fbSymbols[] = { 117 "fbPictureInit", 118 "fbScreenInit", 119 NULL 120}; 121 122static const char *vgaHWSymbols[] = { 123 "vgaHWFreeHWRec", 124 "vgaHWGetHWRec", 125 "vgaHWGetIOBase", 126 "vgaHWGetIndex", 127 "vgaHWInit", 128 "vgaHWLock", 129 "vgaHWProtect", 130 "vgaHWRestore", 131 "vgaHWSave", 132 "vgaHWSaveScreen", 133 "vgaHWUnlock", 134 "vgaHWUnmapMem", 135 NULL 136}; 137 138static const char *xaaSymbols[] = { 139 "XAACreateInfoRec", 140 "XAAInit", 141 NULL 142}; 143 144#ifdef XFree86LOADER 145 146MODULESETUPPROTO(ARKSetup); 147 148static XF86ModuleVersionInfo ARKVersRec = { 149 "ark", 150 MODULEVENDORSTRING, 151 MODINFOSTRING1, 152 MODINFOSTRING2, 153 XORG_VERSION_CURRENT, 154 VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, 155 ABI_CLASS_VIDEODRV, 156 ABI_VIDEODRV_VERSION, 157 MOD_CLASS_VIDEODRV, 158 {0, 0, 0, 0} 159}; 160 161_X_EXPORT XF86ModuleData arkModuleData = { &ARKVersRec, ARKSetup, NULL }; 162 163pointer ARKSetup(pointer module, pointer opts, int *errmaj, int *errmin) 164{ 165 static Bool setupDone = FALSE; 166 167 if (!setupDone) { 168 setupDone = TRUE; 169 xf86AddDriver(&ARK, module, 0); 170 LoaderRefSymLists(fbSymbols, vgaHWSymbols, xaaSymbols, NULL); 171 return (pointer) 1; 172 } else { 173 if (errmaj) 174 *errmaj = LDR_ONCEONLY; 175 return NULL; 176 } 177} 178 179#endif /* XFree86LOADER */ 180 181 182static Bool ARKGetRec(ScrnInfoPtr pScrn) 183{ 184 if (pScrn->driverPrivate) 185 return TRUE; 186 187 pScrn->driverPrivate = xnfcalloc(sizeof(ARKRec), 1); 188 189 return TRUE; 190} 191 192static void ARKFreeRec(ScrnInfoPtr pScrn) 193{ 194 if (!pScrn->driverPrivate) 195 return; 196 197 xfree(pScrn->driverPrivate); 198 pScrn->driverPrivate = NULL; 199} 200 201static const OptionInfoRec * ARKAvailableOptions(int chipid, int busid) 202{ 203 return ARKOptions; 204} 205 206static void ARKIdentify(int flags) 207{ 208 xf86PrintChipsets("ARK", "driver (version " DRIVER_VERSION " for ARK Logic chipset", 209 ARKChipsets); 210} 211 212static Bool ARKProbe(DriverPtr drv, int flags) 213{ 214 int i; 215 GDevPtr *devSections; 216 int *usedChips; 217 int numDevSections; 218 int numUsed; 219 Bool foundScreen = FALSE; 220 221 /* sanity check */ 222 if ((numDevSections = xf86MatchDevice("ark", &devSections)) <= 0) 223 return FALSE; 224 225 /* do ISA later */ 226 numUsed = xf86MatchPciInstances("ark", PCI_VENDOR_ARK, 227 ARKChipsets, ARKPciChipsets, 228 devSections, numDevSections, drv, 229 &usedChips); 230 231 xfree(devSections); 232 233 if (numUsed <= 0) 234 return FALSE; 235 236 if (flags & PROBE_DETECT) 237 foundScreen = TRUE; 238 else for (i=0; i<numUsed; i++) { 239 ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); 240 241 pScrn->driverVersion = VERSION_MAJOR; 242 pScrn->driverName = DRIVER_NAME; 243 pScrn->name = "ark"; 244 pScrn->Probe = ARKProbe; 245 pScrn->PreInit = ARKPreInit; 246 pScrn->ScreenInit = ARKScreenInit; 247 pScrn->SwitchMode = ARKSwitchMode; 248 pScrn->AdjustFrame = ARKAdjustFrame; 249 pScrn->EnterVT = ARKEnterVT; 250 pScrn->LeaveVT = ARKLeaveVT; 251 pScrn->FreeScreen = ARKFreeScreen; 252 foundScreen = TRUE; 253 xf86ConfigActivePciEntity(pScrn, usedChips[i], ARKPciChipsets, 254 NULL, NULL, NULL, NULL, NULL); 255 } 256 257 xfree(usedChips); 258 259 return foundScreen; 260} 261 262 263static Bool ARKPreInit(ScrnInfoPtr pScrn, int flags) 264{ 265 EntityInfoPtr pEnt; 266 ARKPtr pARK; 267 vgaHWPtr hwp; 268 int i; 269 ClockRangePtr clockRanges; 270 rgb zeros = {0, 0, 0}; 271 Gamma gzeros = {0.0, 0.0, 0.0}; 272 unsigned char tmp; 273 274 if (flags & PROBE_DETECT) 275 return FALSE; 276 277 if (!xf86LoadSubModule(pScrn, "vgahw")) 278 return FALSE; 279 280 xf86LoaderReqSymLists(vgaHWSymbols, NULL); 281 282 if (!vgaHWGetHWRec(pScrn)) 283 return FALSE; 284 285 hwp = VGAHWPTR(pScrn); 286 vgaHWGetIOBase(hwp); 287 288 pScrn->monitor = pScrn->confScreen->monitor; 289 290 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb)) 291 return FALSE; 292 else { 293 switch (pScrn->depth) { 294 case 8: 295 case 16: 296 case 24: 297 case 32: 298 /* OK */ 299 break; 300 default: 301 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 302 "Given depth (%d) is not supported by this driver\n", 303 pScrn->depth); 304 return FALSE; 305 } 306 } 307 308 xf86PrintDepthBpp(pScrn); 309 310 if (pScrn->depth > 8) { 311 if (!xf86SetWeight(pScrn, zeros, zeros)) 312 return FALSE; 313 } 314 315 if (pScrn->depth == 8) 316 pScrn->rgbBits = 8; 317 318 if (!xf86SetDefaultVisual(pScrn, -1)) 319 return FALSE; 320 321 pScrn->progClock = TRUE; 322 323 if (!ARKGetRec(pScrn)) 324 return FALSE; 325 326 pARK = ARKPTR(pScrn); 327 328 xf86CollectOptions(pScrn, NULL); 329 if (!(pARK->Options = xalloc(sizeof(ARKOptions)))) 330 return FALSE; 331 memcpy(pARK->Options, ARKOptions, sizeof(ARKOptions)); 332 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pARK->Options); 333 334 if (xf86ReturnOptValBool(pARK->Options, OPTION_NOACCEL, FALSE)) { 335 pARK->NoAccel = TRUE; 336 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - acceleration disabled\n"); 337 } else 338 pARK->NoAccel = FALSE; 339 340 if (pScrn->numEntities > 1) { 341 ARKFreeRec(pScrn); 342 return FALSE; 343 } 344 345 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 346 if (pEnt->resources) { 347 xfree(pEnt); 348 ARKFreeRec(pScrn); 349 return FALSE; 350 } 351 352 pARK->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 353 xf86RegisterResources(pEnt->index, NULL, ResNone); 354 xf86SetOperatingState(resVgaIo, pEnt->index, ResUnusedOpr); 355 xf86SetOperatingState(resVgaMem, pEnt->index, ResDisableOpr); 356 357 if (pEnt->device->chipset && *pEnt->device->chipset) { 358 pScrn->chipset = pEnt->device->chipset; 359 pARK->Chipset = xf86StringToToken(ARKChipsets, pScrn->chipset); 360 } else if (pEnt->device->chipID >= 0) { 361 pARK->Chipset = pEnt->device->chipID; 362 pScrn->chipset = (char *)xf86TokenToString(ARKChipsets, 363 pARK->Chipset); 364 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 365 pARK->Chipset); 366 } else { 367#ifndef XSERVER_LIBPCIACCESS 368 pARK->Chipset = pARK->PciInfo->chipType; 369#else 370 pARK->Chipset = pARK->PciInfo->device_id; 371#endif 372 pScrn->chipset = (char *)xf86TokenToString(ARKChipsets, 373 pARK->Chipset); 374 } 375 376 if (pEnt->device->chipRev >= 0) { 377 pARK->ChipRev = pEnt->device->chipRev; 378 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 379 pARK->ChipRev); 380 } else { 381#ifndef XSERVER_LIBPCIACCESS 382 pARK->ChipRev = pARK->PciInfo->chipRev; 383#else 384 pARK->ChipRev = pARK->PciInfo->revision; 385#endif 386 } 387 xfree(pEnt); 388 389 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", pScrn->chipset); 390 391#ifndef XSERVER_LIBPCIACCESS 392 pARK->PciTag = pciTag(pARK->PciInfo->bus, pARK->PciInfo->device, 393 pARK->PciInfo->func); 394#endif 395 396 /* unlock CRTC[0-7] */ 397 outb(hwp->PIOOffset + hwp->IOBase + 4, 0x11); 398 tmp = inb(hwp->PIOOffset + hwp->IOBase + 5); 399 outb(hwp->PIOOffset + hwp->IOBase + 5, tmp & 0x7f); 400 modinx(hwp->PIOOffset + 0x3c4, 0x1d, 0x01, 0x01); 401 402 /* use membase's later on ??? */ 403 pARK->FBAddress = (rdinx(hwp->PIOOffset + 0x3c4, 0x13) << 16) + 404 (rdinx(hwp->PIOOffset + 0x3c4, 0x14) << 24); 405 406 pScrn->memPhysBase = pARK->FBAddress; 407 408 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Framebuffer @ 0x%lx\n", 409 (unsigned long)pARK->FBAddress); 410 411 if (!xf86SetGamma(pScrn, gzeros)) 412 return FALSE; 413 414 if (!pScrn->videoRam) { 415 unsigned char sr10; 416 417 sr10 = rdinx(hwp->PIOOffset + 0x3c4, 0x10); 418 if (pARK->Chipset == PCI_CHIP_1000PV) { 419 if ((sr10 & 0x40) == 0) 420 pScrn->videoRam = 1024; 421 else 422 pScrn->videoRam = 2048; 423 } 424 if (pARK->Chipset == PCI_CHIP_2000PV || 425 pARK->Chipset == PCI_CHIP_2000MT) { 426 if ((sr10 & 0xc0) == 0) 427 pScrn->videoRam = 1024; 428 else if ((sr10 & 0xc0) == 0x40) 429 pScrn->videoRam = 2048; 430 else 431 pScrn->videoRam = 4096; 432 } 433 434 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected %d bytes video ram\n", 435 pScrn->videoRam); 436 } 437 438 /* try to detect the RAMDAC */ 439 { 440 int man_id, dev_id; 441 442 inb(hwp->PIOOffset + 0x3c6); /* skip cmd register */ 443 man_id = inb(hwp->PIOOffset + 0x3c6); /* manufacturer id */ 444 dev_id = inb(hwp->PIOOffset + 0x3c6); /* device id */ 445 if (man_id == 0x84 && dev_id == 0x98) { 446 pARK->ramdac = ZOOMDAC; 447 pARK->dac_width = 16; 448 pARK->multiplex_threshold = 40000; 449 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 450 "Detected ZOOMDAC\n"); 451 } 452 } 453 454 /* hack for this Bali32 */ 455 pARK->ramdac = ATT490; 456 pARK->dac_width = 8; 457 458 pARK->clock_mult = 1; 459 if (pARK->dac_width == 16) { 460 if (pScrn->bitsPerPixel == 32) 461 pARK->clock_mult = 2; 462 } 463 464 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 465 clockRanges->next = NULL; 466 clockRanges->minClock = 20000; 467 clockRanges->maxClock = 80000; 468 clockRanges->clockIndex = -1; 469 clockRanges->interlaceAllowed = FALSE; /* ? */ 470 clockRanges->doubleScanAllowed = FALSE; /* ? */ 471 472 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 473 pScrn->display->modes, clockRanges, 474 NULL, 256, 2048, pScrn->bitsPerPixel, 475 128, 2048, pScrn->display->virtualX, 476 pScrn->display->virtualY, pARK->videoRam * 1024, 477 LOOKUP_BEST_REFRESH); 478 if (i == -1) { 479 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n"); 480 ARKFreeRec(pScrn); 481 return FALSE; 482 } 483 484 xf86PruneDriverModes(pScrn); 485 486 if (i == 0 || pScrn->modes == NULL) { 487 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes found\n"); 488 ARKFreeRec(pScrn); 489 return FALSE; 490 } 491 492 xf86SetCrtcForModes(pScrn, 0); 493 pScrn->currentMode = pScrn->modes; 494 xf86PrintModes(pScrn); 495 xf86SetDpi(pScrn, 0, 0); 496 497 if (!xf86LoadSubModule(pScrn, "fb")) { 498 ARKFreeRec(pScrn); 499 return FALSE; 500 } 501 502 xf86LoaderReqSymLists(fbSymbols, NULL); 503 504 if (!pARK->NoAccel) { 505 if (!xf86LoadSubModule(pScrn, "xaa")) { 506 ARKFreeRec(pScrn); 507 return FALSE; 508 } 509 xf86LoaderReqSymLists(xaaSymbols, NULL); 510 } 511 512 return TRUE; 513} 514 515static Bool ARKScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 516 char **argv) 517{ 518 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 519 ARKPtr pARK = ARKPTR(pScrn); 520 521 pScrn->fbOffset = 0; 522 523 if (!ARKMapMem(pScrn)) { 524 ARKFreeRec(pScrn); 525 return FALSE; 526 } 527 528 ARKSave(pScrn); 529 530 vgaHWBlankScreen(pScrn, TRUE); 531 532 if (!ARKModeInit(pScrn, pScrn->currentMode)) 533 return FALSE; 534 535 ARKSaveScreen(pScreen, SCREEN_SAVER_ON); 536 537 pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 538 539 miClearVisualTypes(); 540 if (pScrn->bitsPerPixel > 8) { 541 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 542 pScrn->rgbBits, pScrn->defaultVisual)) 543 return FALSE; 544 } else { 545 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 546 pScrn->rgbBits, pScrn->defaultVisual)) 547 return FALSE; 548 } 549 550 miSetPixmapDepths (); 551 552 if (!fbScreenInit(pScreen, pARK->FBBase, pScrn->virtualX, 553 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 554 pScrn->displayWidth, pScrn->bitsPerPixel)) 555 return FALSE; 556 557 xf86SetBlackWhitePixels(pScreen); 558 559 if (pScrn->bitsPerPixel > 8) { 560 VisualPtr pVis; 561 562 pVis = pScreen->visuals + pScreen->numVisuals; 563 while (--pVis >= pScreen->visuals) { 564 if ((pVis->class | DynamicClass) == DirectColor) { 565 pVis->offsetRed = pScrn->offset.red; 566 pVis->offsetGreen = pScrn->offset.green; 567 pVis->offsetBlue = pScrn->offset.blue; 568 pVis->redMask = pScrn->mask.red; 569 pVis->greenMask = pScrn->mask.green; 570 pVis->blueMask = pScrn->mask.blue; 571 } 572 } 573 } 574 575 /* must be after RGB order fixed */ 576 577 fbPictureInit (pScreen, 0, 0); 578 579 miInitializeBackingStore(pScreen); 580 xf86SetBackingStore(pScreen); 581 582 if (!pARK->NoAccel) { 583 if (ARKAccelInit(pScreen)) { 584 xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); 585 } else { 586 xf86DrvMsg(scrnIndex, X_ERROR, "Acceleration initialization failed\n"); 587 xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); 588 } 589 } else { 590 xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); 591 } 592 593 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 594 595 if (!miCreateDefColormap(pScreen)) 596 return FALSE; 597 598 if (!xf86HandleColormaps(pScreen, 256, 8, ARKLoadPalette, NULL, 599 CMAP_RELOAD_ON_MODE_SWITCH)) 600 return FALSE; 601 602 vgaHWBlankScreen(pScrn, FALSE); 603 604 pScreen->SaveScreen = ARKSaveScreen; 605 pARK->CloseScreen = pScreen->CloseScreen; 606 pScreen->CloseScreen = ARKCloseScreen; 607 608 return TRUE; 609} 610 611 612 613static void ARKSave(ScrnInfoPtr pScrn) 614{ 615 ARKPtr pARK = ARKPTR(pScrn); 616 ARKRegPtr save = &pARK->SavedRegs; 617 vgaHWPtr hwp = VGAHWPTR(pScrn); 618 IOADDRESS isaIOBase = hwp->PIOOffset; 619 IOADDRESS vgaIOBase = isaIOBase + hwp->IOBase; 620 621 vgaHWUnlock(hwp); 622 vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); 623 vgaHWLock(hwp); 624 625 /* set read and write aperture index to 0 */ 626 wrinx(isaIOBase + 0x3c4, 0x15, 0x00); 627 wrinx(isaIOBase + 0x3c4, 0x16, 0x00); 628 outb(isaIOBase + 0x3c8, 0); /* reset DAC register access mode */ 629 630 save->sr10 = rdinx(isaIOBase + 0x3c4, 0x10); 631 save->sr11 = rdinx(isaIOBase + 0x3c4, 0x11); 632 save->sr12 = rdinx(isaIOBase + 0x3c4, 0x12); 633 save->sr13 = rdinx(isaIOBase + 0x3c4, 0x13); 634 save->sr14 = rdinx(isaIOBase + 0x3c4, 0x14); 635 save->sr15 = rdinx(isaIOBase + 0x3c4, 0x15); 636 save->sr16 = rdinx(isaIOBase + 0x3c4, 0x16); 637 save->sr17 = rdinx(isaIOBase + 0x3c4, 0x17); 638 save->sr18 = rdinx(isaIOBase + 0x3c4, 0x18); 639 640#if 0 641 save->sr1d = rdinx(isaIOBase + 0x3c4, 0x1d); 642 save->sr1c = rdinx(isaIOBase + 0x3c4, 0x1c); 643 644 save->sr20 = rdinx(isaIOBase + 0x3c4, 0x20); 645 save->sr21 = rdinx(isaIOBase + 0x3c4, 0x21); 646 save->sr22 = rdinx(isaIOBase + 0x3c4, 0x22); 647 save->sr23 = rdinx(isaIOBase + 0x3c4, 0x23); 648 save->sr24 = rdinx(isaIOBase + 0x3c4, 0x24); 649 save->sr25 = rdinx(isaIOBase + 0x3c4, 0x25); 650 save->sr26 = rdinx(isaIOBase + 0x3c4, 0x26); 651 save->sr27 = rdinx(isaIOBase + 0x3c4, 0x27); 652 save->sr29 = rdinx(isaIOBase + 0x3c4, 0x29); 653 save->sr2a = rdinx(isaIOBase + 0x3c4, 0x2a); 654 if ((pARK->Chipset == PCI_CHIP_2000PV) || 655 (pARK->Chipset == PCI_CHIP_2000MT)) { 656 save->sr28 = rdinx(isaIOBase + 0x3c4, 0x28); 657 save->sr2b = rdinx(isaIOBase + 0x3c4, 0x2b); 658 } 659#endif 660 661 save->cr40 = rdinx(vgaIOBase + 4, 0x40); 662 save->cr41 = rdinx(vgaIOBase + 4, 0x41); 663 save->cr42 = rdinx(vgaIOBase + 4, 0x42); 664 save->cr44 = rdinx(vgaIOBase + 4, 0x44); 665 666 if ((pARK->Chipset == PCI_CHIP_2000PV) || 667 (pARK->Chipset == PCI_CHIP_2000MT)) 668 save->cr46 = rdinx(vgaIOBase + 4, 0x46); 669 670 /* save RAMDAC regs here, based on type */ 671 save->dac_command = get_daccomm(isaIOBase); 672} 673 674 675 676static Bool ARKModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 677{ 678 ARKPtr pARK = ARKPTR(pScrn); 679 ARKRegPtr new = &pARK->ModeRegs; 680 int multiplexing, dac16, modepitch; 681 vgaHWPtr hwp = VGAHWPTR(pScrn); 682 vgaRegPtr pVga = &hwp->ModeReg; 683 IOADDRESS isaIOBase = hwp->PIOOffset; 684 IOADDRESS vgaIOBase = isaIOBase + hwp->IOBase; 685 unsigned char tmp; 686 int offset; 687 688 multiplexing = 0; 689 690 if ((pScrn->bitsPerPixel == 8) && (pARK->dac_width == 16) && 691 (mode->Clock > pARK->multiplex_threshold)) 692 multiplexing = 1; 693 694 if (pARK->clock_mult == 2) { 695 if (!mode->CrtcHAdjusted) { 696 mode->CrtcHDisplay <<= 1; 697 mode->CrtcHSyncStart <<= 1; 698 mode->CrtcHSyncEnd <<= 1; 699 mode->CrtcHTotal <<= 1; 700 mode->CrtcHSkew <<= 1; 701 mode->CrtcHAdjusted = TRUE; 702 } 703 } 704 705 if (multiplexing) { 706 if (!mode->CrtcHAdjusted) { 707 mode->CrtcHDisplay >>= 1; 708 mode->CrtcHSyncStart >>= 1; 709 mode->CrtcHSyncEnd >>= 1; 710 mode->CrtcHTotal >>= 1; 711 mode->CrtcHSkew >>= 1; 712 mode->CrtcHAdjusted = TRUE; 713 } 714 } 715 716 if (!vgaHWInit(pScrn, mode)) 717 return FALSE; 718 719 if ((pARK->Chipset == PCI_CHIP_2000PV) || 720 (pARK->Chipset == PCI_CHIP_2000MT)) { 721 new->cr46 = rdinx(vgaIOBase + 4, 0x46) & ~0x04; 722 dac16 = 0; 723 if (pScrn->bitsPerPixel > 8) 724 dac16 = 1; 725 if (dac16) 726 new->cr46 |= 0x04; 727 } 728 729 offset = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3; 730 pVga->CRTC[0x13] = offset; 731 new->cr41 = (offset & 0x100) >> 5; 732 733 new->sr11 = 0x90; 734 switch (pScrn->bitsPerPixel) { 735 case 8: 736 new->sr11 |= 0x06; 737 break; 738 case 16: 739 new->sr11 |= 0x0a; 740 break; 741 case 24: 742 new->sr11 |= 0x06; 743 break; 744 case 32: 745 if ((pARK->Chipset == PCI_CHIP_2000PV) || 746 (pARK->Chipset == PCI_CHIP_2000MT)) 747 new->sr11 |= 0x0e; 748 else 749 new->sr11 |= 0x0a; 750 break; 751 default: 752 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 753 "Unsupported screen depth %d\n", 754 pScrn->bitsPerPixel); 755 return FALSE; 756 } 757 758 switch (pScrn->displayWidth) { 759 case 640: 760 modepitch = 0; 761 break; 762 case 800: 763 modepitch = 1; 764 break; 765 case 1024: 766 modepitch = 2; 767 break; 768 case 1280: 769 modepitch = 4; 770 break; 771 case 1600: 772 modepitch = 5; 773 break; 774 case 2048: 775 modepitch = 6; 776 break; 777 default: 778 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 779 "Unsupported screen width %d\n", 780 pScrn->displayWidth); 781 return FALSE; 782 } 783 784 new->sr17 &= ~0xc7; 785 new->sr17 |= modepitch; 786 787 new->sr10 = rdinx(isaIOBase + 0x3c4, 0x10) & ~0x1f; 788 new->sr10 |= 0x1f; 789 790 new->sr13 = pARK->FBAddress >> 16; 791 new->sr14 = pARK->FBAddress >> 24; 792 793 new->sr12 = rdinx(isaIOBase + 0x3c4, 0x12) & ~0x03; 794 switch (pScrn->videoRam) { 795 case 1024: 796 new->sr12 |= 0x01; 797 break; 798 case 2048: 799 new->sr12 |= 0x02; 800 break; 801 case 4096: 802 new->sr12 |= 0x03; 803 break; 804 default: 805 new->sr12 |= 0x01; 806 break; 807 } 808 809 new->sr15 = new->sr16 = 0; 810 811 tmp = 0; 812 if ((mode->CrtcVTotal - 2) & 0x400) 813 tmp |= 0x80; 814 if ((mode->CrtcVDisplay - 1) & 0x400) 815 tmp |= 0x40; 816 if (mode->CrtcVSyncStart & 0x400) 817 tmp |= 0x10; 818 new->cr40 = tmp; 819 820 tmp = new->cr41; /* initialized earlier */ 821 if ((mode->CrtcHTotal / 8 - 5) & 0x100) 822 tmp |= 0x80; 823 if ((mode->CrtcHDisplay / 8 - 1) & 0x100) 824 tmp |= 0x40; 825 if ((mode->CrtcHSyncStart / 8 - 1) & 0x100) 826 tmp |= 0x20; 827 if ((mode->CrtcHSyncStart / 8) & 0x100) 828 tmp |= 0x10; 829 new->cr41 |= tmp; 830 831 new->cr44 = rdinx(vgaIOBase + 4, 0x44) & ~0x34; 832 new->cr44 &= ~0x01; 833 new->cr42 = 0; 834 835 /* check interlace here later */ 836 837 /* set display FIFO threshold */ 838 { 839 int threshold; 840 int bandwidthused, percentused; 841 842 /* mostly guesses here as I would need to know more about 843 * and from the ramdac... 844 */ 845 bandwidthused = (mode->Clock / pARK->clock_mult) * 846 (pScrn->bitsPerPixel / 8); 847 /* 120000 is another guess */ 848 percentused = (bandwidthused * 100) / 120000; 849 tmp = rdinx(isaIOBase + 0x3c4, 0x18); 850 if (pARK->Chipset == PCI_CHIP_1000PV) { 851 threshold = 4; 852 tmp |= 0x08; /* enable full FIFO (8 deep) */ 853 tmp &= ~0x07; 854 tmp |= threshold; 855 } 856 if ((pARK->Chipset == PCI_CHIP_2000PV) || 857 (pARK->Chipset == PCI_CHIP_2000MT)) { 858 threshold = 12; 859 if (percentused >= 45) 860 threshold = 8; 861 if (percentused >= 70) 862 threshold = 4; 863 tmp &= 0x40; 864 tmp |= 0x10; 865 tmp |= (threshold & 0x0e) >> 1; 866 if (threshold & 0x01) 867 tmp |= 0x80; 868 if (threshold & 0x10) 869 tmp |= 0x20; 870 } 871 new->sr18 = tmp; 872 } 873 874 /* setup the RAMDAC regs */ 875 if (pARK->ramdac == ZOOMDAC) { 876 new->dac_command = 0x04; 877 if ((pScrn->bitsPerPixel == 8) && multiplexing) 878 new->dac_command = 0x24; 879 if ((pScrn->bitsPerPixel == 16) && (pARK->dac_width == 16)) 880 /* assuming green weight is not 5 */ 881 new->dac_command = 0x34; 882 if ((pScrn->bitsPerPixel == 16) && (pARK->dac_width == 8)) 883 new->dac_command = 0x64; 884 if ((pScrn->bitsPerPixel == 24) && (pARK->dac_width == 16)) 885 new->dac_command = 0xb4; /* packed */ 886 if ((pScrn->bitsPerPixel == 32) && (pARK->dac_width == 16)) 887 new->dac_command = 0x54; 888 } else if (pARK->ramdac == ATT490) { 889 new->dac_command = 0x00; 890 if (pScrn->bitsPerPixel == 16) 891 /* assuming green weight is 6 */ 892 new->dac_command = 0xc0; 893 if (pScrn->bitsPerPixel == 24) 894 new->dac_command = 0xe0; 895 } 896 897#if 0 898 /* hw cursor regs */ 899 new->sr20 = rdinx(isaIOBase + 0x3c4, 0x20); 900 new->sr21 = rdinx(isaIOBase + 0x3c4, 0x21); 901 new->sr22 = rdinx(isaIOBase + 0x3c4, 0x22); 902 new->sr23 = rdinx(isaIOBase + 0x3c4, 0x23); 903 new->sr24 = rdinx(isaIOBase + 0x3c4, 0x24); 904 new->sr25 = rdinx(isaIOBase + 0x3c4, 0x25); 905 new->sr26 = rdinx(isaIOBase + 0x3c4, 0x26); 906 new->sr27 = rdinx(isaIOBase + 0x3c4, 0x27); 907 new->sr29 = rdinx(isaIOBase + 0x3c4, 0x29); 908 new->sr2a = rdinx(isaIOBase + 0x3c4, 0x2a); 909 if ((pARK->Chipset == PCI_CHIP_2000PV) || 910 (pARK->Chipset == PCI_CHIP_2000MT)) { 911 new->sr28 = rdinx(isaIOBase + 0x3c4, 0x28); 912 new->sr2b = rdinx(isaIOBase + 0x3c4, 0x3b); 913 } 914#endif 915 916 917 ARKWriteMode(pScrn, pVga, new); 918 919 return TRUE; 920} 921 922 923static void ARKAdjustFrame(int scrnIndex, int x, int y, int flags) 924{ 925 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 926 ARKPtr pARK = ARKPTR(pScrn); 927 vgaHWPtr hwp = VGAHWPTR(pScrn); 928 IOADDRESS vgaIOBase = hwp->PIOOffset + hwp->IOBase; 929 int base; 930 931 base = ((y * pScrn->displayWidth + x) * 932 (pScrn->bitsPerPixel / 8)); 933 934 if (((pARK->Chipset == PCI_CHIP_2000PV) || 935 (pARK->Chipset == PCI_CHIP_2000MT)) && 936 (pScrn->videoRam >= 2048)) 937 base >>= 3; 938 else 939 base >>= 2; 940 if (pScrn->bitsPerPixel == 24) 941 base -= base % 3; 942 943 outw(vgaIOBase + 4, (base & 0x00ff00) | 0x0c); 944 outw(vgaIOBase + 4, ((base & 0x00ff) << 8) | 0x0d); 945 946 modinx(vgaIOBase + 4, 0x40, 0x07, (base & 0x070000) >> 16); 947} 948 949 950 951static void ARKWriteMode(ScrnInfoPtr pScrn, vgaRegPtr pVga, ARKRegPtr new) 952{ 953 ARKPtr pARK = ARKPTR(pScrn); 954 vgaHWPtr hwp = VGAHWPTR(pScrn); 955 IOADDRESS isaIOBase = hwp->PIOOffset; 956 IOADDRESS vgaIOBase = isaIOBase + hwp->IOBase; 957 958 vgaHWProtect(pScrn, TRUE); 959 960 /* set read and write aperture index to 0 */ 961 wrinx(isaIOBase + 0x3c4, 0x15, 0x00); 962 wrinx(isaIOBase + 0x3c4, 0x16, 0x00); 963 964 /* write the extended registers first so that textmode font 965 * restoration can suceed 966 */ 967 wrinx(isaIOBase + 0x3c4, 0x10, new->sr10); 968 wrinx(isaIOBase + 0x3c4, 0x11, new->sr11); 969 wrinx(isaIOBase + 0x3c4, 0x12, new->sr12); 970 wrinx(isaIOBase + 0x3c4, 0x13, new->sr13); 971 wrinx(isaIOBase + 0x3c4, 0x14, new->sr14); 972 wrinx(isaIOBase + 0x3c4, 0x15, new->sr15); 973 wrinx(isaIOBase + 0x3c4, 0x16, new->sr16); 974 wrinx(isaIOBase + 0x3c4, 0x17, new->sr17); 975 976#if 0 977 wrinx(isaIOBase + 0x3c4, 0x1c, new->sr1c); 978 wrinx(isaIOBase + 0x3c4, 0x1d, new->sr1d); 979 980 /* hw cursor regs */ 981 wrinx(isaIOBase + 0x3c4, 0x20, new->sr20); 982 wrinx(isaIOBase + 0x3c4, 0x21, new->sr21); 983 wrinx(isaIOBase + 0x3c4, 0x22, new->sr22); 984 wrinx(isaIOBase + 0x3c4, 0x23, new->sr23); 985 wrinx(isaIOBase + 0x3c4, 0x24, new->sr24); 986 wrinx(isaIOBase + 0x3c4, 0x25, new->sr25); 987 wrinx(isaIOBase + 0x3c4, 0x26, new->sr26); 988 wrinx(isaIOBase + 0x3c4, 0x27, new->sr27); 989 wrinx(isaIOBase + 0x3c4, 0x29, new->sr29); 990 wrinx(isaIOBase + 0x3c4, 0x2a, new->sr2a); 991#endif 992 993 if ((pARK->Chipset == PCI_CHIP_2000PV) || 994 (pARK->Chipset == PCI_CHIP_2000MT)) { 995 wrinx(isaIOBase + 0x3c4, 0x28, new->sr28); 996 wrinx(isaIOBase + 0x3c4, 0x2B, new->sr2b); 997 } 998 999 wrinx(vgaIOBase + 4, 0x40, new->cr40); 1000 wrinx(vgaIOBase + 4, 0x41, new->cr41); 1001 wrinx(vgaIOBase + 4, 0x42, new->cr42); 1002 wrinx(vgaIOBase + 4, 0x44, new->cr44); 1003 1004 if ((pARK->Chipset == PCI_CHIP_2000PV) || 1005 (pARK->Chipset == PCI_CHIP_2000MT)) 1006 wrinx(vgaIOBase + 4, 0x46, new->cr46); 1007 1008 /* RAMDAC regs */ 1009 if (pARK->ramdac == ZOOMDAC) { 1010 set_daccom(isaIOBase, new->dac_command); 1011 } 1012 1013 if (xf86IsPrimaryPci(pARK->PciInfo)) 1014 vgaHWRestore(pScrn, pVga, VGA_SR_ALL); 1015 else 1016 vgaHWRestore(pScrn, pVga, VGA_SR_MODE); 1017 1018 vgaHWProtect(pScrn, FALSE); 1019} 1020 1021 1022static Bool ARKEnterVT(int scrnIndex, int flags) 1023{ 1024 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1025 1026 if (!ARKModeInit(pScrn, pScrn->currentMode)) 1027 return FALSE; 1028 1029 ARKAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 1030 1031 return TRUE; 1032} 1033 1034 1035 1036static void ARKLeaveVT(int scrnIndex, int flags) 1037{ 1038 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1039 ARKPtr pARK = ARKPTR(pScrn); 1040 ARKRegPtr old = &pARK->SavedRegs; 1041 vgaHWPtr hwp = VGAHWPTR(pScrn); 1042 1043 ARKWriteMode(pScrn, &hwp->ModeReg, old); 1044 1045 vgaHWUnlock(hwp); 1046 vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); 1047 vgaHWLock(hwp); 1048} 1049 1050 1051static Bool ARKMapMem(ScrnInfoPtr pScrn) 1052{ 1053 ARKPtr pARK = ARKPTR(pScrn); 1054 vgaHWPtr hwp = VGAHWPTR(pScrn); 1055 1056 /* extended to cover MMIO space at 0xB8000 */ 1057 hwp->MapSize = 0x20000; 1058 1059#ifndef XSERVER_LIBPCIACCESS 1060 pARK->MMIOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO, 1061 pARK->PciTag, 0xb8000, 0x8000); 1062 1063 pARK->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 1064 pARK->PciTag, pARK->FBAddress, 1065 pScrn->videoRam * 1024); 1066#else 1067 1068 pARK->MMIOBase = xf86MapDomainMemory(pScrn->scrnIndex, VIDMEM_MMIO, 1069 pARK->PciInfo, 0xb8000, 0x8000); 1070 1071 { 1072 void** result = (void**)&pARK->FBBase; 1073 int err = pci_device_map_range(pARK->PciInfo, 1074 pARK->FBAddress, 1075 pScrn->videoRam * 1024, 1076 PCI_DEV_MAP_FLAG_WRITABLE | 1077 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 1078 result); 1079 1080 if (err) 1081 return FALSE; 1082 } 1083#endif 1084 1085 if (!pARK->FBBase) { 1086 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1087 "Cound not map framebuffer\n"); 1088 return FALSE; 1089 } 1090 1091 return TRUE; 1092} 1093 1094 1095static void ARKUnmapMem(ScrnInfoPtr pScrn) 1096{ 1097 ARKPtr pARK = ARKPTR(pScrn); 1098 1099 /* XXX vgaHWMapMem() isn't called explicitly, so is this correct? */ 1100 vgaHWUnmapMem(pScrn); 1101 1102#ifndef XSERVER_LIBPCIACCESS 1103 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pARK->FBBase, 1104 pScrn->videoRam * 1024); 1105#else 1106 pci_device_unmap_range(pARK->PciInfo, pARK->FBBase, pScrn->videoRam * 1024); 1107#endif 1108} 1109 1110 1111Bool ARKCloseScreen(int scrnIndex, ScreenPtr pScreen) 1112{ 1113 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1114 ARKPtr pARK = ARKPTR(pScrn); 1115 vgaHWPtr hwp = VGAHWPTR(pScrn); 1116 1117 if (pScrn->vtSema) { 1118 vgaHWUnlock(hwp); 1119 ARKWriteMode(pScrn, &hwp->SavedReg, &pARK->SavedRegs); 1120 vgaHWLock(hwp); 1121 ARKUnmapMem(pScrn); 1122 } 1123 1124 pScrn->vtSema = FALSE; 1125 pScreen->CloseScreen = pARK->CloseScreen; 1126 1127 /* XXX Shouldn't XAADestroyInfoRec() be called? */ 1128 1129 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 1130} 1131 1132 1133Bool ARKSaveScreen(ScreenPtr pScreen, int mode) 1134{ 1135 return vgaHWSaveScreen(pScreen, mode); 1136} 1137 1138 1139Bool ARKSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 1140{ 1141 return ARKModeInit(xf86Screens[scrnIndex], mode); 1142} 1143 1144 1145static void ARKLoadPalette(ScrnInfoPtr pScrn, int numColors, 1146 int *indicies, LOCO *colors, 1147 VisualPtr pVisual) 1148{ 1149 IOADDRESS isaIOBase = pScrn->domainIOBase; 1150 int i, index; 1151 1152 for (i=0; i<numColors; i++) { 1153 index = indicies[i]; 1154 outb(isaIOBase + 0x3c8, index); 1155 outb(isaIOBase + 0x3c9, colors[index].red); 1156 outb(isaIOBase + 0x3c9, colors[index].green); 1157 outb(isaIOBase + 0x3c9, colors[index].blue); 1158 } 1159} 1160 1161 1162static void ARKFreeScreen(int scrnIndex, int flags) 1163{ 1164 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1165 1166 vgaHWFreeHWRec(pScrn); 1167 1168 ARKFreeRec(pScrn); 1169} 1170 1171 1172static unsigned char get_daccomm(IOADDRESS isaIOBase) 1173{ 1174 unsigned char tmp; 1175 1176 outb(isaIOBase + 0x3c8, 0); 1177 inb(isaIOBase + 0x3c6); 1178 inb(isaIOBase + 0x3c6); 1179 inb(isaIOBase + 0x3c6); 1180 inb(isaIOBase + 0x3c6); 1181 tmp = inb(isaIOBase + 0x3c6); 1182 outb(isaIOBase + 0x3c8, 0); 1183 1184 return tmp; 1185} 1186 1187 1188static unsigned char set_daccom(IOADDRESS isaIOBase, unsigned char comm) 1189{ 1190#if 0 1191 outb(isaIOBase + 0x3c8, 0); 1192#else 1193 inb(isaIOBase + 0x3c8); 1194#endif 1195 inb(isaIOBase + 0x3c6); 1196 inb(isaIOBase + 0x3c6); 1197 inb(isaIOBase + 0x3c6); 1198 inb(isaIOBase + 0x3c6); 1199 outb(isaIOBase + 0x3c6, comm); 1200#if 0 1201 outb(isaIOBase + 0x3c8, 0); 1202#else 1203 inb(isaIOBase + 0x3c8); 1204#endif 1205 1206 return inb(isaIOBase + 0x3c6); 1207} 1208