summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/ati_pcigart.c84
-rw-r--r--linux-core/drmP.h17
2 files changed, 61 insertions, 40 deletions
diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c
index c9ace516..1dde5ab3 100644
--- a/linux-core/ati_pcigart.c
+++ b/linux-core/ati_pcigart.c
@@ -91,9 +91,7 @@ static void drm_ati_free_pcigart_table(unsigned long address)
free_pages(address, ATI_PCIGART_TABLE_ORDER);
}
-int drm_ati_pcigart_init(drm_device_t * dev,
- unsigned long *addr, dma_addr_t * bus_addr,
- int is_pcie)
+int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info *gart_info)
{
drm_sg_mem_t *entry = dev->sg;
unsigned long address = 0;
@@ -106,25 +104,36 @@ int drm_ati_pcigart_init(drm_device_t * dev,
goto done;
}
- address = drm_ati_alloc_pcigart_table();
- if (!address) {
- DRM_ERROR("cannot allocate PCI GART page!\n");
- goto done;
- }
-
- if (!dev->pdev) {
- DRM_ERROR("PCI device unknown!\n");
- goto done;
+ if (gart_info->gart_table_location==DRM_ATI_GART_MAIN)
+ {
+ DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
+
+ address = drm_ati_alloc_pcigart_table();
+ if (!address) {
+ DRM_ERROR("cannot allocate PCI GART page!\n");
+ goto done;
+ }
+
+ if (!dev->pdev) {
+ DRM_ERROR("PCI device unknown!\n");
+ goto done;
+ }
+
+ bus_address = pci_map_single(dev->pdev, (void *)address,
+ ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+ PCI_DMA_TODEVICE);
+ if (bus_address == 0) {
+ DRM_ERROR("unable to map PCIGART pages!\n");
+ drm_ati_free_pcigart_table(address);
+ address = 0;
+ goto done;
+ }
}
-
- bus_address = pci_map_single(dev->pdev, (void *)address,
- ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
- PCI_DMA_TODEVICE);
- if (bus_address == 0) {
- DRM_ERROR("unable to map PCIGART pages!\n");
- drm_ati_free_pcigart_table(address);
- address = 0;
- goto done;
+ else
+ {
+ address = gart_info->addr;
+ bus_address = gart_info->bus_addr;
+ DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", bus_address, address);
}
pci_gart = (u32 *) address;
@@ -142,7 +151,7 @@ int drm_ati_pcigart_init(drm_device_t * dev,
PAGE_SIZE, PCI_DMA_TODEVICE);
if (entry->busaddr[i] == 0) {
DRM_ERROR("unable to map PCIGART pages!\n");
- drm_ati_pcigart_cleanup(dev, address, bus_address);
+ drm_ati_pcigart_cleanup(dev, gart_info);
address = 0;
bus_address = 0;
goto done;
@@ -150,11 +159,8 @@ int drm_ati_pcigart_init(drm_device_t * dev,
page_base = (u32) entry->busaddr[i];
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
- if (is_pcie)
- {
+ if (gart_info->is_pcie)
*pci_gart = (cpu_to_le32(page_base)>>8) | 0xc;
-// DRM_DEBUG("PCIE: %d %08X %08X to %p\n", i, page_base, (cpu_to_le32(page_base)>>8)|0xc, pci_gart);
- }
else
*pci_gart = cpu_to_le32(page_base);
pci_gart++;
@@ -171,14 +177,13 @@ int drm_ati_pcigart_init(drm_device_t * dev,
#endif
done:
- *addr = address;
- *bus_addr = bus_address;
+ gart_info->addr = address;
+ gart_info->bus_addr = bus_address;
return ret;
}
EXPORT_SYMBOL(drm_ati_pcigart_init);
-int drm_ati_pcigart_cleanup(drm_device_t * dev,
- unsigned long addr, dma_addr_t bus_addr)
+int drm_ati_pcigart_cleanup(drm_device_t * dev, drm_ati_pcigart_info *gart_info)
{
drm_sg_mem_t *entry = dev->sg;
unsigned long pages;
@@ -190,10 +195,12 @@ int drm_ati_pcigart_cleanup(drm_device_t * dev,
return 0;
}
- if (bus_addr) {
- pci_unmap_single(dev->pdev, bus_addr,
- ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
- PCI_DMA_TODEVICE);
+ if (gart_info->bus_addr) {
+ if (gart_info->gart_table_location==DRM_ATI_GART_MAIN) {
+ pci_unmap_single(dev->pdev, gart_info->bus_addr,
+ ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+ PCI_DMA_TODEVICE);
+ }
pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
? entry->pages : ATI_MAX_PCIGART_PAGES;
@@ -204,10 +211,15 @@ int drm_ati_pcigart_cleanup(drm_device_t * dev,
pci_unmap_single(dev->pdev, entry->busaddr[i],
PAGE_SIZE, PCI_DMA_TODEVICE);
}
+
+ if (gart_info->gart_table_location==DRM_ATI_GART_MAIN)
+ gart_info->bus_addr=0;
}
- if (addr) {
- drm_ati_free_pcigart_table(addr);
+
+ if (gart_info->gart_table_location==DRM_ATI_GART_MAIN && gart_info->addr) {
+ drm_ati_free_pcigart_table(gart_info->addr);
+ gart_info->addr=0;
}
return 1;
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 8b1728bb..81c542dc 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -523,6 +523,17 @@ typedef struct drm_vbl_sig {
struct task_struct *task;
} drm_vbl_sig_t;
+/* location of GART table */
+#define DRM_ATI_GART_MAIN 1
+#define DRM_ATI_GART_FB 2
+
+typedef struct ati_pcigart_info {
+ int gart_table_location;
+ int is_pcie;
+ unsigned long addr;
+ dma_addr_t bus_addr;
+} drm_ati_pcigart_info;
+
/**
* DRM driver structure. This structure represent the common code for
* a family of cards. There will one drm_device for each card present
@@ -978,10 +989,8 @@ extern int drm_sg_free(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* ATI PCIGART support (ati_pcigart.h) */
-extern int drm_ati_pcigart_init(drm_device_t * dev,
- unsigned long *addr, dma_addr_t * bus_addr, int is_pcie);
-extern int drm_ati_pcigart_cleanup(drm_device_t * dev,
- unsigned long addr, dma_addr_t bus_addr);
+extern int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info *gart_info);
+extern int drm_ati_pcigart_cleanup(drm_device_t * dev, drm_ati_pcigart_info *gart_info);
extern drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size,
size_t align, dma_addr_t maxaddr);