ffb_accel.c revision 7a5333bc
1/*
2 * Acceleration for the Creator and Creator3D framebuffer.
3 *
4 * Copyright (C) 1998,1999,2000 Jakub Jelinek (jakub@redhat.com)
5 * Copyright (C) 1998 Michal Rehacek (majkl@iname.com)
6 * Copyright (C) 1999,2000 David S. Miller (davem@redhat.com)
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * JAKUB JELINEK, MICHAL REHACEK, OR DAVID MILLER BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include	"scrnintstr.h"
33#include	"pixmapstr.h"
34#include	"regionstr.h"
35#include	"mistruct.h"
36#include	"miline.h"
37#include	"fb.h"
38
39#include	"ffb.h"
40#include	"ffb_fifo.h"
41#include	"ffb_rcache.h"
42#include	"ffb_loops.h"
43#include	"ffb_regs.h"
44
45#ifdef HAVE_XAA_H
46/* VISmoveImage.s */
47extern void VISmoveImageRL(unsigned char *src, unsigned char *dst, long w, long h, long skind, long dkind);
48extern void VISmoveImageLR(unsigned char *src, unsigned char *dst, long w, long h, long skind, long dkind);
49
50/* Indexed by ffb resolution enum. */
51struct fastfill_parms ffb_fastfill_parms[] = {
52	/* fsmall, psmall,  ffh,  ffw,  pfh,  pfw */
53	{  0x00c0, 0x1400, 0x04, 0x08, 0x10, 0x50 },	/* Standard: 1280 x 1024 */
54	{  0x0140, 0x2800, 0x04, 0x10, 0x10, 0xa0 },	/* High:     1920 x 1360 */
55	{  0x0080, 0x0a00, 0x02, 0x08, 0x08, 0x50 },	/* Stereo:   960  x 580  */
56/*XXX*/	{  0x00c0, 0x0a00, 0x04, 0x08, 0x08, 0x50 },	/* Portrait: 1280 x 2048 XXX */
57};
58
59void
60CreatorVtChange (ScreenPtr pScreen, int enter)
61{
62	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
63	FFBPtr pFfb = GET_FFB_FROM_SCRN (pScrn);
64	ffb_fbcPtr ffb = pFfb->regs;
65
66	pFfb->rp_active = 1;
67	FFBWait(pFfb, ffb);
68	pFfb->fifo_cache = -1;
69	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED |
70			   FFB_FBC_RB_A | FFB_FBC_SB_BOTH| FFB_FBC_XE_OFF |
71			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_MASK);
72	pFfb->ppc_cache = (FFB_PPC_FW_DISABLE |
73			   FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST |
74			   FFB_PPC_XS_CONST | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST|
75			   FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE);
76
77	pFfb->pmask_cache = ~0;
78	pFfb->rop_cache = FFB_ROP_EDIT_BIT;
79	pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
80	pFfb->fg_cache = pFfb->bg_cache = 0;
81	pFfb->fontw_cache = 32;
82	pFfb->fontinc_cache = (1 << 16) | 0;
83	pFfb->laststipple = NULL;
84	FFBFifo(pFfb, 9);
85	ffb->fbc = pFfb->fbc_cache;
86	ffb->ppc = pFfb->ppc_cache;
87	ffb->pmask = pFfb->pmask_cache;
88	ffb->rop = pFfb->rop_cache;
89	ffb->drawop = pFfb->drawop_cache;
90	ffb->fg = pFfb->fg_cache;
91	ffb->bg = pFfb->bg_cache;
92	ffb->fontw = pFfb->fontw_cache;
93	ffb->fontinc = pFfb->fontinc_cache;
94	pFfb->rp_active = 1;
95	FFBWait(pFfb, ffb);
96
97	/* Fixup the FBC/PPC caches to deal with actually using
98	 * a WID for every ROP.
99	 */
100	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED |
101			   FFB_FBC_RB_A | FFB_FBC_SB_BOTH | FFB_FBC_XE_ON |
102			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF | FFB_FBC_RGBE_ON);
103	pFfb->ppc_cache &= ~FFB_PPC_XS_MASK;
104	pFfb->ppc_cache |= FFB_PPC_XS_WID;
105	pFfb->wid_cache = (enter ? pFfb->xaa_wid : 0xff);
106	FFBFifo(pFfb, 11);
107	ffb->fbc = pFfb->fbc_cache;
108	ffb->ppc = FFB_PPC_XS_WID;
109	ffb->wid = pFfb->wid_cache;
110	ffb->xpmask = 0xff;
111	ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
112	ffb->cmp = 0x80808080;
113	ffb->matchab = 0x80808080;
114	ffb->magnab = 0x80808080;
115	ffb->blendc = (FFB_BLENDC_FORCE_ONE |
116		       FFB_BLENDC_DF_ONE_M_A |
117		       FFB_BLENDC_SF_A);
118	ffb->blendc1 = 0;
119	ffb->blendc2 = 0;
120	pFfb->rp_active = 1;
121	FFBWait(pFfb, ffb);
122
123	if (enter) {
124		pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
125
126		FFBFifo(pFfb, 5);
127		ffb->drawop = pFfb->drawop_cache;
128		FFB_WRITE64(&ffb->by, 0, 0);
129		FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width);
130		pFfb->rp_active = 1;
131		FFBWait(pFfb, ffb);
132
133		SET_SYNC_FLAG(pFfb->pXAAInfo);
134	}
135}
136
137#ifdef DEBUG_FFB
138FILE *FDEBUG_FD = NULL;
139#endif
140
141#define FFB_ATTR_SFB_VAR_XAA(__fpriv, __pmask, __alu) \
142do {   unsigned int __ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_VAR | FFB_PPC_XS_WID; \
143       unsigned int __ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; \
144       unsigned int __rop = (FFB_ROP_EDIT_BIT | (__alu))|(FFB_ROP_NEW<<8); \
145       unsigned int __fbc = (__fpriv)->xaa_fbc; \
146       unsigned int __wid = (__fpriv)->xaa_wid; \
147       if (((__fpriv)->ppc_cache & __ppc_mask) != __ppc || \
148           (__fpriv)->fbc_cache != __fbc || \
149           (__fpriv)->wid_cache != __wid || \
150           (__fpriv)->rop_cache != __rop || \
151           (__fpriv)->pmask_cache != (__pmask)) \
152               __FFB_Attr_SFB_VAR(__fpriv, __ppc, __ppc_mask, __fbc, \
153                                  __wid, __rop, (__pmask)); \
154} while(0)
155
156#define FFB_ATTR_VSCROLL_XAA(__fpriv, __pmask) \
157do {    unsigned int __ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_VAR | FFB_PPC_XS_WID; \
158        unsigned int __ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK; \
159        unsigned int __rop = (FFB_ROP_OLD | (FFB_ROP_OLD << 8)); \
160        unsigned int __fbc = (__fpriv)->xaa_fbc; \
161        (__fpriv)->ppc_cache &= ~__ppc_mask; \
162        (__fpriv)->ppc_cache |= __ppc; \
163        (__fpriv)->regs->ppc = __ppc; \
164        if ((__fpriv)->fbc_cache != __fbc || \
165            (__fpriv)->rop_cache != __rop || \
166            (__fpriv)->pmask_cache != (__pmask) || \
167            (__fpriv)->drawop_cache != FFB_DRAWOP_VSCROLL) { \
168                ffb_fbcPtr __ffb = (__fpriv)->regs; \
169                (__fpriv)->fbc_cache = __fbc; \
170                (__fpriv)->rop_cache = __rop; \
171                (__fpriv)->pmask_cache = (__pmask); \
172                (__fpriv)->drawop_cache = FFB_DRAWOP_VSCROLL; \
173                (__fpriv)->rp_active = 1; \
174                FFBFifo(__fpriv, 4); \
175                (__ffb)->fbc = __fbc; \
176                (__ffb)->rop = __rop; \
177                (__ffb)->pmask = (__pmask); \
178                (__ffb)->drawop = FFB_DRAWOP_VSCROLL; \
179        } \
180} while(0)
181
182
183static CARD32 FFBAlphaTextureFormats[2] = { PICT_a8, 0 };
184static CARD32 FFBTextureFormats[2] = { PICT_a8b8g8r8, 0 };
185static CARD32 FFBTextureDstFormats[3] = { PICT_a8b8g8r8, PICT_x8b8g8r8, 0 };
186
187static void FFB_SetupTextureAttrs(FFBPtr pFfb)
188{
189       ffb_fbcPtr ffb = pFfb->regs;
190       unsigned int ppc = FFB_PPC_APE_DISABLE | FFB_PPC_CS_VAR | FFB_PPC_XS_VAR;
191       unsigned int ppc_mask = FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
192       unsigned int rop = FFB_ROP_NEW | (FFB_ROP_NEW << 8);
193       unsigned int fbc = pFfb->xaa_fbc;
194       unsigned int wid = pFfb->xaa_wid;
195
196       ppc |= FFB_PPC_ABE_ENABLE;
197       ppc_mask |= FFB_PPC_ABE_MASK;
198
199       if ((pFfb->ppc_cache & ppc_mask) != ppc ||
200           pFfb->fbc_cache != fbc ||
201           pFfb->wid_cache != wid ||
202           pFfb->rop_cache != rop ||
203           pFfb->pmask_cache != 0xffffffff)
204               __FFB_Attr_SFB_VAR(pFfb, ppc, ppc_mask, fbc,
205                                  wid, rop, 0xffffffff);
206       FFBWait(pFfb, ffb);
207}
208
209static Bool FFB_SetupForCPUToScreenAlphaTexture(
210	ScrnInfoPtr	pScrn,
211	int		op,
212	CARD16		red,
213	CARD16		green,
214	CARD16		blue,
215	CARD16		alpha,
216	CARD32		maskFormat,
217	CARD32		dstFormat,
218	CARD8		*alphaPtr,
219	int		alphaPitch,
220	int		width,
221	int		height,
222	int		flags
223)
224{
225       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
226
227       FFBLOG(("FFB_SetupForCPUToScreenAlphaTexture: "
228               "argb[%04x:%04x:%04x:%04x] alpha[T(%x):P(%d)] "
229               "wh[%d:%d] flgs[%x]\n",
230               alpha, red, green, blue,
231               maskFormat, alphaPitch,
232               width, height, flags));
233
234       FFB_SetupTextureAttrs(pFfb);
235
236       pFfb->xaa_tex = (unsigned char *) alphaPtr;
237       pFfb->xaa_tex_pitch = alphaPitch;
238       pFfb->xaa_tex_width = width;
239       pFfb->xaa_tex_height = height;
240       pFfb->xaa_tex_color = (/*((alpha >> 8) << 24) |*/
241                              ((blue >> 8) << 16) |
242                              ((green >> 8) << 8) |
243                              ((red >> 8) << 0));
244       return TRUE;
245}
246
247static void FFB_SubsequentCPUToScreenAlphaTexture(ScrnInfoPtr pScrn,
248                                                 int dstx, int dsty,
249                                                 int srcx, int srcy,
250                                                 int width, int height)
251{
252       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
253       unsigned char *dst_base, *alpha_base, *sfb32;
254       unsigned int pixel_base;
255       int psz_shift = 2;
256
257       FFBLOG(("FFB_SubsequentCPUToScreenAlphaTexture: "
258               "dst[%d:%d] src[%d:%d] wh[%d:%d]\n",
259               dstx, dsty, srcx, srcy, width, height));
260
261       sfb32 = (unsigned char *) pFfb->sfb32;
262       dst_base = sfb32 + (dsty * (2048 << psz_shift)) + (dstx << psz_shift);
263       alpha_base = pFfb->xaa_tex;
264       alpha_base += srcx;
265       if (srcy)
266               alpha_base += (srcy * pFfb->xaa_tex_pitch);
267       pixel_base = pFfb->xaa_tex_color;
268       while (height--) {
269               unsigned int *dst = (unsigned int *) dst_base;
270               unsigned char *alpha = alpha_base;
271               int w = width;
272
273               while (w--) {
274                       (*dst) = (((unsigned int)*alpha << 24) | pixel_base);
275                       dst++;
276                       alpha++;
277	       }
278	       dst_base += (2048 << psz_shift);
279	       alpha_base += pFfb->xaa_tex_pitch;
280       }
281}
282
283
284static Bool FFB_SetupForCPUToScreenTexture(
285	ScrnInfoPtr	pScrn,
286	int		op,
287	CARD32		srcFormat,
288	CARD32		dstFormat,
289	CARD8		*texPtr,
290	int		texPitch,
291	int		width,
292	int		height,
293	int		flags
294)
295{
296       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
297
298       FFBLOG(("FFB_SetupForCPUToScreenTexture: "
299               "TEX[T(%x):P(%d)] "
300               "wh[%d:%d] flgs[%x]\n",
301               srcFormat, texPitch,
302               width, height, flags));
303
304       FFB_SetupTextureAttrs(pFfb);
305
306       pFfb->xaa_tex = (unsigned char *) texPtr;
307       pFfb->xaa_tex_pitch = texPitch;
308       pFfb->xaa_tex_width = width;
309       pFfb->xaa_tex_height = height;
310
311       return TRUE;
312}
313
314static void FFB_SubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,
315                                            int dstx, int dsty,
316                                            int srcx, int srcy,
317                                            int width, int height)
318{
319       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
320       unsigned char *dst_base, *sfb32;
321       unsigned int *tex_base;
322       int psz_shift = 2;
323
324       FFBLOG(("FFB_SubsequentCPUToScreenAlphaTexture: "
325               "dst[%d:%d] src[%d:%d] wh[%d:%d]\n",
326               dstx, dsty, srcx, srcy, width, height));
327
328       sfb32 = (unsigned char *) pFfb->sfb32;
329       dst_base = sfb32 + (dsty * (2048 << psz_shift)) + (dstx << psz_shift);
330       tex_base = (unsigned int *) pFfb->xaa_tex;
331       tex_base += srcx;
332       if (srcy)
333               tex_base += (srcy * pFfb->xaa_tex_pitch);
334       while (height--) {
335               unsigned int *dst = (unsigned int *) dst_base;
336               unsigned int *tex = tex_base;
337               int w = width;
338               while (w--) {
339                       (*dst) = *tex;
340
341                       dst++;
342                       tex++;
343               }
344               dst_base += (2048 << psz_shift);
345               tex_base += pFfb->xaa_tex_pitch;
346       }
347}
348
349static void FFB_WritePixmap(ScrnInfoPtr pScrn,
350                           int x, int y, int w, int h,
351                           unsigned char *src,
352                           int srcwidth,
353                           int rop,
354                           unsigned int planemask,
355                           int trans, int bpp, int depth)
356{
357       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
358       unsigned char *dst, *sfb32;
359       int psz_shift = 2;
360       ffb_fbcPtr ffb = pFfb->regs;
361
362       FFBLOG(("FFB_WritePixmap: "
363               "x[%d] y[%d] w[%d] h[%d] srcw[%d] rop[%d] pmask[%x] "
364               "trans[%d] bpp[%d] depth[%d]\n",
365               x, y, w, h, srcwidth, rop, planemask,
366               trans, bpp, depth));
367
368       FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop);
369       FFBWait(pFfb, ffb);
370
371       sfb32 = (unsigned char *) pFfb->sfb32;
372       dst = sfb32 + (y * (2048 << psz_shift)) + (x << psz_shift);
373       VISmoveImageLR(src, dst, w << psz_shift, h,
374                      srcwidth, (2048 << psz_shift));
375}
376
377static void FFB_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
378                                          int pat_word1, int pat_word2,
379                                          int fg, int bg, int rop,
380                                          unsigned int planemask)
381{
382       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
383       ffb_fbcPtr ffb = pFfb->regs;
384       unsigned int ppc, ppc_mask, fbc;
385       int i;
386
387       FFBLOG(("FFB_SetupForMono8x8PatternFill: "
388               "pat[%08x:%08x] fg[%x] bg[%x] rop[%d] pmask[%x]\n",
389               pat_word1, pat_word2,
390               fg, bg, rop, planemask));
391
392       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_ENABLE | FFB_PPC_CS_CONST;
393       if (bg < 0)
394               ppc |= FFB_PPC_TBE_TRANSPARENT;
395       else
396               ppc |= FFB_PPC_TBE_OPAQUE;
397       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK |
398         FFB_PPC_TBE_MASK | FFB_PPC_CS_MASK;
399       fbc = pFfb->xaa_fbc;
400       rop = (rop | FFB_ROP_EDIT_BIT) | (FFB_ROP_NEW << 8);
401
402       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask, rop,
403                    FFB_DRAWOP_RECTANGLE, fg, fbc, pFfb->xaa_wid);
404       if (bg >= 0)
405               FFB_WRITE_BG(pFfb, ffb, bg);
406
407       FFBFifo(pFfb, 32);
408       for (i = 0; i < 32; i += 2) {
409               CARD32 val1, val2;
410               int shift = (24 - ((i % 4) * 8));
411
412               if ((i % 8) < 4) {
413                       val1 = (pat_word1 >> shift) & 0xff;
414                       val2 = (pat_word1 >> (shift + 8)) & 0xff;
415               } else {
416                       val1 = (pat_word2 >> shift) & 0xff;
417                       val2 = (pat_word2 >> (shift + 8)) & 0xff;
418               }
419               val1 |= (val1 << 8) | (val1 << 16) | (val1 << 24);
420               val2 |= (val2 << 8) | (val2 << 16) | (val2 << 24);
421               FFB_WRITE64(&ffb->pattern[i], val1, val2);
422       }
423       pFfb->rp_active = 1;
424}
425
426static void FFB_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
427                                                int pat_word1, int pat_word2,
428                                                int x, int y, int w, int h)
429{
430       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
431       ffb_fbcPtr ffb = pFfb->regs;
432
433       FFBLOG(("FFB_SubsequentMono8x8PatternFillRect: "
434               "x[%d] y[%d] w[%d] h[%d]\n", x, y, w, h));
435
436       FFBFifo(pFfb, 4);
437       FFB_WRITE64(&ffb->by, y, x);
438       FFB_WRITE64_2(&ffb->bh, h, w);
439}
440
441static void FFB_SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
442                                                          int fg, int bg,
443                                                          int rop,
444                                                          unsigned int planemask)
445{
446       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
447       ffb_fbcPtr ffb = pFfb->regs;
448       unsigned int ppc, ppc_mask, fbc;
449
450       FFBLOG(("FFB_SetupForScanlineCPUToScreenColorExpandFill: "
451               "fg[%x] bg[%x] rop[%d] pmask[%x]\n",
452               fg, bg, rop, planemask));
453
454       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST;
455       if (bg < 0)
456               ppc |= FFB_PPC_TBE_TRANSPARENT;
457       else
458               ppc |= FFB_PPC_TBE_OPAQUE;
459       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK |
460         FFB_PPC_TBE_MASK | FFB_PPC_CS_MASK;
461       fbc = pFfb->xaa_fbc;
462       rop = (rop | FFB_ROP_EDIT_BIT) | (FFB_ROP_NEW << 8);
463
464       if ((pFfb->ppc_cache & ppc_mask) != ppc ||
465           pFfb->fg_cache != fg ||
466           pFfb->fbc_cache != fbc ||
467           pFfb->rop_cache != rop ||
468           pFfb->pmask_cache != planemask ||
469           pFfb->fontinc_cache != ((0<<16) | 32) ||
470           (bg >= 0 && pFfb->bg_cache != bg)) {
471               pFfb->ppc_cache &= ~ppc_mask;
472               pFfb->ppc_cache |= ppc;
473               pFfb->fg_cache = fg;
474               pFfb->fbc_cache = fbc;
475               pFfb->rop_cache = rop;
476               pFfb->pmask_cache = planemask;
477               pFfb->fontinc_cache = ((0<<16) | 32);
478               if (bg >= 0)
479                       pFfb->bg_cache = bg;
480               FFBFifo(pFfb, (bg >= 0 ? 7 : 6));
481               ffb->ppc = ppc;
482               ffb->fg = fg;
483               ffb->fbc = fbc;
484               ffb->rop = rop;
485               ffb->pmask = planemask;
486               ffb->fontinc = ((0 << 16) | 32);
487               if(bg >= 0)
488                       ffb->bg = bg;
489       }
490       pFfb->rp_active = 1;
491}
492
493static void FFB_SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
494                                                            int x, int y, int w, int h,
495                                                            int skipleft)
496{
497       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
498       FFBLOG(("FFB_SubsequentCPUToScreenColorExpandFill: "
499               "x[%d] y[%d] w[%d] h[%d] skipleft[%d]\n",
500               x, y, w, h, skipleft));
501
502       pFfb->xaa_scanline_x = x;
503       pFfb->xaa_scanline_y = y;
504       pFfb->xaa_scanline_w = w;
505}
506
507static void FFB_SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
508{
509       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
510       ffb_fbcPtr ffb = pFfb->regs;
511       CARD32 *bits = (CARD32 *) pFfb->xaa_scanline_buffers[bufno];
512       int w;
513
514       FFBFifo(pFfb, 1);
515       ffb->fontxy = ((pFfb->xaa_scanline_y << 16) | pFfb->xaa_scanline_x);
516
517       w = pFfb->xaa_scanline_w;
518       if (w >= 32) {
519               FFB_WRITE_FONTW(pFfb, ffb, 32);
520               FFBFifo(pFfb, (w / 32));
521               do {
522                       ffb->font = *bits++;
523                       w -= 32;
524               } while (w >= 32);
525       }
526       if (w > 0) {
527               FFB_WRITE_FONTW(pFfb, ffb, w);
528               FFBFifo(pFfb, 1);
529               ffb->font = *bits++;
530       }
531
532       pFfb->xaa_scanline_y++;
533}
534
535static void FFB_SetupForDashedLine(ScrnInfoPtr pScrn,
536                                  int fg, int bg, int rop,
537                                  unsigned int planemask,
538                                  int length, unsigned char *pattern)
539{
540       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
541       CARD32 *pat_ptr = (CARD32 *)pattern;
542       unsigned int ppc, ppc_mask, fbc;
543
544       FFBLOG(("FFB_SetupForDashedLine: "
545               "fg[%x] bg[%x] rop[%d] pmask[%x] patlen[%d] pat[%x]\n",
546               fg, bg, rop, planemask, length, *pat_ptr));
547
548       pFfb->xaa_planemask = planemask;
549       pFfb->xaa_rop = rop;
550       pFfb->xaa_linepat =
551               (*pat_ptr << FFB_LPAT_PATTERN_SHIFT) |
552               (1 << FFB_LPAT_SCALEVAL_SHIFT) |
553               ((length & 0xf) << FFB_LPAT_PATLEN_SHIFT);
554
555       fbc = pFfb->xaa_fbc;
556       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
557       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
558
559       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
560                    (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8),
561                    FFB_DRAWOP_BRLINEOPEN, fg, fbc, pFfb->xaa_wid);
562       pFfb->rp_active = 1;
563}
564
565static void FFB_SubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
566                                             int x1, int y1,
567                                             int x2, int y2,
568                                             int flags, int phase)
569{
570       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
571       ffb_fbcPtr ffb = pFfb->regs;
572       unsigned int linepat = pFfb->xaa_linepat;
573       unsigned int drawop;
574
575       FFBLOG(("FFB_SubsequentDashedTwoPointLine: "
576               "x1[%d] y1[%d] x2[%d] y2[%d] flgs[%x] phase[%d]\n",
577               x1, y2, x2, y2, flags, phase));
578
579       linepat |= (phase & 0xf) << FFB_LPAT_PATPTR_SHIFT;
580
581       drawop = (flags & OMIT_LAST) ?
582         FFB_DRAWOP_BRLINEOPEN : FFB_DRAWOP_BRLINECAP;
583       FFB_WRITE_DRAWOP(pFfb, ffb, drawop);
584
585       if (pFfb->has_brline_bug) {
586               FFBFifo(pFfb, 6);
587               ffb->ppc = 0;
588       } else
589               FFBFifo(pFfb, 5);
590       ffb->lpat = linepat;
591       FFB_WRITE64(&ffb->by, y1, x1);
592       FFB_WRITE64_2(&ffb->bh, y2, x2);
593}
594
595static void FFB_SetupForSolidLine(ScrnInfoPtr pScrn,
596                                 int color, int rop, unsigned int planemask)
597{
598       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
599       ffb_fbcPtr ffb = pFfb->regs;
600       unsigned int ppc, ppc_mask, fbc;
601       FFBLOG(("FFB_SetupForSolidLine: "
602               "color[%d] rop[%d] pmask[%x]\n",
603               color, rop, planemask));
604
605       pFfb->xaa_planemask = planemask;
606       pFfb->xaa_rop = rop;
607
608       fbc = pFfb->xaa_fbc;
609       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
610       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
611
612       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
613                    (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8),
614                    FFB_DRAWOP_BRLINEOPEN, color, fbc, pFfb->xaa_wid);
615       FFBFifo(pFfb, 1);
616       ffb->lpat = 0;
617       pFfb->rp_active = 1;
618}
619
620static void FFB_SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
621                                           int x1, int y1,
622                                           int x2, int y2,
623                                           int flags)
624{
625       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
626       ffb_fbcPtr ffb = pFfb->regs;
627       int drawop;
628
629       FFBLOG(("FFB_SubsequentSolidTwoPointLine: "
630               "x1[%d] y1[%d] x2[%d] y2[%d] flags[%d]\n",
631               x1, y1, x2, y2, flags));
632
633       drawop = (flags & OMIT_LAST) ?
634         FFB_DRAWOP_BRLINEOPEN : FFB_DRAWOP_BRLINECAP;
635       FFB_WRITE_DRAWOP(pFfb, ffb, drawop);
636
637       if (pFfb->has_brline_bug) {
638               FFBFifo(pFfb, 5);
639               ffb->ppc = 0;
640       } else
641               FFBFifo(pFfb, 4);
642       FFB_WRITE64(&ffb->by, y1, x1);
643       FFB_WRITE64_2(&ffb->bh, y2, x2);
644}
645
646void FFB_SetupForSolidFill(ScrnInfoPtr pScrn,
647                          int color, int rop, unsigned int planemask)
648{
649       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
650       unsigned int ppc, ppc_mask, fbc;
651
652       FFBLOG(("FFB_SetupForSolidFill: "
653               "color[%d] rop[%d] pmask[%u]\n",
654               color, rop, planemask));
655
656       pFfb->xaa_planemask = planemask;
657       pFfb->xaa_rop = rop;
658
659       fbc = pFfb->xaa_fbc;
660       if (pFfb->ffb_res == ffb_res_high)
661               fbc |= FFB_FBC_WB_B;
662       ppc = FFB_PPC_ABE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST | FFB_PPC_XS_WID;
663       ppc_mask = FFB_PPC_ABE_MASK | FFB_PPC_APE_MASK | FFB_PPC_CS_MASK | FFB_PPC_XS_MASK;
664
665       FFB_ATTR_RAW(pFfb, ppc, ppc_mask, planemask,
666                    (FFB_ROP_EDIT_BIT | rop) | (FFB_ROP_NEW << 8),
667                    FFB_DRAWOP_RECTANGLE, color, fbc, pFfb->xaa_wid);
668       pFfb->rp_active = 1;
669}
670
671void FFB_SubsequentSolidFillRect(ScrnInfoPtr pScrn,
672                                int x, int y,
673                                int w, int h)
674{
675       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
676       ffb_fbcPtr ffb = pFfb->regs;
677
678       FFBLOG(("FFB_SubsequentSolidFillRect: "
679               "x[%d] y[%d] w[%d] h[%d]\n", x, y, w, h));
680
681       FFBFifo(pFfb, 4);
682       FFB_WRITE64(&ffb->by, y, x);
683       FFB_WRITE64_2(&ffb->bh, h, w);
684}
685
686static void FFB_ScreenToScreenBitBlt(ScrnInfoPtr pScrn,
687                                    int nbox,
688                                    DDXPointPtr pptSrc,
689                                    BoxPtr pbox,
690                                    int xdir, int ydir,
691                                    int rop, unsigned int planemask)
692{
693       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
694       ffb_fbcPtr ffb = pFfb->regs;
695       int use_vscroll;
696
697       FFBLOG(("FFB_ScreenToScreenBitBlt: "
698               "nbox[%d] xdir[%d] ydir[%d] rop[%d] pmask[%x]\n",
699               nbox, xdir, ydir, rop, planemask));
700
701       use_vscroll = 0;
702       if (!pFfb->disable_vscroll &&
703           rop == GXcopy) {
704               int i;
705
706               for (i = 0; i < nbox; i++)
707                       if (pptSrc[i].x != pbox[i].x1 ||
708                           pptSrc[i].y == pbox[i].y1)
709                               break;
710               if (i == nbox) {
711                       /* If/When double buffer extension is re-enabled
712                        * check buffers here.
713                        */
714                       use_vscroll = 1;
715               }
716       }
717       if (use_vscroll) {
718               FFB_ATTR_VSCROLL_XAA(pFfb, planemask);
719               while (nbox--) {
720                       FFBFifo(pFfb, 7);
721                       ffb->drawop = FFB_DRAWOP_VSCROLL;
722                       FFB_WRITE64(&ffb->by, pptSrc->y, pptSrc->x);
723                       FFB_WRITE64_2(&ffb->dy, pbox->y1, pbox->x1);
724                       FFB_WRITE64_3(&ffb->bh, (pbox->y2 - pbox->y1),
725                                     (pbox->x2 - pbox->x1));
726
727                       pbox++;
728                       pptSrc++;
729               }
730               pFfb->rp_active = 1;
731               SET_SYNC_FLAG(pFfb->pXAAInfo);
732       } else {
733               unsigned char *sfb32 = (unsigned char *) pFfb->sfb32;
734               int psz_shift = 2;
735
736               FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop);
737               if (pFfb->use_blkread_prefetch) {
738                       unsigned int bit;
739
740                       if (xdir < 0)
741                               bit = FFB_MER_EDRA;
742                       else
743                               bit = FFB_MER_EIRA;
744                       FFBFifo(pFfb, 1);
745                       ffb->mer = bit;
746                       pFfb->rp_active = 1;
747               }
748               FFBWait(pFfb, ffb);
749
750               while (nbox--) {
751                       unsigned char *src, *dst;
752                       int x1, y1, x2, y2;
753                       int width, height;
754                       int sdkind;
755
756                       x1 = pptSrc->x;
757                       y1 = pptSrc->y;
758                       x2 = pbox->x1;
759                       y2 = pbox->y1;
760                       width = (pbox->x2 - pbox->x1);
761                       height = (pbox->y2 - pbox->y1);
762
763                       src = sfb32 + (y1 * (2048 << psz_shift))
764                               + (x1 << psz_shift);
765                       dst = sfb32 + (y2 * (2048 << psz_shift))
766                               + (x2 << psz_shift);
767                       sdkind = (2048 << psz_shift);
768
769                       if (ydir < 0) {
770                               src += ((height - 1) * (2048 << psz_shift));
771                               dst += ((height - 1) * (2048 << psz_shift));
772                               sdkind = -sdkind;
773                       }
774                       width <<= psz_shift;
775                       if (xdir < 0)
776                               VISmoveImageRL(src, dst, width, height,
777                                              sdkind, sdkind);
778                       else
779                               VISmoveImageLR(src, dst, width, height,
780                                              sdkind, sdkind);
781                       pbox++;
782                       pptSrc++;
783	       }
784               if (pFfb->use_blkread_prefetch) {
785                       FFBFifo(pFfb, 1);
786                       ffb->mer = FFB_MER_DRA;
787                       pFfb->rp_active = 1;
788                       FFBWait(pFfb, ffb);
789               }
790       }
791}
792
793void FFB_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
794                                   int xdir, int ydir, int rop,
795                                   unsigned int planemask,
796                                   int trans_color)
797{
798       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
799       ffb_fbcPtr ffb = pFfb->regs;
800       FFBLOG(("FFB_SetupForScreenToScreenCopy: "
801               "xdir[%d] ydir[%d] rop[%d] pmask[%x] tcolor[%d]\n",
802               xdir, ydir, rop, planemask, trans_color));
803
804       pFfb->xaa_planemask = planemask;
805       pFfb->xaa_xdir = xdir;
806       pFfb->xaa_ydir = ydir;
807       pFfb->xaa_rop = rop;
808       FFB_ATTR_SFB_VAR_XAA(pFfb, planemask, rop);
809       FFBWait(pFfb, ffb);
810}
811
812void FFB_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
813                                     int x1, int y1,
814                                     int x2, int y2,
815                                     int width, int height)
816{
817       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
818       unsigned char *src, *dst, *sfb32;
819       int psz_shift = 2;
820       int sdkind;
821
822       FFBLOG(("FFB_SubsequentScreenToScreenCopy: "
823               "x1[%d] y1[%d] x2[%d] y2[%u] w[%d] h[%d]\n",
824               x1, y1, x2, y2, width, height));
825
826       sfb32 = (unsigned char *) pFfb->sfb32;
827       src = sfb32 + (y1 * (2048 << psz_shift)) + (x1 << psz_shift);
828       dst = sfb32 + (y2 * (2048 << psz_shift)) + (x2 << psz_shift);
829       sdkind = (2048 << psz_shift);
830
831       if (pFfb->xaa_ydir < 0) {
832               src += ((height - 1) * (2048 << psz_shift));
833               dst += ((height - 1) * (2048 << psz_shift));
834               sdkind = -sdkind;
835       }
836
837       width <<= psz_shift;
838       if (pFfb->xaa_xdir < 0)
839               VISmoveImageRL(src, dst, width, height, sdkind, sdkind);
840       else
841               VISmoveImageLR(src, dst, width, height, sdkind, sdkind);
842}
843
844static void FFB_Sync(ScrnInfoPtr pScrn)
845{
846       FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
847       ffb_fbcPtr ffb = pFfb->regs;
848
849       FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
850       FFBWait(pFfb, ffb);
851}
852
853/* Multiplies and divides suck... */
854static void CreatorAlignTabInit(FFBPtr pFfb)
855{
856	struct fastfill_parms *ffp = &FFB_FFPARMS(pFfb);
857	short *tab = pFfb->Pf_AlignTab;
858	int i;
859
860	for(i = 0; i < 0x800; i++) {
861		int alignval;
862
863		alignval = (i / ffp->pagefill_width) * ffp->pagefill_width;
864		*tab++ = alignval;
865	}
866}
867
868#endif
869
870Bool FFBAccelInit(ScreenPtr pScreen, FFBPtr pFfb)
871{
872#ifdef HAVE_XAA_H
873	XAAInfoRecPtr infoRec;
874	ffb_fbcPtr ffb = pFfb->regs;
875
876	pFfb->xaa_fbc = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
877			 FFB_FBC_WE_FORCEON |
878			 FFB_FBC_SB_BOTH |
879			 FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
880			 FFB_FBC_RGBE_MASK |
881			 FFB_FBC_XE_ON);
882	pFfb->xaa_wid = FFBWidAlloc(pFfb, TrueColor, 0, TRUE);
883	if (pFfb->xaa_wid == (unsigned int) -1)
884		return FALSE;
885
886	pFfb->pXAAInfo = infoRec = XAACreateInfoRec();
887	if (!infoRec) {
888		FFBWidFree(pFfb, pFfb->xaa_wid);
889		return FALSE;
890	}
891
892	pFfb->xaa_scanline_buffers[0] = malloc(2048 * 4);
893	if (!pFfb->xaa_scanline_buffers[0]) {
894		XAADestroyInfoRec(infoRec);
895		return FALSE;
896	}
897
898	pFfb->xaa_scanline_buffers[1] = malloc(2048 * 4);
899	if (!pFfb->xaa_scanline_buffers[1]) {
900		free(pFfb->xaa_scanline_buffers[0]);
901		XAADestroyInfoRec(infoRec);
902		return FALSE;
903	}
904
905	infoRec->Sync = FFB_Sync;
906
907	/* Use VIS and VSCROLL for screen to screen copies.  */
908	infoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
909	infoRec->SetupForScreenToScreenCopy =
910		FFB_SetupForScreenToScreenCopy;
911	infoRec->SubsequentScreenToScreenCopy =
912		FFB_SubsequentScreenToScreenCopy;
913
914	/* In order to optimize VSCROLL and prefetching properly we
915	 * have to use our own mid-layer routine.
916	 */
917	infoRec->ScreenToScreenBitBltFlags = NO_TRANSPARENCY;
918	infoRec->ScreenToScreenBitBlt =
919		FFB_ScreenToScreenBitBlt;
920
921	infoRec->SolidFillFlags = 0;
922	infoRec->SetupForSolidFill =
923		FFB_SetupForSolidFill;
924	infoRec->SubsequentSolidFillRect =
925		FFB_SubsequentSolidFillRect;
926
927	infoRec->SolidLineFlags = 0;
928	infoRec->SetupForSolidLine =
929		FFB_SetupForSolidLine;
930	infoRec->SubsequentSolidTwoPointLine =
931		FFB_SubsequentSolidTwoPointLine;
932	miSetZeroLineBias(pScreen, OCTANT3 | OCTANT4 | OCTANT6 | OCTANT1);
933
934	infoRec->DashedLineFlags = (TRANSPARENCY_ONLY |
935				    LINE_PATTERN_LSBFIRST_LSBJUSTIFIED);
936	infoRec->DashPatternMaxLength = 16;
937	infoRec->SetupForDashedLine =
938		FFB_SetupForDashedLine;
939	infoRec->SubsequentDashedTwoPointLine =
940		FFB_SubsequentDashedTwoPointLine;
941
942	/* We cannot use the non-scanline color expansion mechanism on FFB
943	 * for two reasons:
944	 *
945	 * 1) A render pass can only render 32-pixels wide on FFB, XAA expects
946	 *    that arbitrary widths are possible per render pass.
947	 *
948	 * 2) The FFB accelerator FIFO is only 100 or so words deep, and
949	 *    XAA gives no way to limit the number of words it writes into
950	 *    the ColorExpandBase register per rendering pass.
951	 */
952	infoRec->ScanlineColorExpandBuffers = pFfb->xaa_scanline_buffers;
953	infoRec->NumScanlineColorExpandBuffers = 2;
954	infoRec->ScanlineCPUToScreenColorExpandFillFlags =
955		CPU_TRANSFER_PAD_DWORD |
956		SCANLINE_PAD_DWORD |
957		CPU_TRANSFER_BASE_FIXED |
958		BIT_ORDER_IN_BYTE_LSBFIRST;
959	infoRec->SetupForScanlineCPUToScreenColorExpandFill =
960		FFB_SetupForScanlineCPUToScreenColorExpandFill;
961	infoRec->SubsequentScanlineCPUToScreenColorExpandFill =
962		FFB_SubsequentScanlineCPUToScreenColorExpandFill;
963	infoRec->SubsequentColorExpandScanline =
964		FFB_SubsequentColorExpandScanline;
965
966	infoRec->Mono8x8PatternFillFlags =
967		HARDWARE_PATTERN_PROGRAMMED_BITS |
968		HARDWARE_PATTERN_SCREEN_ORIGIN |
969		BIT_ORDER_IN_BYTE_LSBFIRST;
970	infoRec->SetupForMono8x8PatternFill =
971		FFB_SetupForMono8x8PatternFill;
972	infoRec->SubsequentMono8x8PatternFillRect =
973		FFB_SubsequentMono8x8PatternFillRect;
974
975	/* Use VIS for pixmap writes.  */
976	infoRec->WritePixmap = FFB_WritePixmap;
977
978	/* RENDER optimizations.  */
979	infoRec->CPUToScreenAlphaTextureFlags =
980		XAA_RENDER_NO_TILE |
981		XAA_RENDER_NO_SRC_ALPHA;
982	infoRec->CPUToScreenAlphaTextureFormats = FFBAlphaTextureFormats;
983	infoRec->CPUToScreenAlphaTextureDstFormats = FFBTextureDstFormats;
984	infoRec->SetupForCPUToScreenAlphaTexture2 =
985		FFB_SetupForCPUToScreenAlphaTexture;
986	infoRec->SubsequentCPUToScreenAlphaTexture =
987		FFB_SubsequentCPUToScreenAlphaTexture;
988
989	infoRec->CPUToScreenTextureFlags =
990		XAA_RENDER_NO_TILE |
991		XAA_RENDER_NO_SRC_ALPHA;
992	infoRec->CPUToScreenTextureFormats = FFBTextureFormats;
993	infoRec->CPUToScreenTextureDstFormats = FFBTextureDstFormats;
994	infoRec->SetupForCPUToScreenTexture2 =
995		FFB_SetupForCPUToScreenTexture;
996	infoRec->SubsequentCPUToScreenTexture =
997		FFB_SubsequentCPUToScreenTexture;
998
999	pFfb->fifo_cache = 0;
1000
1001	FFB_DEBUG_init();
1002	FDEBUG((FDEBUG_FD,
1003		"FFB: cfg0(%08x) cfg1(%08x) cfg2(%08x) cfg3(%08x) ppcfg(%08x)\n",
1004		ffb->fbcfg0, ffb->fbcfg1, ffb->fbcfg2, ffb->fbcfg3, ffb->ppcfg));
1005
1006	/* Determine the current screen resolution type.  This is
1007	 * needed to figure out the fastfill/pagefill parameters.
1008	 */
1009	switch(ffb->fbcfg0 & FFB_FBCFG0_RES_MASK) {
1010	default:
1011	case FFB_FBCFG0_RES_STD:
1012		pFfb->ffb_res = ffb_res_standard;
1013		break;
1014	case FFB_FBCFG0_RES_HIGH:
1015		pFfb->ffb_res = ffb_res_high;
1016		break;
1017	case FFB_FBCFG0_RES_STEREO:
1018		pFfb->ffb_res = ffb_res_stereo;
1019		break;
1020	case FFB_FBCFG0_RES_PRTRAIT:
1021		pFfb->ffb_res = ffb_res_portrait;
1022		break;
1023	};
1024	CreatorAlignTabInit(pFfb);
1025
1026	/* Next, determine the hwbug workarounds and feature enables
1027	 * we should be using on this board.
1028	 */
1029	pFfb->disable_pagefill = 0;
1030	pFfb->disable_vscroll = 0;
1031	pFfb->has_brline_bug = 0;
1032	pFfb->use_blkread_prefetch = 0;
1033	if (pFfb->ffb_type == ffb1_prototype ||
1034	    pFfb->ffb_type == ffb1_standard ||
1035	    pFfb->ffb_type == ffb1_speedsort) {
1036		pFfb->has_brline_bug = 1;
1037		if (pFfb->ffb_res == ffb_res_high)
1038			pFfb->disable_vscroll = 1;
1039		if (pFfb->ffb_res == ffb_res_high ||
1040		    pFfb->ffb_res == ffb_res_stereo)
1041			pFfb->disable_pagefill = 1;
1042
1043	} else {
1044		/* FFB2 has blkread prefetch.  AFB supposedly does too
1045		 * but the chip locks up on me when I try to use it. -DaveM
1046		 */
1047#define AFB_PREFETCH_IS_BUGGY	1
1048		if (!AFB_PREFETCH_IS_BUGGY ||
1049		    (pFfb->ffb_type != afb_m3 &&
1050		     pFfb->ffb_type != afb_m6)) {
1051			pFfb->use_blkread_prefetch = 1;
1052		}
1053		/* XXX I still cannot get page/block fast fills
1054		 * XXX to work reliably on any of my AFB boards. -DaveM
1055		 */
1056#define AFB_FASTFILL_IS_BUGGY	1
1057		if (AFB_FASTFILL_IS_BUGGY &&
1058		    (pFfb->ffb_type == afb_m3 ||
1059		     pFfb->ffb_type == afb_m6))
1060			pFfb->disable_pagefill = 1;
1061	}
1062	pFfb->disable_fastfill_ap = 0;
1063	if (pFfb->ffb_res == ffb_res_stereo ||
1064	    pFfb->ffb_res == ffb_res_high)
1065		pFfb->disable_fastfill_ap = 1;
1066
1067	pFfb->ppc_cache = (FFB_PPC_FW_DISABLE |
1068			   FFB_PPC_VCE_DISABLE | FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST |
1069			   FFB_PPC_XS_WID | FFB_PPC_YS_CONST | FFB_PPC_ZS_CONST |
1070			   FFB_PPC_DCE_DISABLE | FFB_PPC_ABE_DISABLE | FFB_PPC_TBE_OPAQUE);
1071	pFfb->wid_cache = pFfb->xaa_wid;
1072	pFfb->pmask_cache = ~0;
1073	pFfb->rop_cache = (FFB_ROP_NEW | (FFB_ROP_NEW << 8));
1074	pFfb->drawop_cache = FFB_DRAWOP_RECTANGLE;
1075	pFfb->fg_cache = pFfb->bg_cache = 0;
1076	pFfb->fontw_cache = 32;
1077	pFfb->fontinc_cache = (1 << 16) | 0;
1078	pFfb->fbc_cache = (FFB_FBC_WB_A | FFB_FBC_WM_COMBINED | FFB_FBC_RB_A |
1079			   FFB_FBC_WE_FORCEON |
1080			   FFB_FBC_SB_BOTH |
1081			   FFB_FBC_ZE_OFF | FFB_FBC_YE_OFF |
1082			   FFB_FBC_RGBE_OFF |
1083			   FFB_FBC_XE_ON);
1084	pFfb->laststipple = NULL;
1085
1086	/* We will now clear the screen: we'll draw a rectangle covering all the
1087	 * viewscreen, using a 'blackness' ROP.
1088	 */
1089	FFBFifo(pFfb, 22);
1090	ffb->fbc = pFfb->fbc_cache;
1091	ffb->ppc = pFfb->ppc_cache;
1092	ffb->wid = pFfb->wid_cache;
1093	ffb->xpmask = 0xff;
1094	ffb->pmask = pFfb->pmask_cache;
1095	ffb->rop = pFfb->rop_cache;
1096	ffb->drawop = pFfb->drawop_cache;
1097	ffb->fg = pFfb->fg_cache;
1098	ffb->bg = pFfb->bg_cache;
1099	ffb->fontw = pFfb->fontw_cache;
1100	ffb->fontinc = pFfb->fontinc_cache;
1101	ffb->xclip = FFB_XCLIP_TEST_ALWAYS;
1102	ffb->cmp = 0x80808080;
1103	ffb->matchab = 0x80808080;
1104	ffb->magnab = 0x80808080;
1105	ffb->blendc = (FFB_BLENDC_FORCE_ONE |
1106		       FFB_BLENDC_DF_ONE_M_A |
1107		       FFB_BLENDC_SF_A);
1108	ffb->blendc1 = 0;
1109	ffb->blendc2 = 0;
1110	FFB_WRITE64(&ffb->by, 0, 0);
1111	FFB_WRITE64_2(&ffb->bh, pFfb->psdp->height, pFfb->psdp->width);
1112	pFfb->rp_active = 1;
1113	FFBWait(pFfb, ffb);
1114
1115	FFB_ATTR_SFB_VAR_XAA(pFfb, 0xffffffff, GXcopy);
1116	FFBWait(pFfb, ffb);
1117
1118	if (!XAAInit(pScreen, infoRec)) {
1119		XAADestroyInfoRec(infoRec);
1120		free(pFfb->xaa_scanline_buffers[0]);
1121		free(pFfb->xaa_scanline_buffers[1]);
1122		pFfb->pXAAInfo = NULL;
1123		FFBWidFree(pFfb, pFfb->xaa_wid);
1124		return FALSE;
1125	}
1126	/* Success */
1127	return TRUE;
1128#else
1129	return FALSE;
1130#endif
1131}
1132