drm/nouveau/fb: merge fb/vram and port to subdev interfaces
authorBen Skeggs <bskeggs@redhat.com>
Wed, 11 Jul 2012 09:05:01 +0000 (19:05 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 3 Oct 2012 03:12:49 +0000 (13:12 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
49 files changed:
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c
drivers/gpu/drm/nouveau/core/engine/graph/nv10.c
drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
drivers/gpu/drm/nouveau/core/include/subdev/fb.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/core/include/subdev/vm.h
drivers/gpu/drm/nouveau/core/subdev/device/nv04.c
drivers/gpu/drm/nouveau/core/subdev/device/nv10.c
drivers/gpu/drm/nouveau/core/subdev/device/nv20.c
drivers/gpu/drm/nouveau/core/subdev/device/nv30.c
drivers/gpu/drm/nouveau/core/subdev/device/nv40.c
drivers/gpu/drm/nouveau/core/subdev/device/nv50.c
drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c
drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
drivers/gpu/drm/nouveau/core/subdev/fb/base.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c
drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c
drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c
drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c
drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c
drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
drivers/gpu/drm/nouveau/core/subdev/fb/nv50_vram.c [deleted file]
drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
drivers/gpu/drm/nouveau/core/subdev/fb/nvc0_vram.c [deleted file]
drivers/gpu/drm/nouveau/core/subdev/instmem/nv50.c
drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_compat.c
drivers/gpu/drm/nouveau/nouveau_compat.h
drivers/gpu/drm/nouveau/nouveau_debugfs.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_fb.h
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nouveau_util.c
drivers/gpu/drm/nouveau/nouveau_util.h
drivers/gpu/drm/nouveau/nv50_evo.c
drivers/gpu/drm/nouveau/nv50_pm.c
drivers/gpu/drm/nouveau/nva3_pm.c
drivers/gpu/drm/nouveau/nvc0_pm.c
drivers/gpu/drm/nouveau/nvd0_display.c

index 0615e95..5e18a53 100644 (file)
@@ -8,6 +8,7 @@ ccflags-y += -I$(src)
 
 nouveau-y := core/core/client.o
 nouveau-y += core/core/engine.o
+nouveau-y += core/core/enum.o
 nouveau-y += core/core/handle.o
 nouveau-y += core/core/mm.o
 nouveau-y += core/core/namedb.o
@@ -50,6 +51,7 @@ nouveau-y += core/subdev/devinit/nv10.o
 nouveau-y += core/subdev/devinit/nv1a.o
 nouveau-y += core/subdev/devinit/nv20.o
 nouveau-y += core/subdev/devinit/nv50.o
+nouveau-y += core/subdev/fb/base.o
 nouveau-y += core/subdev/fb/nv04.o
 nouveau-y += core/subdev/fb/nv10.o
 nouveau-y += core/subdev/fb/nv20.o
@@ -57,8 +59,6 @@ nouveau-y += core/subdev/fb/nv30.o
 nouveau-y += core/subdev/fb/nv40.o
 nouveau-y += core/subdev/fb/nv50.o
 nouveau-y += core/subdev/fb/nvc0.o
-nouveau-y += core/subdev/fb/nv50_vram.o
-nouveau-y += core/subdev/fb/nvc0_vram.o
 nouveau-y += core/subdev/gpio/base.o
 nouveau-y += core/subdev/gpio/nv10.o
 nouveau-y += core/subdev/gpio/nv50.o
@@ -69,6 +69,7 @@ nouveau-y += core/subdev/i2c/bit.o
 nouveau-y += core/subdev/instmem/nv04.o
 nouveau-y += core/subdev/instmem/nv50.o
 nouveau-y += core/subdev/instmem/nvc0.o
+nouveau-y += core/subdev/ltcg/nvc0.o
 nouveau-y += core/subdev/mc/base.o
 nouveau-y += core/subdev/mc/nv04.o
 nouveau-y += core/subdev/mc/nv44.o
index 3079f08..23ae459 100644 (file)
@@ -163,7 +163,7 @@ nv40_fifo_init(struct drm_device *dev, int engine)
                break;
        default:
                nv_wr32(dev, 0x002230, 0x00000000);
-               nv_wr32(dev, 0x002220, ((dev_priv->vram_size - 512 * 1024 +
+               nv_wr32(dev, 0x002220, ((nvfb_vram_size(dev) - 512 * 1024 +
                                         dev_priv->ramfc->pinst) >> 16) |
                                       0x00030000);
                break;
index 19e303b..d006658 100644 (file)
@@ -895,9 +895,7 @@ nv10_graph_context_del(struct nouveau_channel *chan, int engine)
 static void
 nv10_graph_set_tile_region(struct drm_device *dev, int i)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
+       struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
        nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), tile->limit);
        nv_wr32(dev, NV10_PGRAPH_TSIZE(i), tile->pitch);
        nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr);
index 718ecf7..dd31156 100644 (file)
@@ -472,7 +472,7 @@ static void
 nv20_graph_set_tile_region(struct drm_device *dev, int i)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
+       struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
 
        nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit);
        nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch);
index 4ad9759..ab3af6d 100644 (file)
@@ -125,7 +125,7 @@ static void
 nv40_graph_set_tile_region(struct drm_device *dev, int i)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
+       struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
 
        switch (dev_priv->chipset) {
        case 0x40:
@@ -178,7 +178,6 @@ nv40_graph_init(struct drm_device *dev, int engine)
 {
        struct nv40_graph_engine *pgraph = nv_engine(dev, engine);
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
        uint32_t vramsz;
        int i, j;
 
@@ -280,7 +279,7 @@ nv40_graph_init(struct drm_device *dev, int engine)
        }
 
        /* Turn all the tiling regions off. */
-       for (i = 0; i < pfb->num_tiles; i++)
+       for (i = 0; i < nvfb_tile_nr(dev); i++)
                nv40_graph_set_tile_region(dev, i);
 
        /* begin RAM config */
index 4a14a67..eb5455f 100644 (file)
@@ -128,7 +128,6 @@ nv31_mpeg_object_new(struct nouveau_channel *chan, int engine,
 static int
 nv31_mpeg_init(struct drm_device *dev, int engine)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nv31_mpeg_engine *pmpeg = nv_engine(dev, engine);
        int i;
 
@@ -138,7 +137,7 @@ nv31_mpeg_init(struct drm_device *dev, int engine)
        nv_wr32(dev, 0x00b0e0, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
        nv_wr32(dev, 0x00b0e8, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
 
-       for (i = 0; i < dev_priv->engine.fb.num_tiles; i++)
+       for (i = 0; i < nvfb_tile_nr(dev); i++)
                pmpeg->base.set_tile_region(dev, i);
 
        /* PMPEG init */
@@ -235,9 +234,7 @@ nv31_mpeg_isr_chid(struct drm_device *dev, u32 inst)
 static void
 nv31_vpe_set_tile_region(struct drm_device *dev, int i)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
+       struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
        nv_wr32(dev, 0x00b008 + (i * 0x10), tile->pitch);
        nv_wr32(dev, 0x00b004 + (i * 0x10), tile->limit);
        nv_wr32(dev, 0x00b000 + (i * 0x10), tile->addr);
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
new file mode 100644 (file)
index 0000000..91dbdc1
--- /dev/null
@@ -0,0 +1,137 @@
+#ifndef __NOUVEAU_FB_H__
+#define __NOUVEAU_FB_H__
+
+#ifndef XXX_THIS_IS_A_HACK
+#include <core/subdev.h>
+#include <core/device.h>
+#endif
+#include <core/mm.h>
+#include <subdev/vm.h>
+
+/* memory type/access flags, do not match hardware values */
+#define NV_MEM_ACCESS_RO  1
+#define NV_MEM_ACCESS_WO  2
+#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO)
+#define NV_MEM_ACCESS_SYS 4
+#define NV_MEM_ACCESS_VM  8
+#define NV_MEM_ACCESS_NOSNOOP 16
+
+#define NV_MEM_TARGET_VRAM        0
+#define NV_MEM_TARGET_PCI         1
+#define NV_MEM_TARGET_PCI_NOSNOOP 2
+#define NV_MEM_TARGET_VM          3
+#define NV_MEM_TARGET_GART        4
+
+#define NV_MEM_TYPE_VM 0x7f
+#define NV_MEM_COMP_VM 0x03
+
+struct nouveau_mem {
+       struct drm_device *dev;
+
+       struct nouveau_vma bar_vma;
+       struct nouveau_vma vma[2];
+       u8  page_shift;
+
+       struct nouveau_mm_node *tag;
+       struct list_head regions;
+       dma_addr_t *pages;
+       u32 memtype;
+       u64 offset;
+       u64 size;
+       struct sg_table *sg;
+};
+
+struct nouveau_fb_tile {
+       struct nouveau_mm_node *tag;
+       u32 addr;
+       u32 limit;
+       u32 pitch;
+       u32 zcomp;
+};
+
+#ifndef XXX_THIS_IS_A_HACK
+struct nouveau_fb {
+       struct nouveau_subdev base;
+
+       bool (*memtype_valid)(struct nouveau_fb *, u32 memtype);
+
+       struct {
+               enum {
+                       NV_MEM_TYPE_UNKNOWN = 0,
+                       NV_MEM_TYPE_STOLEN,
+                       NV_MEM_TYPE_SGRAM,
+                       NV_MEM_TYPE_SDRAM,
+                       NV_MEM_TYPE_DDR1,
+                       NV_MEM_TYPE_DDR2,
+                       NV_MEM_TYPE_DDR3,
+                       NV_MEM_TYPE_GDDR2,
+                       NV_MEM_TYPE_GDDR3,
+                       NV_MEM_TYPE_GDDR4,
+                       NV_MEM_TYPE_GDDR5
+               } type;
+               u64 stolen;
+               u64 size;
+               int ranks;
+
+               int  (*get)(struct nouveau_fb *, u64 size, u32 align,
+                           u32 size_nc, u32 type, struct nouveau_mem **);
+               void (*put)(struct nouveau_fb *, struct nouveau_mem **);
+       } ram;
+
+       struct nouveau_mm vram;
+       struct nouveau_mm tags;
+
+       struct {
+               struct nouveau_fb_tile region[16];
+               int regions;
+               void (*init)(struct nouveau_fb *, int i, u32 addr, u32 size,
+                            u32 pitch, u32 flags, struct nouveau_fb_tile *);
+               void (*fini)(struct nouveau_fb *, int i,
+                            struct nouveau_fb_tile *);
+               void (*prog)(struct nouveau_fb *, int i,
+                            struct nouveau_fb_tile *);
+       } tile;
+};
+
+static inline struct nouveau_fb *
+nouveau_fb(void *obj)
+{
+       return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB];
+}
+
+#define nouveau_fb_create(p,e,c,d)                                             \
+       nouveau_subdev_create((p), (e), (c), 0, "PFB", "fb", (d))
+int  nouveau_fb_created(struct nouveau_fb *);
+void nouveau_fb_destroy(struct nouveau_fb *);
+int  nouveau_fb_init(struct nouveau_fb *);
+#define nouveau_fb_fini(p,s)                                                   \
+       nouveau_subdev_fini(&(p)->base, (s))
+
+void _nouveau_fb_dtor(struct nouveau_object *);
+int  _nouveau_fb_init(struct nouveau_object *);
+#define _nouveau_fb_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nv04_fb_oclass;
+extern struct nouveau_oclass nv10_fb_oclass;
+extern struct nouveau_oclass nv20_fb_oclass;
+extern struct nouveau_oclass nv30_fb_oclass;
+extern struct nouveau_oclass nv40_fb_oclass;
+extern struct nouveau_oclass nv50_fb_oclass;
+extern struct nouveau_oclass nvc0_fb_oclass;
+
+struct nouveau_bios;
+int  nouveau_fb_bios_memtype(struct nouveau_bios *);
+
+bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype);
+
+void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *);
+
+void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size,
+                      u32 pitch, u32 flags, struct nouveau_fb_tile *);
+void nv30_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *);
+
+void nv50_fb_vram_del(struct nouveau_fb *, struct nouveau_mem **);
+void nv50_fb_trap(struct nouveau_fb *, int display);
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
new file mode 100644 (file)
index 0000000..f351f63
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __NOUVEAU_LTCG_H__
+#define __NOUVEAU_LTCG_H__
+
+#include <core/subdev.h>
+#include <core/device.h>
+
+struct nouveau_ltcg {
+       struct nouveau_subdev base;
+};
+
+static inline struct nouveau_ltcg *
+nouveau_ltcg(void *obj)
+{
+       return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_LTCG];
+}
+
+#define nouveau_ltcg_create(p,e,o,d)                                           \
+       nouveau_subdev_create_((p), (e), (o), 0, "PLTCG", "level2",            \
+                              sizeof(**d), (void **)d)
+#define nouveau_ltcg_destroy(p)                                                \
+       nouveau_subdev_destroy(&(p)->base)
+#define nouveau_ltcg_init(p)                                                   \
+       nouveau_subdev_init(&(p)->base)
+#define nouveau_ltcg_fini(p,s)                                                 \
+       nouveau_subdev_fini(&(p)->base, (s))
+
+#define _nouveau_ltcg_dtor _nouveau_subdev_dtor
+#define _nouveau_ltcg_init _nouveau_subdev_init
+#define _nouveau_ltcg_fini _nouveau_subdev_fini
+
+extern struct nouveau_oclass nvc0_ltcg_oclass;
+
+#endif
index 7c1fc21..6d3764b 100644 (file)
 #ifndef __NOUVEAU_VM_H__
 #define __NOUVEAU_VM_H__
 
-#include "drmP.h"
-
-#include "nouveau_drv.h"
 #include <core/mm.h>
 
+struct nouveau_mem;
+
 struct nouveau_vm_pgt {
        struct nouveau_gpuobj *obj[2];
        u32 refcount[2];
index aa43bd5..66b7156 100644 (file)
@@ -29,6 +29,7 @@
 #include <subdev/devinit.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <subdev/fb.h>
 
 int
 nv04_identify(struct nouveau_device *device)
@@ -41,6 +42,7 @@ nv04_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv04_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv04_fb_oclass;
                break;
        case 0x05:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -49,6 +51,7 @@ nv04_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv05_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv04_fb_oclass;
                break;
        default:
                nv_fatal(device, "unknown RIVA chipset\n");
index 1926c33..cf81479 100644 (file)
@@ -30,6 +30,7 @@
 #include <subdev/devinit.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <subdev/fb.h>
 
 int
 nv10_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv10_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv10_fb_oclass;
                break;
        case 0x15:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv10_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv10_fb_oclass;
                break;
        case 0x16:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv10_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv10_fb_oclass;
                break;
        case 0x1a:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv10_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv10_fb_oclass;
                break;
        case 0x11:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -79,6 +84,7 @@ nv10_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv10_fb_oclass;
                break;
        case 0x17:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -88,6 +94,7 @@ nv10_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv10_fb_oclass;
                break;
        case 0x1f:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -97,6 +104,7 @@ nv10_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv10_fb_oclass;
                break;
        case 0x18:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -106,6 +114,7 @@ nv10_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv10_fb_oclass;
                break;
        default:
                nv_fatal(device, "unknown Celsius chipset\n");
index 88729c3..e97280c 100644 (file)
@@ -30,6 +30,7 @@
 #include <subdev/devinit.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <subdev/fb.h>
 
 int
 nv20_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv20_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv20_fb_oclass;
                break;
        case 0x25:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv20_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv20_fb_oclass;
                break;
        case 0x28:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv20_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv20_fb_oclass;
                break;
        case 0x2a:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv20_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv20_fb_oclass;
                break;
        default:
                nv_fatal(device, "unknown Kelvin chipset\n");
index 4feea88..ddd3ab6 100644 (file)
@@ -30,6 +30,7 @@
 #include <subdev/devinit.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <subdev/fb.h>
 
 int
 nv30_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv30_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv30_fb_oclass;
                break;
        case 0x35:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv30_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv30_fb_oclass;
                break;
        case 0x31:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv30_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv30_fb_oclass;
                break;
        case 0x36:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv30_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv30_fb_oclass;
                break;
        case 0x34:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -79,6 +84,7 @@ nv30_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv30_fb_oclass;
                break;
        default:
                nv_fatal(device, "unknown Rankine chipset\n");
index 8f68361..c7ea921 100644 (file)
@@ -30,6 +30,7 @@
 #include <subdev/devinit.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <subdev/fb.h>
 
 int
 nv40_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x41:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x42:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x43:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x45:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -79,6 +84,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x47:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -88,6 +94,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x49:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -97,6 +104,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x4b:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -106,6 +114,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv04_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x44:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -115,6 +124,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv44_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x46:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -124,6 +134,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv44_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x4a:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -133,6 +144,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv44_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x4c:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -142,6 +154,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv44_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x4e:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -151,6 +164,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv44_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x63:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -160,6 +174,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv44_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x67:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -169,6 +184,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv44_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        case 0x68:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -178,6 +194,7 @@ nv40_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv44_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv40_fb_oclass;
                break;
        default:
                nv_fatal(device, "unknown Curie chipset\n");
index e844525..e60cdf2 100644 (file)
@@ -30,6 +30,7 @@
 #include <subdev/devinit.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <subdev/fb.h>
 
 int
 nv50_identify(struct nouveau_device *device)
@@ -43,6 +44,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv50_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0x84:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -52,6 +54,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv50_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0x86:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -61,6 +64,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv50_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0x92:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -70,6 +74,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv50_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0x94:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -79,6 +84,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv50_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0x96:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -88,6 +94,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv50_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0x98:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -97,6 +104,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0xa0:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -106,6 +114,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0xaa:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -115,6 +124,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0xac:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -124,6 +134,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0xa3:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -133,6 +144,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0xa5:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -142,6 +154,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0xa8:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -151,6 +164,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        case 0xaf:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -160,6 +174,7 @@ nv50_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nv98_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nv50_fb_oclass;
                break;
        default:
                nv_fatal(device, "unknown Tesla chipset\n");
index 56d1950..8de6730 100644 (file)
@@ -30,6 +30,8 @@
 #include <subdev/devinit.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/ltcg.h>
 
 int
 nvc0_identify(struct nouveau_device *device)
@@ -43,6 +45,8 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        case 0xc4:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -52,6 +56,8 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        case 0xc3:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -61,6 +67,8 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        case 0xce:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -70,6 +78,8 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        case 0xcf:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -79,6 +89,8 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        case 0xc1:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -88,6 +100,8 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        case 0xc8:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -97,6 +111,8 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        case 0xd9:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -106,6 +122,8 @@ nvc0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        default:
                nv_fatal(device, "unknown Fermi chipset\n");
index ab5e052..919a102 100644 (file)
@@ -30,6 +30,8 @@
 #include <subdev/devinit.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/ltcg.h>
 
 int
 nve0_identify(struct nouveau_device *device)
@@ -43,6 +45,8 @@ nve0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        case 0xe7:
                device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
@@ -52,6 +56,8 @@ nve0_identify(struct nouveau_device *device)
                device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] = &nvc0_mc_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
