From cb63f8d9c0563fb0eff28e2be6d4adf5666540d2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 6 Sep 2005 10:03:19 +0000 Subject: Handle VIP timeouts more gracefully -- impose a hard limit of 10ms on waiting for VIP_BUSY so we don't lock up hard, spinning. --- src/radeon_vip.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/radeon_vip.c b/src/radeon_vip.c index a75a89d..cc4b635 100644 --- a/src/radeon_vip.c +++ b/src/radeon_vip.c @@ -91,6 +91,18 @@ static CARD32 RADEONVIP_fifo_idle(GENERIC_BUS_Ptr b, CARD8 channel) ((device & 0x3)<<14) | (fifo << 12) | (addr) */ +#define VIP_WAIT_FOR_IDLE() { \ + int i2ctries = 0; \ + while (i2ctries < 10) { \ + status = RADEONVIP_idle(b); \ + if (status==VIP_BUSY) \ + { \ + usleep(1000); \ + i2ctries++; \ + } else break; \ + } \ + } + static Bool RADEONVIP_read(GENERIC_BUS_Ptr b, CARD32 address, CARD32 count, CARD8 *buffer) { ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; @@ -107,7 +119,7 @@ static Bool RADEONVIP_read(GENERIC_BUS_Ptr b, CARD32 address, CARD32 count, CARD RADEONWaitForFifo(pScrn, 2); OUTREG(RADEON_VIPH_REG_ADDR, address | 0x2000); write_mem_barrier(); - while(VIP_BUSY == (status = RADEONVIP_idle(b))); + VIP_WAIT_FOR_IDLE(); if(VIP_IDLE != status) return FALSE; /* @@ -126,7 +138,7 @@ static Bool RADEONVIP_read(GENERIC_BUS_Ptr b, CARD32 address, CARD32 count, CARD RADEONWaitForIdleMMIO(pScrn); INREG(RADEON_VIPH_REG_DATA); - while(VIP_BUSY == (status = RADEONVIP_idle(b))); + VIP_WAIT_FOR_IDLE(); if(VIP_IDLE != status) return FALSE; /* set RADEON_VIPH_REGR_DIS so that the read won't take too long. @@ -147,7 +159,7 @@ static Bool RADEONVIP_read(GENERIC_BUS_Ptr b, CARD32 address, CARD32 count, CARD *(CARD32 *)buffer=(CARD32) ( INREG(RADEON_VIPH_REG_DATA) & 0xffffffff); break; } - while(VIP_BUSY == (status = RADEONVIP_idle(b))); + VIP_WAIT_FOR_IDLE(); if(VIP_IDLE != status) return FALSE; /* so that reading RADEON_VIPH_REG_DATA would not trigger unnecessary vip cycles. -- cgit v1.2.3