diff options
-rw-r--r-- | sys/dev/pci/drm/ati_pcigart.c | 48 | ||||
-rw-r--r-- | sys/dev/pci/drm/drmP.h | 15 | ||||
-rw-r--r-- | sys/dev/pci/drm/r128_cce.c | 1 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon_cp.c | 119 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon_drv.c | 1 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon_drv.h | 1 |
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; |