312 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			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 */
 | |
| };
 |