struct notifier_block nb;
        } acpi;
 
-       struct nvkm_engine *bsp;
        struct nvkm_engine *ce[9];
        struct nvkm_engine *cipher;
        struct nvkm_disp *disp;
        struct nvkm_sec2 *sec2;
        struct nvkm_sw *sw;
        struct nvkm_engine *vic;
-       struct nvkm_engine *vp;
 
 #define NVKM_LAYOUT_ONCE(type,data,ptr) data *ptr;
 #define NVKM_LAYOUT_INST(type,data,ptr,cnt) data *ptr[cnt];
 #undef NVKM_LAYOUT_INST
 #undef NVKM_LAYOUT_ONCE
 
-       int (*bsp     )(struct nvkm_device *, int idx, struct nvkm_engine **);
        int (*ce[9]   )(struct nvkm_device *, int idx, struct nvkm_engine **);
        int (*cipher  )(struct nvkm_device *, int idx, struct nvkm_engine **);
        int (*disp    )(struct nvkm_device *, int idx, struct nvkm_disp **);
        int (*sec2    )(struct nvkm_device *, int idx, struct nvkm_sec2 **);
        int (*sw      )(struct nvkm_device *, int idx, struct nvkm_sw **);
        int (*vic     )(struct nvkm_device *, int idx, struct nvkm_engine **);
-       int (*vp      )(struct nvkm_device *, int idx, struct nvkm_engine **);
 };
 
 struct nvkm_device *nvkm_device_find(u64 name);
 
        struct nvkm_sclass sclass[];
 };
 
-int nvkm_engine_ctor(const struct nvkm_engine_func *, struct nvkm_device *,
-                    int index, bool enable, struct nvkm_engine *);
+int nvkm_engine_ctor_(const struct nvkm_engine_func *, bool old, struct nvkm_device *,
+                    enum nvkm_subdev_type, int inst, bool enable, struct nvkm_engine *);
+#define nvkm_engine_ctor_o(f,d,i,  e,s) nvkm_engine_ctor_((f),  true, (d), (i), -1 , (e), (s))
+#define nvkm_engine_ctor_n(f,d,t,i,e,s) nvkm_engine_ctor_((f), false, (d), (t), (i), (e), (s))
+#define nvkm_engine_ctor__(_1,_2,_3,_4,_5,_6,IMPL,...) IMPL
+#define nvkm_engine_ctor(A...) nvkm_engine_ctor__(A, nvkm_engine_ctor_n, nvkm_engine_ctor_o)(A)
 int nvkm_engine_new_(const struct nvkm_engine_func *, struct nvkm_device *,
                     int index, bool enable, struct nvkm_engine **);
 struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *);
 
 NVKM_LAYOUT_ONCE(NVKM_SUBDEV_THERM   , struct nvkm_therm   ,    therm)
 NVKM_LAYOUT_ONCE(NVKM_SUBDEV_CLK     , struct nvkm_clk     ,      clk)
 NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GSP     , struct nvkm_gsp     ,      gsp)
+
+NVKM_LAYOUT_ONCE(NVKM_ENGINE_BSP     , struct nvkm_engine  ,      bsp)
+NVKM_LAYOUT_ONCE(NVKM_ENGINE_VP      , struct nvkm_engine  ,       vp)
 
 #ifndef __NVKM_BSP_H__
 #define __NVKM_BSP_H__
 #include <engine/xtensa.h>
-int g84_bsp_new(struct nvkm_device *, int, struct nvkm_engine **);
+int g84_bsp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
 #endif
 
 #ifndef __NVKM_VP_H__
 #define __NVKM_VP_H__
 #include <engine/xtensa.h>
-int g84_vp_new(struct nvkm_device *, int, struct nvkm_engine **);
+int g84_vp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
 #endif
 
 };
 
 int nvkm_xtensa_new_(const struct nvkm_xtensa_func *, struct nvkm_device *,
-                    int index, bool enable, u32 addr, struct nvkm_engine **);
+                    enum nvkm_subdev_type, int, bool enable, u32 addr, struct nvkm_engine **);
 
 struct nvkm_xtensa_func {
        u32 fifo_val;
 
 };
 
 int
