Skip to content

Commit

Permalink
drm/radeon: align ring writes to 16 dwords boundaries.
Browse files Browse the repository at this point in the history
On some radeon GPUs this appears to introduce another level of
stability around interacting with the ring.

Its pretty much what fglrx appears to do.

Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Dave Airlie committed Mar 13, 2009
1 parent cd00f95 commit 4247ca9
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
32 changes: 32 additions & 0 deletions drivers/gpu/drm/radeon/radeon_cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1950,3 +1950,35 @@ int radeon_driver_unload(struct drm_device *dev)
dev->dev_private = NULL;
return 0;
}

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();
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 );
}
20 changes: 9 additions & 11 deletions drivers/gpu/drm/radeon/radeon_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1376,15 +1376,16 @@ do { \

#define RADEON_VERBOSE 0

#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring;
#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring;

#define BEGIN_RING( n ) do { \
if ( RADEON_VERBOSE ) { \
DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
} \
if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
_align_nr = (n + 0xf) & ~0xf; \
if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \
COMMIT_RING(); \
radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \
radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \
} \
_nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \
ring = dev_priv->ring.start; \
Expand All @@ -1401,19 +1402,16 @@ do { \
DRM_ERROR( \
"ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \
((dev_priv->ring.tail + _nr) & mask), \
write, __LINE__); \
write, __LINE__); \
} else \
dev_priv->ring.tail = write; \
} while (0)

extern void radeon_commit_ring(drm_radeon_private_t *dev_priv);

#define 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)
radeon_commit_ring(dev_priv); \
} while(0)

#define OUT_RING( x ) do { \
if ( RADEON_VERBOSE ) { \
Expand Down

0 comments on commit 4247ca9

Please sign in to comment.