mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-26 12:20:14 +01:00
AGP backends for TTM.
This commit is contained in:
parent
700bf80ca9
commit
b81ca5e031
2 changed files with 177 additions and 0 deletions
|
|
@ -850,6 +850,16 @@ typedef struct drm_device {
|
|||
|
||||
} drm_device_t;
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
typedef struct drm_agp_ttm_priv {
|
||||
DRM_AGP_MEM *mem;
|
||||
struct agp_bridge_data *bridge;
|
||||
unsigned mem_type;
|
||||
int populated;
|
||||
} drm_agp_ttm_priv;
|
||||
#endif
|
||||
|
||||
|
||||
static __inline__ int drm_core_check_feature(struct drm_device *dev,
|
||||
int feature)
|
||||
{
|
||||
|
|
@ -1162,6 +1172,8 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size
|
|||
extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
|
||||
extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
|
||||
extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
|
||||
extern drm_ttm_backend_t *drm_agp_init_ttm_cached(struct drm_device *dev);
|
||||
extern drm_ttm_backend_t *drm_agp_init_ttm_uncached(struct drm_device *dev);
|
||||
|
||||
/* Stub support (drm_stub.h) */
|
||||
extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
||||
|
|
|
|||
|
|
@ -552,4 +552,169 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
|
|||
return agp_unbind_memory(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* AGP ttm backend interface.
|
||||
*/
|
||||
|
||||
static int drm_agp_needs_cache_adjust_true(drm_ttm_backend_t *backend) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int drm_agp_needs_cache_adjust_false(drm_ttm_backend_t *backend) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define AGP_MEM_USER (1 << 16)
|
||||
#define AGP_MEM_UCACHED (2 << 16)
|
||||
|
||||
static int drm_agp_populate(drm_ttm_backend_t *backend, unsigned long num_pages,
|
||||
struct page **pages) {
|
||||
|
||||
drm_agp_ttm_priv *agp_priv = (drm_agp_ttm_priv *) backend->private;
|
||||
struct page **cur_page, **last_page = pages + num_pages;
|
||||
DRM_AGP_MEM *mem;
|
||||
|
||||
DRM_DEBUG("drm_agp_populate_ttm\n");
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11)
|
||||
mem = drm_agp_allocate_memory(num_pages, agp_priv->mem_type);
|
||||
#else
|
||||
mem = drm_agp_allocate_memory(agp_priv->bridge, num_pages, agp_priv->mem_type);
|
||||
#endif
|
||||
if (!mem)
|
||||
return -1;
|
||||
|
||||
DRM_DEBUG("Current page count is %ld\n", (long) mem->page_count);
|
||||
mem->page_count = 0;
|
||||
for (cur_page = pages; cur_page < last_page; ++cur_page) {
|
||||
mem->memory[mem->page_count++] = page_to_phys(*cur_page);
|
||||
}
|
||||
agp_priv->mem = mem;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drm_agp_bind_ttm(drm_ttm_backend_t *backend, unsigned long offset) {
|
||||
|
||||
drm_agp_ttm_priv *agp_priv = (drm_agp_ttm_priv *) backend->private;
|
||||
DRM_AGP_MEM *mem = agp_priv->mem;
|
||||
int ret;
|
||||
|
||||
DRM_DEBUG("drm_agp_bind_ttm\n");
|
||||
mem->is_flushed = FALSE;
|
||||
ret = drm_agp_bind_memory(mem, offset);
|
||||
if (ret) {
|
||||
DRM_ERROR("AGP Bind memory failed\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int drm_agp_unbind_ttm(drm_ttm_backend_t *backend) {
|
||||
|
||||
drm_agp_ttm_priv *agp_priv = (drm_agp_ttm_priv *) backend->private;
|
||||
|
||||
DRM_DEBUG("drm_agp_unbind_ttm\n");
|
||||
if (agp_priv->mem->is_bound)
|
||||
return drm_agp_unbind_memory(agp_priv->mem);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drm_agp_clear_ttm(drm_ttm_backend_t *backend) {
|
||||
|
||||
drm_agp_ttm_priv *agp_priv = (drm_agp_ttm_priv *) backend->private;
|
||||
DRM_AGP_MEM *mem = agp_priv->mem;
|
||||
|
||||
DRM_DEBUG("drm_agp_clear_ttm\n");
|
||||
if (mem) {
|
||||
if (mem->is_bound) {
|
||||
drm_agp_unbind_memory(mem);
|
||||
}
|
||||
agp_free_memory(mem);
|
||||
}
|
||||
agp_priv->mem = NULL;
|
||||
}
|
||||
|
||||
static void drm_agp_destroy_ttm(drm_ttm_backend_t *backend) {
|
||||
|
||||
drm_agp_ttm_priv *agp_priv;
|
||||
|
||||
if (backend) {
|
||||
DRM_DEBUG("drm_agp_destroy_ttm\n");
|
||||
agp_priv = (drm_agp_ttm_priv *) backend->private;
|
||||
if (agp_priv) {
|
||||
if (agp_priv->mem) {
|
||||
drm_agp_clear_ttm(backend);
|
||||
}
|
||||
drm_free(agp_priv, sizeof(*agp_priv), DRM_MEM_MAPPINGS);
|
||||
}
|
||||
drm_free(backend, sizeof(*backend), DRM_MEM_MAPPINGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
drm_ttm_backend_t *drm_agp_init_ttm_uncached(struct drm_device *dev) {
|
||||
|
||||
drm_ttm_backend_t *agp_be;
|
||||
drm_agp_ttm_priv *agp_priv;
|
||||
|
||||
agp_be = drm_calloc(1, sizeof(*agp_be), DRM_MEM_MAPPINGS);
|
||||
|
||||
if (!agp_be)
|
||||
return NULL;
|
||||
|
||||
agp_priv = drm_calloc(1, sizeof(agp_priv), DRM_MEM_MAPPINGS);
|
||||
|
||||
if (!agp_priv) {
|
||||
drm_free(agp_be, sizeof(*agp_be), DRM_MEM_MAPPINGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
agp_priv->mem = NULL;
|
||||
agp_priv->mem_type = AGP_MEM_USER;
|
||||
agp_priv->bridge = dev->agp->bridge;
|
||||
agp_priv->populated = FALSE;
|
||||
agp_be->aperture_base = dev->agp->agp_info.aper_base;
|
||||
agp_be->private = (void *) agp_priv;
|
||||
agp_be->needs_cache_adjust = drm_agp_needs_cache_adjust_true;
|
||||
agp_be->populate = drm_agp_populate;
|
||||
agp_be->clear = drm_agp_clear_ttm;
|
||||
agp_be->bind = drm_agp_bind_ttm;
|
||||
agp_be->unbind = drm_agp_unbind_ttm;
|
||||
agp_be->destroy = drm_agp_destroy_ttm;
|
||||
return agp_be;
|
||||
}
|
||||
|
||||
|
||||
drm_ttm_backend_t *drm_agp_init_ttm_cached(struct drm_device *dev) {
|
||||
|
||||
drm_ttm_backend_t *agp_be;
|
||||
drm_agp_ttm_priv *agp_priv;
|
||||
|
||||
agp_be = drm_calloc(1, sizeof(*agp_be), DRM_MEM_MAPPINGS);
|
||||
|
||||
if (!agp_be)
|
||||
return NULL;
|
||||
|
||||
agp_priv = drm_calloc(1, sizeof(agp_priv), DRM_MEM_MAPPINGS);
|
||||
|
||||
if (!agp_priv) {
|
||||
drm_free(agp_be, sizeof(*agp_be), DRM_MEM_MAPPINGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
agp_priv->mem = NULL;
|
||||
agp_priv->mem_type = AGP_MEM_UCACHED;
|
||||
agp_priv->bridge = dev->agp->bridge;
|
||||
agp_priv->populated = FALSE;
|
||||
agp_be->aperture_base = dev->agp->agp_info.aper_base;
|
||||
agp_be->private = (void *) agp_priv;
|
||||
agp_be->needs_cache_adjust = drm_agp_needs_cache_adjust_false;
|
||||
agp_be->populate = drm_agp_populate;
|
||||
agp_be->clear = drm_agp_clear_ttm;
|
||||
agp_be->bind = drm_agp_bind_ttm;
|
||||
agp_be->unbind = drm_agp_unbind_ttm;
|
||||
agp_be->destroy = drm_agp_destroy_ttm;
|
||||
return agp_be;
|
||||
}
|
||||
|
||||
|
||||
#endif /* __OS_HAS_AGP */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue