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