aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-11-10 15:24:42 +1000
committerDave Airlie <airlied@redhat.com>2008-11-10 15:24:42 +1000
commit08ef5b5e677579892a454d44a96a12dc771b56ac (patch)
treeca29cbbd3acf59979536ec19425f23cdec107246
parent31b0c4cd20d0eb843268a6307b7c32dbc07e42a0 (diff)
radeon: force all ring writes to 16-dword alignment.
-rw-r--r--shared-core/radeon_cp.c37
-rw-r--r--shared-core/radeon_drv.h21
2 files changed, 41 insertions, 17 deletions
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 9a1e0e02..73192d03 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -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 );
+}
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index a95ab152..828ad3f9 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -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__ */