diff options
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers')
78 files changed, 19049 insertions, 1562 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/Imakefile index 4121f4aea..e2d18d1ef 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/Imakefile,v 1.17 2000/10/20 14:59:00 alanh Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/Imakefile,v 1.19 2000/11/02 21:29:29 tsi Exp $ #define IHaveModules #include <Server.tmpl> @@ -10,12 +10,12 @@ DRIVERS = XF86CardDrivers #ifndef OS2Architecture OBJS = `cat driver.list` #else -OBJS = al2101/?*.o mx/?*.o oak/?*.o realtek/?*.o sis/?*.o trident/?*.o \ - ali/?*.o apm/?*.o apollo/?*.o ark/?*.o ati/?*.o chips/?*.o \ - cirrus/?*.o cl64xx/?*.o compaq/?*.o et3000/?*.o glint/?*.o \ - gvga/?*.o hercules/?*.o hgc1280/?*.o mga/?*.o ncr/?*.o \ - nv/?*.o s3_pio/?*.o s3_newmmio/?*.o sigma/?*.o tseng/?*.o \ - vga/?*.o video7/?*.o wd/?*.o i740/?*.o r128/?*.o i128/?*.o vesa/?*.o +OBJS = apm/?*_drv.o ati/?*_drv.o chips/?*_drv.o cirrus/?*_drv.o \ + cyrix/?*_drv.o glint/?*_drv.o i128/?*_drv.o i740/?*_drv.o \ + i810/?*_drv.o imstt/?*_drv.o mga/?*_drv.o neomagic/?*_drv.o \ + nv/?*_drv.o rendition/?*_drv.o s3virge/?*_drv.o sis/?*_drv.o \ + tdfx/?*_drv.o tga/?*_drv.o trident/?*_drv.o tseng/?*_drv.o \ + vesa/?*_drv.o vga/?*_drv.o #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile index d3a62f8a4..e0c581566 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v 1.23 2000/10/17 16:53:17 tsi Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v 1.25 2000/11/02 16:55:26 tsi Exp $ XCOMM XCOMM Copyright 1997 through 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca XCOMM @@ -29,8 +29,28 @@ CCOPTIONS = ATIDriverCCOptions #endif #if DoLoadableServer -MODSRCS = atiload.c atimodule.c -MODOBJS = atiload.o atimodule.o + +MODSRCS1 = atimodule.c +MODSRCS2 = atiload.c atimisc.c +MODSRCS3 = r128_misc.c +MODSRCS4 = radeon_misc.c + +MODOBJS1 = atimodule.o +MODOBJS2 = atiload.o atimisc.o +MODOBJS3 = r128_misc.o +MODOBJS4 = radeon_misc.o + +#endif + +#if BuildXF86DRI + +DRISRCS3 = r128_dri.c + +DRIOBJS3 = r128_dri.o + +DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri -I$(TOP)/include +DRIDEFINES = $(GLX_DEFINES) + #endif /* @@ -68,39 +88,59 @@ MODOBJS = atiload.o atimodule.o #if !ATIAvoidCPIO -CPIOSRCS = atibank.c atibios.c ativga.c ativgaio.c atiwonder.c atiwonderio.c -CPIOOBJS = atibank.o atibios.o ativga.o ativgaio.o atiwonder.o atiwonderio.o +CPIOSRCS1 = atibios.c ativgaio.c +CPIOSRCS2 = atibank.c ativga.c atiwonder.c atiwonderio.c + +CPIOOBJS1 = atibios.o ativgaio.o +CPIOOBJS2 = atibank.o ativga.o atiwonder.o atiwonderio.o #else -DEFINES = -DAVOID_CPIO +CPIODEFINES = -DAVOID_CPIO #endif -SRCS = ati.c atiadapter.c atiadjust.c atibus.c atichip.c aticlock.c \ - aticonfig.c aticonsole.c atidac.c atidga.c atidsp.c atiident.c \ - atilock.c atimach64.c atimach64io.c atimode.c atioption.c atipreinit.c \ - atiprint.c atiprobe.c atiscreen.c atiutil.c ativalid.c atividmem.c \ - $(MODSRCS) $(CPIOSRCS) +DEFINES = $(CPIODEFINES) $(DRIDEFINES) -OBJS = ati.o atiadapter.o atiadjust.o atibus.o atichip.o aticlock.o \ - aticonfig.o aticonsole.o atidac.o atidga.o atidsp.o atiident.o \ - atilock.o atimach64.o atimach64io.o atimode.o atioption.o atipreinit.o \ - atiprint.o atiprobe.o atiscreen.o atiutil.o ativalid.o atividmem.o \ - $(MODOBJS) $(CPIOOBJS) +SRCS1 = ati.c atiadapter.c atibus.c atichip.c atiident.c atioption.c \ + atiprobe.c atividmem.c $(MODSRCS1) $(CPIOSRCS1) \ + radeon_probe.c r128_probe.c +SRCS2 = atiadjust.c aticlock.c aticonfig.c aticonsole.c atidac.c atidga.c \ + atidsp.c atilock.c atimach64.c atimach64io.c atimode.c atipreinit.c \ + atiprint.c atiscreen.c atiutil.c ativalid.c $(MODSRCS2) $(CPIOSRCS2) +SRCS3 = r128_accel.c r128_cursor.c r128_dga.c r128_driver.c r128_video.c \ + $(MODSRCS3) $(DRISRCS3) +SRCS4 = radeon_accel.c radeon_cursor.c radeon_dga.c radeon_driver.c \ + radeon_video.c $(MODSRCS4) + +OBJS1 = ati.o atiadapter.o atibus.o atichip.o atiident.o atioption.o \ + atiprobe.o atividmem.o $(MODOBJS1) $(CPIOOBJS1) \ + radeon_probe.o r128_probe.o +OBJS2 = atiadjust.o aticlock.o aticonfig.o aticonsole.o atidac.o atidga.o \ + atidsp.o atilock.o atimach64.o atimach64io.o atimode.o atipreinit.o \ + atiprint.o atiscreen.o atiutil.o ativalid.o $(MODOBJS2) $(CPIOOBJS2) +OBJS3 = r128_accel.o r128_cursor.o r128_dga.o r128_driver.o r128_video.o \ + $(MODOBJS3) $(DRIOBJS3) +OBJS4 = radeon_accel.o radeon_cursor.o radeon_dga.o radeon_driver.o \ + radeon_video.o $(MODOBJS4) + +SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) +OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) #if defined(XF86DriverSDK) INCLUDES = -I. -I../../include #else INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC) \ -I$(XF86OSSRC)/vbe -I$(XF86SRC)/int10 \ - -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c -I$(XF86SRC)/rac \ - -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xaa \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ + -I$(XF86SRC)/rac -I$(XF86SRC)/ramdac \ + -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xaa -I$(XF86SRC)/xf24_32bpp \ -I$(XF86SRC)/xf4bpp -I$(XF86SRC)/xf1bpp \ + -I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \ - -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \ - -I$(SERVERSRC)/Xext -I$(XINCLUDESRC) -I$(FONTINCSRC) \ - -I$(EXTINCSRC) -I$(SERVERSRC)/render + -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/render -I$(SERVERSRC)/Xext -I$(SERVERSRC)/include \ + $(DRIINCLUDES) -I$(FONTINCSRC) -I$(EXTINCSRC) -I$(XINCLUDESRC) #endif #if MakeHasPosixVariableSubstitutions @@ -109,19 +149,29 @@ SubdirLibraryRule($(OBJS)) ModuleObjectRule() -ObjectModuleTarget(ati,$(OBJS)) +ObjectModuleTarget(ati,$(OBJS1)) +ObjectModuleTarget(atimisc,$(OBJS2)) +ObjectModuleTarget(r128,$(OBJS3)) +ObjectModuleTarget(radeon,$(OBJS4)) InstallObjectModule(ati,$(MODULEDIR),drivers) +InstallObjectModule(atimisc,$(MODULEDIR),drivers) +InstallObjectModule(r128,$(MODULEDIR),drivers) +InstallObjectModule(radeon,$(MODULEDIR),drivers) -#if !defined(XF86DriverSDK) +#if 0 CppManTarget(ati,) InstallModuleManPage(ati) #endif +CppManTarget(r128,) +InstallModuleManPage(r128) + DependTarget() InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(ati.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(ati.cpp,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(ati.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiadapter.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiadapter.h,$(DRIVERSDKDIR)/drivers/ati) @@ -159,9 +209,11 @@ InstallDriverSDKNonExecFile(atimach64.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimach64.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimach64io.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimach64io.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atimisc.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimode.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimode.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimodule.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atimodule.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimono.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atioption.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atioption.h,$(DRIVERSDKDIR)/drivers/ati) @@ -193,4 +245,57 @@ InstallDriverSDKNonExecFile(atiwonder.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiwonderio.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiwonderio.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128.cpp,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_accel.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_cursor.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_dga.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_dri.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_dri.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_dripriv.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_driver.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_misc.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_probe.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_probe.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_reg.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_sarea.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_version.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_video.c,$(DRIVERSDKDIR)/drivers/ati) + +InstallDriverSDKNonExecFile(radeon.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_accel.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_cursor.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_dga.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_driver.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_misc.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_probe.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_probe.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_reg.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_version.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_video.c,$(DRIVERSDKDIR)/drivers/ati) + InstallDriverSDKObjectModule(ati,$(DRIVERSDKMODULEDIR),drivers) +InstallDriverSDKObjectModule(atimisc,$(DRIVERSDKMODULEDIR),drivers) +InstallDriverSDKObjectModule(r128,$(DRIVERSDKMODULEDIR),drivers) +InstallDriverSDKObjectModule(radeon,$(DRIVERSDKMODULEDIR),drivers) + +/* Remove instances of ati2 module */ +#if DoLoadableServer + +#undef ATI2DriverModuleName +#if MakeDllModules +# define ATI2DriverModuleName ati2_drv.so +#else +# define ATI2DriverModuleName ati2_drv.o +#endif + +all:: + RemoveFile($(BUILDMODULEDIR)/drivers/ATI2DriverModuleName) + +install:: + RemoveFile($(DESTDIR)$(MODULEDIR)/drivers/ATI2DriverModuleName) + +install.sdk:: + RemoveFile($(DESTDIR)$(DRIVERSDKMODULEDIR)/drivers/ATI2DriverModuleName) + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c index d0f334fce..980a84adb 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c,v 1.6 2000/08/04 21:07:14 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c,v 1.7 2000/11/02 16:55:27 tsi Exp $ */ /* * Copyright 1997 through 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca * @@ -25,6 +25,9 @@ #include "atiident.h" #include "ativersion.h" +#include "r128_probe.h" +#include "radeon_probe.h" + const char *ATIChipsetNames[] = { "ati", @@ -78,6 +81,8 @@ ATIIdentify xf86PrintChipsets(ATI_NAME, "ATI driver (version " ATI_VERSION_NAME ") for chipsets", ATIPublicChipsetNames); + R128Identify(flags); + RADEONIdentify(flags); } /* diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c index 4886424eb..e9241d664 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c,v 1.25 2000/08/31 19:03:58 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c,v 1.26 2000/11/02 16:55:28 tsi Exp $ */ /* * Copyright 1997 through 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca * @@ -27,7 +27,7 @@ * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sub license, and/or + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimisc.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimisc.c new file mode 100644 index 000000000..080ba715c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimisc.c @@ -0,0 +1,81 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimisc.c,v 1.1 2000/10/30 23:02:12 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * 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 Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef XFree86LOADER + +#include "ati.h" +#include "ativersion.h" + +/* Module loader interface for subsidiary driver module */ + +static XF86ModuleVersionInfo ATIVersionRec = +{ + ATI_DRIVER_NAME, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + ATI_VERSION_MAJOR, ATI_VERSION_MINOR, ATI_VERSION_PATCH, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +/* + * ATISetup -- + * + * This function is called every time the module is loaded. + */ +static pointer +ATISetup +( + pointer Module, + pointer Options, + int *ErrorMajor, + int *ErrorMinor +) +{ + static Bool Inited = FALSE; + + if (!Inited) + { + /* Ensure main driver module is loaded, but not as a submodule */ + if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME)) + xf86LoadOneModule(ATI_DRIVER_NAME, Options); + + Inited = TRUE; + } + + return (pointer)TRUE; +} + +/* The following record must be called atimiscModuleData */ +XF86ModuleData atimiscModuleData = +{ + &ATIVersionRec, + ATISetup, + NULL +}; + +#endif /* XFree86LOADER */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c index 80cc29a5b..34f9723fd 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c,v 1.9 2000/10/13 13:27:00 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c,v 1.11 2000/11/02 16:55:28 tsi Exp $ */ /* * Copyright 1997 through 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca * @@ -24,11 +24,52 @@ #ifdef XFree86LOADER #include "ati.h" -#include "atistruct.h" +#include "atimodule.h" #include "ativersion.h" /* Module loader interface */ +const char *ATISymbols[] = +{ + "ATIPreInit", + "ATIScreenInit", + "ATISwitchMode", + "ATIAdjustFrame", + "ATIEnterVT", + "ATILeaveVT", + "ATIFreeScreen", + "ATIValidMode", + NULL +}; + +const char *R128Symbols[] = +{ + "R128PreInit", + "R128ScreenInit", + "R128SwitchMode", + "R128AdjustFrame", + "R128EnterVT", + "R128LeaveVT", + "R128FreeScreen", + "R128ValidMode", + "R128Options", + NULL +}; + +const char *RADEONSymbols[] = +{ + "RADEONPreInit", + "RADEONScreenInit", + "RADEONSwitchMode", + "RADEONAdjustFrame", + "RADEONEnterVT", + "RADEONLeaveVT", + "RADEONFreeScreen", + "RADEONValidMode", + "RADEONOptions", + NULL +}; + static XF86ModuleVersionInfo ATIVersionRec = { ATI_DRIVER_NAME, @@ -64,12 +105,14 @@ ATISetup Inited = TRUE; xf86AddDriver(&ATI, Module, 0); - return (pointer)TRUE; + LoaderRefSymLists( + ATISymbols, + R128Symbols, + RADEONSymbols, + NULL); } - if (ErrorMajor) - *ErrorMajor = LDR_ONCEONLY; - return NULL; + return (pointer)1; } /* The following record must be called atiModuleData */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h index f09f04a78..8197d9c69 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h,v 1.4 2000/08/04 21:07:14 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h,v 1.6 2000/11/02 16:55:28 tsi Exp $ */ /* * Copyright 1997 through 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca * @@ -24,11 +24,8 @@ #if defined(XFree86LOADER) && !defined(___ATIMODULE_H___) #define ___ATIMODULE_H___ 1 -#include "atipriv.h" -#include "atiproto.h" - -#include "xf86str.h" - -extern Bool ATILoadModules FunctionPrototype((ScrnInfoPtr, ATIPtr)); +extern const char *ATISymbols[]; +extern const char *R128Symbols[]; +extern const char *RADEONSymbols[]; #endif /* ___ATIMODULE_H___ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c index d2b8c70c5..044e4a083 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c,v 1.12 2000/10/11 22:52:57 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c,v 1.13 2000/11/02 16:55:28 tsi Exp $ */ /* * Copyright 1999 through 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca * @@ -24,6 +24,9 @@ #include "atioption.h" #include "atiutil.h" +#include "radeon_probe.h" +#include "r128_probe.h" + /* * Recognised XF86Config options. */ @@ -108,5 +111,13 @@ ATIAvailableOptions int BusId /* Ignored */ ) { + OptionInfoPtr pOptions; + + if ((pOptions = R128AvailableOptions(ChipId, BusId))) + return pOptions; + + if ((pOptions = RADEONAvailableOptions(ChipId, BusId))) + return pOptions; + return ATIPublicOptions; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c index c0b6719ea..773e67dba 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c,v 1.31 2000/10/26 11:47:46 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c,v 1.35 2000/11/03 03:42:27 tsi Exp $ */ /* * Copyright 1997 through 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca * @@ -30,6 +30,7 @@ #include "aticonsole.h" #include "atiident.h" #include "atimach64io.h" +#include "atimodule.h" #include "atipreinit.h" #include "atiprobe.h" #include "atiscreen.h" @@ -38,6 +39,11 @@ #include "atividmem.h" #include "atiwonderio.h" +#include "radeon_probe.h" +#include "radeon_version.h" +#include "r128_probe.h" +#include "r128_version.h" + /* * NOTES: * @@ -52,7 +58,7 @@ * largely ignored. */ -/* Used a temporary buffer */ +/* Used as a temporary buffer */ #define Identifier ((char *)(pATI->MMIOCache)) /* @@ -175,8 +181,7 @@ ATICheckSparseIOBases /* User might wish to override this decision */ xf86Msg(X_WARNING, - ATI_NAME ": Sparse I/O base 0x%04X not probed.\n", - IOBase); + ATI_NAME ": Sparse I/O base 0x%04X not probed.\n", IOBase); return Allowed; } } @@ -974,8 +979,9 @@ ATIProbe ScrnInfoPtr pScreenInfo; CARD32 PciReg; Bool ProbeSuccess = FALSE; + Bool DoRage128 = FALSE, DoRadeon = FALSE; int i, j, k; - int nGDev, nATIGDev = 0, nATIPtr = 0; + int nGDev, nATIGDev = -1, nATIPtr = 0; int Chipset; ATIChipType Chip; @@ -1009,6 +1015,12 @@ ATIProbe (_p)->iEntity = -2; \ } while (0) +#ifndef AVOID_CPIO + + (void)memset(fChipsets, FALSE, SizeOf(fChipsets)); + +#endif /* AVOID_CPIO */ + if (!(flags & PROBE_DETECT)) { /* @@ -1018,64 +1030,63 @@ ATIProbe * "ChipID" not recognised by the driver. Those device sections that * specify a "ChipRev" without a "ChipID" are also weeded out. */ - if ((nGDev = xf86MatchDevice(ATI_NAME, &GDevs)) <= 0) - return FALSE; - - ATIGDevs = (ATIGDevPtr)xnfcalloc(nGDev, SizeOf(ATIGDev)); - -#ifndef AVOID_CPIO - - (void)memset(fChipsets, FALSE, SizeOf(fChipsets)); - -#endif /* AVOID_CPIO */ - - for (i = 0, pATIGDev = ATIGDevs; i < nGDev; i++) + nATIGDev = 0; + if ((nGDev = xf86MatchDevice(ATI_NAME, &GDevs)) > 0) { - pGDev = GDevs[i]; - Chipset = ATIIdentProbe(pGDev->chipset); - if (Chipset == -1) - continue; - - if ((pGDev->chipID > (int)((CARD16)(-1))) || - (pGDev->chipRev > (int)((CARD8)(-1)))) - continue; + ATIGDevs = (ATIGDevPtr)xnfcalloc(nGDev, SizeOf(ATIGDev)); - if (pGDev->chipID >= 0) + for (i = 0, pATIGDev = ATIGDevs; i < nGDev; i++) { - if (ATIChipID(pGDev->chipID, 0) == ATI_CHIP_Mach64) + pGDev = GDevs[i]; + Chipset = ATIIdentProbe(pGDev->chipset); + if (Chipset == -1) continue; - } - else - { - if (pGDev->chipRev >= 0) + + if ((pGDev->chipID > (int)((CARD16)(-1))) || + (pGDev->chipRev > (int)((CARD8)(-1)))) continue; - } - pATIGDev->pGDev = pGDev; - pATIGDev->Chipset = Chipset; - nATIGDev++; - pATIGDev++; + if (pGDev->chipID >= 0) + { + if (ATIChipID(pGDev->chipID, 0) == ATI_CHIP_Mach64) + continue; + } + else + { + if (pGDev->chipRev >= 0) + continue; + } - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": Candidate \"Device\" section \"%s\".\n", - pGDev->identifier); + pATIGDev->pGDev = pGDev; + pATIGDev->Chipset = Chipset; + nATIGDev++; + pATIGDev++; + + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": Candidate \"Device\" section \"%s\".\n", + pGDev->identifier); #ifndef AVOID_CPIO - fChipsets[Chipset] = TRUE; + fChipsets[Chipset] = TRUE; #endif /* AVOID_CPIO */ - } + } - xfree(GDevs); + xfree(GDevs); - /* If no device sections remain, return now */ - if (!nATIGDev) - { - xfree(ATIGDevs); - return FALSE; + if (!nATIGDev) + { + xfree(ATIGDevs); + ATIGDevs = NULL; + } } + + if (xf86MatchDevice(R128_NAME, NULL) > 0) + DoRage128 = TRUE; + if (xf86MatchDevice(RADEON_NAME, NULL) > 0) + DoRadeon = TRUE; } #ifndef AVOID_CPIO @@ -1105,428 +1116,448 @@ ATIProbe * same I/O ports as 8514/A's or ATI sparse I/O devices without registering * them in PCI configuration space. */ - if (xf86PciVideoInfo) + if (nATIGDev) { - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + if (xf86PciVideoInfo) { - if (pVideo->vendor != PCI_VENDOR_ATI) + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) { - pPCI = pVideo->thisCard; + if (pVideo->vendor != PCI_VENDOR_ATI) + { + pPCI = pVideo->thisCard; - ATIScanPCIBases(&PCIPorts, &nPCIPort, - &pPCI->pci_base0, pVideo->size, - (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) & - PCI_CMD_IO_ENABLE) ? 0 : Allowed); + ATIScanPCIBases(&PCIPorts, &nPCIPort, + &pPCI->pci_base0, pVideo->size, + (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) & + PCI_CMD_IO_ENABLE) ? 0 : Allowed); + } } } - } - /* Check non-video PCI devices for I/O bases */ - if (xf86PciInfo) - { - for (i = 0; (pPCI = xf86PciInfo[i++]); ) + /* Check non-video PCI devices for I/O bases */ + if (xf86PciInfo) { - if ((pPCI->pci_vendor != PCI_VENDOR_ATI) && - (pPCI->pci_base_class != PCI_CLASS_BRIDGE) && - !(pPCI->pci_header_type & - ~GetByte(PCI_HEADER_MULTIFUNCTION, 2))) + for (i = 0; (pPCI = xf86PciInfo[i++]); ) { - ATIScanPCIBases(&PCIPorts, &nPCIPort, - &pPCI->pci_base0, pPCI->basesize, - (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) & - PCI_CMD_IO_ENABLE) ? 0 : Allowed); + if ((pPCI->pci_vendor != PCI_VENDOR_ATI) && + (pPCI->pci_base_class != PCI_CLASS_BRIDGE) && + !(pPCI->pci_header_type & + ~GetByte(PCI_HEADER_MULTIFUNCTION, 2))) + { + ATIScanPCIBases(&PCIPorts, &nPCIPort, + &pPCI->pci_base0, pPCI->basesize, + (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) & + PCI_CMD_IO_ENABLE) ? 0 : Allowed); + } } } - } - - /* Generate ProbeFlags array from list of registered PCI I/O bases */ - (void)memset(ProbeFlags, Allowed | DoProbe, SizeOf(ProbeFlags)); - for (i = 0; i < nPCIPort; i++) - { - CARD32 Base = PCIPorts[i].Base; - CARD16 Count = (1 << PCIPorts[i].Size) - 1; - CARD8 ProbeFlag = PCIPorts[i].Flag; - /* - * The following reduction of Count is based on the assumption that - * PCI-registered I/O port ranges do not overlap. - */ - for (j = 0; j < nPCIPort; j++) + /* Generate ProbeFlags array from list of registered PCI I/O bases */ + (void)memset(ProbeFlags, Allowed | DoProbe, SizeOf(ProbeFlags)); + for (i = 0; i < nPCIPort; i++) { - CARD32 Base2 = PCIPorts[j].Base; + CARD32 Base = PCIPorts[i].Base; + CARD16 Count = (1 << PCIPorts[i].Size) - 1; + CARD8 ProbeFlag = PCIPorts[i].Flag; - if (Base < Base2) - while ((Base + Count) >= Base2) - Count >>= 1; - } + /* + * The following reduction of Count is based on the assumption that + * PCI-registered I/O port ranges do not overlap. + */ + for (j = 0; j < nPCIPort; j++) + { + CARD32 Base2 = PCIPorts[j].Base; - Base = LongPort(Base); - Count = LongPort((Count | IO_BYTE_SELECT) + 1); - while (Count--) - ProbeFlags[Base++] &= ProbeFlag; - } + if (Base < Base2) + while ((Base + Count) >= Base2) + Count >>= 1; + } - xfree(PCIPorts); + Base = LongPort(Base); + Count = LongPort((Count | IO_BYTE_SELECT) + 1); + while (Count--) + ProbeFlags[Base++] &= ProbeFlag; + } - /* - * A note on probe strategy. I/O and memory response by certain PCI - * devices has been disabled by the common layer at this point, including - * any devices this driver might be interested in. The following does - * sparse I/O probes, followed by block I/O probes. Block I/O probes are - * dictated by what is found to be of interest in PCI configuration space. - * All this will detect ATI adapters that do not implement this - * disablement, pre-PCI or not. - * - * PCI configuration space is then scanned again for ATI devices that - * failed to be detected the first time around. Each such device is probed - * for again, this time with I/O temporarily enabled through PCI. - */ - if (ATICheckSparseIOBases(NULL, ProbeFlags, ATTRX, 16, TRUE) == DoProbe) - { - pATI = ATIVGAProbe(NULL); - if (pATI->Adapter == ATI_ADAPTER_NONE) + xfree(PCIPorts); + + /* + * A note on probe strategy. I/O and memory response by certain PCI + * devices has been disabled by the common layer at this point, + * including any devices this driver might be interested in. The + * following does sparse I/O probes, followed by block I/O probes. + * Block I/O probes are dictated by what is found to be of interest in + * PCI configuration space. All this will detect ATI adapters that do + * not implement this disablement, pre-PCI or not. + * + * PCI configuration space is then scanned again for ATI devices that + * failed to be detected the first time around. Each such device is + * probed for again, this time with I/O temporarily enabled through + * PCI. + */ + if (ATICheckSparseIOBases(NULL, ProbeFlags, ATTRX, 16, TRUE) == + DoProbe) { - xfree(pATI); + pATI = ATIVGAProbe(NULL); + if (pATI->Adapter == ATI_ADAPTER_NONE) + { + xfree(pATI); - xf86MsgVerb(X_INFO, 4, ATI_NAME ": Unshared VGA not detected.\n"); + xf86MsgVerb(X_INFO, 4, + ATI_NAME ": Unshared VGA not detected.\n"); + } + else + { + /* + * Claim all MDA/HGA/CGA/EGA/VGA I/O ports. This might need to + * be more selective. + */ + ATIClaimSparseIOBases(ProbeFlags, MonochromeIOBase, 48, + DetectedVGA); + + pVGA = pATI; + strcpy(Identifier, "Unshared VGA"); + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": %s detected.\n", Identifier); + } } else { - /* - * Claim all MDA/HGA/CGA/EGA/VGA I/O ports. This might need to be - * more selective. - */ - ATIClaimSparseIOBases(ProbeFlags, MonochromeIOBase, 48, - DetectedVGA); - - pVGA = pATI; - strcpy(Identifier, "Unshared VGA"); - xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", Identifier); + xf86MsgVerb(X_INFO, 2, ATI_NAME ": Unshared VGA not probed.\n"); } - } - else - { - xf86MsgVerb(X_INFO, 2, ATI_NAME ": Unshared VGA not probed.\n"); - } - if (ATICheckSparseIOBases(NULL, ProbeFlags, 0x02E8U, 8, - fChipsets[ATI_CHIPSET_IBM8514] || - fChipsets[ATI_CHIPSET_MACH8] || - fChipsets[ATI_CHIPSET_MACH32]) == DoProbe) - { - if ((pATI = ATI8514Probe(NULL))) + if (ATICheckSparseIOBases(NULL, ProbeFlags, 0x02E8U, 8, + fChipsets[ATI_CHIPSET_IBM8514] || + fChipsets[ATI_CHIPSET_MACH8] || + fChipsets[ATI_CHIPSET_MACH32]) == DoProbe) { - strcpy(Identifier, "Unshared 8514/A"); - xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", Identifier); + if ((pATI = ATI8514Probe(NULL))) + { + strcpy(Identifier, "Unshared 8514/A"); + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": %s detected.\n", Identifier); - AddAdapter(p8514 = pATI); + AddAdapter(p8514 = pATI); - if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || - (pATI->Coprocessor != ATI_CHIP_NONE)) - ATIClaimVGA(NULL, &pVGA, pATI, p8514, ProbeFlags, - Detected8514A); + if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || + (pATI->Coprocessor != ATI_CHIP_NONE)) + ATIClaimVGA(NULL, &pVGA, pATI, p8514, ProbeFlags, + Detected8514A); - ATIClaimSparseIOBases(ProbeFlags, 0x02E8U, 8, Detected8514A); + ATIClaimSparseIOBases(ProbeFlags, 0x02E8U, 8, Detected8514A); + } + else + { + xf86MsgVerb(X_INFO, 4, + ATI_NAME ": Unshared 8514/A not detected.\n"); + } } else { - xf86MsgVerb(X_INFO, 4, - ATI_NAME ": Unshared 8514/A not detected.\n"); - } - } - else - { - xf86MsgVerb(X_INFO, 2, ATI_NAME ": Unshared 8514/A not probed.\n"); - } - - for (i = 0; i < NumberOf(Mach64SparseIOBases); i++) - { - if (ATICheckSparseIOBases(NULL, ProbeFlags, Mach64SparseIOBases[i], 4, - fChipsets[ATI_CHIPSET_MACH64]) != DoProbe) - { xf86MsgVerb(X_INFO, 2, - ATI_NAME ": Unshared Mach64 at PIO base 0x%04X not probed.\n", - Mach64SparseIOBases[i]); - continue; + ATI_NAME ": Unshared 8514/A not probed.\n"); } - pATI = ATIMach64Probe(NULL, Mach64SparseIOBases[i], SPARSE_IO, 0); - if (!pATI) + for (i = 0; i < NumberOf(Mach64SparseIOBases); i++) { - xf86MsgVerb(X_INFO, 4, - ATI_NAME ": Unshared Mach64 at PIO base 0x%04X not" - " detected.\n", Mach64SparseIOBases[i]); - continue; - } + if (ATICheckSparseIOBases(NULL, ProbeFlags, Mach64SparseIOBases[i], + 4, fChipsets[ATI_CHIPSET_MACH64]) != DoProbe) + { + xf86MsgVerb(X_INFO, 2, + ATI_NAME ": Unshared Mach64 at PIO base 0x%04X not" + " probed.\n", + Mach64SparseIOBases[i]); + continue; + } - sprintf(Identifier, "Unshared Mach64 at sparse PIO base 0x%04X", - Mach64SparseIOBases[i]); - xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", Identifier); + pATI = ATIMach64Probe(NULL, Mach64SparseIOBases[i], SPARSE_IO, 0); + if (!pATI) + { + xf86MsgVerb(X_INFO, 4, + ATI_NAME ": Unshared Mach64 at PIO base 0x%04X not" + " detected.\n", Mach64SparseIOBases[i]); + continue; + } + + sprintf(Identifier, "Unshared Mach64 at sparse PIO base 0x%04X", + Mach64SparseIOBases[i]); + xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", Identifier); - AddAdapter(pMach64[i] = pATI); + AddAdapter(pMach64[i] = pATI); - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIClaimVGA(NULL, &pVGA, pATI, p8514, ProbeFlags, DetectedMach64); + if (pATI->VGAAdapter != ATI_ADAPTER_NONE) + ATIClaimVGA(NULL, &pVGA, pATI, p8514, ProbeFlags, + DetectedMach64); - ATIClaimSparseIOBases(ProbeFlags, Mach64SparseIOBases[i], 4, - DetectedMach64); + ATIClaimSparseIOBases(ProbeFlags, Mach64SparseIOBases[i], 4, + DetectedMach64); + } } #endif /* AVOID_CPIO */ if (xf86PciVideoInfo) { + if (nATIGDev) + { #ifdef AVOID_CPIO - /* PCI sparse I/O adapters can still be used through MMIO */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - IsATIBlockIOBase(pVideo->ioBase[1])) - continue; + /* PCI sparse I/O adapters can still be used through MMIO */ + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + { + if ((pVideo->vendor != PCI_VENDOR_ATI) || + (pVideo->chipType == PCI_CHIP_MACH32) || + IsATIBlockIOBase(pVideo->ioBase[1])) + continue; - pPCI = pVideo->thisCard; - PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); + pPCI = pVideo->thisCard; + PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); - /* Possibly fix block I/O indicator */ - if (PciReg & 0x00000004U) - pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, - PciReg & ~0x00000004U); + /* Possibly fix block I/O indicator */ + if (PciReg & 0x00000004U) + pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, + PciReg & ~0x00000004U); - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); + Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); - /* The CPIO base used by the adapter is of little concern here */ - pATI = ATIMach64Probe(pVideo, 0, SPARSE_IO, Chip); - if (!pATI) - continue; + /* + * The CPIO base used by the adapter is of little concern here. + */ + pATI = ATIMach64Probe(pVideo, 0, SPARSE_IO, Chip); + if (!pATI) + continue; - sprintf(Identifier, - "Unshared PCI sparse I/O Mach64 in slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s detected through Block 0 at 0x%08X.\n", - Identifier, pATI->Block0Base); - AddAdapter(pATI); - pATI->PCIInfo = pVideo; - } + sprintf(Identifier, + "Unshared PCI sparse I/O Mach64 in slot %d:%d:%d", + pVideo->bus, pVideo->device, pVideo->func); + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": %s detected through Block 0 at 0x%08X.\n", + Identifier, pATI->Block0Base); + AddAdapter(pATI); + pATI->PCIInfo = pVideo; + } #endif /* AVOID_CPIO */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - !IsATIBlockIOBase(pVideo->ioBase[1])) - continue; - - /* For now, ignore Rage128's */ - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); - if (Chip > ATI_CHIP_Mach64) - continue; + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + { + if ((pVideo->vendor != PCI_VENDOR_ATI) || + (pVideo->chipType == PCI_CHIP_MACH32) || + !IsATIBlockIOBase(pVideo->ioBase[1])) + continue; - pPCI = pVideo->thisCard; + /* For now, ignore Rage128's */ + Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); + if (Chip > ATI_CHIP_Mach64) + continue; - /* Possibly fix block I/O indicator in PCI configuration space */ - PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); - if (!(PciReg & 0x00000004U)) - pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, - PciReg | 0x00000004U); + pPCI = pVideo->thisCard; - pATI = ATIMach64Probe(pVideo, pVideo->ioBase[1], BLOCK_IO, Chip); - if (!pATI) - continue; + /* + * Possibly fix block I/O indicator in PCI configuration space. + */ + PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); + if (!(PciReg & 0x00000004U)) + pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, + PciReg | 0x00000004U); + + pATI = + ATIMach64Probe(pVideo, pVideo->ioBase[1], BLOCK_IO, Chip); + if (!pATI) + continue; - sprintf(Identifier, "Unshared PCI/AGP Mach64 in slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", Identifier); - AddAdapter(pATI); + sprintf(Identifier, "Unshared PCI/AGP Mach64 in slot %d:%d:%d", + pVideo->bus, pVideo->device, pVideo->func); + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": %s detected.\n", Identifier); + AddAdapter(pATI); #ifndef AVOID_CPIO - /* This is probably not necessary */ - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIClaimVGA(pVideo, &pVGA, pATI, p8514, - ProbeFlags, DetectedMach64); + /* This is probably not necessary */ + if (pATI->VGAAdapter != ATI_ADAPTER_NONE) + ATIClaimVGA(pVideo, &pVGA, pATI, p8514, + ProbeFlags, DetectedMach64); #endif /* AVOID_CPIO */ - } + } #ifndef AVOID_CPIO - /* - * This is the second pass through PCI configuration space. Much of - * this is verbiage to deal with potential situations that are very - * unlikely to occur in practice. - * - * First, look for non-ATI shareable VGA's. For now, these must the - * primary device. - */ - if (ATICheckSparseIOBases(NULL, ProbeFlags, ATTRX, 16, TRUE) == DoProbe) - { - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + /* + * This is the second pass through PCI configuration space. Much + * of this is verbiage to deal with potential situations that are + * very unlikely to occur in practice. + * + * First, look for non-ATI shareable VGA's. For now, these must + * the primary device. + */ + if (ATICheckSparseIOBases(NULL, ProbeFlags, ATTRX, 16, TRUE) == + DoProbe) { - if ((pVideo->vendor == PCI_VENDOR_ATI) || - !xf86IsPrimaryPci(pVideo)) - continue; + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + { + if ((pVideo->vendor == PCI_VENDOR_ATI) || + !xf86IsPrimaryPci(pVideo)) + continue; - if (!xf86CheckPciSlot(pVideo->bus, - pVideo->device, - pVideo->func)) - continue; + if (!xf86CheckPciSlot(pVideo->bus, + pVideo->device, + pVideo->func)) + continue; - xf86SetPciVideo(pVideo, MEM_IO); + xf86SetPciVideo(pVideo, MEM_IO); - pATI = ATIVGAProbe(NULL); - if (pATI->Adapter == ATI_ADAPTER_NONE) - { - xfree(pATI); - xf86Msg(X_WARNING, + pATI = ATIVGAProbe(NULL); + if (pATI->Adapter == ATI_ADAPTER_NONE) + { + xfree(pATI); + xf86Msg(X_WARNING, ATI_NAME ": PCI/AGP VGA compatible in slot" " %d:%d:%d could not be detected!\n", pVideo->bus, pVideo->device, pVideo->func); - } - else - { - sprintf(Identifier, - "Shared non-ATI VGA in PCI/AGP slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", - Identifier); - AddAdapter(pATI); - pATI->SharedVGA = TRUE; - pATI->BusType = ATI_BUS_PCI; - pATI->PCIInfo = pVideo; - } + } + else + { + sprintf(Identifier, + "Shared non-ATI VGA in PCI/AGP slot %d:%d:%d", + pVideo->bus, pVideo->device, pVideo->func); + xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", + Identifier); + AddAdapter(pATI); + pATI->SharedVGA = TRUE; + pATI->BusType = ATI_BUS_PCI; + pATI->PCIInfo = pVideo; + } - xf86SetPciVideo(NULL, NONE); + xf86SetPciVideo(NULL, NONE); + } } - } - - /* Next, look for PCI Mach32's */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType != PCI_CHIP_MACH32)) - continue; - switch (ATICheckSparseIOBases(pVideo, ProbeFlags, - 0x02E8U, 8, TRUE)) + /* Next, look for PCI Mach32's */ + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) { - case 0: - xf86Msg(X_WARNING, + if ((pVideo->vendor != PCI_VENDOR_ATI) || + (pVideo->chipType != PCI_CHIP_MACH32)) + continue; + + switch (ATICheckSparseIOBases(pVideo, ProbeFlags, + 0x02E8U, 8, TRUE)) + { + case 0: + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach32 in slot %d:%d:%d will not" " be enabled\n because it conflicts with a" " non-video PCI/AGP device.\n", pVideo->bus, pVideo->device, pVideo->func); - break; + break; - case Detected8514A: - if ((p8514->BusType >= ATI_BUS_PCI) && !p8514->PCIInfo) - p8514->PCIInfo = pVideo; - else - xf86Msg(X_WARNING, + case Detected8514A: + if ((p8514->BusType >= ATI_BUS_PCI) && !p8514->PCIInfo) + p8514->PCIInfo = pVideo; + else + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach32 in slot %d:%d:%d will" " not be enabled\n because it conflicts with" " another %s %s.\n", pVideo->bus, pVideo->device, pVideo->func, ATIBusNames[p8514->BusType], ATIAdapterNames[p8514->Adapter]); - break; + break; - case DetectedMach64: - xf86Msg(X_WARNING, + case DetectedMach64: + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach32 in slot %d:%d:%d will not" - " be enabled\n because it conflicts with a" - " Mach64 at I/O base 0x02EC.\n", + " be enabled\n because it conflicts with a Mach64" + " at I/O base 0x02EC.\n", pVideo->bus, pVideo->device, pVideo->func); - break; + break; - default: /* Must be DoProbe */ - if (!xf86CheckPciSlot(pVideo->bus, - pVideo->device, - pVideo->func)) - continue; + default: /* Must be DoProbe */ + if (!xf86CheckPciSlot(pVideo->bus, + pVideo->device, + pVideo->func)) + continue; - xf86SetPciVideo(pVideo, MEM_IO); + xf86SetPciVideo(pVideo, MEM_IO); - if (!(pATI = ATI8514Probe(pVideo))) - xf86Msg(X_WARNING, + if (!(pATI = ATI8514Probe(pVideo))) + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach32 in slot %d:%d:%d could" " not be detected!\n", pVideo->bus, pVideo->device, pVideo->func); - else - { - sprintf(Identifier, - "Shared 8514/A in PCI slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, ATI_NAME ": %s detected.\n", - Identifier); - if (pATI->Adapter != ATI_ADAPTER_MACH32) - xf86Msg(X_WARNING, + else + { + sprintf(Identifier, + "Shared 8514/A in PCI slot %d:%d:%d", + pVideo->bus, pVideo->device, pVideo->func); + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": %s detected.\n", Identifier); + if (pATI->Adapter != ATI_ADAPTER_MACH32) + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach32 in slot %d:%d:%d" " could only be detected as an %s!\n", pVideo->bus, pVideo->device, pVideo->func, ATIAdapterNames[pATI->Adapter]); - AddAdapter(pATI); - pATI->SharedAccelerator = TRUE; + AddAdapter(pATI); + pATI->SharedAccelerator = TRUE; - if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || - (pATI->Coprocessor != ATI_CHIP_NONE)) - ATIFindVGA(pVideo, &pVGA, &pATI, p8514, - ProbeFlags); - } + if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) || + (pATI->Coprocessor != ATI_CHIP_NONE)) + ATIFindVGA(pVideo, &pVGA, &pATI, p8514, + ProbeFlags); + } - xf86SetPciVideo(NULL, NONE); - break; + xf86SetPciVideo(NULL, NONE); + break; + } } - } - /* Next, look for sparse I/O Mach64's */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - IsATIBlockIOBase(pVideo->ioBase[1])) - continue; + /* Next, look for sparse I/O Mach64's */ + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) + { + if ((pVideo->vendor != PCI_VENDOR_ATI) || + (pVideo->chipType == PCI_CHIP_MACH32) || + IsATIBlockIOBase(pVideo->ioBase[1])) + continue; - pPCI = pVideo->thisCard; - PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); - j = PciReg & 0x03U; - if (j == 0x03U) - xf86Msg(X_WARNING, + pPCI = pVideo->thisCard; + PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG); + j = PciReg & 0x03U; + if (j == 0x03U) + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach64 in slot %d:%d:%d cannot be" " enabled\n because it has neither a block, nor a" " sparse, I/O base.\n", pVideo->bus, pVideo->device, pVideo->func); - else switch(ATICheckSparseIOBases(pVideo, ProbeFlags, - Mach64SparseIOBases[j], 4, TRUE)) - { - case 0: - xf86Msg(X_WARNING, + else switch(ATICheckSparseIOBases(pVideo, ProbeFlags, + Mach64SparseIOBases[j], 4, TRUE)) + { + case 0: + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach64 in slot %d:%d:%d will not" " be enabled\n because it conflicts with another" " non-video PCI device.\n", pVideo->bus, pVideo->device, pVideo->func); - break; + break; - case Detected8514A: - xf86Msg(X_WARNING, + case Detected8514A: + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach64 in slot %d:%d:%d will not" " be enabled\n because it conflicts with an %s.\n", pVideo->bus, pVideo->device, pVideo->func, ATIAdapterNames[p8514->Adapter]); - break; + break; - case DetectedMach64: - pATI = pMach64[j]; - if ((pATI->BusType >= ATI_BUS_PCI) && !pATI->PCIInfo) - pATI->PCIInfo = pVideo; - else - xf86Msg(X_WARNING, + case DetectedMach64: + pATI = pMach64[j]; + if ((pATI->BusType >= ATI_BUS_PCI) && !pATI->PCIInfo) + pATI->PCIInfo = pVideo; + else + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach64 in slot %d:%d:%d will" " not be enabled\n because it conflicts with" " another %s Mach64 at sparse I/O base" @@ -1534,105 +1565,108 @@ ATIProbe pVideo->bus, pVideo->device, pVideo->func, ATIBusNames[pATI->BusType], Mach64SparseIOBases[j]); - break; + break; - default: /* Must be DoProbe */ - if (!xf86CheckPciSlot(pVideo->bus, - pVideo->device, - pVideo->func)) - continue; + default: /* Must be DoProbe */ + if (!xf86CheckPciSlot(pVideo->bus, + pVideo->device, + pVideo->func)) + continue; - /* Possibly fix block I/O indicator */ - if (PciReg & 0x00000004U) - pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, - PciReg & ~0x00000004U); + /* Possibly fix block I/O indicator */ + if (PciReg & 0x00000004U) + pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG, + PciReg & ~0x00000004U); - xf86SetPciVideo(pVideo, MEM_IO); + xf86SetPciVideo(pVideo, MEM_IO); - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); - pATI = ATIMach64Probe(pVideo, Mach64SparseIOBases[j], - SPARSE_IO, Chip); - if (!pATI) - xf86Msg(X_WARNING, + Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); + pATI = ATIMach64Probe(pVideo, Mach64SparseIOBases[j], + SPARSE_IO, Chip); + if (!pATI) + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach64 in slot %d:%d:%d could" " not be detected!\n", pVideo->bus, pVideo->device, pVideo->func); - else - { - sprintf(Identifier, - "Shared PCI Mach64 in slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s with sparse PIO base 0x%04X" - " detected.\n", Identifier, - Mach64SparseIOBases[j]); - AddAdapter(pATI); - pATI->SharedAccelerator = TRUE; - pATI->PCIInfo = pVideo; + else + { + sprintf(Identifier, + "Shared PCI Mach64 in slot %d:%d:%d", + pVideo->bus, pVideo->device, pVideo->func); + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": %s with sparse PIO base 0x%04X" + " detected.\n", Identifier, + Mach64SparseIOBases[j]); + AddAdapter(pATI); + pATI->SharedAccelerator = TRUE; + pATI->PCIInfo = pVideo; - if (pATI->VGAAdapter != ATI_ADAPTER_NONE) - ATIFindVGA(pVideo, &pVGA, &pATI, p8514, - ProbeFlags); - } + if (pATI->VGAAdapter != ATI_ADAPTER_NONE) + ATIFindVGA(pVideo, &pVGA, &pATI, p8514, + ProbeFlags); + } - xf86SetPciVideo(NULL, NONE); - break; + xf86SetPciVideo(NULL, NONE); + break; + } } - } #else /* AVOID_CPIO */ - for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) - { - if ((pVideo->vendor != PCI_VENDOR_ATI) || - (pVideo->chipType == PCI_CHIP_MACH32) || - IsATIBlockIOBase(pVideo->ioBase[1])) - continue; - - /* Check if this one has already been detected */ - for (j = 0; j < nATIPtr; j++) + for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) { - pATI = ATIPtrs[j]; - if (pATI->PCIInfo == pVideo) - goto SkipThisSlot; - } + if ((pVideo->vendor != PCI_VENDOR_ATI) || + (pVideo->chipType == PCI_CHIP_MACH32) || + IsATIBlockIOBase(pVideo->ioBase[1])) + continue; - if (!xf86CheckPciSlot(pVideo->bus, pVideo->device, pVideo->func)) - continue; + /* Check if this one has already been detected */ + for (j = 0; j < nATIPtr; j++) + { + pATI = ATIPtrs[j]; + if (pATI->PCIInfo == pVideo) + goto SkipThisSlot; + } - xf86SetPciVideo(pVideo, MEM_IO); + if (!xf86CheckPciSlot(pVideo->bus, + pVideo->device, + pVideo->func)) + continue; - Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); + xf86SetPciVideo(pVideo, MEM_IO); - /* The adapter's CPIO base is of little concern here */ - pATI = ATIMach64Probe(pVideo, 0, SPARSE_IO, Chip); - if (pATI) - { - sprintf(Identifier, "Shared PCI Mach64 in slot %d:%d:%d", - pVideo->bus, pVideo->device, pVideo->func); - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s with Block 0 base 0x%08X detected.\n", - Identifier, pATI->Block0Base); - AddAdapter(pATI); - pATI->SharedAccelerator = TRUE; - pATI->PCIInfo = pVideo; - } - else - { - xf86Msg(X_WARNING, + Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); + + /* The adapter's CPIO base is of little concern here */ + pATI = ATIMach64Probe(pVideo, 0, SPARSE_IO, Chip); + if (pATI) + { + sprintf(Identifier, "Shared PCI Mach64 in slot %d:%d:%d", + pVideo->bus, pVideo->device, pVideo->func); + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": %s with Block 0 base 0x%08X detected.\n", + Identifier, pATI->Block0Base); + AddAdapter(pATI); + pATI->SharedAccelerator = TRUE; + pATI->PCIInfo = pVideo; + } + else + { + xf86Msg(X_WARNING, ATI_NAME ": PCI Mach64 in slot %d:%d:%d could not be" " detected!\n", pVideo->bus, pVideo->device, pVideo->func); - } - - xf86SetPciVideo(NULL, NONE); + } + xf86SetPciVideo(NULL, NONE); - SkipThisSlot:; - } + SkipThisSlot:; + } #endif /* AVOID_CPIO */ + } + /* Lastly, look for block I/O devices */ for (i = 0; (pVideo = xf86PciVideoInfo[i++]); ) { @@ -1641,9 +1675,32 @@ ATIProbe !IsATIBlockIOBase(pVideo->ioBase[1])) continue; - /* For now, ignore Rage128's */ + /* Check for Rage128's, Radeon's and later adapters */ Chip = ATIChipID(pVideo->chipType, pVideo->chipRev); if (Chip > ATI_CHIP_Mach64) + { + switch (Chip) + { + case ATI_CHIP_RAGE128GL: + case ATI_CHIP_RAGE128VR: + case ATI_CHIP_RAGE128PROGL: + case ATI_CHIP_RAGE128PROVR: + case ATI_CHIP_RAGE128MOBILITY3: + case ATI_CHIP_RAGE128MOBILITY4: + DoRage128 = TRUE; + continue; + + case ATI_CHIP_RADEON: + DoRadeon = TRUE; + continue; + + case ATI_CHIP_HDTV: + default: + continue; + } + } + + if (!nATIGDev) continue; /* Check if this one has already been detected */ @@ -1684,9 +1741,8 @@ ATIProbe if (!pATI) { xf86Msg(X_WARNING, - ATI_NAME ": PCI/AGP Mach64 in slot %d:%d:%d could not" - " be detected!\n", - pVideo->bus, pVideo->device, pVideo->func); + ATI_NAME ": PCI/AGP Mach64 in slot %d:%d:%d could not be" + " detected!\n", pVideo->bus, pVideo->device, pVideo->func); continue; } @@ -1703,7 +1759,7 @@ ATIProbe */ do { - if (!pVGA || (pVGA->VGAAdapter > ATI_ADAPTER_VGA)) + if (!nATIGDev || !pVGA || (pVGA->VGAAdapter > ATI_ADAPTER_VGA)) break; /* If it has not been assigned to a coprocessor, keep track of it */ @@ -1865,13 +1921,6 @@ NoVGAWonder:; #endif /* AVOID_CPIO */ - /* If no appropriate adapters have been detected, return now */ - if (!nATIPtr) - { - xfree(ATIGDevs); - return FALSE; - } - /* * Re-order list of detected devices so that the primary device is before * any other PCI device. @@ -1931,296 +1980,326 @@ NoVGAWonder:; xfree(pATI); } - - xfree(ATIPtrs); - return ProbeSuccess; } - - /* - * Assign detected devices to XF86Config Device sections. This is done by - * comparing certain Device section specifications against the - * corresponding adapter information. Begin with those specifications that - * are independent of the adapter's bus location. - */ - for (i = 0, pATIGDev = ATIGDevs; i < nATIGDev; i++, pATIGDev++) + else { - pGDev = pATIGDev->pGDev; - - for (j = 0; j < nATIPtr; j++) + /* + * Assign detected devices to XF86Config Device sections. This is done + * by comparing certain Device section specifications against the + * corresponding adapter information. Begin with those specifications + * that are independent of the adapter's bus location. + */ + for (i = 0, pATIGDev = ATIGDevs; i < nATIGDev; i++, pATIGDev++) { - pATI = ATIPtrs[j]; + pGDev = pATIGDev->pGDev; - /* - * First check the Chipset specification. The placement of "break" - * and "continue" statements here is carefully chosen to produce - * the intended behaviour for each Chipset value. - */ - switch (pATIGDev->Chipset) + for (j = 0; j < nATIPtr; j++) { - case ATI_CHIPSET_ATI: - -#ifndef AVOID_CPIO + pATI = ATIPtrs[j]; - if (pATI->Adapter == ATI_ADAPTER_VGA) - continue; - if (pATI->Adapter != ATI_ADAPTER_8514A) - break; - /* Fall through */ + /* + * First check the Chipset specification. The placement of + * "break" and "continue" statements here is carefully chosen + * to produce the intended behaviour for each Chipset value. + */ + switch (pATIGDev->Chipset) + { + case ATI_CHIPSET_ATI: - case ATI_CHIPSET_ATIVGA: - if (pATI->VGAAdapter == ATI_ADAPTER_VGA) - continue; - /* Fall through */ +#ifndef AVOID_CPIO - case ATI_CHIPSET_IBMVGA: - if (pATI->VGAAdapter == ATI_ADAPTER_NONE) - continue; - break; + if (pATI->Adapter == ATI_ADAPTER_VGA) + continue; + if (pATI->Adapter != ATI_ADAPTER_8514A) + break; + /* Fall through */ - case ATI_CHIPSET_VGAWONDER: - if (!pATI->CPIO_VGAWonder) - continue; - break; + case ATI_CHIPSET_ATIVGA: + if (pATI->VGAAdapter == ATI_ADAPTER_VGA) + continue; + /* Fall through */ - case ATI_CHIPSET_IBM8514: - if (pATI->Adapter == ATI_ADAPTER_8514A) + case ATI_CHIPSET_IBMVGA: + if (pATI->VGAAdapter == ATI_ADAPTER_NONE) + continue; break; - /* Fall through */ - case ATI_CHIPSET_MACH8: - if (pATI->Adapter == ATI_ADAPTER_MACH8) + case ATI_CHIPSET_VGAWONDER: + if (!pATI->CPIO_VGAWonder) + continue; break; - /* Fall through */ - case ATI_CHIPSET_MACH32: - if (pATI->Adapter == ATI_ADAPTER_MACH32) - break; - continue; + case ATI_CHIPSET_IBM8514: + if (pATI->Adapter == ATI_ADAPTER_8514A) + break; + /* Fall through */ -#endif /* AVOID_CPIO */ + case ATI_CHIPSET_MACH8: + if (pATI->Adapter == ATI_ADAPTER_MACH8) + break; + /* Fall through */ - case ATI_CHIPSET_MACH64: - if (pATI->Adapter == ATI_ADAPTER_MACH64) - break; - continue; + case ATI_CHIPSET_MACH32: + if (pATI->Adapter == ATI_ADAPTER_MACH32) + break; + continue; - default: - continue; - } +#endif /* AVOID_CPIO */ - /* - * The ChipID and ChipRev specifications are compared next. First, - * require these to be unspecified for anything other than Mach32 - * or Mach64 adapters. ChipRev is also required to be unspecified - * for Mach32's. ChipID is optional for Mach32's, and both - * specifications are optional for Mach64's. Lastly, allow both - * specifications to override their detected value in the case of - * Mach64 adapters whose ChipID is unrecognised. - */ - if (pGDev->chipID >= 0) - { - if (pATI->ChipType != pGDev->chipID) - { - if ((pATI->Adapter != ATI_ADAPTER_MACH64) || - (pATI->Chip != ATI_CHIP_Mach64)) + case ATI_CHIPSET_MACH64: + if (pATI->Adapter == ATI_ADAPTER_MACH64) + break; continue; - Chip = ATIChipID(pGDev->chipID, 0); - if ((Chip <= ATI_CHIP_264GTB) || (Chip == ATI_CHIP_Mach64)) + default: continue; } - if ((pGDev->chipRev >= 0) && (pATI->ChipRev != pGDev->chipRev)) - { - if (pATI->Adapter != ATI_ADAPTER_MACH64) - continue; - if (pATI->Chip != ATI_CHIP_Mach64) + /* + * The ChipID and ChipRev specifications are compared next. + * First, require these to be unspecified for anything other + * than Mach32 or Mach64 adapters. ChipRev is also required to + * be unspecified for Mach32's. ChipID is optional for + * Mach32's, and both specifications are optional for Mach64's. + * Lastly, allow both specifications to override their detected + * value in the case of Mach64 adapters whose ChipID is + * unrecognised. + */ + if (pGDev->chipID >= 0) + { + if (pATI->ChipType != pGDev->chipID) { - if (pATI->ChipRev == pATI->ChipRevision) + if ((pATI->Adapter != ATI_ADAPTER_MACH64) || + (pATI->Chip != ATI_CHIP_Mach64)) continue; - /* - * There are two foundry codes for UMC. Some adapters - * will advertise one in CONFIG_CHIP_ID and the other - * in PCI configuration space. For matching purposes, - * make both codes compare equal. - */ -# define UMC_IGNORE (ATI_FOUNDRY_UMC ^ ATI_FOUNDRY_UMCA) -# define UMC_NOCARE \ - GetBits(SetBits(UMC_IGNORE, CFG_CHIP_FOUNDRY), \ - CFG_CHIP_REV) - - if ((pATI->ChipRev ^ pGDev->chipRev) & ~UMC_NOCARE) + Chip = ATIChipID(pGDev->chipID, 0); + if ((Chip <= ATI_CHIP_264GTB) || + (Chip == ATI_CHIP_Mach64)) continue; - - if ((pATI->ChipFoundry != ATI_FOUNDRY_UMC) && - (pATI->ChipFoundry != ATI_FOUNDRY_UMCA)) + } + if ((pGDev->chipRev >= 0) && + (pATI->ChipRev != pGDev->chipRev)) + { + if (pATI->Adapter != ATI_ADAPTER_MACH64) continue; - k = GetBits(pGDev->chipRev, - GetBits(CFG_CHIP_FOUNDRY, CFG_CHIP_REV)); - if ((k != ATI_FOUNDRY_UMC) && (k != ATI_FOUNDRY_UMCA)) - continue; + if (pATI->Chip != ATI_CHIP_Mach64) + { + if (pATI->ChipRev == pATI->ChipRevision) + continue; + + /* + * There are two foundry codes for UMC. Some + * adapters will advertise one in CONFIG_CHIP_ID + * and the other in PCI configuration space. For + * matching purposes, make both codes compare + * equal. + */ +# define UMC_IGNORE \ + (ATI_FOUNDRY_UMC ^ ATI_FOUNDRY_UMCA) +# define UMC_NOCARE \ + GetBits(SetBits(UMC_IGNORE, CFG_CHIP_FOUNDRY), \ + CFG_CHIP_REV) + + if ((pATI->ChipRev ^ pGDev->chipRev) & ~UMC_NOCARE) + continue; + + if ((pATI->ChipFoundry != ATI_FOUNDRY_UMC) && + (pATI->ChipFoundry != ATI_FOUNDRY_UMCA)) + continue; + + k = GetBits(pGDev->chipRev, + GetBits(CFG_CHIP_FOUNDRY, CFG_CHIP_REV)); + if ((k != ATI_FOUNDRY_UMC) && + (k != ATI_FOUNDRY_UMCA)) + continue; + } } } - } - /* - * IOBase is next. This is the first specification that is - * potentially dependent on bus location. It is only allowed for - * Mach64 adapters, and is optional. - */ - if (pGDev->IOBase && (pATI->CPIOBase != pGDev->IOBase)) - continue; + /* + * IOBase is next. This is the first specification that is + * potentially dependent on bus location. It is only allowed + * for Mach64 adapters, and is optional. + */ + if (pGDev->IOBase && (pATI->CPIOBase != pGDev->IOBase)) + continue; - /* - * Compare BusID's. This specification is only allowed for PCI - * Mach32's or Mach64's and is optional. - */ - if (pGDev->busID && pGDev->busID[0]) - { - pVideo = pATI->PCIInfo; + /* + * Compare BusID's. This specification is only allowed for PCI + * Mach32's or Mach64's and is optional. + */ + if (pGDev->busID && pGDev->busID[0]) + { + pVideo = pATI->PCIInfo; #ifndef AVOID_CPIO - if (!pVideo) - continue; + if (!pVideo) + continue; #endif /* AVOID_CPIO */ - if (!xf86ComparePciBusString(pGDev->busID, - pVideo->bus, pVideo->device, pVideo->func)) - continue; - } + if (!xf86ComparePciBusString(pGDev->busID, + pVideo->bus, pVideo->device, pVideo->func)) + continue; + } - /* - * Ensure no two adapters are assigned to the same XF86Config - * Device section. - */ - if (pATIGDev->iATIPtr) - { - if (pATIGDev->iATIPtr < 0) - break; + /* + * Ensure no two adapters are assigned to the same XF86Config + * Device section. + */ + if (pATIGDev->iATIPtr) + { + if (pATIGDev->iATIPtr < 0) + break; - xf86Msg(X_ERROR, + xf86Msg(X_ERROR, ATI_NAME ": XF86Config Device section \"%s\" may not" " be assigned to more than one adapter.\n", pGDev->identifier); - pATIGDev->iATIPtr = -1; - break; - } + pATIGDev->iATIPtr = -1; + break; + } - /* Assign adapter */ - pATIGDev->iATIPtr = j + 1; + /* Assign adapter */ + pATIGDev->iATIPtr = j + 1; - /* - * For compatibility with previous releases, assign the first - * applicable adapter if there is only one Device section. - */ - if (nATIGDev == 1) - break; + /* + * For compatibility with previous releases, assign the first + * applicable adapter if there is only one Device section. + */ + if (nATIGDev == 1) + break; + } } - } - /* - * Ensure no two XF86Config Device sections are assigned to the same - * adapter. Then, generate screens for any that are left. - */ - for (i = 0, pATIGDev = ATIGDevs; i < nATIGDev; i++, pATIGDev++) - { - pGDev = pATIGDev->pGDev; + /* + * Ensure no two XF86Config Device sections are assigned to the same + * adapter. Then, generate screens for any that are left. + */ + for (i = 0, pATIGDev = ATIGDevs; i < nATIGDev; i++, pATIGDev++) + { + pGDev = pATIGDev->pGDev; - j = pATIGDev->iATIPtr; - if (j <= 0) - continue; + j = pATIGDev->iATIPtr; + if (j <= 0) + continue; - for (k = i; ++k < nATIGDev; ) - { - if (j == ATIGDevs[k].iATIPtr) + for (k = i; ++k < nATIGDev; ) { - xf86Msg(X_ERROR, + if (j == ATIGDevs[k].iATIPtr) + { + xf86Msg(X_ERROR, ATI_NAME ": XF86Config Device sections \"%s\" and" " \"%s\" may not be assigned to the same adapter.\n", pGDev->identifier, ATIGDevs[k].pGDev->identifier); - pATIGDev->iATIPtr = ATIGDevs[k].iATIPtr = -1; + pATIGDev->iATIPtr = ATIGDevs[k].iATIPtr = -1; + } } - } - j = ATIGDevs[i].iATIPtr; - if (j <= 0) - continue; + j = ATIGDevs[i].iATIPtr; + if (j <= 0) + continue; - pATI = ATIPtrs[j - 1]; + pATI = ATIPtrs[j - 1]; - xf86MsgVerb(X_INFO, 3, - ATI_NAME ": %s assigned to %sactive \"Device\" section \"%s\".\n", - Identifier, pGDev->active ? "" : "in", pGDev->identifier); + xf86MsgVerb(X_INFO, 3, + ATI_NAME ": %s assigned to %sactive \"Device\" section" + " \"%s\".\n", + Identifier, pGDev->active ? "" : "in", pGDev->identifier); - /* - * Attach adapter to XF86Config Device section and register its - * resources. - */ - if (ATIClaimBusSlot(pDriver, pATIGDev->Chipset, - pGDev, pGDev->active, pATI) < 0) - { - xf86Msg(X_ERROR, ATI_NAME ": Could not claim bus slot for %s.\n", - Identifier); - continue; - } + /* + * Attach adapter to XF86Config Device section and register its + * resources. + */ + if (ATIClaimBusSlot(pDriver, pATIGDev->Chipset, + pGDev, pGDev->active, pATI) < 0) + { + xf86Msg(X_ERROR, + ATI_NAME ": Could not claim bus slot for %s.\n", + Identifier); + continue; + } - if (!pGDev->active) - continue; + if (!pGDev->active) + continue; - /* Allocate screen */ - pScreenInfo = xf86AllocateScreen(pDriver, 0); + /* Allocate screen */ + pScreenInfo = xf86AllocateScreen(pDriver, 0); - /* Attach device to screen */ - xf86AddEntityToScreen(pScreenInfo, pATI->iEntity); +#ifdef XFree86LOADER - ATIPtrs[j - 1] = NULL; + if (!xf86LoadSubModule(pScreenInfo, "atimisc")) + { + xf86Msg(X_ERROR, + ATI_NAME ": Failed to load \"atimisc\" module.\n"); + xf86DeleteScreen(pScreenInfo->scrnIndex, 0); + continue; + } - /* Fill in probe data */ - pScreenInfo->driverVersion = ATI_VERSION_CURRENT; - pScreenInfo->driverName = ATI_DRIVER_NAME; - pScreenInfo->name = ATI_NAME; - pScreenInfo->Probe = ATIProbe; - pScreenInfo->PreInit = ATIPreInit; - pScreenInfo->ScreenInit = ATIScreenInit; - pScreenInfo->SwitchMode = ATISwitchMode; - pScreenInfo->AdjustFrame = ATIAdjustFrame; - pScreenInfo->EnterVT = ATIEnterVT; - pScreenInfo->LeaveVT = ATILeaveVT; - pScreenInfo->FreeScreen = ATIFreeScreen; - pScreenInfo->ValidMode = ATIValidMode; + xf86LoaderReqSymLists(ATISymbols, NULL); +#endif - pScreenInfo->driverPrivate = pATI; + /* Attach device to screen */ + xf86AddEntityToScreen(pScreenInfo, pATI->iEntity); - pATI->Chipset = pATIGDev->Chipset; + ATIPtrs[j - 1] = NULL; - ProbeSuccess = TRUE; - } + /* Fill in probe data */ + pScreenInfo->driverVersion = ATI_VERSION_CURRENT; + pScreenInfo->driverName = ATI_DRIVER_NAME; + pScreenInfo->name = ATI_NAME; + pScreenInfo->Probe = ATIProbe; + pScreenInfo->PreInit = ATIPreInit; + pScreenInfo->ScreenInit = ATIScreenInit; + pScreenInfo->SwitchMode = ATISwitchMode; + pScreenInfo->AdjustFrame = ATIAdjustFrame; + pScreenInfo->EnterVT = ATIEnterVT; + pScreenInfo->LeaveVT = ATILeaveVT; + pScreenInfo->FreeScreen = ATIFreeScreen; + pScreenInfo->ValidMode = ATIValidMode; - /* Deal with unassigned adapters */ - for (i = 0; i < nATIPtr; i++) - { - if (!(pATI = ATIPtrs[i])) - continue; + pScreenInfo->driverPrivate = pATI; + + pATI->Chipset = pATIGDev->Chipset; + + ProbeSuccess = TRUE; + } + + /* Deal with unassigned adapters */ + for (i = 0; i < nATIPtr; i++) + { + if (!(pATI = ATIPtrs[i])) + continue; #ifndef AVOID_CPIO - if (pATI->Adapter > ATI_ADAPTER_VGA) + if (pATI->Adapter > ATI_ADAPTER_VGA) #endif /* AVOID_CPIO */ - { - if (pATI->iEntity < 0) - (void)ATIClaimBusSlot(pDriver, 0, NULL, FALSE, pATI); + { + if (pATI->iEntity < 0) + (void)ATIClaimBusSlot(pDriver, 0, NULL, FALSE, pATI); + } + + xfree(pATI); } - xfree(pATI); + xfree(ATIGDevs); } + xfree(ATIPtrs); - xfree(ATIGDevs); + + /* Call Rage 128 driver probe */ + if (DoRage128 && R128Probe(pDriver, flags)) + ProbeSuccess = TRUE; + + /* Call Radeon driver probe */ + if (DoRadeon && RADEONProbe(pDriver, flags)) + ProbeSuccess = TRUE; return ProbeSuccess; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h index 40b92fbdc..4a31c46d2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h,v 1.24 2000/10/11 22:52:58 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h,v 1.26 2000/11/02 16:55:29 tsi Exp $ */ /* * Copyright 1997 through 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca * @@ -24,14 +24,14 @@ #ifndef ___ATIVERSION_H___ #define ___ATIVERSION_H___ 1 -#define ATI_NAME "ATI" -#define ATI_DRIVER_NAME "ati" +#define ATI_NAME "ATI" +#define ATI_DRIVER_NAME "ati" -#define ATI_VERSION_NAME "6.0.7" +#define ATI_VERSION_NAME "6.2.0" -#define ATI_VERSION_MAJOR 6 -#define ATI_VERSION_MINOR 0 -#define ATI_VERSION_PATCH 7 +#define ATI_VERSION_MAJOR 6 +#define ATI_VERSION_MINOR 2 +#define ATI_VERSION_PATCH 0 #define ATI_VERSION_CURRENT \ ((ATI_VERSION_MAJOR << 20) | (ATI_VERSION_MINOR << 10) | ATI_VERSION_PATCH) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.cpp b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.cpp new file mode 100644 index 000000000..2f5408b34 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.cpp @@ -0,0 +1,70 @@ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.cpp,v 1.1 2000/11/02 16:55:29 tsi Exp $ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH R128 __drivermansuffix__ "Version 4.0.1" "XFree86" +.SH NAME +r128 \- ATI Rage 128 video driver +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" devname \*q +.B " Driver \*qr128\*q" +\ \ ... +.B EndSection +.fi +.SH DESCRIPTION +.B r128 +is an XFree86 driver for ATI Rage 128 based video cards. It contains +full support for 8, 15, 16 and 24 bit pixel depths, hardware +acceleration of drawing primitives, hardware cursor, video modes up to +1800x1440 @ 70Hz, doublescan modes (e.g., 320x200 and 320x240), gamma +correction at all pixel depths, a fully programming dot clock and robust +text mode restoration for VT switching. +.SH SUPPORTED HARDWARE +The +.B r128 +driver supports all ATI Rage 128 based video cards including the Rage +Fury AGP 32MB, the XPERT 128 AGP 16MB and the XPERT 99 AGP 8MB. +.SH CONFIGURATION DETAILS +Please refer to XF86Config(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to this +driver. +.PP +The driver auto-detects all device information necessary to initialize +the card. However, if you have problems with auto-detection, you can +specify: +.PP +.RS 4 +VideoRam - in kilobytes +.br +MemBase - physical address of the linear framebuffer +.br +IOBase - physical address of the MMIO registers +.br +ChipID - PCI DEVICE ID +.RE +.PP +In addition, the following driver +.B Options +are supported: +.TP +.BI "Option \*qSWcursor\*q \*q" boolean \*q +Selects software cursor. The default is +.B off. +.TP +.BI "Option \*qNoAccel\*q \*q" boolean \*q +Enables or disables all hardware acceleration. The default is to +.B enable +hardware acceleration. +.TP +.BI "Option \*qDac6Bit\*q \*q" boolean \*q +Enables or disables the use of 6 bits per color component when in 8 bpp +mode (emulates VGA mode). By default, all 8 bits per color component +are used. The default is +.B off. +.SH "SEE ALSO" +XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__) +.SH AUTHORS +.nf +Rickard E. (Rik) Faith \fIfaith@precisioninsight.com\fP +Kevin E. Martin \fIkevin@precisioninsight.com\fP diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h new file mode 100644 index 000000000..cde3f03f6 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h @@ -0,0 +1,395 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v 1.1 2000/11/02 16:55:29 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_H_ +#define _R128_H_ + + /* Xv support */ +#include "xf86xv.h" +#include "Xv.h" + + /* vgahw module (for VC save/restore only) */ +#include "vgaHW.h" + +#include "fbdevhw.h" + + /* XAA and Cursor Support */ +#include "xaa.h" +#include "xaalocal.h" +#include "xf86Cursor.h" + + + /* PCI support */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + + /* DDC support */ +#include "xf86DDC.h" + + /* VESA support */ +#include "vbe.h" + + /* DRI support */ +#ifdef XF86DRI +#include "GL/glxint.h" +#include "GL/glxtokens.h" +#include "xf86drm.h" +#include "xf86drmR128.h" +#include "sarea.h" +#define _XF86DRI_SERVER_ +#include "xf86dri.h" +#include "dri.h" +#include "r128_dri.h" +#include "r128_dripriv.h" +#include "r128_sarea.h" +#endif + +#ifdef RENDER +#include "picturestr.h" +#endif + +#define R128_DEBUG 0 /* Turn off debugging output */ +#define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */ +#define R128_MMIOSIZE 0x80000 + +#define R128_VBIOS_SIZE 0x00010000 + +#if R128_DEBUG +#define R128TRACE(x) \ + do { \ + ErrorF("(**) %s(%d): ", R128_NAME, pScrn->scrnIndex); \ + ErrorF x; \ + } while (0); +#else +#define R128TRACE(x) +#endif + + +/* Other macros */ +#define R128_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#define R128_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) +#define R128PTR(pScrn) ((R128InfoPtr)(pScrn)->driverPrivate) + +typedef struct { /* All values in XCLKS */ + int ML; /* Memory Read Latency */ + int MB; /* Memory Burst Length */ + int Trcd; /* RAS to CAS delay */ + int Trp; /* RAS percentage */ + int Twr; /* Write Recovery */ + int CL; /* CAS Latency */ + int Tr2w; /* Read to Write Delay */ + int Rloop; /* Loop Latency */ + int Rloop_fudge; /* Add to ML to get Rloop */ + char *name; +} R128RAMRec, *R128RAMPtr; + +typedef struct { + /* Common registers */ + CARD32 ovr_clr; + CARD32 ovr_wid_left_right; + CARD32 ovr_wid_top_bottom; + CARD32 ov0_scale_cntl; + CARD32 mpp_tb_config; + CARD32 mpp_gp_config; + CARD32 subpic_cntl; + CARD32 viph_control; + CARD32 i2c_cntl_1; + CARD32 gen_int_cntl; + CARD32 cap0_trig_cntl; + CARD32 cap1_trig_cntl; + CARD32 bus_cntl; + + /* Other registers to save for VT switches */ + CARD32 dp_datatype; + CARD32 gen_reset_cntl; + CARD32 clock_cntl_index; + CARD32 amcgpio_en_reg; + CARD32 amcgpio_mask; + + /* CRTC registers */ + CARD32 crtc_gen_cntl; + CARD32 crtc_ext_cntl; + CARD32 dac_cntl; + CARD32 crtc_h_total_disp; + CARD32 crtc_h_sync_strt_wid; + CARD32 crtc_v_total_disp; + CARD32 crtc_v_sync_strt_wid; + CARD32 crtc_offset; + CARD32 crtc_offset_cntl; + CARD32 crtc_pitch; + + /* CRTC2 registers */ + CARD32 crtc2_gen_cntl; + + /* Flat panel registers */ + CARD32 fp_crtc_h_total_disp; + CARD32 fp_crtc_v_total_disp; + CARD32 fp_gen_cntl; + CARD32 fp_h_sync_strt_wid; + CARD32 fp_horz_stretch; + CARD32 fp_panel_cntl; + CARD32 fp_v_sync_strt_wid; + CARD32 fp_vert_stretch; + CARD32 lvds_gen_cntl; + CARD32 tmds_crc; + + /* Computed values for PLL */ + CARD32 dot_clock_freq; + CARD32 pll_output_freq; + int feedback_div; + int post_div; + + /* PLL registers */ + CARD32 ppll_ref_div; + CARD32 ppll_div_3; + CARD32 htotal_cntl; + + /* DDA register */ + CARD32 dda_config; + CARD32 dda_on_off; + + /* Pallet */ + Bool palette_valid; + CARD32 palette[256]; +} R128SaveRec, *R128SavePtr; + +typedef struct { + CARD16 reference_freq; + CARD16 reference_div; + CARD32 min_pll_freq; + CARD32 max_pll_freq; + CARD16 xclk; +} R128PLLRec, *R128PLLPtr; + +typedef struct { + int bitsPerPixel; + int depth; + int displayWidth; + int pixel_code; + int pixel_bytes; + DisplayModePtr mode; +} R128FBLayout; + +typedef struct { + EntityInfoPtr pEnt; + pciVideoPtr PciInfo; + PCITAG PciTag; + int Chipset; + Bool Primary; + + Bool FBDev; + + unsigned long LinearAddr; /* Frame buffer physical address */ + unsigned long MMIOAddr; /* MMIO region physical address */ + unsigned long BIOSAddr; /* BIOS physical address */ + Bool BIOSFromPCI; /* BIOS is read from PCI space */ + + unsigned char *MMIO; /* Map of MMIO region */ + unsigned char *FB; /* Map of frame buffer */ + + CARD32 MemCntl; + CARD32 BusCntl; + unsigned long FbMapSize; /* Size of frame buffer, in bytes */ + int Flags; /* Saved copy of mode flags */ + + Bool HasPanelRegs; /* Current chip can connect to a FP */ + Bool CRTOnly; /* Only use External CRT instead of FP */ + CARD8 *VBIOS; /* Video BIOS for mode validation on FPs */ + int FPBIOSstart; /* Start of the flat panel info */ + + /* Computed values for FPs */ + int PanelXRes; + int PanelYRes; + int PanelPwrDly; + + R128PLLRec pll; + R128RAMPtr ram; + + R128SaveRec SavedReg; /* Original (text) mode */ + R128SaveRec ModeReg; /* Current mode */ + Bool (*CloseScreen)(int, ScreenPtr); + + Bool PaletteSavedOnVT; /* Palette saved on last VT switch */ + + XAAInfoRecPtr accel; + Bool accelOn; + xf86CursorInfoPtr cursor; + unsigned long cursor_start; + unsigned long cursor_end; + + int fifo_slots; /* Free slots in the FIFO (64 max) */ + int pix24bpp; /* Depth of pixmap for 24bpp framebuffer */ + Bool dac6bits; /* Use 6 bit DAC? */ + + /* Computed values for Rage 128 */ + int pitch; + int datatype; + CARD32 dp_gui_master_cntl; + + /* Saved values for ScreenToScreenCopy */ + int xdir; + int ydir; + + /* ScanlineScreenToScreenColorExpand support */ + unsigned char *scratch_buffer[1]; + unsigned char *scratch_save; + int scanline_x; + int scanline_y; + int scanline_h; + int scanline_h_w; + int scanline_words; + int scanline_direct; + int scanline_bpp; /* Only used for ImageWrite */ + + DGAModePtr DGAModes; + int numDGAModes; + Bool DGAactive; + int DGAViewportStatus; + + R128FBLayout CurrentLayout; +#ifdef XF86DRI + Bool directRenderingEnabled; + DRIInfoPtr pDRIInfo; + int drmFD; + int numVisualConfigs; + __GLXvisualConfig *pVisualConfigs; + R128ConfigPrivPtr pVisualConfigsPriv; + + drmHandle fbHandle; + + drmSize registerSize; + drmHandle registerHandle; + + Bool IsPCI; /* Current card is a PCI card */ + + drmSize agpSize; + drmHandle agpMemHandle; /* Handle from drmAgpAlloc */ + unsigned long agpOffset; + unsigned char *AGP; /* Map */ + int agpMode; + + Bool CCEInUse; /* CCE is currently active */ + int CCEMode; /* CCE mode that server/clients use */ + int CCEFifoSize; /* Size of the CCE command FIFO */ + Bool CCESecure; /* CCE security enabled */ + int CCEusecTimeout; /* CCE timeout in usecs */ + Bool CCE2D; /* CCE is used for X server 2D prims */ + + /* CCE ring buffer data */ + unsigned long ringStart; /* Offset into AGP space */ + drmHandle ringHandle; /* Handle from drmAddMap */ + drmSize ringMapSize; /* Size of map */ + int ringSize; /* Size of ring (in MB) */ + unsigned char *ring; /* Map */ + int ringSizeLog2QW; + + unsigned long ringReadOffset; /* Offset into AGP space */ + drmHandle ringReadPtrHandle; /* Handle from drmAddMap */ + drmSize ringReadMapSize; /* Size of map */ + unsigned char *ringReadPtr; /* Map */ + + /* CCE vertex buffer data */ + unsigned long vbStart; /* Offset into AGP space */ + drmHandle vbHandle; /* Handle from drmAddMap */ + drmSize vbMapSize; /* Size of map */ + int vbSize; /* Size of vert bufs (in MB) */ + unsigned char *vb; /* Map */ + int vbBufSize; /* Size of individual vert buf */ + int vbNumBufs; /* Number of vert bufs */ + drmBufMapPtr vbBufs; /* Buffer map */ + + /* CCE indirect buffer data */ + unsigned long indStart; /* Offset into AGP space */ + drmHandle indHandle; /* Handle from drmAddMap */ + drmSize indMapSize; /* Size of map */ + int indSize; /* Size of indirect bufs (in MB) */ + unsigned char *ind; /* Map */ + + /* CCE AGP Texture data */ + unsigned long agpTexStart; /* Offset into AGP space */ + drmHandle agpTexHandle; /* Handle from drmAddMap */ + drmSize agpTexMapSize; /* Size of map */ + int agpTexSize; /* Size of AGP tex space (in MB) */ + unsigned char *agpTex; /* Map */ + int log2AGPTexGran; + + /* DRI screen private data */ + int fbX; + int fbY; + int backX; + int backY; + int depthX; + int depthY; + int textureX; + int textureY; + int textureSize; + int log2TexGran; +#endif + XF86VideoAdaptorPtr adaptor; +} R128InfoRec, *R128InfoPtr; + +#define R128WaitForFifo(pScrn, entries) \ +do { \ + if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \ + info->fifo_slots -= entries; \ +} while (0) + +extern void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries); +extern void R128WaitForIdle(ScrnInfoPtr pScrn); +extern void R128EngineReset(ScrnInfoPtr pScrn); +extern void R128EngineFlush(ScrnInfoPtr pScrn); + +extern int R128INPLL(ScrnInfoPtr pScrn, int addr); +extern void R128WaitForVerticalSync(ScrnInfoPtr pScrn); + +extern Bool R128AccelInit(ScreenPtr pScreen); +extern void R128EngineInit(ScrnInfoPtr pScrn); +extern Bool R128CursorInit(ScreenPtr pScreen); +extern Bool R128DGAInit(ScreenPtr pScreen); + +extern int R128MinBits(int val); + +extern void R128InitVideo(ScreenPtr pScreen); + +#ifdef XF86DRI +extern Bool R128DRIScreenInit(ScreenPtr pScreen); +extern void R128DRICloseScreen(ScreenPtr pScreen); +extern Bool R128DRIFinishScreenInit(ScreenPtr pScreen); +extern void R128CCEStart(ScrnInfoPtr pScrn); +extern void R128CCEStop(ScrnInfoPtr pScrn); +extern void R128CCEResetRing(ScrnInfoPtr pScrn); +extern void R128CCEWaitForIdle(ScrnInfoPtr pScrn); +#endif + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c new file mode 100644 index 000000000..7595b7fe4 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c @@ -0,0 +1,1084 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_accel.c,v 1.1 2000/11/02 16:55:30 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * Alan Hourihane <ahourihane@valinux.com> + * + * Credits: + * + * Thanks to Alan Hourihane <alanh@fairlite.demon..co.uk> and SuSE for + * providing source code to their 3.3.x Rage 128 driver. Portions of + * this file are based on the acceleration code for that driver. + * + * References: + * + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + * Notes on unimplemented XAA optimizations: + * + * SetClipping: The Rage128 doesn't support the full 16bit registers needed + * for XAA clip rect support. + * SolidFillTrap: This will probably work if we can compute the correct + * Bresenham error values. + * TwoPointLine: The Rage 128 supports Bresenham lines instead. + * DashedLine with non-power-of-two pattern length: Apparently, there is + * no way to set the length of the pattern -- it is always + * assumed to be 8 or 32 (or 1024?). + * ScreenToScreenColorExpandFill: See p. 4-17 of the Technical Reference + * Manual where it states that monochrome expansion of frame + * buffer data is not supported. + * CPUToScreenColorExpandFill, direct: The implementation here uses a hybrid + * direct/indirect method. If we had more data registers, + * then we could do better. If XAA supported a trigger write + * address, the code would be simpler. + * (Alan Hourihane) Update. We now use purely indirect and clip the full + * rectangle. Seems as the direct method has some problems + * with this, although this indirect method is much faster + * than the old method of setting up the engine per scanline. + * This code was the basis of the Radeon work we did. + * Color8x8PatternFill: Apparently, an 8x8 color brush cannot take an 8x8 + * pattern from frame buffer memory. + * ImageWrites: See CPUToScreenColorExpandFill. + * + */ + +#define R128_IMAGEWRITE 0 /* Disable ImageWrites - faster in software */ +#define R128_TRAPEZOIDS 0 /* Trapezoids don't work */ + + /* X and server generic header files */ +#include "Xarch.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + + /* Line support */ +#include "miline.h" + + /* XAA and cursor support */ +#include "xaa.h" +#include "xf86Cursor.h" + + /* Driver data structures */ +#include "r128.h" +#include "r128_reg.h" + +static struct { + int rop; + int pattern; +} R128_ROP[] = { + { R128_ROP3_ZERO, R128_ROP3_ZERO }, /* GXclear */ + { R128_ROP3_DSa, R128_ROP3_DPa }, /* Gxand */ + { R128_ROP3_SDna, R128_ROP3_PDna }, /* GXandReverse */ + { R128_ROP3_S, R128_ROP3_P }, /* GXcopy */ + { R128_ROP3_DSna, R128_ROP3_DPna }, /* GXandInverted */ + { R128_ROP3_D, R128_ROP3_D }, /* GXnoop */ + { R128_ROP3_DSx, R128_ROP3_DPx }, /* GXxor */ + { R128_ROP3_DSo, R128_ROP3_DPo }, /* GXor */ + { R128_ROP3_DSon, R128_ROP3_DPon }, /* GXnor */ + { R128_ROP3_DSxn, R128_ROP3_PDxn }, /* GXequiv */ + { R128_ROP3_Dn, R128_ROP3_Dn }, /* GXinvert */ + { R128_ROP3_SDno, R128_ROP3_PDno }, /* GXorReverse */ + { R128_ROP3_Sn, R128_ROP3_Pn }, /* GXcopyInverted */ + { R128_ROP3_DSno, R128_ROP3_DPno }, /* GXorInverted */ + { R128_ROP3_DSan, R128_ROP3_DPan }, /* GXnand */ + { R128_ROP3_ONE, R128_ROP3_ONE } /* GXset */ +}; + +/* Flush all dirty data in the Pixel Cache to memory. */ +void R128EngineFlush(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + OUTREGP(R128_PC_NGUI_CTLSTAT, R128_PC_FLUSH_ALL, ~R128_PC_FLUSH_ALL); + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) break; + } +} + +/* Reset graphics card to known state. */ +void R128EngineReset(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 clock_cntl_index; + CARD32 mclk_cntl; + CARD32 gen_reset_cntl; + + R128EngineFlush(pScrn); + + clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); + mclk_cntl = INPLL(pScrn, R128_MCLK_CNTL); + + OUTPLL(R128_MCLK_CNTL, mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP); + + gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); + + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI); + INREG(R128_GEN_RESET_CNTL); + + OUTPLL(R128_MCLK_CNTL, mclk_cntl); + OUTREG(R128_CLOCK_CNTL_INDEX, clock_cntl_index); + OUTREG(R128_GEN_RESET_CNTL, gen_reset_cntl); + +#ifdef XF86DRI + if (R128CCE_USE_RING_BUFFER(info->CCEMode)) R128CCEResetRing(pScrn); +#endif +} + +/* The FIFO has 64 slots. This routines waits until at least `entries' of + these slots are empty. */ +void R128WaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + info->fifo_slots = INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK; + if (info->fifo_slots >= entries) return; + } + R128TRACE(("FIFO timed out: %d entries, stat=0x%08x, probe=0x%08x\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FIFO timed out, resetting engine...\n"); + R128EngineReset(pScrn); +#ifdef XF86DRI + if (info->CCE2D) R128CCEStart(pScrn); +#endif + } +} + +/* Wait for the graphics engine to be completely idle: the FIFO has + drained, the Pixel Cache is flushed, and the engine is idle. This is a + standard "sync" function that will make the hardware "quiescent". */ +void R128WaitForIdle(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + R128WaitForFifoFunction(pScrn, 64); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_GUI_STAT) & R128_GUI_ACTIVE)) { + R128EngineFlush(pScrn); + return; + } + } + R128TRACE(("Idle timed out: %d entries, stat=0x%08x, probe=0x%08x\n", + INREG(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK, + INREG(R128_GUI_STAT), + INREG(R128_GUI_PROBE))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + R128EngineReset(pScrn); +#ifdef XF86DRI + if (info->CCE2D) R128CCEStart(pScrn); +#endif + } +} + +/* Setup for XAA SolidFill. */ +static void R128SetupForSolidFill(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 4); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].pattern)); + OUTREG(R128_DP_BRUSH_FRGD_CLR, color); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT + | R128_DST_Y_TOP_TO_BOTTOM)); +} + +/* Subsequent XAA SolidFillRect. + + Tests: xtest CH06/fllrctngl, xterm +*/ +static void R128SubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_WIDTH_HEIGHT, (w << 16) | h); +} + +/* Setup for XAA solid lines. */ +static void R128SetupForSolidLine(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].pattern)); + OUTREG(R128_DP_BRUSH_FRGD_CLR, color); + OUTREG(R128_DP_WRITE_MASK, planemask); +} + + +/* Subsequent XAA solid Bresenham line. + + Tests: xtest CH06/drwln, ico, Mark Vojkovich's linetest program + + [See http://www.xfree86.org/devel/archives/devel/1999-Jun/0102.shtml for + Mark Vojkovich's linetest program, posted 2Jun99 to devel@xfree86.org.] + + x11perf -line500 + 1024x768@76Hz 1024x768@76Hz + 8bpp 32bpp + not used: 39700.0/sec 34100.0/sec + used: 47600.0/sec 36800.0/sec +*/ +static void R128SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, + int major, int minor, + int err, int len, int octant) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int flags = 0; + + if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; + if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; + if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; + + R128WaitForFifo(pScrn, 6); + OUTREG(R128_DP_CNTL_XDIR_YDIR_YMAJOR, flags); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_BRES_ERR, err); + OUTREG(R128_DST_BRES_INC, minor); + OUTREG(R128_DST_BRES_DEC, -major); + OUTREG(R128_DST_BRES_LNTH, len); +} + +/* Subsequent XAA solid horizontal and vertical lines + + 1024x768@76Hz 8bpp + Without With + x11perf -hseg500 87600.0/sec 798000.0/sec + x11perf -vseg500 38100.0/sec 38000.0/sec +*/ +static void R128SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, + int x, int y, int len, int dir ) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 1); + OUTREG(R128_DP_CNTL, (R128_DST_X_LEFT_TO_RIGHT + | R128_DST_Y_TOP_TO_BOTTOM)); + + if (dir == DEGREES_0) { + R128SubsequentSolidFillRect(pScrn, x, y, len, 1); + } else { + R128SubsequentSolidFillRect(pScrn, x, y, 1, len); + } +} + +/* Setup for XAA dashed lines. + + Tests: xtest CH05/stdshs, XFree86/drwln + + NOTE: Since we can only accelerate lines with power-of-2 patterns of + length <= 32, these x11perf numbers are not representative of the + speed-up on appropriately-sized patterns. + + 1024x768@76Hz 8bpp + Without With + x11perf -dseg100 218000.0/sec 222000.0/sec + x11perf -dline100 215000.0/sec 221000.0/sec + x11perf -ddline100 178000.0/sec 180000.0/sec +*/ +static void R128SetupForDashedLine(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, unsigned int planemask, + int length, unsigned char *pattern) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 pat = *(CARD32 *)pattern; + + switch (length) { + case 2: pat |= pat << 2; /* fall through */ + case 4: pat |= pat << 4; /* fall through */ + case 8: pat |= pat << 8; /* fall through */ + case 16: pat |= pat << 16; + } + + R128WaitForFifo(pScrn, 5); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? R128_GMC_BRUSH_32x1_MONO_FG_LA + : R128_GMC_BRUSH_32x1_MONO_FG_BG) + | R128_ROP[rop].pattern + | R128_GMC_BYTE_LSB_TO_MSB)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_BRUSH_FRGD_CLR, fg); + OUTREG(R128_DP_BRUSH_BKGD_CLR, bg); + OUTREG(R128_BRUSH_DATA0, pat); +} + +/* Subsequent XAA dashed line. */ +static void R128SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, + int x, int y, + int major, int minor, + int err, int len, int octant, + int phase) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int flags = 0; + + if (octant & YMAJOR) flags |= R128_DST_Y_MAJOR; + if (!(octant & XDECREASING)) flags |= R128_DST_X_DIR_LEFT_TO_RIGHT; + if (!(octant & YDECREASING)) flags |= R128_DST_Y_DIR_TOP_TO_BOTTOM; + + R128WaitForFifo(pScrn, 7); + OUTREG(R128_DP_CNTL_XDIR_YDIR_YMAJOR, flags); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_BRUSH_Y_X, (phase << 16) | phase); + OUTREG(R128_DST_BRES_ERR, err); + OUTREG(R128_DST_BRES_INC, minor); + OUTREG(R128_DST_BRES_DEC, -major); + OUTREG(R128_DST_BRES_LNTH, len); +} + +#if R128_TRAPEZOIDS + /* This doesn't work. Except in the + lower-left quadrant, all of the pixel + errors appear to be because eL and eR + are not correct. Drawing from right to + left doesn't help. Be aware that the + non-_SUB registers set the sub-pixel + values to 0.5 (0x08), which isn't what + XAA wants. */ +/* Subsequent XAA SolidFillTrap. XAA always passes data that assumes we + fill from top to bottom, so dyL and dyR are always non-negative. */ +static void R128SubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int flags = 0; + int Lymajor = 0; + int Rymajor = 0; + int origdxL = dxL; + int origdxR = dxR; + + R128TRACE(("Trap %d %d; L %d %d %d %d; R %d %d %d %d\n", + y, h, + left, dxL, dyL, eL, + right, dxR, dyR, eR)); + + if (dxL < 0) dxL = -dxL; else flags |= (1 << 0) /* | (1 << 8) */; + if (dxR < 0) dxR = -dxR; else flags |= (1 << 6); + + R128WaitForFifo(pScrn, 11); + +#if 1 + OUTREG(R128_DP_CNTL, flags | (1 << 1) | (1 << 7)); + OUTREG(R128_DST_Y_SUB, ((y) << 4) | 0x0 ); + OUTREG(R128_DST_X_SUB, ((left) << 4)|0x0); + OUTREG(R128_TRAIL_BRES_ERR, eR-dxR); + OUTREG(R128_TRAIL_BRES_INC, dxR); + OUTREG(R128_TRAIL_BRES_DEC, -dyR); + OUTREG(R128_TRAIL_X_SUB, ((right) << 4) | 0x0); + OUTREG(R128_LEAD_BRES_ERR, eL-dxL); + OUTREG(R128_LEAD_BRES_INC, dxL); + OUTREG(R128_LEAD_BRES_DEC, -dyL); + OUTREG(R128_LEAD_BRES_LNTH_SUB, ((h) << 4) | 0x00); +#else + OUTREG(R128_DP_CNTL, flags | (1 << 1) ); + OUTREG(R128_DST_Y_SUB, (y << 4)); + OUTREG(R128_DST_X_SUB, (right << 4)); + OUTREG(R128_TRAIL_BRES_ERR, eL); + OUTREG(R128_TRAIL_BRES_INC, dxL); + OUTREG(R128_TRAIL_BRES_DEC, -dyL); + OUTREG(R128_TRAIL_X_SUB, (left << 4) | 0); + OUTREG(R128_LEAD_BRES_ERR, eR); + OUTREG(R128_LEAD_BRES_INC, dxR); + OUTREG(R128_LEAD_BRES_DEC, -dyR); + OUTREG(R128_LEAD_BRES_LNTH_SUB, h << 4); +#endif +} +#endif + +/* Setup for XAA screen-to-screen copy. + + Tests: xtest CH06/fllrctngl (also tests transparency). +*/ +static void R128SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int trans_color) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + info->xdir = xdir; + info->ydir = ydir; + R128WaitForFifo(pScrn, 3); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_MEMORY)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_CNTL, ((xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) + | (ydir >= 0 + ? R128_DST_Y_TOP_TO_BOTTOM + : 0))); + + if (trans_color != -1) { + /* Set up for transparency */ + R128WaitForFifo(pScrn, 3); + OUTREG(R128_CLR_CMP_CLR_SRC, trans_color); + OUTREG(R128_CLR_CMP_MASK, R128_CLR_CMP_MSK); + OUTREG(R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR + | R128_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA screen-to-screen copy. */ +static void R128SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int xa, int ya, + int xb, int yb, + int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + if (info->xdir < 0) xa += w - 1, xb += w - 1; + if (info->ydir < 0) ya += h - 1, yb += h - 1; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_SRC_Y_X, (ya << 16) | xa); + OUTREG(R128_DST_Y_X, (yb << 16) | xb); + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +/* Setup for XAA mono 8x8 pattern color expansion. Patterns with + transparency use `bg == -1'. This routine is only used if the XAA + pixmap cache is turned on. + + Tests: xtest XFree86/fllrctngl (no other test will test this routine with + both transparency and non-transparency) + + 1024x768@76Hz 8bpp + Without With + x11perf -srect100 38600.0/sec 85700.0/sec + x11perf -osrect100 38600.0/sec 85700.0/sec +*/ +static void R128SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 6); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? R128_GMC_BRUSH_8X8_MONO_FG_LA + : R128_GMC_BRUSH_8X8_MONO_FG_BG) + | R128_ROP[rop].pattern + | R128_GMC_BYTE_LSB_TO_MSB)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_BRUSH_FRGD_CLR, fg); + OUTREG(R128_DP_BRUSH_BKGD_CLR, bg); + OUTREG(R128_BRUSH_DATA0, patternx); + OUTREG(R128_BRUSH_DATA1, patterny); +} + +/* Subsequent XAA 8x8 pattern color expansion. Because they are used in + the setup function, `patternx' and `patterny' are not used here. */ +static void R128SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 3); + OUTREG(R128_BRUSH_Y_X, (patterny << 8) | patternx); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +#if 0 +/* Setup for XAA color 8x8 pattern fill. + + Tests: xtest XFree86/fllrctngl (with Mono8x8PatternFill off) +*/ +static void R128SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patx, int paty, + int rop, unsigned int planemask, + int trans_color) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128TRACE(("Color8x8 %d %d %d\n", trans_color, patx, paty)); + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_8x8_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_DP_SRC_SOURCE_MEMORY)); + OUTREG(R128_DP_WRITE_MASK, planemask); + + if (trans_color != -1) { + /* Set up for transparency */ + R128WaitForFifo(pScrn, 3); + OUTREG(R128_CLR_CMP_CLR_SRC, trans_color); + OUTREG(R128_CLR_CMP_MASK, R128_CLR_CMP_MSK); + OUTREG(R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR + | R128_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA 8x8 pattern color expansion. */ +static void R128SubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, int w, int h) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128TRACE(("Color8x8 %d,%d %d,%d %d %d\n", patx, paty, x, y, w, h)); + R128WaitForFifo(pScrn, 3); + OUTREG(R128_SRC_Y_X, (paty << 16) | patx); + OUTREG(R128_DST_Y_X, (y << 16) | x); + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | w); +} +#endif + +/* Setup for XAA indirect CPU-to-screen color expansion (indirect). + Because of how the scratch buffer is initialized, this is really a + mainstore-to-screen color expansion. Transparency is supported when `bg + == -1'. + + x11perf -ftext (pure indirect): + 1024x768@76Hz 1024x768@76Hz + 8bpp 32bpp + not used: 685000.0/sec 794000.0/sec + used: 1070000.0/sec 1080000.0/sec + + We could improve this indirect routine by about 10% if the hardware + could accept DWORD padded scanlines, or if XAA could provide bit-packed + data. We might also be able to move to a direct routine if there were + more HOST_DATA registers. + + Implementing the hybrid indirect/direct scheme improved performance in a + few areas: + + 1024x768@76 8bpp + Indirect Hybrid + x11perf -oddsrect10 50100.0/sec 71700.0/sec + x11perf -oddsrect100 4240.0/sec 6660.0/sec + x11perf -bigsrect10 50300.0/sec 71100.0/sec + x11perf -bigsrect100 4190.0/sec 6800.0/sec + x11perf -polytext 584000.0/sec 714000.0/sec + x11perf -polytext16 154000.0/sec 172000.0/sec + x11perf -seg1 1780000.0/sec 1880000.0/sec + x11perf -copyplane10 42900.0/sec 58300.0/sec + x11perf -copyplane100 4400.0/sec 6710.0/sec + x11perf -putimagexy10 5090.0/sec 6670.0/sec + x11perf -putimagexy100 424.0/sec 575.0/sec + + 1024x768@76 -depth 24 -fbbpp 32 + Indirect Hybrid + x11perf -oddsrect100 4240.0/sec 6670.0/sec + x11perf -bigsrect100 4190.0/sec 6800.0/sec + x11perf -polytext 585000.0/sec 719000.0/sec + x11perf -seg1 2960000.0/sec 2990000.0/sec + x11perf -copyplane100 4400.0/sec 6700.0/sec + x11perf -putimagexy100 138.0/sec 191.0/sec + +*/ +static void R128SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int + planemask) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128WaitForFifo(pScrn, 4); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_NONE + | (bg == -1 + ? R128_GMC_SRC_DATATYPE_MONO_FG_LA + : R128_GMC_SRC_DATATYPE_MONO_FG_BG) + | R128_ROP[rop].rop + | R128_GMC_BYTE_LSB_TO_MSB + | R128_DP_SRC_SOURCE_HOST_DATA)); + OUTREG(R128_DP_WRITE_MASK, planemask); + OUTREG(R128_DP_SRC_FRGD_CLR, fg); + OUTREG(R128_DP_SRC_BKGD_CLR, bg); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is only + called once for each rectangle. */ +static void R128SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int x1clip = x+skipleft; + int x2clip = x+w; + + info->scanline_h = h; + info->scanline_words = (w + 31) >> 5; + +#if 0 + /* Seems as though the Rage128's doesn't like blitting directly + * as we must be overwriting something too quickly, therefore we + * render to the buffer first and then blit */ + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(R128_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else +#endif + { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + if (pScrn->bitsPerPixel == 24) { + x1clip *= 3; + x2clip *= 3; + } + + R128WaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(R128_SC_TOP_LEFT, (y << 16) | (x1clip & 0xffff)); + OUTREG(R128_SC_BOTTOM_RIGHT, ((y+h-1) << 16) | ((x2clip-1) & 0xffff)); + OUTREG(R128_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | ((w + 31) & ~31)); +} + +/* Subsequent XAA indirect CPU-to-screen color expandion. This is called + once for each scanline. */ +static void R128SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 *p = (CARD32 *)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile CARD32 *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + R128WaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} + +/* Setup for XAA indirect image write. + + + 1024x768@76Hz 8bpp + Without With + x11perf -putimage10 37500.0/sec 39300.0/sec + x11perf -putimage100 2150.0/sec 1170.0/sec + x11perf -putimage500 108.0/sec 49.8/sec + */ +#if R128_IMAGEWRITE +static void R128SetupForScanlineImageWrite(ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int trans_color, + int bpp, + int depth) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + info->scanline_bpp = bpp; + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_DST_CLIPPING + | R128_GMC_BRUSH_1X8_COLOR + | R128_GMC_SRC_DATATYPE_COLOR + | R128_ROP[rop].rop + | R128_GMC_BYTE_LSB_TO_MSB + | R128_DP_SRC_SOURCE_HOST_DATA)); + OUTREG(R128_DP_WRITE_MASK, planemask); + + if (trans_color != -1) { + /* Set up for transparency */ + R128WaitForFifo(pScrn, 3); + OUTREG(R128_CLR_CMP_CLR_SRC, trans_color); + OUTREG(R128_CLR_CMP_MASK, R128_CLR_CMP_MSK); + OUTREG(R128_CLR_CMP_CNTL, (R128_SRC_CMP_NEQ_COLOR + | R128_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA indirect image write. This is only called once for each + rectangle. */ +static void R128SubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int x1clip = x+skipleft; + int x2clip = x+w; + + int shift = 0; /* 32bpp */ + + if (pScrn->bitsPerPixel == 8) shift = 3; + else if (pScrn->bitsPerPixel == 16) shift = 1; + + info->scanline_h = h; + info->scanline_words = (w * info->scanline_bpp + 31) >> 5; + +#if 0 + /* Seeing as the CPUToScreen doesn't like this, I've done this + * here too, as it uses pretty much the same path. */ + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(R128_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else +#endif + { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + if (pScrn->bitsPerPixel == 24) { + x1clip *= 3; + x2clip *= 3; + } + + R128WaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(R128_SC_TOP_LEFT, (y << 16) | (x1clip & 0xffff)); + OUTREG(R128_SC_BOTTOM_RIGHT, ((y+h-1) << 16) | ((x2clip-1) & 0xffff)); + OUTREG(R128_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(R128_DST_HEIGHT_WIDTH, (h << 16) | ((w + shift) & ~shift)); +} + +/* Subsequent XAA indirect iamge write. This is called once for each + scanline. */ +static void R128SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 *p = (CARD32 *)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile CARD32 *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + R128WaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + R128WaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(R128_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} +#endif + +/* Initialize the acceleration hardware. */ +void R128EngineInit(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + R128TRACE(("EngineInit (%d/%d)\n", info->CurrentLayout.pixel_code, info->CurrentLayout.bitsPerPixel)); + + OUTREG(R128_SCALE_3D_CNTL, 0); + R128EngineReset(pScrn); + + switch (info->CurrentLayout.pixel_code) { + case 8: info->datatype = 2; break; + case 15: info->datatype = 3; break; + case 16: info->datatype = 4; break; + case 24: info->datatype = 5; break; + case 32: info->datatype = 6; break; + default: + R128TRACE(("Unknown depth/bpp = %d/%d (code = %d)\n", + info->CurrentLayout.depth, info->CurrentLayout.bitsPerPixel, + info->CurrentLayout.pixel_code)); + } + info->pitch = (info->CurrentLayout.displayWidth / 8) * (info->CurrentLayout.pixel_bytes == 3 ? 3 : 1); + + R128TRACE(("Pitch for acceleration = %d\n", info->pitch)); + + R128WaitForFifo(pScrn, 2); + OUTREG(R128_DEFAULT_OFFSET, 0); + OUTREG(R128_DEFAULT_PITCH, info->pitch); + + R128WaitForFifo(pScrn, 4); + OUTREG(R128_AUX_SC_CNTL, 0); + OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX + | R128_DEFAULT_SC_BOTTOM_MAX)); + OUTREG(R128_SC_TOP_LEFT, 0); + OUTREG(R128_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX + | R128_DEFAULT_SC_BOTTOM_MAX)); + + info->dp_gui_master_cntl = ((info->datatype << R128_GMC_DST_DATATYPE_SHIFT) + | R128_GMC_CLR_CMP_CNTL_DIS + | R128_GMC_AUX_CLIP_DIS); + R128WaitForFifo(pScrn, 1); + OUTREG(R128_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | R128_GMC_BRUSH_SOLID_COLOR + | R128_GMC_SRC_DATATYPE_COLOR)); + + R128WaitForFifo(pScrn, 8); + OUTREG(R128_DST_BRES_ERR, 0); + OUTREG(R128_DST_BRES_INC, 0); + OUTREG(R128_DST_BRES_DEC, 0); + OUTREG(R128_DP_BRUSH_FRGD_CLR, 0xffffffff); + OUTREG(R128_DP_BRUSH_BKGD_CLR, 0x00000000); + OUTREG(R128_DP_SRC_FRGD_CLR, 0xffffffff); + OUTREG(R128_DP_SRC_BKGD_CLR, 0x00000000); + OUTREG(R128_DP_WRITE_MASK, 0xffffffff); + + R128WaitForFifo(pScrn, 1); +#if X_BYTE_ORDER == X_BIG_ENDIAN + OUTREGP(R128_DP_DATATYPE, + R128_HOST_BIG_ENDIAN_EN, ~R128_HOST_BIG_ENDIAN_EN); +#else + OUTREGP(R128_DP_DATATYPE, 0, ~R128_HOST_BIG_ENDIAN_EN); +#endif + + R128WaitForIdle(pScrn); +} + +#ifdef XF86DRI + /* FIXME: When direct rendering is enabled, we should use the CCE to + draw 2D commands */ +static void R128CCEAccelInit(XAAInfoRecPtr a) +{ + a->Flags = 0; + + /* Sync */ + a->Sync = R128CCEWaitForIdle; + +} +#endif + +static void R128MMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) +{ + R128InfoPtr info = R128PTR(pScrn); + + a->Flags = (PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER); + + /* Sync */ + a->Sync = R128WaitForIdle; + + /* Solid Filled Rectangle */ + a->PolyFillRectSolidFlags = 0; + a->SetupForSolidFill = R128SetupForSolidFill; + a->SubsequentSolidFillRect = R128SubsequentSolidFillRect; + + /* Screen-to-screen Copy */ + /* Transparency uses the wrong colors for + 24 bpp mode -- the transparent part is + correct, but the opaque color is wrong. + This can be seen with netscape's I-bar + cursor when editing in the URL location + box. */ + a->ScreenToScreenCopyFlags = ((pScrn->bitsPerPixel == 24) + ? NO_TRANSPARENCY + : 0); + a->SetupForScreenToScreenCopy = R128SetupForScreenToScreenCopy; + a->SubsequentScreenToScreenCopy = R128SubsequentScreenToScreenCopy; + + /* Mono 8x8 Pattern Fill (Color Expand) */ + a->SetupForMono8x8PatternFill = R128SetupForMono8x8PatternFill; + a->SubsequentMono8x8PatternFillRect = R128SubsequentMono8x8PatternFillRect; + a->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_PROGRAMMED_ORIGIN + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_LSBFIRST); + + /* Indirect CPU-To-Screen Color Expand */ +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + a->ScanlineCPUToScreenColorExpandFillFlags = LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#else + a->ScanlineCPUToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST + | LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#endif + a->NumScanlineColorExpandBuffers = 1; + a->ScanlineColorExpandBuffers = info->scratch_buffer; + info->scratch_save = xalloc(((pScrn->virtualX+31)/32*4) + + (pScrn->virtualX + * info->CurrentLayout.pixel_bytes)); + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineCPUToScreenColorExpandFill + = R128SetupForScanlineCPUToScreenColorExpandFill; + a->SubsequentScanlineCPUToScreenColorExpandFill + = R128SubsequentScanlineCPUToScreenColorExpandFill; + a->SubsequentColorExpandScanline = R128SubsequentColorExpandScanline; + + /* Bresenham Solid Lines */ + a->SetupForSolidLine = R128SetupForSolidLine; + a->SubsequentSolidBresenhamLine = R128SubsequentSolidBresenhamLine; + a->SubsequentSolidHorVertLine = R128SubsequentSolidHorVertLine; + + /* Bresenham Dashed Lines*/ + a->SetupForDashedLine = R128SetupForDashedLine; + a->SubsequentDashedBresenhamLine = R128SubsequentDashedBresenhamLine; + a->DashPatternMaxLength = 32; + a->DashedLineFlags = (LINE_PATTERN_LSBFIRST_LSBJUSTIFIED + | LINE_PATTERN_POWER_OF_2_ONLY); + + /* ImageWrite */ +#if R128_IMAGEWRITE + a->NumScanlineImageWriteBuffers = 1; + a->ScanlineImageWriteBuffers = info->scratch_buffer; + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineImageWrite = R128SetupForScanlineImageWrite; + a->SubsequentScanlineImageWriteRect= R128SubsequentScanlineImageWriteRect; + a->SubsequentImageWriteScanline = R128SubsequentImageWriteScanline; + a->ScanlineImageWriteFlags = CPU_TRANSFER_PAD_DWORD + /* Performance tests show that we shouldn't use GXcopy for + * uploads as a memcpy is faster */ + | NO_GXCOPY + | LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X + | SCANLINE_PAD_DWORD; +#endif +} + +/* Initialize XAA for supported acceleration and also initialize the + graphics hardware for acceleration. */ +Bool R128AccelInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + XAAInfoRecPtr a; + + if (!(a = info->accel = XAACreateInfoRec())) return FALSE; + +#ifdef XF86DRI + /* FIXME: When direct rendering is enabled, we should use the CCE to + draw 2D commands */ + if (info->CCE2D) R128CCEAccelInit(a); + else +#endif + R128MMIOAccelInit(pScrn, a); + + R128EngineInit(pScrn); + return XAAInit(pScreen, a); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c new file mode 100644 index 000000000..d77c64b5a --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c @@ -0,0 +1,289 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_cursor.c,v 1.1 2000/11/02 16:55:31 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * References: + * + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + + /* X and server generic header files */ +#include "Xarch.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + + /* XAA and Cursor Support */ +#include "xaa.h" +#include "xf86Cursor.h" + +#include "xf86xv.h" + + /* PCI support */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + + /* DDC support */ +#include "xf86DDC.h" + + /* DRI support */ +#ifdef XF86DRI +#include "GL/glxint.h" +#include "xf86drm.h" +#include "sarea.h" +#define _XF86DRI_SERVER_ +#include "xf86dri.h" +#include "dri.h" +#include "r128_dri.h" +#include "r128_dripriv.h" +#include "r128_sarea.h" +#endif + + /* Driver data structures */ +#include "r128.h" +#include "r128_reg.h" + +#if X_BYTE_ORDER == X_BIG_ENDIAN +#define P_SWAP32( a , b ) \ + ((char *)a)[0] = ((char *)b)[3]; \ + ((char *)a)[1] = ((char *)b)[2]; \ + ((char *)a)[2] = ((char *)b)[1]; \ + ((char *)a)[3] = ((char *)b)[0] + +#define P_SWAP16( a , b ) \ + ((char *)a)[0] = ((char *)b)[1]; \ + ((char *)a)[1] = ((char *)b)[0]; \ + ((char *)a)[2] = ((char *)b)[3]; \ + ((char *)a)[3] = ((char *)b)[2] +#endif + + +/* Set cursor foreground and background colors. */ +static void R128SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_CUR_CLR0, bg); + OUTREG(R128_CUR_CLR1, fg); +} + +/* Set cursor position to (x,y) with offset into cursor bitmap at + (xorigin,yorigin). */ +static void R128SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + xf86CursorInfoPtr cursor = info->cursor; + int xorigin = 0; + int yorigin = 0; + int total_y = pScrn->frameY1 - pScrn->frameY0; + + if (x < 0) xorigin = -x; + if (y < 0) yorigin = -y; + if (y > total_y) y = total_y; + if (info->Flags & V_DBLSCAN) y *= 2; + if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; + if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; + + OUTREG(R128_CUR_HORZ_VERT_OFF, R128_CUR_LOCK | (xorigin << 16) | yorigin); + OUTREG(R128_CUR_HORZ_VERT_POSN, (R128_CUR_LOCK + | ((xorigin ? 0 : x) << 16) + | (yorigin ? 0 : y))); + OUTREG(R128_CUR_OFFSET, info->cursor_start + yorigin * 16); +} + +/* Copy cursor image from `image' to video memory. R128SetCursorPosition + will be called after this, so we can ignore xorigin and yorigin. */ +static void R128LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 *s = (CARD32 *)image; + CARD32 *d = (CARD32 *)(info->FB + info->cursor_start); + int y; + CARD32 save; + + save = INREG(R128_CRTC_GEN_CNTL); + OUTREG(R128_CRTC_GEN_CNTL, save & ~R128_CRTC_CUR_EN); + +#if X_BYTE_ORDER == X_BIG_ENDIAN + switch(info->CurrentLayout.pixel_bytes) { + case 4: + case 3: + for (y = 0; y < 64; y++) { + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + } + break; + case 2: + for (y = 0; y < 64; y++) { + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + } + break; + default: + for (y = 0; y < 64; y++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } + } +#else + for (y = 0; y < 64; y++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } +#endif + + /* Set the area after the cursor to be all transparent so that we + won't display corrupted cursors on the screen */ + for (y = 0; y < 64; y++) { + *d++ = 0xffffffff; /* The AND bits */ + *d++ = 0xffffffff; + *d++ = 0x00000000; /* The XOR bits */ + *d++ = 0x00000000; + } + + + OUTREG(R128_CRTC_GEN_CNTL, save); +} + +/* Hide hardware cursor. */ +static void R128HideCursor(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CRTC_GEN_CNTL, 0, ~R128_CRTC_CUR_EN); +} + +/* Show hardware cursor. */ +static void R128ShowCursor(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CRTC_GEN_CNTL, R128_CRTC_CUR_EN, ~R128_CRTC_CUR_EN); +} + +/* Determine if hardware cursor is in use. */ +static Bool R128UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + return info->cursor_start ? TRUE : FALSE; +} + +/* Initialize hardware cursor support. */ +Bool R128CursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + xf86CursorInfoPtr cursor; + FBAreaPtr fbarea; + int width; + int height; + int size; + + + if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE; + + cursor->MaxWidth = 64; + cursor->MaxHeight = 64; + cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST +#endif + | HARDWARE_CURSOR_INVERT_MASK + | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK + | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 + | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK); + + cursor->SetCursorColors = R128SetCursorColors; + cursor->SetCursorPosition = R128SetCursorPosition; + cursor->LoadCursorImage = R128LoadCursorImage; + cursor->HideCursor = R128HideCursor; + cursor->ShowCursor = R128ShowCursor; + cursor->UseHWCursor = R128UseHWCursor; + + size = (cursor->MaxWidth/4) * cursor->MaxHeight; + width = pScrn->displayWidth; + height = (size*2 + 1023) / pScrn->displayWidth; + fbarea = xf86AllocateOffscreenArea(pScreen, + width, + height, + 16, + NULL, + NULL, + NULL); + + if (!fbarea) { + info->cursor_start = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Hardware cursor disabled" + " due to insufficient offscreen memory\n"); + } else { + info->cursor_start = R128_ALIGN((fbarea->box.x1 + + width * fbarea->box.y1) + * info->CurrentLayout.pixel_bytes, 16); + info->cursor_end = info->cursor_start + size; + } + + R128TRACE(("R128CursorInit (0x%08x-0x%08x)\n", + info->cursor_start, info->cursor_end)); + + return xf86InitCursor(pScreen, cursor); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c new file mode 100644 index 000000000..695d49cdb --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c @@ -0,0 +1,358 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dga.c,v 1.1 2000/11/02 16:55:32 tsi Exp $ */ +/* + * Authors: + * Ove Kåven <ovek@transgaming.com>, + * borrowing some code from the Chips and MGA drivers. + */ + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + + /* Driver data structures */ +#include "r128.h" +#include "r128_probe.h" + + /* DGA support */ +#include "dgaproc.h" + + +static Bool R128_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static Bool R128_SetMode(ScrnInfoPtr, DGAModePtr); +static int R128_GetViewport(ScrnInfoPtr); +static void R128_SetViewport(ScrnInfoPtr, int, int, int); +static void R128_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void R128_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); +#if 0 +static void R128_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, + unsigned long); +#endif + +static +DGAFunctionRec R128_DGAFuncs = { + R128_OpenFramebuffer, + NULL, + R128_SetMode, + R128_SetViewport, + R128_GetViewport, + R128WaitForIdle, + R128_FillRect, + R128_BlitRect, +#if 0 + R128_BlitTransRect +#else + NULL +#endif +}; + + +static DGAModePtr +R128SetupDGAMode( + ScrnInfoPtr pScrn, + DGAModePtr modes, + int *num, + int bitsPerPixel, + int depth, + Bool pixmap, + int secondPitch, + unsigned long red, + unsigned long green, + unsigned long blue, + short visualClass +){ + R128InfoPtr info = R128PTR(pScrn); + DGAModePtr newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int otherPitch, Bpp = bitsPerPixel >> 3; + Bool oneMore; + + pMode = firstMode = pScrn->modes; + + while(pMode) { + + otherPitch = secondPitch ? secondPitch : pMode->HDisplay; + + if(pMode->HDisplay != otherPitch) { + newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } else { + newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + + if(!newmodes) { + xfree(modes); + return NULL; + } + modes = newmodes; + +SECOND_PASS: + + currentMode = modes + *num; + (*num)++; + + currentMode->mode = pMode; + /* FIXME: is concurrent access really possible? */ + currentMode->flags = DGA_CONCURRENT_ACCESS; + if(pixmap) + currentMode->flags |= DGA_PIXMAP_AVAILABLE; + if(info->accel) + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if(pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if(pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = depth; + currentMode->bitsPerPixel = bitsPerPixel; + currentMode->red_mask = red; + currentMode->green_mask = green; + currentMode->blue_mask = blue; + currentMode->visualClass = visualClass; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 8; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = (unsigned char*)info->LinearAddr; + + if(oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L; + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = ((otherPitch * Bpp) + 3) & ~3L; + currentMode->imageWidth = otherPitch; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = currentMode->imageHeight - + currentMode->viewportHeight; + } + + pMode = pMode->next; + if(pMode == firstMode) + break; + } + + return modes; +} + + +Bool +R128DGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + DGAModePtr modes = NULL; + int num = 0; + + /* 8 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 8, 8, + (pScrn->bitsPerPixel == 8), + (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth, + 0, 0, 0, PseudoColor); + + /* 15 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 16, 15, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 15) ? 0 : pScrn->displayWidth, + 0x7c00, 0x03e0, 0x001f, TrueColor); + + modes = R128SetupDGAMode (pScrn, modes, &num, 16, 15, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 15) ? 0 : pScrn->displayWidth, + 0x7c00, 0x03e0, 0x001f, DirectColor); + + /* 16 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 16) ? 0 : pScrn->displayWidth, + 0xf800, 0x07e0, 0x001f, TrueColor); + + modes = R128SetupDGAMode (pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + (pScrn->depth != 16) ? 0 : pScrn->displayWidth, + 0xf800, 0x07e0, 0x001f, DirectColor); + + /* 24 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 24, 24, + (pScrn->bitsPerPixel == 24), + (pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, TrueColor); + + modes = R128SetupDGAMode (pScrn, modes, &num, 24, 24, + (pScrn->bitsPerPixel == 24), + (pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, DirectColor); + + /* 32 */ + modes = R128SetupDGAMode (pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, TrueColor); + + modes = R128SetupDGAMode (pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth, + 0xff0000, 0x00ff00, 0x0000ff, DirectColor); + + info->numDGAModes = num; + info->DGAModes = modes; + + return DGAInit(pScreen, &R128_DGAFuncs, modes, num); +} + + +static Bool +R128_SetMode( + ScrnInfoPtr pScrn, + DGAModePtr pMode +){ + static R128FBLayout SavedLayouts[MAXSCREENS]; + int indx = pScrn->pScreen->myNum; + R128InfoPtr info = R128PTR(pScrn); + + if(!pMode) { /* restore the original mode */ + /* put the ScreenParameters back */ + if(info->DGAactive) + memcpy(&info->CurrentLayout, &SavedLayouts[indx], sizeof(R128FBLayout)); + + pScrn->currentMode = info->CurrentLayout.mode; + + R128SwitchMode(indx, pScrn->currentMode, 0); + R128AdjustFrame(indx, 0, 0, 0); + info->DGAactive = FALSE; + } else { + if(!info->DGAactive) { /* save the old parameters */ + memcpy(&SavedLayouts[indx], &info->CurrentLayout, sizeof(R128FBLayout)); + info->DGAactive = TRUE; + } + + info->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel; + info->CurrentLayout.depth = pMode->depth; + info->CurrentLayout.displayWidth = pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3); + info->CurrentLayout.pixel_bytes = pMode->bitsPerPixel / 8; + info->CurrentLayout.pixel_code = (pMode->bitsPerPixel != 16 + ? pMode->bitsPerPixel + : pMode->depth); + /* R128ModeInit() will set the mode field */ + + R128SwitchMode(indx, pMode->mode, 0); + } + + return TRUE; +} + + + +static int +R128_GetViewport( + ScrnInfoPtr pScrn +){ + R128InfoPtr info = R128PTR(pScrn); + + return info->DGAViewportStatus; +} + + +static void +R128_SetViewport( + ScrnInfoPtr pScrn, + int x, int y, + int flags +){ + R128InfoPtr info = R128PTR(pScrn); + + R128AdjustFrame(pScrn->pScreen->myNum, x, y, flags); + info->DGAViewportStatus = 0; /* FIXME */ +} + + +static void +R128_FillRect ( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned long color +){ + R128InfoPtr info = R128PTR(pScrn); + + if(info->accel) { + (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, ~0); + (*info->accel->SubsequentSolidFillRect)(pScrn, x, y, w, h); + SET_SYNC_FLAG(info->accel); + } +} + +static void +R128_BlitRect( + ScrnInfoPtr pScrn, + int srcx, int srcy, + int w, int h, + int dstx, int dsty +){ + R128InfoPtr info = R128PTR(pScrn); + + if(info->accel) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*info->accel->SetupForScreenToScreenCopy)( + pScrn, xdir, ydir, GXcopy, ~0, -1); + (*info->accel->SubsequentScreenToScreenCopy)( + pScrn, srcx, srcy, dstx, dsty, w, h); + SET_SYNC_FLAG(info->accel); + } +} + + +#if 0 +static void +R128_BlitTransRect( + ScrnInfoPtr pScrn, + int srcx, int srcy, + int w, int h, + int dstx, int dsty, + unsigned long color +){ + /* this one should be separate since the XAA function would + prohibit usage of ~0 as the key */ +} +#endif + + +static Bool +R128_OpenFramebuffer( + ScrnInfoPtr pScrn, + char **name, + unsigned char **mem, + int *size, + int *offset, + int *flags +){ + R128InfoPtr info = R128PTR(pScrn); + + *name = NULL; /* no special device */ + *mem = (unsigned char*)info->LinearAddr; + *size = info->FbMapSize; + *offset = 0; + *flags = /* DGA_NEED_ROOT */ 0; /* don't need root, just /dev/mem access */ + + return TRUE; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c new file mode 100644 index 000000000..816dbebee --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c @@ -0,0 +1,1280 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.2 2000/11/03 01:15:49 martin Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * Rickard E. Faith <faith@precisioninsight.com> + * Daryll Strauss <daryll@precisioninsight.com> + * + */ + + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86RAC.h" +#include "xf86cmap.h" +#include "xf86fbman.h" + + /* Backing store, software cursor, and + colormap initialization */ +#include "mibstore.h" +#include "mipointer.h" +#include "micmap.h" + + /* CFB support */ +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" + + /* Driver data structures */ +#include "r128.h" +#include "r128_reg.h" +#include "r128_version.h" + +#define R128_WATERMARK_L 16 +#define R128_WATERMARK_M 8 +#define R128_WATERMARK_N 8 +#define R128_WATERMARK_K 128 + +static int CCEFifoSlots = 0; + +#define R128CCEWaitForFifo(pScrn, entries) \ +do { \ + if (CCEFifoSlots < entries) R128WaitForFifoFunction(pScrn, entries); \ + CCEFifoSlots -= entries; \ +} while (0) + +/* Wait for at least `entries' slots are free. The actual number of + slots available is stored in info->CCEFifoSize. */ +static void R128CCEWaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + CCEFifoSlots = INREG(R128_PM4_STAT) & R128_PM4_FIFOCNT_MASK; + if (CCEFifoSlots >= entries) return; + } + R128EngineReset(pScrn); + if (info->CCE2D) R128CCEStart(pScrn); + } +} + +/* Wait until the CCE is completely idle: the FIFO has drained and the + CCE is idle. */ +void R128CCEWaitForIdle(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return; + + if (R128CCE_USE_RING_BUFFER(info->CCEMode)) { + volatile CARD32 *r128RingReadPtr = + (volatile CARD32 *)(info->ringReadPtr); + R128SAREAPrivPtr pSAREAPriv; + + OUTREGP(R128_PM4_BUFFER_DL_WPTR, + R128_PM4_BUFFER_DL_DONE, ~R128_PM4_BUFFER_DL_DONE); + + pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (*r128RingReadPtr == pSAREAPriv->ringWrite) { + int pm4stat = INREG(R128_PM4_STAT); + if ((pm4stat & R128_PM4_FIFOCNT_MASK) >= info->CCEFifoSize + && !(pm4stat & (R128_PM4_BUSY|R128_PM4_GUI_ACTIVE))) { + R128EngineFlush(pScrn); + return; + } + } + } + R128EngineReset(pScrn); + if (info->CCE2D) R128CCEStart(pScrn); + } + } else { + R128CCEWaitForFifoFunction(pScrn, info->CCEFifoSize); + + for (;;) { + for (i = 0; i < R128_TIMEOUT; i++) { + if (!(INREG(R128_PM4_STAT) + & (R128_PM4_BUSY | R128_PM4_GUI_ACTIVE))) { + R128EngineFlush(pScrn); + return; + } + } + R128EngineReset(pScrn); + if (info->CCE2D) R128CCEStart(pScrn); + } + } +} + +/* Reset the ring buffer status, if the engine was reset */ +void R128CCEResetRing(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128SAREAPrivPtr pSAREAPriv; + volatile CARD32 *r128RingReadPtr; + + if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return; + + r128RingReadPtr = (volatile CARD32 *)(info->ringReadPtr); + pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen); + + OUTREG(R128_PM4_BUFFER_DL_WPTR, 0); + OUTREG(R128_PM4_BUFFER_DL_RPTR, 0); + pSAREAPriv->ringWrite = 0; + *r128RingReadPtr = 0; + + /* Resetting the ring turns off the CCE */ + info->CCEInUse = FALSE; +} + +/* Start the CCE, but only if it is not already in use and the requested + mode is a CCE mode. The mode is stored in info->CCEMode. */ +void R128CCEStart(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + if (info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return; + + R128WaitForIdle(pScrn); + OUTREG(R128_PM4_BUFFER_CNTL, info->CCEMode | info->ringSizeLog2QW); + (void)INREG(R128_PM4_BUFFER_ADDR); /* as per the sample code */ + OUTREG(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN); + info->CCEInUse = TRUE; +} + +/* Stop the CCE, but only if it is in use and the requested mode is not + the non-CCE mode. This function also flushes any outstanding + requests before switching modes.*/ +void R128CCEStop(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + if (!info->CCEInUse || info->CCEMode == R128_PM4_NONPM4) return; + + R128CCEWaitForIdle(pScrn); + OUTREG(R128_PM4_MICRO_CNTL, 0); + OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4); + R128EngineReset(pScrn); + info->CCEInUse = FALSE; +} + +/* Initialize the visual configs that are supported by the hardware. + These are combined with the visual configs that the indirect + rendering core supports, and the intersection is exported to the + client. */ +static Bool R128InitVisualConfigs(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + int numConfigs = 0; + __GLXvisualConfig *pConfigs = 0; + R128ConfigPrivPtr pR128Configs = 0; + R128ConfigPrivPtr *pR128ConfigPtrs = 0; + int i, accum, stencil; + + switch (info->CurrentLayout.pixel_code) { + case 8: /* 8bpp mode is not support */ + case 15: /* FIXME */ + case 24: /* FIXME */ + return FALSE; + +#define R128_USE_ACCUM 1 +#define R128_USE_STENCIL 1 + + case 16: + numConfigs = 1; + if (R128_USE_ACCUM) numConfigs *= 2; + if (R128_USE_STENCIL) numConfigs *= 2; + + if (!(pConfigs + = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), + numConfigs))) { + return FALSE; + } + if (!(pR128Configs + = (R128ConfigPrivPtr)xnfcalloc(sizeof(R128ConfigPrivRec), + numConfigs))) { + xfree(pConfigs); + return FALSE; + } + if (!(pR128ConfigPtrs + = (R128ConfigPrivPtr*)xnfcalloc(sizeof(R128ConfigPrivPtr), + numConfigs))) { + xfree(pConfigs); + xfree(pR128Configs); + return FALSE; + } + + i = 0; + for (accum = 0; accum <= R128_USE_ACCUM; accum++) { + for (stencil = 0; stencil <= R128_USE_STENCIL; stencil++) { + pR128ConfigPtrs[i] = &pR128Configs[i]; + + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 5; + pConfigs[i].greenSize = 6; + pConfigs[i].blueSize = 5; + pConfigs[i].alphaSize = 0; + pConfigs[i].redMask = 0x0000F800; + pConfigs[i].greenMask = 0x000007E0; + pConfigs[i].blueMask = 0x0000001F; + pConfigs[i].alphaMask = 0x00000000; + if (accum) { /* Simulated in software */ + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 0; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + pConfigs[i].doubleBuffer = TRUE; + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 16; + pConfigs[i].depthSize = 16; + if (stencil) + pConfigs[i].stencilSize = 8; /* Simulated in software */ + else + pConfigs[i].stencilSize = 0; + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + pConfigs[i].visualRating = GLX_NONE_EXT; + pConfigs[i].transparentPixel = GLX_NONE; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + break; + case 32: + numConfigs = 1; + if (R128_USE_ACCUM) numConfigs *= 2; + if (R128_USE_STENCIL) numConfigs *= 2; + + if (!(pConfigs + = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), + numConfigs))) { + return FALSE; + } + if (!(pR128Configs + = (R128ConfigPrivPtr)xnfcalloc(sizeof(R128ConfigPrivRec), + numConfigs))) { + xfree(pConfigs); + return FALSE; + } + if (!(pR128ConfigPtrs + = (R128ConfigPrivPtr*)xnfcalloc(sizeof(R128ConfigPrivPtr), + numConfigs))) { + xfree(pConfigs); + xfree(pR128Configs); + return FALSE; + } + + i = 0; + for (accum = 0; accum <= R128_USE_ACCUM; accum++) { + for (stencil = 0; stencil <= R128_USE_STENCIL; stencil++) { + pR128ConfigPtrs[i] = &pR128Configs[i]; + + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 8; + pConfigs[i].greenSize = 8; + pConfigs[i].blueSize = 8; + pConfigs[i].alphaSize = 8; + pConfigs[i].redMask = 0x00FF0000; + pConfigs[i].greenMask = 0x0000FF00; + pConfigs[i].blueMask = 0x000000FF; + pConfigs[i].alphaMask = 0xFF000000; + if (accum) { /* Simulated in software */ + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 16; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + pConfigs[i].doubleBuffer = TRUE; + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 24; + if (stencil) { + pConfigs[i].depthSize = 24; + pConfigs[i].stencilSize = 8; + } else { + pConfigs[i].depthSize = 32; + pConfigs[i].stencilSize = 0; + } + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + pConfigs[i].visualRating = GLX_NONE_EXT; + pConfigs[i].transparentPixel = GLX_NONE; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + break; + } + + info->numVisualConfigs = numConfigs; + info->pVisualConfigs = pConfigs; + info->pVisualConfigsPriv = pR128Configs; + GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pR128ConfigPtrs); + return TRUE; +} + +/* Create the Rage 128-specific context information */ +static Bool R128CreateContext(ScreenPtr pScreen, VisualPtr visual, + drmContext hwContext, void *pVisualConfigPriv, + DRIContextType contextStore) +{ + /* Nothing yet */ + return TRUE; +} + +/* Destroy the Rage 128-specific context information */ +static void R128DestroyContext(ScreenPtr pScreen, drmContext hwContext, + DRIContextType contextStore) +{ + /* Nothing yet */ +} + +/* Called when the X server is woken up to allow the last client's + context to be saved and the X server's context to be loaded. This is + not necessary for the Rage 128 since the client detects when it's + context is not currently loaded and then load's it itself. Since the + registers to start and stop the CCE are privileged, only the X server + can start/stop the engine. */ +static void R128EnterServer(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + if (info->accel) info->accel->NeedToSync = TRUE; + +#if 1 + if (!info->CCE2D) R128CCEStop(pScrn); +#else + if (info->CCE2D) R128CCEWaitForIdle(pScrn); + else R128CCEStop(pScrn); +#endif +} + +/* Called when the X server goes to sleep to allow the X server's + context to be saved and the last client's context to be loaded. This + is not necessary for the Rage 128 since the client detects when it's + context is not currently loaded and then load's it itself. Since the + registers to start and stop the CCE are privileged, only the X server + can start/stop the engine. */ +static void R128LeaveServer(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + +#if 1 + if (!info->CCE2D) R128CCEStart(pScrn); +#else + if (info->CCE2D) R128CCEWaitForIdle(pScrn); + else R128CCEStart(pScrn); +#endif +} + +/* Contexts can be swapped by the X server if necessary. This callback + is currently only used to perform any functions necessary when + entering or leaving the X server, and in the future might not be + necessary. */ +static void R128DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, + DRIContextType oldContextType, void *oldContext, + DRIContextType newContextType, void *newContext) +{ + if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) && + (newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */ + R128EnterServer(pScreen); + } + if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) && + (newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */ + R128LeaveServer(pScreen); + } +} + +/* Initialize the state of the back and depth buffers. */ +static void R128DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx) +{ + /* FIXME: This routine needs to have acceleration turned on */ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + BoxPtr pbox; + int nbox; + int depth; + + /* FIXME: Use accel when CCE 2D code is written */ + if (info->CCE2D) return; + + /* FIXME: This should be based on the __GLXvisualConfig info */ + switch (pScrn->bitsPerPixel) { + case 8: depth = 0x000000ff; break; + case 16: depth = 0x0000ffff; break; + case 24: depth = 0x00ffffff; break; + case 32: depth = 0xffffffff; break; + default: depth = 0x00000000; break; + } + + /* FIXME: Copy XAAPaintWindow() and use REGION_TRANSLATE() */ + /* FIXME: Only initialize the back and depth buffers for contexts + that request them */ + + pbox = REGION_RECTS(prgn); + nbox = REGION_NUM_RECTS(prgn); + + (*info->accel->SetupForSolidFill)(pScrn, 0, GXcopy, -1); + for (; nbox; nbox--, pbox++) { + (*info->accel->SubsequentSolidFillRect)(pScrn, + pbox->x1 + info->fbX, + pbox->y1 + info->fbY, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + (*info->accel->SubsequentSolidFillRect)(pScrn, + pbox->x1 + info->backX, + pbox->y1 + info->backY, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + } + + (*info->accel->SetupForSolidFill)(pScrn, depth, GXcopy, -1); + for (; nbox; nbox--, pbox++) + (*info->accel->SubsequentSolidFillRect)(pScrn, + pbox->x1 + info->depthX, + pbox->y1 + info->depthY, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + + info->accel->NeedToSync = TRUE; +} + +/* Copy the back and depth buffers when the X server moves a window. */ +static void R128DRIMoveBuffers(WindowPtr pWin, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 indx) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + /* FIXME: This routine needs to have acceleration turned on */ + /* FIXME: Copy XAACopyWindow() and use REGION_TRANSLATE() */ + /* FIXME: Only initialize the back and depth buffers for contexts + that request them */ + + /* FIXME: Use accel when CCE 2D code is written */ + if (info->CCE2D) return; +} + +/* Initialize the AGP state. Request memory for use in AGP space, and + initialize the Rage 128 registers to point to that memory. */ +static Bool R128DRIAgpInit(R128InfoPtr info, ScreenPtr pScreen) +{ + unsigned char *R128MMIO = info->MMIO; + unsigned long mode; + unsigned int vendor, device; + int ret; + unsigned long cntl; + int s, l; + int flags; + + if (drmAgpAcquire(info->drmFD) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not available\n"); + return FALSE; + } + + /* Modify the mode if the default mode is + not appropriate for this particular + combination of graphics card and AGP + chipset. */ + + mode = drmAgpGetMode(info->drmFD); /* Default mode */ + vendor = drmAgpVendorId(info->drmFD); + device = drmAgpDeviceId(info->drmFD); + + mode &= ~R128_AGP_MODE_MASK; + switch (info->agpMode) { + case 2: mode |= R128_AGP_2X_MODE; + case 1: default: mode |= R128_AGP_1X_MODE; + } + + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", + mode, vendor, device, + info->PciInfo->vendor, + info->PciInfo->chipType); + + if (drmAgpEnable(info->drmFD, mode) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n"); + drmAgpRelease(info->drmFD); + return FALSE; + } + + info->agpOffset = 0; + + if ((ret = drmAgpAlloc(info->drmFD, info->agpSize*1024*1024, 0, NULL, + &info->agpMemHandle)) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret); + drmAgpRelease(info->drmFD); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] %d kB allocated with handle 0x%08x\n", + info->agpSize*1024, info->agpMemHandle); + + if (drmAgpBind(info->drmFD, info->agpMemHandle, info->agpOffset) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not bind\n"); + drmAgpFree(info->drmFD, info->agpMemHandle); + drmAgpRelease(info->drmFD); + return FALSE; + } + + /* Initialize the CCE ring buffer data */ + info->ringStart = info->agpOffset; + info->ringMapSize = info->ringSize*1024*1024 + 4096; + info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; + + info->ringReadOffset = info->ringStart + info->ringMapSize; + info->ringReadMapSize = 4096; + + /* Reserve space for the vertex buffer */ + info->vbStart = info->ringReadOffset + info->ringReadMapSize; + info->vbMapSize = info->vbSize*1024*1024; + + /* Reserve space for the indirect buffer */ + info->indStart = info->vbStart + info->vbMapSize; + info->indMapSize = info->indSize*1024*1024; + + /* Reserve the rest for AGP textures */ + info->agpTexStart = info->indStart + info->indMapSize; + s = (info->agpSize*1024*1024 - info->agpTexStart); + l = R128MinBits((s-1) / R128_NR_TEX_REGIONS); + if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; + info->agpTexMapSize = (s >> l) << l; + info->log2AGPTexGran = l; + + if (info->CCESecure) flags = DRM_READ_ONLY; + else flags = 0; + + if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize, + DRM_AGP, flags, &info->ringHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add ring mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] ring handle = 0x%08lx\n", info->ringHandle); + + if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize, + (drmAddressPtr)&info->ring) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Ring mapped at 0x%08lx\n", + (unsigned long)info->ring); + + if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize, + DRM_AGP, flags, &info->ringReadPtrHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add ring read ptr mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] ring read ptr handle = 0x%08lx\n", + info->ringReadPtrHandle); + + if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, + (drmAddressPtr)&info->ringReadPtr) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map ring read ptr\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Ring read ptr mapped at 0x%08lx\n", + (unsigned long)info->ringReadPtr); + + if (drmAddMap(info->drmFD, info->vbStart, info->vbMapSize, + DRM_AGP, 0, &info->vbHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add vertex buffers mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] vertex buffers handle = 0x%08lx\n", info->vbHandle); + + if (drmMap(info->drmFD, info->vbHandle, info->vbMapSize, + (drmAddressPtr)&info->vb) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map vertex buffers\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Vertex buffers mapped at 0x%08lx\n", + (unsigned long)info->vb); + + if (drmAddMap(info->drmFD, info->indStart, info->indMapSize, + DRM_AGP, flags, &info->indHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add indirect buffers mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] indirect buffers handle = 0x%08lx\n", info->indHandle); + + if (drmMap(info->drmFD, info->indHandle, info->indMapSize, + (drmAddressPtr)&info->ind) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map indirect buffers\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Indirect buffers mapped at 0x%08lx\n", + (unsigned long)info->ind); + + if (drmAddMap(info->drmFD, info->agpTexStart, info->agpTexMapSize, + DRM_AGP, 0, &info->agpTexHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add AGP texture map mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] AGP texture map handle = 0x%08lx\n", + info->agpTexHandle); + + if (drmMap(info->drmFD, info->agpTexHandle, info->agpTexMapSize, + (drmAddressPtr)&info->agpTex) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map AGP texture map\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] AGP Texture map mapped at 0x%08lx\n", + (unsigned long)info->agpTex); + + /* Initialize Rage 128's AGP registers */ + cntl = INREG(R128_AGP_CNTL); + cntl &= ~R128_AGP_APER_SIZE_MASK; + switch (info->agpSize) { + case 256: cntl |= R128_AGP_APER_SIZE_256MB; break; + case 128: cntl |= R128_AGP_APER_SIZE_128MB; break; + case 64: cntl |= R128_AGP_APER_SIZE_64MB; break; + case 32: cntl |= R128_AGP_APER_SIZE_32MB; break; + case 16: cntl |= R128_AGP_APER_SIZE_16MB; break; + case 8: cntl |= R128_AGP_APER_SIZE_8MB; break; + case 4: cntl |= R128_AGP_APER_SIZE_4MB; break; + default: + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Illegal aperture size %d kB\n", + info->agpSize*1024); + return FALSE; + } + OUTREG(R128_AGP_BASE, info->ringHandle); /* Ring buf is at AGP offset 0 */ + OUTREG(R128_AGP_CNTL, cntl); + + return TRUE; +} + +/* Fake the vertex buffers for PCI cards. */ +static Bool R128DRIPciInit(R128InfoPtr info) +{ + info->vbStart = 0; + info->vbMapSize = info->vbSize*1024*1024; + + return TRUE; +} + +/* Add a map for the MMIO registers that will be accessed by any + DRI-based clients. */ +static Bool R128DRIMapInit(R128InfoPtr info, ScreenPtr pScreen) +{ + int flags; + + if (info->CCESecure) flags = DRM_READ_ONLY; + else flags = 0; + + /* Map registers */ + info->registerSize = R128_MMIOSIZE; + if (drmAddMap(info->drmFD, info->MMIOAddr, info->registerSize, + DRM_REGISTERS, flags, &info->registerHandle) < 0) { + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] register handle = 0x%08lx\n", info->registerHandle); + + return TRUE; +} + +/* Initialize the ring buffer state for use in the X server and any + DRI-based clients. */ +static void R128DRICCEInitRingBuffer(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + unsigned long addr; + + /* FIXME: When we use the CCE for the X server, we should move this + function (and the support functions above) to r128_accel.c */ + + /* The manual (p. 2) says this address is + in "VM space". This means it's an + offset from the start of AGP space. */ + OUTREG(R128_PM4_BUFFER_OFFSET, info->ringStart | 0x02000000); + + OUTREG(R128_PM4_BUFFER_DL_WPTR, 0); + OUTREG(R128_PM4_BUFFER_DL_RPTR, 0); + + /* DL_RPTR_ADDR is a physical address. + This should be in the SAREA. */ + *(volatile long unsigned *)(info->ringReadPtr) = 0; + OUTREG(R128_PM4_BUFFER_DL_RPTR_ADDR, (info->ringReadPtrHandle)); + + /* Set watermark control */ + OUTREG(R128_PM4_BUFFER_WM_CNTL, + ((R128_WATERMARK_L/4) << R128_WMA_SHIFT) + | ((R128_WATERMARK_M/4) << R128_WMB_SHIFT) + | ((R128_WATERMARK_N/4) << R128_WMC_SHIFT) + | ((R128_WATERMARK_K/64) << R128_WB_WM_SHIFT)); + + addr = INREG(R128_PM4_BUFFER_ADDR); /* Force read. Why? Because it's + in the examples... */ + +#if 0 + R128CCEWaitForIdle(pScrn); +#endif + + /* Turn on bus mastering */ + info->BusCntl &= ~R128_BUS_MASTER_DIS; + OUTREGP(R128_BUS_CNTL, 0, ~R128_BUS_MASTER_DIS); +} + +/* Initialize the kernel data structures. */ +static int R128DRIKernelInit(R128InfoPtr info) +{ + drmR128Init drmInfo; + + drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); + drmInfo.is_pci = info->IsPCI; + drmInfo.cce_mode = info->CCEMode; + drmInfo.cce_fifo_size = info->CCEFifoSize; + drmInfo.cce_secure = info->CCESecure; + drmInfo.ring_size = info->ringSize*1024*1024; + drmInfo.usec_timeout = info->CCEusecTimeout; + + drmInfo.fb_offset = info->LinearAddr; + drmInfo.agp_ring_offset = info->ringHandle; + drmInfo.agp_read_ptr_offset = info->ringReadPtrHandle; + drmInfo.agp_vertbufs_offset = info->vbHandle; + drmInfo.agp_indbufs_offset = info->indHandle; + drmInfo.agp_textures_offset = info->agpTexHandle; + drmInfo.mmio_offset = info->registerHandle; + + if (drmR128InitCCE(info->drmFD, &drmInfo) < 0) return FALSE; + + return TRUE; +} + +/* Add a map for the vertex buffers that will be accessed by any + DRI-based clients. */ +static Bool R128DRIBufInit(R128InfoPtr info, ScreenPtr pScreen) +{ + /* Initialize vertex buffers */ + if ((info->vbNumBufs = drmAddBufs(info->drmFD, + info->vbMapSize / info->vbBufSize, + info->vbBufSize, + DRM_AGP_BUFFER, + info->vbStart)) <= 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Could not create vertex buffers list\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Added %d %d byte vertex buffers\n", + info->vbNumBufs, info->vbBufSize); + + if (drmMarkBufs(info->drmFD, 0.133333, 0.266666)) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Failed to mark vertex buffers list\n"); + return FALSE; + } + + if (!(info->vbBufs = drmMapBufs(info->drmFD))) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Failed to map vertex buffers list\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Mapped %d vertex buffers\n", + info->vbBufs->count); + + return TRUE; +} + +/* Load the microcode for the CCE */ +static void R128DRILoadMicrocode(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + unsigned long R128Microcode[] = { + /* CCE microcode (from ATI) */ + 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, 1617039951, + 0, 774592877, 0, 1987540286, 0, 2307490946U, 0, 599558925, 0, 589505315, 0, + 596487092, 0, 589505315, 1, 11544576, 1, 206848, 1, 311296, 1, 198656, 2, + 912273422, 11, 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, + 28, 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, 30, 1, + 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, 1, 15630, 1, 51200, + 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, 15717, 1, 15718, 2, 43, 1, + 15936948, 1, 570480831, 1, 14715071, 12, 322123831, 1, 33953125, 12, 55, 1, + 33559908, 1, 15718, 2, 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, + 509952, 1, 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1, + 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, 15975928, 1, + 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, 268449859, 2, 10307, 12, + 176, 1, 15734, 1, 15735, 1, 15630, 1, 15631, 1, 5253120, 6, 3145810, 16, + 2150645232U, 1, 15864, 2, 82, 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, + 1, 7817, 1, 15729, 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, + 1, 16008, 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0, + 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, 180224, 1, + 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, 114880, 14, 125, 12, + 206975, 1, 33559995, 12, 198784, 0, 33570236, 1, 15803, 0, 15804, 3, + 294912, 1, 294912, 3, 442370, 1, 11544576, 0, 811612160, 1, 12593152, 1, + 11536384, 1, 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, + 14793, 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1, + 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, 114880, 14, + 159, 12, 198784, 1, 1109409213, 12, 198783, 1, 1107312059, 12, 198784, 1, + 1109409212, 2, 162, 1, 1075854781, 1, 1073757627, 1, 1075854780, 1, 540672, + 1, 10485760, 6, 3145894, 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, + 0, 0, 256, 14, 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, + 1, 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, 33560360, 1, + 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, 409611, 9, 188, 0, + 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 + }; + + R128WaitForIdle(pScrn); + + OUTREG(R128_PM4_MICROCODE_ADDR, 0); + for (i = 0; i < 256; i += 1) { + OUTREG(R128_PM4_MICROCODE_DATAH, R128Microcode[i*2]); + OUTREG(R128_PM4_MICROCODE_DATAL, R128Microcode[i*2 + 1]); + } +} + +/* Initialize the CCE state, and start the CCE (if used by the X server) */ +static void R128DRICCEInit(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + /* CCEMode is initialized in r128_driver.c */ + switch (info->CCEMode) { + case R128_PM4_NONPM4: info->CCEFifoSize = 0; break; + case R128_PM4_192PIO: info->CCEFifoSize = 192; break; + case R128_PM4_192BM: info->CCEFifoSize = 192; break; + case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break; + case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break; + case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break; + } + + if (info->CCE2D) { + /* Make sure the CCE is on for the X server */ + R128CCEStart(pScrn); + } else { + /* Make sure the CCE is off for the X server */ + OUTREG(R128_PM4_MICRO_CNTL, 0); + OUTREG(R128_PM4_BUFFER_CNTL, R128_PM4_NONPM4); + } +} + +/* Initialize the screen-specific data structures for the DRI and the + Rage 128. This is the main entry point to the device-specific + initialization code. It calls device-independent DRI functions to + create the DRI data structures and initialize the DRI state. */ +Bool R128DRIScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + DRIInfoPtr pDRIInfo; + R128DRIPtr pR128DRI; + int major, minor, patch; + drmVersionPtr version; + + /* Check that the GLX, DRI, and DRM modules have been loaded by testing + * for known symbols in each module. */ + if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIScreenInit")) return FALSE; + if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "R128DRIScreenInit failed (libdri.a too old)\n"); + return FALSE; + } + + /* Check the DRI version */ + DRIQueryVersion(&major, &minor, &patch); + if (major != 3 || minor != 0 || patch < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "R128DRIScreenInit failed " + "(DRI version = %d.%d.%d, expected 3.0.x). " + "Disabling DRI.\n", + major, minor, patch); + return FALSE; + } + + switch (info->CurrentLayout.pixel_code) { + case 8: + /* These modes are not supported (yet). */ + case 15: + case 24: + return FALSE; + + /* Only 16 and 32 color depths are supports currently. */ + case 16: + case 32: + break; + } + + /* Create the DRI data structure, and fill it in before calling the + DRIScreenInit(). */ + if (!(pDRIInfo = DRICreateInfoRec())) return FALSE; + + info->pDRIInfo = pDRIInfo; + pDRIInfo->drmDriverName = R128_DRIVER_NAME; + pDRIInfo->clientDriverName = R128_DRIVER_NAME; + pDRIInfo->busIdString = xalloc(64); + sprintf(pDRIInfo->busIdString, + "PCI:%d:%d:%d", + info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + pDRIInfo->ddxDriverMajorVersion = R128_VERSION_MAJOR; + pDRIInfo->ddxDriverMinorVersion = R128_VERSION_MINOR; + pDRIInfo->ddxDriverPatchVersion = R128_VERSION_PATCH; + pDRIInfo->frameBufferPhysicalAddress = info->LinearAddr; + pDRIInfo->frameBufferSize = info->FbMapSize; + pDRIInfo->frameBufferStride = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + pDRIInfo->ddxDrawableTableEntry = R128_MAX_DRAWABLES; + pDRIInfo->maxDrawableTableEntry = (SAREA_MAX_DRAWABLES + < R128_MAX_DRAWABLES + ? SAREA_MAX_DRAWABLES + : R128_MAX_DRAWABLES); + +#ifdef NOT_DONE + /* FIXME: Need to extend DRI protocol to pass this size back to + * client for SAREA mapping that includes a device private record + */ + pDRIInfo->SAREASize = + ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ + /* + shared memory device private rec */ +#else + /* For now the mapping works by using a fixed size defined + * in the SAREA header + */ + if (sizeof(XF86DRISAREARec)+sizeof(R128SAREAPriv)>SAREA_MAX) { + ErrorF("Data does not fit in SAREA\n"); + return FALSE; + } + pDRIInfo->SAREASize = SAREA_MAX; +#endif + + if (!(pR128DRI = (R128DRIPtr)xnfcalloc(sizeof(R128DRIRec),1))) { + DRIDestroyInfoRec(info->pDRIInfo); + info->pDRIInfo = NULL; + return FALSE; + } + pDRIInfo->devPrivate = pR128DRI; + pDRIInfo->devPrivateSize = sizeof(R128DRIRec); + pDRIInfo->contextSize = sizeof(R128DRIContextRec); + + pDRIInfo->CreateContext = R128CreateContext; + pDRIInfo->DestroyContext = R128DestroyContext; + pDRIInfo->SwapContext = R128DRISwapContext; + pDRIInfo->InitBuffers = R128DRIInitBuffers; + pDRIInfo->MoveBuffers = R128DRIMoveBuffers; + pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + + if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) { + xfree(pDRIInfo->devPrivate); + pDRIInfo->devPrivate = NULL; + DRIDestroyInfoRec(pDRIInfo); + pDRIInfo = NULL; + return FALSE; + } + + /* Check the r128 DRM version */ + version = drmGetVersion(info->drmFD); + if (version) { + if (version->version_major != 1 || + version->version_minor != 0 || + version->version_patchlevel < 0) { + /* incompatible drm version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "R128DRIScreenInit failed " + "(DRM version = %d.%d.%d, expected 1.0.x). " + "Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + R128DRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(version); + } + + /* Initialize AGP */ + if (!info->IsPCI && !R128DRIAgpInit(info, pScreen)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + /* Initialize PCI */ + if (info->IsPCI && !R128DRIPciInit(info)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + + /* DRIScreenInit doesn't add all the + common mappings. Add additional + mappings here. */ + if (!R128DRIMapInit(info, pScreen)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize the ring buffer */ + if (!info->IsPCI) R128DRICCEInitRingBuffer(pScrn); + + /* Initialize the kernel data structures */ + if (!R128DRIKernelInit(info)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize vertex buffers list */ + if (!info->IsPCI && !R128DRIBufInit(info, pScreen)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + + /* FIXME: When are these mappings unmapped? */ + + if (!R128InitVisualConfigs(pScreen)) { + R128DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Visual configs initialized\n"); + + /* Load the CCE Microcode */ + R128DRILoadMicrocode(pScrn); + + /* Reset the Graphics Engine */ + R128EngineReset(pScrn); + + return TRUE; +} + +/* Finish initializing the device-dependent DRI state, and call + DRIFinishScreenInit() to complete the device-independent DRI + initialization. */ +Bool R128DRIFinishScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + R128SAREAPrivPtr pSAREAPriv; + R128DRIPtr pR128DRI; + + /* Init and start the CCE */ + R128DRICCEInit(pScrn); + + pSAREAPriv = (R128SAREAPrivPtr)DRIGetSAREAPrivate(pScreen); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + info->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; + /* info->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */ + + pR128DRI = (R128DRIPtr)info->pDRIInfo->devPrivate; + pR128DRI->registerHandle = info->registerHandle; + pR128DRI->registerSize = info->registerSize; + + pR128DRI->ringHandle = info->ringHandle; + pR128DRI->ringMapSize = info->ringMapSize; + pR128DRI->ringSize = info->ringSize*1024*1024; + + pR128DRI->ringReadPtrHandle = info->ringReadPtrHandle; + pR128DRI->ringReadMapSize = info->ringReadMapSize; + + pR128DRI->vbHandle = info->vbHandle; + pR128DRI->vbMapSize = info->vbMapSize; + pR128DRI->vbOffset = info->vbStart; + pR128DRI->vbBufSize = info->vbBufSize; + + pR128DRI->indHandle = info->indHandle; + pR128DRI->indMapSize = info->indMapSize; + + pR128DRI->agpTexHandle = info->agpTexHandle; + pR128DRI->agpTexMapSize = info->agpTexMapSize; + pR128DRI->log2AGPTexGran = info->log2AGPTexGran; + pR128DRI->agpTexOffset = info->agpTexStart; + + pR128DRI->deviceID = info->Chipset; + pR128DRI->width = pScrn->virtualX; + pR128DRI->height = pScrn->virtualY; + pR128DRI->depth = pScrn->depth; + pR128DRI->bpp = pScrn->bitsPerPixel; + + pR128DRI->fbX = info->fbX; + pR128DRI->fbY = info->fbY; + pR128DRI->backX = info->backX; + pR128DRI->backY = info->backY; + pR128DRI->depthX = info->depthX; + pR128DRI->depthY = info->depthY; + pR128DRI->textureX = info->textureX; + pR128DRI->textureY = info->textureY; + pR128DRI->textureSize = info->textureSize; + pR128DRI->log2TexGran = info->log2TexGran; + + pR128DRI->IsPCI = info->IsPCI; + + pR128DRI->CCEMode = info->CCEMode; + pR128DRI->CCEFifoSize = info->CCEFifoSize; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "0x%08lx %d\n", + pR128DRI->registerHandle, pR128DRI->registerSize); + return DRIFinishScreenInit(pScreen); +} + +/* The screen is being closed, so clean up any state and free any + resources used by the DRI. */ +void R128DRICloseScreen(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + /* Stop the CCE if it is still in use */ + if (info->CCE2D) R128CCEStop(pScrn); + + /* De-allocate vertex buffers */ + if (info->vbBufs) { + drmUnmapBufs(info->vbBufs); + info->vbBufs = NULL; + } + + /* De-allocate all kernel resources */ + drmR128CleanupCCE(info->drmFD); + + /* De-allocate all AGP resources */ + if (info->agpTex) { + drmUnmap(info->agpTex, info->agpTexMapSize); + info->agpTex = NULL; + } + if (info->ind) { + drmUnmap(info->ind, info->indMapSize); + info->ind = NULL; + } + if (info->vb) { + drmUnmap(info->vb, info->vbMapSize); + info->vb = NULL; + } + if (info->ringReadPtr) { + drmUnmap(info->ringReadPtr, info->ringReadMapSize); + info->ringReadPtr = NULL; + } + if (info->ring) { + drmUnmap(info->ring, info->ringMapSize); + info->ring = NULL; + } + if (info->agpMemHandle) { + drmAgpUnbind(info->drmFD, info->agpMemHandle); + drmAgpFree(info->drmFD, info->agpMemHandle); + info->agpMemHandle = 0; + drmAgpRelease(info->drmFD); + } + + /* De-allocate all DRI resources */ + DRICloseScreen(pScreen); + + /* De-allocate all DRI data structures */ + if (info->pDRIInfo) { + if (info->pDRIInfo->devPrivate) { + xfree(info->pDRIInfo->devPrivate); + info->pDRIInfo->devPrivate = NULL; + } + DRIDestroyInfoRec(info->pDRIInfo); + info->pDRIInfo = NULL; + } + if (info->pVisualConfigs) { + xfree(info->pVisualConfigs); + info->pVisualConfigs = NULL; + } + if (info->pVisualConfigsPriv) { + xfree(info->pVisualConfigsPriv); + info->pVisualConfigsPriv = NULL; + } +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h new file mode 100644 index 000000000..d9cdda3aa --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h @@ -0,0 +1,115 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h,v 1.1 2000/11/02 16:55:33 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * Rickard E. Faith <faith@precisioninsight.com> + * + */ + +#ifndef _R128_DRI_ +#define _R128_DRI_ + +#include <xf86drm.h> + +/* DRI Driver defaults */ +#define R128_DEFAULT_CCE_PIO_MODE R128_PM4_64PIO_64VCBM_64INDBM +#define R128_DEFAULT_CCE_BM_MODE R128_PM4_64BM_64VCBM_64INDBM +#define R128_DEFAULT_AGP_MODE 2 +#define R128_DEFAULT_AGP_SIZE 8 /* MB (must be a power of 2 and > 4MB) */ +#define R128_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */ +#define R128_DEFAULT_VB_SIZE 1 /* MB (must be page aligned) */ +#define R128_DEFAULT_IND_SIZE 1 /* MB (must be page aligned) */ +#define R128_DEFAULT_AGP_TEX_SIZE 1 /* MB (must be page aligned) */ + +#define R128_DEFAULT_VB_BUF_SIZE 16384 /* bytes */ +#define R128_DEFAULT_CCE_TIMEOUT 10000 /* usecs */ + +#define R128_AGP_MAX_MODE 2 + +#define R128CCE_USE_RING_BUFFER(m) \ +(((m) == R128_PM4_192BM) || \ + ((m) == R128_PM4_128BM_64INDBM) || \ + ((m) == R128_PM4_64BM_128INDBM) || \ + ((m) == R128_PM4_64BM_64VCBM_64INDBM)) + +typedef struct { + /* MMIO register data */ + drmHandle registerHandle; + drmSize registerSize; + + /* CCE ring buffer data */ + drmHandle ringHandle; + drmSize ringMapSize; + int ringSize; + + /* CCE ring read pointer data */ + drmHandle ringReadPtrHandle; + drmSize ringReadMapSize; + + /* CCE vertex buffer data */ + drmHandle vbHandle; + drmSize vbMapSize; + int vbOffset; + int vbBufSize; + + /* CCE indirect buffer data */ + drmHandle indHandle; + drmSize indMapSize; + + /* CCE AGP Texture data */ + drmHandle agpTexHandle; + drmSize agpTexMapSize; + int log2AGPTexGran; + int agpTexOffset; + + /* DRI screen private data */ + int deviceID; /* PCI device ID */ + int width; /* Width in pixels of display */ + int height; /* Height in scanlines of display */ + int depth; /* Depth of display (8, 15, 16, 24) */ + int bpp; /* Bit depth of display (8, 16, 24, 32) */ + + int fbX; /* Start of frame buffer */ + int fbY; + int backX; /* Start of shared back buffer */ + int backY; + int depthX; /* Start of shared depth buffer */ + int depthY; + int textureX; /* Start of texture data in frame buffer */ + int textureY; + int textureSize; + int log2TexGran; + + int IsPCI; /* Current card is a PCI card */ + + int CCEMode; /* CCE mode that server/clients use */ + int CCEFifoSize; /* Size of the CCE command FIFO */ +} R128DRIRec, *R128DRIPtr; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h new file mode 100644 index 000000000..f26fe2bba --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h @@ -0,0 +1,53 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dripriv.h,v 1.1 2000/11/02 16:55:34 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_DRIPRIV_H_ +#define _R128_DRIPRIV_H_ + +#define R128_MAX_DRAWABLES 256 + +extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, + void **configprivs); + +typedef struct { + /* Nothing here yet */ + int dummy; +} R128ConfigPrivRec, *R128ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} R128DRIContextRec, *R128DRIContextPtr; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c new file mode 100644 index 000000000..008c1c553 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c @@ -0,0 +1,2839 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c,v 1.1 2000/11/02 16:55:35 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * Credits: + * + * Thanks to Alan Hourihane <alanh@fairlite.demon..co.uk> and SuSE for + * providing source code to their 3.3.x Rage 128 driver. Portions of + * this file are based on the initialization code for that driver. + * + * References: + * + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + * This server does not yet support these XFree86 4.0 features: + * DDC1 & DDC2 + * shadowfb + * overlay planes + * DGA + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86RAC.h" +#include "xf86cmap.h" +#include "xf86fbman.h" +#include "xf86int10.h" + /* Backing store, software cursor, and + colormap initialization */ +#include "mibstore.h" +#include "mipointer.h" +#include "micmap.h" + +#define USE_FB /* not until overlays */ +#ifdef USE_FB +#include "fb.h" +#else + /* CFB support */ +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#endif + /* Driver data structures */ +#include "r128.h" +#include "r128_probe.h" +#include "r128_reg.h" +#include "r128_version.h" + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + + + /* Forward definitions for driver functions */ +static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool R128SaveScreen(ScreenPtr pScreen, int mode); +static void R128Save(ScrnInfoPtr pScrn); +static void R128Restore(ScrnInfoPtr pScrn); +static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, int flags); +static Bool R128EnterVTFBDev(int scrnIndex, int flags); +static void R128LeaveVTFBDev(int scrnIndex, int flags); + +typedef enum { + OPTION_NOACCEL, + OPTION_SW_CURSOR, + OPTION_DAC_6BIT, + OPTION_DAC_8BIT, +#ifdef XF86DRI + OPTION_IS_PCI, + OPTION_CCE_PIO, + OPTION_NO_SECURITY, + OPTION_USEC_TIMEOUT, + OPTION_AGP_MODE, + OPTION_AGP_SIZE, + OPTION_RING_SIZE, + OPTION_VERT_SIZE, + OPTION_VBUF_SIZE, + OPTION_USE_CCE_2D, +#endif +#if 0 + /* FIXME: Disable CRTOnly until it is tested */ + OPTION_CRT, +#endif + OPTION_PANEL_WIDTH, + OPTION_PANEL_HEIGHT, + OPTION_PROG_FP_REGS, + OPTION_FBDEV +} R128Opts; + +OptionInfoRec R128Options[] = { + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC_8BIT, "Dac8Bit", OPTV_BOOLEAN, {0}, TRUE }, +#ifdef XF86DRI + { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CCE_PIO, "CCEPIOMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NO_SECURITY, "CCENoSecurity", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_USEC_TIMEOUT, "CCEusecTimeout", OPTV_INTEGER, {0}, FALSE }, + { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, + { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VERT_SIZE, "VBListSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VBUF_SIZE, "VBSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_USE_CCE_2D, "UseCCEfor2D", OPTV_BOOLEAN, {0}, FALSE }, +#endif +#if 0 + /* FIXME: Disable CRTOnly until it is tested */ + { OPTION_CRT, "CRTOnly", OPTV_BOOLEAN, {0}, FALSE }, +#endif + { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE }, + { OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE }, + { OPTION_PROG_FP_REGS, "ProgramFPRegs", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +R128RAMRec R128RAM[] = { /* Memory Specifications + From RAGE 128 Software Development + Manual (Technical Reference Manual P/N + SDK-G04000 Rev 0.01), page 3-21. */ + { 4, 4, 3, 3, 1, 3, 1, 16, 12, "128-bit SDR SGRAM 1:1" }, + { 4, 8, 3, 3, 1, 3, 1, 17, 13, "64-bit SDR SGRAM 1:1" }, + { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SGRAM 2:1" }, + { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SGRAM" }, +}; + +static const char *vgahwSymbols[] = { + "vgaHWGetHWRec", + "vgaHWFreeHWRec", + "vgaHWLock", + "vgaHWUnlock", + "vgaHWSave", + "vgaHWRestore", + NULL +}; + +static const char *fbdevHWSymbols[] = { + "fbdevHWInit", + "fbdevHWUseBuildinMode", + + "fbdevHWGetDepth", + "fbdevHWGetVidmem", + + /* colormap */ + "fbdevHWLoadPalette", + + /* ScrnInfo hooks */ + "fbdevHWSwitchMode", + "fbdevHWAdjustFrame", + "fbdevHWEnterVT", + "fbdevHWLeaveVT", + "fbdevHWValidMode", + "fbdevHWRestore", + "fbdevHWModeInit", + "fbdevHWSave", + + "fbdevHWUnmapMMIO", + "fbdevHWUnmapVidmem", + "fbdevHWMapMMIO", + "fbdevHWMapVidmem", + + NULL +}; + +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86DoEDID_DDC1", + "xf86DoEDID_DDC2", + NULL +}; + +#ifdef XFree86LOADER +#ifdef USE_FB +static const char *fbSymbols[] = { + "fbScreenInit", + NULL +}; +#else +static const char *cfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + "cfb24_32ScreenInit", + NULL +}; +#endif + +static const char *xaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + "XAAStippleScanlineFuncLSBFirst", + "XAAOverlayFBfuncs", + "XAACachePlanarMonoStipple", + "XAAScreenIndex", + NULL +}; + +static const char *xf8_32bppSymbols[] = { + "xf86Overlay8Plus32Init", + NULL +}; + +static const char *ramdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +#ifdef XF86DRI +static const char *drmSymbols[] = { + "drmAddBufs", + "drmAddMap", + "drmAvailable", + "drmCtlAddCommand", + "drmCtlInstHandler", + "drmGetInterruptFromBusID", + "drmMapBufs", + "drmMarkBufs", + "drmUnmapBufs", + "drmFreeVersion", + "drmGetVersion", + NULL +}; + +static const char *driSymbols[] = { + "DRIGetDrawableIndex", + "DRIFinishScreenInit", + "DRIDestroyInfoRec", + "DRICloseScreen", + "DRIDestroyInfoRec", + "DRIScreenInit", + "DRIDestroyInfoRec", + "DRICreateInfoRec", + "DRILock", + "DRIUnlock", + "DRIGetSAREAPrivate", + "DRIGetContext", + "DRIQueryVersion", + "GlxSetVisualConfigs", + NULL +}; +#endif + +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + NULL +}; +#endif + +/* Allocate our private R128InfoRec. */ +static Bool R128GetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate) return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(R128InfoRec), 1); + return TRUE; +} + +/* Free our private R128InfoRec. */ +static void R128FreeRec(ScrnInfoPtr pScrn) +{ + if (!pScrn || !pScrn->driverPrivate) return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} + +/* Memory map the MMIO region. Used during pre-init and by R128MapMem, + below. */ +static Bool R128MapMMIO(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->FBDev) { + info->MMIO = fbdevHWMapMMIO(pScrn); + } else { + info->MMIO = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, + info->PciTag, + info->MMIOAddr, + R128_MMIOSIZE); + } + + if (!info->MMIO) return FALSE; + return TRUE; +} + +/* Unmap the MMIO region. Used during pre-init and by R128UnmapMem, + below. */ +static Bool R128UnmapMMIO(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->FBDev) + fbdevHWUnmapMMIO(pScrn); + else { + xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, R128_MMIOSIZE); + } + info->MMIO = NULL; + return TRUE; +} + +/* Memory map the frame buffer. Used by R128MapMem, below. */ +static Bool R128MapFB(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->FBDev) { + info->FB = fbdevHWMapVidmem(pScrn); + } else { + info->FB = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_FRAMEBUFFER, + info->PciTag, + info->LinearAddr, + info->FbMapSize); + } + + if (!info->FB) return FALSE; + return TRUE; +} + +/* Unmap the frame buffer. Used by R128UnmapMem, below. */ +static Bool R128UnmapFB(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->FBDev) + fbdevHWUnmapVidmem(pScrn); + else + xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize); + info->FB = NULL; + return TRUE; +} + +/* Memory map the MMIO region and the frame buffer. */ +static Bool R128MapMem(ScrnInfoPtr pScrn) +{ + if (!R128MapMMIO(pScrn)) return FALSE; + if (!R128MapFB(pScrn)) { + R128UnmapMMIO(pScrn); + return FALSE; + } + return TRUE; +} + +/* Unmap the MMIO region and the frame buffer. */ +static Bool R128UnmapMem(ScrnInfoPtr pScrn) +{ + if (!R128UnmapMMIO(pScrn) || !R128UnmapFB(pScrn)) return FALSE; + return TRUE; +} + +/* Read PLL information */ +int R128INPLL(ScrnInfoPtr pScrn, int addr) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG8(R128_CLOCK_CNTL_INDEX, addr & 0x1f); + return INREG(R128_CLOCK_CNTL_DATA); +} + +#if 0 +/* Read PAL information (only used for debugging). */ +static int R128INPAL(int idx) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_PALETTE_INDEX, idx << 16); + return INREG(R128_PALETTE_DATA); +} +#endif + +/* Wait for vertical sync. */ +void R128WaitForVerticalSync(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + OUTREG(R128_GEN_INT_STATUS, R128_VSYNC_INT_AK); + for (i = 0; i < R128_TIMEOUT; i++) { + if (INREG(R128_GEN_INT_STATUS) & R128_VSYNC_INT) break; + } +} + +/* Blank screen. */ +static void R128Blank(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CRTC_EXT_CNTL, R128_CRTC_DISPLAY_DIS, ~R128_CRTC_DISPLAY_DIS); +} + +/* Unblank screen. */ +static void R128Unblank(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CRTC_EXT_CNTL, 0, ~R128_CRTC_DISPLAY_DIS); +} + +/* Compute log base 2 of val. */ +int R128MinBits(int val) +{ + int bits; + + if (!val) return 1; + for (bits = 0; val; val >>= 1, ++bits); + return bits; +} + +/* Compute n/d with rounding. */ +static int R128Div(int n, int d) +{ + return (n + (d / 2)) / d; +} + +/* Read the Video BIOS block and the FP registers (if applicable). */ +static Bool R128GetBIOSParameters(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + int i; + int FPHeader = 0; + +#define R128ReadBIOS(offset, buffer, length) \ + (info->BIOSFromPCI ? \ + xf86ReadPciBIOS(offset, info->PciTag, 0, buffer, length) : \ + xf86ReadBIOS(info->BIOSAddr, offset, buffer, length)) + +#define R128_BIOS8(v) (info->VBIOS[v]) +#define R128_BIOS16(v) (info->VBIOS[v] | \ + (info->VBIOS[(v) + 1] << 8)) +#define R128_BIOS32(v) (info->VBIOS[v] | \ + (info->VBIOS[(v) + 1] << 8) | \ + (info->VBIOS[(v) + 2] << 16) | \ + (info->VBIOS[(v) + 3] << 24)) + + if (!(info->VBIOS = xalloc(R128_VBIOS_SIZE))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Cannot allocate space for hold Video BIOS!\n"); + return FALSE; + } + + info->BIOSFromPCI = TRUE; + R128ReadBIOS(0x0000, info->VBIOS, R128_VBIOS_SIZE); + if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not detected in PCI space!\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Attempting to read Video BIOS from legacy ISA space!\n"); + info->BIOSFromPCI = FALSE; + info->BIOSAddr = 0x000c0000; + R128ReadBIOS(0x0000, info->VBIOS, R128_VBIOS_SIZE); + } + if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { + info->BIOSAddr = 0x00000000; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not found!\n"); + } + + if (info->HasPanelRegs) { + info->FPBIOSstart = 0; + + /* FIXME: There should be direct access to the start of the FP info + tables, but until we find out where that offset is stored, we + must search for the ATI signature string: "M3 ". */ + for (i = 4; i < R128_VBIOS_SIZE-8; i++) { + if (R128_BIOS8(i) == 'M' && + R128_BIOS8(i+1) == '3' && + R128_BIOS8(i+2) == ' ' && + R128_BIOS8(i+3) == ' ' && + R128_BIOS8(i+4) == ' ' && + R128_BIOS8(i+5) == ' ' && + R128_BIOS8(i+6) == ' ' && + R128_BIOS8(i+7) == ' ') { + FPHeader = i-2; + break; + } + } + + if (!FPHeader) return TRUE; + + /* Assume that only one panel is attached and supported */ + for (i = FPHeader+20; i < FPHeader+84; i += 2) { + if (R128_BIOS16(i) != 0) { + info->FPBIOSstart = R128_BIOS16(i); + break; + } + } + if (!info->FPBIOSstart) return TRUE; + + if (!info->PanelXRes) + info->PanelXRes = R128_BIOS16(info->FPBIOSstart+25); + if (!info->PanelYRes) + info->PanelYRes = R128_BIOS16(info->FPBIOSstart+27); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n", + info->PanelXRes, info->PanelYRes); + + info->PanelPwrDly = R128_BIOS8(info->FPBIOSstart+56); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: "); + for (i = 1; i <= 24; i++) + ErrorF("%c", R128_BIOS8(info->FPBIOSstart+i)); + ErrorF("\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: "); + i = R128_BIOS16(info->FPBIOSstart+29); + if (i & 1) ErrorF("Color, "); + else ErrorF("Monochrome, "); + if (i & 2) ErrorF("Dual(split), "); + else ErrorF("Single, "); + switch ((i >> 2) & 0x3f) { + case 0: ErrorF("STN"); break; + case 1: ErrorF("TFT"); break; + case 2: ErrorF("Active STN"); break; + case 3: ErrorF("EL"); break; + case 4: ErrorF("Plasma"); break; + default: ErrorF("UNKNOWN"); break; + } + ErrorF("\n"); + if (R128_BIOS8(info->FPBIOSstart+61) & 1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n"); + } else { + /* FIXME: Add Non-LVDS flat pael support */ + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Non-LVDS panel interface detected! " + "This support is untested and may not " + "function properly\n"); + } + } + + return TRUE; +} + +/* Read PLL parameters from BIOS block. Default to typical values if there + is no BIOS. */ +static Bool R128GetPLLParameters(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + R128PLLPtr pll = &info->pll; + CARD16 bios_header; + CARD16 pll_info_block; + + + if (!info->VBIOS) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not detected, using default PLL parameters!\n"); + /* These probably aren't going to work for + the card you are using. Specifically, + reference freq can be 29.50MHz, + 28.63MHz, or 14.32MHz. YMMV. */ + pll->reference_freq = 2950; + pll->reference_div = 65; + pll->min_pll_freq = 12500; + pll->max_pll_freq = 25000; + pll->xclk = 10300; + } else { + bios_header = R128_BIOS16(0x48); + pll_info_block = R128_BIOS16(bios_header + 0x30); + R128TRACE(("Header at 0x%04x; PLL Information at 0x%04x\n", + bios_header, pll_info_block)); + + pll->reference_freq = R128_BIOS16(pll_info_block + 0x0e); + pll->reference_div = R128_BIOS16(pll_info_block + 0x10); + pll->min_pll_freq = R128_BIOS32(pll_info_block + 0x12); + pll->max_pll_freq = R128_BIOS32(pll_info_block + 0x16); + pll->xclk = R128_BIOS16(pll_info_block + 0x08); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n", + pll->reference_freq, + pll->reference_div, + pll->min_pll_freq, + pll->max_pll_freq, + pll->xclk); + + return TRUE; +} + +/* This is called by R128PreInit to set up the default visual. */ +static Bool R128PreInitVisual(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (!xf86SetDepthBpp(pScrn, 8, 8, 8, (Support24bppFb + | Support32bppFb + | SupportConvert32to24 + ))) + return FALSE; + + switch (pScrn->depth) { + case 8: + case 15: + case 16: + case 24: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by %s driver\n", + pScrn->depth, R128_DRIVER_NAME); + return FALSE; + } + + xf86PrintDepthBpp(pScrn); + + info->fifo_slots = 0; + info->pix24bpp = xf86GetBppFromDepth(pScrn, pScrn->depth); + info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; + info->CurrentLayout.depth = pScrn->depth; + info->CurrentLayout.pixel_bytes = pScrn->bitsPerPixel / 8; + info->CurrentLayout.pixel_code = (pScrn->bitsPerPixel != 16 + ? pScrn->bitsPerPixel + : pScrn->depth); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n", + pScrn->depth, + info->CurrentLayout.pixel_bytes, + info->CurrentLayout.pixel_bytes > 1 ? "s" : "", + info->pix24bpp); + + + if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; + + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Default visual (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + return TRUE; + +} + +/* This is called by R128PreInit to handle all color weight issues. */ +static Bool R128PreInitWeight(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + /* Save flag for 6 bit DAC to use for + setting CRTC registers. Otherwise use + an 8 bit DAC, even if xf86SetWeight sets + pScrn->rgbBits to some value other than + 8. */ + info->dac6bits = FALSE; + if (pScrn->depth > 8) { + rgb defaultWeight = { 0, 0, 0 }; + if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE; + } else { + pScrn->rgbBits = 8; + if (xf86ReturnOptValBool(R128Options, OPTION_DAC_6BIT, FALSE)) { + pScrn->rgbBits = 6; + info->dac6bits = TRUE; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d bits per RGB (%d bit DAC)\n", + pScrn->rgbBits, info->dac6bits ? 6 : 8); + + return TRUE; + +} + +/* This is called by R128PreInit to handle config file overrides for things + like chipset and memory regions. Also determine memory size and type. + If memory type ever needs an override, put it in this routine. */ +static Bool R128PreInitConfig(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + EntityInfoPtr pEnt = info->pEnt; + GDevPtr dev = pEnt->device; + int offset = 0; /* RAM Type */ + MessageType from; + + /* Chipset */ + from = X_PROBED; + if (dev->chipset && *dev->chipset) { + info->Chipset = xf86StringToToken(R128Chipsets, dev->chipset); + from = X_CONFIG; + } else if (dev->chipID >= 0) { + info->Chipset = dev->chipID; + from = X_CONFIG; + } else { + info->Chipset = info->PciInfo->chipType; + } + pScrn->chipset = (char *)xf86TokenToString(R128Chipsets, info->Chipset); + + if (!pScrn->chipset) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04x is not recognized\n", info->Chipset); + return FALSE; + } + + if (info->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognized\n", pScrn->chipset); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, from, + "Chipset: \"%s\" (ChipID = 0x%04x)\n", + pScrn->chipset, + info->Chipset); + + /* Framebuffer */ + + from = X_PROBED; + info->LinearAddr = info->PciInfo->memBase[0] & 0xfc000000; + if (dev->MemBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Linear address override, using 0x%08x instead of 0x%08x\n", + dev->MemBase, + info->LinearAddr); + info->LinearAddr = dev->MemBase; + from = X_CONFIG; + } else if (!info->LinearAddr) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid linear framebuffer address\n"); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, + "Linear framebuffer at 0x%08lx\n", info->LinearAddr); + + /* MMIO registers */ + from = X_PROBED; + info->MMIOAddr = info->PciInfo->memBase[2] & 0xffffff00; + if (dev->IOBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MMIO address override, using 0x%08x instead of 0x%08x\n", + dev->IOBase, + info->MMIOAddr); + info->MMIOAddr = dev->IOBase; + from = X_CONFIG; + } else if (!info->MMIOAddr) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n"); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, + "MMIO registers at 0x%08lx\n", info->MMIOAddr); + + /* BIOS */ + from = X_PROBED; + info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000; + if (dev->BiosBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS address override, using 0x%08x instead of 0x%08x\n", + dev->BiosBase, + info->BIOSAddr); + info->BIOSAddr = dev->BiosBase; + from = X_CONFIG; + } + if (info->BIOSAddr) { + xf86DrvMsg(pScrn->scrnIndex, from, + "BIOS at 0x%08lx\n", info->BIOSAddr); + } + + /* Flat panel (part 1) */ + if (xf86GetOptValBool(R128Options, OPTION_PROG_FP_REGS, + &info->HasPanelRegs)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Turned flat panel register programming %s\n", + info->HasPanelRegs ? "on" : "off"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "\n\nWARNING: Forcing the driver to use/not use the flat panel registers\nmight damage your flat panel. Use at your *OWN* *RISK*.\n\n"); + } else { + switch (info->Chipset) { + case PCI_CHIP_RAGE128LE: + case PCI_CHIP_RAGE128LF: + case PCI_CHIP_RAGE128MF: + case PCI_CHIP_RAGE128ML: info->HasPanelRegs = TRUE; break; + case PCI_CHIP_RAGE128RE: + case PCI_CHIP_RAGE128RF: + case PCI_CHIP_RAGE128RK: + case PCI_CHIP_RAGE128RL: + case PCI_CHIP_RAGE128PF: + default: info->HasPanelRegs = FALSE; break; + } + } + + /* Read registers used to determine options */ + from = X_PROBED; + R128MapMMIO(pScrn); + R128MMIO = info->MMIO; + if (info->FBDev) + pScrn->videoRam = fbdevHWGetVidmem(pScrn) / 1024; + else + pScrn->videoRam = INREG(R128_CONFIG_MEMSIZE) / 1024; + info->MemCntl = INREG(R128_MEM_CNTL); + + info->BusCntl = INREG(R128_BUS_CNTL); + R128MMIO = NULL; + R128UnmapMMIO(pScrn); + + /* RAM */ + switch (info->MemCntl & 0x3) { + case 0: /* SDR SGRAM 1:1 */ + switch (info->Chipset) { + case PCI_CHIP_RAGE128LE: + case PCI_CHIP_RAGE128LF: + case PCI_CHIP_RAGE128MF: + case PCI_CHIP_RAGE128ML: + case PCI_CHIP_RAGE128RE: + case PCI_CHIP_RAGE128RF: offset = 0; break; /* 128-bit SDR SGRAM 1:1 */ + case PCI_CHIP_RAGE128RK: + case PCI_CHIP_RAGE128RL: + default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ + } + break; + case 1: offset = 2; break; /* 64-bit SDR SGRAM 2:1 */ + case 2: offset = 3; break; /* 64-bit DDR SGRAM */ + default: offset = 1; break; /* 64-bit SDR SGRAM 1:1 */ + } + info->ram = &R128RAM[offset]; + + if (dev->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Video RAM override, using %d kB instead of %d kB\n", + dev->videoRam, + pScrn->videoRam); + from = X_CONFIG; + pScrn->videoRam = dev->videoRam; + } + pScrn->videoRam &= ~1023; + info->FbMapSize = pScrn->videoRam * 1024; + xf86DrvMsg(pScrn->scrnIndex, from, + "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name); + + /* Flat panel (part 2) */ + if (info->HasPanelRegs) { +#if 1 + info->CRTOnly = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using flat panel for display\n"); +#else + /* Panel CRT mode override */ + if ((info->CRTOnly = xf86ReturnOptValBool(R128Options, + OPTION_CRT, FALSE))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using external CRT instead of " + "flat panel for display\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using flat panel for display\n"); + } +#endif + + /* Panel width/height overrides */ + info->PanelXRes = 0; + info->PanelYRes = 0; + if (xf86GetOptValInteger(R128Options, + OPTION_PANEL_WIDTH, &(info->PanelXRes))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Flat panel width: %d\n", info->PanelXRes); + } + if (xf86GetOptValInteger(R128Options, + OPTION_PANEL_HEIGHT, &(info->PanelYRes))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Flat panel height: %d\n", info->PanelYRes); + } + } else { + info->CRTOnly = FALSE; + } + +#ifdef XF86DRI + /* AGP/PCI */ + if (xf86ReturnOptValBool(R128Options, OPTION_IS_PCI, FALSE)) { + info->IsPCI = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI-only mode\n"); + } else { + switch (info->Chipset) { + case PCI_CHIP_RAGE128LE: + case PCI_CHIP_RAGE128RE: + case PCI_CHIP_RAGE128RK: info->IsPCI = TRUE; break; + case PCI_CHIP_RAGE128LF: + case PCI_CHIP_RAGE128MF: + case PCI_CHIP_RAGE128ML: + case PCI_CHIP_RAGE128RF: + case PCI_CHIP_RAGE128RL: + case PCI_CHIP_RAGE128PF: + default: info->IsPCI = FALSE; break; + } + } +#endif + + return TRUE; +} + +static Bool R128PreInitDDC(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + vbeInfoPtr pVbe; + + if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE; + xf86LoaderReqSymLists(ddcSymbols, NULL); + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,info->pEnt->index); + if (!pVbe) return FALSE; + + xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); + return TRUE; + } else + return FALSE; +} + +/* This is called by R128PreInit to initialize gamma correction. */ +static Bool R128PreInitGamma(ScrnInfoPtr pScrn) +{ + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScrn, zeros)) return FALSE; + return TRUE; +} + +/* This is called by R128PreInit to validate modes and compute parameters + for all of the valid modes. */ +static Bool R128PreInitModes(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + ClockRangePtr clockRanges; + int modesFound; + char *mod = NULL; + const char *Sym = NULL; + + /* Get mode information */ + pScrn->progClock = TRUE; + clockRanges = xnfcalloc(sizeof(*clockRanges), 1); + clockRanges->next = NULL; + clockRanges->minClock = info->pll.min_pll_freq; + clockRanges->maxClock = info->pll.max_pll_freq * 10; + clockRanges->clockIndex = -1; + if (info->HasPanelRegs) { + clockRanges->interlaceAllowed = FALSE; + clockRanges->doubleScanAllowed = FALSE; + } else { + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = TRUE; + } + + modesFound = xf86ValidateModes(pScrn, + pScrn->monitor->Modes, + pScrn->display->modes, + clockRanges, + NULL, /* linePitches */ + 8 * 64, /* minPitch */ + 8 * 1024, /* maxPitch */ + 64 * pScrn->bitsPerPixel, /* pitchInc */ + 128, /* minHeight */ + 2048, /* maxHeight */ + pScrn->virtualX, + pScrn->virtualY, + info->FbMapSize, + LOOKUP_BEST_REFRESH); + + if (modesFound < 1 && info->FBDev) { + fbdevHWUseBuildinMode(pScrn); + pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ + modesFound = 1; + } + + if (modesFound == -1) return FALSE; + xf86PruneDriverModes(pScrn); + if (!modesFound || !pScrn->modes) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + return FALSE; + } + xf86SetCrtcForModes(pScrn, 0); + pScrn->currentMode = pScrn->modes; + xf86PrintModes(pScrn); + + /* Set DPI */ + xf86SetDpi(pScrn, 0, 0); + + /* Get ScreenInit function */ +#ifdef USE_FB + mod = "fb"; + Sym = "fbScreenInit"; +#else + switch (pScrn->bitsPerPixel) { + case 8: mod = "cfb"; Sym = "cfbScreenInit"; break; + case 16: mod = "cfb16"; Sym = "cfb16ScreenInit"; break; + case 24: + if (info->pix24bpp == 24) { + mod = "cfb24"; Sym = "cfb24ScreenInit"; + } else { + mod = "xf24_32bpp"; Sym = "cfb24_32ScreenInit"; + } + break; + case 32: mod = "cfb32"; Sym = "cfb32ScreenInit"; break; + } +#endif + if (mod && !xf86LoadSubModule(pScrn, mod)) return FALSE; + xf86LoaderReqSymbols(Sym, NULL); +#ifdef USE_FB +#ifdef RENDER + xf86LoaderReqSymbols("fbPictureInit", NULL); +#endif +#endif + + info->CurrentLayout.displayWidth = pScrn->displayWidth; + info->CurrentLayout.mode = pScrn->currentMode; + + return TRUE; +} + +/* This is called by R128PreInit to initialize the hardware cursor. */ +static Bool R128PreInitCursor(ScrnInfoPtr pScrn) +{ + if (!xf86ReturnOptValBool(R128Options, OPTION_SW_CURSOR, FALSE)) { + if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; + } + return TRUE; +} + +/* This is called by R128PreInit to initialize hardware acceleration. */ +static Bool R128PreInitAccel(ScrnInfoPtr pScrn) +{ + if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE)) { + if (!xf86LoadSubModule(pScrn, "xaa")) return FALSE; + } + return TRUE; +} + +static Bool R128PreInitInt10(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); +#if 1 + if (xf86LoadSubModule(pScrn, "int10")) { + xf86Int10InfoPtr pInt; + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); + pInt = xf86InitInt10(info->pEnt->index); + xf86FreeInt10(pInt); + } +#endif + return TRUE; +} + +#ifdef XF86DRI +static Bool R128PreInitDRI(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (info->IsPCI) { + info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; + } else if (xf86ReturnOptValBool(R128Options, OPTION_CCE_PIO, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CCE into PIO mode\n"); + info->CCEMode = R128_DEFAULT_CCE_PIO_MODE; + } else { + info->CCEMode = R128_DEFAULT_CCE_BM_MODE; + } + + if (xf86ReturnOptValBool(R128Options, OPTION_USE_CCE_2D, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using CCE for 2D\n"); + info->CCE2D = TRUE; + } else { + info->CCE2D = FALSE; + } + + if (xf86ReturnOptValBool(R128Options, OPTION_NO_SECURITY, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "WARNING!!! CCE Security checks disabled!!! **********\n"); + info->CCESecure = FALSE; + } else { + info->CCESecure = TRUE; + } + + info->agpMode = R128_DEFAULT_AGP_MODE; + info->agpSize = R128_DEFAULT_AGP_SIZE; + info->ringSize = R128_DEFAULT_RING_SIZE; + info->vbSize = R128_DEFAULT_VB_SIZE; + info->indSize = R128_DEFAULT_IND_SIZE; + info->agpTexSize = R128_DEFAULT_AGP_TEX_SIZE; + + info->vbBufSize = R128_DEFAULT_VB_BUF_SIZE; + + info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT; + + if (!info->IsPCI) { + if (xf86GetOptValInteger(R128Options, + OPTION_AGP_MODE, &(info->agpMode))) { + if (info->agpMode < 1 || info->agpMode > R128_AGP_MAX_MODE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal AGP Mode: %d\n", info->agpMode); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using AGP %dx mode\n", info->agpMode); + } + + if (xf86GetOptValInteger(R128Options, + OPTION_AGP_SIZE, (int *)&(info->agpSize))) { + switch (info->agpSize) { + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal AGP size: %d MB\n", info->agpSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(R128Options, + OPTION_RING_SIZE, &(info->ringSize))) { + if (info->ringSize < 1 || info->ringSize >= (int)info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal ring buffer size: %d MB\n", + info->ringSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(R128Options, + OPTION_VERT_SIZE, &(info->vbSize))) { + if (info->vbSize < 1 || info->vbSize >= (int)info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal vertex buffers list size: %d MB\n", + info->vbSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(R128Options, + OPTION_VBUF_SIZE, &(info->vbBufSize))) { + int numBufs = info->vbSize*1024*1024/info->vbBufSize; + if (numBufs < 2 || numBufs > 512) { /* FIXME: 512 is arbitrary */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal individual vertex buffer size: %d bytes\n", + info->vbBufSize); + return FALSE; + } + } + + if (info->ringSize + info->vbSize + info->indSize + info->agpTexSize > + (int)info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Buffers are too big for requested AGP space\n"); + return FALSE; + } + + info->agpTexSize = info->agpSize - (info->ringSize + + info->vbSize + + info->indSize); + } + + if (xf86GetOptValInteger(R128Options, OPTION_USEC_TIMEOUT, + &(info->CCEusecTimeout))) { + /* This option checked by the R128 DRM kernel module */ + } + + return TRUE; +} +#endif + +static void +R128ProbeDDC(ScrnInfoPtr pScrn, int indx) +{ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,indx); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + } +} + +/* R128PreInit is called once at server startup. */ +Bool R128PreInit(ScrnInfoPtr pScrn, int flags) +{ + R128InfoPtr info; + + R128TRACE(("R128PreInit\n")); + +#ifdef XFree86LOADER + /* + * Tell the loader about symbols from other modules that this module might + * refer to. + */ + LoaderRefSymLists(vgahwSymbols, +#ifdef USE_FB + fbSymbols, +#else + cfbSymbols, +#endif + xaaSymbols, + xf8_32bppSymbols, + ramdacSymbols, +#ifdef XF86DRI + drmSymbols, + driSymbols, +#endif + fbdevHWSymbols, + vbeSymbols, + /* ddcsymbols, */ + /* i2csymbols, */ + /* shadowSymbols, */ + NULL); +#endif + + if (pScrn->numEntities != 1) return FALSE; + + if (!R128GetRec(pScrn)) return FALSE; + + info = R128PTR(pScrn); + + info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (info->pEnt->location.type != BUS_PCI) goto fail; + + if (flags & PROBE_DETECT) { + R128ProbeDDC(pScrn, info->pEnt->index); + return TRUE; + } + + if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; + xf86LoaderReqSymLists(vgahwSymbols, NULL); + if (!vgaHWGetHWRec(pScrn)) { + R128FreeRec(pScrn); + return FALSE; + } + + info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); + info->PciTag = pciTag(info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PCI bus %d card %d func %d\n", + info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + + if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail; + + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP; + pScrn->monitor = pScrn->confScreen->monitor; + + if (!R128PreInitVisual(pScrn)) goto fail; + + /* We can't do this until we have a + pScrn->display. */ + xf86CollectOptions(pScrn, NULL); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, R128Options); + + if (!R128PreInitWeight(pScrn)) goto fail; + + if (xf86ReturnOptValBool(R128Options, OPTION_FBDEV, FALSE)) { + info->FBDev = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using framebuffer device\n"); + } + + if (info->FBDev) { + /* check for linux framebuffer device */ + if (!xf86LoadSubModule(pScrn, "fbdevhw")) return FALSE; + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) return FALSE; + pScrn->SwitchMode = fbdevHWSwitchMode; + pScrn->AdjustFrame = fbdevHWAdjustFrame; + pScrn->EnterVT = R128EnterVTFBDev; + pScrn->LeaveVT = R128LeaveVTFBDev; + pScrn->ValidMode = fbdevHWValidMode; + } + + if (!info->FBDev) + if (!R128PreInitInt10(pScrn)) goto fail; + + if (!R128PreInitConfig(pScrn)) goto fail; + + if (!R128GetBIOSParameters(pScrn)) goto fail; + + if (!R128GetPLLParameters(pScrn)) goto fail; + + if (!R128PreInitDDC(pScrn)) goto fail; + + if (!R128PreInitGamma(pScrn)) goto fail; + + if (!R128PreInitModes(pScrn)) goto fail; + + if (!R128PreInitCursor(pScrn)) goto fail; + + if (!R128PreInitAccel(pScrn)) goto fail; + +#ifdef XF86DRI + if (!R128PreInitDRI(pScrn)) goto fail; +#endif + + /* Free the video bios (if applicable) */ + if (info->VBIOS) { + xfree(info->VBIOS); + info->VBIOS = NULL; + } + + return TRUE; + + fail: + /* Pre-init failed. */ + + /* Free the video bios (if applicable) */ + if (info->VBIOS) { + xfree(info->VBIOS); + info->VBIOS = NULL; + } + + vgaHWFreeHWRec(pScrn); + R128FreeRec(pScrn); + return FALSE; +} + +/* Load a palette. */ +static void R128LoadPalette(ScrnInfoPtr pScrn, int numColors, + int *indices, LOCO *colors, VisualPtr pVisual) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + int idx; + unsigned char r, g, b; + + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); + + if (info->CurrentLayout.depth == 15) { + /* 15bpp mode. This sends 32 values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx].red; + g = colors[idx].green; + b = colors[idx].blue; + OUTPAL(idx * 8, r, g, b); + } + } + else if (info->CurrentLayout.depth == 16) { + /* 16bpp mode. This sends 64 values. */ + /* There are twice as many green values as + there are values for red and blue. So, + we take each red and blue pair, and + combine it with each of the two green + values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx / 2].red; + g = colors[idx].green; + b = colors[idx / 2].blue; + OUTPAL(idx * 4, r, g, b); + } + } + else { + /* 8bpp mode. This sends 256 values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx].red; + b = colors[idx].blue; + g = colors[idx].green; + OUTPAL(idx, r, g, b); + } + } +} + +/* Called at the start of each server generation. */ +Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + BoxRec MemBox; + int y2; + + R128TRACE(("R128ScreenInit %x %d\n", pScrn->memPhysBase, pScrn->fbOffset)); + +#ifdef XF86DRI + /* Turn off the CCE for now. */ + info->CCEInUse = FALSE; +#endif + + if (!R128MapMem(pScrn)) return FALSE; + pScrn->fbOffset = 0; +#ifdef XF86DRI + info->fbX = 0; + info->fbY = 0; +#endif + + info->PaletteSavedOnVT = FALSE; + + R128Save(pScrn); + if (info->FBDev) { + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; + } else { + if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE; + } + + R128SaveScreen(pScreen, SCREEN_SAVER_ON); + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* Visual setup */ + miClearVisualTypes(); + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, + pScrn->defaultVisual)) return FALSE; + miSetPixmapDepths (); + +#ifdef XF86DRI + /* Setup DRI after visuals have been + established, but before cfbScreenInit is + called. cfbScreenInit will eventually + call the driver's InitGLXVisuals call + back. */ + { + /* FIXME: When we move to dynamic allocation of back and depth + buffers, we will want to revisit the following check for 3 + times the virtual size of the screen below. */ + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int maxy = info->FbMapSize / width_bytes; + + if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE) && + (maxy > pScrn->virtualY * 3) +#if 0 + /* FIXME: Disable 3D support for FPs until it is tested */ + && !info->HasPanelRegs +#endif + ) { + info->directRenderingEnabled = R128DRIScreenInit(pScreen); + } else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Static buffer allocation failed -- " + "need at least %d kB video memory\n", + (pScrn->displayWidth * pScrn->virtualY * + info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); + info->directRenderingEnabled = FALSE; + } + } +#endif + +#ifdef USE_FB + if (!fbScreenInit (pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, + pScrn->bitsPerPixel)) + return FALSE; +#ifdef RENDER + fbPictureInit (pScreen, 0, 0); +#endif +#else + switch (pScrn->bitsPerPixel) { + case 8: + if (!cfbScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + case 16: + if (!cfb16ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + case 24: + if (info->pix24bpp == 24) { + if (!cfb24ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth)) + return FALSE; + } else { + if (!cfb24_32ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth)) + return FALSE; + } + break; + case 32: + if (!cfb32ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Invalid bpp (%d)\n", pScrn->bitsPerPixel); + return FALSE; + } +#endif + xf86SetBlackWhitePixels(pScreen); + + if (pScrn->bitsPerPixel > 8) { + VisualPtr visual; + + for (visual = pScreen->visuals + pScreen->numVisuals; + visual >= pScreen->visuals; + visual--) { + 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; + } + } + } + + R128DGAInit(pScreen); + + /* Memory manager setup */ + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + y2 = (info->FbMapSize + / (pScrn->displayWidth * info->CurrentLayout.pixel_bytes)); + if (y2 >= 32768) y2 = 32767; /* because MemBox.y2 is signed short */ + MemBox.y2 = y2; + + /* The acceleration engine uses 14 bit + signed coordinates, so we can't have any + drawable caches beyond this region. */ + if (MemBox.y2 > 8191) MemBox.y2 = 8191; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; + } else { + int width, height; + FBAreaPtr fbarea; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } + +#ifdef XF86DRI + /* Allocate frame buffer space for the + shared back and depth buffers as well + as for local textures. */ + if (info->directRenderingEnabled) { + FBAreaPtr fbarea; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int maxy = info->FbMapSize / width_bytes; + int l; + + switch (info->CCEMode) { + case R128_DEFAULT_CCE_PIO_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n"); + break; + case R128_DEFAULT_CCE_BM_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n"); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n"); + break; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB AGP aperture\n", info->agpSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for the ring buffer\n", info->ringSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for vertex buffers\n", info->vbSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for indirect buffers\n", info->indSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for AGP textures\n", info->agpTexSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d byte vertex buffers\n", info->vbBufSize); + + /* Allocate the shared back buffer */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved back buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->backX = fbarea->box.x1; + info->backY = fbarea->box.y1; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); + info->backX = -1; + info->backY = -1; + } + + /* Allocate the shared depth buffer */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->depthX = fbarea->box.x1; + info->depthY = fbarea->box.y1; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); + info->depthX = -1; + info->depthY = -1; + } + + /* Allocate local texture space */ + if (((maxy - MemBox.y2 - 1) * width_bytes) > + (pScrn->virtualX * pScrn->virtualY * 2 * + info->CurrentLayout.pixel_bytes)) { + info->textureX = 0; + info->textureY = MemBox.y2 + 1; + info->textureSize = (maxy - MemBox.y2 - 1) * width_bytes; + + l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); + if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; + + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", + info->textureSize/1024, + info->textureX, info->textureY, + pScrn->displayWidth, maxy); + } else if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY * 2, + 32, + NULL, NULL, NULL))) { + info->textureX = fbarea->box.x1; + info->textureY = fbarea->box.y1; + info->textureSize = ((fbarea->box.y2 - fbarea->box.y1) * + (fbarea->box.x2 - fbarea->box.x1) * + info->CurrentLayout.pixel_bytes); + + l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); + if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; + + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", + info->textureSize/1024, + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Unable to reserve texture space in frame buffer\n"); + info->textureX = -1; + info->textureY = -1; + } + } +#endif + + /* Backing store setup */ + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* Set Silken Mouse */ + xf86SetSilkenMouse(pScreen); + + /* Acceleration setup */ + if (!xf86ReturnOptValBool(R128Options, OPTION_NOACCEL, FALSE)) { + if (R128AccelInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); + info->accelOn = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Acceleration initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } + + /* Cursor setup */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Hardware cursor setup */ + if (!xf86ReturnOptValBool(R128Options, OPTION_SW_CURSOR, FALSE)) { + if (R128CursorInit(pScreen)) { + int width, height; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using hardware cursor (scanline %d)\n", + info->cursor_start / pScrn->displayWidth); + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, + 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); + } + + /* Colormap setup */ + if (!miCreateDefColormap(pScreen)) return FALSE; + if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, + (info->FBDev ? fbdevHWLoadPalette : + R128LoadPalette), NULL, + CMAP_PALETTED_TRUECOLOR + | CMAP_RELOAD_ON_MODE_SWITCH +#if 0 /* This option messes up text mode! (eich@suse.de) */ + | CMAP_LOAD_EVEN_IF_OFFSCREEN +#endif + )) return FALSE; + + /* DPMS setup */ +#ifdef DPMSExtension + if (!info->HasPanelRegs || info->CRTOnly) + xf86DPMSInit(pScreen, R128DisplayPowerManagementSet, 0); +#endif + + R128InitVideo(pScreen); + + /* Provide SaveScreen */ + pScreen->SaveScreen = R128SaveScreen; + + /* Wrap CloseScreen */ + info->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = R128CloseScreen; + + /* Note unused options */ + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + +#ifdef XF86DRI + /* DRI finalization */ + if (info->directRenderingEnabled) { + /* Now that mi, cfb, drm and others have + done their thing, complete the DRI + setup. */ + info->directRenderingEnabled = R128DRIFinishScreenInit(pScreen); + } + if (info->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n"); + } +#endif + + return TRUE; +} + +/* Write common registers (initialized to 0). */ +static void R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_OVR_CLR, restore->ovr_clr); + OUTREG(R128_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); + OUTREG(R128_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); + OUTREG(R128_OV0_SCALE_CNTL, restore->ov0_scale_cntl); + OUTREG(R128_MPP_TB_CONFIG, restore->mpp_tb_config ); + OUTREG(R128_MPP_GP_CONFIG, restore->mpp_gp_config ); + OUTREG(R128_SUBPIC_CNTL, restore->subpic_cntl); + OUTREG(R128_VIPH_CONTROL, restore->viph_control); + OUTREG(R128_I2C_CNTL_1, restore->i2c_cntl_1); + OUTREG(R128_GEN_INT_CNTL, restore->gen_int_cntl); + OUTREG(R128_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); + OUTREG(R128_CAP1_TRIG_CNTL, restore->cap1_trig_cntl); + OUTREG(R128_BUS_CNTL, restore->bus_cntl); +} + +/* Write CRTC registers. */ +static void R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_CRTC_GEN_CNTL, restore->crtc_gen_cntl); + + OUTREGP(R128_CRTC_EXT_CNTL, restore->crtc_ext_cntl, + R128_CRTC_VSYNC_DIS | R128_CRTC_HSYNC_DIS | R128_CRTC_DISPLAY_DIS); + + OUTREGP(R128_DAC_CNTL, restore->dac_cntl, + R128_DAC_RANGE_CNTL | R128_DAC_BLANKING); + + OUTREG(R128_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp); + OUTREG(R128_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid); + OUTREG(R128_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); + OUTREG(R128_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); + OUTREG(R128_CRTC_OFFSET, restore->crtc_offset); + OUTREG(R128_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); + OUTREG(R128_CRTC_PITCH, restore->crtc_pitch); +} + +/* Write flat panel registers */ +static void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + CARD32 tmp; + + OUTREG(R128_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl); + OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); + OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); + OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl); + OUTREG(R128_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); + OUTREG(R128_FP_HORZ_STRETCH, restore->fp_horz_stretch); + OUTREG(R128_FP_PANEL_CNTL, restore->fp_panel_cntl); + OUTREG(R128_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); + OUTREG(R128_FP_VERT_STRETCH, restore->fp_vert_stretch); + OUTREG(R128_TMDS_CRC, restore->tmds_crc); + + tmp = INREG(R128_LVDS_GEN_CNTL); + if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) == + (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON))) { + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } else { + if (restore->lvds_gen_cntl & (R128_LVDS_ON | R128_LVDS_BLON)) { + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl & ~R128_LVDS_BLON); + usleep(R128PTR(pScrn)->PanelPwrDly * 1000); + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } else { + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl | R128_LVDS_BLON); + usleep(R128PTR(pScrn)->PanelPwrDly * 1000); + OUTREG(R128_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } + } +} + +static void R128PLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn) +{ + while (INPLL(pScrn, R128_PPLL_REF_DIV) & R128_PPLL_ATOMIC_UPDATE_R); +} + +static void R128PLLWriteUpdate(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTPLLP(pScrn, R128_PPLL_REF_DIV, R128_PPLL_ATOMIC_UPDATE_W, 0xffff); +} + +/* Write PLL registers. */ +static void R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREGP(R128_CLOCK_CNTL_INDEX, R128_PLL_DIV_SEL, 0xffff); + + OUTPLLP(pScrn, + R128_PPLL_CNTL, + R128_PPLL_RESET + | R128_PPLL_ATOMIC_UPDATE_EN + | R128_PPLL_VGA_ATOMIC_UPDATE_EN, + 0xffff); + + R128PLLWaitForReadUpdateComplete(pScrn); + OUTPLLP(pScrn, R128_PPLL_REF_DIV, + restore->ppll_ref_div, ~R128_PPLL_REF_DIV_MASK); + R128PLLWriteUpdate(pScrn); + + R128PLLWaitForReadUpdateComplete(pScrn); + OUTPLLP(pScrn, R128_PPLL_DIV_3, + restore->ppll_div_3, ~R128_PPLL_FB3_DIV_MASK); + R128PLLWriteUpdate(pScrn); + OUTPLLP(pScrn, R128_PPLL_DIV_3, + restore->ppll_div_3, ~R128_PPLL_POST3_DIV_MASK); + R128PLLWriteUpdate(pScrn); + + R128PLLWaitForReadUpdateComplete(pScrn); + OUTPLL(R128_HTOTAL_CNTL, restore->htotal_cntl); + R128PLLWriteUpdate(pScrn); + + OUTPLLP(pScrn, R128_PPLL_CNTL, 0, ~R128_PPLL_RESET); + + R128TRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", + restore->ppll_ref_div, + restore->ppll_div_3, + restore->htotal_cntl, + INPLL(pScrn, R128_PPLL_CNTL))); + R128TRACE(("Wrote: rd=%d, fd=%d, pd=%d\n", + restore->ppll_ref_div & R128_PPLL_REF_DIV_MASK, + restore->ppll_div_3 & R128_PPLL_FB3_DIV_MASK, + (restore->ppll_div_3 & R128_PPLL_POST3_DIV_MASK) >> 16)); +} + +/* Write DDA registers. */ +static void R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + OUTREG(R128_DDA_CONFIG, restore->dda_config); + OUTREG(R128_DDA_ON_OFF, restore->dda_on_off); +} + +/* Write palette data. */ +static void R128RestorePalette(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + if (!restore->palette_valid) return; + + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); + + OUTPAL_START(0); + for (i = 0; i < 256; i++) OUTPAL_NEXT_CARD32(restore->palette[i]); +} + +/* Write out state to define a new video mode. */ +static void R128RestoreMode(ScrnInfoPtr pScrn, R128SavePtr restore) +{ + R128InfoPtr info = R128PTR(pScrn); + + R128TRACE(("R128RestoreMode(%p)\n", restore)); + R128RestoreCommonRegisters(pScrn, restore); + R128RestoreCrtcRegisters(pScrn, restore); + if (info->HasPanelRegs) + R128RestoreFPRegisters(pScrn, restore); + if (!info->HasPanelRegs || info->CRTOnly) + R128RestorePLLRegisters(pScrn, restore); + R128RestoreDDARegisters(pScrn, restore); + R128RestorePalette(pScrn, restore); +} + +/* Read common registers. */ +static void R128SaveCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + save->ovr_clr = INREG(R128_OVR_CLR); + save->ovr_wid_left_right = INREG(R128_OVR_WID_LEFT_RIGHT); + save->ovr_wid_top_bottom = INREG(R128_OVR_WID_TOP_BOTTOM); + save->ov0_scale_cntl = INREG(R128_OV0_SCALE_CNTL); + save->mpp_tb_config = INREG(R128_MPP_TB_CONFIG); + save->mpp_gp_config = INREG(R128_MPP_GP_CONFIG); + save->subpic_cntl = INREG(R128_SUBPIC_CNTL); + save->viph_control = INREG(R128_VIPH_CONTROL); + save->i2c_cntl_1 = INREG(R128_I2C_CNTL_1); + save->gen_int_cntl = INREG(R128_GEN_INT_CNTL); + save->cap0_trig_cntl = INREG(R128_CAP0_TRIG_CNTL); + save->cap1_trig_cntl = INREG(R128_CAP1_TRIG_CNTL); + save->bus_cntl = INREG(R128_BUS_CNTL); +} + +/* Read CRTC registers. */ +static void R128SaveCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + save->crtc_gen_cntl = INREG(R128_CRTC_GEN_CNTL); + save->crtc_ext_cntl = INREG(R128_CRTC_EXT_CNTL); + save->dac_cntl = INREG(R128_DAC_CNTL); + save->crtc_h_total_disp = INREG(R128_CRTC_H_TOTAL_DISP); + save->crtc_h_sync_strt_wid = INREG(R128_CRTC_H_SYNC_STRT_WID); + save->crtc_v_total_disp = INREG(R128_CRTC_V_TOTAL_DISP); + save->crtc_v_sync_strt_wid = INREG(R128_CRTC_V_SYNC_STRT_WID); + save->crtc_offset = INREG(R128_CRTC_OFFSET); + save->crtc_offset_cntl = INREG(R128_CRTC_OFFSET_CNTL); + save->crtc_pitch = INREG(R128_CRTC_PITCH); +} + +/* Read flat panel registers */ +static void R128SaveFPRegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + save->crtc2_gen_cntl = INREG(R128_CRTC2_GEN_CNTL); + save->fp_crtc_h_total_disp = INREG(R128_FP_CRTC_H_TOTAL_DISP); + save->fp_crtc_v_total_disp = INREG(R128_FP_CRTC_V_TOTAL_DISP); + save->fp_gen_cntl = INREG(R128_FP_GEN_CNTL); + save->fp_h_sync_strt_wid = INREG(R128_FP_H_SYNC_STRT_WID); + save->fp_horz_stretch = INREG(R128_FP_HORZ_STRETCH); + save->fp_panel_cntl = INREG(R128_FP_PANEL_CNTL); + save->fp_v_sync_strt_wid = INREG(R128_FP_V_SYNC_STRT_WID); + save->fp_vert_stretch = INREG(R128_FP_VERT_STRETCH); + save->lvds_gen_cntl = INREG(R128_LVDS_GEN_CNTL); + save->tmds_crc = INREG(R128_TMDS_CRC); +} + +/* Read PLL registers. */ +static void R128SavePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + save->ppll_ref_div = INPLL(pScrn, R128_PPLL_REF_DIV); + save->ppll_div_3 = INPLL(pScrn, R128_PPLL_DIV_3); + save->htotal_cntl = INPLL(pScrn, R128_HTOTAL_CNTL); + + R128TRACE(("Read: 0x%08x 0x%08x 0x%08x\n", + save->ppll_ref_div, + save->ppll_div_3, + save->htotal_cntl)); + R128TRACE(("Read: rd=%d, fd=%d, pd=%d\n", + save->ppll_ref_div & R128_PPLL_REF_DIV_MASK, + save->ppll_div_3 & R128_PPLL_FB3_DIV_MASK, + (save->ppll_div_3 & R128_PPLL_POST3_DIV_MASK) >> 16)); +} + +/* Read DDA registers. */ +static void R128SaveDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + + save->dda_config = INREG(R128_DDA_CONFIG); + save->dda_on_off = INREG(R128_DDA_ON_OFF); +} + +/* Read palette data. */ +static void R128SavePalette(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int i; + + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); + + INPAL_START(0); + for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); + save->palette_valid = TRUE; +} + +/* Save state that defines current video mode. */ +static void R128SaveMode(ScrnInfoPtr pScrn, R128SavePtr save) +{ + R128TRACE(("R128SaveMode(%p)\n", save)); + + R128SaveCommonRegisters(pScrn, save); + R128SaveCrtcRegisters(pScrn, save); + if (R128PTR(pScrn)->HasPanelRegs) + R128SaveFPRegisters(pScrn, save); + R128SavePLLRegisters(pScrn, save); + R128SaveDDARegisters(pScrn, save); + R128SavePalette(pScrn, save); + + R128TRACE(("R128SaveMode returns %p\n", save)); +} + +/* Save everything needed to restore the original VC state. */ +static void R128Save(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128SavePtr save = &info->SavedReg; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + R128TRACE(("R128Save\n")); + if (info->FBDev) { + fbdevHWSave(pScrn); + return; + } + vgaHWUnlock(hwp); + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); /* save mode, fonts, cmap */ + vgaHWLock(hwp); + + R128SaveMode(pScrn, save); + + save->dp_datatype = INREG(R128_DP_DATATYPE); + save->gen_reset_cntl = INREG(R128_GEN_RESET_CNTL); + save->clock_cntl_index = INREG(R128_CLOCK_CNTL_INDEX); + save->amcgpio_en_reg = INREG(R128_AMCGPIO_EN_REG); + save->amcgpio_mask = INREG(R128_AMCGPIO_MASK); +} + +/* Restore the original (text) mode. */ +static void R128Restore(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128SavePtr restore = &info->SavedReg; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + R128TRACE(("R128Restore\n")); + if (info->FBDev) { + fbdevHWRestore(pScrn); + return; + } + + R128Blank(pScrn); + OUTREG(R128_AMCGPIO_MASK, restore->amcgpio_mask); + OUTREG(R128_AMCGPIO_EN_REG, restore->amcgpio_en_reg); + OUTREG(R128_CLOCK_CNTL_INDEX, restore->clock_cntl_index); + OUTREG(R128_GEN_RESET_CNTL, restore->gen_reset_cntl); + OUTREG(R128_DP_DATATYPE, restore->dp_datatype); + + R128RestoreMode(pScrn, restore); + vgaHWUnlock(hwp); + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); + vgaHWLock(hwp); + + R128WaitForVerticalSync(pScrn); + R128Unblank(pScrn); +} + +/* Define common registers for requested video mode. */ +static void R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info) +{ + save->ovr_clr = 0; + save->ovr_wid_left_right = 0; + save->ovr_wid_top_bottom = 0; + save->ov0_scale_cntl = 0; + save->mpp_tb_config = 0; + save->mpp_gp_config = 0; + save->subpic_cntl = 0; + save->viph_control = 0; + save->i2c_cntl_1 = 0; + save->gen_int_cntl = 0; + save->cap0_trig_cntl = 0; + save->cap1_trig_cntl = 0; + save->bus_cntl = info->BusCntl; + /* + * If bursts are enabled, turn on discards and aborts + */ + if (save->bus_cntl & (R128_BUS_WRT_BURST|R128_BUS_READ_BURST)) + save->bus_cntl |= R128_BUS_RD_DISCARD_EN | R128_BUS_RD_ABORT_EN; +} + +/* Define CRTC registers for requested video mode. */ +static Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save, + DisplayModePtr mode, R128InfoPtr info) +{ + int format; + int hsync_start; + int hsync_wid; + int hsync_fudge; + int vsync_wid; + int bytpp; + int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; + int hsync_fudge_fp[] = { 0x12, 0x11, 0x09, 0x09, 0x05, 0x05 }; + int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 }; + + switch (info->CurrentLayout.pixel_code) { + case 4: format = 1; bytpp = 0; break; + case 8: format = 2; bytpp = 1; break; + case 15: format = 3; bytpp = 2; break; /* 555 */ + case 16: format = 4; bytpp = 2; break; /* 565 */ + case 24: format = 5; bytpp = 3; break; /* RGB */ + case 32: format = 6; bytpp = 4; break; /* xRGB */ + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unsupported pixel depth (%d)\n", info->CurrentLayout.bitsPerPixel); + return FALSE; + } + R128TRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp)); + + if (info->HasPanelRegs) + if (info->CRTOnly) hsync_fudge = hsync_fudge_fp_crt[format-1]; + else hsync_fudge = hsync_fudge_fp[format-1]; + else hsync_fudge = hsync_fudge_default[format-1]; + + save->crtc_gen_cntl = (R128_CRTC_EXT_DISP_EN + | R128_CRTC_EN + | (format << 8) + | ((mode->Flags & V_DBLSCAN) + ? R128_CRTC_DBL_SCAN_EN + : 0) + | ((mode->Flags & V_INTERLACE) + ? R128_CRTC_INTERLACE_EN + : 0)); + + save->crtc_ext_cntl = R128_VGA_ATI_LINEAR | R128_XCRT_CNT_EN; + save->dac_cntl = (R128_DAC_MASK_ALL + | R128_DAC_VGA_ADR_EN + | (info->dac6bits ? 0 : R128_DAC_8BIT_EN)); + + save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff) + | (((mode->CrtcHDisplay / 8) - 1) << 16)); + + hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; + if (!hsync_wid) hsync_wid = 1; + if (hsync_wid > 0x3f) hsync_wid = 0x3f; + + hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; + + save->crtc_h_sync_strt_wid = ((hsync_start & 0xfff) + | (hsync_wid << 16) + | ((mode->Flags & V_NHSYNC) + ? R128_CRTC_H_SYNC_POL + : 0)); + +#if 1 + /* This works for double scan mode. */ + save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) + | ((mode->CrtcVDisplay - 1) << 16)); +#else + /* This is what cce/nbmode.c example code + does -- is this correct? */ + save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) + | ((mode->CrtcVDisplay + * ((mode->Flags & V_DBLSCAN) ? 2 : 1) - 1) + << 16)); +#endif + + vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + if (!vsync_wid) vsync_wid = 1; + if (vsync_wid > 0x1f) vsync_wid = 0x1f; + + save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) + | (vsync_wid << 16) + | ((mode->Flags & V_NVSYNC) + ? R128_CRTC_V_SYNC_POL + : 0)); + save->crtc_offset = 0; + save->crtc_offset_cntl = 0; + save->crtc_pitch = info->CurrentLayout.displayWidth / 8; + + R128TRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n", + save->crtc_pitch, pScrn->virtualX, info->CurrentLayout.displayWidth)); + return TRUE; +} + +/* Define CRTC registers for requested video mode. */ +static void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, + DisplayModePtr mode, R128InfoPtr info) +{ + int xres = mode->CrtcHDisplay; + int yres = mode->CrtcVDisplay; + float Hratio, Vratio; + + if (info->CRTOnly) { + save->crtc_ext_cntl |= R128_CRTC_CRT_ON; + save->crtc2_gen_cntl = 0; + save->fp_gen_cntl = orig->fp_gen_cntl; + save->fp_gen_cntl &= ~(R128_FP_FPON | + R128_FP_CRTC_USE_SHADOW_VEND | + R128_FP_CRTC_HORZ_DIV2_EN | + R128_FP_CRTC_HOR_CRT_DIV2_DIS | + R128_FP_USE_SHADOW_EN); + save->fp_gen_cntl |= (R128_FP_SEL_CRTC2 | + R128_FP_CRTC_DONT_SHADOW_VPAR); + save->fp_panel_cntl = orig->fp_panel_cntl & ~R128_FP_DIGON; + save->lvds_gen_cntl = orig->lvds_gen_cntl & ~(R128_LVDS_ON | + R128_LVDS_BLON); + return; + } + + if (xres > info->PanelXRes) xres = info->PanelXRes; + if (yres > info->PanelYRes) yres = info->PanelYRes; + + Hratio = (float)xres/(float)info->PanelXRes; + Vratio = (float)yres/(float)info->PanelYRes; + + save->fp_horz_stretch = + (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5)) + & R128_HORZ_STRETCH_RATIO_MASK) << R128_HORZ_STRETCH_RATIO_SHIFT) | + (orig->fp_horz_stretch & (R128_HORZ_PANEL_SIZE | + R128_HORZ_FP_LOOP_STRETCH | + R128_HORZ_STRETCH_RESERVED))); + save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN; + if (Hratio == 1.0) save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | + R128_HORZ_STRETCH_ENABLE); + else save->fp_horz_stretch |= (R128_HORZ_STRETCH_BLEND | + R128_HORZ_STRETCH_ENABLE); + + save->fp_vert_stretch = + (((((int)(Vratio * R128_VERT_STRETCH_RATIO_MAX + 0.5)) + & R128_VERT_STRETCH_RATIO_MASK) << R128_VERT_STRETCH_RATIO_SHIFT) | + (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE | + R128_VERT_STRETCH_RESERVED))); + save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN; + if (Vratio == 1.0) save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | + R128_VERT_STRETCH_BLEND); + else save->fp_vert_stretch |= (R128_VERT_STRETCH_ENABLE | + R128_VERT_STRETCH_BLEND); + + save->fp_gen_cntl = (orig->fp_gen_cntl & ~(R128_FP_SEL_CRTC2 | + R128_FP_CRTC_USE_SHADOW_VEND | + R128_FP_CRTC_HORZ_DIV2_EN | + R128_FP_CRTC_HOR_CRT_DIV2_DIS | + R128_FP_USE_SHADOW_EN)); + if (orig->fp_gen_cntl & R128_FP_DETECT_SENSE) { + save->fp_gen_cntl |= (R128_FP_CRTC_DONT_SHADOW_VPAR | + R128_FP_TDMS_EN); + } + + save->fp_panel_cntl = orig->fp_panel_cntl; + save->lvds_gen_cntl = orig->lvds_gen_cntl; + + save->tmds_crc = orig->tmds_crc; + + /* Disable CRT output by disabling CRT output and setting the CRT + DAC to use CRTC2, which we set to 0's. In the future, we will + want to use the dual CRTC capabilities of the R128 to allow both + the flat panel and external CRT to either simultaneously display + the same image or display two different images. */ + save->crtc_ext_cntl &= ~R128_CRTC_CRT_ON; + save->dac_cntl |= R128_DAC_CRT_SEL_CRTC2; + save->crtc2_gen_cntl = 0; + + /* WARNING: Be careful about turning on the flat panel */ +#if 1 + save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON); +#else + save->fp_panel_cntl |= (R128_FP_DIGON | R128_FP_BLON); + save->fp_gen_cntl |= (R128_FP_FPON); +#endif + + save->fp_crtc_h_total_disp = save->crtc_h_total_disp; + save->fp_crtc_v_total_disp = save->crtc_v_total_disp; + save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; + save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; +} + +/* Define PLL registers for requested video mode. */ +static void R128InitPLLRegisters(R128SavePtr save, R128PLLPtr pll, + double dot_clock) +{ + unsigned long freq = dot_clock * 100; + struct { + int divider; + int bitvalue; + } *post_div, + post_divs[] = { + /* From RAGE 128 VR/RAGE 128 GL Register + Reference Manual (Technical Reference + Manual P/N RRG-G04100-C Rev. 0.04), page + 3-17 (PLL_DIV_[3:0]). */ + { 1, 0 }, /* VCLK_SRC */ + { 2, 1 }, /* VCLK_SRC/2 */ + { 4, 2 }, /* VCLK_SRC/4 */ + { 8, 3 }, /* VCLK_SRC/8 */ + + { 3, 4 }, /* VCLK_SRC/3 */ + /* bitvalue = 5 is reserved */ + { 6, 6 }, /* VCLK_SRC/6 */ + { 12, 7 }, /* VCLK_SRC/12 */ + { 0, 0 } + }; + + if (freq > pll->max_pll_freq) freq = pll->max_pll_freq; + if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; + + for (post_div = &post_divs[0]; post_div->divider; ++post_div) { + save->pll_output_freq = post_div->divider * freq; + if (save->pll_output_freq >= pll->min_pll_freq + && save->pll_output_freq <= pll->max_pll_freq) break; + } + + save->dot_clock_freq = freq; + save->feedback_div = R128Div(pll->reference_div * save->pll_output_freq, + pll->reference_freq); + save->post_div = post_div->divider; + + R128TRACE(("dc=%d, of=%d, fd=%d, pd=%d\n", + save->dot_clock_freq, + save->pll_output_freq, + save->feedback_div, + save->post_div)); + + save->ppll_ref_div = pll->reference_div; + save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); + save->htotal_cntl = 0; +} + +/* Define DDA registers for requested video mode. */ +static Bool R128InitDDARegisters(ScrnInfoPtr pScrn, R128SavePtr save, + R128PLLPtr pll, R128InfoPtr info) +{ + int DisplayFifoWidth = 128; + int DisplayFifoDepth = 32; + int XclkFreq; + int VclkFreq; + int XclksPerTransfer; + int XclksPerTransferPrecise; + int UseablePrecision; + int Roff; + int Ron; + + XclkFreq = pll->xclk; + + VclkFreq = R128Div(pll->reference_freq * save->feedback_div, + pll->reference_div * save->post_div); + + XclksPerTransfer = R128Div(XclkFreq * DisplayFifoWidth, + VclkFreq * (info->CurrentLayout.pixel_bytes * 8)); + + UseablePrecision = R128MinBits(XclksPerTransfer) + 1; + + XclksPerTransferPrecise = R128Div((XclkFreq * DisplayFifoWidth) + << (11 - UseablePrecision), + VclkFreq * (info->CurrentLayout.pixel_bytes * 8)); + + Roff = XclksPerTransferPrecise * (DisplayFifoDepth - 4); + + Ron = (4 * info->ram->MB + + 3 * MAX(info->ram->Trcd - 2, 0) + + 2 * info->ram->Trp + + info->ram->Twr + + info->ram->CL + + info->ram->Tr2w + + XclksPerTransfer) << (11 - UseablePrecision); + + if (Ron + info->ram->Rloop >= Roff) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "(Ron = %d) + (Rloop = %d) >= (Roff = %d)\n", + Ron, info->ram->Rloop, Roff); + return FALSE; + } + + save->dda_config = (XclksPerTransferPrecise + | (UseablePrecision << 16) + | (info->ram->Rloop << 20)); + + save->dda_on_off = (Ron << 16) | Roff; + + R128TRACE(("XclkFreq = %d; VclkFreq = %d; per = %d, %d (useable = %d)\n", + XclkFreq, + VclkFreq, + XclksPerTransfer, + XclksPerTransferPrecise, + UseablePrecision)); + R128TRACE(("Roff = %d, Ron = %d, Rloop = %d\n", + Roff, Ron, info->ram->Rloop)); + + return TRUE; +} + + +/* Define initial palette for requested video mode. This doesn't do + anything for XFree86 4.0. */ +static void R128InitPalette(R128SavePtr save) +{ + save->palette_valid = FALSE; +} + +/* Define registers for a requested video mode. */ +static Bool R128Init(ScrnInfoPtr pScrn, DisplayModePtr mode, R128SavePtr save) +{ + R128InfoPtr info = R128PTR(pScrn); + double dot_clock = mode->Clock/1000.0; + +#if R128_DEBUG + ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", + mode->name, + dot_clock, + + mode->HDisplay, + mode->HSyncStart, + mode->HSyncEnd, + mode->HTotal, + + mode->VDisplay, + mode->VSyncStart, + mode->VSyncEnd, + mode->VTotal, + pScrn->depth, + pScrn->bitsPerPixel); + if (mode->Flags & V_DBLSCAN) ErrorF(" D"); + if (mode->Flags & V_INTERLACE) ErrorF(" I"); + if (mode->Flags & V_PHSYNC) ErrorF(" +H"); + if (mode->Flags & V_NHSYNC) ErrorF(" -H"); + if (mode->Flags & V_PVSYNC) ErrorF(" +V"); + if (mode->Flags & V_NVSYNC) ErrorF(" -V"); + ErrorF("\n"); + ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", + mode->name, + dot_clock, + + mode->CrtcHDisplay, + mode->CrtcHSyncStart, + mode->CrtcHSyncEnd, + mode->CrtcHTotal, + + mode->CrtcVDisplay, + mode->CrtcVSyncStart, + mode->CrtcVSyncEnd, + mode->CrtcVTotal, + pScrn->depth, + pScrn->bitsPerPixel); + if (mode->Flags & V_DBLSCAN) ErrorF(" D"); + if (mode->Flags & V_INTERLACE) ErrorF(" I"); + if (mode->Flags & V_PHSYNC) ErrorF(" +H"); + if (mode->Flags & V_NHSYNC) ErrorF(" -H"); + if (mode->Flags & V_PVSYNC) ErrorF(" +V"); + if (mode->Flags & V_NVSYNC) ErrorF(" -V"); + ErrorF("\n"); +#endif + + info->Flags = mode->Flags; + + R128InitCommonRegisters(save, info); + if (!R128InitCrtcRegisters(pScrn, save, mode, info)) return FALSE; + if (info->HasPanelRegs) + R128InitFPRegisters(&info->SavedReg, save, mode, info); + R128InitPLLRegisters(save, &info->pll, dot_clock); + if (!R128InitDDARegisters(pScrn, save, &info->pll, info)) + return FALSE; + if (!info->PaletteSavedOnVT) R128InitPalette(save); + + R128TRACE(("R128Init returns %p\n", save)); + return TRUE; +} + +/* Initialize a new mode. */ +static Bool R128ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + R128InfoPtr info = R128PTR(pScrn); + + if (!R128Init(pScrn, mode, &info->ModeReg)) return FALSE; + /* FIXME? DRILock/DRIUnlock here? */ + pScrn->vtSema = TRUE; + R128Blank(pScrn); + R128RestoreMode(pScrn, &info->ModeReg); + R128Unblank(pScrn); + + info->CurrentLayout.mode = mode; + + return TRUE; +} + +static Bool R128SaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + Bool unblank; + + unblank = xf86IsUnblank(mode); + if (unblank) + SetTimeSinceLastInputEvent(); + + if ((pScrn != NULL) && pScrn->vtSema) { + if (unblank) + R128Unblank(pScrn); + else + R128Blank(pScrn); + } + return TRUE; +} + +Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + return R128ModeInit(xf86Screens[scrnIndex], mode); +} + +/* Used to disallow modes that are not supported by the hardware. */ +int R128ValidMode(int scrnIndex, DisplayModePtr mode, + Bool verbose, int flag) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + + if (info->HasPanelRegs) { + if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; + if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN; + } + + if (info->HasPanelRegs && !info->CRTOnly && info->VBIOS) { + int i; + for (i = info->FPBIOSstart+64; R128_BIOS16(i) != 0; i += 2) { + int j = R128_BIOS16(i); + + if (mode->CrtcHDisplay == R128_BIOS16(j) && + mode->CrtcVDisplay == R128_BIOS16(j+2)) { + /* Assume we are using expanded mode */ + if (R128_BIOS16(j+5)) j = R128_BIOS16(j+5); + else j += 9; + + mode->Clock = (CARD32)R128_BIOS16(j) * 10; + + mode->HDisplay = mode->CrtcHDisplay = + ((R128_BIOS16(j+10) & 0x01ff)+1)*8; + mode->HSyncStart = mode->CrtcHSyncStart = + ((R128_BIOS16(j+12) & 0x01ff)+1)*8; + mode->HSyncEnd = mode->CrtcHSyncEnd = + mode->CrtcHSyncStart + (R128_BIOS8(j+14) & 0x1f); + mode->HTotal = mode->CrtcHTotal = + ((R128_BIOS16(j+8) & 0x01ff)+1)*8; + + mode->VDisplay = mode->CrtcVDisplay = + (R128_BIOS16(j+17) & 0x07ff)+1; + mode->VSyncStart = mode->CrtcVSyncStart = + (R128_BIOS16(j+19) & 0x07ff)+1; + mode->VSyncEnd = mode->CrtcVSyncEnd = + mode->CrtcVSyncStart + ((R128_BIOS16(j+19) >> 11) & 0x1f); + mode->VTotal = mode->CrtcVTotal = + (R128_BIOS16(j+15) & 0x07ff)+1; + + return MODE_OK; + } + } + return MODE_NOMODE; + } + + return MODE_OK; +} + +/* Adjust viewport into virtual desktop such that (0,0) in viewport space + is (x,y) in virtual space. */ +void R128AdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int Base; + + Base = y * info->CurrentLayout.displayWidth + x; + + switch (info->CurrentLayout.pixel_code) { + case 15: + case 16: Base *= 2; break; + case 24: Base *= 3; break; + case 32: Base *= 4; break; + } + + Base &= ~7; /* 3 lower bits are always 0 */ + + if (info->CurrentLayout.pixel_code == 24) + Base += 8 * (Base % 3); /* Must be multiple of 8 and 3 */ + + OUTREG(R128_CRTC_OFFSET, Base); +} + +/* Called when VT switching back to the X server. Reinitialize the video + mode. */ +Bool R128EnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + + R128TRACE(("R128EnterVT\n")); +#ifdef XF86DRI + if (R128PTR(pScrn)->directRenderingEnabled) { + R128CCEStart(pScrn); + DRIUnlock(pScrn->pScreen); + } +#endif + if (!R128ModeInit(pScrn, pScrn->currentMode)) return FALSE; + if (info->accelOn) + R128EngineInit(pScrn); + + info->PaletteSavedOnVT = FALSE; + R128AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + +/* Called when VT switching away from the X server. Restore the original + text mode. */ +void R128LeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + R128SavePtr save = &info->ModeReg; + + R128TRACE(("R128LeaveVT\n")); +#ifdef XF86DRI + if (R128PTR(pScrn)->directRenderingEnabled) { + DRILock(pScrn->pScreen, 0); + R128CCEStop(pScrn); + } +#endif + R128SavePalette(pScrn, save); + info->PaletteSavedOnVT = TRUE; + R128Restore(pScrn); +} + +static Bool +R128EnterVTFBDev(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + R128SavePtr restore = &info->SavedReg; + fbdevHWEnterVT(scrnIndex,flags); + R128RestorePalette(pScrn,restore); + R128EngineInit(pScrn); + return TRUE; +} + +static void R128LeaveVTFBDev(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + R128SavePtr save = &info->SavedReg; + R128SavePalette(pScrn,save); + fbdevHWLeaveVT(scrnIndex,flags); +} + +/* Called at the end of each server generation. Restore the original text + mode, unmap video memory, and unwrap and call the saved CloseScreen + function. */ +static Bool R128CloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + R128InfoPtr info = R128PTR(pScrn); + + R128TRACE(("R128CloseScreen\n")); + +#ifdef XF86DRI + /* Disable direct rendering */ + if (info->directRenderingEnabled) { + R128DRICloseScreen(pScreen); + info->directRenderingEnabled = FALSE; + } +#endif + + if (pScrn->vtSema) { + R128Restore(pScrn); + R128UnmapMem(pScrn); + } + + if (info->accel) XAADestroyInfoRec(info->accel); + info->accel = NULL; + + if (info->scratch_save) xfree(info->scratch_save); + info->scratch_save = NULL; + + if (info->cursor) xf86DestroyCursorInfoRec(info->cursor); + info->cursor = NULL; + + if (info->DGAModes) xfree(info->DGAModes); + info->DGAModes = NULL; + + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = info->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + +void R128FreeScreen(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + R128TRACE(("R128FreeScreen\n")); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(pScrn); + R128FreeRec(pScrn); +} + +#ifdef DPMSExtension +/* Sets VESA Display Power Management Signaling (DPMS) Mode. */ +static void R128DisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, int flags) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + int mask = (R128_CRTC_DISPLAY_DIS + | R128_CRTC_HSYNC_DIS + | R128_CRTC_VSYNC_DIS); + + switch (PowerManagementMode) { + case DPMSModeOn: + /* Screen: On; HSync: On, VSync: On */ + OUTREGP(R128_CRTC_EXT_CNTL, 0, ~mask); + break; + case DPMSModeStandby: + /* Screen: Off; HSync: Off, VSync: On */ + OUTREGP(R128_CRTC_EXT_CNTL, + R128_CRTC_DISPLAY_DIS | R128_CRTC_HSYNC_DIS, ~mask); + break; + case DPMSModeSuspend: + /* Screen: Off; HSync: On, VSync: Off */ + OUTREGP(R128_CRTC_EXT_CNTL, + R128_CRTC_DISPLAY_DIS | R128_CRTC_VSYNC_DIS, ~mask); + break; + case DPMSModeOff: + /* Screen: Off; HSync: Off, VSync: Off */ + OUTREGP(R128_CRTC_EXT_CNTL, mask, ~mask); + break; + } +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_misc.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_misc.c new file mode 100644 index 000000000..bbaf3e4d7 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_misc.c @@ -0,0 +1,84 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_misc.c,v 1.1 2000/11/02 16:55:36 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * 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 Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef XFree86LOADER + +#include "ativersion.h" + +#include "r128_version.h" + +#include "xf86.h" + +/* Module loader interface for subsidiary driver module */ + +static XF86ModuleVersionInfo R128VersionRec = +{ + R128_DRIVER_NAME, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + R128_VERSION_MAJOR, R128_VERSION_MINOR, R128_VERSION_PATCH, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +/* + * R128Setup -- + * + * This function is called every time the module is loaded. + */ +static pointer +R128Setup +( + pointer Module, + pointer Options, + int *ErrorMajor, + int *ErrorMinor +) +{ + static Bool Inited = FALSE; + + if (!Inited) + { + /* Ensure main driver module is loaded, but not as a submodule */ + if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME)) + xf86LoadOneModule(ATI_DRIVER_NAME, Options); + + Inited = TRUE; + } + + return (pointer)TRUE; +} + +/* The following record must be called r128ModuleData */ +XF86ModuleData r128ModuleData = +{ + &R128VersionRec, + R128Setup, + NULL +}; + +#endif /* XFree86LOADER */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c new file mode 100644 index 000000000..03fa17a4c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c @@ -0,0 +1,195 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.c,v 1.1 2000/11/02 16:55:37 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + +#include "atimodule.h" +#include "ativersion.h" + +#include "r128_probe.h" +#include "r128_version.h" + +#include "xf86PciInfo.h" + +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86Resources.h" + +SymTabRec R128Chipsets[] = { + { PCI_CHIP_RAGE128RE, "ATI Rage 128 RE (PCI)" }, + { PCI_CHIP_RAGE128RF, "ATI Rage 128 RF (AGP)" }, + { PCI_CHIP_RAGE128RK, "ATI Rage 128 RK (PCI)" }, + { PCI_CHIP_RAGE128RL, "ATI Rage 128 RL (AGP)" }, + { PCI_CHIP_RAGE128PF, "ATI Rage 128 Pro PF (AGP)" }, + { PCI_CHIP_RAGE128LE, "ATI Rage 128 Mobility LE (PCI)" }, + { PCI_CHIP_RAGE128LF, "ATI Rage 128 Mobility LF (AGP)" }, + { PCI_CHIP_RAGE128MF, "ATI Rage 128 Mobility MF (AGP)" }, + { PCI_CHIP_RAGE128ML, "ATI Rage 128 Mobility ML (AGP)" }, + { -1, NULL } +}; + +PciChipsets R128PciChipsets[] = { + { PCI_CHIP_RAGE128RE, PCI_CHIP_RAGE128RE, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128RF, PCI_CHIP_RAGE128RF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128RK, PCI_CHIP_RAGE128RK, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128RL, PCI_CHIP_RAGE128RL, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128PF, PCI_CHIP_RAGE128PF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128LE, PCI_CHIP_RAGE128LE, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128LF, PCI_CHIP_RAGE128LF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128MF, PCI_CHIP_RAGE128MF, RES_SHARED_VGA }, + { PCI_CHIP_RAGE128ML, PCI_CHIP_RAGE128ML, RES_SHARED_VGA }, + { -1, -1, RES_UNDEFINED } +}; + +/* Return the options for supported chipset 'n'; NULL otherwise */ +OptionInfoPtr +R128AvailableOptions(int chipid, int busid) +{ + int i; + + /* + * Return options defined in the r128 submodule which will have been + * loaded by this point. + */ + for (i = 0; R128PciChipsets[i].PCIid > 0; i++) { + if (chipid == R128PciChipsets[i].PCIid) + return R128Options; + } + return NULL; +} + +/* Return the string name for supported chipset 'n'; NULL otherwise. */ +void +R128Identify(int flags) +{ + xf86PrintChipsets(R128_NAME, + "Driver for ATI Rage 128 chipsets", + R128Chipsets); +} + +/* Return TRUE if chipset is present; FALSE otherwise. */ +Bool +R128Probe(DriverPtr drv, int flags) +{ + int numUsed; + int numDevSections, nATIGDev, nR128GDev; + int *usedChips; + GDevPtr *devSections, *ATIGDevs, *R128GDevs; + EntityInfoPtr pEnt; + Bool foundScreen = FALSE; + int i; + + if (!xf86GetPciVideoInfo()) return FALSE; + + /* Collect unclaimed device sections for both driver names */ + nATIGDev = xf86MatchDevice(ATI_NAME, &ATIGDevs); + nR128GDev = xf86MatchDevice(R128_NAME, &R128GDevs); + + if (!(numDevSections = nATIGDev + nR128GDev)) return FALSE; + + if (!ATIGDevs) { + if (!(devSections = R128GDevs)) + numDevSections = 1; + else + numDevSections = nR128GDev; + } if (!R128GDevs) { + devSections = ATIGDevs; + numDevSections = nATIGDev; + } else { + /* Combine into one list */ + devSections = xnfalloc((numDevSections + 1) * sizeof(GDevPtr)); + (void)memcpy(devSections, + ATIGDevs, nATIGDev * sizeof(GDevPtr)); + (void)memcpy(devSections + nATIGDev, + R128GDevs, nR128GDev * sizeof(GDevPtr)); + devSections[numDevSections] = NULL; + xfree(ATIGDevs); + xfree(R128GDevs); + } + + numUsed = xf86MatchPciInstances(R128_NAME, + PCI_VENDOR_ATI, + R128Chipsets, + R128PciChipsets, + devSections, + numDevSections, + drv, + &usedChips); + + if (numUsed<=0) return FALSE; + + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + pEnt = xf86GetEntityInfo(usedChips[i]); + + if (pEnt->active) { + ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); + +#ifdef XFree86LOADER + if (!xf86LoadSubModule(pScrn, "r128")) { + xf86Msg(X_ERROR, + R128_NAME ": Failed to load \"r128\" module.\n"); + xf86DeleteScreen(pScrn->scrnIndex, 0); + continue; + } + + xf86LoaderReqSymLists(R128Symbols, NULL); +#endif + + pScrn->driverVersion = R128_VERSION_CURRENT; + pScrn->driverName = R128_DRIVER_NAME; + pScrn->name = R128_NAME; + pScrn->Probe = R128Probe; + pScrn->PreInit = R128PreInit; + pScrn->ScreenInit = R128ScreenInit; + pScrn->SwitchMode = R128SwitchMode; + pScrn->AdjustFrame = R128AdjustFrame; + pScrn->EnterVT = R128EnterVT; + pScrn->LeaveVT = R128LeaveVT; + pScrn->FreeScreen = R128FreeScreen; + pScrn->ValidMode = R128ValidMode; + + foundScreen = TRUE; + + xf86ConfigActivePciEntity(pScrn, usedChips[i], R128PciChipsets, + 0, 0, 0, 0, 0); + } + xfree(pEnt); + } + + if (numUsed) xfree(usedChips); + xfree(devSections); + + return foundScreen; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h new file mode 100644 index 000000000..11d71749f --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h @@ -0,0 +1,73 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_probe.h,v 1.1 2000/11/02 16:55:37 tsi Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and VA Linux Systems, Inc., Sunnyvale, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + +#ifndef _R128_PROBE_H_ +#define _R128_PROBE_H_ 1 + +#include "atiproto.h" + +#include "xf86str.h" + +/* r128_probe.c */ +extern OptionInfoPtr R128AvailableOptions + FunctionPrototype((int, int)); +extern void R128Identify + FunctionPrototype((int)); +extern Bool R128Probe + FunctionPrototype((DriverPtr, int)); + +extern SymTabRec R128Chipsets[]; +extern PciChipsets R128PciChipsets[]; + +/* r128_driver.c */ +extern Bool R128PreInit + FunctionPrototype((ScrnInfoPtr, int)); +extern Bool R128ScreenInit + FunctionPrototype((int, ScreenPtr, int, char **)); +extern Bool R128SwitchMode + FunctionPrototype((int, DisplayModePtr, int)); +extern void R128AdjustFrame + FunctionPrototype((int, int, int, int)); +extern Bool R128EnterVT + FunctionPrototype((int, int)); +extern void R128LeaveVT + FunctionPrototype((int, int)); +extern void R128FreeScreen + FunctionPrototype((int, int)); +extern int R128ValidMode + FunctionPrototype((int, DisplayModePtr, Bool, int)); + +extern OptionInfoRec R128Options[]; + +#endif /* _R128_PROBE_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h new file mode 100644 index 000000000..cc71a015e --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h @@ -0,0 +1,1459 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h,v 1.1 2000/11/02 16:55:37 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * References: + * + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + +#ifndef _R128_REG_H_ +#define _R128_REG_H_ +#include <compiler.h> + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(R128MMIO, addr) +#define INREG16(addr) MMIO_IN16(R128MMIO, addr) +#define INREG(addr) MMIO_IN32(R128MMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(R128MMIO, addr, val) +#define OUTREG16(addr, val) MMIO_OUT16(R128MMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(R128MMIO, addr, val) + +#define ADDRREG(addr) ((volatile CARD32 *)(R128MMIO + (addr))) + + +#define OUTREGP(addr, val, mask) \ + do { \ + CARD32 tmp = INREG(addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTREG(addr, tmp); \ + } while (0) + +#define INPLL(pScrn, addr) R128INPLL(pScrn, addr) + +#define OUTPLL(addr, val) \ + do { \ + OUTREG8(R128_CLOCK_CNTL_INDEX, ((addr) & 0x1f) | R128_PLL_WR_EN); \ + OUTREG(R128_CLOCK_CNTL_DATA, val); \ + } while (0) + +#define OUTPLLP(pScrn, addr, val, mask) \ + do { \ + CARD32 tmp = INPLL(pScrn, addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTPLL(addr, tmp); \ + } while (0) + +#define OUTPAL_START(idx) \ + do { \ + OUTREG8(R128_PALETTE_INDEX, (idx)); \ + } while (0) + +#define OUTPAL_NEXT(r, g, b) \ + do { \ + OUTREG(R128_PALETTE_DATA, ((r) << 16) | ((g) << 8) | (b)); \ + } while (0) + +#define OUTPAL_NEXT_CARD32(v) \ + do { \ + OUTREG(R128_PALETTE_DATA, (v & 0x00ffffff)); \ + } while (0) + +#define OUTPAL(idx, r, g, b) \ + do { \ + OUTPAL_START((idx)); \ + OUTPAL_NEXT((r), (g), (b)); \ + } while (0) + +#define INPAL_START(idx) \ + do { \ + OUTREG(R128_PALETTE_INDEX, (idx) << 16); \ + } while (0) + +#define INPAL_NEXT() INREG(R128_PALETTE_DATA) + +#define PAL_SELECT(idx) \ + do { \ + if (idx) { \ + OUTREG(R128_DAC_CNTL, INREG(R128_DAC_CNTL) | \ + R128_DAC_PALETTE_ACC_CTL); \ + } else { \ + OUTREG(R128_DAC_CNTL, INREG(R128_DAC_CNTL) & \ + ~R128_DAC_PALETTE_ACC_CTL); \ + } \ + } while (0) + +#define R128_ADAPTER_ID 0x0f2c /* PCI */ +#define R128_AGP_APER_OFFSET 0x0178 +#define R128_AGP_BASE 0x0170 +#define R128_AGP_CNTL 0x0174 +# define R128_AGP_APER_SIZE_256MB (0x00 << 0) +# define R128_AGP_APER_SIZE_128MB (0x20 << 0) +# define R128_AGP_APER_SIZE_64MB (0x30 << 0) +# define R128_AGP_APER_SIZE_32MB (0x38 << 0) +# define R128_AGP_APER_SIZE_16MB (0x3c << 0) +# define R128_AGP_APER_SIZE_8MB (0x3e << 0) +# define R128_AGP_APER_SIZE_4MB (0x3f << 0) +# define R128_AGP_APER_SIZE_MASK (0x3f << 0) +#define R128_AGP_CNTL_B 0x0b44 +#define R128_AGP_COMMAND 0x0f58 /* PCI */ +#define R128_AGP_PLL_CNTL 0x0010 /* PLL */ +#define R128_AGP_STATUS 0x0f54 /* PCI */ +# define R128_AGP_1X_MODE 0x01 +# define R128_AGP_2X_MODE 0x02 +# define R128_AGP_4X_MODE 0x04 +# define R128_AGP_MODE_MASK 0x07 +#define R128_AMCGPIO_A_REG 0x01a0 +#define R128_AMCGPIO_EN_REG 0x01a8 +#define R128_AMCGPIO_MASK 0x0194 +#define R128_AMCGPIO_Y_REG 0x01a4 +#define R128_ATTRDR 0x03c1 /* VGA */ +#define R128_ATTRDW 0x03c0 /* VGA */ +#define R128_ATTRX 0x03c0 /* VGA */ +# define R128_AUX1_SC_EN (1 << 0) +# define R128_AUX1_SC_MODE_OR (0 << 1) +# define R128_AUX1_SC_MODE_NAND (1 << 1) +# define R128_AUX2_SC_EN (1 << 2) +# define R128_AUX2_SC_MODE_OR (0 << 3) +# define R128_AUX2_SC_MODE_NAND (1 << 3) +# define R128_AUX3_SC_EN (1 << 4) +# define R128_AUX3_SC_MODE_OR (0 << 5) +# define R128_AUX3_SC_MODE_NAND (1 << 5) +#define R128_AUX_SC_CNTL 0x1660 +#define R128_AUX1_SC_BOTTOM 0x1670 +#define R128_AUX1_SC_LEFT 0x1664 +#define R128_AUX1_SC_RIGHT 0x1668 +#define R128_AUX1_SC_TOP 0x166c +#define R128_AUX2_SC_BOTTOM 0x1680 +#define R128_AUX2_SC_LEFT 0x1674 +#define R128_AUX2_SC_RIGHT 0x1678 +#define R128_AUX2_SC_TOP 0x167c +#define R128_AUX3_SC_BOTTOM 0x1690 +#define R128_AUX3_SC_LEFT 0x1684 +#define R128_AUX3_SC_RIGHT 0x1688 +#define R128_AUX3_SC_TOP 0x168c +#define R128_AUX_WINDOW_HORZ_CNTL 0x02d8 +#define R128_AUX_WINDOW_VERT_CNTL 0x02dc + +#define R128_BASE_CODE 0x0f0b +#define R128_BIOS_0_SCRATCH 0x0010 +#define R128_BIOS_1_SCRATCH 0x0014 +#define R128_BIOS_2_SCRATCH 0x0018 +#define R128_BIOS_3_SCRATCH 0x001c +#define R128_BIOS_ROM 0x0f30 /* PCI */ +#define R128_BIST 0x0f0f /* PCI */ +#define R128_BRUSH_DATA0 0x1480 +#define R128_BRUSH_DATA1 0x1484 +#define R128_BRUSH_DATA10 0x14a8 +#define R128_BRUSH_DATA11 0x14ac +#define R128_BRUSH_DATA12 0x14b0 +#define R128_BRUSH_DATA13 0x14b4 +#define R128_BRUSH_DATA14 0x14b8 +#define R128_BRUSH_DATA15 0x14bc +#define R128_BRUSH_DATA16 0x14c0 +#define R128_BRUSH_DATA17 0x14c4 +#define R128_BRUSH_DATA18 0x14c8 +#define R128_BRUSH_DATA19 0x14cc +#define R128_BRUSH_DATA2 0x1488 +#define R128_BRUSH_DATA20 0x14d0 +#define R128_BRUSH_DATA21 0x14d4 +#define R128_BRUSH_DATA22 0x14d8 +#define R128_BRUSH_DATA23 0x14dc +#define R128_BRUSH_DATA24 0x14e0 +#define R128_BRUSH_DATA25 0x14e4 +#define R128_BRUSH_DATA26 0x14e8 +#define R128_BRUSH_DATA27 0x14ec +#define R128_BRUSH_DATA28 0x14f0 +#define R128_BRUSH_DATA29 0x14f4 +#define R128_BRUSH_DATA3 0x148c +#define R128_BRUSH_DATA30 0x14f8 +#define R128_BRUSH_DATA31 0x14fc +#define R128_BRUSH_DATA32 0x1500 +#define R128_BRUSH_DATA33 0x1504 +#define R128_BRUSH_DATA34 0x1508 +#define R128_BRUSH_DATA35 0x150c +#define R128_BRUSH_DATA36 0x1510 +#define R128_BRUSH_DATA37 0x1514 +#define R128_BRUSH_DATA38 0x1518 +#define R128_BRUSH_DATA39 0x151c +#define R128_BRUSH_DATA4 0x1490 +#define R128_BRUSH_DATA40 0x1520 +#define R128_BRUSH_DATA41 0x1524 +#define R128_BRUSH_DATA42 0x1528 +#define R128_BRUSH_DATA43 0x152c +#define R128_BRUSH_DATA44 0x1530 +#define R128_BRUSH_DATA45 0x1534 +#define R128_BRUSH_DATA46 0x1538 +#define R128_BRUSH_DATA47 0x153c +#define R128_BRUSH_DATA48 0x1540 +#define R128_BRUSH_DATA49 0x1544 +#define R128_BRUSH_DATA5 0x1494 +#define R128_BRUSH_DATA50 0x1548 +#define R128_BRUSH_DATA51 0x154c +#define R128_BRUSH_DATA52 0x1550 +#define R128_BRUSH_DATA53 0x1554 +#define R128_BRUSH_DATA54 0x1558 +#define R128_BRUSH_DATA55 0x155c +#define R128_BRUSH_DATA56 0x1560 +#define R128_BRUSH_DATA57 0x1564 +#define R128_BRUSH_DATA58 0x1568 +#define R128_BRUSH_DATA59 0x156c +#define R128_BRUSH_DATA6 0x1498 +#define R128_BRUSH_DATA60 0x1570 +#define R128_BRUSH_DATA61 0x1574 +#define R128_BRUSH_DATA62 0x1578 +#define R128_BRUSH_DATA63 0x157c +#define R128_BRUSH_DATA7 0x149c +#define R128_BRUSH_DATA8 0x14a0 +#define R128_BRUSH_DATA9 0x14a4 +#define R128_BRUSH_SCALE 0x1470 +#define R128_BRUSH_Y_X 0x1474 +#define R128_BUS_CNTL 0x0030 +# define R128_BUS_MASTER_DIS (1 << 6) +# define R128_BUS_RD_DISCARD_EN (1 << 24) +# define R128_BUS_RD_ABORT_EN (1 << 25) +# define R128_BUS_MSTR_DISCONNECT_EN (1 << 28) +# define R128_BUS_WRT_BURST (1 << 29) +# define R128_BUS_READ_BURST (1 << 30) +#define R128_BUS_CNTL1 0x0034 +# define R128_BUS_WAIT_ON_LOCK_EN (1 << 4) + +#define R128_CACHE_CNTL 0x1724 +#define R128_CACHE_LINE 0x0f0c /* PCI */ +#define R128_CAP0_TRIG_CNTL 0x0950 /* ? */ +#define R128_CAP1_TRIG_CNTL 0x09c0 /* ? */ +#define R128_CAPABILITIES_ID 0x0f50 /* PCI */ +#define R128_CAPABILITIES_PTR 0x0f34 /* PCI */ +#define R128_CLK_PIN_CNTL 0x0001 /* PLL */ +#define R128_CLOCK_CNTL_DATA 0x000c +#define R128_CLOCK_CNTL_INDEX 0x0008 +# define R128_PLL_WR_EN (1 << 7) +# define R128_PLL_DIV_SEL (3 << 8) +#define R128_CLR_CMP_CLR_3D 0x1a24 +#define R128_CLR_CMP_CLR_DST 0x15c8 +#define R128_CLR_CMP_CLR_SRC 0x15c4 +#define R128_CLR_CMP_CNTL 0x15c0 +# define R128_SRC_CMP_EQ_COLOR (4 << 0) +# define R128_SRC_CMP_NEQ_COLOR (5 << 0) +# define R128_CLR_CMP_SRC_SOURCE (1 << 24) +#define R128_CLR_CMP_MASK 0x15cc +# define R128_CLR_CMP_MSK 0xffffffff +#define R128_CLR_CMP_MASK_3D 0x1A28 +#define R128_COMMAND 0x0f04 /* PCI */ +#define R128_COMPOSITE_SHADOW_ID 0x1a0c +#define R128_CONFIG_APER_0_BASE 0x0100 +#define R128_CONFIG_APER_1_BASE 0x0104 +#define R128_CONFIG_APER_SIZE 0x0108 +#define R128_CONFIG_BONDS 0x00e8 +#define R128_CONFIG_CNTL 0x00e0 +#define R128_CONFIG_MEMSIZE 0x00f8 +#define R128_CONFIG_MEMSIZE_EMBEDDED 0x0114 +#define R128_CONFIG_REG_1_BASE 0x010c +#define R128_CONFIG_REG_APER_SIZE 0x0110 +#define R128_CONFIG_XSTRAP 0x00e4 +#define R128_CONSTANT_COLOR_C 0x1d34 +# define R128_CONSTANT_COLOR_MASK 0x00ffffff +# define R128_CONSTANT_COLOR_ONE 0x00ffffff +# define R128_CONSTANT_COLOR_ZERO 0x00000000 +#define R128_CRC_CMDFIFO_ADDR 0x0740 +#define R128_CRC_CMDFIFO_DOUT 0x0744 +#define R128_CRTC_CRNT_FRAME 0x0214 +#define R128_CRTC_DEBUG 0x021c +#define R128_CRTC_EXT_CNTL 0x0054 +# define R128_CRTC_VGA_XOVERSCAN (1 << 0) +# define R128_VGA_ATI_LINEAR (1 << 3) +# define R128_XCRT_CNT_EN (1 << 6) +# define R128_CRTC_HSYNC_DIS (1 << 8) +# define R128_CRTC_VSYNC_DIS (1 << 9) +# define R128_CRTC_DISPLAY_DIS (1 << 10) +# define R128_CRTC_CRT_ON (1 << 15) +#define R128_CRTC_EXT_CNTL_DPMS_BYTE 0x0055 +# define R128_CRTC_HSYNC_DIS_BYTE (1 << 0) +# define R128_CRTC_VSYNC_DIS_BYTE (1 << 1) +# define R128_CRTC_DISPLAY_DIS_BYTE (1 << 2) +#define R128_CRTC_GEN_CNTL 0x0050 +# define R128_CRTC_DBL_SCAN_EN (1 << 0) +# define R128_CRTC_INTERLACE_EN (1 << 1) +# define R128_CRTC_CSYNC_EN (1 << 4) +# define R128_CRTC_CUR_EN (1 << 16) +# define R128_CRTC_CUR_MODE_MASK (7 << 17) +# define R128_CRTC_ICON_EN (1 << 20) +# define R128_CRTC_EXT_DISP_EN (1 << 24) +# define R128_CRTC_EN (1 << 25) +# define R128_CRTC_DISP_REQ_EN_B (1 << 26) +#define R128_CRTC_GUI_TRIG_VLINE 0x0218 +#define R128_CRTC_H_SYNC_STRT_WID 0x0204 +# define R128_CRTC_H_SYNC_STRT_PIX (0x07 << 0) +# define R128_CRTC_H_SYNC_STRT_CHAR (0x1ff << 3) +# define R128_CRTC_H_SYNC_STRT_CHAR_SHIFT 3 +# define R128_CRTC_H_SYNC_WID (0x3f << 16) +# define R128_CRTC_H_SYNC_WID_SHIFT 16 +# define R128_CRTC_H_SYNC_POL (1 << 23) +#define R128_CRTC_H_TOTAL_DISP 0x0200 +# define R128_CRTC_H_TOTAL (0x01ff << 0) +# define R128_CRTC_H_TOTAL_SHIFT 0 +# define R128_CRTC_H_DISP (0x00ff << 16) +# define R128_CRTC_H_DISP_SHIFT 16 +#define R128_CRTC_OFFSET 0x0224 +#define R128_CRTC_OFFSET_CNTL 0x0228 +#define R128_CRTC_PITCH 0x022c +#define R128_CRTC_STATUS 0x005c +# define R128_CRTC_VBLANK_SAVE (1 << 1) +#define R128_CRTC_V_SYNC_STRT_WID 0x020c +# define R128_CRTC_V_SYNC_STRT (0x7ff << 0) +# define R128_CRTC_V_SYNC_STRT_SHIFT 0 +# define R128_CRTC_V_SYNC_WID (0x1f << 16) +# define R128_CRTC_V_SYNC_WID_SHIFT 16 +# define R128_CRTC_V_SYNC_POL (1 << 23) +#define R128_CRTC_V_TOTAL_DISP 0x0208 +# define R128_CRTC_V_TOTAL (0x07ff << 0) +# define R128_CRTC_V_TOTAL_SHIFT 0 +# define R128_CRTC_V_DISP (0x07ff << 16) +# define R128_CRTC_V_DISP_SHIFT 16 +#define R128_CRTC_VLINE_CRNT_VLINE 0x0210 +# define R128_CRTC_CRNT_VLINE_MASK (0x7ff << 16) +#define R128_CRTC2_CRNT_FRAME 0x0314 +#define R128_CRTC2_DEBUG 0x031c +#define R128_CRTC2_GEN_CNTL 0x03f8 +#define R128_CRTC2_GUI_TRIG_VLINE 0x0318 +#define R128_CRTC2_H_SYNC_STRT_WID 0x0304 +#define R128_CRTC2_H_TOTAL_DISP 0x0300 +#define R128_CRTC2_OFFSET 0x0324 +#define R128_CRTC2_OFFSET_CNTL 0x0328 +#define R128_CRTC2_PITCH 0x032c +#define R128_CRTC2_STATUS 0x03fc +#define R128_CRTC2_V_SYNC_STRT_WID 0x030c +#define R128_CRTC2_V_TOTAL_DISP 0x0308 +#define R128_CRTC2_VLINE_CRNT_VLINE 0x0310 +#define R128_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ +#define R128_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ +#define R128_CUR_CLR0 0x026c +#define R128_CUR_CLR1 0x0270 +#define R128_CUR_HORZ_VERT_OFF 0x0268 +#define R128_CUR_HORZ_VERT_POSN 0x0264 +#define R128_CUR_OFFSET 0x0260 +# define R128_CUR_LOCK (1 << 31) + +#define R128_DAC_CNTL 0x0058 +# define R128_DAC_RANGE_CNTL (3 << 0) +# define R128_DAC_BLANKING (1 << 2) +# define R128_DAC_CRT_SEL_CRTC2 (1 << 4) +# define R128_DAC_PALETTE_ACC_CTL (1 << 5) +# define R128_DAC_8BIT_EN (1 << 8) +# define R128_DAC_VGA_ADR_EN (1 << 13) +# define R128_DAC_MASK_ALL (0xff << 24) +#define R128_DAC_CRC_SIG 0x02cc +#define R128_DAC_DATA 0x03c9 /* VGA */ +#define R128_DAC_MASK 0x03c6 /* VGA */ +#define R128_DAC_R_INDEX 0x03c7 /* VGA */ +#define R128_DAC_W_INDEX 0x03c8 /* VGA */ +#define R128_DDA_CONFIG 0x02e0 +#define R128_DDA_ON_OFF 0x02e4 +#define R128_DEFAULT_OFFSET 0x16e0 +#define R128_DEFAULT_PITCH 0x16e4 +#define R128_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 +# define R128_DEFAULT_SC_RIGHT_MAX (0x1fff << 0) +# define R128_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) +#define R128_DESTINATION_3D_CLR_CMP_VAL 0x1820 +#define R128_DESTINATION_3D_CLR_CMP_MSK 0x1824 +#define R128_DEVICE_ID 0x0f02 /* PCI */ +#define R128_DP_BRUSH_BKGD_CLR 0x1478 +#define R128_DP_BRUSH_FRGD_CLR 0x147c +#define R128_DP_CNTL 0x16c0 +# define R128_DST_X_LEFT_TO_RIGHT (1 << 0) +# define R128_DST_Y_TOP_TO_BOTTOM (1 << 1) +#define R128_DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0 +# define R128_DST_Y_MAJOR (1 << 2) +# define R128_DST_Y_DIR_TOP_TO_BOTTOM (1 << 15) +# define R128_DST_X_DIR_LEFT_TO_RIGHT (1 << 31) +#define R128_DP_DATATYPE 0x16c4 +# define R128_HOST_BIG_ENDIAN_EN (1 << 29) +#define R128_DP_GUI_MASTER_CNTL 0x146c +# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) +# define R128_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) +# define R128_GMC_SRC_CLIPPING (1 << 2) +# define R128_GMC_DST_CLIPPING (1 << 3) +# define R128_GMC_BRUSH_DATATYPE_MASK (0x0f << 4) +# define R128_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4) +# define R128_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4) +# define R128_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4) +# define R128_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) +# define R128_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) +# define R128_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) +# define R128_GMC_BRUSH_8x8_COLOR (10 << 4) +# define R128_GMC_BRUSH_1X8_COLOR (12 << 4) +# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4) +# define R128_GMC_BRUSH_NONE (15 << 4) +# define R128_GMC_DST_8BPP_CI (2 << 8) +# define R128_GMC_DST_15BPP (3 << 8) +# define R128_GMC_DST_16BPP (4 << 8) +# define R128_GMC_DST_24BPP (5 << 8) +# define R128_GMC_DST_32BPP (6 << 8) +# define R128_GMC_DST_8BPP_RGB (7 << 8) +# define R128_GMC_DST_Y8 (8 << 8) +# define R128_GMC_DST_RGB8 (9 << 8) +# define R128_GMC_DST_VYUY (11 << 8) +# define R128_GMC_DST_YVYU (12 << 8) +# define R128_GMC_DST_AYUV444 (14 << 8) +# define R128_GMC_DST_ARGB4444 (15 << 8) +# define R128_GMC_DST_DATATYPE_MASK (0x0f << 8) +# define R128_GMC_DST_DATATYPE_SHIFT 8 +# define R128_GMC_SRC_DATATYPE_MASK (3 << 12) +# define R128_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12) +# define R128_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12) +# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12) +# define R128_GMC_BYTE_PIX_ORDER (1 << 14) +# define R128_GMC_BYTE_MSB_TO_LSB (0 << 14) +# define R128_GMC_BYTE_LSB_TO_MSB (1 << 14) +# define R128_GMC_CONVERSION_TEMP (1 << 15) +# define R128_GMC_CONVERSION_TEMP_6500 (0 << 15) +# define R128_GMC_CONVERSION_TEMP_9300 (1 << 15) +# define R128_GMC_ROP3_MASK (0xff << 16) +# define R128_DP_SRC_SOURCE_MASK (7 << 24) +# define R128_DP_SRC_SOURCE_MEMORY (2 << 24) +# define R128_DP_SRC_SOURCE_HOST_DATA (3 << 24) +# define R128_GMC_3D_FCN_EN (1 << 27) +# define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define R128_GMC_AUX_CLIP_DIS (1 << 29) +# define R128_GMC_WR_MSK_DIS (1 << 30) +# define R128_GMC_LD_BRUSH_Y_X (1 << 31) +# define R128_ROP3_ZERO 0x00000000 +# define R128_ROP3_DSa 0x00880000 +# define R128_ROP3_SDna 0x00440000 +# define R128_ROP3_S 0x00cc0000 +# define R128_ROP3_DSna 0x00220000 +# define R128_ROP3_D 0x00aa0000 +# define R128_ROP3_DSx 0x00660000 +# define R128_ROP3_DSo 0x00ee0000 +# define R128_ROP3_DSon 0x00110000 +# define R128_ROP3_DSxn 0x00990000 +# define R128_ROP3_Dn 0x00550000 +# define R128_ROP3_SDno 0x00dd0000 +# define R128_ROP3_Sn 0x00330000 +# define R128_ROP3_DSno 0x00bb0000 +# define R128_ROP3_DSan 0x00770000 +# define R128_ROP3_ONE 0x00ff0000 +# define R128_ROP3_DPa 0x00a00000 +# define R128_ROP3_PDna 0x00500000 +# define R128_ROP3_P 0x00f00000 +# define R128_ROP3_DPna 0x000a0000 +# define R128_ROP3_D 0x00aa0000 +# define R128_ROP3_DPx 0x005a0000 +# define R128_ROP3_DPo 0x00fa0000 +# define R128_ROP3_DPon 0x00050000 +# define R128_ROP3_PDxn 0x00a50000 +# define R128_ROP3_PDno 0x00f50000 +# define R128_ROP3_Pn 0x000f0000 +# define R128_ROP3_DPno 0x00af0000 +# define R128_ROP3_DPan 0x005f0000 + + +#define R128_DP_GUI_MASTER_CNTL_C 0x1c84 +#define R128_DP_MIX 0x16c8 +#define R128_DP_SRC_BKGD_CLR 0x15dc +#define R128_DP_SRC_FRGD_CLR 0x15d8 +#define R128_DP_WRITE_MASK 0x16cc +#define R128_DST_BRES_DEC 0x1630 +#define R128_DST_BRES_ERR 0x1628 +#define R128_DST_BRES_INC 0x162c +#define R128_DST_BRES_LNTH 0x1634 +#define R128_DST_BRES_LNTH_SUB 0x1638 +#define R128_DST_HEIGHT 0x1410 +#define R128_DST_HEIGHT_WIDTH 0x143c +#define R128_DST_HEIGHT_WIDTH_8 0x158c +#define R128_DST_HEIGHT_WIDTH_BW 0x15b4 +#define R128_DST_HEIGHT_Y 0x15a0 +#define R128_DST_OFFSET 0x1404 +#define R128_DST_PITCH 0x1408 +#define R128_DST_PITCH_OFFSET 0x142c +#define R128_DST_PITCH_OFFSET_C 0x1c80 +# define R128_PITCH_SHIFT 21 +#define R128_DST_WIDTH 0x140c +#define R128_DST_WIDTH_HEIGHT 0x1598 +#define R128_DST_WIDTH_X 0x1588 +#define R128_DST_WIDTH_X_INCY 0x159c +#define R128_DST_X 0x141c +#define R128_DST_X_SUB 0x15a4 +#define R128_DST_X_Y 0x1594 +#define R128_DST_Y 0x1420 +#define R128_DST_Y_SUB 0x15a8 +#define R128_DST_Y_X 0x1438 + +#define R128_EXT_MEM_CNTL 0x0144 + +#define R128_FCP_CNTL 0x0012 /* PLL */ +#define R128_FLUSH_1 0x1704 +#define R128_FLUSH_2 0x1708 +#define R128_FLUSH_3 0x170c +#define R128_FLUSH_4 0x1710 +#define R128_FLUSH_5 0x1714 +#define R128_FLUSH_6 0x1718 +#define R128_FLUSH_7 0x171c +#define R128_FOG_3D_TABLE_START 0x1810 +#define R128_FOG_3D_TABLE_END 0x1814 +#define R128_FOG_3D_TABLE_DENSITY 0x181c +#define R128_FOG_TABLE_INDEX 0x1a14 +#define R128_FOG_TABLE_DATA 0x1a18 +#define R128_FP_CRTC_H_TOTAL_DISP 0x0250 +#define R128_FP_CRTC_V_TOTAL_DISP 0x0254 +#define R128_FP_GEN_CNTL 0x0284 +# define R128_FP_FPON (1 << 0) +# define R128_FP_TDMS_EN (1 << 2) +# define R128_FP_DETECT_SENSE (1 << 8) +# define R128_FP_SEL_CRTC2 (1 << 13) +# define R128_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) +# define R128_FP_CRTC_USE_SHADOW_VEND (1 << 18) +# define R128_FP_CRTC_HORZ_DIV2_EN (1 << 20) +# define R128_FP_CRTC_HOR_CRT_DIV2_DIS (1 << 21) +# define R128_FP_USE_SHADOW_EN (1 << 24) +#define R128_FP_H_SYNC_STRT_WID 0x02c4 +#define R128_FP_HORZ_STRETCH 0x028c +# define R128_HORZ_STRETCH_RATIO_MASK 0xffff +# define R128_HORZ_STRETCH_RATIO_SHIFT 0 +# define R128_HORZ_STRETCH_RATIO_MAX 4096 +# define R128_HORZ_PANEL_SIZE (0xff << 16) +# define R128_HORZ_PANEL_SHIFT 16 +# define R128_HORZ_STRETCH_PIXREP (0 << 25) +# define R128_HORZ_STRETCH_BLEND (1 << 25) +# define R128_HORZ_STRETCH_ENABLE (1 << 26) +# define R128_HORZ_FP_LOOP_STRETCH (0x7 << 27) +# define R128_HORZ_STRETCH_RESERVED (1 << 30) +# define R128_HORZ_AUTO_RATIO_FIX_EN (1 << 31) + +#define R128_FP_PANEL_CNTL 0x0288 +# define R128_FP_DIGON (1 << 0) +# define R128_FP_BLON (1 << 1) +#define R128_FP_V_SYNC_STRT_WID 0x02c8 +#define R128_FP_VERT_STRETCH 0x0290 +# define R128_VERT_PANEL_SIZE (0x7ff << 0) +# define R128_VERT_PANEL_SHIFT 0 +# define R128_VERT_STRETCH_RATIO_MASK 0x3ff +# define R128_VERT_STRETCH_RATIO_SHIFT 11 +# define R128_VERT_STRETCH_RATIO_MAX 1024 +# define R128_VERT_STRETCH_ENABLE (1 << 24) +# define R128_VERT_STRETCH_LINEREP (0 << 25) +# define R128_VERT_STRETCH_BLEND (1 << 25) +# define R128_VERT_AUTO_RATIO_EN (1 << 26) +# define R128_VERT_STRETCH_RESERVED 0xf8e00000 + +#define R128_GEN_INT_CNTL 0x0040 +#define R128_GEN_INT_STATUS 0x0044 +# define R128_VSYNC_INT_AK (1 << 2) +# define R128_VSYNC_INT (1 << 2) +#define R128_GEN_RESET_CNTL 0x00f0 +# define R128_SOFT_RESET_GUI (1 << 0) +# define R128_SOFT_RESET_VCLK (1 << 8) +# define R128_SOFT_RESET_PCLK (1 << 9) +# define R128_SOFT_RESET_DISPENG_XCLK (1 << 11) +# define R128_SOFT_RESET_MEMCTLR_XCLK (1 << 12) +#define R128_GENENB 0x03c3 /* VGA */ +#define R128_GENFC_RD 0x03ca /* VGA */ +#define R128_GENFC_WT 0x03da /* VGA, 0x03ba */ +#define R128_GENMO_RD 0x03cc /* VGA */ +#define R128_GENMO_WT 0x03c2 /* VGA */ +#define R128_GENS0 0x03c2 /* VGA */ +#define R128_GENS1 0x03da /* VGA, 0x03ba */ +#define R128_GPIO_MONID 0x0068 +# define R128_GPIO_MONID_A_0 (1 << 0) +# define R128_GPIO_MONID_A_1 (1 << 1) +# define R128_GPIO_MONID_A_2 (1 << 2) +# define R128_GPIO_MONID_A_3 (1 << 3) +# define R128_GPIO_MONID_Y_0 (1 << 8) +# define R128_GPIO_MONID_Y_1 (1 << 9) +# define R128_GPIO_MONID_Y_2 (1 << 10) +# define R128_GPIO_MONID_Y_3 (1 << 11) +# define R128_GPIO_MONID_EN_0 (1 << 16) +# define R128_GPIO_MONID_EN_1 (1 << 17) +# define R128_GPIO_MONID_EN_2 (1 << 18) +# define R128_GPIO_MONID_EN_3 (1 << 19) +# define R128_GPIO_MONID_MASK_0 (1 << 24) +# define R128_GPIO_MONID_MASK_1 (1 << 25) +# define R128_GPIO_MONID_MASK_2 (1 << 26) +# define R128_GPIO_MONID_MASK_3 (1 << 27) +#define R128_GPIO_MONIDB 0x006c +#define R128_GRPH8_DATA 0x03cf /* VGA */ +#define R128_GRPH8_IDX 0x03ce /* VGA */ +#define R128_GUI_DEBUG0 0x16a0 +#define R128_GUI_DEBUG1 0x16a4 +#define R128_GUI_DEBUG2 0x16a8 +#define R128_GUI_DEBUG3 0x16ac +#define R128_GUI_DEBUG4 0x16b0 +#define R128_GUI_DEBUG5 0x16b4 +#define R128_GUI_DEBUG6 0x16b8 +#define R128_GUI_PROBE 0x16bc +#define R128_GUI_SCRATCH_REG0 0x15e0 +#define R128_GUI_SCRATCH_REG1 0x15e4 +#define R128_GUI_SCRATCH_REG2 0x15e8 +#define R128_GUI_SCRATCH_REG3 0x15ec +#define R128_GUI_SCRATCH_REG4 0x15f0 +#define R128_GUI_SCRATCH_REG5 0x15f4 +#define R128_GUI_STAT 0x1740 +# define R128_GUI_FIFOCNT_MASK 0x0fff +# define R128_GUI_ACTIVE (1 << 31) + +#define R128_HEADER 0x0f0e /* PCI */ +#define R128_HOST_DATA0 0x17c0 +#define R128_HOST_DATA1 0x17c4 +#define R128_HOST_DATA2 0x17c8 +#define R128_HOST_DATA3 0x17cc +#define R128_HOST_DATA4 0x17d0 +#define R128_HOST_DATA5 0x17d4 +#define R128_HOST_DATA6 0x17d8 +#define R128_HOST_DATA7 0x17dc +#define R128_HOST_DATA_LAST 0x17e0 +#define R128_HOST_PATH_CNTL 0x0130 +#define R128_HTOTAL_CNTL 0x0009 /* PLL */ +#define R128_HW_DEBUG 0x0128 +#define R128_HW_DEBUG2 0x011c + +#define R128_I2C_CNTL_1 0x0094 /* ? */ +#define R128_INTERRUPT_LINE 0x0f3c /* PCI */ +#define R128_INTERRUPT_PIN 0x0f3d /* PCI */ +#define R128_IO_BASE 0x0f14 /* PCI */ + +#define R128_LATENCY 0x0f0d /* PCI */ +#define R128_LEAD_BRES_DEC 0x1608 +#define R128_LEAD_BRES_ERR 0x1600 +#define R128_LEAD_BRES_INC 0x1604 +#define R128_LEAD_BRES_LNTH 0x161c +#define R128_LEAD_BRES_LNTH_SUB 0x1624 +#define R128_LVDS_GEN_CNTL 0x02d0 +# define R128_LVDS_ON (1 << 0) +# define R128_LVDS_BLON (1 << 19) +# define R128_LVDS_SEL_CRTC2 (1 << 23) +# define R128_HSYNC_DELAY_SHIFT 28 +# define R128_HSYNC_DELAY_MASK (0xf << 28) + +#define R128_MAX_LATENCY 0x0f3f /* PCI */ +#define R128_MCLK_CNTL 0x000f /* PLL */ +# define R128_FORCE_GCP (1 << 16) +# define R128_FORCE_PIPE3D_CP (1 << 17) +# define R128_FORCE_RCP (1 << 18) +#define R128_MDGPIO_A_REG 0x01ac +#define R128_MDGPIO_EN_REG 0x01b0 +#define R128_MDGPIO_MASK 0x0198 +#define R128_MDGPIO_Y_REG 0x01b4 +#define R128_MEM_ADDR_CONFIG 0x0148 +#define R128_MEM_BASE 0x0f10 /* PCI */ +#define R128_MEM_CNTL 0x0140 +#define R128_MEM_INIT_LAT_TIMER 0x0154 +#define R128_MEM_INTF_CNTL 0x014c +#define R128_MEM_SDRAM_MODE_REG 0x0158 +#define R128_MEM_STR_CNTL 0x0150 +#define R128_MEM_VGA_RP_SEL 0x003c +#define R128_MEM_VGA_WP_SEL 0x0038 +#define R128_MIN_GRANT 0x0f3e /* PCI */ +#define R128_MM_DATA 0x0004 +#define R128_MM_INDEX 0x0000 +#define R128_MPLL_CNTL 0x000e /* PLL */ +#define R128_MPP_TB_CONFIG 0x01c0 /* ? */ +#define R128_MPP_GP_CONFIG 0x01c8 /* ? */ + +#define R128_N_VIF_COUNT 0x0248 + +#define R128_OVR_CLR 0x0230 +#define R128_OVR_WID_LEFT_RIGHT 0x0234 +#define R128_OVR_WID_TOP_BOTTOM 0x0238 + +/* first overlay unit (there is only one) */ + +#define R128_OV0_Y_X_START 0x0400 +#define R128_OV0_Y_X_END 0x0404 +#define R128_OV0_EXCLUSIVE_HORZ 0x0408 +# define R128_EXCL_HORZ_START_MASK 0x000000ff +# define R128_EXCL_HORZ_END_MASK 0x0000ff00 +# define R128_EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 +# define R128_EXCL_HORZ_EXCLUSIVE_EN 0x80000000 +#define R128_OV0_EXCLUSIVE_VERT 0x040C +# define R128_EXCL_VERT_START_MASK 0x000003ff +# define R128_EXCL_VERT_END_MASK 0x03ff0000 +#define R128_OV0_REG_LOAD_CNTL 0x0410 +# define R128_REG_LD_CTL_LOCK 0x00000001L +# define R128_REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L +# define R128_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L +# define R128_REG_LD_CTL_LOCK_READBACK 0x00000008L +#define R128_OV0_SCALE_CNTL 0x0420 +# define R128_SCALER_PIX_EXPAND 0x00000001L +# define R128_SCALER_Y2R_TEMP 0x00000002L +# define R128_SCALER_HORZ_PICK_NEAREST 0x00000003L +# define R128_SCALER_VERT_PICK_NEAREST 0x00000004L +# define R128_SCALER_SIGNED_UV 0x00000010L +# define R128_SCALER_GAMMA_SEL_MASK 0x00000060L +# define R128_SCALER_GAMMA_SEL_BRIGHT 0x00000000L +# define R128_SCALER_GAMMA_SEL_G22 0x00000020L +# define R128_SCALER_GAMMA_SEL_G18 0x00000040L +# define R128_SCALER_GAMMA_SEL_G14 0x00000060L +# define R128_SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L +# define R128_SCALER_SURFAC_FORMAT 0x00000f00L +# define R128_SCALER_SOURCE_15BPP 0x00000300L +# define R128_SCALER_SOURCE_16BPP 0x00000400L +# define R128_SCALER_SOURCE_32BPP 0x00000600L +# define R128_SCALER_SOURCE_YUV9 0x00000900L +# define R128_SCALER_SOURCE_YUV12 0x00000A00L +# define R128_SCALER_SOURCE_VYUY422 0x00000B00L +# define R128_SCALER_SOURCE_YVYU422 0x00000C00L +# define R128_SCALER_SMART_SWITCH 0x00008000L +# define R128_SCALER_BURST_PER_PLANE 0x00ff0000L +# define R128_SCALER_DOUBLE_BUFFER 0x01000000L +# define R128_SCALER_DIS_LIMIT 0x08000000L +# define R128_SCALER_PRG_LOAD_START 0x10000000L +# define R128_SCALER_INT_EMU 0x20000000L +# define R128_SCALER_ENABLE 0x40000000L +# define R128_SCALER_SOFT_RESET 0x80000000L +#define R128_OV0_V_INC 0x0424 +#define R128_OV0_P1_V_ACCUM_INIT 0x0428 +# define R128_OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L +# define R128_OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L +#define R128_OV0_P23_V_ACCUM_INIT 0x042C +#define R128_OV0_P1_BLANK_LINES_AT_TOP 0x0430 +# define R128_P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL +# define R128_P1_ACTIVE_LINES_M1 0x0fff0000L +#define R128_OV0_P23_BLANK_LINES_AT_TOP 0x0434 +# define R128_P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ffL +# define R128_P23_ACTIVE_LINES_M1 0x07ff0000L +#define R128_OV0_VID_BUF0_BASE_ADRS 0x0440 +# define R128_VIF_BUF0_PITCH_SEL 0x00000001L +# define R128_VIF_BUF0_TILE_ADRS 0x00000002L +# define R128_VIF_BUF0_BASE_ADRS_MASK 0x03fffff0L +# define R128_VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000L +#define R128_OV0_VID_BUF1_BASE_ADRS 0x0444 +# define R128_VIF_BUF1_PITCH_SEL 0x00000001L +# define R128_VIF_BUF1_TILE_ADRS 0x00000002L +# define R128_VIF_BUF1_BASE_ADRS_MASK 0x03fffff0L +# define R128_VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000L +#define R128_OV0_VID_BUF2_BASE_ADRS 0x0448 +# define R128_VIF_BUF2_PITCH_SEL 0x00000001L +# define R128_VIF_BUF2_TILE_ADRS 0x00000002L +# define R128_VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L +# define R128_VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L +#define R128_OV0_VID_BUF3_BASE_ADRS 0x044C +#define R128_OV0_VID_BUF4_BASE_ADRS 0x0450 +#define R128_OV0_VID_BUF5_BASE_ADRS 0x0454 +#define R128_OV0_VID_BUF_PITCH0_VALUE 0x0460 +#define R128_OV0_VID_BUF_PITCH1_VALUE 0x0464 +#define R128_OV0_AUTO_FLIP_CNTL 0x0470 +#define R128_OV0_DEINTERLACE_PATTERN 0x0474 +#define R128_OV0_H_INC 0x0480 +#define R128_OV0_STEP_BY 0x0484 +#define R128_OV0_P1_H_ACCUM_INIT 0x0488 +#define R128_OV0_P23_H_ACCUM_INIT 0x048C +#define R128_OV0_P1_X_START_END 0x0494 +#define R128_OV0_P2_X_START_END 0x0498 +#define R128_OV0_P3_X_START_END 0x049C +#define R128_OV0_FILTER_CNTL 0x04A0 +#define R128_OV0_FOUR_TAP_COEF_0 0x04B0 +#define R128_OV0_FOUR_TAP_COEF_1 0x04B4 +#define R128_OV0_FOUR_TAP_COEF_2 0x04B8 +#define R128_OV0_FOUR_TAP_COEF_3 0x04BC +#define R128_OV0_FOUR_TAP_COEF_4 0x04C0 +#define R128_OV0_COLOUR_CNTL 0x04E0 +#define R128_OV0_VIDEO_KEY_CLR 0x04E4 +#define R128_OV0_VIDEO_KEY_MSK 0x04E8 +#define R128_OV0_GRAPHICS_KEY_CLR 0x04EC +#define R128_OV0_GRAPHICS_KEY_MSK 0x04F0 +#define R128_OV0_KEY_CNTL 0x04F4 +# define R128_VIDEO_KEY_FN_MASK 0x00000007L +# define R128_VIDEO_KEY_FN_FALSE 0x00000000L +# define R128_VIDEO_KEY_FN_TRUE 0x00000001L +# define R128_VIDEO_KEY_FN_EQ 0x00000004L +# define R128_VIDEO_KEY_FN_NE 0x00000005L +# define R128_GRAPHIC_KEY_FN_MASK 0x00000070L +# define R128_GRAPHIC_KEY_FN_FALSE 0x00000000L +# define R128_GRAPHIC_KEY_FN_TRUE 0x00000010L +# define R128_GRAPHIC_KEY_FN_EQ 0x00000040L +# define R128_GRAPHIC_KEY_FN_NE 0x00000050L +# define R128_CMP_MIX_MASK 0x00000100L +# define R128_CMP_MIX_OR 0x00000000L +# define R128_CMP_MIX_AND 0x00000100L +#define R128_OV0_TEST 0x04F8 + + +#define R128_PALETTE_DATA 0x00b4 +#define R128_PALETTE_INDEX 0x00b0 +#define R128_PC_DEBUG_MODE 0x1760 +#define R128_PC_GUI_CTLSTAT 0x1748 +#define R128_PC_GUI_MODE 0x1744 +# define R128_PC_IGNORE_UNIFY (1 << 5) +#define R128_PC_MISC_CNTL 0x0188 +#define R128_PC_NGUI_CTLSTAT 0x0184 +# define R128_PC_FLUSH_GUI (3 << 0) +# define R128_PC_RI_GUI (1 << 2) +# define R128_PC_FLUSH_ALL 0x00ff +# define R128_PC_BUSY (1 << 31) +#define R128_PC_NGUI_MODE 0x0180 +#define R128_PCI_GART_PAGE 0x017c +#define R128_PLANE_3D_MASK_C 0x1d44 +#define R128_PLL_TEST_CNTL 0x0013 /* PLL */ +#define R128_PMI_CAP_ID 0x0f5c /* PCI */ +#define R128_PMI_DATA 0x0f63 /* PCI */ +#define R128_PMI_NXT_CAP_PTR 0x0f5d /* PCI */ +#define R128_PMI_PMC_REG 0x0f5e /* PCI */ +#define R128_PMI_PMCSR_REG 0x0f60 /* PCI */ +#define R128_PMI_REGISTER 0x0f5c /* PCI */ +#define R128_PPLL_CNTL 0x0002 /* PLL */ +# define R128_PPLL_RESET (1 << 0) +# define R128_PPLL_SLEEP (1 << 1) +# define R128_PPLL_ATOMIC_UPDATE_EN (1 << 16) +# define R128_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +#define R128_PPLL_DIV_0 0x0004 /* PLL */ +#define R128_PPLL_DIV_1 0x0005 /* PLL */ +#define R128_PPLL_DIV_2 0x0006 /* PLL */ +#define R128_PPLL_DIV_3 0x0007 /* PLL */ +# define R128_PPLL_FB3_DIV_MASK 0x07ff +# define R128_PPLL_POST3_DIV_MASK 0x00070000 +#define R128_PPLL_REF_DIV 0x0003 /* PLL */ +# define R128_PPLL_REF_DIV_MASK 0x03ff +# define R128_PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ +# define R128_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +#define R128_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ +#define R128_REG_BASE 0x0f18 /* PCI */ +#define R128_REGPROG_INF 0x0f09 /* PCI */ +#define R128_REVISION_ID 0x0f08 /* PCI */ + +#define R128_SC_BOTTOM 0x164c +#define R128_SC_BOTTOM_RIGHT 0x16f0 +#define R128_SC_BOTTOM_RIGHT_C 0x1c8c +#define R128_SC_LEFT 0x1640 +#define R128_SC_RIGHT 0x1644 +#define R128_SC_TOP 0x1648 +#define R128_SC_TOP_LEFT 0x16ec +#define R128_SC_TOP_LEFT_C 0x1c88 +#define R128_SEQ8_DATA 0x03c5 /* VGA */ +#define R128_SEQ8_IDX 0x03c4 /* VGA */ +#define R128_SNAPSHOT_F_COUNT 0x0244 +#define R128_SNAPSHOT_VH_COUNTS 0x0240 +#define R128_SNAPSHOT_VIF_COUNT 0x024c +#define R128_SRC_OFFSET 0x15ac +#define R128_SRC_PITCH 0x15b0 +#define R128_SRC_PITCH_OFFSET 0x1428 +#define R128_SRC_SC_BOTTOM 0x165c +#define R128_SRC_SC_BOTTOM_RIGHT 0x16f4 +#define R128_SRC_SC_RIGHT 0x1654 +#define R128_SRC_X 0x1414 +#define R128_SRC_X_Y 0x1590 +#define R128_SRC_Y 0x1418 +#define R128_SRC_Y_X 0x1434 +#define R128_STATUS 0x0f06 /* PCI */ +#define R128_SUBPIC_CNTL 0x0540 /* ? */ +#define R128_SUB_CLASS 0x0f0a /* PCI */ +#define R128_SURFACE_DELAY 0x0b00 +#define R128_SURFACE0_INFO 0x0b0c +#define R128_SURFACE0_LOWER_BOUND 0x0b04 +#define R128_SURFACE0_UPPER_BOUND 0x0b08 +#define R128_SURFACE1_INFO 0x0b1c +#define R128_SURFACE1_LOWER_BOUND 0x0b14 +#define R128_SURFACE1_UPPER_BOUND 0x0b18 +#define R128_SURFACE2_INFO 0x0b2c +#define R128_SURFACE2_LOWER_BOUND 0x0b24 +#define R128_SURFACE2_UPPER_BOUND 0x0b28 +#define R128_SURFACE3_INFO 0x0b3c +#define R128_SURFACE3_LOWER_BOUND 0x0b34 +#define R128_SURFACE3_UPPER_BOUND 0x0b38 +#define R128_SW_SEMAPHORE 0x013c + +#define R128_TEST_DEBUG_CNTL 0x0120 +#define R128_TEST_DEBUG_MUX 0x0124 +#define R128_TEST_DEBUG_OUT 0x012c +#define R128_TMDS_CRC 0x02a0 +#define R128_TRAIL_BRES_DEC 0x1614 +#define R128_TRAIL_BRES_ERR 0x160c +#define R128_TRAIL_BRES_INC 0x1610 +#define R128_TRAIL_X 0x1618 +#define R128_TRAIL_X_SUB 0x1620 + +#define R128_VCLK_ECP_CNTL 0x0008 /* PLL */ +#define R128_VENDOR_ID 0x0f00 /* PCI */ +#define R128_VGA_DDA_CONFIG 0x02e8 +#define R128_VGA_DDA_ON_OFF 0x02ec +#define R128_VID_BUFFER_CONTROL 0x0900 +#define R128_VIDEOMUX_CNTL 0x0190 +#define R128_VIPH_CONTROL 0x01D0 /* ? */ + +#define R128_WAIT_UNTIL 0x1720 + +#define R128_X_MPLL_REF_FB_DIV 0x000a /* PLL */ +#define R128_XCLK_CNTL 0x000d /* PLL */ +#define R128_XDLL_CNTL 0x000c /* PLL */ +#define R128_XPLL_CNTL 0x000b /* PLL */ + + /* Registers for CCE and Microcode Engine */ +#define R128_PM4_MICROCODE_ADDR 0x07d4 +#define R128_PM4_MICROCODE_RADDR 0x07d8 +#define R128_PM4_MICROCODE_DATAH 0x07dc +#define R128_PM4_MICROCODE_DATAL 0x07e0 + +#define R128_PM4_BUFFER_OFFSET 0x0700 +#define R128_PM4_BUFFER_CNTL 0x0704 +# define R128_PM4_NONPM4 (0 << 28) +# define R128_PM4_192PIO (1 << 28) +# define R128_PM4_192BM (2 << 28) +# define R128_PM4_128PIO_64INDBM (3 << 28) +# define R128_PM4_128BM_64INDBM (4 << 28) +# define R128_PM4_64PIO_128INDBM (5 << 28) +# define R128_PM4_64BM_128INDBM (6 << 28) +# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28) +# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28) +# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28) +#define R128_PM4_BUFFER_WM_CNTL 0x0708 +# define R128_WMA_SHIFT 0 +# define R128_WMB_SHIFT 8 +# define R128_WMC_SHIFT 16 +# define R128_WB_WM_SHIFT 24 +#define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c +#define R128_PM4_BUFFER_DL_RPTR 0x0710 +#define R128_PM4_BUFFER_DL_WPTR 0x0714 +# define R128_PM4_BUFFER_DL_DONE (1 << 31) +#define R128_PM4_BUFFER_DL_WPTR_DELAY 0x0718 +# define R128_PRE_WRITE_TIMER_SHIFT 0 +# define R128_PRE_WRITE_LIMIT_SHIFT 23 +#define R128_PM4_VC_FPU_SETUP 0x071c +# define R128_FRONT_DIR_CW (0 << 0) +# define R128_FRONT_DIR_CCW (1 << 0) +# define R128_FRONT_DIR_MASK (1 << 0) +# define R128_BACKFACE_CULL (0 << 1) +# define R128_BACKFACE_POINTS (1 << 1) +# define R128_BACKFACE_LINES (2 << 1) +# define R128_BACKFACE_SOLID (3 << 1) +# define R128_BACKFACE_MASK (3 << 1) +# define R128_FRONTFACE_CULL (0 << 3) +# define R128_FRONTFACE_POINTS (1 << 3) +# define R128_FRONTFACE_LINES (2 << 3) +# define R128_FRONTFACE_SOLID (3 << 3) +# define R128_FRONTFACE_MASK (3 << 3) +# define R128_FPU_COLOR_SOLID (0 << 5) +# define R128_FPU_COLOR_FLAT (1 << 5) +# define R128_FPU_COLOR_GOURAUD (2 << 5) +# define R128_FPU_COLOR_GOURAUD2 (3 << 5) +# define R128_FPU_COLOR_MASK (3 << 5) +# define R128_FPU_SUB_PIX_2BITS (0 << 7) +# define R128_FPU_SUB_PIX_4BITS (1 << 7) +# define R128_FPU_MODE_2D (0 << 8) +# define R128_FPU_MODE_3D (1 << 8) +# define R128_TRAP_BITS_DISABLE (1 << 9) +# define R128_EDGE_ANTIALIAS (1 << 10) +# define R128_SUPERSAMPLE (1 << 11) +# define R128_XFACTOR_2 (0 << 12) +# define R128_XFACTOR_4 (1 << 12) +# define R128_YFACTOR_2 (0 << 13) +# define R128_YFACTOR_4 (1 << 13) +# define R128_FLAT_SHADE_VERTEX_D3D (0 << 14) +# define R128_FLAT_SHADE_VERTEX_OGL (1 << 14) +# define R128_FPU_ROUND_TRUNCATE (0 << 15) +# define R128_FPU_ROUND_NEAREST (1 << 15) +# define R128_WM_SEL_8DW (0 << 16) +# define R128_WM_SEL_16DW (1 << 16) +# define R128_WM_SEL_32DW (2 << 16) +#define R128_PM4_VC_DEBUG_CONFIG 0x07a4 +#define R128_PM4_VC_STAT 0x07a8 +#define R128_PM4_VC_TIMESTAMP0 0x07b0 +#define R128_PM4_VC_TIMESTAMP1 0x07b4 +#define R128_PM4_STAT 0x07b8 +# define R128_PM4_FIFOCNT_MASK 0x0fff +# define R128_PM4_BUSY (1 << 16) +# define R128_PM4_GUI_ACTIVE (1 << 31) +#define R128_PM4_BUFFER_ADDR 0x07f0 +#define R128_PM4_MICRO_CNTL 0x07fc +# define R128_PM4_MICRO_FREERUN (1 << 30) +#define R128_PM4_FIFO_DATA_EVEN 0x1000 +#define R128_PM4_FIFO_DATA_ODD 0x1004 + +#define R128_SCALE_3D_CNTL 0x1a00 +# define R128_SCALE_DITHER_ERR_DIFF (0 << 1) +# define R128_SCALE_DITHER_TABLE (1 << 1) +# define R128_TEX_CACHE_SIZE_FULL (0 << 2) +# define R128_TEX_CACHE_SIZE_HALF (1 << 2) +# define R128_DITHER_INIT_CURR (0 << 3) +# define R128_DITHER_INIT_RESET (1 << 3) +# define R128_ROUND_24BIT (1 << 4) +# define R128_TEX_CACHE_DISABLE (1 << 5) +# define R128_SCALE_3D_NOOP (0 << 6) +# define R128_SCALE_3D_SCALE (1 << 6) +# define R128_SCALE_3D_TEXMAP_SHADE (2 << 6) +# define R128_SCALE_PIX_BLEND (0 << 8) +# define R128_SCALE_PIX_REPLICATE (1 << 8) +# define R128_TEX_CACHE_SPLIT (1 << 9) +# define R128_APPLE_YUV_MODE (1 << 10) +# define R128_TEX_CACHE_PALLETE_MODE (1 << 11) +# define R128_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define R128_ALPHA_COMB_ADD_NCLAMP (1 << 12) +# define R128_ALPHA_COMB_SUB_DST_SRC_CLAMP (2 << 12) +# define R128_ALPHA_COMB_SUB_DST_SRC_NCLAMP (3 << 12) +# define R128_FOG_TABLE (1 << 14) +# define R128_SIGNED_DST_CLAMP (1 << 15) +# define R128_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define R128_ALPHA_BLEND_SRC_ONE (1 << 16) +# define R128_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define R128_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define R128_ALPHA_BLEND_SRC_DSTALPHA (6 << 16) +# define R128_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16) +# define R128_ALPHA_BLEND_SRC_DSTCOLOR (8 << 16) +# define R128_ALPHA_BLEND_SRC_INVDSTCOLOR (9 << 16) +# define R128_ALPHA_BLEND_SRC_SAT (10 << 16) +# define R128_ALPHA_BLEND_SRC_BLEND (11 << 16) +# define R128_ALPHA_BLEND_SRC_INVBLEND (12 << 16) +# define R128_ALPHA_BLEND_DST_ZERO (0 << 20) +# define R128_ALPHA_BLEND_DST_ONE (1 << 20) +# define R128_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define R128_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define R128_ALPHA_BLEND_DST_DSTALPHA (6 << 20) +# define R128_ALPHA_BLEND_DST_INVDSTALPHA (7 << 20) +# define R128_ALPHA_BLEND_DST_DSTCOLOR (8 << 20) +# define R128_ALPHA_BLEND_DST_INVDSTCOLOR (9 << 20) +# define R128_ALPHA_TEST_NEVER (0 << 24) +# define R128_ALPHA_TEST_LESS (1 << 24) +# define R128_ALPHA_TEST_LESSEQUAL (2 << 24) +# define R128_ALPHA_TEST_EQUAL (3 << 24) +# define R128_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define R128_ALPHA_TEST_GREATER (5 << 24) +# define R128_ALPHA_TEST_NEQUAL (6 << 24) +# define R128_ALPHA_TEST_ALWAYS (7 << 24) +# define R128_COMPOSITE_SHADOW_CMP_EQUAL (0 << 28) +# define R128_COMPOSITE_SHADOW_CMP_NEQUAL (1 << 28) +# define R128_COMPOSITE_SHADOW (1 << 29) +# define R128_TEX_MAP_ALPHA_IN_TEXTURE (1 << 30) +# define R128_TEX_CACHE_LINE_SIZE_8QW (0 << 31) +# define R128_TEX_CACHE_LINE_SIZE_4QW (1 << 31) +#define R128_SCALE_3D_DATATYPE 0x1a20 + +#define R128_SETUP_CNTL 0x1bc4 +# define R128_DONT_START_TRIANGLE (1 << 0) +# define R128_Z_BIAS (0 << 1) +# define R128_DONT_START_ANY_ON (1 << 2) +# define R128_COLOR_SOLID_COLOR (0 << 3) +# define R128_COLOR_FLAT_VERT_1 (1 << 3) +# define R128_COLOR_FLAT_VERT_2 (2 << 3) +# define R128_COLOR_FLAT_VERT_3 (3 << 3) +# define R128_COLOR_GOURAUD (4 << 3) +# define R128_PRIM_TYPE_TRI (0 << 7) +# define R128_PRIM_TYPE_LINE (1 << 7) +# define R128_PRIM_TYPE_POINT (2 << 7) +# define R128_PRIM_TYPE_POLY_EDGE (3 << 7) +# define R128_TEXTURE_ST_MULT_W (0 << 9) +# define R128_TEXTURE_ST_DIRECT (1 << 9) +# define R128_STARTING_VERTEX_1 (1 << 14) +# define R128_STARTING_VERTEX_2 (2 << 14) +# define R128_STARTING_VERTEX_3 (3 << 14) +# define R128_ENDING_VERTEX_1 (1 << 16) +# define R128_ENDING_VERTEX_2 (2 << 16) +# define R128_ENDING_VERTEX_3 (3 << 16) +# define R128_SU_POLY_LINE_LAST (0 << 18) +# define R128_SU_POLY_LINE_NOT_LAST (1 << 18) +# define R128_SUB_PIX_2BITS (0 << 19) +# define R128_SUB_PIX_4BITS (1 << 19) +# define R128_SET_UP_CONTINUE (1 << 31) + +#define R128_WINDOW_XY_OFFSET 0x1bcc +# define R128_WINDOW_Y_SHIFT 4 +# define R128_WINDOW_X_SHIFT 20 + +#define R128_Z_OFFSET_C 0x1c90 +#define R128_Z_PITCH_C 0x1c94 +#define R128_Z_STEN_CNTL_C 0x1c98 +# define R128_Z_PIX_WIDTH_16 (0 << 1) +# define R128_Z_PIX_WIDTH_24 (1 << 1) +# define R128_Z_PIX_WIDTH_32 (2 << 1) +# define R128_Z_PIX_WIDTH_MASK (3 << 1) +# define R128_Z_TEST_NEVER (0 << 4) +# define R128_Z_TEST_LESS (1 << 4) +# define R128_Z_TEST_LESSEQUAL (2 << 4) +# define R128_Z_TEST_EQUAL (3 << 4) +# define R128_Z_TEST_GREATEREQUAL (4 << 4) +# define R128_Z_TEST_GREATER (5 << 4) +# define R128_Z_TEST_NEQUAL (6 << 4) +# define R128_Z_TEST_ALWAYS (7 << 4) +# define R128_Z_TEST_MASK (7 << 4) +# define R128_STENCIL_TEST_NEVER (0 << 12) +# define R128_STENCIL_TEST_LESS (1 << 12) +# define R128_STENCIL_TEST_LESSEQUAL (2 << 12) +# define R128_STENCIL_TEST_EQUAL (3 << 12) +# define R128_STENCIL_TEST_GREATEREQUAL (4 << 12) +# define R128_STENCIL_TEST_GREATER (5 << 12) +# define R128_STENCIL_TEST_NEQUAL (6 << 12) +# define R128_STENCIL_TEST_ALWAYS (7 << 12) +# define R128_STENCIL_S_FAIL_KEEP (0 << 16) +# define R128_STENCIL_S_FAIL_ZERO (1 << 16) +# define R128_STENCIL_S_FAIL_REPLACE (2 << 16) +# define R128_STENCIL_S_FAIL_INC (3 << 16) +# define R128_STENCIL_S_FAIL_DEC (4 << 16) +# define R128_STENCIL_S_FAIL_INV (5 << 16) +# define R128_STENCIL_ZPASS_KEEP (0 << 20) +# define R128_STENCIL_ZPASS_ZERO (1 << 20) +# define R128_STENCIL_ZPASS_REPLACE (2 << 20) +# define R128_STENCIL_ZPASS_INC (3 << 20) +# define R128_STENCIL_ZPASS_DEC (4 << 20) +# define R128_STENCIL_ZPASS_INV (5 << 20) +# define R128_STENCIL_ZFAIL_KEEP (0 << 24) +# define R128_STENCIL_ZFAIL_ZERO (1 << 24) +# define R128_STENCIL_ZFAIL_REPLACE (2 << 24) +# define R128_STENCIL_ZFAIL_INC (3 << 24) +# define R128_STENCIL_ZFAIL_DEC (4 << 24) +# define R128_STENCIL_ZFAIL_INV (5 << 24) +#define R128_TEX_CNTL_C 0x1c9c +# define R128_Z_ENABLE (1 << 0) +# define R128_Z_WRITE_ENABLE (1 << 1) +# define R128_STENCIL_ENABLE (1 << 3) +# define R128_SHADE_ENABLE (0 << 4) +# define R128_TEXMAP_ENABLE (1 << 4) +# define R128_SEC_TEXMAP_ENABLE (1 << 5) +# define R128_FOG_ENABLE (1 << 7) +# define R128_DITHER_ENABLE (1 << 8) +# define R128_ALPHA_ENABLE (1 << 9) +# define R128_ALPHA_TEST_ENABLE (1 << 10) +# define R128_SPEC_LIGHT_ENABLE (1 << 11) +# define R128_TEX_CHROMA_KEY_ENABLE (1 << 12) +# define R128_ALPHA_IN_TEX_COMPLETE_A (0 << 13) +# define R128_ALPHA_IN_TEX_LSB_A (1 << 13) +# define R128_LIGHT_DIS (0 << 14) +# define R128_LIGHT_COPY (1 << 14) +# define R128_LIGHT_MODULATE (2 << 14) +# define R128_LIGHT_ADD (3 << 14) +# define R128_LIGHT_BLEND_CONSTANT (4 << 14) +# define R128_LIGHT_BLEND_TEXTURE (5 << 14) +# define R128_LIGHT_BLEND_VERTEX (6 << 14) +# define R128_LIGHT_BLEND_CONST_COLOR (7 << 14) +# define R128_ALPHA_LIGHT_DIS (0 << 18) +# define R128_ALPHA_LIGHT_COPY (1 << 18) +# define R128_ALPHA_LIGHT_MODULATE (2 << 18) +# define R128_ALPHA_LIGHT_ADD (3 << 18) +# define R128_ANTI_ALIAS (1 << 21) +# define R128_TEX_CACHE_FLUSH (1 << 23) +# define R128_LOD_BIAS_SHIFT 24 +#define R128_MISC_3D_STATE_CNTL_REG 0x1ca0 +# define R128_REF_ALPHA_MASK 0xff +# define R128_MISC_SCALE_3D_NOOP (0 << 8) +# define R128_MISC_SCALE_3D_SCALE (1 << 8) +# define R128_MISC_SCALE_3D_TEXMAP_SHADE (2 << 8) +# define R128_MISC_SCALE_PIX_BLEND (0 << 10) +# define R128_MISC_SCALE_PIX_REPLICATE (1 << 10) +# define R128_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define R128_ALPHA_COMB_ADD_NO_CLAMP (1 << 12) +# define R128_ALPHA_COMB_SUB_SRC_DST_CLAMP (2 << 12) +# define R128_ALPHA_COMB_SUB_SRC_DST_NO_CLAMP (3 << 12) +# define R128_FOG_VERTEX (0 << 14) +# define R128_FOG_TABLE (1 << 14) +# define R128_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define R128_ALPHA_BLEND_SRC_ONE (1 << 16) +# define R128_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define R128_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define R128_ALPHA_BLEND_SRC_DESTALPHA (6 << 16) +# define R128_ALPHA_BLEND_SRC_INVDESTALPHA (7 << 16) +# define R128_ALPHA_BLEND_SRC_DESTCOLOR (8 << 16) +# define R128_ALPHA_BLEND_SRC_INVDESTCOLOR (9 << 16) +# define R128_ALPHA_BLEND_SRC_SRCALPHASAT (10 << 16) +# define R128_ALPHA_BLEND_SRC_BOTHSRCALPHA (11 << 16) +# define R128_ALPHA_BLEND_SRC_BOTHINVSRCALPHA (12 << 16) +# define R128_ALPHA_BLEND_SRC_MASK (15 << 16) +# define R128_ALPHA_BLEND_DST_ZERO (0 << 20) +# define R128_ALPHA_BLEND_DST_ONE (1 << 20) +# define R128_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define R128_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define R128_ALPHA_BLEND_DST_DESTALPHA (6 << 20) +# define R128_ALPHA_BLEND_DST_INVDESTALPHA (7 << 20) +# define R128_ALPHA_BLEND_DST_DESTCOLOR (8 << 20) +# define R128_ALPHA_BLEND_DST_INVDESTCOLOR (9 << 20) +# define R128_ALPHA_BLEND_DST_SRCALPHASAT (10 << 20) +# define R128_ALPHA_BLEND_DST_MASK (15 << 20) +# define R128_ALPHA_TEST_NEVER (0 << 24) +# define R128_ALPHA_TEST_LESS (1 << 24) +# define R128_ALPHA_TEST_LESSEQUAL (2 << 24) +# define R128_ALPHA_TEST_EQUAL (3 << 24) +# define R128_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define R128_ALPHA_TEST_GREATER (5 << 24) +# define R128_ALPHA_TEST_NEQUAL (6 << 24) +# define R128_ALPHA_TEST_ALWAYS (7 << 24) +# define R128_ALPHA_TEST_MASK (7 << 24) +#define R128_TEXTURE_CLR_CMP_CLR_C 0x1ca4 +#define R128_TEXTURE_CLR_CMP_MSK_C 0x1ca8 +#define R128_FOG_COLOR_C 0x1cac +# define R128_FOG_BLUE_SHIFT 0 +# define R128_FOG_GREEN_SHIFT 8 +# define R128_FOG_RED_SHIFT 16 +#define R128_PRIM_TEX_CNTL_C 0x1cb0 +# define R128_MIN_BLEND_NEAREST (0 << 1) +# define R128_MIN_BLEND_LINEAR (1 << 1) +# define R128_MIN_BLEND_MIPNEAREST (2 << 1) +# define R128_MIN_BLEND_MIPLINEAR (3 << 1) +# define R128_MIN_BLEND_LINEARMIPNEAREST (4 << 1) +# define R128_MIN_BLEND_LINEARMIPLINEAR (5 << 1) +# define R128_MIN_BLEND_MASK (7 << 1) +# define R128_MAG_BLEND_NEAREST (0 << 4) +# define R128_MAG_BLEND_LINEAR (1 << 4) +# define R128_MAG_BLEND_MASK (7 << 4) +# define R128_MIP_MAP_DISABLE (1 << 7) +# define R128_TEX_CLAMP_S_WRAP (0 << 8) +# define R128_TEX_CLAMP_S_MIRROR (1 << 8) +# define R128_TEX_CLAMP_S_CLAMP (2 << 8) +# define R128_TEX_CLAMP_S_BORDER_COLOR (3 << 8) +# define R128_TEX_CLAMP_S_MASK (3 << 8) +# define R128_TEX_WRAP_S (1 << 10) +# define R128_TEX_CLAMP_T_WRAP (0 << 11) +# define R128_TEX_CLAMP_T_MIRROR (1 << 11) +# define R128_TEX_CLAMP_T_CLAMP (2 << 11) +# define R128_TEX_CLAMP_T_BORDER_COLOR (3 << 11) +# define R128_TEX_CLAMP_T_MASK (3 << 11) +# define R128_TEX_WRAP_T (1 << 13) +# define R128_TEX_PERSPECTIVE_DISABLE (1 << 14) +# define R128_DATATYPE_VQ (0 << 16) +# define R128_DATATYPE_CI4 (1 << 16) +# define R128_DATATYPE_CI8 (2 << 16) +# define R128_DATATYPE_ARGB1555 (3 << 16) +# define R128_DATATYPE_RGB565 (4 << 16) +# define R128_DATATYPE_RGB888 (5 << 16) +# define R128_DATATYPE_ARGB8888 (6 << 16) +# define R128_DATATYPE_RGB332 (7 << 16) +# define R128_DATATYPE_Y8 (8 << 16) +# define R128_DATATYPE_RGB8 (9 << 16) +# define R128_DATATYPE_CI16 (10 << 16) +# define R128_DATATYPE_YUV422 (11 << 16) +# define R128_DATATYPE_YUV422_2 (12 << 16) +# define R128_DATATYPE_AYUV444 (14 << 16) +# define R128_DATATYPE_ARGB4444 (15 << 16) +# define R128_PALLETE_EITHER (0 << 20) +# define R128_PALLETE_1 (1 << 20) +# define R128_PALLETE_2 (2 << 20) +# define R128_PSEUDOCOLOR_DT_RGB565 (0 << 24) +# define R128_PSEUDOCOLOR_DT_ARGB1555 (1 << 24) +# define R128_PSEUDOCOLOR_DT_ARGB4444 (2 << 24) +#define R128_PRIM_TEXTURE_COMBINE_CNTL_C 0x1cb4 +# define R128_COMB_DIS (0 << 0) +# define R128_COMB_COPY (1 << 0) +# define R128_COMB_COPY_INP (2 << 0) +# define R128_COMB_MODULATE (3 << 0) +# define R128_COMB_MODULATE2X (4 << 0) +# define R128_COMB_MODULATE4X (5 << 0) +# define R128_COMB_ADD (6 << 0) +# define R128_COMB_ADD_SIGNED (7 << 0) +# define R128_COMB_BLEND_VERTEX (8 << 0) +# define R128_COMB_BLEND_TEXTURE (9 << 0) +# define R128_COMB_BLEND_CONST (10 << 0) +# define R128_COMB_BLEND_PREMULT (11 << 0) +# define R128_COMB_BLEND_PREV (12 << 0) +# define R128_COMB_BLEND_PREMULT_INV (13 << 0) +# define R128_COMB_ADD_SIGNED2X (14 << 0) +# define R128_COMB_BLEND_CONST_COLOR (15 << 0) +# define R128_COMB_MASK (15 << 0) +# define R128_COLOR_FACTOR_TEX (4 << 4) +# define R128_COLOR_FACTOR_NTEX (5 << 4) +# define R128_COLOR_FACTOR_ALPHA (6 << 4) +# define R128_COLOR_FACTOR_NALPHA (7 << 4) +# define R128_COLOR_FACTOR_MASK (15 << 4) +# define R128_INPUT_FACTOR_CONST_COLOR (2 << 10) +# define R128_INPUT_FACTOR_CONST_ALPHA (3 << 10) +# define R128_INPUT_FACTOR_INT_COLOR (4 << 10) +# define R128_INPUT_FACTOR_INT_ALPHA (5 << 10) +# define R128_INPUT_FACTOR_MASK (15 << 10) +# define R128_COMB_ALPHA_DIS (0 << 14) +# define R128_COMB_ALPHA_COPY (1 << 14) +# define R128_COMB_ALPHA_COPY_INP (2 << 14) +# define R128_COMB_ALPHA_MODULATE (3 << 14) +# define R128_COMB_ALPHA_MODULATE2X (4 << 14) +# define R128_COMB_ALPHA_MODULATE4X (5 << 14) +# define R128_COMB_ALPHA_ADD (6 << 14) +# define R128_COMB_ALPHA_ADD_SIGNED (7 << 14) +# define R128_COMB_ALPHA_ADD_SIGNED2X (14 << 14) +# define R128_COMB_ALPHA_MASK (15 << 14) +# define R128_ALPHA_FACTOR_TEX_ALPHA (6 << 18) +# define R128_ALPHA_FACTOR_NTEX_ALPHA (7 << 18) +# define R128_ALPHA_FACTOR_MASK (15 << 18) +# define R128_INP_FACTOR_A_CONST_ALPHA (1 << 25) +# define R128_INP_FACTOR_A_INT_ALPHA (2 << 25) +# define R128_INP_FACTOR_A_MASK (7 << 25) +#define R128_TEX_SIZE_PITCH_C 0x1cb8 +# define R128_TEX_PITCH_SHIFT 0 +# define R128_TEX_SIZE_SHIFT 4 +# define R128_TEX_HEIGHT_SHIFT 8 +# define R128_TEX_MIN_SIZE_SHIFT 12 +# define R128_SEC_TEX_PITCH_SHIFT 16 +# define R128_SEC_TEX_SIZE_SHIFT 20 +# define R128_SEC_TEX_HEIGHT_SHIFT 24 +# define R128_SEC_TEX_MIN_SIZE_SHIFT 28 +# define R128_TEX_PITCH_MASK (0x0f << 0) +# define R128_TEX_SIZE_MASK (0x0f << 4) +# define R128_TEX_HEIGHT_MASK (0x0f << 8) +# define R128_TEX_MIN_SIZE_MASK (0x0f << 12) +# define R128_SEC_TEX_PITCH_MASK (0x0f << 16) +# define R128_SEC_TEX_SIZE_MASK (0x0f << 20) +# define R128_SEC_TEX_HEIGHT_MASK (0x0f << 24) +# define R128_SEC_TEX_MIN_SIZE_MASK (0x0f << 28) +# define R128_TEX_SIZE_PITCH_SHIFT 0 +# define R128_SEC_TEX_SIZE_PITCH_SHIFT 16 +# define R128_TEX_SIZE_PITCH_MASK (0xffff << 0) +# define R128_SEC_TEX_SIZE_PITCH_MASK (0xffff << 16) +#define R128_PRIM_TEX_0_OFFSET_C 0x1cbc +#define R128_PRIM_TEX_1_OFFSET_C 0x1cc0 +#define R128_PRIM_TEX_2_OFFSET_C 0x1cc4 +#define R128_PRIM_TEX_3_OFFSET_C 0x1cc8 +#define R128_PRIM_TEX_4_OFFSET_C 0x1ccc +#define R128_PRIM_TEX_5_OFFSET_C 0x1cd0 +#define R128_PRIM_TEX_6_OFFSET_C 0x1cd4 +#define R128_PRIM_TEX_7_OFFSET_C 0x1cd8 +#define R128_PRIM_TEX_8_OFFSET_C 0x1cdc +#define R128_PRIM_TEX_9_OFFSET_C 0x1ce0 +#define R128_PRIM_TEX_10_OFFSET_C 0x1ce4 +# define R128_TEX_NO_TILE (0 << 30) +# define R128_TEX_TILED_BY_HOST (1 << 30) +# define R128_TEX_TILED_BY_STORAGE (2 << 30) +# define R128_TEX_TILED_BY_STORAGE2 (3 << 30) + +#define R128_SEC_TEX_CNTL_C 0x1d00 +# define R128_SEC_SELECT_PRIM_ST (0 << 0) +# define R128_SEC_SELECT_SEC_ST (1 << 0) +#define R128_SEC_TEX_COMBINE_CNTL_C 0x1d04 +# define R128_INPUT_FACTOR_PREV_COLOR (8 << 10) +# define R128_INPUT_FACTOR_PREV_ALPHA (9 << 10) +# define R128_INP_FACTOR_A_PREV_ALPHA (4 << 25) +#define R128_SEC_TEX_0_OFFSET_C 0x1d08 +#define R128_SEC_TEX_1_OFFSET_C 0x1d0c +#define R128_SEC_TEX_2_OFFSET_C 0x1d10 +#define R128_SEC_TEX_3_OFFSET_C 0x1d14 +#define R128_SEC_TEX_4_OFFSET_C 0x1d18 +#define R128_SEC_TEX_5_OFFSET_C 0x1d1c +#define R128_SEC_TEX_6_OFFSET_C 0x1d20 +#define R128_SEC_TEX_7_OFFSET_C 0x1d24 +#define R128_SEC_TEX_8_OFFSET_C 0x1d28 +#define R128_SEC_TEX_9_OFFSET_C 0x1d2c +#define R128_SEC_TEX_10_OFFSET_C 0x1d30 +#define R128_CONSTANT_COLOR_C 0x1d34 +# define R128_CONSTANT_BLUE_SHIFT 0 +# define R128_CONSTANT_GREEN_SHIFT 8 +# define R128_CONSTANT_RED_SHIFT 16 +# define R128_CONSTANT_ALPHA_SHIFT 24 +#define R128_PRIM_TEXTURE_BORDER_COLOR_C 0x1d38 +# define R128_PRIM_TEX_BORDER_BLUE_SHIFT 0 +# define R128_PRIM_TEX_BORDER_GREEN_SHIFT 8 +# define R128_PRIM_TEX_BORDER_RED_SHIFT 16 +# define R128_PRIM_TEX_BORDER_ALPHA_SHIFT 24 +#define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c +# define R128_SEC_TEX_BORDER_BLUE_SHIFT 0 +# define R128_SEC_TEX_BORDER_GREEN_SHIFT 8 +# define R128_SEC_TEX_BORDER_RED_SHIFT 16 +# define R128_SEC_TEX_BORDER_ALPHA_SHIFT 24 +#define R128_STEN_REF_MASK_C 0x1d40 +# define R128_STEN_REFERENCE_SHIFT 0 +# define R128_STEN_MASK_SHIFT 16 +# define R128_STEN_WRITE_MASK_SHIFT 24 +#define R128_PLANE_3D_MASK_C 0x1d44 +#define R128_TEX_CACHE_STAT_COUNT 0x1974 + + + /* Constants */ +#define R128_AGP_TEX_OFFSET 0x02000000 + +#define R128_VB_AGE_REG R128_GUI_SCRATCH_REG0 +#define R128_SWAP_AGE_REG R128_GUI_SCRATCH_REG1 + + /* CCE packet types */ +#define R128_CCE_PACKET0 0x00000000 +#define R128_CCE_PACKET0_ONE_REG_WR 0x00008000 +#define R128_CCE_PACKET1 0x40000000 +#define R128_CCE_PACKET2 0x80000000 +#define R128_CCE_PACKET3_NOP 0xC0001000 +#define R128_CCE_PACKET3_PAINT 0xC0001100 +#define R128_CCE_PACKET3_BITBLT 0xC0001200 +#define R128_CCE_PACKET3_SMALLTEXT 0xC0001300 +#define R128_CCE_PACKET3_HOSTDATA_BLT 0xC0001400 +#define R128_CCE_PACKET3_POLYLINE 0xC0001500 +#define R128_CCE_PACKET3_SCALING 0xC0001600 +#define R128_CCE_PACKET3_TRANS_SCALING 0xC0001700 +#define R128_CCE_PACKET3_POLYSCANLINES 0xC0001800 +#define R128_CCE_PACKET3_NEXT_CHAR 0xC0001900 +#define R128_CCE_PACKET3_PAINT_MULTI 0xC0001A00 +#define R128_CCE_PACKET3_BITBLT_MULTI 0xC0001B00 +#define R128_CCE_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define R128_CCE_PACKET3_SET_SCISSORS 0xC0001E00 +#define R128_CCE_PACKET3_SET_MODE24BPP 0xC0001F00 +#define R128_CCE_PACKET3_CNTL_PAINT 0xC0009100 +#define R128_CCE_PACKET3_CNTL_BITBLT 0xC0009200 +#define R128_CCE_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define R128_CCE_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define R128_CCE_PACKET3_CNTL_POLYLINE 0xC0009500 +#define R128_CCE_PACKET3_CNTL_SCALING 0xC0009600 +#define R128_CCE_PACKET3_CNTL_TRANS_SCALING 0xC0009700 +#define R128_CCE_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define R128_CCE_PACKET3_CNTL_NEXT_CHAR 0xC0009900 +#define R128_CCE_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define R128_CCE_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define R128_CCE_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 +#define R128_CCE_PACKET3_3D_SAVE_CONTEXT 0xC0002000 +#define R128_CCE_PACKET3_3D_PLAY_CONTEXT 0xC0002100 +#define R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define R128_CCE_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 +#define R128_CCE_PACKET3_LOAD_PALETTE 0xC0002C00 +#define R128_CCE_PACKET3_PURGE 0xC0002D00 +#define R128_CCE_PACKET3_NEXT_VERTEX_BUNDLE 0xC0002E00 +# define R128_CCE_PACKET_MASK 0xC0000000 +# define R128_CCE_PACKET_COUNT_MASK 0x3fff0000 +# define R128_CCE_PACKET_MAX_DWORDS (1 << 14) +# define R128_CCE_PACKET0_REG_MASK 0x000007ff +# define R128_CCE_PACKET1_REG0_MASK 0x000007ff +# define R128_CCE_PACKET1_REG1_MASK 0x003ff800 + +#define R128_CCE_VC_FRMT_RHW 0x00000001 +#define R128_CCE_VC_FRMT_DIFFUSE_BGR 0x00000002 +#define R128_CCE_VC_FRMT_DIFFUSE_A 0x00000004 +#define R128_CCE_VC_FRMT_DIFFUSE_ARGB 0x00000008 +#define R128_CCE_VC_FRMT_SPEC_BGR 0x00000010 +#define R128_CCE_VC_FRMT_SPEC_F 0x00000020 +#define R128_CCE_VC_FRMT_SPEC_FRGB 0x00000040 +#define R128_CCE_VC_FRMT_S_T 0x00000080 +#define R128_CCE_VC_FRMT_S2_T2 0x00000100 +#define R128_CCE_VC_FRMT_RHW2 0x00000200 + +#define R128_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define R128_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define R128_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 +#define R128_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define R128_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define R128_CCE_VC_CNTL_NUM_SHIFT 16 + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h new file mode 100644 index 000000000..d9d8d00e6 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h @@ -0,0 +1,76 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h,v 1.1 2000/11/02 16:55:38 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <kevin@precisioninsight.com> + * + */ + +#ifndef _R128_SAREA_H_ +#define _R128_SAREA_H_ + +/* There are 2 heaps (local/AGP). Each region within a heap is a + minimum of 64k, and there are at most 64 of them per heap. */ +#define R128_LOCAL_TEX_HEAP 0 +#define R128_AGP_TEX_HEAP 1 +#define R128_NR_TEX_HEAPS 2 +#define R128_NR_TEX_REGIONS 64 +#define R128_LOG_TEX_GRANULARITY 16 + +typedef struct { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} R128TexRegion; + +typedef struct { + /* Maintain an LRU of contiguous regions of texture space. If you + * think you own a region of texture memory, and it has an age + * different to the one you set, then you are mistaken and it has + * been stolen by another client. If global texAge hasn't changed, + * there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained texture + * information of other clients - by maintaining them in the same + * lru which is used to age their own textures, clients have an + * approximate lru for the whole of global texture space, and can + * make informed decisions as to which areas to kick out. There is + * no need to choose whether to kick out your own texture or someone + * else's - simply eject them all in LRU order. + */ + /* Last elt is sentinal */ + R128TexRegion texList[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; + /* last time texture was uploaded */ + int texAge[R128_NR_TEX_HEAPS]; + + int ctxOwner; /* last context to upload state */ + + CARD32 ringWrite; /* current ring buffer write index */ +} R128SAREAPriv, *R128SAREAPrivPtr; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h new file mode 100644 index 000000000..3c366c49a --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h @@ -0,0 +1,41 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h,v 1.1 2000/11/02 16:55:39 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * 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 Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE 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. + */ + +#ifndef _R128_VERSION_H_ +#define _R128_VERSION_H_ 1 + +#define R128_NAME "R128" +#define R128_DRIVER_NAME "r128" + +#define R128_VERSION_NAME "4.0.1" + +#define R128_VERSION_MAJOR 4 +#define R128_VERSION_MINOR 0 +#define R128_VERSION_PATCH 1 + +#define R128_VERSION_CURRENT \ + ((R128_VERSION_MAJOR << 20) | \ + (R128_VERSION_MINOR << 10) | \ + (R128_VERSION_PATCH)) + +#endif /* _R128_VERSION_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c new file mode 100644 index 000000000..8c8977e8f --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c @@ -0,0 +1,796 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_video.c,v 1.1 2000/11/02 16:55:39 tsi Exp $ */ +/* + * Copyright 2000 Stuart R. Anderson and Metro Link, Inc. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Stuart R. Anderson <anderson@metrolink.com> + * + * Credits: + * + * This code is derived primarily from the GATOS Project run by Stea Greene. + * The initial version of this code was done by Vladimir Dergacheb. + * + * This code was simplified from the GATOS code primarily because I didn't + * have the right hardware handy to test anything beyond simple overlays, + * and because I wanted to complete it in a short time frame that I had + * available. + * + * My apologies to Vladimir as there is more good work in his code that + * should be brought forward. + */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "xf86xv.h" +#include "xf86Cursor.h" +#include "Xv.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" +#ifdef XF86DRI +#include "r128_dri.h" +#endif + +#include "r128.h" +#include "r128_reg.h" + +/* + * For Debug +#define OUTREG(addr, val) { xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"OUTREG(%s,%x)\n",#addr,val) ;MMIO_OUT32(R128MMIO, addr, val);} +*/ + +#define OFF_DELAY 250 /* milliseconds */ +#define FREE_DELAY 15000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) + +#ifndef XvExtension +void R128InitVideo(ScreenPtr pScreen) {} +#else +static XF86VideoAdaptorPtr R128SetupImageVideo(ScreenPtr); +static int R128SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int R128GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); + +static void R128StopVideo(ScrnInfoPtr, pointer, Bool); +static void R128QueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, unsigned int *, pointer); +static int R128PutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static int R128QueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +#define IMAGE_MAX_WIDTH 2048 +#define IMAGE_MAX_HEIGHT 2048 +#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT) + +static Atom xvColorKey; + +typedef struct { + int videoStatus; + unsigned char brightness; + unsigned char contrast; + + RegionRec clip; + CARD32 colorKey; + CARD8 overlay_pixel_size; + CARD8 current_buffer; + int overlay_pad; + CARD32 overlay_id; + CARD32 overlay_width; + + CARD32 scale_cntl; + CARD32 video_format; + FBLinearPtr linear; + } R128PortPrivRec, *R128PortPrivPtr; + +void R128InitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + + R128TRACE(("R128InitVideo called\n")); + + /* Determine if the card supports this */ + if (pScrn->bitsPerPixel != 8) + { + newAdaptor = R128SetupImageVideo(pScreen); + } + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if(newAdaptor) { + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); +} + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 3 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = +{ + {15, TrueColor}, + {16, TrueColor}, + {32, TrueColor} +}; + +#define NUM_ATTRIBUTES 1 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1<<24)-1, "XV_COLORKEY"}, +}; + +#define NUM_IMAGES 3 + +static XF86ImageRec Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_UYVY +}; + +static void +R128ResetVideo(ScrnInfoPtr pScrn) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + + R128TRACE(("R128ResetVideo called\n")); + + /* Initialize some of the HW here */ + OUTREG(R128_OV0_EXCLUSIVE_HORZ,0); /* disable exclusive mode */ + OUTREG(R128_OV0_VIDEO_KEY_MSK,0xffff); + OUTREG(R128_OV0_KEY_CNTL, R128_GRAPHIC_KEY_FN_NE); + OUTREG(R128_OV0_GRAPHICS_KEY_CLR,pPriv->colorKey); + /* Only using one buffer for now + OUTREG(R128_OV0_AUTO_FLIP_CNTL,pAPriv->Port[0].auto_flip_cntl); + */ + switch(pScrn->depth){ + case 8: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0xff); + break; + case 15: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0x7fff); + break; + case 16: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0xffff); + break; + case 24: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0xffffff); + break; + case 32: + OUTREG(R128_OV0_GRAPHICS_KEY_MSK,0xffffffff); + break; + } + + OUTREG(R128_OV0_REG_LOAD_CNTL,0x0); + OUTREG(R128_OV0_DEINTERLACE_PATTERN,0xAAAAA); + OUTREG(R128_OV0_P1_V_ACCUM_INIT,(2<<20)|1); + OUTREG(R128_OV0_P23_V_ACCUM_INIT,(2<<20)|1); + OUTREG(R128_OV0_P1_H_ACCUM_INIT,(3<<28)); + OUTREG(R128_OV0_P23_H_ACCUM_INIT,(2<<28)); + OUTREG(R128_OV0_STEP_BY,1|(1<<8)); + OUTREG(R128_OV0_FILTER_CNTL,0xf); /* use hardcoded coeff's */ + OUTREG(R128_OV0_FILTER_CNTL,0x0); /* use programmable coeff's */ + OUTREG(R128_OV0_FOUR_TAP_COEF_0 , 0x00002000); + OUTREG(R128_OV0_FOUR_TAP_COEF_1 , 0x0D06200D); + OUTREG(R128_OV0_FOUR_TAP_COEF_2 , 0x0D0A1C0D); + OUTREG(R128_OV0_FOUR_TAP_COEF_3 , 0x0C0E1A0C); + OUTREG(R128_OV0_FOUR_TAP_COEF_4 , 0x0C14140C); + OUTREG(R128_OV0_COLOUR_CNTL,(1<<12)|(1<<20)); + OUTREG(R128_OV0_TEST,0); + OUTREG(R128_OV0_SCALE_CNTL,pPriv->scale_cntl|pPriv->video_format); + OUTREG(R128_CAP0_TRIG_CNTL,0); +} + +static XF86VideoAdaptorPtr +R128SetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + XF86VideoAdaptorPtr adapt; + R128PortPrivPtr pPriv; + + R128TRACE(("R128SetupImageVideo called\n")); + + if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(R128PortPrivRec) + + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "R128 Video Overlay"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + + pPriv = (R128PortPrivPtr)(&adapt->pPortPrivates[1]); + + adapt->pPortPrivates[0].ptr = (pointer)(pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = R128StopVideo; + adapt->SetPortAttribute = R128SetPortAttribute; + adapt->GetPortAttribute = R128GetPortAttribute; + adapt->QueryBestSize = R128QueryBestSize; + adapt->PutImage = R128PutImage; + adapt->QueryImageAttributes = R128QueryImageAttributes; + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + info->adaptor = adapt; + + pPriv->colorKey = 0x01; /* a touch of blue */ + pPriv->video_format = R128_SCALER_SOURCE_VYUY422; + pPriv->scale_cntl = R128_SCALER_PRG_LOAD_START|R128_SCALER_DOUBLE_BUFFER; + pPriv->scale_cntl|= R128_SCALER_SMART_SWITCH|R128_SCALER_PIX_EXPAND; + pPriv->scale_cntl|= R128_SCALER_SMART_SWITCH; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + + R128ResetVideo(pScrn); + + return adapt; +} + +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) +{ + int *dataA, *dataB; + int num; + + num = REGION_NUM_RECTS(A); + if(num != REGION_NUM_RECTS(B)) + return FALSE; + + if((A->extents.x1 != B->extents.x1) || + (A->extents.x2 != B->extents.x2) || + (A->extents.y1 != B->extents.y1) || + (A->extents.y2 != B->extents.y2)) + return FALSE; + + dataA = (int*)REGION_RECTS(A); + dataB = (int*)REGION_RECTS(B); + + while(num--) { + if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; + } + + return TRUE; +} + +static void +R128StopVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = (R128PortPrivPtr) data; + + R128TRACE(("R128StopVideo called\n")); + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if (Exit) { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + OUTREG(R128_OV0_SCALE_CNTL,pPriv->scale_cntl|pPriv->video_format); + } + if(pPriv->linear) { + xf86FreeOffscreenLinear(pPriv->linear); + pPriv->linear = NULL; + } + pPriv->videoStatus = 0; + } else { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + } + } +} + +static int +R128SetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value, + pointer data +) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = (R128PortPrivPtr) data; + + R128TRACE(("R128SetPortAttribute called\n")); + + if (attribute == xvColorKey) { + pPriv->colorKey = value; + OUTREG(R128_OV0_GRAPHICS_KEY_CLR,pPriv->colorKey); + R128TRACE(("Setting ColorKey to %d\n", pPriv->colorKey)); + return Success; + } + + return Success; +} + +static int +R128GetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value, + pointer data +) +{ + R128PortPrivPtr pPriv = (R128PortPrivPtr) data; + + R128TRACE(("R128GetPortAttribute called\n")); + + if (attribute == xvColorKey) { + R128TRACE(("Getting ColorKey %d\n", pPriv->colorKey)); + *value = pPriv->colorKey; + return Success; + } + + return Success; +} + +static void +R128QueryBestSize( + ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +) +{ + R128TRACE(("R128QueryBestSize called\n")); + *p_w = drw_w; + *p_h = drw_h; +} + +static void +R128DisplayVideo( + ScrnInfoPtr pScrn, + short width, short height, + int xa, int ya, int xb, int yb, + short src_w, short src_h, + short drw_w, short drw_h, + int fboffset +) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + int step_by, vert_inc, horz_inc; + + R128TRACE(("R128DisplayVideo called\n")); + + /* calculate step_by factor */ + step_by=src_w/(drw_w*2); + switch(step_by){ + case 0: + OUTREG(R128_OV0_STEP_BY,0x101); + step_by=1; + break; + case 1: + OUTREG(R128_OV0_STEP_BY,0x202); + step_by=2; + break; + case 2: + case 3: + OUTREG(R128_OV0_STEP_BY,0x303); + step_by=4; + break; + default: + OUTREG(R128_OV0_STEP_BY,0x404); + step_by=8; + break; + } + + vert_inc=(src_h<<12)/(drw_h); + horz_inc=(src_w<<12)/(drw_w*step_by); + + OUTREG(R128_OV0_Y_X_START,((xa))|(ya<<16)|(1<<31)); + OUTREG(R128_OV0_Y_X_END,((xb))|((yb)<<16)); + OUTREG(R128_OV0_H_INC,(horz_inc)|((horz_inc<<15))); + OUTREG(R128_OV0_V_INC,(vert_inc<<8)); + OUTREG(R128_OV0_P1_BLANK_LINES_AT_TOP,0xfff|((src_h-1)<<16)); + OUTREG(R128_OV0_P23_BLANK_LINES_AT_TOP,0xfff|((src_h-1)<<16)); + OUTREG(R128_OV0_VID_BUF_PITCH0_VALUE,width<<1); + OUTREG(R128_OV0_VID_BUF_PITCH1_VALUE,width<<1); + OUTREG(R128_OV0_P1_X_START_END,(src_w-1)|((xa&0xf)<<16)); + OUTREG(R128_OV0_P2_X_START_END,(src_w-1)|((xa&0xf)<<16)); + OUTREG(R128_OV0_P3_X_START_END,(src_w-1)|((xa&0xf)<<16)); + + OUTREG(R128_OV0_VID_BUF0_BASE_ADRS,(fboffset)&(~0xf)); + OUTREG(R128_OV0_VID_BUF1_BASE_ADRS,(fboffset)&(~0xf)); + OUTREG(R128_OV0_VID_BUF2_BASE_ADRS,(fboffset)&(~0xf)); + +#if 0 + /* Enable this when double buffering is implemented */ + OUTREG(R128_OV0_VID_BUF3_BASE_ADRS,(fboffset2)&(~0xf)); + OUTREG(R128_OV0_VID_BUF4_BASE_ADRS,(fboffset2)&(~0xf)); + OUTREG(R128_OV0_VID_BUF5_BASE_ADRS,(fboffset2)&(~0xf)); +#endif + + OUTREG(R128_OV0_SCALE_CNTL,pPriv->scale_cntl|R128_SCALER_ENABLE|pPriv->video_format); +} + +static void +R128CopyData( + unsigned char *src, + unsigned char *dst, + int srcPitch, + int dstPitch, + int h, + int w + ) +{ + w <<= 1; + while(h--) { + memcpy(dst, src, w); + src += srcPitch; + dst += dstPitch; + } +} + +static void +R128CopyMungedData( + unsigned char *src1, + unsigned char *src2, + unsigned char *src3, + unsigned char *dst1, + int srcPitch, + int srcPitch2, + int dstPitch, + int h, + int w + ) +{ + CARD32 *dst = (CARD32*)dst1; + int i, j; + + dstPitch >>= 2; + w >>= 1; + + for(j = 0; j < h; j++) { + for(i = 0; i < w; i++) { + dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | + (src3[i] << 8) | (src2[i] << 24); + } + dst += dstPitch; + src1 += srcPitch; + if(j & 1) { + src2 += srcPitch2; + src3 += srcPitch2; + } + } +} + +static FBLinearPtr +R128AllocateMemory( + ScrnInfoPtr pScrn, + FBLinearPtr linear, + int size +) +{ + ScreenPtr pScreen; + FBLinearPtr new_linear; + + R128TRACE(("R128AllocateMemory(%x,%d) called\n",linear,size)); + + if(linear) { + if(linear->size >= size) + return linear; + + if(xf86ResizeOffscreenLinear(linear, size)) + return linear; + + xf86FreeOffscreenLinear(linear); + } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + + if(!new_linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, + PRIORITY_EXTREME); + + if(max_size < size) return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + } + + R128TRACE(("returning %x(%x)\n",new_linear,new_linear->offset)); + + return new_linear; +} + +static int +R128PutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool Sync, + RegionPtr clipBoxes, pointer data +) +{ + R128InfoPtr info = R128PTR(pScrn); + unsigned char *R128MMIO = info->MMIO; + R128PortPrivPtr pPriv = (R128PortPrivPtr)data; + INT32 xa, xb, ya, yb; + INT32 d_x,d_y,d_width,d_height; + int srcPitch = 0, srcPitch2 = 0; + int dstPitch = 0; + int offset,offset2 = 0,offset3 = 0,fboffset; + int top, left, npixels, nlines, size; + CARD32 video_format; + + R128TRACE(("R128PutImage called\n")); + + switch(id) { + case FOURCC_YV12: + case FOURCC_UYVY: + video_format=R128_SCALER_SOURCE_VYUY422; + break; + case FOURCC_YUY2: + video_format=R128_SCALER_SOURCE_YVYU422; + break; + default: + return BadValue; + } + + /* Clip */ + d_x=drw_x; + d_y=drw_y; + d_width=drw_w; + d_height=drw_h; + if(drw_x<0){ + drw_w+=drw_x; + drw_x=0; + } + if(drw_y<0){ + drw_h+=drw_y; + drw_y=0; + } + if(drw_x+drw_w>pScrn->pScreen->width){ + drw_w=pScrn->pScreen->width-drw_x; + } + if(drw_y+drw_h>pScrn->pScreen->height){ + drw_h=pScrn->pScreen->height-drw_y; + } + if((drw_w<=0)||(drw_h<=0)){ + /* this should not happen, + since we are outside of visible screen, + but just in case */ + return Success; + } + + xa = src_x; + xb = src_x + src_w; + ya = src_y; + yb = src_y + src_h; + + dstPitch = width*info->CurrentLayout.pixel_bytes; + srcPitch=width; + + switch(id) { + case FOURCC_YV12: + size = width * height * 2; /* 16bpp */ + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = width * height * 1.5; + break; + } + + if(!(pPriv->linear = R128AllocateMemory(pScrn, pPriv->linear,size))) + return BadAlloc; + + /* copy data */ + top = ya >> 16; + left = (xa >> 16) & ~1; + npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left; + + switch(id) { + case FOURCC_YV12: + srcPitch = (width + 3) & ~3; + offset2 = srcPitch * height; + srcPitch2 = ((width >> 1) + 3) & ~3; + offset3 = (srcPitch2 * (height >> 1)) + offset2; + nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + buf += (top * srcPitch) + left; + nlines = ((yb + 0xffff) >> 16) - top; + srcPitch = (width << 1); + break; + } + nlines=src_h; + npixels=src_w; + if(npixels>width) npixels=width; + if(nlines>height) nlines=height; + + /* adjust source rectangle */ + src_x+=((drw_x-d_x)*src_w)/d_width; + src_y+=((drw_y-d_y)*src_h)/d_height; + + src_w=(src_w * drw_w)/d_width; + src_h=(src_h * drw_h)/d_height; + + offset=(src_x+src_y*width)*info->CurrentLayout.pixel_bytes; + fboffset=pPriv->linear->offset*info->CurrentLayout.pixel_bytes; + + if(!(INREG(R128_CRTC_STATUS)&2)){ + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"too fast"); + return Success; + } + + R128DisplayVideo(pScrn, width, height, + drw_x, drw_y, drw_x+drw_w, drw_y+drw_h, + src_w, src_h, drw_w, drw_h, fboffset); + + /* update cliplist */ + if(!RegionsEqual(&pPriv->clip, clipBoxes)) { + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + /* draw these */ + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); + } + + + switch(id) { + case FOURCC_YV12: + R128CopyMungedData(buf + (top * srcPitch) + (left >> 1), + buf + offset2, buf + offset3, info->FB+fboffset, + srcPitch, srcPitch2, dstPitch, nlines, npixels); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + R128CopyData(buf,info->FB+fboffset,srcPitch,dstPitch, + nlines,npixels); + break; + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + return Success; +} + +static int +R128QueryImageAttributes( + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +) +{ + int size, tmp; + R128TRACE(("R128QueryImageAtrributes called\n")); + + if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; + if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; + + *w = (*w + 1) & ~1; + if(offsets) offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if(pitches) pitches[0] = size; + size *= *h; + if(offsets) offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if(pitches) pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) offsets[2] = size; + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = *w << 1; + if(pitches) pitches[0] = size; + size *= *h; + break; + } + + return size; +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h new file mode 100644 index 000000000..e9b8b37e0 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h @@ -0,0 +1,406 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v 1.1 2000/11/02 16:55:40 tsi Exp $ */ +/* + * + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and VA Linux Systems, Inc., Sunnyvale, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * + */ + +#ifndef _RADEON_H_ +#define _RADEON_H_ + + /* Xv support */ +#include "xf86xv.h" +#include "Xv.h" + + /* vgahw module (for VC save/restore only) */ +#include "vgaHW.h" + +#include "fbdevhw.h" + + /* XAA and Cursor Support */ +#include "xaa.h" +#include "xaalocal.h" +#include "xf86Cursor.h" + + + /* PCI support */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + + /* DDC support */ +#include "xf86DDC.h" + + /* VESA support */ +#include "vbe.h" + + /* DRI support */ +#ifdef XF86DRI +#include "GL/glxint.h" +#include "xf86drm.h" +#include "sarea.h" +#define _XF86DRI_SERVER_ +#include "xf86dri.h" +#include "dri.h" +#include "r128_dri.h" +#include "r128_dripriv.h" +#include "r128_sarea.h" +#endif + +#ifdef RENDER +#include "picturestr.h" +#endif + +/* NOTE: Turn off DRI until it is working */ +#ifdef XF86DRI +#undef XF86DRI +#endif + +#define RADEON_DEBUG 0 /* Turn off debugging output */ +#define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ +#define RADEON_MMIOSIZE 0x80000 +/* Atomic updates of PLL clock don't seem to always work and stick, thus + * the bit never resets. Here - we use our own check by reading back the + * register we've just wrote to make sure it's got the Right! value */ +#define RADEON_ATOMIC_UPDATE 0 /* Use PLL Atomic updates (seems broken) */ + +#define RADEON_VBIOS_SIZE 0x00010000 + +#if RADEON_DEBUG +#define RADEONTRACE(x) \ + do { \ + ErrorF("(**) %s(%d): ", RADEON_NAME, pScrn->scrnIndex); \ + ErrorF x; \ + } while (0); +#else +#define RADEONTRACE(x) +#endif + + +/* Other macros */ +#define RADEON_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) +#define RADEONPTR(pScrn) ((RADEONInfoPtr)(pScrn)->driverPrivate) + +typedef struct { /* All values in XCLKS */ + int ML; /* Memory Read Latency */ + int MB; /* Memory Burst Length */ + int Trcd; /* RAS to CAS delay */ + int Trp; /* RAS percentage */ + int Twr; /* Write Recovery */ + int CL; /* CAS Latency */ + int Tr2w; /* Read to Write Delay */ + int Rloop; /* Loop Latency */ + int Rloop_fudge; /* Add to ML to get Rloop */ + char *name; +} RADEONRAMRec, *RADEONRAMPtr; + +typedef struct { + /* Common registers */ + CARD32 ovr_clr; + CARD32 ovr_wid_left_right; + CARD32 ovr_wid_top_bottom; + CARD32 ov0_scale_cntl; + CARD32 mpp_tb_config; + CARD32 mpp_gp_config; + CARD32 subpic_cntl; + CARD32 viph_control; + CARD32 i2c_cntl_1; + CARD32 gen_int_cntl; + CARD32 cap0_trig_cntl; + CARD32 cap1_trig_cntl; + CARD32 bus_cntl; + + /* Other registers to save for VT switches */ + CARD32 dp_datatype; + CARD32 rbbm_soft_reset; + CARD32 clock_cntl_index; + CARD32 amcgpio_en_reg; + CARD32 amcgpio_mask; + + /* CRTC registers */ + CARD32 crtc_gen_cntl; + CARD32 crtc_ext_cntl; + CARD32 dac_cntl; + CARD32 crtc_h_total_disp; + CARD32 crtc_h_sync_strt_wid; + CARD32 crtc_v_total_disp; + CARD32 crtc_v_sync_strt_wid; + CARD32 crtc_offset; + CARD32 crtc_offset_cntl; + CARD32 crtc_pitch; + + /* CRTC2 registers */ + CARD32 crtc2_gen_cntl; + + /* Flat panel registers */ + CARD32 fp_crtc_h_total_disp; + CARD32 fp_crtc_v_total_disp; + CARD32 fp_gen_cntl; + CARD32 fp_h_sync_strt_wid; + CARD32 fp_horz_stretch; + CARD32 fp_panel_cntl; + CARD32 fp_v_sync_strt_wid; + CARD32 fp_vert_stretch; + CARD32 lvds_gen_cntl; + CARD32 tmds_crc; + + /* Computed values for PLL */ + CARD32 dot_clock_freq; + CARD32 pll_output_freq; + int feedback_div; + int post_div; + + /* PLL registers */ + CARD32 ppll_ref_div; + CARD32 ppll_div_3; + CARD32 htotal_cntl; + + /* DDA register */ + CARD32 dda_config; + CARD32 dda_on_off; + + /* Pallet */ + Bool palette_valid; + CARD32 palette[256]; +} RADEONSaveRec, *RADEONSavePtr; + +typedef struct { + CARD16 reference_freq; + CARD16 reference_div; + CARD32 min_pll_freq; + CARD32 max_pll_freq; + CARD16 xclk; +} RADEONPLLRec, *RADEONPLLPtr; + +typedef struct { + int bitsPerPixel; + int depth; + int displayWidth; + int pixel_code; + int pixel_bytes; + DisplayModePtr mode; +} RADEONFBLayout; + +typedef struct { + EntityInfoPtr pEnt; + pciVideoPtr PciInfo; + PCITAG PciTag; + int Chipset; + Bool Primary; + + Bool FBDev; + + unsigned long LinearAddr; /* Frame buffer physical address */ + unsigned long MMIOAddr; /* MMIO region physical address */ + unsigned long BIOSAddr; /* BIOS physical address */ + Bool BIOSFromPCI; /* BIOS is read from PCI space */ + + unsigned char *MMIO; /* Map of MMIO region */ + unsigned char *FB; /* Map of frame buffer */ + CARD8 *VBIOS; /* Video BIOS pointer */ + + CARD32 MemCntl; + CARD32 BusCntl; + unsigned long FbMapSize; /* Size of frame buffer, in bytes */ + int Flags; /* Saved copy of mode flags */ + +#ifdef ENABLE_FLAT_PANEL + Bool HasPanelRegs; /* Current chip can connect to a FP */ + Bool CRTOnly; /* Only use External CRT instead of FP */ + int FPBIOSstart; /* Start of the flat panel info */ + + /* Computed values for FPs */ + int PanelXRes; + int PanelYRes; + int PanelPwrDly; +#endif + + RADEONPLLRec pll; + RADEONRAMPtr ram; + + RADEONSaveRec SavedReg; /* Original (text) mode */ + RADEONSaveRec ModeReg; /* Current mode */ + Bool (*CloseScreen)(int, ScreenPtr); + + Bool PaletteSavedOnVT; /* Palette saved on last VT switch */ + + XAAInfoRecPtr accel; + Bool accelOn; + xf86CursorInfoPtr cursor; + unsigned long cursor_start; + unsigned long cursor_end; + + int fifo_slots; /* Free slots in the FIFO (64 max) */ + int pix24bpp; /* Depth of pixmap for 24bpp framebuffer */ + Bool dac6bits; /* Use 6 bit DAC? */ + + /* Computed values for Radeon */ + int pitch; + int datatype; + CARD32 dp_gui_master_cntl; + + /* Saved values for ScreenToScreenCopy */ + int xdir; + int ydir; + + /* ScanlineScreenToScreenColorExpand support */ + unsigned char *scratch_buffer[1]; + unsigned char *scratch_save; + int scanline_x; + int scanline_y; + int scanline_h; + int scanline_h_w; + int scanline_words; + int scanline_direct; + int scanline_bpp; /* Only used for ImageWrite */ + + DGAModePtr DGAModes; + int numDGAModes; + Bool DGAactive; + int DGAViewportStatus; + + RADEONFBLayout CurrentLayout; +#ifdef XF86DRI + Bool directRenderingEnabled; + DRIInfoPtr pDRIInfo; + int drmFD; + int numVisualConfigs; + __GLXvisualConfig *pVisualConfigs; + RADEONConfigPrivPtr pVisualConfigsPriv; + + drmHandle fbHandle; + + drmSize registerSize; + drmHandle registerHandle; + + Bool IsPCI; /* Current card is a PCI card */ + + drmSize agpSize; + drmHandle agpMemHandle; /* Handle from drmAgpAlloc */ + unsigned long agpOffset; + unsigned char *AGP; /* Map */ + int agpMode; + + Bool CPInUse; /* CP is currently active */ + int CPMode; /* CP mode that server/clients use */ + int CPFifoSize; /* Size of the CP command FIFO */ + Bool CPSecure; /* CP security enabled */ + int CPusecTimeout; /* CP timeout in usecs */ + Bool CP2D; /* CP is used for X server 2D prims */ + + /* CP ring buffer data */ + unsigned long ringStart; /* Offset into AGP space */ + drmHandle ringHandle; /* Handle from drmAddMap */ + drmSize ringMapSize; /* Size of map */ + int ringSize; /* Size of ring (in MB) */ + unsigned char *ring; /* Map */ + int ringSizeLog2QW; + + unsigned long ringReadOffset; /* Offset into AGP space */ + drmHandle ringReadPtrHandle; /* Handle from drmAddMap */ + drmSize ringReadMapSize; /* Size of map */ + unsigned char *ringReadPtr; /* Map */ + + /* CP vertex buffer data */ + unsigned long vbStart; /* Offset into AGP space */ + drmHandle vbHandle; /* Handle from drmAddMap */ + drmSize vbMapSize; /* Size of map */ + int vbSize; /* Size of vert bufs (in MB) */ + unsigned char *vb; /* Map */ + int vbBufSize; /* Size of individual vert buf */ + int vbNumBufs; /* Number of vert bufs */ + drmBufMapPtr vbBufs; /* Buffer map */ + + /* CP indirect buffer data */ + unsigned long indStart; /* Offset into AGP space */ + drmHandle indHandle; /* Handle from drmAddMap */ + drmSize indMapSize; /* Size of map */ + int indSize; /* Size of indirect bufs (in MB) */ + unsigned char *ind; /* Map */ + + /* CP AGP Texture data */ + unsigned long agpTexStart; /* Offset into AGP space */ + drmHandle agpTexHandle; /* Handle from drmAddMap */ + drmSize agpTexMapSize; /* Size of map */ + int agpTexSize; /* Size of AGP tex space (in MB) */ + unsigned char *agpTex; /* Map */ + int log2AGPTexGran; + + /* DRI screen private data */ + int fbX; + int fbY; + int backX; + int backY; + int depthX; + int depthY; + int textureX; + int textureY; + int textureSize; + int log2TexGran; +#endif + XF86VideoAdaptorPtr adaptor; +} RADEONInfoRec, *RADEONInfoPtr; + +#define RADEONWaitForFifo(pScrn, entries) \ +do { \ + if (info->fifo_slots < entries) \ + RADEONWaitForFifoFunction(pScrn, entries); \ + info->fifo_slots -= entries; \ +} while (0) + +extern void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries); +extern void RADEONWaitForIdle(ScrnInfoPtr pScrn); +extern void RADEONEngineReset(ScrnInfoPtr pScrn); +extern void RADEONEngineFlush(ScrnInfoPtr pScrn); + +extern unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr); +extern void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn); + +extern Bool RADEONAccelInit(ScreenPtr pScreen); +extern void RADEONEngineInit(ScrnInfoPtr pScrn); +extern Bool RADEONCursorInit(ScreenPtr pScreen); +extern Bool RADEONDGAInit(ScreenPtr pScreen); + +extern int RADEONMinBits(int val); + +extern void RADEONInitVideo(ScreenPtr); + +#ifdef XF86DRI +extern Bool RADEONDRIScreenInit(ScreenPtr pScreen); +extern void RADEONDRICloseScreen(ScreenPtr pScreen); +extern Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen); +extern void RADEONCPStart(ScrnInfoPtr pScrn); +extern void RADEONCPStop(ScrnInfoPtr pScrn); +extern void RADEONCPResetRing(ScrnInfoPtr pScrn); +extern void RADEONCPWaitForIdle(ScrnInfoPtr pScrn); +#endif + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c new file mode 100644 index 000000000..985137eb3 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c @@ -0,0 +1,972 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c,v 1.2 2000/11/03 09:52:54 alanh Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and VA Linux Systems, Inc., Sunnyvale, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * Alan Hourihane <ahourihane@valinux.com> + * + * Credits: + * + * Thanks to Ani Joshi <ajoshi@shell.unixbox.com> for providing source + * code to his Radeon driver. Portions of this file are based on the + * initialization code for that driver. + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + * Notes on unimplemented XAA optimizations: + * + * SetClipping: This has been removed as XAA expects 16bit registers + * for full clipping. + * TwoPointLine: The Radeon supports this. Not Bresenham. + * DashedLine with non-power-of-two pattern length: Apparently, there is + * no way to set the length of the pattern -- it is always + * assumed to be 8 or 32 (or 1024?). + * ScreenToScreenColorExpandFill: See p. 4-17 of the Technical Reference + * Manual where it states that monochrome expansion of frame + * buffer data is not supported. + * CPUToScreenColorExpandFill, direct: The implementation here uses a hybrid + * direct/indirect method. If we had more data registers, + * then we could do better. If XAA supported a trigger write + * address, the code would be simpler. + * Color8x8PatternFill: Apparently, an 8x8 color brush cannot take an 8x8 + * pattern from frame buffer memory. + * ImageWrites: Same as CPUToScreenColorExpandFill + * + */ + +#define RADEON_IMAGEWRITE 0 /* Turned off by default - slower in accel */ + + /* X and server generic header files */ +#include "Xarch.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + + /* Line support */ +#include "miline.h" + + /* Driver data structures */ +#include "radeon.h" +#include "radeon_reg.h" + +static struct { + int rop; + int pattern; +} RADEON_ROP[] = { + { RADEON_ROP3_ZERO, RADEON_ROP3_ZERO }, /* GXclear */ + { RADEON_ROP3_DSa, RADEON_ROP3_DPa }, /* Gxand */ + { RADEON_ROP3_SDna, RADEON_ROP3_PDna }, /* GXandReverse */ + { RADEON_ROP3_S, RADEON_ROP3_P }, /* GXcopy */ + { RADEON_ROP3_DSna, RADEON_ROP3_DPna }, /* GXandInverted */ + { RADEON_ROP3_D, RADEON_ROP3_D }, /* GXnoop */ + { RADEON_ROP3_DSx, RADEON_ROP3_DPx }, /* GXxor */ + { RADEON_ROP3_DSo, RADEON_ROP3_DPo }, /* GXor */ + { RADEON_ROP3_DSon, RADEON_ROP3_DPon }, /* GXnor */ + { RADEON_ROP3_DSxn, RADEON_ROP3_PDxn }, /* GXequiv */ + { RADEON_ROP3_Dn, RADEON_ROP3_Dn }, /* GXinvert */ + { RADEON_ROP3_SDno, RADEON_ROP3_PDno }, /* GXorReverse */ + { RADEON_ROP3_Sn, RADEON_ROP3_Pn }, /* GXcopyInverted */ + { RADEON_ROP3_DSno, RADEON_ROP3_DPno }, /* GXorInverted */ + { RADEON_ROP3_DSan, RADEON_ROP3_DPan }, /* GXnand */ + { RADEON_ROP3_ONE, RADEON_ROP3_ONE } /* GXset */ +}; + +/* Flush all dirty data in the Pixel Cache to memory. */ +void RADEONEngineFlush(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL, + ~RADEON_RB2D_DC_FLUSH_ALL); + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT) & RADEON_RB2D_DC_BUSY)) break; + } +} + +/* Reset graphics card to known state. */ +void RADEONEngineReset(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 clock_cntl_index; + CARD32 mclk_cntl; + CARD32 rbbm_soft_reset; + + RADEONEngineFlush(pScrn); + + clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); + mclk_cntl = INPLL(pScrn, RADEON_MCLK_CNTL); + + OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl | 0x003f0000)); + + rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); + + OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset | + RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB | + RADEON_SOFT_RESET_HDP); + INREG(RADEON_RBBM_SOFT_RESET); + OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset & + ~(RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB | + RADEON_SOFT_RESET_HDP)); + INREG(RADEON_RBBM_SOFT_RESET); + + OUTPLL(RADEON_MCLK_CNTL, mclk_cntl); + OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); + OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); + +#ifdef XF86DRI + if (RADEONCP_USE_RING_BUFFER(info->CPMode)) RADEONCPResetRing(pScrn); +#endif +} + +/* The FIFO has 64 slots. This routines waits until at least `entries' of + these slots are empty. */ +void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + info->fifo_slots = + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK; + if (info->fifo_slots >= entries) return; + } + RADEONTRACE(("FIFO timed out: %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FIFO timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); +#ifdef XF86DRI + if (info->CP2D) RADEONCPStart(pScrn); +#endif + } +} + +/* Wait for the graphics engine to be completely idle: the FIFO has + drained, the Pixel Cache is flushed, and the engine is idle. This is a + standard "sync" function that will make the hardware "quiescent". */ +void RADEONWaitForIdle(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + + RADEONWaitForFifoFunction(pScrn, 64); + + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { + RADEONEngineFlush(pScrn); + return; + } + } + RADEONTRACE(("Idle timed out: %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); +#ifdef XF86DRI + if (info->CP2D) RADEONCPStart(pScrn); +#endif + } +} + +/* Setup for XAA SolidFill. */ +static void RADEONSetupForSolidFill(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 4); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_SOLID_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].pattern)); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, color); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT + | RADEON_DST_Y_TOP_TO_BOTTOM)); +} + +/* Subsequent XAA SolidFillRect. + + Tests: xtest CH06/fllrctngl, xterm +*/ +static void RADEONSubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 2); + OUTREG(RADEON_DST_Y_X, (y << 16) | x); + OUTREG(RADEON_DST_WIDTH_HEIGHT, (w << 16) | h); +} + +/* Setup for XAA solid lines. */ +static void RADEONSetupForSolidLine(ScrnInfoPtr pScrn, + int color, int rop, unsigned int planemask) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_SOLID_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].pattern)); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, color); + OUTREG(RADEON_DP_WRITE_MASK, planemask); +} + + +/* Subsequent XAA solid TwoPointLine line. + + Tests: xtest CH06/drwln, ico, Mark Vojkovich's linetest program + + [See http://www.xfree86.org/devel/archives/devel/1999-Jun/0102.shtml for + Mark Vojkovich's linetest program, posted 2Jun99 to devel@xfree86.org.] +*/ +static void RADEONSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, + int xa, int ya, int xb, int yb, + int flags) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int direction = 0; + + if (xa < xb) direction |= RADEON_DST_X_DIR_LEFT_TO_RIGHT; + if (ya < yb) direction |= RADEON_DST_Y_DIR_TOP_TO_BOTTOM; + + RADEONWaitForFifo(pScrn, 4); + OUTREG(RADEON_DST_Y_X, (ya << 16) | xa); + if (!(flags & OMIT_LAST)) + OUTREG(RADEON_DP_CNTL_XDIR_YDIR_YMAJOR, direction); + OUTREG(RADEON_DST_LINE_START, (ya << 16) | xa); + OUTREG(RADEON_DST_LINE_END, (yb << 16) | xb); +} + +/* Subsequent XAA solid horizontal and vertical lines */ +static void RADEONSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, + int x, int y, int len, int dir ) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT + | RADEON_DST_Y_TOP_TO_BOTTOM)); + + if (dir == DEGREES_0) { + RADEONSubsequentSolidFillRect(pScrn, x, y, len, 1); + } else { + RADEONSubsequentSolidFillRect(pScrn, x, y, 1, len); + } +} + +/* Setup for XAA dashed lines. + + Tests: xtest CH05/stdshs, XFree86/drwln + + NOTE: Since we can only accelerate lines with power-of-2 patterns of + length <= 32. +*/ +static void RADEONSetupForDashedLine(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, unsigned int planemask, + int length, unsigned char *pattern) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 pat = *(CARD32 *)pattern; + + switch (length) { + case 2: pat |= pat << 2; /* fall through */ + case 4: pat |= pat << 4; /* fall through */ + case 8: pat |= pat << 8; /* fall through */ + case 16: pat |= pat << 16; + } + + RADEONWaitForFifo(pScrn, 5); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? RADEON_GMC_BRUSH_32x1_MONO_FG_LA + : RADEON_GMC_BRUSH_32x1_MONO_FG_BG) + | RADEON_ROP[rop].pattern + | RADEON_GMC_BYTE_LSB_TO_MSB)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, fg); + OUTREG(RADEON_DP_BRUSH_BKGD_CLR, bg); + OUTREG(RADEON_BRUSH_DATA0, pat); +} + +/* Subsequent XAA dashed line. */ +static void RADEONSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, + int xa, int ya, + int xb, int yb, + int flags, + int phase) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int direction = 0; + + if (xa < xb) direction |= RADEON_DST_X_DIR_LEFT_TO_RIGHT; + if (ya < yb) direction |= RADEON_DST_Y_DIR_TOP_TO_BOTTOM; + + RADEONWaitForFifo(pScrn, 5); + if (!(flags & OMIT_LAST)) + OUTREG(RADEON_DP_CNTL_XDIR_YDIR_YMAJOR, direction); + OUTREG(RADEON_DST_Y_X, (ya << 16) | xa); + OUTREG(RADEON_BRUSH_Y_X, (phase << 16) | phase); + OUTREG(RADEON_DST_LINE_START, (ya << 16) | xa); + OUTREG(RADEON_DST_LINE_END, (yb << 16) | xb); +} + +/* Setup for XAA screen-to-screen copy. + + Tests: xtest CH06/fllrctngl (also tests transparency). +*/ +static void RADEONSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int trans_color) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + info->xdir = xdir; + info->ydir = ydir; + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_NONE + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].rop + | RADEON_DP_SRC_SOURCE_MEMORY)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_CNTL, ((xdir >= 0 + ? RADEON_DST_X_LEFT_TO_RIGHT + : 0) + | (ydir >= 0 + ? RADEON_DST_Y_TOP_TO_BOTTOM + : 0))); + + if (trans_color != -1) { + /* Set up for transparency */ + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_CLR_CMP_CLR_SRC, trans_color); + OUTREG(RADEON_CLR_CMP_MASK, RADEON_CLR_CMP_MSK); + /* Mmmm, Seems as though the transparency compare is opposite to r128 + * It should only draw when source != trans_color, + * this is the opposite of that. */ + OUTREG(RADEON_CLR_CMP_CNTL, (RADEON_SRC_CMP_EQ_COLOR + | RADEON_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA screen-to-screen copy. */ +static void RADEONSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int xa, int ya, + int xb, int yb, + int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + if (info->xdir < 0) xa += w - 1, xb += w - 1; + if (info->ydir < 0) ya += h - 1, yb += h - 1; + + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_SRC_Y_X, (ya << 16) | xa); + OUTREG(RADEON_DST_Y_X, (yb << 16) | xb); + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +/* Setup for XAA mono 8x8 pattern color expansion. Patterns with + transparency use `bg == -1'. This routine is only used if the XAA + pixmap cache is turned on. + + Tests: xtest XFree86/fllrctngl (no other test will test this routine with + both transparency and non-transparency) +*/ +static void RADEONSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, int rop, + unsigned int planemask) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 6); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | (bg == -1 + ? RADEON_GMC_BRUSH_8X8_MONO_FG_LA + : RADEON_GMC_BRUSH_8X8_MONO_FG_BG) + | RADEON_ROP[rop].pattern + | RADEON_GMC_BYTE_LSB_TO_MSB)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, fg); + OUTREG(RADEON_DP_BRUSH_BKGD_CLR, bg); + OUTREG(RADEON_BRUSH_DATA0, patternx); + OUTREG(RADEON_BRUSH_DATA1, patterny); +} + +/* Subsequent XAA 8x8 pattern color expansion. Because they are used in + the setup function, `patternx' and `patterny' are not used here. */ +static void RADEONSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_BRUSH_Y_X, (patterny << 8) | patternx); + OUTREG(RADEON_DST_Y_X, (y << 16) | x); + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); +} + +#if 0 +/* Setup for XAA color 8x8 pattern fill. + + Tests: xtest XFree86/fllrctngl (with Mono8x8PatternFill off) +*/ +static void RADEONSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, + int patx, int paty, + int rop, unsigned int planemask, + int trans_color) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + ErrorF("Color8x8 %d %d %d\n", trans_color, patx, paty); + + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_8x8_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].pattern + | RADEON_DP_SRC_SOURCE_MEMORY)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_SRC_Y_X, (paty << 16) | patx); + + if (trans_color != -1) { + /* Set up for transparency */ + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_CLR_CMP_CLR_SRC, trans_color); + OUTREG(RADEON_CLR_CMP_MASK, RADEON_CLR_CMP_MSK); + /* Mmmm, Seems as though the transparency compare is opposite to r128 + * It should only draw when source != trans_color, + * this is the opposite of that. */ + OUTREG(RADEON_CLR_CMP_CNTL, (RADEON_SRC_CMP_EQ_COLOR + | RADEON_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA 8x8 pattern color expansion. */ +static void RADEONSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + ErrorF("Color8x8 %d,%d %d,%d %d %d\n", patx, paty, x, y, w, h); + + RADEONWaitForFifo(pScrn, 4); + OUTREG(RADEON_BRUSH_Y_X, (paty << 16) | patx); + OUTREG(RADEON_DST_Y_X, (y << 16) | x); + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); +} +#endif + +/* Setup for XAA indirect CPU-to-screen color expansion (indirect). + Because of how the scratch buffer is initialized, this is really a + mainstore-to-screen color expansion. Transparency is supported when `bg + == -1'. + Implementing the hybrid indirect/direct scheme improved performance in a + few areas: +*/ +static void RADEONSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int + planemask) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONWaitForFifo(pScrn, 4); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_DST_CLIPPING + | RADEON_GMC_BRUSH_NONE + | (bg == -1 + ? RADEON_GMC_SRC_DATATYPE_MONO_FG_LA + : RADEON_GMC_SRC_DATATYPE_MONO_FG_BG) + | RADEON_ROP[rop].rop + | RADEON_GMC_BYTE_LSB_TO_MSB + | RADEON_DP_SRC_SOURCE_HOST_DATA)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + OUTREG(RADEON_DP_SRC_FRGD_CLR, fg); + OUTREG(RADEON_DP_SRC_BKGD_CLR, bg); +} + +/* Subsequent XAA indirect CPU-to-screen color expansion. This is only + called once for each rectangle. */ +static void RADEONSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr + pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + info->scanline_h = h; + info->scanline_words = (w + 31) >> 5; + + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(RADEON_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + RADEONWaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(RADEON_SC_TOP_LEFT, (y << 16) | ((x+skipleft) & 0xffff)); + /* MMmm, we don't need the -1 on both y+h or x+w, why ? */ + OUTREG(RADEON_SC_BOTTOM_RIGHT, ((y+h) << 16) | ((x+w) & 0xffff)); + OUTREG(RADEON_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | ((w + 31) & ~31)); +} + +/* Subsequent XAA indirect CPU-to-screen color expandion. This is called + once for each scanline. */ +static void RADEONSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 *p = (CARD32 *)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile CARD32 *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + RADEONWaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + RADEONWaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + RADEONWaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} + +#if RADEON_IMAGEWRITE +/* Setup for XAA indirect image write. */ +static void RADEONSetupForScanlineImageWrite(ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int trans_color, + int bpp, + int depth) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + info->scanline_bpp = bpp; + + RADEONWaitForFifo(pScrn, 2); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_DST_CLIPPING + | RADEON_GMC_BRUSH_NONE + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].rop + | RADEON_GMC_BYTE_LSB_TO_MSB + | RADEON_DP_SRC_SOURCE_HOST_DATA)); + OUTREG(RADEON_DP_WRITE_MASK, planemask); + + if (trans_color != -1) { + /* Set up for transparency */ + RADEONWaitForFifo(pScrn, 3); + OUTREG(RADEON_CLR_CMP_CLR_SRC, trans_color); + OUTREG(RADEON_CLR_CMP_MASK, RADEON_CLR_CMP_MSK); + /* Mmmm, Seems as though the transparency compare is opposite to r128 + * It should only draw when source != trans_color, + * this is the opposite of that. */ + OUTREG(RADEON_CLR_CMP_CNTL, (RADEON_SRC_CMP_EQ_COLOR + | RADEON_CLR_CMP_SRC_SOURCE)); + } +} + +/* Subsequent XAA indirect image write. This is only called once for each + rectangle. */ +static void RADEONSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int shift = 0; /* 32bpp */ + + if (pScrn->bitsPerPixel == 8) shift = 3; + else if (pScrn->bitsPerPixel == 16) shift = 1; + + info->scanline_h = h; + info->scanline_words = (w * info->scanline_bpp + 31) >> 5; + + if ((info->scanline_words * h) <= 9) { + /* Turn on direct for less than 9 dword colour expansion */ + info->scratch_buffer[0] + = (unsigned char *)(ADDRREG(RADEON_HOST_DATA_LAST) + - (info->scanline_words - 1)); + info->scanline_direct = 1; + } else { + /* Use indirect for anything else */ + info->scratch_buffer[0] = info->scratch_save; + info->scanline_direct = 0; + } + + RADEONWaitForFifo(pScrn, 4 + (info->scanline_direct ? + (info->scanline_words * h) : 0) ); + OUTREG(RADEON_SC_TOP_LEFT, (y << 16) | ((x+skipleft) & 0xffff)); + /* MMmm, we don't need the -1 on both y+h or x+w, why ? */ + OUTREG(RADEON_SC_BOTTOM_RIGHT, ((y+h) << 16) | ((x+w) & 0xffff)); + OUTREG(RADEON_DST_Y_X, (y << 16) | (x & 0xffff)); + /* Have to pad the width here and use clipping engine */ + OUTREG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | ((w + shift) & ~shift)); +} + +/* Subsequent XAA indirect image write. This is called once for each + scanline. */ +static void RADEONSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 *p = (CARD32 *)info->scratch_buffer[bufno]; + int i; + int left = info->scanline_words; + volatile CARD32 *d; + + if (info->scanline_direct) return; + --info->scanline_h; + while (left) { + if (left <= 8) { + /* Last scanline - finish write to DATA_LAST */ + if (info->scanline_h == 0) { + RADEONWaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA_LAST) - (left - 1); left; --left) + *d++ = *p++; + return; + } else { + RADEONWaitForFifo(pScrn, left); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA7) - (left - 1); left; --left) + *d++ = *p++; + } + } else { + RADEONWaitForFifo(pScrn, 8); + /* Unrolling doesn't improve performance */ + for (d = ADDRREG(RADEON_HOST_DATA0), i = 0; i < 8; i++) + *d++ = *p++; + left -= 8; + } + } +} +#endif + +/* Initialize the acceleration hardware. */ +void RADEONEngineInit(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int pitch64; + + RADEONTRACE(("EngineInit (%d/%d)\n", + info->CurrentLayout.pixel_code, + info->CurrentLayout.bitsPerPixel)); + + OUTREG(RADEON_SCALE_3D_CNTL, 0); + RADEONEngineReset(pScrn); + + RADEONWaitForFifo(pScrn, 1); + /* turn of all automatic flushing - we'll do it all */ + OUTREG(RADEON_RB2D_DSTCACHE_MODE, 0); + + switch (info->CurrentLayout.pixel_code) { + case 8: info->datatype = 2; break; + case 15: info->datatype = 3; break; + case 16: info->datatype = 4; break; + case 24: info->datatype = 5; break; + case 32: info->datatype = 6; break; + default: + RADEONTRACE(("Unknown depth/bpp = %d/%d (code = %d)\n", + info->CurrentLayout.depth, + info->CurrentLayout.bitsPerPixel, + info->CurrentLayout.pixel_code)); + } + info->pitch = ((info->CurrentLayout.displayWidth / 8) * + (info->CurrentLayout.pixel_bytes == 3 ? 3 : 1)); + + RADEONTRACE(("Pitch for acceleration = %d\n", info->pitch)); + + pitch64 = ((pScrn->displayWidth * (pScrn->bitsPerPixel / 8) + 0x3f)) >> 6; + + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DEFAULT_OFFSET, (INREG(RADEON_DEFAULT_OFFSET) & 0xC0000000) | + (pitch64 << 22)); + + RADEONWaitForFifo(pScrn, 1); +#if X_BYTE_ORDER == X_BIG_ENDIAN + OUTREGP(RADEON_DP_DATATYPE, + RADEON_HOST_BIG_ENDIAN_EN, ~RADEON_HOST_BIG_ENDIAN_EN); +#else + OUTREGP(RADEON_DP_DATATYPE, 0, ~RADEON_HOST_BIG_ENDIAN_EN); +#endif + + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX + | RADEON_DEFAULT_SC_BOTTOM_MAX)); + info->dp_gui_master_cntl = + ((info->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) + | RADEON_GMC_CLR_CMP_CNTL_DIS); + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_SOLID_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR)); + + RADEONWaitForFifo(pScrn, 7); + OUTREG(RADEON_DST_LINE_START, 0); + OUTREG(RADEON_DST_LINE_END, 0); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff); + OUTREG(RADEON_DP_BRUSH_BKGD_CLR, 0x00000000); + OUTREG(RADEON_DP_SRC_FRGD_CLR, 0xffffffff); + OUTREG(RADEON_DP_SRC_BKGD_CLR, 0x00000000); + OUTREG(RADEON_DP_WRITE_MASK, 0xffffffff); + + RADEONWaitForIdle(pScrn); +} + +#ifdef XF86DRI +/* FIXME: When direct rendering is enabled, we should use the CP to + draw 2D commands */ +static void RADEONCPAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) +{ + a->Flags = 0; + + /* Sync */ +#if 1 + a->Sync = RADEONWaitForIdle; +#else + a->Sync = RADEONCCEWaitForIdle; +#endif + +} +#endif + +static void RADEONMMIOAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + a->Flags = (PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER); + + /* Sync */ + a->Sync = RADEONWaitForIdle; + + /* Solid Filled Rectangle */ + a->PolyFillRectSolidFlags = 0; + a->SetupForSolidFill = RADEONSetupForSolidFill; + a->SubsequentSolidFillRect = RADEONSubsequentSolidFillRect; + + /* Screen-to-screen Copy */ + a->ScreenToScreenCopyFlags = 0; + a->SetupForScreenToScreenCopy = RADEONSetupForScreenToScreenCopy; + a->SubsequentScreenToScreenCopy = RADEONSubsequentScreenToScreenCopy; + + /* Mono 8x8 Pattern Fill (Color Expand) */ + a->SetupForMono8x8PatternFill + = RADEONSetupForMono8x8PatternFill; + a->SubsequentMono8x8PatternFillRect + = RADEONSubsequentMono8x8PatternFillRect; + a->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_PROGRAMMED_ORIGIN + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_LSBFIRST); + + /* Indirect CPU-To-Screen Color Expand */ +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + a->ScanlineCPUToScreenColorExpandFillFlags = LEFT_EDGE_CLIPPING + /* RADEON gets upset, when using HOST provided data + * without a source rop. To show run 'xtest's drwarc */ + | ROP_NEEDS_SOURCE + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#else + a->ScanlineCPUToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST + /* RADEON gets upset, when using HOST provided data + * without a source rop. To show run 'xtest's drwarc */ + | ROP_NEEDS_SOURCE + | LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#endif + a->NumScanlineColorExpandBuffers = 1; + a->ScanlineColorExpandBuffers = info->scratch_buffer; + info->scratch_save = xalloc(((pScrn->virtualX+31)/32*4) + + (pScrn->virtualX + * info->CurrentLayout.pixel_bytes)); + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineCPUToScreenColorExpandFill + = RADEONSetupForScanlineCPUToScreenColorExpandFill; + a->SubsequentScanlineCPUToScreenColorExpandFill + = RADEONSubsequentScanlineCPUToScreenColorExpandFill; + a->SubsequentColorExpandScanline = RADEONSubsequentColorExpandScanline; + + a->SetupForSolidLine = RADEONSetupForSolidLine; + a->SubsequentSolidTwoPointLine = RADEONSubsequentSolidTwoPointLine; + a->SubsequentSolidHorVertLine = RADEONSubsequentSolidHorVertLine; + + a->SetupForDashedLine = RADEONSetupForDashedLine; + a->SubsequentDashedTwoPointLine = RADEONSubsequentDashedTwoPointLine; + a->DashPatternMaxLength = 32; + a->DashedLineFlags = (LINE_PATTERN_LSBFIRST_LSBJUSTIFIED + | LINE_PATTERN_POWER_OF_2_ONLY); + +#if RADEON_IMAGEWRITE + /* ImageWrite */ + a->NumScanlineImageWriteBuffers = 1; + a->ScanlineImageWriteBuffers = info->scratch_buffer; + info->scratch_buffer[0] = info->scratch_save; + a->SetupForScanlineImageWrite = RADEONSetupForScanlineImageWrite; + a->SubsequentScanlineImageWriteRect + = RADEONSubsequentScanlineImageWriteRect; + a->SubsequentImageWriteScanline = RADEONSubsequentImageWriteScanline; + a->ScanlineImageWriteFlags = CPU_TRANSFER_PAD_DWORD + /* Performance tests show that we shouldn't use GXcopy for + * uploads as a memcpy is faster */ + | NO_GXCOPY + /* RADEON gets upset, when using HOST provided data + * without a source rop. To show run 'xtest's ptimg */ + | ROP_NEEDS_SOURCE + | SCANLINE_PAD_DWORD + | LEFT_EDGE_CLIPPING + | LEFT_EDGE_CLIPPING_NEGATIVE_X; +#endif + +#if 0 + /* Color 8x8 Pattern Fill */ + a->SetupForColor8x8PatternFill + = RADEONSetupForColor8x8PatternFill; + a->SubsequentColor8x8PatternFillRect + = RADEONSubsequentColor8x8PatternFillRect; + a->Color8x8PatternFillFlags = + HARDWARE_PATTERN_PROGRAMMED_ORIGIN + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_LSBFIRST; +#endif +} + +/* Initialize XAA for supported acceleration and also initialize the + graphics hardware for acceleration. */ +Bool RADEONAccelInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + XAAInfoRecPtr a; + + if (!(a = info->accel = XAACreateInfoRec())) return FALSE; + +#ifdef XF86DRI + /* FIXME: When direct rendering is enabled, we should use the CP to + draw 2D commands */ + if (info->CP2D) RADEONCPAccelInit(pScrn, a); + else +#endif + RADEONMMIOAccelInit(pScrn, a); + + RADEONEngineInit(pScrn); + return XAAInit(pScreen, a); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c new file mode 100644 index 000000000..54f8b43d1 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c @@ -0,0 +1,266 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_cursor.c,v 1.1 2000/11/02 16:55:41 tsi Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and VA Linux Systems, Inc., Sunnyvale, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + + /* X and server generic header files */ +#include "Xarch.h" +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86fbman.h" + + /* Driver data structures */ +#include "radeon.h" +#include "radeon_reg.h" + +#if X_BYTE_ORDER == X_BIG_ENDIAN +#define P_SWAP32( a , b ) \ + ((char *)a)[0] = ((char *)b)[3]; \ + ((char *)a)[1] = ((char *)b)[2]; \ + ((char *)a)[2] = ((char *)b)[1]; \ + ((char *)a)[3] = ((char *)b)[0] + +#define P_SWAP16( a , b ) \ + ((char *)a)[0] = ((char *)b)[1]; \ + ((char *)a)[1] = ((char *)b)[0]; \ + ((char *)a)[2] = ((char *)b)[3]; \ + ((char *)a)[3] = ((char *)b)[2] +#endif + + +/* Set cursor foreground and background colors. */ +static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_CUR_CLR0, bg); + OUTREG(RADEON_CUR_CLR1, fg); +} + +/* Set cursor position to (x,y) with offset into cursor bitmap at + (xorigin,yorigin). */ +static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + xf86CursorInfoPtr cursor = info->cursor; + int xorigin = 0; + int yorigin = 0; + int total_y = pScrn->frameY1 - pScrn->frameY0; + + if (x < 0) xorigin = -x; + if (y < 0) yorigin = -y; + if (y > total_y) y = total_y; + if (info->Flags & V_DBLSCAN) y *= 2; + if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; + if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; + + OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK + | (xorigin << 16) + | yorigin)); + OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK + | ((xorigin ? 0 : x) << 16) + | (yorigin ? 0 : y))); + OUTREG(RADEON_CUR_OFFSET, info->cursor_start + yorigin * 16); +} + +/* Copy cursor image from `image' to video memory. RADEONSetCursorPosition + will be called after this, so we can ignore xorigin and yorigin. */ +static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 *s = (CARD32 *)image; + CARD32 *d = (CARD32 *)(info->FB + info->cursor_start); + int y; + CARD32 save; + + save = INREG(RADEON_CRTC_GEN_CNTL); + OUTREG(RADEON_CRTC_GEN_CNTL, save & ~RADEON_CRTC_CUR_EN); + +#if X_BYTE_ORDER == X_BIG_ENDIAN + switch(info->CurrentLayout.pixel_bytes) { + case 4: + case 3: + for (y = 0; y < 64; y++) { + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + P_SWAP32(d,s); + d++; s++; + } + break; + case 2: + for (y = 0; y < 64; y++) { + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + P_SWAP16(d,s); + d++; s++; + } + break; + default: + for (y = 0; y < 64; y++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } + } +#else + for (y = 0; y < 64; y++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + } +#endif + + /* Set the area after the cursor to be all transparent so that we + won't display corrupted cursors on the screen */ + for (y = 0; y < 64; y++) { + *d++ = 0xffffffff; /* The AND bits */ + *d++ = 0xffffffff; + *d++ = 0x00000000; /* The XOR bits */ + *d++ = 0x00000000; + } + + OUTREG(RADEON_CRTC_GEN_CNTL, save); +} + +/* Hide hardware cursor. */ +static void RADEONHideCursor(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN); +} + +/* Show hardware cursor. */ +static void RADEONShowCursor(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, ~RADEON_CRTC_CUR_EN); +} + +/* Determine if hardware cursor is in use. */ +static Bool RADEONUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + return info->cursor_start ? TRUE : FALSE; +} + +/* Initialize hardware cursor support. */ +Bool RADEONCursorInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CursorInfoPtr cursor; + FBAreaPtr fbarea; + int width; + int height; + int size; + + + if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE; + + cursor->MaxWidth = 64; + cursor->MaxHeight = 64; + cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST +#endif + | HARDWARE_CURSOR_INVERT_MASK + | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK + | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 + | HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK); + + cursor->SetCursorColors = RADEONSetCursorColors; + cursor->SetCursorPosition = RADEONSetCursorPosition; + cursor->LoadCursorImage = RADEONLoadCursorImage; + cursor->HideCursor = RADEONHideCursor; + cursor->ShowCursor = RADEONShowCursor; + cursor->UseHWCursor = RADEONUseHWCursor; + + size = (cursor->MaxWidth/4) * cursor->MaxHeight; + width = pScrn->displayWidth; + height = (size*2 + 1023) / pScrn->displayWidth; + fbarea = xf86AllocateOffscreenArea(pScreen, + width, + height, + 16, + NULL, + NULL, + NULL); + + if (!fbarea) { + info->cursor_start = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Hardware cursor disabled" + " due to insufficient offscreen memory\n"); + } else { + info->cursor_start = RADEON_ALIGN((fbarea->box.x1 + + width * fbarea->box.y1) + * info->CurrentLayout.pixel_bytes, + 16); + info->cursor_end = info->cursor_start + size; + } + + RADEONTRACE(("RADEONCursorInit (0x%08x-0x%08x)\n", + info->cursor_start, info->cursor_end)); + + return xf86InitCursor(pScreen, cursor); +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c new file mode 100644 index 000000000..d466d0b67 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c @@ -0,0 +1,355 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dga.c,v 1.2 2000/11/03 09:52:55 alanh Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and VA Linux Systems, Inc., Sunnyvale, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * + * Credits: + * + * Thanks to Ove Kåven <ovek@transgaming.com> for writing the Rage 128 + * DGA support. Portions of this file are based on the initialization + * code for that driver. + * + */ + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + + /* Driver data structures */ +#include "radeon.h" +#include "radeon_probe.h" + + /* DGA support */ +#include "dgaproc.h" + + +static Bool RADEON_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **, + int *, int *, int *); +static Bool RADEON_SetMode(ScrnInfoPtr, DGAModePtr); +static int RADEON_GetViewport(ScrnInfoPtr); +static void RADEON_SetViewport(ScrnInfoPtr, int, int, int); +static void RADEON_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +static void RADEON_BlitRect(ScrnInfoPtr, int, int, int, int, int, int); +#if 0 +static void RADEON_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int, + unsigned long); +#endif + +static +DGAFunctionRec RADEON_DGAFuncs = { + RADEON_OpenFramebuffer, + NULL, + RADEON_SetMode, + RADEON_SetViewport, + RADEON_GetViewport, + RADEONWaitForIdle, + RADEON_FillRect, + RADEON_BlitRect, +#if 0 + RADEON_BlitTransRect +#else + NULL +#endif +}; + + +static DGAModePtr RADEONSetupDGAMode(ScrnInfoPtr pScrn, + DGAModePtr modes, + int *num, + int bitsPerPixel, + int depth, + Bool pixmap, + int secondPitch, + unsigned long red, + unsigned long green, + unsigned long blue, + short visualClass) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + DGAModePtr newmodes = NULL, currentMode; + DisplayModePtr pMode, firstMode; + int otherPitch, Bpp = bitsPerPixel >> 3; + Bool oneMore; + + pMode = firstMode = pScrn->modes; + + while (pMode) { + otherPitch = secondPitch ? secondPitch : pMode->HDisplay; + + if (pMode->HDisplay != otherPitch) { + newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec)); + oneMore = TRUE; + } else { + newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec)); + oneMore = FALSE; + } + + if (!newmodes) { + xfree(modes); + return NULL; + } + modes = newmodes; + +SECOND_PASS: + + currentMode = modes + *num; + (*num)++; + + currentMode->mode = pMode; + /* FIXME: is concurrent access really possible? */ + currentMode->flags = DGA_CONCURRENT_ACCESS; + if (pixmap) + currentMode->flags |= DGA_PIXMAP_AVAILABLE; + if (info->accel) + currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT; + if (pMode->Flags & V_DBLSCAN) + currentMode->flags |= DGA_DOUBLESCAN; + if (pMode->Flags & V_INTERLACE) + currentMode->flags |= DGA_INTERLACED; + currentMode->byteOrder = pScrn->imageByteOrder; + currentMode->depth = depth; + currentMode->bitsPerPixel = bitsPerPixel; + currentMode->red_mask = red; + currentMode->green_mask = green; + currentMode->blue_mask = blue; + currentMode->visualClass = visualClass; + currentMode->viewportWidth = pMode->HDisplay; + currentMode->viewportHeight = pMode->VDisplay; + currentMode->xViewportStep = 8; + currentMode->yViewportStep = 1; + currentMode->viewportFlags = DGA_FLIP_RETRACE; + currentMode->offset = 0; + currentMode->address = (unsigned char*)info->LinearAddr; + + if (oneMore) { /* first one is narrow width */ + currentMode->bytesPerScanline = (((pMode->HDisplay * Bpp) + 3) + & ~3L); + currentMode->imageWidth = pMode->HDisplay; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = currentMode->imageWidth - + currentMode->viewportWidth; + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = (currentMode->imageHeight - + currentMode->viewportHeight); + oneMore = FALSE; + goto SECOND_PASS; + } else { + currentMode->bytesPerScanline = ((otherPitch * Bpp) + 3) & ~3L; + currentMode->imageWidth = otherPitch; + currentMode->imageHeight = pMode->VDisplay; + currentMode->pixmapWidth = currentMode->imageWidth; + currentMode->pixmapHeight = currentMode->imageHeight; + currentMode->maxViewportX = (currentMode->imageWidth - + currentMode->viewportWidth); + /* this might need to get clamped to some maximum */ + currentMode->maxViewportY = (currentMode->imageHeight - + currentMode->viewportHeight); + } + + pMode = pMode->next; + if (pMode == firstMode) + break; + } + + return modes; +} + +Bool RADEONDGAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + DGAModePtr modes = NULL; + int num = 0; + + /* 8 */ + modes = RADEONSetupDGAMode(pScrn, modes, &num, 8, 8, + (pScrn->bitsPerPixel == 8), + ((pScrn->bitsPerPixel != 8) + ? 0 : pScrn->displayWidth), + 0, 0, 0, PseudoColor); + + /* 15 */ + modes = RADEONSetupDGAMode(pScrn, modes, &num, 16, 15, + (pScrn->bitsPerPixel == 16), + ((pScrn->depth != 15) + ? 0 : pScrn->displayWidth), + 0x7c00, 0x03e0, 0x001f, TrueColor); + + modes = RADEONSetupDGAMode(pScrn, modes, &num, 16, 15, + (pScrn->bitsPerPixel == 16), + ((pScrn->depth != 15) + ? 0 : pScrn->displayWidth), + 0x7c00, 0x03e0, 0x001f, DirectColor); + + /* 16 */ + modes = RADEONSetupDGAMode(pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + ((pScrn->depth != 16) + ? 0 : pScrn->displayWidth), + 0xf800, 0x07e0, 0x001f, TrueColor); + + modes = RADEONSetupDGAMode(pScrn, modes, &num, 16, 16, + (pScrn->bitsPerPixel == 16), + ((pScrn->depth != 16) + ? 0 : pScrn->displayWidth), + 0xf800, 0x07e0, 0x001f, DirectColor); + + /* 32 */ + modes = RADEONSetupDGAMode(pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + ((pScrn->bitsPerPixel != 32) + ? 0 : pScrn->displayWidth), + 0xff0000, 0x00ff00, 0x0000ff, TrueColor); + + modes = RADEONSetupDGAMode(pScrn, modes, &num, 32, 24, + (pScrn->bitsPerPixel == 32), + ((pScrn->bitsPerPixel != 32) + ? 0 : pScrn->displayWidth), + 0xff0000, 0x00ff00, 0x0000ff, DirectColor); + + info->numDGAModes = num; + info->DGAModes = modes; + + return DGAInit(pScreen, &RADEON_DGAFuncs, modes, num); +} + +static Bool RADEON_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode) +{ + static RADEONFBLayout SavedLayouts[MAXSCREENS]; + int indx = pScrn->pScreen->myNum; + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (!pMode) { /* restore the original mode */ + /* put the ScreenParameters back */ + if (info->DGAactive) + memcpy(&info->CurrentLayout, &SavedLayouts[indx], + sizeof(RADEONFBLayout)); + + pScrn->currentMode = info->CurrentLayout.mode; + + RADEONSwitchMode(indx, pScrn->currentMode, 0); + RADEONAdjustFrame(indx, 0, 0, 0); + info->DGAactive = FALSE; + } else { + if (!info->DGAactive) { /* save the old parameters */ + memcpy(&SavedLayouts[indx], &info->CurrentLayout, + sizeof(RADEONFBLayout)); + info->DGAactive = TRUE; + } + + info->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel; + info->CurrentLayout.depth = pMode->depth; + info->CurrentLayout.displayWidth = (pMode->bytesPerScanline / + (pMode->bitsPerPixel >> 3)); + info->CurrentLayout.pixel_bytes = pMode->bitsPerPixel / 8; + info->CurrentLayout.pixel_code = (pMode->bitsPerPixel != 16 + ? pMode->bitsPerPixel + : pMode->depth); + /* RADEONModeInit() will set the mode field */ + + RADEONSwitchMode(indx, pMode->mode, 0); + } + + return TRUE; +} + +static int RADEON_GetViewport(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + return info->DGAViewportStatus; +} + +static void RADEON_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + RADEONAdjustFrame(pScrn->pScreen->myNum, x, y, flags); + info->DGAViewportStatus = 0; /* FIXME */ +} + +static void RADEON_FillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned long color) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->accel) { + (*info->accel->SetupForSolidFill)(pScrn, color, GXcopy, ~0); + (*info->accel->SubsequentSolidFillRect)(pScrn, x, y, w, h); + SET_SYNC_FLAG(info->accel); + } +} + +static void RADEON_BlitRect(ScrnInfoPtr pScrn, + int srcx, int srcy, int w, int h, + int dstx, int dsty) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->accel) { + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + + (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, + GXcopy, ~0, -1); + (*info->accel->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy, + dstx, dsty, w, h); + SET_SYNC_FLAG(info->accel); + } +} + +#if 0 +static void RADEON_BlitTransRect(ScrnInfoPtr pScrn, + int srcx, int srcy, int w, int h, + int dstx, int dsty, unsigned long color) +{ + /* this one should be separate since the XAA function would prohibit + usage of ~0 as the key */ +} +#endif + +static Bool RADEON_OpenFramebuffer(ScrnInfoPtr pScrn, + char **name, + unsigned char **mem, + int *size, int *offset, int *flags) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + *name = NULL; /* no special device */ + *mem = (unsigned char*)info->LinearAddr; + *size = info->FbMapSize; + *offset = 0; + *flags = 0; /* DGA_NEED_ROOT; -- don't need root, just /dev/mem access */ + + return TRUE; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c new file mode 100644 index 000000000..0fa24a9b7 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c @@ -0,0 +1,2953 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v 1.2 2000/11/03 09:52:55 alanh Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markhom, Ontario + * and VA Linux Systems, Inc., Sunnyvale, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * + * Credits: + * + * Thanks to Ani Joshi <ajoshi@shell.unixbox.com> for providing source + * code to his Radeon driver. Portions of this file are based on the + * initialization code for that driver. + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + * This server does not yet support these XFree86 4.0 features: + * !!!! FIXME !!!! + * DDC1 & DDC2 + * shadowfb + * overlay planes + * + * Modified by Marc Aurele La France (tsi@xfree86.org) for ATI driver merge. + */ + + /* X and server generic header files */ +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86RAC.h" +#include "xf86cmap.h" +#include "xf86fbman.h" +#include "xf86int10.h" + /* Backing store, software cursor, and + colormap initialization */ +#include "mibstore.h" +#include "mipointer.h" +#include "micmap.h" + +#define USE_FB /* not until overlays */ +#ifdef USE_FB +#include "fb.h" +#else + /* CFB support */ +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" +#include "cfb24_32.h" +#endif + + /* Driver data structures */ +#include "radeon.h" +#include "radeon_probe.h" +#include "radeon_reg.h" +#include "radeon_version.h" + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + + + /* Forward definitions for driver functions */ +static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode); +static void RADEONSave(ScrnInfoPtr pScrn); +static void RADEONRestore(ScrnInfoPtr pScrn); +static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, + int flags); +static Bool RADEONEnterVTFBDev(int scrnIndex, int flags); +static void RADEONLeaveVTFBDev(int scrnIndex, int flags); + +typedef enum { + OPTION_NOACCEL, + OPTION_SW_CURSOR, + OPTION_DAC_6BIT, + OPTION_DAC_8BIT, +#ifdef XF86DRI + OPTION_IS_PCI, + OPTION_CP_PIO, + OPTION_NO_SECURITY, + OPTION_USEC_TIMEOUT, + OPTION_AGP_MODE, + OPTION_AGP_SIZE, + OPTION_RING_SIZE, + OPTION_VERT_SIZE, + OPTION_VBUF_SIZE, + OPTION_USE_CP_2D, +#endif +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ +#if 0 + /* FIXME: Disable CRTOnly until it is tested */ + OPTION_CRT, +#endif + OPTION_PANEL_WIDTH, + OPTION_PANEL_HEIGHT, +#endif + OPTION_FBDEV +} RADEONOpts; + +OptionInfoRec RADEONOptions[] = { + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DAC_8BIT, "Dac8Bit", OPTV_BOOLEAN, {0}, TRUE }, +#ifdef XF86DRI + { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CP_PIO, "CPPIOMode", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_NO_SECURITY, "CPNoSecurity", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_USEC_TIMEOUT, "CPusecTimeout", OPTV_INTEGER, {0}, FALSE }, + { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, + { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VERT_SIZE, "VBListSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_VBUF_SIZE, "VBSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_USE_CP_2D, "UseCPfor2D", OPTV_BOOLEAN, {0}, FALSE }, +#endif +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ +#if 0 + /* FIXME: Disable CRTOnly until it is tested */ + { OPTION_CRT, "CRTOnly", OPTV_BOOLEAN, {0}, FALSE }, +#endif + { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE }, + { OPTION_PANEL_HEIGHT, "PanelHeight", OPTV_INTEGER, {0}, FALSE }, +#endif + { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +RADEONRAMRec RADEONRAM[] = { /* Memory Specifications + From Radeon Manual */ + { 4, 4, 1, 2, 1, 2, 1, 16, 12, "64-bit SDR SDRAM" }, + { 4, 4, 3, 3, 2, 3, 1, 16, 12, "64-bit DDR SDRAM" }, +}; + +static const char *vgahwSymbols[] = { + "vgaHWGetHWRec", + "vgaHWFreeHWRec", + "vgaHWLock", + "vgaHWUnlock", + "vgaHWSave", + "vgaHWRestore", + NULL +}; + +static const char *fbdevHWSymbols[] = { + "fbdevHWInit", + "fbdevHWUseBuildinMode", + + "fbdevHWGetDepth", + "fbdevHWGetVidmem", + + /* colormap */ + "fbdevHWLoadPalette", + + /* ScrnInfo hooks */ + "fbdevHWSwitchMode", + "fbdevHWAdjustFrame", + "fbdevHWEnterVT", + "fbdevHWLeaveVT", + "fbdevHWValidMode", + "fbdevHWRestore", + "fbdevHWModeInit", + "fbdevHWSave", + + "fbdevHWUnmapMMIO", + "fbdevHWUnmapVidmem", + "fbdevHWMapMMIO", + "fbdevHWMapVidmem", + + NULL +}; + +static const char *ddcSymbols[] = { + "xf86PrintEDID", + "xf86DoEDID_DDC1", + "xf86DoEDID_DDC2", + NULL +}; + +#ifdef XFree86LOADER +#ifdef USE_FB +static const char *fbSymbols[] = { + "fbScreenInit", + NULL +}; +#else +static const char *cfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + "cfb24_32ScreenInit", + NULL +}; +#endif + +static const char *xaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + "XAAStippleScanlineFuncLSBFirst", + "XAAOverlayFBfuncs", + "XAACachePlanarMonoStipple", + "XAAScreenIndex", + NULL +}; + +static const char *xf8_32bppSymbols[] = { + "xf86Overlay8Plus32Init", + NULL +}; + +static const char *ramdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +#ifdef XF86DRI +static const char *drmSymbols[] = { + "drmAddBufs", + "drmAddMap", + "drmAvailable", + "drmCtlAddCommand", + "drmCtlInstHandler", + "drmGetInterruptFromBusID", + "drmMapBufs", + "drmMarkBufs", + "drmUnmapBufs", + "drmFreeVersion", + "drmGetVersion", + NULL +}; + +static const char *driSymbols[] = { + "DRIGetDrawableIndex", + "DRIFinishScreenInit", + "DRIDestroyInfoRec", + "DRICloseScreen", + "DRIDestroyInfoRec", + "DRIScreenInit", + "DRIDestroyInfoRec", + "DRICreateInfoRec", + "DRILock", + "DRIUnlock", + "DRIGetSAREAPrivate", + "DRIGetContext", + "DRIQueryVersion", + "GlxSetVisualConfigs", + NULL +}; +#endif + +static const char *vbeSymbols[] = { + "VBEInit", + "vbeDoEDID", + NULL +}; +#endif + +/* Allocate our private RADEONInfoRec. */ +static Bool RADEONGetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate) return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(RADEONInfoRec), 1); + return TRUE; +} + +/* Free our private RADEONInfoRec. */ +static void RADEONFreeRec(ScrnInfoPtr pScrn) +{ + if (!pScrn || !pScrn->driverPrivate) return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} + +/* Memory map the MMIO region. Used during pre-init and by RADEONMapMem, + below. */ +static Bool RADEONMapMMIO(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->FBDev) { + info->MMIO = fbdevHWMapMMIO(pScrn); + } else { + info->MMIO = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, + info->PciTag, + info->MMIOAddr, + RADEON_MMIOSIZE); + } + + if (!info->MMIO) return FALSE; + return TRUE; +} + +/* Unmap the MMIO region. Used during pre-init and by RADEONUnmapMem, + below. */ +static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->FBDev) + fbdevHWUnmapMMIO(pScrn); + else { + xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, RADEON_MMIOSIZE); + } + info->MMIO = NULL; + return TRUE; +} + +/* Memory map the frame buffer. Used by RADEONMapMem, below. */ +static Bool RADEONMapFB(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->FBDev) { + info->FB = fbdevHWMapVidmem(pScrn); + } else { + info->FB = xf86MapPciMem(pScrn->scrnIndex, + VIDMEM_FRAMEBUFFER, + info->PciTag, + info->LinearAddr, + info->FbMapSize); + } + + if (!info->FB) return FALSE; + return TRUE; +} + +/* Unmap the frame buffer. Used by RADEONUnmapMem, below. */ +static Bool RADEONUnmapFB(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->FBDev) + fbdevHWUnmapVidmem(pScrn); + else + xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize); + info->FB = NULL; + return TRUE; +} + +/* Memory map the MMIO region and the frame buffer. */ +static Bool RADEONMapMem(ScrnInfoPtr pScrn) +{ + if (!RADEONMapMMIO(pScrn)) return FALSE; + if (!RADEONMapFB(pScrn)) { + RADEONUnmapMMIO(pScrn); + return FALSE; + } + return TRUE; +} + +/* Unmap the MMIO region and the frame buffer. */ +static Bool RADEONUnmapMem(ScrnInfoPtr pScrn) +{ + if (!RADEONUnmapMMIO(pScrn) || !RADEONUnmapFB(pScrn)) return FALSE; + return TRUE; +} + +/* Read PLL information */ +unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + +#if !RADEON_ATOMIC_UPDATE + while ( (INREG8(RADEON_CLOCK_CNTL_INDEX) & 0x9f) != addr) { +#endif + OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); +#if !RADEON_ATOMIC_UPDATE + } +#endif + return INREG(RADEON_CLOCK_CNTL_DATA); +} + +#if 0 +/* Read PAL information (only used for debugging). */ +static int RADEONINPAL(int idx) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_PALETTE_INDEX, idx << 16); + return INREG(RADEON_PALETTE_DATA); +} +#endif + +/* Wait for vertical sync. */ +void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + OUTREG(RADEON_GEN_INT_STATUS, RADEON_VSYNC_INT_AK); + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (INREG(RADEON_GEN_INT_STATUS) & RADEON_VSYNC_INT) break; + } +} + +/* Blank screen. */ +static void RADEONBlank(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREGP(RADEON_CRTC_EXT_CNTL, + RADEON_CRTC_DISPLAY_DIS | + RADEON_CRTC_VSYNC_DIS | + RADEON_CRTC_HSYNC_DIS, + ~(RADEON_CRTC_DISPLAY_DIS | + RADEON_CRTC_VSYNC_DIS | + RADEON_CRTC_HSYNC_DIS)); +} + +/* Unblank screen. */ +static void RADEONUnblank(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREGP(RADEON_CRTC_EXT_CNTL, 0, + ~(RADEON_CRTC_DISPLAY_DIS | + RADEON_CRTC_VSYNC_DIS | + RADEON_CRTC_HSYNC_DIS)); +} + +/* Compute log base 2 of val. */ +int RADEONMinBits(int val) +{ + int bits; + + if (!val) return 1; + for (bits = 0; val; val >>= 1, ++bits); + return bits; +} + +/* Compute n/d with rounding. */ +static int RADEONDiv(int n, int d) +{ + return (n + (d / 2)) / d; +} + +/* Read the Video BIOS block and the FP registers (if applicable). */ +static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); +#ifdef ENABLE_FLAT_PANEL + int i; + int FPHeader = 0; +#endif + +#define RADEONReadBIOS(offset, buffer, length) \ + (info->BIOSFromPCI ? \ + xf86ReadPciBIOS(offset, info->PciTag, 0, buffer, length) : \ + xf86ReadBIOS(info->BIOSAddr, offset, buffer, length)) + +#define RADEON_BIOS8(v) (info->VBIOS[v]) +#define RADEON_BIOS16(v) (info->VBIOS[v] | \ + (info->VBIOS[(v) + 1] << 8)) +#define RADEON_BIOS32(v) (info->VBIOS[v] | \ + (info->VBIOS[(v) + 1] << 8) | \ + (info->VBIOS[(v) + 2] << 16) | \ + (info->VBIOS[(v) + 3] << 24)) + + if (!(info->VBIOS = xalloc(RADEON_VBIOS_SIZE))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Cannot allocate space for hold Video BIOS!\n"); + return FALSE; + } + + info->BIOSFromPCI = TRUE; + RADEONReadBIOS(0x0000, info->VBIOS, RADEON_VBIOS_SIZE); + if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not detected in PCI space!\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Attempting to read Video BIOS from legacy ISA space!\n"); + info->BIOSFromPCI = FALSE; + info->BIOSAddr = 0x000c0000; + RADEONReadBIOS(0x0000, info->VBIOS, RADEON_VBIOS_SIZE); + } + if (info->VBIOS[0] != 0x55 || info->VBIOS[1] != 0xaa) { + info->BIOSAddr = 0x00000000; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not found!\n"); + } + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) { + info->FPBIOSstart = 0; + + /* FIXME: There should be direct access to the start of the FP info + tables, but until we find out where that offset is stored, we + must search for the ATI signature string: "M3 ". */ + for (i = 4; i < RADEON_VBIOS_SIZE-8; i++) { + if (RADEON_BIOS8(i) == 'M' && + RADEON_BIOS8(i+1) == '3' && + RADEON_BIOS8(i+2) == ' ' && + RADEON_BIOS8(i+3) == ' ' && + RADEON_BIOS8(i+4) == ' ' && + RADEON_BIOS8(i+5) == ' ' && + RADEON_BIOS8(i+6) == ' ' && + RADEON_BIOS8(i+7) == ' ') { + FPHeader = i-2; + break; + } + } + + if (!FPHeader) return TRUE; + + /* Assume that only one panel is attached and supported */ + for (i = FPHeader+20; i < FPHeader+84; i += 2) { + if (RADEON_BIOS16(i) != 0) { + info->FPBIOSstart = RADEON_BIOS16(i); + break; + } + } + if (!info->FPBIOSstart) return TRUE; + + if (!info->PanelXRes) + info->PanelXRes = RADEON_BIOS16(info->FPBIOSstart+25); + if (!info->PanelYRes) + info->PanelYRes = RADEON_BIOS16(info->FPBIOSstart+27); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size: %dx%d\n", + info->PanelXRes, info->PanelYRes); + + info->PanelPwrDly = RADEON_BIOS8(info->FPBIOSstart+56); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel ID: "); + for (i = 1; i <= 24; i++) + ErrorF("%c", RADEON_BIOS8(info->FPBIOSstart+i)); + ErrorF("\n"); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Type: "); + i = RADEON_BIOS16(info->FPBIOSstart+29); + if (i & 1) ErrorF("Color, "); + else ErrorF("Monochrome, "); + if (i & 2) ErrorF("Dual(split), "); + else ErrorF("Single, "); + switch ((i >> 2) & 0x3f) { + case 0: ErrorF("STN"); break; + case 1: ErrorF("TFT"); break; + case 2: ErrorF("Active STN"); break; + case 3: ErrorF("EL"); break; + case 4: ErrorF("Plasma"); break; + default: ErrorF("UNKNOWN"); break; + } + ErrorF("\n"); + if (RADEON_BIOS8(info->FPBIOSstart+61) & 1) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Interface: LVDS\n"); + } else { + /* FIXME: Add Non-LVDS flat pael support */ + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Non-LVDS panel interface detected! " + "This support is untested and may not " + "function properly\n"); + } + } +#endif + + return TRUE; +} + +/* Read PLL parameters from BIOS block. Default to typical values if there + is no BIOS. */ +static Bool RADEONGetPLLParameters(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONPLLPtr pll = &info->pll; + CARD16 bios_header; + CARD16 pll_info_block; + + if (!info->VBIOS) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Video BIOS not detected, using default PLL parameters!\n"); + /* These probably aren't going to work for + the card you are using. Specifically, + reference freq can be 29.50MHz, + 28.63MHz, or 14.32MHz. YMMV. */ + pll->reference_freq = 2950; + pll->reference_div = 65; + pll->min_pll_freq = 12500; + pll->max_pll_freq = 35000; + pll->xclk = 10300; + } else { + bios_header = RADEON_BIOS16(0x48); + pll_info_block = RADEON_BIOS16(bios_header + 0x30); + RADEONTRACE(("Header at 0x%04x; PLL Information at 0x%04x\n", + bios_header, pll_info_block)); + + pll->reference_freq = RADEON_BIOS16(pll_info_block + 0x0e); + pll->reference_div = RADEON_BIOS16(pll_info_block + 0x10); + pll->min_pll_freq = RADEON_BIOS32(pll_info_block + 0x12); + pll->max_pll_freq = RADEON_BIOS32(pll_info_block + 0x16); + pll->xclk = RADEON_BIOS16(pll_info_block + 0x08); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n", + pll->reference_freq, + pll->reference_div, + pll->min_pll_freq, + pll->max_pll_freq, + pll->xclk); + + return TRUE; +} + +/* This is called by RADEONPreInit to set up the default visual. */ +static Bool RADEONPreInitVisual(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support32bppFb)) + return FALSE; + + switch (pScrn->depth) { + case 8: + case 15: + case 16: + case 24: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by %s driver\n", + pScrn->depth, RADEON_DRIVER_NAME); + return FALSE; + } + + xf86PrintDepthBpp(pScrn); + + info->fifo_slots = 0; + info->pix24bpp = xf86GetBppFromDepth(pScrn, pScrn->depth); + info->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; + info->CurrentLayout.depth = pScrn->depth; + info->CurrentLayout.pixel_bytes = pScrn->bitsPerPixel / 8; + info->CurrentLayout.pixel_code = (pScrn->bitsPerPixel != 16 + ? pScrn->bitsPerPixel + : pScrn->depth); + + if (info->pix24bpp == 24) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Radeon does NOT support 24bpp\n"); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n", + pScrn->depth, + info->CurrentLayout.pixel_bytes, + info->CurrentLayout.pixel_bytes > 1 ? "s" : "", + info->pix24bpp); + + + if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; + + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Default visual (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + return TRUE; + +} + +/* This is called by RADEONPreInit to handle all color weight issues. */ +static Bool RADEONPreInitWeight(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + /* Save flag for 6 bit DAC to use for + setting CRTC registers. Otherwise use + an 8 bit DAC, even if xf86SetWeight sets + pScrn->rgbBits to some value other than + 8. */ + info->dac6bits = FALSE; + if (pScrn->depth > 8) { + rgb defaultWeight = { 0, 0, 0 }; + if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE; + } else { + pScrn->rgbBits = 8; + if (xf86ReturnOptValBool(RADEONOptions, OPTION_DAC_6BIT, FALSE)) { + pScrn->rgbBits = 6; + info->dac6bits = TRUE; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d bits per RGB (%d bit DAC)\n", + pScrn->rgbBits, info->dac6bits ? 6 : 8); + + return TRUE; + +} + +/* This is called by RADEONPreInit to handle config file overrides for things + like chipset and memory regions. Also determine memory size and type. + If memory type ever needs an override, put it in this routine. */ +static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + EntityInfoPtr pEnt = info->pEnt; + GDevPtr dev = pEnt->device; + int offset = 0; /* RAM Type */ + MessageType from; + unsigned char *RADEONMMIO; + + /* Chipset */ + from = X_PROBED; + if (dev->chipset && *dev->chipset) { + info->Chipset = xf86StringToToken(RADEONChipsets, dev->chipset); + from = X_CONFIG; + } else if (dev->chipID >= 0) { + info->Chipset = dev->chipID; + from = X_CONFIG; + } else { + info->Chipset = info->PciInfo->chipType; + } + pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset); + + if (!pScrn->chipset) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ChipID 0x%04x is not recognized\n", info->Chipset); + return FALSE; + } + + if (info->Chipset < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Chipset \"%s\" is not recognized\n", pScrn->chipset); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, from, + "Chipset: \"%s\" (ChipID = 0x%04x)\n", + pScrn->chipset, + info->Chipset); + + /* Framebuffer */ + + from = X_PROBED; + info->LinearAddr = info->PciInfo->memBase[0] & 0xfc000000; + if (dev->MemBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Linear address override, using 0x%08x instead of 0x%08x\n", + dev->MemBase, + info->LinearAddr); + info->LinearAddr = dev->MemBase; + from = X_CONFIG; + } else if (!info->LinearAddr) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No valid linear framebuffer address\n"); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, + "Linear framebuffer at 0x%08lx\n", info->LinearAddr); + + /* MMIO registers */ + from = X_PROBED; + info->MMIOAddr = info->PciInfo->memBase[2] & 0xffffff00; + if (dev->IOBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MMIO address override, using 0x%08x instead of 0x%08x\n", + dev->IOBase, + info->MMIOAddr); + info->MMIOAddr = dev->IOBase; + from = X_CONFIG; + } else if (!info->MMIOAddr) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid MMIO address\n"); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, + "MMIO registers at 0x%08lx\n", info->MMIOAddr); + + /* BIOS */ + from = X_PROBED; + info->BIOSAddr = info->PciInfo->biosBase & 0xfffe0000; + if (dev->BiosBase) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "BIOS address override, using 0x%08x instead of 0x%08x\n", + dev->BiosBase, + info->BIOSAddr); + info->BIOSAddr = dev->BiosBase; + from = X_CONFIG; + } + if (info->BIOSAddr) { + xf86DrvMsg(pScrn->scrnIndex, from, + "BIOS at 0x%08lx\n", info->BIOSAddr); + } + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Flat panel (part 1) */ + /* FIXME: Make this an option */ + switch (info->Chipset) { +#if 0 + case PCI_CHIP_RADEON_XX: info->HasPanelRegs = TRUE; break; +#endif + case PCI_CHIP_RADEON_QD: + case PCI_CHIP_RADEON_QE: + case PCI_CHIP_RADEON_QF: + case PCI_CHIP_RADEON_QG: + default: info->HasPanelRegs = FALSE; break; + } +#endif + + /* Read registers used to determine options */ + from = X_PROBED; + RADEONMapMMIO(pScrn); + RADEONMMIO = info->MMIO; + if (info->FBDev) + pScrn->videoRam = fbdevHWGetVidmem(pScrn) / 1024; + else + pScrn->videoRam = INREG(RADEON_CONFIG_MEMSIZE) / 1024; + info->MemCntl = INREG(RADEON_SDRAM_MODE_REG); + info->BusCntl = INREG(RADEON_BUS_CNTL); + RADEONMMIO = NULL; + RADEONUnmapMMIO(pScrn); + + /* RAM */ + switch (info->MemCntl >> 30) { + case 0: offset = 0; break; /* 64-bit SDR SDRAM */ + case 1: offset = 1; break; /* 64-bit DDR SDRAM */ + default: offset = 0; + } + info->ram = &RADEONRAM[offset]; + + if (dev->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Video RAM override, using %d kB instead of %d kB\n", + dev->videoRam, + pScrn->videoRam); + from = X_CONFIG; + pScrn->videoRam = dev->videoRam; + } + pScrn->videoRam &= ~1023; + info->FbMapSize = pScrn->videoRam * 1024; + xf86DrvMsg(pScrn->scrnIndex, from, + "VideoRAM: %d kByte (%s)\n", pScrn->videoRam, info->ram->name); + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Flat panel (part 2) */ + if (info->HasPanelRegs) { +#if 1 + info->CRTOnly = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using flat panel for display\n"); +#else + /* Panel CRT mode override */ + if ((info->CRTOnly = xf86ReturnOptValBool(RADEONOptions, + OPTION_CRT, FALSE))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using external CRT instead of " + "flat panel for display\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using flat panel for display\n"); + } +#endif + + /* Panel width/height overrides */ + info->PanelXRes = 0; + info->PanelYRes = 0; + if (xf86GetOptValInteger(RADEONOptions, + OPTION_PANEL_WIDTH, &(info->PanelXRes))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Flat panel width: %d\n", info->PanelXRes); + } + if (xf86GetOptValInteger(RADEONOptions, + OPTION_PANEL_HEIGHT, &(info->PanelYRes))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Flat panel height: %d\n", info->PanelYRes); + } + } else { + info->CRTOnly = FALSE; + } +#endif + +#ifdef XF86DRI + /* AGP/PCI */ + if (xf86ReturnOptValBool(RADEONOptions, OPTION_IS_PCI, FALSE)) { + info->IsPCI = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forced into PCI-only mode\n"); + } else { + switch (info->Chipset) { +#if 0 + case PCI_CHIP_RADEON_XX: info->IsPCI = TRUE; break; +#endif + case PCI_CHIP_RADEON_QD: + case PCI_CHIP_RADEON_QE: + case PCI_CHIP_RADEON_QF: + case PCI_CHIP_RADEON_QG: + default: info->IsPCI = FALSE; break; + } + } +#endif + + return TRUE; +} + +static Bool RADEONPreInitDDC(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + vbeInfoPtr pVbe; + + if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE; + xf86LoaderReqSymLists(ddcSymbols, NULL); + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,info->pEnt->index); + if (!pVbe) return FALSE; + + xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); + return TRUE; + } else + return FALSE; +} + +/* This is called by RADEONPreInit to initialize gamma correction. */ +static Bool RADEONPreInitGamma(ScrnInfoPtr pScrn) +{ + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScrn, zeros)) return FALSE; + return TRUE; +} + +/* This is called by RADEONPreInit to validate modes and compute parameters + for all of the valid modes. */ +static Bool RADEONPreInitModes(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + ClockRangePtr clockRanges; + int modesFound; + char *mod = NULL; + const char *Sym = NULL; + + /* Get mode information */ + pScrn->progClock = TRUE; + clockRanges = xnfcalloc(sizeof(*clockRanges), 1); + clockRanges->next = NULL; + clockRanges->minClock = info->pll.min_pll_freq; + clockRanges->maxClock = info->pll.max_pll_freq * 10; + clockRanges->clockIndex = -1; +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) { + clockRanges->interlaceAllowed = FALSE; + clockRanges->doubleScanAllowed = FALSE; + } else { + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = TRUE; + } +#else + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = TRUE; +#endif + + modesFound = xf86ValidateModes(pScrn, + pScrn->monitor->Modes, + pScrn->display->modes, + clockRanges, + NULL, /* linePitches */ + 8 * 64, /* minPitch */ + 8 * 1024, /* maxPitch */ + 64 * pScrn->bitsPerPixel, /* pitchInc */ + 128, /* minHeight */ + 2048, /* maxHeight */ + pScrn->virtualX, + pScrn->virtualY, + info->FbMapSize, + LOOKUP_BEST_REFRESH); + + if (modesFound < 1 && info->FBDev) { + fbdevHWUseBuildinMode(pScrn); + pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ + modesFound = 1; + } + + if (modesFound == -1) return FALSE; + xf86PruneDriverModes(pScrn); + if (!modesFound || !pScrn->modes) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); + return FALSE; + } + xf86SetCrtcForModes(pScrn, 0); + pScrn->currentMode = pScrn->modes; + xf86PrintModes(pScrn); + + /* Set DPI */ + xf86SetDpi(pScrn, 0, 0); + + /* Get ScreenInit function */ +#ifdef USE_FB + mod = "fb"; + Sym = "fbScreenInit"; +#else + switch (pScrn->bitsPerPixel) { + case 8: mod = "cfb"; Sym = "cfbScreenInit"; break; + case 16: mod = "cfb16"; Sym = "cfb16ScreenInit"; break; + case 32: mod = "cfb32"; Sym = "cfb32ScreenInit"; break; + } +#endif + if (mod && !xf86LoadSubModule(pScrn, mod)) return FALSE; + xf86LoaderReqSymbols(Sym, NULL); + +#ifdef USE_FB +#ifdef RENDER + xf86LoaderReqSymbols("fbPictureInit", NULL); +#endif +#endif + + info->CurrentLayout.displayWidth = pScrn->displayWidth; + info->CurrentLayout.mode = pScrn->currentMode; + + return TRUE; +} + +/* This is called by RADEONPreInit to initialize the hardware cursor. */ +static Bool RADEONPreInitCursor(ScrnInfoPtr pScrn) +{ + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_SW_CURSOR, FALSE)) { + if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE; + } + return TRUE; +} + +/* This is called by RADEONPreInit to initialize hardware acceleration. */ +static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) +{ + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_NOACCEL, FALSE)) { + if (!xf86LoadSubModule(pScrn, "xaa")) return FALSE; + } + return TRUE; +} + +static Bool RADEONPreInitInt10(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); +#if 1 + if (xf86LoadSubModule(pScrn, "int10")) { + xf86Int10InfoPtr pInt; + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); + pInt = xf86InitInt10(info->pEnt->index); + xf86FreeInt10(pInt); + } +#endif + return TRUE; +} + +#ifdef XF86DRI +static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->IsPCI) { + info->CPMode = RADEON_DEFAULT_CP_PIO_MODE; + } else if (xf86ReturnOptValBool(RADEONOptions, OPTION_CP_PIO, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CP into PIO mode\n"); + info->CPMode = RADEON_DEFAULT_CP_PIO_MODE; + } else { + info->CPMode = RADEON_DEFAULT_CP_BM_MODE; + } + + if (xf86ReturnOptValBool(RADEONOptions, OPTION_USE_CP_2D, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using CP for 2D\n"); + info->CP2D = TRUE; + } else { + info->CP2D = FALSE; + } + + if (xf86ReturnOptValBool(RADEONOptions, OPTION_NO_SECURITY, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "WARNING!!! CP Security checks disabled!!! **********\n"); + info->CPSecure = FALSE; + } else { + info->CPSecure = TRUE; + } + + info->agpMode = RADEON_DEFAULT_AGP_MODE; + info->agpSize = RADEON_DEFAULT_AGP_SIZE; + info->ringSize = RADEON_DEFAULT_RING_SIZE; + info->vbSize = RADEON_DEFAULT_VB_SIZE; + info->indSize = RADEON_DEFAULT_IND_SIZE; + info->agpTexSize = RADEON_DEFAULT_AGP_TEX_SIZE; + + info->vbBufSize = RADEON_DEFAULT_VB_BUF_SIZE; + + info->CPusecTimeout = RADEON_DEFAULT_CP_TIMEOUT; + + if (!info->IsPCI) { + if (xf86GetOptValInteger(RADEONOptions, + OPTION_AGP_MODE, &(info->agpMode))) { + if (info->agpMode < 1 || info->agpMode > RADEON_AGP_MAX_MODE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal AGP Mode: %d\n", info->agpMode); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using AGP %dx mode\n", info->agpMode); + } + + if (xf86GetOptValInteger(RADEONOptions, + OPTION_AGP_SIZE, (int *)&(info->agpSize))) { + switch (info->agpSize) { + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal AGP size: %d MB\n", info->agpSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(RADEONOptions, + OPTION_RING_SIZE, &(info->ringSize))) { + if (info->ringSize < 1 || info->ringSize >= info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal ring buffer size: %d MB\n", + info->ringSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(RADEONOptions, + OPTION_VERT_SIZE, &(info->vbSize))) { + if (info->vbSize < 1 || info->vbSize >= info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal vertex buffers list size: %d MB\n", + info->vbSize); + return FALSE; + } + } + + if (xf86GetOptValInteger(RADEONOptions, + OPTION_VBUF_SIZE, &(info->vbBufSize))) { + int numBufs = info->vbSize*1024*1024/info->vbBufSize; + if (numBufs < 2 || numBufs > 512) { /* FIXME: 512 is arbitrary */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Illegal individual vertex buffer size: %d bytes\n", + info->vbBufSize); + return FALSE; + } + } + + if (info->ringSize + info->vbSize + info->indSize + info->agpTexSize > + info->agpSize) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Buffers are too big for requested AGP space\n"); + return FALSE; + } + + info->agpTexSize = info->agpSize - (info->ringSize + + info->vbSize + + info->indSize); + } + + if (xf86GetOptValInteger(RADEONOptions, OPTION_USEC_TIMEOUT, + &(info->CPusecTimeout))) { + /* This option checked by the RADEON DRM kernel module */ + } + + return TRUE; +} +#endif + +static void +RADEONProbeDDC(ScrnInfoPtr pScrn, int indx) +{ + vbeInfoPtr pVbe; + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,indx); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + } +} + +/* RADEONPreInit is called once at server startup. */ +Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) +{ + RADEONInfoPtr info; + +#ifdef XFree86LOADER + /* + * Tell the loader about symbols from other modules that this module might + * refer to. + */ + LoaderRefSymLists(vgahwSymbols, +#ifdef USE_FB + fbSymbols, +#else + cfbSymbols, +#endif + xaaSymbols, + xf8_32bppSymbols, + ramdacSymbols, +#ifdef XF86DRI + drmSymbols, + driSymbols, +#endif + fbdevHWSymbols, + vbeSymbols, + /* ddcsymbols, */ + /* i2csymbols, */ + /* shadowSymbols, */ + NULL); +#endif + + RADEONTRACE(("RADEONPreInit\n")); + if (pScrn->numEntities != 1) return FALSE; + + if (!RADEONGetRec(pScrn)) return FALSE; + + info = RADEONPTR(pScrn); + + info->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (info->pEnt->location.type != BUS_PCI) goto fail; + + if (flags & PROBE_DETECT) { + RADEONProbeDDC(pScrn, info->pEnt->index); + return TRUE; + } + + if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; + xf86LoaderReqSymLists(vgahwSymbols, NULL); + if (!vgaHWGetHWRec(pScrn)) { + RADEONFreeRec(pScrn); + return FALSE; + } + + info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index); + info->PciTag = pciTag(info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "PCI bus %d card %d func %d\n", + info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + + if (xf86RegisterResources(info->pEnt->index, 0, ResNone)) goto fail; + + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP; + pScrn->monitor = pScrn->confScreen->monitor; + + if (!RADEONPreInitVisual(pScrn)) goto fail; + + /* We can't do this until we have a + pScrn->display. */ + xf86CollectOptions(pScrn, NULL); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, RADEONOptions); + + if (!RADEONPreInitWeight(pScrn)) goto fail; + + if (xf86ReturnOptValBool(RADEONOptions, OPTION_FBDEV, FALSE)) { + info->FBDev = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using framebuffer device\n"); + } + + if (info->FBDev) { + /* check for linux framebuffer device */ + if (!xf86LoadSubModule(pScrn, "fbdevhw")) return FALSE; + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + if (!fbdevHWInit(pScrn, info->PciInfo, NULL)) return FALSE; + pScrn->SwitchMode = fbdevHWSwitchMode; + pScrn->AdjustFrame = fbdevHWAdjustFrame; + pScrn->EnterVT = RADEONEnterVTFBDev; + pScrn->LeaveVT = RADEONLeaveVTFBDev; + pScrn->ValidMode = fbdevHWValidMode; + } + + if (!info->FBDev) + if (!RADEONPreInitInt10(pScrn)) goto fail; + + if (!RADEONPreInitConfig(pScrn)) goto fail; + + if (!RADEONGetBIOSParameters(pScrn)) goto fail; + + if (!RADEONGetPLLParameters(pScrn)) goto fail; + + if (!RADEONPreInitDDC(pScrn)) goto fail; + + if (!RADEONPreInitGamma(pScrn)) goto fail; + + if (!RADEONPreInitModes(pScrn)) goto fail; + + if (!RADEONPreInitCursor(pScrn)) goto fail; + + if (!RADEONPreInitAccel(pScrn)) goto fail; + +#ifdef XF86DRI + if (!RADEONPreInitDRI(pScrn)) goto fail; +#endif + + /* Free the video bios (if applicable) */ + if (info->VBIOS) { + xfree(info->VBIOS); + info->VBIOS = NULL; + } + + return TRUE; + + fail: + /* Pre-init failed. */ + + /* Free the video bios (if applicable) */ + if (info->VBIOS) { + xfree(info->VBIOS); + info->VBIOS = NULL; + } + + vgaHWFreeHWRec(pScrn); + RADEONFreeRec(pScrn); + return FALSE; +} + +/* Load a palette. */ +static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, + int *indices, LOCO *colors, VisualPtr pVisual) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + int idx; + unsigned char r, g, b; + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); +#endif + + if (info->CurrentLayout.depth == 15) { + /* 15bpp mode. This sends 32 values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx].red; + g = colors[idx].green; + b = colors[idx].blue; + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL(idx * 8, r, g, b); + } + } + else if (info->CurrentLayout.depth == 16) { + /* 16bpp mode. This sends 64 values. */ + /* There are twice as many green values as + there are values for red and blue. So, + we take each red and blue pair, and + combine it with each of the two green + values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx / 2].red; + g = colors[idx].green; + b = colors[idx / 2].blue; + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL(idx * 4, r, g, b); + + /* AH - Added to write extra green data - How come this isn't + * needed on R128 ? We didn't load the extra green data in the + * other routine */ + if (idx <= 31) { + r = colors[idx].red; + g = colors[(idx * 2) + 1].green; + b = colors[idx].blue; + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL(idx * 8, r, g, b); + } + } + } + else { + /* 8bpp mode. This sends 256 values. */ + for (i = 0; i < numColors; i++) { + idx = indices[i]; + r = colors[idx].red; + b = colors[idx].blue; + g = colors[idx].green; + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL(idx, r, g, b); + } + } +} + +/* Called at the start of each server generation. */ +Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + BoxRec MemBox; + int y2; + + RADEONTRACE(("RADEONScreenInit %x %d\n", + pScrn->memPhysBase, pScrn->fbOffset)); + +#ifdef XF86DRI + /* Turn off the CP for now. */ + info->CPInUse = FALSE; +#endif + + if (!RADEONMapMem(pScrn)) return FALSE; + pScrn->fbOffset = 0; +#ifdef XF86DRI + info->fbX = 0; + info->fbY = 0; +#endif + + info->PaletteSavedOnVT = FALSE; + + RADEONSave(pScrn); + if (info->FBDev) { + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE; + } else { + if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; + } + + RADEONSaveScreen(pScreen, SCREEN_SAVER_ON); + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* Visual setup */ + miClearVisualTypes(); + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, + pScrn->defaultVisual)) return FALSE; + miSetPixmapDepths (); + +#ifdef XF86DRI + /* Setup DRI after visuals have been + established, but before cfbScreenInit is + called. cfbScreenInit will eventually + call the driver's InitGLXVisuals call + back. */ + { + /* FIXME: When we move to dynamic allocation of back and depth + buffers, we will want to revisit the following check for 3 + times the virtual size of the screen below. */ + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int maxy = info->FbMapSize / width_bytes; + + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_NOACCEL, FALSE) && + (maxy > pScrn->virtualY * 3) +#ifdef ENABLE_FLAT_PANEL + /* FIXME: Disable 3D support for FPs until it is tested */ + && !info->HasPanelRegs +#endif + ) { + info->directRenderingEnabled = RADEONDRIScreenInit(pScreen); + } else { + xf86DrvMsg(scrnIndex, X_WARNING, + "Static buffer allocation failed -- " + "need at least %d kB video memory\n", + (pScrn->displayWidth * pScrn->virtualY * + info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); + info->directRenderingEnabled = FALSE; + } + } +#endif + +#ifdef USE_FB + if (!fbScreenInit (pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, + pScrn->bitsPerPixel)) + return FALSE; +#ifdef RENDER + fbPictureInit (pScreen, 0, 0); +#endif +#else + switch (pScrn->bitsPerPixel) { + case 8: + if (!cfbScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + case 16: + if (!cfb16ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + case 32: + if (!cfb32ScreenInit(pScreen, info->FB, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) + return FALSE; + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Invalid bpp (%d)\n", pScrn->bitsPerPixel); + return FALSE; + } +#endif + xf86SetBlackWhitePixels(pScreen); + + if (pScrn->bitsPerPixel > 8) { + VisualPtr visual; + + for (visual = pScreen->visuals + pScreen->numVisuals; + visual >= pScreen->visuals; + visual--) { + 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; + } + } + } + + RADEONDGAInit(pScreen); + + /* Memory manager setup */ + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + y2 = (info->FbMapSize + / (pScrn->displayWidth * info->CurrentLayout.pixel_bytes)); + if (y2 >= 32768) y2 = 32767; /* because MemBox.y2 is signed short */ + MemBox.y2 = y2; + + /* The acceleration engine uses 14 bit + signed coordinates, so we can't have any + drawable caches beyond this region. */ + if (MemBox.y2 > 8191) MemBox.y2 = 8191; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; + } else { + int width, height; + FBAreaPtr fbarea; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } + +#ifdef XF86DRI + /* Allocate frame buffer space for the + shared back and depth buffers as well + as for local textures. */ + if (info->directRenderingEnabled) { + FBAreaPtr fbarea; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int maxy = info->FbMapSize / width_bytes; + int l; + + switch (info->CPMode) { + case RADEON_DEFAULT_CP_PIO_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n"); + break; + case RADEON_DEFAULT_CP_BM_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n"); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n"); + break; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB AGP aperture\n", info->agpSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for the ring buffer\n", info->ringSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for vertex buffers\n", info->vbSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for indirect buffers\n", info->indSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for AGP textures\n", info->agpTexSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d byte vertex buffers\n", info->vbBufSize); + + /* Allocate the shared back buffer */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved back buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->backX = fbarea->box.x1; + info->backY = fbarea->box.y1; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); + info->backX = -1; + info->backY = -1; + } + + /* Allocate the shared depth buffer */ + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->depthX = fbarea->box.x1; + info->depthY = fbarea->box.y1; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); + info->depthX = -1; + info->depthY = -1; + } + + /* Allocate local texture space */ + if (((maxy - MemBox.y2 - 1) * width_bytes) > + (pScrn->virtualX * pScrn->virtualY * 2 * + info->CurrentLayout.pixel_bytes)) { + info->textureX = 0; + info->textureY = MemBox.y2 + 1; + info->textureSize = (maxy - MemBox.y2 - 1) * width_bytes; + + l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; + + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", + info->textureSize/1024, + info->textureX, info->textureY, + pScrn->displayWidth, maxy); + } else if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY * 2, + 32, + NULL, NULL, NULL))) { + info->textureX = fbarea->box.x1; + info->textureY = fbarea->box.y1; + info->textureSize = ((fbarea->box.y2 - fbarea->box.y1) * + (fbarea->box.x2 - fbarea->box.x1) * + info->CurrentLayout.pixel_bytes); + + l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; + + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", + info->textureSize/1024, + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Unable to reserve texture space in frame buffer\n"); + info->textureX = -1; + info->textureY = -1; + } + } +#endif + + /* Backing store setup */ + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* Set Silken Mouse */ + xf86SetSilkenMouse(pScreen); + + /* Acceleration setup */ + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_NOACCEL, FALSE)) { + if (RADEONAccelInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); + info->accelOn = TRUE; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Acceleration initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n"); + info->accelOn = FALSE; + } + + /* Cursor setup */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Hardware cursor setup */ + if (!xf86ReturnOptValBool(RADEONOptions, OPTION_SW_CURSOR, FALSE)) { + if (RADEONCursorInit(pScreen)) { + int width, height; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using hardware cursor (scanline %d)\n", + info->cursor_start / pScrn->displayWidth); + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, + 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } else { + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); + } + } else { + xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n"); + } + + /* Colormap setup */ + if (!miCreateDefColormap(pScreen)) return FALSE; + if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8, + (info->FBDev ? fbdevHWLoadPalette : + RADEONLoadPalette), NULL, + CMAP_PALETTED_TRUECOLOR + | CMAP_RELOAD_ON_MODE_SWITCH +#if 0 /* This option messes up text mode! (eich@suse.de) */ + | CMAP_LOAD_EVEN_IF_OFFSCREEN +#endif + )) return FALSE; + + /* DPMS setup */ +#ifdef DPMSExtension +#ifdef ENABLE_FLAT_PANEL + if (!info->HasPanelRegs || info->CRTOnly) + xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); +#else + xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0); +#endif +#endif + + RADEONInitVideo(pScreen); + + /* Provide SaveScreen */ + pScreen->SaveScreen = RADEONSaveScreen; + + /* Wrap CloseScreen */ + info->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = RADEONCloseScreen; + + /* Note unused options */ + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + +#ifdef XF86DRI + /* DRI finalization */ + if (info->directRenderingEnabled) { + /* Now that mi, cfb, drm and others have + done their thing, complete the DRI + setup. */ + info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen); + } + if (info->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering disabled\n"); + } +#endif + + return TRUE; +} + +/* Write common registers (initialized to 0). */ +static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn, + RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_OVR_CLR, restore->ovr_clr); + OUTREG(RADEON_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right); + OUTREG(RADEON_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom); + OUTREG(RADEON_OV0_SCALE_CNTL, restore->ov0_scale_cntl); + OUTREG(RADEON_MPP_TB_CONFIG, restore->mpp_tb_config ); + OUTREG(RADEON_MPP_GP_CONFIG, restore->mpp_gp_config ); + OUTREG(RADEON_SUBPIC_CNTL, restore->subpic_cntl); + OUTREG(RADEON_VIPH_CONTROL, restore->viph_control); + OUTREG(RADEON_I2C_CNTL_1, restore->i2c_cntl_1); + OUTREG(RADEON_GEN_INT_CNTL, restore->gen_int_cntl); + OUTREG(RADEON_CAP0_TRIG_CNTL, restore->cap0_trig_cntl); + OUTREG(RADEON_CAP1_TRIG_CNTL, restore->cap1_trig_cntl); + OUTREG(RADEON_BUS_CNTL, restore->bus_cntl); +} + +/* Write CRTC registers. */ +static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, + RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl); + + OUTREGP(RADEON_CRTC_EXT_CNTL, restore->crtc_ext_cntl, + RADEON_CRTC_VSYNC_DIS | + RADEON_CRTC_HSYNC_DIS | + RADEON_CRTC_DISPLAY_DIS); + + OUTREGP(RADEON_DAC_CNTL, restore->dac_cntl, + RADEON_DAC_RANGE_CNTL | + RADEON_DAC_BLANKING); + + OUTREG(RADEON_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp); + OUTREG(RADEON_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid); + OUTREG(RADEON_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); + OUTREG(RADEON_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); + OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset); + OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); + OUTREG(RADEON_CRTC_PITCH, restore->crtc_pitch); +} + +#ifdef ENABLE_FLAT_PANEL +/* Note: Radeon flat panel support has been disabled for now */ +/* Write flat panel registers */ +static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 tmp; + + OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl); + OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); + OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); + OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl); + OUTREG(RADEON_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); + OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch); + OUTREG(RADEON_FP_PANEL_CNTL, restore->fp_panel_cntl); + OUTREG(RADEON_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); + OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch); + OUTREG(RADEON_TMDS_CRC, restore->tmds_crc); + + tmp = INREG(RADEON_LVDS_GEN_CNTL); + if ((tmp & (RADEON_LVDS_ON | RADEON_LVDS_BLON)) == + (restore->lvds_gen_cntl & (RADEON_LVDS_ON | RADEON_LVDS_BLON))) { + OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } else { + if (restore->lvds_gen_cntl & (RADEON_LVDS_ON | RADEON_LVDS_BLON)) { + OUTREG(RADEON_LVDS_GEN_CNTL, + restore->lvds_gen_cntl & ~RADEON_LVDS_BLON); + usleep(RADEONPTR(pScrn)->PanelPwrDly * 1000); + OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } else { + OUTREG(RADEON_LVDS_GEN_CNTL, + restore->lvds_gen_cntl | RADEON_LVDS_BLON); + usleep(RADEONPTR(pScrn)->PanelPwrDly * 1000); + OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } + } +} +#endif + +#if RADEON_ATOMIC_UPDATE +static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn) +{ + while (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R); +} + +static void RADEONPLLWriteUpdate(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTPLLP(pScrn, RADEON_PPLL_REF_DIV, RADEON_PPLL_ATOMIC_UPDATE_W, 0xffff); +} +#endif + +/* Write PLL registers. */ +static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + +#if !RADEON_ATOMIC_UPDATE + while ( (INREG(RADEON_CLOCK_CNTL_INDEX) & RADEON_PLL_DIV_SEL) != + RADEON_PLL_DIV_SEL) { +#endif + OUTREGP(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_DIV_SEL, 0xffff); +#if !RADEON_ATOMIC_UPDATE + } +#endif + +#if RADEON_ATOMIC_UPDATE + OUTPLLP(pScrn, + RADEON_PPLL_CNTL, + RADEON_PPLL_RESET + | RADEON_PPLL_ATOMIC_UPDATE_EN + | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN, + 0xffff); +#else + OUTPLLP(pScrn, + RADEON_PPLL_CNTL, + RADEON_PPLL_RESET, + 0xffff); +#endif + +#if RADEON_ATOMIC_UPDATE + RADEONPLLWaitForReadUpdateComplete(pScrn); +#endif + while ( (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK) != + (restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK)) { + OUTPLLP(pScrn, RADEON_PPLL_REF_DIV, + restore->ppll_ref_div, ~RADEON_PPLL_REF_DIV_MASK); + } +#if RADEON_ATOMIC_UPDATE + RADEONPLLWriteUpdate(pScrn); +#endif + +#if RADEON_ATOMIC_UPDATE + RADEONPLLWaitForReadUpdateComplete(pScrn); +#endif + while ( (INPLL(pScrn, RADEON_PPLL_DIV_3) & RADEON_PPLL_FB3_DIV_MASK) != + (restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK)) { + OUTPLLP(pScrn, RADEON_PPLL_DIV_3, + restore->ppll_div_3, ~RADEON_PPLL_FB3_DIV_MASK); + } +#if RADEON_ATOMIC_UPDATE + RADEONPLLWriteUpdate(pScrn); +#endif + +#if RADEON_ATOMIC_UPDATE + RADEONPLLWaitForReadUpdateComplete(pScrn); +#endif + while ( (INPLL(pScrn, RADEON_PPLL_DIV_3) & RADEON_PPLL_POST3_DIV_MASK) != + (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK)) { + OUTPLLP(pScrn, RADEON_PPLL_DIV_3, + restore->ppll_div_3, ~RADEON_PPLL_POST3_DIV_MASK); + } +#if RADEON_ATOMIC_UPDATE + RADEONPLLWriteUpdate(pScrn); +#endif + +#if RADEON_ATOMIC_UPDATE + RADEONPLLWaitForReadUpdateComplete(pScrn); +#endif + OUTPLL(RADEON_HTOTAL_CNTL, restore->htotal_cntl); +#if RADEON_ATOMIC_UPDATE + RADEONPLLWriteUpdate(pScrn); +#endif + + OUTPLLP(pScrn, RADEON_PPLL_CNTL, 0, ~RADEON_PPLL_RESET); + + RADEONTRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", + restore->ppll_ref_div, + restore->ppll_div_3, + restore->htotal_cntl, + INPLL(pScrn, RADEON_PPLL_CNTL))); + RADEONTRACE(("Wrote: rd=%d, fd=%d, pd=%d\n", + restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, + restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK, + (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16)); +} + +/* Write DDA registers. */ +static void RADEONRestoreDDARegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_DDA_CONFIG, restore->dda_config); + OUTREG(RADEON_DDA_ON_OFF, restore->dda_on_off); +} + +/* Write palette data. */ +static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + if (!restore->palette_valid) return; + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); +#endif + + OUTPAL_START(0); + for (i = 0; i < 256; i++) { + RADEONWaitForFifo(pScrn, 32); /* delay */ + OUTPAL_NEXT_CARD32(restore->palette[i]); + } +} + +/* Write out state to define a new video mode. */ +static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ +#ifdef ENABLE_FLAT_PANEL + RADEONInfoPtr info = RADEONPTR(pScrn); +#endif + + RADEONTRACE(("RADEONRestoreMode(%p)\n", restore)); + RADEONRestoreCommonRegisters(pScrn, restore); + RADEONRestoreCrtcRegisters(pScrn, restore); +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) + RADEONRestoreFPRegisters(pScrn, restore); + if (!info->HasPanelRegs || info->CRTOnly) + RADEONRestorePLLRegisters(pScrn, restore); +#else + RADEONRestorePLLRegisters(pScrn, restore); +#endif + RADEONRestoreDDARegisters(pScrn, restore); + RADEONRestorePalette(pScrn, restore); +} + +/* Read common registers. */ +static void RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->ovr_clr = INREG(RADEON_OVR_CLR); + save->ovr_wid_left_right = INREG(RADEON_OVR_WID_LEFT_RIGHT); + save->ovr_wid_top_bottom = INREG(RADEON_OVR_WID_TOP_BOTTOM); + save->ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL); + save->mpp_tb_config = INREG(RADEON_MPP_TB_CONFIG); + save->mpp_gp_config = INREG(RADEON_MPP_GP_CONFIG); + save->subpic_cntl = INREG(RADEON_SUBPIC_CNTL); + save->viph_control = INREG(RADEON_VIPH_CONTROL); + save->i2c_cntl_1 = INREG(RADEON_I2C_CNTL_1); + save->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL); + save->cap0_trig_cntl = INREG(RADEON_CAP0_TRIG_CNTL); + save->cap1_trig_cntl = INREG(RADEON_CAP1_TRIG_CNTL); + save->bus_cntl = INREG(RADEON_BUS_CNTL); +} + +/* Read CRTC registers. */ +static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL); + save->crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL); + save->dac_cntl = INREG(RADEON_DAC_CNTL); + save->crtc_h_total_disp = INREG(RADEON_CRTC_H_TOTAL_DISP); + save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID); + save->crtc_v_total_disp = INREG(RADEON_CRTC_V_TOTAL_DISP); + save->crtc_v_sync_strt_wid = INREG(RADEON_CRTC_V_SYNC_STRT_WID); + save->crtc_offset = INREG(RADEON_CRTC_OFFSET); + save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL); + save->crtc_pitch = INREG(RADEON_CRTC_PITCH); +} + +#ifdef ENABLE_FLAT_PANEL +/* Note: Radeon flat panel support has been disabled for now */ +/* Read flat panel registers */ +static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL); + save->fp_crtc_h_total_disp = INREG(RADEON_FP_CRTC_H_TOTAL_DISP); + save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP); + save->fp_gen_cntl = INREG(RADEON_FP_GEN_CNTL); + save->fp_h_sync_strt_wid = INREG(RADEON_FP_H_SYNC_STRT_WID); + save->fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH); + save->fp_panel_cntl = INREG(RADEON_FP_PANEL_CNTL); + save->fp_v_sync_strt_wid = INREG(RADEON_FP_V_SYNC_STRT_WID); + save->fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH); + save->lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL); + save->tmds_crc = INREG(RADEON_TMDS_CRC); +} +#endif + +/* Read PLL registers. */ +static void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV); + save->ppll_div_3 = INPLL(pScrn, RADEON_PPLL_DIV_3); + save->htotal_cntl = INPLL(pScrn, RADEON_HTOTAL_CNTL); + + RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08x\n", + save->ppll_ref_div, + save->ppll_div_3, + save->htotal_cntl)); + RADEONTRACE(("Read: rd=%d, fd=%d, pd=%d\n", + save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, + save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK, + (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16)); +} + +/* Read DDA registers. */ +static void RADEONSaveDDARegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->dda_config = INREG(RADEON_DDA_CONFIG); + save->dda_on_off = INREG(RADEON_DDA_ON_OFF); +} + +/* Read palette data. */ +static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + /* Select palette 0 (main CRTC) if using FP-enabled chip */ + if (info->HasPanelRegs) PAL_SELECT(0); +#endif + + INPAL_START(0); + for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT(); + save->palette_valid = TRUE; +} + +/* Save state that defines current video mode. */ +static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONTRACE(("RADEONSaveMode(%p)\n", save)); + + RADEONSaveCommonRegisters(pScrn, save); + RADEONSaveCrtcRegisters(pScrn, save); +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (RADEONPTR(pScrn)->HasPanelRegs) + RADEONSaveFPRegisters(pScrn, save); +#endif + RADEONSavePLLRegisters(pScrn, save); + RADEONSaveDDARegisters(pScrn, save); + RADEONSavePalette(pScrn, save); + + RADEONTRACE(("RADEONSaveMode returns %p\n", save)); +} + +/* Save everything needed to restore the original VC state. */ +static void RADEONSave(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONSavePtr save = &info->SavedReg; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + RADEONTRACE(("RADEONSave\n")); + if (info->FBDev) { + fbdevHWSave(pScrn); + return; + } + vgaHWUnlock(hwp); + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL); /* save mode, fonts, cmap */ + vgaHWLock(hwp); + + RADEONSaveMode(pScrn, save); + + save->dp_datatype = INREG(RADEON_DP_DATATYPE); + save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); + save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); + save->amcgpio_en_reg = INREG(RADEON_AMCGPIO_EN_REG); + save->amcgpio_mask = INREG(RADEON_AMCGPIO_MASK); +} + +/* Restore the original (text) mode. */ +static void RADEONRestore(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONSavePtr restore = &info->SavedReg; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + RADEONTRACE(("RADEONRestore\n")); + if (info->FBDev) { + fbdevHWRestore(pScrn); + return; + } + + RADEONBlank(pScrn); + + OUTREG(RADEON_AMCGPIO_MASK, restore->amcgpio_mask); + OUTREG(RADEON_AMCGPIO_EN_REG, restore->amcgpio_en_reg); + OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index); + OUTREG(RADEON_RBBM_SOFT_RESET, restore->rbbm_soft_reset); + OUTREG(RADEON_DP_DATATYPE, restore->dp_datatype); + + RADEONRestoreMode(pScrn, restore); + vgaHWUnlock(hwp); + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); + vgaHWLock(hwp); + +#if 0 + RADEONWaitForVerticalSync(pScrn); +#endif + RADEONUnblank(pScrn); +} + +/* Define common registers for requested video mode. */ +static void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info) +{ + save->ovr_clr = 0; + save->ovr_wid_left_right = 0; + save->ovr_wid_top_bottom = 0; + save->ov0_scale_cntl = 0; + save->mpp_tb_config = 0; + save->mpp_gp_config = 0; + save->subpic_cntl = 0; + save->viph_control = 0; + save->i2c_cntl_1 = 0; + save->rbbm_soft_reset = 0; + save->cap0_trig_cntl = 0; + save->cap1_trig_cntl = 0; + save->bus_cntl = info->BusCntl; + /* + * If bursts are enabled, turn on discards + * Radeon doesn't have write bursts + */ + if (save->bus_cntl & (RADEON_BUS_READ_BURST)) + save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN; +} + +/* Define CRTC registers for requested video mode. */ +static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, + DisplayModePtr mode, RADEONInfoPtr info) +{ + int format; + int hsync_start; + int hsync_wid; + int hsync_fudge; + int vsync_wid; + int bytpp; + int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + int hsync_fudge_fp[] = { 0x12, 0x11, 0x09, 0x09, 0x05, 0x05 }; + int hsync_fudge_fp_crt[] = { 0x12, 0x10, 0x08, 0x08, 0x04, 0x04 }; +#endif + + switch (info->CurrentLayout.pixel_code) { + case 4: format = 1; bytpp = 0; break; + case 8: format = 2; bytpp = 1; break; + case 15: format = 3; bytpp = 2; break; /* 555 */ + case 16: format = 4; bytpp = 2; break; /* 565 */ + case 24: format = 5; bytpp = 3; break; /* RGB */ + case 32: format = 6; bytpp = 4; break; /* xRGB */ + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unsupported pixel depth (%d)\n", info->CurrentLayout.bitsPerPixel); + return FALSE; + } + RADEONTRACE(("Format = %d (%d bytes per pixel)\n", format, bytpp)); + +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) + if (info->CRTOnly) hsync_fudge = hsync_fudge_fp_crt[format-1]; + else hsync_fudge = hsync_fudge_fp[format-1]; + else hsync_fudge = hsync_fudge_default[format-1]; +#else + hsync_fudge = hsync_fudge_default[format-1]; +#endif + + save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN + | RADEON_CRTC_EN + | (format << 8) + | ((mode->Flags & V_DBLSCAN) + ? RADEON_CRTC_DBL_SCAN_EN + : 0) + | ((mode->Flags & V_INTERLACE) + ? RADEON_CRTC_INTERLACE_EN + : 0)); + + save->crtc_ext_cntl = RADEON_VGA_ATI_LINEAR | RADEON_XCRT_CNT_EN; + save->dac_cntl = (RADEON_DAC_MASK_ALL + | RADEON_DAC_VGA_ADR_EN + | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN)); + + save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0xffff) + | (((mode->CrtcHDisplay / 8) - 1) << 16)); + + hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; + if (!hsync_wid) hsync_wid = 1; + if (hsync_wid > 0x3f) hsync_wid = 0x3f; + + hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; + + save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) + | (hsync_wid << 16) + | ((mode->Flags & V_NHSYNC) + ? RADEON_CRTC_H_SYNC_POL + : 0)); + +#if 1 + /* This works for double scan mode. */ + save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) + | ((mode->CrtcVDisplay - 1) << 16)); +#else + /* This is what cce/nbmode.c example code + does -- is this correct? */ + save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) + | ((mode->CrtcVDisplay + * ((mode->Flags & V_DBLSCAN) ? 2 : 1) - 1) + << 16)); +#endif + + vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + if (!vsync_wid) vsync_wid = 1; + if (vsync_wid > 0x1f) vsync_wid = 0x1f; + + save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) + | (vsync_wid << 16) + | ((mode->Flags & V_NVSYNC) + ? RADEON_CRTC_V_SYNC_POL + : 0)); + save->crtc_offset = 0; + save->crtc_offset_cntl = 0; + + save->crtc_pitch = ((pScrn->displayWidth * pScrn->bitsPerPixel) + + ((pScrn->bitsPerPixel * 8) -1)) / + (pScrn->bitsPerPixel * 8); + save->crtc_pitch |= save->crtc_pitch << 16; + + RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n", + save->crtc_pitch, pScrn->virtualX, + info->CurrentLayout.displayWidth)); + return TRUE; +} + +#ifdef ENABLE_FLAT_PANEL +/* Note: Radeon flat panel support has been disabled for now */ +/* Define CRTC registers for requested video mode. */ +static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, + RADEONSavePtr save, DisplayModePtr mode, + RADEONInfoPtr info) +{ + int xres = mode->CrtcHDisplay; + int yres = mode->CrtcVDisplay; + float Hratio, Vratio; + + if (info->CRTOnly) { + save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON; + save->crtc2_gen_cntl = 0; + save->fp_gen_cntl = orig->fp_gen_cntl; + save->fp_gen_cntl &= ~(RADEON_FP_FPON | + RADEON_FP_CRTC_USE_SHADOW_VEND | + RADEON_FP_CRTC_HORZ_DIV2_EN | + RADEON_FP_CRTC_HOR_CRT_DIV2_DIS | + RADEON_FP_USE_SHADOW_EN); + save->fp_gen_cntl |= (RADEON_FP_SEL_CRTC2 | + RADEON_FP_CRTC_DONT_SHADOW_VPAR); + save->fp_panel_cntl = orig->fp_panel_cntl & ~RADEON_FP_DIGON; + save->lvds_gen_cntl = orig->lvds_gen_cntl & ~(RADEON_LVDS_ON | + RADEON_LVDS_BLON); + return; + } + + if (xres > info->PanelXRes) xres = info->PanelXRes; + if (yres > info->PanelYRes) yres = info->PanelYRes; + + Hratio = (float)xres/(float)info->PanelXRes; + Vratio = (float)yres/(float)info->PanelYRes; + + save->fp_horz_stretch = + (((((int)(Hratio * RADEON_HORZ_STRETCH_RATIO_MAX + 0.5)) + & RADEON_HORZ_STRETCH_RATIO_MASK) + << RADEON_HORZ_STRETCH_RATIO_SHIFT) | + (orig->fp_horz_stretch & (RADEON_HORZ_PANEL_SIZE | + RADEON_HORZ_FP_LOOP_STRETCH | + RADEON_HORZ_STRETCH_RESERVED))); + save->fp_horz_stretch &= ~RADEON_HORZ_AUTO_RATIO_FIX_EN; + if (Hratio == 1.0) save->fp_horz_stretch &= ~(RADEON_HORZ_STRETCH_BLEND | + RADEON_HORZ_STRETCH_ENABLE); + else save->fp_horz_stretch |= (RADEON_HORZ_STRETCH_BLEND | + RADEON_HORZ_STRETCH_ENABLE); + + save->fp_vert_stretch = + (((((int)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX + 0.5)) + & RADEON_VERT_STRETCH_RATIO_MASK) + << RADEON_VERT_STRETCH_RATIO_SHIFT) | + (orig->fp_vert_stretch & (RADEON_VERT_PANEL_SIZE | + RADEON_VERT_STRETCH_RESERVED))); + save->fp_vert_stretch &= ~RADEON_VERT_AUTO_RATIO_EN; + if (Vratio == 1.0) save->fp_vert_stretch &= ~(RADEON_VERT_STRETCH_ENABLE | + RADEON_VERT_STRETCH_BLEND); + else save->fp_vert_stretch |= (RADEON_VERT_STRETCH_ENABLE | + RADEON_VERT_STRETCH_BLEND); + + save->fp_gen_cntl = (orig->fp_gen_cntl & ~(RADEON_FP_SEL_CRTC2 | + RADEON_FP_CRTC_USE_SHADOW_VEND | + RADEON_FP_CRTC_HORZ_DIV2_EN | + RADEON_FP_CRTC_HOR_CRT_DIV2_DIS | + RADEON_FP_USE_SHADOW_EN)); + if (orig->fp_gen_cntl & RADEON_FP_DETECT_SENSE) { + save->fp_gen_cntl |= (RADEON_FP_CRTC_DONT_SHADOW_VPAR | + RADEON_FP_TDMS_EN); + } + + save->fp_panel_cntl = orig->fp_panel_cntl; + save->lvds_gen_cntl = orig->lvds_gen_cntl; + + save->tmds_crc = orig->tmds_crc; + + /* Disable CRT output by disabling CRT output and setting the CRT + DAC to use CRTC2, which we set to 0's. In the future, we will + want to use the dual CRTC capabilities of the RADEON to allow both + the flat panel and external CRT to either simultaneously display + the same image or display two different images. */ + save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; + save->dac_cntl |= RADEON_DAC_CRT_SEL_CRTC2; + save->crtc2_gen_cntl = 0; + + /* WARNING: Be careful about turning on the flat panel */ +#if 1 + save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); +#else + save->fp_panel_cntl |= (RADEON_FP_DIGON | RADEON_FP_BLON); + save->fp_gen_cntl |= (RADEON_FP_FPON); +#endif + + save->fp_crtc_h_total_disp = save->crtc_h_total_disp; + save->fp_crtc_v_total_disp = save->crtc_v_total_disp; + save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; + save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; +} +#endif + +/* Define PLL registers for requested video mode. */ +static void RADEONInitPLLRegisters(RADEONSavePtr save, RADEONPLLPtr pll, + double dot_clock) +{ + unsigned long freq = dot_clock * 100; + struct { + int divider; + int bitvalue; + } *post_div, + post_divs[] = { + /* From RAGE 128 VR/RAGE 128 GL Register + Reference Manual (Technical Reference + Manual P/N RRG-G04100-C Rev. 0.04), page + 3-17 (PLL_DIV_[3:0]). */ + { 1, 0 }, /* VCLK_SRC */ + { 2, 1 }, /* VCLK_SRC/2 */ + { 4, 2 }, /* VCLK_SRC/4 */ + { 8, 3 }, /* VCLK_SRC/8 */ + { 3, 4 }, /* VCLK_SRC/3 */ + { 16, 5 }, /* VCLK_SRC/16 */ + { 6, 6 }, /* VCLK_SRC/6 */ + { 12, 7 }, /* VCLK_SRC/12 */ + { 0, 0 } + }; + + if (freq > pll->max_pll_freq) freq = pll->max_pll_freq; + if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; + + for (post_div = &post_divs[0]; post_div->divider; ++post_div) { + save->pll_output_freq = post_div->divider * freq; + if (save->pll_output_freq >= pll->min_pll_freq + && save->pll_output_freq <= pll->max_pll_freq) break; + } + + save->dot_clock_freq = freq; + save->feedback_div = RADEONDiv(pll->reference_div + * save->pll_output_freq, + pll->reference_freq); + save->post_div = post_div->divider; + + RADEONTRACE(("dc=%d, of=%d, fd=%d, pd=%d\n", + save->dot_clock_freq, + save->pll_output_freq, + save->feedback_div, + save->post_div)); + + save->ppll_ref_div = pll->reference_div; + save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16)); + save->htotal_cntl = 0; +} + +/* Define DDA registers for requested video mode. */ +static Bool RADEONInitDDARegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, + RADEONPLLPtr pll, RADEONInfoPtr info) +{ + int DisplayFifoWidth = 128; + int DisplayFifoDepth = 32; + int XclkFreq; + int VclkFreq; + int XclksPerTransfer; + int XclksPerTransferPrecise; + int UseablePrecision; + int Roff; + int Ron; + + XclkFreq = pll->xclk; + + VclkFreq = RADEONDiv(pll->reference_freq * save->feedback_div, + pll->reference_div * save->post_div); + + XclksPerTransfer = RADEONDiv(XclkFreq * DisplayFifoWidth, + VclkFreq * + (info->CurrentLayout.pixel_bytes * 8)); + + UseablePrecision = RADEONMinBits(XclksPerTransfer) + 1; + + XclksPerTransferPrecise = RADEONDiv((XclkFreq * DisplayFifoWidth) + << (11 - UseablePrecision), + VclkFreq * + (info->CurrentLayout.pixel_bytes * 8)); + + Roff = XclksPerTransferPrecise * (DisplayFifoDepth - 4); + + Ron = (4 * info->ram->MB + + 3 * MAX(info->ram->Trcd - 2, 0) + + 2 * info->ram->Trp + + info->ram->Twr + + info->ram->CL + + info->ram->Tr2w + + XclksPerTransfer) << (11 - UseablePrecision); + + if (Ron + info->ram->Rloop >= Roff) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "(Ron = %d) + (Rloop = %d) >= (Roff = %d)\n", + Ron, info->ram->Rloop, Roff); + return FALSE; + } + + save->dda_config = (XclksPerTransferPrecise + | (UseablePrecision << 16) + | (info->ram->Rloop << 20)); + + save->dda_on_off = (Ron << 16) | Roff; + + RADEONTRACE(("XclkFreq = %d; VclkFreq = %d; per = %d, %d (useable = %d)\n", + XclkFreq, + VclkFreq, + XclksPerTransfer, + XclksPerTransferPrecise, + UseablePrecision)); + RADEONTRACE(("Roff = %d, Ron = %d, Rloop = %d\n", + Roff, Ron, info->ram->Rloop)); + + return TRUE; +} + + +/* Define initial palette for requested video mode. This doesn't do + anything for XFree86 4.0. */ +static void RADEONInitPalette(RADEONSavePtr save) +{ + save->palette_valid = FALSE; +} + +/* Define registers for a requested video mode. */ +static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode, + RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + double dot_clock = mode->Clock/1000.0; + +#if RADEON_DEBUG + ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", + mode->name, + dot_clock, + + mode->HDisplay, + mode->HSyncStart, + mode->HSyncEnd, + mode->HTotal, + + mode->VDisplay, + mode->VSyncStart, + mode->VSyncEnd, + mode->VTotal, + pScrn->depth, + pScrn->bitsPerPixel); + if (mode->Flags & V_DBLSCAN) ErrorF(" D"); + if (mode->Flags & V_INTERLACE) ErrorF(" I"); + if (mode->Flags & V_PHSYNC) ErrorF(" +H"); + if (mode->Flags & V_NHSYNC) ErrorF(" -H"); + if (mode->Flags & V_PVSYNC) ErrorF(" +V"); + if (mode->Flags & V_NVSYNC) ErrorF(" -V"); + ErrorF("\n"); + ErrorF("%-12.12s %7.2f %4d %4d %4d %4d %4d %4d %4d %4d (%d,%d)", + mode->name, + dot_clock, + + mode->CrtcHDisplay, + mode->CrtcHSyncStart, + mode->CrtcHSyncEnd, + mode->CrtcHTotal, + + mode->CrtcVDisplay, + mode->CrtcVSyncStart, + mode->CrtcVSyncEnd, + mode->CrtcVTotal, + pScrn->depth, + pScrn->bitsPerPixel); + if (mode->Flags & V_DBLSCAN) ErrorF(" D"); + if (mode->Flags & V_INTERLACE) ErrorF(" I"); + if (mode->Flags & V_PHSYNC) ErrorF(" +H"); + if (mode->Flags & V_NHSYNC) ErrorF(" -H"); + if (mode->Flags & V_PVSYNC) ErrorF(" +V"); + if (mode->Flags & V_NVSYNC) ErrorF(" -V"); + ErrorF("\n"); +#endif + + info->Flags = mode->Flags; + + RADEONInitCommonRegisters(save, info); + if (!RADEONInitCrtcRegisters(pScrn, save, mode, info)) return FALSE; +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + if (info->HasPanelRegs) + RADEONInitFPRegisters(pScrn, &info->SavedReg, save, mode, info); +#endif + RADEONInitPLLRegisters(save, &info->pll, dot_clock); + if (!RADEONInitDDARegisters(pScrn, save, &info->pll, info)) + return FALSE; + if (!info->PaletteSavedOnVT) RADEONInitPalette(save); + + RADEONTRACE(("RADEONInit returns %p\n", save)); + return TRUE; +} + +/* Initialize a new mode. */ +static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE; + /* FIXME? DRILock/DRIUnlock here? */ + pScrn->vtSema = TRUE; + RADEONBlank(pScrn); + RADEONRestoreMode(pScrn, &info->ModeReg); + RADEONUnblank(pScrn); + + info->CurrentLayout.mode = mode; + + return TRUE; +} + +static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + Bool unblank; + + unblank = xf86IsUnblank(mode); + if (unblank) + SetTimeSinceLastInputEvent(); + + if ((pScrn != NULL) && pScrn->vtSema) { + if (unblank) + RADEONUnblank(pScrn); + else + RADEONBlank(pScrn); + } + return TRUE; +} + +Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + return RADEONModeInit(xf86Screens[scrnIndex], mode); +} + +/* Used to disallow modes that are not supported by the hardware. */ +int RADEONValidMode(int scrnIndex, DisplayModePtr mode, + Bool verbose, int flag) +{ +#ifdef ENABLE_FLAT_PANEL + /* Note: Radeon flat panel support has been disabled for now */ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->HasPanelRegs) { + if (mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; + if (mode->Flags & V_DBLSCAN) return MODE_NO_DBLESCAN; + } + + if (info->HasPanelRegs && !info->CRTOnly && info->VBIOS) { + int i; + for (i = info->FPBIOSstart+64; RADEON_BIOS16(i) != 0; i += 2) { + int j = RADEON_BIOS16(i); + + if (mode->CrtcHDisplay == RADEON_BIOS16(j) && + mode->CrtcVDisplay == RADEON_BIOS16(j+2)) { + /* Assume we are using expanded mode */ + if (RADEON_BIOS16(j+5)) j = RADEON_BIOS16(j+5); + else j += 9; + + mode->Clock = (CARD32)RADEON_BIOS16(j) * 10; + + mode->HDisplay = mode->CrtcHDisplay = + ((RADEON_BIOS16(j+10) & 0x01ff)+1)*8; + mode->HSyncStart = mode->CrtcHSyncStart = + ((RADEON_BIOS16(j+12) & 0x01ff)+1)*8; + mode->HSyncEnd = mode->CrtcHSyncEnd = + mode->CrtcHSyncStart + (RADEON_BIOS8(j+14) & 0x1f); + mode->HTotal = mode->CrtcHTotal = + ((RADEON_BIOS16(j+8) & 0x01ff)+1)*8; + + mode->VDisplay = mode->CrtcVDisplay = + (RADEON_BIOS16(j+17) & 0x07ff)+1; + mode->VSyncStart = mode->CrtcVSyncStart = + (RADEON_BIOS16(j+19) & 0x07ff)+1; + mode->VSyncEnd = mode->CrtcVSyncEnd = + mode->CrtcVSyncStart + ((RADEON_BIOS16(j+19) >> 11)&0x1f); + mode->VTotal = mode->CrtcVTotal = + (RADEON_BIOS16(j+15) & 0x07ff)+1; + + return MODE_OK; + } + } + return MODE_NOMODE; + } +#endif + + return MODE_OK; +} + +/* Adjust viewport into virtual desktop such that (0,0) in viewport space + is (x,y) in virtual space. */ +void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int Base; + + Base = y * info->CurrentLayout.displayWidth + x; + + switch (info->CurrentLayout.pixel_code) { + case 15: + case 16: Base *= 2; break; + case 24: Base *= 3; break; + case 32: Base *= 4; break; + } + + Base &= ~7; /* 3 lower bits are always 0 */ + + OUTREG(RADEON_CRTC_OFFSET, Base); +} + +/* Called when VT switching back to the X server. Reinitialize the video + mode. */ +Bool RADEONEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + RADEONTRACE(("RADEONEnterVT\n")); +#ifdef XF86DRI + if (RADEONPTR(pScrn)->directRenderingEnabled) { + RADEONCPStart(pScrn); + DRIUnlock(pScrn->pScreen); + } +#endif + if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; + if (info->accelOn) + RADEONEngineInit(pScrn); + + info->PaletteSavedOnVT = FALSE; + RADEONAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + +/* Called when VT switching away from the X server. Restore the original + text mode. */ +void RADEONLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONSavePtr save = &info->ModeReg; + + RADEONTRACE(("RADEONLeaveVT\n")); +#ifdef XF86DRI + if (RADEONPTR(pScrn)->directRenderingEnabled) { + DRILock(pScrn->pScreen, 0); + RADEONCPStop(pScrn); + } +#endif + RADEONSavePalette(pScrn, save); + info->PaletteSavedOnVT = TRUE; + RADEONRestore(pScrn); +} + +static Bool +RADEONEnterVTFBDev(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONSavePtr restore = &info->SavedReg; + fbdevHWEnterVT(scrnIndex,flags); + RADEONRestorePalette(pScrn,restore); + RADEONEngineInit(pScrn); + return TRUE; +} + +static void RADEONLeaveVTFBDev(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONSavePtr save = &info->SavedReg; + RADEONSavePalette(pScrn,save); + fbdevHWLeaveVT(scrnIndex,flags); +} + +/* Called at the end of each server generation. Restore the original text + mode, unmap video memory, and unwrap and call the saved CloseScreen + function. */ +static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + RADEONTRACE(("RADEONCloseScreen\n")); + +#ifdef XF86DRI + /* Disable direct rendering */ + if (info->directRenderingEnabled) { + RADEONDRICloseScreen(pScreen); + info->directRenderingEnabled = FALSE; + } +#endif + + if (pScrn->vtSema) { + RADEONRestore(pScrn); + RADEONUnmapMem(pScrn); + } + + if (info->accel) XAADestroyInfoRec(info->accel); + info->accel = NULL; + + if (info->scratch_save) xfree(info->scratch_save); + info->scratch_save = NULL; + + if (info->cursor) xf86DestroyCursorInfoRec(info->cursor); + info->cursor = NULL; + + if (info->DGAModes) xfree(info->DGAModes); + info->DGAModes = NULL; + + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = info->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + +void RADEONFreeScreen(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + RADEONTRACE(("RADEONFreeScreen\n")); + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(pScrn); + RADEONFreeRec(pScrn); +} + +#ifdef DPMSExtension +/* Sets VESA Display Power Management Signaling (DPMS) Mode. */ +static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, + int PowerManagementMode, int flags) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int mask = (RADEON_CRTC_DISPLAY_DIS + | RADEON_CRTC_HSYNC_DIS + | RADEON_CRTC_VSYNC_DIS); + + switch (PowerManagementMode) { + case DPMSModeOn: + /* Screen: On; HSync: On, VSync: On */ + OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask); + break; + case DPMSModeStandby: + /* Screen: Off; HSync: Off, VSync: On */ + OUTREGP(RADEON_CRTC_EXT_CNTL, + RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS, ~mask); + break; + case DPMSModeSuspend: + /* Screen: Off; HSync: On, VSync: Off */ + OUTREGP(RADEON_CRTC_EXT_CNTL, + RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS, ~mask); + break; + case DPMSModeOff: + /* Screen: Off; HSync: Off, VSync: Off */ + OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask); + break; + } +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c new file mode 100644 index 000000000..50cf084f1 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c @@ -0,0 +1,85 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_misc.c,v 1.1 2000/11/02 16:55:43 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * 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 Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef XFree86LOADER + +#include "ati.h" +#include "ativersion.h" + +#include "radeon_version.h" + +#include "xf86.h" + +/* Module loader interface for subsidiary driver module */ + +static XF86ModuleVersionInfo RADEONVersionRec = +{ + RADEON_DRIVER_NAME, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + RADEON_VERSION_MAJOR, RADEON_VERSION_MINOR, RADEON_VERSION_PATCH, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +/* + * RADEONSetup -- + * + * This function is called every time the module is loaded. + */ +static pointer +RADEONSetup +( + pointer Module, + pointer Options, + int *ErrorMajor, + int *ErrorMinor +) +{ + static Bool Inited = FALSE; + + if (!Inited) + { + /* Ensure main driver module is loaded, but not as a submodule */ + if (!xf86ServerIsOnlyDetecting() && !LoaderSymbol(ATI_NAME)) + xf86LoadOneModule(ATI_DRIVER_NAME, Options); + + Inited = TRUE; + } + + return (pointer)TRUE; +} + +/* The following record must be called radeonModuleData */ +XF86ModuleData radeonModuleData = +{ + &RADEONVersionRec, + RADEONSetup, + NULL +}; + +#endif /* XFree86LOADER */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c new file mode 100644 index 000000000..e4200f689 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c @@ -0,0 +1,185 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.c,v 1.1 2000/11/02 16:55:44 tsi Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario + * and Precision Insight, Inc., Cedar Park, Texas. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Rickard E. Faith <faith@precisioninsight.com> + * Kevin E. Martin <kevin@precisioninsight.com> + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + +#include "atimodule.h" +#include "ativersion.h" + +#include "radeon_probe.h" +#include "radeon_version.h" + +#include "xf86PciInfo.h" + +#include "xf86.h" +#include "xf86_ansic.h" +#include "xf86Resources.h" + +SymTabRec RADEONChipsets[] = { + { PCI_CHIP_RADEON_QD, "ATI Radeon QD (AGP)" }, + { PCI_CHIP_RADEON_QE, "ATI Radeon QE (AGP)" }, + { PCI_CHIP_RADEON_QF, "ATI Radeon QF (AGP)" }, + { PCI_CHIP_RADEON_QG, "ATI Radeon QG (AGP)" }, + { -1, NULL } +}; + +PciChipsets RADEONPciChipsets[] = { + { PCI_CHIP_RADEON_QD, PCI_CHIP_RADEON_QD, RES_SHARED_VGA }, + { PCI_CHIP_RADEON_QE, PCI_CHIP_RADEON_QE, RES_SHARED_VGA }, + { PCI_CHIP_RADEON_QF, PCI_CHIP_RADEON_QF, RES_SHARED_VGA }, + { PCI_CHIP_RADEON_QG, PCI_CHIP_RADEON_QG, RES_SHARED_VGA }, + { -1, -1, RES_UNDEFINED } +}; + +/* Return the options for supported chipset 'n'; NULL otherwise */ +OptionInfoPtr +RADEONAvailableOptions(int chipid, int busid) +{ + int i; + + /* + * Return options defined in the radeon submodule which will have been + * loaded by this point. + */ + for (i = 0; RADEONPciChipsets[i].PCIid > 0; i++) { + if (chipid == RADEONPciChipsets[i].PCIid) + return RADEONOptions; + } + return NULL; +} + +/* Return the string name for supported chipset 'n'; NULL otherwise. */ +void +RADEONIdentify(int flags) +{ + xf86PrintChipsets(RADEON_NAME, + "Driver for ATI Radeon chipsets", + RADEONChipsets); +} + +/* Return TRUE if chipset is present; FALSE otherwise. */ +Bool +RADEONProbe(DriverPtr drv, int flags) +{ + int numUsed; + int numDevSections, nATIGDev, nRadeonGDev; + int *usedChips; + GDevPtr *devSections, *ATIGDevs, *RadeonGDevs; + EntityInfoPtr pEnt; + Bool foundScreen = FALSE; + int i; + + if (!xf86GetPciVideoInfo()) return FALSE; + + /* Collect unclaimed device sections for both driver names */ + nATIGDev = xf86MatchDevice(ATI_NAME, &ATIGDevs); + nRadeonGDev = xf86MatchDevice(RADEON_NAME, &RadeonGDevs); + + if (!(numDevSections = nATIGDev + nRadeonGDev)) return FALSE; + + if (!ATIGDevs) { + if (!(devSections = RadeonGDevs)) + numDevSections = 1; + else + numDevSections = nRadeonGDev; + } if (!RadeonGDevs) { + devSections = ATIGDevs; + numDevSections = nATIGDev; + } else { + /* Combine into one list */ + devSections = xnfalloc((numDevSections + 1) * sizeof(GDevPtr)); + (void)memcpy(devSections, + ATIGDevs, nATIGDev * sizeof(GDevPtr)); + (void)memcpy(devSections + nATIGDev, + RadeonGDevs, nRadeonGDev * sizeof(GDevPtr)); + devSections[numDevSections] = NULL; + xfree(ATIGDevs); + xfree(RadeonGDevs); + } + + numUsed = xf86MatchPciInstances(RADEON_NAME, + PCI_VENDOR_ATI, + RADEONChipsets, + RADEONPciChipsets, + devSections, + numDevSections, + drv, + &usedChips); + + if (numUsed<=0) return FALSE; + + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) { + pEnt = xf86GetEntityInfo(usedChips[i]); + + if (pEnt->active) { + ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); + +#ifdef XFree86LOADER + if (!xf86LoadSubModule(pScrn, "radeon")) { + xf86Msg(X_ERROR, + RADEON_NAME ": Failed to load \"radeon\" module.\n"); + xf86DeleteScreen(pScrn->scrnIndex, 0); + continue; + } + + xf86LoaderReqSymLists(RADEONSymbols, NULL); +#endif + + pScrn->driverVersion = RADEON_VERSION_CURRENT; + pScrn->driverName = RADEON_DRIVER_NAME; + pScrn->name = RADEON_NAME; + pScrn->Probe = RADEONProbe; + pScrn->PreInit = RADEONPreInit; + pScrn->ScreenInit = RADEONScreenInit; + pScrn->SwitchMode = RADEONSwitchMode; + pScrn->AdjustFrame = RADEONAdjustFrame; + pScrn->EnterVT = RADEONEnterVT; + pScrn->LeaveVT = RADEONLeaveVT; + pScrn->FreeScreen = RADEONFreeScreen; + pScrn->ValidMode = RADEONValidMode; + + foundScreen = TRUE; + + xf86ConfigActivePciEntity(pScrn, usedChips[i], RADEONPciChipsets, + 0, 0, 0, 0, 0); + } + xfree(pEnt); + } + + if (numUsed) xfree(usedChips); + xfree(devSections); + + return foundScreen; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.h new file mode 100644 index 000000000..9cb8bf007 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.h @@ -0,0 +1,73 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_probe.h,v 1.1 2000/11/02 16:55:45 tsi Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and VA Linux Systems, Inc., Sunnyvale, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * + * Modified by Marc Aurele La France <tsi@xfree86.org> for ATI driver merge. + */ + +#ifndef _RADEON_PROBE_H_ +#define _RADEON_PROBE_H_ 1 + +#include "atiproto.h" + +#include "xf86str.h" + +/* radeon_probe.c */ +extern OptionInfoPtr RADEONAvailableOptions + FunctionPrototype((int, int)); +extern void RADEONIdentify + FunctionPrototype((int)); +extern Bool RADEONProbe + FunctionPrototype((DriverPtr, int)); + +extern SymTabRec RADEONChipsets[]; +extern PciChipsets RADEONPciChipsets[]; + +/* radeon_driver.c */ +extern Bool RADEONPreInit + FunctionPrototype((ScrnInfoPtr, int)); +extern Bool RADEONScreenInit + FunctionPrototype((int, ScreenPtr, int, char **)); +extern Bool RADEONSwitchMode + FunctionPrototype((int, DisplayModePtr, int)); +extern void RADEONAdjustFrame + FunctionPrototype((int, int, int, int)); +extern Bool RADEONEnterVT + FunctionPrototype((int, int)); +extern void RADEONLeaveVT + FunctionPrototype((int, int)); +extern void RADEONFreeScreen + FunctionPrototype((int, int)); +extern int RADEONValidMode + FunctionPrototype((int, DisplayModePtr, Bool, int)); + +extern OptionInfoRec RADEONOptions[]; + +#endif /* _RADEON_PROBE_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h new file mode 100644 index 000000000..e3afbe77d --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h @@ -0,0 +1,1476 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v 1.1 2000/11/02 16:55:46 tsi Exp $ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario + * and VA Linux Systems, Inc., Sunnyvale, California. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Rickard E. Faith <faith@valinux.com> + * + * References: + * + * !!!! FIXME !!!! + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * !!!! FIXME !!!! + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + +/* !!!! FIXME !!!! NOTE: THIS FILE HAS BEEN CONVERTED FROM r128_reg.h + * AND CONTAINS REGISTERS AND REGISTER DEFINITIONS THAT ARE NOT CORRECT + * ON THE RADEON. A FULL AUDIT OF THIS CODE IS NEEDED! */ + +#ifndef _RADEON_REG_H_ +#define _RADEON_REG_H_ +#include <compiler.h> + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(RADEONMMIO, addr) +#define INREG16(addr) MMIO_IN16(RADEONMMIO, addr) +#define INREG(addr) MMIO_IN32(RADEONMMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(RADEONMMIO, addr, val) +#define OUTREG16(addr, val) MMIO_OUT16(RADEONMMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(RADEONMMIO, addr, val) + +#define ADDRREG(addr) ((volatile CARD32 *)(RADEONMMIO + (addr))) + + +#define OUTREGP(addr, val, mask) \ + do { \ + CARD32 tmp = INREG(addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTREG(addr, tmp); \ + } while (0) + +#define INPLL(pScrn, addr) RADEONINPLL(pScrn, addr) + +#if !RADEON_ATOMIC_UPDATE +#define OUTPLL(addr, val) \ + do { \ + while ( (INREG(RADEON_CLOCK_CNTL_INDEX) & 0x9f) != \ + (addr | RADEON_PLL_WR_EN)) { \ + OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x1f) | \ + RADEON_PLL_WR_EN)); \ + } \ + OUTREG(RADEON_CLOCK_CNTL_DATA, val); \ + } while (0) +#else +#define OUTPLL(addr, val) \ + do { \ + OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x1f) | \ + RADEON_PLL_WR_EN)); \ + OUTREG(RADEON_CLOCK_CNTL_DATA, val); \ + } while (0) +#endif + +#define OUTPLLP(pScrn, addr, val, mask) \ + do { \ + CARD32 tmp = INPLL(pScrn, addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTPLL(addr, tmp); \ + } while (0) + +#define OUTPAL_START(idx) \ + do { \ + OUTREG8(RADEON_PALETTE_INDEX, (idx)); \ + } while (0) + +#define OUTPAL_NEXT(r, g, b) \ + do { \ + OUTREG(RADEON_PALETTE_DATA, ((r) << 16) | ((g) << 8) | (b)); \ + } while (0) + +#define OUTPAL_NEXT_CARD32(v) \ + do { \ + OUTREG(RADEON_PALETTE_DATA, (v & 0x00ffffff)); \ + } while (0) + +#define OUTPAL(idx, r, g, b) \ + do { \ + OUTPAL_START((idx)); \ + OUTPAL_NEXT((r), (g), (b)); \ + } while (0) + +#define INPAL_START(idx) \ + do { \ + OUTREG(RADEON_PALETTE_INDEX, (idx) << 16); \ + } while (0) + +#define INPAL_NEXT() INREG(RADEON_PALETTE_DATA) + +#define PAL_SELECT(idx) \ + do { \ + if (idx) { \ + OUTREG(RADEON_DAC_CNTL, INREG(RADEON_DAC_CNTL) | \ + RADEON_DAC_PALETTE_ACC_CTL); \ + } else { \ + OUTREG(RADEON_DAC_CNTL, INREG(RADEON_DAC_CNTL) & \ + ~RADEON_DAC_PALETTE_ACC_CTL); \ + } \ + } while (0) + +#define RADEON_ADAPTER_ID 0x0f2c /* PCI */ +#define RADEON_AGP_BASE 0x0170 +#define RADEON_AGP_CNTL 0x0174 +# define RADEON_AGP_APER_SIZE_256MB (0x00 << 0) +# define RADEON_AGP_APER_SIZE_128MB (0x20 << 0) +# define RADEON_AGP_APER_SIZE_64MB (0x30 << 0) +# define RADEON_AGP_APER_SIZE_32MB (0x38 << 0) +# define RADEON_AGP_APER_SIZE_16MB (0x3c << 0) +# define RADEON_AGP_APER_SIZE_8MB (0x3e << 0) +# define RADEON_AGP_APER_SIZE_4MB (0x3f << 0) +# define RADEON_AGP_APER_SIZE_MASK (0x3f << 0) +#define RADEON_AGP_COMMAND 0x0f60 /* PCI */ +#define RADEON_AGP_PLL_CNTL 0x000b /* PLL */ +#define RADEON_AGP_STATUS 0x0f5c /* PCI */ +# define RADEON_AGP_1X_MODE 0x01 +# define RADEON_AGP_2X_MODE 0x02 +# define RADEON_AGP_4X_MODE 0x04 +# define RADEON_AGP_MODE_MASK 0x07 +#define RADEON_AMCGPIO_A_REG 0x01a0 +#define RADEON_AMCGPIO_EN_REG 0x01a8 +#define RADEON_AMCGPIO_MASK 0x0194 +#define RADEON_AMCGPIO_Y_REG 0x01a4 +#define RADEON_ATTRDR 0x03c1 /* VGA */ +#define RADEON_ATTRDW 0x03c0 /* VGA */ +#define RADEON_ATTRX 0x03c0 /* VGA */ +# define RADEON_AUX1_SC_EN (1 << 0) +# define RADEON_AUX1_SC_MODE_OR (0 << 1) +# define RADEON_AUX1_SC_MODE_NAND (1 << 1) +# define RADEON_AUX2_SC_EN (1 << 2) +# define RADEON_AUX2_SC_MODE_OR (0 << 3) +# define RADEON_AUX2_SC_MODE_NAND (1 << 3) +# define RADEON_AUX3_SC_EN (1 << 4) +# define RADEON_AUX3_SC_MODE_OR (0 << 5) +# define RADEON_AUX3_SC_MODE_NAND (1 << 5) +#define RADEON_AUX_SC_CNTL 0x1660 +#define RADEON_AUX1_SC_BOTTOM 0x1670 +#define RADEON_AUX1_SC_LEFT 0x1664 +#define RADEON_AUX1_SC_RIGHT 0x1668 +#define RADEON_AUX1_SC_TOP 0x166c +#define RADEON_AUX2_SC_BOTTOM 0x1680 +#define RADEON_AUX2_SC_LEFT 0x1674 +#define RADEON_AUX2_SC_RIGHT 0x1678 +#define RADEON_AUX2_SC_TOP 0x167c +#define RADEON_AUX3_SC_BOTTOM 0x1690 +#define RADEON_AUX3_SC_LEFT 0x1684 +#define RADEON_AUX3_SC_RIGHT 0x1688 +#define RADEON_AUX3_SC_TOP 0x168c +#define RADEON_AUX_WINDOW_HORZ_CNTL 0x02d8 +#define RADEON_AUX_WINDOW_VERT_CNTL 0x02dc + +#define RADEON_BASE_CODE 0x0f0b +#define RADEON_BIOS_0_SCRATCH 0x0010 +#define RADEON_BIOS_1_SCRATCH 0x0014 +#define RADEON_BIOS_2_SCRATCH 0x0018 +#define RADEON_BIOS_3_SCRATCH 0x001c +#define RADEON_BIOS_ROM 0x0f30 /* PCI */ +#define RADEON_BIST 0x0f0f /* PCI */ +#define RADEON_BRUSH_DATA0 0x1480 +#define RADEON_BRUSH_DATA1 0x1484 +#define RADEON_BRUSH_DATA10 0x14a8 +#define RADEON_BRUSH_DATA11 0x14ac +#define RADEON_BRUSH_DATA12 0x14b0 +#define RADEON_BRUSH_DATA13 0x14b4 +#define RADEON_BRUSH_DATA14 0x14b8 +#define RADEON_BRUSH_DATA15 0x14bc +#define RADEON_BRUSH_DATA16 0x14c0 +#define RADEON_BRUSH_DATA17 0x14c4 +#define RADEON_BRUSH_DATA18 0x14c8 +#define RADEON_BRUSH_DATA19 0x14cc +#define RADEON_BRUSH_DATA2 0x1488 +#define RADEON_BRUSH_DATA20 0x14d0 +#define RADEON_BRUSH_DATA21 0x14d4 +#define RADEON_BRUSH_DATA22 0x14d8 +#define RADEON_BRUSH_DATA23 0x14dc +#define RADEON_BRUSH_DATA24 0x14e0 +#define RADEON_BRUSH_DATA25 0x14e4 +#define RADEON_BRUSH_DATA26 0x14e8 +#define RADEON_BRUSH_DATA27 0x14ec +#define RADEON_BRUSH_DATA28 0x14f0 +#define RADEON_BRUSH_DATA29 0x14f4 +#define RADEON_BRUSH_DATA3 0x148c +#define RADEON_BRUSH_DATA30 0x14f8 +#define RADEON_BRUSH_DATA31 0x14fc +#define RADEON_BRUSH_DATA32 0x1500 +#define RADEON_BRUSH_DATA33 0x1504 +#define RADEON_BRUSH_DATA34 0x1508 +#define RADEON_BRUSH_DATA35 0x150c +#define RADEON_BRUSH_DATA36 0x1510 +#define RADEON_BRUSH_DATA37 0x1514 +#define RADEON_BRUSH_DATA38 0x1518 +#define RADEON_BRUSH_DATA39 0x151c +#define RADEON_BRUSH_DATA4 0x1490 +#define RADEON_BRUSH_DATA40 0x1520 +#define RADEON_BRUSH_DATA41 0x1524 +#define RADEON_BRUSH_DATA42 0x1528 +#define RADEON_BRUSH_DATA43 0x152c +#define RADEON_BRUSH_DATA44 0x1530 +#define RADEON_BRUSH_DATA45 0x1534 +#define RADEON_BRUSH_DATA46 0x1538 +#define RADEON_BRUSH_DATA47 0x153c +#define RADEON_BRUSH_DATA48 0x1540 +#define RADEON_BRUSH_DATA49 0x1544 +#define RADEON_BRUSH_DATA5 0x1494 +#define RADEON_BRUSH_DATA50 0x1548 +#define RADEON_BRUSH_DATA51 0x154c +#define RADEON_BRUSH_DATA52 0x1550 +#define RADEON_BRUSH_DATA53 0x1554 +#define RADEON_BRUSH_DATA54 0x1558 +#define RADEON_BRUSH_DATA55 0x155c +#define RADEON_BRUSH_DATA56 0x1560 +#define RADEON_BRUSH_DATA57 0x1564 +#define RADEON_BRUSH_DATA58 0x1568 +#define RADEON_BRUSH_DATA59 0x156c +#define RADEON_BRUSH_DATA6 0x1498 +#define RADEON_BRUSH_DATA60 0x1570 +#define RADEON_BRUSH_DATA61 0x1574 +#define RADEON_BRUSH_DATA62 0x1578 +#define RADEON_BRUSH_DATA63 0x157c +#define RADEON_BRUSH_DATA7 0x149c +#define RADEON_BRUSH_DATA8 0x14a0 +#define RADEON_BRUSH_DATA9 0x14a4 +#define RADEON_BRUSH_SCALE 0x1470 +#define RADEON_BRUSH_Y_X 0x1474 +#define RADEON_BUS_CNTL 0x0030 +# define RADEON_BUS_MASTER_DIS (1 << 6) +# define RADEON_BUS_RD_DISCARD_EN (1 << 24) +# define RADEON_BUS_RD_ABORT_EN (1 << 25) +# define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) +# define RADEON_BUS_WRT_BURST (1 << 29) +# define RADEON_BUS_READ_BURST (1 << 30) +#define RADEON_BUS_CNTL1 0x0034 +# define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) + +#define RADEON_CACHE_CNTL 0x1724 +#define RADEON_CACHE_LINE 0x0f0c /* PCI */ +#define RADEON_CAP0_TRIG_CNTL 0x0950 /* ? */ +#define RADEON_CAP1_TRIG_CNTL 0x09c0 /* ? */ +#define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */ +#define RADEON_CAPABILITIES_PTR 0x0f34 /* PCI */ +#define RADEON_CLK_PIN_CNTL 0x0001 /* PLL */ +#define RADEON_CLOCK_CNTL_DATA 0x000c +#define RADEON_CLOCK_CNTL_INDEX 0x0008 +# define RADEON_PLL_WR_EN (1 << 7) +# define RADEON_PLL_DIV_SEL (3 << 8) +#define RADEON_CLR_CMP_CLR_3D 0x1a24 +#define RADEON_CLR_CMP_CLR_DST 0x15c8 +#define RADEON_CLR_CMP_CLR_SRC 0x15c4 +#define RADEON_CLR_CMP_CNTL 0x15c0 +# define RADEON_SRC_CMP_EQ_COLOR (4 << 0) +# define RADEON_SRC_CMP_NEQ_COLOR (5 << 0) +# define RADEON_CLR_CMP_SRC_SOURCE (1 << 24) +#define RADEON_CLR_CMP_MASK 0x15cc +# define RADEON_CLR_CMP_MSK 0xffffffff +#define RADEON_CLR_CMP_MASK_3D 0x1A28 +#define RADEON_COMMAND 0x0f04 /* PCI */ +#define RADEON_COMPOSITE_SHADOW_ID 0x1a0c +#define RADEON_CONFIG_APER_0_BASE 0x0100 +#define RADEON_CONFIG_APER_1_BASE 0x0104 +#define RADEON_CONFIG_APER_SIZE 0x0108 +#define RADEON_CONFIG_BONDS 0x00e8 +#define RADEON_CONFIG_CNTL 0x00e0 +#define RADEON_CONFIG_MEMSIZE 0x00f8 +#define RADEON_CONFIG_MEMSIZE_EMBEDDED 0x0114 +#define RADEON_CONFIG_REG_1_BASE 0x010c +#define RADEON_CONFIG_REG_APER_SIZE 0x0110 +#define RADEON_CONFIG_XSTRAP 0x00e4 +#define RADEON_CONSTANT_COLOR_C 0x1d34 +# define RADEON_CONSTANT_COLOR_MASK 0x00ffffff +# define RADEON_CONSTANT_COLOR_ONE 0x00ffffff +# define RADEON_CONSTANT_COLOR_ZERO 0x00000000 +#define RADEON_CRC_CMDFIFO_ADDR 0x0740 +#define RADEON_CRC_CMDFIFO_DOUT 0x0744 +#define RADEON_CRTC_CRNT_FRAME 0x0214 +#define RADEON_CRTC_DEBUG 0x021c +#define RADEON_CRTC_EXT_CNTL 0x0054 +# define RADEON_CRTC_VGA_XOVERSCAN (1 << 0) +# define RADEON_VGA_ATI_LINEAR (1 << 3) +# define RADEON_XCRT_CNT_EN (1 << 6) +# define RADEON_CRTC_HSYNC_DIS (1 << 8) +# define RADEON_CRTC_VSYNC_DIS (1 << 9) +# define RADEON_CRTC_DISPLAY_DIS (1 << 10) +# define RADEON_CRTC_CRT_ON (1 << 15) +#define RADEON_CRTC_EXT_CNTL_DPMS_BYTE 0x0055 +# define RADEON_CRTC_HSYNC_DIS_BYTE (1 << 0) +# define RADEON_CRTC_VSYNC_DIS_BYTE (1 << 1) +# define RADEON_CRTC_DISPLAY_DIS_BYTE (1 << 2) +#define RADEON_CRTC_GEN_CNTL 0x0050 +# define RADEON_CRTC_DBL_SCAN_EN (1 << 0) +# define RADEON_CRTC_INTERLACE_EN (1 << 1) +# define RADEON_CRTC_CSYNC_EN (1 << 4) +# define RADEON_CRTC_CUR_EN (1 << 16) +# define RADEON_CRTC_CUR_MODE_MASK (7 << 17) +# define RADEON_CRTC_ICON_EN (1 << 20) +# define RADEON_CRTC_EXT_DISP_EN (1 << 24) +# define RADEON_CRTC_EN (1 << 25) +# define RADEON_CRTC_DISP_REQ_EN_B (1 << 26) +#define RADEON_CRTC_GUI_TRIG_VLINE 0x0218 +#define RADEON_CRTC_H_SYNC_STRT_WID 0x0204 +# define RADEON_CRTC_H_SYNC_STRT_PIX (0x07 << 0) +# define RADEON_CRTC_H_SYNC_STRT_CHAR (0x1ff << 3) +# define RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT 3 +# define RADEON_CRTC_H_SYNC_WID (0x3f << 16) +# define RADEON_CRTC_H_SYNC_WID_SHIFT 16 +# define RADEON_CRTC_H_SYNC_POL (1 << 23) +#define RADEON_CRTC_H_TOTAL_DISP 0x0200 +# define RADEON_CRTC_H_TOTAL (0x01ff << 0) +# define RADEON_CRTC_H_TOTAL_SHIFT 0 +# define RADEON_CRTC_H_DISP (0x00ff << 16) +# define RADEON_CRTC_H_DISP_SHIFT 16 +#define RADEON_CRTC_OFFSET 0x0224 +#define RADEON_CRTC_OFFSET_CNTL 0x0228 +#define RADEON_CRTC_PITCH 0x022c +#define RADEON_CRTC_STATUS 0x005c +# define RADEON_CRTC_VBLANK_SAVE (1 << 1) +#define RADEON_CRTC_V_SYNC_STRT_WID 0x020c +# define RADEON_CRTC_V_SYNC_STRT (0x7ff << 0) +# define RADEON_CRTC_V_SYNC_STRT_SHIFT 0 +# define RADEON_CRTC_V_SYNC_WID (0x1f << 16) +# define RADEON_CRTC_V_SYNC_WID_SHIFT 16 +# define RADEON_CRTC_V_SYNC_POL (1 << 23) +#define RADEON_CRTC_V_TOTAL_DISP 0x0208 +# define RADEON_CRTC_V_TOTAL (0x07ff << 0) +# define RADEON_CRTC_V_TOTAL_SHIFT 0 +# define RADEON_CRTC_V_DISP (0x07ff << 16) +# define RADEON_CRTC_V_DISP_SHIFT 16 +#define RADEON_CRTC_VLINE_CRNT_VLINE 0x0210 +# define RADEON_CRTC_CRNT_VLINE_MASK (0x7ff << 16) +#define RADEON_CRTC2_CRNT_FRAME 0x0314 +#define RADEON_CRTC2_DEBUG 0x031c +#define RADEON_CRTC2_GEN_CNTL 0x03f8 +#define RADEON_CRTC2_GUI_TRIG_VLINE 0x0318 +#define RADEON_CRTC2_H_SYNC_STRT_WID 0x0304 +#define RADEON_CRTC2_H_TOTAL_DISP 0x0300 +#define RADEON_CRTC2_OFFSET 0x0324 +#define RADEON_CRTC2_OFFSET_CNTL 0x0328 +#define RADEON_CRTC2_PITCH 0x032c +#define RADEON_CRTC2_STATUS 0x03fc +#define RADEON_CRTC2_V_SYNC_STRT_WID 0x030c +#define RADEON_CRTC2_V_TOTAL_DISP 0x0308 +#define RADEON_CRTC2_VLINE_CRNT_VLINE 0x0310 +#define RADEON_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ +#define RADEON_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ +#define RADEON_CUR_CLR0 0x026c +#define RADEON_CUR_CLR1 0x0270 +#define RADEON_CUR_HORZ_VERT_OFF 0x0268 +#define RADEON_CUR_HORZ_VERT_POSN 0x0264 +#define RADEON_CUR_OFFSET 0x0260 +# define RADEON_CUR_LOCK (1 << 31) + +#define RADEON_DAC_CNTL 0x0058 +# define RADEON_DAC_RANGE_CNTL (3 << 0) +# define RADEON_DAC_BLANKING (1 << 2) +# define RADEON_DAC_CRT_SEL_CRTC2 (1 << 4) +# define RADEON_DAC_PALETTE_ACC_CTL (1 << 5) +# define RADEON_DAC_8BIT_EN (1 << 8) +# define RADEON_DAC_VGA_ADR_EN (1 << 13) +# define RADEON_DAC_MASK_ALL (0xff << 24) +#define RADEON_DAC_CRC_SIG 0x02cc +#define RADEON_DAC_DATA 0x03c9 /* VGA */ +#define RADEON_DAC_MASK 0x03c6 /* VGA */ +#define RADEON_DAC_R_INDEX 0x03c7 /* VGA */ +#define RADEON_DAC_W_INDEX 0x03c8 /* VGA */ +#define RADEON_DDA_CONFIG 0x02e0 +#define RADEON_DDA_ON_OFF 0x02e4 +#define RADEON_DEFAULT_OFFSET 0x16e0 +#define RADEON_DEFAULT_PITCH 0x16e4 +#define RADEON_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 +# define RADEON_DEFAULT_SC_RIGHT_MAX (0x1fff << 0) +# define RADEON_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) +#define RADEON_DESTINATION_3D_CLR_CMP_VAL 0x1820 +#define RADEON_DESTINATION_3D_CLR_CMP_MSK 0x1824 +#define RADEON_DEVICE_ID 0x0f02 /* PCI */ +#define RADEON_DISP_MISC_CNTL 0x0d00 +# define RADEON_SOFT_RESET_GRPH_PP (1 << 0) +#define RADEON_DP_BRUSH_BKGD_CLR 0x1478 +#define RADEON_DP_BRUSH_FRGD_CLR 0x147c +#define RADEON_DP_CNTL 0x16c0 +# define RADEON_DST_X_LEFT_TO_RIGHT (1 << 0) +# define RADEON_DST_Y_TOP_TO_BOTTOM (1 << 1) +#define RADEON_DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0 +# define RADEON_DST_Y_MAJOR (1 << 2) +# define RADEON_DST_Y_DIR_TOP_TO_BOTTOM (1 << 15) +# define RADEON_DST_X_DIR_LEFT_TO_RIGHT (1 << 31) +#define RADEON_DP_DATATYPE 0x16c4 +# define RADEON_HOST_BIG_ENDIAN_EN (1 << 29) +#define RADEON_DP_GUI_MASTER_CNTL 0x146c +# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) +# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) +# define RADEON_GMC_SRC_CLIPPING (1 << 2) +# define RADEON_GMC_DST_CLIPPING (1 << 3) +# define RADEON_GMC_BRUSH_DATATYPE_MASK (0x0f << 4) +# define RADEON_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4) +# define RADEON_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4) +# define RADEON_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4) +# define RADEON_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) +# define RADEON_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) +# define RADEON_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) +# define RADEON_GMC_BRUSH_8x8_COLOR (10 << 4) +# define RADEON_GMC_BRUSH_1X8_COLOR (12 << 4) +# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) +# define RADEON_GMC_BRUSH_NONE (15 << 4) +# define RADEON_GMC_DST_8BPP_CI (2 << 8) +# define RADEON_GMC_DST_15BPP (3 << 8) +# define RADEON_GMC_DST_16BPP (4 << 8) +# define RADEON_GMC_DST_24BPP (5 << 8) +# define RADEON_GMC_DST_32BPP (6 << 8) +# define RADEON_GMC_DST_8BPP_RGB (7 << 8) +# define RADEON_GMC_DST_Y8 (8 << 8) +# define RADEON_GMC_DST_RGB8 (9 << 8) +# define RADEON_GMC_DST_VYUY (11 << 8) +# define RADEON_GMC_DST_YVYU (12 << 8) +# define RADEON_GMC_DST_AYUV444 (14 << 8) +# define RADEON_GMC_DST_ARGB4444 (15 << 8) +# define RADEON_GMC_DST_DATATYPE_MASK (0x0f << 8) +# define RADEON_GMC_DST_DATATYPE_SHIFT 8 +# define RADEON_GMC_SRC_DATATYPE_MASK (3 << 12) +# define RADEON_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12) +# define RADEON_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12) +# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) +# define RADEON_GMC_BYTE_PIX_ORDER (1 << 14) +# define RADEON_GMC_BYTE_MSB_TO_LSB (0 << 14) +# define RADEON_GMC_BYTE_LSB_TO_MSB (1 << 14) +# define RADEON_GMC_CONVERSION_TEMP (1 << 15) +# define RADEON_GMC_CONVERSION_TEMP_6500 (0 << 15) +# define RADEON_GMC_CONVERSION_TEMP_9300 (1 << 15) +# define RADEON_GMC_ROP3_MASK (0xff << 16) +# define RADEON_DP_SRC_SOURCE_MASK (7 << 24) +# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) +# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) +# define RADEON_GMC_3D_FCN_EN (1 << 27) +# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define RADEON_GMC_AUX_CLIP_DIS (1 << 29) +# define RADEON_GMC_WR_MSK_DIS (1 << 30) +# define RADEON_GMC_LD_BRUSH_Y_X (1 << 31) +# define RADEON_ROP3_ZERO 0x00000000 +# define RADEON_ROP3_DSa 0x00880000 +# define RADEON_ROP3_SDna 0x00440000 +# define RADEON_ROP3_S 0x00cc0000 +# define RADEON_ROP3_DSna 0x00220000 +# define RADEON_ROP3_D 0x00aa0000 +# define RADEON_ROP3_DSx 0x00660000 +# define RADEON_ROP3_DSo 0x00ee0000 +# define RADEON_ROP3_DSon 0x00110000 +# define RADEON_ROP3_DSxn 0x00990000 +# define RADEON_ROP3_Dn 0x00550000 +# define RADEON_ROP3_SDno 0x00dd0000 +# define RADEON_ROP3_Sn 0x00330000 +# define RADEON_ROP3_DSno 0x00bb0000 +# define RADEON_ROP3_DSan 0x00770000 +# define RADEON_ROP3_ONE 0x00ff0000 +# define RADEON_ROP3_DPa 0x00a00000 +# define RADEON_ROP3_PDna 0x00500000 +# define RADEON_ROP3_P 0x00f00000 +# define RADEON_ROP3_DPna 0x000a0000 +# define RADEON_ROP3_D 0x00aa0000 +# define RADEON_ROP3_DPx 0x005a0000 +# define RADEON_ROP3_DPo 0x00fa0000 +# define RADEON_ROP3_DPon 0x00050000 +# define RADEON_ROP3_PDxn 0x00a50000 +# define RADEON_ROP3_PDno 0x00f50000 +# define RADEON_ROP3_Pn 0x000f0000 +# define RADEON_ROP3_DPno 0x00af0000 +# define RADEON_ROP3_DPan 0x005f0000 + + +#define RADEON_DP_GUI_MASTER_CNTL_C 0x1c84 +#define RADEON_DP_MIX 0x16c8 +#define RADEON_DP_SRC_BKGD_CLR 0x15dc +#define RADEON_DP_SRC_FRGD_CLR 0x15d8 +#define RADEON_DP_WRITE_MASK 0x16cc +#define RADEON_DST_BRES_DEC 0x1630 +#define RADEON_DST_BRES_ERR 0x1628 +#define RADEON_DST_BRES_INC 0x162c +#define RADEON_DST_BRES_LNTH 0x1634 +#define RADEON_DST_BRES_LNTH_SUB 0x1638 +#define RADEON_DST_HEIGHT 0x1410 +#define RADEON_DST_HEIGHT_WIDTH 0x143c +#define RADEON_DST_HEIGHT_WIDTH_8 0x158c +#define RADEON_DST_HEIGHT_WIDTH_BW 0x15b4 +#define RADEON_DST_HEIGHT_Y 0x15a0 +#define RADEON_DST_LINE_START 0x1600 +#define RADEON_DST_LINE_END 0x1604 +#define RADEON_DST_OFFSET 0x1404 +#define RADEON_DST_PITCH 0x1408 +#define RADEON_DST_PITCH_OFFSET 0x142c +#define RADEON_DST_PITCH_OFFSET_C 0x1c80 +# define RADEON_PITCH_SHIFT 21 +#define RADEON_DST_WIDTH 0x140c +#define RADEON_DST_WIDTH_HEIGHT 0x1598 +#define RADEON_DST_WIDTH_X 0x1588 +#define RADEON_DST_WIDTH_X_INCY 0x159c +#define RADEON_DST_X 0x141c +#define RADEON_DST_X_SUB 0x15a4 +#define RADEON_DST_X_Y 0x1594 +#define RADEON_DST_Y 0x1420 +#define RADEON_DST_Y_SUB 0x15a8 +#define RADEON_DST_Y_X 0x1438 + +#define RADEON_FCP_CNTL 0x0012 /* PLL */ +#define RADEON_FLUSH_1 0x1704 +#define RADEON_FLUSH_2 0x1708 +#define RADEON_FLUSH_3 0x170c +#define RADEON_FLUSH_4 0x1710 +#define RADEON_FLUSH_5 0x1714 +#define RADEON_FLUSH_6 0x1718 +#define RADEON_FLUSH_7 0x171c +#define RADEON_FOG_3D_TABLE_START 0x1810 +#define RADEON_FOG_3D_TABLE_END 0x1814 +#define RADEON_FOG_3D_TABLE_DENSITY 0x181c +#define RADEON_FOG_TABLE_INDEX 0x1a14 +#define RADEON_FOG_TABLE_DATA 0x1a18 +#define RADEON_FP_CRTC_H_TOTAL_DISP 0x0250 +#define RADEON_FP_CRTC_V_TOTAL_DISP 0x0254 +#define RADEON_FP_GEN_CNTL 0x0284 +# define RADEON_FP_FPON (1 << 0) +# define RADEON_FP_TDMS_EN (1 << 2) +# define RADEON_FP_DETECT_SENSE (1 << 8) +# define RADEON_FP_SEL_CRTC2 (1 << 13) +# define RADEON_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) +# define RADEON_FP_CRTC_USE_SHADOW_VEND (1 << 18) +# define RADEON_FP_CRTC_HORZ_DIV2_EN (1 << 20) +# define RADEON_FP_CRTC_HOR_CRT_DIV2_DIS (1 << 21) +# define RADEON_FP_USE_SHADOW_EN (1 << 24) +#define RADEON_FP_H_SYNC_STRT_WID 0x02c4 +#define RADEON_FP_HORZ_STRETCH 0x028c +# define RADEON_HORZ_STRETCH_RATIO_MASK 0xffff +# define RADEON_HORZ_STRETCH_RATIO_SHIFT 0 +# define RADEON_HORZ_STRETCH_RATIO_MAX 4096 +# define RADEON_HORZ_PANEL_SIZE (0xff << 16) +# define RADEON_HORZ_PANEL_SHIFT 16 +# define RADEON_HORZ_STRETCH_PIXREP (0 << 25) +# define RADEON_HORZ_STRETCH_BLEND (1 << 25) +# define RADEON_HORZ_STRETCH_ENABLE (1 << 26) +# define RADEON_HORZ_FP_LOOP_STRETCH (0x7 << 27) +# define RADEON_HORZ_STRETCH_RESERVED (1 << 30) +# define RADEON_HORZ_AUTO_RATIO_FIX_EN (1 << 31) + +#define RADEON_FP_PANEL_CNTL 0x0288 +# define RADEON_FP_DIGON (1 << 0) +# define RADEON_FP_BLON (1 << 1) +#define RADEON_FP_V_SYNC_STRT_WID 0x02c8 +#define RADEON_FP_VERT_STRETCH 0x0290 +# define RADEON_VERT_PANEL_SIZE (0x7ff << 0) +# define RADEON_VERT_PANEL_SHIFT 0 +# define RADEON_VERT_STRETCH_RATIO_MASK 0x3ff +# define RADEON_VERT_STRETCH_RATIO_SHIFT 11 +# define RADEON_VERT_STRETCH_RATIO_MAX 1024 +# define RADEON_VERT_STRETCH_ENABLE (1 << 24) +# define RADEON_VERT_STRETCH_LINEREP (0 << 25) +# define RADEON_VERT_STRETCH_BLEND (1 << 25) +# define RADEON_VERT_AUTO_RATIO_EN (1 << 26) +# define RADEON_VERT_STRETCH_RESERVED 0xf8e00000 + +#define RADEON_GEN_INT_CNTL 0x0040 +#define RADEON_GEN_INT_STATUS 0x0044 +# define RADEON_VSYNC_INT_AK (1 << 2) +# define RADEON_VSYNC_INT (1 << 2) +#define RADEON_RBBM_SOFT_RESET 0x00f0 +# define RADEON_SOFT_RESET_CP (1 << 0) +# define RADEON_SOFT_RESET_HI (1 << 1) +# define RADEON_SOFT_RESET_SE (1 << 2) +# define RADEON_SOFT_RESET_RE (1 << 3) +# define RADEON_SOFT_RESET_PP (1 << 4) +# define RADEON_SOFT_RESET_E2 (1 << 5) +# define RADEON_SOFT_RESET_RB (1 << 6) +# define RADEON_SOFT_RESET_HDP (1 << 7) +#define RADEON_GENENB 0x03c3 /* VGA */ +#define RADEON_GENFC_RD 0x03ca /* VGA */ +#define RADEON_GENFC_WT 0x03da /* VGA, 0x03ba */ +#define RADEON_GENMO_RD 0x03cc /* VGA */ +#define RADEON_GENMO_WT 0x03c2 /* VGA */ +#define RADEON_GENS0 0x03c2 /* VGA */ +#define RADEON_GENS1 0x03da /* VGA, 0x03ba */ +#define RADEON_GPIO_MONID 0x0068 +# define RADEON_GPIO_MONID_A_0 (1 << 0) +# define RADEON_GPIO_MONID_A_1 (1 << 1) +# define RADEON_GPIO_MONID_A_2 (1 << 2) +# define RADEON_GPIO_MONID_A_3 (1 << 3) +# define RADEON_GPIO_MONID_Y_0 (1 << 8) +# define RADEON_GPIO_MONID_Y_1 (1 << 9) +# define RADEON_GPIO_MONID_Y_2 (1 << 10) +# define RADEON_GPIO_MONID_Y_3 (1 << 11) +# define RADEON_GPIO_MONID_EN_0 (1 << 16) +# define RADEON_GPIO_MONID_EN_1 (1 << 17) +# define RADEON_GPIO_MONID_EN_2 (1 << 18) +# define RADEON_GPIO_MONID_EN_3 (1 << 19) +# define RADEON_GPIO_MONID_MASK_0 (1 << 24) +# define RADEON_GPIO_MONID_MASK_1 (1 << 25) +# define RADEON_GPIO_MONID_MASK_2 (1 << 26) +# define RADEON_GPIO_MONID_MASK_3 (1 << 27) +#define RADEON_GPIO_MONIDB 0x006c +#define RADEON_GRPH8_DATA 0x03cf /* VGA */ +#define RADEON_GRPH8_IDX 0x03ce /* VGA */ +#define RADEON_GUI_DEBUG0 0x16a0 +#define RADEON_GUI_DEBUG1 0x16a4 +#define RADEON_GUI_DEBUG2 0x16a8 +#define RADEON_GUI_DEBUG3 0x16ac +#define RADEON_GUI_DEBUG4 0x16b0 +#define RADEON_GUI_DEBUG5 0x16b4 +#define RADEON_GUI_DEBUG6 0x16b8 +#define RADEON_GUI_SCRATCH_REG0 0x15e0 +#define RADEON_GUI_SCRATCH_REG1 0x15e4 +#define RADEON_GUI_SCRATCH_REG2 0x15e8 +#define RADEON_GUI_SCRATCH_REG3 0x15ec +#define RADEON_GUI_SCRATCH_REG4 0x15f0 +#define RADEON_GUI_SCRATCH_REG5 0x15f4 +#define RADEON_HEADER 0x0f0e /* PCI */ +#define RADEON_HOST_DATA0 0x17c0 +#define RADEON_HOST_DATA1 0x17c4 +#define RADEON_HOST_DATA2 0x17c8 +#define RADEON_HOST_DATA3 0x17cc +#define RADEON_HOST_DATA4 0x17d0 +#define RADEON_HOST_DATA5 0x17d4 +#define RADEON_HOST_DATA6 0x17d8 +#define RADEON_HOST_DATA7 0x17dc +#define RADEON_HOST_DATA_LAST 0x17e0 +#define RADEON_HOST_PATH_CNTL 0x0130 +#define RADEON_HTOTAL_CNTL 0x0009 /* PLL */ +#define RADEON_HW_DEBUG 0x0128 +#define RADEON_HW_DEBUG2 0x011c + +#define RADEON_I2C_CNTL_1 0x0094 /* ? */ +#define RADEON_INTERRUPT_LINE 0x0f3c /* PCI */ +#define RADEON_INTERRUPT_PIN 0x0f3d /* PCI */ +#define RADEON_IO_BASE 0x0f14 /* PCI */ + +#define RADEON_LATENCY 0x0f0d /* PCI */ +#define RADEON_LEAD_BRES_DEC 0x1608 +#define RADEON_LEAD_BRES_LNTH 0x161c +#define RADEON_LEAD_BRES_LNTH_SUB 0x1624 +#define RADEON_LVDS_GEN_CNTL 0x02d0 +# define RADEON_LVDS_ON (1 << 0) +# define RADEON_LVDS_BLON (1 << 19) +# define RADEON_LVDS_SEL_CRTC2 (1 << 23) +# define RADEON_HSYNC_DELAY_SHIFT 28 +# define RADEON_HSYNC_DELAY_MASK (0xf << 28) + +#define RADEON_MAX_LATENCY 0x0f3f /* PCI */ +#define RADEON_MC_AGP_LOCATION 0x014c +#define RADEON_MC_FB_LOCATION 0x0148 +#define RADEON_MCLK_CNTL 0x0012 /* PLL */ +# define RADEON_FORCE_GCP (1 << 16) +# define RADEON_FORCE_PIPE3D_CP (1 << 17) +# define RADEON_FORCE_RCP (1 << 18) +#define RADEON_MDGPIO_A_REG 0x01ac +#define RADEON_MDGPIO_EN_REG 0x01b0 +#define RADEON_MDGPIO_MASK 0x0198 +#define RADEON_MDGPIO_Y_REG 0x01b4 +#define RADEON_MEM_ADDR_CONFIG 0x0148 +#define RADEON_MEM_BASE 0x0f10 /* PCI */ +#define RADEON_MEM_CNTL 0x0140 +#define RADEON_MEM_INIT_LAT_TIMER 0x0154 +#define RADEON_MEM_INTF_CNTL 0x014c +#define RADEON_MEM_SDRAM_MODE_REG 0x0158 +#define RADEON_MEM_STR_CNTL 0x0150 +#define RADEON_MEM_VGA_RP_SEL 0x003c +#define RADEON_MEM_VGA_WP_SEL 0x0038 +#define RADEON_MIN_GRANT 0x0f3e /* PCI */ +#define RADEON_MM_DATA 0x0004 +#define RADEON_MM_INDEX 0x0000 +#define RADEON_MPLL_CNTL 0x000e /* PLL */ +#define RADEON_MPP_TB_CONFIG 0x01c0 /* ? */ +#define RADEON_MPP_GP_CONFIG 0x01c8 /* ? */ + +#define RADEON_N_VIF_COUNT 0x0248 + +#define RADEON_OV0_SCALE_CNTL 0x0420 /* ? */ +#define RADEON_OVR_CLR 0x0230 +#define RADEON_OVR_WID_LEFT_RIGHT 0x0234 +#define RADEON_OVR_WID_TOP_BOTTOM 0x0238 + +/* first overlay unit (there is only one) */ + +#define RADEON_OV0_Y_X_START 0x0400 +#define RADEON_OV0_Y_X_END 0x0404 +#define RADEON_OV0_EXCLUSIVE_HORZ 0x0408 +# define RADEON_EXCL_HORZ_START_MASK 0x000000ff +# define RADEON_EXCL_HORZ_END_MASK 0x0000ff00 +# define RADEON_EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 +# define RADEON_EXCL_HORZ_EXCLUSIVE_EN 0x80000000 +#define RADEON_OV0_EXCLUSIVE_VERT 0x040C +# define RADEON_EXCL_VERT_START_MASK 0x000003ff +# define RADEON_EXCL_VERT_END_MASK 0x03ff0000 +#define RADEON_OV0_REG_LOAD_CNTL 0x0410 +# define RADEON_REG_LD_CTL_LOCK 0x00000001L +# define RADEON_REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L +# define RADEON_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L +# define RADEON_REG_LD_CTL_LOCK_READBACK 0x00000008L +#define RADEON_OV0_SCALE_CNTL 0x0420 +# define RADEON_SCALER_PIX_EXPAND 0x00000001L +# define RADEON_SCALER_Y2R_TEMP 0x00000002L +# define RADEON_SCALER_HORZ_PICK_NEAREST 0x00000003L +# define RADEON_SCALER_VERT_PICK_NEAREST 0x00000004L +# define RADEON_SCALER_SIGNED_UV 0x00000010L +# define RADEON_SCALER_GAMMA_SEL_MASK 0x00000060L +# define RADEON_SCALER_GAMMA_SEL_BRIGHT 0x00000000L +# define RADEON_SCALER_GAMMA_SEL_G22 0x00000020L +# define RADEON_SCALER_GAMMA_SEL_G18 0x00000040L +# define RADEON_SCALER_GAMMA_SEL_G14 0x00000060L +# define RADEON_SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L +# define RADEON_SCALER_SURFAC_FORMAT 0x00000f00L +# define RADEON_SCALER_SOURCE_15BPP 0x00000300L +# define RADEON_SCALER_SOURCE_16BPP 0x00000400L +# define RADEON_SCALER_SOURCE_32BPP 0x00000600L +# define RADEON_SCALER_SOURCE_YUV9 0x00000900L +# define RADEON_SCALER_SOURCE_YUV12 0x00000A00L +# define RADEON_SCALER_SOURCE_VYUY422 0x00000B00L +# define RADEON_SCALER_SOURCE_YVYU422 0x00000C00L +# define RADEON_SCALER_SMART_SWITCH 0x00008000L +# define RADEON_SCALER_BURST_PER_PLANE 0x00ff0000L +# define RADEON_SCALER_DOUBLE_BUFFER 0x01000000L +# define RADEON_SCALER_DIS_LIMIT 0x08000000L +# define RADEON_SCALER_PRG_LOAD_START 0x10000000L +# define RADEON_SCALER_INT_EMU 0x20000000L +# define RADEON_SCALER_ENABLE 0x40000000L +# define RADEON_SCALER_SOFT_RESET 0x80000000L +#define RADEON_OV0_V_INC 0x0424 +#define RADEON_OV0_P1_V_ACCUM_INIT 0x0428 +# define RADEON_OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L +# define RADEON_OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L +#define RADEON_OV0_P23_V_ACCUM_INIT 0x042C +#define RADEON_OV0_P1_BLANK_LINES_AT_TOP 0x0430 +# define RADEON_P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL +# define RADEON_P1_ACTIVE_LINES_M1 0x0fff0000L +#define RADEON_OV0_P23_BLANK_LINES_AT_TOP 0x0434 +# define RADEON_P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ffL +# define RADEON_P23_ACTIVE_LINES_M1 0x07ff0000L +#define RADEON_OV0_VID_BUF0_BASE_ADRS 0x0440 +# define RADEON_VIF_BUF0_PITCH_SEL 0x00000001L +# define RADEON_VIF_BUF0_TILE_ADRS 0x00000002L +# define RADEON_VIF_BUF0_BASE_ADRS_MASK 0x03fffff0L +# define RADEON_VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000L +#define RADEON_OV0_VID_BUF1_BASE_ADRS 0x0444 +# define RADEON_VIF_BUF1_PITCH_SEL 0x00000001L +# define RADEON_VIF_BUF1_TILE_ADRS 0x00000002L +# define RADEON_VIF_BUF1_BASE_ADRS_MASK 0x03fffff0L +# define RADEON_VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000L +#define RADEON_OV0_VID_BUF2_BASE_ADRS 0x0448 +# define RADEON_VIF_BUF2_PITCH_SEL 0x00000001L +# define RADEON_VIF_BUF2_TILE_ADRS 0x00000002L +# define RADEON_VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L +# define RADEON_VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L +#define RADEON_OV0_VID_BUF3_BASE_ADRS 0x044C +#define RADEON_OV0_VID_BUF4_BASE_ADRS 0x0450 +#define RADEON_OV0_VID_BUF5_BASE_ADRS 0x0454 +#define RADEON_OV0_VID_BUF_PITCH0_VALUE 0x0460 +#define RADEON_OV0_VID_BUF_PITCH1_VALUE 0x0464 +#define RADEON_OV0_AUTO_FLIP_CNTL 0x0470 +#define RADEON_OV0_DEINTERLACE_PATTERN 0x0474 +#define RADEON_OV0_H_INC 0x0480 +#define RADEON_OV0_STEP_BY 0x0484 +#define RADEON_OV0_P1_H_ACCUM_INIT 0x0488 +#define RADEON_OV0_P23_H_ACCUM_INIT 0x048C +#define RADEON_OV0_P1_X_START_END 0x0494 +#define RADEON_OV0_P2_X_START_END 0x0498 +#define RADEON_OV0_P3_X_START_END 0x049C +#define RADEON_OV0_FILTER_CNTL 0x04A0 +#define RADEON_OV0_FOUR_TAP_COEF_0 0x04B0 +#define RADEON_OV0_FOUR_TAP_COEF_1 0x04B4 +#define RADEON_OV0_FOUR_TAP_COEF_2 0x04B8 +#define RADEON_OV0_FOUR_TAP_COEF_3 0x04BC +#define RADEON_OV0_FOUR_TAP_COEF_4 0x04C0 +#define RADEON_OV0_COLOUR_CNTL 0x04E0 +#define RADEON_OV0_VIDEO_KEY_CLR 0x04E4 +#define RADEON_OV0_VIDEO_KEY_MSK 0x04E8 +#define RADEON_OV0_GRAPHICS_KEY_CLR 0x04EC +#define RADEON_OV0_GRAPHICS_KEY_MSK 0x04F0 +#define RADEON_OV0_KEY_CNTL 0x04F4 +# define RADEON_VIDEO_KEY_FN_MASK 0x00000007L +# define RADEON_VIDEO_KEY_FN_FALSE 0x00000000L +# define RADEON_VIDEO_KEY_FN_TRUE 0x00000001L +# define RADEON_VIDEO_KEY_FN_EQ 0x00000004L +# define RADEON_VIDEO_KEY_FN_NE 0x00000005L +# define RADEON_GRAPHIC_KEY_FN_MASK 0x00000070L +# define RADEON_GRAPHIC_KEY_FN_FALSE 0x00000000L +# define RADEON_GRAPHIC_KEY_FN_TRUE 0x00000010L +# define RADEON_GRAPHIC_KEY_FN_EQ 0x00000040L +# define RADEON_GRAPHIC_KEY_FN_NE 0x00000050L +# define RADEON_CMP_MIX_MASK 0x00000100L +# define RADEON_CMP_MIX_OR 0x00000000L +# define RADEON_CMP_MIX_AND 0x00000100L +#define RADEON_OV0_TEST 0x04F8 + +#define RADEON_PALETTE_DATA 0x00b4 +#define RADEON_PALETTE_30_DATA 0x00b8 +#define RADEON_PALETTE_INDEX 0x00b0 +#define RADEON_PCI_GART_PAGE 0x017c +#define RADEON_PLANE_3D_MASK_C 0x1d44 +#define RADEON_PLL_TEST_CNTL 0x0013 /* PLL */ +#define RADEON_PMI_CAP_ID 0x0f5c /* PCI */ +#define RADEON_PMI_DATA 0x0f63 /* PCI */ +#define RADEON_PMI_NXT_CAP_PTR 0x0f5d /* PCI */ +#define RADEON_PMI_PMC_REG 0x0f5e /* PCI */ +#define RADEON_PMI_PMCSR_REG 0x0f60 /* PCI */ +#define RADEON_PMI_REGISTER 0x0f5c /* PCI */ +#define RADEON_PPLL_CNTL 0x0002 /* PLL */ +# define RADEON_PPLL_RESET (1 << 0) +# define RADEON_PPLL_SLEEP (1 << 1) +# define RADEON_PPLL_ATOMIC_UPDATE_EN (1 << 16) +# define RADEON_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +# define RADEON_PPLL_ATOMIC_UPDATE_VSYNC (1 << 18) +#define RADEON_PPLL_DIV_0 0x0004 /* PLL */ +#define RADEON_PPLL_DIV_1 0x0005 /* PLL */ +#define RADEON_PPLL_DIV_2 0x0006 /* PLL */ +#define RADEON_PPLL_DIV_3 0x0007 /* PLL */ +# define RADEON_PPLL_FB3_DIV_MASK 0x07ff +# define RADEON_PPLL_POST3_DIV_MASK 0x00070000 +#define RADEON_PPLL_REF_DIV 0x0003 /* PLL */ +# define RADEON_PPLL_REF_DIV_MASK 0x03ff +# define RADEON_PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ +# define RADEON_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +#define RADEON_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ +#define RADEON_RBBM_SOFT_RESET 0x00f0 +#define RADEON_RBBM_STATUS 0x0e40 +# define RADEON_RBBM_FIFOCNT_MASK 0x007f +# define RADEON_RBBM_ACTIVE (1 << 31) +#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c +# define RADEON_RB2D_DC_FLUSH_ALL 0xf +# define RADEON_RB2D_DC_BUSY (1 << 31) +#define RADEON_RB2D_DSTCACHE_MODE 0x3428 +#define RADEON_REG_BASE 0x0f18 /* PCI */ +#define RADEON_REGPROG_INF 0x0f09 /* PCI */ +#define RADEON_REVISION_ID 0x0f08 /* PCI */ + +#define RADEON_SC_BOTTOM 0x164c +#define RADEON_SC_BOTTOM_RIGHT 0x16f0 +#define RADEON_SC_BOTTOM_RIGHT_C 0x1c8c +#define RADEON_SC_LEFT 0x1640 +#define RADEON_SC_RIGHT 0x1644 +#define RADEON_SC_TOP 0x1648 +#define RADEON_SC_TOP_LEFT 0x16ec +#define RADEON_SC_TOP_LEFT_C 0x1c88 +#define RADEON_SDRAM_MODE_REG 0x0158 +#define RADEON_SEQ8_DATA 0x03c5 /* VGA */ +#define RADEON_SEQ8_IDX 0x03c4 /* VGA */ +#define RADEON_SNAPSHOT_F_COUNT 0x0244 +#define RADEON_SNAPSHOT_VH_COUNTS 0x0240 +#define RADEON_SNAPSHOT_VIF_COUNT 0x024c +#define RADEON_SRC_OFFSET 0x15ac +#define RADEON_SRC_PITCH 0x15b0 +#define RADEON_SRC_PITCH_OFFSET 0x1428 +#define RADEON_SRC_SC_BOTTOM 0x165c +#define RADEON_SRC_SC_BOTTOM_RIGHT 0x16f4 +#define RADEON_SRC_SC_RIGHT 0x1654 +#define RADEON_SRC_X 0x1414 +#define RADEON_SRC_X_Y 0x1590 +#define RADEON_SRC_Y 0x1418 +#define RADEON_SRC_Y_X 0x1434 +#define RADEON_STATUS 0x0f06 /* PCI */ +#define RADEON_SUBPIC_CNTL 0x0540 /* ? */ +#define RADEON_SUB_CLASS 0x0f0a /* PCI */ +#define RADEON_SURFACE_DELAY 0x0b00 +#define RADEON_SURFACE0_INFO 0x0b0c +#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 +#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 +#define RADEON_SURFACE1_INFO 0x0b1c +#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 +#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 +#define RADEON_SURFACE2_INFO 0x0b2c +#define RADEON_SURFACE2_LOWER_BOUND 0x0b24 +#define RADEON_SURFACE2_UPPER_BOUND 0x0b28 +#define RADEON_SURFACE3_INFO 0x0b3c +#define RADEON_SURFACE3_LOWER_BOUND 0x0b34 +#define RADEON_SURFACE3_UPPER_BOUND 0x0b38 +#define RADEON_SW_SEMAPHORE 0x013c + +#define RADEON_TEST_DEBUG_CNTL 0x0120 +#define RADEON_TEST_DEBUG_MUX 0x0124 +#define RADEON_TEST_DEBUG_OUT 0x012c +#define RADEON_TMDS_CRC 0x02a0 +#define RADEON_TRAIL_BRES_DEC 0x1614 +#define RADEON_TRAIL_BRES_ERR 0x160c +#define RADEON_TRAIL_BRES_INC 0x1610 +#define RADEON_TRAIL_X 0x1618 +#define RADEON_TRAIL_X_SUB 0x1620 + +#define RADEON_VCLK_ECP_CNTL 0x0008 /* PLL */ +#define RADEON_VENDOR_ID 0x0f00 /* PCI */ +#define RADEON_VGA_DDA_CONFIG 0x02e8 +#define RADEON_VGA_DDA_ON_OFF 0x02ec +#define RADEON_VID_BUFFER_CONTROL 0x0900 +#define RADEON_VIDEOMUX_CNTL 0x0190 +#define RADEON_VIPH_CONTROL 0x0c40 /* ? */ + +#define RADEON_WAIT_UNTIL 0x1720 + +#define RADEON_X_MPLL_REF_FB_DIV 0x000a /* PLL */ +#define RADEON_XCLK_CNTL 0x000d /* PLL */ +#define RADEON_XDLL_CNTL 0x000c /* PLL */ +#define RADEON_XPLL_CNTL 0x000b /* PLL */ + + /* Registers for CCE and Microcode Engine */ +#define RADEON_CP_ME_RAM_ADDR 0x07d4 +#define RADEON_CP_ME_RAM_RADDR 0x07d8 +#define RADEON_CP_ME_RAM_DATAH 0x07dc +#define RADEON_CP_ME_RAM_DATAL 0x07e0 + +#define RADEON_CP_RB_BASE 0x0700 +#define RADEON_CP_RB_CNTL 0x0704 +#define RADEON_CP_RB_RPTR_ADDR 0x070c +#define RADEON_CP_RB_RPTR 0x0710 +#define RADEON_CP_RB_WPTR 0x0714 +# define RADEON_PM4_BUFFER_DL_DONE (1 << 31) + +#define RADEON_CP_IB_BASE 0x0738 +#define RADEON_CP_IB_BUFSZ 0x073c + +#define RADEON_CP_CSQ_CNTL 0x0740 +# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) +# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) +# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) +# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) +# define RADEON_CSQ_PRIBM_INDBM (4 << 28) +# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) +#define RADEON_CP_RB_WPTR_DELAY 0x0718 +# define RADEON_PRE_WRITE_TIMER_SHIFT 0 +# define RADEON_PRE_WRITE_LIMIT_SHIFT 23 + +#define RADEON_AIC_CNTL 0x01d0 +# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) + +#define RADEON_PM4_VC_FPU_SETUP 0x071c +# define RADEON_FRONT_DIR_CW (0 << 0) +# define RADEON_FRONT_DIR_CCW (1 << 0) +# define RADEON_FRONT_DIR_MASK (1 << 0) +# define RADEON_BACKFACE_CULL (0 << 1) +# define RADEON_BACKFACE_POINTS (1 << 1) +# define RADEON_BACKFACE_LINES (2 << 1) +# define RADEON_BACKFACE_SOLID (3 << 1) +# define RADEON_BACKFACE_MASK (3 << 1) +# define RADEON_FRONTFACE_CULL (0 << 3) +# define RADEON_FRONTFACE_POINTS (1 << 3) +# define RADEON_FRONTFACE_LINES (2 << 3) +# define RADEON_FRONTFACE_SOLID (3 << 3) +# define RADEON_FRONTFACE_MASK (3 << 3) +# define RADEON_FPU_COLOR_SOLID (0 << 5) +# define RADEON_FPU_COLOR_FLAT (1 << 5) +# define RADEON_FPU_COLOR_GOURAUD (2 << 5) +# define RADEON_FPU_COLOR_GOURAUD2 (3 << 5) +# define RADEON_FPU_COLOR_MASK (3 << 5) +# define RADEON_FPU_SUB_PIX_2BITS (0 << 7) +# define RADEON_FPU_SUB_PIX_4BITS (1 << 7) +# define RADEON_FPU_MODE_2D (0 << 8) +# define RADEON_FPU_MODE_3D (1 << 8) +# define RADEON_TRAP_BITS_DISABLE (1 << 9) +# define RADEON_EDGE_ANTIALIAS (1 << 10) +# define RADEON_SUPERSAMPLE (1 << 11) +# define RADEON_XFACTOR_2 (0 << 12) +# define RADEON_XFACTOR_4 (1 << 12) +# define RADEON_YFACTOR_2 (0 << 13) +# define RADEON_YFACTOR_4 (1 << 13) +# define RADEON_FLAT_SHADE_VERTEX_D3D (0 << 14) +# define RADEON_FLAT_SHADE_VERTEX_OGL (1 << 14) +# define RADEON_FPU_ROUND_TRUNCATE (0 << 15) +# define RADEON_FPU_ROUND_NEAREST (1 << 15) +# define RADEON_WM_SEL_8DW (0 << 16) +# define RADEON_WM_SEL_16DW (1 << 16) +# define RADEON_WM_SEL_32DW (2 << 16) +#define RADEON_PM4_VC_DEBUG_CONFIG 0x07a4 +#define RADEON_PM4_VC_STAT 0x07a8 +#define RADEON_PM4_VC_TIMESTAMP0 0x07b0 +#define RADEON_PM4_VC_TIMESTAMP1 0x07b4 +#define RADEON_PM4_STAT 0x07b8 +# define RADEON_PM4_FIFOCNT_MASK 0x0fff +# define RADEON_PM4_BUSY (1 << 16) +# define RADEON_PM4_GUI_ACTIVE (1 << 31) +#define RADEON_PM4_BUFFER_ADDR 0x07f0 +#define RADEON_CP_ME_CNTL 0x07d0 +# define RADEON_CP_ME_FREERUN (1 << 30) +#define RADEON_PM4_FIFO_DATA_EVEN 0x1000 +#define RADEON_PM4_FIFO_DATA_ODD 0x1004 + +#define RADEON_SCALE_3D_CNTL 0x1a00 +# define RADEON_SCALE_DITHER_ERR_DIFF (0 << 1) +# define RADEON_SCALE_DITHER_TABLE (1 << 1) +# define RADEON_TEX_CACHE_SIZE_FULL (0 << 2) +# define RADEON_TEX_CACHE_SIZE_HALF (1 << 2) +# define RADEON_DITHER_INIT_CURR (0 << 3) +# define RADEON_DITHER_INIT_RESET (1 << 3) +# define RADEON_ROUND_24BIT (1 << 4) +# define RADEON_TEX_CACHE_DISABLE (1 << 5) +# define RADEON_SCALE_3D_NOOP (0 << 6) +# define RADEON_SCALE_3D_SCALE (1 << 6) +# define RADEON_SCALE_3D_TEXMAP_SHADE (2 << 6) +# define RADEON_SCALE_PIX_BLEND (0 << 8) +# define RADEON_SCALE_PIX_REPLICATE (1 << 8) +# define RADEON_TEX_CACHE_SPLIT (1 << 9) +# define RADEON_APPLE_YUV_MODE (1 << 10) +# define RADEON_TEX_CACHE_PALLETE_MODE (1 << 11) +# define RADEON_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define RADEON_ALPHA_COMB_ADD_NCLAMP (1 << 12) +# define RADEON_ALPHA_COMB_SUB_DST_SRC_CLAMP (2 << 12) +# define RADEON_ALPHA_COMB_SUB_DST_SRC_NCLAMP (3 << 12) +# define RADEON_FOG_TABLE (1 << 14) +# define RADEON_SIGNED_DST_CLAMP (1 << 15) +# define RADEON_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define RADEON_ALPHA_BLEND_SRC_ONE (1 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define RADEON_ALPHA_BLEND_SRC_DSTALPHA (6 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16) +# define RADEON_ALPHA_BLEND_SRC_DSTCOLOR (8 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVDSTCOLOR (9 << 16) +# define RADEON_ALPHA_BLEND_SRC_SAT (10 << 16) +# define RADEON_ALPHA_BLEND_SRC_BLEND (11 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVBLEND (12 << 16) +# define RADEON_ALPHA_BLEND_DST_ZERO (0 << 20) +# define RADEON_ALPHA_BLEND_DST_ONE (1 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define RADEON_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define RADEON_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define RADEON_ALPHA_BLEND_DST_DSTALPHA (6 << 20) +# define RADEON_ALPHA_BLEND_DST_INVDSTALPHA (7 << 20) +# define RADEON_ALPHA_BLEND_DST_DSTCOLOR (8 << 20) +# define RADEON_ALPHA_BLEND_DST_INVDSTCOLOR (9 << 20) +# define RADEON_ALPHA_TEST_NEVER (0 << 24) +# define RADEON_ALPHA_TEST_LESS (1 << 24) +# define RADEON_ALPHA_TEST_LESSEQUAL (2 << 24) +# define RADEON_ALPHA_TEST_EQUAL (3 << 24) +# define RADEON_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define RADEON_ALPHA_TEST_GREATER (5 << 24) +# define RADEON_ALPHA_TEST_NEQUAL (6 << 24) +# define RADEON_ALPHA_TEST_ALWAYS (7 << 24) +# define RADEON_COMPOSITE_SHADOW_CMP_EQUAL (0 << 28) +# define RADEON_COMPOSITE_SHADOW_CMP_NEQUAL (1 << 28) +# define RADEON_COMPOSITE_SHADOW (1 << 29) +# define RADEON_TEX_MAP_ALPHA_IN_TEXTURE (1 << 30) +# define RADEON_TEX_CACHE_LINE_SIZE_8QW (0 << 31) +# define RADEON_TEX_CACHE_LINE_SIZE_4QW (1 << 31) +#define RADEON_SCALE_3D_DATATYPE 0x1a20 + +#define RADEON_SETUP_CNTL 0x1bc4 +# define RADEON_DONT_START_TRIANGLE (1 << 0) +# define RADEON_Z_BIAS (0 << 1) +# define RADEON_DONT_START_ANY_ON (1 << 2) +# define RADEON_COLOR_SOLID_COLOR (0 << 3) +# define RADEON_COLOR_FLAT_VERT_1 (1 << 3) +# define RADEON_COLOR_FLAT_VERT_2 (2 << 3) +# define RADEON_COLOR_FLAT_VERT_3 (3 << 3) +# define RADEON_COLOR_GOURAUD (4 << 3) +# define RADEON_PRIM_TYPE_TRI (0 << 7) +# define RADEON_PRIM_TYPE_LINE (1 << 7) +# define RADEON_PRIM_TYPE_POINT (2 << 7) +# define RADEON_PRIM_TYPE_POLY_EDGE (3 << 7) +# define RADEON_TEXTURE_ST_MULT_W (0 << 9) +# define RADEON_TEXTURE_ST_DIRECT (1 << 9) +# define RADEON_STARTING_VERTEX_1 (1 << 14) +# define RADEON_STARTING_VERTEX_2 (2 << 14) +# define RADEON_STARTING_VERTEX_3 (3 << 14) +# define RADEON_ENDING_VERTEX_1 (1 << 16) +# define RADEON_ENDING_VERTEX_2 (2 << 16) +# define RADEON_ENDING_VERTEX_3 (3 << 16) +# define RADEON_SU_POLY_LINE_LAST (0 << 18) +# define RADEON_SU_POLY_LINE_NOT_LAST (1 << 18) +# define RADEON_SUB_PIX_2BITS (0 << 19) +# define RADEON_SUB_PIX_4BITS (1 << 19) +# define RADEON_SET_UP_CONTINUE (1 << 31) + +#define RADEON_WINDOW_XY_OFFSET 0x1bcc +# define RADEON_WINDOW_Y_SHIFT 4 +# define RADEON_WINDOW_X_SHIFT 20 + +#define RADEON_Z_OFFSET_C 0x1c90 +#define RADEON_Z_PITCH_C 0x1c94 +#define RADEON_Z_STEN_CNTL_C 0x1c98 +# define RADEON_Z_PIX_WIDTH_16 (0 << 1) +# define RADEON_Z_PIX_WIDTH_24 (1 << 1) +# define RADEON_Z_PIX_WIDTH_32 (2 << 1) +# define RADEON_Z_PIX_WIDTH_MASK (3 << 1) +# define RADEON_Z_TEST_NEVER (0 << 4) +# define RADEON_Z_TEST_LESS (1 << 4) +# define RADEON_Z_TEST_LESSEQUAL (2 << 4) +# define RADEON_Z_TEST_EQUAL (3 << 4) +# define RADEON_Z_TEST_GREATEREQUAL (4 << 4) +# define RADEON_Z_TEST_GREATER (5 << 4) +# define RADEON_Z_TEST_NEQUAL (6 << 4) +# define RADEON_Z_TEST_ALWAYS (7 << 4) +# define RADEON_Z_TEST_MASK (7 << 4) +# define RADEON_STENCIL_TEST_NEVER (0 << 12) +# define RADEON_STENCIL_TEST_LESS (1 << 12) +# define RADEON_STENCIL_TEST_LESSEQUAL (2 << 12) +# define RADEON_STENCIL_TEST_EQUAL (3 << 12) +# define RADEON_STENCIL_TEST_GREATEREQUAL (4 << 12) +# define RADEON_STENCIL_TEST_GREATER (5 << 12) +# define RADEON_STENCIL_TEST_NEQUAL (6 << 12) +# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) +# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16) +# define RADEON_STENCIL_S_FAIL_ZERO (1 << 16) +# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) +# define RADEON_STENCIL_S_FAIL_INC (3 << 16) +# define RADEON_STENCIL_S_FAIL_DEC (4 << 16) +# define RADEON_STENCIL_S_FAIL_INV (5 << 16) +# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) +# define RADEON_STENCIL_ZPASS_ZERO (1 << 20) +# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) +# define RADEON_STENCIL_ZPASS_INC (3 << 20) +# define RADEON_STENCIL_ZPASS_DEC (4 << 20) +# define RADEON_STENCIL_ZPASS_INV (5 << 20) +# define RADEON_STENCIL_ZFAIL_KEEP (0 << 24) +# define RADEON_STENCIL_ZFAIL_ZERO (1 << 24) +# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) +# define RADEON_STENCIL_ZFAIL_INC (3 << 24) +# define RADEON_STENCIL_ZFAIL_DEC (4 << 24) +# define RADEON_STENCIL_ZFAIL_INV (5 << 24) +#define RADEON_TEX_CNTL_C 0x1c9c +# define RADEON_Z_ENABLE (1 << 0) +# define RADEON_Z_WRITE_ENABLE (1 << 1) +# define RADEON_STENCIL_ENABLE (1 << 3) +# define RADEON_SHADE_ENABLE (0 << 4) +# define RADEON_TEXMAP_ENABLE (1 << 4) +# define RADEON_SEC_TEXMAP_ENABLE (1 << 5) +# define RADEON_FOG_ENABLE (1 << 7) +# define RADEON_DITHER_ENABLE (1 << 8) +# define RADEON_ALPHA_ENABLE (1 << 9) +# define RADEON_ALPHA_TEST_ENABLE (1 << 10) +# define RADEON_SPEC_LIGHT_ENABLE (1 << 11) +# define RADEON_TEX_CHROMA_KEY_ENABLE (1 << 12) +# define RADEON_ALPHA_IN_TEX_COMPLETE_A (0 << 13) +# define RADEON_ALPHA_IN_TEX_LSB_A (1 << 13) +# define RADEON_LIGHT_DIS (0 << 14) +# define RADEON_LIGHT_COPY (1 << 14) +# define RADEON_LIGHT_MODULATE (2 << 14) +# define RADEON_LIGHT_ADD (3 << 14) +# define RADEON_LIGHT_BLEND_CONSTANT (4 << 14) +# define RADEON_LIGHT_BLEND_TEXTURE (5 << 14) +# define RADEON_LIGHT_BLEND_VERTEX (6 << 14) +# define RADEON_LIGHT_BLEND_CONST_COLOR (7 << 14) +# define RADEON_ALPHA_LIGHT_DIS (0 << 18) +# define RADEON_ALPHA_LIGHT_COPY (1 << 18) +# define RADEON_ALPHA_LIGHT_MODULATE (2 << 18) +# define RADEON_ALPHA_LIGHT_ADD (3 << 18) +# define RADEON_ANTI_ALIAS (1 << 21) +# define RADEON_TEX_CACHE_FLUSH (1 << 23) +# define RADEON_LOD_BIAS_SHIFT 24 +#define RADEON_MISC_3D_STATE_CNTL_REG 0x1ca0 +# define RADEON_REF_ALPHA_MASK 0xff +# define RADEON_MISC_SCALE_3D_NOOP (0 << 8) +# define RADEON_MISC_SCALE_3D_SCALE (1 << 8) +# define RADEON_MISC_SCALE_3D_TEXMAP_SHADE (2 << 8) +# define RADEON_MISC_SCALE_PIX_BLEND (0 << 10) +# define RADEON_MISC_SCALE_PIX_REPLICATE (1 << 10) +# define RADEON_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define RADEON_ALPHA_COMB_ADD_NO_CLAMP (1 << 12) +# define RADEON_ALPHA_COMB_SUB_SRC_DST_CLAMP (2 << 12) +# define RADEON_ALPHA_COMB_SUB_SRC_DST_NO_CLAMP (3 << 12) +# define RADEON_FOG_VERTEX (0 << 14) +# define RADEON_FOG_TABLE (1 << 14) +# define RADEON_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define RADEON_ALPHA_BLEND_SRC_ONE (1 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define RADEON_ALPHA_BLEND_SRC_DESTALPHA (6 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVDESTALPHA (7 << 16) +# define RADEON_ALPHA_BLEND_SRC_DESTCOLOR (8 << 16) +# define RADEON_ALPHA_BLEND_SRC_INVDESTCOLOR (9 << 16) +# define RADEON_ALPHA_BLEND_SRC_SRCALPHASAT (10 << 16) +# define RADEON_ALPHA_BLEND_SRC_BOTHSRCALPHA (11 << 16) +# define RADEON_ALPHA_BLEND_SRC_BOTHINVSRCALPHA (12 << 16) +# define RADEON_ALPHA_BLEND_SRC_MASK (15 << 16) +# define RADEON_ALPHA_BLEND_DST_ZERO (0 << 20) +# define RADEON_ALPHA_BLEND_DST_ONE (1 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define RADEON_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define RADEON_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define RADEON_ALPHA_BLEND_DST_DESTALPHA (6 << 20) +# define RADEON_ALPHA_BLEND_DST_INVDESTALPHA (7 << 20) +# define RADEON_ALPHA_BLEND_DST_DESTCOLOR (8 << 20) +# define RADEON_ALPHA_BLEND_DST_INVDESTCOLOR (9 << 20) +# define RADEON_ALPHA_BLEND_DST_SRCALPHASAT (10 << 20) +# define RADEON_ALPHA_BLEND_DST_MASK (15 << 20) +# define RADEON_ALPHA_TEST_NEVER (0 << 24) +# define RADEON_ALPHA_TEST_LESS (1 << 24) +# define RADEON_ALPHA_TEST_LESSEQUAL (2 << 24) +# define RADEON_ALPHA_TEST_EQUAL (3 << 24) +# define RADEON_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define RADEON_ALPHA_TEST_GREATER (5 << 24) +# define RADEON_ALPHA_TEST_NEQUAL (6 << 24) +# define RADEON_ALPHA_TEST_ALWAYS (7 << 24) +# define RADEON_ALPHA_TEST_MASK (7 << 24) +#define RADEON_TEXTURE_CLR_CMP_CLR_C 0x1ca4 +#define RADEON_TEXTURE_CLR_CMP_MSK_C 0x1ca8 +#define RADEON_FOG_COLOR_C 0x1cac +# define RADEON_FOG_BLUE_SHIFT 0 +# define RADEON_FOG_GREEN_SHIFT 8 +# define RADEON_FOG_RED_SHIFT 16 +#define RADEON_PRIM_TEX_CNTL_C 0x1cb0 +# define RADEON_MIN_BLEND_NEAREST (0 << 1) +# define RADEON_MIN_BLEND_LINEAR (1 << 1) +# define RADEON_MIN_BLEND_MIPNEAREST (2 << 1) +# define RADEON_MIN_BLEND_MIPLINEAR (3 << 1) +# define RADEON_MIN_BLEND_LINEARMIPNEAREST (4 << 1) +# define RADEON_MIN_BLEND_LINEARMIPLINEAR (5 << 1) +# define RADEON_MIN_BLEND_MASK (7 << 1) +# define RADEON_MAG_BLEND_NEAREST (0 << 4) +# define RADEON_MAG_BLEND_LINEAR (1 << 4) +# define RADEON_MAG_BLEND_MASK (7 << 4) +# define RADEON_MIP_MAP_DISABLE (1 << 7) +# define RADEON_TEX_CLAMP_S_WRAP (0 << 8) +# define RADEON_TEX_CLAMP_S_MIRROR (1 << 8) +# define RADEON_TEX_CLAMP_S_CLAMP (2 << 8) +# define RADEON_TEX_CLAMP_S_BORDER_COLOR (3 << 8) +# define RADEON_TEX_CLAMP_S_MASK (3 << 8) +# define RADEON_TEX_WRAP_S (1 << 10) +# define RADEON_TEX_CLAMP_T_WRAP (0 << 11) +# define RADEON_TEX_CLAMP_T_MIRROR (1 << 11) +# define RADEON_TEX_CLAMP_T_CLAMP (2 << 11) +# define RADEON_TEX_CLAMP_T_BORDER_COLOR (3 << 11) +# define RADEON_TEX_CLAMP_T_MASK (3 << 11) +# define RADEON_TEX_WRAP_T (1 << 13) +# define RADEON_TEX_PERSPECTIVE_DISABLE (1 << 14) +# define RADEON_DATATYPE_VQ (0 << 16) +# define RADEON_DATATYPE_CI4 (1 << 16) +# define RADEON_DATATYPE_CI8 (2 << 16) +# define RADEON_DATATYPE_ARGB1555 (3 << 16) +# define RADEON_DATATYPE_RGB565 (4 << 16) +# define RADEON_DATATYPE_RGB888 (5 << 16) +# define RADEON_DATATYPE_ARGB8888 (6 << 16) +# define RADEON_DATATYPE_RGB332 (7 << 16) +# define RADEON_DATATYPE_Y8 (8 << 16) +# define RADEON_DATATYPE_RGB8 (9 << 16) +# define RADEON_DATATYPE_CI16 (10 << 16) +# define RADEON_DATATYPE_YUV422 (11 << 16) +# define RADEON_DATATYPE_YUV422_2 (12 << 16) +# define RADEON_DATATYPE_AYUV444 (14 << 16) +# define RADEON_DATATYPE_ARGB4444 (15 << 16) +# define RADEON_PALLETE_EITHER (0 << 20) +# define RADEON_PALLETE_1 (1 << 20) +# define RADEON_PALLETE_2 (2 << 20) +# define RADEON_PSEUDOCOLOR_DT_RGB565 (0 << 24) +# define RADEON_PSEUDOCOLOR_DT_ARGB1555 (1 << 24) +# define RADEON_PSEUDOCOLOR_DT_ARGB4444 (2 << 24) +#define RADEON_PRIM_TEXTURE_COMBINE_CNTL_C 0x1cb4 +# define RADEON_COMB_DIS (0 << 0) +# define RADEON_COMB_COPY (1 << 0) +# define RADEON_COMB_COPY_INP (2 << 0) +# define RADEON_COMB_MODULATE (3 << 0) +# define RADEON_COMB_MODULATE2X (4 << 0) +# define RADEON_COMB_MODULATE4X (5 << 0) +# define RADEON_COMB_ADD (6 << 0) +# define RADEON_COMB_ADD_SIGNED (7 << 0) +# define RADEON_COMB_BLEND_VERTEX (8 << 0) +# define RADEON_COMB_BLEND_TEXTURE (9 << 0) +# define RADEON_COMB_BLEND_CONST (10 << 0) +# define RADEON_COMB_BLEND_PREMULT (11 << 0) +# define RADEON_COMB_BLEND_PREV (12 << 0) +# define RADEON_COMB_BLEND_PREMULT_INV (13 << 0) +# define RADEON_COMB_ADD_SIGNED2X (14 << 0) +# define RADEON_COMB_BLEND_CONST_COLOR (15 << 0) +# define RADEON_COMB_MASK (15 << 0) +# define RADEON_COLOR_FACTOR_TEX (4 << 4) +# define RADEON_COLOR_FACTOR_NTEX (5 << 4) +# define RADEON_COLOR_FACTOR_ALPHA (6 << 4) +# define RADEON_COLOR_FACTOR_NALPHA (7 << 4) +# define RADEON_COLOR_FACTOR_MASK (15 << 4) +# define RADEON_INPUT_FACTOR_CONST_COLOR (2 << 10) +# define RADEON_INPUT_FACTOR_CONST_ALPHA (3 << 10) +# define RADEON_INPUT_FACTOR_INT_COLOR (4 << 10) +# define RADEON_INPUT_FACTOR_INT_ALPHA (5 << 10) +# define RADEON_INPUT_FACTOR_MASK (15 << 10) +# define RADEON_COMB_ALPHA_DIS (0 << 14) +# define RADEON_COMB_ALPHA_COPY (1 << 14) +# define RADEON_COMB_ALPHA_COPY_INP (2 << 14) +# define RADEON_COMB_ALPHA_MODULATE (3 << 14) +# define RADEON_COMB_ALPHA_MODULATE2X (4 << 14) +# define RADEON_COMB_ALPHA_MODULATE4X (5 << 14) +# define RADEON_COMB_ALPHA_ADD (6 << 14) +# define RADEON_COMB_ALPHA_ADD_SIGNED (7 << 14) +# define RADEON_COMB_ALPHA_ADD_SIGNED2X (14 << 14) +# define RADEON_COMB_ALPHA_MASK (15 << 14) +# define RADEON_ALPHA_FACTOR_TEX_ALPHA (6 << 18) +# define RADEON_ALPHA_FACTOR_NTEX_ALPHA (7 << 18) +# define RADEON_ALPHA_FACTOR_MASK (15 << 18) +# define RADEON_INP_FACTOR_A_CONST_ALPHA (1 << 25) +# define RADEON_INP_FACTOR_A_INT_ALPHA (2 << 25) +# define RADEON_INP_FACTOR_A_MASK (7 << 25) +#define RADEON_TEX_SIZE_PITCH_C 0x1cb8 +# define RADEON_TEX_PITCH_SHIFT 0 +# define RADEON_TEX_SIZE_SHIFT 4 +# define RADEON_TEX_HEIGHT_SHIFT 8 +# define RADEON_TEX_MIN_SIZE_SHIFT 12 +# define RADEON_SEC_TEX_PITCH_SHIFT 16 +# define RADEON_SEC_TEX_SIZE_SHIFT 20 +# define RADEON_SEC_TEX_HEIGHT_SHIFT 24 +# define RADEON_SEC_TEX_MIN_SIZE_SHIFT 28 +# define RADEON_TEX_PITCH_MASK (0x0f << 0) +# define RADEON_TEX_SIZE_MASK (0x0f << 4) +# define RADEON_TEX_HEIGHT_MASK (0x0f << 8) +# define RADEON_TEX_MIN_SIZE_MASK (0x0f << 12) +# define RADEON_SEC_TEX_PITCH_MASK (0x0f << 16) +# define RADEON_SEC_TEX_SIZE_MASK (0x0f << 20) +# define RADEON_SEC_TEX_HEIGHT_MASK (0x0f << 24) +# define RADEON_SEC_TEX_MIN_SIZE_MASK (0x0f << 28) +# define RADEON_TEX_SIZE_PITCH_SHIFT 0 +# define RADEON_SEC_TEX_SIZE_PITCH_SHIFT 16 +# define RADEON_TEX_SIZE_PITCH_MASK (0xffff << 0) +# define RADEON_SEC_TEX_SIZE_PITCH_MASK (0xffff << 16) +#define RADEON_PRIM_TEX_0_OFFSET_C 0x1cbc +#define RADEON_PRIM_TEX_1_OFFSET_C 0x1cc0 +#define RADEON_PRIM_TEX_2_OFFSET_C 0x1cc4 +#define RADEON_PRIM_TEX_3_OFFSET_C 0x1cc8 +#define RADEON_PRIM_TEX_4_OFFSET_C 0x1ccc +#define RADEON_PRIM_TEX_5_OFFSET_C 0x1cd0 +#define RADEON_PRIM_TEX_6_OFFSET_C 0x1cd4 +#define RADEON_PRIM_TEX_7_OFFSET_C 0x1cd8 +#define RADEON_PRIM_TEX_8_OFFSET_C 0x1cdc +#define RADEON_PRIM_TEX_9_OFFSET_C 0x1ce0 +#define RADEON_PRIM_TEX_10_OFFSET_C 0x1ce4 +# define RADEON_TEX_NO_TILE (0 << 30) +# define RADEON_TEX_TILED_BY_HOST (1 << 30) +# define RADEON_TEX_TILED_BY_STORAGE (2 << 30) +# define RADEON_TEX_TILED_BY_STORAGE2 (3 << 30) + +#define RADEON_SEC_TEX_CNTL_C 0x1d00 +# define RADEON_SEC_SELECT_PRIM_ST (0 << 0) +# define RADEON_SEC_SELECT_SEC_ST (1 << 0) +#define RADEON_SEC_TEX_COMBINE_CNTL_C 0x1d04 +# define RADEON_INPUT_FACTOR_PREV_COLOR (8 << 10) +# define RADEON_INPUT_FACTOR_PREV_ALPHA (9 << 10) +# define RADEON_INP_FACTOR_A_PREV_ALPHA (4 << 25) +#define RADEON_SEC_TEX_0_OFFSET_C 0x1d08 +#define RADEON_SEC_TEX_1_OFFSET_C 0x1d0c +#define RADEON_SEC_TEX_2_OFFSET_C 0x1d10 +#define RADEON_SEC_TEX_3_OFFSET_C 0x1d14 +#define RADEON_SEC_TEX_4_OFFSET_C 0x1d18 +#define RADEON_SEC_TEX_5_OFFSET_C 0x1d1c +#define RADEON_SEC_TEX_6_OFFSET_C 0x1d20 +#define RADEON_SEC_TEX_7_OFFSET_C 0x1d24 +#define RADEON_SEC_TEX_8_OFFSET_C 0x1d28 +#define RADEON_SEC_TEX_9_OFFSET_C 0x1d2c +#define RADEON_SEC_TEX_10_OFFSET_C 0x1d30 +#define RADEON_CONSTANT_COLOR_C 0x1d34 +# define RADEON_CONSTANT_BLUE_SHIFT 0 +# define RADEON_CONSTANT_GREEN_SHIFT 8 +# define RADEON_CONSTANT_RED_SHIFT 16 +# define RADEON_CONSTANT_ALPHA_SHIFT 24 +#define RADEON_PRIM_TEXTURE_BORDER_COLOR_C 0x1d38 +# define RADEON_PRIM_TEX_BORDER_BLUE_SHIFT 0 +# define RADEON_PRIM_TEX_BORDER_GREEN_SHIFT 8 +# define RADEON_PRIM_TEX_BORDER_RED_SHIFT 16 +# define RADEON_PRIM_TEX_BORDER_ALPHA_SHIFT 24 +#define RADEON_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c +# define RADEON_SEC_TEX_BORDER_BLUE_SHIFT 0 +# define RADEON_SEC_TEX_BORDER_GREEN_SHIFT 8 +# define RADEON_SEC_TEX_BORDER_RED_SHIFT 16 +# define RADEON_SEC_TEX_BORDER_ALPHA_SHIFT 24 +#define RADEON_STEN_REF_MASK_C 0x1d40 +# define RADEON_STEN_REFERENCE_SHIFT 0 +# define RADEON_STEN_MASK_SHIFT 16 +# define RADEON_STEN_WRITE_MASK_SHIFT 24 +#define RADEON_PLANE_3D_MASK_C 0x1d44 +#define RADEON_TEX_CACHE_STAT_COUNT 0x1974 + + + /* Constants */ +#define RADEON_AGP_TEX_OFFSET 0x02000000 + +#define RADEON_VB_AGE_REG RADEON_GUI_SCRATCH_REG0 +#define RADEON_SWAP_AGE_REG RADEON_GUI_SCRATCH_REG1 + + /* CCE packet types */ +#define RADEON_CCE_PACKET0 0x00000000 +#define RADEON_CCE_PACKET0_ONE_REG_WR 0x00008000 +#define RADEON_CCE_PACKET1 0x40000000 +#define RADEON_CCE_PACKET2 0x80000000 +#define RADEON_CCE_PACKET3_NOP 0xC0001000 +#define RADEON_CCE_PACKET3_PAINT 0xC0001100 +#define RADEON_CCE_PACKET3_BITBLT 0xC0001200 +#define RADEON_CCE_PACKET3_SMALLTEXT 0xC0001300 +#define RADEON_CCE_PACKET3_HOSTDATA_BLT 0xC0001400 +#define RADEON_CCE_PACKET3_POLYLINE 0xC0001500 +#define RADEON_CCE_PACKET3_SCALING 0xC0001600 +#define RADEON_CCE_PACKET3_TRANS_SCALING 0xC0001700 +#define RADEON_CCE_PACKET3_POLYSCANLINES 0xC0001800 +#define RADEON_CCE_PACKET3_NEXT_CHAR 0xC0001900 +#define RADEON_CCE_PACKET3_PAINT_MULTI 0xC0001A00 +#define RADEON_CCE_PACKET3_BITBLT_MULTI 0xC0001B00 +#define RADEON_CCE_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define RADEON_CCE_PACKET3_SET_SCISSORS 0xC0001E00 +#define RADEON_CCE_PACKET3_SET_MODE24BPP 0xC0001F00 +#define RADEON_CCE_PACKET3_CNTL_PAINT 0xC0009100 +#define RADEON_CCE_PACKET3_CNTL_BITBLT 0xC0009200 +#define RADEON_CCE_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define RADEON_CCE_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define RADEON_CCE_PACKET3_CNTL_POLYLINE 0xC0009500 +#define RADEON_CCE_PACKET3_CNTL_SCALING 0xC0009600 +#define RADEON_CCE_PACKET3_CNTL_TRANS_SCALING 0xC0009700 +#define RADEON_CCE_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define RADEON_CCE_PACKET3_CNTL_NEXT_CHAR 0xC0009900 +#define RADEON_CCE_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define RADEON_CCE_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define RADEON_CCE_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 +#define RADEON_CCE_PACKET3_3D_SAVE_CONTEXT 0xC0002000 +#define RADEON_CCE_PACKET3_3D_PLAY_CONTEXT 0xC0002100 +#define RADEON_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define RADEON_CCE_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 +#define RADEON_CCE_PACKET3_LOAD_PALETTE 0xC0002C00 +#define RADEON_CCE_PACKET3_PURGE 0xC0002D00 +#define RADEON_CCE_PACKET3_NEXT_VERTEX_BUNDLE 0xC0002E00 +# define RADEON_CCE_PACKET_MASK 0xC0000000 +# define RADEON_CCE_PACKET_COUNT_MASK 0x3fff0000 +# define RADEON_CCE_PACKET_MAX_DWORDS (1 << 14) +# define RADEON_CCE_PACKET0_REG_MASK 0x000007ff +# define RADEON_CCE_PACKET1_REG0_MASK 0x000007ff +# define RADEON_CCE_PACKET1_REG1_MASK 0x003ff800 + +#define RADEON_CCE_VC_FRMT_RHW 0x00000001 +#define RADEON_CCE_VC_FRMT_DIFFUSE_BGR 0x00000002 +#define RADEON_CCE_VC_FRMT_DIFFUSE_A 0x00000004 +#define RADEON_CCE_VC_FRMT_DIFFUSE_ARGB 0x00000008 +#define RADEON_CCE_VC_FRMT_SPEC_BGR 0x00000010 +#define RADEON_CCE_VC_FRMT_SPEC_F 0x00000020 +#define RADEON_CCE_VC_FRMT_SPEC_FRGB 0x00000040 +#define RADEON_CCE_VC_FRMT_S_T 0x00000080 +#define RADEON_CCE_VC_FRMT_S2_T2 0x00000100 +#define RADEON_CCE_VC_FRMT_RHW2 0x00000200 + +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 +#define RADEON_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define RADEON_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define RADEON_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define RADEON_CCE_VC_CNTL_NUM_SHIFT 16 + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h new file mode 100644 index 000000000..e06aead72 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h @@ -0,0 +1,41 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_version.h,v 1.1 2000/11/02 16:55:46 tsi Exp $ */ +/* + * Copyright 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca + * + * 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 Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE 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. + */ + +#ifndef _RADEON_VERSION_H_ +#define _RADEON_VERSION_H_ 1 + +#define RADEON_NAME "RADEON" +#define RADEON_DRIVER_NAME "radeon" + +#define RADEON_VERSION_NAME "4.0.1" + +#define RADEON_VERSION_MAJOR 4 +#define RADEON_VERSION_MINOR 0 +#define RADEON_VERSION_PATCH 1 + +#define RADEON_VERSION_CURRENT \ + ((RADEON_VERSION_MAJOR << 20) | \ + (RADEON_VERSION_MINOR << 10) | \ + (RADEON_VERSION_PATCH)) + +#endif /* _RADEON_VERSION_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c new file mode 100644 index 000000000..8f629fd73 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c @@ -0,0 +1,798 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c,v 1.1 2000/11/02 16:55:47 tsi Exp $ */ +/* + * Copyright 2000 Stuart R. Anderson and Metro Link, Inc. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation on + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS 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. + */ + +/* + * Authors: + * Stuart R. Anderson <anderson@metrolink.com> + * + * Credits: + * + * This code is derived primarily from the GATOS Project run by Stea Greene. + * The initial version of this code was done by Vladimir Dergacheb. + * + * This code was simplified from the GATOS code primarily because I didn't + * have the right hardware handy to test anything beyond simple overlays, + * and because I wanted to complete it in a short time frame that I had + * available. + * + * My apologies to Vladimir as there is more good work in his code that + * should be brought forward. + * + * RADEON ALERT ! + * This is an extremely quick port to the Radeon, it hasn't been tested + * thoroughly, although it appears to work. + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86fbman.h" +#include "regionstr.h" + +#include "xf86xv.h" +#include "xf86Cursor.h" +#include "Xv.h" +#include "xaalocal.h" +#include "dixstruct.h" +#include "fourcc.h" + +#include "radeon.h" +#include "radeon_reg.h" + +/* + * For Debug +#define OUTREG(addr, val) { xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1,"OUTREG(%s,%x)\n",#addr,val) ;MMIO_OUT32(RADEONMMIO, addr, val);} +*/ + +#define OFF_DELAY 250 /* milliseconds */ +#define FREE_DELAY 15000 + +#define OFF_TIMER 0x01 +#define FREE_TIMER 0x02 +#define CLIENT_VIDEO_ON 0x04 + +#define TIMER_MASK (OFF_TIMER | FREE_TIMER) + +#ifndef XvExtension +void RADEONInitVideo(ScreenPtr pScreen) {} +#else +static XF86VideoAdaptorPtr RADEONSetupImageVideo(ScreenPtr); +static int RADEONSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); +static int RADEONGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); + +static void RADEONStopVideo(ScrnInfoPtr, pointer, Bool); +static void RADEONQueryBestSize(ScrnInfoPtr, Bool, + short, short, short, short, unsigned int *, unsigned int *, pointer); +static int RADEONPutImage( ScrnInfoPtr, + short, short, short, short, short, short, short, short, + int, unsigned char*, short, short, Bool, RegionPtr, pointer); +static int RADEONQueryImageAttributes(ScrnInfoPtr, + int, unsigned short *, unsigned short *, int *, int *); + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +#define IMAGE_MAX_WIDTH 2048 +#define IMAGE_MAX_HEIGHT 2048 +#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT) + +static Atom xvColorKey; + +typedef struct { + int videoStatus; + unsigned char brightness; + unsigned char contrast; + + RegionRec clip; + CARD32 colorKey; + CARD8 overlay_pixel_size; + CARD8 current_buffer; + int overlay_pad; + CARD32 overlay_id; + CARD32 overlay_width; + + CARD32 scale_cntl; + CARD32 video_format; + FBLinearPtr linear; + } RADEONPortPrivRec, *RADEONPortPrivPtr; + +void RADEONInitVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; + XF86VideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + + RADEONTRACE(("RADEONInitVideo called\n")); + + /* Determine if the card supports this */ + if (pScrn->bitsPerPixel != 8) + { + newAdaptor = RADEONSetupImageVideo(pScreen); + } + + num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); + + if(newAdaptor) { + if(!num_adaptors) { + num_adaptors = 1; + adaptors = &newAdaptor; + } else { + newAdaptors = /* need to free this someplace */ + xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); + if(newAdaptors) { + memcpy(newAdaptors, adaptors, num_adaptors * + sizeof(XF86VideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + xf86XVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); +} + +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 3 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = +{ + {15, TrueColor}, + {16, TrueColor}, + {32, TrueColor} +}; + +#define NUM_ATTRIBUTES 1 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1<<24)-1, "XV_COLORKEY"}, +}; + +#define NUM_IMAGES 3 + +static XF86ImageRec Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_UYVY +}; + +static void +RADEONResetVideo(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + + RADEONTRACE(("RADEONResetVideo called\n")); + + /* Initialize some of the HW here */ + OUTREG(RADEON_OV0_EXCLUSIVE_HORZ,0); /* disable exclusive mode */ + OUTREG(RADEON_OV0_VIDEO_KEY_MSK,0xffff); + OUTREG(RADEON_OV0_KEY_CNTL, RADEON_GRAPHIC_KEY_FN_NE); + OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR,pPriv->colorKey); + /* Only using one buffer for now + OUTREG(RADEON_OV0_AUTO_FLIP_CNTL,pAPriv->Port[0].auto_flip_cntl); + */ + switch(pScrn->depth){ + case 8: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0xff); + break; + case 15: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0x7fff); + break; + case 16: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0xffff); + break; + case 24: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0xffffff); + break; + case 32: + OUTREG(RADEON_OV0_GRAPHICS_KEY_MSK,0xffffffff); + break; + } + + OUTREG(RADEON_OV0_REG_LOAD_CNTL,0x0); + OUTREG(RADEON_OV0_DEINTERLACE_PATTERN,0xAAAAA); + OUTREG(RADEON_OV0_P1_V_ACCUM_INIT,(2<<20)|1); + OUTREG(RADEON_OV0_P23_V_ACCUM_INIT,(2<<20)|1); + OUTREG(RADEON_OV0_P1_H_ACCUM_INIT,(3<<28)); + OUTREG(RADEON_OV0_P23_H_ACCUM_INIT,(2<<28)); + OUTREG(RADEON_OV0_STEP_BY,1|(1<<8)); + OUTREG(RADEON_OV0_FILTER_CNTL,0xf); /* use hardcoded coeff's */ + OUTREG(RADEON_OV0_FILTER_CNTL,0x0); /* use programmable coeff's */ + OUTREG(RADEON_OV0_FOUR_TAP_COEF_0 , 0x00002000); + OUTREG(RADEON_OV0_FOUR_TAP_COEF_1 , 0x0D06200D); + OUTREG(RADEON_OV0_FOUR_TAP_COEF_2 , 0x0D0A1C0D); + OUTREG(RADEON_OV0_FOUR_TAP_COEF_3 , 0x0C0E1A0C); + OUTREG(RADEON_OV0_FOUR_TAP_COEF_4 , 0x0C14140C); + OUTREG(RADEON_OV0_COLOUR_CNTL,(1<<12)|(1<<20)); + OUTREG(RADEON_OV0_TEST,0); + OUTREG(RADEON_OV0_SCALE_CNTL,pPriv->scale_cntl|pPriv->video_format); + OUTREG(RADEON_CAP0_TRIG_CNTL,0); +} + +static XF86VideoAdaptorPtr +RADEONSetupImageVideo(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + XF86VideoAdaptorPtr adapt; + RADEONPortPrivPtr pPriv; + + RADEONTRACE(("RADEONSetupImageVideo called\n")); + + if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + + sizeof(RADEONPortPrivRec) + + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "RADEON Video Overlay"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + + pPriv = (RADEONPortPrivPtr)(&adapt->pPortPrivates[1]); + + adapt->pPortPrivates[0].ptr = (pointer)(pPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = RADEONStopVideo; + adapt->SetPortAttribute = RADEONSetPortAttribute; + adapt->GetPortAttribute = RADEONGetPortAttribute; + adapt->QueryBestSize = RADEONQueryBestSize; + adapt->PutImage = RADEONPutImage; + adapt->QueryImageAttributes = RADEONQueryImageAttributes; + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPriv->clip, NullBox, 0); + + info->adaptor = adapt; + + pPriv->colorKey = 0x01; /* a touch of blue */ + pPriv->video_format = RADEON_SCALER_SOURCE_VYUY422; + pPriv->scale_cntl = RADEON_SCALER_PRG_LOAD_START|RADEON_SCALER_DOUBLE_BUFFER; + pPriv->scale_cntl|= RADEON_SCALER_SMART_SWITCH|RADEON_SCALER_PIX_EXPAND; + pPriv->scale_cntl|= RADEON_SCALER_SMART_SWITCH; + + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + + RADEONResetVideo(pScrn); + + return adapt; +} + +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) +{ + int *dataA, *dataB; + int num; + + num = REGION_NUM_RECTS(A); + if(num != REGION_NUM_RECTS(B)) + return FALSE; + + if((A->extents.x1 != B->extents.x1) || + (A->extents.x2 != B->extents.x2) || + (A->extents.y1 != B->extents.y1) || + (A->extents.y2 != B->extents.y2)) + return FALSE; + + dataA = (int*)REGION_RECTS(A); + dataB = (int*)REGION_RECTS(B); + + while(num--) { + if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; + } + + return TRUE; +} + +static void +RADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr) data; + + RADEONTRACE(("RADEONStopVideo called\n")); + + REGION_EMPTY(pScrn->pScreen, &pPriv->clip); + + if (Exit) { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + OUTREG(RADEON_OV0_SCALE_CNTL,pPriv->scale_cntl|pPriv->video_format); + } + if(pPriv->linear) { + xf86FreeOffscreenLinear(pPriv->linear); + pPriv->linear = NULL; + } + pPriv->videoStatus = 0; + } else { + if(pPriv->videoStatus & CLIENT_VIDEO_ON) { + } + } +} + +static int +RADEONSetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 value, + pointer data +) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr) data; + + RADEONTRACE(("RADEONSetPortAttribute called\n")); + + if (attribute == xvColorKey) { + pPriv->colorKey = value; + OUTREG(RADEON_OV0_GRAPHICS_KEY_CLR,pPriv->colorKey); + RADEONTRACE(("Setting ColorKey to %d\n", pPriv->colorKey)); + return Success; + } + + return Success; +} + +static int +RADEONGetPortAttribute( + ScrnInfoPtr pScrn, + Atom attribute, + INT32 *value, + pointer data +) +{ + RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr) data; + + RADEONTRACE(("RADEONGetPortAttribute called\n")); + + if (attribute == xvColorKey) { + RADEONTRACE(("Getting ColorKey %d\n", pPriv->colorKey)); + *value = pPriv->colorKey; + return Success; + } + + return Success; +} + +static void +RADEONQueryBestSize( + ScrnInfoPtr pScrn, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + pointer data +) +{ + RADEONTRACE(("RADEONQueryBestSize called\n")); + *p_w = drw_w; + *p_h = drw_h; +} + +static void +RADEONDisplayVideo( + ScrnInfoPtr pScrn, + short width, short height, + int xa, int ya, int xb, int yb, + short src_w, short src_h, + short drw_w, short drw_h, + int fboffset +) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; + int step_by, vert_inc, horz_inc; + + RADEONTRACE(("RADEONDisplayVideo called\n")); + + /* calculate step_by factor */ + step_by=src_w/(drw_w*2); + switch(step_by){ + case 0: + OUTREG(RADEON_OV0_STEP_BY,0x101); + step_by=1; + break; + case 1: + OUTREG(RADEON_OV0_STEP_BY,0x202); + step_by=2; + break; + case 2: + case 3: + OUTREG(RADEON_OV0_STEP_BY,0x303); + step_by=4; + break; + default: + OUTREG(RADEON_OV0_STEP_BY,0x404); + step_by=8; + break; + } + + vert_inc=(src_h<<12)/(drw_h); + horz_inc=(src_w<<12)/(drw_w*step_by); + + OUTREG(RADEON_OV0_Y_X_START,((xa))|(ya<<16)|(1<<31)); + OUTREG(RADEON_OV0_Y_X_END,((xb))|((yb)<<16)); + OUTREG(RADEON_OV0_H_INC,(horz_inc)|((horz_inc<<15))); + OUTREG(RADEON_OV0_V_INC,(vert_inc<<8)); + OUTREG(RADEON_OV0_P1_BLANK_LINES_AT_TOP,0xfff|((src_h-1)<<16)); + OUTREG(RADEON_OV0_P23_BLANK_LINES_AT_TOP,0xfff|((src_h-1)<<16)); + OUTREG(RADEON_OV0_VID_BUF_PITCH0_VALUE,width<<1); + OUTREG(RADEON_OV0_VID_BUF_PITCH1_VALUE,width<<1); + OUTREG(RADEON_OV0_P1_X_START_END,(src_w-1)|((xa&0xf)<<16)); + OUTREG(RADEON_OV0_P2_X_START_END,(src_w-1)|((xa&0xf)<<16)); + OUTREG(RADEON_OV0_P3_X_START_END,(src_w-1)|((xa&0xf)<<16)); + + OUTREG(RADEON_OV0_VID_BUF0_BASE_ADRS,(fboffset)&(~0xf)); + OUTREG(RADEON_OV0_VID_BUF1_BASE_ADRS,(fboffset)&(~0xf)); + OUTREG(RADEON_OV0_VID_BUF2_BASE_ADRS,(fboffset)&(~0xf)); + +#if 0 + /* Enable this when double buffering is implemented */ + OUTREG(RADEON_OV0_VID_BUF3_BASE_ADRS,(fboffset2)&(~0xf)); + OUTREG(RADEON_OV0_VID_BUF4_BASE_ADRS,(fboffset2)&(~0xf)); + OUTREG(RADEON_OV0_VID_BUF5_BASE_ADRS,(fboffset2)&(~0xf)); +#endif + + OUTREG(RADEON_OV0_SCALE_CNTL,pPriv->scale_cntl|RADEON_SCALER_ENABLE|pPriv->video_format); +} + +static void +RADEONCopyData( + unsigned char *src, + unsigned char *dst, + int srcPitch, + int dstPitch, + int h, + int w + ) +{ + w <<= 1; + while(h--) { + memcpy(dst, src, w); + src += srcPitch; + dst += dstPitch; + } +} + +static void +RADEONCopyMungedData( + unsigned char *src1, + unsigned char *src2, + unsigned char *src3, + unsigned char *dst1, + int srcPitch, + int srcPitch2, + int dstPitch, + int h, + int w + ) +{ + CARD32 *dst = (CARD32*)dst1; + int i, j; + + dstPitch >>= 2; + w >>= 1; + + for(j = 0; j < h; j++) { + for(i = 0; i < w; i++) { + dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | + (src3[i] << 8) | (src2[i] << 24); + } + dst += dstPitch; + src1 += srcPitch; + if(j & 1) { + src2 += srcPitch2; + src3 += srcPitch2; + } + } +} + +static FBLinearPtr +RADEONAllocateMemory( + ScrnInfoPtr pScrn, + FBLinearPtr linear, + int size +) +{ + ScreenPtr pScreen; + FBLinearPtr new_linear; + + RADEONTRACE(("RADEONAllocateMemory(%x,%d) called\n",linear,size)); + + if(linear) { + if(linear->size >= size) + return linear; + + if(xf86ResizeOffscreenLinear(linear, size)) + return linear; + + xf86FreeOffscreenLinear(linear); + } + + pScreen = screenInfo.screens[pScrn->scrnIndex]; + + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + + if(!new_linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, + PRIORITY_EXTREME); + + if(max_size < size) return NULL; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + } + + RADEONTRACE(("returning %x(%x)\n",new_linear,new_linear->offset)); + + return new_linear; +} + +static int +RADEONPutImage( + ScrnInfoPtr pScrn, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, unsigned char* buf, + short width, short height, + Bool Sync, + RegionPtr clipBoxes, pointer data +) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; + INT32 xa, xb, ya, yb; + INT32 d_x,d_y,d_width,d_height; + int srcPitch = 0, srcPitch2 = 0; + int dstPitch = 0; + int offset,offset2 = 0,offset3 = 0,fboffset; + int top, left, npixels, nlines, size; + CARD32 video_format; + + RADEONTRACE(("RADEONPutImage called\n")); + + switch(id) { + case FOURCC_YV12: + case FOURCC_UYVY: + video_format=RADEON_SCALER_SOURCE_VYUY422; + break; + case FOURCC_YUY2: + video_format=RADEON_SCALER_SOURCE_YVYU422; + break; + default: + return BadValue; + } + + /* Clip */ + d_x=drw_x; + d_y=drw_y; + d_width=drw_w; + d_height=drw_h; + if(drw_x<0){ + drw_w+=drw_x; + drw_x=0; + } + if(drw_y<0){ + drw_h+=drw_y; + drw_y=0; + } + if(drw_x+drw_w>pScrn->pScreen->width){ + drw_w=pScrn->pScreen->width-drw_x; + } + if(drw_y+drw_h>pScrn->pScreen->height){ + drw_h=pScrn->pScreen->height-drw_y; + } + if((drw_w<=0)||(drw_h<=0)){ + /* this should not happen, + since we are outside of visible screen, + but just in case */ + return Success; + } + + xa = src_x; + xb = src_x + src_w; + ya = src_y; + yb = src_y + src_h; + + dstPitch = width*info->CurrentLayout.pixel_bytes; + srcPitch=width; + + switch(id) { + case FOURCC_YV12: + size = width * height * 2; /* 16bpp */ + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = width * height * 1.5; + break; + } + + if(!(pPriv->linear = RADEONAllocateMemory(pScrn, pPriv->linear,size))) + return BadAlloc; + + /* copy data */ + top = ya >> 16; + left = (xa >> 16) & ~1; + npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left; + + switch(id) { + case FOURCC_YV12: + srcPitch = (width + 3) & ~3; + offset2 = srcPitch * height; + srcPitch2 = ((width >> 1) + 3) & ~3; + offset3 = (srcPitch2 * (height >> 1)) + offset2; + nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + buf += (top * srcPitch) + left; + nlines = ((yb + 0xffff) >> 16) - top; + srcPitch = (width << 1); + break; + } + nlines=src_h; + npixels=src_w; + if(npixels>width) npixels=width; + if(nlines>height) nlines=height; + + /* adjust source rectangle */ + src_x+=((drw_x-d_x)*src_w)/d_width; + src_y+=((drw_y-d_y)*src_h)/d_height; + + src_w=(src_w * drw_w)/d_width; + src_h=(src_h * drw_h)/d_height; + + offset=(src_x+src_y*width)*info->CurrentLayout.pixel_bytes; + fboffset=pPriv->linear->offset*info->CurrentLayout.pixel_bytes; + + if(!(INREG(RADEON_CRTC_STATUS)&2)){ + xf86DrvMsg(pScrn->scrnIndex,X_INFO,"too fast"); + return Success; + } + + RADEONDisplayVideo(pScrn, width, height, + drw_x, drw_y, drw_x+drw_w, drw_y+drw_h, + src_w, src_h, drw_w, drw_h, fboffset); + + /* update cliplist */ + if(!RegionsEqual(&pPriv->clip, clipBoxes)) { + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); + /* draw these */ + XAAFillSolidRects(pScrn, pPriv->colorKey, GXcopy, ~0, + REGION_NUM_RECTS(clipBoxes), + REGION_RECTS(clipBoxes)); + } + + + switch(id) { + case FOURCC_YV12: + RADEONCopyMungedData(buf + (top * srcPitch) + (left >> 1), + buf + offset2, buf + offset3, info->FB+fboffset, + srcPitch, srcPitch2, dstPitch, nlines, npixels); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + RADEONCopyData(buf,info->FB+fboffset,srcPitch,dstPitch, + nlines,npixels); + break; + } + + pPriv->videoStatus = CLIENT_VIDEO_ON; + return Success; +} + +static int +RADEONQueryImageAttributes( + ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets +) +{ + int size, tmp; + RADEONTRACE(("RADEONQueryImageAtrributes called\n")); + + if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; + if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; + + *w = (*w + 1) & ~1; + if(offsets) offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if(pitches) pitches[0] = size; + size *= *h; + if(offsets) offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if(pitches) pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) offsets[2] = size; + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = *w << 1; + if(pitches) pitches[0] = size; + size *= *h; + break; + } + + return size; +} +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile index e460edc38..b52639771 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile @@ -4,7 +4,7 @@ XCOMM $XConsortium: Imakefile /main/13 1996/10/27 11:49:09 kaleb $ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile,v 1.26 2000/10/23 12:10:10 alanh Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile,v 1.27 2000/11/03 18:46:08 eich Exp $ #define IHaveModules #include <Server.tmpl> @@ -21,13 +21,13 @@ DEFINES = -DPSZ=8 INCLUDES = -I. -I../../include #else INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC)/fbdevhw\ - -I$(XF86SRC)/vgafb -I$(XF86SRC)/vgahw -I$(SERVERSRC)/include \ - -I$(SERVERSRC)/mi -I$(SERVERSRC)/fb -I$(SERVERSRC)/cfb \ - -I$(SERVERSRC)/mfb -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \ - -I$(SERVERSRC)/Xext -I$(XINCLUDESRC) -I$(XF86SRC)/xaa \ - -I$(FONTINCSRC) -I$(XF86SRC)/ramdac -I$(XF86SRC)/rac \ - -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c -I$(XF86SRC)/xf24_32bpp \ - -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xf8_16bpp -I$(XF86SRC)/int10 \ + -I$(SERVERSRC)/fb -I$(XF86SRC)/vgahw -I$(SERVERSRC)/include \ + -I$(SERVERSRC)/mi -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \ + -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp -I$(SERVERSRC)/Xext \ + -I$(XINCLUDESRC) -I$(XF86SRC)/xaa -I$(FONTINCSRC) \ + -I$(XF86SRC)/ramdac -I$(XF86SRC)/rac -I$(XF86SRC)/ddc \ + -I$(XF86SRC)/i2c -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb \ + -I$(XF86SRC)/xf8_16bpp -I$(XF86SRC)/int10 \ -I$(XF86OSSRC)/vbe -I$(EXTINCSRC) -I$(SERVERSRC)/render #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c index 8cea2ce6f..d22accc44 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c +++ b/xc/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.97 2000/10/27 18:31:03 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c,v 1.99 2000/11/03 22:05:46 tsi Exp $ */ /* * Copyright 1993 by Jon Block <block@frc.com> @@ -105,17 +105,7 @@ /* All drivers using the mi colormap manipulation need this */ #include "micmap.h" -/* Using fb so this is needed */ #include "fb.h" - -/* If using cfb, cfb.h is required. */ -#define PSZ 8 -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" -#include "cfb24_32.h" #include "cfb8_16.h" @@ -136,6 +126,10 @@ /* Needed for replacement LoadPalette function for Gamma Correction */ #include "xf86cmap.h" +#ifdef RENDER +#include "picturestr.h" +#endif + /* Driver specific headers */ #include "ct_driver.h" @@ -564,8 +558,7 @@ typedef enum { OPTION_FP_CLOCK_32, OPTION_SET_MCLK, OPTION_ROTATE, - OPTION_NO_TMED, - OPTION_USE_FB + OPTION_NO_TMED } CHIPSOpts; static OptionInfoRec Chips655xxOptions[] = { @@ -592,7 +585,6 @@ static OptionInfoRec Chips655xxOptions[] = { { OPTION_FP_CLOCK_8, "FPClock8", OPTV_FREQ, {0}, FALSE }, { OPTION_FP_CLOCK_16, "FPClock16", OPTV_FREQ, {0}, FALSE }, { OPTION_FP_CLOCK_24, "FPClock24", OPTV_FREQ, {0}, FALSE }, - { OPTION_USE_FB, "UseFB", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -608,7 +600,6 @@ static OptionInfoRec ChipsWingineOptions[] = { { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, - { OPTION_USE_FB, "UseFB", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -638,7 +629,6 @@ static OptionInfoRec ChipsHiQVOptions[] = { { OPTION_FP_CLOCK_32, "FPClock32", OPTV_FREQ, {0}, FALSE }, { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE }, { OPTION_NO_TMED, "NoTMED", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_USE_FB, "UseFB", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -667,13 +657,8 @@ static const char *vgahwSymbols[] = { static const char *fbSymbols[] = { "xf1bppScreenInit", "xf4bppScreenInit", - "cfbScreenInit", - "cfb16ScreenInit", "cfb8_16ScreenInit", - "cfb24ScreenInit", - "cfb24_32ScreenInit", - "cfb32ScreenInit", - "fbScreenInit", + "fb_ScreenInit", NULL }; @@ -1118,13 +1103,6 @@ CHIPSPreInit(ScrnInfoPtr pScrn, int flags) else res = chipsPreInit655xx(pScrn, flags); - /* See whether the user wants to use the new framebuffer code */ - if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_FB, FALSE)) { - cPtr->Flags |= ChipsUseNewFB; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using \"New Framebuffer\"\n"); - } - if (cPtr->UseFullMMIO) chipsUnmapMem(pScrn); @@ -1205,69 +1183,40 @@ CHIPSPreInit(ScrnInfoPtr pScrn, int flags) /* Load bpp-specific modules */ switch (pScrn->bitsPerPixel) { case 1: - mod = "xf1bpp"; - reqSym = "xf1bppScreenInit"; + if (xf86LoadSubModule(pScrn, "xf1bpp") == NULL) { + CHIPSFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols("xf1bppScreenInit", NULL); break; case 4: - mod = "xf4bpp"; - reqSym = "xf4bppScreenInit"; + if (xf86LoadSubModule(pScrn, "xf4bpp") == NULL) { + CHIPSFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols("xf4bppScreenInit", NULL); break; + case 16: + if (cPtr->Flags & ChipsOverlay8plus16) { + if (xf86LoadSubModule(pScrn, "xf8_16bpp") == NULL) { + CHIPSFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols("cfb8_16bppScreenInit", NULL); + break; + } default: - if (cPtr->Flags & ChipsUseNewFB) - switch (pScrn->bitsPerPixel) { - case 16: - reqSym = "xf4bppScreenInit"; - if (cPtr->Flags & ChipsOverlay8plus16) { - mod = "xf8_16bpp"; - reqSym = "cfb8_16ScreenInit"; - break; - } else - reqSym = "fbScreenInit"; - /* fall through */ - case 8: - case 24: - case 32: - mod = "fb"; - break; - } - else - switch (pScrn->bitsPerPixel) { - case 8: - mod = "cfb"; - reqSym = "cfbScreenInit"; - break; - case 16: - if (cPtr->Flags & ChipsOverlay8plus16) { - mod = "xf8_16bpp"; - reqSym = "cfb8_16ScreenInit"; - } else { - mod = "cfb16"; - reqSym = "cfb16ScreenInit"; - } - break; - case 24: - if (pix24bpp == 24) { - mod = "cfb24"; - reqSym = "cfb24ScreenInit"; - } else { - mod = "xf24_32bpp"; - reqSym = "cfb24_32ScreenInit"; - } - break; - case 32: - mod = "cfb32"; - reqSym = "cfb32ScreenInit"; - break; - } - } - - if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { - CHIPSFreeRec(pScrn); - return FALSE; + if (xf86LoadSubModule(pScrn, "fb") == NULL) { + CHIPSFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols("fbScreenInit", NULL); +#ifdef RENDER + xf86LoaderReqSymbols("fbPictureInit", NULL); +#endif + break; } - - xf86LoaderReqSymbols(reqSym, NULL); - + if (cPtr->Flags & ChipsAccelSupport) { if (!xf86LoadSubModule(pScrn, "xaa")) { CHIPSFreeRec(pScrn); @@ -1378,17 +1327,8 @@ chipsPreInitHiQV(ScrnInfoPtr pScrn, int flags) } } - if (!xf86SetDefaultVisual(pScrn, -1)) { + 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; - } - } /* The gamma fields must be initialised when using the new cmap code */ if (pScrn->depth > 1) { @@ -2226,17 +2166,8 @@ chipsPreInitWingine(ScrnInfoPtr pScrn, int flags) } } - if (!xf86SetDefaultVisual(pScrn, -1)) { + 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; - } - } /* The gamma fields must be initialised when using the new cmap code */ if (pScrn->depth > 1) { @@ -2700,17 +2631,8 @@ chipsPreInit655xx(ScrnInfoPtr pScrn, int flags) } } - if (!xf86SetDefaultVisual(pScrn, -1)) { + 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; - } - } /* The gamma fields must be initialised when using the new cmap code */ if (pScrn->depth > 1) { @@ -3588,24 +3510,14 @@ CHIPSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask, pScrn->rgbBits, PseudoColor)) return FALSE; - if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, - TrueColor)) - return FALSE; - } else if ((pScrn->depth > 8) && (!(cPtr->Flags & ChipsGammaSupport))) { - /* - * For bpp > 8, the default visuals are not acceptable because we only - * support TrueColor and not DirectColor. To deal with this, call - * miSetVisualTypes for each visual supported. - */ - 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 (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; } + ErrorF("bla\n"); + miSetPixmapDepths (); /* * Call the framebuffer layer's ScreenInit function, and fill in other @@ -3643,77 +3555,24 @@ CHIPSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->xDpi, pScrn->yDpi, displayWidth); break; + case 16: + if (cPtr->Flags & ChipsOverlay8plus16) { + ret = cfb8_16ScreenInit(pScreen, (unsigned char *)FBStart + + cPtr->FbOffset16, FBStart, width, + height, pScrn->xDpi, pScrn->yDpi, + displayWidth, displayWidth); + break; + } default: - if (cPtr->Flags & ChipsUseNewFB) - switch (pScrn->bitsPerPixel) { - case 16: - if (cPtr->Flags & ChipsOverlay8plus16) { - ret = cfb8_16ScreenInit(pScreen, (unsigned char *)FBStart - + cPtr->FbOffset16, FBStart, width, - height, pScrn->xDpi, pScrn->yDpi, - displayWidth, displayWidth); - break; - } - case 8: - case 24: - case 32: - ret = fbScreenInit(pScreen, FBStart, + ret = fbScreenInit(pScreen, FBStart, width,height, pScrn->xDpi, pScrn->yDpi, displayWidth,pScrn->bitsPerPixel); - break; - default: - xf86DrvMsg(scrnIndex, X_ERROR, - "Internal error: invalid bpp (%d) in CHIPSScreenInit\n", - pScrn->bitsPerPixel); - ret = FALSE; - break; - } - else - switch (pScrn->bitsPerPixel) { - case 8: - ret = cfbScreenInit(pScreen, FBStart, - width,height, - pScrn->xDpi, pScrn->yDpi, - displayWidth); - break; - case 16: - if (cPtr->Flags & ChipsOverlay8plus16) - ret = cfb8_16ScreenInit(pScreen, (unsigned char *)FBStart - + cPtr->FbOffset16, FBStart, width, - height, pScrn->xDpi, pScrn->yDpi, - displayWidth, displayWidth); - else - ret = cfb16ScreenInit(pScreen, FBStart, - width, height, - pScrn->xDpi, pScrn->yDpi, - displayWidth); - break; - case 24: - if (pix24bpp == 24) - ret = cfb24ScreenInit(pScreen, FBStart, - width,height, - pScrn->xDpi, pScrn->yDpi, - displayWidth); - else - ret = cfb24_32ScreenInit(pScreen, FBStart, - width,height, - pScrn->xDpi, pScrn->yDpi, - displayWidth); - break; - case 32: - ret = cfb32ScreenInit(pScreen, FBStart, - width,height, - pScrn->xDpi, pScrn->yDpi, - displayWidth); - break; - default: - xf86DrvMsg(scrnIndex, X_ERROR, - "Internal error: invalid bpp (%d) in CHIPSScreenInit\n", - pScrn->bitsPerPixel); - ret = FALSE; - break; - } +#ifdef RENDER + if (ret) + fbPictureInit (pScreen, 0, 0); +#endif + break; } if (!ret) @@ -4187,6 +4046,9 @@ chipsDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, CHIPSPtr cPtr = CHIPSPTR(pScrn); unsigned char dpmsreg, seqreg, lcdoff, tmp; + if (!pScrn->vtSema) + return; + xf86EnableAccess(pScrn); switch (PowerManagementMode) { case DPMSModeOn: @@ -6271,7 +6133,7 @@ chipsRestoreExtendedRegs(ScrnInfoPtr pScrn, CHIPSRegPtr Regs) if ((i == 0x03) && (cPtr->Chipset != CHIPS_CT69030)) { /* restore the non clock bits */ tmp = cPtr->readFR(cPtr, 0x03); - cPtr->writeFR(cPtr, 0x01, ((Regs->FR[0x03] & 0xC3) | + cPtr->writeFR(cPtr, 0x03, ((Regs->FR[0x03] & 0xC3) | (tmp & ~0xC3))); continue; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c index 10f2a7c13..fa65fcdc3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c @@ -22,7 +22,7 @@ * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c,v 1.9 2000/10/27 22:30:29 robin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128_driver.c,v 1.13 2000/11/06 02:56:03 robin Exp $ */ /* All drivers should typically include these */ @@ -41,6 +41,9 @@ /* Drivers that need to access the PCI config space directly need this */ #include "xf86Pci.h" +/* vgaHW module is only used to save/restore fonts by this driver */ +#include "vgaHW.h" + /* All drivers initialising the SW cursor need this */ #include "mipointer.h" @@ -171,6 +174,18 @@ XF86ModuleData i128ModuleData = { &i128VersRec, i128Setup, NULL }; * LoaderRefSymLists() function in the module specific Setup() function. */ +static const char *vgahwSymbols[] = { + "vgaHWFreeHWRec", + "vgaHWGetHWRec", + "vgaHWGetIOBase", + "vgaHWLock", + "vgaHWProtect", + "vgaHWRestore", + "vgaHWSave", + "vgaHWUnlock", + NULL +}; + static const char *fbSymbols[] = { "fbScreenInit", NULL @@ -267,6 +282,7 @@ i128Setup(pointer module, pointer opts, int *errmaj, int *errmin) i2cSymbols, vbeSymbols, int10Symbols, + vgahwSymbols, NULL); /* @@ -545,6 +561,20 @@ I128PreInit(ScrnInfoPtr pScrn, int flags) pI128->Primary = xf86IsPrimaryPci(pI128->PciInfo); + /* The vgahw module should be allocated here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + return FALSE; + + xf86LoaderReqSymLists(vgahwSymbols, NULL); + + /* + * Allocate a vgaHWRec + */ + if (!vgaHWGetHWRec(pScrn)) + return FALSE; + + vgaHWGetIOBase(VGAHWPTR(pScrn)); + /* Set pScrn->monitor */ pScrn->monitor = pScrn->confScreen->monitor; @@ -793,8 +823,7 @@ I128PreInit(ScrnInfoPtr pScrn, int flags) if (!pI128->Primary) I128SoftReset(pScrn); - if ((pI128->Chipset == PCI_CHIP_I128_T2R) || - (pI128->Chipset == PCI_CHIP_I128_T2R4)) { + if (pI128->Chipset != PCI_CHIP_I128) { pI128->ddc1Read = NULL /*I128DDC1Read*/; pI128->i2cInit = I128I2CInit; } @@ -1074,8 +1103,8 @@ I128PreInit(ScrnInfoPtr pScrn, int flags) linePitches, minPitch, maxPitch, pitchAlignment * pI128->bitsPerPixel, 128, 2048, - pScrn->virtualX, - pScrn->virtualY, + pScrn->display->virtualX, + pScrn->display->virtualY, pI128->MemorySize, LOOKUP_BEST_REFRESH); @@ -1324,9 +1353,7 @@ I128MapMem(ScrnInfoPtr pScrn) static Bool I128UnmapMem(ScrnInfoPtr pScrn) { - I128Ptr pI128; - - pI128 = I128PTR(pScrn); + I128Ptr pI128 = I128PTR(pScrn); xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unmapping memory\n"); @@ -1358,6 +1385,12 @@ I128UnmapMem(ScrnInfoPtr pScrn) static void I128Save(ScrnInfoPtr pScrn) { + I128Ptr pI128 = I128PTR(pScrn); + vgaHWPtr vgaHWP = VGAHWPTR(pScrn); + + if (pI128->Primary) + vgaHWSave(pScrn, &vgaHWP->SavedReg, VGA_SR_ALL); + I128SaveState(pScrn); } @@ -1367,7 +1400,16 @@ I128Save(ScrnInfoPtr pScrn) static void I128Restore(ScrnInfoPtr pScrn) { + I128Ptr pI128 = I128PTR(pScrn); + vgaHWPtr vgaHWP = VGAHWPTR(pScrn); + I128RestoreState(pScrn); + + if (pI128->Primary) { + vgaHWProtect(pScrn, TRUE); + vgaHWRestore(pScrn, &vgaHWP->SavedReg, VGA_SR_ALL); + vgaHWProtect(pScrn, FALSE); + } } /* Usually mandatory */ @@ -1678,6 +1720,9 @@ I128FreeScreen(int scrnIndex, int flags) * This only gets called when a screen is being deleted. It does not * get called routinely at the end of a server generation. */ + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + I128FreeRec(xf86Screens[scrnIndex]); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c index 27ad796cc..46b4abafd 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c,v 1.4 2000/10/24 02:00:06 robin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128accel.c,v 1.6 2000/11/01 23:33:06 robin Exp $ */ /* * Copyright 1997-2000 by Robin Cutshaw <robin@XFree86.Org> @@ -104,7 +104,7 @@ I128BitBlit(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) #if 0 if (pI128->Debug) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BB %d,%d %d,%d %d,%d\n", x1, y1, x2, y2, w, h); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BB %d,%d %d,%d %d,%d 0x%x/0x%x\n", x1, y1, x2, y2, w, h, pI128->cmd); #endif ENG_PIPELINE_READY(); @@ -428,7 +428,7 @@ I128AccelInit(ScreenPtr pScreen) infoPtr->Sync = I128EngineDone; /* screen to screen copy */ - infoPtr->ScreenToScreenCopyFlags = 0; + infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; if (pI128->Chipset == PCI_CHIP_I128_T2R) infoPtr->ScreenToScreenCopyFlags |= ONLY_LEFT_TO_RIGHT_BITBLT; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128init.c b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128init.c index f8c8a804e..125e66f5f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/i128/i128init.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/i128/i128init.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128init.c,v 1.4 2000/10/25 00:09:17 robin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i128/i128init.c,v 1.5 2000/11/03 00:50:53 robin Exp $ */ /* * Copyright 1995-2000 by Robin Cutshaw <robin@XFree86.Org> * Copyright 1998 by Number Nine Visual Technology, Inc. @@ -39,8 +39,6 @@ void I128SavePalette(I128Ptr pI128); void I128RestorePalette(I128Ptr pI128); -#define VGA_SAVE_COUNT 4096*1024 - void I128SaveState(ScrnInfoPtr pScrn) @@ -59,6 +57,7 @@ I128SaveState(ScrnInfoPtr pScrn) } /* iobase is filled in during the device probe (as well as config 1&2)*/ + if ((pI128->io.id&0x7) > 0) { iR->vga_ctl = inl(iR->iobase + 0x30); } @@ -299,15 +298,10 @@ I128RestoreState(ScrnInfoPtr pScrn) } /* iobase is filled in during the device probe (as well as config 1&2)*/ + if (((pI128->io.id&0x7) > 0) || (pI128->Chipset == PCI_CHIP_I128_T2R) || (pI128->Chipset == PCI_CHIP_I128_T2R4)) { - int i; - unsigned char *vidmem = (unsigned char *)pI128->mem.mw0_ad; - - if (pI128->Primary) - for (i=0; i<VGA_SAVE_COUNT; i++) - vidmem[i] = pI128->vgamem[i]; outl(iR->iobase + 0x30, iR->vga_ctl); } @@ -508,18 +502,6 @@ I128Init(ScrnInfoPtr pScrn, DisplayModePtr mode) usleep(5000); outl(iR->iobase + 0x24, 0xA1089030); } - - if (!pI128->FontsSaved && pI128->Primary) { - int i; - unsigned char *vidmem = - (unsigned char *)pI128->mem.mw0_ad; - - pI128->vgamem = xnfalloc(VGA_SAVE_COUNT); - for (i=0; i<VGA_SAVE_COUNT; i++) - pI128->vgamem[i] = vidmem[i]; - pI128->FontsSaved = TRUE; - } - } ret = pI128->ProgramDAC(pScrn, mode); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c index 5ec08696f..0979a7281 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c,v 1.54 2000/10/24 22:45:07 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c,v 1.55 2000/11/02 02:51:19 dawes Exp $ */ /* * Copyright 1994 by Robin Cutshaw <robin@XFree86.org> * @@ -50,12 +50,10 @@ #include "mga_bios.h" #include "mga_reg.h" #include "mga.h" +#include "mga_macros.h" #include "xf86DDC.h" -/* Set to 1 if you want to set MCLK from XF86Config - AT YOUR OWN RISK! */ -#define MCLK_FROM_XCONFIG 0 - /* * Only change these bits in the Option register. Make sure that the * vgaioen bit is never in this mask because it is controlled elsewhere @@ -269,7 +267,6 @@ MGATi3026CalcClock ( return f_pll; } -#ifndef USEMGAHAL /* * MGATi3026SetMCLK - Set the memory clock (MCLK) PLL. * @@ -353,7 +350,6 @@ MGATi3026SetMCLK( ScrnInfoPtr pScrn, long f_out ) ; } } -#endif /* * MGATi3026SetPCLK - Set the pixel (PCLK) and loop (LCLK) clocks. @@ -505,9 +501,7 @@ MGA3026Init(ScrnInfoPtr pScrn, DisplayModePtr mode) int i, BppShift, index_1d = 0; const unsigned char* initDAC; MGAPtr pMga = MGAPTR(pScrn); -#ifndef USEMGAHAL MGARamdacPtr MGAdac = &pMga->Dac; -#endif MGAFBLayout *pLayout = &pMga->CurrentLayout; MGARegPtr pReg = &pMga->ModeReg; vgaRegPtr pVga = &VGAHWPTR(pScrn)->ModeReg; @@ -720,9 +714,7 @@ MGA3026Init(ScrnInfoPtr pScrn, DisplayModePtr mode) but that's no big deal since we will Restore right after this function */ -#ifndef USEMGAHAL - MGATi3026SetMCLK( pScrn, MGAdac->MemoryClock ); -#endif + MGA_NOT_HAL(MGATi3026SetMCLK(pScrn, MGAdac->MemoryClock)); #ifdef DEBUG ErrorF("%6ld: %02X %02X %02X %02X %02X %02X %08lX\n", mode->Clock, @@ -760,7 +752,7 @@ MGA3026Restore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, OPTION_MASK, mgaReg->Option); -#ifndef USEMGAHAL + MGA_NOT_HAL( /* select pixel clock PLL as clock source */ outTi3026(TVP3026_CLK_SEL, 0, mgaReg->DacRegs[3]); @@ -768,7 +760,7 @@ MGA3026Restore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, outTi3026(TVP3026_PLL_ADDR, 0, 0x2A); outTi3026(TVP3026_LOAD_CLK_DATA, 0, 0); outTi3026(TVP3026_PIX_CLK_DATA, 0, 0); -#endif + ); /* MGA_NOT_HAL */ /* * This function handles restoring the generic VGA registers. @@ -782,7 +774,7 @@ MGA3026Restore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, * goes here. */ -#ifndef USEMGAHAL + MGA_NOT_HAL( /* program pixel clock PLL */ outTi3026(TVP3026_PLL_ADDR, 0, 0x00); for (i = 0; i < 3; i++) @@ -796,20 +788,20 @@ MGA3026Restore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, /* set Q divider for loop clock PLL */ outTi3026(TVP3026_MCLK_CTL, 0, mgaReg->DacRegs[18]); -#endif + ); /* MGA_NOT_HAL */ /* program loop PLL */ outTi3026(TVP3026_PLL_ADDR, 0, 0x00); for (i = 3; i < 6; i++) outTi3026(TVP3026_LOAD_CLK_DATA, 0, mgaReg->DacClk[i]); -#ifndef USEMGAHAL + MGA_NOT_HAL( if ((vgaReg->MiscOutReg & 0x08) && ((mgaReg->DacClk[3] & 0xC0) == 0xC0) ) { /* poll until loop PLL LOCK bit is set */ outTi3026(TVP3026_PLL_ADDR, 0, 0x3F); while ( ! (inTi3026(TVP3026_LOAD_CLK_DATA) & 0x40) ); } -#endif + ); /* MGA_NOT_HAL */ /* * restore other DAC registers @@ -862,7 +854,7 @@ MGA3026Save(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, mgaReg->ExtVga[i] = INREG8(0x1FDF); } -#ifndef USEMGAHAL + MGA_NOT_HAL( outTi3026(TVP3026_PLL_ADDR, 0, 0x00); for (i = 0; i < 3; i++) outTi3026(TVP3026_PIX_CLK_DATA, 0, mgaReg->DacClk[i] = @@ -872,7 +864,7 @@ MGA3026Save(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, for (i = 3; i < 6; i++) outTi3026(TVP3026_LOAD_CLK_DATA, 0, mgaReg->DacClk[i] = inTi3026(TVP3026_LOAD_CLK_DATA)); -#endif + ); /* MGA_NOT_HAL */ for (i = 0; i < DACREGSIZE; i++) mgaReg->DacRegs[i] = inTi3026(MGADACregs[i]); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c index 620b2c7d0..5efb33ab6 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c @@ -2,7 +2,7 @@ * MGA-1064, MGA-G100, MGA-G200, MGA-G400 RAMDAC driver */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c,v 1.40 2000/10/24 22:45:07 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c,v 1.41 2000/11/02 02:51:19 dawes Exp $ */ /* * This is a first cut at a non-accelerated version to work with the @@ -25,6 +25,7 @@ #include "mga_bios.h" #include "mga_reg.h" #include "mga.h" +#include "mga_macros.h" #include "xf86DDC.h" @@ -82,7 +83,6 @@ static Bool MGAGInit(ScrnInfoPtr, DisplayModePtr); static void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr); static Bool MGAG_i2cInit(ScrnInfoPtr pScrn); -#ifndef USEMGAHAL /* * MGAGCalcClock - Calculate the PLL settings (m, n, p, s). * @@ -245,7 +245,6 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out ) pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n & 0x7F; pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = (p & 0x07) | ((s & 0x03) << 3); } -#endif /* * MGAGInit @@ -253,7 +252,6 @@ MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out ) static Bool MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) { -#ifndef USEMGAHAL /* * initial values of the DAC registers */ @@ -271,7 +269,6 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) }; int i, weight555 = FALSE; -#endif int hd, hs, he, ht, vd, vs, ve, vt, wd; int BppShift; MGAPtr pMga; @@ -286,7 +283,7 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) BppShift = pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]; -#ifndef USEMGAHAL + MGA_NOT_HAL( /* Allocate the DacRegs space if not done already */ if (pReg->DacRegs == NULL) { pReg->DacRegs = xnfcalloc(DACREGSIZE, 1); @@ -294,6 +291,7 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) for (i = 0; i < DACREGSIZE; i++) { pReg->DacRegs[i] = initDAC[i]; } + ); /* MGA_NOT_HAL */ switch(pMga->Chipset) { @@ -336,6 +334,7 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) } pReg->Option2 = 0x0000007; break; +#ifndef USEMGAHAL case PCI_CHIP_MGAG400: if(pMga->Dac.maxPixelClock == 360000) { /* G400 MAX */ if(pMga->OverclockMem) { @@ -394,8 +393,10 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) else pReg->Option = 0x4049cd21; break; +#endif } + MGA_NOT_HAL( /* must always have the pci retries on but rely on polling to keep them from occuring */ pReg->Option &= ~0x20000000; @@ -427,7 +428,7 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) default: FatalError("MGA: unsupported depth\n"); } -#endif + ); /* MGA_NOT_HAL */ /* * This will initialize all of the generic VGA registers. @@ -508,29 +509,23 @@ MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pVga->CRTC[21] = vd & 0xFF; pVga->CRTC[22] = (vt + 1) & 0xFF; -#ifndef USEMGAHAL - pReg->DacRegs[ MGA1064_CURSOR_BASE_ADR_LOW ] = - pMga->FbCursorOffset >> 10; - pReg->DacRegs[ MGA1064_CURSOR_BASE_ADR_HI ] = - pMga->FbCursorOffset >> 18; -#endif + MGA_NOT_HAL(pReg->DacRegs[MGA1064_CURSOR_BASE_ADR_LOW] = pMga->FbCursorOffset >> 10); + MGA_NOT_HAL(pReg->DacRegs[MGA1064_CURSOR_BASE_ADR_HI] = pMga->FbCursorOffset >> 18); if (pMga->SyncOnGreen) { -#ifndef USEMGAHAL - pReg->DacRegs[ MGA1064_GEN_CTL ] &= ~0x20; -#endif + MGA_NOT_HAL(pReg->DacRegs[MGA1064_GEN_CTL] &= ~0x20); pReg->ExtVga[3] |= 0x40; } /* select external clock */ pVga->MiscOutReg |= 0x0C; -#ifndef USEMGAHAL + MGA_NOT_HAL( if (mode->Flags & V_DBLSCAN) pVga->CRTC[9] |= 0x80; - MGAGSetPCLK( pScrn, mode->Clock ); -#endif + MGAGSetPCLK(pScrn, mode->Clock); + ); /* MGA_NOT_HAL */ /* This disables the VGA memory aperture */ pVga->MiscOutReg &= ~0x02; @@ -639,9 +634,9 @@ MGAGRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, { int i; MGAPtr pMga = MGAPTR(pScrn); -#ifndef USEMGAHAL CARD32 optionMask; + MGA_NOT_HAL( /* * Code is needed to get things back to bank zero. */ @@ -675,7 +670,8 @@ MGAGRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, if (pMga->Chipset == PCI_CHIP_MGAG400) pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION3, OPTION3_MASK, mgaReg->Option3); -#endif + ); /* MGA_NOT_HAL */ + /* restore CRTCEXT regs */ for (i = 0; i < 6; i++) OUTREG16(0x1FDE, (mgaReg->ExtVga[i] << 8) | i); @@ -724,12 +720,12 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, MGAPtr pMga = MGAPTR(pScrn); if(pMga->SecondCrtc == TRUE) return; -#ifndef USEMGAHAL + MGA_NOT_HAL( /* Allocate the DacRegs space if not done already */ if (mgaReg->DacRegs == NULL) { mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1); } -#endif + ); /* MGA_NOT_HAL */ /* * Code is needed to get back to bank zero. @@ -743,7 +739,7 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | (saveFonts ? VGA_SR_FONTS : 0)); MGAGSavePalette(pScrn, vgaReg->DAC); -#ifndef USEMGAHAL + MGA_NOT_HAL( /* * The port I/O code necessary to read in the extended registers. */ @@ -755,7 +751,7 @@ MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg, mgaReg->Option2 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION2); if (pMga->Chipset == PCI_CHIP_MGAG400) mgaReg->Option3 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION3); -#endif + ); /* MGA_NOT_HAL */ for (i = 0; i < 6; i++) { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c index 947fb1565..b8d46ade3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.9 2000/10/24 22:45:07 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.10 2000/11/02 19:10:51 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -101,12 +101,10 @@ Bool MgaInitDma(ScrnInfoPtr pScrn, int prim_size) init.chipset = MGA_CARD_TYPE_G400; break; case PCI_CHIP_MGAG200: + case PCI_CHIP_MGAG200_PCI: init.chipset = MGA_CARD_TYPE_G200; break; - case PCI_CHIP_MGAG200_PCI: default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[drm] Direct rendering not supported on this card/chipset\n"); return FALSE; } @@ -350,6 +348,18 @@ Bool MGADRIScreenInit(ScreenPtr pScreen) int init_offset; int i; + switch(pMGA->Chipset) { + case PCI_CHIP_MGAG400: + case PCI_CHIP_MGAG200: +#if 0 + case PCI_CHIP_MGAG200_PCI: +#endif + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] Direct rendering only supported with G200/G400 AGP\n"); + return FALSE; + } + /* Check that the GLX, DRI, and DRM modules have been loaded by testing * for canonical symbols in each module. */ if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; @@ -373,15 +383,12 @@ Bool MGADRIScreenInit(ScreenPtr pScreen) } } - xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] bpp: %d depth: %d\n", pScrn->bitsPerPixel, - pScrn->depth); - + xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] bpp: %d depth: %d\n", pScrn->bitsPerPixel, pScrn->depth); if ((pScrn->bitsPerPixel / 8) != 2 && (pScrn->bitsPerPixel / 8) != 4) { xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] Direct Rendering only supported in 16 and 32 bpp modes\n"); + "[drm] Direct rendering only supported in 16 and 32 bpp modes\n"); return FALSE; } @@ -607,12 +614,10 @@ Bool MGADRIScreenInit(ScreenPtr pScreen) pMGADRI->chipset = MGA_CARD_TYPE_G400; break; case PCI_CHIP_MGAG200: + case PCI_CHIP_MGAG200_PCI: pMGADRI->chipset = MGA_CARD_TYPE_G200; break; - case PCI_CHIP_MGAG200_PCI: default: - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] Direct rendering not supported on this card/chipset\n"); return FALSE; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c index 243c27e82..685721aaf 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c +++ b/xc/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.173 2000/10/24 22:45:07 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.178 2000/11/03 18:46:10 eich Exp $ */ /* * This is a first cut at a non-accelerated version to work with the @@ -173,8 +173,8 @@ static SymTabRec MGAChipsets[] = { { PCI_CHIP_MGA1064, "mga1064sg" }, { PCI_CHIP_MGA2164, "mga2164w" }, { PCI_CHIP_MGA2164_AGP, "mga2164w AGP" }, - { PCI_CHIP_MGAG100_PCI, "mgag100" }, { PCI_CHIP_MGAG100, "mgag100" }, + { PCI_CHIP_MGAG100_PCI, "mgag100 PCI" }, { PCI_CHIP_MGAG200, "mgag200" }, { PCI_CHIP_MGAG200_PCI, "mgag200 PCI" }, { PCI_CHIP_MGAG400, "mgag400" }, @@ -842,7 +842,6 @@ MGASoftReset(ScrnInfoPtr pScrn) { MGAPtr pMga = MGAPTR(pScrn); - ErrorF("SoftReset called!!!\n"); pMga->FbMapSize = 8192 * 1024; MGAMapMem(pScrn); @@ -1138,11 +1137,6 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) MGAEntPtr pMgaEnt = NULL; #ifdef USEMGAHAL MGAMODEINFO mgaModeInfo = {0}; - ULONG ulBOARDHANDLESize; - UCHAR ucMgaBase2; -#if 0 - ULONG ulOrgFBuffer; -#endif Bool digital = FALSE; Bool tv = FALSE; #endif @@ -1907,16 +1901,15 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) clockRanges->minClock = pMga->MinClock; clockRanges->maxClock = pMga->MaxClock; clockRanges->clockIndex = -1; /* programmable */ + clockRanges->interlaceAllowed = TRUE; + clockRanges->doubleScanAllowed = TRUE; #ifdef USEMGAHAL - clockRanges->interlaceAllowed = FALSE; - clockRanges->doubleScanAllowed = FALSE; -#else + MGA_HAL(clockRanges->interlaceAllowed = FALSE); + MGA_HAL(clockRanges->doubleScanAllowed = FALSE); +#endif if (pMga->SecondCrtc == TRUE) clockRanges->interlaceAllowed = FALSE; - else - clockRanges->interlaceAllowed = TRUE; - clockRanges->doubleScanAllowed = TRUE; -#endif + clockRanges->ClockMulFactor = 1; clockRanges->ClockDivFactor = 1; @@ -2010,37 +2003,18 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } #ifdef USEMGAHAL + MGA_HAL( if(pMga->SecondCrtc == FALSE) { - ulBOARDHANDLESize = MGAGetBOARDHANDLESize(); - pMga->pBoard = (LPBOARDHANDLE) xalloc (sizeof(CLIENTDATA) + ulBOARDHANDLESize); + pMga->pBoard = (LPBOARDHANDLE) xalloc (sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); pMga->pClientStruct = (LPCLIENTDATA) xalloc (sizeof(CLIENTDATA)); - /* Fill the client part */ pMga->pClientStruct->pMga = (MGAPtr) pMga; - - /* Determine the Frame buffer limit size */ - if((pMga->Chipset == PCI_CHIP_MGA1064 && pMga->ChipRev < 3) || - (pMga->Chipset == PCI_CHIP_MGA2064)) { - ucMgaBase2 = 0x14; - } else { - ucMgaBase2 = 0x10; - } -#if 0 - /* - * This is bad for cards where there is less physical memory than - * the PCI map size. - */ - ulOrgFBuffer = pciReadLong(pMga->PciTag,ucMgaBase2); - pciWriteLong(pMga->PciTag,ucMgaBase2,0xffffffff); - pMga->FbMapSize = pciReadLong(pMga->PciTag,ucMgaBase2); - pciWriteLong(pMga->PciTag,ucMgaBase2,ulOrgFBuffer); - pMga->FbMapSize = ~(pMga->FbMapSize & 0xfffffff0) + 1; -#endif - /* Open the matrox low level library */ + MGAMapMem(pScrn); MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); MGAUnmapMem(pScrn); pMga->pMgaHwInfo = (LPMGAHWINFO) xalloc (sizeof(MGAHWINFO)); MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); + /* copy the board handles */ if(xf86IsEntityShared(pScrn->entityList[0])) { pMgaEnt->pClientStruct = pMga->pClientStruct; @@ -2048,13 +2022,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) pMgaEnt->pMgaHwInfo = pMga->pMgaHwInfo; } mgaModeInfo.flOutput = MGAMODEINFO_ANALOG1; -#if 1 mgaModeInfo.ulDispWidth = pScrn->virtualX; mgaModeInfo.ulDispHeight = pScrn->virtualY; -#else - mgaModeInfo.ulDispWidth = pScrn->modes->HDisplay; - mgaModeInfo.ulDispHeight = pScrn->modes->VDisplay; -#endif mgaModeInfo.ulDeskWidth = pScrn->virtualX; mgaModeInfo.ulDeskHeight = pScrn->virtualY; mgaModeInfo.ulBpp = pScrn->bitsPerPixel; @@ -2070,13 +2039,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) mgaModeInfo.flOutput = MGAMODEINFO_ANALOG2 | MGAMODEINFO_SECOND_CRTC; } -#if 1 mgaModeInfo.ulDispWidth = pScrn->virtualX; mgaModeInfo.ulDispHeight = pScrn->virtualY; -#else - mgaModeInfo.ulDispWidth = pScrn->modes->HDisplay; - mgaModeInfo.ulDispHeight = pScrn->modes->VDisplay; -#endif mgaModeInfo.ulDeskWidth = pScrn->virtualX; mgaModeInfo.ulDeskHeight = pScrn->virtualY; mgaModeInfo.ulBpp = pScrn->bitsPerPixel; @@ -2090,8 +2054,8 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) "MGAValidateMode from HALlib found the mode to be invalid\n"); return FALSE; } - pScrn->displayWidth = mgaModeInfo.ulFBPitch; + ); /* MGA_HAL */ #endif /* @@ -2103,10 +2067,12 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) * are not pre-initialised at all. */ #ifdef USEMGAHAL - xf86SetCrtcForModes(pScrn, 0); + MGA_HAL(xf86SetCrtcForModes(pScrn, 0)); + MGA_NOT_HAL(xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V)); #else - xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); #endif + /* Set the current mode to the first in the list */ pScrn->currentMode = pScrn->modes; @@ -2269,6 +2235,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24; pMga->CurrentLayout.mode = pScrn->currentMode; #ifdef USEMGAHAL + MGA_HAL( /* Close the library after preinit */ /* This needs to only happen after this board has completed preinit * both times @@ -2302,6 +2269,7 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) if (pMga->pMgaHwInfo) xfree(pMga->pMgaHwInfo); } + ); /* MGA_HAL */ #endif xf86SetPrimInitDone(pScrn->entityList[0]); @@ -2451,12 +2419,9 @@ MGASave(ScrnInfoPtr pScrn) MGAPtr pMga = MGAPTR(pScrn); MGARegPtr mgaReg = &pMga->SavedReg; -#ifdef USEMGAHAL if(pMga->SecondCrtc == TRUE) return; - - if(pMga->pBoard != NULL) { - MGASaveVgaState(pMga->pBoard); - } +#ifdef USEMGAHAL + MGA_HAL(if (pMga->pBoard != NULL) MGASaveVgaState(pMga->pBoard)); #endif /* Only save text mode fonts/text for the primary card */ @@ -2469,8 +2434,8 @@ static void FillModeInfoStruct(ScrnInfoPtr pScrn, DisplayModePtr mode) { const char *s; MGAPtr pMga = MGAPTR(pScrn); + pMga->pMgaModeInfo = (LPMGAMODEINFO) xalloc (sizeof(MGAMODEINFO)); - pMga->pMgaModeInfo->flOutput = 0; pMga->pMgaModeInfo->ulDispWidth = mode->HDisplay; pMga->pMgaModeInfo->ulDispHeight = mode->VDisplay; @@ -2568,6 +2533,7 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) mgaReg = &pMga->ModeReg; #ifdef USEMGAHAL + MGA_HAL( FillModeInfoStruct(pScrn,mode); if(pMga->SecondCrtc == TRUE) { @@ -2604,6 +2570,7 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MGAValidateVideoParameters from HALlib found the mode to be invalid. Error: %lx\n", status); return FALSE; } + ); /* MGA_HAL */ #endif #ifdef XF86DRI @@ -2613,21 +2580,25 @@ MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) #endif #ifdef USEMGAHAL + MGA_HAL( /* Initialize the board */ if(MGASetMode(pMga->pBoard,pMga->pMgaModeInfo) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "MGASetMode returned an error. Make sure to validate the mode before.\n"); return FALSE; } + ); /* MGA_HAL */ #define outMGAdreg(reg, val) OUTREG8(RAMDAC_OFFSET + (reg), val) -#define outMGAdac(reg, val) \ - (outMGAdreg(MGA1064_INDEX, reg), outMGAdreg(MGA1064_DATA, val)) +#define outMGAdac(reg, val) (outMGAdreg(MGA1064_INDEX, reg), outMGAdreg(MGA1064_DATA, val)) + MGA_HAL( if(pMga->SecondCrtc == FALSE && pMga->HWCursor == TRUE) { outMGAdac(MGA1064_CURSOR_BASE_ADR_LOW, pMga->FbCursorOffset >> 10); outMGAdac(MGA1064_CURSOR_BASE_ADR_HI, pMga->FbCursorOffset >> 18); } + ); /* MGA_HAL */ + MGA_NOT_HAL((*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE)); #else (*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE); #endif @@ -2673,10 +2644,12 @@ MGARestore(ScrnInfoPtr pScrn) vgaHWProtect(pScrn, TRUE); if (pMga->Primary) { #ifdef USEMGAHAL + MGA_HAL( if(pMga->pBoard != NULL) { MGASetVgaMode(pMga->pBoard); MGARestoreVgaState(pMga->pBoard); } + ); /* MGA_HAL */ #endif (*pMga->Restore)(pScrn, vgaReg, mgaReg, TRUE); } else { @@ -2699,7 +2672,7 @@ MGACrtc2FillStrip(ScrnInfoPtr pScrn) } else { xf86SetLastScrnFlag(pScrn->entityList[0], pScrn->scrnIndex); pMga->RestoreAccelState(pScrn); - pMga->SetupForSolidFill(pScrn, 0, GXcopy, 0xFFFFFFFF); + pMga->SetupForSolidFill(pScrn, 0, GXcopy, 0x00000000); pMga->SubsequentSolidFillRect(pScrn, pScrn->virtualX, 0, pScrn->displayWidth - pScrn->virtualX, pScrn->virtualY); @@ -2751,13 +2724,12 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pMgaEnt = pPriv->ptr; pMgaEnt->refCount++; #ifdef USEMGAHAL + MGA_HAL( if(pMgaEnt->refCount == 1) { - pMga->pBoard = - (LPBOARDHANDLE) xalloc (sizeof(CLIENTDATA) + - MGAGetBOARDHANDLESize()); + pMga->pBoard = (LPBOARDHANDLE) xalloc (sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); pMga->pClientStruct = (LPCLIENTDATA) xalloc (sizeof(CLIENTDATA)); - /* Fill the client part */ pMga->pClientStruct->pMga = (MGAPtr) pMga; + MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); pMga->pMgaHwInfo = (LPMGAHWINFO) xalloc (sizeof(MGAHWINFO)); MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); @@ -2779,18 +2751,19 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pMga->pBoard = pMgaEnt->pBoard; pMga->pMgaHwInfo = pMgaEnt->pMgaHwInfo; } + ); /* MGA_HAL */ #endif } else { #ifdef USEMGAHAL - pMga->pBoard = - (LPBOARDHANDLE) xalloc (sizeof(CLIENTDATA) + - MGAGetBOARDHANDLESize()); + MGA_HAL( + pMga->pBoard = (LPBOARDHANDLE) xalloc (sizeof(CLIENTDATA) + MGAGetBOARDHANDLESize()); pMga->pClientStruct = (LPCLIENTDATA) xalloc (sizeof(CLIENTDATA)); - /* Fill the client part */ pMga->pClientStruct->pMga = (MGAPtr) pMga; + MGAOpenLibrary(pMga->pBoard,pMga->pClientStruct,sizeof(CLIENTDATA)); pMga->pMgaHwInfo = (LPMGAHWINFO) xalloc (sizeof(MGAHWINFO)); MGAGetHardwareInfo(pMga->pBoard,pMga->pMgaHwInfo); + ); /* MGA_HAL */ #endif } @@ -3046,8 +3019,8 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScreen->SaveScreen = MGASaveScreenCrtc2; } else { pScreen->SaveScreen = MGASaveScreen; - MGAInitVideo(pScreen); } + MGAInitVideo(pScreen); /* Wrap the current CloseScreen function */ pMga->CloseScreen = pScreen->CloseScreen; @@ -3283,6 +3256,7 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen) } #ifdef USEMGAHAL + MGA_HAL( if(xf86IsEntityShared(pScrn->entityList[0])) { if(pMgaEnt->refCount == 0) { /* Both boards have closed there screen */ @@ -3309,6 +3283,7 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen) if (pMga->pMgaHwInfo) xfree(pMga->pMgaHwInfo); } + ); /* MGA_HAL */ #endif if (pMga->AccelInfoRec) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h index c2a47eaf1..4aa48527b 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h,v 1.16 2000/10/24 22:45:07 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h,v 1.17 2000/11/02 02:51:20 dawes Exp $ */ #ifndef _MGA_MACROS_H_ #define _MGA_MACROS_H_ @@ -17,7 +17,7 @@ #define REPLICATE(r) /* */ #endif -#define RGBEQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff)) +#define RGBEQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff)) #ifdef XF86DRI #define MGA_SYNC_XTAG 0x275f4200 @@ -49,8 +49,7 @@ while(INREG(MGAREG_DWGSYNC) != MGA_SYNC_XTAG) ; \ ( MAKEDMAINDEX(one) | \ (MAKEDMAINDEX(two) << 8) | \ (MAKEDMAINDEX(three) << 16) | \ - (MAKEDMAINDEX(four) << 24) ) - + (MAKEDMAINDEX(four) << 24) ) #if PSZ == 24 #define SET_PLANEMASK(p) /**/ @@ -63,7 +62,6 @@ while(INREG(MGAREG_DWGSYNC) != MGA_SYNC_XTAG) ; \ } #endif - #define SET_FOREGROUND(c) \ if((c) != pMga->FgColor) { \ pMga->FgColor = (c); \ @@ -93,5 +91,20 @@ while(INREG(MGAREG_DWGSYNC) != MGA_SYNC_XTAG) ; \ #define CHECK_DMA_QUIESCENT(pMGA, pScrn) #endif +#ifdef USEMGAHAL +#define HAL_CHIPSETS ((pMga->Chipset == PCI_CHIP_MGAG200_PCI) || \ + (pMga->Chipset == PCI_CHIP_MGAG200) || \ + (pMga->Chipset == PCI_CHIP_MGAG400)) +#define MGA_HAL(x) { \ + MGAPtr pMga = MGAPTR(pScrn); \ + if (HAL_CHIPSETS) { x; } \ +} +#define MGA_NOT_HAL(x) { \ + MGAPtr pMga = MGAPTR(pScrn); \ + if (!HAL_CHIPSETS) { x; } \ +} +#else +#define MGA_NOT_HAL(x) { x; } +#endif #endif /* _MGA_MACROS_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h index 12538fd3c..247acbdff 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h @@ -2,7 +2,7 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h,v 1.12 2000/06/09 22:43:38 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h,v 1.13 2000/11/01 21:55:09 mvojkovi Exp $ */ @@ -425,8 +425,10 @@ #define MGAREG_TEXTRANS 0x2c34 #define MGAREG_TEXTRANSHIGH 0x2c38 #define MGAREG_TEXFILTER 0x2c58 +#define MGAREG_ALPHASTART 0x2c70 +#define MGAREG_ALPHAXINC 0x2c74 +#define MGAREG_ALPHAYINC 0x2c78 #define MGAREG_ALPHACTRL 0x2c7c - #define MGAREG_DWGSYNC 0x2c4c diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c index d8dbe698e..2ffcc8788 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.78 2000/10/27 18:31:04 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.80 2000/11/03 18:46:11 eich Exp $ */ /* All drivers should typically include these */ @@ -153,6 +153,23 @@ MGASetupForCPUToScreenAlphaTexture ( ); extern Bool +MGASetupForCPUToScreenAlphaTextureFaked ( + ScrnInfoPtr pScrn, + int op, + CARD16 red, + CARD16 green, + CARD16 blue, + CARD16 alpha, + int alphaType, + CARD8 *alphaPtr, + int alphaPitch, + int width, + int height, + int flags +); + + +extern Bool MGASetupForCPUToScreenTexture ( ScrnInfoPtr pScrn, int op, @@ -259,7 +276,7 @@ GetPowerOfTwo(int w) static int tex_padw, tex_padh; Bool -MGASetupForCPUToScreenAlphaTexture ( +MGASetupForCPUToScreenAlphaTextureFaked ( ScrnInfoPtr pScrn, int op, CARD16 red, @@ -339,6 +356,106 @@ MGASetupForCPUToScreenAlphaTexture ( } Bool +MGASetupForCPUToScreenAlphaTexture ( + ScrnInfoPtr pScrn, + int op, + CARD16 red, + CARD16 green, + CARD16 blue, + CARD16 alpha, + int alphaType, + CARD8 *alphaPtr, + int alphaPitch, + int width, + int height, + int flags +){ + int log2w, log2h, i, pitch, sizeNeeded, offset; + CARD8 *dst; + MGAPtr pMga = MGAPTR(pScrn); + + if(op != PictOpOver) /* only one tested */ + return FALSE; + + if((width > 2048) || (height > 2048)) + return FALSE; + + log2w = GetPowerOfTwo(width); + log2h = GetPowerOfTwo(height); + + CHECK_DMA_QUIESCENT(pMga, pScrn); + + if(pMga->Overlay8Plus24) { + i = 0x00ffffff; + WAITFIFO(1); + SET_PLANEMASK(i); + } + + pitch = (width + 15) & ~15; + sizeNeeded = (pitch * height) >> 1; + if(pScrn->bitsPerPixel == 32) + sizeNeeded >>= 1; + + if(!AllocateLinear(pScrn, sizeNeeded)) + return FALSE; + + offset = pMga->LinearScratch->offset << 1; + if(pScrn->bitsPerPixel == 32) + offset <<= 1; + + if(pMga->AccelInfoRec->NeedToSync) + MGAStormSync(pScrn); + + i = height; + dst = pMga->FbStart + offset; + while(i--) { + memcpy(dst, alphaPtr, width); + dst += pitch; + alphaPtr += alphaPitch; + } + + tex_padw = 1 << log2w; + tex_padh = 1 << log2h; + + + WAITFIFO(12); + OUTREG(MGAREG_DR4, red << 7); /* red start */ + OUTREG(MGAREG_DR6, 0); + OUTREG(MGAREG_DR7, 0); + OUTREG(MGAREG_DR8, green << 7); /* green start */ + OUTREG(MGAREG_DR10, 0); + OUTREG(MGAREG_DR11, 0); + OUTREG(MGAREG_DR12, blue << 7); /* blue start */ + OUTREG(MGAREG_DR14, 0); + OUTREG(MGAREG_DR15, 0); + OUTREG(MGAREG_ALPHASTART, alpha << 7); /* alpha start */ + OUTREG(MGAREG_ALPHAXINC, 0); + OUTREG(MGAREG_ALPHAYINC, 0); + + WAITFIFO(15); + OUTREG(MGAREG_TMR0, (1 << 20) / tex_padw); /* sx inc */ + OUTREG(MGAREG_TMR1, 0); /* sy inc */ + OUTREG(MGAREG_TMR2, 0); /* tx inc */ + OUTREG(MGAREG_TMR3, (1 << 20) / tex_padh); /* ty inc */ + OUTREG(MGAREG_TMR4, 0x00000000); + OUTREG(MGAREG_TMR5, 0x00000000); + OUTREG(MGAREG_TMR8, 0x00010000); + OUTREG(MGAREG_TEXORG, offset); + OUTREG(MGAREG_TEXWIDTH, log2w | (((8 - log2w) & 63) << 9) | + ((width - 1) << 18)); + OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) | + ((height - 1) << 18)); + OUTREG(MGAREG_TEXCTL, 0x3A000107 | ((pitch & 0x07FF) << 9)); + OUTREG(MGAREG_TEXCTL2, 0x00000014); + OUTREG(MGAREG_DWGCTL, 0x000c7076); + OUTREG(MGAREG_TEXFILTER, 0x01e00020); + OUTREG(MGAREG_ALPHACTRL, 0x02000151); + + return TRUE; +} + + +Bool MGASetupForCPUToScreenTexture ( ScrnInfoPtr pScrn, int op, @@ -731,12 +848,18 @@ MGANAME(AccelInit)(ScreenPtr pScreen) #ifdef RENDER if(doRender && ((pScrn->bitsPerPixel == 32) || (pScrn->bitsPerPixel == 16))) { - infoPtr->SetupForCPUToScreenAlphaTexture = + if(pMga->Chipset == PCI_CHIP_MGAG400) { + infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE; + infoPtr->SetupForCPUToScreenAlphaTexture = MGASetupForCPUToScreenAlphaTexture; + } else { + infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE | + XAA_RENDER_NO_SRC_ALPHA; + infoPtr->SetupForCPUToScreenAlphaTexture = + MGASetupForCPUToScreenAlphaTextureFaked; + } infoPtr->SubsequentCPUToScreenAlphaTexture = MGASubsequentCPUToScreenTexture; - infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE | - XAA_RENDER_NO_SRC_ALPHA; infoPtr->CPUToScreenAlphaTextureFormats = MGAAlphaTextureFormats; infoPtr->SetupForCPUToScreenTexture = MGASetupForCPUToScreenTexture; @@ -903,8 +1026,8 @@ MGAStormEngineInit(ScrnInfoPtr pScrn) OUTREG(MGAREG_MACCESS, maccess); pMga->MAccess = maccess; pMga->PlaneMask = ~0; - if((pMga->Chipset != PCI_CHIP_MGAG100) - && (pMga->Chipset != PCI_CHIP_MGAG100_PCI)) + /* looks like this doesn't apply to mga g100 pci */ + if (pMga->Chipset != PCI_CHIP_MGAG100) OUTREG(MGAREG_PLNWT, pMga->PlaneMask); pMga->FgColor = 0; OUTREG(MGAREG_FCOL, pMga->FgColor); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c index 59a4da867..c6b5a59c4 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c,v 1.18 2000/10/24 22:45:07 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_video.c,v 1.19 2000/11/02 19:10:53 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -74,11 +74,11 @@ void MGAInitVideo(ScreenPtr pScreen) int num_adaptors; if((pScrn->bitsPerPixel != 8) && !pMga->NoAccel && + (pMga->SecondCrtc == FALSE) && ((pMga->Chipset == PCI_CHIP_MGAG200) || (pMga->Chipset == PCI_CHIP_MGAG200_PCI) || (pMga->Chipset == PCI_CHIP_MGAG400))) { - if((pMga->Overlay8Plus24 || pMga->TexturedVideo) && (pScrn->bitsPerPixel != 24)) { @@ -90,11 +90,9 @@ void MGAInitVideo(ScreenPtr pScreen) newAdaptor = MGASetupImageVideoOverlay(pScreen); pMga->TexturedVideo = FALSE; } - if(!pMga->Overlay8Plus24) MGAInitOffscreenImages(pScreen); } - num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c index 066d20991..5eb25defd 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c,v 1.4 2000/09/26 15:57:12 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_warp.c,v 1.5 2000/11/02 19:10:53 dawes Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -19,11 +19,10 @@ Bool mgaConfigureWarp(ScrnInfoPtr pScrn) { MGAPtr pMga = MGAPTR(pScrn); int wmisc; - - CHECK_DMA_QUIESCENT( pMga, pScrn ); + CHECK_DMA_QUIESCENT(pMga, pScrn); WAITFIFO(3); - + switch(pMga->Chipset) { case PCI_CHIP_MGAG400: OUTREG(MGAREG_WIADDR2, WIA_wmode_suspend); @@ -31,41 +30,34 @@ Bool mgaConfigureWarp(ScrnInfoPtr pScrn) OUTREG(MGAREG_WVRTXSZ, 0x00001807); OUTREG(MGAREG_WACCEPTSEQ, 0x18000000); break; - case PCI_CHIP_MGAG200: -#if 0 case PCI_CHIP_MGAG200_PCI: -#endif OUTREG(MGAREG_WIADDR, WIA_wmode_suspend); OUTREG(MGAREG_WGETMSB, 0x1606); - OUTREG(MGAREG_WVRTXSZ, 7); /* may be set on something else later on*/ + OUTREG(MGAREG_WVRTXSZ, 7); /* may be set on something else later on */ break; - default: - ErrorF("Only Matrox G200 and G400 work correctly under the DRI\n"); return FALSE; } - + WAITFIFO(1); - OUTREG(MGAREG_WMISC, WM_wucodecache_enable | - WM_wmaster_enable | + OUTREG(MGAREG_WMISC, WM_wucodecache_enable | + WM_wmaster_enable | WM_wcacheflush_enable); wmisc = INREG(MGAREG_WMISC); - if(wmisc != (WM_wucodecache_enable | WM_wmaster_enable)) { + if (wmisc != (WM_wucodecache_enable | WM_wmaster_enable)) { FatalError("[mga] WARP engine wrongly configured (%d != %d)." - " Switch off your PC and try again.\n", wmisc, + " Switch off your PC and try again.\n", wmisc, WM_wmaster_enable | WM_wucodecache_enable); } - - return TRUE; + return TRUE; } static unsigned int mgaG400GetMicrocodeSize(MGAPtr pMGA) { #define CODESIZE(which) ((sizeof(which)/256 + 1)*256) - unsigned int microcode_size = 0; - + microcode_size = CODESIZE(WARP_G400_t2gz) + CODESIZE(WARP_G400_t2gza) + CODESIZE(WARP_G400_t2gzaf) + CODESIZE(WARP_G400_t2gzf) + CODESIZE(WARP_G400_t2gzs) + CODESIZE(WARP_G400_t2gzsa) + @@ -76,25 +68,24 @@ static unsigned int mgaG400GetMicrocodeSize(MGAPtr pMGA) CODESIZE(WARP_G400_tgzsaf) + CODESIZE(WARP_G400_tgzsf); microcode_size = ((microcode_size + 4096 - 1) / 4096) * 4096; return(microcode_size); - #undef CODESIZE } static unsigned int mgaG200GetMicrocodeSize(MGAPtr pMGA) { #define CODESIZE(which) ((sizeof(which)/256 + 1)*256) - unsigned int microcode_size; - + microcode_size = CODESIZE(WARP_G200_tgz) + CODESIZE(WARP_G200_tgza) + CODESIZE(WARP_G200_tgzaf) + CODESIZE(WARP_G200_tgzf) + CODESIZE(WARP_G200_tgzs) + CODESIZE(WARP_G200_tgzsa) + CODESIZE(WARP_G200_tgzsaf) + CODESIZE(WARP_G200_tgzsf); microcode_size = ((microcode_size + 4096 - 1) / 4096) * 4096; - return(microcode_size); + return(microcode_size); #undef CODESIZE } + static unsigned int mgaG400InstallMicrocode(MGAPtr pMGA, int agp_offset) { #define mgaWarpInstallCode(which, where) {\ @@ -105,16 +96,15 @@ static unsigned int mgaG400InstallMicrocode(MGAPtr pMGA, int agp_offset) pcbase += (sizeof(WARP_G400_ ## which) / 256 + 1) * 256; \ vcbase += (sizeof(WARP_G400_ ## which) / 256 + 1) * 256; \ } - MGADRIServerPrivatePtr pMGADRIServer = pMGA->DRIServerInfo; CARD8 *vcbase = pMGADRIServer->agp_map + agp_offset; - unsigned long pcbase = (unsigned long)pMGADRIServer->agpBase + agp_offset; + unsigned long pcbase = (unsigned long)pMGADRIServer->agpBase + agp_offset; unsigned int microcode_size = 0; - memset(pMGADRIServer->WarpIndex, 0, + memset(pMGADRIServer->WarpIndex, 0, sizeof(drmMgaWarpIndex) * MGA_MAX_WARP_PIPES); - microcode_size = mgaG400GetMicrocodeSize(pMGA); + microcode_size = mgaG400GetMicrocodeSize(pMGA); mgaWarpInstallCode(tgz, MGA_WARP_TGZ); mgaWarpInstallCode(tgzf, MGA_WARP_TGZF); mgaWarpInstallCode(tgza, MGA_WARP_TGZA); @@ -131,9 +121,7 @@ static unsigned int mgaG400InstallMicrocode(MGAPtr pMGA, int agp_offset) mgaWarpInstallCode(t2gzsf, MGA_WARP_T2GZSF); mgaWarpInstallCode(t2gzsa, MGA_WARP_T2GZSA); mgaWarpInstallCode(t2gzsaf, MGA_WARP_T2GZSAF); - #undef mgaWarpInstallCode - return microcode_size; } @@ -147,16 +135,15 @@ static unsigned int mgaG200InstallMicrocode(MGAPtr pMGA, int agp_offset) pcbase += (sizeof(WARP_G200_ ## which) / 256 + 1) * 256; \ vcbase += (sizeof(WARP_G200_ ## which) / 256 + 1) * 256; \ } - MGADRIServerPrivatePtr pMGADRIServer = pMGA->DRIServerInfo; CARD8 *vcbase = pMGADRIServer->agp_map + agp_offset; - unsigned long pcbase = (unsigned long)pMGADRIServer->agpBase + agp_offset; + unsigned long pcbase = (unsigned long)pMGADRIServer->agpBase + agp_offset; unsigned int microcode_size = 0; - memset(pMGADRIServer->WarpIndex, 0, + memset(pMGADRIServer->WarpIndex, 0, sizeof(drmMgaWarpIndex) * MGA_MAX_WARP_PIPES); - microcode_size = mgaG400GetMicrocodeSize(pMGA); + microcode_size = mgaG400GetMicrocodeSize(pMGA); mgaWarpInstallCode(tgz, MGA_WARP_TGZ); mgaWarpInstallCode(tgza, MGA_WARP_TGZA); mgaWarpInstallCode(tgzaf, MGA_WARP_TGZAF); @@ -165,9 +152,7 @@ static unsigned int mgaG200InstallMicrocode(MGAPtr pMGA, int agp_offset) mgaWarpInstallCode(tgzsa, MGA_WARP_TGZSA); mgaWarpInstallCode(tgzsaf, MGA_WARP_TGZSAF); mgaWarpInstallCode(tgzsf, MGA_WARP_TGZSF); - #undef mgaWarpInstallCode - return microcode_size; } @@ -176,25 +161,18 @@ unsigned int mgaGetMicrocodeSize(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; MGAPtr pMGA = MGAPTR(pScrn); int retval; - + switch(pMGA->Chipset) { case PCI_CHIP_MGAG400: retval = mgaG400GetMicrocodeSize(pMGA); break; case PCI_CHIP_MGAG200: - retval = mgaG200GetMicrocodeSize(pMGA); - break; -#if 0 case PCI_CHIP_MGAG200_PCI: retval = mgaG200GetMicrocodeSize(pMGA); break; -#endif - default: - ErrorF("Only Matrox G200 and G400 work correctly under the DRI\n"); retval = 0; } - return(retval); } @@ -203,26 +181,20 @@ unsigned int mgaInstallMicrocode(ScreenPtr pScreen, int agp_offset) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; MGAPtr pMGA = MGAPTR(pScrn); int retval; - + switch(pMGA->Chipset) { case PCI_CHIP_MGAG400: retval = mgaG400InstallMicrocode(pMGA, agp_offset); break; case PCI_CHIP_MGAG200: - retval = mgaG200InstallMicrocode(pMGA, agp_offset); - break; -#if 0 case PCI_CHIP_MGAG200_PCI: - retval = mgaG200InstallMicrocode(pMGA); + retval = mgaG200InstallMicrocode(pMGA, agp_offset); break; -#endif - default: - ErrorF("Only Matrox G200 and G400 work correctly under the DRI\n"); retval = 0; } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "WARP Microcode Loaded\n"); - + + if (retval) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "WARP Microcode Loaded\n"); return retval; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile index dd81f50f7..ff5d1f682 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile,v 1.9 2000/09/25 23:57:08 mvojkovi Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile,v 1.10 2000/11/03 18:46:11 eich Exp $ #define IHaveModules #include <Server.tmpl> @@ -17,6 +17,7 @@ INCLUDES = -I. -I../../include INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ -I$(XF86SRC)/vgafb -I$(XF86SRC)/vgahw -I$(SERVERSRC)/include \ -I$(SERVERSRC)/mi -I$(SERVERSRC)/fb -I$(SERVERSRC)/mfb \ + -I$(SERVERSRC)/miext/shadow \ -I$(XINCLUDESRC) -I$(XF86SRC)/xaa -I$(FONTINCSRC) \ -I$(XF86SRC)/ramdac -I$(XF86SRC)/rac -I$(XF86SRC)/ddc \ -I$(XF86SRC)/i2c -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xf24_32bpp \ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h index 477fbe95e..55b9cffd8 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h,v 1.16 2000/09/26 15:57:13 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h,v 1.17 2000/11/03 18:46:11 eich Exp $ */ /* * The original Precision Insight driver for @@ -48,6 +48,8 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "xaalocal.h" /* XAA internals as we replace some of XAA */ #include "xf86Cursor.h" +#include "shadowfb.h" + #include "vbe.h" /* Drivers that need to access the PCI config space directly need this */ @@ -105,6 +107,7 @@ int NEOSetRead(ScreenPtr pScreen, int bank); extern Bool neo_I2CInit(ScrnInfoPtr pScrn); /* in neo_shadow.c */ +void neoShadowUpdate (ScreenPtr pScreen, PixmapPtr pShadow, RegionPtr damage); void neoPointerMoved(int index, int x, int y); void neoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); void neoRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); @@ -239,6 +242,7 @@ typedef struct neoRec vbeInfoPtr pVbe; unsigned char * ShadowPtr; int ShadowPitch; + RefreshAreaFuncPtr refreshArea; void (*PointerMoved)(int index, int x, int y); int rotate; } NEORec, *NEOPtr; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c index 7bc864526..3cb0704d5 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c,v 1.6 2000/09/25 23:57:09 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c,v 1.7 2000/11/03 18:46:11 eich Exp $ */ /* * The original Precision Insight driver for @@ -200,52 +200,27 @@ _neoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src, int xoff, int yoff) unsigned char *_dest, *_src; int _width, _fill; - if (!nPtr->noLinear) { - for (i = 0; i< nPtr->CursorInfo->MaxHeight - yoff; i++) { - _dest = ((unsigned char *)nPtr->NeoFbBase - + nAcl->CursorAddress - + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); - _width = (nPtr->CursorInfo->MaxWidth - - (xoff & 0x38)) >> 3; - _src = (src + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); - _fill = (xoff & 0x38) >> 3; - - memcpy(_dest,_src,_width); - memset(_dest + _width, 0, _fill); - - _dest += (nPtr->CursorInfo->MaxWidth >> 3); - _src += (nPtr->CursorInfo->MaxWidth >> 3); - memcpy(_dest,_src,_width); - memset(_dest + _width, 0, _fill); - } - memset(nPtr->NeoFbBase + nAcl->CursorAddress - + ((nPtr->CursorInfo->MaxWidth >> 2) * i), - 0, (nPtr->CursorInfo->MaxHeight - i) - * (nPtr->CursorInfo->MaxWidth >> 2)); - } else { - /* - * The cursor can only be in the last 16K of video memory, - * which fits in the last banking window. - */ - for (i = 0; i<nPtr->CursorInfo->MaxHeight; i++) { - _dest = ((unsigned char *)nPtr->NeoFbBase - + (nAcl->CursorAddress & 0xFFFF) - + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); - _width = (nPtr->CursorInfo->MaxWidth - - ((xoff & 0x38) >> 3)); - _src = (src + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); - _fill = (xoff & 0x38) >> 3; - - NEOSetWrite(pScrn->pScreen, (int)(nAcl->CursorAddress >> 16)); - memcpy(_dest,_src,_width); - memset(_dest + _width, 0, _fill); - - _dest += (nPtr->CursorInfo->MaxWidth >> 3); - _src += (nPtr->CursorInfo->MaxWidth >> 3); - memcpy(_dest,_src,_width); - memset(_dest + _width, 0, _fill); - } + for (i = 0; i< nPtr->CursorInfo->MaxHeight - yoff; i++) { + _dest = ((unsigned char *)nPtr->NeoFbBase + + nAcl->CursorAddress + + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); + _width = (nPtr->CursorInfo->MaxWidth + - (xoff & 0x38)) >> 3; + _src = (src + ((nPtr->CursorInfo->MaxWidth >> 2) * i)); + _fill = (xoff & 0x38) >> 3; + + memcpy(_dest,_src,_width); + memset(_dest + _width, 0, _fill); + + _dest += (nPtr->CursorInfo->MaxWidth >> 3); + _src += (nPtr->CursorInfo->MaxWidth >> 3); + memcpy(_dest,_src,_width); + memset(_dest + _width, 0, _fill); } + memset(nPtr->NeoFbBase + nAcl->CursorAddress + + ((nPtr->CursorInfo->MaxWidth >> 2) * i), + 0, (nPtr->CursorInfo->MaxHeight - i) + * (nPtr->CursorInfo->MaxWidth >> 2)); /* set cursor address here or we loose the cursor on video mode change */ /* Load storage location. */ OUTREG(NEOREG_CURSMEMPOS, ((0x000f & (nAcl->CursorAddress >> 10)) << 8) | @@ -270,11 +245,7 @@ neoUseHWCursor(ScreenPtr pScr, CursorPtr pCurs) NEOACLPtr nAcl = NEOACLPTR(xf86Screens[pScr->myNum]); NEOPtr nPtr = NEOPTR(xf86Screens[pScr->myNum]); - if(!nPtr->noLinear) { - return(nAcl->UseHWCursor && !nAcl->NoCursorMode); - } - - return (FALSE); + return(nAcl->UseHWCursor && !nAcl->NoCursorMode); } static unsigned char* @@ -323,7 +294,6 @@ NeoCursorInit(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; NEOPtr nPtr = NEOPTR(pScrn); xf86CursorInfoPtr infoPtr; - infoPtr = xf86CreateCursorInfoRec(); if(!infoPtr) return FALSE; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c index 519aeea03..3b93b220c 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c,v 1.38 2000/10/24 22:45:08 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c,v 1.39 2000/11/03 18:46:11 eich Exp $ */ /* * The original Precision Insight driver for @@ -78,7 +78,7 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "xf86RAC.h" /* Needed by the Shadow Framebuffer */ -#include "shadowfb.h" +#include "shadow.h" /* int10 */ #include "xf86int10.h" @@ -87,6 +87,10 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* Needed for Device Data Channel (DDC) support */ #include "xf86DDC.h" +#ifdef RENDER +#include "picturestr.h" +#endif + /* * Driver data structures. */ @@ -131,7 +135,11 @@ static Bool neoUnmapMem(ScrnInfoPtr pScrn); static void neoProgramShadowRegs(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore); static void neoCalcVCLK(ScrnInfoPtr pScrn, long freq); -static void neo_ddc1(int scrnIndex); +static xf86MonPtr neo_ddc1(int scrnIndex); +static Bool neoDoDDC1(ScrnInfoPtr pScrn); +static Bool neoDoDDC2(ScrnInfoPtr pScrn); +static Bool neoDoDDCVBE(ScrnInfoPtr pScrn); +static void neoProbeDDC(ScrnInfoPtr pScrn, int index); static void NeoDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); static int neoFindMode(int xres, int yres, int depth); @@ -342,7 +350,10 @@ static const char *ramdacSymbols[] = { }; static const char *shadowSymbols[] = { + "shadowInit", +#if 0 "ShadowFBInit", +#endif NULL }; @@ -453,7 +464,6 @@ static OptionInfoPtr NEOAvailableOptions(int chipid, int busid) { - int vendor = ((chipid & 0xffff0000) >> 16); int chip = (chipid & 0x0000ffff); if (chip == PCI_CHIP_NM2070) @@ -607,9 +617,11 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) int w; int apertureSize; char *s; - Bool ddc_done = FALSE; - if (flags & PROBE_DETECT) return FALSE; + if (flags & PROBE_DETECT) { + neoProbeDDC( pScrn, xf86GetEntityInfo(pScrn->entityList[0])->index ); + return TRUE; + } /* The vgahw module should be loaded here when needed */ if (!xf86LoadSubModule(pScrn, "vgahw")) @@ -623,7 +635,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) if (!vgaHWGetHWRec(pScrn)) return FALSE; hwp = VGAHWPTR(pScrn); - + /* Allocate the NeoRec driverPrivate */ if (!NEOGetRec(pScrn)) { return FALSE; @@ -689,14 +701,10 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) } xf86ErrorF("\n"); - if (xf86LoadSubModule(pScrn, "vbe")) { - nPtr->pVbe = VBEInit(NULL,nPtr->pEnt->index); - } - vgaHWGetIOBase(hwp); nPtr->vgaIOBase = hwp->IOBase; vgaHWSetStdFuncs(hwp); - + /* Determine the panel type */ VGAwGR(0x09,0x26); type = VGArGR(0x21); @@ -767,7 +775,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) break; case NM2097: bppSupport = Support24bppFb | Support32bppFb | - SupportConvert32to24 | PreferConvert32to24; + SupportConvert32to24 | PreferConvert32to24; videoRam = 1152; maxClock = 80000; CursorMem = 1024; @@ -835,35 +843,15 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) pScrn->monitor = pScrn->confScreen->monitor; - if (!xf86LoadSubModule(pScrn, "ddc")) - return FALSE; - xf86LoaderReqSymLists(ddcSymbols, NULL); -#if 0 - VGAwGR(0x09,0x26); - neo_ddc1(pScrn->scrnIndex); - VGAwGR(0x09,0x00); + if (xf86LoadSubModule(pScrn, "ddc")) { + xf86LoaderReqSymLists(ddcSymbols, NULL); +#if 1 + if (!neoDoDDCVBE(pScrn)) + if (!neoDoDDC2(pScrn)) + neoDoDDC1(pScrn); #endif - if (!xf86LoadSubModule(pScrn, "i2c")) - return FALSE; - xf86LoaderReqSymLists(i2cSymbols, NULL); - if (!neo_I2CInit(pScrn)) - return FALSE; - - VGAwGR(0x09,0x26); - - if (nPtr->pVbe) { - xf86MonPtr pMon; - if ((pMon = xf86PrintEDID(vbeDoEDID(nPtr->pVbe,NULL))) != NULL) - ddc_done = TRUE; - xf86SetDDCproperties(pScrn,pMon); } - if (ddc_done) - xf86SetDDCproperties( - pScrn,xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,nPtr->I2C))); - - VGAwGR(0x09,0x00); - if (!xf86SetDepthBpp(pScrn, 8, 8, 8, bppSupport )) return FALSE; else { @@ -1040,7 +1028,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) nPtr->NeoLinearAddr = 0; } - if (nPtr->pEnt->device->IOBase) { + if (nPtr->pEnt->device->IOBase && !nPtr->noMMIO) { /* XXX Check this matches a PCI base address */ nPtr->NeoMMIOAddr = nPtr->pEnt->device->IOBase; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, @@ -1199,6 +1187,9 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) } xf86LoaderReqSymbols("fbScreenInit", NULL); +#ifdef RENDER + xf86LoaderReqSymbols("fbPictureInit", NULL); +#endif if (!nPtr->noLinear) { if (!xf86LoadSubModule(pScrn, "xaa")) @@ -1207,7 +1198,7 @@ NEOPreInit(ScrnInfoPtr pScrn, int flags) } if (nPtr->shadowFB) { - if (!xf86LoadSubModule(pScrn, "shadowfb")) { + if (!xf86LoadSubModule(pScrn, "shadow")) { RETURN; } xf86LoaderReqSymLists(shadowSymbols, NULL); @@ -1281,9 +1272,13 @@ NEOLoadPalette( for(i = 0; i < numColors; i++) { index = indices[i]; hwp->writeDacWriteAddr(hwp, index); + DACDelay(hwp); hwp->writeDacData(hwp, colors[index].red << shift); + DACDelay(hwp); hwp->writeDacData(hwp, colors[index].green << Gshift); + DACDelay(hwp); hwp->writeDacData(hwp, colors[index].blue << shift); + DACDelay(hwp); } } @@ -1329,18 +1324,6 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; vgaHWSaveScreen(pScreen,SCREEN_SAVER_ON); NEOAdjustFrame(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. @@ -1354,14 +1337,7 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->rgbBits, pScrn->defaultVisual)) return FALSE; - /* - * Temporarily set the global defaultColorVisualClass to make - * cfbInitVisuals do what we want. - */ -#if 0 - savedDefaultVisualClass = xf86GetDefaultColorVisualClass(); - xf86SetDefaultColorVisualClass(pScrn->defaultVisual); -#endif + miSetPixmapDepths (); /* * Call the framebuffer layer's ScreenInit function, and fill in other @@ -1390,7 +1366,10 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) width, height, pScrn->xDpi, pScrn->yDpi, displayWidth, pScrn->bitsPerPixel); - +#ifdef RENDER + if (ret) + fbPictureInit (pScreen, 0, 0); +#endif if (!ret) return FALSE; @@ -1417,6 +1396,7 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) nPtr->NeoHWCursorShown = FALSE; nPtr->NeoHWCursorInitialized = FALSE; nAcl->UseHWCursor = FALSE; + nAcl->CursorAddress = -1; if (nPtr->noLinear) { miBankInfoPtr pBankInfo; @@ -1427,7 +1407,7 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; pBankInfo->pBankA = hwp->Base; - pBankInfo->pBankB = (unsigned char *)hwp->Base + 0x10000; + pBankInfo->pBankB = (unsigned char *)hwp->Base; pBankInfo->BankSize = 0x10000; pBankInfo->nBankDepth = pScrn->depth; @@ -1443,8 +1423,8 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Using nonlinear mode\n"); - xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Using software cursor\n"); - + xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Using software cursor in " + "nonlinear mode\n"); miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); @@ -1453,7 +1433,6 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); } else { - nAcl->CursorAddress = -1; nAcl->cacheStart = -1; nAcl->cacheEnd = -1; xf86DrvMsg(pScrn->scrnIndex,X_INFO, @@ -1482,8 +1461,11 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } else xf86DrvMsg(scrnIndex, X_ERROR, "Too little space for H/W cursor.\n"); + xf86DrvMsg(pScrn->scrnIndex,X_INFO, + "Acceleration disabled when not using MMIO\n"); + /* Setup the acceleration primitives */ - if (!nPtr->noAccel) { + if (!nPtr->noAccel || nPtr->noMMIO) { nAcl->cacheStart = currentaddr - freespace; nAcl->cacheEnd = currentaddr; freespace = 0; @@ -1512,7 +1494,8 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Acceleration Initialized\n"); } - + if (!nPtr->noAccel && nPtr->noMMIO) + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); @@ -1520,21 +1503,22 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Initialise cursor functions */ miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); - if (nAcl->CursorAddress != -1) { - /* HW cursor functions */ - if (!NeoCursorInit(pScreen)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Hardware cursor initialization failed\n"); - return FALSE; - } - nAcl->UseHWCursor = TRUE; - nPtr->NeoHWCursorInitialized = TRUE; - } else - nAcl->UseHWCursor = FALSE; } + if (nAcl->CursorAddress != -1) { + /* HW cursor functions */ + if (!NeoCursorInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + return FALSE; + } + nAcl->UseHWCursor = TRUE; + nPtr->NeoHWCursorInitialized = TRUE; + } else + nAcl->UseHWCursor = FALSE; + if (nPtr->shadowFB) { - RefreshAreaFuncPtr refreshArea = neoRefreshArea; + nPtr->refreshArea = neoRefreshArea; if(nPtr->rotate) { if (!nPtr->PointerMoved) { @@ -1543,14 +1527,17 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } switch(pScrn->bitsPerPixel) { - case 8: refreshArea = neoRefreshArea8; break; - case 16: refreshArea = neoRefreshArea16; break; - case 24: refreshArea = neoRefreshArea24; break; - case 32: refreshArea = neoRefreshArea32; break; + case 8: nPtr->refreshArea = neoRefreshArea8; break; + case 16: nPtr->refreshArea = neoRefreshArea16; break; + case 24: nPtr->refreshArea = neoRefreshArea24; break; + case 32: nPtr->refreshArea = neoRefreshArea32; break; } } - - ShadowFBInit(pScreen, refreshArea); +#if 0 + ShadowFBInit(pScreen, nPtr->refreshArea); +#else + shadowInit (pScreen, neoShadowUpdate, 0); +#endif } /* Initialise default colourmap */ @@ -1562,8 +1549,7 @@ NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; - if (pScrn->bitsPerPixel == 8) - racflag |= RAC_COLORMAP; + racflag |= RAC_COLORMAP; if (nPtr->NeoHWCursorInitialized) racflag |= RAC_CURSOR; @@ -1784,9 +1770,9 @@ neoMapMem(ScrnInfoPtr pScrn) xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, nPtr->NeoMMIOAddr, 0x200000L); + if (nPtr->NeoMMIOBase == NULL) + return FALSE; } - if (nPtr->NeoMMIOBase == NULL) - return FALSE; if (nPtr->pEnt->location.type == BUS_PCI) nPtr->NeoFbBase = @@ -1890,7 +1876,8 @@ neoSave(ScrnInfoPtr pScrn) || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) save->VCLK3NumeratorHigh = VGArGR(0x8F); save->VCLK3Denominator = VGArGR(0x9F); - + save->ProgramVCLK = TRUE; + if (save->reg == NULL) save->reg = (regSavePtr)xnfcalloc(sizeof(regSaveRec), 1); else @@ -2093,7 +2080,8 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, vgaHWPtr hwp = VGAHWPTR(pScrn); unsigned char temp; int i; - + Bool clock_hi = FALSE; + vgaHWProtect(pScrn,TRUE); /* Blank the screen */ VGAwGR(0x09,0x26); @@ -2216,12 +2204,18 @@ neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore, VGAwGR(0x37, restore->PanelVertCenterReg5); VGAwGR(0x38, restore->PanelHorizCenterReg5); } - + if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230 + || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) + clock_hi = TRUE; + /* Program VCLK3 if needed. */ - if (restore->ProgramVCLK) { + if (restore->ProgramVCLK + && ((VGArGR(0x9B) != restore->VCLK3NumeratorLow) + || (VGArGR(0x9F) != restore->VCLK3Denominator) + || (clock_hi && ((VGArGR(0x8F) & ~0x0f) + != (restore->VCLK3NumeratorHigh & ~0x0F))))) { VGAwGR(0x9B, restore->VCLK3NumeratorLow); - if (nPtr->NeoChipset == NM2200 || nPtr->NeoChipset == NM2230 - || nPtr->NeoChipset == NM2360 || nPtr->NeoChipset == NM2380) { + if (clock_hi) { temp = VGArGR(0x8F); temp &= 0x0F; /* Save bits 3:0 */ temp |= (restore->VCLK3NumeratorHigh & ~0x0F); @@ -2537,7 +2531,7 @@ neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) #define MAX_N 127 #define MAX_D 31 #define MAX_F 1 - +#define DEBUG static void neoCalcVCLK(ScrnInfoPtr pScrn, long freq) { @@ -2574,6 +2568,14 @@ neoCalcVCLK(ScrnInfoPtr pScrn, long freq) nPtr->NeoModeReg.VCLK3NumeratorLow = n_best | (f_best << 7); } nPtr->NeoModeReg.VCLK3Denominator = d_best; +#ifdef DEBUG + ErrorF("neoVCLK: f:%f NumLow=%i NumHi=%i Den=%i Df=%f\n", + f_target, + nPtr->NeoModeReg.VCLK3NumeratorLow, + nPtr->NeoModeReg.VCLK3NumeratorHigh, + nPtr->NeoModeReg.VCLK3Denominator, + f_best_diff); +#endif } /* @@ -2663,11 +2665,12 @@ neo_ddc1Read(ScrnInfoPtr pScrn) return (tmp); } -static void +static xf86MonPtr neo_ddc1(int scrnIndex) { vgaHWPtr hwp = VGAHWPTR(xf86Screens[scrnIndex]); unsigned int reg1, reg2, reg3; + xf86MonPtr ret; /* initialize chipset */ reg1 = VGArCR(0x21); @@ -2676,11 +2679,65 @@ neo_ddc1(int scrnIndex) VGAwCR(0x21,0x00); VGAwCR(0x1D,0x01); /* some Voodoo */ VGAwGR(0xA1,0x2F); - xf86SetDDCproperties(xf86Screens[scrnIndex],xf86PrintEDID( - xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,neo_ddc1Read))); + ret = xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,neo_ddc1Read); /* undo initialization */ VGAwCR(0x21,reg1); VGAwCR(0x1D,reg2); + return ret; +} + +static Bool +neoDoDDC1(ScrnInfoPtr pScrn) +{ + Bool ret = FALSE; + vgaHWPtr hwp = VGAHWPTR(pScrn); + + VGAwGR(0x09,0x26); + ret = xf86SetDDCproperties(pScrn, + xf86PrintEDID(neo_ddc1(pScrn->scrnIndex))); + VGAwGR(0x09,0x00); + + return ret; +} + +static Bool +neoDoDDC2(ScrnInfoPtr pScrn) +{ + NEOPtr nPtr = NEOPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + Bool ret = FALSE; + + VGAwGR(0x09,0x26); + if (xf86LoadSubModule(pScrn, "i2c")) { + xf86LoaderReqSymLists(i2cSymbols, NULL); + if (neo_I2CInit(pScrn)) { + ret = xf86SetDDCproperties(pScrn,xf86PrintEDID(xf86DoEDID_DDC2( + pScrn->scrnIndex,nPtr->I2C))); + } + } + VGAwGR(0x09,0x00); + + return ret; +} + +static Bool +neoDoDDCVBE(ScrnInfoPtr pScrn) +{ + NEOPtr nPtr = NEOPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + vbeInfoPtr pVbe; + Bool ret = FALSE; + + VGAwGR(0x09,0x26); + if (xf86LoadSubModule(pScrn, "vbe")) { + if ((pVbe = VBEInit(NULL,nPtr->pEnt->index))) { + ret = xf86SetDDCproperties( + pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); + vbeFree(pVbe); + } + } + VGAwGR(0x09,0x00); + return ret; } static int @@ -2725,3 +2782,14 @@ neoFindMode(int xres, int yres, int depth) return mode[size - 1].mode; } + +static void +neoProbeDDC(ScrnInfoPtr pScrn, int index) +{ + vbeInfoPtr pVbe; + + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL,index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + } +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c index e7f74f327..cd1925375 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c @@ -22,7 +22,7 @@ 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. **********************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c,v 1.2 1999/06/27 14:08:10 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c,v 1.3 2000/11/03 18:46:11 eich Exp $ */ /* * The original Precision Insight driver for @@ -89,6 +89,9 @@ neo_I2CInit(ScrnInfoPtr pScrn) I2CPtr->scrnIndex = pScrn->scrnIndex; I2CPtr->I2CPutBits = neo_I2CPutBits; I2CPtr->I2CGetBits = neo_I2CGetBits; + /* increase these as the defaults are too low */ + I2CPtr->RiseFallTime = 2; + I2CPtr->HoldTime = 40; if (!xf86I2CBusInit(I2CPtr)) return FALSE; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c index 5d9e04983..1a7320b90 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c,v 1.1 2000/02/08 13:13:18 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c,v 1.2 2000/11/03 18:46:11 eich Exp $ */ /* Copyright (c) 1999, 2000 The XFree86 Project Inc. @@ -15,6 +15,15 @@ #include "servermd.h" #include "neo.h" +void +neoShadowUpdate (ScreenPtr pScreen, PixmapPtr pShadow, RegionPtr damage) +{ + ScrnInfoPtr pScrn; + pScrn = xf86Screens[pScreen->myNum]; + + (NEOPTR(pScrn))->refreshArea (pScrn, REGION_NUM_RECTS(damage), + REGION_RECTS(damage)); +} void neoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c index 2b5f8966b..819b329fe 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c @@ -24,7 +24,7 @@ /* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen <jpaana@s2.org> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.7 2000/02/08 17:19:09 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.8 2000/11/03 18:46:12 eich Exp $ */ #include "nv_include.h" @@ -202,12 +202,12 @@ NV_ddc1Read(ScrnInfoPtr pScrn) unsigned char val; /* wait for Vsync */ - while(pNv->riva.PCIO[0x3da] & 0x08); - while(!(pNv->riva.PCIO[0x3da] & 0x08)); + while(VGA_RD08(pNv->riva.PCIO, 0x3da) & 0x08); + while(!(VGA_RD08(pNv->riva.PCIO, 0x3da) & 0x08)); /* Get the result */ - pNv->riva.PCIO[0x3d4] = 0x3e; - val = pNv->riva.PCIO[0x3d5]; + VGA_WR08(pNv->riva.PCIO, 0x3d4, 0x3e); + val = VGA_RD08(pNv->riva.PCIO, 0x3d5); DEBUG(ErrorF("NV_ddc1Read(%p,...) returns %d\n", pScrn, val)); return (val & DDC_SDA_READ_MASK) != 0; @@ -220,8 +220,8 @@ NV_I2CGetBits(I2CBusPtr b, int *clock, int *data) unsigned char val; /* Get the result. */ - pNv->riva.PCIO[0x3d4] = 0x3e; - val = pNv->riva.PCIO[0x3d5]; + VGA_WR08(pNv->riva.PCIO, 0x3d4, 0x3e); + val = VGA_RD08(pNv->riva.PCIO, 0x3d5); *clock = (val & DDC_SCL_READ_MASK) != 0; *data = (val & DDC_SDA_READ_MASK) != 0; @@ -235,8 +235,8 @@ NV_I2CPutBits(I2CBusPtr b, int clock, int data) NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]); unsigned char val; - pNv->riva.PCIO[0x3d4] = 0x3f; - val = pNv->riva.PCIO[0x3d5] & 0xf0; + VGA_WR08(pNv->riva.PCIO, 0x3d4, 0x3f); + val = VGA_RD08(pNv->riva.PCIO, 0x3d5) & 0xf0; if (clock) val |= DDC_SCL_WRITE_MASK; else @@ -247,8 +247,8 @@ NV_I2CPutBits(I2CBusPtr b, int clock, int data) else val &= ~DDC_SDA_WRITE_MASK; - pNv->riva.PCIO[0x3d4] = 0x3f; - pNv->riva.PCIO[0x3d5] = val | 0x1; + VGA_WR08(pNv->riva.PCIO, 0x3d4, 0x3f); + VGA_WR08(pNv->riva.PCIO, 0x3d5, val | 0x1); DEBUG(ErrorF("NV_I2CPutBits(%p, %d, %d) val=0x%x\n", b, clock, data, val)); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c index 72e1d29e8..844dcb1fe 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c @@ -24,7 +24,7 @@ /* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen <jpaana@s2.org> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.48 2000/10/24 22:45:08 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.49 2000/11/03 18:46:12 eich Exp $ */ #include "nv_include.h" @@ -555,10 +555,13 @@ static Bool NVEnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + NVPtr pNv = NVPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVEnterVT\n")); - RivaEnterLeave(pScrn, TRUE); + vgaHWUnlock(hwp); + pNv->riva.LockUnlock(&pNv->riva, 0); if (!NVModeInit(pScrn, pScrn->currentMode)) return FALSE; NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); @@ -586,10 +589,14 @@ static void NVLeaveVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + NVPtr pNv = NVPTR(pScrn); + vgaHWPtr hwp = VGAHWPTR(pScrn); + DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVLeaveVT\n")); NVRestore(pScrn); - RivaEnterLeave(pScrn, FALSE); + pNv->riva.LockUnlock(&pNv->riva, 1); + vgaHWLock(hwp); } /* @@ -611,11 +618,12 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen) if (pScrn->vtSema) { NVRestore(pScrn); + pNv->riva.LockUnlock(&pNv->riva, 1); vgaHWLock(hwp); - NVUnmapMem(pScrn); - vgaHWUnmapMem(pScrn); } + NVUnmapMem(pScrn); + vgaHWUnmapMem(pScrn); if (pNv->AccelInfoRec) XAADestroyInfoRec(pNv->AccelInfoRec); if (pNv->CursorInfoRec) @@ -702,11 +710,9 @@ NVdoDDC(ScrnInfoPtr pScrn) } } #endif - if (pNv->pInt) xf86FreeInt10(pNv->pInt); pNv->pInt = NULL; - if (!pNv->Primary) { /* XXX Need to write an NV mode ddc1SetSpeed */ if (pNv->DDC1SetSpeed == vgaHWddc1SetSpeed) { @@ -720,7 +726,8 @@ NVdoDDC(ScrnInfoPtr pScrn) NVSave(pScrn); /* Enable access to extended registers */ - RivaEnterLeave(pScrn, TRUE); + vgaHWUnlock(hwp); + pNv->riva.LockUnlock(&pNv->riva, 0); /* It is now safe to talk to the card */ #if NVuseI2C @@ -755,14 +762,15 @@ NVdoDDC(ScrnInfoPtr pScrn) #endif /* NVuseI2C */ /* Read and output monitor info using DDC1 */ if (pNv->ddc1Read && pNv->DDC1SetSpeed) { +#if 0 MonInfo = xf86DoEDID_DDC1(pScrn->scrnIndex, pNv->DDC1SetSpeed, pNv->ddc1Read ); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n", MonInfo); xf86PrintEDID( MonInfo ); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n\n"); +#endif } - /* Restore previous state */ NVRestore(pScrn); @@ -823,7 +831,10 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo); /* Initialize the card through int10 interface if needed */ - if ( !pNv->Primary && xf86LoadSubModule(pScrn, "int10")){ +#if 0 + if ( !pNv->Primary &&) +#endif + if (xf86LoadSubModule(pScrn, "int10")){ xf86LoaderReqSymLists(int10Symbols, NULL); @@ -1565,6 +1576,8 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; } else { /* Save the current state */ + vgaHWUnlock(hwp); + pNv->riva.LockUnlock(&pNv->riva, 0); NVSave(pScrn); /* Initialise the first mode */ if (!NVModeInit(pScrn, pScrn->currentMode)) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_local.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_local.h index 08332f02f..842d86db9 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_local.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_local.h @@ -36,7 +36,7 @@ |* those rights set forth herein. *| |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_local.h,v 1.5 2000/08/03 12:24:03 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_local.h,v 1.6 2000/11/03 18:46:12 eich Exp $ */ #ifndef __NV_LOCAL_H__ #define __NV_LOCAL_H__ @@ -56,12 +56,14 @@ typedef unsigned int U032; /* * HW access macros. */ -#define NV_WR08(p,i,d) (((U008 *)(p))[i]=(d)) -#define NV_RD08(p,i) (((U008 *)(p))[i]) -#define NV_WR16(p,i,d) (((U016 *)(p))[(i)/2]=(d)) -#define NV_RD16(p,i) (((U016 *)(p))[(i)/2]) -#define NV_WR32(p,i,d) (((U032 *)(p))[(i)/4]=(d)) -#define NV_RD32(p,i) (((U032 *)(p))[(i)/4]) +#include "xf86_OSproc.h" +/* these assume memory-mapped I/O, and not normal I/O space */ +#define NV_WR08(p,i,d) MMIO_OUT8((volatile pointer)(p), (i), (d)) +#define NV_RD08(p,i) MMIO_IN8((volatile pointer)(p), (i)) +#define NV_WR16(p,i,d) MMIO_OUT16((volatile pointer)(p), (i), (d)) +#define NV_RD16(p,i) MMIO_IN16((volatile pointer)(p), (i)) +#define NV_WR32(p,i,d) MMIO_OUT32((volatile pointer)(p), (i), (d)) +#define NV_RD32(p,i) MMIO_IN32((volatile pointer)(p), (i)) #if 1 #define VGA_WR08(p,i,d) NV_WR08(p,i,d) #define VGA_RD08(p,i) NV_RD08(p,i) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c index ae7257e00..bb0df1af5 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c @@ -24,7 +24,7 @@ /* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen <jpaana@s2.org> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.6 2000/02/10 18:59:38 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.7 2000/11/03 18:46:12 eich Exp $ */ #include "nv_include.h" @@ -32,26 +32,6 @@ #include "nvvga.h" /* - * Lock and unlock VGA and SVGA registers. - */ -void RivaEnterLeave(ScrnInfoPtr pScrn, Bool enter) -{ - vgaHWPtr hwp = VGAHWPTR(pScrn); - NVPtr pNv = NVPTR(pScrn); - - if (enter) - { - vgaHWUnlock(hwp); - pNv->riva.LockUnlock(&pNv->riva, 0); - } - else - { - pNv->riva.LockUnlock(&pNv->riva, 1); - vgaHWLock(hwp); - } -} - -/* * Override VGA I/O routines. */ static void NVWriteCrtc(vgaHWPtr pVga, CARD8 index, CARD8 value) @@ -279,7 +259,8 @@ NVCommonSetup(ScrnInfoPtr pScrn) pNv->Dac.maxPixelClock = pNv->riva.MaxVClockFreqKHz; - RivaEnterLeave(pScrn, TRUE); + vgaHWUnlock(VGAHWPTR(pScrn)); + pNv->riva.LockUnlock(&pNv->riva, 0); } void diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c index 0de053973..6939aa860 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c @@ -41,7 +41,7 @@ /* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen <jpaana@s2.org> */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.17 2000/10/24 22:45:09 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.18 2000/11/03 18:46:12 eich Exp $ */ #include "nv_include.h" #include "xaalocal.h" @@ -69,6 +69,7 @@ NVSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) RIVA_FIFO_FREE(pNv->riva, Clip, 2); pNv->riva.Clip->TopLeft = (y1 << 16) | (x1 & 0xffff); pNv->riva.Clip->WidthHeight = (height << 16) | width; + mem_barrier(); } @@ -142,6 +143,7 @@ NVSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) RIVA_FIFO_FREE(pNv->riva, Bitmap, 2); pNv->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y; pNv->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h; + mem_barrier(); } /* @@ -160,10 +162,14 @@ NVSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, { NVPtr pNv = NVPTR(pScrn); +/* ErrorF("E SubseqSS\n"); */ RIVA_FIFO_FREE(pNv->riva, Blt, 3); pNv->riva.Blt->TopLeftSrc = (y1 << 16) | x1; pNv->riva.Blt->TopLeftDst = (y2 << 16) | x2; pNv->riva.Blt->WidthHeight = (h << 16) | w; + mem_barrier(); +/* ErrorF("L SubseqSS\n"); */ + } @@ -199,6 +205,7 @@ NVSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, bg = (bg == -1) ? 0 : bg | pNv->opaqueMonochrome; }; NVSetPattern(pNv, bg, fg, patternx, patterny); + mem_barrier(); RIVA_FIFO_FREE(pNv->riva, Bitmap, 1); pNv->riva.Bitmap->Color1A = fg; } @@ -213,6 +220,7 @@ NVSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, RIVA_FIFO_FREE(pNv->riva, Bitmap, 2); pNv->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y; pNv->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h; + mem_barrier(); } @@ -224,8 +232,9 @@ NVSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, void NVSync(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - +/* ErrorF("sync enter\n"); */ while (pNv->riva.Busy(&pNv->riva)); +/* ErrorF("sync leave\n"); */ } /* Color expansion */ @@ -458,6 +467,8 @@ NVSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask) NVPtr pNv = NVPTR(pScrn); NVSetRopSolid(pNv, rop); + mem_barrier(); + RIVA_FIFO_FREE(pNv->riva, Line, 1); pNv->FgColor = color; } @@ -473,6 +484,7 @@ NVSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir) pNv->riva.Line->Lin[0].point1 = ((y << 16) | (( x + len ) & 0xffff)); else pNv->riva.Line->Lin[0].point1 = (((y + len) << 16) | ( x & 0xffff)); + mem_barrier(); } static void @@ -491,6 +503,7 @@ NVSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, pNv->riva.Line->Lin[1].point0 = ((y2 << 16) | (x2 & 0xffff)); pNv->riva.Line->Lin[1].point1 = (((y2 + 1) << 16) | (x2 & 0xffff)); } + mem_barrier(); } #else @@ -553,6 +566,7 @@ NVSubsequentSolidHorVertLine( RIVA_FIFO_FREE(pNv->riva, Bitmap, 2); pNv->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y; pNv->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h; + mem_barrier(); } #ifndef NV_USE_FB @@ -757,6 +771,7 @@ NVAccelInit(ScreenPtr pScreen) infoPtr->PolyPointMask = GCFunction | GCPlaneMask; NVDisableClipping(pScrn); + return(XAAInit(pScreen, infoPtr)); } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h index 0b6683b59..752a797df 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h @@ -36,7 +36,7 @@ |* those rights set forth herein. *| |* *| \***************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h,v 1.6 2000/02/08 17:19:12 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h,v 1.7 2000/11/03 18:46:12 eich Exp $ */ #ifndef __RIVA_HW_H__ #define __RIVA_HW_H__ #define RIVA_SW_VERSION 0x00010003 @@ -425,8 +425,10 @@ int RivaGetConfig(RIVA_HW_INST *); #define RIVA_FIFO_FREE(hwinst,hwptr,cnt) \ { \ - while ((hwinst).FifoFreeCount < (cnt)) \ + while ((hwinst).FifoFreeCount < (cnt)) { \ + mem_barrier(); \ (hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2; \ + } \ (hwinst).FifoFreeCount -= (cnt); \ } #endif /* __RIVA_HW_H__ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h index 2c3aa87da..ddd93555a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h,v 1.23 2000/10/23 12:10:15 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h,v 1.24 2000/11/02 16:29:12 anderson Exp $ */ /* Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. @@ -80,11 +80,9 @@ in this Software without prior written authorization from the XFree86 Project. #include "vbe.h" -#ifdef XvExtension #include "xf86xv.h" #include "Xv.h" #include "fourcc.h" -#endif #ifndef _S3V_VGAHWMMIO_H #define _S3V_VGAHWMMIO_H diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c index 27e7c84cc..6752f9633 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c,v 1.63 2000/10/23 12:10:16 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c,v 1.64 2000/11/03 18:46:13 eich Exp $ */ /* Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. @@ -103,6 +103,8 @@ static void S3VDisplayPowerManagementSet(ScrnInfoPtr pScrn, int flags); #endif static Bool S3Vddc1(int scrnIndex); +static Bool S3Vddc2(int scrnIndex); + static unsigned int S3Vddc1Read(ScrnInfoPtr pScrn); static void S3VProbeDDC(ScrnInfoPtr pScrn, int index); @@ -985,16 +987,7 @@ S3VPreInit(ScrnInfoPtr pScrn, int flags) && ((pMon = xf86PrintEDID(vbeDoEDID(ps3v->pVbe, NULL))) != NULL)) xf86SetDDCproperties(pScrn,pMon); else if (!S3Vddc1(pScrn->scrnIndex)) { - if ( xf86LoadSubModule(pScrn, "i2c") ) { - xf86LoaderReqSymLists(i2cSymbols,NULL); - if (S3V_I2CInit(pScrn)) { - CARD32 tmp = (INREG(DDC_REG)); - OUTREG(DDC_REG,(tmp | 0x13)); - xf86SetDDCproperties(pScrn,xf86PrintEDID( - xf86DoEDID_DDC2(pScrn->scrnIndex,ps3v->I2C))); - OUTREG(DDC_REG,tmp); - } - } + S3Vddc2(pScrn->scrnIndex); } } if (ps3v->pVbe) @@ -3759,6 +3752,25 @@ S3Vddc1(int scrnIndex) return success; } +static Bool +S3Vddc2(int scrnIndex) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + S3VPtr ps3v = S3VPTR(pScrn); + + if ( xf86LoadSubModule(pScrn, "i2c") ) { + xf86LoaderReqSymLists(i2cSymbols,NULL); + if (S3V_I2CInit(pScrn)) { + CARD32 tmp = (INREG(DDC_REG)); + OUTREG(DDC_REG,(tmp | 0x13)); + xf86SetDDCproperties(pScrn,xf86PrintEDID( + xf86DoEDID_DDC2(pScrn->scrnIndex,ps3v->I2C))); + OUTREG(DDC_REG,tmp); + return TRUE; + } + } + return FALSE; +} static void S3VProbeDDC(ScrnInfoPtr pScrn, int index) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile index 553ed84f4..94e72cd9d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile,v 1.25 2000/09/03 05:13:27 keithp Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile,v 1.26 2000/11/03 18:46:13 eich Exp $ XCOMM XCOMM This is an Imakefile for the TRIDENT driver. XCOMM @@ -8,10 +8,12 @@ XCOMM SRCS = trident_driver.c trident_dac.c tridenthelper.c \ trident_accel.c trident_i2c.c trident_bank.c \ - image_accel.c blade_accel.c tvga_dac.c trident_dga.c + image_accel.c blade_accel.c tvga_dac.c trident_dga.c \ + trident_shadow.c OBJS = trident_driver.o trident_dac.o tridenthelper.o \ trident_accel.o trident_i2c.o trident_bank.o \ - image_accel.o blade_accel.o tvga_dac.o trident_dga.o + image_accel.o blade_accel.o tvga_dac.o trident_dga.o \ + trident_shadow.o #if defined(XF86DriverSDK) INCLUDES = -I. -I../../include @@ -19,7 +21,7 @@ INCLUDES = -I. -I../../include INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \ -I$(SERVERSRC)/mi -I$(XF86SRC)/xaa -I$(SERVERSRC)/fb \ -I$(XF86SRC)/xf1bpp -I$(SERVERSRC)/miext/shadow \ - -I$(SERVERSRC)/render \ + -I$(SERVERSRC)/render -I$(XF86SRC)/shadowfb \ -I$(XF86SRC)/xf4bpp -I$(SERVERSRC)/mfb \ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \ -I$(XF86SRC)/rac -I$(XF86SRC)/int10 \ @@ -55,6 +57,7 @@ InstallDriverSDKNonExecFile(trident_dac.c,$(DRIVERSDKDIR)/drivers/trident) InstallDriverSDKNonExecFile(trident_dga.c,$(DRIVERSDKDIR)/drivers/trident) InstallDriverSDKNonExecFile(trident_driver.c,$(DRIVERSDKDIR)/drivers/trident) InstallDriverSDKNonExecFile(trident_i2c.c,$(DRIVERSDKDIR)/drivers/trident) +InstallDriverSDKNonExecFile(trident_shadow.c,$(DRIVERSDKDIR)/drivers/trident) InstallDriverSDKNonExecFile(trident_regs.h,$(DRIVERSDKDIR)/drivers/trident) InstallDriverSDKNonExecFile(tridenthelper.c,$(DRIVERSDKDIR)/drivers/trident) InstallDriverSDKNonExecFile(tridentramdac.c,$(DRIVERSDKDIR)/drivers/trident) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c index e4cc22d85..04ad36259 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c @@ -23,7 +23,7 @@ * * Trident Blade3D accelerated options. */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c,v 1.7 2000/07/05 13:41:37 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c,v 1.8 2000/11/03 18:46:13 eich Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -146,6 +146,7 @@ BladeAccelInit(ScreenPtr pScreen) pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); if (!infoPtr) return FALSE; + pTrident->InitializeAccelerator = BladeInitializeAccelerator; BladeInitializeAccelerator(pScrn); infoPtr->Flags = PIXMAP_CACHE | diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c index 23c9a5e28..75b83482a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c +++ b/xc/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.15 2000/10/11 15:42:05 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c,v 1.16 2000/11/03 18:46:13 eich Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -143,6 +143,7 @@ ImageAccelInit(ScreenPtr pScreen) pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); if (!infoPtr) return FALSE; + pTrident->InitializeAccelerator = ImageInitializeAccelerator; ImageInitializeAccelerator(pScrn); infoPtr->Flags = PIXMAP_CACHE | diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h index 8beaa9d40..b30f32fc6 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h +++ b/xc/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.27 2000/10/11 15:42:05 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h,v 1.28 2000/11/03 18:46:13 eich Exp $ */ #ifndef _TRIDENT_H_ #define _TRIDENT_H_ @@ -33,6 +33,7 @@ #include "vgaHW.h" #include "xf86i2c.h" #include "xf86int10.h" +#include "shadowfb.h" typedef struct { unsigned char tridentRegs3x4[0x100]; @@ -91,6 +92,9 @@ typedef struct { int DGAViewportStatus; unsigned char * ShadowPtr; int ShadowPitch; + RefreshAreaFuncPtr RefreshArea; + void (*PointerMoved)(int index, int x, int y); + int Rotate; float frequency; unsigned char REGPCIReg; unsigned char REGNewMode1; @@ -129,6 +133,7 @@ typedef struct { unsigned int (*ddc1Read)(ScrnInfoPtr); CARD8* XAAScanlineColorExpandBuffers[2]; CARD8* XAAImageScanlineBuffer[1]; + void (*InitializeAccelerator)(ScrnInfoPtr); } TRIDENTRec, *TRIDENTPtr; typedef struct { @@ -193,6 +198,14 @@ int TVGA8900SetWrite(ScreenPtr pScreen, int bank); int TVGA8900SetReadWrite(ScreenPtr pScreen, int bank); void TridentFindClock(ScrnInfoPtr pScrn, int clock); float CalculateMCLK(ScrnInfoPtr pScrn); +void TRIDENTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void TRIDENTShadowUpdate (ScreenPtr pScreen, PixmapPtr pShadow, + RegionPtr damage); +void TRIDENTPointerMoved(int index, int x, int y); +void TRIDENTRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void TRIDENTRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void TRIDENTRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void TRIDENTRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); /* * Trident Chipset Definitions diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c index 5555e4c28..f0d8824c6 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c +++ b/xc/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.15 2000/10/11 16:35:05 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c,v 1.16 2000/11/03 18:46:13 eich Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -111,6 +111,7 @@ TridentAccelInit(ScreenPtr pScreen) pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); if (!infoPtr) return FALSE; + pTrident->InitializeAccelerator = TridentInitializeAccelerator; TridentInitializeAccelerator(pScrn); if (!(pTrident->Chipset == TGUI9440AGi && pScrn->bitsPerPixel > 8)) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c index 6b53c1368..05f529f68 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c @@ -21,7 +21,7 @@ * * Author: Alan Hourihane, alanh@fairlite.demon.co.uk */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.27 2000/10/09 17:09:43 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.28 2000/11/03 18:46:14 eich Exp $ */ #include "xf86.h" #include "xf86_OSproc.h" @@ -237,7 +237,7 @@ TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode) pReg->tridentRegs3x4[0x5] = LCD[i].shadow_5; pReg->tridentRegs3x4[0x6] = LCD[i].shadow_6; xf86DrvMsgVerb(pScrn->scrnIndex,X_INFO,1, - "Overriding Horizontal timings."); + "Overriding Horizontal timings.\n"); } } @@ -526,7 +526,7 @@ TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) if (pTrident->Chipset >= BLADE3D) OUTW_3x4(RAMDACTiming); if (pTrident->IsCyber) { CARD8 tmp; - + OUTW_3CE(VertStretch); OUTW_3CE(HorStretch); OUTW_3CE(BiosMode); @@ -542,7 +542,7 @@ TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg) OUTW_3x4(0x7); OUTW_3x4(0x10); OUTW_3x4(0x11); - OUTW_3x4(0x96); + OUTW_3x4(0x16); SHADOW_RESTORE(tmp); OUTW_3x4(PreEndControl); OUTW_3x4(PreEndFetch); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c index 8dc7ef045..a8a574d1a 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c +++ b/xc/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.107 2000/09/20 00:09:32 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c,v 1.108 2000/11/03 18:46:14 eich Exp $ */ #include "xf1bpp.h" #include "xf4bpp.h" @@ -100,6 +100,7 @@ static void TRIDENTDisableMMIO(ScrnInfoPtr pScrn); static void PC98TRIDENTInit(ScrnInfoPtr pScrn); static void PC98TRIDENTEnable(ScrnInfoPtr pScrn); static void PC98TRIDENTDisable(ScrnInfoPtr pScrn); + /* * This is intentionally screen-independent. It indicates the binding * choice made in the first PreInit. @@ -201,6 +202,7 @@ typedef enum { OPTION_SETMCLK, OPTION_MUX_THRESHOLD, OPTION_SHADOW_FB, + OPTION_ROTATE, OPTION_MMIO_ONLY, #if 0 /* obsolete */ @@ -218,6 +220,7 @@ static OptionInfoRec TRIDENTOptions[] = { { OPTION_SETMCLK, "SetMClk", OPTV_FREQ, {0}, FALSE }, { OPTION_MUX_THRESHOLD, "MUXThreshold", OPTV_INTEGER, {0}, FALSE }, { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, #if 0 /* obsolete */ { OPTION_CYBER_SHADOW, "CyberShadow", OPTV_BOOLEAN, {0}, FALSE }, @@ -423,7 +426,7 @@ tridentLCD LCD[] = { /* 0 3 4 5 6 7 10 11 16 */ { 0,"640x480",25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08}, { 1,"800x600",40000,0x7f,0x99,0x69,0x99,0x72,0xf0,0x59,0x2d,0x5e,0x08}, { 2,"1024x768",65000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, - { 3,"1024x768",65000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, + { 3,"1024x768",65000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, /*0x96*/ { 4,"1280x1024",108000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x25,0x96,0x08}, { 5,"1024x600",50500 ,0xa3,0x6,0x8f,0xa0,0xb,0x3e,0xea,0x8c,0xb,0x08}, { 0xff,"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } @@ -432,7 +435,7 @@ tridentLCD LCD[] = { /* 0 3 4 5 6 7 10 11 16 */ tridentLCD LCD[] = { { 1,"640x480",25200,0x5f,0x82,0x54,0x80,0xb,0x3e,0xea,0x8c,0xb,0x08}, { 3,"800x600",40000,0x7f,0x82,0x6b,0x1b,0x72,0xf8,0x58,0x8c,0x72,0x08}, - { 2,"1024x768",65000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x24,0x96,0x08}, + { 2,"1024x768",65000,0xa3,0x6,0x8f,0xa0,0x24,0xf5,0x0f,0x24,0x0a,0x08}, { 0,"1280x1024",108000,0xce,0x81,0xa6,0x9a,0x27,0x50,0x00,0x03,0x26,0xa8}, { 0xff,"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; @@ -571,6 +574,9 @@ TRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int TRIDENTPtr pTrident = TRIDENTPTR(pScrn); CARD8 DPMSCont, PMCont, temp; + if (!pScrn->vtSema) + return; + OUTB(0x3C4, 0x0E); temp = INB(0x3C5); OUTB(0x3C5, 0xC2); @@ -965,42 +971,6 @@ GetAccelPitchValues(ScrnInfoPtr pScrn) } static void -TRIDENTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) -{ - TRIDENTPtr pTrident = TRIDENTPTR(pScrn); - int width, height, Bpp, FBPitch; - unsigned char *src, *dst; - - Bpp = pScrn->bitsPerPixel >> 3; - FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); - - while(num--) { - width = (pbox->x2 - pbox->x1) * Bpp; - height = pbox->y2 - pbox->y1; - src = pTrident->ShadowPtr + (pbox->y1 * pTrident->ShadowPitch) + - (pbox->x1 * Bpp); - dst = pTrident->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); - - while(height--) { - memcpy(dst, src, width); - dst += FBPitch; - src += pTrident->ShadowPitch; - } - - pbox++; - } -} - -static void -TRIDENTShadowUpdate (ScreenPtr pScreen, PixmapPtr pShadow, RegionPtr damage) -{ - ScrnInfoPtr pScrn; - pScrn = xf86Screens[pScreen->myNum]; - - TRIDENTRefreshArea (pScrn, REGION_NUM_RECTS(damage), REGION_RECTS(damage)); -} - -static void TRIDENTProbeDDC(ScrnInfoPtr pScrn, int index) { vbeInfoPtr pVbe; @@ -1028,7 +998,8 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) char *mod = NULL; const char *Sym = ""; Bool ddcLoaded = FALSE; - + char *s; + /* Allocate the TRIDENTRec driverPrivate */ if (!TRIDENTGetRec(pScrn)) { return FALSE; @@ -1235,10 +1206,50 @@ TRIDENTPreInit(ScrnInfoPtr pScrn, int flags) pTrident->MUXThreshold); } if (xf86ReturnOptValBool(TRIDENTOptions, OPTION_SHADOW_FB, FALSE)) { - pTrident->ShadowFB = TRUE; - pTrident->NoAccel = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using \"Shadow Framebuffer\" - acceleration disabled\n"); + if (!pTrident->Linear) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option SHADOW_FB" + " in non-Linear Mode\n"); + else if (pScrn->depth < 8) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Tgnoring Option SHADOW_FB" + " when depth < 8"); + else { + pTrident->ShadowFB = TRUE; + pTrident->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using \"Shadow Framebuffer\" - acceleration disabled\n"); + } + } + pTrident->Rotate = 0; + if ((s = xf86GetOptValString(TRIDENTOptions, OPTION_ROTATE))) { + if (!pTrident->Linear) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring Option ROTATE " + "in non-Linear Mode\n"); + else if (pScrn->depth < 8) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Tgnoring Option ROTATE " + "when depth < 8"); + else { + if(!xf86NameCmp(s, "CW")) { + /* accel is disabled below for shadowFB */ + pTrident->ShadowFB = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + pTrident->Rotate = 1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n"); + } else if(!xf86NameCmp(s, "CCW")) { + pTrident->ShadowFB = TRUE; + pTrident->NoAccel = TRUE; + pTrident->HWCursor = FALSE; + pTrident->Rotate = -1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" + "counter clockwise - acceleration disabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" + "value for Option \"Rotate\"\n", s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid options are \"CW\" or \"CCW\"\n"); + } + } } /* FIXME ACCELERATION */ @@ -2306,6 +2317,7 @@ TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) int ret; VisualPtr visual; unsigned char *FBStart; + int width, height, displayWidth; /* * First get the ScrnInfoRec @@ -2364,28 +2376,27 @@ TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Setup the visuals we support. */ - /* - * For bpp > 8, the default visuals are not acceptable because we only - * support TrueColor and not DirectColor. - */ + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; - 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; - } miSetPixmapDepths (); /* FIXME - we don't do shadowfb for < 4 */ + displayWidth = pScrn->displayWidth; + if (pTrident->Rotate) { + height = pScrn->virtualX; + width = pScrn->virtualY; + } else { + width = pScrn->virtualX; + height = pScrn->virtualY; + } + if(pTrident->ShadowFB) { - pTrident->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * pScrn->virtualX); - pTrident->ShadowPtr = xalloc(pTrident->ShadowPitch * pScrn->virtualY); - pScrn->displayWidth = pTrident->ShadowPitch / (pScrn->bitsPerPixel >> 3); + pTrident->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); + pTrident->ShadowPtr = xalloc(pTrident->ShadowPitch * height); + displayWidth = pTrident->ShadowPitch / (pScrn->bitsPerPixel >> 3); FBStart = pTrident->ShadowPtr; } else { pTrident->ShadowFB = FALSE; @@ -2400,22 +2411,22 @@ TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) switch (pScrn->bitsPerPixel) { case 1: - ret = xf1bppScreenInit(pScreen, FBStart, pScrn->virtualX, - pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); + ret = xf1bppScreenInit(pScreen, FBStart, width, + height, pScrn->xDpi, pScrn->yDpi, + displayWidth); break; case 4: - ret = xf4bppScreenInit(pScreen, FBStart, pScrn->virtualX, - pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); + ret = xf4bppScreenInit(pScreen, FBStart, width, + height, pScrn->xDpi, pScrn->yDpi, + displayWidth); break; case 8: case 16: case 24: case 32: - ret = fbScreenInit(pScreen, FBStart, pScrn->virtualX, - pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth, pScrn->bitsPerPixel); + ret = fbScreenInit(pScreen, FBStart, width, + height, pScrn->xDpi, pScrn->yDpi, + displayWidth, pScrn->bitsPerPixel); break; default: xf86DrvMsg(scrnIndex, X_ERROR, @@ -2520,12 +2531,36 @@ TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; if(pTrident->ShadowFB) { + if(pTrident->Rotate) { + if (!pTrident->PointerMoved) { + pTrident->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = TRIDENTPointerMoved; + } + switch (pScrn->bitsPerPixel) { +#if 1 + case 8: pTrident->RefreshArea = TRIDENTRefreshArea8; break; + case 16: pTrident->RefreshArea = TRIDENTRefreshArea16; break; + case 24: pTrident->RefreshArea = TRIDENTRefreshArea24; break; + case 32: pTrident->RefreshArea = TRIDENTRefreshArea32; break; +#else + case 8: shadowInit (pScreen, shadowUpdateRotate8, 0); break; + case 16: shadowInit (pScreen, shadowUpdateRotate16, 0); break; + case 24: shadowInit (pScreen, shadowUpdateRotate32, 0); break; +#endif + } + } else { + pTrident->RefreshArea = TRIDENTRefreshArea; #if 0 - RefreshAreaFuncPtr refreshArea = TRIDENTRefreshArea; - ShadowFBInit(pScreen, refreshArea); + shadowInit (pScreen, shadowUpdatePacked, 0); +#endif + } +#if 1 +#if 0 + ShadowFBInit(pScreen, pTrident->RefreshArea); #else shadowInit (pScreen, TRIDENTShadowUpdate, 0); #endif +#endif } #ifdef DPMSExtension @@ -2642,6 +2677,9 @@ TRIDENTEnterVT(int scrnIndex, int flags) if (!TRIDENTModeInit(pScrn, pScrn->currentMode)) return FALSE; + if (pTrident->InitializeAccelerator) + pTrident->InitializeAccelerator(pScrn); + return TRUE; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c new file mode 100644 index 000000000..a6defb300 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c @@ -0,0 +1,258 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_shadow.c,v 1.1 2000/11/03 18:46:14 eich Exp $ */ + +/* + Copyright (c) 1999, 2000 The XFree86 Project Inc. + based on code written by Mark Vojkovich <markv@valinux.com> +*/ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86_ansic.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "shadowfb.h" +#include "servermd.h" +#include "trident.h" + +void +TRIDENTRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pTrident->ShadowPtr + (pbox->y1 * pTrident->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pTrident->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pTrident->ShadowPitch; + } + + pbox++; + } +} + +void +TRIDENTShadowUpdate (ScreenPtr pScreen, PixmapPtr pShadow, RegionPtr damage) +{ + ScrnInfoPtr pScrn; + pScrn = xf86Screens[pScreen->myNum]; + + (TRIDENTPTR(pScrn))->RefreshArea (pScrn, REGION_NUM_RECTS(damage), + REGION_RECTS(damage)); +} + +void +TRIDENTPointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int newX, newY; + + if(pTrident->Rotate == 1) { + newX = pScrn->pScreen->height - y - 1; + newY = x; + } else { + newX = y; + newY = pScrn->pScreen->width - x - 1; + } + + (*pTrident->PointerMoved)(index, newX, newY); +} + +void +TRIDENTRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* in dwords */ + + if(pTrident->Rotate == 1) { + dstPtr = pTrident->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = pTrident->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = pTrident->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 8) | + (src[srcPitch * 2] << 16) | + (src[srcPitch * 3] << 24); + src += srcPitch * 4; + } + srcPtr += pTrident->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +void +TRIDENTRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD16 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch >> 1; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~1; + y2 = (pbox->y2 + 1) & ~1; + height = (y2 - y1) >> 1; /* in dwords */ + + if(pTrident->Rotate == 1) { + dstPtr = (CARD16*)pTrident->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = (CARD16*)pTrident->ShadowPtr + + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD16*)pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = (CARD16*)pTrident->ShadowPtr + + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 16); + src += srcPitch * 2; + } + srcPtr += pTrident->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +/* this one could be faster */ +void +TRIDENTRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = BitmapBytePad(pScrn->displayWidth * 24); + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* blocks of 3 dwords */ + + if(pTrident->Rotate == 1) { + dstPtr = pTrident->FbBase + + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); + srcPtr = pTrident->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); + } else { + dstPtr = pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); + srcPtr = pTrident->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | + (src[srcPitch] << 24); + dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | + (src[srcPitch * 2] << 16) | + (src[(srcPitch * 2) + 1] << 24); + dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | + (src[(srcPitch * 3) + 1] << 16) | + (src[(srcPitch * 3) + 2] << 24); + dst += 3; + src += srcPitch * 4; + } + srcPtr += pTrident->Rotate * 3; + dstPtr += dstPitch; + } + + pbox++; + } +} + +void +TRIDENTRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + TRIDENTPtr pTrident = TRIDENTPTR(pScrn); + int count, width, height, dstPitch, srcPitch; + CARD32 *dstPtr, *srcPtr, *src, *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pTrident->Rotate * pTrident->ShadowPitch >> 2; + + while(num--) { + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + if(pTrident->Rotate == 1) { + dstPtr = (CARD32*)pTrident->FbBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; + srcPtr = (CARD32*)pTrident->ShadowPtr + + ((1 - pbox->y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD32*)pTrident->FbBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; + srcPtr = (CARD32*)pTrident->ShadowPtr + + (pbox->y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = dstPtr; + count = height; + while(count--) { + *(dst++) = *src; + src += srcPitch; + } + srcPtr += pTrident->Rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile index 49ce1f5a5..dc9de4004 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile @@ -4,7 +4,7 @@ XCOMM $XConsortium: Imakefile /main/10 1996/09/28 17:29:32 rws $ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile,v 1.18 2000/09/20 00:09:33 keithp Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile,v 1.19 2000/11/03 18:46:14 eich Exp $ #define IHaveModules #include <Server.tmpl> @@ -22,7 +22,7 @@ INCLUDES = -I. -I../../include #else INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ - -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \ + -I$(SERVERSRC)/fb -I$(XF86SRC)/xaa \ -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \ -I$(XF86SRC)/xf24_32bpp \ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h index 709530014..30664b2da 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h @@ -1,5 +1,5 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h,v 1.31 2000/10/17 16:53:17 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h,v 1.32 2000/11/03 18:46:15 eich Exp $ */ @@ -40,18 +40,7 @@ /* Needed for the 1 and 4 bpp framebuffers */ #include "xf1bpp.h" #include "xf4bpp.h" - -/* Drivers using cfb need this */ - -#define PSZ 8 -#include "cfb.h" -#undef PSZ - -/* Drivers supporting bpp 16, 24 or 32 with cfb need these */ - -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" +#include "fb.h" /* Drivers using the XAA interface ... */ #include "xaa.h" diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c index bd62f995d..2d365d9ba 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c,v 1.74 2000/10/17 16:53:18 tsi Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c,v 1.75 2000/11/03 18:46:15 eich Exp $ * * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. * @@ -43,17 +43,11 @@ /* All drivers implementing backing store need this */ #include "mibstore.h" -/* - * If using cfb, cfb.h is required. Select the others for the bpp values - * the driver supports. - */ -#define PSZ 8 /* needed for cfb.h */ -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb24.h" -#include "cfb32.h" -#include "cfb24_32.h" +#include "fb.h" +#ifdef RENDER +#include "picturestr.h" +#endif + #include "xf86RAC.h" #include "xf86Resources.h" #include "xf86int10.h" @@ -226,6 +220,53 @@ static OptionInfoRec TsengOptions[] = {0}, FALSE} }; +static const char *int10Symbols[] = { + "xf86InitInt10", + "xf86FreeInt10", + NULL +}; + +static const char *vgaHWSymbols[] = { + "vgaHWMapMem", + "vgaHWUnmapMem", + "vgaHWGetHWRec", + "vgaHWGetIOBase", + "vgaHWHandleColormaps", + "vgaHWUnlock", + "vgaHWLock", + "vgaHWSaveScreen", + "vgaHWInit", + "vgaHWSave", + "vgaHWRestore", + "vgaHWBlankScreen", + "vgaHWSeqReset", + "vgaHWProtect", + NULL +}; + +static const char* fbSymbols[] = { + "xf1bppScreenInit", + "xf4bppScreenInit", + "fbScreenInit", + "fbScreenInit", + "fbPictureInit", + NULL +}; + +static const char *ramdacSymbols[] = { + "xf86InitCursor", + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + NULL +}; + +static const char *xaaSymbols[] = { + "XAADestroyInfoRec", + "XAACreateInfoRec", + "XAAInit", + NULL +}; + #ifdef XFree86LOADER static MODULESETUPPROTO(tsengSetup); @@ -264,6 +305,12 @@ tsengSetup(pointer module, pointer opts, int *errmaj, int *errmin) * Modules that this driver always requires can be loaded here * by calling LoadSubModule(). */ + /* + * Tell the loader about symbols from other modules that this module + * might refer to. + */ + LoaderRefSymLists(vgaHWSymbols, fbSymbols, xaaSymbols, + ramdacSymbols, NULL); /* * The return value must be non-NULL on success even though there @@ -1460,7 +1507,6 @@ TsengPreInit(ScrnInfoPtr pScrn, int flags) TsengPtr pTseng; MessageType from; int i; - char *mod = NULL; if (flags & PROBE_DETECT) return FALSE; @@ -1497,6 +1543,7 @@ TsengPreInit(ScrnInfoPtr pScrn, int flags) #if 1 if (xf86LoadSubModule(pScrn, "int10")) { xf86Int10InfoPtr pInt; + xf86LoaderReqSymLists(int10Symbols, NULL); #if 1 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); pInt = xf86InitInt10(pTseng->pEnt->index); @@ -1507,7 +1554,7 @@ TsengPreInit(ScrnInfoPtr pScrn, int flags) if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; - + xf86LoaderReqSymLists(vgaHWSymbols, NULL); /* * Allocate a vgaHWRec */ @@ -1658,17 +1705,8 @@ TsengPreInit(ScrnInfoPtr pScrn, int flags) } } /* Set the default visual. */ - if (!xf86SetDefaultVisual(pScrn, -1)) { + if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; - } else { - /* Tseng doesn't 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; - } - } /* The gamma fields must be initialised when using the new cmap code */ if (pScrn->depth > 1) { @@ -1782,43 +1820,46 @@ TsengPreInit(ScrnInfoPtr pScrn, int flags) /* Load bpp-specific modules */ switch (pScrn->bitsPerPixel) { case 1: - mod = "xf1bpp"; + if (xf86LoadSubModule(pScrn, "xf1bpp") == NULL) { + TsengFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols("xf1bppScreenInit", NULL); break; case 4: - mod = "xf4bpp"; - break; - case 8: - mod = "cfb"; - break; - case 16: - mod = "cfb16"; - break; - case 24: - if (pix24bpp == 24) - mod = "cfb24"; - else - mod = "xf24_32bpp"; - break; - case 32: - mod = "cfb32"; + if (xf86LoadSubModule(pScrn, "xf4bpp") == NULL) { + TsengFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols("xf4bppScreenInit", NULL); break; + default: + if (xf86LoadSubModule(pScrn, "fb") == NULL) { + TsengFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols("fbScreenInit", NULL); +#ifdef RENDER + xf86LoaderReqSymbols("fbPictureInit", NULL); +#endif + break; } - if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { - TsengFreeRec(pScrn); - return FALSE; - } + /* Load XAA if needed */ if (pTseng->UseAccel) if (!xf86LoadSubModule(pScrn, "xaa")) { TsengFreeRec(pScrn); return FALSE; } + xf86LoaderReqSymLists(xaaSymbols, NULL); /* Load ramdac if needed */ - if (pTseng->HWCursor) + if (pTseng->HWCursor) { if (!xf86LoadSubModule(pScrn, "ramdac")) { TsengFreeRec(pScrn); return FALSE; } + xf86LoaderReqSymLists(ramdacSymbols, NULL); + } /* TsengLock(); */ return TRUE; @@ -1981,18 +2022,6 @@ TsengScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* XXX Fill the screen with black */ /* - * 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(); @@ -2005,16 +2034,11 @@ TsengScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) * miSetVisualTypes for each visual supported. */ - if (pScrn->depth > 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 (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, + pScrn->defaultVisual)) + return FALSE; + + miSetPixmapDepths (); /* * Call the framebuffer layer's ScreenInit function, and fill in other @@ -2034,36 +2058,15 @@ TsengScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); break; - case 8: - ret = cfbScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX, - pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 16: - ret = cfb16ScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX, - pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 24: - if (pix24bpp == 24) - ret = cfb24ScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX, - pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - else - ret = cfb24_32ScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX, - pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; - case 32: - ret = cfb32ScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX, - pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, - pScrn->displayWidth); - break; default: - xf86DrvMsg(scrnIndex, X_ERROR, - "Internal error: invalid bpp (%d) in TsengScrnInit\n", - pScrn->bitsPerPixel); - ret = FALSE; + ret = fbScreenInit(pScreen, pTseng->FbBase, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth, pScrn->bitsPerPixel); +#ifdef RENDER + if (ret) + fbPictureInit(pScreen, 0, 0); +#endif break; } if (!ret) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c b/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c index 558652a18..494075d00 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c @@ -26,7 +26,7 @@ * * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br> * - * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c,v 1.4 2000/10/27 18:31:04 dawes Exp $ + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vesa/vesa.c,v 1.5 2000/10/29 14:24:12 tsi Exp $ */ #include "vesa.h" @@ -118,7 +118,7 @@ static IsaChipsets VESAISAchipsets[] = { }; typedef enum { - OPTION_SHADOW_FB, + OPTION_SHADOW_FB } VESAOpts; static OptionInfoRec VESAOptions[] = { diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c b/xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c index 9726b8219..9649216b3 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c,v 1.45 2000/08/04 16:13:37 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c,v 1.46 2000/11/03 18:46:15 eich Exp $ */ /* * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved. * @@ -776,10 +776,6 @@ GenericEnterGraphics(ScreenPtr pScreen, ScrnInfoPtr pScreenInfo) { vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo); - /* Map VGA aperture */ - if (!vgaHWMapMem(pScreenInfo)) - return FALSE; - /* Unlock VGA registers */ vgaHWUnlock(pvgaHW); @@ -804,7 +800,6 @@ GenericLeaveGraphics(ScrnInfoPtr pScreenInfo) { GenericRestore(pScreenInfo); vgaHWLock(VGAHWPTR(pScreenInfo)); - vgaHWUnmapMem(pScreenInfo); } @@ -829,6 +824,7 @@ GenericCloseScreen(int scrnIndex, ScreenPtr pScreen) GenericLeaveGraphics(pScreenInfo); pScreenInfo->vtSema = FALSE; } + vgaHWUnmapMem(pScreenInfo); return Closed; } @@ -1066,6 +1062,9 @@ GenericScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Get driver private */ pGenericPriv = GenericGetRec(pScreenInfo); + /* Map VGA aperture */ + if (!vgaHWMapMem(pScreenInfo)) + return FALSE; /* Initialise graphics mode */ if (!GenericEnterGraphics(pScreen, pScreenInfo)) |