+               device->oclass[NVDEV_SUBDEV_FB     ] = &nvc0_fb_oclass;
+               device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
                break;
        default:
                nv_fatal(device, "unknown Kepler chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
new file mode 100644 (file)
index 0000000..f0086de
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2012 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
+ */
+
+#include "subdev/fb.h"
+#include "subdev/bios.h"
+#include "subdev/bios/bit.h"
+
+int
+nouveau_fb_bios_memtype(struct nouveau_bios *bios)
+{
+       struct bit_entry M;
+       u8 ramcfg;
+
+       ramcfg = (nv_rd32(bios, 0x101000) & 0x0000003c) >> 2;
+       if (!bit_entry(bios, 'M', &M) && M.version == 2 && M.length >= 5) {
+               u16 table   = nv_ro16(bios, M.offset + 3);
+               u8  version = nv_ro08(bios, table + 0);
+               u8  header  = nv_ro08(bios, table + 1);
+               u8  record  = nv_ro08(bios, table + 2);
+               u8  entries = nv_ro08(bios, table + 3);
+               if (table && version == 0x10 && ramcfg < entries) {
+                       u16 entry = table + header + (ramcfg * record);
+                       switch (nv_ro08(bios, entry) & 0x0f) {
+                       case 0: return NV_MEM_TYPE_DDR2;
+                       case 1: return NV_MEM_TYPE_DDR3;
+                       case 2: return NV_MEM_TYPE_GDDR3;
+                       case 3: return NV_MEM_TYPE_GDDR5;
+                       default:
+                               break;
+                       }
+
+               }
+       }
+
+       return NV_MEM_TYPE_UNKNOWN;
+}
+
+int
+nouveau_fb_init(struct nouveau_fb *pfb)
+{
+       int ret, i;
+
+       ret = nouveau_subdev_init(&pfb->base);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < pfb->tile.regions; i++)
+               pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
+
+       return 0;
+}
+
+int
+_nouveau_fb_init(struct nouveau_object *object)
+{
+       struct nouveau_fb *pfb = (void *)object;
+       return nouveau_fb_init(pfb);
+}
+
+void
+nouveau_fb_destroy(struct nouveau_fb *pfb)
+{
+       int i;
+
+       for (i = 0; i < pfb->tile.regions; i++)
+               pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
+
+       if (pfb->tags.block_size)
+               nouveau_mm_fini(&pfb->tags);
+
+       if (pfb->vram.block_size)
+               nouveau_mm_fini(&pfb->vram);
+
+       nouveau_subdev_destroy(&pfb->base);
+}
+
+void
+_nouveau_fb_dtor(struct nouveau_object *object)
+{
+       struct nouveau_fb *pfb = (void *)object;
+       nouveau_fb_destroy(pfb);
+}
+
+int
+nouveau_fb_created(struct nouveau_fb *pfb)
+{
+       static const char *name[] = {
+               [NV_MEM_TYPE_UNKNOWN] = "unknown",
+               [NV_MEM_TYPE_STOLEN ] = "stolen system memory",
+               [NV_MEM_TYPE_SGRAM  ] = "SGRAM",
+               [NV_MEM_TYPE_SDRAM  ] = "SDRAM",
+               [NV_MEM_TYPE_DDR1   ] = "DDR1",
+               [NV_MEM_TYPE_DDR2   ] = "DDR2",
+               [NV_MEM_TYPE_DDR3   ] = "DDR3",
+               [NV_MEM_TYPE_GDDR2  ] = "GDDR2",
+               [NV_MEM_TYPE_GDDR3  ] = "GDDR3",
+               [NV_MEM_TYPE_GDDR4  ] = "GDDR4",
+               [NV_MEM_TYPE_GDDR5  ] = "GDDR5",
+       };
+
+       if (pfb->ram.size == 0) {
+               nv_fatal(pfb, "no vram detected!!\n");
+               return -ERANGE;
+       }
+
+       nv_info(pfb, "RAM type: %s\n", name[pfb->ram.type]);
+       nv_info(pfb, "RAM size: %d MiB\n", (int)(pfb->ram.size >> 20));
+       return 0;
+}
index eef4844..eb06836 100644 (file)
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include <nouveau_drm.h>
+/*
+ * Copyright 2012 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
+ */
 
-int
-nv04_fb_vram_init(struct drm_device *dev)
+#include <subdev/fb.h>
+
+#define NV04_PFB_BOOT_0                                                0x00100000
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT                       0x00000003
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB                  0x00000000
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB                   0x00000001
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB                   0x00000002
+#      define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB                  0x00000003
+#      define NV04_PFB_BOOT_0_RAM_WIDTH_128                    0x00000004
+#      define NV04_PFB_BOOT_0_RAM_TYPE                         0x00000028
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT             0x00000000
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT            0x00000008
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK      0x00000010
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT            0x00000018
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT            0x00000020
+#      define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16         0x00000028
+#      define NV04_PFB_BOOT_0_UMA_ENABLE                       0x00000100
+#      define NV04_PFB_BOOT_0_UMA_SIZE                         0x0000f000
+#define NV04_PFB_CFG0                                          0x00100200
+
+struct nv04_fb_priv {
+       struct nouveau_fb base;
+};
+
+bool
+nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
+{
+       if (!(tile_flags & 0xff00))
+               return true;
+
+       return false;
+}
+
+static int
+nv04_fb_init(struct nouveau_object *object)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       u32 boot0 = nv_rd32(dev, NV04_PFB_BOOT_0);
+       struct nv04_fb_priv *priv = (void *)object;
+       int ret;
+
+       ret = nouveau_fb_init(&priv->base);
+       if (ret)
+               return ret;
+
+       /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows
+        * nvidia reading PFB_CFG_0, then writing back its original value.
+        * (which was 0x701114 in this case)
+        */
+       nv_wr32(priv, NV04_PFB_CFG0, 0x1114);
+       return 0;
+}
 
+static int
+nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+            struct nouveau_oclass *oclass, void *data, u32 size,
+            struct nouveau_object **pobject)
+{
+       struct nv04_fb_priv *priv;
+       u32 boot0;
+       int ret;
+
+       ret = nouveau_fb_create(parent, engine, oclass, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
+
+       boot0 = nv_rd32(priv, NV04_PFB_BOOT_0);
        if (boot0 & 0x00000100) {
-               dev_priv->vram_size  = ((boot0 >> 12) & 0xf) * 2 + 2;
-               dev_priv->vram_size *= 1024 * 1024;
+               priv->base.ram.size  = ((boot0 >> 12) & 0xf) * 2 + 2;
+               priv->base.ram.size *= 1024 * 1024;
        } else {
                switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
                case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
-                       dev_priv->vram_size = 32 * 1024 * 1024;
+                       priv->base.ram.size = 32 * 1024 * 1024;
                        break;
                case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
-                       dev_priv->vram_size = 16 * 1024 * 1024;
+                       priv->base.ram.size = 16 * 1024 * 1024;
                        break;
                case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
-                       dev_priv->vram_size = 8 * 1024 * 1024;
+                       priv->base.ram.size = 8 * 1024 * 1024;
                        break;
                case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
-                       dev_priv->vram_size = 4 * 1024 * 1024;
+                       priv->base.ram.size = 4 * 1024 * 1024;
                        break;
                }
        }
 
        if ((boot0 & 0x00000038) <= 0x10)
-               dev_priv->vram_type = NV_MEM_TYPE_SGRAM;
+               priv->base.ram.type = NV_MEM_TYPE_SGRAM;
        else
-               dev_priv->vram_type = NV_MEM_TYPE_SDRAM;
+               priv->base.ram.type = NV_MEM_TYPE_SDRAM;
 
-       return 0;
-}
-
-int
-nv04_fb_init(struct drm_device *dev)
-{
-       /* This is what the DDX did for NV_ARCH_04, but a mmio-trace shows
-        * nvidia reading PFB_CFG_0, then writing back its original value.
-        * (which was 0x701114 in this case)
-        */
 
-       nv_wr32(dev, NV04_PFB_CFG0, 0x1114);
-       return 0;
+       priv->base.memtype_valid = nv04_fb_memtype_valid;
+       return nouveau_fb_created(&priv->base);
 }
 
-void
-nv04_fb_takedown(struct drm_device *dev)
-{
-}
+struct nouveau_oclass
+nv04_fb_oclass = {
+       .handle = NV_SUBDEV(FB, 0x04),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nv04_fb_ctor,
+               .dtor = _nouveau_fb_dtor,
+               .init = nv04_fb_init,
+               .fini = _nouveau_fb_fini,
+       },
+};
index 09af63b..f037a42 100644 (file)
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include <nouveau_drm.h>
-
-void
-nv10_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
-                        uint32_t size, uint32_t pitch, uint32_t flags)
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * 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"), 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 (including the
+ * next paragraph) 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 OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/fb.h>
+
+struct nv10_fb_priv {
+       struct nouveau_fb base;
+};
+
+static void
+nv10_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+                 u32 flags, struct nouveau_fb_tile *tile)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
        tile->addr  = 0x80000000 | addr;
        tile->limit = max(1u, addr + size) - 1;
        tile->pitch = pitch;
 }
 
-void
-nv10_fb_free_tile_region(struct drm_device *dev, int i)
+static void
+nv10_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
-       tile->addr = tile->limit = tile->pitch = tile->zcomp = 0;
+       tile->addr  = 0;
+       tile->limit = 0;
+       tile->pitch = 0;
+       tile->zcomp = 0;
 }
 
 void
-nv10_fb_set_tile_region(struct drm_device *dev, int i)
+nv10_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
-       nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit);
-       nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
-       nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
+       nv_wr32(pfb, 0x100244 + (i * 0x10), tile->limit);
+       nv_wr32(pfb, 0x100248 + (i * 0x10), tile->pitch);
+       nv_wr32(pfb, 0x100240 + (i * 0x10), tile->addr);
 }
 
-int
-nv1a_fb_vram_init(struct drm_device *dev)
+static int
+nv10_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+            struct nouveau_oclass *oclass, void *data, u32 size,
+            struct nouveau_object **pobject)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct pci_dev *bridge;
-       uint32_t mem, mib;
-
-       bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
-       if (!bridge) {
-               NV_ERROR(dev, "no bridge device\n");
-               return 0;
-       }
-
-       if (dev_priv->chipset == 0x1a) {
-               pci_read_config_dword(bridge, 0x7c, &mem);
-               mib = ((mem >> 6) & 31) + 1;
+       struct nouveau_device *device = nv_device(parent);
+       struct nv10_fb_priv *priv;
+       int ret;
+
+       ret = nouveau_fb_create(parent, engine, oclass, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
+
+       if (device->chipset == 0x1a ||  device->chipset == 0x1f) {
+               struct pci_dev *bridge;
+               u32 mem, mib;
+
+               bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
+               if (!bridge) {
+                       nv_fatal(device, "no bridge device\n");
+                       return 0;
+               }
+
+               if (device->chipset == 0x1a) {
+                       pci_read_config_dword(bridge, 0x7c, &mem);
+                       mib = ((mem >> 6) & 31) + 1;
+               } else {
+                       pci_read_config_dword(bridge, 0x84, &mem);
+                       mib = ((mem >> 4) & 127) + 1;
+               }
+
+               priv->base.ram.type = NV_MEM_TYPE_STOLEN;
+               priv->base.ram.size = mib * 1024 * 1024;
        } else {
-               pci_read_config_dword(bridge, 0x84, &mem);
-               mib = ((mem >> 4) & 127) + 1;
-       }
+               u32 cfg0 = nv_rd32(priv, 0x100200);
+               if (cfg0 & 0x00000001)
+                       priv->base.ram.type = NV_MEM_TYPE_DDR1;
+               else
+                       priv->base.ram.type = NV_MEM_TYPE_SDRAM;
 
-       dev_priv->vram_size = mib * 1024 * 1024;
-       return 0;
-}
-
-int
-nv10_fb_vram_init(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       u32 fifo_data = nv_rd32(dev, NV04_PFB_FIFO_DATA);
-       u32 cfg0 = nv_rd32(dev, 0x100200);
-
-       dev_priv->vram_size = fifo_data & NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
-
-       if (cfg0 & 0x00000001)
-               dev_priv->vram_type = NV_MEM_TYPE_DDR1;
-       else
-               dev_priv->vram_type = NV_MEM_TYPE_SDRAM;
-
-       return 0;
-}
-
-int
-nv10_fb_init(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       int i;
-
-       /* Turn all the tiling regions off. */
-       pfb->num_tiles = NV10_PFB_TILE__SIZE;
-       for (i = 0; i < pfb->num_tiles; i++)
-               pfb->set_tile_region(dev, i);
+               priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
+       }
 
-       return 0;
+       priv->base.memtype_valid = nv04_fb_memtype_valid;
+       priv->base.tile.regions = 8;
+       priv->base.tile.init = nv10_fb_tile_init;
+       priv->base.tile.fini = nv10_fb_tile_fini;
+       priv->base.tile.prog = nv10_fb_tile_prog;
+       return nouveau_fb_created(&priv->base);
 }
 
-void
-nv10_fb_takedown(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       int i;
-
-       for (i = 0; i < pfb->num_tiles; i++)
-               pfb->free_tile_region(dev, i);
-}
+struct nouveau_oclass
+nv10_fb_oclass = {
+       .handle = NV_SUBDEV(FB, 0x10),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nv10_fb_ctor,
+               .dtor = _nouveau_fb_dtor,
+               .init = _nouveau_fb_init,
+               .fini = _nouveau_fb_fini,
+       },
+};
index a7f056c..4b3578f 100644 (file)
@@ -1,49 +1,41 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include <nouveau_drm.h>
-
-static struct drm_mm_node *
-nv20_fb_alloc_tag(struct drm_device *dev, uint32_t size)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       struct drm_mm_node *mem;
-       int ret;
-
-       ret = drm_mm_pre_get(&pfb->tag_heap);
-       if (ret)
-               return NULL;
-
-       spin_lock(&dev_priv->tile.lock);
-       mem = drm_mm_search_free(&pfb->tag_heap, size, 0, 0);
-       if (mem)
-               mem = drm_mm_get_block_atomic(mem, size, 0);
-       spin_unlock(&dev_priv->tile.lock);
-
-       return mem;
-}
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * 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"), 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 (including the
+ * next paragraph) 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 OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/fb.h>
+
+struct nv20_fb_priv {
+       struct nouveau_fb base;
+};
 
 static void
-nv20_fb_free_tag(struct drm_device *dev, struct drm_mm_node **pmem)
+nv20_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+                 u32 flags, struct nouveau_fb_tile *tile)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct drm_mm_node *mem = *pmem;
-       if (mem) {
-               spin_lock(&dev_priv->tile.lock);
-               drm_mm_put_block(mem);
-               spin_unlock(&dev_priv->tile.lock);
-               *pmem = NULL;
-       }
-}
-
-void
-nv20_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
-                        uint32_t size, uint32_t pitch, uint32_t flags)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-       int bpp = (flags & NOUVEAU_GEM_TILE_32BPP ? 32 : 16);
+       struct nouveau_device *device = nv_device(pfb);
+       int bpp = (flags & 2) ? 32 : 16;
 
        tile->addr  = 0x00000001 | addr;
        tile->limit = max(1u, addr + size) - 1;
@@ -53,20 +45,20 @@ nv20_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
         * compression meta-data (most likely just a bitmap determining
         * if a given tile is compressed or not).
         */
