summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/drm/ati_pcigart.c48
-rw-r--r--sys/dev/pci/drm/drmP.h15
-rw-r--r--sys/dev/pci/drm/r128_cce.c1
-rw-r--r--sys/dev/pci/drm/radeon_cp.c119
-rw-r--r--sys/dev/pci/drm/radeon_drv.c1
-rw-r--r--sys/dev/pci/drm/radeon_drv.h1
6 files changed, 104 insertions, 81 deletions
diff --git a/sys/dev/pci/drm/ati_pcigart.c b/sys/dev/pci/drm/ati_pcigart.c
index 9290ef3327b..b9a5c4c55c9 100644
--- a/sys/dev/pci/drm/ati_pcigart.c
+++ b/sys/dev/pci/drm/ati_pcigart.c
@@ -33,17 +33,17 @@
#include "drmP.h"
-#define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
-#define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1))
+#define ATI_PCIGART_PAGE_SIZE 4096 /* PCI GART page size */
+#define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1))
-#define ATI_PCIE_WRITE 0x4
-#define ATI_PCIE_READ 0x8
+#define ATI_PCIE_WRITE 0x4
+#define ATI_PCIE_READ 0x8
-void pcigart_add_entry(struct drm_ati_pcigart_info *, u_int32_t *,
+void pcigart_add_entry(struct drm_ati_pcigart_info *, bus_size_t,
bus_addr_t);
void
-pcigart_add_entry(struct drm_ati_pcigart_info *gart_info, u_int32_t *pci_gart,
+pcigart_add_entry(struct drm_ati_pcigart_info *gart_info, bus_size_t offset,
bus_addr_t entry_addr)
{
u_int32_t page_base = (u_int32_t)entry_addr &
@@ -63,7 +63,11 @@ pcigart_add_entry(struct drm_ati_pcigart_info *gart_info, u_int32_t *pci_gart,
case DRM_ATI_GART_PCI:
break;
}
- *pci_gart = htole32(page_base);
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
+ gart_info->tbl.dma.addr[offset] = htole32(page_base);
+ else
+ bus_space_write_4(gart_info->tbl.fb.bst, gart_info->tbl.fb.bsh,
+ offset * sizeof(u_int32_t), page_base);
}
int
@@ -78,11 +82,10 @@ drm_ati_pcigart_cleanup(struct drm_device *dev,
if (gart_info->bus_addr) {
gart_info->bus_addr = 0;
- gart_info->addr = 0;
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN &&
- gart_info->mem != NULL) {
- drm_dmamem_free(dev->dmat, gart_info->mem);
- gart_info->mem = NULL;
+ gart_info->tbl.dma.mem != NULL) {
+ drm_dmamem_free(dev->dmat, gart_info->tbl.dma.mem);
+ gart_info->tbl.dma.mem = NULL;
}
}
@@ -94,8 +97,8 @@ drm_ati_pcigart_init(struct drm_device *dev,
struct drm_ati_pcigart_info *gart_info)
{
- u_int32_t *pci_gart;
bus_addr_t entry_addr;
+ bus_size_t gart_idx;
u_long pages, max_ati_pages, max_real_pages;
int i, j, ret;
@@ -114,38 +117,38 @@ drm_ati_pcigart_init(struct drm_device *dev,
if (gart_info->gart_reg_if == DRM_ATI_GART_IGP)
flags |= BUS_DMA_NOCACHE;
- gart_info->mem = drm_dmamem_alloc(dev->dmat,
+ gart_info->tbl.dma.mem = drm_dmamem_alloc(dev->dmat,
gart_info->table_size, PAGE_SIZE, 1,
gart_info->table_size, flags, 0);
- if (gart_info->mem == NULL) {
+ if (gart_info->tbl.dma.mem == NULL) {
DRM_ERROR("cannot allocate PCI GART page!\n");
ret = ENOMEM;
goto error;
}
- gart_info->addr = gart_info->mem->kva;
- gart_info->bus_addr = gart_info->mem->map->dm_segs[0].ds_addr;
+ gart_info->tbl.dma.addr =
+ (u_int32_t *)gart_info->tbl.dma.mem->kva;
+ gart_info->bus_addr =
+ gart_info->tbl.dma.mem->map->dm_segs[0].ds_addr;
} else {
DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
(unsigned int)bus_address, (unsigned long)address);
+ bus_space_set_region_1(gart_info->tbl.fb.bst,
+ gart_info->tbl.fb.bsh, 0, 0, gart_info->table_size);
}
- pci_gart = (u_int32_t *)gart_info->addr;
-
max_ati_pages = (gart_info->table_size / sizeof(u_int32_t));
max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE);
pages = (dev->sg->mem->map->dm_nsegs <= max_real_pages) ?
dev->sg->mem->map->dm_nsegs : max_real_pages;
- memset(pci_gart, 0, max_ati_pages * sizeof(u_int32_t));
-
KASSERT(PAGE_SIZE >= ATI_PCIGART_PAGE_SIZE);
- for (i = 0; i < pages; i++) {
+ for (gart_idx = 0, i = 0; i < pages; i++) {
entry_addr = dev->sg->mem->map->dm_segs[i].ds_addr;
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE);
j++, entry_addr += ATI_PCIGART_PAGE_SIZE)
- pcigart_add_entry(gart_info, pci_gart++, entry_addr);
+ pcigart_add_entry(gart_info, gart_idx++, entry_addr);
}
DRM_MEMORYBARRIER();
@@ -153,7 +156,6 @@ drm_ati_pcigart_init(struct drm_device *dev,
return (0);
error:
- gart_info->addr = NULL;
gart_info->bus_addr = 0;
return (ret);
}
diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h
index 877a6032b69..9cc5e9017df 100644
--- a/sys/dev/pci/drm/drmP.h
+++ b/sys/dev/pci/drm/drmP.h
@@ -332,14 +332,21 @@ struct drm_mem {
#define upper_32_bits(_val) ((u_int32_t)(((_val) >> 16) >> 16))
struct drm_ati_pcigart_info {
- struct drm_local_map mapping;
- struct drm_dmamem *mem;
- void *addr;
+ union pcigart_table {
+ struct fb_gart {
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ } fb;
+ struct mem_gart {
+ struct drm_dmamem *mem;
+ u_int32_t *addr;
+ } dma;
+ } tbl;
bus_addr_t bus_addr;
bus_addr_t table_mask;
+ bus_size_t table_size;
int gart_table_location;
int gart_reg_if;
- int table_size;
};
struct drm_driver_info {
diff --git a/sys/dev/pci/drm/r128_cce.c b/sys/dev/pci/drm/r128_cce.c
index 5f923c17c22..3a52f5c374e 100644
--- a/sys/dev/pci/drm/r128_cce.c
+++ b/sys/dev/pci/drm/r128_cce.c
@@ -541,7 +541,6 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE;
- dev_priv->gart_info.addr = NULL;
dev_priv->gart_info.bus_addr = 0;
dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
if (drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
diff --git a/sys/dev/pci/drm/radeon_cp.c b/sys/dev/pci/drm/radeon_cp.c
index 501c9345ac1..92fdea4b372 100644
--- a/sys/dev/pci/drm/radeon_cp.c
+++ b/sys/dev/pci/drm/radeon_cp.c
@@ -69,6 +69,7 @@ void radeon_test_writeback(drm_radeon_private_t *);
void radeon_set_igpgart(drm_radeon_private_t *, int);
void radeon_set_pciegart(drm_radeon_private_t *, int);
void radeon_set_pcigart(drm_radeon_private_t *, int);
+int radeondrm_setup_pcigart(struct drm_radeon_private *);
u32
@@ -751,6 +752,62 @@ radeon_test_writeback(drm_radeon_private_t *dev_priv)
}
}
+/*
+ * Set up the addresses for a pcigart table, then fill it.
+ */
+int
+radeondrm_setup_pcigart(struct drm_radeon_private *dev_priv)
+{
+ struct drm_ati_pcigart_info *agi = &dev_priv->gart_info;
+ struct drm_device *dev;
+ bus_addr_t gartaddr;
+ int ret;
+
+ dev = (struct drm_device *)dev_priv->drmdev;
+
+ agi->table_mask = DMA_BIT_MASK(32);
+
+ /* if we have an offset set from userspace */
+ if (dev_priv->pcigart_offset_set) {
+ gartaddr = dev_priv->fb_aper_offset + dev_priv->pcigart_offset;
+
+ agi->tbl.fb.bst = dev_priv->bst;
+ /* XXX write combining */
+ if (bus_space_map(agi->tbl.fb.bst, gartaddr, agi->table_size,
+ 0, &agi->tbl.fb.bsh) != 0)
+ return (ret);
+
+ /* this is a radeon virtual address */
+ agi->bus_addr = dev_priv->fb_location +
+ dev_priv->pcigart_offset;
+ agi->gart_reg_if = dev_priv->flags & RADEON_IS_PCIE ?
+ DRM_ATI_GART_PCIE : DRM_ATI_GART_PCI;
+ agi->gart_table_location = DRM_ATI_GART_FB;
+ } else {
+ if (dev_priv->flags & RADEON_IS_PCIE) {
+ DRM_ERROR("Cannot use PCI Express without GART "
+ "in FB memory\n");
+ return (EINVAL);
+ }
+ agi->gart_reg_if = dev_priv->flags & RADEON_IS_IGPGART ?
+ DRM_ATI_GART_IGP : DRM_ATI_GART_PCI;
+ agi->gart_table_location = DRM_ATI_GART_MAIN;
+
+ /* pcigart_init will allocate dma memory for us */
+ agi->bus_addr = 0;
+ }
+
+ if (drm_ati_pcigart_init(dev, agi)) {
+ DRM_ERROR("failed to init PCI GART!\n");
+ return (ENOMEM);
+ }
+
+ /* Turn on PCI GART */
+ radeon_set_pcigart(dev_priv, 1);
+
+ return (0);
+}
+
/* Enable or disable IGP GART on the chip */
void
radeon_set_igpgart(drm_radeon_private_t *dev_priv, int on)
@@ -1173,55 +1230,10 @@ radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init)
} else
#endif
{
- dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
- /* if we have an offset set from userspace */
- if (dev_priv->pcigart_offset_set) {
- dev_priv->gart_info.bus_addr =
- dev_priv->pcigart_offset + dev_priv->fb_location;
- dev_priv->gart_info.mapping.offset =
- dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
- dev_priv->gart_info.mapping.size =
- dev_priv->gart_info.table_size;
-
- drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev);
- dev_priv->gart_info.addr =
- dev_priv->gart_info.mapping.handle;
-
- if (dev_priv->flags & RADEON_IS_PCIE)
- dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
- else
- dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
- dev_priv->gart_info.gart_table_location =
- DRM_ATI_GART_FB;
-
- DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
- dev_priv->gart_info.addr,
- dev_priv->pcigart_offset);
- } else {
- if (dev_priv->flags & RADEON_IS_IGPGART)
- dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
- else
- dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
- dev_priv->gart_info.gart_table_location =
- DRM_ATI_GART_MAIN;
- dev_priv->gart_info.addr = NULL;
- dev_priv->gart_info.bus_addr = 0;
- if (dev_priv->flags & RADEON_IS_PCIE) {
- DRM_ERROR
- ("Cannot use PCI Express without GART in FB memory\n");
- radeon_do_cleanup_cp(dev);
- return EINVAL;
- }
- }
-
- if (drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
- DRM_ERROR("failed to init PCI GART!\n");
+ if (radeondrm_setup_pcigart(dev_priv) != 0) {
radeon_do_cleanup_cp(dev);
- return ENOMEM;
+ return EINVAL;
}
-
- /* Turn on PCI GART */
- radeon_set_pcigart(dev_priv, 1);
}
/* Start with assuming that writeback doesn't work */
@@ -1263,12 +1275,13 @@ radeon_do_cleanup_cp(struct drm_device *dev)
DRM_ERROR("failed to cleanup PCI GART!\n");
}
- if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
- {
- drm_core_ioremapfree(&dev_priv->gart_info.mapping);
- dev_priv->gart_info.addr = 0;
- dev_priv->gart_info.gart_table_location = 0;
- }
+ if (dev_priv->gart_info.gart_table_location ==
+ DRM_ATI_GART_FB && dev_priv->gart_info.tbl.fb.bst != 0)
+ bus_space_unmap(dev_priv->gart_info.tbl.fb.bst,
+ dev_priv->gart_info.tbl.fb.bsh,
+ dev_priv->gart_info.table_size);
+ memset(&dev_priv->gart_info.tbl, 0,
+ sizeof(dev_priv->gart_info.tbl));
}
dev_priv->cp_ring = NULL;
dev_priv->ring_rptr = NULL;
diff --git a/sys/dev/pci/drm/radeon_drv.c b/sys/dev/pci/drm/radeon_drv.c
index 3623862e8fe..b302470d9cf 100644
--- a/sys/dev/pci/drm/radeon_drv.c
+++ b/sys/dev/pci/drm/radeon_drv.c
@@ -528,6 +528,7 @@ radeondrm_attach(struct device *parent, struct device *self, void *aux)
PCI_PRODUCT(pa->pa_id), radeondrm_pciidlist);
dev_priv->flags = id_entry->driver_private;
dev_priv->pc = pa->pa_pc;
+ dev_priv->bst = pa->pa_memt;
bar = vga_pci_bar_info((struct vga_pci_softc *)parent, 0);
if (bar == NULL) {
diff --git a/sys/dev/pci/drm/radeon_drv.h b/sys/dev/pci/drm/radeon_drv.h
index 8b18cf049a7..586c1595a92 100644
--- a/sys/dev/pci/drm/radeon_drv.h
+++ b/sys/dev/pci/drm/radeon_drv.h
@@ -212,6 +212,7 @@ typedef struct drm_radeon_private {
pci_chipset_tag_t pc;
pci_intr_handle_t ih;
+ bus_space_tag_t bst;
void *irqh;
struct vga_pci_bar *regs;