tga_driver.c revision b92e825a
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 267706df26Smrg#ifdef HAVE_CONFIG_H 277706df26Smrg#include "config.h" 287706df26Smrg#endif 297706df26Smrg 307706df26Smrg#include <string.h> 317ae0a258Smrg#include <unistd.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 417ae0a258Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 427706df26Smrg#include "xf86Resources.h" 437ae0a258Smrg#include "xf86RAC.h" 447ae0a258Smrg#endif 457706df26Smrg/* #include "vgaHW.h" */ 467706df26Smrg 477706df26Smrg/* software cursor */ 487706df26Smrg#include "mipointer.h" 497706df26Smrg/* backing store */ 507706df26Smrg#include "mibstore.h" 517706df26Smrg 527706df26Smrg/* #include "mibank.h" */ 537706df26Smrg/* colormap manipulation */ 547706df26Smrg#include "micmap.h" 557706df26Smrg 567706df26Smrg#include "fb.h" 577706df26Smrg 587706df26Smrg/* Gamma Correction? */ 597706df26Smrg#include "xf86cmap.h" 607706df26Smrg 617706df26Smrg#include "tga_regs.h" 627706df26Smrg#include "BT.h" 637706df26Smrg#include "tga.h" 647706df26Smrg 657706df26Smrg#ifdef XFreeXDGA 66b92e825aSmrg#include <X11/extensions/xf86dgaproto.h> 677706df26Smrg#endif 687706df26Smrg 697706df26Smrg#include "globals.h" 707ae0a258Smrg#ifdef HAVE_XEXTPROTO_71 717ae0a258Smrg#include <X11/extensions/dpmsconst.h> 727ae0a258Smrg#else 737706df26Smrg#define DPMS_SERVER 747706df26Smrg#include <X11/extensions/dpms.h> 757ae0a258Smrg#endif 767ae0a258Smrg 777706df26Smrg 787706df26Smrg#include "xf86xv.h" 797706df26Smrg#include <X11/extensions/Xv.h> 807706df26Smrg 817706df26Smrgstatic const OptionInfoRec * TGAAvailableOptions(int chipid, int busid); 827706df26Smrgstatic void TGAIdentify(int flags); 837706df26Smrgstatic Bool TGAProbe(DriverPtr drv, int flags); 847706df26Smrgstatic Bool TGAPreInit(ScrnInfoPtr pScrn, int flags); 85b92e825aSmrgstatic Bool TGAScreenInit(SCREEN_INIT_ARGS_DECL); 86b92e825aSmrgstatic Bool TGAEnterVT(VT_FUNC_ARGS_DECL); 87b92e825aSmrgstatic void TGALeaveVT(VT_FUNC_ARGS_DECL); 88b92e825aSmrgstatic Bool TGACloseScreen(CLOSE_SCREEN_ARGS_DECL); 897706df26Smrgstatic Bool TGASaveScreen(ScreenPtr pScreen, int mode); 907706df26Smrg 917706df26Smrg/* Required if the driver supports mode switching */ 92b92e825aSmrgstatic Bool TGASwitchMode(SWITCH_MODE_ARGS_DECL); 937706df26Smrg/* Required if the driver supports moving the viewport */ 94b92e825aSmrgstatic void TGAAdjustFrame(ADJUST_FRAME_ARGS_DECL); 957706df26Smrg 967706df26Smrg/* Optional functions */ 97b92e825aSmrgstatic void TGAFreeScreen(FREE_SCREEN_ARGS_DECL); 98b92e825aSmrgstatic ModeStatus TGAValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, 997706df26Smrg Bool verbose, int flags); 1007706df26Smrg 1017706df26Smrg/* Internally used functions */ 1027706df26Smrgstatic Bool TGAMapMem(ScrnInfoPtr pScrn); 1037706df26Smrgstatic Bool TGAUnmapMem(ScrnInfoPtr pScrn); 1047706df26Smrgstatic void TGASave(ScrnInfoPtr pScrn); 1057706df26Smrgstatic void TGARestore(ScrnInfoPtr pScrn); 1067706df26Smrgstatic Bool TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); 1077706df26Smrg 1087706df26Smrgstatic void TGARestoreHWCursor(ScrnInfoPtr pScrn); 1097706df26Smrg 1107706df26Smrgstatic void TGADisplayPowerManagementSet(ScrnInfoPtr pScrn, 1117706df26Smrg int PowerManagementMode, 1127706df26Smrg int flags); 1137706df26Smrg 1147706df26Smrgvoid TGASync(ScrnInfoPtr pScrn); 1157706df26Smrg 1167706df26Smrg#define TGA_VERSION 4000 1177706df26Smrg#define TGA_NAME "TGA" 1187706df26Smrg#define TGA_DRIVER_NAME "tga" 119047944f3Smrg#define TGA_MAJOR_VERSION PACKAGE_VERSION_MAJOR 120047944f3Smrg#define TGA_MINOR_VERSION PACKAGE_VERSION_MINOR 121047944f3Smrg#define TGA_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 1227706df26Smrg 1237706df26Smrg/* 1247706df26Smrg * This contains the functions needed by the server after loading the driver 1257706df26Smrg * module. It must be supplied, and gets passed back by the SetupProc 1267706df26Smrg * function in the dynamic case. In the static case, a reference to this 1277706df26Smrg * is compiled in, and this requires that the name of this DriverRec be 1287706df26Smrg * an upper-case version of the driver name. 1297706df26Smrg */ 1307706df26Smrg 1317706df26Smrg_X_EXPORT DriverRec TGA = { 1327706df26Smrg TGA_VERSION, 1337706df26Smrg TGA_DRIVER_NAME, 1347706df26Smrg TGAIdentify, 1357706df26Smrg TGAProbe, 1367706df26Smrg TGAAvailableOptions, 1377706df26Smrg NULL, 1387706df26Smrg 0 1397706df26Smrg}; 1407706df26Smrg 1417706df26Smrgstatic SymTabRec TGAChipsets[] = { 1427706df26Smrg { PCI_CHIP_DEC21030, "tga" }, 1437706df26Smrg { PCI_CHIP_TGA2, "tga2" }, 1447706df26Smrg { -1, NULL } 1457706df26Smrg}; 1467706df26Smrg 1477706df26Smrgstatic PciChipsets TGAPciChipsets[] = { 1487706df26Smrg { PCI_CHIP_DEC21030, PCI_CHIP_DEC21030, NULL }, 1497706df26Smrg { PCI_CHIP_TGA2, PCI_CHIP_TGA2, NULL }, 1507706df26Smrg { -1, -1, RES_UNDEFINED } 1517706df26Smrg}; 1527706df26Smrg 1537706df26Smrgtypedef enum { 1547706df26Smrg OPTION_SW_CURSOR, 1557706df26Smrg OPTION_HW_CURSOR, 1567706df26Smrg OPTION_PCI_RETRY, 1577706df26Smrg OPTION_RGB_BITS, 1587706df26Smrg OPTION_NOACCEL, 1597706df26Smrg OPTION_SYNC_ON_GREEN, 1607706df26Smrg OPTION_DAC_6_BIT, 1617706df26Smrg OPTION_NOXAAPOLYSEGMENT 1627706df26Smrg} TGAOpts; 1637706df26Smrg 1647706df26Smrgstatic const OptionInfoRec TGAOptions[] = { 1657706df26Smrg { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 1667706df26Smrg { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE }, 1677706df26Smrg { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE }, 1687706df26Smrg { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE }, 1697706df26Smrg { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 1707706df26Smrg { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE }, 1717706df26Smrg { OPTION_DAC_6_BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE }, 1727706df26Smrg { OPTION_NOXAAPOLYSEGMENT, "NoXaaPolySegment",OPTV_BOOLEAN,{0}, FALSE }, 1737706df26Smrg { -1, NULL, OPTV_NONE, {0}, FALSE } 1747706df26Smrg}; 1757706df26Smrg 1767706df26Smrgstatic RamDacSupportedInfoRec BTramdacs[] = { 1777706df26Smrg { BT485_RAMDAC }, 1787706df26Smrg { -1 } 1797706df26Smrg}; 1807706df26Smrg 1817706df26Smrg#ifdef XFree86LOADER 1827706df26Smrg 1837706df26Smrgstatic MODULESETUPPROTO(tgaSetup); 1847706df26Smrg 1857706df26Smrgstatic XF86ModuleVersionInfo tgaVersRec = 1867706df26Smrg{ 1877706df26Smrg "tga", 1887706df26Smrg MODULEVENDORSTRING, 1897706df26Smrg MODINFOSTRING1, 1907706df26Smrg MODINFOSTRING2, 1917706df26Smrg XORG_VERSION_CURRENT, 1927706df26Smrg TGA_MAJOR_VERSION, TGA_MINOR_VERSION, TGA_PATCHLEVEL, 1937706df26Smrg ABI_CLASS_VIDEODRV, /* This is a video driver */ 1947706df26Smrg ABI_VIDEODRV_VERSION, 1957706df26Smrg MOD_CLASS_VIDEODRV, 1967706df26Smrg {0,0,0,0} 1977706df26Smrg}; 1987706df26Smrg 1997706df26Smrg_X_EXPORT XF86ModuleData tgaModuleData = { &tgaVersRec, tgaSetup, NULL }; 2007706df26Smrg 2017706df26Smrgpointer 2027706df26SmrgtgaSetup(pointer module, pointer opts, int *errmaj, int *errmin) 2037706df26Smrg{ 2047706df26Smrg static Bool setupDone = FALSE; 2057706df26Smrg 2067706df26Smrg if (!setupDone) { 2077706df26Smrg setupDone = TRUE; 2087706df26Smrg xf86AddDriver(&TGA, module, 0); 2097706df26Smrg 2107706df26Smrg /* 2117706df26Smrg * The return value must be non-NULL on success even though there 2127706df26Smrg * is no TearDownProc. 2137706df26Smrg */ 2147706df26Smrg return (pointer)1; 2157706df26Smrg } else { 2167706df26Smrg if (errmaj) *errmaj = LDR_ONCEONLY; 2177706df26Smrg return NULL; 2187706df26Smrg } 2197706df26Smrg} 2207706df26Smrg 2217706df26Smrg#endif /* XFree86LOADER */ 2227706df26Smrg 2237706df26Smrgstatic unsigned int fb_offset_presets[4] = { 2247706df26Smrg TGA_8PLANE_FB_OFFSET, 2257706df26Smrg TGA_24PLANE_FB_OFFSET, 2267706df26Smrg 0xffffffff, 2277706df26Smrg TGA_24PLUSZ_FB_OFFSET 2287706df26Smrg}; 2297706df26Smrg 2307706df26Smrgstatic char *tga_cardnames[4] = { 2317706df26Smrg "TGA 8 Plane", 2327706df26Smrg "TGA 24 Plane", 2337706df26Smrg NULL, 2347706df26Smrg "TGA 24 Plane 3D" 2357706df26Smrg}; 2367706df26Smrg 2377706df26Smrgstatic Bool 2387706df26SmrgTGAGetRec(ScrnInfoPtr pScrn) 2397706df26Smrg{ 2407706df26Smrg /* 2417706df26Smrg * Allocate an TGARec, and hook it into pScrn->driverPrivate. 2427706df26Smrg * pScrn->driverPrivate is initialised to NULL, so we can check if 2437706df26Smrg * the allocation has already been done. 2447706df26Smrg */ 2457706df26Smrg if (pScrn->driverPrivate != NULL) 2467706df26Smrg return TRUE; 2477706df26Smrg 2487706df26Smrg pScrn->driverPrivate = xnfcalloc(sizeof(TGARec), 1); 2497706df26Smrg /* Initialise it */ 2507706df26Smrg 2517706df26Smrg 2527706df26Smrg return TRUE; 2537706df26Smrg} 2547706df26Smrg 2557706df26Smrgstatic void 2567706df26SmrgTGAFreeRec(ScrnInfoPtr pScrn) 2577706df26Smrg{ 2587706df26Smrg TGAPtr pTga; 2597706df26Smrg 2607706df26Smrg if (pScrn->driverPrivate == NULL) 2617706df26Smrg return; 2627706df26Smrg 2637706df26Smrg pTga = TGAPTR(pScrn); 2647706df26Smrg 2657706df26Smrg if(pTga->buffers[0]) 2667706df26Smrg free(pTga->buffers[0]); 2677706df26Smrg 268b92e825aSmrg free(pScrn->driverPrivate); 2697706df26Smrg pScrn->driverPrivate = NULL; 2707706df26Smrg 2717706df26Smrg return; 2727706df26Smrg} 2737706df26Smrg 2747706df26Smrgstatic const OptionInfoRec * 2757706df26SmrgTGAAvailableOptions(int chipid, int busid) 2767706df26Smrg{ 2777706df26Smrg return TGAOptions; 2787706df26Smrg} 2797706df26Smrg 2807706df26Smrg/* Mandatory */ 2817706df26Smrgstatic void 2827706df26SmrgTGAIdentify(int flags) 2837706df26Smrg{ 2847706df26Smrg xf86PrintChipsets(TGA_NAME, "driver for Digital chipsets", TGAChipsets); 2857706df26Smrg return; 2867706df26Smrg} 2877706df26Smrg 2887706df26Smrg 2897706df26Smrg/* Mandatory */ 2907706df26Smrgstatic Bool 2917706df26SmrgTGAProbe(DriverPtr drv, int flags) 2927706df26Smrg{ 2937706df26Smrg int i; 2947706df26Smrg GDevPtr *devSections; 2957706df26Smrg int *usedChips; 2967706df26Smrg int numDevSections; 2977706df26Smrg int numUsed; 2987706df26Smrg Bool foundScreen = FALSE; 2997706df26Smrg 3007706df26Smrg /* 3017706df26Smrg * The aim here is to find all cards that this driver can handle, 3027706df26Smrg * and for the ones not already claimed by another driver, claim the 3037706df26Smrg * slot, and allocate a ScrnInfoRec. 3047706df26Smrg * 3057706df26Smrg * This should be a minimal probe, and it should under no circumstances 3067706df26Smrg * change the state of the hardware. Because a device is found, don't 3077706df26Smrg * assume that it will be used. Don't do any initialisations other than 3087706df26Smrg * the required ScrnInfoRec initialisations. Don't allocate any new 3097706df26Smrg * data structures. 3107706df26Smrg */ 3117706df26Smrg 3127706df26Smrg /* 3137706df26Smrg * Next we check, if there has been a chipset override in the config file. 3147706df26Smrg * For this we must find out if there is an active device section which 3157706df26Smrg * is relevant, i.e., which has no driver specified or has THIS driver 3167706df26Smrg * specified. 3177706df26Smrg */ 3187706df26Smrg 3197706df26Smrg if ((numDevSections = xf86MatchDevice(TGA_DRIVER_NAME, 3207706df26Smrg &devSections)) <= 0) { 3217706df26Smrg /* 3227706df26Smrg * There's no matching device section in the config file, so quit 3237706df26Smrg * now. 3247706df26Smrg */ 3257706df26Smrg return FALSE; 3267706df26Smrg } 3277706df26Smrg 3287706df26Smrg /* 3297706df26Smrg * We need to probe the hardware first. We then need to see how this 3307706df26Smrg * fits in with what is given in the config file, and allow the config 3317706df26Smrg * file info to override any contradictions. 3327706df26Smrg */ 3337706df26Smrg 3347706df26Smrg /* 3357706df26Smrg * All of the cards this driver supports are PCI, so the "probing" just 3367706df26Smrg * amounts to checking the PCI data that the server has already collected. 3377706df26Smrg */ 338047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 3397706df26Smrg if (xf86GetPciVideoInfo() == NULL) { 3407706df26Smrg /* 3417706df26Smrg * We won't let anything in the config file override finding no 3427706df26Smrg * PCI video cards at all. This seems reasonable now, but we'll see. 3437706df26Smrg */ 3447706df26Smrg return FALSE; 3457706df26Smrg } 346047944f3Smrg#endif 3477706df26Smrg 3487706df26Smrg numUsed = xf86MatchPciInstances(TGA_NAME, PCI_VENDOR_DIGITAL, 3497706df26Smrg TGAChipsets, TGAPciChipsets, devSections, numDevSections, 3507706df26Smrg drv, &usedChips); 3517706df26Smrg 352b92e825aSmrg free(devSections); 3537706df26Smrg if (numUsed <= 0) 3547706df26Smrg return FALSE; 3557706df26Smrg 3567706df26Smrg if (flags & PROBE_DETECT) 3577706df26Smrg foundScreen = TRUE; 3587706df26Smrg else for (i = 0; i < numUsed; i++) { 3597706df26Smrg /* 3607706df26Smrg * Check that nothing else has claimed the slots. 3617706df26Smrg */ 3627706df26Smrg ScrnInfoPtr pScrn = NULL; 3637706df26Smrg 3647706df26Smrg /* Allocate a ScrnInfoRec and claim the slot */ 3657706df26Smrg if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], 3667706df26Smrg TGAPciChipsets, NULL, NULL, 3677706df26Smrg NULL, NULL, NULL))) { 3687706df26Smrg /* Fill in what we can of the ScrnInfoRec */ 3697706df26Smrg pScrn->driverVersion = TGA_VERSION; 3707706df26Smrg pScrn->driverName = TGA_DRIVER_NAME; 3717706df26Smrg pScrn->name = TGA_NAME; 3727706df26Smrg pScrn->Probe = TGAProbe; 3737706df26Smrg pScrn->PreInit = TGAPreInit; 3747706df26Smrg pScrn->ScreenInit = TGAScreenInit; 3757706df26Smrg pScrn->SwitchMode = TGASwitchMode; 3767706df26Smrg pScrn->AdjustFrame = TGAAdjustFrame; 3777706df26Smrg pScrn->EnterVT = TGAEnterVT; 3787706df26Smrg pScrn->LeaveVT = TGALeaveVT; 3797706df26Smrg pScrn->FreeScreen = TGAFreeScreen; 3807706df26Smrg pScrn->ValidMode = TGAValidMode; 3817706df26Smrg foundScreen = TRUE; 3827706df26Smrg } 3837706df26Smrg } 384b92e825aSmrg free(usedChips); 3857706df26Smrg return foundScreen; 3867706df26Smrg} 3877706df26Smrg 3887706df26Smrg#if 0 3897706df26Smrg/* 3907706df26Smrg * GetAccelPitchValues - 3917706df26Smrg * 3927706df26Smrg * This function returns a list of display width (pitch) values that can 3937706df26Smrg * be used in accelerated mode. 3947706df26Smrg */ 3957706df26Smrgstatic int * 3967706df26SmrgGetAccelPitchValues(ScrnInfoPtr pScrn) 3977706df26Smrg{ 3987706df26Smrg int *linePitches = NULL; 3997706df26Smrg int i, n = 0; 4007706df26Smrg int *linep = NULL; 4017706df26Smrg /* TGAPtr pTga = TGAPTR(pScrn); */ 4027706df26Smrg 4037706df26Smrg for (i = 0; linep[i] != 0; i++) { 4047706df26Smrg if (linep[i] != -1) { 4057706df26Smrg n++; 4067706df26Smrg linePitches = xnfrealloc(linePitches, n * sizeof(int)); 4077706df26Smrg linePitches[n - 1] = i << 5; 4087706df26Smrg } 4097706df26Smrg } 4107706df26Smrg 4117706df26Smrg /* Mark the end of the list */ 4127706df26Smrg if (n > 0) { 4137706df26Smrg linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int)); 4147706df26Smrg linePitches[n] = 0; 4157706df26Smrg } 4167706df26Smrg return linePitches; 4177706df26Smrg} 4187706df26Smrg#endif /* 0 */ 4197706df26Smrg 4207706df26Smrg/* Mandatory */ 4217706df26Smrgstatic Bool 4227706df26SmrgTGAPreInit(ScrnInfoPtr pScrn, int flags) 4237706df26Smrg{ 4247706df26Smrg pciVideoPtr pciPtr; 4257706df26Smrg TGAPtr pTga; 4267706df26Smrg MessageType from; 4277706df26Smrg int i; 4287706df26Smrg ClockRangePtr clockRanges; 4297706df26Smrg pointer Base; 4307706df26Smrg 4317706df26Smrg if (flags & PROBE_DETECT) return FALSE; 4327706df26Smrg 4337706df26Smrg /* 4347706df26Smrg * Note: This function is only called once at server startup, and 4357706df26Smrg * not at the start of each server generation. This means that 4367706df26Smrg * only things that are persistent across server generations can 4377706df26Smrg * be initialised here. xf86Screens[] is (pScrn is a pointer to one 4387706df26Smrg * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() 4397706df26Smrg * are too, and should be used for data that must persist across 4407706df26Smrg * server generations. 4417706df26Smrg * 4427706df26Smrg * Per-generation data should be allocated with 4437706df26Smrg * AllocateScreenPrivateIndex() from the ScreenInit() function. 4447706df26Smrg */ 4457706df26Smrg 4467706df26Smrg /* The ramdac module should be loaded here when needed */ 4477706df26Smrg if (!xf86LoadSubModule(pScrn, "ramdac")) 4487706df26Smrg return FALSE; 4497706df26Smrg 4507706df26Smrg /* Allocate the TGARec driverPrivate */ 4517706df26Smrg if (!TGAGetRec(pScrn)) { 4527706df26Smrg return FALSE; 4537706df26Smrg } 4547706df26Smrg pTga = TGAPTR(pScrn); 4557706df26Smrg 4567706df26Smrg /* Set pScrn->monitor */ 4577706df26Smrg pScrn->monitor = pScrn->confScreen->monitor; 4587706df26Smrg 4597706df26Smrg /********************* 4607706df26Smrg Handle pci and chipset stuff 4617706df26Smrg *********************/ 4627706df26Smrg 4637706df26Smrg 4647706df26Smrg /* This driver doesn't expect more than one entity per screen */ 4657706df26Smrg if (pScrn->numEntities > 1) 4667706df26Smrg return FALSE; 4677706df26Smrg /* This is the general case */ 4687706df26Smrg for (i = 0; i < pScrn->numEntities; i++) { 4697706df26Smrg pTga->pEnt = xf86GetEntityInfo(pScrn->entityList[i]); 4707ae0a258Smrg#ifndef XSERVER_LIBPCIACCESS 4717706df26Smrg if (pTga->pEnt->resources) return FALSE; 4727ae0a258Smrg#endif 4737706df26Smrg pTga->Chipset = pTga->pEnt->chipset; 4747706df26Smrg pScrn->chipset = (char *)xf86TokenToString(TGAChipsets, 4757706df26Smrg pTga->pEnt->chipset); 4767706df26Smrg 4777706df26Smrg /* TGA is purely PCI */ 4787706df26Smrg if (pTga->pEnt->location.type == BUS_PCI) { 4797706df26Smrg pciPtr = xf86GetPciInfoForEntity(pTga->pEnt->index); 4807706df26Smrg pTga->PciInfo = pciPtr; 481047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 4827706df26Smrg pTga->PciTag = pciTag(pTga->PciInfo->bus, 4837706df26Smrg pTga->PciInfo->device, 4847706df26Smrg pTga->PciInfo->func); 485047944f3Smrg#endif 4867706df26Smrg } 4877706df26Smrg else 4887706df26Smrg return FALSE; 4897706df26Smrg } 4907706df26Smrg 4917706df26Smrg /* 4927706df26Smrg * This shouldn't happen because such problems should be caught in 4937706df26Smrg * TGAProbe(), but check it just in case. 4947706df26Smrg */ 4957706df26Smrg if (pScrn->chipset == NULL) { 4967706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 4977706df26Smrg "ChipID 0x%04X is not recognised\n", pTga->Chipset); 4987706df26Smrg return FALSE; 4997706df26Smrg } 5007706df26Smrg if (pTga->Chipset < 0) { 5017706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 5027706df26Smrg "Chipset \"%s\" is not recognised\n", pScrn->chipset); 5037706df26Smrg return FALSE; 5047706df26Smrg } 5057706df26Smrg 5067706df26Smrg from = X_PROBED; 5077706df26Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); 5087706df26Smrg 509047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 5107706df26Smrg pTga->PciTag = pciTag(pTga->PciInfo->bus, pTga->PciInfo->device, 5117706df26Smrg pTga->PciInfo->func); 512047944f3Smrg#endif 5137706df26Smrg 5147706df26Smrg 5157706df26Smrg 5167706df26Smrg /********************* 5177706df26Smrg deal with depth and framebuffer size 5187706df26Smrg *********************/ 5197706df26Smrg 5207706df26Smrg if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { 5217706df26Smrg return FALSE; 5227706df26Smrg } else { 5237706df26Smrg /* Check that the returned depth is one we support */ 5247706df26Smrg switch (pScrn->depth) { 5257706df26Smrg case 8: 5267706df26Smrg case 24: 5277706df26Smrg /* OK */ 5287706df26Smrg break; 5297706df26Smrg default: 5307706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 5317706df26Smrg "Given depth (%d) is not supported by this driver\n", 5327706df26Smrg pScrn->depth); 5337706df26Smrg return FALSE; 5347706df26Smrg } 5357706df26Smrg } 5367706df26Smrg 5377706df26Smrg /* we can do option processing now */ 5387706df26Smrg 5397706df26Smrg /* Collect all of the relevant option flags (fill in pScrn->options) */ 5407706df26Smrg xf86CollectOptions(pScrn, NULL); 5417706df26Smrg /* Process the options */ 542b92e825aSmrg if (!(pTga->Options = malloc(sizeof(TGAOptions)))) 5437706df26Smrg return FALSE; 5447706df26Smrg memcpy(pTga->Options, TGAOptions, sizeof(TGAOptions)); 5457706df26Smrg xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTga->Options); 5467706df26Smrg if (xf86ReturnOptValBool(pTga->Options, OPTION_PCI_RETRY, FALSE)) { 5477706df26Smrg pTga->UsePCIRetry = TRUE; 5487706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n"); 5497706df26Smrg } 5507706df26Smrg 5517706df26Smrg if(xf86ReturnOptValBool(pTga->Options, OPTION_SYNC_ON_GREEN, FALSE)) { 5527706df26Smrg pTga->SyncOnGreen = TRUE; 5537706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n"); 5547706df26Smrg } 5557706df26Smrg 5567706df26Smrg if(xf86ReturnOptValBool(pTga->Options, OPTION_DAC_6_BIT, FALSE)) { 5577706df26Smrg pTga->Dac6Bit = TRUE; 5587706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "6 bit DAC enabled\n"); 5597706df26Smrg } 5607706df26Smrg 5617706df26Smrg if(xf86ReturnOptValBool(pTga->Options, OPTION_NOXAAPOLYSEGMENT, FALSE)) { 5627706df26Smrg pTga->NoXaaPolySegment = TRUE; 5637706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "XAA PolySegment() disabled\n"); 5647706df26Smrg } 5657706df26Smrg 5667706df26Smrg /* end option processing */ 5677706df26Smrg 5687706df26Smrg /* 5697706df26Smrg * This must happen after pScrn->display has been set because 5707706df26Smrg * xf86SetWeight references it. 5717706df26Smrg */ 5727706df26Smrg if (pScrn->depth > 8) { 5737706df26Smrg /* The defaults are OK for us */ 5747706df26Smrg rgb zeros = {0, 0, 0}; 5757706df26Smrg 5767706df26Smrg if (!xf86SetWeight(pScrn, zeros, zeros)) { 5777706df26Smrg return FALSE; 5787706df26Smrg } else { 5797706df26Smrg /* XXX check that weight returned is supported */ 5807706df26Smrg ; 5817706df26Smrg } 5827706df26Smrg } 5837706df26Smrg 5847706df26Smrg if (!xf86SetDefaultVisual(pScrn, -1)) { 5857706df26Smrg return FALSE; 5867706df26Smrg } else { 5877706df26Smrg /* We don't currently support DirectColor at > 8bpp */ 5887706df26Smrg if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 5897706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 5907706df26Smrg " (%s) is not supported at depth %d\n", 5917706df26Smrg xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 5927706df26Smrg return FALSE; 5937706df26Smrg } 5947706df26Smrg } 5957706df26Smrg 5967706df26Smrg /* 5977706df26Smrg * The new cmap code requires this to be initialised. 5987706df26Smrg */ 5997706df26Smrg 6007706df26Smrg { 6017706df26Smrg Gamma zeros = {0.0, 0.0, 0.0}; 6027706df26Smrg 6037706df26Smrg if (!xf86SetGamma(pScrn, zeros)) { 6047706df26Smrg return FALSE; 6057706df26Smrg } 6067706df26Smrg } 6077706df26Smrg 6087706df26Smrg /* Set the bits per RGB for 8bpp mode */ 6097706df26Smrg if (pScrn->depth == 8) { 6107706df26Smrg /* Default to 8 */ 6117706df26Smrg pScrn->rgbBits = 8; 6127706df26Smrg if(pTga->Dac6Bit) 6137706df26Smrg pScrn->rgbBits = 6; 6147706df26Smrg } 6157706df26Smrg from = X_DEFAULT; 6167706df26Smrg 6177706df26Smrg /* determine whether we use hardware or software cursor */ 6187706df26Smrg 6197706df26Smrg pTga->HWCursor = TRUE; 6207706df26Smrg if (xf86GetOptValBool(pTga->Options, OPTION_HW_CURSOR, &pTga->HWCursor)) 6217706df26Smrg from = X_CONFIG; 6227706df26Smrg if (xf86ReturnOptValBool(pTga->Options, OPTION_SW_CURSOR, FALSE)) { 6237706df26Smrg from = X_CONFIG; 6247706df26Smrg pTga->HWCursor = FALSE; 6257706df26Smrg } 6267706df26Smrg 6277706df26Smrg if(pScrn->depth != 8) { 6287706df26Smrg pTga->HWCursor = FALSE; 6297706df26Smrg from = X_WARNING; 6307706df26Smrg xf86DrvMsg(pScrn->scrnIndex, from, 6317706df26Smrg "Hardware cursor currently only works with BT485 ramdac\n"); 6327706df26Smrg } 6337706df26Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", 6347706df26Smrg pTga->HWCursor ? "HW" : "SW"); 6357706df26Smrg 6367706df26Smrg if (xf86ReturnOptValBool(pTga->Options, OPTION_NOACCEL, FALSE)) { 6377706df26Smrg pTga->NoAccel = TRUE; 6387706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); 6397706df26Smrg } 6407706df26Smrg 6417706df26Smrg if (pTga->pEnt->device->MemBase != 0) { 6427706df26Smrg pTga->CardAddress = pTga->pEnt->device->MemBase; 6437706df26Smrg from = X_CONFIG; 6447706df26Smrg } else { 645047944f3Smrg pTga->CardAddress = PCI_REGION_BASE(pTga->PciInfo, 0, REGION_MEM) & 0xFFC00000;/*??*/ 6467706df26Smrg } 6477706df26Smrg 6487706df26Smrg pTga->FbAddress = pTga->CardAddress; 6497706df26Smrg /* Adjust MMIO region */ 6507706df26Smrg pTga->IOAddress = pTga->CardAddress + TGA_REGS_OFFSET; 6517706df26Smrg 6527706df26Smrg 6537706df26Smrg /********************* 6547706df26Smrg determine what sort of TGA card we have -- the only differences are 6557706df26Smrg framebuffer size and ramdac type, all TGA cards use 21030 chips 6567706df26Smrg *********************/ 6577706df26Smrg 6587706df26Smrg /* check what the user has specified in XF86Config */ 6597706df26Smrg if(pTga->pEnt->device->videoRam) { 6607706df26Smrg switch(pTga->pEnt->device->videoRam) { 6617706df26Smrg case 2048: 6627706df26Smrg pTga->CardType = TYPE_TGA_8PLANE; 6637706df26Smrg break; 6647706df26Smrg case 8192: 6657706df26Smrg pTga->CardType = TYPE_TGA_24PLANE; 6667706df26Smrg break; 6677706df26Smrg case 16384: 6687706df26Smrg pTga->CardType = TYPE_TGA_24PLUSZ; 6697706df26Smrg break; 6707706df26Smrg default: 6717706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 6727706df26Smrg "%d KB video RAM specified, driver only supports 2048, 8192, or 16384 KB cards\n", 6737706df26Smrg pTga->pEnt->device->videoRam); 6747706df26Smrg return FALSE; 6757706df26Smrg } 6767706df26Smrg } 6777706df26Smrg else { /* try to divine the amount of RAM */ 6787706df26Smrg switch (pTga->Chipset) 6797706df26Smrg { 6807706df26Smrg case PCI_CHIP_TGA2: 681047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 6827706df26Smrg Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, 6837706df26Smrg pTga->PciTag, pTga->IOAddress, 0x1000); 684047944f3Smrg 685047944f3Smrg#else 686047944f3Smrg { 687047944f3Smrg void** result = (void**)&Base; 688047944f3Smrg int err = pci_device_map_range(pTga->PciInfo, 689047944f3Smrg pTga->IOAddress, 690047944f3Smrg 0x1000, 691047944f3Smrg PCI_DEV_MAP_FLAG_WRITABLE, 692047944f3Smrg result); 693047944f3Smrg if (err) 694047944f3Smrg return FALSE; 695047944f3Smrg } 696047944f3Smrg#endif 6977706df26Smrg pTga->CardType = (*(unsigned int *)((char *)Base+TGA_REVISION_REG) >> 21) & 0x3; 6987706df26Smrg pTga->CardType ^= (pTga->CardType == 1) ? 0 : 3; 699047944f3Smrg 700047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 7017706df26Smrg xf86UnMapVidMem(pScrn->scrnIndex, Base, 0x1000); 702047944f3Smrg#else 703047944f3Smrg pci_device_unmap_range(pTga->PciInfo, Base, 0x1000); 704047944f3Smrg#endif 7057706df26Smrg break; 7067706df26Smrg case PCI_CHIP_DEC21030: 707047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 7087706df26Smrg Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, 7097706df26Smrg pTga->PciTag, pTga->FbAddress, 4); 710047944f3Smrg#else 711047944f3Smrg { 712047944f3Smrg void** result = (void**)&Base; 713047944f3Smrg int err = pci_device_map_range(pTga->PciInfo, 714047944f3Smrg pTga->FbAddress, 715047944f3Smrg 0x4, 716047944f3Smrg PCI_DEV_MAP_FLAG_WRITABLE, 717047944f3Smrg result); 718047944f3Smrg if (err) 719047944f3Smrg return FALSE; 720047944f3Smrg } 721047944f3Smrg#endif 7227706df26Smrg pTga->CardType = (*(unsigned int *)Base >> 12) & 0xf; 723047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 7247706df26Smrg xf86UnMapVidMem(pScrn->scrnIndex, Base, 4); 725047944f3Smrg#else 726047944f3Smrg pci_device_unmap_range(pTga->PciInfo, Base, 4); 727047944f3Smrg#endif 7287706df26Smrg break; 7297706df26Smrg } 7307706df26Smrg } 7317706df26Smrg 7327706df26Smrg switch (pTga->CardType) { 7337706df26Smrg case TYPE_TGA_8PLANE: 7347706df26Smrg case TYPE_TGA_24PLANE: 7357706df26Smrg case TYPE_TGA_24PLUSZ: 7367706df26Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Card Name: \"%s\"\n", 7377706df26Smrg tga_cardnames[pTga->CardType]); 7387706df26Smrg break; 7397706df26Smrg default: 7407706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 7417706df26Smrg "Card \"0x%02x\" is not recognised\n", pTga->CardType); 7427706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 7437706df26Smrg "Assuming 8 plane TGA with 2MB frame buffer\n"); 7447706df26Smrg pTga->CardType = TYPE_TGA_8PLANE; 7457706df26Smrg break; 7467706df26Smrg } 7477706df26Smrg 7487706df26Smrg /* Adjust framebuffer for card type */ 7497706df26Smrg pTga->FbAddress += fb_offset_presets[pTga->CardType]; 7507706df26Smrg 7517706df26Smrg if (!(((pScrn->depth == 8) && (pTga->CardType == TYPE_TGA_8PLANE)) || 7527706df26Smrg ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLANE)) || 7537706df26Smrg ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLUSZ)))) { 7547706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 7557706df26Smrg "Given depth (%d) is not supported by this card\n", 7567706df26Smrg pScrn->depth); 7577706df26Smrg return FALSE; 7587706df26Smrg } 7597706df26Smrg 7607706df26Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", 7617706df26Smrg (unsigned long)pTga->FbAddress); 7627706df26Smrg 7637706df26Smrg xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", 7647706df26Smrg (unsigned long)pTga->IOAddress); 7657706df26Smrg 7667ae0a258Smrg#ifndef XSERVER_LIBPCIACCESS 7677706df26Smrg /* RAC stuff: we don't have any resources we need to reserve, 7687706df26Smrg but we should do this here anyway */ 7697706df26Smrg if (xf86RegisterResources(pTga->pEnt->index, NULL, ResExclusive)) { 7707706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 7717706df26Smrg "xf86RegisterResources() found resource conflicts\n"); 7727706df26Smrg TGAFreeRec(pScrn); 7737706df26Smrg return FALSE; 7747706df26Smrg } 7757ae0a258Smrg#endif 7767706df26Smrg 7777706df26Smrg /* HW bpp matches reported bpp */ 7787706df26Smrg pTga->HwBpp = pScrn->bitsPerPixel; 7797706df26Smrg 7807706df26Smrg if (pTga->pEnt->device->videoRam != 0) { 7817706df26Smrg pScrn->videoRam = pTga->pEnt->device->videoRam; 7827706df26Smrg from = X_CONFIG; 7837706df26Smrg } else { 7847706df26Smrg switch (pTga->CardType) { 7857706df26Smrg case TYPE_TGA_8PLANE: 7867706df26Smrg pScrn->videoRam = 2*1024; 7877706df26Smrg break; 7887706df26Smrg case TYPE_TGA_24PLANE: 7897706df26Smrg pScrn->videoRam = 8*1024; 7907706df26Smrg break; 7917706df26Smrg case TYPE_TGA_24PLUSZ: 7927706df26Smrg pScrn->videoRam = 16*1024; 7937706df26Smrg break; 7947706df26Smrg } 7957706df26Smrg } 7967706df26Smrg 7977706df26Smrg xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n", 7987706df26Smrg pScrn->videoRam); 7997706df26Smrg 8007706df26Smrg pTga->FbMapSize = pScrn->videoRam * 1024; 8017706df26Smrg 8027706df26Smrg if (xf86LoadSubModule(pScrn, "fb") == NULL) { 8037706df26Smrg TGAFreeRec(pScrn); 8047706df26Smrg return FALSE; 8057706df26Smrg } 8067706df26Smrg 8077706df26Smrg /* Load XAA if needed */ 8087706df26Smrg if (!pTga->NoAccel || pTga->HWCursor) { 8097706df26Smrg if (!xf86LoadSubModule(pScrn, "xaa")) { 8107706df26Smrg TGAFreeRec(pScrn); 8117706df26Smrg return FALSE; 8127706df26Smrg } 8137706df26Smrg } 8147706df26Smrg 8157706df26Smrg 8167706df26Smrg /********************* 8177706df26Smrg Let's check what type of DAC we have and reject if necessary 8187706df26Smrg *********************/ 8197706df26Smrg 8207706df26Smrg pTga->RamDac = NULL; 8217706df26Smrg 8227706df26Smrg if (pTga->CardType != TYPE_TGA_8PLANE) { 8237706df26Smrg pTga->RamDacRec = NULL; 8247706df26Smrg pTga->RamDac = NULL; 8257706df26Smrg } else { 8267706df26Smrg 8277706df26Smrg pTga->RamDacRec = RamDacCreateInfoRec(); 8287706df26Smrg switch (pTga->Chipset) 8297706df26Smrg { 8307706df26Smrg case PCI_CHIP_DEC21030: 8317706df26Smrg pTga->RamDacRec->ReadDAC = tgaBTInIndReg; 8327706df26Smrg pTga->RamDacRec->WriteDAC = tgaBTOutIndReg; 8337706df26Smrg pTga->RamDacRec->ReadAddress = tgaBTReadAddress; 8347706df26Smrg pTga->RamDacRec->WriteAddress = tgaBTWriteAddress; 8357706df26Smrg pTga->RamDacRec->ReadData = tgaBTReadData; 8367706df26Smrg pTga->RamDacRec->WriteData = tgaBTWriteData; 8377706df26Smrg break; 8387706df26Smrg case PCI_CHIP_TGA2: 8397706df26Smrg pTga->RamDacRec->ReadDAC = tga2BTInIndReg; 8407706df26Smrg pTga->RamDacRec->WriteDAC = tga2BTOutIndReg; 8417706df26Smrg pTga->RamDacRec->ReadAddress = tga2BTReadAddress; 8427706df26Smrg pTga->RamDacRec->WriteAddress = tga2BTWriteAddress; 8437706df26Smrg pTga->RamDacRec->ReadData = tga2BTReadData; 8447706df26Smrg pTga->RamDacRec->WriteData = tga2BTWriteData; 8457706df26Smrg break; 8467706df26Smrg } 8477706df26Smrg 8487706df26Smrg if (!RamDacInit(pScrn, pTga->RamDacRec)) { 8497706df26Smrg RamDacDestroyInfoRec(pTga->RamDacRec); 8507706df26Smrg return FALSE; 8517706df26Smrg } 8527706df26Smrg 8537706df26Smrg TGAMapMem(pScrn); 8547706df26Smrg 8557706df26Smrg pTga->RamDac = BTramdacProbe(pScrn, BTramdacs); 8567706df26Smrg 8577706df26Smrg TGAUnmapMem(pScrn); 8587706df26Smrg 8597706df26Smrg if (pTga->RamDac == NULL) 8607706df26Smrg return FALSE; 8617706df26Smrg } 8627706df26Smrg 8637706df26Smrg /********************* 8647706df26Smrg set up clock and mode stuff 8657706df26Smrg *********************/ 8667706df26Smrg 8677706df26Smrg pScrn->progClock = TRUE; 8687706df26Smrg 8697706df26Smrg /* Set the min pixel clock */ 8707706df26Smrg pTga->MinClock = 16250; /* XXX Guess, need to check this */ 8717706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n", 8727706df26Smrg pTga->MinClock / 1000); 8737706df26Smrg 8747706df26Smrg /* 8757706df26Smrg * If the user has specified ramdac speed in the XF86Config 8767706df26Smrg * file, we respect that setting. 8777706df26Smrg */ 8787706df26Smrg if (pTga->pEnt->device->dacSpeeds[0]) { 8797706df26Smrg int speed = 0; 8807706df26Smrg 8817706df26Smrg switch (pScrn->bitsPerPixel) { 8827706df26Smrg case 8: 8837706df26Smrg speed = pTga->pEnt->device->dacSpeeds[DAC_BPP8]; 8847706df26Smrg break; 8857706df26Smrg case 32: 8867706df26Smrg speed = pTga->pEnt->device->dacSpeeds[DAC_BPP32]; 8877706df26Smrg break; 8887706df26Smrg } 8897706df26Smrg if (speed == 0) 8907706df26Smrg pTga->MaxClock = pTga->pEnt->device->dacSpeeds[0]; 8917706df26Smrg else 8927706df26Smrg pTga->MaxClock = speed; 8937706df26Smrg from = X_CONFIG; 8947706df26Smrg } else { 8957706df26Smrg switch (pTga->Chipset) { 8967706df26Smrg case PCI_CHIP_DEC21030: 8977706df26Smrg pTga->MaxClock = 135000; 8987706df26Smrg break; 8997706df26Smrg case PCI_CHIP_TGA2: 9007706df26Smrg pTga->MaxClock = 170000; 9017706df26Smrg break; 9027706df26Smrg } 9037706df26Smrg } 9047706df26Smrg xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n", 9057706df26Smrg pTga->MaxClock / 1000); 9067706df26Smrg 9077706df26Smrg /* 9087706df26Smrg * Setup the ClockRanges, which describe what clock ranges are available, 9097706df26Smrg * and what sort of modes they can be used for. 9107706df26Smrg */ 9117706df26Smrg clockRanges = xnfcalloc(sizeof(ClockRange), 1); 9127706df26Smrg clockRanges->next = NULL; 9137706df26Smrg clockRanges->minClock = pTga->MinClock; 9147706df26Smrg clockRanges->maxClock = pTga->MaxClock; 9157706df26Smrg clockRanges->clockIndex = -1; /* programmable */ 9167706df26Smrg clockRanges->interlaceAllowed = FALSE; /* XXX check this */ 9177706df26Smrg clockRanges->doubleScanAllowed = FALSE; /* XXX check this */ 9187706df26Smrg 9197706df26Smrg if(pScrn->display->virtualX || pScrn->display->virtualY) { 9207706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 9217706df26Smrg "TGA does not support a virtual desktop\n"); 9227706df26Smrg pScrn->display->virtualX = 0; 9237706df26Smrg pScrn->display->virtualY = 0; 9247706df26Smrg } 9257706df26Smrg 9267706df26Smrg /* 9277706df26Smrg * xf86ValidateModes will check that the mode HTotal and VTotal values 9287706df26Smrg * don't exceed the chipset's limit if pScrn->maxHValue and 9297706df26Smrg * pScrn->maxVValue are set. Since our TGAValidMode() already takes 9307706df26Smrg * care of this, we don't worry about setting them here. 9317706df26Smrg */ 9327706df26Smrg /* Select valid modes from those available */ 9337706df26Smrg /* 9347706df26Smrg * XXX Assuming min pitch 256, max 2048 9357706df26Smrg * XXX Assuming min height 128, max 2048 9367706df26Smrg */ 9377706df26Smrg i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 9387706df26Smrg pScrn->display->modes, clockRanges, 9397706df26Smrg NULL, 256, 2048, 9407706df26Smrg pScrn->bitsPerPixel, 128, 2048, 9417706df26Smrg pScrn->display->virtualX, 9427706df26Smrg pScrn->display->virtualY, 9437706df26Smrg pTga->FbMapSize, 9447706df26Smrg LOOKUP_BEST_REFRESH); 9457706df26Smrg 9467706df26Smrg if (i == -1) { 9477706df26Smrg TGAFreeRec(pScrn); 9487706df26Smrg return FALSE; 9497706df26Smrg } 9507706df26Smrg 9517706df26Smrg /* Prune the modes marked as invalid */ 9527706df26Smrg xf86PruneDriverModes(pScrn); 9537706df26Smrg 9547706df26Smrg if (i == 0 || pScrn->modes == NULL) { 9557706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 9567706df26Smrg TGAFreeRec(pScrn); 9577706df26Smrg return FALSE; 9587706df26Smrg } 9597706df26Smrg 9607706df26Smrg if(i > 1) { 9617706df26Smrg DisplayModePtr mp1 = NULL, mp2 = NULL; 9627706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 9637706df26Smrg "TGA only supports one mode, using first mode.\n"); 9647706df26Smrg mp1 = pScrn->modes->next; 9657706df26Smrg mp2 = mp1; 9667706df26Smrg while(mp1 && mp1->next != mp1) { 9677706df26Smrg mp1 = mp1->next; 9687706df26Smrg xf86DeleteMode(&(pScrn->modes), mp2); 9697706df26Smrg mp2 = mp1; 9707706df26Smrg } 9717706df26Smrg } 9727706df26Smrg 9737706df26Smrg xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 9747706df26Smrg 9757706df26Smrg /* Set the current mode to the first in the list */ 9767706df26Smrg pScrn->currentMode = pScrn->modes; 9777706df26Smrg 9787706df26Smrg /* 9797706df26Smrg This is a bit of a hack; we seem to have to init 9807706df26Smrg the TGA2 chipset knowing what the mode is, so we 9817706df26Smrg do this now as soon as we know it... 9827706df26Smrg */ 9837706df26Smrg if (pTga->Chipset == PCI_CHIP_TGA2) { 9847706df26Smrg TGA2SetupMode(pScrn); 9857706df26Smrg } 9867706df26Smrg 9877706df26Smrg /* Print the list of modes being used */ 9887706df26Smrg xf86PrintModes(pScrn); 9897706df26Smrg 9907706df26Smrg /* Set display resolution */ 9917706df26Smrg xf86SetDpi(pScrn, 0, 0); 9927706df26Smrg 9937706df26Smrg return TRUE; 9947706df26Smrg} 9957706df26Smrg 9967706df26Smrg 9977706df26Smrg/* 9987706df26Smrg * Map the framebuffer and MMIO memory. 9997706df26Smrg */ 10007706df26Smrg 10017706df26Smrgstatic Bool 10027706df26SmrgTGAMapMem(ScrnInfoPtr pScrn) 10037706df26Smrg{ 10047706df26Smrg TGAPtr pTga; 10057706df26Smrg 10067706df26Smrg pTga = TGAPTR(pScrn); 10077706df26Smrg 10087706df26Smrg /* 10097706df26Smrg * Map IO registers to virtual address space 10107706df26Smrg */ 10117706df26Smrg 10127706df26Smrg /* TGA doesn't need a sparse memory mapping, because all register 10137706df26Smrg accesses are doublewords */ 1014047944f3Smrg 1015047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 10167706df26Smrg pTga->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, 10177706df26Smrg pTga->PciTag, 10187706df26Smrg pTga->IOAddress, 0x100000); 1019047944f3Smrg#else 1020047944f3Smrg { 1021047944f3Smrg void** result = (void**)&pTga->IOBase; 1022047944f3Smrg int err = pci_device_map_range(pTga->PciInfo, 1023047944f3Smrg pTga->IOAddress, 1024047944f3Smrg 0x100000, 1025047944f3Smrg PCI_DEV_MAP_FLAG_WRITABLE, 1026047944f3Smrg result); 1027047944f3Smrg if (err) 1028047944f3Smrg return FALSE; 1029047944f3Smrg } 1030047944f3Smrg#endif 10317706df26Smrg if (pTga->IOBase == NULL) 10327706df26Smrg return FALSE; 10337706df26Smrg 1034047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 10357706df26Smrg pTga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 10367706df26Smrg pTga->PciTag, 10377706df26Smrg (unsigned long)pTga->FbAddress, 10387706df26Smrg pTga->FbMapSize); 1039047944f3Smrg#else 1040047944f3Smrg { 1041047944f3Smrg void** result = (void**)&pTga->FbBase; 1042047944f3Smrg int err = pci_device_map_range(pTga->PciInfo, 1043047944f3Smrg pTga->FbAddress, 1044047944f3Smrg pTga->FbMapSize, 1045047944f3Smrg PCI_DEV_MAP_FLAG_WRITABLE | 1046047944f3Smrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 1047047944f3Smrg result); 1048047944f3Smrg if (err) 1049047944f3Smrg return FALSE; 1050047944f3Smrg } 1051047944f3Smrg#endif 10527706df26Smrg if (pTga->FbBase == NULL) 10537706df26Smrg return FALSE; 10547706df26Smrg 10557706df26Smrg if (pTga->Chipset == PCI_CHIP_DEC21030) 10567706df26Smrg return TRUE; 10577706df26Smrg 1058047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 10597706df26Smrg pTga->ClkBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, 10607706df26Smrg pTga->PciTag, 10617706df26Smrg (unsigned long)pTga->CardAddress + TGA2_CLOCK_OFFSET, 10627706df26Smrg 0x10000); 1063047944f3Smrg#else 1064047944f3Smrg { 1065047944f3Smrg void** result = (void**)&pTga->ClkBase; 1066047944f3Smrg int err = pci_device_map_range(pTga->PciInfo, 1067047944f3Smrg pTga->CardAddress + TGA2_CLOCK_OFFSET, 1068047944f3Smrg 0x10000, 1069047944f3Smrg PCI_DEV_MAP_FLAG_WRITABLE, 1070047944f3Smrg result); 1071047944f3Smrg if (err) 1072047944f3Smrg return FALSE; 1073047944f3Smrg } 1074047944f3Smrg#endif 10757706df26Smrg if (pTga->ClkBase == NULL) 10767706df26Smrg return FALSE; 10777706df26Smrg 1078047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 10797706df26Smrg pTga->DACBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO_32BIT, 10807706df26Smrg pTga->PciTag, 10817706df26Smrg (unsigned long)pTga->CardAddress + TGA2_RAMDAC_OFFSET, 10827706df26Smrg 0x10000); 1083047944f3Smrg#else 1084047944f3Smrg { 1085047944f3Smrg void** result = (void**)&pTga->DACBase; 1086047944f3Smrg int err = pci_device_map_range(pTga->PciInfo, 1087047944f3Smrg pTga->CardAddress + TGA2_RAMDAC_OFFSET, 1088047944f3Smrg 0x10000, 1089047944f3Smrg PCI_DEV_MAP_FLAG_WRITABLE, 1090047944f3Smrg result); 1091047944f3Smrg if (err) 1092047944f3Smrg return FALSE; 1093047944f3Smrg } 1094047944f3Smrg#endif 10957706df26Smrg if (pTga->DACBase == NULL) 10967706df26Smrg return FALSE; 10977706df26Smrg 10987706df26Smrg /* 10997706df26Smrg * This is a hack specifically for the TGA2 code, as it sometimes 11007706df26Smrg * calculates/uses addresses in TGA2 memory which are NOT mmapped 11017706df26Smrg * by the normal framebuffer code above. This most frequently occurs 11027706df26Smrg * when displaying something close to the top-left corner (in the 11037706df26Smrg * routines CopyLine{Forwards,Backwards}. 11047706df26Smrg * 11057706df26Smrg * This could most likely also be fixed by further modifying the 11067706df26Smrg * code, but it (the code) is ugly enough already... ;-} 11077706df26Smrg * 11087706df26Smrg * So, the workaround is to simply mmap an additional PAGE of 11097706df26Smrg * framebuffer memory in front of the normal mmap to prevent 11107706df26Smrg * SEGVs from happening. 11117706df26Smrg */ 1112047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 11137706df26Smrg pTga->HACKBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 11147706df26Smrg pTga->PciTag, 11157706df26Smrg (unsigned long)pTga->FbAddress - getpagesize(), 11167706df26Smrg getpagesize()); 1117047944f3Smrg#else 1118047944f3Smrg { 1119047944f3Smrg void** result = (void**)&pTga->DACBase; 1120047944f3Smrg int err = pci_device_map_range(pTga->PciInfo, 1121047944f3Smrg pTga->FbAddress - getpagesize(), 1122047944f3Smrg getpagesize(), 1123047944f3Smrg PCI_DEV_MAP_FLAG_WRITABLE | 1124047944f3Smrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 1125047944f3Smrg result); 1126047944f3Smrg if (err) 1127047944f3Smrg return FALSE; 1128047944f3Smrg } 1129047944f3Smrg#endif 1130047944f3Smrg 11317706df26Smrg if (pTga->HACKBase == NULL) 11327706df26Smrg return FALSE; 11337706df26Smrg 11347706df26Smrg return TRUE; 11357706df26Smrg} 11367706df26Smrg 11377706df26Smrg 11387706df26Smrg/* 11397706df26Smrg * Unmap the framebuffer and MMIO memory. 11407706df26Smrg */ 11417706df26Smrg 11427706df26Smrgstatic Bool 11437706df26SmrgTGAUnmapMem(ScrnInfoPtr pScrn) 11447706df26Smrg{ 11457706df26Smrg TGAPtr pTga; 11467706df26Smrg 11477706df26Smrg pTga = TGAPTR(pScrn); 11487706df26Smrg 1149047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 11507706df26Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->IOBase, 0x100000); 1151047944f3Smrg#else 1152047944f3Smrg pci_device_unmap_range(pTga->PciInfo, pTga->IOBase, 0x100000); 1153047944f3Smrg#endif 11547706df26Smrg pTga->IOBase = NULL; 11557706df26Smrg 1156047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 11577706df26Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->FbBase, pTga->FbMapSize); 1158047944f3Smrg#else 1159047944f3Smrg pci_device_unmap_range(pTga->PciInfo, pTga->FbBase, pTga->FbMapSize); 1160047944f3Smrg#endif 11617706df26Smrg pTga->FbBase = NULL; 11627706df26Smrg 11637706df26Smrg if (pTga->Chipset == PCI_CHIP_DEC21030) 11647706df26Smrg return TRUE; 11657706df26Smrg 1166047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 11677706df26Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->ClkBase, 0x10000); 1168047944f3Smrg#else 1169047944f3Smrg pci_device_unmap_range(pTga->PciInfo, pTga->ClkBase, 0x10000); 1170047944f3Smrg#endif 11717706df26Smrg pTga->ClkBase = NULL; 11727706df26Smrg 1173047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 11747706df26Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->DACBase, 0x10000); 1175047944f3Smrg#else 1176047944f3Smrg pci_device_unmap_range(pTga->PciInfo, pTga->DACBase, 0x10000); 1177047944f3Smrg#endif 11787706df26Smrg pTga->DACBase = NULL; 11797706df26Smrg 1180047944f3Smrg#ifndef XSERVER_LIBPCIACCESS 11817706df26Smrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->HACKBase, getpagesize()); 1182047944f3Smrg#else 1183047944f3Smrg pci_device_unmap_range(pTga->PciInfo, pTga->HACKBase, getpagesize()); 1184047944f3Smrg#endif 11857706df26Smrg pTga->HACKBase = NULL; 11867706df26Smrg 11877706df26Smrg return TRUE; 11887706df26Smrg} 11897706df26Smrg 11907706df26Smrg 11917706df26Smrg/* 11927706df26Smrg * This function saves the video state. 11937706df26Smrg */ 11947706df26Smrgstatic void 11957706df26SmrgTGASave(ScrnInfoPtr pScrn) 11967706df26Smrg{ 11977706df26Smrg TGAPtr pTga; 11987706df26Smrg TGARegPtr tgaReg; 11997706df26Smrg RamDacHWRecPtr pBT; 12007706df26Smrg RamDacRegRecPtr BTreg; 12017706df26Smrg 12027706df26Smrg pTga = TGAPTR(pScrn); 12037706df26Smrg tgaReg = &pTga->SavedReg; 12047706df26Smrg 12057706df26Smrg DEC21030Save(pScrn, tgaReg); 12067706df26Smrg if (pTga->RamDac) { /* must be BT485... */ 12077706df26Smrg pBT = RAMDACHWPTR(pScrn); 12087706df26Smrg BTreg = &pBT->SavedReg; 12097706df26Smrg (*pTga->RamDac->Save)(pScrn, pTga->RamDacRec, BTreg); 12107706df26Smrg } else switch (pTga->Chipset) 12117706df26Smrg { 12127706df26Smrg case PCI_CHIP_TGA2: 12137706df26Smrg IBM561ramdacSave(pScrn, pTga->Ibm561saveReg); 12147706df26Smrg break; 12157706df26Smrg case PCI_CHIP_DEC21030: 12167706df26Smrg BT463ramdacSave(pScrn, pTga->Bt463saveReg); 12177706df26Smrg break; 12187706df26Smrg } 12197706df26Smrg} 12207706df26Smrg 12217706df26Smrg 12227706df26Smrg/* 12237706df26Smrg * Initialise a new mode. This is currently still using the old 12247706df26Smrg * "initialise struct, restore/write struct to HW" model. That could 12257706df26Smrg * be changed. 12267706df26Smrg */ 12277706df26Smrg 12287706df26Smrgstatic Bool 12297706df26SmrgTGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 12307706df26Smrg{ 12317706df26Smrg int ret = -1; 12327706df26Smrg TGAPtr pTga; 12337706df26Smrg TGARegPtr tgaReg; 12347706df26Smrg RamDacHWRecPtr pBT; 12357706df26Smrg RamDacRegRecPtr BTreg; 12367706df26Smrg 12377706df26Smrg pTga = TGAPTR(pScrn); 12387706df26Smrg 12397706df26Smrg pScrn->vtSema = TRUE; 12407706df26Smrg 12417706df26Smrg ret = DEC21030Init(pScrn, mode); 12427706df26Smrg 12437706df26Smrg if (pTga->Chipset == PCI_CHIP_TGA2 && pTga->RamDac == NULL) 12447706df26Smrg IBM561ramdacHWInit(pScrn); 12457706df26Smrg 12467706df26Smrg if (!ret) 12477706df26Smrg return FALSE; 12487706df26Smrg 12497706df26Smrg /* Program the registers */ 12507706df26Smrg tgaReg = &pTga->ModeReg; 12517706df26Smrg 12527706df26Smrg DEC21030Restore(pScrn, tgaReg); 12537706df26Smrg 12547706df26Smrg if (pTga->RamDac != NULL) { 12557706df26Smrg pBT = RAMDACHWPTR(pScrn); 12567706df26Smrg BTreg = &pBT->ModeReg; 12577706df26Smrg (*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg); 12587706df26Smrg if (pTga->Chipset == PCI_CHIP_TGA2) { 12597706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); 12607706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x0c); 12617706df26Smrg } 12627706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff); 12637706df26Smrg } else { 12647706df26Smrg switch (pTga->Chipset) { 12657706df26Smrg case PCI_CHIP_TGA2: 12667706df26Smrg IBM561ramdacRestore(pScrn, pTga->Ibm561modeReg); 12677706df26Smrg break; 12687706df26Smrg case PCI_CHIP_DEC21030: 12697706df26Smrg BT463ramdacRestore(pScrn, pTga->Bt463modeReg); 12707706df26Smrg break; 12717706df26Smrg } 12727706df26Smrg } 12737706df26Smrg return TRUE; 12747706df26Smrg} 12757706df26Smrg 12767706df26Smrg/* 12777706df26Smrg * Restore the initial (text) mode. 12787706df26Smrg */ 12797706df26Smrgstatic void 12807706df26SmrgTGARestore(ScrnInfoPtr pScrn) 12817706df26Smrg{ 12827706df26Smrg TGAPtr pTga; 12837706df26Smrg TGARegPtr tgaReg; 12847706df26Smrg RamDacHWRecPtr pBT; 12857706df26Smrg RamDacRegRecPtr BTreg; 12867706df26Smrg 12877706df26Smrg pTga = TGAPTR(pScrn); 12887706df26Smrg tgaReg = &pTga->SavedReg; 12897706df26Smrg 12907706df26Smrg /* Initial Text mode clock */ 12917706df26Smrg tgaReg->tgaRegs[0x0A] = 25175; 12927706df26Smrg 12937706df26Smrg DEC21030Restore(pScrn, tgaReg); 12947706df26Smrg 12957706df26Smrg if (pTga->RamDac != NULL) { 12967706df26Smrg pBT = RAMDACHWPTR(pScrn); 12977706df26Smrg BTreg = &pBT->SavedReg; 12987706df26Smrg (*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg); 12997706df26Smrg if (pTga->Chipset == PCI_CHIP_TGA2) { 13007706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); 13017706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0x00, 0x00); 13027706df26Smrg } 13037706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_PIXEL_MASK, 0x00, 0xff); 13047706df26Smrg } else switch (pTga->Chipset) { 13057706df26Smrg case PCI_CHIP_TGA2: 13067706df26Smrg IBM561ramdacRestore(pScrn, pTga->Ibm561saveReg); 13077706df26Smrg break; 13087706df26Smrg case PCI_CHIP_DEC21030: 13097706df26Smrg BT463ramdacRestore(pScrn, pTga->Bt463saveReg); 13107706df26Smrg break; 13117706df26Smrg } 13127706df26Smrg 13137706df26Smrg if (pTga->HWCursor) 13147706df26Smrg TGARestoreHWCursor(pScrn); 13157706df26Smrg} 13167706df26Smrg 13177706df26Smrg 13187706df26Smrg/* Mandatory */ 13197706df26Smrg 13207706df26Smrg/* This gets called at the start of each server generation */ 13217706df26Smrg 13227706df26Smrgstatic Bool 1323b92e825aSmrgTGAScreenInit(SCREEN_INIT_ARGS_DECL) 13247706df26Smrg{ 13257706df26Smrg ScrnInfoPtr pScrn; 13267706df26Smrg TGAPtr pTga; 13277706df26Smrg int ret; 13287706df26Smrg VisualPtr visual; 13297706df26Smrg 13307706df26Smrg /* 13317706df26Smrg * First get the ScrnInfoRec 13327706df26Smrg */ 1333b92e825aSmrg pScrn = xf86ScreenToScrn(pScreen); 13347706df26Smrg pTga = TGAPTR(pScrn); 13357706df26Smrg 13367706df26Smrg /* Map the TGA memory and MMIO areas */ 13377706df26Smrg if (!TGAMapMem(pScrn)) 13387706df26Smrg return FALSE; 13397706df26Smrg 13407706df26Smrg#if 1 13417706df26Smrg /* dump original register contents */ 13427706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MODE 0x%x\n", 13437706df26Smrg TGA_READ_REG(TGA_MODE_REG)); 13447706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VALID 0x%x\n", 13457706df26Smrg TGA_READ_REG(TGA_VALID_REG)); 13467706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "DEEP 0x%x\n", 13477706df26Smrg TGA_READ_REG(TGA_DEEP_REG)); 13487706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXSH 0x%x\n", 13497706df26Smrg TGA_READ_REG(TGA_PIXELSHIFT_REG)); 13507706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ROP 0x%x\n", 13517706df26Smrg TGA_READ_REG(TGA_RASTEROP_REG)); 13527706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "HORIZ 0x%x\n", 13537706df26Smrg TGA_READ_REG(TGA_HORIZ_REG)); 13547706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VERT 0x%x\n", 13557706df26Smrg TGA_READ_REG(TGA_VERT_REG)); 13567706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PIXMSK 0x%x\n", 13577706df26Smrg TGA_READ_REG(TGA_PIXELMASK_REG)); 13587706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "REV 0x%x\n", 13597706df26Smrg TGA_READ_REG(TGA_REVISION_REG)); 13607706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VADDR 0x%x\n", 13617706df26Smrg TGA_READ_REG(TGA_BASE_ADDR_REG)); 13627706df26Smrg#endif 13637706df26Smrg 13647706df26Smrg /* Save the current state */ 13657706df26Smrg TGASave(pScrn); 13667706df26Smrg 13677706df26Smrg /* Initialise the first mode */ 13687706df26Smrg TGAModeInit(pScrn, pScrn->currentMode); 13697706df26Smrg 13707706df26Smrg /* Darken the screen for aesthetic reasons and set the viewport */ 13717706df26Smrg TGASaveScreen(pScreen, SCREEN_SAVER_ON); 13727706df26Smrg 13737706df26Smrg /* 13747706df26Smrg * The next step is to setup the screen's visuals, and initialise the 13757706df26Smrg * framebuffer code. In cases where the framebuffer's default 13767706df26Smrg * choices for things like visual layouts and bits per RGB are OK, 13777706df26Smrg * this may be as simple as calling the framebuffer's ScreenInit() 13787706df26Smrg * function. If not, the visuals will need to be setup before calling 13797706df26Smrg * a fb ScreenInit() function and fixed up after. 13807706df26Smrg * 13817706df26Smrg * For most PC hardware at depths >= 8, the defaults that fb uses 13827706df26Smrg * are not appropriate. In this driver, we fixup the visuals after. 13837706df26Smrg */ 13847706df26Smrg 13857706df26Smrg /* 13867706df26Smrg * Reset visual list. 13877706df26Smrg */ 13887706df26Smrg miClearVisualTypes(); 13897706df26Smrg 13907706df26Smrg /* Setup the visuals we support. */ 13917706df26Smrg 13927706df26Smrg /* 13937706df26Smrg * For bpp > 8, the default visuals are not acceptable because we only 13947706df26Smrg * support TrueColor and not DirectColor. To deal with this, call 13957706df26Smrg * miSetVisualTypes for each visual supported. 13967706df26Smrg */ 13977706df26Smrg 13987706df26Smrg if (pScrn->bitsPerPixel > 8) { 13997706df26Smrg if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, 14007706df26Smrg pScrn->defaultVisual)) 14017706df26Smrg return FALSE; 14027706df26Smrg } else { 14037706df26Smrg if (!miSetVisualTypes(pScrn->depth, 14047706df26Smrg miGetDefaultVisualMask(pScrn->depth), 14057706df26Smrg pScrn->rgbBits, pScrn->defaultVisual)) 14067706df26Smrg return FALSE; 14077706df26Smrg } 14087706df26Smrg 14097706df26Smrg miSetPixmapDepths (); 14107706df26Smrg 14117706df26Smrg /* 14127706df26Smrg * Call the framebuffer layer's ScreenInit function, and fill in other 14137706df26Smrg * pScreen fields. 14147706df26Smrg */ 14157706df26Smrg 14167706df26Smrg switch (pScrn->bitsPerPixel) { 14177706df26Smrg case 8: 14187706df26Smrg case 32: 14197706df26Smrg ret = fbScreenInit(pScreen, pTga->FbBase, pScrn->virtualX, 14207706df26Smrg pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 14217706df26Smrg pScrn->displayWidth, pScrn->bitsPerPixel); 14227706df26Smrg break; 14237706df26Smrg default: 1424b92e825aSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 14257706df26Smrg "Internal error: invalid bpp (%d) in TGAScrnInit\n", 14267706df26Smrg pScrn->bitsPerPixel); 14277706df26Smrg ret = FALSE; 14287706df26Smrg break; 14297706df26Smrg } 14307706df26Smrg if (!ret) 14317706df26Smrg return FALSE; 14327706df26Smrg 14337706df26Smrg xf86SetBlackWhitePixels(pScreen); 14347706df26Smrg 14357706df26Smrg if (pScrn->bitsPerPixel > 8) { 14367706df26Smrg /* Fixup RGB ordering */ 14377706df26Smrg visual = pScreen->visuals + pScreen->numVisuals; 14387706df26Smrg while (--visual >= pScreen->visuals) { 14397706df26Smrg if ((visual->class | DynamicClass) == DirectColor) { 14407706df26Smrg visual->offsetRed = pScrn->offset.red; 14417706df26Smrg visual->offsetGreen = pScrn->offset.green; 14427706df26Smrg visual->offsetBlue = pScrn->offset.blue; 14437706df26Smrg visual->redMask = pScrn->mask.red; 14447706df26Smrg visual->greenMask = pScrn->mask.green; 14457706df26Smrg visual->blueMask = pScrn->mask.blue; 14467706df26Smrg } 14477706df26Smrg } 14487706df26Smrg } 14497706df26Smrg 14507706df26Smrg /* must be after RGB ordering fixed */ 14517706df26Smrg 14527706df26Smrg fbPictureInit (pScreen, 0, 0); 14537706df26Smrg 14547706df26Smrg miInitializeBackingStore(pScreen); 14557706df26Smrg xf86SetBackingStore(pScreen); 14567706df26Smrg xf86SetSilkenMouse(pScreen); 14577706df26Smrg 14587706df26Smrg /* we should ALWAYS do this */ 14597706df26Smrg if (pScrn->bitsPerPixel == 8) { 14607706df26Smrg TGA_WRITE_REG(SIMPLE | X11 | BPP8PACKED, TGA_MODE_REG); 14617706df26Smrg TGA_WRITE_REG(0x3 | BPP8PACKED, TGA_RASTEROP_REG); 14627706df26Smrg if (pTga->Chipset == PCI_CHIP_TGA2) 14637706df26Smrg TGA_WRITE_REG(2 << 28, TGA_DEEP_REG); 14647706df26Smrg } else { 14657706df26Smrg TGA_WRITE_REG(SIMPLE | X11 | BPP24, TGA_MODE_REG); 14667706df26Smrg TGA_WRITE_REG(0x3 | BPP24, TGA_RASTEROP_REG); 14677706df26Smrg if (pTga->Chipset == PCI_CHIP_TGA2) 14687706df26Smrg TGA_WRITE_REG((7 << 2) | 1 | (2 << 28), TGA_DEEP_REG); 14697706df26Smrg } 14707706df26Smrg TGA_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 14717706df26Smrg TGA_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); 14727706df26Smrg 14737706df26Smrg if (!pTga->NoAccel) { 14747706df26Smrg switch (pTga->Chipset) 14757706df26Smrg { 14767706df26Smrg case PCI_CHIP_TGA2: 14777706df26Smrg case PCI_CHIP_DEC21030: 14787706df26Smrg if(DEC21030AccelInit(pScreen) == FALSE) { 14797706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 14807706df26Smrg "XAA Initialization failed\n"); 14817706df26Smrg return(FALSE); 14827706df26Smrg } 14837706df26Smrg break; 14847706df26Smrg } 14857706df26Smrg } 14867706df26Smrg 14877706df26Smrg /* Initialise cursor functions */ 14887706df26Smrg miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); 14897706df26Smrg 14907706df26Smrg /* Initialize HW cursor layer. 14917706df26Smrg Must follow software cursor initialization*/ 14927706df26Smrg if (pTga->HWCursor) { 14937706df26Smrg if(!TGAHWCursorInit(pScreen)) { 14947706df26Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 14957706df26Smrg "Hardware cursor initialization failed\n"); 14967706df26Smrg return(FALSE); 14977706df26Smrg } 14987706df26Smrg } 14997706df26Smrg 15007706df26Smrg 15017706df26Smrg /* Initialise default colourmap */ 15027706df26Smrg if (!miCreateDefColormap(pScreen)) 15037706df26Smrg return FALSE; 15047706df26Smrg 15057706df26Smrg if ((pScrn->bitsPerPixel==8) && 15067706df26Smrg (!RamDacHandleColormaps(pScreen, 256, pScrn->rgbBits, 15077706df26Smrg CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))) 15087706df26Smrg return FALSE; 15097706df26Smrg 15107706df26Smrg pTga->CloseScreen = pScreen->CloseScreen; 15117706df26Smrg pScreen->CloseScreen = TGACloseScreen; 15127706df26Smrg pScreen->SaveScreen = TGASaveScreen; 15137706df26Smrg 15147706df26Smrg if(xf86DPMSInit(pScreen, TGADisplayPowerManagementSet, 0) == FALSE) 15157706df26Smrg ErrorF("DPMS initialization failed!\n"); 15167706df26Smrg 15177706df26Smrg { 15187706df26Smrg XF86VideoAdaptorPtr *ptr; 15197706df26Smrg int n; 15207706df26Smrg 15217706df26Smrg pScrn->memPhysBase = pTga->FbAddress; 15227706df26Smrg pScrn->fbOffset = 0; 15237706df26Smrg 15247706df26Smrg n = xf86XVListGenericAdaptors(pScrn,&ptr); 15257706df26Smrg 15267706df26Smrg if(n) { 15277706df26Smrg xf86XVScreenInit(pScreen, ptr, n); 15287706df26Smrg } 15297706df26Smrg 15307706df26Smrg } 15317706df26Smrg 15327706df26Smrg /* Report any unused options (only for the first generation) */ 15337706df26Smrg if (serverGeneration == 1) { 15347706df26Smrg xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 15357706df26Smrg } 15367706df26Smrg 15377706df26Smrg /* unblank the screen */ 15387706df26Smrg TGASaveScreen(pScreen, SCREEN_SAVER_OFF); 15397706df26Smrg 15407706df26Smrg /* Done */ 15417706df26Smrg return TRUE; 15427706df26Smrg} 15437706df26Smrg 15447706df26Smrg 15457706df26Smrg/* Usually mandatory */ 15467706df26Smrgstatic Bool 1547b92e825aSmrgTGASwitchMode(SWITCH_MODE_ARGS_DECL) 15487706df26Smrg{ 1549b92e825aSmrg SCRN_INFO_PTR(arg); 1550b92e825aSmrg return TGAModeInit(pScrn, mode); 15517706df26Smrg} 15527706df26Smrg 15537706df26Smrg 15547706df26Smrg/* 15557706df26Smrg * This function is used to initialize the Start Address - the first 15567706df26Smrg * displayed location in the video memory. 15577706df26Smrg */ 15587706df26Smrg/* Usually mandatory */ 15597706df26Smrgstatic void 1560b92e825aSmrgTGAAdjustFrame(ADJUST_FRAME_ARGS_DECL) 15617706df26Smrg{ 15627706df26Smrg /* we don't support virtual desktops, because TGA doesn't have the 15637706df26Smrg ability to set the start of the visible framebuffer at an arbitrary 15647706df26Smrg pixel */ 15657706df26Smrg return; 15667706df26Smrg} 15677706df26Smrg 15687706df26Smrg/* 15697706df26Smrg * This is called when VT switching back to the X server. Its job is 15707706df26Smrg * to reinitialise the video mode. 15717706df26Smrg * 15727706df26Smrg * We may wish to unmap video/MMIO memory too. 15737706df26Smrg */ 15747706df26Smrg 15757706df26Smrg/* Mandatory */ 15767706df26Smrgstatic Bool 1577b92e825aSmrgTGAEnterVT(VT_FUNC_ARGS_DECL) 15787706df26Smrg{ 1579b92e825aSmrg SCRN_INFO_PTR(arg); 15807706df26Smrg 15817706df26Smrg /* Should we re-save the text mode on each VT enter? */ 15827706df26Smrg if (!TGAModeInit(pScrn, pScrn->currentMode)) 15837706df26Smrg return FALSE; 15847706df26Smrg 15857706df26Smrg return TRUE; 15867706df26Smrg} 15877706df26Smrg 15887706df26Smrg 15897706df26Smrg/* 15907706df26Smrg * This is called when VT switching away from the X server. Its job is 15917706df26Smrg * to restore the previous (text) mode. 15927706df26Smrg * 15937706df26Smrg * We may wish to remap video/MMIO memory too. 15947706df26Smrg */ 15957706df26Smrg 15967706df26Smrg/* Mandatory */ 15977706df26Smrgstatic void 1598b92e825aSmrgTGALeaveVT(VT_FUNC_ARGS_DECL) 15997706df26Smrg{ 1600b92e825aSmrg SCRN_INFO_PTR(arg); 16017706df26Smrg/* TGAPtr pTga = TGAPTR(pScrn); */ 16027706df26Smrg 16037706df26Smrg TGARestore(pScrn); 16047706df26Smrg 16057706df26Smrg /* no longer necessary with new VT switching code */ 16067706df26Smrg/* memset(pTga->FbBase, 0, pTga->FbMapSize); */ 16077706df26Smrg return; 16087706df26Smrg} 16097706df26Smrg 16107706df26Smrg 16117706df26Smrg/* 16127706df26Smrg * This is called at the end of each server generation. It restores the 16137706df26Smrg * original (text) mode. 16147706df26Smrg */ 16157706df26Smrg 16167706df26Smrg/* Mandatory */ 16177706df26Smrgstatic Bool 1618b92e825aSmrgTGACloseScreen(CLOSE_SCREEN_ARGS_DECL) 16197706df26Smrg{ 1620b92e825aSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 16217706df26Smrg TGAPtr pTga = TGAPTR(pScrn); 16227706df26Smrg 16237706df26Smrg TGARestore(pScrn); 16247706df26Smrg /* memset(pTga->FbBase, 0, pScrn->videoRam * 1024); */ 16257706df26Smrg TGASync(pScrn); 16267706df26Smrg TGAUnmapMem(pScrn); 16277706df26Smrg 1628b92e825aSmrg#ifdef HAVE_XAA_H 16297706df26Smrg if(pTga->AccelInfoRec) 16307706df26Smrg XAADestroyInfoRec(pTga->AccelInfoRec); 1631b92e825aSmrg#endif 16327706df26Smrg pScrn->vtSema = FALSE; 16337706df26Smrg 16347706df26Smrg pScreen->CloseScreen = pTga->CloseScreen; 1635b92e825aSmrg return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 16367706df26Smrg} 16377706df26Smrg 16387706df26Smrg 16397706df26Smrg/* Free up any per-generation data structures */ 16407706df26Smrg 16417706df26Smrg/* Optional */ 16427706df26Smrgstatic void 1643b92e825aSmrgTGAFreeScreen(FREE_SCREEN_ARGS_DECL) 16447706df26Smrg{ 1645b92e825aSmrg SCRN_INFO_PTR(arg); 1646b92e825aSmrg RamDacFreeRec(pScrn); 1647b92e825aSmrg TGAFreeRec(pScrn); 16487706df26Smrg} 16497706df26Smrg 16507706df26Smrg 16517706df26Smrg/* Checks if a mode is suitable for the selected chipset. */ 16527706df26Smrg 16537706df26Smrg/* Optional */ 16547706df26Smrgstatic ModeStatus 1655b92e825aSmrgTGAValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 16567706df26Smrg{ 16577706df26Smrg if (mode->Flags & V_INTERLACE) 16587706df26Smrg return(MODE_BAD); 16597706df26Smrg 16607706df26Smrg return(MODE_OK); 16617706df26Smrg} 16627706df26Smrg 16637706df26Smrg/* Do screen blanking */ 16647706df26Smrg 16657706df26Smrg/* Mandatory */ 16667706df26Smrgstatic Bool 16677706df26SmrgTGASaveScreen(ScreenPtr pScreen, int mode) 16687706df26Smrg /* this function should blank the screen when unblank is FALSE and 16697706df26Smrg unblank it when unblank is TRUE -- it doesn't actually seem to be 16707706df26Smrg used for much though */ 16717706df26Smrg{ 16727706df26Smrg TGAPtr pTga; 16737706df26Smrg ScrnInfoPtr pScrn; 16747706df26Smrg int valid_reg = 0; 16757706df26Smrg Bool unblank; 16767706df26Smrg 1677b92e825aSmrg pScrn = xf86ScreenToScrn(pScreen); 16787706df26Smrg pTga = TGAPTR(pScrn); 16797706df26Smrg valid_reg = TGA_READ_REG(TGA_VALID_REG); 16807706df26Smrg valid_reg &= 0xFFFFFFFC; 16817706df26Smrg 16827706df26Smrg unblank = xf86IsUnblank(mode); 16837706df26Smrg 16847706df26Smrg if(unblank == FALSE) 16857706df26Smrg valid_reg |= 0x3; 16867706df26Smrg else /* this function is sometimes called w/1 || 2 as TRUE */ 16877706df26Smrg valid_reg |= 0x1; 16887706df26Smrg 16897706df26Smrg TGA_WRITE_REG(valid_reg, TGA_VALID_REG); 16907706df26Smrg 16917706df26Smrg/* ErrorF("TGASaveScreen called\n"); */ 16927706df26Smrg 16937706df26Smrg return TRUE; 16947706df26Smrg} 16957706df26Smrg 16967706df26Smrg 16977706df26Smrg/* 16987706df26Smrg * TGADisplayPowerManagementSet -- 16997706df26Smrg * 17007706df26Smrg * Sets VESA Display Power Management Signaling (DPMS) Mode. 17017706df26Smrg */ 17027706df26Smrgstatic void 17037706df26SmrgTGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 17047706df26Smrg int flags) 17057706df26Smrg{ 17067706df26Smrg TGAPtr pTga; 17077706df26Smrg int valid_reg = 0; 17087706df26Smrg 17097706df26Smrg pTga = TGAPTR(pScrn); 17107706df26Smrg valid_reg = TGA_READ_REG(TGA_VALID_REG); 17117706df26Smrg valid_reg &= 0xFFFFFFFC; 17127706df26Smrg 17137706df26Smrg switch(PowerManagementMode) { 17147706df26Smrg case DPMSModeOn: 17157706df26Smrg /* HSync: On, VSync: On */ 17167706df26Smrg valid_reg |= 0x1; 17177706df26Smrg break; 17187706df26Smrg case DPMSModeStandby: 17197706df26Smrg case DPMSModeSuspend: 17207706df26Smrg /* TGA gives us a function to blank the screen while maintaining sync... 17217706df26Smrg I guess we can just use that here... */ 17227706df26Smrg valid_reg |= 0x3; 17237706df26Smrg break; 17247706df26Smrg case DPMSModeOff: 17257706df26Smrg valid_reg |= 0x2; 17267706df26Smrg break; 17277706df26Smrg default: 17287706df26Smrg ErrorF("Invalid PowerManagementMode %d passed to TGADisplayPowerManagementSet\n", PowerManagementMode); 17297706df26Smrg break; 17307706df26Smrg } 17317706df26Smrg 17327706df26Smrg TGA_WRITE_REG(valid_reg, TGA_VALID_REG); 17337706df26Smrg return; 17347706df26Smrg} 17357706df26Smrg 17367706df26Smrgstatic void 17377706df26SmrgTGARestoreHWCursor(ScrnInfoPtr pScrn) 17387706df26Smrg /* 17397706df26Smrg from tga.c in the linux kernel...may not work for BSD... 17407706df26Smrg when the cursor is restored, it is one line down from where it should 17417706df26Smrg be...this is disconcerting, but purely cosmetic. Unfortunately reading 17427706df26Smrg in the cursor framebuffer doesn't seem to work, I get a bunch of junk 17437706df26Smrg at the beginning...other than that, see tga_cursor.c 17447706df26Smrg I believe this to be a problem with the linux kernel code. 17457706df26Smrg Hmm...this seems to be a 2.0.* problem, 2.2 works ok 17467706df26Smrg */ 17477706df26Smrg{ 17487706df26Smrg unsigned char *p = NULL; 17497706df26Smrg int i = 0; 17507706df26Smrg TGAPtr pTga; 17517706df26Smrg 17527706df26Smrg /* Making this static prevents EGCS from compiling memset code 17537706df26Smrg to initialize it, which was causing a problem. */ 17547706df26Smrg static const CARD32 tga_cursor_source[128] = { 17557706df26Smrg 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 17567706df26Smrg 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 17577706df26Smrg 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 17587706df26Smrg 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 17597706df26Smrg 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 17607706df26Smrg 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 17617706df26Smrg 0x000000ff, 0x00000000, 17627706df26Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 17637706df26Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 17647706df26Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 17657706df26Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 17667706df26Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 17677706df26Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 17687706df26Smrg }; 17697706df26Smrg 17707706df26Smrg /* this is the linux console hw cursor...what about the bsd console? */ 17717706df26Smrg /* what about tgafb? */ 17727706df26Smrg pTga = TGAPTR(pScrn); 17737706df26Smrg 17747706df26Smrg /* we want to move the cursor off the screen before we do anything with it 17757706df26Smrg otherwise, there is a "ghost cursor" that shows up */ 17767706df26Smrg 17777706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, 0); 17787706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, 0); 17797706df26Smrg 17807706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, 0); 17817706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, 0); 17827706df26Smrg 17837706df26Smrg 17847706df26Smrg /* set a windows cursor -- oddly, this doesn't seem necessary */ 17857706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x02); 17867706df26Smrg 17877706df26Smrg /* set a 64 bit cursor */ 17887706df26Smrg/* pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80); */ 17897706df26Smrg/* pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01); */ 17907706df26Smrg/* pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0xF8, 0x04); */ 17917706df26Smrg 17927706df26Smrg /* set the colors */ 17937706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01); 17947706df26Smrg 17957706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa); 17967706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa); 17977706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0xaa); 17987706df26Smrg 17997706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); 18007706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); 18017706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); 18027706df26Smrg 18037706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); 18047706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); 18057706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); 18067706df26Smrg 18077706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); 18087706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); 18097706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, 0x00); 18107706df26Smrg 18117706df26Smrg 18127706df26Smrg /* load the console cursor */ 18137706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); 18147706df26Smrg p = (unsigned char *)tga_cursor_source; 18157706df26Smrg for(i = 0; i < 512; i++) 18167706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *p++); 18177706df26Smrg for(i = 0; i < 512; i++) 18187706df26Smrg pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, 0xff); 18197706df26Smrg 18207706df26Smrg return; 18217706df26Smrg} 18227706df26Smrg 18237706df26Smrg 18247706df26Smrg/* 18257706df26Smrg * This is the implementation of the Sync() function. 18267706df26Smrg */ 18277706df26Smrgvoid 18287706df26SmrgTGASync(ScrnInfoPtr pScrn) 18297706df26Smrg{ 18307706df26Smrg TGAPtr pTga = TGAPTR(pScrn); 18317706df26Smrg unsigned int stat; 18327706df26Smrg 18337706df26Smrg switch (pTga->Chipset) 18347706df26Smrg { 18357706df26Smrg case PCI_CHIP_TGA2: 18367706df26Smrg /* This code is weird, but then so is TGA2... ;-} */ 18377706df26Smrg mem_barrier(); 18387706df26Smrg while((stat = TGA_READ_REG(TGA_CMD_STAT_REG))) { 18397706df26Smrg if (((stat >> 8) & 0xff) == ((stat >> 16) & 0xff)) { 18407706df26Smrg TGA_WRITE_REG(0, TGA_CMD_STAT_REG); 18417706df26Smrg mem_barrier(); 18427706df26Smrg#if 0 18437706df26SmrgErrorF("TGASync: writing CMD_STATUS\n"); 18447706df26Smrg#endif 18457706df26Smrg } 18467706df26Smrg usleep(1000); 18477706df26Smrg } 18487706df26Smrg break; 18497706df26Smrg 18507706df26Smrg case PCI_CHIP_DEC21030: 18517706df26Smrg#if 0 18527706df26Smrg /* I'm experiencing lockups which could be due to this function. 18537706df26Smrg We don't seem to need it anyway... 18547706df26Smrg */ 18557706df26Smrg while (TGA_READ_REG(TGA_CMD_STAT_REG) & 0x01); 18567706df26Smrg#endif 18577706df26Smrg break; 18587706df26Smrg } 18597706df26Smrg 18607706df26Smrg return; 18617706df26Smrg} 18627706df26Smrg 1863