-       if (flags & NOUVEAU_GEM_TILE_ZETA) {
-               tile->tag_mem = nv20_fb_alloc_tag(dev, size / 256);
-               if (tile->tag_mem) {
+       size /= 256;
+       if (flags & 4) {
+               if (!nouveau_mm_head(&pfb->tags, 1, size, size, 1, &tile->tag)) {
                        /* Enable Z compression */
-                       tile->zcomp = tile->tag_mem->start;
-                       if (dev_priv->chipset >= 0x25) {
+                       tile->zcomp = tile->tag->offset;
+                       if (device->chipset >= 0x25) {
                                if (bpp == 16)
-                                       tile->zcomp |= NV25_PFB_ZCOMP_MODE_16;
+                                       tile->zcomp |= 0x00100000;
                                else
-                                       tile->zcomp |= NV25_PFB_ZCOMP_MODE_32;
+                                       tile->zcomp |= 0x00200000;
                        } else {
-                               tile->zcomp |= NV20_PFB_ZCOMP_EN;
+                               tile->zcomp |= 0x80000000;
                                if (bpp != 16)
-                                       tile->zcomp |= NV20_PFB_ZCOMP_MODE_32;
+                                       tile->zcomp |= 0x04000000;
                        }
                }
 
@@ -74,75 +66,71 @@ nv20_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
        }
 }
 
-void
-nv20_fb_free_tile_region(struct drm_device *dev, int i)
+static void
+nv20_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
-       tile->addr = tile->limit = tile->pitch = tile->zcomp = 0;
-       nv20_fb_free_tag(dev, &tile->tag_mem);
+       tile->addr  = 0;
+       tile->limit = 0;
+       tile->pitch = 0;
+       tile->zcomp = 0;
+       nouveau_mm_free(&pfb->tags, &tile->tag);
 }
 
-void
-nv20_fb_set_tile_region(struct drm_device *dev, int i)
+static void
+nv20_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
-       nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit);
-       nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
-       nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
-       nv_wr32(dev, NV20_PFB_ZCOMP(i), tile->zcomp);
+       nv_wr32(pfb, 0x100244 + (i * 0x10), tile->limit);
+       nv_wr32(pfb, 0x100248 + (i * 0x10), tile->pitch);
+       nv_wr32(pfb, 0x100240 + (i * 0x10), tile->addr);
+       nv_wr32(pfb, 0x100300 + (i * 0x04), tile->zcomp);
 }
 
-int
-nv20_fb_vram_init(struct drm_device *dev)
+static int
+nv20_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+            struct nouveau_oclass *oclass, void *data, u32 size,
+            struct nouveau_object **pobject)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       u32 mem_size = nv_rd32(dev, 0x10020c);
-       u32 pbus1218 = nv_rd32(dev, 0x001218);
+       struct nouveau_device *device = nv_device(parent);
+       struct nv20_fb_priv *priv;
+       u32 pbus1218;
+       int ret;
+
+       ret = nouveau_fb_create(parent, engine, oclass, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
 
-       dev_priv->vram_size = mem_size & 0xff000000;
+       pbus1218 = nv_rd32(priv, 0x001218);
        switch (pbus1218 & 0x00000300) {
-       case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break;
-       case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
-       case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
-       case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_GDDR2; break;
+       case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_SDRAM; break;
+       case 0x00000100: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+       case 0x00000200: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
+       case 0x00000300: priv->base.ram.type = NV_MEM_TYPE_GDDR2; break;
        }
+       priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
 
-       return 0;
-}
-
-int
-nv20_fb_init(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       int i;
-
-       if (dev_priv->chipset >= 0x25)
-               drm_mm_init(&pfb->tag_heap, 0, 64 * 1024);
+       if (device->chipset >= 0x25)
+               ret = nouveau_mm_init(&priv->base.tags, 0, 64 * 1024, 1);
        else
-               drm_mm_init(&pfb->tag_heap, 0, 32 * 1024);
-
-       /* Turn all the tiling regions off. */
-       pfb->num_tiles = NV10_PFB_TILE__SIZE;
-       for (i = 0; i < pfb->num_tiles; i++)
-               pfb->set_tile_region(dev, i);
-
-       return 0;
+               ret = nouveau_mm_init(&priv->base.tags, 0, 32 * 1024, 1);
+       if (ret)
+               return ret;
+
+       priv->base.memtype_valid = nv04_fb_memtype_valid;
+       priv->base.tile.regions = 8;
+       priv->base.tile.init = nv20_fb_tile_init;
+       priv->base.tile.fini = nv20_fb_tile_fini;
+       priv->base.tile.prog = nv20_fb_tile_prog;
+       return nouveau_fb_created(&priv->base);
 }
 
-void
-nv20_fb_takedown(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       int i;
-
-       for (i = 0; i < pfb->num_tiles; i++)
-               pfb->free_tile_region(dev, i);
-
-       drm_mm_takedown(&pfb->tag_heap);
-}
+struct nouveau_oclass
+nv20_fb_oclass = {
+       .handle = NV_SUBDEV(FB, 0x20),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nv20_fb_ctor,
+               .dtor = _nouveau_fb_dtor,
+               .init = _nouveau_fb_init,
+               .fini = _nouveau_fb_fini,
+       },
+};
index 30639a0..cba67bc 100644 (file)
  *
  */
 
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include <nouveau_drm.h>
+#include <subdev/fb.h>
+
+struct nv30_fb_priv {
+       struct nouveau_fb base;
+};
 
 void
-nv30_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr,
-                        uint32_t size, uint32_t pitch, uint32_t flags)
+nv30_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch,
+                 u32 flags, struct nouveau_fb_tile *tile)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
        tile->addr = addr | 1;
        tile->limit = max(1u, addr + size) - 1;
        tile->pitch = pitch;
 }
 
 void
-nv30_fb_free_tile_region(struct drm_device *dev, int i)
+nv30_fb_tile_fini(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
-
-       tile->addr = tile->limit = tile->pitch = 0;
+       tile->addr  = 0;
+       tile->limit = 0;
+       tile->pitch = 0;
 }
 
 static int
-calc_bias(struct drm_device *dev, int k, int i, int j)
+calc_bias(struct nv30_fb_priv *priv, int k, int i, int j)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       int b = (dev_priv->chipset > 0x30 ?
-                nv_rd32(dev, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) :
+       struct nouveau_device *device = nv_device(priv);
+       int b = (device->chipset > 0x30 ?
+                nv_rd32(priv, 0x122c + 0x10 * k + 0x4 * j) >> (4 * (i ^ 1)) :
                 0) & 0xf;
 
        return 2 * (b & 0x8 ? b - 0x10 : b);
 }
 
 static int
-calc_ref(struct drm_device *dev, int l, int k, int i)
+calc_ref(struct nv30_fb_priv *priv, int l, int k, int i)
 {
        int j, x = 0;
 
        for (j = 0; j < 4; j++) {
-               int m = (l >> (8 * i) & 0xff) + calc_bias(dev, k, i, j);
+               int m = (l >> (8 * i) & 0xff) + calc_bias(priv, k, i, j);
 
                x |= (0x80 | clamp(m, 0, 0x1f)) << (8 * j);
        }
@@ -75,42 +72,77 @@ calc_ref(struct drm_device *dev, int l, int k, int i)
        return x;
 }
 
-int
-nv30_fb_init(struct drm_device *dev)
+static int
+nv30_fb_init(struct nouveau_object *object)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       int i, j;
-
-       pfb->num_tiles = NV10_PFB_TILE__SIZE;
+       struct nouveau_device *device = nv_device(object);
+       struct nv30_fb_priv *priv = (void *)object;
+       int ret, i, j;
 
-       /* Turn all the tiling regions off. */
-       for (i = 0; i < pfb->num_tiles; i++)
-               pfb->set_tile_region(dev, i);
+       ret = nouveau_fb_init(&priv->base);
+       if (ret)
+               return ret;
 
        /* Init the memory timing regs at 0x10037c/0x1003ac */
-       if (dev_priv->chipset == 0x30 ||
-           dev_priv->chipset == 0x31 ||
-           dev_priv->chipset == 0x35) {
+       if (device->chipset == 0x30 ||
+           device->chipset == 0x31 ||
+           device->chipset == 0x35) {
                /* Related to ROP count */
-               int n = (dev_priv->chipset == 0x31 ? 2 : 4);
-               int l = nv_rd32(dev, 0x1003d0);
+               int n = (device->chipset == 0x31 ? 2 : 4);
+               int l = nv_rd32(priv, 0x1003d0);
 
                for (i = 0; i < n; i++) {
                        for (j = 0; j < 3; j++)
-                               nv_wr32(dev, 0x10037c + 0xc * i + 0x4 * j,
-                                       calc_ref(dev, l, 0, j));
+                               nv_wr32(priv, 0x10037c + 0xc * i + 0x4 * j,
+                                       calc_ref(priv, l, 0, j));
 
                        for (j = 0; j < 2; j++)
-                               nv_wr32(dev, 0x1003ac + 0x8 * i + 0x4 * j,
-                                       calc_ref(dev, l, 1, j));
+                               nv_wr32(priv, 0x1003ac + 0x8 * i + 0x4 * j,
+                                       calc_ref(priv, l, 1, j));
                }
        }
 
        return 0;
 }
 
-void
-nv30_fb_takedown(struct drm_device *dev)
+static int
+nv30_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+            struct nouveau_oclass *oclass, void *data, u32 size,
+            struct nouveau_object **pobject)
 {
+       struct nv30_fb_priv *priv;
+       u32 pbus1218;
+       int ret;
+
+       ret = nouveau_fb_create(parent, engine, oclass, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
+
+       pbus1218 = nv_rd32(priv, 0x001218);
+       switch (pbus1218 & 0x00000300) {
+       case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_SDRAM; break;
+       case 0x00000100: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+       case 0x00000200: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
+       case 0x00000300: priv->base.ram.type = NV_MEM_TYPE_GDDR2; break;
+       }
+       priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
+
+       priv->base.memtype_valid = nv04_fb_memtype_valid;
+       priv->base.tile.regions = 8;
+       priv->base.tile.init = nv30_fb_tile_init;
+       priv->base.tile.fini = nv30_fb_tile_fini;
+       priv->base.tile.prog = nv10_fb_tile_prog;
+       return nouveau_fb_created(&priv->base);
 }
+
+struct nouveau_oclass
+nv30_fb_oclass = {
+       .handle = NV_SUBDEV(FB, 0x30),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nv30_fb_ctor,
+               .dtor = _nouveau_fb_dtor,
+               .init = nv30_fb_init,
+               .fini = _nouveau_fb_fini,
+       },
+};
index e08c2e1..84aa71c 100644 (file)
@@ -1,55 +1,83 @@
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include <nouveau_drm.h>
-
-void
-nv40_fb_set_tile_region(struct drm_device *dev, int i)
+/*
+ * Copyright (C) 2010 Francisco Jerez.
+ * 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"), 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 (including the
+ * next paragraph) 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 OWNER(S) AND/OR ITS SUPPLIERS 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 <subdev/fb.h>
+
+struct nv40_fb_priv {
+       struct nouveau_fb base;
+};
+
+static inline int
+nv44_graph_class(struct nouveau_device *device)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
+       if ((device->chipset & 0xf0) == 0x60)
+               return 1;
 
-       switch (dev_priv->chipset) {
-       case 0x40:
-               nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit);
-               nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch);
-               nv_wr32(dev, NV10_PFB_TILE(i), tile->addr);
-               break;
+       return !(0x0baf & (1 << (device->chipset & 0x0f)));
+}
 
-       default:
-               nv_wr32(dev, NV40_PFB_TLIMIT(i), tile->limit);
-               nv_wr32(dev, NV40_PFB_TSIZE(i), tile->pitch);
-               nv_wr32(dev, NV40_PFB_TILE(i), tile->addr);
-               break;
-       }
+static void
+nv40_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile)
+{
+       nv_wr32(pfb, 0x100604 + (i * 0x10), tile->limit);
+       nv_wr32(pfb, 0x100608 + (i * 0x10), tile->pitch);
+       nv_wr32(pfb, 0x100600 + (i * 0x10), tile->addr);
 }
 
 static void
-nv40_fb_init_gart(struct drm_device *dev)
+nv40_fb_init_gart(struct nv40_fb_priv *priv)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma;
+#if 0
+       struct nouveau_gpuobj *gart = ndev->gart_info.sg_ctxdma;
 
-       if (dev_priv->gart_info.type != NOUVEAU_GART_HW) {
-               nv_wr32(dev, 0x100800, 0x00000001);
+       if (ndev->gart_info.type != NOUVEAU_GART_HW) {
+#endif
+               nv_wr32(priv, 0x100800, 0x00000001);
+#if 0
                return;
        }
 
-       nv_wr32(dev, 0x100800, gart->pinst | 0x00000002);
-       nv_mask(dev, 0x10008c, 0x00000100, 0x00000100);
-       nv_wr32(dev, 0x100820, 0x00000000);
+       nv_wr32(ndev, 0x100800, gart->pinst | 0x00000002);
+       nv_mask(ndev, 0x10008c, 0x00000100, 0x00000100);
+       nv_wr32(ndev, 0x100820, 0x00000000);
+#endif
 }
 
 static void
-nv44_fb_init_gart(struct drm_device *dev)
+nv44_fb_init_gart(struct nv40_fb_priv *priv)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma;
+#if 0
+       struct nouveau_gpuobj *gart = ndev->gart_info.sg_ctxdma;
        u32 vinst;
 
-       if (dev_priv->gart_info.type != NOUVEAU_GART_HW) {
-               nv_wr32(dev, 0x100850, 0x80000000);
-               nv_wr32(dev, 0x100800, 0x00000001);
+       if (ndev->gart_info.type != NOUVEAU_GART_HW) {
+#endif
+               nv_wr32(priv, 0x100850, 0x80000000);
+               nv_wr32(priv, 0x100800, 0x00000001);
+#if 0
                return;
        }
 
@@ -57,24 +85,60 @@ nv44_fb_init_gart(struct drm_device *dev)
         * must be allocated on 512KiB alignment, and not exceed
         * a total size of 512KiB for this to work correctly
         */
-       vinst  = nv_rd32(dev, 0x10020c);
+       vinst  = nv_rd32(ndev, 0x10020c);
        vinst -= ((gart->pinst >> 19) + 1) << 19;
 
-       nv_wr32(dev, 0x100850, 0x80000000);
-       nv_wr32(dev, 0x100818, dev_priv->gart_info.dummy.addr);
+       nv_wr32(ndev, 0x100850, 0x80000000);
+       nv_wr32(ndev, 0x100818, ndev->gart_info.dummy.addr);
+
+       nv_wr32(ndev, 0x100804, ndev->gart_info.aper_size);
+       nv_wr32(ndev, 0x100850, 0x00008000);
+       nv_mask(ndev, 0x10008c, 0x00000200, 0x00000200);
+       nv_wr32(ndev, 0x100820, 0x00000000);
+       nv_wr32(ndev, 0x10082c, 0x00000001);
+       nv_wr32(ndev, 0x100800, vinst | 0x00000010);
+#endif
+}
+
+static int
+nv40_fb_init(struct nouveau_object *object)
+{
+       struct nv40_fb_priv *priv = (void *)object;
+       int ret;
+
+       ret = nouveau_fb_init(&priv->base);
+       if (ret)
+               return ret;
+
+       switch (nv_device(priv)->chipset) {
+       case 0x40:
+       case 0x45:
+               nv_mask(priv, 0x10033c, 0x00008000, 0x00000000);
+               break;
+       default:
+               if (nv44_graph_class(nv_device(priv)))
+                       nv44_fb_init_gart(priv);
+               else
+                       nv40_fb_init_gart(priv);
+               break;
+       }
 
-       nv_wr32(dev, 0x100804, dev_priv->gart_info.aper_size);
-       nv_wr32(dev, 0x100850, 0x00008000);
-       nv_mask(dev, 0x10008c, 0x00000200, 0x00000200);
-       nv_wr32(dev, 0x100820, 0x00000000);
-       nv_wr32(dev, 0x10082c, 0x00000001);
-       nv_wr32(dev, 0x100800, vinst | 0x00000010);
+       return 0;
 }
 
