summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
authorDave Airlie <airlied@nx6125b.(none)>2007-06-05 12:26:06 +1000
committerDave Airlie <airlied@nx6125b.(none)>2007-06-05 12:26:06 +1000
commit4294dcc050c5d2685f633e8a52deb925d806be85 (patch)
treee564842fd5c8a333f44a4b048c88235c15970b6e /linux-core
parent234a9062009e48bf7b6c7239564ab95b3bcb06aa (diff)
complete PCIE backend for ttm
ttm test runs with it at least, needs to do more testing on it
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/ati_pcigart.c68
-rw-r--r--linux-core/drmP.h3
-rw-r--r--linux-core/radeon_buffer.c3
3 files changed, 65 insertions, 9 deletions
diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c
index 44229a0d..91136060 100644
--- a/linux-core/ati_pcigart.c
+++ b/linux-core/ati_pcigart.c
@@ -51,6 +51,27 @@ static __inline__ void insert_page_into_table(struct ati_pcigart_info *info, u32
}
}
+static __inline__ u32 get_page_base_from_table(struct ati_pcigart_info *info, u32 *pci_gart)
+{
+ u32 retval;
+ switch(info->gart_reg_if) {
+ case DRM_ATI_GART_IGP:
+ retval = *pci_gart;
+ retval &= ~0xc;
+ break;
+ case DRM_ATI_GART_PCIE:
+ retval = *pci_gart;
+ retval &= ~0xc;
+ retval <<= 8;
+ break;
+ default:
+ case DRM_ATI_GART_PCI:
+ retval = *pci_gart;
+ break;
+ }
+ return retval;
+}
+
static void *drm_ati_alloc_pcigart_table(int order)
@@ -258,9 +279,10 @@ static int ati_pcigart_populate(drm_ttm_backend_t *backend,
ati_pcigart_ttm_backend_t *atipci_be =
container_of(backend, ati_pcigart_ttm_backend_t, backend);
- DRM_DEBUG("%d\n", num_pages);
+ DRM_ERROR("%ld\n", num_pages);
atipci_be->pages = pages;
atipci_be->num_pages = num_pages;
+ atipci_be->populated = 1;
return 0;
}
@@ -271,28 +293,58 @@ static int ati_pcigart_bind_ttm(drm_ttm_backend_t *backend,
ati_pcigart_ttm_backend_t *atipci_be =
container_of(backend, ati_pcigart_ttm_backend_t, backend);
off_t j;
+ int i;
+ struct ati_pcigart_info *info = atipci_be->gart_info;
+ u32 *pci_gart;
+ u32 page_base;
+ pci_gart = info->addr;
+ DRM_ERROR("Offset is %08lX\n", offset);
j = offset;
while (j < (offset + atipci_be->num_pages)) {
+ if (get_page_base_from_table(info, pci_gart+j))
+ return -EBUSY;
j++;
}
-// for (i = 0, j = offset; i < mem->page_count; i++, j++) {
+ for (i = 0, j = offset; i < atipci_be->num_pages; i++, j++) {
+ struct page *cur_page = atipci_be->pages[i];
/* write value */
-// }
+ page_base = page_to_phys(cur_page);
+ insert_page_into_table(info, page_base, pci_gart + j);
+ }
+
+ atipci_be->gart_flush_fn(atipci_be->dev);
+ atipci_be->bound = 1;
+ atipci_be->offset = offset;
/* need to traverse table and add entries */
DRM_DEBUG("\n");
- return -1;
+ return 0;
}
static int ati_pcigart_unbind_ttm(drm_ttm_backend_t *backend)
{
ati_pcigart_ttm_backend_t *atipci_be =
container_of(backend, ati_pcigart_ttm_backend_t, backend);
-
+ struct ati_pcigart_info *info = atipci_be->gart_info;
+ unsigned long offset = atipci_be->offset;
+ int i;
+ off_t j;
+ u32 *pci_gart = info->addr;
+
DRM_DEBUG("\n");
- return -1;
+
+ if (atipci_be->bound != 1)
+ return -EINVAL;
+
+ for (i = 0, j = offset; i < atipci_be->num_pages; i++, j++) {
+ *(pci_gart + j) = 0;
+ }
+ atipci_be->gart_flush_fn(atipci_be->dev);
+ atipci_be->bound = 0;
+ atipci_be->offset = 0;
+ return 0;
}
static void ati_pcigart_clear_ttm(drm_ttm_backend_t *backend)
@@ -334,7 +386,7 @@ static drm_ttm_backend_func_t ati_pcigart_ttm_backend =
.destroy = ati_pcigart_destroy_ttm,
};
-drm_ttm_backend_t *ati_pcigart_init_ttm(struct drm_device *dev, struct ati_pcigart_info *info)
+drm_ttm_backend_t *ati_pcigart_init_ttm(struct drm_device *dev, struct ati_pcigart_info *info, void (*gart_flush_fn)(struct drm_device *dev))
{
ati_pcigart_ttm_backend_t *atipci_be;
@@ -346,6 +398,8 @@ drm_ttm_backend_t *ati_pcigart_init_ttm(struct drm_device *dev, struct ati_pciga
atipci_be->backend.func = &ati_pcigart_ttm_backend;
atipci_be->backend.mem_type = DRM_BO_MEM_TT;
atipci_be->gart_info = info;
+ atipci_be->gart_flush_fn = gart_flush_fn;
+ atipci_be->dev = dev;
return &atipci_be->backend;
}
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 16e3f5b0..5eb7c037 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -846,10 +846,13 @@ typedef struct drm_agp_ttm_backend {
typedef struct ati_pcigart_ttm_backend {
drm_ttm_backend_t backend;
int populated;
+ void (*gart_flush_fn)(struct drm_device *dev);
struct ati_pcigart_info *gart_info;
+ unsigned long offset;
struct page **pages;
int num_pages;
int bound;
+ drm_device_t *dev;
} ati_pcigart_ttm_backend_t;
static __inline__ int drm_core_check_feature(struct drm_device *dev,
diff --git a/linux-core/radeon_buffer.c b/linux-core/radeon_buffer.c
index a90dae83..6f7a7603 100644
--- a/linux-core/radeon_buffer.c
+++ b/linux-core/radeon_buffer.c
@@ -33,7 +33,6 @@
#include "radeon_drm.h"
#include "radeon_drv.h"
-
drm_ttm_backend_t *radeon_create_ttm_backend_entry(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -41,7 +40,7 @@ drm_ttm_backend_t *radeon_create_ttm_backend_entry(drm_device_t * dev)
if(dev_priv->flags & RADEON_IS_AGP)
return drm_agp_init_ttm(dev);
else
- return ati_pcigart_init_ttm(dev, &dev_priv->gart_info);
+ return ati_pcigart_init_ttm(dev, &dev_priv->gart_info, radeon_gart_flush);
}
int radeon_fence_types(drm_buffer_object_t *bo, uint32_t * class, uint32_t * type)