xserver-multidpi/hw/kdrive/sis300/sis.c
2007-06-29 14:06:52 -04:00

312 lines
7.3 KiB
C

/*
* Copyright © 2003 Eric Anholt
*
* 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 Eric Anholt not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Eric Anholt makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ERIC ANHOLT 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 "sis.h"
#include "sis_reg.h"
struct pci_id_entry sis_pci_ids[] = {
{0x1039, 0x0300, 0x1, "SiS 300/305"},
{0x1039, 0x5300, 0x1, "SiS 540"},
{0x1039, 0x6300, 0x1, "SiS 630"},
{0x1039, 0x7300, 0x1, "SiS 730"},
{0, 0, 0, NULL}
};
static Bool
SiSCardInit(KdCardInfo *card)
{
SiSCardInfo *sisc;
Bool initialized = FALSE;
sisc = xcalloc(sizeof(SiSCardInfo), 1);
if (sisc == NULL)
return FALSE;
#ifdef KDRIVEFBDEV
if (!initialized && fbdevInitialize(card, &sisc->backend_priv.fbdev)) {
sisc->use_fbdev = TRUE;
initialized = TRUE;
sisc->backend_funcs.cardfini = fbdevCardFini;
sisc->backend_funcs.scrfini = fbdevScreenFini;
sisc->backend_funcs.initScreen = fbdevInitScreen;
sisc->backend_funcs.finishInitScreen = fbdevFinishInitScreen;
sisc->backend_funcs.createRes = fbdevCreateResources;
sisc->backend_funcs.preserve = fbdevPreserve;
sisc->backend_funcs.restore = fbdevRestore;
sisc->backend_funcs.dpms = fbdevDPMS;
sisc->backend_funcs.enable = fbdevEnable;
sisc->backend_funcs.disable = fbdevDisable;
sisc->backend_funcs.getColors = fbdevGetColors;
sisc->backend_funcs.putColors = fbdevPutColors;
}
#endif
#ifdef KDRIVEVESA
if (!initialized && vesaInitialize(card, &sisc->backend_priv.vesa)) {
sisc->use_vesa = TRUE;
initialized = TRUE;
sisc->backend_funcs.cardfini = vesaCardFini;
sisc->backend_funcs.scrfini = vesaScreenFini;
sisc->backend_funcs.initScreen = vesaInitScreen;
sisc->backend_funcs.finishInitScreen = vesaFinishInitScreen;
sisc->backend_funcs.createRes = vesaCreateResources;
sisc->backend_funcs.preserve = vesaPreserve;
sisc->backend_funcs.restore = vesaRestore;
sisc->backend_funcs.dpms = vesaDPMS;
sisc->backend_funcs.enable = vesaEnable;
sisc->backend_funcs.disable = vesaDisable;
sisc->backend_funcs.getColors = vesaGetColors;
sisc->backend_funcs.putColors = vesaPutColors;
}
#endif
if (!initialized || !SiSMapReg(card, sisc)) {
xfree(sisc);
return FALSE;
}
card->driver = sisc;
return TRUE;
}
static void
SiSCardFini(KdCardInfo *card)
{
SiSCardInfo *sisc = (SiSCardInfo *)card->driver;
SiSUnmapReg(card, sisc);
sisc->backend_funcs.cardfini(card);
}
static Bool
SiSScreenInit(KdScreenInfo *screen)
{
SiSScreenInfo *siss;
SiSCardInfo(screen);
int success = FALSE;
siss = xcalloc(sizeof(SiSScreenInfo), 1);
if (siss == NULL)
return FALSE;
siss->sisc = sisc;
screen->driver = siss;
#ifdef KDRIVEFBDEV
if (sisc->use_fbdev) {
success = fbdevScreenInitialize(screen,
&siss->backend_priv.fbdev);
screen->memory_size = sisc->backend_priv.fbdev.fix.smem_len;
screen->off_screen_base =
sisc->backend_priv.fbdev.var.yres_virtual *
screen->fb[0].byteStride;
}
#endif
#ifdef KDRIVEVESA
if (sisc->use_vesa) {
if (screen->fb[0].depth == 0)
screen->fb[0].depth = 16;
success = vesaScreenInitialize(screen,
&siss->backend_priv.vesa);
}
#endif
if (!success) {
screen->driver = NULL;
xfree(siss);
return FALSE;
}
return TRUE;
}
static void
SiSScreenFini(KdScreenInfo *screen)
{
SiSScreenInfo *siss = (SiSScreenInfo *)screen->driver;
SiSCardInfo *sisc = screen->card->driver;
sisc->backend_funcs.scrfini(screen);
xfree(siss);
screen->driver = 0;
}
Bool
SiSMapReg(KdCardInfo *card, SiSCardInfo *sisc)
{
sisc->reg_base = (CARD8 *)KdMapDevice(SIS_REG_BASE(card),
SIS_REG_SIZE(card));
if (sisc->reg_base == NULL)
return FALSE;
KdSetMappedMode(SIS_REG_BASE(card), SIS_REG_SIZE(card),
KD_MAPPED_MODE_REGISTERS);
return TRUE;
}
void
SiSUnmapReg(KdCardInfo *card, SiSCardInfo *sisc)
{
if (sisc->reg_base) {
KdResetMappedMode(SIS_REG_BASE(card), SIS_REG_SIZE(card),
KD_MAPPED_MODE_REGISTERS);
KdUnmapDevice((void *)sisc->reg_base, SIS_REG_SIZE(card));
sisc->reg_base = 0;
}
}
static Bool
SiSInitScreen(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
SiSCardInfo(pScreenPriv);
return sisc->backend_funcs.initScreen(pScreen);
}
static Bool
SiSFinishInitScreen(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
SiSCardInfo(pScreenPriv);
return sisc->backend_funcs.finishInitScreen(pScreen);
}
static Bool
SiSCreateResources(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
SiSCardInfo(pScreenPriv);
return sisc->backend_funcs.createRes(pScreen);
}
static void
SiSPreserve(KdCardInfo *card)
{
SiSCardInfo *sisc = card->driver;
sisc->backend_funcs.preserve(card);
}
static void
SiSRestore(KdCardInfo *card)
{
SiSCardInfo *sisc = card->driver;
SiSUnmapReg(card, sisc);
sisc->backend_funcs.restore(card);
}
static Bool
SiSDPMS(ScreenPtr pScreen, int mode)
{
KdScreenPriv(pScreen);
SiSCardInfo(pScreenPriv);
return sisc->backend_funcs.dpms(pScreen, mode);
}
static Bool
SiSEnable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
SiSCardInfo(pScreenPriv);
if (!sisc->backend_funcs.enable(pScreen))
return FALSE;
if ((sisc->reg_base == NULL) && !SiSMapReg(pScreenPriv->screen->card,
sisc))
return FALSE;
SiSDPMS(pScreen, KD_DPMS_NORMAL);
return TRUE;
}
static void
SiSDisable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
SiSCardInfo(pScreenPriv);
SiSUnmapReg(pScreenPriv->card, sisc);
sisc->backend_funcs.disable(pScreen);
}
static void
SiSGetColors(ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
SiSCardInfo(pScreenPriv);
sisc->backend_funcs.getColors(pScreen, fb, n, pdefs);
}
static void
SiSPutColors(ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
SiSCardInfo(pScreenPriv);
sisc->backend_funcs.putColors(pScreen, fb, n, pdefs);
}
KdCardFuncs SiSFuncs = {
SiSCardInit, /* cardinit */
SiSScreenInit, /* scrinit */
SiSInitScreen, /* initScreen */
SiSFinishInitScreen, /* finishInitScreen */
SiSCreateResources, /* createRes */
SiSPreserve, /* preserve */
SiSEnable, /* enable */
SiSDPMS, /* dpms */
SiSDisable, /* disable */
SiSRestore, /* restore */
SiSScreenFini, /* scrfini */
SiSCardFini, /* cardfini */
0, /* initCursor */
0, /* enableCursor */
0, /* disableCursor */
0, /* finiCursor */
0, /* recolorCursor */
SiSDrawInit, /* initAccel */
SiSDrawEnable, /* enableAccel */
SiSDrawSync, /* syncAccel */
SiSDrawDisable, /* disableAccel */
SiSDrawFini, /* finiAccel */
SiSGetColors, /* getColors */
SiSPutColors, /* putColors */
};