1692f60a7Smrg/********************************************************************** 2692f60a7SmrgCopyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas. 3692f60a7Smrg 4692f60a7Smrg All Rights Reserved 5692f60a7Smrg 6692f60a7SmrgPermission to use, copy, modify, distribute, and sell this software and 7692f60a7Smrgits documentation for any purpose is hereby granted without fee, 8692f60a7Smrgprovided that the above copyright notice appear in all copies and that 9692f60a7Smrgboth that copyright notice and this permission notice appear in 10692f60a7Smrgsupporting documentation, and that the name of Precision Insight not be 11692f60a7Smrgused in advertising or publicity pertaining to distribution of the 12692f60a7Smrgsoftware without specific, written prior permission. Precision Insight 13692f60a7Smrgand its suppliers make no representations about the suitability of this 14692f60a7Smrgsoftware for any purpose. It is provided "as is" without express or 15692f60a7Smrgimplied warranty. 16692f60a7Smrg 17692f60a7SmrgPRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18692f60a7SmrgINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19692f60a7SmrgEVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY 20692f60a7SmrgSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 21692f60a7SmrgRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 22692f60a7SmrgCONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 23692f60a7SmrgCONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24692f60a7Smrg**********************************************************************/ 25692f60a7Smrg 26692f60a7Smrg/* 27692f60a7Smrg * The original Precision Insight driver for 28692f60a7Smrg * XFree86 v.3.3 has been sponsored by Red Hat. 29692f60a7Smrg * 30692f60a7Smrg * Authors: 31692f60a7Smrg * Jens Owen (jens@tungstengraphics.com) 32692f60a7Smrg * Kevin E. Martin (kevin@precisioninsight.com) 33692f60a7Smrg * 34692f60a7Smrg * Port to Xfree86 v.4.0 35692f60a7Smrg * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE) 36692f60a7Smrg */ 37692f60a7Smrg 38692f60a7Smrg#include <string.h> 3954569438Smrg 4054569438Smrg#include "neo_pcirename.h" 4154569438Smrg 42692f60a7Smrg/* All drivers should typically include these */ 43692f60a7Smrg#include "xf86.h" 44692f60a7Smrg#include "xf86_OSproc.h" 45692f60a7Smrg 46692f60a7Smrg/* Everything using inb/outb, etc needs "compiler.h" */ 47692f60a7Smrg#include "compiler.h" 48692f60a7Smrg 493f6d0e1dSmrg#ifdef HAVE_XAA_H 50692f60a7Smrg#include "xaa.h" 51692f60a7Smrg#include "xaalocal.h" /* XAA internals as we replace some of XAA */ 523f6d0e1dSmrg#endif 533f6d0e1dSmrg#include "xf86fbman.h" 54692f60a7Smrg#include "xf86Cursor.h" 55692f60a7Smrg 56692f60a7Smrg#include "shadowfb.h" 57692f60a7Smrg 58692f60a7Smrg#include "vbe.h" 59692f60a7Smrg 60692f60a7Smrg/* Needed by the Shadow Framebuffer */ 61692f60a7Smrg#include "shadow.h" 62692f60a7Smrg 63692f60a7Smrg/* Drivers that need to access the PCI config space directly need this */ 64692f60a7Smrg#include "xf86Pci.h" 65692f60a7Smrg 66692f60a7Smrg#include "xf86i2c.h" 67692f60a7Smrg 68692f60a7Smrg#include "xf86xv.h" 69692f60a7Smrg#include <X11/extensions/Xv.h> 70692f60a7Smrg 71692f60a7Smrg/* 72692f60a7Smrg * Driver data structures. 73692f60a7Smrg */ 74692f60a7Smrg#include "neo_reg.h" 75692f60a7Smrg#include "neo_macros.h" 76692f60a7Smrg 773f6d0e1dSmrg#include "compat-api.h" 78692f60a7Smrg/* Supported chipsets */ 79692f60a7Smrgtypedef enum { 80692f60a7Smrg NM2070, 81692f60a7Smrg NM2090, 82692f60a7Smrg NM2093, 83692f60a7Smrg NM2097, 84692f60a7Smrg NM2160, 85692f60a7Smrg NM2200, 86692f60a7Smrg NM2230, 87692f60a7Smrg NM2360, 88692f60a7Smrg NM2380 89692f60a7Smrg} NEOType; 90692f60a7Smrg 91692f60a7Smrg/* function prototypes */ 92692f60a7Smrg 933f6d0e1dSmrgextern Bool NEOSwitchMode(SWITCH_MODE_ARGS_DECL); 943f6d0e1dSmrgextern void NEOAdjustFrame(ADJUST_FRAME_ARGS_DECL); 95692f60a7Smrg 96692f60a7Smrg/* in neo_2070.c */ 97692f60a7Smrgextern Bool Neo2070AccelInit(ScreenPtr pScreen); 98692f60a7Smrg 99692f60a7Smrg/* in neo_2090.c */ 100692f60a7Smrgextern Bool Neo2090AccelInit(ScreenPtr pScreen); 101692f60a7Smrg 102692f60a7Smrg/* in neo_2097.c */ 103692f60a7Smrgextern Bool Neo2097AccelInit(ScreenPtr pScreen); 104692f60a7Smrg 105692f60a7Smrg/* in neo_2200.c */ 106692f60a7Smrgextern Bool Neo2200AccelInit(ScreenPtr pScreen); 107692f60a7Smrg 108692f60a7Smrg/* in neo_cursor.c */ 109692f60a7Smrgextern Bool NeoCursorInit(ScreenPtr pScrn); 110692f60a7Smrgextern void NeoShowCursor(ScrnInfoPtr pScrn); 111692f60a7Smrgextern void NeoHideCursor(ScrnInfoPtr pScrn); 112692f60a7Smrg 113692f60a7Smrg/* in neo_i2c.c */ 114692f60a7Smrgextern Bool neo_I2CInit(ScrnInfoPtr pScrn); 115692f60a7Smrg 116692f60a7Smrg/* in neo_shadow.c */ 117692f60a7Smrgvoid neoShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); 1183f6d0e1dSmrgvoid neoPointerMoved(SCRN_ARG_TYPE arg, int x, int y); 119692f60a7Smrgvoid neoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 120692f60a7Smrgvoid neoRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 121692f60a7Smrgvoid neoRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 122692f60a7Smrgvoid neoRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 123692f60a7Smrgvoid neoRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 124692f60a7Smrg 125692f60a7Smrg/* in neo_dga.c */ 126692f60a7SmrgBool NEODGAInit(ScreenPtr pScreen); 127692f60a7Smrg 128692f60a7Smrg/* in neo_video.c */ 129692f60a7Smrgextern void NEOInitVideo(ScreenPtr pScreen); 130692f60a7Smrgextern void NEOResetVideo(ScrnInfoPtr pScrn); 131692f60a7Smrg 132692f60a7Smrg/* shadow regs */ 133692f60a7Smrg 134692f60a7Smrg#define NEO_EXT_CR_MAX 0x85 135692f60a7Smrg#define NEO_EXT_GR_MAX 0xC7 136692f60a7Smrgtypedef struct { 137692f60a7Smrg unsigned char CR[NEO_EXT_CR_MAX+1]; 138692f60a7Smrg unsigned char GR[NEO_EXT_GR_MAX+1]; 139692f60a7Smrg} regSaveRec, *regSavePtr; 140692f60a7Smrg 141692f60a7Smrg/* registers */ 142692f60a7Smrgtypedef struct { 143692f60a7Smrg unsigned char GeneralLockReg; 144692f60a7Smrg unsigned char ExtCRTDispAddr; 145692f60a7Smrg unsigned char ExtCRTOffset; 146692f60a7Smrg unsigned char SysIfaceCntl1; 147692f60a7Smrg unsigned char SysIfaceCntl2; 148692f60a7Smrg unsigned char ExtColorModeSelect; 149692f60a7Smrg unsigned char SingleAddrPage; 150692f60a7Smrg unsigned char DualAddrPage; 151692f60a7Smrg unsigned char biosMode; 152692f60a7Smrg unsigned char PanelDispCntlReg1; 153692f60a7Smrg unsigned char PanelDispCntlReg2; 154692f60a7Smrg unsigned char PanelDispCntlReg3; 155692f60a7Smrg unsigned char PanelVertCenterReg1; 156692f60a7Smrg unsigned char PanelVertCenterReg2; 157692f60a7Smrg unsigned char PanelVertCenterReg3; 158692f60a7Smrg unsigned char PanelVertCenterReg4; 159692f60a7Smrg unsigned char PanelVertCenterReg5; 160692f60a7Smrg unsigned char PanelHorizCenterReg1; 161692f60a7Smrg unsigned char PanelHorizCenterReg2; 162692f60a7Smrg unsigned char PanelHorizCenterReg3; 163692f60a7Smrg unsigned char PanelHorizCenterReg4; 164692f60a7Smrg unsigned char PanelHorizCenterReg5; 165692f60a7Smrg unsigned char Sequencer1; 166692f60a7Smrg Bool ProgramVCLK; 167692f60a7Smrg unsigned char VCLK3NumeratorLow; 168692f60a7Smrg unsigned char VCLK3NumeratorHigh; 169692f60a7Smrg unsigned char VCLK3Denominator; 170692f60a7Smrg unsigned char VerticalExt; 171692f60a7Smrg regSavePtr reg; 172692f60a7Smrg} NeoRegRec, *NeoRegPtr; 173692f60a7Smrg 174692f60a7Smrgtypedef struct { 175692f60a7Smrg /* Hardware cursor address */ 176692f60a7Smrg unsigned int CursorAddress; 177692f60a7Smrg Bool UseHWCursor; 178692f60a7Smrg Bool NoCursorMode; 179692f60a7Smrg unsigned char CursTemp[1024]; 180692f60a7Smrg /* Boundaries of the pixmap cache */ 181692f60a7Smrg unsigned int cacheStart; 182692f60a7Smrg unsigned int cacheEnd; 183692f60a7Smrg /* Blitter */ 184692f60a7Smrg unsigned int tmpBltCntlFlags; 185692f60a7Smrg unsigned int BltCntlFlags; 186692f60a7Smrg unsigned int BltModeFlags; 187692f60a7Smrg unsigned int ColorShiftAmt; 188692f60a7Smrg unsigned int Pitch; 189692f60a7Smrg unsigned int PixelWidth; 190692f60a7Smrg unsigned int PlaneMask; 191692f60a7Smrg int CPUToScreenColorExpandFill_x; 192692f60a7Smrg int CPUToScreenColorExpandFill_y; 193692f60a7Smrg int CPUToScreenColorExpandFill_w; 194692f60a7Smrg int CPUToScreenColorExpandFill_h; 195692f60a7Smrg int CPUToScreenColorExpandFill_skipleft; 196692f60a7Smrg} NEOACLRec, *NEOACLPtr; 197692f60a7Smrg#define NEOACLPTR(p) &((NEOPtr)((p)->driverPrivate))->Accel 198692f60a7Smrg 199692f60a7Smrg/* globals */ 200692f60a7Smrgtypedef struct neoRec 201692f60a7Smrg{ 202692f60a7Smrg int NeoChipset; 203692f60a7Smrg pciVideoPtr PciInfo; 20454569438Smrg#ifndef XSERVER_LIBPCIACCESS 205692f60a7Smrg PCITAG PciTag; 20654569438Smrg#endif 207692f60a7Smrg EntityInfoPtr pEnt; 2083f6d0e1dSmrg#ifdef HAVE_XAA_H 209692f60a7Smrg XAAInfoRecPtr AccelInfoRec; 2103f6d0e1dSmrg#endif 211692f60a7Smrg NEOACLRec Accel; 212692f60a7Smrg unsigned long NeoMMIOAddr; 213692f60a7Smrg unsigned long NeoLinearAddr; 214692f60a7Smrg unsigned char* NeoMMIOBase; 215692f60a7Smrg unsigned long NeoMMIOAddr2; 216692f60a7Smrg unsigned char* NeoMMIOBase2; 217692f60a7Smrg unsigned char* NeoFbBase; 218692f60a7Smrg long NeoFbMapSize; 219692f60a7Smrg unsigned long vgaIOBase; 220692f60a7Smrg DGAModePtr DGAModes; 221692f60a7Smrg int numDGAModes; 222692f60a7Smrg Bool DGAactive; 223692f60a7Smrg int DGAViewportStatus; 224692f60a7Smrg /* ??? */ 225692f60a7Smrg int NeoFifoCount; 226692f60a7Smrg /* cursor */ 227692f60a7Smrg int NeoCursorMem; 228692f60a7Smrg Bool NeoHWCursorShown; 229692f60a7Smrg Bool NeoHWCursorInitialized; 230692f60a7Smrg xf86CursorInfoPtr CursorInfo; 231692f60a7Smrg int NeoCursorOffset; 232692f60a7Smrg int NeoCursorPrevX; 233692f60a7Smrg int NeoCursorPrevY; 234692f60a7Smrg unsigned char *NeoCursorImage; 235692f60a7Smrg /* Panels size */ 236692f60a7Smrg int NeoPanelWidth; 237692f60a7Smrg int NeoPanelHeight; 238692f60a7Smrg /* options */ 239692f60a7Smrg OptionInfoPtr Options; 240692f60a7Smrg Bool noAccel; 241692f60a7Smrg Bool noAccelSet; 242692f60a7Smrg Bool swCursor; 243692f60a7Smrg Bool noMMIO; 244692f60a7Smrg Bool internDisp; 245692f60a7Smrg Bool externDisp; 246692f60a7Smrg Bool noLcdStretch; 247692f60a7Smrg Bool shadowFB; 248692f60a7Smrg Bool lcdCenter; 249692f60a7Smrg Bool onPciBurst; 250692f60a7Smrg Bool progLcdRegs; 251692f60a7Smrg Bool progLcdStretch; 252692f60a7Smrg Bool progLcdStretchOpt; 253692f60a7Smrg Bool overrideValidate; 254692f60a7Smrg Bool strangeLockups; 255692f60a7Smrg /* registers */ 256692f60a7Smrg NeoRegRec NeoModeReg; 257692f60a7Smrg NeoRegRec NeoSavedReg; 258692f60a7Smrg /* proc pointer */ 259692f60a7Smrg CloseScreenProcPtr CloseScreen; 260692f60a7Smrg I2CBusPtr I2C; 261692f60a7Smrg vbeInfoPtr pVbe; 262692f60a7Smrg unsigned char * ShadowPtr; 263692f60a7Smrg int ShadowPitch; 264eaa3dbe0Smrg CreateScreenResourcesProcPtr CreateScreenResources; 265692f60a7Smrg RefreshAreaFuncPtr refreshArea; 2663f6d0e1dSmrg void (*PointerMoved)(SCRN_ARG_TYPE arg, int x, int y); 267692f60a7Smrg int rotate; 268692f60a7Smrg Bool showcache; 269692f60a7Smrg Bool video; 270692f60a7Smrg double videoHZoom; 271692f60a7Smrg double videoVZoom; 272692f60a7Smrg XF86VideoAdaptorPtr overlayAdaptor; 273692f60a7Smrg int overlay; 274692f60a7Smrg int overlay_offset; 275692f60a7Smrg int videoKey; 276692f60a7Smrg int interlace; 277692f60a7Smrg} NEORec, *NEOPtr; 278692f60a7Smrg 279692f60a7Smrgtypedef struct { 280692f60a7Smrg int x_res; 281692f60a7Smrg int y_res; 282692f60a7Smrg int mode; 283692f60a7Smrg} biosMode; 284692f60a7Smrg 285692f60a7Smrg/* The privates of the NEO driver */ 286692f60a7Smrg#define NEOPTR(p) ((NEOPtr)((p)->driverPrivate)) 287692f60a7Smrg 288692f60a7Smrg/* I/O register offsets */ 289692f60a7Smrg#define GRAX 0x3CE 290692f60a7Smrg 291692f60a7Smrg/* vga IO functions */ 292692f60a7Smrg#define VGArCR(index) (*hwp->readCrtc)(hwp, index) 293692f60a7Smrg#define VGAwCR(index, val) (*hwp->writeCrtc)(hwp, index, val) 294692f60a7Smrg#define VGArGR(index) (*hwp->readGr)(hwp, index) 295692f60a7Smrg#define VGAwGR(index, val) (*hwp->writeGr)(hwp, index, val) 296692f60a7Smrg#define VGArSR(index) (*hwp->readSeq)(hwp, index) 297692f60a7Smrg#define VGAwSR(index, val) (*hwp->writeSeq)(hwp, index, val) 298692f60a7Smrg 299692f60a7Smrg/* memory mapped register access macros */ 300692f60a7Smrg#define INREG8(addr) MMIO_IN8(nPtr->NeoMMIOBase, addr) 301692f60a7Smrg#define INREG16(addr) MMIO_IN16(nPtr->NeoMMIOBase, addr) 302692f60a7Smrg#define INREG(addr) MMIO_IN32(nPtr->NeoMMIOBase, addr) 303692f60a7Smrg#define OUTREG8(addr, val) MMIO_OUT8(nPtr->NeoMMIOBase, addr, val) 304692f60a7Smrg#define OUTREG16(addr, val) MMIO_OUT16(nPtr->NeoMMIOBase, addr, val) 305692f60a7Smrg#define OUTREG(addr, val) MMIO_OUT32(nPtr->NeoMMIOBase, addr, val) 306692f60a7Smrg 307692f60a7Smrg/* This swizzle macro is to support the manipulation of cursor masks when 308692f60a7Smrg * the sprite moves off the left edge of the display. This code is 309692f60a7Smrg * platform specific, and is known to work with 32bit little endian machines 310692f60a7Smrg */ 311692f60a7Smrg#define SWIZZLE32(__b) { \ 312692f60a7Smrg ((unsigned char *)&__b)[0] = byte_reversed[((unsigned char *)&__b)[0]]; \ 313692f60a7Smrg ((unsigned char *)&__b)[1] = byte_reversed[((unsigned char *)&__b)[1]]; \ 314692f60a7Smrg ((unsigned char *)&__b)[2] = byte_reversed[((unsigned char *)&__b)[2]]; \ 315692f60a7Smrg ((unsigned char *)&__b)[3] = byte_reversed[((unsigned char *)&__b)[3]]; \ 316692f60a7Smrg} 317692f60a7Smrg 318692f60a7Smrg#define PROBED_NM2070 0x01 319692f60a7Smrg#define PROBED_NM2090 0x42 320692f60a7Smrg#define PROBED_NM2093 0x43 321692f60a7Smrg#define PROBED_NM2097 0x83 322692f60a7Smrg#define PROBED_NM2160 0x44 323692f60a7Smrg#define PROBED_NM2200 0x45 324eaa3dbe0Smrg 325eaa3dbe0Smrg#define PCI_VENDOR_NEOMAGIC 0x10C8 326eaa3dbe0Smrg#define PCI_CHIP_NM2070 0x0001 327eaa3dbe0Smrg#define PCI_CHIP_NM2090 0x0002 328eaa3dbe0Smrg#define PCI_CHIP_NM2093 0x0003 329eaa3dbe0Smrg#define PCI_CHIP_NM2097 0x0083 330eaa3dbe0Smrg#define PCI_CHIP_NM2160 0x0004 331eaa3dbe0Smrg#define PCI_CHIP_NM2200 0x0005 332eaa3dbe0Smrg#define PCI_CHIP_NM2230 0x0025 333eaa3dbe0Smrg#define PCI_CHIP_NM2360 0x0006 334eaa3dbe0Smrg#define PCI_CHIP_NM2380 0x0016 335