summaryrefslogtreecommitdiff
path: root/shared-core/radeon_cp.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2005-09-11 08:51:23 +0000
committerDave Airlie <airlied@linux.ie>2005-09-11 08:51:23 +0000
commit5565a00916122bb131ce89a2ca8f7f81ddc9387c (patch)
treefd1b06f4a2b4d7f56130e8308789ec7368f70e92 /shared-core/radeon_cp.c
parent29326c1a8990ffb512a891d8deecf4cd4046915c (diff)
Add GART in FB support for ati pcigart, and PCIE support for r300
Diffstat (limited to 'shared-core/radeon_cp.c')
-rw-r--r--shared-core/radeon_cp.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index 09a473d7..b7e0ec0c 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -1246,17 +1246,17 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
if (on) {
DRM_DEBUG("programming pcie %08X %08lX %08X\n",
- dev_priv->gart_vm_start, (long)dev_priv->bus_pci_gart,
+ dev_priv->gart_vm_start, (long)dev_priv->gart_info.bus_addr,
dev_priv->gart_size);
RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, dev_priv->gart_vm_start);
- RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->bus_pci_gart);
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE, dev_priv->gart_info.bus_addr);
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO, dev_priv->gart_vm_start);
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO, dev_priv->gart_vm_start
+ dev_priv->gart_size - 1);
RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */
- RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN | RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD | RADEON_PCIE_TX_GART_CHK_RW_VALID_EN);
+ RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, RADEON_PCIE_TX_GART_EN);
} else {
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
}
@@ -1279,7 +1279,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
/* set PCI GART page-table base address
*/
- RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart);
+ RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr);
/* set address range for PCI address translate
*/
@@ -1526,8 +1526,28 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
} else
#endif
{
- if (!drm_ati_pcigart_init(dev, &dev_priv->phys_pci_gart,
- &dev_priv->bus_pci_gart, (dev_priv->flags & CHIP_IS_PCIE))) {
+ /* if we have an offset set from userspace */
+ if (dev_priv->pcigart_offset) {
+ dev_priv->gart_info.bus_addr = dev_priv->pcigart_offset + dev_priv->fb_location;
+ dev_priv->gart_info.addr = (unsigned long)drm_ioremap(dev_priv->gart_info.bus_addr, RADEON_PCIGART_TABLE_SIZE, dev);
+
+ dev_priv->gart_info.is_pcie = !!(dev_priv->flags & CHIP_IS_PCIE);
+ dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB;
+
+ DRM_DEBUG("Setting phys_pci_gart to %08lX %08lX\n", dev_priv->gart_info.addr, dev_priv->pcigart_offset);
+ }
+ else {
+ dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
+ dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr= 0;
+ if (dev_priv->flags & CHIP_IS_PCIE)
+ {
+ DRM_ERROR("Cannot use PCI Express without GART in FB memory\n");
+ radeon_do_cleanup_cp(dev);
+ return DRM_ERR(EINVAL);
+ }
+ }
+
+ if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
DRM_ERROR("failed to init PCI GART!\n");
radeon_do_cleanup_cp(dev);
return DRM_ERR(ENOMEM);
@@ -1576,10 +1596,15 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
} else
#endif
{
- if (!drm_ati_pcigart_cleanup(dev,
- dev_priv->phys_pci_gart,
- dev_priv->bus_pci_gart))
- DRM_ERROR("failed to cleanup PCI GART!\n");
+ if (dev_priv->gart_info.bus_addr)
+ if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
+ DRM_ERROR("failed to cleanup PCI GART!\n");
+
+ if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
+ {
+ drm_ioremapfree((void *)dev_priv->gart_info.addr, RADEON_PCIGART_TABLE_SIZE, dev);
+ dev_priv->gart_info.addr = 0;
+ }
}
/* only clear to the start of flags */
memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));