diff options
author | Dave Airlie <airlied@redhat.com> | 2009-03-09 01:31:20 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-03-13 00:24:20 -0400 |
commit | 6546bf6d6cbf1f9ac350fd278a1d937d4bb9ad06 (patch) | |
tree | a5bfc5c549f92c38fa7eff49b5aa2bc729073172 /drivers/gpu | |
parent | 1847a549ac4db1272dea13d86331c492a2640b3b (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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_cp.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 6f2cc74350c5..04fde35dc21d 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c | |||
@@ -1630,6 +1630,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
1630 | { | 1630 | { |
1631 | struct drm_radeon_master_private *master_priv; | 1631 | struct drm_radeon_master_private *master_priv; |
1632 | u32 ring_start; | 1632 | u32 ring_start; |
1633 | u64 rptr_addr; | ||
1633 | 1634 | ||
1634 | if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) | 1635 | if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) |
1635 | r700_gfx_init(dev, dev_priv); | 1636 | r700_gfx_init(dev, dev_priv); |
@@ -1684,21 +1685,20 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
1684 | 1685 | ||
1685 | #if __OS_HAS_AGP | 1686 | #if __OS_HAS_AGP |
1686 | if (dev_priv->flags & RADEON_IS_AGP) { | 1687 | if (dev_priv->flags & RADEON_IS_AGP) { |
1687 | /* XXX */ | 1688 | rptr_addr = dev_priv->ring_rptr->offset |
1688 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR, | 1689 | - dev->agp->base + |
1689 | (dev_priv->ring_rptr->offset | 1690 | dev_priv->gart_vm_start; |
1690 | - dev->agp->base + dev_priv->gart_vm_start) >> 8); | ||
1691 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, 0); | ||
1692 | } else | 1691 | } else |
1693 | #endif | 1692 | #endif |
1694 | { | 1693 | { |
1695 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR, | 1694 | rptr_addr = dev_priv->ring_rptr->offset |
1696 | dev_priv->ring_rptr->offset | 1695 | - ((unsigned long) dev->sg->virtual) |
1697 | - ((unsigned long) dev->sg->virtual) | 1696 | + dev_priv->gart_vm_start; |
1698 | + dev_priv->gart_vm_start); | ||
1699 | |||
1700 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, 0); | ||
1701 | } | 1697 | } |
1698 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR, | ||
1699 | rptr_addr & 0xffffffff); | ||
1700 | RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, | ||
1701 | upper_32_bits(rptr_addr)); | ||
1702 | 1702 | ||
1703 | #ifdef __BIG_ENDIAN | 1703 | #ifdef __BIG_ENDIAN |
1704 | RADEON_WRITE(R600_CP_RB_CNTL, | 1704 | RADEON_WRITE(R600_CP_RB_CNTL, |
@@ -1747,8 +1747,17 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, | |||
1747 | * We simply put this behind the ring read pointer, this works | 1747 | * We simply put this behind the ring read pointer, this works |
1748 | * with PCI GART as well as (whatever kind of) AGP GART | 1748 | * with PCI GART as well as (whatever kind of) AGP GART |
1749 | */ | 1749 | */ |
1750 | RADEON_WRITE(R600_SCRATCH_ADDR, ((RADEON_READ(R600_CP_RB_RPTR_ADDR) << 8) | 1750 | { |
1751 | + R600_SCRATCH_REG_OFFSET) >> 8); | 1751 | u64 scratch_addr; |
1752 | |||
1753 | scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR); | ||
1754 | scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; | ||
1755 | scratch_addr += R600_SCRATCH_REG_OFFSET; | ||
1756 | scratch_addr >>= 8; | ||
1757 | scratch_addr &= 0xffffffff; | ||
1758 | |||
1759 | RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr); | ||
1760 | } | ||
1752 | 1761 | ||
1753 | RADEON_WRITE(R600_SCRATCH_UMSK, 0x7); | 1762 | RADEON_WRITE(R600_SCRATCH_UMSK, 0x7); |
1754 | 1763 | ||