diff options
author | Maciej Cencora <m.cencora@gmail.com> | 2008-02-19 21:32:45 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2008-02-20 09:35:42 +1000 |
commit | 60f92683943c5b7a85963b283d6f8a853aa09203 (patch) | |
tree | 0291f47cc073c218cdd393b99735d8c428c540af /drivers/char/drm/radeon_cp.c | |
parent | 00e962c5408b9f2d0bebd2308673fe982cb9a5fe (diff) |
drm/radeon: add initial rs690 support to drm.
This adds support for configuring the RS690 GART.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/char/drm/radeon_cp.c')
-rw-r--r-- | drivers/char/drm/radeon_cp.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 5dc799ab86b8..833abc7e55fb 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c @@ -825,11 +825,19 @@ static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) return ret; } +static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) +{ + RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK)); + return RADEON_READ(RS690_MC_DATA); +} + u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); else @@ -840,6 +848,8 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); else @@ -850,6 +860,8 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo { if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) + RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); else @@ -1362,6 +1374,70 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) } } +/* Enable or disable RS690 GART on the chip */ +static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on) +{ + u32 temp; + + if (on) { + DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n", + dev_priv->gart_vm_start, + (long)dev_priv->gart_info.bus_addr, + dev_priv->gart_size); + + temp = RS690_READ_MCIND(dev_priv, RS690_MC_MISC_CNTL); + RS690_WRITE_MCIND(RS690_MC_MISC_CNTL, 0x5000); + + RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, + RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB); + + temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_FEATURE_ID); + RS690_WRITE_MCIND(RS690_MC_GART_FEATURE_ID, 0x42040800); + + RS690_WRITE_MCIND(RS690_MC_GART_BASE, + dev_priv->gart_info.bus_addr); + + temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_MODE_CONTROL); + RS690_WRITE_MCIND(RS690_MC_AGP_MODE_CONTROL, 0x01400000); + + RS690_WRITE_MCIND(RS690_MC_AGP_BASE, + (unsigned int)dev_priv->gart_vm_start); + + dev_priv->gart_size = 32*1024*1024; + temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & + 0xffff0000) | (dev_priv->gart_vm_start >> 16)); + + RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp); + + temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_SIZE); + RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, + RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB); + + do { + temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL); + if ((temp & RS690_MC_GART_CLEAR_STATUS) == + RS690_MC_GART_CLEAR_DONE) + break; + DRM_UDELAY(1); + } while (1); + + RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL, + RS690_MC_GART_CC_CLEAR); + do { + temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL); + if ((temp & RS690_MC_GART_CLEAR_STATUS) == + RS690_MC_GART_CLEAR_DONE) + break; + DRM_UDELAY(1); + } while (1); + + RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL, + RS690_MC_GART_CC_NO_CHANGE); + } else { + RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, RS690_MC_GART_DIS); + } +} + static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) { u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); @@ -1396,6 +1472,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { u32 tmp; + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) { + radeon_set_rs690gart(dev_priv, on); + return; + } + if (dev_priv->flags & RADEON_IS_IGPGART) { radeon_set_igpgart(dev_priv, on); return; |