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>
NVDEV_SUBDEV_INSTMEM,
NVDEV_SUBDEV_VM,
NVDEV_SUBDEV_BAR,
- NVDEV_SUBDEV_PWR,
+ NVDEV_SUBDEV_PMU,
NVDEV_SUBDEV_VOLT,
NVDEV_SUBDEV_THERM,
NVDEV_SUBDEV_CLK,
-#ifndef __NOUVEAU_PWR_H__
-#define __NOUVEAU_PWR_H__
+#ifndef __NOUVEAU_PMU_H__
+#define __NOUVEAU_PMU_H__
#include <core/subdev.h>
#include <core/device.h>
-struct nouveau_pwr {
+struct nouveau_pmu {
struct nouveau_subdev base;
struct {
u32 data[2];
} recv;
- int (*message)(struct nouveau_pwr *, u32[2], u32, u32, u32, u32);
- void (*pgob)(struct nouveau_pwr *, bool);
+ int (*message)(struct nouveau_pmu *, u32[2], u32, u32, u32, u32);
+ void (*pgob)(struct nouveau_pmu *, bool);
};
-static inline struct nouveau_pwr *
-nouveau_pwr(void *obj)
+static inline struct nouveau_pmu *
+nouveau_pmu(void *obj)
{
- return (void *)nouveau_subdev(obj, NVDEV_SUBDEV_PWR);
+ return (void *)nouveau_subdev(obj, NVDEV_SUBDEV_PMU);
}
-extern struct nouveau_oclass *nva3_pwr_oclass;
-extern struct nouveau_oclass *nvc0_pwr_oclass;
-extern struct nouveau_oclass *nvd0_pwr_oclass;
-extern struct nouveau_oclass *gk104_pwr_oclass;
-extern struct nouveau_oclass *nv108_pwr_oclass;
-extern struct nouveau_oclass *gk20a_pwr_oclass;
+extern struct nouveau_oclass *nva3_pmu_oclass;
+extern struct nouveau_oclass *nvc0_pmu_oclass;
+extern struct nouveau_oclass *nvd0_pmu_oclass;
+extern struct nouveau_oclass *gk104_pmu_oclass;
+extern struct nouveau_oclass *nv108_pmu_oclass;
+extern struct nouveau_oclass *gk20a_pmu_oclass;
-/* interface to MEMX process running on PPWR */
+/* interface to MEMX process running on PMU */
struct nouveau_memx;
-int nouveau_memx_init(struct nouveau_pwr *, struct nouveau_memx **);
+int nouveau_memx_init(struct nouveau_pmu *, struct nouveau_memx **);
int nouveau_memx_fini(struct nouveau_memx **, bool exec);
void nouveau_memx_wr32(struct nouveau_memx *, u32 addr, u32 data);
void nouveau_memx_wait(struct nouveau_memx *,
void nouveau_memx_nsec(struct nouveau_memx *, u32 nsec);
void nouveau_memx_wait_vblank(struct nouveau_memx *);
void nouveau_memx_train(struct nouveau_memx *);
-int nouveau_memx_train_result(struct nouveau_pwr *, u32 *, int);
+int nouveau_memx_train_result(struct nouveau_pmu *, u32 *, int);
void nouveau_memx_block(struct nouveau_memx *);
void nouveau_memx_unblock(struct nouveau_memx *);
[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,
#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>
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;
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
#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>
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;
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;
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;
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;
#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>
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;
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;
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;
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;
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;
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;
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;
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;
#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>
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;
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;
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;
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";
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;
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;
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;
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;
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
#include "nvc0.h"
#include "ctxnvc0.h"
{
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)
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
#ifndef __NVKM_FBRAM_FUC_H__
#define __NVKM_FBRAM_FUC_H__
-#include <subdev/pwr.h>
+#include <subdev/pmu.h>
struct ramfuc {
struct nouveau_memx *memx;
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;
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
{ 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 */
{ 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 },
--- /dev/null
+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
--- /dev/null
+/*
+ * 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;
+}
#include "macros.fuc"
-.section #nv108_pwr_data
+.section #nv108_pmu_data
#define INCLUDE_PROC
#include "kernel.fuc"
#include "arith.fuc"
#undef INCLUDE_DATA
.align 256
-.section #nv108_pwr_code
+.section #nv108_pmu_code
#define INCLUDE_CODE
#include "kernel.fuc"
#include "arith.fuc"
-uint32_t nv108_pwr_data[] = {
+uint32_t nv108_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
0x00000000,
};
-uint32_t nv108_pwr_code[] = {
+uint32_t nv108_pmu_code[] = {
0x031c0ef5,
/* 0x0004: rd32 */
0xf607a040,
#include "macros.fuc"
-.section #nva3_pwr_data
+.section #nva3_pmu_data
#define INCLUDE_PROC
#include "kernel.fuc"
#include "arith.fuc"
#undef INCLUDE_DATA
.align 256
-.section #nva3_pwr_code
+.section #nva3_pmu_code
#define INCLUDE_CODE
#include "kernel.fuc"
#include "arith.fuc"
-uint32_t nva3_pwr_data[] = {
+uint32_t nva3_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
0x00000000,
};
-uint32_t nva3_pwr_code[] = {
+uint32_t nva3_pmu_code[] = {
0x039e0ef5,
/* 0x0004: rd32 */
0x07a007f1,
#include "macros.fuc"
-.section #nvc0_pwr_data
+.section #nvc0_pmu_data
#define INCLUDE_PROC
#include "kernel.fuc"
#include "arith.fuc"
#undef INCLUDE_DATA
.align 256
-.section #nvc0_pwr_code
+.section #nvc0_pmu_code
#define INCLUDE_CODE
#include "kernel.fuc"
#include "arith.fuc"
-uint32_t nvc0_pwr_data[] = {
+uint32_t nvc0_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
0x00000000,
};
-uint32_t nvc0_pwr_code[] = {
+uint32_t nvc0_pmu_code[] = {
0x039e0ef5,
/* 0x0004: rd32 */
0x07a007f1,
#include "macros.fuc"
-.section #nvd0_pwr_data
+.section #nvd0_pmu_data
#define INCLUDE_PROC
#include "kernel.fuc"
#include "arith.fuc"
#undef INCLUDE_DATA
.align 256
-.section #nvd0_pwr_code
+.section #nvd0_pmu_code
#define INCLUDE_CODE
#include "kernel.fuc"
#include "arith.fuc"
-uint32_t nvd0_pwr_data[] = {
+uint32_t nvd0_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
0x00000000,
};
-uint32_t nvd0_pwr_code[] = {
+uint32_t nvd0_pmu_code[] = {
0x034d0ef5,
/* 0x0004: rd32 */
0x07a007f1,
#include "priv.h"
-#define nvd0_pwr_code gk104_pwr_code
-#define nvd0_pwr_data gk104_pwr_data
+#define nvd0_pmu_code gk104_pmu_code
+#define nvd0_pmu_data gk104_pmu_data
#include "fuc/nvd0.fuc4.h"
static void
-gk104_pwr_pgob(struct nouveau_pwr *ppwr, bool enable)
+gk104_pmu_pgob(struct nouveau_pmu *pmu, bool enable)
{
- nv_mask(ppwr, 0x000200, 0x00001000, 0x00000000);
- nv_rd32(ppwr, 0x000200);
- nv_mask(ppwr, 0x000200, 0x08000000, 0x08000000);
+ nv_mask(pmu, 0x000200, 0x00001000, 0x00000000);
+ nv_rd32(pmu, 0x000200);
+ nv_mask(pmu, 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(pmu, 0x10a78c, 0x00000002, 0x00000002);
+ nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001);
+ nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000);
- nv_mask(ppwr, 0x020004, 0xc0000000, enable ? 0xc0000000 : 0x40000000);
+ nv_mask(pmu, 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(pmu, 0x10a78c, 0x00000002, 0x00000000);
+ nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000001);
+ nv_mask(pmu, 0x10a78c, 0x00000001, 0x00000000);
- nv_mask(ppwr, 0x000200, 0x08000000, 0x00000000);
- nv_mask(ppwr, 0x000200, 0x00001000, 0x00001000);
- nv_rd32(ppwr, 0x000200);
+ nv_mask(pmu, 0x000200, 0x08000000, 0x00000000);
+ nv_mask(pmu, 0x000200, 0x00001000, 0x00001000);
+ nv_rd32(pmu, 0x000200);
}
struct nouveau_oclass *
-gk104_pwr_oclass = &(struct nvkm_pwr_impl) {
- .base.handle = NV_SUBDEV(PWR, 0xe4),
+gk104_pmu_oclass = &(struct nvkm_pmu_impl) {
+ .base.handle = NV_SUBDEV(PMU, 0xe4),
.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 = gk104_pwr_code,
- .code.size = sizeof(gk104_pwr_code),
- .data.data = gk104_pwr_data,
- .data.size = sizeof(gk104_pwr_data),
- .pgob = gk104_pwr_pgob,
+ .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;
#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);
}
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);
}
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;
}
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));
}
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;
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;
-#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 {
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;
}
}
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;
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;
}
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;
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 });
}
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 */
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 */
}
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) {
}
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 */
}
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;
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;
}
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);
}
#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;
#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;
#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;
#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;
--- /dev/null
+#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
+++ /dev/null
-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
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-#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
/* 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