From 5676a2a6105afdfc343e7f36f3c87e528a9d14b3 Mon Sep 17 00:00:00 2001 From: Michel Daenzer Date: Sun, 2 Jun 2002 16:00:45 +0000 Subject: fixes for big endian in general and powerpc in particular --- linux/r128_drv.h | 49 +++++++++------------------------------- linux/radeon_cp.c | 6 ++++- linux/radeon_drv.c | 4 ++-- linux/radeon_drv.h | 63 +++++++++++++++++++++++----------------------------- linux/radeon_state.c | 10 +++++++++ 5 files changed, 55 insertions(+), 77 deletions(-) (limited to 'linux') diff --git a/linux/r128_drv.h b/linux/r128_drv.h index 4b46db08..0485deda 100644 --- a/linux/r128_drv.h +++ b/linux/r128_drv.h @@ -34,8 +34,8 @@ #ifndef __R128_DRV_H__ #define __R128_DRV_H__ -#define GET_RING_HEAD( ring ) le32_to_cpu( *(ring)->head ) -#define SET_RING_HEAD( ring, val ) *(ring)->head = cpu_to_le32( val ) +#define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head ) +#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head ) typedef struct drm_r128_freelist { unsigned int age; @@ -384,44 +384,11 @@ extern int r128_cce_indirect( struct inode *inode, struct file *filp, #define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define R128_ADDR(reg) (R128_BASE( reg ) + reg) -#define R128_DEREF(reg) *(volatile u32 *)R128_ADDR( reg ) -#ifdef __alpha__ -#define R128_READ(reg) (_R128_READ((u32 *)R128_ADDR(reg))) -static inline u32 _R128_READ(u32 *addr) -{ - mb(); - return *(volatile u32 *)addr; -} -#define R128_WRITE(reg,val) \ -do { \ - wmb(); \ - R128_DEREF(reg) = val; \ -} while (0) -#else -#define R128_READ(reg) le32_to_cpu( R128_DEREF( reg ) ) -#define R128_WRITE(reg,val) \ -do { \ - R128_DEREF( reg ) = cpu_to_le32( val ); \ -} while (0) -#endif +#define R128_READ(reg) readl( (volatile u32 *) R128_ADDR(reg) ) +#define R128_WRITE(reg,val) writel( (val), (volatile u32 *) R128_ADDR(reg) ) -#define R128_DEREF8(reg) *(volatile u8 *)R128_ADDR( reg ) -#ifdef __alpha__ -#define R128_READ8(reg) _R128_READ8((u8 *)R128_ADDR(reg)) -static inline u8 _R128_READ8(u8 *addr) -{ - mb(); - return *(volatile u8 *)addr; -} -#define R128_WRITE8(reg,val) \ -do { \ - wmb(); \ - R128_DEREF8(reg) = val; \ -} while (0) -#else -#define R128_READ8(reg) R128_DEREF8( reg ) -#define R128_WRITE8(reg,val) do { R128_DEREF8( reg ) = val; } while (0) -#endif +#define R128_READ8(reg) readb( (volatile u8 *) R128_ADDR(reg) ) +#define R128_WRITE8(reg,val) writeb( (val), (volatile u8 *) R128_ADDR(reg) ) #define R128_WRITE_PLL(addr,val) \ do { \ @@ -493,7 +460,11 @@ do { \ * Ring control */ +#if defined(__powerpc__) +#define r128_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) +#else #define r128_flush_write_combine() mb() +#endif #define R128_VERBOSE 0 diff --git a/linux/radeon_cp.c b/linux/radeon_cp.c index 0823edd0..14901f59 100644 --- a/linux/radeon_cp.c +++ b/linux/radeon_cp.c @@ -40,7 +40,7 @@ #define RADEON_FIFO_DEBUG 0 -#if defined(__alpha__) +#if defined(__alpha__) || defined(__powerpc__) # define PCIGART_ENABLED #else # undef PCIGART_ENABLED @@ -631,7 +631,11 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, } /* Set ring buffer size */ +#ifdef __BIG_ENDIAN + RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT ); +#else RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); +#endif radeon_do_wait_for_idle( dev_priv ); diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c index 4dea95f6..135dd184 100644 --- a/linux/radeon_drv.c +++ b/linux/radeon_drv.c @@ -39,11 +39,11 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20010405" +#define DRIVER_DATE "20020602" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 +#define DRIVER_PATCHLEVEL 1 /* Interface history: * diff --git a/linux/radeon_drv.h b/linux/radeon_drv.h index abbf7179..d6a90078 100644 --- a/linux/radeon_drv.h +++ b/linux/radeon_drv.h @@ -31,6 +31,9 @@ #ifndef __RADEON_DRV_H__ #define __RADEON_DRV_H__ +#define GET_RING_HEAD(ring) readl( (volatile u32 *) (ring)->head ) +#define SET_RING_HEAD(ring,val) writel( (val), (volatile u32 *) (ring)->head ) + typedef struct drm_radeon_freelist { unsigned int age; drm_buf_t *buf; @@ -152,7 +155,7 @@ extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ); static inline void radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring ) { - ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32); + ring->space = (GET_RING_HEAD(ring) - ring->tail) * sizeof(u32); if ( ring->space <= 0 ) ring->space += ring->size; } @@ -255,6 +258,12 @@ extern int radeon_cp_vertex2( struct inode *inode, struct file *filp, # define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) # define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) +#define RADEON_RBBM_GUICNTL 0x172c +# define RADEON_HOST_DATA_SWAP_NONE (0 << 0) +# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0) +# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0) +# define RADEON_HOST_DATA_SWAP_HDW (3 << 0) + #define RADEON_MC_AGP_LOCATION 0x014c #define RADEON_MC_FB_LOCATION 0x0148 #define RADEON_MCLK_CNTL 0x0012 @@ -424,6 +433,7 @@ extern int radeon_cp_vertex2( struct inode *inode, struct file *filp, #define RADEON_CP_RB_BASE 0x0700 #define RADEON_CP_RB_CNTL 0x0704 +# define RADEON_BUF_SWAP_32BIT (2 << 16) #define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_WPTR 0x0714 @@ -530,41 +540,11 @@ extern int radeon_cp_vertex2( struct inode *inode, struct file *filp, #define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) #define RADEON_ADDR(reg) (RADEON_BASE( reg ) + reg) -#define RADEON_DEREF(reg) *(volatile u32 *)RADEON_ADDR( reg ) -#ifdef __alpha__ -#define RADEON_READ(reg) (_RADEON_READ((u32 *)RADEON_ADDR( reg ))) -static inline u32 _RADEON_READ(u32 *addr) -{ - mb(); - return *(volatile u32 *)addr; -} -#define RADEON_WRITE(reg,val) \ -do { \ - wmb(); \ - RADEON_DEREF(reg) = val; \ -} while (0) -#else -#define RADEON_READ(reg) RADEON_DEREF( reg ) -#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0) -#endif +#define RADEON_READ(reg) readl( (volatile u32 *) RADEON_ADDR(reg) ) +#define RADEON_WRITE(reg,val) writel( (val), (volatile u32 *) RADEON_ADDR(reg) ) -#define RADEON_DEREF8(reg) *(volatile u8 *)RADEON_ADDR( reg ) -#ifdef __alpha__ -#define RADEON_READ8(reg) _RADEON_READ8((u8 *)RADEON_ADDR( reg )) -static inline u8 _RADEON_READ8(u8 *addr) -{ - mb(); - return *(volatile u8 *)addr; -} -#define RADEON_WRITE8(reg,val) \ -do { \ - wmb(); \ - RADEON_DEREF8( reg ) = val; \ -} while (0) -#else -#define RADEON_READ8(reg) RADEON_DEREF8( reg ) -#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0) -#endif +#define RADEON_READ8(reg) readb( (volatile u8 *) RADEON_ADDR(reg) ) +#define RADEON_WRITE8(reg,val) writeb( (val), (volatile u8 *) RADEON_ADDR(reg) ) #define RADEON_WRITE_PLL( addr, val ) \ do { \ @@ -661,6 +641,15 @@ do { \ goto __ring_space_done; \ udelay( 1 ); \ } \ + DRM_ERROR( "ring space check from memory failed, reading register...\n" ); \ + /* If ring space check fails from RAM, try reading the \ + register directly */ \ + ring->space = 4 * ( RADEON_READ( RADEON_CP_RB_RPTR ) - ring->tail ); \ + if ( ring->space <= 0 ) \ + ring->space += ring->size; \ + if ( ring->space >= ring->high_mark ) \ + goto __ring_space_done; \ + \ DRM_ERROR( "ring space check failed!\n" ); \ return -EBUSY; \ } \ @@ -698,7 +687,11 @@ do { \ * Ring control */ +#if defined(__powerpc__) +#define radeon_flush_write_combine() (void) GET_RING_HEAD( &dev_priv->ring ) +#else #define radeon_flush_write_combine() mb() +#endif #define RADEON_VERBOSE 0 diff --git a/linux/radeon_state.c b/linux/radeon_state.c index 79b29134..cc518a0e 100644 --- a/linux/radeon_state.c +++ b/linux/radeon_state.c @@ -1062,6 +1062,16 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev, ADVANCE_RING(); +#ifdef __BIG_ENDIAN + /* The Mesa texture functions provide the data in little endian as the + * chip wants it, but we need to compensate for the fact that the CP + * ring gets byte-swapped + */ + BEGIN_RING( 2 ); + OUT_RING_REG( RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT ); + ADVANCE_RING(); +#endif + /* Make a copy of the parameters in case we have to update them * for a multi-pass texture blit. */ -- cgit v1.2.3