diff options
Diffstat (limited to 'programs/Xserver/hw')
59 files changed, 8261 insertions, 2365 deletions
diff --git a/programs/Xserver/hw/xfree86/CHANGELOG b/programs/Xserver/hw/xfree86/CHANGELOG index 8e97cf326..61ec07e84 100644 --- a/programs/Xserver/hw/xfree86/CHANGELOG +++ b/programs/Xserver/hw/xfree86/CHANGELOG @@ -1,5 +1,41 @@ -XFree86 3.9Nw (17 January 1999) +XFree86 3.9Nx (24 January 1999) +2180. Fix the VT switch screen restore bug introduced a few versions ago + (#2406, Mark Vojkovich). +2179. ND version of the sis driver, currently only for the 6326 chip (#2404, + 2405, Alan Hourihane). +2178. xterm patch #91 (#2402, Thomas Dickey). +2177. Add 32/24 support to the MGA driver (#2401, Mark Vojkovich). +2176. Add 32bpp->24bpp conversion acceleration to XAA (#2400, Mark Vojkovich). +2175. Add partial acceleration support to the TGA driver (#2399, 2403, + Matt Grossman). +2174. Fix an 8+32 layer bug introduced in 3.9Nw (#2398, Mark Vojkovich). +2173. Add a 32/24 conversion layer. Pixmaps are still 24bpp internally, + but the interfaces visible to clients are all 32bpp (#2397, + Mark Vojkovich). +2172. Fix trident driver panning at 24bpp (#2395, Alan Hourihane). +2171. Add DDC1 and DDC2 (the latter not working yet) to the trident driver + (#2395, Alan Hourihane). +2170. Add MCLK override to the trident driver (#2395, Alan Hourihane). +2169. Enable pixel multiplexing to the trident drive for high resolution + 8bpp modes (#2395, Alan Hourihane). +2168. Add clipping for the Trident 9682 and 9685 and Mono8x8 and CPUToScreen + support for the 9685 (#2395, Alan Hourihane). +2167. Add offscreen pixmap support for the Trident Image series (#2395, + Alan Hourihane). +2166. Fix some cfb problems that showed up after the previous changes + (#2396, Nozomi Ytow). +2165. Update the C&T HW cursor defaults to only disable them by default when + necessary (#2394, David Bateman). +2164. Add some sanity checking for the subdirs argument to LoadSubModule, etc. +2163. Fix a bug in the verbose Mode handling in the parser that can result + in an infinite loop when the "Mode" keyword is used incorrectly in + a config file. +2162. Add a global default module path to the loader, and a function that + the common layer can call to set it. +2161. LoadModule was ignoring the subdir list argument (Nozomi Ytow). 2160. Add printing of subsystem ids to scanpci (Dirk Hohndel). + +XFree86 3.9Nw (17 January 1999) 2159. Add functions for finding the pixmap format and pixmap bpp for a given depth, and fix a crash in xf86ValidateModes() caused by recent changes in this area. @@ -7106,4 +7142,4 @@ XFree86 3.0 (26 April 1994) -$XFree86: /home/ftp/pub/xf86/CVS/xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.672 1999/01/17 11:25:16 dawes Exp $ +$XFree86: xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.673 1999/01/21 06:55:12 hohndel Exp $ diff --git a/programs/Xserver/hw/xfree86/Imakefile b/programs/Xserver/hw/xfree86/Imakefile index af47811e5..26cceb790 100644 --- a/programs/Xserver/hw/xfree86/Imakefile +++ b/programs/Xserver/hw/xfree86/Imakefile @@ -3,7 +3,7 @@ XCOMM $XConsortium: Imakefile /main/12 1996/12/16 12:31:46 rws $ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/Imakefile,v 3.48 1998/12/20 11:57:38 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/Imakefile,v 3.49 1999/01/03 03:58:24 dawes Exp $ #include <Server.tmpl> #define IHaveSubdirs @@ -27,6 +27,10 @@ XF4BPPDIR = xf4bpp XF8_32BPPDIR = xf8_32bpp #endif +#if XF24_32Bpp +XF24_32BPPDIR = xf24_32bpp +#endif + #if XF86I2C I2CDIR = i2c #endif @@ -62,7 +66,7 @@ INPUTDIR = input #endif SUBDIRS = os-support common $(XAADIR) $(XF1BPPDIR) $(XF4BPPDIR) \ - $(XF8_32BPPDIR) drivers $(LOADERDIR) $(VGAHWDIR) \ + $(XF8_32BPPDIR) $(XF24_32BPPDIR) drivers $(LOADERDIR) $(VGAHWDIR) \ $(RAMDACDIR) $(RACDIR) \ $(I2CDIR) $(DDCDIR) $(INPUTDIR) parser \ doc xf86config $(XF86SETUPDIR) etc /* LinkKit */ \ diff --git a/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c b/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c index b65293b42..8681d4b6f 100644 --- a/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c +++ b/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c,v 1.46 1999/01/15 02:27:13 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c,v 1.47 1999/01/17 10:53:58 dawes Exp $ */ /* * Copyright 1993 by Jon Block <block@frc.com> @@ -4049,6 +4049,15 @@ chipsModeInitHiQV(ScrnInfoPtr pScrn, DisplayModePtr mode) ChipsNew = &cPtr->ModeReg; ChipsStd = &hwp->ModeReg; + /* + * Possibly fix up the panel size, if the manufacture is stupid + * enough to set it incorrectly in text modes + */ + if (xf86IsOptionSet(cPtr->Options, OPTION_PANEL_SIZE)) { + cPtr->PanelSize.HDisplay = mode->CrtcHDisplay; + cPtr->PanelSize.VDisplay = mode->CrtcVDisplay; + } + /* generic init */ if (!vgaHWInit(pScrn, mode)) { ErrorF("bomb 1\n"); @@ -4201,10 +4210,13 @@ chipsModeInitHiQV(ScrnInfoPtr pScrn, DisplayModePtr mode) if (xf86IsOptionSet(cPtr->Options, OPTION_HW_CURSOR)) cPtr->Accel.UseHWCursor = TRUE; /* H/W cursor forced */ else { - if(cPtr->Accel.UseHWCursor) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling HW Cursor\n"); - cPtr->Accel.UseHWCursor = FALSE; /* Possible H/W bug? */ + if ((cPtr->PanelSize.HDisplay != mode->CrtcHDisplay) && + (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) { + if(cPtr->Accel.UseHWCursor) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Disabling HW Cursor on stretched LCD\n"); + cPtr->Accel.UseHWCursor = FALSE; /* Possible H/W bug? */ + } } } } @@ -4864,10 +4876,14 @@ chipsModeInit655xx(ScrnInfoPtr pScrn, DisplayModePtr mode) if (xf86IsOptionSet(cPtr->Options, OPTION_HW_CURSOR)) cPtr->Accel.UseHWCursor = TRUE; /* H/W cursor forced */ else { - if(cPtr->Accel.UseHWCursor) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling HW Cursor\n"); - cPtr->Accel.UseHWCursor = FALSE; + if ((cPtr->PanelSize.HDisplay != mode->CrtcHDisplay) + && (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) { + /* Possible H/W bug? */ + if(cPtr->Accel.UseHWCursor) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Disabling HW Cursor on stretched LCD\n"); + cPtr->Accel.UseHWCursor = FALSE; + } } else cPtr->Accel.UseHWCursor = TRUE; diff --git a/programs/Xserver/hw/xfree86/drivers/mga/Imakefile b/programs/Xserver/hw/xfree86/drivers/mga/Imakefile index c786a9f24..117d5c4d0 100644 --- a/programs/Xserver/hw/xfree86/drivers/mga/Imakefile +++ b/programs/Xserver/hw/xfree86/drivers/mga/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v 1.15 1998/12/13 05:32:48 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v 1.16 1999/01/03 03:58:35 dawes Exp $ XCOMM XCOMM This is an Imakefile for the MGA driver. XCOMM @@ -20,7 +20,8 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\ - -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) + -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ + -I$(XF86SRC)/xf24_32bpp #endif #if MakeHasPosixVariableSubstitutions diff --git a/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c b/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c index ee22a4425..5023f698d 100644 --- a/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c +++ b/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c @@ -43,7 +43,7 @@ * Fixed 32bpp hires 8MB horizontal line glitch at middle right */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.67 1999/01/14 13:04:28 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.68 1999/01/17 10:54:02 dawes Exp $ */ /* * This is a first cut at a non-accelerated version to work with the @@ -84,6 +84,7 @@ #include "cfb16.h" #include "cfb24.h" #include "cfb32.h" +#include "cfb24_32.h" #include "cfb8_32.h" /* These need to be checked */ @@ -243,6 +244,7 @@ static const char *cfbSymbols[] = { "cfb24ScreenInit", "cfb32ScreenInit", "cfb8_32ScreenInit", + "cfb24_32ScreenInit", NULL }; @@ -826,7 +828,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) * Our default depth is 8, so pass it to the helper function. * We support both 24bpp and 32bpp layouts, so indicate that. */ - if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb)) { + if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb + | SupportConvert32to24 | PreferConvert32to24)) { return FALSE; } else { /* Check that the returned depth is one we support */ @@ -954,18 +957,6 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) } if (xf86IsOptionSet(MGAOptions, OPTION_8_PLUS_24)) { if(pScrn->bitsPerPixel == 32) { -#if 0 - int num = pScrn->numFormats; - pScrn->formats[num].depth = pScrn->formats[num - 1].depth; - pScrn->formats[num].bitsPerPixel = - pScrn->formats[num - 1].bitsPerPixel; - pScrn->formats[num].scanlinePad = - pScrn->formats[num - 1].scanlinePad; - pScrn->formats[num - 1].depth = 8; - pScrn->formats[num - 1].bitsPerPixel = 8; - pScrn->formats[num - 1].scanlinePad = BITMAP_SCANLINE_PAD; - pScrn->numFormats++; -#endif pMga->Overlay8Plus24 = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PseudoColor overlay enabled\n"); @@ -1414,8 +1405,13 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) reqSym = "cfb16ScreenInit"; break; case 24: - mod = "cfb24"; - reqSym = "cfb24ScreenInit"; + if (0) { + mod = "cfb24"; + reqSym = "cfb24ScreenInit"; + } else { + mod = "xf24_32bpp"; + reqSym = "cfb24_32ScreenInit"; + } break; case 32: if (pMga->Overlay8Plus24) { @@ -1814,7 +1810,13 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->displayWidth); break; case 24: - ret = cfb24ScreenInit(pScreen, pMga->FbStart, + if(0) + ret = cfb24ScreenInit(pScreen, pMga->FbStart, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth); + else + ret = cfb24_32ScreenInit(pScreen, pMga->FbStart, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); diff --git a/programs/Xserver/hw/xfree86/drivers/sis/Imakefile b/programs/Xserver/hw/xfree86/drivers/sis/Imakefile index d7f271c5a..2cb33df25 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/Imakefile +++ b/programs/Xserver/hw/xfree86/drivers/sis/Imakefile @@ -1,58 +1,34 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile,v 1.1 1997/03/06 23:16:45 hohndel Exp $ - - +XCOMM $XFree86$ +XCOMM +XCOMM This is an Imakefile for the SIS driver. +XCOMM #define IHaveModules #include <Server.tmpl> -SRCS = sis_driver.c sis_bank.s sis_curs.c sis_BitBlt.c sis_blitter.c\ - sis_solid.c sis_blt16.c sis_pntwin.c sis_FillRct.c sis_FillSt.c\ - sis_colexp.c sis_teblt8.c sis_textblt.s sis_accel.c - -OBJS = sis_driver.o sis_bank.o sis_curs.o sis_BitBlt.o sis_blitter.o\ - sis_solid.o sis_blt16.o sis_pntwin.o sis_FillRct.o sis_FillSt.o\ - sis_colexp.o sis_teblt8.o sis_textblt.o sis_accel.o - -DEFINES = -DPSZ=8 +SRCS = sis_driver.c sis_dac.c sis_accel.c +OBJS = sis_driver.o sis_dac.o sis_accel.o #if XF86LinkKit INCLUDES = -I. -I../../../include -I../../../include/X11 -I../.. #else -INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86HWSRC) -I$(XF86OSSRC) \ - -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/cfb \ - -I$(XF86SRC)/vga256/vga -I../../xaa -I$(SERVERSRC)/include \ - -I$(XINCLUDESRC) -I$(FONTINCSRC) +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \ + -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \ + -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \ + -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac -I$(XF86SRC)/i2c \ + -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ + -I$(XTOP)/include/extensions #endif #if MakeHasPosixVariableSubstitutions SubdirLibraryRule($(OBJS)) #endif -NormalLibraryObjectRule() -NormalAsmObjectRule() - -NormalRelocatableTarget(sis_drv, $(OBJS)) - -InstallLinkKitNonExecFile(sis_driver.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_bank.s,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_curs.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(Imakefile,$(LINKKITDIR)/drivers/svga/sis) - -InstallLinkKitNonExecFile(sis_accel.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_blt16.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_blitter.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_BitBlt.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_solid.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_Blitter.h,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_driver.h,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_pntwin.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_FillRct.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_FillSt.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_colexp.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_teblt8.c,$(LINKKITDIR)/drivers/svga/sis) -InstallLinkKitNonExecFile(sis_textblt.s,$(LINKKITDIR)/drivers/svga/sis) - -#if DoLoadableServer -InstallDynamicModule(sis_drv.o,$(MODULEDIR)) -#endif + +ModuleObjectRule() + +ObjectModuleTarget(sis,$(OBJS)) + +InstallObjectModule(sis,$(MODULEDIR),drivers) DependTarget() diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis.h b/programs/Xserver/hw/xfree86/drivers/sis/sis.h new file mode 100644 index 000000000..a8e6f29ac --- /dev/null +++ b/programs/Xserver/hw/xfree86/drivers/sis/sis.h @@ -0,0 +1,89 @@ +/* + * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. + */ +/* $XFree86$ */ + +#ifndef _SIS_H +#define _SIS_H_ + +#include "xf86Cursor.h" +#include "xaa.h" +#include "compiler.h" +#include "vgaHW.h" + +typedef struct { + unsigned char sisRegs3x4[0x100]; + unsigned char sisRegs3C4[0x100]; + unsigned char sisRegs3C2[0x100]; +} SISRegRec, *SISRegPtr; + +#define SISPTR(p) ((SISPtr)((p)->driverPrivate)) + +typedef struct { + ScrnInfoPtr pScrn; + pciVideoPtr PciInfo; + PCITAG PciTag; + int Chipset; + int ChipRev; + int DACtype; + int HwBpp; + int BppShift; + CARD32 IOAddress; + CARD32 FbAddress; + unsigned char * IOBase; +#ifdef __alpha__ + unsigned char * IOBaseDense; +#endif + unsigned char * FbBase; + CARD32 IOAccelAddress; + unsigned char * IOAccel; + long FbMapSize; + Bool NoAccel; + Bool HWCursor; + Bool UsePCIRetry; + Bool TurboQueue; + int MinClock; + int MaxClock; + int Xdirection; + int Ydirection; + int sisPatternReg[4]; + SISRegRec SavedReg; + SISRegRec ModeReg; + CARD32 AccelFlags; + xf86CursorInfoPtr CursorInfoRec; + XAAInfoRecPtr AccelInfoRec; + CloseScreenProcPtr CloseScreen; +} SISRec, *SISPtr; + +/* Prototypes */ + +void SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg); +void SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg); +Bool SiSInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +Bool SiSAccelInit(ScreenPtr pScreen); + +#endif diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c b/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c index a5bb91f21..dd9931145 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c +++ b/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c @@ -1,218 +1,99 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c,v 1.1 1997/03/06 23:16:49 hohndel Exp $ */ +/* $XFree86$ */ - -/* - * This is a sample driver implementation template for the new acceleration - * interface. - */ - -#include "vga256.h" #include "xf86.h" -#include "vga.h" -#define XCONFIG_FLAGS_ONLY -#include "xf86_Config.h" - -#include "xf86xaa.h" - -#include "sis_driver.h" -#include "sis_Blitter.h" -extern Bool sisUseXAAcolorExp ; -/* - * Include any definitions for communicating with the coprocessor here. - * In this sample driver, the following macros are defined: - * - * SETFOREGROUNDCOLOR(color) - * SETRASTEROP(rop) - * SETWRITEPLANEMASK(planemask) - * SETSOURCEADDR(srcaddr) - * SETDESTADDR(destaddr) - * SETWIDTH(width) - * SETHEIGHT(height) - * SETBLTXDIR(xdir) - * SETBLTYDIR(yrdir) - * SETCOMMAND(command) - * WAITUNTILFINISHED() - * - * The interface for accelerator chips varies widely, and this may not - * be a realistic scenario. In this sample implemention, the chip requires - * the source and destation location to be specified with addresses, but - * it might just as well use coordinates. When implementing the primitives, - * you will often find the need to store some settings in a variable. - */ -/* #include "coprocessor.h" */ - -void SISSync(); -void SISSetupForFillRectSolid(); -void SISSubsequentFillRectSolid(); -void SISSetupForScreenToScreenCopy(); -void SISSubsequentScreenToScreenCopy(); - -void SISSetupForScreenToScreenColorExpand(); -void SISSubsequentScreenToScreenColorExpand(); -void SISSetupForScanlineScreenToScreenColorExpand(); -void SISSubsequentScanlineScreenToScreenColorExpand(); - -void SISSetupFor8x8PatternColorExpand(); -void SISSubsequent8x8PatternColorExpand(); - -static int sisPatternHeight=16 ; - -/* - * The following function sets up the supported acceleration. Call it - * from the FbInit() function in the SVGA driver, or before ScreenInit - * in a monolithic server. - */ -void SISAccelInit() +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "miline.h" + +#include "sis_regs.h" +#include "sis.h" + +static void SiSSync(ScrnInfoPtr pScrn); +static void SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, + int rop, unsigned int planemask); +static void SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, + int y, int w, int h); +static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, int x2, + int y2, int w, int h); +static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int transparency_color); +static void SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, int fg, int bg, + int rop, unsigned int planemask); +static void SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, int x, int y, + int w, int h); + +static void +SiSInitializeAccelerator(ScrnInfoPtr pScrn) { - int cacheStart, cacheEnd; - int sisCursorSize = sisHWCursor ? 16384 : 0 ; - int offscreen_available ; - int sisBLTPatternAddress ; - int sisBLTPatternOffscreenSize ; - /* - * If you want to disable acceleration, just don't modify anything - * in the AccelInfoRec. - */ - - /* - * Set up the main acceleration flags. - * Usually, you will want to use BACKGROUND_OPERATIONS, - * and if you have ScreenToScreenCopy, use the PIXMAP_CACHE. - * - * If the chip is restricted in the screen-to-screen BitBLT - * directions it supports, you can indicate that here: - * - * ONLY_TWO_BITBLT_DIRECTIONS indicates that xdir must be equal to ydir. - * ONLY_LEFT_TO_RIGHT_BITBLT indicates that the xdir must be 1. - */ + SISPtr pSiS = SISPTR(pScrn); +} - /* Disable the PIXMAP CACHE in no linear because XAA high level does not - * work with video in banked mode. - * May be in the future we could restore the PIXMAP CACHE even in banked - * mode - */ - +Bool +SiSAccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr infoPtr; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SISPtr pSiS = SISPTR(pScrn); + BoxRec AvailFBArea; - xf86AccelInfoRec.Flags = BACKGROUND_OPERATIONS | - (sisUseXAAcolorExp ? PIXMAP_CACHE : 0 ) ; + pSiS->AccelInfoRec = infoPtr = XAACreateInfoRec(); + if (!infoPtr) return FALSE; - /* - * The following line installs a "Sync" function, that waits for - * all coprocessor operations to complete. - */ - xf86AccelInfoRec.Sync = SISSync; + SiSInitializeAccelerator(pScrn); - /* - * We want to set up the FillRectSolid primitive for filling a solid - * rectangle. First we set up the flags for the graphics operation. - * It may include GXCOPY_ONLY, NO_PLANEMASK, and RGB_EQUAL. - */ - xf86GCInfoRec.PolyFillRectSolidFlags = NO_PLANEMASK ; - - /* - * Install the low-level functions for drawing solid filled rectangles. - */ - xf86AccelInfoRec.SetupForFillRectSolid = SISSetupForFillRectSolid; - xf86AccelInfoRec.SubsequentFillRectSolid = SISSubsequentFillRectSolid; + infoPtr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | + LINEAR_FRAMEBUFFER; + + infoPtr->Sync = SiSSync; - /* - * We also want to set up the ScreenToScreenCopy (BitBLT) primitive for - * copying a rectangular area from one location on the screen to - * another. First we set up the restrictions. In this case, we - * don't handle transparency color compare. Other allowed flags are - * GXCOPY_ONLY and NO_PLANEMASK. - */ - xf86GCInfoRec.CopyAreaFlags = NO_TRANSPARENCY | NO_PLANEMASK; - - /* - * Install the low-level functions for screen-to-screen copy. - */ - xf86AccelInfoRec.SetupForScreenToScreenCopy = - SISSetupForScreenToScreenCopy; - xf86AccelInfoRec.SubsequentScreenToScreenCopy = - SISSubsequentScreenToScreenCopy; - - /* Color Expansion */ - if (vga256InfoRec.bitsPerPixel != 24) { - /* the enhanced color expansion is not supported - * by the engine in 16M-color graphic mode. - */ - xf86AccelInfoRec.ColorExpandFlags = VIDEO_SOURCE_GRANULARITY_DWORD | - BIT_ORDER_IN_BYTE_MSBFIRST | - SCANLINE_PAD_DWORD | - GXCOPY_ONLY | - NO_PLANEMASK; - if ( sisUseXAAcolorExp ) { - xf86AccelInfoRec.SetupForScreenToScreenColorExpand = - SISSetupForScreenToScreenColorExpand; - xf86AccelInfoRec.SubsequentScreenToScreenColorExpand = - SISSubsequentScreenToScreenColorExpand; - xf86AccelInfoRec.SetupForScanlineScreenToScreenColorExpand = - SISSetupForScanlineScreenToScreenColorExpand; - xf86AccelInfoRec.SubsequentScanlineScreenToScreenColorExpand = - SISSubsequentScanlineScreenToScreenColorExpand; - - offscreen_available = vga256InfoRec.videoRam * 1024 - - vga256InfoRec.displayWidth * vga256InfoRec.virtualY - * (vgaBitsPerPixel / 8); - sisBLTPatternOffscreenSize = 1024 ; - - if (offscreen_available < sisBLTPatternOffscreenSize) { - ErrorF("%s %s: Not enough off-screen video" - " memory for expand color.\n", - XCONFIG_PROBED, vga256InfoRec.name); - sisBLTPatternOffscreenSize = 0 ; - } - else { - sisBLTPatternAddress = vga256InfoRec.videoRam * 1024 - - sisCursorSize - sisBLTPatternOffscreenSize; - xf86AccelInfoRec.ScratchBufferAddr=sisBLTPatternAddress; - xf86AccelInfoRec.ScratchBufferSize=sisBLTPatternOffscreenSize; - } - } - /* - * 8x8 color expand pattern fill - */ - xf86AccelInfoRec.PatternFlags = HARDWARE_PATTERN_PROGRAMMED_BITS | - HARDWARE_PATTERN_PROGRAMMED_ORIGIN | - HARDWARE_PATTERN_BIT_ORDER_MSBFIRST | - HARDWARE_PATTERN_MONO_TRANSPARENCY ; - xf86AccelInfoRec.SetupFor8x8PatternColorExpand = - SISSetupFor8x8PatternColorExpand; - xf86AccelInfoRec.Subsequent8x8PatternColorExpand = - SISSubsequent8x8PatternColorExpand; - - } - /* - * Finally, we set up the video memory space available to the pixmap - * cache. In this case, all memory from the end of the virtual screen - * to the end of video memory minus 1K, can be used. If you haven't - * enabled the PIXMAP_CACHE flag, then these lines can be omitted. - */ - if (sisUseXAAcolorExp) { - cacheStart = - vga256InfoRec.virtualY * vga256InfoRec.displayWidth - * vga256InfoRec.bitsPerPixel / 8; - cacheEnd = - vga256InfoRec.videoRam * 1024 - 1024 - sisBLTPatternOffscreenSize - - sisCursorSize ; - - xf86InitPixmapCache(&vga256InfoRec, cacheStart, cacheEnd); - } - /* - * Now set variables often used - * - */ - - sisPatternHeight = (SISchipset == SIS86C205) ? 16 : 8 ; +#if 1 + infoPtr->SolidFillFlags = NO_PLANEMASK; + infoPtr->SetupForSolidFill = SiSSetupForFillRectSolid; + infoPtr->SubsequentSolidFillRect = SiSSubsequentFillRectSolid; +#endif + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK; + infoPtr->SetupForScreenToScreenCopy = + SiSSetupForScreenToScreenCopy; + infoPtr->SubsequentScreenToScreenCopy = + SiSSubsequentScreenToScreenCopy; + + infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + BIT_ORDER_IN_BYTE_MSBFIRST; + + infoPtr->SetupForMono8x8PatternFill = + SiSSetupForMono8x8PatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = + SiSSubsequentMono8x8PatternFillRect; + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = (pSiS->FbMapSize - 4096) / (pScrn->displayWidth * + pScrn->bitsPerPixel / 8); + + xf86InitFBManager(pScreen, &AvailFBArea); + + return(XAAInit(pScreen, infoPtr)); } -/* - * This is the implementation of the Sync() function. - */ -void SISSync() { - sisBLTWAIT; +static void +SiSSync(ScrnInfoPtr pScrn) { + SISPtr pSiS = SISPTR(pScrn); + sisBLTSync; } static int sisALUConv[] = @@ -235,21 +116,16 @@ static int sisALUConv[] = 0xFF, /* dest = 0xFF; GXset, 0xF */ }; -/* - * This is the implementation of the SetupForFillRectSolid function - * that sets up the coprocessor for a subsequent batch of solid - * rectangle fills. - */ -void SISSetupForFillRectSolid(color, rop, planemask) - int color, rop; - unsigned planemask; +static void +SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask) { + SISPtr pSiS = SISPTR(pScrn); - sisBLTWAIT; sisSETFGCOLOR(color); sisSETROP(sisALUConv[rop & 0xF]); - sisSETPITCH(vga256InfoRec.displayWidth * vgaBytesPerPixel, - vga256InfoRec.displayWidth * vgaBytesPerPixel); + sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8, + pScrn->displayWidth * pScrn->bitsPerPixel / 8); /* * If you don't support a write planemask, and have set the * appropriate flag, then the planemask can be safely ignored. @@ -258,95 +134,54 @@ void SISSetupForFillRectSolid(color, rop, planemask) /*SETWRITEPLANEMASK(planemask);*/ } -/* - * This is the implementation of the SubsequentForFillRectSolid function - * that sends commands to the coprocessor to fill a solid rectangle of - * the specified location and size, with the parameters from the SetUp - * call. - */ -void SISSubsequentFillRectSolid(x, y, w, h) - int x, y, w, h; +static void +SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) { + SISPtr pSiS = SISPTR(pScrn); int destaddr, op; - destaddr = y * vga256InfoRec.displayWidth + x; + destaddr = y * pScrn->displayWidth + x; op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT; - destaddr *= vgaBytesPerPixel ; - /* - * When BACKGROUND_OPERATIONS is enabled, on some chips (such as - * Cirrus) you must wait here for the previous operation to finish. - * On others (like ARK or Matrox), you don't, or you might wait for - * a certain number of command FIFO slots to become free (the - * latter is often unnecessary, and it does impact performance). - */ - /* ChipSync(); */ - sisBLTWAIT; - sisSETHEIGHTWIDTH(h-1, w * vgaBytesPerPixel-1); + destaddr *= (pScrn->bitsPerPixel / 8); + + sisSETHEIGHTWIDTH(h-1, w * (pScrn->bitsPerPixel/8)-1); sisSETDSTADDR(destaddr); sisSETCMD(op); - /* - * If you don't use BACKGROUND_OPERATIONS, this would be the - * place to call SISSync(). - */ + SiSSync(pScrn); } -/* - * This is the implementation of the SetupForScreenToScreenCopy function - * that sets up the coprocessor for a subsequent batch of - * screen-to-screen copies. Remember, we don't handle transparency, - * so the transparency color is ignored. - */ -static int blitxdir, blitydir; - -void SISSetupForScreenToScreenCopy(xdir, ydir, rop, planemask, -transparency_color) - int xdir, ydir; - int rop; - unsigned planemask; - int transparency_color; +static void +SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, + int rop, unsigned int planemask, + int transparency_color) { - /* - * xdir can be either 1 (left-to-right) or -1 (right-to-left). - * ydir can be either 1 (top-to-bottom) or -1 (bottom-to-top). - */ - sisBLTWAIT; - sisSETPITCH(vga256InfoRec.displayWidth * vgaBytesPerPixel, - vga256InfoRec.displayWidth * vgaBytesPerPixel); + SISPtr pSiS = SISPTR(pScrn); + sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8, + pScrn->displayWidth * pScrn->bitsPerPixel / 8); sisSETROP(sisALUConv[rop & 0xF]); - blitxdir = xdir; - blitydir = ydir; + pSiS->Xdirection = xdir; + pSiS->Ydirection = ydir; } -/* - * This is the implementation of the SubsequentForScreenToScreenCopy - * that sends commands to the coprocessor to perform a screen-to-screen - * copy of the specified areas, with the parameters from the SetUp call. - * In this sample implementation, the direction must be taken into - * account when calculating the addresses (with coordinates, it might be - * a little easier). - */ -void SISSubsequentScreenToScreenCopy(x1, y1, x2, y2, w, h) - int x1, y1, x2, y2, w, h; +static void +SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w, int h) { + SISPtr pSiS = SISPTR(pScrn); int srcaddr, destaddr; int op ; - /* - * If the direction is "decreasing", the chip wants the addresses - * to be at the other end, so we must be aware of that in our - * calculations. - */ op = sisCMDBLT | sisSRCVIDEO; - if (blitydir == -1) { + if (pSiS->Ydirection == -1) { op |= sisBOTTOM2TOP; - srcaddr = (y1 + h - 1) * vga256InfoRec.displayWidth; - destaddr = (y2 + h - 1) * vga256InfoRec.displayWidth; + srcaddr = (y1 + h - 1) * pScrn->displayWidth; + destaddr = (y2 + h - 1) * pScrn->displayWidth; } else { op |= sisTOP2BOTTOM; - srcaddr = y1 * vga256InfoRec.displayWidth; - destaddr = y2 * vga256InfoRec.displayWidth; + srcaddr = y1 * pScrn->displayWidth; + destaddr = y2 * pScrn->displayWidth; } - if (blitxdir == -1) { + if (pSiS->Xdirection == -1) { op |= sisRIGHT2LEFT; srcaddr += x1 + w - 1; destaddr += x2 + w - 1; @@ -355,195 +190,31 @@ void SISSubsequentScreenToScreenCopy(x1, y1, x2, y2, w, h) srcaddr += x1; destaddr += x2; } - srcaddr *= vgaBytesPerPixel; - destaddr *= vgaBytesPerPixel; - if ( (vgaBytesPerPixel>1) && (blitxdir == -1) ) { - srcaddr += vgaBytesPerPixel-1; - destaddr += vgaBytesPerPixel-1; + srcaddr *= (pScrn->bitsPerPixel/8); + destaddr *= (pScrn->bitsPerPixel/8); + if ( ((pScrn->bitsPerPixel/8)>1) && (pSiS->Xdirection == -1) ) { + srcaddr += (pScrn->bitsPerPixel/8)-1; + destaddr += (pScrn->bitsPerPixel/8)-1; } - /* - * Again, you may have to wait for the previous operation to - * finish when using BACKGROUND_OPERATIONS. - */ - /* SISSync(); */ - sisBLTWAIT; + sisSETSRCADDR(srcaddr); sisSETDSTADDR(destaddr); - sisSETHEIGHTWIDTH(h-1, w * vgaBytesPerPixel-1); + sisSETHEIGHTWIDTH(h-1, w * (pScrn->bitsPerPixel/8)-1); sisSETCMD(op); - /* - * If you don't use BACKGROUND_OPERATIONS, this would be the - * place to call SISSync(). - */ + SiSSync(pScrn); } -/* - * setup for screen-to-screen color expansion - */ -static int sisColExp_op ; -void SISSetupForScreenToScreenColorExpand(bg, fg, rop, planemask) - int bg, fg, rop; - unsigned planemask; -{ - int isTransparent = ( bg == -1 ); - int op ; - - /*ErrorF("SISSetupScreenToScreenColorExpand()\n");*/ - - sisBLTWAIT; - op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT ; - - /* - * check transparency - */ - /* becareful with rop */ - if (isTransparent) { - sisSETFGCOLOR(fg); - sisSETROPFG(0xf0); /* pat copy */ - sisSETROPBG(0xAA); /* dst */ - op |= sisPATFG | sisSRCBG ; - } else { - sisSETBGCOLOR(bg); - sisSETFGCOLOR(fg); - sisSETROPFG(0xf0); /* pat copy */ - sisSETROPBG(0xcc); /* copy */ - op |= sisPATFG | sisSRCBG ; - } - op |= sisCMDENHCOLEXP ; - sisColExp_op = op ; -} - -/* - * executing screen-to-screen color expansion - */ -void SISSubsequentScreenToScreenColorExpand(srcx, srcy, x, y, ww, h) - int srcx, srcy, x, y, ww, h; -{ - int destpitch = vga256InfoRec.displayWidth * vgaBytesPerPixel ; - int srcaddr = srcy * destpitch * + srcx ; - int destaddr = y * destpitch + x * vgaBytesPerPixel; - int srcpitch ; - int w ; - int widthTodo ; - - /*ErrorF("SISSubsequentScreenToScreenColorExpand()\n");*/ -#define maxWidth 144 - /* can't expand more than maxWidth in one time. - it's a work around for scanline greater than maxWidth - */ - destpitch = vga256InfoRec.displayWidth * vgaBytesPerPixel ; - srcpitch = ((ww + 31)& ~31) /8 ; - sisBLTWAIT; - sisSETPITCH(srcpitch, destpitch); - widthTodo = ww ; - do { - w = widthTodo < maxWidth ? widthTodo : maxWidth ; - sisBLTWAIT; - sisSETDSTADDR(destaddr); - sisSETSRCADDR(srcaddr); - sisSETHEIGHTWIDTH(h-1, w*vgaBytesPerPixel-1); - sisSETCMD(sisColExp_op); - srcaddr += w ; - destaddr += w*vgaBytesPerPixel ; - widthTodo -= w ; - } while ( widthTodo > 0 ) ; - -} - -static int sisDstAddr; -static int sisDstPitch; -static int sisWidth ; -void SISSetupForScanlineScreenToScreenColorExpand(x, y, w, h, bg, fg, rop, -planemask) - int x, y, w, h, bg, fg, rop; - unsigned int planemask; -{ - int isTransparent = ( bg == -1 ); - int op ; - int pitch = vga256InfoRec.displayWidth * vgaBytesPerPixel ; - int destaddr = y * pitch + x * vgaBytesPerPixel; - - sisBLTWAIT; - op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT | - sisPATFG | sisSRCBG | sisCMDENHCOLEXP ; - /* - * check transparency - */ - /* becareful with rop */ - if (isTransparent) { - sisSETFGCOLOR(fg); - sisSETROPFG(0xf0); /* pat copy */ - sisSETROPBG(0xAA); /* dst */ - } else { - sisSETBGCOLOR(bg); - sisSETFGCOLOR(fg); - sisSETROPFG(0xf0); /* pat copy */ - sisSETROPBG(0xcc); /* copy */ - } - sisColExp_op = op ; - sisSETDSTADDR(destaddr); - sisDstPitch = pitch ; - sisDstAddr = destaddr ; - sisWidth = w ; -} - -void SISSubsequentScanlineScreenToScreenColorExpand(srcaddr) - int srcaddr; -{ - int widthTodo ; - int dstaddr, srcpitch ; - int w ; - - /*ErrorF("SISSubsequentScanlineScreenToScreenColorExpand()\n");*/ -#define maxWidth 144 - /* can't expand more than maxWidth in one time. - it's a work around for scanline greater than maxWidth - */ - dstaddr = sisDstAddr ; - widthTodo = sisWidth ; - do { - w = widthTodo < maxWidth ? widthTodo : maxWidth ; - srcpitch = ((w + 31)& ~31) /8 ; - sisBLTWAIT; - sisSETPITCH(srcpitch, sisDstPitch); - sisSETHEIGHTWIDTH(0, w*vgaBytesPerPixel-1); - sisSETSRCADDR(srcaddr/8); - sisSETDSTADDR(dstaddr); - sisSETCMD(sisColExp_op); - srcaddr += w ; - dstaddr += w*vgaBytesPerPixel ; - widthTodo -= w ; - } while ( widthTodo > 0 ) ; - sisDstAddr += sisDstPitch ; - - -} - -/* - * setup for 8x8 color expand pattern fill - * - * HARDWARE_PATTERN_PROGRAMMED_BITS mean pattern in patternx,patterny - * HARDWARE_PATTERN_PROGRAMMED_ORIGIN is not supported by the chip - * the rotation is done on the fly during the load of the pattern into - * the SiS registers. - */ -static unsigned int sisPatternReg[4]; /* plus 2 for rotation */ -void SISSetupFor8x8PatternColorExpand(patternx, patterny, bg, fg, - rop, planemask) - unsigned patternx, patterny, planemask; - int bg, fg, rop; +static void +SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, + int fg, int bg, int rop, unsigned int planemask) { + SISPtr pSiS = SISPTR(pScrn); unsigned int *patternRegPtr ; int i ; int dstpitch; int isTransparent = ( bg == -1 ); - int op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT | - sisPATFG | sisSRCBG ; - - /*ErrorF("SISSetupFor8x8PatternColorExpand(%d %d %d %d %d %x)\n", - patternx, patterny, bg, fg, rop, planemask);*/ - sisBLTWAIT; - dstpitch = vga256InfoRec.displayWidth * vgaBytesPerPixel ; + + dstpitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8 ; /* * check transparency */ @@ -558,27 +229,22 @@ void SISSetupFor8x8PatternColorExpand(patternx, patterny, bg, fg, sisSETROPFG(0xf0); /* pat copy */ sisSETROPBG(0xcc); /* copy */ } - sisBLTWAIT; sisSETPITCH(0, dstpitch); sisSETSRCADDR(0); - sisColExp_op = op ; patternRegPtr = (unsigned int *)sisSETPATREG(); - sisPatternReg[0] = sisPatternReg[2] = patternx ; - sisPatternReg[1] = sisPatternReg[3] = patterny ; - for ( i = 0 ; i < sisPatternHeight ; ) { + pSiS->sisPatternReg[0] = pSiS->sisPatternReg[2] = patternx ; + pSiS->sisPatternReg[1] = pSiS->sisPatternReg[3] = patterny ; + for ( i = 0 ; i < 16 /* sisPatternHeight */ ; ) { patternRegPtr[i++] = patternx ; patternRegPtr[i++] = patterny ; } } -/* - * executing 8x8 color expand pattern fill - * reload the pattern in the SiS registers and do the rotation. - */ -void SISSubsequent8x8PatternColorExpand(patternx, patterny, x, y, w, h) - unsigned patternx, patterny; - int x, y, w, h; +static void +SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, + int patterny, int x, int y, int w, int h) { + SISPtr pSiS = SISPTR(pScrn); int dstaddr; register unsigned char *patternRegPtr ; register unsigned char *srcPatternRegPtr ; @@ -586,14 +252,12 @@ void SISSubsequent8x8PatternColorExpand(patternx, patterny, x, y, w, h) int i, k ; unsigned short tmp; int shift ; + int op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT | + sisPATFG | sisSRCBG ; - dstaddr = ( y * vga256InfoRec.displayWidth + x ) * vgaBytesPerPixel; - - /*ErrorF("SISSubsequent8x8PatternColorExpand(%d %d %d %d %d %d)\n", - patternx, patterny, x, y, w, h);*/ - sisBLTWAIT; + dstaddr = ( y * pScrn->displayWidth + x ) * pScrn->bitsPerPixel / 8; patternRegPtr = sisSETPATREG(); - srcPatternRegPtr = (unsigned char *)sisPatternReg ; + srcPatternRegPtr = (unsigned char *)pSiS->sisPatternReg ; shift = 8-patternx ; for ( i = 0, k = patterny ; i < 8 ; i++, k++ ) { tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ; @@ -601,18 +265,13 @@ void SISSubsequent8x8PatternColorExpand(patternx, patterny, x, y, w, h) patternRegPtr[i] = tmp & 0xff ; } patternRegPtrL = (unsigned int *)sisSETPATREG(); - for ( i = 2 ; i < sisPatternHeight ; ) { + for ( i = 2 ; i < 16 /* sisPatternHeight */; ) { patternRegPtrL[i++] = patternRegPtrL[0]; patternRegPtrL[i++] = patternRegPtrL[1]; } sisSETDSTADDR(dstaddr); - sisSETHEIGHTWIDTH(h-1, w*vgaBytesPerPixel-1); - sisSETCMD(sisColExp_op); + sisSETHEIGHTWIDTH(h-1, w*(pScrn->bitsPerPixel/8)-1); + sisSETCMD(op); + SiSSync(pScrn); } - - - - - - diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c b/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c new file mode 100644 index 000000000..f9f9d44e4 --- /dev/null +++ b/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c @@ -0,0 +1,534 @@ +/* + * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. + */ +/* $XFree86$ */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Version.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "vgaHW.h" + +#include "sis.h" +#include "sis_regs.h" + +static void +SiSCalcClock(int clock, int max_VLD, unsigned int *vclk) +{ + int M, N, P, PSN, VLD, PSNx; + int bestM, bestN, bestP, bestPSN, bestVLD; + double bestError, abest = 42.0, bestFout; + double target; + double Fvco, Fout; + double error, aerror; + + /* + * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler) + * + * M = Numerator [1:128] + * N = DeNumerator [1:32] + * VLD = Divider (Vco Loop Divider) : divide by 1, 2 + * P = Post Scaler : divide by 1, 2, 3, 4 + * PSN = Pre Scaler (Reference Divisor Select) + * + * result in vclk[] + */ +#define Midx 0 +#define Nidx 1 +#define VLDidx 2 +#define Pidx 3 +#define PSNidx 4 +#define Fref 14318180 +/* stability constraints for internal VCO -- MAX_VCO also determines + * the maximum Video pixel clock */ +#define MIN_VCO Fref +#define MAX_VCO 135000000 +#define MAX_VCO_5597 353000000 +#define MAX_PSN 0 /* no pre scaler for this chip */ +#define TOLERANCE 0.01 /* search smallest M and N in this tolerance */ + + int M_min = 2; + int M_max = 128; + +/* abest=10000.0; */ + + target = clock * 1000; + +#if 0 /* Implied at the moment */ + if (SISchipset == SIS5597 || SISchipset == SIS6326){ +#endif + { + int low_N = 2; + int high_N = 5; + int PSN = 1; + + P = 1; + if (target < MAX_VCO_5597 / 2) + P = 2; + if (target < MAX_VCO_5597 / 3) + P = 3; + if (target < MAX_VCO_5597 / 4) + P = 4; + if (target < MAX_VCO_5597 / 6) + P = 6; + if (target < MAX_VCO_5597 / 8) + P = 8; + + Fvco = P * target; + + for (N = low_N; N <= high_N; N++){ + double M_desired = Fvco / Fref * N; + if (M_desired > M_max * max_VLD) + continue; + + if ( M_desired > M_max ) { + M = M_desired / 2 + 0.5; + VLD = 2; + } else { + M = Fvco / Fref * N + 0.5; + VLD = 1; + }; + + Fout = (double)Fref * (M * VLD)/(N * P); + + error = (target - Fout) / target; + aerror = (error < 0) ? -error : error; +/* if (aerror < abest && abest > TOLERANCE) {*/ + if (aerror < abest) { + abest = aerror; + bestError = error; + bestM = M; + bestN = N; + bestP = P; + bestPSN = PSN; + bestVLD = VLD; + bestFout = Fout; + } + } + } +#if 0 + else { + for (PSNx = 0; PSNx <= MAX_PSN ; PSNx++) { + int low_N, high_N; + double FrefVLDPSN; + + PSN = !PSNx ? 1 : 4; + + low_N = 2; + high_N = 32; + + for ( VLD = 1 ; VLD <= max_VLD ; VLD++ ) { + + FrefVLDPSN = (double)Fref * VLD / PSN; + for (N = low_N; N <= high_N; N++) { + double tmp = FrefVLDPSN / N; + + for (P = 1; P <= 4; P++) { + double Fvco_desired = target * ( P ); + double M_desired = Fvco_desired / tmp; + + /* Which way will M_desired be rounded? + * Do all three just to be safe. + */ + int M_low = M_desired - 1; + int M_hi = M_desired + 1; + + if (M_hi < M_min || M_low > M_max) + continue; + + if (M_low < M_min) + M_low = M_min; + if (M_hi > M_max) + M_hi = M_max; + + for (M = M_low; M <= M_hi; M++) { + Fvco = tmp * M; + if (Fvco <= MIN_VCO) + continue; + if (Fvco > MAX_VCO) + break; + + Fout = Fvco / ( P ); + + error = (target - Fout) / target; + aerror = (error < 0) ? -error : error; + if (aerror < abest) { + abest = aerror; + bestError = error; + bestM = M; + bestN = N; + bestP = P; + bestPSN = PSN; + bestVLD = VLD; + bestFout = Fout; + } +#ifdef DEBUG1 + ErrorF("Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d," + " P=%d, PSN=%d\n", + (float)(clock / 1000.), M, N, P, VLD, PSN); + ErrorF("Freq. set: %.2f MHz\n", Fout / 1.0e6); +#endif + } + } + } + } + } + } +#endif + vclk[Midx] = bestM; + vclk[Nidx] = bestN; + vclk[VLDidx] = bestVLD; + vclk[Pidx] = bestP; + vclk[PSNidx] = bestPSN; +#ifdef DEBUG + ErrorF("Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n", + (float)(clock / 1000.), vclk[Midx], vclk[Nidx], vclk[VLDidx], + vclk[Pidx], vclk[PSNidx]); + ErrorF("Freq. set: %.2f MHz\n", bestFout / 1.0e6); + ErrorF("VCO Freq.: %.2f MHz\n", bestFout*bestP / 1.0e6); +#endif +#ifdef DEBUG1 + ErrorF("abest=%f\n", + abest); +#endif +} + +Bool +SiSInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + SISPtr pSiS = SISPTR(pScrn); + SISRegPtr pReg = &pSiS->ModeReg; + int vgaIOBase; + unsigned char temp; + int offset; + int clock = mode->Clock; + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + offset = pScrn->displayWidth >> (mode->Flags & V_INTERLACE ? 2 : 3); + + outb(0x3C4, 0x05); /* Unlock Registers */ + temp = inb(0x3C5); + outw(0x3C4, 0x8605); + + outb(0x3C4, BankReg); + pReg->sisRegs3C4[BankReg] |= 0x82; /* Enable Linear */ + + switch (pScrn->depth) { + case 15: + offset <<= 1; + pReg->sisRegs3C4[BankReg] |= 0x04; + break; + case 16: + offset <<= 1; + pReg->sisRegs3C4[BankReg] |= 0x08; + break; + case 24: + offset += (offset << 1); + pReg->sisRegs3C4[BankReg] |= 0x80; + break; + } + + pReg->sisRegs3C4[LinearAdd0] = (pSiS->FbAddress & 0x07F80000) >> 19; + pReg->sisRegs3C4[LinearAdd1] = ((pSiS->FbAddress & 0xF8000000) >> 27) | 0x60; + pReg->sisRegs3x4[Offset] = offset & 0xFF; + pReg->sisRegs3C4[CRTCOff] = ((offset & 0xF00) >> 4) | + (((mode->CrtcVTotal-2) & 0x400) >> 10 ) | + (((mode->CrtcVDisplay-1) & 0x400) >> 9 ) | + ((mode->CrtcVSyncStart & 0x400) >> 8 ) | + (((mode->CrtcVSyncStart) & 0x400) >> 7 ) ; + + { + unsigned int vclk[5]; + unsigned char xr2a, xr2b; + + SiSCalcClock(clock, 2, vclk); + + xr2a = (vclk[Midx] - 1) & 0x7f ; + xr2a |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ; + xr2b = (vclk[Nidx] -1) & 0x1f ; /* bits [4:0] contain denumerator -MC */ + + outb(0x3C4, ClockBase); + pReg->sisRegs3C4[ClockBase] = inb(0x3C5); + if (vclk[Pidx] <= 4){ + xr2b |= (vclk[Pidx] -1 ) << 5 ; /* postscale 1,2,3,4 */ + pReg->sisRegs3C4[ClockBase] &= 0xBF; + } else { + xr2b |= ((vclk[Pidx] / 2) -1 ) << 5 ; /* postscale 6,8 */ + pReg->sisRegs3C4[ClockBase] |= 0x40; + }; + xr2b |= 0x80 ; /* gain for high frequency */ + + pReg->sisRegs3C4[XR2A] = xr2a; + pReg->sisRegs3C4[XR2B] = xr2b; + pReg->sisRegs3C2[0x00] = inb(0x3CC) | 0x0C; + } + + if (!pSiS->NoAccel) { + outb(0x3C4, GraphEng); + pReg->sisRegs3C4[GraphEng] = inb(0x3C5) | 0x70; + outb(0x3C4, Mode64); + pReg->sisRegs3C4[Mode64] = inb(0x3C5) | 0x80; + outb(0x3C4, MMIOEnable); + pReg->sisRegs3C4[MMIOEnable] = inb(0x3C5) | 0x60; /* At PCI base */ + } + + outw(0x3C4, (temp << 8) | 0x05); /* Relock Registers */ + return(TRUE); +} + +void +SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg) +{ + SISPtr pSiS = SISPTR(pScrn); + int i; + int vgaIOBase; + unsigned char temp; + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + outb(0x3C4, 0x05); /* Unlock Registers */ + temp = inb(0x3C5); + outw(0x3C4, 0x8605); + outw(0x3C4, (sisReg->sisRegs3C4[BankReg] << 8) | BankReg); + outw(0x3C4, (sisReg->sisRegs3C4[LinearAdd0] << 8) | LinearAdd0); + outw(0x3C4, (sisReg->sisRegs3C4[LinearAdd1] << 8) | LinearAdd1); + outw(vgaIOBase + 4, (sisReg->sisRegs3x4[Offset] << 8) | Offset); + outw(0x3C4, (sisReg->sisRegs3C4[CRTCOff] << 8) | CRTCOff); + + outw(0x3C4, (sisReg->sisRegs3C4[XR2A] << 8) | XR2A); + outw(0x3C4, (sisReg->sisRegs3C4[XR2B] << 8) | XR2B); + outw(0x3C4, (sisReg->sisRegs3C4[ClockBase] << 8) | ClockBase); + outb(0x3C2, sisReg->sisRegs3C2[0x00]); + + if (!pSiS->NoAccel) { + outw(0x3C4, (sisReg->sisRegs3C4[GraphEng] << 8) | GraphEng); + outw(0x3C4, (sisReg->sisRegs3C4[Mode64] << 8) | Mode64); + outw(0x3C4, (sisReg->sisRegs3C4[MMIOEnable] << 8) | MMIOEnable); + } + + + outw(0x3C4, (temp << 8) | 0x05); /* Relock Registers */ +} + +void +SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg) +{ + SISPtr pSiS = SISPTR(pScrn); + int i; + int vgaIOBase; + unsigned char temp; + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + outb(0x3C4, 0x05); /* Unlock Registers */ + temp = inb(0x3C5); + outw(0x3C4, 0x8605); + outb(0x3C4, BankReg); + sisReg->sisRegs3C4[BankReg] = inb(0x3C5); + outb(0x3C4, LinearAdd0); + sisReg->sisRegs3C4[LinearAdd0] = inb(0x3C5); + outb(0x3C4, LinearAdd1); + sisReg->sisRegs3C4[LinearAdd1] = inb(0x3C5); + outb(vgaIOBase + 4, Offset); + sisReg->sisRegs3x4[Offset] = inb(0x3C5); + outb(0x3C4, CRTCOff); + sisReg->sisRegs3C4[CRTCOff] = inb(0x3C5); + + sisReg->sisRegs3C2[0x00] = inb(0x3CC); + outb(0x3C4, ClockBase); + sisReg->sisRegs3C4[ClockBase] = inb(0x3C5); + outb(0x3C4, XR2A); + sisReg->sisRegs3C4[XR2A] = inb(0x3C5); + outb(0x3C4, XR2B); + sisReg->sisRegs3C4[XR2B] = inb(0x3C5); + + if (!pSiS->NoAccel) { + outb(0x3C4, GraphEng); + sisReg->sisRegs3C4[GraphEng] = inb(0x3C5); + outb(0x3C4, Mode64); + sisReg->sisRegs3C4[Mode64] = inb(0x3C5); + outb(0x3C4, MMIOEnable); + sisReg->sisRegs3C4[MMIOEnable] = inb(0x3C5); + } + + outw(0x3C4, (temp << 8) | 0x05); /* Relock Registers */ +} + +#if 0 +static void +TridentShowCursor(ScrnInfoPtr pScrn) +{ + int vgaIOBase; + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + /* 64x64 */ + outw(vgaIOBase + 4, 0xC150); +} + +static void +TridentHideCursor(ScrnInfoPtr pScrn) { + int vgaIOBase; + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + outw(vgaIOBase + 4, 0x4150); +} + +static void +TridentSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + int vgaIOBase; + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + if (x < 0) { + outw(vgaIOBase + 4, (-x)<<8 | 0x46); + x = 0; + } else + outw(vgaIOBase + 4, 0x0046); + + if (y < 0) { + outw(vgaIOBase + 4, (-y)<<8 | 0x47); + y = 0; + } else + outw(vgaIOBase + 4, 0x0047); + + outw(vgaIOBase + 4, (x&0xFF)<<8 | 0x40); + outw(vgaIOBase + 4, (x&0xFF00) | 0x41); + outw(vgaIOBase + 4, (y&0xFF)<<8 | 0x42); + outw(vgaIOBase + 4, (y&0xFF00) | 0x43); +} + +static void +TridentSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + int vgaIOBase; + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + outw(vgaIOBase + 4, (fg & 0x000000FF)<<8 | 0x48); + outw(vgaIOBase + 4, (fg & 0x0000FF00) | 0x49); + outw(vgaIOBase + 4, (fg & 0x00FF0000)>>8 | 0x4A); + outw(vgaIOBase + 4, (fg & 0xFF000000)>>16 | 0x4B); + outw(vgaIOBase + 4, (bg & 0x000000FF)<<8 | 0x4C); + outw(vgaIOBase + 4, (bg & 0x0000FF00) | 0x4D); + outw(vgaIOBase + 4, (bg & 0x00FF0000)>>8 | 0x4E); + outw(vgaIOBase + 4, (bg & 0xFF000000)>>16 | 0x4F); +} + +static void +TridentLoadCursorImage( + ScrnInfoPtr pScrn, + unsigned char *src +) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase; + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; + + memcpy((unsigned char *)pTrident->FbBase + (pScrn->videoRam * 1024) - 4096, + src, pTrident->CursorInfoRec->MaxWidth * + pTrident->CursorInfoRec->MaxHeight / 4); + + outw(vgaIOBase + 4, (((pScrn->videoRam-4) & 0xFF) << 8) | 0x44); + outw(vgaIOBase + 4, ((pScrn->videoRam-4) & 0xFF00) | 0x45); +} + +static Bool +TridentUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->MUX && pScrn->bitsPerPixel == 8) return FALSE; + + return TRUE; +} + +Bool +TridentHWCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + xf86CursorInfoPtr infoPtr; + int memory = pScrn->displayWidth * pScrn->virtualY * pScrn->bitsPerPixel/8; + + if (memory > (pScrn->videoRam * 1024 - 4096)) return FALSE; + infoPtr = xf86CreateCursorInfoRec(); + if(!infoPtr) return FALSE; + + pTrident->CursorInfoRec = infoPtr; + + infoPtr->MaxWidth = 64; + infoPtr->MaxHeight = 64; + infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32; + infoPtr->SetCursorColors = TridentSetCursorColors; + infoPtr->SetCursorPosition = TridentSetCursorPosition; + infoPtr->LoadCursorImage = TridentLoadCursorImage; + infoPtr->HideCursor = TridentHideCursor; + infoPtr->ShowCursor = TridentShowCursor; + infoPtr->UseHWCursor = TridentUseHWCursor; + + return(xf86InitCursor(pScreen, infoPtr)); +} + +unsigned int +Tridentddc1Read(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + unsigned char temp; + + /* New mode */ + outb(0x3C4, 0x0B); inb(0x3C5); + + outb(vgaIOBase + 4, NewMode1); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp | 0x80); + + /* Define SDA as input */ + outw(vgaIOBase + 4, (0x04 << 8) | I2C); + + outw(vgaIOBase + 4, (temp << 8) | NewMode1); + + /* Wait until vertical retrace is in progress. */ + while (inb(vgaIOBase + 0xA) & 0x08); + while (!(inb(vgaIOBase + 0xA) & 0x08)); + + /* Get the result */ + outb(vgaIOBase + 4, I2C); + return ( inb(vgaIOBase + 5) & 0x01 ); +} +#endif diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c b/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c index 7d96f1450..a59315fe7 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c +++ b/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c @@ -1,6 +1,5 @@ -/* $XConsortium: sis86c201.c /main/11 1996/10/27 13:24:11 kaleb $ */ /* - * Copyright 1995 by Alan Hourihane, Wigan, England. + * Copyright 1998,1999 by Alan Hourihane, Wigan, England. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -20,1534 +19,1508 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Author: Alan Hourihane, alanh@fairlite.demon.co.uk - * - * Modified 1996 by Xavier Ducoin <xavier@rd.lectra.fr> - * + * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.8 1998/01/24 16:58:22 hohndel Exp $ */ - -/*#define DEBUG*/ -/*#define IO_DEBUG*/ +/* $XFree86$ */ + +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#include "xf1bpp.h" +#include "xf4bpp.h" +#include "mibank.h" +#include "micmap.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Version.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86cmap.h" +#include "vgaHW.h" -/*#define USE_XAA*/ -#include "X.h" -#include "input.h" -#include "screenint.h" -#include "dix.h" +#include "mipointer.h" -#include "compiler.h" +#include "mibstore.h" -#include "xf86.h" -#include "xf86Version.h" -#include "xf86Priv.h" -#include "xf86_ansic.h" -#include "xf86_HWlib.h" -#define XCONFIG_FLAGS_ONLY -#include "xf86_Config.h" -#include "vga.h" -#include "vgaPCI.h" +#include "sis_regs.h" +#include "sis.h" #ifdef XFreeXDGA -#include "X.h" -#include "Xproto.h" -#include "scrnintstr.h" -#include "servermd.h" #define _XF86DGA_SERVER_ #include "extensions/xf86dgastr.h" #endif -#include "vga256.h" -#include "sis_driver.h" -#define SIS86C201 0 -#define SIS86C202 1 -#define SIS86C205 2 +#ifdef DPMSExtension +#include "globals.h" +#include "extensions/dpms.h" +#endif + +static void SISIdentify(int flags); +static Bool SISProbe(DriverPtr drv, int flags); +static Bool SISPreInit(ScrnInfoPtr pScrn, int flags); +static Bool SISScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool SISEnterVT(int scrnIndex, int flags); +static void SISLeaveVT(int scrnIndex, int flags); +static Bool SISCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool SISSaveScreen(ScreenPtr pScreen, Bool unblank); + +/* Required if the driver supports mode switching */ +static Bool SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +/* Required if the driver supports moving the viewport */ +static void SISAdjustFrame(int scrnIndex, int x, int y, int flags); + +/* Optional functions */ +static void SISFreeScreen(int scrnIndex, int flags); +static int SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, + int flags); + +/* Internally used functions */ +static Bool SISMapMem(ScrnInfoPtr pScrn); +static Bool SISUnmapMem(ScrnInfoPtr pScrn); +static void SISSave(ScrnInfoPtr pScrn); +static void SISRestore(ScrnInfoPtr pScrn); +static Bool SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); + +#define VERSION 4000 +#define SIS_NAME "SIS" +#define SIS_DRIVER_NAME "sis" +#define SIS_MAJOR_VERSION 1 +#define SIS_MINOR_VERSION 0 +#define SIS_PATCHLEVEL 0 + +/* + * This contains the functions needed by the server after loading the driver + * module. It must be supplied, and gets passed back by the ModuleInit + * function in the dynamic case. In the static case, a reference to this + * is compiled in, and this requires that the name of this DriverRec be + * an upper-case version of the driver name. + */ + +DriverRec SIS = { + VERSION, + "accelerated driver for SiS chipsets", + SISIdentify, + SISProbe, + NULL, + 0 +}; -extern vgaHWCursorRec vgaHWCursor; +static SymTabRec SISChipsets[] = { + { PCI_CHIP_SIS6326, "sis6326" }, + { -1, NULL } +}; -/* Blitter related */ -/*address in video ram of tile/stipple pattern*/ -unsigned int sisBLTPatternAddress = -1; -int sisBLTPatternOffscreenSize = 0 ; -unsigned char *sisBltDataWindow = NULL; -Bool sisAvoidImageBLT = FALSE; +static PciChipsets SISPciChipsets[] = { + { PCI_CHIP_SIS6326, PCI_CHIP_SIS6326, RES_SHARED_VGA }, + { -1, -1, RES_UNDEFINED } +}; + +typedef enum { + OPTION_SW_CURSOR, + OPTION_HW_CURSOR, + OPTION_PCI_RETRY, + OPTION_RGB_BITS, + OPTION_NOACCEL +} SISOpts; + +static OptionInfoRec SISOptions[] = { + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_RGB_BITS, "rgbbits", OPTV_INTEGER, {0}, -1 }, + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; int sisReg32MMIO[]={0x8280,0x8284,0x8288,0x828C,0x8290,0x8294,0x8298,0x829C, 0x82A0,0x82A4,0x82A8,0x82AC}; -extern GCOps cfb16TEOps1Rect, cfb16TEOps, cfb16NonTEOps1Rect, cfb16NonTEOps; -extern GCOps cfb24TEOps1Rect, cfb24TEOps, cfb24NonTEOps1Rect, cfb24NonTEOps; - -Bool sisHWCursor = FALSE ; - -/* Clock related */ -typedef struct { - unsigned char msr; - unsigned char xr2A; - unsigned char xr2B; - int Clock; -} sisClockReg, *sisClockPtr; - -typedef struct { - vgaHWRec std; /* std IBM VGA register */ - unsigned char Port_3C4[0x38]; - unsigned char ClockReg2; - sisClockReg sisClock; -} vgaSISRec, *vgaSISPtr; - -/* alias for specific extended registers */ -#define ClockReg Port_3C4[0x07] -#define DualBanks Port_3C4[0x0B] -#define BankReg Port_3C4[0x06] -#define CRTCOff Port_3C4[0x0A] -#define DispCRT Port_3C4[0x27] -#define Unknown Port_3C4[0x08] -#define LinearAddr0 Port_3C4[0x20] -#define LinearAddr1 Port_3C4[0x21] - -static Bool SISClockSelect(); -static char *SISIdent(); -static Bool SISProbe(); -static void SISEnterLeave(); -static Bool SISInit(); -static int SISValidMode(); -static void *SISSave(); -static void SISRestore(); -static void SISFbInit(); -static void SISAdjust(); -static void SISDisplayPowerManagementSet(); -extern void SISSetRead(); -extern void SISSetWrite(); -extern void SISSetReadWrite(); - -extern int SISCursorHotX; -extern int SISCursorHotY; -extern int SISCursorWidth; -extern int SISCursorHeight; - -extern Bool SISCursorInit(); -extern void SISRestoreCursor(); -extern void SISWarpCursor(); -extern void SISQueryBestSize(); - -vgaVideoChipRec SIS = { - SISProbe, - SISIdent, - SISEnterLeave, - SISInit, - SISValidMode, - SISSave, - SISRestore, - SISAdjust, - vgaHWSaveScreen, - (void (*)())NoopDDA, - SISFbInit, - SISSetRead, - SISSetWrite, - SISSetReadWrite, - 0x10000, - 0x10000, - 16, - 0xffff, - 0x00000, 0x10000, - 0x00000, 0x10000, - TRUE, - VGA_DIVIDE_VERT, - {0,}, - 16, - FALSE, - 0, - 0, - /* - * This is TRUE if the driver has support for the given depth for - * the detected configuration. It must be set in the Probe function. - * It most cases it should be FALSE. - */ - TRUE, /* 1bpp */ - TRUE, /* 4bpp */ - TRUE, /* 8bpp */ - FALSE, /* 15bpp */ - TRUE, /* 16bpp */ - TRUE, /* 24bpp */ - FALSE, /* 32bpp */ - NULL, - 1, /* ClockMulFactor */ - 1 /* ClockDivFactor */ + +static const char *xaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + "XAAStippleScanlineFuncLSBFirst", + "XAAOverlayFBfuncs", + "XAACachePlanarMonoStipple", + "XAAScreenIndex", + NULL +}; + +static const char *vgahwSymbols[] = { + "vgaHWGetHWRec", + "vgaHWUnlock", + "vgaHWInit", + "vgaHWProtect", + "vgaHWGetIOBase", + "vgaHWMapMem", + "vgaHWLock", + "vgaHWFreeHWRec", + "vgaHWSaveScreen", + NULL }; -#define new ((vgaSISPtr)vgaNewVideoState) +static const char *fbSymbols[] = { + "xf1bppScreenInit", + "xf4bppScreenInit", + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + NULL +}; + +static const char *racSymbols[] = { + "xf86RACInit", + NULL +}; -int SISchipset; -/* default is enhanced mode (use option to disable)*/ -Bool sisUseLinear = TRUE; -Bool sisUseMMIO = TRUE; -Bool sisUseXAAcolorExp = TRUE; -static int SISDisplayableMemory; -unsigned char *sisMMIOBase = NULL; -unsigned long PCIMMIOBase=0; +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86DoEDID_DDC1", + NULL +}; +static const char *i2cSymbols[] = { + "xf86I2CBusInit", + "xf86CreateI2CBusRec", + NULL +}; #ifdef XFree86LOADER -XF86ModuleVersionInfo sisVersRec = + +MODULEINITPROTO(sisModuleInit); +static MODULESETUPPROTO(sisSetup); + +static XF86ModuleVersionInfo sisVersRec = { - "sis_drv.o", + "sis", MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, XF86_VERSION_CURRENT, - 0x00010001, + SIS_MAJOR_VERSION, SIS_MINOR_VERSION, SIS_PATCHLEVEL, + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + NULL, {0,0,0,0} }; /* - * this function returns the vgaVideoChipPtr for this driver + * This function is the magic init function for XFree86 modules. + * It adds the DriverRec to the list of available drivers. * - * its name has to be ModuleInit() + * Its name has to be the driver name followed by ModuleInit() */ void -ModuleInit(data,magic) - pointer * data; - INT32 * magic; +sisModuleInit(XF86ModuleVersionInfo **vers, ModuleSetupProc *setup, + ModuleTearDownProc *teardown) { - static int cnt = 0; - - switch(cnt++) - { - /* MAGIC_VERSION must be first in ModuleInit */ - case 0: - * data = (pointer) &sisVersRec; - * magic= MAGIC_VERSION; - break; - case 1: - * data = (pointer)&SIS; - * magic= MAGIC_ADD_VIDEO_CHIP_REC; - break; - default: - xf86issvgatype = TRUE; /* later load the correct libvgaxx.a */ - * magic= MAGIC_DONE; - break; - } + *vers = &sisVersRec; + *setup = sisSetup; + *teardown = NULL; +} - return; +pointer +sisSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&SIS, module, 0); + LoaderRefSymLists(vgahwSymbols, fbSymbols, racSymbols, i2cSymbols, + xaaSymbols, NULL); + return (pointer)TRUE; + } + + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; } + #endif /* XFree86LOADER */ -/* - * SISIdent -- - */ -static char * -SISIdent(n) - int n; +static Bool +SISGetRec(ScrnInfoPtr pScrn) { - static char *chipsets[] = {"sis86c201", "sis86c202", "sis86c205", }; + /* + * Allocate an SISRec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + if (pScrn->driverPrivate != NULL) + return TRUE; - if (n + 1 > sizeof(chipsets) / sizeof(char *)) - return(NULL); - else - return(chipsets[n]); + pScrn->driverPrivate = xnfcalloc(sizeof(SISRec), 1); + /* Initialise it */ + + return TRUE; } -/* - * SISClockSelect -- - * select one of the possible clocks ... - */ -static Bool -SISClockSelect(no) - int no; +static void +SISFreeRec(ScrnInfoPtr pScrn) { - static unsigned char save1, save2; - unsigned char temp; -#ifdef DEBUG - ErrorF("SISClockSelect(%d)\n",no); + if (pScrn->driverPrivate == NULL) + return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} + +#ifdef DPMSExtension +static void +SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) +{ + unsigned char DPMSCont, PMCont, temp; + +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); #endif - /* - * CS0 and CS1 are in MiscOutReg - * - * CS2,CS3,CS4 are in 0x3C4 index 7 - * But - only active when CS0/CS1 are set. - */ - switch(no) + outb(0x3C4, 0x0E); + temp = inb(0x3C5); + outb(0x3C5, 0xC2); + outb(0x83C8, 0x04); /* Read DPMS Control */ + PMCont = inb(0x83C6) & 0xFC; + outb(0x3CE, 0x23); + DPMSCont = inb(0x3CF) & 0xFC; + switch (PowerManagementMode) { - case CLK_REG_SAVE: - save1 = inb(0x3CC); - outb(0x3C4, 0x07); - save2 = inb(0x3C5); + case DPMSModeOn: + /* Screen: On, HSync: On, VSync: On */ + PMCont |= 0x03; + DPMSCont |= 0x00; break; - case CLK_REG_RESTORE: - outb(0x3C2, save1); - outw(0x3C4, (save2 << 8) | 0x07); + case DPMSModeStandby: + /* Screen: Off, HSync: Off, VSync: On */ + PMCont |= 0x02; + DPMSCont |= 0x01; + break; + case DPMSModeSuspend: + /* Screen: Off, HSync: On, VSync: Off */ + PMCont |= 0x02; + DPMSCont |= 0x02; + break; + case DPMSModeOff: + /* Screen: Off, HSync: Off, VSync: Off */ + PMCont |= 0x00; + DPMSCont |= 0x03; break; - default: - /* - * Do CS0 and CS1 and set them - makes index 7 valid - */ - temp = inb(0x3CC); - temp &= ~0x0C ; - if ( no >= 2 ) { - outb(0x3C2, temp | 0x0C); - outw(0x3C4, (no << 8) | 0x07); - } - else /* using vga clock */ - outb(0x3C2, temp | ( (no<<2) & 0x0C) ); - } - return(TRUE); -} + outb(0x3CF, DPMSCont); + outb(0x83C8, 0x04); + outb(0x83C6, PMCont); + outw(0x3C4, (temp<<8) | 0x0E); -#define write_xr(num,val) {outb(0x3C4, num);outb(0x3C5, val);} -#define read_xr(num,var) {outb(0x3C4, num);var=inb(0x3C5);} +#if 0 + xf86DelControlledResource(&pScrn->Access, FALSE); +#endif +} +#endif -static Bool -ClockProgramable() +/* Mandatory */ +static void +SISIdentify(int flags) { - if (vgaBitsPerPixel < 8) - return FALSE; - else - return (OFLG_ISSET(CLOCK_OPTION_PROGRAMABLE, - &vga256InfoRec.clockOptions)) ; + xf86PrintChipsets(SIS_NAME, "driver for SiS chipsets", SISChipsets); } static void -sisCalcClock(int Clock, unsigned int *vclk) +SIS1bppColorMap(ScrnInfoPtr pScrn) { +/* In 1 bpp we have color 0 at LUT 0 and color 1 at LUT 0x3f. + This makes white and black look right (otherwise they were both + black. I'm sure there's a better way to do that, just lazy to + search the docs. */ + +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); +#endif + outb(0x3C8, 0x00); outb(0x3C9, 0x00); outb(0x3C9, 0x00); outb(0x3C9, 0x00); + outb(0x3C8, 0x3F); outb(0x3C9, 0x3F); outb(0x3C9, 0x3F); outb(0x3C9, 0x3F); +#if 0 + xf86DelControlledResource(&pScrn->Access,FALSE); +#endif +} + +/* Mandatory */ +static Bool +SISProbe(DriverPtr drv, int flags) { - int M, N, P, PSN, VLD, PSNx; + int i; + pciVideoPtr pPci, *usedPci; + GDevPtr *devSections; + GDevPtr *usedDevs; + int *usedChips; + int numDevSections; + int numUsed; + BusResource resource; + Bool foundScreen = FALSE; - int bestM, bestN, bestP, bestPSN, bestVLD; - double bestError, abest = 42, bestFout; - double target; + /* + * The aim here is to find all cards that this driver can handle, + * and for the ones not already claimed by another driver, claim the + * slot, and allocate a ScrnInfoRec. + * + * This should be a minimal probe, and it should under no circumstances + * change the state of the hardware. Because a device is found, don't + * assume that it will be used. Don't do any initialisations other than + * the required ScrnInfoRec initialisations. Don't allocate any new + * data structures. + * + * Since this test version still uses vgaHW, we'll only actually claim + * one for now, and just print a message about the others. + */ - double Fvco, Fout; - double error, aerror; + /* + * Next we check, if there has been a chipset override in the config file. + * For this we must find out if there is an active device section which + * is relevant, i.e., which has no driver specified or has THIS driver + * specified. + */ + if ((numDevSections = xf86MatchDevice(SIS_DRIVER_NAME, + &devSections)) <= 0) { + /* + * There's no matching device section in the config file, so quit + * now. + */ + return FALSE; + } + /* + * While we're VGA-dependent, can really only have one such instance, but + * we'll ignore that. + */ /* - * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler) - * - * M = Numerator [1:128] - * N = DeNumerator [1:32] - * VLD = Divider (Vco Loop Divider) : divide by 1, 2 - * P = Post Scaler : divide by 1, 2, 3, 4 - * PSN = Pre Scaler (Reference Divisor Select) - * - * result in vclk[] + * We need to probe the hardware first. We then need to see how this + * fits in with what is given in the config file, and allow the config + * file info to override any contradictions. */ -#define Midx 0 -#define Nidx 1 -#define VLDidx 2 -#define Pidx 3 -#define PSNidx 4 -#define Fref 14318180 -/* stability constraints for internal VCO -- MAX_VCO also determines - * the maximum Video pixel clock */ -#define MIN_VCO Fref -#define MAX_VCO 135000000 -#define MAX_VLD 2 -#define MAX_PSN 0 /* no pre scaler for this chip */ - - int M_min = 2; - int M_max = 128; - - target = Clock * 1000; - - for (PSNx = 0; PSNx <= MAX_PSN ; PSNx++) { - int low_N, high_N; - double FrefVLDPSN; - - PSN = !PSNx ? 1 : 4; - - low_N = 2; - high_N = 32; - - for ( VLD = 1 ; VLD <= MAX_VLD ; VLD++ ) { - - FrefVLDPSN = (double)Fref * VLD / PSN; - for (N = low_N; N <= high_N; N++) { - double tmp = FrefVLDPSN / N; - - for (P = 1; P <= 4; P++) { - double Fvco_desired = target * ( P ); - double M_desired = Fvco_desired / tmp; - - /* Which way will M_desired be rounded? - * Do all three just to be safe. - */ - int M_low = M_desired - 1; - int M_hi = M_desired + 1; - - if (M_hi < M_min || M_low > M_max) - continue; - - if (M_low < M_min) - M_low = M_min; - if (M_hi > M_max) - M_hi = M_max; - - for (M = M_low; M <= M_hi; M++) { - Fvco = tmp * M; - if (Fvco <= MIN_VCO) - continue; - if (Fvco > MAX_VCO) - break; - - Fout = Fvco / ( P ); - - error = (target - Fout) / target; - aerror = (error < 0) ? -error : error; - if (aerror < abest) { - abest = aerror; - bestError = error; - bestM = M; - bestN = N; - bestP = P; - bestPSN = PSN; - bestVLD = VLD; - bestFout = Fout; - } -#ifdef DEBUG1 - ErrorF("Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d," - " P=%d, PSN=%d\n", - (float)(Clock / 1000.), M, N, P, VLD, PSN); - ErrorF("Freq. set: %.2f MHz\n", Fout / 1.0e6); -#endif - } - } - } + + /* + * All of the cards this driver supports are PCI, so the "probing" just + * amounts to checking the PCI data that the server has already collected. + */ + if (xf86GetPciVideoInfo() == NULL) { + /* + * We won't let anything in the config file override finding no + * PCI video cards at all. This seems reasonable now, but we'll see. + */ + return FALSE; + } + + numUsed = xf86MatchPciInstances(SIS_NAME, PCI_VENDOR_SIS, + SISChipsets, SISPciChipsets, devSections, + numDevSections, &usedDevs, &usedPci, &usedChips); + + /* Free it since we don't need that list after this */ + xfree(devSections); + devSections = NULL; + if (numUsed <= 0) + return FALSE; + + for (i = 0; i < numUsed; i++) { + pPci = usedPci[i]; + resource = xf86FindPciResource(usedChips[i], SISPciChipsets); + + /* + * Check that nothing else has claimed the slots. + */ + + if (xf86CheckPciSlot(pPci->bus, pPci->device, pPci->func, resource)) { + ScrnInfoPtr pScrn; + + /* Allocate a ScrnInfoRec and claim the slot */ + pScrn = xf86AllocateScreen(drv, 0); + xf86ClaimPciSlot(pPci->bus, pPci->device, pPci->func, resource, + &SIS, usedChips[i], pScrn->scrnIndex); + + /* Fill in what we can of the ScrnInfoRec */ + pScrn->driverVersion = VERSION; + pScrn->driverName = SIS_DRIVER_NAME; + pScrn->name = SIS_NAME; + pScrn->Probe = SISProbe; + pScrn->PreInit = SISPreInit; + pScrn->ScreenInit = SISScreenInit; + pScrn->SwitchMode = SISSwitchMode; + pScrn->AdjustFrame = SISAdjustFrame; + pScrn->EnterVT = SISEnterVT; + pScrn->LeaveVT = SISLeaveVT; + pScrn->FreeScreen = SISFreeScreen; + pScrn->ValidMode = SISValidMode; + pScrn->device = usedDevs[i]; + foundScreen = TRUE; } } - vclk[Midx] = bestM; - vclk[Nidx] = bestN; - vclk[VLDidx] = bestVLD; - vclk[Pidx] = bestP; - vclk[PSNidx] = bestPSN; -#ifdef DEBUG - ErrorF("Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n", - (float)(Clock / 1000.), vclk[Midx], vclk[Nidx], vclk[VLDidx], - vclk[Pidx], vclk[PSNidx]); - ErrorF("Freq. set: %.2f MHz\n", bestFout / 1.0e6); -#endif + xfree(usedDevs); + xfree(usedPci); + return foundScreen; } - -static void -sisClockSave(Clock) - sisClockPtr Clock; + +/* + * GetAccelPitchValues - + * + * This function returns a list of display width (pitch) values that can + * be used in accelerated mode. + */ +static int * +GetAccelPitchValues(ScrnInfoPtr pScrn) { -#ifdef DEBUG - ErrorF("sisClockSave(Clock)\n"); +#if 0 + SISPtr pSiS = SISPTR(pScrn); #endif - Clock->msr = (inb(0x3CC) & 0xFE); /* save the standard VGA clock - * registers */ - read_xr(0x2A, Clock->xr2A); - read_xr(0x2B, Clock->xr2B); - -} - -static void -sisClockRestore(Clock) - sisClockPtr Clock; -{ -#ifdef DEBUG - ErrorF("sisClockRestore(Clock)\n"); + int *linePitches = NULL; + int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */ +#if 0 + int lines[sizeof(AvailablePitches[pSiS->Chipset])] = + AvailablePitches[pSiS->Chipset]; #endif - outb(0x3C2, Clock->msr); - write_xr(0x2A, Clock->xr2A); - write_xr(0x2B, Clock->xr2B); + int i, n = 0; + + for (i = 0; i < 4; i++) { + n++; + linePitches = xnfrealloc(linePitches, n * sizeof(int)); + linePitches[n - 1] = lines[i]; + } + /* Mark the end of the list */ + if (n > 0) { + linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int)); + linePitches[n] = 0; + } + return linePitches; } +/* Mandatory */ static Bool -sisClockFind(no, Clock) - int no; - sisClockPtr Clock; +SISPreInit(ScrnInfoPtr pScrn, int flags) { - int clock ; + pciVideoPtr *pciList = NULL; + SISPtr pSiS; + MessageType from; + unsigned char videoram; + char *ramtype = NULL, *chipset = NULL; + Bool Support24bpp; + int vgaIOBase; + float mclk; + int i,j; + unsigned char revision; + ClockRangePtr clockRanges; + char *mod = NULL; + const char *Sym; + + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); + + /* + * Note: This function is only called once at server startup, and + * not at the start of each server generation. This means that + * only things that are persistent across server generations can + * be initialised here. xf86Screens[] is (pScrn is a pointer to one + * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() + * are too, and should be used for data that must persist across + * server generations. + * + * Per-generation data should be allocated with + * AllocateScreenPrivateIndex() from the ScreenInit() function. + */ - clock = vga256InfoRec.clock[no] ; -#ifdef DEBUG - ErrorF("sisClockFind(%d %d)\n",no,clock); -#endif + /* The vgahw module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; - if (no > (vga256InfoRec.clocks - 1)) - return (FALSE); + xf86LoaderReqSymLists(vgahwSymbols, NULL); - Clock->Clock = clock; + /* + * Allocate a vgaHWRec + */ + if (!vgaHWGetHWRec(pScrn)) + return FALSE; - return (TRUE); -} + VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */ -static void -sisClockLoad(Clock) - sisClockPtr Clock; -{ - unsigned int vclk[5]; - unsigned char temp, xr2a, xr2b; -#ifdef DEBUG - ErrorF("sisClockLoad(Clock)\n"); -#endif + if (!vgaHWMapMem(pScrn)) + return FALSE; + vgaHWGetIOBase(VGAHWPTR(pScrn)); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; - if (!Clock->Clock) { /* Hack to load saved console clock */ - sisClockRestore(Clock) ; + /* The ramdac module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "ramdac")) + return FALSE; + + /* Set pScrn->monitor */ + pScrn->monitor = pScrn->confScreen->monitor; + + /* + * The first thing we should figure out is the depth, bpp, etc. + * Our default depth is 8, so pass it to the helper function. + * Our preference for depth 24 is 24bpp, so tell it that too. + */ + if (!xf86SetDepthBpp(pScrn, 8, 0, 0, Support24bppFb | Support32bppFb)) { + return FALSE; + } else { + /* Check that the returned depth is one we support */ + switch (pScrn->depth) { + case 1: + case 4: + case 8: + case 15: + case 16: + case 24: + /* OK */ + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by this driver\n", + pScrn->depth); + return FALSE; + } } - else { - sisCalcClock(Clock->Clock, vclk); - - xr2a = (vclk[Midx] - 1) & 0x7f ; - xr2a |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ; - xr2b = (vclk[Nidx] -1) & 0x1f ; - xr2b |= (vclk[Pidx] -1 ) << 5 ; - /*xr2b |= 0x80 ;*/ /* gain for high frequency */ - - write_xr(0x2A, xr2a ); - write_xr(0x2B, xr2b ); -#ifdef DEBUG - ErrorF("xr2a=%2x xr2b=%2x\n",xr2a, xr2b); -#endif + + /* + * This must happen after pScrn->display has been set because + * xf86SetWeight references it. + */ + if (pScrn->depth > 8) { + /* The defaults are OK for us */ + rgb zeros = {0, 0, 0}; + + if (!xf86SetWeight(pScrn, zeros, zeros)) { + return FALSE; + } else { + /* XXX check that weight returned is supported */ + ; + } } -} + if (!xf86SetDefaultVisual(pScrn, -1)) { + return FALSE; + } else { + /* We don't currently support DirectColor at > 8bpp */ + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + } -/* - * SISProbe -- - * check up whether a SIS 86C201 based board is installed - */ -static Bool -SISProbe() -{ - int numClocks; - unsigned char temp; - pciConfigPtr pcr, *pcrpp; - int i; + /* + * The new cmap layer needs this to be initialised. + */ - SISchipset = -1; - SIS.ChipLinearBase = -1; + { + Gamma zeros = {0.0, 0.0, 0.0}; - pcrpp = xf86scanpci(vga256InfoRec.scrnIndex); - for (i = 0, pcr = pcrpp[0]; pcr; pcr = pcrpp[++i]) { - if (pcr->_vendor == PCI_VENDOR_SIS) - break; + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; } + } - if (pcr) { - switch (pcr->_device) { - case PCI_CHIP_SG86C201: /* 86C201 */ - SISchipset = SIS86C201; - break; - case PCI_CHIP_SG86C202: /* 86C202 */ - SISchipset = SIS86C202; - break; - case PCI_CHIP_SG86C205: /* 86C205 */ - SISchipset = SIS86C205; - break; - } - if (pcr->_base0) - if (pcr->_base0 & 1) - PCIMMIOBase = pcr->_base0 & 0xfffffffc; - else - SIS.ChipLinearBase = pcr->_base0 & 0xfffffff0; - if (pcr->_base1) - if (pcr->_base1 & 1) - PCIMMIOBase = pcr->_base1 & 0xfffffffc; - else - SIS.ChipLinearBase = pcr->_base1 & 0xfffffff0; - - if (SIS.ChipLinearBase != -1) - SIS.ChipLinearBase &= 0xfff80000; - else - ErrorF("%s %s: %s: Can't find valid PCI " - "Base Address\n", XCONFIG_PROBED, - vga256InfoRec.name, vga256InfoRec.chipset); + /* We use a programamble clock */ + pScrn->progClock = TRUE; - } else { - if (xf86Verbose > 1) - ErrorF("%s %s: %s: Can't find SiS PCI device in " - "configuration space\n", XCONFIG_PROBED, - vga256InfoRec.name, vga256InfoRec.chipset); + /* Allocate the SISRec driverPrivate */ + if (!SISGetRec(pScrn)) { + return FALSE; + } + pSiS = SISPTR(pScrn); + pSiS->pScrn = pScrn; + + /* Collect all of the relevant option flags (fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + + /* Process the options */ + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, SISOptions); + + /* Set the bits per RGB for 8bpp mode */ + if (pScrn->depth == 8) { + /* XXX This is here just to test options. */ + /* Default to 8 */ + pScrn->rgbBits = 6; +#if 0 + if (xf86GetOptValInteger(SISOptions, OPTION_RGB_BITS, + &pScrn->rgbBits)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n", + pScrn->rgbBits); } +#endif + } + from = X_DEFAULT; + pSiS->HWCursor = TRUE; + if (xf86IsOptionSet(SISOptions, OPTION_HW_CURSOR)) { + from = X_CONFIG; + pSiS->HWCursor = TRUE; + } + if (xf86IsOptionSet(SISOptions, OPTION_SW_CURSOR)) { + from = X_CONFIG; + pSiS->HWCursor = FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pSiS->HWCursor ? "HW" : "SW"); + if (xf86IsOptionSet(SISOptions, OPTION_NOACCEL)) { + pSiS->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } + if (xf86IsOptionSet(SISOptions, OPTION_PCI_RETRY)) { + pSiS->UsePCIRetry = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); + } - if (vga256InfoRec.chipset) - { - /* - * If chipset from XF86Config doesn't match... - */ - if (!StrCaseCmp(vga256InfoRec.chipset, SISIdent(0))) - SISchipset = SIS86C201; - else if (!StrCaseCmp(vga256InfoRec.chipset, SISIdent(1))) - SISchipset = SIS86C202; - else if (!StrCaseCmp(vga256InfoRec.chipset, SISIdent(2))) - SISchipset = SIS86C205; - else - return(FALSE); - } - else - { - /* Aparently there are only PCI based 86C201's */ - if (SISchipset == -1) - return (FALSE); - vga256InfoRec.chipset = SISIdent(SISchipset); + /* Find the PCI slot for this screen */ + if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL)) != 1) { + /* This shouldn't happen */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Expected one PCI card, but found %d\n", i); + SISFreeRec(pScrn); + return FALSE; + } + + pSiS->TurboQueue = FALSE; /* For now */ + pSiS->PciInfo = *pciList; + /* + * Set the Chipset and ChipRev, allowing config file entries to + * override. + */ + if (pScrn->device->chipset && *pScrn->device->chipset) { + pScrn->chipset = pScrn->device->chipset; + pSiS->Chipset = xf86StringToToken(SISChipsets, pScrn->chipset); + from = X_CONFIG; + } else if (pScrn->device->chipID >= 0) { + pSiS->Chipset = pScrn->device->chipID; + pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset); + + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", + pSiS->Chipset); + } else { + from = X_PROBED; + pSiS->Chipset = pSiS->PciInfo->chipType; + pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset); + } + if (pScrn->device->chipRev >= 0) { + pSiS->ChipRev = pScrn->device->chipRev; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", + pSiS->ChipRev); + } else { + pSiS->ChipRev = pSiS->PciInfo->chipRev; + } + + /* + * This shouldn't happen because such problems should be caught in + * SISProbe(), but check it just in case. + */ + if (pScrn->chipset == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04X is not recognised\n", pSiS->Chipset); + return FALSE; + } + if (pSiS->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognised\n", pScrn->chipset); + return FALSE; + } + + pSiS->PciTag = pciTag(pSiS->PciInfo->bus, pSiS->PciInfo->device, + pSiS->PciInfo->func); + + if (pScrn->device->MemBase != 0) { + pSiS->FbAddress = pScrn->device->MemBase; + from = X_CONFIG; + } else { + pSiS->FbAddress = pSiS->PciInfo->memBase[0] & 0xFFFFFFF0; + } + + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", + (unsigned long)pSiS->FbAddress); + + if (pScrn->device->IOBase != 0) { + pSiS->IOAddress = pScrn->device->IOBase; + from = X_CONFIG; + } else { + pSiS->IOAddress = pSiS->PciInfo->memBase[1] & 0xFFFFFFF0; + } + + xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", + (unsigned long)pSiS->IOAddress); + + /* HW bpp matches reported bpp */ + pSiS->HwBpp = pScrn->bitsPerPixel; + + if (pScrn->device->videoRam != 0) { + pScrn->videoRam = pScrn->device->videoRam; + from = X_CONFIG; + } else { + unsigned char temp; + outb(0x3C4, 0x05); + temp = inb(0x3C5); + outw(0x3C4, 0x8605); /* Unlock registers */ + outb(0x3C4, RAMSize); /* Get memory size */ + videoram = (inb(0x3C5) >> 1); + outw(0x3C4, (temp << 8) | 0x05); /* relock registers */ + switch (videoram & 0x0B) { + case 0x00: + pScrn->videoRam = 1024; + break; + case 0x01: + pScrn->videoRam = 2048; + break; + case 0x02: + pScrn->videoRam = 4096; + break; + case 0x03: + pScrn->videoRam = 1024; + break; + case 0x08: + pScrn->videoRam = 0; /* OUCH ! */ + break; + case 0x09: + pScrn->videoRam = 2048; + break; + case 0x0A: + pScrn->videoRam = 4096; + break; + case 0x0B: + pScrn->videoRam = 8192; + break; + default: + pScrn->videoRam = 1024; + xf86DrvMsg(pScrn->scrnIndex, from, + "Unable to determine VideoRam, defaulting to 1MB\n", + pScrn->videoRam); + break; } + } - SISEnterLeave(ENTER); - - /* - * How much Video Ram have we got? - */ - if (!vga256InfoRec.videoRam) - { - unsigned char temp; - - outb(0x3C4, 0x0F); - temp = inb(0x3C5); - - switch (temp & 0x03) - { - case 0: - vga256InfoRec.videoRam = 1024; - break; - case 1: - vga256InfoRec.videoRam = 2048; - break; - case 2: - vga256InfoRec.videoRam = 4096; - break; - } - } - - if (vgaBitsPerPixel < 8) { - if (!vga256InfoRec.clocks) { - numClocks = 4; - vgaGetClocks(numClocks, SISClockSelect); + xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", + pScrn->videoRam); + + pSiS->FbMapSize = pScrn->videoRam * 1024; + + /* Set the min pixel clock */ + pSiS->MinClock = 16250; /* XXX Guess, need to check this */ + pSiS->MaxClock = 170000; /* XXX Guess, need to check this */ + xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", + pSiS->MinClock / 1000); + + /* + * If the user has specified ramdac speed in the XF86Config + * file, we respect that setting. + */ + if (pScrn->device->dacSpeeds[0]) { + int speed = 0; + + switch (pScrn->bitsPerPixel) { + case 8: + speed = pScrn->device->dacSpeeds[DAC_BPP8]; + break; + case 16: + speed = pScrn->device->dacSpeeds[DAC_BPP16]; + break; + case 24: + speed = pScrn->device->dacSpeeds[DAC_BPP24]; + break; + case 32: + speed = pScrn->device->dacSpeeds[DAC_BPP32]; + break; } - } else { + if (speed == 0) + pSiS->MaxClock = pScrn->device->dacSpeeds[0]; + else + pSiS->MaxClock = speed; + from = X_CONFIG; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", + pSiS->MaxClock / 1000); + + /* + * Setup the ClockRanges, which describe what clock ranges are available, + * and what sort of modes they can be used for. + */ + clockRanges = xnfalloc(sizeof(ClockRange)); + clockRanges->next = NULL; + clockRanges->minClock = pSiS->MinClock; + clockRanges->maxClock = pSiS->MaxClock; + clockRanges->clockIndex = -1; /* programmable */ + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ + + /* + * xf86ValidateModes will check that the mode HTotal and VTotal values + * don't exceed the chipset's limit if pScrn->maxHValue and + * pScrn->maxVValue are set. Since our SISValidMode() already takes + * care of this, we don't worry about setting them here. + */ + + /* Select valid modes from those available */ +#if 0 + if (pSiS->NoAccel) { +#endif /* - * If clocks are not specified in XF86Config file, probe for them + * XXX Assuming min pitch 256, max 4096 + * XXX Assuming min height 128, max 4096 */ - if ( (OFLG_ISSET(OPTION_HW_CLKS, &vga256InfoRec.options)) || - (SISchipset == SIS86C201) ) { - /* if sis86c201 force to use the hw clock - * if programmable clock works with the sis86c201 - * let us know - */ - if (!vga256InfoRec.clocks) { - numClocks = 32; - vgaGetClocks(numClocks, SISClockSelect); - } - } - else { - OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &vga256InfoRec.clockOptions); - ErrorF("%s %s: using programmable clocks.\n", - XCONFIG_PROBED, vga256InfoRec.name); - if(!vga256InfoRec.clockprog) - vga256InfoRec.clocks = 0; - } - - /* maximal clock */ - if ( (SISchipset == SIS86C205) || (SISchipset == SIS86C202) ) - vga256InfoRec.maxClock = 135000; - } - - vga256InfoRec.bankedMono = TRUE; - if (vgaBitsPerPixel > 8) { - /* We support Direct Video Access */ - vga256InfoRec.directMode = XF86DGADirectPresent; - - /* MaxClock set at 90MHz for 256 - ??? */ - - OFLG_SET(OPTION_HW_CURSOR, &SIS.ChipOptionFlags); - OFLG_SET(OPTION_SW_CURSOR, &SIS.ChipOptionFlags); - OFLG_SET(OPTION_HW_CLKS, &SIS.ChipOptionFlags); - OFLG_SET(OPTION_LINEAR, &SIS.ChipOptionFlags); - OFLG_SET(OPTION_MMIO, &SIS.ChipOptionFlags); - OFLG_SET(OPTION_NOLINEAR_MODE, &SIS.ChipOptionFlags); - OFLG_SET(OPTION_NO_BITBLT, &SIS.ChipOptionFlags); - OFLG_SET(OPTION_NO_IMAGEBLT, &SIS.ChipOptionFlags); - OFLG_SET(OPTION_NOACCEL, &SIS.ChipOptionFlags); - } else { - /* Set to 130MHz at 16 colours */ - vga256InfoRec.maxClock = 130000; - } -#ifdef DPMSExtension - vga256InfoRec.DPMSSet = SISDisplayPowerManagementSet; + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + NULL, 256, 4096, + pScrn->bitsPerPixel, 128, 4096, + pScrn->display->virtualX, + pScrn->display->virtualY, + pSiS->FbMapSize, + LOOKUP_BEST_REFRESH); +#if 0 + } else { + /* + * XXX Assuming min height 128, max 2048 + */ + j = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + GetAccelPitchValues(pScrn), 0, 0, + pScrn->bitsPerPixel, 128, 2048, + pScrn->display->virtualX, + pScrn->display->virtualY, + pSiS->FbMapSize, + LOOKUP_BEST_REFRESH); + } #endif - return(TRUE); -} + if (i == -1) { + SISFreeRec(pScrn); + return FALSE; + } -/* - * SISScrnInit -- - * - * Sets some accelerated functions - */ -static int -SISScrnInit(pScreen, LinearBase, virtualX, virtualY, res1, res2, width) -ScreenPtr pScreen; -char *LinearBase; -int virtualX, virtualY, res1, res2, width; -{ -#ifdef DEBUG - ErrorF("SISScrnInit\n"); -#endif - if (vgaBitsPerPixel > 8) { - pScreen->CopyWindow = siscfbCopyWindow; - pScreen->PaintWindowBackground = sisPaintWindow; - pScreen->PaintWindowBorder = sisPaintWindow; + /* Prune the modes marked as invalid */ + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + SISFreeRec(pScrn); + return FALSE; + } + + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + + /* Set the current mode to the first in the list */ + pScrn->currentMode = pScrn->modes; + + /* Print the list of modes being used */ + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load bpp-specific modules */ + switch (pScrn->bitsPerPixel) { + case 1: + mod = "xf1bpp"; + Sym = "xf1bppScreenInit"; + break; + case 4: + mod = "xf4bpp"; + Sym = "xf4bppScreenInit"; + break; + case 8: + mod = "cfb"; + Sym = "cfbScreenInit"; + break; + case 16: + mod = "cfb16"; + Sym = "cfb16ScreenInit"; + break; + case 24: + mod = "cfb24"; + Sym = "cfb24ScreenInit"; + break; + case 32: + mod = "cfb32"; + Sym = "cfb32ScreenInit"; + break; } - return(TRUE); + + if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + SISFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymbols(Sym, NULL); + + if (!xf86LoadSubModule(pScrn, "rac")) { + SISFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(racSymbols, NULL); + + if (!xf86LoadSubModule(pScrn, "i2c")) { + SISFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(i2cSymbols, NULL); + + /* Load XAA if needed */ + if (!pSiS->NoAccel) { + if (!xf86LoadSubModule(pScrn, "xaa")) { + SISFreeRec(pScrn); + return FALSE; + } + + xf86LoaderReqSymLists(xaaSymbols, NULL); + } + + return TRUE; } + /* - * SISFbInit -- - * enable speedups for the chips that support it + * Map the framebuffer and MMIO memory. */ -static void -SISFbInit() -{ - unsigned long j; - unsigned long i; - pointer sisVideoMem; - long *poker; - int offscreen_available; - unsigned char tmp1,tmp2; -#ifdef DEBUG - ErrorF("SISFbInit()\n"); -#endif - if (vgaBitsPerPixel >= 8) { - if (OFLG_ISSET(OPTION_LINEAR, &vga256InfoRec.options)) - { - ErrorF("%s %s: Enabling Linear Addressing\n", - XCONFIG_GIVEN, vga256InfoRec.name); - sisUseLinear = TRUE; - } - if (OFLG_ISSET(OPTION_NOLINEAR_MODE, &vga256InfoRec.options)) - { - ErrorF("%s %s: Disabling Linear Addressing\n", - XCONFIG_GIVEN, vga256InfoRec.name); - sisUseLinear = FALSE; - } +static Bool +SISMapMem(ScrnInfoPtr pScrn) +{ + CARD32 save = 0; + SISPtr pSiS; - if ( sisUseLinear ) { - if (vga256InfoRec.MemBase != 0) { - SIS.ChipLinearBase = vga256InfoRec.MemBase; - ErrorF("%s %s: base address is set at 0x%X.\n", - XCONFIG_GIVEN, vga256InfoRec.name, SIS.ChipLinearBase); - } - else { - if (SIS.ChipLinearBase == -1) { - unsigned long addr,addr2 ; - - outb(0x3C4, 0x21); - addr = inb(0x3C5) & 0x1f ; - addr <<= 27 ; - outb(0x3C4, 0x20); - addr2 = inb(0x3C5) ; - addr2 <<= 19 ; - addr |= addr2 ; - if ( addr == 0 ) { - ErrorF("%s %s: Disabling Linear Addressing\n", - XCONFIG_PROBED, vga256InfoRec.name); - ErrorF("%s %s: Try to set MemBase in XF86Config\n", - XCONFIG_PROBED, vga256InfoRec.name); - sisUseLinear = FALSE; - } - else { - SIS.ChipLinearBase = addr ; - ErrorF("%s %s: Trying Linear Addressing at 0x0%x\n", - XCONFIG_PROBED, vga256InfoRec.name, - SIS.ChipLinearBase); - } - } - } - } + pSiS = SISPTR(pScrn); - if ( sisUseLinear && xf86LinearVidMem() ) - { - SIS.ChipLinearSize = vga256InfoRec.videoRam * 1024; - ErrorF("%s %s: Using Linear Frame Buffer at 0x0%x, Size %dMB\n" - ,XCONFIG_PROBED, vga256InfoRec.name, - SIS.ChipLinearBase, SIS.ChipLinearSize/1048576); - } - - if (sisUseLinear) - SIS.ChipUseLinearAddressing = TRUE; - else - SIS.ChipUseLinearAddressing = FALSE; - - if (sisUseMMIO && OFLG_ISSET(OPTION_NO_BITBLT,&vga256InfoRec.options)){ - sisUseMMIO = FALSE ; - ErrorF("%s %s: SIS: Bit Block Transfert disabled\n", - OFLG_ISSET(OPTION_NO_BITBLT, &vga256InfoRec.options) ? - XCONFIG_GIVEN : XCONFIG_PROBED, vga256InfoRec.name); - } + /* + * Disable memory and I/O before mapping the MMIO area. This avoids + * the MMIO area being read during the mapping (which happens on + * some SVR4 versions), which will cause a lockup. + */ - if ( sisUseMMIO ){ - sisUseMMIO = TRUE ; - if (PCIMMIOBase == 0) { - /* use default base */ - if ( sisUseLinear) - /* sisMMIOBase = vgaBase , but not yet mapped here */ - PCIMMIOBase = vga256InfoRec.VGAbase; - else { - PCIMMIOBase = 0xB0000 ; - sisMMIOBase = xf86MapVidMem(vga256InfoRec.scrnIndex, - MMIO_REGION, - (pointer)(PCIMMIOBase), 0x10000L); - } - } else { - sisMMIOBase = xf86MapVidMem(vga256InfoRec.scrnIndex, - MMIO_REGION, - (pointer)(PCIMMIOBase), 0x10000L); - } - ErrorF("%s %s: SIS: Memory mapped I/O selected at 0x0%x\n", - OFLG_ISSET(OPTION_MMIO, &vga256InfoRec.options) ? - XCONFIG_GIVEN : XCONFIG_PROBED, - vga256InfoRec.name,PCIMMIOBase); - } + save = pciReadLong(pSiS->PciTag, PCI_CMD_STAT_REG); + pciWriteLong(pSiS->PciTag, PCI_CMD_STAT_REG, + save & ~(PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE)); + /* + * Map IO registers to virtual address space + */ +#if !defined(__alpha__) + pSiS->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pSiS->PciTag, (pointer)pSiS->IOAddress, 0x10000); +#else + /* + * For Alpha, we need to map SPARSE memory, since we need + * byte/short access. + */ + pSiS->IOBase = xf86MapPciMemSparse(pScrn->scrnIndex, VIDMEM_MMIO, + (pointer)pSiS->IOAddress, 0x10000); +#endif + if (pSiS->IOBase == NULL) + return FALSE; - SISDisplayableMemory = vga256InfoRec.displayWidth - * vga256InfoRec.virtualY - * (vgaBitsPerPixel / 8); +#if defined(SVR4) + /* + * For some SVR4 versions, a 32-bit read is done for the first + * location in each page when the page is first mapped. If this + * is done while memory and I/O are enabled, the result will be + * a lockup, so make sure each page is mapped here while it is safe + * to do so. + */ + { + CARD32 val; - offscreen_available = vga256InfoRec.videoRam * 1024 - - SISDisplayableMemory; + val = *(volatile CARD32 *)(pSiS->IOBase+0); + val = *(volatile CARD32 *)(pSiS->IOBase+0x1000); + val = *(volatile CARD32 *)(pSiS->IOBase+0x2000); + val = *(volatile CARD32 *)(pSiS->IOBase+0x3000); + } +#endif - if (OFLG_ISSET(OPTION_HW_CURSOR, &vga256InfoRec.options) || - !OFLG_ISSET(OPTION_SW_CURSOR, &vga256InfoRec.options) ) - { - OFLG_SET(OPTION_HW_CURSOR, &vga256InfoRec.options) ; - /* SiS needs upper 16K for hardware cursor */ - if (offscreen_available < 16384) - ErrorF("%s %s: Not enough off-screen video" - " memory for hardware cursor," - " using software cursor.\n", - XCONFIG_PROBED, vga256InfoRec.name); - else { - SISCursorWidth = 64; - SISCursorHeight = 64; - vgaHWCursor.Initialized = TRUE; - vgaHWCursor.Init = SISCursorInit; - vgaHWCursor.Restore = SISRestoreCursor; - vgaHWCursor.Warp = SISWarpCursor; - vgaHWCursor.QueryBestSize = SISQueryBestSize; - sisHWCursor = TRUE; - ErrorF("%s %s: Using hardware cursor\n", - XCONFIG_GIVEN, vga256InfoRec.name); - /* new offscreen_available */ - offscreen_available -= 16384 ; - } - } +#ifdef __alpha__ + /* + * for Alpha, we need to map DENSE memory as well, for + * setting CPUToScreenColorExpandBase. + */ + pSiS->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pSiS->PciTag, (pointer)pSiS->IOAddress, 0x1000); - if (OFLG_ISSET(OPTION_NO_IMAGEBLT, &vga256InfoRec.options)) { - ErrorF("%s %s: SIS: Not using mono expand system-to-video BitBLT.\n", - XCONFIG_GIVEN, vga256InfoRec.name); - sisAvoidImageBLT = TRUE; - } + if (pSiS->IOBaseDense == NULL) + return FALSE; +#endif /* __alpha__ */ - if (sisUseMMIO) { - if (!OFLG_ISSET(OPTION_NOACCEL, &vga256InfoRec.options)) { - if ( !sisUseLinear || - OFLG_ISSET(OPTION_XAA_NO_COL_EXP, &vga256InfoRec.options)) - sisUseXAAcolorExp = FALSE; - SISAccelInit(); - } - else if ( sisUseLinear ) { - ErrorF("%s %s: SIS: using old accelerated functions.\n", - XCONFIG_PROBED, vga256InfoRec.name); - switch (vgaBitsPerPixel) { - case 8: - - vga256LowlevFuncs.doBitbltCopy = siscfbDoBitbltCopy; - vga256LowlevFuncs.vgaBitblt = sisMMIOBitBlt; - - vga256LowlevFuncs.fillRectSolidCopy = sisMMIOFillRectSolid; - - vga256LowlevFuncs.fillBoxSolid = siscfbFillBoxSolid; - vga256TEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; - vga256TEOps.FillSpans = sisMMIOFillSolidSpansGeneral; - vga256LowlevFuncs.fillSolidSpans =sisMMIOFillSolidSpansGeneral; - - /* Setup the address of the tile/stipple in vram. - * be aligned on a 64 bytes value. Size of the space - * is 1024 */ - /* in the future it might be better to keep all the offscreen - memory for cache pixmap/bitmap - */ - if (offscreen_available < 1024) { - ErrorF("%s %s: Not enough off-screen video" - " memory for expand color." - " using builin pattern reg for 512 pixels\n", - XCONFIG_PROBED, vga256InfoRec.name); - sisBLTPatternOffscreenSize = - (SISchipset == SIS86C205) ? 512 : 256 ; - } - else { - int CursorSize = sisHWCursor?16384:0 ; - sisBLTPatternAddress = vga256InfoRec.videoRam * 1024 - - CursorSize - 1024; - sisBLTPatternOffscreenSize = 1024 ; - } - /* Hook special op. fills (and tiles): */ - vga256TEOps1Rect.PolyFillRect = siscfbPolyFillRect; - vga256NonTEOps1Rect.PolyFillRect = siscfbPolyFillRect; - vga256TEOps.PolyFillRect = siscfbPolyFillRect; - vga256NonTEOps.PolyFillRect = siscfbPolyFillRect; - - if (!OFLG_ISSET(OPTION_NO_IMAGEBLT, - &vga256InfoRec.options)) { - vga256TEOps1Rect.PolyGlyphBlt = sisMMIOPolyGlyphBlt; - vga256TEOps.PolyGlyphBlt = sisMMIOPolyGlyphBlt; - vga256LowlevFuncs.teGlyphBlt8 = sisMMIOImageGlyphBlt; - vga256TEOps1Rect.ImageGlyphBlt = sisMMIOImageGlyphBlt; - vga256TEOps.ImageGlyphBlt = sisMMIOImageGlyphBlt; - } + pSiS->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + pSiS->PciTag, + (pointer)((unsigned long)pSiS->FbAddress), + pSiS->FbMapSize); + if (pSiS->FbBase == NULL) + return FALSE; - break; - case 16: - /* There are no corresponding structures to vga256LowlevFuncs - * for 16/24bpp. Hence we have to hook to the cfb functions - * in a similar way to the cirrus driver. For now I've just - * implemented the most basic of blits */ - - cfb16TEOps1Rect.CopyArea = siscfb16CopyArea; - cfb16TEOps.CopyArea = siscfb16CopyArea; - cfb16NonTEOps1Rect.CopyArea = siscfb16CopyArea; - cfb16NonTEOps.CopyArea = siscfb16CopyArea; - - cfb16TEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; - cfb16TEOps.FillSpans = sisMMIOFillSolidSpansGeneral; - cfb16NonTEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; - cfb16NonTEOps.FillSpans = sisMMIOFillSolidSpansGeneral; - - /* Setup the address of the tile/stipple in vram. - * be aligned on a 64 bytes value. Size of the space - * is 1024 */ - /* in the future it might be better to keep all the offscreen - memory for cache pixmap/bitmap - */ - if (offscreen_available < 1024) { - ErrorF("%s %s: Not enough off-screen video" - " memory for expand color." - " using builin pattern reg for 512 pixels\n", - XCONFIG_PROBED, vga256InfoRec.name); - sisBLTPatternOffscreenSize = - (SISchipset == SIS86C205) ? 512 : 256 ; - } - else { - int CursorSize = sisHWCursor?16384:0 ; - sisBLTPatternAddress = vga256InfoRec.videoRam * 1024 - - CursorSize - 1024; - sisBLTPatternOffscreenSize = 1024 ; - } - cfb16TEOps1Rect.PolyFillRect = siscfbPolyFillRect; - cfb16TEOps.PolyFillRect = siscfbPolyFillRect; - cfb16NonTEOps1Rect.PolyFillRect = siscfbPolyFillRect; - cfb16NonTEOps.PolyFillRect = siscfbPolyFillRect; - - if (!OFLG_ISSET(OPTION_NO_IMAGEBLT, - &vga256InfoRec.options)) { - cfb16TEOps1Rect.PolyGlyphBlt = sisMMIOPolyGlyphBlt; - cfb16TEOps.PolyGlyphBlt = sisMMIOPolyGlyphBlt; - cfb16TEOps1Rect.ImageGlyphBlt = sisMMIOImageGlyphBlt; - cfb16TEOps.ImageGlyphBlt = sisMMIOImageGlyphBlt; - } - - break ; - case 24: - - cfb24TEOps1Rect.CopyArea = siscfb24CopyArea; - cfb24TEOps.CopyArea = siscfb24CopyArea; - cfb24NonTEOps1Rect.CopyArea = siscfb24CopyArea; - cfb24NonTEOps.CopyArea = siscfb24CopyArea; - - cfb24TEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; - cfb24TEOps.FillSpans = sisMMIOFillSolidSpansGeneral; - cfb24NonTEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; - cfb24NonTEOps.FillSpans = sisMMIOFillSolidSpansGeneral; - - /* Setup the address of the tile/stipple in vram. - * be aligned on a 64 bytes value. Size of the space - * is 1024 */ - /* in the future it might be better to keep all the offscreen - memory for cache pixmap/bitmap - */ - if (offscreen_available < 1024) { - ErrorF("%s %s: Not enough off-screen video" - " memory for expand color." - " using builin pattern reg for 512 pixels\n", - XCONFIG_PROBED, vga256InfoRec.name); - sisBLTPatternOffscreenSize = - (SISchipset == SIS86C205) ? 512 : 256 ; - } - else { - int CursorSize = sisHWCursor?16384:0 ; - sisBLTPatternAddress = vga256InfoRec.videoRam * 1024 - - CursorSize - 1024; - sisBLTPatternOffscreenSize = 1024 ; - } - cfb24TEOps1Rect.PolyFillRect = siscfbPolyFillRect; - cfb24TEOps.PolyFillRect = siscfbPolyFillRect; - cfb24NonTEOps1Rect.PolyFillRect = siscfbPolyFillRect; - cfb24NonTEOps.PolyFillRect = siscfbPolyFillRect; - - /* the enhanced color expansion is not supported - * by the engine in 16M-color graphic mode. - */ - sisAvoidImageBLT = TRUE; + /* Re-enable I/O and memory */ + pciWriteLong(pSiS->PciTag, PCI_CMD_STAT_REG, + save | (PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE)); - break; - } - vgaSetScreenInitHook(SISScrnInit); - } - } - } + return TRUE; } + /* - * SISEnterLeave -- - * enable/disable io-mapping + * Unmap the framebuffer and MMIO memory. */ -static void -SISEnterLeave(enter) - Bool enter; + +static Bool +SISUnmapMem(ScrnInfoPtr pScrn) { - unsigned char temp; -#ifdef DEBUG - ErrorF("SISEnterLeave("); - if (enter) - ErrorF("Enter)\n"); - else - ErrorF("Leave)\n"); -#endif + SISPtr pSiS; - if (vgaBitsPerPixel >= 8) { -#ifdef XFreeXDGA - if (vga256InfoRec.directMode & XF86DGADirectGraphics && !enter) - if (OFLG_ISSET(OPTION_HW_CURSOR, &vga256InfoRec.options)) - SISHideCursor(); + pSiS = SISPTR(pScrn); + + /* + * Unmap IO registers to virtual address space + */ +#ifndef __alpha__ + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBase, 0x1000); +#else + xf86UnMapVidMemSparse(pScrn->scrnIndex, (pointer)pSiS->IOBase, 0x1000); #endif - } + pSiS->IOBase = NULL; - if (enter) - { - xf86EnableIOPorts(vga256InfoRec.scrnIndex); - vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0; - outb(vgaIOBase + 4, 0x11); temp = inb(vgaIOBase + 5); - outb(vgaIOBase + 5, temp & 0x7F); - - outw(0x3C4, 0x8605); /* Unlock Specials */ - } - else - { - outw(0x3C4, 0x0005); /* Lock Specials */ - - xf86DisableIOPorts(vga256InfoRec.scrnIndex); - } +#ifdef __alpha__ + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBaseDense, 0x1000); + pSiS->IOBaseDense = NULL; +#endif /* __alpha__ */ + + xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->FbBase, pScrn->videoRam); + pSiS->FbBase = NULL; + return TRUE; } + /* - * SISRestore -- - * restore a video mode + * This function saves the video state. */ static void -SISRestore(restore) - vgaSISPtr restore; +SISSave(ScrnInfoPtr pScrn) { - int i; - -#ifdef DEBUG - ErrorF("SISRestore\n"); -#endif - vgaProtect(TRUE); + SISPtr pSiS; + vgaRegPtr vgaReg; + SISRegPtr sisReg; - for (i = 5 ; i <= 0x37; i++) { - outb(0x3C4, i); - if (inb(0x3C5) != restore->Port_3C4[i]) - outb(0x3C5,restore->Port_3C4[i]); - } + pSiS = SISPTR(pScrn); + vgaReg = &VGAHWPTR(pScrn)->SavedReg; + sisReg = &pSiS->SavedReg; - /* set the clock */ - if ( ClockProgramable() ) { - if (restore->std.NoClock >= 0) - sisClockLoad(&restore->sisClock); - } - else - outw(0x3C4, ((restore->ClockReg) << 8) | 0x07); +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); +#endif - /* - * Now restore generic VGA Registers - */ - vgaHWRestore((vgaHWPtr)restore); + vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); - outb(0x3C2, restore->ClockReg2); + SiSSave(pScrn, sisReg); -#ifdef IO_DEBUG - for (i = 5 ; i <= 0x37; i++) { - outb(0x3C4, i); - ErrorF("XR%X - %X\n", i, inb(0x3C5)); - } +#if 0 + xf86DelControlledResource(&pScrn->Access,FALSE); #endif - vgaProtect(FALSE); } + /* - * SISSave -- - * save the current video mode + * Initialise a new mode. This is currently still using the old + * "initialise struct, restore/write struct to HW" model. That could + * be changed. */ -static void * -SISSave(save) - vgaSISPtr save; + +static Bool +SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { - int i; -#ifdef DEBUG - ErrorF("SISSave\n"); -#endif - save = (vgaSISPtr)vgaHWSave((vgaHWPtr)save, sizeof(vgaSISRec)); + vgaHWPtr hwp = VGAHWPTR(pScrn); + vgaRegPtr vgaReg; + SISPtr pSiS = SISPTR(pScrn); + SISRegPtr sisReg; - for (i = 5 ; i <= 0x37; i++) { - outb(0x3C4, i); - save->Port_3C4[i] = inb(0x3C5) ; -#ifdef IO_DEBUG - ErrorF("XS%X - %X\n", i, inb(0x3C5)); +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); #endif - } - save->ClockReg2 = inb(0x3CC); + vgaHWUnlock(hwp); - /* save clock */ - if ( ClockProgramable() ) - sisClockSave(&save->sisClock); + /* Initialise the ModeReg values */ + if (!vgaHWInit(pScrn, mode)) + return FALSE; + pScrn->vtSema = TRUE; - return ((void *) save); + if (!SiSInit(pScrn, mode)) + return FALSE; + + /* Program the registers */ + vgaHWProtect(pScrn, TRUE); + vgaReg = &hwp->ModeReg; + sisReg = &pSiS->ModeReg; + + vgaReg->Attribute[0x10] = 0x01; + + vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); + + SiSRestore(pScrn, sisReg); + + vgaHWProtect(pScrn, FALSE); + +#if 0 + xf86DelControlledResource(&pScrn->Access,FALSE); +#endif + + return TRUE; } /* - * In graphic mode: data ---------> to selector switch - * - * Now, let's look at the selector switch - * - * FIFO - * MCLK ________________ VCLK - * cpu/engine <---o o-------->|________________|---------> CRT - * ^ ^ ^ ^ - * \ / | | - * \ / | | - * \ / | | - * selector switch Threshold low Threshold high - * - * CRT consumes the data in the fifo. When data in FIFO reaches the - * level of threshold low, the selector will switch to right so that the - * FIFO can be filled by data. When the data in FIFO reaches the threshold - * high level, the selector will switch back to left. - * The threshold low must be set to a minimum level or the snow - * phenomenon (flicker noise) will be found on the screen. - * - * The threshold low should increase if bpp increased, cause it means the - * required data for CRT is increased when bpp increased. When the threshold - * low increased, the distance between threshold high and thereshold low - * should not be too near, else it will have the selector switch frequently, - * a bad performance result. + * Restore the initial (text) mode. */ -static int -FindCRT_CPUthreshold(dotClock,bpp,thresholdLow,thresholdHigh) -int dotClock ; -int bpp; -int *thresholdLow; -int *thresholdHigh; +static void +SISRestore(ScrnInfoPtr pScrn) { - /* here is an hack to set the CRT/CPU threshold register. - the value in the three arrays come from Dump Registers in W95 - */ - struct ThresholdREC { - int freq; - int thresholdHigh; - int thresholdLow; - } ; -#if 0 - static struct ThresholdREC threshold8[]={{25250,0x6,0x3},{31500,0x6,0x3}, - {40000,0x7,0x4},{44900,0x7,0x4}, - {56250,0x7,0x4}, - {65500,0x8,0x5},{78750,0x9,0x6}, - {95000,0xa,0x7},{110000,0xd,0xb}, - {135000,0xc,0xa}}; -#else /* adjusted for X11 */ - /* this is the best values I've found. - * there is no glitch but with intensive generation snow still appears - * on screen especially well seen on the tiled root window. - */ - static struct ThresholdREC threshold8[]={{25250,0x6,0x3},{31500,0x6,0x3}, - {40000,0x7,0x4},{44900,0x7,0x4}, - {56250,0x9,0x5}, - {65000,0xe,0x5},/* ??? */ - {78750,0xd,0x6},{85000,0xd,0x6}, - {95000,0xb,0x7},{110000,0xc,0xa}, - {135000,0xc,0xa}}; -#endif + vgaHWPtr hwp; + vgaRegPtr vgaReg; + SISPtr pSiS; + SISRegPtr sisReg; + + hwp = VGAHWPTR(pScrn); + pSiS = SISPTR(pScrn); + vgaReg = &hwp->SavedReg; + sisReg = &pSiS->SavedReg; + #if 0 - static struct ThresholdREC threshold16[]={{25250,0x8,0x5},{31500,0x8,0x5}, - {40000,0xa,0x7},{44900,0xa,0x7}, - {56250,0xb,0x8}, - {65500,0xc,0xa},{78750,0xe,0xc}, - {95000,0xf,0xd}}; -#else - static struct ThresholdREC threshold16[]={{25250,0x8,0x5},{31500,0x8,0x5}, - {40000,0xa,0x7},{44900,0xa,0x7}, - {56250,0xf,0x7}, - {65000,0xf,0x7},{78750,0xf,0x8}, - {95000,0xf,0xd}}; + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); #endif - static struct ThresholdREC threshold24[]={{25250,0xa,0x7},{31500,0xa,0x7}, - {40000,0xc,0x9},{56250,0xe,0xc}}; - int nfreq ; - int i; - struct ThresholdREC *thresholdTab; + vgaHWProtect(pScrn, TRUE); - switch ( bpp ) { - case 8: - thresholdTab = threshold8 ; - nfreq = sizeof(threshold8)/sizeof(struct ThresholdREC); - break; - case 16: - thresholdTab = threshold16 ; - nfreq = sizeof(threshold16)/sizeof(struct ThresholdREC); - break; - case 24: - thresholdTab = threshold24 ; - nfreq = sizeof(threshold24)/sizeof(struct ThresholdREC); - break; - default: - thresholdTab = threshold8 ; - nfreq = sizeof(threshold8)/sizeof(struct ThresholdREC); - } - - for ( i = 0 ; i < nfreq ; i++ ) - if ( thresholdTab[i].freq >= dotClock ) break ; - if ( i == 0 ) { - *thresholdLow = thresholdTab[0].thresholdLow ; - *thresholdHigh = thresholdTab[0].thresholdHigh ; - return ; - } - if ( i == nfreq ) { /* nothing found */ - *thresholdLow = thresholdTab[nfreq -1].thresholdLow ; - *thresholdHigh = thresholdTab[nfreq -1].thresholdHigh ; - } - else { - *thresholdLow = thresholdTab[i-1].thresholdLow + - ((thresholdTab[i].thresholdLow - thresholdTab[i-1].thresholdLow) * - (dotClock - thresholdTab[i-1].freq)) / - ( thresholdTab[i].freq - thresholdTab[i-1].freq) ; - *thresholdHigh = thresholdTab[i-1].thresholdHigh + - ((thresholdTab[i].thresholdHigh - thresholdTab[i-1].thresholdHigh)* - (dotClock - thresholdTab[i-1].freq)) / - ( thresholdTab[i].freq - thresholdTab[i-1].freq) ; - } + SiSRestore(pScrn, sisReg); -#ifdef DEBUG - ErrorF("FindCRT_CPUthreshold(%d, %d) = 0x%x 0x%x\n", dotClock, bpp, - *thresholdLow,*thresholdHigh); -#endif + vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); + + vgaHWProtect(pScrn, FALSE); +#if 0 + xf86DelControlledResource(&pScrn->Access,FALSE); +#endif } -/* - * SISInit -- - * Handle the initialization, etc. of a screen. - */ +/* Mandatory */ + +/* This gets called at the start of each server generation */ + static Bool -SISInit(mode) - DisplayModePtr mode; +SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { - unsigned char temp; - int offset; - int i; - unsigned int CRT_CPUthresholdLow ; - unsigned int CRT_CPUthresholdHigh ; - unsigned char CRT_ENGthreshold ; -#ifdef DEBUG - ErrorF("SISInit\n"); -#endif + /* The vgaHW references will disappear one day */ + ScrnInfoPtr pScrn; + vgaHWPtr hwp; + SISPtr pSiS; + int ret; + VisualPtr visual; + + /* + * First get the ScrnInfoRec + */ + pScrn = xf86Screens[pScreen->myNum]; - /* - * Initialize generic VGA registers. - */ - vgaHWInit(mode, sizeof(vgaSISRec)); + hwp = VGAHWPTR(pScrn); - /* get SIS Specific Registers */ - for (i = 5 ; i <= 0x37; i++) { - outb(0x3C4, i); - new->Port_3C4[i] = inb(0x3C5); - } + hwp->MapSize = 0x10000; /* Standard 64k VGA window */ - if (vgaBitsPerPixel < 8) { - offset = vga256InfoRec.displayWidth >> - (mode->Flags & V_INTERLACE ? 3 : 4); - } - else - { - offset = vga256InfoRec.displayWidth >> - (mode->Flags & V_INTERLACE ? 2 : 3); + pSiS = SISPTR(pScrn); - new->std.Attribute[16] = 0x01; - new->std.CRTC[20] = 0x40; - new->std.CRTC[23] = 0xA3; - } + /* Map the VGA memory and get the VGA IO base */ + if (!vgaHWMapMem(pScrn)) + return FALSE; + vgaHWGetIOBase(hwp); - if (vgaBitsPerPixel >= 8) { - /* some generic settings */ - new->std.Attribute[0x10] = 0x01; /* mode */ - new->std.Attribute[0x11] = 0x00; /* overscan (border) color */ - new->std.Attribute[0x12] = 0x0F; /* enable all color planes */ - new->std.Attribute[0x13] = 0x00; /* horiz pixel panning 0 */ - - if ( (vgaBitsPerPixel == 16) || (vgaBitsPerPixel == 24) ) - new->std.Graphics[0x05] = 0x00; /* normal read/write mode */ - - if (vgaBitsPerPixel == 16) { - offset <<= 1; /* double the width of the buffer */ - } else if (vgaBitsPerPixel == 24) { - offset += offset << 1; - } - - new->BankReg = 0x02; - new->DualBanks = 0x00; - - if ( sisUseLinear ) { - new->BankReg |= 0x80; /* enable linear mode addressing */ - new->LinearAddr0 = (SIS.ChipLinearBase & 0x07f80000) >> 19 ; - new->LinearAddr1 = ((SIS.ChipLinearBase & 0xf8000000) >> 27) | - (0x60) ; /* Enable Linear with max 4 mb*/ - } - else - new->DualBanks |= 0x08; + /* Map the SIS memory and MMIO areas */ + if (!SISMapMem(pScrn)) + return FALSE; - if (vgaBitsPerPixel == 16) - if (xf86weight.green == 5) - new->BankReg |= 0x04; /* 16bpp = 5-5-5 */ - else - new->BankReg |= 0x08; /* 16bpp = 5-6-5 */ + /* Save the current state */ + SISSave(pScrn); - if (vgaBitsPerPixel == 24) { - new->BankReg |= 0x10; - new->DualBanks |= 0x80; - } + /* Initialise the first mode */ + if (!SISModeInit(pScrn, pScrn->currentMode)) + return FALSE; - new->std.CRTC[0x13] = offset & 0xFF; - new->CRTCOff = ((offset & 0xF00) >> 4) | - (((mode->CrtcVTotal-2) & 0x400) >> 10 ) | - (((mode->CrtcVDisplay-1) & 0x400) >> 9 ) | - ((mode->CrtcVSyncStart & 0x400) >> 8 ) | - (((mode->CrtcVSyncStart) & 0x400) >> 7 ) ; - - if (mode->Flags & V_INTERLACE) - new->BankReg |= 0x20; + /* Darken the screen for aesthetic reasons and set the viewport */ + SISSaveScreen(pScreen, FALSE); + SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* + * The next step is to setup the screen's visuals, and initialise the + * framebuffer code. In cases where the framebuffer's default + * choices for things like visual layouts and bits per RGB are OK, + * this may be as simple as calling the framebuffer's ScreenInit() + * function. If not, the visuals will need to be setup before calling + * a fb ScreenInit() function and fixed up after. + * + * For most PC hardware at depths >= 8, the defaults that cfb uses + * are not appropriate. In this driver, we fixup the visuals after. + */ + + /* + * Reset visual list. + */ + miClearVisualTypes(); + + /* Setup the visuals we support. */ + + /* + * For bpp > 8, the default visuals are not acceptable because we only + * support TrueColor and not DirectColor. + */ + if (pScrn->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, + pScrn->defaultVisual)) + return FALSE; + } else { + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + } - if ( ClockProgramable() ){ - /* init clock */ - if (!sisClockFind(new->std.NoClock, &new->sisClock)) { - ErrorF("Can't find desired clock\n"); - return (FALSE); + /* + * Call the framebuffer layer's ScreenInit function, and fill in other + * pScreen fields. + */ + + switch (pScrn->bitsPerPixel) { + case 1: + ret = xf1bppScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth); + break; + case 4: + ret = xf4bppScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth); + break; + case 8: + ret = cfbScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth); + break; + case 16: + ret = cfb16ScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth); + break; + case 24: + ret = cfb24ScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth); + break; + case 32: + ret = cfb32ScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth); + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in SISScrnInit\n", + pScrn->bitsPerPixel); + ret = FALSE; + break; + } + if (!ret) + return FALSE; + + xf86SetBlackWhitePixels(pScreen); + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; } } + } else if (pScrn->depth == 1) { + SIS1bppColorMap(pScrn); + } - if (new->std.NoClock >= 0) { - new->ClockReg = new->std.NoClock; /* not used in programmable */ - new->ClockReg2 = inb(0x3CC) | 0x0C; /* set internal/external clk */ - } + if (!pSiS->NoAccel) + SiSAccelInit(pScreen); + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* Initialise cursor functions */ + miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); - /* - * this is function of the bandwidth - * (pixelsize, displaysize, dotclock) - * worst case is not optimal - */ - CRT_ENGthreshold = 0x0f ; - FindCRT_CPUthreshold(vga256InfoRec.clock[new->std.NoClock], - vgaBitsPerPixel, - &CRT_CPUthresholdLow, &CRT_CPUthresholdHigh); - new->Port_3C4[0x08] = (CRT_ENGthreshold & 0x0F) | - (CRT_CPUthresholdLow & 0x0F)<<4 ; - new->Port_3C4[0x09] = (CRT_CPUthresholdHigh & 0x0F) ; #if 0 - /* Graphics Modes seem to need a Higher MClk, than at Console - * Force a higher Mclk for now */ - if ( SISchipset == SIS86C205 ) { - /* 80 MHz MCLK */ - /*new->Port_3C4[0x28] = 0xCF ; - new->Port_3C4[0x29] = 0x9C ;*/ - /* 70 MHz MCLK */ - new->Port_3C4[0x28] = 0xC1 ; - new->Port_3C4[0x29] = 0x1A ; - /* 60 MHz MCLK */ - /*new->Port_3C4[0x28] = 0x57 ; - new->Port_3C4[0x29] = 0x14 ;*/ - /* 45 MHz MCLK */ - /*new->Port_3C4[0x28] = 0x15 ; - new->Port_3C4[0x29] = 0x06 ;*/ - } + if (pSiS->HWCursor) + SiSHWCursorInit(pScreen); #endif - - new->Port_3C4[0x27] |= 0x30 ; /* invalid logical screen width */ - - if ( sisUseMMIO ) { - new->Port_3C4[0x27] |= 0x40 ; /* enable Graphic Engine Prog */ - if ( !sisMMIOBase ) - sisMMIOBase = (unsigned char *)vgaBase ; - switch ( PCIMMIOBase ) { - case 0xA0000: - new->Port_3C4[0x0B] |= 0x20 ; /* enable MMIO at 0xAxxxx */ - break; - case 0xB0000: - new->Port_3C4[0x0B] |= 0x40 ; /* enable MMIO at 0xBxxxx*/ - break; - default: - new->Port_3C4[0x0B] |= 0x60 ; /* enable MMIO at PCI reg */ - } - new->Port_3C4[0x0C] |= 0x80 ; /* 64-bit mode */ - /* - * Setup the address to write monochrome source data to, for - * system to the screen colour expansion. - */ - sisBltDataWindow = vgaLinearBase ; - } - } else { - if (new->std.NoClock >= 0) { - new->ClockReg = new->std.NoClock; - temp = inb(0x3CC) & ~0x0C ; - new->ClockReg2 = temp | ( (new->ClockReg<<2) & 0x0C) ; - } - } - return(TRUE); -} + /* Initialise default colourmap */ + if (!miCreateDefColormap(pScreen)) + return FALSE; -/* - * SISAdjust -- - * adjust the current video frame to display the mousecursor - */ + if (!vgaHWHandleColormaps(pScreen)) + return FALSE; -static void -SISAdjust(x, y) - int x, y; -{ - unsigned char temp; - int base; +#ifdef DPMSExtension + xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSet, 0); +#endif - if (vgaBitsPerPixel < 8) { - base = (y * vga256InfoRec.displayWidth + x + 3) >> 3; - } else { - base = y * vga256InfoRec.displayWidth + x ; - /* calculate base bpp dep. */ - switch (vgaBitsPerPixel) { - case 16: - base >>= 1; - break; - case 24: - base = ((base * 3)) >> 2; - base -= base % 6; - break; - default: /* 8bpp */ - base >>= 2; - break; - } - } + pSiS->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = SISCloseScreen; + pScreen->SaveScreen = SISSaveScreen; + + /* Report any unused options (only for the first generation) */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + } - outw(vgaIOBase + 4, (base & 0x00FF00) | 0x0C); - outw(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D); + /* Turn on the screen now */ + SISSaveScreen(pScreen, TRUE); - outb(0x3C4, 0x27); temp = inb(0x3C5) & 0xF0; - temp |= (base & 0x0F0000) >> 16; - outb(0x3C5, temp); + return TRUE; +} -#ifdef XFreeXDGA - if (vga256InfoRec.directMode & XF86DGADirectGraphics) { - /* Wait until vertical retrace is in progress. */ - while (inb(vgaIOBase + 0xA) & 0x08); - while (!(inb(vgaIOBase + 0xA) & 0x08)); - } -#endif + +/* Usually mandatory */ +static Bool +SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + return SISModeInit(xf86Screens[scrnIndex], mode); } + +/* + * This function is used to initialize the Start Address - the first + * displayed location in the video memory. + */ +/* Usually mandatory */ +static void +SISAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + SISPtr pSiS; + vgaHWPtr hwp; + int base = y * pScrn->displayWidth + x; + int vgaIOBase; + unsigned char temp; + + hwp = VGAHWPTR(pScrn); + pSiS = SISPTR(pScrn); + vgaIOBase = VGAHWPTR(pScrn)->IOBase; +} + + /* - * SISValidMode -- + * This is called when VT switching back to the X server. Its job is + * to reinitialise the video mode. * + * We may wish to unmap video/MMIO memory too. */ -static int -SISValidMode(mode, verbose,flag) -DisplayModePtr mode; -Bool verbose; -int flag; + +/* Mandatory */ +static Bool +SISEnterVT(int scrnIndex, int flags) { - return MODE_OK; + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + /* Should we re-save the text mode on each VT enter? */ + if (!SISModeInit(pScrn, pScrn->currentMode)) + return FALSE; + + return TRUE; } + /* - * MGADisplayPowerManagementSet -- + * This is called when VT switching away from the X server. Its job is + * to restore the previous (text) mode. * - * Sets VESA Display Power Management Signaling (DPMS) Mode. + * We may wish to remap video/MMIO memory too. */ -#ifdef DPMSExtension -static void SISDisplayPowerManagementSet(PowerManagementMode) -int PowerManagementMode; + +/* Mandatory */ +static void +SISLeaveVT(int scrnIndex, int flags) { - unsigned char extDDC_PCR; - unsigned char crtc17; - unsigned char seq1; + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); -#ifdef DEBUG - ErrorF("SISDisplayPowerManagementSet(%d)\n",PowerManagementMode); -#endif - if (!xf86VTSema) return; - outb(vgaIOBase + 4, 0x17); - crtc17 = inb(vgaIOBase + 5); - outb(0x3C4, 0x11); - extDDC_PCR = inb(0x3C5) & ~0xC0; - switch (PowerManagementMode) - { - case DPMSModeOn: - /* HSync: On, VSync: On */ - seq1 = 0x00 ; - crtc17 |= 0x80; - break; - case DPMSModeStandby: - /* HSync: Off, VSync: On */ - seq1 = 0x20 ; - extDDC_PCR |= 0x40; - break; - case DPMSModeSuspend: - /* HSync: On, VSync: Off */ - seq1 = 0x20 ; - extDDC_PCR |= 0x80; - break; - case DPMSModeOff: - /* HSync: Off, VSync: Off */ - seq1 = 0x20 ; - extDDC_PCR |= 0xC0; - /* DPMSModeOff is not supported with ModeStandby | ModeSuspend */ - /* need same as the generic VGA function */ - crtc17 &= ~0x80; - break; - } - outw(0x3C4, 0x0100); /* Synchronous Reset */ - outb(0x3C4, 0x01); /* Select SEQ1 */ - seq1 |= inb(0x3C5) & ~0x20; - outb(0x3C5, seq1); - usleep(10000); - outb(vgaIOBase + 4, 0x17); - outb(vgaIOBase + 5, crtc17); - outb(0x3C4, 0x11); - outb(0x3C5, extDDC_PCR); - outw(0x3C4, 0x0300); /* End Reset */ + SISRestore(pScrn); + vgaHWLock(hwp); } -#endif +/* + * This is called at the end of each server generation. It restores the + * original (text) mode. It should really also unmap the video memory too. + */ +/* Mandatory */ +static Bool +SISCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + vgaHWPtr hwp = VGAHWPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + + if (pScrn->vtSema) { + SISRestore(pScrn); + vgaHWLock(hwp); + SISUnmapMem(pScrn); + } + if(pSiS->AccelInfoRec) + XAADestroyInfoRec(pSiS->AccelInfoRec); + if(pSiS->CursorInfoRec) + xf86DestroyCursorInfoRec(pSiS->CursorInfoRec); + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = pSiS->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} +/* Free up any per-generation data structures */ +/* Optional */ +static void +SISFreeScreen(int scrnIndex, int flags) +{ + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + SISFreeRec(xf86Screens[scrnIndex]); +} +/* Checks if a mode is suitable for the selected chipset. */ +/* Optional */ +static int +SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + return(MODE_OK); +} + +/* Do screen blanking */ +/* Mandatory */ +static Bool +SISSaveScreen(ScreenPtr pScreen, Bool unblank) +{ + return vgaHWSaveScreen(pScreen, unblank); +} diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h b/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h new file mode 100644 index 000000000..e4f4a38a3 --- /dev/null +++ b/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h @@ -0,0 +1,171 @@ +/* + * Copyright 1998,1999 by Alan Hourihane, Wigan, England. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk + * Mike Chapman <mike@paranoia.com>, + * Juanjo Santamarta <santamarta@ctv.es>, + * Mitani Hiroshi <hmitani@drl.mei.co.jp> + * David Thomas <davtom@dream.org.uk>. + */ +/* $XFree86$ */ + +/* 3C4 */ +#define BankReg 0x06 +#define ClockReg 0x07 +#define CRTCOff 0x0A +#define DualBanks 0x0B +#define MMIOEnable 0x0B +#define RAMSize 0x0C +#define Mode64 0x0C +#define ClockBase 0x13 +#define LinearAdd0 0x20 +#define LinearAdd1 0x21 +#define GraphEng 0x27 +#define XR2A 0x2A +#define XR2B 0x2B + +/* 3x4 */ +#define Offset 0x13 + +/* Definitions for the SIS engine communication. */ + +extern int sisReg32MMIO[]; +#define BR(x) sisReg32MMIO[x] + +/* These are done using Memory Mapped IO, of the registers */ +/* + * Modified for Sis by Xavier Ducoin (xavier@rd.lectra.fr) + */ + + +#define sisLEFT2RIGHT 0x10 +#define sisRIGHT2LEFT 0x00 +#define sisTOP2BOTTOM 0x20 +#define sisBOTTOM2TOP 0x00 + +#define sisSRCSYSTEM 0x03 +#define sisSRCVIDEO 0x02 +#define sisSRCFG 0x01 +#define sisSRCBG 0x00 + +#define sisCMDBLT 0x0000 +#define sisCMDBLTMSK 0x0100 +#define sisCMDCOLEXP 0x0200 +#define sisCMDLINE 0x0300 + +#define sisCMDENHCOLEXP 0x2000 + +#define sisCLIPINTRN 0x00 +#define sisCLIPEXTRN 0x80 + +#define sisCLIPENABL 0x40 + +#define sisPATREG 0x08 +#define sisPATFG 0x04 +#define sisPATBG 0x00 + + +/* Macros to do useful things with the SIS BitBLT engine */ + +#define sisBLTSync \ + while(*(volatile unsigned short *)(pSiS->IOBase + BR(10)+2) & \ + (0x4000)){} + +/* According to SiS 6326 2D programming guide, 16 bits position at */ +/* 0x82A8 returns queue free. But this don't work, so don't wait */ +/* anything when turbo-queue is enabled. If there are frequent syncs */ +/* (as XAA does) this should work. But not for xaa_benchmark :-( */ + +#define sisBLTWAIT \ + if (!pSiS->TurboQueue) {\ + while(*(volatile unsigned short *)(pSiS->IOBase + BR(10)+2) & \ + (0x4000)){}} /* \ + else {while(*(volatile unsigned short *)(pSiS->IOBase + BR(10)) < \ + 63){}} */ + +#define sisSETPATREG()\ + ((unsigned char *)(pSiS->IOBase + BR(11))) + +#define sisSETPATREGL()\ + ((unsigned long *)(pSiS->IOBase + BR(11))) + +#define sisSETCMD(op) \ + *(unsigned short *)(pSiS->IOBase + BR(10) +2 ) = op + +#define sisSETROPFG(op) \ + *(unsigned int *)(pSiS->IOBase + BR(4)) = ((*(unsigned int *)(pSiS->IOBase + BR(4)))&0xffffff) | (op<<24) + +#define sisSETROPBG(op) \ + *(unsigned int *)(pSiS->IOBase + BR(5)) = ((*(unsigned int *)(pSiS->IOBase + BR(5)))&0xffffff) | (op<<24) + +#define sisSETROP(op) \ + sisSETROPFG(op);sisSETROPBG(op); + + +#define sisSETSRCADDR(srcAddr) \ + *(unsigned int *)(pSiS->IOBase + BR(0)) = srcAddr&0x3FFFFFL + +#define sisSETDSTADDR(dstAddr) \ + *(unsigned int *)(pSiS->IOBase + BR(1)) = dstAddr&0x3FFFFFL + +#define sisSETPITCH(srcPitch,dstPitch) \ + *(unsigned int *)(pSiS->IOBase + BR(2)) = ((dstPitch&0xFFFF)<<16)| \ + (srcPitch&0xFFFF) + +/* according to SIS 2D Engine Programming Guide + * width -1 independant of Bpp + */ +#define sisSETHEIGHTWIDTH(Height,Width)\ + *(unsigned int *)(pSiS->IOBase + BR(3)) = (((Height)&0xFFFF)<<16)| \ + ((Width)&0xFFFF) + +#define sisSETCLIPTOP(x,y)\ + *(unsigned int *)(pSiS->IOBase + BR(8)) = (((y)&0xFFFF)<<16)| \ + ((x)&0xFFFF) + +#define sisSETCLIPBOTTOM(x,y)\ + *(unsigned int *)(pSiS->IOBase + BR(9)) = (((y)&0xFFFF)<<16)| \ + ((x)&0xFFFF) + +#define sisSETBGCOLOR(bgColor)\ + *(unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor) + +#define sisSETBGCOLOR8(bgColor)\ + *(unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor&0xFF) + +#define sisSETBGCOLOR16(bgColor)\ + *(unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor&0xFFFF) + +#define sisSETBGCOLOR24(bgColor)\ + *(unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor&0xFFFFFF) + + +#define sisSETFGCOLOR(fgColor)\ + *(unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor) + +#define sisSETFGCOLOR8(fgColor)\ + *(unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor&0xFF) + +#define sisSETFGCOLOR16(fgColor)\ + *(unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor&0xFFFF) + +#define sisSETFGCOLOR24(fgColor)\ + *(unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor&0xFFFFFF) diff --git a/programs/Xserver/hw/xfree86/drivers/tga/Imakefile b/programs/Xserver/hw/xfree86/drivers/tga/Imakefile index b8eb01da7..af57e56e9 100644 --- a/programs/Xserver/hw/xfree86/drivers/tga/Imakefile +++ b/programs/Xserver/hw/xfree86/drivers/tga/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/Imakefile,v 1.3 1998/08/29 05:43:34 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/Imakefile,v 1.4 1999/01/03 03:58:38 dawes Exp $ XCOMM XCOMM This is an Imakefile for the TGA driver. XCOMM @@ -6,8 +6,8 @@ XCOMM #define IHaveModules #include <Server.tmpl> -SRCS = tga_driver.c tga_dac.c /* tga_accel.c */ BTramdac.c ICS1562.c BT463ramdac.c -OBJS = tga_driver.o tga_dac.o /* tga_accel.o */ BTramdac.o ICS1562.o BT463ramdac.o +SRCS = tga_driver.c tga_dac.c tga_accel.c BTramdac.c ICS1562.c BT463ramdac.c +OBJS = tga_driver.o tga_dac.o tga_accel.o BTramdac.o ICS1562.o BT463ramdac.o #if XF86LinkKit INCLUDES = -I. -I../../../include -I../../../include/X11 -I../.. diff --git a/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c b/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c index 77f5dddde..fba5f5a64 100644 --- a/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c +++ b/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c @@ -24,173 +24,634 @@ * DEC TGA accelerated options. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c,v 1.1.2.1 1998/07/18 17:53:45 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c,v 1.2 1998/07/25 16:55:57 dawes Exp $ */ +#define PSZ 8 #include "cfb.h" +#undef PSZ +/* +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +*/ +#include "micmap.h" #include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86cmap.h" +#include "mipointer.h" + +#include "mibstore.h" #include "miline.h" -#include "compiler.h" -#include "tga.h" -#include "tga_presets.h" #include "tga_regs.h" -#include "xaa.h" +#include "BT.h" +#include "tga.h" + +/* defines */ + +#define BLIT_FORWARDS 0 +#define BLIT_BACKWARDS 1 +#define USE_BLOCK_FILL 2 +#define USE_OPAQUE_FILL 3 +#define MIX_SRC 0x03 + +/* prototypes */ +unsigned int fb_offset(ScrnInfoPtr pScrn, int x, int y); +void TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w); +void TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w); void TGASync(); -void TGASetupForFillRectSolid(); -void TGASubsequentFillRectSolid(); -void TGASetupForScreenToScreenCopy(); -void TGASubsequentScreenToScreenCopy(); +void TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask); +void TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); +void TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, + int rop, unsigned int planemask, + int transparency_color); +void TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h); +void TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, + int fg, int bg, int rop, + unsigned int planemask); +void TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, + int paty, int x, int y, int w, + int h); + +#ifdef __alpha__ +unsigned int tga_reg_offset = 0; +#endif + +static int block_or_opaque_p; +static int blitdir; +static unsigned int current_rop; +static int transparent_pattern_p; -unsigned char byte_reversed[256] = -{ - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, -}; /* * The following function sets up the supported acceleration. Call it * from the FbInit() function in the SVGA driver. */ -void TGAAccelInit() { +Bool +DEC21030AccelInit(ScreenPtr pScreen) +{ + XAAInfoRecPtr TGA_AccelInfoRec; + BoxRec AvailFBArea; + ScrnInfoPtr pScrn; - xf86AccelInfoRec.Flags = BACKGROUND_OPERATIONS | - PIXMAP_CACHE; + /* ErrorF("DEC21030AccelInit called!"); */ + + /* first, create the XAAInfoRec */ + TGA_AccelInfoRec = XAACreateInfoRec(); - xf86AccelInfoRec.Sync = TGASync; + /* ErrorF("XAACreateInfoRec called"); */ -#if 0 - xf86GCInfoRec.PolyFillRectSolidFlags = 0; + TGA_AccelInfoRec->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS; + + TGA_AccelInfoRec->Sync = TGASync; - xf86AccelInfoRec.SetupForFillRectSolid = TGASetupForFillRectSolid; - xf86AccelInfoRec.SubsequentFillRectSolid = TGASubsequentFillRectSolid; + TGA_AccelInfoRec->SolidFillFlags = 0; + TGA_AccelInfoRec->SetupForSolidFill = TGASetupForSolidFill; + TGA_AccelInfoRec->SubsequentSolidFillRect = TGASubsequentSolidFillRect; - xf86GCInfoRec.CopyAreaFlags = 0; + TGA_AccelInfoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY; + TGA_AccelInfoRec->SetupForScreenToScreenCopy = + TGASetupForScreenToScreenCopy; + TGA_AccelInfoRec->SubsequentScreenToScreenCopy = + TGASubsequentScreenToScreenCopy; - xf86AccelInfoRec.SetupForScreenToScreenCopy = - TGASetupForScreenToScreenCopy; - xf86AccelInfoRec.SubsequentScreenToScreenCopy = - TGASubsequentScreenToScreenCopy; -#endif + TGA_AccelInfoRec->Mono8x8PatternFillFlags = + HARDWARE_PATTERN_PROGRAMMED_BITS | BIT_ORDER_IN_BYTE_LSBFIRST | + HARDWARE_PATTERN_SCREEN_ORIGIN; + TGA_AccelInfoRec->SetupForMono8x8PatternFill = + TGASetupForMono8x8PatternFill; + TGA_AccelInfoRec->SubsequentMono8x8PatternFillRect = + TGASubsequentMono8x8PatternFillRect; + + /* initialize the pixmap cache */ - xf86AccelInfoRec.ServerInfoRec = &tgaInfoRec; + pScrn = xf86Screens[pScreen->myNum]; + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; /* these gotta be 0 */ + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = (pScrn->videoRam * 1024) / (pScrn->displayWidth); + xf86InitFBManager(pScreen, &AvailFBArea); - xf86AccelInfoRec.PixmapCacheMemoryStart = tgaInfoRec.virtualY * - tgaInfoRec.displayWidth * tgaInfoRec.bitsPerPixel / 8; + TGA_AccelInfoRec->PixmapCacheFlags = 0; - xf86AccelInfoRec.PixmapCacheMemoryEnd = tgaInfoRec.videoRam * 1024-1024; + /* initialize XAA */ + return(XAAInit(pScreen, TGA_AccelInfoRec)); +} + +unsigned int +fb_offset(ScrnInfoPtr pScrn, int x, int y) +{ + /* return((y * tgaInfoRec.displayWidth) + x); */ + return((y * pScrn->displayWidth) + x); +} + +void +TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w) +{ + /* copy a line of width w from x1,y1 to x2,y2 using copy mode */ + int read, span_dir, line_dir; + unsigned long a1, a2; + unsigned long source_address, destination_address; + unsigned int mask_source, mask_destination; + int source_align, destination_align; + int pixel_shift; + TGAPtr pTga = TGAPTR(pScrn); + + span_dir = BLIT_FORWARDS; + line_dir = BLIT_FORWARDS; + + a1 = fb_offset(pScrn, x1, y1); + a2 = fb_offset(pScrn, x2, y2); + + source_address = a1; + destination_address = a2; + + read = 0; + while(read < w) { + mask_source = 0xFFFFFFFF; + if((w - read) >= 32) + mask_destination = 0xFFFFFFFF; + else + mask_destination = ((unsigned int)0xFFFFFFFF) >> (32 - (w - read)); + source_align = source_address & 0x07; + destination_align = destination_address & 0x07; + source_address = source_address - source_align; + mask_source <<= source_align; + destination_address = destination_address - destination_align; + mask_destination <<= destination_align; + + if(destination_align >= source_align) + pixel_shift = destination_align - source_align; + else { + pixel_shift = 8 - (source_align - destination_align); + /* we need to prime the residue register in this case */ + destination_address = destination_address - 8; + mask_destination <<= 8; + } + + TGA_FAST_WRITE_REG(pTga, pixel_shift, TGA_PIXELSHIFT_REG); + /* use GADR and GCTR */ + TGA_FAST_WRITE_REG(pTga, source_address, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, mask_source, TGA_CONTINUE_REG); + TGA_FAST_WRITE_REG(pTga, destination_address, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, mask_destination, TGA_CONTINUE_REG); + + source_address = source_address + (32 - pixel_shift); + destination_address += 32; + + read += 32; + read -= destination_align; /* "read" is perhaps better + called "written"... */ + if(destination_align < source_align) { + read -= 8; + } + } + return; +} + + +void TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w) + /* x1, y1 = source + x2, y2 = destination + w = width + */ +{ + unsigned long a1, a2; + unsigned long source_address, destination_address; + unsigned int mask_source, mask_destination; + int source_align, destination_align; + int pixel_shift; + int read; + TGAPtr pTga = TGAPTR(pScrn); + + a1 = fb_offset(pScrn, x1, y1); + a2 = fb_offset(pScrn, x2, y2); + + source_address = fb_offset(pScrn, (x1 + w) - 32, y1); + destination_address = fb_offset(pScrn, (x2 + w) - 32, y2); + + read = 0; + while(read < w) { + mask_source = 0xFFFFFFFF; + if((w - read) >= 32) + mask_destination = 0xFFFFFFFF; + else + mask_destination = ((unsigned int)0xFFFFFFFF) << (32 - (w - read)); + + source_align = source_address & 0x07; + destination_align = destination_address & 0x07; + + if(read == 0 && destination_align && + (source_align > destination_align)) { + /* we want to take out all the destination_align pixels in one + little copy first, then move on to the main stuff */ + unsigned long tmp_src, tmp_dest; + unsigned int tmp_src_mask, tmp_dest_mask; + + tmp_src = (a1 + w) - source_align; + tmp_dest = ((a2 + w) - destination_align) - 8; + tmp_src_mask = 0xFFFFFFFF; + tmp_dest_mask = ((unsigned int)0x000000FF) >> (8 - destination_align); + tmp_dest_mask <<= 8; + pixel_shift = (8 - source_align) + destination_align; + + TGA_FAST_WRITE_REG(pTga, pixel_shift, TGA_PIXELSHIFT_REG); + TGA_FAST_WRITE_REG(pTga, tmp_src, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, tmp_src_mask, TGA_CONTINUE_REG); + TGA_FAST_WRITE_REG(pTga, tmp_dest, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, tmp_dest_mask, TGA_CONTINUE_REG); + +/* ErrorF("premature copy: sa = %d, da = %d, ps =%d\n", source_align, */ +/* destination_align, pixel_shift); */ + + source_address += (8 - source_align); + mask_source >>= (8 - source_align); + mask_source >>= destination_align; + mask_destination >>= destination_align; + } + else if(read == 0 && (source_align != destination_align)) { + source_address += (8 - source_align); + /* mask_source >>= (8 - source_align); */ + /* if we comment this out, it breaks...TGA tries to + optimize away a read of our last pixels... */ + } + else if(source_align) { + source_address += (8 - source_align); + mask_source >>= (8 - source_align); + } + if(destination_align) { + destination_address += (8 - destination_align); + mask_destination >>= (8 - destination_align); + } + + if(destination_align >= source_align) + pixel_shift = destination_align - source_align; + else { + pixel_shift = (8 - source_align) + destination_align; + if(destination_align) { + source_address += 8; + mask_source >>= 8; + } + } + + TGA_FAST_WRITE_REG(pTga, pixel_shift, TGA_PIXELSHIFT_REG); + /* use GADR and GCTR */ + TGA_FAST_WRITE_REG(pTga, source_address, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, mask_source, TGA_CONTINUE_REG); + TGA_FAST_WRITE_REG(pTga, destination_address, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, mask_destination, TGA_CONTINUE_REG); + +/* if(read == 0) */ +/* ErrorF("sa = %d, da = %d, ps = %d\n", source_align, destination_align, */ +/* pixel_shift); */ + + if(destination_align > source_align) { + source_address -= 24; + destination_address -= (32 - pixel_shift); + } + else if(destination_align == source_align) { + source_address -= 32; + destination_address -= 32; + } + else if(source_align > destination_align) { + source_address -= 24; + destination_address -= (32 - pixel_shift); + } + + if(destination_align > source_align) { + if(read == 0) + read += 24 + source_align; + else + read += 24; + } + else if(destination_align == source_align) { + if(read == 0 && destination_align) + read += (32 - (8 - destination_align)); + else + read += 32; + } + else if(source_align > destination_align) { + /* only happens when read == 0 */ + if(destination_align) + read += 16 + source_align; + else + read += 32 - pixel_shift; + } + } + return; } /* * This is the implementation of the Sync() function. */ -void TGASync() { - return; +void +TGASync() +{ +#if 0 mb(); while (TGA_READ_REG(TGA_CMD_STAT_REG) & 0x01); +#endif + return; } /* - * This is the implementation of the SetupForFillRectSolid function - * that sets up the coprocessor for a subsequent batch for solid - * rectangle fills. - */ + 1) translate the source and destination addresses into PCI addresses + 2) compute the mask source and mask destination + 3) compute the pixel shift + 4) write mask source to address source + 5) write mask destination to address destination + + Mask source and mask destination specify which pixels are read or written +*/ -void TGASetupForFillRectSolid(color, rop, planemask) - int color, rop; - unsigned planemask; +/* Block Fill mode is faster, but only works for certain rops. So we will + have to implement Opaque Fill anyway, so we will do that first, then + do Block Fill for the special cases +*/ +void +TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, + unsigned int planemask) { - TGA_WRITE_REG(TGA_MODE_REG, BLOCKFILL | BPP8UNPACK | X11 | CAP_ENDS); - TGA_WRITE_REG(TGA_RASTEROP_REG, BPP8UNPACK | rop); - TGA_WRITE_REG(TGA_FOREGROUND_REG, color | (color << 8) | - (color << 16) | (color << 24)); - TGA_WRITE_REG(TGA_PLANEMASK_REG, planemask | (planemask << 8) | - (planemask << 16) | (planemask << 24) ); + TGAPtr pTga = TGAPTR(pScrn); + + /* ErrorF("TGASetupForSolidFill called"); */ + + if(rop == MIX_SRC) { /* we can just do a block copy */ + block_or_opaque_p = USE_BLOCK_FILL; + TGA_FAST_WRITE_REG(pTga, (color | (color << 8) | (color << 16) | + (color << 24)), TGA_BLOCK_COLOR0_REG); + TGA_FAST_WRITE_REG(pTga, (color | (color << 8) | (color << 16) | + (color << 24)), TGA_BLOCK_COLOR1_REG); + } + else { + block_or_opaque_p = USE_OPAQUE_FILL; + current_rop = rop | BPP8PACKED; + TGA_FAST_WRITE_REG(pTga, (color | (color << 8) | (color << 16) | + (color << 24)), TGA_FOREGROUND_REG); +/* ErrorF("opaque fill called\n"); */ + } + + TGA_FAST_WRITE_REG(pTga, (planemask | (planemask << 8) | + (planemask << 16) | + (planemask << 24)), TGA_PLANEMASK_REG); + TGA_FAST_WRITE_REG(pTga, 0xFFFFFFFF, TGA_DATA_REG); + return; } -/* - * This is the implementation of the SubsequentForFillRectSolid function - * that sends commands to the coprocessor to fill a solid rectangle of - * the specified location and size, with the parameters from the SetUp - * call. - */ -void TGASubsequentFillRectSolid(x, y, w, h) - int x, y, w, h; + +void +TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) { - TGA_WRITE_REG(TGA_ADDRESS_REG, y * tgaInfoRec.displayWidth + x); + unsigned int mode_reg = 0; + int i = 0; + unsigned int pixel_count = 0; /* the actual # of pixels to be written */ + unsigned int write_data = 0; /* the actual data written */ + int a1 = 0; + TGAPtr pTga; + + pTga = TGAPTR(pScrn); + + /* ErrorF("TGASubsequentFillRectSolid called\n"); */ + + if(block_or_opaque_p == USE_OPAQUE_FILL) { + mode_reg = OPAQUEFILL | X11 | BPP8PACKED; + TGA_FAST_WRITE_REG(pTga, current_rop, TGA_RASTEROP_REG); + /* we have to set this to GXCOPY every time before we exit */ + } + else + mode_reg = BLOCKFILL | X11 | BPP8PACKED; + + TGA_FAST_WRITE_REG(pTga, mode_reg, TGA_MODE_REG); + + if(w > 2048) { + ErrorF("TGASubsequentSolidFillRect called with w = %d, truncating.\n"); + w = 2048; + } + pixel_count = w - 1; + + for(i = 0; i < h; i++) { + a1 = fb_offset(pScrn, x, y + i); + if(block_or_opaque_p == USE_OPAQUE_FILL) + TGA_FAST_WRITE_REG(pTga, 0xFFFFFFFF, TGA_PIXELMASK_REG); + write_data = pixel_count; + TGA_FAST_WRITE_REG(pTga, a1, TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, write_data, TGA_CONTINUE_REG); + } + + mode_reg = SIMPLE | X11 | BPP8PACKED; + TGA_FAST_WRITE_REG(pTga, mode_reg, TGA_MODE_REG); + if(block_or_opaque_p == USE_OPAQUE_FILL) +/* TGA_FAST_WRITE_REG(pTga, prev_GOPR, TGA_RASTEROP_REG); */ + TGA_FAST_WRITE_REG(pTga, MIX_SRC | BPP8PACKED, TGA_RASTEROP_REG); /* GXCOPY */ + + return; } -/* - * This is the implementation of the SetupForScreenToScreenCopy function - * that sets up the coprocessor for a subsequent batch for solid - * screen-to-screen copies. Remember, we don't handle transparency, - * so the transparency color is ignored. - */ -static int blitxdir, blitydir; - -void TGASetupForScreenToScreenCopy(xdir, ydir, rop, planemask, -transparency_color) - int xdir, ydir; - int rop; - unsigned planemask; - int transparency_color; +/* we only need to calculate the direction of a move once per move, + so we do it in the setup function and leave it */ + +void +TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, + int rop, unsigned int planemask, + int transparency_color) + /* xdir 1 = left-to-right, -1 = right to left + ydir 1 = top-to-bottom, -1 = bottom to top + */ { - int direction = 0; + TGAPtr pTga = TGAPTR(pScrn); + + /* see section 6.2.9 */ -#if 0 - if (xdir < 0) direction |= XNEG; - if (ydir < 0) direction |= YNEG; -GUI STUFF - blitxdir = xdir; - blitydir = ydir; -#endif + /* ErrorF("TGASetupForScreenToScreenCopy called\n"); */ + + TGA_FAST_WRITE_REG(pTga, (planemask | (planemask << 8) | (planemask << 16) | + (planemask << 24)), TGA_PLANEMASK_REG); + + current_rop = rop; + if(current_rop == MIX_SRC) + TGA_FAST_WRITE_REG(pTga, current_rop | BPP8PACKED, TGA_RASTEROP_REG); + + /* do we copy a rectangle from top to bottom or bottom to top? */ + if(ydir == -1) { + blitdir = BLIT_FORWARDS; + } + else { + blitdir = BLIT_BACKWARDS; + } + return; } /* * This is the implementation of the SubsequentForScreenToScreenCopy * that sends commands to the coprocessor to perform a screen-to-screen * copy of the specified areas, with the parameters from the SetUp call. - * In this sample implementation, the direction must be taken into - * account when calculating the addresses (with coordinates, it might be - * a little easier). */ -void TGASubsequentScreenToScreenCopy(x1, y1, x2, y2, w, h) - int x1, y1, x2, y2, w, h; +void +TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int w, int h) { - if (blitydir < 0) { - y1 = y1 + h - 1; - y2 = y2 + h - 1; + /* x1, y1 = source coords + x2, y2 = destination coords + w = width + h = height + */ + + int i = 0, mode_reg = 0; + void (*copy_func)(); + TGAPtr pTga = TGAPTR(pScrn); + + /* ErrorF("TGASubsequentScreenToScreenCopy called\n"); */ + + mode_reg = COPY | X11 | BPP8PACKED; /* the others are 0 but what the + heck */ + TGA_FAST_WRITE_REG(pTga, mode_reg, TGA_MODE_REG); + if(current_rop != MIX_SRC) + TGA_FAST_WRITE_REG(pTga, current_rop | BPP8PACKED, TGA_RASTEROP_REG); + + if(x2 > x1 && (x1 + w) > x2) + copy_func = TGACopyLineBackwards; + else + copy_func = TGACopyLineForwards; + /* copy_func = TGA_copy_line; */ + + if(blitdir == BLIT_FORWARDS) { + for(i = h - 1; i >= 0; i--) { /* copy from bottom to top */ + (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); } - if (blitxdir < 0) { - x1 = x1 + w - 1; - x2 = x2 + w - 1; + } + else { + for(i = 0; i < h; i++) { + (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); } + } + mode_reg = SIMPLE | X11 | BPP8PACKED; + TGA_FAST_WRITE_REG(pTga, mode_reg,TGA_MODE_REG); + if(current_rop != MIX_SRC) + TGA_FAST_WRITE_REG(pTga, MIX_SRC | BPP8PACKED, TGA_RASTEROP_REG); + + return; } + +void +TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, + int fg, int bg, int rop, unsigned int planemask) +{ + TGAPtr pTga = TGAPTR(pScrn); + +/* ErrorF("TGASetupForMono8x8PatternFill called with patx = %d, paty = %d, fg = %d, bg = %d, rop = %d, planemask = %d\n", */ +/* patx, paty, fg, bg, rop, planemask); */ + if(bg == -1) /* we are transparent */ + transparent_pattern_p = 1; + else + transparent_pattern_p = 0; + + if(rop == MIX_SRC) + block_or_opaque_p = USE_BLOCK_FILL; + else + block_or_opaque_p = USE_OPAQUE_FILL; + + if(transparent_pattern_p && block_or_opaque_p == USE_BLOCK_FILL) { + /* we can use block fill mode to draw a transparent stipple */ + TGA_FAST_WRITE_REG(pTga, (fg | (fg << 8) | (fg << 16) | (fg << 24)), + TGA_BLOCK_COLOR0_REG); + TGA_FAST_WRITE_REG(pTga, (fg | (fg << 8) | (fg << 16) | (fg << 24)), + TGA_BLOCK_COLOR1_REG); + } + else if(transparent_pattern_p) { + TGA_FAST_WRITE_REG(pTga, (fg | (fg << 8) | (fg << 16) | (fg << 24)), + TGA_FOREGROUND_REG); + } + else { + TGA_FAST_WRITE_REG(pTga, (bg | (bg << 8) | (bg << 16) | (bg << 24)), + TGA_BACKGROUND_REG); + TGA_FAST_WRITE_REG(pTga, (fg | (fg << 8) | (fg << 16) | (fg << 24)), + TGA_FOREGROUND_REG); + TGA_FAST_WRITE_REG(pTga, 0xFFFFFFFF, TGA_PIXELMASK_REG); + } + current_rop = rop; + TGA_FAST_WRITE_REG(pTga, (planemask | (planemask << 8) | (planemask << 16) | + (planemask << 24)), TGA_PLANEMASK_REG); + + return; +} + +void +TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty, + int x, int y, int w, int h) +/* patx and paty = first & second dwords of pattern to be rendered, packed */ +{ + TGAPtr pTga; + int i, j; + unsigned int stipple_mask[8], align, tmp; + + +/* ErrorF("TGASubsequentMono8x8PatternFillRect called with x = %d, y = %d, w = %d, h = %d\n", x, y, w, h); */ + + pTga = TGAPTR(pScrn); + + if(w > 2048) + ErrorF("TGASubsequentMono8x8PatternFillRect called with w > 2048, truncating\n"); + if(block_or_opaque_p == USE_OPAQUE_FILL) + TGA_FAST_WRITE_REG(pTga, current_rop | BPP8PACKED, TGA_RASTEROP_REG); + + align = fb_offset(pScrn, x, y) % 4; + + for(i = 0; i < 4; i++) { + tmp = (patx >> (i * 8)) & 0xFF; + stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); + } + for(i = 4; i < 8; i++) { + tmp = (paty >> ((i - 4) * 8)) & 0xFF; + stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); + } + if(align) { /* stipples must be aligned to four bytes */ + for(i = 0; i < 8; i++) { + stipple_mask[i] = (stipple_mask[i] << align) | + ((stipple_mask[i] & 0xFF000000) >> (32 - align)); + } + } + + if((block_or_opaque_p == USE_BLOCK_FILL) && transparent_pattern_p) { + /* use block fill */ + TGA_FAST_WRITE_REG(pTga, BLOCKFILL | X11 | BPP8PACKED, TGA_MODE_REG); + + for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { + TGA_FAST_WRITE_REG(pTga, stipple_mask[j], TGA_DATA_REG); + TGA_FAST_WRITE_REG(pTga, fb_offset(pScrn, x, y + i), TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, w - 1, TGA_CONTINUE_REG); + } + } + else if(transparent_pattern_p) { + /* if we can't use block fill, we'll use transparent fill */ + TGA_FAST_WRITE_REG(pTga, TRANSPARENTFILL | X11 | BPP8PACKED, TGA_MODE_REG); + for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { + TGA_FAST_WRITE_REG(pTga, stipple_mask[j], TGA_DATA_REG); + TGA_FAST_WRITE_REG(pTga, fb_offset(pScrn, x, y + i), TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, w - 1, TGA_CONTINUE_REG); + } + } + else { /* use opaque fill mode */ +/* ErrorF("Using opaque fill mode\n"); */ + TGA_FAST_WRITE_REG(pTga, OPAQUEFILL | X11 | BPP8PACKED, TGA_MODE_REG); + for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { + TGA_FAST_WRITE_REG(pTga, stipple_mask[j], TGA_DATA_REG); + TGA_FAST_WRITE_REG(pTga, fb_offset(pScrn, x, y + i), TGA_ADDRESS_REG); + TGA_FAST_WRITE_REG(pTga, w - 1, TGA_CONTINUE_REG); + } + } + + TGA_FAST_WRITE_REG(pTga, SIMPLE | X11 | BPP8PACKED, TGA_MODE_REG); + if(current_rop != MIX_SRC) + TGA_FAST_WRITE_REG(pTga, MIX_SRC | BPP8PACKED, TGA_RASTEROP_REG); + return; +} + diff --git a/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c b/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c index ccfdf0556..3bdbbe001 100644 --- a/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c +++ b/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c @@ -21,7 +21,7 @@ * * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c,v 1.11 1999/01/14 13:04:34 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c,v 1.12 1999/01/17 10:54:05 dawes Exp $ */ #define PSZ 8 #include "cfb.h" @@ -363,7 +363,7 @@ GetAccelPitchValues(ScrnInfoPtr pScrn) int *linePitches = NULL; int i, n = 0; int *linep = NULL; - TGAPtr pTga = TGAPTR(pScrn); + /* TGAPtr pTga = TGAPTR(pScrn); */ for (i = 0; linep[i] != 0; i++) { if (linep[i] != -1) { @@ -519,6 +519,10 @@ TGAPreInit(ScrnInfoPtr pScrn, int flags) pTga->UsePCIRetry = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); } + if(pScrn->depth > 8) { + pTga->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "No acceleration for >8bpp cards yet\n"); + } /* Find the PCI slot for this screen */ if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL)) != 1) { @@ -583,7 +587,7 @@ TGAPreInit(ScrnInfoPtr pScrn, int flags) pTga->FbAddress = pScrn->device->MemBase; from = X_CONFIG; } else { - pTga->FbAddress = pTga->PciInfo->memBase[0] & 0xFF800000; + pTga->FbAddress = pTga->PciInfo->memBase[0] & 0xFF800000; } /* Adjust MMIO region */ @@ -593,11 +597,11 @@ TGAPreInit(ScrnInfoPtr pScrn, int flags) Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pTga->PciTag, (pointer)pTga->IOAddress, 4); pTga->CardType = (*(unsigned int *)Base >> 12) & 0xf; - xf86UnMapVidMem(pScrn->scrnIndex, Base, 4); + xf86UnMapVidMem(pScrn->scrnIndex, Base, 4); /* Adjust framebuffer for card type */ pTga->FbAddress += fb_offset_presets[pTga->CardType]; - + switch (pTga->CardType) { case TYPE_TGA_8PLANE: case TYPE_TGA_24PLANE: @@ -620,6 +624,7 @@ TGAPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", (unsigned long)pTga->FbAddress); @@ -679,9 +684,14 @@ TGAPreInit(ScrnInfoPtr pScrn, int flags) RamDacDestroyInfoRec(pTga->RamDacRec); return FALSE; } + TGAMapMem(pScrn); + + pTga->RamDac = BTramdacProbe(pScrn, BTramdacs); - TGAUnmapMem(pScrn); + + TGAUnmapMem(pScrn); + if (pTga->RamDac == NULL) return FALSE; break; @@ -823,14 +833,14 @@ TGAPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } -#if 0 + /* Load XAA if needed */ if (!pTga->NoAccel || pTga->HWCursor) if (!xf86LoadSubModule(pScrn, "xaa")) { TGAFreeRec(pScrn); return FALSE; } -#endif + return TRUE; } @@ -900,9 +910,14 @@ TGAMapMem(ScrnInfoPtr pScrn) * for Alpha, we need to map DENSE memory as well, for * setting CPUToScreenColorExpandBase. */ +#if 0 + pTga->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, + pTga->PciTag, (pointer)pTga->IOAddress, + 0x10000); +#endif pTga->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, - pTga->PciTag, (pointer)pTga->IOAddress, - 0x10000); + pTga->PciTag, + (pointer)pTga->IOAddress, 0x100000); if (pTga->IOBaseDense == NULL) return FALSE; #endif /* __alpha__ */ @@ -952,6 +967,7 @@ TGAUnmapMem(ScrnInfoPtr pScrn) xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->FbBase, pScrn->videoRam); pTga->FbBase = NULL; + return TRUE; } @@ -1187,15 +1203,27 @@ TGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) switch (pTga->Chipset) { case PCI_CHIP_DEC21030: -#if 0 - TGAAccelInit(pScreen); -#endif + + if(DEC21030AccelInit(pScreen) == FALSE) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "XAA Initialization failed\n"); break; } } /* Initialise cursor functions */ miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); +#if 0 + /* AFAIK, TGA HW cursor doesn't support the features of the X + hardware cursor */ + /* Initialize HW cursor layer. + Must follow software cursor initialization*/ + if (pTga->HWCursor) { + if(!TGAHWCursorInit(pScreen)) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + } +#endif /* Initialise default colourmap */ if (!miCreateDefColormap(pScreen)) @@ -1272,8 +1300,15 @@ TGAEnterVT(int scrnIndex, int flags) static void TGALeaveVT(int scrnIndex, int flags) { + TGAPtr pTga; ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + pTga = TGAPTR(pScrn); TGARestore(pScrn); + + /* clear the screen...there's probably a better way to do this */ + memset(pTga->FbBase, 0, pTga->FbMapSize); + return; } diff --git a/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h b/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h index b9101b042..be19154fa 100644 --- a/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h +++ b/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h @@ -21,7 +21,7 @@ * * Author: Alan Hourihane, <alanh@fairlite.demon.co.uk> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h,v 1.1.2.1 1998/07/18 17:53:47 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h,v 1.2 1998/07/25 16:55:58 dawes Exp $ */ /* TGA hardware description (minimal) * @@ -34,31 +34,46 @@ #ifndef TGA_REGS_H #define TGA_REGS_H +#include "compiler.h" + #define TYPE_TGA_8PLANE 0 #define TYPE_TGA_24PLANE 1 #define TYPE_TGA_24PLUSZ 3 #ifdef __alpha__ -#define TGA_WRITE_REG(v,r) \ - { *(unsigned int *)((char*)(pTga->IOBaseDense)+(r)) = v; mb(); } +/* we can avoid an mb() if we write to an alternate register space each time */ +extern unsigned int tga_reg_offset; /* in tga_accel.c */ + +/* XXX should tga_reg_offset be screen-specific rather than global? */ +#define TGA_FAST_WRITE_REG(pTga,v,r) \ +do {\ + *(unsigned int *)(((char *)pTga->IOBaseDense) + tga_reg_offset + (r)) = v;\ + if(tga_reg_offset >= 1047552) (tga_reg_offset = 0); else (tga_reg_offset += 1024);\ +} while (0) + +#define TGA_WRITE_REG(v,r) \ + do {\ + *(unsigned int *)((char*)(pTga->IOBaseDense)+(r)) = v;\ + mem_barrier();\ + } while (0) #define TGA_READ_REG(r) \ ( *(unsigned int *)((char*)(pTga->IOBaseDense)+(r))) + #else #define TGA_WRITE_REG(v,r) \ - { *(unsigned int *)((char*)(pTga->IOBase)+(r)) = v; } + *(unsigned int *)((char*)(pTga->IOBase)+(r)) = v; + +#define TGA_FAST_WRITE_REG(pTga,v,r) TGA_WRITE_REG(v,r) #define TGA_READ_REG(r) \ ( *(unsigned int *)((char*)(pTga->IOBase)+(r))) -#endif +#endif /* __alpha__ */ #define BT485_WRITE(v,r) \ TGA_WRITE_REG((r),TGA_RAMDAC_SETUP_REG); \ TGA_WRITE_REG(((v)&0xff)|((r)<<8),TGA_RAMDAC_REG); -#define mb() \ - __asm__ __volatile__("mb": : :"memory") - #define TGA_ROM_OFFSET 0x0000000 #define TGA_REGS_OFFSET 0x0100000 #define TGA_8PLANE_FB_OFFSET 0x0200000 @@ -86,10 +101,17 @@ #define CAP_ENDS 0x8000 #define X11 0x0000 #define WIN32 0x2000 + /* copy mode */ +#define COPY 0x07 + /* opaque fill mode */ +#define OPAQUEFILL 0x21 +#define TRANSPARENTFILL 0x45 #define TGA_RASTEROP_REG 0x0034 +#define TGA_PIXELSHIFT_REG 0x0038 #define TGA_ADDRESS_REG 0x003c +#define TGA_CONTINUE_REG 0x004c #define TGA_DEEP_REG 0x0050 -#define TGA_PIXELMASK_REG 0x005c +#define TGA_PIXELMASK_REG 0x002c #define TGA_CURSOR_BASE_REG 0x0060 #define TGA_HORIZ_REG 0x0064 #define TGA_VERT_REG 0x0068 @@ -97,8 +119,23 @@ #define TGA_VALID_REG 0x0070 #define TGA_CURSOR_XY_REG 0x0074 #define TGA_INTR_STAT_REG 0x007c + /* GDAR */ +#define TGA_DATA_REG 0x0080 +#define TGA_WIDTH_REG 0x009c #define TGA_SPAN_REG 0x00bc #define TGA_RAMDAC_SETUP_REG 0x00c0 +#define TGA_SLOPE0_REG 0x0120 +#define TGA_SLOPE1_REG 0x0124 +#define TGA_SLOPE2_REG 0x0128 +#define TGA_SLOPE3_REG 0x012C +#define TGA_SLOPE4_REG 0x0130 +#define TGA_SLOPE5_REG 0x0134 +#define TGA_SLOPE6_REG 0x0138 +#define TGA_SLOPE7_REG 0x013C +#define TGA_BRES3_REG 0x0048; +#define TGA_BRES2_REG 0x0044; +#define TGA_BRES1_REG 0x0040; + #define TGA_BLOCK_COLOR0_REG 0x0140 #define TGA_BLOCK_COLOR1_REG 0x0144 #define TGA_CLOCK_REG 0x01e8 diff --git a/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c b/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c index 703d1d97c..c71601877 100644 --- a/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c +++ b/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c @@ -23,7 +23,7 @@ * * Trident 3DImage' accelerated options. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c,v 1.1 1998/11/15 04:30:32 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c,v 1.2 1998/11/15 05:53:24 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -146,7 +146,9 @@ ImageAccelInit(ScreenPtr pScreen) ImageInitializeAccelerator(pScrn); - infoPtr->Flags = PIXMAP_CACHE; + infoPtr->Flags = PIXMAP_CACHE | + LINEAR_FRAMEBUFFER | + OFFSCREEN_PIXMAPS; infoPtr->Sync = ImageSync; @@ -189,14 +191,12 @@ ImageAccelInit(ScreenPtr pScreen) infoPtr->SubsequentColor8x8PatternFillRect = TridentSubsequentColor8x8PatternFillRect; - infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | - NO_TRANSPARENCY | - BIT_ORDER_IN_BYTE_MSBFIRST; + infoPtr->ScreenToScreenColorExpandFillFlags = NO_TRANSPARENCY |NO_PLANEMASK; infoPtr->SetupForScreenToScreenColorExpandFill = - TridentSetupForScreenToScreenColorExpand; + ImageSetupForScreenToScreenColorExpand; infoPtr->SubsequentScreenToScreenColorExpandFill = - TridentSubsequentScreenToScreenColorExpand; + ImageSubsequentScreenToScreenColorExpand; infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD | NO_TRANSPARENCY | @@ -300,7 +300,7 @@ ImageSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, IMAGE_OUT(0x0C, (y2+h-1)<<16 | (x2+w-1)); } - IMAGE_OUT(0x24, 0x80000000 | 1<<22 | 1<<7 | 1<<10 | pTrident->BltScanDirection); + IMAGE_OUT(0x24, 0x80000000 | 1<<22 | 1<<7 | (pTrident->ROP == GXcopy ? 0 : 1<<10) | pTrident->BltScanDirection); if (!pTrident->UsePCIRetry) ImageSync(pScrn); @@ -359,6 +359,7 @@ ImageSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, TRIDENTPtr pTrident = TRIDENTPTR(pScrn); REPLICATE(color); + pTrident->ROP = rop; IMAGE_OUT(0x20, 0x40000000 | pTrident->EngineOperation); IMAGE_OUT(0x44, color); IMAGE_OUT(0x48, color); @@ -372,7 +373,7 @@ ImageSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) IMAGE_OUT(0x08, y<<16 | x); IMAGE_OUT(0x0C, (y+h-1)<<16 | x+w-1); - IMAGE_OUT(0x24, 0x80000000 | 1<<22 | 1<<10 | 1<<9); + IMAGE_OUT(0x24, 0x80000000 | 3<<22 | (pTrident->ROP == GXcopy ? 0 : 1<<10) | 1<<9); if (!pTrident->UsePCIRetry) ImageSync(pScrn); } @@ -384,13 +385,13 @@ ImageSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); - REPLICATE(fg); - TGUI_FCOLOUR(fg); - REPLICATE(bg); - TGUI_BCOLOUR(bg); + pTrident->ROP = rop; - TGUI_DRAWFLAG(SRCMONO | SCR2SCR); - TGUI_FMIX(TGUIRops_alu[rop]); + REPLICATE(bg); + REPLICATE(fg); + IMAGE_OUT(0x44, fg); + IMAGE_OUT(0x48, bg); + IMAGE_OUT(0x20, 0x90000000 | TGUIRops_alu[rop]); } static void @@ -399,13 +400,15 @@ ImageSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); - TGUI_SRC_XY(srcx,srcy); - TGUI_DEST_XY(x,y); - TGUI_DIM_XY(w,h); - TGUI_COMMAND(GE_BLT); + IMAGE_OUT(0x00, srcy<<16 | srcx); + IMAGE_OUT(0x04, (srcy+h-1)<<16 | (srcx+w-1)); + IMAGE_OUT(0x08, y<<16 | x); + IMAGE_OUT(0x0C, (y+h-1)<<16 | (x+w-1)); + + IMAGE_OUT(0x24, 0x80000000 | 3<<22 | 1<<7 | (pTrident->ROP == GXcopy ? 0 : 1<<10) | offset<<25); + if (!pTrident->UsePCIRetry) ImageSync(pScrn); - CHECKCLIPPING; } static void @@ -556,13 +559,13 @@ ImageSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, } else { IMAGE_OUT(0x20, 0x80000000 | 1<<27); } - IMAGE_OUT(0x34, (patternx & 0xFF000000)>>24); + IMAGE_OUT(0x30, (patternx & 0xFF000000)>>24); IMAGE_OUT(0x30, (patternx & 0xFF0000)>>16); - IMAGE_OUT(0x34, (patternx & 0xFF00)>>8); + IMAGE_OUT(0x30, (patternx & 0xFF00)>>8); IMAGE_OUT(0x30, (patternx & 0xFF)); - IMAGE_OUT(0x34, (patterny & 0xFF000000)>>24); + IMAGE_OUT(0x30, (patterny & 0xFF000000)>>24); IMAGE_OUT(0x30, (patterny & 0xFF0000)>>16); - IMAGE_OUT(0x34, (patterny & 0xFF00)>>8); + IMAGE_OUT(0x30, (patterny & 0xFF00)>>8); IMAGE_OUT(0x30, (patterny & 0xFF)); IMAGE_OUT(0x50, fg); IMAGE_OUT(0x54, bg); @@ -578,7 +581,7 @@ ImageSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, IMAGE_OUT(0x08, y<<16 | x); IMAGE_OUT(0x0C, (y+h-1)<<16 | x+w-1); - IMAGE_OUT(0x24, 0x80000000 | 1<<10 | 1<<22 | 1<<9); + IMAGE_OUT(0x24, 0x80000000 | 7<<18 | 1<<10 | 3<<22 | 1<<9); if (!pTrident->UsePCIRetry) ImageSync(pScrn); } diff --git a/programs/Xserver/hw/xfree86/drivers/trident/trident.h b/programs/Xserver/hw/xfree86/drivers/trident/trident.h index f4a4e6bf6..d54a54fd4 100644 --- a/programs/Xserver/hw/xfree86/drivers/trident/trident.h +++ b/programs/Xserver/hw/xfree86/drivers/trident/trident.h @@ -21,7 +21,7 @@ * * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h,v 1.3 1998/11/15 04:30:32 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h,v 1.4 1999/01/11 05:13:31 dawes Exp $ */ #ifndef _TRIDENT_H_ #define _TRIDENT_H_ @@ -45,6 +45,7 @@ typedef struct { #define TRIDENTPTR(p) ((TRIDENTPtr)((p)->driverPrivate)) typedef struct { + ScrnInfoPtr pScrn; pciVideoPtr PciInfo; PCITAG PciTag; int Chipset; @@ -67,19 +68,22 @@ typedef struct { Bool NoMMIO; Bool HWCursor; Bool UsePCIRetry; + Bool UseGERetry; Bool NewClockCode; Bool IsCyber; Bool Clipping; Bool DstEnable; Bool ROP; Bool HasSGRAM; + Bool MUX; float frequency; int MinClock; int MaxClock; + int MUXThreshold; + int MCLK; TRIDENTRegRec SavedReg; TRIDENTRegRec ModeReg; - I2CBusPtr I2CPtr1; - I2CBusPtr I2CPtr2; + I2CBusPtr DDC; short EngineOperation; CARD32 AccelFlags; CARD32 BltScanDirection; @@ -87,10 +91,12 @@ typedef struct { xf86CursorInfoPtr CursorInfoRec; XAAInfoRecPtr AccelInfoRec; CloseScreenProcPtr CloseScreen; + unsigned int (*ddc1Read)(ScrnInfoPtr); } TRIDENTRec, *TRIDENTPtr; /* Prototypes */ +unsigned int Tridentddc1Read(ScrnInfoPtr pScrn); void TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg); void TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg); Bool TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode); @@ -145,8 +151,7 @@ float CalculateMCLK(ScrnInfoPtr pScrn); #define IMAGE985 26 #define CYBER939A 27 -#define HAS_DST_TRANS ((pTrident->Chipset == PROVIDIA9682) || \ - (pTrident->Chipset == PROVIDIA9685)) +#define HAS_DST_TRANS (pTrident->Chipset == PROVIDIA9682) #define Is3Dchip ((pTrident->Chipset == CYBER9388) || \ (pTrident->Chipset == CYBER9397) || \ diff --git a/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c b/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c index a4982c2f3..9cdd35e33 100644 --- a/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c +++ b/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c @@ -23,7 +23,7 @@ * * Trident accelerated options. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c,v 1.3 1999/01/03 03:58:38 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c,v 1.4 1999/01/11 05:13:31 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -135,6 +135,8 @@ TridentInitializeAccelerator(ScrnInfoPtr pScrn) TRIDENTPtr pTrident = TRIDENTPTR(pScrn); CHECKCLIPPING; + if (pTrident->Chipset == PROVIDIA9682) + pTrident->EngineOperation |= 0x100; /* Disable Clipping */ TGUI_OPERMODE(pTrident->EngineOperation); } @@ -148,7 +150,6 @@ TridentAccelInit(ScreenPtr pScreen) pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); if (!infoPtr) return FALSE; - if (pScrn->bitsPerPixel == 24) return FALSE; /* Not supported yet */ TridentInitializeAccelerator(pScrn); @@ -185,18 +186,16 @@ TridentAccelInit(ScreenPtr pScreen) infoPtr->SubsequentScreenToScreenCopy = TridentSubsequentScreenToScreenCopy; - if (pTrident->Chipset != PROVIDIA9685) { - infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | + infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | + NO_TRANSPARENCY | HARDWARE_PATTERN_SCREEN_ORIGIN | - BIT_ORDER_IN_BYTE_MSBFIRST | - NO_TRANSPARENCY; + BIT_ORDER_IN_BYTE_MSBFIRST; - infoPtr->SetupForMono8x8PatternFill = + infoPtr->SetupForMono8x8PatternFill = TridentSetupForMono8x8PatternFill; - infoPtr->SubsequentMono8x8PatternFillRect = + infoPtr->SubsequentMono8x8PatternFillRect = TridentSubsequentMono8x8PatternFillRect; - infoPtr->MonoPatternPitch = 64; - } + infoPtr->MonoPatternPitch = 64; #if 0 infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK | @@ -212,8 +211,7 @@ TridentAccelInit(ScreenPtr pScreen) #if 0 infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | - NO_TRANSPARENCY | - BIT_ORDER_IN_BYTE_MSBFIRST; + NO_TRANSPARENCY; infoPtr->SetupForScreenToScreenColorExpandFill = TridentSetupForScreenToScreenColorExpand; @@ -221,21 +219,24 @@ TridentAccelInit(ScreenPtr pScreen) TridentSubsequentScreenToScreenColorExpand; #endif -#if 0 - infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD | - NO_TRANSPARENCY | + if (pTrident->Chipset == PROVIDIA9685) { + infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD | + LEFT_EDGE_CLIPPING | + LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND | BIT_ORDER_IN_BYTE_MSBFIRST | SCANLINE_PAD_DWORD | + NO_TRANSPARENCY | NO_PLANEMASK; - infoPtr->ColorExpandRange = pScrn->displayWidth * pScrn->bitsPerPixel / 8; - infoPtr->ColorExpandBase = pTrident->FbBase; - infoPtr->SetupForCPUToScreenColorExpandFill = + infoPtr->ColorExpandRange = pScrn->displayWidth * pScrn->bitsPerPixel/8; + infoPtr->ColorExpandBase = pTrident->FbBase; + infoPtr->SetupForCPUToScreenColorExpandFill = TridentSetupForCPUToScreenColorExpand; - infoPtr->SubsequentCPUToScreenColorExpandFill = + infoPtr->SubsequentCPUToScreenColorExpandFill = TridentSubsequentCPUToScreenColorExpand; -#endif + } + /* Requires clipping, therefore only 9660's or above */ if (pTrident->Chipset > CYBER9320) { infoPtr->WritePixmap = TridentWritePixmap; infoPtr->WritePixmapFlags = NO_PLANEMASK; @@ -300,7 +301,7 @@ TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, if (transparency_color != -1) { pTrident->DstEnable = TRUE; if (pTrident->Chipset == PROVIDIA9685) { - dst = 1<<16; + dst = 3<<16; } else { TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE); } @@ -308,6 +309,12 @@ TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, TGUI_CKEY(transparency_color); } + if ((pTrident->Chipset == PROVIDIA9682 || + pTrident->Chipset == TGUI9680) && rop == GXcopy) + dst = FASTMODE; + + if (pTrident->Chipset == PROVIDIA9685 && rop == GXcopy) dst |= 1<<21; + TGUI_DRAWFLAG(pTrident->BltScanDirection | SCR2SCR | dst); TGUI_FMIX(TGUIRops_alu[rop]); } @@ -330,7 +337,7 @@ TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, TGUI_DEST_XY(x2,y2); TGUI_DIM_XY(w,h); TGUI_COMMAND(GE_BLT); - if (!pTrident->UsePCIRetry) + if (!pTrident->UseGERetry) TridentSync(pScrn); CHECKCLIPPING; if (pTrident->DstEnable) { @@ -390,7 +397,7 @@ TridentSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, TGUI_DEST_XY(x,y); TGUI_DIM_XY(dmin+e,len); TGUI_COMMAND(GE_BRESLINE); - if (!pTrident->UsePCIRetry) + if (!pTrident->UseGERetry) TridentSync(pScrn); CHECKCLIPPING; } @@ -400,12 +407,16 @@ TridentSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int drawflag = 0; REPLICATE(color); TGUI_FCOLOUR(color); TGUI_BCOLOUR(color); TGUI_FMIX(TGUIRops_Pixalu[rop]); - TGUI_DRAWFLAG(SOLIDFILL | PATMONO); + if ((pTrident->Chipset == PROVIDIA9682 || + pTrident->Chipset == TGUI9680) && rop == GXcopy) drawflag = FASTMODE; + if (pTrident->Chipset == PROVIDIA9685 && rop == GXcopy) drawflag |= 1<<21; + TGUI_DRAWFLAG(SOLIDFILL | PATMONO | drawflag); } static void @@ -429,7 +440,7 @@ TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) TGUI_DIM_XY(w,h); TGUI_DEST_XY(x,y); TGUI_COMMAND(GE_BLT); - if (!pTrident->UsePCIRetry) + if (!pTrident->UseGERetry) TridentSync(pScrn); CHECKCLIPPING; } @@ -442,8 +453,8 @@ TridentSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, TRIDENTPtr pTrident = TRIDENTPTR(pScrn); REPLICATE(fg); - TGUI_FCOLOUR(fg); REPLICATE(bg); + TGUI_FCOLOUR(fg); TGUI_BCOLOUR(bg); TGUI_DRAWFLAG(SRCMONO | SCR2SCR); @@ -456,11 +467,12 @@ TridentSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + TGUI_OUTL(0x44, (offset << 28) | ((srcy * pScrn->displayWidth + srcx) * pScrn->bitsPerPixel * 8)); TGUI_SRC_XY(srcx,srcy); TGUI_DEST_XY(x,y); TGUI_DIM_XY(w,h); TGUI_COMMAND(GE_BLT); - if (!pTrident->UsePCIRetry) + if (!pTrident->UseGERetry) TridentSync(pScrn); CHECKCLIPPING; } @@ -471,18 +483,22 @@ TridentSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn, unsigned int planemask) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int drawflag = 0; + + if (bg != -1) + drawflag |= SRCMONO; + else + drawflag |= SRCMONO | 1<<12; + if (pTrident->Chipset == PROVIDIA9685) + drawflag |= 1<<30; + REPLICATE(fg); REPLICATE(bg); TGUI_FCOLOUR(fg); TGUI_BCOLOUR(bg); - - if (bg != -1) { - TGUI_DRAWFLAG(SRCMONO); - } else { - TGUI_DRAWFLAG(SRCMONO | 1<<12); - } TGUI_SRC_XY(0,0); + TGUI_DRAWFLAG(drawflag); TGUI_FMIX(TGUIRops_alu[rop]); } @@ -491,14 +507,22 @@ TridentSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int bpp = pScrn->bitsPerPixel >> 3; -#if 0 - TridentSetClippingRectangle(pScrn,x,y,((w+x)*(pScrn->bitsPerPixel>>3))-1,y+h-1); -#endif + TridentSetClippingRectangle(pScrn,((x+skipleft)*bpp),y,((w+x)*bpp)-1,y+h-1); + + if (pTrident->Chipset == PROVIDIA9682) + TGUI_OPERMODE(pTrident->EngineOperation & 0xFEFF); TGUI_DEST_XY(x,y); TGUI_DIM_XY(w,h); TGUI_COMMAND(GE_BLT); + + if (!pTrident->UseGERetry) + TridentSync(pScrn); + + if (pTrident->Chipset == PROVIDIA9682) + TGUI_OPERMODE(pTrident->EngineOperation); } static void MoveDWORDS( @@ -553,7 +577,7 @@ TridentWritePixmap( if (transparency_color != -1) { pTrident->DstEnable = TRUE; if (pTrident->Chipset == PROVIDIA9685) { - dst = 1<<16; + dst = 3<<16; } else { TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE); } @@ -565,10 +589,18 @@ TridentWritePixmap( TGUI_DEST_XY(x,y); TGUI_DIM_XY(w,h); if (pTrident->Chipset == PROVIDIA9685) { + if (rop == GXcopy) dst |= 1<<21; TGUI_DRAWFLAG(1<<30 | dst); /* Enable Clipping */ } else { - TGUI_DRAWFLAG(0); + if ((pTrident->Chipset == PROVIDIA9682 || + pTrident->Chipset == TGUI9680) && rop == GXcopy) { + TGUI_DRAWFLAG(FASTMODE); + } else { + TGUI_DRAWFLAG(0); + } } + if (pTrident->Chipset == PROVIDIA9682) + TGUI_OPERMODE(pTrident->EngineOperation & 0xFEFF); /* Enable Clipping */ TGUI_COMMAND(GE_BLT); if (pScrn->bitsPerPixel == 8) @@ -581,7 +613,7 @@ TridentWritePixmap( src += srcwidth; } - if (pTrident->UsePCIRetry) + if (pTrident->UseGERetry) SET_SYNC_FLAG(infoRec); else TridentSync(pScrn); @@ -592,6 +624,8 @@ TridentWritePixmap( } pTrident->DstEnable = FALSE; } + if (pTrident->Chipset == PROVIDIA9682) + TGUI_OPERMODE(pTrident->EngineOperation); CHECKCLIPPING; } @@ -603,12 +637,23 @@ TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, unsigned int planemask) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int drawflag = 0; REPLICATE(bg); - TGUI_BCOLOUR(bg); REPLICATE(fg); - TGUI_FCOLOUR(fg); - TGUI_DRAWFLAG(PAT2SCR | PATMONO); + if (pTrident->Chipset == PROVIDIA9685) { + drawflag |= 7<<18; + TGUI_BPATCOL(bg); + TGUI_FPATCOL(fg); + if (rop == GXcopy) drawflag |= 1<<21; + } else { + TGUI_BCOLOUR(bg); + TGUI_FCOLOUR(fg); + if ((pTrident->Chipset == PROVIDIA9682 || + pTrident->Chipset == TGUI9680) && rop == GXcopy) + drawflag |= FASTMODE; + } + TGUI_DRAWFLAG(PAT2SCR | PATMONO | drawflag); TGUI_PATLOC(((patterny * pScrn->displayWidth * pScrn->bitsPerPixel / 8) + (patternx * pScrn->bitsPerPixel / 8)) >> 6); TGUI_FMIX(TGUIRops_Pixalu[rop]); @@ -625,7 +670,7 @@ TridentSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, TGUI_DEST_XY(x,y); TGUI_DIM_XY(w,h); TGUI_COMMAND(GE_BLT); - if (!pTrident->UsePCIRetry) + if (!pTrident->UseGERetry) TridentSync(pScrn); CHECKCLIPPING; } @@ -661,7 +706,7 @@ TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, TGUI_DEST_XY(x,y); TGUI_DIM_XY(w,h); TGUI_COMMAND(GE_BLT); - if (!pTrident->UsePCIRetry) + if (!pTrident->UseGERetry) TridentSync(pScrn); CHECKCLIPPING; } diff --git a/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c b/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c index d4c246322..0ac0743be 100644 --- a/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c +++ b/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.4 1999/01/03 03:58:38 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.5 1999/01/11 05:13:31 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -24,26 +24,48 @@ TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode) vgaIOBase = VGAHWPTR(pScrn)->IOBase; pReg->tridentRegs3x4[PixelBusReg] = 0x00; + pReg->tridentRegsDAC[0x00] = 0x00; + outb(vgaIOBase + 4, NewMode2); + pReg->tridentRegs3C4[NewMode2] = inb(vgaIOBase + 5) & 0xF9; + /* Enable Chipset specific options */ switch (pTrident->Chipset) { + case IMAGE975: + case IMAGE985: + case PROVIDIA9685: + if (pTrident->UsePCIRetry) { + pTrident->UseGERetry = TRUE; + outb(vgaIOBase + 4, Enhancement0); + pReg->tridentRegs3x4[Enhancement0] = inb(vgaIOBase + 5) | 0x70; + } else { + pTrident->UseGERetry = FALSE; + outb(vgaIOBase + 4, Enhancement0); + pReg->tridentRegs3x4[Enhancement0] = inb(vgaIOBase + 5) & 0x8F; + } + /* Fall Through */ + case TGUI9660: + case TGUI9680: case PROVIDIA9682: - pReg->tridentRegs3x4[PixelBusReg] |= 0x40; /* Late Sync */ + if (pTrident->MUX && pScrn->bitsPerPixel == 8 && mode->CrtcHAdjusted) { + pReg->tridentRegs3x4[PixelBusReg] |= 0x01; /* 16bit bus */ + pReg->tridentRegs3C4[NewMode2] |= 0x02; /* half clock */ + pReg->tridentRegsDAC[0x00] |= 0x20; /* mux mode */ + } break; } + /* Defaults for all trident chipsets follows */ switch (pScrn->bitsPerPixel) { case 1: case 4: outb(0x3CE, MiscExtFunc); pReg->tridentRegs3CE[MiscExtFunc] = (inb(0x3CF) & 0xB7) | 0x04; offset = pScrn->displayWidth >> 3; - pReg->tridentRegsDAC[0x00] = 0x00; break; case 8: outb(0x3CE, MiscExtFunc); pReg->tridentRegs3CE[MiscExtFunc] = (inb(0x3CF) & 0xB7) | 0x02; offset = pScrn->displayWidth >> 3; - pReg->tridentRegsDAC[0x00] = 0x00; break; case 16: outb(0x3CE, MiscExtFunc); @@ -53,19 +75,15 @@ TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->tridentRegsDAC[0x00] = 0x10; else pReg->tridentRegsDAC[0x00] = 0x30; - pReg->tridentRegs3x4[PixelBusReg] |= 0x04; + pReg->tridentRegs3x4[PixelBusReg] = 0x04; if (pTrident->Chipset > CYBER9320) pReg->tridentRegs3x4[PixelBusReg] |= 0x01; break; case 24: outb(0x3CE, MiscExtFunc); pReg->tridentRegs3CE[MiscExtFunc] = (inb(0x3CF) & 0xB7) | 0x02; -#if 0 - pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; /* Clock Division by 2*/ - clock *= 2; /* Double the clock */ -#endif offset = (pScrn->displayWidth * 3) >> 3; - pReg->tridentRegs3x4[PixelBusReg] |= 0x29; + pReg->tridentRegs3x4[PixelBusReg] = 0x29; pReg->tridentRegsDAC[0x00] = 0xD0; break; case 32: @@ -74,7 +92,7 @@ TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; /* Clock Division by 2*/ clock *= 2; /* Double the clock */ offset = pScrn->displayWidth >> 1; - pReg->tridentRegs3x4[PixelBusReg] |= 0x09; + pReg->tridentRegs3x4[PixelBusReg] = 0x09; pReg->tridentRegsDAC[0x00] = 0xD0; break; } @@ -87,6 +105,11 @@ TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->tridentRegsClock[0x00] = (inb(0x3CC) & 0xF3) | 0x08; pReg->tridentRegsClock[0x01] = a; pReg->tridentRegsClock[0x02] = b; + if (pTrident->MCLK > 0) { + TGUISetMCLK(pScrn, pTrident->MCLK, &a, &b); + pReg->tridentRegsClock[0x03] = a; + pReg->tridentRegsClock[0x04] = b; + } } pReg->tridentRegs3C4[NewMode1] = 0xC0; @@ -94,7 +117,7 @@ TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->tridentRegs3x4[LinearAddReg] = ((pTrident->FbAddress >> 24) << 6) | ((pTrident->FbAddress >> 20) & 0x0F)| 0x20; - pReg->tridentRegs3x4[CRTHiOrd] = (((mode->CrtcVBlankStart-1)& 0x400) >> 4) | + pReg->tridentRegs3x4[CRTHiOrd] = (((mode->CrtcVBlankEnd-1) & 0x400) >> 4) | (((mode->CrtcVTotal - 2) & 0x400) >> 3) | ((mode->CrtcVSyncStart & 0x400) >> 5) | (((mode->CrtcVDisplay - 1) & 0x400) >> 6) | @@ -114,21 +137,14 @@ TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode) else pReg->tridentRegs3x4[GraphEngReg] = 0x82; + outb(0x3CE, MiscIntContReg); + pReg->tridentRegs3CE[MiscIntContReg] = inb(0x3CF) | 0x04; + outb(vgaIOBase+ 4, PCIReg); pReg->tridentRegs3x4[PCIReg] = inb(vgaIOBase + 5) & 0xF9; /* Enable PCI Bursting on capable chips */ if (pTrident->Chipset > CYBER9320) pReg->tridentRegs3x4[PCIReg] |= 0x06; - outb(0x3CE, MiscIntContReg); - pReg->tridentRegs3CE[MiscIntContReg] = inb(0x3CF) | 0x04; - - if (pTrident->UsePCIRetry) { - outb(vgaIOBase + 4, PCIRetry); - pReg->tridentRegs3x4[PCIRetry] = inb(vgaIOBase + 5) | 0xDF; - outb(vgaIOBase + 4, Enhancement0); - pReg->tridentRegs3x4[Enhancement0] = inb(vgaIOBase + 5) | 0x50; - } - return(TRUE); } @@ -148,6 +164,14 @@ TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) /* Unprotect registers */ outw(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1); + inb(0x3C8); + inb(0x3C6); + inb(0x3C6); + inb(0x3C6); + inb(0x3C6); + outb(0x3C6, tridentReg->tridentRegsDAC[0x00]); + inb(0x3C8); + outw(vgaIOBase + 4, (tridentReg->tridentRegs3x4[CRTCModuleTest] << 8) | CRTCModuleTest); outw(vgaIOBase + 4, (tridentReg->tridentRegs3x4[LinearAddReg] << 8) | LinearAddReg); @@ -156,10 +180,19 @@ TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) if (Is3Dchip) { outw(0x3C4, (tridentReg->tridentRegsClock[0x01])<<8 | ClockLow); outw(0x3C4, (tridentReg->tridentRegsClock[0x02])<<8 | ClockHigh); + if (pTrident->MCLK > 0) { + outw(0x3C4, (tridentReg->tridentRegsClock[0x03])<<8 | MCLKLow); + outw(0x3C4, (tridentReg->tridentRegsClock[0x04])<<8 | MCLKHigh); + } } else { outb(0x43C8, tridentReg->tridentRegsClock[0x01]); outb(0x43C9, tridentReg->tridentRegsClock[0x02]); + if (pTrident->MCLK > 0) { + outb(0x43C6, tridentReg->tridentRegsClock[0x03]); + outb(0x43C7, tridentReg->tridentRegsClock[0x04]); + } } + outw(0x3C4, (tridentReg->tridentRegs3C4[NewMode2])<<8 | NewMode2); outw(vgaIOBase + 4, (tridentReg->tridentRegs3x4[CRTHiOrd] << 8) | CRTHiOrd); outw(vgaIOBase + 4, (tridentReg->tridentRegs3x4[AddColReg] << 8) | AddColReg); @@ -174,22 +207,13 @@ TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) outw(vgaIOBase + 4, (tridentReg->tridentRegs3x4[Offset] << 8) | Offset); if (pTrident->UsePCIRetry) { - outw(vgaIOBase + 4, (tridentReg->tridentRegs3x4[PCIRetry] << 8) | PCIRetry); - outw(vgaIOBase + 4, (tridentReg->tridentRegs3x4[Enhancement0] << 8) | Enhancement0); + outw(vgaIOBase + 4, (tridentReg->tridentRegs3x4[Enhancement0] << 8) | Enhancement0); } /* restore cursor registers */ for (i=CursorXLow;i<=CursorControl;i++) outw(vgaIOBase + 4, (tridentReg->tridentRegs3x4[i] << 8) | i); - inb(0x3C8); - inb(0x3C6); - inb(0x3C6); - inb(0x3C6); - inb(0x3C6); - outb(0x3C6, tridentReg->tridentRegsDAC[0x00]); - inb(0x3C8); - outw(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1] ^ 0x02) << 8) | NewMode1); } @@ -212,6 +236,9 @@ TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) outb(0x3C4, NewMode1); tridentReg->tridentRegs3C4[NewMode1] = inb(0x3C5); + /* Unprotect registers */ + outw(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1); + outb(vgaIOBase + 4, LinearAddReg); tridentReg->tridentRegs3x4[LinearAddReg] = inb(vgaIOBase + 5); outb(vgaIOBase + 4, CRTCModuleTest); @@ -234,10 +261,8 @@ TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) tridentReg->tridentRegs3x4[PCIReg] = inb(vgaIOBase + 5); if (pTrident->UsePCIRetry) { - outb(vgaIOBase + 4, PCIRetry); - tridentReg->tridentRegs3x4[PCIRetry] = inb(vgaIOBase + 5); - outb(vgaIOBase + 4, Enhancement0); - tridentReg->tridentRegs3x4[Enhancement0] = inb(vgaIOBase + 5); + outb(vgaIOBase + 4, Enhancement0); + tridentReg->tridentRegs3x4[Enhancement0] = inb(vgaIOBase + 5); } /* save cursor registers */ @@ -265,10 +290,25 @@ TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) tridentReg->tridentRegsClock[0x01] = inb(0x3C5); outb(0x3C4, ClockHigh); tridentReg->tridentRegsClock[0x02] = inb(0x3C5); + if (pTrident->MCLK > 0) { + outb(0x3C4, MCLKLow); + tridentReg->tridentRegsClock[0x03] = inb(0x3C5); + outb(0x3C4, MCLKHigh); + tridentReg->tridentRegsClock[0x04] = inb(0x3C5); + } } else { tridentReg->tridentRegsClock[0x01] = inb(0x43C8); tridentReg->tridentRegsClock[0x02] = inb(0x43C9); + if (pTrident->MCLK > 0) { + tridentReg->tridentRegsClock[0x03] = inb(0x43C6); + tridentReg->tridentRegsClock[0x04] = inb(0x43C7); + } } + outb(0x3C4, NewMode2); + tridentReg->tridentRegs3C4[NewMode2] = inb(0x3C5); + + /* Protect registers */ + outw(0x3C4, (tridentReg->tridentRegs3C4[NewMode1] << 8) | NewMode1); } static void @@ -353,8 +393,13 @@ TridentLoadCursorImage( } static Bool -TridentUseHWCursor(ScreenPtr pScr, CursorPtr pCurs) +TridentUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + + if (pTrident->MUX && pScrn->bitsPerPixel == 8) return FALSE; + return TRUE; } @@ -364,10 +409,12 @@ TridentHWCursorInit(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; TRIDENTPtr pTrident = TRIDENTPTR(pScrn); xf86CursorInfoPtr infoPtr; + int memory = pScrn->displayWidth * pScrn->virtualY * pScrn->bitsPerPixel/8; + if (memory > (pScrn->videoRam * 1024 - 4096)) return FALSE; infoPtr = xf86CreateCursorInfoRec(); if(!infoPtr) return FALSE; - + pTrident->CursorInfoRec = infoPtr; infoPtr->MaxWidth = 64; @@ -384,3 +431,31 @@ TridentHWCursorInit(ScreenPtr pScreen) return(xf86InitCursor(pScreen, infoPtr)); } + +unsigned int +Tridentddc1Read(ScrnInfoPtr pScrn) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int vgaIOBase = VGAHWPTR(pScrn)->IOBase; + unsigned char temp; + + /* New mode */ + outb(0x3C4, 0x0B); inb(0x3C5); + + outb(vgaIOBase + 4, NewMode1); + temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp | 0x80); + + /* Define SDA as input */ + outw(vgaIOBase + 4, (0x04 << 8) | I2C); + + outw(vgaIOBase + 4, (temp << 8) | NewMode1); + + /* Wait until vertical retrace is in progress. */ + while (inb(vgaIOBase + 0xA) & 0x08); + while (!(inb(vgaIOBase + 0xA) & 0x08)); + + /* Get the result */ + outb(vgaIOBase + 4, I2C); + return ( inb(vgaIOBase + 5) & 0x01 ); +} diff --git a/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c b/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c index e5689044a..282299980 100644 --- a/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c +++ b/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c @@ -28,7 +28,7 @@ * Massimiliano Ghilardi, max@Linuz.sns.it, some fixes to the * clockchip programming code. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c,v 1.39 1999/01/14 13:04:35 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c,v 1.40 1999/01/17 10:54:05 dawes Exp $ */ #define PSZ 8 #include "cfb.h" @@ -154,15 +154,19 @@ typedef enum { OPTION_PCI_RETRY, OPTION_RGB_BITS, OPTION_NOACCEL, - OPTION_NOMMIO + OPTION_NOMMIO, + OPTION_MUX_THRESHOLD, + OPTION_MCLK } TRIDENTOpts; static OptionInfoRec TRIDENTOptions[] = { { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_NOMMIO, "NoMMIO", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_MUX_THRESHOLD, "MUXThreshold", OPTV_INTEGER, {0}, FALSE }, + { OPTION_MCLK, "MCLK", OPTV_INTEGER, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -357,6 +361,17 @@ static int ClockLimit32bpp[] = { 115000, }; +static const char *xaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + "XAAStippleScanlineFuncLSBFirst", + "XAAOverlayFBfuncs", + "XAACachePlanarMonoStipple", + "XAAScreenIndex", + NULL +}; + static const char *vgahwSymbols[] = { "vgaHWGetHWRec", "vgaHWUnlock", @@ -385,6 +400,12 @@ static const char *racSymbols[] = { NULL }; +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86DoEDID_DDC1", + NULL +}; + static const char *i2cSymbols[] = { "xf86I2CBusInit", "xf86CreateI2CBusRec", @@ -434,7 +455,7 @@ tridentSetup(pointer module, pointer opts, int *errmaj, int *errmin) setupDone = TRUE; xf86AddDriver(&TRIDENT, module, 0); LoaderRefSymLists(vgahwSymbols, fbSymbols, racSymbols, i2cSymbols, - NULL); + xaaSymbols, NULL); return (pointer)TRUE; } @@ -475,6 +496,12 @@ static void TRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) { unsigned char DPMSCont, PMCont, temp; + +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); +#endif + outb(0x3C4, 0x0E); temp = inb(0x3C5); outb(0x3C5, 0xC2); @@ -509,6 +536,10 @@ TRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int outb(0x83C8, 0x04); outb(0x83C6, PMCont); outw(0x3C4, (temp<<8) | 0x0E); + +#if 0 + xf86DelControlledResource(&pScrn->Access, FALSE); +#endif } #endif @@ -526,8 +557,15 @@ Trident1bppColorMap(ScrnInfoPtr pScrn) { black. I'm sure there's a better way to do that, just lazy to search the docs. */ +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); +#endif outb(0x3C8, 0x00); outb(0x3C9, 0x00); outb(0x3C9, 0x00); outb(0x3C9, 0x00); outb(0x3C8, 0x3F); outb(0x3C9, 0x3F); outb(0x3C9, 0x3F); outb(0x3C9, 0x3F); +#if 0 + xf86DelControlledResource(&pScrn->Access,FALSE); +#endif } /* Mandatory */ @@ -655,7 +693,9 @@ TRIDENTProbe(DriverPtr drv, int flags) static int * GetAccelPitchValues(ScrnInfoPtr pScrn) { +#if 0 TRIDENTPtr pTrident = TRIDENTPTR(pScrn); +#endif int *linePitches = NULL; int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */ #if 0 @@ -687,6 +727,7 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) MessageType from; unsigned char videoram; char *ramtype = NULL, *chipset = NULL; + Bool Support24bpp; int vgaIOBase; float mclk; int i,j; @@ -696,6 +737,7 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) const char *Sym; xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); /* * Note: This function is only called once at server startup, and @@ -710,7 +752,6 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) * AllocateScreenPrivateIndex() from the ScreenInit() function. */ - xf86EnableAccess(&pScrn->Access); /* The vgahw module should be loaded here when needed */ if (!xf86LoadSubModule(pScrn, "vgahw")) @@ -812,6 +853,7 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } pTrident = TRIDENTPTR(pScrn); + pTrident->pScrn = pScrn; /* Collect all of the relevant option flags (fill in pScrn->options) */ xf86CollectOptions(pScrn, NULL); @@ -856,6 +898,12 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) pTrident->UsePCIRetry = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); } + pTrident->MUXThreshold = 100000; /* 100MHz */ + if (xf86GetOptValInteger(TRIDENTOptions, OPTION_MUX_THRESHOLD, + &pTrident->MUXThreshold)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MUX Threshold set to %d\n", + pTrident->MUXThreshold); + } /* Find the PCI slot for this screen */ if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL)) != 1) { @@ -915,14 +963,18 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Revision is %d\n",revision); pTrident->EngineOperation = 0x00; + pTrident->UseGERetry = FALSE; pTrident->IsCyber = FALSE; pTrident->HasSGRAM = FALSE; pTrident->NewClockCode = FALSE; + pTrident->MUX = FALSE; + Support24bpp = FALSE; outb(vgaIOBase + 4, InterfaceSel); switch (pTrident->Chipset) { case PCI_CHIP_9440: + pTrident->ddc1Read = Tridentddc1Read; pTrident->HWCursor = FALSE; chipset = "TGUI9440"; pTrident->Chipset = TGUI9440AGi; @@ -932,6 +984,7 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) pTrident->UsePCIRetry = FALSE; /* Not Supported */ break; case PCI_CHIP_9320: + pTrident->ddc1Read = Tridentddc1Read; chipset = "Cyber9320"; pTrident->Chipset = CYBER9320; ramtype = "Standard DRAM"; @@ -940,6 +993,7 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) pTrident->UsePCIRetry = FALSE; /* Not Supported */ break; case PCI_CHIP_9660: + pTrident->ddc1Read = Tridentddc1Read; if ((inb(vgaIOBase + 5) & 0x0C) == 0x04) ramtype = "EDO Ram"; if ((inb(vgaIOBase + 5) & 0x0C) == 0x0C) @@ -961,10 +1015,15 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) break; case 0x10: chipset = "ProVidia 9682"; + Support24bpp = TRUE; pTrident->Chipset = PROVIDIA9682; + if (pTrident->UsePCIRetry) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n"); + pTrident->UsePCIRetry = FALSE; /* Not Supported */ break; case 0x21: chipset = "ProVidia 9685"; + Support24bpp = TRUE; pTrident->NewClockCode = TRUE; pTrident->Chipset = PROVIDIA9685; break; @@ -979,6 +1038,7 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) pTrident->HasSGRAM = TRUE; ramtype = "SGRAM"; } + pTrident->NoMMIO = FALSE; /* Can't disable MMIO */ pTrident->NewClockCode = TRUE; pTrident->Chipset = CYBER9397; pTrident->IsCyber = TRUE; @@ -993,6 +1053,7 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) pTrident->HasSGRAM = TRUE; ramtype = "SGRAM"; } + pTrident->NoMMIO = FALSE; /* Can't disable MMIO */ pTrident->NewClockCode = TRUE; pTrident->Chipset = CYBER939A; pTrident->IsCyber = TRUE; @@ -1025,14 +1086,15 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) break; case 0x4A: chipset = "Cyber 9388"; - if ((inb(vgaIOBase + 5) & 0x0C) == 0x04) - ramtype = "EDO Ram"; - if ((inb(vgaIOBase + 5) & 0x0C) == 0x08) - ramtype = "SDRAM"; - if ((inb(vgaIOBase + 5) & 0x0C) == 0x0C) { - pTrident->HasSGRAM = TRUE; - ramtype = "SGRAM"; - } + if ((inb(vgaIOBase + 5) & 0x0C) == 0x04) + ramtype = "EDO Ram"; + if ((inb(vgaIOBase + 5) & 0x0C) == 0x08) + ramtype = "SDRAM"; + if ((inb(vgaIOBase + 5) & 0x0C) == 0x0C) { + pTrident->HasSGRAM = TRUE; + ramtype = "SGRAM"; + } + pTrident->NoMMIO = FALSE; /* Can't disable MMIO */ pTrident->NewClockCode = TRUE; pTrident->Chipset = CYBER9388; pTrident->IsCyber = TRUE; @@ -1044,6 +1106,7 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) } break; case PCI_CHIP_9750: + pTrident->ddc1Read = Tridentddc1Read; if ((inb(vgaIOBase + 5) & 0x0C) == 0x04) ramtype = "EDO Ram"; if ((inb(vgaIOBase + 5) & 0x0C) == 0x08) @@ -1052,11 +1115,14 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) pTrident->HasSGRAM = TRUE; ramtype = "SGRAM"; } + Support24bpp = TRUE; chipset = "3DImage975"; + pTrident->NoMMIO = FALSE; /* Can't disable MMIO for this chipset */ pTrident->NewClockCode = TRUE; pTrident->Chipset = IMAGE975; break; case PCI_CHIP_9850: + pTrident->ddc1Read = Tridentddc1Read; if ((inb(vgaIOBase + 5) & 0x0C) == 0x04) ramtype = "EDO Ram"; if ((inb(vgaIOBase + 5) & 0x0C) == 0x08) @@ -1065,7 +1131,9 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) pTrident->HasSGRAM = TRUE; ramtype = "SGRAM"; } + Support24bpp = TRUE; chipset = "3DImage985"; + pTrident->NoMMIO = FALSE; /* Can't disable MMIO for this chipset */ pTrident->NewClockCode = TRUE; pTrident->Chipset = IMAGE985; break; @@ -1078,6 +1146,10 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", chipset); if (ramtype) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RAM type is %s\n", ramtype); + if (!Support24bpp) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No support for 24bpp on this chipset, use 32bpp.\n"); + return FALSE; + } pTrident->PciTag = pciTag(pTrident->PciInfo->bus, pTrident->PciInfo->device, pTrident->PciInfo->func); @@ -1149,6 +1221,12 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) mclk = CalculateMCLK(pScrn); xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Clock is %3.2f MHz\n", mclk); + pTrident->MCLK = 0; + if (xf86GetOptValInteger(TRIDENTOptions, OPTION_MCLK, + &pTrident->MCLK)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Setting new Memory Clock to %3.2f MHz\n", + (float)(pTrident->MCLK / 1000)); + } /* Set the min pixel clock */ pTrident->MinClock = 16250; /* XXX Guess, need to check this */ @@ -1219,16 +1297,21 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) * care of this, we don't worry about setting them here. */ + if ((pScrn->depth < 8) || + (pScrn->bitsPerPixel == 24)) + pTrident->NoAccel = TRUE; + /* Select valid modes from those available */ - if (pTrident->NoAccel) { + if (pTrident->NoAccel || pTrident->Chipset == IMAGE975 || + pTrident->Chipset == IMAGE985) { /* - * XXX Assuming min pitch 256, max 2048 - * XXX Assuming min height 128, max 2048 + * XXX Assuming min pitch 256, max 4096 + * XXX Assuming min height 128, max 4096 */ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, - NULL, 256, 2048, - pScrn->bitsPerPixel, 128, 2048, + NULL, 256, 4096, + pScrn->bitsPerPixel, 128, 4096, pScrn->display->virtualX, pScrn->display->virtualY, pTrident->FbMapSize, @@ -1276,13 +1359,11 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) switch (pScrn->bitsPerPixel) { case 1: pTrident->EngineOperation |= 0x00; - pTrident->NoAccel = TRUE; mod = "xf1bpp"; Sym = "xf1bppScreenInit"; break; case 4: pTrident->EngineOperation |= 0x00; - pTrident->NoAccel = TRUE; mod = "xf4bpp"; Sym = "xf4bppScreenInit"; break; @@ -1337,6 +1418,8 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } + xf86LoaderReqSymLists(xaaSymbols, NULL); + switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) { case 512: pTrident->EngineOperation |= 0x00; @@ -1353,6 +1436,18 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) } } + /* Load DDC if needed */ + /* This gives us DDC1 - we should be able to get DDC2B using i2c */ + if (!xf86LoadSubModule(pScrn, "ddc")) { + TRIDENTFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(ddcSymbols, NULL); + + /* Initialize DDC1 if possible */ + if (pTrident->ddc1Read) + xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex,vgaHWddc1SetSpeed,pTrident->ddc1Read ) ); + return TRUE; } @@ -1492,9 +1587,18 @@ TRIDENTSave(ScrnInfoPtr pScrn) vgaReg = &VGAHWPTR(pScrn)->SavedReg; tridentReg = &pTrident->SavedReg; +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); +#endif + vgaHWSave(pScrn, vgaReg, VGA_SR_ALL); TridentSave(pScrn, tridentReg); + +#if 0 + xf86DelControlledResource(&pScrn->Access,FALSE); +#endif } @@ -1507,13 +1611,39 @@ TRIDENTSave(ScrnInfoPtr pScrn) static Bool TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { - int ret = -1; - vgaHWPtr hwp; + vgaHWPtr hwp = VGAHWPTR(pScrn); vgaRegPtr vgaReg; - TRIDENTPtr pTrident; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); TRIDENTRegPtr tridentReg; - hwp = VGAHWPTR(pScrn); + if (mode->Clock > pTrident->MUXThreshold) pTrident->MUX = TRUE; + else pTrident->MUX = FALSE; + + switch (pTrident->Chipset) { + case TGUI9660: + case TGUI9680: + case PROVIDIA9682: + case PROVIDIA9685: + /* Get ready for MUX mode */ + if (pTrident->MUX && + pScrn->bitsPerPixel == 8 && + !mode->CrtcHAdjusted) { + mode->CrtcHDisplay >>= 1; + mode->CrtcHSyncStart >>= 1; + mode->CrtcHSyncEnd >>= 1; + mode->CrtcHBlankStart >>= 1; + mode->CrtcHBlankEnd >>= 1; + mode->CrtcHTotal >>= 1; + mode->CrtcHAdjusted = TRUE; + } + break; + } + +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); +#endif + vgaHWUnlock(hwp); /* Initialise the ModeReg values */ @@ -1521,11 +1651,7 @@ TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) return FALSE; pScrn->vtSema = TRUE; - pTrident = TRIDENTPTR(pScrn); - - ret = TridentInit(pScrn, mode); - - if (!ret) + if (!TridentInit(pScrn, mode)) return FALSE; /* Program the registers */ @@ -1539,6 +1665,10 @@ TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) vgaHWProtect(pScrn, FALSE); +#if 0 + xf86DelControlledResource(&pScrn->Access,FALSE); +#endif + return TRUE; } @@ -1558,6 +1688,11 @@ TRIDENTRestore(ScrnInfoPtr pScrn) vgaReg = &hwp->SavedReg; tridentReg = &pTrident->SavedReg; +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); +#endif + vgaHWProtect(pScrn, TRUE); TridentRestore(pScrn, tridentReg); @@ -1565,6 +1700,10 @@ TRIDENTRestore(ScrnInfoPtr pScrn) vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); vgaHWProtect(pScrn, FALSE); + +#if 0 + xf86DelControlledResource(&pScrn->Access,FALSE); +#endif } @@ -1606,7 +1745,8 @@ TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) TRIDENTSave(pScrn); /* Initialise the first mode */ - TRIDENTModeInit(pScrn, pScrn->currentMode); + if (!TRIDENTModeInit(pScrn, pScrn->currentMode)) + return FALSE; /* Darken the screen for aesthetic reasons and set the viewport */ TRIDENTSaveScreen(pScreen, FALSE); @@ -1627,7 +1767,7 @@ TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* * Reset visual list. */ - if (pScrn->bitsPerPixel >= 8) miClearVisualTypes(); + miClearVisualTypes(); /* Setup the visuals we support. */ @@ -1781,8 +1921,12 @@ TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); } +#if 0 TRIDENTI2CInit(pScreen); + xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pTrident->DDC)); +#endif + /* Turn on the screen now */ TRIDENTSaveScreen(pScreen, TRUE); @@ -1828,12 +1972,17 @@ TRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags) base >>= 1; break; case 24: - base = ((base + 1) & ~0x03) * 3; + base = (((base + 1) & ~0x03) * 3) >> 2; break; case 32: break; } +#if 0 + xf86AddControlledResource(pScrn,IO); + xf86EnableAccess(&pScrn->Access); +#endif + /* CRT bits 0-15 */ outw(vgaIOBase + 4, (base & 0x00FF00) | 0x0C); outw(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D); @@ -1843,6 +1992,10 @@ TRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags) /* CRT bit 17-19 */ outb(vgaIOBase + 4, CRTHiOrd); temp = inb(vgaIOBase + 5) & 0xF8; outb(vgaIOBase + 5, temp | (base & 0xE0000) >> 17); + +#if 0 + xf86DelControlledResource(&pScrn->Access,FALSE); +#endif } diff --git a/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c b/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c index 6cebf60b9..08baeaec0 100644 --- a/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c +++ b/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c @@ -1,4 +1,4 @@ -/* $XFree86$ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c,v 1.1 1998/11/15 04:30:34 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -13,38 +13,11 @@ #include "trident.h" #include "trident_regs.h" -/* - * Switch between internal I2C bus and external (DDC) bus. - * There is one I2C port controlled by SR08 and the programmable - * outputs control a multiplexer. - */ -static Bool -TRIDENTI2CSwitchToBus(I2CBusPtr b) { +static void +TRIDENTI2CPutBits(I2CBusPtr b, int clock, int data) { + unsigned int reg = 0x0C; TRIDENTPtr pTrident = ((TRIDENTPtr)b->DriverPrivate.ptr); - int vgaIOBase; - vgaIOBase = 0x3D0; /* VGAHWPTR(pScrn)->IOBase; */ - if (b == pTrident->I2CPtr1) { - if ((pTrident->ModeReg.tridentRegs3x4[I2C] & 0x04) == 0) - return TRUE; - pTrident->ModeReg.tridentRegs3x4[I2C] &= ~0x04; - } - else if(b == pTrident->I2CPtr2) { - if ((pTrident->ModeReg.tridentRegs3x4[I2C] & 0x04) != 0) - return TRUE; - pTrident->ModeReg.tridentRegs3x4[I2C] |= 0x04; - } - else return FALSE; - - ErrorF("TRIDENTI2CSwitchToBus: \"%s\"\n", b->BusName); - outw(vgaIOBase + 4, (pTrident->ModeReg.tridentRegs3x4[I2C] << 8) | I2C); - return TRUE; -} - -static Bool -TRIDENTI2CPutBits(I2CBusPtr b, int clock, int data) { - unsigned int reg = 4; - int vgaIOBase; - vgaIOBase = 0x3D0; /* VGAHWPTR(pScrn)->IOBase; */ + int vgaIOBase = VGAHWPTR(pTrident->pScrn)->IOBase; #if 0 if(!TRIDENTI2CSwitchToBus(b)) @@ -53,16 +26,18 @@ TRIDENTI2CPutBits(I2CBusPtr b, int clock, int data) { if(clock) reg |= 2; if(data) reg |= 1; - outw(vgaIOBase + 4, (reg << 8) | 0x08); - /* ErrorF("TRIDENTI2CPutBits: %d %d\n", clock, data); */ - return TRUE; + outb(vgaIOBase + 4, I2C); + outb(vgaIOBase + 5, reg); +#if 0 + ErrorF("TRIDENTI2CPutBits: %d %d\n", clock, data); +#endif } -static Bool +static void TRIDENTI2CGetBits(I2CBusPtr b, int *clock, int *data) { unsigned int reg; - int vgaIOBase; - vgaIOBase = 0x3D0; /* VGAHWPTR(pScrn)->IOBase; */ + TRIDENTPtr pTrident = ((TRIDENTPtr)b->DriverPrivate.ptr); + int vgaIOBase = VGAHWPTR(pTrident->pScrn)->IOBase; #if 0 if(!TRIDENTI2CSwitchToBus(b)) @@ -73,8 +48,9 @@ TRIDENTI2CGetBits(I2CBusPtr b, int *clock, int *data) { reg = inb(vgaIOBase + 5); *clock = (reg & 0x02) != 0; *data = (reg & 0x01) != 0; - /* ErrorF("TRIDENTI2CGetBits: %d %d\n", *clock, *data); */ - return TRUE; +#if 0 + ErrorF("TRIDENTI2CGetBits: %d %d\n", *clock, *data); +#endif } Bool @@ -84,27 +60,12 @@ TRIDENTI2CInit(ScreenPtr pScreen) TRIDENTPtr pTrident = TRIDENTPTR(pScrn); I2CBusPtr I2CPtr; - ErrorF("TRIDENTI2CInit\n"); - - I2CPtr = xf86CreateI2CBusRec(); - if(!I2CPtr) return FALSE; - - pTrident->I2CPtr1 = I2CPtr; - - I2CPtr->BusName = "I2C bus 1"; - I2CPtr->I2CPutBits = TRIDENTI2CPutBits; - I2CPtr->I2CGetBits = TRIDENTI2CGetBits; - I2CPtr->DriverPrivate.ptr = pTrident; - - if(!xf86I2CBusInit(I2CPtr)) - return FALSE; - I2CPtr = xf86CreateI2CBusRec(); - if(!I2CPtr) return FALSE; - pTrident->I2CPtr2 = I2CPtr; + pTrident->DDC = I2CPtr; - I2CPtr->BusName = "I2C bus 2"; + I2CPtr->BusName = "DDC"; + I2CPtr->scrnIndex = pScrn->scrnIndex; I2CPtr->I2CPutBits = TRIDENTI2CPutBits; I2CPtr->I2CGetBits = TRIDENTI2CGetBits; I2CPtr->DriverPrivate.ptr = pTrident; diff --git a/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h b/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h index e5ab6257c..467fe59e2 100644 --- a/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h +++ b/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h @@ -21,7 +21,7 @@ * * Author: Alan Hourihane, alanh@fairlite.demon.co.uk */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h,v 1.2 1998/09/13 05:23:42 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h,v 1.3 1998/11/15 04:30:34 dawes Exp $ */ /* General Registers */ #define SPR 0x1F /* Software Programming Register (videoram) */ @@ -33,6 +33,8 @@ #define OldMode2 0x0D #define OldMode1 0x0E #define NewMode1 0x0E +#define MCLKLow 0x16 +#define MCLKHigh 0x17 #define ClockLow 0x18 #define ClockHigh 0x19 @@ -69,7 +71,9 @@ #define CursorBG4 0x4F #define CursorControl 0x50 #define PCIRetry 0x55 +#define PCIMaster 0x60 #define Enhancement0 0x62 +#define NewEDO 0x64 #define TVinterface 0xC0 #define TVMode 0xC1 #define ClockControl 0xCF @@ -119,6 +123,7 @@ #define GE_ELLIP_FILL 0x09 /* Ellipse Fill (96xx only) (RES)*/ #define GER_FMIX 0x27 #define GER_DRAWFLAG 0x28 /* long */ +#define FASTMODE 1<<28 #define STENCIL 0x8000 #define SOLIDFILL 0x4000 #define TRANS_ENABLE 0x1000 @@ -197,11 +202,13 @@ x |= x << 8; \ } -#define CHECKCLIPPING \ - if (pTrident->Clipping) { \ - pTrident->Clipping = FALSE; \ - TGUI_SRCCLIP_XY(0,0); \ - TGUI_DSTCLIP_XY(4095,2047); \ +#define CHECKCLIPPING \ + if (pTrident->Clipping) { \ + pTrident->Clipping = FALSE; \ + if (pTrident->Chipset < PROVIDIA9682) { \ + TGUI_SRCCLIP_XY(0,0); \ + TGUI_DSTCLIP_XY(4095,2047); \ + } \ } @@ -289,8 +296,8 @@ *(CARD32 *)(pTrident->IOBase + GER_CKEY) = c; #define IMAGE_OUT(addr, c) \ *(CARD32 *)(pTrident->IOBase + addr) = c; -#define TGUI_OUTB(addr, c) \ - *(unsigned char *)(pTrident->IOBase + addr) = c; +#define TGUI_OUTL(addr, c) \ + *(CARD32 *)(pTrident->IOBase + addr) = c; #define TGUI_COMMAND(c) \ { \ *(unsigned char *)(pTrident->IOBase + GER_COMMAND) = c; \ @@ -391,8 +398,8 @@ outw(GER_BASE+GER_PATLOC, addr); #define TGUI_CKEY(c) \ outl(GER_BASE+GER_CKEY, c); -#define TGUI_OUTB(addr, c) \ - outb(GER_BASE+addr, c); +#define TGUI_OUTL(addr, c) \ + outl(GER_BASE+addr, c); #define TGUI_OUTW(addr, c) \ outw(GER_BASE+addr, c); #define TGUI_COMMAND(c) \ diff --git a/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c b/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c index e5883e73f..e13c6c529 100644 --- a/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c +++ b/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c,v 1.3 1998/09/13 13:12:24 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c,v 1.4 1998/11/15 04:30:34 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -186,3 +186,74 @@ CalculateMCLK(ScrnInfoPtr pScrn) } return (freq); } + +void +TGUISetMCLK(ScrnInfoPtr pScrn, int clock, unsigned char *a, unsigned char *b) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int powerup[4] = { 1,2,4,8 }; + int clock_diff = 750; + int freq, ffreq; + int m,n,k; + int p, q, r, s; + int startn, endn; + int endm, endk; + unsigned char temp; + + p = q = r = s = 0; + + IsClearTV(pScrn); + + if (pTrident->NewClockCode) + { + startn = 64; + endn = 255; + endm = 63; + endk = 3; + } + else + { + startn = 0; + endn = 121; + endm = 31; + endk = 1; + } + + freq = clock; + + if (!pTrident->HasSGRAM) { + for (k=0;k<=endk;k++) + for (n=startn;n<=endn;n++) + for (m=1;m<=endm;m++) { + ffreq = ((((n+8)*pTrident->frequency)/((m+2)*powerup[k]))*1000); + if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff)) + { + clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq; + p = n; q = m; r = k; s = ffreq; + } + } + + if (s == 0) + { + FatalError("Unable to set memory clock.\n" + "Frequency %d is not a valid clock.\n" + "Please modify XF86Config for a new clock.\n", + freq); + } + + if (pTrident->NewClockCode) + { + /* N is all 8bits */ + *a = p; + /* M is first 6bits, with K last 2bits */ + *b = (q & 0x3F) | (r << 6); + } + else + { + /* N is first 7bits, first M bit is 8th bit */ + *a = ((1 & q) << 7) | p; + /* first 4bits are rest of M, 1bit for K value */ + *b = (((q & 0xFE) >> 1) | (r << 4)); + } + } +} diff --git a/programs/Xserver/hw/xfree86/loader/loaderProcs.h b/programs/Xserver/hw/xfree86/loader/loaderProcs.h index dfcd0b004..a7471de70 100644 --- a/programs/Xserver/hw/xfree86/loader/loaderProcs.h +++ b/programs/Xserver/hw/xfree86/loader/loaderProcs.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loaderProcs.h,v 1.11 1999/01/15 02:12:39 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loaderProcs.h,v 1.12 1999/01/17 10:54:11 dawes Exp $ */ /* * @@ -67,6 +67,7 @@ void UnloadDriver (ModuleDescPtr); void FreeModuleDesc (ModuleDescPtr mod); ModuleDescPtr NewModuleDesc (const char *); ModuleDescPtr AddSibling (ModuleDescPtr head, ModuleDescPtr new); +void LoaderSetPath(const char *path); void LoaderVReqSymLists(const char **, va_list args); diff --git a/programs/Xserver/hw/xfree86/loader/loadmod.c b/programs/Xserver/hw/xfree86/loader/loadmod.c index a3e9f989a..93b1f70fa 100644 --- a/programs/Xserver/hw/xfree86/loader/loadmod.c +++ b/programs/Xserver/hw/xfree86/loader/loadmod.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadmod.c,v 1.35 1999/01/15 02:51:57 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadmod.c,v 1.36 1999/01/17 10:54:11 dawes Exp $ */ /* * @@ -109,6 +109,8 @@ FreeStringList(char **paths) xfree(paths); } +static char **defaultPathList = NULL; + /* * Convert a comma-separated path into a NULL-terminated array of path * elements, rejecting any that are not full absolute paths, and appending @@ -124,6 +126,9 @@ InitPathList(const char *path) int addslash; int n = 0; + if (!path) + return defaultPathList; + fullpath = xstrdup(path); if (!fullpath) return NULL; @@ -170,7 +175,21 @@ InitPathList(const char *path) return list; } -#ifndef OLD_FINDMODULE +static void +FreePathList(char **pathlist) +{ + if (pathlist && pathlist != defaultPathList) + FreeStringList(pathlist); +} + +void +LoaderSetPath(const char *path) +{ + if (!path) + return; + + defaultPathList = InitPathList(path); +} /* Standard set of module subdirectories to search, in order of preference */ static const char *stdSubdirs[] = @@ -265,10 +284,24 @@ InitSubdirs(const char **subdirlist) const char **s; if (subdirlist) { - /* Count number of entries */ - for (i = 0, s = subdirlist; *s; i++, s++) - if (*s == DEFAULT_LIST) + /* Count number of entries and check for invalid paths */ + for (i = 0, s = subdirlist; *s; i++, s++) { + if (*s == DEFAULT_LIST) { i += sizeof(stdSubdirs) / sizeof(stdSubdirs[0]) - 1 - 1; + } else { + /* + * Path validity check. Don't allow absolute paths, or + * paths containing "..". To catch absolute paths on + * platforms that use driver letters, don't allow the ':' + * character to appear at all. + */ + if (**s == '/' || **s == '\\' || strchr(*s, ':') || + strstr(*s, "..")) { + xf86Msg(X_ERROR, "InitSubdirs: Bad subdir: \"%s\"\n", *s); + return NULL; + } + } + } subdirs = xalloc((i + 1) * sizeof(char *)); if (!subdirs) return NULL; @@ -392,17 +425,14 @@ LoaderListDirs(const char *path, const char **subdirlist, char **save; int n = 0; - if (!path) - return NULL; - if (!(pathlist = InitPathList(path))) return NULL; if (!(subdirs = InitSubdirs(subdirlist))) { - FreeStringList(pathlist); + FreePathList(pathlist); return NULL; } if (!(patterns = InitPatterns(patternlist))) { - FreeStringList(pathlist); + FreePathList(pathlist); FreeSubdirs(subdirs); return NULL; } @@ -439,7 +469,7 @@ LoaderListDirs(const char *path, const char **subdirlist, save[n] = NULL; FreeStringList(save); } - FreeStringList(pathlist); + FreePathList(pathlist); FreeSubdirs(subdirs); FreePatterns(patterns); return NULL; @@ -447,7 +477,7 @@ LoaderListDirs(const char *path, const char **subdirlist, listing[n] = xalloc(len + 1); if (!listing[n]) { FreeStringList(listing); - FreeStringList(pathlist); + FreePathList(pathlist); FreeSubdirs(subdirs); FreePatterns(patterns); return NULL; @@ -475,65 +505,6 @@ LoaderFreeDirList(char **list) FreeStringList(list); } -#else - -static char *subdirs[] = -{ - "", - "drivers/", - "extensions/", - "fonts/", - "internal/", -}; -static char *prefixes[] = -{ - "", - "lib", -}; -static char *suffixes[] = -{ - "", - ".so", - "_drv.so", - ".o", - "_drv.o", - ".a", -}; - -static char * -FindModule (const char *module, const char *dir, const char **subdirlist, - const char **patternlist) -{ - char *buf; - int d, p, s; - struct stat stat_buf; - - buf = xcalloc (1, strlen (module) + strlen (dir) + 40); - for (d = 0; d < sizeof (subdirs) / sizeof (char *); d++) - for (p = 0; p < sizeof (prefixes) / sizeof (char *); p++) - for (s = 0; s < sizeof (suffixes) / sizeof (char *); s++) - { - /* - * put together a possible filename - */ - strcpy (buf, dir); - strcat (buf, subdirs[d]); - strcat (buf, prefixes[p]); - strcat (buf, module); - strcat (buf, suffixes[s]); -#ifdef __EMX__ - strcpy (buf, (char *) __XOS2RedirRoot (buf)); -#endif - if ((stat (buf, &stat_buf) == 0) && - S_ISREG(stat_buf.st_mode)) - { - return (buf); - } - } - xfree (buf); - return (NULL); -} -#endif static Bool CheckVersion (const char *module, XF86ModuleVersionInfo *data, @@ -844,9 +815,6 @@ LoadModule (const char *module, const char *path, const char **subdirlist, xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module); - if (!path) - goto LoadModule_fail; - patterns = InitPatterns(patternlist); name = LoaderGetCanonicalName(module, patterns); noncanonical = (name && strcmp(module, name) != 0); @@ -863,15 +831,31 @@ LoadModule (const char *module, const char *path, const char **subdirlist, xf86ErrorFVerb(3, "\n"); m = (char *)module; } - if (!name) + if (!name) { + if (errmaj) + *errmaj = LDR_BADUSAGE; + if (errmin) + *errmin = 0; goto LoadModule_fail; + } ret = NewModuleDesc (name); - if (!ret) + if (!ret) { + if (errmaj) + *errmaj = LDR_NOMEM; + if (errmin) + *errmin = 0; goto LoadModule_fail; + } pathlist = InitPathList(path); - if (!pathlist) + if (!pathlist) { + /* This could be a malloc failure too */ + if (errmaj) + *errmaj = LDR_BADUSAGE; + if (errmin) + *errmin = 1; goto LoadModule_fail; + } /* * if the module name is not a full pathname, we need to @@ -888,7 +872,7 @@ LoadModule (const char *module, const char *path, const char **subdirlist, path_elem = pathlist; while (!found && *path_elem != NULL) { - found = FindModule (m, *path_elem, NULL, patterns); + found = FindModule (m, *path_elem, subdirlist, patterns); path_elem++; /* * When the module name isn't the canonical name, search for the @@ -908,6 +892,10 @@ LoadModule (const char *module, const char *path, const char **subdirlist, { xf86Msg (X_WARNING, "Warning, couldn't open module %s\n", module); + if (errmaj) + *errmaj = LDR_NOENT; + if (errmin) + *errmin = 0; goto LoadModule_fail; } ret->handle = LoaderOpen (found, name, 0, errmaj, errmin, &wasLoaded); @@ -921,8 +909,13 @@ LoadModule (const char *module, const char *path, const char **subdirlist, * and if yes, call it. */ p = xalloc (strlen (name) + strlen ("ModuleInit") + 1); - if (!p) + if (!p) { + if (errmaj) + *errmaj = LDR_NOMEM; + if (errmin) + *errmin = 0; goto LoadModule_fail; + } strcpy (p, name); strcat (p, "ModuleInit"); initfunc = (ModuleInitProc) LoaderSymbol (p); @@ -994,7 +987,7 @@ LoadModule (const char *module, const char *path, const char **subdirlist, ret = NULL; LoadModule_exit: - FreeStringList(pathlist); + FreePathList(pathlist); FreePatterns(patterns); TestFree (found); TestFree (name); @@ -1189,6 +1182,9 @@ LoaderErrorMsg(const char *name, const char *modname, int errmaj, int errmin) case LDR_MISMATCH: msg = "module requirement mismatch"; break; + case LDR_BADUSAGE: + msg = "invalid argument(s) to LoadModule()"; + break; default: msg = "uknown error"; } diff --git a/programs/Xserver/hw/xfree86/loader/xf86sym.c b/programs/Xserver/hw/xfree86/loader/xf86sym.c index 0490eaaef..844176767 100644 --- a/programs/Xserver/hw/xfree86/loader/xf86sym.c +++ b/programs/Xserver/hw/xfree86/loader/xf86sym.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/xf86sym.c,v 1.56 1999/01/17 10:54:12 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/xf86sym.c,v 1.57 1999/01/17 11:25:22 dawes Exp $ */ /* * @@ -454,7 +454,6 @@ LOOKUP xfree86LookupTab[] = { SYMFUNC(LoadSubModule) SYMFUNC(DuplicateModule) SYMFUNC(LoaderErrorMsg) - SYMFUNC(xf86ModulePath) SYMFUNC(LoaderCheckUnresolved) SYMFUNC(LoadExtension) SYMFUNC(LoadFont) diff --git a/programs/Xserver/hw/xfree86/olddrivers/sis/Imakefile b/programs/Xserver/hw/xfree86/olddrivers/sis/Imakefile new file mode 100644 index 000000000..688db93b4 --- /dev/null +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/Imakefile @@ -0,0 +1,58 @@ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile,v 1.2 1997/04/08 10:13:19 hohndel Exp $ + + + +#define IHaveModules +#include <Server.tmpl> + +SRCS = sis_driver.c sis_bank.s sis_curs.c sis_BitBlt.c sis_blitter.c\ + sis_solid.c sis_blt16.c sis_pntwin.c sis_FillRct.c sis_FillSt.c\ + sis_colexp.c sis_teblt8.c sis_textblt.s sis_accel.c + +OBJS = sis_driver.o sis_bank.o sis_curs.o sis_BitBlt.o sis_blitter.o\ + sis_solid.o sis_blt16.o sis_pntwin.o sis_FillRct.o sis_FillSt.o\ + sis_colexp.o sis_teblt8.o sis_textblt.o sis_accel.o + +DEFINES = -DPSZ=8 + +#if XF86LinkKit +INCLUDES = -I. -I../../../include -I../../../include/X11 -I../.. +#else +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86HWSRC) -I$(XF86OSSRC) \ + -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/cfb \ + -I$(XF86SRC)/vga256/vga -I../../xaa -I$(SERVERSRC)/include \ + -I$(XINCLUDESRC) -I$(FONTINCSRC) +#endif + +#if MakeHasPosixVariableSubstitutions +SubdirLibraryRule($(OBJS)) +#endif +NormalLibraryObjectRule() +NormalAsmObjectRule() + +NormalRelocatableTarget(sis_drv, $(OBJS)) + +InstallLinkKitNonExecFile(sis_driver.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_bank.s,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_curs.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(Imakefile,$(LINKKITDIR)/drivers/svga/sis) + +InstallLinkKitNonExecFile(sis_accel.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_blt16.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_blitter.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_BitBlt.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_solid.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_Blitter.h,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_driver.h,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_pntwin.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_FillRct.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_FillSt.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_colexp.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_teblt8.c,$(LINKKITDIR)/drivers/svga/sis) +InstallLinkKitNonExecFile(sis_textblt.s,$(LINKKITDIR)/drivers/svga/sis) + +#if DoLoadableServer +InstallDynamicModule(sis_drv.o,$(MODULEDIR)) +#endif + +DependTarget() diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_BitBlt.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_BitBlt.c index bc8828fbb..f60f47f5a 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_BitBlt.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_BitBlt.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/sis/sis_BitBlt.c,v 1.1 1997/01/12 10:43:02 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_BitBlt.c,v 1.1 1997/03/06 23:16:46 hohndel Exp $ */ /* * diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_Blitter.h b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_Blitter.h index 22910f693..3f000df91 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_Blitter.h +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_Blitter.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/sis/sis_Blitter.h,v 1.2 1997/01/18 06:56:51 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_Blitter.h,v 1.1 1997/03/06 23:16:47 hohndel Exp $ */ /* Definitions for the SIS engine communication. */ diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_FillRct.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_FillRct.c index 7f2f44f89..aca090304 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_FillRct.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_FillRct.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_FillRct.c,v 1.1 1997/03/06 23:16:47 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_FillRct.c,v 1.2 1998/03/20 21:06:56 hohndel Exp $ */ /* * diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_FillSt.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_FillSt.c index 082ba9668..36f31e5be 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_FillSt.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_FillSt.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_FillSt.c,v 1.2 1998/01/24 16:58:21 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_FillSt.c,v 1.3 1998/03/20 21:06:57 hohndel Exp $ */ /* * diff --git a/programs/Xserver/hw/xfree86/olddrivers/sis/sis_accel.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_accel.c new file mode 100644 index 000000000..05b839e38 --- /dev/null +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_accel.c @@ -0,0 +1,618 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c,v 1.2 1997/04/17 08:17:24 hohndel Exp $ */ + + +/* + * This is a sample driver implementation template for the new acceleration + * interface. + */ + +#include "vga256.h" +#include "xf86.h" +#include "vga.h" +#define XCONFIG_FLAGS_ONLY +#include "xf86_Config.h" + +#include "xf86xaa.h" + +#include "sis_driver.h" +#include "sis_Blitter.h" +extern Bool sisUseXAAcolorExp ; +/* + * Include any definitions for communicating with the coprocessor here. + * In this sample driver, the following macros are defined: + * + * SETFOREGROUNDCOLOR(color) + * SETRASTEROP(rop) + * SETWRITEPLANEMASK(planemask) + * SETSOURCEADDR(srcaddr) + * SETDESTADDR(destaddr) + * SETWIDTH(width) + * SETHEIGHT(height) + * SETBLTXDIR(xdir) + * SETBLTYDIR(yrdir) + * SETCOMMAND(command) + * WAITUNTILFINISHED() + * + * The interface for accelerator chips varies widely, and this may not + * be a realistic scenario. In this sample implemention, the chip requires + * the source and destation location to be specified with addresses, but + * it might just as well use coordinates. When implementing the primitives, + * you will often find the need to store some settings in a variable. + */ +/* #include "coprocessor.h" */ + +void SISSync(); +void SISSetupForFillRectSolid(); +void SISSubsequentFillRectSolid(); +void SISSetupForScreenToScreenCopy(); +void SISSubsequentScreenToScreenCopy(); + +void SISSetupForScreenToScreenColorExpand(); +void SISSubsequentScreenToScreenColorExpand(); +void SISSetupForScanlineScreenToScreenColorExpand(); +void SISSubsequentScanlineScreenToScreenColorExpand(); + +void SISSetupFor8x8PatternColorExpand(); +void SISSubsequent8x8PatternColorExpand(); + +static int sisPatternHeight=16 ; + +/* + * The following function sets up the supported acceleration. Call it + * from the FbInit() function in the SVGA driver, or before ScreenInit + * in a monolithic server. + */ +void SISAccelInit() +{ + int cacheStart, cacheEnd; + int sisCursorSize = sisHWCursor ? 16384 : 0 ; + int offscreen_available ; + int sisBLTPatternAddress ; + int sisBLTPatternOffscreenSize ; + /* + * If you want to disable acceleration, just don't modify anything + * in the AccelInfoRec. + */ + + /* + * Set up the main acceleration flags. + * Usually, you will want to use BACKGROUND_OPERATIONS, + * and if you have ScreenToScreenCopy, use the PIXMAP_CACHE. + * + * If the chip is restricted in the screen-to-screen BitBLT + * directions it supports, you can indicate that here: + * + * ONLY_TWO_BITBLT_DIRECTIONS indicates that xdir must be equal to ydir. + * ONLY_LEFT_TO_RIGHT_BITBLT indicates that the xdir must be 1. + */ + + /* Disable the PIXMAP CACHE in no linear because XAA high level does not + * work with video in banked mode. + * May be in the future we could restore the PIXMAP CACHE even in banked + * mode + */ + + + xf86AccelInfoRec.Flags = BACKGROUND_OPERATIONS | + (sisUseXAAcolorExp ? PIXMAP_CACHE : 0 ) ; + + /* + * The following line installs a "Sync" function, that waits for + * all coprocessor operations to complete. + */ + xf86AccelInfoRec.Sync = SISSync; + + /* + * We want to set up the FillRectSolid primitive for filling a solid + * rectangle. First we set up the flags for the graphics operation. + * It may include GXCOPY_ONLY, NO_PLANEMASK, and RGB_EQUAL. + */ + xf86GCInfoRec.PolyFillRectSolidFlags = NO_PLANEMASK ; + + /* + * Install the low-level functions for drawing solid filled rectangles. + */ + xf86AccelInfoRec.SetupForFillRectSolid = SISSetupForFillRectSolid; + xf86AccelInfoRec.SubsequentFillRectSolid = SISSubsequentFillRectSolid; + + /* + * We also want to set up the ScreenToScreenCopy (BitBLT) primitive for + * copying a rectangular area from one location on the screen to + * another. First we set up the restrictions. In this case, we + * don't handle transparency color compare. Other allowed flags are + * GXCOPY_ONLY and NO_PLANEMASK. + */ + xf86GCInfoRec.CopyAreaFlags = NO_TRANSPARENCY | NO_PLANEMASK; + + /* + * Install the low-level functions for screen-to-screen copy. + */ + xf86AccelInfoRec.SetupForScreenToScreenCopy = + SISSetupForScreenToScreenCopy; + xf86AccelInfoRec.SubsequentScreenToScreenCopy = + SISSubsequentScreenToScreenCopy; + + /* Color Expansion */ + if (vga256InfoRec.bitsPerPixel != 24) { + /* the enhanced color expansion is not supported + * by the engine in 16M-color graphic mode. + */ + xf86AccelInfoRec.ColorExpandFlags = VIDEO_SOURCE_GRANULARITY_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + SCANLINE_PAD_DWORD | + GXCOPY_ONLY | + NO_PLANEMASK; + if ( sisUseXAAcolorExp ) { + xf86AccelInfoRec.SetupForScreenToScreenColorExpand = + SISSetupForScreenToScreenColorExpand; + xf86AccelInfoRec.SubsequentScreenToScreenColorExpand = + SISSubsequentScreenToScreenColorExpand; + xf86AccelInfoRec.SetupForScanlineScreenToScreenColorExpand = + SISSetupForScanlineScreenToScreenColorExpand; + xf86AccelInfoRec.SubsequentScanlineScreenToScreenColorExpand = + SISSubsequentScanlineScreenToScreenColorExpand; + + offscreen_available = vga256InfoRec.videoRam * 1024 - + vga256InfoRec.displayWidth * vga256InfoRec.virtualY + * (vgaBitsPerPixel / 8); + sisBLTPatternOffscreenSize = 1024 ; + + if (offscreen_available < sisBLTPatternOffscreenSize) { + ErrorF("%s %s: Not enough off-screen video" + " memory for expand color.\n", + XCONFIG_PROBED, vga256InfoRec.name); + sisBLTPatternOffscreenSize = 0 ; + } + else { + sisBLTPatternAddress = vga256InfoRec.videoRam * 1024 + - sisCursorSize - sisBLTPatternOffscreenSize; + xf86AccelInfoRec.ScratchBufferAddr=sisBLTPatternAddress; + xf86AccelInfoRec.ScratchBufferSize=sisBLTPatternOffscreenSize; + } + } + /* + * 8x8 color expand pattern fill + */ + xf86AccelInfoRec.PatternFlags = HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | + HARDWARE_PATTERN_BIT_ORDER_MSBFIRST | + HARDWARE_PATTERN_MONO_TRANSPARENCY ; + xf86AccelInfoRec.SetupFor8x8PatternColorExpand = + SISSetupFor8x8PatternColorExpand; + xf86AccelInfoRec.Subsequent8x8PatternColorExpand = + SISSubsequent8x8PatternColorExpand; + + } + /* + * Finally, we set up the video memory space available to the pixmap + * cache. In this case, all memory from the end of the virtual screen + * to the end of video memory minus 1K, can be used. If you haven't + * enabled the PIXMAP_CACHE flag, then these lines can be omitted. + */ + if (sisUseXAAcolorExp) { + cacheStart = + vga256InfoRec.virtualY * vga256InfoRec.displayWidth + * vga256InfoRec.bitsPerPixel / 8; + cacheEnd = + vga256InfoRec.videoRam * 1024 - 1024 - sisBLTPatternOffscreenSize - + sisCursorSize ; + + xf86InitPixmapCache(&vga256InfoRec, cacheStart, cacheEnd); + } + /* + * Now set variables often used + * + */ + + sisPatternHeight = (SISchipset == SIS86C205) ? 16 : 8 ; + +} + +/* + * This is the implementation of the Sync() function. + */ +void SISSync() { + sisBLTWAIT; +} + +static int sisALUConv[] = +{ + 0x00, /* dest = 0; GXclear, 0 */ + 0x88, /* dest &= src; GXand, 0x1 */ + 0x44, /* dest = src & ~dest; GXandReverse, 0x2 */ + 0xCC, /* dest = src; GXcopy, 0x3 */ + 0x22, /* dest &= ~src; GXandInverted, 0x4 */ + 0xAA, /* dest = dest; GXnoop, 0x5 */ + 0x66, /* dest = ^src; GXxor, 0x6 */ + 0xEE, /* dest |= src; GXor, 0x7 */ + 0x11, /* dest = ~src & ~dest;GXnor, 0x8 */ + 0x99, /*?? dest ^= ~src ;GXequiv, 0x9 */ + 0x55, /* dest = ~dest; GXInvert, 0xA */ + 0xDD, /* dest = src|~dest ;GXorReverse, 0xB */ + 0x33, /* dest = ~src; GXcopyInverted, 0xC */ + 0xBB, /* dest |= ~src; GXorInverted, 0xD */ + 0x77, /*?? dest = ~src|~dest ;GXnand, 0xE */ + 0xFF, /* dest = 0xFF; GXset, 0xF */ +}; + +/* + * This is the implementation of the SetupForFillRectSolid function + * that sets up the coprocessor for a subsequent batch of solid + * rectangle fills. + */ +void SISSetupForFillRectSolid(color, rop, planemask) + int color, rop; + unsigned planemask; +{ + + sisBLTWAIT; + sisSETFGCOLOR(color); + sisSETROP(sisALUConv[rop & 0xF]); + sisSETPITCH(vga256InfoRec.displayWidth * vgaBytesPerPixel, + vga256InfoRec.displayWidth * vgaBytesPerPixel); + /* + * If you don't support a write planemask, and have set the + * appropriate flag, then the planemask can be safely ignored. + * The same goes for the raster-op if only GXcopy is supported. + */ + /*SETWRITEPLANEMASK(planemask);*/ +} + +/* + * This is the implementation of the SubsequentForFillRectSolid function + * that sends commands to the coprocessor to fill a solid rectangle of + * the specified location and size, with the parameters from the SetUp + * call. + */ +void SISSubsequentFillRectSolid(x, y, w, h) + int x, y, w, h; +{ + int destaddr, op; + + destaddr = y * vga256InfoRec.displayWidth + x; + op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT; + destaddr *= vgaBytesPerPixel ; + /* + * When BACKGROUND_OPERATIONS is enabled, on some chips (such as + * Cirrus) you must wait here for the previous operation to finish. + * On others (like ARK or Matrox), you don't, or you might wait for + * a certain number of command FIFO slots to become free (the + * latter is often unnecessary, and it does impact performance). + */ + /* ChipSync(); */ + sisBLTWAIT; + sisSETHEIGHTWIDTH(h-1, w * vgaBytesPerPixel-1); + sisSETDSTADDR(destaddr); + sisSETCMD(op); + /* + * If you don't use BACKGROUND_OPERATIONS, this would be the + * place to call SISSync(). + */ +} + +/* + * This is the implementation of the SetupForScreenToScreenCopy function + * that sets up the coprocessor for a subsequent batch of + * screen-to-screen copies. Remember, we don't handle transparency, + * so the transparency color is ignored. + */ +static int blitxdir, blitydir; + +void SISSetupForScreenToScreenCopy(xdir, ydir, rop, planemask, +transparency_color) + int xdir, ydir; + int rop; + unsigned planemask; + int transparency_color; +{ + /* + * xdir can be either 1 (left-to-right) or -1 (right-to-left). + * ydir can be either 1 (top-to-bottom) or -1 (bottom-to-top). + */ + sisBLTWAIT; + sisSETPITCH(vga256InfoRec.displayWidth * vgaBytesPerPixel, + vga256InfoRec.displayWidth * vgaBytesPerPixel); + sisSETROP(sisALUConv[rop & 0xF]); + blitxdir = xdir; + blitydir = ydir; +} + +/* + * This is the implementation of the SubsequentForScreenToScreenCopy + * that sends commands to the coprocessor to perform a screen-to-screen + * copy of the specified areas, with the parameters from the SetUp call. + * In this sample implementation, the direction must be taken into + * account when calculating the addresses (with coordinates, it might be + * a little easier). + */ +void SISSubsequentScreenToScreenCopy(x1, y1, x2, y2, w, h) + int x1, y1, x2, y2, w, h; +{ + int srcaddr, destaddr; + int op ; + + /* + * If the direction is "decreasing", the chip wants the addresses + * to be at the other end, so we must be aware of that in our + * calculations. + */ + op = sisCMDBLT | sisSRCVIDEO; + if (blitydir == -1) { + op |= sisBOTTOM2TOP; + srcaddr = (y1 + h - 1) * vga256InfoRec.displayWidth; + destaddr = (y2 + h - 1) * vga256InfoRec.displayWidth; + } else { + op |= sisTOP2BOTTOM; + srcaddr = y1 * vga256InfoRec.displayWidth; + destaddr = y2 * vga256InfoRec.displayWidth; + } + if (blitxdir == -1) { + op |= sisRIGHT2LEFT; + srcaddr += x1 + w - 1; + destaddr += x2 + w - 1; + } else { + op |= sisLEFT2RIGHT; + srcaddr += x1; + destaddr += x2; + } + srcaddr *= vgaBytesPerPixel; + destaddr *= vgaBytesPerPixel; + if ( (vgaBytesPerPixel>1) && (blitxdir == -1) ) { + srcaddr += vgaBytesPerPixel-1; + destaddr += vgaBytesPerPixel-1; + } + /* + * Again, you may have to wait for the previous operation to + * finish when using BACKGROUND_OPERATIONS. + */ + /* SISSync(); */ + sisBLTWAIT; + sisSETSRCADDR(srcaddr); + sisSETDSTADDR(destaddr); + sisSETHEIGHTWIDTH(h-1, w * vgaBytesPerPixel-1); + sisSETCMD(op); + /* + * If you don't use BACKGROUND_OPERATIONS, this would be the + * place to call SISSync(). + */ +} + +/* + * setup for screen-to-screen color expansion + */ +static int sisColExp_op ; +void SISSetupForScreenToScreenColorExpand(bg, fg, rop, planemask) + int bg, fg, rop; + unsigned planemask; +{ + int isTransparent = ( bg == -1 ); + int op ; + + /*ErrorF("SISSetupScreenToScreenColorExpand()\n");*/ + + sisBLTWAIT; + op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT ; + + /* + * check transparency + */ + /* becareful with rop */ + if (isTransparent) { + sisSETFGCOLOR(fg); + sisSETROPFG(0xf0); /* pat copy */ + sisSETROPBG(0xAA); /* dst */ + op |= sisPATFG | sisSRCBG ; + } else { + sisSETBGCOLOR(bg); + sisSETFGCOLOR(fg); + sisSETROPFG(0xf0); /* pat copy */ + sisSETROPBG(0xcc); /* copy */ + op |= sisPATFG | sisSRCBG ; + } + op |= sisCMDENHCOLEXP ; + sisColExp_op = op ; +} + +/* + * executing screen-to-screen color expansion + */ +void SISSubsequentScreenToScreenColorExpand(srcx, srcy, x, y, ww, h) + int srcx, srcy, x, y, ww, h; +{ + int destpitch = vga256InfoRec.displayWidth * vgaBytesPerPixel ; + int srcaddr = srcy * destpitch * + srcx ; + int destaddr = y * destpitch + x * vgaBytesPerPixel; + int srcpitch ; + int w ; + int widthTodo ; + + /*ErrorF("SISSubsequentScreenToScreenColorExpand()\n");*/ +#define maxWidth 144 + /* can't expand more than maxWidth in one time. + it's a work around for scanline greater than maxWidth + */ + destpitch = vga256InfoRec.displayWidth * vgaBytesPerPixel ; + srcpitch = ((ww + 31)& ~31) /8 ; + sisBLTWAIT; + sisSETPITCH(srcpitch, destpitch); + widthTodo = ww ; + do { + w = widthTodo < maxWidth ? widthTodo : maxWidth ; + sisBLTWAIT; + sisSETDSTADDR(destaddr); + sisSETSRCADDR(srcaddr); + sisSETHEIGHTWIDTH(h-1, w*vgaBytesPerPixel-1); + sisSETCMD(sisColExp_op); + srcaddr += w ; + destaddr += w*vgaBytesPerPixel ; + widthTodo -= w ; + } while ( widthTodo > 0 ) ; + +} + +static int sisDstAddr; +static int sisDstPitch; +static int sisWidth ; +void SISSetupForScanlineScreenToScreenColorExpand(x, y, w, h, bg, fg, rop, +planemask) + int x, y, w, h, bg, fg, rop; + unsigned int planemask; +{ + int isTransparent = ( bg == -1 ); + int op ; + int pitch = vga256InfoRec.displayWidth * vgaBytesPerPixel ; + int destaddr = y * pitch + x * vgaBytesPerPixel; + + sisBLTWAIT; + op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT | + sisPATFG | sisSRCBG | sisCMDENHCOLEXP ; + /* + * check transparency + */ + /* becareful with rop */ + if (isTransparent) { + sisSETFGCOLOR(fg); + sisSETROPFG(0xf0); /* pat copy */ + sisSETROPBG(0xAA); /* dst */ + } else { + sisSETBGCOLOR(bg); + sisSETFGCOLOR(fg); + sisSETROPFG(0xf0); /* pat copy */ + sisSETROPBG(0xcc); /* copy */ + } + sisColExp_op = op ; + sisSETDSTADDR(destaddr); + sisDstPitch = pitch ; + sisDstAddr = destaddr ; + sisWidth = w ; +} + +void SISSubsequentScanlineScreenToScreenColorExpand(srcaddr) + int srcaddr; +{ + int widthTodo ; + int dstaddr, srcpitch ; + int w ; + + /*ErrorF("SISSubsequentScanlineScreenToScreenColorExpand()\n");*/ +#define maxWidth 144 + /* can't expand more than maxWidth in one time. + it's a work around for scanline greater than maxWidth + */ + dstaddr = sisDstAddr ; + widthTodo = sisWidth ; + do { + w = widthTodo < maxWidth ? widthTodo : maxWidth ; + srcpitch = ((w + 31)& ~31) /8 ; + sisBLTWAIT; + sisSETPITCH(srcpitch, sisDstPitch); + sisSETHEIGHTWIDTH(0, w*vgaBytesPerPixel-1); + sisSETSRCADDR(srcaddr/8); + sisSETDSTADDR(dstaddr); + sisSETCMD(sisColExp_op); + srcaddr += w ; + dstaddr += w*vgaBytesPerPixel ; + widthTodo -= w ; + } while ( widthTodo > 0 ) ; + sisDstAddr += sisDstPitch ; + + +} + +/* + * setup for 8x8 color expand pattern fill + * + * HARDWARE_PATTERN_PROGRAMMED_BITS mean pattern in patternx,patterny + * HARDWARE_PATTERN_PROGRAMMED_ORIGIN is not supported by the chip + * the rotation is done on the fly during the load of the pattern into + * the SiS registers. + */ +static unsigned int sisPatternReg[4]; /* plus 2 for rotation */ +void SISSetupFor8x8PatternColorExpand(patternx, patterny, bg, fg, + rop, planemask) + unsigned patternx, patterny, planemask; + int bg, fg, rop; +{ + unsigned int *patternRegPtr ; + int i ; + int dstpitch; + int isTransparent = ( bg == -1 ); + int op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT | + sisPATFG | sisSRCBG ; + + /*ErrorF("SISSetupFor8x8PatternColorExpand(%d %d %d %d %d %x)\n", + patternx, patterny, bg, fg, rop, planemask);*/ + sisBLTWAIT; + dstpitch = vga256InfoRec.displayWidth * vgaBytesPerPixel ; + /* + * check transparency + */ + /* becareful with rop */ + if (isTransparent) { + sisSETFGCOLOR(fg); + sisSETROPFG(0xf0); /* pat copy */ + sisSETROPBG(0xAA); /* dst */ + } else { + sisSETBGCOLOR(bg); + sisSETFGCOLOR(fg); + sisSETROPFG(0xf0); /* pat copy */ + sisSETROPBG(0xcc); /* copy */ + } + sisBLTWAIT; + sisSETPITCH(0, dstpitch); + sisSETSRCADDR(0); + sisColExp_op = op ; + patternRegPtr = (unsigned int *)sisSETPATREG(); + sisPatternReg[0] = sisPatternReg[2] = patternx ; + sisPatternReg[1] = sisPatternReg[3] = patterny ; + for ( i = 0 ; i < sisPatternHeight ; ) { + patternRegPtr[i++] = patternx ; + patternRegPtr[i++] = patterny ; + } +} + +/* + * executing 8x8 color expand pattern fill + * reload the pattern in the SiS registers and do the rotation. + */ +void SISSubsequent8x8PatternColorExpand(patternx, patterny, x, y, w, h) + unsigned patternx, patterny; + int x, y, w, h; +{ + int dstaddr; + register unsigned char *patternRegPtr ; + register unsigned char *srcPatternRegPtr ; + register unsigned int *patternRegPtrL ; + int i, k ; + unsigned short tmp; + int shift ; + + dstaddr = ( y * vga256InfoRec.displayWidth + x ) * vgaBytesPerPixel; + + /*ErrorF("SISSubsequent8x8PatternColorExpand(%d %d %d %d %d %d)\n", + patternx, patterny, x, y, w, h);*/ + sisBLTWAIT; + patternRegPtr = sisSETPATREG(); + srcPatternRegPtr = (unsigned char *)sisPatternReg ; + shift = 8-patternx ; + for ( i = 0, k = patterny ; i < 8 ; i++, k++ ) { + tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ; + tmp >>= shift ; + patternRegPtr[i] = tmp & 0xff ; + } + patternRegPtrL = (unsigned int *)sisSETPATREG(); + for ( i = 2 ; i < sisPatternHeight ; ) { + patternRegPtrL[i++] = patternRegPtrL[0]; + patternRegPtrL[i++] = patternRegPtrL[1]; + } + + sisSETDSTADDR(dstaddr); + sisSETHEIGHTWIDTH(h-1, w*vgaBytesPerPixel-1); + sisSETCMD(sisColExp_op); +} + + + + + + diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_bank.s b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_bank.s index 80ef2c2d7..d7d923958 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_bank.s +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_bank.s @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/sis/sis_bank.s,v 3.2 1996/12/23 06:58:30 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_bank.s,v 1.1 1997/03/06 23:16:50 hohndel Exp $ */ /* * Copyright 1995 by Alan Hourihane, Wigan, England. * diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_blitter.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_blitter.c index 8d0fb04ce..70badb345 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_blitter.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_blitter.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/sis/sis_blitter.c,v 1.1 1997/01/12 10:43:06 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_blitter.c,v 1.1 1997/03/06 23:16:50 hohndel Exp $ */ /* * diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_blt16.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_blt16.c index e0953ddd9..4dd552c64 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_blt16.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_blt16.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/sis/sis_blt16.c,v 1.1 1997/01/12 10:43:07 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_blt16.c,v 1.1 1997/03/06 23:16:51 hohndel Exp $ */ /* * Hooks for cfb16/24 CopyArea diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_colexp.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_colexp.c index e718e1aca..7b3fbde3a 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_colexp.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_colexp.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_colexp.c,v 1.1 1997/03/06 23:16:52 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_colexp.c,v 1.2 1998/01/24 16:58:21 hohndel Exp $ */ /* * diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_curs.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_curs.c index 6e5b6a795..abec3f0cd 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_curs.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_curs.c @@ -26,7 +26,7 @@ * accel/s3/s3Cursor.c, and ark/ark_cursor.c */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_curs.c,v 1.2 1997/05/31 13:51:34 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_curs.c,v 1.3 1998/01/24 16:58:22 hohndel Exp $ */ #include "X.h" #include "Xproto.h" diff --git a/programs/Xserver/hw/xfree86/olddrivers/sis/sis_driver.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_driver.c new file mode 100644 index 000000000..d7f953baf --- /dev/null +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_driver.c @@ -0,0 +1,1553 @@ +/* $XConsortium: sis86c201.c /main/11 1996/10/27 13:24:11 kaleb $ */ +/* + * Copyright 1995 by Alan Hourihane, Wigan, England. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Author: Alan Hourihane, alanh@fairlite.demon.co.uk + * + * Modified 1996 by Xavier Ducoin <xavier@rd.lectra.fr> + * + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.9 1998/03/27 23:23:41 hohndel Exp $ */ + +/*#define DEBUG*/ +/*#define IO_DEBUG*/ + +/*#define USE_XAA*/ +#include "X.h" +#include "input.h" +#include "screenint.h" +#include "dix.h" + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Version.h" +#include "xf86Priv.h" +#include "xf86_ansic.h" +#include "xf86_HWlib.h" +#define XCONFIG_FLAGS_ONLY +#include "xf86_Config.h" +#include "vga.h" +#include "vgaPCI.h" + +#ifdef XFreeXDGA +#include "X.h" +#include "Xproto.h" +#include "scrnintstr.h" +#include "servermd.h" +#define _XF86DGA_SERVER_ +#include "extensions/xf86dgastr.h" +#endif + +#include "vga256.h" +#include "sis_driver.h" +#define SIS86C201 0 +#define SIS86C202 1 +#define SIS86C205 2 + +extern vgaHWCursorRec vgaHWCursor; + +/* Blitter related */ +/*address in video ram of tile/stipple pattern*/ +unsigned int sisBLTPatternAddress = -1; +int sisBLTPatternOffscreenSize = 0 ; +unsigned char *sisBltDataWindow = NULL; +Bool sisAvoidImageBLT = FALSE; + +int sisReg32MMIO[]={0x8280,0x8284,0x8288,0x828C,0x8290,0x8294,0x8298,0x829C, + 0x82A0,0x82A4,0x82A8,0x82AC}; +extern GCOps cfb16TEOps1Rect, cfb16TEOps, cfb16NonTEOps1Rect, cfb16NonTEOps; +extern GCOps cfb24TEOps1Rect, cfb24TEOps, cfb24NonTEOps1Rect, cfb24NonTEOps; + +Bool sisHWCursor = FALSE ; + +/* Clock related */ +typedef struct { + unsigned char msr; + unsigned char xr2A; + unsigned char xr2B; + int Clock; +} sisClockReg, *sisClockPtr; + +typedef struct { + vgaHWRec std; /* std IBM VGA register */ + unsigned char Port_3C4[0x38]; + unsigned char ClockReg2; + sisClockReg sisClock; +} vgaSISRec, *vgaSISPtr; + +/* alias for specific extended registers */ +#define ClockReg Port_3C4[0x07] +#define DualBanks Port_3C4[0x0B] +#define BankReg Port_3C4[0x06] +#define CRTCOff Port_3C4[0x0A] +#define DispCRT Port_3C4[0x27] +#define Unknown Port_3C4[0x08] +#define LinearAddr0 Port_3C4[0x20] +#define LinearAddr1 Port_3C4[0x21] + +static Bool SISClockSelect(); +static char *SISIdent(); +static Bool SISProbe(); +static void SISEnterLeave(); +static Bool SISInit(); +static int SISValidMode(); +static void *SISSave(); +static void SISRestore(); +static void SISFbInit(); +static void SISAdjust(); +static void SISDisplayPowerManagementSet(); +extern void SISSetRead(); +extern void SISSetWrite(); +extern void SISSetReadWrite(); + +extern int SISCursorHotX; +extern int SISCursorHotY; +extern int SISCursorWidth; +extern int SISCursorHeight; + +extern Bool SISCursorInit(); +extern void SISRestoreCursor(); +extern void SISWarpCursor(); +extern void SISQueryBestSize(); + +vgaVideoChipRec SIS = { + SISProbe, + SISIdent, + SISEnterLeave, + SISInit, + SISValidMode, + SISSave, + SISRestore, + SISAdjust, + vgaHWSaveScreen, + (void (*)())NoopDDA, + SISFbInit, + SISSetRead, + SISSetWrite, + SISSetReadWrite, + 0x10000, + 0x10000, + 16, + 0xffff, + 0x00000, 0x10000, + 0x00000, 0x10000, + TRUE, + VGA_DIVIDE_VERT, + {0,}, + 16, + FALSE, + 0, + 0, + /* + * This is TRUE if the driver has support for the given depth for + * the detected configuration. It must be set in the Probe function. + * It most cases it should be FALSE. + */ + TRUE, /* 1bpp */ + TRUE, /* 4bpp */ + TRUE, /* 8bpp */ + FALSE, /* 15bpp */ + TRUE, /* 16bpp */ + TRUE, /* 24bpp */ + FALSE, /* 32bpp */ + NULL, + 1, /* ClockMulFactor */ + 1 /* ClockDivFactor */ +}; + +#define new ((vgaSISPtr)vgaNewVideoState) + +int SISchipset; +/* default is enhanced mode (use option to disable)*/ +Bool sisUseLinear = TRUE; +Bool sisUseMMIO = TRUE; +Bool sisUseXAAcolorExp = TRUE; +static int SISDisplayableMemory; +unsigned char *sisMMIOBase = NULL; +unsigned long PCIMMIOBase=0; + + +#ifdef XFree86LOADER +XF86ModuleVersionInfo sisVersRec = +{ + "sis_drv.o", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + 0x00010001, + {0,0,0,0} +}; + +/* + * this function returns the vgaVideoChipPtr for this driver + * + * its name has to be ModuleInit() + */ +void +ModuleInit(data,magic) + pointer * data; + INT32 * magic; +{ + static int cnt = 0; + + switch(cnt++) + { + /* MAGIC_VERSION must be first in ModuleInit */ + case 0: + * data = (pointer) &sisVersRec; + * magic= MAGIC_VERSION; + break; + case 1: + * data = (pointer)&SIS; + * magic= MAGIC_ADD_VIDEO_CHIP_REC; + break; + default: + xf86issvgatype = TRUE; /* later load the correct libvgaxx.a */ + * magic= MAGIC_DONE; + break; + } + + return; +} +#endif /* XFree86LOADER */ + +/* + * SISIdent -- + */ +static char * +SISIdent(n) + int n; +{ + static char *chipsets[] = {"sis86c201", "sis86c202", "sis86c205", }; + + if (n + 1 > sizeof(chipsets) / sizeof(char *)) + return(NULL); + else + return(chipsets[n]); +} + +/* + * SISClockSelect -- + * select one of the possible clocks ... + */ +static Bool +SISClockSelect(no) + int no; +{ + static unsigned char save1, save2; + unsigned char temp; +#ifdef DEBUG + ErrorF("SISClockSelect(%d)\n",no); +#endif + + /* + * CS0 and CS1 are in MiscOutReg + * + * CS2,CS3,CS4 are in 0x3C4 index 7 + * But - only active when CS0/CS1 are set. + */ + switch(no) + { + case CLK_REG_SAVE: + save1 = inb(0x3CC); + outb(0x3C4, 0x07); + save2 = inb(0x3C5); + break; + case CLK_REG_RESTORE: + outb(0x3C2, save1); + outw(0x3C4, (save2 << 8) | 0x07); + break; + default: + /* + * Do CS0 and CS1 and set them - makes index 7 valid + */ + temp = inb(0x3CC); + temp &= ~0x0C ; + if ( no >= 2 ) { + outb(0x3C2, temp | 0x0C); + outw(0x3C4, (no << 8) | 0x07); + } + else /* using vga clock */ + outb(0x3C2, temp | ( (no<<2) & 0x0C) ); + + } + return(TRUE); +} + +#define write_xr(num,val) {outb(0x3C4, num);outb(0x3C5, val);} +#define read_xr(num,var) {outb(0x3C4, num);var=inb(0x3C5);} + +static Bool +ClockProgramable() +{ + if (vgaBitsPerPixel < 8) + return FALSE; + else + return (OFLG_ISSET(CLOCK_OPTION_PROGRAMABLE, + &vga256InfoRec.clockOptions)) ; +} + +static void +sisCalcClock(int Clock, unsigned int *vclk) +{ + int M, N, P, PSN, VLD, PSNx; + + int bestM, bestN, bestP, bestPSN, bestVLD; + double bestError, abest = 42, bestFout; + double target; + + double Fvco, Fout; + double error, aerror; + + + + /* + * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler) + * + * M = Numerator [1:128] + * N = DeNumerator [1:32] + * VLD = Divider (Vco Loop Divider) : divide by 1, 2 + * P = Post Scaler : divide by 1, 2, 3, 4 + * PSN = Pre Scaler (Reference Divisor Select) + * + * result in vclk[] + */ +#define Midx 0 +#define Nidx 1 +#define VLDidx 2 +#define Pidx 3 +#define PSNidx 4 +#define Fref 14318180 +/* stability constraints for internal VCO -- MAX_VCO also determines + * the maximum Video pixel clock */ +#define MIN_VCO Fref +#define MAX_VCO 135000000 +#define MAX_VLD 2 +#define MAX_PSN 0 /* no pre scaler for this chip */ + + int M_min = 2; + int M_max = 128; + + target = Clock * 1000; + + for (PSNx = 0; PSNx <= MAX_PSN ; PSNx++) { + int low_N, high_N; + double FrefVLDPSN; + + PSN = !PSNx ? 1 : 4; + + low_N = 2; + high_N = 32; + + for ( VLD = 1 ; VLD <= MAX_VLD ; VLD++ ) { + + FrefVLDPSN = (double)Fref * VLD / PSN; + for (N = low_N; N <= high_N; N++) { + double tmp = FrefVLDPSN / N; + + for (P = 1; P <= 4; P++) { + double Fvco_desired = target * ( P ); + double M_desired = Fvco_desired / tmp; + + /* Which way will M_desired be rounded? + * Do all three just to be safe. + */ + int M_low = M_desired - 1; + int M_hi = M_desired + 1; + + if (M_hi < M_min || M_low > M_max) + continue; + + if (M_low < M_min) + M_low = M_min; + if (M_hi > M_max) + M_hi = M_max; + + for (M = M_low; M <= M_hi; M++) { + Fvco = tmp * M; + if (Fvco <= MIN_VCO) + continue; + if (Fvco > MAX_VCO) + break; + + Fout = Fvco / ( P ); + + error = (target - Fout) / target; + aerror = (error < 0) ? -error : error; + if (aerror < abest) { + abest = aerror; + bestError = error; + bestM = M; + bestN = N; + bestP = P; + bestPSN = PSN; + bestVLD = VLD; + bestFout = Fout; + } +#ifdef DEBUG1 + ErrorF("Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d," + " P=%d, PSN=%d\n", + (float)(Clock / 1000.), M, N, P, VLD, PSN); + ErrorF("Freq. set: %.2f MHz\n", Fout / 1.0e6); +#endif + } + } + } + } + } + vclk[Midx] = bestM; + vclk[Nidx] = bestN; + vclk[VLDidx] = bestVLD; + vclk[Pidx] = bestP; + vclk[PSNidx] = bestPSN; +#ifdef DEBUG + ErrorF("Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n", + (float)(Clock / 1000.), vclk[Midx], vclk[Nidx], vclk[VLDidx], + vclk[Pidx], vclk[PSNidx]); + ErrorF("Freq. set: %.2f MHz\n", bestFout / 1.0e6); +#endif +} + +static void +sisClockSave(Clock) + sisClockPtr Clock; +{ +#ifdef DEBUG + ErrorF("sisClockSave(Clock)\n"); +#endif + Clock->msr = (inb(0x3CC) & 0xFE); /* save the standard VGA clock + * registers */ + read_xr(0x2A, Clock->xr2A); + read_xr(0x2B, Clock->xr2B); + +} + +static void +sisClockRestore(Clock) + sisClockPtr Clock; +{ +#ifdef DEBUG + ErrorF("sisClockRestore(Clock)\n"); +#endif + outb(0x3C2, Clock->msr); + write_xr(0x2A, Clock->xr2A); + write_xr(0x2B, Clock->xr2B); + +} + +static Bool +sisClockFind(no, Clock) + int no; + sisClockPtr Clock; +{ + int clock ; + + clock = vga256InfoRec.clock[no] ; + +#ifdef DEBUG + ErrorF("sisClockFind(%d %d)\n",no,clock); +#endif + + if (no > (vga256InfoRec.clocks - 1)) + return (FALSE); + + Clock->Clock = clock; + + return (TRUE); +} + +static void +sisClockLoad(Clock) + sisClockPtr Clock; +{ + unsigned int vclk[5]; + unsigned char temp, xr2a, xr2b; +#ifdef DEBUG + ErrorF("sisClockLoad(Clock)\n"); +#endif + + if (!Clock->Clock) { /* Hack to load saved console clock */ + sisClockRestore(Clock) ; + } + else { + sisCalcClock(Clock->Clock, vclk); + + xr2a = (vclk[Midx] - 1) & 0x7f ; + xr2a |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ; + xr2b = (vclk[Nidx] -1) & 0x1f ; + xr2b |= (vclk[Pidx] -1 ) << 5 ; + /*xr2b |= 0x80 ;*/ /* gain for high frequency */ + + write_xr(0x2A, xr2a ); + write_xr(0x2B, xr2b ); +#ifdef DEBUG + ErrorF("xr2a=%2x xr2b=%2x\n",xr2a, xr2b); +#endif + } +} + + +/* + * SISProbe -- + * check up whether a SIS 86C201 based board is installed + */ +static Bool +SISProbe() +{ + int numClocks; + unsigned char temp; + pciConfigPtr pcr, *pcrpp; + int i; + + SISchipset = -1; + SIS.ChipLinearBase = -1; + + pcrpp = xf86scanpci(vga256InfoRec.scrnIndex); + for (i = 0, pcr = pcrpp[0]; pcr; pcr = pcrpp[++i]) { + if (pcr->_vendor == PCI_VENDOR_SIS) + break; + } + + if (pcr) { + switch (pcr->_device) { + case PCI_CHIP_SG86C201: /* 86C201 */ + SISchipset = SIS86C201; + break; + case PCI_CHIP_SG86C202: /* 86C202 */ + SISchipset = SIS86C202; + break; + case PCI_CHIP_SG86C205: /* 86C205 */ + SISchipset = SIS86C205; + break; + } + if (pcr->_base0) + if (pcr->_base0 & 1) + PCIMMIOBase = pcr->_base0 & 0xfffffffc; + else + SIS.ChipLinearBase = pcr->_base0 & 0xfffffff0; + if (pcr->_base1) + if (pcr->_base1 & 1) + PCIMMIOBase = pcr->_base1 & 0xfffffffc; + else + SIS.ChipLinearBase = pcr->_base1 & 0xfffffff0; + + if (SIS.ChipLinearBase != -1) + SIS.ChipLinearBase &= 0xfff80000; + else + ErrorF("%s %s: %s: Can't find valid PCI " + "Base Address\n", XCONFIG_PROBED, + vga256InfoRec.name, vga256InfoRec.chipset); + + } else { + if (xf86Verbose > 1) + ErrorF("%s %s: %s: Can't find SiS PCI device in " + "configuration space\n", XCONFIG_PROBED, + vga256InfoRec.name, vga256InfoRec.chipset); + } + + if (vga256InfoRec.chipset) + { + /* + * If chipset from XF86Config doesn't match... + */ + if (!StrCaseCmp(vga256InfoRec.chipset, SISIdent(0))) + SISchipset = SIS86C201; + else if (!StrCaseCmp(vga256InfoRec.chipset, SISIdent(1))) + SISchipset = SIS86C202; + else if (!StrCaseCmp(vga256InfoRec.chipset, SISIdent(2))) + SISchipset = SIS86C205; + else + return(FALSE); + } + else + { + /* Aparently there are only PCI based 86C201's */ + if (SISchipset == -1) + return (FALSE); + vga256InfoRec.chipset = SISIdent(SISchipset); + } + + SISEnterLeave(ENTER); + + /* + * How much Video Ram have we got? + */ + if (!vga256InfoRec.videoRam) + { + unsigned char temp; + + outb(0x3C4, 0x0F); + temp = inb(0x3C5); + + switch (temp & 0x03) + { + case 0: + vga256InfoRec.videoRam = 1024; + break; + case 1: + vga256InfoRec.videoRam = 2048; + break; + case 2: + vga256InfoRec.videoRam = 4096; + break; + } + } + + if (vgaBitsPerPixel < 8) { + if (!vga256InfoRec.clocks) { + numClocks = 4; + vgaGetClocks(numClocks, SISClockSelect); + } + } else { + /* + * If clocks are not specified in XF86Config file, probe for them + */ + if ( (OFLG_ISSET(OPTION_HW_CLKS, &vga256InfoRec.options)) || + (SISchipset == SIS86C201) ) { + /* if sis86c201 force to use the hw clock + * if programmable clock works with the sis86c201 + * let us know + */ + if (!vga256InfoRec.clocks) { + numClocks = 32; + vgaGetClocks(numClocks, SISClockSelect); + } + } + else { + OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &vga256InfoRec.clockOptions); + ErrorF("%s %s: using programmable clocks.\n", + XCONFIG_PROBED, vga256InfoRec.name); + if(!vga256InfoRec.clockprog) + vga256InfoRec.clocks = 0; + } + + /* maximal clock */ + if ( (SISchipset == SIS86C205) || (SISchipset == SIS86C202) ) + vga256InfoRec.maxClock = 135000; + } + + vga256InfoRec.bankedMono = TRUE; + if (vgaBitsPerPixel > 8) { + /* We support Direct Video Access */ + vga256InfoRec.directMode = XF86DGADirectPresent; + + /* MaxClock set at 90MHz for 256 - ??? */ + + OFLG_SET(OPTION_HW_CURSOR, &SIS.ChipOptionFlags); + OFLG_SET(OPTION_SW_CURSOR, &SIS.ChipOptionFlags); + OFLG_SET(OPTION_HW_CLKS, &SIS.ChipOptionFlags); + OFLG_SET(OPTION_LINEAR, &SIS.ChipOptionFlags); + OFLG_SET(OPTION_MMIO, &SIS.ChipOptionFlags); + OFLG_SET(OPTION_NOLINEAR_MODE, &SIS.ChipOptionFlags); + OFLG_SET(OPTION_NO_BITBLT, &SIS.ChipOptionFlags); + OFLG_SET(OPTION_NO_IMAGEBLT, &SIS.ChipOptionFlags); + OFLG_SET(OPTION_NOACCEL, &SIS.ChipOptionFlags); + } else { + /* Set to 130MHz at 16 colours */ + vga256InfoRec.maxClock = 130000; + } +#ifdef DPMSExtension + vga256InfoRec.DPMSSet = SISDisplayPowerManagementSet; +#endif + + return(TRUE); +} + +/* + * SISScrnInit -- + * + * Sets some accelerated functions + */ +static int +SISScrnInit(pScreen, LinearBase, virtualX, virtualY, res1, res2, width) +ScreenPtr pScreen; +char *LinearBase; +int virtualX, virtualY, res1, res2, width; +{ +#ifdef DEBUG + ErrorF("SISScrnInit\n"); +#endif + if (vgaBitsPerPixel > 8) { + pScreen->CopyWindow = siscfbCopyWindow; + pScreen->PaintWindowBackground = sisPaintWindow; + pScreen->PaintWindowBorder = sisPaintWindow; + } + return(TRUE); +} + +/* + * SISFbInit -- + * enable speedups for the chips that support it + */ +static void +SISFbInit() +{ + unsigned long j; + unsigned long i; + pointer sisVideoMem; + long *poker; + int offscreen_available; + unsigned char tmp1,tmp2; +#ifdef DEBUG + ErrorF("SISFbInit()\n"); +#endif + + if (vgaBitsPerPixel >= 8) { + if (OFLG_ISSET(OPTION_LINEAR, &vga256InfoRec.options)) + { + ErrorF("%s %s: Enabling Linear Addressing\n", + XCONFIG_GIVEN, vga256InfoRec.name); + sisUseLinear = TRUE; + } + if (OFLG_ISSET(OPTION_NOLINEAR_MODE, &vga256InfoRec.options)) + { + ErrorF("%s %s: Disabling Linear Addressing\n", + XCONFIG_GIVEN, vga256InfoRec.name); + sisUseLinear = FALSE; + } + + if ( sisUseLinear ) { + if (vga256InfoRec.MemBase != 0) { + SIS.ChipLinearBase = vga256InfoRec.MemBase; + ErrorF("%s %s: base address is set at 0x%X.\n", + XCONFIG_GIVEN, vga256InfoRec.name, SIS.ChipLinearBase); + } + else { + if (SIS.ChipLinearBase == -1) { + unsigned long addr,addr2 ; + + outb(0x3C4, 0x21); + addr = inb(0x3C5) & 0x1f ; + addr <<= 27 ; + outb(0x3C4, 0x20); + addr2 = inb(0x3C5) ; + addr2 <<= 19 ; + addr |= addr2 ; + if ( addr == 0 ) { + ErrorF("%s %s: Disabling Linear Addressing\n", + XCONFIG_PROBED, vga256InfoRec.name); + ErrorF("%s %s: Try to set MemBase in XF86Config\n", + XCONFIG_PROBED, vga256InfoRec.name); + sisUseLinear = FALSE; + } + else { + SIS.ChipLinearBase = addr ; + ErrorF("%s %s: Trying Linear Addressing at 0x0%x\n", + XCONFIG_PROBED, vga256InfoRec.name, + SIS.ChipLinearBase); + } + } + } + } + + if ( sisUseLinear && xf86LinearVidMem() ) + { + SIS.ChipLinearSize = vga256InfoRec.videoRam * 1024; + ErrorF("%s %s: Using Linear Frame Buffer at 0x0%x, Size %dMB\n" + ,XCONFIG_PROBED, vga256InfoRec.name, + SIS.ChipLinearBase, SIS.ChipLinearSize/1048576); + } + + if (sisUseLinear) + SIS.ChipUseLinearAddressing = TRUE; + else + SIS.ChipUseLinearAddressing = FALSE; + + if (sisUseMMIO && OFLG_ISSET(OPTION_NO_BITBLT,&vga256InfoRec.options)){ + sisUseMMIO = FALSE ; + ErrorF("%s %s: SIS: Bit Block Transfert disabled\n", + OFLG_ISSET(OPTION_NO_BITBLT, &vga256InfoRec.options) ? + XCONFIG_GIVEN : XCONFIG_PROBED, vga256InfoRec.name); + } + + if ( sisUseMMIO ){ + sisUseMMIO = TRUE ; + if (PCIMMIOBase == 0) { + /* use default base */ + if ( sisUseLinear) + /* sisMMIOBase = vgaBase , but not yet mapped here */ + PCIMMIOBase = vga256InfoRec.VGAbase; + else { + PCIMMIOBase = 0xB0000 ; + sisMMIOBase = xf86MapVidMem(vga256InfoRec.scrnIndex, + MMIO_REGION, + (pointer)(PCIMMIOBase), 0x10000L); + } + } else { + sisMMIOBase = xf86MapVidMem(vga256InfoRec.scrnIndex, + MMIO_REGION, + (pointer)(PCIMMIOBase), 0x10000L); + } + ErrorF("%s %s: SIS: Memory mapped I/O selected at 0x0%x\n", + OFLG_ISSET(OPTION_MMIO, &vga256InfoRec.options) ? + XCONFIG_GIVEN : XCONFIG_PROBED, + vga256InfoRec.name,PCIMMIOBase); + } + + + SISDisplayableMemory = vga256InfoRec.displayWidth + * vga256InfoRec.virtualY + * (vgaBitsPerPixel / 8); + + offscreen_available = vga256InfoRec.videoRam * 1024 - + SISDisplayableMemory; + + if (OFLG_ISSET(OPTION_HW_CURSOR, &vga256InfoRec.options) || + !OFLG_ISSET(OPTION_SW_CURSOR, &vga256InfoRec.options) ) + { + OFLG_SET(OPTION_HW_CURSOR, &vga256InfoRec.options) ; + /* SiS needs upper 16K for hardware cursor */ + if (offscreen_available < 16384) + ErrorF("%s %s: Not enough off-screen video" + " memory for hardware cursor," + " using software cursor.\n", + XCONFIG_PROBED, vga256InfoRec.name); + else { + SISCursorWidth = 64; + SISCursorHeight = 64; + vgaHWCursor.Initialized = TRUE; + vgaHWCursor.Init = SISCursorInit; + vgaHWCursor.Restore = SISRestoreCursor; + vgaHWCursor.Warp = SISWarpCursor; + vgaHWCursor.QueryBestSize = SISQueryBestSize; + sisHWCursor = TRUE; + ErrorF("%s %s: Using hardware cursor\n", + XCONFIG_GIVEN, vga256InfoRec.name); + /* new offscreen_available */ + offscreen_available -= 16384 ; + } + } + + if (OFLG_ISSET(OPTION_NO_IMAGEBLT, &vga256InfoRec.options)) { + ErrorF("%s %s: SIS: Not using mono expand system-to-video BitBLT.\n", + XCONFIG_GIVEN, vga256InfoRec.name); + sisAvoidImageBLT = TRUE; + } + + if (sisUseMMIO) { + if (!OFLG_ISSET(OPTION_NOACCEL, &vga256InfoRec.options)) { + if ( !sisUseLinear || + OFLG_ISSET(OPTION_XAA_NO_COL_EXP, &vga256InfoRec.options)) + sisUseXAAcolorExp = FALSE; + SISAccelInit(); + } + else if ( sisUseLinear ) { + ErrorF("%s %s: SIS: using old accelerated functions.\n", + XCONFIG_PROBED, vga256InfoRec.name); + switch (vgaBitsPerPixel) { + case 8: + + vga256LowlevFuncs.doBitbltCopy = siscfbDoBitbltCopy; + vga256LowlevFuncs.vgaBitblt = sisMMIOBitBlt; + + vga256LowlevFuncs.fillRectSolidCopy = sisMMIOFillRectSolid; + + vga256LowlevFuncs.fillBoxSolid = siscfbFillBoxSolid; + vga256TEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; + vga256TEOps.FillSpans = sisMMIOFillSolidSpansGeneral; + vga256LowlevFuncs.fillSolidSpans =sisMMIOFillSolidSpansGeneral; + + /* Setup the address of the tile/stipple in vram. + * be aligned on a 64 bytes value. Size of the space + * is 1024 */ + /* in the future it might be better to keep all the offscreen + memory for cache pixmap/bitmap + */ + if (offscreen_available < 1024) { + ErrorF("%s %s: Not enough off-screen video" + " memory for expand color." + " using builin pattern reg for 512 pixels\n", + XCONFIG_PROBED, vga256InfoRec.name); + sisBLTPatternOffscreenSize = + (SISchipset == SIS86C205) ? 512 : 256 ; + } + else { + int CursorSize = sisHWCursor?16384:0 ; + sisBLTPatternAddress = vga256InfoRec.videoRam * 1024 + - CursorSize - 1024; + sisBLTPatternOffscreenSize = 1024 ; + } + /* Hook special op. fills (and tiles): */ + vga256TEOps1Rect.PolyFillRect = siscfbPolyFillRect; + vga256NonTEOps1Rect.PolyFillRect = siscfbPolyFillRect; + vga256TEOps.PolyFillRect = siscfbPolyFillRect; + vga256NonTEOps.PolyFillRect = siscfbPolyFillRect; + + if (!OFLG_ISSET(OPTION_NO_IMAGEBLT, + &vga256InfoRec.options)) { + vga256TEOps1Rect.PolyGlyphBlt = sisMMIOPolyGlyphBlt; + vga256TEOps.PolyGlyphBlt = sisMMIOPolyGlyphBlt; + vga256LowlevFuncs.teGlyphBlt8 = sisMMIOImageGlyphBlt; + vga256TEOps1Rect.ImageGlyphBlt = sisMMIOImageGlyphBlt; + vga256TEOps.ImageGlyphBlt = sisMMIOImageGlyphBlt; + } + + break; + case 16: + /* There are no corresponding structures to vga256LowlevFuncs + * for 16/24bpp. Hence we have to hook to the cfb functions + * in a similar way to the cirrus driver. For now I've just + * implemented the most basic of blits */ + + cfb16TEOps1Rect.CopyArea = siscfb16CopyArea; + cfb16TEOps.CopyArea = siscfb16CopyArea; + cfb16NonTEOps1Rect.CopyArea = siscfb16CopyArea; + cfb16NonTEOps.CopyArea = siscfb16CopyArea; + + cfb16TEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; + cfb16TEOps.FillSpans = sisMMIOFillSolidSpansGeneral; + cfb16NonTEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; + cfb16NonTEOps.FillSpans = sisMMIOFillSolidSpansGeneral; + + /* Setup the address of the tile/stipple in vram. + * be aligned on a 64 bytes value. Size of the space + * is 1024 */ + /* in the future it might be better to keep all the offscreen + memory for cache pixmap/bitmap + */ + if (offscreen_available < 1024) { + ErrorF("%s %s: Not enough off-screen video" + " memory for expand color." + " using builin pattern reg for 512 pixels\n", + XCONFIG_PROBED, vga256InfoRec.name); + sisBLTPatternOffscreenSize = + (SISchipset == SIS86C205) ? 512 : 256 ; + } + else { + int CursorSize = sisHWCursor?16384:0 ; + sisBLTPatternAddress = vga256InfoRec.videoRam * 1024 + - CursorSize - 1024; + sisBLTPatternOffscreenSize = 1024 ; + } + cfb16TEOps1Rect.PolyFillRect = siscfbPolyFillRect; + cfb16TEOps.PolyFillRect = siscfbPolyFillRect; + cfb16NonTEOps1Rect.PolyFillRect = siscfbPolyFillRect; + cfb16NonTEOps.PolyFillRect = siscfbPolyFillRect; + + if (!OFLG_ISSET(OPTION_NO_IMAGEBLT, + &vga256InfoRec.options)) { + cfb16TEOps1Rect.PolyGlyphBlt = sisMMIOPolyGlyphBlt; + cfb16TEOps.PolyGlyphBlt = sisMMIOPolyGlyphBlt; + cfb16TEOps1Rect.ImageGlyphBlt = sisMMIOImageGlyphBlt; + cfb16TEOps.ImageGlyphBlt = sisMMIOImageGlyphBlt; + } + + break ; + case 24: + + cfb24TEOps1Rect.CopyArea = siscfb24CopyArea; + cfb24TEOps.CopyArea = siscfb24CopyArea; + cfb24NonTEOps1Rect.CopyArea = siscfb24CopyArea; + cfb24NonTEOps.CopyArea = siscfb24CopyArea; + + cfb24TEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; + cfb24TEOps.FillSpans = sisMMIOFillSolidSpansGeneral; + cfb24NonTEOps1Rect.FillSpans = sisMMIOFillSolidSpansGeneral; + cfb24NonTEOps.FillSpans = sisMMIOFillSolidSpansGeneral; + + /* Setup the address of the tile/stipple in vram. + * be aligned on a 64 bytes value. Size of the space + * is 1024 */ + /* in the future it might be better to keep all the offscreen + memory for cache pixmap/bitmap + */ + if (offscreen_available < 1024) { + ErrorF("%s %s: Not enough off-screen video" + " memory for expand color." + " using builin pattern reg for 512 pixels\n", + XCONFIG_PROBED, vga256InfoRec.name); + sisBLTPatternOffscreenSize = + (SISchipset == SIS86C205) ? 512 : 256 ; + } + else { + int CursorSize = sisHWCursor?16384:0 ; + sisBLTPatternAddress = vga256InfoRec.videoRam * 1024 + - CursorSize - 1024; + sisBLTPatternOffscreenSize = 1024 ; + } + cfb24TEOps1Rect.PolyFillRect = siscfbPolyFillRect; + cfb24TEOps.PolyFillRect = siscfbPolyFillRect; + cfb24NonTEOps1Rect.PolyFillRect = siscfbPolyFillRect; + cfb24NonTEOps.PolyFillRect = siscfbPolyFillRect; + + /* the enhanced color expansion is not supported + * by the engine in 16M-color graphic mode. + */ + sisAvoidImageBLT = TRUE; + + break; + } + vgaSetScreenInitHook(SISScrnInit); + } + } + } +} + +/* + * SISEnterLeave -- + * enable/disable io-mapping + */ +static void +SISEnterLeave(enter) + Bool enter; +{ + unsigned char temp; +#ifdef DEBUG + ErrorF("SISEnterLeave("); + if (enter) + ErrorF("Enter)\n"); + else + ErrorF("Leave)\n"); +#endif + + if (vgaBitsPerPixel >= 8) { +#ifdef XFreeXDGA + if (vga256InfoRec.directMode & XF86DGADirectGraphics && !enter) + if (OFLG_ISSET(OPTION_HW_CURSOR, &vga256InfoRec.options)) + SISHideCursor(); +#endif + } + + if (enter) + { + xf86EnableIOPorts(vga256InfoRec.scrnIndex); + vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0; + outb(vgaIOBase + 4, 0x11); temp = inb(vgaIOBase + 5); + outb(vgaIOBase + 5, temp & 0x7F); + + outw(0x3C4, 0x8605); /* Unlock Specials */ + } + else + { + outw(0x3C4, 0x0005); /* Lock Specials */ + + xf86DisableIOPorts(vga256InfoRec.scrnIndex); + } +} + +/* + * SISRestore -- + * restore a video mode + */ +static void +SISRestore(restore) + vgaSISPtr restore; +{ + int i; + +#ifdef DEBUG + ErrorF("SISRestore\n"); +#endif + vgaProtect(TRUE); + + for (i = 5 ; i <= 0x37; i++) { + outb(0x3C4, i); + if (inb(0x3C5) != restore->Port_3C4[i]) + outb(0x3C5,restore->Port_3C4[i]); + } + + /* set the clock */ + if ( ClockProgramable() ) { + if (restore->std.NoClock >= 0) + sisClockLoad(&restore->sisClock); + } + else + outw(0x3C4, ((restore->ClockReg) << 8) | 0x07); + + /* + * Now restore generic VGA Registers + */ + vgaHWRestore((vgaHWPtr)restore); + + outb(0x3C2, restore->ClockReg2); + +#ifdef IO_DEBUG + for (i = 5 ; i <= 0x37; i++) { + outb(0x3C4, i); + ErrorF("XR%X - %X\n", i, inb(0x3C5)); + } +#endif + vgaProtect(FALSE); +} + +/* + * SISSave -- + * save the current video mode + */ +static void * +SISSave(save) + vgaSISPtr save; +{ + int i; +#ifdef DEBUG + ErrorF("SISSave\n"); +#endif + save = (vgaSISPtr)vgaHWSave((vgaHWPtr)save, sizeof(vgaSISRec)); + + for (i = 5 ; i <= 0x37; i++) { + outb(0x3C4, i); + save->Port_3C4[i] = inb(0x3C5) ; +#ifdef IO_DEBUG + ErrorF("XS%X - %X\n", i, inb(0x3C5)); +#endif + } + + save->ClockReg2 = inb(0x3CC); + + /* save clock */ + if ( ClockProgramable() ) + sisClockSave(&save->sisClock); + + return ((void *) save); +} + +/* + * In graphic mode: data ---------> to selector switch + * + * Now, let's look at the selector switch + * + * FIFO + * MCLK ________________ VCLK + * cpu/engine <---o o-------->|________________|---------> CRT + * ^ ^ ^ ^ + * \ / | | + * \ / | | + * \ / | | + * selector switch Threshold low Threshold high + * + * CRT consumes the data in the fifo. When data in FIFO reaches the + * level of threshold low, the selector will switch to right so that the + * FIFO can be filled by data. When the data in FIFO reaches the threshold + * high level, the selector will switch back to left. + * The threshold low must be set to a minimum level or the snow + * phenomenon (flicker noise) will be found on the screen. + * + * The threshold low should increase if bpp increased, cause it means the + * required data for CRT is increased when bpp increased. When the threshold + * low increased, the distance between threshold high and thereshold low + * should not be too near, else it will have the selector switch frequently, + * a bad performance result. + */ +static int +FindCRT_CPUthreshold(dotClock,bpp,thresholdLow,thresholdHigh) +int dotClock ; +int bpp; +int *thresholdLow; +int *thresholdHigh; +{ + /* here is an hack to set the CRT/CPU threshold register. + the value in the three arrays come from Dump Registers in W95 + */ + struct ThresholdREC { + int freq; + int thresholdHigh; + int thresholdLow; + } ; +#if 0 + static struct ThresholdREC threshold8[]={{25250,0x6,0x3},{31500,0x6,0x3}, + {40000,0x7,0x4},{44900,0x7,0x4}, + {56250,0x7,0x4}, + {65500,0x8,0x5},{78750,0x9,0x6}, + {95000,0xa,0x7},{110000,0xd,0xb}, + {135000,0xc,0xa}}; +#else /* adjusted for X11 */ + /* this is the best values I've found. + * there is no glitch but with intensive generation snow still appears + * on screen especially well seen on the tiled root window. + */ + static struct ThresholdREC threshold8[]={{25250,0x6,0x3},{31500,0x6,0x3}, + {40000,0x7,0x4},{44900,0x7,0x4}, + {56250,0x9,0x5}, + {65000,0xe,0x5},/* ??? */ + {78750,0xd,0x6},{85000,0xd,0x6}, + {95000,0xb,0x7},{110000,0xc,0xa}, + {135000,0xc,0xa}}; +#endif +#if 0 + static struct ThresholdREC threshold16[]={{25250,0x8,0x5},{31500,0x8,0x5}, + {40000,0xa,0x7},{44900,0xa,0x7}, + {56250,0xb,0x8}, + {65500,0xc,0xa},{78750,0xe,0xc}, + {95000,0xf,0xd}}; +#else + static struct ThresholdREC threshold16[]={{25250,0x8,0x5},{31500,0x8,0x5}, + {40000,0xa,0x7},{44900,0xa,0x7}, + {56250,0xf,0x7}, + {65000,0xf,0x7},{78750,0xf,0x8}, + {95000,0xf,0xd}}; +#endif + static struct ThresholdREC threshold24[]={{25250,0xa,0x7},{31500,0xa,0x7}, + {40000,0xc,0x9},{56250,0xe,0xc}}; + + int nfreq ; + int i; + struct ThresholdREC *thresholdTab; + + switch ( bpp ) { + case 8: + thresholdTab = threshold8 ; + nfreq = sizeof(threshold8)/sizeof(struct ThresholdREC); + break; + case 16: + thresholdTab = threshold16 ; + nfreq = sizeof(threshold16)/sizeof(struct ThresholdREC); + break; + case 24: + thresholdTab = threshold24 ; + nfreq = sizeof(threshold24)/sizeof(struct ThresholdREC); + break; + default: + thresholdTab = threshold8 ; + nfreq = sizeof(threshold8)/sizeof(struct ThresholdREC); + } + + for ( i = 0 ; i < nfreq ; i++ ) + if ( thresholdTab[i].freq >= dotClock ) break ; + if ( i == 0 ) { + *thresholdLow = thresholdTab[0].thresholdLow ; + *thresholdHigh = thresholdTab[0].thresholdHigh ; + return ; + } + if ( i == nfreq ) { /* nothing found */ + *thresholdLow = thresholdTab[nfreq -1].thresholdLow ; + *thresholdHigh = thresholdTab[nfreq -1].thresholdHigh ; + } + else { + *thresholdLow = thresholdTab[i-1].thresholdLow + + ((thresholdTab[i].thresholdLow - thresholdTab[i-1].thresholdLow) * + (dotClock - thresholdTab[i-1].freq)) / + ( thresholdTab[i].freq - thresholdTab[i-1].freq) ; + *thresholdHigh = thresholdTab[i-1].thresholdHigh + + ((thresholdTab[i].thresholdHigh - thresholdTab[i-1].thresholdHigh)* + (dotClock - thresholdTab[i-1].freq)) / + ( thresholdTab[i].freq - thresholdTab[i-1].freq) ; + } + +#ifdef DEBUG + ErrorF("FindCRT_CPUthreshold(%d, %d) = 0x%x 0x%x\n", dotClock, bpp, + *thresholdLow,*thresholdHigh); +#endif + +} + + +/* + * SISInit -- + * Handle the initialization, etc. of a screen. + */ +static Bool +SISInit(mode) + DisplayModePtr mode; +{ + unsigned char temp; + int offset; + int i; + unsigned int CRT_CPUthresholdLow ; + unsigned int CRT_CPUthresholdHigh ; + unsigned char CRT_ENGthreshold ; +#ifdef DEBUG + ErrorF("SISInit\n"); +#endif + + /* + * Initialize generic VGA registers. + */ + vgaHWInit(mode, sizeof(vgaSISRec)); + + /* get SIS Specific Registers */ + for (i = 5 ; i <= 0x37; i++) { + outb(0x3C4, i); + new->Port_3C4[i] = inb(0x3C5); + } + + if (vgaBitsPerPixel < 8) { + offset = vga256InfoRec.displayWidth >> + (mode->Flags & V_INTERLACE ? 3 : 4); + } + else + { + offset = vga256InfoRec.displayWidth >> + (mode->Flags & V_INTERLACE ? 2 : 3); + + new->std.Attribute[16] = 0x01; + new->std.CRTC[20] = 0x40; + new->std.CRTC[23] = 0xA3; + } + + if (vgaBitsPerPixel >= 8) { + /* some generic settings */ + new->std.Attribute[0x10] = 0x01; /* mode */ + new->std.Attribute[0x11] = 0x00; /* overscan (border) color */ + new->std.Attribute[0x12] = 0x0F; /* enable all color planes */ + new->std.Attribute[0x13] = 0x00; /* horiz pixel panning 0 */ + + if ( (vgaBitsPerPixel == 16) || (vgaBitsPerPixel == 24) ) + new->std.Graphics[0x05] = 0x00; /* normal read/write mode */ + + if (vgaBitsPerPixel == 16) { + offset <<= 1; /* double the width of the buffer */ + } else if (vgaBitsPerPixel == 24) { + offset += offset << 1; + } + + new->BankReg = 0x02; + new->DualBanks = 0x00; + + if ( sisUseLinear ) { + new->BankReg |= 0x80; /* enable linear mode addressing */ + new->LinearAddr0 = (SIS.ChipLinearBase & 0x07f80000) >> 19 ; + new->LinearAddr1 = ((SIS.ChipLinearBase & 0xf8000000) >> 27) | + (0x60) ; /* Enable Linear with max 4 mb*/ + } + else + new->DualBanks |= 0x08; + + if (vgaBitsPerPixel == 16) + if (xf86weight.green == 5) + new->BankReg |= 0x04; /* 16bpp = 5-5-5 */ + else + new->BankReg |= 0x08; /* 16bpp = 5-6-5 */ + + if (vgaBitsPerPixel == 24) { + new->BankReg |= 0x10; + new->DualBanks |= 0x80; + } + + new->std.CRTC[0x13] = offset & 0xFF; + new->CRTCOff = ((offset & 0xF00) >> 4) | + (((mode->CrtcVTotal-2) & 0x400) >> 10 ) | + (((mode->CrtcVDisplay-1) & 0x400) >> 9 ) | + ((mode->CrtcVSyncStart & 0x400) >> 8 ) | + (((mode->CrtcVSyncStart) & 0x400) >> 7 ) ; + + if (mode->Flags & V_INTERLACE) + new->BankReg |= 0x20; + + + if ( ClockProgramable() ){ + /* init clock */ + if (!sisClockFind(new->std.NoClock, &new->sisClock)) { + ErrorF("Can't find desired clock\n"); + return (FALSE); + } + } + + if (new->std.NoClock >= 0) { + new->ClockReg = new->std.NoClock; /* not used in programmable */ + new->ClockReg2 = inb(0x3CC) | 0x0C; /* set internal/external clk */ + } + + /* + * this is function of the bandwidth + * (pixelsize, displaysize, dotclock) + * worst case is not optimal + */ + CRT_ENGthreshold = 0x0f ; + FindCRT_CPUthreshold(vga256InfoRec.clock[new->std.NoClock], + vgaBitsPerPixel, + &CRT_CPUthresholdLow, &CRT_CPUthresholdHigh); + new->Port_3C4[0x08] = (CRT_ENGthreshold & 0x0F) | + (CRT_CPUthresholdLow & 0x0F)<<4 ; + new->Port_3C4[0x09] = (CRT_CPUthresholdHigh & 0x0F) ; +#if 0 + /* Graphics Modes seem to need a Higher MClk, than at Console + * Force a higher Mclk for now */ + if ( SISchipset == SIS86C205 ) { + /* 80 MHz MCLK */ + /*new->Port_3C4[0x28] = 0xCF ; + new->Port_3C4[0x29] = 0x9C ;*/ + /* 70 MHz MCLK */ + new->Port_3C4[0x28] = 0xC1 ; + new->Port_3C4[0x29] = 0x1A ; + /* 60 MHz MCLK */ + /*new->Port_3C4[0x28] = 0x57 ; + new->Port_3C4[0x29] = 0x14 ;*/ + /* 45 MHz MCLK */ + /*new->Port_3C4[0x28] = 0x15 ; + new->Port_3C4[0x29] = 0x06 ;*/ + } +#endif + + new->Port_3C4[0x27] |= 0x30 ; /* invalid logical screen width */ + + if ( sisUseMMIO ) { + new->Port_3C4[0x27] |= 0x40 ; /* enable Graphic Engine Prog */ + if ( !sisMMIOBase ) + sisMMIOBase = (unsigned char *)vgaBase ; + switch ( PCIMMIOBase ) { + case 0xA0000: + new->Port_3C4[0x0B] |= 0x20 ; /* enable MMIO at 0xAxxxx */ + break; + case 0xB0000: + new->Port_3C4[0x0B] |= 0x40 ; /* enable MMIO at 0xBxxxx*/ + break; + default: + new->Port_3C4[0x0B] |= 0x60 ; /* enable MMIO at PCI reg */ + } + new->Port_3C4[0x0C] |= 0x80 ; /* 64-bit mode */ + /* + * Setup the address to write monochrome source data to, for + * system to the screen colour expansion. + */ + sisBltDataWindow = vgaLinearBase ; + } + } else { + if (new->std.NoClock >= 0) { + new->ClockReg = new->std.NoClock; + temp = inb(0x3CC) & ~0x0C ; + new->ClockReg2 = temp | ( (new->ClockReg<<2) & 0x0C) ; + } + + } + return(TRUE); +} + +/* + * SISAdjust -- + * adjust the current video frame to display the mousecursor + */ + +static void +SISAdjust(x, y) + int x, y; +{ + unsigned char temp; + int base; + + if (vgaBitsPerPixel < 8) { + base = (y * vga256InfoRec.displayWidth + x + 3) >> 3; + } else { + base = y * vga256InfoRec.displayWidth + x ; + /* calculate base bpp dep. */ + switch (vgaBitsPerPixel) { + case 16: + base >>= 1; + break; + case 24: + base = ((base * 3)) >> 2; + base -= base % 6; + break; + default: /* 8bpp */ + base >>= 2; + break; + } + } + + outw(vgaIOBase + 4, (base & 0x00FF00) | 0x0C); + outw(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D); + + outb(0x3C4, 0x27); temp = inb(0x3C5) & 0xF0; + temp |= (base & 0x0F0000) >> 16; + outb(0x3C5, temp); + +#ifdef XFreeXDGA + if (vga256InfoRec.directMode & XF86DGADirectGraphics) { + /* Wait until vertical retrace is in progress. */ + while (inb(vgaIOBase + 0xA) & 0x08); + while (!(inb(vgaIOBase + 0xA) & 0x08)); + } +#endif +} + +/* + * SISValidMode -- + * + */ +static int +SISValidMode(mode, verbose,flag) +DisplayModePtr mode; +Bool verbose; +int flag; +{ + return MODE_OK; +} + +/* + * MGADisplayPowerManagementSet -- + * + * Sets VESA Display Power Management Signaling (DPMS) Mode. + */ +#ifdef DPMSExtension +static void SISDisplayPowerManagementSet(PowerManagementMode) +int PowerManagementMode; +{ + unsigned char extDDC_PCR; + unsigned char crtc17; + unsigned char seq1; + +#ifdef DEBUG + ErrorF("SISDisplayPowerManagementSet(%d)\n",PowerManagementMode); +#endif + if (!xf86VTSema) return; + outb(vgaIOBase + 4, 0x17); + crtc17 = inb(vgaIOBase + 5); + outb(0x3C4, 0x11); + extDDC_PCR = inb(0x3C5) & ~0xC0; + switch (PowerManagementMode) + { + case DPMSModeOn: + /* HSync: On, VSync: On */ + seq1 = 0x00 ; + crtc17 |= 0x80; + break; + case DPMSModeStandby: + /* HSync: Off, VSync: On */ + seq1 = 0x20 ; + extDDC_PCR |= 0x40; + break; + case DPMSModeSuspend: + /* HSync: On, VSync: Off */ + seq1 = 0x20 ; + extDDC_PCR |= 0x80; + break; + case DPMSModeOff: + /* HSync: Off, VSync: Off */ + seq1 = 0x20 ; + extDDC_PCR |= 0xC0; + /* DPMSModeOff is not supported with ModeStandby | ModeSuspend */ + /* need same as the generic VGA function */ + crtc17 &= ~0x80; + break; + } + outw(0x3C4, 0x0100); /* Synchronous Reset */ + outb(0x3C4, 0x01); /* Select SEQ1 */ + seq1 |= inb(0x3C5) & ~0x20; + outb(0x3C5, seq1); + usleep(10000); + outb(vgaIOBase + 4, 0x17); + outb(vgaIOBase + 5, crtc17); + outb(0x3C4, 0x11); + outb(0x3C5, extDDC_PCR); + outw(0x3C4, 0x0300); /* End Reset */ +} +#endif + + + + + + + + + + diff --git a/programs/Xserver/hw/xfree86/olddrivers/sis/sis_driver.h b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_driver.h new file mode 100644 index 000000000..101943ed8 --- /dev/null +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_driver.h @@ -0,0 +1,105 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h,v 1.2 1998/01/24 16:58:22 hohndel Exp $ */ + +/* + * + * 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 the authors not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHORS 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. + * + * Modified for Sis by Xavier Ducoin (xavier@rd.lectra.fr) + * + */ + + +/*#define DEBUG*/ + +#include "xf86_ansic.h" + +#define SIS86C201 0 +#define SIS86C202 1 +#define SIS86C205 2 + +extern int SISchipset; + +extern Bool sisLinearSupport; /*linear addressing enable */ + +extern Bool sisUseMMIO; +extern unsigned char *sisMMIOBase; +extern unsigned int sisBLTPatternAddress; +extern int sisBLTPatternOffscreenSize; +extern Bool sisAvoidImageBLT; +extern unsigned char *sisBltDataWindow; + +extern Bool sisHWCursor; + +extern int sisAluConv[]; /* Map Alu to SIS ROP source data */ + +/* + * Definitions for IO access to 32 bit ports + */ +extern int sisReg32MMIO[]; +#define BR(x) sisReg32MMIO[x] + + +/* + * Forward definitions for the functions that make up the driver. See + * the definitions of these functions for the real scoop. + */ + +/* in sis_blitter.c */ +extern void sisBitBlt(); +extern void sisMMIOBitBlt(); + +/* in sis_BitBlt.c */ +extern void siscfbDoBitbltCopy(); +extern void siscfbFillBoxSolid(); + +/* in sis_solid.c */ +extern void siscfbFillRectSolid(); +extern void siscfbFillSolidSpansGeneral(); +extern void sisMMIOFillRectSolid(); +extern void sisMMIOFillSolidSpansGeneral(); + +/* in sis_blt16.c */ +extern RegionPtr siscfb16CopyArea(); +extern RegionPtr siscfb24CopyArea(); +extern void siscfbCopyWindow(); + +/* in sis_line.c */ +extern void sisMMIOLineSS(); +extern void sisMMIOSegmentSS(); + +/* in sis_pntwin.c */ +extern void sisPaintWindow(); + +/* in sis_FillRct.c */ +extern void siscfbPolyFillRect(); + +/* in ct_FillSt.c */ +extern void siscfbFillRectOpaqueStippled32(); +extern void siscfbFillRectTransparentStippled32(); +extern void sisMMIOFillRectOpaqueStippled32(); +extern void sisMMIOFillRectTransparentStippled32(); + +/* in sis_teblt8.c */ +extern void sisMMIOImageGlyphBlt(); +extern void sisMMIOPolyGlyphBlt(); + + + + + diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_pntwin.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_pntwin.c index efaee8bf1..68c96fcad 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_pntwin.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_pntwin.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/sis/sis_pntwin.c,v 1.1 1997/01/12 10:43:10 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_pntwin.c,v 1.1 1997/03/06 23:16:56 hohndel Exp $ */ diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_solid.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_solid.c index 79b38acb7..e44877d5a 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_solid.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_solid.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_solid.c,v 1.2 1998/01/24 16:58:23 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_solid.c,v 1.3 1998/03/20 21:06:57 hohndel Exp $ */ /* * diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_teblt8.c b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_teblt8.c index 311fbe52a..98ccc6ed1 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_teblt8.c +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_teblt8.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_teblt8.c,v 1.1 1997/03/06 23:16:58 hohndel Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_teblt8.c,v 1.2 1998/01/24 16:58:23 hohndel Exp $ */ /* * Copyright (c) 1989 X Consortium diff --git a/programs/Xserver/hw/xfree86/drivers/sis/sis_textblt.s b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_textblt.s index 051816cb4..8ce090ac3 100644 --- a/programs/Xserver/hw/xfree86/drivers/sis/sis_textblt.s +++ b/programs/Xserver/hw/xfree86/olddrivers/sis/sis_textblt.s @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/sis/sis_textblt.s,v 1.2 1997/01/12 10:52:29 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_textblt.s,v 1.1 1997/03/06 23:16:58 hohndel Exp $ */ /* * diff --git a/programs/Xserver/hw/xfree86/parser/Monitor.c b/programs/Xserver/hw/xfree86/parser/Monitor.c index 33c192478..3d230c56c 100644 --- a/programs/Xserver/hw/xfree86/parser/Monitor.c +++ b/programs/Xserver/hw/xfree86/parser/Monitor.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Monitor.c,v 1.2 1998/07/25 16:57:13 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Monitor.c,v 1.3 1998/11/22 10:37:36 dawes Exp $ */ /* * * Copyright (c) 1997 Metro Link Incorporated @@ -86,7 +86,7 @@ parseModeLine (void) parsePrologue (XF86ConfModeLinePtr, XF86ConfModeLineRec) /* Identifier */ - if (xf86GetToken (NULL) != STRING) + if (xf86GetToken (NULL) != STRING) Error ("ModeLine identifier expected", NULL); ptr->ml_identifier = val.str; @@ -320,15 +320,20 @@ parseVerboseMode (void) break; case HSKEW: if (xf86GetToken (NULL) != NUMBER) - xf86ParseError ("Horizontal skew expected"); + Error ("Horizontal skew expected", NULL); ptr->ml_flags |= XF86CONF_HSKEW; ptr->ml_hskew = val.num; break; case VSCAN: if (xf86GetToken (NULL) != NUMBER) - xf86ParseError ("Vertical scan count expected"); + Error ("Vertical scan count expected", NULL); ptr->ml_vscan = val.num; break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error ("Unexepcted token in verbose \"Mode\" entry\n", NULL); } } if (!had_dotclock) diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/Imakefile b/programs/Xserver/hw/xfree86/xf24_32bpp/Imakefile new file mode 100644 index 000000000..8ef4b3837 --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/Imakefile @@ -0,0 +1,39 @@ +XCOMM $XFree86$ +#define IHaveModules +#include <Server.tmpl> + + +#if DoLoadableServer +XFMODSRC = cfb24_32module.c +XFMODOBJ = cfb24_32module.o +#endif + +SRCS = cfbbstore.c cfbcpyarea.c cfbgcmisc.c cfbpixmap.c \ + cfbimage.c cfbscrinit.c cfbwindow.c \ + $(XFMODSRC) cfbgc24.c cfbgc32.c + + +OBJS = cfbbstore.o cfbcpyarea.o cfbgcmisc.o cfbpixmap.o \ + cfbimage.o cfbscrinit.o cfbwindow.o \ + $(XFMODOBJ) cfbgc24.o cfbgc32.o + +INCLUDES = -I. -I$(XF86SRC)/xf1bpp -I$(SERVERSRC)/mfb \ + -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \ + -I$(XF86OSSRC) -I$(XF86COMSRC) \ + -I$(FONTINCSRC) -I$(XINCLUDESRC) + + +ModuleObjectRule() +LibraryModuleTarget(xf24_32bpp,$(OBJS)) +LintLibraryTarget(xf24_32bpp,$(SRCS)) +NormalLintTarget($(LINTDEFS) $(SRCS)) + +ObjectFromSpecialSource(cfbgc24,cfbgc,-DPSZ=24) +ObjectFromSpecialSource(cfbgc32,cfbgc,-DPSZ=32) + + +InstallLibraryModule(xf24_32bpp,$(MODULEDIR),.) +InstallLinkKitLibrary(xf24_32bpp,$(LINKKITDIR)/lib) +InstallLinkKitNonExecFile(cfb24_32.h,$(LINKKITDIR)/include) + +DependTarget() diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32.h b/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32.h new file mode 100644 index 000000000..3752b60f1 --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32.h @@ -0,0 +1,172 @@ +/* $XFree86$ */ + +#ifndef _CFB24_32_H +#define _CFB24_32_H + +#include "gcstruct.h" + +typedef struct { + GCOps *Ops24bpp; + GCOps *Ops32bpp; + unsigned long changes; + Bool OpsAre24bpp; +} cfb24_32GCRec, *cfb24_32GCPtr; + + +extern int cfb24_32GCIndex; +extern int cfb24_32PixmapIndex; + +typedef struct { + PixmapPtr pix; + Bool freePrivate; +} cfb24_32PixmapRec, *cfb24_32PixmapPtr; + + +void +cfb24_32SaveAreas( + PixmapPtr pPixmap, + RegionPtr prgnSave, + int xorg, + int yorg, + WindowPtr pWin +); + +void +cfb24_32RestoreAreas( + PixmapPtr pPixmap, + RegionPtr prgnRestore, + int xorg, + int yorg, + WindowPtr pWin +); + +RegionPtr +cfb24_32CopyArea( + DrawablePtr pSrcDraw, + DrawablePtr pDstDraw, + GC *pGC, + int srcx, int srcy, + int width, int height, + int dstx, int dsty +); + +void +cfbDoBitblt24To32( + DrawablePtr pSrc, + DrawablePtr pDst, + int rop, + RegionPtr prgnDst, + DDXPointPtr pptSrc, + unsigned long planemask, + unsigned long bitPlane +); + +void +cfbDoBitblt32To24( + DrawablePtr pSrc, + DrawablePtr pDst, + int rop, + RegionPtr prgnDst, + DDXPointPtr pptSrc, + unsigned long planemask, + unsigned long bitPlane +); + + +void +cfb24_32ValidateGC24( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDrawable +); + +void +cfb24_32ValidateGC32( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDrawable +); + +Bool cfb24_32CreateGC(GCPtr pGC); + +void +cfb24_32GetSpans( + DrawablePtr pDraw, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pchardstStart +); + +void +cfb24_32PutImage ( + DrawablePtr pDraw, + GCPtr pGC, + int depth, + int x, int y, int w, int h, + int leftPad, + int format, + char *pImage +); + +void +cfb24_32GetImage ( + DrawablePtr pDraw, + int sx, int sy, int w, int h, + unsigned int format, + unsigned long planeMask, + char *pdstLine +); + +Bool +cfb24_32ScreenInit ( + ScreenPtr pScreen, + pointer pbits, + int xsize, int ysize, + int dpix, int dpiy, + int width +); + + +Bool cfb24_32CreateWindow(WindowPtr pWin); +Bool cfb24_32DestroyWindow(WindowPtr pWin); + +Bool +cfb24_32PositionWindow( + WindowPtr pWin, + int x, int y +); + +void +cfb24_32CopyWindow( + WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc +); + +Bool +cfb24_32ChangeWindowAttributes( + WindowPtr pWin, + unsigned long mask +); + +PixmapPtr +cfb24_32CreatePixmap ( + ScreenPtr pScreen, + int width, + int height, + int depth +); + +Bool cfb24_32DestroyPixmap(PixmapPtr pPixmap); + +PixmapPtr cfb24_32RefreshPixmap(PixmapPtr pix); + +#define CFB24_32_GET_GC_PRIVATE(pGC)\ + (cfb24_32GCPtr)((pGC)->devPrivates[cfb24_32GCIndex].ptr) + +#define CFB24_32_GET_PIXMAP_PRIVATE(pPix) \ + (cfb24_32PixmapPtr)((pPix)->devPrivates[cfb24_32PixmapIndex].ptr) + +#endif /* _CFB24_32_H */ diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32module.c b/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32module.c new file mode 100644 index 000000000..27dbfd696 --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32module.c @@ -0,0 +1,45 @@ +/* $XFree86$ */ + +#ifdef XFree86LOADER + +#include "xf86Module.h" + +MODULEINITPROTO(xf24_32bppModuleInit); +static MODULESETUPPROTO(xf24_32bppSetup); + +static XF86ModuleVersionInfo VersRec = +{ + "xf24_32bpp", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + 1, 0, 0, + ABI_CLASS_ANSIC, /* Only need the ansic layer */ + ABI_ANSIC_VERSION, + NULL, + {0,0,0,0} /* signature, to be patched into the file by a tool */ +}; + +void +xf24_32bppModuleInit(XF86ModuleVersionInfo **vers, ModuleSetupProc *setup, + ModuleTearDownProc *teardown) +{ + *vers = &VersRec; + *setup = xf24_32bppSetup; + *teardown = NULL; +} + +static pointer +xf24_32bppSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + if (!LoadSubModule(module, "cfb24", NULL, NULL, NULL, NULL, NULL, + errmaj, errmin)) + return NULL; + if (!LoadSubModule(module, "cfb32", NULL, NULL, NULL, NULL, NULL, + errmaj, errmin)) + return NULL; + return (pointer)1; /* non-NULL required to indicate success */ +} + +#endif diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfbbstore.c b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbbstore.c new file mode 100644 index 000000000..9fb61f40f --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbbstore.c @@ -0,0 +1,89 @@ +/* $XFree86$ */ + +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#include "X.h" +#include "mibstore.h" +#include "regionstr.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "windowstr.h" + +void +cfb24_32SaveAreas( + PixmapPtr pPixmap, + RegionPtr prgnSave, + int xorg, + int yorg, + WindowPtr pWin +){ + DDXPointPtr pPt; + DDXPointPtr pPtsInit; + BoxPtr pBox; + ScreenPtr pScreen = pPixmap->drawable.pScreen; + PixmapPtr pScrPix; + int i = REGION_NUM_RECTS(prgnSave); + + + pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec)); + if (!pPtsInit) + return; + + pBox = REGION_RECTS(prgnSave); + pPt = pPtsInit; + while (--i >= 0) { + pPt->x = pBox->x1 + xorg; + pPt->y = pBox->y1 + yorg; + pPt++; + pBox++; + } + + pScrPix = (PixmapPtr) pScreen->devPrivate; + + cfbDoBitblt24To32((DrawablePtr) pScrPix, (DrawablePtr)pPixmap, + GXcopy, prgnSave, pPtsInit, ~0L, 0); + + DEALLOCATE_LOCAL (pPtsInit); +} + + +void +cfb24_32RestoreAreas( + PixmapPtr pPixmap, + RegionPtr prgnRestore, + int xorg, + int yorg, + WindowPtr pWin +){ + DDXPointPtr pPt; + DDXPointPtr pPtsInit; + BoxPtr pBox; + int i; + ScreenPtr pScreen = pPixmap->drawable.pScreen; + PixmapPtr pScrPix; + + i = REGION_NUM_RECTS(prgnRestore); + pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i*sizeof(DDXPointRec)); + if (!pPtsInit) + return; + + pBox = REGION_RECTS(prgnRestore); + pPt = pPtsInit; + while (--i >= 0) { + pPt->x = pBox->x1 - xorg; + pPt->y = pBox->y1 - yorg; + pPt++; + pBox++; + } + + pScrPix = (PixmapPtr) pScreen->devPrivate; + + cfbDoBitblt32To24((DrawablePtr)pPixmap, (DrawablePtr) pScrPix, + GXcopy, prgnRestore, pPtsInit, ~0L, 0); + + DEALLOCATE_LOCAL (pPtsInit); +} diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfbcpyarea.c b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbcpyarea.c new file mode 100644 index 000000000..271367f81 --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbcpyarea.c @@ -0,0 +1,540 @@ +/* $XFree86$ */ + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "resource.h" +#include "colormap.h" +#include "colormapst.h" +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#include "mi.h" +#include "mistruct.h" +#include "dix.h" +#include "mibstore.h" + + +RegionPtr +cfb24_32CopyArea( + DrawablePtr pSrcDraw, + DrawablePtr pDstDraw, + GC *pGC, + int srcx, int srcy, + int width, int height, + int dstx, int dsty +){ + + if(pSrcDraw->bitsPerPixel == 32) { + if(pDstDraw->bitsPerPixel == 32) { + return(cfb32CopyArea(pSrcDraw, pDstDraw, pGC, srcx, srcy, + width, height, dstx, dsty)); + } else { + /* have to translate 32 -> 24 copies */ + return cfb32BitBlt (pSrcDraw, pDstDraw, + pGC, srcx, srcy, width, height, dstx, dsty, + cfbDoBitblt32To24, 0L); + } + } else { + if(pDstDraw->bitsPerPixel == 32) { + /* have to translate 24 -> 32 copies */ + return cfb32BitBlt (pSrcDraw, pDstDraw, + pGC, srcx, srcy, width, height, dstx, dsty, + cfbDoBitblt24To32, 0L); + } else { + return(cfb24CopyArea(pSrcDraw, pDstDraw, pGC, srcx, srcy, + width, height, dstx, dsty)); + } + } +} + + + +/* This is probably the slowest way to transfer data across the + bus - a byte at a time. This is temporary until somebody wants + to optimize it */ + + +void +cfbDoBitblt24To32( + DrawablePtr pSrc, + DrawablePtr pDst, + int rop, + RegionPtr prgnDst, + DDXPointPtr pptSrc, + unsigned long planemask, + unsigned long bitPlane +){ + BoxPtr pbox = REGION_RECTS(prgnDst); + int nbox = REGION_NUM_RECTS(prgnDst); + unsigned char *ptr24, *ptr32; + unsigned char *data24, *data32; + int pitch24, pitch32; + int height, width, i, j; + unsigned char *pm; + + cfbGetByteWidthAndPointer(pSrc, pitch24, ptr24); + cfbGetByteWidthAndPointer(pDst, pitch32, ptr32); + + planemask &= 0x00ffffff; + pm = (unsigned char*)(&planemask); + + if((planemask == 0x00ffffff) && (rop == GXcopy)) { + for(;nbox; pbox++, pptSrc++, nbox--) { + data24 = ptr24 + (pptSrc->y * pitch24) + (pptSrc->x * 3); + data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2); + width = (pbox->x2 - pbox->x1) << 2; + height = pbox->y2 - pbox->y1; + + while(height--) { + for(i = j = 0; i < width; i += 4, j += 3) { + data32[i] = data24[j]; + data32[i + 1] = data24[j + 1]; + data32[i + 2] = data24[j + 2]; + } + data24 += pitch24; + data32 += pitch32; + } + } + } else { /* it ain't pretty, but hey */ + register unsigned char tmp; + for(;nbox; pbox++, pptSrc++, nbox--) { + data24 = ptr24 + (pptSrc->y * pitch24) + (pptSrc->x * 3); + data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2); + width = (pbox->x2 - pbox->x1) << 2; + height = pbox->y2 - pbox->y1; + + /* Some of these can probably be reduced more */ + + while(height--) { + switch(rop) { + case GXcopy: + for(i = j = 0; i < width; i += 4, j += 3) { + data32[i] = (data24[j] & pm[0]) | (data32[i] & ~pm[0]); + data32[i+1] = (data24[j+1] & pm[1]) | + (data32[i+1] & ~pm[1]); + data32[i+2] = (data24[j+2] & pm[2]) | + (data32[i+2] & ~pm[2]); + } + break; + case GXor: + for(i = j = 0; i < width; i += 4, j += 3) { + data32[i] |= data24[j] & pm[0]; + data32[i+1] |= data24[j+1] & pm[1]; + data32[i+2] |= data24[j+2] & pm[2]; + } + break; + case GXclear: + for(i = 0; i < width; i += 4) { + data32[i] &= ~pm[0]; + data32[i+1] &= ~pm[1]; + data32[i+2] &= ~pm[2]; + } + break; + case GXand: + for(i = j = 0; i < width; i += 4, j += 3) { + data32[i] &= data24[j] | ~pm[0]; + data32[i+1] &= data24[j+1] | ~pm[1]; + data32[i+2] &= data24[j+2] | ~pm[2]; + } + break; + case GXandReverse: + for(i = j = 0; i < width; i += 4, j += 3) { + tmp = data32[i]; + data32[i] = ((~tmp & data24[j]) & pm[0]) | + (tmp & ~pm[0]); + tmp = data32[i+1]; + data32[i+1] = ((~tmp & data24[j+1]) & pm[1]) | + (tmp & ~pm[1]); + tmp = data32[i+2]; + data32[i+2] = ((~tmp & data24[j+2]) & pm[2]) | + (tmp & ~pm[2]); + } + break; + case GXandInverted: + for(i = j = 0; i < width; i += 4, j += 3) { + tmp = data32[i]; + data32[i] = (tmp & ~data24[j] & pm[0]) | (tmp & ~pm[0]); + tmp = data32[i+1]; + data32[i+1] = (tmp & ~data24[j+1] & pm[1]) | + (tmp & ~pm[1]); + tmp = data32[i+2]; + data32[i+2] = (tmp & ~data24[j+2] & pm[2]) | + (tmp & ~pm[2]); + } + break; + case GXnoop: + return; + case GXxor: + for(i = j = 0; i < width; i += 4, j += 3) { + tmp = data32[i]; + data32[i] = ((tmp ^ data24[j]) & pm[0]) | + (tmp & ~pm[0]); + tmp = data32[i+1]; + data32[i+1] = ((tmp ^ data24[j+1]) & pm[1]) | + (tmp & ~pm[1]); + tmp = data32[i+2]; + data32[i+2] = ((tmp ^ data24[j+2]) & pm[2]) | + (tmp & ~pm[2]); + } + break; + case GXnor: + for(i = j = 0; i < width; i += 4, j += 3) { + tmp = data32[i]; + data32[i] = (~(tmp | data24[j]) & pm[0]) | + (tmp & ~pm[0]); + tmp = data32[i+1]; + data32[i+1] = (~(tmp | data24[j+1]) & pm[1]) | + (tmp & ~pm[1]); + tmp = data32[i+2]; + data32[i+2] = (~(tmp | data24[j+2]) & pm[2]) | + (tmp & ~pm[2]); + } + break; + case GXequiv: + for(i = j = 0; i < width; i += 4, j += 3) { + tmp = data32[i]; + data32[i] = ((tmp ^ ~data24[j]) & pm[0]) | + (tmp & ~pm[0]); + tmp = data32[i+1]; + data32[i+1] = ((tmp ^ ~data24[j+1]) & pm[1]) | + (tmp & ~pm[1]); + tmp = data32[i+2]; + data32[i+2] = ((tmp ^ ~data24[j+2]) & pm[2]) | + (tmp & ~pm[2]); + } + break; + case GXinvert: + for(i = 0; i < width; i += 4) { + data32[i] ^= pm[0]; + data32[i+1] ^= pm[1]; + data32[i+2] ^= pm[2]; + } + break; + case GXorReverse: + for(i = j = 0; i < width; i += 4, j += 3) { + tmp = data32[i]; + data32[i] = ((~tmp | data24[j]) & pm[0]) | + (tmp & ~pm[0]); + tmp = data32[i+1]; + data32[i+1] = ((~tmp | data24[j+1]) & pm[1]) | + (tmp & ~pm[1]); + tmp = data32[i+2]; + data32[i+2] = ((~tmp | data24[j+2]) & pm[2]) | + (tmp & ~pm[2]); + } + break; + case GXcopyInverted: + for(i = j = 0; i < width; i += 4, j += 3) { + data32[i] = (~data24[j] & pm[0]) | (data32[i] & ~pm[0]); + data32[i+1] = (~data24[j+1] & pm[1]) | + (data32[i+1] & ~pm[1]); + data32[i+2] = (~data24[j+2] & pm[2]) | + (data32[i+2] & ~pm[2]); + } + break; + case GXorInverted: + for(i = j = 0; i < width; i += 4, j += 3) { + tmp = data32[i]; + data32[i] = ((tmp | ~data24[j]) & pm[0]) | + (tmp & ~pm[0]); + tmp = data32[i+1]; + data32[i+1] = ((tmp | ~data24[j+1]) & pm[1]) | + (tmp & ~pm[1]); + tmp = data32[i+2]; + data32[i+2] = ((tmp | ~data24[j+2]) & pm[2]) | + (tmp & ~pm[2]); + } + break; + case GXnand: + for(i = j = 0; i < width; i += 4, j += 3) { + tmp = data32[i]; + data32[i] = (~(tmp & data24[j]) & pm[0]) | + (tmp & ~pm[0]); + tmp = data32[i+1]; + data32[i+1] = (~(tmp & data24[j+1]) & pm[1]) | + (tmp & ~pm[1]); + tmp = data32[i+2]; + data32[i+2] = (~(tmp & data24[j+2]) & pm[2]) | + (tmp & ~pm[2]); + } + break; + case GXset: + for(i = 0; i < width; i+=4) { + data32[i] |= pm[0]; + data32[i+1] |= pm[1]; + data32[i+2] |= pm[2]; + } + break; + } + data24 += pitch24; + data32 += pitch32; + } + } + } +} + + +void +cfbDoBitblt32To24( + DrawablePtr pSrc, + DrawablePtr pDst, + int rop, + RegionPtr prgnDst, + DDXPointPtr pptSrc, + unsigned long planemask, + unsigned long bitPlane +){ + BoxPtr pbox = REGION_RECTS(prgnDst); + int nbox = REGION_NUM_RECTS(prgnDst); + unsigned char *ptr24, *ptr32; + unsigned char *data24, *data32; + int pitch24, pitch32; + int height, width, i, j; + unsigned char *pm; + + cfbGetByteWidthAndPointer(pDst, pitch24, ptr24); + cfbGetByteWidthAndPointer(pSrc, pitch32, ptr32); + + planemask &= 0x00ffffff; + pm = (unsigned char*)(&planemask); + + if((planemask == 0x00ffffff) && (rop == GXcopy)) { + CARD32 *src; + CARD8 *dst; + long phase; + for(;nbox; pbox++, pptSrc++, nbox--) { + data24 = ptr24 + (pbox->y1 * pitch24) + (pbox->x1 * 3); + data32 = ptr32 + (pptSrc->y * pitch32) + (pptSrc->x << 2); + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + phase = (long)data32 & 3L; + + while(height--) { + src = (CARD32*)data32; + dst = data24; + j = width; + +#if 1 + /* Why doesn't this help performance on my machine ? */ + switch(phase) { + case 0: break; + case 1: + dst[0] = src[0]; + *((CARD16*)(dst + 1)) = src[0] >> 8; + dst += 3; + src = (CARD32*)(data32 + 3); + j--; + break; + case 2: + if(j == 1) break; + *((CARD16*)dst) = src[0]; + *((CARD32*)dst) = ((src[0] >> 16) & 0x000000ff) | + (src[1] << 8); + dst += 6; + src = (CARD32*)(data32 + 6); + j -= 2; + break; + default: + if(j < 3) break; + dst[0] = src[0]; + *((CARD32*)(dst + 1)) = ((src[0] >> 8) & 0x0000ffff) | + (src[1] << 16); + *((CARD32*)(dst + 5)) = ((src[1] >> 16) & 0x000000ff) | + (src[2] << 8); + dst += 9; + src = (CARD32*)(data32 + 9); + j -= 3; + } +#endif + + while(j >= 4) { + *((CARD32*)dst) = (src[0] & 0x00ffffff) | (src[1] << 24); + *((CARD32*)(dst + 4)) = ((src[1] >> 8) & 0x0000ffff)| + (src[2] << 16); + *((CARD32*)(dst + 8)) = ((src[2] >> 16) & 0x000000ff) | + (src[3] << 8); + dst += 12; + src += 4; + j -= 4; + } + switch(j) { + case 0: + break; + case 1: + *((CARD16*)dst) = src[0]; + dst[2] = src[0] >> 16; + break; + case 2: + *((CARD32*)dst) = (src[0] & 0x00ffffff) | (src[1] << 24); + *((CARD16*)(dst + 4)) = src[1] >> 8; + break; + default: + *((CARD32*)dst) = (src[0] & 0x00ffffff) | (src[1] << 24); + *((CARD32*)(dst + 4)) = ((src[1] >> 8) & 0x0000ffff) | + (src[2] << 16); + dst[8] = src[2] >> 16; + break; + } + + data24 += pitch24; + data32 += pitch32; + } + } + } else { + for(;nbox; pbox++, pptSrc++, nbox--) { + data24 = ptr24 + (pbox->y1 * pitch24) + (pbox->x1 * 3); + data32 = ptr32 + (pptSrc->y * pitch32) + (pptSrc->x << 2); + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + while(height--) { + switch(rop) { + case GXcopy: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] = (data32[i] & pm[0]) | (data24[j] & ~pm[0]); + data24[j+1] = (data32[i+1] & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[j+2] = (data32[i+2] & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXor: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] |= data32[i] & pm[0]; + data24[j+1] |= data32[i+1] & pm[1]; + data24[j+2] |= data32[i+2] & pm[2]; + } + break; + case GXclear: + for(j = 0; j < width; j += 3) { + data24[j] &= ~pm[0]; + data24[j+1] &= ~pm[1]; + data24[j+2] &= ~pm[2]; + } + break; + case GXand: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] &= data32[i] | ~pm[0]; + data24[j+1] &= data32[i+1] | ~pm[1]; + data24[j+2] &= data32[i+2] | ~pm[2]; + } + break; + case GXandReverse: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] = ((data32[i] & ~data24[j]) & pm[0]) | + (data24[j] & ~pm[0]); + data24[j+1] = ((data32[i+1] & ~data24[j+1]) & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[j+2] = ((data32[i+2] & ~data24[j+2]) & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXandInverted: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[i] = (~data32[i] & data24[j] & pm[0]) | + (data24[j] & ~pm[0]); + data24[i+1] = (~data32[i+1] & data24[j+1] & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[i+2] = (~data32[i+2] & data24[j+2] & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXnoop: + return; + case GXxor: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] = ((data32[i] ^ data24[j]) & pm[0]) | + (data24[j] & ~pm[0]); + data24[j+1] = ((data32[i+1] ^ data24[j+1]) & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[j+2] = ((data32[i+2] ^ data24[j+2]) & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXnor: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] = (~(data32[i] | data24[j]) & pm[0]) | + (data24[j] & ~pm[0]); + data24[j+1] = (~(data32[i+1] | data24[j+1]) & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[j+2] = (~(data32[i+2] | data24[j+2]) & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXequiv: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] = ((~data32[i] ^ data24[j]) & pm[0]) | + (data24[j] & ~pm[0]); + data24[j+1] = ((~data32[i+1] ^ data24[j+1]) & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[j+2] = ((~data32[i+2] ^ data24[j+2]) & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXinvert: + for(j = 0; j < width; j+=3) { + data24[j] ^= pm[0]; + data24[j+1] ^= pm[1]; + data24[j+2] ^= pm[2]; + } + break; + case GXorReverse: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] = ((data32[i] | ~data24[j]) & pm[0]) | + (data24[j] & ~pm[0]); + data24[j+1] = ((data32[i+1] | ~data24[j+1]) & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[j+2] = ((data32[i+2] | ~data24[j+2]) & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXcopyInverted: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] = (~data32[i] & pm[0]) | (data24[j] & ~pm[0]); + data24[j+1] = (~data32[i+1] & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[j+2] = (~data32[i+2] & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXorInverted: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] = ((~data32[i] | data24[j]) & pm[0]) | + (data24[j] & ~pm[0]); + data24[j+1] = ((~data32[i+1] | data24[j+1]) & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[j+2] = ((~data32[i+2] | data24[j+2]) & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXnand: + for(i = j = 0; j < width; i += 4, j += 3) { + data24[j] = (~(data32[i] & data24[j]) & pm[0]) | + (data24[j] & ~pm[0]); + data24[j+1] = (~(data32[i+1] & data24[j+1]) & pm[1]) | + (data24[j+1] & ~pm[1]); + data24[j+2] = (~(data32[i+2] & data24[j+2]) & pm[2]) | + (data24[j+2] & ~pm[2]); + } + break; + case GXset: + for(j = 0; j < width; j+=3) { + data24[j] |= pm[0]; + data24[j+1] |= pm[1]; + data24[j+2] |= pm[2]; + } + break; + } + data24 += pitch24; + data32 += pitch32; + } + } + } +} diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgc.c b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgc.c new file mode 100644 index 000000000..4bbce3de2 --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgc.c @@ -0,0 +1,667 @@ +/* $XFree86$ */ + +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +******************************************************************/ + + +/* + +PSZ 8 16 24 32 +PIXEL_ADDR True True True True +NO_ONE_RECT False False False False +WriteBitGroup True True True True +FOUR_BIT_CODE True False False False +LOWMEMFTPT False False False False + +*/ + + +/* This gets built twice. Once for 24bpp and another for 32bpp */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#include "cfb.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "region.h" + +#include "mistruct.h" +#include "mibstore.h" +#include "migc.h" + +#include "cfb24_32.h" +#include "cfbmskbits.h" +#include "cfb8bit.h" + + +#if PSZ == 8 +# define useTEGlyphBlt cfbTEGlyphBlt8 +#else +# ifdef WriteBitGroup +# define useTEGlyphBlt cfbImageGlyphBlt8 +# else +# define useTEGlyphBlt cfbTEGlyphBlt +# endif +#endif + +#ifdef WriteBitGroup +# define useImageGlyphBlt cfbImageGlyphBlt8 +# define usePolyGlyphBlt cfbPolyGlyphBlt8 +#else +# define useImageGlyphBlt miImageGlyphBlt +# define usePolyGlyphBlt miPolyGlyphBlt +#endif + +#ifdef FOUR_BIT_CODE +# define usePushPixels cfbPushPixels8 +#else +#ifndef LOWMEMFTPT +# define usePushPixels mfbPushPixels +#else +# define usePushPixels miPushPixels +#endif /* ifndef LOWMEMFTPT */ +#endif + +#ifdef PIXEL_ADDR +# define ZeroPolyArc cfbZeroPolyArcSS8Copy +#else +# define ZeroPolyArc miZeroPolyArc +#endif + + +static GCOps cfb24_32TEOps1Rect = { + cfbSolidSpansCopy, + cfbSetSpans, + cfbPutImage, + cfb24_32CopyArea, + miCopyPlane, + cfbPolyPoint, +#ifdef PIXEL_ADDR + cfb8LineSS1Rect, + cfb8SegmentSS1Rect, +#else + cfbLineSS, + cfbSegmentSS, +#endif + miPolyRectangle, + ZeroPolyArc, + cfbFillPoly1RectCopy, + cfbPolyFillRect, + cfbPolyFillArcSolidCopy, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + useTEGlyphBlt, + usePolyGlyphBlt, + usePushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +static GCOps cfb24_32NonTEOps1Rect = { + cfbSolidSpansCopy, + cfbSetSpans, + cfbPutImage, + cfb24_32CopyArea, + miCopyPlane, + cfbPolyPoint, +#ifdef PIXEL_ADDR + cfb8LineSS1Rect, + cfb8SegmentSS1Rect, +#else + cfbLineSS, + cfbSegmentSS, +#endif + miPolyRectangle, + ZeroPolyArc, + cfbFillPoly1RectCopy, + cfbPolyFillRect, + cfbPolyFillArcSolidCopy, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + useImageGlyphBlt, + usePolyGlyphBlt, + usePushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +static GCOps cfb24_32TEOps = { + cfbSolidSpansCopy, + cfbSetSpans, + cfbPutImage, + cfb24_32CopyArea, + miCopyPlane, + cfbPolyPoint, + cfbLineSS, + cfbSegmentSS, + miPolyRectangle, + ZeroPolyArc, + miFillPolygon, + cfbPolyFillRect, + cfbPolyFillArcSolidCopy, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + useTEGlyphBlt, + usePolyGlyphBlt, + usePushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +static GCOps cfb24_32NonTEOps = { + cfbSolidSpansCopy, + cfbSetSpans, + cfbPutImage, + cfb24_32CopyArea, + miCopyPlane, + cfbPolyPoint, + cfbLineSS, + cfbSegmentSS, + miPolyRectangle, +#ifdef PIXEL_ADDR + cfbZeroPolyArcSS8Copy, +#else + miZeroPolyArc, +#endif + miFillPolygon, + cfbPolyFillRect, + cfbPolyFillArcSolidCopy, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + useImageGlyphBlt, + usePolyGlyphBlt, + usePushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +static GCOps * +cfb24_32MatchCommon (GCPtr pGC, cfbPrivGCPtr devPriv) +{ + if (pGC->lineWidth != 0) + return 0; + if (pGC->lineStyle != LineSolid) + return 0; + if (pGC->fillStyle != FillSolid) + return 0; + if (devPriv->rop != GXcopy) + return 0; + if (pGC->font && + FONTMAXBOUNDS(pGC->font,rightSideBearing) - + FONTMINBOUNDS(pGC->font,leftSideBearing) <= 32 && + FONTMINBOUNDS(pGC->font,characterWidth) >= 0) + { + if (TERMINALFONT(pGC->font) +#ifdef FOUR_BIT_CODE + && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB +#endif + ) +#ifdef NO_ONE_RECT + return &cfb24_32TEOps1Rect; +#else + if (devPriv->oneRect) + return &cfb24_32TEOps1Rect; + else + return &cfb24_32TEOps; +#endif + else +#ifdef NO_ONE_RECT + return &cfb24_32NonTEOps1Rect; +#else + if (devPriv->oneRect) + return &cfb24_32NonTEOps1Rect; + else + return &cfb24_32NonTEOps; +#endif + } + return 0; +} + + +/* Clipping conventions + if the drawable is a window + CT_REGION ==> pCompositeClip really is the composite + CT_other ==> pCompositeClip is the window clip region + if the drawable is a pixmap + CT_REGION ==> pCompositeClip is the translated client region + clipped to the pixmap boundary + CT_other ==> pCompositeClip is the pixmap bounding box +*/ + +void +#if PSZ == 24 +cfb24_32ValidateGC24( +#else +cfb24_32ValidateGC32( +#endif + GCPtr pGC, + unsigned long changes, + DrawablePtr pDrawable +){ + int mask; /* stateChanges */ + int index; /* used for stepping through bitfields */ + int new_rrop; + int new_line, new_text, new_fillspans, new_fillarea; + /* flags for changing the proc vector */ + cfbPrivGCPtr devPriv; + int oneRect; + + pGC->lastWinOrg.x = pDrawable->x; + pGC->lastWinOrg.y = pDrawable->y; + devPriv = cfbGetGCPrivate(pGC); + + new_rrop = FALSE; + new_line = FALSE; + new_text = FALSE; + new_fillspans = FALSE; + new_fillarea = FALSE; + + /* + * if the client clip is different or moved OR the subwindowMode has + * changed OR the window's clip has changed since the last validation + * we need to recompute the composite clip + */ + + if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) || + (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))) + { + miComputeCompositeClip (pGC, pDrawable); +#ifdef NO_ONE_RECT + devPriv->oneRect = FALSE; +#else + oneRect = REGION_NUM_RECTS(pGC->pCompositeClip) == 1; + if (oneRect != devPriv->oneRect) + new_line = TRUE; + devPriv->oneRect = oneRect; +#endif + } + + mask = changes; + while (mask) { + index = lowbit (mask); + mask &= ~index; + + /* + * this switch acculmulates a list of which procedures might have + * to change due to changes in the GC. in some cases (e.g. + * changing one 16 bit tile for another) we might not really need + * a change, but the code is being paranoid. this sort of batching + * wins if, for example, the alu and the font have been changed, + * or any other pair of items that both change the same thing. + */ + switch (index) { + case GCFunction: + case GCForeground: + new_rrop = TRUE; + break; + case GCPlaneMask: + new_rrop = TRUE; + new_text = TRUE; + break; + case GCBackground: + break; + case GCLineStyle: + case GCLineWidth: + new_line = TRUE; + break; + case GCJoinStyle: + case GCCapStyle: + break; + case GCFillStyle: + new_text = TRUE; + new_fillspans = TRUE; + new_line = TRUE; + new_fillarea = TRUE; + break; + case GCFillRule: + break; + case GCTile: + new_fillspans = TRUE; + new_fillarea = TRUE; + break; + case GCStipple: + new_fillspans = TRUE; + new_fillarea = TRUE; + break; + case GCTileStipXOrigin: + case GCTileStipYOrigin: + break; + case GCFont: + new_text = TRUE; + break; + case GCSubwindowMode: + case GCGraphicsExposures: + case GCClipXOrigin: + case GCClipYOrigin: + case GCClipMask: + case GCDashOffset: + case GCDashList: + case GCArcMode: + default: + break; + } + } + + /* + * If the drawable has changed, ensure suitable + * entries are in the proc vector. + */ + if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS))) + new_fillspans = TRUE; /* deal with FillSpans later */ + + if (new_rrop) + { + int old_rrop; + + old_rrop = devPriv->rop; + devPriv->rop = cfbReduceRasterOp (pGC->alu, pGC->fgPixel, + pGC->planemask, + &devPriv->and, &devPriv->xor); + if (old_rrop == devPriv->rop) + new_rrop = FALSE; + else + { +#ifdef PIXEL_ADDR + new_line = TRUE; +#endif +#ifdef WriteBitGroup + new_text = TRUE; +#endif + new_fillspans = TRUE; + new_fillarea = TRUE; + } + } + + if(!pGC->ops) + pGC->ops = & cfb24_32NonTEOps; + + if (new_rrop || new_fillspans || new_text || new_fillarea || new_line) + { + GCOps *newops; + + if ((newops = cfb24_32MatchCommon (pGC, devPriv))) + { + if (pGC->ops->devPrivate.val) + miDestroyGCOps (pGC->ops); + pGC->ops = newops; + new_rrop = new_line = new_fillspans = new_text = new_fillarea = 0; + } + else + { + if (!pGC->ops->devPrivate.val) + { + pGC->ops = miCreateGCOps (pGC->ops); + pGC->ops->devPrivate.val = 1; + } + } + } + + /* deal with the changes we've collected */ + if (new_line) + { + pGC->ops->FillPolygon = miFillPolygon; +#ifdef NO_ONE_RECT + if (pGC->fillStyle == FillSolid) + { + switch (devPriv->rop) { + case GXcopy: + pGC->ops->FillPolygon = cfbFillPoly1RectCopy; + break; + default: + pGC->ops->FillPolygon = cfbFillPoly1RectGeneral; + break; + } + } +#else + if (devPriv->oneRect && pGC->fillStyle == FillSolid) + { + switch (devPriv->rop) { + case GXcopy: + pGC->ops->FillPolygon = cfbFillPoly1RectCopy; + break; + default: + pGC->ops->FillPolygon = cfbFillPoly1RectGeneral; + break; + } + } +#endif + if (pGC->lineWidth == 0) + { +#ifdef PIXEL_ADDR + if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid)) + { + switch (devPriv->rop) + { + case GXxor: + pGC->ops->PolyArc = cfbZeroPolyArcSS8Xor; + break; + case GXcopy: + pGC->ops->PolyArc = cfbZeroPolyArcSS8Copy; + break; + default: + pGC->ops->PolyArc = cfbZeroPolyArcSS8General; + break; + } + } + else +#endif + pGC->ops->PolyArc = miZeroPolyArc; + } + else + pGC->ops->PolyArc = miPolyArc; + pGC->ops->PolySegment = miPolySegment; + switch (pGC->lineStyle) + { + case LineSolid: + if(pGC->lineWidth == 0) + { + if (pGC->fillStyle == FillSolid) + { +#if defined(PIXEL_ADDR) && !defined(NO_ONE_RECT) + if (devPriv->oneRect && + ((pDrawable->x >= pGC->pScreen->width - 32768) && + (pDrawable->y >= pGC->pScreen->height - 32768))) + { + pGC->ops->Polylines = cfb8LineSS1Rect; + pGC->ops->PolySegment = cfb8SegmentSS1Rect; + } else +#endif +#ifdef NO_ONE_RECT + { + pGC->ops->Polylines = cfb8LineSS1Rect; + pGC->ops->PolySegment = cfb8SegmentSS1Rect; + } +#else + { + pGC->ops->Polylines = cfbLineSS; + pGC->ops->PolySegment = cfbSegmentSS; + } +#endif + } + else + pGC->ops->Polylines = miZeroLine; + } + else + pGC->ops->Polylines = miWideLine; + break; + case LineOnOffDash: + case LineDoubleDash: + if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid) + { + pGC->ops->Polylines = cfbLineSD; + pGC->ops->PolySegment = cfbSegmentSD; + } else + pGC->ops->Polylines = miWideDash; + break; + } + } + + if (new_text && (pGC->font)) + { + if (FONTMAXBOUNDS(pGC->font,rightSideBearing) - + FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 || + FONTMINBOUNDS(pGC->font,characterWidth) < 0) + { + pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; + pGC->ops->ImageGlyphBlt = miImageGlyphBlt; + } + else + { +#ifdef WriteBitGroup + if (pGC->fillStyle == FillSolid) + { + if (devPriv->rop == GXcopy) + pGC->ops->PolyGlyphBlt = cfbPolyGlyphBlt8; + else +#ifdef FOUR_BIT_CODE + pGC->ops->PolyGlyphBlt = cfbPolyGlyphRop8; +#else + pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; +#endif + } + else +#endif + pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; + /* special case ImageGlyphBlt for terminal emulator fonts */ +#if !defined(WriteBitGroup) || PSZ == 8 + if (TERMINALFONT(pGC->font) && + (pGC->planemask & PMSK) == PMSK +#ifdef FOUR_BIT_CODE + && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB +#endif + ) + { + pGC->ops->ImageGlyphBlt = useTEGlyphBlt; + } + else +#endif + { +#ifdef WriteBitGroup + if (devPriv->rop == GXcopy && + pGC->fillStyle == FillSolid && + (pGC->planemask & PMSK) == PMSK) + pGC->ops->ImageGlyphBlt = cfbImageGlyphBlt8; + else +#endif + pGC->ops->ImageGlyphBlt = miImageGlyphBlt; + } + } + } + + + if (new_fillspans) { + switch (pGC->fillStyle) { + case FillSolid: + switch (devPriv->rop) { + case GXcopy: + pGC->ops->FillSpans = cfbSolidSpansCopy; + break; + case GXxor: + pGC->ops->FillSpans = cfbSolidSpansXor; + break; + default: + pGC->ops->FillSpans = cfbSolidSpansGeneral; + break; + } + break; + case FillTiled: + pGC->ops->FillSpans = cfbUnnaturalTileFS; + break; + case FillStippled: + case FillOpaqueStippled: + pGC->ops->FillSpans = cfbUnnaturalStippleFS; + break; + default: + FatalError("cfbValidateGC: illegal fillStyle\n"); + } + } /* end of new_fillspans */ + + if (new_fillarea) { +#ifndef FOUR_BIT_CODE + pGC->ops->PolyFillRect = miPolyFillRect; + if (pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) + { + pGC->ops->PolyFillRect = cfbPolyFillRect; + } +#endif +#ifdef FOUR_BIT_CODE +#ifndef LOWMEMFTPT + pGC->ops->PushPixels = mfbPushPixels; +#else + pGC->ops->PushPixels = miPushPixels; +#endif /* ifndef LOWMEMFTPT */ + if (pGC->fillStyle == FillSolid && devPriv->rop == GXcopy) + pGC->ops->PushPixels = cfbPushPixels8; +#endif + pGC->ops->PolyFillArc = miPolyFillArc; + if (pGC->fillStyle == FillSolid) + { + switch (devPriv->rop) + { + case GXcopy: + pGC->ops->PolyFillArc = cfbPolyFillArcSolidCopy; + break; + default: + pGC->ops->PolyFillArc = cfbPolyFillArcSolidGeneral; + break; + } + } + } +} diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgcmisc.c b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgcmisc.c new file mode 100644 index 000000000..1f039e6e8 --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgcmisc.c @@ -0,0 +1,170 @@ +/* $XFree86$ */ + +#include "X.h" +#include "Xmd.h" +#include "Xproto.h" +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "region.h" + +#include "mistruct.h" +#include "mibstore.h" +#include "migc.h" + + +static void cfb24_32ValidateGC(GCPtr, unsigned long, DrawablePtr); +static void cfb24_32DestroyGC(GCPtr pGC); +static void cfb24_32ChangeGC(GCPtr pGC, unsigned long mask); +static void cfb24_32CopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst); + +static +GCFuncs cfb24_32GCFuncs = { + cfb24_32ValidateGC, + cfb24_32ChangeGC, + cfb24_32CopyGC, + cfb24_32DestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip, +}; + +static void +cfb24_32DestroyGC(GCPtr pGC) +{ + cfb24_32GCPtr pGCPriv = CFB24_32_GET_GC_PRIVATE(pGC); + + if (pGC->freeCompClip) + REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip); + if(pGCPriv->Ops24bpp) + miDestroyGCOps(pGCPriv->Ops24bpp); + if(pGCPriv->Ops32bpp) + miDestroyGCOps(pGCPriv->Ops32bpp); +} + +static void +cfb24_32ChangeGC( + GCPtr pGC, + unsigned long mask +){ + + if((mask & GCTile) && pGC->tile.pixmap && !pGC->tileIsPixel) { + PixmapPtr pPix = pGC->tile.pixmap; + cfb24_32PixmapPtr pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix); + + if(pixPriv->pix && (pPix->refcnt != pixPriv->pix->refcnt)) + pixPriv->pix->refcnt = pPix->refcnt; + } + + return; +} + +static void +cfb24_32CopyGC( + GCPtr pGCSrc, + unsigned long changes, + GCPtr pGCDst +){ + if((changes & GCTile) && pGCDst->tile.pixmap && !pGCDst->tileIsPixel) { + PixmapPtr pPix = pGCDst->tile.pixmap; + cfb24_32PixmapPtr pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix); + + if(pixPriv->pix && (pPix->refcnt != pixPriv->pix->refcnt)) + pixPriv->pix->refcnt = pPix->refcnt; + } + + return; +} + + + +Bool +cfb24_32CreateGC(GCPtr pGC) +{ + cfb24_32GCPtr pGCPriv; + cfbPrivGC *pPriv; + + if (PixmapWidthPaddingInfo[pGC->depth].padPixelsLog2 == LOG2_BITMAP_PAD) + return (mfbCreateGC(pGC)); + + pGC->clientClip = NULL; + pGC->clientClipType = CT_NONE; + pGC->miTranslate = 1; + pGC->fExpose = TRUE; + pGC->freeCompClip = FALSE; + pGC->pRotatedPixmap = (PixmapPtr) NULL; + + pPriv = cfbGetGCPrivate(pGC); + pPriv->rop = pGC->alu; + pPriv->oneRect = FALSE; + + pGC->ops = NULL; + pGC->funcs = &cfb24_32GCFuncs; + + pGCPriv = CFB24_32_GET_GC_PRIVATE(pGC); + pGCPriv->Ops24bpp = NULL; + pGCPriv->Ops32bpp = NULL; + pGCPriv->OpsAre24bpp = FALSE; + pGCPriv->changes = 0; + + return TRUE; +} + + +static void +cfb24_32ValidateGC( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw +){ + cfb24_32GCPtr pGCPriv = CFB24_32_GET_GC_PRIVATE(pGC); + + if(pDraw->bitsPerPixel == 32) { + if(pGCPriv->OpsAre24bpp) { + int origChanges = changes; + pGC->ops = pGCPriv->Ops32bpp; + changes |= pGCPriv->changes; + pGCPriv->changes = origChanges; + pGCPriv->OpsAre24bpp = FALSE; + } else + pGCPriv->changes |= changes; + + if((pGC->fillStyle == FillTiled) && + (pGC->tile.pixmap->drawable.bitsPerPixel == 24)){ + pGC->tile.pixmap = cfb24_32RefreshPixmap(pGC->tile.pixmap); + changes |= GCTile; + } + + cfb24_32ValidateGC32(pGC, changes, pDraw); + pGCPriv->Ops32bpp = pGC->ops; + } else { /* bitsPerPixel == 24 */ + if(!pGCPriv->OpsAre24bpp) { + int origChanges = changes; + pGC->ops = pGCPriv->Ops24bpp; + changes |= pGCPriv->changes; + pGCPriv->changes = origChanges; + pGCPriv->OpsAre24bpp = TRUE; + } else + pGCPriv->changes |= changes; + + if((pGC->fillStyle == FillTiled) && + (pGC->tile.pixmap->drawable.bitsPerPixel == 32)){ + pGC->tile.pixmap = cfb24_32RefreshPixmap(pGC->tile.pixmap); + changes |= GCTile; + } + + cfb24_32ValidateGC24(pGC, changes, pDraw); + pGCPriv->Ops24bpp = pGC->ops; + } + +} + diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfbimage.c b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbimage.c new file mode 100644 index 000000000..36f7c327d --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbimage.c @@ -0,0 +1,94 @@ +/* $XFree86$ */ + +#include "X.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#include "servermd.h" +#include "mi.h" + + +void +cfb24_32GetImage ( + DrawablePtr pDraw, + int sx, int sy, int w, int h, + unsigned int format, + unsigned long planemask, + char *pdstLine +){ + if(!w || !h) return; + + if((pDraw->bitsPerPixel != 24) || (format != ZPixmap)) { + cfb32GetImage(pDraw, sx, sy, w, h, format, planemask, pdstLine); + return; + } else { + BoxRec box; + DDXPointRec ptSrc; + RegionRec rgnDst; + ScreenPtr pScreen; + PixmapPtr pPixmap; + + pScreen = pDraw->pScreen; + pPixmap = GetScratchPixmapHeader(pScreen, w, h, 24, 32, + PixmapBytePad(w,24), (pointer)pdstLine); + if (!pPixmap) + return; + if ((planemask & 0x00ffffff) != 0x00ffffff) + bzero((char *)pdstLine, pPixmap->devKind * h); + ptSrc.x = sx + pDraw->x; + ptSrc.y = sy + pDraw->y; + box.x1 = 0; + box.y1 = 0; + box.x2 = w; + box.y2 = h; + REGION_INIT(pScreen, &rgnDst, &box, 1); + cfbDoBitblt24To32(pDraw, (DrawablePtr)pPixmap, GXcopy, &rgnDst, + &ptSrc, planemask, 0); + REGION_UNINIT(pScreen, &rgnDst); + FreeScratchPixmapHeader(pPixmap); + } +} + + +void +cfb24_32GetSpans( + DrawablePtr pDraw, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pDst +){ + int pitch, i; + CARD8 *ptr, *ptrBase; + + if(pDraw->bitsPerPixel != 24){ + cfb32GetSpans(pDraw, wMax, ppt, pwidth, nspans, pDst); + return; + } + + /* gotta get spans from a 24 bpp window */ + cfbGetByteWidthAndPointer(pDraw, pitch, ptrBase); + + while(nspans--) { + ptr = ptrBase + (ppt->y * pitch) + (ppt->x * 3); + + for(i = *pwidth; i--; ptr += 3, pDst += 4) { + /* this is used so infrequently that it's not worth optimizing */ + pDst[0] = ptr[0]; + pDst[1] = ptr[1]; + pDst[2] = ptr[2]; + } + + ppt++; pwidth++; + } +} + + diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfbpixmap.c b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbpixmap.c new file mode 100644 index 000000000..60c9b3833 --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbpixmap.c @@ -0,0 +1,142 @@ +/* $XFree86$ */ + +#include "Xmd.h" +#include "servermd.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "mi.h" +#include "cfb24_32.h" + + +PixmapPtr +cfb24_32CreatePixmap ( + ScreenPtr pScreen, + int width, + int height, + int depth +){ + cfb24_32PixmapPtr pPixPriv; + PixmapPtr pPix; + int size, bpp, pitch; + + /* All depth 24 pixmaps are 24bpp unless the caller is allocating + its own data (width == 0) */ + + if(depth == 1) { + pitch = ((width + 31) >> 5) << 2; + bpp = 1; + } else { /* depth == 24 */ + pitch = ((width * 3) + 3) & ~3L; + bpp = (width && height) ? 24 : 32; + } + + size = height * pitch; + pPix = AllocatePixmap(pScreen, size); + if (!pPix) + return NullPixmap; + pPix->drawable.type = DRAWABLE_PIXMAP; + pPix->drawable.class = 0; + pPix->drawable.pScreen = pScreen; + pPix->drawable.depth = depth; + pPix->drawable.bitsPerPixel = bpp; + pPix->drawable.id = 0; + pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPix->drawable.x = 0; + pPix->drawable.y = 0; + pPix->drawable.width = width; + pPix->drawable.height = height; + pPix->devKind = pitch; + pPix->refcnt = 1; + pPix->devPrivate.ptr = size ? + (pointer)((char*)pPix + pScreen->totalPixmapSize) : NULL; + + pPixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix); + pPixPriv->pix = NULL; /* no clone yet */ + pPixPriv->freePrivate = FALSE; + + return pPix; +} + +Bool +cfb24_32DestroyPixmap(PixmapPtr pPix) +{ + cfb24_32PixmapPtr pPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix); + PixmapPtr pClone = pPriv->pix; + + if(pClone) { + cfb24_32PixmapPtr cPriv = CFB24_32_GET_PIXMAP_PRIVATE(pClone); + int refcnt = pPix->refcnt; + cPriv->pix = NULL; /* avoid looping back */ + + if(refcnt != pClone->refcnt) + ErrorF("Pixmap refcnt mismatch in DestroyPixmap()\n"); + + (*pPix->drawable.pScreen->DestroyPixmap)(pClone); + + if(refcnt > 1) + cPriv->pix = pPix; + } + + if(--pPix->refcnt) + return TRUE; + + if(pPriv->freePrivate) + xfree(pPix->devPrivate.ptr); + xfree(pPix); + + return TRUE; +} + +PixmapPtr +cfb24_32RefreshPixmap(PixmapPtr pPix) +{ + cfb24_32PixmapPtr newPixPriv, pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix); + ScreenPtr pScreen = pPix->drawable.pScreen; + int width = pPix->drawable.width; + int height = pPix->drawable.height; + GCPtr pGC; + + if(pPix->drawable.bitsPerPixel == 24) { + if(!pixPriv->pix) { /* need to make a 32bpp clone */ + int pitch = width << 2; + unsigned char* data; + PixmapPtr newPix; + + if(!(data = (unsigned char*)xalloc(pitch * height))) + FatalError("Out of memory\n"); + + /* cfb24_32CreatePixmap will make a 32bpp header for us */ + newPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, 24); + newPix->devKind = pitch; + newPix->devPrivate.ptr = (pointer)data; + newPix->drawable.width = width; + newPix->drawable.height = height; + newPix->refcnt = pPix->refcnt; + pixPriv->pix = newPix; + newPixPriv = CFB24_32_GET_PIXMAP_PRIVATE(newPix); + newPixPriv->pix = pPix; + newPixPriv->freePrivate = TRUE; + } + } else { /* bitsPerPixel == 32 */ + if(!pixPriv->pix) { /* need to make a 32bpp clone */ + + /* cfb24_32CreatePixmap will make a 24bpp pixmap for us */ + pixPriv->pix = (*pScreen->CreatePixmap)(pScreen, width, height, 24); + pixPriv->pix->refcnt = pPix->refcnt; + newPixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pixPriv->pix); + newPixPriv->pix = pPix; + } + } + + if(pPix->refcnt != pixPriv->pix->refcnt) + ErrorF("Pixmap refcnt mismatch in RefreshPixmap()\n"); + + pGC = GetScratchGC(24, pScreen); + ValidateGC((DrawablePtr)pixPriv->pix, pGC); + (*pGC->ops->CopyArea)((DrawablePtr)pPix, (DrawablePtr)pixPriv->pix, + pGC, 0, 0, width, height, 0, 0); + FreeScratchGC(pGC); + + return pixPriv->pix; +} + diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfbscrinit.c b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbscrinit.c new file mode 100644 index 000000000..606a3bb71 --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbscrinit.c @@ -0,0 +1,192 @@ +/* $XFree86$ */ + + +#include "X.h" +#include "Xmd.h" +#include "misc.h" +#include "servermd.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "resource.h" +#include "colormap.h" +#include "colormapst.h" +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#include "mi.h" +#include "micmap.h" +#include "mistruct.h" +#include "dix.h" +#include "mibstore.h" + +/* CAUTION: We require that cfb24 and cfb32 were NOT + compiled with CFB_NEED_SCREEN_PRIVATE */ + +static BSFuncRec cfb24_32BSFuncRec = { + cfb24_32SaveAreas, + cfb24_32RestoreAreas, + (BackingStoreSetClipmaskRgnProcPtr) 0, + (BackingStoreGetImagePixmapProcPtr) 0, + (BackingStoreGetSpansPixmapProcPtr) 0, +}; + + +int cfb24_32GCIndex = 1; +int cfb24_32PixmapIndex = 1; + +static unsigned long cfb24_32Generation = 0; +extern WindowPtr *WindowTable; + +static Bool +cfb24_32AllocatePrivates(ScreenPtr pScreen) +{ + if(cfb24_32Generation != serverGeneration) { + if( ((cfb24_32GCIndex = AllocateGCPrivateIndex()) < 0) | + ((cfb24_32PixmapIndex = AllocatePixmapPrivateIndex()) < 0)) + return FALSE; + cfb24_32Generation = serverGeneration; + } + + + /* All cfb will have the same GC and Window private indicies */ + if(!mfbAllocatePrivates(pScreen,&cfbWindowPrivateIndex, &cfbGCPrivateIndex)) + return FALSE; + + /* The cfb indicies are the mfb indicies. Reallocating them resizes them */ + if(!AllocateWindowPrivate(pScreen,cfbWindowPrivateIndex,sizeof(cfbPrivWin))) + return FALSE; + + if(!AllocateGCPrivate(pScreen, cfbGCPrivateIndex, sizeof(cfbPrivGC))) + return FALSE; + + if(!AllocateGCPrivate(pScreen, cfb24_32GCIndex, sizeof(cfb24_32GCRec))) + return FALSE; + + if(!AllocatePixmapPrivate( + pScreen, cfb24_32PixmapIndex, sizeof(cfb24_32PixmapRec))) + return FALSE; + + + return TRUE; +} + +static Bool +cfb24_32SetupScreen( + ScreenPtr pScreen, + pointer pbits, /* pointer to screen bitmap */ + int xsize, int ysize, /* in pixels */ + int dpix, int dpiy, /* dots per inch */ + int width /* pixel width of frame buffer */ +){ + if (!cfb24_32AllocatePrivates(pScreen)) + return FALSE; + pScreen->defColormap = FakeClientID(0); + /* let CreateDefColormap do whatever it wants for pixels */ + pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0; + pScreen->QueryBestSize = mfbQueryBestSize; + /* SaveScreen */ + pScreen->GetImage = cfb24_32GetImage; + pScreen->GetSpans = cfb24_32GetSpans; + pScreen->CreateWindow = cfb24_32CreateWindow; + pScreen->DestroyWindow = cfb24_32DestroyWindow; + pScreen->PositionWindow = cfb24_32PositionWindow; + pScreen->ChangeWindowAttributes = cfb24_32ChangeWindowAttributes; + pScreen->RealizeWindow = cfb24MapWindow; /* OK */ + pScreen->UnrealizeWindow = cfb24UnmapWindow; /* OK */ + pScreen->PaintWindowBackground = cfb24PaintWindow; /* OK */ + pScreen->PaintWindowBorder = cfb24PaintWindow; /* OK */ + pScreen->CopyWindow = cfb24CopyWindow; /* OK */ + pScreen->CreatePixmap = cfb24_32CreatePixmap; + pScreen->DestroyPixmap = cfb24_32DestroyPixmap; + pScreen->RealizeFont = mfbRealizeFont; + pScreen->UnrealizeFont = mfbUnrealizeFont; + pScreen->CreateGC = cfb24_32CreateGC; + pScreen->CreateColormap = miInitializeColormap; + pScreen->DestroyColormap = (void (*)())NoopDDA; + pScreen->InstallColormap = miInstallColormap; + pScreen->UninstallColormap = miUninstallColormap; + pScreen->ListInstalledColormaps = miListInstalledColormaps; + pScreen->StoreColors = (void (*)())NoopDDA; + pScreen->ResolveColor = miResolveColor; + pScreen->BitmapToRegion = mfbPixmapToRegion; + + mfbRegisterCopyPlaneProc (pScreen, miCopyPlane); + return TRUE; +} + +typedef struct { + pointer pbits; + int width; +} miScreenInitParmsRec, *miScreenInitParmsPtr; + +static Bool +cfb24_32CreateScreenResources(ScreenPtr pScreen) +{ + miScreenInitParmsPtr pScrInitParms; + int pitch; + Bool retval; + + /* get the pitch before mi destroys it */ + pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate; + pitch = pScrInitParms->width * 3; /* this should already be padded */ + + if((retval = miCreateScreenResources(pScreen))) { + /* fix the screen pixmap */ + PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate; + pPix->drawable.bitsPerPixel = 24; + pPix->devKind = pitch; + } + + return retval; +} + + +static Bool +cfb24_32FinishScreenInit( + ScreenPtr pScreen, + pointer pbits, /* pointer to screen bitmap */ + int xsize, int ysize, /* in pixels */ + int dpix, int dpiy, /* dots per inch */ + int width /* pixel width of frame buffer */ +){ + VisualPtr visuals; + DepthPtr depths; + int nvisuals; + int ndepths; + int rootdepth; + VisualID defaultVisual; + + rootdepth = 0; + if (!miInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth, + &defaultVisual,((unsigned long)1<<(24-1)), 8, -1)) + return FALSE; + if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, + rootdepth, ndepths, depths, + defaultVisual, nvisuals, visuals)) + return FALSE; + + pScreen->BackingStoreFuncs = cfb24_32BSFuncRec; + pScreen->CreateScreenResources = cfb24_32CreateScreenResources; + pScreen->CloseScreen = cfb32CloseScreen; /* OK */ + pScreen->GetScreenPixmap = cfb32GetScreenPixmap; /* OK */ + pScreen->SetScreenPixmap = cfb32SetScreenPixmap; /* OK */ + return TRUE; +} + +Bool +cfb24_32ScreenInit( + ScreenPtr pScreen, + pointer pbits, /* pointer to screen bitmap */ + int xsize, int ysize, /* in pixels */ + int dpix, int dpiy, /* dots per inch */ + int width /* pixel width of frame buffer */ +){ + if (!cfb24_32SetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width)) + return FALSE; + return cfb24_32FinishScreenInit( + pScreen, pbits, xsize, ysize, dpix, dpiy, width); +} + diff --git a/programs/Xserver/hw/xfree86/xf24_32bpp/cfbwindow.c b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbwindow.c new file mode 100644 index 000000000..56119f45c --- /dev/null +++ b/programs/Xserver/hw/xfree86/xf24_32bpp/cfbwindow.c @@ -0,0 +1,79 @@ +/* $XFree86$ */ + +#include "X.h" +#include "windowstr.h" +#include "regionstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#include "mi.h" + + +Bool +cfb24_32CreateWindow(WindowPtr pWin) +{ + cfbPrivWin *pPrivWin = cfbGetWindowPrivate(pWin); + + pPrivWin->fastBackground = FALSE; + pPrivWin->fastBorder = FALSE; + + pWin->drawable.bitsPerPixel = 24; + return TRUE; +} + + +Bool +cfb24_32DestroyWindow(WindowPtr pWin) +{ + return TRUE; +} + +Bool +cfb24_32PositionWindow( + WindowPtr pWin, + int x, int y +){ + return TRUE; +} + + +Bool +cfb24_32ChangeWindowAttributes( + WindowPtr pWin, + unsigned long mask +){ + cfb24_32PixmapPtr pixPriv; + PixmapPtr pPix; + + /* The dix layer may have incremented a refcnt. We sync them here */ + + if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap)) { + pPix = pWin->background.pixmap; + pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix); + + if(pixPriv->pix && (pPix->refcnt != pixPriv->pix->refcnt)) + pixPriv->pix->refcnt = pPix->refcnt; + + if(pPix->drawable.bitsPerPixel != 24) + pWin->background.pixmap = cfb24_32RefreshPixmap(pPix); + } + + if((mask & CWBorderPixmap) && !pWin->borderIsPixel) { + pPix = pWin->border.pixmap; + pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix); + + if(pixPriv->pix && (pPix->refcnt != pixPriv->pix->refcnt)) + pixPriv->pix->refcnt = pPix->refcnt; + + if(pPix->drawable.bitsPerPixel != 24) + pWin->border.pixmap = cfb24_32RefreshPixmap(pPix); + } + + return TRUE; +} + diff --git a/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile b/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile index fcaf4a710..b7047d797 100644 --- a/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile +++ b/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86$ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile,v 1.1 1999/01/03 03:58:54 dawes Exp $ #define IHaveModules #include <Server.tmpl> @@ -36,3 +36,5 @@ ObjectFromSpecialSource(cfbgc32,cfbgc,-DPSZ=32) InstallLibraryModule(xf8_32bpp,$(MODULEDIR),.) InstallLinkKitLibrary(xf8_32bpp,$(LINKKITDIR)/lib) InstallLinkKitNonExecFile(cfb8_32.h,$(LINKKITDIR)/include) + +DependTarget() diff --git a/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c b/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c index 5d7e7d264..45b77ff13 100644 --- a/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c +++ b/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c @@ -1,4 +1,4 @@ -/* $XFree86$ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c,v 1.1 1999/01/03 03:58:56 dawes Exp $ */ /*********************************************************** Copyright 1987, 1998 The Open Group @@ -48,7 +48,7 @@ SOFTWARE. PSZ 8 16 24 32 PIXEL_ADDR True True True True NO_ONE_RECT False False False False -WriteBitGroup False False False False (because cfb cheats ?) +WriteBitGroup True True True True FOUR_BIT_CODE True False False False LOWMEMFTPT False False False False @@ -81,31 +81,35 @@ LOWMEMFTPT False False False False #if PSZ == 8 # define useTEGlyphBlt cfbTEGlyphBlt8 #else -# define useTEGlyphBlt cfbTEGlyphBlt +# ifdef WriteBitGroup +# define useTEGlyphBlt cfbImageGlyphBlt8 +# else +# define useTEGlyphBlt cfbTEGlyphBlt +# endif #endif #ifdef WriteBitGroup -# define useImageGlyphBlt cfbImageGlyphBlt8 -# define usePolyGlyphBlt cfbPolyGlyphBlt8 +# define useImageGlyphBlt cfbImageGlyphBlt8 +# define usePolyGlyphBlt cfbPolyGlyphBlt8 #else -# define useImageGlyphBlt miImageGlyphBlt -# define usePolyGlyphBlt miPolyGlyphBlt +# define useImageGlyphBlt miImageGlyphBlt +# define usePolyGlyphBlt miPolyGlyphBlt #endif #ifdef FOUR_BIT_CODE -# define usePushPixels cfbPushPixels8 +# define usePushPixels cfbPushPixels8 #else #ifndef LOWMEMFTPT -# define usePushPixels mfbPushPixels +# define usePushPixels mfbPushPixels #else -# define usePushPixels miPushPixels +# define usePushPixels miPushPixels #endif /* ifndef LOWMEMFTPT */ #endif #ifdef PIXEL_ADDR -# define ZeroPolyArc cfbZeroPolyArcSS8Copy +# define ZeroPolyArc cfbZeroPolyArcSS8Copy #else -# define ZeroPolyArc miZeroPolyArc +# define ZeroPolyArc miZeroPolyArc #endif diff --git a/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c b/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c index 3b34ad699..649bb3f8e 100644 --- a/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c +++ b/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c,v 1.2 1999/01/03 08:06:40 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c,v 1.3 1999/01/11 12:09:40 dawes Exp $ */ #include "X.h" @@ -23,6 +23,11 @@ extern WindowPtr *WindowTable; Bool cfb8_32CreateWindow(WindowPtr pWin) { + cfbPrivWin *pPrivWin = cfbGetWindowPrivate(pWin); + + pPrivWin->fastBackground = FALSE; + pPrivWin->fastBorder = FALSE; + pWin->drawable.bitsPerPixel = 32; return TRUE; } diff --git a/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c b/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c index f2c23ad2f..228acabf4 100644 --- a/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c +++ b/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c,v 1.2 1999/01/11 12:09:40 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c,v 1.3 1999/01/14 13:05:35 dawes Exp $ */ /* Copyright (C) 1998. The XFree86 Project Inc. @@ -83,7 +83,7 @@ static void PixmapImageGlyphBlt(DrawablePtr, GCPtr, int, int, static void PixmapPolyGlyphBlt(DrawablePtr, GCPtr, int, int, unsigned int, CharInfoPtr *, pointer); -GCOps PixmapGCOps = { +static GCOps PixmapGCOps = { PixmapFillSpans, PixmapSetSpans, PixmapPutImage, PixmapCopyArea, PixmapCopyPlane, PixmapPolyPoint, @@ -134,7 +134,7 @@ static void WindowImageGlyphBlt(DrawablePtr, GCPtr, int, int, static void WindowPolyGlyphBlt(DrawablePtr, GCPtr, int, int, unsigned int, CharInfoPtr *, pointer); -GCOps WindowGCOps = { +static GCOps WindowGCOps = { WindowFillSpans, WindowSetSpans, WindowPutImage, WindowCopyArea, WindowCopyPlane, WindowPolyPoint, @@ -426,11 +426,18 @@ OverlayPaintWindow( PixmapPtr oldPix = NULL; if(what == PW_BACKGROUND) { - if((pWin->drawable.depth == 8) && - (pWin->backgroundState == BackgroundPixmap)) { - oldPix = pWin->background.pixmap; - pixPriv = OVERLAY_GET_PIXMAP_PRIVATE(oldPix); - pWin->background.pixmap = pixPriv->pix32; + if(pWin->drawable.depth == 8) { + if(pWin->backgroundState == ParentRelative) { + do { + pWin = pWin->parent; + } while (pWin->backgroundState == ParentRelative); + } + + if(pWin->backgroundState == BackgroundPixmap) { + oldPix = pWin->background.pixmap; + pixPriv = OVERLAY_GET_PIXMAP_PRIVATE(oldPix); + pWin->background.pixmap = pixPriv->pix32; + } } pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground; |