GT215, GF100-GP100, and GP10x are all different.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
 {
        struct nvkm_device *device = pmu->subdev.device;
 
-       if (!(nvkm_rd32(device, 0x000200) & 0x00002000))
+       if (!pmu->func->enabled(pmu))
                return 0;
 
        /* Inhibit interrupts, and wait for idle. */
 
        nvkm_mc_enable(device, NVKM_SUBDEV_PMU);
 }
 
+bool
+gf100_pmu_enabled(struct nvkm_pmu *pmu)
+{
+       return nvkm_mc_enabled(pmu->subdev.device, NVKM_SUBDEV_PMU);
+}
+
 static const struct nvkm_pmu_func
 gf100_pmu = {
        .code.data = gf100_pmu_code,
        .code.size = sizeof(gf100_pmu_code),
        .data.data = gf100_pmu_data,
        .data.size = sizeof(gf100_pmu_data),
+       .enabled = gf100_pmu_enabled,
        .reset = gf100_pmu_reset,
        .init = gt215_pmu_init,
        .fini = gt215_pmu_fini,
 
        .code.size = sizeof(gf119_pmu_code),
        .data.data = gf119_pmu_data,
        .data.size = sizeof(gf119_pmu_data),
+       .enabled = gf100_pmu_enabled,
        .reset = gf100_pmu_reset,
        .init = gt215_pmu_init,
        .fini = gt215_pmu_fini,
 
        .code.size = sizeof(gk104_pmu_code),
        .data.data = gk104_pmu_data,
        .data.size = sizeof(gk104_pmu_data),
+       .enabled = gf100_pmu_enabled,
        .reset = gf100_pmu_reset,
        .init = gt215_pmu_init,
        .fini = gt215_pmu_fini,
 
        .code.size = sizeof(gk110_pmu_code),
        .data.data = gk110_pmu_data,
        .data.size = sizeof(gk110_pmu_data),
+       .enabled = gf100_pmu_enabled,
        .reset = gf100_pmu_reset,
        .init = gt215_pmu_init,
        .fini = gt215_pmu_fini,
 
        .code.size = sizeof(gk208_pmu_code),
        .data.data = gk208_pmu_data,
        .data.size = sizeof(gk208_pmu_data),
+       .enabled = gf100_pmu_enabled,
        .reset = gf100_pmu_reset,
        .init = gt215_pmu_init,
        .fini = gt215_pmu_fini,
 
 
 static const struct nvkm_pmu_func
 gk20a_pmu = {
+       .enabled = gf100_pmu_enabled,
        .init = gk20a_pmu_init,
        .fini = gk20a_pmu_fini,
        .reset = gf100_pmu_reset,
 
        .code.size = sizeof(gm107_pmu_code),
        .data.data = gm107_pmu_data,
        .data.size = sizeof(gm107_pmu_data),
+       .enabled = gf100_pmu_enabled,
        .reset = gf100_pmu_reset,
        .init = gt215_pmu_init,
        .fini = gt215_pmu_fini,
 
 
 static const struct nvkm_pmu_func
 gm20b_pmu = {
+       .enabled = gf100_pmu_enabled,
        .intr = gt215_pmu_intr,
        .recv = gm20b_pmu_recv,
 };
 
 
 static const struct nvkm_pmu_func
 gp100_pmu = {
+       .enabled = gf100_pmu_enabled,
        .reset = gf100_pmu_reset,
 };
 
 
        nvkm_mask(device, 0x10a3c0, 0x00000001, 0x00000000);
 }
 
+static bool
+gp102_pmu_enabled(struct nvkm_pmu *pmu)
+{
+       return !(nvkm_rd32(pmu->subdev.device, 0x10a3c0) & 0x00000001);
+}
+
 static const struct nvkm_pmu_func
 gp102_pmu = {
+       .enabled = gp102_pmu_enabled,
        .reset = gp102_pmu_reset,
 };
 
 
        nvkm_rd32(device, 0x022210);
 }
 
+static bool
+gt215_pmu_enabled(struct nvkm_pmu *pmu)
+{
+       return nvkm_rd32(pmu->subdev.device, 0x022210) & 0x00000001;
+}
+
 int
 gt215_pmu_init(struct nvkm_pmu *pmu)
 {
        .code.size = sizeof(gt215_pmu_code),
        .data.data = gt215_pmu_data,
        .data.size = sizeof(gt215_pmu_data),
+       .enabled = gt215_pmu_enabled,
        .reset = gt215_pmu_reset,
        .init = gt215_pmu_init,
        .fini = gt215_pmu_fini,
 
                u32  size;
        } data;
 
+       bool (*enabled)(struct nvkm_pmu *);
        void (*reset)(struct nvkm_pmu *);
        int (*init)(struct nvkm_pmu *);
        void (*fini)(struct nvkm_pmu *);
 void gt215_pmu_recv(struct nvkm_pmu *);
 int gt215_pmu_send(struct nvkm_pmu *, u32[2], u32, u32, u32, u32);
 
+bool gf100_pmu_enabled(struct nvkm_pmu *);
 void gf100_pmu_reset(struct nvkm_pmu *);
 
 void gk110_pmu_pgob(struct nvkm_pmu *, bool);