1/**********************************************************************
2Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
3
4                        All Rights Reserved
5
6Permission to use, copy, modify, distribute, and sell this software and
7its documentation for any purpose is hereby granted without fee,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of Precision Insight not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.  Precision Insight
13and its suppliers make no representations about the suitability of this
14software for any purpose.  It is provided "as is" without express or
15implied warranty.
16
17PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
20SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
21RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
22CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24**********************************************************************/
25
26/*
27 * The original Precision Insight driver for
28 * XFree86 v.3.3 has been sponsored by Red Hat.
29 *
30 * Authors:
31 *   Jens Owen (jens@tungstengraphics.com)
32 *   Kevin E. Martin (kevin@precisioninsight.com)
33 *
34 * Port to Xfree86 v.4.0
35 *   1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
36 */
37
38#ifdef HAVE_CONFIG_H
39#include "config.h"
40#endif
41
42#include "xf86.h"
43#include "xf86_OSproc.h"
44#include "compiler.h"
45
46/* Drivers that use XAA need this */
47#include "xf86fbman.h"
48
49#include "miline.h"
50
51#include "neo.h"
52#include "neo_reg.h"
53#include "neo_macros.h"
54
55#ifdef HAVE_XAA_H
56/* Memory Mapped I/O for BitBlt */
57#define NEO2070_BLTSTAT		0x00
58#define NEO2070_BLTCNTL		0x04
59#define NEO2070_XPCOLOR		0x08
60#define NEO2070_FGCOLOR		0x0c
61#define NEO2070_BGCOLOR		0x10
62#define NEO2070_PLANEMASK	0x14
63#define NEO2070_XYEXT           0x18
64#define NEO2070_SRCPITCH        0x1c
65#define NEO2070_SRCBITOFF       0x20
66#define NEO2070_SRCSTART        0x24
67#define NEO2070_DSTPITCH        0x28
68#define NEO2070_DSTBITOFF       0x2c
69#define NEO2070_DSTSTART        0x30
70
71static unsigned int neo2070Rop[16] = {
72    0x000000,    /* 0x0000 - GXclear         */
73    0x080000,    /* 0x1000 - GXand           */
74    0x040000,    /* 0x0100 - GXandReverse    */
75    0x0c0000,    /* 0x1100 - GXcopy          */
76    0x020000,    /* 0x0010 - GXandInvert     */
77    0x0a0000,    /* 0x1010 - GXnoop          */
78    0x060000,    /* 0x0110 - GXxor           */
79    0x0e0000,    /* 0x1110 - GXor            */
80    0x010000,    /* 0x0001 - GXnor           */
81    0x090000,    /* 0x1001 - GXequiv         */
82    0x050000,    /* 0x0101 - GXinvert        */
83    0x0d0000,    /* 0x1101 - GXorReverse     */
84    0x030000,    /* 0x0011 - GXcopyInvert    */
85    0x0b0000,    /* 0x1011 - GXorInverted    */
86    0x070000,    /* 0x0111 - GXnand          */
87    0x0f0000     /* 0x1111 - GXset           */
88};
89
90static void Neo2070Sync(ScrnInfoPtr pScrn);
91static void Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
92					      int ydir, int rop,
93					      unsigned int planemask,
94					      int trans_color);
95static void Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
96						int srcY, int dstX, int dstY,
97						int w, int h);
98static void Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
99				  unsigned int planemask);
100static void Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
101					   int w, int h);
102
103#endif
104
105Bool
106Neo2070AccelInit(ScreenPtr pScreen)
107{
108#ifdef HAVE_XAA_H
109    XAAInfoRecPtr infoPtr;
110    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
111    NEOPtr nPtr = NEOPTR(pScrn);
112    NEOACLPtr nAcl = NEOACLPTR(pScrn);
113
114    nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
115    if(!infoPtr) return FALSE;
116
117    /*
118     * Set up the main acceleration flags.
119     */
120    infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
121    if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE;
122#if 0
123    infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
124#endif
125    /* sync */
126    infoPtr->Sync = Neo2070Sync;
127
128    /* screen to screen copy */
129    infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | GXCOPY_ONLY);
130    infoPtr->SetupForScreenToScreenCopy =
131	Neo2070SetupForScreenToScreenCopy;
132    infoPtr->SubsequentScreenToScreenCopy =
133	Neo2070SubsequentScreenToScreenCopy;
134
135    /* solid filled rectangles */
136    infoPtr->SolidFillFlags = GXCOPY_ONLY;
137    infoPtr->SetupForSolidFill =
138	Neo2070SetupForSolidFillRect;
139    infoPtr->SubsequentSolidFillRect =
140	Neo2070SubsequentSolidFillRect;
141
142    /*
143     * Setup some global variables
144     */
145
146    /* Initialize for 8bpp or 15/16bpp support accelerated */
147    switch (pScrn->bitsPerPixel) {
148    case 8:
149	nAcl->BltCntlFlags = NEO_BC1_DEPTH8;
150	nAcl->ColorShiftAmt = 8;
151	nAcl->PixelWidth = 1;
152	nAcl->PlaneMask = 0xff;
153	break;
154    case 15:
155    case 16:
156	nAcl->BltCntlFlags = NEO_BC1_DEPTH16;
157	nAcl->ColorShiftAmt = 0;
158	nAcl->PixelWidth = 2;
159	nAcl->PlaneMask = 0xffff;
160	break;
161    case 24: /* not supported, but check anyway */
162    default:
163	return FALSE;
164    }
165
166    return(XAAInit(pScreen, infoPtr));
167#else
168    return FALSE;
169#endif
170}
171
172#ifdef HAVE_XAA_H
173static void
174Neo2070Sync(ScrnInfoPtr pScrn)
175{
176    NEOPtr nPtr = NEOPTR(pScrn);
177    WAIT_ENGINE_IDLE();
178}
179
180static void
181Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
182				  int rop,
183				  unsigned int planemask,
184				  int trans_color)
185{
186    NEOPtr nPtr = NEOPTR(pScrn);
187    NEOACLPtr nAcl = NEOACLPTR(pScrn);
188
189    /* set blt control */
190    WAIT_ENGINE_IDLE();
191    OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
192    OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
193    OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
194    OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
195    OUTREG(NEO2070_SRCBITOFF, 0);
196    OUTREG(NEO2070_DSTBITOFF, 0);
197}
198
199static void
200Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
201				    int srcX, int srcY,
202				    int dstX, int dstY,
203				    int w, int h)
204{
205    NEOPtr nPtr = NEOPTR(pScrn);
206    NEOACLPtr nAcl = NEOACLPTR(pScrn);
207
208    if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
209	/* start with upper left corner */
210	WAIT_ENGINE_IDLE();
211	OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
212	OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
213	OUTREG(NEO2070_SRCSTART,
214	    (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));
215	OUTREG(NEO2070_DSTSTART,
216	    (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));
217    }
218    else {
219	/* start with lower right corner */
220	WAIT_ENGINE_IDLE();
221	OUTREG(NEO2070_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC
222                                                        | NEO_BC0_DST_Y_DEC
223                                                        | NEO_BC0_SRC_Y_DEC));
224	OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
225	OUTREG(NEO2070_SRCSTART,
226	    ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth));
227	OUTREG(NEO2070_DSTSTART,
228	    ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) * nAcl->PixelWidth));
229    }
230}
231
232
233static void
234Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
235			     unsigned int planemask)
236{
237    NEOPtr nPtr = NEOPTR(pScrn);
238    NEOACLPtr nAcl = NEOACLPTR(pScrn);
239
240    planemask &= nAcl->PlaneMask;
241    if (!rop) color=0;
242
243    WAIT_ENGINE_IDLE();
244
245    OUTREG(NEO2070_BLTCNTL, nAcl->BltCntlFlags  |
246                            NEO_BC0_SRC_IS_FG    | neo2070Rop[3]);
247    OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
248    if (pScrn->bitsPerPixel == 8)
249	OUTREG(NEO2070_FGCOLOR, color |= (color << 8));
250    else
251	/* swap bytes in color */
252	OUTREG(NEO2070_FGCOLOR, ((color&0xff00) >> 8) | (color << 8));
253    OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
254    OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
255    OUTREG(NEO2070_SRCBITOFF, 0);
256    OUTREG(NEO2070_DSTBITOFF, 0);
257}
258
259
260static void
261Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
262{
263    NEOPtr nPtr = NEOPTR(pScrn);
264    NEOACLPtr nAcl = NEOACLPTR(pScrn);
265
266    WAIT_ENGINE_IDLE();
267    OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
268    OUTREG(NEO2070_DSTSTART, (y * nAcl->Pitch) + (x * nAcl->PixelWidth));
269}
270#endif
271
272