summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAri Hirvonen <ahirvonen@nvidia.com>2015-02-16 17:02:48 +0900
committerAlexandre Courbot <acourbot@nvidia.com>2015-03-27 16:06:57 +0900
commit73de0a7758eb447d6157d2ed79c84d1a4e6ca09b (patch)
treee9099103d0b3d90f9822fadca5d9ffe214783464
parentdb8926500e7a0bb12a3f7ce88d883d7c2518b7a9 (diff)
downloadnouveau-baserock/tegra/4.0.tar.gz
drm/nouveau: Set tile modebaserock/tegra/4.0
Add new NOUVEAU_GEM_SET_TILING ioctl to set correct tiling mode for imported dma-bufs. Signed-off-by: Ari Hirvonen <ahirvonen@nvidia.com> Signed-off-by: Lauri Peltonen <lpeltonen@nvidia.com> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
-rw-r--r--drm/nouveau/nouveau_drm.c1
-rw-r--r--drm/nouveau/nouveau_gem.c56
-rw-r--r--drm/nouveau/nouveau_gem.h2
-rw-r--r--drm/nouveau/uapi/drm/nouveau_drm.h8
4 files changed, 67 insertions, 0 deletions
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index 2908b6a14..dbb51410d 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -890,6 +890,7 @@ nouveau_ioctls[] = {
DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_abi16_ioctl_notifierobj_alloc, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_abi16_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_SET_TILING, nouveau_gem_ioctl_set_tiling, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF_2, nouveau_gem_ioctl_pushbuf_2, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
diff --git a/drm/nouveau/nouveau_gem.c b/drm/nouveau/nouveau_gem.c
index 9ebf16c1a..bc14f631e 100644
--- a/drm/nouveau/nouveau_gem.c
+++ b/drm/nouveau/nouveau_gem.c
@@ -173,6 +173,62 @@ 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 (!pfb->memtype_valid(pfb, req->tile_flags)) {
+ NV_PRINTK(error, cli, "bad memtype: 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);
+
+ 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;
+
+ vma = nouveau_bo_vma_find(nvbo, cli->vm);
+
+ if (!vma) {
+ ret = -ENOENT;
+ } else {
+ struct nvkm_mem *mem = nvbo->bo.mem.mm_node;
+
+ nvbo->tile_mode = req->tile_mode;
+ nvbo->tile_flags = req->tile_flags;
+
+ /* Need to rewrite page tables */
+ mem->memtype = (nvbo->tile_flags >> 8) & 0xff;
+ 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)
diff --git a/drm/nouveau/nouveau_gem.h b/drm/nouveau/nouveau_gem.h
index 07f54a4fe..9e4323f34 100644
--- a/drm/nouveau/nouveau_gem.h
+++ b/drm/nouveau/nouveau_gem.h
@@ -23,6 +23,8 @@ extern void nouveau_gem_object_del(struct drm_gem_object *);
extern int nouveau_gem_object_open(struct drm_gem_object *, struct drm_file *);
extern void nouveau_gem_object_close(struct drm_gem_object *,
struct drm_file *);
+extern int nouveau_gem_ioctl_set_tiling(struct drm_device *, void *,
+ struct drm_file *);
extern int nouveau_gem_ioctl_new(struct drm_device *, void *,
struct drm_file *);
extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *,
diff --git a/drm/nouveau/uapi/drm/nouveau_drm.h b/drm/nouveau/uapi/drm/nouveau_drm.h
index 01a4cf44d..34033d1cf 100644
--- a/drm/nouveau/uapi/drm/nouveau_drm.h
+++ b/drm/nouveau/uapi/drm/nouveau_drm.h
@@ -64,6 +64,12 @@ struct drm_nouveau_gem_new {
uint32_t align;
};
+struct drm_nouveau_gem_set_tiling {
+ uint32_t handle;
+ uint32_t tile_mode;
+ uint32_t tile_flags;
+};
+
#define NOUVEAU_GEM_MAX_BUFFERS 1024
struct drm_nouveau_gem_pushbuf_bo_presumed {
uint32_t valid;
@@ -156,8 +162,10 @@ struct drm_nouveau_gem_cpu_fini {
#define DRM_NOUVEAU_GEM_CPU_FINI 0x43
#define DRM_NOUVEAU_GEM_INFO 0x44
#define DRM_NOUVEAU_GEM_PUSHBUF_2 0x45
+#define DRM_NOUVEAU_GEM_SET_TILING 0x46
#define DRM_IOCTL_NOUVEAU_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new)
+#define DRM_IOCTL_NOUVEAU_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_SET_TILING, struct drm_nouveau_gem_set_tiling)
#define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf)
#define DRM_IOCTL_NOUVEAU_GEM_PUSHBUF_2 DRM_IOWR(DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_PUSHBUF_2, struct drm_nouveau_gem_pushbuf_2)
#define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep)