diff options
Diffstat (limited to 'drivers/char/drm/radeon_cp.c')
-rw-r--r-- | drivers/char/drm/radeon_cp.c | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 6d9080a3ca7e..6dff5e43f713 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
@@ -825,6 +825,12 @@ static int RADEON_READ_PLL(drm_device_t *dev, int addr) | |||
825 | return RADEON_READ(RADEON_CLOCK_CNTL_DATA); | 825 | return RADEON_READ(RADEON_CLOCK_CNTL_DATA); |
826 | } | 826 | } |
827 | 827 | ||
828 | static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) | ||
829 | { | ||
830 | RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); | ||
831 | return RADEON_READ(RADEON_PCIE_DATA); | ||
832 | } | ||
833 | |||
828 | #if RADEON_FIFO_DEBUG | 834 | #if RADEON_FIFO_DEBUG |
829 | static void radeon_status( drm_radeon_private_t *dev_priv ) | 835 | static void radeon_status( drm_radeon_private_t *dev_priv ) |
830 | { | 836 | { |
@@ -1241,17 +1247,46 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, | |||
1241 | RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); | 1247 | RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); |
1242 | } | 1248 | } |
1243 | 1249 | ||
1250 | /* Enable or disable PCI-E GART on the chip */ | ||
1251 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) | ||
1252 | { | ||
1253 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); | ||
1254 | if (on) { | ||
1255 | |||
1256 | DRM_DEBUG("programming pcie %08X %08lX %08X\n", | ||
1257 | dev_priv->gart_vm_start, (long)dev_priv->gart_info.bus_addr, | ||
1258 | dev_priv->gart_size); | ||
1259 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, dev_priv->gart_vm_start); | ||
1260 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->gart_info.bus_addr); | ||
1261 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, dev_priv->gart_vm_start); | ||
1262 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, dev_priv->gart_vm_start | ||
1263 | + dev_priv->gart_size - 1); | ||
1264 | |||
1265 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */ | ||
1266 | |||
1267 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN); | ||
1268 | } else { | ||
1269 | RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN); | ||
1270 | } | ||
1271 | } | ||
1272 | |||
1244 | /* Enable or disable PCI GART on the chip */ | 1273 | /* Enable or disable PCI GART on the chip */ |
1245 | static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) | 1274 | static void radeon_set_pcigart( drm_radeon_private_t *dev_priv, int on ) |
1246 | { | 1275 | { |
1247 | u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); | 1276 | u32 tmp = RADEON_READ( RADEON_AIC_CNTL ); |
1248 | 1277 | ||
1278 | if (dev_priv->flags & CHIP_IS_PCIE) | ||
1279 | { | ||
1280 | radeon_set_pciegart(dev_priv, on); | ||
1281 | return; | ||
1282 | } | ||
1283 | |||
1249 | if ( on ) { | 1284 | if ( on ) { |
1250 | RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); | 1285 | RADEON_WRITE( RADEON_AIC_CNTL, tmp | RADEON_PCIGART_TRANSLATE_EN ); |
1251 | 1286 | ||
1252 | /* set PCI GART page-table base address | 1287 | /* set PCI GART page-table base address |
1253 | */ | 1288 | */ |
1254 | RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart ); | 1289 | RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr); |
1255 | 1290 | ||
1256 | /* set address range for PCI address translate | 1291 | /* set address range for PCI address translate |
1257 | */ | 1292 | */ |
@@ -1519,8 +1554,28 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) | |||
1519 | } else | 1554 | } else |
1520 | #endif | 1555 | #endif |
1521 | { | 1556 | { |
1522 | if (!drm_ati_pcigart_init( dev, &dev_priv->phys_pci_gart, | 1557 | /* if we have an offset set from userspace */ |
1523 | &dev_priv->bus_pci_gart)) { | 1558 | if (dev_priv->pcigart_offset) { |
1559 | dev_priv->gart_info.bus_addr = dev_priv->pcigart_offset + dev_priv->fb_location; | ||
1560 | dev_priv->gart_info.addr = (unsigned long)drm_ioremap(dev_priv->gart_info.bus_addr, RADEON_PCIGART_TABLE_SIZE, dev); | ||
1561 | |||
1562 | dev_priv->gart_info.is_pcie = !!(dev_priv->flags & CHIP_IS_PCIE); | ||
1563 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; | ||
1564 | |||
1565 | DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n", dev_priv->gart_info.addr, dev_priv->pcigart_offset); | ||
1566 | } | ||
1567 | else { | ||
1568 | dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; | ||
1569 | dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr= 0; | ||
1570 | if (dev_priv->flags & CHIP_IS_PCIE) | ||
1571 | { | ||
1572 | DRM_ERROR("Cannot use PCI Express without GART in FB memory\n"); | ||
1573 | radeon_do_cleanup_cp(dev); | ||
1574 | return DRM_ERR(EINVAL); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { | ||
1524 | DRM_ERROR( "failed to init PCI GART!\n" ); | 1579 | DRM_ERROR( "failed to init PCI GART!\n" ); |
1525 | dev->dev_private = (void *)dev_priv; | 1580 | dev->dev_private = (void *)dev_priv; |
1526 | radeon_do_cleanup_cp(dev); | 1581 | radeon_do_cleanup_cp(dev); |
@@ -1568,10 +1623,15 @@ static int radeon_do_cleanup_cp( drm_device_t *dev ) | |||
1568 | } else | 1623 | } else |
1569 | #endif | 1624 | #endif |
1570 | { | 1625 | { |
1571 | if (!drm_ati_pcigart_cleanup( dev, | 1626 | if (dev_priv->gart_info.bus_addr) |
1572 | dev_priv->phys_pci_gart, | 1627 | if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) |
1573 | dev_priv->bus_pci_gart )) | 1628 | DRM_ERROR("failed to cleanup PCI GART!\n"); |
1574 | DRM_ERROR( "failed to cleanup PCI GART!\n" ); | 1629 | |
1630 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) | ||
1631 | { | ||
1632 | drm_ioremapfree((void *)dev_priv->gart_info.addr, RADEON_PCIGART_TABLE_SIZE, dev); | ||
1633 | dev_priv->gart_info.addr = 0; | ||
1634 | } | ||
1575 | } | 1635 | } |
1576 | 1636 | ||
1577 | /* only clear to the start of flags */ | 1637 | /* only clear to the start of flags */ |
@@ -2057,6 +2117,9 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags) | |||
2057 | if (drm_device_is_agp(dev)) | 2117 | if (drm_device_is_agp(dev)) |
2058 | dev_priv->flags |= CHIP_IS_AGP; | 2118 | dev_priv->flags |= CHIP_IS_AGP; |
2059 | 2119 | ||
2120 | if (drm_device_is_pcie(dev)) | ||
2121 | dev_priv->flags |= CHIP_IS_PCIE; | ||
2122 | |||
2060 | DRM_DEBUG("%s card detected\n", | 2123 | DRM_DEBUG("%s card detected\n", |
2061 | ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); | 2124 | ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI")); |
2062 | return ret; | 2125 | return ret; |