nouveau: move card initialisation into the drm
authorBen Skeggs <skeggsb@gmail.com>
Mon, 26 Mar 2007 09:43:48 +0000 (19:43 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Mon, 26 Mar 2007 10:59:37 +0000 (20:59 +1000)
The PGRAPH init for the various cards will need cleaning up at some point,
a lot of the values written there are per-context state left over from the
all the hardcoding done in the ddx.

It's possible some cards get broken by this commit, let me know.
Tested on: NV5, NV18, NV28, NV35, NV40, NV4E

25 files changed:
linux-core/Makefile.kernel
linux-core/nv04_fb.c [new symlink]
linux-core/nv04_mc.c [new symlink]
linux-core/nv04_timer.c [new symlink]
linux-core/nv10_fb.c [new symlink]
linux-core/nv40_fb.c [new symlink]
linux-core/nv40_mc.c [new symlink]
shared-core/nouveau_drm.h
shared-core/nouveau_drv.h
shared-core/nouveau_fifo.c
shared-core/nouveau_irq.c
shared-core/nouveau_mem.c
shared-core/nouveau_reg.h
shared-core/nouveau_state.c
shared-core/nv04_fb.c [new file with mode: 0644]
shared-core/nv04_graph.c
shared-core/nv04_mc.c [new file with mode: 0644]
shared-core/nv04_timer.c [new file with mode: 0644]
shared-core/nv10_fb.c [new file with mode: 0644]
shared-core/nv10_graph.c
shared-core/nv20_graph.c
shared-core/nv30_graph.c
shared-core/nv40_fb.c [new file with mode: 0644]
shared-core/nv40_graph.c
shared-core/nv40_mc.c [new file with mode: 0644]

index 81a9433..6f5b021 100644 (file)
@@ -21,7 +21,11 @@ i810-objs   := i810_drv.o i810_dma.o
 i915-objs   := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \
                i915_buffer.o
 nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
-               nouveau_object.o nouveau_irq.o nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \
+               nouveau_object.o nouveau_irq.o \
+               nv04_timer.o \
+               nv04_mc.o nv40_mc.o \
+               nv04_fb.o nv10_fb.o nv40_fb.o \
+               nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \
                nv40_graph.o
 radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
 sis-objs    := sis_drv.o sis_mm.o
diff --git a/linux-core/nv04_fb.c b/linux-core/nv04_fb.c
new file mode 120000 (symlink)
index 0000000..867e200
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/nv04_fb.c
\ No newline at end of file
diff --git a/linux-core/nv04_mc.c b/linux-core/nv04_mc.c
new file mode 120000 (symlink)
index 0000000..32e9182
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/nv04_mc.c
\ No newline at end of file
diff --git a/linux-core/nv04_timer.c b/linux-core/nv04_timer.c
new file mode 120000 (symlink)
index 0000000..11108b2
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/nv04_timer.c
\ No newline at end of file
diff --git a/linux-core/nv10_fb.c b/linux-core/nv10_fb.c
new file mode 120000 (symlink)
index 0000000..f858c7c
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/nv10_fb.c
\ No newline at end of file
diff --git a/linux-core/nv40_fb.c b/linux-core/nv40_fb.c
new file mode 120000 (symlink)
index 0000000..4a816b1
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/nv40_fb.c
\ No newline at end of file
diff --git a/linux-core/nv40_mc.c b/linux-core/nv40_mc.c
new file mode 120000 (symlink)
index 0000000..fff2649
--- /dev/null
@@ -0,0 +1 @@
+../shared-core/nv40_mc.c
\ No newline at end of file
index c3a69a8..3ba7e96 100644 (file)
@@ -25,7 +25,7 @@
 #ifndef __NOUVEAU_DRM_H__
 #define __NOUVEAU_DRM_H__
 
-#define NOUVEAU_DRM_HEADER_PATCHLEVEL 5
+#define NOUVEAU_DRM_HEADER_PATCHLEVEL 6
 
 typedef struct drm_nouveau_fifo_alloc {
        int          channel;
@@ -142,7 +142,7 @@ drm_nouveau_sarea_t;
 
 #define DRM_NOUVEAU_FIFO_ALLOC      0x00
 #define DRM_NOUVEAU_OBJECT_INIT     0x01
-#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x02 // We don't want this eventually..
+#define DRM_NOUVEAU_DMA_OBJECT_INIT 0x02
 #define DRM_NOUVEAU_MEM_ALLOC       0x03
 #define DRM_NOUVEAU_MEM_FREE        0x04
 #define DRM_NOUVEAU_GETPARAM        0x05
index 265479f..debee8e 100644 (file)
@@ -34,7 +34,7 @@
 
 #define DRIVER_MAJOR           0
 #define DRIVER_MINOR           0
-#define DRIVER_PATCHLEVEL      5
+#define DRIVER_PATCHLEVEL      6
 
 #define NOUVEAU_FAMILY   0x0000FFFF
 #define NOUVEAU_FLAGS    0xFFFF0000
@@ -99,6 +99,33 @@ struct nouveau_config {
        } cmdbuf;
 };
 
+struct nouveau_engine_func {
+       struct {
+               int     (*Init)(drm_device_t *dev);
+               void    (*Takedown)(drm_device_t *dev);
+       } Mc;
+
+       struct {
+               int     (*Init)(drm_device_t *dev);
+               void    (*Takedown)(drm_device_t *dev);
+       } Timer;
+
+       struct {
+               int     (*Init)(drm_device_t *dev);
+               void    (*Takedown)(drm_device_t *dev);
+       } Fb;
+
+       struct {
+               int     (*Init)(drm_device_t *dev);
+               void    (*Takedown)(drm_device_t *dev);
+       } Graph;
+
+       struct {
+               int     (*Init)(drm_device_t *dev);
+               void    (*Takedown)(drm_device_t *dev);
+       } Fifo;
+};
+
 typedef struct drm_nouveau_private {
        /* the card type, takes NV_* as values */
        int card_type;
@@ -113,6 +140,8 @@ typedef struct drm_nouveau_private {
        int fifo_alloc_count;
        struct nouveau_fifo fifos[NV_MAX_FIFO_NUMBER];
 
+       struct nouveau_engine_func Engine;
+
        /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */
        uint32_t ramin_size;
        uint32_t ramht_offset;
@@ -154,6 +183,7 @@ extern int nouveau_unload(struct drm_device *dev);
 extern int nouveau_ioctl_getparam(DRM_IOCTL_ARGS);
 extern int nouveau_ioctl_setparam(DRM_IOCTL_ARGS);
 extern void nouveau_wait_for_idle(struct drm_device *dev);
+extern int nouveau_ioctl_card_init(DRM_IOCTL_ARGS);
 
 /* nouveau_mem.c */
 extern uint64_t          nouveau_mem_fb_amount(struct drm_device *dev);
@@ -164,8 +194,7 @@ extern struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment
 extern void              nouveau_mem_free(struct drm_device* dev, struct mem_block*);
 extern int               nouveau_mem_init(struct drm_device *dev);
 extern void              nouveau_mem_close(struct drm_device *dev);
-extern int               nouveau_instmem_init(struct drm_device *dev,
-                                             uint32_t offset);
+extern int               nouveau_instmem_init(struct drm_device *dev);
 extern struct mem_block* nouveau_instmem_alloc(struct drm_device *dev,
                                               uint32_t size, uint32_t align);
 extern void              nouveau_instmem_free(struct drm_device *dev,
@@ -179,6 +208,7 @@ extern void              nouveau_instmem_w32(drm_nouveau_private_t *dev_priv,
 /* nouveau_fifo.c */
 extern int  nouveau_fifo_init(drm_device_t *dev);
 extern int  nouveau_fifo_number(drm_device_t *dev);
+extern int  nouveau_fifo_ctx_size(drm_device_t *dev);
 extern void nouveau_fifo_cleanup(drm_device_t *dev, DRMFILE filp);
 extern int  nouveau_fifo_owner(drm_device_t *dev, DRMFILE filp, int channel);
 extern void nouveau_fifo_free(drm_device_t *dev, int channel);
@@ -202,31 +232,60 @@ extern void        nouveau_irq_preinstall(drm_device_t*);
 extern void        nouveau_irq_postinstall(drm_device_t*);
 extern void        nouveau_irq_uninstall(drm_device_t*);
 
+/* nv04_fb.c */
+extern int  nv04_fb_init(drm_device_t *dev);
+extern void nv04_fb_takedown(drm_device_t *dev);
+
+/* nv10_fb.c */
+extern int  nv10_fb_init(drm_device_t *dev);
+extern void nv10_fb_takedown(drm_device_t *dev);
+
+/* nv40_fb.c */
+extern int  nv40_fb_init(drm_device_t *dev);
+extern void nv40_fb_takedown(drm_device_t *dev);
+
 /* nv04_graph.c */
 extern void nouveau_nv04_context_switch(drm_device_t *dev);
 extern int nv04_graph_init(drm_device_t *dev);
+extern void nv04_graph_takedown(drm_device_t *dev);
 extern int nv04_graph_context_create(drm_device_t *dev, int channel);
 
 /* nv10_graph.c */
 extern void nouveau_nv10_context_switch(drm_device_t *dev);
 extern int nv10_graph_init(drm_device_t *dev);
+extern void nv10_graph_takedown(drm_device_t *dev);
 extern int nv10_graph_context_create(drm_device_t *dev, int channel);
 
 /* nv20_graph.c */
 extern void nouveau_nv20_context_switch(drm_device_t *dev);
 extern int nv20_graph_init(drm_device_t *dev);
+extern void nv20_graph_takedown(drm_device_t *dev);
 extern int nv20_graph_context_create(drm_device_t *dev, int channel);
 
 /* nv30_graph.c */
 extern int nv30_graph_init(drm_device_t *dev);
+extern void nv30_graph_takedown(drm_device_t *dev);
 extern int nv30_graph_context_create(drm_device_t *dev, int channel);
 
 /* nv40_graph.c */
 extern int  nv40_graph_init(drm_device_t *dev);
+extern void nv40_graph_takedown(drm_device_t *dev);
 extern int  nv40_graph_context_create(drm_device_t *dev, int channel);
 extern void nv40_graph_context_save_current(drm_device_t *dev);
 extern void nv40_graph_context_restore(drm_device_t *dev, int channel);
 
+/* nv04_mc.c */
+extern int  nv04_mc_init(drm_device_t *dev);
+extern void nv04_mc_takedown(drm_device_t *dev);
+
+/* nv40_mc.c */
+extern int  nv40_mc_init(drm_device_t *dev);
+extern void nv40_mc_takedown(drm_device_t *dev);
+
+/* nv04_timer.c */
+extern int  nv04_timer_init(drm_device_t *dev);
+extern void nv04_timer_takedown(drm_device_t *dev);
+
 extern long nouveau_compat_ioctl(struct file *filp, unsigned int cmd,
                                unsigned long arg);
 
index 2733c1b..92166ee 100644 (file)
@@ -45,7 +45,7 @@ int nouveau_fifo_number(drm_device_t* dev)
 }
 
 /* returns the size of fifo context */
-static int nouveau_fifo_ctx_size(drm_device_t* dev)
+int nouveau_fifo_ctx_size(drm_device_t* dev)
 {
        drm_nouveau_private_t *dev_priv=dev->dev_private;
 
@@ -69,78 +69,36 @@ static int nouveau_fifo_ctx_size(drm_device_t* dev)
 static int nouveau_fifo_instmem_configure(drm_device_t *dev)
 {
        drm_nouveau_private_t *dev_priv = dev->dev_private;
-       int i;
-
-       /* Clear start of RAMIN, enough to cover RAMFC/HT/RO basically */
-       for (i=0x00710000; i<0x00730000; i++)
-               NV_WRITE(i, 0x00000000);
 
-       /* FIFO hash table (RAMHT)
-        *   use 4k hash table at RAMIN+0x10000
-        *   TODO: extend the hash table
-        */
-       dev_priv->ramht_offset = 0x10000;
-       dev_priv->ramht_bits   = 9;
-       dev_priv->ramht_size   = (1 << dev_priv->ramht_bits);
        NV_WRITE(NV03_PFIFO_RAMHT,
                        (0x03 << 24) /* search 128 */ | 
                        ((dev_priv->ramht_bits - 9) << 16) |
                        (dev_priv->ramht_offset >> 8)
                        );
-       DRM_DEBUG("RAMHT offset=0x%x, size=%d\n",
-                       dev_priv->ramht_offset,
-                       dev_priv->ramht_size);
 
-       /* FIFO runout table (RAMRO) - 512k at 0x11200 */
-       dev_priv->ramro_offset = 0x11200;
-       dev_priv->ramro_size   = 512;
        NV_WRITE(NV03_PFIFO_RAMRO, dev_priv->ramro_offset>>8);
-       DRM_DEBUG("RAMRO offset=0x%x, size=%d\n",
-                       dev_priv->ramro_offset,
-                       dev_priv->ramro_size);
-
-       /* FIFO context table (RAMFC)
-        *   NV40  : Not sure exactly how to position RAMFC on some cards,
-        *           0x30002 seems to position it at RAMIN+0x20000 on these
-        *           cards.  RAMFC is 4kb (32 fifos, 128byte entries).
-        *   Others: Position RAMFC at RAMIN+0x11400
-        */
+
        switch(dev_priv->card_type)
        {
                case NV_50:
                case NV_40:
-                       dev_priv->ramfc_offset = 0x20000;
-                       dev_priv->ramfc_size   = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev);
                        NV_WRITE(NV40_PFIFO_RAMFC, 0x30002);
                        break;
                case NV_44:
-                       dev_priv->ramfc_offset = 0x20000;
-                       dev_priv->ramfc_size   = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev);
                        NV_WRITE(NV40_PFIFO_RAMFC, ((nouveau_mem_fb_amount(dev)-512*1024+dev_priv->ramfc_offset)>>16) |
                                        (2 << 16));
                        break;
                case NV_30:
                case NV_20:
                case NV_10:
-                       dev_priv->ramfc_offset = 0x11400;
-                       dev_priv->ramfc_size   = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev);
                        NV_WRITE(NV03_PFIFO_RAMFC, (dev_priv->ramfc_offset>>8) |
                                        (1 << 16) /* 64 Bytes entry*/);
                        break;
                case NV_04:
                case NV_03:
-                       dev_priv->ramfc_offset = 0x11400;
-                       dev_priv->ramfc_size   = nouveau_fifo_number(dev) * nouveau_fifo_ctx_size(dev);
                        NV_WRITE(NV03_PFIFO_RAMFC, dev_priv->ramfc_offset>>8);
                        break;
        }
-       DRM_DEBUG("RAMFC offset=0x%x, size=%d\n",
-                       dev_priv->ramfc_offset,
-                       dev_priv->ramfc_size);
-
-       if (nouveau_instmem_init(dev, dev_priv->ramfc_offset +
-                                     dev_priv->ramfc_size))
-               return 1;
 
        return 0;
 }
@@ -150,6 +108,11 @@ int nouveau_fifo_init(drm_device_t *dev)
        drm_nouveau_private_t *dev_priv = dev->dev_private;
        int ret;
 
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
+                       ~NV_PMC_ENABLE_PFIFO);
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
+                        NV_PMC_ENABLE_PFIFO);
+
        NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
 
        ret = nouveau_fifo_instmem_configure(dev);
