362 lines
9.0 KiB
C
362 lines
9.0 KiB
C
|
/*
|
||
|
* 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 */
|
||
|
};
|