diff --git a/src/radeon.h b/src/radeon.h index a22e481..e418947 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -187,7 +187,7 @@ typedef struct _region { /* ------------------------------------- */ #define RADEON_IDLE_RETRY 16 /* Fall out of idle loops after this count */ -#define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ +#define RADEON_TIMEOUT 200000 /* Fall out of wait loops after this count */ /* Buffer are aligned on 4096 byte boundaries */ #define RADEON_BUFFER_ALIGN 0x00000fff @@ -1178,4 +1178,20 @@ static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn) #endif } +static __inline__ void RADEON_INIT_TIMEOUT(struct timeval *tv) +{ + gettimeofday(tv, NULL); + tv->tv_usec += RADEON_TIMEOUT; + tv->tv_sec += tv->tv_usec / 1000000; + tv->tv_usec %= 1000000; +} + +static __inline__ int RADEON_TIMEDOUT(const struct timeval *tv) +{ + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec > tv->tv_sec || + (now.tv_sec == tv->tv_sec && now.tv_usec > tv->tv_usec)); +} + #endif /* _RADEON_H_ */ diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 5c20b0e..f105bf3 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -783,6 +783,7 @@ void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn) unsigned char *RADEONMMIO = info->MMIO; CARD32 crtc2_gen_cntl; int i; + struct timeval tv, tv2; crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL); if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) || @@ -793,9 +794,10 @@ void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn) OUTREG(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR); /* Wait for it to go back up */ - for (i = 0; i < RADEON_TIMEOUT/1000; i++) { - if (INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) break; - usleep(1); + RADEON_INIT_TIMEOUT(&tv); + while (!(INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) && + !RADEON_TIMEDOUT(&tv)) { + usleep(100); } }