alp_driver.c revision 76888252
1/* 2 * Driver for CL-GD5480. 3 * Itai Nahshon. 4 * 5 * Support for the CL-GD7548: David Monniaux 6 * 7 * This is mainly a cut & paste from the MGA driver. 8 * Original autors and contributors list include: 9 * Radoslaw Kapitan, Andrew Vanderstock, Dirk Hohndel, 10 * David Dawes, Andrew E. Mileski, Leonard N. Zubkoff, 11 * Guy DESBIEF 12 */ 13 14#ifdef HAVE_CONFIG_H 15#include "config.h" 16#endif 17 18/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_driver.c,v 1.35 2003/11/03 05:11:09 tsi Exp $ */ 19 20/* All drivers should typically include these */ 21#include "xf86.h" 22#include "xf86_OSproc.h" 23 24/* All drivers need this */ 25 26/* Everything using inb/outb, etc needs "compiler.h" */ 27#include "compiler.h" 28 29/* Drivers for PCI hardware need this */ 30#include "xf86PciInfo.h" 31 32/* Drivers that need to access the PCI config space directly need this */ 33#include "xf86Pci.h" 34 35/* All drivers using the vgahw module need this */ 36/* This driver needs to be modified to not use vgaHW for multihead operation */ 37#include "vgaHW.h" 38 39#include "xf86RAC.h" 40#include "xf86Resources.h" 41 42/* All drivers initialising the SW cursor need this */ 43#include "mipointer.h" 44 45/* All drivers implementing backing store need this */ 46#include "mibstore.h" 47 48#include "micmap.h" 49 50/* Needed by the Shadow Framebuffer */ 51#include "shadowfb.h" 52 53/* Note: can HWCUR64 be set even though the hw cursor is disabled for 54 want of memory ? */ 55 56/* Framebuffer memory manager */ 57#include "xf86fbman.h" 58 59#include "xf4bpp.h" 60#include "xf1bpp.h" 61#include "fb.h" 62 63 64#include "xf86DDC.h" 65#include "xf86int10.h" 66 67#include "cir.h" 68#define _ALP_PRIVATE_ 69#include "alp.h" 70 71#include "xf86xv.h" 72#include <X11/extensions/Xv.h> 73 74#ifdef ALPPROBEI2C 75/* For debugging... should go away. */ 76static void AlpProbeI2C(int scrnIndex); 77#endif 78 79/* 80 * Forward definitions for the functions that make up the driver. 81 */ 82 83/* Mandatory functions */ 84 85Bool AlpPreInit(ScrnInfoPtr pScrn, int flags); 86Bool AlpScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); 87Bool AlpEnterVT(int scrnIndex, int flags); 88void AlpLeaveVT(int scrnIndex, int flags); 89static Bool AlpCloseScreen(int scrnIndex, ScreenPtr pScreen); 90static Bool AlpSaveScreen(ScreenPtr pScreen, int mode); 91 92/* Required if the driver supports mode switching */ 93Bool AlpSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); 94/* Required if the driver supports moving the viewport */ 95void AlpAdjustFrame(int scrnIndex, int x, int y, int flags); 96 97/* Optional functions */ 98void AlpFreeScreen(int scrnIndex, int flags); 99ModeStatus AlpValidMode(int scrnIndex, DisplayModePtr mode, 100 Bool verbose, int flags); 101/* Internally used functions */ 102static void AlpSave(ScrnInfoPtr pScrn); 103static void AlpRestore(ScrnInfoPtr pScrn); 104static Bool AlpModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 105 106static void AlpProbeLCD(ScrnInfoPtr pScrn); 107 108static void AlpSetClock(CirPtr pCir, vgaHWPtr hwp, int freq); 109 110static void AlpOffscreenAccelInit(ScrnInfoPtr pScrn); 111 112static void AlpDisplayPowerManagementSet(ScrnInfoPtr pScrn, 113 int PowerManagementMode, int flags); 114 115/* 116 * This is intentionally screen-independent. It indicates the binding 117 * choice made in the first PreInit. 118 */ 119static int pix24bpp = 0; 120 121typedef enum { 122 OPTION_HW_CURSOR, 123 OPTION_PCI_RETRY, 124 OPTION_NOACCEL, 125 OPTION_MMIO, 126 OPTION_ROTATE, 127 OPTION_SHADOW_FB, 128 OPTION_MEMCFG1, 129 OPTION_MEMCFG2 130} CirOpts; 131 132static const OptionInfoRec CirOptions[] = { 133 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 134 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 135 { OPTION_MMIO, "MMIO", OPTV_BOOLEAN, {0}, FALSE }, 136 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 137 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 138 { OPTION_MEMCFG1, "MemCFG1", OPTV_INTEGER, {0}, -1 }, 139 { OPTION_MEMCFG2, "MemCFG2", OPTV_INTEGER, {0}, -1 }, 140 { -1, NULL, OPTV_NONE, {0}, FALSE } 141}; 142 143/* 1/4bpp 8bpp 15/16bpp 24bpp 32bpp 144static int unsupp_MaxClocks[] = { 0, 0, 0, 0, 0 }; */ 145static int gd5430_MaxClocks[] = { 85500, 85500, 50000, 28500, 0 }; 146static int gd5446_MaxClocks[] = { 135100, 135100, 85500, 85500, 0 }; 147static int gd5480_MaxClocks[] = { 135100, 200000, 200000, 135100, 135100 }; 148static int gd7548_MaxClocks[] = { 80100, 80100, 80100, 80100, 80100 }; 149 150/* 151 * List of symbols from other modules that this module references. This 152 * list is used to tell the loader that it is OK for symbols here to be 153 * unresolved providing that it hasn't been told that they haven't been 154 * told that they are essential via a call to xf86LoaderReqSymbols() or 155 * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about 156 * unresolved symbols that are not required. 157 */ 158 159static const char *vgahwSymbols[] = { 160 "vgaHWFreeHWRec", 161 "vgaHWGetHWRec", 162 "vgaHWGetIOBase", 163 "vgaHWGetIndex", 164 "vgaHWHandleColormaps", 165 "vgaHWInit", 166 "vgaHWLock", 167 "vgaHWMapMem", 168 "vgaHWProtect", 169 "vgaHWRestore", 170 "vgaHWSave", 171 "vgaHWSaveScreen", 172 "vgaHWSetMmioFuncs", 173 "vgaHWSetStdFuncs", 174 "vgaHWUnlock", 175 NULL 176}; 177 178#ifdef XFree86LOADER 179static const char *miscfbSymbols[] = { 180 "xf1bppScreenInit", 181 "xf4bppScreenInit", 182 NULL 183}; 184#endif 185 186static const char *fbSymbols[] = { 187 "fbScreenInit", 188 "fbPictureInit", 189 NULL 190}; 191 192static const char *xaaSymbols[] = { 193 "XAACreateInfoRec", 194 "XAADestroyInfoRec", 195 "XAAInit", 196 NULL 197}; 198 199static const char *ramdacSymbols[] = { 200 "xf86CreateCursorInfoRec", 201 "xf86DestroyCursorInfoRec", 202 "xf86InitCursor", 203 NULL 204}; 205 206static const char *int10Symbols[] = { 207 "xf86FreeInt10", 208 "xf86InitInt10", 209 NULL 210}; 211 212static const char *shadowSymbols[] = { 213 "ShadowFBInit", 214 NULL 215}; 216 217static const char *ddcSymbols[] = { 218 "xf86PrintEDID", 219 "xf86DoEDID_DDC2", 220 "xf86SetDDCproperties", 221 NULL 222}; 223 224static const char *i2cSymbols[] = { 225 "xf86CreateI2CBusRec", 226 "xf86I2CBusInit", 227 NULL 228}; 229 230#ifdef XFree86LOADER 231 232#define ALP_MAJOR_VERSION 1 233#define ALP_MINOR_VERSION 0 234#define ALP_PATCHLEVEL 0 235 236static MODULESETUPPROTO(alpSetup); 237 238static XF86ModuleVersionInfo alpVersRec = 239{ 240 "cirrus_alpine", 241 MODULEVENDORSTRING, 242 MODINFOSTRING1, 243 MODINFOSTRING2, 244 XORG_VERSION_CURRENT, 245 ALP_MAJOR_VERSION, ALP_MINOR_VERSION, ALP_PATCHLEVEL, 246 ABI_CLASS_VIDEODRV, /* This is a video driver */ 247 ABI_VIDEODRV_VERSION, 248 MOD_CLASS_NONE, 249 {0,0,0,0} 250}; 251 252/* 253 * This is the module init data. 254 * Its name has to be the driver name followed by ModuleData. 255 */ 256_X_EXPORT XF86ModuleData cirrus_alpineModuleData = { 257 &alpVersRec, 258 alpSetup, 259 NULL 260}; 261 262static pointer 263alpSetup(pointer module, pointer opts, int *errmaj, int *errmin) 264{ 265 static Bool setupDone = FALSE; 266 if (!setupDone) { 267 setupDone = TRUE; 268 LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, 269 miscfbSymbols, ramdacSymbols,int10Symbols, 270 ddcSymbols, i2cSymbols, shadowSymbols, NULL); 271 } 272 return (pointer)1; 273} 274 275#endif /* XFree86LOADER */ 276 277_X_EXPORT const OptionInfoRec * 278AlpAvailableOptions(int chipid) 279{ 280 return CirOptions; 281} 282 283_X_EXPORT ScrnInfoPtr 284AlpProbe(int entity) 285{ 286 ScrnInfoPtr pScrn = NULL; 287 288 if ((pScrn = xf86ConfigPciEntity(pScrn, 0, entity, CIRPciChipsets, 289 NULL,NULL, NULL, NULL, NULL))) { 290 pScrn->PreInit = AlpPreInit; 291 pScrn->ScreenInit = AlpScreenInit; 292 pScrn->SwitchMode = AlpSwitchMode; 293 pScrn->AdjustFrame = AlpAdjustFrame; 294 pScrn->EnterVT = AlpEnterVT; 295 pScrn->LeaveVT = AlpLeaveVT; 296 pScrn->FreeScreen = AlpFreeScreen; 297 pScrn->ValidMode = AlpValidMode; 298 } 299 300 return pScrn; 301} 302 303 304static Bool 305AlpGetRec(ScrnInfoPtr pScrn) 306{ 307#ifdef ALP_DEBUG 308 ErrorF("AlpGetRec\n"); 309#endif 310 if (pScrn->driverPrivate != NULL) 311 return TRUE; 312 313 pScrn->driverPrivate = xnfcalloc(sizeof(CirRec), 1); 314 ((CirPtr)pScrn->driverPrivate)->chip.alp = xnfcalloc(sizeof(AlpRec),1); 315 316#ifdef ALP_DEBUG 317 ErrorF("AlpGetRec 0x%x\n", CIRPTR(pScrn)); 318#endif 319 return TRUE; 320} 321 322static void 323AlpFreeRec(ScrnInfoPtr pScrn) 324{ 325 if (pScrn->driverPrivate == NULL) 326 return; 327 xfree(pScrn->driverPrivate); 328 pScrn->driverPrivate = NULL; 329} 330 331 332/* 333 * AlpCountRAM -- 334 * 335 * Counts amount of installed RAM 336 * 337 * XXX Can use options to configure memory on non-primary cards. 338 */ 339static int 340AlpCountRam(ScrnInfoPtr pScrn) 341{ 342 CirPtr pCir = CIRPTR(pScrn); 343 vgaHWPtr hwp = VGAHWPTR(pScrn); 344 MessageType from; 345 int videoram = 0; 346 347 /* Map the Alp memory and MMIO areas */ 348 pCir->FbMapSize = 1024*1024; /* XX temp */ 349 pCir->IoMapSize = 0x4000; /* 16K for moment */ 350 if (!CirMapMem(pCir, pScrn->scrnIndex)) 351 return 0; 352 353 /* The 754x supports MMIO for the BitBlt engine but 354 not for the VGA registers */ 355 switch (pCir->Chipset) 356 { 357 case PCI_CHIP_GD7548: 358 break; 359 default: 360 if (pCir->UseMMIO) 361 vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0); 362 } 363 364 if (pCir->chip.alp->sr0f != (CARD32)-1) { 365 from = X_CONFIG; 366 hwp->writeSeq(hwp, 0x0F, pCir->chip.alp->sr0f); 367 } else { 368 from = X_PROBED; 369 pCir->chip.alp->sr0f = hwp->readSeq(hwp, 0x0F); 370 } 371 xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 1 is 0x%02X\n", 372 (unsigned int)pCir->chip.alp->sr0f); 373 374 switch (pCir->Chipset) { 375 case PCI_CHIP_GD5430: 376/* case PCI_CHIP_GD5440: */ 377 switch (pCir->chip.alp->sr0f & 0x18) { 378 case 0x08: 379 videoram = 512; 380 break; 381 case 0x10: 382 videoram = 1024; 383 break; 384 case 0x18: 385 videoram = 2048; 386 break; 387 } 388 break; 389 390 case PCI_CHIP_GD5434_4: 391 case PCI_CHIP_GD5434_8: 392 case PCI_CHIP_GD5436: 393 switch (pCir->chip.alp->sr0f & 0x18) { 394 case 0x10: 395 videoram = 1024; 396 break; 397 case 0x18: 398 videoram = 2048; 399 if (pCir->chip.alp->sr0f & 0x80) 400 videoram = 4096; 401 break; 402 } 403 404 case PCI_CHIP_GD5446: 405 videoram = 1024; 406 407 if (pCir->chip.alp->sr17 != (CARD32)-1) { 408 from = X_CONFIG; 409 hwp->writeSeq(hwp, 0x17, pCir->chip.alp->sr17); 410 } else { 411 from = X_PROBED; 412 pCir->chip.alp->sr17 = hwp->readSeq(hwp, 0x17); 413 } 414 xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 2 is 0x%02X\n", 415 (unsigned int)pCir->chip.alp->sr17); 416 417 if ((pCir->chip.alp->sr0f & 0x18) == 0x18) { 418 if (pCir->chip.alp->sr0f & 0x80) { 419 if (pCir->chip.alp->sr17 & 0x80) 420 videoram = 2048; 421 else if (pCir->chip.alp->sr17 & 0x02) 422 videoram = 3072; 423 else 424 videoram = 4096; 425 } else { 426 if ((pCir->chip.alp->sr17 & 80) == 0) 427 videoram = 2048; 428 } 429 } 430 break; 431 432 case PCI_CHIP_GD5480: 433 if (pCir->chip.alp->sr17 != (CARD32)-1) { 434 from = X_CONFIG; 435 hwp->writeSeq(hwp, 0x17, pCir->chip.alp->sr17); 436 } else { 437 from = X_PROBED; 438 pCir->chip.alp->sr17 = hwp->readSeq(hwp, 0x17); 439 } 440 xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 2 is 0x%02X\n", 441 (unsigned int)pCir->chip.alp->sr17); 442 videoram = 1024; 443 if ((pCir->chip.alp->sr0f & 0x18) == 0x18) { /* 2 or 4 MB */ 444 videoram = 2048; 445 if (pCir->chip.alp->sr0f & 0x80) /* Second bank enable */ 446 videoram = 4096; 447 } 448 if (pCir->chip.alp->sr17 & 0x80) 449 videoram <<= 1; 450 break; 451 452 case PCI_CHIP_GD7548: 453 videoram = 1024; 454 switch (pCir->chip.alp->sr0f & 0x90) { 455 case 0x10: 456 /* TODO: 2 256K X 16 DRAMs (1024) or 4 512K X 8 DRAMs (2048)? */ 457 break; 458 case 0x90: 459 videoram <<= 1; 460 break; 461 } 462 break; 463 } 464 465 /* UNMap the Alp memory and MMIO areas */ 466 if (!CirUnmapMem(pCir, pScrn->scrnIndex)) 467 return 0; 468 vgaHWSetStdFuncs(hwp); 469 470 return videoram; 471} 472 473 474/* 475 * GetAccelPitchValues - 476 * 477 * This function returns a list of display width (pitch) values that can 478 * be used in accelerated mode. 479 */ 480static int * 481GetAccelPitchValues(ScrnInfoPtr pScrn) 482{ 483 int *linePitches = NULL; 484 int i, n = 0; 485 CirPtr pCir = CIRPTR(pScrn); 486 487 /* XXX ajv - 512, 576, and 1536 may not be supported 488 line pitches. see sdk pp 4-59 for more 489 details. Why anyone would want less than 640 is 490 bizarre. (maybe lots of pixels tall?) */ 491 492 /* The only line pitches the accelerator supports */ 493#if 1 494 int accelWidths[] = { 640, 768, 800, 960, 1024, 1152, 1280, 495 1600, 1920, 2048, 0 }; 496#else 497 int accelWidths[] = { 512, 576, 640, 768, 800, 960, 1024, 1152, 498 1280, 1536, 1600, 1920, 2048, 0 }; 499#endif 500 501 for (i = 0; accelWidths[i] != 0; i++) { 502 if (accelWidths[i] % pCir->Rounding == 0) { 503 n++; 504 linePitches = xnfrealloc(linePitches, n * sizeof(int)); 505 linePitches[n - 1] = accelWidths[i]; 506 } 507 } 508 /* Mark the end of the list */ 509 if (n > 0) { 510 linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int)); 511 linePitches[n] = 0; 512 } 513 return linePitches; 514} 515 516 517/* Mandatory */ 518Bool 519AlpPreInit(ScrnInfoPtr pScrn, int flags) 520{ 521 CirPtr pCir; 522 vgaHWPtr hwp; 523 MessageType from, from1; 524 int i; 525 ClockRangePtr clockRanges; 526 char *s; 527 xf86Int10InfoPtr pInt = NULL; 528 529 if (flags & PROBE_DETECT) { 530 cirProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index ); 531 return TRUE; 532 } 533 534#ifdef ALP_DEBUG 535 ErrorF("AlpPreInit\n"); 536#endif 537 538 /* Check the number of entities, and fail if it isn't one. */ 539 if (pScrn->numEntities != 1) 540 return FALSE; 541 542 if (!xf86LoadSubModule(pScrn, "vgahw")) 543 return FALSE; 544 545 xf86LoaderReqSymLists(vgahwSymbols, NULL); 546 547 /* 548 * Allocate a vgaHWRec 549 */ 550 if (!vgaHWGetHWRec(pScrn)) 551 return FALSE; 552 hwp = VGAHWPTR(pScrn); 553 vgaHWGetIOBase(hwp); 554 555 /* Allocate the AlpRec driverPrivate */ 556 if (!AlpGetRec(pScrn)) 557 return FALSE; 558 559 pCir = CIRPTR(pScrn); 560 pCir->pScrn = pScrn; 561 pCir->PIOReg = hwp->PIOOffset + 0x3CE; 562 563 /* Get the entity, and make sure it is PCI. */ 564 pCir->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 565 if (pCir->pEnt->location.type != BUS_PCI) { 566 xfree(pCir->pEnt); 567 return FALSE; 568 } 569 570 pCir->Chipset = pCir->pEnt->chipset; 571 /* Find the PCI info for this screen */ 572 pCir->PciInfo = xf86GetPciInfoForEntity(pCir->pEnt->index); 573 pCir->PciTag = pciTag(pCir->PciInfo->bus, 574 pCir->PciInfo->device, 575 pCir->PciInfo->func); 576 577 if (xf86LoadSubModule(pScrn, "int10")) { 578 xf86LoaderReqSymLists(int10Symbols,NULL); 579 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); 580 pInt = xf86InitInt10(pCir->pEnt->index); 581 xf86FreeInt10(pInt); 582 /* 583 * This is a hack: We restore the PCI base regs as some Colorgraphic 584 * BIOSes tend to mess them up 585 */ 586 pciWriteLong(pCir->PciTag,0x10,pCir->PciInfo->memBase[0]); 587 pciWriteLong(pCir->PciTag,0x14,pCir->PciInfo->memBase[1]); 588 589 } 590 591 /* Set pScrn->monitor */ 592 pScrn->monitor = pScrn->confScreen->monitor; 593 594 /* 595 * The first thing we should figure out is the depth, bpp, etc. 596 * We support both 24bpp and 32bpp layouts, so indicate that. 597 */ 598 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb | 599 SupportConvert32to24 | PreferConvert32to24)) { 600 return FALSE; 601 } else { 602 /* Check that the returned depth is one we support */ 603 switch (pScrn->depth) { 604 case 1: 605 case 4: 606 case 8: 607 case 15: 608 case 16: 609 case 24: 610 /* OK */ 611 break; 612 default: 613 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 614 "Given depth (%d) is not supported by this driver\n", 615 pScrn->depth); 616 return FALSE; 617 } 618 } 619 xf86PrintDepthBpp(pScrn); 620 621 /* Get the depth24 pixmap format */ 622 if (pScrn->depth == 24 && pix24bpp == 0) 623 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 624 625 /* 626 * This must happen after pScrn->display has been set because 627 * xf86SetWeight references it. 628 */ 629 if (pScrn->depth > 8) { 630 /* The defaults are OK for us */ 631 rgb zeros = {0, 0, 0}; 632 633 if (!xf86SetWeight(pScrn, zeros, zeros)) { 634 return FALSE; 635 } else { 636 /* XXX check that weight returned is supported */ 637 ; 638 } 639 } 640 641 if (!xf86SetDefaultVisual(pScrn, -1)) { 642 return FALSE; 643 } 644 /* Collect all of the relevant option flags (fill in pScrn->options) */ 645 xf86CollectOptions(pScrn, NULL); 646 647 /* Process the options */ 648 if (!(pCir->Options = xalloc(sizeof(CirOptions)))) 649 return FALSE; 650 memcpy(pCir->Options, CirOptions, sizeof(CirOptions)); 651 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pCir->Options); 652 653 if (!xf86IsPrimaryPci(pCir->PciInfo) 654 && !(pInt || (xf86IsOptionSet(pCir->Options,OPTION_MEMCFG1) 655 && xf86IsOptionSet(pCir->Options,OPTION_MEMCFG2)))) 656 return FALSE; 657 658 if (pScrn->depth == 8) 659 pScrn->rgbBits = 6; 660 661 from = X_DEFAULT; 662 pCir->HWCursor = FALSE; 663 if (xf86GetOptValBool(pCir->Options, OPTION_HW_CURSOR, &pCir->HWCursor)) 664 from = X_CONFIG; 665 666 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 667 pCir->HWCursor ? "HW" : "SW"); 668 if (xf86ReturnOptValBool(pCir->Options, OPTION_NOACCEL, FALSE)) { 669 pCir->NoAccel = TRUE; 670 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 671 } 672 if(pScrn->bitsPerPixel < 8) { 673 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 674 "Cannot use accelerations in less than 8 bpp\n"); 675 pCir->NoAccel = TRUE; 676 } 677 678 /* 679 * Set the ChipRev, allowing config file entries to 680 * override. 681 */ 682 if (pCir->pEnt->device->chipRev >= 0) { 683 pCir->ChipRev = pCir->pEnt->device->chipRev; 684 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 685 pCir->ChipRev); 686 } else { 687 pCir->ChipRev = pCir->PciInfo->chipRev; 688 } 689 690 /* Find the frame buffer base address */ 691 if (pCir->pEnt->device->MemBase != 0) { 692 if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->MemBase)) { 693 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 694 "MemBase 0x%08lX doesn't match any PCI base register.\n", 695 pCir->pEnt->device->MemBase); 696 return FALSE; 697 } 698 pCir->FbAddress = pCir->pEnt->device->MemBase; 699 from = X_CONFIG; 700 } else { 701 if (pCir->PciInfo->memBase[0] != 0) { 702 /* 5446B and 5480 use mask of 0xfe000000. 703 5446A uses 0xff000000. */ 704 pCir->FbAddress = pCir->PciInfo->memBase[0] & 0xff000000; 705 from = X_PROBED; 706 } else { 707 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 708 "No valid FB address in PCI config space\n"); 709 AlpFreeRec(pScrn); 710 return FALSE; 711 } 712 } 713 xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", 714 (unsigned long)pCir->FbAddress); 715 716 if (pCir->pEnt->device->IOBase != 0) { 717 /* Require that the config file value matches one of the PCI values. */ 718 if (!xf86CheckPciMemBase(pCir->PciInfo, pCir->pEnt->device->IOBase)) { 719 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 720 "IOBase 0x%08lX doesn't match any PCI base register.\n", 721 pCir->pEnt->device->IOBase); 722 return FALSE; 723 } 724 pCir->IOAddress = pCir->pEnt->device->IOBase; 725 from = X_CONFIG; 726 } else { 727 if (pCir->PciInfo->memBase[1] != 0) { 728 pCir->IOAddress = pCir->PciInfo->memBase[1] & 0xfffff000; 729 from = X_PROBED; 730 } else { 731 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 732 "No valid MMIO address in PCI config space\n"); 733 /* 5446 rev A do not use a separate MMIO segment */ 734 /* We do not really need that YET. */ 735 } 736 } 737 738 /* User options can override the MMIO default */ 739#if 0 740 /* Will we ever support MMIO on 5446A or older? */ 741 if (xf86ReturnOptValBool(pCir->Options, OPTION_MMIO, FALSE)) { 742 pCir->UseMMIO = TRUE; 743 from = X_CONFIG; 744 } 745#endif 746 if (!xf86ReturnOptValBool(pCir->Options, OPTION_MMIO, TRUE)) { 747 pCir->UseMMIO = FALSE; 748 from1 = X_CONFIG; 749 } else if (pCir->IOAddress) { 750 /* Default to MMIO if we have a separate IOAddress and 751 not in monochrome mode (IO 0x3Bx is not relocated!) */ 752 if (pScrn->bitsPerPixel != 1) { 753 pCir->UseMMIO = TRUE; 754 from1 = X_PROBED; 755 } else { 756 pCir->UseMMIO = FALSE; 757 from1 = X_PROBED; 758 } 759 } else { 760 pCir->UseMMIO = FALSE; 761 from1 = X_PROBED; 762 } 763 764 if (pCir->UseMMIO) { 765 xf86DrvMsg(pScrn->scrnIndex, from1, "Using MMIO\n"); 766 xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", 767 (unsigned long)pCir->IOAddress); 768 } else 769 xf86DrvMsg(pScrn->scrnIndex, from1, "Not Using MMIO\n"); 770 771 /* 772 * XXX Check if this is correct 773 */ 774 if (!pCir->UseMMIO) { 775 pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT | RAC_FB; 776 xf86SetOperatingState(resVgaMem, pCir->pEnt->index, ResUnusedOpr); 777 } else { 778 xf86SetOperatingState(resVga, pCir->pEnt->index, ResUnusedOpr); 779 } 780 781 /* Register the PCI-assigned resources. */ 782 if (xf86RegisterResources(pCir->pEnt->index, NULL, ResExclusive)) { 783 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 784 "xf86RegisterResources() found resource conflicts\n"); 785 return FALSE; 786 } 787 788 if (!xf86LoadSubModule(pScrn, "i2c")) { 789 AlpFreeRec(pScrn); 790 return FALSE; 791 } 792 xf86LoaderReqSymLists(i2cSymbols,NULL); 793 794 if (!xf86LoadSubModule(pScrn, "ddc")) { 795 AlpFreeRec(pScrn); 796 return FALSE; 797 } 798 xf86LoaderReqSymLists(ddcSymbols, NULL); 799 800 if(!AlpI2CInit(pScrn)) { 801 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 802 "I2C initialization failed\n"); 803 } 804 else 805 xf86SetDDCproperties(pScrn,xf86PrintEDID( 806 xf86DoEDID_DDC2(pScrn->scrnIndex,pCir->I2CPtr1))); 807 808 /* Probe the possible LCD display */ 809 AlpProbeLCD(pScrn); 810 811#ifdef CIRPROBEI2C 812 CirProbeI2C(pScrn->scrnIndex); 813#endif 814 815 /* The gamma fields must be initialised when using the new cmap code */ 816 if (pScrn->depth > 1) { 817 Gamma zeros = {0.0, 0.0, 0.0}; 818 819 if (!xf86SetGamma(pScrn, zeros)) 820 return FALSE; 821 } 822 823 /* XXX If UseMMIO == TRUE and for any reason we cannot do MMIO, 824 abort here */ 825 826 if (xf86GetOptValBool(pCir->Options, 827 OPTION_SHADOW_FB,&pCir->shadowFB)) 828 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n", 829 pCir->shadowFB ? "enabled" : "disabled"); 830 831 if ((s = xf86GetOptValString(pCir->Options, OPTION_ROTATE))) { 832 if(!xf86NameCmp(s, "CW")) { 833 /* accel is disabled below for shadowFB */ 834 pCir->shadowFB = TRUE; 835 pCir->rotate = 1; 836 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 837 "Rotating screen clockwise - acceleration disabled\n"); 838 } else if(!xf86NameCmp(s, "CCW")) { 839 pCir->shadowFB = TRUE; 840 pCir->rotate = -1; 841 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" 842 "counter clockwise - acceleration disabled\n"); 843 } else { 844 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" 845 "value for Option \"Rotate\"\n", s); 846 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 847 "Valid options are \"CW\" or \"CCW\"\n"); 848 } 849 } 850 if (pCir->shadowFB && (pScrn->depth < 8)) { 851 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 852 "shadowFB not supported at this depth.\n"); 853 pCir->shadowFB = FALSE; 854 pCir->rotate = 0; 855 } 856 857 if (pCir->shadowFB && !pCir->NoAccel) { 858 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 859 "HW acceleration not supported with \"shadowFB\".\n"); 860 pCir->NoAccel = TRUE; 861 } 862 863 if (pCir->rotate && pCir->HWCursor) { 864 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 865 "HW cursor not supported with \"rotate\".\n"); 866 pCir->HWCursor = FALSE; 867 } 868 869 /* XXX We do not know yet how to configure memory on this card. 870 Use options MemCFG1 and MemCFG2 to set registers SR0F and 871 SR17 before trying to count ram size. */ 872 873 pCir->chip.alp->sr0f = (CARD32)-1; 874 pCir->chip.alp->sr17 = (CARD32)-1; 875 876 (void) xf86GetOptValULong(pCir->Options, OPTION_MEMCFG1, (unsigned long *)&pCir->chip.alp->sr0f); 877 (void) xf86GetOptValULong(pCir->Options, OPTION_MEMCFG2, (unsigned long *)&pCir->chip.alp->sr17); 878 /* 879 * If the user has specified the amount of memory in the XF86Config 880 * file, we respect that setting. 881 */ 882 if (pCir->pEnt->device->videoRam != 0) { 883 pScrn->videoRam = pCir->pEnt->device->videoRam; 884 pCir->IoMapSize = 0x4000; /* 16K for moment */ 885 from = X_CONFIG; 886 } else { 887 pScrn->videoRam = AlpCountRam(pScrn); 888 from = X_PROBED; 889 } 890 xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", pScrn->videoRam); 891 892 pCir->FbMapSize = pScrn->videoRam * 1024; 893 894 /* properties */ 895 pCir->properties = 0; 896 897 if ((pCir->chip.alp->sr0f & 0x18) > 0x8) 898 pCir->properties |= HWCUR64; 899 900 switch (pCir->Chipset) { 901 case PCI_CHIP_GD7548: 902 pCir->properties |= HWCUR64; 903 pCir->properties |= ACCEL_AUTOSTART; 904 break; 905 case PCI_CHIP_GD5436: 906 case PCI_CHIP_GD5480: 907 pCir->properties |= ACCEL_AUTOSTART; 908 break; 909 default: 910 break; 911 } 912 913 /* We use a programmable clock */ 914 pScrn->progClock = TRUE; 915 916 /* XXX Set HW cursor use */ 917 918 /* Set the min pixel clock */ 919 pCir->MinClock = 12000; /* XXX Guess, need to check this */ 920 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", 921 pCir->MinClock / 1000); 922 /* 923 * If the user has specified ramdac speed in the XF86Config 924 * file, we respect that setting. 925 */ 926 if (pCir->pEnt->device->dacSpeeds[0]) { 927 ErrorF("Do not specily a Clocks line for Cirrus chips\n"); 928 return FALSE; 929 } else { 930 int speed; 931 int *p = NULL; 932 switch (pCir->Chipset) { 933 case PCI_CHIP_GD5430: 934 case PCI_CHIP_GD5434_4: 935 case PCI_CHIP_GD5434_8: 936 case PCI_CHIP_GD5436: 937 /* case PCI_CHIP_GD5440: */ 938 p = gd5430_MaxClocks; 939 break; 940 case PCI_CHIP_GD5446: 941 p = gd5446_MaxClocks; 942 break; 943 case PCI_CHIP_GD5480: 944 p = gd5480_MaxClocks; 945 break; 946 case PCI_CHIP_GD7548: 947 p = gd7548_MaxClocks; 948 break; 949 } 950 if (!p) 951 return FALSE; 952 switch(pScrn->bitsPerPixel) { 953 case 1: 954 case 4: 955 speed = p[0]; 956 break; 957 case 8: 958 speed = p[1]; 959 break; 960 case 15: 961 case 16: 962 speed = p[2]; 963 break; 964 case 24: 965 speed = p[3]; 966 break; 967 case 32: 968 speed = p[4]; 969 break; 970 default: 971 /* Should not get here */ 972 speed = 0; 973 break; 974 } 975 pCir->MaxClock = speed; 976 from = X_PROBED; 977 } 978 xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", 979 pCir->MaxClock / 1000); 980 981 /* 982 * Setup the ClockRanges, which describe what clock ranges are available, 983 * and what sort of modes they can be used for. 984 */ 985 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 986 clockRanges->next = NULL; 987 clockRanges->minClock = pCir->MinClock; 988 clockRanges->maxClock = pCir->MaxClock; 989 clockRanges->clockIndex = -1; /* programmable */ 990 clockRanges->interlaceAllowed = FALSE; /* XXX check this */ 991 clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ 992 clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ 993 clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ 994 clockRanges->ClockMulFactor = 1; 995 clockRanges->ClockDivFactor = 1; 996 clockRanges->PrivFlags = 0; 997 998 switch (pCir->Chipset) 999 { 1000 case PCI_CHIP_GD7548: 1001 pCir->Rounding = 1; 1002 break; 1003 1004 default: 1005 pCir->Rounding = 128 >> pCir->BppShift; 1006 } 1007 1008#if 0 1009 if (pCir->Chipset != PCI_CHIP_GD5446 && 1010 pCir->Chipset != PCI_CHIP_GD5480) { 1011 /* XXX Kludge */ 1012 pCir->NoAccel = TRUE; 1013 } 1014#endif 1015 1016 /* 1017 * xf86ValidateModes will check that the mode HTotal and VTotal values 1018 * don't exceed the chipset's limit if pScrn->maxHValue and 1019 * pScrn->maxVValue are set. Since our AlpValidMode() already takes 1020 * care of this, we don't worry about setting them here. 1021 */ 1022 1023 /* Select valid modes from those available */ 1024 if (pCir->NoAccel) { 1025 /* 1026 * XXX Assuming min pitch 256, max 2048 1027 * XXX Assuming min height 128, max 2048 1028 */ 1029 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 1030 pScrn->display->modes, clockRanges, 1031 NULL, 256, 2048, 1032 pCir->Rounding * pScrn->bitsPerPixel, 128, 2048, 1033 pScrn->display->virtualX, 1034 pScrn->display->virtualY, 1035 pCir->FbMapSize, 1036 LOOKUP_BEST_REFRESH); 1037 } else { 1038 /* 1039 * XXX Assuming min height 128, max 2048 1040 */ 1041 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 1042 pScrn->display->modes, clockRanges, 1043 GetAccelPitchValues(pScrn), 0, 0, 1044 pCir->Rounding * pScrn->bitsPerPixel, 128, 2048, 1045 pScrn->display->virtualX, 1046 pScrn->display->virtualY, 1047 pCir->FbMapSize, 1048 LOOKUP_BEST_REFRESH); 1049 } 1050 if (i == -1) { 1051 AlpFreeRec(pScrn); 1052 return FALSE; 1053 } 1054 1055 /* Prune the modes marked as invalid */ 1056 xf86PruneDriverModes(pScrn); 1057 1058 if (i == 0 || pScrn->modes == NULL) { 1059 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 1060 AlpFreeRec(pScrn); 1061 return FALSE; 1062 } 1063 1064 /* 1065 * Set the CRTC parameters for all of the modes based on the type 1066 * of mode, and the chipset's interlace requirements. 1067 * 1068 * Calling this is required if the mode->Crtc* values are used by the 1069 * driver and if the driver doesn't provide code to set them. They 1070 * are not pre-initialised at all. 1071 */ 1072 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 1073 1074 /* Set the current mode to the first in the list */ 1075 pScrn->currentMode = pScrn->modes; 1076 1077 /* Print the list of modes being used */ 1078 xf86PrintModes(pScrn); 1079 1080 /* Set display resolution */ 1081 xf86SetDpi(pScrn, 0, 0); 1082 1083 /* Load bpp-specific modules */ 1084 switch (pScrn->bitsPerPixel) { 1085 case 1: 1086 if (xf86LoadSubModule(pScrn, "xf1bpp") == NULL) { 1087 AlpFreeRec(pScrn); 1088 return FALSE; 1089 } 1090 xf86LoaderReqSymbols("xf1bppScreenInit",NULL); 1091 break; 1092 case 4: 1093 if (xf86LoadSubModule(pScrn, "xf4bpp") == NULL) { 1094 AlpFreeRec(pScrn); 1095 return FALSE; 1096 } 1097 xf86LoaderReqSymbols("xf4bppScreenInit",NULL); 1098 break; 1099 case 8: 1100 case 16: 1101 case 24: 1102 case 32: 1103 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 1104 AlpFreeRec(pScrn); 1105 return FALSE; 1106 } 1107 xf86LoaderReqSymLists(fbSymbols, NULL); 1108 break; 1109 } 1110 1111 /* Load XAA if needed */ 1112 if (!pCir->NoAccel) { 1113 if (!xf86LoadSubModule(pScrn, "xaa")) { 1114 AlpFreeRec(pScrn); 1115 return FALSE; 1116 } 1117 xf86LoaderReqSymLists(xaaSymbols, NULL); 1118 } 1119 1120 /* Load ramdac if needed */ 1121 if (pCir->HWCursor) { 1122 if (!xf86LoadSubModule(pScrn, "ramdac")) { 1123 AlpFreeRec(pScrn); 1124 return FALSE; 1125 } 1126 xf86LoaderReqSymLists(ramdacSymbols, NULL); 1127 } 1128 1129 if (pCir->shadowFB) { 1130 if (!xf86LoadSubModule(pScrn, "shadowfb")) { 1131 AlpFreeRec(pScrn); 1132 return FALSE; 1133 } 1134 xf86LoaderReqSymLists(shadowSymbols, NULL); 1135 } 1136 1137 return TRUE; 1138} 1139 1140/* 1141 * This function saves the video state. 1142 */ 1143static void 1144AlpSave(ScrnInfoPtr pScrn) 1145{ 1146 CirPtr pCir = CIRPTR(pScrn); 1147 vgaHWPtr hwp = VGAHWPTR(pScrn); 1148 1149#ifdef ALP_DEBUG 1150 ErrorF("AlpSave\n"); 1151#endif 1152 vgaHWSave(pScrn, &VGAHWPTR(pScrn)->SavedReg, VGA_SR_ALL); 1153 1154 pCir->chip.alp->ModeReg.ExtVga[CR1A] = pCir->chip.alp->SavedReg.ExtVga[CR1A] = hwp->readCrtc(hwp, 0x1A); 1155 pCir->chip.alp->ModeReg.ExtVga[CR1B] = pCir->chip.alp->SavedReg.ExtVga[CR1B] = hwp->readCrtc(hwp, 0x1B); 1156 pCir->chip.alp->ModeReg.ExtVga[CR1D] = pCir->chip.alp->SavedReg.ExtVga[CR1D] = hwp->readCrtc(hwp, 0x1D); 1157 pCir->chip.alp->ModeReg.ExtVga[SR07] = pCir->chip.alp->SavedReg.ExtVga[SR07] = hwp->readSeq(hwp, 0x07); 1158 pCir->chip.alp->ModeReg.ExtVga[SR0E] = pCir->chip.alp->SavedReg.ExtVga[SR0E] = hwp->readSeq(hwp, 0x0E); 1159 pCir->chip.alp->ModeReg.ExtVga[SR12] = pCir->chip.alp->SavedReg.ExtVga[SR12] = hwp->readSeq(hwp, 0x12); 1160 pCir->chip.alp->ModeReg.ExtVga[SR13] = pCir->chip.alp->SavedReg.ExtVga[SR13] = hwp->readSeq(hwp, 0x13); 1161 pCir->chip.alp->ModeReg.ExtVga[SR17] = pCir->chip.alp->SavedReg.ExtVga[SR17] = hwp->readSeq(hwp, 0x17); 1162 pCir->chip.alp->ModeReg.ExtVga[SR1E] = pCir->chip.alp->SavedReg.ExtVga[SR1E] = hwp->readSeq(hwp, 0x1E); 1163 pCir->chip.alp->ModeReg.ExtVga[SR21] = pCir->chip.alp->SavedReg.ExtVga[SR21] = hwp->readSeq(hwp, 0x21); 1164 pCir->chip.alp->ModeReg.ExtVga[SR2D] = pCir->chip.alp->SavedReg.ExtVga[SR2D] = hwp->readSeq(hwp, 0x2D); 1165 pCir->chip.alp->ModeReg.ExtVga[GR17] = pCir->chip.alp->SavedReg.ExtVga[GR17] = hwp->readGr(hwp, 0x17); 1166 pCir->chip.alp->ModeReg.ExtVga[GR18] = pCir->chip.alp->SavedReg.ExtVga[GR18] = hwp->readGr(hwp, 0x18); 1167 /* The first 4 reads are for the pixel mask register. After 4 times that 1168 this register is accessed in succession reading/writing this address 1169 accesses the HDR. */ 1170 hwp->readDacMask(hwp); 1171 hwp->readDacMask(hwp); 1172 hwp->readDacMask(hwp); 1173 hwp->readDacMask(hwp); 1174 pCir->chip.alp->ModeReg.ExtVga[HDR] = pCir->chip.alp->SavedReg.ExtVga[HDR] = hwp->readDacMask(hwp); 1175} 1176 1177/* XXX */ 1178static void 1179AlpFix1bppColorMap(ScrnInfoPtr pScrn) 1180{ 1181 vgaHWPtr hwp = VGAHWPTR(pScrn); 1182/* In 1 bpp we have color 0 at LUT 0 and color 1 at LUT 0x3f. 1183 This makes white and black look right (otherwise they were both 1184 black. I'm sure there's a better way to do that, just lazy to 1185 search the docs. */ 1186 1187 hwp->writeDacWriteAddr(hwp, 0x00); 1188 hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00); 1189 hwp->writeDacWriteAddr(hwp, 0x3F); 1190 hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F); 1191} 1192 1193static void 1194alpRestore(vgaHWPtr hwp, AlpRegPtr cirReg) 1195{ 1196 hwp->writeCrtc(hwp, 0x1A, cirReg->ExtVga[CR1A]); 1197 hwp->writeCrtc(hwp, 0x1B, cirReg->ExtVga[CR1B]); 1198 hwp->writeCrtc(hwp, 0x1D, cirReg->ExtVga[CR1D]); 1199 hwp->writeSeq(hwp, 0x07, cirReg->ExtVga[SR07]); 1200 hwp->writeSeq(hwp, 0x0E, cirReg->ExtVga[SR0E]); 1201 hwp->writeSeq(hwp, 0x12, cirReg->ExtVga[SR12]); 1202 hwp->writeSeq(hwp, 0x13, cirReg->ExtVga[SR13]); 1203 hwp->writeSeq(hwp, 0x17, cirReg->ExtVga[SR17]); 1204 hwp->writeSeq(hwp, 0x1E, cirReg->ExtVga[SR1E]); 1205 hwp->writeSeq(hwp, 0x21, cirReg->ExtVga[SR21]); 1206 hwp->writeSeq(hwp, 0x2D, cirReg->ExtVga[SR2D]); 1207 hwp->writeGr(hwp, 0x17, cirReg->ExtVga[GR17]); 1208 hwp->writeGr(hwp, 0x18, cirReg->ExtVga[GR18]); 1209 /* The first 4 reads are for the pixel mask register. After 4 times that 1210 this register is accessed in succession reading/writing this address 1211 accesses the HDR. */ 1212 hwp->readDacMask(hwp); 1213 hwp->readDacMask(hwp); 1214 hwp->readDacMask(hwp); 1215 hwp->readDacMask(hwp); 1216 hwp->writeDacMask(hwp, cirReg->ExtVga[HDR ]); 1217} 1218 1219 1220/* 1221 * Initialise a new mode. This is currently still using the old 1222 * "initialise struct, restore/write struct to HW" model. That could 1223 * be changed. 1224 * Why?? (EE) 1225 */ 1226 1227static Bool 1228AlpModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 1229{ 1230 vgaHWPtr hwp; 1231 CirPtr pCir; 1232 int depthcode; 1233 int width; 1234 Bool HDiv2 = FALSE, VDiv2 = FALSE; 1235 1236#ifdef ALP_DEBUG 1237 ErrorF("AlpModeInit %d bpp, %d %d %d %d %d %d %d %d %d\n", 1238 pScrn->bitsPerPixel, 1239 mode->Clock, 1240 mode->HDisplay, 1241 mode->HSyncStart, 1242 mode->HSyncEnd, 1243 mode->HTotal, 1244 mode->VDisplay, 1245 mode->VSyncStart, 1246 mode->VSyncEnd, 1247 mode->VTotal); 1248 1249 ErrorF("AlpModeInit: depth %d bits\n", pScrn->depth); 1250#endif 1251 1252 pCir = CIRPTR(pScrn); 1253 hwp = VGAHWPTR(pScrn); 1254 vgaHWUnlock(hwp); 1255 1256 pCir->pitch = pScrn->displayWidth * pScrn->bitsPerPixel >> 3; 1257 1258 depthcode = pScrn->depth; 1259 if (pScrn->bitsPerPixel == 32) 1260 depthcode = 32; 1261 1262 if ((pCir->Chipset == PCI_CHIP_GD5480 && mode->Clock > 135100) || 1263 (pCir->Chipset == PCI_CHIP_GD5446 && mode->Clock > 85500)) { 1264 /* The actual DAC register value is set later. */ 1265 /* The CRTC is clocked at VCLK / 2, so we must half the */ 1266 /* horizontal timings. */ 1267 if (!mode->CrtcHAdjusted) { 1268 mode->CrtcHDisplay >>= 1; 1269 mode->CrtcHSyncStart >>= 1; 1270 mode->CrtcHTotal >>= 1; 1271 mode->CrtcHSyncEnd >>= 1; 1272 mode->SynthClock >>= 1; 1273 mode->CrtcHAdjusted = TRUE; 1274 } 1275 depthcode += 64; 1276 HDiv2 = TRUE; 1277 } 1278 1279 if (mode->VTotal >= 1024 && !(mode->Flags & V_INTERLACE)) { 1280 /* For non-interlaced vertical timing >= 1024, the vertical timings */ 1281 /* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */ 1282 if (!mode->CrtcVAdjusted) { 1283 mode->CrtcVDisplay >>= 1; 1284 mode->CrtcVSyncStart >>= 1; 1285 mode->CrtcVSyncEnd >>= 1; 1286 mode->CrtcVTotal >>= 1; 1287 mode->CrtcVAdjusted = TRUE; 1288 } 1289 VDiv2 = TRUE; 1290 } 1291 1292 /* Initialise the ModeReg values */ 1293 if (!vgaHWInit(pScrn, mode)) 1294 return FALSE; 1295 pScrn->vtSema = TRUE; 1296 1297 /* Turn off HW cursor, gamma correction, overscan color protect. */ 1298 pCir->chip.alp->ModeReg.ExtVga[SR12] = 0; 1299 if ((pCir->properties & HWCUR64) == HWCUR64) 1300 { 1301 pCir->chip.alp->ModeReg.ExtVga[SR12] = 0x4; 1302 switch (pCir->Chipset) 1303 { 1304 case PCI_CHIP_GD7548: 1305 pCir->chip.alp->ModeReg.ExtVga[SR21] |= 0x10; 1306 break; 1307 } 1308 1309 } 1310 else 1311 pCir->chip.alp->ModeReg.ExtVga[SR12] = 0; 1312 1313 1314 if(VDiv2) 1315 hwp->ModeReg.CRTC[0x17] |= 0x04; 1316 1317#ifdef ALP_DEBUG 1318 ErrorF("SynthClock = %d\n", mode->SynthClock); 1319#endif 1320 1321 /* Disable DCLK pin driver, interrupts. */ 1322 pCir->chip.alp->ModeReg.ExtVga[GR17] |= 0x08; 1323 pCir->chip.alp->ModeReg.ExtVga[GR17] &= ~0x04; 1324 1325 pCir->chip.alp->ModeReg.ExtVga[HDR] = 0; 1326 /* Enable linear mode and high-res packed pixel mode */ 1327 pCir->chip.alp->ModeReg.ExtVga[SR07] &= 0xe0; 1328#ifdef ALP_DEBUG 1329 ErrorF("depthcode = %d\n", depthcode); 1330#endif 1331 1332 if (pScrn->bitsPerPixel == 1) { 1333 hwp->IOBase = 0x3B0; 1334 hwp->ModeReg.MiscOutReg &= ~0x01; 1335 } else { 1336 hwp->IOBase = 0x3D0; 1337 hwp->ModeReg.MiscOutReg |= 0x01; 1338 } 1339 1340 switch (depthcode) { 1341 case 1: 1342 case 4: 1343 pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x10; 1344 break; 1345 case 8: 1346 pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x11; 1347 break; 1348 case 64+8: 1349 pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17; 1350 break; 1351 case 15: 1352 pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17; 1353 pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC0; 1354 break; 1355 case 64+15: 1356 pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19; 1357 pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC0; 1358 break; 1359 case 16: 1360 pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x17; 1361 pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC1; 1362 break; 1363 case 64+16: 1364 pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19; 1365 pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC1; 1366 break; 1367 case 24: 1368 pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x15; 1369 pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC5; 1370 break; 1371 case 32: 1372 pCir->chip.alp->ModeReg.ExtVga[SR07] |= 0x19; 1373 pCir->chip.alp->ModeReg.ExtVga[HDR ] = 0xC5; 1374 break; 1375 default: 1376 ErrorF("X11: Internal error: AlpModeInit: Cannot Initialize display to requested mode\n"); 1377#ifdef ALP_DEBUG 1378 ErrorF("AlpModeInit returning FALSE on depthcode %d\n", depthcode); 1379#endif 1380 return FALSE; 1381 } 1382 if (HDiv2) 1383 pCir->chip.alp->ModeReg.ExtVga[GR18] |= 0x20; 1384 else 1385 pCir->chip.alp->ModeReg.ExtVga[GR18] &= ~0x20; 1386 1387 1388 /* Some extra init stuff */ 1389 switch (pCir->Chipset) 1390 { 1391 case PCI_CHIP_GD7548: 1392 /* Do we use MMIO ? 1393 If we do and we are on a 7548, we need to tell the board 1394 that we want MMIO. */ 1395 if (pCir->UseMMIO) 1396 { 1397 pCir->chip.alp->ModeReg.ExtVga[SR17] = 1398 (pCir->chip.alp->ModeReg.ExtVga[SR17] & ~0x40) | 4; 1399 ErrorF("UseMMIO: SR17=%2X\n", (int) (pCir->chip.alp->ModeReg.ExtVga[SR17])); 1400 } 1401#ifdef ALP_SETUP 1402 ErrorF("SR2D=%2X\n", (int) (pCir->chip.alp->ModeReg.ExtVga[SR17])); 1403#endif 1404 pCir->chip.alp->ModeReg.ExtVga[SR2D] |= 0xC0; 1405 break; 1406 } 1407 1408 /* No support for interlace (yet) */ 1409 pCir->chip.alp->ModeReg.ExtVga[CR1A] = 0x00; 1410 1411 width = pScrn->displayWidth * pScrn->bitsPerPixel / 8; 1412 if (pScrn->bitsPerPixel == 1) 1413 width <<= 2; 1414 hwp->ModeReg.CRTC[0x13] = width >> 3; 1415 /* Offset extension (see CR13) */ 1416 pCir->chip.alp->ModeReg.ExtVga[CR1B] &= 0xAF; 1417 pCir->chip.alp->ModeReg.ExtVga[CR1B] |= (width >> (3+4)) & 0x10; 1418 pCir->chip.alp->ModeReg.ExtVga[CR1B] |= (width >> (3+3)) & 0x40; 1419 pCir->chip.alp->ModeReg.ExtVga[CR1B] |= 0x22; 1420 1421 /* Programme the registers */ 1422 vgaHWProtect(pScrn, TRUE); 1423 hwp->writeMiscOut(hwp, hwp->ModeReg.MiscOutReg); 1424 alpRestore(hwp,&pCir->chip.alp->ModeReg); 1425 AlpSetClock(pCir, hwp, mode->SynthClock); 1426 1427 vgaHWRestore(pScrn, &hwp->ModeReg, VGA_SR_MODE | VGA_SR_CMAP); 1428 1429 /* XXX */ 1430 if (pScrn->bitsPerPixel == 1) 1431 AlpFix1bppColorMap(pScrn); 1432 1433 vgaHWProtect(pScrn, FALSE); 1434 1435 return TRUE; 1436} 1437 1438/* 1439 * Restore the initial (text) mode. 1440 */ 1441static void 1442AlpRestore(ScrnInfoPtr pScrn) 1443{ 1444 vgaHWPtr hwp; 1445 vgaRegPtr vgaReg; 1446 CirPtr pCir; 1447 AlpRegPtr alpReg; 1448 1449#ifdef ALP_DEBUG 1450 ErrorF("AlpRestore\n"); 1451#endif 1452 1453 hwp = VGAHWPTR(pScrn); 1454 pCir = CIRPTR(pScrn); 1455 vgaReg = &hwp->SavedReg; 1456 alpReg = &pCir->chip.alp->SavedReg; 1457 1458 vgaHWProtect(pScrn, TRUE); 1459 1460 alpRestore(hwp,alpReg); 1461 1462 vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); 1463 vgaHWProtect(pScrn, FALSE); 1464} 1465 1466/* Mandatory */ 1467 1468/* This gets called at the start of each server generation */ 1469 1470Bool 1471AlpScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 1472{ 1473 ScrnInfoPtr pScrn; 1474 vgaHWPtr hwp; 1475 CirPtr pCir; 1476 int i, ret; 1477 int init_picture = 0; 1478 VisualPtr visual; 1479 int displayWidth,width,height; 1480 unsigned char * FbBase = NULL; 1481 int cursor_size = 0; 1482 1483#ifdef ALP_DEBUG 1484 ErrorF("AlpScreenInit\n"); 1485#endif 1486 1487 /* 1488 * First get the ScrnInfoRec 1489 */ 1490 pScrn = xf86Screens[pScreen->myNum]; 1491 1492 hwp = VGAHWPTR(pScrn); 1493 pCir = CIRPTR(pScrn); 1494 1495 /* Map the VGA memory when the primary video */ 1496 if (!vgaHWMapMem(pScrn)) 1497 return FALSE; 1498 1499 /* Map the Alp memory and MMIO areas */ 1500 if (!CirMapMem(pCir, pScrn->scrnIndex)) 1501 return FALSE; 1502 1503 /* The 754x supports MMIO for the BitBlt engine but 1504 not for the VGA registers */ 1505 switch (pCir->Chipset) 1506 { 1507 case PCI_CHIP_GD7548: 1508 break; 1509 default: 1510 if(pCir->UseMMIO) 1511 vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0); 1512 } 1513 1514 vgaHWGetIOBase(hwp); 1515 1516 /* Save the current state */ 1517 AlpSave(pScrn); 1518 1519 /* Initialise the first mode */ 1520 if (!AlpModeInit(pScrn, pScrn->currentMode)) 1521 return FALSE; 1522 1523 /* Make things beautiful */ 1524 AlpSaveScreen(pScreen, SCREEN_SAVER_ON); 1525 1526 /* Set the viewport */ 1527 AlpAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 1528 1529 /* 1530 * The next step is to setup the screen's visuals, and initialise the 1531 * framebuffer code. In cases where the framebuffer's default 1532 * choices for things like visual layouts and bits per RGB are OK, 1533 * this may be as simple as calling the framebuffer's ScreenInit() 1534 * function. If not, the visuals will need to be setup before calling 1535 * a fb ScreenInit() function and fixed up after. 1536 * 1537 */ 1538 1539 /* 1540 * Reset the visual list. 1541 */ 1542 miClearVisualTypes(); 1543 1544 /* Setup the visuals we support. */ 1545 1546 if (!miSetVisualTypes(pScrn->depth, 1547 miGetDefaultVisualMask(pScrn->depth), 1548 pScrn->rgbBits, pScrn->defaultVisual)) 1549 return FALSE; 1550 1551 miSetPixmapDepths (); 1552 1553 displayWidth = pScrn->displayWidth; 1554 if (pCir->rotate) { 1555 height = pScrn->virtualX; 1556 width = pScrn->virtualY; 1557 } else { 1558 width = pScrn->virtualX; 1559 height = pScrn->virtualY; 1560 } 1561 1562 if(pCir->shadowFB) { 1563 pCir->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 1564 pCir->ShadowPtr = xalloc(pCir->ShadowPitch * height); 1565 displayWidth = pCir->ShadowPitch / (pScrn->bitsPerPixel >> 3); 1566 FbBase = pCir->ShadowPtr; 1567 } else { 1568 pCir->ShadowPtr = NULL; 1569 FbBase = pCir->FbBase; 1570 } 1571 1572 /* 1573 * Call the framebuffer layer's ScreenInit function, and fill in other 1574 * pScreen fields. 1575 */ 1576 1577 switch (pScrn->bitsPerPixel) { 1578 case 1: 1579 ret = xf1bppScreenInit(pScreen, FbBase, 1580 width, height, 1581 pScrn->xDpi, pScrn->yDpi, 1582 displayWidth); 1583 break; 1584 case 4: 1585 ret = xf4bppScreenInit(pScreen, FbBase, 1586 width, height, 1587 pScrn->xDpi, pScrn->yDpi, 1588 displayWidth); 1589 break; 1590 case 8: 1591 case 16: 1592 case 24: 1593 case 32: 1594 ret = fbScreenInit(pScreen, FbBase, 1595 width,height, 1596 pScrn->xDpi, pScrn->yDpi, 1597 displayWidth,pScrn->bitsPerPixel); 1598 init_picture = 1; 1599 break; 1600 default: 1601 xf86DrvMsg(scrnIndex, X_ERROR, 1602 "X11: Internal error: invalid bpp (%d) in AlpScreenInit\n", 1603 pScrn->bitsPerPixel); 1604 ret = FALSE; 1605 break; 1606 } 1607 if (!ret) 1608 return FALSE; 1609 1610#ifdef ALP_DEBUG 1611 ErrorF("AlpScreenInit after depth dependent init\n"); 1612#endif 1613 1614 /* Override the default mask/offset settings */ 1615 if (pScrn->bitsPerPixel > 8) { 1616 for (i = 0; i < pScreen->numVisuals; i++) { 1617 visual = &pScreen->visuals[i]; 1618 if ((visual->class | DynamicClass) == DirectColor) { 1619 visual->offsetRed = pScrn->offset.red; 1620 visual->offsetGreen = pScrn->offset.green; 1621 visual->offsetBlue = pScrn->offset.blue; 1622 visual->redMask = pScrn->mask.red; 1623 visual->greenMask = pScrn->mask.green; 1624 visual->blueMask = pScrn->mask.blue; 1625 } 1626 } 1627 } 1628 1629 /* must be after RGB ordering fixed */ 1630 if (init_picture) 1631 fbPictureInit (pScreen, 0, 0); 1632 1633 miInitializeBackingStore(pScreen); 1634 1635 /* 1636 * Set initial black & white colourmap indices. 1637 */ 1638 xf86SetBlackWhitePixels(pScreen); 1639 1640 /* 1641 Allocation of off-screen memory to various stuff 1642 (hardware cursor, 8x8 mono pattern...) 1643 Allocation goes top-down in memory, since the cursor 1644 *must* be in the last videoram locations 1645 */ 1646 pCir->offscreen_offset = pScrn->videoRam*1024; 1647 pCir->offscreen_size = pScrn->videoRam * 1024 - pScrn->virtualY * 1648 (BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel)); 1649 1650#ifdef ALP_DEBUG 1651 ErrorF("offscreen_offset=%d, offscreen_size=%d\n", 1652 pCir->offscreen_offset, pCir->offscreen_size); 1653#endif 1654 1655 /* Initialise cursor functions */ 1656 if (pCir->HWCursor) { /* Initialize HW cursor layer */ 1657 1658 if ((pCir->properties & HWCUR64) 1659 && (pCir->offscreen_size >= 64*8*2)) { 1660 cursor_size = 64; 1661 pCir->offscreen_size -= 64*8*2; 1662 pCir->offscreen_offset -= 64*8*2; 1663 } else if (pCir->offscreen_size >= 32*4*2) { 1664 cursor_size = 32; 1665 pCir->offscreen_size -= 32*8*2; 1666 pCir->offscreen_offset -= 32*8*2; 1667 } 1668 } 1669 1670 if (!pCir->NoAccel) { /* Initialize XAA functions */ 1671 AlpOffscreenAccelInit(pScrn); 1672 if (!(pCir->UseMMIO ? AlpXAAInitMMIO(pScreen) : 1673 AlpXAAInit(pScreen))) 1674 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1675 "Could not initialize XAA\n"); 1676 } 1677 1678#if 1 1679 pCir->DGAModeInit = AlpModeInit; 1680 if (!CirDGAInit(pScreen)) 1681 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1682 "DGA initialization failed\n"); 1683#endif 1684 xf86SetSilkenMouse(pScreen); 1685 1686 /* Initialise cursor functions */ 1687 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 1688 1689 if (pCir->HWCursor) { 1690 if (!AlpHWCursorInit(pScreen, cursor_size)) 1691 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1692 "Hardware cursor initialization failed\n"); 1693#ifdef ALP_DEBUG 1694 ErrorF("AlpHWCursorInit() complete\n"); 1695#endif 1696 } 1697 1698 if (pCir->shadowFB) { 1699 RefreshAreaFuncPtr refreshArea = cirRefreshArea; 1700 1701 if(pCir->rotate) { 1702 if (!pCir->PointerMoved) { 1703 pCir->PointerMoved = pScrn->PointerMoved; 1704 pScrn->PointerMoved = cirPointerMoved; 1705 } 1706 1707 switch(pScrn->bitsPerPixel) { 1708 case 8: refreshArea = cirRefreshArea8; break; 1709 case 16: refreshArea = cirRefreshArea16; break; 1710 case 24: refreshArea = cirRefreshArea24; break; 1711 case 32: refreshArea = cirRefreshArea32; break; 1712 } 1713 } 1714 1715 ShadowFBInit(pScreen, refreshArea); 1716 } 1717 1718 /* Initialise default colourmap */ 1719 if (!miCreateDefColormap(pScreen)) 1720 return FALSE; 1721 1722 if (pScrn->bitsPerPixel > 1 && pScrn->bitsPerPixel <= 8) 1723 vgaHWHandleColormaps(pScreen); 1724 1725 xf86DPMSInit(pScreen, AlpDisplayPowerManagementSet, 0); 1726 1727 pScrn->memPhysBase = pCir->FbAddress; 1728 pScrn->fbOffset = 0; 1729 1730 { 1731 XF86VideoAdaptorPtr *ptr; 1732 int n; 1733 1734 n = xf86XVListGenericAdaptors(pScrn,&ptr); 1735 if (n) 1736 xf86XVScreenInit(pScreen, ptr, n); 1737 } 1738 1739 /* 1740 * Wrap the CloseScreen vector and set SaveScreen. 1741 */ 1742 pScreen->SaveScreen = AlpSaveScreen; 1743 pCir->CloseScreen = pScreen->CloseScreen; 1744 pScreen->CloseScreen = AlpCloseScreen; 1745 1746 /* Report any unused options (only for the first generation) */ 1747 if (serverGeneration == 1) 1748 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 1749 1750 /* Done */ 1751 return TRUE; 1752} 1753 1754 1755/* Usually mandatory */ 1756Bool 1757AlpSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 1758{ 1759 return AlpModeInit(xf86Screens[scrnIndex], mode); 1760} 1761 1762 1763/* 1764 * This function is used to initialize the Start Address - the first 1765 * displayed location in the video memory. 1766 */ 1767/* Usually mandatory */ 1768void 1769AlpAdjustFrame(int scrnIndex, int x, int y, int flags) 1770{ 1771 ScrnInfoPtr pScrn; 1772 int Base, tmp; 1773 vgaHWPtr hwp; 1774 1775 pScrn = xf86Screens[scrnIndex]; 1776 hwp = VGAHWPTR(pScrn); 1777 1778 Base = ((y * pScrn->displayWidth + x) / 8); 1779 if (pScrn->bitsPerPixel != 1) 1780 Base *= (pScrn->bitsPerPixel/4); 1781 1782#ifdef ALP_DEBUG 1783 ErrorF("AlpAdjustFrame %d %d 0x%x %d %x\n", x, y, flags, Base, Base); 1784#endif 1785 1786 if ((Base & ~0x000FFFFF) != 0) { 1787 ErrorF("X11: Internal error: AlpAdjustFrame: cannot handle overflow\n"); 1788 return; 1789 } 1790 1791 hwp->writeCrtc(hwp, 0x0C, (Base >> 8) & 0xff); 1792 hwp->writeCrtc(hwp, 0x0D, Base & 0xff); 1793 tmp = hwp->readCrtc(hwp, 0x1B); 1794 tmp &= 0xF2; 1795 tmp |= (Base >> 16) & 0x01; 1796 tmp |= (Base >> 15) & 0x0C; 1797 hwp->writeCrtc(hwp, 0x1B, tmp); 1798 tmp = hwp->readCrtc(hwp, 0x1D); 1799 tmp &= 0x7F; 1800 tmp |= (Base >> 12) & 0x80; 1801 hwp->writeCrtc(hwp, 0x1D, tmp); 1802} 1803 1804/* 1805 * This is called when VT switching back to the X server. Its job is 1806 * to reinitialise the video mode. 1807 * 1808 * We may wish to unmap video/MMIO memory too. 1809 */ 1810 1811/* Mandatory */ 1812Bool 1813AlpEnterVT(int scrnIndex, int flags) 1814{ 1815 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1816 CirPtr pCir = CIRPTR(pScrn); 1817 Bool ret; 1818 1819#ifdef ALP_DEBUG 1820 ErrorF("AlpEnterVT\n"); 1821#endif 1822 1823 /* Should we re-save the text mode on each VT enter? */ 1824 if (!(ret = AlpModeInit(pScrn, pScrn->currentMode))) 1825 return FALSE; 1826 1827 if (!pCir->NoAccel) 1828 pCir->InitAccel(pScrn); 1829 1830 return ret; 1831} 1832 1833 1834/* 1835 * This is called when VT switching away from the X server. Its job is 1836 * to restore the previous (text) mode. 1837 * 1838 * We may wish to remap video/MMIO memory too. 1839 */ 1840 1841/* Mandatory */ 1842void 1843AlpLeaveVT(int scrnIndex, int flags) 1844{ 1845 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1846 vgaHWPtr hwp = VGAHWPTR(pScrn); 1847#ifdef ALP_DEBUG 1848 ErrorF("AlpLeaveVT\n"); 1849#endif 1850 1851 AlpRestore(pScrn); 1852 vgaHWLock(hwp); 1853} 1854 1855 1856/* 1857 * This is called at the end of each server generation. It restores the 1858 * original (text) mode. It should also unmap the video memory, and free 1859 * any per-generation data allocated by the driver. It should finish 1860 * by unwrapping and calling the saved CloseScreen function. 1861 */ 1862 1863/* Mandatory */ 1864static Bool 1865AlpCloseScreen(int scrnIndex, ScreenPtr pScreen) 1866{ 1867 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1868 vgaHWPtr hwp = VGAHWPTR(pScrn); 1869 CirPtr pCir = CIRPTR(pScrn); 1870 1871 if(pScrn->vtSema) { 1872 AlpRestore(pScrn); 1873 vgaHWLock(hwp); 1874 CirUnmapMem(pCir, pScrn->scrnIndex); 1875 } 1876 1877 if (pCir->AccelInfoRec) 1878 XAADestroyInfoRec(pCir->AccelInfoRec); 1879 pCir->AccelInfoRec = NULL; 1880 if (pCir->CursorInfoRec) 1881 xf86DestroyCursorInfoRec(pCir->CursorInfoRec); 1882 pCir->CursorInfoRec = NULL; 1883 if (pCir->DGAModes) 1884 xfree(pCir->DGAModes); 1885 pCir->DGAnumModes = 0; 1886 pCir->DGAModes = NULL; 1887 1888 pScrn->vtSema = FALSE; 1889 1890 pScreen->CloseScreen = pCir->CloseScreen; 1891 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 1892} 1893 1894 1895/* Free up any persistent data structures */ 1896 1897/* Optional */ 1898void 1899AlpFreeScreen(int scrnIndex, int flags) 1900{ 1901#ifdef ALP_DEBUG 1902 ErrorF("AlpFreeScreen\n"); 1903#endif 1904 /* 1905 * This only gets called when a screen is being deleted. It does not 1906 * get called routinely at the end of a server generation. 1907 */ 1908 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 1909 vgaHWFreeHWRec(xf86Screens[scrnIndex]); 1910 AlpFreeRec(xf86Screens[scrnIndex]); 1911} 1912 1913 1914/* Checks if a mode is suitable for the selected chipset. */ 1915 1916/* Optional */ 1917ModeStatus 1918AlpValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 1919{ 1920 int lace; 1921 1922 lace = 1 + ((mode->Flags & V_INTERLACE) != 0); 1923 1924 if ((mode->CrtcHDisplay <= 2048) && 1925 (mode->CrtcHSyncStart <= 4096) && 1926 (mode->CrtcHSyncEnd <= 4096) && 1927 (mode->CrtcHTotal <= 4096) && 1928 (mode->CrtcVDisplay <= 2048 * lace) && 1929 (mode->CrtcVSyncStart <= 4096 * lace) && 1930 (mode->CrtcVSyncEnd <= 4096 * lace) && 1931 (mode->CrtcVTotal <= 4096 * lace)) { 1932 return(MODE_OK); 1933 } else { 1934 return(MODE_BAD); 1935 } 1936} 1937 1938/* Do screen blanking */ 1939 1940/* Mandatory */ 1941static Bool 1942AlpSaveScreen(ScreenPtr pScreen, int mode) 1943{ 1944 return vgaHWSaveScreen(pScreen, mode); 1945} 1946 1947/* 1948 * Set the clock to the requested frequency. If the MCLK is very close 1949 * to the requested frequency, it sets a flag so that the MCLK can be used 1950 * as VCLK. However this flag is not yet acted upon. 1951 */ 1952static void 1953AlpSetClock(CirPtr pCir, vgaHWPtr hwp, int freq) 1954{ 1955 int num, den, ffreq; 1956 CARD8 tmp; 1957 1958#ifdef ALP_DEBUG 1959 ErrorF("AlpSetClock freq=%d.%03dMHz\n", freq / 1000, freq % 1000); 1960#endif 1961 1962 ffreq = freq; 1963 if (!CirrusFindClock(&ffreq, pCir->MaxClock, &num, &den)) 1964 return; 1965 1966#ifdef ALP_DEBUG 1967 ErrorF("AlpSetClock: nom=%x den=%x ffreq=%d.%03dMHz\n", 1968 num, den, ffreq / 1000, ffreq % 1000); 1969#endif 1970 /* So - how do we use MCLK here for the VCLK ? */ 1971 1972 /* Set VCLK3. */ 1973 tmp = hwp->readSeq(hwp, 0x0E); 1974 hwp->writeSeq(hwp, 0x0E, (tmp & 0x80) | num); 1975 hwp->writeSeq(hwp, 0x1E, den); 1976} 1977 1978/* 1979 * AlpDisplayPowerManagementSet -- 1980 * 1981 * Sets VESA Display Power Management Signaling (DPMS) Mode. 1982 */ 1983static void 1984AlpDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 1985 int flags) 1986{ 1987 unsigned char sr01, gr0e; 1988 vgaHWPtr hwp; 1989 1990#ifdef ALP_DEBUG 1991 ErrorF("AlpDisplayPowerManagementSet\n"); 1992#endif 1993 1994 hwp = VGAHWPTR(pScrn); 1995 1996#ifdef ALP_DEBUG 1997 ErrorF("AlpDisplayPowerManagementSet: %d\n", PowerManagementMode); 1998#endif 1999 2000 switch (PowerManagementMode) { 2001 case DPMSModeOn: 2002 /* Screen: On; HSync: On, VSync: On */ 2003 sr01 = 0x00; 2004 gr0e = 0x00; 2005 break; 2006 case DPMSModeStandby: 2007 /* Screen: Off; HSync: Off, VSync: On */ 2008 sr01 = 0x20; 2009 gr0e = 0x02; 2010 break; 2011 case DPMSModeSuspend: 2012 /* Screen: Off; HSync: On, VSync: Off */ 2013 sr01 = 0x20; 2014 gr0e = 0x04; 2015 break; 2016 case DPMSModeOff: 2017 /* Screen: Off; HSync: Off, VSync: Off */ 2018 sr01 = 0x20; 2019 gr0e = 0x06; 2020 break; 2021 default: 2022 return; 2023 } 2024 2025 sr01 |= hwp->readSeq(hwp, 0x01) & ~0x20; 2026 hwp->writeSeq(hwp, 0x01, sr01); 2027 gr0e |= hwp->readGr(hwp, 0x0E) & ~0x06; 2028 hwp->writeGr(hwp, 0x0E, gr0e); 2029} 2030 2031#ifdef ALPPROBEI2C 2032static void AlpProbeI2C(int scrnIndex) 2033{ 2034 int i; 2035 I2CBusPtr b; 2036 2037 b = xf86I2CFindBus(scrnIndex, "I2C bus 1"); 2038 if (b == NULL) 2039 ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 1"); 2040 else { 2041 for (i = 2; i < 256; i += 2) 2042 if (xf86I2CProbeAddress(b, i)) 2043 ErrorF("Found device 0x%02x on bus \"%s\"\n", i, b->BusName); 2044 } 2045 b = xf86I2CFindBus(scrnIndex, "I2C bus 2"); 2046 if (b == NULL) 2047 ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 2"); 2048 else { 2049 for (i = 2; i < 256; i += 2) 2050 if (xf86I2CProbeAddress(b, i)) 2051 ErrorF("Found device 0x%02x on bus \"%s\"\n", i, b->BusName); 2052 } 2053} 2054#endif 2055 2056static void 2057AlpProbeLCD(ScrnInfoPtr pScrn) 2058{ 2059 CirPtr pCir = CIRPTR(pScrn); 2060 AlpPtr pAlp = ALPPTR(pCir); 2061 2062 vgaHWPtr hwp = VGAHWPTR(pScrn); 2063 CARD8 lcdCrtl; 2064 2065 static const char* lcd_type_names[] = 2066 { 2067 "none", 2068 "dual-scan monochrome", 2069 "unknown", 2070 "DSTN (dual scan color)", 2071 "TFT (active matrix)" 2072 }; 2073 2074 2075 pAlp->lcdType = LCD_NONE; 2076 2077 switch (pCir->Chipset) { 2078 case PCI_CHIP_GD7548: 2079 switch (hwp->readCrtc(hwp, 0x2C) >> 6) { 2080 case 0: pAlp->lcdType = LCD_DUAL_MONO; break; 2081 case 1: pAlp->lcdType = LCD_UNKNOWN; break; 2082 case 2: pAlp->lcdType = LCD_DSTN; break; 2083 case 3: pAlp->lcdType = LCD_TFT; break; 2084 } 2085 2086 /* Enable LCD control registers instead of normal CRTC registers */ 2087 lcdCrtl = hwp->readCrtc(hwp, 0x2D); 2088 hwp->writeCrtc(hwp, 0x2D, lcdCrtl | 0x80); 2089 2090 switch ((hwp->readCrtc(hwp, 0x9) >> 2) & 3) { 2091 case 0: 2092 pAlp->lcdWidth = 640; 2093 pAlp->lcdHeight = 480; 2094 break; 2095 2096 case 1: 2097 pAlp->lcdWidth = 800; 2098 pAlp->lcdHeight = 600; 2099 break; 2100 2101 case 2: 2102 pAlp->lcdWidth = 1024; 2103 pAlp->lcdHeight = 768; 2104 break; 2105 2106 case 3: 2107 pAlp->lcdWidth = 0; 2108 pAlp->lcdHeight = 0; 2109 break; 2110 } 2111 2112 /* Disable LCD control registers */ 2113 hwp->writeCrtc(hwp, 0x2D, lcdCrtl); 2114 break; 2115 } 2116 2117 if (pAlp->lcdType != LCD_NONE) { 2118 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 2119 "LCD display: %dx%d %s\n", 2120 pAlp->lcdWidth, pAlp->lcdHeight, 2121 lcd_type_names[pAlp->lcdType]); 2122 } 2123} 2124 2125static void 2126AlpOffscreenAccelInit(ScrnInfoPtr pScrn) 2127{ 2128 CirPtr pCir = CIRPTR(pScrn); 2129 AlpPtr pAlp = ALPPTR(pCir); 2130 2131 if (pCir->offscreen_size >= 8 && pCir->Chipset == PCI_CHIP_GD7548) { 2132 pCir->offscreen_offset -= 8; 2133 pCir->offscreen_size -= 8; 2134 pAlp->monoPattern8x8 = pCir->offscreen_offset; 2135#ifdef ALP_DEBUG 2136 ErrorF("monoPattern8x8=%d\n", pAlp->monoPattern8x8); 2137#endif 2138 } else pAlp->monoPattern8x8 = 0; 2139 2140 { 2141 /* TODO: probably not correct if rotated */ 2142 BoxRec box; 2143 box.x1=0; 2144 box.y1=0; 2145 box.x2=pScrn->virtualX; 2146 box.y2= pCir->offscreen_offset / pCir->pitch; 2147 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2148 "Using %d lines for offscreen memory\n", 2149 box.y2 - pScrn->virtualY); 2150 } 2151} 2152