From 5565a00916122bb131ce89a2ca8f7f81ddc9387c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 11 Sep 2005 08:51:23 +0000 Subject: Add GART in FB support for ati pcigart, and PCIE support for r300 --- shared-core/r128_cce.c | 15 ++++++++------- shared-core/r128_drv.h | 3 +-- shared-core/radeon_cp.c | 45 +++++++++++++++++++++++++++++++++++---------- shared-core/radeon_drm.h | 1 + shared-core/radeon_drv.h | 14 ++++++++------ shared-core/radeon_state.c | 3 +++ 6 files changed, 56 insertions(+), 25 deletions(-) (limited to 'shared-core') diff --git a/shared-core/r128_cce.c b/shared-core/r128_cce.c index 33553670..cb84fa84 100644 --- a/shared-core/r128_cce.c +++ b/shared-core/r128_cce.c @@ -558,14 +558,16 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) #if __OS_HAS_AGP if (dev_priv->is_pci) { #endif - if (!drm_ati_pcigart_init(dev, &dev_priv->phys_pci_gart, - &dev_priv->bus_pci_gart, 0)) { + dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; + dev_priv->gart_info.addr = dev_priv->gart_info.bus_addr = 0; + dev_priv->gart_info.is_pcie = 0; + if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR("failed to init PCI GART!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); return DRM_ERR(ENOMEM); } - R128_WRITE(R128_PCI_GART_PAGE, dev_priv->bus_pci_gart); + R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); #if __OS_HAS_AGP } #endif @@ -606,10 +608,9 @@ int r128_do_cleanup_cce(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"); } drm_free(dev->dev_private, sizeof(drm_r128_private_t), diff --git a/shared-core/r128_drv.h b/shared-core/r128_drv.h index c6bdf563..34724fde 100644 --- a/shared-core/r128_drv.h +++ b/shared-core/r128_drv.h @@ -87,8 +87,6 @@ typedef struct drm_r128_private { int usec_timeout; int is_pci; - unsigned long phys_pci_gart; - dma_addr_t bus_pci_gart; unsigned long cce_buffers_offset; atomic_t idle_count; @@ -119,6 +117,7 @@ typedef struct drm_r128_private { drm_local_map_t *cce_ring; drm_local_map_t *ring_rptr; drm_local_map_t *agp_textures; + drm_ati_pcigart_info gart_info; } drm_r128_private_t; typedef struct drm_r128_buf_priv { 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)); diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h index 64b96939..60656741 100644 --- a/shared-core/radeon_drm.h +++ b/shared-core/radeon_drm.h @@ -690,6 +690,7 @@ typedef struct drm_radeon_setparam { #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ +#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ /* 1.14: Clients can allocate/free a surface */ diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 58e4c17a..265697c7 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -38,7 +38,7 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20050905" +#define DRIVER_DATE "20050911" /* Interface history: * @@ -86,10 +86,11 @@ * 1.18- Add support for GL_ATI_fragment_shader, new packets R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6) + * 1.19- Add support for gart table in FB memory and PCIE r300 */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 18 +#define DRIVER_MINOR 19 #define DRIVER_PATCHLEVEL 0 enum radeon_family { @@ -211,9 +212,6 @@ typedef struct drm_radeon_private { int microcode_version; - unsigned long phys_pci_gart; - dma_addr_t bus_pci_gart; - struct { u32 boxes; int freelist_timeouts; @@ -265,7 +263,9 @@ typedef struct drm_radeon_private { struct radeon_surface surfaces[RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES]; - + + unsigned long pcigart_offset; + drm_ati_pcigart_info gart_info; /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ @@ -920,6 +920,8 @@ extern int r300_do_cp_cmdbuf( drm_device_t* dev, #define RADEON_RING_HIGH_MARK 128 +#define RADEON_PCIGART_TABLE_SIZE (32*1024) + #define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) #define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c index 8b3317b2..91fc9f2d 100644 --- a/shared-core/radeon_state.c +++ b/shared-core/radeon_state.c @@ -3007,6 +3007,9 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) dev_priv->sarea_priv->tiling_enabled = 1; } break; + case RADEON_SETPARAM_PCIGART_LOCATION: + dev_priv->pcigart_offset = sp.value; + break; default: DRM_DEBUG("Invalid parameter %d\n", sp.param); return DRM_ERR(EINVAL); -- cgit v1.2.3