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