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