-int
-nv40_fb_vram_init(struct drm_device *dev)
+static int
+nv40_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+            struct nouveau_oclass *oclass, void *data, u32 size,
+            struct nouveau_object **pobject)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_device *device = nv_device(parent);
+       struct nv40_fb_priv *priv;
+       int ret;
+
+       ret = nouveau_fb_create(parent, engine, oclass, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
 
        /* 0x001218 is actually present on a few other NV4X I looked at,
         * and even contains sane values matching 0x100474.  From looking
@@ -82,82 +146,73 @@ nv40_fb_vram_init(struct drm_device *dev)
         * So, I chose to use the same regs I've seen NVIDIA reading around
         * the memory detection, hopefully that'll get us the right numbers
         */
-       if (dev_priv->chipset == 0x40) {
-               u32 pbus1218 = nv_rd32(dev, 0x001218);
+       if (device->chipset == 0x40) {
+               u32 pbus1218 = nv_rd32(priv, 0x001218);
                switch (pbus1218 & 0x00000300) {
-               case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break;
-               case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
-               case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
-               case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break;
+               case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_SDRAM; break;
+               case 0x00000100: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+               case 0x00000200: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
+               case 0x00000300: priv->base.ram.type = NV_MEM_TYPE_DDR2; break;
                }
        } else
-       if (dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) {
-               u32 pfb914 = nv_rd32(dev, 0x100914);
+       if (device->chipset == 0x49 || device->chipset == 0x4b) {
+               u32 pfb914 = nv_rd32(priv, 0x100914);
                switch (pfb914 & 0x00000003) {
-               case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
-               case 0x00000001: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break;
-               case 0x00000002: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
+               case 0x00000000: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+               case 0x00000001: priv->base.ram.type = NV_MEM_TYPE_DDR2; break;
+               case 0x00000002: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
                case 0x00000003: break;
                }
        } else
-       if (dev_priv->chipset != 0x4e) {
-               u32 pfb474 = nv_rd32(dev, 0x100474);
+       if (device->chipset != 0x4e) {
+               u32 pfb474 = nv_rd32(priv, 0x100474);
                if (pfb474 & 0x00000004)
-                       dev_priv->vram_type = NV_MEM_TYPE_GDDR3;
+                       priv->base.ram.type = NV_MEM_TYPE_GDDR3;
                if (pfb474 & 0x00000002)
-                       dev_priv->vram_type = NV_MEM_TYPE_DDR2;
+                       priv->base.ram.type = NV_MEM_TYPE_DDR2;
                if (pfb474 & 0x00000001)
-                       dev_priv->vram_type = NV_MEM_TYPE_DDR1;
+                       priv->base.ram.type = NV_MEM_TYPE_DDR1;
        } else {
-               dev_priv->vram_type = NV_MEM_TYPE_STOLEN;
+               priv->base.ram.type = NV_MEM_TYPE_STOLEN;
        }
 
-       dev_priv->vram_size = nv_rd32(dev, 0x10020c) & 0xff000000;
-       return 0;
-}
-
-int
-nv40_fb_init(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       uint32_t tmp;
-       int i;
-
-       if (dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) {
-               if (nv44_graph_class(dev))
-                       nv44_fb_init_gart(dev);
-               else
-                       nv40_fb_init_gart(dev);
-       }
+       priv->base.ram.size = nv_rd32(priv, 0x10020c) & 0xff000000;
 
-       switch (dev_priv->chipset) {
+       priv->base.memtype_valid = nv04_fb_memtype_valid;
+       switch (device->chipset) {
        case 0x40:
        case 0x45:
-               tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2);
-               nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15));
-               pfb->num_tiles = NV10_PFB_TILE__SIZE;
+               priv->base.tile.regions = 8;
                break;
-       case 0x46: /* G72 */
-       case 0x47: /* G70 */
-       case 0x49: /* G71 */
-       case 0x4b: /* G73 */
-       case 0x4c: /* C51 (G7X version) */
-               pfb->num_tiles = NV40_PFB_TILE__SIZE_1;
+       case 0x46:
+       case 0x47:
+       case 0x49:
+       case 0x4b:
+       case 0x4c:
+               priv->base.tile.regions = 15;
                break;
        default:
-               pfb->num_tiles = NV40_PFB_TILE__SIZE_0;
+               priv->base.tile.regions = 12;
                break;
        }
-
-       /* Turn all the tiling regions off. */
-       for (i = 0; i < pfb->num_tiles; i++)
-               pfb->set_tile_region(dev, i);
-
-       return 0;
+       priv->base.tile.init = nv30_fb_tile_init;
+       priv->base.tile.fini = nv30_fb_tile_fini;
+       if (device->chipset == 0x40)
+               priv->base.tile.prog = nv10_fb_tile_prog;
+       else
+               priv->base.tile.prog = nv40_fb_tile_prog;
+
+       return nouveau_fb_created(&priv->base);
 }
 
-void
-nv40_fb_takedown(struct drm_device *dev)
-{
-}
+
+struct nouveau_oclass
+nv40_fb_oclass = {
+       .handle = NV_SUBDEV(FB, 0x40),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nv40_fb_ctor,
+               .dtor = _nouveau_fb_dtor,
+               .init = nv40_fb_init,
+               .fini = _nouveau_fb_fini,
+       },
+};
index a145b1c..eaf18fb 100644 (file)
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include <nouveau_drm.h>
-#include <engine/fifo.h>
+/*
+ * Copyright 2012 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
+ */
+
+#include <core/object.h>
+#include <core/enum.h>
+
+#include <subdev/fb.h>
+#include <subdev/bios.h>
 
 struct nv50_fb_priv {
+       struct nouveau_fb base;
        struct page *r100c08_page;
        dma_addr_t r100c08;
 };
 
-static void
-nv50_fb_destroy(struct drm_device *dev)
+static int types[0x80] = {
+       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
+       1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0,
+       0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+       1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0
+};
+
+static bool
+nv50_fb_memtype_valid(struct nouveau_fb *pfb, u32 memtype)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       struct nv50_fb_priv *priv = pfb->priv;
+       return types[(memtype & 0xff00) >> 8] != 0;
+}
 
-       if (drm_mm_initialized(&pfb->tag_heap))
-               drm_mm_takedown(&pfb->tag_heap);
+static int
+nv50_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
+                u32 memtype, struct nouveau_mem **pmem)
+{
+       struct nv50_fb_priv *priv = (void *)pfb;
+       struct nouveau_mm *heap = &priv->base.vram;
+       struct nouveau_mm *tags = &priv->base.tags;
+       struct nouveau_mm_node *r;
+       struct nouveau_mem *mem;
+       int comp = (memtype & 0x300) >> 8;
+       int type = (memtype & 0x07f);
+       int back = (memtype & 0x800);
+       int min, max, ret;
+
+       max = (size >> 12);
+       min = ncmin ? (ncmin >> 12) : max;
+       align >>= 12;
+
+       mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+       if (!mem)
+               return -ENOMEM;
 
-       if (priv->r100c08_page) {
-               pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE,
-                              PCI_DMA_BIDIRECTIONAL);
-               __free_page(priv->r100c08_page);
+       mutex_lock(&pfb->base.mutex);
+       if (comp) {
+               if (align == 16) {
+                       int n = (max >> 4) * comp;
+
+                       ret = nouveau_mm_head(tags, 1, n, n, 1, &mem->tag);
+                       if (ret)
+                               mem->tag = NULL;
+               }
+
+               if (unlikely(!mem->tag))
+                       comp = 0;
        }
 
-       kfree(priv);
-       pfb->priv = NULL;
+       INIT_LIST_HEAD(&mem->regions);
+       mem->memtype = (comp << 7) | type;
+       mem->size = max;
+
+       type = types[type];
+       do {
+               if (back)
+                       ret = nouveau_mm_tail(heap, type, max, min, align, &r);
+               else
+                       ret = nouveau_mm_head(heap, type, max, min, align, &r);
+               if (ret) {
+                       mutex_unlock(&pfb->base.mutex);
+                       pfb->ram.put(pfb, &mem);
+                       return ret;
+               }
+
+               list_add_tail(&r->rl_entry, &mem->regions);
+               max -= r->length;
+       } while (max);
+       mutex_unlock(&pfb->base.mutex);
+
+       r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+       mem->offset = (u64)r->offset << 12;
+       *pmem = mem;
+       return 0;
 }
 
-static int
-nv50_fb_create(struct drm_device *dev)
+void
+nv50_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       struct nv50_fb_priv *priv;
-       u32 tagmem;
-       int ret;
+       struct nv50_fb_priv *priv = (void *)pfb;
+       struct nouveau_mm_node *this;
+       struct nouveau_mem *mem;
 
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-       pfb->priv = priv;
+       mem = *pmem;
+       *pmem = NULL;
+       if (unlikely(mem == NULL))
+               return;
 
-       priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
-       if (!priv->r100c08_page) {
-               nv50_fb_destroy(dev);
-               return -ENOMEM;
+       mutex_lock(&pfb->base.mutex);
+       while (!list_empty(&mem->regions)) {
+               this = list_first_entry(&mem->regions, typeof(*this), rl_entry);
+
+               list_del(&this->rl_entry);
+               nouveau_mm_free(&priv->base.vram, &this);
        }
 
-       priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0,
-                                    PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-       if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) {
-               nv50_fb_destroy(dev);
-               return -EFAULT;
+       nouveau_mm_free(&priv->base.tags, &mem->tag);
+       mutex_unlock(&pfb->base.mutex);
+
+       kfree(mem);
+}
+
+static u32
+nv50_vram_rblock(struct nv50_fb_priv *priv)
+{
+       int i, parts, colbits, rowbitsa, rowbitsb, banks;
+       u64 rowsize, predicted;
+       u32 r0, r4, rt, ru, rblock_size;
+
+       r0 = nv_rd32(priv, 0x100200);
+       r4 = nv_rd32(priv, 0x100204);
+       rt = nv_rd32(priv, 0x100250);
+       ru = nv_rd32(priv, 0x001540);
+       nv_debug(priv, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
+
+       for (i = 0, parts = 0; i < 8; i++) {
+               if (ru & (0x00010000 << i))
+                       parts++;
        }
 
-       tagmem = nv_rd32(dev, 0x100320);
-       NV_DEBUG(dev, "%d tags available\n", tagmem);
-       ret = drm_mm_init(&pfb->tag_heap, 0, tagmem);
-       if (ret) {
-               nv50_fb_destroy(dev);
-               return ret;
+       colbits  =  (r4 & 0x0000f000) >> 12;
+       rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
+       rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
+       banks    = 1 << (((r4 & 0x03000000) >> 24) + 2);
+
+       rowsize = parts * banks * (1 << colbits) * 8;
+       predicted = rowsize << rowbitsa;
+       if (r0 & 0x00000004)
+               predicted += rowsize << rowbitsb;
+
+       if (predicted != priv->base.ram.size) {
+               nv_warn(priv, "memory controller reports %d MiB VRAM\n",
+                       (u32)(priv->base.ram.size >> 20));
        }
 
-       return 0;
+       rblock_size = rowsize;
+       if (rt & 1)
+               rblock_size *= 3;
+
+       nv_debug(priv, "rblock %d bytes\n", rblock_size);
+       return rblock_size;
 }
 
-int
-nv50_fb_init(struct drm_device *dev)
+static int
+nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+            struct nouveau_oclass *oclass, void *data, u32 size,
+            struct nouveau_object **pobject)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_device *device = nv_device(parent);
+       struct nouveau_bios *bios = nouveau_bios(device);
+       const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
+       const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
        struct nv50_fb_priv *priv;
+       u32 tags;
        int ret;
 
-       if (!dev_priv->engine.fb.priv) {
-               ret = nv50_fb_create(dev);
+       ret = nouveau_fb_create(parent, engine, oclass, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
+
+       switch (nv_rd32(priv, 0x100714) & 0x00000007) {
+       case 0: priv->base.ram.type = NV_MEM_TYPE_DDR1; break;
+       case 1:
+               if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3)
+                       priv->base.ram.type = NV_MEM_TYPE_DDR3;
+               else
+                       priv->base.ram.type = NV_MEM_TYPE_DDR2;
+               break;
+       case 2: priv->base.ram.type = NV_MEM_TYPE_GDDR3; break;
+       case 3: priv->base.ram.type = NV_MEM_TYPE_GDDR4; break;
+       case 4: priv->base.ram.type = NV_MEM_TYPE_GDDR5; break;
+       default:
+               break;
+       }
+
+       priv->base.ram.size = nv_rd32(priv, 0x10020c);
+       priv->base.ram.size = (priv->base.ram.size & 0xffffff00) |
+                            ((priv->base.ram.size & 0x000000ff) << 32);
+
+       tags = nv_rd32(priv, 0x100320);
+       if (tags) {
+               ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1);
                if (ret)
                        return ret;
+
+               nv_debug(priv, "%d compression tags\n", tags);
+       }
+
+       size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail;
+       switch (device->chipset) {
+       case 0xaa:
+       case 0xac:
+       case 0xaf: /* IGPs, no reordering, no real VRAM */
+               ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size, 1);
+               if (ret)
+                       return ret;
+
+               priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12;
+               break;
+       default:
+               ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size,
+                                     nv50_vram_rblock(priv) >> 12);
+               if (ret)
+                       return ret;
+
+               priv->base.ram.ranks = (nv_rd32(priv, 0x100200) & 0x4) ? 2 : 1;
+               break;
+       }
+
+       priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+       if (priv->r100c08_page) {
+               priv->r100c08 = pci_map_page(device->pdev, priv->r100c08_page,
+                                            0, PAGE_SIZE,
+                                            PCI_DMA_BIDIRECTIONAL);
+               if (pci_dma_mapping_error(device->pdev, priv->r100c08))
+                       nv_warn(priv, "failed 0x100c08 page map\n");
+       } else {
+               nv_warn(priv, "failed 0x100c08 page alloc\n");
        }
