diff options
-rw-r--r-- | src/radeon.h | 21 | ||||
-rw-r--r-- | src/radeon_driver.c | 20 |
2 files changed, 31 insertions, 10 deletions
diff --git a/src/radeon.h b/src/radeon.h index b19b017e..9e70ab58 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -39,6 +39,8 @@ #include <stdlib.h> /* For abs() */ #include <unistd.h> /* For usleep() */ +#include <sys/time.h> /* For +#include <time.h> * gettimeofday() */ #include "xf86str.h" #include "compiler.h" @@ -189,6 +191,8 @@ 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_VSYNC_TIMEOUT 20000 /* Maximum wait for VSYNC (in usecs) */ + /* Buffer are aligned on 4096 byte boundaries */ #define RADEON_BUFFER_ALIGN 0x00000fff #define RADEON_VBIOS_SIZE 0x00010000 @@ -1175,4 +1179,21 @@ static __inline__ void RADEON_SYNC(RADEONInfoPtr info, ScrnInfoPtr pScrn) #endif } +static __inline__ void radeon_init_timeout(struct timeval *endtime, + unsigned int timeout) +{ + gettimeofday(endtime, NULL); + endtime->tv_usec += timeout; + endtime->tv_sec += endtime->tv_usec / 1000000; + endtime->tv_usec %= 1000000; +} + +static __inline__ int radeon_timedout(const struct timeval *endtime) +{ + struct timeval now; + gettimeofday(&now, NULL); + return now.tv_sec == endtime->tv_sec ? + now.tv_usec > endtime->tv_usec : now.tv_sec > endtime->tv_sec; +} + #endif /* _RADEON_H_ */ diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 894131fa..418b39d1 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -759,7 +759,7 @@ void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; CARD32 crtc_gen_cntl; - int i; + struct timeval timeout; crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL); if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) || @@ -770,10 +770,10 @@ void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn) OUTREG(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR); /* Wait for it to go back up */ - for (i = 0; i < RADEON_TIMEOUT/1000; i++) { - if (INREG(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_SAVE) break; - usleep(1); - } + radeon_init_timeout(&timeout, RADEON_VSYNC_TIMEOUT); + while (!(INREG(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_SAVE) && + !radeon_timedout(&timeout)) + usleep(100); } /* Wait for vertical sync on secondary CRTC */ @@ -782,7 +782,7 @@ void RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; CARD32 crtc2_gen_cntl; - int i; + struct timeval timeout; crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL); if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) || @@ -793,10 +793,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(&timeout, RADEON_VSYNC_TIMEOUT); + while (!(INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) && + !radeon_timedout(&timeout)) + usleep(100); } |