1 /*
2 * Copyright 1992-2003 by Alan Hourihane, North Wales, UK.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
13 *
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
23 *
24 * CyberBladeXP4 accelerated options.
25 */
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "xf86.h"
31 #include "xf86_OSproc.h"
32
33 #include "xf86Pci.h"
34
35 #include "miline.h"
36
37 #include "trident.h"
38 #include "trident_regs.h"
39
40 #ifdef HAVE_XAA_H
41 #include "xaarop.h"
42
43 static void XP4Sync(ScrnInfoPtr pScrn);
44 #if 0
45 static void XP4SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg,
46 int rop, unsigned int planemask, int length,
47 unsigned char *pattern);
48 static void XP4SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
49 int x, int y, int dmaj, int dmin, int e,
50 int len, int octant, int phase);
51 static void XP4SetupForSolidLine(ScrnInfoPtr pScrn, int color,
52 int rop, unsigned int planemask);
53 static void XP4SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
54 int x, int y, int dmaj, int dmin, int e,
55 int len, int octant);
56 #endif
57 static void XP4SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y,
58 int len, int dir);
59 static void XP4SetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
60 int rop, unsigned int planemask);
61 static void XP4SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
62 int y, int w, int h);
63 static void XP4SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
64 int x1, int y1, int x2,
65 int y2, int w, int h);
66 static void XP4SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
67 int xdir, int ydir, int rop,
68 unsigned int planemask,
69 int transparency_color);
70 static void XP4SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
71 int patternx, int patterny, int fg, int bg,
72 int rop, unsigned int planemask);
73 static void XP4SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
74 int patternx, int patterny, int x, int y,
75 int w, int h);
76 static void XP4SetupForCPUToScreenColorExpandFill(
77 ScrnInfoPtr pScrn,
78 int fg, int bg, int rop,
79 unsigned int planemask);
80 static void XP4SubsequentCPUToScreenColorExpandFill(
81 ScrnInfoPtr pScrn, int x,
82 int y, int w, int h, int skipleft);
83
84 static int bpp;
85 static int ropcode;
86
87 static void
XP4InitializeAccelerator(ScrnInfoPtr pScrn)88 XP4InitializeAccelerator(ScrnInfoPtr pScrn)
89 {
90 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
91 int shift;
92
93 /* This forces updating the clipper */
94 pTrident->Clipping = TRUE;
95
96 CHECKCLIPPING;
97
98 switch (pScrn->bitsPerPixel) {
99 case 8:
100 default: /* Muffle compiler */
101 shift = 18;
102 break;
103 case 16:
104 shift = 19;
105 break;
106 case 32:
107 shift = 20;
108 break;
109 }
110
111 switch (pScrn->bitsPerPixel) {
112 case 8:
113 bpp = 0x40;
114 break;
115 case 16:
116 bpp = 0x41;
117 break;
118 case 32:
119 bpp = 0x42;
120 break;
121 }
122 MMIO_OUT32(pTrident->IOBase, 0x2154, (pScrn->displayWidth) << shift);
123 MMIO_OUT32(pTrident->IOBase, 0x2150, (pScrn->displayWidth) << shift);
124 }
125 #endif
126
127 Bool
XP4XaaInit(ScreenPtr pScreen)128 XP4XaaInit(ScreenPtr pScreen)
129 {
130 #ifdef HAVE_XAA_H
131 XAAInfoRecPtr infoPtr;
132 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
133 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
134
135 if (pTrident->NoAccel)
136 return FALSE;
137
138 pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
139 if (!infoPtr) return FALSE;
140
141 infoPtr->Flags = PIXMAP_CACHE |
142 OFFSCREEN_PIXMAPS |
143 LINEAR_FRAMEBUFFER;
144
145 pTrident->InitializeAccelerator = XP4InitializeAccelerator;
146 XP4InitializeAccelerator(pScrn);
147
148 infoPtr->Sync = XP4Sync;
149
150 #if 0 /* TO DO for the XP */
151 infoPtr->SolidLineFlags = NO_PLANEMASK;
152 infoPtr->SetupForSolidLine = XP4SetupForSolidLine;
153 infoPtr->SolidBresenhamLineErrorTermBits = 12;
154 infoPtr->SubsequentSolidBresenhamLine = XP4SubsequentSolidBresenhamLine;
155
156 infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED |
157 NO_PLANEMASK |
158 LINE_PATTERN_POWER_OF_2_ONLY;
159 infoPtr->SetupForDashedLine = XP4SetupForDashedLine;
160 infoPtr->DashedBresenhamLineErrorTermBits = 12;
161 infoPtr->SubsequentDashedBresenhamLine =
162 XP4SubsequentDashedBresenhamLine;
163 infoPtr->DashPatternMaxLength = 16;
164 #endif
165
166
167 infoPtr->SolidFillFlags = NO_PLANEMASK;
168 infoPtr->SetupForSolidFill = XP4SetupForFillRectSolid;
169 infoPtr->SubsequentSolidFillRect = XP4SubsequentFillRectSolid;
170 #if 0
171 infoPtr->SubsequentSolidHorVertLine = XP4SubsequentSolidHorVertLine;
172 #endif
173
174 infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
175
176 infoPtr->SetupForScreenToScreenCopy =
177 XP4SetupForScreenToScreenCopy;
178 infoPtr->SubsequentScreenToScreenCopy =
179 XP4SubsequentScreenToScreenCopy;
180
181 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
182 HARDWARE_PATTERN_PROGRAMMED_BITS |
183 HARDWARE_PATTERN_SCREEN_ORIGIN |
184 BIT_ORDER_IN_BYTE_MSBFIRST;
185
186 infoPtr->SetupForMono8x8PatternFill =
187 XP4SetupForMono8x8PatternFill;
188 infoPtr->SubsequentMono8x8PatternFillRect =
189 XP4SubsequentMono8x8PatternFillRect;
190
191 #if 0
192 infoPtr->CPUToScreenColorExpandFillFlags = NO_PLANEMASK |
193 BIT_ORDER_IN_BYTE_MSBFIRST;
194 infoPtr->ColorExpandBase = pTrident->D3Base;
195 infoPtr->ColorExpandRange = pScrn->displayWidth;
196
197 infoPtr->SetupForCPUToScreenColorExpandFill =
198 XP4SetupForCPUToScreenColorExpandFill;
199 infoPtr->SubsequentCPUToScreenColorExpandFill =
200 XP4SubsequentCPUToScreenColorExpandFill;
201 #endif
202
203 return(XAAInit(pScreen, infoPtr));
204 #else
205 return FALSE;
206 #endif
207 }
208
209 #ifdef HAVE_XAA_H
210 static void
XP4Sync(ScrnInfoPtr pScrn)211 XP4Sync(ScrnInfoPtr pScrn)
212 {
213 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
214 int count = 0, timeout = 0;
215 int busy;
216
217 for (;;) {
218 BLTBUSY(busy);
219 if (busy != GE_BUSY) {
220 return;
221 }
222 count++;
223 if (count == 10000000) {
224 ErrorF("XP: BitBLT engine time-out.\n");
225 count = 9990000;
226 timeout++;
227 if (timeout == 4) {
228 /* Reset BitBLT Engine */
229 TGUI_STATUS(0x00);
230 return;
231 }
232 }
233 }
234 }
235
236 static void
XP4SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,int xdir,int ydir,int rop,unsigned int planemask,int transparency_color)237 XP4SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
238 int xdir, int ydir, int rop,
239 unsigned int planemask, int transparency_color)
240 {
241 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
242 int dst = 0;
243
244 pTrident->BltScanDirection = 0;
245 if (xdir < 0) pTrident->BltScanDirection |= XNEG;
246 if (ydir < 0) pTrident->BltScanDirection |= YNEG;
247
248 REPLICATE(transparency_color);
249 if (transparency_color != -1) {
250 dst |= 3<<16;
251 MMIO_OUT32(pTrident->IOBase, 0x2134, transparency_color);
252 }
253
254 ropcode = rop;
255
256 MMIO_OUT32(pTrident->IOBase, 0x2128, pTrident->BltScanDirection | SCR2SCR);
257 }
258
259 static void
XP4SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,int x1,int y1,int x2,int y2,int w,int h)260 XP4SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
261 int x2, int y2, int w, int h)
262 {
263 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
264
265 if (pTrident->BltScanDirection & YNEG) {
266 y1 = y1 + h - 1;
267 y2 = y2 + h - 1;
268 }
269 if (pTrident->BltScanDirection & XNEG) {
270 x1 = x1 + w - 1;
271 x2 = x2 + w - 1;
272 }
273 MMIO_OUT32(pTrident->IOBase, 0x2138, x2<<16 | y2);
274 MMIO_OUT32(pTrident->IOBase, 0x213C, x1<<16 | y1);
275 MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h);
276 XP4Sync(pScrn);
277 MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetCopyROP(ropcode) << 24 | bpp << 8 | 1);
278 }
279
280 #if 0
281 static void
282 XP4SetupForSolidLine(ScrnInfoPtr pScrn, int color,
283 int rop, unsigned int planemask)
284 {
285 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
286
287 pTrident->BltScanDirection = 0;
288 REPLICATE(color);
289 TGUI_FMIX(XAAPatternROP[rop]);
290 if (pTrident->Chipset >= PROVIDIA9685) {
291 TGUI_FPATCOL(color);
292 } else {
293 TGUI_FCOLOUR(color);
294 }
295 }
296
297 static void
298 XP4SubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
299 int x, int y, int dmaj, int dmin, int e, int len, int octant)
300 {
301 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
302 int tmp = pTrident->BltScanDirection;
303
304 if (octant & YMAJOR) tmp |= YMAJ;
305 if (octant & XDECREASING) tmp |= XNEG;
306 if (octant & YDECREASING) tmp |= YNEG;
307 TGUI_DRAWFLAG(SOLIDFILL | STENCIL | tmp);
308 XP_SRC_XY(dmin-dmaj,dmin);
309 XP_DEST_XY(x,y);
310 XP_DIM_XY(dmin+e,len);
311 TGUI_COMMAND(GE_BRESLINE);
312 XP4Sync(pScrn);
313 }
314 #endif
315
316 static void
XP4SubsequentSolidHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)317 XP4SubsequentSolidHorVertLine(
318 ScrnInfoPtr pScrn,
319 int x, int y,
320 int len, int dir
321 ){
322 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
323
324 TGUI_DRAWFLAG(SOLIDFILL);
325 if (dir == DEGREES_0) {
326 XP_DIM_XY(len,1);
327 XP_DEST_XY(x,y);
328 } else {
329 XP_DIM_XY(1,len);
330 XP_DEST_XY(x,y);
331 }
332 TGUI_COMMAND(GE_BLT);
333 XP4Sync(pScrn);
334 }
335
336 #if 0
337 void
338 XP4SetupForDashedLine(
339 ScrnInfoPtr pScrn,
340 int fg, int bg, int rop,
341 unsigned int planemask,
342 int length,
343 unsigned char *pattern
344 ){
345 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
346 CARD32 *DashPattern = (CARD32*)pattern;
347 CARD32 NiceDashPattern = DashPattern[0];
348
349 NiceDashPattern = *((CARD16 *)pattern) & ((1<<length) - 1);
350 switch(length) {
351 case 2: NiceDashPattern |= NiceDashPattern << 2;
352 case 4: NiceDashPattern |= NiceDashPattern << 4;
353 case 8: NiceDashPattern |= NiceDashPattern << 8;
354 }
355 pTrident->BltScanDirection = 0;
356 REPLICATE(fg);
357 if (pTrident->Chipset >= PROVIDIA9685) {
358 TGUI_FPATCOL(fg);
359 if (bg == -1) {
360 pTrident->BltScanDirection |= 1<<12;
361 TGUI_BPATCOL(~fg);
362 } else {
363 REPLICATE(bg);
364 TGUI_BPATCOL(bg);
365 }
366 } else {
367 TGUI_FCOLOUR(fg);
368 if (bg == -1) {
369 pTrident->BltScanDirection |= 1<<12;
370 TGUI_BCOLOUR(~fg);
371 } else {
372 REPLICATE(bg);
373 TGUI_BCOLOUR(bg);
374 }
375 }
376 TGUI_FMIX(XAAPatternROP[rop]);
377 pTrident->LinePattern = NiceDashPattern;
378 }
379
380 void
381 XP4SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
382 int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase)
383 {
384 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
385 int tmp = pTrident->BltScanDirection;
386
387 if (octant & YMAJOR) tmp |= YMAJ;
388 if (octant & XDECREASING) tmp |= XNEG;
389 if (octant & YDECREASING) tmp |= YNEG;
390
391 TGUI_STYLE(((pTrident->LinePattern >> phase) |
392 (pTrident->LinePattern << (16-phase))) & 0x0000FFFF);
393 TGUI_DRAWFLAG(STENCIL | tmp);
394 XP_SRC_XY(dmin-dmaj,dmin);
395 XP_DEST_XY(x,y);
396 XP_DIM_XY(e+dmin,len);
397 TGUI_COMMAND(GE_BRESLINE);
398 XP4Sync(pScrn);
399 }
400 #endif
401
402 static void
XP4SetupForFillRectSolid(ScrnInfoPtr pScrn,int color,int rop,unsigned int planemask)403 XP4SetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
404 int rop, unsigned int planemask)
405 {
406 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
407
408 ropcode = rop;
409
410 REPLICATE(color);
411 MMIO_OUT32(pTrident->IOBase, 0x2158, color);
412 MMIO_OUT32(pTrident->IOBase, 0x2128, 1<<14);
413 }
414
415 static void
XP4SubsequentFillRectSolid(ScrnInfoPtr pScrn,int x,int y,int w,int h)416 XP4SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
417 {
418 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
419
420 MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y);
421 MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h);
422 XP4Sync(pScrn);
423 MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetPatternROP(ropcode) << 24 | bpp << 8 | 2);
424 }
425
426 #if 1
MoveDWORDS(register CARD32 * dest,register CARD32 * src,register int dwords)427 static void MoveDWORDS(
428 register CARD32* dest,
429 register CARD32* src,
430 register int dwords )
431 {
432 while(dwords & ~0x03) {
433 *dest = *src;
434 *(dest + 1) = *(src + 1);
435 *(dest + 2) = *(src + 2);
436 *(dest + 3) = *(src + 3);
437 src += 4;
438 dest += 4;
439 dwords -= 4;
440 }
441 if (!dwords) return;
442 *dest = *src;
443 dest += 1;
444 src += 1;
445 if (dwords == 1) return;
446 *dest = *src;
447 dest += 1;
448 src += 1;
449 if (dwords == 2) return;
450 *dest = *src;
451 dest += 1;
452 src += 1;
453 }
454 #endif
455
456 #if 1
MoveDWORDS_FixedBase(register CARD32 * dest,register CARD32 * src,register int dwords)457 static void MoveDWORDS_FixedBase(
458 register CARD32* dest,
459 register CARD32* src,
460 register int dwords )
461 {
462 while(dwords & ~0x03) {
463 *dest = *src;
464 *dest = *(src + 1);
465 *dest = *(src + 2);
466 *dest = *(src + 3);
467 dwords -= 4;
468 src += 4;
469 }
470
471 if(!dwords) return;
472 *dest = *src;
473 if(dwords == 1) return;
474 *dest = *(src + 1);
475 if(dwords == 2) return;
476 *dest = *(src + 2);
477 }
478 #endif
479
480
481 static void
XP4SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,int patternx,int patterny,int fg,int bg,int rop,unsigned int planemask)482 XP4SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
483 int patternx, int patterny,
484 int fg, int bg, int rop,
485 unsigned int planemask)
486 {
487 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
488 int drawflag = 0;
489
490 REPLICATE(fg);
491 MMIO_OUT32(pTrident->IOBase, 0x2158, fg);
492
493 if (bg == -1) {
494 drawflag |= 1<<12;
495 MMIO_OUT32(pTrident->IOBase, 0x215C, ~fg);
496 } else {
497 REPLICATE(bg);
498 MMIO_OUT32(pTrident->IOBase, 0x215C, bg);
499 }
500
501 ropcode = rop;
502
503 drawflag |= 7<<18;
504 TGUI_DRAWFLAG(PATMONO | drawflag);
505 }
506
507 static void
XP4SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,int patternx,int patterny,int x,int y,int w,int h)508 XP4SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
509 int patternx, int patterny,
510 int x, int y,
511 int w, int h)
512 {
513 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
514
515 MMIO_OUT32(pTrident->IOBase, 0x2180, patternx);
516 MMIO_OUT32(pTrident->IOBase, 0x2184, patterny);
517 MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y);
518 MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h);
519 XP4Sync(pScrn);
520 MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetPatternROP(ropcode) << 24 | bpp << 8 | 2);
521 }
522
523 #if 1
524 static void
XP4SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,int fg,int bg,int rop,unsigned int planemask)525 XP4SetupForCPUToScreenColorExpandFill(
526 ScrnInfoPtr pScrn,
527 int fg, int bg,
528 int rop,
529 unsigned int planemask
530 ){
531 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
532
533 ropcode = XAAGetCopyROP(rop);
534 #if 0
535 TGUI_FMIX(XAACopyROP[rop]);
536 #endif
537 if (bg == -1) {
538 TGUI_DRAWFLAG(SRCMONO | 1<<12);
539 REPLICATE(fg);
540 TGUI_FCOLOUR(fg);
541 } else {
542 TGUI_DRAWFLAG(SRCMONO);
543 REPLICATE(fg);
544 REPLICATE(bg);
545 TGUI_FCOLOUR(fg);
546 TGUI_BCOLOUR(bg);
547 }
548 }
549
550 static void
XP4SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,int x,int y,int w,int h,int skipleft)551 XP4SubsequentCPUToScreenColorExpandFill(
552 ScrnInfoPtr pScrn,
553 int x, int y, int w, int h,
554 int skipleft
555 ){
556 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
557
558 MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y);
559 MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h);
560 XP4Sync(pScrn);
561 MMIO_OUT32(pTrident->IOBase, 0x2124, ropcode << 24 | bpp << 8 | 2);
562 }
563 #endif
564 #endif
565