drm/nouveau/pmu: rename from pwr (no binary change)

Switch to NVIDIA's name for the device.

The namespace of NVKM is being changed to nvkm_ instead of nouveau_,
which will be used for the DRM part of the driver.  This is being
done in order to make it very clear as to what part of the driver a
given symbol belongs to, and as a minor step towards splitting the
DRM driver out to be able to stand on its own (for virt).

Because there's already a large amount of churn here anyway, this is
as good a time as any to also switch to NVIDIA's device and chipset
naming to ease collaboration with them.

A comparison of objdump disassemblies proves no code changes.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index f9589e8..e141dff 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -222,7 +222,7 @@
 	[NVDEV_SUBDEV_BAR]	= NV_DEVICE_V0_DISABLE_CORE,
 	[NVDEV_SUBDEV_VOLT]	= NV_DEVICE_V0_DISABLE_CORE,
 	[NVDEV_SUBDEV_THERM]	= NV_DEVICE_V0_DISABLE_CORE,
-	[NVDEV_SUBDEV_PWR]	= NV_DEVICE_V0_DISABLE_CORE,
+	[NVDEV_SUBDEV_PMU]	= NV_DEVICE_V0_DISABLE_CORE,
 	[NVDEV_SUBDEV_FUSE]	= NV_DEVICE_V0_DISABLE_CORE,
 	[NVDEV_ENGINE_DMAOBJ]	= NV_DEVICE_V0_DISABLE_CORE,
 	[NVDEV_ENGINE_PERFMON]  = NV_DEVICE_V0_DISABLE_CORE,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c
index e453a52..763572f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/gm100.c
@@ -39,7 +39,7 @@
 #include <subdev/instmem.h>
 #include <subdev/vm.h>
 #include <subdev/bar.h>
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
 #include <subdev/volt.h>
 
 #include <engine/device.h>
@@ -77,7 +77,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nv108_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nv108_pmu_oclass;
 
 #if 0
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
@@ -121,7 +121,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nv108_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nv108_pmu_oclass;
 #if 0
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c
index ccf82ab..867b79a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nv50.c
@@ -37,7 +37,7 @@
 #include <subdev/instmem.h>
 #include <subdev/vm.h>
 #include <subdev/bar.h>
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
 #include <subdev/volt.h>
 
 #include <engine/device.h>
@@ -362,7 +362,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nv50_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nv50_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nva3_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nva3_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv84_fifo_oclass;
@@ -393,7 +393,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nv50_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nv50_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nva3_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nva3_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv84_fifo_oclass;
@@ -423,7 +423,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nv50_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nv50_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nva3_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nva3_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv84_fifo_oclass;
@@ -453,7 +453,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nv50_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nv50_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nva3_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nva3_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nv50_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv84_fifo_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nvc0.c
index ff5b2ab..d54d6ac 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nvc0.c
@@ -39,7 +39,7 @@
 #include <subdev/instmem.h>
 #include <subdev/vm.h>
 #include <subdev/bar.h>
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
 #include <subdev/volt.h>
 
 #include <engine/device.h>
@@ -77,7 +77,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvc0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvc0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
@@ -110,7 +110,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvc0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvc0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
@@ -143,7 +143,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvc0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvc0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
@@ -175,7 +175,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvc0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvc0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
@@ -208,7 +208,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvc0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvc0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
@@ -240,7 +240,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvc0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvc0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
@@ -272,7 +272,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvc0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvc0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
@@ -305,7 +305,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvd0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvd0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/nve0.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/nve0.c
index 7c02ff5..39b3fe3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/nve0.c
@@ -39,7 +39,7 @@
 #include <subdev/instmem.h>
 #include <subdev/vm.h>
 #include <subdev/bar.h>
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
 #include <subdev/volt.h>
 
 #include <engine/device.h>
@@ -77,7 +77,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  gk104_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk104_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nve0_fifo_oclass;
@@ -111,7 +111,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvd0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvd0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nve0_fifo_oclass;
@@ -145,7 +145,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  gk104_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk104_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nve0_fifo_oclass;
@@ -180,7 +180,7 @@
 		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &gk20a_volt_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  gk20a_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  gk20a_pmu_oclass;
 		break;
 	case 0xf0:
 		device->cname = "GK110";
@@ -201,7 +201,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvd0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvd0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nve0_fifo_oclass;
@@ -235,7 +235,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nvd0_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nvd0_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nve0_fifo_oclass;
@@ -269,7 +269,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nv108_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nv108_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv108_fifo_oclass;
@@ -302,7 +302,7 @@
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
 		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
-		device->oclass[NVDEV_SUBDEV_PWR    ] =  nv108_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_PMU    ] =  nv108_pmu_oclass;
 		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] =  nvd0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv108_fifo_oclass;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/graph/nve4.c b/drivers/gpu/drm/nouveau/nvkm/engine/graph/nve4.c
index 83a966f..8e6b62c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/graph/nve4.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/graph/nve4.c
@@ -22,7 +22,7 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
 
 #include "nvc0.h"
 #include "ctxnvc0.h"
