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#ifdef HAVE_CONFIG_H
39692f60a7Smrg#include "config.h"
40692f60a7Smrg#endif
41692f60a7Smrg
42692f60a7Smrg#include "xf86.h"
43692f60a7Smrg#include "xf86_OSproc.h"
44692f60a7Smrg#include "compiler.h"
45692f60a7Smrg
46692f60a7Smrg/* Drivers that use XAA need this */
47692f60a7Smrg#include "xf86fbman.h"
48692f60a7Smrg
49692f60a7Smrg#include "miline.h"
50692f60a7Smrg
51692f60a7Smrg#include "neo.h"
52692f60a7Smrg#include "neo_reg.h"
53692f60a7Smrg#include "neo_macros.h"
54692f60a7Smrg
553f6d0e1dSmrg#ifdef HAVE_XAA_H
56692f60a7Smrg/* Memory Mapped I/O for BitBlt */
57692f60a7Smrg#define NEO2070_BLTSTAT		0x00
58692f60a7Smrg#define NEO2070_BLTCNTL		0x04
59692f60a7Smrg#define NEO2070_XPCOLOR		0x08
60692f60a7Smrg#define NEO2070_FGCOLOR		0x0c
61692f60a7Smrg#define NEO2070_BGCOLOR		0x10
62692f60a7Smrg#define NEO2070_PLANEMASK	0x14
63692f60a7Smrg#define NEO2070_XYEXT           0x18
64692f60a7Smrg#define NEO2070_SRCPITCH        0x1c
65692f60a7Smrg#define NEO2070_SRCBITOFF       0x20
66692f60a7Smrg#define NEO2070_SRCSTART        0x24
67692f60a7Smrg#define NEO2070_DSTPITCH        0x28
68692f60a7Smrg#define NEO2070_DSTBITOFF       0x2c
69692f60a7Smrg#define NEO2070_DSTSTART        0x30
70692f60a7Smrg
71692f60a7Smrgstatic unsigned int neo2070Rop[16] = {
72692f60a7Smrg    0x000000,    /* 0x0000 - GXclear         */
73692f60a7Smrg    0x080000,    /* 0x1000 - GXand           */
74692f60a7Smrg    0x040000,    /* 0x0100 - GXandReverse    */
75692f60a7Smrg    0x0c0000,    /* 0x1100 - GXcopy          */
76692f60a7Smrg    0x020000,    /* 0x0010 - GXandInvert     */
77692f60a7Smrg    0x0a0000,    /* 0x1010 - GXnoop          */
78692f60a7Smrg    0x060000,    /* 0x0110 - GXxor           */
79692f60a7Smrg    0x0e0000,    /* 0x1110 - GXor            */
80692f60a7Smrg    0x010000,    /* 0x0001 - GXnor           */
81692f60a7Smrg    0x090000,    /* 0x1001 - GXequiv         */
82692f60a7Smrg    0x050000,    /* 0x0101 - GXinvert        */
83692f60a7Smrg    0x0d0000,    /* 0x1101 - GXorReverse     */
84692f60a7Smrg    0x030000,    /* 0x0011 - GXcopyInvert    */
85692f60a7Smrg    0x0b0000,    /* 0x1011 - GXorInverted    */
86692f60a7Smrg    0x070000,    /* 0x0111 - GXnand          */
87692f60a7Smrg    0x0f0000     /* 0x1111 - GXset           */
88692f60a7Smrg};
89692f60a7Smrg
90692f60a7Smrgstatic void Neo2070Sync(ScrnInfoPtr pScrn);
91692f60a7Smrgstatic void Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
92692f60a7Smrg					      int ydir, int rop,
93692f60a7Smrg					      unsigned int planemask,
94692f60a7Smrg					      int trans_color);
95692f60a7Smrgstatic void Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
96692f60a7Smrg						int srcY, int dstX, int dstY,
97692f60a7Smrg						int w, int h);
98692f60a7Smrgstatic void Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
99692f60a7Smrg				  unsigned int planemask);
100692f60a7Smrgstatic void Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
101692f60a7Smrg					   int w, int h);
102692f60a7Smrg
1033f6d0e1dSmrg#endif
1043f6d0e1dSmrg
105692f60a7SmrgBool
106692f60a7SmrgNeo2070AccelInit(ScreenPtr pScreen)
107692f60a7Smrg{
1083f6d0e1dSmrg#ifdef HAVE_XAA_H
109692f60a7Smrg    XAAInfoRecPtr infoPtr;
1103f6d0e1dSmrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
111692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
112692f60a7Smrg    NEOACLPtr nAcl = NEOACLPTR(pScrn);
113692f60a7Smrg
114692f60a7Smrg    nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
115692f60a7Smrg    if(!infoPtr) return FALSE;
116692f60a7Smrg
117692f60a7Smrg    /*
118692f60a7Smrg     * Set up the main acceleration flags.
119692f60a7Smrg     */
120692f60a7Smrg    infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
121692f60a7Smrg    if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE;
122692f60a7Smrg#if 0
123692f60a7Smrg    infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
124692f60a7Smrg#endif
125692f60a7Smrg    /* sync */
126692f60a7Smrg    infoPtr->Sync = Neo2070Sync;
127692f60a7Smrg
128692f60a7Smrg    /* screen to screen copy */
129692f60a7Smrg    infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | GXCOPY_ONLY);
130692f60a7Smrg    infoPtr->SetupForScreenToScreenCopy =
131692f60a7Smrg	Neo2070SetupForScreenToScreenCopy;
132692f60a7Smrg    infoPtr->SubsequentScreenToScreenCopy =
133692f60a7Smrg	Neo2070SubsequentScreenToScreenCopy;
134692f60a7Smrg
135692f60a7Smrg    /* solid filled rectangles */
136692f60a7Smrg    infoPtr->SolidFillFlags = GXCOPY_ONLY;
137692f60a7Smrg    infoPtr->SetupForSolidFill =
138692f60a7Smrg	Neo2070SetupForSolidFillRect;
139692f60a7Smrg    infoPtr->SubsequentSolidFillRect =
140692f60a7Smrg	Neo2070SubsequentSolidFillRect;
141692f60a7Smrg
142692f60a7Smrg    /*
143692f60a7Smrg     * Setup some global variables
144692f60a7Smrg     */
145692f60a7Smrg
146efb46889Smrg    /* Initialize for 8bpp or 15/16bpp support accelerated */
147692f60a7Smrg    switch (pScrn->bitsPerPixel) {
148692f60a7Smrg    case 8:
149692f60a7Smrg	nAcl->BltCntlFlags = NEO_BC1_DEPTH8;
150692f60a7Smrg	nAcl->ColorShiftAmt = 8;
151692f60a7Smrg	nAcl->PixelWidth = 1;
152692f60a7Smrg	nAcl->PlaneMask = 0xff;
153692f60a7Smrg	break;
154692f60a7Smrg    case 15:
155692f60a7Smrg    case 16:
156692f60a7Smrg	nAcl->BltCntlFlags = NEO_BC1_DEPTH16;
157692f60a7Smrg	nAcl->ColorShiftAmt = 0;
158692f60a7Smrg	nAcl->PixelWidth = 2;
159692f60a7Smrg	nAcl->PlaneMask = 0xffff;
160692f60a7Smrg	break;
161692f60a7Smrg    case 24: /* not supported, but check anyway */
162692f60a7Smrg    default:
163692f60a7Smrg	return FALSE;
164692f60a7Smrg    }
165692f60a7Smrg
166c3c9db83Smrg    return(XAAInit(pScreen, infoPtr));
1673f6d0e1dSmrg#else
1683f6d0e1dSmrg    return FALSE;
1693f6d0e1dSmrg#endif
170692f60a7Smrg}
171692f60a7Smrg
1723f6d0e1dSmrg#ifdef HAVE_XAA_H
173692f60a7Smrgstatic void
174692f60a7SmrgNeo2070Sync(ScrnInfoPtr pScrn)
175692f60a7Smrg{
176692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
177692f60a7Smrg    WAIT_ENGINE_IDLE();
178692f60a7Smrg}
179692f60a7Smrg
180692f60a7Smrgstatic void
181692f60a7SmrgNeo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
182692f60a7Smrg				  int rop,
183692f60a7Smrg				  unsigned int planemask,
184692f60a7Smrg				  int trans_color)
185692f60a7Smrg{
186692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
187692f60a7Smrg    NEOACLPtr nAcl = NEOACLPTR(pScrn);
188692f60a7Smrg
189692f60a7Smrg    /* set blt control */
190692f60a7Smrg    WAIT_ENGINE_IDLE();
191692f60a7Smrg    OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
192692f60a7Smrg    OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
193692f60a7Smrg    OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
194692f60a7Smrg    OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
195692f60a7Smrg    OUTREG(NEO2070_SRCBITOFF, 0);
196692f60a7Smrg    OUTREG(NEO2070_DSTBITOFF, 0);
197692f60a7Smrg}
198692f60a7Smrg
199692f60a7Smrgstatic void
200692f60a7SmrgNeo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
201692f60a7Smrg				    int srcX, int srcY,
202692f60a7Smrg				    int dstX, int dstY,
203692f60a7Smrg				    int w, int h)
204692f60a7Smrg{
205692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
206692f60a7Smrg    NEOACLPtr nAcl = NEOACLPTR(pScrn);
207692f60a7Smrg
208692f60a7Smrg    if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
209692f60a7Smrg	/* start with upper left corner */
210692f60a7Smrg	WAIT_ENGINE_IDLE();
211692f60a7Smrg	OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
212692f60a7Smrg	OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
213692f60a7Smrg	OUTREG(NEO2070_SRCSTART,
214692f60a7Smrg	    (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));
215692f60a7Smrg	OUTREG(NEO2070_DSTSTART,
216692f60a7Smrg	    (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));
217692f60a7Smrg    }
218692f60a7Smrg    else {
219692f60a7Smrg	/* start with lower right corner */
220692f60a7Smrg	WAIT_ENGINE_IDLE();
221692f60a7Smrg	OUTREG(NEO2070_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC
222692f60a7Smrg                                                        | NEO_BC0_DST_Y_DEC
223692f60a7Smrg                                                        | NEO_BC0_SRC_Y_DEC));
224692f60a7Smrg	OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
225692f60a7Smrg	OUTREG(NEO2070_SRCSTART,
226692f60a7Smrg	    ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth));
227692f60a7Smrg	OUTREG(NEO2070_DSTSTART,
228692f60a7Smrg	    ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) * nAcl->PixelWidth));
229692f60a7Smrg    }
230692f60a7Smrg}
231692f60a7Smrg
232692f60a7Smrg
233692f60a7Smrgstatic void
234692f60a7SmrgNeo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
235692f60a7Smrg			     unsigned int planemask)
236692f60a7Smrg{
237692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
238692f60a7Smrg    NEOACLPtr nAcl = NEOACLPTR(pScrn);
239692f60a7Smrg
240692f60a7Smrg    planemask &= nAcl->PlaneMask;
241692f60a7Smrg    if (!rop) color=0;
242692f60a7Smrg
243692f60a7Smrg    WAIT_ENGINE_IDLE();
244692f60a7Smrg
245692f60a7Smrg    OUTREG(NEO2070_BLTCNTL, nAcl->BltCntlFlags  |
246692f60a7Smrg                            NEO_BC0_SRC_IS_FG    | neo2070Rop[3]);
247692f60a7Smrg    OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
248692f60a7Smrg    if (pScrn->bitsPerPixel == 8)
249692f60a7Smrg	OUTREG(NEO2070_FGCOLOR, color |= (color << 8));
250692f60a7Smrg    else
251692f60a7Smrg	/* swap bytes in color */
252692f60a7Smrg	OUTREG(NEO2070_FGCOLOR, ((color&0xff00) >> 8) | (color << 8));
253692f60a7Smrg    OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
254692f60a7Smrg    OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
255692f60a7Smrg    OUTREG(NEO2070_SRCBITOFF, 0);
256692f60a7Smrg    OUTREG(NEO2070_DSTBITOFF, 0);
257692f60a7Smrg}
258692f60a7Smrg
259692f60a7Smrg
260692f60a7Smrgstatic void
261692f60a7SmrgNeo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
262692f60a7Smrg{
263692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
264692f60a7Smrg    NEOACLPtr nAcl = NEOACLPTR(pScrn);
265692f60a7Smrg
266692f60a7Smrg    WAIT_ENGINE_IDLE();
267692f60a7Smrg    OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
268692f60a7Smrg    OUTREG(NEO2070_DSTSTART, (y * nAcl->Pitch) + (x * nAcl->PixelWidth));
269692f60a7Smrg}
2703f6d0e1dSmrg#endif
271692f60a7Smrg
272