drm/nv04-nv40/instmem: duplicate nv04 code as nv40, remove alternate paths
authorBen Skeggs <bskeggs@redhat.com>
Fri, 13 Jul 2012 06:14:25 +0000 (16:14 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 3 Oct 2012 03:12:49 +0000 (13:12 +1000)
A ton of duplication for the moment, will go away when they become subdevs.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_state.c

index 5e18a53e2c0c5b16b5c35f5fc1a3e9c3a0d86ade..68043a40d9ea29e2ff3af0a608208c9d5c4f44ca 100644 (file)
@@ -67,6 +67,7 @@ nouveau-y += core/subdev/i2c/base.o
 nouveau-y += core/subdev/i2c/aux.o
 nouveau-y += core/subdev/i2c/bit.o
 nouveau-y += core/subdev/instmem/nv04.o
+nouveau-y += core/subdev/instmem/nv40.o
 nouveau-y += core/subdev/instmem/nv50.o
 nouveau-y += core/subdev/instmem/nvc0.o
 nouveau-y += core/subdev/ltcg/nvc0.o
index f01063c078e6ec71a10b797c000f2b8c2d840667..8265ca8adf3fadcd9437ff7093bafcbd8b89d4f8 100644 (file)
@@ -11,9 +11,6 @@ nouveau_fifo_ctx_size(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
 
-       if (dev_priv->chipset >= 0x40)
-               return 128 * 32;
-       else
        if (dev_priv->chipset >= 0x17)
                return 64 * 32;
        else
@@ -32,27 +29,7 @@ int nv04_instmem_init(struct drm_device *dev)
 
        /* RAMIN always available */
        dev_priv->ramin_available = true;
-
-       /* Reserve space at end of VRAM for PRAMIN */
-       if (dev_priv->card_type >= NV_40) {
-               u32 vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8);
-               u32 rsvd;
-
-               /* estimate grctx size, the magics come from nv40_grctx.c */
-               if      (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs;
-               else if (dev_priv->chipset  < 0x43) rsvd = 0x4f00 * vs;
-               else if (nv44_graph_class(dev))     rsvd = 0x4980 * vs;
-               else                                rsvd = 0x4a40 * vs;
-               rsvd += 16 * 1024;
-               rsvd *= 32; /* per-channel */
-
-               rsvd += 512 * 1024; /* pci(e)gart table */
-               rsvd += 512 * 1024; /* object storage */
-
-               dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096);
-       } else {
-               dev_priv->ramin_rsvd_vram = 512 * 1024;
-       }
+       dev_priv->ramin_rsvd_vram = 512 * 1024;
 
        /* Setup shared RAMHT */
        ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096,
@@ -73,14 +50,7 @@ int nv04_instmem_init(struct drm_device *dev)
 
        /* And RAMFC */
        length = nouveau_fifo_ctx_size(dev);
-       switch (dev_priv->card_type) {
-       case NV_40:
-               offset = 0x20000;
-               break;
-       default:
-               offset = 0x11400;
-               break;
-       }
+       offset = 0x11400;
 
        ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length,
                                      NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc);
@@ -90,19 +60,6 @@ int nv04_instmem_init(struct drm_device *dev)
        /* Only allow space after RAMFC to be used for object allocation */
        offset += length;
 