@@ -736,7 +699,7 @@ static int nouveau_ioctl_fifo_alloc(DRM_IOCTL_ARGS)
  ***********************************/
 
 drm_ioctl_desc_t nouveau_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, DRM_AUTH},
+       [DRM_IOCTL_NR(DRM_NOUVEAU_FIFO_ALLOC)] = {nouveau_ioctl_fifo_alloc, DRM_AUTH},  
        [DRM_IOCTL_NR(DRM_NOUVEAU_OBJECT_INIT)] = {nouveau_ioctl_object_init, DRM_AUTH},
        [DRM_IOCTL_NR(DRM_NOUVEAU_DMA_OBJECT_INIT)] = {nouveau_ioctl_dma_object_init, DRM_AUTH},
        [DRM_IOCTL_NR(DRM_NOUVEAU_MEM_ALLOC)] = {nouveau_ioctl_mem_alloc, DRM_AUTH},
index 32b3307..b7c1d53 100644 (file)
@@ -42,6 +42,15 @@ void nouveau_irq_preinstall(drm_device_t *dev)
 
        DRM_DEBUG("IRQ: preinst\n");
 
+       if (!dev_priv) {
+               DRM_ERROR("AIII, no dev_priv\n");
+               return;
+       }
+       if (!dev_priv->mmio) {
+               DRM_ERROR("AIII, no dev_priv->mmio\n");
+               return;
+       }
+
        /* Disable/Clear PFIFO interrupts */
        NV_WRITE(NV03_PFIFO_INTR_EN_0, 0);
        NV_WRITE(NV03_PFIFO_INTR_0, 0xFFFFFFFF);
