2
* Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
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 copyright
7
* notice and this permission notice appear in supporting documentation, and
8
* that the name of Marc Aurele La France not be used in advertising or
9
* publicity pertaining to distribution of the software without specific,
10
* written prior permission. Marc Aurele La France makes no representations
11
* about the suitability of this software for any purpose. It is provided
12
* "as-is" without express or implied warranty.
14
* MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
16
* EVENT SHALL MARC AURELE LA FRANCE 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.
23
* Copyright 1999-2000 Precision Insight, Inc., Cedar Park, Texas.
24
* All Rights Reserved.
26
* Permission is hereby granted, free of charge, to any person obtaining a copy
27
* of this software and associated documentation files (the "Software"), to
28
* deal in the Software without restriction, including without limitation the
29
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
30
* sell copies of the Software, and to permit persons to whom the Software is
31
* furnished to do so, subject to the following conditions:
33
* The above copyright notice and this permission notice (including the next
34
* paragraph) shall be included in all copies or substantial portions of the
37
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
40
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
41
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
42
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
43
* DEALINGS IN THE SOFTWARE.
48
* Leif Delgass <ldelgass@retinalburn.net>
57
#include "atimach64accel.h"
58
#include "atimach64io.h"
63
#include "mach64_common.h"
68
/* Used to test MMIO cache integrity in ATIMach64Sync() */
69
#define TestRegisterCaching(_Register) \
70
if (RegisterIsCached(_Register) && \
71
(CacheSlot(_Register) != inm(_Register))) \
73
UncacheRegister(_Register); \
74
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, \
75
#_Register " MMIO write cache disabled!\n"); \
79
* X-to-Mach64 mix translation table.
81
CARD8 ATIMach64ALU[16] =
85
MIX_SRC_AND_NOT_DST, /* GXandReverse */
87
MIX_NOT_SRC_AND_DST, /* GXandInverted */
92
MIX_XNOR, /* GXequiv */
93
MIX_NOT_DST, /* GXinvert */
94
MIX_SRC_OR_NOT_DST, /* GXorReverse */
95
MIX_NOT_SRC, /* GXcopyInverted */
96
MIX_NOT_SRC_OR_DST, /* GXorInverted */
97
MIX_NAND, /* GXnand */
102
* ATIMach64ValidateClip --
104
* This function ensures the current scissor settings do not interfere with
105
* the current draw request.
108
ATIMach64ValidateClip
117
if ((sc_left < (int)pATI->sc_left) || (sc_right > (int)pATI->sc_right))
119
outf(SC_LEFT_RIGHT, pATI->sc_left_right);
120
pATI->sc_left = pATI->NewHW.sc_left;
121
pATI->sc_right = pATI->NewHW.sc_right;
124
if ((sc_top < (int)pATI->sc_top) || (sc_bottom > (int)pATI->sc_bottom))
126
outf(SC_TOP_BOTTOM, pATI->sc_top_bottom);
127
pATI->sc_top = pATI->NewHW.sc_top;
128
pATI->sc_bottom = pATI->NewHW.sc_bottom;
132
static __inline__ void TestRegisterCachingDP(ScrnInfoPtr pScreenInfo);
133
static __inline__ void TestRegisterCachingXV(ScrnInfoPtr pScreenInfo);
138
* This is called to wait for the draw engine to become idle.
143
ScrnInfoPtr pScreenInfo
146
ATIPtr pATI = ATIPTR(pScreenInfo);
150
if ( pATI->directRenderingEnabled && pATI->NeedDRISync )
152
ATIHWPtr pATIHW = &pATI->NewHW;
155
if (pATI->OptionMMIOCache) {
156
/* "Invalidate" the MMIO cache so the cache slots get updated */
157
UncacheRegister(SRC_CNTL);
158
UncacheRegister(SCALE_3D_CNTL);
159
UncacheRegister(HOST_CNTL);
160
UncacheRegister(PAT_CNTL);
161
UncacheRegister(SC_LEFT_RIGHT);
162
UncacheRegister(SC_TOP_BOTTOM);
163
UncacheRegister(DP_BKGD_CLR);
164
UncacheRegister(DP_FRGD_CLR);
165
UncacheRegister(DP_PIX_WIDTH);
166
UncacheRegister(DP_MIX);
167
UncacheRegister(CLR_CMP_CNTL);
168
UncacheRegister(TEX_SIZE_PITCH);
171
ATIDRIWaitForIdle(pATI);
173
outr( BUS_CNTL, pATIHW->bus_cntl );
175
/* DRI uses GUI_TRAJ_CNTL, which is a composite of
176
* src_cntl, dst_cntl, pat_cntl, and host_cntl
178
outf( SRC_CNTL, pATIHW->src_cntl );
179
outf( DST_CNTL, pATIHW->dst_cntl );
180
outf( PAT_CNTL, pATIHW->pat_cntl );
181
outf( HOST_CNTL, pATIHW->host_cntl );
183
outf( DST_OFF_PITCH, pATIHW->dst_off_pitch );
184
outf( SRC_OFF_PITCH, pATIHW->src_off_pitch );
185
outf( DP_SRC, pATIHW->dp_src );
186
outf( DP_MIX, pATIHW->dp_mix );
187
outf( DP_FRGD_CLR, pATIHW->dp_frgd_clr );
188
outf( DP_WRITE_MASK, pATIHW->dp_write_mask );
189
outf( DP_PIX_WIDTH, pATIHW->dp_pix_width );
191
outf( CLR_CMP_CNTL, pATIHW->clr_cmp_cntl );
193
offset = TEX_LEVEL(pATIHW->tex_size_pitch);
195
ATIMach64WaitForFIFO(pATI, 6);
196
outf( ALPHA_TST_CNTL, 0 );
198
outf( SCALE_3D_CNTL, pATIHW->scale_3d_cntl );
199
outf( TEX_0_OFF + offset, pATIHW->tex_offset );
200
outf( TEX_SIZE_PITCH, pATIHW->tex_size_pitch );
201
outf( TEX_CNTL, pATIHW->tex_cntl );
203
ATIMach64WaitForFIFO(pATI, 2);
205
SetWord(pATIHW->sc_right, 1) | SetWord(pATIHW->sc_left, 0) );
207
SetWord(pATIHW->sc_bottom, 1) | SetWord(pATIHW->sc_top, 0) );
209
if (pATI->OptionMMIOCache) {
210
/* Now that the cache slots reflect the register state, re-enable MMIO cache */
211
CacheRegister(SRC_CNTL);
212
CacheRegister(SCALE_3D_CNTL);
213
CacheRegister(HOST_CNTL);
214
CacheRegister(PAT_CNTL);
215
CacheRegister(SC_LEFT_RIGHT);
216
CacheRegister(SC_TOP_BOTTOM);
217
CacheRegister(DP_BKGD_CLR);
218
CacheRegister(DP_FRGD_CLR);
219
CacheRegister(DP_PIX_WIDTH);
220
CacheRegister(DP_MIX);
221
CacheRegister(CLR_CMP_CNTL);
222
CacheRegister(TEX_SIZE_PITCH);
225
ATIMach64WaitForIdle(pATI);
227
if (pATI->OptionMMIOCache && pATI->OptionTestMMIOCache) {
229
/* Only check registers we didn't restore */
230
TestRegisterCaching(PAT_REG0);
231
TestRegisterCaching(PAT_REG1);
233
TestRegisterCaching(CLR_CMP_CLR);
234
TestRegisterCaching(CLR_CMP_MSK);
236
TestRegisterCachingXV(pScreenInfo);
238
pATI->NeedDRISync = FALSE;
243
#endif /* XF86DRI_DEVEL */
245
ATIMach64WaitForIdle(pATI);
247
if (pATI->OptionMMIOCache && pATI->OptionTestMMIOCache)
250
* For debugging purposes, attempt to verify that each cached register
251
* should actually be cached.
253
TestRegisterCachingDP(pScreenInfo);
255
TestRegisterCachingXV(pScreenInfo);
260
/* EXA sets pEXA->needsSync to FALSE on its own */
265
pATI->pXAAInfo->NeedToSync = FALSE;
268
if (pATI->Chip >= ATI_CHIP_264VTB)
271
* Flush the read-back cache (by turning on INVALIDATE_RB_CACHE),
272
* otherwise the host might get stale data when reading through the
275
outr(MEM_BUF_CNTL, pATI->NewHW.mem_buf_cntl);
280
* Before actually invalidating the read-back cache, the mach64 driver
281
* was using the trick below which is buggy. The code is left here for
282
* reference, DRI uses this trick and needs updating.
284
* For VTB's and later, the first CPU read of the framebuffer will return
285
* zeroes, so do it here. This appears to be due to some kind of engine
286
* caching of framebuffer data I haven't found any way of disabling, or
287
* otherwise circumventing. Thanks to Mark Vojkovich for the suggestion.
289
* pATI = *(volatile ATIPtr *)pATI->pMemory;
293
static __inline__ void
294
TestRegisterCachingDP(ScrnInfoPtr pScreenInfo)
296
ATIPtr pATI = ATIPTR(pScreenInfo);
298
TestRegisterCaching(SRC_CNTL);
300
if (pATI->Chip >= ATI_CHIP_264GTPRO)
302
TestRegisterCaching(SCALE_3D_CNTL);
305
TestRegisterCaching(HOST_CNTL);
307
TestRegisterCaching(PAT_REG0);
308
TestRegisterCaching(PAT_REG1);
309
TestRegisterCaching(PAT_CNTL);
311
if (RegisterIsCached(SC_LEFT_RIGHT) && /* Special case */
312
(CacheSlot(SC_LEFT_RIGHT) !=
313
(SetWord(inm(SC_RIGHT), 1) | SetWord(inm(SC_LEFT), 0))))
315
UncacheRegister(SC_LEFT_RIGHT);
316
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
317
"SC_LEFT_RIGHT write cache disabled!\n");
320
if (RegisterIsCached(SC_TOP_BOTTOM) && /* Special case */
321
(CacheSlot(SC_TOP_BOTTOM) !=
322
(SetWord(inm(SC_BOTTOM), 1) | SetWord(inm(SC_TOP), 0))))
324
UncacheRegister(SC_TOP_BOTTOM);
325
xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
326
"SC_TOP_BOTTOM write cache disabled!\n");
329
TestRegisterCaching(DP_BKGD_CLR);
330
TestRegisterCaching(DP_FRGD_CLR);
331
TestRegisterCaching(DP_PIX_WIDTH);
332
TestRegisterCaching(DP_MIX);
334
TestRegisterCaching(CLR_CMP_CLR);
335
TestRegisterCaching(CLR_CMP_MSK);
336
TestRegisterCaching(CLR_CMP_CNTL);
338
if (pATI->Chip >= ATI_CHIP_264GTPRO)
340
TestRegisterCaching(TEX_SIZE_PITCH);
344
static __inline__ void
345
TestRegisterCachingXV(ScrnInfoPtr pScreenInfo)
347
ATIPtr pATI = ATIPTR(pScreenInfo);
349
if (!pATI->Block1Base)
352
TestRegisterCaching(OVERLAY_Y_X_START);
353
TestRegisterCaching(OVERLAY_Y_X_END);
355
TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR);
356
TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK);
358
TestRegisterCaching(OVERLAY_KEY_CNTL);
360
TestRegisterCaching(OVERLAY_SCALE_INC);
361
TestRegisterCaching(OVERLAY_SCALE_CNTL);
363
TestRegisterCaching(SCALER_HEIGHT_WIDTH);
365
TestRegisterCaching(SCALER_TEST);
367
TestRegisterCaching(VIDEO_FORMAT);
369
if (pATI->Chip < ATI_CHIP_264VTB)
371
TestRegisterCaching(BUF0_OFFSET);
372
TestRegisterCaching(BUF0_PITCH);
373
TestRegisterCaching(BUF1_OFFSET);
374
TestRegisterCaching(BUF1_PITCH);
379
TestRegisterCaching(SCALER_BUF0_OFFSET);
380
TestRegisterCaching(SCALER_BUF1_OFFSET);
381
TestRegisterCaching(SCALER_BUF_PITCH);
383
TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ);
384
TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT);
386
if (pATI->Chip < ATI_CHIP_264GTPRO)
389
TestRegisterCaching(SCALER_COLOUR_CNTL);
391
TestRegisterCaching(SCALER_H_COEFF0);
392
TestRegisterCaching(SCALER_H_COEFF1);
393
TestRegisterCaching(SCALER_H_COEFF2);
394
TestRegisterCaching(SCALER_H_COEFF3);
395
TestRegisterCaching(SCALER_H_COEFF4);
397
TestRegisterCaching(SCALER_BUF0_OFFSET_U);
398
TestRegisterCaching(SCALER_BUF0_OFFSET_V);
399
TestRegisterCaching(SCALER_BUF1_OFFSET_U);
400
TestRegisterCaching(SCALER_BUF1_OFFSET_V);
405
* ATIMach64SetupForScreenToScreenCopy --
407
* This function sets up the draw engine for a series of screen-to-screen copy
411
ATIMach64SetupForScreenToScreenCopy
413
ScrnInfoPtr pScreenInfo,
417
unsigned int planemask,
418
int TransparencyColour
421
ATIPtr pATI = ATIPTR(pScreenInfo);
423
ATIDRISync(pScreenInfo);
425
ATIMach64WaitForFIFO(pATI, 3);
426
outf(DP_WRITE_MASK, planemask);
427
outf(DP_SRC, DP_MONO_SRC_ALLONES |
428
SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
429
outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX));
433
if (TransparencyColour == -1)
435
#else /* AVOID_DGA */
437
if (!pATI->XAAForceTransBlit && (TransparencyColour == -1))
439
#endif /* AVOID_DGA */
442
outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
446
ATIMach64WaitForFIFO(pATI, 2);
447
outf(CLR_CMP_CLR, TransparencyColour);
448
outf(CLR_CMP_CNTL, CLR_CMP_FN_EQUAL | CLR_CMP_SRC_2D);
454
pATI->dst_cntl |= DST_Y_DIR;
456
pATI->dst_cntl |= DST_X_DIR;
458
if (pATI->XModifier == 1)
459
outf(DST_CNTL, pATI->dst_cntl);
461
pATI->dst_cntl |= DST_24_ROT_EN;
465
* ATIMach64SubsequentScreenToScreenCopy --
467
* This function performs a screen-to-screen copy operation.
470
ATIMach64SubsequentScreenToScreenCopy
472
ScrnInfoPtr pScreenInfo,
481
ATIPtr pATI = ATIPTR(pScreenInfo);
483
xSrc *= pATI->XModifier;
484
xDst *= pATI->XModifier;
485
w *= pATI->XModifier;
487
ATIDRISync(pScreenInfo);
489
/* Disable clipping if it gets in the way */
490
ATIMach64ValidateClip(pATI, xDst, xDst + w - 1, yDst, yDst + h - 1);
492
if (!(pATI->dst_cntl & DST_X_DIR))
498
if (!(pATI->dst_cntl & DST_Y_DIR))
504
if (pATI->XModifier != 1)
505
outf(DST_CNTL, pATI->dst_cntl | SetBits((xDst / 4) % 6, DST_24_ROT));
507
ATIMach64WaitForFIFO(pATI, 4);
508
outf(SRC_Y_X, SetWord(xSrc, 1) | SetWord(ySrc, 0));
510
outf(DST_Y_X, SetWord(xDst, 1) | SetWord(yDst, 0));
511
outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
514
* On VTB's and later, the engine will randomly not wait for a copy
515
* operation to commit its results to video memory before starting the next
516
* one. The probability of such occurrences increases with GUI_WB_FLUSH
517
* (or GUI_WB_FLUSH_P) setting, bitsPerPixel and/or CRTC clock. This
518
* would point to some kind of video memory bandwidth problem were it noti
519
* for the fact that the problem occurs less often (but still occurs) when
520
* copying larger rectangles.
522
if ((pATI->Chip >= ATI_CHIP_264VTB) && !pATI->OptionDevel)
523
ATIMach64Sync(pScreenInfo);
527
* ATIMach64SetupForSolidFill --
529
* This function sets up the draw engine for a series of solid fills.
532
ATIMach64SetupForSolidFill
534
ScrnInfoPtr pScreenInfo,
537
unsigned int planemask
540
ATIPtr pATI = ATIPTR(pScreenInfo);
542
ATIDRISync(pScreenInfo);
544
ATIMach64WaitForFIFO(pATI, 5);
545
outf(DP_WRITE_MASK, planemask);
546
outf(DP_SRC, DP_MONO_SRC_ALLONES |
547
SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
548
outf(DP_FRGD_CLR, colour);
549
outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX));
551
outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
553
if (pATI->XModifier == 1)
554
outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
558
* ATIMach64SubsequentSolidFillRect --
560
* This function performs a solid rectangle fill.
563
ATIMach64SubsequentSolidFillRect
565
ScrnInfoPtr pScreenInfo,
572
ATIPtr pATI = ATIPTR(pScreenInfo);
574
ATIDRISync(pScreenInfo);
576
if (pATI->XModifier != 1)
578
x *= pATI->XModifier;
579
w *= pATI->XModifier;
581
outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
582
(DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
585
/* Disable clipping if it gets in the way */
586
ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1);
588
ATIMach64WaitForFIFO(pATI, 2);
589
outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
590
outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
594
* ATIMach64SetupForSolidLine --
596
* This function sets up the draw engine for a series of solid lines. It is
597
* not used for 24bpp because the engine doesn't support it.
600
ATIMach64SetupForSolidLine
602
ScrnInfoPtr pScreenInfo,
605
unsigned int planemask
608
ATIPtr pATI = ATIPTR(pScreenInfo);
610
ATIDRISync(pScreenInfo);
612
ATIMach64WaitForFIFO(pATI, 5);
613
outf(DP_WRITE_MASK, planemask);
614
outf(DP_SRC, DP_MONO_SRC_ALLONES |
615
SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
616
outf(DP_FRGD_CLR, colour);
617
outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX));
619
outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
621
ATIMach64ValidateClip(pATI, pATI->NewHW.sc_left, pATI->NewHW.sc_right,
622
pATI->NewHW.sc_top, pATI->NewHW.sc_bottom);
626
* ATIMach64SubsequentSolidHorVertLine --
628
* This is called to draw a solid horizontal or vertical line. This does a
629
* one-pixel wide solid fill.
632
ATIMach64SubsequentSolidHorVertLine
634
ScrnInfoPtr pScreenInfo,
641
ATIPtr pATI = ATIPTR(pScreenInfo);
643
ATIDRISync(pScreenInfo);
645
ATIMach64WaitForFIFO(pATI, 3);
646
outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
647
outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
649
if (dir == DEGREES_0)
650
outf(DST_HEIGHT_WIDTH, SetWord(len, 1) | SetWord(1, 0));
651
else /* if (dir == DEGREES_270) */
652
outf(DST_HEIGHT_WIDTH, SetWord(1, 1) | SetWord(len, 0));
656
* ATIMach64SubsequentSolidBresenhamLine --
658
* This function draws a line using the Bresenham line engine.
661
ATIMach64SubsequentSolidBresenhamLine
663
ScrnInfoPtr pScreenInfo,
673
ATIPtr pATI = ATIPTR(pScreenInfo);
674
CARD32 dst_cntl = DST_LAST_PEL;
677
dst_cntl |= DST_Y_MAJOR;
679
if (!(octant & XDECREASING))
680
dst_cntl |= DST_X_DIR;
682
if (!(octant & YDECREASING))
683
dst_cntl |= DST_Y_DIR;
685
ATIDRISync(pScreenInfo);
687
ATIMach64WaitForFIFO(pATI, 6);
688
outf(DST_CNTL, dst_cntl);
689
outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
690
outf(DST_BRES_ERR, minor + err);
691
outf(DST_BRES_INC, minor);
692
outf(DST_BRES_DEC, minor - major);
693
outf(DST_BRES_LNTH, len);
697
* ATIMach64SetupForMono8x8PatternFill --
699
* This function sets up the draw engine for a series of 8x8 1bpp pattern
703
ATIMach64SetupForMono8x8PatternFill
705
ScrnInfoPtr pScreenInfo,
711
unsigned int planemask
714
ATIPtr pATI = ATIPTR(pScreenInfo);
716
ATIDRISync(pScreenInfo);
718
ATIMach64WaitForFIFO(pATI, 3);
719
outf(DP_WRITE_MASK, planemask);
720
outf(DP_SRC, DP_MONO_SRC_PATTERN |
721
SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
722
outf(DP_FRGD_CLR, fg);
726
outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
727
SetBits(MIX_DST, DP_BKGD_MIX));
731
ATIMach64WaitForFIFO(pATI, 2);
732
outf(DP_BKGD_CLR, bg);
733
outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
734
SetBits(ATIMach64ALU[rop], DP_BKGD_MIX));
737
ATIMach64WaitForFIFO(pATI, 4);
738
outf(PAT_REG0, patx);
739
outf(PAT_REG1, paty);
740
outf(PAT_CNTL, PAT_MONO_EN);
742
outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
744
if (pATI->XModifier == 1)
745
outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
749
* ATIMach64SubsequentMono8x8PatternFillRect --
751
* This function performs an 8x8 1bpp pattern fill.
754
ATIMach64SubsequentMono8x8PatternFillRect
756
ScrnInfoPtr pScreenInfo,
765
ATIPtr pATI = ATIPTR(pScreenInfo);
767
ATIDRISync(pScreenInfo);
769
if (pATI->XModifier != 1)
771
x *= pATI->XModifier;
772
w *= pATI->XModifier;
774
outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
775
(DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
778
/* Disable clipping if it gets in the way */
779
ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1);
781
ATIMach64WaitForFIFO(pATI, 2);
782
outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
783
outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
787
* ATIMach64SetupForScanlineCPUToScreenColorExpandFill --
789
* This function sets up the engine for a series of colour expansion fills.
792
ATIMach64SetupForScanlineCPUToScreenColorExpandFill
794
ScrnInfoPtr pScreenInfo,
798
unsigned int planemask
801
ATIPtr pATI = ATIPTR(pScreenInfo);
803
ATIDRISync(pScreenInfo);
805
ATIMach64WaitForFIFO(pATI, 3);
806
outf(DP_WRITE_MASK, planemask);
807
outf(DP_SRC, DP_MONO_SRC_HOST |
808
SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
809
outf(DP_FRGD_CLR, fg);
813
outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
814
SetBits(MIX_DST, DP_BKGD_MIX));
818
ATIMach64WaitForFIFO(pATI, 2);
819
outf(DP_BKGD_CLR, bg);
820
outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) |
821
SetBits(ATIMach64ALU[rop], DP_BKGD_MIX));
824
outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
826
if (pATI->XModifier == 1)
827
outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
831
* ATIMach64SubsequentScanlineCPUToScreenColorExpandFill --
833
* This function sets up the engine for a single colour expansion fill.
836
ATIMach64SubsequentScanlineCPUToScreenColorExpandFill
838
ScrnInfoPtr pScreenInfo,
846
ATIPtr pATI = ATIPTR(pScreenInfo);
848
ATIDRISync(pScreenInfo);
850
if (pATI->XModifier != 1)
852
x *= pATI->XModifier;
853
w *= pATI->XModifier;
854
skipleft *= pATI->XModifier;
856
outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
857
(DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
860
pATI->ExpansionBitmapWidth = (w + 31) / 32;
862
ATIMach64WaitForFIFO(pATI, 3);
863
pATI->sc_left = x + skipleft;
864
pATI->sc_right = x + w - 1;
866
SetWord(pATI->sc_right, 1) | SetWord(pATI->sc_left, 0));
867
outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
868
outf(DST_HEIGHT_WIDTH,
869
SetWord(pATI->ExpansionBitmapWidth * 32, 1) | SetWord(h, 0));
873
* ATIMach64SubsequentColorExpandScanline --
875
* This function feeds a bitmap scanline to the engine for a colour expansion
876
* fill. This is written to do burst transfers for those platforms that can do
877
* them, and to improve CPU/engine concurrency.
880
ATIMach64SubsequentColorExpandScanline
882
ScrnInfoPtr pScreenInfo,
886
ATIPtr pATI = ATIPTR(pScreenInfo);
887
CARD32 *pBitmapData = pATI->ExpansionBitmapScanlinePtr[iBuffer];
888
int w = pATI->ExpansionBitmapWidth;
891
ATIDRISync(pScreenInfo);
896
* Transfers are done in chunks of up to 64 bytes in length (32 on
897
* earlier controllers).
900
if (nDWord > pATI->nHostFIFOEntries)
901
nDWord = pATI->nHostFIFOEntries;
903
/* Make enough FIFO slots available */
904
ATIMach64WaitForFIFO(pATI, nDWord);
907
* Always start transfers on a chuck-sized boundary. Note that
908
* HOST_DATA_0 is actually on a 512-byte boundary, but *pBitmapData can
909
* only be guaranteed to be on a chunk-sized boundary.
911
* Transfer current chunk. With any luck, the compiler won't mangle
915
# if defined(ATIMove32)
918
ATIMove32(pATI->pHOST_DATA, pBitmapData, nDWord);
924
volatile CARD32 *pDst;
928
iDWord = 16 - nDWord;
929
pDst = (volatile CARD32 *)pATI->pHOST_DATA - iDWord;
930
pSrc = pBitmapData - iDWord;
934
case 0: MMIO_MOVE32(pDst + 0, 0, *(pSrc + 0));
935
case 1: MMIO_MOVE32(pDst + 1, 0, *(pSrc + 1));
936
case 2: MMIO_MOVE32(pDst + 2, 0, *(pSrc + 2));
937
case 3: MMIO_MOVE32(pDst + 3, 0, *(pSrc + 3));
938
case 4: MMIO_MOVE32(pDst + 4, 0, *(pSrc + 4));
939
case 5: MMIO_MOVE32(pDst + 5, 0, *(pSrc + 5));
940
case 6: MMIO_MOVE32(pDst + 6, 0, *(pSrc + 6));
941
case 7: MMIO_MOVE32(pDst + 7, 0, *(pSrc + 7));
942
case 8: MMIO_MOVE32(pDst + 8, 0, *(pSrc + 8));
943
case 9: MMIO_MOVE32(pDst + 9, 0, *(pSrc + 9));
944
case 10: MMIO_MOVE32(pDst + 10, 0, *(pSrc + 10));
945
case 11: MMIO_MOVE32(pDst + 11, 0, *(pSrc + 11));
946
case 12: MMIO_MOVE32(pDst + 12, 0, *(pSrc + 12));
947
case 13: MMIO_MOVE32(pDst + 13, 0, *(pSrc + 13));
948
case 14: MMIO_MOVE32(pDst + 14, 0, *(pSrc + 14));
949
case 15: MMIO_MOVE32(pDst + 15, 0, *(pSrc + 15));
951
default: /* Muffle compiler */
958
/* Step to next chunk */
959
pBitmapData += nDWord;
961
pATI->nAvailableFIFOEntries -= nDWord;
964
pATI->EngineIsBusy = TRUE;
968
* ATIMach64AccelInit --
970
* This function fills in structure fields needed for acceleration on Mach64
979
ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen);
980
ATIPtr pATI = ATIPTR(pScreenInfo);
981
XAAInfoRecPtr pXAAInfo;
983
if (!(pATI->pXAAInfo = XAACreateInfoRec()))
986
pXAAInfo = pATI->pXAAInfo;
988
/* This doesn't seem quite right... */
989
if (pATI->XModifier == 1)
991
pXAAInfo->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
992
pXAAInfo->Flags |= LINEAR_FRAMEBUFFER;
996
pXAAInfo->Sync = ATIMach64Sync;
998
/* Screen-to-screen copy */
999
pXAAInfo->SetupForScreenToScreenCopy = ATIMach64SetupForScreenToScreenCopy;
1000
pXAAInfo->SubsequentScreenToScreenCopy =
1001
ATIMach64SubsequentScreenToScreenCopy;
1004
pXAAInfo->SetupForSolidFill = ATIMach64SetupForSolidFill;
1005
pXAAInfo->SubsequentSolidFillRect = ATIMach64SubsequentSolidFillRect;
1007
/* 8x8 mono pattern fills */
1008
pXAAInfo->Mono8x8PatternFillFlags =
1010
#if X_BYTE_ORDER != X_LITTLE_ENDIAN
1012
BIT_ORDER_IN_BYTE_MSBFIRST |
1014
#endif /* X_BYTE_ORDER */
1016
HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN;
1017
pXAAInfo->SetupForMono8x8PatternFill = ATIMach64SetupForMono8x8PatternFill;
1018
pXAAInfo->SubsequentMono8x8PatternFillRect =
1019
ATIMach64SubsequentMono8x8PatternFillRect;
1022
* Use scanline version of colour expansion, not only for the non-ix86
1023
* case, but also to avoid PCI retries.
1025
pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags =
1026
LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X |
1027
CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD;
1028
if (pATI->XModifier != 1)
1029
pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags |= TRIPLE_BITS_24BPP;
1030
pXAAInfo->NumScanlineColorExpandBuffers = 1;
1032
/* Align bitmap data on a 64-byte boundary */
1033
pATI->ExpansionBitmapWidth = /* DWord size in bits */
1034
((pATI->displayWidth * pATI->XModifier) + 31) & ~31U;
1035
pATI->ExpansionBitmapScanlinePtr[1] =
1036
(CARD32 *)xnfalloc((pATI->ExpansionBitmapWidth >> 3) + 63);
1037
pATI->ExpansionBitmapScanlinePtr[0] =
1038
(pointer)(((unsigned long)pATI->ExpansionBitmapScanlinePtr[1] + 63) &
1040
pXAAInfo->ScanlineColorExpandBuffers =
1041
(CARD8 **)pATI->ExpansionBitmapScanlinePtr;
1042
pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill =
1043
ATIMach64SetupForScanlineCPUToScreenColorExpandFill;
1044
pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill =
1045
ATIMach64SubsequentScanlineCPUToScreenColorExpandFill;
1046
pXAAInfo->SubsequentColorExpandScanline =
1047
ATIMach64SubsequentColorExpandScanline;
1049
/* The engine does not support the following primitives for 24bpp */
1050
if (pATI->XModifier != 1)
1054
pXAAInfo->SetupForSolidLine = ATIMach64SetupForSolidLine;
1055
pXAAInfo->SubsequentSolidHorVertLine = ATIMach64SubsequentSolidHorVertLine;
1056
pXAAInfo->SubsequentSolidBresenhamLine =
1057
ATIMach64SubsequentSolidBresenhamLine;
1060
if (!XAAInit(pScreen, pATI->pXAAInfo)) {
1061
XAADestroyInfoRec(pATI->pXAAInfo);
1062
pATI->pXAAInfo = NULL;
1068
#endif /* USE_XAA */