132b578d3Smrg/* 232b578d3Smrg * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 332b578d3Smrg * 432b578d3Smrg * Permission to use, copy, modify, distribute, and sell this software and its 532b578d3Smrg * documentation for any purpose is hereby granted without fee, provided that 632b578d3Smrg * the above copyright notice appear in all copies and that both that copyright 732b578d3Smrg * notice and this permission notice appear in supporting documentation, and 832b578d3Smrg * that the name of Marc Aurele La France not be used in advertising or 932b578d3Smrg * publicity pertaining to distribution of the software without specific, 1032b578d3Smrg * written prior permission. Marc Aurele La France makes no representations 1132b578d3Smrg * about the suitability of this software for any purpose. It is provided 1232b578d3Smrg * "as-is" without express or implied warranty. 1332b578d3Smrg * 1432b578d3Smrg * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1532b578d3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 1632b578d3Smrg * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1732b578d3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1832b578d3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1932b578d3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2032b578d3Smrg * PERFORMANCE OF THIS SOFTWARE. 2132b578d3Smrg */ 2232b578d3Smrg/* 2332b578d3Smrg * Copyright 1999-2000 Precision Insight, Inc., Cedar Park, Texas. 2432b578d3Smrg * All Rights Reserved. 2532b578d3Smrg * 2632b578d3Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy 2732b578d3Smrg * of this software and associated documentation files (the "Software"), to 2832b578d3Smrg * deal in the Software without restriction, including without limitation the 2932b578d3Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 3032b578d3Smrg * sell copies of the Software, and to permit persons to whom the Software is 3132b578d3Smrg * furnished to do so, subject to the following conditions: 3232b578d3Smrg * 3332b578d3Smrg * The above copyright notice and this permission notice (including the next 3432b578d3Smrg * paragraph) shall be included in all copies or substantial portions of the 3532b578d3Smrg * Software. 3632b578d3Smrg * 3732b578d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 3832b578d3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 3932b578d3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 4032b578d3Smrg * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 4132b578d3Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 4232b578d3Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 4332b578d3Smrg * DEALINGS IN THE SOFTWARE. 4432b578d3Smrg */ 4532b578d3Smrg/* 4632b578d3Smrg * DRI support by: 4732b578d3Smrg * Manuel Teira 4832b578d3Smrg * Leif Delgass <ldelgass@retinalburn.net> 4932b578d3Smrg */ 5032b578d3Smrg 5132b578d3Smrg#ifdef HAVE_CONFIG_H 5232b578d3Smrg#include "config.h" 5332b578d3Smrg#endif 5432b578d3Smrg 5532b578d3Smrg#include "ati.h" 5632b578d3Smrg#include "atichip.h" 5732b578d3Smrg#include "atimach64accel.h" 5832b578d3Smrg#include "atimach64io.h" 5932b578d3Smrg#include "atipriv.h" 6032b578d3Smrg#include "atiregs.h" 6132b578d3Smrg 6232b578d3Smrg#ifdef XF86DRI_DEVEL 6332b578d3Smrg#include "mach64_common.h" 6432b578d3Smrg#endif 6532b578d3Smrg 6632b578d3Smrg#include "miline.h" 6732b578d3Smrg 6832b578d3Smrg/* Used to test MMIO cache integrity in ATIMach64Sync() */ 6932b578d3Smrg#define TestRegisterCaching(_Register) \ 7032b578d3Smrg if (RegisterIsCached(_Register) && \ 7132b578d3Smrg (CacheSlot(_Register) != inm(_Register))) \ 7232b578d3Smrg { \ 7332b578d3Smrg UncacheRegister(_Register); \ 7432b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, \ 7532b578d3Smrg #_Register " MMIO write cache disabled!\n"); \ 7632b578d3Smrg } 7732b578d3Smrg 7832b578d3Smrg/* 7932b578d3Smrg * X-to-Mach64 mix translation table. 8032b578d3Smrg */ 8132b578d3SmrgCARD8 ATIMach64ALU[16] = 8232b578d3Smrg{ 8332b578d3Smrg MIX_0, /* GXclear */ 8432b578d3Smrg MIX_AND, /* GXand */ 8532b578d3Smrg MIX_SRC_AND_NOT_DST, /* GXandReverse */ 8632b578d3Smrg MIX_SRC, /* GXcopy */ 8732b578d3Smrg MIX_NOT_SRC_AND_DST, /* GXandInverted */ 8832b578d3Smrg MIX_DST, /* GXnoop */ 8932b578d3Smrg MIX_XOR, /* GXxor */ 9032b578d3Smrg MIX_OR, /* GXor */ 9132b578d3Smrg MIX_NOR, /* GXnor */ 9232b578d3Smrg MIX_XNOR, /* GXequiv */ 9332b578d3Smrg MIX_NOT_DST, /* GXinvert */ 9432b578d3Smrg MIX_SRC_OR_NOT_DST, /* GXorReverse */ 9532b578d3Smrg MIX_NOT_SRC, /* GXcopyInverted */ 9632b578d3Smrg MIX_NOT_SRC_OR_DST, /* GXorInverted */ 9732b578d3Smrg MIX_NAND, /* GXnand */ 9832b578d3Smrg MIX_1 /* GXset */ 9932b578d3Smrg}; 10032b578d3Smrg 10132b578d3Smrg/* 10232b578d3Smrg * ATIMach64ValidateClip -- 10332b578d3Smrg * 10432b578d3Smrg * This function ensures the current scissor settings do not interfere with 10532b578d3Smrg * the current draw request. 10632b578d3Smrg */ 10732b578d3Smrgvoid 10832b578d3SmrgATIMach64ValidateClip 10932b578d3Smrg( 11032b578d3Smrg ATIPtr pATI, 11132b578d3Smrg int sc_left, 11232b578d3Smrg int sc_right, 11332b578d3Smrg int sc_top, 11432b578d3Smrg int sc_bottom 11532b578d3Smrg) 11632b578d3Smrg{ 11732b578d3Smrg if ((sc_left < (int)pATI->sc_left) || (sc_right > (int)pATI->sc_right)) 11832b578d3Smrg { 11932b578d3Smrg outf(SC_LEFT_RIGHT, pATI->sc_left_right); 12032b578d3Smrg pATI->sc_left = pATI->NewHW.sc_left; 12132b578d3Smrg pATI->sc_right = pATI->NewHW.sc_right; 12232b578d3Smrg } 12332b578d3Smrg 12432b578d3Smrg if ((sc_top < (int)pATI->sc_top) || (sc_bottom > (int)pATI->sc_bottom)) 12532b578d3Smrg { 12632b578d3Smrg outf(SC_TOP_BOTTOM, pATI->sc_top_bottom); 12732b578d3Smrg pATI->sc_top = pATI->NewHW.sc_top; 12832b578d3Smrg pATI->sc_bottom = pATI->NewHW.sc_bottom; 12932b578d3Smrg } 13032b578d3Smrg} 13132b578d3Smrg 13232b578d3Smrgstatic __inline__ void TestRegisterCachingDP(ScrnInfoPtr pScreenInfo); 13332b578d3Smrgstatic __inline__ void TestRegisterCachingXV(ScrnInfoPtr pScreenInfo); 13432b578d3Smrg 13532b578d3Smrg/* 13632b578d3Smrg * ATIMach64Sync -- 13732b578d3Smrg * 13832b578d3Smrg * This is called to wait for the draw engine to become idle. 13932b578d3Smrg */ 14032b578d3Smrgvoid 14132b578d3SmrgATIMach64Sync 14232b578d3Smrg( 14332b578d3Smrg ScrnInfoPtr pScreenInfo 14432b578d3Smrg) 14532b578d3Smrg{ 14632b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 14732b578d3Smrg 14832b578d3Smrg#ifdef XF86DRI_DEVEL 14932b578d3Smrg 15032b578d3Smrg if ( pATI->directRenderingEnabled && pATI->NeedDRISync ) 15132b578d3Smrg { 15232b578d3Smrg ATIHWPtr pATIHW = &pATI->NewHW; 15332b578d3Smrg CARD32 offset; 15432b578d3Smrg 15532b578d3Smrg if (pATI->OptionMMIOCache) { 15632b578d3Smrg /* "Invalidate" the MMIO cache so the cache slots get updated */ 15732b578d3Smrg UncacheRegister(SRC_CNTL); 15832b578d3Smrg UncacheRegister(SCALE_3D_CNTL); 15932b578d3Smrg UncacheRegister(HOST_CNTL); 16032b578d3Smrg UncacheRegister(PAT_CNTL); 16132b578d3Smrg UncacheRegister(SC_LEFT_RIGHT); 16232b578d3Smrg UncacheRegister(SC_TOP_BOTTOM); 16332b578d3Smrg UncacheRegister(DP_BKGD_CLR); 16432b578d3Smrg UncacheRegister(DP_FRGD_CLR); 16532b578d3Smrg UncacheRegister(DP_PIX_WIDTH); 16632b578d3Smrg UncacheRegister(DP_MIX); 16732b578d3Smrg UncacheRegister(CLR_CMP_CNTL); 16832b578d3Smrg UncacheRegister(TEX_SIZE_PITCH); 16932b578d3Smrg } 17032b578d3Smrg 17132b578d3Smrg ATIDRIWaitForIdle(pATI); 17232b578d3Smrg 17332b578d3Smrg outr( BUS_CNTL, pATIHW->bus_cntl ); 17432b578d3Smrg 17532b578d3Smrg /* DRI uses GUI_TRAJ_CNTL, which is a composite of 17632b578d3Smrg * src_cntl, dst_cntl, pat_cntl, and host_cntl 17732b578d3Smrg */ 17832b578d3Smrg outf( SRC_CNTL, pATIHW->src_cntl ); 17932b578d3Smrg outf( DST_CNTL, pATIHW->dst_cntl ); 18032b578d3Smrg outf( PAT_CNTL, pATIHW->pat_cntl ); 18132b578d3Smrg outf( HOST_CNTL, pATIHW->host_cntl ); 18232b578d3Smrg 18332b578d3Smrg outf( DST_OFF_PITCH, pATIHW->dst_off_pitch ); 18432b578d3Smrg outf( SRC_OFF_PITCH, pATIHW->src_off_pitch ); 18532b578d3Smrg outf( DP_SRC, pATIHW->dp_src ); 18632b578d3Smrg outf( DP_MIX, pATIHW->dp_mix ); 18732b578d3Smrg outf( DP_FRGD_CLR, pATIHW->dp_frgd_clr ); 18832b578d3Smrg outf( DP_WRITE_MASK, pATIHW->dp_write_mask ); 18932b578d3Smrg outf( DP_PIX_WIDTH, pATIHW->dp_pix_width ); 19032b578d3Smrg 19132b578d3Smrg outf( CLR_CMP_CNTL, pATIHW->clr_cmp_cntl ); 19232b578d3Smrg 19332b578d3Smrg offset = TEX_LEVEL(pATIHW->tex_size_pitch); 19432b578d3Smrg 19532b578d3Smrg ATIMach64WaitForFIFO(pATI, 6); 19632b578d3Smrg outf( ALPHA_TST_CNTL, 0 ); 19732b578d3Smrg outf( Z_CNTL, 0 ); 19832b578d3Smrg outf( SCALE_3D_CNTL, pATIHW->scale_3d_cntl ); 19932b578d3Smrg outf( TEX_0_OFF + offset, pATIHW->tex_offset ); 20032b578d3Smrg outf( TEX_SIZE_PITCH, pATIHW->tex_size_pitch ); 20132b578d3Smrg outf( TEX_CNTL, pATIHW->tex_cntl ); 20232b578d3Smrg 20332b578d3Smrg ATIMach64WaitForFIFO(pATI, 2); 20432b578d3Smrg outf( SC_LEFT_RIGHT, 20532b578d3Smrg SetWord(pATIHW->sc_right, 1) | SetWord(pATIHW->sc_left, 0) ); 20632b578d3Smrg outf( SC_TOP_BOTTOM, 20732b578d3Smrg SetWord(pATIHW->sc_bottom, 1) | SetWord(pATIHW->sc_top, 0) ); 20832b578d3Smrg 20932b578d3Smrg if (pATI->OptionMMIOCache) { 21032b578d3Smrg /* Now that the cache slots reflect the register state, re-enable MMIO cache */ 21132b578d3Smrg CacheRegister(SRC_CNTL); 21232b578d3Smrg CacheRegister(SCALE_3D_CNTL); 21332b578d3Smrg CacheRegister(HOST_CNTL); 21432b578d3Smrg CacheRegister(PAT_CNTL); 21532b578d3Smrg CacheRegister(SC_LEFT_RIGHT); 21632b578d3Smrg CacheRegister(SC_TOP_BOTTOM); 21732b578d3Smrg CacheRegister(DP_BKGD_CLR); 21832b578d3Smrg CacheRegister(DP_FRGD_CLR); 21932b578d3Smrg CacheRegister(DP_PIX_WIDTH); 22032b578d3Smrg CacheRegister(DP_MIX); 22132b578d3Smrg CacheRegister(CLR_CMP_CNTL); 22232b578d3Smrg CacheRegister(TEX_SIZE_PITCH); 22332b578d3Smrg } 22432b578d3Smrg 22532b578d3Smrg ATIMach64WaitForIdle(pATI); 22632b578d3Smrg 22732b578d3Smrg if (pATI->OptionMMIOCache && pATI->OptionTestMMIOCache) { 22832b578d3Smrg 22932b578d3Smrg /* Only check registers we didn't restore */ 23032b578d3Smrg TestRegisterCaching(PAT_REG0); 23132b578d3Smrg TestRegisterCaching(PAT_REG1); 23232b578d3Smrg 23332b578d3Smrg TestRegisterCaching(CLR_CMP_CLR); 23432b578d3Smrg TestRegisterCaching(CLR_CMP_MSK); 23532b578d3Smrg 23632b578d3Smrg TestRegisterCachingXV(pScreenInfo); 23732b578d3Smrg } 23832b578d3Smrg pATI->NeedDRISync = FALSE; 23932b578d3Smrg 24032b578d3Smrg } 24132b578d3Smrg else 24232b578d3Smrg 24332b578d3Smrg#endif /* XF86DRI_DEVEL */ 24432b578d3Smrg { 24532b578d3Smrg ATIMach64WaitForIdle(pATI); 24632b578d3Smrg 24732b578d3Smrg if (pATI->OptionMMIOCache && pATI->OptionTestMMIOCache) 24832b578d3Smrg { 24932b578d3Smrg /* 25032b578d3Smrg * For debugging purposes, attempt to verify that each cached register 25132b578d3Smrg * should actually be cached. 25232b578d3Smrg */ 25332b578d3Smrg TestRegisterCachingDP(pScreenInfo); 25432b578d3Smrg 25532b578d3Smrg TestRegisterCachingXV(pScreenInfo); 25632b578d3Smrg } 25732b578d3Smrg } 25832b578d3Smrg 25932b578d3Smrg#ifdef USE_EXA 26032b578d3Smrg /* EXA sets pEXA->needsSync to FALSE on its own */ 26132b578d3Smrg#endif 26232b578d3Smrg 26332b578d3Smrg#ifdef USE_XAA 26432b578d3Smrg if (pATI->pXAAInfo) 26532b578d3Smrg pATI->pXAAInfo->NeedToSync = FALSE; 26632b578d3Smrg#endif 26732b578d3Smrg 26832b578d3Smrg if (pATI->Chip >= ATI_CHIP_264VTB) 26932b578d3Smrg { 27032b578d3Smrg /* 27132b578d3Smrg * Flush the read-back cache (by turning on INVALIDATE_RB_CACHE), 27232b578d3Smrg * otherwise the host might get stale data when reading through the 27332b578d3Smrg * aperture. 27432b578d3Smrg */ 27532b578d3Smrg outr(MEM_BUF_CNTL, pATI->NewHW.mem_buf_cntl); 27632b578d3Smrg } 27732b578d3Smrg 27832b578d3Smrg /* 27932b578d3Smrg * Note: 28032b578d3Smrg * Before actually invalidating the read-back cache, the mach64 driver 28132b578d3Smrg * was using the trick below which is buggy. The code is left here for 28232b578d3Smrg * reference, DRI uses this trick and needs updating. 28332b578d3Smrg * 28432b578d3Smrg * For VTB's and later, the first CPU read of the framebuffer will return 28532b578d3Smrg * zeroes, so do it here. This appears to be due to some kind of engine 28632b578d3Smrg * caching of framebuffer data I haven't found any way of disabling, or 28732b578d3Smrg * otherwise circumventing. Thanks to Mark Vojkovich for the suggestion. 28832b578d3Smrg * 28932b578d3Smrg * pATI = *(volatile ATIPtr *)pATI->pMemory; 29032b578d3Smrg */ 29132b578d3Smrg} 29232b578d3Smrg 29332b578d3Smrgstatic __inline__ void 29432b578d3SmrgTestRegisterCachingDP(ScrnInfoPtr pScreenInfo) 29532b578d3Smrg{ 29632b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 29732b578d3Smrg 29832b578d3Smrg TestRegisterCaching(SRC_CNTL); 29932b578d3Smrg 30032b578d3Smrg if (pATI->Chip >= ATI_CHIP_264GTPRO) 30132b578d3Smrg { 30232b578d3Smrg TestRegisterCaching(SCALE_3D_CNTL); 30332b578d3Smrg } 30432b578d3Smrg 30532b578d3Smrg TestRegisterCaching(HOST_CNTL); 30632b578d3Smrg 30732b578d3Smrg TestRegisterCaching(PAT_REG0); 30832b578d3Smrg TestRegisterCaching(PAT_REG1); 30932b578d3Smrg TestRegisterCaching(PAT_CNTL); 31032b578d3Smrg 31132b578d3Smrg if (RegisterIsCached(SC_LEFT_RIGHT) && /* Special case */ 31232b578d3Smrg (CacheSlot(SC_LEFT_RIGHT) != 31332b578d3Smrg (SetWord(inm(SC_RIGHT), 1) | SetWord(inm(SC_LEFT), 0)))) 31432b578d3Smrg { 31532b578d3Smrg UncacheRegister(SC_LEFT_RIGHT); 31632b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 31732b578d3Smrg "SC_LEFT_RIGHT write cache disabled!\n"); 31832b578d3Smrg } 31932b578d3Smrg 32032b578d3Smrg if (RegisterIsCached(SC_TOP_BOTTOM) && /* Special case */ 32132b578d3Smrg (CacheSlot(SC_TOP_BOTTOM) != 32232b578d3Smrg (SetWord(inm(SC_BOTTOM), 1) | SetWord(inm(SC_TOP), 0)))) 32332b578d3Smrg { 32432b578d3Smrg UncacheRegister(SC_TOP_BOTTOM); 32532b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 32632b578d3Smrg "SC_TOP_BOTTOM write cache disabled!\n"); 32732b578d3Smrg } 32832b578d3Smrg 32932b578d3Smrg TestRegisterCaching(DP_BKGD_CLR); 33032b578d3Smrg TestRegisterCaching(DP_FRGD_CLR); 33132b578d3Smrg TestRegisterCaching(DP_PIX_WIDTH); 33232b578d3Smrg TestRegisterCaching(DP_MIX); 33332b578d3Smrg 33432b578d3Smrg TestRegisterCaching(CLR_CMP_CLR); 33532b578d3Smrg TestRegisterCaching(CLR_CMP_MSK); 33632b578d3Smrg TestRegisterCaching(CLR_CMP_CNTL); 33732b578d3Smrg 33832b578d3Smrg if (pATI->Chip >= ATI_CHIP_264GTPRO) 33932b578d3Smrg { 34032b578d3Smrg TestRegisterCaching(TEX_SIZE_PITCH); 34132b578d3Smrg } 34232b578d3Smrg} 34332b578d3Smrg 34432b578d3Smrgstatic __inline__ void 34532b578d3SmrgTestRegisterCachingXV(ScrnInfoPtr pScreenInfo) 34632b578d3Smrg{ 34732b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 34832b578d3Smrg 34932b578d3Smrg if (!pATI->Block1Base) 35032b578d3Smrg return; 35132b578d3Smrg 35232b578d3Smrg TestRegisterCaching(OVERLAY_Y_X_START); 35332b578d3Smrg TestRegisterCaching(OVERLAY_Y_X_END); 35432b578d3Smrg 35532b578d3Smrg TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR); 35632b578d3Smrg TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK); 35732b578d3Smrg 35832b578d3Smrg TestRegisterCaching(OVERLAY_KEY_CNTL); 35932b578d3Smrg 36032b578d3Smrg TestRegisterCaching(OVERLAY_SCALE_INC); 36132b578d3Smrg TestRegisterCaching(OVERLAY_SCALE_CNTL); 36232b578d3Smrg 36332b578d3Smrg TestRegisterCaching(SCALER_HEIGHT_WIDTH); 36432b578d3Smrg 36532b578d3Smrg TestRegisterCaching(SCALER_TEST); 36632b578d3Smrg 36732b578d3Smrg TestRegisterCaching(VIDEO_FORMAT); 36832b578d3Smrg 36932b578d3Smrg if (pATI->Chip < ATI_CHIP_264VTB) 37032b578d3Smrg { 37132b578d3Smrg TestRegisterCaching(BUF0_OFFSET); 37232b578d3Smrg TestRegisterCaching(BUF0_PITCH); 37332b578d3Smrg TestRegisterCaching(BUF1_OFFSET); 37432b578d3Smrg TestRegisterCaching(BUF1_PITCH); 37532b578d3Smrg 37632b578d3Smrg return; 37732b578d3Smrg } 37832b578d3Smrg 37932b578d3Smrg TestRegisterCaching(SCALER_BUF0_OFFSET); 38032b578d3Smrg TestRegisterCaching(SCALER_BUF1_OFFSET); 38132b578d3Smrg TestRegisterCaching(SCALER_BUF_PITCH); 38232b578d3Smrg 38332b578d3Smrg TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ); 38432b578d3Smrg TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT); 38532b578d3Smrg 38632b578d3Smrg if (pATI->Chip < ATI_CHIP_264GTPRO) 38732b578d3Smrg return; 38832b578d3Smrg 38932b578d3Smrg TestRegisterCaching(SCALER_COLOUR_CNTL); 39032b578d3Smrg 39132b578d3Smrg TestRegisterCaching(SCALER_H_COEFF0); 39232b578d3Smrg TestRegisterCaching(SCALER_H_COEFF1); 39332b578d3Smrg TestRegisterCaching(SCALER_H_COEFF2); 39432b578d3Smrg TestRegisterCaching(SCALER_H_COEFF3); 39532b578d3Smrg TestRegisterCaching(SCALER_H_COEFF4); 39632b578d3Smrg 39732b578d3Smrg TestRegisterCaching(SCALER_BUF0_OFFSET_U); 39832b578d3Smrg TestRegisterCaching(SCALER_BUF0_OFFSET_V); 39932b578d3Smrg TestRegisterCaching(SCALER_BUF1_OFFSET_U); 40032b578d3Smrg TestRegisterCaching(SCALER_BUF1_OFFSET_V); 40132b578d3Smrg} 40232b578d3Smrg 40332b578d3Smrg#ifdef USE_XAA 40432b578d3Smrg/* 40532b578d3Smrg * ATIMach64SetupForScreenToScreenCopy -- 40632b578d3Smrg * 40732b578d3Smrg * This function sets up the draw engine for a series of screen-to-screen copy 40832b578d3Smrg * operations. 40932b578d3Smrg */ 41032b578d3Smrgstatic void 41132b578d3SmrgATIMach64SetupForScreenToScreenCopy 41232b578d3Smrg( 41332b578d3Smrg ScrnInfoPtr pScreenInfo, 41432b578d3Smrg int xdir, 41532b578d3Smrg int ydir, 41632b578d3Smrg int rop, 41732b578d3Smrg unsigned int planemask, 41832b578d3Smrg int TransparencyColour 41932b578d3Smrg) 42032b578d3Smrg{ 42132b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 42232b578d3Smrg 42332b578d3Smrg ATIDRISync(pScreenInfo); 42432b578d3Smrg 42532b578d3Smrg ATIMach64WaitForFIFO(pATI, 3); 42632b578d3Smrg outf(DP_WRITE_MASK, planemask); 42732b578d3Smrg outf(DP_SRC, DP_MONO_SRC_ALLONES | 42832b578d3Smrg SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); 42932b578d3Smrg outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX)); 43032b578d3Smrg 43132b578d3Smrg#ifdef AVOID_DGA 43232b578d3Smrg 43332b578d3Smrg if (TransparencyColour == -1) 43432b578d3Smrg 43532b578d3Smrg#else /* AVOID_DGA */ 43632b578d3Smrg 43732b578d3Smrg if (!pATI->XAAForceTransBlit && (TransparencyColour == -1)) 43832b578d3Smrg 43932b578d3Smrg#endif /* AVOID_DGA */ 44032b578d3Smrg 44132b578d3Smrg { 44232b578d3Smrg outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); 44332b578d3Smrg } 44432b578d3Smrg else 44532b578d3Smrg { 44632b578d3Smrg ATIMach64WaitForFIFO(pATI, 2); 44732b578d3Smrg outf(CLR_CMP_CLR, TransparencyColour); 44832b578d3Smrg outf(CLR_CMP_CNTL, CLR_CMP_FN_EQUAL | CLR_CMP_SRC_2D); 44932b578d3Smrg } 45032b578d3Smrg 45132b578d3Smrg pATI->dst_cntl = 0; 45232b578d3Smrg 45332b578d3Smrg if (ydir > 0) 45432b578d3Smrg pATI->dst_cntl |= DST_Y_DIR; 45532b578d3Smrg if (xdir > 0) 45632b578d3Smrg pATI->dst_cntl |= DST_X_DIR; 45732b578d3Smrg 45832b578d3Smrg if (pATI->XModifier == 1) 45932b578d3Smrg outf(DST_CNTL, pATI->dst_cntl); 46032b578d3Smrg else 46132b578d3Smrg pATI->dst_cntl |= DST_24_ROT_EN; 46232b578d3Smrg} 46332b578d3Smrg 46432b578d3Smrg/* 46532b578d3Smrg * ATIMach64SubsequentScreenToScreenCopy -- 46632b578d3Smrg * 46732b578d3Smrg * This function performs a screen-to-screen copy operation. 46832b578d3Smrg */ 46932b578d3Smrgstatic void 47032b578d3SmrgATIMach64SubsequentScreenToScreenCopy 47132b578d3Smrg( 47232b578d3Smrg ScrnInfoPtr pScreenInfo, 47332b578d3Smrg int xSrc, 47432b578d3Smrg int ySrc, 47532b578d3Smrg int xDst, 47632b578d3Smrg int yDst, 47732b578d3Smrg int w, 47832b578d3Smrg int h 47932b578d3Smrg) 48032b578d3Smrg{ 48132b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 48232b578d3Smrg 48332b578d3Smrg xSrc *= pATI->XModifier; 48432b578d3Smrg xDst *= pATI->XModifier; 48532b578d3Smrg w *= pATI->XModifier; 48632b578d3Smrg 48732b578d3Smrg ATIDRISync(pScreenInfo); 48832b578d3Smrg 48932b578d3Smrg /* Disable clipping if it gets in the way */ 49032b578d3Smrg ATIMach64ValidateClip(pATI, xDst, xDst + w - 1, yDst, yDst + h - 1); 49132b578d3Smrg 49232b578d3Smrg if (!(pATI->dst_cntl & DST_X_DIR)) 49332b578d3Smrg { 49432b578d3Smrg xSrc += w - 1; 49532b578d3Smrg xDst += w - 1; 49632b578d3Smrg } 49732b578d3Smrg 49832b578d3Smrg if (!(pATI->dst_cntl & DST_Y_DIR)) 49932b578d3Smrg { 50032b578d3Smrg ySrc += h - 1; 50132b578d3Smrg yDst += h - 1; 50232b578d3Smrg } 50332b578d3Smrg 50432b578d3Smrg if (pATI->XModifier != 1) 50532b578d3Smrg outf(DST_CNTL, pATI->dst_cntl | SetBits((xDst / 4) % 6, DST_24_ROT)); 50632b578d3Smrg 50732b578d3Smrg ATIMach64WaitForFIFO(pATI, 4); 50832b578d3Smrg outf(SRC_Y_X, SetWord(xSrc, 1) | SetWord(ySrc, 0)); 50932b578d3Smrg outf(SRC_WIDTH1, w); 51032b578d3Smrg outf(DST_Y_X, SetWord(xDst, 1) | SetWord(yDst, 0)); 51132b578d3Smrg outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); 51232b578d3Smrg 51332b578d3Smrg /* 51432b578d3Smrg * On VTB's and later, the engine will randomly not wait for a copy 51532b578d3Smrg * operation to commit its results to video memory before starting the next 51632b578d3Smrg * one. The probability of such occurrences increases with GUI_WB_FLUSH 51732b578d3Smrg * (or GUI_WB_FLUSH_P) setting, bitsPerPixel and/or CRTC clock. This 51832b578d3Smrg * would point to some kind of video memory bandwidth problem were it noti 51932b578d3Smrg * for the fact that the problem occurs less often (but still occurs) when 52032b578d3Smrg * copying larger rectangles. 52132b578d3Smrg */ 52232b578d3Smrg if ((pATI->Chip >= ATI_CHIP_264VTB) && !pATI->OptionDevel) 52332b578d3Smrg ATIMach64Sync(pScreenInfo); 52432b578d3Smrg} 52532b578d3Smrg 52632b578d3Smrg/* 52732b578d3Smrg * ATIMach64SetupForSolidFill -- 52832b578d3Smrg * 52932b578d3Smrg * This function sets up the draw engine for a series of solid fills. 53032b578d3Smrg */ 53132b578d3Smrgstatic void 53232b578d3SmrgATIMach64SetupForSolidFill 53332b578d3Smrg( 53432b578d3Smrg ScrnInfoPtr pScreenInfo, 53532b578d3Smrg int colour, 53632b578d3Smrg int rop, 53732b578d3Smrg unsigned int planemask 53832b578d3Smrg) 53932b578d3Smrg{ 54032b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 54132b578d3Smrg 54232b578d3Smrg ATIDRISync(pScreenInfo); 54332b578d3Smrg 54432b578d3Smrg ATIMach64WaitForFIFO(pATI, 5); 54532b578d3Smrg outf(DP_WRITE_MASK, planemask); 54632b578d3Smrg outf(DP_SRC, DP_MONO_SRC_ALLONES | 54732b578d3Smrg SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); 54832b578d3Smrg outf(DP_FRGD_CLR, colour); 54932b578d3Smrg outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX)); 55032b578d3Smrg 55132b578d3Smrg outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); 55232b578d3Smrg 55332b578d3Smrg if (pATI->XModifier == 1) 55432b578d3Smrg outf(DST_CNTL, DST_X_DIR | DST_Y_DIR); 55532b578d3Smrg} 55632b578d3Smrg 55732b578d3Smrg/* 55832b578d3Smrg * ATIMach64SubsequentSolidFillRect -- 55932b578d3Smrg * 56032b578d3Smrg * This function performs a solid rectangle fill. 56132b578d3Smrg */ 56232b578d3Smrgstatic void 56332b578d3SmrgATIMach64SubsequentSolidFillRect 56432b578d3Smrg( 56532b578d3Smrg ScrnInfoPtr pScreenInfo, 56632b578d3Smrg int x, 56732b578d3Smrg int y, 56832b578d3Smrg int w, 56932b578d3Smrg int h 57032b578d3Smrg) 57132b578d3Smrg{ 57232b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 57332b578d3Smrg 57432b578d3Smrg ATIDRISync(pScreenInfo); 57532b578d3Smrg 57632b578d3Smrg if (pATI->XModifier != 1) 57732b578d3Smrg { 57832b578d3Smrg x *= pATI->XModifier; 57932b578d3Smrg w *= pATI->XModifier; 58032b578d3Smrg 58132b578d3Smrg outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) | 58232b578d3Smrg (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)); 58332b578d3Smrg } 58432b578d3Smrg 58532b578d3Smrg /* Disable clipping if it gets in the way */ 58632b578d3Smrg ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1); 58732b578d3Smrg 58832b578d3Smrg ATIMach64WaitForFIFO(pATI, 2); 58932b578d3Smrg outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0)); 59032b578d3Smrg outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); 59132b578d3Smrg} 59232b578d3Smrg 59332b578d3Smrg/* 59432b578d3Smrg * ATIMach64SetupForSolidLine -- 59532b578d3Smrg * 59632b578d3Smrg * This function sets up the draw engine for a series of solid lines. It is 59732b578d3Smrg * not used for 24bpp because the engine doesn't support it. 59832b578d3Smrg */ 59932b578d3Smrgstatic void 60032b578d3SmrgATIMach64SetupForSolidLine 60132b578d3Smrg( 60232b578d3Smrg ScrnInfoPtr pScreenInfo, 60332b578d3Smrg int colour, 60432b578d3Smrg int rop, 60532b578d3Smrg unsigned int planemask 60632b578d3Smrg) 60732b578d3Smrg{ 60832b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 60932b578d3Smrg 61032b578d3Smrg ATIDRISync(pScreenInfo); 61132b578d3Smrg 61232b578d3Smrg ATIMach64WaitForFIFO(pATI, 5); 61332b578d3Smrg outf(DP_WRITE_MASK, planemask); 61432b578d3Smrg outf(DP_SRC, DP_MONO_SRC_ALLONES | 61532b578d3Smrg SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); 61632b578d3Smrg outf(DP_FRGD_CLR, colour); 61732b578d3Smrg outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX)); 61832b578d3Smrg 61932b578d3Smrg outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); 62032b578d3Smrg 62132b578d3Smrg ATIMach64ValidateClip(pATI, pATI->NewHW.sc_left, pATI->NewHW.sc_right, 62232b578d3Smrg pATI->NewHW.sc_top, pATI->NewHW.sc_bottom); 62332b578d3Smrg} 62432b578d3Smrg 62532b578d3Smrg/* 62632b578d3Smrg * ATIMach64SubsequentSolidHorVertLine -- 62732b578d3Smrg * 62832b578d3Smrg * This is called to draw a solid horizontal or vertical line. This does a 62932b578d3Smrg * one-pixel wide solid fill. 63032b578d3Smrg */ 63132b578d3Smrgstatic void 63232b578d3SmrgATIMach64SubsequentSolidHorVertLine 63332b578d3Smrg( 63432b578d3Smrg ScrnInfoPtr pScreenInfo, 63532b578d3Smrg int x, 63632b578d3Smrg int y, 63732b578d3Smrg int len, 63832b578d3Smrg int dir 63932b578d3Smrg) 64032b578d3Smrg{ 64132b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 64232b578d3Smrg 64332b578d3Smrg ATIDRISync(pScreenInfo); 64432b578d3Smrg 64532b578d3Smrg ATIMach64WaitForFIFO(pATI, 3); 64632b578d3Smrg outf(DST_CNTL, DST_X_DIR | DST_Y_DIR); 64732b578d3Smrg outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0)); 64832b578d3Smrg 64932b578d3Smrg if (dir == DEGREES_0) 65032b578d3Smrg outf(DST_HEIGHT_WIDTH, SetWord(len, 1) | SetWord(1, 0)); 65132b578d3Smrg else /* if (dir == DEGREES_270) */ 65232b578d3Smrg outf(DST_HEIGHT_WIDTH, SetWord(1, 1) | SetWord(len, 0)); 65332b578d3Smrg} 65432b578d3Smrg 65532b578d3Smrg/* 65632b578d3Smrg * ATIMach64SubsequentSolidBresenhamLine -- 65732b578d3Smrg * 65832b578d3Smrg * This function draws a line using the Bresenham line engine. 65932b578d3Smrg */ 66032b578d3Smrgstatic void 66132b578d3SmrgATIMach64SubsequentSolidBresenhamLine 66232b578d3Smrg( 66332b578d3Smrg ScrnInfoPtr pScreenInfo, 66432b578d3Smrg int x, 66532b578d3Smrg int y, 66632b578d3Smrg int major, 66732b578d3Smrg int minor, 66832b578d3Smrg int err, 66932b578d3Smrg int len, 67032b578d3Smrg int octant 67132b578d3Smrg) 67232b578d3Smrg{ 67332b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 67432b578d3Smrg CARD32 dst_cntl = DST_LAST_PEL; 67532b578d3Smrg 67632b578d3Smrg if (octant & YMAJOR) 67732b578d3Smrg dst_cntl |= DST_Y_MAJOR; 67832b578d3Smrg 67932b578d3Smrg if (!(octant & XDECREASING)) 68032b578d3Smrg dst_cntl |= DST_X_DIR; 68132b578d3Smrg 68232b578d3Smrg if (!(octant & YDECREASING)) 68332b578d3Smrg dst_cntl |= DST_Y_DIR; 68432b578d3Smrg 68532b578d3Smrg ATIDRISync(pScreenInfo); 68632b578d3Smrg 68732b578d3Smrg ATIMach64WaitForFIFO(pATI, 6); 68832b578d3Smrg outf(DST_CNTL, dst_cntl); 68932b578d3Smrg outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0)); 69032b578d3Smrg outf(DST_BRES_ERR, minor + err); 69132b578d3Smrg outf(DST_BRES_INC, minor); 69232b578d3Smrg outf(DST_BRES_DEC, minor - major); 69332b578d3Smrg outf(DST_BRES_LNTH, len); 69432b578d3Smrg} 69532b578d3Smrg 69632b578d3Smrg/* 69732b578d3Smrg * ATIMach64SetupForMono8x8PatternFill -- 69832b578d3Smrg * 69932b578d3Smrg * This function sets up the draw engine for a series of 8x8 1bpp pattern 70032b578d3Smrg * fills. 70132b578d3Smrg */ 70232b578d3Smrgstatic void 70332b578d3SmrgATIMach64SetupForMono8x8PatternFill 70432b578d3Smrg( 70532b578d3Smrg ScrnInfoPtr pScreenInfo, 70632b578d3Smrg int patx, 70732b578d3Smrg int paty, 70832b578d3Smrg int fg, 70932b578d3Smrg int bg, 71032b578d3Smrg int rop, 71132b578d3Smrg unsigned int planemask 71232b578d3Smrg) 71332b578d3Smrg{ 71432b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 71532b578d3Smrg 71632b578d3Smrg ATIDRISync(pScreenInfo); 71732b578d3Smrg 71832b578d3Smrg ATIMach64WaitForFIFO(pATI, 3); 71932b578d3Smrg outf(DP_WRITE_MASK, planemask); 72032b578d3Smrg outf(DP_SRC, DP_MONO_SRC_PATTERN | 72132b578d3Smrg SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); 72232b578d3Smrg outf(DP_FRGD_CLR, fg); 72332b578d3Smrg 72432b578d3Smrg if (bg == -1) 72532b578d3Smrg { 72632b578d3Smrg outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) | 72732b578d3Smrg SetBits(MIX_DST, DP_BKGD_MIX)); 72832b578d3Smrg } 72932b578d3Smrg else 73032b578d3Smrg { 73132b578d3Smrg ATIMach64WaitForFIFO(pATI, 2); 73232b578d3Smrg outf(DP_BKGD_CLR, bg); 73332b578d3Smrg outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) | 73432b578d3Smrg SetBits(ATIMach64ALU[rop], DP_BKGD_MIX)); 73532b578d3Smrg } 73632b578d3Smrg 73732b578d3Smrg ATIMach64WaitForFIFO(pATI, 4); 73832b578d3Smrg outf(PAT_REG0, patx); 73932b578d3Smrg outf(PAT_REG1, paty); 74032b578d3Smrg outf(PAT_CNTL, PAT_MONO_EN); 74132b578d3Smrg 74232b578d3Smrg outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); 74332b578d3Smrg 74432b578d3Smrg if (pATI->XModifier == 1) 74532b578d3Smrg outf(DST_CNTL, DST_X_DIR | DST_Y_DIR); 74632b578d3Smrg} 74732b578d3Smrg 74832b578d3Smrg/* 74932b578d3Smrg * ATIMach64SubsequentMono8x8PatternFillRect -- 75032b578d3Smrg * 75132b578d3Smrg * This function performs an 8x8 1bpp pattern fill. 75232b578d3Smrg */ 75332b578d3Smrgstatic void 75432b578d3SmrgATIMach64SubsequentMono8x8PatternFillRect 75532b578d3Smrg( 75632b578d3Smrg ScrnInfoPtr pScreenInfo, 75732b578d3Smrg int patx, 75832b578d3Smrg int paty, 75932b578d3Smrg int x, 76032b578d3Smrg int y, 76132b578d3Smrg int w, 76232b578d3Smrg int h 76332b578d3Smrg) 76432b578d3Smrg{ 76532b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 76632b578d3Smrg 76732b578d3Smrg ATIDRISync(pScreenInfo); 76832b578d3Smrg 76932b578d3Smrg if (pATI->XModifier != 1) 77032b578d3Smrg { 77132b578d3Smrg x *= pATI->XModifier; 77232b578d3Smrg w *= pATI->XModifier; 77332b578d3Smrg 77432b578d3Smrg outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) | 77532b578d3Smrg (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)); 77632b578d3Smrg } 77732b578d3Smrg 77832b578d3Smrg /* Disable clipping if it gets in the way */ 77932b578d3Smrg ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1); 78032b578d3Smrg 78132b578d3Smrg ATIMach64WaitForFIFO(pATI, 2); 78232b578d3Smrg outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0)); 78332b578d3Smrg outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); 78432b578d3Smrg} 78532b578d3Smrg 78632b578d3Smrg/* 78732b578d3Smrg * ATIMach64SetupForScanlineCPUToScreenColorExpandFill -- 78832b578d3Smrg * 78932b578d3Smrg * This function sets up the engine for a series of colour expansion fills. 79032b578d3Smrg */ 79132b578d3Smrgstatic void 79232b578d3SmrgATIMach64SetupForScanlineCPUToScreenColorExpandFill 79332b578d3Smrg( 79432b578d3Smrg ScrnInfoPtr pScreenInfo, 79532b578d3Smrg int fg, 79632b578d3Smrg int bg, 79732b578d3Smrg int rop, 79832b578d3Smrg unsigned int planemask 79932b578d3Smrg) 80032b578d3Smrg{ 80132b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 80232b578d3Smrg 80332b578d3Smrg ATIDRISync(pScreenInfo); 80432b578d3Smrg 80532b578d3Smrg ATIMach64WaitForFIFO(pATI, 3); 80632b578d3Smrg outf(DP_WRITE_MASK, planemask); 80732b578d3Smrg outf(DP_SRC, DP_MONO_SRC_HOST | 80832b578d3Smrg SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); 80932b578d3Smrg outf(DP_FRGD_CLR, fg); 81032b578d3Smrg 81132b578d3Smrg if (bg == -1) 81232b578d3Smrg { 81332b578d3Smrg outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) | 81432b578d3Smrg SetBits(MIX_DST, DP_BKGD_MIX)); 81532b578d3Smrg } 81632b578d3Smrg else 81732b578d3Smrg { 81832b578d3Smrg ATIMach64WaitForFIFO(pATI, 2); 81932b578d3Smrg outf(DP_BKGD_CLR, bg); 82032b578d3Smrg outf(DP_MIX, SetBits(ATIMach64ALU[rop], DP_FRGD_MIX) | 82132b578d3Smrg SetBits(ATIMach64ALU[rop], DP_BKGD_MIX)); 82232b578d3Smrg } 82332b578d3Smrg 82432b578d3Smrg outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); 82532b578d3Smrg 82632b578d3Smrg if (pATI->XModifier == 1) 82732b578d3Smrg outf(DST_CNTL, DST_X_DIR | DST_Y_DIR); 82832b578d3Smrg} 82932b578d3Smrg 83032b578d3Smrg/* 83132b578d3Smrg * ATIMach64SubsequentScanlineCPUToScreenColorExpandFill -- 83232b578d3Smrg * 83332b578d3Smrg * This function sets up the engine for a single colour expansion fill. 83432b578d3Smrg */ 83532b578d3Smrgstatic void 83632b578d3SmrgATIMach64SubsequentScanlineCPUToScreenColorExpandFill 83732b578d3Smrg( 83832b578d3Smrg ScrnInfoPtr pScreenInfo, 83932b578d3Smrg int x, 84032b578d3Smrg int y, 84132b578d3Smrg int w, 84232b578d3Smrg int h, 84332b578d3Smrg int skipleft 84432b578d3Smrg) 84532b578d3Smrg{ 84632b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 84732b578d3Smrg 84832b578d3Smrg ATIDRISync(pScreenInfo); 84932b578d3Smrg 85032b578d3Smrg if (pATI->XModifier != 1) 85132b578d3Smrg { 85232b578d3Smrg x *= pATI->XModifier; 85332b578d3Smrg w *= pATI->XModifier; 85432b578d3Smrg skipleft *= pATI->XModifier; 85532b578d3Smrg 85632b578d3Smrg outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) | 85732b578d3Smrg (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)); 85832b578d3Smrg } 85932b578d3Smrg 86032b578d3Smrg pATI->ExpansionBitmapWidth = (w + 31) / 32; 86132b578d3Smrg 86232b578d3Smrg ATIMach64WaitForFIFO(pATI, 3); 86332b578d3Smrg pATI->sc_left = x + skipleft; 86432b578d3Smrg pATI->sc_right = x + w - 1; 86532b578d3Smrg outf(SC_LEFT_RIGHT, 86632b578d3Smrg SetWord(pATI->sc_right, 1) | SetWord(pATI->sc_left, 0)); 86732b578d3Smrg outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0)); 86832b578d3Smrg outf(DST_HEIGHT_WIDTH, 86932b578d3Smrg SetWord(pATI->ExpansionBitmapWidth * 32, 1) | SetWord(h, 0)); 87032b578d3Smrg} 87132b578d3Smrg 87232b578d3Smrg/* 87332b578d3Smrg * ATIMach64SubsequentColorExpandScanline -- 87432b578d3Smrg * 87532b578d3Smrg * This function feeds a bitmap scanline to the engine for a colour expansion 87632b578d3Smrg * fill. This is written to do burst transfers for those platforms that can do 87732b578d3Smrg * them, and to improve CPU/engine concurrency. 87832b578d3Smrg */ 87932b578d3Smrgstatic void 88032b578d3SmrgATIMach64SubsequentColorExpandScanline 88132b578d3Smrg( 88232b578d3Smrg ScrnInfoPtr pScreenInfo, 88332b578d3Smrg int iBuffer 88432b578d3Smrg) 88532b578d3Smrg{ 88632b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 88732b578d3Smrg CARD32 *pBitmapData = pATI->ExpansionBitmapScanlinePtr[iBuffer]; 88832b578d3Smrg int w = pATI->ExpansionBitmapWidth; 88932b578d3Smrg int nDWord; 89032b578d3Smrg 89132b578d3Smrg ATIDRISync(pScreenInfo); 89232b578d3Smrg 89332b578d3Smrg while (w > 0) 89432b578d3Smrg { 89532b578d3Smrg /* 89632b578d3Smrg * Transfers are done in chunks of up to 64 bytes in length (32 on 89732b578d3Smrg * earlier controllers). 89832b578d3Smrg */ 89932b578d3Smrg nDWord = w; 90032b578d3Smrg if (nDWord > pATI->nHostFIFOEntries) 90132b578d3Smrg nDWord = pATI->nHostFIFOEntries; 90232b578d3Smrg 90332b578d3Smrg /* Make enough FIFO slots available */ 90432b578d3Smrg ATIMach64WaitForFIFO(pATI, nDWord); 90532b578d3Smrg 90632b578d3Smrg /* 90732b578d3Smrg * Always start transfers on a chuck-sized boundary. Note that 90832b578d3Smrg * HOST_DATA_0 is actually on a 512-byte boundary, but *pBitmapData can 90932b578d3Smrg * only be guaranteed to be on a chunk-sized boundary. 91032b578d3Smrg * 91132b578d3Smrg * Transfer current chunk. With any luck, the compiler won't mangle 91232b578d3Smrg * this too badly... 91332b578d3Smrg */ 91432b578d3Smrg 91532b578d3Smrg# if defined(ATIMove32) 91632b578d3Smrg 91732b578d3Smrg { 91832b578d3Smrg ATIMove32(pATI->pHOST_DATA, pBitmapData, nDWord); 91932b578d3Smrg } 92032b578d3Smrg 92132b578d3Smrg# else 92232b578d3Smrg 92332b578d3Smrg { 92432b578d3Smrg volatile CARD32 *pDst; 92532b578d3Smrg CARD32 *pSrc; 92632b578d3Smrg unsigned int iDWord; 92732b578d3Smrg 92832b578d3Smrg iDWord = 16 - nDWord; 92932b578d3Smrg pDst = (volatile CARD32 *)pATI->pHOST_DATA - iDWord; 93032b578d3Smrg pSrc = pBitmapData - iDWord; 93132b578d3Smrg 93232b578d3Smrg switch (iDWord) 93332b578d3Smrg { 93432b578d3Smrg case 0: MMIO_MOVE32(pDst + 0, 0, *(pSrc + 0)); 93532b578d3Smrg case 1: MMIO_MOVE32(pDst + 1, 0, *(pSrc + 1)); 93632b578d3Smrg case 2: MMIO_MOVE32(pDst + 2, 0, *(pSrc + 2)); 93732b578d3Smrg case 3: MMIO_MOVE32(pDst + 3, 0, *(pSrc + 3)); 93832b578d3Smrg case 4: MMIO_MOVE32(pDst + 4, 0, *(pSrc + 4)); 93932b578d3Smrg case 5: MMIO_MOVE32(pDst + 5, 0, *(pSrc + 5)); 94032b578d3Smrg case 6: MMIO_MOVE32(pDst + 6, 0, *(pSrc + 6)); 94132b578d3Smrg case 7: MMIO_MOVE32(pDst + 7, 0, *(pSrc + 7)); 94232b578d3Smrg case 8: MMIO_MOVE32(pDst + 8, 0, *(pSrc + 8)); 94332b578d3Smrg case 9: MMIO_MOVE32(pDst + 9, 0, *(pSrc + 9)); 94432b578d3Smrg case 10: MMIO_MOVE32(pDst + 10, 0, *(pSrc + 10)); 94532b578d3Smrg case 11: MMIO_MOVE32(pDst + 11, 0, *(pSrc + 11)); 94632b578d3Smrg case 12: MMIO_MOVE32(pDst + 12, 0, *(pSrc + 12)); 94732b578d3Smrg case 13: MMIO_MOVE32(pDst + 13, 0, *(pSrc + 13)); 94832b578d3Smrg case 14: MMIO_MOVE32(pDst + 14, 0, *(pSrc + 14)); 94932b578d3Smrg case 15: MMIO_MOVE32(pDst + 15, 0, *(pSrc + 15)); 95032b578d3Smrg 95132b578d3Smrg default: /* Muffle compiler */ 95232b578d3Smrg break; 95332b578d3Smrg } 95432b578d3Smrg } 95532b578d3Smrg 95632b578d3Smrg# endif 95732b578d3Smrg 95832b578d3Smrg /* Step to next chunk */ 95932b578d3Smrg pBitmapData += nDWord; 96032b578d3Smrg w -= nDWord; 96132b578d3Smrg pATI->nAvailableFIFOEntries -= nDWord; 96232b578d3Smrg } 96332b578d3Smrg 96432b578d3Smrg pATI->EngineIsBusy = TRUE; 96532b578d3Smrg} 96632b578d3Smrg 96732b578d3Smrg/* 96832b578d3Smrg * ATIMach64AccelInit -- 96932b578d3Smrg * 97032b578d3Smrg * This function fills in structure fields needed for acceleration on Mach64 97132b578d3Smrg * variants. 97232b578d3Smrg */ 97332b578d3SmrgBool 97432b578d3SmrgATIMach64AccelInit 97532b578d3Smrg( 97632b578d3Smrg ScreenPtr pScreen 97732b578d3Smrg) 97832b578d3Smrg{ 979e35d4d8eSmrg ScrnInfoPtr pScreenInfo = xf86ScreenToScrn(pScreen); 98032b578d3Smrg ATIPtr pATI = ATIPTR(pScreenInfo); 98132b578d3Smrg XAAInfoRecPtr pXAAInfo; 98232b578d3Smrg 98332b578d3Smrg if (!(pATI->pXAAInfo = XAACreateInfoRec())) 98432b578d3Smrg return FALSE; 98532b578d3Smrg 98632b578d3Smrg pXAAInfo = pATI->pXAAInfo; 98732b578d3Smrg 98832b578d3Smrg /* This doesn't seem quite right... */ 98932b578d3Smrg if (pATI->XModifier == 1) 99032b578d3Smrg { 99132b578d3Smrg pXAAInfo->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS; 99232b578d3Smrg pXAAInfo->Flags |= LINEAR_FRAMEBUFFER; 99332b578d3Smrg } 99432b578d3Smrg 99532b578d3Smrg /* Sync */ 99632b578d3Smrg pXAAInfo->Sync = ATIMach64Sync; 99732b578d3Smrg 99832b578d3Smrg /* Screen-to-screen copy */ 99932b578d3Smrg pXAAInfo->SetupForScreenToScreenCopy = ATIMach64SetupForScreenToScreenCopy; 100032b578d3Smrg pXAAInfo->SubsequentScreenToScreenCopy = 100132b578d3Smrg ATIMach64SubsequentScreenToScreenCopy; 100232b578d3Smrg 100332b578d3Smrg /* Solid fills */ 100432b578d3Smrg pXAAInfo->SetupForSolidFill = ATIMach64SetupForSolidFill; 100532b578d3Smrg pXAAInfo->SubsequentSolidFillRect = ATIMach64SubsequentSolidFillRect; 100632b578d3Smrg 100732b578d3Smrg /* 8x8 mono pattern fills */ 100832b578d3Smrg pXAAInfo->Mono8x8PatternFillFlags = 100932b578d3Smrg 101032b578d3Smrg#if X_BYTE_ORDER != X_LITTLE_ENDIAN 101132b578d3Smrg 101232b578d3Smrg BIT_ORDER_IN_BYTE_MSBFIRST | 101332b578d3Smrg 101432b578d3Smrg#endif /* X_BYTE_ORDER */ 101532b578d3Smrg 101632b578d3Smrg HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN; 101732b578d3Smrg pXAAInfo->SetupForMono8x8PatternFill = ATIMach64SetupForMono8x8PatternFill; 101832b578d3Smrg pXAAInfo->SubsequentMono8x8PatternFillRect = 101932b578d3Smrg ATIMach64SubsequentMono8x8PatternFillRect; 102032b578d3Smrg 102132b578d3Smrg /* 102232b578d3Smrg * Use scanline version of colour expansion, not only for the non-ix86 102332b578d3Smrg * case, but also to avoid PCI retries. 102432b578d3Smrg */ 102532b578d3Smrg pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags = 102632b578d3Smrg LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X | 102732b578d3Smrg CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD; 102832b578d3Smrg if (pATI->XModifier != 1) 102932b578d3Smrg pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags |= TRIPLE_BITS_24BPP; 103032b578d3Smrg pXAAInfo->NumScanlineColorExpandBuffers = 1; 103132b578d3Smrg 103232b578d3Smrg /* Align bitmap data on a 64-byte boundary */ 103332b578d3Smrg pATI->ExpansionBitmapWidth = /* DWord size in bits */ 103432b578d3Smrg ((pATI->displayWidth * pATI->XModifier) + 31) & ~31U; 103532b578d3Smrg pATI->ExpansionBitmapScanlinePtr[1] = 103632b578d3Smrg (CARD32 *)xnfalloc((pATI->ExpansionBitmapWidth >> 3) + 63); 103732b578d3Smrg pATI->ExpansionBitmapScanlinePtr[0] = 103832b578d3Smrg (pointer)(((unsigned long)pATI->ExpansionBitmapScanlinePtr[1] + 63) & 103932b578d3Smrg ~63UL); 104032b578d3Smrg pXAAInfo->ScanlineColorExpandBuffers = 104132b578d3Smrg (CARD8 **)pATI->ExpansionBitmapScanlinePtr; 104232b578d3Smrg pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill = 104332b578d3Smrg ATIMach64SetupForScanlineCPUToScreenColorExpandFill; 104432b578d3Smrg pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill = 104532b578d3Smrg ATIMach64SubsequentScanlineCPUToScreenColorExpandFill; 104632b578d3Smrg pXAAInfo->SubsequentColorExpandScanline = 104732b578d3Smrg ATIMach64SubsequentColorExpandScanline; 104832b578d3Smrg 104932b578d3Smrg /* The engine does not support the following primitives for 24bpp */ 105032b578d3Smrg if (pATI->XModifier != 1) 105132b578d3Smrg goto XAAInit; 105232b578d3Smrg 105332b578d3Smrg /* Solid lines */ 105432b578d3Smrg pXAAInfo->SetupForSolidLine = ATIMach64SetupForSolidLine; 105532b578d3Smrg pXAAInfo->SubsequentSolidHorVertLine = ATIMach64SubsequentSolidHorVertLine; 105632b578d3Smrg pXAAInfo->SubsequentSolidBresenhamLine = 105732b578d3Smrg ATIMach64SubsequentSolidBresenhamLine; 105832b578d3Smrg 105932b578d3SmrgXAAInit: 106032b578d3Smrg if (!XAAInit(pScreen, pATI->pXAAInfo)) { 106132b578d3Smrg XAADestroyInfoRec(pATI->pXAAInfo); 106232b578d3Smrg pATI->pXAAInfo = NULL; 106332b578d3Smrg return FALSE; 106432b578d3Smrg } 106532b578d3Smrg 106632b578d3Smrg return TRUE; 106732b578d3Smrg} 106832b578d3Smrg#endif /* USE_XAA */ 1069