@@ -66,6 +75,15 @@ void nouveau_irq_postinstall(drm_device_t *dev)
 {
        drm_nouveau_private_t *dev_priv = dev->dev_private;
 
+       if (!dev_priv) {
+               DRM_ERROR("AIII, no dev_priv\n");
+               return;
+       }
+       if (!dev_priv->mmio) {
+               DRM_ERROR("AIII, no dev_priv->mmio\n");
+               return;
+       }
+
        DRM_DEBUG("IRQ: postinst\n");
 
        /* Enable PFIFO error reporting */
@@ -113,6 +131,15 @@ void nouveau_irq_uninstall(drm_device_t *dev)
 {
        drm_nouveau_private_t *dev_priv = dev->dev_private;
 
+       if (!dev_priv) {
+               DRM_ERROR("AIII, no dev_priv\n");
+               return;
+       }
+       if (!dev_priv->mmio) {
+               DRM_ERROR("AIII, no dev_priv->mmio\n");
+               return;
+       }
+
        DRM_DEBUG("IRQ: uninst\n");
 
        /* Disable PFIFO interrupts */
index f62d861..541f154 100644 (file)
@@ -35,8 +35,6 @@
 #include "drm_sarea.h"
 #include "nouveau_drv.h"
 
-//static int meminit_ok=0;
-
 static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64_t size,
                DRMFILE filp)
 {
@@ -340,6 +338,11 @@ int nouveau_mem_init(struct drm_device *dev)
        }
 no_agp:
 
+       /* setup a mtrr over the FB */
+       dev_priv->fb_mtrr = drm_mtrr_add(drm_get_resource_start(dev, 1),
+                                        nouveau_mem_fb_amount(dev),
+                                        DRM_MTRR_WC);
+
        /* Init FB */
        dev_priv->fb_phys=drm_get_resource_start(dev,1);
        fb_size = nouveau_mem_fb_amount(dev);
@@ -372,14 +375,6 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, uint6
        int type;
        drm_nouveau_private_t *dev_priv = dev->dev_private;
 
-       /*
-        * Init memory if needed
-        */
-       if (dev_priv->fb_phys == 0)
-       {
-               nouveau_mem_init(dev);
-       }
-
        /* 
         * Make things easier on ourselves: all allocations are page-aligned. 
         * We need that to map allocated regions into the user space
@@ -447,44 +442,113 @@ alloc_ok:
 
 void nouveau_mem_free(struct drm_device* dev, struct mem_block* block)
 {
-        drm_nouveau_private_t *dev_priv = dev->dev_private;
-
        DRM_INFO("freeing 0x%llx\n", block->start);
-       if (dev_priv->fb_phys == 0)
-       {
-               DRM_ERROR("%s called without init\n", __FUNCTION__);
-               return;
-       }
        if (block->flags&NOUVEAU_MEM_MAPPED)
                drm_rmmap(dev, block->map);
        free_block(block);
 }
 
-int nouveau_instmem_init(struct drm_device *dev, uint32_t offset)
+static void
+nouveau_instmem_determine_amount(struct drm_device *dev)
 {
        drm_nouveau_private_t *dev_priv = dev->dev_private;
-       int ret;
+       int i;
 
-       if (dev_priv->card_type >= NV_40)
+       /* Figure out how much instance memory we need */
+       switch (dev_priv->card_type) {
+       case NV_40:
                /* We'll want more instance memory than this on some NV4x cards.
                 * There's a 16MB aperture to play with that maps onto the end
                 * of vram.  For now, only reserve a small piece until we know
                 * more about what each chipset requires.
                 */
                dev_priv->ramin_size = (1*1024* 1024);
-       else {
+               break;
+       default:
                /*XXX: what *are* the limits on <NV40 cards?, and does RAMIN
                 *     exist in vram on those cards as well?
                 */
                dev_priv->ramin_size = (512*1024);
+               break;
        }
        DRM_DEBUG("RAMIN size: %dKiB\n", dev_priv->ramin_size>>10);
 
+       /* Clear all of it, except the BIOS image that's in the first 64KiB */
+       if (dev_priv->ramin) {
+               for (i=(64*1024); i<dev_priv->ramin_size; i+=4)
+                       DRM_WRITE32(dev_priv->ramin, i, 0x00000000);
+       } else {
+               for (i=(64*1024); i<dev_priv->ramin_size; i+=4)
+                       DRM_WRITE32(dev_priv->mmio, NV_RAMIN + i, 0x00000000);
+       }
+}
+
+static void
+nouveau_instmem_configure_fixed_tables(struct drm_device *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+
+       /* FIFO hash table (RAMHT)
+        *   use 4k hash table at RAMIN+0x10000
+        *   TODO: extend the hash table
+        */
+       dev_priv->ramht_offset = 0x10000;
+       dev_priv->ramht_bits   = 9;
+       dev_priv->ramht_size   = (1 << dev_priv->ramht_bits);
+       DRM_DEBUG("RAMHT offset=0x%x, size=%d\n", dev_priv->ramht_offset,
+                                                 dev_priv->ramht_size);
+
+       /* FIFO runout table (RAMRO) - 512k at 0x11200 */
+       dev_priv->ramro_offset = 0x11200;
+       dev_priv->ramro_size   = 512;
+       DRM_DEBUG("RAMRO offset=0x%x, size=%d\n", dev_priv->ramro_offset,
+                                                 dev_priv->ramro_size);
+
+       /* FIFO context table (RAMFC)
+        *   NV40  : Not sure exactly how to position RAMFC on some cards,
+        *           0x30002 seems to position it at RAMIN+0x20000 on these
+        *           cards.  RAMFC is 4kb (32 fifos, 128byte entries).
+        *   Others: Position RAMFC at RAMIN+0x11400
+        */
+       switch(dev_priv->card_type)
+       {
+               case NV_50:
+               case NV_40:
+               case NV_44:
+                       dev_priv->ramfc_offset = 0x20000;
+                       dev_priv->ramfc_size   = nouveau_fifo_number(dev) *
+                               nouveau_fifo_ctx_size(dev);
+                       break;
+               case NV_30:
+               case NV_20:
+               case NV_10:
+               case NV_04:
+               case NV_03:
+               default:
+                       dev_priv->ramfc_offset = 0x11400;
+                       dev_priv->ramfc_size   = nouveau_fifo_number(dev) *
+                               nouveau_fifo_ctx_size(dev);
+                       break;
+       }
+       DRM_DEBUG("RAMFC offset=0x%x, size=%d\n", dev_priv->ramfc_offset,
+                                                 dev_priv->ramfc_size);
+}
+
+int nouveau_instmem_init(struct drm_device *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+       uint32_t offset;
+       int ret = 0;
+
+       nouveau_instmem_determine_amount(dev);
+       nouveau_instmem_configure_fixed_tables(dev);
+
        /* Create a heap to manage RAMIN allocations, we don't allocate
         * the space that was reserved for RAMHT/FC/RO.
         */
-       ret = init_heap(&dev_priv->ramin_heap, offset,
-                       dev_priv->ramin_size - offset);
+       offset = dev_priv->ramfc_offset + dev_priv->ramfc_size;
+       ret = init_heap(&dev_priv->ramin_heap,
+                        offset, dev_priv->ramin_size - offset);
        if (ret) {
                dev_priv->ramin_heap = NULL;
                DRM_ERROR("Failed to init RAMIN heap\n");
@@ -590,11 +654,6 @@ int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS)
        drm_nouveau_mem_free_t memfree;
        struct mem_block *block;
 
-       if (!dev_priv) {
-               DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
-               return DRM_ERR(EINVAL);
-       }
-
        DRM_COPY_FROM_USER_IOCTL(memfree, (drm_nouveau_mem_free_t __user *) data,
                                 sizeof(memfree));
 
index e7ab380..3360fec 100644 (file)
 #    define NV_PMC_INTR_0_CRTCn_PENDING                       (3<<24)
 #define NV03_PMC_INTR_EN_0                                 0x00000140
 #    define NV_PMC_INTR_EN_0_MASTER_ENABLE                    (1<< 0)
+#define NV03_PMC_ENABLE                                    0x00000200
+#    define NV_PMC_ENABLE_PFIFO                               (1<< 8)
+#    define NV_PMC_ENABLE_PGRAPH                              (1<<12)
+#define NV40_PMC_1700                                      0x00001700
+#define NV40_PMC_1704                                      0x00001704
+#define NV40_PMC_1708                                      0x00001708
+#define NV40_PMC_170C                                      0x0000170C
 
+#define NV04_PTIMER_INTR_0                                 0x00009100
+#define NV04_PTIMER_INTR_EN_0                              0x00009140
+#define NV04_PTIMER_NUMERATOR                              0x00009200
+#define NV04_PTIMER_DENOMINATOR                            0x00009210
+#define NV04_PTIMER_TIME_0                                 0x00009400
+#define NV04_PTIMER_TIME_1                                 0x00009410
+#define NV04_PTIMER_ALARM_0                                0x00009420
+
+#define NV04_PFB_CFG0                                      0x00100200
+#define NV04_PFB_CFG1                                      0x00100204
+#define NV40_PFB_020C                                      0x0010020C
+#define NV10_PFB_TILE(i)                                   (0x00100240 + (i*16))
+#define NV10_PFB_TILE__SIZE                                8
+#define NV10_PFB_TLIMIT(i)                                 (0x00100244 + (i*16))
+#define NV10_PFB_TSIZE(i)                                  (0x00100248 + (i*16))
+#define NV10_PFB_TSTATUS(i)                                (0x0010024C + (i*16))
+#define NV10_PFB_CLOSE_PAGE2                               0x0010033C
+#define NV40_PFB_TILE(i)                                   (0x00100600 + (i*16))
+#define NV40_PFB_TILE__SIZE_0                              12
+#define NV40_PFB_TILE__SIZE_1                              15
+#define NV40_PFB_TLIMIT(i)                                 (0x00100604 + (i*16))
+#define NV40_PFB_TSIZE(i)                                  (0x00100608 + (i*16))
+#define NV40_PFB_TSTATUS(i)                                (0x0010060C + (i*16))
+
+#define NV04_PGRAPH_DEBUG_0                                0x00400080
+#define NV04_PGRAPH_DEBUG_1                                0x00400084
+#define NV04_PGRAPH_DEBUG_2                                0x00400088
+#define NV04_PGRAPH_DEBUG_3                                0x0040008c
 #define NV10_PGRAPH_DEBUG_4                                0x00400090
 #define NV03_PGRAPH_INTR                                   0x00400100
 #define NV03_PGRAPH_INTR_EN                                0x00400140
 #define NV04_PGRAPH_ROP3                                   0x00400604
 #define NV04_PGRAPH_BETA_AND                               0x00400608
 #define NV04_PGRAPH_BETA_PREMULT                           0x0040060C
+#define NV04_PGRAPH_LIMIT_VIOL_PIX                         0x00400610
 #define NV04_PGRAPH_FORMATS                                0x00400618
+#define NV10_PGRAPH_DEBUG_2                                0x00400620
 #define NV04_PGRAPH_BOFFSET0                               0x00400640
 #define NV04_PGRAPH_BOFFSET1                               0x00400644
 #define NV04_PGRAPH_BOFFSET2                               0x00400648
 #define NV04_PGRAPH_BLEND                                  0x00400824
 #define NV04_PGRAPH_STORED_FMT                             0x00400830
 #define NV04_PGRAPH_PATT_COLORRAM                          0x00400900
+#define NV40_PGRAPH_TILE0(i)                               0x00400900
+#define NV40_PGRAPH_TLIMIT0(i)                             0x00400904
+#define NV40_PGRAPH_TSIZE0(i)                              0x00400908
+#define NV40_PGRAPH_TSTATUS0(i)                            0x0040090C
+#define NV10_PGRAPH_TILE(i)                                (0x00400B00 + (i*16))
+#define NV10_PGRAPH_TLIMIT(i)                              (0x00400B04 + (i*16))
+#define NV10_PGRAPH_TSIZE(i)                               (0x00400B08 + (i*16))
+#define NV10_PGRAPH_TSTATUS(i)                             (0x00400B0C + (i*16))
 #define NV04_PGRAPH_U_RAM                                  0x00400D00
+#define NV47_PGRAPH_TILE0(i)                               0x00400D00
+#define NV47_PGRAPH_TLIMIT0(i)                             0x00400D04
+#define NV47_PGRAPH_TSIZE0(i)                              0x00400D08
+#define NV47_PGRAPH_TSTATUS0(i)                            0x00400D0C
 #define NV04_PGRAPH_V_RAM                                  0x00400D40
 #define NV04_PGRAPH_W_RAM                                  0x00400D80
 #define NV10_PGRAPH_WINDOWCLIP_HORIZONTAL                  0x00400F00
 #define NV04_PGRAPH_DMA_B_OFFSET                           0x00401098
 #define NV04_PGRAPH_DMA_B_SIZE                             0x0040109C
 #define NV04_PGRAPH_DMA_B_Y_SIZE                           0x004010A0
+#define NV40_PGRAPH_TILE1(i)                               0x00406900
+#define NV40_PGRAPH_TLIMIT1(i)                             0x00406904
+#define NV40_PGRAPH_TSIZE1(i)                              0x00406908
+#define NV40_PGRAPH_TSTATUS1(i)                            0x0040690C
 
 
 /* It's a guess that this works on NV03. Confirmed on NV04, though */
index ed45c16..e7930b9 100644 (file)
 #include "drm.h"
 #include "drm_sarea.h"
 #include "nouveau_drv.h"
+#include "nouveau_drm.h"
 
-/* here a client dies, release the stuff that was allocated for its filp */
-void nouveau_preclose(drm_device_t * dev, DRMFILE filp)
+static int nouveau_init_card_mappings(drm_device_t *dev)
 {
        drm_nouveau_private_t *dev_priv = dev->dev_private;
-
-       nouveau_mem_release(filp,dev_priv->fb_heap);
-       nouveau_mem_release(filp,dev_priv->agp_heap);
-       nouveau_fifo_cleanup(dev, filp);
-}
-
-/* first module load, setup the mmio/fb mapping */
-int nouveau_firstopen(struct drm_device *dev)
-{
        int ret;
-       drm_nouveau_private_t *dev_priv = dev->dev_private;
 
        /* resource 0 is mmio regs */
        /* resource 1 is linear FB */
@@ -49,19 +39,16 @@ int nouveau_firstopen(struct drm_device *dev)
        /* resource 6 is bios */
 
        /* map the mmio regs */
-       ret = drm_addmap(dev, drm_get_resource_start(dev, 0), drm_get_resource_len(dev, 0), 
-                       _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
-       if (dev_priv->mmio)
-       {
-               DRM_INFO("regs mapped ok at 0x%lx\n",dev_priv->mmio->offset);
-       }
-       else
-       {
-               DRM_ERROR("Unable to initialize the mmio mapping. Please report your setup to " DRIVER_EMAIL "\n");
-               return 1; 
+       ret = drm_addmap(dev, drm_get_resource_start(dev, 0),
+                             drm_get_resource_len(dev, 0), 
+                             _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
+       if (ret) {
+               DRM_ERROR("Unable to initialize the mmio mapping (%d). "
+                         "Please report your setup to " DRIVER_EMAIL "\n",
+                         ret);
+               return 1;
        }
-
-       DRM_INFO("%lld MB of video ram detected\n",nouveau_mem_fb_amount(dev)>>20);
+       DRM_DEBUG("regs mapped ok at 0x%lx\n", dev_priv->mmio->offset);
 
        /* map larger RAMIN aperture on NV40 cards */
        if (dev_priv->card_type >= NV_40) {
@@ -69,11 +56,11 @@ int nouveau_firstopen(struct drm_device *dev)
                if (drm_get_resource_len(dev, ramin_resource) == 0)
                        ramin_resource = 3;
 
-               ret = drm_addmap(dev, drm_get_resource_start(dev, ramin_resource),
-                                     drm_get_resource_len(dev, ramin_resource),
-                                     _DRM_REGISTERS,
-                                     _DRM_READ_ONLY,
-                                     &dev_priv->ramin);
+               ret = drm_addmap(dev,
+                                drm_get_resource_start(dev, ramin_resource),
+                                drm_get_resource_len(dev, ramin_resource),
+                                _DRM_REGISTERS, _DRM_READ_ONLY,
+                                &dev_priv->ramin);
                if (ret) {
                        DRM_ERROR("Failed to init RAMIN mapping, "
                                  "limited instance memory available\n");
@@ -82,33 +69,165 @@ int nouveau_firstopen(struct drm_device *dev)
        } else
                dev_priv->ramin = NULL;
 
+       return 0;
+}
+
+static void nouveau_stub_takedown(drm_device_t *dev) {}
+static int nouveau_init_engine_ptrs(drm_device_t *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+       struct nouveau_engine_func *engine = &dev_priv->Engine;
+
+       switch (dev_priv->chipset & 0xf0) {
+       case 0x00:
+               engine->Mc.Init         = nv04_mc_init;
+               engine->Mc.Takedown     = nv04_mc_takedown;
+               engine->Timer.Init      = nv04_timer_init;
+               engine->Timer.Takedown  = nv04_timer_takedown;
+               engine->Fb.Init         = nv04_fb_init;
+               engine->Fb.Takedown     = nv04_fb_takedown;
+               engine->Graph.Init      = nv04_graph_init;
+               engine->Graph.Takedown  = nv04_graph_takedown;
+               engine->Fifo.Init       = nouveau_fifo_init;
+               engine->Fifo.Takedown   = nouveau_stub_takedown;
+               break;
+       case 0x10:
+               engine->Mc.Init         = nv04_mc_init;
+               engine->Mc.Takedown     = nv04_mc_takedown;
+               engine->Timer.Init      = nv04_timer_init;
+               engine->Timer.Takedown  = nv04_timer_takedown;
+               engine->Fb.Init         = nv10_fb_init;
+               engine->Fb.Takedown     = nv10_fb_takedown;
+               engine->Graph.Init      = nv10_graph_init;
+               engine->Graph.Takedown  = nv10_graph_takedown;
+               engine->Fifo.Init       = nouveau_fifo_init;
+               engine->Fifo.Takedown   = nouveau_stub_takedown;
+               break;
+       case 0x20:
+               engine->Mc.Init         = nv04_mc_init;
+               engine->Mc.Takedown     = nv04_mc_takedown;
+               engine->Timer.Init      = nv04_timer_init;
+               engine->Timer.Takedown  = nv04_timer_takedown;
+               engine->Fb.Init         = nv10_fb_init;
+               engine->Fb.Takedown     = nv10_fb_takedown;
+               engine->Graph.Init      = nv20_graph_init;
+               engine->Graph.Takedown  = nv20_graph_takedown;
+               engine->Fifo.Init       = nouveau_fifo_init;
+               engine->Fifo.Takedown   = nouveau_stub_takedown;
+               break;
+       case 0x30:
+               engine->Mc.Init         = nv04_mc_init;
+               engine->Mc.Takedown     = nv04_mc_takedown;
+               engine->Timer.Init      = nv04_timer_init;
+               engine->Timer.Takedown  = nv04_timer_takedown;
+               engine->Fb.Init         = nv10_fb_init;
+               engine->Fb.Takedown     = nv10_fb_takedown;
+               engine->Graph.Init      = nv30_graph_init;
+               engine->Graph.Takedown  = nv30_graph_takedown;
+               engine->Fifo.Init       = nouveau_fifo_init;
+               engine->Fifo.Takedown   = nouveau_stub_takedown;
+               break;
+       case 0x40:
+               engine->Mc.Init         = nv40_mc_init;
+               engine->Mc.Takedown     = nv40_mc_takedown;
+               engine->Timer.Init      = nv04_timer_init;
+               engine->Timer.Takedown  = nv04_timer_takedown;
+               engine->Fb.Init         = nv40_fb_init;
+               engine->Fb.Takedown     = nv40_fb_takedown;
+               engine->Graph.Init      = nv40_graph_init;
+               engine->Graph.Takedown  = nv40_graph_takedown;
+               engine->Fifo.Init       = nouveau_fifo_init;
+               engine->Fifo.Takedown   = nouveau_stub_takedown;
+               break;
+       case 0x50:
+       default:
+               DRM_ERROR("NV%02x unsupported\n", dev_priv->chipset);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int nouveau_card_init(drm_device_t *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+       struct nouveau_engine_func *engine;
+       int ret;
+
+       /* Map any PCI resources we need on the card */
+       ret = nouveau_init_card_mappings(dev);
+       if (ret) return ret;
+
        /* Determine exact chipset we're running on */
        if (dev_priv->card_type < NV_10)
                dev_priv->chipset = dev_priv->card_type;
        else
-               dev_priv->chipset =(NV_READ(NV03_PMC_BOOT_0) & 0x0ff00000) >> 20;
+               dev_priv->chipset =
+                       (NV_READ(NV03_PMC_BOOT_0) & 0x0ff00000) >> 20;
 
-       /* Clear RAMIN
-        * Determine locations for RAMHT/FC/RO
-        * Initialise PFIFO
+       /* Initialise internal driver API hooks */
+       ret = nouveau_init_engine_ptrs(dev);
+       if (ret) return ret;
+       engine = &dev_priv->Engine;
+
+       /* Initialise instance memory, must happen before mem_init so we
+        * know exactly how much VRAM we're able to use for "normal"
+        * purposes.
         */
-       ret = nouveau_fifo_init(dev);
+       ret = nouveau_instmem_init(dev);
+       if (ret) return ret;
+
+       /* Setup the memory manager */
+       ret = nouveau_mem_init(dev);
+       if (ret) return ret;
+
+       /* Parse BIOS tables / Run init tables? */
+
+       /* PMC */
+       ret = engine->Mc.Init(dev);
+       if (ret) return ret;
+
+       /* PTIMER */
+       ret = engine->Timer.Init(dev);
+       if (ret) return ret;
+
+       /* PFB */
+       ret = engine->Fb.Init(dev);
+       if (ret) return ret;
+
+       /* PGRAPH */
+       ret = engine->Graph.Init(dev);
+       if (ret) return ret;
+
+       /* PFIFO */
+       ret = engine->Fifo.Init(dev);
        if (ret) return ret;
 
-       /* setup a mtrr over the FB */
-       dev_priv->fb_mtrr=drm_mtrr_add(drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC);
-
-       /* FIXME: doesn't belong here, and have no idea what it's for.. */
-       if (dev_priv->card_type >= NV_40)
-               nv40_graph_init(dev);
-       else if (dev_priv->card_type >= NV_30)
-               nv30_graph_init(dev);
-       else if (dev_priv->card_type >= NV_20)
-               nv20_graph_init(dev);
-       else if (dev_priv->card_type >= NV_10)
-               nv10_graph_init(dev);
-       else if (dev_priv->card_type >= NV_04)
-               nv04_graph_init(dev);
+       /* what about PVIDEO/PCRTC/PRAMDAC etc? */
+
+       return 0;
+}
+
+/* here a client dies, release the stuff that was allocated for its filp */
+void nouveau_preclose(drm_device_t * dev, DRMFILE filp)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+
+       nouveau_mem_release(filp,dev_priv->fb_heap);
+       nouveau_mem_release(filp,dev_priv->agp_heap);
+       nouveau_fifo_cleanup(dev, filp);
+}
+
+/* first module load, setup the mmio/fb mapping */
+int nouveau_firstopen(struct drm_device *dev)
+{
+       int ret;
+
+       ret = nouveau_card_init(dev);
+       if (ret) {
+               DRM_ERROR("nouveau_card_init() failed! (%d)\n", ret);
+               return ret;
+       }
 
        return 0;
 }
@@ -116,6 +235,7 @@ int nouveau_firstopen(struct drm_device *dev)
 int nouveau_load(struct drm_device *dev, unsigned long flags)
 {
        drm_nouveau_private_t *dev_priv;
+       int ret;
 
        if (flags==NV_UNKNOWN)
                return DRM_ERR(EINVAL);
@@ -130,6 +250,14 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
 
        dev->dev_private = (void *)dev_priv;
 
+#if 0
+       ret = nouveau_card_init(dev);
+       if (ret) {
+               DRM_ERROR("nouveau_card_init() failed! (%d)\n", ret);
+               return ret;
+       }
+#endif
+
        return 0;
 }
 
@@ -244,3 +372,4 @@ void nouveau_wait_for_idle(struct drm_device *dev)
        }
 }
 
+
diff --git a/shared-core/nv04_fb.c b/shared-core/nv04_fb.c
new file mode 100644 (file)
index 0000000..06b1c99
--- /dev/null
@@ -0,0 +1,24 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv04_fb_init(drm_device_t *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+
+       /* 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_WRITE(NV04_PFB_CFG0, 0x1114);
+
+       return 0;
+}
+
+void
+nv04_fb_takedown(drm_device_t *dev)
+{
+}
+
index 830d673..cf4e58f 100644 (file)
@@ -222,13 +222,44 @@ int nv04_graph_context_create(drm_device_t *dev, int channel) {
 
 int nv04_graph_init(drm_device_t *dev) {
        drm_nouveau_private_t *dev_priv = dev->dev_private;
+       int i,sum=0;
+
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
+                       ~NV_PMC_ENABLE_PGRAPH);
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
+                        NV_PMC_ENABLE_PGRAPH);
 
        // check the context is big enough
-       int i,sum=0;
        for ( i = 0 ; i<sizeof(nv04_graph_ctx_regs)/sizeof(nv04_graph_ctx_regs[0]); i++)
                sum+=nv04_graph_ctx_regs[i].number;
        if ( sum*4>sizeof(dev_priv->fifos[0].pgraph_ctx) )
                DRM_ERROR("pgraph_ctx too small\n");
+
+       NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000);
+       NV_WRITE(NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x000001FF);
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x1230C000);
+       NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x72111101);
+       NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x11D5F071);
+       NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x0004FF31);
+       NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x4004FF31 |
+                                   (0x00D00000) |
+                                   (1<<29) |
+                                   (1<<31));
+
+       NV_WRITE(NV04_PGRAPH_STATE        , 0xFFFFFFFF);
+       NV_WRITE(NV04_PGRAPH_CTX_CONTROL  , 0x10010100);
+       NV_WRITE(NV04_PGRAPH_FIFO         , 0x00000001);
+
+       /* These don't belong here, they're part of a per-channel context */
+       NV_WRITE(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
+       NV_WRITE(NV04_PGRAPH_BETA_AND     , 0xFFFFFFFF);
+
        return 0;
 }
 
+void nv04_graph_takedown(drm_device_t *dev)
+{
+}
+
diff --git a/shared-core/nv04_mc.c b/shared-core/nv04_mc.c
new file mode 100644 (file)
index 0000000..2619eb7
--- /dev/null
@@ -0,0 +1,20 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv04_mc_init(drm_device_t *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+
+       NV_WRITE(NV03_PMC_INTR_EN_0, 0);
+
+       return 0;
+}
+
+void
+nv04_mc_takedown(drm_device_t *dev)
+{
+}
+
diff --git a/shared-core/nv04_timer.c b/shared-core/nv04_timer.c
new file mode 100644 (file)
index 0000000..a4b4e82
--- /dev/null
@@ -0,0 +1,24 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv04_timer_init(drm_device_t *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+
+       NV_WRITE(NV04_PTIMER_INTR_EN_0, 0x00000000);
+       NV_WRITE(NV04_PTIMER_INTR_0, 0xFFFFFFFF);
+
+       NV_WRITE(NV04_PTIMER_NUMERATOR, 0x00000008);
+       NV_WRITE(NV04_PTIMER_DENOMINATOR, 0x00000003);
+
+       return 0;
+}
+
+void
+nv04_timer_takedown(drm_device_t *dev)
+{
+}
+
diff --git a/shared-core/nv10_fb.c b/shared-core/nv10_fb.c
new file mode 100644 (file)
index 0000000..e8336a2
--- /dev/null
@@ -0,0 +1,26 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv10_fb_init(drm_device_t *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+       uint32_t fb_bar_size;
+       int i;
+
+       fb_bar_size = drm_get_resource_len(dev, 0) - 1;
+       for (i=0; i<NV10_PFB_TILE__SIZE; i++) {
+               NV_WRITE(NV10_PFB_TILE(i), 0);
+               NV_WRITE(NV10_PFB_TLIMIT(i), fb_bar_size);
+       }
+
+       return 0;
+}
+
+void
+nv10_fb_takedown(drm_device_t *dev)
+{
+}
+
index ad74b84..3ca843d 100644 (file)
@@ -605,5 +605,58 @@ int nv10_graph_context_create(drm_device_t *dev, int channel) {
 
 
 int nv10_graph_init(drm_device_t *dev) {
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+       uint32_t tmp, vramsz;
+       int i;
+
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
+                       ~NV_PMC_ENABLE_PGRAPH);
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
+                        NV_PMC_ENABLE_PGRAPH);
+
+       NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000);
+       NV_WRITE(NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
+       NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x00118700);
+       NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x24E00810);
+       NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x55DE0030 |
+                                     (1<<29) |
+                                     (1<<31));
+
+       /* copy tile info from PFB */
+       for (i=0; i<NV10_PFB_TILE__SIZE; i++) {
+               NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i)));
+               NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i)));
+               NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i)));
+               NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i)));
+       }
+
+       NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100);
+       NV_WRITE(NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+       NV_WRITE(NV04_PGRAPH_FIFO       , 0x00000001);
+
+       /* the below don't belong here, per-channel context state */
+       tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
+       NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+       tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100;
+       NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+
+       vramsz = drm_get_resource_len(dev, 0) - 1;
+       NV_WRITE(NV04_PGRAPH_BOFFSET0, 0);
+       NV_WRITE(NV04_PGRAPH_BOFFSET1, 0);
+       NV_WRITE(NV04_PGRAPH_BLIMIT0 , vramsz);
+       NV_WRITE(NV04_PGRAPH_BLIMIT1 , vramsz);
+
+       NV_WRITE(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000);
+       NV_WRITE(NV04_PGRAPH_BETA_AND     , 0xFFFFFFFF);
+
        return 0;
+
 }
