summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-03-09 11:11:40 -0400
committerAlex Deucher <alexdeucher@gmail.com>2009-03-09 11:11:40 -0400
commit7a2f958dc9a108dd4cb0cd14585262c429f85754 (patch)
tree8dcc61a53f0eeb0f8727b99df803e34a1b51e21c
parentf80b83278fde794defd556807c5408e67bd39e7e (diff)
drm/radeon: fix r600 writeback setup.
This fixes 2 bugs: 1. the AGP calculation wasn't consistent with the PCI(E) calc for the RPTR_ADDR registers. This consolidates the writes and fixes it up. 2. The scratch address was being incorrectly calculated, this breaks it out into a lot more linear steps. Signed-off-by: Dave Airlie <airlied@redhat.com> pull in from drm-next
-rw-r--r--shared-core/r600_cp.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/shared-core/r600_cp.c b/shared-core/r600_cp.c
index d273ea70..3e6fbbf9 100644
--- a/shared-core/r600_cp.c
+++ b/shared-core/r600_cp.c
@@ -1984,6 +1984,7 @@ static void r600_cp_init_ring_buffer(struct drm_device * dev,
drm_radeon_private_t * dev_priv)
{
u32 ring_start;
+ u64 rptr_addr;
/*u32 cur_read_ptr;*/
u32 tmp;
@@ -2048,28 +2049,22 @@ static void r600_cp_init_ring_buffer(struct drm_device * dev,
#if __OS_HAS_AGP
if (dev_priv->flags & RADEON_IS_AGP) {
- // XXX
- RADEON_WRITE(R600_CP_RB_RPTR_ADDR,
- (dev_priv->ring_rptr->offset
- - dev->agp->base + dev_priv->gart_vm_start) >> 8);
- RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, 0);
+ rptr_addr = dev_priv->ring_rptr->offset
+ - dev->agp->base +
+ dev_priv->gart_vm_start;
} else
#endif
{
- struct drm_sg_mem *entry = dev->sg;
- unsigned long tmp_ofs, page_ofs;
-
- tmp_ofs = dev_priv->ring_rptr->offset -
- (unsigned long)dev->sg->virtual;
- page_ofs = tmp_ofs >> PAGE_SHIFT;
-
- RADEON_WRITE(R600_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs] >> 8);
- RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, 0);
- DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n",
- (unsigned long)entry->busaddr[page_ofs],
- entry->handle + tmp_ofs);
+ rptr_addr = dev_priv->ring_rptr->offset
+ - ((unsigned long) dev->sg->virtual)
+ + dev_priv->gart_vm_start;
}
+ RADEON_WRITE(R600_CP_RB_RPTR_ADDR,
+ rptr_addr & 0xffffffff);
+ RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI,
+ upper_32_bits(rptr_addr));
+
#ifdef __BIG_ENDIAN
RADEON_WRITE(R600_CP_RB_CNTL,
RADEON_BUF_SWAP_32BIT |
@@ -2117,8 +2112,18 @@ static void r600_cp_init_ring_buffer(struct drm_device * dev,
* We simply put this behind the ring read pointer, this works
* with PCI GART as well as (whatever kind of) AGP GART
*/
- RADEON_WRITE(R600_SCRATCH_ADDR, ((RADEON_READ(R600_CP_RB_RPTR_ADDR) << 8)
- + R600_SCRATCH_REG_OFFSET) >> 8);
+
+ {
+ u64 scratch_addr;
+
+ scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR);
+ scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32;
+ scratch_addr += R600_SCRATCH_REG_OFFSET;
+ scratch_addr >>= 8;
+ scratch_addr &= 0xffffffff;
+
+ RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr);
+ }
dev_priv->scratch = ((__volatile__ u32 *)
dev_priv->ring_rptr->handle +