/* * 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 #endif #include "nvidia.h" #include "kaa.h" #include 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 */ };