i740_accel.c revision 301ea0f4
1301ea0f4Smrg
2301ea0f4Smrg/**************************************************************************
3301ea0f4Smrg
4301ea0f4SmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5301ea0f4SmrgAll Rights Reserved.
6301ea0f4Smrg
7301ea0f4SmrgPermission is hereby granted, free of charge, to any person obtaining a
8301ea0f4Smrgcopy of this software and associated documentation files (the
9301ea0f4Smrg"Software"), to deal in the Software without restriction, including
10301ea0f4Smrgwithout limitation the rights to use, copy, modify, merge, publish,
11301ea0f4Smrgdistribute, sub license, and/or sell copies of the Software, and to
12301ea0f4Smrgpermit persons to whom the Software is furnished to do so, subject to
13301ea0f4Smrgthe following conditions:
14301ea0f4Smrg
15301ea0f4SmrgThe above copyright notice and this permission notice (including the
16301ea0f4Smrgnext paragraph) shall be included in all copies or substantial portions
17301ea0f4Smrgof the Software.
18301ea0f4Smrg
19301ea0f4SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20301ea0f4SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21301ea0f4SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22301ea0f4SmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
23301ea0f4SmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24301ea0f4SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25301ea0f4SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26301ea0f4Smrg
27301ea0f4Smrg**************************************************************************/
28301ea0f4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_accel.c,v 1.6 2002/01/25 21:56:02 tsi Exp $ */
29301ea0f4Smrg
30301ea0f4Smrg/*
31301ea0f4Smrg * Authors:
32301ea0f4Smrg *   Daryll Strauss <daryll@precisioninsight.com>
33301ea0f4Smrg *
34301ea0f4Smrg */
35301ea0f4Smrg
36301ea0f4Smrg#ifdef HAVE_CONFIG_H
37301ea0f4Smrg#include "config.h"
38301ea0f4Smrg#endif
39301ea0f4Smrg
40301ea0f4Smrg#include "xf86.h"
41301ea0f4Smrg#include "xf86_OSproc.h"
42301ea0f4Smrg
43301ea0f4Smrg#include "compiler.h"
44301ea0f4Smrg
45301ea0f4Smrg#include "xf86Pci.h"
46301ea0f4Smrg#include "xf86PciInfo.h"
47301ea0f4Smrg
48301ea0f4Smrg#include "xaa.h"
49301ea0f4Smrg#include "vgaHW.h"
50301ea0f4Smrg
51301ea0f4Smrg#include "xf86xv.h"
52301ea0f4Smrg#include "i740.h"
53301ea0f4Smrg
54301ea0f4Smrgstatic unsigned int i740Rop[16] = {
55301ea0f4Smrg    0x00, /* GXclear      */
56301ea0f4Smrg    0x88, /* GXand        */
57301ea0f4Smrg    0x44, /* GXandReverse */
58301ea0f4Smrg    0xCC, /* GXcopy       */
59301ea0f4Smrg    0x22, /* GXandInvert  */
60301ea0f4Smrg    0xAA, /* GXnoop       */
61301ea0f4Smrg    0x66, /* GXxor        */
62301ea0f4Smrg    0xEE, /* GXor         */
63301ea0f4Smrg    0x11, /* GXnor        */
64301ea0f4Smrg    0x99, /* GXequiv      */
65301ea0f4Smrg    0x55, /* GXinvert     */
66301ea0f4Smrg    0xDD, /* GXorReverse  */
67301ea0f4Smrg    0x33, /* GXcopyInvert */
68301ea0f4Smrg    0xBB, /* GXorInverted */
69301ea0f4Smrg    0x77, /* GXnand       */
70301ea0f4Smrg    0xFF  /* GXset        */
71301ea0f4Smrg};
72301ea0f4Smrg
73301ea0f4Smrgstatic unsigned int i740PatternRop[16] = {
74301ea0f4Smrg    0x00, /* GXclear      */
75301ea0f4Smrg    0xA0, /* GXand        */
76301ea0f4Smrg    0x50, /* GXandReverse */
77301ea0f4Smrg    0xF0, /* GXcopy       */
78301ea0f4Smrg    0x0A, /* GXandInvert  */
79301ea0f4Smrg    0xAA, /* GXnoop       */
80301ea0f4Smrg    0x5A, /* GXxor        */
81301ea0f4Smrg    0xFA, /* GXor         */
82301ea0f4Smrg    0x05, /* GXnor        */
83301ea0f4Smrg    0xA5, /* GXequiv      */
84301ea0f4Smrg    0x55, /* GXinvert     */
85301ea0f4Smrg    0xF5, /* GXorReverse  */
86301ea0f4Smrg    0x0F, /* GXcopyInvert */
87301ea0f4Smrg    0xAF, /* GXorInverted */
88301ea0f4Smrg    0x5F, /* GXnand       */
89301ea0f4Smrg    0xFF  /* GXset        */
90301ea0f4Smrg};
91301ea0f4Smrg
92301ea0f4Smrgstatic void I740SyncPIO(ScrnInfoPtr pScrn);
93301ea0f4Smrgstatic void I740SyncMMIO(ScrnInfoPtr pScrn);
94301ea0f4Smrgstatic void I740SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
95301ea0f4Smrg				      unsigned int planemask);
96301ea0f4Smrgstatic void I740SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
97301ea0f4Smrg					int w, int h);
98301ea0f4Smrgstatic void I740SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
99301ea0f4Smrg					   int ydir, int rop,
100301ea0f4Smrg					   unsigned int planemask,
101301ea0f4Smrg					   int transparency_color);
102301ea0f4Smrgstatic void I740SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
103301ea0f4Smrg					     int x2, int y2, int w, int h);
104301ea0f4Smrgstatic void I740SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
105301ea0f4Smrg					   int pattx, int patty,
106301ea0f4Smrg					   int fg, int bg, int rop,
107301ea0f4Smrg					   unsigned int planemask);
108301ea0f4Smrgstatic void I740SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
109301ea0f4Smrg						  int pattx, int patty,
110301ea0f4Smrg						  int x, int y, int w, int h);
111301ea0f4Smrg#if 0
112301ea0f4Smrgstatic void I740SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
113301ea0f4Smrg						   int bg, int fg, int rop,
114301ea0f4Smrg						   unsigned int planemask);
115301ea0f4Smrgstatic void I740SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
116301ea0f4Smrg						     int x, int y, int w, int h,
117301ea0f4Smrg						     int skipleft);
118301ea0f4Smrg#endif
119301ea0f4Smrg/*
120301ea0f4Smrg * The following function sets up the supported acceleration. Call it
121301ea0f4Smrg * from the FbInit() function in the SVGA driver, or before ScreenInit
122301ea0f4Smrg * in a monolithic server.
123301ea0f4Smrg */
124301ea0f4SmrgBool
125301ea0f4SmrgI740AccelInit(ScreenPtr pScreen) {
126301ea0f4Smrg  XAAInfoRecPtr infoPtr;
127301ea0f4Smrg  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
128301ea0f4Smrg  I740Ptr pI740 = I740PTR(pScrn);
129301ea0f4Smrg
130301ea0f4Smrg  pI740->AccelInfoRec = infoPtr = XAACreateInfoRec();
131301ea0f4Smrg  if (!infoPtr) return FALSE;
132301ea0f4Smrg
133301ea0f4Smrg  if (pScrn->bitsPerPixel == 32) {
134301ea0f4Smrg    infoPtr->Flags = 0; /* Disables all acceleration */
135301ea0f4Smrg    return TRUE;;
136301ea0f4Smrg  }
137301ea0f4Smrg
138301ea0f4Smrg  infoPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
139301ea0f4Smrg
140301ea0f4Smrg  /* Sync */
141301ea0f4Smrg  if (pI740->usePIO)
142301ea0f4Smrg    infoPtr->Sync = I740SyncPIO;
143301ea0f4Smrg  else
144301ea0f4Smrg    infoPtr->Sync = I740SyncMMIO;
145301ea0f4Smrg
146301ea0f4Smrg  infoPtr->CachePixelGranularity=8/pI740->cpp;
147301ea0f4Smrg
148301ea0f4Smrg  /* Solid filled rectangles */
149301ea0f4Smrg  infoPtr->SolidFillFlags = NO_PLANEMASK;
150301ea0f4Smrg  infoPtr->SetupForSolidFill = I740SetupForSolidFill;
151301ea0f4Smrg  infoPtr->SubsequentSolidFillRect = I740SubsequentSolidFillRect;
152301ea0f4Smrg
153301ea0f4Smrg  /* Screen to screen copy */
154301ea0f4Smrg  infoPtr->ScreenToScreenCopyFlags = (NO_PLANEMASK | NO_TRANSPARENCY);
155301ea0f4Smrg  infoPtr->SetupForScreenToScreenCopy = I740SetupForScreenToScreenCopy;
156301ea0f4Smrg  infoPtr->SubsequentScreenToScreenCopy = I740SubsequentScreenToScreenCopy;
157301ea0f4Smrg
158301ea0f4Smrg  /* 8x8 pattern fills */
159301ea0f4Smrg  infoPtr->SetupForMono8x8PatternFill = I740SetupForMono8x8PatternFill;
160301ea0f4Smrg  infoPtr->SubsequentMono8x8PatternFillRect = I740SubsequentMono8x8PatternFillRect;
161301ea0f4Smrg  infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | HARDWARE_PATTERN_SCREEN_ORIGIN |
162301ea0f4Smrg    BIT_ORDER_IN_BYTE_MSBFIRST;
163301ea0f4Smrg
164301ea0f4Smrg  /* CPU to screen color expansion */
165301ea0f4Smrg  /* Currently XAA is limited to only DWORD padding.  The 3.3 driver
166301ea0f4Smrg   * uses NO_PAD scanlines b/c of problems with using the chip in
167301ea0f4Smrg   * DWORD mode. Once other padding modes are available in XAA this
168301ea0f4Smrg   * Code can be turned back on.
169301ea0f4Smrg   */
170301ea0f4Smrg#if 0
171301ea0f4Smrg#ifndef ALLOW_PCI_COLOR_EXP
172301ea0f4Smrg  if (pI740->Chipset != PCI_CHIP_I740_PCI) {
173301ea0f4Smrg#endif
174301ea0f4Smrg    /*
175301ea0f4Smrg     * Currently, we are not properly able to read the bitblt engine
176301ea0f4Smrg     * busy bit on the PCI i740 card.  When we are able to do so, we
177301ea0f4Smrg     * can re-enable color expansion.
178301ea0f4Smrg     */
179301ea0f4Smrg    infoPtr->CPUToScreenColorExpandFillFlags =
180301ea0f4Smrg       					  NO_PLANEMASK |
181301ea0f4Smrg#ifdef USE_DWORD_COLOR_EXP
182301ea0f4Smrg					  SCANLINE_PAD_DWORD |
183301ea0f4Smrg#endif
184301ea0f4Smrg					  CPU_TRANSFER_PAD_QWORD |
185301ea0f4Smrg					  SYNC_AFTER_COLOR_EXPAND |
186301ea0f4Smrg					  BIT_ORDER_IN_BYTE_MSBFIRST;
187301ea0f4Smrg    infoPtr->ColorExpandBase = (unsigned char *)(pI740->MMIOBase + BLTDATA);
188301ea0f4Smrg    infoPtr->ColorExpandRange = 0x10000;
189301ea0f4Smrg    infoPtr->SetupForCPUToScreenColorExpandFill = I740SetupForCPUToScreenColorExpandFill;
190301ea0f4Smrg    infoPtr->SubsequentCPUToScreenColorExpandFill = I740SubsequentCPUToScreenColorExpandFill;
191301ea0f4Smrg#ifndef ALLOW_PCI_COLOR_EXP
192301ea0f4Smrg    }
193301ea0f4Smrg#endif
194301ea0f4Smrg#endif
195301ea0f4Smrg  return XAAInit(pScreen, infoPtr);
196301ea0f4Smrg}
197301ea0f4Smrg
198301ea0f4Smrgstatic void
199301ea0f4SmrgI740SyncPIO(ScrnInfoPtr pScrn) {
200301ea0f4Smrg  WAIT_ENGINE_IDLE_PIO();
201301ea0f4Smrg}
202301ea0f4Smrg
203301ea0f4Smrgstatic void
204301ea0f4SmrgI740SyncMMIO(ScrnInfoPtr pScrn) {
205301ea0f4Smrg  I740Ptr pI740;
206301ea0f4Smrg
207301ea0f4Smrg  pI740 = I740PTR(pScrn);
208301ea0f4Smrg  WAIT_ENGINE_IDLE_MMIO();
209301ea0f4Smrg}
210301ea0f4Smrg
211301ea0f4Smrgstatic void
212301ea0f4SmrgI740SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
213301ea0f4Smrg		      unsigned int planemask) {
214301ea0f4Smrg  I740Ptr pI740;
215301ea0f4Smrg
216301ea0f4Smrg  pI740 = I740PTR(pScrn);
217301ea0f4Smrg
218301ea0f4Smrg  pI740->bltcmd.BR00 = ((pScrn->displayWidth * pI740->cpp) << 16) |
219301ea0f4Smrg    (pScrn->displayWidth * pI740->cpp);
220301ea0f4Smrg  pI740->bltcmd.BR01 = color;
221301ea0f4Smrg  pI740->bltcmd.BR04 = SOLID_PAT_SELECT | PAT_IS_MONO | i740PatternRop[rop];
222301ea0f4Smrg}
223301ea0f4Smrg
224301ea0f4Smrgstatic void
225301ea0f4SmrgI740SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) {
226301ea0f4Smrg  I740Ptr pI740;
227301ea0f4Smrg
228301ea0f4Smrg  pI740 = I740PTR(pScrn);
229301ea0f4Smrg  WAIT_LP_FIFO(12);
230301ea0f4Smrg  OUTREG(LP_FIFO, 0x6000000A);
231301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR00);
232301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR01);
233301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
234301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
235301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR04);
236301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
237301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
238301ea0f4Smrg  OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp);
239301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
240301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
241301ea0f4Smrg  OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
242301ea0f4Smrg}
243301ea0f4Smrg
244301ea0f4Smrgstatic void
245301ea0f4SmrgI740SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
246301ea0f4Smrg			       unsigned int planemask, int transparency_color)
247301ea0f4Smrg{
248301ea0f4Smrg  I740Ptr pI740;
249301ea0f4Smrg
250301ea0f4Smrg  pI740 = I740PTR(pScrn);
251301ea0f4Smrg  pI740->bltcmd.BR00 = (((pScrn->displayWidth * pI740->cpp) << 16) |
252301ea0f4Smrg			(pScrn->displayWidth * pI740->cpp));
253301ea0f4Smrg
254301ea0f4Smrg  pI740->bltcmd.BR04 = SRC_IS_IN_COLOR | SRC_USE_SRC_ADDR | i740Rop[rop];
255301ea0f4Smrg  if (xdir == -1)
256301ea0f4Smrg    pI740->bltcmd.BR04 |= BLT_RIGHT_TO_LEFT;
257301ea0f4Smrg  else
258301ea0f4Smrg    pI740->bltcmd.BR04 |= BLT_LEFT_TO_RIGHT;
259301ea0f4Smrg
260301ea0f4Smrg  if (ydir == -1)
261301ea0f4Smrg    pI740->bltcmd.BR04 |= BLT_BOT_TO_TOP;
262301ea0f4Smrg  else
263301ea0f4Smrg    pI740->bltcmd.BR04 |= BLT_TOP_TO_BOT;
264301ea0f4Smrg
265301ea0f4Smrg    pI740->bltcmd.BR01 = 0x00000000;
266301ea0f4Smrg
267301ea0f4Smrg}
268301ea0f4Smrg
269301ea0f4Smrgstatic void
270301ea0f4SmrgI740SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
271301ea0f4Smrg				 int x2, int y2, int w, int h) {
272301ea0f4Smrg  I740Ptr pI740;
273301ea0f4Smrg
274301ea0f4Smrg  pI740 = I740PTR(pScrn);
275301ea0f4Smrg  if (pI740->bltcmd.BR04 & BLT_BOT_TO_TOP) {
276301ea0f4Smrg    pI740->bltcmd.BR06 = (y1 + h - 1) *
277301ea0f4Smrg      pScrn->displayWidth * pI740->cpp;
278301ea0f4Smrg    pI740->bltcmd.BR07 = (y2 + h - 1) *
279301ea0f4Smrg      pScrn->displayWidth * pI740->cpp;
280301ea0f4Smrg    } else {
281301ea0f4Smrg      pI740->bltcmd.BR06 = y1 * pScrn->displayWidth * pI740->cpp;
282301ea0f4Smrg      pI740->bltcmd.BR07 = y2 * pScrn->displayWidth * pI740->cpp;
283301ea0f4Smrg    }
284301ea0f4Smrg
285301ea0f4Smrg  if (pI740->bltcmd.BR04 & BLT_RIGHT_TO_LEFT) {
286301ea0f4Smrg    pI740->bltcmd.BR06 += (x1 + w - 1) * pI740->cpp + pI740->cpp - 1;
287301ea0f4Smrg    pI740->bltcmd.BR07 += (x2 + w - 1) * pI740->cpp + pI740->cpp - 1;
288301ea0f4Smrg  } else {
289301ea0f4Smrg    pI740->bltcmd.BR06 += x1 * pI740->cpp;
290301ea0f4Smrg    pI740->bltcmd.BR07 += x2 * pI740->cpp;
291301ea0f4Smrg  }
292301ea0f4Smrg
293301ea0f4Smrg  WAIT_LP_FIFO(12);
294301ea0f4Smrg  OUTREG(LP_FIFO, 0x6000000A);
295301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR00);
296301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR01);
297301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
298301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
299301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR04);
300301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
301301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR06);
302301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR07);
303301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
304301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
305301ea0f4Smrg  OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
306301ea0f4Smrg}
307301ea0f4Smrg
308301ea0f4Smrgstatic void
309301ea0f4SmrgI740SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
310301ea0f4Smrg				int fg, int bg, int rop,
311301ea0f4Smrg				unsigned int planemask) {
312301ea0f4Smrg  I740Ptr pI740;
313301ea0f4Smrg
314301ea0f4Smrg  pI740 = I740PTR(pScrn);
315301ea0f4Smrg  pI740->bltcmd.BR00 = ((pScrn->displayWidth * pI740->cpp) << 16) |
316301ea0f4Smrg			(pScrn->displayWidth * pI740->cpp);
317301ea0f4Smrg
318301ea0f4Smrg  pI740->bltcmd.BR01 = bg;
319301ea0f4Smrg  pI740->bltcmd.BR02 = fg;
320301ea0f4Smrg
321301ea0f4Smrg  pI740->bltcmd.BR04 = PAT_IS_MONO | i740PatternRop[rop];
322301ea0f4Smrg  if (bg == -1) pI740->bltcmd.BR04 |= MONO_PAT_TRANSP;
323301ea0f4Smrg
324301ea0f4Smrg  pI740->bltcmd.BR05 = (pattx + patty * pScrn->displayWidth) * pI740->cpp;
325301ea0f4Smrg}
326301ea0f4Smrg
327301ea0f4Smrgstatic void
328301ea0f4SmrgI740SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
329301ea0f4Smrg				     int x, int y, int w, int h) {
330301ea0f4Smrg  I740Ptr pI740;
331301ea0f4Smrg
332301ea0f4Smrg  pI740 = I740PTR(pScrn);
333301ea0f4Smrg  WAIT_LP_FIFO(12);
334301ea0f4Smrg  OUTREG(LP_FIFO, 0x6000000A);
335301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR00);
336301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR01);
337301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR02);
338301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
339301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR04 | ((y<<20) & PAT_VERT_ALIGN));
340301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR05);
341301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
342301ea0f4Smrg  OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp);
343301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
344301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
345301ea0f4Smrg  OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
346301ea0f4Smrg}
347301ea0f4Smrg#if 0
348301ea0f4Smrgstatic void
349301ea0f4SmrgI740SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int bg, int fg,
350301ea0f4Smrg				       int rop, unsigned int planemask) {
351301ea0f4Smrg  I740Ptr pI740;
352301ea0f4Smrg
353301ea0f4Smrg  pI740 = I740PTR(pScrn);
354301ea0f4Smrg  pI740->bltcmd.BR00 = (pScrn->displayWidth * pI740->cpp) << 16;
355301ea0f4Smrg  pI740->bltcmd.BR01 = bg;
356301ea0f4Smrg  pI740->bltcmd.BR02 = fg;
357301ea0f4Smrg#ifdef USE_DWORD_COLOR_EXP
358301ea0f4Smrg  pI740->bltcmd.BR03 = MONO_DWORD_ALIGN | MONO_USE_COLEXP;
359301ea0f4Smrg#else
360301ea0f4Smrg  pI740->bltcmd.BR03 = MONO_BIT_ALIGN | MONO_USE_COLEXP;
361301ea0f4Smrg#endif
362301ea0f4Smrg  pI740->bltcmd.BR04 = SRC_IS_MONO | SRC_USE_BLTDATA | i740Rop[rop];
363301ea0f4Smrg  if (bg == -1) pI740->bltcmd.BR04 |= MONO_SRC_TRANSP;
364301ea0f4Smrg}
365301ea0f4Smrg
366301ea0f4Smrgstatic void
367301ea0f4SmrgI740SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y,
368301ea0f4Smrg				     int w, int h, int skipleft) {
369301ea0f4Smrg  I740Ptr pI740;
370301ea0f4Smrg
371301ea0f4Smrg  pI740 = I740PTR(pScrn);
372301ea0f4Smrg  pI740->AccelInfoRec->Sync(pScrn);
373301ea0f4Smrg  OUTREG(LP_FIFO, 0x6000000A);
374301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR00);
375301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR01);
376301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR02);
377301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR03 | (skipleft & MONO_SRC_LEFT_CLIP));
378301ea0f4Smrg  OUTREG(LP_FIFO, pI740->bltcmd.BR04);
379301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
380301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
381301ea0f4Smrg  OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp);
382301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
383301ea0f4Smrg  OUTREG(LP_FIFO, 0x00000000);
384301ea0f4Smrg#ifdef USE_DWORD_COLOR_EXP
385301ea0f4Smrg  /*
386301ea0f4Smrg   * This extra wait is necessary to keep the bitblt engine from
387301ea0f4Smrg   * locking up, but I am not sure why it is needed.  If we take it
388301ea0f4Smrg   * out, "x11perf -copyplane10" will lock the bitblt engine.  When
389301ea0f4Smrg   * the bitblt engine is locked, it is waiting for mono data to be
390301ea0f4Smrg   * written to the BLTDATA region, which seems to imply that some of
391301ea0f4Smrg   * the data that was written was lost.  This might be fixed by
392301ea0f4Smrg   * BLT_SKEW changes.  Update: The engine still locks up with this
393301ea0f4Smrg   * extra wait.  More investigation (and time) is needed.
394301ea0f4Smrg   */
395301ea0f4Smrg  WAIT_BLT_IDLE();
396301ea0f4Smrg#endif
397301ea0f4Smrg  OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
398301ea0f4Smrg}
399301ea0f4Smrg#endif
400