-       /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
-        * on certain NV4x chipsets as well as RAMFC.  When 0x2230 == 0
-        * ("new style" control) the upper 16-bits of 0x2220 points at this
-        * other mysterious table that's clobbering important things.
-        *
-        * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
-        * smashed to pieces on us, so reserve 0x30000-0x40000 too..
-        */
-       if (dev_priv->card_type >= NV_40) {
-               if (offset < 0x40000)
-                       offset = 0x40000;
-       }
-
        ret = drm_mm_init(&dev_priv->ramin_heap, offset,
                          dev_priv->ramin_rsvd_vram - offset);
        if (ret) {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
new file mode 100644 (file)
index 0000000..a8c1104
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __NV04_INSTMEM_H__
+#define __NV04_INSTMEM_H__
+
+struct nv04_instmem_priv {
+       struct nouveau_gpuobj *vbios;
+       struct nouveau_gpuobj *ramht;
+       struct nouveau_gpuobj *ramro;
+       struct nouveau_gpuobj *ramfc;
+};
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c
new file mode 100644 (file)
index 0000000..91abf0b
--- /dev/null
@@ -0,0 +1,167 @@
+#include "drmP.h"
+#include "drm.h"
+
+#include "nouveau_drv.h"
+#include <engine/fifo.h>
+#include <core/ramht.h>
+
+/* returns the size of fifo context */
+static int
+nouveau_fifo_ctx_size(struct drm_device *dev)
+{
+       return 128 * 32;
+}
+
+int nv40_instmem_init(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_gpuobj *ramht = NULL;
+       u32 offset, length, vs, rsvd;
+       int ret;
+
+       /* RAMIN always available */
+       dev_priv->ramin_available = true;
+
+       /* Reserve space at end of VRAM for PRAMIN */
+       /* estimate grctx size, the magics come from nv40_grctx.c */
+       vs = hweight8((nv_rd32(dev, 0x001540) & 0x0000ff00) >> 8);
+       if      (dev_priv->chipset == 0x40) rsvd = 0x6aa0 * vs;
+       else if (dev_priv->chipset  < 0x43) rsvd = 0x4f00 * vs;
+       else if (nv44_graph_class(dev))     rsvd = 0x4980 * vs;
+       else                                rsvd = 0x4a40 * vs;
+       rsvd += 16 * 1024;
+       rsvd *= 32; /* per-channel */
+
+       rsvd += 512 * 1024; /* pci(e)gart table */
+       rsvd += 512 * 1024; /* object storage */
+
+       dev_priv->ramin_rsvd_vram = round_up(rsvd, 4096);
+
+       /* Setup shared RAMHT */
+       ret = nouveau_gpuobj_new_fake(dev, 0x10000, ~0, 4096,
+                                     NVOBJ_FLAG_ZERO_ALLOC, &ramht);
+       if (ret)
+               return ret;
+
+       ret = nouveau_ramht_new(dev, ramht, &dev_priv->ramht);
+       nouveau_gpuobj_ref(NULL, &ramht);
+       if (ret)
+               return ret;
+
+       /* And RAMRO */
+       ret = nouveau_gpuobj_new_fake(dev, 0x11200, ~0, 512,
+                                     NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramro);
+       if (ret)
+               return ret;
+
+       /* And RAMFC */
+       length = nouveau_fifo_ctx_size(dev);
+       offset = 0x20000;
+
+       ret = nouveau_gpuobj_new_fake(dev, offset, ~0, length,
+                                     NVOBJ_FLAG_ZERO_ALLOC, &dev_priv->ramfc);
+       if (ret)
+               return ret;
+
+       /* Only allow space after RAMFC to be used for object allocation */
+       offset += length;
+
+       /* It appears RAMRO (or something?) is controlled by 0x2220/0x2230
+        * on certain NV4x chipsets as well as RAMFC.  When 0x2230 == 0
+        * ("new style" control) the upper 16-bits of 0x2220 points at this
+        * other mysterious table that's clobbering important things.
+        *
+        * We're now pointing this at RAMIN+0x30000 to avoid RAMFC getting
+        * smashed to pieces on us, so reserve 0x30000-0x40000 too..
+        */
+       if (offset < 0x40000)
+               offset = 0x40000;
+
+       ret = drm_mm_init(&dev_priv->ramin_heap, offset,
+                         dev_priv->ramin_rsvd_vram - offset);
+       if (ret) {
+               NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+void
+nv40_instmem_takedown(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL);
+       nouveau_gpuobj_ref(NULL, &dev_priv->ramro);
+       nouveau_gpuobj_ref(NULL, &dev_priv->ramfc);
+
+       if (drm_mm_initialized(&dev_priv->ramin_heap))
+               drm_mm_takedown(&dev_priv->ramin_heap);
+}
+
+int
+nv40_instmem_suspend(struct drm_device *dev)
+{
+       return 0;
+}
+
+void
+nv40_instmem_resume(struct drm_device *dev)
+{
+}
+
+int
+nv40_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
+                u32 size, u32 align)
+{
+       struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
+       struct drm_mm_node *ramin = NULL;
+
+       do {
+               if (drm_mm_pre_get(&dev_priv->ramin_heap))
+                       return -ENOMEM;
+
+               spin_lock(&dev_priv->ramin_lock);
+               ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, align, 0);
+               if (ramin == NULL) {
+                       spin_unlock(&dev_priv->ramin_lock);
+                       return -ENOMEM;
+               }
+
+               ramin = drm_mm_get_block_atomic(ramin, size, align);
+               spin_unlock(&dev_priv->ramin_lock);
+       } while (ramin == NULL);
+
+       gpuobj->node  = ramin;
+       gpuobj->vinst = ramin->start;
+       return 0;
+}
+
+void
+nv40_instmem_put(struct nouveau_gpuobj *gpuobj)
+{
+       struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
+
+       spin_lock(&dev_priv->ramin_lock);
+       drm_mm_put_block(gpuobj->node);
+       gpuobj->node = NULL;
+       spin_unlock(&dev_priv->ramin_lock);
+}
+
+int
+nv40_instmem_map(struct nouveau_gpuobj *gpuobj)
+{
+       gpuobj->pinst = gpuobj->vinst;
+       return 0;
+}
+
+void
+nv40_instmem_unmap(struct nouveau_gpuobj *gpuobj)
+{
+}
+
+void
+nv40_instmem_flush(struct drm_device *dev)
+{
+}
index c7bc6ecad60192021bd9d1d64a7a7637ddc6eacb..ca88403be3f96b56705b4305b4a31f4fe84d69af 100644 (file)
@@ -1072,6 +1072,18 @@ extern int  nv04_instmem_map(struct nouveau_gpuobj *);
 extern void nv04_instmem_unmap(struct nouveau_gpuobj *);
 extern void nv04_instmem_flush(struct drm_device *);
 