+
+void nv10_graph_takedown(drm_device_t *dev)
+{
+}
+
index 9ba6a87..45d88d6 100644 (file)
@@ -136,6 +136,12 @@ int nv20_graph_init(drm_device_t *dev) {
        drm_nouveau_private_t *dev_priv =
                (drm_nouveau_private_t *)dev->dev_private;
        int i;
+       uint32_t tmp, vramsz;
+
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
+                       ~NV_PMC_ENABLE_PGRAPH);
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
+                        NV_PMC_ENABLE_PGRAPH);
 
        /* Create Context Pointer Table */
        dev_priv->ctx_table_size = 32 * 4;
@@ -151,5 +157,78 @@ int nv20_graph_init(drm_device_t *dev) {
        //XXX need to be done and save/restore for each fifo ???
        nv20_graph_rdi(dev);
 
+       NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000);
+       NV_WRITE(NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
+       NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x00118700);
+       NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xF20E0431);
+       NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00000000);
+       NV_WRITE(0x40009C           , 0x00000040);
+
+       if (dev_priv->chipset >= 0x25) {
+               NV_WRITE(0x400890, 0x00080000);
+               NV_WRITE(0x400610, 0x304B1FB6);
+               NV_WRITE(0x400B80, 0x18B82880);
+               NV_WRITE(0x400B84, 0x44000000);
+               NV_WRITE(0x400098, 0x40000080);
+               NV_WRITE(0x400B88, 0x000000ff);
+       } else {
+               NV_WRITE(0x400880, 0x00080000);
+               NV_WRITE(0x400094, 0x00000005);
+               NV_WRITE(0x400B80, 0x45CAA208);
+               NV_WRITE(0x400B84, 0x24000000);
+               NV_WRITE(0x400098, 0x00000040);
+               NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00E00038);
+               NV_WRITE(NV10_PGRAPH_RDI_DATA , 0x00000030);
+               NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00E10038);
+               NV_WRITE(NV10_PGRAPH_RDI_DATA , 0x00000030);
+       }
+
+       /* copy tile info from PFB */
+       for (i=0; i<NV10_PFB_TILE__SIZE; i++) {
+               NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i)));
+               NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i)));
+               NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i)));
+               NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i)));
+       }
+
+       NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100);
+       NV_WRITE(NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+       NV_WRITE(NV04_PGRAPH_FIFO       , 0x00000001);
+
+       tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
+       NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+       tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100;
+       NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+
+       /* begin RAM config */
+       vramsz = drm_get_resource_len(dev, 0) - 1;
+       NV_WRITE(0x4009A4, NV_READ(NV04_PFB_CFG0));
+       NV_WRITE(0x4009A8, NV_READ(NV04_PFB_CFG1));
+       NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA0000);
+       NV_WRITE(NV10_PGRAPH_RDI_DATA , NV_READ(NV04_PFB_CFG0));
+       NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA0004);
+       NV_WRITE(NV10_PGRAPH_RDI_DATA , NV_READ(NV04_PFB_CFG1));
+       NV_WRITE(0x400820, 0);
+       NV_WRITE(0x400824, 0);
+       NV_WRITE(0x400864, vramsz-1);
+       NV_WRITE(0x400868, vramsz-1);
+
+       /* interesting.. the below overwrites some of the tile setup above.. */
+       NV_WRITE(0x400B20, 0x00000000);
+       NV_WRITE(0x400B04, 0xFFFFFFFF);
+
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
+
        return 0;
 }
