diff options
Diffstat (limited to 'shared/mach64_drv.h')
-rw-r--r-- | shared/mach64_drv.h | 265 |
1 files changed, 177 insertions, 88 deletions
diff --git a/shared/mach64_drv.h b/shared/mach64_drv.h index 9aa55739..74880250 100644 --- a/shared/mach64_drv.h +++ b/shared/mach64_drv.h @@ -3,6 +3,7 @@ * * Copyright 2000 Gareth Hughes * Copyright 2002 Frank C. Earl + * Copyright 2002-2003 Leif Delgass * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -19,7 +20,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * THE COPYRIGHT OWNER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * @@ -47,7 +48,7 @@ typedef struct drm_mach64_freelist { } drm_mach64_freelist_t; typedef struct drm_mach64_descriptor_ring { - dma_addr_t handle; + dma_addr_t handle; /* handle (bus address) of ring returned by pci_alloc_consistent() */ void *start; /* write pointer (cpu address) to start of descriptor ring */ u32 start_addr; /* bus address of beginning of descriptor ring */ int size; /* size of ring in bytes */ @@ -69,11 +70,6 @@ typedef struct drm_mach64_private { int usec_timeout; /* Number of microseconds to wait in the idle functions */ -#if MACH64_INTERRUPTS - atomic_t intr_vblank; /* Flag for the bottom half to know what to do */ - atomic_t intr_bm_complete; /* Flag for the bottom half to know what to do */ -#endif - /* DMA descriptor table (ring buffer) */ drm_mach64_descriptor_ring_t ring; int ring_running; @@ -373,25 +369,73 @@ extern int mach64_get_param( DRM_IOCTL_ARGS ); # define MACH64_CRTC_CRNT_VLINE_MASK 0x07ff0000 #define MACH64_CRTC_OFF_PITCH 0x0414 #define MACH64_CRTC_INT_CNTL 0x0418 +# define MACH64_CRTC_VBLANK (1 << 0) # define MACH64_CRTC_VBLANK_INT_EN (1 << 1) # define MACH64_CRTC_VBLANK_INT (1 << 2) -# define MACH64_CRTC_VBLANK_INT_AK (1 << 2) # define MACH64_CRTC_VLINE_INT_EN (1 << 3) # define MACH64_CRTC_VLINE_INT (1 << 4) -# define MACH64_CRTC_VLINE_INT_AK (1 << 4) -# define MACH64_CRTC_VLINE_SYNC (1 << 5) -# define MACH64_CRTC_FRAME (1 << 6) +# define MACH64_CRTC_VLINE_SYNC (1 << 5) /* 0=even, 1=odd */ +# define MACH64_CRTC_FRAME (1 << 6) /* 0=even, 1=odd */ # define MACH64_CRTC_SNAPSHOT_INT_EN (1 << 7) # define MACH64_CRTC_SNAPSHOT_INT (1 << 8) -# define MACH64_CRTC_SNAPSHOT_INT_AK (1 << 8) +# define MACH64_CRTC_I2C_INT_EN (1 << 9) +# define MACH64_CRTC_I2C_INT (1 << 10) +# define MACH64_CRTC2_VBLANK (1 << 11) /* LT Pro */ +# define MACH64_CRTC2_VBLANK_INT_EN (1 << 12) /* LT Pro */ +# define MACH64_CRTC2_VBLANK_INT (1 << 13) /* LT Pro */ +# define MACH64_CRTC2_VLINE_INT_EN (1 << 14) /* LT Pro */ +# define MACH64_CRTC2_VLINE_INT (1 << 15) /* LT Pro */ +# define MACH64_CRTC_CAPBUF0_INT_EN (1 << 16) +# define MACH64_CRTC_CAPBUF0_INT (1 << 17) +# define MACH64_CRTC_CAPBUF1_INT_EN (1 << 18) +# define MACH64_CRTC_CAPBUF1_INT (1 << 19) +# define MACH64_CRTC_OVERLAY_EOF_INT_EN (1 << 20) +# define MACH64_CRTC_OVERLAY_EOF_INT (1 << 21) +# define MACH64_CRTC_ONESHOT_CAP_INT_EN (1 << 22) +# define MACH64_CRTC_ONESHOT_CAP_INT (1 << 23) # define MACH64_CRTC_BUSMASTER_EOL_INT_EN (1 << 24) # define MACH64_CRTC_BUSMASTER_EOL_INT (1 << 25) -# define MACH64_CRTC_BUSMASTER_EOL_INT_AK (1 << 25) # define MACH64_CRTC_GP_INT_EN (1 << 26) # define MACH64_CRTC_GP_INT (1 << 27) -# define MACH64_CRTC_GP_INT_AK (1 << 27) +# define MACH64_CRTC2_VLINE_SYNC (1 << 28) /* LT Pro */ /* 0=even, 1=odd */ +# define MACH64_CRTC_SNAPSHOT2_INT_EN (1 << 29) /* LT Pro */ +# define MACH64_CRTC_SNAPSHOT2_INT (1 << 30) /* LT Pro */ # define MACH64_CRTC_VBLANK2_INT (1 << 31) -# define MACH64_CRTC_VBLANK2_INT_AK (1 << 31) +# define MACH64_CRTC_INT_ENS \ + ( \ + MACH64_CRTC_VBLANK_INT_EN | \ + MACH64_CRTC_VLINE_INT_EN | \ + MACH64_CRTC_SNAPSHOT_INT_EN | \ + MACH64_CRTC_I2C_INT_EN | \ + MACH64_CRTC2_VBLANK_INT_EN | \ + MACH64_CRTC2_VLINE_INT_EN | \ + MACH64_CRTC_CAPBUF0_INT_EN | \ + MACH64_CRTC_CAPBUF1_INT_EN | \ + MACH64_CRTC_OVERLAY_EOF_INT_EN | \ + MACH64_CRTC_ONESHOT_CAP_INT_EN | \ + MACH64_CRTC_BUSMASTER_EOL_INT_EN | \ + MACH64_CRTC_GP_INT_EN | \ + MACH64_CRTC_SNAPSHOT2_INT_EN | \ + 0 \ + ) +# define MACH64_CRTC_INT_ACKS \ + ( \ + MACH64_CRTC_VBLANK_INT | \ + MACH64_CRTC_VLINE_INT | \ + MACH64_CRTC_SNAPSHOT_INT | \ + MACH64_CRTC_I2C_INT | \ + MACH64_CRTC2_VBLANK_INT | \ + MACH64_CRTC2_VLINE_INT | \ + MACH64_CRTC_CAPBUF0_INT | \ + MACH64_CRTC_CAPBUF1_INT | \ + MACH64_CRTC_OVERLAY_EOF_INT | \ + MACH64_CRTC_ONESHOT_CAP_INT | \ + MACH64_CRTC_BUSMASTER_EOL_INT | \ + MACH64_CRTC_GP_INT | \ + MACH64_CRTC_SNAPSHOT2_INT | \ + MACH64_CRTC_VBLANK2_INT | \ + 0 \ + ) #define MACH64_DATATYPE_CI8 2 #define MACH64_DATATYPE_ARGB1555 3 @@ -428,10 +472,121 @@ extern int mach64_get_param( DRM_IOCTL_ARGS ); #define MMSELECT(r) (ISMMREG0(r) ? MMSELECT0(r) : MMSELECT1(r)) /* ================================================================ + * DMA constants + */ + +/* DMA descriptor field indices: + * The descriptor fields are loaded into the read-only + * BM_* system bus master registers during a bus-master operation + */ +#define MACH64_DMA_FRAME_BUF_OFFSET 0 /* BM_FRAME_BUF_OFFSET */ +#define MACH64_DMA_SYS_MEM_ADDR 1 /* BM_SYSTEM_MEM_ADDR */ +#define MACH64_DMA_COMMAND 2 /* BM_COMMAND */ +#define MACH64_DMA_RESERVED 3 /* BM_STATUS */ + +/* BM_COMMAND descriptor field flags */ +#define MACH64_DMA_HOLD_OFFSET (1<<30) /* Don't increment DMA_FRAME_BUF_OFFSET */ +#define MACH64_DMA_EOL (1<<31) /* End of descriptor list flag */ + +#define MACH64_DMA_CHUNKSIZE 0x1000 /* 4kB per DMA descriptor */ +#define MACH64_APERTURE_OFFSET 0x7ff800 /* frame-buffer offset for gui-masters */ + + +/* ================================================================ * Misc helper macros */ -static inline void mach64_ring_start( drm_mach64_private_t *dev_priv ) +static __inline__ void mach64_set_dma_eol( volatile u32 * addr ) +{ +#if defined(__i386__) + int nr = 31; + + /* Taken from include/asm-i386/bitops.h linux header */ + __asm__ __volatile__( "lock;" + "btsl %1,%0" + :"=m" (*addr) + :"Ir" (nr)); +#elif defined(__powerpc__) + u32 old; + u32 mask = cpu_to_le32( MACH64_DMA_EOL ); + + /* Taken from the include/asm-ppc/bitops.h linux header */ + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + or %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ + bne- 1b" + : "=&r" (old), "=m" (*addr) + : "r" (mask), "r" (addr), "m" (*addr) + : "cc"); +#elif defined(__alpha__) + u32 temp; + u32 mask = MACH64_DMA_EOL; + + /* Taken from the include/asm-alpha/bitops.h linux header */ + __asm__ __volatile__( + "1: ldl_l %0,%3\n" + " bis %0,%2,%0\n" + " stl_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + :"=&r" (temp), "=m" (*addr) + :"Ir" (mask), "m" (*addr)); +#else + u32 mask = cpu_to_le32( MACH64_DMA_EOL ); + + *addr |= mask; +#endif +} + +static __inline__ void mach64_clear_dma_eol( volatile u32 * addr ) +{ +#if defined(__i386__) + int nr = 31; + + /* Taken from include/asm-i386/bitops.h linux header */ + __asm__ __volatile__( "lock;" + "btrl %1,%0" + :"=m" (*addr) + :"Ir" (nr)); +#elif defined(__powerpc__) + u32 old; + u32 mask = cpu_to_le32( MACH64_DMA_EOL ); + + /* Taken from the include/asm-ppc/bitops.h linux header */ + __asm__ __volatile__("\n\ +1: lwarx %0,0,%3 \n\ + andc %0,%0,%2 \n\ + stwcx. %0,0,%3 \n\ + bne- 1b" + : "=&r" (old), "=m" (*addr) + : "r" (mask), "r" (addr), "m" (*addr) + : "cc"); +#elif defined(__alpha__) + u32 temp; + u32 mask = ~MACH64_DMA_EOL; + + /* Taken from the include/asm-alpha/bitops.h linux header */ + __asm__ __volatile__( + "1: ldl_l %0,%3\n" + " and %0,%2,%0\n" + " stl_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + :"=&r" (temp), "=m" (*addr) + :"Ir" (mask), "m" (*addr)); +#else + u32 mask = cpu_to_le32( ~MACH64_DMA_EOL ); + + *addr &= mask; +#endif +} + +static __inline__ void mach64_ring_start( drm_mach64_private_t *dev_priv ) { drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; @@ -448,9 +603,8 @@ static inline void mach64_ring_start( drm_mach64_private_t *dev_priv ) MACH64_WRITE( MACH64_BUS_CNTL, ( MACH64_READ(MACH64_BUS_CNTL) & ~MACH64_BUS_MASTER_DIS ) | MACH64_BUS_EXT_REG_EN ); + mach64_do_wait_for_idle( dev_priv ); } - - mach64_do_wait_for_idle( dev_priv ); /* reset descriptor table ring head */ MACH64_WRITE( MACH64_BM_GUI_TABLE_CMD, @@ -459,7 +613,7 @@ static inline void mach64_ring_start( drm_mach64_private_t *dev_priv ) dev_priv->ring_running = 1; } -static inline void mach64_ring_resume( drm_mach64_private_t *dev_priv, +static __inline__ void mach64_ring_resume( drm_mach64_private_t *dev_priv, drm_mach64_descriptor_ring_t *ring ) { DRM_DEBUG( "%s: head_addr: 0x%08x head: %d tail: %d space: %d\n", @@ -493,7 +647,7 @@ static inline void mach64_ring_resume( drm_mach64_private_t *dev_priv, } } -static inline void mach64_ring_tick( drm_mach64_private_t *dev_priv, +static __inline__ void mach64_ring_tick( drm_mach64_private_t *dev_priv, drm_mach64_descriptor_ring_t *ring ) { DRM_DEBUG( "%s: head_addr: 0x%08x head: %d tail: %d space: %d\n", @@ -540,7 +694,7 @@ static inline void mach64_ring_tick( drm_mach64_private_t *dev_priv, } } -static inline void mach64_ring_stop( drm_mach64_private_t *dev_priv ) +static __inline__ void mach64_ring_stop( drm_mach64_private_t *dev_priv ) { DRM_DEBUG( "%s: head_addr: 0x%08x head: %d tail: %d space: %d\n", __FUNCTION__, @@ -559,7 +713,7 @@ static inline void mach64_ring_stop( drm_mach64_private_t *dev_priv ) dev_priv->ring_running = 0; } -static inline void +static __inline__ void mach64_update_ring_snapshot( drm_mach64_private_t *dev_priv ) { drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; @@ -606,25 +760,6 @@ do { \ __ring_space_done: \ } while (0) -/* ================================================================ - * DMA constants - */ - -/* DMA descriptor field indices: - * The descriptor fields are loaded into the read-only - * BM_* system bus master registers during a bus-master operation - */ -#define MACH64_DMA_FRAME_BUF_OFFSET 0 /* BM_FRAME_BUF_OFFSET */ -#define MACH64_DMA_SYS_MEM_ADDR 1 /* BM_SYSTEM_MEM_ADDR */ -#define MACH64_DMA_COMMAND 2 /* BM_COMMAND */ -#define MACH64_DMA_RESERVED 3 /* BM_STATUS */ - -/* BM_COMMAND descriptor field flags */ -#define MACH64_DMA_HOLD_OFFSET (1<<30) /* Don't increment DMA_FRAME_BUF_OFFSET */ -#define MACH64_DMA_EOL (1<<31) /* End of descriptor list flag */ - -#define MACH64_DMA_CHUNKSIZE 0x1000 /* 4kB per DMA descriptor */ -#define MACH64_APERTURE_OFFSET 0x7ff800 /* frame-buffer offset for gui-masters */ /* ================================================================ * DMA descriptor ring macros @@ -666,52 +801,6 @@ do { \ _ring_write &= _ring_mask; \ } while (0) - -static __inline__ void mach64_clear_dma_eol( volatile u32 * addr ) -{ -#if defined(__i386__) - int nr = 31; - - /* Taken from include/asm-i386/bitops.h linux header */ - __asm__ __volatile__( "lock;" - "btrl %1,%0" - :"=m" (*addr) - :"Ir" (nr)); -#elif defined(__powerpc__) - u32 old; - u32 mask = cpu_to_le32( MACH64_DMA_EOL ); - - /* Taken from the include/asm-ppc/bitops.h linux header */ - __asm__ __volatile__("\n\ -1: lwarx %0,0,%3 \n\ - andc %0,%0,%2 \n\ - stwcx. %0,0,%3 \n\ - bne- 1b" - : "=&r" (old), "=m" (*addr) - : "r" (mask), "r" (addr), "m" (*addr) - : "cc"); -#elif defined(__alpha__) - u32 temp; - u32 mask = ~MACH64_DMA_EOL; - - /* Taken from the include/asm-alpha/bitops.h linux header */ - __asm__ __volatile__( - "1: ldl_l %0,%3\n" - " and %0,%2,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (*addr) - :"Ir" (mask), "m" (*addr)); -#else - u32 mask = cpu_to_le32( ~MACH64_DMA_EOL ); - - *addr &= mask; -#endif -} - #define ADVANCE_RING() \ do { \ if ( MACH64_VERBOSE ) { \ @@ -747,7 +836,7 @@ do { \ #define GETRINGOFFSET() (_entry->ring_ofs) -static inline int mach64_find_pending_buf_entry ( drm_mach64_private_t *dev_priv, +static __inline__ int mach64_find_pending_buf_entry ( drm_mach64_private_t *dev_priv, drm_mach64_freelist_t **entry, drm_buf_t *buf ) { |