-       priv = dev_priv->engine.fb.priv;
+
+       priv->base.memtype_valid = nv50_fb_memtype_valid;
+       priv->base.ram.get = nv50_fb_vram_new;
+       priv->base.ram.put = nv50_fb_vram_del;
+       return nouveau_fb_created(&priv->base);
+}
+
+static void
+nv50_fb_dtor(struct nouveau_object *object)
+{
+       struct nouveau_device *device = nv_device(object);
+       struct nv50_fb_priv *priv = (void *)object;
+
+       if (priv->r100c08_page) {
+               pci_unmap_page(device->pdev, priv->r100c08, PAGE_SIZE,
+                              PCI_DMA_BIDIRECTIONAL);
+               __free_page(priv->r100c08_page);
+       }
+
+       nouveau_mm_fini(&priv->base.vram);
+       nouveau_fb_destroy(&priv->base);
+}
+
+static int
+nv50_fb_init(struct nouveau_object *object)
+{
+       struct nouveau_device *device = nv_device(object);
+       struct nv50_fb_priv *priv = (void *)object;
+       int ret;
+
+       ret = nouveau_fb_init(&priv->base);
+       if (ret)
+               return ret;
 
        /* Not a clue what this is exactly.  Without pointing it at a
         * scratch page, VRAM->GART blits with M2MF (as in DDX DFS)
         * cause IOMMU "read from address 0" errors (rh#561267)
         */
-       nv_wr32(dev, 0x100c08, priv->r100c08 >> 8);
+       nv_wr32(priv, 0x100c08, priv->r100c08 >> 8);
 
        /* This is needed to get meaningful information from 100c90
         * on traps. No idea what these values mean exactly. */
-       switch (dev_priv->chipset) {
+       switch (device->chipset) {
        case 0x50:
-               nv_wr32(dev, 0x100c90, 0x000707ff);
+               nv_wr32(priv, 0x100c90, 0x000707ff);
                break;
        case 0xa3:
        case 0xa5:
        case 0xa8:
-               nv_wr32(dev, 0x100c90, 0x000d0fff);
+               nv_wr32(priv, 0x100c90, 0x000d0fff);
                break;
        case 0xaf:
-               nv_wr32(dev, 0x100c90, 0x089d1fff);
+               nv_wr32(priv, 0x100c90, 0x089d1fff);
                break;
        default:
-               nv_wr32(dev, 0x100c90, 0x001d07ff);
+               nv_wr32(priv, 0x100c90, 0x001d07ff);
                break;
        }
 
        return 0;
 }
 
-void
-nv50_fb_takedown(struct drm_device *dev)
-{
-       nv50_fb_destroy(dev);
-}
+struct nouveau_oclass
+nv50_fb_oclass = {
+       .handle = NV_SUBDEV(FB, 0x50),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nv50_fb_ctor,
+               .dtor = nv50_fb_dtor,
+               .init = nv50_fb_init,
+               .fini = _nouveau_fb_fini,
+       },
+};
 
 static struct nouveau_enum vm_dispatch_subclients[] = {
        { 0x00000000, "GRCTX", NULL },
@@ -211,47 +427,32 @@ static struct nouveau_enum vm_fault[] = {
 };
 
 void
-nv50_fb_vm_trap(struct drm_device *dev, int display)
+nv50_fb_trap(struct nouveau_fb *pfb, int display)
 {
-       struct nouveau_fifo_priv *pfifo = nv_engine(dev, NVOBJ_ENGINE_FIFO);
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_device *device = nv_device(pfb);
+       struct nv50_fb_priv *priv = (void *)pfb;
        const struct nouveau_enum *en, *cl;
-       unsigned long flags;
-       u32 trap[6], idx, chinst;
+       u32 trap[6], idx, chan;
        u8 st0, st1, st2, st3;
-       int i, ch;
+       int i;
 
-       idx = nv_rd32(dev, 0x100c90);
+       idx = nv_rd32(priv, 0x100c90);
        if (!(idx & 0x80000000))
                return;
        idx &= 0x00ffffff;
 
        for (i = 0; i < 6; i++) {
-               nv_wr32(dev, 0x100c90, idx | i << 24);
-               trap[i] = nv_rd32(dev, 0x100c94);
+               nv_wr32(priv, 0x100c90, idx | i << 24);
+               trap[i] = nv_rd32(priv, 0x100c94);
        }
-       nv_wr32(dev, 0x100c90, idx | 0x80000000);
+       nv_wr32(priv, 0x100c90, idx | 0x80000000);
 
        if (!display)
                return;
 
-       /* lookup channel id */
-       chinst = (trap[2] << 16) | trap[1];
-       spin_lock_irqsave(&dev_priv->channels.lock, flags);
-       for (ch = 0; ch < pfifo->channels; ch++) {
-               struct nouveau_channel *chan = dev_priv->channels.ptr[ch];
-
-               if (!chan || !chan->ramin)
-                       continue;
-
-               if (chinst == chan->ramin->vinst >> 12)
-                       break;
-       }
-       spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
-
        /* decode status bits into something more useful */
-       if (dev_priv->chipset  < 0xa3 ||
-           dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) {
+       if (device->chipset  < 0xa3 ||
+           device->chipset == 0xaa || device->chipset == 0xac) {
                st0 = (trap[0] & 0x0000000f) >> 0;
                st1 = (trap[0] & 0x000000f0) >> 4;
                st2 = (trap[0] & 0x00000f00) >> 8;
@@ -262,10 +463,11 @@ nv50_fb_vm_trap(struct drm_device *dev, int display)
                st2 = (trap[0] & 0x00ff0000) >> 16;
                st3 = (trap[0] & 0xff000000) >> 24;
        }
+       chan = (trap[2] << 16) | trap[1];
 
-       NV_INFO(dev, "VM: trapped %s at 0x%02x%04x%04x on ch %d [0x%08x] ",
-               (trap[5] & 0x00000100) ? "read" : "write",
-               trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, ch, chinst);
+       nv_error(priv, "trapped %s at 0x%02x%04x%04x on channel 0x%08x ",
+                (trap[5] & 0x00000100) ? "read" : "write",
+                trap[5] & 0xff, trap[4] & 0xffff, trap[3] & 0xffff, chan);
 
        en = nouveau_enum_find(vm_engine, st0);
        if (en)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50_vram.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50_vram.c
deleted file mode 100644 (file)
index 84b99b6..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2010 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
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include <core/mm.h>
-
-static int types[0x80] = {
-       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0,
-       1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0,
-       0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-       1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0
-};
-
-bool
-nv50_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
-{
-       int type = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8;
-
-       if (likely(type < ARRAY_SIZE(types) && types[type]))
-               return true;
-       return false;
-}
-
-void
-nv50_vram_del(struct drm_device *dev, struct nouveau_mem **pmem)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
-       struct nouveau_mm_node *this;
-       struct nouveau_mem *mem;
-
-       mem = *pmem;
-       *pmem = NULL;
-       if (unlikely(mem == NULL))
-               return;
-
-       mutex_lock(&mm->mutex);
-       while (!list_empty(&mem->regions)) {
-               this = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
-
-               list_del(&this->rl_entry);
-               nouveau_mm_free(mm, &this);
-       }
-
-       if (mem->tag) {
-               drm_mm_put_block(mem->tag);
-               mem->tag = NULL;
-       }
-       mutex_unlock(&mm->mutex);
-
-       kfree(mem);
-}
-
-int
-nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
-             u32 memtype, struct nouveau_mem **pmem)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
-       struct nouveau_mm_node *r;
-       struct nouveau_mem *mem;
-       int comp = (memtype & 0x300) >> 8;
-       int type = (memtype & 0x07f);
-       int back = (memtype & 0x800);
-       int ret;
-
-       size >>= 12;
-       align >>= 12;
-       ncmin >>= 12;
-       if (!ncmin)
-               ncmin = size;
-
-       mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-       if (!mem)
-               return -ENOMEM;
-
-       mutex_lock(&mm->mutex);
-       if (comp) {
-               if (align == 16) {
-                       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-                       int n = (size >> 4) * comp;
-
-                       mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0);
-                       if (mem->tag)
-                               mem->tag = drm_mm_get_block(mem->tag, n, 0);
-               }
-
-               if (unlikely(!mem->tag))
-                       comp = 0;
-       }
-
-       INIT_LIST_HEAD(&mem->regions);
-       mem->dev = dev_priv->dev;
-       mem->memtype = (comp << 7) | type;
-       mem->size = size;
-
-       type = types[type];
-       do {
-               if (back)
-                       ret = nouveau_mm_tail(mm, type, size, ncmin, align, &r);
-               else
-                       ret = nouveau_mm_head(mm, type, size, ncmin, align, &r);
-
-               if (ret) {
-                       mutex_unlock(&mm->mutex);
-                       nv50_vram_del(dev, &mem);
-                       return ret;
-               }
-
-               list_add_tail(&r->rl_entry, &mem->regions);
-               size -= r->length;
-       } while (size);
-       mutex_unlock(&mm->mutex);
-
-       r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
-       mem->offset = (u64)r->offset << 12;
-       *pmem = mem;
-       return 0;
-}
-
-static u32
-nv50_vram_rblock(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       int i, parts, colbits, rowbitsa, rowbitsb, banks;
-       u64 rowsize, predicted;
-       u32 r0, r4, rt, ru, rblock_size;
-
-       r0 = nv_rd32(dev, 0x100200);
-       r4 = nv_rd32(dev, 0x100204);
-       rt = nv_rd32(dev, 0x100250);
-       ru = nv_rd32(dev, 0x001540);
-       NV_DEBUG(dev, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru);
-
-       for (i = 0, parts = 0; i < 8; i++) {
-               if (ru & (0x00010000 << i))
-                       parts++;
-       }
-
-       colbits  =  (r4 & 0x0000f000) >> 12;
-       rowbitsa = ((r4 & 0x000f0000) >> 16) + 8;
-       rowbitsb = ((r4 & 0x00f00000) >> 20) + 8;
-       banks    = 1 << (((r4 & 0x03000000) >> 24) + 2);
-
-       rowsize = parts * banks * (1 << colbits) * 8;
-       predicted = rowsize << rowbitsa;
-       if (r0 & 0x00000004)
-               predicted += rowsize << rowbitsb;
-
-       if (predicted != dev_priv->vram_size) {
-               NV_WARN(dev, "memory controller reports %dMiB VRAM\n",
-                       (u32)(dev_priv->vram_size >> 20));
-               NV_WARN(dev, "we calculated %dMiB VRAM\n",
-                       (u32)(predicted >> 20));
-       }
-
-       rblock_size = rowsize;
-       if (rt & 1)
-               rblock_size *= 3;
-
-       NV_DEBUG(dev, "rblock %d bytes\n", rblock_size);
-       return rblock_size;
-}
-
-int
-nv50_vram_init(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
-       const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
-       const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
-       u32 pfb714 = nv_rd32(dev, 0x100714);
-       u32 rblock, length;
-
-       switch (pfb714 & 0x00000007) {
-       case 0: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break;
-       case 1:
-               if (nouveau_mem_vbios_type(dev) == NV_MEM_TYPE_DDR3)
-                       dev_priv->vram_type = NV_MEM_TYPE_DDR3;
-               else
-                       dev_priv->vram_type = NV_MEM_TYPE_DDR2;
-               break;
-       case 2: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break;
-       case 3: dev_priv->vram_type = NV_MEM_TYPE_GDDR4; break;
-       case 4: dev_priv->vram_type = NV_MEM_TYPE_GDDR5; break;
-       default:
-               break;
-       }
-
-       dev_priv->vram_rank_B = !!(nv_rd32(dev, 0x100200) & 0x4);
-       dev_priv->vram_size  = nv_rd32(dev, 0x10020c);
-       dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32;
-       dev_priv->vram_size &= 0xffffffff00ULL;
-
-       /* IGPs, no funky reordering happens here, they don't have VRAM */
-       if (dev_priv->chipset == 0xaa ||
-           dev_priv->chipset == 0xac ||
-           dev_priv->chipset == 0xaf) {
-               dev_priv->vram_sys_base = (u64)nv_rd32(dev, 0x100e10) << 12;
-               rblock = 4096 >> 12;
-       } else {
-               rblock = nv50_vram_rblock(dev) >> 12;
-       }
-
-       length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail;
-
-       return nouveau_mm_init(&vram->mm, rsvd_head, length, rblock);
-}
-
-void
-nv50_vram_fini(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
-
-       nouveau_mm_fini(&vram->mm);
-}
index f054331..9f59f2b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011 Red Hat Inc.
+ * Copyright 2012 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"),
  * Authors: Ben Skeggs
  */
 
-#include "drmP.h"
-#include "drm.h"
-#include "nouveau_drv.h"
-#include <nouveau_drm.h>
+#include <subdev/fb.h>
+#include <subdev/bios.h>
 
 struct nvc0_fb_priv {
+       struct nouveau_fb base;
        struct page *r100c10_page;
        dma_addr_t r100c10;
 };
 
-static inline void
-nvc0_mfb_subp_isr(struct drm_device *dev, int unit, int subp)
+/* 0 = unsupported
+ * 1 = non-compressed
+ * 3 = compressed
+ */
+static const u8 types[256] = {
+       1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+       0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
+       3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+       3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
+       3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
+       3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
+       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
+};
+
+static bool
+nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
 {
-       u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400);
-       u32 stat = nv_rd32(dev, subp_base + 0x020);
+       u8 memtype = (tile_flags & 0x0000ff00) >> 8;
+       return likely((types[memtype] == 1));
+}
 
-       if (stat) {
-               NV_INFO(dev, "PMFB%d_SUBP%d: 0x%08x\n", unit, subp, stat);
-               nv_wr32(dev, subp_base + 0x020, stat);
-       }
+static int
+nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
+                u32 memtype, struct nouveau_mem **pmem)
+{
+       struct nouveau_mm *mm = &pfb->vram;
+       struct nouveau_mm_node *r;
+       struct nouveau_mem *mem;
+       int type = (memtype & 0x0ff);
+       int back = (memtype & 0x800);
+       int ret;
+
+       size  >>= 12;
+       align >>= 12;
+       ncmin >>= 12;
+       if (!ncmin)
+               ncmin = size;
+
+       mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+       if (!mem)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&mem->regions);
+       mem->memtype = type;
+       mem->size = size;
+
+       mutex_lock(&mm->mutex);
+       do {
+               if (back)
+                       ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
+               else
+                       ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
+               if (ret) {
+                       mutex_unlock(&mm->mutex);
+                       pfb->ram.put(pfb, &mem);
+                       return ret;
+               }
+
+               list_add_tail(&r->rl_entry, &mem->regions);
+               size -= r->length;
+       } while (size);
+       mutex_unlock(&mm->mutex);
+
+       r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+       mem->offset = (u64)r->offset << 12;
+       *pmem = mem;
+       return 0;
 }
 
-static void
-nvc0_mfb_isr(struct drm_device *dev)
+static int
+nvc0_fb_init(struct nouveau_object *object)
 {
-       u32 units = nv_rd32(dev, 0x00017c);
-       while (units) {
-               u32 subp, unit = ffs(units) - 1;
-               for (subp = 0; subp < 2; subp++)
-                       nvc0_mfb_subp_isr(dev, unit, subp);
-               units &= ~(1 << unit);
-       }
+       struct nvc0_fb_priv *priv = (void *)object;
+       int ret;
+
+       ret = nouveau_fb_init(&priv->base);
+       if (ret)
+               return ret;
 
-       /* we do something horribly wrong and upset PMFB a lot, so mask off
-        * interrupts from it after the first one until it's fixed
-        */
-       nv_mask(dev, 0x000640, 0x02000000, 0x00000000);
+       nv_wr32(priv, 0x100c10, priv->r100c10 >> 8);
+       return 0;
 }
 
 static void
-nvc0_fb_destroy(struct drm_device *dev)
+nvc0_fb_dtor(struct nouveau_object *object)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       struct nvc0_fb_priv *priv = pfb->priv;
-
-       nouveau_irq_unregister(dev, 25);
+       struct nouveau_device *device = nv_device(object);
+       struct nvc0_fb_priv *priv = (void *)object;
 
        if (priv->r100c10_page) {
-               pci_unmap_page(dev->pdev, priv->r100c10, PAGE_SIZE,
+               pci_unmap_page(device->pdev, priv->r100c10, PAGE_SIZE,
                               PCI_DMA_BIDIRECTIONAL);
                __free_page(priv->r100c10_page);
        }
 
-       kfree(priv);
-       pfb->priv = NULL;
+       nouveau_fb_destroy(&priv->base);
 }
 
 static int
-nvc0_fb_create(struct drm_device *dev)
+nvc0_vram_detect(struct nvc0_fb_priv *priv)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       struct nvc0_fb_priv *priv;
-
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-       pfb->priv = priv;
+       struct nouveau_bios *bios = nouveau_bios(priv);
+       struct nouveau_fb *pfb = &priv->base;
+       const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
+       const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
+       u32 parts = nv_rd32(priv, 0x022438);
+       u32 pmask = nv_rd32(priv, 0x022554);
+       u32 bsize = nv_rd32(priv, 0x10f20c);
+       u32 offset, length;
+       bool uniform = true;
+       int ret, part;
+
+       nv_debug(priv, "0x100800: 0x%08x\n", nv_rd32(priv, 0x100800));
+       nv_debug(priv, "parts 0x%08x mask 0x%08x\n", parts, pmask);
+
+       priv->base.ram.type = nouveau_fb_bios_memtype(bios);
+       priv->base.ram.ranks = (nv_rd32(priv, 0x10f200) & 0x00000004) ? 2 : 1;
+
+       /* read amount of vram attached to each memory controller */
+       for (part = 0; part < parts; part++) {
+               if (!(pmask & (1 << part))) {
+                       u32 psize = nv_rd32(priv, 0x11020c + (part * 0x1000));
+                       if (psize != bsize) {
+                               if (psize < bsize)
+                                       bsize = psize;
+                               uniform = false;
+                       }
+
+                       nv_debug(priv, "%d: mem_amount 0x%08x\n", part, psize);
+                       priv->base.ram.size += (u64)psize << 20;
+               }
+       }
 
