drm/nv20: split PFB code out of nv10_fb.c
authorBen Skeggs <bskeggs@redhat.com>
Mon, 12 Dec 2011 12:51:33 +0000 (22:51 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 13 Mar 2012 07:05:29 +0000 (17:05 +1000)
Most functions were quite different between NV10/NV20 already, and they're
about to get even more so.

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

index 9f27e3d9e69a9aa32bc4d6c9470861075dbff6ba..1a2ad7eb1734b64af3fa8b166a6f3120a51ba7e9 100644 (file)
@@ -14,7 +14,8 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
             nouveau_mm.o nouveau_vm.o nouveau_mxm.o nouveau_gpio.o \
              nv04_timer.o \
              nv04_mc.o nv40_mc.o nv50_mc.o \
-             nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o nvc0_fb.o \
+             nv04_fb.o nv10_fb.o nv20_fb.o nv30_fb.o nv40_fb.o \
+             nv50_fb.o nvc0_fb.o \
              nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o nvc0_fifo.o \
              nv04_graph.o nv10_graph.o nv20_graph.o \
              nv40_graph.o nv50_graph.o nvc0_graph.o \
index 36b50e555b92d4e8733d58ff9f093faed8baa7e9..576b0f67a8baf8bc6e21bcc9ec06ca2f24a7acfe 100644 (file)
@@ -1154,6 +1154,16 @@ extern void nv10_fb_init_tile_region(struct drm_device *dev, int i,
 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 *);
index dba3e90188de547837d117813c79ae5902e72302..6c262e1aaf9eab47e0531596455a9fbadb9cfc6a 100644 (file)
@@ -157,11 +157,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->timer.init              = nv04_timer_init;
                engine->timer.read              = nv04_timer_read;
                engine->timer.takedown          = nv04_timer_takedown;
-               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->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->fifo.channels           = 32;
                engine->fifo.init               = nv10_fifo_init;
                engine->fifo.takedown           = nv04_fifo_fini;
@@ -185,7 +185,7 @@ 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               = nv10_fb_vram_init;
+               engine->vram.init               = nv20_fb_vram_init;
                engine->vram.takedown           = nouveau_stub_takedown;
                engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
@@ -234,7 +234,7 @@ 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               = nv10_fb_vram_init;
+               engine->vram.init               = nv20_fb_vram_init;
                engine->vram.takedown           = nouveau_stub_takedown;
                engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
@@ -290,7 +290,7 @@ 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               = nv10_fb_vram_init;
+               engine->vram.init               = nv20_fb_vram_init;
                engine->vram.takedown           = nouveau_stub_takedown;
                engine->vram.flags_valid        = nouveau_mem_flags_valid;
                break;
index 447d6f2365265249899dc9387126330eed3ae744..420b1608536d16af3935889261b9f8cffa8ea161 100644 (file)
@@ -3,6 +3,38 @@
 #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)
+{
+       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)
+{
+       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;
+}
+
+void
+nv10_fb_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];
+
+       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);
+}
+
 int
 nv1a_fb_vram_init(struct drm_device *dev)
 {
@@ -33,122 +65,16 @@ 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 (dev_priv->card_type < NV_20) {
-               u32 cfg0 = nv_rd32(dev, 0x100200);
-               if (cfg0 & 0x00000001)
-                       dev_priv->vram_type = NV_MEM_TYPE_DDR1;
-               else
-                       dev_priv->vram_type = NV_MEM_TYPE_SDRAM;
-       }
-
-       return 0;
-}
-
-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;
-}
-
-static void
-nv20_fb_free_tag(struct drm_device *dev, struct drm_mm_node *mem)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       if (cfg0 & 0x00000001)
+               dev_priv->vram_type = NV_MEM_TYPE_DDR1;
+       else
+               dev_priv->vram_type = NV_MEM_TYPE_SDRAM;
 
