lg_driver.c revision d2b10af6
1/* 2 * Driver for CL-GD546x -- The Laguna family 3 * 4 * lg_driver.c 5 * 6 * (c) 1998 Corin Anderson. 7 * corina@the4cs.com 8 * Tukwila, WA 9 * 10 * This driver is derived from the cir_driver.c module. 11 * Original authors and contributors list include: 12 * Radoslaw Kapitan, Andrew Vanderstock, Dirk Hohndel, 13 * David Dawes, Andrew E. Mileski, Leonard N. Zubkoff, 14 * Guy DESBIEF, Itai Nahshon. 15 */ 16 17#ifdef HAVE_CONFIG_H 18#include "config.h" 19#endif 20 21#define EXPERIMENTAL 22 23/* 24 * All drivers should typically include these. 25 */ 26#include "xf86.h" 27#include "xf86_OSproc.h" 28 29/* 30 * All drivers need this. 31 */ 32 33#include "compiler.h" 34 35/* 36 * Drivers that need to access the PCI config space directly need 37 * this. 38 */ 39#include "xf86Pci.h" 40 41/* 42 * All drivers using the vgahw module need this. This driver needs 43 * to be modified to not use vgaHW for multihead operation. 44 */ 45#include "vgaHW.h" 46 47#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 48#include "xf86RAC.h" 49#include "xf86Resources.h" 50#endif 51 52/* 53 * All drivers initialising the SW cursor need this. 54 */ 55#include "mipointer.h" 56 57/* 58 * Need this for inputInfo. 59 */ 60#include "inputstr.h" 61 62#include "micmap.h" 63 64/* 65 * Needed by the shadowfb. 66 */ 67#include "shadowfb.h" 68 69#include "xf86int10.h" 70 71#include "fb.h" 72 73#include "xf86DDC.h" 74 75#undef LG_DEBUG 76 77#include "cir.h" 78#define _LG_PRIVATE_ 79#include "lg.h" 80 81#include "xf86xv.h" 82#include <X11/extensions/Xv.h> 83 84/* 85 * Forward definitions for the functions that make up the driver. 86 */ 87 88/* 89 * Mandatory functions 90 */ 91Bool LgPreInit(ScrnInfoPtr pScrn, int flags); 92Bool LgScreenInit(SCREEN_INIT_ARGS_DECL); 93Bool LgEnterVT(VT_FUNC_ARGS_DECL); 94void LgLeaveVT(VT_FUNC_ARGS_DECL); 95static Bool LgCloseScreen(CLOSE_SCREEN_ARGS_DECL); 96static Bool LgSaveScreen(ScreenPtr pScreen, Bool mode); 97 98/* 99 * Required if the driver supports mode switching. 100 */ 101Bool LgSwitchMode(SWITCH_MODE_ARGS_DECL); 102/* 103 * Required if the driver supports moving the viewport. 104 */ 105void LgAdjustFrame(ADJUST_FRAME_ARGS_DECL); 106 107/* 108 * Optional functions 109 */ 110void LgFreeScreen(FREE_SCREEN_ARGS_DECL); 111ModeStatus LgValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, 112 Bool verbose, int flags); 113 114/* 115 * Internal functions 116 */ 117static void LgRestoreLgRegs(ScrnInfoPtr pScrn, LgRegPtr lgReg); 118static int LgFindLineData(int displayWidth, int bpp); 119static CARD16 LgSetClock(CirPtr pCir, vgaHWPtr hwp, int freq); 120static void lg_vgaHWSetMmioFunc(vgaHWPtr hwp, CARD8 *base); 121 122static void LgDisplayPowerManagementSet(ScrnInfoPtr pScrn, 123 int PowerManagementMode, 124 int flags); 125 126/* 127 * This is intentionally screen-independent. It indicates the binding 128 * choice made in the first PreInit. 129 */ 130static int pix24bpp = 0; 131 132/* 133 * This contains the functions needed by the server after loading the 134 * driver module. It must be supplied, and gets added the driver list 135 * by the Module Setup function in the dynamic case. In the static 136 * case a reference to this is compiled in, and this requires that the 137 * name of this DriverRec be an upper-case version of the driver name. 138 */ 139 140typedef enum { 141 OPTION_HW_CURSOR, 142 OPTION_PCI_RETRY, 143 OPTION_ROTATE, 144 OPTION_SHADOW_FB, 145 OPTION_NOACCEL 146} LgOpts; 147 148static const OptionInfoRec LgOptions[] = { 149 { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 150 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 151 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 152 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 153/* 154 * fifo_conservative/aggressive; fast/med/slow_dram; ... 155 */ 156 { -1, NULL, OPTV_NONE, {0}, FALSE } 157}; 158 159/* 160 * 1/4 bpp 8 bpp 15/16 bpp 24 bpp 32 bpp 161 */ 162static int gd5462_MaxClocks[] = 163 { 170000, 170000, 135100, 135100, 85500 }; 164static int gd5464_MaxClocks[] = 165 { 170000, 250000, 170000, 170000, 135100 }; 166static int gd5465_MaxClocks[] = 167 { 170000, 250000, 170000, 170000, 135100 }; 168 169/* 170 * We're rather use skinny tiles, so put all of them at the head of 171 * the table. 172 */ 173LgLineDataRec LgLineData[] = { 174 { 5, 640, 0}, 175 { 8, 1024, 0}, 176 {10, 1280, 0}, 177 {13, 1664, 0}, 178 {16, 2048, 0}, 179 {20, 2560, 0}, 180 {10, 2560, 1}, 181 {26, 3328, 0}, 182 { 5, 1280, 1}, 183 { 8, 2048, 1}, 184 {13, 3328, 1}, 185 {16, 4096, 1}, 186 {20, 5120, 1}, 187 {26, 6656, 1}, 188/* 189 * Sentinel to indicate end of table. 190 */ 191 {-1, -1, -1} 192}; 193 194static int LgLinePitches[4][11] = { 195/* 196 * 8 bpp 197 */ 198 { 640, 1024, 1280, 1664, 2048, 2560, 3328, 4096, 5120, 6656, 0 }, 199/* 200 * 16 bpp 201 */ 202 { 320, 512, 640, 832, 1024, 1280, 1664, 2048, 2560, 3328, 0 }, 203/* 204 * 24 bpp 205 */ 206 { 213, 341, 426, 554, 682, 853, 1109, 1365, 1706, 2218, 0 }, 207/* 208 * 32 bpp 209 */ 210 { 160, 256, 320, 416, 512, 640, 832, 1024, 1280, 1664, 0 } 211}; 212 213#ifdef XFree86LOADER 214 215#define LG_MAJOR_VERSION 1 216#define LG_MINOR_VERSION 0 217#define LG_PATCHLEVEL 0 218 219static XF86ModuleVersionInfo lgVersRec = 220{ 221 "cirrus_laguna", 222 MODULEVENDORSTRING, 223 MODINFOSTRING1, 224 MODINFOSTRING2, 225 XORG_VERSION_CURRENT, 226 LG_MAJOR_VERSION, LG_MINOR_VERSION, LG_PATCHLEVEL, 227/* 228 * This is a video driver. 229 */ 230 ABI_CLASS_VIDEODRV, 231 ABI_VIDEODRV_VERSION, 232 MOD_CLASS_NONE, 233 {0,0,0,0} 234}; 235 236/* 237 * This is the module init data. 238 * Its name has to be the driver name followed by ModuleData. 239 */ 240_X_EXPORT XF86ModuleData cirrus_lagunaModuleData = { 241 &lgVersRec, 242 NULL, 243 NULL 244}; 245 246#endif /* XFree86LOADER */ 247 248_X_EXPORT const OptionInfoRec * 249LgAvailableOptions(int chipid) { 250 return LgOptions; 251} 252 253_X_EXPORT ScrnInfoPtr 254LgProbe(int entity) 255{ 256 ScrnInfoPtr pScrn = NULL; 257 if ((pScrn = xf86ConfigPciEntity(pScrn, 0, entity, 258 CIRPciChipsets, 259 NULL, NULL, NULL, 260 NULL, NULL))) { 261 pScrn->PreInit = LgPreInit; 262 pScrn->ScreenInit = LgScreenInit; 263 pScrn->SwitchMode = LgSwitchMode; 264 pScrn->AdjustFrame = LgAdjustFrame; 265 pScrn->EnterVT = LgEnterVT; 266 pScrn->LeaveVT = LgLeaveVT; 267 pScrn->FreeScreen = LgFreeScreen; 268 pScrn->ValidMode = LgValidMode; 269 } 270 return pScrn; 271} 272 273static Bool 274LgGetRec(ScrnInfoPtr pScrn) 275{ 276 CirPtr pCir; 277 278 if (pScrn->driverPrivate != NULL) 279 return TRUE; 280 281 pScrn->driverPrivate = xnfcalloc(sizeof(CirRec), 1); 282 ((CirPtr) pScrn->driverPrivate)->chip.lg = 283 xnfcalloc(sizeof(LgRec), 1); 284 285 /* 286 * Initialize it. 287 */ 288 pCir = CIRPTR(pScrn); 289 pCir->chip.lg->oldBitmask = 0x00000000; 290 291 return TRUE; 292} 293 294static void 295LgFreeRec(ScrnInfoPtr pScrn) 296{ 297 if (pScrn->driverPrivate == NULL) 298 return; 299 free(pScrn->driverPrivate); 300 pScrn->driverPrivate = NULL; 301} 302 303/* 304 * LgCountRAM -- 305 * 306 * Counts amount of installed RAM 307 */ 308/* 309 * XXX We need to get rid of this PIO (MArk) 310 */ 311static int 312LgCountRam(ScrnInfoPtr pScrn) 313{ 314 vgaHWPtr hwp = VGAHWPTR(pScrn); 315 CARD8 SR14; 316 317 vgaHWProtect(pScrn, TRUE); 318 319 /* 320 * The ROM BIOS scratch pad registers contain, among other things, 321 * the amount of installed RDRAM for the Laguna chip. 322 */ 323 SR14 = hwp->readSeq(hwp, 0x14); 324 325 ErrorF("Scratch Pads: 0:%02x 1:%02x 2:%02x 3:%02x\n", 326 hwp->readSeq(hwp, 9), 327 hwp->readSeq(hwp, 10), 328 SR14, 329 hwp->readSeq(hwp, 0x15)); 330 331 vgaHWProtect(pScrn, FALSE); 332 333 return 1024 * ((SR14 & 0x7) + 1); 334 335 /* 336 * !!! This function seems to be incorrect... 337 */ 338} 339 340static xf86MonPtr 341LgDoDDC(ScrnInfoPtr pScrn) 342{ 343 CirPtr pCir = CIRPTR(pScrn); 344 xf86MonPtr MonInfo = NULL; 345 346 /* 347 * Map the CIR memory and MMIO areas. 348 */ 349 if (!CirMapMem(pCir, pScrn->scrnIndex)) 350 return FALSE; 351 352 if (!LgI2CInit(pScrn)) { 353 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 354 "I2C initialization failed\n"); 355 goto unmap_out; 356 } 357 358 /* 359 * Read and output monitor info using DDC2 over I2C bus. 360 */ 361 MonInfo = xf86DoEDID_DDC2(XF86_SCRN_ARG(pScrn), pCir->I2CPtr1); 362 if (!MonInfo) { 363 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 364 "Failed to obtain EDID.\n"); 365 goto unmap_out; 366 } 367 368 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 369 "I2C Monitor info: %p\n", (void *)MonInfo); 370 xf86PrintEDID(MonInfo); 371 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 372 "end of I2C Monitor info\n\n"); 373 374 xf86SetDDCproperties(pScrn, MonInfo); 375 376unmap_out: 377 CirUnmapMem(pCir, pScrn->scrnIndex); 378 379 return MonInfo; 380} 381 382/* 383 * Mandatory 384 */ 385Bool 386LgPreInit(ScrnInfoPtr pScrn, int flags) 387{ 388 CirPtr pCir; 389 vgaHWPtr hwp; 390 MessageType from; 391 int i; 392 ClockRangePtr clockRanges; 393 int fbPCIReg, ioPCIReg; 394 const char *s; 395 396 if (flags & PROBE_DETECT) { 397 cirProbeDDC(pScrn, 398 xf86GetEntityInfo(pScrn->entityList[0])->index); 399 return TRUE; 400 } 401 402#ifdef LG_DEBUG 403 ErrorF("LgPreInit\n"); 404#endif 405 406 /* 407 * Check the number of entities, and fail if it isn't one. 408 */ 409 if (pScrn->numEntities != 1) 410 return FALSE; 411 412 /* 413 * The vgahw module should be loaded here when needed. 414 */ 415 if (!xf86LoadSubModule(pScrn, "vgahw")) 416 return FALSE; 417 418 /* 419 * Allocate a vgaHWRec. 420 */ 421 if (!vgaHWGetHWRec(pScrn)) 422 return FALSE; 423 424 hwp = VGAHWPTR(pScrn); 425 vgaHWSetStdFuncs(hwp); 426 vgaHWGetIOBase(hwp); 427 428 /* 429 * Allocate the LgRec driverPrivate. 430 */ 431 if (!LgGetRec(pScrn)) 432 return FALSE; 433 434 pCir = CIRPTR(pScrn); 435 pCir->pScrn = pScrn; 436 437#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12 438 pCir->PIOReg = hwp->PIOOffset + 0x3CE; 439#else 440 pCir->PIOReg = 0x3CE; 441#endif 442 443 /* 444 * Get the entity, and make sure it is PCI. 445 */ 446 pCir->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 447 if (pCir->pEnt->location.type != BUS_PCI) 448 return FALSE; 449 pCir->Chipset = pCir->pEnt->chipset; 450 451 /* 452 * Find the PCI info for this screen. 453 */ 454 pCir->PciInfo = xf86GetPciInfoForEntity(pCir->pEnt->index); 455#ifndef XSERVER_LIBPCIACCESS 456 pCir->PciTag = pciTag(PCI_DEV_BUS(pCir->PciInfo), 457 PCI_DEV_DEV(pCir->PciInfo), PCI_DEV_FUNC(pCir->PciInfo)); 458#endif 459 460 if (xf86LoadSubModule(pScrn, "int10")) { 461 xf86Int10InfoPtr int10InfoPtr; 462 463 int10InfoPtr = xf86InitInt10(pCir->pEnt->index); 464 465 if (int10InfoPtr) 466 xf86FreeInt10(int10InfoPtr); 467 } 468 469 /* 470 * Set pScrn->monitor. 471 */ 472 pScrn->monitor = pScrn->confScreen->monitor; 473 474 /* 475 * The first thing we should figure out is the depth, bpp, etc. 476 * We support both 24 bpp and 32 bpp layouts, so indicate that. 477 */ 478 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | 479 Support32bppFb | 480 SupportConvert32to24 | 481 PreferConvert32to24)) { 482 return FALSE; 483 } 484 /* 485 * Check that the returned depth is one we support. 486 */ 487 switch (pScrn->depth) { 488 case 8: 489 case 15: 490 case 16: 491 case 24: 492 case 32: 493 /* 494 * OK 495 */ 496 break; 497 default: 498 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 499 "Given depth (%d) is not supported by this " 500 "driver\n", pScrn->depth); 501 return FALSE; 502 } 503 xf86PrintDepthBpp(pScrn); 504 505 /* 506 * Get the depth24 pixmap format. 507 */ 508 if (pScrn->depth == 24 && pix24bpp == 0) 509 pix24bpp = xf86GetBppFromDepth(pScrn, 24); 510 511 /* 512 * This must happen after pScrn->display has been set because 513 * xf86SetWeight references it. 514 */ 515 if (pScrn->depth > 8) { 516 /* 517 * The defaults are OK for us. 518 */ 519 rgb zeros = { 0, 0, 0 }; 520 521 /* 522 * !!! I think we can force 5-6-5 weight for 16bpp here for 523 * the 5462. 524 */ 525 526 if (!xf86SetWeight(pScrn, zeros, zeros)) { 527 return FALSE; 528 } else { 529 /* 530 * XXX Check that weight returned is supported. 531 */ 532 ; 533 } 534 } 535 536 if (!xf86SetDefaultVisual(pScrn, -1)) 537 return FALSE; 538 539 /* 540 * Collect all of the relevant option flags (fill in 541 * pScrn->options). 542 */ 543 xf86CollectOptions(pScrn, NULL); 544 545 /* 546 * Process the options. 547 */ 548 if (!(pCir->Options = malloc(sizeof(LgOptions)))) 549 return FALSE; 550 memcpy(pCir->Options, LgOptions, sizeof(LgOptions)); 551 xf86ProcessOptions(pScrn->scrnIndex, 552 pScrn->options, 553 pCir->Options); 554 555 pScrn->rgbBits = 6; 556 from = X_DEFAULT; 557 pCir->HWCursor = FALSE; 558 if (xf86GetOptValBool(pCir->Options, OPTION_HW_CURSOR, 559 &pCir->HWCursor)) 560 from = X_CONFIG; 561 562 xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 563 pCir->HWCursor ? "HW" : "SW"); 564 if (xf86ReturnOptValBool(pCir->Options, OPTION_NOACCEL, FALSE)) { 565 pCir->NoAccel = TRUE; 566 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 567 "Acceleration disabled\n"); 568 } 569 if (pScrn->bitsPerPixel < 8) { 570 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 571 "Cannot use in less than 8 bpp\n"); 572 return FALSE; 573 } 574 /* 575 * Set the ChipRev, allowing config file entries to override. 576 */ 577 if (pCir->pEnt->device->chipRev >= 0) { 578 pCir->ChipRev = pCir->pEnt->device->chipRev; 579 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 580 "ChipRev override: %d\n", pCir->ChipRev); 581 } else { 582 pCir->ChipRev = PCI_DEV_REVISION(pCir->PciInfo); 583 } 584 585 /* 586 * Cirrus Logic swapped the FB and IO registers in the 5465 587 * (by design). 588 */ 589 if (PCI_CHIP_GD5465 == pCir->Chipset) { 590 fbPCIReg = 0; 591 ioPCIReg = 1; 592 } else { 593 fbPCIReg = 1; 594 ioPCIReg = 0; 595 } 596 597 /* 598 * Find the frame buffer base address. 599 */ 600 if (pCir->pEnt->device->MemBase != 0) { 601 /* 602 * Require that the config file value matches one of the PCI 603 * values. 604 */ 605 if (!xf86CheckPciMemBase(pCir->PciInfo, 606 pCir->pEnt->device->MemBase)) { 607 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 608 "MemBase 0x%08lX doesn't match any PCI base " 609 "register.\n", 610 pCir->pEnt->device->MemBase); 611 return FALSE; 612 } 613 pCir->FbAddress = pCir->pEnt->device->MemBase; 614 from = X_CONFIG; 615 } else { 616 if (PCI_REGION_BASE(pCir->PciInfo, 617 fbPCIReg, 618 REGION_MEM) != 0) { 619 pCir->FbAddress = PCI_REGION_BASE(pCir->PciInfo, 620 fbPCIReg, 621 REGION_MEM) & 622 0xff000000; 623 from = X_PROBED; 624 } else { 625 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 626 "No valid FB address in PCI config space\n"); 627 LgFreeRec(pScrn); 628 return FALSE; 629 } 630 } 631 xf86DrvMsg(pScrn->scrnIndex, from, 632 "Linear framebuffer at 0x%lX\n", 633 (unsigned long) pCir->FbAddress); 634 635 /* 636 * Find the MMIO base address. 637 */ 638 if (pCir->pEnt->device->IOBase != 0) { 639 /* 640 * Require that the config file value matches one of the PCI 641 * values. 642 */ 643 if (!xf86CheckPciMemBase(pCir->PciInfo, 644 pCir->pEnt->device->IOBase)) { 645 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 646 "IOBase 0x%08lX doesn't match any PCI base " 647 "register.\n", 648 pCir->pEnt->device->IOBase); 649 return FALSE; 650 } 651 pCir->IOAddress = pCir->pEnt->device->IOBase; 652 from = X_CONFIG; 653 } else { 654 if (PCI_REGION_BASE(pCir->PciInfo, 655 ioPCIReg, 656 REGION_MEM) != 0) { 657 pCir->IOAddress = PCI_REGION_BASE(pCir->PciInfo, 658 ioPCIReg, 659 REGION_MEM) & 660 0xfffff000; 661 from = X_PROBED; 662 } else { 663 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 664 "No valid MMIO address in PCI config " 665 "space\n"); 666 } 667 } 668 xf86DrvMsg(pScrn->scrnIndex, from, 669 "MMIO registers at 0x%lX\n", 670 (unsigned long) pCir->IOAddress); 671 672 /* 673 * If the user has specified the amount of memory in the 674 * XF86Config file, we respect that setting. 675 */ 676 if (pCir->pEnt->device->videoRam != 0) { 677 pScrn->videoRam = pCir->pEnt->device->videoRam; 678 from = X_CONFIG; 679 } else { 680 pScrn->videoRam = LgCountRam(pScrn); 681 from = X_PROBED; 682 } 683 if (2048 == pScrn->videoRam) { 684 /* 685 * Two-way interleaving 686 */ 687 pCir->chip.lg->memInterleave = 0x40; 688 } else if (4096 == pScrn->videoRam || 8192 == pScrn->videoRam) { 689 /* 690 * Four-way interleaving 691 */ 692 pCir->chip.lg->memInterleave = 0x80; 693 } else { 694 /* 695 * One-way interleaving 696 */ 697 pCir->chip.lg->memInterleave = 0x00; 698 } 699 700 xf86DrvMsg(pScrn->scrnIndex, from, 701 "VideoRAM: %d kByte\n", pScrn->videoRam); 702 703 pCir->FbMapSize = pScrn->videoRam * 1024; 704 /* 705 * 16K for moment, will increase. 706 */ 707 pCir->IoMapSize = 0x4000; 708 709#ifndef XSERVER_LIBPCIACCESS 710 pScrn->racIoFlags = RAC_COLORMAP 711#ifndef EXPERIMENTAL 712 | RAC_VIEWPORT 713#endif 714 ; 715 xf86SetOperatingState(resVgaMem, pCir->pEnt->index, ResUnusedOpr); 716 717 /* 718 * Register the PCI-assigned resources. 719 */ 720 if (xf86RegisterResources(pCir->pEnt->index, NULL, ResExclusive)) { 721 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 722 "xf86RegisterResources() found resource " 723 "conflicts\n"); 724 return FALSE; 725 } 726#endif 727 if (!xf86LoadSubModule(pScrn, "ddc")) { 728 LgFreeRec(pScrn); 729 return FALSE; 730 } 731 732#if LGuseI2C 733 if (!xf86LoadSubModule(pScrn, "i2c")) { 734 LgFreeRec(pScrn); 735 return FALSE; 736 } 737#endif 738 739 /* 740 * Read and print the monitor DDC information. 741 */ 742 pScrn->monitor->DDC = LgDoDDC(pScrn); 743 744 /* 745 * The gamma fields must be initialised when using the new cmap 746 * code. 747 */ 748 if (pScrn->depth > 1) { 749 Gamma zeros = { 0.0, 0.0, 0.0 }; 750 751 if (!xf86SetGamma(pScrn, zeros)) 752 return FALSE; 753 } 754 if (xf86GetOptValBool(pCir->Options, 755 OPTION_SHADOW_FB, 756 &pCir->shadowFB)) 757 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 758 "ShadowFB %s.\n", 759 pCir->shadowFB ? "enabled" : "disabled"); 760 761 if ((s = xf86GetOptValString(pCir->Options, OPTION_ROTATE))) { 762 if (!xf86NameCmp(s, "CW")) { 763 /* 764 * Acceleration is disabled below for shadowfb. 765 */ 766 pCir->shadowFB = TRUE; 767 pCir->rotate = 1; 768 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 769 "Rotating screen clockwise - " 770 "acceleration disabled\n"); 771 } else if (!xf86NameCmp(s, "CCW")) { 772 pCir->shadowFB = TRUE; 773 pCir->rotate = -1; 774 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 775 "Rotating screen counter clockwise - " 776 "acceleration disabled\n"); 777 } else { 778 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 779 "\"%s\" is not a valid value for Option " 780 "\"Rotate\"\n", s); 781 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 782 "Valid options are \"CW\" or \"CCW\"\n"); 783 } 784 } 785 786 if (pCir->shadowFB && !pCir->NoAccel) { 787 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 788 "HW acceleration not supported with " 789 "\"shadowFB\".\n"); 790 pCir->NoAccel = TRUE; 791 } 792 793 if (pCir->rotate && pCir->HWCursor) { 794 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 795 "HW cursor not supported with \"rotate\".\n"); 796 pCir->HWCursor = FALSE; 797 } 798 799 /* 800 * We use a programmable clock. 801 */ 802 pScrn->progClock = TRUE; 803 804 /* 805 * XXX Set HW cursor use. 806 */ 807 808 /* 809 * Set the min pixel clock. 810 */ 811 /* 812 * XXX Guess, need to check this. 813 */ 814 pCir->MinClock = 12000; 815 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, 816 "Min pixel clock is %d MHz\n", 817 pCir->MinClock / 1000); 818 /* 819 * If the user has specified RAMDAC speed in the XF86Config 820 * file, we respect that setting. 821 */ 822 if (pCir->pEnt->device->dacSpeeds[0]) { 823 ErrorF("Do not specify a Clocks line for Cirrus chips\n"); 824 return FALSE; 825 } else { 826 int speed; 827 int *p; 828 switch (pCir->Chipset) { 829 case PCI_CHIP_GD5462: 830 p = gd5462_MaxClocks; 831 break; 832 case PCI_CHIP_GD5464: 833 case PCI_CHIP_GD5464BD: 834 p = gd5464_MaxClocks; 835 break; 836 case PCI_CHIP_GD5465: 837 p = gd5465_MaxClocks; 838 break; 839 default: 840 ErrorF("???\n"); 841 return FALSE; 842 } 843 switch (pScrn->bitsPerPixel) { 844 case 8: 845 speed = p[1]; 846 break; 847 case 15: 848 case 16: 849 speed = p[2]; 850 break; 851 case 24: 852 speed = p[3]; 853 break; 854 case 32: 855 speed = p[4]; 856 break; 857 default: 858 /* 859 * Should not get here. 860 */ 861 speed = 0; 862 break; 863 } 864 pCir->MaxClock = speed; 865 from = X_PROBED; 866 } 867 xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", 868 pCir->MaxClock / 1000); 869 870 /* 871 * Setup the ClockRanges, which describe what clock ranges are 872 * available, and what sort of modes they can be used for. 873 */ 874 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 875 clockRanges->next = NULL; 876 clockRanges->minClock = pCir->MinClock; 877 clockRanges->maxClock = pCir->MaxClock; 878 /* 879 * programmable 880 */ 881 clockRanges->clockIndex = -1; 882 /* 883 * XXX Check this. 884 */ 885 clockRanges->interlaceAllowed = FALSE; 886 /* 887 * XXX Check this. 888 */ 889 clockRanges->doubleScanAllowed = FALSE; 890 /* 891 * XXX Check this. 892 */ 893 clockRanges->doubleScanAllowed = FALSE; 894 /* 895 * XXX Check this. 896 */ 897 clockRanges->doubleScanAllowed = FALSE; 898 clockRanges->ClockMulFactor = 1; 899 clockRanges->ClockDivFactor = 1; 900 clockRanges->PrivFlags = 0; 901 902 /* 903 * Depending upon what sized tiles used, either 128 or 256. 904 */ 905 /* 906 * Aw, heck. Just say 128. 907 */ 908 pCir->Rounding = 128 >> pCir->BppShift; 909 910 /* 911 * xf86ValidateModes will check that the mode HTotal and VTotal 912 * values don't exceed the chipset's limit if pScrn->maxHValue 913 * and pScrn->maxVValue are set. Since our CIRValidMode() 914 * already takes care of this, we don't worry about setting them 915 * here. 916 */ 917 918 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 919 pScrn->display->modes, clockRanges, 920 LgLinePitches[pScrn->bitsPerPixel / 8 - 1], 921 0, 0, 922 128 * 8, 0, 923 /* 924 * Any virtual height is allowed. 925 */ 926 0, 927 pScrn->display->virtualX, 928 pScrn->display->virtualY, 929 pCir->FbMapSize, LOOKUP_BEST_REFRESH); 930 931 pCir->chip.lg->lineDataIndex = 932 LgFindLineData(pScrn->displayWidth, 933 pScrn->bitsPerPixel); 934 935 if (i == -1) { 936 LgFreeRec(pScrn); 937 return FALSE; 938 } 939 940 /* 941 * Prune the modes marked as invalid. 942 */ 943 xf86PruneDriverModes(pScrn); 944 945 if (i == 0 || pScrn->modes == NULL) { 946 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 947 "No valid modes found\n"); 948 LgFreeRec(pScrn); 949 return FALSE; 950 } 951 952 /* 953 * Set the CRTC parameters for all of the modes based on the type 954 * of mode, and the chipset's interlace requirements. Calling 955 * this is required if the mode->Crtc* values are used by the 956 * driver and if the driver doesn't provide code to set 957 * them. They are not pre-initialised at all. 958 */ 959 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 960 961 /* 962 * Set the current mode to the first in the list. 963 */ 964 pScrn->currentMode = pScrn->modes; 965 966 /* 967 * Print the list of modes being used. 968 */ 969 xf86PrintModes(pScrn); 970 971 /* 972 * Set display resolution. 973 */ 974 xf86SetDpi(pScrn, 0, 0); 975 976 /* 977 * Load bpp-specific modules. 978 */ 979 switch (pScrn->bitsPerPixel) { 980 case 8: 981 case 16: 982 case 24: 983 case 32: 984 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 985 LgFreeRec(pScrn); 986 return FALSE; 987 } 988 break; 989 } 990 991 /* 992 * Load XAA if needed. 993 */ 994 if (!pCir->NoAccel) { 995#ifdef HAVE_XAA_H 996 if (!xf86LoadSubModule(pScrn, "xaa")) 997#else 998 if (1) 999#endif 1000 { 1001 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1002 "Falling back to shadowfb\n"); 1003 pCir->NoAccel = TRUE; 1004 pCir->shadowFB = TRUE; 1005 } 1006 } 1007 1008 /* 1009 * Load RAMDAC if needed. 1010 */ 1011 if (pCir->HWCursor) { 1012 if (!xf86LoadSubModule(pScrn, "ramdac")) { 1013 LgFreeRec(pScrn); 1014 return FALSE; 1015 } 1016 } 1017 1018 if (pCir->shadowFB) { 1019 if (!xf86LoadSubModule(pScrn, "shadowfb")) { 1020 LgFreeRec(pScrn); 1021 return FALSE; 1022 } 1023 } 1024 1025 return TRUE; 1026} 1027 1028/* 1029 * This function saves the video state. 1030 */ 1031static void 1032LgSave(ScrnInfoPtr pScrn) 1033{ 1034 CirPtr pCir = CIRPTR(pScrn); 1035 vgaHWPtr hwp = VGAHWPTR(pScrn); 1036 1037#ifdef LG_DEBUG 1038 ErrorF("LgSave\n"); 1039#endif 1040 1041 vgaHWSave(pScrn, &VGAHWPTR(pScrn)->SavedReg, VGA_SR_ALL); 1042 1043 pCir->chip.lg->ModeReg.ExtVga[CR1A] = 1044 pCir->chip.lg->SavedReg.ExtVga[CR1A] = hwp->readCrtc(hwp, 0x1A); 1045 pCir->chip.lg->ModeReg.ExtVga[CR1B] = 1046 pCir->chip.lg->SavedReg.ExtVga[CR1B] = hwp->readCrtc(hwp, 0x1B); 1047 pCir->chip.lg->ModeReg.ExtVga[CR1D] = 1048 pCir->chip.lg->SavedReg.ExtVga[CR1D] = hwp->readCrtc(hwp, 0x1D); 1049 pCir->chip.lg->ModeReg.ExtVga[CR1E] = 1050 pCir->chip.lg->SavedReg.ExtVga[CR1E] = hwp->readCrtc(hwp, 0x1E); 1051 pCir->chip.lg->ModeReg.ExtVga[SR07] = 1052 pCir->chip.lg->SavedReg.ExtVga[SR07] = hwp->readSeq(hwp, 0x07); 1053 pCir->chip.lg->ModeReg.ExtVga[SR0E] = 1054 pCir->chip.lg->SavedReg.ExtVga[SR0E] = hwp->readSeq(hwp, 0x0E); 1055 pCir->chip.lg->ModeReg.ExtVga[SR1E] = 1056 pCir->chip.lg->SavedReg.ExtVga[SR1E] = hwp->readSeq(hwp, 0x1E); 1057 1058 pCir->chip.lg->ModeReg.FORMAT = 1059 pCir->chip.lg->SavedReg.FORMAT = memrw(0xC0); 1060 1061 pCir->chip.lg->ModeReg.VSC = 1062 pCir->chip.lg->SavedReg.VSC = memrl(0x3FC); 1063 1064 pCir->chip.lg->ModeReg.DTTC = 1065 pCir->chip.lg->SavedReg.DTTC = memrw(0xEA); 1066 1067 if (pCir->Chipset == PCI_CHIP_GD5465) { 1068 pCir->chip.lg->ModeReg.TileCtrl = 1069 pCir->chip.lg->SavedReg.TileCtrl = memrw(0x2C4); 1070 } 1071 1072 pCir->chip.lg->ModeReg.TILE = 1073 pCir->chip.lg->SavedReg.TILE = memrb(0x407); 1074 1075 if (pCir->Chipset == PCI_CHIP_GD5465) 1076 pCir->chip.lg->ModeReg.BCLK = 1077 pCir->chip.lg->SavedReg.BCLK = memrb(0x2C0); 1078 else 1079 pCir->chip.lg->ModeReg.BCLK = 1080 pCir->chip.lg->SavedReg.BCLK = memrb(0x8C); 1081 1082 pCir->chip.lg->ModeReg.CONTROL = 1083 pCir->chip.lg->SavedReg.CONTROL = memrw(0x402); 1084 1085 pCir->chip.lg->ModeReg.RIFCtrl = 1086 pCir->chip.lg->SavedReg.RIFCtrl = memrw(0x200); 1087 1088 pCir->chip.lg->ModeReg.RACCtrl = 1089 pCir->chip.lg->SavedReg.RACCtrl = memrw(0x202); 1090} 1091 1092/* 1093 * Initialise a new mode. This is currently still using the old 1094 * "initialise struct, restore/write struct to HW" model. That could 1095 * be changed. 1096 */ 1097static Bool 1098LgModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 1099{ 1100 vgaHWPtr hwp; 1101 CirPtr pCir; 1102 int width; 1103 Bool VDiv2 = FALSE; 1104 CARD16 clockData; 1105 LgLineDataPtr lineData; 1106 1107#ifdef LG_DEBUG 1108 ErrorF("LgModeInit %d bpp, %d %d %d %d %d %d %d %d %d\n", 1109 pScrn->bitsPerPixel, mode->Clock, 1110 mode->HDisplay, mode->HSyncStart, 1111 mode->HSyncEnd, mode->HTotal, 1112 mode->VDisplay, mode->VSyncStart, 1113 mode->VSyncEnd, mode->VTotal); 1114 1115 ErrorF("LgModeInit: depth %d bits\n", pScrn->depth); 1116#endif 1117 1118 pCir = CIRPTR(pScrn); 1119 hwp = VGAHWPTR(pScrn); 1120 vgaHWUnlock(hwp); 1121 1122 if (mode->VTotal >= 1024 && !(mode->Flags & V_INTERLACE)) { 1123 /* 1124 * For non-interlaced vertical timing >= 1024, the vertical 1125 * timings are divided by 2 and VGA CRTC 0x17 bit 2 is set. 1126 */ 1127 if (!mode->CrtcVAdjusted) { 1128 mode->CrtcVDisplay >>= 1; 1129 mode->CrtcVSyncStart >>= 1; 1130 mode->CrtcVSyncEnd >>= 1; 1131 mode->CrtcVTotal >>= 1; 1132 mode->CrtcVAdjusted = TRUE; 1133 } 1134 VDiv2 = TRUE; 1135 } 1136 1137 /* 1138 * Initialise the ModeReg values. 1139 */ 1140 if (!vgaHWInit(pScrn, mode)) 1141 return FALSE; 1142 pScrn->vtSema = TRUE; 1143 1144 if (VDiv2) 1145 hwp->ModeReg.CRTC[0x17] |= 0x04; 1146 1147#ifdef LG_DEBUG 1148 ErrorF("SynthClock = %d\n", mode->SynthClock); 1149#endif 1150 hwp->IOBase = 0x3D0; 1151 hwp->ModeReg.MiscOutReg |= 0x01; 1152/* 1153 * Mono address 1154 */ 1155#if 0 1156 hwp->IOBase = 0x3B0; 1157 hwp->ModeReg.MiscOutReg &= ~0x01; 1158#endif 1159 1160 /* 1161 * ??? Should these be both ...End or ...Start, not one of each? 1162 */ 1163 pCir->chip.lg->ModeReg.ExtVga[CR1A] = 1164 (((mode->CrtcVSyncStart + 1) & 0x300) >> 2) | 1165 (((mode->CrtcHSyncEnd >> 3) & 0xC0) >> 2); 1166 1167 width = pScrn->displayWidth * pScrn->bitsPerPixel / 8; 1168 if (pScrn->bitsPerPixel == 1) 1169 width <<= 2; 1170 hwp->ModeReg.CRTC[0x13] = (width + 7) >> 3; 1171 /* 1172 * Offset extension (see CR13) 1173 */ 1174 pCir->chip.lg->ModeReg.ExtVga[CR1B] &= 0xEF; 1175 pCir->chip.lg->ModeReg.ExtVga[CR1B] |= 1176 (((width + 7) >> 3) & 0x100) ? 0x10 : 0x00; 1177 pCir->chip.lg->ModeReg.ExtVga[CR1B] |= 0x22; 1178 pCir->chip.lg->ModeReg.ExtVga[CR1D] = 1179 (((width + 7) >> 3) & 0x200) ? 0x01 : 0x00; 1180 1181 /* 1182 * Set the 28th bit to enable extended modes. 1183 */ 1184 pCir->chip.lg->ModeReg.VSC = 0x10000000; 1185 1186 /* 1187 * Overflow register (sure are a lot of overflow bits around...) 1188 */ 1189 pCir->chip.lg->ModeReg.ExtVga[CR1E] = 0x00; 1190 pCir->chip.lg->ModeReg.ExtVga[CR1E] |= ( 1191 (mode->CrtcHTotal >> 3 & 0x0100) ? 1 : 0) << 7; 1192 pCir->chip.lg->ModeReg.ExtVga[CR1E] |= ( 1193 (mode->CrtcHDisplay >> 3 & 0x0100) ? 1 : 0) << 6; 1194 pCir->chip.lg->ModeReg.ExtVga[CR1E] |= ( 1195 (mode->CrtcHSyncStart >> 3 & 0x0100) ? 1 : 0) << 5; 1196 pCir->chip.lg->ModeReg.ExtVga[CR1E] |= ( 1197 (mode->CrtcHSyncStart >> 3 & 0x0100) ? 1 : 0) << 4; 1198 pCir->chip.lg->ModeReg.ExtVga[CR1E] |= 1199 ((mode->CrtcVTotal & 0x0400) ? 1 : 0) << 3; 1200 pCir->chip.lg->ModeReg.ExtVga[CR1E] |= ( 1201 (mode->CrtcVDisplay & 0x0400) ? 1 : 0) << 2; 1202 pCir->chip.lg->ModeReg.ExtVga[CR1E] |= ( 1203 (mode->CrtcVSyncStart & 0x0400) ? 1 : 0) << 1; 1204 pCir->chip.lg->ModeReg.ExtVga[CR1E] |= ( 1205 (mode->CrtcVSyncStart & 0x0400) ? 1 : 0) << 0; 1206 1207 lineData = &LgLineData[pCir->chip.lg->lineDataIndex]; 1208 1209 pCir->chip.lg->ModeReg.TILE = lineData->tilesPerLine & 0x3F; 1210 1211 if (8 == pScrn->bitsPerPixel) { 1212 pCir->chip.lg->ModeReg.FORMAT = 0x0000; 1213 1214 pCir->chip.lg->ModeReg.DTTC = 1215 (pCir->chip.lg->ModeReg.TILE << 8) | 1216 0x0080 | 1217 (lineData->width << 6); 1218 pCir->chip.lg->ModeReg.CONTROL = 0x0000 | 1219 (lineData->width << 11); 1220 1221 /* 1222 * There is an optimal FIFO threshold value (lower 1223 * 5 bits of DTTC) for every resolution and color depth 1224 * combination. We'll hit the highlights here, and get 1225 * close for anything that's not covered. 1226 */ 1227 if (mode->CrtcHDisplay <= 640) { 1228 /* 1229 * BAD numbers: 0x1E 1230 * GOOD numbers: 0x14 1231 */ 1232 pCir->chip.lg->ModeReg.DTTC = 1233 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1234 (0x0014); 1235 } else if (mode->CrtcHDisplay <= 800) { 1236 /* 1237 * BAD numbers: 0x16 1238 * GOOD numbers: 0x13 0x14 1239 */ 1240 pCir->chip.lg->ModeReg.DTTC = 1241 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1242 (0x0014); 1243 } else if (mode->CrtcHDisplay <= 1024) { 1244 /* 1245 * BAD numbers: 1246 * GOOD numbers: 0x15 1247 */ 1248 pCir->chip.lg->ModeReg.DTTC = 1249 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1250 (0x0015); 1251 } else if (mode->CrtcHDisplay <= 1280) { 1252 /* 1253 * BAD numbers: 1254 * GOOD numbers: 0x16 1255 */ 1256 pCir->chip.lg->ModeReg.DTTC = 1257 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1258 (0x0016); 1259 } else { 1260 /* 1261 * BAD numbers: 1262 * GOOD numbers: 1263 */ 1264 pCir->chip.lg->ModeReg.DTTC = 1265 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1266 (0x0017); 1267 } 1268 } else if (16 == pScrn->bitsPerPixel) { 1269 /* 1270 * !!! Assume 5-6-5 RGB mode (for now...). 1271 */ 1272 pCir->chip.lg->ModeReg.FORMAT = 0x1400; 1273 1274 if (pScrn->depth == 15) 1275 pCir->chip.lg->ModeReg.FORMAT = 0x1600; 1276 1277 pCir->chip.lg->ModeReg.DTTC = 1278 (pCir->chip.lg->ModeReg.TILE << 8) | 1279 0x0080 | 1280 (lineData->width << 6); 1281 pCir->chip.lg->ModeReg.CONTROL = 0x2000 | 1282 (lineData->width << 11); 1283 1284 if (mode->CrtcHDisplay <= 640) { 1285 /* 1286 * BAD numbers: 0x12 1287 * GOOD numbers: 0x10 1288 */ 1289 pCir->chip.lg->ModeReg.DTTC = 1290 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1291 (0x0010); 1292 } else if (mode->CrtcHDisplay <= 800) { 1293 /* 1294 * BAD numbers: 0x13 1295 * GOOD numbers: 0x11 1296 */ 1297 pCir->chip.lg->ModeReg.DTTC = 1298 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1299 (0x0011); 1300 } else if (mode->CrtcHDisplay <= 1024) { 1301 /* 1302 * BAD numbers: 0x14 1303 * GOOD numbers: 0x12 1304 */ 1305 pCir->chip.lg->ModeReg.DTTC = 1306 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1307 (0x0012); 1308 } else if (mode->CrtcHDisplay <= 1280) { 1309 /* 1310 * BAD numbers: 0x08 0x10 1311 * Borderline numbers: 0x12 1312 * GOOD numbers: 0x15 1313 */ 1314 pCir->chip.lg->ModeReg.DTTC = 1315 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1316 (0x0015); 1317 } else { 1318 pCir->chip.lg->ModeReg.DTTC = 1319 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1320 (0x0017); 1321 } 1322 } else if (24 == pScrn->bitsPerPixel) { 1323 pCir->chip.lg->ModeReg.FORMAT = 0x2400; 1324 1325 pCir->chip.lg->ModeReg.DTTC = 1326 (pCir->chip.lg->ModeReg.TILE << 8) | 1327 0x0080 | 1328 (lineData->width << 6); 1329 pCir->chip.lg->ModeReg.CONTROL = 0x4000 | 1330 (lineData->width << 11); 1331 1332 if (mode->CrtcHDisplay <= 640) { 1333 /* 1334 * BAD numbers: 1335 * GOOD numbers: 0x10 1336 */ 1337 pCir->chip.lg->ModeReg.DTTC = 1338 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1339 (0x0010); 1340 } else if (mode->CrtcHDisplay <= 800) { 1341 /* 1342 * BAD numbers: 1343 * GOOD numbers: 0x11 1344 */ 1345 pCir->chip.lg->ModeReg.DTTC = 1346 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1347 (0x0011); 1348 } else if (mode->CrtcHDisplay <= 1024) { 1349 /* 1350 * BAD numbers: 0x12 0x13 1351 * Borderline numbers: 0x15 1352 * GOOD numbers: 0x17 1353 */ 1354 pCir->chip.lg->ModeReg.DTTC = 1355 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1356 (0x0017); 1357 } else if (mode->CrtcHDisplay <= 1280) { 1358 /* 1359 * BAD numbers: 1360 * GOOD numbers: 0x1E 1361 */ 1362 pCir->chip.lg->ModeReg.DTTC = 1363 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1364 (0x001E); 1365 } else { 1366 /* 1367 * BAD numbers: 1368 * GOOD numbers: 1369 */ 1370 pCir->chip.lg->ModeReg.DTTC = 1371 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1372 (0x0020); 1373 } 1374 } else if (32 == pScrn->bitsPerPixel) { 1375 pCir->chip.lg->ModeReg.FORMAT = 0x3400; 1376 1377 pCir->chip.lg->ModeReg.DTTC = 1378 (pCir->chip.lg->ModeReg.TILE << 8) | 1379 0x0080 | 1380 (lineData->width << 6); 1381 pCir->chip.lg->ModeReg.CONTROL = 0x6000 | 1382 (lineData->width << 11); 1383 1384 if (mode->CrtcHDisplay <= 640) { 1385 /* 1386 * GOOD numbers: 0x0E 1387 * BAD numbers: 1388 */ 1389 pCir->chip.lg->ModeReg.DTTC = 1390 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1391 (0x000E); 1392 } else if (mode->CrtcHDisplay <= 800) { 1393 /* 1394 * GOOD numbers: 0x17 1395 * BAD numbers: 1396 */ 1397 pCir->chip.lg->ModeReg.DTTC = 1398 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1399 (0x0017); 1400 } else if (mode->CrtcHDisplay <= 1024) { 1401 /* 1402 * GOOD numbers: 0x1D 1403 * OKAY numbers: 0x15 0x14 0x16 0x18 0x19 1404 * BAD numbers: 0x0E 0x12 0x13 0x0D 1405 */ 1406 pCir->chip.lg->ModeReg.DTTC = 1407 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1408 (0x001D); 1409 } else if (mode->CrtcHDisplay <= 1280) { 1410 /* 1411 * GOOD numbers: 1412 * BAD numbers: 1413 */ 1414 /* 1415 * 10 1416 */ 1417 pCir->chip.lg->ModeReg.DTTC = 1418 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1419 (0x0022); 1420 } else { 1421 pCir->chip.lg->ModeReg.DTTC = 1422 (pCir->chip.lg->ModeReg.DTTC & 0xFFE0) | 1423 (0x0024); 1424 } 1425 } else { 1426 /* 1427 * ??? What could it be? Use some sane numbers. 1428 */ 1429 } 1430 1431 /* 1432 * Setup the appropriate memory interleaving. 1433 */ 1434 pCir->chip.lg->ModeReg.DTTC |= (pCir->chip.lg->memInterleave << 8); 1435 pCir->chip.lg->ModeReg.TILE |= pCir->chip.lg->memInterleave & 0xC0; 1436 1437 if (PCI_CHIP_GD5465 == pCir->Chipset) { 1438 /* 1439 * The tile control information in the DTTC is also mirrored 1440 * elsewhere. 1441 */ 1442 pCir->chip.lg->ModeReg.TileCtrl = 1443 pCir->chip.lg->ModeReg.DTTC & 0xFFC0; 1444 1445 /* 1446 * The 5465's DTTC records _fetches_ per line, not tiles per 1447 * line. Fetches are 128-byte fetches. 1448 */ 1449 if (pCir->chip.lg->ModeReg.DTTC & 0x0040) { 1450 /* 1451 * Using 256-byte wide tiles. Double the fetches per 1452 * line field. 1453 */ 1454 pCir->chip.lg->ModeReg.DTTC = 1455 (pCir->chip.lg->ModeReg.DTTC & 0xC0FF) | 1456 ((pCir->chip.lg->ModeReg.DTTC & 0x3F00) << 1); 1457 } 1458 } 1459 1460 /* 1461 * Programme the registers. 1462 */ 1463 vgaHWProtect(pScrn, TRUE); 1464 hwp->writeMiscOut(hwp, hwp->ModeReg.MiscOutReg); 1465 1466 clockData = LgSetClock(pCir, hwp, mode->SynthClock); 1467 pCir->chip.lg->ModeReg.ExtVga[SR0E] = (clockData >> 8) & 0xFF; 1468 pCir->chip.lg->ModeReg.ExtVga[SR1E] = clockData & 0xFF; 1469 1470 /* 1471 * Write those registers out to the card. 1472 */ 1473 LgRestoreLgRegs(pScrn, &pCir->chip.lg->ModeReg); 1474 1475 /* 1476 * Programme the registers. 1477 */ 1478 vgaHWRestore(pScrn, &hwp->ModeReg, VGA_SR_MODE | VGA_SR_CMAP); 1479 1480 vgaHWProtect(pScrn, FALSE); 1481 1482 return TRUE; 1483} 1484 1485static int 1486LgFindLineData(int displayWidth, int bpp) 1487{ 1488 /* 1489 * Find the smallest tile-line-pitch such that the total byte 1490 * pitch is greater than or equal to displayWidth * Bpp. 1491 */ 1492 int i; 1493 1494 /* 1495 * Some pitch sizes are duplicates in the table. BUT, the 1496 * invariant is that the _first_ time a pitch occurs in the table 1497 * is always _before_ all other pitches greater than it. Said in 1498 * another way... if all duplicate entries from the table were 1499 * removed, then the resulting pitch values are strictly 1500 * increasing. 1501 */ 1502 1503 for (i = 0; LgLineData[i].pitch > 0; i++) 1504 if (LgLineData[i].pitch >= displayWidth * bpp >> 3) 1505 return i; 1506 1507 /* 1508 * Um, uh oh! 1509 */ 1510 return -1; 1511} 1512 1513static void 1514LgRestoreLgRegs(ScrnInfoPtr pScrn, LgRegPtr lgReg) 1515{ 1516 CirPtr pCir; 1517 vgaHWPtr hwp; 1518 CARD8 cr1D; 1519 1520 pCir = CIRPTR(pScrn); 1521 1522 /* 1523 * First, VGAish registers. 1524 */ 1525 hwp = VGAHWPTR(pScrn); 1526 hwp->writeCrtc(hwp, 0x1A, lgReg->ExtVga[CR1A]); 1527 hwp->writeCrtc(hwp, 0x1B, lgReg->ExtVga[CR1B]); 1528 cr1D = (hwp->readCrtc(hwp, 0x1D) & ~1) | 1529 (lgReg->ExtVga[CR1D] & 0x01); 1530 hwp->writeCrtc(hwp, 0x1D, cr1D); 1531 hwp->writeCrtc(hwp, 0x1E, lgReg->ExtVga[CR1E]); 1532 1533 hwp->writeSeq(hwp, 0x07, lgReg->ExtVga[SR07]); 1534 hwp->writeSeq(hwp, 0x0E, lgReg->ExtVga[SR0E]); 1535 hwp->writeSeq(hwp, 0x1E, lgReg->ExtVga[SR1E]); 1536 memww(0xC0, lgReg->FORMAT); 1537 1538 /* 1539 * Vendor Specific Control is touchy. Only bit 28 is of concern. 1540 */ 1541 memwl(0x3FC, ((memrl(0x3FC) & ~(1 << 28)) | 1542 (lgReg->VSC & (1 << 28)))); 1543 1544 memww(0xEA, lgReg->DTTC); 1545 1546 if (pCir->Chipset == PCI_CHIP_GD5465) { 1547 memww(0x2C4, lgReg->TileCtrl); 1548 } 1549 1550 memwb(0x407, lgReg->TILE); 1551 1552 if (pCir->Chipset == PCI_CHIP_GD5465) 1553 memwb(0x2C0, lgReg->BCLK); 1554 else 1555 memwb(0x8C, lgReg->BCLK); 1556 1557 memww(0x402, lgReg->CONTROL); 1558 1559 memww(0x200, lgReg->RIFCtrl); 1560 memww(0x202, lgReg->RACCtrl); 1561} 1562 1563/* 1564 * Restore the initial (text) mode. 1565 */ 1566static void 1567LgRestore(ScrnInfoPtr pScrn) 1568{ 1569 vgaHWPtr hwp; 1570 vgaRegPtr vgaReg; 1571 CirPtr pCir; 1572 LgRegPtr lgReg; 1573 1574#ifdef LG_DEBUG 1575 ErrorF("LgRestore pScrn = %p\n", (void *) pScrn); 1576#endif 1577 1578 pCir = CIRPTR(pScrn); 1579 hwp = VGAHWPTR(pScrn); 1580 vgaReg = &hwp->SavedReg; 1581 lgReg = &pCir->chip.lg->SavedReg; 1582 1583 vgaHWProtect(pScrn, TRUE); 1584 1585 LgRestoreLgRegs(pScrn, lgReg); 1586 1587 vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); 1588 vgaHWProtect(pScrn, FALSE); 1589} 1590 1591/* 1592 * This gets called at the start of each server generation 1593 */ 1594/* 1595 * Mandatory 1596 */ 1597Bool 1598LgScreenInit(SCREEN_INIT_ARGS_DECL) 1599{ 1600 /* 1601 * The vgaHW references will disappear one day 1602 */ 1603 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1604 vgaHWPtr hwp; 1605 CirPtr pCir; 1606 int i, ret; 1607 VisualPtr visual; 1608 int displayWidth, width, height; 1609 unsigned char * FbBase = NULL; 1610 1611#ifdef LG_DEBUG 1612 ErrorF("LgScreenInit\n"); 1613#endif 1614 1615 hwp = VGAHWPTR(pScrn); 1616 1617 /* 1618 * Standard 64k VGA window 1619 */ 1620 hwp->MapSize = 0x10000; 1621 1622 pCir = CIRPTR(pScrn); 1623 1624 /* 1625 * Map the VGA memory and get the VGA IO base. 1626 */ 1627 if (!vgaHWMapMem(pScrn)) 1628 return FALSE; 1629 1630 /* 1631 * Map the CIR memory and MMIO areas. 1632 */ 1633 if (!CirMapMem(pCir, pScrn->scrnIndex)) 1634 return FALSE; 1635#ifdef EXPERIMENTAL 1636 lg_vgaHWSetMmioFunc(hwp, pCir->IOBase); 1637#endif 1638 vgaHWGetIOBase(hwp); 1639 1640 /* 1641 * Save the current state. 1642 */ 1643 LgSave(pScrn); 1644 1645 /* 1646 * Initialise the first mode. 1647 */ 1648 if (!LgModeInit(pScrn, pScrn->currentMode)) 1649 return FALSE; 1650 1651 /* 1652 * Make things beautiful. 1653 */ 1654 LgSaveScreen(pScreen, SCREEN_SAVER_ON); 1655 1656 /* 1657 * Set the viewport. 1658 */ 1659 LgAdjustFrame(ADJUST_FRAME_ARGS(pScrn, 1660 pScrn->frameX0, 1661 pScrn->frameY0)); 1662 1663 /* 1664 * The next step is to setup the screen's visuals, and initialise 1665 * the framebuffer code. In cases where the framebuffer's default 1666 * choices for things like visual layouts and bits per RGB are OK, 1667 * this may be as simple as calling the framebuffer's ScreenInit() 1668 * function. If not, the visuals will need to be setup before 1669 * calling a fb ScreenInit() function and fixed up after. 1670 */ 1671 1672 /* 1673 * Reset the visual list. 1674 */ 1675 miClearVisualTypes(); 1676 1677 /* 1678 * Setup the visuals we support. 1679 */ 1680 if (!miSetVisualTypes(pScrn->depth, 1681 miGetDefaultVisualMask(pScrn->depth), 1682 pScrn->rgbBits, 1683 pScrn->defaultVisual)) 1684 return FALSE; 1685 1686 miSetPixmapDepths(); 1687 1688#ifdef LG_DEBUG 1689 ErrorF("LgScreenInit after miSetVisualTypes\n"); 1690#endif 1691 displayWidth = pScrn->displayWidth; 1692 if (pCir->rotate) { 1693 height = pScrn->virtualX; 1694 width = pScrn->virtualY; 1695 } else { 1696 width = pScrn->virtualX; 1697 height = pScrn->virtualY; 1698 } 1699 1700 if (pCir->shadowFB) { 1701 pCir->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 1702 pCir->ShadowPtr = malloc(pCir->ShadowPitch * height); 1703 displayWidth = pCir->ShadowPitch / (pScrn->bitsPerPixel >> 3); 1704 FbBase = pCir->ShadowPtr; 1705 } else { 1706 pCir->ShadowPtr = NULL; 1707 FbBase = pCir->FbBase; 1708 } 1709 1710 /* 1711 * Call the framebuffer layer's ScreenInit function, and fill in 1712 * other pScreen fields. 1713 */ 1714 switch (pScrn->bitsPerPixel) { 1715 case 8: 1716 case 16: 1717 case 24: 1718 case 32: 1719 ret = fbScreenInit(pScreen, FbBase, width, height, 1720 pScrn->xDpi, pScrn->yDpi, 1721 displayWidth, pScrn->bitsPerPixel); 1722 break; 1723 default: 1724 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1725 "X11: Internal error: invalid bpp (%d) in " 1726 "LgScreenInit\n", 1727 pScrn->bitsPerPixel); 1728 ret = FALSE; 1729 break; 1730 } 1731 if (!ret) 1732 return FALSE; 1733 1734#ifdef LG_DEBUG 1735 ErrorF("LgScreenInit after depth dependent init\n"); 1736#endif 1737 1738 /* 1739 * Override the default mask/offset settings. 1740 */ 1741 if (pScrn->bitsPerPixel > 8) { 1742 for (i = 0; i < pScreen->numVisuals; i++) { 1743 visual = &pScreen->visuals[i]; 1744 if ((visual->class | DynamicClass) == DirectColor) { 1745 visual->offsetRed = pScrn->offset.red; 1746 visual->offsetGreen = pScrn->offset.green; 1747 visual->offsetBlue = pScrn->offset.blue; 1748 visual->redMask = pScrn->mask.red; 1749 visual->greenMask = pScrn->mask.green; 1750 visual->blueMask = pScrn->mask.blue; 1751 } 1752 } 1753 } 1754 1755 /* 1756 * Must be after RGB ordering fixed. 1757 */ 1758 1759 fbPictureInit(pScreen, 0, 0); 1760 1761 /* 1762 * Set initial black & white colourmap indices. 1763 */ 1764 xf86SetBlackWhitePixels(pScreen); 1765 1766#ifdef HAVE_XAA_H 1767 /* 1768 * Initialize XAA functions. 1769 */ 1770 if (!pCir->NoAccel) { 1771 if (!LgXAAInit(pScreen)) 1772 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1773 "Could not initialize XAA\n"); 1774 } 1775#endif 1776#if 1 1777 pCir->DGAModeInit = LgModeInit; 1778 if (!CirDGAInit(pScreen)) 1779 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1780 "DGA initialization failed\n"); 1781#endif 1782 xf86SetSilkenMouse(pScreen); 1783 1784 /* 1785 * Initialise cursor functions. 1786 */ 1787 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 1788 1789 /* 1790 * Initialize HW cursor layer. 1791 */ 1792 if (pCir->HWCursor) { 1793 if (!LgHWCursorInit(pScreen)) 1794 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1795 "Hardware cursor initialization failed\n"); 1796 } 1797 1798 /* 1799 * Initialise default colourmap. 1800 */ 1801 if (!miCreateDefColormap(pScreen)) 1802 return FALSE; 1803 1804 if (pScrn->bitsPerPixel > 1 && pScrn->bitsPerPixel <= 8) 1805 vgaHWHandleColormaps(pScreen); 1806 1807 xf86DPMSInit(pScreen, LgDisplayPowerManagementSet, 0); 1808 1809 pScrn->memPhysBase = pCir->FbAddress; 1810 pScrn->fbOffset = 0; 1811 1812 { 1813 XF86VideoAdaptorPtr *ptr; 1814 int n; 1815 1816 n = xf86XVListGenericAdaptors(pScrn, &ptr); 1817 if (n) 1818 xf86XVScreenInit(pScreen, ptr, n); 1819 } 1820 1821 /* 1822 * Wrap the CloseScreen vector and set SaveScreen. 1823 */ 1824 pScreen->SaveScreen = LgSaveScreen; 1825 pCir->CloseScreen = pScreen->CloseScreen; 1826 pScreen->CloseScreen = LgCloseScreen; 1827 1828 /* 1829 * Report any unused options (only for the first generation). 1830 */ 1831 if (serverGeneration == 1) 1832 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 1833 1834 /* 1835 * Done 1836 */ 1837 return TRUE; 1838} 1839 1840/* 1841 * Usually mandatory 1842 */ 1843Bool 1844LgSwitchMode(SWITCH_MODE_ARGS_DECL) 1845{ 1846 SCRN_INFO_PTR(arg); 1847 return LgModeInit(pScrn, mode); 1848} 1849 1850#define ROUND_DOWN(x, mod) (((x) / (mod)) * (mod)) 1851#define ROUND_UP(x, mod) ((((x) + (mod) - 1) / (mod)) * (mod)) 1852 1853/* 1854 * This function is used to initialize the Start Address - the first 1855 * displayed location in the video memory. 1856 */ 1857/* 1858 * Usually mandatory 1859 */ 1860void LgAdjustFrame(ADJUST_FRAME_ARGS_DECL) { 1861 SCRN_INFO_PTR(arg); 1862 int Base, tmp; 1863 CirPtr pCir = CIRPTR(pScrn); 1864 vgaHWPtr hwp = VGAHWPTR(pScrn); 1865 int cursorX, cursorY; 1866 int middleX, middleY; 1867 const LgLineDataPtr lineData = 1868 &LgLineData[pCir->chip.lg->lineDataIndex]; 1869 const int viewportXRes = 1870 (PCI_CHIP_GD5465 == pCir->Chipset) ? 1871 (24 == pScrn->bitsPerPixel ? 24 : 1) : 1872 (lineData->width ? 256 : 128) 1873 / (24 == pScrn->bitsPerPixel ? 1874 1 : (pScrn->bitsPerPixel >> 3)); 1875 const int viewportYRes = 1876 (PCI_CHIP_GD5465 == pCir->Chipset) ? 1877 1 : (24 == pScrn->bitsPerPixel ? 3 : 1); 1878 1879 /* 1880 * Where's the pointer? 1881 */ 1882 miPointerGetPosition(inputInfo.pointer, &cursorX, &cursorY); 1883 1884 /* 1885 * Where's the middle of the screen? We want to eventually know 1886 * which side of the screen the pointer is on. 1887 */ 1888 middleX = (pScrn->frameX1 + pScrn->frameX0) / 2; 1889 middleY = (pScrn->frameY1 + pScrn->frameY0) / 2; 1890 1891 if (cursorX < middleX) { 1892 /* 1893 * Pointer is on left side of screen. Round the frame value 1894 * down. 1895 */ 1896 pScrn->frameX0 = ROUND_DOWN(pScrn->frameX0, viewportXRes); 1897 } else { 1898 /* 1899 * Pointer is on right side of screen. Round the frame value 1900 * up. A side effect of this rounding up is that we might 1901 * expose a part of the screen that's actually on the far 1902 * /left/ of the frame buffer. That's because, although the 1903 * virtual desktop might be an integral number of tiles, the 1904 * display might not. We'll just live with this artifact. 1905 */ 1906 pScrn->frameX0 = ROUND_UP(pScrn->frameX0, viewportXRes); 1907 } 1908 pScrn->frameX1 = pScrn->frameX0 + 1909 pScrn->currentMode->HDisplay - 1; 1910 1911 if (cursorY < middleY) { 1912 pScrn->frameY0 = ROUND_DOWN(pScrn->frameY0, viewportYRes); 1913 } else { 1914 pScrn->frameY0 = ROUND_UP(pScrn->frameY0, viewportYRes); 1915 } 1916 pScrn->frameY1 = pScrn->frameY0 + 1917 pScrn->currentMode->VDisplay - 1; 1918 1919 if (x != pScrn->frameX0 || y != pScrn->frameY0) { 1920 /* 1921 * !!! 1922 */ 1923 /* 1924 * We moved the frame from where xf86SetViewport() placed 1925 * it. If we're using a SW cursor, that's okay -- the 1926 * pointer exists in the framebuffer, and those bits are 1927 * still all aligned. But if we're using a HW cursor, then 1928 * we need to re-align the pointer. Call SetCursorPosition() 1929 * with the appropriate new pointer values, adjusted to be 1930 * wrt the new frame. 1931 */ 1932 x = pScrn->frameX0; 1933 y = pScrn->frameY0; 1934 } 1935 1936 /* 1937 * ??? Will this work for 1bpp? 1938 */ 1939 Base = (y * lineData->pitch + (x * pScrn->bitsPerPixel / 8)) / 4; 1940 1941 if ((Base & ~0x000FFFFF) != 0) { 1942 /* 1943 * ??? 1944 */ 1945 ErrorF("X11: Internal error: LgAdjustFrame: cannot handle " 1946 "overflow\n"); 1947 return; 1948 } 1949 1950 hwp->writeCrtc(hwp, 0x0C, (Base >> 8) & 0xFF); 1951 hwp->writeCrtc(hwp, 0x0D, Base & 0xFF); 1952 tmp = hwp->readCrtc(hwp, 0x1B) & 0xF2; 1953 tmp |= (Base >> 16) & 0x01; 1954 tmp |= (Base >> 15) & 0x0C; 1955 hwp->writeCrtc(hwp, 0x1B, tmp); 1956 tmp = hwp->readCrtc(hwp, 0x1D) & 0xE7; 1957 tmp |= (Base >> 16) & 0x18; 1958 hwp->writeCrtc(hwp, 0x1D, tmp); 1959} 1960 1961/* 1962 * This is called when VT switching back to the X server. Its job is 1963 * to reinitialise the video mode. We may wish to unmap video/MMIO 1964 * memory too. 1965 */ 1966/* 1967 * Mandatory 1968 */ 1969Bool 1970LgEnterVT(VT_FUNC_ARGS_DECL) 1971{ 1972 SCRN_INFO_PTR(arg); 1973 CirPtr pCir = CIRPTR(pScrn); 1974#ifdef LG_DEBUG 1975 ErrorF("LgEnterVT\n"); 1976#endif 1977 1978 /* 1979 * XXX Shouldn't this be in LeaveVT? 1980 */ 1981 /* 1982 * Disable HW cursor. 1983 */ 1984 if (pCir->HWCursor) 1985 LgHideCursor(pScrn); 1986 1987 /* 1988 * Should we re-save the text mode on each VT enter? 1989 */ 1990 return LgModeInit(pScrn, pScrn->currentMode); 1991} 1992 1993/* 1994 * This is called when VT switching away from the X server. Its job 1995 * is to restore the previous (text) mode. We may wish to remap 1996 * video/MMIO memory too. 1997 */ 1998/* 1999 * Mandatory 2000 */ 2001void LgLeaveVT(VT_FUNC_ARGS_DECL) { 2002 SCRN_INFO_PTR(arg); 2003 vgaHWPtr hwp = VGAHWPTR(pScrn); 2004 CirPtr pCir = CIRPTR(pScrn); 2005#ifdef LG_DEBUG 2006 ErrorF("LgLeaveVT\n"); 2007#endif 2008 2009 /* 2010 * XXX Shouldn't this be in EnterVT? 2011 */ 2012 /* 2013 * Enable HW cursor. 2014 */ 2015 if (pCir->HWCursor) 2016 LgShowCursor(pScrn); 2017 2018 LgRestore(pScrn); 2019 vgaHWLock(hwp); 2020} 2021 2022/* 2023 * This is called at the end of each server generation. It restores 2024 * the original (text) mode. It should also unmap the video memory, 2025 * and free any per-generation data allocated by the driver. It 2026 * should finish by unwrapping and calling the saved CloseScreen 2027 * function. 2028 */ 2029/* 2030 * Mandatory 2031 */ 2032static Bool 2033LgCloseScreen(CLOSE_SCREEN_ARGS_DECL) 2034{ 2035 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2036 vgaHWPtr hwp = VGAHWPTR(pScrn); 2037 CirPtr pCir = CIRPTR(pScrn); 2038 2039 if (pScrn->vtSema) { 2040 LgRestore(pScrn); 2041 if (pCir->HWCursor) 2042 LgHideCursor(pScrn); 2043 2044 vgaHWLock(hwp); 2045 2046 CirUnmapMem(pCir, pScrn->scrnIndex); 2047 } 2048 2049#ifdef HAVE_XAA_H 2050 if (pCir->AccelInfoRec) 2051 XAADestroyInfoRec(pCir->AccelInfoRec); 2052 pCir->AccelInfoRec = NULL; 2053#endif 2054 2055 if (pCir->CursorInfoRec) 2056 xf86DestroyCursorInfoRec(pCir->CursorInfoRec); 2057 pCir->CursorInfoRec = NULL; 2058 if (pCir->DGAModes) 2059 free(pCir->DGAModes); 2060 pCir->DGAnumModes = 0; 2061 pCir->DGAModes = NULL; 2062 2063 pScrn->vtSema = FALSE; 2064 2065 pScreen->CloseScreen = pCir->CloseScreen; 2066 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 2067} 2068 2069/* 2070 * Free up any persistent data structures. 2071 */ 2072/* 2073 * Optional 2074 */ 2075void 2076LgFreeScreen(FREE_SCREEN_ARGS_DECL) 2077{ 2078 SCRN_INFO_PTR(arg); 2079#ifdef LG_DEBUG 2080 ErrorF("LgFreeScreen\n"); 2081#endif 2082 /* 2083 * This only gets called when a screen is being deleted. It does 2084 * not get called routinely at the end of a server generation. 2085 */ 2086 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 2087 vgaHWFreeHWRec(pScrn); 2088 LgFreeRec(pScrn); 2089} 2090 2091/* 2092 * Checks if a mode is suitable for the selected chipset. 2093 */ 2094/* 2095 * Optional 2096 */ 2097ModeStatus 2098LgValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, 2099 Bool verbose, int flags) 2100{ 2101 int lace; 2102 2103 lace = 1 + ((mode->Flags & V_INTERLACE) != 0); 2104 2105 if ((mode->CrtcHDisplay <= 2048) && 2106 (mode->CrtcHSyncStart <= 4096) && 2107 (mode->CrtcHSyncEnd <= 4096) && 2108 (mode->CrtcHTotal <= 4096) && 2109 (mode->CrtcVDisplay <= 2048 * lace) && 2110 (mode->CrtcVSyncStart <= 4096 * lace) && 2111 (mode->CrtcVSyncEnd <= 4096 * lace) && 2112 (mode->CrtcVTotal <= 4096 * lace)) { 2113 return (MODE_OK); 2114 } 2115 return (MODE_BAD); 2116} 2117 2118/* 2119 * Do screen blanking. 2120 */ 2121/* 2122 * Mandatory 2123 */ 2124static Bool 2125LgSaveScreen(ScreenPtr pScreen, int mode) 2126{ 2127 CirPtr pCir = CIRPTR(xf86ScreenToScrn(pScreen)); 2128 ScrnInfoPtr pScrn = NULL; 2129 Bool unblank; 2130 2131 unblank = xf86IsUnblank(mode); 2132 2133 if (pScreen != NULL) 2134 pScrn = xf86ScreenToScrn(pScreen); 2135 2136 if (pScrn != NULL && pScrn->vtSema) { 2137 if (unblank) 2138 /* 2139 * Power up the palette DAC. 2140 */ 2141 memwb(0xB0, memrb(0xB0) & 0x7F); 2142 else 2143 /* 2144 * Power down the palette DAC. 2145 */ 2146 memwb(0xB0, memrb(0xB0) | 0x80); 2147 } 2148 2149 return vgaHWSaveScreen(pScreen, mode); 2150} 2151 2152static CARD16 2153LgSetClock(CirPtr pCir, vgaHWPtr hwp, int freq) 2154{ 2155 int ffreq, num, den; 2156 CARD8 tmp; 2157 2158 ErrorF("LgSetClock freq=%d.%03dMHz\n", freq / 1000, freq % 1000); 2159 2160 ffreq = freq; 2161 if (!CirrusFindClock(&ffreq, pCir->MaxClock, &num, &den)) 2162 return 0; 2163 2164 ErrorF("LgSetClock: nom=%x den=%x ffreq=%d.%03dMHz\n", 2165 num, den, ffreq / 1000, ffreq % 1000); 2166 2167 /* 2168 * Set VCLK3. 2169 */ 2170 /* 2171 * The numerator and denominator registers are switched around 2172 * in the Laguna chips. 2173 */ 2174 tmp = hwp->readSeq(hwp, 0x0E); 2175 hwp->writeSeq(hwp, 0x0E, (tmp & 0x80) | den); 2176 hwp->writeSeq(hwp, 0x1E, num); 2177 2178 return (den << 8) | num; 2179} 2180 2181/* 2182 * LgDisplayPowerManagementSet -- 2183 * 2184 * Sets VESA Display Power Management Signaling (DPMS) Mode. 2185 */ 2186static void 2187LgDisplayPowerManagementSet(ScrnInfoPtr pScrn, 2188 int PowerManagementMode, 2189 int flags) 2190{ 2191 unsigned char sr01, cr1a; 2192 vgaHWPtr hwp; 2193 2194#ifdef LG_DEBUG 2195 ErrorF("LgDisplayPowerManagementSet: %d\n", PowerManagementMode); 2196#endif 2197 2198 hwp = VGAHWPTR(pScrn); 2199 2200 switch (PowerManagementMode) { 2201 case DPMSModeOn: 2202 /* 2203 * Screen: On; HSync: On, VSync: On 2204 */ 2205 sr01 = 0x00; 2206 cr1a = 0x00; 2207 break; 2208 case DPMSModeStandby: 2209 /* 2210 * Screen: Off; HSync: Off, VSync: On 2211 */ 2212 sr01 = 0x20; 2213 cr1a = 0x08; 2214 break; 2215 case DPMSModeSuspend: 2216 /* 2217 * Screen: Off; HSync: On, VSync: Off 2218 */ 2219 sr01 = 0x20; 2220 cr1a = 0x04; 2221 break; 2222 case DPMSModeOff: 2223 /* 2224 * Screen: Off; HSync: Off, VSync: Off 2225 */ 2226 sr01 = 0x20; 2227 cr1a = 0x0c; 2228 break; 2229 default: 2230 return; 2231 } 2232 2233 sr01 |= hwp->readSeq(hwp, 0x01) & ~0x20; 2234 hwp->writeSeq(hwp, 0x01, sr01); 2235 cr1a |= hwp->readCrtc(hwp, 0x1A) & ~0x0C; 2236 hwp->writeCrtc(hwp, 0x1A, cr1a); 2237} 2238 2239#define minb(p) MMIO_IN8(hwp->MMIOBase, (p)) 2240#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (p),(v)) 2241 2242static void 2243mmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value) 2244{ 2245 moutb(index << 2, value); 2246} 2247 2248static CARD8 2249mmioReadCrtc(vgaHWPtr hwp, CARD8 index) 2250{ 2251 return minb(index << 2); 2252} 2253 2254static void 2255lg_vgaHWSetMmioFunc(vgaHWPtr hwp, CARD8 *base) 2256{ 2257 hwp->writeCrtc = mmioWriteCrtc; 2258 hwp->readCrtc = mmioReadCrtc; 2259 hwp->MMIOBase = base; 2260 hwp->MMIOOffset = 0; 2261} 2262