neo_2070.c revision c3c9db83
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/* Memory Mapped I/O for BitBlt */
56#define NEO2070_BLTSTAT		0x00
57#define NEO2070_BLTCNTL		0x04
58#define NEO2070_XPCOLOR		0x08
59#define NEO2070_FGCOLOR		0x0c
60#define NEO2070_BGCOLOR		0x10
61#define NEO2070_PLANEMASK	0x14
62#define NEO2070_XYEXT           0x18
63#define NEO2070_SRCPITCH        0x1c
64#define NEO2070_SRCBITOFF       0x20
65#define NEO2070_SRCSTART        0x24
66#define NEO2070_DSTPITCH        0x28
67#define NEO2070_DSTBITOFF       0x2c
68#define NEO2070_DSTSTART        0x30
69
70static unsigned int neo2070Rop[16] = {
71    0x000000,    /* 0x0000 - GXclear         */
72    0x080000,    /* 0x1000 - GXand           */
73    0x040000,    /* 0x0100 - GXandReverse    */
74    0x0c0000,    /* 0x1100 - GXcopy          */
75    0x020000,    /* 0x0010 - GXandInvert     */
76    0x0a0000,    /* 0x1010 - GXnoop          */
77    0x060000,    /* 0x0110 - GXxor           */
78    0x0e0000,    /* 0x1110 - GXor            */
79    0x010000,    /* 0x0001 - GXnor           */
80    0x090000,    /* 0x1001 - GXequiv         */
81    0x050000,    /* 0x0101 - GXinvert        */
82    0x0d0000,    /* 0x1101 - GXorReverse     */
83    0x030000,    /* 0x0011 - GXcopyInvert    */
84    0x0b0000,    /* 0x1011 - GXorInverted    */
85    0x070000,    /* 0x0111 - GXnand          */
86    0x0f0000     /* 0x1111 - GXset           */
87};
88
89static void Neo2070Sync(ScrnInfoPtr pScrn);
90static void Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
91					      int ydir, int rop,
92					      unsigned int planemask,
93					      int trans_color);
94static void Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
95						int srcY, int dstX, int dstY,
96						int w, int h);
97static void Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
98				  unsigned int planemask);
99static void Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
100					   int w, int h);
101
102Bool
103Neo2070AccelInit(ScreenPtr pScreen)
104{
105    XAAInfoRecPtr infoPtr;
106    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
107    NEOPtr nPtr = NEOPTR(pScrn);
108    NEOACLPtr nAcl = NEOACLPTR(pScrn);
109
110    nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
111    if(!infoPtr) return FALSE;
112
113    /*
114     * Set up the main acceleration flags.
115     */
116    infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
117    if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags |= PIXMAP_CACHE;
118#if 0
119    infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
120#endif
121    /* sync */
122    infoPtr->Sync = Neo2070Sync;
123
124    /* screen to screen copy */
125    infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | GXCOPY_ONLY);
126    infoPtr->SetupForScreenToScreenCopy =
127	Neo2070SetupForScreenToScreenCopy;
128    infoPtr->SubsequentScreenToScreenCopy =
129	Neo2070SubsequentScreenToScreenCopy;
130
131    /* solid filled rectangles */
132    infoPtr->SolidFillFlags = GXCOPY_ONLY;
133    infoPtr->SetupForSolidFill =
134	Neo2070SetupForSolidFillRect;
135    infoPtr->SubsequentSolidFillRect =
136	Neo2070SubsequentSolidFillRect;
137
138    /*
139     * Setup some global variables
140     */
141
142    /* Initialize for 8bpp or 15/16bpp support accellerated */
143    switch (pScrn->bitsPerPixel) {
144    case 8:
145	nAcl->BltCntlFlags = NEO_BC1_DEPTH8;
146	nAcl->ColorShiftAmt = 8;
147	nAcl->PixelWidth = 1;
148	nAcl->PlaneMask = 0xff;
149	break;
150    case 15:
151    case 16:
152	nAcl->BltCntlFlags = NEO_BC1_DEPTH16;
153	nAcl->ColorShiftAmt = 0;
154	nAcl->PixelWidth = 2;
155	nAcl->PlaneMask = 0xffff;
156	break;
157    case 24: /* not supported, but check anyway */
158    default:
159	return FALSE;
160    }
161
162    return(XAAInit(pScreen, infoPtr));
163
164}
165
166static void
167Neo2070Sync(ScrnInfoPtr pScrn)
168{
169    NEOPtr nPtr = NEOPTR(pScrn);
170    WAIT_ENGINE_IDLE();
171}
172
173static void
174Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
175				  int rop,
176				  unsigned int planemask,
177				  int trans_color)
178{
179    NEOPtr nPtr = NEOPTR(pScrn);
180    NEOACLPtr nAcl = NEOACLPTR(pScrn);
181
182    /* set blt control */
183    WAIT_ENGINE_IDLE();
184    OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
185    OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
186    OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
187    OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
188    OUTREG(NEO2070_SRCBITOFF, 0);
189    OUTREG(NEO2070_DSTBITOFF, 0);
190}
191
192static void
193Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
194				    int srcX, int srcY,
195				    int dstX, int dstY,
196				    int w, int h)
197{
198    NEOPtr nPtr = NEOPTR(pScrn);
199    NEOACLPtr nAcl = NEOACLPTR(pScrn);
200
201    if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
202	/* start with upper left corner */
203	WAIT_ENGINE_IDLE();
204	OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
205	OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
206	OUTREG(NEO2070_SRCSTART,
207	    (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));
208	OUTREG(NEO2070_DSTSTART,
209	    (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));
210    }
211    else {
212	/* start with lower right corner */
213	WAIT_ENGINE_IDLE();
214	OUTREG(NEO2070_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC
215                                                        | NEO_BC0_DST_Y_DEC
216                                                        | NEO_BC0_SRC_Y_DEC));
217	OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
218	OUTREG(NEO2070_SRCSTART,
219	    ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth));
220	OUTREG(NEO2070_DSTSTART,
221	    ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) * nAcl->PixelWidth));
222    }
223}
224
225
226static void
227Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
228			     unsigned int planemask)
229{
230    NEOPtr nPtr = NEOPTR(pScrn);
231    NEOACLPtr nAcl = NEOACLPTR(pScrn);
232
233    planemask &= nAcl->PlaneMask;
234    if (!rop) color=0;
235
236    WAIT_ENGINE_IDLE();
237
238    OUTREG(NEO2070_BLTCNTL, nAcl->BltCntlFlags  |
239                            NEO_BC0_SRC_IS_FG    | neo2070Rop[3]);
240    OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
241    if (pScrn->bitsPerPixel == 8)
242	OUTREG(NEO2070_FGCOLOR, color |= (color << 8));
243    else
244	/* swap bytes in color */
245	OUTREG(NEO2070_FGCOLOR, ((color&0xff00) >> 8) | (color << 8));
246    OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
247    OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
248    OUTREG(NEO2070_SRCBITOFF, 0);
249    OUTREG(NEO2070_DSTBITOFF, 0);
250}
251
252
253static void
254Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
255{
256    NEOPtr nPtr = NEOPTR(pScrn);
257    NEOACLPtr nAcl = NEOACLPTR(pScrn);
258
259    WAIT_ENGINE_IDLE();
260    OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
261    OUTREG(NEO2070_DSTSTART, (y * nAcl->Pitch) + (x * nAcl->PixelWidth));
262}
263
264
265
266
267
268