-       spin_lock(&dev_priv->tile.lock);
-       drm_mm_put_block(mem);
-       spin_unlock(&dev_priv->tile.lock);
-}
-
-void
-nv10_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);
-
-       tile->addr = addr;
-       tile->limit = max(1u, addr + size) - 1;
-       tile->pitch = pitch;
-
-       if (dev_priv->card_type == NV_20) {
-               if (flags & NOUVEAU_GEM_TILE_ZETA) {
-                       /*
-                        * Allocate some of the on-die tag memory,
-                        * used to store Z compression meta-data (most
-                        * likely just a bitmap determining if a given
-                        * tile is compressed or not).
-                        */
-                       tile->tag_mem = nv20_fb_alloc_tag(dev, size / 256);
-
-                       if (tile->tag_mem) {
-                               /* Enable Z compression */
-                               if (dev_priv->chipset >= 0x25)
-                                       tile->zcomp = tile->tag_mem->start |
-                                               (bpp == 16 ?
-                                                NV25_PFB_ZCOMP_MODE_16 :
-                                                NV25_PFB_ZCOMP_MODE_32);
-                               else
-                                       tile->zcomp = tile->tag_mem->start |
-                                               NV20_PFB_ZCOMP_EN |
-                                               (bpp == 16 ? 0 :
-                                                NV20_PFB_ZCOMP_MODE_32);
-                       }
-
-                       tile->addr |= 3;
-               } else {
-                       tile->addr |= 1;
-               }
-
-       } else {
-               tile->addr |= 1 << 31;
-       }
-}
-
-void
-nv10_fb_free_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];
-
-       if (tile->tag_mem) {
-               nv20_fb_free_tag(dev, tile->tag_mem);
-               tile->tag_mem = NULL;
-       }
-
-       tile->addr = tile->limit = tile->pitch = tile->zcomp = 0;
-}
-
-void
-nv10_fb_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];
-
-       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);
-
-       if (dev_priv->card_type == NV_20)
-               nv_wr32(dev, NV20_PFB_ZCOMP(i), tile->zcomp);
+       return 0;
 }
 
 int
@@ -158,14 +84,8 @@ nv10_fb_init(struct drm_device *dev)
        struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
        int i;
 
-       pfb->num_tiles = NV10_PFB_TILE__SIZE;
-
-       if (dev_priv->card_type == NV_20)
-               drm_mm_init(&pfb->tag_heap, 0,
-                           (dev_priv->chipset >= 0x25 ?
-                            64 * 1024 : 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);
 
@@ -181,7 +101,4 @@ nv10_fb_takedown(struct drm_device *dev)
 
        for (i = 0; i < pfb->num_tiles; i++)
                pfb->free_tile_region(dev, i);
-
-       if (dev_priv->card_type == NV_20)
-               drm_mm_takedown(&pfb->tag_heap);
 }
diff --git a/drivers/gpu/drm/nouveau/nv20_fb.c b/drivers/gpu/drm/nouveau/nv20_fb.c
new file mode 100644 (file)
index 0000000..6585c27
--- /dev/null
@@ -0,0 +1,139 @@
+#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;
+}
+
+static void
+nv20_fb_free_tag(struct drm_device *dev, struct drm_mm_node **pmem)
+{
+       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);
+
+       tile->addr  = 0x00000001 | addr;
+       tile->limit = max(1u, addr + size) - 1;
+       tile->pitch = pitch;
+
+       /* Allocate some of the on-die tag memory, used to store Z
+        * 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) {
+                       /* Enable Z compression */
+                       tile->zcomp = tile->tag_mem->start;
+                       if (dev_priv->chipset >= 0x25) {
+                               if (bpp == 16)
+                                       tile->zcomp |= NV25_PFB_ZCOMP_MODE_16;
+                               else
+                                       tile->zcomp |= NV25_PFB_ZCOMP_MODE_32;
+                       } else {
+                               tile->zcomp |= NV20_PFB_ZCOMP_EN;
+                               if (bpp != 16)
+                                       tile->zcomp |= NV20_PFB_ZCOMP_MODE_32;
+                       }
+               }
+
+               tile->addr |= 2;
+       }
+}
+
+void
+nv20_fb_free_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];
+
+       tile->addr = tile->limit = tile->pitch = tile->zcomp = 0;
+       nv20_fb_free_tag(dev, &tile->tag_mem);
+}
+
+void
+nv20_fb_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];
+
+       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);
+}
+
+int
+nv20_fb_vram_init(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       dev_priv->vram_size = nv_rd32(dev, 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);
+       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;
+}
+
+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);
+}