diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-03-04 16:18:17 -0500 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-03-04 16:18:17 -0500 |
commit | cf8196e6eb9723a13f2155a4e253e4f3c2698148 (patch) | |
tree | 6ae19ccb5c24614cf79e5890c22f1213ada9bff8 | |
parent | 189cd825a8a2cc2c0a28023589a5f18a4122410b (diff) |
radeon: pull in ring padding form drm-next
-rw-r--r-- | shared-core/r600_cp.c | 19 | ||||
-rw-r--r-- | shared-core/radeon_cp.c | 41 | ||||
-rw-r--r-- | shared-core/radeon_drv.h | 23 |
3 files changed, 47 insertions, 36 deletions
diff --git a/shared-core/r600_cp.c b/shared-core/r600_cp.c index 207f050f..3baef856 100644 --- a/shared-core/r600_cp.c +++ b/shared-core/r600_cp.c @@ -2525,7 +2525,7 @@ void r600_do_cp_start(drm_radeon_private_t * dev_priv) RING_LOCALS; DRM_DEBUG("\n"); - BEGIN_RING(8); + BEGIN_RING(7); OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5)); OUT_RING(0x00000001); if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) @@ -2536,7 +2536,6 @@ void r600_do_cp_start(drm_radeon_private_t * dev_priv) OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1)); OUT_RING(0x00000000); OUT_RING(0x00000000); - OUT_RING(CP_PACKET2()); ADVANCE_RING(); COMMIT_RING(); @@ -2583,14 +2582,8 @@ static void r600_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ - BEGIN_RING(8); + BEGIN_RING(2); R600_DISPATCH_AGE(buf_priv->age); - OUT_RING(CP_PACKET2()); - OUT_RING(CP_PACKET2()); - OUT_RING(CP_PACKET2()); - OUT_RING(CP_PACKET2()); - OUT_RING(CP_PACKET2()); - OUT_RING(CP_PACKET2()); ADVANCE_RING(); buf->pending = 1; @@ -2620,7 +2613,7 @@ int r600_cp_indirect(struct drm_device *dev, struct drm_buf *buf, drm_radeon_ind /* Indirect buffer data must be modulo 8. * pad the data with a Type-2 CP packet. */ - while (dwords & 7) { + while (dwords & 0xf) { u32 *data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset + start); @@ -2628,15 +2621,11 @@ int r600_cp_indirect(struct drm_device *dev, struct drm_buf *buf, drm_radeon_ind } /* Fire off the indirect buffer */ - BEGIN_RING(8); + BEGIN_RING(4); OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2)); OUT_RING((offset & 0xfffffffc)); OUT_RING((upper_32_bits(offset) & 0xff)); OUT_RING(dwords); - OUT_RING(CP_PACKET2()); - OUT_RING(CP_PACKET2()); - OUT_RING(CP_PACKET2()); - OUT_RING(CP_PACKET2()); ADVANCE_RING(); } if (indirect->discard) diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 381cb4d7..ededb0da 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -1974,6 +1974,47 @@ int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_ return ret; } +void radeon_commit_ring(drm_radeon_private_t *dev_priv) +{ + int i; + u32 *ring; + int tail_aligned; + + /* check if the ring is padded out to 16-dword alignment */ + + tail_aligned = dev_priv->ring.tail & 0xf; + if (tail_aligned) { + int num_p2 = 16 - tail_aligned; + + ring = dev_priv->ring.start; + /* pad with some CP_PACKET2 */ + for (i = 0; i < num_p2; i++) + ring[dev_priv->ring.tail + i] = CP_PACKET2(); + + dev_priv->ring.tail += i; + + dev_priv->ring.space -= num_p2 * sizeof(u32); + } + + dev_priv->ring.tail &= dev_priv->ring.tail_mask; + + DRM_MEMORYBARRIER(); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + R600_GET_RING_HEAD( dev_priv ); + else + GET_RING_HEAD( dev_priv ); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); + /* read from PCI bus to ensure correct posting */ + RADEON_READ(R600_CP_RB_RPTR); + } else { + RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); + /* read from PCI bus to ensure correct posting */ + RADEON_READ(RADEON_CP_RB_RPTR); + } +} + int radeon_driver_load(struct drm_device *dev, unsigned long flags) { drm_radeon_private_t *dev_priv; diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 2e3e4cc6..e6a1ae30 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -399,6 +399,7 @@ extern void radeon_freelist_reset(struct drm_device * dev); extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); +extern void radeon_commit_ring(drm_radeon_private_t *dev_priv); extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); @@ -1640,29 +1641,9 @@ do { \ dev_priv->ring.tail = write; \ } while (0) -#define R600_COMMIT_RING() do { \ - DRM_MEMORYBARRIER(); \ - R600_GET_RING_HEAD( dev_priv ); \ - RADEON_WRITE( R600_CP_RB_WPTR, dev_priv->ring.tail ); \ - RADEON_READ( R600_CP_RB_RPTR); \ -} while (0) -#define RADEON_COMMIT_RING() do { \ - /* Flush writes to ring */ \ - DRM_MEMORYBARRIER(); \ - GET_RING_HEAD( dev_priv ); \ - RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ - /* read from PCI bus to ensure correct posting */ \ - RADEON_READ( RADEON_CP_RB_RPTR ); \ -} while (0) +#define COMMIT_RING() radeon_commit_ring(dev_priv) -#define COMMIT_RING() do { \ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { \ - R600_COMMIT_RING(); \ - } else { \ - RADEON_COMMIT_RING(); \ - } \ -} while (0) #define OUT_RING( x ) do { \ if ( RADEON_VERBOSE ) { \ |