vesa.c revision 50f2e948
145bc899bSmrg#define DEBUG_VERB 2 245bc899bSmrg/* 345bc899bSmrg * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com) 450f2e948Smrg * Copyright 2008 Red Hat, Inc. 545bc899bSmrg * 645bc899bSmrg * Permission is hereby granted, free of charge, to any person obtaining a 745bc899bSmrg * copy of this software and associated documentation files (the "Software"), 845bc899bSmrg * to deal in the Software without restriction, including without limitation 945bc899bSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1045bc899bSmrg * and/or sell copies of the Software, and to permit persons to whom the 1145bc899bSmrg * Software is furnished to do so, subject to the following conditions: 1245bc899bSmrg * 1345bc899bSmrg * The above copyright notice and this permission notice shall be included in 1445bc899bSmrg * all copies or substantial portions of the Software. 1545bc899bSmrg * 1645bc899bSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1745bc899bSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1845bc899bSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1945bc899bSmrg * CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 2045bc899bSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 2145bc899bSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2245bc899bSmrg * SOFTWARE. 2345bc899bSmrg * 2445bc899bSmrg * Except as contained in this notice, the name of Conectiva Linux shall 2545bc899bSmrg * not be used in advertising or otherwise to promote the sale, use or other 2645bc899bSmrg * dealings in this Software without prior written authorization from 2745bc899bSmrg * Conectiva Linux. 2845bc899bSmrg * 2945bc899bSmrg * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br> 3045bc899bSmrg * David Dawes <dawes@xfree86.org> 3150f2e948Smrg * Adam Jackson <ajax@redhat.com> 3250f2e948Smrg */ 3350f2e948Smrg 3450f2e948Smrg/* 3550f2e948Smrg * TODO: 3650f2e948Smrg * - PanelID might give us useful size hints. 3750f2e948Smrg * - Port to RANDR 1.2 setup to make mode selection slightly better 3850f2e948Smrg * - Port to RANDR 1.2 to drop the old-school DGA junk 3950f2e948Smrg * - VBE/SCI for secondary DDC method? 4045bc899bSmrg */ 4145bc899bSmrg 4245bc899bSmrg#ifdef HAVE_CONFIG_H 4345bc899bSmrg#include "config.h" 4445bc899bSmrg#endif 4545bc899bSmrg 4645bc899bSmrg#include <string.h> 4745bc899bSmrg 4845bc899bSmrg#include "vesa.h" 4945bc899bSmrg 5045bc899bSmrg/* All drivers initialising the SW cursor need this */ 5145bc899bSmrg#include "mipointer.h" 5245bc899bSmrg 5345bc899bSmrg/* All drivers implementing backing store need this */ 5445bc899bSmrg#include "mibstore.h" 5545bc899bSmrg 5645bc899bSmrg/* Colormap handling */ 5745bc899bSmrg#include "micmap.h" 5845bc899bSmrg#include "xf86cmap.h" 5950f2e948Smrg#include "xf86Modes.h" 6045bc899bSmrg 6145bc899bSmrg/* DPMS */ 6245bc899bSmrg#define DPMS_SERVER 6345bc899bSmrg#include <X11/extensions/dpms.h> 6445bc899bSmrg 6545bc899bSmrg/* Mandatory functions */ 6645bc899bSmrgstatic const OptionInfoRec * VESAAvailableOptions(int chipid, int busid); 6745bc899bSmrgstatic void VESAIdentify(int flags); 6845bc899bSmrgstatic Bool VESAProbe(DriverPtr drv, int flags); 6950f2e948Smrg#ifdef XSERVER_LIBPCIACCESS 7050f2e948Smrgstatic Bool VESAPciProbe(DriverPtr drv, int entity_num, 7150f2e948Smrg struct pci_device *dev, intptr_t match_data); 7250f2e948Smrg#endif 7345bc899bSmrgstatic Bool VESAPreInit(ScrnInfoPtr pScrn, int flags); 7445bc899bSmrgstatic Bool VESAScreenInit(int Index, ScreenPtr pScreen, int argc, 7545bc899bSmrg char **argv); 7645bc899bSmrgstatic Bool VESAEnterVT(int scrnIndex, int flags); 7745bc899bSmrgstatic void VESALeaveVT(int scrnIndex, int flags); 7845bc899bSmrgstatic Bool VESACloseScreen(int scrnIndex, ScreenPtr pScreen); 7945bc899bSmrgstatic Bool VESASaveScreen(ScreenPtr pScreen, int mode); 8045bc899bSmrg 8145bc899bSmrgstatic Bool VESASwitchMode(int scrnIndex, DisplayModePtr pMode, int flags); 8245bc899bSmrgstatic Bool VESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode); 8345bc899bSmrgstatic void VESAAdjustFrame(int scrnIndex, int x, int y, int flags); 8445bc899bSmrgstatic void VESAFreeScreen(int scrnIndex, int flags); 8545bc899bSmrgstatic void VESAFreeRec(ScrnInfoPtr pScrn); 8650f2e948Smrgstatic VESAPtr VESAGetRec(ScrnInfoPtr pScrn); 8745bc899bSmrg 8845bc899bSmrgstatic void 8945bc899bSmrgVESADisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode, 9045bc899bSmrg int flags); 9145bc899bSmrg 9245bc899bSmrg/* locally used functions */ 9345bc899bSmrgstatic int VESAFindIsaDevice(GDevPtr dev); 9445bc899bSmrgstatic Bool VESAMapVidMem(ScrnInfoPtr pScrn); 9545bc899bSmrgstatic void VESAUnmapVidMem(ScrnInfoPtr pScrn); 9645bc899bSmrgstatic int VESABankSwitch(ScreenPtr pScreen, unsigned int iBank); 9745bc899bSmrgstatic void VESALoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 9845bc899bSmrg LOCO *colors, VisualPtr pVisual); 9945bc899bSmrgstatic void SaveFonts(ScrnInfoPtr pScrn); 10045bc899bSmrgstatic void RestoreFonts(ScrnInfoPtr pScrn); 10145bc899bSmrgstatic Bool 10245bc899bSmrgVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function); 10345bc899bSmrg 10445bc899bSmrgstatic void *VESAWindowLinear(ScreenPtr pScrn, CARD32 row, CARD32 offset, 10545bc899bSmrg int mode, CARD32 *size, void *closure); 10645bc899bSmrgstatic void *VESAWindowWindowed(ScreenPtr pScrn, CARD32 row, CARD32 offset, 10745bc899bSmrg int mode, CARD32 *size, void *closure); 10845bc899bSmrg 10945bc899bSmrgstatic Bool VESADGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen); 11045bc899bSmrg 11145bc899bSmrgenum GenericTypes 11245bc899bSmrg{ 11345bc899bSmrg CHIP_VESA_GENERIC 11445bc899bSmrg}; 11545bc899bSmrg 11650f2e948Smrg#ifdef XSERVER_LIBPCIACCESS 11750f2e948Smrgstatic const struct pci_id_match vesa_device_match[] = { 11850f2e948Smrg { 11950f2e948Smrg PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 12050f2e948Smrg 0x00030000, 0x00ffffff, CHIP_VESA_GENERIC 12150f2e948Smrg }, 12250f2e948Smrg 12350f2e948Smrg { 0, 0, 0 }, 12450f2e948Smrg}; 12550f2e948Smrg#endif 12650f2e948Smrg 12745bc899bSmrg/* Supported chipsets */ 12845bc899bSmrgstatic SymTabRec VESAChipsets[] = 12945bc899bSmrg{ 13045bc899bSmrg {CHIP_VESA_GENERIC, "vesa"}, 13145bc899bSmrg {-1, NULL} 13245bc899bSmrg}; 13345bc899bSmrg 13450f2e948Smrg#ifndef XSERVER_LIBPCIACCESS 13545bc899bSmrgstatic PciChipsets VESAPCIchipsets[] = { 13645bc899bSmrg { CHIP_VESA_GENERIC, PCI_CHIP_VGA, RES_SHARED_VGA }, 13745bc899bSmrg { -1, -1, RES_UNDEFINED }, 13845bc899bSmrg}; 13950f2e948Smrg#endif 14045bc899bSmrg 14150f2e948Smrg#ifdef HAVE_ISA 14245bc899bSmrgstatic IsaChipsets VESAISAchipsets[] = { 14345bc899bSmrg {CHIP_VESA_GENERIC, RES_EXCLUSIVE_VGA}, 14445bc899bSmrg {-1, 0 } 14545bc899bSmrg}; 14650f2e948Smrg#endif 14750f2e948Smrg 14850f2e948Smrg 14950f2e948Smrg/* 15050f2e948Smrg * This contains the functions needed by the server after loading the 15150f2e948Smrg * driver module. It must be supplied, and gets added the driver list by 15250f2e948Smrg * the Module Setup funtion in the dynamic case. In the static case a 15350f2e948Smrg * reference to this is compiled in, and this requires that the name of 15450f2e948Smrg * this DriverRec be an upper-case version of the driver name. 15550f2e948Smrg */ 15650f2e948Smrg_X_EXPORT DriverRec VESA = { 15750f2e948Smrg VESA_VERSION, 15850f2e948Smrg VESA_DRIVER_NAME, 15950f2e948Smrg VESAIdentify, 16050f2e948Smrg VESAProbe, 16150f2e948Smrg VESAAvailableOptions, 16250f2e948Smrg NULL, 16350f2e948Smrg 0, 16450f2e948Smrg NULL, 16550f2e948Smrg 16650f2e948Smrg#ifdef XSERVER_LIBPCIACCESS 16750f2e948Smrg vesa_device_match, 16850f2e948Smrg VESAPciProbe 16950f2e948Smrg#endif 17050f2e948Smrg}; 17150f2e948Smrg 17245bc899bSmrg 17345bc899bSmrgtypedef enum { 17445bc899bSmrg OPTION_SHADOW_FB, 17545bc899bSmrg OPTION_DFLT_REFRESH, 17645bc899bSmrg OPTION_MODESET_CLEAR_SCREEN 17745bc899bSmrg} VESAOpts; 17845bc899bSmrg 17945bc899bSmrgstatic const OptionInfoRec VESAOptions[] = { 18045bc899bSmrg { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 18145bc899bSmrg { OPTION_DFLT_REFRESH, "DefaultRefresh", OPTV_BOOLEAN, {0}, FALSE }, 18245bc899bSmrg { OPTION_MODESET_CLEAR_SCREEN, "ModeSetClearScreen", 18345bc899bSmrg OPTV_BOOLEAN, {0}, FALSE }, 18445bc899bSmrg { -1, NULL, OPTV_NONE, {0}, FALSE } 18545bc899bSmrg}; 18645bc899bSmrg 18745bc899bSmrg#ifdef XFree86LOADER 18845bc899bSmrg 18945bc899bSmrg/* Module loader interface */ 19045bc899bSmrgstatic MODULESETUPPROTO(vesaSetup); 19145bc899bSmrg 19245bc899bSmrgstatic XF86ModuleVersionInfo vesaVersionRec = 19345bc899bSmrg{ 19445bc899bSmrg VESA_DRIVER_NAME, 19545bc899bSmrg MODULEVENDORSTRING, 19645bc899bSmrg MODINFOSTRING1, 19745bc899bSmrg MODINFOSTRING2, 19845bc899bSmrg XORG_VERSION_CURRENT, 19945bc899bSmrg VESA_MAJOR_VERSION, VESA_MINOR_VERSION, VESA_PATCHLEVEL, 20045bc899bSmrg ABI_CLASS_VIDEODRV, /* This is a video driver */ 20145bc899bSmrg ABI_VIDEODRV_VERSION, 20245bc899bSmrg MOD_CLASS_VIDEODRV, 20345bc899bSmrg {0, 0, 0, 0} 20445bc899bSmrg}; 20545bc899bSmrg 20645bc899bSmrg/* 20745bc899bSmrg * This data is accessed by the loader. The name must be the module name 20845bc899bSmrg * followed by "ModuleData". 20945bc899bSmrg */ 21045bc899bSmrg_X_EXPORT XF86ModuleData vesaModuleData = { &vesaVersionRec, vesaSetup, NULL }; 21145bc899bSmrg 21245bc899bSmrgstatic pointer 21345bc899bSmrgvesaSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) 21445bc899bSmrg{ 21545bc899bSmrg static Bool Initialised = FALSE; 21645bc899bSmrg 21745bc899bSmrg if (!Initialised) 21845bc899bSmrg { 21945bc899bSmrg Initialised = TRUE; 22050f2e948Smrg xf86AddDriver(&VESA, Module, 1); 22145bc899bSmrg return (pointer)TRUE; 22245bc899bSmrg } 22345bc899bSmrg 22445bc899bSmrg if (ErrorMajor) 22545bc899bSmrg *ErrorMajor = LDR_ONCEONLY; 22645bc899bSmrg return (NULL); 22745bc899bSmrg} 22845bc899bSmrg 22945bc899bSmrg#endif 23045bc899bSmrg 23145bc899bSmrgstatic const OptionInfoRec * 23245bc899bSmrgVESAAvailableOptions(int chipid, int busid) 23345bc899bSmrg{ 23445bc899bSmrg return (VESAOptions); 23545bc899bSmrg} 23645bc899bSmrg 23745bc899bSmrgstatic void 23845bc899bSmrgVESAIdentify(int flags) 23945bc899bSmrg{ 24045bc899bSmrg xf86PrintChipsets(VESA_NAME, "driver for VESA chipsets", VESAChipsets); 24145bc899bSmrg} 24245bc899bSmrg 24350f2e948Smrgstatic VESAPtr 24450f2e948SmrgVESAGetRec(ScrnInfoPtr pScrn) 24550f2e948Smrg{ 24650f2e948Smrg if (!pScrn->driverPrivate) 24750f2e948Smrg pScrn->driverPrivate = xcalloc(sizeof(VESARec), 1); 24850f2e948Smrg 24950f2e948Smrg return ((VESAPtr)pScrn->driverPrivate); 25050f2e948Smrg} 25150f2e948Smrg 25250f2e948Smrg/* Only a little like VBESetModeParameters */ 25350f2e948Smrgstatic void 25450f2e948SmrgVESASetModeParameters(vbeInfoPtr pVbe, DisplayModePtr vbemode, 25550f2e948Smrg DisplayModePtr ddcmode) 25650f2e948Smrg{ 25750f2e948Smrg VbeModeInfoData *data; 25850f2e948Smrg int clock; 25950f2e948Smrg 26050f2e948Smrg data = (VbeModeInfoData *)vbemode->Private; 26150f2e948Smrg 26250f2e948Smrg data->block = xcalloc(sizeof(VbeCRTCInfoBlock), 1); 26350f2e948Smrg data->block->HorizontalTotal = ddcmode->HTotal; 26450f2e948Smrg data->block->HorizontalSyncStart = ddcmode->HSyncStart; 26550f2e948Smrg data->block->HorizontalSyncEnd = ddcmode->HSyncEnd; 26650f2e948Smrg data->block->VerticalTotal = ddcmode->VTotal; 26750f2e948Smrg data->block->VerticalSyncStart = ddcmode->VSyncStart; 26850f2e948Smrg data->block->VerticalSyncEnd = ddcmode->VSyncEnd; 26950f2e948Smrg data->block->Flags = ((ddcmode->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) | 27050f2e948Smrg ((ddcmode->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0); 27150f2e948Smrg data->block->PixelClock = ddcmode->Clock * 1000; 27250f2e948Smrg 27350f2e948Smrg /* ask the BIOS to figure out the real clock */ 27450f2e948Smrg clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock); 27550f2e948Smrg if (clock) 27650f2e948Smrg data->block->PixelClock = clock; 27750f2e948Smrg 27850f2e948Smrg data->mode |= (1 << 11); 27950f2e948Smrg data->block->RefreshRate = 100 * ((double)(data->block->PixelClock) / 28050f2e948Smrg (double)(ddcmode->HTotal * ddcmode->VTotal)); 28150f2e948Smrg} 28250f2e948Smrg 28350f2e948Smrgstatic ModeStatus 28450f2e948SmrgVESAValidMode(int scrn, DisplayModePtr p, Bool flag, int pass) 28550f2e948Smrg{ 28650f2e948Smrg static int warned = 0; 28750f2e948Smrg int found = 0; 28850f2e948Smrg ScrnInfoPtr pScrn = xf86Screens[scrn]; 28950f2e948Smrg VESAPtr pVesa = VESAGetRec(pScrn); 29050f2e948Smrg MonPtr mon = pScrn->monitor; 29150f2e948Smrg ModeStatus ret = MODE_BAD; 29250f2e948Smrg DisplayModePtr mode; 29350f2e948Smrg float v; 29450f2e948Smrg 29550f2e948Smrg pVesa = VESAGetRec(pScrn); 29650f2e948Smrg 29750f2e948Smrg if (pass != MODECHECK_FINAL) { 29850f2e948Smrg if (!warned) { 29950f2e948Smrg xf86DrvMsg(scrn, X_WARNING, "VESAValidMode called unexpectedly\n"); 30050f2e948Smrg warned = 1; 30150f2e948Smrg } 30250f2e948Smrg return MODE_OK; 30350f2e948Smrg } 30450f2e948Smrg 30550f2e948Smrg /* 30650f2e948Smrg * This is suboptimal. We pass in just the barest description of a mode 30750f2e948Smrg * we can get away with to VBEValidateModes, so it can't really throw 30850f2e948Smrg * out anything we give it. But we need to filter the list so that we 30950f2e948Smrg * don't populate the mode list with things the monitor can't do. 31050f2e948Smrg * 31150f2e948Smrg * So first off, if this isn't a mode we handed to the server (ie, 31250f2e948Smrg * M_T_BUILTIN), then we know we can't do it. 31350f2e948Smrg */ 31450f2e948Smrg if (!(p->type & M_T_BUILTIN)) 31550f2e948Smrg return MODE_NOMODE; 31650f2e948Smrg 31750f2e948Smrg if (pVesa->strict_validation) { 31850f2e948Smrg /* 31950f2e948Smrg * If it's our first pass at mode validation, we'll try for a strict 32050f2e948Smrg * intersection between the VBE and DDC mode lists. 32150f2e948Smrg */ 32250f2e948Smrg if (pScrn->monitor->DDC) { 32350f2e948Smrg for (mode = pScrn->monitor->Modes; mode; mode = mode->next) { 32450f2e948Smrg if (mode->type & M_T_DRIVER && 32550f2e948Smrg mode->HDisplay == p->HDisplay && 32650f2e948Smrg mode->VDisplay == p->VDisplay) { 32750f2e948Smrg if (xf86CheckModeForMonitor(mode, mon) == MODE_OK) { 32850f2e948Smrg found = 1; 32950f2e948Smrg break; 33050f2e948Smrg } 33150f2e948Smrg } 33250f2e948Smrg if (mode == pScrn->monitor->Last) 33350f2e948Smrg break; 33450f2e948Smrg } 33550f2e948Smrg if (!found) 33650f2e948Smrg return MODE_NOMODE; 33750f2e948Smrg 33850f2e948Smrg /* having found a matching mode, stash the CRTC values aside */ 33950f2e948Smrg VESASetModeParameters(pVesa->pVbe, p, mode); 34050f2e948Smrg return MODE_OK; 34150f2e948Smrg } 34250f2e948Smrg 34350f2e948Smrg /* No DDC and no modes make Homer something something... */ 34450f2e948Smrg return MODE_NOMODE; 34550f2e948Smrg } 34650f2e948Smrg 34750f2e948Smrg /* 34850f2e948Smrg * Finally, walk through the vsync rates 1Hz at a time looking for a mode 34950f2e948Smrg * that will fit. This is assuredly a terrible way to do this, but 35050f2e948Smrg * there's no obvious method for computing a mode of a given size that 35150f2e948Smrg * will pass xf86CheckModeForMonitor. XXX this path is terrible, but 35250f2e948Smrg * then, by this point, you're well into despair territory. 35350f2e948Smrg */ 35450f2e948Smrg for (v = mon->vrefresh[0].lo; v <= mon->vrefresh[0].hi; v++) { 35550f2e948Smrg mode = xf86GTFMode(p->HDisplay, p->VDisplay, v, 0, 0); 35650f2e948Smrg ret = xf86CheckModeForMonitor(mode, mon); 35750f2e948Smrg xfree(mode); 35850f2e948Smrg if (ret == MODE_OK) 35950f2e948Smrg break; 36050f2e948Smrg } 36150f2e948Smrg 36250f2e948Smrg return ret; 36350f2e948Smrg} 36450f2e948Smrg 36550f2e948Smrgstatic void 36650f2e948SmrgVESAInitScrn(ScrnInfoPtr pScrn) 36750f2e948Smrg{ 36850f2e948Smrg pScrn->driverVersion = VESA_VERSION; 36950f2e948Smrg pScrn->driverName = VESA_DRIVER_NAME; 37050f2e948Smrg pScrn->name = VESA_NAME; 37150f2e948Smrg pScrn->Probe = VESAProbe; 37250f2e948Smrg pScrn->PreInit = VESAPreInit; 37350f2e948Smrg pScrn->ScreenInit = VESAScreenInit; 37450f2e948Smrg pScrn->SwitchMode = VESASwitchMode; 37550f2e948Smrg pScrn->ValidMode = VESAValidMode; 37650f2e948Smrg pScrn->AdjustFrame = VESAAdjustFrame; 37750f2e948Smrg pScrn->EnterVT = VESAEnterVT; 37850f2e948Smrg pScrn->LeaveVT = VESALeaveVT; 37950f2e948Smrg pScrn->FreeScreen = VESAFreeScreen; 38050f2e948Smrg} 38150f2e948Smrg 38245bc899bSmrg/* 38345bc899bSmrg * This function is called once, at the start of the first server generation to 38445bc899bSmrg * do a minimal probe for supported hardware. 38545bc899bSmrg */ 38645bc899bSmrg 38750f2e948Smrg#ifdef XSERVER_LIBPCIACCESS 38850f2e948Smrgstatic Bool 38950f2e948SmrgVESAPciProbe(DriverPtr drv, int entity_num, struct pci_device *dev, 39050f2e948Smrg intptr_t match_data) 39150f2e948Smrg{ 39250f2e948Smrg ScrnInfoPtr pScrn; 39350f2e948Smrg 39450f2e948Smrg pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL, 39550f2e948Smrg NULL, NULL, NULL, NULL, NULL); 39650f2e948Smrg if (pScrn != NULL) { 39750f2e948Smrg VESAPtr pVesa = VESAGetRec(pScrn); 39850f2e948Smrg 39950f2e948Smrg VESAInitScrn(pScrn); 40050f2e948Smrg pVesa->pciInfo = dev; 40150f2e948Smrg } 40250f2e948Smrg 40350f2e948Smrg return (pScrn != NULL); 40450f2e948Smrg} 40550f2e948Smrg#endif 40650f2e948Smrg 40745bc899bSmrgstatic Bool 40845bc899bSmrgVESAProbe(DriverPtr drv, int flags) 40945bc899bSmrg{ 41045bc899bSmrg Bool foundScreen = FALSE; 41145bc899bSmrg int numDevSections, numUsed; 41245bc899bSmrg GDevPtr *devSections; 41345bc899bSmrg int *usedChips; 41445bc899bSmrg int i; 41545bc899bSmrg 41645bc899bSmrg /* 41745bc899bSmrg * Find the config file Device sections that match this 41845bc899bSmrg * driver, and return if there are none. 41945bc899bSmrg */ 42045bc899bSmrg if ((numDevSections = xf86MatchDevice(VESA_NAME, 42145bc899bSmrg &devSections)) <= 0) 42245bc899bSmrg return (FALSE); 42345bc899bSmrg 42450f2e948Smrg#ifndef XSERVER_LIBPCIACCESS 42545bc899bSmrg /* PCI BUS */ 42645bc899bSmrg if (xf86GetPciVideoInfo()) { 42745bc899bSmrg numUsed = xf86MatchPciInstances(VESA_NAME, PCI_VENDOR_GENERIC, 42845bc899bSmrg VESAChipsets, VESAPCIchipsets, 42945bc899bSmrg devSections, numDevSections, 43045bc899bSmrg drv, &usedChips); 43145bc899bSmrg if (numUsed > 0) { 43245bc899bSmrg if (flags & PROBE_DETECT) 43345bc899bSmrg foundScreen = TRUE; 43445bc899bSmrg else { 43545bc899bSmrg for (i = 0; i < numUsed; i++) { 43645bc899bSmrg ScrnInfoPtr pScrn = NULL; 43745bc899bSmrg /* Allocate a ScrnInfoRec */ 43845bc899bSmrg if ((pScrn = xf86ConfigPciEntity(pScrn,0,usedChips[i], 43945bc899bSmrg VESAPCIchipsets,NULL, 44045bc899bSmrg NULL,NULL,NULL,NULL))) { 44150f2e948Smrg VESAInitScrn(pScrn); 44245bc899bSmrg foundScreen = TRUE; 44345bc899bSmrg } 44445bc899bSmrg } 44545bc899bSmrg } 44645bc899bSmrg xfree(usedChips); 44745bc899bSmrg } 44845bc899bSmrg } 44950f2e948Smrg#endif 45045bc899bSmrg 45150f2e948Smrg#ifdef HAVE_ISA 45245bc899bSmrg /* Isa Bus */ 45345bc899bSmrg numUsed = xf86MatchIsaInstances(VESA_NAME,VESAChipsets, 45445bc899bSmrg VESAISAchipsets, drv, 45545bc899bSmrg VESAFindIsaDevice, devSections, 45645bc899bSmrg numDevSections, &usedChips); 45745bc899bSmrg if(numUsed > 0) { 45845bc899bSmrg if (flags & PROBE_DETECT) 45945bc899bSmrg foundScreen = TRUE; 46045bc899bSmrg else for (i = 0; i < numUsed; i++) { 46145bc899bSmrg ScrnInfoPtr pScrn = NULL; 46245bc899bSmrg if ((pScrn = xf86ConfigIsaEntity(pScrn, 0,usedChips[i], 46345bc899bSmrg VESAISAchipsets, NULL, 46445bc899bSmrg NULL, NULL, NULL, NULL))) { 46550f2e948Smrg VESAInitScrn(pScrn); 46645bc899bSmrg foundScreen = TRUE; 46745bc899bSmrg } 46845bc899bSmrg } 46945bc899bSmrg xfree(usedChips); 47045bc899bSmrg } 47150f2e948Smrg#endif 47245bc899bSmrg 47345bc899bSmrg xfree(devSections); 47445bc899bSmrg 47545bc899bSmrg return (foundScreen); 47645bc899bSmrg} 47745bc899bSmrg 47850f2e948Smrg#ifdef HAVE_ISA 47945bc899bSmrgstatic int 48045bc899bSmrgVESAFindIsaDevice(GDevPtr dev) 48145bc899bSmrg{ 48245bc899bSmrg#ifndef PC98_EGC 48345bc899bSmrg CARD16 GenericIOBase = VGAHW_GET_IOBASE(); 48445bc899bSmrg CARD8 CurrentValue, TestValue; 48545bc899bSmrg 48645bc899bSmrg /* There's no need to unlock VGA CRTC registers here */ 48745bc899bSmrg 48845bc899bSmrg /* VGA has one more read/write attribute register than EGA */ 48945bc899bSmrg (void) inb(GenericIOBase + VGA_IN_STAT_1_OFFSET); /* Reset flip-flop */ 49045bc899bSmrg outb(VGA_ATTR_INDEX, 0x14 | 0x20); 49145bc899bSmrg CurrentValue = inb(VGA_ATTR_DATA_R); 49245bc899bSmrg outb(VGA_ATTR_DATA_W, CurrentValue ^ 0x0F); 49345bc899bSmrg outb(VGA_ATTR_INDEX, 0x14 | 0x20); 49445bc899bSmrg TestValue = inb(VGA_ATTR_DATA_R); 49545bc899bSmrg outb(VGA_ATTR_DATA_R, CurrentValue); 49645bc899bSmrg 49745bc899bSmrg /* Quit now if no VGA is present */ 49845bc899bSmrg if ((CurrentValue ^ 0x0F) != TestValue) 49945bc899bSmrg return -1; 50045bc899bSmrg#endif 50145bc899bSmrg return (int)CHIP_VESA_GENERIC; 50245bc899bSmrg} 50350f2e948Smrg#endif 50445bc899bSmrg 50545bc899bSmrgstatic void 50645bc899bSmrgVESAFreeRec(ScrnInfoPtr pScrn) 50745bc899bSmrg{ 50845bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 50945bc899bSmrg#if 0 51045bc899bSmrg DisplayModePtr mode = pScrn->modes; 51145bc899bSmrg /* I am not sure if the modes will ever get freed. 51245bc899bSmrg * Anyway, the data unknown to other modules is being freed here. 51345bc899bSmrg */ 51445bc899bSmrg if (mode) { 51545bc899bSmrg do { 51645bc899bSmrg if (mode->Private) { 51745bc899bSmrg VbeModeInfoData *data = (VbeModeInfoData*)mode->Private; 51845bc899bSmrg 51945bc899bSmrg if (data->block) 52045bc899bSmrg xfree(data->block); 52145bc899bSmrg 52245bc899bSmrg xfree(data); 52345bc899bSmrg 52445bc899bSmrg mode->Private = NULL; 52545bc899bSmrg } 52645bc899bSmrg mode = mode->next; 52745bc899bSmrg } while (mode && mode != pScrn->modes); 52845bc899bSmrg } 52945bc899bSmrg#endif 53045bc899bSmrg xfree(pVesa->monitor); 53145bc899bSmrg xfree(pVesa->vbeInfo); 53245bc899bSmrg xfree(pVesa->pal); 53345bc899bSmrg xfree(pVesa->savedPal); 53445bc899bSmrg xfree(pVesa->fonts); 53545bc899bSmrg xfree(pScrn->driverPrivate); 53645bc899bSmrg pScrn->driverPrivate = NULL; 53745bc899bSmrg} 53845bc899bSmrg 53950f2e948Smrgstatic int 54050f2e948SmrgVESAValidateModes(ScrnInfoPtr pScrn) 54150f2e948Smrg{ 54250f2e948Smrg VESAPtr pVesa = VESAGetRec(pScrn); 54350f2e948Smrg DisplayModePtr mode; 54450f2e948Smrg 54550f2e948Smrg for (mode = pScrn->monitor->Modes; mode; mode = mode->next) 54650f2e948Smrg mode->status = MODE_OK; 54750f2e948Smrg 54850f2e948Smrg return VBEValidateModes(pScrn, NULL, pScrn->display->modes, 54950f2e948Smrg NULL, NULL, 0, 2048, 1, 0, 2048, 55050f2e948Smrg pScrn->display->virtualX, 55150f2e948Smrg pScrn->display->virtualY, 55250f2e948Smrg pVesa->mapSize, LOOKUP_BEST_REFRESH); 55350f2e948Smrg} 55450f2e948Smrg 55545bc899bSmrg/* 55645bc899bSmrg * This function is called once for each screen at the start of the first 55745bc899bSmrg * server generation to initialise the screen for all server generations. 55845bc899bSmrg */ 55945bc899bSmrgstatic Bool 56045bc899bSmrgVESAPreInit(ScrnInfoPtr pScrn, int flags) 56145bc899bSmrg{ 56245bc899bSmrg VESAPtr pVesa; 56345bc899bSmrg VbeInfoBlock *vbe; 56445bc899bSmrg DisplayModePtr pMode; 56545bc899bSmrg VbeModeInfoBlock *mode; 56645bc899bSmrg Gamma gzeros = {0.0, 0.0, 0.0}; 56745bc899bSmrg rgb rzeros = {0, 0, 0}; 56845bc899bSmrg pointer pDDCModule; 56945bc899bSmrg int i; 57045bc899bSmrg int flags24 = 0; 57145bc899bSmrg int defaultDepth = 0; 57250f2e948Smrg int defaultBpp = 0; 57345bc899bSmrg int depths = 0; 57445bc899bSmrg 57545bc899bSmrg if (flags & PROBE_DETECT) 57645bc899bSmrg return (FALSE); 57745bc899bSmrg 57845bc899bSmrg pVesa = VESAGetRec(pScrn); 57945bc899bSmrg pVesa->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 58045bc899bSmrg 58145bc899bSmrg /* Load vbe module */ 58245bc899bSmrg if (!xf86LoadSubModule(pScrn, "vbe")) 58345bc899bSmrg return (FALSE); 58445bc899bSmrg 58545bc899bSmrg if ((pVesa->pVbe = VBEExtendedInit(NULL, pVesa->pEnt->index, 58645bc899bSmrg SET_BIOS_SCRATCH 58745bc899bSmrg | RESTORE_BIOS_SCRATCH)) == NULL) 58845bc899bSmrg return (FALSE); 58945bc899bSmrg 59050f2e948Smrg#ifndef XSERVER_LIBPCIACCESS 59145bc899bSmrg if (pVesa->pEnt->location.type == BUS_PCI) { 59245bc899bSmrg pVesa->pciInfo = xf86GetPciInfoForEntity(pVesa->pEnt->index); 59345bc899bSmrg pVesa->pciTag = pciTag(pVesa->pciInfo->bus, pVesa->pciInfo->device, 59445bc899bSmrg pVesa->pciInfo->func); 59545bc899bSmrg } 59650f2e948Smrg#endif 59745bc899bSmrg 59845bc899bSmrg pScrn->chipset = "vesa"; 59945bc899bSmrg pScrn->monitor = pScrn->confScreen->monitor; 60045bc899bSmrg pScrn->progClock = TRUE; 60145bc899bSmrg pScrn->rgbBits = 8; 60245bc899bSmrg 60345bc899bSmrg if ((vbe = VBEGetVBEInfo(pVesa->pVbe)) == NULL) 60445bc899bSmrg return (FALSE); 60545bc899bSmrg pVesa->major = (unsigned)(vbe->VESAVersion >> 8); 60645bc899bSmrg pVesa->minor = vbe->VESAVersion & 0xff; 60745bc899bSmrg pVesa->vbeInfo = vbe; 60845bc899bSmrg pScrn->videoRam = vbe->TotalMemory * 64; 60945bc899bSmrg 61045bc899bSmrg /* 61145bc899bSmrg * Find what depths are available. 61245bc899bSmrg */ 61345bc899bSmrg depths = VBEFindSupportedDepths(pVesa->pVbe, pVesa->vbeInfo, &flags24, 61445bc899bSmrg V_MODETYPE_VBE); 61545bc899bSmrg 61645bc899bSmrg /* Preferred order for default depth selection. */ 61750f2e948Smrg if (depths & V_DEPTH_24) 61850f2e948Smrg defaultDepth = 24; 61950f2e948Smrg else if (depths & V_DEPTH_16) 62045bc899bSmrg defaultDepth = 16; 62145bc899bSmrg else if (depths & V_DEPTH_15) 62245bc899bSmrg defaultDepth = 15; 62345bc899bSmrg else if (depths & V_DEPTH_8) 62445bc899bSmrg defaultDepth = 8; 62545bc899bSmrg else if (depths & V_DEPTH_4) 62645bc899bSmrg defaultDepth = 4; 62745bc899bSmrg else if (depths & V_DEPTH_1) 62845bc899bSmrg defaultDepth = 1; 62945bc899bSmrg 63050f2e948Smrg if (defaultDepth == 24 && !(flags24 & Support32bppFb)) 63150f2e948Smrg defaultBpp = 24; 63245bc899bSmrg 63350f2e948Smrg /* Prefer 32bpp because 1999 called and wants its packed pixels back */ 63450f2e948Smrg if (flags24 & Support32bppFb) 63550f2e948Smrg flags24 |= SupportConvert24to32 | PreferConvert24to32; 63645bc899bSmrg if (flags24 & Support24bppFb) 63750f2e948Smrg flags24 |= SupportConvert32to24; 63845bc899bSmrg 63950f2e948Smrg if (!xf86SetDepthBpp(pScrn, defaultDepth, 0, defaultBpp, flags24)) { 64045bc899bSmrg vbeFree(pVesa->pVbe); 64145bc899bSmrg return (FALSE); 64245bc899bSmrg } 64345bc899bSmrg xf86PrintDepthBpp(pScrn); 64445bc899bSmrg 64545bc899bSmrg /* color weight */ 64645bc899bSmrg if (pScrn->depth > 8 && !xf86SetWeight(pScrn, rzeros, rzeros)) { 64745bc899bSmrg vbeFree(pVesa->pVbe); 64845bc899bSmrg return (FALSE); 64945bc899bSmrg } 65045bc899bSmrg /* visual init */ 65145bc899bSmrg if (!xf86SetDefaultVisual(pScrn, -1)) { 65245bc899bSmrg vbeFree(pVesa->pVbe); 65345bc899bSmrg return (FALSE); 65445bc899bSmrg } 65545bc899bSmrg 65645bc899bSmrg xf86SetGamma(pScrn, gzeros); 65745bc899bSmrg 65845bc899bSmrg if (pVesa->major >= 2) { 65945bc899bSmrg /* Load ddc module */ 66045bc899bSmrg if ((pDDCModule = xf86LoadSubModule(pScrn, "ddc")) == NULL) { 66145bc899bSmrg vbeFree(pVesa->pVbe); 66245bc899bSmrg return (FALSE); 66345bc899bSmrg } 66445bc899bSmrg 66545bc899bSmrg if ((pVesa->monitor = vbeDoEDID(pVesa->pVbe, pDDCModule)) != NULL) { 66645bc899bSmrg xf86PrintEDID(pVesa->monitor); 66745bc899bSmrg } 66845bc899bSmrg 66945bc899bSmrg xf86UnloadSubModule(pDDCModule); 67045bc899bSmrg } 67145bc899bSmrg 67245bc899bSmrg if ((pScrn->monitor->DDC = pVesa->monitor) != NULL) 67345bc899bSmrg xf86SetDDCproperties(pScrn, pVesa->monitor); 67445bc899bSmrg 67545bc899bSmrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, DEBUG_VERB, 67645bc899bSmrg "Searching for matching VESA mode(s):\n"); 67745bc899bSmrg 67845bc899bSmrg /* 67945bc899bSmrg * Check the available BIOS modes, and extract those that match the 68045bc899bSmrg * requirements into the modePool. Note: modePool is a NULL-terminated 68145bc899bSmrg * list. 68245bc899bSmrg */ 68345bc899bSmrg pScrn->modePool = VBEGetModePool (pScrn, pVesa->pVbe, pVesa->vbeInfo, 68445bc899bSmrg V_MODETYPE_VBE); 68545bc899bSmrg 68645bc899bSmrg xf86ErrorFVerb(DEBUG_VERB, "\n"); 68745bc899bSmrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, DEBUG_VERB, 68845bc899bSmrg "Total Memory: %d 64KB banks (%dkB)\n", vbe->TotalMemory, 68945bc899bSmrg (vbe->TotalMemory * 65536) / 1024); 69045bc899bSmrg 69145bc899bSmrg pVesa->mapSize = vbe->TotalMemory * 65536; 69245bc899bSmrg if (pScrn->modePool == NULL) { 69345bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No matching modes\n"); 69445bc899bSmrg vbeFree(pVesa->pVbe); 69545bc899bSmrg return (FALSE); 69645bc899bSmrg } 69745bc899bSmrg 69845bc899bSmrg VBESetModeNames(pScrn->modePool); 69945bc899bSmrg 70050f2e948Smrg pVesa->strict_validation = TRUE; 70150f2e948Smrg i = VESAValidateModes(pScrn); 70250f2e948Smrg 70350f2e948Smrg if (i <= 0) { 70450f2e948Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 70550f2e948Smrg "No valid modes left. Trying less strict filter...\n"); 70650f2e948Smrg pVesa->strict_validation = FALSE; 70750f2e948Smrg i = VESAValidateModes(pScrn); 70850f2e948Smrg } 70950f2e948Smrg 71050f2e948Smrg if (i <= 0) do { 71150f2e948Smrg Bool changed = FALSE; 71250f2e948Smrg /* maybe there's more modes at the bottom... */ 71350f2e948Smrg if (pScrn->monitor->vrefresh[0].lo > 50) { 71450f2e948Smrg changed = TRUE; 71550f2e948Smrg pScrn->monitor->vrefresh[0].lo = 50; 71650f2e948Smrg } 71750f2e948Smrg if (pScrn->monitor->hsync[0].lo > 31.5) { 71850f2e948Smrg changed = TRUE; 71950f2e948Smrg pScrn->monitor->hsync[0].lo = 31.5; 72050f2e948Smrg } 72150f2e948Smrg 72250f2e948Smrg if (!changed) 72350f2e948Smrg break; 72450f2e948Smrg 72550f2e948Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 72650f2e948Smrg "No valid modes left. Trying aggressive sync range...\n"); 72750f2e948Smrg i = VESAValidateModes(pScrn); 72850f2e948Smrg } while (0); 72945bc899bSmrg 73045bc899bSmrg if (i <= 0) { 73150f2e948Smrg /* alright, i'm out of ideas */ 73245bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes\n"); 73345bc899bSmrg vbeFree(pVesa->pVbe); 73445bc899bSmrg return (FALSE); 73545bc899bSmrg } 73645bc899bSmrg 73745bc899bSmrg xf86PruneDriverModes(pScrn); 73845bc899bSmrg 73945bc899bSmrg pMode = pScrn->modes; 74045bc899bSmrg do { 74145bc899bSmrg mode = ((VbeModeInfoData*)pMode->Private)->data; 74245bc899bSmrg if (mode->BytesPerScanline > pVesa->maxBytesPerScanline) { 74345bc899bSmrg pVesa->maxBytesPerScanline = mode->BytesPerScanline; 74445bc899bSmrg } 74545bc899bSmrg pMode = pMode->next; 74645bc899bSmrg } while (pMode != pScrn->modes); 74745bc899bSmrg 74845bc899bSmrg pScrn->currentMode = pScrn->modes; 74945bc899bSmrg pScrn->displayWidth = pScrn->virtualX; 75045bc899bSmrg 75145bc899bSmrg VBEPrintModes(pScrn); 75245bc899bSmrg 75345bc899bSmrg /* Set display resolution */ 75445bc899bSmrg xf86SetDpi(pScrn, 0, 0); 75545bc899bSmrg 75645bc899bSmrg if (pScrn->modes == NULL) { 75745bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes\n"); 75845bc899bSmrg vbeFree(pVesa->pVbe); 75945bc899bSmrg return (FALSE); 76045bc899bSmrg } 76145bc899bSmrg 76245bc899bSmrg /* options */ 76345bc899bSmrg xf86CollectOptions(pScrn, NULL); 76445bc899bSmrg if (!(pVesa->Options = xalloc(sizeof(VESAOptions)))) { 76545bc899bSmrg vbeFree(pVesa->pVbe); 76645bc899bSmrg return FALSE; 76745bc899bSmrg } 76845bc899bSmrg memcpy(pVesa->Options, VESAOptions, sizeof(VESAOptions)); 76945bc899bSmrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pVesa->Options); 77045bc899bSmrg 77145bc899bSmrg /* Use shadow by default */ 77245bc899bSmrg if (xf86ReturnOptValBool(pVesa->Options, OPTION_SHADOW_FB, TRUE)) 77345bc899bSmrg pVesa->shadowFB = TRUE; 77445bc899bSmrg 77545bc899bSmrg if (xf86ReturnOptValBool(pVesa->Options, OPTION_DFLT_REFRESH, FALSE)) 77645bc899bSmrg pVesa->defaultRefresh = TRUE; 77745bc899bSmrg 77850f2e948Smrg pVesa->ModeSetClearScreen = FALSE; 77945bc899bSmrg if (xf86ReturnOptValBool(pVesa->Options, OPTION_MODESET_CLEAR_SCREEN, 78050f2e948Smrg FALSE)) 78145bc899bSmrg pVesa->ModeSetClearScreen = TRUE; 78245bc899bSmrg 78350f2e948Smrg if (!pVesa->defaultRefresh && !pVesa->strict_validation) 78445bc899bSmrg VBESetModeParameters(pScrn, pVesa->pVbe); 78545bc899bSmrg 78645bc899bSmrg mode = ((VbeModeInfoData*)pScrn->modes->Private)->data; 78745bc899bSmrg switch (mode->MemoryModel) { 78845bc899bSmrg case 0x4: /* Packed pixel */ 78950f2e948Smrg case 0x6: /* Direct Color */ 79045bc899bSmrg pScrn->bitmapBitOrder = BITMAP_BIT_ORDER; 79145bc899bSmrg 79245bc899bSmrg switch (pScrn->bitsPerPixel) { 79345bc899bSmrg case 8: 79445bc899bSmrg case 16: 79545bc899bSmrg case 24: 79645bc899bSmrg case 32: 79745bc899bSmrg break; 79845bc899bSmrg default: 79945bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 80045bc899bSmrg "Unsupported bpp: %d", pScrn->bitsPerPixel); 80145bc899bSmrg vbeFree(pVesa->pVbe); 80245bc899bSmrg return FALSE; 80345bc899bSmrg } 80445bc899bSmrg break; 80550f2e948Smrg default: 80650f2e948Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 80750f2e948Smrg "Unsupported Memory Model: %d", mode->MemoryModel); 80850f2e948Smrg return FALSE; 80945bc899bSmrg } 81045bc899bSmrg 81145bc899bSmrg if (pVesa->shadowFB) { 81245bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using \"Shadow Framebuffer\"\n"); 81345bc899bSmrg if (!xf86LoadSubModule(pScrn, "shadow")) { 81445bc899bSmrg vbeFree(pVesa->pVbe); 81545bc899bSmrg return (FALSE); 81645bc899bSmrg } 81745bc899bSmrg } 81845bc899bSmrg 81950f2e948Smrg if (xf86LoadSubModule(pScrn, "fb") == NULL) { 82045bc899bSmrg VESAFreeRec(pScrn); 82145bc899bSmrg vbeFree(pVesa->pVbe); 82245bc899bSmrg return (FALSE); 82345bc899bSmrg } 82445bc899bSmrg 82545bc899bSmrg vbeFree(pVesa->pVbe); 82645bc899bSmrg 82745bc899bSmrg return (TRUE); 82845bc899bSmrg} 82945bc899bSmrg 83045bc899bSmrgstatic Bool 83145bc899bSmrgvesaCreateScreenResources(ScreenPtr pScreen) 83245bc899bSmrg{ 83345bc899bSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 83445bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 83545bc899bSmrg Bool ret; 83645bc899bSmrg 83745bc899bSmrg pScreen->CreateScreenResources = pVesa->CreateScreenResources; 83845bc899bSmrg ret = pScreen->CreateScreenResources(pScreen); 83945bc899bSmrg pScreen->CreateScreenResources = vesaCreateScreenResources; 84045bc899bSmrg 84145bc899bSmrg shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen), pVesa->update, 84245bc899bSmrg pVesa->window, 0, 0); 84345bc899bSmrg 84445bc899bSmrg return ret; 84545bc899bSmrg} 84645bc899bSmrg 84750f2e948Smrgstatic void 84850f2e948SmrgvesaEnableDisableFBAccess(int scrnIndex, Bool enable) 84950f2e948Smrg{ 85050f2e948Smrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 85150f2e948Smrg VESAPtr pVesa = VESAGetRec(pScrn); 85250f2e948Smrg 85350f2e948Smrg pVesa->accessEnabled = enable; 85450f2e948Smrg pVesa->EnableDisableFBAccess(scrnIndex, enable); 85550f2e948Smrg} 85650f2e948Smrg 85745bc899bSmrgstatic Bool 85845bc899bSmrgVESAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 85945bc899bSmrg{ 86045bc899bSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 86145bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 86245bc899bSmrg VisualPtr visual; 86345bc899bSmrg VbeModeInfoBlock *mode; 86445bc899bSmrg int flags; 86545bc899bSmrg int init_picture = 0; 86645bc899bSmrg 86745bc899bSmrg if ((pVesa->pVbe = VBEExtendedInit(NULL, pVesa->pEnt->index, 86845bc899bSmrg SET_BIOS_SCRATCH 86945bc899bSmrg | RESTORE_BIOS_SCRATCH)) == NULL) 87045bc899bSmrg return (FALSE); 87145bc899bSmrg 87245bc899bSmrg if (pVesa->mapPhys == 0) { 87345bc899bSmrg mode = ((VbeModeInfoData*)(pScrn->currentMode->Private))->data; 87445bc899bSmrg pScrn->videoRam = pVesa->mapSize; 87545bc899bSmrg pVesa->mapPhys = mode->PhysBasePtr; 87645bc899bSmrg pVesa->mapOff = 0; 87745bc899bSmrg } 87845bc899bSmrg 87945bc899bSmrg if (pVesa->mapPhys == 0) { 88045bc899bSmrg pVesa->mapPhys = 0xa0000; 88145bc899bSmrg pVesa->mapSize = 0x10000; 88245bc899bSmrg } 88345bc899bSmrg 88445bc899bSmrg if (!VESAMapVidMem(pScrn)) { 88545bc899bSmrg if (pVesa->mapPhys != 0xa0000) { 88645bc899bSmrg pVesa->mapPhys = 0xa0000; 88745bc899bSmrg pVesa->mapSize = 0x10000; 88845bc899bSmrg if (!VESAMapVidMem(pScrn)) 88945bc899bSmrg return (FALSE); 89045bc899bSmrg } 89145bc899bSmrg else 89245bc899bSmrg return (FALSE); 89345bc899bSmrg } 89445bc899bSmrg 89545bc899bSmrg /* Set bpp to 8 for depth 4 when using shadowfb. */ 89645bc899bSmrg if (pVesa->shadowFB && pScrn->bitsPerPixel == 4) 89745bc899bSmrg pScrn->bitsPerPixel = 8; 89845bc899bSmrg 89945bc899bSmrg if (pVesa->shadowFB) { 90045bc899bSmrg pVesa->shadow = xcalloc(1, pScrn->displayWidth * pScrn->virtualY * 90145bc899bSmrg ((pScrn->bitsPerPixel + 7) / 8)); 90245bc899bSmrg if (!pVesa->shadow) { 90345bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 90445bc899bSmrg "Failed to allocate shadow buffer\n"); 90545bc899bSmrg return FALSE; 90645bc899bSmrg } 90745bc899bSmrg } 90845bc899bSmrg 90945bc899bSmrg /* save current video state */ 91045bc899bSmrg VESASaveRestore(pScrn, MODE_SAVE); 91145bc899bSmrg pVesa->savedPal = VBESetGetPaletteData(pVesa->pVbe, FALSE, 0, 256, 91245bc899bSmrg NULL, FALSE, FALSE); 91345bc899bSmrg 91445bc899bSmrg /* set first video mode */ 91545bc899bSmrg if (!VESASetMode(pScrn, pScrn->currentMode)) 91645bc899bSmrg return (FALSE); 91745bc899bSmrg 91845bc899bSmrg /* set the viewport */ 91945bc899bSmrg VESAAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 92045bc899bSmrg 92145bc899bSmrg /* Blank the screen for aesthetic reasons. */ 92245bc899bSmrg VESASaveScreen(pScreen, SCREEN_SAVER_ON); 92345bc899bSmrg 92445bc899bSmrg /* mi layer */ 92545bc899bSmrg miClearVisualTypes(); 92645bc899bSmrg if (!xf86SetDefaultVisual(pScrn, -1)) 92745bc899bSmrg return (FALSE); 92845bc899bSmrg if (pScrn->bitsPerPixel > 8) { 92945bc899bSmrg if (!miSetVisualTypes(pScrn->depth, TrueColorMask, 93045bc899bSmrg pScrn->rgbBits, TrueColor)) 93145bc899bSmrg return (FALSE); 93245bc899bSmrg } 93345bc899bSmrg else { 93445bc899bSmrg if (!miSetVisualTypes(pScrn->depth, 93545bc899bSmrg miGetDefaultVisualMask(pScrn->depth), 93645bc899bSmrg pScrn->rgbBits, pScrn->defaultVisual)) 93745bc899bSmrg return (FALSE); 93845bc899bSmrg } 93945bc899bSmrg if (!miSetPixmapDepths()) 94045bc899bSmrg return (FALSE); 94145bc899bSmrg 94245bc899bSmrg mode = ((VbeModeInfoData*)pScrn->modes->Private)->data; 94345bc899bSmrg switch (mode->MemoryModel) { 94445bc899bSmrg case 0x4: /* Packed pixel */ 94550f2e948Smrg case 0x6: /* Direct Color */ 94645bc899bSmrg switch (pScrn->bitsPerPixel) { 94745bc899bSmrg case 8: 94845bc899bSmrg case 16: 94945bc899bSmrg case 24: 95045bc899bSmrg case 32: 95145bc899bSmrg if (!fbScreenInit(pScreen, 95245bc899bSmrg pVesa->shadowFB ? pVesa->shadow : pVesa->base, 95345bc899bSmrg pScrn->virtualX, pScrn->virtualY, 95445bc899bSmrg pScrn->xDpi, pScrn->yDpi, 95545bc899bSmrg pScrn->displayWidth, pScrn->bitsPerPixel)) 95645bc899bSmrg return (FALSE); 95745bc899bSmrg init_picture = 1; 95845bc899bSmrg break; 95945bc899bSmrg default: 96045bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 96145bc899bSmrg "Unsupported bpp: %d", pScrn->bitsPerPixel); 96245bc899bSmrg return (FALSE); 96345bc899bSmrg } 96445bc899bSmrg break; 96550f2e948Smrg default: 96650f2e948Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 96750f2e948Smrg "Unsupported Memory Model: %d", mode->MemoryModel); 96850f2e948Smrg return (FALSE); 96945bc899bSmrg } 97045bc899bSmrg 97145bc899bSmrg 97245bc899bSmrg if (pScrn->bitsPerPixel > 8) { 97345bc899bSmrg /* Fixup RGB ordering */ 97445bc899bSmrg visual = pScreen->visuals + pScreen->numVisuals; 97545bc899bSmrg while (--visual >= pScreen->visuals) { 97645bc899bSmrg if ((visual->class | DynamicClass) == DirectColor) { 97745bc899bSmrg visual->offsetRed = pScrn->offset.red; 97845bc899bSmrg visual->offsetGreen = pScrn->offset.green; 97945bc899bSmrg visual->offsetBlue = pScrn->offset.blue; 98045bc899bSmrg visual->redMask = pScrn->mask.red; 98145bc899bSmrg visual->greenMask = pScrn->mask.green; 98245bc899bSmrg visual->blueMask = pScrn->mask.blue; 98345bc899bSmrg } 98445bc899bSmrg } 98545bc899bSmrg } 98645bc899bSmrg 98745bc899bSmrg /* must be after RGB ordering fixed */ 98845bc899bSmrg if (init_picture) 98945bc899bSmrg fbPictureInit(pScreen, 0, 0); 99045bc899bSmrg 99145bc899bSmrg if (pVesa->shadowFB) { 99250f2e948Smrg if (pVesa->mapPhys == 0xa0000) { /* Windowed */ 99345bc899bSmrg pVesa->update = shadowUpdatePackedWeak(); 99445bc899bSmrg pVesa->window = VESAWindowWindowed; 99545bc899bSmrg } 99645bc899bSmrg else { /* Linear */ 99745bc899bSmrg pVesa->update = shadowUpdatePackedWeak(); 99845bc899bSmrg pVesa->window = VESAWindowLinear; 99945bc899bSmrg } 100045bc899bSmrg 100145bc899bSmrg if (!shadowSetup(pScreen)) 100245bc899bSmrg return FALSE; 100345bc899bSmrg pVesa->CreateScreenResources = pScreen->CreateScreenResources; 100445bc899bSmrg pScreen->CreateScreenResources = vesaCreateScreenResources; 100545bc899bSmrg } 100650f2e948Smrg else if (pVesa->mapPhys == 0xa0000) { 100745bc899bSmrg unsigned int bankShift = 0; 100845bc899bSmrg while ((unsigned)(64 >> bankShift) != mode->WinGranularity) 100945bc899bSmrg bankShift++; 101045bc899bSmrg pVesa->curBank = -1; 101145bc899bSmrg pVesa->bank.SetSourceBank = 101245bc899bSmrg pVesa->bank.SetDestinationBank = 101345bc899bSmrg pVesa->bank.SetSourceAndDestinationBanks = VESABankSwitch; 101445bc899bSmrg pVesa->bank.pBankA = pVesa->bank.pBankB = pVesa->base; 101545bc899bSmrg pVesa->bank.BankSize = (mode->WinSize * 1024) >> bankShift; 101645bc899bSmrg pVesa->bank.nBankDepth = pScrn->depth; 101745bc899bSmrg if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY, 101845bc899bSmrg pScrn->virtualX, &pVesa->bank)) { 101945bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 102045bc899bSmrg "Bank switch initialization failed!\n"); 102145bc899bSmrg return (FALSE); 102245bc899bSmrg } 102345bc899bSmrg } 102445bc899bSmrg 102545bc899bSmrg VESADGAInit(pScrn, pScreen); 102645bc899bSmrg 102745bc899bSmrg xf86SetBlackWhitePixels(pScreen); 102845bc899bSmrg miInitializeBackingStore(pScreen); 102945bc899bSmrg xf86SetBackingStore(pScreen); 103045bc899bSmrg 103145bc899bSmrg /* software cursor */ 103245bc899bSmrg miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 103345bc899bSmrg 103445bc899bSmrg /* colormap */ 103545bc899bSmrg if (!miCreateDefColormap(pScreen)) 103645bc899bSmrg return (FALSE); 103745bc899bSmrg 103845bc899bSmrg flags = CMAP_RELOAD_ON_MODE_SWITCH; 103945bc899bSmrg 104045bc899bSmrg if(!xf86HandleColormaps(pScreen, 256, 104145bc899bSmrg pVesa->vbeInfo->Capabilities[0] & 0x01 ? 8 : 6, 104245bc899bSmrg VESALoadPalette, NULL, flags)) 104345bc899bSmrg return (FALSE); 104445bc899bSmrg 104550f2e948Smrg pVesa->accessEnabled = TRUE; 104650f2e948Smrg pVesa->EnableDisableFBAccess = pScrn->EnableDisableFBAccess; 104750f2e948Smrg pScrn->EnableDisableFBAccess = vesaEnableDisableFBAccess; 104850f2e948Smrg 104945bc899bSmrg pVesa->CloseScreen = pScreen->CloseScreen; 105045bc899bSmrg pScreen->CloseScreen = VESACloseScreen; 105145bc899bSmrg pScreen->SaveScreen = VESASaveScreen; 105245bc899bSmrg 105345bc899bSmrg xf86DPMSInit(pScreen, VESADisplayPowerManagementSet, 0); 105445bc899bSmrg 105545bc899bSmrg /* Report any unused options (only for the first generation) */ 105645bc899bSmrg if (serverGeneration == 1) 105745bc899bSmrg xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 105845bc899bSmrg 105945bc899bSmrg return (TRUE); 106045bc899bSmrg} 106145bc899bSmrg 106245bc899bSmrgstatic Bool 106345bc899bSmrgVESAEnterVT(int scrnIndex, int flags) 106445bc899bSmrg{ 106545bc899bSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 106645bc899bSmrg 106745bc899bSmrg if (!VESASetMode(pScrn, pScrn->currentMode)) 106845bc899bSmrg return FALSE; 106945bc899bSmrg VESAAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 107045bc899bSmrg return TRUE; 107145bc899bSmrg} 107245bc899bSmrg 107345bc899bSmrgstatic void 107445bc899bSmrgVESALeaveVT(int scrnIndex, int flags) 107545bc899bSmrg{ 107645bc899bSmrg VESASaveRestore(xf86Screens[scrnIndex], MODE_RESTORE); 107745bc899bSmrg} 107845bc899bSmrg 107945bc899bSmrgstatic Bool 108045bc899bSmrgVESACloseScreen(int scrnIndex, ScreenPtr pScreen) 108145bc899bSmrg{ 108245bc899bSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 108345bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 108445bc899bSmrg 108545bc899bSmrg if (pScrn->vtSema) { 108645bc899bSmrg VESASaveRestore(xf86Screens[scrnIndex], MODE_RESTORE); 108745bc899bSmrg if (pVesa->savedPal) 108845bc899bSmrg VBESetGetPaletteData(pVesa->pVbe, TRUE, 0, 256, 108945bc899bSmrg pVesa->savedPal, FALSE, TRUE); 109045bc899bSmrg VESAUnmapVidMem(pScrn); 109145bc899bSmrg } 109245bc899bSmrg if (pVesa->shadowFB && pVesa->shadow) 109345bc899bSmrg xfree(pVesa->shadow); 109445bc899bSmrg if (pVesa->pDGAMode) { 109545bc899bSmrg xfree(pVesa->pDGAMode); 109645bc899bSmrg pVesa->pDGAMode = NULL; 109745bc899bSmrg pVesa->nDGAMode = 0; 109845bc899bSmrg } 109945bc899bSmrg pScrn->vtSema = FALSE; 110045bc899bSmrg 110150f2e948Smrg pScrn->EnableDisableFBAccess = pVesa->EnableDisableFBAccess; 110245bc899bSmrg pScreen->CreateScreenResources = pVesa->CreateScreenResources; 110345bc899bSmrg pScreen->CloseScreen = pVesa->CloseScreen; 110445bc899bSmrg return pScreen->CloseScreen(scrnIndex, pScreen); 110545bc899bSmrg} 110645bc899bSmrg 110745bc899bSmrgstatic Bool 110845bc899bSmrgVESASwitchMode(int scrnIndex, DisplayModePtr pMode, int flags) 110945bc899bSmrg{ 111045bc899bSmrg ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 111145bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 111250f2e948Smrg Bool ret, disableAccess = pVesa->ModeSetClearScreen && pVesa->accessEnabled; 111345bc899bSmrg 111450f2e948Smrg if (disableAccess) 111545bc899bSmrg pScrn->EnableDisableFBAccess(scrnIndex,FALSE); 111645bc899bSmrg ret = VESASetMode(xf86Screens[scrnIndex], pMode); 111750f2e948Smrg if (disableAccess) 111845bc899bSmrg pScrn->EnableDisableFBAccess(scrnIndex,TRUE); 111945bc899bSmrg return ret; 112045bc899bSmrg} 112145bc899bSmrg 112245bc899bSmrg/* Set a graphics mode */ 112345bc899bSmrgstatic Bool 112445bc899bSmrgVESASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) 112545bc899bSmrg{ 112645bc899bSmrg VESAPtr pVesa; 112745bc899bSmrg VbeModeInfoData *data; 112845bc899bSmrg int mode; 112945bc899bSmrg 113045bc899bSmrg pVesa = VESAGetRec(pScrn); 113145bc899bSmrg 113245bc899bSmrg data = (VbeModeInfoData*)pMode->Private; 113350f2e948Smrg 113450f2e948Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 113550f2e948Smrg "Setting up VESA Mode 0x%X (%dx%d)\n", 113650f2e948Smrg data->mode & 0x7FF, pMode->HDisplay, pMode->VDisplay); 113750f2e948Smrg 113850f2e948Smrg /* careful, setting the bit means don't clear the screen */ 113950f2e948Smrg mode = data->mode | (pVesa->ModeSetClearScreen ? 0 : (1U << 15)); 114045bc899bSmrg 114145bc899bSmrg /* enable linear addressing */ 114245bc899bSmrg if (pVesa->mapPhys != 0xa0000) 114345bc899bSmrg mode |= 1 << 14; 114445bc899bSmrg 114545bc899bSmrg if (VBESetVBEMode(pVesa->pVbe, mode, data->block) == FALSE) { 114645bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBESetVBEMode failed"); 114745bc899bSmrg if ((data->block || (data->mode & (1 << 11))) && 114845bc899bSmrg VBESetVBEMode(pVesa->pVbe, (mode & ~(1 << 11)), NULL) == TRUE) { 114945bc899bSmrg /* Some cards do not like setting the clock. 115045bc899bSmrg * Free it as it will not be any longer useful 115145bc899bSmrg */ 115245bc899bSmrg xf86ErrorF("...Tried again without customized values.\n"); 115345bc899bSmrg xfree(data->block); 115445bc899bSmrg data->block = NULL; 115545bc899bSmrg data->mode &= ~(1 << 11); 115645bc899bSmrg } 115745bc899bSmrg else { 115845bc899bSmrg ErrorF("\n"); 115945bc899bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Set VBE Mode failed!\n"); 116045bc899bSmrg return (FALSE); 116145bc899bSmrg } 116245bc899bSmrg } 116345bc899bSmrg 116445bc899bSmrg pVesa->bankSwitchWindowB = 116545bc899bSmrg !((data->data->WinBSegment == 0) && (data->data->WinBAttributes == 0)); 116645bc899bSmrg 116745bc899bSmrg if (data->data->XResolution != pScrn->displayWidth) 116845bc899bSmrg VBESetLogicalScanline(pVesa->pVbe, pScrn->displayWidth); 116945bc899bSmrg 117045bc899bSmrg if (pScrn->bitsPerPixel == 8 && pVesa->vbeInfo->Capabilities[0] & 0x01 && 117150f2e948Smrg !(data->data->MemoryModel == 0x6 || data->data->MemoryModel == 0x7)) 117245bc899bSmrg VBESetGetDACPaletteFormat(pVesa->pVbe, 8); 117345bc899bSmrg 117445bc899bSmrg pScrn->vtSema = TRUE; 117545bc899bSmrg 117645bc899bSmrg return (TRUE); 117745bc899bSmrg} 117845bc899bSmrg 117945bc899bSmrgstatic void 118045bc899bSmrgVESAAdjustFrame(int scrnIndex, int x, int y, int flags) 118145bc899bSmrg{ 118245bc899bSmrg VESAPtr pVesa = VESAGetRec(xf86Screens[scrnIndex]); 118345bc899bSmrg 118445bc899bSmrg VBESetDisplayStart(pVesa->pVbe, x, y, TRUE); 118545bc899bSmrg} 118645bc899bSmrg 118745bc899bSmrgstatic void 118845bc899bSmrgVESAFreeScreen(int scrnIndex, int flags) 118945bc899bSmrg{ 119045bc899bSmrg VESAFreeRec(xf86Screens[scrnIndex]); 119145bc899bSmrg} 119245bc899bSmrg 119345bc899bSmrgstatic Bool 119445bc899bSmrgVESAMapVidMem(ScrnInfoPtr pScrn) 119545bc899bSmrg{ 119645bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 119745bc899bSmrg 119845bc899bSmrg if (pVesa->base != NULL) 119945bc899bSmrg return (TRUE); 120045bc899bSmrg 120145bc899bSmrg pScrn->memPhysBase = pVesa->mapPhys; 120245bc899bSmrg pScrn->fbOffset = pVesa->mapOff; 120345bc899bSmrg 120450f2e948Smrg#ifdef XSERVER_LIBPCIACCESS 120550f2e948Smrg if ((pVesa->mapPhys != 0xa0000) && (pVesa->pciInfo != NULL)) { 120650f2e948Smrg (void) pci_device_map_range(pVesa->pciInfo, pScrn->memPhysBase, 120750f2e948Smrg pVesa->mapSize, 120850f2e948Smrg (PCI_DEV_MAP_FLAG_WRITABLE 120950f2e948Smrg | PCI_DEV_MAP_FLAG_WRITE_COMBINE), 121050f2e948Smrg & pVesa->base); 121150f2e948Smrg } 121250f2e948Smrg else 121350f2e948Smrg pVesa->base = xf86MapDomainMemory(pScrn->scrnIndex, 0, pVesa->pciInfo, 121450f2e948Smrg pScrn->memPhysBase, pVesa->mapSize); 121550f2e948Smrg 121650f2e948Smrg if (pVesa->base) { 121750f2e948Smrg if (pVesa->mapPhys != 0xa0000) 121850f2e948Smrg pVesa->VGAbase = xf86MapDomainMemory(pScrn->scrnIndex, 0, 121950f2e948Smrg pVesa->pciInfo, 122050f2e948Smrg 0xa0000, 0x10000); 122150f2e948Smrg else 122250f2e948Smrg pVesa->VGAbase = pVesa->base; 122350f2e948Smrg 122450f2e948Smrg } 122550f2e948Smrg#else 122645bc899bSmrg if (pVesa->mapPhys != 0xa0000 && pVesa->pEnt->location.type == BUS_PCI) 122745bc899bSmrg pVesa->base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 122845bc899bSmrg pVesa->pciTag, pScrn->memPhysBase, 122945bc899bSmrg pVesa->mapSize); 123045bc899bSmrg else 123145bc899bSmrg pVesa->base = xf86MapDomainMemory(pScrn->scrnIndex, 0, pVesa->pciTag, 123245bc899bSmrg pScrn->memPhysBase, pVesa->mapSize); 123345bc899bSmrg 123445bc899bSmrg if (pVesa->base) { 123545bc899bSmrg if (pVesa->mapPhys != 0xa0000) 123645bc899bSmrg pVesa->VGAbase = xf86MapDomainMemory(pScrn->scrnIndex, 0, 123745bc899bSmrg pVesa->pciTag, 123845bc899bSmrg 0xa0000, 0x10000); 123945bc899bSmrg else 124045bc899bSmrg pVesa->VGAbase = pVesa->base; 124145bc899bSmrg } 124250f2e948Smrg#endif 124345bc899bSmrg 124445bc899bSmrg pVesa->ioBase = pScrn->domainIOBase; 124545bc899bSmrg 124645bc899bSmrg xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, DEBUG_VERB, 124745bc899bSmrg "virtual address = %p,\n" 124845bc899bSmrg "\tphysical address = 0x%lx, size = %ld\n", 124945bc899bSmrg pVesa->base, pScrn->memPhysBase, pVesa->mapSize); 125045bc899bSmrg 125145bc899bSmrg return (pVesa->base != NULL); 125245bc899bSmrg} 125345bc899bSmrg 125445bc899bSmrgstatic void 125545bc899bSmrgVESAUnmapVidMem(ScrnInfoPtr pScrn) 125645bc899bSmrg{ 125745bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 125845bc899bSmrg 125945bc899bSmrg if (pVesa->base == NULL) 126045bc899bSmrg return; 126145bc899bSmrg 126250f2e948Smrg#ifdef XSERVER_LIBPCIACCESS 126350f2e948Smrg if (pVesa->mapPhys != 0xa0000) { 126450f2e948Smrg (void) pci_device_unmap_range(pVesa->pciInfo, pVesa->base, 126550f2e948Smrg pVesa->mapSize); 126650f2e948Smrg xf86UnMapVidMem(pScrn->scrnIndex, pVesa->VGAbase, 0x10000); 126750f2e948Smrg } 126850f2e948Smrg else { 126950f2e948Smrg xf86UnMapVidMem(pScrn->scrnIndex, pVesa->base, pVesa->mapSize); 127050f2e948Smrg } 127150f2e948Smrg#else 127245bc899bSmrg xf86UnMapVidMem(pScrn->scrnIndex, pVesa->base, pVesa->mapSize); 127345bc899bSmrg if (pVesa->mapPhys != 0xa0000) 127445bc899bSmrg xf86UnMapVidMem(pScrn->scrnIndex, pVesa->VGAbase, 0x10000); 127550f2e948Smrg#endif 127645bc899bSmrg pVesa->base = NULL; 127745bc899bSmrg} 127845bc899bSmrg 127945bc899bSmrgstatic void * 128045bc899bSmrgVESAWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 128145bc899bSmrg CARD32 *size, void *closure) 128245bc899bSmrg{ 128345bc899bSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 128445bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 128545bc899bSmrg 128645bc899bSmrg *size = pVesa->maxBytesPerScanline; 128745bc899bSmrg return ((CARD8 *)pVesa->base + row * pVesa->maxBytesPerScanline + offset); 128845bc899bSmrg} 128945bc899bSmrg 129045bc899bSmrgstatic void * 129145bc899bSmrgVESAWindowWindowed(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 129245bc899bSmrg CARD32 *size, void *closure) 129345bc899bSmrg{ 129445bc899bSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 129545bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 129645bc899bSmrg VbeModeInfoBlock *data = ((VbeModeInfoData*)(pScrn->currentMode->Private))->data; 129745bc899bSmrg int window; 129845bc899bSmrg 129945bc899bSmrg offset += pVesa->maxBytesPerScanline * row; 130045bc899bSmrg window = offset / (data->WinGranularity * 1024); 130145bc899bSmrg pVesa->windowAoffset = window * data->WinGranularity * 1024; 130245bc899bSmrg VESABankSwitch(pScreen, window); 130345bc899bSmrg *size = data->WinSize * 1024 - (offset - pVesa->windowAoffset); 130445bc899bSmrg 130545bc899bSmrg return (void *)((unsigned long)pVesa->base + 130645bc899bSmrg (offset - pVesa->windowAoffset)); 130745bc899bSmrg} 130845bc899bSmrg 130945bc899bSmrgstatic void 131045bc899bSmrgVESALoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 131145bc899bSmrg LOCO *colors, VisualPtr pVisual) 131245bc899bSmrg{ 131345bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 131445bc899bSmrg int i, idx; 131545bc899bSmrg 131645bc899bSmrg#if 0 131745bc899bSmrg 131845bc899bSmrg /* This code works, but is very slow for programs that use it intensively */ 131945bc899bSmrg int base; 132045bc899bSmrg 132145bc899bSmrg if (pVesa->pal == NULL) 132245bc899bSmrg pVesa->pal = xcalloc(1, sizeof(CARD32) * 256); 132345bc899bSmrg 132445bc899bSmrg for (i = 0, base = idx = indices[i]; i < numColors; i++, idx++) { 132545bc899bSmrg int j = indices[i]; 132645bc899bSmrg 132745bc899bSmrg if (j < 0 || j >= 256) 132845bc899bSmrg continue; 132945bc899bSmrg pVesa->pal[j] = colors[j].blue | 133045bc899bSmrg (colors[j].green << 8) | 133145bc899bSmrg (colors[j].red << 16); 133245bc899bSmrg if (j != idx) { 133345bc899bSmrg VBESetGetPaletteData(pVesa->pVbe, TRUE, base, idx - base, 133445bc899bSmrg pVesa->pal + base, FALSE, TRUE); 133545bc899bSmrg idx = base = j; 133645bc899bSmrg } 133745bc899bSmrg } 133845bc899bSmrg 133945bc899bSmrg if (idx - 1 == indices[i - 1]) 134045bc899bSmrg VBESetGetPaletteData(pVesa->pVbe, TRUE, base, idx - base, 134145bc899bSmrg pVesa->pal + base, FALSE, TRUE); 134245bc899bSmrg 134345bc899bSmrg#else 134445bc899bSmrg 134545bc899bSmrg#define VESADACDelay() \ 134645bc899bSmrg do { \ 134745bc899bSmrg (void)inb(pVesa->ioBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); \ 134845bc899bSmrg (void)inb(pVesa->ioBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); \ 134945bc899bSmrg } while (0) 135045bc899bSmrg 135145bc899bSmrg for (i = 0; i < numColors; i++) { 135245bc899bSmrg idx = indices[i]; 135345bc899bSmrg outb(pVesa->ioBase + VGA_DAC_WRITE_ADDR, idx); 135445bc899bSmrg VESADACDelay(); 135545bc899bSmrg outb(pVesa->ioBase + VGA_DAC_DATA, colors[idx].red); 135645bc899bSmrg VESADACDelay(); 135745bc899bSmrg outb(pVesa->ioBase + VGA_DAC_DATA, colors[idx].green); 135845bc899bSmrg VESADACDelay(); 135945bc899bSmrg outb(pVesa->ioBase + VGA_DAC_DATA, colors[idx].blue); 136045bc899bSmrg VESADACDelay(); 136145bc899bSmrg } 136245bc899bSmrg 136345bc899bSmrg#endif 136445bc899bSmrg} 136545bc899bSmrg 136645bc899bSmrg/* 136745bc899bSmrg * Just adapted from the std* functions in vgaHW.c 136845bc899bSmrg */ 136945bc899bSmrgstatic void 137045bc899bSmrgWriteAttr(VESAPtr pVesa, int index, int value) 137145bc899bSmrg{ 137245bc899bSmrg (void) inb(pVesa->ioBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); 137345bc899bSmrg 137445bc899bSmrg index |= 0x20; 137545bc899bSmrg outb(pVesa->ioBase + VGA_ATTR_INDEX, index); 137645bc899bSmrg outb(pVesa->ioBase + VGA_ATTR_DATA_W, value); 137745bc899bSmrg} 137845bc899bSmrg 137945bc899bSmrgstatic int 138045bc899bSmrgReadAttr(VESAPtr pVesa, int index) 138145bc899bSmrg{ 138245bc899bSmrg (void) inb(pVesa->ioBase + VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET); 138345bc899bSmrg 138445bc899bSmrg index |= 0x20; 138545bc899bSmrg outb(pVesa->ioBase + VGA_ATTR_INDEX, index); 138645bc899bSmrg return (inb(pVesa->ioBase + VGA_ATTR_DATA_R)); 138745bc899bSmrg} 138845bc899bSmrg 138945bc899bSmrg#define WriteMiscOut(value) outb(pVesa->ioBase + VGA_MISC_OUT_W, value) 139045bc899bSmrg#define ReadMiscOut() inb(pVesa->ioBase + VGA_MISC_OUT_R) 139145bc899bSmrg#define WriteSeq(index, value) outb(pVesa->ioBase + VGA_SEQ_INDEX, index);\ 139245bc899bSmrg outb(pVesa->ioBase + VGA_SEQ_DATA, value) 139345bc899bSmrg 139445bc899bSmrgstatic int 139545bc899bSmrgReadSeq(VESAPtr pVesa, int index) 139645bc899bSmrg{ 139745bc899bSmrg outb(pVesa->ioBase + VGA_SEQ_INDEX, index); 139845bc899bSmrg 139945bc899bSmrg return (inb(pVesa->ioBase + VGA_SEQ_DATA)); 140045bc899bSmrg} 140145bc899bSmrg 140245bc899bSmrg#define WriteGr(index, value) \ 140345bc899bSmrg outb(pVesa->ioBase + VGA_GRAPH_INDEX, index); \ 140445bc899bSmrg outb(pVesa->ioBase + VGA_GRAPH_DATA, value) 140545bc899bSmrg 140645bc899bSmrgstatic int 140745bc899bSmrgReadGr(VESAPtr pVesa, int index) 140845bc899bSmrg{ 140945bc899bSmrg outb(pVesa->ioBase + VGA_GRAPH_INDEX, index); 141045bc899bSmrg 141145bc899bSmrg return (inb(pVesa->ioBase + VGA_GRAPH_DATA)); 141245bc899bSmrg} 141345bc899bSmrg 141445bc899bSmrg#define WriteCrtc(index, value) \ 141545bc899bSmrg outb(pVesa->ioBase + (VGA_IOBASE_COLOR + VGA_CRTC_INDEX_OFFSET), index); \ 141645bc899bSmrg outb(pVesa->ioBase + (VGA_IOBASE_COLOR + VGA_CRTC_DATA_OFFSET), value) 141745bc899bSmrg 141845bc899bSmrgstatic void 141945bc899bSmrgSeqReset(VESAPtr pVesa, Bool start) 142045bc899bSmrg{ 142145bc899bSmrg if (start) { 142245bc899bSmrg WriteSeq(0x00, 0x01); /* Synchronous Reset */ 142345bc899bSmrg } 142445bc899bSmrg else { 142545bc899bSmrg WriteSeq(0x00, 0x03); /* End Reset */ 142645bc899bSmrg } 142745bc899bSmrg} 142845bc899bSmrg 142945bc899bSmrgstatic void 143045bc899bSmrgSaveFonts(ScrnInfoPtr pScrn) 143145bc899bSmrg{ 143245bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 143345bc899bSmrg unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4, scrn; 143445bc899bSmrg 143545bc899bSmrg if (pVesa->fonts != NULL) 143645bc899bSmrg return; 143745bc899bSmrg 143845bc899bSmrg /* If in graphics mode, don't save anything */ 143945bc899bSmrg attr10 = ReadAttr(pVesa, 0x10); 144045bc899bSmrg if (attr10 & 0x01) 144145bc899bSmrg return; 144245bc899bSmrg 144345bc899bSmrg pVesa->fonts = xalloc(16384); 144445bc899bSmrg 144545bc899bSmrg /* save the registers that are needed here */ 144645bc899bSmrg miscOut = ReadMiscOut(); 144745bc899bSmrg gr4 = ReadGr(pVesa, 0x04); 144845bc899bSmrg gr5 = ReadGr(pVesa, 0x05); 144945bc899bSmrg gr6 = ReadGr(pVesa, 0x06); 145045bc899bSmrg seq2 = ReadSeq(pVesa, 0x02); 145145bc899bSmrg seq4 = ReadSeq(pVesa, 0x04); 145245bc899bSmrg 145345bc899bSmrg /* Force into colour mode */ 145445bc899bSmrg WriteMiscOut(miscOut | 0x01); 145545bc899bSmrg 145645bc899bSmrg scrn = ReadSeq(pVesa, 0x01) | 0x20; 145745bc899bSmrg SeqReset(pVesa, TRUE); 145845bc899bSmrg WriteSeq(0x01, scrn); 145945bc899bSmrg SeqReset(pVesa, FALSE); 146045bc899bSmrg 146145bc899bSmrg WriteAttr(pVesa, 0x10, 0x01); /* graphics mode */ 146245bc899bSmrg 146345bc899bSmrg /*font1 */ 146445bc899bSmrg WriteSeq(0x02, 0x04); /* write to plane 2 */ 146545bc899bSmrg WriteSeq(0x04, 0x06); /* enable plane graphics */ 146645bc899bSmrg WriteGr(0x04, 0x02); /* read plane 2 */ 146745bc899bSmrg WriteGr(0x05, 0x00); /* write mode 0, read mode 0 */ 146845bc899bSmrg WriteGr(0x06, 0x05); /* set graphics */ 146945bc899bSmrg slowbcopy_frombus(pVesa->VGAbase, pVesa->fonts, 8192); 147045bc899bSmrg 147145bc899bSmrg /* font2 */ 147245bc899bSmrg WriteSeq(0x02, 0x08); /* write to plane 3 */ 147345bc899bSmrg WriteSeq(0x04, 0x06); /* enable plane graphics */ 147445bc899bSmrg WriteGr(0x04, 0x03); /* read plane 3 */ 147545bc899bSmrg WriteGr(0x05, 0x00); /* write mode 0, read mode 0 */ 147645bc899bSmrg WriteGr(0x06, 0x05); /* set graphics */ 147745bc899bSmrg slowbcopy_frombus(pVesa->VGAbase, pVesa->fonts + 8192, 8192); 147845bc899bSmrg 147945bc899bSmrg scrn = ReadSeq(pVesa, 0x01) & ~0x20; 148045bc899bSmrg SeqReset(pVesa, TRUE); 148145bc899bSmrg WriteSeq(0x01, scrn); 148245bc899bSmrg SeqReset(pVesa, FALSE); 148345bc899bSmrg 148445bc899bSmrg /* Restore clobbered registers */ 148545bc899bSmrg WriteAttr(pVesa, 0x10, attr10); 148645bc899bSmrg WriteSeq(0x02, seq2); 148745bc899bSmrg WriteSeq(0x04, seq4); 148845bc899bSmrg WriteGr(0x04, gr4); 148945bc899bSmrg WriteGr(0x05, gr5); 149045bc899bSmrg WriteGr(0x06, gr6); 149145bc899bSmrg WriteMiscOut(miscOut); 149245bc899bSmrg} 149345bc899bSmrg 149445bc899bSmrgstatic void 149545bc899bSmrgRestoreFonts(ScrnInfoPtr pScrn) 149645bc899bSmrg{ 149745bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 149845bc899bSmrg unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4, scrn; 149945bc899bSmrg 150045bc899bSmrg if (pVesa->fonts == NULL) 150145bc899bSmrg return; 150245bc899bSmrg 150345bc899bSmrg if (pVesa->mapPhys == 0xa0000 && pVesa->curBank != 0) 150445bc899bSmrg VESABankSwitch(pScrn->pScreen, 0); 150545bc899bSmrg 150645bc899bSmrg /* save the registers that are needed here */ 150745bc899bSmrg miscOut = ReadMiscOut(); 150845bc899bSmrg attr10 = ReadAttr(pVesa, 0x10); 150945bc899bSmrg gr1 = ReadGr(pVesa, 0x01); 151045bc899bSmrg gr3 = ReadGr(pVesa, 0x03); 151145bc899bSmrg gr4 = ReadGr(pVesa, 0x04); 151245bc899bSmrg gr5 = ReadGr(pVesa, 0x05); 151345bc899bSmrg gr6 = ReadGr(pVesa, 0x06); 151445bc899bSmrg gr8 = ReadGr(pVesa, 0x08); 151545bc899bSmrg seq2 = ReadSeq(pVesa, 0x02); 151645bc899bSmrg seq4 = ReadSeq(pVesa, 0x04); 151745bc899bSmrg 151845bc899bSmrg /* Force into colour mode */ 151945bc899bSmrg WriteMiscOut(miscOut | 0x01); 152045bc899bSmrg 152145bc899bSmrg scrn = ReadSeq(pVesa, 0x01) | 0x20; 152245bc899bSmrg SeqReset(pVesa, TRUE); 152345bc899bSmrg WriteSeq(0x01, scrn); 152445bc899bSmrg SeqReset(pVesa, FALSE); 152545bc899bSmrg 152645bc899bSmrg WriteAttr(pVesa, 0x10, 0x01); /* graphics mode */ 152745bc899bSmrg if (pScrn->depth == 4) { 152845bc899bSmrg /* GJA */ 152945bc899bSmrg WriteGr(0x03, 0x00); /* don't rotate, write unmodified */ 153045bc899bSmrg WriteGr(0x08, 0xFF); /* write all bits in a byte */ 153145bc899bSmrg WriteGr(0x01, 0x00); /* all planes come from CPU */ 153245bc899bSmrg } 153345bc899bSmrg 153445bc899bSmrg WriteSeq(0x02, 0x04); /* write to plane 2 */ 153545bc899bSmrg WriteSeq(0x04, 0x06); /* enable plane graphics */ 153645bc899bSmrg WriteGr(0x04, 0x02); /* read plane 2 */ 153745bc899bSmrg WriteGr(0x05, 0x00); /* write mode 0, read mode 0 */ 153845bc899bSmrg WriteGr(0x06, 0x05); /* set graphics */ 153945bc899bSmrg slowbcopy_tobus(pVesa->fonts, pVesa->VGAbase, 8192); 154045bc899bSmrg 154145bc899bSmrg WriteSeq(0x02, 0x08); /* write to plane 3 */ 154245bc899bSmrg WriteSeq(0x04, 0x06); /* enable plane graphics */ 154345bc899bSmrg WriteGr(0x04, 0x03); /* read plane 3 */ 154445bc899bSmrg WriteGr(0x05, 0x00); /* write mode 0, read mode 0 */ 154545bc899bSmrg WriteGr(0x06, 0x05); /* set graphics */ 154645bc899bSmrg slowbcopy_tobus(pVesa->fonts + 8192, pVesa->VGAbase, 8192); 154745bc899bSmrg 154845bc899bSmrg scrn = ReadSeq(pVesa, 0x01) & ~0x20; 154945bc899bSmrg SeqReset(pVesa, TRUE); 155045bc899bSmrg WriteSeq(0x01, scrn); 155145bc899bSmrg SeqReset(pVesa, FALSE); 155245bc899bSmrg 155345bc899bSmrg /* restore the registers that were changed */ 155445bc899bSmrg WriteMiscOut(miscOut); 155545bc899bSmrg WriteAttr(pVesa, 0x10, attr10); 155645bc899bSmrg WriteGr(0x01, gr1); 155745bc899bSmrg WriteGr(0x03, gr3); 155845bc899bSmrg WriteGr(0x04, gr4); 155945bc899bSmrg WriteGr(0x05, gr5); 156045bc899bSmrg WriteGr(0x06, gr6); 156145bc899bSmrg WriteGr(0x08, gr8); 156245bc899bSmrg WriteSeq(0x02, seq2); 156345bc899bSmrg WriteSeq(0x04, seq4); 156445bc899bSmrg} 156545bc899bSmrg 156645bc899bSmrgstatic Bool 156745bc899bSmrgVESASaveScreen(ScreenPtr pScreen, int mode) 156845bc899bSmrg{ 156945bc899bSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 157045bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 157145bc899bSmrg Bool on = xf86IsUnblank(mode); 157245bc899bSmrg 157345bc899bSmrg if (on) 157445bc899bSmrg SetTimeSinceLastInputEvent(); 157545bc899bSmrg 157645bc899bSmrg if (pScrn->vtSema) { 157745bc899bSmrg unsigned char scrn = ReadSeq(pVesa, 0x01); 157845bc899bSmrg 157945bc899bSmrg if (on) 158045bc899bSmrg scrn &= ~0x20; 158145bc899bSmrg else 158245bc899bSmrg scrn |= 0x20; 158345bc899bSmrg SeqReset(pVesa, TRUE); 158445bc899bSmrg WriteSeq(0x01, scrn); 158545bc899bSmrg SeqReset(pVesa, FALSE); 158645bc899bSmrg } 158745bc899bSmrg 158845bc899bSmrg return (TRUE); 158945bc899bSmrg} 159045bc899bSmrg 159145bc899bSmrgstatic int 159245bc899bSmrgVESABankSwitch(ScreenPtr pScreen, unsigned int iBank) 159345bc899bSmrg{ 159445bc899bSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 159545bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 159645bc899bSmrg 159745bc899bSmrg if (pVesa->curBank == iBank) 159845bc899bSmrg return (0); 159945bc899bSmrg if (!VBEBankSwitch(pVesa->pVbe, iBank, 0)) 160045bc899bSmrg return (1); 160145bc899bSmrg if (pVesa->bankSwitchWindowB) { 160245bc899bSmrg if (!VBEBankSwitch(pVesa->pVbe, iBank, 1)) 160345bc899bSmrg return (1); 160445bc899bSmrg } 160545bc899bSmrg pVesa->curBank = iBank; 160645bc899bSmrg 160745bc899bSmrg return (0); 160845bc899bSmrg} 160945bc899bSmrg 161045bc899bSmrgBool 161145bc899bSmrgVESASaveRestore(ScrnInfoPtr pScrn, vbeSaveRestoreFunction function) 161245bc899bSmrg{ 161345bc899bSmrg VESAPtr pVesa; 161445bc899bSmrg 161545bc899bSmrg if (MODE_QUERY < 0 || function > MODE_RESTORE) 161645bc899bSmrg return (FALSE); 161745bc899bSmrg 161845bc899bSmrg pVesa = VESAGetRec(pScrn); 161945bc899bSmrg 162045bc899bSmrg 162145bc899bSmrg /* Query amount of memory to save state */ 162245bc899bSmrg if (function == MODE_QUERY || 162345bc899bSmrg (function == MODE_SAVE && pVesa->state == NULL)) { 162445bc899bSmrg 162545bc899bSmrg /* Make sure we save at least this information in case of failure */ 162645bc899bSmrg (void)VBEGetVBEMode(pVesa->pVbe, &pVesa->stateMode); 162745bc899bSmrg SaveFonts(pScrn); 162845bc899bSmrg 162945bc899bSmrg if (pVesa->major > 1) { 163045bc899bSmrg if (!VBESaveRestore(pVesa->pVbe,function,(pointer)&pVesa->state, 163145bc899bSmrg &pVesa->stateSize,&pVesa->statePage)) 163245bc899bSmrg return FALSE; 163345bc899bSmrg 163445bc899bSmrg } 163545bc899bSmrg } 163645bc899bSmrg 163745bc899bSmrg /* Save/Restore Super VGA state */ 163845bc899bSmrg if (function != MODE_QUERY) { 163945bc899bSmrg Bool retval = TRUE; 164045bc899bSmrg 164145bc899bSmrg if (pVesa->major > 1) { 164245bc899bSmrg if (function == MODE_RESTORE) 164345bc899bSmrg memcpy(pVesa->state, pVesa->pstate, pVesa->stateSize); 164445bc899bSmrg 164545bc899bSmrg if ((retval = VBESaveRestore(pVesa->pVbe,function, 164645bc899bSmrg (pointer)&pVesa->state, 164745bc899bSmrg &pVesa->stateSize,&pVesa->statePage)) 164845bc899bSmrg && function == MODE_SAVE) { 164945bc899bSmrg /* don't rely on the memory not being touched */ 165045bc899bSmrg if (pVesa->pstate == NULL) 165145bc899bSmrg pVesa->pstate = xalloc(pVesa->stateSize); 165245bc899bSmrg memcpy(pVesa->pstate, pVesa->state, pVesa->stateSize); 165345bc899bSmrg } 165445bc899bSmrg } 165545bc899bSmrg 165645bc899bSmrg if (function == MODE_RESTORE) { 165745bc899bSmrg VBESetVBEMode(pVesa->pVbe, pVesa->stateMode, NULL); 165845bc899bSmrg RestoreFonts(pScrn); 165945bc899bSmrg } 166045bc899bSmrg 166145bc899bSmrg if (!retval) 166245bc899bSmrg return (FALSE); 166345bc899bSmrg 166445bc899bSmrg } 166545bc899bSmrg 166645bc899bSmrg return (TRUE); 166745bc899bSmrg} 166845bc899bSmrg 166945bc899bSmrgstatic void 167045bc899bSmrgVESADisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode, 167145bc899bSmrg int flags) 167245bc899bSmrg{ 167345bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 167445bc899bSmrg 167545bc899bSmrg if (!pScrn->vtSema) 167645bc899bSmrg return; 167745bc899bSmrg 167850f2e948Smrg VBEDPMSSet(pVesa->pVbe, mode); 167945bc899bSmrg} 168045bc899bSmrg 168145bc899bSmrg/*********************************************************************** 168245bc899bSmrg * DGA stuff 168345bc899bSmrg ***********************************************************************/ 168445bc899bSmrgstatic Bool VESADGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, 168545bc899bSmrg unsigned char **ApertureBase, 168645bc899bSmrg int *ApertureSize, int *ApertureOffset, 168745bc899bSmrg int *flags); 168845bc899bSmrgstatic Bool VESADGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode); 168945bc899bSmrgstatic void VESADGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags); 169045bc899bSmrg 169145bc899bSmrgstatic Bool 169245bc899bSmrgVESADGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, 169345bc899bSmrg unsigned char **ApertureBase, int *ApertureSize, 169445bc899bSmrg int *ApertureOffset, int *flags) 169545bc899bSmrg{ 169645bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 169745bc899bSmrg 169845bc899bSmrg *DeviceName = NULL; /* No special device */ 169945bc899bSmrg *ApertureBase = (unsigned char *)(long)(pVesa->mapPhys); 170045bc899bSmrg *ApertureSize = pVesa->mapSize; 170145bc899bSmrg *ApertureOffset = pVesa->mapOff; 170245bc899bSmrg *flags = DGA_NEED_ROOT; 170345bc899bSmrg 170445bc899bSmrg return (TRUE); 170545bc899bSmrg} 170645bc899bSmrg 170745bc899bSmrgstatic Bool 170845bc899bSmrgVESADGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode) 170945bc899bSmrg{ 171045bc899bSmrg DisplayModePtr pMode; 171145bc899bSmrg int scrnIdx = pScrn->pScreen->myNum; 171245bc899bSmrg int frameX0, frameY0; 171345bc899bSmrg 171445bc899bSmrg if (pDGAMode) { 171545bc899bSmrg pMode = pDGAMode->mode; 171645bc899bSmrg frameX0 = frameY0 = 0; 171745bc899bSmrg } 171845bc899bSmrg else { 171945bc899bSmrg if (!(pMode = pScrn->currentMode)) 172045bc899bSmrg return (TRUE); 172145bc899bSmrg 172245bc899bSmrg frameX0 = pScrn->frameX0; 172345bc899bSmrg frameY0 = pScrn->frameY0; 172445bc899bSmrg } 172545bc899bSmrg 172645bc899bSmrg if (!(*pScrn->SwitchMode)(scrnIdx, pMode, 0)) 172745bc899bSmrg return (FALSE); 172845bc899bSmrg (*pScrn->AdjustFrame)(scrnIdx, frameX0, frameY0, 0); 172945bc899bSmrg 173045bc899bSmrg return (TRUE); 173145bc899bSmrg} 173245bc899bSmrg 173345bc899bSmrgstatic void 173445bc899bSmrgVESADGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) 173545bc899bSmrg{ 173645bc899bSmrg (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags); 173745bc899bSmrg} 173845bc899bSmrg 173945bc899bSmrgstatic int 174045bc899bSmrgVESADGAGetViewport(ScrnInfoPtr pScrn) 174145bc899bSmrg{ 174245bc899bSmrg return (0); 174345bc899bSmrg} 174445bc899bSmrg 174545bc899bSmrgstatic DGAFunctionRec VESADGAFunctions = 174645bc899bSmrg{ 174745bc899bSmrg VESADGAOpenFramebuffer, 174845bc899bSmrg NULL, /* CloseFramebuffer */ 174945bc899bSmrg VESADGASetMode, 175045bc899bSmrg VESADGASetViewport, 175145bc899bSmrg VESADGAGetViewport, 175245bc899bSmrg NULL, /* Sync */ 175345bc899bSmrg NULL, /* FillRect */ 175445bc899bSmrg NULL, /* BlitRect */ 175545bc899bSmrg NULL, /* BlitTransRect */ 175645bc899bSmrg}; 175745bc899bSmrg 175845bc899bSmrgstatic void 175945bc899bSmrgVESADGAAddModes(ScrnInfoPtr pScrn) 176045bc899bSmrg{ 176145bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 176245bc899bSmrg DisplayModePtr pMode = pScrn->modes; 176345bc899bSmrg DGAModePtr pDGAMode; 176445bc899bSmrg 176545bc899bSmrg do { 176645bc899bSmrg pDGAMode = xrealloc(pVesa->pDGAMode, 176745bc899bSmrg (pVesa->nDGAMode + 1) * sizeof(DGAModeRec)); 176845bc899bSmrg if (!pDGAMode) 176945bc899bSmrg break; 177045bc899bSmrg 177145bc899bSmrg pVesa->pDGAMode = pDGAMode; 177245bc899bSmrg pDGAMode += pVesa->nDGAMode; 177345bc899bSmrg (void)memset(pDGAMode, 0, sizeof(DGAModeRec)); 177445bc899bSmrg 177545bc899bSmrg ++pVesa->nDGAMode; 177645bc899bSmrg pDGAMode->mode = pMode; 177745bc899bSmrg pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; 177845bc899bSmrg pDGAMode->byteOrder = pScrn->imageByteOrder; 177945bc899bSmrg pDGAMode->depth = pScrn->depth; 178045bc899bSmrg pDGAMode->bitsPerPixel = pScrn->bitsPerPixel; 178145bc899bSmrg pDGAMode->red_mask = pScrn->mask.red; 178245bc899bSmrg pDGAMode->green_mask = pScrn->mask.green; 178345bc899bSmrg pDGAMode->blue_mask = pScrn->mask.blue; 178445bc899bSmrg pDGAMode->visualClass = pScrn->bitsPerPixel > 8 ? 178545bc899bSmrg TrueColor : PseudoColor; 178645bc899bSmrg pDGAMode->xViewportStep = 1; 178745bc899bSmrg pDGAMode->yViewportStep = 1; 178845bc899bSmrg pDGAMode->viewportWidth = pMode->HDisplay; 178945bc899bSmrg pDGAMode->viewportHeight = pMode->VDisplay; 179045bc899bSmrg 179145bc899bSmrg pDGAMode->bytesPerScanline = pVesa->maxBytesPerScanline; 179245bc899bSmrg pDGAMode->imageWidth = pMode->HDisplay; 179345bc899bSmrg pDGAMode->imageHeight = pMode->VDisplay; 179445bc899bSmrg pDGAMode->pixmapWidth = pDGAMode->imageWidth; 179545bc899bSmrg pDGAMode->pixmapHeight = pDGAMode->imageHeight; 179645bc899bSmrg pDGAMode->maxViewportX = pScrn->virtualX - 179745bc899bSmrg pDGAMode->viewportWidth; 179845bc899bSmrg pDGAMode->maxViewportY = pScrn->virtualY - 179945bc899bSmrg pDGAMode->viewportHeight; 180045bc899bSmrg 180145bc899bSmrg pDGAMode->address = pVesa->base; 180245bc899bSmrg 180345bc899bSmrg pMode = pMode->next; 180445bc899bSmrg } while (pMode != pScrn->modes); 180545bc899bSmrg} 180645bc899bSmrg 180745bc899bSmrgstatic Bool 180845bc899bSmrgVESADGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) 180945bc899bSmrg{ 181045bc899bSmrg VESAPtr pVesa = VESAGetRec(pScrn); 181145bc899bSmrg 181245bc899bSmrg if (pScrn->depth < 8 || pVesa->mapPhys == 0xa0000L) 181345bc899bSmrg return (FALSE); 181445bc899bSmrg 181545bc899bSmrg if (!pVesa->nDGAMode) 181645bc899bSmrg VESADGAAddModes(pScrn); 181745bc899bSmrg 181845bc899bSmrg return (DGAInit(pScreen, &VESADGAFunctions, 181945bc899bSmrg pVesa->pDGAMode, pVesa->nDGAMode)); 182045bc899bSmrg} 1821