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