diff options
Diffstat (limited to 'xorg-server/hw/kdrive/neomagic/neomagic.c')
-rw-r--r-- | xorg-server/hw/kdrive/neomagic/neomagic.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/neomagic/neomagic.c b/xorg-server/hw/kdrive/neomagic/neomagic.c new file mode 100644 index 000000000..ac0c7569a --- /dev/null +++ b/xorg-server/hw/kdrive/neomagic/neomagic.c @@ -0,0 +1,335 @@ +/* + * + * Copyright © 2004 Franco Catrin + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Franco Catrin not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Franco Catrin makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * FRANCO CATRIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL FRANCO CATRIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#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; // no hardware color cursor available + + 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); // disable MMIO and linear mode + 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); // enable MMIO and linear mode +} + + +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 */ +//#define neoDrawInit 0 // initAccel +//#define neoDrawEnable 0 // enableAccel +//#define neoDrawSync 0 // syncAccel +//#define neoDrawDisable 0 // disableAccel +//#define neoDrawFini 0 // finiAccel + +KdCardFuncs neoFuncs = { + neoCardInit, // cardinit + neoScreenInit, // scrinit + neoInitScreen, // initScreen + neoFinishInitScreen, // finishInitScreen + neoCreateResources, // createRes + neoPreserve, // preserve + neoEnable, // enable + neoDPMS, // dpms + neoDisable, // disable + neoRestore, // restore + neoScreenFini, // scrfini + neoCardFini, // cardfini + + neoCursorInit, // initCursor + neoCursorEnable, // enableCursor + neoCursorDisable, // disableCursor + neoCursorFini, // finiCursor + neoRecolorCursor, // recolorCursor + + neoDrawInit, // initAccel + neoDrawEnable, // enableAccel + neoDrawDisable, // disableAccel + neoDrawFini, // finiAccel + + neoGetColors, // getColors + neoPutColors, // putColors +}; |