1fa225cbcSrjs
2fa225cbcSrjs/**************************************************************************
3fa225cbcSrjs
4fa225cbcSrjsCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5fa225cbcSrjsAll Rights Reserved.
6fa225cbcSrjs
7fa225cbcSrjsPermission is hereby granted, free of charge, to any person obtaining a
8fa225cbcSrjscopy of this software and associated documentation files (the
9fa225cbcSrjs"Software"), to deal in the Software without restriction, including
10fa225cbcSrjswithout limitation the rights to use, copy, modify, merge, publish,
11fa225cbcSrjsdistribute, sub license, and/or sell copies of the Software, and to
12fa225cbcSrjspermit persons to whom the Software is furnished to do so, subject to
13fa225cbcSrjsthe following conditions:
14fa225cbcSrjs
15fa225cbcSrjsThe above copyright notice and this permission notice (including the
16fa225cbcSrjsnext paragraph) shall be included in all copies or substantial portions
17fa225cbcSrjsof the Software.
18fa225cbcSrjs
19fa225cbcSrjsTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20fa225cbcSrjsOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21fa225cbcSrjsMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22fa225cbcSrjsIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23fa225cbcSrjsANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24fa225cbcSrjsTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25fa225cbcSrjsSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26fa225cbcSrjs
27fa225cbcSrjs**************************************************************************/
28fa225cbcSrjs
29fa225cbcSrjs#ifdef HAVE_CONFIG_H
30fa225cbcSrjs#include "config.h"
31fa225cbcSrjs#endif
32fa225cbcSrjs
33fa225cbcSrjs/*
34fa225cbcSrjs * Authors:
35fa225cbcSrjs *   Keith Whitwell <keith@tungstengraphics.com>
36fa225cbcSrjs *
37fa225cbcSrjs */
38fa225cbcSrjs
39fa225cbcSrjs#include "xf86.h"
40fa225cbcSrjs#include "xaarop.h"
41fa225cbcSrjs#include "i810.h"
42fa225cbcSrjs
43fa225cbcSrjsstatic void I810SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
44fa225cbcSrjs					   int pattx, int patty,
45fa225cbcSrjs					   int fg, int bg, int rop,
46fa225cbcSrjs					   unsigned int planemask);
47fa225cbcSrjsstatic void I810SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
48fa225cbcSrjs						 int pattx, int patty,
49fa225cbcSrjs						 int x, int y, int w, int h);
50fa225cbcSrjs
51fa225cbcSrjsstatic void I810SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
52fa225cbcSrjs							   int fg, int bg,
53fa225cbcSrjs							   int rop,
54fa225cbcSrjs							   unsigned int mask);
55fa225cbcSrjs
56fa225cbcSrjsstatic void I810SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr
57fa225cbcSrjs							     pScrn, int x,
58fa225cbcSrjs							     int y, int w,
59fa225cbcSrjs							     int h,
60fa225cbcSrjs							     int skipleft);
61fa225cbcSrjs
62fa225cbcSrjsstatic void I810SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
63fa225cbcSrjs
64fa225cbcSrjs/* The following function sets up the supported acceleration. Call it
65fa225cbcSrjs * from the FbInit() function in the SVGA driver, or before ScreenInit
66fa225cbcSrjs * in a monolithic server.
67fa225cbcSrjs */
68fa225cbcSrjsBool
69fa225cbcSrjsI810AccelInit(ScreenPtr pScreen)
70fa225cbcSrjs{
71fa225cbcSrjs   XAAInfoRecPtr infoPtr;
72fa225cbcSrjs   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
73fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
74fa225cbcSrjs
75fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
76fa225cbcSrjs      ErrorF("I810AccelInit\n");
77fa225cbcSrjs
78fa225cbcSrjs   pI810->AccelInfoRec = infoPtr = XAACreateInfoRec();
79fa225cbcSrjs   if (!infoPtr)
80fa225cbcSrjs      return FALSE;
81fa225cbcSrjs
82fa225cbcSrjs   pI810->bufferOffset = 0;
83fa225cbcSrjs   infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
84fa225cbcSrjs   infoPtr->Flags |= PIXMAP_CACHE;
85fa225cbcSrjs
86fa225cbcSrjs   /* Sync
87fa225cbcSrjs    */
88fa225cbcSrjs   infoPtr->Sync = I810Sync;
89fa225cbcSrjs
90fa225cbcSrjs   /* Solid filled rectangles
91fa225cbcSrjs    */
92fa225cbcSrjs   {
93fa225cbcSrjs      infoPtr->SolidFillFlags = NO_PLANEMASK;
94fa225cbcSrjs      infoPtr->SetupForSolidFill = I810SetupForSolidFill;
95fa225cbcSrjs      infoPtr->SubsequentSolidFillRect = I810SubsequentSolidFillRect;
96fa225cbcSrjs   }
97fa225cbcSrjs
98fa225cbcSrjs   /* Screen to screen copy
99fa225cbcSrjs    *   - the transparency op hangs the blit engine, disable for now.
100fa225cbcSrjs    */
101fa225cbcSrjs   {
102fa225cbcSrjs      infoPtr->ScreenToScreenCopyFlags = (0
103fa225cbcSrjs					  | NO_PLANEMASK
104fa225cbcSrjs					  | NO_TRANSPARENCY | 0);
105fa225cbcSrjs
106fa225cbcSrjs      infoPtr->SetupForScreenToScreenCopy = I810SetupForScreenToScreenCopy;
107fa225cbcSrjs      infoPtr->SubsequentScreenToScreenCopy =
108fa225cbcSrjs	    I810SubsequentScreenToScreenCopy;
109fa225cbcSrjs   }
110fa225cbcSrjs
111fa225cbcSrjs   /* 8x8 pattern fills
112fa225cbcSrjs    */
113fa225cbcSrjs   {
114fa225cbcSrjs      infoPtr->SetupForMono8x8PatternFill = I810SetupForMono8x8PatternFill;
115fa225cbcSrjs      infoPtr->SubsequentMono8x8PatternFillRect =
116fa225cbcSrjs	    I810SubsequentMono8x8PatternFillRect;
117fa225cbcSrjs
118fa225cbcSrjs      infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
119fa225cbcSrjs					  HARDWARE_PATTERN_SCREEN_ORIGIN |
120fa225cbcSrjs					  BIT_ORDER_IN_BYTE_MSBFIRST |
121fa225cbcSrjs					  NO_PLANEMASK | 0);
122fa225cbcSrjs   }
123fa225cbcSrjs
124fa225cbcSrjs   /* 8x8 color fills - not considered useful for XAA.
125fa225cbcSrjs    */
126fa225cbcSrjs
127fa225cbcSrjs   /* Scanline color expansion - Use the same scheme as the 3.3 driver.
128fa225cbcSrjs    *
129fa225cbcSrjs    */
130fa225cbcSrjs   if (pI810->Scratch.Size != 0) {
131fa225cbcSrjs      int i;
132fa225cbcSrjs      int width = ((pScrn->displayWidth + 31) & ~31) / 8;
133fa225cbcSrjs      int nr_buffers = pI810->Scratch.Size / width;
134fa225cbcSrjs      unsigned char *ptr = pI810->FbBase + pI810->Scratch.Start;
135fa225cbcSrjs
136fa225cbcSrjs      pI810->NumScanlineColorExpandBuffers = nr_buffers;
137fa225cbcSrjs      pI810->ScanlineColorExpandBuffers = (unsigned char **)
138fa225cbcSrjs	    xnfcalloc(nr_buffers, sizeof(unsigned char *));
139fa225cbcSrjs
140fa225cbcSrjs      for (i = 0; i < nr_buffers; i++, ptr += width)
141fa225cbcSrjs	 pI810->ScanlineColorExpandBuffers[i] = ptr;
142fa225cbcSrjs
143fa225cbcSrjs      infoPtr->ScanlineCPUToScreenColorExpandFillFlags = (NO_PLANEMASK |
144fa225cbcSrjs							  ROP_NEEDS_SOURCE |
145fa225cbcSrjs							  BIT_ORDER_IN_BYTE_MSBFIRST
146fa225cbcSrjs							  | 0);
147fa225cbcSrjs
148fa225cbcSrjs      infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
149fa225cbcSrjs	    xnfcalloc(1, sizeof(unsigned char *));
150fa225cbcSrjs      infoPtr->NumScanlineColorExpandBuffers = 1;
151fa225cbcSrjs
152fa225cbcSrjs      infoPtr->ScanlineColorExpandBuffers[0] =
153fa225cbcSrjs	    pI810->ScanlineColorExpandBuffers[0];
154fa225cbcSrjs      pI810->nextColorExpandBuf = 0;
155fa225cbcSrjs
156fa225cbcSrjs      infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
157fa225cbcSrjs	    I810SetupForScanlineCPUToScreenColorExpandFill;
158fa225cbcSrjs
159fa225cbcSrjs      infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
160fa225cbcSrjs	    I810SubsequentScanlineCPUToScreenColorExpandFill;
161fa225cbcSrjs
162fa225cbcSrjs      infoPtr->SubsequentColorExpandScanline =
163fa225cbcSrjs	    I810SubsequentColorExpandScanline;
164fa225cbcSrjs   }
165fa225cbcSrjs
166fa225cbcSrjs   /* Possible todo: Image writes w/ non-GXCOPY rop.
167fa225cbcSrjs    */
168fa225cbcSrjs
169fa225cbcSrjs   I810SelectBuffer(pScrn, I810_SELECT_FRONT);
170fa225cbcSrjs
171fa225cbcSrjs   return XAAInit(pScreen, infoPtr);
172fa225cbcSrjs}
173fa225cbcSrjs
174fa225cbcSrjsint
175fa225cbcSrjsI810WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
176fa225cbcSrjs{
177fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
178fa225cbcSrjs   I810RingBuffer *ring = pI810->LpRing;
179fa225cbcSrjs   int iters = 0;
180fa225cbcSrjs   int start = 0;
181fa225cbcSrjs   int now = 0;
182fa225cbcSrjs   int last_head = 0;
183fa225cbcSrjs   int first = 0;
184fa225cbcSrjs
185fa225cbcSrjs   /* If your system hasn't moved the head pointer in 2 seconds, I'm going to
186fa225cbcSrjs    * call it crashed.
187fa225cbcSrjs    */
188fa225cbcSrjs   if (timeout_millis == 0)
189fa225cbcSrjs      timeout_millis = 2000;
190fa225cbcSrjs
191fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) {
192fa225cbcSrjs      ErrorF("I810WaitLpRing %d\n", n);
193fa225cbcSrjs      first = GetTimeInMillis();
194fa225cbcSrjs   }
195fa225cbcSrjs
196fa225cbcSrjs   while (ring->space < n) {
197fa225cbcSrjs      ring->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
198fa225cbcSrjs      ring->space = ring->head - (ring->tail + 8);
199fa225cbcSrjs
200fa225cbcSrjs      if (ring->space < 0)
201fa225cbcSrjs	 ring->space += ring->mem.Size;
202fa225cbcSrjs
203fa225cbcSrjs      iters++;
204fa225cbcSrjs      now = GetTimeInMillis();
205fa225cbcSrjs      if (start == 0 || now < start || ring->head != last_head) {
206fa225cbcSrjs	 if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
207fa225cbcSrjs	    if (now > start)
208fa225cbcSrjs	       ErrorF("space: %d wanted %d\n", ring->space, n);
209fa225cbcSrjs	 start = now;
210fa225cbcSrjs	 last_head = ring->head;
211fa225cbcSrjs      } else if (now - start > timeout_millis) {
212fa225cbcSrjs	 ErrorF("Error in I810WaitLpRing(), now is %d, start is %d\n", now,
213fa225cbcSrjs		start);
214fa225cbcSrjs	 I810PrintErrorState(pScrn);
215fa225cbcSrjs	 ErrorF("space: %d wanted %d\n", ring->space, n);
216fa225cbcSrjs#ifdef XF86DRI
217fa225cbcSrjs	 if (pI810->directRenderingEnabled) {
218fa225cbcSrjs	    DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
219fa225cbcSrjs	    DRICloseScreen(screenInfo.screens[pScrn->scrnIndex]);
220fa225cbcSrjs	 }
221fa225cbcSrjs#endif
222fa225cbcSrjs	 pI810->AccelInfoRec = NULL;	/* Stops recursive behavior */
223fa225cbcSrjs	 FatalError("lockup\n");
224fa225cbcSrjs      }
225fa225cbcSrjs
226fa225cbcSrjs      DELAY(10000);
227fa225cbcSrjs   }
228fa225cbcSrjs
229fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) {
230fa225cbcSrjs      now = GetTimeInMillis();
231fa225cbcSrjs      if (now - first) {
232fa225cbcSrjs	 ErrorF("Elapsed %d ms\n", now - first);
233fa225cbcSrjs	 ErrorF("space: %d wanted %d\n", ring->space, n);
234fa225cbcSrjs      }
235fa225cbcSrjs   }
236fa225cbcSrjs
237fa225cbcSrjs   return iters;
238fa225cbcSrjs}
239fa225cbcSrjs
240fa225cbcSrjsvoid
241fa225cbcSrjsI810Sync(ScrnInfoPtr pScrn)
242fa225cbcSrjs{
243fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
244fa225cbcSrjs
245fa225cbcSrjs   if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC))
246fa225cbcSrjs      ErrorF("I810Sync\n");
247fa225cbcSrjs
248fa225cbcSrjs#ifdef XF86DRI
249fa225cbcSrjs   /* VT switching tries to do this.
250fa225cbcSrjs    */
251fa225cbcSrjs   if (!pI810->LockHeld && pI810->directRenderingEnabled) {
252fa225cbcSrjs      return;
253fa225cbcSrjs   }
254fa225cbcSrjs#endif
255fa225cbcSrjs
256fa225cbcSrjs   /* Send a flush instruction and then wait till the ring is empty.
257fa225cbcSrjs    * This is stronger than waiting for the blitter to finish as it also
258fa225cbcSrjs    * flushes the internal graphics caches.
259fa225cbcSrjs    */
260fa225cbcSrjs   {
261fa225cbcSrjs      BEGIN_LP_RING(2);
262fa225cbcSrjs      OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
263fa225cbcSrjs      OUT_RING(0);			/* pad to quadword */
264fa225cbcSrjs      ADVANCE_LP_RING();
265fa225cbcSrjs   }
266fa225cbcSrjs
267fa225cbcSrjs   I810WaitLpRing(pScrn, pI810->LpRing->mem.Size - 8, 0);
268fa225cbcSrjs
269fa225cbcSrjs   pI810->LpRing->space = pI810->LpRing->mem.Size - 8;
270fa225cbcSrjs   pI810->nextColorExpandBuf = 0;
271fa225cbcSrjs}
272fa225cbcSrjs
273fa225cbcSrjsvoid
274fa225cbcSrjsI810SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
275fa225cbcSrjs		      unsigned int planemask)
276fa225cbcSrjs{
277fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
278fa225cbcSrjs
279fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
280fa225cbcSrjs      ErrorF("I810SetupForFillRectSolid color: %x rop: %x mask: %x\n",
281fa225cbcSrjs	     color, rop, planemask);
282fa225cbcSrjs
283fa225cbcSrjs   /* Color blit, p166 */
284fa225cbcSrjs   pI810->BR[13] = (BR13_SOLID_PATTERN |
285fa225cbcSrjs		    (XAAGetPatternROP(rop) << 16) |
286fa225cbcSrjs		    (pScrn->displayWidth * pI810->cpp));
287fa225cbcSrjs   pI810->BR[16] = color;
288fa225cbcSrjs}
289fa225cbcSrjs
290fa225cbcSrjsvoid
291fa225cbcSrjsI810SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
292fa225cbcSrjs{
293fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
294fa225cbcSrjs
295fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
296fa225cbcSrjs      ErrorF("I810SubsequentFillRectSolid %d,%d %dx%d\n", x, y, w, h);
297fa225cbcSrjs
298fa225cbcSrjs   {
299fa225cbcSrjs      BEGIN_LP_RING(6);
300fa225cbcSrjs
301fa225cbcSrjs      OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
302fa225cbcSrjs      OUT_RING(pI810->BR[13]);
303fa225cbcSrjs      OUT_RING((h << 16) | (w * pI810->cpp));
304fa225cbcSrjs      OUT_RING(pI810->bufferOffset +
305fa225cbcSrjs	       (y * pScrn->displayWidth + x) * pI810->cpp);
306fa225cbcSrjs
307fa225cbcSrjs      OUT_RING(pI810->BR[16]);
308fa225cbcSrjs      OUT_RING(0);			/* pad to quadword */
309fa225cbcSrjs
310fa225cbcSrjs      ADVANCE_LP_RING();
311fa225cbcSrjs   }
312fa225cbcSrjs}
313fa225cbcSrjs
314fa225cbcSrjsvoid
315fa225cbcSrjsI810SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
316fa225cbcSrjs			       unsigned int planemask, int transparency_color)
317fa225cbcSrjs{
318fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
319fa225cbcSrjs
320fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
321fa225cbcSrjs      ErrorF("I810SetupForScreenToScreenCopy %d %d %x %x %d\n",
322fa225cbcSrjs	     xdir, ydir, rop, planemask, transparency_color);
323fa225cbcSrjs
324fa225cbcSrjs   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
325fa225cbcSrjs
326fa225cbcSrjs   if (ydir == -1)
327fa225cbcSrjs      pI810->BR[13] = (-pI810->BR[13]) & 0xFFFF;
328fa225cbcSrjs   if (xdir == -1)
329fa225cbcSrjs      pI810->BR[13] |= BR13_RIGHT_TO_LEFT;
330fa225cbcSrjs
331fa225cbcSrjs   pI810->BR[13] |= XAAGetCopyROP(rop) << 16;
332fa225cbcSrjs
333fa225cbcSrjs   pI810->BR[18] = 0;
334fa225cbcSrjs}
335fa225cbcSrjs
336fa225cbcSrjsvoid
337fa225cbcSrjsI810SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
338fa225cbcSrjs				 int x2, int y2, int w, int h)
339fa225cbcSrjs{
340fa225cbcSrjs    I810Ptr pI810 = I810PTR(pScrn);
341fa225cbcSrjs    int src, dst;
342fa225cbcSrjs    int w_back = w;
343fa225cbcSrjs
344fa225cbcSrjs    if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
345fa225cbcSrjs	ErrorF( "I810SubsequentScreenToScreenCopy %d,%d - %d,%d %dx%d\n",
346fa225cbcSrjs		x1,y1,x2,y2,w,h);
347fa225cbcSrjs    /*
348fa225cbcSrjs     * This works around a bug in the i810 drawing engine.
349fa225cbcSrjs     * This was developed empirically so it may not catch all
350fa225cbcSrjs     * cases.
351fa225cbcSrjs     */
352fa225cbcSrjs#define I810_MWIDTH 8
353fa225cbcSrjs
354fa225cbcSrjs    if ( !(pI810->BR[13] & BR13_RIGHT_TO_LEFT) && (y2 - y1) < 3
355fa225cbcSrjs	 && (y2 - y1) >= 0 && (x2 - x1) <= (w + I810_MWIDTH)
356fa225cbcSrjs	 && (w > I810_MWIDTH))
357fa225cbcSrjs	w = I810_MWIDTH;
358fa225cbcSrjs    do {
359fa225cbcSrjs
360fa225cbcSrjs	if (pI810->BR[13] & BR13_PITCH_SIGN_BIT) {
361fa225cbcSrjs	    src = (y1 + h - 1) * pScrn->displayWidth * pI810->cpp;
362fa225cbcSrjs	    dst = (y2 + h - 1) * pScrn->displayWidth * pI810->cpp;
363fa225cbcSrjs	} else {
364fa225cbcSrjs	    src = y1 * pScrn->displayWidth * pI810->cpp;
365fa225cbcSrjs	    dst = y2 * pScrn->displayWidth * pI810->cpp;
366fa225cbcSrjs	}
367fa225cbcSrjs
368fa225cbcSrjs	if (pI810->BR[13] & BR13_RIGHT_TO_LEFT) {
369fa225cbcSrjs	    src += (x1 + w - 1) * pI810->cpp + pI810->cpp - 1;
370fa225cbcSrjs	    dst += (x2 + w - 1) * pI810->cpp + pI810->cpp - 1;
371fa225cbcSrjs	} else {
372fa225cbcSrjs	    src += x1 * pI810->cpp;
373fa225cbcSrjs	    dst += x2 * pI810->cpp;
374fa225cbcSrjs	}
375fa225cbcSrjs
376fa225cbcSrjs
377fa225cbcSrjs	/* SRC_COPY_BLT, p169 */
378fa225cbcSrjs	{
379fa225cbcSrjs	    BEGIN_LP_RING(6);
380fa225cbcSrjs	    OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 );
381fa225cbcSrjs	    OUT_RING( pI810->BR[13]);
382fa225cbcSrjs
383fa225cbcSrjs	    OUT_RING( (h << 16) | (w * pI810->cpp));
384fa225cbcSrjs	    OUT_RING( pI810->bufferOffset + dst);
385fa225cbcSrjs
386fa225cbcSrjs	    OUT_RING( pI810->BR[13] & 0xFFFF);
387fa225cbcSrjs	    OUT_RING( pI810->bufferOffset + src);
388fa225cbcSrjs	    ADVANCE_LP_RING();
389fa225cbcSrjs	}
390fa225cbcSrjs	w_back -= w;
391fa225cbcSrjs	if (w_back <= 0)
392fa225cbcSrjs	    break;
393fa225cbcSrjs	x2 += w;
394fa225cbcSrjs	x1 += w;
395fa225cbcSrjs	if (w_back > I810_MWIDTH)
396fa225cbcSrjs	    w = I810_MWIDTH;
397fa225cbcSrjs	else
398fa225cbcSrjs	    w = w_back;
399fa225cbcSrjs    }  while (1);
400fa225cbcSrjs}
401fa225cbcSrjs
402fa225cbcSrjsstatic void
403fa225cbcSrjsI810SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
404fa225cbcSrjs			       int fg, int bg, int rop,
405fa225cbcSrjs			       unsigned int planemask)
406fa225cbcSrjs{
407fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
408fa225cbcSrjs
409fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
410fa225cbcSrjs      ErrorF("I810SetupFor8x8PatternColorExpand\n");
411fa225cbcSrjs
412fa225cbcSrjs   /* FULL_MONO_PAT_BLT, p176 */
413fa225cbcSrjs   pI810->BR[0] = (BR00_BITBLT_CLIENT | BR00_OP_MONO_PAT_BLT | 0x9);
414fa225cbcSrjs   pI810->BR[18] = bg;
415fa225cbcSrjs   pI810->BR[19] = fg;
416fa225cbcSrjs   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
417fa225cbcSrjs   pI810->BR[13] |= XAAGetPatternROP(rop) << 16;
418fa225cbcSrjs   if (bg == -1)
419fa225cbcSrjs      pI810->BR[13] |= BR13_MONO_PATN_TRANS;
420fa225cbcSrjs}
421fa225cbcSrjs
422fa225cbcSrjsstatic void
423fa225cbcSrjsI810SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
424fa225cbcSrjs				     int x, int y, int w, int h)
425fa225cbcSrjs{
426fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
427fa225cbcSrjs   int addr =
428fa225cbcSrjs	 pI810->bufferOffset + (y * pScrn->displayWidth + x) * pI810->cpp;
429fa225cbcSrjs
430fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
431fa225cbcSrjs      ErrorF("I810Subsequent8x8PatternColorExpand\n");
432fa225cbcSrjs
433fa225cbcSrjs   {
434fa225cbcSrjs      BEGIN_LP_RING(12);
435fa225cbcSrjs      OUT_RING(pI810->BR[0] | ((y << 5) & BR00_PAT_VERT_ALIGN));
436fa225cbcSrjs      OUT_RING(pI810->BR[13]);
437fa225cbcSrjs      OUT_RING((h << 16) | (w * pI810->cpp));
438fa225cbcSrjs      OUT_RING(addr);
439fa225cbcSrjs      OUT_RING(pI810->BR[13] & 0xFFFF);	/* src pitch */
440fa225cbcSrjs      OUT_RING(addr);			/* src addr */
441fa225cbcSrjs      OUT_RING(0);			/* transparency color */
442fa225cbcSrjs      OUT_RING(pI810->BR[18]);		/* bg */
443fa225cbcSrjs      OUT_RING(pI810->BR[19]);		/* fg */
444fa225cbcSrjs      OUT_RING(pattx);			/* pattern data */
445fa225cbcSrjs      OUT_RING(patty);
446fa225cbcSrjs      OUT_RING(0);
447fa225cbcSrjs      ADVANCE_LP_RING();
448fa225cbcSrjs   }
449fa225cbcSrjs}
450fa225cbcSrjs
451fa225cbcSrjsstatic void
452fa225cbcSrjsI810GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
453fa225cbcSrjs{
454fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
455fa225cbcSrjs   XAAInfoRecPtr infoPtr = pI810->AccelInfoRec;
456fa225cbcSrjs
457fa225cbcSrjs   if (pI810->nextColorExpandBuf == pI810->NumScanlineColorExpandBuffers)
458fa225cbcSrjs      I810Sync(pScrn);
459fa225cbcSrjs
460fa225cbcSrjs   infoPtr->ScanlineColorExpandBuffers[0] =
461fa225cbcSrjs	 pI810->ScanlineColorExpandBuffers[pI810->nextColorExpandBuf];
462fa225cbcSrjs
463fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
464fa225cbcSrjs      ErrorF("using color expand buffer %d\n", pI810->nextColorExpandBuf);
465fa225cbcSrjs
466fa225cbcSrjs   pI810->nextColorExpandBuf++;
467fa225cbcSrjs}
468fa225cbcSrjs
469fa225cbcSrjsstatic void
470fa225cbcSrjsI810SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
471fa225cbcSrjs					       int fg, int bg, int rop,
472fa225cbcSrjs					       unsigned int planemask)
473fa225cbcSrjs{
474fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
475fa225cbcSrjs
476fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
477fa225cbcSrjs      ErrorF("I810SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
478fa225cbcSrjs	     fg, bg, rop, planemask);
479fa225cbcSrjs
480fa225cbcSrjs   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
481fa225cbcSrjs   pI810->BR[13] |= XAAGetCopyROP(rop) << 16;
482fa225cbcSrjs   pI810->BR[13] |= (1 << 27);
483fa225cbcSrjs   if (bg == -1)
484fa225cbcSrjs      pI810->BR[13] |= BR13_MONO_TRANSPCY;
485fa225cbcSrjs
486fa225cbcSrjs   pI810->BR[18] = bg;
487fa225cbcSrjs   pI810->BR[19] = fg;
488fa225cbcSrjs
489fa225cbcSrjs   I810GetNextScanlineColorExpandBuffer(pScrn);
490fa225cbcSrjs}
491fa225cbcSrjs
492fa225cbcSrjsstatic void
493fa225cbcSrjsI810SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
494fa225cbcSrjs						 int x, int y,
495fa225cbcSrjs						 int w, int h, int skipleft)
496fa225cbcSrjs{
497fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
498fa225cbcSrjs
499fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
500fa225cbcSrjs      ErrorF("I810SubsequentScanlineCPUToScreenColorExpandFill "
501fa225cbcSrjs	     "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
502fa225cbcSrjs
503fa225cbcSrjs   pI810->BR[0] = BR00_BITBLT_CLIENT | BR00_OP_MONO_SRC_COPY_BLT | 0x06;
504fa225cbcSrjs   pI810->BR[9] = (pI810->bufferOffset +
505fa225cbcSrjs		   (y * pScrn->displayWidth + x) * pI810->cpp);
506fa225cbcSrjs   pI810->BR[14] = ((1 << 16) | (w * pI810->cpp));
507fa225cbcSrjs   pI810->BR[11] = ((w + 31) / 32) - 1;
508fa225cbcSrjs}
509fa225cbcSrjs
510fa225cbcSrjsstatic void
511fa225cbcSrjsI810SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
512fa225cbcSrjs{
513fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
514fa225cbcSrjs
515fa225cbcSrjs   pI810->BR[12] = (pI810->AccelInfoRec->ScanlineColorExpandBuffers[0] -
516fa225cbcSrjs		    pI810->FbBase);
517fa225cbcSrjs
518fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
519fa225cbcSrjs      ErrorF("I810SubsequentColorExpandScanline %d (addr %x)\n",
520fa225cbcSrjs	     bufno, pI810->BR[12]);
521fa225cbcSrjs
522fa225cbcSrjs   {
523fa225cbcSrjs      BEGIN_LP_RING(8);
524fa225cbcSrjs      OUT_RING(pI810->BR[0]);
525fa225cbcSrjs      OUT_RING(pI810->BR[13]);
526fa225cbcSrjs      OUT_RING(pI810->BR[14]);
527fa225cbcSrjs      OUT_RING(pI810->BR[9]);
528fa225cbcSrjs      OUT_RING(pI810->BR[11]);
529fa225cbcSrjs      OUT_RING(pI810->BR[12]);		/* srcaddr */
530fa225cbcSrjs      OUT_RING(pI810->BR[18]);
531fa225cbcSrjs      OUT_RING(pI810->BR[19]);
532fa225cbcSrjs      ADVANCE_LP_RING();
533fa225cbcSrjs   }
534fa225cbcSrjs
535fa225cbcSrjs   /* Advance to next scanline.
536fa225cbcSrjs    */
537fa225cbcSrjs   pI810->BR[9] += pScrn->displayWidth * pI810->cpp;
538fa225cbcSrjs   I810GetNextScanlineColorExpandBuffer(pScrn);
539fa225cbcSrjs}
540fa225cbcSrjs
541fa225cbcSrjsvoid
542fa225cbcSrjsI810EmitFlush(ScrnInfoPtr pScrn)
543fa225cbcSrjs{
544fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
545fa225cbcSrjs
546fa225cbcSrjs   BEGIN_LP_RING(2);
547fa225cbcSrjs   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
548fa225cbcSrjs   OUT_RING(0);
549fa225cbcSrjs   ADVANCE_LP_RING();
550fa225cbcSrjs}
551fa225cbcSrjs
552fa225cbcSrjsvoid
553fa225cbcSrjsI810SelectBuffer(ScrnInfoPtr pScrn, int buffer)
554fa225cbcSrjs{
555fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
556fa225cbcSrjs
557fa225cbcSrjs   switch (buffer) {
558fa225cbcSrjs   case I810_SELECT_BACK:
559fa225cbcSrjs      pI810->bufferOffset = pI810->BackBuffer.Start;
560fa225cbcSrjs      break;
561fa225cbcSrjs   case I810_SELECT_DEPTH:
562fa225cbcSrjs      pI810->bufferOffset = pI810->DepthBuffer.Start;
563fa225cbcSrjs      break;
564fa225cbcSrjs   default:
565fa225cbcSrjs   case I810_SELECT_FRONT:
566fa225cbcSrjs      pI810->bufferOffset = pI810->FrontBuffer.Start;
567fa225cbcSrjs      break;
568fa225cbcSrjs   }
569fa225cbcSrjs
570fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
571fa225cbcSrjs      ErrorF("I810SelectBuffer %d --> offset %x\n",
572fa225cbcSrjs	     buffer, pI810->bufferOffset);
573fa225cbcSrjs}
574fa225cbcSrjs
575fa225cbcSrjsvoid
576fa225cbcSrjsI810RefreshRing(ScrnInfoPtr pScrn)
577fa225cbcSrjs{
578fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
579fa225cbcSrjs
580fa225cbcSrjs   pI810->LpRing->head = INREG(LP_RING + RING_HEAD) & HEAD_ADDR;
581fa225cbcSrjs   pI810->LpRing->tail = INREG(LP_RING + RING_TAIL);
582fa225cbcSrjs   pI810->LpRing->space = pI810->LpRing->head - (pI810->LpRing->tail + 8);
583fa225cbcSrjs   if (pI810->LpRing->space < 0)
584fa225cbcSrjs      pI810->LpRing->space += pI810->LpRing->mem.Size;
585fa225cbcSrjs
586fa225cbcSrjs   if (pI810->AccelInfoRec)
587fa225cbcSrjs      pI810->AccelInfoRec->NeedToSync = TRUE;
588fa225cbcSrjs}
589fa225cbcSrjs
590fa225cbcSrjs/* Emit on gaining VT?
591fa225cbcSrjs */
592fa225cbcSrjsvoid
593fa225cbcSrjsI810EmitInvarientState(ScrnInfoPtr pScrn)
594fa225cbcSrjs{
595fa225cbcSrjs   I810Ptr pI810 = I810PTR(pScrn);
596fa225cbcSrjs
597fa225cbcSrjs   BEGIN_LP_RING(10);
598fa225cbcSrjs
599fa225cbcSrjs   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
600fa225cbcSrjs   OUT_RING(GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0);
601fa225cbcSrjs   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
602fa225cbcSrjs   OUT_RING(0);
603fa225cbcSrjs
604fa225cbcSrjs   OUT_RING(GFX_OP_COLOR_CHROMA_KEY);
605fa225cbcSrjs   OUT_RING(CC1_UPDATE_KILL_WRITE |
606fa225cbcSrjs	    CC1_DISABLE_KILL_WRITE |
607fa225cbcSrjs	    CC1_UPDATE_COLOR_IDX |
608fa225cbcSrjs	    CC1_UPDATE_CHROMA_LOW | CC1_UPDATE_CHROMA_HI | 0);
609fa225cbcSrjs   OUT_RING(0);
610fa225cbcSrjs   OUT_RING(0);
611fa225cbcSrjs
612fa225cbcSrjs/*     OUT_RING( CMD_OP_Z_BUFFER_INFO ); */
613fa225cbcSrjs/*     OUT_RING( pI810->DepthBuffer.Start | pI810->auxPitchBits); */
614fa225cbcSrjs
615fa225cbcSrjs   ADVANCE_LP_RING();
616fa225cbcSrjs}
617fa225cbcSrjs
618