diff options
Diffstat (limited to 'linux-core/drm_agpsupport.c')
-rw-r--r-- | linux-core/drm_agpsupport.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index 80663717..6ccb4b6d 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -484,7 +484,50 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle) return agp_unbind_memory(handle); } +/** + * Binds a collection of pages into AGP memory at the given offset, returning + * the AGP memory structure containing them. + * + * No reference is held on the pages during this time -- it is up to the + * caller to handle that. + */ +DRM_AGP_MEM * +drm_agp_bind_pages(struct drm_device *dev, + struct page **pages, + unsigned long num_pages, + uint32_t gtt_offset) +{ + DRM_AGP_MEM *mem; + int ret, i; + DRM_DEBUG("drm_agp_populate_ttm\n"); +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11) + mem = drm_agp_allocate_memory(num_pages, AGP_USER_MEMORY); +#else + mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages, + AGP_USER_MEMORY); +#endif + if (mem == NULL) { + DRM_ERROR("Failed to allocate memory for %ld pages\n", + num_pages); + return NULL; + } + + for (i = 0; i < num_pages; i++) + mem->memory[i] = phys_to_gart(page_to_phys(pages[i])); + mem->page_count = num_pages; + + mem->is_flushed = TRUE; + ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE); + if (ret != 0) { + DRM_ERROR("Failed to bind AGP memory: %d\n", ret); + agp_free_memory(mem); + return NULL; + } + + return mem; +} +EXPORT_SYMBOL(drm_agp_bind_pages); /* * AGP ttm backend interface. |