-nvkm_engine_ctor(const struct nvkm_engine_func *func,
-                struct nvkm_device *device, int index, bool enable,
-                struct nvkm_engine *engine)
+nvkm_engine_ctor_(const struct nvkm_engine_func *func, bool old, struct nvkm_device *device,
+                 enum nvkm_subdev_type type, int inst, bool enable, struct nvkm_engine *engine)
 {
-       nvkm_subdev_ctor(&nvkm_engine, device, index, &engine->subdev);
+       nvkm_subdev_ctor_(&nvkm_engine, old, device, type, inst, &engine->subdev);
        engine->func = func;
        refcount_set(&engine->use.refcount, 0);
        mutex_init(&engine->use.mutex);
 
 #include <core/layout.h>
 #undef NVKM_LAYOUT_ONCE
 #undef NVKM_LAYOUT_INST
-       [NVKM_ENGINE_BSP     ] = "bsp",
        [NVKM_ENGINE_CE0     ] = "ce0",
        [NVKM_ENGINE_CE1     ] = "ce1",
        [NVKM_ENGINE_CE2     ] = "ce2",
        [NVKM_ENGINE_SEC2    ] = "sec2",
        [NVKM_ENGINE_SW      ] = "sw",
        [NVKM_ENGINE_VIC     ] = "vic",
-       [NVKM_ENGINE_VP      ] = "vp",
 };
 
 void
 
 };
 
 int
-g84_bsp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine)
+g84_bsp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
+           struct nvkm_engine **pengine)
 {
-       return nvkm_xtensa_new_(&g84_bsp, device, index,
+       return nvkm_xtensa_new_(&g84_bsp, device, type, inst,
                                device->chipset != 0x92, 0x103000, pengine);
 }
 
        .therm    = { 0x00000001, g84_therm_new },
        .timer    = { 0x00000001, nv41_timer_new },
        .volt     = { 0x00000001, nv40_volt_new },
-       .bsp = g84_bsp_new,
+       .bsp      = { 0x00000001, g84_bsp_new },
        .cipher = g84_cipher_new,
        .disp = g84_disp_new,
        .dma = nv50_dma_new,
        .mpeg = g84_mpeg_new,
        .pm = g84_pm_new,
        .sw = nv50_sw_new,
-       .vp = g84_vp_new,
+       .vp       = { 0x00000001, g84_vp_new },
 };
 
 static const struct nvkm_device_chip
        .therm    = { 0x00000001, g84_therm_new },
        .timer    = { 0x00000001, nv41_timer_new },
        .volt     = { 0x00000001, nv40_volt_new },
-       .bsp = g84_bsp_new,
+       .bsp      = { 0x00000001, g84_bsp_new },
        .cipher = g84_cipher_new,
        .disp = g84_disp_new,
        .dma = nv50_dma_new,
        .mpeg = g84_mpeg_new,
        .pm = g84_pm_new,
        .sw = nv50_sw_new,
-       .vp = g84_vp_new,
+       .vp       = { 0x00000001, g84_vp_new },
 };
 
 static const struct nvkm_device_chip
        .therm    = { 0x00000001, g84_therm_new },
        .timer    = { 0x00000001, nv41_timer_new },
        .volt     = { 0x00000001, nv40_volt_new },
-       .bsp = g84_bsp_new,
+       .bsp      = { 0x00000001, g84_bsp_new },
        .cipher = g84_cipher_new,
        .disp = g84_disp_new,
        .dma = nv50_dma_new,
        .mpeg = g84_mpeg_new,
        .pm = g84_pm_new,
        .sw = nv50_sw_new,
-       .vp = g84_vp_new,
+       .vp       = { 0x00000001, g84_vp_new },
 };
 
 static const struct nvkm_device_chip
        .therm    = { 0x00000001, g84_therm_new },
        .timer    = { 0x00000001, nv41_timer_new },
        .volt     = { 0x00000001, nv40_volt_new },
-       .bsp = g84_bsp_new,
+       .bsp      = { 0x00000001, g84_bsp_new },
        .cipher = g84_cipher_new,
        .disp = g94_disp_new,
        .dma = nv50_dma_new,
        .mpeg = g84_mpeg_new,
        .pm = g84_pm_new,
        .sw = nv50_sw_new,