+
+void nv20_graph_takedown(drm_device_t *dev)
+{
+}
+
index cb183be..391a106 100644 (file)
@@ -136,8 +136,14 @@ int nv30_graph_init(drm_device_t *dev)
 {
        drm_nouveau_private_t *dev_priv =
                (drm_nouveau_private_t *)dev->dev_private;
+       uint32_t vramsz, tmp;
        int i;
 
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
+                       ~NV_PMC_ENABLE_PGRAPH);
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
+                        NV_PMC_ENABLE_PGRAPH);
+
         /* Create Context Pointer Table */
         dev_priv->ctx_table_size = 32 * 4;
         dev_priv->ctx_table = nouveau_instmem_alloc(dev, dev_priv->ctx_table_size, 4);
@@ -149,6 +155,68 @@ int nv30_graph_init(drm_device_t *dev)
 
         NV_WRITE(NV10_PGRAPH_CHANNEL_CTX_TABLE, nouveau_chip_instance_get(dev, dev_priv->ctx_table));
 
+       NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000);
+       NV_WRITE(NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
+       NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x401287c0);
+       NV_WRITE(0x400890, 0x00140000);
+       NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xf0de0475);
+       NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x10008000);
+       NV_WRITE(NV04_PGRAPH_LIMIT_VIOL_PIX, 0xf04b1f36);
+       NV_WRITE(0x400B80, 0x1003d888);
+       NV_WRITE(0x400B84, 0x0c000000);
+       NV_WRITE(0x400B88, 0x62ff0f7f);
+       NV_WRITE(0x400098, 0x000000c0);
+       NV_WRITE(0x40009C, 0x0005dc00);
+       NV_WRITE(NV04_PGRAPH_DEBUG_2, 0x62ff0f7f);
+       NV_WRITE(0x4000a0, 0x00000000);
+       NV_WRITE(0x4000a4, 0x00000008);
+
+       /* copy tile info from PFB */
+       for (i=0; i<NV10_PFB_TILE__SIZE; i++) {
+               NV_WRITE(NV10_PGRAPH_TILE(i), NV_READ(NV10_PFB_TILE(i)));
+               NV_WRITE(NV10_PGRAPH_TLIMIT(i), NV_READ(NV10_PFB_TLIMIT(i)));
+               NV_WRITE(NV10_PGRAPH_TSIZE(i), NV_READ(NV10_PFB_TSIZE(i)));
+               NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i)));
+       }
+
+       NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100);
+       NV_WRITE(NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+       NV_WRITE(NV04_PGRAPH_FIFO       , 0x00000001);
+
+       /* begin RAM config */
+       vramsz = drm_get_resource_len(dev, 0) - 1;
+       NV_WRITE(0x4009A4, NV_READ(NV04_PFB_CFG0));
+       NV_WRITE(0x4009A8, NV_READ(NV04_PFB_CFG1));
+       NV_WRITE(0x400750, 0x00EA0000);
+       NV_WRITE(0x400754, NV_READ(NV04_PFB_CFG0));
+       NV_WRITE(0x400750, 0x00EA0004);
+       NV_WRITE(0x400754, NV_READ(NV04_PFB_CFG1));
+       NV_WRITE(0x400820, 0);
+       NV_WRITE(0x400824, 0);
+       NV_WRITE(0x400864, vramsz-1);
+       NV_WRITE(0x400868, vramsz-1);
+
+       NV_WRITE(0x400B20, 0x00000000);
+       NV_WRITE(0x400B04, 0xFFFFFFFF);
+
+       /* per-context state, doesn't belong here */
+       tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
+       NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+       tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100;
+       NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
+
        return 0;
 }
 
