/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * */ /* * File Contents: This is the main module configures the interfacing with * the X server. The individual modules will be loaded based * upon the options selected from the XF86Config. This file * also has modules for finding supported modes, turning on * the modes based on options. * * Project: Geode Xfree Frame buffer device driver. * */ /* Includes that are used by all drivers */ #include "xf86.h" #include "xf86_OSproc.h" #include "xf86_ansic.h" #include "xf86_libc.h" #include "xf86Resources.h" /* We may want inb() and outb() */ #include "compiler.h" /* We may want to access the PCI config space */ #include "xf86PciInfo.h" #include "xf86Pci.h" /* Colormap handling stuff */ #include "xf86cmap.h" #define RC_MAX_DEPTH 24 #include "amd.h" #include "gfx_defs.h" #include "gfx_regs.h" #include "panel.h" /* Frame buffer stuff */ #if CFB /* * If using cfb, cfb.h is required. Select the others for the bpp values * the driver supports. */ #define PSZ 8 /* needed for cfb.h */ #include "cfb.h" #undef PSZ #include "cfb16.h" #include "cfb24.h" #include "cfb32.h" #else #include "fb.h" #endif #include "shadowfb.h" /* Machine independent stuff */ #include "mipointer.h" #include "mibank.h" #include "micmap.h" /* All drivers implementing backing store need this */ #include "mibstore.h" #include "vgaHW.h" #include "vbe.h" /* Check for some extensions */ #ifdef XFreeXDGA #define _XF86_DGA_SERVER_ #include "extensions/xf86dgastr.h" #endif /* XFreeXDGA */ #ifdef DPMSExtension #include "globals.h" #include "opaque.h" #define DPMS_SERVER #include "extensions/dpms.h" #endif /* DPMSExtension */ #include "amd_gx_vga.c" extern SymTabRec GeodeChipsets[]; extern OptionInfoRec GX_GeodeOptions[]; /* Forward definitions */ static Bool GXPreInit(ScrnInfoPtr, int); static Bool GXScreenInit(int, ScreenPtr, int, char **); static Bool GXEnterVT(int, int); static void GXLeaveVT(int, int); static void GXFreeScreen(int, int); void GXAdjustFrame(int, int, int, int); Bool GXSwitchMode(int, DisplayModePtr, int); static int GXValidMode(int, DisplayModePtr, Bool, int); static void GXLoadPalette(ScrnInfoPtr pScrni, int numColors, int *indizes, LOCO * colors, VisualPtr pVisual); static Bool GXMapMem(ScrnInfoPtr); static Bool GXUnmapMem(ScrnInfoPtr); static void gx_set_DvLineSize(unsigned int pitch); extern Bool GXAccelInit(ScreenPtr pScrn); extern Bool GXHWCursorInit(ScreenPtr pScrn); extern void GXHideCursor(ScrnInfoPtr pScrni); extern void GXShowCursor(ScrnInfoPtr pScrni); extern void GXPointerMoved(int index, int x, int y); extern void GXRotationInit(ScrnInfoPtr pScrni); extern void GXShadowFBInit(ScreenPtr pScrn, GeodeRec *pGeode, int bytpp); extern void GXInitVideo(ScreenPtr pScrn); extern Bool GXDGAInit(ScreenPtr pScrn); extern void GXLoadCursorImage(ScrnInfoPtr pScrni, unsigned char *src); unsigned long fb; /* Existing Processor Models */ #define GX1 0x1 #define GX 0x2 #define GX_CRT 0x6 #define GX_TFT 0xA /* List of symbols from other modules that this module references.The purpose * is that to avoid unresolved symbol warnings */ extern const char *amdVgahwSymbols[]; extern const char *amdVbeSymbols[]; extern const char *amdInt10Symbols[]; #if CFB extern const char *amdCfbSymbols[]; #else extern const char *amdFbSymbols[]; #endif extern const char *amdXaaSymbols[]; extern const char *amdExaSymbols[]; extern const char *amdRamdacSymbols[]; extern const char *amdShadowSymbols[]; void GXSetupChipsetFPtr(ScrnInfoPtr pScrn); GeodeRec *GXGetRec(ScrnInfoPtr pScrni); void get_flatpanel_info(const char *options, int *W, int *H, int *D, int *C, int *T); void gx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp); void gx_enable_dac_power(ScrnInfoPtr pScrni); void gx_disable_dac_power(ScrnInfoPtr pScrni); #if DEBUGLVL>0 FILE *zdfp = NULL; #endif void GXSetupChipsetFPtr(ScrnInfoPtr pScrn) { #if DEBUGLVL>0 if (zdfp == NULL) { zdfp = fopen("/tmp/xwin.log", "w"); #if DEBUGTIM==0 setbuf(zdfp, NULL); #endif } #endif DEBUGMSG(1, (0, X_INFO, "GXSetupChipsetFPtr!\n")); pScrn->PreInit = GXPreInit; pScrn->ScreenInit = GXScreenInit; pScrn->SwitchMode = GXSwitchMode; pScrn->AdjustFrame = GXAdjustFrame; pScrn->EnterVT = GXEnterVT; pScrn->LeaveVT = GXLeaveVT; pScrn->FreeScreen = GXFreeScreen; pScrn->ValidMode = GXValidMode; } /*---------------------------------------------------------------------------- * GXGetRec. * * Description :This function allocates a GeodeRec and hooks into pScrni * struct's driverPrivate member of ScreeenInfo structure. * * Parameters. * pScrni :Pointer handle to the screenonfo structure. * * Returns :allocated pScrninfo structure. * * Comments :none * *---------------------------------------------------------------------------- */ GeodeRec * GXGetRec(ScrnInfoPtr pScrni) { if (!pScrni->driverPrivate) { GeodeRec *pGeode; pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); #if INT10_SUPPORT pGeode->vesa = xcalloc(sizeof(VESARec), 1); #endif } return GEODEPTR(pScrni); } /*---------------------------------------------------------------------------- * GXFreeRec. * * Description :This function deallocates and disconnect the GeodeRec from * the pScrni struct's driverPrivate member. * * Parameters. * pScrni :Pointer handle to the screenonfo structure. * * Returns :none * * Comments :none * *---------------------------------------------------------------------------- */ static void GXFreeRec(ScrnInfoPtr pScrni) { if (pScrni->driverPrivate == NULL) { return; } xfree(pScrni->driverPrivate); pScrni->driverPrivate = NULL; } /*---------------------------------------------------------------------------- * GXSaveScreen. * * Description :This is todo the screen blanking * * Parameters. * pScrn :Handle to ScreenPtr structure. * mode :mode is used by vgaHWSaveScren to check blnak os on. * * Returns :TRUE on success and FALSE on failure. * * Comments :none *---------------------------------------------------------------------------- */ static Bool GXSaveScreen(ScreenPtr pScrn, int mode) { ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; GeodePtr pGeode = GEODEPTR(pScrni); if (pGeode->useVGA && !pScrni->vtSema) return vgaHWSaveScreen(pScrn, mode); return TRUE; } /*---------------------------------------------------------------------------- * get_flatpanel_info. * * Description: This gets the parameter values of the flatpanel attached. * * Parameters: * options: Pointer to the display options. * W: Pointer to the width of the panel * H: Pointer to the height of the panel * D: Pointer to the depth of the panel. * C: Pointer to the color of the panel. * T: Pointer to the type of the panel. * * Returns: none. * * Comments: none *------------------------------------------------------------------------ */ void get_flatpanel_info(const char *options, int *W, int *H, int *D, int *C, int *T) { char *pnl_opt; pnl_opt = strtok((char *)options, ":"); *W = strtoul(pnl_opt, NULL, 0); pnl_opt = strtok(NULL, ":"); *H = strtoul(pnl_opt, NULL, 0); pnl_opt = strtok(NULL, ":"); *D = strtoul(pnl_opt, NULL, 0); pnl_opt = strtok(NULL, ":"); *C = strtoul(pnl_opt, NULL, 0); pnl_opt = strtok(NULL, ":"); *T = strtoul(pnl_opt, NULL, 0); *C = (*C) ? PNL_COLOR_PANEL : PNL_MONO_PANEL; switch (*T) { case 0: *T = PNL_SSTN; break; case 1: *T = PNL_DSTN; break; case 2: default: *T = PNL_TFT; break; } if ((*W != 640) && (*W != 800) && (*W != 1024)) *W = 640; if ((*H != 480) && (*H != 600) && (*H != 768)) *H = 480; } static xf86MonPtr GXProbeDDC(ScrnInfoPtr pScrni, int index) { vbeInfoPtr pVbe; xf86MonPtr ddc = NULL; if (xf86LoadSubModule(pScrni, "vbe")) { pVbe = VBEInit(NULL, index); ddc = vbeDoEDID(pVbe, NULL); vbeFree(pVbe); } return ddc; } static void GXDecodeDDC(ScrnInfoPtr pScrni, xf86MonPtr ddc) { int i; DEBUGMSG(1, (0, X_INFO, "Detected monitor DDC (%4s) id %d serno %d week %d year %d " "nsects %d\n", &ddc->vendor.name[0], ddc->vendor.prod_id, ddc->vendor.serial, ddc->vendor.week, ddc->vendor.year, ddc->no_sections)); for (i = 0; i < DET_TIMINGS; ++i) { struct detailed_monitor_section *dp = &ddc->det_mon[i]; switch (dp->type) { case DT: { struct detailed_timings *r = &dp->section.d_timings; DEBUGMSG(1, (0, X_INFO, " mon det timing %0.3f %dx%d\n", r->clock / 1000000.0, r->h_active, r->v_active)); DEBUGMSG(1, (0, X_INFO, " mon border %d,%d laced %d stereo %d sync %d, misc" " %d\n", r->h_border, r->v_border, r->interlaced, r->stereo, r->sync, r->misc)); } break; case DS_SERIAL: { char *serial_no = (char *)&dp->section.serial[0]; DEBUGMSG(1, (0, X_INFO, " mon serial %13s\n", serial_no)); } break; case DS_ASCII_STR: { char *ascii = (char *)&dp->section.ascii_data[0]; DEBUGMSG(1, (0, X_INFO, " mon ascii_str %13s\n", ascii)); } break; case DS_NAME: { char *name = (char *)&dp->section.name[0]; DEBUGMSG(1, (0, X_INFO, " mon name %13s\n", name)); } break; case DS_RANGES: { struct monitor_ranges *r = &dp->section.ranges; DEBUGMSG(1, (0, X_INFO, " mon ranges v %d-%d h %d-%d clk %d\n", r->min_v, r->max_v, r->min_h, r->max_h, r->max_clock)); } break; case DS_WHITE_P: { struct whitePoints *wp = &dp->section.wp[0]; DEBUGMSG(1, (0, X_INFO, " mon whitept %f,%f %f,%f idx %d,%d gamma %f,%f\n", wp[1].white_x, wp[1].white_y, wp[2].white_x, wp[2].white_y, wp[1].index, wp[2].index, wp[1].white_gamma, wp[2].white_gamma)); } break; case DS_STD_TIMINGS: { struct std_timings *t = &dp->section.std_t[0]; DEBUGMSG(1, (0, X_INFO, " mon std_timing no size @rate, id\n")); for (i = 0; i < 5; ++i) DEBUGMSG(1, (0, X_INFO, " %d %5dx%-5d @%-4d %d\n", i, t[i].hsize, t[i].vsize, t[i].refresh, t[i].id)); } break; } } } /*---------------------------------------------------------------------------- * GXPreInit. * * Description :This function is called only once ate teh server startup * * Parameters. * pScrni :Handle to ScreenPtr structure. * flags :flags may be used to check the probeed one with config. * * Returns :TRUE on success and FALSE on failure. * * Comments :none. *---------------------------------------------------------------------------- */ static Bool GXPreInit(ScrnInfoPtr pScrni, int flags) { ClockRangePtr GeodeClockRange; MessageType from; int i = 0; GeodeRec *pGeode; char *mod = NULL; xf86MonPtr ddc = NULL; OptionInfoRec *GeodeOptions = &GX_GeodeOptions[0]; #if CFB char *reqSymbol = NULL; #endif /* CFB */ #if INT10_SUPPORT VESARec *pVesa; #endif unsigned int PitchInc = 0, minPitch = 0, maxPitch = 0; unsigned int minHeight = 0, maxHeight = 0, maxWidth = 0; unsigned int SupportFlags; const char *s; char **modes; /* * Setup the ClockRanges, which describe what clock ranges are * available, and what sort of modes they can be used for. */ GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); GeodeClockRange->next = NULL; GeodeClockRange->minClock = 25175; GeodeClockRange->maxClock = 229500; GeodeClockRange->clockIndex = -1; /* programmable */ GeodeClockRange->interlaceAllowed = TRUE; GeodeClockRange->doubleScanAllowed = FALSE; /* XXX check this */ DEBUGMSG(1, (0, X_INFO, "GXPreInit!\n")); /* Allocate driver private structure */ if (!(pGeode = GXGetRec(pScrni))) return FALSE; if (pScrni->numEntities != 1) return FALSE; pGeode->pEnt = xf86GetEntityInfo(pScrni->entityList[i]); if (pGeode->pEnt->resources) return FALSE; pGeode->Chipset = pGeode->pEnt->chipset; pScrni->chipset = (char *)xf86TokenToString(GeodeChipsets, pGeode->pEnt->chipset); DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "PROBEDDC\n")); /* Note that we can't do this without VGA */ if (flags & PROBE_DETECT != 0) { ConfiguredMonitor = GXProbeDDC(pScrni, pGeode->pEnt->index); return TRUE; } /* Hardware detection */ pGeode->cpu_version = gfx_detect_cpu(); if ((pGeode->cpu_version & 0xFF) == GFX_CPU_REDCLOUD) { Q_WORD msrValue; pGeode->DetectedChipSet = GX; /* See if this a CRT or TFT part */ gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msrValue); pGeode->DetectedChipSet = ((msrValue.low & RCDF_CONFIG_FMT_MASK) == RCDF_CONFIG_FMT_FP) ? GX_TFT : GX_CRT; } pGeode->vid_version = gfx_detect_video(); pGeode->FBLinearAddr = gfx_get_frame_buffer_base(); /* update the max clock from the one system suports */ GeodeClockRange->maxClock = gfx_get_max_supported_pixel_clock(); /* Set Durango register pointers */ if (pGeode->DetectedChipSet & GX) { pGeode->cpu_reg_size = 0x4000; pGeode->gp_reg_size = 0x4000; pGeode->vid_reg_size = 0x4000; } else { pGeode->cpu_reg_size = 0x9000; pGeode->vid_reg_size = 0x1000; } pGeode->FBVGAActive = 0; /* Fill in the monitor field */ pScrni->monitor = pScrni->confScreen->monitor; SupportFlags = Support24bppFb | Support32bppFb; if (!xf86SetDepthBpp(pScrni, 8, 8, 8, SupportFlags)) { return FALSE; } else { if (!((pScrni->depth == 8) || (pScrni->depth == 16) || (pScrni->depth == 24) || (pScrni->depth == 32))) { DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "Given depth (%d bpp) is not supported by this driver\n", pScrni->depth)); return FALSE; } } /*This must happen after pScrni->display has been set * * because xf86SetWeight references it. */ if (pScrni->depth > 8) { rgb BitsPerComponent = { 0, 0, 0 }; rgb BitMask = { 0, 0, 0 }; if (pScrni->depth > 16) { BitsPerComponent.red = 8; BitsPerComponent.green = 8; BitsPerComponent.blue = 8; BitMask.red = 0xFF0000; BitMask.green = 0x00FF00; BitMask.blue = 0x0000FF; } if (!xf86SetWeight(pScrni, BitsPerComponent, BitMask)) { return FALSE; } else { /* XXX Check if the returned weight is supported */ } } xf86PrintDepthBpp(pScrni); if (!xf86SetDefaultVisual(pScrni, -1)) return FALSE; if (pScrni->depth > 1) { Gamma zeros = { 0.0, 0.0, 0.0 }; if (!xf86SetGamma(pScrni, zeros)) { return FALSE; } } /* We use a programmable clock */ pScrni->progClock = TRUE; xf86CollectOptions(pScrni, NULL); xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); pGeode->useVGA = TRUE; if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOVGA, FALSE)) pGeode->useVGA = FALSE; xf86DrvMsg(pScrni->scrnIndex, X_DEFAULT, "useVGA=%d\n", pGeode->useVGA); if (pGeode->useVGA) { #if INT10_SUPPORT if (!xf86LoadSubModule(pScrni, "int10")) return FALSE; xf86LoaderReqSymLists(amdInt10Symbols, NULL); pVesa = pGeode->vesa; if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "Unable to initialize INT10 support\n")); return FALSE; } #endif if (!xf86LoadSubModule(pScrni, "vgahw")) return FALSE; xf86LoaderReqSymLists(amdVgahwSymbols, NULL); pGeode->FBAvail = gfx_get_frame_buffer_size(); } else { if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_FBSIZE, &(pGeode->FBAvail))) pGeode->FBAvail = 0x800000; } if (!GXMapMem(pScrni)) return FALSE; pGeode->FBVGAActive = FALSE; if (pGeode->useVGA) pGeode->FBVGAActive = gu2_get_vga_active(); /*Set the bits per RGB for 8bpp mode */ if (pScrni->depth == 8) pScrni->rgbBits = 8; from = X_DEFAULT; /* * *The preferred method is to use the "hw cursor" option as a tri-state * *option, with the default set above. */ pGeode->HWCursor = TRUE; if (xf86GetOptValBool(GeodeOptions, GX_OPTION_HW_CURSOR, &pGeode->HWCursor)) { from = X_CONFIG; } /* For compatibility, accept this too (as an override) */ if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_SW_CURSOR, FALSE)) { from = X_CONFIG; pGeode->HWCursor = FALSE; } pGeode->Compression = TRUE; if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOCOMPRESSION, FALSE)) { pGeode->Compression = FALSE; } pGeode->NoAccel = FALSE; if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOACCEL, FALSE)) { pGeode->NoAccel = TRUE; } if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_IMG_BUFS, &(pGeode->NoOfImgBuffers))) pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; if (pGeode->NoOfImgBuffers <= 0) pGeode->NoOfImgBuffers = 0; if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, &(pGeode->NoOfColorExpandLines))) pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; if (pGeode->NoOfColorExpandLines <= 0) pGeode->NoOfColorExpandLines = 0; if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_EXA_SCRATCH_BFRSZ, &(pGeode->exaBfrSz))) pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; if (pGeode->exaBfrSz <= 0) pGeode->exaBfrSz = 0; pGeode->CustomMode = FALSE; if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_CUSTOM_MODE, FALSE)) { pGeode->CustomMode = TRUE; } pGeode->Panel = FALSE; if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_FLATPANEL, FALSE)) { pGeode->Panel = TRUE; } /* Force the Panel on if on a GX TFT part, no CRT support anyway */ if (pGeode->DetectedChipSet == GX_TFT) { pGeode->Panel = TRUE; } /* If on a CRT and Panel flag set, disable Panel */ if ((pGeode->DetectedChipSet == GX_CRT) && (pGeode->Panel)) pGeode->Panel = FALSE; /* if FP not supported in BIOS, then turn off user option */ /* NOTE * NOTE * NOTE - this probably won't work for OLPC! */ #if defined(PNL_SUP) if (pGeode->Panel) { pGeode->Panel = Pnl_IsPanelEnabledInBIOS(); if (pGeode->Panel) { Pnl_GetPanelInfoFromBIOS(&pGeode->FPBX, &pGeode->FPBY, &pGeode->FPBB, &pGeode->FPBF); Pnl_PowerUp(); } else Pnl_PowerDown(); } #endif pGeode->useEXA = FALSE; from = X_DEFAULT; if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ACCEL_METHOD))) { if (!xf86NameCmp(s, "XAA")) { from = X_CONFIG; pGeode->useEXA = FALSE; #if XF86EXA } else if (!xf86NameCmp(s, "EXA")) { from = X_CONFIG; pGeode->useEXA = TRUE; #endif } else xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Unknown acceleration architecture - %s\n", s); } xf86DrvMsg(pScrni->scrnIndex, from, "Using %s acceleration architecture\n", pGeode->useEXA ? "EXA" : "XAA"); pGeode->ShadowFB = FALSE; if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_SHADOW_FB, FALSE)) { pGeode->ShadowFB = TRUE; pGeode->NoAccel = TRUE; } pGeode->Rotate = 0; if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ROTATE))) { if (!xf86NameCmp(s, "CW")) pGeode->Rotate = 1; else if (!xf86NameCmp(s, "INVERT")) pGeode->Rotate = 2; else if (!xf86NameCmp(s, "CCW")) pGeode->Rotate = 3; if (pGeode->Rotate == 0) { DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "\"%s\" is not a valid value for Option \"Rotate\"\n", s)); DEBUGMSG(1, (pScrni->scrnIndex, X_INFO, "Valid options are \"CW\", \"INVERT\" or \"CCW\"\n")); } } if (pGeode->Rotate == 1) xf86DrvMsg(pScrni->scrnIndex, X_CONFIG, "Rotating screen clockwise\n"); else if (pGeode->Rotate == 2) xf86DrvMsg(pScrni->scrnIndex, X_CONFIG, "Rotating screen 180 degrees\n"); else if (pGeode->Rotate == 3) xf86DrvMsg(pScrni->scrnIndex, X_CONFIG, "Rotating screen 180 counter clockwise\n"); if (pGeode->Rotate != 0) { xf86DrvMsg(pScrni->scrnIndex, X_CONFIG, "Option 'Rotate' will disable acceleration and enable shadow\n"); pGeode->NoAccel = TRUE; pGeode->ShadowFB = TRUE; } /* XXX Init further private data here */ /* * * This shouldn't happen because such problems should be caught in * * GeodeProbe(), but check it just in case. */ if (pScrni->chipset == NULL) { Xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "ChipID 0x%04X is not recognised\n", pGeode->Chipset); return FALSE; } if (pGeode->Chipset < 0) { Xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Chipset %s is not recognised\n", pScrni->chipset); return FALSE; } if (pScrni->memPhysBase == 0) { from = X_PROBED; pScrni->memPhysBase = gfx_get_frame_buffer_base(); } pScrni->fbOffset = 0; if (pGeode->pEnt->device->videoRam == 0) { from = X_PROBED; pScrni->videoRam = pGeode->FBAvail / 1024; } else { pScrni->videoRam = pGeode->pEnt->device->videoRam; from = X_CONFIG; } /* * * xf86ValidateModes will check that the mode HTotal and VTotal values * * don't exceed the chipset's limit if pScrni->maxHValue adn * * pScrni->maxVValue are set. Since our GXValidMode() * * already takes care of this, we don't worry about setting them here. */ /* Select valid modes from those available */ /* * * min pitch 1024, max 2048 (Pixel count) * * min height 480, max 1024 (Pixel count) */ minPitch = 1024; maxPitch = 8192; /* Can support upto 1600x1200 32Bpp */ maxWidth = 1600; minHeight = 400; maxHeight = 1200; /* Can support upto 1600x1200 32Bpp */ if (pScrni->depth > 16) { PitchInc = 4096; } else if (pScrni->depth == 16) { PitchInc = 2048; } else { PitchInc = 1024; } PitchInc <<= 3; /* in bits */ pGeode->maxWidth = maxWidth; pGeode->maxHeight = maxHeight; /* by default use what user sets in the XF86Config file */ modes = pScrni->display->modes; if (ddc != NULL && pScrni->monitor != NULL && pScrni->monitor->DDC == NULL) { pScrni->monitor->DDC = ddc; GXDecodeDDC(pScrni, ddc); } i = xf86ValidateModes(pScrni, pScrni->monitor->Modes, modes, GeodeClockRange, NULL, minPitch, maxPitch, PitchInc, minHeight, maxHeight, pScrni->display->virtualX, pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); if (i == -1) { Xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); GXFreeRec(pScrni); return FALSE; } /* Prune the modes marked as invalid */ xf86PruneDriverModes(pScrni); if (i == 0 || pScrni->modes == NULL) { Xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); GXFreeRec(pScrni); return FALSE; } xf86SetCrtcForModes(pScrni, 0); /* Set the current mode to the first in the list */ pScrni->currentMode = pScrni->modes; DEBUGMSG(1, (0, X_INFO, "GXPreInit(12)!\n")); /* Print the list of modes being used */ xf86PrintModes(pScrni); /* Set the display resolution */ xf86SetDpi(pScrni, 0, 0); /* Load bpp-specific modules */ mod = NULL; #if CFB /* Load bpp-specific modules */ switch (pScrni->bitsPerPixel) { case 8: mod = "cfb"; reqSymbol = "cfbScreenInit"; break; case 16: mod = "cfb16"; reqSymbol = "cfb16ScreenInit"; break; case 24: mod = "cfb24"; reqSymbol = "cfb24ScreenInit"; break; case 32: mod = "cfb32"; reqSymbol = "cfb32ScreenInit"; break; default: return FALSE; } if (mod && xf86LoadSubModule(pScrni, mod) == NULL) { GXFreeRec(pScrni); return FALSE; } xf86LoaderReqSymbols(reqSymbol, NULL); #else if (xf86LoadSubModule(pScrni, "fb") == NULL) { GXFreeRec(pScrni); return FALSE; } xf86LoaderReqSymLists(amdFbSymbols, NULL); #endif if (pGeode->NoAccel == FALSE) { const char *module = "xaa"; const char **symbols = &amdXaaSymbols[0]; #if XF86EXA if (pGeode->useEXA) { module = "exa"; symbols = &amdExaSymbols[0]; } #endif if (!xf86LoadSubModule(pScrni, module)) { GXFreeRec(pScrni); return FALSE; } xf86LoaderReqSymLists(symbols, NULL); } if (pGeode->HWCursor == TRUE) { if (!xf86LoadSubModule(pScrni, "ramdac")) { GXFreeRec(pScrni); return FALSE; } xf86LoaderReqSymLists(amdRamdacSymbols, NULL); } /* Load shadowfb if needed */ if (pGeode->ShadowFB) { if (!xf86LoadSubModule(pScrni, "shadowfb")) { GXFreeRec(pScrni); return FALSE; } xf86LoaderReqSymLists(amdShadowSymbols, NULL); } if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { DEBUGMSG(1, (pScrni->scrnIndex, X_ERROR, "xf86RegisterResources() found resource conflicts\n")); GXFreeRec(pScrni); return FALSE; } GXUnmapMem(pScrni); return TRUE; } /*---------------------------------------------------------------------------- * GXRestore. * * Description :This function restores the mode that was saved on server entry * Parameters. * pScrni :Handle to ScreenPtr structure. * Pmode :poits to screen mode * * Returns :none. * * Comments :none. *---------------------------------------------------------------------------- */ static void GXRestore(ScrnInfoPtr pScrni) { GeodeRec *pGeode = GEODEPTR(pScrni); if (pGeode->useVGA && pGeode->FBVGAActive) { vgaHWPtr pvgaHW = VGAHWPTR(pScrni); vgaHWProtect(pScrni, TRUE); vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); vgaHWProtect(pScrni, FALSE); } } /*---------------------------------------------------------------------------- * GXCalculatePitchBytes. * * Description :This function restores the mode that was saved on server * * Parameters. * pScrni :Handle to ScreenPtr structure. * Pmode :Points to screenmode * * Returns :none. * * Comments :none. *---------------------------------------------------------------------------- */ static int GXCalculatePitchBytes(unsigned int width, unsigned int bpp) { int lineDelta = width * (bpp >> 3); if (width < 640) { /* low resolutions have both pixel and line doubling */ DEBUGMSG(1, (0, X_PROBED, "lower resolution %d %d\n", width, lineDelta)); lineDelta <<= 1; } /* needed in Rotate mode when in accel is turned off */ if (1) { /*!pGeode->NoAccel */ if (lineDelta > 4096) lineDelta = 8192; else if (lineDelta > 2048) lineDelta = 4096; else if (lineDelta > 1024) lineDelta = 2048; else lineDelta = 1024; } DEBUGMSG(1, (0, X_PROBED, "pitch %d %d\n", width, lineDelta)); return lineDelta; } /*---------------------------------------------------------------------------- * GXGetRefreshRate. * * Description :This function restores the mode that saved on server * * Parameters. * Pmode :Pointer to the screen modes * * Returns :It returns the selected refresh rate. * * Comments :none. *---------------------------------------------------------------------------- */ static int GXGetRefreshRate(DisplayModePtr pMode) { #define THRESHOLD 2 unsigned int i; static int validRates[] = { 56, 60, 70, 72, 75, 85, 90, 100 }; /* Hz */ unsigned long dotClock; int refreshRate; int selectedRate; dotClock = pMode->SynthClock * 1000; refreshRate = dotClock / pMode->CrtcHTotal / pMode->CrtcVTotal; if ((pMode->CrtcHTotal < 640) && (pMode->CrtcVTotal < 480)) refreshRate >>= 2; /* double pixel and double scan */ DEBUGMSG(1, (0, X_PROBED, "dotclock %lu %d\n", dotClock, refreshRate)); selectedRate = validRates[0]; for (i = 0; i < (sizeof(validRates) / sizeof(validRates[0])); i++) { if (validRates[i] < (refreshRate + THRESHOLD)) { selectedRate = validRates[i]; } } return selectedRate; } void gx_clear_screen(ScrnInfoPtr pScrni, int width, int height, int bpp) { /* no accels, mode is not yet set */ GeodeRec *pGeode = GEODEPTR(pScrni); unsigned long offset = gfx_get_display_offset(); unsigned long pitch = gfx_get_display_pitch(); unsigned long n = width * ((bpp + 7) >> 3); DEBUGMSG(1, (0, X_PROBED, "clear screen %lx %d %d %d %ld %ld\n", offset, width, height, bpp, pitch, n)); while (height > 0) { memset(pGeode->FBBase + offset, 0, n); offset += pitch; --height; } } void gx_clear_fb(ScrnInfoPtr pScrni) { GeodeRec *pGeode = GEODEPTR(pScrni); unsigned char *fb = pGeode->FBBase + pGeode->FBOffset; memset(fb, 0, pGeode->FBSize); if (pGeode->ShadowPtr != NULL && pGeode->ShadowPtr != fb) memset(pGeode->ShadowPtr, 0, pGeode->ShadowSize); } void gx_set_DvLineSize(unsigned int pitch) { unsigned long temp, dv_size = MDC_DV_LINE_SIZE_1024; if (pitch > 1024) { dv_size = MDC_DV_LINE_SIZE_2048; } if (pitch > 2048) { dv_size = MDC_DV_LINE_SIZE_4096; } if (pitch > 4096) { dv_size = MDC_DV_LINE_SIZE_8192; } /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */ temp = READ_REG32(MDC_DV_CTL); WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size); } /*---------------------------------------------------------------------------- * GXSetMode. * * Description :This function sets parametrs for screen mode * * Parameters. * pScrni :Pointer to the screenInfo structure. * Pmode :Pointer to the screen modes * * Returns :TRUE on success and FALSE on Failure. * * Comments :none. *---------------------------------------------------------------------------- */ static Bool GXSetMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) { int flags; static char *quals[4] = { " +hsync +vsync", " -hsync +vsync", " +hsync -vsync", " -hsync -vsync" }; GeodeRec *pGeode = GEODEPTR(pScrni); gfx_wait_until_idle(); /* disable video */ gx_disable_dac_power(pScrni); /* unsigned int compOffset, compPitch, compSize; */ DEBUGMSG(1, (0, X_INFO, "GXSetMode %p %p %p %p %p\n", gfx_virt_regptr, gfx_virt_gpptr, gfx_virt_spptr, gfx_virt_vidptr, gfx_virt_fbptr)); /* Set the VT semaphore */ pScrni->vtSema = TRUE; /* The timing will be adjusted later */ flags = 0; if ((pMode->Flags & V_NHSYNC) != 0) flags |= 1; if ((pMode->Flags & V_NVSYNC) != 0) flags |= 2; DEBUGMSG(1, (0, X_PROBED, "Setting mode %dx%d %0.3f %d %d %d %d %d %d %d %d%s\n", pMode->CrtcHDisplay, pMode->CrtcVDisplay, pMode->SynthClock / 1000.0, pMode->CrtcHDisplay, pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, pMode->CrtcHTotal, pMode->CrtcVDisplay, pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, pMode->CrtcVTotal, quals[flags])); DEBUGMSG(1, (0, X_INFO, "Set display mode: %dHz Pitch %d\n", GXGetRefreshRate(pMode), pGeode->Pitch)); /* TV not selected */ DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT or TFT\n")); if (pGeode->CustomMode != 0) { DEBUGMSG(1, (0, X_PROBED, "Setting Custom mode\n")); GFX(set_display_timings(pScrni->bitsPerPixel, flags, pMode->CrtcHDisplay, pMode->CrtcHBlankStart, pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, pMode->CrtcHBlankEnd, pMode->CrtcHTotal, pMode->CrtcVDisplay, pMode->CrtcVBlankStart, pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, pMode->CrtcVBlankEnd, pMode->CrtcVTotal, (int)((pMode->SynthClock / 1000.0) * 0x10000))); } else if (pGeode->Panel != 0) { DEBUGMSG(0, (0, X_PROBED, "Setting Display for TFT\n")); DEBUGMSG(1, (0, X_PROBED, "Restore Panel %d %d %d %d %d\n", pGeode->FPBX, pGeode->FPBY, pMode->CrtcHDisplay, pMode->CrtcVDisplay, pScrni->bitsPerPixel)); DEBUGMSG(1, (pScrni->scrnIndex, X_CONFIG, "FP Bios %d\n", pGeode->Panel)); GFX(set_fixed_timings(pGeode->FPBX, pGeode->FPBY, pMode->CrtcHDisplay, pMode->CrtcVDisplay, pScrni->bitsPerPixel)); } else { /* display is crt */ DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT %dx%d-%d@%d\n", pMode->CrtcHDisplay, pMode->CrtcVDisplay, pScrni->bitsPerPixel, GXGetRefreshRate(pMode))); GFX(set_display_mode(pMode->CrtcHDisplay, pMode->CrtcVDisplay, pScrni->bitsPerPixel, GXGetRefreshRate(pMode))); /* adjust the pitch */ } /* enable crt */ GFX(set_crt_enable(CRT_ENABLE)); GFX(set_display_pitch(pGeode->Pitch)); GFX(set_display_offset(0L)); GFX(wait_vertical_blank()); DEBUGMSG(1, (0, X_PROBED, "Display mode set\n")); /* enable compression if option selected */ if (pGeode->Compression) { DEBUGMSG(1, (0, X_PROBED, "Compression mode set %d\n", pGeode->Compression)); /* set the compression parameters,and it will be turned on later. */ gx_set_DvLineSize(pGeode->Pitch); gfx_set_compression_offset(pGeode->CBOffset); gfx_set_compression_pitch(pGeode->CBPitch); gfx_set_compression_size(pGeode->CBSize); /* set the compression buffer, all parameters already set */ gfx_set_compression_enable(1); } if (pGeode->HWCursor) { /* Load blank cursor */ GXLoadCursorImage(pScrni, NULL); GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0)); GFX(set_cursor_enable(1)); } else { DEBUGMSG(1,(0, X_INFO, "GXRestore ... ")); GXRestore(pScrni); DEBUGMSG(1,(0, X_INFO, "done.\n")); } DEBUGMSG(1, (0, X_INFO, "done.\n")); /* Reenable the hardware cursor after the mode switch */ if (pGeode->HWCursor == TRUE) { DEBUGMSG(1, (0, X_INFO, "GXShowCursor ... ")); GXShowCursor(pScrni); DEBUGMSG(1, (0, X_INFO, "done.\n")); } if (!pGeode->Panel) GFX(set_display_offset(pGeode->PrevDisplayOffset)); /* Restore the contents in the screen info */ DEBUGMSG(1, (0, X_INFO, "After setting the mode\n")); switch (pGeode->Rotate) { case 1: case 3: pGeode->HDisplay = pMode->VDisplay; pGeode->VDisplay = pMode->HDisplay; break; default: pGeode->HDisplay = pMode->HDisplay; pGeode->VDisplay = pMode->VDisplay; break; } gx_enable_dac_power(pScrni); return TRUE; } /*---------------------------------------------------------------------------- * GXEnterGraphics. * * Description :This function will intiallize the displaytiming structure for nextmode and switch to VGA mode. * * Parameters. * pScrn :Screen information will be stored in this structure. * pScrni :Pointer to the screenInfo structure. * * Returns :TRUE on success and FALSE on Failure. * * Comments :gfx_vga_mode_switch() will start and end the * switching based on the arguments 0 or 1.soft_vga * is disabled in this function. *---------------------------------------------------------------------------- */ static Bool GXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) { GeodeRec *pGeode = GEODEPTR(pScrni); gfx_wait_until_idle(); DEBUGMSG(1, (0, X_INFO, "GXEnterGraphics(1)!\n")); /* Save CRT State */ pGeode->FBgfxdisplaytiming.dwDotClock = gfx_get_clock_frequency(); pGeode->FBgfxdisplaytiming.wPitch = gfx_get_display_pitch(); pGeode->FBgfxdisplaytiming.wBpp = gfx_get_display_bpp(); pGeode->FBgfxdisplaytiming.wHTotal = gfx_get_htotal(); pGeode->FBgfxdisplaytiming.wHActive = gfx_get_hactive(); pGeode->FBgfxdisplaytiming.wHSyncStart = gfx_get_hsync_start(); pGeode->FBgfxdisplaytiming.wHSyncEnd = gfx_get_hsync_end(); pGeode->FBgfxdisplaytiming.wHBlankStart = gfx_get_hblank_start(); pGeode->FBgfxdisplaytiming.wHBlankEnd = gfx_get_hblank_end(); pGeode->FBgfxdisplaytiming.wVTotal = gfx_get_vtotal(); pGeode->FBgfxdisplaytiming.wVActive = gfx_get_vactive(); pGeode->FBgfxdisplaytiming.wVSyncStart = gfx_get_vsync_start(); pGeode->FBgfxdisplaytiming.wVSyncEnd = gfx_get_vsync_end(); pGeode->FBgfxdisplaytiming.wVBlankStart = gfx_get_vblank_start(); pGeode->FBgfxdisplaytiming.wVBlankEnd = gfx_get_vblank_end(); pGeode->FBgfxdisplaytiming.wPolarity = gfx_get_sync_polarities(); /* Save Display offset */ pGeode->FBDisplayOffset = gfx_get_display_offset(); DEBUGMSG(1, (0, X_INFO, "GXEnterGraphics(2)!\n")); if (pGeode->useVGA) { vgaHWPtr pvgaHW = VGAHWPTR(pScrni); pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); } /* Save the current Compression state */ pGeode->FBCompressionEnable = gfx_get_compression_enable(); pGeode->FBCompressionOffset = gfx_get_compression_offset(); pGeode->FBCompressionPitch = gfx_get_compression_pitch(); pGeode->FBCompressionSize = gfx_get_compression_size(); /* Save Cursor offset */ pGeode->FBCursorOffset = gfx_get_cursor_offset(); #if defined(PNL_SUP) /* Save the Panel state */ DEBUGMSG(1, (0, X_INFO, "GXEnterGraphics(3)!\n")); Pnl_SavePanelState(); #endif /* only if comming from VGA */ if (pGeode->useVGA && pGeode->FBVGAActive) { unsigned short sequencer; vgaHWPtr pvgaHW = VGAHWPTR(pScrni); /* Map VGA aperture */ if (!vgaHWMapMem(pScrni)) return FALSE; /* Unlock VGA registers */ vgaHWUnlock(pvgaHW); /* Save the current state and setup the current mode */ vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); /* DISABLE VGA SEQUENCER */ /* This allows the VGA state machine to terminate. We must delay */ /* such that there are no pending MBUS requests. */ gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); sequencer = gfx_inb(MDC_SEQUENCER_DATA); sequencer |= MDC_CLK_MODE_SCREEN_OFF; gfx_outb(MDC_SEQUENCER_DATA, sequencer); gfx_delay_milliseconds(1); /* BLANK THE VGA DISPLAY */ gfx_outw(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_RESET); sequencer = gfx_inb(MDC_SEQUENCER_DATA); sequencer &= ~MDC_RESET_VGA_DISP_ENABLE; gfx_outb(MDC_SEQUENCER_DATA, sequencer); gfx_delay_milliseconds(1); } gx_clear_fb(pScrni); if (!GXSetMode(pScrni, pScrni->currentMode)) { return FALSE; } gx_enable_dac_power(pScrni); DEBUGMSG(1, (0, X_INFO, "GXEnterGraphics(4)!\n")); return TRUE; } void gx_enable_dac_power(ScrnInfoPtr pScrni) { /* enable the DAC POWER */ gfx_write_vid32(RCDF_VID_MISC, gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH); } void gx_disable_dac_power(ScrnInfoPtr pScrni) { /* disable the DAC POWER */ gfx_write_vid32(RCDF_VID_MISC, RCDF_DAC_POWER_DOWN | RCDF_ANALOG_POWER_DOWN | (gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH)); } /*---------------------------------------------------------------------------- * GXLeaveGraphics: * * Description :This function will restore the displaymode parameters * and switches the VGA mode * * Parameters. * pScrn :Screen information will be stored in this structure. * pScrni :Pointer to the screenInfo structure. * * Returns :none. * * Comments : gfx_vga_mode_switch() will start and end the switching * based on the arguments 0 or 1.soft_vga is disabled in * this function. *---------------------------------------------------------------------------- */ static void GXLeaveGraphics(ScrnInfoPtr pScrni) { GeodeRec *pGeode = GEODEPTR(pScrni); gfx_wait_until_idle(); /* Restore VG registers */ gfx_set_display_timings(pGeode->FBgfxdisplaytiming.wBpp, pGeode->FBgfxdisplaytiming.wPolarity, pGeode->FBgfxdisplaytiming.wHActive, pGeode->FBgfxdisplaytiming.wHBlankStart, pGeode->FBgfxdisplaytiming.wHSyncStart, pGeode->FBgfxdisplaytiming.wHSyncEnd, pGeode->FBgfxdisplaytiming.wHBlankEnd, pGeode->FBgfxdisplaytiming.wHTotal, pGeode->FBgfxdisplaytiming.wVActive, pGeode->FBgfxdisplaytiming.wVBlankStart, pGeode->FBgfxdisplaytiming.wVSyncStart, pGeode->FBgfxdisplaytiming.wVSyncEnd, pGeode->FBgfxdisplaytiming.wVBlankEnd, pGeode->FBgfxdisplaytiming.wVTotal, pGeode->FBgfxdisplaytiming.dwDotClock); gfx_set_compression_enable(0); /* Restore the previous Compression state */ if (pGeode->FBCompressionEnable) { gfx_set_compression_offset(pGeode->FBCompressionOffset); gfx_set_compression_pitch(pGeode->FBCompressionPitch); gfx_set_compression_size(pGeode->FBCompressionSize); gfx_set_compression_enable(1); } gfx_set_display_pitch(pGeode->FBgfxdisplaytiming.wPitch); gfx_set_display_offset(pGeode->FBDisplayOffset); /* Restore Cursor */ gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); if (pGeode->useVGA) { pGeode->vesa->pInt->num = 0x10; pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; pGeode->vesa->pInt->bx = 0; xf86ExecX86int10(pGeode->vesa->pInt); gfx_delay_milliseconds(3); } GXRestore(pScrni); gx_enable_dac_power(pScrni); } /*---------------------------------------------------------------------------- * GXCloseScreen. * * Description :This function will restore the original mode * and also it unmap video memory * * Parameters. * ScrnIndex :Screen index value of the screen will be closed. * pScrn :Pointer to the screen structure. * * * Returns :TRUE on success and FALSE on Failure. * * Comments :none. *---------------------------------------------------------------------------- */ static Bool GXCloseScreen(int scrnIndex, ScreenPtr pScrn) { ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); if (pGeode->ShadowPtr) xfree(pGeode->ShadowPtr); DEBUGMSG(0, (scrnIndex, X_PROBED, "GXCloseScreen %d\n", pScrni->vtSema)); if (pScrni->vtSema) GXLeaveGraphics(pScrni); if (pGeode->AccelInfoRec) XAADestroyInfoRec(pGeode->AccelInfoRec); if (pGeode->AccelImageWriteBuffers) { #if GX_USE_OFFSCRN_MEM xfree(pGeode->AccelImageWriteBuffers[0]); #endif xfree(pGeode->AccelImageWriteBuffers); pGeode->AccelImageWriteBuffers = NULL; } if (pGeode->AccelColorExpandBuffers) { xfree(pGeode->AccelColorExpandBuffers); pGeode->AccelColorExpandBuffers = NULL; } if (pGeode->pExa) { exaDriverFini(pScrn); xfree(pGeode->pExa); pGeode->pExa = NULL; } pScrni->vtSema = FALSE; GXUnmapMem(pScrni); if (pGeode && (pScrn->CloseScreen = pGeode->CloseScreen)) { pGeode->CloseScreen = NULL; return ((*pScrn->CloseScreen) (scrnIndex, pScrn)); } return TRUE; } #ifdef DPMSExtension static void GXPanelPower(int enable) { unsigned long power = READ_VID32(RCDF_POWER_MANAGEMENT); if (enable != 0) power |= RCDF_PM_PANEL_POWER_ON; else power &= ~RCDF_PM_PANEL_POWER_ON; WRITE_VID32(RCDF_POWER_MANAGEMENT, power); } /*---------------------------------------------------------------------------- * GXDPMSSet. * * Description :This function sets geode into Power Management * Signalling mode. * * Parameters. * pScrni :Pointer to screen info strucrure. * mode :Specifies the power management mode. * * Returns :none. * * Comments :none. *---------------------------------------------------------------------------- */ static void GXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) { GeodeRec *pGeode; pGeode = GEODEPTR(pScrni); DEBUGMSG(1, (0, X_INFO, "GXDPMSSet! %d %d\n", mode, flags)); /* Check if we are actively controlling the display */ if (!pScrni->vtSema) { ErrorF("GXDPMSSet called when we not controlling the VT!\n"); return; } switch (mode) { case DPMSModeOn: /* Screen: On; HSync: On; VSync: On */ GFX(set_crt_enable(CRT_ENABLE)); #if defined(PNL_SUP) if (pGeode->Panel) { Pnl_PowerUp(); GXPanelPower(1); } #endif break; case DPMSModeStandby: /* Screen: Off; HSync: Off; VSync: On */ GFX(set_crt_enable(CRT_STANDBY)); #if defined(PNL_SUP) if (pGeode->Panel) { Pnl_PowerDown(); GXPanelPower(0); } #endif break; case DPMSModeSuspend: /* Screen: Off; HSync: On; VSync: Off */ GFX(set_crt_enable(CRT_SUSPEND)); #if defined(PNL_SUP) if (pGeode->Panel) { Pnl_PowerDown(); GXPanelPower(0); } #endif break; case DPMSModeOff: /* Screen: Off; HSync: Off; VSync: Off */ GFX(set_crt_enable(CRT_DISABLE)); #if defined(PNL_SUP) if (pGeode->Panel) { Pnl_PowerDown(); GXPanelPower(0); } #endif break; } } #endif /*---------------------------------------------------------------------------- * GXScreenInit. * * Description :This function will be called at the each ofserver * generation. * * Parameters. * scrnIndex :Specfies the screenindex value during generation. * pScrn :Pointer to screen info strucrure. * argc :parameters for command line arguments count * argv :command line arguments if any it is not used. * * Returns :none. * * Comments :none. *---------------------------------------------------------------------------- */ static Bool GXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) { int i, l, bytpp, size, fbsize, fboffset, fbavail; int pitch, displayWidth, virtualX, virtualY; int HDisplay, VDisplay, maxHDisplay, maxVDisplay, maxX, maxY; unsigned char *FBStart; unsigned char **ap, *bp; DisplayModePtr p; GeodeRec *pGeode; VisualPtr visual; BoxRec AvailBox; RegionRec OffscreenRegion; ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; Bool Inited = FALSE; pGeode = GXGetRec(pScrni); if (pGeode->useVGA) { if (!vgaHWGetHWRec(pScrni)) return FALSE; if (!vgaHWMapMem(pScrni)) return FALSE; vgaHWGetIOBase(VGAHWPTR(pScrni)); } if (!GXMapMem(pScrni)) return FALSE; pGeode->Pitch = GXCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); pGeode->AccelPitch = pGeode->Pitch; bytpp = (pScrni->bitsPerPixel + 7) / 8; /* start of framebuffer for accels */ fboffset = 0; /* 0x4000 for gfx_gu2_scratch_buffer */ fbavail = pGeode->FBAvail - 0x4000; #ifdef V4L2_VIDEO_BFR_SZ fbavail -= V4L2_VIDEO_BFR_SZ; #endif /* allocate display frame buffer at zero offset */ fbsize = pScrni->virtualY * pGeode->Pitch; pGeode->FBSize = fbsize; pGeode->CursorSize = 16 * 64; /* 64x64 */ pGeode->CursorStartOffset = 0; DEBUGMSG(1, (scrnIndex, X_PROBED, "%d %d %d\n", pScrni->virtualX, pScrni->bitsPerPixel, pGeode->Pitch)); HDisplay = pScrni->currentMode->HDisplay; VDisplay = pScrni->currentMode->VDisplay; pGeode->orig_virtX = pScrni->virtualX; pGeode->orig_virtY = pScrni->virtualY; p = pScrni->modes; maxHDisplay = p->HDisplay; maxVDisplay = p->VDisplay; while ((p = p->next) != pScrni->modes) { if (maxHDisplay < p->HDisplay) maxHDisplay = p->HDisplay; if (maxVDisplay < p->VDisplay) maxVDisplay = p->VDisplay; } DEBUGMSG(1, (scrnIndex, X_PROBED, "maxHDisplay %d maxVDisplay %d\n", maxHDisplay, maxVDisplay)); switch (pGeode->Rotate) { case 1: case 3: pGeode->HDisplay = VDisplay; pGeode->VDisplay = HDisplay; virtualX = pScrni->virtualY; virtualY = pScrni->virtualX; maxX = maxVDisplay; maxY = maxHDisplay; break; default: pGeode->HDisplay = HDisplay; pGeode->VDisplay = VDisplay; virtualX = pScrni->virtualX; virtualY = pScrni->virtualY; maxX = maxHDisplay; maxY = maxVDisplay; break; } /* shadow may be first in FB, since accels render there */ pGeode->ShadowPtr = NULL; if (pGeode->ShadowFB) { if (!pGeode->PointerMoved) { pGeode->PointerMoved = pScrni->PointerMoved; pScrni->PointerMoved = GXPointerMoved; } if (pGeode->ShadowPtr == NULL) { pGeode->ShadowPitch = BitmapBytePad(pScrni->bitsPerPixel * virtualX); size = pGeode->ShadowPitch * virtualY; pGeode->ShadowPtr = xalloc(size); if (pGeode->ShadowPtr != NULL) { pGeode->ShadowSize = size; if (!pGeode->NoAccel) { pGeode->NoAccel = TRUE; pGeode->HWCursor = FALSE; xf86DrvMsg(scrnIndex, X_ERROR, "Shadow FB offscreen, All Accels disabled\n"); } } else { xf86DrvMsg(scrnIndex, X_ERROR, "Shadow FB, No offscreen Memory, disabled\n"); pGeode->ShadowFB = FALSE; pGeode->Rotate = 0; pGeode->HDisplay = HDisplay; pGeode->VDisplay = VDisplay; virtualX = pScrni->virtualX; virtualY = pScrni->virtualY; } } } if (pGeode->ShadowPtr != NULL) { displayWidth = pGeode->ShadowPitch / bytpp; FBStart = pGeode->ShadowPtr; DEBUGMSG(1, (0, X_PROBED, "Shadow %p \n", FBStart)); } else { displayWidth = pGeode->Pitch / bytpp; FBStart = pGeode->FBBase; DEBUGMSG(1, (0, X_PROBED, "FBStart %p \n", FBStart)); } DEBUGMSG(1, (0, X_PROBED, "FB display %X size %X \n", fboffset, fbsize)); pGeode->FBOffset = fboffset; /* offset of display framebuffer */ pScrni->fbOffset = fboffset; fboffset += fbsize; fbavail -= fbsize; if (pGeode->Compression) { /* Compression enabled */ pGeode->CBPitch = 512 + 32; pGeode->CBSize = 512 + 32; size = maxY * pGeode->CBPitch; DEBUGMSG(1, (0, X_PROBED, "CB %#x size %#x (%d*%d)\n", fboffset, size, maxY, pGeode->CBPitch)); if (size <= fbavail) { pGeode->CBOffset = fboffset; fboffset += size; fbavail -= size; } else { xf86DrvMsg(scrnIndex, X_ERROR, "Compression, No FB Memory, disabled\n"); pGeode->Compression = FALSE; } } if (pGeode->HWCursor) { /* HWCursor enabled */ size = pGeode->CursorSize; if (size <= fbavail) { pGeode->CursorStartOffset = fboffset; fboffset += size; fbavail -= size; } else { xf86DrvMsg(scrnIndex, X_ERROR, "HWCursor, No FB Memory, disabled\n"); pGeode->HWCursor = FALSE; } } #if XF86EXA if (!pGeode->NoAccel && pGeode->useEXA) { /* exa acceleration enabled */ if (!(pGeode->pExa = xnfcalloc(sizeof(ExaDriverRec), 1))) { xf86DrvMsg(scrnIndex, X_ERROR, "No ExaDriverRec Memory, disabled\n"); pGeode->NoAccel = TRUE; } else { if ((size = pGeode->exaBfrSz) > 0 && size <= fbavail) { pGeode->exaBfrOffset = fboffset; fboffset += size; fbavail -= size; } } } #endif if (!pGeode->NoAccel && !pGeode->useEXA) { /* xaa acceleration enabled */ if (pGeode->NoOfImgBuffers > 0) { pGeode->AccelImageWriteBuffers = NULL; pitch = pGeode->AccelPitch; size = pitch * pGeode->NoOfImgBuffers; #if !GX_USE_OFFSCRN_MEM if (size <= fbavail) { bp = (unsigned char *)pGeode->FBBase + fboffset; l = sizeof(pGeode->AccelImageWriteBuffers[0]) * pGeode->NoOfImgBuffers; ap = (unsigned char **)xalloc(l); if (ap != NULL) { for (i = 0; i < pGeode->NoOfImgBuffers; ++i) { ap[i] = bp; DEBUGMSG(1, (scrnIndex, X_PROBED, "img line %d %p\n", i, ap[i])); bp += pitch; } pGeode->AccelImageWriteBuffers = ap; fboffset += size; fbavail -= size; } else { xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No Memory\n"); } } else { xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No FB Memory\n"); } #else if ((bp = (unsigned char *)xalloc(size)) != NULL) { ap = xalloc(sizeof(pGeode->AccelImageWriteBuffers[0]) * pGeode->NoOfImgBuffers); if (ap != NULL) { for (i = 0; i < pGeode->NoOfImgBuffers; ++i) { ap[i] = bp; DEBUGMSG(1, (scrnIndex, X_PROBED, "img line %d %x\n", i, ap[i])); bp += pitch; } pGeode->AccelImageWriteBuffers = ap; } else { xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No Memory\n"); } } else { xf86DrvMsg(scrnIndex, X_ERROR, "Image Write, No offscreen Memory\n"); } #endif if (pGeode->AccelImageWriteBuffers == NULL) { xf86DrvMsg(scrnIndex, X_ERROR, "Accel Image Write disabled\n"); pGeode->NoOfImgBuffers = 0; } } if (pGeode->NoOfColorExpandLines > 0) { pGeode->AccelColorExpandBuffers = NULL; pitch = ((pGeode->AccelPitch + 31) >> 5) << 2; size = pitch * pGeode->NoOfColorExpandLines; if (size <= fbavail) { bp = (unsigned char *)pGeode->FBBase + fboffset; l = sizeof(pGeode->AccelColorExpandBuffers[0]) * pGeode->NoOfColorExpandLines; ap = (unsigned char **)xalloc(l); if (ap != NULL) { for (i = 0; i < pGeode->NoOfColorExpandLines; ++i) { ap[i] = bp; DEBUGMSG(1, (scrnIndex, X_PROBED, "clr line %d %p\n", i, ap[i])); bp += pitch; } pGeode->AccelColorExpandBuffers = ap; fboffset += size; fbavail -= size; } else { xf86DrvMsg(scrnIndex, X_ERROR, "Color Expansion, No Memory\n"); } } else { xf86DrvMsg(scrnIndex, X_ERROR, "Color Expansion, No offscreen Memory\n"); } if (pGeode->AccelColorExpandBuffers == NULL) { xf86DrvMsg(scrnIndex, X_ERROR, "Accel Color Expansion disabled\n"); pGeode->NoOfColorExpandLines = 0; } } } else { pGeode->NoOfImgBuffers = 0; pGeode->AccelImageWriteBuffers = NULL; pGeode->NoOfColorExpandLines = 0; pGeode->AccelColorExpandBuffers = NULL; } /* Initialise graphics mode */ if (!GXEnterGraphics(pScrn, pScrni)) return FALSE; pScrni->virtualX = virtualX; pScrni->virtualY = virtualY; DEBUGMSG(1, (0, X_INFO, "GXScreenInit(1)!\n")); /* Reset visual list */ miClearVisualTypes(); DEBUGMSG(1, (0, X_INFO, "GXScreenInit(2)!\n")); /* Setup the visual we support */ if (pScrni->bitsPerPixel > 8) { DEBUGMSG(1, (scrnIndex, X_PROBED, "miSetVisualTypes %d %X %X %X\n", pScrni->depth, TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)); if (!miSetVisualTypes(pScrni->depth, TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { return FALSE; } } else { if (!miSetVisualTypes(pScrni->depth, miGetDefaultVisualMask(pScrni->depth), pScrni->rgbBits, pScrni->defaultVisual)) { return FALSE; } } DEBUGMSG(1, (0, X_INFO, "GXScreenInit(3)!\n")); /* Set for RENDER extensions */ miSetPixmapDepths(); /* Call the framebuffer layer's ScreenInit function, and fill in other * * pScrn fields. */ switch (pScrni->bitsPerPixel) { #if CFB case 8: Inited = cfbScreenInit(pScrn, FBStart, virtualX, virtualY, pScrni->xDpi, pScrni->yDpi, displayWidth); break; case 16: Inited = cfb16ScreenInit(pScrn, FBStart, virtualX, virtualY, pScrni->xDpi, pScrni->yDpi, displayWidth); break; case 24: case 32: Inited = cfb32ScreenInit(pScrn, FBStart, virtualX, virtualY, pScrni->xDpi, pScrni->yDpi, displayWidth); break; #else case 8: case 16: case 24: case 32: Inited = fbScreenInit(pScrn, FBStart, virtualX, virtualY, pScrni->xDpi, pScrni->yDpi, displayWidth, pScrni->bitsPerPixel); break; #endif default: xf86DrvMsg(scrnIndex, X_ERROR, "Internal error: invalid bpp (%d) in ScreenInit\n", pScrni->bitsPerPixel); Inited = FALSE; break; } if (!Inited) return FALSE; GXRotationInit(pScrni); GXAdjustFrame(scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); if (!pGeode->NoAccel) { if (!pGeode->useEXA) { AvailBox.x1 = 0; /* SET UP GRAPHICS MEMORY AVAILABLE FOR PIXMAP CACHE */ AvailBox.y1 = (fboffset + pGeode->AccelPitch - 1) / pGeode->AccelPitch; AvailBox.x2 = displayWidth; AvailBox.y2 = (fboffset + fbavail) / pGeode->AccelPitch; DEBUGMSG(1, (scrnIndex, X_PROBED, "Memory manager initialized to (%d,%d) (%d,%d)\n", AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2)); if (AvailBox.y1 < AvailBox.y2) { xf86DrvMsg(scrnIndex, X_INFO, "Initializing Memory manager to (%d,%d) (%d,%d)\n", AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2); if (!xf86InitFBManagerRegion(pScrn, &OffscreenRegion)) { xf86DrvMsg(scrnIndex, X_ERROR, "Memory manager initialization failed, Cache Diabled\n"); } REGION_UNINIT(pScrn, &OffscreenRegion); } else { xf86DrvMsg(scrnIndex, X_INFO, "No Off Screen Memory, Cache Disabled (%d,%d) (%d,%d)\n", AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2); } } #if XF86EXA else if (pGeode->pExa) { ExaDriverPtr pExa = pGeode->pExa; pExa->memoryBase = pGeode->FBBase; pExa->offScreenBase = fboffset; pExa->memorySize = fboffset + fbavail; pExa->pixmapOffsetAlign = 32; pExa->pixmapPitchAlign = 32; pExa->flags = EXA_OFFSCREEN_PIXMAPS; pExa->maxX = pGeode->maxWidth - 1; pExa->maxY = pGeode->maxHeight - 1; } #endif } DEBUGMSG(1, (0, X_INFO, "GXScreenInit(4)!\n")); xf86SetBlackWhitePixels(pScrn); if (!pGeode->ShadowFB) { GXDGAInit(pScrn); } DEBUGMSG(1, (0, X_INFO, "GXScreenInit(5)!\n")); if (pScrni->bitsPerPixel > 8) { /* Fixup RGB ordering */ visual = pScrn->visuals + pScrn->numVisuals; while (--visual >= pScrn->visuals) { if ((visual->class | DynamicClass) == DirectColor) { visual->offsetRed = pScrni->offset.red; visual->offsetGreen = pScrni->offset.green; visual->offsetBlue = pScrni->offset.blue; visual->redMask = pScrni->mask.red; visual->greenMask = pScrni->mask.green; visual->blueMask = pScrni->mask.blue; } } } #if CFB #else /* must be after RGB ordering fixed */ fbPictureInit(pScrn, 0, 0); #endif DEBUGMSG(1, (0, X_INFO, "GXScreenInit(6)!\n")); if (!pGeode->NoAccel) { GXAccelInit(pScrn); } DEBUGMSG(1, (0, X_INFO, "GXScreenInit(7)!\n")); miInitializeBackingStore(pScrn); xf86SetBackingStore(pScrn); DEBUGMSG(1, (0, X_INFO, "GXScreenInit(8)!\n")); /* Initialise software cursor */ miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); /* Initialize HW cursor layer. * * Must follow software cursor initialization */ if (pGeode->HWCursor) { if (!GXHWCursorInit(pScrn)) xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Hardware cursor initialization failed\n"); } DEBUGMSG(1, (0, X_INFO, "GXScreenInit(9)!\n")); /* Setup default colourmap */ if (!miCreateDefColormap(pScrn)) { return FALSE; } DEBUGMSG(1, (0, X_INFO, "GXScreenInit(10)!\n")); if (pScrni->bitsPerPixel == 8) { /* Initialize colormap layer. * * Must follow initialization of the default colormap */ if (!xf86HandleColormaps(pScrn, 256, 8, GXLoadPalette, NULL, CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { return FALSE; } } DEBUGMSG(1, (0, X_INFO, "GXScreenInit(11)!\n")); if (pGeode->ShadowFB) { DEBUGMSG(1, (0, X_INFO, "Shadowed, Rotate=%d, NoAccel=%d\n", pGeode->Rotate, pGeode->NoAccel)); GXShadowFBInit(pScrn, pGeode, bytpp); } #ifdef DPMSExtension xf86DPMSInit(pScrn, GXDPMSSet, 0); #endif DEBUGMSG(1, (0, X_INFO, "GXScreenInit(12)!\n")); DEBUGMSG(1, (0, X_INFO, "GXScreenInit(13)!\n")); GXInitVideo(pScrn); /* needed for video */ /* Wrap the screen's CloseScreen vector and set its * SaveScreen vector */ pGeode->CloseScreen = pScrn->CloseScreen; pScrn->CloseScreen = GXCloseScreen; pScrn->SaveScreen = GXSaveScreen; DEBUGMSG(1, (0, X_INFO, "GXScreenInit(14)!\n")); /* Report any unused options */ if (serverGeneration == 1) { xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); } DEBUGMSG(1, (0, X_INFO, "GXScreenInit(15)!\n")); return TRUE; } /*---------------------------------------------------------------------------- * GXSwitchMode. * * Description :This function will switches the screen mode * * Parameters: * scrnIndex :Specfies the screen index value. * pMode :pointer to the mode structure. * flags :may be used for status check?. * * Returns :Returns TRUE on success and FALSE on failure. * * Comments :none. *---------------------------------------------------------------------------- */ Bool GXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags) { DEBUGMSG(1, (0, X_INFO, "GXSwitchMode!\n")); return GXSetMode(xf86Screens[scrnIndex], pMode); } /*---------------------------------------------------------------------------- * GXAdjustFrame. * * Description :This function is used to intiallize the start * address of the memory. * Parameters. * scrnIndex :Specfies the screen index value. * x :x co-ordinate value interms of pixels. * y :y co-ordinate value interms of pixels. * * Returns :none. * * Comments :none. *---------------------------------------------------------------------------- */ void GXAdjustFrame(int scrnIndex, int x, int y, int flags) { ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); int newX, newY; unsigned long offset; if (x + pGeode->HDisplay >= pScrni->virtualX) x = pScrni->virtualX - pGeode->HDisplay; if (x < 0) x = 0; if (y + pGeode->VDisplay >= pScrni->virtualY) y = pScrni->virtualY - pGeode->VDisplay; if (y < 0) y = 0; pScrni->frameX0 = x; pScrni->frameY0 = y; pScrni->frameX1 = x + pGeode->HDisplay - 1; pScrni->frameY1 = y + pGeode->VDisplay - 1; (*pGeode->Rotation) (x, y, pScrni->virtualX, pScrni->virtualY, &newX, &newY); (*pGeode->RBltXlat) (newX, newY, pGeode->HDisplay, pGeode->VDisplay, &newX, &newY); offset = pGeode->FBOffset + newY * pGeode->Pitch + newX * (pScrni->bitsPerPixel >> 3); gfx_set_display_offset(offset); } /*---------------------------------------------------------------------------- * GXEnterVT. * * Description :This is called when VT switching back to the X server * * Parameters. * scrnIndex :Specfies the screen index value. * flags :Not used inside the function. * * Returns :none. * * Comments :none. *---------------------------------------------------------------------------- */ static Bool GXEnterVT(int scrnIndex, int flags) { DEBUGMSG(1, (0, X_INFO, "GXEnterVT!\n")); return GXEnterGraphics(NULL, xf86Screens[scrnIndex]); } /*---------------------------------------------------------------------------- * GXLeaveVT. * * Description :This is called when VT switching X server text mode. * * Parameters. * scrnIndex :Specfies the screen index value. * flags :Not used inside the function. * * Returns :none. * * Comments :none. *---------------------------------------------------------------------------- */ static void GXLeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; GeodeRec *pGeode = GEODEPTR(pScrni); pGeode->PrevDisplayOffset = gfx_get_display_offset(); DEBUGMSG(1, (0, X_INFO, "GXLeaveVT!\n")); GXLeaveGraphics(xf86Screens[scrnIndex]); } /*---------------------------------------------------------------------------- * GXFreeScreen. * * Description :This is called to free any persistent data structures. * * Parameters. * scrnIndex :Specfies the screen index value. * flags :Not used inside the function. * * Returns :none. * * Comments :This will be called only when screen being deleted.. *---------------------------------------------------------------------------- */ static void GXFreeScreen(int scrnIndex, int flags) { DEBUGMSG(1, (0, X_INFO, "GXFreeScreen!\n")); if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) vgaHWFreeHWRec(xf86Screens[scrnIndex]); GXFreeRec(xf86Screens[scrnIndex]); } /*---------------------------------------------------------------------------- * GXValidMode. * * Description :This function checks if a mode is suitable for selected * chipset. * Parameters. * scrnIndex :Specfies the screen index value. * pMode :Pointer to the screen mode structure.. * verbose :not used for implementation. * flags :not used for implementation * * Returns :MODE_OK if the specified mode is supported or * MODE_NO_INTERLACE. * Comments :none. *---------------------------------------------------------------------------- */ static int GXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) { unsigned int total_memory_required; ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; int ret = -1; GeodeRec *pGeode = GEODEPTR(pScrni); DEBUGMSG(1, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n", pMode->CrtcHDisplay, pMode->CrtcVDisplay, pScrni->bitsPerPixel, GXGetRefreshRate(pMode))); if (pGeode->CustomMode == 0) { #if defined(PNL_SUP) if (pGeode->Panel != 0) { if (pMode->CrtcHDisplay > pGeode->FPBX || pMode->CrtcVDisplay > pGeode->FPBY || gfx_is_panel_mode_supported(pGeode->FPBX, pGeode->FPBY, pMode->CrtcHDisplay, pMode->CrtcVDisplay, pScrni->bitsPerPixel) < 0) return MODE_NOMODE; } #endif /* PNL_SUP */ DEBUGMSG(1, (0, X_NONE, "CRT mode\n")); if (pMode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; ret = gfx_is_display_mode_supported(pMode->CrtcHDisplay, pMode->CrtcVDisplay, pScrni->bitsPerPixel, GXGetRefreshRate(pMode)); if (ret < 0) return MODE_NOMODE; } total_memory_required = GXCalculatePitchBytes(pMode->CrtcHDisplay, pScrni->bitsPerPixel) * pMode->CrtcVDisplay; DEBUGMSG(1, (0, X_NONE, "Total Mem %X %lX\n", total_memory_required, pGeode->FBAvail)); if (total_memory_required > pGeode->FBAvail) return MODE_MEM; return MODE_OK; } /*---------------------------------------------------------------------------- * GXLoadPalette. * * Description: This function sets the palette entry used for graphics * data * * Parameters. * pScrni: Points the screeninfo structure. * numColors: Specifies the no of colors it supported. * indizes: This is used get index value . * LOCO: to be added. * pVisual: to be added. * * Returns: MODE_OK if the specified mode is supported or * MODE_NO_INTERLACE. * * Comments: none. *---------------------------------------------------------------------------- */ static void GXLoadPalette(ScrnInfoPtr pScrni, int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) { int i, index, color; for (i = 0; i < numColors; i++) { index = indizes[i] & 0xFF; color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | (((unsigned long)(colors[index].green & 0xFF)) << 8) | ((unsigned long)(colors[index].blue & 0xFF)); DEBUGMSG(0, (0, X_NONE, "GXLoadPalette: %d %d %X\n", numColors, index, color)); GFX(set_display_palette_entry(index, color)); } } static Bool GXMapMem(ScrnInfoPtr pScrni) { GeodeRec *pGeode = GEODEPTR(pScrni); gfx_virt_regptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, VIDMEM_MMIO, (unsigned int) gfx_get_cpu_register_base(), pGeode->cpu_reg_size); if (pGeode->DetectedChipSet & GX) { gfx_virt_gpptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, VIDMEM_MMIO, (unsigned int) gfx_get_graphics_register_base(), pGeode->gp_reg_size); } else { gfx_virt_spptr = gfx_virt_regptr; } gfx_virt_vidptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, VIDMEM_MMIO, (unsigned int) gfx_get_vid_register_base(), pGeode->vid_reg_size); gfx_virt_fbptr = (unsigned char *)xf86MapVidMem(pScrni->scrnIndex, VIDMEM_FRAMEBUFFER, pGeode->FBLinearAddr, pGeode->FBAvail); pGeode->FBBase = gfx_virt_fbptr; DEBUGMSG(1, (0, X_NONE, "Set mode %p %p %p %p %p\n", gfx_virt_regptr, gfx_virt_gpptr, gfx_virt_spptr, gfx_virt_vidptr, gfx_virt_fbptr)); /* CHECK IF REGISTERS WERE MAPPED SUCCESSFULLY */ if ((!gfx_virt_regptr) || (!gfx_virt_gpptr) || (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) { DEBUGMSG(1, (0, X_NONE, "Could not map hardware registers.\n")); return (FALSE); } DEBUGMSG(1, (0, X_NONE, "adapter info %lx %lx %lx %p\n", pGeode->cpu_version, pGeode->vid_version, pGeode->FBAvail, pGeode->FBBase)); return TRUE; } /* * Unmap the framebuffer and MMIO memory. */ static Bool GXUnmapMem(ScrnInfoPtr pScrni) { GeodeRec *pGeode = GEODEPTR(pScrni); /* unmap all the memory map's */ xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_regptr, pGeode->cpu_reg_size); if (pGeode->DetectedChipSet & GX) { xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_gpptr, pGeode->gp_reg_size); } xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_vidptr, pGeode->vid_reg_size); xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_fbptr, pGeode->FBAvail); return TRUE; } /* End of file */