aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/kdrive/nvidia/nvidia.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/kdrive/nvidia/nvidia.c')
-rw-r--r--xorg-server/hw/kdrive/nvidia/nvidia.c361
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 */
+};