+/* nv40_instmem.c */
+extern int  nv40_instmem_init(struct drm_device *);
+extern void nv40_instmem_takedown(struct drm_device *);
+extern int  nv40_instmem_suspend(struct drm_device *);
+extern void nv40_instmem_resume(struct drm_device *);
+extern int  nv40_instmem_get(struct nouveau_gpuobj *, struct nouveau_channel *,
+                            u32 size, u32 align);
+extern void nv40_instmem_put(struct nouveau_gpuobj *);
+extern int  nv40_instmem_map(struct nouveau_gpuobj *);
+extern void nv40_instmem_unmap(struct nouveau_gpuobj *);
+extern void nv40_instmem_flush(struct drm_device *);
+
 /* nv50_instmem.c */
 extern int  nv50_instmem_init(struct drm_device *);
 extern void nv50_instmem_takedown(struct drm_device *);
index d8d9e5c527a4aaba09563ff485f5b3bdcb98b3a2..14998ee89c949382f562e7251500228cf7c90f93 100644 (file)
@@ -135,15 +135,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                break;
        case 0x40:
        case 0x60:
-               engine->instmem.init            = nv04_instmem_init;
-               engine->instmem.takedown        = nv04_instmem_takedown;
-               engine->instmem.suspend         = nv04_instmem_suspend;
-               engine->instmem.resume          = nv04_instmem_resume;
-               engine->instmem.get             = nv04_instmem_get;
-               engine->instmem.put             = nv04_instmem_put;
-               engine->instmem.map             = nv04_instmem_map;
-               engine->instmem.unmap           = nv04_instmem_unmap;
-               engine->instmem.flush           = nv04_instmem_flush;
+               engine->instmem.init            = nv40_instmem_init;
+               engine->instmem.takedown        = nv40_instmem_takedown;
+               engine->instmem.suspend         = nv40_instmem_suspend;
+               engine->instmem.resume          = nv40_instmem_resume;
+               engine->instmem.get             = nv40_instmem_get;
+               engine->instmem.put             = nv40_instmem_put;
+               engine->instmem.map             = nv40_instmem_map;
+               engine->instmem.unmap           = nv40_instmem_unmap;
+               engine->instmem.flush           = nv40_instmem_flush;
                engine->display.early_init      = nv04_display_early_init;
                engine->display.late_takedown   = nv04_display_late_takedown;
                engine->display.create          = nv04_display_create;