-       priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
-       if (!priv->r100c10_page) {
-               nvc0_fb_destroy(dev);
-               return -ENOMEM;
+       /* if all controllers have the same amount attached, there's no holes */
+       if (uniform) {
+               offset = rsvd_head;
+               length = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail;
+               return nouveau_mm_init(&pfb->vram, offset, length, 1);
        }
 
-       priv->r100c10 = pci_map_page(dev->pdev, priv->r100c10_page, 0,
-                                    PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-       if (pci_dma_mapping_error(dev->pdev, priv->r100c10)) {
-               nvc0_fb_destroy(dev);
-               return -EFAULT;
+       /* otherwise, address lowest common amount from 0GiB */
+       ret = nouveau_mm_init(&pfb->vram, rsvd_head, (bsize << 8) * parts, 1);
+       if (ret)
+               return ret;
+
+       /* and the rest starting from (8GiB + common_size) */
+       offset = (0x0200000000ULL >> 12) + (bsize << 8);
+       length = (priv->base.ram.size >> 12) - (bsize << 8) - rsvd_tail;
+
+       ret = nouveau_mm_init(&pfb->vram, offset, length, 0);
+       if (ret) {
+               nouveau_mm_fini(&pfb->vram);
+               return ret;
        }
 
-       nouveau_irq_register(dev, 25, nvc0_mfb_isr);
        return 0;
 }
 
-int
-nvc0_fb_init(struct drm_device *dev)
+static int
+nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+            struct nouveau_oclass *oclass, void *data, u32 size,
+            struct nouveau_object **pobject)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_device *device = nv_device(parent);
        struct nvc0_fb_priv *priv;
        int ret;
 
-       if (!dev_priv->engine.fb.priv) {
-               ret = nvc0_fb_create(dev);
-               if (ret)
-                       return ret;
-       }
-       priv = dev_priv->engine.fb.priv;
+       ret = nouveau_fb_create(parent, engine, oclass, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
 
-       nv_wr32(dev, 0x100c10, priv->r100c10 >> 8);
-       nv_mask(dev, 0x17e820, 0x00100000, 0x00000000); /* NV_PLTCG_INTR_EN */
-       return 0;
-}
+       priv->base.memtype_valid = nvc0_fb_memtype_valid;
+       priv->base.ram.get = nvc0_fb_vram_new;
+       priv->base.ram.put = nv50_fb_vram_del;
 
-void
-nvc0_fb_takedown(struct drm_device *dev)
-{
-       nvc0_fb_destroy(dev);
+       ret = nvc0_vram_detect(priv);
+       if (ret)
+               return ret;
+
+       priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+       if (!priv->r100c10_page)
+               return -ENOMEM;
+
+       priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page, 0,
+                                    PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+       if (pci_dma_mapping_error(device->pdev, priv->r100c10))
+               return -EFAULT;
+
+       return nouveau_fb_created(&priv->base);
 }
+
+
+struct nouveau_oclass
+nvc0_fb_oclass = {
+       .handle = NV_SUBDEV(FB, 0xc0),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nvc0_fb_ctor,
+               .dtor = nvc0_fb_dtor,
+               .init = nvc0_fb_init,
+               .fini = _nouveau_fb_fini,
+       },
+};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0_vram.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0_vram.c
deleted file mode 100644 (file)
index f363234..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2010 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
- */
-
-#include "drmP.h"
-#include "nouveau_drv.h"
-#include <core/mm.h>
-
-/* 0 = unsupported
- * 1 = non-compressed
- * 3 = compressed
- */
-static const u8 types[256] = {
-       1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
-       0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
-       3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
-       3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
-       3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
-       3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
-       3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
-};
-
-bool
-nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags)
-{
-       u8 memtype = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8;
-       return likely((types[memtype] == 1));
-}
-
-int
-nvc0_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
-             u32 memtype, struct nouveau_mem **pmem)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_mm *mm = &dev_priv->engine.vram.mm;
-       struct nouveau_mm_node *r;
-       struct nouveau_mem *mem;
-       int type = (memtype & 0x0ff);
-       int back = (memtype & 0x800);
-       int ret;
-
-       size  >>= 12;
-       align >>= 12;
-       ncmin >>= 12;
-       if (!ncmin)
-               ncmin = size;
-
-       mem = kzalloc(sizeof(*mem), GFP_KERNEL);
-       if (!mem)
-               return -ENOMEM;
-
-       INIT_LIST_HEAD(&mem->regions);
-       mem->dev = dev_priv->dev;
-       mem->memtype = type;
-       mem->size = size;
-
-       mutex_lock(&mm->mutex);
-       do {
-               if (back)
-                       ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
-               else
-                       ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
-               if (ret) {
-                       mutex_unlock(&mm->mutex);
-                       nv50_vram_del(dev, &mem);
-                       return ret;
-               }
-
-               list_add_tail(&r->rl_entry, &mem->regions);
-               size -= r->length;
-       } while (size);
-       mutex_unlock(&mm->mutex);
-
-       r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
-       mem->offset = (u64)r->offset << 12;
-       *pmem = mem;
-       return 0;
-}
-
-int
-nvc0_vram_init(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
-       const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */
-       const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */
-       u32 parts = nv_rd32(dev, 0x022438);
-       u32 pmask = nv_rd32(dev, 0x022554);
-       u32 bsize = nv_rd32(dev, 0x10f20c);
-       u32 offset, length;
-       bool uniform = true;
-       int ret, part;
-
-       NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800));
-       NV_DEBUG(dev, "parts 0x%08x mask 0x%08x\n", parts, pmask);
-
-       dev_priv->vram_type = nouveau_mem_vbios_type(dev);
-       dev_priv->vram_rank_B = !!(nv_rd32(dev, 0x10f200) & 0x00000004);
-
-       /* read amount of vram attached to each memory controller */
-       for (part = 0; part < parts; part++) {
-               if (!(pmask & (1 << part))) {
-                       u32 psize = nv_rd32(dev, 0x11020c + (part * 0x1000));
-                       if (psize != bsize) {
-                               if (psize < bsize)
-                                       bsize = psize;
-                               uniform = false;
-                       }
-
-                       NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize);
-                       dev_priv->vram_size += (u64)psize << 20;
-               }
-       }
-
-       /* if all controllers have the same amount attached, there's no holes */
-       if (uniform) {
-               offset = rsvd_head;
-               length = (dev_priv->vram_size >> 12) - rsvd_head - rsvd_tail;
-               return nouveau_mm_init(&vram->mm, offset, length, 1);
-       }
-
-       /* otherwise, address lowest common amount from 0GiB */
-       ret = nouveau_mm_init(&vram->mm, rsvd_head, (bsize << 8) * parts, 1);
-       if (ret)
-               return ret;
-
-       /* and the rest starting from (8GiB + common_size) */
-       offset = (0x0200000000ULL >> 12) + (bsize << 8);
-       length = (dev_priv->vram_size >> 12) - (bsize << 8) - rsvd_tail;
-
-       ret = nouveau_mm_init(&vram->mm, offset, length, 0);
-       if (ret) {
-               nouveau_mm_fini(&vram->mm);
-               return ret;
-       }
-
-       return 0;
-}
index 5965eb7..24d077a 100644 (file)
@@ -310,8 +310,6 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
                 u32 size, u32 align)
 {
        struct drm_device *dev = gpuobj->dev;
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
        struct nv50_gpuobj_node *node = NULL;
        int ret;
 
@@ -323,7 +321,7 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
        size  = (size + 4095) & ~4095;
        align = max(align, (u32)4096);
 
-       ret = vram->get(dev, size, align, 0, 0x800, &node->vram);
+       ret = nvfb_vram_get(dev, size, align, 0, 0x800, &node->vram);
        if (ret) {
                kfree(node);
                return ret;
@@ -339,7 +337,7 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, struct nouveau_channel *chan,
                ret = nouveau_vm_get(chan->vm, size, 12, flags,
                                     &node->chan_vma);
                if (ret) {
-                       vram->put(dev, &node->vram);
+                       nvfb_vram_put(dev, &node->vram);
                        kfree(node);
                        return ret;
                }
@@ -357,8 +355,6 @@ void
 nv50_instmem_put(struct nouveau_gpuobj *gpuobj)
 {
        struct drm_device *dev = gpuobj->dev;
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
        struct nv50_gpuobj_node *node;
 
        node = gpuobj->node;
@@ -368,7 +364,7 @@ nv50_instmem_put(struct nouveau_gpuobj *gpuobj)
                nouveau_vm_unmap(&node->chan_vma);
                nouveau_vm_put(&node->chan_vma);
        }
-       vram->put(dev, &node->vram);
+       nvfb_vram_put(dev, &node->vram);
        kfree(node);
 }
 
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
new file mode 100644 (file)
index 0000000..7c2840c
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2012 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
+ */
+
+#include <subdev/ltcg.h>
+
+struct nvc0_ltcg_priv {
+       struct nouveau_ltcg base;
+};
+
+static void
+nvc0_ltcg_subp_isr(struct nvc0_ltcg_priv *priv, int unit, int subp)
+{
+       u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400);
+       u32 stat = nv_rd32(priv, subp_base + 0x020);
+
+       if (stat) {
+               nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", unit, subp, stat);
+               nv_wr32(priv, subp_base + 0x020, stat);
+       }
+}
+
+static void
+nvc0_ltcg_intr(struct nouveau_subdev *subdev)
+{
+       struct nvc0_ltcg_priv *priv = (void *)subdev;
+       u32 units;
+
+       units = nv_rd32(priv, 0x00017c);
+       while (units) {
+               u32 subp, unit = ffs(units) - 1;
+               for (subp = 0; subp < 2; subp++)
+                       nvc0_ltcg_subp_isr(priv, unit, subp);
+               units &= ~(1 << unit);
+       }
+
+       /* we do something horribly wrong and upset PMFB a lot, so mask off
+        * interrupts from it after the first one until it's fixed
+        */
+       nv_mask(priv, 0x000640, 0x02000000, 0x00000000);
+}
+
+static int
+nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+              struct nouveau_oclass *oclass, void *data, u32 size,
+              struct nouveau_object **pobject)
+{
+       struct nvc0_ltcg_priv *priv;
+       int ret;
+
+       ret = nouveau_ltcg_create(parent, engine, oclass, &priv);
+       *pobject = nv_object(priv);
+       if (ret)
+               return ret;
+
+       nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
+
+       nv_subdev(priv)->intr = nvc0_ltcg_intr;
+       return 0;
+}
+
+struct nouveau_oclass
+nvc0_ltcg_oclass = {
+       .handle = NV_SUBDEV(LTCG, 0xc0),
+       .ofuncs = &(struct nouveau_ofuncs) {
+               .ctor = nvc0_ltcg_ctor,
+               .dtor = _nouveau_ltcg_dtor,
+               .init = _nouveau_ltcg_init,
+               .fini = _nouveau_ltcg_fini,
+       },
+};
index 3fa39bb..bd9e994 100644 (file)
@@ -38,6 +38,7 @@ nvc0_mc_intr[] = {
        { 0x00008000, NVDEV_ENGINE_BSP },
        { 0x00100000, NVDEV_SUBDEV_TIMER },
        { 0x00200000, NVDEV_SUBDEV_GPIO },
+       { 0x02000000, NVDEV_SUBDEV_LTCG },
        { 0x04000000, NVDEV_ENGINE_DISP },
        { 0x80000000, NVDEV_ENGINE_SW },
        {},
index eeac72f..7e46826 100644 (file)
@@ -80,8 +80,8 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
 
        /* IGPs don't have real VRAM, re-target to stolen system memory */
        target = 0;
-       if (dev_priv->vram_sys_base) {
-               phys += dev_priv->vram_sys_base;
+       if (nvfb_vram_sys_base(dev_priv->dev)) {
+               phys += nvfb_vram_sys_base(dev_priv->dev);
                target = 3;
        }
 
@@ -103,7 +103,7 @@ nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
                phys += block << (vma->node->type - 3);
                cnt  -= block;
                if (comp) {
-                       u32 tag = mem->tag->start + ((delta >> 16) * comp);
+                       u32 tag = mem->tag->offset + ((delta >> 16) * comp);
                        offset_h |= (tag << 17);
                        delta    += block << (vma->node->type - 3);
                }
index d952754..f63785c 100644 (file)
@@ -156,7 +156,7 @@ static void
 set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
 {
        struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
-       int vram_pages = dev_priv->vram_size >> PAGE_SHIFT;
+       int vram_pages = nvfb_vram_size(dev_priv->dev) >> PAGE_SHIFT;
 
        if (dev_priv->card_type == NV_10 &&
            nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
index 7880ebb..3d65c17 100644 (file)
@@ -10,6 +10,7 @@
 #include <subdev/clock.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <subdev/fb.h>
 
 void *nouveau_newpriv(struct drm_device *);
 
@@ -332,3 +333,108 @@ nv_timer_read(struct drm_device *dev)
        struct nouveau_timer *ptimer = nouveau_timer(drm->device);
        return ptimer->read(ptimer);
 }
+
+int
+nvfb_tile_nr(struct drm_device *dev)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       return pfb->tile.regions;
+}
+
+struct nouveau_fb_tile *
+nvfb_tile(struct drm_device *dev, int i)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       return &pfb->tile.region[i];
+}
+
+void
+nvfb_tile_init(struct drm_device *dev, int i, u32 a, u32 b, u32 c, u32 d)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       pfb->tile.init(pfb, i, a, b, c, d, &pfb->tile.region[i]);
+}
+
+void
+nvfb_tile_fini(struct drm_device *dev, int i)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       pfb->tile.fini(pfb, i, &pfb->tile.region[i]);
+}
+
+void
+nvfb_tile_prog(struct drm_device *dev, int i)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       pfb->tile.prog(pfb, i, &pfb->tile.region[i]);
+}
+
+bool
+nvfb_flags_valid(struct drm_device *dev, u32 flags)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       return pfb->memtype_valid(pfb, flags);
+}
+
+int
+nvfb_vram_get(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
+             u32 memtype, struct nouveau_mem **pmem)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       int ret = pfb->ram.get(pfb, size, align, ncmin, memtype, pmem);
+       if (ret)
+               return ret;
+       (*pmem)->dev = dev;
+       return 0;
+}
+
+void
+nvfb_vram_put(struct drm_device *dev, struct nouveau_mem **pmem)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       pfb->ram.put(pfb, pmem);
+}
+
+
+u64 nvfb_vram_sys_base(struct drm_device *dev)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       return pfb->ram.stolen;
+}
+
+u64 nvfb_vram_size(struct drm_device *dev)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       return pfb->ram.size;
+}
+
+int nvfb_vram_type(struct drm_device *dev)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       return pfb->ram.type;
+}
+
+int nvfb_vram_rank_B(struct drm_device *dev)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       struct nouveau_fb *pfb = nouveau_fb(drm->device);
+       return pfb->ram.ranks > 1;
+}
+
+void
+nv50_fb_vm_trap(struct drm_device *dev, int disp)
+{
+       struct nouveau_drm *drm = nouveau_newpriv(dev);
+       nv50_fb_trap(nouveau_fb(drm->device), disp);
+}
index c9622eb..d047a20 100644 (file)
@@ -62,4 +62,24 @@ bool nouveau_wait_cb(struct drm_device *, u64 timeout,
 
 u64 nv_timer_read(struct drm_device *);
 
+int  nvfb_tile_nr(struct drm_device *);
+void nvfb_tile_init(struct drm_device *, int, u32, u32, u32, u32);
+void nvfb_tile_fini(struct drm_device *, int);
+void nvfb_tile_prog(struct drm_device *, int);
+
+struct nouveau_fb_tile *nvfb_tile(struct drm_device *, int);
+
+struct nouveau_mem;
+int nvfb_vram_get(struct drm_device *dev, u64 size, u32 align, u32 ncmin,
+                 u32 memtype, struct nouveau_mem **pmem);
+void nvfb_vram_put(struct drm_device *dev, struct nouveau_mem **pmem);
+bool nvfb_flags_valid(struct drm_device *dev, u32);
+
+u64 nvfb_vram_sys_base(struct drm_device *);
+u64 nvfb_vram_size(struct drm_device *);
+int nvfb_vram_type(struct drm_device *);
+int nvfb_vram_rank_B(struct drm_device *);
+
+void nv50_fb_vm_trap(struct drm_device *, int);
+
 #endif
index 188c92b..6564b54 100644 (file)
@@ -137,9 +137,8 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data)
 {
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_minor *minor = node->minor;
-       struct drm_nouveau_private *dev_priv = minor->dev->dev_private;
 
-       seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10));
+       seq_printf(m, "VRAM total: %dKiB\n", (int)(nvfb_vram_size(minor->dev) >> 10));
        return 0;
 }
 
index 7223a4f..3f660a9 100644 (file)
@@ -252,7 +252,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
 
        NV_INFO(dev, "Reinitialising engines...\n");
        engine->instmem.resume(dev);
-       engine->fb.init(dev);
        for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
                if (dev_priv->eng[i])
                        dev_priv->eng[i]->init(dev, i);
index b459599..c7bc6ec 100644 (file)
 #include "ttm/ttm_memory.h"
 #include "ttm/ttm_module.h"
 
