You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
drm/gem: Use struct dma_buf_map in GEM vmap ops and convert GEM backends
This patch replaces the vmap/vunmap's use of raw pointers in GEM object
functions with instances of struct dma_buf_map. GEM backends are
converted as well. For most of them, this simply changes the returned type.
TTM-based drivers now return information about the location of the memory,
either system or I/O memory. GEM VRAM helpers and qxl now use ttm_bo_vmap()
et al. Amdgpu, nouveau and radeon use drm_gem_ttm_vmap() et al instead of
implementing their own vmap callbacks.
v7:
* init QXL cursor to mapped BO buffer (kernel test robot)
v5:
* update vkms after switch to shmem
v4:
* use ttm_bo_vmap(), drm_gem_ttm_vmap(), et al. (Daniel, Christian)
* fix a trailing { in drm_gem_vmap()
* remove several empty functions instead of converting them (Daniel)
* comment uses of raw pointers with a TODO (Daniel)
* TODO list: convert more helpers to use struct dma_buf_map
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Christian König <christian.koenig@amd.com>
Tested-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20201103093015.1063-7-tzimmermann@suse.de
This commit is contained in:
@@ -450,6 +450,24 @@ Contact: Ville Syrjälä, Daniel Vetter
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
Use struct dma_buf_map throughout codebase
|
||||
------------------------------------------
|
||||
|
||||
Pointers to shared device memory are stored in struct dma_buf_map. Each
|
||||
instance knows whether it refers to system or I/O memory. Most of the DRM-wide
|
||||
interface have been converted to use struct dma_buf_map, but implementations
|
||||
often still use raw pointers.
|
||||
|
||||
The task is to use struct dma_buf_map where it makes sense.
|
||||
|
||||
* Memory managers should use struct dma_buf_map for dma-buf-imported buffers.
|
||||
* TTM might benefit from using struct dma_buf_map internally.
|
||||
* Framebuffer copying and blitting helpers should operate on struct dma_buf_map.
|
||||
|
||||
Contact: Thomas Zimmermann <tzimmermann@suse.de>, Christian König, Daniel Vetter
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
|
||||
Core refactorings
|
||||
=================
|
||||
|
||||
@@ -232,6 +232,7 @@ config DRM_RADEON
|
||||
select FW_LOADER
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_TTM
|
||||
select DRM_TTM_HELPER
|
||||
select POWER_SUPPLY
|
||||
select HWMON
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
@@ -252,6 +253,7 @@ config DRM_AMDGPU
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_SCHED
|
||||
select DRM_TTM
|
||||
select DRM_TTM_HELPER
|
||||
select POWER_SUPPLY
|
||||
select HWMON
|
||||
select BACKLIGHT_CLASS_DEVICE
|
||||
|
||||
@@ -41,42 +41,6 @@
|
||||
#include <linux/dma-fence-array.h>
|
||||
#include <linux/pci-p2pdma.h>
|
||||
|
||||
/**
|
||||
* amdgpu_gem_prime_vmap - &dma_buf_ops.vmap implementation
|
||||
* @obj: GEM BO
|
||||
*
|
||||
* Sets up an in-kernel virtual mapping of the BO's memory.
|
||||
*
|
||||
* Returns:
|
||||
* The virtual address of the mapping or an error pointer.
|
||||
*/
|
||||
void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj)
|
||||
{
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
|
||||
int ret;
|
||||
|
||||
ret = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages,
|
||||
&bo->dma_buf_vmap);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return bo->dma_buf_vmap.virtual;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gem_prime_vunmap - &dma_buf_ops.vunmap implementation
|
||||
* @obj: GEM BO
|
||||
* @vaddr: Virtual address (unused)
|
||||
*
|
||||
* Tears down the in-kernel virtual mapping of the BO's memory.
|
||||
*/
|
||||
void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
|
||||
{
|
||||
struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
|
||||
|
||||
ttm_bo_kunmap(&bo->dma_buf_vmap);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_gem_prime_mmap - &drm_driver.gem_prime_mmap implementation
|
||||
* @obj: GEM BO
|
||||
|
||||
@@ -31,8 +31,6 @@ struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev,
|
||||
struct dma_buf *dma_buf);
|
||||
bool amdgpu_dmabuf_is_xgmi_accessible(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo *bo);
|
||||
void *amdgpu_gem_prime_vmap(struct drm_gem_object *obj);
|
||||
void amdgpu_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
|
||||
int amdgpu_gem_prime_mmap(struct drm_gem_object *obj,
|
||||
struct vm_area_struct *vma);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <drm/amdgpu_drm.h>
|
||||
#include <drm/drm_debugfs.h>
|
||||
#include <drm/drm_gem_ttm_helper.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_display.h"
|
||||
@@ -220,8 +221,8 @@ static const struct drm_gem_object_funcs amdgpu_gem_object_funcs = {
|
||||
.open = amdgpu_gem_object_open,
|
||||
.close = amdgpu_gem_object_close,
|
||||
.export = amdgpu_gem_prime_export,
|
||||
.vmap = amdgpu_gem_prime_vmap,
|
||||
.vunmap = amdgpu_gem_prime_vunmap,
|
||||
.vmap = drm_gem_ttm_vmap,
|
||||
.vunmap = drm_gem_ttm_vunmap,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -100,7 +100,6 @@ struct amdgpu_bo {
|
||||
struct amdgpu_bo *parent;
|
||||
struct amdgpu_bo *shadow;
|
||||
|
||||
struct ttm_bo_kmap_obj dma_buf_vmap;
|
||||
struct amdgpu_mn *mn;
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ static void ast_cursor_fini(struct ast_private *ast)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ast->cursor.gbo); ++i) {
|
||||
gbo = ast->cursor.gbo[i];
|
||||
drm_gem_vram_vunmap(gbo, ast->cursor.vaddr[i]);
|
||||
drm_gem_vram_vunmap(gbo, &ast->cursor.map[i]);
|
||||
drm_gem_vram_unpin(gbo);
|
||||
drm_gem_vram_put(gbo);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ int ast_cursor_init(struct ast_private *ast)
|
||||
struct drm_device *dev = &ast->base;
|
||||
size_t size, i;
|
||||
struct drm_gem_vram_object *gbo;
|
||||
void __iomem *vaddr;
|
||||
struct dma_buf_map map;
|
||||
int ret;
|
||||
|
||||
size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
|
||||
@@ -77,16 +77,15 @@ int ast_cursor_init(struct ast_private *ast)
|
||||
drm_gem_vram_put(gbo);
|
||||
goto err_drm_gem_vram_put;
|
||||
}
|
||||
vaddr = drm_gem_vram_vmap(gbo);
|
||||
if (IS_ERR(vaddr)) {
|
||||
ret = PTR_ERR(vaddr);
|
||||
ret = drm_gem_vram_vmap(gbo, &map);
|
||||
if (ret) {
|
||||
drm_gem_vram_unpin(gbo);
|
||||
drm_gem_vram_put(gbo);
|
||||
goto err_drm_gem_vram_put;
|
||||
}
|
||||
|
||||
ast->cursor.gbo[i] = gbo;
|
||||
ast->cursor.vaddr[i] = vaddr;
|
||||
ast->cursor.map[i] = map;
|
||||
}
|
||||
|
||||
return drmm_add_action_or_reset(dev, ast_cursor_release, NULL);
|
||||
@@ -95,7 +94,7 @@ err_drm_gem_vram_put:
|
||||
while (i) {
|
||||
--i;
|
||||
gbo = ast->cursor.gbo[i];
|
||||
drm_gem_vram_vunmap(gbo, ast->cursor.vaddr[i]);
|
||||
drm_gem_vram_vunmap(gbo, &ast->cursor.map[i]);
|
||||
drm_gem_vram_unpin(gbo);
|
||||
drm_gem_vram_put(gbo);
|
||||
}
|
||||
@@ -170,6 +169,7 @@ int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb)
|
||||
{
|
||||
struct drm_device *dev = &ast->base;
|
||||
struct drm_gem_vram_object *gbo;
|
||||
struct dma_buf_map map;
|
||||
int ret;
|
||||
void *src;
|
||||
void __iomem *dst;
|
||||
@@ -183,18 +183,17 @@ int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb)
|
||||
ret = drm_gem_vram_pin(gbo, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
src = drm_gem_vram_vmap(gbo);
|
||||
if (IS_ERR(src)) {
|
||||
ret = PTR_ERR(src);
|
||||
ret = drm_gem_vram_vmap(gbo, &map);
|
||||
if (ret)
|
||||
goto err_drm_gem_vram_unpin;
|
||||
}
|
||||
src = map.vaddr; /* TODO: Use mapping abstraction properly */
|
||||
|
||||
dst = ast->cursor.vaddr[ast->cursor.next_index];
|
||||
dst = ast->cursor.map[ast->cursor.next_index].vaddr_iomem;
|
||||
|
||||
/* do data transfer to cursor BO */
|
||||
update_cursor_image(dst, src, fb->width, fb->height);
|
||||
|
||||
drm_gem_vram_vunmap(gbo, src);
|
||||
drm_gem_vram_vunmap(gbo, &map);
|
||||
drm_gem_vram_unpin(gbo);
|
||||
|
||||
return 0;
|
||||
@@ -257,7 +256,7 @@ void ast_cursor_show(struct ast_private *ast, int x, int y,
|
||||
u8 __iomem *sig;
|
||||
u8 jreg;
|
||||
|
||||
dst = ast->cursor.vaddr[ast->cursor.next_index];
|
||||
dst = ast->cursor.map[ast->cursor.next_index].vaddr;
|
||||
|
||||
sig = dst + AST_HWC_SIZE;
|
||||
writel(x, sig + AST_HWC_SIGNATURE_X);
|
||||
|
||||
@@ -28,10 +28,11 @@
|
||||
#ifndef __AST_DRV_H__
|
||||
#define __AST_DRV_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/dma-buf-map.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-algo-bit.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
@@ -131,7 +132,7 @@ struct ast_private {
|
||||
|
||||
struct {
|
||||
struct drm_gem_vram_object *gbo[AST_DEFAULT_HWC_NUM];
|
||||
void __iomem *vaddr[AST_DEFAULT_HWC_NUM];
|
||||
struct dma_buf_map map[AST_DEFAULT_HWC_NUM];
|
||||
unsigned int next_index;
|
||||
} cursor;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/shmem_fs.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-buf-map.h>
|
||||
#include <linux/mem_encrypt.h>
|
||||
#include <linux/pagevec.h>
|
||||
|
||||
@@ -1207,26 +1208,30 @@ void drm_gem_unpin(struct drm_gem_object *obj)
|
||||
|
||||
void *drm_gem_vmap(struct drm_gem_object *obj)
|
||||
{
|
||||
void *vaddr;
|
||||
struct dma_buf_map map;
|
||||
int ret;
|
||||
|
||||
if (obj->funcs->vmap)
|
||||
vaddr = obj->funcs->vmap(obj);
|
||||
else
|
||||
vaddr = ERR_PTR(-EOPNOTSUPP);
|
||||
if (!obj->funcs->vmap)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
if (!vaddr)
|
||||
vaddr = ERR_PTR(-ENOMEM);
|
||||
ret = obj->funcs->vmap(obj, &map);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
else if (dma_buf_map_is_null(&map))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
return vaddr;
|
||||
return map.vaddr;
|
||||
}
|
||||
|
||||
void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr)
|
||||
{
|
||||
struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(vaddr);
|
||||
|
||||
if (!vaddr)
|
||||
return;
|
||||
|
||||
if (obj->funcs->vunmap)
|
||||
obj->funcs->vunmap(obj, vaddr);
|
||||
obj->funcs->vunmap(obj, &map);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -519,6 +519,8 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap);
|
||||
* drm_gem_cma_prime_vmap - map a CMA GEM object into the kernel's virtual
|
||||
* address space
|
||||
* @obj: GEM object
|
||||
* @map: Returns the kernel virtual address of the CMA GEM object's backing
|
||||
* store.
|
||||
*
|
||||
* This function maps a buffer exported via DRM PRIME into the kernel's
|
||||
* virtual address space. Since the CMA buffers are already mapped into the
|
||||
@@ -527,13 +529,15 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap);
|
||||
* driver's &drm_gem_object_funcs.vmap callback.
|
||||
*
|
||||
* Returns:
|
||||
* The kernel virtual address of the CMA GEM object's backing store.
|
||||
* 0 on success, or a negative error code otherwise.
|
||||
*/
|
||||
void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj)
|
||||
int drm_gem_cma_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
|
||||
{
|
||||
struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj);
|
||||
|
||||
return cma_obj->vaddr;
|
||||
dma_buf_map_set_vaddr(map, cma_obj->vaddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap);
|
||||
|
||||
|
||||
@@ -258,19 +258,25 @@ void drm_gem_shmem_unpin(struct drm_gem_object *obj)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_shmem_unpin);
|
||||
|
||||
static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem)
|
||||
static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map)
|
||||
{
|
||||
struct drm_gem_object *obj = &shmem->base;
|
||||
struct dma_buf_map map;
|
||||
int ret = 0;
|
||||
|
||||
if (shmem->vmap_use_count++ > 0)
|
||||
return shmem->vaddr;
|
||||
if (shmem->vmap_use_count++ > 0) {
|
||||
dma_buf_map_set_vaddr(map, shmem->vaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (obj->import_attach) {
|
||||
ret = dma_buf_vmap(obj->import_attach->dmabuf, &map);
|
||||
if (!ret)
|
||||
shmem->vaddr = map.vaddr;
|
||||
ret = dma_buf_vmap(obj->import_attach->dmabuf, map);
|
||||
if (!ret) {
|
||||
if (WARN_ON(map->is_iomem)) {
|
||||
ret = -EIO;
|
||||
goto err_put_pages;
|
||||
}
|
||||
shmem->vaddr = map->vaddr;
|
||||
}
|
||||
} else {
|
||||
pgprot_t prot = PAGE_KERNEL;
|
||||
|
||||
@@ -284,6 +290,8 @@ static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem)
|
||||
VM_MAP, prot);
|
||||
if (!shmem->vaddr)
|
||||
ret = -ENOMEM;
|
||||
else
|
||||
dma_buf_map_set_vaddr(map, shmem->vaddr);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
@@ -291,7 +299,7 @@ static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem)
|
||||
goto err_put_pages;
|
||||
}
|
||||
|
||||
return shmem->vaddr;
|
||||
return 0;
|
||||
|
||||
err_put_pages:
|
||||
if (!obj->import_attach)
|
||||
@@ -299,12 +307,14 @@ err_put_pages:
|
||||
err_zero_use:
|
||||
shmem->vmap_use_count = 0;
|
||||
|
||||
return ERR_PTR(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* drm_gem_shmem_vmap - Create a virtual mapping for a shmem GEM object
|
||||
* @shmem: shmem GEM object
|
||||
* @map: Returns the kernel virtual address of the SHMEM GEM object's backing
|
||||
* store.
|
||||
*
|
||||
* This function makes sure that a contiguous kernel virtual address mapping
|
||||
* exists for the buffer backing the shmem GEM object.
|
||||
@@ -318,26 +328,25 @@ err_zero_use:
|
||||
* Returns:
|
||||
* 0 on success or a negative error code on failure.
|
||||
*/
|
||||
void *drm_gem_shmem_vmap(struct drm_gem_object *obj)
|
||||
int drm_gem_shmem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
|
||||
{
|
||||
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
|
||||
void *vaddr;
|
||||
int ret;
|
||||
|
||||
ret = mutex_lock_interruptible(&shmem->vmap_lock);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
vaddr = drm_gem_shmem_vmap_locked(shmem);
|
||||
return ret;
|
||||
ret = drm_gem_shmem_vmap_locked(shmem, map);
|
||||
mutex_unlock(&shmem->vmap_lock);
|
||||
|
||||
return vaddr;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_shmem_vmap);
|
||||
|
||||
static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem)
|
||||
static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem,
|
||||
struct dma_buf_map *map)
|
||||
{
|
||||
struct drm_gem_object *obj = &shmem->base;
|
||||
struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(shmem->vaddr);
|
||||
|
||||
if (WARN_ON_ONCE(!shmem->vmap_use_count))
|
||||
return;
|
||||
@@ -346,7 +355,7 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem)
|
||||
return;
|
||||
|
||||
if (obj->import_attach)
|
||||
dma_buf_vunmap(obj->import_attach->dmabuf, &map);
|
||||
dma_buf_vunmap(obj->import_attach->dmabuf, map);
|
||||
else
|
||||
vunmap(shmem->vaddr);
|
||||
|
||||
@@ -357,6 +366,7 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem)
|
||||
/*
|
||||
* drm_gem_shmem_vunmap - Unmap a virtual mapping fo a shmem GEM object
|
||||
* @shmem: shmem GEM object
|
||||
* @map: Kernel virtual address where the SHMEM GEM object was mapped
|
||||
*
|
||||
* This function cleans up a kernel virtual address mapping acquired by
|
||||
* drm_gem_shmem_vmap(). The mapping is only removed when the use count drops to
|
||||
@@ -366,12 +376,12 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem)
|
||||
* also be called by drivers directly, in which case it will hide the
|
||||
* differences between dma-buf imported and natively allocated objects.
|
||||
*/
|
||||
void drm_gem_shmem_vunmap(struct drm_gem_object *obj, void *vaddr)
|
||||
void drm_gem_shmem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map)
|
||||
{
|
||||
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
|
||||
|
||||
mutex_lock(&shmem->vmap_lock);
|
||||
drm_gem_shmem_vunmap_locked(shmem);
|
||||
drm_gem_shmem_vunmap_locked(shmem, map);
|
||||
mutex_unlock(&shmem->vmap_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_shmem_vunmap);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <linux/dma-buf-map.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <drm/drm_debugfs.h>
|
||||
@@ -112,8 +113,8 @@ static void drm_gem_vram_cleanup(struct drm_gem_vram_object *gbo)
|
||||
* up; only release the GEM object.
|
||||
*/
|
||||
|
||||
WARN_ON(gbo->kmap_use_count);
|
||||
WARN_ON(gbo->kmap.virtual);
|
||||
WARN_ON(gbo->vmap_use_count);
|
||||
WARN_ON(dma_buf_map_is_set(&gbo->map));
|
||||
|
||||
drm_gem_object_release(&gbo->bo.base);
|
||||
}
|
||||
@@ -378,29 +379,37 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_vram_unpin);
|
||||
|
||||
static void *drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo)
|
||||
static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
|
||||
struct dma_buf_map *map)
|
||||
{
|
||||
int ret;
|
||||
struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
|
||||
bool is_iomem;
|
||||
|
||||
if (gbo->kmap_use_count > 0)
|
||||
if (gbo->vmap_use_count > 0)
|
||||
goto out;
|
||||
|
||||
ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, kmap);
|
||||
ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
return ret;
|
||||
|
||||
out:
|
||||
++gbo->kmap_use_count;
|
||||
return ttm_kmap_obj_virtual(kmap, &is_iomem);
|
||||
++gbo->vmap_use_count;
|
||||
*map = gbo->map;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo)
|
||||
static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo,
|
||||
struct dma_buf_map *map)
|
||||
{
|
||||
if (WARN_ON_ONCE(!gbo->kmap_use_count))
|
||||
struct drm_device *dev = gbo->bo.base.dev;
|
||||
|
||||
if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count))
|
||||
return;
|
||||
if (--gbo->kmap_use_count > 0)
|
||||
|
||||
if (drm_WARN_ON_ONCE(dev, !dma_buf_map_is_equal(&gbo->map, map)))
|
||||
return; /* BUG: map not mapped from this BO */
|
||||
|
||||
if (--gbo->vmap_use_count > 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -414,7 +423,9 @@ static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo)
|
||||
/**
|
||||
* drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
|
||||
* space
|
||||
* @gbo: The GEM VRAM object to map
|
||||
* @gbo: The GEM VRAM object to map
|
||||
* @map: Returns the kernel virtual address of the VRAM GEM object's backing
|
||||
* store.
|
||||
*
|
||||
* The vmap function pins a GEM VRAM object to its current location, either
|
||||
* system or video memory, and maps its buffer into kernel address space.
|
||||
@@ -423,48 +434,44 @@ static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo)
|
||||
* unmap and unpin the GEM VRAM object.
|
||||
*
|
||||
* Returns:
|
||||
* The buffer's virtual address on success, or
|
||||
* an ERR_PTR()-encoded error code otherwise.
|
||||
* 0 on success, or a negative error code otherwise.
|
||||
*/
|
||||
void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo)
|
||||
int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct dma_buf_map *map)
|
||||
{
|
||||
int ret;
|
||||
void *base;
|
||||
|
||||
ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
return ret;
|
||||
|
||||
ret = drm_gem_vram_pin_locked(gbo, 0);
|
||||
if (ret)
|
||||
goto err_ttm_bo_unreserve;
|
||||
base = drm_gem_vram_kmap_locked(gbo);
|
||||
if (IS_ERR(base)) {
|
||||
ret = PTR_ERR(base);
|
||||
ret = drm_gem_vram_kmap_locked(gbo, map);
|
||||
if (ret)
|
||||
goto err_drm_gem_vram_unpin_locked;
|
||||
}
|
||||
|
||||
ttm_bo_unreserve(&gbo->bo);
|
||||
|
||||
return base;
|
||||
return 0;
|
||||
|
||||
err_drm_gem_vram_unpin_locked:
|
||||
drm_gem_vram_unpin_locked(gbo);
|
||||
err_ttm_bo_unreserve:
|
||||
ttm_bo_unreserve(&gbo->bo);
|
||||
return ERR_PTR(ret);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_vram_vmap);
|
||||
|
||||
/**
|
||||
* drm_gem_vram_vunmap() - Unmaps and unpins a GEM VRAM object
|
||||
* @gbo: The GEM VRAM object to unmap
|
||||
* @vaddr: The mapping's base address as returned by drm_gem_vram_vmap()
|
||||
* @gbo: The GEM VRAM object to unmap
|
||||
* @map: Kernel virtual address where the VRAM GEM object was mapped
|
||||
*
|
||||
* A call to drm_gem_vram_vunmap() unmaps and unpins a GEM VRAM buffer. See
|
||||
* the documentation for drm_gem_vram_vmap() for more information.
|
||||
*/
|
||||
void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, void *vaddr)
|
||||
void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, struct dma_buf_map *map)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -472,7 +479,7 @@ void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, void *vaddr)
|
||||
if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
|
||||
return;
|
||||
|
||||
drm_gem_vram_kunmap_locked(gbo);
|
||||
drm_gem_vram_kunmap_locked(gbo, map);
|
||||
drm_gem_vram_unpin_locked(gbo);
|
||||
|
||||
ttm_bo_unreserve(&gbo->bo);
|
||||
@@ -563,15 +570,13 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo,
|
||||
bool evict,
|
||||
struct ttm_resource *new_mem)
|
||||
{
|
||||
struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
|
||||
struct ttm_buffer_object *bo = &gbo->bo;
|
||||
struct drm_device *dev = bo->base.dev;
|
||||
|
||||
if (WARN_ON_ONCE(gbo->kmap_use_count))
|
||||
if (drm_WARN_ON_ONCE(dev, gbo->vmap_use_count))
|
||||
return;
|
||||
|
||||
if (!kmap->virtual)
|
||||
return;
|
||||
ttm_bo_kunmap(kmap);
|
||||
kmap->virtual = NULL;
|
||||
ttm_bo_vunmap(bo, &gbo->map);
|
||||
}
|
||||
|
||||
static int drm_gem_vram_bo_driver_move(struct drm_gem_vram_object *gbo,
|
||||
@@ -837,37 +842,33 @@ static void drm_gem_vram_object_unpin(struct drm_gem_object *gem)
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_gem_vram_object_vmap() - \
|
||||
Implements &struct drm_gem_object_funcs.vmap
|
||||
* @gem: The GEM object to map
|
||||
* drm_gem_vram_object_vmap() -
|
||||
* Implements &struct drm_gem_object_funcs.vmap
|
||||
* @gem: The GEM object to map
|
||||
* @map: Returns the kernel virtual address of the VRAM GEM object's backing
|
||||
* store.
|
||||
*
|
||||
* Returns:
|
||||
* The buffers virtual address on success, or
|
||||
* NULL otherwise.
|
||||
* 0 on success, or a negative error code otherwise.
|
||||
*/
|
||||
static void *drm_gem_vram_object_vmap(struct drm_gem_object *gem)
|
||||
static int drm_gem_vram_object_vmap(struct drm_gem_object *gem, struct dma_buf_map *map)
|
||||
{
|
||||
struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
|
||||
void *base;
|
||||
|
||||
base = drm_gem_vram_vmap(gbo);
|
||||
if (IS_ERR(base))
|
||||
return NULL;
|
||||
return base;
|
||||
return drm_gem_vram_vmap(gbo, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_gem_vram_object_vunmap() - \
|
||||
Implements &struct drm_gem_object_funcs.vunmap
|
||||
* @gem: The GEM object to unmap
|
||||
* @vaddr: The mapping's base address
|
||||
* drm_gem_vram_object_vunmap() -
|
||||
* Implements &struct drm_gem_object_funcs.vunmap
|
||||
* @gem: The GEM object to unmap
|
||||
* @map: Kernel virtual address where the VRAM GEM object was mapped
|
||||
*/
|
||||
static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem,
|
||||
void *vaddr)
|
||||
static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem, struct dma_buf_map *map)
|
||||
{
|
||||
struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
|
||||
|
||||
drm_gem_vram_vunmap(gbo, vaddr);
|
||||
drm_gem_vram_vunmap(gbo, map);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -51,7 +51,7 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
|
||||
int etnaviv_gem_mmap(struct file *filp, struct vm_area_struct *vma);
|
||||
int etnaviv_gem_mmap_offset(struct drm_gem_object *obj, u64 *offset);
|
||||
struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj);
|
||||
void *etnaviv_gem_prime_vmap(struct drm_gem_object *obj);
|
||||
int etnaviv_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map);
|
||||
int etnaviv_gem_prime_mmap(struct drm_gem_object *obj,
|
||||
struct vm_area_struct *vma);
|
||||
struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev,
|
||||
|
||||
@@ -22,9 +22,16 @@ struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj)
|
||||
return drm_prime_pages_to_sg(obj->dev, etnaviv_obj->pages, npages);
|
||||
}
|
||||
|
||||
void *etnaviv_gem_prime_vmap(struct drm_gem_object *obj)
|
||||
int etnaviv_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
|
||||
{
|
||||
return etnaviv_gem_vmap(obj);
|
||||
void *vaddr;
|
||||
|
||||
vaddr = etnaviv_gem_vmap(obj);
|
||||
if (!vaddr)
|
||||
return -ENOMEM;
|
||||
dma_buf_map_set_vaddr(map, vaddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int etnaviv_gem_prime_mmap(struct drm_gem_object *obj,
|
||||
|
||||
@@ -182,14 +182,14 @@ static int lima_gem_pin(struct drm_gem_object *obj)
|
||||
return drm_gem_shmem_pin(obj);
|
||||
}
|
||||
|
||||
static void *lima_gem_vmap(struct drm_gem_object *obj)
|
||||
static int lima_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
|
||||
{
|
||||
struct lima_bo *bo = to_lima_bo(obj);
|
||||
|
||||
if (bo->heap_size)
|
||||
return ERR_PTR(-EINVAL);
|
||||
return -EINVAL;
|
||||
|
||||
return drm_gem_shmem_vmap(obj);
|
||||
return drm_gem_shmem_vmap(obj, map);
|
||||
}
|
||||
|
||||
static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
/* Copyright 2017-2019 Qiang Yu <yuq825@gmail.com> */
|
||||
|
||||
#include <linux/dma-buf-map.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
@@ -303,6 +304,8 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task)
|
||||
struct lima_dump_chunk_buffer *buffer_chunk;
|
||||
u32 size, task_size, mem_size;
|
||||
int i;
|
||||
struct dma_buf_map map;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev->error_task_list_lock);
|
||||
|
||||
@@ -388,15 +391,15 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task)
|
||||
} else {
|
||||
buffer_chunk->size = lima_bo_size(bo);
|
||||
|
||||
data = drm_gem_shmem_vmap(&bo->base.base);
|
||||
if (IS_ERR_OR_NULL(data)) {
|
||||
ret = drm_gem_shmem_vmap(&bo->base.base, &map);
|
||||
if (ret) {
|
||||
kvfree(et);
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(buffer_chunk + 1, data, buffer_chunk->size);
|
||||
memcpy(buffer_chunk + 1, map.vaddr, buffer_chunk->size);
|
||||
|
||||
drm_gem_shmem_vunmap(&bo->base.base, data);
|
||||
drm_gem_shmem_vunmap(&bo->base.base, &map);
|
||||
}
|
||||
|
||||
buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-buf-map.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_atomic_state_helper.h>
|
||||
@@ -1551,15 +1552,18 @@ mgag200_handle_damage(struct mga_device *mdev, struct drm_framebuffer *fb,
|
||||
struct drm_rect *clip)
|
||||
{
|
||||
struct drm_device *dev = &mdev->base;
|
||||
struct dma_buf_map map;
|
||||
void *vmap;
|
||||
int ret;
|
||||
|
||||
vmap = drm_gem_shmem_vmap(fb->obj[0]);
|
||||
if (drm_WARN_ON(dev, !vmap))
|
||||
ret = drm_gem_shmem_vmap(fb->obj[0], &map);
|
||||
if (drm_WARN_ON(dev, ret))
|
||||
return; /* BUG: SHMEM BO should always be vmapped */
|
||||
vmap = map.vaddr; /* TODO: Use mapping abstraction properly */
|
||||
|
||||
drm_fb_memcpy_dstclip(mdev->vram, vmap, fb, clip);
|
||||
|
||||
drm_gem_shmem_vunmap(fb->obj[0], vmap);
|
||||
drm_gem_shmem_vunmap(fb->obj[0], &map);
|
||||
|
||||
/* Always scanout image at VRAM offset 0 */
|
||||
mgag200_set_startadd(mdev, (u32)0);
|
||||
|
||||
@@ -6,6 +6,7 @@ config DRM_NOUVEAU
|
||||
select FW_LOADER
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_TTM
|
||||
select DRM_TTM_HELPER
|
||||
select BACKLIGHT_CLASS_DEVICE if DRM_NOUVEAU_BACKLIGHT
|
||||
select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && INPUT
|
||||
select X86_PLATFORM_DEVICES if ACPI && X86
|
||||
|
||||
@@ -39,8 +39,6 @@ struct nouveau_bo {
|
||||
unsigned mode;
|
||||
|
||||
struct nouveau_drm_tile *tile;
|
||||
|
||||
struct ttm_bo_kmap_obj dma_buf_vmap;
|
||||
};
|
||||
|
||||
static inline struct nouveau_bo *
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drm/drm_gem_ttm_helper.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_dma.h"
|
||||
#include "nouveau_fence.h"
|
||||
@@ -176,8 +178,8 @@ const struct drm_gem_object_funcs nouveau_gem_object_funcs = {
|
||||
.pin = nouveau_gem_prime_pin,
|
||||
.unpin = nouveau_gem_prime_unpin,
|
||||
.get_sg_table = nouveau_gem_prime_get_sg_table,
|
||||
.vmap = nouveau_gem_prime_vmap,
|
||||
.vunmap = nouveau_gem_prime_vunmap,
|
||||
.vmap = drm_gem_ttm_vmap,
|
||||
.vunmap = drm_gem_ttm_vunmap,
|
||||
};
|
||||
|
||||
int
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user