+void nv30_graph_takedown(drm_device_t *dev)
+{
+}
+
diff --git a/shared-core/nv40_fb.c b/shared-core/nv40_fb.c
new file mode 100644 (file)
index 0000000..83a7580
--- /dev/null
@@ -0,0 +1,56 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv40_fb_init(drm_device_t *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+       uint32_t fb_bar_size, tmp;
+       int num_tiles;
+       int i;
+
+       switch (dev_priv->chipset) {
+       case 0x40:
+       case 0x45:
+               tmp = NV_READ(NV10_PFB_CLOSE_PAGE2);
+               NV_WRITE(NV10_PFB_CLOSE_PAGE2, tmp & ~(1<<15));
+               num_tiles = NV10_PFB_TILE__SIZE;
+               break;
+       case 0x46: /* G72 */
+       case 0x47: /* G70 */
+       case 0x49: /* G71 */
+       case 0x4b: /* G73 */
+       case 0x4c: /* C51 (G7X version) */
+               num_tiles = NV40_PFB_TILE__SIZE_1;
+               break;
+       default:
+               num_tiles = NV40_PFB_TILE__SIZE_0;
+               break;
+       }
+
+       fb_bar_size = drm_get_resource_len(dev, 0) - 1;
+       switch (dev_priv->chipset) {
+       case 0x40:
+               for (i=0; i<num_tiles; i++) {
+                       NV_WRITE(NV10_PFB_TILE(i), 0);
+                       NV_WRITE(NV10_PFB_TLIMIT(i), fb_bar_size);
+               }
+               break;
+       default:
+               for (i=0; i<num_tiles; i++) {
+                       NV_WRITE(NV40_PFB_TILE(i), 0);
+                       NV_WRITE(NV40_PFB_TLIMIT(i), fb_bar_size);
+               }
+               break;
+       }
+
+       return 0;
+}
+
+void
+nv40_fb_takedown(drm_device_t *dev)
+{
+}
+
index f2650ca..510ffa7 100644 (file)
@@ -887,14 +887,28 @@ static uint32_t nv4e_ctx_voodoo[] = {
        ~0
 };
 