+#define XXX_THIS_IS_A_HACK
+#include <subdev/fb.h>
+
+enum blah {
+       NV_MEM_TYPE_UNKNOWN = 0,
+       NV_MEM_TYPE_STOLEN,
+       NV_MEM_TYPE_SGRAM,
+       NV_MEM_TYPE_SDRAM,
+       NV_MEM_TYPE_DDR1,
+       NV_MEM_TYPE_DDR2,
+       NV_MEM_TYPE_DDR3,
+       NV_MEM_TYPE_GDDR2,
+       NV_MEM_TYPE_GDDR3,
+       NV_MEM_TYPE_GDDR4,
+       NV_MEM_TYPE_GDDR5
+};
+
 struct nouveau_fpriv {
        spinlock_t lock;
        struct list_head channels;
@@ -76,29 +93,8 @@ struct nouveau_mem;
 #define NOUVEAU_MAX_CHANNEL_NR 4096
 #define NOUVEAU_MAX_TILE_NR 15
 
-struct nouveau_mem {
-       struct drm_device *dev;
-
-       struct nouveau_vma bar_vma;
-       struct nouveau_vma vma[2];
-       u8  page_shift;
-
-       struct drm_mm_node *tag;
-       struct list_head regions;
-       dma_addr_t *pages;
-       u32 memtype;
-       u64 offset;
-       u64 size;
-       struct sg_table *sg;
-};
-
 struct nouveau_tile_reg {
        bool used;
-       uint32_t addr;
-       uint32_t limit;
-       uint32_t pitch;
-       uint32_t zcomp;
-       struct drm_mm_node *tag_mem;
        struct nouveau_fence *fence;
 };
 
@@ -324,21 +320,6 @@ struct nouveau_instmem_engine {
        void    (*flush)(struct drm_device *);
 };
 
-struct nouveau_fb_engine {
-       int num_tiles;
-       struct drm_mm tag_heap;
-       void *priv;
-
-       int  (*init)(struct drm_device *dev);
-       void (*takedown)(struct drm_device *dev);
-
-       void (*init_tile_region)(struct drm_device *dev, int i,
-                                uint32_t addr, uint32_t size,
-                                uint32_t pitch, uint32_t flags);
-       void (*set_tile_region)(struct drm_device *dev, int i);
-       void (*free_tile_region)(struct drm_device *dev, int i);
-};
-
 struct nouveau_display_engine {
        void *priv;
        int (*early_init)(struct drm_device *);
@@ -519,24 +500,10 @@ struct nouveau_pm_engine {
        int (*temp_get)(struct drm_device *);
 };
 
-struct nouveau_vram_engine {
-       struct nouveau_mm mm;
-
-       int  (*init)(struct drm_device *);
-       void (*takedown)(struct drm_device *dev);
-       int  (*get)(struct drm_device *, u64, u32 align, u32 size_nc,
-                   u32 type, struct nouveau_mem **);
-       void (*put)(struct drm_device *, struct nouveau_mem **);
-
-       bool (*flags_valid)(struct drm_device *, u32 tile_flags);
-};
-
 struct nouveau_engine {
        struct nouveau_instmem_engine instmem;
-       struct nouveau_fb_engine      fb;
        struct nouveau_display_engine display;
        struct nouveau_pm_engine      pm;
-       struct nouveau_vram_engine    vram;
 };
 
 enum nv04_fp_display_regs {
@@ -714,24 +681,6 @@ struct drm_nouveau_private {
                spinlock_t lock;
        } tile;
 
-       /* VRAM/fb configuration */
-       enum {
-               NV_MEM_TYPE_UNKNOWN = 0,
-               NV_MEM_TYPE_STOLEN,
-               NV_MEM_TYPE_SGRAM,
-               NV_MEM_TYPE_SDRAM,
-               NV_MEM_TYPE_DDR1,
-               NV_MEM_TYPE_DDR2,
-               NV_MEM_TYPE_DDR3,
-               NV_MEM_TYPE_GDDR2,
-               NV_MEM_TYPE_GDDR3,
-               NV_MEM_TYPE_GDDR4,
-               NV_MEM_TYPE_GDDR5
-       } vram_type;
-       uint64_t vram_size;
-       uint64_t vram_sys_base;
-       bool vram_rank_B;
-
        uint64_t fb_available_size;
        uint64_t fb_mappable_pages;
        uint64_t fb_aper_free;
@@ -1047,55 +996,6 @@ int nouveau_ttm_mmap(struct file *, struct vm_area_struct *);
 /* nouveau_hdmi.c */
 void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *);
 
-/* nv04_fb.c */
-extern int  nv04_fb_vram_init(struct drm_device *);
-extern int  nv04_fb_init(struct drm_device *);
-extern void nv04_fb_takedown(struct drm_device *);
-
-/* nv10_fb.c */
-extern int  nv10_fb_vram_init(struct drm_device *dev);
-extern int  nv1a_fb_vram_init(struct drm_device *dev);
-extern int  nv10_fb_init(struct drm_device *);
-extern void nv10_fb_takedown(struct drm_device *);
-extern void nv10_fb_init_tile_region(struct drm_device *dev, int i,
-                                    uint32_t addr, uint32_t size,
-                                    uint32_t pitch, uint32_t flags);
-extern void nv10_fb_set_tile_region(struct drm_device *dev, int i);
-extern void nv10_fb_free_tile_region(struct drm_device *dev, int i);
-
-/* nv20_fb.c */
-extern int  nv20_fb_vram_init(struct drm_device *dev);
-extern int  nv20_fb_init(struct drm_device *);
-extern void nv20_fb_takedown(struct drm_device *);
-extern void nv20_fb_init_tile_region(struct drm_device *dev, int i,
-                                    uint32_t addr, uint32_t size,
-                                    uint32_t pitch, uint32_t flags);
-extern void nv20_fb_set_tile_region(struct drm_device *dev, int i);
-extern void nv20_fb_free_tile_region(struct drm_device *dev, int i);
-
-/* nv30_fb.c */
-extern int  nv30_fb_init(struct drm_device *);
-extern void nv30_fb_takedown(struct drm_device *);
-extern void nv30_fb_init_tile_region(struct drm_device *dev, int i,
-                                    uint32_t addr, uint32_t size,
-                                    uint32_t pitch, uint32_t flags);
-extern void nv30_fb_free_tile_region(struct drm_device *dev, int i);
-
-/* nv40_fb.c */
-extern int  nv40_fb_vram_init(struct drm_device *dev);
-extern int  nv40_fb_init(struct drm_device *);
-extern void nv40_fb_takedown(struct drm_device *);
-extern void nv40_fb_set_tile_region(struct drm_device *dev, int i);
-
-/* nv50_fb.c */
-extern int  nv50_fb_init(struct drm_device *);
-extern void nv50_fb_takedown(struct drm_device *);
-extern void nv50_fb_vm_trap(struct drm_device *, int display);
-
-/* nvc0_fb.c */
-extern int  nvc0_fb_init(struct drm_device *);
-extern void nvc0_fb_takedown(struct drm_device *);
-
 /* nv04_graph.c */
 extern int  nv04_graph_create(struct drm_device *);
 extern int  nv04_graph_object_new(struct nouveau_channel *, int, u32, u16);
@@ -1488,18 +1388,6 @@ nv44_graph_class(struct drm_device *dev)
        return !(0x0baf & (1 << (dev_priv->chipset & 0x0f)));
 }
 
-int  nv50_vram_init(struct drm_device *);
-void nv50_vram_fini(struct drm_device *);
-int  nv50_vram_new(struct drm_device *, u64 size, u32 align, u32 size_nc,
-                   u32 memtype, struct nouveau_mem **);
-void nv50_vram_del(struct drm_device *, struct nouveau_mem **);
-bool nv50_vram_flags_valid(struct drm_device *, u32 tile_flags);
-
-int  nvc0_vram_init(struct drm_device *);
-int  nvc0_vram_new(struct drm_device *, u64 size, u32 align, u32 ncmin,
-                   u32 memtype, struct nouveau_mem **);
-bool nvc0_vram_flags_valid(struct drm_device *, u32 tile_flags);
-
 /* memory type/access flags, do not match hardware values */
 #define NV_MEM_ACCESS_RO  1
 #define NV_MEM_ACCESS_WO  2
index f3fb649..d767567 100644 (file)
@@ -24,8 +24,8 @@
  *
  */
 
-#ifndef __NOUVEAU_FB_H__
-#define __NOUVEAU_FB_H__
+#ifndef __NOUVEAU_FRB_H__
+#define __NOUVEAU_FRB_H__
 
 struct nouveau_framebuffer {
        struct drm_framebuffer base;
index 9b07803..f3f0b4c 100644 (file)
@@ -475,9 +475,9 @@ int nouveau_fbcon_init(struct drm_device *dev)
 
        drm_fb_helper_single_add_all_connectors(&nfbdev->helper);
 
-       if (dev_priv->vram_size <= 32 * 1024 * 1024)
+       if (nvfb_vram_size(dev) <= 32 * 1024 * 1024)
                preferred_bpp = 8;
-       else if (dev_priv->vram_size <= 64 * 1024 * 1024)
+       else if (nvfb_vram_size(dev) <= 64 * 1024 * 1024)
                preferred_bpp = 16;
        else
                preferred_bpp = 32;
index c8bb9f2..96a34bc 100644 (file)
@@ -209,7 +209,7 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
 
        dev_priv->ttm.bdev.dev_mapping = dev->dev_mapping;
 
-       if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) {
+       if (!nvfb_flags_valid(dev, req->info.tile_flags)) {
                NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags);
                return -EINVAL;
        }
index 689d3e7..4aea1c4 100644 (file)
 
 static void
 nv10_mem_update_tile_region(struct drm_device *dev,
-                           struct nouveau_tile_reg *tile, uint32_t addr,
+                           struct nouveau_tile_reg *tilereg, uint32_t addr,
                            uint32_t size, uint32_t pitch, uint32_t flags)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-       int i = tile - dev_priv->tile.reg, j;
+       int i = tilereg - dev_priv->tile.reg, j;
+       struct nouveau_fb_tile *tile = nvfb_tile(dev, i);
        unsigned long save;
 
-       nouveau_fence_unref(&tile->fence);
+       nouveau_fence_unref(&tilereg->fence);
 
        if (tile->pitch)
-               pfb->free_tile_region(dev, i);
+               nvfb_tile_fini(dev, i);
 
        if (pitch)
-               pfb->init_tile_region(dev, i, addr, size, pitch, flags);
+               nvfb_tile_init(dev, i, addr, size, pitch, flags);
 
        spin_lock_irqsave(&dev_priv->context_switch_lock, save);
        nv_wr32(dev, NV03_PFIFO_CACHES, 0);
@@ -70,7 +70,7 @@ nv10_mem_update_tile_region(struct drm_device *dev,
 
        nouveau_wait_for_idle(dev);
 
-       pfb->set_tile_region(dev, i);
+       nvfb_tile_prog(dev, i);
        for (j = 0; j < NVOBJ_ENGINE_NR; j++) {
                if (dev_priv->eng[j] && dev_priv->eng[j]->set_tile_region)
                        dev_priv->eng[j]->set_tile_region(dev, i);
@@ -122,19 +122,17 @@ struct nouveau_tile_reg *
 nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size,
                    uint32_t pitch, uint32_t flags)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
        struct nouveau_tile_reg *tile, *found = NULL;
        int i;
 
-       for (i = 0; i < pfb->num_tiles; i++) {
+       for (i = 0; i < nvfb_tile_nr(dev); i++) {
                tile = nv10_mem_get_tile_region(dev, i);
 
                if (pitch && !found) {
                        found = tile;
                        continue;
 
-               } else if (tile && tile->pitch) {
+               } else if (tile && nvfb_tile(dev, i)->pitch) {
                        /* Kill an unused tile region. */
                        nv10_mem_update_tile_region(dev, tile, 0, 0, 0, 0);
                }
@@ -174,38 +172,11 @@ nouveau_mem_gart_fini(struct drm_device *dev)
        nouveau_sgdma_takedown(dev);
 }
 
-bool
-nouveau_mem_flags_valid(struct drm_device *dev, u32 tile_flags)
-{
-       if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK))
-               return true;
-
-       return false;
-}
-
-static const struct vram_types {
-       int value;
-       const char *name;
-} vram_type_map[] = {
-       { NV_MEM_TYPE_STOLEN , "stolen system memory" },
-       { NV_MEM_TYPE_SGRAM  , "SGRAM" },
-       { NV_MEM_TYPE_SDRAM  , "SDRAM" },
-       { NV_MEM_TYPE_DDR1   , "DDR1" },
-       { NV_MEM_TYPE_DDR2   , "DDR2" },
-       { NV_MEM_TYPE_DDR3   , "DDR3" },
-       { NV_MEM_TYPE_GDDR2  , "GDDR2" },
-       { NV_MEM_TYPE_GDDR3  , "GDDR3" },
-       { NV_MEM_TYPE_GDDR4  , "GDDR4" },
-       { NV_MEM_TYPE_GDDR5  , "GDDR5" },
-       { NV_MEM_TYPE_UNKNOWN, "unknown type" }
-};
-
 int
 nouveau_mem_vram_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
-       const struct vram_types *vram_type;
        int ret, dma_bits;
 
        dma_bits = 32;
@@ -243,27 +214,7 @@ nouveau_mem_vram_init(struct drm_device *dev)
                return ret;
        }
 
-       vram_type = vram_type_map;
-       while (vram_type->value != NV_MEM_TYPE_UNKNOWN) {
-               if (nouveau_vram_type) {
-                       if (!strcasecmp(nouveau_vram_type, vram_type->name))
-                               break;
-                       dev_priv->vram_type = vram_type->value;
-               } else {
-                       if (vram_type->value == dev_priv->vram_type)
-                               break;
-               }
-               vram_type++;
-       }
-
-       NV_INFO(dev, "Detected %dMiB VRAM (%s)\n",
-               (int)(dev_priv->vram_size >> 20), vram_type->name);
-       if (dev_priv->vram_sys_base) {
-               NV_INFO(dev, "Stolen system memory at: 0x%010llx\n",
-                       dev_priv->vram_sys_base);
-       }
-
-       dev_priv->fb_available_size = dev_priv->vram_size;
+       dev_priv->fb_available_size = nvfb_vram_size(dev);
        dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
        if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1))
                dev_priv->fb_mappable_pages = pci_resource_len(dev->pdev, 1);
@@ -364,7 +315,6 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
                     struct nouveau_pm_memtiming *boot,
                     struct nouveau_pm_memtiming *t)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct bit_entry P;
        uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3;
 
@@ -418,7 +368,7 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
                t->reg[7] = 0x4000202 | (e->tCL - 1) << 16;
 
                /* XXX: P.version == 1 only has DDR2 and GDDR3? */
