radeon: force all ring writes to 16-dword alignment.

main
Dave Airlie 2008-11-10 15:24:42 +10:00
parent 31b0c4cd20
commit 08ef5b5e67
2 changed files with 41 additions and 17 deletions

View File

@ -1313,9 +1313,7 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
dev_priv->ring.rptr_update = /* init->rptr_update */ 4096;
dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8);
dev_priv->ring.fetch_size = /* init->fetch_size */ 32;
dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16);
dev_priv->ring.fetch_size_l2ow = 2;
dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
@ -2513,8 +2511,7 @@ int radeon_modeset_cp_init(struct drm_device *dev)
dev_priv->ring.size_l2qw = drm_order(dev_priv->ring.size / 8);
dev_priv->ring.rptr_update = 4096;
dev_priv->ring.rptr_update_l2qw = drm_order(4096 / 8);
dev_priv->ring.fetch_size = 32;
dev_priv->ring.fetch_size_l2ow = drm_order(32 / 16);
dev_priv->ring.fetch_size_l2ow = 2; /* do what tcore does */
dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
@ -2841,3 +2838,33 @@ void radeon_gart_flush(struct drm_device *dev)
}
}
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);
}
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 );
}

View File

@ -219,7 +219,6 @@ typedef struct drm_radeon_ring_buffer {
int rptr_update; /* Double Words */
int rptr_update_l2qw; /* log2 Quad Words */
int fetch_size; /* Double Words */
int fetch_size_l2ow; /* log2 Oct Words */
u32 tail;
@ -1515,15 +1514,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; \
@ -1540,19 +1540,14 @@ 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)
#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 ) { \
@ -1731,6 +1726,8 @@ extern void radeon_gem_proc_cleanup(struct drm_minor *minor);
#define MARK_CHECK_OFFSET 2
#define MARK_CHECK_SCISSOR 3
extern void radeon_commit_ring(drm_radeon_private_t *dev_priv);
extern int r300_check_range(unsigned reg, int count);
extern int r300_get_reg_flags(unsigned reg);
#endif /* __RADEON_DRV_H__ */