From e835820e2359952bd42a66137c6b7ab243a5a541 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 3 Apr 2007 19:04:48 +1000 Subject: add initial PCIE GART framework for TTM --- linux-core/ati_pcigart.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'linux-core/ati_pcigart.c') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index bb30dd74..f3f91129 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -228,3 +228,88 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) return ret; } EXPORT_SYMBOL(drm_ati_pcigart_init); + +static int ati_pcigart_needs_unbind_cache_adjust(drm_ttm_backend_t *backend) +{ + return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1); +} + +static int ati_pcigart_populate(drm_ttm_backend_t *backend, + unsigned long num_pages, + struct page **pages) +{ + ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + + return -1; +} + +static int ati_pcigart_bind_ttm(drm_ttm_backend_t *backend, + unsigned long offset, + int cached) +{ + ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + + return -1; +} + +static int ati_pcigart_unbind_ttm(drm_ttm_backend_t *backend) +{ + ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + + return -1; +} + +static void ati_pcigart_clear_ttm(drm_ttm_backend_t *backend) +{ + ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; +} + +static void ati_pcigart_destroy_ttm(drm_ttm_backend_t *backend) +{ + ati_pcigart_ttm_priv *atipci_priv; + + if (backend) { + DRM_DEBUG("\n"); + atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + if (atipci_priv) { + drm_ctl_free(atipci_priv, sizeof(*atipci_priv), DRM_MEM_MAPPINGS); + backend->private = NULL; + } + if (backend->flags & DRM_BE_FLAG_NEEDS_FREE) { + drm_ctl_free(backend, sizeof(*backend), DRM_MEM_MAPPINGS); + } + } +} + + +drm_ttm_backend_t *ati_pcigart_init_ttm(struct drm_device *dev, + drm_ttm_backend_t *backend) +{ + drm_ttm_backend_t *atipci_be; + ati_pcigart_ttm_priv *atipci_priv; + + atipci_be = (backend != NULL) ? backend : + drm_ctl_calloc(1, sizeof (*atipci_be), DRM_MEM_MAPPINGS); + + if (!atipci_be) + return NULL; + + atipci_priv = drm_ctl_calloc(1, sizeof(*atipci_priv), DRM_MEM_MAPPINGS); + if (!atipci_priv) { + drm_ctl_free(atipci_be, sizeof(*atipci_be), DRM_MEM_MAPPINGS); + return NULL; + } + + atipci_priv->populated = FALSE; + atipci_be->needs_ub_cache_adjust = ati_pcigart_needs_unbind_cache_adjust; + atipci_be->populate = ati_pcigart_populate; + atipci_be->clear = ati_pcigart_clear_ttm; + atipci_be->bind = ati_pcigart_bind_ttm; + atipci_be->unbind = ati_pcigart_unbind_ttm; + atipci_be->destroy = ati_pcigart_destroy_ttm; + + DRM_FLAG_MASKED(atipci_be->flags, (backend == NULL) ? DRM_BE_FLAG_NEEDS_FREE : 0, DRM_BE_FLAG_NEEDS_FREE); + atipci_be->drm_map_type = _DRM_SCATTER_GATHER; + return atipci_be; +} +EXPORT_SYMBOL(ati_pcigart_init_ttm); -- cgit v1.2.3 From 29ac7b1fe364a4be1db7e22d2b400bef04fc240d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 3 Apr 2007 21:20:00 +1000 Subject: radeon: add setup for PCIE GART ttm --- linux-core/ati_pcigart.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'linux-core/ati_pcigart.c') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index f3f91129..108e1875 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -239,8 +239,22 @@ static int ati_pcigart_populate(drm_ttm_backend_t *backend, struct page **pages) { ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + struct page **cur_page, **last_page = pages + num_pages; + struct ati_pcigart_memory *mem; - return -1; + DRM_DEBUG("%d\n", num_pages); + if (drm_alloc_memctl(num_pages * sizeof(void *))) + return -1; + + mem = drm_alloc(sizeof(struct ati_pcigart_memory), DRM_MEM_MAPPINGS); + if (!mem) { + drm_free_memctl(num_pages * sizeof(void *)); + return -1; + } + + mem->page_count = num_pages; + atipci_priv->mem = mem; + return 0; } static int ati_pcigart_bind_ttm(drm_ttm_backend_t *backend, @@ -249,6 +263,7 @@ static int ati_pcigart_bind_ttm(drm_ttm_backend_t *backend, { ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + DRM_DEBUG("\n"); return -1; } @@ -256,12 +271,24 @@ static int ati_pcigart_unbind_ttm(drm_ttm_backend_t *backend) { ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + DRM_DEBUG("\n"); return -1; } static void ati_pcigart_clear_ttm(drm_ttm_backend_t *backend) { ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + struct ati_pcigart_memory *mem = atipci_priv->mem; + + DRM_DEBUG("\n"); + if (mem) { + unsigned long num_pages = mem->page_count; + backend->unbind(backend); + /* free test */ + drm_free(mem, sizeof(struct ati_pcigart_memory), DRM_MEM_MAPPINGS); + drm_free_memctl(num_pages * sizeof(void *)); + } + atipci_priv->mem = NULL; } static void ati_pcigart_destroy_ttm(drm_ttm_backend_t *backend) @@ -272,6 +299,9 @@ static void ati_pcigart_destroy_ttm(drm_ttm_backend_t *backend) DRM_DEBUG("\n"); atipci_priv = (ati_pcigart_ttm_priv *)backend->private; if (atipci_priv) { + if (atipci_priv->mem) { + backend->clear(backend); + } drm_ctl_free(atipci_priv, sizeof(*atipci_priv), DRM_MEM_MAPPINGS); backend->private = NULL; } -- cgit v1.2.3 From 704ca0638977f58742a8bff6aba9905fe862cfb3 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Fri, 1 Jun 2007 18:12:45 +1000 Subject: WIP more code for radeon --- linux-core/ati_pcigart.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'linux-core/ati_pcigart.c') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index 108e1875..ad47ed25 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -234,6 +234,19 @@ static int ati_pcigart_needs_unbind_cache_adjust(drm_ttm_backend_t *backend) return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1); } +void ati_pcigart_alloc_page_array(size_t size, struct ati_pcigart_memory *mem) +{ + mem->memory = NULL; + mem->flags = 0; + + if (size <= 2*PAGE_SIZE) + mem->memory = kmalloc(size, GFP_KERNEL | __GFP_NORETRY); + if (mem->memory == NULL) { + mem->memory = vmalloc(size); + mem->flags |= ATI_PCIGART_FLAG_VMALLOC; + } +} + static int ati_pcigart_populate(drm_ttm_backend_t *backend, unsigned long num_pages, struct page **pages) @@ -241,6 +254,7 @@ static int ati_pcigart_populate(drm_ttm_backend_t *backend, ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; struct page **cur_page, **last_page = pages + num_pages; struct ati_pcigart_memory *mem; + unsigned long alloc_size = num_pages * sizeof(struct page *); DRM_DEBUG("%d\n", num_pages); if (drm_alloc_memctl(num_pages * sizeof(void *))) @@ -252,7 +266,11 @@ static int ati_pcigart_populate(drm_ttm_backend_t *backend, return -1; } - mem->page_count = num_pages; + ati_pcigart_alloc_page_array(alloc_size, mem); + mem->page_count = 0; + for (cur_page = pages; cur_page < last_page; ++cur_page) { + mem->memory[mem->page_count++] = page_to_phys(*cur_page); + } atipci_priv->mem = mem; return 0; } @@ -262,7 +280,19 @@ static int ati_pcigart_bind_ttm(drm_ttm_backend_t *backend, int cached) { ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + struct ati_pcigart_memory *mem = atipci_priv->mem; + off_t j; + + j = offset; + while (j < (pg_start + mem->page_count)) { + j++; + } + + for (i = 0, j = offset; i < mem->page_count; i++, j++) { + /* write value */ + } + /* need to traverse table and add entries */ DRM_DEBUG("\n"); return -1; } -- cgit v1.2.3 From 77b9d9d16b1d1f1715722182d5893aa202f73074 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 5 Jun 2007 10:35:41 +1000 Subject: cleanup pcigart ttm for new backend layout --- linux-core/ati_pcigart.c | 94 +++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 50 deletions(-) (limited to 'linux-core/ati_pcigart.c') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index 66742bbc..08dbfe6c 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -261,7 +261,8 @@ static int ati_pcigart_populate(drm_ttm_backend_t *backend, unsigned long num_pages, struct page **pages) { - ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + ati_pcigart_ttm_backend_t *atipci_be = + container_of(backend, ati_pcigart_ttm_backend_t, backend); struct page **cur_page, **last_page = pages + num_pages; struct ati_pcigart_memory *mem; unsigned long alloc_size = num_pages * sizeof(struct page *); @@ -281,7 +282,7 @@ static int ati_pcigart_populate(drm_ttm_backend_t *backend, for (cur_page = pages; cur_page < last_page; ++cur_page) { mem->memory[mem->page_count++] = page_to_phys(*cur_page); } - atipci_priv->mem = mem; + atipci_be->mem = mem; return 0; } @@ -289,18 +290,20 @@ static int ati_pcigart_bind_ttm(drm_ttm_backend_t *backend, unsigned long offset, int cached) { - ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; - struct ati_pcigart_memory *mem = atipci_priv->mem; + ati_pcigart_ttm_backend_t *atipci_be = + container_of(backend, ati_pcigart_ttm_backend_t, backend); + + struct ati_pcigart_memory *mem = atipci_be->mem; off_t j; j = offset; - while (j < (pg_start + mem->page_count)) { + while (j < (offset + mem->page_count)) { j++; } - for (i = 0, j = offset; i < mem->page_count; i++, j++) { +// for (i = 0, j = offset; i < mem->page_count; i++, j++) { /* write value */ - } +// } /* need to traverse table and add entries */ DRM_DEBUG("\n"); @@ -309,7 +312,8 @@ static int ati_pcigart_bind_ttm(drm_ttm_backend_t *backend, static int ati_pcigart_unbind_ttm(drm_ttm_backend_t *backend) { - ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; + ati_pcigart_ttm_backend_t *atipci_be = + container_of(backend, ati_pcigart_ttm_backend_t, backend); DRM_DEBUG("\n"); return -1; @@ -317,69 +321,59 @@ static int ati_pcigart_unbind_ttm(drm_ttm_backend_t *backend) static void ati_pcigart_clear_ttm(drm_ttm_backend_t *backend) { - ati_pcigart_ttm_priv *atipci_priv = (ati_pcigart_ttm_priv *)backend->private; - struct ati_pcigart_memory *mem = atipci_priv->mem; + ati_pcigart_ttm_backend_t *atipci_be = + container_of(backend, ati_pcigart_ttm_backend_t, backend); + struct ati_pcigart_memory *mem = atipci_be->mem; DRM_DEBUG("\n"); if (mem) { unsigned long num_pages = mem->page_count; - backend->unbind(backend); + backend->func->unbind(backend); /* free test */ - drm_free(mem, sizeof(struct ati_pcigart_memory), DRM_MEM_MAPPINGS); - drm_free_memctl(num_pages * sizeof(void *)); +// drm_free(mem, sizeof(struct ati_pcigart_memory), DRM_MEM_MAPPINGS); +// drm_free_memctl(num_pages * sizeof(void *)); } - atipci_priv->mem = NULL; + atipci_be->mem = NULL; } static void ati_pcigart_destroy_ttm(drm_ttm_backend_t *backend) { - ati_pcigart_ttm_priv *atipci_priv; - + ati_pcigart_ttm_backend_t *atipci_be; if (backend) { DRM_DEBUG("\n"); - atipci_priv = (ati_pcigart_ttm_priv *)backend->private; - if (atipci_priv) { - if (atipci_priv->mem) { - backend->clear(backend); + atipci_be = container_of(backend, ati_pcigart_ttm_backend_t, backend); + if (atipci_be) { + if (atipci_be->mem) { + backend->func->clear(backend); } - drm_ctl_free(atipci_priv, sizeof(*atipci_priv), DRM_MEM_MAPPINGS); - backend->private = NULL; - } - if (backend->flags & DRM_BE_FLAG_NEEDS_FREE) { - drm_ctl_free(backend, sizeof(*backend), DRM_MEM_MAPPINGS); + drm_ctl_free(atipci_be, sizeof(*atipci_be), DRM_MEM_TTM); } } } - -drm_ttm_backend_t *ati_pcigart_init_ttm(struct drm_device *dev, - drm_ttm_backend_t *backend) +static drm_ttm_backend_func_t ati_pcigart_ttm_backend = { - drm_ttm_backend_t *atipci_be; - ati_pcigart_ttm_priv *atipci_priv; - - atipci_be = (backend != NULL) ? backend : - drm_ctl_calloc(1, sizeof (*atipci_be), DRM_MEM_MAPPINGS); + .needs_ub_cache_adjust = ati_pcigart_needs_unbind_cache_adjust, + .populate = ati_pcigart_populate, + .clear = ati_pcigart_clear_ttm, + .bind = ati_pcigart_bind_ttm, + .unbind = ati_pcigart_unbind_ttm, + .destroy = ati_pcigart_destroy_ttm, +}; + +drm_ttm_backend_t *ati_pcigart_init_ttm(struct drm_device *dev, struct ati_pcigart_info *info) +{ + ati_pcigart_ttm_backend_t *atipci_be; + atipci_be = drm_ctl_calloc(1, sizeof (*atipci_be), DRM_MEM_TTM); if (!atipci_be) return NULL; - - atipci_priv = drm_ctl_calloc(1, sizeof(*atipci_priv), DRM_MEM_MAPPINGS); - if (!atipci_priv) { - drm_ctl_free(atipci_be, sizeof(*atipci_be), DRM_MEM_MAPPINGS); - return NULL; - } - - atipci_priv->populated = FALSE; - atipci_be->needs_ub_cache_adjust = ati_pcigart_needs_unbind_cache_adjust; - atipci_be->populate = ati_pcigart_populate; - atipci_be->clear = ati_pcigart_clear_ttm; - atipci_be->bind = ati_pcigart_bind_ttm; - atipci_be->unbind = ati_pcigart_unbind_ttm; - atipci_be->destroy = ati_pcigart_destroy_ttm; - DRM_FLAG_MASKED(atipci_be->flags, (backend == NULL) ? DRM_BE_FLAG_NEEDS_FREE : 0, DRM_BE_FLAG_NEEDS_FREE); - atipci_be->drm_map_type = _DRM_SCATTER_GATHER; - return atipci_be; + atipci_be->populated = 0; + atipci_be->backend.func = &ati_pcigart_ttm_backend; + atipci_be->backend.mem_type = DRM_BO_MEM_TT; + atipci_be->gart_info = info; + + return &atipci_be->backend; } EXPORT_SYMBOL(ati_pcigart_init_ttm); -- cgit v1.2.3 From 234a9062009e48bf7b6c7239564ab95b3bcb06aa Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 5 Jun 2007 10:47:42 +1000 Subject: WIP cleanup --- linux-core/ati_pcigart.c | 81 ++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 54 deletions(-) (limited to 'linux-core/ati_pcigart.c') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index 08dbfe6c..44229a0d 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -35,6 +35,24 @@ # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ +static __inline__ void insert_page_into_table(struct ati_pcigart_info *info, u32 page_base, u32 *pci_gart) +{ + switch(info->gart_reg_if) { + case DRM_ATI_GART_IGP: + *pci_gart = cpu_to_le32((page_base) | 0xc); + break; + case DRM_ATI_GART_PCIE: + *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); + break; + default: + case DRM_ATI_GART_PCI: + *pci_gart = cpu_to_le32(page_base); + break; + } +} + + + static void *drm_ati_alloc_pcigart_table(int order) { unsigned long address; @@ -207,18 +225,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) page_base = (u32) entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - switch(gart_info->gart_reg_if) { - case DRM_ATI_GART_IGP: - *pci_gart = cpu_to_le32((page_base) | 0xc); - break; - case DRM_ATI_GART_PCIE: - *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); - break; - default: - case DRM_ATI_GART_PCI: - *pci_gart = cpu_to_le32(page_base); - break; - } + insert_page_into_table(gart_info, page_base, pci_gart); pci_gart++; page_base += ATI_PCIGART_PAGE_SIZE; } @@ -244,45 +251,16 @@ static int ati_pcigart_needs_unbind_cache_adjust(drm_ttm_backend_t *backend) return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1); } -void ati_pcigart_alloc_page_array(size_t size, struct ati_pcigart_memory *mem) -{ - mem->memory = NULL; - mem->flags = 0; - - if (size <= 2*PAGE_SIZE) - mem->memory = kmalloc(size, GFP_KERNEL | __GFP_NORETRY); - if (mem->memory == NULL) { - mem->memory = vmalloc(size); - mem->flags |= ATI_PCIGART_FLAG_VMALLOC; - } -} - static int ati_pcigart_populate(drm_ttm_backend_t *backend, unsigned long num_pages, struct page **pages) { ati_pcigart_ttm_backend_t *atipci_be = container_of(backend, ati_pcigart_ttm_backend_t, backend); - struct page **cur_page, **last_page = pages + num_pages; - struct ati_pcigart_memory *mem; - unsigned long alloc_size = num_pages * sizeof(struct page *); DRM_DEBUG("%d\n", num_pages); - if (drm_alloc_memctl(num_pages * sizeof(void *))) - return -1; - - mem = drm_alloc(sizeof(struct ati_pcigart_memory), DRM_MEM_MAPPINGS); - if (!mem) { - drm_free_memctl(num_pages * sizeof(void *)); - return -1; - } - - ati_pcigart_alloc_page_array(alloc_size, mem); - mem->page_count = 0; - for (cur_page = pages; cur_page < last_page; ++cur_page) { - mem->memory[mem->page_count++] = page_to_phys(*cur_page); - } - atipci_be->mem = mem; + atipci_be->pages = pages; + atipci_be->num_pages = num_pages; return 0; } @@ -292,12 +270,10 @@ 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); - - struct ati_pcigart_memory *mem = atipci_be->mem; off_t j; j = offset; - while (j < (offset + mem->page_count)) { + while (j < (offset + atipci_be->num_pages)) { j++; } @@ -323,17 +299,14 @@ static void ati_pcigart_clear_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_memory *mem = atipci_be->mem; DRM_DEBUG("\n"); - if (mem) { - unsigned long num_pages = mem->page_count; + if (atipci_be->pages) { backend->func->unbind(backend); - /* free test */ -// drm_free(mem, sizeof(struct ati_pcigart_memory), DRM_MEM_MAPPINGS); -// drm_free_memctl(num_pages * sizeof(void *)); + atipci_be->pages = NULL; + } - atipci_be->mem = NULL; + atipci_be->num_pages = 0; } static void ati_pcigart_destroy_ttm(drm_ttm_backend_t *backend) @@ -343,7 +316,7 @@ static void ati_pcigart_destroy_ttm(drm_ttm_backend_t *backend) DRM_DEBUG("\n"); atipci_be = container_of(backend, ati_pcigart_ttm_backend_t, backend); if (atipci_be) { - if (atipci_be->mem) { + if (atipci_be->pages) { backend->func->clear(backend); } drm_ctl_free(atipci_be, sizeof(*atipci_be), DRM_MEM_TTM); -- cgit v1.2.3 From 4294dcc050c5d2685f633e8a52deb925d806be85 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 5 Jun 2007 12:26:06 +1000 Subject: complete PCIE backend for ttm ttm test runs with it at least, needs to do more testing on it --- linux-core/ati_pcigart.c | 68 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 7 deletions(-) (limited to 'linux-core/ati_pcigart.c') 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; } -- cgit v1.2.3 From 96705ce6644389722f1605571e0a0dfde5568b8f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 5 Jun 2007 18:23:05 +1000 Subject: add wbinvd calls --- linux-core/ati_pcigart.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'linux-core/ati_pcigart.c') diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c index 91136060..ebf19a2b 100644 --- a/linux-core/ati_pcigart.c +++ b/linux-core/ati_pcigart.c @@ -314,6 +314,12 @@ static int ati_pcigart_bind_ttm(drm_ttm_backend_t *backend, insert_page_into_table(info, page_base, pci_gart + j); } +#if defined(__i386__) || defined(__x86_64__) + wbinvd(); +#else + mb(); +#endif + atipci_be->gart_flush_fn(atipci_be->dev); atipci_be->bound = 1; -- cgit v1.2.3