diff options
Diffstat (limited to 'drivers/gpu/drm/ati_pcigart.c')
| -rw-r--r-- | drivers/gpu/drm/ati_pcigart.c | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c index c533d0c9ec6..c399dea27a3 100644 --- a/drivers/gpu/drm/ati_pcigart.c +++ b/drivers/gpu/drm/ati_pcigart.c @@ -31,7 +31,8 @@ * DEALINGS IN THE SOFTWARE. */ -#include "drmP.h" +#include <linux/export.h> +#include <drm/drmP.h> # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ @@ -39,8 +40,7 @@ static int drm_ati_alloc_pcigart_table(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) { gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size, - PAGE_SIZE, - gart_info->table_mask); + PAGE_SIZE); if (gart_info->table_handle == NULL) return -ENOMEM; @@ -77,7 +77,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info if (!entry->busaddr[i]) break; pci_unmap_page(dev->pdev, entry->busaddr[i], - PAGE_SIZE, PCI_DMA_TODEVICE); + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); } if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) @@ -95,13 +95,14 @@ EXPORT_SYMBOL(drm_ati_pcigart_cleanup); int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) { + struct drm_local_map *map = &gart_info->mapping; struct drm_sg_mem *entry = dev->sg; void *address = NULL; unsigned long pages; - u32 *pci_gart, page_base; + u32 *pci_gart = NULL, page_base, gart_idx; dma_addr_t bus_address = 0; int i, j, ret = 0; - int max_pages; + int max_ati_pages, max_real_pages; if (!entry) { DRM_ERROR("no scatter/gather memory!\n"); @@ -111,12 +112,20 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); + if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) { + DRM_ERROR("fail to set dma mask to 0x%Lx\n", + (unsigned long long)gart_info->table_mask); + ret = 1; + goto done; + } + ret = drm_ati_alloc_pcigart_table(dev, gart_info); if (ret) { DRM_ERROR("cannot allocate PCI GART page!\n"); goto done; } + pci_gart = gart_info->table_handle->vaddr; address = gart_info->table_handle->vaddr; bus_address = gart_info->table_handle->busaddr; } else { @@ -127,19 +136,24 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga (unsigned long)address); } - pci_gart = (u32 *) address; - max_pages = (gart_info->table_size / sizeof(u32)); - pages = (entry->pages <= max_pages) - ? entry->pages : max_pages; + max_ati_pages = (gart_info->table_size / sizeof(u32)); + max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); + pages = (entry->pages <= max_real_pages) + ? entry->pages : max_real_pages; - memset(pci_gart, 0, max_pages * sizeof(u32)); + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { + memset(pci_gart, 0, max_ati_pages * sizeof(u32)); + } else { + memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u32)); + } + gart_idx = 0; for (i = 0; i < pages; i++) { /* we need to support large memory configurations */ entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i], - 0, PAGE_SIZE, PCI_DMA_TODEVICE); - if (entry->busaddr[i] == 0) { + 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + if (pci_dma_mapping_error(dev->pdev, entry->busaddr[i])) { DRM_ERROR("unable to map PCIGART pages!\n"); drm_ati_pcigart_cleanup(dev, gart_info); address = NULL; @@ -149,19 +163,26 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga page_base = (u32) entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { + u32 val; + switch(gart_info->gart_reg_if) { case DRM_ATI_GART_IGP: - *pci_gart = cpu_to_le32((page_base) | 0xc); + val = page_base | 0xc; break; case DRM_ATI_GART_PCIE: - *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); + val = (page_base >> 8) | 0xc; break; default: case DRM_ATI_GART_PCI: - *pci_gart = cpu_to_le32(page_base); + val = page_base; break; } - pci_gart++; + if (gart_info->gart_table_location == + DRM_ATI_GART_MAIN) + pci_gart[gart_idx] = cpu_to_le32(val); + else + DRM_WRITE32(map, gart_idx * sizeof(u32), val); + gart_idx++; page_base += ATI_PCIGART_PAGE_SIZE; } } |
