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