#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include "neomagic.h"
#include <sys/io.h>
struct NeoChipInfo neoChips[] = {
{NEO_VENDOR, 0x0001, CAP_NM2070, "MagicGraph 128(NM2070)",
896, 65000, 2048, 0x100, 1024, 1024, 1024},
{NEO_VENDOR, 0x0002, CAP_NM2090, "MagicGraph 128V(NM2090)",
1152, 80000, 2048, 0x100, 2048, 1024, 1024},
{NEO_VENDOR, 0x0003, CAP_NM2090, "MagicGraph 128ZV(NM2093)",
1152, 80000, 2048, 0x100, 2048, 1024, 1024},
{NEO_VENDOR, 0x0083, CAP_NM2097, "MagicGraph 128ZV+(NM2097)",
1152, 80000, 1024, 0x100, 2048, 1024, 1024},
{NEO_VENDOR, 0x0004, CAP_NM2097, "MagicGraph 128XD(NM2160)",
2048, 90000, 1024, 0x100, 2048, 1024, 1024},
{NEO_VENDOR, 0x0005, CAP_NM2200, "MagicGraph 256AV(NM2200)",
2560, 110000, 1024, 0x1000, 4096, 1280, 1024},
{NEO_VENDOR, 0x0025, CAP_NM2200, "MagicGraph 256AV+(NM2230)",
3008, 110000, 1024, 0x1000, 4096, 1280, 1024},
{NEO_VENDOR, 0x0006, CAP_NM2200, "MagicGraph 256ZX(NM2360)",
4096, 110000, 1024, 0x1000, 4096, 1280, 1024},
{NEO_VENDOR, 0x0016, CAP_NM2200, "MagicGraph 256XL+(NM2380)",
6144, 110000, 1024, 0x1000, 8192, 1280, 1024},
{0, 0, 0, NULL},
};
static Bool
neoCardInit(KdCardInfo *card)
{
NeoCardInfo *neoc;
struct NeoChipInfo *chip;
neoc =(NeoCardInfo *) xalloc(sizeof(NeoCardInfo));
if(!neoc) {
return FALSE;
}
if(!vesaInitialize(card, &neoc->backendCard)) {
xfree(neoc);
return FALSE;
}
for(chip = neoChips; chip->name != NULL; ++chip) {
if(chip->device == card->attr.deviceID) {
neoc->chip = chip;
break;
}
}
ErrorF("Using Neomagic card: %s\n", neoc->chip->name);
neoMapReg(card, neoc);
card->driver = neoc;
return TRUE;
}
static Bool
neoScreenInit(KdScreenInfo *screen)
{
NeoScreenInfo *neos;
int screen_size, memory;
neos = xcalloc(sizeof(NeoScreenInfo), 1);
if(neos == NULL) {
return FALSE;
}
memset (neos, '\0', sizeof (NeoScreenInfo));
if(!vesaScreenInitialize(screen, &neos->backendScreen)) {
xfree(neos);
return FALSE;
}
screen->softCursor = TRUE;
neos->screen = neos->backendScreen.fb;
memory = neos->backendScreen.fb_size;
screen_size = screen->fb[0].byteStride * screen->height;
memory -= screen_size;
if(memory > screen->fb[0].byteStride) {
neos->off_screen = neos->screen + screen_size;
neos->off_screen_size = memory;
} else {
neos->off_screen = 0;
neos->off_screen_size = 0;
}
screen->driver = neos;
return TRUE;
}
static Bool
neoInitScreen(ScreenPtr pScreen)
{
return vesaInitScreen(pScreen);
}
static Bool
neoFinishInitScreen(ScreenPtr pScreen)
{
return vesaFinishInitScreen(pScreen);
}
static Bool
neoCreateResources(ScreenPtr pScreen)
{
return vesaCreateResources(pScreen);
}
void
neoPreserve(KdCardInfo *card)
{
vesaPreserve(card);
}
CARD8
neoGetIndex(NeoCardInfo *nvidiac, CARD16 addr, CARD8 index)
{
outb(index, addr);
return inb(addr+1);
}
void
neoSetIndex(NeoCardInfo *nvidiac, CARD16 addr, CARD8 index, CARD8 val)
{
outb(index, addr);
outb(val, addr+1);
}
static void neoLock(NeoCardInfo *neoc){
CARD8 cr11;
neoSetIndex(neoc, 0x3ce, 0x09, 0x00);
neoSetIndex(neoc, 0x3ce, 0x11, 0x0); cr11 = neoGetIndex(neoc, 0x3d4, 0x11);
neoSetIndex(neoc, 0x3d4, 0x11, cr11 | 0x80);
}
static void neoUnlock(NeoCardInfo *neoc){
CARD8 cr11;
cr11 = neoGetIndex(neoc, 0x3d4, 0x11);
neoSetIndex(neoc, 0x3d4, 0x11, cr11 & 0x7F);
neoSetIndex(neoc, 0x3ce, 0x09, 0x26);
neoSetIndex(neoc, 0x3ce, 0x11, 0xc0); }
Bool
neoMapReg(KdCardInfo *card, NeoCardInfo *neoc)
{
neoc->reg_base = card->attr.address[1] & 0xFFF80000;
if(!neoc->reg_base) {
return FALSE;
}
neoc->mmio = KdMapDevice(neoc->reg_base, NEO_REG_SIZE(card));
if(!neoc->mmio) {
return FALSE;
}
KdSetMappedMode(neoc->reg_base, NEO_REG_SIZE(card), KD_MAPPED_MODE_REGISTERS);
return TRUE;
}
void
neoUnmapReg(KdCardInfo *card, NeoCardInfo *neoc)
{
if(neoc->reg_base)
{
neoSetIndex(neoc, 0x3ce, 0x82,0);
KdResetMappedMode(neoc->reg_base, NEO_REG_SIZE(card), KD_MAPPED_MODE_REGISTERS);
KdUnmapDevice((void *)neoc->mmio, NEO_REG_SIZE(card));
neoc->reg_base = 0;
}
}
static void
neoSetMMIO(KdCardInfo *card, NeoCardInfo *neoc)
{
if(!neoc->reg_base)
neoMapReg(card, neoc);
neoUnlock(neoc);
}
static void
neoResetMMIO(KdCardInfo *card, NeoCardInfo *neoc)
{
neoUnmapReg(card, neoc);
neoLock(neoc);
}
Bool
neoEnable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
neoCardInfo(pScreenPriv);
if(!vesaEnable(pScreen)) {
return FALSE;
}
neoSetMMIO(pScreenPriv->card, neoc);
return TRUE;
}
void
neoDisable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
neoCardInfo(pScreenPriv);
neoResetMMIO(pScreenPriv->card, neoc);
vesaDisable(pScreen);
}
static void
neoGetColors(ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
vesaGetColors(pScreen, fb, n, pdefs);
}
static void
neoPutColors(ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
vesaPutColors(pScreen, fb, n, pdefs);
}
static Bool
neoDPMS(ScreenPtr pScreen, int mode)
{
return vesaDPMS(pScreen, mode);
}
static void
neoRestore(KdCardInfo *card)
{
NeoCardInfo *neoc = card->driver;
neoResetMMIO(card, neoc);
vesaRestore(card);
}
static void
neoScreenFini(KdScreenInfo *screen)
{
NeoScreenInfo *neos =(NeoScreenInfo *) screen->driver;
vesaScreenFini(screen);
xfree(neos);
screen->driver = 0;
}
static void
neoCardFini(KdCardInfo *card)
{
NeoCardInfo *neoc = card->driver;
neoUnmapReg(card, neoc);
vesaCardFini(card);
}
#define neoCursorInit 0 // initCursor
#define neoCursorEnable 0 // enableCursor
#define neoCursorDisable 0 // disableCursor
#define neoCursorFini 0 // finiCursor */
#define neoRecolorCursor 0 // recolorCursor */
KdCardFuncs neoFuncs = {
neoCardInit, neoScreenInit, neoInitScreen, neoFinishInitScreen, neoCreateResources, neoPreserve, neoEnable, neoDPMS, neoDisable, neoRestore, neoScreenFini, neoCardFini,
neoCursorInit, neoCursorEnable, neoCursorDisable, neoCursorFini, neoRecolorCursor,
neoDrawInit, neoDrawEnable, neoDrawDisable, neoDrawFini,
neoGetColors, neoPutColors, };