1428d7b3dSmrg
2428d7b3dSmrg/**************************************************************************
3428d7b3dSmrg
4428d7b3dSmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5428d7b3dSmrgAll Rights Reserved.
6428d7b3dSmrg
7428d7b3dSmrgPermission is hereby granted, free of charge, to any person obtaining a
8428d7b3dSmrgcopy of this software and associated documentation files (the
9428d7b3dSmrg"Software"), to deal in the Software without restriction, including
10428d7b3dSmrgwithout limitation the rights to use, copy, modify, merge, publish,
11428d7b3dSmrgdistribute, sub license, and/or sell copies of the Software, and to
12428d7b3dSmrgpermit persons to whom the Software is furnished to do so, subject to
13428d7b3dSmrgthe following conditions:
14428d7b3dSmrg
15428d7b3dSmrgThe above copyright notice and this permission notice (including the
16428d7b3dSmrgnext paragraph) shall be included in all copies or substantial portions
17428d7b3dSmrgof the Software.
18428d7b3dSmrg
19428d7b3dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20428d7b3dSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21428d7b3dSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22428d7b3dSmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23428d7b3dSmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24428d7b3dSmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25428d7b3dSmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26428d7b3dSmrg
27428d7b3dSmrg**************************************************************************/
28428d7b3dSmrg
29428d7b3dSmrg#ifdef HAVE_CONFIG_H
30428d7b3dSmrg#include "config.h"
31428d7b3dSmrg#endif
32428d7b3dSmrg
33428d7b3dSmrg/*
34428d7b3dSmrg * Authors:
35428d7b3dSmrg *   Keith Whitwell <keith@tungstengraphics.com>
36428d7b3dSmrg *
37428d7b3dSmrg */
38428d7b3dSmrg
39428d7b3dSmrg#include "xorg-server.h"
40428d7b3dSmrg#include "xf86.h"
41428d7b3dSmrg#include "xaarop.h"
42428d7b3dSmrg#include "i810.h"
43428d7b3dSmrg
44428d7b3dSmrgstatic void
45428d7b3dSmrgI810SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
46428d7b3dSmrg			       int fg, int bg, int rop,
47428d7b3dSmrg			       unsigned int planemask)
48428d7b3dSmrg{
49428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
50428d7b3dSmrg
51428d7b3dSmrg   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
52428d7b3dSmrg      ErrorF("I810SetupFor8x8PatternColorExpand\n");
53428d7b3dSmrg
54428d7b3dSmrg   /* FULL_MONO_PAT_BLT, p176 */
55428d7b3dSmrg   pI810->BR[0] = (BR00_BITBLT_CLIENT | BR00_OP_MONO_PAT_BLT | 0x9);
56428d7b3dSmrg   pI810->BR[18] = bg;
57428d7b3dSmrg   pI810->BR[19] = fg;
58428d7b3dSmrg   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
59428d7b3dSmrg   pI810->BR[13] |= I810PatternROP[rop] << 16;
60428d7b3dSmrg   if (bg == -1)
61428d7b3dSmrg      pI810->BR[13] |= BR13_MONO_PATN_TRANS;
62428d7b3dSmrg}
63428d7b3dSmrg
64428d7b3dSmrgstatic void
65428d7b3dSmrgI810SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
66428d7b3dSmrg				     int x, int y, int w, int h)
67428d7b3dSmrg{
68428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
69428d7b3dSmrg   int addr =
70428d7b3dSmrg	 pI810->bufferOffset + (y * pScrn->displayWidth + x) * pI810->cpp;
71428d7b3dSmrg
72428d7b3dSmrg   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
73428d7b3dSmrg      ErrorF("I810Subsequent8x8PatternColorExpand\n");
74428d7b3dSmrg
75428d7b3dSmrg   {
76428d7b3dSmrg      BEGIN_LP_RING(12);
77428d7b3dSmrg      OUT_RING(pI810->BR[0] | ((y << 5) & BR00_PAT_VERT_ALIGN));
78428d7b3dSmrg      OUT_RING(pI810->BR[13]);
79428d7b3dSmrg      OUT_RING((h << 16) | (w * pI810->cpp));
80428d7b3dSmrg      OUT_RING(addr);
81428d7b3dSmrg      OUT_RING(pI810->BR[13] & 0xFFFF);	/* src pitch */
82428d7b3dSmrg      OUT_RING(addr);			/* src addr */
83428d7b3dSmrg      OUT_RING(0);			/* transparency color */
84428d7b3dSmrg      OUT_RING(pI810->BR[18]);		/* bg */
85428d7b3dSmrg      OUT_RING(pI810->BR[19]);		/* fg */
86428d7b3dSmrg      OUT_RING(pattx);			/* pattern data */
87428d7b3dSmrg      OUT_RING(patty);
88428d7b3dSmrg      OUT_RING(0);
89428d7b3dSmrg      ADVANCE_LP_RING();
90428d7b3dSmrg   }
91428d7b3dSmrg}
92428d7b3dSmrg
93428d7b3dSmrgstatic void
94428d7b3dSmrgI810GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
95428d7b3dSmrg{
96428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
97428d7b3dSmrg   XAAInfoRecPtr infoPtr = pI810->AccelInfoRec;
98428d7b3dSmrg
99428d7b3dSmrg   if (pI810->nextColorExpandBuf == pI810->NumScanlineColorExpandBuffers)
100428d7b3dSmrg      I810Sync(pScrn);
101428d7b3dSmrg
102428d7b3dSmrg   infoPtr->ScanlineColorExpandBuffers[0] =
103428d7b3dSmrg	 pI810->ScanlineColorExpandBuffers[pI810->nextColorExpandBuf];
104428d7b3dSmrg
105428d7b3dSmrg   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
106428d7b3dSmrg      ErrorF("using color expand buffer %d\n", pI810->nextColorExpandBuf);
107428d7b3dSmrg
108428d7b3dSmrg   pI810->nextColorExpandBuf++;
109428d7b3dSmrg}
110428d7b3dSmrg
111428d7b3dSmrgstatic void
112428d7b3dSmrgI810SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
113428d7b3dSmrg					       int fg, int bg, int rop,
114428d7b3dSmrg					       unsigned int planemask)
115428d7b3dSmrg{
116428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
117428d7b3dSmrg
118428d7b3dSmrg   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
119428d7b3dSmrg      ErrorF("I810SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
120428d7b3dSmrg	     fg, bg, rop, planemask);
121428d7b3dSmrg
122428d7b3dSmrg   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
123428d7b3dSmrg   pI810->BR[13] |= I810CopyROP[rop] << 16;
124428d7b3dSmrg   pI810->BR[13] |= (1 << 27);
125428d7b3dSmrg   if (bg == -1)
126428d7b3dSmrg      pI810->BR[13] |= BR13_MONO_TRANSPCY;
127428d7b3dSmrg
128428d7b3dSmrg   pI810->BR[18] = bg;
129428d7b3dSmrg   pI810->BR[19] = fg;
130428d7b3dSmrg
131428d7b3dSmrg   I810GetNextScanlineColorExpandBuffer(pScrn);
132428d7b3dSmrg}
133428d7b3dSmrg
134428d7b3dSmrgstatic void
135428d7b3dSmrgI810SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
136428d7b3dSmrg						 int x, int y,
137428d7b3dSmrg						 int w, int h, int skipleft)
138428d7b3dSmrg{
139428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
140428d7b3dSmrg
141428d7b3dSmrg   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
142428d7b3dSmrg      ErrorF("I810SubsequentScanlineCPUToScreenColorExpandFill "
143428d7b3dSmrg	     "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
144428d7b3dSmrg
145428d7b3dSmrg   pI810->BR[0] = BR00_BITBLT_CLIENT | BR00_OP_MONO_SRC_COPY_BLT | 0x06;
146428d7b3dSmrg   pI810->BR[9] = (pI810->bufferOffset +
147428d7b3dSmrg		   (y * pScrn->displayWidth + x) * pI810->cpp);
148428d7b3dSmrg   pI810->BR[14] = ((1 << 16) | (w * pI810->cpp));
149428d7b3dSmrg   pI810->BR[11] = ((w + 31) / 32) - 1;
150428d7b3dSmrg}
151428d7b3dSmrg
152428d7b3dSmrgstatic void
153428d7b3dSmrgI810SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
154428d7b3dSmrg{
155428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
156428d7b3dSmrg
157428d7b3dSmrg   pI810->BR[12] = (pI810->AccelInfoRec->ScanlineColorExpandBuffers[0] -
158428d7b3dSmrg		    pI810->FbBase);
159428d7b3dSmrg
160428d7b3dSmrg   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
161428d7b3dSmrg      ErrorF("I810SubsequentColorExpandScanline %d (addr %x)\n",
162428d7b3dSmrg	     bufno, pI810->BR[12]);
163428d7b3dSmrg
164428d7b3dSmrg   {
165428d7b3dSmrg      BEGIN_LP_RING(8);
166428d7b3dSmrg      OUT_RING(pI810->BR[0]);
167428d7b3dSmrg      OUT_RING(pI810->BR[13]);
168428d7b3dSmrg      OUT_RING(pI810->BR[14]);
169428d7b3dSmrg      OUT_RING(pI810->BR[9]);
170428d7b3dSmrg      OUT_RING(pI810->BR[11]);
171428d7b3dSmrg      OUT_RING(pI810->BR[12]);		/* srcaddr */
172428d7b3dSmrg      OUT_RING(pI810->BR[18]);
173428d7b3dSmrg      OUT_RING(pI810->BR[19]);
174428d7b3dSmrg      ADVANCE_LP_RING();
175428d7b3dSmrg   }
176428d7b3dSmrg
177428d7b3dSmrg   /* Advance to next scanline.
178428d7b3dSmrg    */
179428d7b3dSmrg   pI810->BR[9] += pScrn->displayWidth * pI810->cpp;
180428d7b3dSmrg   I810GetNextScanlineColorExpandBuffer(pScrn);
181428d7b3dSmrg}
182428d7b3dSmrg
183428d7b3dSmrg/* Emit on gaining VT?
184428d7b3dSmrg */
185428d7b3dSmrg#if 0
186428d7b3dSmrgstatic void
187428d7b3dSmrgI810EmitInvarientState(ScrnInfoPtr pScrn)
188428d7b3dSmrg{
189428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
190428d7b3dSmrg
191428d7b3dSmrg   BEGIN_LP_RING(10);
192428d7b3dSmrg
193428d7b3dSmrg   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
194428d7b3dSmrg   OUT_RING(GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0);
195428d7b3dSmrg   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
196428d7b3dSmrg   OUT_RING(0);
197428d7b3dSmrg
198428d7b3dSmrg   OUT_RING(GFX_OP_COLOR_CHROMA_KEY);
199428d7b3dSmrg   OUT_RING(CC1_UPDATE_KILL_WRITE |
200428d7b3dSmrg	    CC1_DISABLE_KILL_WRITE |
201428d7b3dSmrg	    CC1_UPDATE_COLOR_IDX |
202428d7b3dSmrg	    CC1_UPDATE_CHROMA_LOW | CC1_UPDATE_CHROMA_HI | 0);
203428d7b3dSmrg   OUT_RING(0);
204428d7b3dSmrg   OUT_RING(0);
205428d7b3dSmrg
206428d7b3dSmrg/*     OUT_RING( CMD_OP_Z_BUFFER_INFO ); */
207428d7b3dSmrg/*     OUT_RING( pI810->DepthBuffer.Start | pI810->auxPitchBits); */
208428d7b3dSmrg
209428d7b3dSmrg   ADVANCE_LP_RING();
210428d7b3dSmrg}
211428d7b3dSmrg#endif
212428d7b3dSmrg
213428d7b3dSmrg/* The following function sets up the supported acceleration. Call it
214428d7b3dSmrg * from the FbInit() function in the SVGA driver, or before ScreenInit
215428d7b3dSmrg * in a monolithic server.
216428d7b3dSmrg */
217428d7b3dSmrgBool
218428d7b3dSmrgI810AccelInit(ScreenPtr pScreen)
219428d7b3dSmrg{
220428d7b3dSmrg   XAAInfoRecPtr infoPtr;
221428d7b3dSmrg   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
222428d7b3dSmrg   I810Ptr pI810 = I810PTR(pScrn);
223428d7b3dSmrg
224428d7b3dSmrg   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
225428d7b3dSmrg      ErrorF("I810AccelInit\n");
226428d7b3dSmrg
227428d7b3dSmrg   pI810->AccelInfoRec = infoPtr = XAACreateInfoRec();
228428d7b3dSmrg   if (!infoPtr)
229428d7b3dSmrg      return FALSE;
230428d7b3dSmrg
231428d7b3dSmrg   pI810->bufferOffset = 0;
232428d7b3dSmrg   infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
233428d7b3dSmrg   infoPtr->Flags |= PIXMAP_CACHE;
234428d7b3dSmrg
235428d7b3dSmrg   /* Sync
236428d7b3dSmrg    */
237428d7b3dSmrg   infoPtr->Sync = I810Sync;
238428d7b3dSmrg
239428d7b3dSmrg   /* Solid filled rectangles
240428d7b3dSmrg    */
241428d7b3dSmrg   {
242428d7b3dSmrg      infoPtr->SolidFillFlags = NO_PLANEMASK;
243428d7b3dSmrg      infoPtr->SetupForSolidFill = I810SetupForSolidFill;
244428d7b3dSmrg      infoPtr->SubsequentSolidFillRect = I810SubsequentSolidFillRect;
245428d7b3dSmrg   }
246428d7b3dSmrg
247428d7b3dSmrg   /* Screen to screen copy
248428d7b3dSmrg    *   - the transparency op hangs the blit engine, disable for now.
249428d7b3dSmrg    */
250428d7b3dSmrg   {
251428d7b3dSmrg      infoPtr->ScreenToScreenCopyFlags = (0
252428d7b3dSmrg					  | NO_PLANEMASK
253428d7b3dSmrg					  | NO_TRANSPARENCY | 0);
254428d7b3dSmrg
255428d7b3dSmrg      infoPtr->SetupForScreenToScreenCopy = I810SetupForScreenToScreenCopy;
256428d7b3dSmrg      infoPtr->SubsequentScreenToScreenCopy =
257428d7b3dSmrg	    I810SubsequentScreenToScreenCopy;
258428d7b3dSmrg   }
259428d7b3dSmrg
260428d7b3dSmrg   /* 8x8 pattern fills
261428d7b3dSmrg    */
262428d7b3dSmrg   {
263428d7b3dSmrg      infoPtr->SetupForMono8x8PatternFill = I810SetupForMono8x8PatternFill;
264428d7b3dSmrg      infoPtr->SubsequentMono8x8PatternFillRect =
265428d7b3dSmrg	    I810SubsequentMono8x8PatternFillRect;
266428d7b3dSmrg
267428d7b3dSmrg      infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
268428d7b3dSmrg					  HARDWARE_PATTERN_SCREEN_ORIGIN |
269428d7b3dSmrg					  BIT_ORDER_IN_BYTE_MSBFIRST |
270428d7b3dSmrg					  NO_PLANEMASK | 0);
271428d7b3dSmrg   }
272428d7b3dSmrg
273428d7b3dSmrg   /* 8x8 color fills - not considered useful for XAA.
274428d7b3dSmrg    */
275428d7b3dSmrg
276428d7b3dSmrg   /* Scanline color expansion - Use the same scheme as the 3.3 driver.
277428d7b3dSmrg    *
278428d7b3dSmrg    */
279428d7b3dSmrg   if (pI810->Scratch.Size != 0) {
280428d7b3dSmrg      int i;
281428d7b3dSmrg      int width = ALIGN(pScrn->displayWidth, 32) / 8;
282428d7b3dSmrg      int nr_buffers = pI810->Scratch.Size / width;
283428d7b3dSmrg      unsigned char *ptr = pI810->FbBase + pI810->Scratch.Start;
284428d7b3dSmrg
285428d7b3dSmrg      pI810->NumScanlineColorExpandBuffers = nr_buffers;
286428d7b3dSmrg      pI810->ScanlineColorExpandBuffers = (unsigned char **)
287428d7b3dSmrg	    xnfcalloc(nr_buffers, sizeof(unsigned char *));
288428d7b3dSmrg
289428d7b3dSmrg      for (i = 0; i < nr_buffers; i++, ptr += width)
290428d7b3dSmrg	 pI810->ScanlineColorExpandBuffers[i] = ptr;
291428d7b3dSmrg
292428d7b3dSmrg      infoPtr->ScanlineCPUToScreenColorExpandFillFlags = (NO_PLANEMASK |
293428d7b3dSmrg							  ROP_NEEDS_SOURCE |
294428d7b3dSmrg							  BIT_ORDER_IN_BYTE_MSBFIRST
295428d7b3dSmrg							  | 0);
296428d7b3dSmrg
297428d7b3dSmrg      infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
298428d7b3dSmrg	    xnfcalloc(1, sizeof(unsigned char *));
299428d7b3dSmrg      infoPtr->NumScanlineColorExpandBuffers = 1;
300428d7b3dSmrg
301428d7b3dSmrg      infoPtr->ScanlineColorExpandBuffers[0] =
302428d7b3dSmrg	    pI810->ScanlineColorExpandBuffers[0];
303428d7b3dSmrg      pI810->nextColorExpandBuf = 0;
304428d7b3dSmrg
305428d7b3dSmrg      infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
306428d7b3dSmrg	    I810SetupForScanlineCPUToScreenColorExpandFill;
307428d7b3dSmrg
308428d7b3dSmrg      infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
309428d7b3dSmrg	    I810SubsequentScanlineCPUToScreenColorExpandFill;
310428d7b3dSmrg
311428d7b3dSmrg      infoPtr->SubsequentColorExpandScanline =
312428d7b3dSmrg	    I810SubsequentColorExpandScanline;
313428d7b3dSmrg   }
314428d7b3dSmrg
315428d7b3dSmrg   /* Possible todo: Image writes w/ non-GXCOPY rop.
316428d7b3dSmrg    */
317428d7b3dSmrg
318428d7b3dSmrg   I810SelectBuffer(pScrn, I810_SELECT_FRONT);
319428d7b3dSmrg
320428d7b3dSmrg   return XAAInit(pScreen, infoPtr);
321428d7b3dSmrg}
322