aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/radeon_cp.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2007-05-08 01:19:23 -0400
committerDave Airlie <airlied@linux.ie>2007-05-08 01:19:23 -0400
commitf2b04cd219e5c0f1214c0eeeec814ddd08a12c1b (patch)
treefa114ea7f96b5985e10c7f8696d635b074649bab /drivers/char/drm/radeon_cp.c
parent5b94f675f57e4ff16c8fda09088d7480a84dcd91 (diff)
drm/radeon: upgrade to 1.27 - make PCI GART more flexible
radeon: make PCI GART aperture size variable, but making table size variable This is precursor to getting a TTM backend for this stuff, and also allows the PCI table to be allocated at fb 0 radeon: add support for reverse engineered xpress200m The IGPGART setup code was traced using mmio-trace on fglrx by myself and Phillip Ezolt <phillipezolt@gmail.com> on dri-devel. This code doesn't let the 3D driver work properly as the card has no vertex shader support. Thanks to Matthew Garrett + Ubuntu for providing me some hardware to do this work on. Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm/radeon_cp.c')
-rw-r--r--drivers/char/drm/radeon_cp.c71
1 files changed, 65 insertions, 6 deletions
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index c1850ecac302..68338389d836 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -830,6 +830,15 @@ static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
830 return RADEON_READ(RADEON_PCIE_DATA); 830 return RADEON_READ(RADEON_PCIE_DATA);
831} 831}
832 832
833static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr)
834{
835 u32 ret;
836 RADEON_WRITE(RADEON_IGPGART_INDEX, addr & 0x7f);
837 ret = RADEON_READ(RADEON_IGPGART_DATA);
838 RADEON_WRITE(RADEON_IGPGART_INDEX, 0x7f);
839 return ret;
840}
841
833#if RADEON_FIFO_DEBUG 842#if RADEON_FIFO_DEBUG
834static void radeon_status(drm_radeon_private_t * dev_priv) 843static void radeon_status(drm_radeon_private_t * dev_priv)
835{ 844{
@@ -1267,7 +1276,44 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
1267 } 1276 }
1268} 1277}
1269 1278
1270/* Enable or disable PCI-E GART on the chip */ 1279/* Enable or disable IGP GART on the chip */
1280static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
1281{
1282 u32 temp, tmp;
1283
1284 tmp = RADEON_READ(RADEON_AIC_CNTL);
1285 if (on) {
1286 DRM_DEBUG("programming igpgart %08X %08lX %08X\n",
1287 dev_priv->gart_vm_start,
1288 (long)dev_priv->gart_info.bus_addr,
1289 dev_priv->gart_size);
1290
1291 RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_18, 0x1000);
1292 RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, 0x1);
1293 RADEON_WRITE_IGPGART(RADEON_IGPGART_CTRL, 0x42040800);
1294 RADEON_WRITE_IGPGART(RADEON_IGPGART_BASE_ADDR,
1295 dev_priv->gart_info.bus_addr);
1296
1297 temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_39);
1298 RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_39, temp);
1299
1300 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
1301 dev_priv->gart_size = 32*1024*1024;
1302 RADEON_WRITE(RADEON_MC_AGP_LOCATION,
1303 (((dev_priv->gart_vm_start - 1 +
1304 dev_priv->gart_size) & 0xffff0000) |
1305 (dev_priv->gart_vm_start >> 16)));
1306
1307 temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_ENABLE);
1308 RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, temp);
1309
1310 RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
1311 RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1);
1312 RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
1313 RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0);
1314 }
1315}
1316
1271static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) 1317static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
1272{ 1318{
1273 u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); 1319 u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
@@ -1302,6 +1348,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
1302{ 1348{
1303 u32 tmp; 1349 u32 tmp;
1304 1350
1351 if (dev_priv->flags & RADEON_IS_IGPGART) {
1352 radeon_set_igpgart(dev_priv, on);
1353 return;
1354 }
1355
1305 if (dev_priv->flags & RADEON_IS_PCIE) { 1356 if (dev_priv->flags & RADEON_IS_PCIE) {
1306 radeon_set_pciegart(dev_priv, on); 1357 radeon_set_pciegart(dev_priv, on);
1307 return; 1358 return;
@@ -1620,20 +1671,22 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1620#endif 1671#endif
1621 { 1672 {
1622 /* if we have an offset set from userspace */ 1673 /* if we have an offset set from userspace */
1623 if (dev_priv->pcigart_offset) { 1674 if (dev_priv->pcigart_offset_set) {
1624 dev_priv->gart_info.bus_addr = 1675 dev_priv->gart_info.bus_addr =
1625 dev_priv->pcigart_offset + dev_priv->fb_location; 1676 dev_priv->pcigart_offset + dev_priv->fb_location;
1626 dev_priv->gart_info.mapping.offset = 1677 dev_priv->gart_info.mapping.offset =
1627 dev_priv->gart_info.bus_addr; 1678 dev_priv->gart_info.bus_addr;
1628 dev_priv->gart_info.mapping.size = 1679 dev_priv->gart_info.mapping.size =
1629 RADEON_PCIGART_TABLE_SIZE; 1680 dev_priv->gart_info.table_size;
1630 1681
1631 drm_core_ioremap(&dev_priv->gart_info.mapping, dev); 1682 drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
1632 dev_priv->gart_info.addr = 1683 dev_priv->gart_info.addr =
1633 dev_priv->gart_info.mapping.handle; 1684 dev_priv->gart_info.mapping.handle;
1634 1685
1635 dev_priv->gart_info.is_pcie = 1686 if (dev_priv->flags & RADEON_IS_PCIE)
1636 !!(dev_priv->flags & RADEON_IS_PCIE); 1687 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
1688 else
1689 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
1637 dev_priv->gart_info.gart_table_location = 1690 dev_priv->gart_info.gart_table_location =
1638 DRM_ATI_GART_FB; 1691 DRM_ATI_GART_FB;
1639 1692
@@ -1641,6 +1694,10 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1641 dev_priv->gart_info.addr, 1694 dev_priv->gart_info.addr,
1642 dev_priv->pcigart_offset); 1695 dev_priv->pcigart_offset);
1643 } else { 1696 } else {
1697 if (dev_priv->flags & RADEON_IS_IGPGART)
1698 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
1699 else
1700 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
1644 dev_priv->gart_info.gart_table_location = 1701 dev_priv->gart_info.gart_table_location =
1645 DRM_ATI_GART_MAIN; 1702 DRM_ATI_GART_MAIN;
1646 dev_priv->gart_info.addr = NULL; 1703 dev_priv->gart_info.addr = NULL;
@@ -1714,7 +1771,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
1714 if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) 1771 if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
1715 { 1772 {
1716 drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); 1773 drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
1717 dev_priv->gart_info.addr = NULL; 1774 dev_priv->gart_info.addr = 0;
1718 } 1775 }
1719 } 1776 }
1720 /* only clear to the start of flags */ 1777 /* only clear to the start of flags */
@@ -2222,6 +2279,8 @@ int radeon_driver_firstopen(struct drm_device *dev)
2222 drm_local_map_t *map; 2279 drm_local_map_t *map;
2223 drm_radeon_private_t *dev_priv = dev->dev_private; 2280 drm_radeon_private_t *dev_priv = dev->dev_private;
2224 2281
2282 dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
2283
2225 ret = drm_addmap(dev, drm_get_resource_start(dev, 2), 2284 ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
2226 drm_get_resource_len(dev, 2), _DRM_REGISTERS, 2285 drm_get_resource_len(dev, 2), _DRM_REGISTERS,
2227 _DRM_READ_ONLY, &dev_priv->mmio); 2286 _DRM_READ_ONLY, &dev_priv->mmio);