From 9ace404b1098221021b01c2ba0eeea0c257fa4a5 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 14:54:06 +1000
Subject: drm/nouveau/device: include core/device.h automatically for
 subdevs/engines

Pretty much every subdev/engine is going to need access to nvkm_device
shortly to touch registers and/or output messages.

The odd placement of the includes is necessary to work around some
inter-dependencies that currently exist.  This will be fixed later.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 1 -
 1 file changed, 1 deletion(-)

(limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c')

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index dd0994d9ebfc..cd8ab5fcb585 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -40,7 +40,6 @@
 
 #include <subdev/fb.h>
 #include <core/mm.h>
-#include <core/device.h>
 
 #ifdef __KERNEL__
 #include <linux/dma-attrs.h>
-- 
cgit v1.2.3-70-g09d2


From c44c06aeebf481fb69c665a21090f2f0aac878c5 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 14:54:06 +1000
Subject: drm/nouveau/imem: cosmetic changes

This is purely preparation for upcoming commits, there should be no
code changes here.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 .../gpu/drm/nouveau/include/nvkm/subdev/instmem.h  |   2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c    |   2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c    |   2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c    |   2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c    |   2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c |  18 +--
 .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c    | 156 ++++++++++-----------
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c |  78 +++++------
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h |   6 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c |  60 ++++----
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c |  54 +++----
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h |  10 +-
 12 files changed, 194 insertions(+), 198 deletions(-)

(limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c')

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
index 1bcb763cfca0..f9812a9e8a8c 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
@@ -21,7 +21,7 @@ nv_memobj(void *obj)
 }
 
 struct nvkm_instmem {
-	struct nvkm_subdev base;
+	struct nvkm_subdev subdev;
 	struct list_head list;
 
 	u32 reserved;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
index d157aaede405..bdf635f9ab5f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
@@ -559,7 +559,7 @@ nv04_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
 	       struct nvkm_object **pobject)
 {
-	struct nv04_instmem_priv *imem = nv04_instmem(parent);
+	struct nv04_instmem *imem = nv04_instmem(parent);
 	struct nv04_fifo_priv *priv;
 	int ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
index 48ce4af6f543..3537accc927b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
@@ -143,7 +143,7 @@ nv10_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
 	       struct nvkm_object **pobject)
 {
-	struct nv04_instmem_priv *imem = nv04_instmem(parent);
+	struct nv04_instmem *imem = nv04_instmem(parent);
 	struct nv04_fifo_priv *priv;
 	int ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
index 4a20a6fd3887..e9c88da81f10 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
@@ -150,7 +150,7 @@ nv17_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
 	       struct nvkm_object **pobject)
 {
-	struct nv04_instmem_priv *imem = nv04_instmem(parent);
+	struct nv04_instmem *imem = nv04_instmem(parent);
 	struct nv04_fifo_priv *priv;
 	int ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
index a9bb6a53f9fa..f9456a5c762c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
@@ -268,7 +268,7 @@ nv40_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
 	       struct nvkm_object **pobject)
 {
-	struct nv04_instmem_priv *imem = nv04_instmem(parent);
+	struct nv04_instmem *imem = nv04_instmem(parent);
 	struct nv04_fifo_priv *priv;
 	int ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
index d16358cc6cbb..43a8f4e19eb6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
@@ -56,9 +56,9 @@ nvkm_instobj_create_(struct nvkm_object *parent, struct nvkm_object *engine,
 	if (ret)
 		return ret;
 
-	mutex_lock(&imem->base.mutex);
+	mutex_lock(&imem->subdev.mutex);
 	list_add(&iobj->head, &imem->list);
-	mutex_unlock(&imem->base.mutex);
+	mutex_unlock(&imem->subdev.mutex);
 	return 0;
 }
 
@@ -70,7 +70,7 @@ static int
 nvkm_instmem_alloc(struct nvkm_instmem *imem, struct nvkm_object *parent,
 		   u32 size, u32 align, struct nvkm_object **pobject)
 {
-	struct nvkm_instmem_impl *impl = (void *)imem->base.object.oclass;
+	struct nvkm_instmem_impl *impl = (void *)imem->subdev.object.oclass;
 	struct nvkm_instobj_args args = { .size = size, .align = align };
 	return nvkm_object_ctor(parent, &parent->engine->subdev.object,
 				impl->instobj, &args, sizeof(args), pobject);
@@ -84,7 +84,7 @@ _nvkm_instmem_fini(struct nvkm_object *object, bool suspend)
 	int i, ret = 0;
 
 	if (suspend) {
-		mutex_lock(&imem->base.mutex);
+		mutex_lock(&imem->subdev.mutex);
 		list_for_each_entry(iobj, &imem->list, head) {
 			iobj->suspend = vmalloc(iobj->size);
 			if (!iobj->suspend) {
@@ -95,12 +95,12 @@ _nvkm_instmem_fini(struct nvkm_object *object, bool suspend)
 			for (i = 0; i < iobj->size; i += 4)
 				iobj->suspend[i / 4] = nv_ro32(iobj, i);
 		}
-		mutex_unlock(&imem->base.mutex);
+		mutex_unlock(&imem->subdev.mutex);
 		if (ret)
 			return ret;
 	}
 
-	return nvkm_subdev_fini(&imem->base, suspend);
+	return nvkm_subdev_fini(&imem->subdev, suspend);
 }
 
 int
@@ -110,11 +110,11 @@ _nvkm_instmem_init(struct nvkm_object *object)
 	struct nvkm_instobj *iobj;
 	int ret, i;
 
-	ret = nvkm_subdev_init(&imem->base);
+	ret = nvkm_subdev_init(&imem->subdev);
 	if (ret)
 		return ret;
 
-	mutex_lock(&imem->base.mutex);
+	mutex_lock(&imem->subdev.mutex);
 	list_for_each_entry(iobj, &imem->list, head) {
 		if (iobj->suspend) {
 			for (i = 0; i < iobj->size; i += 4)
@@ -123,7 +123,7 @@ _nvkm_instmem_init(struct nvkm_object *object)
 			iobj->suspend = NULL;
 		}
 	}
-	mutex_unlock(&imem->base.mutex);
+	mutex_unlock(&imem->subdev.mutex);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index cd8ab5fcb585..abc41c0a4ad8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -49,7 +49,7 @@
 
 #include "priv.h"
 
-struct gk20a_instobj_priv {
+struct gk20a_instobj {
 	struct nvkm_instobj base;
 	/* Must be second member here - see nouveau_gpuobj_map_vm() */
 	struct nvkm_mem *mem;
@@ -61,7 +61,7 @@ struct gk20a_instobj_priv {
  * Used for objects allocated using the DMA API
  */
 struct gk20a_instobj_dma {
-	struct gk20a_instobj_priv base;
+	struct gk20a_instobj base;
 
 	void *cpuaddr;
 	dma_addr_t handle;
@@ -72,13 +72,13 @@ struct gk20a_instobj_dma {
  * Used for objects flattened using the IOMMU API
  */
 struct gk20a_instobj_iommu {
-	struct gk20a_instobj_priv base;
+	struct gk20a_instobj base;
 
 	/* array of base.mem->size pages */
 	struct page *pages[];
 };
 
-struct gk20a_instmem_priv {
+struct gk20a_instmem {
 	struct nvkm_instmem base;
 	spinlock_t lock;
 	u64 addr;
@@ -105,60 +105,60 @@ struct gk20a_instmem_priv {
 static u32
 gk20a_instobj_rd32(struct nvkm_object *object, u64 offset)
 {
-	struct gk20a_instmem_priv *priv = (void *)nvkm_instmem(object);
-	struct gk20a_instobj_priv *node = (void *)object;
+	struct gk20a_instmem *imem = (void *)nvkm_instmem(object);
+	struct gk20a_instobj *node = (void *)object;
 	unsigned long flags;
 	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
 	u32 data;
 
-	spin_lock_irqsave(&priv->lock, flags);
-	if (unlikely(priv->addr != base)) {
-		nv_wr32(priv, 0x001700, base >> 16);
-		priv->addr = base;
+	spin_lock_irqsave(&imem->lock, flags);
+	if (unlikely(imem->addr != base)) {
+		nv_wr32(imem, 0x001700, base >> 16);
+		imem->addr = base;
 	}
-	data = nv_rd32(priv, 0x700000 + addr);
-	spin_unlock_irqrestore(&priv->lock, flags);
+	data = nv_rd32(imem, 0x700000 + addr);
+	spin_unlock_irqrestore(&imem->lock, flags);
 	return data;
 }
 
 static void
 gk20a_instobj_wr32(struct nvkm_object *object, u64 offset, u32 data)
 {
-	struct gk20a_instmem_priv *priv = (void *)nvkm_instmem(object);
-	struct gk20a_instobj_priv *node = (void *)object;
+	struct gk20a_instmem *imem = (void *)nvkm_instmem(object);
+	struct gk20a_instobj *node = (void *)object;
 	unsigned long flags;
 	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
 
-	spin_lock_irqsave(&priv->lock, flags);
-	if (unlikely(priv->addr != base)) {
-		nv_wr32(priv, 0x001700, base >> 16);
-		priv->addr = base;
+	spin_lock_irqsave(&imem->lock, flags);
+	if (unlikely(imem->addr != base)) {
+		nv_wr32(imem, 0x001700, base >> 16);
+		imem->addr = base;
 	}
-	nv_wr32(priv, 0x700000 + addr, data);
-	spin_unlock_irqrestore(&priv->lock, flags);
+	nv_wr32(imem, 0x700000 + addr, data);
+	spin_unlock_irqrestore(&imem->lock, flags);
 }
 
 static void
-gk20a_instobj_dtor_dma(struct gk20a_instobj_priv *_node)
+gk20a_instobj_dtor_dma(struct gk20a_instobj *_node)
 {
 	struct gk20a_instobj_dma *node = (void *)_node;
-	struct gk20a_instmem_priv *priv = (void *)nvkm_instmem(node);
-	struct device *dev = nv_device_base(nv_device(priv));
+	struct gk20a_instmem *imem = (void *)nvkm_instmem(node);
+	struct device *dev = nv_device_base(nv_device(imem));
 
 	if (unlikely(!node->cpuaddr))
 		return;
 
 	dma_free_attrs(dev, _node->mem->size << PAGE_SHIFT, node->cpuaddr,
-		       node->handle, &priv->attrs);
+		       node->handle, &imem->attrs);
 }
 
 static void
-gk20a_instobj_dtor_iommu(struct gk20a_instobj_priv *_node)
+gk20a_instobj_dtor_iommu(struct gk20a_instobj *_node)
 {
 	struct gk20a_instobj_iommu *node = (void *)_node;
-	struct gk20a_instmem_priv *priv = (void *)nvkm_instmem(node);
+	struct gk20a_instmem *imem = (void *)nvkm_instmem(node);
 	struct nvkm_mm_node *r;
 	int i;
 
@@ -169,28 +169,28 @@ gk20a_instobj_dtor_iommu(struct gk20a_instobj_priv *_node)
 			     rl_entry);
 
 	/* clear bit 34 to unmap pages */
-	r->offset &= ~BIT(34 - priv->iommu_pgshift);
+	r->offset &= ~BIT(34 - imem->iommu_pgshift);
 
 	/* Unmap pages from GPU address space and free them */
 	for (i = 0; i < _node->mem->size; i++) {
-		iommu_unmap(priv->domain,
-			    (r->offset + i) << priv->iommu_pgshift, PAGE_SIZE);
+		iommu_unmap(imem->domain,
+			    (r->offset + i) << imem->iommu_pgshift, PAGE_SIZE);
 		__free_page(node->pages[i]);
 	}
 
 	/* Release area from GPU address space */
-	mutex_lock(priv->mm_mutex);
-	nvkm_mm_free(priv->mm, &r);
-	mutex_unlock(priv->mm_mutex);
+	mutex_lock(imem->mm_mutex);
+	nvkm_mm_free(imem->mm, &r);
+	mutex_unlock(imem->mm_mutex);
 }
 
 static void
 gk20a_instobj_dtor(struct nvkm_object *object)
 {
-	struct gk20a_instobj_priv *node = (void *)object;
-	struct gk20a_instmem_priv *priv = (void *)nvkm_instmem(node);
+	struct gk20a_instobj *node = (void *)object;
+	struct gk20a_instmem *imem = (void *)nvkm_instmem(node);
 
-	if (priv->domain)
+	if (imem->domain)
 		gk20a_instobj_dtor_iommu(node);
 	else
 		gk20a_instobj_dtor_dma(node);
@@ -201,10 +201,10 @@ gk20a_instobj_dtor(struct nvkm_object *object)
 static int
 gk20a_instobj_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 		       struct nvkm_oclass *oclass, u32 npages, u32 align,
-		       struct gk20a_instobj_priv **_node)
+		       struct gk20a_instobj **_node)
 {
 	struct gk20a_instobj_dma *node;
-	struct gk20a_instmem_priv *priv = (void *)nvkm_instmem(parent);
+	struct gk20a_instmem *imem = (void *)nvkm_instmem(parent);
 	struct device *dev = nv_device_base(nv_device(parent));
 	int ret;
 
@@ -216,15 +216,15 @@ gk20a_instobj_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	node->cpuaddr = dma_alloc_attrs(dev, npages << PAGE_SHIFT,
 					&node->handle, GFP_KERNEL,
-					&priv->attrs);
+					&imem->attrs);
 	if (!node->cpuaddr) {
-		nv_error(priv, "cannot allocate DMA memory\n");
+		nv_error(imem, "cannot allocate DMA memory\n");
 		return -ENOMEM;
 	}
 
 	/* alignment check */
 	if (unlikely(node->handle & (align - 1)))
-		nv_warn(priv, "memory not aligned as requested: %pad (0x%x)\n",
+		nv_warn(imem, "memory not aligned as requested: %pad (0x%x)\n",
 			&node->handle, align);
 
 	/* present memory for being mapped using small pages */
@@ -243,10 +243,10 @@ gk20a_instobj_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 static int
 gk20a_instobj_ctor_iommu(struct nvkm_object *parent, struct nvkm_object *engine,
 			 struct nvkm_oclass *oclass, u32 npages, u32 align,
-			 struct gk20a_instobj_priv **_node)
+			 struct gk20a_instobj **_node)
 {
 	struct gk20a_instobj_iommu *node;
-	struct gk20a_instmem_priv *priv = (void *)nvkm_instmem(parent);
+	struct gk20a_instmem *imem = (void *)nvkm_instmem(parent);
 	struct nvkm_mm_node *r;
 	int ret;
 	int i;
@@ -269,38 +269,38 @@ gk20a_instobj_ctor_iommu(struct nvkm_object *parent, struct nvkm_object *engine,
 		node->pages[i] = p;
 	}
 
-	mutex_lock(priv->mm_mutex);
+	mutex_lock(imem->mm_mutex);
 	/* Reserve area from GPU address space */
-	ret = nvkm_mm_head(priv->mm, 0, 1, npages, npages,
-			   align >> priv->iommu_pgshift, &r);
-	mutex_unlock(priv->mm_mutex);
+	ret = nvkm_mm_head(imem->mm, 0, 1, npages, npages,
+			   align >> imem->iommu_pgshift, &r);
+	mutex_unlock(imem->mm_mutex);
 	if (ret) {
-		nv_error(priv, "virtual space is full!\n");
+		nv_error(imem, "virtual space is full!\n");
 		goto free_pages;
 	}
 
 	/* Map into GPU address space */
 	for (i = 0; i < npages; i++) {
 		struct page *p = node->pages[i];
-		u32 offset = (r->offset + i) << priv->iommu_pgshift;
+		u32 offset = (r->offset + i) << imem->iommu_pgshift;
 
-		ret = iommu_map(priv->domain, offset, page_to_phys(p),
+		ret = iommu_map(imem->domain, offset, page_to_phys(p),
 				PAGE_SIZE, IOMMU_READ | IOMMU_WRITE);
 		if (ret < 0) {
-			nv_error(priv, "IOMMU mapping failure: %d\n", ret);
+			nv_error(imem, "IOMMU mapping failure: %d\n", ret);
 
 			while (i-- > 0) {
 				offset -= PAGE_SIZE;
-				iommu_unmap(priv->domain, offset, PAGE_SIZE);
+				iommu_unmap(imem->domain, offset, PAGE_SIZE);
 			}
 			goto release_area;
 		}
 	}
 
 	/* Bit 34 tells that an address is to be resolved through the IOMMU */
-	r->offset |= BIT(34 - priv->iommu_pgshift);
+	r->offset |= BIT(34 - imem->iommu_pgshift);
 
-	node->base._mem.offset = ((u64)r->offset) << priv->iommu_pgshift;
+	node->base._mem.offset = ((u64)r->offset) << imem->iommu_pgshift;
 
 	INIT_LIST_HEAD(&node->base._mem.regions);
 	list_add_tail(&r->rl_entry, &node->base._mem.regions);
@@ -308,9 +308,9 @@ gk20a_instobj_ctor_iommu(struct nvkm_object *parent, struct nvkm_object *engine,
 	return 0;
 
 release_area:
-	mutex_lock(priv->mm_mutex);
-	nvkm_mm_free(priv->mm, &r);
-	mutex_unlock(priv->mm_mutex);
+	mutex_lock(imem->mm_mutex);
+	nvkm_mm_free(imem->mm, &r);
+	mutex_unlock(imem->mm_mutex);
 
 free_pages:
 	for (i = 0; i < npages && node->pages[i] != NULL; i++)
@@ -325,19 +325,19 @@ gk20a_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		   struct nvkm_object **pobject)
 {
 	struct nvkm_instobj_args *args = data;
-	struct gk20a_instmem_priv *priv = (void *)nvkm_instmem(parent);
-	struct gk20a_instobj_priv *node;
+	struct gk20a_instmem *imem = (void *)nvkm_instmem(parent);
+	struct gk20a_instobj *node;
 	u32 size, align;
 	int ret;
 
 	nv_debug(parent, "%s (%s): size: %x align: %x\n", __func__,
-		 priv->domain ? "IOMMU" : "DMA", args->size, args->align);
+		 imem->domain ? "IOMMU" : "DMA", args->size, args->align);
 
 	/* Round size and align to page bounds */
 	size = max(roundup(args->size, PAGE_SIZE), PAGE_SIZE);
 	align = max(roundup(args->align, PAGE_SIZE), PAGE_SIZE);
 
-	if (priv->domain)
+	if (imem->domain)
 		ret = gk20a_instobj_ctor_iommu(parent, engine, oclass,
 					      size >> PAGE_SHIFT, align, &node);
 	else
@@ -380,9 +380,9 @@ gk20a_instobj_oclass = {
 static int
 gk20a_instmem_fini(struct nvkm_object *object, bool suspend)
 {
-	struct gk20a_instmem_priv *priv = (void *)object;
-	priv->addr = ~0ULL;
-	return nvkm_instmem_fini(&priv->base, suspend);
+	struct gk20a_instmem *imem = (void *)object;
+	imem->addr = ~0ULL;
+	return nvkm_instmem_fini(&imem->base, suspend);
 }
 
 static int
@@ -390,37 +390,37 @@ gk20a_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		   struct nvkm_oclass *oclass, void *data, u32 size,
 		   struct nvkm_object **pobject)
 {
-	struct gk20a_instmem_priv *priv;
+	struct gk20a_instmem *imem;
 	struct nouveau_platform_device *plat;
 	int ret;
 
-	ret = nvkm_instmem_create(parent, engine, oclass, &priv);
-	*pobject = nv_object(priv);
+	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
+	*pobject = nv_object(imem);
 	if (ret)
 		return ret;
 
-	spin_lock_init(&priv->lock);
+	spin_lock_init(&imem->lock);
 
 	plat = nv_device_to_platform(nv_device(parent));
 	if (plat->gpu->iommu.domain) {
-		priv->domain = plat->gpu->iommu.domain;
-		priv->mm = plat->gpu->iommu.mm;
-		priv->iommu_pgshift = plat->gpu->iommu.pgshift;
-		priv->mm_mutex = &plat->gpu->iommu.mutex;
+		imem->domain = plat->gpu->iommu.domain;
+		imem->mm = plat->gpu->iommu.mm;
+		imem->iommu_pgshift = plat->gpu->iommu.pgshift;
+		imem->mm_mutex = &plat->gpu->iommu.mutex;
 
-		nv_info(priv, "using IOMMU\n");
+		nv_info(imem, "using IOMMU\n");
 	} else {
-		init_dma_attrs(&priv->attrs);
+		init_dma_attrs(&imem->attrs);
 		/*
 		 * We will access instmem through PRAMIN and thus do not need a
 		 * consistent CPU pointer or kernel mapping
 		 */
-		dma_set_attr(DMA_ATTR_NON_CONSISTENT, &priv->attrs);
-		dma_set_attr(DMA_ATTR_WEAK_ORDERING, &priv->attrs);
-		dma_set_attr(DMA_ATTR_WRITE_COMBINE, &priv->attrs);
-		dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &priv->attrs);
+		dma_set_attr(DMA_ATTR_NON_CONSISTENT, &imem->attrs);
+		dma_set_attr(DMA_ATTR_WEAK_ORDERING, &imem->attrs);
+		dma_set_attr(DMA_ATTR_WRITE_COMBINE, &imem->attrs);
+		dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &imem->attrs);
 
-		nv_info(priv, "using DMA API\n");
+		nv_info(imem, "using DMA API\n");
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
index 282143f49d72..23084f18199e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
@@ -32,30 +32,27 @@
 static u32
 nv04_instobj_rd32(struct nvkm_object *object, u64 addr)
 {
-	struct nv04_instmem_priv *priv = (void *)nvkm_instmem(object);
-	struct nv04_instobj_priv *node = (void *)object;
-	return nv_ro32(priv, node->mem->offset + addr);
+	struct nv04_instmem *imem = (void *)nvkm_instmem(object);
+	struct nv04_instobj *node = (void *)object;
+	return nv_ro32(imem, node->mem->offset + addr);
 }
 
 static void
 nv04_instobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
 {
-	struct nv04_instmem_priv *priv = (void *)nvkm_instmem(object);
-	struct nv04_instobj_priv *node = (void *)object;
-	nv_wo32(priv, node->mem->offset + addr, data);
+	struct nv04_instmem *imem = (void *)nvkm_instmem(object);
+	struct nv04_instobj *node = (void *)object;
+	nv_wo32(imem, node->mem->offset + addr, data);
 }
 
 static void
 nv04_instobj_dtor(struct nvkm_object *object)
 {
-	struct nv04_instmem_priv *priv = (void *)nvkm_instmem(object);
-	struct nv04_instobj_priv *node = (void *)object;
-	struct nvkm_subdev *subdev = (void *)priv;
-
-	mutex_lock(&subdev->mutex);
-	nvkm_mm_free(&priv->heap, &node->mem);
-	mutex_unlock(&subdev->mutex);
-
+	struct nv04_instmem *imem = (void *)nvkm_instmem(object);
+	struct nv04_instobj *node = (void *)object;
+	mutex_lock(&imem->base.subdev.mutex);
+	nvkm_mm_free(&imem->heap, &node->mem);
+	mutex_unlock(&imem->base.subdev.mutex);
 	nvkm_instobj_destroy(&node->base);
 }
 
@@ -64,10 +61,9 @@ nv04_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		  struct nvkm_oclass *oclass, void *data, u32 size,
 		  struct nvkm_object **pobject)
 {
-	struct nv04_instmem_priv *priv = (void *)nvkm_instmem(parent);
-	struct nv04_instobj_priv *node;
+	struct nv04_instmem *imem = (void *)nvkm_instmem(parent);
+	struct nv04_instobj *node;
 	struct nvkm_instobj_args *args = data;
-	struct nvkm_subdev *subdev = (void *)priv;
 	int ret;
 
 	if (!args->align)
@@ -78,10 +74,10 @@ nv04_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	if (ret)
 		return ret;
 
-	mutex_lock(&subdev->mutex);
-	ret = nvkm_mm_head(&priv->heap, 0, 1, args->size, args->size,
+	mutex_lock(&imem->base.subdev.mutex);
+	ret = nvkm_mm_head(&imem->heap, 0, 1, args->size, args->size,
 			   args->align, &node->mem);
-	mutex_unlock(&subdev->mutex);
+	mutex_unlock(&imem->base.subdev.mutex);
 	if (ret)
 		return ret;
 
@@ -121,15 +117,15 @@ nv04_instmem_wr32(struct nvkm_object *object, u64 addr, u32 data)
 void
 nv04_instmem_dtor(struct nvkm_object *object)
 {
-	struct nv04_instmem_priv *priv = (void *)object;
-	nvkm_gpuobj_ref(NULL, &priv->ramfc);
-	nvkm_gpuobj_ref(NULL, &priv->ramro);
-	nvkm_ramht_ref(NULL, &priv->ramht);
-	nvkm_gpuobj_ref(NULL, &priv->vbios);
-	nvkm_mm_fini(&priv->heap);
-	if (priv->iomem)
-		iounmap(priv->iomem);
-	nvkm_instmem_destroy(&priv->base);
+	struct nv04_instmem *imem = (void *)object;
+	nvkm_gpuobj_ref(NULL, &imem->ramfc);
+	nvkm_gpuobj_ref(NULL, &imem->ramro);
+	nvkm_ramht_ref(NULL, &imem->ramht);
+	nvkm_gpuobj_ref(NULL, &imem->vbios);
+	nvkm_mm_fini(&imem->heap);
+	if (imem->iomem)
+		iounmap(imem->iomem);
+	nvkm_instmem_destroy(&imem->base);
 }
 
 static int
@@ -137,41 +133,41 @@ nv04_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		  struct nvkm_oclass *oclass, void *data, u32 size,
 		  struct nvkm_object **pobject)
 {
-	struct nv04_instmem_priv *priv;
+	struct nv04_instmem *imem;
 	int ret;
 
-	ret = nvkm_instmem_create(parent, engine, oclass, &priv);
-	*pobject = nv_object(priv);
+	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
+	*pobject = nv_object(imem);
 	if (ret)
 		return ret;
 
 	/* PRAMIN aperture maps over the end of VRAM, reserve it */
-	priv->base.reserved = 512 * 1024;
+	imem->base.reserved = 512 * 1024;
 
-	ret = nvkm_mm_init(&priv->heap, 0, priv->base.reserved, 1);
+	ret = nvkm_mm_init(&imem->heap, 0, imem->base.reserved, 1);
 	if (ret)
 		return ret;
 
 	/* 0x00000-0x10000: reserve for probable vbios image */
-	ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
-			      &priv->vbios);
+	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x10000, 0, 0,
+			      &imem->vbios);
 	if (ret)
 		return ret;
 
 	/* 0x10000-0x18000: reserve for RAMHT */
-	ret = nvkm_ramht_new(nv_object(priv), NULL, 0x08000, 0, &priv->ramht);
+	ret = nvkm_ramht_new(nv_object(imem), NULL, 0x08000, 0, &imem->ramht);
 	if (ret)
 		return ret;
 
 	/* 0x18000-0x18800: reserve for RAMFC (enough for 32 nv30 channels) */
-	ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x00800, 0,
-			      NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
+	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x00800, 0,
+			      NVOBJ_FLAG_ZERO_ALLOC, &imem->ramfc);
 	if (ret)
 		return ret;
 
 	/* 0x18800-0x18a00: reserve for RAMRO */
-	ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x00200, 0, 0,
-			      &priv->ramro);
+	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x00200, 0, 0,
+			      &imem->ramro);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h
index 42b6c928047c..6065e34e2f0d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h
@@ -6,7 +6,7 @@
 
 extern struct nvkm_instobj_impl nv04_instobj_oclass;
 
-struct nv04_instmem_priv {
+struct nv04_instmem {
 	struct nvkm_instmem base;
 
 	void __iomem *iomem;
@@ -18,13 +18,13 @@ struct nv04_instmem_priv {
 	struct nvkm_gpuobj *ramfc;
 };
 
-static inline struct nv04_instmem_priv *
+static inline struct nv04_instmem *
 nv04_instmem(void *obj)
 {
 	return (void *)nvkm_instmem(obj);
 }
 
-struct nv04_instobj_priv {
+struct nv04_instobj {
 	struct nvkm_instobj base;
 	struct nvkm_mm_node *mem;
 };
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
index b42b8588fc0e..d6827b377bd9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
@@ -33,15 +33,15 @@
 static u32
 nv40_instmem_rd32(struct nvkm_object *object, u64 addr)
 {
-	struct nv04_instmem_priv *priv = (void *)object;
-	return ioread32_native(priv->iomem + addr);
+	struct nv04_instmem *imem = (void *)object;
+	return ioread32_native(imem->iomem + addr);
 }
 
 static void
 nv40_instmem_wr32(struct nvkm_object *object, u64 addr, u32 data)
 {
-	struct nv04_instmem_priv *priv = (void *)object;
-	iowrite32_native(data, priv->iomem + addr);
+	struct nv04_instmem *imem = (void *)object;
+	iowrite32_native(data, imem->iomem + addr);
 }
 
 static int
@@ -50,11 +50,11 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		  struct nvkm_object **pobject)
 {
 	struct nvkm_device *device = nv_device(parent);
-	struct nv04_instmem_priv *priv;
+	struct nv04_instmem *imem;
 	int ret, bar, vs;
 
-	ret = nvkm_instmem_create(parent, engine, oclass, &priv);
-	*pobject = nv_object(priv);
+	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
+	*pobject = nv_object(imem);
 	if (ret)
 		return ret;
 
@@ -64,10 +64,10 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	else
 		bar = 3;
 
-	priv->iomem = ioremap(nv_device_resource_start(device, bar),
+	imem->iomem = ioremap(nv_device_resource_start(device, bar),
 			      nv_device_resource_len(device, bar));
-	if (!priv->iomem) {
-		nv_error(priv, "unable to map PRAMIN BAR\n");
+	if (!imem->iomem) {
+		nv_error(imem, "unable to map PRAMIN BAR\n");
 		return -EFAULT;
 	}
 
@@ -75,46 +75,46 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	 * to fit graphics contexts for every channel, the magics come
 	 * from engine/gr/nv40.c
 	 */
-	vs = hweight8((nv_rd32(priv, 0x001540) & 0x0000ff00) >> 8);
-	if      (device->chipset == 0x40) priv->base.reserved = 0x6aa0 * vs;
-	else if (device->chipset  < 0x43) priv->base.reserved = 0x4f00 * vs;
-	else if (nv44_gr_class(priv))  priv->base.reserved = 0x4980 * vs;
-	else				  priv->base.reserved = 0x4a40 * vs;
-	priv->base.reserved += 16 * 1024;
-	priv->base.reserved *= 32;		/* per-channel */
-	priv->base.reserved += 512 * 1024;	/* pci(e)gart table */
-	priv->base.reserved += 512 * 1024;	/* object storage */
-
-	priv->base.reserved = round_up(priv->base.reserved, 4096);
-
-	ret = nvkm_mm_init(&priv->heap, 0, priv->base.reserved, 1);
+	vs = hweight8((nv_rd32(imem, 0x001540) & 0x0000ff00) >> 8);
+	if      (device->chipset == 0x40) imem->base.reserved = 0x6aa0 * vs;
+	else if (device->chipset  < 0x43) imem->base.reserved = 0x4f00 * vs;
+	else if (nv44_gr_class(imem))  imem->base.reserved = 0x4980 * vs;
+	else				  imem->base.reserved = 0x4a40 * vs;
+	imem->base.reserved += 16 * 1024;
+	imem->base.reserved *= 32;		/* per-channel */
+	imem->base.reserved += 512 * 1024;	/* pci(e)gart table */
+	imem->base.reserved += 512 * 1024;	/* object storage */
+
+	imem->base.reserved = round_up(imem->base.reserved, 4096);
+
+	ret = nvkm_mm_init(&imem->heap, 0, imem->base.reserved, 1);
 	if (ret)
 		return ret;
 
 	/* 0x00000-0x10000: reserve for probable vbios image */
-	ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
-			      &priv->vbios);
+	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x10000, 0, 0,
+			      &imem->vbios);
 	if (ret)
 		return ret;
 
 	/* 0x10000-0x18000: reserve for RAMHT */
-	ret = nvkm_ramht_new(nv_object(priv), NULL, 0x08000, 0, &priv->ramht);
+	ret = nvkm_ramht_new(nv_object(imem), NULL, 0x08000, 0, &imem->ramht);
 	if (ret)
 		return ret;
 
 	/* 0x18000-0x18200: reserve for RAMRO
 	 * 0x18200-0x20000: padding
 	 */
-	ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x08000, 0, 0,
-			      &priv->ramro);
+	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x08000, 0, 0,
+			      &imem->ramro);
 	if (ret)
 		return ret;
 
 	/* 0x20000-0x21000: reserve for RAMFC
 	 * 0x21000-0x40000: padding and some unknown crap
 	 */
-	ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
-			      NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
+	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x20000, 0,
+			      NVOBJ_FLAG_ZERO_ALLOC, &imem->ramfc);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
index b6c5e2d12f20..6c83c5797e32 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -25,13 +25,13 @@
 
 #include <subdev/fb.h>
 
-struct nv50_instmem_priv {
+struct nv50_instmem {
 	struct nvkm_instmem base;
 	spinlock_t lock;
 	u64 addr;
 };
 
-struct nv50_instobj_priv {
+struct nv50_instobj {
 	struct nvkm_instobj base;
 	struct nvkm_mem *mem;
 };
@@ -43,45 +43,45 @@ struct nv50_instobj_priv {
 static u32
 nv50_instobj_rd32(struct nvkm_object *object, u64 offset)
 {
-	struct nv50_instmem_priv *priv = (void *)nvkm_instmem(object);
-	struct nv50_instobj_priv *node = (void *)object;
+	struct nv50_instmem *imem = (void *)nvkm_instmem(object);
+	struct nv50_instobj *node = (void *)object;
 	unsigned long flags;
 	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
 	u32 data;
 
-	spin_lock_irqsave(&priv->lock, flags);
-	if (unlikely(priv->addr != base)) {
-		nv_wr32(priv, 0x001700, base >> 16);
-		priv->addr = base;
+	spin_lock_irqsave(&imem->lock, flags);
+	if (unlikely(imem->addr != base)) {
+		nv_wr32(imem, 0x001700, base >> 16);
+		imem->addr = base;
 	}
-	data = nv_rd32(priv, 0x700000 + addr);
-	spin_unlock_irqrestore(&priv->lock, flags);
+	data = nv_rd32(imem, 0x700000 + addr);
+	spin_unlock_irqrestore(&imem->lock, flags);
 	return data;
 }
 
 static void
 nv50_instobj_wr32(struct nvkm_object *object, u64 offset, u32 data)
 {
-	struct nv50_instmem_priv *priv = (void *)nvkm_instmem(object);
-	struct nv50_instobj_priv *node = (void *)object;
+	struct nv50_instmem *imem = (void *)nvkm_instmem(object);
+	struct nv50_instobj *node = (void *)object;
 	unsigned long flags;
 	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
 
-	spin_lock_irqsave(&priv->lock, flags);
-	if (unlikely(priv->addr != base)) {
-		nv_wr32(priv, 0x001700, base >> 16);
-		priv->addr = base;
+	spin_lock_irqsave(&imem->lock, flags);
+	if (unlikely(imem->addr != base)) {
+		nv_wr32(imem, 0x001700, base >> 16);
+		imem->addr = base;
 	}
-	nv_wr32(priv, 0x700000 + addr, data);
-	spin_unlock_irqrestore(&priv->lock, flags);
+	nv_wr32(imem, 0x700000 + addr, data);
+	spin_unlock_irqrestore(&imem->lock, flags);
 }
 
 static void
 nv50_instobj_dtor(struct nvkm_object *object)
 {
-	struct nv50_instobj_priv *node = (void *)object;
+	struct nv50_instobj *node = (void *)object;
 	struct nvkm_fb *fb = nvkm_fb(object);
 	fb->ram->put(fb, &node->mem);
 	nvkm_instobj_destroy(&node->base);
@@ -94,7 +94,7 @@ nv50_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 {
 	struct nvkm_fb *fb = nvkm_fb(parent);
 	struct nvkm_instobj_args *args = data;
-	struct nv50_instobj_priv *node;
+	struct nv50_instobj *node;
 	int ret;
 
 	args->size  = max((args->size  + 4095) & ~4095, (u32)4096);
@@ -134,9 +134,9 @@ nv50_instobj_oclass = {
 static int
 nv50_instmem_fini(struct nvkm_object *object, bool suspend)
 {
-	struct nv50_instmem_priv *priv = (void *)object;
-	priv->addr = ~0ULL;
-	return nvkm_instmem_fini(&priv->base, suspend);
+	struct nv50_instmem *imem = (void *)object;
+	imem->addr = ~0ULL;
+	return nvkm_instmem_fini(&imem->base, suspend);
 }
 
 static int
@@ -144,15 +144,15 @@ nv50_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		  struct nvkm_oclass *oclass, void *data, u32 size,
 		  struct nvkm_object **pobject)
 {
-	struct nv50_instmem_priv *priv;
+	struct nv50_instmem *imem;
 	int ret;
 
-	ret = nvkm_instmem_create(parent, engine, oclass, &priv);
-	*pobject = nv_object(priv);
+	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
+	*pobject = nv_object(imem);
 	if (ret)
 		return ret;
 
-	spin_lock_init(&priv->lock);
+	spin_lock_init(&imem->lock);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
index b10e292e5607..e217ebebd325 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
@@ -36,14 +36,14 @@ struct nvkm_instmem_impl {
 #define nvkm_instmem_create(p,e,o,d)                                        \
 	nvkm_instmem_create_((p), (e), (o), sizeof(**d), (void **)d)
 #define nvkm_instmem_destroy(p)                                             \
-	nvkm_subdev_destroy(&(p)->base)
+	nvkm_subdev_destroy(&(p)->subdev)
 #define nvkm_instmem_init(p) ({                                             \
-	struct nvkm_instmem *imem = (p);                                    \
-	_nvkm_instmem_init(nv_object(imem));                                \
+	struct nvkm_instmem *_imem = (p);                                    \
+	_nvkm_instmem_init(nv_object(_imem));                                \
 })
 #define nvkm_instmem_fini(p,s) ({                                           \
-	struct nvkm_instmem *imem = (p);                                    \
-	_nvkm_instmem_fini(nv_object(imem), (s));                           \
+	struct nvkm_instmem *_imem = (p);                                    \
+	_nvkm_instmem_fini(nv_object(_imem), (s));                           \
 })
 
 int nvkm_instmem_create_(struct nvkm_object *, struct nvkm_object *,
-- 
cgit v1.2.3-70-g09d2


From d5c5bcf693e7c72f2f853066858f3d40a42ba942 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 14:54:09 +1000
Subject: drm/nouveau/imem: switch to device pri macros

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 10 ++++++----
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c  |  6 ++++--
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c  |  2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c  | 10 ++++++----
 4 files changed, 17 insertions(+), 11 deletions(-)

(limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c')

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index abc41c0a4ad8..e2e400e35bc8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -107,6 +107,7 @@ gk20a_instobj_rd32(struct nvkm_object *object, u64 offset)
 {
 	struct gk20a_instmem *imem = (void *)nvkm_instmem(object);
 	struct gk20a_instobj *node = (void *)object;
+	struct nvkm_device *device = imem->base.subdev.device;
 	unsigned long flags;
 	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
@@ -114,10 +115,10 @@ gk20a_instobj_rd32(struct nvkm_object *object, u64 offset)
 
 	spin_lock_irqsave(&imem->lock, flags);
 	if (unlikely(imem->addr != base)) {
-		nv_wr32(imem, 0x001700, base >> 16);
+		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
-	data = nv_rd32(imem, 0x700000 + addr);
+	data = nvkm_rd32(device, 0x700000 + addr);
 	spin_unlock_irqrestore(&imem->lock, flags);
 	return data;
 }
@@ -127,16 +128,17 @@ gk20a_instobj_wr32(struct nvkm_object *object, u64 offset, u32 data)
 {
 	struct gk20a_instmem *imem = (void *)nvkm_instmem(object);
 	struct gk20a_instobj *node = (void *)object;
+	struct nvkm_device *device = imem->base.subdev.device;
 	unsigned long flags;
 	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
 
 	spin_lock_irqsave(&imem->lock, flags);
 	if (unlikely(imem->addr != base)) {
-		nv_wr32(imem, 0x001700, base >> 16);
+		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
-	nv_wr32(imem, 0x700000 + addr, data);
+	nvkm_wr32(device, 0x700000 + addr, data);
 	spin_unlock_irqrestore(&imem->lock, flags);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
index 23084f18199e..6410cc1fd419 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
@@ -105,13 +105,15 @@ nv04_instobj_oclass = {
 static u32
 nv04_instmem_rd32(struct nvkm_object *object, u64 addr)
 {
-	return nv_rd32(object, 0x700000 + addr);
+	struct nvkm_instmem *imem = (void *)object;
+	return nvkm_rd32(imem->subdev.device, 0x700000 + addr);
 }
 
 static void
 nv04_instmem_wr32(struct nvkm_object *object, u64 addr, u32 data)
 {
-	return nv_wr32(object, 0x700000 + addr, data);
+	struct nvkm_instmem *imem = (void *)object;
+	nvkm_wr32(imem->subdev.device, 0x700000 + addr, data);
 }
 
 void
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
index d6827b377bd9..fe00881bda65 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
@@ -75,7 +75,7 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	 * to fit graphics contexts for every channel, the magics come
 	 * from engine/gr/nv40.c
 	 */
-	vs = hweight8((nv_rd32(imem, 0x001540) & 0x0000ff00) >> 8);
+	vs = hweight8((nvkm_rd32(device, 0x001540) & 0x0000ff00) >> 8);
 	if      (device->chipset == 0x40) imem->base.reserved = 0x6aa0 * vs;
 	else if (device->chipset  < 0x43) imem->base.reserved = 0x4f00 * vs;
 	else if (nv44_gr_class(imem))  imem->base.reserved = 0x4980 * vs;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
index 6c83c5797e32..339dd19e0e45 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -45,6 +45,7 @@ nv50_instobj_rd32(struct nvkm_object *object, u64 offset)
 {
 	struct nv50_instmem *imem = (void *)nvkm_instmem(object);
 	struct nv50_instobj *node = (void *)object;
+	struct nvkm_device *device = imem->base.subdev.device;
 	unsigned long flags;
 	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
@@ -52,10 +53,10 @@ nv50_instobj_rd32(struct nvkm_object *object, u64 offset)
 
 	spin_lock_irqsave(&imem->lock, flags);
 	if (unlikely(imem->addr != base)) {
-		nv_wr32(imem, 0x001700, base >> 16);
+		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
-	data = nv_rd32(imem, 0x700000 + addr);
+	data = nvkm_rd32(device, 0x700000 + addr);
 	spin_unlock_irqrestore(&imem->lock, flags);
 	return data;
 }
@@ -65,16 +66,17 @@ nv50_instobj_wr32(struct nvkm_object *object, u64 offset, u32 data)
 {
 	struct nv50_instmem *imem = (void *)nvkm_instmem(object);
 	struct nv50_instobj *node = (void *)object;
+	struct nvkm_device *device = imem->base.subdev.device;
 	unsigned long flags;
 	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
 
 	spin_lock_irqsave(&imem->lock, flags);
 	if (unlikely(imem->addr != base)) {
-		nv_wr32(imem, 0x001700, base >> 16);
+		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
-	nv_wr32(imem, 0x700000 + addr, data);
+	nvkm_wr32(device, 0x700000 + addr, data);
 	spin_unlock_irqrestore(&imem->lock, flags);
 }
 
-- 
cgit v1.2.3-70-g09d2


From 00c5550710184bad189d2cfe6b1880c0e9331bae Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 14:54:12 +1000
Subject: drm/nouveau/imem: switch to subdev printk macros

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c    | 26 +++++++++++++---------
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c |  4 ++--
 2 files changed, 17 insertions(+), 13 deletions(-)

(limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c')

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index e2e400e35bc8..f5642698406a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -207,6 +207,7 @@ gk20a_instobj_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 {
 	struct gk20a_instobj_dma *node;
 	struct gk20a_instmem *imem = (void *)nvkm_instmem(parent);
+	struct nvkm_subdev *subdev = &imem->base.subdev;
 	struct device *dev = nv_device_base(nv_device(parent));
 	int ret;
 
@@ -220,14 +221,15 @@ gk20a_instobj_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 					&node->handle, GFP_KERNEL,
 					&imem->attrs);
 	if (!node->cpuaddr) {
-		nv_error(imem, "cannot allocate DMA memory\n");
+		nvkm_error(subdev, "cannot allocate DMA memory\n");
 		return -ENOMEM;
 	}
 
 	/* alignment check */
 	if (unlikely(node->handle & (align - 1)))
-		nv_warn(imem, "memory not aligned as requested: %pad (0x%x)\n",
-			&node->handle, align);
+		nvkm_warn(subdev,
+			  "memory not aligned as requested: %pad (0x%x)\n",
+			  &node->handle, align);
 
 	/* present memory for being mapped using small pages */
 	node->r.type = 12;
@@ -249,6 +251,7 @@ gk20a_instobj_ctor_iommu(struct nvkm_object *parent, struct nvkm_object *engine,
 {
 	struct gk20a_instobj_iommu *node;
 	struct gk20a_instmem *imem = (void *)nvkm_instmem(parent);
+	struct nvkm_subdev *subdev = &imem->base.subdev;
 	struct nvkm_mm_node *r;
 	int ret;
 	int i;
@@ -277,7 +280,7 @@ gk20a_instobj_ctor_iommu(struct nvkm_object *parent, struct nvkm_object *engine,
 			   align >> imem->iommu_pgshift, &r);
 	mutex_unlock(imem->mm_mutex);
 	if (ret) {
-		nv_error(imem, "virtual space is full!\n");
+		nvkm_error(subdev, "virtual space is full!\n");
 		goto free_pages;
 	}
 
@@ -289,7 +292,7 @@ gk20a_instobj_ctor_iommu(struct nvkm_object *parent, struct nvkm_object *engine,
 		ret = iommu_map(imem->domain, offset, page_to_phys(p),
 				PAGE_SIZE, IOMMU_READ | IOMMU_WRITE);
 		if (ret < 0) {
-			nv_error(imem, "IOMMU mapping failure: %d\n", ret);
+			nvkm_error(subdev, "IOMMU mapping failure: %d\n", ret);
 
 			while (i-- > 0) {
 				offset -= PAGE_SIZE;
@@ -329,11 +332,12 @@ gk20a_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	struct nvkm_instobj_args *args = data;
 	struct gk20a_instmem *imem = (void *)nvkm_instmem(parent);
 	struct gk20a_instobj *node;
+	struct nvkm_subdev *subdev = &imem->base.subdev;
 	u32 size, align;
 	int ret;
 
-	nv_debug(parent, "%s (%s): size: %x align: %x\n", __func__,
-		 imem->domain ? "IOMMU" : "DMA", args->size, args->align);
+	nvkm_debug(subdev, "%s (%s): size: %x align: %x\n", __func__,
+		   imem->domain ? "IOMMU" : "DMA", args->size, args->align);
 
 	/* Round size and align to page bounds */
 	size = max(roundup(args->size, PAGE_SIZE), PAGE_SIZE);
@@ -359,8 +363,8 @@ gk20a_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	node->base.addr = node->mem->offset;
 	node->base.size = size;
 
-	nv_debug(parent, "alloc size: 0x%x, align: 0x%x, gaddr: 0x%llx\n",
-		 size, align, node->mem->offset);
+	nvkm_debug(subdev, "alloc size: 0x%x, align: 0x%x, gaddr: 0x%llx\n",
+		   size, align, node->mem->offset);
 
 	return 0;
 }
@@ -410,7 +414,7 @@ gk20a_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		imem->iommu_pgshift = plat->gpu->iommu.pgshift;
 		imem->mm_mutex = &plat->gpu->iommu.mutex;
 
-		nv_info(imem, "using IOMMU\n");
+		nvkm_info(&imem->base.subdev, "using IOMMU\n");
 	} else {
 		init_dma_attrs(&imem->attrs);
 		/*
@@ -422,7 +426,7 @@ gk20a_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		dma_set_attr(DMA_ATTR_WRITE_COMBINE, &imem->attrs);
 		dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &imem->attrs);
 
-		nv_info(imem, "using DMA API\n");
+		nvkm_info(&imem->base.subdev, "using DMA API\n");
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
index fe00881bda65..c194a28b7971 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
@@ -49,7 +49,7 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		  struct nvkm_oclass *oclass, void *data, u32 size,
 		  struct nvkm_object **pobject)
 {
-	struct nvkm_device *device = nv_device(parent);
+	struct nvkm_device *device = (void *)parent;
 	struct nv04_instmem *imem;
 	int ret, bar, vs;
 
@@ -67,7 +67,7 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	imem->iomem = ioremap(nv_device_resource_start(device, bar),
 			      nv_device_resource_len(device, bar));
 	if (!imem->iomem) {
-		nv_error(imem, "unable to map PRAMIN BAR\n");
+		nvkm_error(&imem->base.subdev, "unable to map PRAMIN BAR\n");
 		return -EFAULT;
 	}
 
-- 
cgit v1.2.3-70-g09d2


From 47b2505efb2d951f16c3a229d93450b463d925e5 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 14:54:15 +1000
Subject: drm/nouveau/platform: remove subclassing of nvkm_device

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/include/nvkm/core/device.h  |  2 ++
 drivers/gpu/drm/nouveau/nouveau_drm.c               | 14 +++++++-------
 drivers/gpu/drm/nouveau/nouveau_drm.h               |  5 +----
 drivers/gpu/drm/nouveau/nouveau_platform.c          |  6 +++---
 drivers/gpu/drm/nouveau/nouveau_platform.h          | 10 ----------
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c     |  5 ++---
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c | 13 ++++++-------
 drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c    | 10 ++++------
 8 files changed, 25 insertions(+), 40 deletions(-)

(limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c')

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
index ffff6fd5a348..d48e5006e14e 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
@@ -144,6 +144,8 @@ struct nvkm_device {
 	struct nvkm_sw *sw;
 	struct nvkm_engine *vic;
 	struct nvkm_engine *vp;
+
+	struct nouveau_platform_gpu *gpu;
 };
 
 struct nvkm_device *nvkm_device_find(u64 name);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 4e6c1803fd37..9e420f6c1a74 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -1056,16 +1056,16 @@ nouveau_drm_pci_driver = {
 };
 
 struct drm_device *
-nouveau_platform_device_create_(struct platform_device *pdev, int size,
-				void **pobject)
+nouveau_platform_device_create(struct platform_device *pdev,
+			       struct nvkm_device **pdevice)
 {
 	struct drm_device *drm;
 	int err;
 
-	err = nvkm_device_create_(pdev, NVKM_BUS_PLATFORM,
-				  nouveau_platform_name(pdev),
-				  dev_name(&pdev->dev), nouveau_config,
-				  nouveau_debug, size, pobject);
+	err = nvkm_device_create(pdev, NVKM_BUS_PLATFORM,
+				 nouveau_platform_name(pdev),
+				 dev_name(&pdev->dev), nouveau_config,
+				 nouveau_debug, pdevice);
 	if (err)
 		return ERR_PTR(err);
 
@@ -1085,7 +1085,7 @@ nouveau_platform_device_create_(struct platform_device *pdev, int size,
 	return drm;
 
 err_free:
-	nvkm_object_ref(NULL, (struct nvkm_object **)pobject);
+	nvkm_object_ref(NULL, (struct nvkm_object **)pdevice);
 
 	return ERR_PTR(err);
 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
index 81ef59272ed2..d1a4c120b71b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -182,11 +182,8 @@ nouveau_drm(struct drm_device *dev)
 int nouveau_pmops_suspend(struct device *);
 int nouveau_pmops_resume(struct device *);
 
-#define nouveau_platform_device_create(p, u)                                   \
-	nouveau_platform_device_create_(p, sizeof(**u), (void **)u)
 struct drm_device *
-nouveau_platform_device_create_(struct platform_device *pdev,
-				int size, void **pobject);
+nouveau_platform_device_create(struct platform_device *, struct nvkm_device **);
 void nouveau_drm_device_remove(struct drm_device *dev);
 
 #define NV_PRINTK(l,c,f,a...) do {                                             \
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c
index 7a39d449fefa..c03736bce953 100644
--- a/drivers/gpu/drm/nouveau/nouveau_platform.c
+++ b/drivers/gpu/drm/nouveau/nouveau_platform.c
@@ -177,7 +177,7 @@ static void nouveau_platform_remove_iommu(struct device *dev,
 static int nouveau_platform_probe(struct platform_device *pdev)
 {
 	struct nouveau_platform_gpu *gpu;
-	struct nouveau_platform_device *device;
+	struct nvkm_device *device;
 	struct drm_device *drm;
 	int err;
 
@@ -214,7 +214,7 @@ static int nouveau_platform_probe(struct platform_device *pdev)
 	}
 
 	device->gpu = gpu;
-	device->gpu_speedo = tegra_sku_info.gpu_speedo_value;
+	gpu->gpu_speedo = tegra_sku_info.gpu_speedo_value;
 
 	err = drm_dev_register(drm, 0);
 	if (err < 0)
@@ -237,7 +237,7 @@ static int nouveau_platform_remove(struct platform_device *pdev)
 	struct drm_device *drm_dev = platform_get_drvdata(pdev);
 	struct nouveau_drm *drm = nouveau_drm(drm_dev);
 	struct nvkm_device *device = nvxx_device(&drm->device);
-	struct nouveau_platform_gpu *gpu = nv_device_to_platform(device)->gpu;
+	struct nouveau_platform_gpu *gpu = device->gpu;
 	int err;
 
 	nouveau_drm_device_remove(drm_dev);
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.h b/drivers/gpu/drm/nouveau/nouveau_platform.h
index 392874cf4725..7a4020f31cc5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_platform.h
+++ b/drivers/gpu/drm/nouveau/nouveau_platform.h
@@ -54,19 +54,9 @@ struct nouveau_platform_gpu {
 		struct iommu_domain *domain;
 		unsigned long pgshift;
 	} iommu;
-};
-
-struct nouveau_platform_device {
-	struct nvkm_device device;
-
-	struct nouveau_platform_gpu *gpu;
 
 	int gpu_speedo;
 };
 
-#define nv_device_to_platform(d)                                               \
-	container_of(d, struct nouveau_platform_device, device)
-
 extern struct platform_driver nouveau_platform_driver;
-
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c
index 2d10dc17238d..ce89955ff8f9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c
@@ -650,8 +650,8 @@ gk20a_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
 	       struct nvkm_object **pobject)
 {
+	struct nvkm_device *device = (void *)parent;
 	struct gk20a_clk *clk;
-	struct nouveau_platform_device *plat;
 	int ret;
 	int i;
 
@@ -670,8 +670,7 @@ gk20a_clk_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	clk->params = &gk20a_pllg_params;
 
-	plat = nv_device_to_platform(nv_device(parent));
-	clk->parent_rate = clk_get_rate(plat->gpu->clk);
+	clk->parent_rate = clk_get_rate(device->gpu->clk);
 	nvkm_info(&clk->base.subdev, "parent clock rate: %d Mhz\n",
 		  clk->parent_rate / MHZ);
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index f5642698406a..e6370382109b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -396,8 +396,8 @@ gk20a_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		   struct nvkm_oclass *oclass, void *data, u32 size,
 		   struct nvkm_object **pobject)
 {
+	struct nvkm_device *device = (void *)parent;
 	struct gk20a_instmem *imem;
-	struct nouveau_platform_device *plat;
 	int ret;
 
 	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
@@ -407,12 +407,11 @@ gk20a_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	spin_lock_init(&imem->lock);
 
-	plat = nv_device_to_platform(nv_device(parent));
-	if (plat->gpu->iommu.domain) {
-		imem->domain = plat->gpu->iommu.domain;
-		imem->mm = plat->gpu->iommu.mm;
-		imem->iommu_pgshift = plat->gpu->iommu.pgshift;
-		imem->mm_mutex = &plat->gpu->iommu.mutex;
+	if (device->gpu->iommu.domain) {
+		imem->domain = device->gpu->iommu.domain;
+		imem->mm = device->gpu->iommu.mm;
+		imem->iommu_pgshift = device->gpu->iommu.pgshift;
+		imem->mm_mutex = &device->gpu->iommu.mutex;
 
 		nvkm_info(&imem->base.subdev, "using IOMMU\n");
 	} else {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c
index d86f4eaba04c..59fa2cf898d2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c
@@ -152,8 +152,8 @@ gk20a_volt_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		struct nvkm_oclass *oclass, void *data, u32 size,
 		struct nvkm_object **pobject)
 {
+	struct nvkm_device *device = (void *)parent;
 	struct gk20a_volt *volt;
-	struct nouveau_platform_device *plat;
 	int i, ret, uv;
 
 	ret = nvkm_volt_create(parent, engine, oclass, &volt);
@@ -161,12 +161,10 @@ gk20a_volt_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	if (ret)
 		return ret;
 
-	plat = nv_device_to_platform(nv_device(parent));
-
-	uv = regulator_get_voltage(plat->gpu->vdd);
+	uv = regulator_get_voltage(device->gpu->vdd);
 	nvkm_info(&volt->base.subdev, "The default voltage is %duV\n", uv);
 
-	volt->vdd = plat->gpu->vdd;
+	volt->vdd = device->gpu->vdd;
 	volt->base.vid_get = gk20a_volt_vid_get;
 	volt->base.vid_set = gk20a_volt_vid_set;
 	volt->base.set_id = gk20a_volt_set_id;
@@ -178,7 +176,7 @@ gk20a_volt_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		volt->base.vid[i].vid = i;
 		volt->base.vid[i].uv =
 			gk20a_volt_calc_voltage(&gk20a_cvb_coef[i],
-						plat->gpu_speedo);
+						device->gpu->gpu_speedo);
 		nvkm_debug(&volt->base.subdev, "%2d: vid=%d, uv=%d\n", i,
 			   volt->base.vid[i].vid, volt->base.vid[i].uv);
 	}
-- 
cgit v1.2.3-70-g09d2


From d8e83994aaf6749b7124a219f5b46bd1329e2a08 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 14:54:17 +1000
Subject: drm/nouveau/imem: improve management of instance memory

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h |  33 +--
 drivers/gpu/drm/nouveau/include/nvkm/core/memory.h |  53 +++++
 drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h  |   9 +-
 .../gpu/drm/nouveau/include/nvkm/subdev/instmem.h  |  27 +--
 drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h  |   1 +
 drivers/gpu/drm/nouveau/nouveau_bo.c               |   6 +-
 drivers/gpu/drm/nouveau/nvkm/core/Kbuild           |   1 +
 drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c         | 133 ++++++-----
 drivers/gpu/drm/nouveau/nvkm/core/memory.c         |  64 ++++++
 drivers/gpu/drm/nouveau/nvkm/core/ramht.c          |   8 -
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c     |   9 -
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c   |   9 -
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c   |   9 -
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c    |   5 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c    |   5 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c    |   5 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c    |   5 +-
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c    |  11 -
 drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c  |   4 -
 drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c    |   3 -
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c     |  90 --------
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c    |  43 +---
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c     |  32 +--
 drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h     |   3 -
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 244 ++++++++++++++++-----
 .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c    | 214 ++++++++++--------
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c | 160 ++++++++------
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h |  36 ---
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c | 146 +++++++++++-
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 198 ++++++++++++-----
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h |  31 +--
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c     |  19 ++
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c    |   4 -
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c     |   4 -
 34 files changed, 968 insertions(+), 656 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/include/nvkm/core/memory.h
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/core/memory.c
 delete mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h

(limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c')

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
index 2260aef3ec3e..4e4a9964d235 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
@@ -1,6 +1,7 @@
 #ifndef __NVKM_GPUOBJ_H__
 #define __NVKM_GPUOBJ_H__
 #include <core/object.h>
+#include <core/memory.h>
 #include <core/mm.h>
 struct nvkm_vma;
 struct nvkm_vm;
@@ -11,13 +12,23 @@ struct nvkm_vm;
 
 struct nvkm_gpuobj {
 	struct nvkm_object object;
-	struct nvkm_object *parent;
+	struct nvkm_memory *memory;
+	struct nvkm_gpuobj *parent;
 	struct nvkm_mm_node *node;
 	struct nvkm_mm heap;
 
 	u32 flags;
 	u64 addr;
 	u32 size;
+
+	const struct nvkm_gpuobj_func *func;
+};
+
+struct nvkm_gpuobj_func {
+	void (*acquire)(struct nvkm_gpuobj *);
+	void (*release)(struct nvkm_gpuobj *);
+	u32 (*rd32)(struct nvkm_gpuobj *, u32 offset);
+	void (*wr32)(struct nvkm_gpuobj *, u32 offset, u32 data);
 };
 
 static inline struct nvkm_gpuobj *
@@ -60,24 +71,4 @@ int  _nvkm_gpuobj_init(struct nvkm_object *);
 int  _nvkm_gpuobj_fini(struct nvkm_object *, bool);
 u32  _nvkm_gpuobj_rd32(struct nvkm_object *, u64);
 void _nvkm_gpuobj_wr32(struct nvkm_object *, u64, u32);
-
-/* accessor macros - kmap()/done() must bracket use of the other accessor
- * macros to guarantee correct behaviour across all chipsets
- */
-#define nvkm_kmap(o) do {                                                      \
-	struct nvkm_gpuobj *_gpuobj = (o);                                     \
-	(void)_gpuobj;                                                         \
-} while(0)
-#define nvkm_ro32(o,a) ({                                                      \
-	u32 _data;                                                             \
-	nvkm_object_rd32(&(o)->object, (a), &_data);                           \
-	_data;                                                                 \
-})
-#define nvkm_wo32(o,a,d) nvkm_object_wr32(&(o)->object, (a), (d))
-#define nvkm_mo32(o,a,m,d) ({                                                  \
-	u32 _addr = (a), _data = nvkm_ro32((o), _addr);                        \
-	nvkm_wo32((o), _addr, (_data & ~(m)) | (d));                           \
-	_data;                                                                 \
-})
-#define nvkm_done(o) nvkm_kmap(o)
 #endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h
new file mode 100644
index 000000000000..9363b839a9da
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/memory.h
@@ -0,0 +1,53 @@
+#ifndef __NVKM_MEMORY_H__
+#define __NVKM_MEMORY_H__
+#include <core/os.h>
+struct nvkm_device;
+struct nvkm_vma;
+struct nvkm_vm;
+
+enum nvkm_memory_target {
+	NVKM_MEM_TARGET_INST,
+	NVKM_MEM_TARGET_VRAM,
+	NVKM_MEM_TARGET_HOST,
+};
+
+struct nvkm_memory {
+	const struct nvkm_memory_func *func;
+};
+
+struct nvkm_memory_func {
+	void *(*dtor)(struct nvkm_memory *);
+	enum nvkm_memory_target (*target)(struct nvkm_memory *);
+	u64 (*addr)(struct nvkm_memory *);
+	u64 (*size)(struct nvkm_memory *);
+	void (*boot)(struct nvkm_memory *, struct nvkm_vm *);
+	void __iomem *(*acquire)(struct nvkm_memory *);
+	void (*release)(struct nvkm_memory *);
+	u32 (*rd32)(struct nvkm_memory *, u64 offset);
+	void (*wr32)(struct nvkm_memory *, u64 offset, u32 data);
+	void (*map)(struct nvkm_memory *, struct nvkm_vma *, u64 offset);
+};
+
+void nvkm_memory_ctor(const struct nvkm_memory_func *, struct nvkm_memory *);
+int nvkm_memory_new(struct nvkm_device *, enum nvkm_memory_target,
+		    u64 size, u32 align, bool zero, struct nvkm_memory **);
+void nvkm_memory_del(struct nvkm_memory **);
+#define nvkm_memory_target(p) (p)->func->target(p)
+#define nvkm_memory_addr(p) (p)->func->addr(p)
+#define nvkm_memory_size(p) (p)->func->size(p)
+#define nvkm_memory_boot(p,v) (p)->func->boot((p),(v))
+#define nvkm_memory_map(p,v,o) (p)->func->map((p),(v),(o))
+
+/* accessor macros - kmap()/done() must bracket use of the other accessor
+ * macros to guarantee correct behaviour across all chipsets
+ */
+#define nvkm_kmap(o)     (o)->func->acquire(o)
+#define nvkm_ro32(o,a)   (o)->func->rd32((o), (a))
+#define nvkm_wo32(o,a,d) (o)->func->wr32((o), (a), (d))
+#define nvkm_mo32(o,a,m,d) ({                                                  \
+	u32 _addr = (a), _data = nvkm_ro32((o), _addr);                        \
+	nvkm_wo32((o), _addr, (_data & ~(m)) | (d));                           \
+	_data;                                                                 \
+})
+#define nvkm_done(o)     (o)->func->release(o)
+#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
index 753b7e953035..1eaf7de79d50 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bar.h
@@ -7,13 +7,8 @@ struct nvkm_vma;
 struct nvkm_bar {
 	struct nvkm_subdev subdev;
 
-	int  (*alloc)(struct nvkm_bar *, struct nvkm_object *,
-		      struct nvkm_mem *, struct nvkm_object **);
-
-	int  (*kmap)(struct nvkm_bar *, struct nvkm_mem *, u32 flags,
-		     struct nvkm_vma *);
-	int  (*umap)(struct nvkm_bar *, struct nvkm_mem *, u32 flags,
-		     struct nvkm_vma *);
+	struct nvkm_vm *(*kmap)(struct nvkm_bar *);
+	int  (*umap)(struct nvkm_bar *, u64 size, int type, struct nvkm_vma *);
 	void (*unmap)(struct nvkm_bar *, struct nvkm_vma *);
 	void (*flush)(struct nvkm_bar *);
 
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
index 7ba3ff27e89e..2e9e6f058dc0 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
@@ -1,33 +1,22 @@
 #ifndef __NVKM_INSTMEM_H__
 #define __NVKM_INSTMEM_H__
 #include <core/subdev.h>
-
-struct nvkm_instobj {
-	struct nvkm_object object;
-	struct list_head head;
-	u32 *suspend;
-	u64 addr;
-	u32 size;
-};
-
-static inline struct nvkm_instobj *
-nv_memobj(void *obj)
-{
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
-	BUG_ON(!nv_iclass(obj, NV_MEMOBJ_CLASS));
-#endif
-	return obj;
-}
+struct nvkm_memory;
 
 struct nvkm_instmem {
 	struct nvkm_subdev subdev;
 	struct list_head list;
 
 	u32 reserved;
-	int (*alloc)(struct nvkm_instmem *, struct nvkm_object *,
-		     u32 size, u32 align, struct nvkm_object **);
+	int (*alloc)(struct nvkm_instmem *, u32 size, u32 align, bool zero,
+		     struct nvkm_memory **);
 
 	const struct nvkm_instmem_func *func;
+
+	struct nvkm_gpuobj *vbios;
+	struct nvkm_ramht  *ramht;
+	struct nvkm_gpuobj *ramro;
+	struct nvkm_gpuobj *ramfc;
 };
 
 struct nvkm_instmem_func {
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
index 0991c9011dc1..677f6c0cbb9b 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h
@@ -97,6 +97,7 @@ int  nvkm_vm_create(struct nvkm_mmu *, u64 offset, u64 length, u64 mm_offset,
 int  nvkm_vm_new(struct nvkm_device *, u64 offset, u64 length, u64 mm_offset,
 		 struct lock_class_key *, struct nvkm_vm **);
 int  nvkm_vm_ref(struct nvkm_vm *, struct nvkm_vm **, struct nvkm_gpuobj *pgd);
+int  nvkm_vm_boot(struct nvkm_vm *, u64 size);
 int  nvkm_vm_get(struct nvkm_vm *, u64 size, u32 page_shift, u32 access,
 		 struct nvkm_vma *);
 void nvkm_vm_put(struct nvkm_vma *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 496c00d585cd..982c0ed163eb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1388,12 +1388,16 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
 		mem->bus.is_iomem = true;
 		if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
 			struct nvkm_bar *bar = nvxx_bar(&drm->device);
+			int page_shift = 12;
+			if (drm->device.info.family >= NV_DEVICE_INFO_V0_FERMI)
+				page_shift = node->page_shift;
 
-			ret = bar->umap(bar, node, NV_MEM_ACCESS_RW,
+			ret = bar->umap(bar, node->size << 12, page_shift,
 					&node->bar_vma);
 			if (ret)
 				return ret;
 
+			nvkm_vm_map(&node->bar_vma, node);
 			mem->bus.offset = node->bar_vma.offset;
 		}
 		break;
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/Kbuild b/drivers/gpu/drm/nouveau/nvkm/core/Kbuild
index c4198164bc59..98cf39f732c1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/core/Kbuild
@@ -6,6 +6,7 @@ nvkm-y += nvkm/core/event.o
 nvkm-y += nvkm/core/gpuobj.o
 nvkm-y += nvkm/core/handle.o
 nvkm-y += nvkm/core/ioctl.o
+nvkm-y += nvkm/core/memory.o
 nvkm-y += nvkm/core/mm.o
 nvkm-y += nvkm/core/namedb.o
 nvkm-y += nvkm/core/notify.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
index bc4b3c2d075e..037036069839 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
@@ -28,6 +28,44 @@
 #include <subdev/bar.h>
 #include <subdev/mmu.h>
 
+static void
+nvkm_gpuobj_release(struct nvkm_gpuobj *gpuobj)
+{
+	if (gpuobj->node) {
+		nvkm_done(gpuobj->parent);
+		return;
+	}
+	nvkm_done(gpuobj->memory);
+}
+
+static void
+nvkm_gpuobj_acquire(struct nvkm_gpuobj *gpuobj)
+{
+	if (gpuobj->node) {
+		nvkm_kmap(gpuobj->parent);
+		return;
+	}
+	nvkm_kmap(gpuobj->memory);
+}
+
+static u32
+nvkm_gpuobj_rd32(struct nvkm_gpuobj *gpuobj, u32 offset)
+{
+	if (gpuobj->node)
+		return nvkm_ro32(gpuobj->parent, gpuobj->node->offset + offset);
+	return nvkm_ro32(gpuobj->memory, offset);
+}
+
+static void
+nvkm_gpuobj_wr32(struct nvkm_gpuobj *gpuobj, u32 offset, u32 data)
+{
+	if (gpuobj->node) {
+		nvkm_wo32(gpuobj->parent, gpuobj->node->offset + offset, data);
+		return;
+	}
+	nvkm_wo32(gpuobj->memory, offset, data);
+}
+
 void
 nvkm_gpuobj_destroy(struct nvkm_gpuobj *gpuobj)
 {
@@ -46,17 +84,27 @@ nvkm_gpuobj_destroy(struct nvkm_gpuobj *gpuobj)
 	if (gpuobj->heap.block_size)
 		nvkm_mm_fini(&gpuobj->heap);
 
+	nvkm_memory_del(&gpuobj->memory);
 	nvkm_object_destroy(&gpuobj->object);
 }
 
+static const struct nvkm_gpuobj_func
+nvkm_gpuobj_func = {
+	.acquire = nvkm_gpuobj_acquire,
+	.release = nvkm_gpuobj_release,
+	.rd32 = nvkm_gpuobj_rd32,
+	.wr32 = nvkm_gpuobj_wr32,
+};
+
 int
 nvkm_gpuobj_create_(struct nvkm_object *parent, struct nvkm_object *engine,
 		    struct nvkm_oclass *oclass, u32 pclass,
-		    struct nvkm_object *pargpu, u32 size, u32 align, u32 flags,
+		    struct nvkm_object *objgpu, u32 size, u32 align, u32 flags,
 		    int length, void **pobject)
 {
-	struct nvkm_instmem *imem = nvkm_instmem(parent);
-	struct nvkm_bar *bar = nvkm_bar(parent);
+	struct nvkm_device *device = nv_device(parent);
+	struct nvkm_memory *memory = NULL;
+	struct nvkm_gpuobj *pargpu = NULL;
 	struct nvkm_gpuobj *gpuobj;
 	struct nvkm_mm *heap = NULL;
 	int ret, i;
@@ -64,46 +112,39 @@ nvkm_gpuobj_create_(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	*pobject = NULL;
 
-	if (pargpu) {
-		while ((pargpu = nv_pclass(pargpu, NV_GPUOBJ_CLASS))) {
-			if (nv_gpuobj(pargpu)->heap.block_size)
+	if (objgpu) {
+		while ((objgpu = nv_pclass(objgpu, NV_GPUOBJ_CLASS))) {
+			if (nv_gpuobj(objgpu)->heap.block_size)
 				break;
-			pargpu = pargpu->parent;
+			objgpu = objgpu->parent;
 		}
 
-		if (WARN_ON(pargpu == NULL))
+		if (WARN_ON(objgpu == NULL))
 			return -EINVAL;
+		pargpu = nv_gpuobj(objgpu);
 
-		addr =  nv_gpuobj(pargpu)->addr;
-		heap = &nv_gpuobj(pargpu)->heap;
-		atomic_inc(&parent->refcount);
+		addr =  pargpu->addr;
+		heap = &pargpu->heap;
 	} else {
-		ret = imem->alloc(imem, parent, size, align, &parent);
-		pargpu = parent;
+		ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
+				      size, align, false, &memory);
 		if (ret)
 			return ret;
 
-		addr = nv_memobj(pargpu)->addr;
-		size = nv_memobj(pargpu)->size;
-
-		if (bar && bar->alloc) {
-			struct nvkm_instobj *iobj = (void *)parent;
-			struct nvkm_mem **mem = (void *)(iobj + 1);
-			struct nvkm_mem *node = *mem;
-			if (!bar->alloc(bar, parent, node, &pargpu)) {
-				nvkm_object_ref(NULL, &parent);
-				parent = pargpu;
-			}
-		}
+		addr = nvkm_memory_addr(memory);
+		size = nvkm_memory_size(memory);
 	}
 
 	ret = nvkm_object_create_(parent, engine, oclass, pclass |
 				  NV_GPUOBJ_CLASS, length, pobject);
-	nvkm_object_ref(NULL, &parent);
 	gpuobj = *pobject;
-	if (ret)
+	if (ret) {
+		nvkm_memory_del(&memory);
 		return ret;
+	}
 
+	gpuobj->func = &nvkm_gpuobj_func;
+	gpuobj->memory = memory;
 	gpuobj->parent = pargpu;
 	gpuobj->flags = flags;
 	gpuobj->addr = addr;
@@ -182,20 +223,14 @@ u32
 _nvkm_gpuobj_rd32(struct nvkm_object *object, u64 addr)
 {
 	struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
-	u32 data;
-	if (gpuobj->node)
-		addr += gpuobj->node->offset;
-	nvkm_object_rd32(gpuobj->parent, addr, &data);
-	return data;
+	return nvkm_ro32(gpuobj, addr);
 }
 
 void
 _nvkm_gpuobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
 {
 	struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
-	if (gpuobj->node)
-		addr += gpuobj->node->offset;
-	nvkm_object_wr32(gpuobj->parent, addr, data);
+	nvkm_wo32(gpuobj, addr, data);
 }
 
 static struct nvkm_oclass
@@ -231,14 +266,14 @@ nvkm_gpuobj_new(struct nvkm_object *parent, struct nvkm_object *pargpu,
 int
 nvkm_gpuobj_map(struct nvkm_gpuobj *gpuobj, u32 access, struct nvkm_vma *vma)
 {
+	struct nvkm_memory *memory = gpuobj->memory;
 	struct nvkm_bar *bar = nvkm_bar(gpuobj);
 	int ret = -EINVAL;
 
 	if (bar && bar->umap) {
-		struct nvkm_instobj *iobj = (void *)
-			nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
-		struct nvkm_mem **mem = (void *)(iobj + 1);
-		ret = bar->umap(bar, *mem, access, vma);
+		ret = bar->umap(bar, gpuobj->size, 12, vma);
+		if (ret == 0)
+			nvkm_memory_map(memory, vma, 0);
 	}
 
 	return ret;
@@ -248,17 +283,11 @@ int
 nvkm_gpuobj_map_vm(struct nvkm_gpuobj *gpuobj, struct nvkm_vm *vm,
 		   u32 access, struct nvkm_vma *vma)
 {
-	struct nvkm_instobj *iobj = (void *)
-		nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
-	struct nvkm_mem **mem = (void *)(iobj + 1);
-	int ret;
-
-	ret = nvkm_vm_get(vm, gpuobj->size, 12, access, vma);
-	if (ret)
-		return ret;
-
-	nvkm_vm_map(vma, *mem);
-	return 0;
+	struct nvkm_memory *memory = gpuobj->memory;
+	int ret = nvkm_vm_get(vm, gpuobj->size, 12, access, vma);
+	if (ret == 0)
+		nvkm_memory_map(memory, vma, 0);
+	return ret;
 }
 
 void
@@ -279,7 +308,7 @@ static void
 nvkm_gpudup_dtor(struct nvkm_object *object)
 {
 	struct nvkm_gpuobj *gpuobj = (void *)object;
-	nvkm_object_ref(NULL, &gpuobj->parent);
+	nvkm_object_ref(NULL, (struct nvkm_object **)&gpuobj->parent);
 	nvkm_object_destroy(&gpuobj->object);
 }
 
@@ -306,7 +335,7 @@ nvkm_gpuobj_dup(struct nvkm_object *parent, struct nvkm_gpuobj *base,
 	if (ret)
 		return ret;
 
-	nvkm_object_ref(nv_object(base), &gpuobj->parent);
+	nvkm_object_ref(nv_object(base), (struct nvkm_object **)&gpuobj->parent);
 	gpuobj->addr = base->addr;
 	gpuobj->size = base->size;
 	return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/memory.c b/drivers/gpu/drm/nouveau/nvkm/core/memory.c
new file mode 100644
index 000000000000..0b88faa845f3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/core/memory.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+#include <core/memory.h>
+#include <subdev/instmem.h>
+
+void
+nvkm_memory_ctor(const struct nvkm_memory_func *func,
+		 struct nvkm_memory *memory)
+{
+	memory->func = func;
+}
+
+void
+nvkm_memory_del(struct nvkm_memory **pmemory)
+{
+	struct nvkm_memory *memory = *pmemory;
+	if (memory && !WARN_ON(!memory->func)) {
+		if (memory->func->dtor)
+			*pmemory = memory->func->dtor(memory);
+		kfree(*pmemory);
+		*pmemory = NULL;
+	}
+}
+
+int
+nvkm_memory_new(struct nvkm_device *device, enum nvkm_memory_target target,
+		u64 size, u32 align, bool zero,
+		struct nvkm_memory **pmemory)
+{
+	struct nvkm_instmem *imem = device->imem;
+	struct nvkm_memory *memory;
+	int ret = -ENOSYS;
+
+	if (unlikely(target != NVKM_MEM_TARGET_INST || !imem))
+		return -ENOSYS;
+
+	ret = imem->alloc(imem, size, align, zero, &memory);
+	if (ret)
+		return ret;
+
+	*pmemory = memory;
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
index 4717af0800e9..061adedc6e2c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
@@ -22,8 +22,6 @@
 #include <core/ramht.h>
 #include <core/engine.h>
 
-#include <subdev/bar.h>
-
 static u32
 nvkm_ramht_hash(struct nvkm_ramht *ramht, int chid, u32 handle)
 {
@@ -43,7 +41,6 @@ int
 nvkm_ramht_insert(struct nvkm_ramht *ramht, int chid, u32 handle, u32 context)
 {
 	struct nvkm_gpuobj *gpuobj = &ramht->gpuobj;
-	struct nvkm_bar *bar = nvkm_bar(ramht);
 	int ret = -ENOSPC;
 	u32 co, ho;
 
@@ -53,8 +50,6 @@ nvkm_ramht_insert(struct nvkm_ramht *ramht, int chid, u32 handle, u32 context)
 		if (!nvkm_ro32(gpuobj, co + 4)) {
 			nvkm_wo32(gpuobj, co + 0, handle);
 			nvkm_wo32(gpuobj, co + 4, context);
-			if (bar)
-				bar->flush(bar);
 			ret = co;
 			break;
 		}
@@ -72,12 +67,9 @@ void
 nvkm_ramht_remove(struct nvkm_ramht *ramht, int cookie)
 {
 	struct nvkm_gpuobj *gpuobj = &ramht->gpuobj;
-	struct nvkm_bar *bar = nvkm_bar(ramht);
 	nvkm_kmap(gpuobj);
 	nvkm_wo32(gpuobj, cookie + 0, 0x00000000);
 	nvkm_wo32(gpuobj, cookie + 4, 0x00000000);
-	if (bar)
-		bar->flush(bar);
 	nvkm_done(gpuobj);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
index 64523d7eea58..c6150eaf16f0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
@@ -27,7 +27,6 @@
 #include <core/client.h>
 #include <core/engctx.h>
 #include <core/ramht.h>
-#include <subdev/bar.h>
 #include <subdev/mmu.h>
 #include <subdev/timer.h>
 
@@ -41,7 +40,6 @@
 static int
 g84_fifo_context_attach(struct nvkm_object *parent, struct nvkm_object *object)
 {
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct nv50_fifo_base *base = (void *)parent->parent;
 	struct nvkm_gpuobj *ectx = (void *)object;
 	u64 limit = ectx->addr + ectx->size - 1;
@@ -73,7 +71,6 @@ g84_fifo_context_attach(struct nvkm_object *parent, struct nvkm_object *object)
 					  upper_32_bits(start));
 	nvkm_wo32(base->eng, addr + 0x10, 0x00000000);
 	nvkm_wo32(base->eng, addr + 0x14, 0x00000000);
-	bar->flush(bar);
 	nvkm_done(base->eng);
 	return 0;
 }
@@ -87,7 +84,6 @@ g84_fifo_context_detach(struct nvkm_object *parent, bool suspend,
 	struct nv50_fifo_chan *chan = (void *)parent;
 	struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
 	struct nvkm_device *device = subdev->device;
-	struct nvkm_bar *bar = device->bar;
 	u32 addr, save, engn;
 	bool done;
 
@@ -128,7 +124,6 @@ g84_fifo_context_detach(struct nvkm_object *parent, bool suspend,
 	nvkm_wo32(base->eng, addr + 0x0c, 0x00000000);
 	nvkm_wo32(base->eng, addr + 0x10, 0x00000000);
 	nvkm_wo32(base->eng, addr + 0x14, 0x00000000);
-	bar->flush(bar);
 	nvkm_done(base->eng);
 	return 0;
 }
@@ -175,7 +170,6 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 	union {
 		struct nv50_channel_dma_v0 v0;
 	} *args = data;
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct nv50_fifo_base *base = (void *)parent;
 	struct nv50_fifo_chan *chan;
 	int ret;
@@ -239,7 +233,6 @@ g84_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 				     (chan->ramht->gpuobj.node->offset >> 4));
 	nvkm_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
 	nvkm_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
-	bar->flush(bar);
 	nvkm_done(base->ramfc);
 	return 0;
 }
@@ -252,7 +245,6 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
 	union {
 		struct nv50_channel_gpfifo_v0 v0;
 	} *args = data;
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct nv50_fifo_base *base = (void *)parent;
 	struct nv50_fifo_chan *chan;
 	u64 ioffset, ilength;
@@ -318,7 +310,6 @@ g84_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
 				     (chan->ramht->gpuobj.node->offset >> 4));
 	nvkm_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
 	nvkm_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
-	bar->flush(bar);
 	nvkm_done(base->ramfc);
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
index ba6b390a1fef..763a2db7603a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
@@ -27,7 +27,6 @@
 #include <core/engctx.h>
 #include <core/enum.h>
 #include <core/handle.h>
-#include <subdev/bar.h>
 #include <subdev/fb.h>
 #include <subdev/mmu.h>
 #include <subdev/timer.h>
@@ -79,7 +78,6 @@ gf100_fifo_runlist_update(struct gf100_fifo *fifo)
 {
 	struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
 	struct nvkm_device *device = subdev->device;
-	struct nvkm_bar *bar = device->bar;
 	struct nvkm_gpuobj *cur;
 	int i, p;
 
@@ -96,7 +94,6 @@ gf100_fifo_runlist_update(struct gf100_fifo *fifo)
 			p += 8;
 		}
 	}
-	bar->flush(bar);
 	nvkm_done(cur);
 
 	nvkm_wr32(device, 0x002270, cur->addr >> 12);
@@ -113,7 +110,6 @@ static int
 gf100_fifo_context_attach(struct nvkm_object *parent,
 			  struct nvkm_object *object)
 {
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct gf100_fifo_base *base = (void *)parent->parent;
 	struct nvkm_gpuobj *engn = &base->base.gpuobj;
 	struct nvkm_engctx *ectx = (void *)object;
@@ -144,7 +140,6 @@ gf100_fifo_context_attach(struct nvkm_object *parent,
 	nvkm_kmap(engn);
 	nvkm_wo32(engn, addr + 0x00, lower_32_bits(ectx->vma.offset) | 4);
 	nvkm_wo32(engn, addr + 0x04, upper_32_bits(ectx->vma.offset));
-	bar->flush(bar);
 	nvkm_done(engn);
 	return 0;
 }
@@ -159,7 +154,6 @@ gf100_fifo_context_detach(struct nvkm_object *parent, bool suspend,
 	struct nvkm_gpuobj *engn = &base->base.gpuobj;
 	struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
 	struct nvkm_device *device = subdev->device;
-	struct nvkm_bar *bar = device->bar;
 	u32 addr;
 
 	switch (nv_engidx(object->engine)) {
@@ -188,7 +182,6 @@ gf100_fifo_context_detach(struct nvkm_object *parent, bool suspend,
 	nvkm_kmap(engn);
 	nvkm_wo32(engn, addr + 0x00, 0x00000000);
 	nvkm_wo32(engn, addr + 0x04, 0x00000000);
-	bar->flush(bar);
 	nvkm_done(engn);
 	return 0;
 }
@@ -201,7 +194,6 @@ gf100_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	union {
 		struct fermi_channel_gpfifo_v0 v0;
 	} *args = data;
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct gf100_fifo *fifo = (void *)engine;
 	struct gf100_fifo_base *base = (void *)parent;
 	struct gf100_fifo_chan *chan;
@@ -264,7 +256,6 @@ gf100_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	nvkm_wo32(ramfc, 0xb8, 0xf8000000);
 	nvkm_wo32(ramfc, 0xf8, 0x10003080); /* 0x002310 */
 	nvkm_wo32(ramfc, 0xfc, 0x10000010); /* 0x002350 */
-	bar->flush(bar);
 	nvkm_done(ramfc);
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
index 62b3de4e9353..d1238aa7bec5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
@@ -27,7 +27,6 @@
 #include <core/engctx.h>
 #include <core/enum.h>
 #include <core/handle.h>
-#include <subdev/bar.h>
 #include <subdev/fb.h>
 #include <subdev/mmu.h>
 #include <subdev/timer.h>
@@ -99,7 +98,6 @@ gk104_fifo_runlist_update(struct gk104_fifo *fifo, u32 engine)
 	struct gk104_fifo_engn *engn = &fifo->engine[engine];
 	struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
 	struct nvkm_device *device = subdev->device;
-	struct nvkm_bar *bar = device->bar;
 	struct nvkm_gpuobj *cur;
 	int i, p;
 
@@ -116,7 +114,6 @@ gk104_fifo_runlist_update(struct gk104_fifo *fifo, u32 engine)
 			p += 8;
 		}
 	}
-	bar->flush(bar);
 	nvkm_done(cur);
 
 	nvkm_wr32(device, 0x002270, cur->addr >> 12);
@@ -133,7 +130,6 @@ static int
 gk104_fifo_context_attach(struct nvkm_object *parent,
 			  struct nvkm_object *object)
 {
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct gk104_fifo_base *base = (void *)parent->parent;
 	struct nvkm_gpuobj *engn = &base->base.gpuobj;
 	struct nvkm_engctx *ectx = (void *)object;
@@ -168,7 +164,6 @@ gk104_fifo_context_attach(struct nvkm_object *parent,
 	nvkm_kmap(engn);
 	nvkm_wo32(engn, addr + 0x00, lower_32_bits(ectx->vma.offset) | 4);
 	nvkm_wo32(engn, addr + 0x04, upper_32_bits(ectx->vma.offset));
-	bar->flush(bar);
 	nvkm_done(engn);
 	return 0;
 }
@@ -198,7 +193,6 @@ static int
 gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend,
 			  struct nvkm_object *object)
 {
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct gk104_fifo_base *base = (void *)parent->parent;
 	struct gk104_fifo_chan *chan = (void *)parent;
 	struct nvkm_gpuobj *engn = &base->base.gpuobj;
@@ -226,7 +220,6 @@ gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend,
 		nvkm_kmap(engn);
 		nvkm_wo32(engn, addr + 0x00, 0x00000000);
 		nvkm_wo32(engn, addr + 0x04, 0x00000000);
-		bar->flush(bar);
 		nvkm_done(engn);
 	}
 
@@ -241,7 +234,6 @@ gk104_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	union {
 		struct kepler_channel_gpfifo_a_v0 v0;
 	} *args = data;
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct gk104_fifo *fifo = (void *)engine;
 	struct gk104_fifo_base *base = (void *)parent;
 	struct gk104_fifo_chan *chan;
@@ -320,7 +312,6 @@ gk104_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	nvkm_wo32(ramfc, 0xb8, 0xf8000000);
 	nvkm_wo32(ramfc, 0xf8, 0x10003080); /* 0x002310 */
 	nvkm_wo32(ramfc, 0xfc, 0x10000010); /* 0x002350 */
-	bar->flush(bar);
 	nvkm_done(ramfc);
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
index 51b8fce9e0fc..b01490f71f09 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
@@ -27,7 +27,7 @@
 #include <core/engctx.h>
 #include <core/handle.h>
 #include <core/ramht.h>
-#include <subdev/instmem/nv04.h>
+#include <subdev/instmem.h>
 #include <subdev/timer.h>
 
 #include <nvif/class.h>
@@ -574,7 +574,8 @@ nv04_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
 	       struct nvkm_object **pobject)
 {
-	struct nv04_instmem *imem = nv04_instmem(parent);
+	struct nvkm_device *device = (void *)parent;
+	struct nvkm_instmem *imem = device->imem;
 	struct nv04_fifo *fifo;
 	int ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
index 046acc281381..7491b10a76b7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
@@ -26,7 +26,7 @@
 #include <core/client.h>
 #include <core/engctx.h>
 #include <core/ramht.h>
-#include <subdev/instmem/nv04.h>
+#include <subdev/instmem.h>
 
 #include <nvif/class.h>
 #include <nvif/unpack.h>
@@ -145,7 +145,8 @@ nv10_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
 	       struct nvkm_object **pobject)
 {
-	struct nv04_instmem *imem = nv04_instmem(parent);
+	struct nvkm_device *device = (void *)parent;
+	struct nvkm_instmem *imem = device->imem;
 	struct nv04_fifo *fifo;
 	int ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
index 7be6fea90010..e652941d04f3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
@@ -26,7 +26,7 @@
 #include <core/client.h>
 #include <core/engctx.h>
 #include <core/ramht.h>
-#include <subdev/instmem/nv04.h>
+#include <subdev/instmem.h>
 
 #include <nvif/class.h>
 #include <nvif/unpack.h>
@@ -152,7 +152,8 @@ nv17_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
 	       struct nvkm_object **pobject)
 {
-	struct nv04_instmem *imem = nv04_instmem(parent);
+	struct nvkm_device *device = (void *)parent;
+	struct nvkm_instmem *imem = device->imem;
 	struct nv04_fifo *fifo;
 	int ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
index cad4b4be1938..f35ae7647239 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
@@ -27,7 +27,7 @@
 #include <core/engctx.h>
 #include <core/ramht.h>
 #include <subdev/fb.h>
-#include <subdev/instmem/nv04.h>
+#include <subdev/instmem.h>
 
 #include <nvif/class.h>
 #include <nvif/unpack.h>
@@ -276,7 +276,8 @@ nv40_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
 	       struct nvkm_object **pobject)
 {
-	struct nv04_instmem *imem = nv04_instmem(parent);
+	struct nvkm_device *device = (void *)parent;
+	struct nvkm_instmem *imem = device->imem;
 	struct nv04_fifo *fifo;
 	int ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
index 402639cb4ec9..ffa495c1692b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
@@ -27,7 +27,6 @@
 #include <core/client.h>
 #include <core/engctx.h>
 #include <core/ramht.h>
-#include <subdev/bar.h>
 #include <subdev/mmu.h>
 #include <subdev/timer.h>
 
@@ -42,7 +41,6 @@ static void
 nv50_fifo_playlist_update_locked(struct nv50_fifo *fifo)
 {
 	struct nvkm_device *device = fifo->base.engine.subdev.device;
-	struct nvkm_bar *bar = device->bar;
 	struct nvkm_gpuobj *cur;
 	int i, p;
 
@@ -54,7 +52,6 @@ nv50_fifo_playlist_update_locked(struct nv50_fifo *fifo)
 		if (nvkm_rd32(device, 0x002600 + (i * 4)) & 0x80000000)
 			nvkm_wo32(cur, p++ * 4, i);
 	}
-	bar->flush(bar);
 	nvkm_done(cur);
 
 	nvkm_wr32(device, 0x0032f4, cur->addr >> 12);
@@ -73,7 +70,6 @@ nv50_fifo_playlist_update(struct nv50_fifo *fifo)
 static int
 nv50_fifo_context_attach(struct nvkm_object *parent, struct nvkm_object *object)
 {
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct nv50_fifo_base *base = (void *)parent->parent;
 	struct nvkm_gpuobj *ectx = (void *)object;
 	u64 limit = ectx->addr + ectx->size - 1;
@@ -98,7 +94,6 @@ nv50_fifo_context_attach(struct nvkm_object *parent, struct nvkm_object *object)
 					  upper_32_bits(start));
 	nvkm_wo32(base->eng, addr + 0x10, 0x00000000);
 	nvkm_wo32(base->eng, addr + 0x14, 0x00000000);
-	bar->flush(bar);
 	nvkm_done(base->eng);
 	return 0;
 }
@@ -112,7 +107,6 @@ nv50_fifo_context_detach(struct nvkm_object *parent, bool suspend,
 	struct nv50_fifo_chan *chan = (void *)parent;
 	struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
 	struct nvkm_device *device = subdev->device;
-	struct nvkm_bar *bar = device->bar;
 	u32 addr, me;
 	int ret = 0;
 
@@ -159,7 +153,6 @@ nv50_fifo_context_detach(struct nvkm_object *parent, bool suspend,
 		nvkm_wo32(base->eng, addr + 0x0c, 0x00000000);
 		nvkm_wo32(base->eng, addr + 0x10, 0x00000000);
 		nvkm_wo32(base->eng, addr + 0x14, 0x00000000);
-		bar->flush(bar);
 		nvkm_done(base->eng);
 	}
 
@@ -205,7 +198,6 @@ nv50_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 	union {
 		struct nv50_channel_dma_v0 v0;
 	} *args = data;
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct nv50_fifo_base *base = (void *)parent;
 	struct nv50_fifo_chan *chan;
 	int ret;
@@ -257,7 +249,6 @@ nv50_fifo_chan_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 	nvkm_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
 				     (4 << 24) /* SEARCH_FULL */ |
 				     (chan->ramht->gpuobj.node->offset >> 4));
-	bar->flush(bar);
 	nvkm_done(base->ramfc);
 	return 0;
 }
@@ -270,7 +261,6 @@ nv50_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
 	union {
 		struct nv50_channel_gpfifo_v0 v0;
 	} *args = data;
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct nv50_fifo_base *base = (void *)parent;
 	struct nv50_fifo_chan *chan;
 	u64 ioffset, ilength;
@@ -324,7 +314,6 @@ nv50_fifo_chan_ctor_ind(struct nvkm_object *parent, struct nvkm_object *engine,
 	nvkm_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
 				     (4 << 24) /* SEARCH_FULL */ |
 				     (chan->ramht->gpuobj.node->offset >> 4));
-	bar->flush(bar);
 	nvkm_done(base->ramfc);
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
index f36e0896ae9c..a2e60b1ddb27 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
@@ -23,7 +23,6 @@
  */
 #include "ctxgf100.h"
 
-#include <subdev/bar.h>
 #include <subdev/fb.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
@@ -1273,7 +1272,6 @@ gf100_grctx_generate(struct gf100_gr *gr)
 	struct gf100_grctx_oclass *oclass = (void *)nv_engine(gr)->cclass;
 	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
 	struct nvkm_device *device = subdev->device;
-	struct nvkm_bar *bar = device->bar;
 	struct nvkm_gpuobj *chan;
 	struct gf100_grctx info;
 	int ret, i;
@@ -1309,7 +1307,6 @@ gf100_grctx_generate(struct gf100_gr *gr)
 	/* context pointer (virt) */
 	nvkm_wo32(chan, 0x0210, 0x00080004);
 	nvkm_wo32(chan, 0x0214, 0x00000000);
-	bar->flush(bar);
 	nvkm_done(chan);
 
 	nvkm_wr32(device, 0x100cb8, (chan->addr + 0x1000) >> 8);
@@ -1341,7 +1338,6 @@ gf100_grctx_generate(struct gf100_gr *gr)
 		nvkm_wo32(chan, 0x80020, 0);
 		nvkm_wo32(chan, 0x80028, 0);
 		nvkm_wo32(chan, 0x8002c, 0);
-		bar->flush(bar);
 		nvkm_done(chan);
 	} else {
 		nvkm_wr32(device, 0x409840, 0x80000000);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c
index 6af707b5be18..c906c43e9065 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c
@@ -23,7 +23,6 @@
  */
 #include <engine/mpeg.h>
 
-#include <subdev/bar.h>
 #include <subdev/timer.h>
 
 struct nv50_mpeg_chan {
@@ -84,7 +83,6 @@ nv50_mpeg_context_ctor(struct nvkm_object *parent,
 		       struct nvkm_oclass *oclass, void *data, u32 size,
 		       struct nvkm_object **pobject)
 {
-	struct nvkm_bar *bar = nvkm_bar(parent);
 	struct nv50_mpeg_chan *chan;
 	struct nvkm_gpuobj *image;
 	int ret;
@@ -100,7 +98,6 @@ nv50_mpeg_context_ctor(struct nvkm_object *parent,
 	nvkm_kmap(image);
 	nvkm_wo32(image, 0x0070, 0x00801ec1);
 	nvkm_wo32(image, 0x007c, 0x0000037c);
-	bar->flush(bar);
 	nvkm_done(image);
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
index 6fe71b2276cc..8daaa65fc8cf 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
@@ -23,96 +23,6 @@
  */
 #include "priv.h"
 
-#include <subdev/fb.h>
-#include <subdev/mmu.h>
-
-struct nvkm_barobj {
-	struct nvkm_object base;
-	struct nvkm_vma vma;
-	void __iomem *iomem;
-};
-
-static int
-nvkm_barobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-		 struct nvkm_oclass *oclass, void *data, u32 size,
-		 struct nvkm_object **pobject)
-{
-	struct nvkm_device *device = nv_device(parent);
-	struct nvkm_bar *bar = nvkm_bar(device);
-	struct nvkm_mem *mem = data;
-	struct nvkm_barobj *barobj;
-	int ret;
-
-	ret = nvkm_object_create(parent, engine, oclass, 0, &barobj);
-	*pobject = nv_object(barobj);
-	if (ret)
-		return ret;
-
-	ret = bar->kmap(bar, mem, NV_MEM_ACCESS_RW, &barobj->vma);
-	if (ret)
-		return ret;
-
-	barobj->iomem = ioremap(nv_device_resource_start(device, 3) +
-				(u32)barobj->vma.offset, mem->size << 12);
-	if (!barobj->iomem) {
-		nvkm_warn(&bar->subdev, "PRAMIN ioremap failed\n");
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static void
-nvkm_barobj_dtor(struct nvkm_object *object)
-{
-	struct nvkm_bar *bar = nvkm_bar(object);
-	struct nvkm_barobj *barobj = (void *)object;
-	if (barobj->vma.node) {
-		if (barobj->iomem)
-			iounmap(barobj->iomem);
-		bar->unmap(bar, &barobj->vma);
-	}
-	nvkm_object_destroy(&barobj->base);
-}
-
-static u32
-nvkm_barobj_rd32(struct nvkm_object *object, u64 addr)
-{
-	struct nvkm_barobj *barobj = (void *)object;
-	return ioread32_native(barobj->iomem + addr);
-}
-
-static void
-nvkm_barobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
-{
-	struct nvkm_barobj *barobj = (void *)object;
-	iowrite32_native(data, barobj->iomem + addr);
-}
-
-static struct nvkm_oclass
-nvkm_barobj_oclass = {
-	.ofuncs = &(struct nvkm_ofuncs) {
-		.ctor = nvkm_barobj_ctor,
-		.dtor = nvkm_barobj_dtor,
-		.init = _nvkm_object_init,
-		.fini = _nvkm_object_fini,
-		.rd32 = nvkm_barobj_rd32,
-		.wr32 = nvkm_barobj_wr32,
-	},
-};
-
-int
-nvkm_bar_alloc(struct nvkm_bar *bar, struct nvkm_object *parent,
-	       struct nvkm_mem *mem, struct nvkm_object **pobject)
-{
-	struct nvkm_object *gpuobj;
-	int ret = nvkm_object_old(parent, &parent->engine->subdev.object,
-				   &nvkm_barobj_oclass, mem, 0, &gpuobj);
-	if (ret == 0)
-		*pobject = gpuobj;
-	return ret;
-}
-
 int
 nvkm_bar_create_(struct nvkm_object *parent, struct nvkm_object *engine,
 		 struct nvkm_oclass *oclass, int length, void **pobject)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
index 01e26213fd88..1ea6b3909c3a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c
@@ -39,35 +39,18 @@ struct gf100_bar {
 	struct gf100_bar_vm bar[2];
 };
 
-static int
-gf100_bar_kmap(struct nvkm_bar *obj, struct nvkm_mem *mem, u32 flags,
-	       struct nvkm_vma *vma)
+static struct nvkm_vm *
+gf100_bar_kmap(struct nvkm_bar *obj)
 {
 	struct gf100_bar *bar = container_of(obj, typeof(*bar), base);
-	int ret;
-
-	ret = nvkm_vm_get(bar->bar[0].vm, mem->size << 12, 12, flags, vma);
-	if (ret)
-		return ret;
-
-	nvkm_vm_map(vma, mem);
-	return 0;
+	return bar->bar[0].vm;
 }
 
 static int
-gf100_bar_umap(struct nvkm_bar *obj, struct nvkm_mem *mem, u32 flags,
-	       struct nvkm_vma *vma)
+gf100_bar_umap(struct nvkm_bar *obj, u64 size, int type, struct nvkm_vma *vma)
 {
 	struct gf100_bar *bar = container_of(obj, typeof(*bar), base);
-	int ret;
-
-	ret = nvkm_vm_get(bar->bar[1].vm, mem->size << 12,
-			  mem->page_shift, flags, vma);
-	if (ret)
-		return ret;
-
-	nvkm_vm_map(vma, mem);
-	return 0;
+	return nvkm_vm_get(bar->bar[1].vm, size, type, NV_MEM_ACCESS_RW, vma);
 }
 
 static void
@@ -109,11 +92,7 @@ gf100_bar_ctor_vm(struct gf100_bar *bar, struct gf100_bar_vm *bar_vm,
 	 * Bootstrap page table lookup.
 	 */
 	if (bar_nr == 3) {
-		ret = nvkm_gpuobj_new(nv_object(bar), NULL,
-				      (bar_len >> 12) * 8, 0x1000,
-				      NVOBJ_FLAG_ZERO_ALLOC,
-				      &vm->pgt[0].obj[0]);
-		vm->pgt[0].refcount[0] = 1;
+		ret = nvkm_vm_boot(vm, bar_len);
 		if (ret)
 			return ret;
 	}
@@ -149,6 +128,10 @@ gf100_bar_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	if (ret)
 		return ret;
 
+	device->bar = &bar->base;
+	bar->base.flush = g84_bar_flush;
+	spin_lock_init(&bar->lock);
+
 	/* BAR3 */
 	if (has_bar3) {
 		ret = gf100_bar_ctor_vm(bar, &bar->bar[0], &bar3_lock, 3);
@@ -161,14 +144,10 @@ gf100_bar_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	if (ret)
 		return ret;
 
-	if (has_bar3) {
-		bar->base.alloc = nvkm_bar_alloc;
+	if (has_bar3)
 		bar->base.kmap = gf100_bar_kmap;
-	}
 	bar->base.umap = gf100_bar_umap;
 	bar->base.unmap = gf100_bar_unmap;
-	bar->base.flush = g84_bar_flush;
-	spin_lock_init(&bar->lock);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
index cb58cc5b2b57..ec864afc8862 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c
@@ -40,34 +40,18 @@ struct nv50_bar {
 	struct nvkm_gpuobj *bar3;
 };
 
-static int
-nv50_bar_kmap(struct nvkm_bar *obj, struct nvkm_mem *mem, u32 flags,
-	      struct nvkm_vma *vma)
+static struct nvkm_vm *
+nv50_bar_kmap(struct nvkm_bar *obj)
 {
 	struct nv50_bar *bar = container_of(obj, typeof(*bar), base);
-	int ret;
-
-	ret = nvkm_vm_get(bar->bar3_vm, mem->size << 12, 12, flags, vma);
-	if (ret)
-		return ret;
-
-	nvkm_vm_map(vma, mem);
-	return 0;
+	return bar->bar3_vm;
 }
 
 static int
-nv50_bar_umap(struct nvkm_bar *obj, struct nvkm_mem *mem, u32 flags,
-	      struct nvkm_vma *vma)
+nv50_bar_umap(struct nvkm_bar *obj, u64 size, int type, struct nvkm_vma *vma)
 {
 	struct nv50_bar *bar = container_of(obj, typeof(*bar), base);
-	int ret;
-
-	ret = nvkm_vm_get(bar->bar1_vm, mem->size << 12, 12, flags, vma);
-	if (ret)
-		return ret;
-
-	nvkm_vm_map(vma, mem);
-	return 0;
+	return nvkm_vm_get(bar->bar1_vm, size, type, NV_MEM_ACCESS_RW, vma);
 }
 
 static void
@@ -152,10 +136,7 @@ nv50_bar_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
 
-	ret = nvkm_gpuobj_new(nv_object(bar), heap,
-			      ((limit-- - start) >> 12) * 8, 0x1000,
-			      NVOBJ_FLAG_ZERO_ALLOC, &vm->pgt[0].obj[0]);
-	vm->pgt[0].refcount[0] = 1;
+	ret = nvkm_vm_boot(vm, limit-- - start);
 	if (ret)
 		return ret;
 
@@ -207,7 +188,6 @@ nv50_bar_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	nvkm_wo32(bar->bar1, 0x14, 0x00000000);
 	nvkm_done(bar->bar1);
 
-	bar->base.alloc = nvkm_bar_alloc;
 	bar->base.kmap = nv50_bar_kmap;
 	bar->base.umap = nv50_bar_umap;
 	bar->base.unmap = nv50_bar_unmap;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
index e9d2f7b6b22f..3a8fbaea582d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/priv.h
@@ -17,9 +17,6 @@ void _nvkm_bar_dtor(struct nvkm_object *);
 #define _nvkm_bar_init _nvkm_subdev_init
 #define _nvkm_bar_fini _nvkm_subdev_fini
 
-int  nvkm_bar_alloc(struct nvkm_bar *, struct nvkm_object *,
-		    struct nvkm_mem *, struct nvkm_object **);
-
 void g84_bar_flush(struct nvkm_bar *);
 
 int gf100_bar_ctor(struct nvkm_object *, struct nvkm_object *,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
index 8ac8e4f4fa4b..2a1dab304087 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
@@ -23,83 +23,221 @@
  */
 #include "priv.h"
 
-#include <core/engine.h>
+#include <core/memory.h>
+#include <subdev/bar.h>
 
 /******************************************************************************
  * instmem object base implementation
  *****************************************************************************/
+#define nvkm_instobj(p) container_of((p), struct nvkm_instobj, memory)
 
-void
-_nvkm_instobj_dtor(struct nvkm_object *object)
+struct nvkm_instobj {
+	struct nvkm_memory memory;
+	struct nvkm_memory *parent;
+	struct nvkm_instmem *imem;
+	struct list_head head;
+	u32 *suspend;
+	void __iomem *map;
+};
+
+static enum nvkm_memory_target
+nvkm_instobj_target(struct nvkm_memory *memory)
+{
+	memory = nvkm_instobj(memory)->parent;
+	return nvkm_memory_target(memory);
+}
+
+static u64
+nvkm_instobj_addr(struct nvkm_memory *memory)
+{
+	memory = nvkm_instobj(memory)->parent;
+	return nvkm_memory_addr(memory);
+}
+
+static u64
+nvkm_instobj_size(struct nvkm_memory *memory)
+{
+	memory = nvkm_instobj(memory)->parent;
+	return nvkm_memory_size(memory);
+}
+
+static void
+nvkm_instobj_release(struct nvkm_memory *memory)
+{
+	struct nvkm_instobj *iobj = nvkm_instobj(memory);
+	struct nvkm_bar *bar = iobj->imem->subdev.device->bar;
+	if (bar && bar->flush)
+		bar->flush(bar);
+}
+
+static void __iomem *
+nvkm_instobj_acquire(struct nvkm_memory *memory)
+{
+	return nvkm_instobj(memory)->map;
+}
+
+static u32
+nvkm_instobj_rd32(struct nvkm_memory *memory, u64 offset)
+{
+	return ioread32_native(nvkm_instobj(memory)->map + offset);
+}
+
+static void
+nvkm_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
 {
-	struct nvkm_instmem *imem = nvkm_instmem(object);
-	struct nvkm_instobj *iobj = (void *)object;
+	iowrite32_native(data, nvkm_instobj(memory)->map + offset);
+}
+
+static void
+nvkm_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset)
+{
+	memory = nvkm_instobj(memory)->parent;
+	nvkm_memory_map(memory, vma, offset);
+}
 
-	mutex_lock(&nv_subdev(imem)->mutex);
+static void *
+nvkm_instobj_dtor(struct nvkm_memory *memory)
+{
+	struct nvkm_instobj *iobj = nvkm_instobj(memory);
 	list_del(&iobj->head);
-	mutex_unlock(&nv_subdev(imem)->mutex);
+	nvkm_memory_del(&iobj->parent);
+	return iobj;
+}
 
-	return nvkm_object_destroy(&iobj->object);
+const struct nvkm_memory_func
+nvkm_instobj_func = {
+	.dtor = nvkm_instobj_dtor,
+	.target = nvkm_instobj_target,
+	.addr = nvkm_instobj_addr,
+	.size = nvkm_instobj_size,
+	.acquire = nvkm_instobj_acquire,
+	.release = nvkm_instobj_release,
+	.rd32 = nvkm_instobj_rd32,
+	.wr32 = nvkm_instobj_wr32,
+	.map = nvkm_instobj_map,
+};
+
+static void
+nvkm_instobj_boot(struct nvkm_memory *memory, struct nvkm_vm *vm)
+{
+	memory = nvkm_instobj(memory)->parent;
+	nvkm_memory_boot(memory, vm);
 }
 
-int
-nvkm_instobj_create_(struct nvkm_object *parent, struct nvkm_object *engine,
-		     struct nvkm_oclass *oclass, int length, void **pobject)
+static void
+nvkm_instobj_release_slow(struct nvkm_memory *memory)
+{
+	struct nvkm_instobj *iobj = nvkm_instobj(memory);
+	nvkm_instobj_release(memory);
+	nvkm_done(iobj->parent);
+}
+
+static void __iomem *
+nvkm_instobj_acquire_slow(struct nvkm_memory *memory)
+{
+	struct nvkm_instobj *iobj = nvkm_instobj(memory);
+	iobj->map = nvkm_kmap(iobj->parent);
+	if (iobj->map)
+		memory->func = &nvkm_instobj_func;
+	return iobj->map;
+}
+
+static u32
+nvkm_instobj_rd32_slow(struct nvkm_memory *memory, u64 offset)
+{
+	struct nvkm_instobj *iobj = nvkm_instobj(memory);
+	return nvkm_ro32(iobj->parent, offset);
+}
+
+static void
+nvkm_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data)
+{
+	struct nvkm_instobj *iobj = nvkm_instobj(memory);
+	return nvkm_wo32(iobj->parent, offset, data);
+}
+
+const struct nvkm_memory_func
+nvkm_instobj_func_slow = {
+	.dtor = nvkm_instobj_dtor,
+	.target = nvkm_instobj_target,
+	.addr = nvkm_instobj_addr,
+	.size = nvkm_instobj_size,
+	.boot = nvkm_instobj_boot,
+	.acquire = nvkm_instobj_acquire_slow,
+	.release = nvkm_instobj_release_slow,
+	.rd32 = nvkm_instobj_rd32_slow,
+	.wr32 = nvkm_instobj_wr32_slow,
+	.map = nvkm_instobj_map,
+};
+
+static int
+nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
+		 struct nvkm_memory **pmemory)
 {
-	struct nvkm_instmem *imem = nvkm_instmem(parent);
+	struct nvkm_instmem_impl *impl = (void *)imem->subdev.object.oclass;
+	struct nvkm_memory *memory;
 	struct nvkm_instobj *iobj;
+	u32 offset;
 	int ret;
 
-	ret = nvkm_object_create_(parent, engine, oclass, NV_MEMOBJ_CLASS,
-				  length, pobject);
-	iobj = *pobject;
+	ret = impl->memory_new(imem, size, align, zero, &memory);
 	if (ret)
-		return ret;
+		goto done;
 
-	mutex_lock(&imem->subdev.mutex);
-	list_add(&iobj->head, &imem->list);
-	mutex_unlock(&imem->subdev.mutex);
-	return 0;
+	if (!impl->persistent) {
+		if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) {
+			ret = -ENOMEM;
+			goto done;
+		}
+
+		nvkm_memory_ctor(&nvkm_instobj_func_slow, &iobj->memory);
+		iobj->parent = memory;
+		iobj->imem = imem;
+		list_add_tail(&iobj->head, &imem->list);
+		memory = &iobj->memory;
+	}
+
+	if (!impl->zero && zero) {
+		void __iomem *map = nvkm_kmap(memory);
+		if (unlikely(!map)) {
+			for (offset = 0; offset < size; offset += 4)
+				nvkm_wo32(memory, offset, 0x00000000);
+		} else {
+			memset_io(map, 0x00, size);
+		}
+		nvkm_done(memory);
+	}
+
+done:
+	if (ret)
+		nvkm_memory_del(&memory);
+	*pmemory = memory;
+	return ret;
 }
 
 /******************************************************************************
  * instmem subdev base implementation
  *****************************************************************************/
 
-static int
-nvkm_instmem_alloc(struct nvkm_instmem *imem, struct nvkm_object *parent,
-		   u32 size, u32 align, struct nvkm_object **pobject)
-{
-	struct nvkm_instmem_impl *impl = (void *)imem->subdev.object.oclass;
-	struct nvkm_instobj_args args = { .size = size, .align = align };
-	return nvkm_object_old(parent, &parent->engine->subdev.object,
-				impl->instobj, &args, sizeof(args), pobject);
-}
-
 int
 _nvkm_instmem_fini(struct nvkm_object *object, bool suspend)
 {
 	struct nvkm_instmem *imem = (void *)object;
 	struct nvkm_instobj *iobj;
-	int i, ret = 0;
+	int i;
 
 	if (suspend) {
-		mutex_lock(&imem->subdev.mutex);
 		list_for_each_entry(iobj, &imem->list, head) {
-			iobj->suspend = vmalloc(iobj->size);
-			if (!iobj->suspend) {
-				ret = -ENOMEM;
-				break;
-			}
-
-			for (i = 0; i < iobj->size; i += 4) {
-				nvkm_object_rd32(&iobj->object, i, (u32 *)
-						 &iobj->suspend[i/4]);
-			}
+			struct nvkm_memory *memory = iobj->parent;
+			u64 size = nvkm_memory_size(memory);
+
+			iobj->suspend = vmalloc(size);
+			if (!iobj->suspend)
+				return -ENOMEM;
+
+			for (i = 0; i < size; i += 4)
+				iobj->suspend[i / 4] = nvkm_ro32(memory, i);
 		}
-		mutex_unlock(&imem->subdev.mutex);
-		if (ret)
-			return ret;
 	}
 
 	return nvkm_subdev_fini_old(&imem->subdev, suspend);
@@ -116,18 +254,17 @@ _nvkm_instmem_init(struct nvkm_object *object)
 	if (ret)
 		return ret;
 
-	mutex_lock(&imem->subdev.mutex);
 	list_for_each_entry(iobj, &imem->list, head) {
 		if (iobj->suspend) {
-			for (i = 0; i < iobj->size; i += 4) {
-				nvkm_object_wr32(&iobj->object, i, *(u32 *)
-						 &iobj->suspend[i/4]);
-			}
+			struct nvkm_memory *memory = iobj->parent;
+			u64 size = nvkm_memory_size(memory);
+			for (i = 0; i < size; i += 4)
+				nvkm_wo32(memory, i, iobj->suspend[i / 4]);
 			vfree(iobj->suspend);
 			iobj->suspend = NULL;
 		}
 	}
-	mutex_unlock(&imem->subdev.mutex);
+
 	return 0;
 }
 
@@ -135,6 +272,7 @@ int
 nvkm_instmem_create_(struct nvkm_object *parent, struct nvkm_object *engine,
 		     struct nvkm_oclass *oclass, int length, void **pobject)
 {
+	struct nvkm_device *device = (void *)parent;
 	struct nvkm_instmem *imem;
 	int ret;
 
@@ -144,7 +282,9 @@ nvkm_instmem_create_(struct nvkm_object *parent, struct nvkm_object *engine,
 	if (ret)
 		return ret;
 
+	device->imem = imem;
+
 	INIT_LIST_HEAD(&imem->list);
-	imem->alloc = nvkm_instmem_alloc;
+	imem->alloc = nvkm_instobj_new;
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index e6370382109b..a64c3f9bfc3d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -37,9 +37,12 @@
  * to use more "relaxed" allocation parameters when using the DMA API, since we
  * never need a kernel mapping.
  */
+#define gk20a_instmem(p) container_of((p), struct gk20a_instmem, base)
+#include "priv.h"
 
-#include <subdev/fb.h>
+#include <core/memory.h>
 #include <core/mm.h>
+#include <subdev/fb.h>
 
 #ifdef __KERNEL__
 #include <linux/dma-attrs.h>
@@ -47,14 +50,12 @@
 #include <nouveau_platform.h>
 #endif
 
-#include "priv.h"
+#define gk20a_instobj(p) container_of((p), struct gk20a_instobj, memory)
 
 struct gk20a_instobj {
-	struct nvkm_instobj base;
-	/* Must be second member here - see nouveau_gpuobj_map_vm() */
-	struct nvkm_mem *mem;
-	/* Pointed by mem */
-	struct nvkm_mem _mem;
+	struct nvkm_memory memory;
+	struct gk20a_instmem *imem;
+	struct nvkm_mem mem;
 };
 
 /*
@@ -80,6 +81,7 @@ struct gk20a_instobj_iommu {
 
 struct gk20a_instmem {
 	struct nvkm_instmem base;
+	unsigned long lock_flags;
 	spinlock_t lock;
 	u64 addr;
 
@@ -93,6 +95,42 @@ struct gk20a_instmem {
 	struct dma_attrs attrs;
 };
 
+static enum nvkm_memory_target
+gk20a_instobj_target(struct nvkm_memory *memory)
+{
+	return NVKM_MEM_TARGET_HOST;
+}
+
+static u64
+gk20a_instobj_addr(struct nvkm_memory *memory)
+{
+	return gk20a_instobj(memory)->mem.offset;
+
+}
+
+static u64
+gk20a_instobj_size(struct nvkm_memory *memory)
+{
+	return (u64)gk20a_instobj(memory)->mem.size << 12;
+}
+
+static void __iomem *
+gk20a_instobj_acquire(struct nvkm_memory *memory)
+{
+	struct gk20a_instmem *imem = gk20a_instobj(memory)->imem;
+	unsigned long flags;
+	spin_lock_irqsave(&imem->lock, flags);
+	imem->lock_flags = flags;
+	return NULL;
+}
+
+static void
+gk20a_instobj_release(struct nvkm_memory *memory)
+{
+	struct gk20a_instmem *imem = gk20a_instobj(memory)->imem;
+	spin_unlock_irqrestore(&imem->lock, imem->lock_flags);
+}
+
 /*
  * Use PRAMIN to read/write data and avoid coherency issues.
  * PRAMIN uses the GPU path and ensures data will always be coherent.
@@ -103,56 +141,57 @@ struct gk20a_instmem {
  */
 
 static u32
-gk20a_instobj_rd32(struct nvkm_object *object, u64 offset)
+gk20a_instobj_rd32(struct nvkm_memory *memory, u64 offset)
 {
-	struct gk20a_instmem *imem = (void *)nvkm_instmem(object);
-	struct gk20a_instobj *node = (void *)object;
+	struct gk20a_instobj *node = gk20a_instobj(memory);
+	struct gk20a_instmem *imem = node->imem;
 	struct nvkm_device *device = imem->base.subdev.device;
-	unsigned long flags;
-	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
-	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
+	u64 base = (node->mem.offset + offset) & 0xffffff00000ULL;
+	u64 addr = (node->mem.offset + offset) & 0x000000fffffULL;
 	u32 data;
 
-	spin_lock_irqsave(&imem->lock, flags);
 	if (unlikely(imem->addr != base)) {
 		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
 	data = nvkm_rd32(device, 0x700000 + addr);
-	spin_unlock_irqrestore(&imem->lock, flags);
 	return data;
 }
 
 static void
-gk20a_instobj_wr32(struct nvkm_object *object, u64 offset, u32 data)
+gk20a_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
 {
-	struct gk20a_instmem *imem = (void *)nvkm_instmem(object);
-	struct gk20a_instobj *node = (void *)object;
+	struct gk20a_instobj *node = gk20a_instobj(memory);
+	struct gk20a_instmem *imem = node->imem;
 	struct nvkm_device *device = imem->base.subdev.device;
-	unsigned long flags;
-	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
-	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
+	u64 base = (node->mem.offset + offset) & 0xffffff00000ULL;
+	u64 addr = (node->mem.offset + offset) & 0x000000fffffULL;
 
-	spin_lock_irqsave(&imem->lock, flags);
 	if (unlikely(imem->addr != base)) {
 		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
 	nvkm_wr32(device, 0x700000 + addr, data);
-	spin_unlock_irqrestore(&imem->lock, flags);
+}
+
+static void
+gk20a_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset)
+{
+	struct gk20a_instobj *node = gk20a_instobj(memory);
+	nvkm_vm_map_at(vma, offset, &node->mem);
 }
 
 static void
 gk20a_instobj_dtor_dma(struct gk20a_instobj *_node)
 {
 	struct gk20a_instobj_dma *node = (void *)_node;
-	struct gk20a_instmem *imem = (void *)nvkm_instmem(node);
+	struct gk20a_instmem *imem = _node->imem;
 	struct device *dev = nv_device_base(nv_device(imem));
 
 	if (unlikely(!node->cpuaddr))
 		return;
 
-	dma_free_attrs(dev, _node->mem->size << PAGE_SHIFT, node->cpuaddr,
+	dma_free_attrs(dev, _node->mem.size << PAGE_SHIFT, node->cpuaddr,
 		       node->handle, &imem->attrs);
 }
 
@@ -160,21 +199,21 @@ static void
 gk20a_instobj_dtor_iommu(struct gk20a_instobj *_node)
 {
 	struct gk20a_instobj_iommu *node = (void *)_node;
-	struct gk20a_instmem *imem = (void *)nvkm_instmem(node);
+	struct gk20a_instmem *imem = _node->imem;
 	struct nvkm_mm_node *r;
 	int i;
 
-	if (unlikely(list_empty(&_node->mem->regions)))
+	if (unlikely(list_empty(&_node->mem.regions)))
 		return;
 
-	r = list_first_entry(&_node->mem->regions, struct nvkm_mm_node,
+	r = list_first_entry(&_node->mem.regions, struct nvkm_mm_node,
 			     rl_entry);
 
 	/* clear bit 34 to unmap pages */
 	r->offset &= ~BIT(34 - imem->iommu_pgshift);
 
 	/* Unmap pages from GPU address space and free them */
-	for (i = 0; i < _node->mem->size; i++) {
+	for (i = 0; i < _node->mem.size; i++) {
 		iommu_unmap(imem->domain,
 			    (r->offset + i) << imem->iommu_pgshift, PAGE_SIZE);
 		__free_page(node->pages[i]);
@@ -186,36 +225,44 @@ gk20a_instobj_dtor_iommu(struct gk20a_instobj *_node)
 	mutex_unlock(imem->mm_mutex);
 }
 
-static void
-gk20a_instobj_dtor(struct nvkm_object *object)
+static void *
+gk20a_instobj_dtor(struct nvkm_memory *memory)
 {
-	struct gk20a_instobj *node = (void *)object;
-	struct gk20a_instmem *imem = (void *)nvkm_instmem(node);
+	struct gk20a_instobj *node = gk20a_instobj(memory);
+	struct gk20a_instmem *imem = node->imem;
 
 	if (imem->domain)
 		gk20a_instobj_dtor_iommu(node);
 	else
 		gk20a_instobj_dtor_dma(node);
 
-	nvkm_instobj_destroy(&node->base);
+	return node;
 }
 
+static const struct nvkm_memory_func
+gk20a_instobj_func = {
+	.dtor = gk20a_instobj_dtor,
+	.target = gk20a_instobj_target,
+	.addr = gk20a_instobj_addr,
+	.size = gk20a_instobj_size,
+	.acquire = gk20a_instobj_acquire,
+	.release = gk20a_instobj_release,
+	.rd32 = gk20a_instobj_rd32,
+	.wr32 = gk20a_instobj_wr32,
+	.map = gk20a_instobj_map,
+};
+
 static int
-gk20a_instobj_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
-		       struct nvkm_oclass *oclass, u32 npages, u32 align,
+gk20a_instobj_ctor_dma(struct gk20a_instmem *imem, u32 npages, u32 align,
 		       struct gk20a_instobj **_node)
 {
 	struct gk20a_instobj_dma *node;
-	struct gk20a_instmem *imem = (void *)nvkm_instmem(parent);
 	struct nvkm_subdev *subdev = &imem->base.subdev;
-	struct device *dev = nv_device_base(nv_device(parent));
-	int ret;
+	struct device *dev = subdev->device->dev;
 
-	ret = nvkm_instobj_create_(parent, engine, oclass, sizeof(*node),
-				   (void **)&node);
+	if (!(node = kzalloc(sizeof(*node), GFP_KERNEL)))
+		return -ENOMEM;
 	*_node = &node->base;
-	if (ret)
-		return ret;
 
 	node->cpuaddr = dma_alloc_attrs(dev, npages << PAGE_SHIFT,
 					&node->handle, GFP_KERNEL,
@@ -236,32 +283,28 @@ gk20a_instobj_ctor_dma(struct nvkm_object *parent, struct nvkm_object *engine,
 	node->r.offset = node->handle >> 12;
 	node->r.length = (npages << PAGE_SHIFT) >> 12;
 
-	node->base._mem.offset = node->handle;
+	node->base.mem.offset = node->handle;
 
-	INIT_LIST_HEAD(&node->base._mem.regions);
-	list_add_tail(&node->r.rl_entry, &node->base._mem.regions);
+	INIT_LIST_HEAD(&node->base.mem.regions);
+	list_add_tail(&node->r.rl_entry, &node->base.mem.regions);
 
 	return 0;
 }
 
 static int
-gk20a_instobj_ctor_iommu(struct nvkm_object *parent, struct nvkm_object *engine,
-			 struct nvkm_oclass *oclass, u32 npages, u32 align,
+gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align,
 			 struct gk20a_instobj **_node)
 {
 	struct gk20a_instobj_iommu *node;
-	struct gk20a_instmem *imem = (void *)nvkm_instmem(parent);
 	struct nvkm_subdev *subdev = &imem->base.subdev;
 	struct nvkm_mm_node *r;
 	int ret;
 	int i;
 
-	ret = nvkm_instobj_create_(parent, engine, oclass,
-				sizeof(*node) + sizeof(node->pages[0]) * npages,
-				(void **)&node);
+	if (!(node = kzalloc(sizeof(*node) +
+			     sizeof( node->pages[0]) * npages, GFP_KERNEL)))
+		return -ENOMEM;
 	*_node = &node->base;
-	if (ret)
-		return ret;
 
 	/* Allocate backing memory */
 	for (i = 0; i < npages; i++) {
@@ -305,10 +348,10 @@ gk20a_instobj_ctor_iommu(struct nvkm_object *parent, struct nvkm_object *engine,
 	/* Bit 34 tells that an address is to be resolved through the IOMMU */
 	r->offset |= BIT(34 - imem->iommu_pgshift);
 
-	node->base._mem.offset = ((u64)r->offset) << imem->iommu_pgshift;
+	node->base.mem.offset = ((u64)r->offset) << imem->iommu_pgshift;
 
-	INIT_LIST_HEAD(&node->base._mem.regions);
-	list_add_tail(&r->rl_entry, &node->base._mem.regions);
+	INIT_LIST_HEAD(&node->base.mem.regions);
+	list_add_tail(&r->rl_entry, &node->base.mem.regions);
 
 	return 0;
 
@@ -325,64 +368,45 @@ free_pages:
 }
 
 static int
-gk20a_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-		   struct nvkm_oclass *oclass, void *data, u32 _size,
-		   struct nvkm_object **pobject)
+gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
+		  struct nvkm_memory **pmemory)
 {
-	struct nvkm_instobj_args *args = data;
-	struct gk20a_instmem *imem = (void *)nvkm_instmem(parent);
+	struct gk20a_instmem *imem = gk20a_instmem(base);
 	struct gk20a_instobj *node;
 	struct nvkm_subdev *subdev = &imem->base.subdev;
-	u32 size, align;
 	int ret;
 
 	nvkm_debug(subdev, "%s (%s): size: %x align: %x\n", __func__,
-		   imem->domain ? "IOMMU" : "DMA", args->size, args->align);
+		   imem->domain ? "IOMMU" : "DMA", size, align);
 
 	/* Round size and align to page bounds */
-	size = max(roundup(args->size, PAGE_SIZE), PAGE_SIZE);
-	align = max(roundup(args->align, PAGE_SIZE), PAGE_SIZE);
+	size = max(roundup(size, PAGE_SIZE), PAGE_SIZE);
+	align = max(roundup(align, PAGE_SIZE), PAGE_SIZE);
 
 	if (imem->domain)
-		ret = gk20a_instobj_ctor_iommu(parent, engine, oclass,
-					      size >> PAGE_SHIFT, align, &node);
+		ret = gk20a_instobj_ctor_iommu(imem, size >> PAGE_SHIFT,
+					       align, &node);
 	else
-		ret = gk20a_instobj_ctor_dma(parent, engine, oclass,
-					     size >> PAGE_SHIFT, align, &node);
-	*pobject = nv_object(node);
+		ret = gk20a_instobj_ctor_dma(imem, size >> PAGE_SHIFT,
+					     align, &node);
 	if (ret)
 		return ret;
+	*pmemory = &node->memory;
 
-	node->mem = &node->_mem;
+	nvkm_memory_ctor(&gk20a_instobj_func, &node->memory);
+	node->imem = imem;
 
 	/* present memory for being mapped using small pages */
-	node->mem->size = size >> 12;
-	node->mem->memtype = 0;
-	node->mem->page_shift = 12;
-
-	node->base.addr = node->mem->offset;
-	node->base.size = size;
+	node->mem.size = size >> 12;
+	node->mem.memtype = 0;
+	node->mem.page_shift = 12;
 
 	nvkm_debug(subdev, "alloc size: 0x%x, align: 0x%x, gaddr: 0x%llx\n",
-		   size, align, node->mem->offset);
+		   size, align, node->mem.offset);
 
 	return 0;
 }
 
-static struct nvkm_instobj_impl
-gk20a_instobj_oclass = {
-	.base.ofuncs = &(struct nvkm_ofuncs) {
-		.ctor = gk20a_instobj_ctor,
-		.dtor = gk20a_instobj_dtor,
-		.init = _nvkm_instobj_init,
-		.fini = _nvkm_instobj_fini,
-		.rd32 = gk20a_instobj_rd32,
-		.wr32 = gk20a_instobj_wr32,
-	},
-};
-
-
-
 static int
 gk20a_instmem_fini(struct nvkm_object *object, bool suspend)
 {
@@ -440,5 +464,7 @@ gk20a_instmem_oclass = &(struct nvkm_instmem_impl) {
 		.init = _nvkm_instmem_init,
 		.fini = gk20a_instmem_fini,
 	},
-	.instobj = &gk20a_instobj_oclass.base,
+	.memory_new = gk20a_instobj_new,
+	.persistent = true,
+	.zero = false,
 }.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
index 8ba95f366e2f..c499e485373b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
@@ -21,83 +21,119 @@
  *
  * Authors: Ben Skeggs
  */
-#include "nv04.h"
+#define nv04_instmem(p) container_of((p), struct nv04_instmem, base)
+#include "priv.h"
 
+#include <core/memory.h>
 #include <core/ramht.h>
 
+struct nv04_instmem {
+	struct nvkm_instmem base;
+	struct nvkm_mm heap;
+};
+
 /******************************************************************************
  * instmem object implementation
  *****************************************************************************/
+#define nv04_instobj(p) container_of((p), struct nv04_instobj, memory)
 
-static u32
-nv04_instobj_rd32(struct nvkm_object *object, u64 addr)
+struct nv04_instobj {
+	struct nvkm_memory memory;
+	struct nv04_instmem *imem;
+	struct nvkm_mm_node *node;
+};
+
+static enum nvkm_memory_target
+nv04_instobj_target(struct nvkm_memory *memory)
+{
+	return NVKM_MEM_TARGET_INST;
+}
+
+static u64
+nv04_instobj_addr(struct nvkm_memory *memory)
+{
+	return nv04_instobj(memory)->node->offset;
+}
+
+static u64
+nv04_instobj_size(struct nvkm_memory *memory)
+{
+	return nv04_instobj(memory)->node->length;
+}
+
+static void __iomem *
+nv04_instobj_acquire(struct nvkm_memory *memory)
 {
-	struct nvkm_instmem *imem = nvkm_instmem(object);
-	struct nv04_instobj *node = (void *)object;
-	return imem->func->rd32(imem, node->mem->offset + addr);
+	struct nv04_instobj *iobj = nv04_instobj(memory);
+	struct nvkm_device *device = iobj->imem->base.subdev.device;
+	return device->pri + 0x700000 + iobj->node->offset;
 }
 
 static void
-nv04_instobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
+nv04_instobj_release(struct nvkm_memory *memory)
 {
-	struct nvkm_instmem *imem = nvkm_instmem(object);
-	struct nv04_instobj *node = (void *)object;
-	imem->func->wr32(imem, node->mem->offset + addr, data);
+}
+
+static u32
+nv04_instobj_rd32(struct nvkm_memory *memory, u64 offset)
+{
+	struct nv04_instobj *iobj = nv04_instobj(memory);
+	struct nvkm_device *device = iobj->imem->base.subdev.device;
+	return nvkm_rd32(device, 0x700000 + iobj->node->offset + offset);
 }
 
 static void
-nv04_instobj_dtor(struct nvkm_object *object)
+nv04_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
 {
-	struct nv04_instmem *imem = (void *)nvkm_instmem(object);
-	struct nv04_instobj *node = (void *)object;
-	mutex_lock(&imem->base.subdev.mutex);
-	nvkm_mm_free(&imem->heap, &node->mem);
-	mutex_unlock(&imem->base.subdev.mutex);
-	nvkm_instobj_destroy(&node->base);
+	struct nv04_instobj *iobj = nv04_instobj(memory);
+	struct nvkm_device *device = iobj->imem->base.subdev.device;
+	nvkm_wr32(device, 0x700000 + iobj->node->offset + offset, data);
 }
 
+static void *
+nv04_instobj_dtor(struct nvkm_memory *memory)
+{
+	struct nv04_instobj *iobj = nv04_instobj(memory);
+	mutex_lock(&iobj->imem->base.subdev.mutex);
+	nvkm_mm_free(&iobj->imem->heap, &iobj->node);
+	mutex_unlock(&iobj->imem->base.subdev.mutex);
+	return iobj;
+}
+
+static const struct nvkm_memory_func
+nv04_instobj_func = {
+	.dtor = nv04_instobj_dtor,
+	.target = nv04_instobj_target,
+	.size = nv04_instobj_size,
+	.addr = nv04_instobj_addr,
+	.acquire = nv04_instobj_acquire,
+	.release = nv04_instobj_release,
+	.rd32 = nv04_instobj_rd32,
+	.wr32 = nv04_instobj_wr32,
+};
+
 static int
-nv04_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-		  struct nvkm_oclass *oclass, void *data, u32 size,
-		  struct nvkm_object **pobject)
+nv04_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
+		 struct nvkm_memory **pmemory)
 {
-	struct nv04_instmem *imem = (void *)nvkm_instmem(parent);
-	struct nv04_instobj *node;
-	struct nvkm_instobj_args *args = data;
+	struct nv04_instmem *imem = nv04_instmem(base);
+	struct nv04_instobj *iobj;
 	int ret;
 
-	if (!args->align)
-		args->align = 1;
+	if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL)))
+		return -ENOMEM;
+	*pmemory = &iobj->memory;
 
-	ret = nvkm_instobj_create(parent, engine, oclass, &node);
-	*pobject = nv_object(node);
-	if (ret)
-		return ret;
+	nvkm_memory_ctor(&nv04_instobj_func, &iobj->memory);
+	iobj->imem = imem;
 
 	mutex_lock(&imem->base.subdev.mutex);
-	ret = nvkm_mm_head(&imem->heap, 0, 1, args->size, args->size,
-			   args->align, &node->mem);
+	ret = nvkm_mm_head(&imem->heap, 0, 1, size, size,
+			   align ? align : 1, &iobj->node);
 	mutex_unlock(&imem->base.subdev.mutex);
-	if (ret)
-		return ret;
-
-	node->base.addr = node->mem->offset;
-	node->base.size = node->mem->length;
-	return 0;
+	return ret;
 }
 
-struct nvkm_instobj_impl
-nv04_instobj_oclass = {
-	.base.ofuncs = &(struct nvkm_ofuncs) {
-		.ctor = nv04_instobj_ctor,
-		.dtor = nv04_instobj_dtor,
-		.init = _nvkm_instobj_init,
-		.fini = _nvkm_instobj_fini,
-		.rd32 = nv04_instobj_rd32,
-		.wr32 = nv04_instobj_wr32,
-	},
-};
-
 /******************************************************************************
  * instmem subdev implementation
  *****************************************************************************/
@@ -114,17 +150,15 @@ nv04_instmem_wr32(struct nvkm_instmem *imem, u32 addr, u32 data)
 	nvkm_wr32(imem->subdev.device, 0x700000 + addr, data);
 }
 
-void
+static void
 nv04_instmem_dtor(struct nvkm_object *object)
 {
 	struct nv04_instmem *imem = (void *)object;
-	nvkm_gpuobj_ref(NULL, &imem->ramfc);
-	nvkm_gpuobj_ref(NULL, &imem->ramro);
-	nvkm_ramht_ref(NULL, &imem->ramht);
-	nvkm_gpuobj_ref(NULL, &imem->vbios);
+	nvkm_gpuobj_ref(NULL, &imem->base.ramfc);
+	nvkm_gpuobj_ref(NULL, &imem->base.ramro);
+	nvkm_ramht_ref(NULL, &imem->base.ramht);
+	nvkm_gpuobj_ref(NULL, &imem->base.vbios);
 	nvkm_mm_fini(&imem->heap);
-	if (imem->iomem)
-		iounmap(imem->iomem);
 	nvkm_instmem_destroy(&imem->base);
 }
 
@@ -158,24 +192,26 @@ nv04_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	/* 0x00000-0x10000: reserve for probable vbios image */
 	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x10000, 0, 0,
-			      &imem->vbios);
+			      &imem->base.vbios);
 	if (ret)
 		return ret;
 
 	/* 0x10000-0x18000: reserve for RAMHT */
-	ret = nvkm_ramht_new(nv_object(imem), NULL, 0x08000, 0, &imem->ramht);
+	ret = nvkm_ramht_new(nv_object(imem), NULL, 0x08000, 0,
+			     &imem->base.ramht);
 	if (ret)
 		return ret;
 
 	/* 0x18000-0x18800: reserve for RAMFC (enough for 32 nv30 channels) */
 	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x00800, 0,
-			      NVOBJ_FLAG_ZERO_ALLOC, &imem->ramfc);
+			      NVOBJ_FLAG_ZERO_ALLOC,
+			      &imem->base.ramfc);
 	if (ret)
 		return ret;
 
 	/* 0x18800-0x18a00: reserve for RAMRO */
 	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x00200, 0, 0,
-			      &imem->ramro);
+			      &imem->base.ramro);
 	if (ret)
 		return ret;
 
@@ -191,5 +227,7 @@ nv04_instmem_oclass = &(struct nvkm_instmem_impl) {
 		.init = _nvkm_instmem_init,
 		.fini = _nvkm_instmem_fini,
 	},
-	.instobj = &nv04_instobj_oclass.base,
+	.memory_new = nv04_instobj_new,
+	.persistent = false,
+	.zero = false,
 }.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h
deleted file mode 100644
index 6065e34e2f0d..000000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __NV04_INSTMEM_H__
-#define __NV04_INSTMEM_H__
-#include "priv.h"
-
-#include <core/mm.h>
-
-extern struct nvkm_instobj_impl nv04_instobj_oclass;
-
-struct nv04_instmem {
-	struct nvkm_instmem base;
-
-	void __iomem *iomem;
-	struct nvkm_mm heap;
-
-	struct nvkm_gpuobj *vbios;
-	struct nvkm_ramht  *ramht;
-	struct nvkm_gpuobj *ramro;
-	struct nvkm_gpuobj *ramfc;
-};
-
-static inline struct nv04_instmem *
-nv04_instmem(void *obj)
-{
-	return (void *)nvkm_instmem(obj);
-}
-
-struct nv04_instobj {
-	struct nvkm_instobj base;
-	struct nvkm_mm_node *mem;
-};
-
-void nv04_instmem_dtor(struct nvkm_object *);
-
-int nv04_instmem_alloc(struct nvkm_instmem *, struct nvkm_object *,
-		       u32 size, u32 align, struct nvkm_object **pobject);
-#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
index c645e0261530..3ac55481cc97 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
@@ -21,11 +21,118 @@
  *
  * Authors: Ben Skeggs
  */
-#include "nv04.h"
+#define nv40_instmem(p) container_of((p), struct nv40_instmem, base)
+#include "priv.h"
 
+#include <core/memory.h>
 #include <core/ramht.h>
 #include <engine/gr/nv40.h>
 
+struct nv40_instmem {
+	struct nvkm_instmem base;
+	struct nvkm_mm heap;
+	void __iomem *iomem;
+};
+
+/******************************************************************************
+ * instmem object implementation
+ *****************************************************************************/
+#define nv40_instobj(p) container_of((p), struct nv40_instobj, memory)
+
+struct nv40_instobj {
+	struct nvkm_memory memory;
+	struct nv40_instmem *imem;
+	struct nvkm_mm_node *node;
+};
+
+static enum nvkm_memory_target
+nv40_instobj_target(struct nvkm_memory *memory)
+{
+	return NVKM_MEM_TARGET_INST;
+}
+
+static u64
+nv40_instobj_addr(struct nvkm_memory *memory)
+{
+	return nv40_instobj(memory)->node->offset;
+}
+
+static u64
+nv40_instobj_size(struct nvkm_memory *memory)
+{
+	return nv40_instobj(memory)->node->length;
+}
+
+static void __iomem *
+nv40_instobj_acquire(struct nvkm_memory *memory)
+{
+	struct nv40_instobj *iobj = nv40_instobj(memory);
+	return iobj->imem->iomem + iobj->node->offset;
+}
+
+static void
+nv40_instobj_release(struct nvkm_memory *memory)
+{
+}
+
+static u32
+nv40_instobj_rd32(struct nvkm_memory *memory, u64 offset)
+{
+	struct nv40_instobj *iobj = nv40_instobj(memory);
+	return ioread32_native(iobj->imem->iomem + iobj->node->offset + offset);
+}
+
+static void
+nv40_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
+{
+	struct nv40_instobj *iobj = nv40_instobj(memory);
+	iowrite32_native(data, iobj->imem->iomem + iobj->node->offset + offset);
+}
+
+static void *
+nv40_instobj_dtor(struct nvkm_memory *memory)
+{
+	struct nv40_instobj *iobj = nv40_instobj(memory);
+	mutex_lock(&iobj->imem->base.subdev.mutex);
+	nvkm_mm_free(&iobj->imem->heap, &iobj->node);
+	mutex_unlock(&iobj->imem->base.subdev.mutex);
+	return iobj;
+}
+
+static const struct nvkm_memory_func
+nv40_instobj_func = {
+	.dtor = nv40_instobj_dtor,
+	.target = nv40_instobj_target,
+	.size = nv40_instobj_size,
+	.addr = nv40_instobj_addr,
+	.acquire = nv40_instobj_acquire,
+	.release = nv40_instobj_release,
+	.rd32 = nv40_instobj_rd32,
+	.wr32 = nv40_instobj_wr32,
+};
+
+static int
+nv40_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
+		 struct nvkm_memory **pmemory)
+{
+	struct nv40_instmem *imem = nv40_instmem(base);
+	struct nv40_instobj *iobj;
+	int ret;
+
+	if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL)))
+		return -ENOMEM;
+	*pmemory = &iobj->memory;
+
+	nvkm_memory_ctor(&nv40_instobj_func, &iobj->memory);
+	iobj->imem = imem;
+
+	mutex_lock(&imem->base.subdev.mutex);
+	ret = nvkm_mm_head(&imem->heap, 0, 1, size, size,
+			   align ? align : 1, &iobj->node);
+	mutex_unlock(&imem->base.subdev.mutex);
+	return ret;
+}
+
 /******************************************************************************
  * instmem subdev implementation
  *****************************************************************************/
@@ -33,17 +140,31 @@
 static u32
 nv40_instmem_rd32(struct nvkm_instmem *obj, u32 addr)
 {
-	struct nv04_instmem *imem = container_of(obj, typeof(*imem), base);
+	struct nv40_instmem *imem = container_of(obj, typeof(*imem), base);
 	return ioread32_native(imem->iomem + addr);
 }
 
 static void
 nv40_instmem_wr32(struct nvkm_instmem *obj, u32 addr, u32 data)
 {
-	struct nv04_instmem *imem = container_of(obj, typeof(*imem), base);
+	struct nv40_instmem *imem = container_of(obj, typeof(*imem), base);
 	iowrite32_native(data, imem->iomem + addr);
 }
 
+static void
+nv40_instmem_dtor(struct nvkm_object *object)
+{
+	struct nv40_instmem *imem = (void *)object;
+	nvkm_gpuobj_ref(NULL, &imem->base.ramfc);
+	nvkm_gpuobj_ref(NULL, &imem->base.ramro);
+	nvkm_ramht_ref(NULL, &imem->base.ramht);
+	nvkm_gpuobj_ref(NULL, &imem->base.vbios);
+	nvkm_mm_fini(&imem->heap);
+	if (imem->iomem)
+		iounmap(imem->iomem);
+	nvkm_instmem_destroy(&imem->base);
+}
+
 static const struct nvkm_instmem_func
 nv40_instmem_func = {
 	.rd32 = nv40_instmem_rd32,
@@ -56,7 +177,7 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		  struct nvkm_object **pobject)
 {
 	struct nvkm_device *device = (void *)parent;
-	struct nv04_instmem *imem;
+	struct nv40_instmem *imem;
 	int ret, bar, vs;
 
 	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
@@ -86,7 +207,7 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	vs = hweight8((nvkm_rd32(device, 0x001540) & 0x0000ff00) >> 8);
 	if      (device->chipset == 0x40) imem->base.reserved = 0x6aa0 * vs;
 	else if (device->chipset  < 0x43) imem->base.reserved = 0x4f00 * vs;
-	else if (nv44_gr_class(imem))  imem->base.reserved = 0x4980 * vs;
+	else if (nv44_gr_class(imem))     imem->base.reserved = 0x4980 * vs;
 	else				  imem->base.reserved = 0x4a40 * vs;
 	imem->base.reserved += 16 * 1024;
 	imem->base.reserved *= 32;		/* per-channel */
@@ -101,12 +222,13 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	/* 0x00000-0x10000: reserve for probable vbios image */
 	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x10000, 0, 0,
-			      &imem->vbios);
+			      &imem->base.vbios);
 	if (ret)
 		return ret;
 
 	/* 0x10000-0x18000: reserve for RAMHT */
-	ret = nvkm_ramht_new(nv_object(imem), NULL, 0x08000, 0, &imem->ramht);
+	ret = nvkm_ramht_new(nv_object(imem), NULL, 0x08000, 0,
+			     &imem->base.ramht);
 	if (ret)
 		return ret;
 
@@ -114,7 +236,7 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	 * 0x18200-0x20000: padding
 	 */
 	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x08000, 0, 0,
-			      &imem->ramro);
+			      &imem->base.ramro);
 	if (ret)
 		return ret;
 
@@ -122,7 +244,7 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	 * 0x21000-0x40000: padding and some unknown crap
 	 */
 	ret = nvkm_gpuobj_new(nv_object(imem), NULL, 0x20000, 0,
-			      NVOBJ_FLAG_ZERO_ALLOC, &imem->ramfc);
+			      NVOBJ_FLAG_ZERO_ALLOC, &imem->base.ramfc);
 	if (ret)
 		return ret;
 
@@ -134,9 +256,11 @@ nv40_instmem_oclass = &(struct nvkm_instmem_impl) {
 	.base.handle = NV_SUBDEV(INSTMEM, 0x40),
 	.base.ofuncs = &(struct nvkm_ofuncs) {
 		.ctor = nv40_instmem_ctor,
-		.dtor = nv04_instmem_dtor,
+		.dtor = nv40_instmem_dtor,
 		.init = _nvkm_instmem_init,
 		.fini = _nvkm_instmem_fini,
 	},
-	.instobj = &nv04_instobj_oclass.base,
+	.memory_new = nv40_instobj_new,
+	.persistent = false,
+	.zero = false,
 }.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
index 4f6354df538a..535a8f9c23ce 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -21,115 +21,201 @@
  *
  * Authors: Ben Skeggs
  */
+#define nv50_instmem(p) container_of((p), struct nv50_instmem, base)
 #include "priv.h"
 
+#include <core/memory.h>
+#include <subdev/bar.h>
 #include <subdev/fb.h>
+#include <subdev/mmu.h>
 
 struct nv50_instmem {
 	struct nvkm_instmem base;
+	unsigned long lock_flags;
 	spinlock_t lock;
 	u64 addr;
 };
 
+/******************************************************************************
+ * instmem object implementation
+ *****************************************************************************/
+#define nv50_instobj(p) container_of((p), struct nv50_instobj, memory)
+
 struct nv50_instobj {
-	struct nvkm_instobj base;
+	struct nvkm_memory memory;
+	struct nv50_instmem *imem;
 	struct nvkm_mem *mem;
+	struct nvkm_vma bar;
+	void *map;
 };
 
-/******************************************************************************
- * instmem object implementation
- *****************************************************************************/
+static enum nvkm_memory_target
+nv50_instobj_target(struct nvkm_memory *memory)
+{
+	return NVKM_MEM_TARGET_VRAM;
+}
+
+static u64
+nv50_instobj_addr(struct nvkm_memory *memory)
+{
+	return nv50_instobj(memory)->mem->offset;
+}
+
+static u64
+nv50_instobj_size(struct nvkm_memory *memory)
+{
+	return (u64)nv50_instobj(memory)->mem->size << NVKM_RAM_MM_SHIFT;
+}
+
+static void
+nv50_instobj_boot(struct nvkm_memory *memory, struct nvkm_vm *vm)
+{
+	struct nv50_instobj *iobj = nv50_instobj(memory);
+	struct nvkm_subdev *subdev = &iobj->imem->base.subdev;
+	struct nvkm_device *device = subdev->device;
+	u64 size = nvkm_memory_size(memory);
+	void __iomem *map;
+	int ret;
+
+	iobj->map = ERR_PTR(-ENOMEM);
+
+	ret = nvkm_vm_get(vm, size, 12, NV_MEM_ACCESS_RW, &iobj->bar);
+	if (ret == 0) {
+		map = ioremap(nv_device_resource_start(device, 3) +
+			      (u32)iobj->bar.offset, size);
+		if (map) {
+			nvkm_memory_map(memory, &iobj->bar, 0);
+			iobj->map = map;
+		} else {
+			nvkm_warn(subdev, "PRAMIN ioremap failed\n");
+			nvkm_vm_put(&iobj->bar);
+		}
+	} else {
+		nvkm_warn(subdev, "PRAMIN exhausted\n");
+	}
+}
+
+static void
+nv50_instobj_release(struct nvkm_memory *memory)
+{
+	struct nv50_instmem *imem = nv50_instobj(memory)->imem;
+	spin_unlock_irqrestore(&imem->lock, imem->lock_flags);
+}
+
+static void __iomem *
+nv50_instobj_acquire(struct nvkm_memory *memory)
+{
+	struct nv50_instobj *iobj = nv50_instobj(memory);
+	struct nv50_instmem *imem = iobj->imem;
+	struct nvkm_bar *bar = imem->base.subdev.device->bar;
+	struct nvkm_vm *vm;
+	unsigned long flags;
+
+	if (!iobj->map && bar && bar->kmap && (vm = bar->kmap(bar)))
+		nvkm_memory_boot(memory, vm);
+	if (!IS_ERR_OR_NULL(iobj->map))
+		return iobj->map;
+
+	spin_lock_irqsave(&imem->lock, flags);
+	imem->lock_flags = flags;
+	return NULL;
+}
 
 static u32
-nv50_instobj_rd32(struct nvkm_object *object, u64 offset)
+nv50_instobj_rd32(struct nvkm_memory *memory, u64 offset)
 {
-	struct nv50_instmem *imem = (void *)nvkm_instmem(object);
-	struct nv50_instobj *node = (void *)object;
+	struct nv50_instobj *iobj = nv50_instobj(memory);
+	struct nv50_instmem *imem = iobj->imem;
 	struct nvkm_device *device = imem->base.subdev.device;
-	unsigned long flags;
-	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
-	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
+	u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL;
+	u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL;
 	u32 data;
 
-	spin_lock_irqsave(&imem->lock, flags);
 	if (unlikely(imem->addr != base)) {
 		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
 	data = nvkm_rd32(device, 0x700000 + addr);
-	spin_unlock_irqrestore(&imem->lock, flags);
 	return data;
 }
 
 static void
-nv50_instobj_wr32(struct nvkm_object *object, u64 offset, u32 data)
+nv50_instobj_wr32(struct nvkm_memory *memory, u64 offset, u32 data)
 {
-	struct nv50_instmem *imem = (void *)nvkm_instmem(object);
-	struct nv50_instobj *node = (void *)object;
+	struct nv50_instobj *iobj = nv50_instobj(memory);
+	struct nv50_instmem *imem = iobj->imem;
 	struct nvkm_device *device = imem->base.subdev.device;
-	unsigned long flags;
-	u64 base = (node->mem->offset + offset) & 0xffffff00000ULL;
-	u64 addr = (node->mem->offset + offset) & 0x000000fffffULL;
+	u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL;
+	u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL;
 
-	spin_lock_irqsave(&imem->lock, flags);
 	if (unlikely(imem->addr != base)) {
 		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
 	nvkm_wr32(device, 0x700000 + addr, data);
-	spin_unlock_irqrestore(&imem->lock, flags);
 }
 
 static void
-nv50_instobj_dtor(struct nvkm_object *object)
+nv50_instobj_map(struct nvkm_memory *memory, struct nvkm_vma *vma, u64 offset)
 {
-	struct nv50_instobj *node = (void *)object;
-	struct nvkm_ram *ram = nvkm_fb(object)->ram;
-	ram->func->put(ram, &node->mem);
-	nvkm_instobj_destroy(&node->base);
+	struct nv50_instobj *iobj = nv50_instobj(memory);
+	nvkm_vm_map_at(vma, offset, iobj->mem);
 }
 
+static void *
+nv50_instobj_dtor(struct nvkm_memory *memory)
+{
+	struct nv50_instobj *iobj = nv50_instobj(memory);
+	struct nvkm_ram *ram = iobj->imem->base.subdev.device->fb->ram;
+	if (!IS_ERR_OR_NULL(iobj->map)) {
+		nvkm_vm_put(&iobj->bar);
+		iounmap(iobj->map);
+	}
+	ram->func->put(ram, &iobj->mem);
+	return iobj;
+}
+
+static const struct nvkm_memory_func
+nv50_instobj_func = {
+	.dtor = nv50_instobj_dtor,
+	.target = nv50_instobj_target,
+	.size = nv50_instobj_size,
+	.addr = nv50_instobj_addr,
+	.boot = nv50_instobj_boot,
+	.acquire = nv50_instobj_acquire,
+	.release = nv50_instobj_release,
+	.rd32 = nv50_instobj_rd32,
+	.wr32 = nv50_instobj_wr32,
+	.map = nv50_instobj_map,
+};
+
 static int
-nv50_instobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-		  struct nvkm_oclass *oclass, void *data, u32 size,
-		  struct nvkm_object **pobject)
+nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
+		 struct nvkm_memory **pmemory)
 {
-	struct nvkm_ram *ram = nvkm_fb(parent)->ram;
-	struct nvkm_instobj_args *args = data;
-	struct nv50_instobj *node;
+	struct nv50_instmem *imem = nv50_instmem(base);
+	struct nv50_instobj *iobj;
+	struct nvkm_ram *ram = imem->base.subdev.device->fb->ram;
 	int ret;
 
-	args->size  = max((args->size  + 4095) & ~4095, (u32)4096);
-	args->align = max((args->align + 4095) & ~4095, (u32)4096);
+	if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL)))
+		return -ENOMEM;
+	*pmemory = &iobj->memory;
 
-	ret = nvkm_instobj_create(parent, engine, oclass, &node);
-	*pobject = nv_object(node);
-	if (ret)
-		return ret;
+	nvkm_memory_ctor(&nv50_instobj_func, &iobj->memory);
+	iobj->imem = imem;
+
+	size  = max((size  + 4095) & ~4095, (u32)4096);
+	align = max((align + 4095) & ~4095, (u32)4096);
 
-	ret = ram->func->get(ram, args->size, args->align, 0, 0x800,
-			     &node->mem);
+	ret = ram->func->get(ram, size, align, 0, 0x800, &iobj->mem);
 	if (ret)
 		return ret;
 
-	node->base.addr = node->mem->offset;
-	node->base.size = node->mem->size << 12;
-	node->mem->page_shift = 12;
+	iobj->mem->page_shift = 12;
 	return 0;
 }
 
-static struct nvkm_instobj_impl
-nv50_instobj_oclass = {
-	.base.ofuncs = &(struct nvkm_ofuncs) {
-		.ctor = nv50_instobj_ctor,
-		.dtor = nv50_instobj_dtor,
-		.init = _nvkm_instobj_init,
-		.fini = _nvkm_instobj_fini,
-		.rd32 = nv50_instobj_rd32,
-		.wr32 = nv50_instobj_wr32,
-	},
-};
-
 /******************************************************************************
  * instmem subdev implementation
  *****************************************************************************/
@@ -168,5 +254,7 @@ nv50_instmem_oclass = &(struct nvkm_instmem_impl) {
 		.init = _nvkm_instmem_init,
 		.fini = nv50_instmem_fini,
 	},
-	.instobj = &nv50_instobj_oclass.base,
+	.memory_new = nv50_instobj_new,
+	.persistent = false,
+	.zero = false,
 }.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
index 819f615782cf..2b6d73005767 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
@@ -2,35 +2,12 @@
 #define __NVKM_INSTMEM_PRIV_H__
 #include <subdev/instmem.h>
 
-struct nvkm_instobj_impl {
-	struct nvkm_oclass base;
-};
-
-struct nvkm_instobj_args {
-	u32 size;
-	u32 align;
-};
-
-#define nvkm_instobj_create(p,e,o,d)                                        \
-	nvkm_instobj_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nvkm_instobj_destroy(p) ({                                          \
-	struct nvkm_instobj *iobj = (p);                                    \
-	_nvkm_instobj_dtor(nv_object(iobj));                                \
-})
-#define nvkm_instobj_init(p)                                                \
-	_nvkm_object_init(&(p)->base)
-#define nvkm_instobj_fini(p,s)                                              \
-	_nvkm_object_fini(&(p)->base, (s))
-
-int  nvkm_instobj_create_(struct nvkm_object *, struct nvkm_object *,
-			     struct nvkm_oclass *, int, void **);
-void _nvkm_instobj_dtor(struct nvkm_object *);
-#define _nvkm_instobj_init _nvkm_object_init
-#define _nvkm_instobj_fini _nvkm_object_fini
-
 struct nvkm_instmem_impl {
 	struct nvkm_oclass base;
-	struct nvkm_oclass *instobj;
+	int (*memory_new)(struct nvkm_instmem *, u32 size, u32 align,
+			  bool zero, struct nvkm_memory **);
+	bool persistent;
+	bool zero;
 };
 
 #define nvkm_instmem_create(p,e,o,d)                                        \
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
index e81d3170325f..35b6d33f6669 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
@@ -338,6 +338,25 @@ nvkm_vm_put(struct nvkm_vma *vma)
 	nvkm_vm_ref(NULL, &vma->vm, NULL);
 }
 
+int
+nvkm_vm_boot(struct nvkm_vm *vm, u64 size)
+{
+	struct nvkm_mmu *mmu = vm->mmu;
+	struct nvkm_gpuobj *pgt;
+	int ret;
+
+	ret = nvkm_gpuobj_new(nv_object(mmu), NULL,
+			      (size >> mmu->spg_shift) * 8, 0x1000,
+			      NVOBJ_FLAG_ZERO_ALLOC, &pgt);
+	if (ret == 0) {
+		vm->pgt[0].refcount[0] = 1;
+		vm->pgt[0].obj[0] = pgt;
+		nvkm_memory_boot(pgt->memory, vm);
+	}
+
+	return ret;
+}
+
 int
 nvkm_vm_create(struct nvkm_mmu *mmu, u64 offset, u64 length, u64 mm_offset,
 	       u32 block, struct lock_class_key *key, struct nvkm_vm **pvm)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c
index e801e57946ad..12d6ef461c62 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gf100.c
@@ -22,7 +22,6 @@
  * Authors: Ben Skeggs
  */
 #include <subdev/mmu.h>
-#include <subdev/bar.h>
 #include <subdev/fb.h>
 #include <subdev/ltc.h>
 #include <subdev/timer.h>
@@ -163,12 +162,9 @@ gf100_vm_flush(struct nvkm_vm *vm)
 {
 	struct nvkm_mmu *mmu = (void *)vm->mmu;
 	struct nvkm_device *device = mmu->subdev.device;
-	struct nvkm_bar *bar = device->bar;
 	struct nvkm_vm_pgd *vpgd;
 	u32 type;
 
-	bar->flush(bar);
-
 	type = 0x00000001; /* PAGE_ALL */
 	if (atomic_read(&vm->engref[NVDEV_SUBDEV_BAR]))
 		type |= 0x00000004; /* HUB_ONLY */
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c
index b87fef9ee198..cd63b9288507 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv50.c
@@ -22,7 +22,6 @@
  * Authors: Ben Skeggs
  */
 #include <subdev/mmu.h>
-#include <subdev/bar.h>
 #include <subdev/fb.h>
 #include <subdev/timer.h>
 
@@ -156,12 +155,9 @@ nv50_vm_flush(struct nvkm_vm *vm)
 	struct nvkm_mmu *mmu = (void *)vm->mmu;
 	struct nvkm_subdev *subdev = &mmu->subdev;
 	struct nvkm_device *device = subdev->device;
-	struct nvkm_bar *bar = device->bar;
 	struct nvkm_engine *engine;
 	int i, vme;
 
-	bar->flush(bar);
-
 	mutex_lock(&subdev->mutex);
 	for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
 		if (!atomic_read(&vm->engref[i]))
-- 
cgit v1.2.3-70-g09d2


From b7a2bc1886d00f5f1358079e1e6f4979006a4ed6 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 14:54:20 +1000
Subject: drm/nouveau/imem: convert to new-style nvkm_subdev

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 .../gpu/drm/nouveau/include/nvkm/subdev/instmem.h  |  35 ++----
 drivers/gpu/drm/nouveau/nvkm/core/memory.c         |   2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/device/base.c  | 138 ++++++++++-----------
 drivers/gpu/drm/nouveau/nvkm/engine/device/gf100.c |   9 --
 drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c |   8 --
 drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c |   4 -
 drivers/gpu/drm/nouveau/nvkm/engine/device/nv04.c  |   2 -
 drivers/gpu/drm/nouveau/nvkm/engine/device/nv10.c  |   8 --
 drivers/gpu/drm/nouveau/nvkm/engine/device/nv20.c  |   4 -
 drivers/gpu/drm/nouveau/nvkm/engine/device/nv30.c  |   5 -
 drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c  |  16 ---
 drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c  |  14 ---
 drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c      |   3 +-
 drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h      |   4 +-
 drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c    |   6 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c |  91 +++++++++-----
 .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c    |  54 ++++----
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c |  75 ++++++-----
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c | 122 +++++++++---------
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c |  47 +++----
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h |  29 ++---
 21 files changed, 285 insertions(+), 391 deletions(-)

(limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c')

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
index a4b943ee7a9a..28bc202f9753 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h
@@ -4,14 +4,11 @@
 struct nvkm_memory;
 
 struct nvkm_instmem {
+	const struct nvkm_instmem_func *func;
 	struct nvkm_subdev subdev;
-	struct list_head list;
 
+	struct list_head list;
 	u32 reserved;
-	int (*alloc)(struct nvkm_instmem *, u32 size, u32 align, bool zero,
-		     struct nvkm_memory **);
-
-	const struct nvkm_instmem_func *func;
 
 	struct nvkm_memory *vbios;
 	struct nvkm_ramht  *ramht;
@@ -19,26 +16,14 @@ struct nvkm_instmem {
 	struct nvkm_memory *ramfc;
 };
 
-struct nvkm_instmem_func {
-	u32  (*rd32)(struct nvkm_instmem *, u32 addr);
-	void (*wr32)(struct nvkm_instmem *, u32 addr, u32 data);
-};
-
-static inline struct nvkm_instmem *
-nvkm_instmem(void *obj)
-{
-	/* nv04/nv40 impls need to create objects in their constructor,
-	 * which is before the subdev pointer is valid
-	 */
-	if (nv_iclass(obj, NV_SUBDEV_CLASS) &&
-	    nv_subidx(obj) == NVDEV_SUBDEV_INSTMEM)
-		return obj;
+u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr);
+void nvkm_instmem_wr32(struct nvkm_instmem *, u32 addr, u32 data);
+int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero,
+		     struct nvkm_memory **);
 
-	return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_INSTMEM);
-}
 
-extern struct nvkm_oclass *nv04_instmem_oclass;
-extern struct nvkm_oclass *nv40_instmem_oclass;
-extern struct nvkm_oclass *nv50_instmem_oclass;
-extern struct nvkm_oclass *gk20a_instmem_oclass;
+int nv04_instmem_new(struct nvkm_device *, int, struct nvkm_instmem **);
+int nv40_instmem_new(struct nvkm_device *, int, struct nvkm_instmem **);
+int nv50_instmem_new(struct nvkm_device *, int, struct nvkm_instmem **);
+int gk20a_instmem_new(struct nvkm_device *, int, struct nvkm_instmem **);
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/memory.c b/drivers/gpu/drm/nouveau/nvkm/core/memory.c
index 0b88faa845f3..8903c04c977e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/memory.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/memory.c
@@ -55,7 +55,7 @@ nvkm_memory_new(struct nvkm_device *device, enum nvkm_memory_target target,
 	if (unlikely(target != NVKM_MEM_TARGET_INST || !imem))
 		return -ENOSYS;
 
-	ret = imem->alloc(imem, size, align, zero, &memory);
+	ret = nvkm_instobj_new(imem, size, align, zero, &memory);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 99a07694a298..3b83f17b3a23 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -82,7 +82,7 @@ nv4_chipset = {
 	.devinit = nv04_devinit_new,
 	.fb = nv04_fb_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -102,7 +102,7 @@ nv5_chipset = {
 	.devinit = nv05_devinit_new,
 	.fb = nv04_fb_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -123,7 +123,7 @@ nv10_chipset = {
 	.fb = nv10_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -142,7 +142,7 @@ nv11_chipset = {
 	.fb = nv10_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -163,7 +163,7 @@ nv15_chipset = {
 	.fb = nv10_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -184,7 +184,7 @@ nv17_chipset = {
 	.fb = nv10_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -205,7 +205,7 @@ nv18_chipset = {
 	.fb = nv10_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -226,7 +226,7 @@ nv1a_chipset = {
 	.fb = nv1a_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -247,7 +247,7 @@ nv1f_chipset = {
 	.fb = nv1a_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -268,7 +268,7 @@ nv20_chipset = {
 	.fb = nv20_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -289,7 +289,7 @@ nv25_chipset = {
 	.fb = nv25_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -310,7 +310,7 @@ nv28_chipset = {
 	.fb = nv25_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -331,7 +331,7 @@ nv2a_chipset = {
 	.fb = nv25_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -352,7 +352,7 @@ nv30_chipset = {
 	.fb = nv30_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -373,7 +373,7 @@ nv31_chipset = {
 	.fb = nv30_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -395,7 +395,7 @@ nv34_chipset = {
 	.fb = nv10_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -417,7 +417,7 @@ nv35_chipset = {
 	.fb = nv35_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -438,7 +438,7 @@ nv36_chipset = {
 	.fb = nv36_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv04_instmem_new,
+	.imem = nv04_instmem_new,
 //	.mc = nv04_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.timer = nv04_timer_new,
@@ -460,7 +460,7 @@ nv40_chipset = {
 	.fb = nv40_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv40_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.therm = nv40_therm_new,
@@ -485,7 +485,7 @@ nv41_chipset = {
 	.fb = nv41_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv40_mc_new,
 //	.mmu = nv41_mmu_new,
 //	.therm = nv40_therm_new,
@@ -510,7 +510,7 @@ nv42_chipset = {
 	.fb = nv41_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv40_mc_new,
 //	.mmu = nv41_mmu_new,
 //	.therm = nv40_therm_new,
@@ -535,7 +535,7 @@ nv43_chipset = {
 	.fb = nv41_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv40_mc_new,
 //	.mmu = nv41_mmu_new,
 //	.therm = nv40_therm_new,
@@ -560,7 +560,7 @@ nv44_chipset = {
 	.fb = nv44_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv44_mc_new,
 //	.mmu = nv44_mmu_new,
 //	.therm = nv40_therm_new,
@@ -585,7 +585,7 @@ nv45_chipset = {
 	.fb = nv40_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv40_mc_new,
 //	.mmu = nv04_mmu_new,
 //	.therm = nv40_therm_new,
@@ -610,7 +610,7 @@ nv46_chipset = {
 	.fb = nv46_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv44_mc_new,
 //	.mmu = nv44_mmu_new,
 //	.therm = nv40_therm_new,
@@ -635,7 +635,7 @@ nv47_chipset = {
 	.fb = nv47_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv40_mc_new,
 //	.mmu = nv41_mmu_new,
 //	.therm = nv40_therm_new,
@@ -660,7 +660,7 @@ nv49_chipset = {
 	.fb = nv49_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv40_mc_new,
 //	.mmu = nv41_mmu_new,
 //	.therm = nv40_therm_new,
@@ -685,7 +685,7 @@ nv4a_chipset = {
 	.fb = nv44_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv44_mc_new,
 //	.mmu = nv44_mmu_new,
 //	.therm = nv40_therm_new,
@@ -710,7 +710,7 @@ nv4b_chipset = {
 	.fb = nv49_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv40_mc_new,
 //	.mmu = nv41_mmu_new,
 //	.therm = nv40_therm_new,
@@ -735,7 +735,7 @@ nv4c_chipset = {
 	.fb = nv46_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv4c_mc_new,
 //	.mmu = nv44_mmu_new,
 //	.therm = nv40_therm_new,
@@ -760,7 +760,7 @@ nv4e_chipset = {
 	.fb = nv4e_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv4e_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv4c_mc_new,
 //	.mmu = nv44_mmu_new,
 //	.therm = nv40_therm_new,
@@ -787,7 +787,7 @@ nv50_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = nv50_gpio_new,
 	.i2c = nv50_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = nv50_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -813,7 +813,7 @@ nv63_chipset = {
 	.fb = nv46_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv4c_mc_new,
 //	.mmu = nv44_mmu_new,
 //	.therm = nv40_therm_new,
@@ -838,7 +838,7 @@ nv67_chipset = {
 	.fb = nv46_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv4c_mc_new,
 //	.mmu = nv44_mmu_new,
 //	.therm = nv40_therm_new,
@@ -863,7 +863,7 @@ nv68_chipset = {
 	.fb = nv46_fb_new,
 	.gpio = nv10_gpio_new,
 	.i2c = nv04_i2c_new,
-//	.imem = nv40_instmem_new,
+	.imem = nv40_instmem_new,
 //	.mc = nv4c_mc_new,
 //	.mmu = nv44_mmu_new,
 //	.therm = nv40_therm_new,
@@ -890,7 +890,7 @@ nv84_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = nv50_gpio_new,
 	.i2c = nv50_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = nv50_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -921,7 +921,7 @@ nv86_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = nv50_gpio_new,
 	.i2c = nv50_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = nv50_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -952,7 +952,7 @@ nv92_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = nv50_gpio_new,
 	.i2c = nv50_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = nv50_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -983,7 +983,7 @@ nv94_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = g94_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -1017,7 +1017,7 @@ nv96_chipset = {
 	.bus = g94_bus_new,
 //	.timer = nv04_timer_new,
 	.fb = g84_fb_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mmu = nv50_mmu_new,
 	.bar = g84_bar_new,
 //	.volt = nv40_volt_new,
@@ -1048,7 +1048,7 @@ nv98_chipset = {
 	.bus = g94_bus_new,
 //	.timer = nv04_timer_new,
 	.fb = g84_fb_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mmu = nv50_mmu_new,
 	.bar = g84_bar_new,
 //	.volt = nv40_volt_new,
@@ -1076,7 +1076,7 @@ nva0_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = g94_gpio_new,
 	.i2c = nv50_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = g98_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -1107,7 +1107,7 @@ nva3_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = g98_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -1140,7 +1140,7 @@ nva5_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = g98_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -1172,7 +1172,7 @@ nva8_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = g98_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -1204,7 +1204,7 @@ nvaa_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = g98_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -1235,7 +1235,7 @@ nvac_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = g98_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -1266,7 +1266,7 @@ nvaf_chipset = {
 	.fuse = nv50_fuse_new,
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.mc = g98_mc_new,
 //	.mmu = nv50_mmu_new,
 //	.mxm = nv50_mxm_new,
@@ -1299,7 +1299,7 @@ nvc0_chipset = {
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
 	.ibus = gf100_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gf100_ltc_new,
 //	.mc = gf100_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1334,7 +1334,7 @@ nvc1_chipset = {
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
 	.ibus = gf100_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gf100_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1368,7 +1368,7 @@ nvc3_chipset = {
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
 	.ibus = gf100_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gf100_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1402,7 +1402,7 @@ nvc4_chipset = {
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
 	.ibus = gf100_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gf100_ltc_new,
 //	.mc = gf100_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1437,7 +1437,7 @@ nvc8_chipset = {
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
 	.ibus = gf100_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gf100_ltc_new,
 //	.mc = gf100_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1472,7 +1472,7 @@ nvce_chipset = {
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
 	.ibus = gf100_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gf100_ltc_new,
 //	.mc = gf100_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1507,7 +1507,7 @@ nvcf_chipset = {
 	.gpio = g94_gpio_new,
 	.i2c = g94_i2c_new,
 	.ibus = gf100_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gf100_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1541,7 +1541,7 @@ nvd7_chipset = {
 	.gpio = gf119_gpio_new,
 	.i2c = gf117_i2c_new,
 	.ibus = gf100_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gf100_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1573,7 +1573,7 @@ nvd9_chipset = {
 	.gpio = gf119_gpio_new,
 	.i2c = gf119_i2c_new,
 	.ibus = gf100_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gf100_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1607,7 +1607,7 @@ nve4_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gk104_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1643,7 +1643,7 @@ nve6_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gk104_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1679,7 +1679,7 @@ nve7_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gk104_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1711,7 +1711,7 @@ nvea_chipset = {
 	.fb = gk20a_fb_new,
 	.fuse = gf100_fuse_new,
 	.ibus = gk20a_ibus_new,
-//	.imem = gk20a_instmem_new,
+	.imem = gk20a_instmem_new,
 //	.ltc = gk104_ltc_new,
 //	.mc = gk20a_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1739,7 +1739,7 @@ nvf0_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gk104_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1775,7 +1775,7 @@ nvf1_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gf119_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gk104_ltc_new,
 //	.mc = gf106_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1811,7 +1811,7 @@ nv106_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gk104_ltc_new,
 //	.mc = gk20a_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1846,7 +1846,7 @@ nv108_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gk104_ltc_new,
 //	.mc = gk20a_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1881,7 +1881,7 @@ nv117_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gf119_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gm107_ltc_new,
 //	.mc = gk20a_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1910,7 +1910,7 @@ nv124_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gm204_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gm107_ltc_new,
 //	.mc = gk20a_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1939,7 +1939,7 @@ nv126_chipset = {
 	.gpio = gk104_gpio_new,
 	.i2c = gm204_i2c_new,
 	.ibus = gk104_ibus_new,
-//	.imem = nv50_instmem_new,
+	.imem = nv50_instmem_new,
 //	.ltc = gm107_ltc_new,
 //	.mc = gk20a_mc_new,
 //	.mmu = gf100_mmu_new,
@@ -1964,7 +1964,7 @@ nv12b_chipset = {
 	.fb = gk20a_fb_new,
 	.fuse = gm107_fuse_new,
 	.ibus = gk20a_ibus_new,
-//	.imem = gk20a_instmem_new,
+	.imem = gk20a_instmem_new,
 //	.ltc = gm107_ltc_new,
 //	.mc = gk20a_mc_new,
 //	.mmu = gf100_mmu_new,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/gf100.c
index a0f54fd80810..8f9d871b545f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/gf100.c
@@ -33,7 +33,6 @@ gf100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf100_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gf100_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gf100_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -55,7 +54,6 @@ gf100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf100_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gf100_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gf100_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -77,7 +75,6 @@ gf100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gf100_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gf100_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -98,7 +95,6 @@ gf100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf100_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gf100_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gf100_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -120,7 +116,6 @@ gf100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gf100_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gf100_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -141,7 +136,6 @@ gf100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gf100_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gf100_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -162,7 +156,6 @@ gf100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf100_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gf100_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gf100_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -184,7 +177,6 @@ gf100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gf100_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gf110_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -205,7 +197,6 @@ gf100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gf100_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  gf110_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  gf100_fifo_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c
index f2f524b21950..dcb0f6db213d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/gk104.c
@@ -33,7 +33,6 @@ gk104_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk104_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -56,7 +55,6 @@ gk104_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gf110_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -79,7 +77,6 @@ gk104_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk104_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -100,7 +97,6 @@ gk104_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &gk20a_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] = gk20a_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  gf110_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  gk20a_fifo_oclass;
@@ -117,7 +113,6 @@ gk104_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk110_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -140,7 +135,6 @@ gk104_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk110_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -163,7 +157,6 @@ gk104_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk208_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -185,7 +178,6 @@ gk104_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk208_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c
index 9c0306279de8..158af1f8799e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c
@@ -33,7 +33,6 @@ gm100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &gk20a_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gm107_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk208_pmu_oclass;
 
@@ -66,7 +65,6 @@ gm100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &gk20a_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gm107_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk208_pmu_oclass;
 #if 0
@@ -96,7 +94,6 @@ gm100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &gk20a_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gm107_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk208_pmu_oclass;
 #if 0
@@ -122,7 +119,6 @@ gm100_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &gk20a_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_LTC    ] =  gm107_ltc_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] = gk20a_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  gf110_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  gm20b_fifo_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv04.c
index de456b2d44b3..dc90bad93869 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv04.c
@@ -30,7 +30,6 @@ nv04_identify(struct nvkm_device *device)
 	case 0x04:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv04_fifo_oclass;
@@ -41,7 +40,6 @@ nv04_identify(struct nvkm_device *device)
 	case 0x05:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv04_fifo_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv10.c
index 6e58a0e20ba2..b1db20f4a15c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv10.c
@@ -30,7 +30,6 @@ nv10_identify(struct nvkm_device *device)
 	case 0x10:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv10_gr_oclass;
@@ -39,7 +38,6 @@ nv10_identify(struct nvkm_device *device)
 	case 0x15:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv10_fifo_oclass;
@@ -50,7 +48,6 @@ nv10_identify(struct nvkm_device *device)
 	case 0x16:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv10_fifo_oclass;
@@ -61,7 +58,6 @@ nv10_identify(struct nvkm_device *device)
 	case 0x1a:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv10_fifo_oclass;
@@ -72,7 +68,6 @@ nv10_identify(struct nvkm_device *device)
 	case 0x11:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv10_fifo_oclass;
@@ -83,7 +78,6 @@ nv10_identify(struct nvkm_device *device)
 	case 0x17:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
@@ -94,7 +88,6 @@ nv10_identify(struct nvkm_device *device)
 	case 0x1f:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
@@ -105,7 +98,6 @@ nv10_identify(struct nvkm_device *device)
 	case 0x18:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv20.c
index 146773775922..f11b7d01f34a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv20.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv20.c
@@ -30,7 +30,6 @@ nv20_identify(struct nvkm_device *device)
 	case 0x20:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
@@ -41,7 +40,6 @@ nv20_identify(struct nvkm_device *device)
 	case 0x25:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
@@ -52,7 +50,6 @@ nv20_identify(struct nvkm_device *device)
 	case 0x28:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
@@ -63,7 +60,6 @@ nv20_identify(struct nvkm_device *device)
 	case 0x2a:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv30.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv30.c
index e4d5fc697f49..780dd1019666 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv30.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv30.c
@@ -30,7 +30,6 @@ nv30_identify(struct nvkm_device *device)
 	case 0x30:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
@@ -41,7 +40,6 @@ nv30_identify(struct nvkm_device *device)
 	case 0x35:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
@@ -52,7 +50,6 @@ nv30_identify(struct nvkm_device *device)
 	case 0x31:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
@@ -64,7 +61,6 @@ nv30_identify(struct nvkm_device *device)
 	case 0x36:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
@@ -76,7 +72,6 @@ nv30_identify(struct nvkm_device *device)
 	case 0x34:
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv04_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv04_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c
index 0bf4fcefcf88..a5d874a2c297 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv40.c
@@ -31,7 +31,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv40_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -46,7 +45,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv40_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv41_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -61,7 +59,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv40_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv41_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -76,7 +73,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv40_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv41_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -91,7 +87,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv40_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv04_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -106,7 +101,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv40_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv41_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -121,7 +115,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv40_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv41_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -136,7 +129,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv40_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv41_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -151,7 +143,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv44_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv44_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -166,7 +157,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv4c_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv44_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -181,7 +171,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv44_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv44_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -196,7 +185,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv4c_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv44_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -211,7 +199,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv4c_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv44_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -226,7 +213,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv4c_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv44_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -241,7 +227,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv4c_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv44_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
@@ -256,7 +241,6 @@ nv40_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_THERM  ] = &nv40_therm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv4c_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv40_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv44_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv04_dmaeng_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c
index 956ea9c02f45..2507559e5894 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c
@@ -32,7 +32,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv50_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -48,7 +47,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv50_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -67,7 +65,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv50_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -86,7 +83,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  nv50_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -105,7 +101,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g94_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -124,7 +119,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g94_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -143,7 +137,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -162,7 +155,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -181,7 +173,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -200,7 +191,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
@@ -219,7 +209,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gt215_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -240,7 +229,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gt215_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -260,7 +248,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gt215_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -280,7 +267,6 @@ nv50_identify(struct nvkm_device *device)
 		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
 		device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
-		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_MMU    ] = &nv50_mmu_oclass;
 		device->oclass[NVDEV_SUBDEV_PMU    ] =  gt215_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
index 0103337f55d2..0e4e1152eeec 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
@@ -353,6 +353,7 @@ nv40_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	     struct nvkm_oclass *oclass, void *data, u32 size,
 	     struct nvkm_object **pobject)
 {
+	struct nvkm_device *device = (void *)parent;
 	struct nv40_gr *gr;
 	int ret;
 
@@ -365,7 +366,7 @@ nv40_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	nv_subdev(gr)->unit = 0x00001000;
 	nv_subdev(gr)->intr = nv40_gr_intr;
-	if (nv44_gr_class(gr))
+	if (nv44_gr_class(device))
 		gr->base.func = &nv44_gr;
 	else
 		gr->base.func = &nv40_gr;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h
index eefb36cbeeea..42cc409a8df2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.h
@@ -23,10 +23,8 @@ struct nv40_gr_chan {
  * helpful to determine a number of other hardware features
  */
 static inline int
-nv44_gr_class(void *priv)
+nv44_gr_class(struct nvkm_device *device)
 {
-	struct nvkm_device *device = nv_device(priv);
-
 	if ((device->chipset & 0xf0) == 0x60)
 		return 1;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
index b4ef1ebd38ab..97529c4f0a25 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c
@@ -32,9 +32,9 @@ nv40_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data)
 {
 	struct nvkm_instmem *imem = device->imem;
 	u32 inst = data << 4;
-	u32 dma0 = imem->func->rd32(imem, inst + 0);
-	u32 dma1 = imem->func->rd32(imem, inst + 4);
-	u32 dma2 = imem->func->rd32(imem, inst + 8);
+	u32 dma0 = nvkm_instmem_rd32(imem, inst + 0);
+	u32 dma1 = nvkm_instmem_rd32(imem, inst + 4);
+	u32 dma2 = nvkm_instmem_rd32(imem, inst + 8);
 	u32 base = (dma2 & 0xfffff000) | (dma0 >> 20);
 	u32 size = dma1 + 1;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
index 6a356f348c58..895ba74057d4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
@@ -168,21 +168,20 @@ nvkm_instobj_func_slow = {
 	.map = nvkm_instobj_map,
 };
 
-static int
+int
 nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
 		 struct nvkm_memory **pmemory)
 {
-	struct nvkm_instmem_impl *impl = (void *)imem->subdev.object.oclass;
-	struct nvkm_memory *memory;
+	struct nvkm_memory *memory = NULL;
 	struct nvkm_instobj *iobj;
 	u32 offset;
 	int ret;
 
-	ret = impl->memory_new(imem, size, align, zero, &memory);
+	ret = imem->func->memory_new(imem, size, align, zero, &memory);
 	if (ret)
 		goto done;
 
-	if (!impl->persistent) {
+	if (!imem->func->persistent) {
 		if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) {
 			ret = -ENOMEM;
 			goto done;
@@ -195,7 +194,7 @@ nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
 		memory = &iobj->memory;
 	}
 
-	if (!impl->zero && zero) {
+	if (!imem->func->zero && zero) {
 		void __iomem *map = nvkm_kmap(memory);
 		if (unlikely(!map)) {
 			for (offset = 0; offset < size; offset += 4)
@@ -217,13 +216,28 @@ done:
  * instmem subdev base implementation
  *****************************************************************************/
 
-int
-_nvkm_instmem_fini(struct nvkm_object *object, bool suspend)
+u32
+nvkm_instmem_rd32(struct nvkm_instmem *imem, u32 addr)
+{
+	return imem->func->rd32(imem, addr);
+}
+
+void
+nvkm_instmem_wr32(struct nvkm_instmem *imem, u32 addr, u32 data)
+{
+	return imem->func->wr32(imem, addr, data);
+}
+
+static int
+nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend)
 {
-	struct nvkm_instmem *imem = (void *)object;
+	struct nvkm_instmem *imem = nvkm_instmem(subdev);
 	struct nvkm_instobj *iobj;
 	int i;
 
+	if (imem->func->fini)
+		imem->func->fini(imem);
+
 	if (suspend) {
 		list_for_each_entry(iobj, &imem->list, head) {
 			struct nvkm_memory *memory = iobj->parent;
@@ -238,19 +252,24 @@ _nvkm_instmem_fini(struct nvkm_object *object, bool suspend)
 		}
 	}
 
-	return nvkm_subdev_fini_old(&imem->subdev, suspend);
+	return 0;
 }
 
-int
-_nvkm_instmem_init(struct nvkm_object *object)
+static int
+nvkm_instmem_oneinit(struct nvkm_subdev *subdev)
 {
-	struct nvkm_instmem *imem = (void *)object;
-	struct nvkm_instobj *iobj;
-	int ret, i;
+	struct nvkm_instmem *imem = nvkm_instmem(subdev);
+	if (imem->func->oneinit)
+		return imem->func->oneinit(imem);
+	return 0;
+}
 
-	ret = nvkm_subdev_init_old(&imem->subdev);
-	if (ret)
-		return ret;
+static int
+nvkm_instmem_init(struct nvkm_subdev *subdev)
+{
+	struct nvkm_instmem *imem = nvkm_instmem(subdev);
+	struct nvkm_instobj *iobj;
+	int i;
 
 	list_for_each_entry(iobj, &imem->list, head) {
 		if (iobj->suspend) {
@@ -266,23 +285,29 @@ _nvkm_instmem_init(struct nvkm_object *object)
 	return 0;
 }
 
-int
-nvkm_instmem_create_(struct nvkm_object *parent, struct nvkm_object *engine,
-		     struct nvkm_oclass *oclass, int length, void **pobject)
+static void *
+nvkm_instmem_dtor(struct nvkm_subdev *subdev)
 {
-	struct nvkm_device *device = (void *)parent;
-	struct nvkm_instmem *imem;
-	int ret;
-
-	ret = nvkm_subdev_create_(parent, engine, oclass, 0, "INSTMEM",
-				  "instmem", length, pobject);
-	imem = *pobject;
-	if (ret)
-		return ret;
+	struct nvkm_instmem *imem = nvkm_instmem(subdev);
+	if (imem->func->dtor)
+		return imem->func->dtor(imem);
+	return imem;
+}
 
-	device->imem = imem;
+static const struct nvkm_subdev_func
+nvkm_instmem = {
+	.dtor = nvkm_instmem_dtor,
+	.oneinit = nvkm_instmem_oneinit,
+	.init = nvkm_instmem_init,
+	.fini = nvkm_instmem_fini,
+};
 
+void
+nvkm_instmem_ctor(const struct nvkm_instmem_func *func,
+		  struct nvkm_device *device, int index,
+		  struct nvkm_instmem *imem)
+{
+	nvkm_subdev_ctor(&nvkm_instmem, device, index, 0, &imem->subdev);
+	imem->func = func;
 	INIT_LIST_HEAD(&imem->list);
-	imem->alloc = nvkm_instobj_new;
-	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index a64c3f9bfc3d..ab01989c3430 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -186,7 +186,7 @@ gk20a_instobj_dtor_dma(struct gk20a_instobj *_node)
 {
 	struct gk20a_instobj_dma *node = (void *)_node;
 	struct gk20a_instmem *imem = _node->imem;
-	struct device *dev = nv_device_base(nv_device(imem));
+	struct device *dev = nv_device_base(imem->base.subdev.device);
 
 	if (unlikely(!node->cpuaddr))
 		return;
@@ -372,7 +372,7 @@ gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
 		  struct nvkm_memory **pmemory)
 {
 	struct gk20a_instmem *imem = gk20a_instmem(base);
-	struct gk20a_instobj *node;
+	struct gk20a_instobj *node = NULL;
 	struct nvkm_subdev *subdev = &imem->base.subdev;
 	int ret;
 
@@ -389,9 +389,9 @@ gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
 	else
 		ret = gk20a_instobj_ctor_dma(imem, size >> PAGE_SHIFT,
 					     align, &node);
+	*pmemory = node ? &node->memory : NULL;
 	if (ret)
 		return ret;
-	*pmemory = &node->memory;
 
 	nvkm_memory_ctor(&gk20a_instobj_func, &node->memory);
 	node->imem = imem;
@@ -407,29 +407,31 @@ gk20a_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
 	return 0;
 }
 
-static int
-gk20a_instmem_fini(struct nvkm_object *object, bool suspend)
+static void
+gk20a_instmem_fini(struct nvkm_instmem *base)
 {
-	struct gk20a_instmem *imem = (void *)object;
-	imem->addr = ~0ULL;
-	return nvkm_instmem_fini(&imem->base, suspend);
+	gk20a_instmem(base)->addr = ~0ULL;
 }
 
-static int
-gk20a_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-		   struct nvkm_oclass *oclass, void *data, u32 size,
-		   struct nvkm_object **pobject)
+static const struct nvkm_instmem_func
+gk20a_instmem = {
+	.fini = gk20a_instmem_fini,
+	.memory_new = gk20a_instobj_new,
+	.persistent = true,
+	.zero = false,
+};
+
+int
+gk20a_instmem_new(struct nvkm_device *device, int index,
+		 struct nvkm_instmem **pimem)
 {
-	struct nvkm_device *device = (void *)parent;
 	struct gk20a_instmem *imem;
-	int ret;
-
-	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
-	*pobject = nv_object(imem);
-	if (ret)
-		return ret;
 
+	if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
+		return -ENOMEM;
+	nvkm_instmem_ctor(&gk20a_instmem, device, index, &imem->base);
 	spin_lock_init(&imem->lock);
+	*pimem = &imem->base;
 
 	if (device->gpu->iommu.domain) {
 		imem->domain = device->gpu->iommu.domain;
@@ -454,17 +456,3 @@ gk20a_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
 	return 0;
 }
-
-struct nvkm_oclass *
-gk20a_instmem_oclass = &(struct nvkm_instmem_impl) {
-	.base.handle = NV_SUBDEV(INSTMEM, 0xea),
-	.base.ofuncs = &(struct nvkm_ofuncs) {
-		.ctor = gk20a_instmem_ctor,
-		.dtor = _nvkm_instmem_dtor,
-		.init = _nvkm_instmem_init,
-		.fini = gk20a_instmem_fini,
-	},
-	.memory_new = gk20a_instobj_new,
-	.persistent = true,
-	.zero = false,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
index 1df45273bff7..6133c8bb2d42 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c
@@ -150,40 +150,13 @@ nv04_instmem_wr32(struct nvkm_instmem *imem, u32 addr, u32 data)
 	nvkm_wr32(imem->subdev.device, 0x700000 + addr, data);
 }
 
-static void
-nv04_instmem_dtor(struct nvkm_object *object)
-{
-	struct nv04_instmem *imem = (void *)object;
-	nvkm_memory_del(&imem->base.ramfc);
-	nvkm_memory_del(&imem->base.ramro);
-	nvkm_ramht_del(&imem->base.ramht);
-	nvkm_memory_del(&imem->base.vbios);
-	nvkm_mm_fini(&imem->heap);
-	nvkm_instmem_destroy(&imem->base);
-}
-
-static const struct nvkm_instmem_func
-nv04_instmem_func = {
-	.rd32 = nv04_instmem_rd32,
-	.wr32 = nv04_instmem_wr32,
-};
-
 static int
-nv04_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-		  struct nvkm_oclass *oclass, void *data, u32 size,
-		  struct nvkm_object **pobject)
+nv04_instmem_oneinit(struct nvkm_instmem *base)
 {
-	struct nvkm_device *device = (void *)parent;
-	struct nv04_instmem *imem;
+	struct nv04_instmem *imem = nv04_instmem(base);
+	struct nvkm_device *device = imem->base.subdev.device;
 	int ret;
 
-	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
-	*pobject = nv_object(imem);
-	if (ret)
-		return ret;
-
-	imem->base.func = &nv04_instmem_func;
-
 	/* PRAMIN aperture maps over the end of VRAM, reserve it */
 	imem->base.reserved = 512 * 1024;
 
@@ -217,16 +190,38 @@ nv04_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	return 0;
 }
 
-struct nvkm_oclass *
-nv04_instmem_oclass = &(struct nvkm_instmem_impl) {
-	.base.handle = NV_SUBDEV(INSTMEM, 0x04),
-	.base.ofuncs = &(struct nvkm_ofuncs) {
-		.ctor = nv04_instmem_ctor,
-		.dtor = nv04_instmem_dtor,
-		.init = _nvkm_instmem_init,
-		.fini = _nvkm_instmem_fini,
-	},
+static void *
+nv04_instmem_dtor(struct nvkm_instmem *base)
+{
+	struct nv04_instmem *imem = nv04_instmem(base);
+	nvkm_memory_del(&imem->base.ramfc);
+	nvkm_memory_del(&imem->base.ramro);
+	nvkm_ramht_del(&imem->base.ramht);
+	nvkm_memory_del(&imem->base.vbios);
+	nvkm_mm_fini(&imem->heap);
+	return imem;
+}
+
+static const struct nvkm_instmem_func
+nv04_instmem = {
+	.dtor = nv04_instmem_dtor,
+	.oneinit = nv04_instmem_oneinit,
+	.rd32 = nv04_instmem_rd32,
+	.wr32 = nv04_instmem_wr32,
 	.memory_new = nv04_instobj_new,
 	.persistent = false,
 	.zero = false,
-}.base;
+};
+
+int
+nv04_instmem_new(struct nvkm_device *device, int index,
+		 struct nvkm_instmem **pimem)
+{
+	struct nv04_instmem *imem;
+
+	if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
+		return -ENOMEM;
+	nvkm_instmem_ctor(&nv04_instmem, device, index, &imem->base);
+	*pimem = &imem->base;
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
index 8e7a11503c09..a170ff9b32e7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c
@@ -138,67 +138,23 @@ nv40_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
  *****************************************************************************/
 
 static u32
-nv40_instmem_rd32(struct nvkm_instmem *obj, u32 addr)
+nv40_instmem_rd32(struct nvkm_instmem *base, u32 addr)
 {
-	struct nv40_instmem *imem = container_of(obj, typeof(*imem), base);
-	return ioread32_native(imem->iomem + addr);
+	return ioread32_native(nv40_instmem(base)->iomem + addr);
 }
 
 static void
-nv40_instmem_wr32(struct nvkm_instmem *obj, u32 addr, u32 data)
+nv40_instmem_wr32(struct nvkm_instmem *base, u32 addr, u32 data)
 {
-	struct nv40_instmem *imem = container_of(obj, typeof(*imem), base);
-	iowrite32_native(data, imem->iomem + addr);
+	iowrite32_native(data, nv40_instmem(base)->iomem + addr);
 }
 
-static void
-nv40_instmem_dtor(struct nvkm_object *object)
-{
-	struct nv40_instmem *imem = (void *)object;
-	nvkm_memory_del(&imem->base.ramfc);
-	nvkm_memory_del(&imem->base.ramro);
-	nvkm_ramht_del(&imem->base.ramht);
-	nvkm_memory_del(&imem->base.vbios);
-	nvkm_mm_fini(&imem->heap);
-	if (imem->iomem)
-		iounmap(imem->iomem);
-	nvkm_instmem_destroy(&imem->base);
-}
-
-static const struct nvkm_instmem_func
-nv40_instmem_func = {
-	.rd32 = nv40_instmem_rd32,
-	.wr32 = nv40_instmem_wr32,
-};
-
 static int
-nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-		  struct nvkm_oclass *oclass, void *data, u32 size,
-		  struct nvkm_object **pobject)
+nv40_instmem_oneinit(struct nvkm_instmem *base)
 {
-	struct nvkm_device *device = (void *)parent;
-	struct nv40_instmem *imem;
-	int ret, bar, vs;
-
-	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
-	*pobject = nv_object(imem);
-	if (ret)
-		return ret;
-
-	imem->base.func = &nv40_instmem_func;
-
-	/* map bar */
-	if (nv_device_resource_len(device, 2))
-		bar = 2;
-	else
-		bar = 3;
-
-	imem->iomem = ioremap(nv_device_resource_start(device, bar),
-			      nv_device_resource_len(device, bar));
-	if (!imem->iomem) {
-		nvkm_error(&imem->base.subdev, "unable to map PRAMIN BAR\n");
-		return -EFAULT;
-	}
+	struct nv40_instmem *imem = nv40_instmem(base);
+	struct nvkm_device *device = imem->base.subdev.device;
+	int ret, vs;
 
 	/* PRAMIN aperture maps over the end of vram, reserve enough space
 	 * to fit graphics contexts for every channel, the magics come
@@ -207,13 +163,12 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	vs = hweight8((nvkm_rd32(device, 0x001540) & 0x0000ff00) >> 8);
 	if      (device->chipset == 0x40) imem->base.reserved = 0x6aa0 * vs;
 	else if (device->chipset  < 0x43) imem->base.reserved = 0x4f00 * vs;
-	else if (nv44_gr_class(imem))     imem->base.reserved = 0x4980 * vs;
+	else if (nv44_gr_class(device))   imem->base.reserved = 0x4980 * vs;
 	else				  imem->base.reserved = 0x4a40 * vs;
 	imem->base.reserved += 16 * 1024;
 	imem->base.reserved *= 32;		/* per-channel */
 	imem->base.reserved += 512 * 1024;	/* pci(e)gart table */
 	imem->base.reserved += 512 * 1024;	/* object storage */
-
 	imem->base.reserved = round_up(imem->base.reserved, 4096);
 
 	ret = nvkm_mm_init(&imem->heap, 0, imem->base.reserved, 1);
@@ -250,16 +205,55 @@ nv40_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	return 0;
 }
 
-struct nvkm_oclass *
-nv40_instmem_oclass = &(struct nvkm_instmem_impl) {
-	.base.handle = NV_SUBDEV(INSTMEM, 0x40),
-	.base.ofuncs = &(struct nvkm_ofuncs) {
-		.ctor = nv40_instmem_ctor,
-		.dtor = nv40_instmem_dtor,
-		.init = _nvkm_instmem_init,
-		.fini = _nvkm_instmem_fini,
-	},
+static void *
+nv40_instmem_dtor(struct nvkm_instmem *base)
+{
+	struct nv40_instmem *imem = nv40_instmem(base);
+	nvkm_memory_del(&imem->base.ramfc);
+	nvkm_memory_del(&imem->base.ramro);
+	nvkm_ramht_del(&imem->base.ramht);
+	nvkm_memory_del(&imem->base.vbios);
+	nvkm_mm_fini(&imem->heap);
+	if (imem->iomem)
+		iounmap(imem->iomem);
+	return imem;
+}
+
+static const struct nvkm_instmem_func
+nv40_instmem = {
+	.dtor = nv40_instmem_dtor,
+	.oneinit = nv40_instmem_oneinit,
+	.rd32 = nv40_instmem_rd32,
+	.wr32 = nv40_instmem_wr32,
 	.memory_new = nv40_instobj_new,
 	.persistent = false,
 	.zero = false,
-}.base;
+};
+
+int
+nv40_instmem_new(struct nvkm_device *device, int index,
+		 struct nvkm_instmem **pimem)
+{
+	struct nv40_instmem *imem;
+	int bar;
+
+	if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
+		return -ENOMEM;
+	nvkm_instmem_ctor(&nv40_instmem, device, index, &imem->base);
+	*pimem = &imem->base;
+
+	/* map bar */
+	if (nv_device_resource_len(device, 2))
+		bar = 2;
+	else
+		bar = 3;
+
+	imem->iomem = ioremap(nv_device_resource_start(device, bar),
+			      nv_device_resource_len(device, bar));
+	if (!imem->iomem) {
+		nvkm_error(&imem->base.subdev, "unable to map PRAMIN BAR\n");
+		return -EFAULT;
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
index af236f8e4ddc..ec5020e3fc42 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -220,41 +220,30 @@ nv50_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero,
  * instmem subdev implementation
  *****************************************************************************/
 
-static int
-nv50_instmem_fini(struct nvkm_object *object, bool suspend)
+static void
+nv50_instmem_fini(struct nvkm_instmem *base)
 {
-	struct nv50_instmem *imem = (void *)object;
-	imem->addr = ~0ULL;
-	return nvkm_instmem_fini(&imem->base, suspend);
+	nv50_instmem(base)->addr = ~0ULL;
 }
 
-static int
-nv50_instmem_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-		  struct nvkm_oclass *oclass, void *data, u32 size,
-		  struct nvkm_object **pobject)
+static const struct nvkm_instmem_func
+nv50_instmem = {
+	.fini = nv50_instmem_fini,
+	.memory_new = nv50_instobj_new,
+	.persistent = false,
+	.zero = false,
+};
+
+int
+nv50_instmem_new(struct nvkm_device *device, int index,
+		 struct nvkm_instmem **pimem)
 {
 	struct nv50_instmem *imem;
-	int ret;
-
-	ret = nvkm_instmem_create(parent, engine, oclass, &imem);
-	*pobject = nv_object(imem);
-	if (ret)
-		return ret;
 
+	if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
+		return -ENOMEM;
+	nvkm_instmem_ctor(&nv50_instmem, device, index, &imem->base);
 	spin_lock_init(&imem->lock);
+	*pimem = &imem->base;
 	return 0;
 }
-
-struct nvkm_oclass *
-nv50_instmem_oclass = &(struct nvkm_instmem_impl) {
-	.base.handle = NV_SUBDEV(INSTMEM, 0x50),
-	.base.ofuncs = &(struct nvkm_ofuncs) {
-		.ctor = nv50_instmem_ctor,
-		.dtor = _nvkm_instmem_dtor,
-		.init = _nvkm_instmem_init,
-		.fini = nv50_instmem_fini,
-	},
-	.memory_new = nv50_instobj_new,
-	.persistent = false,
-	.zero = false,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
index 2b6d73005767..ace4471864a3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h
@@ -1,31 +1,20 @@
 #ifndef __NVKM_INSTMEM_PRIV_H__
 #define __NVKM_INSTMEM_PRIV_H__
+#define nvkm_instmem(p) container_of((p), struct nvkm_instmem, subdev)
 #include <subdev/instmem.h>
 
-struct nvkm_instmem_impl {
-	struct nvkm_oclass base;
+struct nvkm_instmem_func {
+	void *(*dtor)(struct nvkm_instmem *);
+	int (*oneinit)(struct nvkm_instmem *);
+	void (*fini)(struct nvkm_instmem *);
+	u32  (*rd32)(struct nvkm_instmem *, u32 addr);
+	void (*wr32)(struct nvkm_instmem *, u32 addr, u32 data);
 	int (*memory_new)(struct nvkm_instmem *, u32 size, u32 align,
 			  bool zero, struct nvkm_memory **);
 	bool persistent;
 	bool zero;
 };
 
-#define nvkm_instmem_create(p,e,o,d)                                        \
-	nvkm_instmem_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nvkm_instmem_destroy(p)                                             \
-	nvkm_subdev_destroy(&(p)->subdev)
-#define nvkm_instmem_init(p) ({                                             \
-	struct nvkm_instmem *_imem = (p);                                    \
-	_nvkm_instmem_init(nv_object(_imem));                                \
-})
-#define nvkm_instmem_fini(p,s) ({                                           \
-	struct nvkm_instmem *_imem = (p);                                    \
-	_nvkm_instmem_fini(nv_object(_imem), (s));                           \
-})
-
-int nvkm_instmem_create_(struct nvkm_object *, struct nvkm_object *,
-			    struct nvkm_oclass *, int, void **);
-#define _nvkm_instmem_dtor _nvkm_subdev_dtor
-int _nvkm_instmem_init(struct nvkm_object *);
-int _nvkm_instmem_fini(struct nvkm_object *, bool);
+void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *,
+		       int index, struct nvkm_instmem *);
 #endif
-- 
cgit v1.2.3-70-g09d2


From 26c9e8effebb9166eb1cfba2d164676e98c505c7 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 14:54:23 +1000
Subject: drm/nouveau/device: remove pci/platform_device from common struct

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 40 ++++++----------------
 drivers/gpu/drm/nouveau/nouveau_abi16.c            |  6 ++--
 drivers/gpu/drm/nouveau/nouveau_acpi.c             |  4 +--
 drivers/gpu/drm/nouveau/nouveau_acpi.h             |  4 +--
 drivers/gpu/drm/nouveau/nouveau_agp.c              |  7 ++--
 drivers/gpu/drm/nouveau/nouveau_bo.c               | 18 +++++-----
 drivers/gpu/drm/nouveau/nouveau_sysfs.c            |  4 +--
 drivers/gpu/drm/nouveau/nouveau_ttm.c              |  2 +-
 drivers/gpu/drm/nouveau/nv50_display.c             |  8 ++---
 drivers/gpu/drm/nouveau/nvkm/engine/device/base.c  | 14 ++------
 drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c   |  7 ++--
 drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h  |  2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c |  5 +--
 drivers/gpu/drm/nouveau/nvkm/engine/device/user.c  | 24 ++++++++-----
 drivers/gpu/drm/nouveau/nvkm/engine/falcon.c       |  6 ++--
 drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c     |  2 +-
 drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c       |  2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c  |  2 +-
 .../gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c  |  6 ++--
 .../gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c   | 18 ++++++++--
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c     |  9 +++--
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c      |  9 +++--
 .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c    |  2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c     |  4 +--
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c     |  2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c     |  5 +--
 drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c     |  2 +-
 27 files changed, 106 insertions(+), 108 deletions(-)

(limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c')

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
index 5741bf228762..773951bfd200 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
@@ -47,13 +47,21 @@ enum nvkm_devidx {
 	NVKM_ENGINE_SEC,
 	NVKM_ENGINE_MSPDEC,
 
-	NVKM_SUBDEV_NR,
+	NVKM_SUBDEV_NR
+};
+
+enum nvkm_device_type {
+	NVKM_DEVICE_PCI,
+	NVKM_DEVICE_AGP,
+	NVKM_DEVICE_PCIE,
+	NVKM_DEVICE_TEGRA,
 };
 
 struct nvkm_device {
 	const struct nvkm_device_func *func;
 	const struct nvkm_device_quirk *quirk;
 	struct device *dev;
+	enum nvkm_device_type type;
 	u64 handle;
 	const char *name;
 	const char *cfgopt;
@@ -63,9 +71,6 @@ struct nvkm_device {
 	struct mutex mutex;
 	int refcount;
 
-	struct pci_dev *pdev;
-	struct platform_device *platformdev;
-
 	void __iomem *pri;
 
 	struct nvkm_event event;
@@ -150,6 +155,7 @@ struct nvkm_device_func {
 	void (*fini)(struct nvkm_device *, bool suspend);
 	resource_size_t (*resource_addr)(struct nvkm_device *, unsigned bar);
 	resource_size_t (*resource_size)(struct nvkm_device *, unsigned bar);
+	bool cpu_coherent;
 };
 
 struct nvkm_device_quirk {
@@ -220,32 +226,6 @@ int nvkm_device_list(u64 *name, int size);
 	_temp;                                                                 \
 })
 
-static inline bool
-nv_device_is_pci(struct nvkm_device *device)
-{
-	return device->pdev != NULL;
-}
-
-static inline bool
-nv_device_is_cpu_coherent(struct nvkm_device *device)
-{
-	return (!IS_ENABLED(CONFIG_ARM) && nv_device_is_pci(device));
-}
-
-static inline struct device *
-nv_device_base(struct nvkm_device *device)
-{
-	return nv_device_is_pci(device) ? &device->pdev->dev :
-					  &device->platformdev->dev;
-}
-
-struct platform_device;
-
-enum nv_bus_type {
-	NVKM_BUS_PCI,
-	NVKM_BUS_PLATFORM,
-};
-
 void nvkm_device_del(struct nvkm_device **);
 
 struct nvkm_device_oclass {
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index 40a903b79343..4252e7796c4c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -174,19 +174,19 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
 		getparam->value = device->info.chipset;
 		break;
 	case NOUVEAU_GETPARAM_PCI_VENDOR:
-		if (nv_device_is_pci(nvxx_device(device)))
+		if (nvxx_device(device)->func->pci)
 			getparam->value = dev->pdev->vendor;
 		else
 			getparam->value = 0;
 		break;
 	case NOUVEAU_GETPARAM_PCI_DEVICE:
-		if (nv_device_is_pci(nvxx_device(device)))
+		if (nvxx_device(device)->func->pci)
 			getparam->value = dev->pdev->device;
 		else
 			getparam->value = 0;
 		break;
 	case NOUVEAU_GETPARAM_BUS_TYPE:
-		if (!nv_device_is_pci(nvxx_device(device)))
+		if (!nvxx_device(device)->func->pci)
 			getparam->value = 3;
 		else
 		if (drm_pci_device_is_agp(dev))
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 622424692b3b..df2d9818aba3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -372,12 +372,12 @@ static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios,
 	return len;
 }
 
-bool nouveau_acpi_rom_supported(struct pci_dev *pdev)
+bool nouveau_acpi_rom_supported(struct device *dev)
 {
 	acpi_status status;
 	acpi_handle dhandle, rom_handle;
 
-	dhandle = ACPI_HANDLE(&pdev->dev);
+	dhandle = ACPI_HANDLE(dev);
 	if (!dhandle)
 		return false;
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h b/drivers/gpu/drm/nouveau/nouveau_acpi.h
index 74acf0f87785..2f03653aff86 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.h
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
@@ -10,7 +10,7 @@ void nouveau_register_dsm_handler(void);
 void nouveau_unregister_dsm_handler(void);
 void nouveau_switcheroo_optimus_dsm(void);
 int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
-bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
+bool nouveau_acpi_rom_supported(struct device *);
 void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
 #else
 static inline bool nouveau_is_optimus(void) { return false; };
@@ -18,7 +18,7 @@ static inline bool nouveau_is_v1_dsm(void) { return false; };
 static inline void nouveau_register_dsm_handler(void) {}
 static inline void nouveau_unregister_dsm_handler(void) {}
 static inline void nouveau_switcheroo_optimus_dsm(void) {}
-static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
+static inline bool nouveau_acpi_rom_supported(struct device *dev) { return false; }
 static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
 static inline void *nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return NULL; }
 #endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_agp.c b/drivers/gpu/drm/nouveau/nouveau_agp.c
index 320f48c41fe0..c3f3e49e5f8f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_agp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_agp.c
@@ -4,6 +4,8 @@
 #include "nouveau_agp.h"
 #include "nouveau_reg.h"
 
+#include <core/pci.h>
+
 #if __OS_HAS_AGP
 MODULE_PARM_DESC(agpmode, "AGP mode (0 to disable AGP)");
 static int nouveau_agpmode = -1;
@@ -28,6 +30,7 @@ static unsigned long
 get_agp_mode(struct nouveau_drm *drm, const struct drm_agp_info *info)
 {
 	struct nvif_device *device = &drm->device;
+	struct pci_dev *pdev = nvxx_device(device)->func->pci(nvxx_device(device))->pdev;
 	struct nouveau_agpmode_quirk *quirk = nouveau_agpmode_quirk_list;
 	int agpmode = nouveau_agpmode;
 	unsigned long mode = info->mode;
@@ -45,8 +48,8 @@ get_agp_mode(struct nouveau_drm *drm, const struct drm_agp_info *info)
 	while (agpmode == -1 && quirk->hostbridge_vendor) {
 		if (info->id_vendor == quirk->hostbridge_vendor &&
 		    info->id_device == quirk->hostbridge_device &&
-		    nvxx_device(device)->pdev->vendor == quirk->chip_vendor &&
-		    nvxx_device(device)->pdev->device == quirk->chip_device) {
+		    pdev->vendor == quirk->chip_vendor &&
+		    pdev->device == quirk->chip_device) {
 			agpmode = quirk->mode;
 			NV_INFO(drm, "Forcing agp mode to %dX. Use agpmode to override.\n",
 				agpmode);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 6024edf8529e..373fbd2d14ff 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -209,7 +209,7 @@ nouveau_bo_new(struct drm_device *dev, int size, int align,
 	nvbo->tile_flags = tile_flags;
 	nvbo->bo.bdev = &drm->ttm.bdev;
 
-	if (!nv_device_is_cpu_coherent(nvxx_device(&drm->device)))
+	if (!nvxx_device(&drm->device)->func->cpu_coherent)
 		nvbo->force_coherent = flags & TTM_PL_FLAG_UNCACHED;
 
 	nvbo->page_shift = 12;
@@ -466,8 +466,8 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo)
 		return;
 
 	for (i = 0; i < ttm_dma->ttm.num_pages; i++)
-		dma_sync_single_for_device(nv_device_base(device),
-			ttm_dma->dma_address[i], PAGE_SIZE, DMA_TO_DEVICE);
+		dma_sync_single_for_device(device->dev, ttm_dma->dma_address[i],
+					   PAGE_SIZE, DMA_TO_DEVICE);
 }
 
 void
@@ -486,8 +486,8 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo)
 		return;
 
 	for (i = 0; i < ttm_dma->ttm.num_pages; i++)
-		dma_sync_single_for_cpu(nv_device_base(device),
-			ttm_dma->dma_address[i], PAGE_SIZE, DMA_FROM_DEVICE);
+		dma_sync_single_for_cpu(device->dev, ttm_dma->dma_address[i],
+					PAGE_SIZE, DMA_FROM_DEVICE);
 }
 
 int
@@ -1487,13 +1487,13 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
 	drm = nouveau_bdev(ttm->bdev);
 	device = nvxx_device(&drm->device);
 	dev = drm->dev;
-	pdev = nv_device_base(device);
+	pdev = device->dev;
 
 	/*
 	 * Objects matching this condition have been marked as force_coherent,
 	 * so use the DMA API for them.
 	 */
-	if (!nv_device_is_cpu_coherent(device) &&
+	if (!nvxx_device(&drm->device)->func->cpu_coherent &&
 	    ttm->caching_state == tt_uncached)
 		return ttm_dma_populate(ttm_dma, dev->dev);
 
@@ -1552,13 +1552,13 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
 	drm = nouveau_bdev(ttm->bdev);
 	device = nvxx_device(&drm->device);
 	dev = drm->dev;
-	pdev = nv_device_base(device);
+	pdev = device->dev;
 
 	/*
 	 * Objects matching this condition have been marked as force_coherent,
 	 * so use the DMA API for them.
 	 */
-	if (!nv_device_is_cpu_coherent(device) &&
+	if (!nvxx_device(&drm->device)->func->cpu_coherent &&
 	    ttm->caching_state == tt_uncached) {
 		ttm_dma_unpopulate(ttm_dma, dev->dev);
 		return;
diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
index ce612064fa6a..d12a5faee047 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c
@@ -165,7 +165,7 @@ nouveau_sysfs_fini(struct drm_device *dev)
 	struct nvif_device *device = &drm->device;
 
 	if (sysfs && sysfs->ctrl.priv) {
-		device_remove_file(nv_device_base(nvxx_device(device)), &dev_attr_pstate);
+		device_remove_file(nvxx_device(device)->dev, &dev_attr_pstate);
 		nvif_object_fini(&sysfs->ctrl);
 	}
 
@@ -192,7 +192,7 @@ nouveau_sysfs_init(struct drm_device *dev)
 			       NVIF_IOCTL_NEW_V0_CONTROL, NULL, 0,
 			       &sysfs->ctrl);
 	if (ret == 0)
-		device_create_file(nv_device_base(nvxx_device(device)), &dev_attr_pstate);
+		device_create_file(nvxx_device(device)->dev, &dev_attr_pstate);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 1fd70d6900cf..ba9fd151bd28 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -341,7 +341,7 @@ nouveau_ttm_init(struct nouveau_drm *drm)
 	int ret;
 
 	bits = nvxx_mmu(&drm->device)->dma_bits;
-	if (nv_device_is_pci(nvxx_device(&drm->device))) {
+	if (nvxx_device(&drm->device)->func->pci) {
 		if (drm->agp.stat == ENABLED ||
 		     !pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits)))
 			bits = 32;
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 57b13602b2c5..4ae87aed4505 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -210,8 +210,8 @@ nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp)
 	nv50_chan_destroy(&dmac->base);
 
 	if (dmac->ptr) {
-		struct pci_dev *pdev = nvxx_device(device)->pdev;
-		pci_free_consistent(pdev, PAGE_SIZE, dmac->ptr, dmac->handle);
+		struct device *dev = nvxx_device(device)->dev;
+		dma_free_coherent(dev, PAGE_SIZE, dmac->ptr, dmac->handle);
 	}
 }
 
@@ -226,8 +226,8 @@ nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp,
 
 	mutex_init(&dmac->lock);
 
-	dmac->ptr = pci_alloc_consistent(nvxx_device(device)->pdev,
-					 PAGE_SIZE, &dmac->handle);
+	dmac->ptr = dma_alloc_coherent(nvxx_device(device)->dev, PAGE_SIZE,
+				       &dmac->handle, GFP_KERNEL);
 	if (!dmac->ptr)
 		return -ENOMEM;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index b8d46144e68a..94a906b8cb88 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -2294,7 +2294,7 @@ nvkm_device_del(struct nvkm_device **pdevice)
 int
 nvkm_device_ctor(const struct nvkm_device_func *func,
 		 const struct nvkm_device_quirk *quirk,
-		 void *dev, enum nv_bus_type type, u64 handle,
+		 struct device *dev, enum nvkm_device_type type, u64 handle,
 		 const char *name, const char *cfg, const char *dbg,
 		 bool detect, bool mmio, u64 subdev_mask,
 		 struct nvkm_device *device)
@@ -2312,16 +2312,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
 
 	device->func = func;
 	device->quirk = quirk;
-	switch (type) {
-	case NVKM_BUS_PCI:
-		device->pdev = dev;
-		device->dev = &device->pdev->dev;
-		break;
-	case NVKM_BUS_PLATFORM:
-		device->platformdev = dev;
-		device->dev = &device->platformdev->dev;
-		break;
-	}
+	device->dev = dev;
+	device->type = type;
 	device->handle = handle;
 	device->cfgopt = cfg;
 	device->dbgopt = dbg;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
index 8702a9efc7b4..9dd1cac81e80 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
@@ -1621,6 +1621,7 @@ nvkm_device_pci_func = {
 	.fini = nvkm_device_pci_fini,
 	.resource_addr = nvkm_device_pci_resource_addr,
 	.resource_size = nvkm_device_pci_resource_size,
+	.cpu_coherent = !IS_ENABLED(CONFIG_ARM),
 };
 
 int
@@ -1671,8 +1672,10 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg,
 	*pdevice = &pdev->device;
 	pdev->pdev = pci_dev;
 
-	return nvkm_device_ctor(&nvkm_device_pci_func, quirk,
-				pci_dev, NVKM_BUS_PCI,
+	return nvkm_device_ctor(&nvkm_device_pci_func, quirk, &pci_dev->dev,
+				pci_is_pcie(pci_dev) ? NVKM_DEVICE_PCIE :
+				pci_find_capability(pci_dev, PCI_CAP_ID_AGP) ?
+				NVKM_DEVICE_AGP : NVKM_DEVICE_PCI,
 				(u64)pci_domain_nr(pci_dev->bus) << 32 |
 				     pci_dev->bus->number << 16 |
 				     PCI_SLOT(pci_dev->devfn) << 8 |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h
index 6dea6e8fc854..ed3ad2c30e17 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h
@@ -41,7 +41,7 @@
 
 int  nvkm_device_ctor(const struct nvkm_device_func *,
 		      const struct nvkm_device_quirk *,
-		      void *, enum nv_bus_type type, u64 handle,
+		      struct device *, enum nvkm_device_type, u64 handle,
 		      const char *name, const char *cfg, const char *dbg,
 		      bool detect, bool mmio, u64 subdev_mask,
 		      struct nvkm_device *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
index f4bc11c1671f..ada73e13d1af 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
@@ -102,6 +102,7 @@ nvkm_device_tegra_func = {
 	.fini = nvkm_device_tegra_fini,
 	.resource_addr = nvkm_device_tegra_resource_addr,
 	.resource_size = nvkm_device_tegra_resource_size,
+	.cpu_coherent = false,
 };
 
 int
@@ -118,8 +119,8 @@ nvkm_device_tegra_new(struct platform_device *pdev,
 	tdev->pdev = pdev;
 	tdev->irq = -1;
 
-	return nvkm_device_ctor(&nvkm_device_tegra_func, NULL, pdev,
-				NVKM_BUS_PLATFORM, pdev->id, NULL,
+	return nvkm_device_ctor(&nvkm_device_tegra_func, NULL, &pdev->dev,
+				NVKM_DEVICE_TEGRA, pdev->id, NULL,
 				cfg, dbg, detect, mmio, subdev_mask,
 				&tdev->device);
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
index eddf9b1d3340..1ae48f27029d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
@@ -70,16 +70,22 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size)
 		args->v0.platform = NV_DEVICE_INFO_V0_IGP;
 		break;
 	default:
-		if (device->pdev) {
-			if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP))
-				args->v0.platform = NV_DEVICE_INFO_V0_AGP;
-			else
-			if (pci_is_pcie(device->pdev))
-				args->v0.platform = NV_DEVICE_INFO_V0_PCIE;
-			else
-				args->v0.platform = NV_DEVICE_INFO_V0_PCI;
-		} else {
+		switch (device->type) {
+		case NVKM_DEVICE_PCI:
+			args->v0.platform = NV_DEVICE_INFO_V0_PCI;
+			break;
+		case NVKM_DEVICE_AGP:
+			args->v0.platform = NV_DEVICE_INFO_V0_AGP;
+			break;
+		case NVKM_DEVICE_PCIE:
+			args->v0.platform = NV_DEVICE_INFO_V0_PCIE;
+			break;
+		case NVKM_DEVICE_TEGRA:
 			args->v0.platform = NV_DEVICE_INFO_V0_SOC;
+			break;
+		default:
+			WARN_ON(1);
+			break;
 		}
 		break;
 	}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
index 2d11b328bee1..74000602fbb1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
@@ -190,7 +190,7 @@ nvkm_falcon_init(struct nvkm_engine *engine)
 		snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03x",
 			 device->chipset, falcon->addr >> 12);
 
-		ret = request_firmware(&fw, name, nv_device_base(device));
+		ret = request_firmware(&fw, name, device->dev);
 		if (ret == 0) {
 			falcon->code.data = vmemdup(fw->data, fw->size);
 			falcon->code.size = fw->size;
@@ -209,7 +209,7 @@ nvkm_falcon_init(struct nvkm_engine *engine)
 		snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03xd",
 			 device->chipset, falcon->addr >> 12);
 
-		ret = request_firmware(&fw, name, nv_device_base(device));
+		ret = request_firmware(&fw, name, device->dev);
 		if (ret) {
 			nvkm_error(subdev, "unable to load firmware data\n");
 			return -ENODEV;
@@ -224,7 +224,7 @@ nvkm_falcon_init(struct nvkm_engine *engine)
 		snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03xc",
 			 device->chipset, falcon->addr >> 12);
 
-		ret = request_firmware(&fw, name, nv_device_base(device));
+		ret = request_firmware(&fw, name, device->dev);
 		if (ret) {
 			nvkm_error(subdev, "unable to load firmware code\n");
 			return -ENODEV;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
index 1ad6785683f2..f1358a564e3e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -1642,7 +1642,7 @@ gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
 	}
 
 	snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname);
-	ret = request_firmware(&fw, f, nv_device_base(device));
+	ret = request_firmware(&fw, f, device->dev);
 	if (ret) {
 		nvkm_error(subdev, "failed to load %s\n", fwname);
 		return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c
index d6a2b9593538..a3d4f5bcec7a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c
@@ -107,7 +107,7 @@ nvkm_xtensa_init(struct nvkm_engine *engine)
 		snprintf(name, sizeof(name), "nouveau/nv84_xuc%03x",
 			 xtensa->addr >> 12);
 
-		ret = request_firmware(&fw, name, nv_device_base(device));
+		ret = request_firmware(&fw, name, device->dev);
 		if (ret) {
 			nvkm_warn(subdev, "unable to load firmware %s\n", name);
 			return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
index b089a11ba08c..792f017525f6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
@@ -134,7 +134,7 @@ shadow_fw_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
 static void *
 shadow_fw_init(struct nvkm_bios *bios, const char *name)
 {
-	struct device *dev = &bios->subdev.device->pdev->dev;
+	struct device *dev = bios->subdev.device->dev;
 	const struct firmware *fw;
 	int ret = request_firmware(&fw, name, dev);
 	if (ret)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c
index 468066817c75..8fecb5ff22a0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c
@@ -24,10 +24,10 @@
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_X86)
 int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
-bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
+bool nouveau_acpi_rom_supported(struct device *);
 #else
 static inline bool
-nouveau_acpi_rom_supported(struct pci_dev *pdev)
+nouveau_acpi_rom_supported(struct device *dev)
 {
 	return false;
 }
@@ -88,7 +88,7 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
 static void *
 acpi_init(struct nvkm_bios *bios, const char *name)
 {
-	if (!nouveau_acpi_rom_supported(bios->subdev.device->pdev))
+	if (!nouveau_acpi_rom_supported(bios->subdev.device->dev))
 		return ERR_PTR(-ENODEV);
 	return NULL;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
index 0979bc89eeab..9b91da09dc5f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c
@@ -22,6 +22,8 @@
  */
 #include "priv.h"
 
+#include <core/pci.h>
+
 struct priv {
 	struct pci_dev *pdev;
 	void __iomem *rom;
@@ -51,10 +53,16 @@ pcirom_fini(void *data)
 static void *
 pcirom_init(struct nvkm_bios *bios, const char *name)
 {
-	struct pci_dev *pdev = bios->subdev.device->pdev;
+	struct nvkm_device *device = bios->subdev.device;
 	struct priv *priv = NULL;
+	struct pci_dev *pdev;
 	int ret;
 
+	if (device->func->pci)
+		pdev = device->func->pci(device)->pdev;
+	else
+		return ERR_PTR(-ENODEV);
+
 	if (!(ret = pci_enable_rom(pdev))) {
 		if (ret = -ENOMEM,
 		    (priv = kmalloc(sizeof(*priv), GFP_KERNEL))) {
@@ -83,10 +91,16 @@ nvbios_pcirom = {
 static void *
 platform_init(struct nvkm_bios *bios, const char *name)
 {
-	struct pci_dev *pdev = bios->subdev.device->pdev;
+	struct nvkm_device *device = bios->subdev.device;
+	struct pci_dev *pdev;
 	struct priv *priv;
 	int ret = -ENOMEM;
 
+	if (device->func->pci)
+		pdev = device->func->pci(device)->pdev;
+	else
+		return ERR_PTR(-ENODEV);
+
 	if ((priv = kmalloc(sizeof(*priv), GFP_KERNEL))) {
 		if (ret = -ENODEV,
 		    (priv->rom = pci_platform_rom(pdev, &priv->size)))
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
index ef3149aa5124..008bb9849f3b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
@@ -65,7 +65,7 @@ gf100_fb_dtor(struct nvkm_fb *base)
 	struct nvkm_device *device = fb->base.subdev.device;
 
 	if (fb->r100c10_page) {
-		dma_unmap_page(nv_device_base(device), fb->r100c10, PAGE_SIZE,
+		dma_unmap_page(device->dev, fb->r100c10, PAGE_SIZE,
 			       DMA_BIDIRECTIONAL);
 		__free_page(fb->r100c10_page);
 	}
@@ -86,10 +86,9 @@ gf100_fb_new_(const struct nvkm_fb_func *func, struct nvkm_device *device,
 
 	fb->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
 	if (fb->r100c10_page) {
-		fb->r100c10 = dma_map_page(nv_device_base(device),
-					     fb->r100c10_page, 0, PAGE_SIZE,
-					     DMA_BIDIRECTIONAL);
-		if (dma_mapping_error(nv_device_base(device), fb->r100c10))
+		fb->r100c10 = dma_map_page(device->dev, fb->r100c10_page, 0,
+					   PAGE_SIZE, DMA_BIDIRECTIONAL);
+		if (dma_mapping_error(device->dev, fb->r100c10))
 			return -EFAULT;
 	}
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c
index c2b6ccde7473..f5edfadb5b46 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c
@@ -234,7 +234,7 @@ nv50_fb_dtor(struct nvkm_fb *base)
 	struct nvkm_device *device = fb->base.subdev.device;
 
 	if (fb->r100c08_page) {
-		dma_unmap_page(nv_device_base(device), fb->r100c08, PAGE_SIZE,
+		dma_unmap_page(device->dev, fb->r100c08, PAGE_SIZE,
 			       DMA_BIDIRECTIONAL);
 		__free_page(fb->r100c08_page);
 	}
@@ -265,10 +265,9 @@ nv50_fb_new_(const struct nv50_fb_func *func, struct nvkm_device *device,
 
 	fb->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
 	if (fb->r100c08_page) {
-		fb->r100c08 = dma_map_page(nv_device_base(device),
-					     fb->r100c08_page, 0, PAGE_SIZE,
-					     DMA_BIDIRECTIONAL);
-		if (dma_mapping_error(nv_device_base(device), fb->r100c08))
+		fb->r100c08 = dma_map_page(device->dev, fb->r100c08_page, 0,
+					   PAGE_SIZE, DMA_BIDIRECTIONAL);
+		if (dma_mapping_error(device->dev, fb->r100c08))
 			return -EFAULT;
 	} else {
 		nvkm_warn(&fb->base.subdev, "failed 100c08 page alloc\n");
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index ab01989c3430..5ef04b72a80a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -186,7 +186,7 @@ gk20a_instobj_dtor_dma(struct gk20a_instobj *_node)
 {
 	struct gk20a_instobj_dma *node = (void *)_node;
 	struct gk20a_instmem *imem = _node->imem;
-	struct device *dev = nv_device_base(imem->base.subdev.device);
+	struct device *dev = imem->base.subdev.device->dev;
 
 	if (unlikely(!node->cpuaddr))
 		return;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c
index 5def412f0467..37927c3fdc3e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv04.c
@@ -110,8 +110,8 @@ nv04_mmu_dtor(struct nvkm_mmu *base)
 		nvkm_vm_ref(NULL, &mmu->vm, NULL);
 	}
 	if (mmu->nullp) {
-		pci_free_consistent(device->pdev, 16 * 1024,
-				    mmu->nullp, mmu->null);
+		dma_free_coherent(device->dev, 16 * 1024,
+				  mmu->nullp, mmu->null);
 	}
 	return mmu;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c
index f30c3b890626..c6a26f907009 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv41.c
@@ -133,7 +133,7 @@ nv41_mmu = {
 int
 nv41_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu)
 {
-	if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
+	if (device->type == NVKM_DEVICE_AGP ||
 	    !nvkm_boolopt(device->cfgopt, "NvPCIE", true))
 		return nv04_mmu_new(device, index, pmmu);
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c
index 7c37bd84b862..a648c2395545 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/nv44.c
@@ -165,7 +165,8 @@ nv44_mmu_oneinit(struct nvkm_mmu *base)
 	struct nvkm_device *device = mmu->base.subdev.device;
 	int ret;
 
-	mmu->nullp = pci_alloc_consistent(device->pdev, 16 * 1024, &mmu->null);
+	mmu->nullp = dma_alloc_coherent(device->dev, 16 * 1024,
+					&mmu->null, GFP_KERNEL);
 	if (!mmu->nullp) {
 		nvkm_warn(&mmu->base.subdev, "unable to allocate dummy pages\n");
 		mmu->null = 0;
@@ -227,7 +228,7 @@ nv44_mmu = {
 int
 nv44_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu)
 {
-	if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
+	if (device->type == NVKM_DEVICE_AGP ||
 	    !nvkm_boolopt(device->cfgopt, "NvPCIE", true))
 		return nv04_mmu_new(device, index, pmmu);
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c
index 442b5e200a77..9700a7625012 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c
@@ -95,7 +95,7 @@ mxm_shadow_dsm(struct nvkm_mxm *mxm, u8 version)
 	acpi_handle handle;
 	int rev;
 
-	handle = ACPI_HANDLE(nv_device_base(device));
+	handle = ACPI_HANDLE(device->dev);
 	if (!handle)
 		return false;
 
-- 
cgit v1.2.3-70-g09d2


From 43a70661eaa64aa4e36e421eee3b9ded3190837b Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 14:54:23 +1000
Subject: drm/nouveau/tegra: merge platform setup from nouveau drm

The copyright header in nvkm/engine/device/platform.c has been replaced
with the NVIDIA one from drm/nouveau_platform.c, as most of the actual
code is now theirs.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---
 drivers/gpu/drm/nouveau/include/nvif/os.h          |   3 +
 drivers/gpu/drm/nouveau/include/nvkm/core/device.h |   2 -
 drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h  |  20 ++
 drivers/gpu/drm/nouveau/nouveau_platform.c         | 224 +--------------------
 drivers/gpu/drm/nouveau/nouveau_platform.h         |  37 +---
 drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 181 ++++++++++++++++-
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c    |   8 +-
 .../gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c    |  20 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c   |  11 +-
 9 files changed, 221 insertions(+), 285 deletions(-)

(limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c')

diff --git a/drivers/gpu/drm/nouveau/include/nvif/os.h b/drivers/gpu/drm/nouveau/include/nvif/os.h
index 97317f7fe4e5..3accc99d8e0b 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/os.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/os.h
@@ -25,10 +25,13 @@
 #include <linux/clk.h>
 #include <linux/regulator/consumer.h>
 #include <linux/agp_backend.h>
+#include <linux/reset.h>
+#include <linux/iommu.h>
 
 #include <asm/unaligned.h>
 
 #include <soc/tegra/fuse.h>
+#include <soc/tegra/pmc.h>
 
 #ifndef ioread32_native
 #ifdef __BIG_ENDIAN
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
index 773951bfd200..8f760002e401 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
@@ -139,8 +139,6 @@ struct nvkm_device {
 	struct nvkm_sw *sw;
 	struct nvkm_engine *vic;
 	struct nvkm_engine *vp;
-
-	struct nouveau_platform_gpu *gpu;
 };
 
 struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int index);
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
index 1755c2d30fcd..5aa2480da25f 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
@@ -1,11 +1,31 @@
 #ifndef __NVKM_DEVICE_TEGRA_H__
 #define __NVKM_DEVICE_TEGRA_H__
 #include <core/device.h>
+#include <core/mm.h>
 
 struct nvkm_device_tegra {
 	struct nvkm_device device;
 	struct platform_device *pdev;
 	int irq;
+
+	struct reset_control *rst;
+	struct clk *clk;
+	struct clk *clk_pwr;
+
+	struct regulator *vdd;
+
+	struct {
+		/*
+		 * Protects accesses to mm from subsystems
+		 */
+		struct mutex mutex;
+
+		struct nvkm_mm mm;
+		struct iommu_domain *domain;
+		unsigned long pgshift;
+	} iommu;
+
+	int gpu_speedo;
 };
 
 int nvkm_device_tegra_new(struct platform_device *,
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c
index c03736bce953..3eb665453165 100644
--- a/drivers/gpu/drm/nouveau/nouveau_platform.c
+++ b/drivers/gpu/drm/nouveau/nouveau_platform.c
@@ -19,234 +19,32 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/reset.h>
-#include <linux/regulator/consumer.h>
-#include <linux/iommu.h>
-#include <soc/tegra/fuse.h>
-#include <soc/tegra/pmc.h>
-
-#include "nouveau_drm.h"
 #include "nouveau_platform.h"
 
-static int nouveau_platform_power_up(struct nouveau_platform_gpu *gpu)
-{
-	int err;
-
-	err = regulator_enable(gpu->vdd);
-	if (err)
-		goto err_power;
-
-	err = clk_prepare_enable(gpu->clk);
-	if (err)
-		goto err_clk;
-	err = clk_prepare_enable(gpu->clk_pwr);
-	if (err)
-		goto err_clk_pwr;
-	clk_set_rate(gpu->clk_pwr, 204000000);
-	udelay(10);
-
-	reset_control_assert(gpu->rst);
-	udelay(10);
-
-	err = tegra_powergate_remove_clamping(TEGRA_POWERGATE_3D);
-	if (err)
-		goto err_clamp;
-	udelay(10);
-
-	reset_control_deassert(gpu->rst);
-	udelay(10);
-
-	return 0;
-
-err_clamp:
-	clk_disable_unprepare(gpu->clk_pwr);
-err_clk_pwr:
-	clk_disable_unprepare(gpu->clk);
-err_clk:
-	regulator_disable(gpu->vdd);
-err_power:
-	return err;
-}
-
-static int nouveau_platform_power_down(struct nouveau_platform_gpu *gpu)
-{
-	int err;
-
-	reset_control_assert(gpu->rst);
-	udelay(10);
-
-	clk_disable_unprepare(gpu->clk_pwr);
-	clk_disable_unprepare(gpu->clk);
-	udelay(10);
-
-	err = regulator_disable(gpu->vdd);
-	if (err)
-		return err;
-
-	return 0;
-}
-
-#if IS_ENABLED(CONFIG_IOMMU_API)
-
-static void nouveau_platform_probe_iommu(struct device *dev,
-					 struct nouveau_platform_gpu *gpu)
-{
-	int err;
-	unsigned long pgsize_bitmap;
-
-	mutex_init(&gpu->iommu.mutex);
-
-	if (iommu_present(&platform_bus_type)) {
-		gpu->iommu.domain = iommu_domain_alloc(&platform_bus_type);
-		if (IS_ERR(gpu->iommu.domain))
-			goto error;
-
-		/*
-		 * A IOMMU is only usable if it supports page sizes smaller
-		 * or equal to the system's PAGE_SIZE, with a preference if
-		 * both are equal.
-		 */
-		pgsize_bitmap = gpu->iommu.domain->ops->pgsize_bitmap;
-		if (pgsize_bitmap & PAGE_SIZE) {
-			gpu->iommu.pgshift = PAGE_SHIFT;
-		} else {
-			gpu->iommu.pgshift = fls(pgsize_bitmap & ~PAGE_MASK);
-			if (gpu->iommu.pgshift == 0) {
-				dev_warn(dev, "unsupported IOMMU page size\n");
-				goto free_domain;
-			}
-			gpu->iommu.pgshift -= 1;
-		}
-
-		err = iommu_attach_device(gpu->iommu.domain, dev);
-		if (err)
-			goto free_domain;
-
-		err = nvkm_mm_init(&gpu->iommu._mm, 0,
-				   (1ULL << 40) >> gpu->iommu.pgshift, 1);
-		if (err)
-			goto detach_device;
-
-		gpu->iommu.mm = &gpu->iommu._mm;
-	}
-
-	return;
-
-detach_device:
-	iommu_detach_device(gpu->iommu.domain, dev);
-
-free_domain:
-	iommu_domain_free(gpu->iommu.domain);
-
-error:
-	gpu->iommu.domain = NULL;
-	gpu->iommu.pgshift = 0;
-	dev_err(dev, "cannot initialize IOMMU MM\n");
-}
-
-static void nouveau_platform_remove_iommu(struct device *dev,
-					  struct nouveau_platform_gpu *gpu)
-{
-	if (gpu->iommu.domain) {
-		nvkm_mm_fini(&gpu->iommu._mm);
-		iommu_detach_device(gpu->iommu.domain, dev);
-		iommu_domain_free(gpu->iommu.domain);
-	}
-}
-
-#else
-
-static void nouveau_platform_probe_iommu(struct device *dev,
-					 struct nouveau_platform_gpu *gpu)
-{
-}
-
-static void nouveau_platform_remove_iommu(struct device *dev,
-					  struct nouveau_platform_gpu *gpu)
-{
-}
-
-#endif
-
 static int nouveau_platform_probe(struct platform_device *pdev)
 {
-	struct nouveau_platform_gpu *gpu;
 	struct nvkm_device *device;
 	struct drm_device *drm;
-	int err;
-
-	gpu = devm_kzalloc(&pdev->dev, sizeof(*gpu), GFP_KERNEL);
-	if (!gpu)
-		return -ENOMEM;
-
-	gpu->vdd = devm_regulator_get(&pdev->dev, "vdd");
-	if (IS_ERR(gpu->vdd))
-		return PTR_ERR(gpu->vdd);
-
-	gpu->rst = devm_reset_control_get(&pdev->dev, "gpu");
-	if (IS_ERR(gpu->rst))
-		return PTR_ERR(gpu->rst);
-
-	gpu->clk = devm_clk_get(&pdev->dev, "gpu");
-	if (IS_ERR(gpu->clk))
-		return PTR_ERR(gpu->clk);
-
-	gpu->clk_pwr = devm_clk_get(&pdev->dev, "pwr");
-	if (IS_ERR(gpu->clk_pwr))
-		return PTR_ERR(gpu->clk_pwr);
-
-	nouveau_platform_probe_iommu(&pdev->dev, gpu);
-
-	err = nouveau_platform_power_up(gpu);
-	if (err)
-		return err;
+	int ret;
 
 	drm = nouveau_platform_device_create(pdev, &device);
-	if (IS_ERR(drm)) {
-		err = PTR_ERR(drm);
-		goto power_down;
-	}
+	if (IS_ERR(drm))
+		return PTR_ERR(drm);
 
-	device->gpu = gpu;
-	gpu->gpu_speedo = tegra_sku_info.gpu_speedo_value;
-
-	err = drm_dev_register(drm, 0);
-	if (err < 0)
-		goto err_unref;
+	ret = drm_dev_register(drm, 0);
+	if (ret < 0) {
+		drm_dev_unref(drm);
+		return ret;
+	}
 
 	return 0;
-
-err_unref:
-	drm_dev_unref(drm);
-
-power_down:
-	nouveau_platform_power_down(gpu);
-	nouveau_platform_remove_iommu(&pdev->dev, gpu);
-
-	return err;
 }
 
 static int nouveau_platform_remove(struct platform_device *pdev)
 {
-	struct drm_device *drm_dev = platform_get_drvdata(pdev);
-	struct nouveau_drm *drm = nouveau_drm(drm_dev);
-	struct nvkm_device *device = nvxx_device(&drm->device);
-	struct nouveau_platform_gpu *gpu = device->gpu;
-	int err;
-
-	nouveau_drm_device_remove(drm_dev);
-
-	err = nouveau_platform_power_down(gpu);
-
-	nouveau_platform_remove_iommu(&pdev->dev, gpu);
-
-	return err;
+	struct drm_device *dev = platform_get_drvdata(pdev);
+	nouveau_drm_device_remove(dev);
+	return 0;
 }
 
 #if IS_ENABLED(CONFIG_OF)
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.h b/drivers/gpu/drm/nouveau/nouveau_platform.h
index 7a4020f31cc5..f41056d0f5f4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_platform.h
+++ b/drivers/gpu/drm/nouveau/nouveau_platform.h
@@ -19,44 +19,9 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-
 #ifndef __NOUVEAU_PLATFORM_H__
 #define __NOUVEAU_PLATFORM_H__
-
-#include "core/device.h"
-#include "core/mm.h"
-
-struct reset_control;
-struct clk;
-struct regulator;
-struct iommu_domain;
-struct platform_driver;
-
-struct nouveau_platform_gpu {
-	struct reset_control *rst;
-	struct clk *clk;
-	struct clk *clk_pwr;
-
-	struct regulator *vdd;
-
-	struct {
-		/*
-		 * Protects accesses to mm from subsystems
-		 */
-		struct mutex mutex;
-
-		struct nvkm_mm _mm;
-		/*
-		 * Just points to _mm. We need this to avoid embedding
-		 * struct nvkm_mm in os.h
-		 */
-		struct nvkm_mm *mm;
-		struct iommu_domain *domain;
-		unsigned long pgshift;
-	} iommu;
-
-	int gpu_speedo;
-};
+#include "nouveau_drm.h"
 
 extern struct platform_driver nouveau_platform_driver;
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
index ada73e13d1af..da57c8a60608 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Red Hat Inc.
+ * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -14,17 +14,138 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs <bskeggs@redhat.com>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  */
 #include <core/tegra.h>
 #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
 #include "priv.h"
 
+static int
+nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev)
+{
+	int ret;
+
+	ret = regulator_enable(tdev->vdd);
+	if (ret)
+		goto err_power;
+
+	ret = clk_prepare_enable(tdev->clk);
+	if (ret)
+		goto err_clk;
+	ret = clk_prepare_enable(tdev->clk_pwr);
+	if (ret)
+		goto err_clk_pwr;
+	clk_set_rate(tdev->clk_pwr, 204000000);
+	udelay(10);
+
+	reset_control_assert(tdev->rst);
+	udelay(10);
+
+	ret = tegra_powergate_remove_clamping(TEGRA_POWERGATE_3D);
+	if (ret)
+		goto err_clamp;
+	udelay(10);
+
+	reset_control_deassert(tdev->rst);
+	udelay(10);
+
+	return 0;
+
+err_clamp:
+	clk_disable_unprepare(tdev->clk_pwr);
+err_clk_pwr:
+	clk_disable_unprepare(tdev->clk);
+err_clk:
+	regulator_disable(tdev->vdd);
+err_power:
+	return ret;
+}
+
+static int
+nvkm_device_tegra_power_down(struct nvkm_device_tegra *tdev)
+{
+	reset_control_assert(tdev->rst);
+	udelay(10);
+
+	clk_disable_unprepare(tdev->clk_pwr);
+	clk_disable_unprepare(tdev->clk);
+	udelay(10);
+
+	return regulator_disable(tdev->vdd);
+}
+
+static void
+nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
+{
+#if IS_ENABLED(CONFIG_IOMMU_API)
+	struct device *dev = &tdev->pdev->dev;
+	unsigned long pgsize_bitmap;
+	int ret;
+
+	mutex_init(&tdev->iommu.mutex);
+
+	if (iommu_present(&platform_bus_type)) {
+		tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type);
+		if (IS_ERR(tdev->iommu.domain))
+			goto error;
+
+		/*
+		 * A IOMMU is only usable if it supports page sizes smaller
+		 * or equal to the system's PAGE_SIZE, with a preference if
+		 * both are equal.
+		 */
+		pgsize_bitmap = tdev->iommu.domain->ops->pgsize_bitmap;
+		if (pgsize_bitmap & PAGE_SIZE) {
+			tdev->iommu.pgshift = PAGE_SHIFT;
+		} else {
+			tdev->iommu.pgshift = fls(pgsize_bitmap & ~PAGE_MASK);
+			if (tdev->iommu.pgshift == 0) {
+				dev_warn(dev, "unsupported IOMMU page size\n");
+				goto free_domain;
+			}
+			tdev->iommu.pgshift -= 1;
+		}
+
+		ret = iommu_attach_device(tdev->iommu.domain, dev);
+		if (ret)
+			goto free_domain;
+
+		ret = nvkm_mm_init(&tdev->iommu.mm, 0,
+				   (1ULL << 40) >> tdev->iommu.pgshift, 1);
+		if (ret)
+			goto detach_device;
+	}
+
+	return;
+
+detach_device:
+	iommu_detach_device(tdev->iommu.domain, dev);
+
+free_domain:
+	iommu_domain_free(tdev->iommu.domain);
+
+error:
+	tdev->iommu.domain = NULL;
+	tdev->iommu.pgshift = 0;
+	dev_err(dev, "cannot initialize IOMMU MM\n");
+#endif
+}
+
+static void
+nvkm_device_tegra_remove_iommu(struct nvkm_device_tegra *tdev)
+{
+#if IS_ENABLED(CONFIG_IOMMU_API)
+	if (tdev->iommu.domain) {
+		nvkm_mm_fini(&tdev->iommu.mm);
+		iommu_detach_device(tdev->iommu.domain, tdev->device.dev);
+		iommu_domain_free(tdev->iommu.domain);
+	}
+#endif
+}
+
 static struct nvkm_device_tegra *
 nvkm_device_tegra(struct nvkm_device *device)
 {
@@ -95,9 +216,19 @@ nvkm_device_tegra_init(struct nvkm_device *device)
 	return 0;
 }
 
+static void *
+nvkm_device_tegra_dtor(struct nvkm_device *device)
+{
+	struct nvkm_device_tegra *tdev = nvkm_device_tegra(device);
+	nvkm_device_tegra_power_down(tdev);
+	nvkm_device_tegra_remove_iommu(tdev);
+	return tdev;
+}
+
 static const struct nvkm_device_func
 nvkm_device_tegra_func = {
 	.tegra = nvkm_device_tegra,
+	.dtor = nvkm_device_tegra_dtor,
 	.init = nvkm_device_tegra_init,
 	.fini = nvkm_device_tegra_fini,
 	.resource_addr = nvkm_device_tegra_resource_addr,
@@ -112,6 +243,7 @@ nvkm_device_tegra_new(struct platform_device *pdev,
 		      struct nvkm_device **pdevice)
 {
 	struct nvkm_device_tegra *tdev;
+	int ret;
 
 	if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL)))
 		return -ENOMEM;
@@ -119,10 +251,37 @@ nvkm_device_tegra_new(struct platform_device *pdev,
 	tdev->pdev = pdev;
 	tdev->irq = -1;
 
-	return nvkm_device_ctor(&nvkm_device_tegra_func, NULL, &pdev->dev,
-				NVKM_DEVICE_TEGRA, pdev->id, NULL,
-				cfg, dbg, detect, mmio, subdev_mask,
-				&tdev->device);
+	tdev->vdd = devm_regulator_get(&pdev->dev, "vdd");
+	if (IS_ERR(tdev->vdd))
+		return PTR_ERR(tdev->vdd);
+
+	tdev->rst = devm_reset_control_get(&pdev->dev, "gpu");
+	if (IS_ERR(tdev->rst))
+		return PTR_ERR(tdev->rst);
+
+	tdev->clk = devm_clk_get(&pdev->dev, "gpu");
+	if (IS_ERR(tdev->clk))
+		return PTR_ERR(tdev->clk);
+
+	tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr");
+	if (IS_ERR(tdev->clk_pwr))
+		return PTR_ERR(tdev->clk_pwr);
+
+	nvkm_device_tegra_probe_iommu(tdev);
+
+	ret = nvkm_device_tegra_power_up(tdev);
+	if (ret)
+		return ret;
+
+	tdev->gpu_speedo = tegra_sku_info.gpu_speedo_value;
+	ret = nvkm_device_ctor(&nvkm_device_tegra_func, NULL, &pdev->dev,
+			       NVKM_DEVICE_TEGRA, pdev->id, NULL,
+			       cfg, dbg, detect, mmio, subdev_mask,
+			       &tdev->device);
+	if (ret)
+		return ret;
+
+	return 0;
 }
 #else
 int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c
index 6a74ce3730d0..254094ab7fb8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c
@@ -25,12 +25,9 @@
 #define gk20a_clk(p) container_of((p), struct gk20a_clk, base)
 #include "priv.h"
 
+#include <core/tegra.h>
 #include <subdev/timer.h>
 
-#ifdef __KERNEL__
-#include <nouveau_platform.h>
-#endif
-
 #define MHZ (1000 * 1000)
 
 #define MASK(w)	((1 << w) - 1)
@@ -649,6 +646,7 @@ gk20a_clk = {
 int
 gk20a_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
 {
+	struct nvkm_device_tegra *tdev = device->func->tegra(device);
 	struct gk20a_clk *clk;
 	int ret, i;
 
@@ -663,7 +661,7 @@ gk20a_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
 	}
 
 	clk->params = &gk20a_pllg_params;
-	clk->parent_rate = clk_get_rate(device->gpu->clk);
+	clk->parent_rate = clk_get_rate(tdev->clk);
 
 	ret = nvkm_clk_ctor(&gk20a_clk, device, index, true, &clk->base);
 	nvkm_info(&clk->base.subdev, "parent clock rate: %d Mhz\n",
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index 5ef04b72a80a..cd7feb1b25f6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -42,14 +42,9 @@
 
 #include <core/memory.h>
 #include <core/mm.h>
+#include <core/tegra.h>
 #include <subdev/fb.h>
 
-#ifdef __KERNEL__
-#include <linux/dma-attrs.h>
-#include <linux/iommu.h>
-#include <nouveau_platform.h>
-#endif
-
 #define gk20a_instobj(p) container_of((p), struct gk20a_instobj, memory)
 
 struct gk20a_instobj {
@@ -423,8 +418,9 @@ gk20a_instmem = {
 
 int
 gk20a_instmem_new(struct nvkm_device *device, int index,
-		 struct nvkm_instmem **pimem)
+		  struct nvkm_instmem **pimem)
 {
+	struct nvkm_device_tegra *tdev = device->func->tegra(device);
 	struct gk20a_instmem *imem;
 
 	if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
@@ -433,11 +429,11 @@ gk20a_instmem_new(struct nvkm_device *device, int index,
 	spin_lock_init(&imem->lock);
 	*pimem = &imem->base;
 
-	if (device->gpu->iommu.domain) {
-		imem->domain = device->gpu->iommu.domain;
-		imem->mm = device->gpu->iommu.mm;
-		imem->iommu_pgshift = device->gpu->iommu.pgshift;
-		imem->mm_mutex = &device->gpu->iommu.mutex;
+	if (tdev->iommu.domain) {
+		imem->domain = tdev->iommu.domain;
+		imem->mm = &tdev->iommu.mm;
+		imem->iommu_pgshift = tdev->iommu.pgshift;
+		imem->mm_mutex = &tdev->iommu.mutex;
 
 		nvkm_info(&imem->base.subdev, "using IOMMU\n");
 	} else {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c
index 01394a05e9d8..fd56c6476064 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c
@@ -22,9 +22,7 @@
 #define gk20a_volt(p) container_of((p), struct gk20a_volt, base)
 #include "priv.h"
 
-#ifdef __KERNEL__
-#include <nouveau_platform.h>
-#endif
+#include <core/tegra.h>
 
 struct cvb_coef {
 	int c0;
@@ -159,6 +157,7 @@ gk20a_volt = {
 int
 gk20a_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt)
 {
+	struct nvkm_device_tegra *tdev = device->func->tegra(device);
 	struct gk20a_volt *volt;
 	int i, uv;
 
@@ -168,10 +167,10 @@ gk20a_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt)
 	nvkm_volt_ctor(&gk20a_volt, device, index, &volt->base);
 	*pvolt = &volt->base;
 
-	uv = regulator_get_voltage(device->gpu->vdd);
+	uv = regulator_get_voltage(tdev->vdd);
 	nvkm_info(&volt->base.subdev, "The default voltage is %duV\n", uv);
 
-	volt->vdd = device->gpu->vdd;
+	volt->vdd = tdev->vdd;
 
 	volt->base.vid_nr = ARRAY_SIZE(gk20a_cvb_coef);
 	nvkm_debug(&volt->base.subdev, "%s - vid_nr = %d\n", __func__,
@@ -180,7 +179,7 @@ gk20a_volt_new(struct nvkm_device *device, int index, struct nvkm_volt **pvolt)
 		volt->base.vid[i].vid = i;
 		volt->base.vid[i].uv =
 			gk20a_volt_calc_voltage(&gk20a_cvb_coef[i],
-						device->gpu->gpu_speedo);
+						tdev->gpu_speedo);
 		nvkm_debug(&volt->base.subdev, "%2d: vid=%d, uv=%d\n", i,
 			   volt->base.vid[i].vid, volt->base.vid[i].uv);
 	}
-- 
cgit v1.2.3-70-g09d2