struct nvkm_memory *mmu_wr;
 };
 
+u64 nvkm_fb_vidmem_size(struct nvkm_device *);
 int nvkm_fb_mem_unlock(struct nvkm_fb *);
 
 void nvkm_fb_tile_init(struct nvkm_fb *, int region, u32 addr, u32 size,
 
 nvkm-y += nvkm/subdev/fb/ramgm107.o
 nvkm-y += nvkm/subdev/fb/ramgm200.o
 nvkm-y += nvkm/subdev/fb/ramgp100.o
+nvkm-y += nvkm/subdev/fb/ramgp102.o
 nvkm-y += nvkm/subdev/fb/ramga102.o
 nvkm-y += nvkm/subdev/fb/sddr2.o
 nvkm-y += nvkm/subdev/fb/sddr3.o
 
        return 0;
 }
 
+u64
+nvkm_fb_vidmem_size(struct nvkm_device *device)
+{
+       struct nvkm_fb *fb = device->fb;
+
+       if (fb && fb->func->vidmem.size)
+               return fb->func->vidmem.size(fb);
+
+       WARN_ON(1);
+       return 0;
+}
+
 static int
 nvkm_fb_init(struct nvkm_subdev *subdev)
 {
 
        .init_page = gv100_fb_init_page,
        .init_unkn = gp100_fb_init_unkn,
        .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init,
-       .ram_new = gp100_ram_new,
+       .vidmem.size = gp102_fb_vidmem_size,
+       .ram_new = gp102_ram_new,
        .default_bigpage = 16,
 };
 
 
        return (nvkm_rd32(device, 0x100cd0) & 0x00000010) != 0;
 }
 
+u64
+gp102_fb_vidmem_size(struct nvkm_fb *fb)
+{
+       const u32 data = nvkm_rd32(fb->subdev.device, 0x100ce0);
+       const u32 lmag = (data & 0x000003f0) >> 4;
+       const u32 lsca = (data & 0x0000000f);
+       const u64 size = (u64)lmag << (lsca + 20);
+
+       if (data & 0x40000000)
+               return size / 16 * 15;
+
+       return size;
+}
+
 int
 gp102_fb_oneinit(struct nvkm_fb *fb)
 {
        .init_remapper = gp100_fb_init_remapper,
        .init_page = gm200_fb_init_page,
        .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init,
+       .vidmem.size = gp102_fb_vidmem_size,
        .vpr.scrub_required = gp102_fb_vpr_scrub_required,
        .vpr.scrub = gp102_fb_vpr_scrub,
-       .ram_new = gp100_ram_new,
+       .ram_new = gp102_ram_new,
 };
 
 int
 
        .init_page = gv100_fb_init_page,
        .init_unkn = gp100_fb_init_unkn,
        .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init,
+       .vidmem.size = gp102_fb_vidmem_size,
        .vpr.scrub_required = gp102_fb_vpr_scrub_required,
        .vpr.scrub = gp102_fb_vpr_scrub,
-       .ram_new = gp100_ram_new,
+       .ram_new = gp102_ram_new,
        .default_bigpage = 16,
 };
 
 
                void (*flush_page_init)(struct nvkm_fb *);
        } sysmem;
 
+       struct nvkm_fb_func_vidmem {
+               u64 (*size)(struct nvkm_fb *);
+       } vidmem;
+
        struct {
                bool (*scrub_required)(struct nvkm_fb *);
                int (*scrub)(struct nvkm_fb *);
 void gp100_fb_init_unkn(struct nvkm_fb *);
 
 int gp102_fb_oneinit(struct nvkm_fb *);
+u64 gp102_fb_vidmem_size(struct nvkm_fb *);
 bool gp102_fb_vpr_scrub_required(struct nvkm_fb *);
 int gp102_fb_vpr_scrub(struct nvkm_fb *);
 
 
 int gm107_ram_new(struct nvkm_fb *, struct nvkm_ram **);
 int gm200_ram_new(struct nvkm_fb *, struct nvkm_ram **);
 int gp100_ram_new(struct nvkm_fb *, struct nvkm_ram **);
+int gp102_ram_new(struct nvkm_fb *, struct nvkm_ram **);
 int ga102_ram_new(struct nvkm_fb *, struct nvkm_ram **);
 #endif
 
--- /dev/null
+// SPDX-License-Identifier: MIT
+#include "ram.h"
+
+#include <subdev/bios.h>
+
+static const struct nvkm_ram_func
+gp102_ram = {
+};
+
+int
+gp102_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
+{
+       enum nvkm_ram_type type = nvkm_fb_bios_memtype(fb->subdev.device->bios);
+       const u32 rsvd_head = ( 256 * 1024); /* vga memory */
+       const u32 rsvd_tail = (1024 * 1024); /* vbios etc */
+       u64 size = fb->func->vidmem.size(fb);
+       int ret;
+
+       ret = nvkm_ram_new_(&gp102_ram, fb, type, size, pram);
+       if (ret)
+               return ret;
+
+       nvkm_mm_fini(&(*pram)->vram);
+
+       return nvkm_mm_init(&(*pram)->vram, NVKM_RAM_MM_NORMAL,
+                           rsvd_head >> NVKM_RAM_MM_SHIFT,
+                           (size - rsvd_head - rsvd_tail) >> NVKM_RAM_MM_SHIFT,
+                           1);
+
+}
 
        .init_page = gv100_fb_init_page,
        .init_unkn = gp100_fb_init_unkn,
        .sysmem.flush_page_init = gf100_fb_sysmem_flush_page_init,
+       .vidmem.size = gp102_fb_vidmem_size,
        .vpr.scrub_required = tu102_fb_vpr_scrub_required,
        .vpr.scrub = gp102_fb_vpr_scrub,
-       .ram_new = gp100_ram_new,
+       .ram_new = gp102_ram_new,
        .default_bigpage = 16,
 };