1/* (c) Itai Nahshon */
2
3#ifdef HAVE_CONFIG_H
4#include "config.h"
5#endif
6
7#include "xf86.h"
8#include "xf86_OSproc.h"
9#include "compiler.h"
10
11#include "xf86Pci.h"
12
13#include "vgaHW.h"
14
15#include "cir.h"
16#define _ALP_PRIVATE_
17#include "alp.h"
18
19#ifdef HAVE_XAA_H
20#define WAIT	outb(pCir->PIOReg, 0x31); \
21		while(inb(pCir->PIOReg + 1) & pCir->chip.alp->waitMsk){};
22#define WAIT_1	outb(pCir->PIOReg, 0x31); \
23		while(inb(pCir->PIOReg + 1) & 0x1){};
24
25static const CARD16 translated_rop[] =
26{
27  /* GXclear */        0x0032U,
28  /* GXand   */        0x0532U,
29  /* GXandreverse */   0x0932U,
30  /* GXcopy */         0x0D32U,
31  /* GXandinversted */ 0x5032U,
32  /* GXnoop */         0x0632U,
33  /* GXxor */          0x5932U,
34  /* GXor */           0x6D32U,
35  /* GXnor */          0x9032U,
36  /* GXequiv */        0x9532U,
37  /* GXinvert */       0x0B32U,
38  /* GXorReverse */    0xAD32U,
39  /* GXcopyInverted */ 0xD032U,
40  /* GXorInverted */   0xD632U,
41  /* GXnand */         0xDA32U,
42  /* GXset */          0x0E32U
43};
44
45#if 1
46#define SetupForRop(rop) outw(pCir->PIOReg, translated_rop[rop])
47#else
48#define SetupForRop(rop) outw(pCir->PIOReg, 0x0D32)
49#endif
50
51static void AlpSync(ScrnInfoPtr pScrn)
52{
53	CirPtr pCir = CIRPTR(pScrn);
54
55#ifdef ALP_DEBUG
56	ErrorF("AlpSync\n");
57#endif
58	WAIT_1;
59	return;
60}
61
62static void
63AlpSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
64			      int rop, unsigned int planemask,
65			      int trans_color)
66{
67	CirPtr pCir = CIRPTR(pScrn);
68	int pitch = pCir->pitch;
69
70#ifdef ALP_DEBUG
71	ErrorF("AlpSetupForScreenToScreenCopy xdir=%d ydir=%d rop=%x planemask=%x trans_color=%x\n",
72		xdir, ydir, rop, planemask, trans_color);
73#endif
74	WAIT;
75	SetupForRop(rop);
76	/* Set dest pitch */
77	outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24);
78	outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25);
79	/* Set source pitch */
80	outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x26);
81	outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x27);
82}
83
84static void
85AlpSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
86								int y2, int w, int h)
87{
88	CirPtr pCir = CIRPTR(pScrn);
89	int source, dest;
90	int  hh, ww;
91	int decrement = 0;
92	int pitch = pCir->pitch;
93
94	ww = (w * pScrn->bitsPerPixel / 8) - 1;
95	hh = h - 1;
96	dest = y2 * pitch + x2 * pScrn->bitsPerPixel / 8;
97	source = y1 * pitch + x1 * pScrn->bitsPerPixel / 8;
98	if (dest > source) {
99		decrement = 1 << 8;
100		dest += hh * pitch + ww;
101		source += hh * pitch + ww;
102	}
103
104	WAIT;
105
106	outw(pCir->PIOReg, decrement | 0x30);
107
108	/* Width */
109	outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20);
110	outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21);
111	/* Height */
112	outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22);
113	outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23);
114
115
116	/* source */
117	outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C);
118	outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D);
119	outw(pCir->PIOReg, ((source >> 8) & 0x3f00)| 0x2E);
120
121	/* dest */
122	outw(pCir->PIOReg, ((dest  << 8) & 0xff00) | 0x28);
123	outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29);
124	outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A);
125	if (!pCir->chip.alp->autoStart)
126	  outw(pCir->PIOReg, 0x0231);
127
128#ifdef ALP_DEBUG
129	ErrorF("AlpSubsequentScreenToScreenCopy x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n",
130			x1, y1, x2, y2, w, h);
131	ErrorF("AlpSubsequentScreenToScreenCopy s=%d d=%d ww=%d hh=%d\n",
132			source, dest, ww, hh);
133#endif
134
135}
136
137static void
138AlpSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
139						unsigned int planemask)
140{
141	CirPtr pCir = CIRPTR(pScrn);
142	AlpPtr pAlp = ALPPTR(pCir);
143	int pitch = pCir->pitch;
144
145#ifdef ALP_DEBUG
146	ErrorF("AlpSetupForSolidFill color=%x rop=%x planemask=%x\n",
147			color, rop, planemask);
148#endif
149	WAIT;
150
151	SetupForRop(rop);
152
153	switch (pCir -> Chipset)
154	{
155	case PCI_CHIP_GD7548:
156	  /* The GD7548 does not (apparently) support solid filling
157	     directly, it always need an actual source.
158	     We therefore use it as a pattern fill with a solid
159	     pattern */
160	  {
161	    int source = pAlp->monoPattern8x8;
162	    /* source = 8x8 solid mono pattern */
163	    outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C);
164	    outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D);
165	    outw(pCir->PIOReg, ((source >> 8) & 0x3f00) | 0x2E);
166	    /* memset() may not be the fastest */
167	    memset(pCir->FbBase + pAlp->monoPattern8x8, 0xFF, 8);
168	    write_mem_barrier();
169	    break;
170	  }
171        default:
172          /* GR33 = 0x04 => does not exist on GD7548 */
173	  outw(pCir->PIOReg, 0x0433);
174	}
175
176        /* GR30 = color expansion, pattern copy */
177	/* Choses 8bpp / 16bpp color expansion */
178	outw(pCir->PIOReg, 0xC030 |((pScrn->bitsPerPixel - 8) << 9));
179
180	outw(pCir->PIOReg, ((color << 8) & 0xff00) | 0x01);
181	outw(pCir->PIOReg, ((color) & 0xff00) | 0x11);
182	outw(pCir->PIOReg, ((color >> 8) & 0xff00) | 0x13);
183	outw(pCir->PIOReg, 0x15);
184
185	/* Set dest pitch */
186	outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24);
187	outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25);
188}
189
190static void
191AlpSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
192{
193	CirPtr pCir = CIRPTR(pScrn);
194	int dest;
195	int hh, ww;
196	int pitch = pCir->pitch;
197
198	ww = (w * pScrn->bitsPerPixel / 8) - 1;
199	hh = h - 1;
200	dest = y * pitch + x * pScrn->bitsPerPixel / 8;
201
202	WAIT;
203
204	/* Width */
205	outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20);
206	outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21);
207	/* Height */
208	outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22);
209	outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23);
210
211	/* dest */
212	outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28);
213	outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29);
214	outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A);
215	if (!pCir->chip.alp->autoStart)
216	  outw(pCir->PIOReg, 0x0231);
217
218#ifdef ALP_DEBUG
219	ErrorF("AlpSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n",
220			x, y, w, h);
221#endif
222
223}
224
225static void
226AlpSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
227			      int patx, int paty,
228			      int fg, int bg,
229			      int rop, unsigned int planemask)
230{
231	CirPtr pCir = CIRPTR(pScrn);
232	AlpPtr pAlp = ALPPTR(pCir);
233	int pitch = pCir->pitch;
234
235#ifdef ALP_DEBUG
236	ErrorF("AlpSetupFor8x8PatternFill pattern=%8x%8x"
237	       "fg=%x bg=%x rop=%x planemask=%x\n",
238			patx, paty, fg, bg, rop, planemask);
239#endif
240	WAIT;
241
242	SetupForRop(rop);
243
244	{
245	  int source = pAlp->monoPattern8x8;
246	  /* source = 8x8 solid mono pattern */
247	  outw(pCir->PIOReg, ((source << 8) & 0xff00) | 0x2C);
248	  outw(pCir->PIOReg, ((source) & 0xff00) | 0x2D);
249	  outw(pCir->PIOReg, ((source >> 8) & 0x3f00) | 0x2E);
250	}
251
252        /* GR30 = color expansion, pattern copy */
253	/* Choses 8bpp / 16bpp color expansion */
254	if (bg == -1)
255	{ /* transparency requested */
256	  outw(pCir->PIOReg, 0xC830 |((pScrn->bitsPerPixel - 8) << 9));
257
258	  bg = ~fg;
259	  /* transparent color compare */
260	  outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x34);
261	  outw(pCir->PIOReg, ((bg) & 0xff00) | 0x35);
262
263	  /* transparent color mask = 0 (all bits matters) */
264	  outw(pCir->PIOReg, 0x38);
265	  outw(pCir->PIOReg, 0x39);
266	}
267	else
268	{
269	  outw(pCir->PIOReg, 0xC030 |((pScrn->bitsPerPixel - 8) << 9));
270	}
271
272	outw(pCir->PIOReg, ((fg << 8) & 0xff00) | 0x01);
273	outw(pCir->PIOReg, ((fg) & 0xff00) | 0x11);
274
275	outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x00);
276	outw(pCir->PIOReg, ((bg) & 0xff00) | 0x10);
277
278	/* Set dest pitch */
279	outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24);
280	outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25);
281}
282
283static void
284AlpSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
285			   int x, int y, int w, int h)
286{
287	CirPtr pCir = CIRPTR(pScrn);
288	AlpPtr pAlp = ALPPTR(pCir);
289	int dest;
290	int hh, ww;
291	int pitch = pCir->pitch;
292
293	ww = (w * pScrn->bitsPerPixel / 8) - 1;
294	hh = h - 1;
295	dest = y * pitch + x * pScrn->bitsPerPixel / 8;
296
297	WAIT;
298	/* memcpy() may not be the fastest */
299	memcpy(pCir->FbBase + pAlp->monoPattern8x8, &patx, 4);
300	memcpy(pCir->FbBase + pAlp->monoPattern8x8 + 4, &paty, 4);
301	write_mem_barrier();
302
303	/* Width */
304	outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20);
305	outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21);
306	/* Height */
307	outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22);
308	outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23);
309
310	/* dest */
311	outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28);
312	outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29);
313	outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A);
314	if (!pCir->chip.alp->autoStart)
315	  outw(pCir->PIOReg, 0x0231);
316
317#ifdef ALP_DEBUG
318	ErrorF("AlpSubsequent8x8PatternFill x=%d y=%d w=%d h=%d\n",
319			x, y, w, h);
320#endif
321
322}
323
324#if 0
325/* XF86 does not support byte-padded scanlines */
326
327static void
328AlpSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
329                        int fg, int bg,
330                        int rop,
331                        unsigned int planemask)
332{
333	CirPtr pCir = CIRPTR(pScrn);
334	AlpPtr pAlp = ALPPTR(pCir);
335	int pitch = pCir->pitch;
336
337#ifdef ALP_DEBUG
338	ErrorF("AlpSetupForCPUToScreenColorExpandFill "
339	       "fg=%x bg=%x rop=%x planemask=%x\n",
340			fg, bg, rop, planemask);
341#endif
342	WAIT;
343
344	SetupForRop(rop);
345
346        /* GR30 = color expansion, CPU->display copy */
347	/* Choses 8bpp / 16bpp color expansion */
348	if (bg == -1)
349	{ /* transparency requested */
350	  outw(pCir->PIOReg, 0x8C30 |((pScrn->bitsPerPixel - 8) << 9));
351
352	  bg = ~fg;
353	  /* transparent color compare */
354	  outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x34);
355	  outw(pCir->PIOReg, ((bg) & 0xff00) | 0x35);
356
357	  /* transparent color mask = 0 (all bits matters) */
358	  outw(pCir->PIOReg, 0x38);
359	  outw(pCir->PIOReg, 0x39);
360	}
361	else
362	{
363	  outw(pCir->PIOReg, 0x8430 |((pScrn->bitsPerPixel - 8) << 9));
364	}
365
366	outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x00);
367	outw(pCir->PIOReg, ((bg) & 0xff00) | 0x10);
368
369	outw(pCir->PIOReg, ((fg << 8) & 0xff00) | 0x01);
370	outw(pCir->PIOReg, ((fg) & 0xff00) | 0x11);
371
372	/* Set dest pitch */
373	outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24);
374	outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25);
375}
376
377static void
378AlpSubsequentCPUToScreenColorExpandFill(
379	ScrnInfoPtr pScrn,
380	int x, int y, int w, int h,
381	int skipleft)
382{
383	CirPtr pCir = CIRPTR(pScrn);
384	int dest;
385	int hh, ww;
386	int pitch = pCir->pitch;
387
388	ww = (((w+7) & ~7) * pScrn->bitsPerPixel / 8) - 1;
389	hh = h - 1;
390	dest = y * pitch + x * pScrn->bitsPerPixel / 8;
391
392	WAIT;
393
394	/* Width */
395	outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20);
396	outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21);
397	/* Height */
398	outw(pCir->PIOReg, ((hh << 8) & 0xff00) | 0x22);
399	outw(pCir->PIOReg, ((hh) & 0x0700) | 0x23);
400
401	/* source = CPU ; description of bit 2 of GR30 in the 7548 manual
402	   says that if we do color expansion we must zero the source
403	   address registers (GR2C, GR2D, GR2E) */
404	outw(pCir->PIOReg, 0x2C);
405	outw(pCir->PIOReg, 0x2D);
406	outw(pCir->PIOReg, 0x2E);
407
408	/* dest */
409	outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28);
410	outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29);
411	outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A);
412	if (!pCir->chip.alp->autoStart)
413	  outw(pCir->PIOReg, 0x0231);
414
415#ifdef ALP_DEBUG
416	ErrorF("AlpSubsequentCPUToScreenColorExpandFill x=%d y=%d w=%d h=%d\n",
417			x, y, w, h);
418#endif
419}
420#endif
421
422#if 1
423static void
424AlpSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
425                        int fg, int bg,
426                        int rop,
427                        unsigned int planemask)
428{
429	CirPtr pCir = CIRPTR(pScrn);
430	int pitch = pCir->pitch;
431
432#ifdef ALP_DEBUG
433	ErrorF("AlpSetupForCPUToScreenColorExpandFill "
434	       "fg=%x bg=%x rop=%x planemask=%x, bpp=%d\n",
435			fg, bg, rop, planemask, pScrn->bitsPerPixel);
436#endif
437	WAIT;
438
439	SetupForRop(rop);
440
441        /* GR30 = color expansion, CPU->display copy */
442	/* Choses 8bpp / 16bpp color expansion */
443	if (bg == -1)
444	{ /* transparency requested */
445	  if (pScrn->bitsPerPixel > 8) /* 16 bpp */
446	  {
447	    outw(pCir->PIOReg, 0x9C30);
448
449	    bg = ~fg;
450	    /* transparent color compare */
451	    outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x34);
452	    outw(pCir->PIOReg, ((bg) & 0xff00) | 0x35);
453	  } else /* 8 bpp */
454	  {
455	    outw(pCir->PIOReg, 0x8C30);
456
457	    bg = ~fg;
458	    /* transparent color compare */
459	    outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x34);
460	    outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x35);
461	  }
462
463	  /* transparent color mask = 0 (all bits matters) */
464	  outw(pCir->PIOReg, 0x38);
465	  outw(pCir->PIOReg, 0x39);
466	}
467	else
468	{
469	  outw(pCir->PIOReg, 0x8430 |((pScrn->bitsPerPixel - 8) << 9));
470	}
471
472	outw(pCir->PIOReg, ((bg << 8) & 0xff00) | 0x00);
473	outw(pCir->PIOReg, ((bg) & 0xff00) | 0x10);
474
475	outw(pCir->PIOReg, ((fg << 8) & 0xff00) | 0x01);
476	outw(pCir->PIOReg, ((fg) & 0xff00) | 0x11);
477
478	/* Set dest pitch */
479	outw(pCir->PIOReg, ((pitch << 8) & 0xff00) | 0x24);
480	outw(pCir->PIOReg, ((pitch) & 0x1f00) | 0x25);
481}
482
483static void
484AlpSubsequentScanlineCPUToScreenColorExpandFill(
485	ScrnInfoPtr pScrn,
486	int x, int y, int w, int h,
487	int skipleft)
488{
489	CirPtr pCir = CIRPTR(pScrn);
490	AlpPtr pAlp = ALPPTR(pCir);
491
492	int pitch = pCir->pitch;
493
494	pAlp->SubsequentColorExpandScanlineByteWidth =
495	  (w * pScrn->bitsPerPixel / 8) - 1;
496	pAlp->SubsequentColorExpandScanlineDWordWidth =
497	  (w + 31) >> 5;
498	pAlp->SubsequentColorExpandScanlineDest =
499	  y * pitch + x * pScrn->bitsPerPixel / 8;
500
501#ifdef ALP_DEBUG
502	ErrorF("AlpSubsequentScanlineCPUToScreenColorExpandFill x=%d y=%d w=%d h=%d skipleft=%d\n",
503			x, y, w, h, skipleft);
504#endif
505}
506
507static void
508AlpSubsequentColorExpandScanline(
509	ScrnInfoPtr pScrn,
510	int bufno)
511{
512        CirPtr pCir = CIRPTR(pScrn);
513	AlpPtr pAlp = ALPPTR(pCir);
514	int dest=pAlp->SubsequentColorExpandScanlineDest;
515	int ww=pAlp->SubsequentColorExpandScanlineByteWidth;
516	int width=pAlp->SubsequentColorExpandScanlineDWordWidth;
517	CARD32* from;
518	volatile CARD32 *to;
519
520#ifdef ALP_DEBUG
521	ErrorF("AlpSubsequentColorExpandScanline\n");
522#endif
523
524	pAlp->SubsequentColorExpandScanlineDest += pCir->pitch;
525
526	to   = (CARD32*) pCir->FbBase;
527	from = (CARD32*) (pCir->ScanlineColorExpandBuffers[bufno]);
528	WAIT_1;
529
530	/* Width */
531	outw(pCir->PIOReg, ((ww << 8) & 0xff00) | 0x20);
532	outw(pCir->PIOReg, ((ww) & 0x1f00) | 0x21);
533
534	/* Height = 1 */
535	outw(pCir->PIOReg, 0x22);
536	outw(pCir->PIOReg, 0x23);
537
538	/* source = CPU ; description of bit 2 of GR30 in the 7548 manual
539	   says that if we do color expansion we must zero the source
540	   address registers (GR2C, GR2D, GR2E) */
541	outw(pCir->PIOReg, 0x2C);
542	outw(pCir->PIOReg, 0x2D);
543	outw(pCir->PIOReg, 0x2E);
544
545	/* dest */
546	outw(pCir->PIOReg, ((dest << 8) & 0xff00) | 0x28);
547	outw(pCir->PIOReg, ((dest) & 0xff00) | 0x29);
548	write_mem_barrier();
549
550#ifdef ALP_DEBUG
551	ErrorF("AlpSubsequentColorExpandScanline (2)\n");
552#endif
553
554	outw(pCir->PIOReg, ((dest >> 8) & 0x3f00) | 0x2A);
555	if (!pCir->chip.alp->autoStart)
556	  outw(pCir->PIOReg, 0x0231);
557
558	{
559	  int i;
560	  for (i=0; i<width; i++)
561	    *to=*(from++);
562	  write_mem_barrier();
563	}
564
565#ifdef ALP_DEBUG
566	ErrorF("AlpSubsequentColorExpandScanline (3)\n");
567#endif
568}
569#endif
570
571static void
572AlpAccelEngineInit(ScrnInfoPtr pScrn)
573{
574    CirPtr pCir = CIRPTR(pScrn);
575
576    outw(pCir->PIOReg, 0x200E); /* enable writes to gr33 */
577    /* Setup things for autostart */
578    if (pCir->properties & ACCEL_AUTOSTART) {
579        outw(pCir->PIOReg, 0x8031); /* enable autostart */
580	pCir->chip.alp->waitMsk = 0x10;
581	pCir->chip.alp->autoStart = TRUE;
582    } else {
583        pCir->chip.alp->waitMsk = 0x1;
584	pCir->chip.alp->autoStart = FALSE;
585    }
586}
587
588Bool
589AlpXAAInit(ScreenPtr pScreen)
590{
591    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
592    CirPtr pCir = CIRPTR(pScrn);
593    AlpPtr pAlp = ALPPTR(pCir);
594    XAAInfoRecPtr XAAPtr;
595
596    pCir->InitAccel =  AlpAccelEngineInit;
597#ifdef ALP_DEBUG
598    ErrorF("AlpXAAInit\n");
599#endif
600
601    XAAPtr = XAACreateInfoRec();
602    if (!XAAPtr) return FALSE;
603
604    /* Pixmap cache */
605    XAAPtr->Flags |= LINEAR_FRAMEBUFFER;
606    XAAPtr->Sync = AlpSync;
607
608    XAAPtr->SetupForScreenToScreenCopy = AlpSetupForScreenToScreenCopy;
609    XAAPtr->SubsequentScreenToScreenCopy = AlpSubsequentScreenToScreenCopy;
610    XAAPtr->ScreenToScreenCopyFlags =
611        NO_TRANSPARENCY | NO_PLANEMASK;
612
613    XAAPtr->SetupForSolidFill = AlpSetupForSolidFill;
614    XAAPtr->SubsequentSolidFillRect = AlpSubsequentSolidFillRect;
615    XAAPtr->SubsequentSolidFillTrap = NULL;
616    XAAPtr->SolidFillFlags = NO_PLANEMASK;
617
618    if (pCir->Chipset == PCI_CHIP_GD7548) {
619        if (pAlp->monoPattern8x8) {
620	    XAAPtr->SetupForMono8x8PatternFill
621	        = AlpSetupForMono8x8PatternFill;
622	    XAAPtr->SubsequentMono8x8PatternFillRect
623	        = AlpSubsequentMono8x8PatternFillRect;
624	    XAAPtr->SubsequentMono8x8PatternFillTrap = NULL;
625	    XAAPtr->Mono8x8PatternFillFlags =
626	        NO_PLANEMASK |
627		HARDWARE_PATTERN_PROGRAMMED_BITS | BIT_ORDER_IN_BYTE_MSBFIRST;
628	}
629#if 1
630	/* kludge: since XF86 does not support byte-padded
631	   mono bitmaps (only dword-padded), use the
632	   scanline version */
633	XAAPtr->SetupForScanlineCPUToScreenColorExpandFill =
634	    AlpSetupForScanlineCPUToScreenColorExpandFill;
635	XAAPtr->SubsequentScanlineCPUToScreenColorExpandFill =
636	    AlpSubsequentScanlineCPUToScreenColorExpandFill;
637	XAAPtr->SubsequentColorExpandScanline =
638	    AlpSubsequentColorExpandScanline;
639	{
640	  const int NumScanlineColorExpandBuffers = 2;
641	  int i;
642	  int buffer_size = (pCir->pScrn->virtualX + 31) & ~31;
643#ifdef ALP_DEBUG
644	  ErrorF("Computing buffers for %d pixel lines\n",
645		 pCir->pScrn->virtualX);
646#endif
647	  XAAPtr->NumScanlineColorExpandBuffers =
648	      NumScanlineColorExpandBuffers;
649	  XAAPtr->ScanlineColorExpandBuffers =
650	      pCir->ScanlineColorExpandBuffers = (unsigned char **)
651	      (malloc(sizeof(unsigned char *) *
652		      NumScanlineColorExpandBuffers));
653	    /* TODO: are those mallocs to be freed ? */
654
655	  for(i=0; i<NumScanlineColorExpandBuffers; i++)
656	      pCir->ScanlineColorExpandBuffers[i] = (unsigned char *)
657		malloc(buffer_size);
658	}
659	XAAPtr->ScanlineCPUToScreenColorExpandFillFlags =
660	    NO_PLANEMASK | BIT_ORDER_IN_BYTE_MSBFIRST |
661	    SCANLINE_PAD_DWORD | ROP_NEEDS_SOURCE;
662#endif
663#if 0
664	/* Currently disabled: XF86 sends DWORD-padded data,
665	   not byte-padded */
666	XAAPtr->SetupForCPUToScreenColorExpandFill =
667	  AlpSetupForCPUToScreenColorExpandFill;
668	XAAPtr->SubsequentCPUToScreenColorExpandFill =
669	  AlpSubsequentCPUToScreenColorExpandFill;
670	XAAPtr->ColorExpandBase = pCir->FbBase + 4;
671	XAAPtr->CPUToScreenColorExpandFillFlags =
672	  NO_PLANEMASK | BIT_ORDER_IN_BYTE_MSBFIRST |
673	  SCANLINE_PAD_DWORD | ROP_NEEDS_SOURCE |
674	  CPU_TRANSFER_PAD_DWORD | CPU_TRANSFER_BASE_FIXED;
675#endif
676    }
677
678    AlpAccelEngineInit(pScrn);
679
680    pCir->AccelInfoRec = XAAPtr;
681
682    if (!XAAInit(pScreen, XAAPtr))
683        return FALSE;
684
685    return TRUE;
686}
687#endif
688