drm/ttm: Add vmap/vunmap to TTM and TTM GEM helpers
The new functions ttm_bo_{vmap,vunmap}() map and unmap a TTM BO in kernel address space. The mapping's address is returned as struct dma_buf_map. Each function is a simplified version of TTM's existing kmap code. Both functions respect the memory's location ani/or writecombine flags. On top TTM's functions, GEM TTM helpers got drm_gem_ttm_{vmap,vunmap}(), two helpers that convert a GEM object into the TTM BO and forward the call to TTM's vmap/vunmap. These helpers can be dropped into the rsp GEM object callbacks. v5: * use size_t for storing mapping size (Christian) * ignore premapped memory areas correctly in ttm_bo_vunmap() * rebase onto latest TTM interfaces (Christian) * remove BUG() from ttm_bo_vmap() (Christian) v4: * drop ttm_kmap_obj_to_dma_buf() in favor of vmap helpers (Daniel, Christian) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Christian König <christian.koenig@amd.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Tested-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.freedesktop.org/patch/msgid/20201103093015.1063-6-tzimmermann@suse.de
This commit is contained in:
Родитель
f216fcb8e4
Коммит
43676605f8
|
@ -49,6 +49,43 @@ void drm_gem_ttm_print_info(struct drm_printer *p, unsigned int indent,
|
|||
}
|
||||
EXPORT_SYMBOL(drm_gem_ttm_print_info);
|
||||
|
||||
/**
|
||||
* drm_gem_ttm_vmap() - vmap &ttm_buffer_object
|
||||
* @gem: GEM object.
|
||||
* @map: [out] returns the dma-buf mapping.
|
||||
*
|
||||
* Maps a GEM object with ttm_bo_vmap(). This function can be used as
|
||||
* &drm_gem_object_funcs.vmap callback.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, or a negative errno code otherwise.
|
||||
*/
|
||||
int drm_gem_ttm_vmap(struct drm_gem_object *gem,
|
||||
struct dma_buf_map *map)
|
||||
{
|
||||
struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
|
||||
|
||||
return ttm_bo_vmap(bo, map);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_ttm_vmap);
|
||||
|
||||
/**
|
||||
* drm_gem_ttm_vunmap() - vunmap &ttm_buffer_object
|
||||
* @gem: GEM object.
|
||||
* @map: dma-buf mapping.
|
||||
*
|
||||
* Unmaps a GEM object with ttm_bo_vunmap(). This function can be used as
|
||||
* &drm_gem_object_funcs.vmap callback.
|
||||
*/
|
||||
void drm_gem_ttm_vunmap(struct drm_gem_object *gem,
|
||||
struct dma_buf_map *map)
|
||||
{
|
||||
struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
|
||||
|
||||
ttm_bo_vunmap(bo, map);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_ttm_vunmap);
|
||||
|
||||
/**
|
||||
* drm_gem_ttm_mmap() - mmap &ttm_buffer_object
|
||||
* @gem: GEM object.
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <drm/ttm/ttm_bo_driver.h>
|
||||
#include <drm/ttm/ttm_placement.h>
|
||||
#include <drm/drm_vma_manager.h>
|
||||
#include <linux/dma-buf-map.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/wait.h>
|
||||
|
@ -471,6 +472,77 @@ void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
|
|||
}
|
||||
EXPORT_SYMBOL(ttm_bo_kunmap);
|
||||
|
||||
int ttm_bo_vmap(struct ttm_buffer_object *bo, struct dma_buf_map *map)
|
||||
{
|
||||
struct ttm_resource *mem = &bo->mem;
|
||||
int ret;
|
||||
|
||||
ret = ttm_mem_io_reserve(bo->bdev, mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mem->bus.is_iomem) {
|
||||
void __iomem *vaddr_iomem;
|
||||
size_t size = bo->num_pages << PAGE_SHIFT;
|
||||
|
||||
if (mem->bus.addr)
|
||||
vaddr_iomem = (void __iomem *)mem->bus.addr;
|
||||
else if (mem->bus.caching == ttm_write_combined)
|
||||
vaddr_iomem = ioremap_wc(mem->bus.offset, size);
|
||||
else
|
||||
vaddr_iomem = ioremap(mem->bus.offset, size);
|
||||
|
||||
if (!vaddr_iomem)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_buf_map_set_vaddr_iomem(map, vaddr_iomem);
|
||||
|
||||
} else {
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
struct ttm_tt *ttm = bo->ttm;
|
||||
pgprot_t prot;
|
||||
void *vaddr;
|
||||
|
||||
ret = ttm_tt_populate(bo->bdev, ttm, &ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* We need to use vmap to get the desired page protection
|
||||
* or to make the buffer object look contiguous.
|
||||
*/
|
||||
prot = ttm_io_prot(bo, mem, PAGE_KERNEL);
|
||||
vaddr = vmap(ttm->pages, bo->num_pages, 0, prot);
|
||||
if (!vaddr)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_buf_map_set_vaddr(map, vaddr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_bo_vmap);
|
||||
|
||||
void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct dma_buf_map *map)
|
||||
{
|
||||
struct ttm_resource *mem = &bo->mem;
|
||||
|
||||
if (dma_buf_map_is_null(map))
|
||||
return;
|
||||
|
||||
if (!map->is_iomem)
|
||||
vunmap(map->vaddr);
|
||||
else if (!mem->bus.addr)
|
||||
iounmap(map->vaddr_iomem);
|
||||
dma_buf_map_clear(map);
|
||||
|
||||
ttm_mem_io_free(bo->bdev, &bo->mem);
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_bo_vunmap);
|
||||
|
||||
static int ttm_bo_wait_free_node(struct ttm_buffer_object *bo,
|
||||
bool dst_use_tt)
|
||||
{
|
||||
|
|
|
@ -10,11 +10,17 @@
|
|||
#include <drm/ttm/ttm_bo_api.h>
|
||||
#include <drm/ttm/ttm_bo_driver.h>
|
||||
|
||||
struct dma_buf_map;
|
||||
|
||||
#define drm_gem_ttm_of_gem(gem_obj) \
|
||||
container_of(gem_obj, struct ttm_buffer_object, base)
|
||||
|
||||
void drm_gem_ttm_print_info(struct drm_printer *p, unsigned int indent,
|
||||
const struct drm_gem_object *gem);
|
||||
int drm_gem_ttm_vmap(struct drm_gem_object *gem,
|
||||
struct dma_buf_map *map);
|
||||
void drm_gem_ttm_vunmap(struct drm_gem_object *gem,
|
||||
struct dma_buf_map *map);
|
||||
int drm_gem_ttm_mmap(struct drm_gem_object *gem,
|
||||
struct vm_area_struct *vma);
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@ struct ttm_bo_global;
|
|||
|
||||
struct ttm_bo_device;
|
||||
|
||||
struct dma_buf_map;
|
||||
|
||||
struct drm_mm_node;
|
||||
|
||||
struct ttm_placement;
|
||||
|
@ -495,6 +497,32 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page,
|
|||
*/
|
||||
void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map);
|
||||
|
||||
/**
|
||||
* ttm_bo_vmap
|
||||
*
|
||||
* @bo: The buffer object.
|
||||
* @map: pointer to a struct dma_buf_map representing the map.
|
||||
*
|
||||
* Sets up a kernel virtual mapping, using ioremap or vmap to the
|
||||
* data in the buffer object. The parameter @map returns the virtual
|
||||
* address as struct dma_buf_map. Unmap the buffer with ttm_bo_vunmap().
|
||||
*
|
||||
* Returns
|
||||
* -ENOMEM: Out of memory.
|
||||
* -EINVAL: Invalid range.
|
||||
*/
|
||||
int ttm_bo_vmap(struct ttm_buffer_object *bo, struct dma_buf_map *map);
|
||||
|
||||
/**
|
||||
* ttm_bo_vunmap
|
||||
*
|
||||
* @bo: The buffer object.
|
||||
* @map: Object describing the map to unmap.
|
||||
*
|
||||
* Unmaps a kernel map set up by ttm_bo_vmap().
|
||||
*/
|
||||
void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct dma_buf_map *map);
|
||||
|
||||
/**
|
||||
* ttm_bo_mmap_obj - mmap memory backed by a ttm buffer object.
|
||||
*
|
||||
|
|
|
@ -45,6 +45,12 @@
|
|||
*
|
||||
* dma_buf_map_set_vaddr(&map. 0xdeadbeaf);
|
||||
*
|
||||
* To set an address in I/O memory, use dma_buf_map_set_vaddr_iomem().
|
||||
*
|
||||
* .. code-block:: c
|
||||
*
|
||||
* dma_buf_map_set_vaddr_iomem(&map. 0xdeadbeaf);
|
||||
*
|
||||
* Test if a mapping is valid with either dma_buf_map_is_set() or
|
||||
* dma_buf_map_is_null().
|
||||
*
|
||||
|
@ -118,6 +124,20 @@ static inline void dma_buf_map_set_vaddr(struct dma_buf_map *map, void *vaddr)
|
|||
map->is_iomem = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_buf_map_set_vaddr_iomem - Sets a dma-buf mapping structure to an address in I/O memory
|
||||
* @map: The dma-buf mapping structure
|
||||
* @vaddr_iomem: An I/O-memory address
|
||||
*
|
||||
* Sets the address and the I/O-memory flag.
|
||||
*/
|
||||
static inline void dma_buf_map_set_vaddr_iomem(struct dma_buf_map *map,
|
||||
void __iomem *vaddr_iomem)
|
||||
{
|
||||
map->vaddr_iomem = vaddr_iomem;
|
||||
map->is_iomem = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* dma_buf_map_is_equal - Compares two dma-buf mapping structures for equality
|
||||
* @lhs: The dma-buf mapping structure
|
||||
|
|
Загрузка…
Ссылка в новой задаче