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 * BladeXP accelerated options.
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "xf86.h"
32 #include "xf86_OSproc.h"
33
34 #include "xf86Pci.h"
35
36 #include "miline.h"
37
38 #include "trident.h"
39 #include "trident_regs.h"
40
41 #ifdef HAVE_XAA_H
42 #include "xaarop.h"
43
44 static void XPSync(ScrnInfoPtr pScrn);
45 #if 0
46 static void XPSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg,
47 int rop, unsigned int planemask, int length,
48 unsigned char *pattern);
49 static void XPSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
50 int x, int y, int dmaj, int dmin, int e,
51 int len, int octant, int phase);
52 static void XPSetupForSolidLine(ScrnInfoPtr pScrn, int color,
53 int rop, unsigned int planemask);
54 static void XPSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
55 int x, int y, int dmaj, int dmin, int e,
56 int len, int octant);
57 #endif
58 static void XPSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y,
59 int len, int dir);
60 static void XPSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
61 int rop, unsigned int planemask);
62 static void XPSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
63 int y, int w, int h);
64 static void XPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
65 int x1, int y1, int x2,
66 int y2, int w, int h);
67 static void XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
68 int xdir, int ydir, int rop,
69 unsigned int planemask,
70 int transparency_color);
71 static void XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
72 int patternx, int patterny, int fg, int bg,
73 int rop, unsigned int planemask);
74 static void XPSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
75 int patternx, int patterny, int x, int y,
76 int w, int h);
77 #if 0
78 static void XPSetupForScanlineCPUToScreenColorExpandFill(
79 ScrnInfoPtr pScrn,
80 int fg, int bg, int rop,
81 unsigned int planemask);
82 static void XPSubsequentScanlineCPUToScreenColorExpandFill(
83 ScrnInfoPtr pScrn, int x,
84 int y, int w, int h, int skipleft);
85 static void XPSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
86 #endif
87
88 static void
XPInitializeAccelerator(ScrnInfoPtr pScrn)89 XPInitializeAccelerator(ScrnInfoPtr pScrn)
90 {
91 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
92 int shift;
93
94 /* This forces updating the clipper */
95 pTrident->Clipping = TRUE;
96
97 CHECKCLIPPING;
98
99 BLADE_XP_OPERMODE(pTrident->EngineOperation);
100 pTrident->EngineOperation |= 0x40;
101 switch (pScrn->bitsPerPixel) {
102 case 8:
103 default: /* Muffle compiler */
104 shift = 18;
105 break;
106 case 16:
107 shift = 19;
108 break;
109 case 32:
110 shift = 20;
111 break;
112 }
113 MMIO_OUT32(pTrident->IOBase, 0x2154, (pScrn->displayWidth) << shift);
114 MMIO_OUT32(pTrident->IOBase, 0x2150, (pScrn->displayWidth) << shift);
115 MMIO_OUT8(pTrident->IOBase, 0x2126, 3);
116 }
117 #endif
118
119 Bool
XPAccelInit(ScreenPtr pScreen)120 XPAccelInit(ScreenPtr pScreen)
121 {
122 #ifdef HAVE_XAA_H
123 XAAInfoRecPtr infoPtr;
124 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
125 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
126
127 if (pTrident->NoAccel)
128 return FALSE;
129
130 pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
131 if (!infoPtr) return FALSE;
132
133 infoPtr->Flags = PIXMAP_CACHE |
134 OFFSCREEN_PIXMAPS |
135 LINEAR_FRAMEBUFFER;
136
137 pTrident->InitializeAccelerator = XPInitializeAccelerator;
138 XPInitializeAccelerator(pScrn);
139
140 infoPtr->Sync = XPSync;
141
142 #if 0 /* TO DO for the XP */
143 infoPtr->SolidLineFlags = NO_PLANEMASK;
144 infoPtr->SetupForSolidLine = XPSetupForSolidLine;
145 infoPtr->SolidBresenhamLineErrorTermBits = 12;
146 infoPtr->SubsequentSolidBresenhamLine = XPSubsequentSolidBresenhamLine;
147
148 infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED |
149 NO_PLANEMASK |
150 LINE_PATTERN_POWER_OF_2_ONLY;
151 infoPtr->SetupForDashedLine = XPSetupForDashedLine;
152 infoPtr->DashedBresenhamLineErrorTermBits = 12;
153 infoPtr->SubsequentDashedBresenhamLine =
154 XPSubsequentDashedBresenhamLine;
155 infoPtr->DashPatternMaxLength = 16;
156 #endif
157
158 infoPtr->SolidFillFlags = NO_PLANEMASK;
159 infoPtr->SetupForSolidFill = XPSetupForFillRectSolid;
160 infoPtr->SubsequentSolidFillRect = XPSubsequentFillRectSolid;
161 infoPtr->SubsequentSolidHorVertLine = XPSubsequentSolidHorVertLine;
162
163 infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
164
165 infoPtr->SetupForScreenToScreenCopy =
166 XPSetupForScreenToScreenCopy;
167 infoPtr->SubsequentScreenToScreenCopy =
168 XPSubsequentScreenToScreenCopy;
169
170 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
171 HARDWARE_PATTERN_PROGRAMMED_BITS |
172 BIT_ORDER_IN_BYTE_MSBFIRST;
173
174 infoPtr->SetupForMono8x8PatternFill =
175 XPSetupForMono8x8PatternFill;
176 infoPtr->SubsequentMono8x8PatternFillRect =
177 XPSubsequentMono8x8PatternFillRect;
178
179 #if 0 /* Needs fixing */
180 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
181 BIT_ORDER_IN_BYTE_MSBFIRST;
182
183 pTrident->XAAScanlineColorExpandBuffers[0] =
184 xnfalloc(((pScrn->virtualX + 63)) *4* (pScrn->bitsPerPixel / 8));
185
186 infoPtr->NumScanlineColorExpandBuffers = 1;
187 infoPtr->ScanlineColorExpandBuffers =
188 pTrident->XAAScanlineColorExpandBuffers;
189
190 infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
191 XPSetupForScanlineCPUToScreenColorExpandFill;
192 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
193 XPSubsequentScanlineCPUToScreenColorExpandFill;
194 infoPtr->SubsequentColorExpandScanline =
195 XPSubsequentColorExpandScanline;
196 #endif
197
198 return(XAAInit(pScreen, infoPtr));
199 #else
200 return FALSE;
201 #endif
202 }
203
204 #ifdef HAVE_XAA_H
205 static void
XPSync(ScrnInfoPtr pScrn)206 XPSync(ScrnInfoPtr pScrn)
207 {
208 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
209 int count = 0, timeout = 0;
210 int busy;
211
212 BLADE_XP_OPERMODE(pTrident->EngineOperation);
213
214 for (;;) {
215 BLTBUSY(busy);
216 if (busy != GE_BUSY) {
217 return;
218 }
219 count++;
220 if (count == 10000000) {
221 ErrorF("XP: BitBLT engine time-out.\n");
222 count = 9990000;
223 timeout++;
224 if (timeout == 8) {
225 /* Reset BitBLT Engine */
226 TGUI_STATUS(0x00);
227 return;
228 }
229 }
230 }
231 }
232
233 static void
XPClearSync(ScrnInfoPtr pScrn)234 XPClearSync(ScrnInfoPtr pScrn)
235 {
236 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
237 int count = 0, timeout = 0;
238 int busy;
239
240 for (;;) {
241 BLTBUSY(busy);
242 if (busy != GE_BUSY) {
243 return;
244 }
245 count++;
246 if (count == 10000000) {
247 ErrorF("XP: BitBLT engine time-out.\n");
248 count = 9990000;
249 timeout++;
250 if (timeout == 8) {
251 /* Reset BitBLT Engine */
252 TGUI_STATUS(0x00);
253 return;
254 }
255 }
256 }
257 }
258
259 static void
XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,int xdir,int ydir,int rop,unsigned int planemask,int transparency_color)260 XPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
261 int xdir, int ydir, int rop,
262 unsigned int planemask, int transparency_color)
263 {
264 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
265 int dst = 0;
266
267 pTrident->BltScanDirection = 0;
268 if (xdir < 0) pTrident->BltScanDirection |= XNEG;
269 if (ydir < 0) pTrident->BltScanDirection |= YNEG;
270
271 REPLICATE(transparency_color);
272 if (transparency_color != -1) {
273 dst |= 3<<16;
274 MMIO_OUT32(pTrident->IOBase, 0x2134, transparency_color);
275 }
276
277 TGUI_DRAWFLAG(pTrident->BltScanDirection | SCR2SCR | dst);
278 TGUI_FMIX(XAAGetCopyROP(rop));
279 }
280
281 static void
XPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,int x1,int y1,int x2,int y2,int w,int h)282 XPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
283 int x2, int y2, int w, int h)
284 {
285 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
286
287 if (pTrident->BltScanDirection & YNEG) {
288 y1 = y1 + h - 1;
289 y2 = y2 + h - 1;
290 }
291 if (pTrident->BltScanDirection & XNEG) {
292 x1 = x1 + w - 1;
293 x2 = x2 + w - 1;
294 }
295 XP_SRC_XY(x1,y1);
296 XP_DEST_XY(x2,y2);
297 XP_DIM_XY(w,h);
298 TGUI_COMMAND(GE_BLT);
299 XPClearSync(pScrn);
300 }
301
302 #if 0
303 static void
304 XPSetupForSolidLine(ScrnInfoPtr pScrn, int color,
305 int rop, unsigned int planemask)
306 {
307 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
308
309 pTrident->BltScanDirection = 0;
310 REPLICATE(color);
311 TGUI_FMIX(XAAGetPatternROP(rop));
312 if (pTrident->Chipset >= PROVIDIA9685) {
313 TGUI_FPATCOL(color);
314 } else {
315 TGUI_FCOLOUR(color);
316 }
317 }
318
319 static void
320 XPSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
321 int x, int y, int dmaj, int dmin, int e, int len, int octant)
322 {
323 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
324 int tmp = pTrident->BltScanDirection;
325
326 if (octant & YMAJOR) tmp |= YMAJ;
327 if (octant & XDECREASING) tmp |= XNEG;
328 if (octant & YDECREASING) tmp |= YNEG;
329 TGUI_DRAWFLAG(SOLIDFILL | STENCIL | tmp);
330 XP_SRC_XY(dmin-dmaj,dmin);
331 XP_DEST_XY(x,y);
332 XP_DIM_XY(dmin+e,len);
333 TGUI_COMMAND(GE_BRESLINE);
334 XPSync(pScrn);
335 }
336 #endif
337
338 static void
XPSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)339 XPSubsequentSolidHorVertLine(
340 ScrnInfoPtr pScrn,
341 int x, int y,
342 int len, int dir
343 ){
344 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
345
346 TGUI_DRAWFLAG(SOLIDFILL);
347 if (dir == DEGREES_0) {
348 XP_DIM_XY(len,1);
349 XP_DEST_XY(x,y);
350 } else {
351 XP_DIM_XY(1,len);
352 XP_DEST_XY(x,y);
353 }
354 TGUI_COMMAND(GE_BLT);
355 XPSync(pScrn);
356 }
357
358 #if 0
359 void
360 XPSetupForDashedLine(
361 ScrnInfoPtr pScrn,
362 int fg, int bg, int rop,
363 unsigned int planemask,
364 int length,
365 unsigned char *pattern
366 ){
367 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
368 CARD32 *DashPattern = (CARD32*)pattern;
369 CARD32 NiceDashPattern = DashPattern[0];
370
371 NiceDashPattern = *((CARD16 *)pattern) & ((1<<length) - 1);
372 switch(length) {
373 case 2: NiceDashPattern |= NiceDashPattern << 2;
374 case 4: NiceDashPattern |= NiceDashPattern << 4;
375 case 8: NiceDashPattern |= NiceDashPattern << 8;
376 }
377 pTrident->BltScanDirection = 0;
378 REPLICATE(fg);
379 if (pTrident->Chipset >= PROVIDIA9685) {
380 TGUI_FPATCOL(fg);
381 if (bg == -1) {
382 pTrident->BltScanDirection |= 1<<12;
383 TGUI_BPATCOL(~fg);
384 } else {
385 REPLICATE(bg);
386 TGUI_BPATCOL(bg);
387 }
388 } else {
389 TGUI_FCOLOUR(fg);
390 if (bg == -1) {
391 pTrident->BltScanDirection |= 1<<12;
392 TGUI_BCOLOUR(~fg);
393 } else {
394 REPLICATE(bg);
395 TGUI_BCOLOUR(bg);
396 }
397 }
398 TGUI_FMIX(XAAGetPatternROP(rop));
399 pTrident->LinePattern = NiceDashPattern;
400 }
401
402 void
403 XPSubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
404 int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase)
405 {
406 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
407 int tmp = pTrident->BltScanDirection;
408
409 if (octant & YMAJOR) tmp |= YMAJ;
410 if (octant & XDECREASING) tmp |= XNEG;
411 if (octant & YDECREASING) tmp |= YNEG;
412
413 TGUI_STYLE(((pTrident->LinePattern >> phase) |
414 (pTrident->LinePattern << (16-phase))) & 0x0000FFFF);
415 TGUI_DRAWFLAG(STENCIL | tmp);
416 XP_SRC_XY(dmin-dmaj,dmin);
417 XP_DEST_XY(x,y);
418 XP_DIM_XY(e+dmin,len);
419 TGUI_COMMAND(GE_BRESLINE);
420 XPSync(pScrn);
421 }
422 #endif
423
424 static void
XPSetupForFillRectSolid(ScrnInfoPtr pScrn,int color,int rop,unsigned int planemask)425 XPSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
426 int rop, unsigned int planemask)
427 {
428 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
429
430 REPLICATE(color);
431 TGUI_FMIX(XAAGetPatternROP(rop));
432 MMIO_OUT32(pTrident->IOBase, 0x2158, color);
433 TGUI_DRAWFLAG(SOLIDFILL);
434 }
435
436 static void
XPSubsequentFillRectSolid(ScrnInfoPtr pScrn,int x,int y,int w,int h)437 XPSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
438 {
439 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
440
441 XP_DIM_XY(w,h);
442 XP_DEST_XY(x,y);
443 TGUI_COMMAND(GE_BLT);
444 XPSync(pScrn);
445 }
446
447 #if 0
448 static void MoveDWORDS(
449 register CARD32* dest,
450 register CARD32* src,
451 register int dwords )
452 {
453 while(dwords & ~0x03) {
454 *dest = *src;
455 *(dest + 1) = *(src + 1);
456 *(dest + 2) = *(src + 2);
457 *(dest + 3) = *(src + 3);
458 src += 4;
459 dest += 4;
460 dwords -= 4;
461 }
462 if (!dwords) return;
463 *dest = *src;
464 dest += 1;
465 src += 1;
466 if (dwords == 1) return;
467 *dest = *src;
468 dest += 1;
469 src += 1;
470 if (dwords == 2) return;
471 *dest = *src;
472 dest += 1;
473 src += 1;
474 }
475 #endif
476
477 #if 0
478 static void MoveDWORDS_FixedBase(
479 register CARD32* dest,
480 register CARD32* src,
481 register int dwords )
482 {
483 while(dwords & ~0x03) {
484 *dest = *src;
485 *dest = *(src + 1);
486 *dest = *(src + 2);
487 *dest = *(src + 3);
488 dwords -= 4;
489 src += 4;
490 }
491
492 if(!dwords) return;
493 *dest = *src;
494 if(dwords == 1) return;
495 *dest = *(src + 1);
496 if(dwords == 2) return;
497 *dest = *(src + 2);
498 }
499 #endif
500
501
502 static void
XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,int patternx,int patterny,int fg,int bg,int rop,unsigned int planemask)503 XPSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
504 int patternx, int patterny,
505 int fg, int bg, int rop,
506 unsigned int planemask)
507 {
508 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
509 int drawflag = 0;
510
511 REPLICATE(fg);
512 MMIO_OUT32(pTrident->IOBase, 0x2158, fg);
513
514 if (bg == -1) {
515 drawflag |= 1<<12;
516 MMIO_OUT32(pTrident->IOBase, 0x215C, ~fg);
517 } else {
518 REPLICATE(bg);
519 MMIO_OUT32(pTrident->IOBase, 0x215C, bg);
520 }
521
522 drawflag |= 7<<18;
523 TGUI_DRAWFLAG(PATMONO | drawflag);
524 MMIO_OUT32(pTrident->IOBase, 0x2180, patternx);
525 MMIO_OUT32(pTrident->IOBase, 0x2184, patterny);
526 TGUI_FMIX(XAAGetPatternROP(rop));
527 }
528
529 static void
XPSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,int patternx,int patterny,int x,int y,int w,int h)530 XPSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
531 int patternx, int patterny,
532 int x, int y,
533 int w, int h)
534 {
535 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
536
537 XP_DEST_XY(x,y);
538 XP_DIM_XY(w,h);
539 TGUI_COMMAND(GE_BLT);
540 XPSync(pScrn);
541 }
542
543 #if 0
544 static void
545 XPSetupForScanlineCPUToScreenColorExpandFill(
546 ScrnInfoPtr pScrn,
547 int fg, int bg,
548 int rop,
549 unsigned int planemask
550 ){
551 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
552
553 TGUI_FMIX(XAAGetCopyROP(rop));
554 if (bg == -1) {
555 TGUI_DRAWFLAG(SRCMONO | 1<<12);
556 REPLICATE(fg);
557 TGUI_FCOLOUR(fg);
558 } else {
559 TGUI_DRAWFLAG(SRCMONO);
560 REPLICATE(fg);
561 REPLICATE(bg);
562 TGUI_FCOLOUR(fg);
563 TGUI_BCOLOUR(bg);
564 }
565 }
566
567 static void
568 XPSubsequentScanlineCPUToScreenColorExpandFill(
569 ScrnInfoPtr pScrn,
570 int x, int y, int w, int h,
571 int skipleft
572 ){
573 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
574 pTrident->dwords = (w + 31) >> 5;
575 pTrident->h = h;
576
577 XP_DEST_XY(x,y);
578 XP_DIM_XY(w>>1,h);
579 TGUI_COMMAND(GE_BLT);
580 }
581
582 static void
583 XPSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
584 {
585 TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
586 XAAInfoRecPtr infoRec;
587 infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
588
589 MoveDWORDS_FixedBase((CARD32 *)pTrident->IOBase + 0x2160,
590 (CARD32 *)pTrident->XAAScanlineColorExpandBuffers[0],
591 pTrident->dwords);
592
593 pTrident->h--;
594 if (pTrident->h)
595 XPSync(pScrn);
596 }
597 #endif
598 #endif
599