diff options
Diffstat (limited to 'src/atimach64accel.c')
-rw-r--r-- | src/atimach64accel.c | 308 |
1 files changed, 167 insertions, 141 deletions
diff --git a/src/atimach64accel.c b/src/atimach64accel.c index 1ecb13b..442dcf7 100644 --- a/src/atimach64accel.c +++ b/src/atimach64accel.c @@ -79,7 +79,7 @@ /* * X-to-Mach64 mix translation table. */ -static CARD8 ATIMach64ALU[16] = +CARD8 ATIMach64ALU[16] = { MIX_0, /* GXclear */ MIX_AND, /* GXand */ @@ -105,7 +105,7 @@ static CARD8 ATIMach64ALU[16] = * This function ensures the current scissor settings do not interfere with * the current draw request. */ -static void +void ATIMach64ValidateClip ( ATIPtr pATI, @@ -130,6 +130,9 @@ ATIMach64ValidateClip } } +static __inline__ void TestRegisterCachingDP(ScrnInfoPtr pScreenInfo); +static __inline__ void TestRegisterCachingXV(ScrnInfoPtr pScreenInfo); + /* * ATIMach64Sync -- * @@ -148,19 +151,22 @@ ATIMach64Sync if ( pATI->directRenderingEnabled && pATI->NeedDRISync ) { ATIHWPtr pATIHW = &pATI->NewHW; + CARD32 offset; if (pATI->OptionMMIOCache) { /* "Invalidate" the MMIO cache so the cache slots get updated */ UncacheRegister(SRC_CNTL); + UncacheRegister(SCALE_3D_CNTL); UncacheRegister(HOST_CNTL); UncacheRegister(PAT_CNTL); UncacheRegister(SC_LEFT_RIGHT); UncacheRegister(SC_TOP_BOTTOM); UncacheRegister(DP_BKGD_CLR); UncacheRegister(DP_FRGD_CLR); - UncacheRegister(DP_WRITE_MASK); + UncacheRegister(DP_PIX_WIDTH); UncacheRegister(DP_MIX); UncacheRegister(CLR_CMP_CNTL); + UncacheRegister(TEX_SIZE_PITCH); } ATIDRIWaitForIdle(pATI); @@ -181,12 +187,19 @@ ATIMach64Sync outf( DP_MIX, pATIHW->dp_mix ); outf( DP_FRGD_CLR, pATIHW->dp_frgd_clr ); outf( DP_WRITE_MASK, pATIHW->dp_write_mask ); - outf( DP_PIX_WIDTH, pATIHW->dp_pix_width ); + outf( CLR_CMP_CNTL, pATIHW->clr_cmp_cntl ); + + offset = TEX_LEVEL(pATIHW->tex_size_pitch); + + ATIMach64WaitForFIFO(pATI, 6); outf( ALPHA_TST_CNTL, 0 ); outf( Z_CNTL, 0 ); - outf( SCALE_3D_CNTL, 0 ); + outf( SCALE_3D_CNTL, pATIHW->scale_3d_cntl ); + outf( TEX_0_OFF + offset, pATIHW->tex_offset ); + outf( TEX_SIZE_PITCH, pATIHW->tex_size_pitch ); + outf( TEX_CNTL, pATIHW->tex_cntl ); ATIMach64WaitForFIFO(pATI, 2); outf( SC_LEFT_RIGHT, @@ -197,15 +210,17 @@ ATIMach64Sync if (pATI->OptionMMIOCache) { /* Now that the cache slots reflect the register state, re-enable MMIO cache */ CacheRegister(SRC_CNTL); + CacheRegister(SCALE_3D_CNTL); CacheRegister(HOST_CNTL); CacheRegister(PAT_CNTL); CacheRegister(SC_LEFT_RIGHT); CacheRegister(SC_TOP_BOTTOM); CacheRegister(DP_BKGD_CLR); CacheRegister(DP_FRGD_CLR); - CacheRegister(DP_WRITE_MASK); + CacheRegister(DP_PIX_WIDTH); CacheRegister(DP_MIX); CacheRegister(CLR_CMP_CNTL); + CacheRegister(TEX_SIZE_PITCH); } ATIMach64WaitForIdle(pATI); @@ -219,58 +234,7 @@ ATIMach64Sync TestRegisterCaching(CLR_CMP_CLR); TestRegisterCaching(CLR_CMP_MSK); - if (pATI->Block1Base) - { - TestRegisterCaching(OVERLAY_Y_X_START); - TestRegisterCaching(OVERLAY_Y_X_END); - - TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR); - TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK); - - TestRegisterCaching(OVERLAY_KEY_CNTL); - - TestRegisterCaching(OVERLAY_SCALE_INC); - TestRegisterCaching(OVERLAY_SCALE_CNTL); - - TestRegisterCaching(SCALER_HEIGHT_WIDTH); - - TestRegisterCaching(SCALER_TEST); - - TestRegisterCaching(VIDEO_FORMAT); - - if (pATI->Chip < ATI_CHIP_264VTB) - { - TestRegisterCaching(BUF0_OFFSET); - TestRegisterCaching(BUF0_PITCH); - TestRegisterCaching(BUF1_OFFSET); - TestRegisterCaching(BUF1_PITCH); - } - else - { - TestRegisterCaching(SCALER_BUF0_OFFSET); - TestRegisterCaching(SCALER_BUF1_OFFSET); - TestRegisterCaching(SCALER_BUF_PITCH); - - TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ); - TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT); - - if (pATI->Chip >= ATI_CHIP_264GTPRO) - { - TestRegisterCaching(SCALER_COLOUR_CNTL); - - TestRegisterCaching(SCALER_H_COEFF0); - TestRegisterCaching(SCALER_H_COEFF1); - TestRegisterCaching(SCALER_H_COEFF2); - TestRegisterCaching(SCALER_H_COEFF3); - TestRegisterCaching(SCALER_H_COEFF4); - - TestRegisterCaching(SCALER_BUF0_OFFSET_U); - TestRegisterCaching(SCALER_BUF0_OFFSET_V); - TestRegisterCaching(SCALER_BUF1_OFFSET_U); - TestRegisterCaching(SCALER_BUF1_OFFSET_V); - } - } - } + TestRegisterCachingXV(pScreenInfo); } pATI->NeedDRISync = FALSE; @@ -287,108 +251,157 @@ ATIMach64Sync * For debugging purposes, attempt to verify that each cached register * should actually be cached. */ - TestRegisterCaching(SRC_CNTL); + TestRegisterCachingDP(pScreenInfo); - TestRegisterCaching(HOST_CNTL); + TestRegisterCachingXV(pScreenInfo); + } + } - TestRegisterCaching(PAT_REG0); - TestRegisterCaching(PAT_REG1); - TestRegisterCaching(PAT_CNTL); +#ifdef USE_EXA + /* EXA sets pEXA->needsSync to FALSE on its own */ +#endif - if (RegisterIsCached(SC_LEFT_RIGHT) && /* Special case */ - (CacheSlot(SC_LEFT_RIGHT) != - (SetWord(inm(SC_RIGHT), 1) | SetWord(inm(SC_LEFT), 0)))) - { - UncacheRegister(SC_LEFT_RIGHT); - xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, - "SC_LEFT_RIGHT write cache disabled!\n"); - } +#ifdef USE_XAA + if (pATI->pXAAInfo) + pATI->pXAAInfo->NeedToSync = FALSE; +#endif - if (RegisterIsCached(SC_TOP_BOTTOM) && /* Special case */ - (CacheSlot(SC_TOP_BOTTOM) != - (SetWord(inm(SC_BOTTOM), 1) | SetWord(inm(SC_TOP), 0)))) - { - UncacheRegister(SC_TOP_BOTTOM); - xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, - "SC_TOP_BOTTOM write cache disabled!\n"); - } + if (pATI->Chip >= ATI_CHIP_264VTB) + { + /* + * Flush the read-back cache (by turning on INVALIDATE_RB_CACHE), + * otherwise the host might get stale data when reading through the + * aperture. + */ + outr(MEM_BUF_CNTL, pATI->NewHW.mem_buf_cntl); + } - TestRegisterCaching(DP_BKGD_CLR); - TestRegisterCaching(DP_FRGD_CLR); - TestRegisterCaching(DP_WRITE_MASK); - TestRegisterCaching(DP_MIX); + /* + * Note: + * Before actually invalidating the read-back cache, the mach64 driver + * was using the trick below which is buggy. The code is left here for + * reference, DRI uses this trick and needs updating. + * + * For VTB's and later, the first CPU read of the framebuffer will return + * zeroes, so do it here. This appears to be due to some kind of engine + * caching of framebuffer data I haven't found any way of disabling, or + * otherwise circumventing. Thanks to Mark Vojkovich for the suggestion. + * + * pATI = *(volatile ATIPtr *)pATI->pMemory; + */ +} - TestRegisterCaching(CLR_CMP_CLR); - TestRegisterCaching(CLR_CMP_MSK); - TestRegisterCaching(CLR_CMP_CNTL); +static __inline__ void +TestRegisterCachingDP(ScrnInfoPtr pScreenInfo) +{ + ATIPtr pATI = ATIPTR(pScreenInfo); - if (pATI->Block1Base) - { - TestRegisterCaching(OVERLAY_Y_X_START); - TestRegisterCaching(OVERLAY_Y_X_END); + TestRegisterCaching(SRC_CNTL); - TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR); - TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK); + if (pATI->Chip >= ATI_CHIP_264GTPRO) + { + TestRegisterCaching(SCALE_3D_CNTL); + } - TestRegisterCaching(OVERLAY_KEY_CNTL); + TestRegisterCaching(HOST_CNTL); - TestRegisterCaching(OVERLAY_SCALE_INC); - TestRegisterCaching(OVERLAY_SCALE_CNTL); + TestRegisterCaching(PAT_REG0); + TestRegisterCaching(PAT_REG1); + TestRegisterCaching(PAT_CNTL); - TestRegisterCaching(SCALER_HEIGHT_WIDTH); + if (RegisterIsCached(SC_LEFT_RIGHT) && /* Special case */ + (CacheSlot(SC_LEFT_RIGHT) != + (SetWord(inm(SC_RIGHT), 1) | SetWord(inm(SC_LEFT), 0)))) + { + UncacheRegister(SC_LEFT_RIGHT); + xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, + "SC_LEFT_RIGHT write cache disabled!\n"); + } - TestRegisterCaching(SCALER_TEST); + if (RegisterIsCached(SC_TOP_BOTTOM) && /* Special case */ + (CacheSlot(SC_TOP_BOTTOM) != + (SetWord(inm(SC_BOTTOM), 1) | SetWord(inm(SC_TOP), 0)))) + { + UncacheRegister(SC_TOP_BOTTOM); + xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, + "SC_TOP_BOTTOM write cache disabled!\n"); + } - TestRegisterCaching(VIDEO_FORMAT); + TestRegisterCaching(DP_BKGD_CLR); + TestRegisterCaching(DP_FRGD_CLR); + TestRegisterCaching(DP_PIX_WIDTH); + TestRegisterCaching(DP_MIX); - if (pATI->Chip < ATI_CHIP_264VTB) - { - TestRegisterCaching(BUF0_OFFSET); - TestRegisterCaching(BUF0_PITCH); - TestRegisterCaching(BUF1_OFFSET); - TestRegisterCaching(BUF1_PITCH); - } - else - { - TestRegisterCaching(SCALER_BUF0_OFFSET); - TestRegisterCaching(SCALER_BUF1_OFFSET); - TestRegisterCaching(SCALER_BUF_PITCH); - - TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ); - TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT); - - if (pATI->Chip >= ATI_CHIP_264GTPRO) - { - TestRegisterCaching(SCALER_COLOUR_CNTL); - - TestRegisterCaching(SCALER_H_COEFF0); - TestRegisterCaching(SCALER_H_COEFF1); - TestRegisterCaching(SCALER_H_COEFF2); - TestRegisterCaching(SCALER_H_COEFF3); - TestRegisterCaching(SCALER_H_COEFF4); - - TestRegisterCaching(SCALER_BUF0_OFFSET_U); - TestRegisterCaching(SCALER_BUF0_OFFSET_V); - TestRegisterCaching(SCALER_BUF1_OFFSET_U); - TestRegisterCaching(SCALER_BUF1_OFFSET_V); - } - } - } - } + TestRegisterCaching(CLR_CMP_CLR); + TestRegisterCaching(CLR_CMP_MSK); + TestRegisterCaching(CLR_CMP_CNTL); + + if (pATI->Chip >= ATI_CHIP_264GTPRO) + { + TestRegisterCaching(TEX_SIZE_PITCH); } +} - /* - * For VTB's and later, the first CPU read of the framebuffer will return - * zeroes, so do it here. This appears to be due to some kind of engine - * caching of framebuffer data I haven't found any way of disabling, or - * otherwise circumventing. Thanks to Mark Vojkovich for the suggestion. - */ - if (pATI->pXAAInfo) - pATI->pXAAInfo->NeedToSync = FALSE; +static __inline__ void +TestRegisterCachingXV(ScrnInfoPtr pScreenInfo) +{ + ATIPtr pATI = ATIPTR(pScreenInfo); + + if (!pATI->Block1Base) + return; + + TestRegisterCaching(OVERLAY_Y_X_START); + TestRegisterCaching(OVERLAY_Y_X_END); - pATI = *(volatile ATIPtr *)pATI->pMemory; + TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR); + TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK); + + TestRegisterCaching(OVERLAY_KEY_CNTL); + + TestRegisterCaching(OVERLAY_SCALE_INC); + TestRegisterCaching(OVERLAY_SCALE_CNTL); + + TestRegisterCaching(SCALER_HEIGHT_WIDTH); + + TestRegisterCaching(SCALER_TEST); + + TestRegisterCaching(VIDEO_FORMAT); + + if (pATI->Chip < ATI_CHIP_264VTB) + { + TestRegisterCaching(BUF0_OFFSET); + TestRegisterCaching(BUF0_PITCH); + TestRegisterCaching(BUF1_OFFSET); + TestRegisterCaching(BUF1_PITCH); + + return; + } + + TestRegisterCaching(SCALER_BUF0_OFFSET); + TestRegisterCaching(SCALER_BUF1_OFFSET); + TestRegisterCaching(SCALER_BUF_PITCH); + + TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ); + TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT); + + if (pATI->Chip < ATI_CHIP_264GTPRO) + return; + + TestRegisterCaching(SCALER_COLOUR_CNTL); + + TestRegisterCaching(SCALER_H_COEFF0); + TestRegisterCaching(SCALER_H_COEFF1); + TestRegisterCaching(SCALER_H_COEFF2); + TestRegisterCaching(SCALER_H_COEFF3); + TestRegisterCaching(SCALER_H_COEFF4); + + TestRegisterCaching(SCALER_BUF0_OFFSET_U); + TestRegisterCaching(SCALER_BUF0_OFFSET_V); + TestRegisterCaching(SCALER_BUF1_OFFSET_U); + TestRegisterCaching(SCALER_BUF1_OFFSET_V); } +#ifdef USE_XAA /* * ATIMach64SetupForScreenToScreenCopy -- * @@ -497,6 +510,18 @@ ATIMach64SubsequentScreenToScreenCopy outf(SRC_WIDTH1, w); outf(DST_Y_X, SetWord(xDst, 1) | SetWord(yDst, 0)); outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); + + /* + * On VTB's and later, the engine will randomly not wait for a copy + * operation to commit its results to video memory before starting the next + * one. The probability of such occurrences increases with GUI_WB_FLUSH + * (or GUI_WB_FLUSH_P) setting, bitsPerPixel and/or CRTC clock. This + * would point to some kind of video memory bandwidth problem were it noti + * for the fact that the problem occurs less often (but still occurs) when + * copying larger rectangles. + */ + if ((pATI->Chip >= ATI_CHIP_264VTB) && !pATI->OptionDevel) + ATIMach64Sync(pScreenInfo); } /* @@ -1035,3 +1060,4 @@ ATIMach64AccelInit return ATIMach64MaxY; } +#endif /* USE_XAA */ |