aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-02-19 22:28:34 -0500
committerDave Airlie <airlied@redhat.com>2009-03-13 00:24:05 -0400
commit4247ca942a16745da3d09c58996b276d02655a72 (patch)
tree650f309e886a7fccb0a5f637a9e395cbbf96e163
parentcd00f95aff6b4cfeccb261fd4100cceb4f5270ea (diff)
drm/radeon: align ring writes to 16 dwords boundaries.
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>
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c32
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h20
2 files changed, 41 insertions, 11 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index a18b3688a7f0..78a058fc039f 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -1950,3 +1950,35 @@ int radeon_driver_unload(struct drm_device *dev)
1950 dev->dev_private = NULL; 1950 dev->dev_private = NULL;
1951 return 0; 1951 return 0;
1952} 1952}
1953
1954void radeon_commit_ring(drm_radeon_private_t *dev_priv)
1955{
1956 int i;
1957 u32 *ring;
1958 int tail_aligned;
1959
1960 /* check if the ring is padded out to 16-dword alignment */
1961
1962 tail_aligned = dev_priv->ring.tail & 0xf;
1963 if (tail_aligned) {
1964 int num_p2 = 16 - tail_aligned;
1965
1966 ring = dev_priv->ring.start;
1967 /* pad with some CP_PACKET2 */
1968 for (i = 0; i < num_p2; i++)
1969 ring[dev_priv->ring.tail + i] = CP_PACKET2();
1970
1971 dev_priv->ring.tail += i;
1972
1973 dev_priv->ring.space -= num_p2 * sizeof(u32);
1974 }
1975
1976 dev_priv->ring.tail &= dev_priv->ring.tail_mask;
1977
1978 DRM_MEMORYBARRIER();
1979 GET_RING_HEAD( dev_priv );
1980
1981 RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail );
1982 /* read from PCI bus to ensure correct posting */
1983 RADEON_READ( RADEON_CP_RB_RPTR );
1984}
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index ecfd414bb99c..aa078cbe38f3 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -1376,15 +1376,16 @@ do { \
1376 1376
1377#define RADEON_VERBOSE 0 1377#define RADEON_VERBOSE 0
1378 1378
1379#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring; 1379#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring;
1380 1380
1381#define BEGIN_RING( n ) do { \ 1381#define BEGIN_RING( n ) do { \
1382 if ( RADEON_VERBOSE ) { \ 1382 if ( RADEON_VERBOSE ) { \
1383 DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ 1383 DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
1384 } \ 1384 } \
1385 if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ 1385 _align_nr = (n + 0xf) & ~0xf; \
1386 if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \
1386 COMMIT_RING(); \ 1387 COMMIT_RING(); \
1387 radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ 1388 radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \
1388 } \ 1389 } \
1389 _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ 1390 _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \
1390 ring = dev_priv->ring.start; \ 1391 ring = dev_priv->ring.start; \
@@ -1401,19 +1402,16 @@ do { \
1401 DRM_ERROR( \ 1402 DRM_ERROR( \
1402 "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \ 1403 "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \
1403 ((dev_priv->ring.tail + _nr) & mask), \ 1404 ((dev_priv->ring.tail + _nr) & mask), \
1404 write, __LINE__); \ 1405 write, __LINE__); \
1405 } else \ 1406 } else \
1406 dev_priv->ring.tail = write; \ 1407 dev_priv->ring.tail = write; \
1407} while (0) 1408} while (0)
1408 1409
1410extern void radeon_commit_ring(drm_radeon_private_t *dev_priv);
1411
1409#define COMMIT_RING() do { \ 1412#define COMMIT_RING() do { \
1410 /* Flush writes to ring */ \ 1413 radeon_commit_ring(dev_priv); \
1411 DRM_MEMORYBARRIER(); \ 1414 } while(0)
1412 GET_RING_HEAD( dev_priv ); \
1413 RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
1414 /* read from PCI bus to ensure correct posting */ \
1415 RADEON_READ( RADEON_CP_RB_RPTR ); \
1416} while (0)
1417 1415
1418#define OUT_RING( x ) do { \ 1416#define OUT_RING( x ) do { \
1419 if ( RADEON_VERBOSE ) { \ 1417 if ( RADEON_VERBOSE ) { \