-               if (dev_priv->vram_type == NV_MEM_TYPE_DDR2) {
+               if (nvfb_vram_type(dev) == NV_MEM_TYPE_DDR2) {
                        t->reg[5] |= (e->tCL + 3) << 8;
                        t->reg[6] |= (t->tCWL - 2) << 8;
                        t->reg[8] |= (e->tCL - 4);
@@ -711,7 +661,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
                break;
        }
 
-       switch (dev_priv->vram_type * !ret) {
+       switch (nvfb_vram_type(dev) * !ret) {
        case NV_MEM_TYPE_GDDR3:
                ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
                break;
@@ -738,7 +688,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
                else
                        dll_off = !!(ramcfg[2] & 0x40);
 
-               switch (dev_priv->vram_type) {
+               switch (nvfb_vram_type(dev)) {
                case NV_MEM_TYPE_GDDR3:
                        t->mr[1] &= ~0x00000040;
                        t->mr[1] |=  0x00000040 * dll_off;
@@ -804,7 +754,7 @@ nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t)
        t->odt = 0;
        t->drive_strength = 0;
 
-       switch (dev_priv->vram_type) {
+       switch (nvfb_vram_type(dev)) {
        case NV_MEM_TYPE_DDR3:
                t->odt |= (t->mr[1] & 0x200) >> 7;
        case NV_MEM_TYPE_DDR2:
@@ -831,7 +781,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
        u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] };
        u32 mr1_dlloff;
 
-       switch (dev_priv->vram_type) {
+       switch (nvfb_vram_type(dev_priv->dev)) {
        case NV_MEM_TYPE_DDR2:
                tDLLK = 2000;
                mr1_dlloff = 0x00000001;
@@ -852,7 +802,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
        }
 
        /* fetch current MRs */
-       switch (dev_priv->vram_type) {
+       switch (nvfb_vram_type(dev_priv->dev)) {
        case NV_MEM_TYPE_GDDR3:
        case NV_MEM_TYPE_DDR3:
                mr[2] = exec->mrg(exec, 2);
@@ -919,7 +869,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
                exec->mrs (exec, 0, info->mr[0] | 0x00000000);
                exec->wait(exec, tMRD);
                exec->wait(exec, tDLLK);
-               if (dev_priv->vram_type == NV_MEM_TYPE_GDDR3)
+               if (nvfb_vram_type(dev_priv->dev) == NV_MEM_TYPE_GDDR3)
                        exec->precharge(exec);
        }
 
@@ -982,11 +932,10 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man,
                         struct ttm_mem_reg *mem)
 {
        struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev);
-       struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
        struct drm_device *dev = dev_priv->dev;
 
        nouveau_mem_node_cleanup(mem->mm_node);
-       vram->put(dev, (struct nouveau_mem **)&mem->mm_node);
+       nvfb_vram_put(dev, (struct nouveau_mem **)&mem->mm_node);
 }
 
 static int
@@ -996,7 +945,6 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
                         struct ttm_mem_reg *mem)
 {
        struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev);
-       struct nouveau_vram_engine *vram = &dev_priv->engine.vram;
        struct drm_device *dev = dev_priv->dev;
        struct nouveau_bo *nvbo = nouveau_bo(bo);
        struct nouveau_mem *node;
@@ -1006,7 +954,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
        if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG)
                size_nc = 1 << nvbo->page_shift;
 
-       ret = vram->get(dev, mem->num_pages << PAGE_SHIFT,
+       ret = nvfb_vram_get(dev, mem->num_pages << PAGE_SHIFT,
                        mem->page_alignment << PAGE_SHIFT, size_nc,
                        (nvbo->tile_flags >> 8) & 0x3ff, &node);
        if (ret) {
index 3b11962..d8d9e5c 100644 (file)
@@ -61,8 +61,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.map             = nv04_instmem_map;
                engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
-               engine->fb.init                 = nv04_fb_init;
-               engine->fb.takedown             = nv04_fb_takedown;
                engine->display.early_init      = nv04_display_early_init;
                engine->display.late_takedown   = nv04_display_late_takedown;
                engine->display.create          = nv04_display_create;
@@ -72,9 +70,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.clocks_get           = nv04_pm_clocks_get;
                engine->pm.clocks_pre           = nv04_pm_clocks_pre;
                engine->pm.clocks_set           = nv04_pm_clocks_set;
-               engine->vram.init               = nv04_fb_vram_init;
-               engine->vram.takedown           = nouveau_stub_takedown;
-               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x10:
                engine->instmem.init            = nv04_instmem_init;
@@ -86,11 +81,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.map             = nv04_instmem_map;
                engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
-               engine->fb.init                 = nv10_fb_init;
-               engine->fb.takedown             = nv10_fb_takedown;
-               engine->fb.init_tile_region     = nv10_fb_init_tile_region;
-               engine->fb.set_tile_region      = nv10_fb_set_tile_region;
-               engine->fb.free_tile_region     = nv10_fb_free_tile_region;
                engine->display.early_init      = nv04_display_early_init;
                engine->display.late_takedown   = nv04_display_late_takedown;
                engine->display.create          = nv04_display_create;
@@ -100,13 +90,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.clocks_get           = nv04_pm_clocks_get;
                engine->pm.clocks_pre           = nv04_pm_clocks_pre;
                engine->pm.clocks_set           = nv04_pm_clocks_set;
-               if (dev_priv->chipset == 0x1a ||
-                   dev_priv->chipset == 0x1f)
-                       engine->vram.init       = nv1a_fb_vram_init;
-               else
-                       engine->vram.init       = nv10_fb_vram_init;
-               engine->vram.takedown           = nouveau_stub_takedown;
-               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x20:
                engine->instmem.init            = nv04_instmem_init;
@@ -118,11 +101,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.map             = nv04_instmem_map;
                engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
-               engine->fb.init                 = nv20_fb_init;
-               engine->fb.takedown             = nv20_fb_takedown;
-               engine->fb.init_tile_region     = nv20_fb_init_tile_region;
-               engine->fb.set_tile_region      = nv20_fb_set_tile_region;
-               engine->fb.free_tile_region     = nv20_fb_free_tile_region;
                engine->display.early_init      = nv04_display_early_init;
                engine->display.late_takedown   = nv04_display_late_takedown;
                engine->display.create          = nv04_display_create;
@@ -132,9 +110,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.clocks_get           = nv04_pm_clocks_get;
                engine->pm.clocks_pre           = nv04_pm_clocks_pre;
                engine->pm.clocks_set           = nv04_pm_clocks_set;
-               engine->vram.init               = nv20_fb_vram_init;
-               engine->vram.takedown           = nouveau_stub_takedown;
-               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x30:
                engine->instmem.init            = nv04_instmem_init;
@@ -146,11 +121,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.map             = nv04_instmem_map;
                engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
-               engine->fb.init                 = nv30_fb_init;
-               engine->fb.takedown             = nv30_fb_takedown;
-               engine->fb.init_tile_region     = nv30_fb_init_tile_region;
-               engine->fb.set_tile_region      = nv10_fb_set_tile_region;
-               engine->fb.free_tile_region     = nv30_fb_free_tile_region;
                engine->display.early_init      = nv04_display_early_init;
                engine->display.late_takedown   = nv04_display_late_takedown;
                engine->display.create          = nv04_display_create;
@@ -162,9 +132,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.clocks_set           = nv04_pm_clocks_set;
                engine->pm.voltage_get          = nouveau_voltage_gpio_get;
                engine->pm.voltage_set          = nouveau_voltage_gpio_set;
-               engine->vram.init               = nv20_fb_vram_init;
-               engine->vram.takedown           = nouveau_stub_takedown;
-               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x40:
        case 0x60:
@@ -177,11 +144,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.map             = nv04_instmem_map;
                engine->instmem.unmap           = nv04_instmem_unmap;
                engine->instmem.flush           = nv04_instmem_flush;
-               engine->fb.init                 = nv40_fb_init;
-               engine->fb.takedown             = nv40_fb_takedown;
-               engine->fb.init_tile_region     = nv30_fb_init_tile_region;
-               engine->fb.set_tile_region      = nv40_fb_set_tile_region;
-               engine->fb.free_tile_region     = nv30_fb_free_tile_region;
                engine->display.early_init      = nv04_display_early_init;
                engine->display.late_takedown   = nv04_display_late_takedown;
                engine->display.create          = nv04_display_create;
@@ -196,9 +158,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.temp_get             = nv40_temp_get;
                engine->pm.pwm_get              = nv40_pm_pwm_get;
                engine->pm.pwm_set              = nv40_pm_pwm_set;
-               engine->vram.init               = nv40_fb_vram_init;
-               engine->vram.takedown           = nouveau_stub_takedown;
-               engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
        case 0x50:
        case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -216,8 +175,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                        engine->instmem.flush   = nv50_instmem_flush;
                else
                        engine->instmem.flush   = nv84_instmem_flush;
-               engine->fb.init                 = nv50_fb_init;
-               engine->fb.takedown             = nv50_fb_takedown;
                engine->display.early_init      = nv50_display_early_init;
                engine->display.late_takedown   = nv50_display_late_takedown;
                engine->display.create          = nv50_display_create;
@@ -253,11 +210,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                        engine->pm.temp_get     = nv40_temp_get;
                engine->pm.pwm_get              = nv50_pm_pwm_get;
                engine->pm.pwm_set              = nv50_pm_pwm_set;
-               engine->vram.init               = nv50_vram_init;
-               engine->vram.takedown           = nv50_vram_fini;
-               engine->vram.get                = nv50_vram_new;
-               engine->vram.put                = nv50_vram_del;
-               engine->vram.flags_valid        = nv50_vram_flags_valid;
                break;
        case 0xc0:
                engine->instmem.init            = nvc0_instmem_init;
@@ -269,19 +221,12 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.map             = nv50_instmem_map;
                engine->instmem.unmap           = nv50_instmem_unmap;
                engine->instmem.flush           = nv84_instmem_flush;
-               engine->fb.init                 = nvc0_fb_init;
-               engine->fb.takedown             = nvc0_fb_takedown;
                engine->display.early_init      = nv50_display_early_init;
                engine->display.late_takedown   = nv50_display_late_takedown;
                engine->display.create          = nv50_display_create;
                engine->display.destroy         = nv50_display_destroy;
                engine->display.init            = nv50_display_init;
                engine->display.fini            = nv50_display_fini;
-               engine->vram.init               = nvc0_vram_init;
-               engine->vram.takedown           = nv50_vram_fini;
-               engine->vram.get                = nvc0_vram_new;
-               engine->vram.put                = nv50_vram_del;
-               engine->vram.flags_valid        = nvc0_vram_flags_valid;
                engine->pm.temp_get             = nv84_temp_get;
                engine->pm.clocks_get           = nvc0_pm_clocks_get;
                engine->pm.clocks_pre           = nvc0_pm_clocks_pre;
@@ -301,19 +246,12 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.map             = nv50_instmem_map;
                engine->instmem.unmap           = nv50_instmem_unmap;
                engine->instmem.flush           = nv84_instmem_flush;
-               engine->fb.init                 = nvc0_fb_init;
-               engine->fb.takedown             = nvc0_fb_takedown;
                engine->display.early_init      = nouveau_stub_init;
                engine->display.late_takedown   = nouveau_stub_takedown;
                engine->display.create          = nvd0_display_create;
                engine->display.destroy         = nvd0_display_destroy;
                engine->display.init            = nvd0_display_init;
                engine->display.fini            = nvd0_display_fini;
-               engine->vram.init               = nvc0_vram_init;
-               engine->vram.takedown           = nv50_vram_fini;
-               engine->vram.get                = nvc0_vram_new;
-               engine->vram.put                = nv50_vram_del;
-               engine->vram.flags_valid        = nvc0_vram_flags_valid;
                engine->pm.temp_get             = nv84_temp_get;
                engine->pm.clocks_get           = nvc0_pm_clocks_get;
                engine->pm.clocks_pre           = nvc0_pm_clocks_pre;
@@ -331,19 +269,12 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->instmem.map             = nv50_instmem_map;
                engine->instmem.unmap           = nv50_instmem_unmap;
                engine->instmem.flush           = nv84_instmem_flush;
-               engine->fb.init                 = nvc0_fb_init;
-               engine->fb.takedown             = nvc0_fb_takedown;
                engine->display.early_init      = nouveau_stub_init;
                engine->display.late_takedown   = nouveau_stub_takedown;
                engine->display.create          = nvd0_display_create;
                engine->display.destroy         = nvd0_display_destroy;
                engine->display.init            = nvd0_display_init;
                engine->display.fini            = nvd0_display_fini;
-               engine->vram.init               = nvc0_vram_init;
-               engine->vram.takedown           = nv50_vram_fini;
-               engine->vram.get                = nvc0_vram_new;
-               engine->vram.put                = nv50_vram_del;
-               engine->vram.flags_valid        = nvc0_vram_flags_valid;
                break;
        default:
                NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
@@ -488,18 +419,9 @@ nouveau_card_init(struct drm_device *dev)
                nv_mask(dev, 0x00088080, 0x00000800, 0x00000000);
        }
 
-       /* PFB */
-       ret = engine->fb.init(dev);
-       if (ret)
-               goto out_bios;
-
-       ret = engine->vram.init(dev);
-       if (ret)
-               goto out_fb;
-
        ret = nouveau_gpuobj_init(dev);
        if (ret)
-               goto out_vram;
+               goto out_bios;
 
        ret = engine->instmem.init(dev);
        if (ret)
@@ -734,10 +656,6 @@ out_instmem:
        engine->instmem.takedown(dev);
 out_gpuobj:
        nouveau_gpuobj_takedown(dev);
-out_vram:
-       engine->vram.takedown(dev);
-out_fb:
-       engine->fb.takedown(dev);
 out_bios:
        nouveau_bios_takedown(dev);
 out_display_early:
@@ -788,9 +706,6 @@ static void nouveau_card_takedown(struct drm_device *dev)
        engine->instmem.takedown(dev);
        nouveau_gpuobj_takedown(dev);
 
-       engine->vram.takedown(dev);
-       engine->fb.takedown(dev);
-
        nouveau_bios_takedown(dev);
        engine->display.late_takedown(dev);
 
index e51b515..6bff634 100644 (file)
  */
 
 #include <linux/ratelimit.h>
-
 #include "nouveau_util.h"
 
-static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
-
-void
-nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value)
-{
-       while (bf->name) {
-               if (value & bf->mask) {
-                       printk(" %s", bf->name);
-                       value &= ~bf->mask;
-               }
-
-               bf++;
-       }
-
-       if (value)
-               printk(" (unknown bits 0x%08x)", value);
-}
+#include <core/enum.h>
 
-const struct nouveau_enum *
-nouveau_enum_find(const struct nouveau_enum *en, u32 value)
-{
-       while (en->name) {
-               if (en->value == value)
-                       return en;
-               en++;
-       }
-
-       return NULL;
-}
-
-void
-nouveau_enum_print(const struct nouveau_enum *en, u32 value)
-{
-       en = nouveau_enum_find(en, value);
-       if (en) {
-               printk("%s", en->name);
-               return;
-       }
-
-       printk("(unknown enum 0x%08x)", value);
-}
+static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20);
 
 int
 nouveau_ratelimit(void)
index b97719f..1142937 100644 (file)
 #ifndef __NOUVEAU_UTIL_H__
 #define __NOUVEAU_UTIL_H__
 
-struct nouveau_bitfield {
-       u32 mask;
-       const char *name;
-};
-
-struct nouveau_enum {
-       u32 value;
-       const char *name;
-       void *data;
-};
-
-void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value);
-void nouveau_enum_print(const struct nouveau_enum *, u32 value);
-const struct nouveau_enum *
-nouveau_enum_find(const struct nouveau_enum *, u32 value);
+#include <core/enum.h>
 
 int nouveau_ratelimit(void);
 
index 5731cb3..7a14242 100644 (file)
@@ -300,24 +300,24 @@ nv50_evo_create(struct drm_device *dev)
 
        /* create some default objects for the scanout memtypes we support */
        ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM, 0x0000,
-                                 0, dev_priv->vram_size, NULL);
+                                 0, nvfb_vram_size(dev), NULL);
        if (ret)
                goto err;
 
        ret = nv50_evo_dmaobj_new(disp->master, NvEvoVRAM_LP, 0x80000000,
-                                 0, dev_priv->vram_size, NULL);
+                                 0, nvfb_vram_size(dev), NULL);
        if (ret)
                goto err;
 
        ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB32, 0x80000000 |
                                  (dev_priv->chipset < 0xc0 ? 0x7a00 : 0xfe00),
-                                 0, dev_priv->vram_size, NULL);
+                                 0, nvfb_vram_size(dev), NULL);
        if (ret)
                goto err;
 
        ret = nv50_evo_dmaobj_new(disp->master, NvEvoFB16, 0x80000000 |
                                  (dev_priv->chipset < 0xc0 ? 0x7000 : 0xfe00),
-                                 0, dev_priv->vram_size, NULL);
+                                 0, nvfb_vram_size(dev), NULL);
        if (ret)
                goto err;
 
@@ -352,21 +352,21 @@ nv50_evo_create(struct drm_device *dev)
                        goto err;
 
                ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000,
-                                         0, dev_priv->vram_size, NULL);
+                                         0, nvfb_vram_size(dev), NULL);
                if (ret)
                        goto err;
 
                ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 |
                                          (dev_priv->chipset < 0xc0 ?
                                          0x7a00 : 0xfe00),
-                                         0, dev_priv->vram_size, NULL);
+                                         0, nvfb_vram_size(dev), NULL);
                if (ret)
                        goto err;
 
                ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 |
                                          (dev_priv->chipset < 0xc0 ?
                                          0x7000 : 0xfe00),
-                                         0, dev_priv->vram_size, NULL);
+                                         0, nvfb_vram_size(dev), NULL);
                if (ret)
                        goto err;
 
index 378ca8c..142cd4e 100644 (file)
@@ -471,17 +471,16 @@ mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
 static void
 mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
 {
-       struct drm_nouveau_private *dev_priv = exec->dev->dev_private;
        struct nv50_pm_state *info = exec->priv;
        struct hwsq_ucode *hwsq = &info->mclk_hwsq;
 
        if (mr <= 1) {
-               if (dev_priv->vram_rank_B)
+               if (nvfb_vram_rank_B(exec->dev))
                        hwsq_wr32(hwsq, 0x1002c8 + ((mr - 0) * 4), data);
                hwsq_wr32(hwsq, 0x1002c0 + ((mr - 0) * 4), data);
        } else
        if (mr <= 3) {
-               if (dev_priv->vram_rank_B)
+               if (nvfb_vram_rank_B(exec->dev))
                        hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data);
                hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data);
        }
index 847c616..2f7ee50 100644 (file)
@@ -361,15 +361,13 @@ mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
 static void
 mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
 {
-       struct drm_nouveau_private *dev_priv = exec->dev->dev_private;
-
        if (mr <= 1) {
-               if (dev_priv->vram_rank_B)
+               if (nvfb_vram_rank_B(exec->dev))
                        nv_wr32(exec->dev, 0x1002c8 + ((mr - 0) * 4), data);
                nv_wr32(exec->dev, 0x1002c0 + ((mr - 0) * 4), data);
        } else
        if (mr <= 3) {
-               if (dev_priv->vram_rank_B)
+               if (nvfb_vram_rank_B(exec->dev))
                        nv_wr32(exec->dev, 0x1002e8 + ((mr - 2) * 4), data);
                nv_wr32(exec->dev, 0x1002e0 + ((mr - 2) * 4), data);
        }
index 4a21a72..a14711c 100644 (file)
@@ -459,8 +459,7 @@ static u32
 mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
 {
        struct drm_device *dev = exec->dev;
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       if (dev_priv->vram_type != NV_MEM_TYPE_GDDR5) {
+       if (nvfb_vram_type(dev) != NV_MEM_TYPE_GDDR5) {
                if (mr <= 1)
                        return nv_rd32(dev, 0x10f300 + ((mr - 0) * 4));
                return nv_rd32(dev, 0x10f320 + ((mr - 2) * 4));
@@ -478,16 +477,15 @@ static void
 mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
 {
        struct drm_device *dev = exec->dev;
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       if (dev_priv->vram_type != NV_MEM_TYPE_GDDR5) {
+       if (nvfb_vram_type(dev) != NV_MEM_TYPE_GDDR5) {
                if (mr <= 1) {
                        nv_wr32(dev, 0x10f300 + ((mr - 0) * 4), data);
-                       if (dev_priv->vram_rank_B)
+                       if (nvfb_vram_rank_B(dev))
                                nv_wr32(dev, 0x10f308 + ((mr - 0) * 4), data);
                } else
                if (mr <= 3) {
                        nv_wr32(dev, 0x10f320 + ((mr - 2) * 4), data);
-                       if (dev_priv->vram_rank_B)
+                       if (nvfb_vram_rank_B(dev))
                                nv_wr32(dev, 0x10f328 + ((mr - 2) * 4), data);
                }
        } else {
index d26dd02..8d9fc00 100644 (file)
@@ -2077,7 +2077,7 @@ nvd0_display_create(struct drm_device *dev)
 
                nv_wo32(disp->mem, dmao + 0x20, 0x00000049);
                nv_wo32(disp->mem, dmao + 0x24, 0x00000000);
-               nv_wo32(disp->mem, dmao + 0x28, (dev_priv->vram_size - 1) >> 8);
+               nv_wo32(disp->mem, dmao + 0x28, (nvfb_vram_size(dev) - 1) >> 8);
                nv_wo32(disp->mem, dmao + 0x2c, 0x00000000);
                nv_wo32(disp->mem, dmao + 0x30, 0x00000000);
                nv_wo32(disp->mem, dmao + 0x34, 0x00000000);
@@ -2087,7 +2087,7 @@ nvd0_display_create(struct drm_device *dev)
 
                nv_wo32(disp->mem, dmao + 0x40, 0x00000009);
                nv_wo32(disp->mem, dmao + 0x44, 0x00000000);
-               nv_wo32(disp->mem, dmao + 0x48, (dev_priv->vram_size - 1) >> 8);
+               nv_wo32(disp->mem, dmao + 0x48, (nvfb_vram_size(dev) - 1) >> 8);
                nv_wo32(disp->mem, dmao + 0x4c, 0x00000000);
                nv_wo32(disp->mem, dmao + 0x50, 0x00000000);
                nv_wo32(disp->mem, dmao + 0x54, 0x00000000);
@@ -2097,7 +2097,7 @@ nvd0_display_create(struct drm_device *dev)
 
                nv_wo32(disp->mem, dmao + 0x60, 0x0fe00009);
                nv_wo32(disp->mem, dmao + 0x64, 0x00000000);
-               nv_wo32(disp->mem, dmao + 0x68, (dev_priv->vram_size - 1) >> 8);
+               nv_wo32(disp->mem, dmao + 0x68, (nvfb_vram_size(dev) - 1) >> 8);
                nv_wo32(disp->mem, dmao + 0x6c, 0x00000000);
                nv_wo32(disp->mem, dmao + 0x70, 0x00000000);
                nv_wo32(disp->mem, dmao + 0x74, 0x00000000);