@@ -196,15 +196,15 @@
 {
 	struct nvc0_graph_oclass *oclass = (void *)object->oclass;
 	struct nvc0_graph_priv *priv = (void *)object;
-	struct nouveau_pwr *ppwr = nouveau_pwr(priv);
+	struct nouveau_pmu *pmu = nouveau_pmu(priv);
 	const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
 	u32 data[TPC_MAX / 8] = {};
 	u8  tpcnr[GPC_MAX];
 	int gpc, tpc, rop;
 	int ret, i;
 
-	if (ppwr)
-		ppwr->pgob(ppwr, false);
+	if (pmu)
+		pmu->pgob(pmu, false);
 
 	ret = nouveau_graph_init(&priv->base);
 	if (ret)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild
index 39f800a..55090f7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild
@@ -12,7 +12,7 @@
 include $(src)/nvkm/subdev/ltc/Kbuild
 include $(src)/nvkm/subdev/mc/Kbuild
 include $(src)/nvkm/subdev/mxm/Kbuild
-include $(src)/nvkm/subdev/pwr/Kbuild
+include $(src)/nvkm/subdev/pmu/Kbuild
 include $(src)/nvkm/subdev/therm/Kbuild
 include $(src)/nvkm/subdev/timer/Kbuild
 include $(src)/nvkm/subdev/vm/Kbuild
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
index 0ac7256..f641f3a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
@@ -1,7 +1,7 @@
 #ifndef __NVKM_FBRAM_FUC_H__
 #define __NVKM_FBRAM_FUC_H__
 
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
 
 struct ramfuc {
 	struct nouveau_memx *memx;
@@ -57,10 +57,10 @@
 static inline int
 ramfuc_init(struct ramfuc *ram, struct nouveau_fb *pfb)
 {
-	struct nouveau_pwr *ppwr = nouveau_pwr(pfb);
+	struct nouveau_pmu *pmu = nouveau_pmu(pfb);
 	int ret;
 
-	ret = nouveau_memx_init(ppwr, &ram->memx);
+	ret = nouveau_memx_init(pmu, &ram->memx);
 	if (ret)
 		return ret;
 
@@ -149,9 +149,9 @@
 static inline int
 ramfuc_train_result(struct nouveau_fb *pfb, u32 *result, u32 rsize)
 {
-	struct nouveau_pwr *ppwr = nouveau_pwr(pfb);
+	struct nouveau_pmu *pmu = nouveau_pmu(pfb);
 
-	return nouveau_memx_train_result(ppwr, result, rsize);
+	return nouveau_memx_train_result(pmu, result, rsize);
 }
 
 static inline void
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv98.c
index 3c76d90..aa1c690 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv98.c
@@ -33,7 +33,7 @@
 	{ 0x00004000, NVDEV_ENGINE_CRYPT },	/* NV84:NVA3 */
 	{ 0x00008000, NVDEV_ENGINE_BSP },
 	{ 0x00020000, NVDEV_ENGINE_VP },
-	{ 0x00040000, NVDEV_SUBDEV_PWR },	/* NVA3:NVC0 */
+	{ 0x00040000, NVDEV_SUBDEV_PMU },	/* NVA3:NVC0 */
 	{ 0x00080000, NVDEV_SUBDEV_THERM },	/* NVA3:NVC0 */
 	{ 0x00100000, NVDEV_SUBDEV_TIMER },
 	{ 0x00200000, NVDEV_SUBDEV_GPIO },	/* PMGR->GPIO */
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nvc0.c
index 15d41dc..7053ae3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nvc0.c
@@ -40,7 +40,7 @@
 	{ 0x00100000, NVDEV_SUBDEV_TIMER },
 	{ 0x00200000, NVDEV_SUBDEV_GPIO },	/* PMGR->GPIO */
 	{ 0x00200000, NVDEV_SUBDEV_I2C },	/* PMGR->I2C/AUX */
-	{ 0x01000000, NVDEV_SUBDEV_PWR },
+	{ 0x01000000, NVDEV_SUBDEV_PMU },
 	{ 0x02000000, NVDEV_SUBDEV_LTC },
 	{ 0x08000000, NVDEV_SUBDEV_FB },
 	{ 0x10000000, NVDEV_SUBDEV_BUS },
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild
new file mode 100644
index 0000000..85c8392
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/Kbuild
@@ -0,0 +1,8 @@
+nvkm-y += nvkm/subdev/pmu/base.o
+nvkm-y += nvkm/subdev/pmu/memx.o
+nvkm-y += nvkm/subdev/pmu/nva3.o
+nvkm-y += nvkm/subdev/pmu/nvc0.o
+nvkm-y += nvkm/subdev/pmu/nvd0.o
+nvkm-y += nvkm/subdev/pmu/gk104.o
+nvkm-y += nvkm/subdev/pmu/nv108.o
+nvkm-y += nvkm/subdev/pmu/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
new file mode 100644
index 0000000..562ea6e
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/timer.h>
+
+#include "priv.h"
+
+void
+nouveau_pmu_pgob(struct nouveau_pmu *pmu, bool enable)
+{
+	const struct nvkm_pmu_impl *impl = (void *)nv_oclass(pmu);
+	if (impl->pgob)
+		impl->pgob(pmu, enable);
+}
+
+static int
+nouveau_pmu_send(struct nouveau_pmu *pmu, u32 reply[2],
+		 u32 process, u32 message, u32 data0, u32 data1)
+{
+	struct nouveau_subdev *subdev = nv_subdev(pmu);
+	u32 addr;
+
+	/* wait for a free slot in the fifo */
+	addr  = nv_rd32(pmu, 0x10a4a0);
+	if (!nv_wait_ne(pmu, 0x10a4b0, 0xffffffff, addr ^ 8))
+		return -EBUSY;
+
+	/* we currently only support a single process at a time waiting
+	 * on a synchronous reply, take the PMU mutex and tell the
+	 * receive handler what we're waiting for
+	 */
+	if (reply) {
+		mutex_lock(&subdev->mutex);
+		pmu->recv.message = message;
+		pmu->recv.process = process;
+	}
+
+	/* acquire data segment access */
+	do {
+		nv_wr32(pmu, 0x10a580, 0x00000001);
+	} while (nv_rd32(pmu, 0x10a580) != 0x00000001);
+
+	/* write the packet */
+	nv_wr32(pmu, 0x10a1c0, 0x01000000 | (((addr & 0x07) << 4) +
+				pmu->send.base));
+	nv_wr32(pmu, 0x10a1c4, process);
+	nv_wr32(pmu, 0x10a1c4, message);
+	nv_wr32(pmu, 0x10a1c4, data0);
+	nv_wr32(pmu, 0x10a1c4, data1);
+	nv_wr32(pmu, 0x10a4a0, (addr + 1) & 0x0f);
+
+	/* release data segment access */
+	nv_wr32(pmu, 0x10a580, 0x00000000);
+
+	/* wait for reply, if requested */
+	if (reply) {
+		wait_event(pmu->recv.wait, (pmu->recv.process == 0));
+		reply[0] = pmu->recv.data[0];
+		reply[1] = pmu->recv.data[1];
+		mutex_unlock(&subdev->mutex);
+	}
+
+	return 0;
+}
+
+static void
+nouveau_pmu_recv(struct work_struct *work)
+{
+	struct nouveau_pmu *pmu =
+		container_of(work, struct nouveau_pmu, recv.work);
+	u32 process, message, data0, data1;
+
+	/* nothing to do if GET == PUT */
+	u32 addr =  nv_rd32(pmu, 0x10a4cc);
+	if (addr == nv_rd32(pmu, 0x10a4c8))
+		return;
+
+	/* acquire data segment access */
+	do {
+		nv_wr32(pmu, 0x10a580, 0x00000002);
+	} while (nv_rd32(pmu, 0x10a580) != 0x00000002);
+
+	/* read the packet */
+	nv_wr32(pmu, 0x10a1c0, 0x02000000 | (((addr & 0x07) << 4) +
+				pmu->recv.base));
+	process = nv_rd32(pmu, 0x10a1c4);
+	message = nv_rd32(pmu, 0x10a1c4);
+	data0   = nv_rd32(pmu, 0x10a1c4);
+	data1   = nv_rd32(pmu, 0x10a1c4);
+	nv_wr32(pmu, 0x10a4cc, (addr + 1) & 0x0f);
+
+	/* release data segment access */
+	nv_wr32(pmu, 0x10a580, 0x00000000);
+
+	/* wake process if it's waiting on a synchronous reply */
+	if (pmu->recv.process) {
+		if (process == pmu->recv.process &&
+		    message == pmu->recv.message) {
+			pmu->recv.data[0] = data0;
+			pmu->recv.data[1] = data1;
+			pmu->recv.process = 0;
+			wake_up(&pmu->recv.wait);
+			return;
+		}
+	}
+
+	/* right now there's no other expected responses from the engine,
+	 * so assume that any unexpected message is an error.
+	 */
+	nv_warn(pmu, "%c%c%c%c 0x%08x 0x%08x 0x%08x 0x%08x\n",
+		(char)((process & 0x000000ff) >>  0),
+		(char)((process & 0x0000ff00) >>  8),
+		(char)((process & 0x00ff0000) >> 16),
+		(char)((process & 0xff000000) >> 24),
+		process, message, data0, data1);
+}
+
+static void
+nouveau_pmu_intr(struct nouveau_subdev *subdev)
+{
+	struct nouveau_pmu *pmu = (void *)subdev;
+	u32 disp = nv_rd32(pmu, 0x10a01c);
+	u32 intr = nv_rd32(pmu, 0x10a008) & disp & ~(disp >> 16);
+
+	if (intr & 0x00000020) {
+		u32 stat = nv_rd32(pmu, 0x10a16c);
+		if (stat & 0x80000000) {
+			nv_error(pmu, "UAS fault at 0x%06x addr 0x%08x\n",
+				 stat & 0x00ffffff, nv_rd32(pmu, 0x10a168));
+			nv_wr32(pmu, 0x10a16c, 0x00000000);
+			intr &= ~0x00000020;
+		}
+	}
+
+	if (intr & 0x00000040) {
+		schedule_work(&pmu->recv.work);
+		nv_wr32(pmu, 0x10a004, 0x00000040);
+		intr &= ~0x00000040;
+	}
+
+	if (intr & 0x00000080) {
+		nv_info(pmu, "wr32 0x%06x 0x%08x\n", nv_rd32(pmu, 0x10a7a0),
+						      nv_rd32(pmu, 0x10a7a4));
+		nv_wr32(pmu, 0x10a004, 0x00000080);
+		intr &= ~0x00000080;
+	}
+
+	if (intr) {
+		nv_error(pmu, "intr 0x%08x\n", intr);
+		nv_wr32(pmu, 0x10a004, intr);
+	}
+}
+
+int
+_nouveau_pmu_fini(struct nouveau_object *object, bool suspend)
+{
+	struct nouveau_pmu *pmu = (void *)object;
+
+	nv_wr32(pmu, 0x10a014, 0x00000060);
+	flush_work(&pmu->recv.work);
+
+	return nouveau_subdev_fini(&pmu->base, suspend);
+}
+
+int
+_nouveau_pmu_init(struct nouveau_object *object)
+{
+	const struct nvkm_pmu_impl *impl = (void *)object->oclass;
+	struct nouveau_pmu *pmu = (void *)object;
+	int ret, i;
+
+	ret = nouveau_subdev_init(&pmu->base);
+	if (ret)
+		return ret;
+
+	nv_subdev(pmu)->intr = nouveau_pmu_intr;
+	pmu->message = nouveau_pmu_send;
+	pmu->pgob = nouveau_pmu_pgob;
+
+	/* prevent previous ucode from running, wait for idle, reset */
+	nv_wr32(pmu, 0x10a014, 0x0000ffff); /* INTR_EN_CLR = ALL */
+	nv_wait(pmu, 0x10a04c, 0xffffffff, 0x00000000);
+	nv_mask(pmu, 0x000200, 0x00002000, 0x00000000);
+	nv_mask(pmu, 0x000200, 0x00002000, 0x00002000);
+	nv_rd32(pmu, 0x000200);
+	nv_wait(pmu, 0x10a10c, 0x00000006, 0x00000000);
+
+	/* upload data segment */
+	nv_wr32(pmu, 0x10a1c0, 0x01000000);
+	for (i = 0; i < impl->data.size / 4; i++)
+		nv_wr32(pmu, 0x10a1c4, impl->data.data[i]);
+
+	/* upload code segment */
+	nv_wr32(pmu, 0x10a180, 0x01000000);
+	for (i = 0; i < impl->code.size / 4; i++) {
+		if ((i & 0x3f) == 0)
+			nv_wr32(pmu, 0x10a188, i >> 6);
+		nv_wr32(pmu, 0x10a184, impl->code.data[i]);
+	}
+
+	/* start it running */
+	nv_wr32(pmu, 0x10a10c, 0x00000000);
+	nv_wr32(pmu, 0x10a104, 0x00000000);
+	nv_wr32(pmu, 0x10a100, 0x00000002);
+
+	/* wait for valid host->pmu ring configuration */
+	if (!nv_wait_ne(pmu, 0x10a4d0, 0xffffffff, 0x00000000))
+		return -EBUSY;
+	pmu->send.base = nv_rd32(pmu, 0x10a4d0) & 0x0000ffff;
+	pmu->send.size = nv_rd32(pmu, 0x10a4d0) >> 16;
+
+	/* wait for valid pmu->host ring configuration */
+	if (!nv_wait_ne(pmu, 0x10a4dc, 0xffffffff, 0x00000000))
+		return -EBUSY;
+	pmu->recv.base = nv_rd32(pmu, 0x10a4dc) & 0x0000ffff;
+	pmu->recv.size = nv_rd32(pmu, 0x10a4dc) >> 16;
+
+	nv_wr32(pmu, 0x10a010, 0x000000e0);
+	return 0;
+}
+
+int
+nouveau_pmu_create_(struct nouveau_object *parent,
+		    struct nouveau_object *engine,
+		    struct nouveau_oclass *oclass, int length, void **pobject)
+{
+	struct nouveau_pmu *pmu;
+	int ret;
+
+	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PMU",
+				     "pmu", length, pobject);
+	pmu = *pobject;
+	if (ret)
+		return ret;
+
+	INIT_WORK(&pmu->recv.work, nouveau_pmu_recv);
+	init_waitqueue_head(&pmu->recv.wait);
+	return 0;
+}
+
+int
+_nouveau_pmu_ctor(struct nouveau_object *parent,
+		  struct nouveau_object *engine,
+		  struct nouveau_oclass *oclass, void *data, u32 size,
+		  struct nouveau_object **pobject)
+{
+	struct nouveau_pmu *pmu;
+	int ret = nouveau_pmu_create(parent, engine, oclass, &pmu);
+	*pobject = nv_object(pmu);
+	return ret;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/arith.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/arith.fuc
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/arith.fuc
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/arith.fuc
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/host.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/host.fuc
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/host.fuc
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/host.fuc
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/i2c_.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/i2c_.fuc
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/i2c_.fuc
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/i2c_.fuc
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/idle.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/idle.fuc
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/idle.fuc
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/idle.fuc
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/kernel.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/kernel.fuc
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/kernel.fuc
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/kernel.fuc
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/macros.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/macros.fuc
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/macros.fuc
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/memx.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/memx.fuc
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/memx.fuc
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/memx.fuc
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nv108.fuc5 b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nv108.fuc5
similarity index 97%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nv108.fuc5
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nv108.fuc5
index b439519..d2214ab 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nv108.fuc5
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nv108.fuc5
@@ -32,7 +32,7 @@
 
 #include "macros.fuc"
 
-.section #nv108_pwr_data
+.section #nv108_pmu_data
 #define INCLUDE_PROC
 #include "kernel.fuc"
 #include "arith.fuc"
@@ -56,7 +56,7 @@
 #undef INCLUDE_DATA
 .align 256
 
-.section #nv108_pwr_code
+.section #nv108_pmu_code
 #define INCLUDE_CODE
 #include "kernel.fuc"
 #include "arith.fuc"
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nv108.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nv108.fuc5.h
similarity index 99%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nv108.fuc5.h
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nv108.fuc5.h
index 713e11e..c25ee1f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nv108.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nv108.fuc5.h
@@ -1,4 +1,4 @@
-uint32_t nv108_pwr_data[] = {
+uint32_t nv108_pmu_data[] = {
 /* 0x0000: proc_kern */
 	0x52544e49,
 	0x00000000,
@@ -915,7 +915,7 @@
 	0x00000000,
 };
 
-uint32_t nv108_pwr_code[] = {
+uint32_t nv108_pmu_code[] = {
 	0x031c0ef5,
 /* 0x0004: rd32 */
 	0xf607a040,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nva3.fuc3 b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nva3.fuc3
similarity index 97%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nva3.fuc3
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nva3.fuc3
index daa06c1..93d7617 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nva3.fuc3
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nva3.fuc3
@@ -32,7 +32,7 @@
 
 #include "macros.fuc"
 
-.section #nva3_pwr_data
+.section #nva3_pmu_data
 #define INCLUDE_PROC
 #include "kernel.fuc"
 #include "arith.fuc"
@@ -56,7 +56,7 @@
 #undef INCLUDE_DATA
 .align 256
 
-.section #nva3_pwr_code
+.section #nva3_pmu_code
 #define INCLUDE_CODE
 #include "kernel.fuc"
 #include "arith.fuc"
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nva3.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nva3.fuc3.h
similarity index 99%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nva3.fuc3.h
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nva3.fuc3.h
index d1f9b6c..e827440 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nva3.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nva3.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nva3_pwr_data[] = {
+uint32_t nva3_pmu_data[] = {
 /* 0x0000: proc_kern */
 	0x52544e49,
 	0x00000000,
@@ -916,7 +916,7 @@
 	0x00000000,
 };
 
-uint32_t nva3_pwr_code[] = {
+uint32_t nva3_pmu_code[] = {
 	0x039e0ef5,
 /* 0x0004: rd32 */
 	0x07a007f1,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvc0.fuc3 b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvc0.fuc3
similarity index 97%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvc0.fuc3
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvc0.fuc3
index 21bf8cc..6eee93d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvc0.fuc3
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvc0.fuc3
@@ -32,7 +32,7 @@
 
 #include "macros.fuc"
 
-.section #nvc0_pwr_data
+.section #nvc0_pmu_data
 #define INCLUDE_PROC
 #include "kernel.fuc"
 #include "arith.fuc"
@@ -56,7 +56,7 @@
 #undef INCLUDE_DATA
 .align 256
 
-.section #nvc0_pwr_code
+.section #nvc0_pmu_code
 #define INCLUDE_CODE
 #include "kernel.fuc"
 #include "arith.fuc"
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvc0.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvc0.fuc3.h
similarity index 99%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvc0.fuc3.h
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvc0.fuc3.h
index 90221d9..124f5c1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvc0.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvc0.fuc3.h
@@ -1,4 +1,4 @@
-uint32_t nvc0_pwr_data[] = {
+uint32_t nvc0_pmu_data[] = {
 /* 0x0000: proc_kern */
 	0x52544e49,
 	0x00000000,
@@ -916,7 +916,7 @@
 	0x00000000,
 };
 
-uint32_t nvc0_pwr_code[] = {
+uint32_t nvc0_pmu_code[] = {
 	0x039e0ef5,
 /* 0x0004: rd32 */
 	0x07a007f1,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvd0.fuc4 b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvd0.fuc4
similarity index 97%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvd0.fuc4
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvd0.fuc4
index b854432..e11f993 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvd0.fuc4
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvd0.fuc4
@@ -32,7 +32,7 @@
 
 #include "macros.fuc"
 
-.section #nvd0_pwr_data
+.section #nvd0_pmu_data
 #define INCLUDE_PROC
 #include "kernel.fuc"
 #include "arith.fuc"
@@ -56,7 +56,7 @@
 #undef INCLUDE_DATA
 .align 256
 
-.section #nvd0_pwr_code
+.section #nvd0_pmu_code
 #define INCLUDE_CODE
 #include "kernel.fuc"
 #include "arith.fuc"
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvd0.fuc4.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvd0.fuc4.h
similarity index 99%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvd0.fuc4.h
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvd0.fuc4.h
index 7e16aab..6fc8c70 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/nvd0.fuc4.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/nvd0.fuc4.h
@@ -1,4 +1,4 @@
-uint32_t nvd0_pwr_data[] = {
+uint32_t nvd0_pmu_data[] = {
 /* 0x0000: proc_kern */
 	0x52544e49,
 	0x00000000,
@@ -915,7 +915,7 @@
 	0x00000000,
 };
 
-uint32_t nvd0_pwr_code[] = {
+uint32_t nvd0_pmu_code[] = {
 	0x034d0ef5,
 /* 0x0004: rd32 */
 	0x07a007f1,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/os.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/os.h
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/os.h
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/os.h
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/perf.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/perf.fuc
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/perf.fuc
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/test.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/test.fuc
similarity index 100%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/fuc/test.fuc
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/test.fuc
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
new file mode 100644
index 0000000..7776b4a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "priv.h"
+
+#define nvd0_pmu_code gk104_pmu_code
+#define nvd0_pmu_data gk104_pmu_data
+#include "fuc/nvd0.fuc4.h"
+
+static void
+gk104_pmu_pgob(struct nouveau_pmu *pmu, bool enable)
+{
+	nv_mask(pmu, 0x000200, 0x00001000, 0x00000000);
+	nv_rd32(pmu, 0x000200);
+	nv_mask(pmu, 0x000200, 0x08000000, 0x08000000);
+	msleep(50);
+
+	nv_mask(pmu, 0x10a78c, 0x00000002, 0x00000002);
+	nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001);
+	nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000);
+
+	nv_mask(pmu, 0x020004, 0xc0000000, enable ? 0xc0000000 : 0x40000000);
+	msleep(50);
+
+	nv_mask(pmu, 0x10a78c, 0x00000002, 0x00000000);
+	nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001);
+	nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000);
+
+	nv_mask(pmu, 0x000200, 0x08000000, 0x00000000);
+	nv_mask(pmu, 0x000200, 0x00001000, 0x00001000);
+	nv_rd32(pmu, 0x000200);
+}
+
+struct nouveau_oclass *
+gk104_pmu_oclass = &(struct nvkm_pmu_impl) {
+	.base.handle = NV_SUBDEV(PMU, 0xe4),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = _nouveau_pmu_ctor,
+		.dtor = _nouveau_pmu_dtor,
+		.init = _nouveau_pmu_init,
+		.fini = _nouveau_pmu_fini,
+	},
+	.code.data = gk104_pmu_code,
+	.code.size = sizeof(gk104_pmu_code),
+	.data.data = gk104_pmu_data,
+	.data.size = sizeof(gk104_pmu_data),
+	.pgob = gk104_pmu_pgob,
+}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
similarity index 64%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/gk20a.c
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index a4e3a9b..28d858a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -28,27 +28,27 @@
 #define BUSY_SLOT	0
 #define CLK_SLOT	7
 
-struct gk20a_pwr_dvfs_data {
+struct gk20a_pmu_dvfs_data {
 	int p_load_target;
 	int p_load_max;
 	int p_smooth;
 	unsigned int avg_load;
 };
 
-struct gk20a_pwr_priv {
-	struct nouveau_pwr base;
+struct gk20a_pmu_priv {
+	struct nouveau_pmu base;
 	struct nouveau_alarm alarm;
-	struct gk20a_pwr_dvfs_data *data;
+	struct gk20a_pmu_dvfs_data *data;
 };
 
-struct gk20a_pwr_dvfs_dev_status {
+struct gk20a_pmu_dvfs_dev_status {
 	unsigned long total;
 	unsigned long busy;
 	int cur_state;
 };
 
 static int
-gk20a_pwr_dvfs_target(struct gk20a_pwr_priv *priv, int *state)
+gk20a_pmu_dvfs_target(struct gk20a_pmu_priv *priv, int *state)
 {
 	struct nouveau_clk *clk = nouveau_clk(priv);
 
@@ -56,7 +56,7 @@
 }
 
 static int
-gk20a_pwr_dvfs_get_cur_state(struct gk20a_pwr_priv *priv, int *state)
+gk20a_pmu_dvfs_get_cur_state(struct gk20a_pmu_priv *priv, int *state)
 {
 	struct nouveau_clk *clk = nouveau_clk(priv);
 
@@ -65,10 +65,10 @@
 }
 
 static int
-gk20a_pwr_dvfs_get_target_state(struct gk20a_pwr_priv *priv,
+gk20a_pmu_dvfs_get_target_state(struct gk20a_pmu_priv *priv,
 		int *state, int load)
 {
-	struct gk20a_pwr_dvfs_data *data = priv->data;
+	struct gk20a_pmu_dvfs_data *data = priv->data;
 	struct nouveau_clk *clk = nouveau_clk(priv);
 	int cur_level, level;
 
@@ -95,8 +95,8 @@
 }
 
 static int
-gk20a_pwr_dvfs_get_dev_status(struct gk20a_pwr_priv *priv,
-		struct gk20a_pwr_dvfs_dev_status *status)
+gk20a_pmu_dvfs_get_dev_status(struct gk20a_pmu_priv *priv,
+		struct gk20a_pmu_dvfs_dev_status *status)
 {
 	status->busy = nv_rd32(priv, 0x10a508 + (BUSY_SLOT * 0x10));
 	status->total= nv_rd32(priv, 0x10a508 + (CLK_SLOT * 0x10));
@@ -104,32 +104,32 @@
 }
 
 static void
-gk20a_pwr_dvfs_reset_dev_status(struct gk20a_pwr_priv *priv)
+gk20a_pmu_dvfs_reset_dev_status(struct gk20a_pmu_priv *priv)
 {
 	nv_wr32(priv, 0x10a508 + (BUSY_SLOT * 0x10), 0x80000000);
 	nv_wr32(priv, 0x10a508 + (CLK_SLOT * 0x10), 0x80000000);
 }
 
 static void
-gk20a_pwr_dvfs_work(struct nouveau_alarm *alarm)
+gk20a_pmu_dvfs_work(struct nouveau_alarm *alarm)
 {
-	struct gk20a_pwr_priv *priv = container_of(alarm,
-					struct gk20a_pwr_priv, alarm);
-	struct gk20a_pwr_dvfs_data *data = priv->data;
-	struct gk20a_pwr_dvfs_dev_status status;
+	struct gk20a_pmu_priv *priv = container_of(alarm,
+					struct gk20a_pmu_priv, alarm);
+	struct gk20a_pmu_dvfs_data *data = priv->data;
+	struct gk20a_pmu_dvfs_dev_status status;
 	struct nouveau_clk *clk = nouveau_clk(priv);
 	struct nouveau_volt *volt = nouveau_volt(priv);
 	u32 utilization = 0;
 	int state, ret;
 
 	/*
-	 * The PWR is initialized before CLK and VOLT, so we have to make sure the
+	 * The PMU is initialized before CLK and VOLT, so we have to make sure the
 	 * CLK and VOLT are ready here.
 	 */
 	if (!clk || !volt)
 		goto resched;
 
-	ret = gk20a_pwr_dvfs_get_dev_status(priv, &status);
+	ret = gk20a_pmu_dvfs_get_dev_status(priv, &status);
 	if (ret) {
 		nv_warn(priv, "failed to get device status\n");
 		goto resched;
@@ -143,90 +143,90 @@
 	nv_trace(priv, "utilization = %d %%, avg_load = %d %%\n",
 			utilization, data->avg_load);
 
-	ret = gk20a_pwr_dvfs_get_cur_state(priv, &state);
+	ret = gk20a_pmu_dvfs_get_cur_state(priv, &state);
 	if (ret) {
 		nv_warn(priv, "failed to get current state\n");
 		goto resched;
 	}
 
-	if (gk20a_pwr_dvfs_get_target_state(priv, &state, data->avg_load)) {
+	if (gk20a_pmu_dvfs_get_target_state(priv, &state, data->avg_load)) {
 		nv_trace(priv, "set new state to %d\n", state);
-		gk20a_pwr_dvfs_target(priv, &state);
+		gk20a_pmu_dvfs_target(priv, &state);
 	}
 
 resched:
-	gk20a_pwr_dvfs_reset_dev_status(priv);
+	gk20a_pmu_dvfs_reset_dev_status(priv);
 	nouveau_timer_alarm(priv, 100000000, alarm);
 }
 
 int
-gk20a_pwr_fini(struct nouveau_object *object, bool suspend)
+gk20a_pmu_fini(struct nouveau_object *object, bool suspend)
 {
-	struct nouveau_pwr *ppwr = (void *)object;
-	struct gk20a_pwr_priv *priv = (void *)ppwr;
+	struct nouveau_pmu *pmu = (void *)object;
+	struct gk20a_pmu_priv *priv = (void *)pmu;
 
 	nouveau_timer_alarm_cancel(priv, &priv->alarm);
 
-	return nouveau_subdev_fini(&ppwr->base, suspend);
+	return nouveau_subdev_fini(&pmu->base, suspend);
 }
 
 int
-gk20a_pwr_init(struct nouveau_object *object)
+gk20a_pmu_init(struct nouveau_object *object)
 {
-	struct nouveau_pwr *ppwr = (void *)object;
-	struct gk20a_pwr_priv *priv = (void *)ppwr;
+	struct nouveau_pmu *pmu = (void *)object;
+	struct gk20a_pmu_priv *priv = (void *)pmu;
 	int ret;
 
-	ret = nouveau_subdev_init(&ppwr->base);
+	ret = nouveau_subdev_init(&pmu->base);
 	if (ret)
 		return ret;
 
-	ppwr->pgob = nouveau_pwr_pgob;
+	pmu->pgob = nouveau_pmu_pgob;
 
 	/* init pwr perf counter */
-	nv_wr32(ppwr, 0x10a504 + (BUSY_SLOT * 0x10), 0x00200001);
-	nv_wr32(ppwr, 0x10a50c + (BUSY_SLOT * 0x10), 0x00000002);
-	nv_wr32(ppwr, 0x10a50c + (CLK_SLOT * 0x10), 0x00000003);
+	nv_wr32(pmu, 0x10a504 + (BUSY_SLOT * 0x10), 0x00200001);
+	nv_wr32(pmu, 0x10a50c + (BUSY_SLOT * 0x10), 0x00000002);
+	nv_wr32(pmu, 0x10a50c + (CLK_SLOT * 0x10), 0x00000003);
 
-	nouveau_timer_alarm(ppwr, 2000000000, &priv->alarm);
+	nouveau_timer_alarm(pmu, 2000000000, &priv->alarm);
 
 	return ret;
 }
 
-struct gk20a_pwr_dvfs_data gk20a_dvfs_data= {
+struct gk20a_pmu_dvfs_data gk20a_dvfs_data= {
 	.p_load_target = 70,
 	.p_load_max = 90,
 	.p_smooth = 1,
 };
 
 static int
-gk20a_pwr_ctor(struct nouveau_object *parent,
+gk20a_pmu_ctor(struct nouveau_object *parent,
 		  struct nouveau_object *engine,
 		  struct nouveau_oclass *oclass, void *data, u32 size,
 		  struct nouveau_object **pobject)
 {
-	struct gk20a_pwr_priv *priv;
+	struct gk20a_pmu_priv *priv;
 	int ret;
 
-	ret = nouveau_pwr_create(parent, engine, oclass, &priv);
+	ret = nouveau_pmu_create(parent, engine, oclass, &priv);
 	*pobject = nv_object(priv);
 	if (ret)
 		return ret;
 
 	priv->data = &gk20a_dvfs_data;
 
-	nouveau_alarm_init(&priv->alarm, gk20a_pwr_dvfs_work);
+	nouveau_alarm_init(&priv->alarm, gk20a_pmu_dvfs_work);
 
 	return 0;
 }
 
 struct nouveau_oclass *
-gk20a_pwr_oclass = &(struct nvkm_pwr_impl) {
-	.base.handle = NV_SUBDEV(PWR, 0xea),
+gk20a_pmu_oclass = &(struct nvkm_pmu_impl) {
+	.base.handle = NV_SUBDEV(PMU, 0xea),
 	.base.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = gk20a_pwr_ctor,
-		.dtor = _nouveau_pwr_dtor,
-		.init = gk20a_pwr_init,
-		.fini = gk20a_pwr_fini,
+		.ctor = gk20a_pmu_ctor,
+		.dtor = _nouveau_pmu_dtor,
+		.init = gk20a_pmu_init,
+		.fini = gk20a_pmu_fini,
 	},
 }.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/memx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
similarity index 64%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/memx.c
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
index 7a9299d..671c717 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/memx.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
@@ -1,10 +1,10 @@
-#ifndef __NVKM_PWR_MEMX_H__
-#define __NVKM_PWR_MEMX_H__
+#ifndef __NVKM_PMU_MEMX_H__
+#define __NVKM_PMU_MEMX_H__
 
 #include "priv.h"
 
 struct nouveau_memx {
-	struct nouveau_pwr *ppwr;
+	struct nouveau_pmu *pmu;
 	u32 base;
 	u32 size;
 	struct {
@@ -17,13 +17,13 @@
 static void
 memx_out(struct nouveau_memx *memx)
 {
-	struct nouveau_pwr *ppwr = memx->ppwr;
+	struct nouveau_pmu *pmu = memx->pmu;
 	int i;
 
 	if (memx->c.mthd) {
-		nv_wr32(ppwr, 0x10a1c4, (memx->c.size << 16) | memx->c.mthd);
+		nv_wr32(pmu, 0x10a1c4, (memx->c.size << 16) | memx->c.mthd);
 		for (i = 0; i < memx->c.size; i++)
-			nv_wr32(ppwr, 0x10a1c4, memx->c.data[i]);
+			nv_wr32(pmu, 0x10a1c4, memx->c.data[i]);
 		memx->c.mthd = 0;
 		memx->c.size = 0;
 	}
@@ -41,13 +41,13 @@
 }
 
 int
-nouveau_memx_init(struct nouveau_pwr *ppwr, struct nouveau_memx **pmemx)
+nouveau_memx_init(struct nouveau_pmu *pmu, struct nouveau_memx **pmemx)
 {
 	struct nouveau_memx *memx;
 	u32 reply[2];
 	int ret;
 
-	ret = ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_INFO,
+	ret = pmu->message(pmu, reply, PROC_MEMX, MEMX_MSG_INFO,
 					MEMX_INFO_DATA, 0);
 	if (ret)
 		return ret;
@@ -55,15 +55,15 @@
 	memx = *pmemx = kzalloc(sizeof(*memx), GFP_KERNEL);
 	if (!memx)
 		return -ENOMEM;
-	memx->ppwr = ppwr;
+	memx->pmu = pmu;
 	memx->base = reply[0];
 	memx->size = reply[1];
 
 	/* acquire data segment access */
 	do {
-		nv_wr32(ppwr, 0x10a580, 0x00000003);
-	} while (nv_rd32(ppwr, 0x10a580) != 0x00000003);
-	nv_wr32(ppwr, 0x10a1c0, 0x01000000 | memx->base);
+		nv_wr32(pmu, 0x10a580, 0x00000003);
+	} while (nv_rd32(pmu, 0x10a580) != 0x00000003);
+	nv_wr32(pmu, 0x10a1c0, 0x01000000 | memx->base);
 
 	return 0;
 }
@@ -72,23 +72,23 @@
 nouveau_memx_fini(struct nouveau_memx **pmemx, bool exec)
 {
 	struct nouveau_memx *memx = *pmemx;
-	struct nouveau_pwr *ppwr = memx->ppwr;
+	struct nouveau_pmu *pmu = memx->pmu;
 	u32 finish, reply[2];
 
 	/* flush the cache... */
 	memx_out(memx);
 
 	/* release data segment access */
-	finish = nv_rd32(ppwr, 0x10a1c0) & 0x00ffffff;
-	nv_wr32(ppwr, 0x10a580, 0x00000000);
+	finish = nv_rd32(pmu, 0x10a1c0) & 0x00ffffff;
+	nv_wr32(pmu, 0x10a580, 0x00000000);
 
 	/* call MEMX process to execute the script, and wait for reply */
 	if (exec) {
-		ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_EXEC,
+		pmu->message(pmu, reply, PROC_MEMX, MEMX_MSG_EXEC,
 				 memx->base, finish);
 	}
 
-	nv_debug(memx->ppwr, "Exec took %uns, PPWR_IN %08x\n",
+	nv_debug(memx->pmu, "Exec took %uns, PMU_IN %08x\n",
 		 reply[0], reply[1]);
 	kfree(memx);
 	return 0;
@@ -97,7 +97,7 @@
 void
 nouveau_memx_wr32(struct nouveau_memx *memx, u32 addr, u32 data)
 {
-	nv_debug(memx->ppwr, "R[%06x] = 0x%08x\n", addr, data);
+	nv_debug(memx->pmu, "R[%06x] = 0x%08x\n", addr, data);
 	memx_cmd(memx, MEMX_WR32, 2, (u32[]){ addr, data });
 }
 
@@ -105,7 +105,7 @@
 nouveau_memx_wait(struct nouveau_memx *memx,
 		  u32 addr, u32 mask, u32 data, u32 nsec)
 {
-	nv_debug(memx->ppwr, "R[%06x] & 0x%08x == 0x%08x, %d us\n",
+	nv_debug(memx->pmu, "R[%06x] & 0x%08x == 0x%08x, %d us\n",
 				addr, mask, data, nsec);
 	memx_cmd(memx, MEMX_WAIT, 4, (u32[]){ addr, mask, data, nsec });
 	memx_out(memx); /* fuc can't handle multiple */
@@ -114,7 +114,7 @@
 void
 nouveau_memx_nsec(struct nouveau_memx *memx, u32 nsec)
 {
-	nv_debug(memx->ppwr, "    DELAY = %d ns\n", nsec);
+	nv_debug(memx->pmu, "    DELAY = %d ns\n", nsec);
 	memx_cmd(memx, MEMX_DELAY, 1, (u32[]){ nsec });
 	memx_out(memx); /* fuc can't handle multiple */
 }
@@ -122,16 +122,16 @@
 void
 nouveau_memx_wait_vblank(struct nouveau_memx *memx)
 {
-	struct nouveau_pwr *ppwr = memx->ppwr;
+	struct nouveau_pmu *pmu = memx->pmu;
 	u32 heads, x, y, px = 0;
 	int i, head_sync;
 
-	if (nv_device(ppwr)->chipset < 0xd0) {
-		heads = nv_rd32(ppwr, 0x610050);
+	if (nv_device(pmu)->chipset < 0xd0) {
+		heads = nv_rd32(pmu, 0x610050);
 		for (i = 0; i < 2; i++) {
 			/* Heuristic: sync to head with biggest resolution */
 			if (heads & (2 << (i << 3))) {
-				x = nv_rd32(ppwr, 0x610b40 + (0x540 * i));
+				x = nv_rd32(pmu, 0x610b40 + (0x540 * i));
 				y = (x & 0xffff0000) >> 16;
 				x &= 0x0000ffff;
 				if ((x * y) > px) {
@@ -143,11 +143,11 @@
 	}
 
 	if (px == 0) {
-		nv_debug(memx->ppwr, "WAIT VBLANK !NO ACTIVE HEAD\n");
+		nv_debug(memx->pmu, "WAIT VBLANK !NO ACTIVE HEAD\n");
 		return;
 	}
 
-	nv_debug(memx->ppwr, "WAIT VBLANK HEAD%d\n", head_sync);
+	nv_debug(memx->pmu, "WAIT VBLANK HEAD%d\n", head_sync);
 	memx_cmd(memx, MEMX_VBLANK, 1, (u32[]){ head_sync });
 	memx_out(memx); /* fuc can't handle multiple */
 }
@@ -155,17 +155,17 @@
 void
 nouveau_memx_train(struct nouveau_memx *memx)
 {
-	nv_debug(memx->ppwr, "   MEM TRAIN\n");
+	nv_debug(memx->pmu, "   MEM TRAIN\n");
 	memx_cmd(memx, MEMX_TRAIN, 0, NULL);
 }
 
 int
-nouveau_memx_train_result(struct nouveau_pwr *ppwr, u32 *res, int rsize)
+nouveau_memx_train_result(struct nouveau_pmu *pmu, u32 *res, int rsize)
 {
 	u32 reply[2], base, size, i;
 	int ret;
 
-	ret = ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_INFO,
+	ret = pmu->message(pmu, reply, PROC_MEMX, MEMX_MSG_INFO,
 					MEMX_INFO_TRAIN, 0);
 	if (ret)
 		return ret;
@@ -176,10 +176,10 @@
 		return -ENOMEM;
 
 	/* read the packet */
-	nv_wr32(ppwr, 0x10a1c0, 0x02000000 | base);
+	nv_wr32(pmu, 0x10a1c0, 0x02000000 | base);
 
 	for (i = 0; i < size; i++)
-		res[i] = nv_rd32(ppwr, 0x10a1c4);
+		res[i] = nv_rd32(pmu, 0x10a1c4);
 
 	return 0;
 }
@@ -187,14 +187,14 @@
 void
 nouveau_memx_block(struct nouveau_memx *memx)
 {
-	nv_debug(memx->ppwr, "   HOST BLOCKED\n");
+	nv_debug(memx->pmu, "   HOST BLOCKED\n");
 	memx_cmd(memx, MEMX_ENTER, 0, NULL);
 }
 
 void
 nouveau_memx_unblock(struct nouveau_memx *memx)
 {
-	nv_debug(memx->ppwr, "   HOST UNBLOCKED\n");
+	nv_debug(memx->pmu, "   HOST UNBLOCKED\n");
 	memx_cmd(memx, MEMX_LEAVE, 0, NULL);
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nv108.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nv108.c
similarity index 79%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nv108.c
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nv108.c
index dacee08..a7db087 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nv108.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nv108.c
@@ -26,16 +26,16 @@
 #include "fuc/nv108.fuc5.h"
 
 struct nouveau_oclass *
-nv108_pwr_oclass = &(struct nvkm_pwr_impl) {
-	.base.handle = NV_SUBDEV(PWR, 0x00),
+nv108_pmu_oclass = &(struct nvkm_pmu_impl) {
+	.base.handle = NV_SUBDEV(PMU, 0x00),
 	.base.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = _nouveau_pwr_ctor,
-		.dtor = _nouveau_pwr_dtor,
-		.init = _nouveau_pwr_init,
-		.fini = _nouveau_pwr_fini,
+		.ctor = _nouveau_pmu_ctor,
+		.dtor = _nouveau_pmu_dtor,
+		.init = _nouveau_pmu_init,
+		.fini = _nouveau_pmu_fini,
 	},
-	.code.data = nv108_pwr_code,
-	.code.size = sizeof(nv108_pwr_code),
-	.data.data = nv108_pwr_data,
-	.data.size = sizeof(nv108_pwr_data),
+	.code.data = nv108_pmu_code,
+	.code.size = sizeof(nv108_pmu_code),
+	.data.data = nv108_pmu_data,
+	.data.size = sizeof(nv108_pmu_data),
 }.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nva3.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nva3.c
similarity index 70%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nva3.c
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nva3.c
index f8325a6..06f9928 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nva3.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nva3.c
@@ -26,25 +26,25 @@
 #include "fuc/nva3.fuc3.h"
 
 static int
-nva3_pwr_init(struct nouveau_object *object)
+nva3_pmu_init(struct nouveau_object *object)
 {
-	struct nouveau_pwr *ppwr = (void *)object;
-	nv_mask(ppwr, 0x022210, 0x00000001, 0x00000000);
-	nv_mask(ppwr, 0x022210, 0x00000001, 0x00000001);
-	return nouveau_pwr_init(ppwr);
+	struct nouveau_pmu *pmu = (void *)object;
+	nv_mask(pmu, 0x022210, 0x00000001, 0x00000000);
+	nv_mask(pmu, 0x022210, 0x00000001, 0x00000001);
+	return nouveau_pmu_init(pmu);
 }
 
 struct nouveau_oclass *
-nva3_pwr_oclass = &(struct nvkm_pwr_impl) {
-	.base.handle = NV_SUBDEV(PWR, 0xa3),
+nva3_pmu_oclass = &(struct nvkm_pmu_impl) {
+	.base.handle = NV_SUBDEV(PMU, 0xa3),
 	.base.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = _nouveau_pwr_ctor,
-		.dtor = _nouveau_pwr_dtor,
-		.init = nva3_pwr_init,
-		.fini = _nouveau_pwr_fini,
+		.ctor = _nouveau_pmu_ctor,
+		.dtor = _nouveau_pmu_dtor,
+		.init = nva3_pmu_init,
+		.fini = _nouveau_pmu_fini,
 	},
-	.code.data = nva3_pwr_code,
-	.code.size = sizeof(nva3_pwr_code),
-	.data.data = nva3_pwr_data,
-	.data.size = sizeof(nva3_pwr_data),
+	.code.data = nva3_pmu_code,
+	.code.size = sizeof(nva3_pmu_code),
+	.data.data = nva3_pmu_data,
+	.data.size = sizeof(nva3_pmu_data),
 }.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nvc0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nvc0.c
similarity index 79%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nvc0.c
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nvc0.c
index 669417c..a9fd145 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nvc0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nvc0.c
@@ -26,16 +26,16 @@
 #include "fuc/nvc0.fuc3.h"
 
 struct nouveau_oclass *
-nvc0_pwr_oclass = &(struct nvkm_pwr_impl) {
-	.base.handle = NV_SUBDEV(PWR, 0xc0),
+nvc0_pmu_oclass = &(struct nvkm_pmu_impl) {
+	.base.handle = NV_SUBDEV(PMU, 0xc0),
 	.base.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = _nouveau_pwr_ctor,
-		.dtor = _nouveau_pwr_dtor,
-		.init = _nouveau_pwr_init,
-		.fini = _nouveau_pwr_fini,
+		.ctor = _nouveau_pmu_ctor,
+		.dtor = _nouveau_pmu_dtor,
+		.init = _nouveau_pmu_init,
+		.fini = _nouveau_pmu_fini,
 	},
-	.code.data = nvc0_pwr_code,
-	.code.size = sizeof(nvc0_pwr_code),
-	.data.data = nvc0_pwr_data,
-	.data.size = sizeof(nvc0_pwr_data),
+	.code.data = nvc0_pmu_code,
+	.code.size = sizeof(nvc0_pmu_code),
+	.data.data = nvc0_pmu_data,
+	.data.size = sizeof(nvc0_pmu_data),
 }.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nvd0.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nvd0.c
similarity index 79%
rename from drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nvd0.c
rename to drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nvd0.c
index d6e33d0..a9b1d7e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/nvd0.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/nvd0.c
@@ -26,16 +26,16 @@
 #include "fuc/nvd0.fuc4.h"
 
 struct nouveau_oclass *
-nvd0_pwr_oclass = &(struct nvkm_pwr_impl) {
-	.base.handle = NV_SUBDEV(PWR, 0xd0),
+nvd0_pmu_oclass = &(struct nvkm_pmu_impl) {
+	.base.handle = NV_SUBDEV(PMU, 0xd0),
 	.base.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = _nouveau_pwr_ctor,
-		.dtor = _nouveau_pwr_dtor,
-		.init = _nouveau_pwr_init,
-		.fini = _nouveau_pwr_fini,
+		.ctor = _nouveau_pmu_ctor,
+		.dtor = _nouveau_pmu_dtor,
+		.init = _nouveau_pmu_init,
+		.fini = _nouveau_pmu_fini,
 	},
-	.code.data = nvd0_pwr_code,
-	.code.size = sizeof(nvd0_pwr_code),
-	.data.data = nvd0_pwr_data,
-	.data.size = sizeof(nvd0_pwr_data),
+	.code.data = nvd0_pmu_code,
+	.code.size = sizeof(nvd0_pmu_code),
+	.data.data = nvd0_pmu_data,
+	.data.size = sizeof(nvd0_pmu_data),
 }.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
new file mode 100644
index 0000000..eb5bd1c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
@@ -0,0 +1,45 @@
+#ifndef __NVKM_PMU_PRIV_H__
+#define __NVKM_PMU_PRIV_H__
+
+#include <subdev/pmu.h>
+#include <subdev/pmu/fuc/os.h>
+
+#define nouveau_pmu_create(p, e, o, d)                                         \
+	nouveau_pmu_create_((p), (e), (o), sizeof(**d), (void **)d)
+#define nouveau_pmu_destroy(p)                                                 \
+	nouveau_subdev_destroy(&(p)->base)
+#define nouveau_pmu_init(p) ({                                                 \
+	struct nouveau_pmu *_pmu = (p);                                       \
+	_nouveau_pmu_init(nv_object(_pmu));                                   \
+})
+#define nouveau_pmu_fini(p,s) ({                                               \
+	struct nouveau_pmu *_pmu = (p);                                       \
+	_nouveau_pmu_fini(nv_object(_pmu), (s));                              \
+})
+
+int nouveau_pmu_create_(struct nouveau_object *, struct nouveau_object *,
+			struct nouveau_oclass *, int, void **);
+
+int _nouveau_pmu_ctor(struct nouveau_object *, struct nouveau_object *,
+		      struct nouveau_oclass *, void *, u32,
+		      struct nouveau_object **);
+#define _nouveau_pmu_dtor _nouveau_subdev_dtor
+int _nouveau_pmu_init(struct nouveau_object *);
+int _nouveau_pmu_fini(struct nouveau_object *, bool);
+void nouveau_pmu_pgob(struct nouveau_pmu *pmu, bool enable);
+
+struct nvkm_pmu_impl {
+	struct nouveau_oclass base;
+	struct {
+		u32 *data;
+		u32  size;
+	} code;
+	struct {
+		u32 *data;
+		u32  size;
+	} data;
+
+	void (*pgob)(struct nouveau_pmu *, bool);
+};
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/Kbuild
deleted file mode 100644
index a664886..0000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/Kbuild
+++ /dev/null
@@ -1,8 +0,0 @@
-nvkm-y += nvkm/subdev/pwr/base.o
-nvkm-y += nvkm/subdev/pwr/memx.o
-nvkm-y += nvkm/subdev/pwr/nva3.o
-nvkm-y += nvkm/subdev/pwr/nvc0.o
-nvkm-y += nvkm/subdev/pwr/nvd0.o
-nvkm-y += nvkm/subdev/pwr/gk104.o
-nvkm-y += nvkm/subdev/pwr/nv108.o
-nvkm-y += nvkm/subdev/pwr/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/base.c
deleted file mode 100644
index 1ea433a..0000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/base.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright 2013 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include <subdev/timer.h>
-
-#include "priv.h"
-
-void
-nouveau_pwr_pgob(struct nouveau_pwr *ppwr, bool enable)
-{
-	const struct nvkm_pwr_impl *impl = (void *)nv_oclass(ppwr);
-	if (impl->pgob)
-		impl->pgob(ppwr, enable);
-}
-
-static int
-nouveau_pwr_send(struct nouveau_pwr *ppwr, u32 reply[2],
-		 u32 process, u32 message, u32 data0, u32 data1)
-{
-	struct nouveau_subdev *subdev = nv_subdev(ppwr);
-	u32 addr;
-
-	/* wait for a free slot in the fifo */
-	addr  = nv_rd32(ppwr, 0x10a4a0);
-	if (!nv_wait_ne(ppwr, 0x10a4b0, 0xffffffff, addr ^ 8))
-		return -EBUSY;
-
-	/* we currently only support a single process at a time waiting
-	 * on a synchronous reply, take the PPWR mutex and tell the
-	 * receive handler what we're waiting for
-	 */
-	if (reply) {
-		mutex_lock(&subdev->mutex);
-		ppwr->recv.message = message;
-		ppwr->recv.process = process;
-	}
-
-	/* acquire data segment access */
-	do {
-		nv_wr32(ppwr, 0x10a580, 0x00000001);
-	} while (nv_rd32(ppwr, 0x10a580) != 0x00000001);
-
-	/* write the packet */
-	nv_wr32(ppwr, 0x10a1c0, 0x01000000 | (((addr & 0x07) << 4) +
-				ppwr->send.base));
-	nv_wr32(ppwr, 0x10a1c4, process);
-	nv_wr32(ppwr, 0x10a1c4, message);
-	nv_wr32(ppwr, 0x10a1c4, data0);
-	nv_wr32(ppwr, 0x10a1c4, data1);
-	nv_wr32(ppwr, 0x10a4a0, (addr + 1) & 0x0f);
-
-	/* release data segment access */
-	nv_wr32(ppwr, 0x10a580, 0x00000000);
-
-	/* wait for reply, if requested */
-	if (reply) {
-		wait_event(ppwr->recv.wait, (ppwr->recv.process == 0));
-		reply[0] = ppwr->recv.data[0];
-		reply[1] = ppwr->recv.data[1];
-		mutex_unlock(&subdev->mutex);
-	}
-
-	return 0;
-}
-
-static void
-nouveau_pwr_recv(struct work_struct *work)
-{
-	struct nouveau_pwr *ppwr =
-		container_of(work, struct nouveau_pwr, recv.work);
-	u32 process, message, data0, data1;
-
-	/* nothing to do if GET == PUT */
-	u32 addr =  nv_rd32(ppwr, 0x10a4cc);
-	if (addr == nv_rd32(ppwr, 0x10a4c8))
-		return;
-
-	/* acquire data segment access */
-	do {
-		nv_wr32(ppwr, 0x10a580, 0x00000002);
-	} while (nv_rd32(ppwr, 0x10a580) != 0x00000002);
-
-	/* read the packet */
-	nv_wr32(ppwr, 0x10a1c0, 0x02000000 | (((addr & 0x07) << 4) +
-				ppwr->recv.base));
-	process = nv_rd32(ppwr, 0x10a1c4);
-	message = nv_rd32(ppwr, 0x10a1c4);
-	data0   = nv_rd32(ppwr, 0x10a1c4);
-	data1   = nv_rd32(ppwr, 0x10a1c4);
-	nv_wr32(ppwr, 0x10a4cc, (addr + 1) & 0x0f);
-
-	/* release data segment access */
-	nv_wr32(ppwr, 0x10a580, 0x00000000);
-
-	/* wake process if it's waiting on a synchronous reply */
-	if (ppwr->recv.process) {
-		if (process == ppwr->recv.process &&
-		    message == ppwr->recv.message) {
-			ppwr->recv.data[0] = data0;
-			ppwr->recv.data[1] = data1;
-			ppwr->recv.process = 0;
-			wake_up(&ppwr->recv.wait);
-			return;
-		}
-	}
-
-	/* right now there's no other expected responses from the engine,
-	 * so assume that any unexpected message is an error.
-	 */
-	nv_warn(ppwr, "%c%c%c%c 0x%08x 0x%08x 0x%08x 0x%08x\n",
-		(char)((process & 0x000000ff) >>  0),
-		(char)((process & 0x0000ff00) >>  8),
-		(char)((process & 0x00ff0000) >> 16),
-		(char)((process & 0xff000000) >> 24),
-		process, message, data0, data1);
-}
-
-static void
-nouveau_pwr_intr(struct nouveau_subdev *subdev)
-{
-	struct nouveau_pwr *ppwr = (void *)subdev;
-	u32 disp = nv_rd32(ppwr, 0x10a01c);
-	u32 intr = nv_rd32(ppwr, 0x10a008) & disp & ~(disp >> 16);
-
-	if (intr & 0x00000020) {
-		u32 stat = nv_rd32(ppwr, 0x10a16c);
-		if (stat & 0x80000000) {
-			nv_error(ppwr, "UAS fault at 0x%06x addr 0x%08x\n",
-				 stat & 0x00ffffff, nv_rd32(ppwr, 0x10a168));
-			nv_wr32(ppwr, 0x10a16c, 0x00000000);
-			intr &= ~0x00000020;
-		}
-	}
-
-	if (intr & 0x00000040) {
-		schedule_work(&ppwr->recv.work);
-		nv_wr32(ppwr, 0x10a004, 0x00000040);
-		intr &= ~0x00000040;
-	}
-
-	if (intr & 0x00000080) {
-		nv_info(ppwr, "wr32 0x%06x 0x%08x\n", nv_rd32(ppwr, 0x10a7a0),
-						      nv_rd32(ppwr, 0x10a7a4));
-		nv_wr32(ppwr, 0x10a004, 0x00000080);
-		intr &= ~0x00000080;
-	}
-
-	if (intr) {
-		nv_error(ppwr, "intr 0x%08x\n", intr);
-		nv_wr32(ppwr, 0x10a004, intr);
-	}
-}
-
-int
-_nouveau_pwr_fini(struct nouveau_object *object, bool suspend)
-{
-	struct nouveau_pwr *ppwr = (void *)object;
-
-	nv_wr32(ppwr, 0x10a014, 0x00000060);
-	flush_work(&ppwr->recv.work);
-
-	return nouveau_subdev_fini(&ppwr->base, suspend);
-}
-
-int
-_nouveau_pwr_init(struct nouveau_object *object)
-{
-	const struct nvkm_pwr_impl *impl = (void *)object->oclass;
-	struct nouveau_pwr *ppwr = (void *)object;
-	int ret, i;
-
-	ret = nouveau_subdev_init(&ppwr->base);
-	if (ret)
-		return ret;
-
-	nv_subdev(ppwr)->intr = nouveau_pwr_intr;
-	ppwr->message = nouveau_pwr_send;
-	ppwr->pgob = nouveau_pwr_pgob;
-
-	/* prevent previous ucode from running, wait for idle, reset */
-	nv_wr32(ppwr, 0x10a014, 0x0000ffff); /* INTR_EN_CLR = ALL */
-	nv_wait(ppwr, 0x10a04c, 0xffffffff, 0x00000000);
-	nv_mask(ppwr, 0x000200, 0x00002000, 0x00000000);
-	nv_mask(ppwr, 0x000200, 0x00002000, 0x00002000);
-	nv_rd32(ppwr, 0x000200);
-	nv_wait(ppwr, 0x10a10c, 0x00000006, 0x00000000);
-
-	/* upload data segment */
-	nv_wr32(ppwr, 0x10a1c0, 0x01000000);
-	for (i = 0; i < impl->data.size / 4; i++)
-		nv_wr32(ppwr, 0x10a1c4, impl->data.data[i]);
-
-	/* upload code segment */
-	nv_wr32(ppwr, 0x10a180, 0x01000000);
-	for (i = 0; i < impl->code.size / 4; i++) {
-		if ((i & 0x3f) == 0)
-			nv_wr32(ppwr, 0x10a188, i >> 6);
-		nv_wr32(ppwr, 0x10a184, impl->code.data[i]);
-	}
-
-	/* start it running */
-	nv_wr32(ppwr, 0x10a10c, 0x00000000);
-	nv_wr32(ppwr, 0x10a104, 0x00000000);
-	nv_wr32(ppwr, 0x10a100, 0x00000002);
-
-	/* wait for valid host->pwr ring configuration */
-	if (!nv_wait_ne(ppwr, 0x10a4d0, 0xffffffff, 0x00000000))
-		return -EBUSY;
-	ppwr->send.base = nv_rd32(ppwr, 0x10a4d0) & 0x0000ffff;
-	ppwr->send.size = nv_rd32(ppwr, 0x10a4d0) >> 16;
-
-	/* wait for valid pwr->host ring configuration */
-	if (!nv_wait_ne(ppwr, 0x10a4dc, 0xffffffff, 0x00000000))
-		return -EBUSY;
-	ppwr->recv.base = nv_rd32(ppwr, 0x10a4dc) & 0x0000ffff;
-	ppwr->recv.size = nv_rd32(ppwr, 0x10a4dc) >> 16;
-
-	nv_wr32(ppwr, 0x10a010, 0x000000e0);
-	return 0;
-}
-
-int
-nouveau_pwr_create_(struct nouveau_object *parent,
-		    struct nouveau_object *engine,
-		    struct nouveau_oclass *oclass, int length, void **pobject)
-{
-	struct nouveau_pwr *ppwr;
-	int ret;
-
-	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PPWR",
-				     "pwr", length, pobject);
-	ppwr = *pobject;
-	if (ret)
-		return ret;
-
-	INIT_WORK(&ppwr->recv.work, nouveau_pwr_recv);
-	init_waitqueue_head(&ppwr->recv.wait);
-	return 0;
-}
-
-int
-_nouveau_pwr_ctor(struct nouveau_object *parent,
-		  struct nouveau_object *engine,
-		  struct nouveau_oclass *oclass, void *data, u32 size,
-		  struct nouveau_object **pobject)
-{
-	struct nouveau_pwr *ppwr;
-	int ret = nouveau_pwr_create(parent, engine, oclass, &ppwr);
-	*pobject = nv_object(ppwr);
-	return ret;
-}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/gk104.c
deleted file mode 100644
index 9bb419c..0000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/gk104.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2013 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-
-#include "priv.h"
-
-#define nvd0_pwr_code gk104_pwr_code
-#define nvd0_pwr_data gk104_pwr_data
-#include "fuc/nvd0.fuc4.h"
-
-static void
-gk104_pwr_pgob(struct nouveau_pwr *ppwr, bool enable)
-{
-	nv_mask(ppwr, 0x000200, 0x00001000, 0x00000000);
-	nv_rd32(ppwr, 0x000200);
-	nv_mask(ppwr, 0x000200, 0x08000000, 0x08000000);
-	msleep(50);
-
-	nv_mask(ppwr, 0x10a78c, 0x00000002, 0x00000002);
-	nv_mask(ppwr, 0x10a78c, 0x00000001, 0x00000001);
-	nv_mask(ppwr, 0x10a78c, 0x00000001, 0x00000000);
-
-	nv_mask(ppwr, 0x020004, 0xc0000000, enable ? 0xc0000000 : 0x40000000);
-	msleep(50);
-
-	nv_mask(ppwr, 0x10a78c, 0x00000002, 0x00000000);
-	nv_mask(ppwr, 0x10a78c, 0x00000001, 0x00000001);
-	nv_mask(ppwr, 0x10a78c, 0x00000001, 0x00000000);
-
-	nv_mask(ppwr, 0x000200, 0x08000000, 0x00000000);
-	nv_mask(ppwr, 0x000200, 0x00001000, 0x00001000);
-	nv_rd32(ppwr, 0x000200);
-}
-
-struct nouveau_oclass *
-gk104_pwr_oclass = &(struct nvkm_pwr_impl) {
-	.base.handle = NV_SUBDEV(PWR, 0xe4),
-	.base.ofuncs = &(struct nouveau_ofuncs) {
-		.ctor = _nouveau_pwr_ctor,
-		.dtor = _nouveau_pwr_dtor,
-		.init = _nouveau_pwr_init,
-		.fini = _nouveau_pwr_fini,
-	},
-	.code.data = gk104_pwr_code,
-	.code.size = sizeof(gk104_pwr_code),
-	.data.data = gk104_pwr_data,
-	.data.size = sizeof(gk104_pwr_data),
-	.pgob = gk104_pwr_pgob,
-}.base;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/priv.h
deleted file mode 100644
index 86149d9..0000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pwr/priv.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __NVKM_PWR_PRIV_H__
-#define __NVKM_PWR_PRIV_H__
-
-#include <subdev/pwr.h>
-#include <subdev/pwr/fuc/os.h>
-
-#define nouveau_pwr_create(p, e, o, d)                                         \
-	nouveau_pwr_create_((p), (e), (o), sizeof(**d), (void **)d)
-#define nouveau_pwr_destroy(p)                                                 \
-	nouveau_subdev_destroy(&(p)->base)
-#define nouveau_pwr_init(p) ({                                                 \
-	struct nouveau_pwr *_ppwr = (p);                                       \
-	_nouveau_pwr_init(nv_object(_ppwr));                                   \
-})
-#define nouveau_pwr_fini(p,s) ({                                               \
-	struct nouveau_pwr *_ppwr = (p);                                       \
-	_nouveau_pwr_fini(nv_object(_ppwr), (s));                              \
-})
-
-int nouveau_pwr_create_(struct nouveau_object *, struct nouveau_object *,
-			struct nouveau_oclass *, int, void **);
-
-int _nouveau_pwr_ctor(struct nouveau_object *, struct nouveau_object *,
-		      struct nouveau_oclass *, void *, u32,
-		      struct nouveau_object **);
-#define _nouveau_pwr_dtor _nouveau_subdev_dtor
-int _nouveau_pwr_init(struct nouveau_object *);
-int _nouveau_pwr_fini(struct nouveau_object *, bool);
-void nouveau_pwr_pgob(struct nouveau_pwr *ppwr, bool enable);
-
-struct nvkm_pwr_impl {
-	struct nouveau_oclass base;
-	struct {
-		u32 *data;
-		u32  size;
-	} code;
-	struct {
-		u32 *data;
-		u32  size;
-	} data;
-
-	void (*pgob)(struct nouveau_pwr *, bool);
-};
-
-#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
index 9ad01da..7d4bfd8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
@@ -176,7 +176,7 @@
 	/* The default PPWR ucode on fermi interferes with fan management */
 	if ((mode >= ARRAY_SIZE(name)) ||
 	    (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0 &&
-	     !nouveau_subdev(device, NVDEV_SUBDEV_PWR)))
+	     !nouveau_subdev(device, NVDEV_SUBDEV_PMU)))
 		return -EINVAL;
 
 	/* do not allow automatic fan management if the thermal sensor is