diff options
Diffstat (limited to 'xorg-server/hw/kdrive/nvidia/nvidia.c')
-rw-r--r-- | xorg-server/hw/kdrive/nvidia/nvidia.c | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/nvidia/nvidia.c b/xorg-server/hw/kdrive/nvidia/nvidia.c new file mode 100644 index 000000000..be42e561a --- /dev/null +++ b/xorg-server/hw/kdrive/nvidia/nvidia.c @@ -0,0 +1,361 @@ +/* + * Copyright © 2003 Keith Packard + * + * 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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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 "nvidia.h" +#include "kaa.h" +#include <sys/io.h> + +static Bool +nvidiaCardInit (KdCardInfo *card) +{ + NvidiaCardInfo *nvidiac; + + nvidiac = (NvidiaCardInfo *) xalloc (sizeof (NvidiaCardInfo)); + if (!nvidiac) + return FALSE; + + (void) nvidiaMapReg (card, nvidiac); + + if (!vesaInitialize (card, &nvidiac->vesa)) + { + xfree (nvidiac); + return FALSE; + } + + card->driver = nvidiac; + + return TRUE; +} + +static Bool +nvidiaScreenInit (KdScreenInfo *screen) +{ + NvidiaCardInfo *nvidiac = screen->card->driver; + NvidiaScreenInfo *nvidias; + int screen_size, memory; + + nvidias = (NvidiaScreenInfo *) xalloc (sizeof (NvidiaScreenInfo)); + if (!nvidias) + return FALSE; + memset (nvidias, '\0', sizeof (NvidiaScreenInfo)); + if (!vesaScreenInitialize (screen, &nvidias->vesa)) + { + xfree (nvidias); + return FALSE; + } + if (!nvidiac->reg_base) + screen->dumb = TRUE; + if (nvidias->vesa.mapping != VESA_LINEAR) + screen->dumb = TRUE; + nvidias->screen = nvidias->vesa.fb; + memory = nvidias->vesa.fb_size; + screen_size = screen->fb[0].byteStride * screen->height; + if (nvidias->screen && memory >= screen_size + 2048) + { + memory -= 2048; + nvidias->cursor_base = nvidias->screen + memory - 2048; + } + else + nvidias->cursor_base = 0; + screen->softCursor = TRUE; /* XXX for now */ + memory -= screen_size; + if (memory > screen->fb[0].byteStride) + { + nvidias->off_screen = nvidias->screen + screen_size; + nvidias->off_screen_size = memory; + } + else + { + nvidias->off_screen = 0; + nvidias->off_screen_size = 0; + } + screen->driver = nvidias; + return TRUE; +} + +static Bool +nvidiaInitScreen (ScreenPtr pScreen) +{ +#if 0 +#ifdef XV + KdScreenPriv(pScreen); + NvidiaCardInfo *nvidiac = pScreenPriv->screen->card->driver; + if (nvidiac->media_reg && nvidiac->reg) + nvidiaInitVideo(pScreen); +#endif +#endif + return vesaInitScreen (pScreen); +} + +#ifdef RANDR +static Bool +nvidiaRandRSetConfig (ScreenPtr pScreen, + Rotation rotation, + int rate, + RRScreenSizePtr pSize) +{ + kaaWaitSync (pScreen); + + if (!vesaRandRSetConfig (pScreen, rotation, rate, pSize)) + return FALSE; + + return TRUE; +} + +static void +nvidiaRandRInit (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + + pScrPriv->rrSetConfig = nvidiaRandRSetConfig; +} +#endif + +static Bool +nvidiaFinishInitScreen (ScreenPtr pScreen) +{ + Bool ret; + ret = vesaFinishInitScreen (pScreen); +#ifdef RANDR + nvidiaRandRInit (pScreen); +#endif + return ret; +} + +void +nvidiaPreserve (KdCardInfo *card) +{ + vesaPreserve(card); +} + +void +nvidiaOutb (NvidiaCardInfo *nvidiac, CARD16 port, CARD8 val) +{ + asm volatile ("outb %b0,%w1" : : "a" (val), "d" (port)); +} + +CARD8 +nvidiaInb (NvidiaCardInfo *nvidiac, CARD16 port) +{ + CARD8 v; + asm volatile ("inb %w1,%b0" : "=a" (v) : "d" (port)); + return v; +} + +CARD8 +nvidiaGetIndex (NvidiaCardInfo *nvidiac, CARD16 addr, CARD16 data, CARD8 id) +{ + CARD8 ret; + DBGOUT ("nvidiaGetIndex(0x%x,0x%x)\n", addr, id); + nvidiaOutb (nvidiac, addr, id); + ret = nvidiaInb (nvidiac, data); + DBGOUT (" -> 0x%x\n", ret); + return ret; +} + +void +nvidiaSetIndex (NvidiaCardInfo *nvidiac, CARD16 addr, CARD16 data, CARD8 id, CARD8 val) +{ + DBGOUT ("nvidiaSetIndex(0x%x,0x%x) = 0x%x\n", addr, id, val); + nvidiaOutb (nvidiac, addr, id); + nvidiaOutb (nvidiac, data, val); +} + +static void vgaLockUnlock (NvidiaCardInfo *nvidiac, Bool lock) +{ + CARD8 cr11; + ENTER (); + cr11 = nvidiaGetIndex (nvidiac, 0x3d4, 0x3d5, 0x11); + if (lock) cr11 |= 0x80; + else cr11 &= ~0x80; + nvidiaSetIndex (nvidiac, 0x3d4, 0x3d5, 0x11, cr11); + LEAVE (); +} + +static void nvidiaLockUnlock (NvidiaCardInfo *nvidiac, Bool lock) +{ + if (NVIDIA_IS_3(nvidiac)) + nvidiaSetIndex (nvidiac, 0x3c4, 0x3c5, 0x06, lock ? 0x99 : 0x57); + else + nvidiaSetIndex (nvidiac, 0x3c4, 0x3c5, 0x1f, lock ? 0x99 : 0x57); + vgaLockUnlock(nvidiac, lock); +} + +Bool +nvidiaMapReg (KdCardInfo *card, NvidiaCardInfo *nvidiac) +{ + nvidiac->reg_base = (CARD8 *) KdMapDevice (NVIDIA_REG_BASE(card), + NVIDIA_REG_SIZE(card)); + + if (!nvidiac->reg_base) + { + nvidiac->mmio = 0; + nvidiac->rop = 0; + nvidiac->blt = 0; + nvidiac->rect = 0; + return FALSE; + } + + nvidiac->mmio = (CARD8 *) (nvidiac->reg_base + NVIDIA_MMIO_OFF(card)); + nvidiac->rop = (NvidiaRop *) (nvidiac->reg_base + NVIDIA_ROP_OFF(card)); + nvidiac->rect = (NvidiaRectangle *) (nvidiac->reg_base + NVIDIA_RECTANGLE_OFF(card)); + nvidiac->blt = (NvidiaScreenBlt *) (nvidiac->reg_base + NVIDIA_BLT_OFF(card)); + nvidiac->busy = (NvidiaBusy *) (nvidiac->reg_base + NVIDIA_BUSY_OFF(card)); + KdSetMappedMode (NVIDIA_REG_BASE(card), + NVIDIA_REG_SIZE(card), + KD_MAPPED_MODE_REGISTERS); + return TRUE; +} + +void +nvidiaUnmapReg (KdCardInfo *card, NvidiaCardInfo *nvidiac) +{ + if (nvidiac->reg_base) + { + KdResetMappedMode (NVIDIA_REG_BASE(card), + NVIDIA_REG_SIZE(card), + KD_MAPPED_MODE_REGISTERS); + KdUnmapDevice ((void *) nvidiac->reg_base, NVIDIA_REG_SIZE(card)); + nvidiac->reg_base = 0; + nvidiac->rop = 0; + nvidiac->blt = 0; + nvidiac->rect = 0; + } +} + +void +nvidiaSetMMIO (KdCardInfo *card, NvidiaCardInfo *nvidiac) +{ + if (!nvidiac->reg_base) + nvidiaMapReg (card, nvidiac); + nvidiaLockUnlock (nvidiac, FALSE); + nvidiac->fifo_free = 0; + nvidiac->fifo_size = nvidiac->rop->FifoFree.FifoFree; +} + +void +nvidiaResetMMIO (KdCardInfo *card, NvidiaCardInfo *nvidiac) +{ + nvidiaUnmapReg (card, nvidiac); + nvidiaLockUnlock (nvidiac, TRUE); +} + +Bool +nvidiaEnable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + NvidiaCardInfo *nvidiac = pScreenPriv->card->driver; + + if (!vesaEnable (pScreen)) + return FALSE; + + nvidiaSetMMIO (pScreenPriv->card, nvidiac); +#ifdef XV + KdXVEnable (pScreen); +#endif + return TRUE; +} + +void +nvidiaDisable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + NvidiaCardInfo *nvidiac = pScreenPriv->card->driver; + +#ifdef XV + KdXVDisable (pScreen); +#endif + nvidiaResetMMIO (pScreenPriv->card, nvidiac); + vesaDisable (pScreen); +} + +static Bool +nvidiaDPMS (ScreenPtr pScreen, int mode) +{ + return vesaDPMS (pScreen, mode); +} + +static void +nvidiaRestore (KdCardInfo *card) +{ + NvidiaCardInfo *nvidiac = card->driver; + + nvidiaResetMMIO (card, nvidiac); + vesaRestore (card); +} + +static void +nvidiaScreenFini (KdScreenInfo *screen) +{ + NvidiaScreenInfo *nvidias = (NvidiaScreenInfo *) screen->driver; + + vesaScreenFini (screen); + xfree (nvidias); + screen->driver = 0; +} + +static void +nvidiaCardFini (KdCardInfo *card) +{ + NvidiaCardInfo *nvidiac = card->driver; + + nvidiaUnmapReg (card, nvidiac); + vesaCardFini (card); +} + +#define nvidiaCursorInit 0 /* initCursor */ +#define nvidiaCursorEnable 0 /* enableCursor */ +#define nvidiaCursorDisable 0 /* disableCursor */ +#define nvidiaCursorFini 0 /* finiCursor */ +#define nvidiaRecolorCursor 0 /* recolorCursor */ + +KdCardFuncs nvidiaFuncs = { + nvidiaCardInit, /* cardinit */ + nvidiaScreenInit, /* scrinit */ + nvidiaInitScreen, /* initScreen */ + nvidiaFinishInitScreen, /* finishInitScreen */ + vesaCreateResources, /* createRes */ + nvidiaPreserve, /* preserve */ + nvidiaEnable, /* enable */ + nvidiaDPMS, /* dpms */ + nvidiaDisable, /* disable */ + nvidiaRestore, /* restore */ + nvidiaScreenFini, /* scrfini */ + nvidiaCardFini, /* cardfini */ + + nvidiaCursorInit, /* initCursor */ + nvidiaCursorEnable, /* enableCursor */ + nvidiaCursorDisable, /* disableCursor */ + nvidiaCursorFini, /* finiCursor */ + nvidiaRecolorCursor, /* recolorCursor */ + + nvidiaDrawInit, /* initAccel */ + nvidiaDrawEnable, /* enableAccel */ + nvidiaDrawDisable, /* disableAccel */ + nvidiaDrawFini, /* finiAccel */ + + vesaGetColors, /* getColors */ + vesaPutColors, /* putColors */ +}; |