#define DEBUG(x)
#define GEODE_TRACE 0
#define CFB 0
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "xf86Resources.h"
#include "compiler.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#define INT10_SUPPORT 1
#include "xf86cmap.h"
#define RC_MAX_DEPTH 24
#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 !defined(STB_X)
#include "nsc_gx2_vga.c"
#endif
#if GEODE_TRACE
#define GeodeDebug(args) DebugPort(DCount++);ErrorF args
#else
#define GeodeDebug(args)
#endif
extern SymTabRec GeodeChipsets[];
extern PciChipsets GeodePCIchipsets[];
extern OptionInfoRec GeodeOptions[];
static Bool GX2PreInit(ScrnInfoPtr, int);
static Bool GX2ScreenInit(int, ScreenPtr, int, char **);
static Bool GX2EnterVT(int, int);
static void GX2LeaveVT(int, int);
static void GX2FreeScreen(int, int);
void GX2AdjustFrame(int, int, int, int);
Bool GX2SwitchMode(int, DisplayModePtr, int);
static ModeStatus GX2ValidMode(int, DisplayModePtr, Bool, int);
static void GX2LoadPalette(ScrnInfoPtr pScreenInfo,
int numColors, int *indizes,
LOCO * colors, VisualPtr pVisual);
static Bool GX2MapMem(ScrnInfoPtr);
static Bool GX2UnmapMem(ScrnInfoPtr);
static void gx2_set_DvLineSize(unsigned int pitch);
extern Bool GX2AccelInit(ScreenPtr pScreen);
extern Bool GX2HWCursorInit(ScreenPtr pScreen);
extern void GX2HideCursor(ScrnInfoPtr pScreenInfo);
extern void GX2ShowCursor(ScrnInfoPtr pScreenInfo);
extern void GX2PointerMoved(int index, int x, int y);
extern void GX2RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
extern void GX2RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
extern void GX2RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
extern void GX2RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
extern void GX2RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
extern void GX2InitVideo(ScreenPtr pScreen);
extern Bool GX2DGAInit(ScreenPtr pScreen);
extern void GX2LoadCursorImage(ScrnInfoPtr pScreenInfo, unsigned char *src);
#if !defined(STB_X)
extern unsigned char *XpressROMPtr;
#endif
#define GX1 0x1
#define GX2 0x2
#define GX2_CRT 0x6
#define GX2_TFT 0xA
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 GX2SetupChipsetFPtr(ScrnInfoPtr pScrn);
GeodePtr GX2GetRec(ScrnInfoPtr pScreenInfo);
void get_flatpanel_info(const char *options, int *W, int *H,
int *D, int *C, int *T);
void gx2_clear_screen(int width, int height);
void EnableDACPower(void);
void redcloud_gfx_2_vga_fix(void);
void
GX2SetupChipsetFPtr(ScrnInfoPtr pScrn)
{
GeodeDebug(("GX2SetupChipsetFPtr!\n"));
pScrn->PreInit = GX2PreInit;
pScrn->ScreenInit = GX2ScreenInit;
pScrn->SwitchMode = GX2SwitchMode;
pScrn->AdjustFrame = GX2AdjustFrame;
pScrn->EnterVT = GX2EnterVT;
pScrn->LeaveVT = GX2LeaveVT;
pScrn->FreeScreen = GX2FreeScreen;
pScrn->ValidMode = GX2ValidMode;
}
GeodePtr
GX2GetRec(ScrnInfoPtr pScreenInfo)
{
if (!pScreenInfo->driverPrivate) {
GeodePtr pGeode;
pGeode = pScreenInfo->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1);
#if INT10_SUPPORT
pGeode->vesa = xcalloc(sizeof(VESARec), 1);
#endif
}
return GEODEPTR(pScreenInfo);
}
static void
GX2FreeRec(ScrnInfoPtr pScreenInfo)
{
if (pScreenInfo->driverPrivate == NULL) {
return;
}
xfree(pScreenInfo->driverPrivate);
pScreenInfo->driverPrivate = NULL;
}
static Bool
GX2SaveScreen(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_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 void
GX2ProbeDDC(ScrnInfoPtr pScrn, int index)
{
vbeInfoPtr pVbe;
if (xf86LoadSubModule(pScrn, "vbe")) {
pVbe = VBEInit(NULL, index);
ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
vbeFree(pVbe);
}
}
static Bool
GX2PreInit(ScrnInfoPtr pScreenInfo, int flags)
{
static ClockRange GeodeClockRange =
{ NULL, 25175, 229500, 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;
unsigned int SupportFlags;
const char *s;
char **modes;
#if INT10_SUPPORT
VESAPtr pVesa;
#endif
DCount = 10;
GeodeDebug(("GX2PreInit!\n"));
if (!(pGeode = GX2GetRec(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) {
GX2ProbeDDC(pScreenInfo, pGeode->pEnt->index);
return TRUE;
}
#if INT10_SUPPORT
if (!xf86LoadSubModule(pScreenInfo, "int10"))
return FALSE;
xf86LoaderReqSymLists(nscInt10Symbols, NULL);
#endif
pGeode->FBVGAActive = 0;
#if !defined(STB_X)
if (!xf86LoadSubModule(pScreenInfo, "vgahw")) {
return FALSE;
}
xf86LoaderReqSymLists(nscVgahwSymbols, NULL);
#endif
GeodeDebug(("GX2PreInit(1)!\n"));
#if defined(STB_X)
if (!Gal_initialize_interface()) {
GeodeDebug(("GALintialize fail GX2PreInit(1.00)!\n"));
return FALSE;
}
if (Gal_get_adapter_info(&sAdapterInfo)) {
pGeode->cpu_version = sAdapterInfo.dwCPUVersion;
if ((pGeode->cpu_version & 0xFF) == GFX_CPU_REDCLOUD) {
if (sAdapterInfo.dwCPUType)
pGeode->DetectedChipSet = GX2_TFT;
else
pGeode->DetectedChipSet = GX2_CRT;
}
DEBUGMSG(1,
(0, X_NONE, "Detected BaseChip %d, %d\n",
pGeode->DetectedChipSet, sAdapterInfo.dwCPUType));
pGeode->vid_version = sAdapterInfo.dwVideoVersion;
pGeode->FBSize = sAdapterInfo.dwFrameBufferSize;
GeodeClockRange.maxClock = sAdapterInfo.dwMaxSupportedPixelClock;
pGeode->FBLinearAddr = sAdapterInfo.dwFrameBufferBase;
#if 0
pGeode->FBBase = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex,
VIDMEM_FRAMEBUFFER,
pGeode->FBLinearAddr,
pGeode->FBSize);
#endif
if (!GX2MapMem(pScreenInfo))
return FALSE;
DEBUGMSG(1, (0, X_NONE, "CPU=%x vid %x FB %x FBAdd %X\n",
pGeode->cpu_version, pGeode->vid_version, pGeode->FBSize,
pGeode->FBLinearAddr));
} else {
return FALSE;
}
#else
pGeode->cpu_version = gfx_detect_cpu();
if ((pGeode->cpu_version & 0xFF) == GFX_CPU_REDCLOUD)
pGeode->DetectedChipSet = GX2;
GeodeDebug(("Detected BaseChip (%d)\n", pGeode->DetectedChipSet));
{
Q_WORD msrValue;
gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msrValue);
pGeode->DetectedChipSet =
((msrValue.low & RCDF_CONFIG_FMT_MASK) ==
RCDF_CONFIG_FMT_FP) ? GX2_TFT : GX2_CRT;
GeodeDebug(("Gx2 for %s\n",
((pGeode->DetectedChipSet == GX2_TFT) ? "TFT" : "CRT")));
}
GeodeDebug(("GX2PreInit(1.1)!\n"));
pGeode->vid_version = gfx_detect_video();
GeodeDebug(("GX2PreInit(1.2)!\n"));
pGeode->FBLinearAddr = gfx_get_frame_buffer_base();
GeodeDebug(("GX2PreInit(1.3)!\n"));
pGeode->FBSize = gfx_get_frame_buffer_size();
GeodeDebug(("GX2PreInit(1.4)!\n"));
GeodeClockRange.maxClock = gfx_get_max_supported_pixel_clock();
GeodeDebug(("GX2PreInit(1.5)!\n"));
if (pGeode->DetectedChipSet & GX2) {
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;
}
if (!GX2MapMem(pScreenInfo))
return FALSE;
pGeode->FBVGAActive = gu2_get_vga_active();
#endif
DEBUGMSG(1, (0, X_PROBED, "VGA = %d\n", pGeode->FBVGAActive));
pScreenInfo->monitor = pScreenInfo->confScreen->monitor;
GeodeDebug(("GX2PreInit(2)!\n"));
SupportFlags = Support24bppFb | Support32bppFb;
GeodeDebug(("GX2PreInit(2)!\n"));
if (!xf86SetDepthBpp(pScreenInfo, 0, 0, 0, SupportFlags)) {
return FALSE;
} else {
if (!((pScreenInfo->depth == 8) ||
(pScreenInfo->depth == 16) ||
(pScreenInfo->depth == 24))) {
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 BitsPerComponent = { 0, 0, 0 };
rgb BitMask = { 0, 0, 0 };
if (pScreenInfo->depth > 16) {
BitsPerComponent.red = 8;
BitsPerComponent.green = 8;
BitsPerComponent.blue = 8;
BitMask.red = 0xFF0000;
BitMask.green = 0x00FF00;
BitMask.blue = 0x0000FF;
}
if (!xf86SetWeight(pScreenInfo, BitsPerComponent, BitMask)) {
return FALSE;
} else {
}
}
xf86PrintDepthBpp(pScreenInfo);
GeodeDebug(("GX2PreInit(3)!\n"));
if (!xf86SetDefaultVisual(pScreenInfo, -1))
return FALSE;
GeodeDebug(("GX2PreInit(4)!\n"));
if (pScreenInfo->depth > 1) {
Gamma zeros = { 0.0, 0.0, 0.0 };
if (!xf86SetGamma(pScreenInfo, zeros)) {
return FALSE;
}
}
GeodeDebug(("GX2PreInit(5)!\n"));
pScreenInfo->progClock = TRUE;
xf86CollectOptions(pScreenInfo, NULL);
xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
GeodeOptions);
#if INT10_SUPPORT
pVesa = pGeode->vesa;
if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) {
xf86DrvMsg(0, X_ERROR, "Int10 initialization failed.\n");
return (FALSE);
}
#endif
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,
"NoOfImgBuffers = %d\n", pGeode->NoOfImgBuffers));
pGeode->Panel = FALSE;
if (xf86ReturnOptValBool(GeodeOptions, OPTION_FLATPANEL, FALSE)) {
DEBUGMSG(0, (pScreenInfo->scrnIndex, X_CONFIG, "FlatPanel Selected\n"));
pGeode->Panel = TRUE;
}
if (pGeode->DetectedChipSet == GX2_TFT) {
pGeode->Panel = TRUE;
}
if ((pGeode->DetectedChipSet == GX2_CRT) && (pGeode->Panel))
pGeode->Panel = FALSE;
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG,
"Quering FP Bios %d\n", pGeode->Panel));
if (pGeode->Panel) {
#if defined(STB_X)
Gal_pnl_enabled_in_bios(&pGeode->Panel);
Gal_pnl_info_from_bios(&pGeode->FPBX, &pGeode->FPBY,
&pGeode->FPBB, &pGeode->FPBF);
#else
pGeode->Panel = Pnl_IsPanelEnabledInBIOS();
Pnl_GetPanelInfoFromBIOS(&pGeode->FPBX, &pGeode->FPBY,
&pGeode->FPBB, &pGeode->FPBF);
#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 (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(("GX2PreInit(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(("GX2PreInit(7)!\n"));
minPitch = 1024;
maxPitch = 4096;
minHeight = 480;
maxHeight = 1200;
if (pScreenInfo->depth > 16) {
PitchInc = 4096;
} else if (pScreenInfo->depth == 16) {
PitchInc = 2048;
} else {
PitchInc = 1024;
}
PitchInc <<= 3;
modes = pScreenInfo->display->modes;
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
gfx_get_frame_buffer_size(),
#endif
LOOKUP_BEST_REFRESH);
DEBUGMSG(1, (pScreenInfo->scrnIndex, from,
"xf86ValidateModes: %d %d %d\n",
pScreenInfo->virtualX,
pScreenInfo->virtualY, pScreenInfo->displayWidth));
if (i == -1) {
GX2FreeRec(pScreenInfo);
return FALSE;
}
GeodeDebug(("GX2PreInit(8)!\n"));
xf86PruneDriverModes(pScreenInfo);
GeodeDebug(("GX2PreInit(9)!\n"));
if (i == 0 || pScreenInfo->modes == NULL) {
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_ERROR,
"No valid modes found\n"));
GX2FreeRec(pScreenInfo);
return FALSE;
}
GeodeDebug(("GX2PreInit(10)!\n"));
xf86SetCrtcForModes(pScreenInfo, 0);
GeodeDebug(("GX2PreInit(11)!\n"));
pScreenInfo->currentMode = pScreenInfo->modes;
GeodeDebug(("GX2PreInit(12)!\n"));
xf86PrintModes(pScreenInfo);
GeodeDebug(("GX2PreInit(13)!\n"));
xf86SetDpi(pScreenInfo, 0, 0);
GeodeDebug(("GX2PreInit(14)!\n"));
#if CFB
mod = NULL;
switch (pScreenInfo->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(pScreenInfo, mod) == NULL) {
GX2FreeRec(pScreenInfo);
return FALSE;
}
xf86LoaderReqSymbols(reqSymbol, NULL);
#else
if (xf86LoadSubModule(pScreenInfo, "fb") == NULL) {
GX2FreeRec(pScreenInfo);
return FALSE;
}
xf86LoaderReqSymLists(nscFbSymbols, NULL);
#endif
GeodeDebug(("GX2PreInit(15)!\n"));
if (pGeode->NoAccel == FALSE) {
if (!xf86LoadSubModule(pScreenInfo, "xaa")) {
GX2FreeRec(pScreenInfo);
return FALSE;
}
xf86LoaderReqSymLists(nscXaaSymbols, NULL);
}
GeodeDebug(("GX2PreInit(16)!\n"));
if (pGeode->HWCursor == TRUE) {
if (!xf86LoadSubModule(pScreenInfo, "ramdac")) {
GX2FreeRec(pScreenInfo);
return FALSE;
}
xf86LoaderReqSymLists(nscRamdacSymbols, NULL);
}
GeodeDebug(("GX2PreInit(17)!\n"));
if (pGeode->ShadowFB) {
if (!xf86LoadSubModule(pScreenInfo, "shadowfb")) {
GX2FreeRec(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"));
GX2FreeRec(pScreenInfo);
return FALSE;
}
GX2UnmapMem(pScreenInfo);
GeodeDebug(("GX2PreInit ... done successfully!\n"));
(void) from;
return TRUE;
}
static void
GX2Restore(ScrnInfoPtr pScreenInfo)
{
GeodePtr pGeode;
GeodeDebug(("GX2Restore!\n"));
if (!(pGeode = GX2GetRec(pScreenInfo)))
return;
if (pGeode->FBVGAActive) {
vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
vgaHWProtect(pScreenInfo, TRUE);
vgaHWRestore(pScreenInfo, &pvgaHW->SavedReg, VGA_SR_ALL);
vgaHWProtect(pScreenInfo, FALSE);
}
}
static int
GX2CalculatePitchBytes(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 > 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;
}
static int
GX2GetRefreshRate(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
gx2_clear_screen(int width, int height)
{
GFX(set_solid_pattern(0));
GFX(set_raster_operation(0xF0));
GFX(pattern_fill(0, 0, width, height));
}
void
gx2_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;
}
#if defined(STB_X)
Gal_read_register(GAL_REG, MDC_DV_CTL, &temp, 4);
temp = (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size;
Gal_write_register(GAL_REG, MDC_DV_CTL, temp, 4);
#else
temp = READ_REG32(MDC_DV_CTL);
WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size);
#endif
}
static Bool
GX2SetMode(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode)
{
GeodePtr pGeode = GEODEPTR(pScreenInfo);
DCount = 50;
GeodeDebug(("GX2SetMode!\n"));
#if !defined(STB_X)
DEBUGMSG(1, (0, X_NONE, "Set mode %X %X %X %X %X\n",
gfx_virt_regptr,
gfx_virt_gpptr,
gfx_virt_spptr, gfx_virt_vidptr, gfx_virt_fbptr));
#endif
pScreenInfo->vtSema = TRUE;
DEBUGMSG(1, (0, X_NONE, "Set mode"));
GeodeDebug(("Set display mode: %dx%d-%d (%dHz) Pitch %d\n",
pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel,
GX2GetRefreshRate(pMode), pGeode->Pitch));
GeodeDebug(("Before setting the mode\n"));
if (1) {
{
DEBUGMSG(1, (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));
DEBUGMSG(1, (pScreenInfo->scrnIndex, X_CONFIG, "FP Bios %d\n",
pGeode->Panel));
GFX(set_fixed_timings(pGeode->FPBX, pGeode->FPBY,
pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel));
} else {
DEBUGMSG(1, (0, X_PROBED, "Setting Display for CRT %dx%d-%d@%d\n",
pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel,
GX2GetRefreshRate(pMode)));
GFX(set_display_mode(pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel,
GX2GetRefreshRate(pMode)));
GFX(set_display_pitch(pGeode->Pitch));
}
GFX(set_bpp(pScreenInfo->bitsPerPixel));
GFX(set_crt_enable(CRT_ENABLE));
}
GFX(set_display_offset(0L));
GFX(wait_vertical_blank());
DEBUGMSG(1, (0, X_PROBED, "Display mode set\n"));
if (pGeode->Compression) {
DEBUGMSG(1, (0, X_PROBED, "Compression mode set %d\n",
pGeode->Compression));
gx2_set_DvLineSize(pGeode->Pitch);
#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) {
GX2LoadCursorImage(pScreenInfo, NULL);
GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0));
GFX(set_cursor_enable(1));
}
} else {
GeodeDebug(("GX2Restore ... "));
GX2Restore(pScreenInfo);
GeodeDebug(("done.\n"));
}
GeodeDebug(("done.\n"));
if (pGeode->HWCursor == TRUE) {
GeodeDebug(("GX2ShowCursor ... "));
GX2ShowCursor(pScreenInfo);
GeodeDebug(("done.\n"));
}
GeodeDebug(("After setting the mode\n"));
return TRUE;
}
static Bool
GX2EnterGraphics(ScreenPtr pScreen, ScrnInfoPtr pScreenInfo)
{
GeodePtr pGeode = GX2GetRec(pScreenInfo);
#if defined(STB_X)
Gal_get_display_timing(&pGeode->FBgfxdisplaytiming);
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();
#else
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();
if (pGeode->FBVGAActive) {
unsigned short sequencer;
vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
if (!vgaHWMapMem(pScreenInfo))
return FALSE;
vgaHWUnlock(pvgaHW);
vgaHWSave(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL);
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);
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);
}
#endif
if (!GX2SetMode(pScreenInfo, pScreenInfo->currentMode)) {
return FALSE;
}
gx2_clear_screen(pScreenInfo->currentMode->CrtcHDisplay,
pScreenInfo->currentMode->CrtcVDisplay);
return TRUE;
}
#if !defined(STB_X)
void
EnableDACPower(void)
{
gfx_write_vid32(RCDF_VID_MISC,
gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH);
}
void
redcloud_gfx_2_vga_fix(void)
{
EnableDACPower();
#if 0
int i;
gfx_outb(0x3C4, 0x1);
gfx_outb(0x3C5, 0x2);
gfx_inb(0x3DA);
gfx_outb(0x3C0, 0x30);
gfx_outb(0x3C0, 0xC);
for (i = 0; i < 16; i++) {
gfx_inb(0x3DA);
gfx_outb(0x3C0, i);
gfx_outb(0x3C0, i);
}
gfx_inb(0x3DA);
gfx_outb(0x3C0, 0x11);
gfx_outb(0x3C0, 0x0);
gfx_inb(0x3DA);
gfx_outb(0x3C0, 0x12);
gfx_outb(0x3C0, 0xF);
gfx_inb(0x3DA);
gfx_outb(0x3C0, 0x33);
gfx_outb(0x3C0, 0x8);
gfx_outb(0x3C0, 0x20);
gfx_outb(0x3C0, 0x20);
#endif
}
#endif
static void
GX2LeaveGraphics(ScrnInfoPtr pScreenInfo)
{
GeodePtr pGeode = GX2GetRec(pScreenInfo);
#if defined(STB_X)
Gal_set_display_timing(&pGeode->FBgfxdisplaytiming);
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
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);
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);
gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0);
GeodeDebug(("FBVGAActive %d\n", pGeode->FBVGAActive));
if (pGeode->FBVGAActive) {
pGeode->vesa->pInt->num = 0x10;
pGeode->vesa->pInt->ax = 0x3;
pGeode->vesa->pInt->bx = 0;
xf86ExecX86int10(pGeode->vesa->pInt);
gfx_delay_milliseconds(3);
EnableDACPower();
}
#endif
}
static Bool
GX2CloseScreen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
GeodePtr pGeode = GEODEPTR(pScreenInfo);
if (pGeode->ShadowPtr)
xfree(pGeode->ShadowPtr);
DEBUGMSG(0, (scrnIndex, X_PROBED, "GX2CloseScreen %d\n",
pScreenInfo->vtSema));
if (pScreenInfo->vtSema)
GX2LeaveGraphics(pScreenInfo);
if (pGeode->AccelInfoRec)
XAADestroyInfoRec(pGeode->AccelInfoRec);
if (pGeode->AccelImageWriteBufferOffsets) {
xfree(pGeode->AccelImageWriteBufferOffsets);
pGeode->AccelImageWriteBufferOffsets = 0x0;
}
xf86FreeOffscreenArea(pGeode->AccelImgArea);
xf86FreeOffscreenArea(pGeode->CompressionArea);
pScreenInfo->vtSema = FALSE;
GX2UnmapMem(pScreenInfo);
if (pGeode && (pScreen->CloseScreen = pGeode->CloseScreen)) {
pGeode->CloseScreen = NULL;
return ((*pScreen->CloseScreen) (scrnIndex, pScreen));
}
return TRUE;
}
static void
GX2DPMSSet(ScrnInfoPtr pScreenInfo, int mode, int flags)
{
GeodePtr pGeode;
pGeode = GEODEPTR(pScreenInfo);
GeodeDebug(("GX2DPMSSet!\n"));
if (!pScreenInfo->vtSema) {
ErrorF("GX2DPMSSet 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
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
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
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
break;
}
}
static Bool
GX2ScreenInit(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(("GX2ScreenInit!\n"));
pGeode = GX2GetRec(pScreenInfo);
GeodeDebug(("GX2ScreenInit(0)!\n"));
GeodeDebug(("FBVGAActive %d\n", pGeode->FBVGAActive));
if (pGeode->FBVGAActive) {
if (!vgaHWGetHWRec(pScreenInfo))
return FALSE;
if (!vgaHWMapMem(pScreenInfo))
return FALSE;
vgaHWGetIOBase(VGAHWPTR(pScreenInfo));
}
if (!GX2MapMem(pScreenInfo))
return FALSE;
pGeode->Pitch = GX2CalculatePitchBytes(pScreenInfo->virtualX,
pScreenInfo->bitsPerPixel);
AvailBox.x1 = 0;
AvailBox.y1 = pScreenInfo->virtualY;
AvailBox.x2 = pScreenInfo->displayWidth;
AvailBox.y2 = (pGeode->FBSize / pGeode->Pitch);
pGeode->CursorSize = 16 * 64;
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 %d\n",
AvailBox.x1, AvailBox.y1, AvailBox.x2, AvailBox.y2,
pGeode->Pitch, pScreenInfo->displayWidth,
pScreenInfo->bitsPerPixel));
if (pGeode->Compression) {
pGeode->CBPitch = 544;
pGeode->CBSize = 544;
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 (!GX2EnterGraphics(pScreen, pScreenInfo))
return FALSE;
GX2AdjustFrame(scrnIndex, pScreenInfo->frameX0, pScreenInfo->frameY0, 0);
GeodeDebug(("GX2ScreenInit(1)!\n"));
miClearVisualTypes();
GeodeDebug(("GX2ScreenInit(2)!\n"));
if (pScreenInfo->bitsPerPixel > 8) {
DEBUGMSG(1, (scrnIndex, X_PROBED,
"miSetVisualTypes %d %X %X %X\n",
pScreenInfo->depth,
TrueColorMask,
pScreenInfo->rgbBits, pScreenInfo->defaultVisual));
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(("GX2ScreenInit(3)!\n"));
miSetPixmapDepths();
width = pScreenInfo->virtualX;
height = pScreenInfo->virtualY;
displayWidth = pScreenInfo->displayWidth;
if (pGeode->Rotate) {
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;
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;
case 24:
case 32:
Inited = cfb32ScreenInit(pScreen, FBStart, width, height,
pScreenInfo->xDpi, pScreenInfo->yDpi,
displayWidth);
break;
#else
case 8:
case 16:
case 24:
case 32:
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(("GX2ScreenInit(4)!\n"));
xf86SetBlackWhitePixels(pScreen);
if (!pGeode->ShadowFB) {
GX2DGAInit(pScreen);
}
GeodeDebug(("GX2ScreenInit(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(("GX2ScreenInit(6)!\n"));
if (!pGeode->NoAccel) {
GX2AccelInit(pScreen);
}
GeodeDebug(("GX2ScreenInit(7)!\n"));
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
GeodeDebug(("GX2ScreenInit(8)!\n"));
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
if (pGeode->HWCursor) {
if (!GX2HWCursorInit(pScreen))
xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
"Hardware cursor initialization failed\n");
}
GeodeDebug(("GX2ScreenInit(9)!\n"));
if (!miCreateDefColormap(pScreen)) {
return FALSE;
}
GeodeDebug(("GX2ScreenInit(10)!\n"));
if (!xf86HandleColormaps(pScreen, 256, 8,
GX2LoadPalette, NULL,
CMAP_PALETTED_TRUECOLOR |
CMAP_RELOAD_ON_MODE_SWITCH)) {
return FALSE;
}
GeodeDebug(("GX2ScreenInit(11)!\n"));
if (pGeode->ShadowFB) {
RefreshAreaFuncPtr refreshArea = GX2RefreshArea;
if (pGeode->Rotate) {
if (!pGeode->PointerMoved) {
pGeode->PointerMoved = pScreenInfo->PointerMoved;
pScreenInfo->PointerMoved = GX2PointerMoved;
}
switch (pScreenInfo->bitsPerPixel) {
case 8:
refreshArea = GX2RefreshArea8;
break;
case 16:
refreshArea = GX2RefreshArea16;
break;
case 24:
refreshArea = GX2RefreshArea24;
break;
case 32:
refreshArea = GX2RefreshArea32;
break;
}
}
ShadowFBInit(pScreen, refreshArea);
}
xf86DPMSInit(pScreen, GX2DPMSSet, 0);
GeodeDebug(("GX2ScreenInit(12)!\n"));
pScreenInfo->memPhysBase = (unsigned long)pGeode->FBBase;
pScreenInfo->fbOffset = 0;
GeodeDebug(("GX2ScreenInit(13)!\n"));
GX2InitVideo(pScreen);
pGeode->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = GX2CloseScreen;
pScreen->SaveScreen = GX2SaveScreen;
GeodeDebug(("GX2ScreenInit(14)!\n"));
if (serverGeneration == 1) {
xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options);
}
GeodeDebug(("GX2ScreenInit(15)!\n"));
return TRUE;
}
Bool
GX2SwitchMode(int scrnIndex, DisplayModePtr pMode, int flags)
{
GeodeDebug(("GX2SwitchMode!\n"));
return GX2SetMode(xf86Screens[scrnIndex], pMode);
}
void
GX2AdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
GeodePtr pGeode = GX2GetRec(pScreenInfo);
unsigned long offset;
offset = (unsigned long)y *(unsigned long)pGeode->Pitch;
offset += x * (pScreenInfo->bitsPerPixel >> 3);
GFX(set_display_offset(offset));
}
static Bool
GX2EnterVT(int scrnIndex, int flags)
{
GeodeDebug(("GX2EnterVT!\n"));
return GX2EnterGraphics(NULL, xf86Screens[scrnIndex]);
}
static void
GX2LeaveVT(int scrnIndex, int flags)
{
GeodeDebug(("GX2LeaveVT!\n"));
GX2LeaveGraphics(xf86Screens[scrnIndex]);
}
static void
GX2FreeScreen(int scrnIndex, int flags)
{
GeodeDebug(("GX2FreeScreen!\n"));
if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
vgaHWFreeHWRec(xf86Screens[scrnIndex]);
GX2FreeRec(xf86Screens[scrnIndex]);
}
static ModeStatus
GX2ValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags)
{
unsigned int total_memory_required;
ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
int ret = -1;
GeodePtr pGeode = GX2GetRec(pScreenInfo);
DEBUGMSG(1, (0, X_NONE, "GeodeValidateMode: %dx%d %d %d\n",
pMode->CrtcHDisplay, pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel, GX2GetRefreshRate(pMode)));
{
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,
GX2GetRefreshRate(pMode), &ret);
#else
ret = gfx_is_display_mode_supported(pMode->CrtcHDisplay,
pMode->CrtcVDisplay,
pScreenInfo->bitsPerPixel,
GX2GetRefreshRate(pMode));
#endif
}
if (ret < 0)
return MODE_NOMODE;
total_memory_required = GX2CalculatePitchBytes(pMode->CrtcHDisplay,
pScreenInfo->bitsPerPixel) *
pMode->CrtcVDisplay;
DEBUGMSG(1, (0, X_NONE, "Total Mem %X %X\n",
total_memory_required, pGeode->FBSize));
if (total_memory_required > pGeode->FBSize)
return MODE_MEM;
return MODE_OK;
}
static void
GX2LoadPalette(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, "GX2LoadPalette: %d %d %X\n",
numColors, index, color));
GFX(set_display_palette_entry(index, color));
}
}
static Bool
GX2MapMem(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
(), pGeode->cpu_reg_size);
if (pGeode->DetectedChipSet & GX2) {
gfx_virt_gpptr = (unsigned char *)xf86MapVidMem(pScreenInfo->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(pScreenInfo->scrnIndex,
VIDMEM_MMIO,
(unsigned int)
gfx_get_vid_register_base
(), pGeode->vid_reg_size);
gfx_virt_fbptr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex,
VIDMEM_FRAMEBUFFER,
pGeode->FBLinearAddr,
pGeode->FBSize);
pGeode->FBBase = gfx_virt_fbptr;
DEBUGMSG(1, (0, X_NONE, "Set mode %X %X %X %X %X\n",
gfx_virt_regptr,
gfx_virt_gpptr,
gfx_virt_spptr, gfx_virt_vidptr, gfx_virt_fbptr));
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);
}
XpressROMPtr = (unsigned char *)xf86MapVidMem(pScreenInfo->scrnIndex,
VIDMEM_FRAMEBUFFER, 0xF0000,
0x10000);
DEBUGMSG(1, (0, X_NONE, "adapter info %x %x %x %x, %X\n",
pGeode->cpu_version,
pGeode->vid_version,
pGeode->FBSize, pGeode->FBBase, XpressROMPtr));
#endif
return TRUE;
}
static Bool
GX2UnmapMem(ScrnInfoPtr pScreenInfo)
{
#if !defined(STB_X)
GeodePtr pGeode = GEODEPTR(pScreenInfo);
xf86UnMapVidMem(pScreenInfo->scrnIndex,
gfx_virt_regptr, pGeode->cpu_reg_size);
if (pGeode->DetectedChipSet & GX2) {
xf86UnMapVidMem(pScreenInfo->scrnIndex,
gfx_virt_gpptr, pGeode->gp_reg_size);
}
xf86UnMapVidMem(pScreenInfo->scrnIndex,
gfx_virt_vidptr, pGeode->vid_reg_size);
xf86UnMapVidMem(pScreenInfo->scrnIndex, gfx_virt_fbptr, pGeode->FBSize);
xf86UnMapVidMem(pScreenInfo->scrnIndex, XpressROMPtr, 0x10000);
#endif
return TRUE;
}