aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/radeon_cp.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-02-20 13:28:34 +1000
committerDave Airlie <airlied@redhat.com>2009-03-13 14:24:05 +1000
commit4247ca942a16745da3d09c58996b276d02655a72 (patch)
tree650f309e886a7fccb0a5f637a9e395cbbf96e163 /drivers/gpu/drm/radeon/radeon_cp.c
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>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cp.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index a18b3688a7f..78a058fc039 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)
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 );
+}