tga_driver.c revision 7706df26
17706df26Smrg/*
27706df26Smrg * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
37706df26Smrg *
47706df26Smrg * Permission to use, copy, modify, distribute, and sell this software and its
57706df26Smrg * documentation for any purpose is hereby granted without fee, provided that
67706df26Smrg * the above copyright notice appear in all copies and that both that
77706df26Smrg * copyright notice and this permission notice appear in supporting
87706df26Smrg * documentation, and that the name of Alan Hourihane not be used in
97706df26Smrg * advertising or publicity pertaining to distribution of the software without
107706df26Smrg * specific, written prior permission.  Alan Hourihane makes no representations
117706df26Smrg * about the suitability of this software for any purpose.  It is provided
127706df26Smrg * "as is" without express or implied warranty.
137706df26Smrg *
147706df26Smrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
157706df26Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
167706df26Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
177706df26Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
187706df26Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
197706df26Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
207706df26Smrg * PERFORMANCE OF THIS SOFTWARE.
217706df26Smrg *
227706df26Smrg * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
237706df26Smrg *           Matthew Grossman, <mattg@oz.net> - acceleration and misc fixes
247706df26Smrg */
257706df26Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c,v 1.60tsi Exp $ */
267706df26Smrg
277706df26Smrg#ifdef HAVE_CONFIG_H
287706df26Smrg#include "config.h"
297706df26Smrg#endif
307706df26Smrg
317706df26Smrg#include <string.h>
327706df26Smrg
337706df26Smrg/* everybody includes these */
347706df26Smrg#include "xf86.h"
357706df26Smrg#include "xf86_OSproc.h"
367706df26Smrg
377706df26Smrg/* PCI headers */
387706df26Smrg#include "xf86PciInfo.h"
397706df26Smrg#include "xf86Pci.h"
407706df26Smrg
417706df26Smrg/* module versioning */
427706df26Smrg#include "xf86Version.h"
437706df26Smrg
447706df26Smrg/* RAC stuff */
457706df26Smrg#include "xf86Resources.h"
467706df26Smrg
477706df26Smrg/*  #include "vgaHW.h" */
487706df26Smrg
497706df26Smrg/* software cursor */
507706df26Smrg#include "mipointer.h"
517706df26Smrg/* backing store */
527706df26Smrg#include "mibstore.h"
537706df26Smrg
547706df26Smrg/*  #include "mibank.h" */
557706df26Smrg/* colormap manipulation */
567706df26Smrg#include "micmap.h"
577706df26Smrg
587706df26Smrg#include "fb.h"
597706df26Smrg
607706df26Smrg/* more RAC stuff */
617706df26Smrg#include "xf86RAC.h"
627706df26Smrg
637706df26Smrg/* Gamma Correction? */
647706df26Smrg#include "xf86cmap.h"
657706df26Smrg
667706df26Smrg#include "tga_regs.h"
677706df26Smrg#include "BT.h"
687706df26Smrg#include "tga.h"
697706df26Smrg
707706df26Smrg#ifdef XFreeXDGA
717706df26Smrg#define _XF86DGA_SERVER_
727706df26Smrg#include <X11/extensions/xf86dgastr.h>
737706df26Smrg#endif
747706df26Smrg
757706df26Smrg#include "globals.h"
767706df26Smrg#define DPMS_SERVER
777706df26Smrg#include <X11/extensions/dpms.h>
787706df26Smrg
797706df26Smrg#include "xf86xv.h"
807706df26Smrg#include <X11/extensions/Xv.h>
817706df26Smrg
827706df26Smrgstatic const OptionInfoRec * TGAAvailableOptions(int chipid, int busid);
837706df26Smrgstatic void	TGAIdentify(int flags);
847706df26Smrgstatic Bool	TGAProbe(DriverPtr drv, int flags);
857706df26Smrgstatic Bool	TGAPreInit(ScrnInfoPtr pScrn, int flags);
867706df26Smrgstatic Bool	TGAScreenInit(int Index, ScreenPtr pScreen, int argc,
877706df26Smrg			      char **argv);
887706df26Smrgstatic Bool	TGAEnterVT(int scrnIndex, int flags);
897706df26Smrgstatic void	TGALeaveVT(int scrnIndex, int flags);
907706df26Smrgstatic Bool	TGACloseScreen(int scrnIndex, ScreenPtr pScreen);
917706df26Smrgstatic Bool	TGASaveScreen(ScreenPtr pScreen, int mode);
927706df26Smrg
937706df26Smrg/* Required if the driver supports mode switching */
947706df26Smrgstatic Bool	TGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
957706df26Smrg/* Required if the driver supports moving the viewport */
967706df26Smrgstatic void	TGAAdjustFrame(int scrnIndex, int x, int y, int flags);
977706df26Smrg
987706df26Smrg/* Optional functions */
997706df26Smrgstatic void	TGAFreeScreen(int scrnIndex, int flags);
1007706df26Smrgstatic ModeStatus TGAValidMode(int scrnIndex, DisplayModePtr mode,
1017706df26Smrg			       Bool verbose, int flags);
1027706df26Smrg
1037706df26Smrg/* Internally used functions */
1047706df26Smrgstatic Bool	TGAMapMem(ScrnInfoPtr pScrn);
1057706df26Smrgstatic Bool	TGAUnmapMem(ScrnInfoPtr pScrn);
1067706df26Smrgstatic void	TGASave(ScrnInfoPtr pScrn);
1077706df26Smrgstatic void	TGARestore(ScrnInfoPtr pScrn);
1087706df26Smrgstatic Bool	TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
1097706df26Smrg
1107706df26Smrgstatic void     TGARestoreHWCursor(ScrnInfoPtr pScrn);
1117706df26Smrg
1127706df26Smrgstatic void TGADisplayPowerManagementSet(ScrnInfoPtr pScrn,
1137706df26Smrg					 int PowerManagementMode,
1147706df26Smrg					 int flags);
1157706df26Smrg
1167706df26Smrgvoid TGASync(ScrnInfoPtr pScrn);
1177706df26Smrg
1187706df26Smrg#define TGA_VERSION 4000
1197706df26Smrg#define TGA_NAME "TGA"
1207706df26Smrg#define TGA_DRIVER_NAME "tga"
1217706df26Smrg#define TGA_MAJOR_VERSION 1
1227706df26Smrg#define TGA_MINOR_VERSION 1
1237706df26Smrg#define TGA_PATCHLEVEL 0
1247706df26Smrg
1257706df26Smrg/*
1267706df26Smrg * This contains the functions needed by the server after loading the driver
1277706df26Smrg * module.  It must be supplied, and gets passed back by the SetupProc
1287706df26Smrg * function in the dynamic case.  In the static case, a reference to this
1297706df26Smrg * is compiled in, and this requires that the name of this DriverRec be
1307706df26Smrg * an upper-case version of the driver name.
1317706df26Smrg */
1327706df26Smrg
1337706df26Smrg_X_EXPORT DriverRec TGA = {
1347706df26Smrg    TGA_VERSION,
1357706df26Smrg    TGA_DRIVER_NAME,
1367706df26Smrg    TGAIdentify,
1377706df26Smrg    TGAProbe,
1387706df26Smrg    TGAAvailableOptions,
1397706df26Smrg    NULL,
1407706df26Smrg    0
1417706df26Smrg};
1427706df26Smrg
1437706df26Smrgstatic SymTabRec TGAChipsets[] = {
1447706df26Smrg    { PCI_CHIP_DEC21030,		"tga" },
1457706df26Smrg    { PCI_CHIP_TGA2,			"tga2" },
1467706df26Smrg    { -1,				NULL }
1477706df26Smrg};
1487706df26Smrg
1497706df26Smrgstatic PciChipsets TGAPciChipsets[] = {
1507706df26Smrg    { PCI_CHIP_DEC21030,	PCI_CHIP_DEC21030,	NULL },
1517706df26Smrg    { PCI_CHIP_TGA2,		PCI_CHIP_TGA2,		NULL },
1527706df26Smrg    { -1,			-1,			RES_UNDEFINED }
1537706df26Smrg};
1547706df26Smrg
1557706df26Smrgtypedef enum {
1567706df26Smrg    OPTION_SW_CURSOR,
1577706df26Smrg    OPTION_HW_CURSOR,
1587706df26Smrg    OPTION_PCI_RETRY,
1597706df26Smrg    OPTION_RGB_BITS,
1607706df26Smrg    OPTION_NOACCEL,
1617706df26Smrg    OPTION_SYNC_ON_GREEN,
1627706df26Smrg    OPTION_DAC_6_BIT,
1637706df26Smrg    OPTION_NOXAAPOLYSEGMENT
1647706df26Smrg} TGAOpts;
1657706df26Smrg
1667706df26Smrgstatic const OptionInfoRec TGAOptions[] = {
1677706df26Smrg    { OPTION_SW_CURSOR,		"SWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
1687706df26Smrg    { OPTION_HW_CURSOR,		"HWcursor",	OPTV_BOOLEAN,	{0}, FALSE },
1697706df26Smrg    { OPTION_PCI_RETRY,		"PciRetry",	OPTV_BOOLEAN,	{0}, FALSE },
1707706df26Smrg    { OPTION_RGB_BITS,		"RGBbits",	OPTV_INTEGER,	{0}, FALSE },
1717706df26Smrg    { OPTION_NOACCEL,		"NoAccel",	OPTV_BOOLEAN,	{0}, FALSE },
1727706df26Smrg    { OPTION_SYNC_ON_GREEN,     "SyncOnGreen",  OPTV_BOOLEAN,   {0}, FALSE },
1737706df26Smrg    { OPTION_DAC_6_BIT,         "Dac6Bit",      OPTV_BOOLEAN,   {0}, FALSE },
1747706df26Smrg    { OPTION_NOXAAPOLYSEGMENT,  "NoXaaPolySegment",OPTV_BOOLEAN,{0}, FALSE },
1757706df26Smrg    { -1,			NULL,		OPTV_NONE,	{0}, FALSE }
1767706df26Smrg};
1777706df26Smrg
1787706df26Smrgstatic RamDacSupportedInfoRec BTramdacs[] = {
1797706df26Smrg    { BT485_RAMDAC },
1807706df26Smrg    { -1 }
1817706df26Smrg};
1827706df26Smrg
1837706df26Smrgstatic const char *ramdacSymbols[] = {
1847706df26Smrg    "BTramdacProbe",
1857706df26Smrg    "RamDacCreateInfoRec",
1867706df26Smrg    "RamDacDestroyInfoRec",
1877706df26Smrg    "RamDacFreeRec",
1887706df26Smrg    "RamDacGetHWIndex",
1897706df26Smrg    "RamDacHandleColormaps",
1907706df26Smrg    "RamDacInit",
1917706df26Smrg    "xf86CreateCursorInfoRec",
1927706df26Smrg    "xf86InitCursor",
1937706df26Smrg    NULL
1947706df26Smrg};
1957706df26Smrg
1967706df26Smrgstatic const char *xaaSymbols[] = {
1977706df26Smrg    "XAACreateInfoRec",
1987706df26Smrg    "XAADestroyInfoRec",
1997706df26Smrg    "XAAGetGCIndex",
2007706df26Smrg    "XAAInit",
2017706df26Smrg    NULL
2027706df26Smrg};
2037706df26Smrg
2047706df26Smrgstatic const char *fbSymbols[] = {
2057706df26Smrg    "fbPictureInit",
2067706df26Smrg    "fbScreenInit",
2077706df26Smrg    NULL
2087706df26Smrg};
2097706df26Smrg
2107706df26Smrg#ifdef XFree86LOADER
2117706df26Smrg
2127706df26Smrgstatic MODULESETUPPROTO(tgaSetup);
2137706df26Smrg
2147706df26Smrgstatic XF86ModuleVersionInfo tgaVersRec =
2157706df26Smrg{
2167706df26Smrg	"tga",
2177706df26Smrg	MODULEVENDORSTRING,
2187706df26Smrg	MODINFOSTRING1,
2197706df26Smrg	MODINFOSTRING2,
2207706df26Smrg	XORG_VERSION_CURRENT,
2217706df26Smrg	TGA_MAJOR_VERSION, TGA_MINOR_VERSION, TGA_PATCHLEVEL,
2227706df26Smrg	ABI_CLASS_VIDEODRV,			/* This is a video driver */
2237706df26Smrg	ABI_VIDEODRV_VERSION,
2247706df26Smrg	MOD_CLASS_VIDEODRV,
2257706df26Smrg	{0,0,0,0}
2267706df26Smrg};
2277706df26Smrg
2287706df26Smrg_X_EXPORT XF86ModuleData tgaModuleData = { &tgaVersRec, tgaSetup, NULL };
2297706df26Smrg
2307706df26Smrgpointer
2317706df26SmrgtgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
2327706df26Smrg{
2337706df26Smrg    static Bool setupDone = FALSE;
2347706df26Smrg
2357706df26Smrg    if (!setupDone) {
2367706df26Smrg	setupDone = TRUE;
2377706df26Smrg	xf86AddDriver(&TGA, module, 0);
2387706df26Smrg
2397706df26Smrg	/*
2407706df26Smrg	 * Modules that this driver always requires can be loaded here
2417706df26Smrg	 * by calling LoadSubModule().
2427706df26Smrg	 */
2437706df26Smrg
2447706df26Smrg	LoaderRefSymLists(ramdacSymbols, fbSymbols, xaaSymbols, NULL);
2457706df26Smrg
2467706df26Smrg	/*
2477706df26Smrg	 * The return value must be non-NULL on success even though there
2487706df26Smrg	 * is no TearDownProc.
2497706df26Smrg	 */
2507706df26Smrg	return (pointer)1;
2517706df26Smrg    } else {
2527706df26Smrg	if (errmaj) *errmaj = LDR_ONCEONLY;
2537706df26Smrg	return NULL;
2547706df26Smrg    }
2557706df26Smrg}
2567706df26Smrg
2577706df26Smrg#endif /* XFree86LOADER */
2587706df26Smrg
2597706df26Smrgstatic unsigned int fb_offset_presets[4] = {
2607706df26Smrg	TGA_8PLANE_FB_OFFSET,
2617706df26Smrg	TGA_24PLANE_FB_OFFSET,
2627706df26Smrg	0xffffffff,
2637706df26Smrg	TGA_24PLUSZ_FB_OFFSET
2647706df26Smrg};
2657706df26Smrg
2667706df26Smrgstatic char *tga_cardnames[4] = {
2677706df26Smrg	"TGA 8 Plane",
2687706df26Smrg	"TGA 24 Plane",
2697706df26Smrg	NULL,
2707706df26Smrg	"TGA 24 Plane 3D"
2717706df26Smrg};
2727706df26Smrg
2737706df26Smrgstatic Bool
2747706df26SmrgTGAGetRec(ScrnInfoPtr pScrn)
2757706df26Smrg{
2767706df26Smrg    /*
2777706df26Smrg     * Allocate an TGARec, and hook it into pScrn->driverPrivate.
2787706df26Smrg     * pScrn->driverPrivate is initialised to NULL, so we can check if
2797706df26Smrg     * the allocation has already been done.
2807706df26Smrg     */
2817706df26Smrg    if (pScrn->driverPrivate != NULL)
2827706df26Smrg	return TRUE;
2837706df26Smrg
2847706df26Smrg    pScrn->driverPrivate = xnfcalloc(sizeof(TGARec), 1);
2857706df26Smrg    /* Initialise it */
2867706df26Smrg
2877706df26Smrg
2887706df26Smrg    return TRUE;
2897706df26Smrg}
2907706df26Smrg
2917706df26Smrgstatic void
2927706df26SmrgTGAFreeRec(ScrnInfoPtr pScrn)
2937706df26Smrg{
2947706df26Smrg    TGAPtr pTga;
2957706df26Smrg
2967706df26Smrg    if (pScrn->driverPrivate == NULL)
2977706df26Smrg	return;
2987706df26Smrg
2997706df26Smrg    pTga = TGAPTR(pScrn);
3007706df26Smrg
3017706df26Smrg    if(pTga->buffers[0])
3027706df26Smrg      free(pTga->buffers[0]);
3037706df26Smrg
3047706df26Smrg    xfree(pScrn->driverPrivate);
3057706df26Smrg    pScrn->driverPrivate = NULL;
3067706df26Smrg
3077706df26Smrg    return;
3087706df26Smrg}
3097706df26Smrg
3107706df26Smrgstatic const OptionInfoRec *
3117706df26SmrgTGAAvailableOptions(int chipid, int busid)
3127706df26Smrg{
3137706df26Smrg    return TGAOptions;
3147706df26Smrg}
3157706df26Smrg
3167706df26Smrg/* Mandatory */
3177706df26Smrgstatic void
3187706df26SmrgTGAIdentify(int flags)
3197706df26Smrg{
3207706df26Smrg    xf86PrintChipsets(TGA_NAME, "driver for Digital chipsets", TGAChipsets);
3217706df26Smrg    return;
3227706df26Smrg}
3237706df26Smrg
3247706df26Smrg
3257706df26Smrg/* Mandatory */
3267706df26Smrgstatic Bool
3277706df26SmrgTGAProbe(DriverPtr drv, int flags)
3287706df26Smrg{
3297706df26Smrg    int i;
3307706df26Smrg    GDevPtr *devSections;
3317706df26Smrg    int *usedChips;
3327706df26Smrg    int numDevSections;
3337706df26Smrg    int numUsed;
3347706df26Smrg    Bool foundScreen = FALSE;
3357706df26Smrg
3367706df26Smrg    /*
3377706df26Smrg     * The aim here is to find all cards that this driver can handle,
3387706df26Smrg     * and for the ones not already claimed by another driver, claim the
3397706df26Smrg     * slot, and allocate a ScrnInfoRec.
3407706df26Smrg     *
3417706df26Smrg     * This should be a minimal probe, and it should under no circumstances
3427706df26Smrg     * change the state of the hardware.  Because a device is found, don't
3437706df26Smrg     * assume that it will be used.  Don't do any initialisations other than
3447706df26Smrg     * the required ScrnInfoRec initialisations.  Don't allocate any new
3457706df26Smrg     * data structures.
3467706df26Smrg     */
3477706df26Smrg
3487706df26Smrg    /*
3497706df26Smrg     * Next we check, if there has been a chipset override in the config file.
3507706df26Smrg     * For this we must find out if there is an active device section which
3517706df26Smrg     * is relevant, i.e., which has no driver specified or has THIS driver
3527706df26Smrg     * specified.
3537706df26Smrg     */
3547706df26Smrg
3557706df26Smrg    if ((numDevSections = xf86MatchDevice(TGA_DRIVER_NAME,
3567706df26Smrg					  &devSections)) <= 0) {
3577706df26Smrg	/*
3587706df26Smrg	 * There's no matching device section in the config file, so quit
3597706df26Smrg	 * now.
3607706df26Smrg	 */
3617706df26Smrg	return FALSE;
3627706df26Smrg    }
3637706df26Smrg
3647706df26Smrg    /*
3657706df26Smrg     * We need to probe the hardware first.  We then need to see how this
3667706df26Smrg     * fits in with what is given in the config file, and allow the config
3677706df26Smrg     * file info to override any contradictions.
3687706df26Smrg     */
3697706df26Smrg
3707706df26Smrg    /*
3717706df26Smrg     * All of the cards this driver supports are PCI, so the "probing" just
3727706df26Smrg     * amounts to checking the PCI data that the server has already collected.
3737706df26Smrg     */
3747706df26Smrg    if (xf86GetPciVideoInfo() == NULL) {
3757706df26Smrg	/*
3767706df26Smrg	 * We won't let anything in the config file override finding no
3777706df26Smrg	 * PCI video cards at all.  This seems reasonable now, but we'll see.
3787706df26Smrg	 */
3797706df26Smrg	return FALSE;
3807706df26Smrg    }
3817706df26Smrg
3827706df26Smrg    numUsed = xf86MatchPciInstances(TGA_NAME, PCI_VENDOR_DIGITAL,
3837706df26Smrg		   TGAChipsets, TGAPciChipsets, devSections, numDevSections,
3847706df26Smrg		   drv, &usedChips);
3857706df26Smrg
3867706df26Smrg    xfree(devSections);
3877706df26Smrg    if (numUsed <= 0)
3887706df26Smrg	return FALSE;
3897706df26Smrg
3907706df26Smrg    if (flags & PROBE_DETECT)
3917706df26Smrg	foundScreen = TRUE;
3927706df26Smrg    else for (i = 0; i < numUsed; i++) {
3937706df26Smrg	/*
3947706df26Smrg	 * Check that nothing else has claimed the slots.
3957706df26Smrg	 */
3967706df26Smrg	ScrnInfoPtr pScrn = NULL;
3977706df26Smrg
3987706df26Smrg	/* Allocate a ScrnInfoRec and claim the slot */
3997706df26Smrg	if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
4007706df26Smrg					       TGAPciChipsets, NULL, NULL,
4017706df26Smrg					       NULL, NULL, NULL))) {
4027706df26Smrg	    /* Fill in what we can of the ScrnInfoRec */
4037706df26Smrg	    pScrn->driverVersion = TGA_VERSION;
4047706df26Smrg	    pScrn->driverName	 = TGA_DRIVER_NAME;
4057706df26Smrg	    pScrn->name		 = TGA_NAME;
4067706df26Smrg	    pScrn->Probe	 = TGAProbe;
4077706df26Smrg	    pScrn->PreInit	 = TGAPreInit;
4087706df26Smrg	    pScrn->ScreenInit	 = TGAScreenInit;
4097706df26Smrg  	    pScrn->SwitchMode	 = TGASwitchMode;
4107706df26Smrg  	    pScrn->AdjustFrame	 = TGAAdjustFrame;
4117706df26Smrg	    pScrn->EnterVT	 = TGAEnterVT;
4127706df26Smrg	    pScrn->LeaveVT	 = TGALeaveVT;
4137706df26Smrg	    pScrn->FreeScreen	 = TGAFreeScreen;
4147706df26Smrg	    pScrn->ValidMode	 = TGAValidMode;
4157706df26Smrg	    foundScreen = TRUE;
4167706df26Smrg	}
4177706df26Smrg    }
4187706df26Smrg    xfree(usedChips);
4197706df26Smrg    return foundScreen;
4207706df26Smrg}
4217706df26Smrg
4227706df26Smrg#if 0
4237706df26Smrg/*
4247706df26Smrg * GetAccelPitchValues -
4257706df26Smrg *
4267706df26Smrg * This function returns a list of display width (pitch) values that can
4277706df26Smrg * be used in accelerated mode.
4287706df26Smrg */
4297706df26Smrgstatic int *
4307706df26SmrgGetAccelPitchValues(ScrnInfoPtr pScrn)
4317706df26Smrg{
4327706df26Smrg    int *linePitches = NULL;
4337706df26Smrg    int i, n = 0;
4347706df26Smrg    int *linep = NULL;
4357706df26Smrg    /*     TGAPtr pTga = TGAPTR(pScrn); */
4367706df26Smrg
4377706df26Smrg    for (i = 0; linep[i] != 0; i++) {
4387706df26Smrg	if (linep[i] != -1) {
4397706df26Smrg	    n++;
4407706df26Smrg	    linePitches = xnfrealloc(linePitches, n * sizeof(int));
4417706df26Smrg	    linePitches[n - 1] = i << 5;
4427706df26Smrg	}
4437706df26Smrg    }
4447706df26Smrg
4457706df26Smrg    /* Mark the end of the list */
4467706df26Smrg    if (n > 0) {
4477706df26Smrg	linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
4487706df26Smrg	linePitches[n] = 0;
4497706df26Smrg    }
4507706df26Smrg    return linePitches;
4517706df26Smrg}
4527706df26Smrg#endif /* 0 */
4537706df26Smrg
4547706df26Smrg/* Mandatory */
4557706df26Smrgstatic Bool
4567706df26SmrgTGAPreInit(ScrnInfoPtr pScrn, int flags)
4577706df26Smrg{
4587706df26Smrg    pciVideoPtr pciPtr;
4597706df26Smrg    TGAPtr pTga;
4607706df26Smrg    MessageType from;
4617706df26Smrg    int i;
4627706df26Smrg    ClockRangePtr clockRanges;
4637706df26Smrg    pointer Base;
4647706df26Smrg
4657706df26Smrg    if (flags & PROBE_DETECT) return FALSE;
4667706df26Smrg
4677706df26Smrg    /*
4687706df26Smrg     * Note: This function is only called once at server startup, and
4697706df26Smrg     * not at the start of each server generation.  This means that
4707706df26Smrg     * only things that are persistent across server generations can
4717706df26Smrg     * be initialised here.  xf86Screens[] is (pScrn is a pointer to one
4727706df26Smrg     * of these).  Privates allocated using xf86AllocateScrnInfoPrivateIndex()
4737706df26Smrg     * are too, and should be used for data that must persist across
4747706df26Smrg     * server generations.
4757706df26Smrg     *
4767706df26Smrg     * Per-generation data should be allocated with
4777706df26Smrg     * AllocateScreenPrivateIndex() from the ScreenInit() function.
4787706df26Smrg     */
4797706df26Smrg
4807706df26Smrg    /* The ramdac module should be loaded here when needed */
4817706df26Smrg    if (!xf86LoadSubModule(pScrn, "ramdac"))
4827706df26Smrg	return FALSE;
4837706df26Smrg
4847706df26Smrg    xf86LoaderReqSymLists(ramdacSymbols, NULL);
4857706df26Smrg
4867706df26Smrg    /* Allocate the TGARec driverPrivate */
4877706df26Smrg    if (!TGAGetRec(pScrn)) {
4887706df26Smrg	return FALSE;
4897706df26Smrg    }
4907706df26Smrg    pTga = TGAPTR(pScrn);
4917706df26Smrg
4927706df26Smrg    /* Set pScrn->monitor */
4937706df26Smrg    pScrn->monitor = pScrn->confScreen->monitor;
4947706df26Smrg
4957706df26Smrg    /*********************
4967706df26Smrg    Handle pci and chipset stuff
4977706df26Smrg    *********************/
4987706df26Smrg
4997706df26Smrg
5007706df26Smrg    /* This driver doesn't expect more than one entity per screen */
5017706df26Smrg    if (pScrn->numEntities > 1)
5027706df26Smrg	return FALSE;
5037706df26Smrg    /* This is the general case */
5047706df26Smrg    for (i = 0; i < pScrn->numEntities; i++) {
5057706df26Smrg	pTga->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
5067706df26Smrg	if (pTga->pEnt->resources) return FALSE;
5077706df26Smrg	pTga->Chipset = pTga->pEnt->chipset;
5087706df26Smrg	pScrn->chipset = (char *)xf86TokenToString(TGAChipsets,
5097706df26Smrg						   pTga->pEnt->chipset);
5107706df26Smrg
5117706df26Smrg	/* TGA is purely PCI */
5127706df26Smrg	if (pTga->pEnt->location.type == BUS_PCI) {
5137706df26Smrg	    pciPtr = xf86GetPciInfoForEntity(pTga->pEnt->index);
5147706df26Smrg	    pTga->PciInfo = pciPtr;
5157706df26Smrg	    pTga->PciTag = pciTag(pTga->PciInfo->bus,
5167706df26Smrg				  pTga->PciInfo->device,
5177706df26Smrg				  pTga->PciInfo->func);
5187706df26Smrg	}
5197706df26Smrg	else
5207706df26Smrg	    return FALSE;
5217706df26Smrg    }
5227706df26Smrg
5237706df26Smrg    /*
5247706df26Smrg     * This shouldn't happen because such problems should be caught in
5257706df26Smrg     * TGAProbe(), but check it just in case.
5267706df26Smrg     */
5277706df26Smrg    if (pScrn->chipset == NULL) {
5287706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
5297706df26Smrg		   "ChipID 0x%04X is not recognised\n", pTga->Chipset);
5307706df26Smrg	return FALSE;
5317706df26Smrg    }
5327706df26Smrg    if (pTga->Chipset < 0) {
5337706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
5347706df26Smrg		   "Chipset \"%s\" is not recognised\n", pScrn->chipset);
5357706df26Smrg	return FALSE;
5367706df26Smrg    }
5377706df26Smrg
5387706df26Smrg    from = X_PROBED;
5397706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
5407706df26Smrg
5417706df26Smrg    pTga->PciTag = pciTag(pTga->PciInfo->bus, pTga->PciInfo->device,
5427706df26Smrg			  pTga->PciInfo->func);
5437706df26Smrg
5447706df26Smrg
5457706df26Smrg
5467706df26Smrg    /*********************
5477706df26Smrg    deal with depth and framebuffer size
5487706df26Smrg    *********************/
5497706df26Smrg
5507706df26Smrg    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
5517706df26Smrg	return FALSE;
5527706df26Smrg    } else {
5537706df26Smrg	/* Check that the returned depth is one we support */
5547706df26Smrg	switch (pScrn->depth) {
5557706df26Smrg	case 8:
5567706df26Smrg	case 24:
5577706df26Smrg	    /* OK */
5587706df26Smrg	    break;
5597706df26Smrg	default:
5607706df26Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
5617706df26Smrg		       "Given depth (%d) is not supported by this driver\n",
5627706df26Smrg		       pScrn->depth);
5637706df26Smrg	    return FALSE;
5647706df26Smrg	}
5657706df26Smrg    }
5667706df26Smrg
5677706df26Smrg    /* we can do option processing now */
5687706df26Smrg
5697706df26Smrg    /* Collect all of the relevant option flags (fill in pScrn->options) */
5707706df26Smrg    xf86CollectOptions(pScrn, NULL);
5717706df26Smrg    /* Process the options */
5727706df26Smrg    if (!(pTga->Options = xalloc(sizeof(TGAOptions))))
5737706df26Smrg	return FALSE;
5747706df26Smrg    memcpy(pTga->Options, TGAOptions, sizeof(TGAOptions));
5757706df26Smrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTga->Options);
5767706df26Smrg    if (xf86ReturnOptValBool(pTga->Options, OPTION_PCI_RETRY, FALSE)) {
5777706df26Smrg	pTga->UsePCIRetry = TRUE;
5787706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
5797706df26Smrg    }
5807706df26Smrg
5817706df26Smrg    if(xf86ReturnOptValBool(pTga->Options, OPTION_SYNC_ON_GREEN, FALSE)) {
5827706df26Smrg	pTga->SyncOnGreen = TRUE;
5837706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n");
5847706df26Smrg    }
5857706df26Smrg
5867706df26Smrg    if(xf86ReturnOptValBool(pTga->Options, OPTION_DAC_6_BIT, FALSE)) {
5877706df26Smrg	pTga->Dac6Bit = TRUE;
5887706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "6 bit DAC enabled\n");
5897706df26Smrg    }
5907706df26Smrg
5917706df26Smrg    if(xf86ReturnOptValBool(pTga->Options, OPTION_NOXAAPOLYSEGMENT, FALSE)) {
5927706df26Smrg	pTga->NoXaaPolySegment = TRUE;
5937706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "XAA PolySegment() disabled\n");
5947706df26Smrg    }
5957706df26Smrg
5967706df26Smrg    /* end option processing */
5977706df26Smrg
5987706df26Smrg    /*
5997706df26Smrg     * This must happen after pScrn->display has been set because
6007706df26Smrg     * xf86SetWeight references it.
6017706df26Smrg     */
6027706df26Smrg    if (pScrn->depth > 8) {
6037706df26Smrg	/* The defaults are OK for us */
6047706df26Smrg	rgb zeros = {0, 0, 0};
6057706df26Smrg
6067706df26Smrg	if (!xf86SetWeight(pScrn, zeros, zeros)) {
6077706df26Smrg	    return FALSE;
6087706df26Smrg	} else {
6097706df26Smrg	    /* XXX check that weight returned is supported */
6107706df26Smrg            ;
6117706df26Smrg        }
6127706df26Smrg    }
6137706df26Smrg
6147706df26Smrg    if (!xf86SetDefaultVisual(pScrn, -1)) {
6157706df26Smrg	return FALSE;
6167706df26Smrg    } else {
6177706df26Smrg	/* We don't currently support DirectColor at > 8bpp */
6187706df26Smrg	if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
6197706df26Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
6207706df26Smrg		       " (%s) is not supported at depth %d\n",
6217706df26Smrg		       xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
6227706df26Smrg	    return FALSE;
6237706df26Smrg	}
6247706df26Smrg    }
6257706df26Smrg
6267706df26Smrg    /*
6277706df26Smrg     * The new cmap code requires this to be initialised.
6287706df26Smrg     */
6297706df26Smrg
6307706df26Smrg    {
6317706df26Smrg	Gamma zeros = {0.0, 0.0, 0.0};
6327706df26Smrg
6337706df26Smrg	if (!xf86SetGamma(pScrn, zeros)) {
6347706df26Smrg	    return FALSE;
6357706df26Smrg	}
6367706df26Smrg    }
6377706df26Smrg
6387706df26Smrg    /* Set the bits per RGB for 8bpp mode */
6397706df26Smrg    if (pScrn->depth == 8) {
6407706df26Smrg	/* Default to 8 */
6417706df26Smrg	pScrn->rgbBits = 8;
6427706df26Smrg	if(pTga->Dac6Bit)
6437706df26Smrg	    pScrn->rgbBits = 6;
6447706df26Smrg    }
6457706df26Smrg    from = X_DEFAULT;
6467706df26Smrg
6477706df26Smrg    /* determine whether we use hardware or software cursor */
6487706df26Smrg
6497706df26Smrg    pTga->HWCursor = TRUE;
6507706df26Smrg    if (xf86GetOptValBool(pTga->Options, OPTION_HW_CURSOR, &pTga->HWCursor))
6517706df26Smrg	from = X_CONFIG;
6527706df26Smrg    if (xf86ReturnOptValBool(pTga->Options, OPTION_SW_CURSOR, FALSE)) {
6537706df26Smrg	from = X_CONFIG;
6547706df26Smrg	pTga->HWCursor = FALSE;
6557706df26Smrg    }
6567706df26Smrg
6577706df26Smrg    if(pScrn->depth != 8) {
6587706df26Smrg      pTga->HWCursor = FALSE;
6597706df26Smrg      from = X_WARNING;
6607706df26Smrg      xf86DrvMsg(pScrn->scrnIndex, from,
6617706df26Smrg		 "Hardware cursor currently only works with BT485 ramdac\n");
6627706df26Smrg    }
6637706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
6647706df26Smrg		pTga->HWCursor ? "HW" : "SW");
6657706df26Smrg
6667706df26Smrg    if (xf86ReturnOptValBool(pTga->Options, OPTION_NOACCEL, FALSE)) {
6677706df26Smrg	pTga->NoAccel = TRUE;
6687706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
6697706df26Smrg    }
6707706df26Smrg
6717706df26Smrg    if (pTga->pEnt->device->MemBase != 0) {
6727706df26Smrg	pTga->CardAddress = pTga->pEnt->device->MemBase;
6737706df26Smrg	from = X_CONFIG;
6747706df26Smrg    } else {
6757706df26Smrg      pTga->CardAddress = pTga->PciInfo->memBase[0] & 0xFFC00000;/*??*/
6767706df26Smrg    }
6777706df26Smrg
6787706df26Smrg    pTga->FbAddress = pTga->CardAddress;
6797706df26Smrg    /* Adjust MMIO region */
6807706df26Smrg    pTga->IOAddress = pTga->CardAddress + TGA_REGS_OFFSET;
6817706df26Smrg
6827706df26Smrg
6837706df26Smrg    /*********************
6847706df26Smrg    determine what sort of TGA card we have -- the only differences are
6857706df26Smrg    framebuffer size and ramdac type, all TGA cards use 21030 chips
6867706df26Smrg    *********************/
6877706df26Smrg
6887706df26Smrg    /* check what the user has specified in XF86Config */
6897706df26Smrg    if(pTga->pEnt->device->videoRam) {
6907706df26Smrg      switch(pTga->pEnt->device->videoRam) {
6917706df26Smrg      case 2048:
6927706df26Smrg	pTga->CardType = TYPE_TGA_8PLANE;
6937706df26Smrg	break;
6947706df26Smrg      case 8192:
6957706df26Smrg	pTga->CardType = TYPE_TGA_24PLANE;
6967706df26Smrg	break;
6977706df26Smrg      case 16384:
6987706df26Smrg	pTga->CardType = TYPE_TGA_24PLUSZ;
6997706df26Smrg	break;
7007706df26Smrg      default:
7017706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
7027706df26Smrg		   "%d KB video RAM specified, driver only supports 2048, 8192, or 16384 KB cards\n",
7037706df26Smrg		   pTga->pEnt->device->videoRam);
7047706df26Smrg	return FALSE;
7057706df26Smrg      }
7067706df26Smrg    }
7077706df26Smrg    else { /* try to divine the amount of RAM */
7087706df26Smrg      switch (pTga->Chipset)
7097706df26Smrg	{
7107706df26Smrg	case PCI_CHIP_TGA2:
7117706df26Smrg	  Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
7127706df26Smrg			       pTga->PciTag, pTga->IOAddress, 0x1000);
7137706df26Smrg	  pTga->CardType = (*(unsigned int *)((char *)Base+TGA_REVISION_REG) >> 21) & 0x3;
7147706df26Smrg	  pTga->CardType ^= (pTga->CardType == 1) ? 0 : 3;
7157706df26Smrg	  xf86UnMapVidMem(pScrn->scrnIndex, Base, 0x1000);
7167706df26Smrg	  break;
7177706df26Smrg	case PCI_CHIP_DEC21030:
7187706df26Smrg	  Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
7197706df26Smrg			       pTga->PciTag, pTga->FbAddress, 4);
7207706df26Smrg	  pTga->CardType = (*(unsigned int *)Base >> 12) & 0xf;
7217706df26Smrg	  xf86UnMapVidMem(pScrn->scrnIndex, Base, 4);
7227706df26Smrg	  break;
7237706df26Smrg	}
7247706df26Smrg    }
7257706df26Smrg
7267706df26Smrg    switch (pTga->CardType) {
7277706df26Smrg        case TYPE_TGA_8PLANE:
7287706df26Smrg        case TYPE_TGA_24PLANE:
7297706df26Smrg        case TYPE_TGA_24PLUSZ:
7307706df26Smrg            xf86DrvMsg(pScrn->scrnIndex, from, "Card Name: \"%s\"\n",
7317706df26Smrg			tga_cardnames[pTga->CardType]);
7327706df26Smrg	    break;
7337706df26Smrg	default:
7347706df26Smrg            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
7357706df26Smrg                 "Card \"0x%02x\" is not recognised\n", pTga->CardType);
7367706df26Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
7377706df26Smrg		       "Assuming 8 plane TGA with 2MB frame buffer\n");
7387706df26Smrg	    pTga->CardType = TYPE_TGA_8PLANE;
7397706df26Smrg	    break;
7407706df26Smrg    }
7417706df26Smrg
7427706df26Smrg    /* Adjust framebuffer for card type */
7437706df26Smrg    pTga->FbAddress += fb_offset_presets[pTga->CardType];
7447706df26Smrg
7457706df26Smrg    if (!(((pScrn->depth ==  8) && (pTga->CardType == TYPE_TGA_8PLANE)) ||
7467706df26Smrg	  ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLANE)) ||
7477706df26Smrg	  ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLUSZ)))) {
7487706df26Smrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
7497706df26Smrg		   "Given depth (%d) is not supported by this card\n",
7507706df26Smrg		   pScrn->depth);
7517706df26Smrg	return FALSE;
7527706df26Smrg    }
7537706df26Smrg
7547706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
7557706df26Smrg	       (unsigned long)pTga->FbAddress);
7567706df26Smrg
7577706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
7587706df26Smrg	       (unsigned long)pTga->IOAddress);
7597706df26Smrg
7607706df26Smrg    /* RAC stuff: we don't have any resources we need to reserve,
7617706df26Smrg       but we should do this here anyway */
7627706df26Smrg    if (xf86RegisterResources(pTga->pEnt->index, NULL, ResExclusive)) {
7637706df26Smrg      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
7647706df26Smrg		 "xf86RegisterResources() found resource conflicts\n");
7657706df26Smrg      TGAFreeRec(pScrn);
7667706df26Smrg      return FALSE;
7677706df26Smrg    }
7687706df26Smrg
7697706df26Smrg
7707706df26Smrg
7717706df26Smrg    /* HW bpp matches reported bpp */
7727706df26Smrg    pTga->HwBpp = pScrn->bitsPerPixel;
7737706df26Smrg
7747706df26Smrg    if (pTga->pEnt->device->videoRam != 0) {
7757706df26Smrg	pScrn->videoRam = pTga->pEnt->device->videoRam;
7767706df26Smrg	from = X_CONFIG;
7777706df26Smrg    } else {
7787706df26Smrg      switch (pTga->CardType) {
7797706df26Smrg      case TYPE_TGA_8PLANE:
7807706df26Smrg	pScrn->videoRam = 2*1024;
7817706df26Smrg	break;
7827706df26Smrg      case TYPE_TGA_24PLANE:
7837706df26Smrg	pScrn->videoRam = 8*1024;
7847706df26Smrg	break;
7857706df26Smrg      case TYPE_TGA_24PLUSZ:
7867706df26Smrg	pScrn->videoRam = 16*1024;
7877706df26Smrg	break;
7887706df26Smrg      }
7897706df26Smrg    }
7907706df26Smrg
7917706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
7927706df26Smrg               pScrn->videoRam);
7937706df26Smrg
7947706df26Smrg    pTga->FbMapSize = pScrn->videoRam * 1024;
7957706df26Smrg
7967706df26Smrg    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
7977706df26Smrg	TGAFreeRec(pScrn);
7987706df26Smrg	return FALSE;
7997706df26Smrg    }
8007706df26Smrg
8017706df26Smrg    xf86LoaderReqSymLists(fbSymbols, NULL);
8027706df26Smrg
8037706df26Smrg    /* Load XAA if needed */
8047706df26Smrg    if (!pTga->NoAccel || pTga->HWCursor) {
8057706df26Smrg	if (!xf86LoadSubModule(pScrn, "xaa")) {
8067706df26Smrg	    TGAFreeRec(pScrn);
8077706df26Smrg	    return FALSE;
8087706df26Smrg	}
8097706df26Smrg	xf86LoaderReqSymLists(xaaSymbols, NULL);
8107706df26Smrg    }
8117706df26Smrg
8127706df26Smrg
8137706df26Smrg    /*********************
8147706df26Smrg    Let's check what type of DAC we have and reject if necessary
8157706df26Smrg    *********************/
8167706df26Smrg
8177706df26Smrg    pTga->RamDac = NULL;
8187706df26Smrg
8197706df26Smrg    if (pTga->CardType != TYPE_TGA_8PLANE) {
8207706df26Smrg        pTga->RamDacRec = NULL;
8217706df26Smrg	pTga->RamDac = NULL;
8227706df26Smrg    } else {
8237706df26Smrg
8247706df26Smrg        pTga->RamDacRec = RamDacCreateInfoRec();
8257706df26Smrg        switch (pTga->Chipset)
8267706df26Smrg	{
8277706df26Smrg	case PCI_CHIP_DEC21030:
8287706df26Smrg	    pTga->RamDacRec->ReadDAC = tgaBTInIndReg;
8297706df26Smrg	    pTga->RamDacRec->WriteDAC = tgaBTOutIndReg;
8307706df26Smrg	    pTga->RamDacRec->ReadAddress = tgaBTReadAddress;
8317706df26Smrg	    pTga->RamDacRec->WriteAddress = tgaBTWriteAddress;
8327706df26Smrg	    pTga->RamDacRec->ReadData = tgaBTReadData;
8337706df26Smrg	    pTga->RamDacRec->WriteData = tgaBTWriteData;
8347706df26Smrg	    break;
8357706df26Smrg	case PCI_CHIP_TGA2:
8367706df26Smrg	    pTga->RamDacRec->ReadDAC = tga2BTInIndReg;
8377706df26Smrg	    pTga->RamDacRec->WriteDAC = tga2BTOutIndReg;
8387706df26Smrg	    pTga->RamDacRec->ReadAddress = tga2BTReadAddress;
8397706df26Smrg	    pTga->RamDacRec->WriteAddress = tga2BTWriteAddress;
8407706df26Smrg	    pTga->RamDacRec->ReadData = tga2BTReadData;
8417706df26Smrg	    pTga->RamDacRec->WriteData = tga2BTWriteData;
8427706df26Smrg	    break;
8437706df26Smrg	}
8447706df26Smrg
8457706df26Smrg	if (!RamDacInit(pScrn, pTga->RamDacRec)) {
8467706df26Smrg	    RamDacDestroyInfoRec(pTga->RamDacRec);
8477706df26Smrg	    return FALSE;
8487706df26Smrg	}
8497706df26Smrg
8507706df26Smrg	TGAMapMem(pScrn);
8517706df26Smrg
8527706df26Smrg	pTga->RamDac = BTramdacProbe(pScrn, BTramdacs);
8537706df26Smrg
8547706df26Smrg	TGAUnmapMem(pScrn);
8557706df26Smrg
8567706df26Smrg	if (pTga->RamDac == NULL)
8577706df26Smrg	    return FALSE;
8587706df26Smrg    }
8597706df26Smrg
8607706df26Smrg    /*********************
8617706df26Smrg    set up clock and mode stuff
8627706df26Smrg    *********************/
8637706df26Smrg
8647706df26Smrg    pScrn->progClock = TRUE;
8657706df26Smrg
8667706df26Smrg    /* Set the min pixel clock */
8677706df26Smrg    pTga->MinClock = 16250;	/* XXX Guess, need to check this */
8687706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
8697706df26Smrg	       pTga->MinClock / 1000);
8707706df26Smrg
8717706df26Smrg    /*
8727706df26Smrg     * If the user has specified ramdac speed in the XF86Config
8737706df26Smrg     * file, we respect that setting.
8747706df26Smrg     */
8757706df26Smrg    if (pTga->pEnt->device->dacSpeeds[0]) {
8767706df26Smrg	int speed = 0;
8777706df26Smrg
8787706df26Smrg	switch (pScrn->bitsPerPixel) {
8797706df26Smrg	case 8:
8807706df26Smrg	   speed = pTga->pEnt->device->dacSpeeds[DAC_BPP8];
8817706df26Smrg	   break;
8827706df26Smrg	case 32:
8837706df26Smrg	   speed = pTga->pEnt->device->dacSpeeds[DAC_BPP32];
8847706df26Smrg	   break;
8857706df26Smrg	}
8867706df26Smrg	if (speed == 0)
8877706df26Smrg	    pTga->MaxClock = pTga->pEnt->device->dacSpeeds[0];
8887706df26Smrg	else
8897706df26Smrg	    pTga->MaxClock = speed;
8907706df26Smrg	from = X_CONFIG;
8917706df26Smrg    } else {
8927706df26Smrg	switch (pTga->Chipset) {
8937706df26Smrg	case PCI_CHIP_DEC21030:
8947706df26Smrg		pTga->MaxClock = 135000;
8957706df26Smrg		break;
8967706df26Smrg	case PCI_CHIP_TGA2:
8977706df26Smrg		pTga->MaxClock = 170000;
8987706df26Smrg		break;
8997706df26Smrg	}
9007706df26Smrg    }
9017706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
9027706df26Smrg	       pTga->MaxClock / 1000);
9037706df26Smrg
9047706df26Smrg    /*
9057706df26Smrg     * Setup the ClockRanges, which describe what clock ranges are available,
9067706df26Smrg     * and what sort of modes they can be used for.
9077706df26Smrg     */
9087706df26Smrg    clockRanges = xnfcalloc(sizeof(ClockRange), 1);
9097706df26Smrg    clockRanges->next = NULL;
9107706df26Smrg    clockRanges->minClock = pTga->MinClock;
9117706df26Smrg    clockRanges->maxClock = pTga->MaxClock;
9127706df26Smrg    clockRanges->clockIndex = -1;		/* programmable */
9137706df26Smrg    clockRanges->interlaceAllowed = FALSE;	/* XXX check this */
9147706df26Smrg    clockRanges->doubleScanAllowed = FALSE;	/* XXX check this */
9157706df26Smrg
9167706df26Smrg    if(pScrn->display->virtualX || pScrn->display->virtualY) {
9177706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
9187706df26Smrg		   "TGA does not support a virtual desktop\n");
9197706df26Smrg	pScrn->display->virtualX = 0;
9207706df26Smrg	pScrn->display->virtualY = 0;
9217706df26Smrg    }
9227706df26Smrg
9237706df26Smrg    /*
9247706df26Smrg     * xf86ValidateModes will check that the mode HTotal and VTotal values
9257706df26Smrg     * don't exceed the chipset's limit if pScrn->maxHValue and
9267706df26Smrg     * pScrn->maxVValue are set.  Since our TGAValidMode() already takes
9277706df26Smrg     * care of this, we don't worry about setting them here.
9287706df26Smrg     */
9297706df26Smrg    /* Select valid modes from those available */
9307706df26Smrg    /*
9317706df26Smrg     * XXX Assuming min pitch 256, max 2048
9327706df26Smrg     * XXX Assuming min height 128, max 2048
9337706df26Smrg     */
9347706df26Smrg    i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
9357706df26Smrg			  pScrn->display->modes, clockRanges,
9367706df26Smrg			  NULL, 256, 2048,
9377706df26Smrg			  pScrn->bitsPerPixel, 128, 2048,
9387706df26Smrg			  pScrn->display->virtualX,
9397706df26Smrg			  pScrn->display->virtualY,
9407706df26Smrg			  pTga->FbMapSize,
9417706df26Smrg			  LOOKUP_BEST_REFRESH);
9427706df26Smrg
9437706df26Smrg    if (i == -1) {
9447706df26Smrg	TGAFreeRec(pScrn);
9457706df26Smrg	return FALSE;
9467706df26Smrg    }
9477706df26Smrg
9487706df26Smrg    /* Prune the modes marked as invalid */
9497706df26Smrg    xf86PruneDriverModes(pScrn);
9507706df26Smrg
9517706df26Smrg    if (i == 0 || pScrn->modes == NULL) {
9527706df26Smrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
9537706df26Smrg	TGAFreeRec(pScrn);
9547706df26Smrg	return FALSE;
9557706df26Smrg    }
9567706df26Smrg
9577706df26Smrg    if(i > 1) {
9587706df26Smrg	DisplayModePtr mp1 = NULL, mp2 = NULL;
9597706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
9607706df26Smrg		   "TGA only supports one mode, using first mode.\n");
9617706df26Smrg	mp1 = pScrn->modes->next;
9627706df26Smrg	mp2 = mp1;
9637706df26Smrg	while(mp1 && mp1->next != mp1) {
9647706df26Smrg	    mp1 = mp1->next;
9657706df26Smrg	    xf86DeleteMode(&(pScrn->modes), mp2);
9667706df26Smrg	    mp2 = mp1;
9677706df26Smrg	}
9687706df26Smrg    }
9697706df26Smrg
9707706df26Smrg    xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
9717706df26Smrg
9727706df26Smrg    /* Set the current mode to the first in the list */
9737706df26Smrg    pScrn->currentMode = pScrn->modes;
9747706df26Smrg
9757706df26Smrg    /*
9767706df26Smrg     This is a bit of a hack; we seem to have to init
9777706df26Smrg     the TGA2 chipset knowing what the mode is, so we
9787706df26Smrg     do this now as soon as we know it...
9797706df26Smrg    */
9807706df26Smrg    if (pTga->Chipset == PCI_CHIP_TGA2) {
9817706df26Smrg      TGA2SetupMode(pScrn);
9827706df26Smrg    }
9837706df26Smrg
9847706df26Smrg    /* Print the list of modes being used */
9857706df26Smrg    xf86PrintModes(pScrn);
9867706df26Smrg
9877706df26Smrg    /* Set display resolution */
9887706df26Smrg    xf86SetDpi(pScrn, 0, 0);
9897706df26Smrg
9907706df26Smrg    return TRUE;
9917706df26Smrg}
9927706df26Smrg
9937706df26Smrg
9947706df26Smrg/*
9957706df26Smrg * Map the framebuffer and MMIO memory.
9967706df26Smrg */
9977706df26Smrg
9987706df26Smrgstatic Bool
9997706df26SmrgTGAMapMem(ScrnInfoPtr pScrn)
10007706df26Smrg{
10017706df26Smrg    TGAPtr pTga;
10027706df26Smrg
10037706df26Smrg    pTga = TGAPTR(pScrn);
10047706df26Smrg
10057706df26Smrg    /*
10067706df26Smrg     * Map IO registers to virtual address space
10077706df26Smrg     */
10087706df26Smrg
10097706df26Smrg    /* TGA doesn't need a sparse memory mapping, because all register
10107706df26Smrg       accesses are doublewords */
10117706df26Smrg
10127706df26Smrg    pTga->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
10137706df26Smrg				      pTga->PciTag,
10147706df26Smrg				      pTga->IOAddress, 0x100000);
10157706df26Smrg    if (pTga->IOBase == NULL)
10167706df26Smrg	return FALSE;
10177706df26Smrg
10187706df26Smrg    pTga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
10197706df26Smrg				 pTga->PciTag,
10207706df26Smrg				 (unsigned long)pTga->FbAddress,
10217706df26Smrg				 pTga->FbMapSize);
10227706df26Smrg    if (pTga->FbBase == NULL)
10237706df26Smrg	return FALSE;
10247706df26Smrg
10257706df26Smrg    if (pTga->Chipset == PCI_CHIP_DEC21030)
10267706df26Smrg	return TRUE;
10277706df26Smrg
10287706df26Smrg    pTga->ClkBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
10297706df26Smrg			pTga->PciTag,
10307706df26Smrg			(unsigned long)pTga->CardAddress + TGA2_CLOCK_OFFSET,
10317706df26Smrg			0x10000);
10327706df26Smrg    if (pTga->ClkBase == NULL)
10337706df26Smrg	return FALSE;
10347706df26Smrg
10357706df26Smrg    pTga->DACBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT,
10367706df26Smrg			pTga->PciTag,
10377706df26Smrg			(unsigned long)pTga->CardAddress + TGA2_RAMDAC_OFFSET,
10387706df26Smrg			0x10000);
10397706df26Smrg    if (pTga->DACBase == NULL)
10407706df26Smrg	return FALSE;
10417706df26Smrg
10427706df26Smrg    /*
10437706df26Smrg     * This is a hack specifically for the TGA2 code, as it sometimes
10447706df26Smrg     * calculates/uses addresses in TGA2 memory which are NOT mmapped
10457706df26Smrg     * by the normal framebuffer code above. This most frequently occurs
10467706df26Smrg     * when displaying something close to the top-left corner (in the
10477706df26Smrg     * routines CopyLine{Forwards,Backwards}.
10487706df26Smrg     *
10497706df26Smrg     * This could most likely also be fixed by further modifying the
10507706df26Smrg     * code, but it (the code) is ugly enough already... ;-}
10517706df26Smrg     *
10527706df26Smrg     * So, the workaround is to simply mmap an additional PAGE of
10537706df26Smrg     * framebuffer memory in front of the normal mmap to prevent
10547706df26Smrg     * SEGVs from happening.
10557706df26Smrg     */
10567706df26Smrg    pTga->HACKBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
10577706df26Smrg				 pTga->PciTag,
10587706df26Smrg				 (unsigned long)pTga->FbAddress - getpagesize(),
10597706df26Smrg				 getpagesize());
10607706df26Smrg    if (pTga->HACKBase == NULL)
10617706df26Smrg	return FALSE;
10627706df26Smrg
10637706df26Smrg    return TRUE;
10647706df26Smrg}
10657706df26Smrg
10667706df26Smrg
10677706df26Smrg/*
10687706df26Smrg * Unmap the framebuffer and MMIO memory.
10697706df26Smrg */
10707706df26Smrg
10717706df26Smrgstatic Bool
10727706df26SmrgTGAUnmapMem(ScrnInfoPtr pScrn)
10737706df26Smrg{
10747706df26Smrg    TGAPtr pTga;
10757706df26Smrg
10767706df26Smrg    pTga = TGAPTR(pScrn);
10777706df26Smrg
10787706df26Smrg    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->IOBase, 0x100000);
10797706df26Smrg    pTga->IOBase = NULL;
10807706df26Smrg
10817706df26Smrg    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->FbBase, pTga->FbMapSize);
10827706df26Smrg    pTga->FbBase = NULL;
10837706df26Smrg
10847706df26Smrg    if (pTga->Chipset == PCI_CHIP_DEC21030)
10857706df26Smrg	return TRUE;
10867706df26Smrg
10877706df26Smrg    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->ClkBase, 0x10000);
10887706df26Smrg    pTga->ClkBase = NULL;
10897706df26Smrg
10907706df26Smrg    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->DACBase, 0x10000);
10917706df26Smrg    pTga->DACBase = NULL;
10927706df26Smrg
10937706df26Smrg    xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->HACKBase, getpagesize());
10947706df26Smrg    pTga->HACKBase = NULL;
10957706df26Smrg
10967706df26Smrg    return TRUE;
10977706df26Smrg}
10987706df26Smrg
10997706df26Smrg
11007706df26Smrg/*
11017706df26Smrg * This function saves the video state.
11027706df26Smrg */
11037706df26Smrgstatic void
11047706df26SmrgTGASave(ScrnInfoPtr pScrn)
11057706df26Smrg{
11067706df26Smrg    TGAPtr pTga;
11077706df26Smrg    TGARegPtr tgaReg;
11087706df26Smrg    RamDacHWRecPtr pBT;
11097706df26Smrg    RamDacRegRecPtr BTreg;
11107706df26Smrg
11117706df26Smrg    pTga = TGAPTR(pScrn);
11127706df26Smrg    tgaReg = &pTga->SavedReg;
11137706df26Smrg
11147706df26Smrg    DEC21030Save(pScrn, tgaReg);
11157706df26Smrg    if (pTga->RamDac) { /* must be BT485... */
11167706df26Smrg        pBT = RAMDACHWPTR(pScrn);
11177706df26Smrg	BTreg = &pBT->SavedReg;
11187706df26Smrg	(*pTga->RamDac->Save)(pScrn, pTga->RamDacRec, BTreg);
11197706df26Smrg    } else switch (pTga->Chipset)
11207706df26Smrg    {
11217706df26Smrg    case PCI_CHIP_TGA2:
11227706df26Smrg        IBM561ramdacSave(pScrn, pTga->Ibm561saveReg);
11237706df26Smrg	break;
11247706df26Smrg    case PCI_CHIP_DEC21030:
11257706df26Smrg        BT463ramdacSave(pScrn, pTga->Bt463saveReg);
11267706df26Smrg	break;
11277706df26Smrg    }
11287706df26Smrg}
11297706df26Smrg
11307706df26Smrg
11317706df26Smrg/*
11327706df26Smrg * Initialise a new mode.  This is currently still using the old
11337706df26Smrg * "initialise struct, restore/write struct to HW" model.  That could
11347706df26Smrg * be changed.
11357706df26Smrg */
11367706df26Smrg
11377706df26Smrgstatic Bool
11387706df26SmrgTGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
11397706df26Smrg{
11407706df26Smrg    int ret = -1;
11417706df26Smrg    TGAPtr pTga;
11427706df26Smrg    TGARegPtr tgaReg;
11437706df26Smrg    RamDacHWRecPtr pBT;
11447706df26Smrg    RamDacRegRecPtr BTreg;
11457706df26Smrg
11467706df26Smrg    pTga = TGAPTR(pScrn);
11477706df26Smrg
11487706df26Smrg    pScrn->vtSema = TRUE;
11497706df26Smrg
11507706df26Smrg    ret = DEC21030Init(pScrn, mode);
11517706df26Smrg
11527706df26Smrg    if (pTga->Chipset == PCI_CHIP_TGA2 && pTga->RamDac == NULL)
11537706df26Smrg        IBM561ramdacHWInit(pScrn);
11547706df26Smrg
11557706df26Smrg    if (!ret)
11567706df26Smrg	return FALSE;
11577706df26Smrg
11587706df26Smrg    /* Program the registers */
11597706df26Smrg    tgaReg = &pTga->ModeReg;
11607706df26Smrg
11617706df26Smrg    DEC21030Restore(pScrn, tgaReg);
11627706df26Smrg
11637706df26Smrg    if (pTga->RamDac != NULL) {
11647706df26Smrg        pBT = RAMDACHWPTR(pScrn);
11657706df26Smrg	BTreg = &pBT->ModeReg;
11667706df26Smrg	(*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg);
11677706df26Smrg	if (pTga->Chipset == PCI_CHIP_TGA2) {
11687706df26Smrg	    pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
11697706df26Smrg	    pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x0c);
11707706df26Smrg	}
11717706df26Smrg	pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff);
11727706df26Smrg    } else {
11737706df26Smrg        switch (pTga->Chipset) {
11747706df26Smrg	case PCI_CHIP_TGA2:
11757706df26Smrg	    IBM561ramdacRestore(pScrn, pTga->Ibm561modeReg);
11767706df26Smrg	    break;
11777706df26Smrg	case PCI_CHIP_DEC21030:
11787706df26Smrg	    BT463ramdacRestore(pScrn, pTga->Bt463modeReg);
11797706df26Smrg	    break;
11807706df26Smrg	}
11817706df26Smrg    }
11827706df26Smrg    return TRUE;
11837706df26Smrg}
11847706df26Smrg
11857706df26Smrg/*
11867706df26Smrg * Restore the initial (text) mode.
11877706df26Smrg */
11887706df26Smrgstatic void
11897706df26SmrgTGARestore(ScrnInfoPtr pScrn)
11907706df26Smrg{
11917706df26Smrg    TGAPtr pTga;
11927706df26Smrg    TGARegPtr tgaReg;
11937706df26Smrg    RamDacHWRecPtr pBT;
11947706df26Smrg    RamDacRegRecPtr BTreg;
11957706df26Smrg
11967706df26Smrg    pTga = TGAPTR(pScrn);
11977706df26Smrg    tgaReg = &pTga->SavedReg;
11987706df26Smrg
11997706df26Smrg    /* Initial Text mode clock */
12007706df26Smrg    tgaReg->tgaRegs[0x0A] = 25175;
12017706df26Smrg
12027706df26Smrg    DEC21030Restore(pScrn, tgaReg);
12037706df26Smrg
12047706df26Smrg    if (pTga->RamDac != NULL) {
12057706df26Smrg        pBT = RAMDACHWPTR(pScrn);
12067706df26Smrg	BTreg = &pBT->SavedReg;
12077706df26Smrg	(*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg);
12087706df26Smrg	if (pTga->Chipset == PCI_CHIP_TGA2) {
12097706df26Smrg	    pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
12107706df26Smrg	    pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x00);
12117706df26Smrg	}
12127706df26Smrg	pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff);
12137706df26Smrg    } else switch (pTga->Chipset) {
12147706df26Smrg    case PCI_CHIP_TGA2:
12157706df26Smrg        IBM561ramdacRestore(pScrn, pTga->Ibm561saveReg);
12167706df26Smrg	break;
12177706df26Smrg    case PCI_CHIP_DEC21030:
12187706df26Smrg        BT463ramdacRestore(pScrn, pTga->Bt463saveReg);
12197706df26Smrg	break;
12207706df26Smrg    }
12217706df26Smrg
12227706df26Smrg if (pTga->HWCursor)
12237706df26Smrg     TGARestoreHWCursor(pScrn);
12247706df26Smrg}
12257706df26Smrg
12267706df26Smrg
12277706df26Smrg/* Mandatory */
12287706df26Smrg
12297706df26Smrg/* This gets called at the start of each server generation */
12307706df26Smrg
12317706df26Smrgstatic Bool
12327706df26SmrgTGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
12337706df26Smrg{
12347706df26Smrg    ScrnInfoPtr pScrn;
12357706df26Smrg    TGAPtr pTga;
12367706df26Smrg    int ret;
12377706df26Smrg    VisualPtr visual;
12387706df26Smrg
12397706df26Smrg    /*
12407706df26Smrg     * First get the ScrnInfoRec
12417706df26Smrg     */
12427706df26Smrg    pScrn = xf86Screens[pScreen->myNum];
12437706df26Smrg    pTga = TGAPTR(pScrn);
12447706df26Smrg
12457706df26Smrg    /* Map the TGA memory and MMIO areas */
12467706df26Smrg    if (!TGAMapMem(pScrn))
12477706df26Smrg	return FALSE;
12487706df26Smrg
12497706df26Smrg#if 1
12507706df26Smrg    /* dump original register contents */
12517706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MODE 0x%x\n",
12527706df26Smrg	       TGA_READ_REG(TGA_MODE_REG));
12537706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VALID 0x%x\n",
12547706df26Smrg	       TGA_READ_REG(TGA_VALID_REG));
12557706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DEEP 0x%x\n",
12567706df26Smrg	       TGA_READ_REG(TGA_DEEP_REG));
12577706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXSH 0x%x\n",
12587706df26Smrg	       TGA_READ_REG(TGA_PIXELSHIFT_REG));
12597706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ROP 0x%x\n",
12607706df26Smrg	       TGA_READ_REG(TGA_RASTEROP_REG));
12617706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "HORIZ 0x%x\n",
12627706df26Smrg	       TGA_READ_REG(TGA_HORIZ_REG));
12637706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VERT 0x%x\n",
12647706df26Smrg	       TGA_READ_REG(TGA_VERT_REG));
12657706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXMSK 0x%x\n",
12667706df26Smrg	       TGA_READ_REG(TGA_PIXELMASK_REG));
12677706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "REV 0x%x\n",
12687706df26Smrg	       TGA_READ_REG(TGA_REVISION_REG));
12697706df26Smrg    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VADDR 0x%x\n",
12707706df26Smrg	       TGA_READ_REG(TGA_BASE_ADDR_REG));
12717706df26Smrg#endif
12727706df26Smrg
12737706df26Smrg    /* Save the current state */
12747706df26Smrg    TGASave(pScrn);
12757706df26Smrg
12767706df26Smrg    /* Initialise the first mode */
12777706df26Smrg    TGAModeInit(pScrn, pScrn->currentMode);
12787706df26Smrg
12797706df26Smrg    /* Darken the screen for aesthetic reasons and set the viewport */
12807706df26Smrg    TGASaveScreen(pScreen, SCREEN_SAVER_ON);
12817706df26Smrg
12827706df26Smrg    /*
12837706df26Smrg     * The next step is to setup the screen's visuals, and initialise the
12847706df26Smrg     * framebuffer code.  In cases where the framebuffer's default
12857706df26Smrg     * choices for things like visual layouts and bits per RGB are OK,
12867706df26Smrg     * this may be as simple as calling the framebuffer's ScreenInit()
12877706df26Smrg     * function.  If not, the visuals will need to be setup before calling
12887706df26Smrg     * a fb ScreenInit() function and fixed up after.
12897706df26Smrg     *
12907706df26Smrg     * For most PC hardware at depths >= 8, the defaults that fb uses
12917706df26Smrg     * are not appropriate.  In this driver, we fixup the visuals after.
12927706df26Smrg     */
12937706df26Smrg
12947706df26Smrg    /*
12957706df26Smrg     * Reset visual list.
12967706df26Smrg     */
12977706df26Smrg    miClearVisualTypes();
12987706df26Smrg
12997706df26Smrg    /* Setup the visuals we support. */
13007706df26Smrg
13017706df26Smrg    /*
13027706df26Smrg     * For bpp > 8, the default visuals are not acceptable because we only
13037706df26Smrg     * support TrueColor and not DirectColor.  To deal with this, call
13047706df26Smrg     * miSetVisualTypes for each visual supported.
13057706df26Smrg     */
13067706df26Smrg
13077706df26Smrg    if (pScrn->bitsPerPixel > 8) {
13087706df26Smrg	if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
13097706df26Smrg				pScrn->defaultVisual))
13107706df26Smrg	    return FALSE;
13117706df26Smrg    } else {
13127706df26Smrg	if (!miSetVisualTypes(pScrn->depth,
13137706df26Smrg			      miGetDefaultVisualMask(pScrn->depth),
13147706df26Smrg			      pScrn->rgbBits, pScrn->defaultVisual))
13157706df26Smrg	    return FALSE;
13167706df26Smrg    }
13177706df26Smrg
13187706df26Smrg    miSetPixmapDepths ();
13197706df26Smrg
13207706df26Smrg    /*
13217706df26Smrg     * Call the framebuffer layer's ScreenInit function, and fill in other
13227706df26Smrg     * pScreen fields.
13237706df26Smrg     */
13247706df26Smrg
13257706df26Smrg    switch (pScrn->bitsPerPixel) {
13267706df26Smrg    case 8:
13277706df26Smrg    case 32:
13287706df26Smrg	ret = fbScreenInit(pScreen, pTga->FbBase, pScrn->virtualX,
13297706df26Smrg			pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
13307706df26Smrg			pScrn->displayWidth, pScrn->bitsPerPixel);
13317706df26Smrg	break;
13327706df26Smrg    default:
13337706df26Smrg	xf86DrvMsg(scrnIndex, X_ERROR,
13347706df26Smrg		   "Internal error: invalid bpp (%d) in TGAScrnInit\n",
13357706df26Smrg		   pScrn->bitsPerPixel);
13367706df26Smrg	    ret = FALSE;
13377706df26Smrg	break;
13387706df26Smrg    }
13397706df26Smrg    if (!ret)
13407706df26Smrg	return FALSE;
13417706df26Smrg
13427706df26Smrg    xf86SetBlackWhitePixels(pScreen);
13437706df26Smrg
13447706df26Smrg    if (pScrn->bitsPerPixel > 8) {
13457706df26Smrg        /* Fixup RGB ordering */
13467706df26Smrg        visual = pScreen->visuals + pScreen->numVisuals;
13477706df26Smrg        while (--visual >= pScreen->visuals) {
13487706df26Smrg	    if ((visual->class | DynamicClass) == DirectColor) {
13497706df26Smrg		visual->offsetRed = pScrn->offset.red;
13507706df26Smrg		visual->offsetGreen = pScrn->offset.green;
13517706df26Smrg		visual->offsetBlue = pScrn->offset.blue;
13527706df26Smrg		visual->redMask = pScrn->mask.red;
13537706df26Smrg		visual->greenMask = pScrn->mask.green;
13547706df26Smrg		visual->blueMask = pScrn->mask.blue;
13557706df26Smrg	    }
13567706df26Smrg	}
13577706df26Smrg    }
13587706df26Smrg
13597706df26Smrg    /* must be after RGB ordering fixed */
13607706df26Smrg
13617706df26Smrg    fbPictureInit (pScreen, 0, 0);
13627706df26Smrg
13637706df26Smrg    miInitializeBackingStore(pScreen);
13647706df26Smrg    xf86SetBackingStore(pScreen);
13657706df26Smrg    xf86SetSilkenMouse(pScreen);
13667706df26Smrg
13677706df26Smrg    /* we should ALWAYS do this */
13687706df26Smrg    if (pScrn->bitsPerPixel == 8) {
13697706df26Smrg      TGA_WRITE_REG(SIMPLE | X11 | BPP8PACKED, TGA_MODE_REG);
13707706df26Smrg      TGA_WRITE_REG(0x3 | BPP8PACKED, TGA_RASTEROP_REG);
13717706df26Smrg      if (pTga->Chipset == PCI_CHIP_TGA2)
13727706df26Smrg	TGA_WRITE_REG(2 << 28, TGA_DEEP_REG);
13737706df26Smrg    } else {
13747706df26Smrg      TGA_WRITE_REG(SIMPLE | X11 | BPP24, TGA_MODE_REG);
13757706df26Smrg      TGA_WRITE_REG(0x3 | BPP24, TGA_RASTEROP_REG);
13767706df26Smrg      if (pTga->Chipset == PCI_CHIP_TGA2)
13777706df26Smrg	TGA_WRITE_REG((7 << 2) | 1 | (2 << 28), TGA_DEEP_REG);
13787706df26Smrg    }
13797706df26Smrg    TGA_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG);
13807706df26Smrg    TGA_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG);
13817706df26Smrg
13827706df26Smrg    if (!pTga->NoAccel) {
13837706df26Smrg        switch (pTga->Chipset)
13847706df26Smrg        {
13857706df26Smrg	case PCI_CHIP_TGA2:
13867706df26Smrg	case PCI_CHIP_DEC21030:
13877706df26Smrg	  if(DEC21030AccelInit(pScreen) == FALSE) {
13887706df26Smrg	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
13897706df26Smrg			 "XAA Initialization failed\n");
13907706df26Smrg	      return(FALSE);
13917706df26Smrg	  }
13927706df26Smrg	  break;
13937706df26Smrg        }
13947706df26Smrg    }
13957706df26Smrg
13967706df26Smrg    /* Initialise cursor functions */
13977706df26Smrg    miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
13987706df26Smrg
13997706df26Smrg    /* Initialize HW cursor layer.
14007706df26Smrg       Must follow software cursor initialization*/
14017706df26Smrg    if (pTga->HWCursor) {
14027706df26Smrg      if(!TGAHWCursorInit(pScreen)) {
14037706df26Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
14047706df26Smrg		   "Hardware cursor initialization failed\n");
14057706df26Smrg	return(FALSE);
14067706df26Smrg      }
14077706df26Smrg    }
14087706df26Smrg
14097706df26Smrg
14107706df26Smrg    /* Initialise default colourmap */
14117706df26Smrg    if (!miCreateDefColormap(pScreen))
14127706df26Smrg	return FALSE;
14137706df26Smrg
14147706df26Smrg    if ((pScrn->bitsPerPixel==8) &&
14157706df26Smrg        (!RamDacHandleColormaps(pScreen, 256, pScrn->rgbBits,
14167706df26Smrg	 CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)))
14177706df26Smrg	return FALSE;
14187706df26Smrg
14197706df26Smrg    pTga->CloseScreen = pScreen->CloseScreen;
14207706df26Smrg    pScreen->CloseScreen = TGACloseScreen;
14217706df26Smrg    pScreen->SaveScreen = TGASaveScreen;
14227706df26Smrg
14237706df26Smrg    if(xf86DPMSInit(pScreen, TGADisplayPowerManagementSet, 0) == FALSE)
14247706df26Smrg      ErrorF("DPMS initialization failed!\n");
14257706df26Smrg
14267706df26Smrg    {
14277706df26Smrg      XF86VideoAdaptorPtr *ptr;
14287706df26Smrg      int n;
14297706df26Smrg
14307706df26Smrg      pScrn->memPhysBase = pTga->FbAddress;
14317706df26Smrg      pScrn->fbOffset = 0;
14327706df26Smrg
14337706df26Smrg      n = xf86XVListGenericAdaptors(pScrn,&ptr);
14347706df26Smrg
14357706df26Smrg      if(n) {
14367706df26Smrg	xf86XVScreenInit(pScreen, ptr, n);
14377706df26Smrg      }
14387706df26Smrg
14397706df26Smrg    }
14407706df26Smrg
14417706df26Smrg    /* Report any unused options (only for the first generation) */
14427706df26Smrg    if (serverGeneration == 1) {
14437706df26Smrg	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
14447706df26Smrg    }
14457706df26Smrg
14467706df26Smrg    /* unblank the screen */
14477706df26Smrg    TGASaveScreen(pScreen, SCREEN_SAVER_OFF);
14487706df26Smrg
14497706df26Smrg    /* Done */
14507706df26Smrg    return TRUE;
14517706df26Smrg}
14527706df26Smrg
14537706df26Smrg
14547706df26Smrg/* Usually mandatory */
14557706df26Smrgstatic Bool
14567706df26SmrgTGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
14577706df26Smrg{
14587706df26Smrg    return TGAModeInit(xf86Screens[scrnIndex], mode);
14597706df26Smrg}
14607706df26Smrg
14617706df26Smrg
14627706df26Smrg/*
14637706df26Smrg * This function is used to initialize the Start Address - the first
14647706df26Smrg * displayed location in the video memory.
14657706df26Smrg */
14667706df26Smrg/* Usually mandatory */
14677706df26Smrgstatic void
14687706df26SmrgTGAAdjustFrame(int scrnIndex, int x, int y, int flags)
14697706df26Smrg{
14707706df26Smrg    /* we don't support virtual desktops, because TGA doesn't have the
14717706df26Smrg       ability to set the start of the visible framebuffer at an arbitrary
14727706df26Smrg       pixel */
14737706df26Smrg    return;
14747706df26Smrg}
14757706df26Smrg
14767706df26Smrg/*
14777706df26Smrg * This is called when VT switching back to the X server.  Its job is
14787706df26Smrg * to reinitialise the video mode.
14797706df26Smrg *
14807706df26Smrg * We may wish to unmap video/MMIO memory too.
14817706df26Smrg */
14827706df26Smrg
14837706df26Smrg/* Mandatory */
14847706df26Smrgstatic Bool
14857706df26SmrgTGAEnterVT(int scrnIndex, int flags)
14867706df26Smrg{
14877706df26Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
14887706df26Smrg
14897706df26Smrg    /* Should we re-save the text mode on each VT enter? */
14907706df26Smrg    if (!TGAModeInit(pScrn, pScrn->currentMode))
14917706df26Smrg	return FALSE;
14927706df26Smrg
14937706df26Smrg    return TRUE;
14947706df26Smrg}
14957706df26Smrg
14967706df26Smrg
14977706df26Smrg/*
14987706df26Smrg * This is called when VT switching away from the X server.  Its job is
14997706df26Smrg * to restore the previous (text) mode.
15007706df26Smrg *
15017706df26Smrg * We may wish to remap video/MMIO memory too.
15027706df26Smrg */
15037706df26Smrg
15047706df26Smrg/* Mandatory */
15057706df26Smrgstatic void
15067706df26SmrgTGALeaveVT(int scrnIndex, int flags)
15077706df26Smrg{
15087706df26Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
15097706df26Smrg/*     TGAPtr pTga = TGAPTR(pScrn); */
15107706df26Smrg
15117706df26Smrg    TGARestore(pScrn);
15127706df26Smrg
15137706df26Smrg    /* no longer necessary with new VT switching code */
15147706df26Smrg/*      memset(pTga->FbBase, 0, pTga->FbMapSize); */
15157706df26Smrg    return;
15167706df26Smrg}
15177706df26Smrg
15187706df26Smrg
15197706df26Smrg/*
15207706df26Smrg * This is called at the end of each server generation.  It restores the
15217706df26Smrg * original (text) mode.
15227706df26Smrg */
15237706df26Smrg
15247706df26Smrg/* Mandatory */
15257706df26Smrgstatic Bool
15267706df26SmrgTGACloseScreen(int scrnIndex, ScreenPtr pScreen)
15277706df26Smrg{
15287706df26Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
15297706df26Smrg    TGAPtr pTga = TGAPTR(pScrn);
15307706df26Smrg
15317706df26Smrg    TGARestore(pScrn);
15327706df26Smrg    /*    memset(pTga->FbBase, 0, pScrn->videoRam * 1024); */
15337706df26Smrg    TGASync(pScrn);
15347706df26Smrg    TGAUnmapMem(pScrn);
15357706df26Smrg
15367706df26Smrg    if(pTga->AccelInfoRec)
15377706df26Smrg	XAADestroyInfoRec(pTga->AccelInfoRec);
15387706df26Smrg    pScrn->vtSema = FALSE;
15397706df26Smrg
15407706df26Smrg    pScreen->CloseScreen = pTga->CloseScreen;
15417706df26Smrg    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
15427706df26Smrg}
15437706df26Smrg
15447706df26Smrg
15457706df26Smrg/* Free up any per-generation data structures */
15467706df26Smrg
15477706df26Smrg/* Optional */
15487706df26Smrgstatic void
15497706df26SmrgTGAFreeScreen(int scrnIndex, int flags)
15507706df26Smrg{
15517706df26Smrg    RamDacFreeRec(xf86Screens[scrnIndex]);
15527706df26Smrg    TGAFreeRec(xf86Screens[scrnIndex]);
15537706df26Smrg}
15547706df26Smrg
15557706df26Smrg
15567706df26Smrg/* Checks if a mode is suitable for the selected chipset. */
15577706df26Smrg
15587706df26Smrg/* Optional */
15597706df26Smrgstatic ModeStatus
15607706df26SmrgTGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
15617706df26Smrg{
15627706df26Smrg    if (mode->Flags & V_INTERLACE)
15637706df26Smrg	return(MODE_BAD);
15647706df26Smrg
15657706df26Smrg    return(MODE_OK);
15667706df26Smrg}
15677706df26Smrg
15687706df26Smrg/* Do screen blanking */
15697706df26Smrg
15707706df26Smrg/* Mandatory */
15717706df26Smrgstatic Bool
15727706df26SmrgTGASaveScreen(ScreenPtr pScreen, int mode)
15737706df26Smrg    /* this function should blank the screen when unblank is FALSE and
15747706df26Smrg       unblank it when unblank is TRUE -- it doesn't actually seem to be
15757706df26Smrg       used for much though */
15767706df26Smrg{
15777706df26Smrg    TGAPtr pTga;
15787706df26Smrg    ScrnInfoPtr pScrn;
15797706df26Smrg    int valid_reg = 0;
15807706df26Smrg    Bool unblank;
15817706df26Smrg
15827706df26Smrg    pScrn = xf86Screens[pScreen->myNum];
15837706df26Smrg    pTga = TGAPTR(pScrn);
15847706df26Smrg    valid_reg = TGA_READ_REG(TGA_VALID_REG);
15857706df26Smrg    valid_reg &= 0xFFFFFFFC;
15867706df26Smrg
15877706df26Smrg    unblank = xf86IsUnblank(mode);
15887706df26Smrg
15897706df26Smrg    if(unblank == FALSE)
15907706df26Smrg	valid_reg |= 0x3;
15917706df26Smrg    else /* this function is sometimes called w/1 || 2 as TRUE */
15927706df26Smrg	valid_reg |= 0x1;
15937706df26Smrg
15947706df26Smrg    TGA_WRITE_REG(valid_reg, TGA_VALID_REG);
15957706df26Smrg
15967706df26Smrg/*      ErrorF("TGASaveScreen called\n"); */
15977706df26Smrg
15987706df26Smrg    return TRUE;
15997706df26Smrg}
16007706df26Smrg
16017706df26Smrg
16027706df26Smrg/*
16037706df26Smrg * TGADisplayPowerManagementSet --
16047706df26Smrg *
16057706df26Smrg * Sets VESA Display Power Management Signaling (DPMS) Mode.
16067706df26Smrg */
16077706df26Smrgstatic void
16087706df26SmrgTGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
16097706df26Smrg			     int flags)
16107706df26Smrg{
16117706df26Smrg  TGAPtr pTga;
16127706df26Smrg  int valid_reg = 0;
16137706df26Smrg
16147706df26Smrg  pTga = TGAPTR(pScrn);
16157706df26Smrg  valid_reg = TGA_READ_REG(TGA_VALID_REG);
16167706df26Smrg  valid_reg &= 0xFFFFFFFC;
16177706df26Smrg
16187706df26Smrg  switch(PowerManagementMode) {
16197706df26Smrg  case DPMSModeOn:
16207706df26Smrg    /* HSync: On, VSync: On */
16217706df26Smrg    valid_reg |= 0x1;
16227706df26Smrg    break;
16237706df26Smrg  case DPMSModeStandby:
16247706df26Smrg  case DPMSModeSuspend:
16257706df26Smrg    /* TGA gives us a function to blank the screen while maintaining sync...
16267706df26Smrg       I guess we can just use that here... */
16277706df26Smrg    valid_reg |= 0x3;
16287706df26Smrg    break;
16297706df26Smrg  case DPMSModeOff:
16307706df26Smrg    valid_reg |= 0x2;
16317706df26Smrg    break;
16327706df26Smrg  default:
16337706df26Smrg    ErrorF("Invalid PowerManagementMode %d passed to TGADisplayPowerManagementSet\n", PowerManagementMode);
16347706df26Smrg    break;
16357706df26Smrg  }
16367706df26Smrg
16377706df26Smrg  TGA_WRITE_REG(valid_reg, TGA_VALID_REG);
16387706df26Smrg  return;
16397706df26Smrg}
16407706df26Smrg
16417706df26Smrgstatic void
16427706df26SmrgTGARestoreHWCursor(ScrnInfoPtr pScrn)
16437706df26Smrg     /*
16447706df26Smrg       from tga.c in the linux kernel...may not work for BSD...
16457706df26Smrg       when the cursor is restored, it is one line down from where it should
16467706df26Smrg       be...this is disconcerting, but purely cosmetic.  Unfortunately reading
16477706df26Smrg       in the cursor framebuffer doesn't seem to work, I get a bunch of junk
16487706df26Smrg       at the beginning...other than that, see tga_cursor.c
16497706df26Smrg       I believe this to be a problem with the linux kernel code.
16507706df26Smrg       Hmm...this seems to be a 2.0.* problem, 2.2 works ok
16517706df26Smrg     */
16527706df26Smrg{
16537706df26Smrg  unsigned char *p = NULL;
16547706df26Smrg  int i = 0;
16557706df26Smrg  TGAPtr pTga;
16567706df26Smrg
16577706df26Smrg  /* Making this static prevents EGCS from compiling memset code
16587706df26Smrg     to initialize it, which was causing a problem. */
16597706df26Smrg  static const CARD32 tga_cursor_source[128] = {
16607706df26Smrg    0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
16617706df26Smrg    0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
16627706df26Smrg    0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
16637706df26Smrg    0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
16647706df26Smrg    0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
16657706df26Smrg    0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
16667706df26Smrg    0x000000ff, 0x00000000,
16677706df26Smrg    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16687706df26Smrg    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16697706df26Smrg    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16707706df26Smrg    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16717706df26Smrg    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16727706df26Smrg    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
16737706df26Smrg  };
16747706df26Smrg
16757706df26Smrg  /* this is the linux console hw cursor...what about the bsd console? */
16767706df26Smrg  /* what about tgafb? */
16777706df26Smrg  pTga = TGAPTR(pScrn);
16787706df26Smrg
16797706df26Smrg  /* we want to move the cursor off the screen before we do anything with it
16807706df26Smrg     otherwise, there is a "ghost cursor" that shows up */
16817706df26Smrg
16827706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, 0);
16837706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, 0);
16847706df26Smrg
16857706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, 0);
16867706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, 0);
16877706df26Smrg
16887706df26Smrg
16897706df26Smrg  /* set a windows cursor -- oddly, this doesn't seem necessary */
16907706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x02);
16917706df26Smrg
16927706df26Smrg  /* set a 64 bit cursor */
16937706df26Smrg/*    pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80); */
16947706df26Smrg/*    pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); */
16957706df26Smrg/*    pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0xF8, 0x04); */
16967706df26Smrg
16977706df26Smrg  /* set the colors */
16987706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01);
16997706df26Smrg
17007706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa);
17017706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa);
17027706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa);
17037706df26Smrg
17047706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
17057706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
17067706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
17077706df26Smrg
17087706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
17097706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
17107706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
17117706df26Smrg
17127706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
17137706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
17147706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00);
17157706df26Smrg
17167706df26Smrg
17177706df26Smrg  /* load the console cursor */
17187706df26Smrg  pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00);
17197706df26Smrg  p = (unsigned char *)tga_cursor_source;
17207706df26Smrg  for(i = 0; i < 512; i++)
17217706df26Smrg    pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *p++);
17227706df26Smrg  for(i = 0; i < 512; i++)
17237706df26Smrg    pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, 0xff);
17247706df26Smrg
17257706df26Smrg  return;
17267706df26Smrg}
17277706df26Smrg
17287706df26Smrg
17297706df26Smrg/*
17307706df26Smrg * This is the implementation of the Sync() function.
17317706df26Smrg */
17327706df26Smrgvoid
17337706df26SmrgTGASync(ScrnInfoPtr pScrn)
17347706df26Smrg{
17357706df26Smrg    TGAPtr pTga = TGAPTR(pScrn);
17367706df26Smrg    unsigned int stat;
17377706df26Smrg
17387706df26Smrg    switch (pTga->Chipset)
17397706df26Smrg    {
17407706df26Smrg    case PCI_CHIP_TGA2:
17417706df26Smrg      /* This code is weird, but then so is TGA2... ;-} */
17427706df26Smrg	mem_barrier();
17437706df26Smrg	while((stat = TGA_READ_REG(TGA_CMD_STAT_REG))) {
17447706df26Smrg	    if (((stat >> 8) & 0xff) == ((stat >> 16) & 0xff)) {
17457706df26Smrg	        TGA_WRITE_REG(0, TGA_CMD_STAT_REG);
17467706df26Smrg		mem_barrier();
17477706df26Smrg#if 0
17487706df26SmrgErrorF("TGASync: writing CMD_STATUS\n");
17497706df26Smrg#endif
17507706df26Smrg	    }
17517706df26Smrg	    usleep(1000);
17527706df26Smrg	}
17537706df26Smrg	break;
17547706df26Smrg
17557706df26Smrg    case PCI_CHIP_DEC21030:
17567706df26Smrg#if 0
17577706df26Smrg        /* I'm experiencing lockups which could be due to this function.
17587706df26Smrg	   We don't seem to need it anyway...
17597706df26Smrg	*/
17607706df26Smrg        while (TGA_READ_REG(TGA_CMD_STAT_REG) & 0x01);
17617706df26Smrg#endif
17627706df26Smrg	break;
17637706df26Smrg    }
17647706df26Smrg
17657706df26Smrg    return;
17667706df26Smrg}
17677706df26Smrg
1768