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 */
 | 
						|
};
 |