diff options
author | Ari Hirvonen <ahirvonen@nvidia.com> | 2015-06-15 15:26:37 +0900 |
---|---|---|
committer | Alexandre Courbot <acourbot@nvidia.com> | 2016-01-15 14:32:54 +0900 |
commit | ce8a0340c70fa3f181e0b0725322b29f36166fa3 (patch) | |
tree | aef66a1ccd08d131b87fc10c6d4471a144faeac2 /drm/nouveau/nouveau_gem.c | |
parent | eb87d86fd2c1395485d5cea93fe6159146fd1d9b (diff) | |
download | nouveau-ce8a0340c70fa3f181e0b0725322b29f36166fa3.tar.gz |
drm/nouveau: add GEM_SET_TILING staging ioctl
Add new NOUVEAU_GEM_SET_TILING ioctl to set correct tiling
mode for imported dma-bufs. This ioctl is staging for now
and enabled with the "staging_tiling" module option.
Signed-off-by: Ari Hirvonen <ahirvonen@nvidia.com>
[acourbot@nvidia.com: carry upstream, many fixes]
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Diffstat (limited to 'drm/nouveau/nouveau_gem.c')
-rw-r--r-- | drm/nouveau/nouveau_gem.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/drm/nouveau/nouveau_gem.c b/drm/nouveau/nouveau_gem.c index a0865c49e..789f7aaef 100644 --- a/drm/nouveau/nouveau_gem.c +++ b/drm/nouveau/nouveau_gem.c @@ -175,6 +175,60 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) } int +nouveau_gem_ioctl_set_tiling(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_cli *cli = nouveau_cli(file_priv); + struct nvkm_fb *pfb = nvxx_fb(&drm->device); + struct drm_nouveau_gem_set_tiling *req = data; + struct drm_gem_object *gem; + struct nouveau_bo *nvbo; + struct nvkm_vma *vma; + int ret = 0; + + if (!nvkm_fb_memtype_valid(pfb, req->tile_flags)) { + NV_PRINTK(err, cli, "bad page flags: 0x%08x\n", req->tile_flags); + return -EINVAL; + } + + gem = drm_gem_object_lookup(dev, file_priv, req->handle); + if (!gem) + return -ENOENT; + + nvbo = nouveau_gem_object(gem); + + /* We can only change tiling on PRIME-imported buffers */ + if (nvbo->bo.type != ttm_bo_type_sg) { + ret = -EINVAL; + goto out; + } + + if (nvbo->tile_mode != req->tile_mode || + nvbo->tile_flags != req->tile_flags) { + ret = ttm_bo_reserve(&nvbo->bo, false, false, false, NULL); + if (ret) + goto out; + + nvbo->tile_mode = req->tile_mode; + nvbo->tile_flags = req->tile_flags; + + nouveau_bo_update_tiling(drm, nvbo, nvbo->bo.mem.mm_node); + + /* remap over existing mapping with new tile parameters */ + vma = nouveau_bo_vma_find(nvbo, cli->vm); + if (vma) + nvkm_vm_map(vma, nvbo->bo.mem.mm_node); + + ttm_bo_unreserve(&nvbo->bo); + } + +out: + drm_gem_object_unreference_unlocked(gem); + return ret; +} + +int nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain, uint32_t tile_mode, uint32_t tile_flags, struct nouveau_bo **pnvbo) |