-
+/*
+ * G70         0x47
+ * G71         0x49
+ * NV45                0x48
+ * G72         0x46
+ * G73         0x4b
+ * C51_G7X     0x4c
+ * C51         0x4e
+ */
 int
 nv40_graph_init(drm_device_t *dev)
 {
        drm_nouveau_private_t *dev_priv =
                (drm_nouveau_private_t *)dev->dev_private;
        uint32_t *ctx_voodoo;
-       int i;
+       uint32_t vramsz, tmp;
+       int i, j;
+
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) &
+                       ~NV_PMC_ENABLE_PGRAPH);
+       NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) |
+                        NV_PMC_ENABLE_PGRAPH);
 
        switch (dev_priv->chipset) {
        case 0x40: ctx_voodoo = nv40_ctx_voodoo; break;
@@ -923,6 +937,194 @@ nv40_graph_init(drm_device_t *dev)
        /* No context present currently */
        NV_WRITE(0x40032C, 0x00000000);
 
+       NV_WRITE(NV03_PGRAPH_INTR_EN, 0x00000000);
+       NV_WRITE(NV03_PGRAPH_INTR   , 0xFFFFFFFF);
+
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0xFFFFFFFF);
+       NV_WRITE(NV04_PGRAPH_DEBUG_0, 0x00000000);
+       NV_WRITE(NV04_PGRAPH_DEBUG_1, 0x401287c0);
+       NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xe0de8055);
+       NV_WRITE(NV10_PGRAPH_DEBUG_4, 0x00008000);
+       NV_WRITE(NV04_PGRAPH_LIMIT_VIOL_PIX, 0x00be3c5f);
+
+       NV_WRITE(NV04_PGRAPH_CTX_CONTROL, 0x10010100);
+       NV_WRITE(NV10_PGRAPH_STATE      , 0xFFFFFFFF);
+       NV_WRITE(NV04_PGRAPH_FIFO       , 0x00000001);
+
+       j = NV_READ(0x1540) & 0xff;
+       if (j) {
+               for (i=0; !(j&1); j>>=1, i++);
+               NV_WRITE(0x405000, i);
+       }
+
+       if (dev_priv->chipset == 0x40) {
+               NV_WRITE(0x4009b0, 0x83280fff);
+               NV_WRITE(0x4009b4, 0x000000a0);
+       } else {
+               NV_WRITE(0x400820, 0x83280eff);
+               NV_WRITE(0x400824, 0x000000a0);
+       }
+
+       switch (dev_priv->chipset) {
+       case 0x40:
+       case 0x45:
+               NV_WRITE(0x4009b8, 0x0078e366);
+               NV_WRITE(0x4009bc, 0x0000014c);
+               break;
+       case 0x41:
+       case 0x42: /* pciid also 0x00Cx */
+//     case 0x0120: //XXX (pciid)
+               NV_WRITE(0x400828, 0x007596ff);
+               NV_WRITE(0x40082c, 0x00000108);
+               break;
+       case 0x43:
+               NV_WRITE(0x400828, 0x0072cb77);
+               NV_WRITE(0x40082c, 0x00000108);
+               break;
+       case 0x44:
+       case 0x46: /* G72 */
+       case 0x4a:
+       case 0x4c: /* G7x-based C51 */
+       case 0x4e:
+               NV_WRITE(0x400860, 0);
+               NV_WRITE(0x400864, 0);
+               break;
+       case 0x47: /* G70 */
+       case 0x49: /* G71 */
+       case 0x4b: /* G73 */
+               NV_WRITE(0x400828, 0x07830610);
+               NV_WRITE(0x40082c, 0x0000016A);
+               break;
+       default:
+               break;
+       }
+
+       NV_WRITE(0x400b38, 0x2ffff800);
+       NV_WRITE(0x400b3c, 0x00006000);
+
+       /* copy tile info from PFB */
+       switch (dev_priv->chipset) {
+       case 0x40: /* vanilla NV40 */
+               for (i=0; i<NV10_PFB_TILE__SIZE; i++) {
+                       tmp = NV_READ(NV10_PFB_TILE(i));
+                       NV_WRITE(NV40_PGRAPH_TILE0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TILE1(i), tmp);
+                       tmp = NV_READ(NV10_PFB_TLIMIT(i));
+                       NV_WRITE(NV40_PGRAPH_TLIMIT0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TLIMIT1(i), tmp);
+                       tmp = NV_READ(NV10_PFB_TSIZE(i));
+                       NV_WRITE(NV40_PGRAPH_TSIZE0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TSIZE1(i), tmp);
+                       tmp = NV_READ(NV10_PFB_TSTATUS(i));
+                       NV_WRITE(NV40_PGRAPH_TSTATUS0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TSTATUS1(i), tmp);
+               }
+               break;
+       case 0x44:
+       case 0x4a:
+       case 0x4e: /* NV44-based cores don't have 0x406900? */
+               for (i=0; i<NV40_PFB_TILE__SIZE_0; i++) {
+                       tmp = NV_READ(NV40_PFB_TILE(i));
+                       NV_WRITE(NV40_PGRAPH_TILE0(i), tmp);
+                       tmp = NV_READ(NV40_PFB_TLIMIT(i));
+                       NV_WRITE(NV40_PGRAPH_TLIMIT0(i), tmp);
+                       tmp = NV_READ(NV40_PFB_TSIZE(i));
+                       NV_WRITE(NV40_PGRAPH_TSIZE0(i), tmp);
+                       tmp = NV_READ(NV40_PFB_TSTATUS(i));
+                       NV_WRITE(NV40_PGRAPH_TSTATUS0(i), tmp);
+               }
+               break;
+       case 0x46:
+       case 0x47:
+       case 0x49:
+       case 0x4b: /* G7X-based cores */
+               for (i=0; i<NV40_PFB_TILE__SIZE_1; i++) {
+                       tmp = NV_READ(NV40_PFB_TILE(i));
+                       NV_WRITE(NV47_PGRAPH_TILE0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TILE1(i), tmp);
+                       tmp = NV_READ(NV40_PFB_TLIMIT(i));
+                       NV_WRITE(NV47_PGRAPH_TLIMIT0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TLIMIT1(i), tmp);
+                       tmp = NV_READ(NV40_PFB_TSIZE(i));
+                       NV_WRITE(NV47_PGRAPH_TSIZE0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TSIZE1(i), tmp);
+                       tmp = NV_READ(NV40_PFB_TSTATUS(i));
+                       NV_WRITE(NV47_PGRAPH_TSTATUS0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TSTATUS1(i), tmp);
+               }
+               break;
+       default: /* everything else */
+               for (i=0; i<NV40_PFB_TILE__SIZE_0; i++) {
+                       tmp = NV_READ(NV40_PFB_TILE(i));
+                       NV_WRITE(NV40_PGRAPH_TILE0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TILE1(i), tmp);
+                       tmp = NV_READ(NV40_PFB_TLIMIT(i));
+                       NV_WRITE(NV40_PGRAPH_TLIMIT0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TLIMIT1(i), tmp);
+                       tmp = NV_READ(NV40_PFB_TSIZE(i));
+                       NV_WRITE(NV40_PGRAPH_TSIZE0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TSIZE1(i), tmp);
+                       tmp = NV_READ(NV40_PFB_TSTATUS(i));
+                       NV_WRITE(NV40_PGRAPH_TSTATUS0(i), tmp);
+                       NV_WRITE(NV40_PGRAPH_TSTATUS1(i), tmp);
+               }
+               break;
+       }
+
+       /* begin RAM config */
+       vramsz = drm_get_resource_len(dev, 0) - 1;
+       switch (dev_priv->chipset) {
+       case 0x40:
+               NV_WRITE(0x4009A4, NV_READ(NV04_PFB_CFG0));
+               NV_WRITE(0x4009A8, NV_READ(NV04_PFB_CFG1));
+               NV_WRITE(0x4069A4, NV_READ(NV04_PFB_CFG0));
+               NV_WRITE(0x4069A8, NV_READ(NV04_PFB_CFG1));
+               NV_WRITE(0x400820, 0);
+               NV_WRITE(0x400824, 0);
+               NV_WRITE(0x400864, vramsz);
+               NV_WRITE(0x400868, vramsz);
+               break;
+       default:
+               switch (dev_priv->chipset) {
+               case 0x46:
+               case 0x47:
+               case 0x49:
+               case 0x4b:
+                       NV_WRITE(0x400DF0, NV_READ(NV04_PFB_CFG0));
+                       NV_WRITE(0x400DF4, NV_READ(NV04_PFB_CFG1));
+                       break;
+               default:
+                       NV_WRITE(0x4009F0, NV_READ(NV04_PFB_CFG0));
+                       NV_WRITE(0x4009F4, NV_READ(NV04_PFB_CFG1));
+                       break;
+               }
+               NV_WRITE(0x4069F0, NV_READ(NV04_PFB_CFG0));
+               NV_WRITE(0x4069F4, NV_READ(NV04_PFB_CFG1));
+               NV_WRITE(0x400840, 0);
+               NV_WRITE(0x400844, 0);
+               NV_WRITE(0x4008A0, vramsz);
+               NV_WRITE(0x4008A4, vramsz);
+               break;
+       }
+
+       /* per-context state, doesn't belong here */
+       NV_WRITE(0x400B20, 0x00000000);
+       NV_WRITE(0x400B04, 0xFFFFFFFF);
+
+       tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
+       NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+       tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100;
+       NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
+       NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
+
        return 0;
 }
 
+void nv40_graph_takedown(drm_device_t *dev)
+{
+}
+
diff --git a/shared-core/nv40_mc.c b/shared-core/nv40_mc.c
new file mode 100644 (file)
index 0000000..554a224
--- /dev/null
@@ -0,0 +1,36 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv40_mc_init(drm_device_t *dev)
+{
+       drm_nouveau_private_t *dev_priv = dev->dev_private;
+       uint32_t tmp;
+
+       NV_WRITE(NV03_PMC_INTR_EN_0, 0);
+
+       switch (dev_priv->chipset) {
+       case 0x44:
+       case 0x46: /* G72 */
+       case 0x4e:
+       case 0x4c: /* C51_G7X */
+               tmp = NV_READ(NV40_PFB_020C);
+               NV_WRITE(NV40_PMC_1700, tmp);
+               NV_WRITE(NV40_PMC_1704, 0);
+               NV_WRITE(NV40_PMC_1708, 0);
+               NV_WRITE(NV40_PMC_170C, tmp);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+void
+nv40_mc_takedown(drm_device_t *dev)
+{
+}
+