mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-08 15:08:05 +02:00
Use of atomic bit ops in ADVANCE_RING() to lock the BUS when writing to the
descriptor table. Slight changes to make the GUI master operations be
handled more similarly to the Mach64 SDK example.
This commit is contained in:
parent
f7aa134628
commit
8a6e0b2caa
2 changed files with 57 additions and 27 deletions
|
|
@ -489,12 +489,16 @@ static int mach64_bm_dma_test( drm_device_t *dev )
|
|||
data_addr = (u32) data_handle;
|
||||
}
|
||||
|
||||
mach64_do_wait_for_fifo( dev_priv, 4 );
|
||||
|
||||
MACH64_WRITE( MACH64_SRC_CNTL, 0 );
|
||||
|
||||
MACH64_WRITE( MACH64_VERTEX_1_S, 0x00000000 );
|
||||
MACH64_WRITE( MACH64_VERTEX_1_T, 0x00000000 );
|
||||
MACH64_WRITE( MACH64_VERTEX_1_W, 0x00000000 );
|
||||
|
||||
mach64_do_wait_for_idle( dev_priv );
|
||||
|
||||
for (i=0; i < 3; i++) {
|
||||
DRM_DEBUG( "(Before DMA Transfer) reg %d = 0x%08x\n", i,
|
||||
MACH64_READ( (MACH64_VERTEX_1_S + i*4) ) );
|
||||
|
|
|
|||
|
|
@ -476,12 +476,6 @@ static inline void mach64_ring_start( drm_mach64_private_t *dev_priv )
|
|||
( MACH64_READ(MACH64_BUS_CNTL) & ~MACH64_BUS_MASTER_DIS )
|
||||
| MACH64_BUS_EXT_REG_EN );
|
||||
|
||||
/* enable GUI bus mastering, and sync the bus master to the GUI */
|
||||
MACH64_WRITE( MACH64_SRC_CNTL,
|
||||
MACH64_SRC_BM_ENABLE | MACH64_SRC_BM_SYNC |
|
||||
MACH64_SRC_BM_OP_SYSTEM_TO_REG );
|
||||
|
||||
/* FIXME: See mach64_ring_resume */
|
||||
mach64_do_wait_for_idle( dev_priv );
|
||||
|
||||
dev_priv->ring_running = 1;
|
||||
|
|
@ -493,25 +487,11 @@ static inline void mach64_ring_resume( drm_mach64_private_t *dev_priv, drm_mach6
|
|||
__FUNCTION__,
|
||||
ring->head_addr, ring->head, ring->tail, ring->space);
|
||||
|
||||
#if 0
|
||||
/* FIXME: at this moment this is always called on idle but we could gain something by just
|
||||
* wait for FIFO when resuming the BM and in that case we will have to check for the apropriate
|
||||
* number of free entries here
|
||||
*/
|
||||
mach64_do_wait_for_fifo( dev_priv, 2 );
|
||||
#endif
|
||||
|
||||
#if MACH64_EXTRA_CHECKING
|
||||
if ( !(MACH64_READ(MACH64_SRC_CNTL) & MACH64_SRC_BM_ENABLE) ) {
|
||||
DRM_ERROR("Call of %s without BM enabled!!!\n", __FUNCTION__ );
|
||||
mach64_dump_ring_info( dev_priv );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE ) {
|
||||
DRM_ERROR("Call of %s with GUI ACTIVE!!!\n", __FUNCTION__ );
|
||||
mach64_dump_ring_info( dev_priv );
|
||||
return;
|
||||
mach64_do_wait_for_idle( dev_priv );
|
||||
}
|
||||
|
||||
if( ring->head_addr < ring->start_addr || ring->head_addr >= ring->start_addr + ring->size ) {
|
||||
|
|
@ -524,6 +504,11 @@ static inline void mach64_ring_resume( drm_mach64_private_t *dev_priv, drm_mach6
|
|||
/* reset descriptor table ring head */
|
||||
MACH64_WRITE( MACH64_BM_GUI_TABLE_CMD, ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB );
|
||||
|
||||
/* enable GUI bus mastering, and sync the bus master to the GUI */
|
||||
MACH64_WRITE( MACH64_SRC_CNTL,
|
||||
MACH64_SRC_BM_ENABLE | MACH64_SRC_BM_SYNC |
|
||||
MACH64_SRC_BM_OP_SYSTEM_TO_REG );
|
||||
|
||||
/* kick off the transfer */
|
||||
MACH64_WRITE( MACH64_DST_HEIGHT_WIDTH, 0 );
|
||||
}
|
||||
|
|
@ -538,11 +523,9 @@ static inline void mach64_ring_stop( drm_mach64_private_t *dev_priv )
|
|||
mach64_do_wait_for_fifo( dev_priv, 1 );
|
||||
MACH64_WRITE( MACH64_SRC_CNTL, 0 );
|
||||
|
||||
#if 1
|
||||
/* FIXME: This probably can be safely removed from here. */
|
||||
/* disable busmastering but keep the block 1 registers enabled */
|
||||
mach64_do_wait_for_idle( dev_priv );
|
||||
MACH64_WRITE( MACH64_BUS_CNTL, MACH64_READ( MACH64_BUS_CNTL ) | MACH64_BUS_MASTER_DIS | MACH64_BUS_EXT_REG_EN );
|
||||
#endif
|
||||
|
||||
dev_priv->ring_running = 0;
|
||||
}
|
||||
|
|
@ -556,7 +539,6 @@ do { \
|
|||
mach64_ring_start( dev_priv ); \
|
||||
} \
|
||||
/* GUI_ACTIVE must be read before BM_GUI_TABLE to correctly determine the ring head */ \
|
||||
/* FIXME: See mach64_ring_resume */ \
|
||||
gui_active = MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE; \
|
||||
(ring)->head_addr = MACH64_READ(MACH64_BM_GUI_TABLE) & 0xfffffff0; \
|
||||
if ( gui_active ) { \
|
||||
|
|
@ -662,7 +644,7 @@ do { \
|
|||
* DMA descriptor ring macros
|
||||
*/
|
||||
|
||||
#define RING_LOCALS int tail, write; unsigned int mask; volatile u32 *ring;
|
||||
#define RING_LOCALS int tail, write; unsigned int mask; volatile u32 *ring
|
||||
|
||||
#define RING_WRITE_OFS write
|
||||
|
||||
|
|
@ -699,6 +681,49 @@ do { \
|
|||
write &= mask; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#if defined(__i386__)
|
||||
|
||||
/* Taken from include/asm-i386/bitops.h linux header */
|
||||
static __inline__ void mach64_clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__asm__ __volatile__( "lock;"
|
||||
"btrl %1,%0"
|
||||
:"=m" (*(volatile long *) addr)
|
||||
:"Ir" (nr));
|
||||
}
|
||||
|
||||
#elif defined(__powerpc__)
|
||||
|
||||
/* Taken from the include/asm-ppc/bitops.h linux header */
|
||||
static __inline__ void mach64_clear_bit(int nr, volatile void *addr)
|
||||
{
|
||||
unsigned long old;
|
||||
unsigned long mask = 1 << (nr & 0x1f);
|
||||
unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
|
||||
|
||||
__asm__ __volatile__("\n\
|
||||
1: lwarx %0,0,%3 \n\
|
||||
andc %0,%0,%2 \n\
|
||||
stwcx. %0,0,%3 \n\
|
||||
bne- 1b"
|
||||
: "=&r" (old), "=m" (*p)
|
||||
: "r" (mask), "r" (p), "m" (*p)
|
||||
: "cc");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __inline__ void mach64_clear_bit(int nr, volatile void *addr)
|
||||
{
|
||||
unsigned long mask = 1 << (nr & 0x1f);
|
||||
volatile unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
|
||||
|
||||
*p &= ~mask;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define ADVANCE_RING() \
|
||||
do { \
|
||||
if ( MACH64_VERBOSE ) { \
|
||||
|
|
@ -706,7 +731,8 @@ do { \
|
|||
write, tail ); \
|
||||
} \
|
||||
mach64_flush_write_combine(); \
|
||||
ring[(tail - 2) & mask] &= cpu_to_le32( ~DMA_EOL ); \
|
||||
/* Clear DMA_EOL */ \
|
||||
mach64_clear_bit(31, &ring[(tail - 2) & mask]); \
|
||||
mach64_flush_write_combine(); \
|
||||
dev_priv->ring.tail = write; \
|
||||
UPDATE_RING_HEAD( dev_priv, &(dev_priv)->ring ); \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue