vesa.c revision a0c41156
1#define DEBUG_VERB 2 2/* 3 * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com) 4 * Copyright 2008 Red Hat, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 21 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 * Except as contained in this notice, the name of Conectiva Linux shall 25 * not be used in advertising or otherwise to promote the sale, use or other 26 * dealings in this Software without prior written authorization from 27 * Conectiva Linux. 28 * 29 * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br> 30 * David Dawes <dawes@xfree86.org> 31 * Adam Jackson <ajax@redhat.com> 32 */ 33 34/* 35 * TODO: 36 * - Port to RANDR 1.2 setup to make mode selection slightly better 37 * - Port to RANDR 1.2 to drop the old-school DGA junk 38 * - VBE/SCI for secondary DDC method? 39 */ 40 41#ifdef HAVE_CONFIG_H 42#include "config.h" 43#endif 44 45#include <string.h> 46#include <unistd.h> 47#include "vesa.h" 48 49/* All drivers initialising the SW cursor need this */ 50#include "mipointer.h" 51 52/* Colormap handling */ 53#include "micmap.h" 54#include "xf86cmap.h" 55#include "xf86Modes.h" 56 57/* DPMS */ 58#ifdef HAVE_XEXTPROTO_71 59#include <X11/extensions/dpmsconst.h> 60#else 61#define DPMS_SERVER 62#include <X11/extensions/dpms.h> 63#endif 64#include "compat-api.h" 65 66/* Mandatory functions */ 67static const OptionInfoRec * VESAAvailableOptions(int chipid, int busid); 68static void VESAIdentify(int flags); 69#if defined(XSERVER_LIBPCIACCESS) && !defined(HAVE_ISA) 70#define VESAProbe NULL 71#else 72static Bool VESAProbe(DriverPtr drv, int flags); 73#endif 74#ifdef XSERVER_LIBPCIACCESS 75static Bool VESAPciProbe(DriverPtr drv, int entity_num, 76 struct pci_device *dev, intptr_t match_data); 77#endif 78static Bool VESAPreInit(ScrnInfoPtr pScrn, int flags); 79static Bool VESAScreenInit(SCREEN_INIT_ARGS_DECL); 80static Bool VESAEnterVT(VT_FUNC_ARGS_DECL); 81static void VESALeaveVT(VT_FUNC_ARGS_DECL); 82static Bool VESACloseScreen(CLOSE_SCREEN_ARGS_DECL); 83static Bool VESASaveScreen(ScreenPtr pScreen, int mode); 84 85static Bool VESASwitchMode(SWITCH_MODE_ARGS_DECL); 86static Bool VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode); 87static void VESAAdjustFrame(ADJUST_FRAME_ARGS_DECL); 88static void VESAFreeScreen(FREE_SCREEN_ARGS_DECL); 89static void VESAFreeRec(ScrnInfoPtr pScrn); 90static VESAPtr VESAGetRec(ScrnInfoPtr pScrn); 91 92static void 93VESADisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode, 94 int flags); 95 96/* locally used functions */ 97#ifdef HAVE_ISA 98static int VESAFindIsaDevice(GDevPtr dev); 99#endif 100static Bool VESAMapVidMem(ScrnInfoPtr pScrn); 101static void VESAUnmapVidMem(ScrnInfoPtr pScrn); 102static int VESABankSwitch(ScreenPtr pScreen, unsigned int iBank); 103static void VESALoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 104 LOCO *colors, VisualPtr pVisual); 105static void SaveFonts(ScrnInfoPtr pScrn); 106static void RestoreFonts(ScrnInfoPtr pScrn); 107static Bool 108VESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function); 109 110static void * 111VESAWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 112 CARD32 *size, void *closure) 113{ 114 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 115 VESAPtr pVesa = VESAGetRec(pScrn); 116 117 *size = pVesa->maxBytesPerScanline; 118 return ((CARD8 *)pVesa->base + row * pVesa->maxBytesPerScanline + offset); 119} 120 121static void * 122VESAWindowWindowed(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 123 CARD32 *size, void *closure) 124{ 125 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 126 VESAPtr pVesa = VESAGetRec(pScrn); 127 VbeModeInfoBlock *data = ((VbeModeInfoData*)(pScrn->currentMode->Private))->data; 128 int window; 129 130 offset += pVesa->maxBytesPerScanline * row; 131 window = offset / (data->WinGranularity * 1024); 132 pVesa->windowAoffset = window * data->WinGranularity * 1024; 133 VESABankSwitch(pScreen, window); 134 *size = data->WinSize * 1024 - (offset - pVesa->windowAoffset); 135 136 return (void *)((unsigned long)pVesa->base + 137 (offset - pVesa->windowAoffset)); 138} 139 140static void 141vesaUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) 142{ 143 shadowUpdatePacked(pScreen, pBuf); 144} 145 146static Bool VESADGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen); 147 148enum GenericTypes 149{ 150 CHIP_VESA_GENERIC 151}; 152 153#ifdef XSERVER_LIBPCIACCESS 154static const struct pci_id_match vesa_device_match[] = { 155 { 156 PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 157 0x00030000, 0x00ffffff, CHIP_VESA_GENERIC 158 }, 159 160 { 0, 0, 0 }, 161}; 162#endif 163 164/* Supported chipsets */ 165static SymTabRec VESAChipsets[] = 166{ 167 {CHIP_VESA_GENERIC, "vesa"}, 168 {-1, NULL} 169}; 170 171#ifndef XSERVER_LIBPCIACCESS 172static PciChipsets VESAPCIchipsets[] = { 173 { CHIP_VESA_GENERIC, PCI_CHIP_VGA, RES_SHARED_VGA }, 174 { -1, -1, RES_UNDEFINED }, 175}; 176#endif 177 178#ifdef HAVE_ISA 179static IsaChipsets VESAISAchipsets[] = { 180 {CHIP_VESA_GENERIC, RES_EXCLUSIVE_VGA}, 181 {-1, 0 } 182}; 183#endif 184 185 186/* 187 * This contains the functions needed by the server after loading the 188 * driver module. It must be supplied, and gets added the driver list by 189 * the Module Setup funtion in the dynamic case. In the static case a 190 * reference to this is compiled in, and this requires that the name of 191 * this DriverRec be an upper-case version of the driver name. 192 */ 193_X_EXPORT DriverRec VESA = { 194 VESA_VERSION, 195 VESA_DRIVER_NAME, 196 VESAIdentify, 197 VESAProbe, 198 VESAAvailableOptions, 199 NULL, 200 0, 201 NULL, 202 203#ifdef XSERVER_LIBPCIACCESS 204 vesa_device_match, 205 VESAPciProbe 206#endif 207}; 208 209 210typedef enum { 211 OPTION_SHADOW_FB, 212 OPTION_DFLT_REFRESH, 213 OPTION_MODESET_CLEAR_SCREEN 214} VESAOpts; 215 216static const OptionInfoRec VESAOptions[] = { 217 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 218 { OPTION_DFLT_REFRESH, "DefaultRefresh", OPTV_BOOLEAN, {0}, FALSE }, 219 { OPTION_MODESET_CLEAR_SCREEN, "ModeSetClearScreen", 220 OPTV_BOOLEAN, {0}, FALSE }, 221 { -1, NULL, OPTV_NONE, {0}, FALSE } 222}; 223 224#ifdef XFree86LOADER 225 226/* Module loader interface */ 227static MODULESETUPPROTO(vesaSetup); 228 229static XF86ModuleVersionInfo vesaVersionRec = 230{ 231 VESA_DRIVER_NAME, 232 MODULEVENDORSTRING, 233 MODINFOSTRING1, 234 MODINFOSTRING2, 235 XORG_VERSION_CURRENT, 236 VESA_MAJOR_VERSION, VESA_MINOR_VERSION, VESA_PATCHLEVEL, 237 ABI_CLASS_VIDEODRV, /* This is a video driver */ 238 ABI_VIDEODRV_VERSION, 239 MOD_CLASS_VIDEODRV, 240 {0, 0, 0, 0} 241}; 242 243/* 244 * This data is accessed by the loader. The name must be the module name 245 * followed by "ModuleData". 246 */ 247_X_EXPORT XF86ModuleData vesaModuleData = { &vesaVersionRec, vesaSetup, NULL }; 248 249static pointer 250vesaSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) 251{ 252 static Bool Initialised = FALSE; 253 254 if (!Initialised) 255 { 256 Initialised = TRUE; 257 xf86AddDriver(&VESA, Module, 1); 258 return (pointer)TRUE; 259 } 260 261 if (ErrorMajor) 262 *ErrorMajor = LDR_ONCEONLY; 263 return (NULL); 264} 265 266#endif 267 268static const OptionInfoRec * 269VESAAvailableOptions(int chipid, int busid) 270{ 271 return (VESAOptions); 272} 273 274static void 275VESAIdentify(int flags) 276{ 277 xf86PrintChipsets(VESA_NAME, "driver for VESA chipsets", VESAChipsets); 278} 279 280static VESAPtr 281VESAGetRec(ScrnInfoPtr pScrn) 282{ 283 if (!pScrn->driverPrivate) 284 pScrn->driverPrivate = calloc(sizeof(VESARec), 1); 285 286 return ((VESAPtr)pScrn->driverPrivate); 287} 288 289/* Only a little like VBESetModeParameters */ 290static void 291VESASetModeParameters(vbeInfoPtr pVbe, DisplayModePtr vbemode, 292 DisplayModePtr ddcmode) 293{ 294 VbeModeInfoData *data; 295 int clock; 296 297 data = (VbeModeInfoData *)vbemode->Private; 298 299 data->block = calloc(sizeof(VbeCRTCInfoBlock), 1); 300 data->block->HorizontalTotal = ddcmode->HTotal; 301 data->block->HorizontalSyncStart = ddcmode->HSyncStart; 302 data->block->HorizontalSyncEnd = ddcmode->HSyncEnd; 303 data->block->VerticalTotal = ddcmode->VTotal; 304 data->block->VerticalSyncStart = ddcmode->VSyncStart; 305 data->block->VerticalSyncEnd = ddcmode->VSyncEnd; 306 data->block->Flags = ((ddcmode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) | 307 ((ddcmode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0); 308 data->block->PixelClock = ddcmode->Clock * 1000; 309 310 /* ask the BIOS to figure out the real clock */ 311 clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock); 312 if (clock) 313 data->block->PixelClock = clock; 314 315 data->mode |= (1 << 11); 316 data->block->RefreshRate = 100 * ((double)(data->block->PixelClock) / 317 (double)(ddcmode->HTotal * ddcmode->VTotal)); 318} 319 320/* 321 * Despite that VBE gives you pixel granularity for mode sizes, some BIOSes 322 * think they can only give sizes in multiples of character cells; and 323 * indeed, the reference CVT and GTF formulae only give results where 324 * (h % 8) == 0. Whatever, let's just try to cope. What we're looking for 325 * here is cases where the display says 1366x768 and the BIOS says 1360x768. 326 */ 327static Bool 328vesaModesCloseEnough(DisplayModePtr edid, DisplayModePtr vbe) 329{ 330 if (!(edid->type & M_T_DRIVER)) 331 return FALSE; 332 333 /* never seen a height granularity... */ 334 if (edid->VDisplay != vbe->VDisplay) 335 return FALSE; 336 337 if (edid->HDisplay >= vbe->HDisplay && 338 (edid->HDisplay & ~7) == (vbe->HDisplay & ~7)) 339 return TRUE; 340 341 return FALSE; 342} 343 344static ModeStatus 345VESAValidMode(SCRN_ARG_TYPE arg, DisplayModePtr p, Bool flag, int pass) 346{ 347 SCRN_INFO_PTR(arg); 348 static int warned = 0; 349 int found = 0; 350 VESAPtr pVesa = VESAGetRec(pScrn); 351 MonPtr mon = pScrn->monitor; 352 ModeStatus ret = MODE_BAD; 353 DisplayModePtr mode; 354 float v; 355 356 pVesa = VESAGetRec(pScrn); 357 358 if (pass != MODECHECK_FINAL) { 359 if (!warned) { 360 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VESAValidMode called unexpectedly\n"); 361 warned = 1; 362 } 363 return MODE_OK; 364 } 365 366 /* 367 * This is suboptimal. We pass in just the barest description of a mode 368 * we can get away with to VBEValidateModes, so it can't really throw 369 * out anything we give it. But we need to filter the list so that we 370 * don't populate the mode list with things the monitor can't do. 371 * 372 * So first off, if this isn't a mode we handed to the server (ie, 373 * M_T_BUILTIN), then we know we can't do it. 374 */ 375 if (!(p->type & M_T_BUILTIN)) 376 return MODE_NOMODE; 377 378 if (pVesa->strict_validation) { 379 /* 380 * If it's our first pass at mode validation, we'll try for a strict 381 * intersection between the VBE and DDC mode lists. 382 */ 383 if (pScrn->monitor->DDC) { 384 for (mode = pScrn->monitor->Modes; mode; mode = mode->next) { 385 if (vesaModesCloseEnough(mode, p)) { 386 if (xf86CheckModeForMonitor(mode, mon) == MODE_OK) { 387 found = 1; 388 break; 389 } 390 } 391 if (mode == pScrn->monitor->Last) 392 break; 393 } 394 if (!found) 395 return MODE_NOMODE; 396 397 /* having found a matching mode, stash the CRTC values aside */ 398 VESASetModeParameters(pVesa->pVbe, p, mode); 399 return MODE_OK; 400 } 401 402 /* No DDC and no modes make Homer something something... */ 403 return MODE_NOMODE; 404 } 405 406 /* 407 * Finally, walk through the vsync rates 1Hz at a time looking for a mode 408 * that will fit. This is assuredly a terrible way to do this, but 409 * there's no obvious method for computing a mode of a given size that 410 * will pass xf86CheckModeForMonitor. XXX this path is terrible, but 411 * then, by this point, you're well into despair territory. 412 */ 413 for (v = mon->vrefresh[0].lo; v <= mon->vrefresh[0].hi; v++) { 414 mode = xf86GTFMode(p->HDisplay, p->VDisplay, v, 0, 0); 415 ret = xf86CheckModeForMonitor(mode, mon); 416 free(mode->name); 417 free(mode); 418 if (ret == MODE_OK) 419 break; 420 } 421 422 return ret; 423} 424 425static void 426VESAInitScrn(ScrnInfoPtr pScrn) 427{ 428 pScrn->driverVersion = VESA_VERSION; 429 pScrn->driverName = VESA_DRIVER_NAME; 430 pScrn->name = VESA_NAME; 431 pScrn->Probe = VESAProbe; 432 pScrn->PreInit = VESAPreInit; 433 pScrn->ScreenInit = VESAScreenInit; 434 pScrn->SwitchMode = VESASwitchMode; 435 pScrn->ValidMode = VESAValidMode; 436 pScrn->AdjustFrame = VESAAdjustFrame; 437 pScrn->EnterVT = VESAEnterVT; 438 pScrn->LeaveVT = VESALeaveVT; 439 pScrn->FreeScreen = VESAFreeScreen; 440} 441 442/* 443 * This function is called once, at the start of the first server generation to 444 * do a minimal probe for supported hardware. 445 */ 446 447#ifdef XSERVER_LIBPCIACCESS 448static Bool 449VESAPciProbe(DriverPtr drv, int entity_num, struct pci_device *dev, 450 intptr_t match_data) 451{ 452 ScrnInfoPtr pScrn; 453 454#ifdef __linux__ 455 if (access("/sys/devices/platform/efi-framebuffer.0", F_OK) == 0 || 456 access("/sys/devices/platform/efifb.0", F_OK) == 0) { 457 ErrorF("vesa: Refusing to run on UEFI\n"); 458 return FALSE; 459 } 460#endif 461 462 pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL, 463 NULL, NULL, NULL, NULL, NULL); 464 if (pScrn != NULL) { 465 VESAPtr pVesa; 466 467 if (pci_device_has_kernel_driver(dev)) { 468 ErrorF("vesa: Ignoring device with a bound kernel driver\n"); 469 return FALSE; 470 } 471 472 pVesa = VESAGetRec(pScrn); 473 VESAInitScrn(pScrn); 474 pVesa->pciInfo = dev; 475 } 476 477 return (pScrn != NULL); 478} 479#endif 480 481#ifndef VESAProbe 482static Bool 483VESAProbe(DriverPtr drv, int flags) 484{ 485 Bool foundScreen = FALSE; 486 int numDevSections, numUsed; 487 GDevPtr *devSections; 488 int *usedChips; 489 int i; 490 491 /* 492 * Find the config file Device sections that match this 493 * driver, and return if there are none. 494 */ 495 if ((numDevSections = xf86MatchDevice(VESA_NAME, 496 &devSections)) <= 0) 497 return (FALSE); 498 499#ifndef XSERVER_LIBPCIACCESS 500 /* PCI BUS */ 501 if (xf86GetPciVideoInfo()) { 502 numUsed = xf86MatchPciInstances(VESA_NAME, PCI_VENDOR_GENERIC, 503 VESAChipsets, VESAPCIchipsets, 504 devSections, numDevSections, 505 drv, &usedChips); 506 if (numUsed > 0) { 507 if (flags & PROBE_DETECT) 508 foundScreen = TRUE; 509 else { 510 for (i = 0; i < numUsed; i++) { 511 ScrnInfoPtr pScrn = NULL; 512 /* Allocate a ScrnInfoRec */ 513 if ((pScrn = xf86ConfigPciEntity(pScrn,0,usedChips[i], 514 VESAPCIchipsets,NULL, 515 NULL,NULL,NULL,NULL))) { 516 VESAInitScrn(pScrn); 517 foundScreen = TRUE; 518 } 519 } 520 } 521 free(usedChips); 522 } 523 } 524#endif 525 526#ifdef HAVE_ISA 527 /* Isa Bus */ 528 numUsed = xf86MatchIsaInstances(VESA_NAME,VESAChipsets, 529 VESAISAchipsets, drv, 530 VESAFindIsaDevice, devSections, 531 numDevSections, &usedChips); 532 if(numUsed > 0) { 533 if (flags & PROBE_DETECT) 534 foundScreen = TRUE; 535 else for (i = 0; i < numUsed; i++) { 536 ScrnInfoPtr pScrn = NULL; 537 if ((pScrn = xf86ConfigIsaEntity(pScrn, 0,usedChips[i], 538 VESAISAchipsets, NULL, 539 NULL, NULL, NULL, NULL))) { 540 VESAInitScrn(pScrn); 541 foundScreen = TRUE; 542 } 543 } 544 free(usedChips); 545 } 546#endif 547 548 free(devSections); 549 550 return (foundScreen); 551} 552#endif 553 554#ifdef HAVE_ISA 555static int 556VESAFindIsaDevice(GDevPtr dev) 557{ 558#ifndef PC98_EGC 559 CARD16 GenericIOBase = VGAHW_GET_IOBASE(); 560 CARD8 CurrentValue, TestValue; 561 562 /* There's no need to unlock VGA CRTC registers here */ 563 564 /* VGA has one more read/write attribute register than EGA */ 565 (void) inb(GenericIOBase + VGA_IN_STAT_1_OFFSET); /* Reset flip-flop */ 566 outb(VGA_ATTR_INDEX, 0x14 | 0x20); 567 CurrentValue = inb(VGA_ATTR_DATA_R); 568 outb(VGA_ATTR_DATA_W, CurrentValue ^ 0x0F); 569 outb(VGA_ATTR_INDEX, 0x14 | 0x20); 570 TestValue = inb(VGA_ATTR_DATA_R); 571 outb(VGA_ATTR_DATA_R, CurrentValue); 572 573 /* Quit now if no VGA is present */ 574 if ((CurrentValue ^ 0x0F) != TestValue) 575 return -1; 576#endif 577 return (int)CHIP_VESA_GENERIC; 578} 579#endif 580 581static void 582VESAFreeRec(ScrnInfoPtr pScrn) 583{ 584 VESAPtr pVesa = VESAGetRec(pScrn); 585#if 0 586 DisplayModePtr mode = pScrn->modes; 587 /* I am not sure if the modes will ever get freed. 588 * Anyway, the data unknown to other modules is being freed here. 589 */ 590 if (mode) { 591 do { 592 if (mode->Private) { 593 VbeModeInfoData *data = (VbeModeInfoData*)mode->Private; 594 595 if (data->block) 596 free(data->block); 597 598 free(data); 599 600 mode->Private = NULL; 601 } 602 mode = mode->next; 603 } while (mode && mode != pScrn->modes); 604 } 605#endif 606 free(pVesa->monitor); 607 if (pVesa->vbeInfo) 608 VBEFreeVBEInfo(pVesa->vbeInfo); 609 free(pVesa->pal); 610 free(pVesa->savedPal); 611 free(pVesa->fonts); 612 free(pScrn->driverPrivate); 613 pScrn->driverPrivate = NULL; 614} 615 616static int 617VESAValidateModes(ScrnInfoPtr pScrn) 618{ 619 VESAPtr pVesa = VESAGetRec(pScrn); 620 DisplayModePtr mode; 621 622 for (mode = pScrn->monitor->Modes; mode; mode = mode->next) 623 mode->status = MODE_OK; 624 625 return VBEValidateModes(pScrn, NULL, pScrn->display->modes, 626 NULL, NULL, 0, 32767, 1, 0, 32767, 627 pScrn->display->virtualX, 628 pScrn->display->virtualY, 629 pVesa->mapSize, LOOKUP_BEST_REFRESH); 630} 631 632/* 633 * This function is called once for each screen at the start of the first 634 * server generation to initialise the screen for all server generations. 635 */ 636static Bool 637VESAPreInit(ScrnInfoPtr pScrn, int flags) 638{ 639 VESAPtr pVesa; 640 VbeInfoBlock *vbe; 641 DisplayModePtr pMode; 642 VbeModeInfoBlock *mode; 643 Gamma gzeros = {0.0, 0.0, 0.0}; 644 rgb rzeros = {0, 0, 0}; 645 pointer pDDCModule; 646 int i; 647 int flags24 = 0; 648 int defaultDepth = 0; 649 int defaultBpp = 0; 650 int depths = 0; 651 652 if (flags & PROBE_DETECT) 653 return (FALSE); 654 655 pVesa = VESAGetRec(pScrn); 656 pVesa->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 657 658 /* Load vbe module */ 659 if (!xf86LoadSubModule(pScrn, "vbe")) 660 return (FALSE); 661 662 if ((pVesa->pVbe = VBEExtendedInit(NULL, pVesa->pEnt->index, 663 SET_BIOS_SCRATCH 664 | RESTORE_BIOS_SCRATCH)) == NULL) 665 return (FALSE); 666 667#ifndef XSERVER_LIBPCIACCESS 668 if (pVesa->pEnt->location.type == BUS_PCI) { 669 pVesa->pciInfo = xf86GetPciInfoForEntity(pVesa->pEnt->index); 670 pVesa->pciTag = pciTag(pVesa->pciInfo->bus, pVesa->pciInfo->device, 671 pVesa->pciInfo->func); 672 } 673#endif 674 675 pScrn->chipset = "vesa"; 676 pScrn->monitor = pScrn->confScreen->monitor; 677 pScrn->progClock = TRUE; 678 pScrn->rgbBits = 8; 679 680 if ((vbe = VBEGetVBEInfo(pVesa->pVbe)) == NULL) 681 return (FALSE); 682 pVesa->major = (unsigned)(vbe->VESAVersion >> 8); 683 pVesa->minor = vbe->VESAVersion & 0xff; 684 pVesa->vbeInfo = vbe; 685 pScrn->videoRam = vbe->TotalMemory * 64; 686 687 /* 688 * Find what depths are available. 689 */ 690 depths = VBEFindSupportedDepths(pVesa->pVbe, pVesa->vbeInfo, &flags24, 691 V_MODETYPE_VBE); 692 693 /* Preferred order for default depth selection. */ 694 if (depths & V_DEPTH_24 && (flags24 & Support32bppFb)) 695 defaultDepth = 24; 696 else if (depths & V_DEPTH_16) 697 defaultDepth = 16; 698 else if (depths & V_DEPTH_15) 699 defaultDepth = 15; 700 else if (depths & V_DEPTH_24) 701 defaultDepth = 24; /* ew though */ 702 else if (depths & V_DEPTH_8) 703 defaultDepth = 8; 704 else if (depths & V_DEPTH_4) 705 defaultDepth = 4; 706 else if (depths & V_DEPTH_1) 707 defaultDepth = 1; 708 709 if (defaultDepth == 24 && !(flags24 & Support32bppFb)) 710 defaultBpp = 24; 711 712 /* Prefer 32bpp because 1999 called and wants its packed pixels back */ 713 if (flags24 & Support32bppFb) 714 flags24 |= SupportConvert24to32 | PreferConvert24to32; 715 if (flags24 & Support24bppFb) 716 flags24 |= SupportConvert32to24; 717 718 if (!xf86SetDepthBpp(pScrn, defaultDepth, 0, defaultBpp, flags24)) { 719 vbeFree(pVesa->pVbe); 720 return (FALSE); 721 } 722 xf86PrintDepthBpp(pScrn); 723 724 /* color weight */ 725 if (pScrn->depth > 8 && !xf86SetWeight(pScrn, rzeros, rzeros)) { 726 vbeFree(pVesa->pVbe); 727 return (FALSE); 728 } 729 /* visual init */ 730 if (!xf86SetDefaultVisual(pScrn, -1)) { 731 vbeFree(pVesa->pVbe); 732 return (FALSE); 733 } 734 735 xf86SetGamma(pScrn, gzeros); 736 737 /* set up options before loading any modules that may look at them */ 738 xf86CollectOptions(pScrn, NULL); 739 740 if (pVesa->major >= 2) { 741 /* Load ddc module */ 742 if ((pDDCModule = xf86LoadSubModule(pScrn, "ddc")) == NULL) { 743 vbeFree(pVesa->pVbe); 744 return (FALSE); 745 } 746 747 if ((pVesa->monitor = vbeDoEDID(pVesa->pVbe, pDDCModule)) != NULL) { 748 xf86PrintEDID(pVesa->monitor); 749 } 750 751 xf86UnloadSubModule(pDDCModule); 752 } 753 754 if ((pScrn->monitor->DDC = pVesa->monitor) != NULL) 755 xf86SetDDCproperties(pScrn, pVesa->monitor); 756 else { 757 void *panelid = VBEReadPanelID(pVesa->pVbe); 758 VBEInterpretPanelID(SCRN_OR_INDEX_ARG(pScrn), panelid); 759 free(panelid); 760 } 761 762 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, DEBUG_VERB, 763 "Searching for matching VESA mode(s):\n"); 764 765 /* 766 * Check the available BIOS modes, and extract those that match the 767 * requirements into the modePool. Note: modePool is a NULL-terminated 768 * list. 769 */ 770 pScrn->modePool = VBEGetModePool (pScrn, pVesa->pVbe, pVesa->vbeInfo, 771 V_MODETYPE_VBE); 772 773 xf86ErrorFVerb(DEBUG_VERB, "\n"); 774 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, DEBUG_VERB, 775 "Total Memory: %d 64KB banks (%dkB)\n", vbe->TotalMemory, 776 (vbe->TotalMemory * 65536) / 1024); 777 778 pVesa->mapSize = vbe->TotalMemory * 65536; 779 if (pScrn->modePool == NULL) { 780 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No matching modes\n"); 781 vbeFree(pVesa->pVbe); 782 return (FALSE); 783 } 784 785 VBESetModeNames(pScrn->modePool); 786 787 pVesa->strict_validation = TRUE; 788 i = VESAValidateModes(pScrn); 789 790 if (i <= 0) { 791 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 792 "No valid modes left. Trying less strict filter...\n"); 793 pVesa->strict_validation = FALSE; 794 i = VESAValidateModes(pScrn); 795 } 796 797 if (i <= 0) do { 798 Bool changed = FALSE; 799 /* maybe there's more modes at the bottom... */ 800 if (pScrn->monitor->vrefresh[0].lo > 50) { 801 changed = TRUE; 802 pScrn->monitor->vrefresh[0].lo = 50; 803 } 804 if (pScrn->monitor->hsync[0].lo > 31.5) { 805 changed = TRUE; 806 pScrn->monitor->hsync[0].lo = 31.5; 807 } 808 809 if (!changed) 810 break; 811 812 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 813 "No valid modes left. Trying aggressive sync range...\n"); 814 i = VESAValidateModes(pScrn); 815 } while (0); 816 817 if (i <= 0) { 818 /* alright, i'm out of ideas */ 819 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes\n"); 820 vbeFree(pVesa->pVbe); 821 return (FALSE); 822 } 823 824 xf86PruneDriverModes(pScrn); 825 826 pMode = pScrn->modes; 827 do { 828 mode = ((VbeModeInfoData*)pMode->Private)->data; 829 if (mode->BytesPerScanline > pVesa->maxBytesPerScanline) { 830 pVesa->maxBytesPerScanline = mode->BytesPerScanline; 831 } 832 pMode = pMode->next; 833 } while (pMode != pScrn->modes); 834 835 pScrn->currentMode = pScrn->modes; 836 pScrn->displayWidth = pScrn->virtualX; 837 838 VBEPrintModes(pScrn); 839 840 /* Set display resolution */ 841 xf86SetDpi(pScrn, 0, 0); 842 843 if (pScrn->modes == NULL) { 844 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes\n"); 845 vbeFree(pVesa->pVbe); 846 return (FALSE); 847 } 848 849 /* options */ 850 if (!(pVesa->Options = malloc(sizeof(VESAOptions)))) { 851 vbeFree(pVesa->pVbe); 852 return FALSE; 853 } 854 memcpy(pVesa->Options, VESAOptions, sizeof(VESAOptions)); 855 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pVesa->Options); 856 857 /* Use shadow by default, for non-virt hardware */ 858 if (!xf86GetOptValBool(pVesa->Options, OPTION_SHADOW_FB, &pVesa->shadowFB)) 859 { 860 switch (pVesa->pciInfo->vendor_id) { 861 case 0x1234: /* bochs vga (not in pci.ids) */ 862 case 0x15ad: /* vmware */ 863 case 0x1b36: /* qemu qxl */ 864 case 0x80ee: /* virtualbox */ 865 case 0xaaaa: /* parallels (not in pci.ids) */ 866 pVesa->shadowFB = FALSE; 867 break; 868 869 case 0x1013: /* qemu's cirrus emulation */ 870 if (pVesa->pciInfo->subvendor_id == 0x1af4) 871 pVesa->shadowFB = FALSE; 872 else 873 pVesa->shadowFB = TRUE; 874 break; 875 876 case 0x1414: /* microsoft hyper-v */ 877 if (pVesa->pciInfo->device_id == 0x5353) 878 pVesa->shadowFB = FALSE; 879 else 880 pVesa->shadowFB = TRUE; 881 break; 882 883 default: 884 pVesa->shadowFB = TRUE; 885 break; 886 } 887 } 888 889 /* Use default refresh by default. Too many VBE 3.0 890 * BIOSes are incorrectly implemented. 891 */ 892 pVesa->defaultRefresh = xf86ReturnOptValBool(pVesa->Options, 893 OPTION_DFLT_REFRESH, TRUE); 894 895 pVesa->ModeSetClearScreen = 896 xf86ReturnOptValBool(pVesa->Options, 897 OPTION_MODESET_CLEAR_SCREEN, FALSE); 898 899 if (!pVesa->defaultRefresh && !pVesa->strict_validation) 900 VBESetModeParameters(pScrn, pVesa->pVbe); 901 902 mode = ((VbeModeInfoData*)pScrn->modes->Private)->data; 903 switch (mode->MemoryModel) { 904 case 0x4: /* Packed pixel */ 905 case 0x6: /* Direct Color */ 906 pScrn->bitmapBitOrder = BITMAP_BIT_ORDER; 907 908 switch (pScrn->bitsPerPixel) { 909 case 8: 910 case 16: 911 case 24: 912 case 32: 913 break; 914 default: 915 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 916 "Unsupported bpp: %d\n", pScrn->bitsPerPixel); 917 vbeFree(pVesa->pVbe); 918 return FALSE; 919 } 920 break; 921 default: 922 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 923 "Unsupported Memory Model: %d\n", mode->MemoryModel); 924 return FALSE; 925 } 926 927 if (pVesa->shadowFB) { 928 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using \"Shadow Framebuffer\"\n"); 929 if (!xf86LoadSubModule(pScrn, "shadow")) { 930 vbeFree(pVesa->pVbe); 931 return (FALSE); 932 } 933 } 934 935 if (xf86LoadSubModule(pScrn, "fb") == NULL) { 936 VESAFreeRec(pScrn); 937 vbeFree(pVesa->pVbe); 938 return (FALSE); 939 } 940 941 vbeFree(pVesa->pVbe); 942 943 return (TRUE); 944} 945 946static Bool 947vesaCreateScreenResources(ScreenPtr pScreen) 948{ 949 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 950 VESAPtr pVesa = VESAGetRec(pScrn); 951 Bool ret; 952 953 pScreen->CreateScreenResources = pVesa->CreateScreenResources; 954 ret = pScreen->CreateScreenResources(pScreen); 955 pScreen->CreateScreenResources = vesaCreateScreenResources; 956 957 shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen), pVesa->update, 958 pVesa->window, 0, 0); 959 960 return ret; 961} 962 963static void 964vesaEnableDisableFBAccess(SCRN_ARG_TYPE arg, Bool enable) 965{ 966 SCRN_INFO_PTR(arg); 967 VESAPtr pVesa = VESAGetRec(pScrn); 968 969 pVesa->accessEnabled = enable; 970 pVesa->EnableDisableFBAccess(arg, enable); 971} 972 973static Bool 974VESAScreenInit(SCREEN_INIT_ARGS_DECL) 975{ 976 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 977 VESAPtr pVesa = VESAGetRec(pScrn); 978 VisualPtr visual; 979 VbeModeInfoBlock *mode; 980 int flags; 981 982 if ((pVesa->pVbe = VBEExtendedInit(NULL, pVesa->pEnt->index, 983 SET_BIOS_SCRATCH 984 | RESTORE_BIOS_SCRATCH)) == NULL) 985 return (FALSE); 986 987 if (pVesa->mapPhys == 0) { 988 mode = ((VbeModeInfoData*)(pScrn->currentMode->Private))->data; 989 pScrn->videoRam = pVesa->mapSize; 990 pVesa->mapPhys = mode->PhysBasePtr; 991 pVesa->mapOff = 0; 992 } 993 994 if (pVesa->mapPhys == 0) { 995 pVesa->mapPhys = 0xa0000; 996 pVesa->mapSize = 0x10000; 997 } 998 999 if (!VESAMapVidMem(pScrn)) { 1000 if (pVesa->mapPhys != 0xa0000) { 1001 pVesa->mapPhys = 0xa0000; 1002 pVesa->mapSize = 0x10000; 1003 if (!VESAMapVidMem(pScrn)) 1004 return (FALSE); 1005 } 1006 else 1007 return (FALSE); 1008 } 1009 1010 /* Set bpp to 8 for depth 4 when using shadowfb. */ 1011 if (pVesa->shadowFB && pScrn->bitsPerPixel == 4) 1012 pScrn->bitsPerPixel = 8; 1013 1014 if (pVesa->shadowFB) { 1015 pVesa->shadow = calloc(1, pScrn->displayWidth * pScrn->virtualY * 1016 ((pScrn->bitsPerPixel + 7) / 8)); 1017 if (!pVesa->shadow) { 1018 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1019 "Failed to allocate shadow buffer\n"); 1020 return FALSE; 1021 } 1022 } 1023 1024 /* save current video state */ 1025 VESASaveRestore(pScrn, MODE_SAVE); 1026 pVesa->savedPal = VBESetGetPaletteData(pVesa->pVbe, FALSE, 0, 256, 1027 NULL, FALSE, FALSE); 1028 1029 /* set first video mode */ 1030 if (!VESASetMode(pScrn, pScrn->currentMode)) 1031 return (FALSE); 1032 1033 /* set the viewport */ 1034 VESAAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 1035 1036 /* Blank the screen for aesthetic reasons. */ 1037 VESASaveScreen(pScreen, SCREEN_SAVER_ON); 1038 1039 /* mi layer */ 1040 miClearVisualTypes(); 1041 if (!xf86SetDefaultVisual(pScrn, -1)) 1042 return (FALSE); 1043 if (pScrn->bitsPerPixel > 8) { 1044 if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 1045 pScrn->rgbBits, TrueColor)) 1046 return (FALSE); 1047 } 1048 else { 1049 if (!miSetVisualTypes(pScrn->depth, 1050 miGetDefaultVisualMask(pScrn->depth), 1051 pScrn->rgbBits, pScrn->defaultVisual)) 1052 return (FALSE); 1053 } 1054 if (!miSetPixmapDepths()) 1055 return (FALSE); 1056 1057 mode = ((VbeModeInfoData*)pScrn->modes->Private)->data; 1058 switch (mode->MemoryModel) { 1059 case 0x4: /* Packed pixel */ 1060 case 0x6: /* Direct Color */ 1061 switch (pScrn->bitsPerPixel) { 1062 case 8: 1063 case 16: 1064 case 24: 1065 case 32: 1066 if (!fbScreenInit(pScreen, 1067 pVesa->shadowFB ? pVesa->shadow : pVesa->base, 1068 pScrn->virtualX, pScrn->virtualY, 1069 pScrn->xDpi, pScrn->yDpi, 1070 pScrn->displayWidth, pScrn->bitsPerPixel)) 1071 return (FALSE); 1072 break; 1073 default: 1074 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1075 "Unsupported bpp: %d", pScrn->bitsPerPixel); 1076 return (FALSE); 1077 } 1078 break; 1079 default: 1080 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1081 "Unsupported Memory Model: %d", mode->MemoryModel); 1082 return (FALSE); 1083 } 1084 1085 1086 if (pScrn->bitsPerPixel > 8) { 1087 /* Fixup RGB ordering */ 1088 visual = pScreen->visuals + pScreen->numVisuals; 1089 while (--visual >= pScreen->visuals) { 1090 if ((visual->class | DynamicClass) == DirectColor) { 1091 visual->offsetRed = pScrn->offset.red; 1092 visual->offsetGreen = pScrn->offset.green; 1093 visual->offsetBlue = pScrn->offset.blue; 1094 visual->redMask = pScrn->mask.red; 1095 visual->greenMask = pScrn->mask.green; 1096 visual->blueMask = pScrn->mask.blue; 1097 } 1098 } 1099 } 1100 1101 /* must be after RGB ordering fixed */ 1102 fbPictureInit(pScreen, 0, 0); 1103 1104 if (pVesa->shadowFB) { 1105 if (pVesa->mapPhys == 0xa0000) { /* Windowed */ 1106 pVesa->update = vesaUpdatePacked; 1107 pVesa->window = VESAWindowWindowed; 1108 } 1109 else { /* Linear */ 1110 pVesa->update = vesaUpdatePacked; 1111 pVesa->window = VESAWindowLinear; 1112 } 1113 1114 if (!shadowSetup(pScreen)) 1115 return FALSE; 1116 pVesa->CreateScreenResources = pScreen->CreateScreenResources; 1117 pScreen->CreateScreenResources = vesaCreateScreenResources; 1118 } 1119 else if (pVesa->mapPhys == 0xa0000) { 1120 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1121 "Banked framebuffer requires ShadowFB\n"); 1122 return FALSE; 1123 } 1124 1125 VESADGAInit(pScrn, pScreen); 1126 1127 xf86SetBlackWhitePixels(pScreen); 1128 xf86SetBackingStore(pScreen); 1129 1130 /* software cursor */ 1131 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 1132 1133 /* colormap */ 1134 if (!miCreateDefColormap(pScreen)) 1135 return (FALSE); 1136 1137 flags = CMAP_RELOAD_ON_MODE_SWITCH; 1138 1139 if(!xf86HandleColormaps(pScreen, 256, 1140 pVesa->vbeInfo->Capabilities[0] & 0x01 ? 8 : 6, 1141 VESALoadPalette, NULL, flags)) 1142 return (FALSE); 1143 1144 pVesa->accessEnabled = TRUE; 1145 pVesa->EnableDisableFBAccess = pScrn->EnableDisableFBAccess; 1146 pScrn->EnableDisableFBAccess = vesaEnableDisableFBAccess; 1147 1148 pVesa->CloseScreen = pScreen->CloseScreen; 1149 pScreen->CloseScreen = VESACloseScreen; 1150 pScreen->SaveScreen = VESASaveScreen; 1151 1152 xf86DPMSInit(pScreen, VESADisplayPowerManagementSet, 0); 1153 1154 /* Report any unused options (only for the first generation) */ 1155 if (serverGeneration == 1) 1156 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 1157 1158 return (TRUE); 1159} 1160 1161static Bool 1162VESAEnterVT(VT_FUNC_ARGS_DECL) 1163{ 1164 SCRN_INFO_PTR(arg); 1165 1166 if (!VESASetMode(pScrn, pScrn->currentMode)) 1167 return FALSE; 1168 VESAAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 1169 return TRUE; 1170} 1171 1172static void 1173VESALeaveVT(VT_FUNC_ARGS_DECL) 1174{ 1175 SCRN_INFO_PTR(arg); 1176 VESASaveRestore(pScrn, MODE_RESTORE); 1177} 1178 1179static Bool 1180VESACloseScreen(CLOSE_SCREEN_ARGS_DECL) 1181{ 1182 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1183 VESAPtr pVesa = VESAGetRec(pScrn); 1184 1185 if (pScrn->vtSema) { 1186 VESASaveRestore(pScrn, MODE_RESTORE); 1187 if (pVesa->savedPal) 1188 VBESetGetPaletteData(pVesa->pVbe, TRUE, 0, 256, 1189 pVesa->savedPal, FALSE, TRUE); 1190 VESAUnmapVidMem(pScrn); 1191 } 1192 if (pVesa->shadowFB && pVesa->shadow) { 1193 shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); 1194 free(pVesa->shadow); 1195 } 1196 if (pVesa->pDGAMode) { 1197 free(pVesa->pDGAMode); 1198 pVesa->pDGAMode = NULL; 1199 pVesa->nDGAMode = 0; 1200 } 1201 pScrn->vtSema = FALSE; 1202 1203 pScrn->EnableDisableFBAccess = pVesa->EnableDisableFBAccess; 1204 pScreen->CreateScreenResources = pVesa->CreateScreenResources; 1205 pScreen->CloseScreen = pVesa->CloseScreen; 1206 return pScreen->CloseScreen(CLOSE_SCREEN_ARGS); 1207} 1208 1209static Bool 1210VESASwitchMode(SWITCH_MODE_ARGS_DECL) 1211{ 1212 SCRN_INFO_PTR(arg); 1213 VESAPtr pVesa = VESAGetRec(pScrn); 1214 Bool ret, disableAccess = pVesa->ModeSetClearScreen && pVesa->accessEnabled; 1215 1216 if (disableAccess) 1217 pScrn->EnableDisableFBAccess(SCRN_OR_INDEX_ARG(pScrn),FALSE); 1218 ret = VESASetMode(pScrn, mode); 1219 if (disableAccess) 1220 pScrn->EnableDisableFBAccess(SCRN_OR_INDEX_ARG(pScrn),TRUE); 1221 return ret; 1222} 1223 1224/* Set a graphics mode */ 1225static Bool 1226VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) 1227{ 1228 VESAPtr pVesa; 1229 VbeModeInfoData *data; 1230 int mode; 1231 1232 pVesa = VESAGetRec(pScrn); 1233 1234 data = (VbeModeInfoData*)pMode->Private; 1235 1236 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 1237 "Setting up VESA Mode 0x%X (%dx%d)\n", 1238 data->mode & 0x7FF, pMode->HDisplay, pMode->VDisplay); 1239 1240 /* careful, setting the bit means don't clear the screen */ 1241 mode = data->mode | (pVesa->ModeSetClearScreen ? 0 : (1U << 15)); 1242 1243 /* enable linear addressing */ 1244 if (pVesa->mapPhys != 0xa0000) 1245 mode |= 1 << 14; 1246 1247 if (VBESetVBEMode(pVesa->pVbe, mode, data->block) == FALSE) { 1248 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBESetVBEMode failed"); 1249 if ((data->block || (data->mode & (1 << 11))) && 1250 VBESetVBEMode(pVesa->pVbe, (mode & ~(1 << 11)), NULL) == TRUE) { 1251 /* Some cards do not like setting the clock. 1252 * Free it as it will not be any longer useful 1253 */ 1254 xf86ErrorF(", mode set without customized refresh.\n"); 1255 free(data->block); 1256 data->block = NULL; 1257 data->mode &= ~(1 << 11); 1258 } 1259 else { 1260 ErrorF("\n"); 1261 return (FALSE); 1262 } 1263 } 1264 1265 pVesa->bankSwitchWindowB = 1266 !((data->data->WinBSegment == 0) && (data->data->WinBAttributes == 0)); 1267 1268 if (data->data->XResolution != pScrn->displayWidth) 1269 VBESetLogicalScanline(pVesa->pVbe, pScrn->displayWidth); 1270 1271 if (pScrn->bitsPerPixel == 8 && pVesa->vbeInfo->Capabilities[0] & 0x01 && 1272 !(data->data->MemoryModel == 0x6 || data->data->MemoryModel == 0x7)) 1273 VBESetGetDACPaletteFormat(pVesa->pVbe, 8); 1274 1275 pScrn->vtSema = TRUE; 1276 1277 return (TRUE); 1278} 1279 1280static void 1281VESAAdjustFrame(ADJUST_FRAME_ARGS_DECL) 1282{ 1283 SCRN_INFO_PTR(arg); 1284 VESAPtr pVesa = VESAGetRec(pScrn); 1285 1286 VBESetDisplayStart(pVesa->pVbe, x, y, TRUE); 1287} 1288 1289static void 1290VESAFreeScreen(FREE_SCREEN_ARGS_DECL) 1291{ 1292 SCRN_INFO_PTR(arg); 1293 VESAFreeRec(pScrn); 1294} 1295 1296static Bool 1297VESAMapVidMem(ScrnInfoPtr pScrn) 1298{ 1299 VESAPtr pVesa = VESAGetRec(pScrn); 1300 1301 if (pVesa->base != NULL) 1302 return (TRUE); 1303 1304 pScrn->memPhysBase = pVesa->mapPhys; 1305 pScrn->fbOffset = pVesa->mapOff; 1306 1307#ifdef XSERVER_LIBPCIACCESS 1308 if (pVesa->pciInfo != NULL) { 1309 if (pVesa->mapPhys != 0xa0000) { 1310 (void) pci_device_map_range(pVesa->pciInfo, pScrn->memPhysBase, 1311 pVesa->mapSize, 1312 (PCI_DEV_MAP_FLAG_WRITABLE 1313 | PCI_DEV_MAP_FLAG_WRITE_COMBINE), 1314 & pVesa->base); 1315 1316 if (pVesa->base) 1317 (void) pci_device_map_legacy(pVesa->pciInfo, 0xa0000, 0x10000, 1318 PCI_DEV_MAP_FLAG_WRITABLE, 1319 & pVesa->VGAbase); 1320 } 1321 else { 1322 (void) pci_device_map_legacy(pVesa->pciInfo, pScrn->memPhysBase, 1323 pVesa->mapSize, 1324 PCI_DEV_MAP_FLAG_WRITABLE, 1325 & pVesa->base); 1326 1327 if (pVesa->base) 1328 pVesa->VGAbase = pVesa->base; 1329 } 1330 } 1331#else 1332 if (pVesa->mapPhys != 0xa0000 && pVesa->pEnt->location.type == BUS_PCI) 1333 pVesa->base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 1334 pVesa->pciTag, pScrn->memPhysBase, 1335 pVesa->mapSize); 1336 else 1337 pVesa->base = xf86MapDomainMemory(pScrn->scrnIndex, 0, pVesa->pciTag, 1338 pScrn->memPhysBase, pVesa->mapSize); 1339 1340 if (pVesa->base) { 1341 if (pVesa->mapPhys != 0xa0000) 1342 pVesa->VGAbase = xf86MapDomainMemory(pScrn->scrnIndex, 0, 1343 pVesa->pciTag, 1344 0xa0000, 0x10000); 1345 else 1346 pVesa->VGAbase = pVesa->base; 1347 } 1348#endif 1349 1350#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12 1351 pVesa->ioBase = pScrn->domainIOBase; 1352#else 1353 pVesa->ioBase = 0; 1354#endif 1355 1356 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, DEBUG_VERB, 1357 "virtual address = %p, VGAbase = %p\n" 1358 "\tphysical address = 0x%lx, size = %ld\n", 1359 pVesa->base, pVesa->VGAbase, 1360 pScrn->memPhysBase, pVesa->mapSize); 1361 1362 return (pVesa->base != NULL); 1363} 1364 1365static void 1366VESAUnmapVidMem(ScrnInfoPtr pScrn) 1367{ 1368 VESAPtr pVesa = VESAGetRec(pScrn); 1369 1370 if (pVesa->base == NULL) 1371 return; 1372 1373#ifdef XSERVER_LIBPCIACCESS 1374 if (pVesa->mapPhys != 0xa0000) { 1375 (void) pci_device_unmap_range(pVesa->pciInfo, pVesa->base, 1376 pVesa->mapSize); 1377 (void) pci_device_unmap_legacy(pVesa->pciInfo, pVesa->VGAbase, 1378 0x10000); 1379 } 1380 else { 1381 (void) pci_device_unmap_legacy(pVesa->pciInfo, pVesa->base, 1382 pVesa->mapSize); 1383 } 1384#else 1385 xf86UnMapVidMem(pScrn->scrnIndex, pVesa->base, pVesa->mapSize); 1386 if (pVesa->mapPhys != 0xa0000) 1387 xf86UnMapVidMem(pScrn->scrnIndex, pVesa->VGAbase, 0x10000); 1388#endif 1389 pVesa->base = NULL; 1390} 1391 1392/* This code works, but is very slow for programs that use it intensively */ 1393static void 1394VESALoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 1395 LOCO *colors, VisualPtr pVisual) 1396{ 1397 VESAPtr pVesa = VESAGetRec(pScrn); 1398 int i, idx; 1399 int base; 1400 1401 if (!pVesa->savedPal) { 1402#define VESADACDelay() \ 1403 do { \ 1404 (void)inb(pVesa->ioBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); \ 1405 (void)inb(pVesa->ioBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); \ 1406 } while (0) 1407 1408 for (i = 0; i < numColors; i++) { 1409 idx = indices[i]; 1410 outb(pVesa->ioBase + VGA_DAC_WRITE_ADDR, idx); 1411 VESADACDelay(); 1412 outb(pVesa->ioBase + VGA_DAC_DATA, colors[idx].red); 1413 VESADACDelay(); 1414 outb(pVesa->ioBase + VGA_DAC_DATA, colors[idx].green); 1415 VESADACDelay(); 1416 outb(pVesa->ioBase + VGA_DAC_DATA, colors[idx].blue); 1417 VESADACDelay(); 1418 } 1419 return; 1420 } 1421 1422 if (pVesa->pal == NULL) 1423 pVesa->pal = calloc(1, sizeof(CARD32) * 256); 1424 1425 for (i = 0, base = idx = indices[i]; i < numColors; i++, idx++) { 1426 int j = indices[i]; 1427 1428 if (j < 0 || j >= 256) 1429 continue; 1430 pVesa->pal[j] = colors[j].blue | 1431 (colors[j].green << 8) | 1432 (colors[j].red << 16); 1433 if (j != idx) { 1434 VBESetGetPaletteData(pVesa->pVbe, TRUE, base, idx - base, 1435 pVesa->pal + base, FALSE, TRUE); 1436 idx = base = j; 1437 } 1438 } 1439 1440 if (idx - 1 == indices[i - 1]) 1441 VBESetGetPaletteData(pVesa->pVbe, TRUE, base, idx - base, 1442 pVesa->pal + base, FALSE, TRUE); 1443} 1444 1445/* 1446 * Just adapted from the std* functions in vgaHW.c 1447 */ 1448static void 1449WriteAttr(VESAPtr pVesa, int index, int value) 1450{ 1451 (void) inb(pVesa->ioBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); 1452 1453 index |= 0x20; 1454 outb(pVesa->ioBase + VGA_ATTR_INDEX, index); 1455 outb(pVesa->ioBase + VGA_ATTR_DATA_W, value); 1456} 1457 1458static int 1459ReadAttr(VESAPtr pVesa, int index) 1460{ 1461 (void) inb(pVesa->ioBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); 1462 1463 index |= 0x20; 1464 outb(pVesa->ioBase + VGA_ATTR_INDEX, index); 1465 return (inb(pVesa->ioBase + VGA_ATTR_DATA_R)); 1466} 1467 1468#define WriteMiscOut(value) outb(pVesa->ioBase + VGA_MISC_OUT_W, value) 1469#define ReadMiscOut() inb(pVesa->ioBase + VGA_MISC_OUT_R) 1470#define WriteSeq(index, value) outb(pVesa->ioBase + VGA_SEQ_INDEX, index);\ 1471 outb(pVesa->ioBase + VGA_SEQ_DATA, value) 1472 1473static int 1474ReadSeq(VESAPtr pVesa, int index) 1475{ 1476 outb(pVesa->ioBase + VGA_SEQ_INDEX, index); 1477 1478 return (inb(pVesa->ioBase + VGA_SEQ_DATA)); 1479} 1480 1481#define WriteGr(index, value) \ 1482 outb(pVesa->ioBase + VGA_GRAPH_INDEX, index); \ 1483 outb(pVesa->ioBase + VGA_GRAPH_DATA, value) 1484 1485static int 1486ReadGr(VESAPtr pVesa, int index) 1487{ 1488 outb(pVesa->ioBase + VGA_GRAPH_INDEX, index); 1489 1490 return (inb(pVesa->ioBase + VGA_GRAPH_DATA)); 1491} 1492 1493#define WriteCrtc(index, value) \ 1494 outb(pVesa->ioBase + (VGA_IOBASE_COLOR + VGA_CRTC_INDEX_OFFSET), index); \ 1495 outb(pVesa->ioBase + (VGA_IOBASE_COLOR + VGA_CRTC_DATA_OFFSET), value) 1496 1497static void 1498SeqReset(VESAPtr pVesa, Bool start) 1499{ 1500 if (start) { 1501 WriteSeq(0x00, 0x01); /* Synchronous Reset */ 1502 } 1503 else { 1504 WriteSeq(0x00, 0x03); /* End Reset */ 1505 } 1506} 1507 1508static void 1509SaveFonts(ScrnInfoPtr pScrn) 1510{ 1511 VESAPtr pVesa = VESAGetRec(pScrn); 1512 unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4, scrn; 1513 1514 if (pVesa->fonts != NULL) 1515 return; 1516 1517 /* If in graphics mode, don't save anything */ 1518 attr10 = ReadAttr(pVesa, 0x10); 1519 if (attr10 & 0x01) 1520 return; 1521 1522 pVesa->fonts = malloc(16384); 1523 1524 /* save the registers that are needed here */ 1525 miscOut = ReadMiscOut(); 1526 gr4 = ReadGr(pVesa, 0x04); 1527 gr5 = ReadGr(pVesa, 0x05); 1528 gr6 = ReadGr(pVesa, 0x06); 1529 seq2 = ReadSeq(pVesa, 0x02); 1530 seq4 = ReadSeq(pVesa, 0x04); 1531 1532 /* Force into colour mode */ 1533 WriteMiscOut(miscOut | 0x01); 1534 1535 scrn = ReadSeq(pVesa, 0x01) | 0x20; 1536 SeqReset(pVesa, TRUE); 1537 WriteSeq(0x01, scrn); 1538 SeqReset(pVesa, FALSE); 1539 1540 WriteAttr(pVesa, 0x10, 0x01); /* graphics mode */ 1541 1542 /*font1 */ 1543 WriteSeq(0x02, 0x04); /* write to plane 2 */ 1544 WriteSeq(0x04, 0x06); /* enable plane graphics */ 1545 WriteGr(0x04, 0x02); /* read plane 2 */ 1546 WriteGr(0x05, 0x00); /* write mode 0, read mode 0 */ 1547 WriteGr(0x06, 0x05); /* set graphics */ 1548 slowbcopy_frombus(pVesa->VGAbase, pVesa->fonts, 8192); 1549 1550 /* font2 */ 1551 WriteSeq(0x02, 0x08); /* write to plane 3 */ 1552 WriteSeq(0x04, 0x06); /* enable plane graphics */ 1553 WriteGr(0x04, 0x03); /* read plane 3 */ 1554 WriteGr(0x05, 0x00); /* write mode 0, read mode 0 */ 1555 WriteGr(0x06, 0x05); /* set graphics */ 1556 slowbcopy_frombus(pVesa->VGAbase, pVesa->fonts + 8192, 8192); 1557 1558 scrn = ReadSeq(pVesa, 0x01) & ~0x20; 1559 SeqReset(pVesa, TRUE); 1560 WriteSeq(0x01, scrn); 1561 SeqReset(pVesa, FALSE); 1562 1563 /* Restore clobbered registers */ 1564 WriteAttr(pVesa, 0x10, attr10); 1565 WriteSeq(0x02, seq2); 1566 WriteSeq(0x04, seq4); 1567 WriteGr(0x04, gr4); 1568 WriteGr(0x05, gr5); 1569 WriteGr(0x06, gr6); 1570 WriteMiscOut(miscOut); 1571} 1572 1573static void 1574RestoreFonts(ScrnInfoPtr pScrn) 1575{ 1576 VESAPtr pVesa = VESAGetRec(pScrn); 1577 unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4, scrn; 1578 1579 if (pVesa->fonts == NULL) 1580 return; 1581 1582 if (pVesa->mapPhys == 0xa0000 && pVesa->curBank != 0) 1583 VESABankSwitch(pScrn->pScreen, 0); 1584 1585 /* save the registers that are needed here */ 1586 miscOut = ReadMiscOut(); 1587 attr10 = ReadAttr(pVesa, 0x10); 1588 gr1 = ReadGr(pVesa, 0x01); 1589 gr3 = ReadGr(pVesa, 0x03); 1590 gr4 = ReadGr(pVesa, 0x04); 1591 gr5 = ReadGr(pVesa, 0x05); 1592 gr6 = ReadGr(pVesa, 0x06); 1593 gr8 = ReadGr(pVesa, 0x08); 1594 seq2 = ReadSeq(pVesa, 0x02); 1595 seq4 = ReadSeq(pVesa, 0x04); 1596 1597 /* Force into colour mode */ 1598 WriteMiscOut(miscOut | 0x01); 1599 1600 scrn = ReadSeq(pVesa, 0x01) | 0x20; 1601 SeqReset(pVesa, TRUE); 1602 WriteSeq(0x01, scrn); 1603 SeqReset(pVesa, FALSE); 1604 1605 WriteAttr(pVesa, 0x10, 0x01); /* graphics mode */ 1606 if (pScrn->depth == 4) { 1607 /* GJA */ 1608 WriteGr(0x03, 0x00); /* don't rotate, write unmodified */ 1609 WriteGr(0x08, 0xFF); /* write all bits in a byte */ 1610 WriteGr(0x01, 0x00); /* all planes come from CPU */ 1611 } 1612 1613 WriteSeq(0x02, 0x04); /* write to plane 2 */ 1614 WriteSeq(0x04, 0x06); /* enable plane graphics */ 1615 WriteGr(0x04, 0x02); /* read plane 2 */ 1616 WriteGr(0x05, 0x00); /* write mode 0, read mode 0 */ 1617 WriteGr(0x06, 0x05); /* set graphics */ 1618 slowbcopy_tobus(pVesa->fonts, pVesa->VGAbase, 8192); 1619 1620 WriteSeq(0x02, 0x08); /* write to plane 3 */ 1621 WriteSeq(0x04, 0x06); /* enable plane graphics */ 1622 WriteGr(0x04, 0x03); /* read plane 3 */ 1623 WriteGr(0x05, 0x00); /* write mode 0, read mode 0 */ 1624 WriteGr(0x06, 0x05); /* set graphics */ 1625 slowbcopy_tobus(pVesa->fonts + 8192, pVesa->VGAbase, 8192); 1626 1627 scrn = ReadSeq(pVesa, 0x01) & ~0x20; 1628 SeqReset(pVesa, TRUE); 1629 WriteSeq(0x01, scrn); 1630 SeqReset(pVesa, FALSE); 1631 1632 /* restore the registers that were changed */ 1633 WriteMiscOut(miscOut); 1634 WriteAttr(pVesa, 0x10, attr10); 1635 WriteGr(0x01, gr1); 1636 WriteGr(0x03, gr3); 1637 WriteGr(0x04, gr4); 1638 WriteGr(0x05, gr5); 1639 WriteGr(0x06, gr6); 1640 WriteGr(0x08, gr8); 1641 WriteSeq(0x02, seq2); 1642 WriteSeq(0x04, seq4); 1643} 1644 1645static Bool 1646VESASaveScreen(ScreenPtr pScreen, int mode) 1647{ 1648 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1649 VESAPtr pVesa = VESAGetRec(pScrn); 1650 Bool on = xf86IsUnblank(mode); 1651 1652 if (on) 1653 SetTimeSinceLastInputEvent(); 1654 1655 if (pScrn->vtSema) { 1656 unsigned char scrn = ReadSeq(pVesa, 0x01); 1657 1658 if (on) 1659 scrn &= ~0x20; 1660 else 1661 scrn |= 0x20; 1662 SeqReset(pVesa, TRUE); 1663 WriteSeq(0x01, scrn); 1664 SeqReset(pVesa, FALSE); 1665 } 1666 1667 return (TRUE); 1668} 1669 1670static int 1671VESABankSwitch(ScreenPtr pScreen, unsigned int iBank) 1672{ 1673 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1674 VESAPtr pVesa = VESAGetRec(pScrn); 1675 1676 if (pVesa->curBank == iBank) 1677 return (0); 1678 if (!VBEBankSwitch(pVesa->pVbe, iBank, 0)) 1679 return (1); 1680 if (pVesa->bankSwitchWindowB) { 1681 if (!VBEBankSwitch(pVesa->pVbe, iBank, 1)) 1682 return (1); 1683 } 1684 pVesa->curBank = iBank; 1685 1686 return (0); 1687} 1688 1689Bool 1690VESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) 1691{ 1692 VESAPtr pVesa; 1693 1694 if (function < MODE_QUERY || function > MODE_RESTORE) 1695 return (FALSE); 1696 1697 pVesa = VESAGetRec(pScrn); 1698 1699 1700 /* Query amount of memory to save state */ 1701 if (function == MODE_QUERY || 1702 (function == MODE_SAVE && pVesa->state == NULL)) { 1703 1704 /* Make sure we save at least this information in case of failure */ 1705 (void)VBEGetVBEMode(pVesa->pVbe, &pVesa->stateMode); 1706 SaveFonts(pScrn); 1707 1708 if (pVesa->major > 1) { 1709 if (!VBESaveRestore(pVesa->pVbe,function,(pointer)&pVesa->state, 1710 &pVesa->stateSize,&pVesa->statePage)) 1711 return FALSE; 1712 1713 } 1714 } 1715 1716 /* Save/Restore Super VGA state */ 1717 if (function != MODE_QUERY) { 1718 Bool retval = TRUE; 1719 1720 if (pVesa->major > 1) { 1721 if (function == MODE_RESTORE) 1722 memcpy(pVesa->state, pVesa->pstate, pVesa->stateSize); 1723 1724 if ((retval = VBESaveRestore(pVesa->pVbe,function, 1725 (pointer)&pVesa->state, 1726 &pVesa->stateSize,&pVesa->statePage)) 1727 && function == MODE_SAVE) { 1728 /* don't rely on the memory not being touched */ 1729 if (pVesa->pstate == NULL) 1730 pVesa->pstate = malloc(pVesa->stateSize); 1731 memcpy(pVesa->pstate, pVesa->state, pVesa->stateSize); 1732 } 1733 } 1734 1735 if (function == MODE_RESTORE) { 1736 VBESetVBEMode(pVesa->pVbe, pVesa->stateMode, NULL); 1737 RestoreFonts(pScrn); 1738 } 1739 1740 if (!retval) 1741 return (FALSE); 1742 1743 } 1744 1745 return (TRUE); 1746} 1747 1748static void 1749VESADisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode, 1750 int flags) 1751{ 1752 VESAPtr pVesa = VESAGetRec(pScrn); 1753 1754 if (!pScrn->vtSema) 1755 return; 1756 1757 VBEDPMSSet(pVesa->pVbe, mode); 1758} 1759 1760/*********************************************************************** 1761 * DGA stuff 1762 ***********************************************************************/ 1763static Bool VESADGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, 1764 unsigned char **ApertureBase, 1765 int *ApertureSize, int *ApertureOffset, 1766 int *flags); 1767static Bool VESADGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode); 1768static void VESADGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags); 1769 1770static Bool 1771VESADGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, 1772 unsigned char **ApertureBase, int *ApertureSize, 1773 int *ApertureOffset, int *flags) 1774{ 1775 VESAPtr pVesa = VESAGetRec(pScrn); 1776 1777 *DeviceName = NULL; /* No special device */ 1778 *ApertureBase = (unsigned char *)(long)(pVesa->mapPhys); 1779 *ApertureSize = pVesa->mapSize; 1780 *ApertureOffset = pVesa->mapOff; 1781 *flags = DGA_NEED_ROOT; 1782 1783 return (TRUE); 1784} 1785 1786static Bool 1787VESADGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode) 1788{ 1789 DisplayModePtr pMode; 1790 int scrnIdx = pScrn->pScreen->myNum; 1791 int frameX0, frameY0; 1792 1793 if (pDGAMode) { 1794 pMode = pDGAMode->mode; 1795 frameX0 = frameY0 = 0; 1796 } 1797 else { 1798 if (!(pMode = pScrn->currentMode)) 1799 return (TRUE); 1800 1801 frameX0 = pScrn->frameX0; 1802 frameY0 = pScrn->frameY0; 1803 } 1804 1805 if (!(*pScrn->SwitchMode)(SWITCH_MODE_ARGS(pScrn, pMode))) 1806 return (FALSE); 1807 (*pScrn->AdjustFrame)(ADJUST_FRAME_ARGS(pScrn, frameX0, frameY0)); 1808 1809 return (TRUE); 1810} 1811 1812static void 1813VESADGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 1814{ 1815 (*pScrn->AdjustFrame)(ADJUST_FRAME_ARGS(pScrn, x, y)); 1816} 1817 1818static int 1819VESADGAGetViewport(ScrnInfoPtr pScrn) 1820{ 1821 return (0); 1822} 1823 1824static DGAFunctionRec VESADGAFunctions = 1825{ 1826 VESADGAOpenFramebuffer, 1827 NULL, /* CloseFramebuffer */ 1828 VESADGASetMode, 1829 VESADGASetViewport, 1830 VESADGAGetViewport, 1831 NULL, /* Sync */ 1832 NULL, /* FillRect */ 1833 NULL, /* BlitRect */ 1834 NULL, /* BlitTransRect */ 1835}; 1836 1837static void 1838VESADGAAddModes(ScrnInfoPtr pScrn) 1839{ 1840 VESAPtr pVesa = VESAGetRec(pScrn); 1841 DisplayModePtr pMode = pScrn->modes; 1842 DGAModePtr pDGAMode; 1843 1844 do { 1845 pDGAMode = realloc(pVesa->pDGAMode, 1846 (pVesa->nDGAMode + 1) * sizeof(DGAModeRec)); 1847 if (!pDGAMode) 1848 break; 1849 1850 pVesa->pDGAMode = pDGAMode; 1851 pDGAMode += pVesa->nDGAMode; 1852 (void)memset(pDGAMode, 0, sizeof(DGAModeRec)); 1853 1854 ++pVesa->nDGAMode; 1855 pDGAMode->mode = pMode; 1856 pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 1857 pDGAMode->byteOrder = pScrn->imageByteOrder; 1858 pDGAMode->depth = pScrn->depth; 1859 pDGAMode->bitsPerPixel = pScrn->bitsPerPixel; 1860 pDGAMode->red_mask = pScrn->mask.red; 1861 pDGAMode->green_mask = pScrn->mask.green; 1862 pDGAMode->blue_mask = pScrn->mask.blue; 1863 pDGAMode->visualClass = pScrn->bitsPerPixel > 8 ? 1864 TrueColor : PseudoColor; 1865 pDGAMode->xViewportStep = 1; 1866 pDGAMode->yViewportStep = 1; 1867 pDGAMode->viewportWidth = pMode->HDisplay; 1868 pDGAMode->viewportHeight = pMode->VDisplay; 1869 1870 pDGAMode->bytesPerScanline = pVesa->maxBytesPerScanline; 1871 pDGAMode->imageWidth = pMode->HDisplay; 1872 pDGAMode->imageHeight = pMode->VDisplay; 1873 pDGAMode->pixmapWidth = pDGAMode->imageWidth; 1874 pDGAMode->pixmapHeight = pDGAMode->imageHeight; 1875 pDGAMode->maxViewportX = pScrn->virtualX - 1876 pDGAMode->viewportWidth; 1877 pDGAMode->maxViewportY = pScrn->virtualY - 1878 pDGAMode->viewportHeight; 1879 1880 pDGAMode->address = pVesa->base; 1881 1882 pMode = pMode->next; 1883 } while (pMode != pScrn->modes); 1884} 1885 1886static Bool 1887VESADGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) 1888{ 1889 VESAPtr pVesa = VESAGetRec(pScrn); 1890 1891 if (pScrn->depth < 8 || pVesa->mapPhys == 0xa0000L) 1892 return (FALSE); 1893 1894 if (!pVesa->nDGAMode) 1895 VESADGAAddModes(pScrn); 1896 1897 return (DGAInit(pScreen, &VESADGAFunctions, 1898 pVesa->pDGAMode, pVesa->nDGAMode)); 1899} 1900