return mm->heap_nodes;
 }
 
-int  nvkm_mm_init(struct nvkm_mm *, u32 offset, u32 length, u32 block);
+int  nvkm_mm_init(struct nvkm_mm *, u8 heap, u32 offset, u32 length, u32 block);
 int  nvkm_mm_fini(struct nvkm_mm *);
 int  nvkm_mm_head(struct nvkm_mm *, u8 heap, u8 type, u32 size_max,
                  u32 size_min, u32 align, struct nvkm_mm_node **);
 
        u64 size;
 
 #define NVKM_RAM_MM_SHIFT 12
+#define NVKM_RAM_MM_ANY    (NVKM_MM_HEAP_ANY + 0)
+#define NVKM_RAM_MM_NORMAL (NVKM_MM_HEAP_ANY + 1)
+#define NVKM_RAM_MM_NOMAP  (NVKM_MM_HEAP_ANY + 2)
+#define NVKM_RAM_MM_MIXED  (NVKM_MM_HEAP_ANY + 3)
        struct nvkm_mm vram;
        struct nvkm_mm tags;
        u64 stolen;
 
        if (ret)
                goto done;
 
-       ret = nvkm_mm_init(&chan->heap, 0, PAGE_SIZE, 1);
+       ret = nvkm_mm_init(&chan->heap, 0, 0, PAGE_SIZE, 1);
 done:
        if (ret)
                nouveau_abi16_chan_fini(abi16, chan);
 
                gpuobj->size = nvkm_memory_size(gpuobj->memory);
        }
 
-       return nvkm_mm_init(&gpuobj->heap, 0, gpuobj->size, 1);
+       return nvkm_mm_init(&gpuobj->heap, 0, 0, gpuobj->size, 1);
 }
 
 void
 
 }
 
 int
-nvkm_mm_init(struct nvkm_mm *mm, u32 offset, u32 length, u32 block)
+nvkm_mm_init(struct nvkm_mm *mm, u8 heap, u32 offset, u32 length, u32 block)
 {
        struct nvkm_mm_node *node, *prev;
        u32 next;
 
        list_add_tail(&node->nl_entry, &mm->nodes);
        list_add_tail(&node->fl_entry, &mm->free);
-       node->heap = ++mm->heap_nodes;
+       node->heap = heap;
+       mm->heap_nodes++;
        return 0;
 }
 
 
                if (ret)
                        goto free_domain;
 
