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