#define DEBUG(x)
#define GEODE_TRACE 0
#define CFB 0
#define HWVGA 0
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "xf86Resources.h"
#include "compiler.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "xf86cmap.h"
#if CFB
#define PSZ 8
#include "cfb.h"
#undef PSZ
#include "cfb16.h"
#include "cfb24.h"
#include "cfb32.h"
#else
#include "fb.h"
#endif
#include "shadowfb.h"
#include "mipointer.h"
#include "mibank.h"
#include "micmap.h"
#include "mibstore.h"
#include "vgaHW.h"
#include "vbe.h"
#ifdef XFreeXDGA
#define _XF86_DGA_SERVER_
#include "extensions/xf86dgastr.h"
#endif
#include "globals.h"
#include "opaque.h"
#define DPMS_SERVER
#include "extensions/dpms.h"
#include "nsc.h"
#if GEODE_TRACE
#define GeodeDebug(args) DebugPort(DCount++);ErrorF args
#else
#define GeodeDebug(args)
#endif
extern SymTabRec GeodeChipsets[];
extern OptionInfoRec GeodeOptions[];
typedef struct _MemOffset
{
unsigned long xres;
unsigned long yres;
unsigned long bpp;
unsigned long CBOffset;
unsigned short CBPitch;
unsigned short CBSize;
unsigned long CurOffset;
unsigned long OffScreenOffset;
}
MemOffset;
MemOffset GeodeMemOffset[] = {
{640, 480, 8, 640, 1024, 272, 0x78000, 0x78100},
{640, 480, 16, 1280, 2048, 272, 0x610, 0xF0000},
{800, 600, 8, 800, 1024, 208, 0x96000, 0x96100},
{800, 600, 16, 1600, 2048, 272, 0x12C000, 0x12C100},
{1024, 768, 8, 0xC0000, 272, 272, 0xF3000, 0xF3100},
{1024, 768, 16, 0x180000, 272, 272, 0x1B3000, 0x1B3100},
{1152, 864, 8, 1152, 2048, 272, 0x590, 0x1B0000},
{1152, 864, 16, 2304, 4096, 272, 0xA10, 0x360000},
{1280, 1024, 8, 1280, 2048, 272, 0x610, 0x200000},
{1280, 1024, 16, 2560, 4096, 272, 0xB10, 0x400000},
{704, 576, 16, 1408, 2048, 272, 0x690, 0x120000},
{720, 576, 16, 1440, 2048, 272, 0x6B0, 0x120000},
{768, 576, 16, 1536, 2048, 256, 0x700, 0x120000},
{704, 480, 16, 1408, 2048, 272, 0x690, 0xF0000},
{720, 480, 16, 1440, 2048, 272, 0x6B0, 0xF0000}
};
static int MemIndex = 0;
static Bool GX1PreInit(ScrnInfoPtr, int);
static Bool GX1ScreenInit(int, ScreenPtr, int, char **);
static Bool GX1EnterVT(int, int);
static void GX1LeaveVT(int, int);
static void GX1FreeScreen(int, int);
void GX1AdjustFrame(int, int, int, int);
Bool GX1SwitchMode(int, DisplayModePtr, int);
static ModeStatus GX1ValidMode(int, DisplayModePtr, Bool, int);
static void GX1LoadPalette(ScrnInfoPtr pScreenInfo,
int numColors, int *indizes,
LOCO * colors, VisualPtr pVisual);
static Bool GX1MapMem(ScrnInfoPtr);
static Bool GX1UnmapMem(ScrnInfoPtr);
extern Bool GX1AccelInit(ScreenPtr pScreen);
extern Bool GX1HWCursorInit(ScreenPtr pScreen);
extern void GX1HideCursor(ScrnInfoPtr pScreenInfo);
extern void GX1ShowCursor(ScrnInfoPtr pScreenInfo);
extern void GX1PointerMoved(int index, int x, int y);
extern void GX1RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
extern void GX1RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
extern void GX1RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
extern void GX1InitVideo(ScreenPtr pScreen);
extern Bool GX1DGAInit(ScreenPtr pScreen);
extern void GX1LoadCursorImage(ScrnInfoPtr pScreenInfo, unsigned char *src);
extern unsigned int GetVideoMemSize(void);
void get_tv_overscan_geom(const char *options, int *X, int *Y, int *W,
int *H);
void GX1SetupChipsetFPtr(ScrnInfoPtr pScrn);
GeodePtr GX1GetRec(ScrnInfoPtr pScreenInfo);
void gx1_clear_screen(int width, int height);
#if !defined(STB_X)
extern unsigned char *XpressROMPtr;
#endif
extern const char *nscVgahwSymbols[];
extern const char *nscVbeSymbols[];
extern const char *nscInt10Symbols[];
#if CFB
extern const char *nscCfbSymbols[];
#else
extern const char *nscFbSymbols[];
#endif
extern const char *nscXaaSymbols[];
extern const char *nscRamdacSymbols[];
extern const char *nscShadowSymbols[];
void
GX1SetupChipsetFPtr(ScrnInfoPtr pScrn)
{
GeodeDebug(("GX1SetupChipsetFPtr!\n"));
pScrn->PreInit = GX1PreInit;
pScrn->ScreenInit = GX1ScreenInit;
pScrn->SwitchMode = GX1SwitchMode;
pScrn->AdjustFrame = GX1AdjustFrame;
pScrn->EnterVT = GX1EnterVT;
pScrn->LeaveVT = GX1LeaveVT;
pScrn->FreeScreen = GX1FreeScreen;
pScrn->ValidMode = GX1ValidMode;
}
GeodePtr
GX1GetRec(ScrnInfoPtr pScreenInfo)
{
if (!pScreenInfo->driverPrivate)
pScreenInfo->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1);
return GEODEPTR(pScreenInfo);
}
static void
GX1FreeRec(ScrnInfoPtr pScreenInfo)
{
if (pScreenInfo->driverPrivate == NULL) {
return;
}
xfree(pScreenInfo->driverPrivate);
pScreenInfo->driverPrivate = NULL;
}
static Bool
GX1SaveScreen(ScreenPtr pScreen, int mode)
{
#if !defined(STB_X)
ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
GeodeDebug(("GX2SaveScreen!\n"));
if (!pScreenInfo->vtSema)
return vgaHWSaveScreen(pScreen, mode);
#endif
return TRUE;
}
void
get_tv_overscan_geom(const char *options, int *X, int *Y, int *W, int *H)
{
char *tv_opt;
tv_opt = strtok((char *)options, ":");
*X = strtoul(tv_opt, NULL, 0);
tv_opt = strtok(NULL, ":");
*Y = strtoul(tv_opt, NULL, 0);
tv_opt = strtok(NULL, ":");
*W = strtoul(tv_opt, NULL, 0);
tv_opt = strtok(NULL, ":");
*H = strtoul(tv_opt, NULL, 0);
}
static void
GX1ProbeDDC(ScrnInfoPtr pScrn, int index)
{
vbeInfoPtr pVbe;
if (xf86LoadSubModule(pScrn, "vbe")) {
pVbe = VBEInit(NULL, index);
ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
vbeFree(pVbe);
}
}
static Bool
GX1PreInit(ScrnInfoPtr pScreenInfo, int flags)
{
static ClockRange GeodeClockRange =
{ NULL, 25175, 135000, 0, FALSE, TRUE, 1, 1, 0 };
MessageType from;
int i = 0;
GeodePtr pGeode;
#if CFB
char *mod = NULL;
char *reqSymbol = NULL;
#endif
#if defined(STB_X)
GAL_ADAPTERINFO sAdapterInfo;
#endif
unsigned int PitchInc = 0, minPitch = 0, maxPitch = 0;
unsigned int minHeight = 0, maxHeight = 0;
const char *s;
char **modes;
char **tvmodes_defa;
GeodeDebug(("GX1PreInit!\n"));
if (!(pGeode = GX1GetRec(pScreenInfo)))
return FALSE;
for (i = 0; i < pScreenInfo->numEntities; i++) {
pGeode->pEnt = xf86GetEntityInfo(pScreenInfo->entityList[i]);
if (pGeode->pEnt->resources)
return FALSE;
pGeode->Chipset = pGeode->pEnt->chipset;
pScreenInfo->chipset = (char *)xf86TokenToString(GeodeChipsets,
pGeode->pEnt->chipset);
}
if (flags & PROBE_DETECT) {
GX1ProbeDDC(pScreenInfo, pGeode->pEnt->index);
return TRUE;
}
pGeode->FBVGAActive = 0;
#if !defined(STB_X)
if (!xf86LoadSubModule(pScreenInfo, "vgahw")) {
return FALSE;
}
xf86LoaderReqSymLists(nscVgahwSymbols, NULL);
#endif
GeodeDebug(("GX1PreInit(1)!\n"));
#if defined(STB_X)
if (!Gal_initialize_interface())
return FALSE;
if (Gal_get_adapter_info(&sAdapterInfo)) {
pGeode->cpu_version = sAdapterInfo.dwCPUVersion;
pGeode->vid_version = sAdapterInfo.dwVideoVersion;
pGeode->FBSize = sAdapterInfo.dwFrameBufferSize;
GeodeClockRange.maxClock = sAdapterInfo.dwMaxSupportedPixelClock;
pGeode->FBLinearAddr = sAdapterInfo.dwFrameBufferBase;
if (!GX1MapMem(pScreenInfo))
return FALSE;
} else {
return FALSE;
}
#else
pGeode->cpu_version = gfx_detect_cpu();
pGeode->vid_version = gfx_detect_video();
pGeode->FBLinearAddr = gfx_get_frame_buffer_base();
GeodeClockRange.maxClock = gfx_get_max_supported_pixel_clock();
if (!GX1MapMem(pScreenInfo))
return FALSE;
DEBUGMSG(1,
(0, X_INFO,
"Geode chip info: cpu:%x vid:%x size:%x base:%x, rom:%X\n",
pGeode->cpu_version, pGeode->vid_version, pGeode->FBSize,
pGeode->FBBase, XpressROMPtr));
#endif
pScreenInfo->monitor = pScreenInfo->confScreen->monitor;
GeodeDebug(("GX1PreInit(2)!\n"));
if (!xf86SetDepthBpp(pScreenInfo, 16, 0, 0, 0)) {
return FALSE;
} else {
switch (pScreenInfo->depth) {
case 8:
case 16:
break;
default:
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR,
"Given depth (%d bpp) is not supported by this driver\n",
pScreenInfo->depth));
return FALSE;
}
}
if (pScreenInfo->depth > 8) {
rgb zeros = { 0, 0, 0 };
if (!xf86SetWeight(pScreenInfo, zeros, zeros)) {
return FALSE;
} else {
}
}
xf86PrintDepthBpp(pScreenInfo);
GeodeDebug(("GX1PreInit(3)!\n"));
if (!xf86SetDefaultVisual(pScreenInfo, -1))
return FALSE;
GeodeDebug(("GX1PreInit(4)!\n"));
if (pScreenInfo->depth > 1) {
Gamma zeros = { 0.0, 0.0, 0.0 };
if (!xf86SetGamma(pScreenInfo, zeros)) {
return FALSE;
}
}
GeodeDebug(("GX1PreInit(5)!\n"));
pScreenInfo->progClock = TRUE;
xf86CollectOptions(pScreenInfo, NULL);
xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
GeodeOptions);
if (pScreenInfo->depth == 8) {
pScreenInfo->rgbBits = 8;
}
from = X_DEFAULT;
pGeode->HWCursor = TRUE;
if (xf86GetOptValBool(GeodeOptions, OPTION_HW_CURSOR, &pGeode->HWCursor)) {
from = X_CONFIG;
}
if (xf86ReturnOptValBool(GeodeOptions, OPTION_SW_CURSOR, FALSE)) {
from = X_CONFIG;
pGeode->HWCursor = FALSE;
}
DEBUGMSG(1, (pScreenInfo->scrnIndex, from, "Using %s cursor\n",
pGeode->HWCursor ? "HW" : "SW"));
pGeode->Compression = TRUE;
if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOCOMPRESSION, FALSE)) {
pGeode->Compression = FALSE;
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "NoCompression\n"));
}
pGeode->NoAccel = FALSE;
if (xf86ReturnOptValBool(GeodeOptions, OPTION_NOACCEL, FALSE)) {
pGeode->NoAccel = TRUE;
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "Acceleration \
disabled\n"));
}
if (!xf86GetOptValInteger(GeodeOptions, OPTION_OSM_IMG_BUFS,
&(pGeode->NoOfImgBuffers)))
pGeode->NoOfImgBuffers = DEFAULT_NUM_OF_BUF;
if (pGeode->NoOfImgBuffers <= 0)
pGeode->NoOfImgBuffers = 0;
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "No of Buffers %d\n",
pGeode->NoOfImgBuffers));
pGeode->TVSupport = FALSE;
pGeode->FBTVActive = 0;
GFX(get_tv_enable(&(pGeode->FBTVActive)));
DEBUGMSG(1, (1, X_PROBED, "FB TV %d \n", pGeode->FBTVActive));
if ((s = xf86GetOptValString(GeodeOptions, OPTION_TV_SUPPORT))) {
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "TV = %s\n", s));
if (!xf86NameCmp(s, "PAL-768x576")) {
pGeode->TvParam.wStandard = TV_STANDARD_PAL;
pGeode->TvParam.wType = GFX_ON_TV_SQUARE_PIXELS;
pGeode->TvParam.wWidth = 768;
pGeode->TvParam.wHeight = 576;
pGeode->TVSupport = TRUE;
} else if (!xf86NameCmp(s, "PAL-720x576")) {
pGeode->TvParam.wStandard = TV_STANDARD_PAL;
pGeode->TvParam.wType = GFX_ON_TV_NO_SCALING;
pGeode->TvParam.wWidth = 720;
pGeode->TvParam.wHeight = 576;
pGeode->TVSupport = TRUE;
} else if (!xf86NameCmp(s, "NTSC-640x480")) {
pGeode->TvParam.wStandard = TV_STANDARD_NTSC;
pGeode->TvParam.wType = GFX_ON_TV_SQUARE_PIXELS;
pGeode->TvParam.wWidth = 640;
pGeode->TvParam.wHeight = 480;
pGeode->TVSupport = TRUE;
} else if (!xf86NameCmp(s, "NTSC-720x480")) {
pGeode->TvParam.wStandard = TV_STANDARD_NTSC;
pGeode->TvParam.wType = GFX_ON_TV_NO_SCALING;
pGeode->TvParam.wWidth = 720;
pGeode->TvParam.wHeight = 480;
pGeode->TVSupport = TRUE;
}
if (pGeode->TVSupport == TRUE) {
pGeode->TvParam.wOutput = TV_OUTPUT_S_VIDEO;
if (pGeode->TVSupport) {
if ((s = xf86GetOptValString(GeodeOptions, OPTION_TV_OUTPUT))) {
if (!xf86NameCmp(s, "COMPOSITE")) {
pGeode->TvParam.wOutput = TV_OUTPUT_COMPOSITE;
} else if (!xf86NameCmp(s, "SVIDEO")) {
pGeode->TvParam.wOutput = TV_OUTPUT_S_VIDEO;
} else if (!xf86NameCmp(s, "YUV")) {
pGeode->TvParam.wOutput = TV_OUTPUT_YUV;
} else if (!xf86NameCmp(s, "SCART")) {
pGeode->TvParam.wOutput = TV_OUTPUT_SCART;
}
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"TVOutput = %s %d\n", s,
pGeode->TvParam.wOutput));
}
}
}
if ((pGeode->vid_version != GFX_VID_SC1200)
&& (pGeode->TVSupport == TRUE)) {
pGeode->TVSupport = FALSE;
}
if ((pScreenInfo->depth == 8) && (pGeode->TVSupport == TRUE)) {
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"Warning TV Disabled, TV Can't be supported in 8Bpp !!!\n"));
pGeode->TVSupport = FALSE;
}
}
if (pGeode->TVSupport == TRUE) {
pGeode->TVOx = 0;
pGeode->TVOy = 0;
pGeode->TVOw = 0;
pGeode->TVOh = 0;
pGeode->TV_Overscan_On = FALSE;
if ((s = xf86GetOptValString(GeodeOptions, OPTION_TV_OVERSCAN))) {
get_tv_overscan_geom(s, &(pGeode->TVOx),
&(pGeode->TVOy), &(pGeode->TVOw),
&(pGeode->TVOh));
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"TVO %d %d %d %d\n", pGeode->TVOx, pGeode->TVOy,
pGeode->TVOw, pGeode->TVOh));
if ((pGeode->TVOx >= 0 && pGeode->TVOy >= 0) &&
(pGeode->TVOh > 0 && pGeode->TVOw > 0)) {
if (((pGeode->TVOx + pGeode->TVOw) <= pGeode->TvParam.wWidth) &&
((pGeode->TVOy + pGeode->TVOh) <= pGeode->TvParam.wHeight)) {
pGeode->TV_Overscan_On = TRUE;
}
}
}
}
if (pGeode->TVSupport == FALSE) {
unsigned int status = 0;
GFX(get_tv_enable(&status));
if (status)
GFX(set_tv_enable(0));
}
pGeode->Panel = FALSE;
if (xf86ReturnOptValBool(GeodeOptions, OPTION_FLATPANEL, FALSE)) {
DEBUGMSG(0, (pScreenInfo->scrnIndex, X_CONFIG, "FlatPanel Selected\n"));
pGeode->Panel = TRUE;
}
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"Quering FP Bios %d\n", pGeode->Panel));
if (pGeode->Panel) {
int ret;
#if defined(STB_X)
Gal_get_softvga_state(&ret);
if (!ret) {
Gal_set_softvga_state(TRUE);
Gal_vga_mode_switch(0);
}
Gal_pnl_enabled_in_bios(&pGeode->Panel);
if (pGeode->Panel) {
Gal_pnl_info_from_bios(&pGeode->FPBX, &pGeode->FPBY,
&pGeode->FPBB, &pGeode->FPBF);
}
if (!ret) {
Gal_set_softvga_state(FALSE);
Gal_vga_mode_switch(1);
}
#else
ret = gfx_get_softvga_active();
if (!ret) {
gfx_enable_softvga();
gfx_vga_mode_switch(0);
}
pGeode->Panel = Pnl_IsPanelEnabledInBIOS();
if (pGeode->Panel) {
Pnl_GetPanelInfoFromBIOS(&pGeode->FPBX, &pGeode->FPBY,
&pGeode->FPBB, &pGeode->FPBF);
}
if (!ret) {
gfx_disable_softvga();
gfx_vga_mode_switch(1);
}
#endif
}
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"Quering FP Bios %d %d %d %d\n",
pGeode->FPBX, pGeode->FPBY, pGeode->FPBB, pGeode->FPBF));
if (!pGeode->Panel) {
#if defined(STB_X)
Gal_pnl_powerdown();
#else
Pnl_PowerDown();
#endif
} else {
#if defined(STB_X)
Gal_pnl_powerup();
#else
Pnl_PowerUp();
#endif
}
pGeode->ShadowFB = FALSE;
if (xf86ReturnOptValBool(GeodeOptions, OPTION_SHADOW_FB, FALSE)) {
pGeode->ShadowFB = TRUE;
pGeode->NoAccel = TRUE;
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"Using \"Shadow Framebuffer\" - acceleration disabled\n"));
}
pGeode->Rotate = 0;
if ((s = xf86GetOptValString(GeodeOptions, OPTION_ROTATE))) {
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "Rotating - %s\n", s));
if (!xf86NameCmp(s, "CW")) {
pGeode->ShadowFB = TRUE;
pGeode->NoAccel = TRUE;
pGeode->HWCursor = FALSE;
pGeode->Rotate = 1;
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"Rotating screen clockwise - acceleration disabled\n"));
} else {
if (!xf86NameCmp(s, "CCW")) {
pGeode->ShadowFB = TRUE;
pGeode->NoAccel = TRUE;
pGeode->HWCursor = FALSE;
pGeode->Rotate = -1;
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"Rotating screen counter clockwise - acceleration \
disabled\n"));
} else {
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"\"%s\" is not a valid value for Option \"Rotate\"\n",
s));
DEBUGMSG(1,
(pScreenInfo->scrnIndex, X_INFO,
"Valid options are \"CW\" or \"CCW\"\n"));
}
}
}
if (pGeode->TV_Overscan_On)
pGeode->Rotate = 0;
if (pScreenInfo->chipset == NULL) {
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR,
"ChipID 0x%04X is not recognised\n", pGeode->Chipset));
return FALSE;
}
if (pGeode->Chipset < 0) {
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR,
"Chipset \"%s\" is not recognised\n",
pScreenInfo->chipset));
return FALSE;
}
GeodeDebug(("GX1PreInit(6)!\n"));
#if !defined(STB_X)
DEBUGMSG(1, (pScreenInfo->scrnIndex, from,
"Video I/O registers at 0x%08lX\n",
(unsigned long)VGAHW_GET_IOBASE()));
#endif
if (pScreenInfo->memPhysBase == 0) {
from = X_PROBED;
#if defined(STB_X)
pScreenInfo->memPhysBase = sAdapterInfo.dwFrameBufferBase;
#else
pScreenInfo->memPhysBase = gfx_get_frame_buffer_base();
#endif
}
DEBUGMSG(1, (pScreenInfo->scrnIndex, from,
"Linear framebuffer at 0x%08lX\n",
(unsigned long)pScreenInfo->memPhysBase));
if (pGeode->pEnt->device->videoRam == 0) {
from = X_PROBED;
pScreenInfo->videoRam = pGeode->FBSize / 1024;
} else {
pScreenInfo->videoRam = pGeode->pEnt->device->videoRam;
from = X_CONFIG;
}
DEBUGMSG(1, (pScreenInfo->scrnIndex, from,
"VideoRam: %d kByte\n",
(unsigned long)pScreenInfo->videoRam));
GeodeDebug(("GX1PreInit(7)!\n"));
minPitch = 1024;
maxPitch = 2048;
minHeight = 480;
maxHeight = 1024;
if (pScreenInfo->depth == 16) {
PitchInc = 2048;
} else {
PitchInc = 1024;
}
PitchInc <<= 3;
modes = pScreenInfo->display->modes;
if (pGeode->TVSupport == TRUE) {
char str[20];
sprintf(str, "%dx%d-%d",
pGeode->TvParam.wWidth,
pGeode->TvParam.wHeight,
((pGeode->TvParam.wStandard == TV_STANDARD_PAL) ? 50 : 60));
tvmodes_defa = (char **)malloc(sizeof(char *) * 2);
tvmodes_defa[0] = (char *)malloc(strlen(str));
tvmodes_defa[1] = NULL;
strcpy(str, tvmodes_defa[0]);
modes = tvmodes_defa;
}
i = xf86ValidateModes(pScreenInfo,
pScreenInfo->monitor->Modes,
modes,
&GeodeClockRange,
NULL, minPitch, maxPitch,
PitchInc, minHeight, maxHeight,
pScreenInfo->display->virtualX,
pScreenInfo->display->virtualY,
#if defined(STB_X)
sAdapterInfo.dwFrameBufferSize,
#else
pGeode->FBSize,
#endif
LOOKUP_BEST_REFRESH);
DEBUGMSG(0, (pScreenInfo->scrnIndex, from,
"xf86ValidateModes: %d %d %d\n",
pScreenInfo->virtualX,
pScreenInfo->virtualY, pScreenInfo->displayWidth));
if (i == -1) {
GX1FreeRec(pScreenInfo);
return FALSE;
}
GeodeDebug(("GX1PreInit(8)!\n"));
xf86PruneDriverModes(pScreenInfo);
GeodeDebug(("GX1PreInit(9)!\n"));
if (i == 0 || pScreenInfo->modes == NULL) {
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR,
"No valid modes found\n"));
GX1FreeRec(pScreenInfo);
return FALSE;
}
GeodeDebug(("GX1PreInit(10)!\n"));
xf86SetCrtcForModes(pScreenInfo, 0);
GeodeDebug(("GX1PreInit(11)!\n"));
pScreenInfo->currentMode = pScreenInfo->modes;
GeodeDebug(("GX1PreInit(12)!\n"));
xf86PrintModes(pScreenInfo);
GeodeDebug(("GX1PreInit(13)!\n"));
xf86SetDpi(pScreenInfo, 0, 0);
GeodeDebug(("GX1PreInit(14)!\n"));
#if CFB
mod = NULL;
switch (pScreenInfo->bitsPerPixel) {
case 8:
mod = "cfb";
reqSymbol = "cfbScreenInit";
break;
case 16:
mod = "cfb16";
reqSymbol = "cfb16ScreenInit";
break;
default:
return FALSE;
}
if (mod && xf86LoadSubModule(pScreenInfo, mod) == NULL) {
GX1FreeRec(pScreenInfo);
return FALSE;
}
xf86LoaderReqSymbols(reqSymbol, NULL);
#else
if (xf86LoadSubModule(pScreenInfo, "fb") == NULL) {
GX1FreeRec(pScreenInfo);
return FALSE;
}
xf86LoaderReqSymLists(nscFbSymbols, NULL);
#endif
GeodeDebug(("GX1PreInit(15)!\n"));
if (pGeode->NoAccel == FALSE) {
if (!xf86LoadSubModule(pScreenInfo, "xaa")) {
GX1FreeRec(pScreenInfo);
return FALSE;
}
xf86LoaderReqSymLists(nscXaaSymbols, NULL);
}
GeodeDebug(("GX1PreInit(16)!\n"));
if (pGeode->HWCursor == TRUE) {
if (!xf86LoadSubModule(pScreenInfo, "ramdac")) {
GX1FreeRec(pScreenInfo);
return FALSE;
}
xf86LoaderReqSymLists(nscRamdacSymbols, NULL);
}
GeodeDebug(("GX1PreInit(17)!\n"));
if (pGeode->ShadowFB) {
if (!xf86LoadSubModule(pScreenInfo, "shadowfb")) {
GX1FreeRec(pScreenInfo);
return FALSE;
}
xf86LoaderReqSymLists(nscShadowSymbols, NULL);
}
GeodeDebug(("GX2PreInit(18)!\n"));
if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) {
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR,
"xf86RegisterResources() found resource conflicts\n"));
GX1FreeRec(pScreenInfo);
return FALSE;
}
GX1UnmapMem(pScreenInfo);
GeodeDebug(("GX1PreInit(19)!\n"));
GeodeDebug(("GX1PreInit(20)!\n"));
GeodeDebug(("GX1PreInit ... done successfully!\n"));
(void) from;
return TRUE;
}
static void
GX1RestoreEx(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode)
{
GeodePtr pGeode;
GeodeDebug(("GX1RestoreEx!\n"));
if (!(pGeode = GX1GetRec(pScreenInfo)))
return;
#if defined(STB_X)
pGeode->FBgfxVgaRegs.dwFlags = GFX_VGA_FLAG_MISC_OUTPUT |
GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC;
Gal_vga_restore(&(pGeode->FBgfxVgaRegs));
#else
gfx_vga_restore(&(pGeode->FBgfxVgaRegs),
GFX_VGA_FLAG_MISC_OUTPUT |
GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC);
#endif
}
static int
GX1CalculatePitchBytes(unsigned int width, unsigned int bpp)
{
int lineDelta = width * (bpp >> 3);
if (width < 640) {
DEBUGMSG(1, (0, X_PROBED, "lower resolution %d %d\n",
width, lineDelta));
lineDelta <<= 1;
}
if (1) {
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;
}
static int
GX1GetRefreshRate(DisplayModePtr pMode)
{
#define THRESHOLD 2
unsigned int i;
static int validRates[] = { 50, 56, 60, 70, 72, 75, 85 };
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;
DEBUGMSG(1, (0, X_PROBED, "dotclock %d %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
gx1_clear_screen(int width, int height)
{
GFX(set_solid_pattern(0));
GFX(set_raster_operation(0xF0));
GFX(pattern_fill(0, 0, width, height));
}
static Bool
GX1SetMode(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode)
{
GeodePtr pGeode;
GeodeDebug(("GX1SetMode!\n"));
pGeode = GEODEPTR(pScreenInfo);
pScreenInfo->vtSema = TRUE;
DEBUGMSG(1, (0, X_NONE, "Set mode"));
GeodeDebug(("Set display mode: %dx%d-%d (%dHz)\n",
pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel, GX1GetRefreshRate(pMode)));
GeodeDebug(("Before setting the mode\n"));
if ((pMode->CrtcHDisplay >= 640) && (pMode->CrtcVDisplay >= 480))
GFX(set_display_bpp(pScreenInfo->bitsPerPixel));
if (pGeode->TVSupport == TRUE) {
pGeode->TvParam.bState = 1;
#if defined(STB_X)
Gal_tv_set_params(GAL_TVSTATE | GAL_TVOUTPUT |
GAL_TVFORMAT | GAL_TVRESOLUTION, &(pGeode->TvParam));
#else
gfx_set_tv_display(pGeode->TvParam.wWidth, pGeode->TvParam.wHeight);
gfx_set_tv_format((TVStandardType)pGeode->TvParam.wStandard,
(GfxOnTVType)pGeode->TvParam.wType);
gfx_set_tv_output(pGeode->TvParam.wOutput);
gfx_set_tv_enable(pGeode->TvParam.bState);
#endif
} else {
DEBUGMSG(0, (0, X_PROBED, "Setting Display for CRT or TFT\n"));
if (pGeode->Panel) {
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, pScreenInfo->bitsPerPixel));
GFX(set_fixed_timings(pGeode->FPBX, pGeode->FPBY,
pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel));
} else {
DEBUGMSG(0, (0, X_PROBED, "Setting Display for CRT\n"));
GFX(set_display_mode(pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel,
GX1GetRefreshRate(pMode)));
GFX(set_display_pitch(pGeode->Pitch));
}
GFX(set_crt_enable(CRT_ENABLE));
}
GFX(set_display_offset(0L));
GFX(wait_vertical_blank());
if (pGeode->Compression) {
#if defined(STB_X)
Gal_set_compression_parameters(GAL_COMPRESSION_ALL,
pGeode->CBOffset,
pGeode->CBPitch, pGeode->CBSize);
Gal_set_compression_enable(GAL_COMPRESSION_ENABLE);
#else
gfx_set_compression_offset(pGeode->CBOffset);
gfx_set_compression_pitch(pGeode->CBPitch);
gfx_set_compression_size(pGeode->CBSize);
gfx_set_compression_enable(1);
#endif
}
if (pGeode->HWCursor) {
GX1LoadCursorImage(pScreenInfo, NULL);
GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0));
GFX(set_cursor_enable(1));
} else {
GeodeDebug(("GX1RestoreEx ... "));
GX1RestoreEx(pScreenInfo, pMode);
GeodeDebug(("done.\n"));
}
GeodeDebug(("done.\n"));
if (pGeode->HWCursor == TRUE) {
GeodeDebug(("GX1ShowCursor ... "));
GX1ShowCursor(pScreenInfo);
GeodeDebug(("done.\n"));
}
GeodeDebug(("After setting the mode\n"));
return TRUE;
}
static Bool
GX1EnterGraphics(ScreenPtr pScreen, ScrnInfoPtr pScreenInfo)
{
GeodePtr pGeode;
#if !defined(STB_X)
vgaHWPtr hwp = VGAHWPTR(pScreenInfo);
vgaHWUnlock(hwp);
#endif
GeodeDebug(("GX1EnterGraphics!\n"));
DEBUGMSG(1, (0, X_NONE, "EnterGraphics\n"));
pGeode = GX1GetRec(pScreenInfo);
#if 0
print_gxm_gfx_reg(pGeode, 0x4C);
print_gxm_vga_reg();
#endif
#if defined(STB_X)
Gal_get_softvga_state(&pGeode->FBVGAActive);
pGeode->FBgfxVgaRegs.dwFlags = GFX_VGA_FLAG_MISC_OUTPUT |
GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC;
Gal_vga_save(&(pGeode->FBgfxVgaRegs));
#else
pGeode->FBVGAActive = gfx_get_softvga_active();
gfx_vga_save(&(pGeode->FBgfxVgaRegs),
GFX_VGA_FLAG_MISC_OUTPUT |
GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC);
#endif
DEBUGMSG(1, (0, X_PROBED, "VSA = %d\n", pGeode->FBVGAActive));
#if !defined(STB_X)
vgaHWSave(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL);
#endif
#if defined(STB_X)
Gal_get_display_timing(&pGeode->FBgfxdisplaytiming);
Gal_tv_get_timings(0, &pGeode->FBgfxtvtiming);
Gal_get_display_offset(&(pGeode->FBDisplayOffset));
Gal_get_compression_enable(&(pGeode->FBCompressionEnable));
Gal_get_compression_parameters(GAL_COMPRESSION_ALL,
&(pGeode->FBCompressionOffset),
&(pGeode->FBCompressionPitch),
&(pGeode->FBCompressionSize));
{
unsigned short x, y, xhot, yhot;
Gal_get_cursor_position(&(pGeode->FBCursorOffset),
&x, &y, &xhot, &yhot);
}
Gal_pnl_save();
Gal_set_softvga_state(FALSE);
Gal_vga_mode_switch(1);
#else
gfx_get_tv_enable(&(pGeode->FBTVEnabled));
if (pGeode->FBTVEnabled) {
pGeode->FBtvtiming.HorzTim = READ_VID32(SC1200_TVOUT_HORZ_TIM);
pGeode->FBtvtiming.HorzSync = READ_VID32(SC1200_TVOUT_HORZ_SYNC);
pGeode->FBtvtiming.VertSync = READ_VID32(SC1200_TVOUT_VERT_SYNC);
pGeode->FBtvtiming.LineEnd = READ_VID32(SC1200_TVOUT_LINE_END);
pGeode->FBtvtiming.VertDownscale =
READ_VID32(SC1200_TVOUT_VERT_DOWNSCALE);
pGeode->FBtvtiming.HorzScaling = READ_VID32(SC1200_TVOUT_HORZ_SCALING);
pGeode->FBtvtiming.TimCtrl1 = READ_VID32(SC1200_TVENC_TIM_CTRL_1);
pGeode->FBtvtiming.TimCtrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2);
pGeode->FBtvtiming.Subfreq = READ_VID32(SC1200_TVENC_SUB_FREQ);
pGeode->FBtvtiming.DispPos = READ_VID32(SC1200_TVENC_DISP_POS);
pGeode->FBtvtiming.DispSize = READ_VID32(SC1200_TVENC_DISP_SIZE);
pGeode->FBtvtiming.TimCtrl2 = READ_VID32(SC1200_TVENC_TIM_CTRL_2);
pGeode->FBtvtiming.Debug = READ_VID32(SC1200_TVOUT_DEBUG);
pGeode->FBtvtiming.DacCtrl = READ_VID32(SC1200_TVENC_DAC_CONTROL);
}
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();
pGeode->FBDisplayOffset = gfx_get_display_offset();
pGeode->FBCompressionEnable = gfx_get_compression_enable();
pGeode->FBCompressionOffset = gfx_get_compression_offset();
pGeode->FBCompressionPitch = gfx_get_compression_pitch();
pGeode->FBCompressionSize = gfx_get_compression_size();
pGeode->FBCursorOffset = gfx_get_cursor_offset();
Pnl_SavePanelState();
gfx_disable_softvga();
gfx_vga_mode_switch(1);
#endif
if (!GX1SetMode(pScreenInfo, pScreenInfo->currentMode)) {
return FALSE;
}
#if 1
gx1_clear_screen(pScreenInfo->currentMode->CrtcHDisplay,
pScreenInfo->currentMode->CrtcVDisplay);
#endif
return TRUE;
}
static void
GX1LeaveGraphics(ScrnInfoPtr pScreenInfo)
{
GeodePtr pGeode;
GeodeDebug(("GX1LeaveGraphics!\n"));
pGeode = GEODEPTR(pScreenInfo);
if (!pGeode->FBTVActive) {
GFX(set_tv_enable(0));
}
gx1_clear_screen(pScreenInfo->virtualX, pScreenInfo->virtualY);
#if defined(STB_X)
Gal_set_display_timing(&pGeode->FBgfxdisplaytiming);
Gal_tv_set_timings(0, &pGeode->FBgfxtvtiming);
Gal_set_display_offset(pGeode->FBDisplayOffset);
Gal_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0);
if (pGeode->FBCompressionEnable) {
Gal_set_compression_parameters(GAL_COMPRESSION_ALL,
pGeode->FBCompressionOffset,
pGeode->FBCompressionPitch,
pGeode->FBCompressionSize);
Gal_set_compression_enable(GAL_COMPRESSION_ENABLE);
}
#else
if (pGeode->FBTVEnabled) {
WRITE_VID32(SC1200_TVOUT_HORZ_TIM, pGeode->FBtvtiming.HorzTim);
WRITE_VID32(SC1200_TVOUT_HORZ_SYNC, pGeode->FBtvtiming.HorzSync);
WRITE_VID32(SC1200_TVOUT_VERT_SYNC, pGeode->FBtvtiming.VertSync);
WRITE_VID32(SC1200_TVOUT_LINE_END, pGeode->FBtvtiming.LineEnd);
WRITE_VID32(SC1200_TVOUT_VERT_DOWNSCALE,
pGeode->FBtvtiming.VertDownscale);
WRITE_VID32(SC1200_TVOUT_HORZ_SCALING, pGeode->FBtvtiming.HorzScaling);
WRITE_VID32(SC1200_TVENC_TIM_CTRL_1, pGeode->FBtvtiming.TimCtrl1);
WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, pGeode->FBtvtiming.TimCtrl2);
WRITE_VID32(SC1200_TVENC_SUB_FREQ, pGeode->FBtvtiming.Subfreq);
WRITE_VID32(SC1200_TVENC_DISP_POS, pGeode->FBtvtiming.DispPos);
WRITE_VID32(SC1200_TVENC_DISP_SIZE, pGeode->FBtvtiming.DispSize);
WRITE_VID32(SC1200_TVENC_TIM_CTRL_2, pGeode->FBtvtiming.TimCtrl2);
WRITE_VID32(SC1200_TVOUT_DEBUG, pGeode->FBtvtiming.Debug);
WRITE_VID32(SC1200_TVENC_DAC_CONTROL, pGeode->FBtvtiming.DacCtrl);
}
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_display_pitch(pGeode->FBgfxdisplaytiming.wPitch);
gfx_set_display_offset(pGeode->FBDisplayOffset);
gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0);
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);
}
#endif
#if 0
if ((pGeode->FBgfxdisplaytiming.wHActive == 720) &&
(pGeode->FBgfxdisplaytiming.wVActive == 400))
#else
if (pGeode->FBVGAActive)
#endif
{
#if defined(STB_X)
Gal_set_softvga_state(TRUE);
Gal_vga_mode_switch(1);
Gal_vga_clear_extended();
#else
gfx_enable_softvga();
gfx_vga_mode_switch(1);
gfx_vga_clear_extended();
#endif
#if !defined(STB_X)
vgaHWRestore(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL);
#endif
#if defined(STB_X)
pGeode->FBgfxVgaRegs.dwFlags = GFX_VGA_FLAG_MISC_OUTPUT |
GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC;
Gal_vga_restore(&(pGeode->FBgfxVgaRegs));
Gal_vga_mode_switch(0);
#else
gfx_vga_restore(&(pGeode->FBgfxVgaRegs),
GFX_VGA_FLAG_MISC_OUTPUT |
GFX_VGA_FLAG_STD_CRTC | GFX_VGA_FLAG_EXT_CRTC);
gfx_vga_mode_switch(0);
#endif
}
#if 0
print_gxm_gfx_reg(pGeode, 0x4C);
print_gxm_vga_reg();
#endif
}
static Bool
GX1CloseScreen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
GeodePtr pGeode = GEODEPTR(pScreenInfo);
DEBUGMSG(1, (scrnIndex, X_PROBED, "GX1CloseScreen\n"));
GeodeDebug(("GX1CloseScreen!\n"));
GX1LeaveGraphics(pScreenInfo);
if (pGeode->AccelInfoRec)
XAADestroyInfoRec(pGeode->AccelInfoRec);
pScreenInfo->vtSema = FALSE;
if (pGeode->DGAModes)
xfree(pGeode->DGAModes);
pGeode->DGAModes = 0;
if (pGeode->ShadowPtr)
xfree(pGeode->ShadowPtr);
if (pGeode->AccelImageWriteBufferOffsets) {
xfree(pGeode->AccelImageWriteBufferOffsets);
pGeode->AccelImageWriteBufferOffsets = 0x0;
}
xf86FreeOffscreenArea(pGeode->AccelImgArea);
xf86FreeOffscreenArea(pGeode->CompressionArea);
GX1UnmapMem(pScreenInfo);
pScreen->CloseScreen = pGeode->CloseScreen;
return (*pScreen->CloseScreen) (scrnIndex, pScreen);
}
static void
GX1DPMSSet(ScrnInfoPtr pScreenInfo, int mode, int flags)
{
GeodePtr pGeode;
pGeode = GEODEPTR(pScreenInfo);
GeodeDebug(("GX1DPMSSet!\n"));
if (!pScreenInfo->vtSema) {
ErrorF("GX1DPMSSet called when we not controlling the VT!\n");
return;
}
switch (mode) {
case DPMSModeOn:
GFX(set_crt_enable(CRT_ENABLE));
#if defined(STB_X)
if (pGeode->Panel)
Gal_pnl_powerup();
#else
if (pGeode->Panel)
Pnl_PowerUp();
#endif
if (pGeode->TVSupport)
GFX(set_tv_enable(1));
break;
case DPMSModeStandby:
GFX(set_crt_enable(CRT_STANDBY));
#if defined(STB_X)
if (pGeode->Panel)
Gal_pnl_powerdown();
#else
if (pGeode->Panel)
Pnl_PowerDown();
#endif
if (pGeode->TVSupport)
GFX(set_tv_enable(0));
break;
case DPMSModeSuspend:
GFX(set_crt_enable(CRT_SUSPEND));
#if defined(STB_X)
if (pGeode->Panel)
Gal_pnl_powerdown();
#else
if (pGeode->Panel)
Pnl_PowerDown();
#endif
if (pGeode->TVSupport)
GFX(set_tv_enable(0));
break;
case DPMSModeOff:
GFX(set_crt_enable(CRT_DISABLE));
#if defined(STB_X)
if (pGeode->Panel)
Gal_pnl_powerdown();
#else
if (pGeode->Panel)
Pnl_PowerDown();
#endif
if (pGeode->TVSupport)
GFX(set_tv_enable(0));
break;
}
}
static Bool
GX1ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
GeodePtr pGeode;
int i;
Bool Inited = FALSE;
unsigned char *FBStart;
unsigned int req_offscreenmem;
int width, height, displayWidth;
VisualPtr visual;
BoxRec AvailBox;
RegionRec OffscreenRegion;
DCount = 30;
GeodeDebug(("GX1ScreenInit!\n"));
pGeode = GX1GetRec(pScreenInfo);
GeodeDebug(("GX1ScreenInit(0)!\n"));
#if !defined(STB_X)
if (!vgaHWGetHWRec(pScreenInfo))
return FALSE;
VGAHWPTR(pScreenInfo)->MapSize = 0x10000;
if (!vgaHWMapMem(pScreenInfo))
return FALSE;
#endif
if (!GX1MapMem(pScreenInfo))
return FALSE;
#if !defined(STB_X)
vgaHWGetIOBase(VGAHWPTR(pScreenInfo));
#endif
pGeode->Pitch = GX1CalculatePitchBytes(pScreenInfo->virtualX,
pScreenInfo->bitsPerPixel);
for (i = 0; i < (int)((sizeof(GeodeMemOffset) / sizeof(MemOffset))); i++) {
if ((pScreenInfo->virtualX == (int)GeodeMemOffset[i].xres) &&
(pScreenInfo->virtualY == (int)GeodeMemOffset[i].yres) &&
(pScreenInfo->bitsPerPixel == (int)GeodeMemOffset[i].bpp)) {
MemIndex = i;
break;
}
}
if (MemIndex == -1)
return FALSE;
AvailBox.x1 = 0;
AvailBox.y1 = pScreenInfo->virtualY;
AvailBox.x2 = pScreenInfo->displayWidth;
AvailBox.y2 = (pGeode->FBSize / pGeode->Pitch);
pGeode->CursorSize = 8 * 32;
if (pGeode->HWCursor) {
pGeode->CursorStartOffset = pGeode->FBSize - pGeode->CursorSize;
AvailBox.y2 -= 1;
}
DEBUGMSG(1, (scrnIndex, X_PROBED,
"Memory manager initialized to (%d,%d) (%d,%d) %d %d\n",
AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2,
pGeode->Pitch, pScreenInfo->displayWidth));
if (pGeode->Compression) {
pGeode->CBOffset = GeodeMemOffset[MemIndex].CBOffset;
pGeode->CBSize = GeodeMemOffset[MemIndex].CBSize - 16;
pGeode->CBPitch = GeodeMemOffset[MemIndex].CBPitch;
if ((pScreenInfo->virtualX == 1024) && (pScreenInfo->virtualY == 768)) {
req_offscreenmem = pScreenInfo->virtualY * pGeode->CBPitch;
req_offscreenmem += pGeode->Pitch - 1;
req_offscreenmem /= pGeode->Pitch;
pGeode->CBOffset = AvailBox.y1 * pGeode->Pitch;
AvailBox.y1 += req_offscreenmem;
}
}
DEBUGMSG(1, (scrnIndex, X_PROBED,
"Memory manager initialized to (%d,%d) (%d,%d)\n",
AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2));
if (!pGeode->NoAccel) {
if (pGeode->NoOfImgBuffers > 0) {
if (pGeode->NoOfImgBuffers <= (AvailBox.y2 - AvailBox.y1)) {
pGeode->AccelImageWriteBufferOffsets =
xalloc(sizeof(unsigned long) * pGeode->NoOfImgBuffers);
pGeode->AccelImageWriteBufferOffsets[0] =
((unsigned char *)pGeode->FBBase) +
(AvailBox.y1 * pGeode->Pitch);
for (i = 1; i < pGeode->NoOfImgBuffers; i++) {
pGeode->AccelImageWriteBufferOffsets[i] =
pGeode->AccelImageWriteBufferOffsets[i - 1] +
pGeode->Pitch;
}
for (i = 0; i < pGeode->NoOfImgBuffers; i++) {
DEBUGMSG(1, (scrnIndex, X_PROBED,
"memory %d %x\n", i,
pGeode->AccelImageWriteBufferOffsets[i]));
}
AvailBox.y1 += pGeode->NoOfImgBuffers;
} else {
xf86DrvMsg(scrnIndex, X_ERROR,
"Unable to reserve scanline area\n");
}
}
DEBUGMSG(1, (scrnIndex, X_PROBED,
"Memory manager initialized to (%d,%d) (%d,%d)\n",
AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2));
REGION_INIT(pScreen, &OffscreenRegion, &AvailBox, 2);
if (!xf86InitFBManagerRegion(pScreen, &OffscreenRegion)) {
xf86DrvMsg(scrnIndex, X_ERROR,
"Memory manager initialization to (%d,%d) (%d,%d) failed\n",
AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2);
} else {
xf86DrvMsg(scrnIndex, X_INFO,
"Memory manager initialized to (%d,%d) (%d,%d)\n",
AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2);
}
REGION_UNINIT(pScreen, &OffscreenRegion);
}
if (!GX1EnterGraphics(pScreen, pScreenInfo))
return FALSE;
GX1AdjustFrame(scrnIndex, pScreenInfo->frameX0, pScreenInfo->frameY0, 0);
GeodeDebug(("GX1ScreenInit(1)!\n"));
miClearVisualTypes();
GeodeDebug(("GX1ScreenInit(2)!\n"));
if (pScreenInfo->bitsPerPixel > 8) {
if (!miSetVisualTypes(pScreenInfo->depth,
TrueColorMask,
pScreenInfo->rgbBits,
pScreenInfo->defaultVisual)) {
return FALSE;
}
} else {
if (!miSetVisualTypes(pScreenInfo->depth,
miGetDefaultVisualMask(pScreenInfo->depth),
pScreenInfo->rgbBits,
pScreenInfo->defaultVisual)) {
return FALSE;
}
}
GeodeDebug(("GX1ScreenInit(3)!\n"));
miSetPixmapDepths();
if (pGeode->TV_Overscan_On) {
width = pGeode->TVOw;
height = pGeode->TVOh;
GeodeDebug(("width : %d , height : %d", width, height));
} else {
width = pScreenInfo->virtualX;
height = pScreenInfo->virtualY;
}
displayWidth = pScreenInfo->displayWidth;
if (pGeode->Rotate) {
if (pGeode->TV_Overscan_On) {
width = pGeode->TVOh;
height = pGeode->TVOw;
} else {
width = pScreenInfo->virtualY;
height = pScreenInfo->virtualX;
}
}
if (pGeode->ShadowFB) {
pGeode->ShadowPitch = BitmapBytePad(pScreenInfo->bitsPerPixel * width);
pGeode->ShadowPtr = xalloc(pGeode->ShadowPitch * height);
displayWidth = pGeode->ShadowPitch / (pScreenInfo->bitsPerPixel >> 3);
FBStart = pGeode->ShadowPtr;
} else {
pGeode->ShadowPtr = NULL;
if (pGeode->TV_Overscan_On) {
GeodeDebug(("pGeode->Pitch (%d)!\n", pGeode->Pitch));
FBStart = pGeode->FBBase + (pGeode->Pitch * pGeode->TVOy) +
(pGeode->TVOx << ((pScreenInfo->depth >> 3) - 1));
} else {
FBStart = pGeode->FBBase;
}
DEBUGMSG(1, (0, X_PROBED, "FBStart %X \n", FBStart));
}
switch (pScreenInfo->bitsPerPixel) {
#if CFB
case 8:
Inited = cfbScreenInit(pScreen, FBStart, width, height,
pScreenInfo->xDpi, pScreenInfo->yDpi,
displayWidth);
break;
case 16:
Inited = cfb16ScreenInit(pScreen, FBStart, width, height,
pScreenInfo->xDpi, pScreenInfo->yDpi,
displayWidth);
break;
#else
case 8:
case 16:
Inited = fbScreenInit(pScreen, FBStart, width, height,
pScreenInfo->xDpi, pScreenInfo->yDpi,
displayWidth, pScreenInfo->bitsPerPixel);
break;
#endif
default:
xf86DrvMsg(scrnIndex, X_ERROR,
"Internal error: invalid bpp (%d) in ScreenInit\n",
pScreenInfo->bitsPerPixel);
Inited = FALSE;
break;
}
if (!Inited)
return FALSE;
GeodeDebug(("GX1ScreenInit(4)!\n"));
xf86SetBlackWhitePixels(pScreen);
if (!pGeode->ShadowFB && (!pGeode->TV_Overscan_On)) {
GX1DGAInit(pScreen);
}
GeodeDebug(("GX1ScreenInit(5)!\n"));
if (pScreenInfo->bitsPerPixel > 8) {
visual = pScreen->visuals + pScreen->numVisuals;
while (--visual >= pScreen->visuals) {
if ((visual->class | DynamicClass) == DirectColor) {
visual->offsetRed = pScreenInfo->offset.red;
visual->offsetGreen = pScreenInfo->offset.green;
visual->offsetBlue = pScreenInfo->offset.blue;
visual->redMask = pScreenInfo->mask.red;
visual->greenMask = pScreenInfo->mask.green;
visual->blueMask = pScreenInfo->mask.blue;
}
}
}
#if CFB
#else
fbPictureInit(pScreen, 0, 0);
#endif
GeodeDebug(("GX1ScreenInit(6)!\n"));
if (!pGeode->NoAccel) {
GX1AccelInit(pScreen);
}
GeodeDebug(("GX1ScreenInit(7)!\n"));
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
GeodeDebug(("GX1ScreenInit(8)!\n"));
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
if (pGeode->HWCursor) {
if (!GX1HWCursorInit(pScreen))
xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
"Hardware cursor initialization failed\n");
}
GeodeDebug(("GX1ScreenInit(9)!\n"));
if (!miCreateDefColormap(pScreen)) {
return FALSE;
}
GeodeDebug(("GX1ScreenInit(10)!\n"));
if (!xf86HandleColormaps(pScreen, 256, 8,
GX1LoadPalette, NULL,
CMAP_PALETTED_TRUECOLOR |
CMAP_RELOAD_ON_MODE_SWITCH)) {
return FALSE;
}
GeodeDebug(("GX1ScreenInit(11)!\n"));
if (pGeode->ShadowFB) {
RefreshAreaFuncPtr refreshArea = GX1RefreshArea;
if (pGeode->Rotate) {
if (!pGeode->PointerMoved) {
pGeode->PointerMoved = pScreenInfo->PointerMoved;
pScreenInfo->PointerMoved = GX1PointerMoved;
}
switch (pScreenInfo->bitsPerPixel) {
case 8:
refreshArea = GX1RefreshArea8;
break;
case 16:
refreshArea = GX1RefreshArea16;
break;
}
}
ShadowFBInit(pScreen, refreshArea);
}
xf86DPMSInit(pScreen, GX1DPMSSet, 0);
GeodeDebug(("GX1ScreenInit(12)!\n"));
if (pGeode->TV_Overscan_On) {
GeodeDebug(("pGeode->Pitch (%d)!\n", pGeode->Pitch));
pScreenInfo->memPhysBase = (unsigned long)(pGeode->FBBase +
(pGeode->Pitch *
pGeode->TVOy) +
(pGeode->
TVOx <<
((pScreenInfo->depth >> 3) -
1)));
GeodeDebug(("->memPhysBase (%X)!\n", pScreenInfo->memPhysBase));
} else {
pScreenInfo->memPhysBase = (unsigned long)pGeode->FBBase;
}
pScreenInfo->fbOffset = 0;
GeodeDebug(("GX1ScreenInit(13)!\n"));
GX1InitVideo(pScreen);
pGeode->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = GX1CloseScreen;
pScreen->SaveScreen = GX1SaveScreen;
GeodeDebug(("GX1ScreenInit(14)!\n"));
if (serverGeneration == 1) {
xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options);
}
GeodeDebug(("GX2ScreenInit(15)!\n"));
return TRUE;
}
Bool
GX1SwitchMode(int scrnIndex, DisplayModePtr pMode, int flags)
{
GeodeDebug(("GX1SwitchMode!\n"));
return GX1SetMode(xf86Screens[scrnIndex], pMode);
}
void
GX1AdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
GeodePtr pGeode;
unsigned long offset;
pGeode = GX1GetRec(pScreenInfo);
offset = (unsigned long)y *(unsigned long)pGeode->Pitch;
offset += x;
if (pScreenInfo->bitsPerPixel > 8) {
offset += x;
}
GFX(set_display_offset(offset));
}
static Bool
GX1EnterVT(int scrnIndex, int flags)
{
GeodeDebug(("GX1EnterVT!\n"));
return GX1EnterGraphics(NULL, xf86Screens[scrnIndex]);
}
static void
GX1LeaveVT(int scrnIndex, int flags)
{
GeodeDebug(("GX1LeaveVT!\n"));
GX1LeaveGraphics(xf86Screens[scrnIndex]);
}
static void
GX1FreeScreen(int scrnIndex, int flags)
{
GeodeDebug(("GX1FreeScreen!\n"));
#if !defined(STB_X)
if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
vgaHWFreeHWRec(xf86Screens[scrnIndex]);
#endif
GX1FreeRec(xf86Screens[scrnIndex]);
}
static ModeStatus
GX1ValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags)
{
ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
unsigned int total_memory_required;
int ret = -1;
GeodePtr pGeode = GX1GetRec(pScreenInfo);
DEBUGMSG(1, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n",
pMode->CrtcHDisplay, pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel, GX1GetRefreshRate(pMode)));
if (pGeode->TVSupport == TRUE) {
if ((pGeode->TvParam.wWidth == pMode->CrtcHDisplay) &&
(pGeode->TvParam.wHeight == pMode->CrtcVDisplay)) {
DEBUGMSG(1, (0, X_NONE, "TV mode\n"));
#if defined(STB_X)
Gal_is_tv_mode_supported(0, &(pGeode->TvParam), &ret);
#else
ret = gfx_is_tv_display_mode_supported(pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
(TVStandardType)pGeode->TvParam.wStandard);
#endif
}
} else {
DEBUGMSG(1, (0, X_NONE, "CRT mode\n"));
if (pMode->Flags & V_INTERLACE)
return MODE_NO_INTERLACE;
#if defined(STB_X)
Gal_is_display_mode_supported(pMode->CrtcHDisplay, pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel,
GX1GetRefreshRate(pMode), &ret);
#else
ret = gfx_is_display_mode_supported(pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel,
GX1GetRefreshRate(pMode));
#endif
}
if (ret < 0)
return MODE_NOMODE;
total_memory_required = GX1CalculatePitchBytes(pMode->CrtcHDisplay,
pScreenInfo->bitsPerPixel) *
pMode->CrtcVDisplay;
DEBUGMSG(0, (0, X_NONE, "Total Mem %X %X",
total_memory_required, pGeode->FBSize));
if (total_memory_required > pGeode->FBSize)
return MODE_MEM;
return MODE_OK;
}
static void
GX1LoadPalette(ScrnInfoPtr pScreenInfo,
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, "GX1LoadPalette: %d %d %X\n",
numColors, index, color));
GFX(set_display_palette_entry(index, color));
}
}
static Bool
GX1MapMem(ScrnInfoPtr pScreenInfo)
{
GeodePtr pGeode = GEODEPTR(pScreenInfo);
#if defined(STB_X)
pGeode->FBBase = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex,
VIDMEM_FRAMEBUFFER,
pGeode->FBLinearAddr,
pGeode->FBSize);
#else
gfx_virt_regptr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex,
VIDMEM_MMIO,
(unsigned int)
gfx_get_cpu_register_base
(), 0x9000);
gfx_virt_spptr = gfx_virt_regptr;
gfx_virt_vidptr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex,
VIDMEM_MMIO,
(unsigned int)
gfx_get_vid_register_base
(), 0x1000);
pGeode->FBSize = GetVideoMemSize();
gfx_virt_fbptr =
(unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex,
VIDMEM_FRAMEBUFFER,
pGeode->FBLinearAddr, pGeode->FBSize);
if ((!gfx_virt_regptr) ||
(!gfx_virt_spptr) || (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) {
DEBUGMSG(1, (0, X_NONE, "Could not map hardware registers.\n"));
return (FALSE);
}
XpressROMPtr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex,
VIDMEM_FRAMEBUFFER, 0xF0000,
0x10000);
if (!XpressROMPtr)
return FALSE;
pGeode->FBBase = gfx_virt_fbptr;
#endif
return TRUE;
}
static Bool
GX1UnmapMem(ScrnInfoPtr pScreenInfo)
{
#if !defined(STB_X)
GeodePtr pGeode = GEODEPTR(pScreenInfo);
xf86UnMapVidMem(pScreenInfo->scrnIndex, gfx_virt_regptr, 0x9000);
xf86UnMapVidMem(pScreenInfo->scrnIndex, gfx_virt_vidptr, 0x1000);
xf86UnMapVidMem(pScreenInfo->scrnIndex, gfx_virt_fbptr, pGeode->FBSize);
xf86UnMapVidMem(pScreenInfo->scrnIndex, XpressROMPtr, 0x10000);
#endif
return TRUE;
}