Files
xf86-video-geode/src/amd_gx_driver.c
Jordan Crouse 3718e9e263 PATCH: Fix some VGA issues
Fix some issues from the recent NoVGA refactoring
2006-07-07 17:45:29 -06:00

2493 lines
75 KiB
C

/* 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 */