-               ret = nvkm_mm_init(&tdev->iommu.mm, 0,
+               ret = nvkm_mm_init(&tdev->iommu.mm, 0, 0,
                                   (1ULL << tdev->func->iommu_bit) >>
                                   tdev->iommu.pgshift, 1);
                if (ret)
 
        ram->size = size;
 
        if (!nvkm_mm_initialised(&ram->vram)) {
-               ret = nvkm_mm_init(&ram->vram, 0, size >> NVKM_RAM_MM_SHIFT, 1);
+               ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL, 0,
+                                  size >> NVKM_RAM_MM_SHIFT, 1);
                if (ret)
                        return ret;
        }
 
        if (!nvkm_mm_initialised(&ram->tags)) {
-               ret = nvkm_mm_init(&ram->tags, 0, tags ? ++tags : 0, 1);
+               ret = nvkm_mm_init(&ram->tags, 0, 0, tags ? ++tags : 0, 1);
                if (ret)
                        return ret;
 
 
         */
        if (lower != total) {
                /* The common memory amount is addressed normally. */
-               ret = nvkm_mm_init(&ram->vram, rsvd_head >> NVKM_RAM_MM_SHIFT,
+               ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL,
+                                  rsvd_head >> NVKM_RAM_MM_SHIFT,
                                   (lower - rsvd_head) >> NVKM_RAM_MM_SHIFT, 1);
                if (ret)
                        return ret;
                /* And the rest is much higher in the physical address
                 * space, and may not be usable for certain operations.
                 */
-               ret = nvkm_mm_init(&ram->vram, ubase >> NVKM_RAM_MM_SHIFT,
+               ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_MIXED,
+                                  ubase >> NVKM_RAM_MM_SHIFT,
                                   (usize - rsvd_tail) >> NVKM_RAM_MM_SHIFT, 1);
                if (ret)
                        return ret;
        } else {
                /* GPUs without mixed-memory are a lot nicer... */
-               ret = nvkm_mm_init(&ram->vram, rsvd_head >> NVKM_RAM_MM_SHIFT,
+               ret = nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL,
+                                  rsvd_head >> NVKM_RAM_MM_SHIFT,
                                   (total - rsvd_head - rsvd_tail) >>
                                   NVKM_RAM_MM_SHIFT, 1);
                if (ret)
 
        ram->base.stolen = base;
        nvkm_mm_fini(&ram->base.vram);
 
-       return nvkm_mm_init(&ram->base.vram, rsvd_head >> NVKM_RAM_MM_SHIFT,
+       return nvkm_mm_init(&ram->base.vram, NVKM_RAM_MM_NORMAL,
+                           rsvd_head >> NVKM_RAM_MM_SHIFT,
                            (size - rsvd_head - rsvd_tail) >>
                            NVKM_RAM_MM_SHIFT, 1);
 }
 
        ram->ranks = (nvkm_rd32(device, 0x100200) & 0x4) ? 2 : 1;
        nvkm_mm_fini(&ram->vram);
 
-       return nvkm_mm_init(&ram->vram, rsvd_head >> NVKM_RAM_MM_SHIFT,
+       return nvkm_mm_init(&ram->vram, NVKM_RAM_MM_NORMAL,
+                           rsvd_head >> NVKM_RAM_MM_SHIFT,
                            (size - rsvd_head - rsvd_tail) >> NVKM_RAM_MM_SHIFT,
                            nv50_fb_vram_rblock(ram) >> NVKM_RAM_MM_SHIFT);
 }
 
        /* PRAMIN aperture maps over the end of VRAM, reserve it */
        imem->base.reserved = 512 * 1024;
 
-       ret = nvkm_mm_init(&imem->heap, 0, imem->base.reserved, 1);
+       ret = nvkm_mm_init(&imem->heap, 0, 0, imem->base.reserved, 1);
        if (ret)
                return ret;
 
 
        imem->base.reserved += 512 * 1024;      /* object storage */
        imem->base.reserved = round_up(imem->base.reserved, 4096);
 
-       ret = nvkm_mm_init(&imem->heap, 0, imem->base.reserved, 1);
+       ret = nvkm_mm_init(&imem->heap, 0, 0, imem->base.reserved, 1);
        if (ret)
                return ret;
 
 
        tag_size += tag_align;
        tag_size  = (tag_size + 0xfff) >> 12; /* round up */
 
-       ret = nvkm_mm_tail(&ram->vram, 1, 1, tag_size, tag_size, 1,
-                          <c->tag_ram);
+       ret = nvkm_mm_tail(&ram->vram, NVKM_RAM_MM_NORMAL, 1, tag_size,
+                          tag_size, 1, <c->tag_ram);
        if (ret) {
                ltc->num_tags = 0;
        } else {
        }
 
 mm_init:
-       return nvkm_mm_init(<c->tags, 0, ltc->num_tags, 1);
+       return nvkm_mm_init(<c->tags, 0, 0, ltc->num_tags, 1);
 }
 
 int
 
        ltc->ltc_nr = nvkm_rd32(device, 0x12006c);
        ltc->lts_nr = nvkm_rd32(device, 0x17e280) >> 28;
        /*XXX: tagram allocation - TBD */
-       return nvkm_mm_init(<c->tags, 0, 0, 1);
+       return nvkm_mm_init(<c->tags, 0, 0, 0, 1);
 }
 
 static void
 
                return -ENOMEM;
        }
 
-       ret = nvkm_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12,
+       ret = nvkm_mm_init(&vm->mm, 0, mm_offset >> 12, mm_length >> 12,
                           block >> 12);
        if (ret) {
                vfree(vm->pgt);