*/
#include "priv.h"
+#include <core/firmware.h>
#include <core/msgqueue.h>
#include <subdev/timer.h>
};
int
-nvkm_pmu_ctor(const struct nvkm_pmu_func *func, struct nvkm_device *device,
+nvkm_pmu_ctor(const struct nvkm_pmu_fwif *fwif, struct nvkm_device *device,
int index, struct nvkm_pmu *pmu)
{
nvkm_subdev_ctor(&nvkm_pmu, device, index, &pmu->subdev);
- pmu->func = func;
+
INIT_WORK(&pmu->recv.work, nvkm_pmu_recv);
init_waitqueue_head(&pmu->recv.wait);
+
+ fwif = nvkm_firmware_load(&pmu->subdev, fwif, "Pmu", pmu);
+ if (IS_ERR(fwif))
+ return PTR_ERR(fwif);
+
+ pmu->func = fwif->func;
return 0;
}
int
-nvkm_pmu_new_(const struct nvkm_pmu_func *func, struct nvkm_device *device,
+nvkm_pmu_new_(const struct nvkm_pmu_fwif *fwif, struct nvkm_device *device,
int index, struct nvkm_pmu **ppmu)
{
struct nvkm_pmu *pmu;
if (!(pmu = *ppmu = kzalloc(sizeof(*pmu), GFP_KERNEL)))
return -ENOMEM;
- return nvkm_pmu_ctor(func, device, index, *ppmu);
+ return nvkm_pmu_ctor(fwif, device, index, *ppmu);
}
.recv = gt215_pmu_recv,
};
+int
+gf100_pmu_nofw(struct nvkm_pmu *pmu, int ver, const struct nvkm_pmu_fwif *fwif)
+{
+ return 0;
+}
+
+static const struct nvkm_pmu_fwif
+gf100_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, &gf100_pmu },
+ {}
+};
+
int
gf100_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gf100_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gf100_pmu_fwif, device, index, ppmu);
}
.recv = gt215_pmu_recv,
};
+static const struct nvkm_pmu_fwif
+gf119_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, &gf119_pmu },
+ {}
+};
+
int
gf119_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gf119_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gf119_pmu_fwif, device, index, ppmu);
}
.pgob = gk104_pmu_pgob,
};
+static const struct nvkm_pmu_fwif
+gk104_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, &gk104_pmu },
+ {}
+};
+
int
gk104_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gk104_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gk104_pmu_fwif, device, index, ppmu);
}
.pgob = gk110_pmu_pgob,
};
+static const struct nvkm_pmu_fwif
+gk110_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, &gk110_pmu },
+ {}
+};
+
int
gk110_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gk110_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gk110_pmu_fwif, device, index, ppmu);
}
.pgob = gk110_pmu_pgob,
};
+static const struct nvkm_pmu_fwif
+gk208_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, &gk208_pmu },
+ {}
+};
+
int
gk208_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gk208_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gk208_pmu_fwif, device, index, ppmu);
}
.reset = gf100_pmu_reset,
};
+static const struct nvkm_pmu_fwif
+gk20a_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, &gk20a_pmu },
+ {}
+};
+
int
gk20a_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
struct gk20a_pmu *pmu;
+ int ret;
if (!(pmu = kzalloc(sizeof(*pmu), GFP_KERNEL)))
return -ENOMEM;
*ppmu = &pmu->base;
- nvkm_pmu_ctor(&gk20a_pmu, device, index, &pmu->base);
+ ret = nvkm_pmu_ctor(gk20a_pmu_fwif, device, index, &pmu->base);
+ if (ret)
+ return ret;
pmu->data = &gk20a_dvfs_data;
nvkm_alarm_init(&pmu->alarm, gk20a_pmu_dvfs_work);
-
return 0;
}
.recv = gt215_pmu_recv,
};
+static const struct nvkm_pmu_fwif
+gm107_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, &gm107_pmu },
+ {}
+};
+
int
gm107_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gm107_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gm107_pmu_fwif, device, index, ppmu);
}
*/
#include "priv.h"
#include <core/msgqueue.h>
-#include <engine/falcon.h>
+#include <subdev/acr.h>
+
+static const struct nvkm_acr_lsf_func
+gm20b_pmu_acr = {
+};
void
gm20b_pmu_recv(struct nvkm_pmu *pmu)
.recv = gm20b_pmu_recv,
};
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
+MODULE_FIRMWARE("nvidia/gm20b/pmu/desc.bin");
+MODULE_FIRMWARE("nvidia/gm20b/pmu/image.bin");
+MODULE_FIRMWARE("nvidia/gm20b/pmu/sig.bin");
+#endif
+
+int
+gm20b_pmu_load(struct nvkm_pmu *pmu, int ver, const struct nvkm_pmu_fwif *fwif)
+{
+ return nvkm_acr_lsfw_load_sig_image_desc(&pmu->subdev, pmu->falcon,
+ NVKM_ACR_LSF_PMU, "pmu/",
+ ver, fwif->acr);
+}
+
+static const struct nvkm_pmu_fwif
+gm20b_pmu_fwif[] = {
+ { 0, gm20b_pmu_load, &gm20b_pmu, &gm20b_pmu_acr },
+ {}
+};
+
int
gm20b_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gm20b_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gm20b_pmu_fwif, device, index, ppmu);
}
.reset = gf100_pmu_reset,
};
+static const struct nvkm_pmu_fwif
+gp100_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, &gp100_pmu },
+ {}
+};
+
int
gp100_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gp100_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gp100_pmu_fwif, device, index, ppmu);
}
.reset = gp102_pmu_reset,
};
+static const struct nvkm_pmu_fwif
+gp102_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, &gp102_pmu },
+ {}
+};
+
int
gp102_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gp102_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gp102_pmu_fwif, device, index, ppmu);
}
* DEALINGS IN THE SOFTWARE.
*/
#include "priv.h"
+#include <subdev/acr.h>
+
+static const struct nvkm_acr_lsf_func
+gp10b_pmu_acr = {
+};
static const struct nvkm_pmu_func
gp10b_pmu = {
.recv = gm20b_pmu_recv,
};
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
+MODULE_FIRMWARE("nvidia/gp10b/pmu/desc.bin");
+MODULE_FIRMWARE("nvidia/gp10b/pmu/image.bin");
+MODULE_FIRMWARE("nvidia/gp10b/pmu/sig.bin");
+#endif
+
+static const struct nvkm_pmu_fwif
+gp10b_pmu_fwif[] = {
+ { 0, gm20b_pmu_load, &gp10b_pmu, &gp10b_pmu_acr },
+ {}
+};
+
int
gp10b_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(&gp10b_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gp10b_pmu_fwif, device, index, ppmu);
}
.recv = gt215_pmu_recv,
};
+static const struct nvkm_pmu_fwif
+gt215_pmu_fwif[] = {
+ { -1, gf100_pmu_nofw, >215_pmu },
+ {}
+};
+
int
gt215_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
{
- return nvkm_pmu_new_(>215_pmu, device, index, ppmu);
+ return nvkm_pmu_new_(gt215_pmu_fwif, device, index, ppmu);
}
#include <subdev/pmu.h>
#include <subdev/pmu/fuc/os.h>
-int nvkm_pmu_ctor(const struct nvkm_pmu_func *, struct nvkm_device *,
- int index, struct nvkm_pmu *);
-int nvkm_pmu_new_(const struct nvkm_pmu_func *, struct nvkm_device *,
- int index, struct nvkm_pmu **);
-
struct nvkm_pmu_func {
struct {
u32 *data;
void gk110_pmu_pgob(struct nvkm_pmu *, bool);
void gm20b_pmu_recv(struct nvkm_pmu *);
+
+struct nvkm_pmu_fwif {
+ int version;
+ int (*load)(struct nvkm_pmu *, int ver, const struct nvkm_pmu_fwif *);
+ const struct nvkm_pmu_func *func;
+ const struct nvkm_acr_lsf_func *acr;
+};
+
+int gf100_pmu_nofw(struct nvkm_pmu *, int, const struct nvkm_pmu_fwif *);
+int gm20b_pmu_load(struct nvkm_pmu *, int, const struct nvkm_pmu_fwif *);
+
+int nvkm_pmu_ctor(const struct nvkm_pmu_fwif *, struct nvkm_device *,
+ int index, struct nvkm_pmu *);
+int nvkm_pmu_new_(const struct nvkm_pmu_fwif *, struct nvkm_device *,
+ int index, struct nvkm_pmu **);
#endif
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_method_init.bin");
-MODULE_FIRMWARE("nvidia/gm20b/pmu/desc.bin");
-MODULE_FIRMWARE("nvidia/gm20b/pmu/image.bin");
-MODULE_FIRMWARE("nvidia/gm20b/pmu/sig.bin");
#endif
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_method_init.bin");
-MODULE_FIRMWARE("nvidia/gp10b/pmu/desc.bin");
-MODULE_FIRMWARE("nvidia/gp10b/pmu/image.bin");
-MODULE_FIRMWARE("nvidia/gp10b/pmu/sig.bin");
#endif