-       .vp = g84_vp_new,
+       .vp       = { 0x00000001, g84_vp_new },
 };
 
 static const struct nvkm_device_chip
        .therm    = { 0x00000001, g84_therm_new },
        .timer    = { 0x00000001, nv41_timer_new },
        .volt     = { 0x00000001, nv40_volt_new },
-       .bsp = g84_bsp_new,
+       .bsp      = { 0x00000001, g84_bsp_new },
        .cipher = g84_cipher_new,
        .disp = g94_disp_new,
        .dma = nv50_dma_new,
        .mpeg = g84_mpeg_new,
        .pm = g84_pm_new,
        .sw = nv50_sw_new,
-       .vp = g84_vp_new,
+       .vp       = { 0x00000001, g84_vp_new },
 };
 
 static const struct nvkm_device_chip
        .therm    = { 0x00000001, g84_therm_new },
        .timer    = { 0x00000001, nv41_timer_new },
        .volt     = { 0x00000001, nv40_volt_new },
-       .bsp = g84_bsp_new,
+       .bsp      = { 0x00000001, g84_bsp_new },
        .cipher = g84_cipher_new,
        .disp = gt200_disp_new,
        .dma = nv50_dma_new,
        .mpeg = g84_mpeg_new,
        .pm = gt200_pm_new,
        .sw = nv50_sw_new,
-       .vp = g84_vp_new,
+       .vp       = { 0x00000001, g84_vp_new },
 };
 
 static const struct nvkm_device_chip
 #include <core/layout.h>
 #undef NVKM_LAYOUT_INST
 #undef NVKM_LAYOUT_ONCE
-               _(NVKM_ENGINE_BSP     ,      bsp);
                _(NVKM_ENGINE_CE0     ,    ce[0]);
                _(NVKM_ENGINE_CE1     ,    ce[1]);
                _(NVKM_ENGINE_CE2     ,    ce[2]);
                _(NVKM_ENGINE_SEC2    ,     sec2);
                _(NVKM_ENGINE_SW      ,       sw);
                _(NVKM_ENGINE_VIC     ,      vic);
-               _(NVKM_ENGINE_VP      ,       vp);
                default:
                        WARN_ON(1);
                        continue;
 
 };
 
 int
-g84_vp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine)
+g84_vp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
+          struct nvkm_engine **pengine)
 {
-       return nvkm_xtensa_new_(&g84_vp, device, index,
-                               true, 0x00f000, pengine);
+       return nvkm_xtensa_new_(&g84_vp, device, type, inst, true, 0x00f000, pengine);
 }
 
 };
 
 int
-nvkm_xtensa_new_(const struct nvkm_xtensa_func *func,
-                struct nvkm_device *device, int index, bool enable,
-                u32 addr, struct nvkm_engine **pengine)
+nvkm_xtensa_new_(const struct nvkm_xtensa_func *func, struct nvkm_device *device,
+                enum nvkm_subdev_type type, int inst, bool enable, u32 addr,
+                struct nvkm_engine **pengine)
 {
        struct nvkm_xtensa *xtensa;
 
        xtensa->addr = addr;
        *pengine = &xtensa->engine;
 
-       return nvkm_engine_ctor(&nvkm_xtensa, device, index,
-                               enable, &xtensa->engine);
+       return nvkm_engine_ctor(&nvkm_xtensa, device, type, inst, enable, &xtensa->engine);
 }
 
 
        if (!(r001540 & 0x40000000)) {
                disable |= (1ULL << NVKM_ENGINE_MPEG);
-               disable |= (1ULL << NVKM_ENGINE_VP);
-               disable |= (1ULL << NVKM_ENGINE_BSP);
+               nvkm_subdev_disable(device, NVKM_ENGINE_VP, 0);
+               nvkm_subdev_disable(device, NVKM_ENGINE_BSP, 0);
                disable |= (1ULL << NVKM_ENGINE_CIPHER);
        }
 
        if (!(r00154c & 0x00000004))
                disable |= (1ULL << NVKM_ENGINE_DISP);
        if (!(r00154c & 0x00000020))
-               disable |= (1ULL << NVKM_ENGINE_BSP);
+               nvkm_subdev_disable(device, NVKM_ENGINE_BSP, 0);
        if (!(r00154c & 0x00000040))
                disable |= (1ULL << NVKM_ENGINE_CIPHER);