drm/nouveau/pmu: select implementation based on available firmware
This will allow for further customisation of the subdev depending on what firmware is available. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
e905736c6d
commit
989863d7cb
16 changed files with 149 additions and 29 deletions
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
#include "priv.h"
|
#include "priv.h"
|
||||||
|
|
||||||
|
#include <core/firmware.h>
|
||||||
#include <core/msgqueue.h>
|
#include <core/msgqueue.h>
|
||||||
#include <subdev/timer.h>
|
#include <subdev/timer.h>
|
||||||
|
|
||||||
|
@ -160,22 +161,28 @@ nvkm_pmu = {
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
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)
|
int index, struct nvkm_pmu *pmu)
|
||||||
{
|
{
|
||||||
nvkm_subdev_ctor(&nvkm_pmu, device, index, &pmu->subdev);
|
nvkm_subdev_ctor(&nvkm_pmu, device, index, &pmu->subdev);
|
||||||
pmu->func = func;
|
|
||||||
INIT_WORK(&pmu->recv.work, nvkm_pmu_recv);
|
INIT_WORK(&pmu->recv.work, nvkm_pmu_recv);
|
||||||
init_waitqueue_head(&pmu->recv.wait);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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)
|
int index, struct nvkm_pmu **ppmu)
|
||||||
{
|
{
|
||||||
struct nvkm_pmu *pmu;
|
struct nvkm_pmu *pmu;
|
||||||
if (!(pmu = *ppmu = kzalloc(sizeof(*pmu), GFP_KERNEL)))
|
if (!(pmu = *ppmu = kzalloc(sizeof(*pmu), GFP_KERNEL)))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
return nvkm_pmu_ctor(func, device, index, *ppmu);
|
return nvkm_pmu_ctor(fwif, device, index, *ppmu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,20 @@ gf100_pmu = {
|
||||||
.recv = gt215_pmu_recv,
|
.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
|
int
|
||||||
gf100_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,14 @@ gf119_pmu = {
|
||||||
.recv = gt215_pmu_recv,
|
.recv = gt215_pmu_recv,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_pmu_fwif
|
||||||
|
gf119_pmu_fwif[] = {
|
||||||
|
{ -1, gf100_pmu_nofw, &gf119_pmu },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
gf119_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,8 +119,14 @@ gk104_pmu = {
|
||||||
.pgob = gk104_pmu_pgob,
|
.pgob = gk104_pmu_pgob,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_pmu_fwif
|
||||||
|
gk104_pmu_fwif[] = {
|
||||||
|
{ -1, gf100_pmu_nofw, &gk104_pmu },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
gk104_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,8 +98,14 @@ gk110_pmu = {
|
||||||
.pgob = gk110_pmu_pgob,
|
.pgob = gk110_pmu_pgob,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_pmu_fwif
|
||||||
|
gk110_pmu_fwif[] = {
|
||||||
|
{ -1, gf100_pmu_nofw, &gk110_pmu },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
gk110_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,14 @@ gk208_pmu = {
|
||||||
.pgob = gk110_pmu_pgob,
|
.pgob = gk110_pmu_pgob,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_pmu_fwif
|
||||||
|
gk208_pmu_fwif[] = {
|
||||||
|
{ -1, gf100_pmu_nofw, &gk208_pmu },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
gk208_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,19 +202,27 @@ gk20a_pmu = {
|
||||||
.reset = gf100_pmu_reset,
|
.reset = gf100_pmu_reset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_pmu_fwif
|
||||||
|
gk20a_pmu_fwif[] = {
|
||||||
|
{ -1, gf100_pmu_nofw, &gk20a_pmu },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
gk20a_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
gk20a_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
||||||
{
|
{
|
||||||
struct gk20a_pmu *pmu;
|
struct gk20a_pmu *pmu;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!(pmu = kzalloc(sizeof(*pmu), GFP_KERNEL)))
|
if (!(pmu = kzalloc(sizeof(*pmu), GFP_KERNEL)))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
*ppmu = &pmu->base;
|
*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;
|
pmu->data = &gk20a_dvfs_data;
|
||||||
nvkm_alarm_init(&pmu->alarm, gk20a_pmu_dvfs_work);
|
nvkm_alarm_init(&pmu->alarm, gk20a_pmu_dvfs_work);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,14 @@ gm107_pmu = {
|
||||||
.recv = gt215_pmu_recv,
|
.recv = gt215_pmu_recv,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_pmu_fwif
|
||||||
|
gm107_pmu_fwif[] = {
|
||||||
|
{ -1, gf100_pmu_nofw, &gm107_pmu },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
gm107_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,11 @@
|
||||||
*/
|
*/
|
||||||
#include "priv.h"
|
#include "priv.h"
|
||||||
#include <core/msgqueue.h>
|
#include <core/msgqueue.h>
|
||||||
#include <engine/falcon.h>
|
#include <subdev/acr.h>
|
||||||
|
|
||||||
|
static const struct nvkm_acr_lsf_func
|
||||||
|
gm20b_pmu_acr = {
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
gm20b_pmu_recv(struct nvkm_pmu *pmu)
|
gm20b_pmu_recv(struct nvkm_pmu *pmu)
|
||||||
|
@ -42,8 +46,28 @@ gm20b_pmu = {
|
||||||
.recv = gm20b_pmu_recv,
|
.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
|
int
|
||||||
gm20b_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,14 @@ gp100_pmu = {
|
||||||
.reset = gf100_pmu_reset,
|
.reset = gf100_pmu_reset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_pmu_fwif
|
||||||
|
gp100_pmu_fwif[] = {
|
||||||
|
{ -1, gf100_pmu_nofw, &gp100_pmu },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
gp100_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,14 @@ gp102_pmu = {
|
||||||
.reset = gp102_pmu_reset,
|
.reset = gp102_pmu_reset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_pmu_fwif
|
||||||
|
gp102_pmu_fwif[] = {
|
||||||
|
{ -1, gf100_pmu_nofw, &gp102_pmu },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
gp102_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,11 @@
|
||||||
* DEALINGS IN THE SOFTWARE.
|
* DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "priv.h"
|
#include "priv.h"
|
||||||
|
#include <subdev/acr.h>
|
||||||
|
|
||||||
|
static const struct nvkm_acr_lsf_func
|
||||||
|
gp10b_pmu_acr = {
|
||||||
|
};
|
||||||
|
|
||||||
static const struct nvkm_pmu_func
|
static const struct nvkm_pmu_func
|
||||||
gp10b_pmu = {
|
gp10b_pmu = {
|
||||||
|
@ -28,8 +33,20 @@ gp10b_pmu = {
|
||||||
.recv = gm20b_pmu_recv,
|
.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
|
int
|
||||||
gp10b_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,8 +256,14 @@ gt215_pmu = {
|
||||||
.recv = gt215_pmu_recv,
|
.recv = gt215_pmu_recv,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct nvkm_pmu_fwif
|
||||||
|
gt215_pmu_fwif[] = {
|
||||||
|
{ -1, gf100_pmu_nofw, >215_pmu },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
gt215_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,6 @@
|
||||||
#include <subdev/pmu.h>
|
#include <subdev/pmu.h>
|
||||||
#include <subdev/pmu/fuc/os.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 nvkm_pmu_func {
|
||||||
struct {
|
struct {
|
||||||
u32 *data;
|
u32 *data;
|
||||||
|
@ -44,4 +39,19 @@ void gf100_pmu_reset(struct nvkm_pmu *);
|
||||||
void gk110_pmu_pgob(struct nvkm_pmu *, bool);
|
void gk110_pmu_pgob(struct nvkm_pmu *, bool);
|
||||||
|
|
||||||
void gm20b_pmu_recv(struct nvkm_pmu *);
|
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
|
#endif
|
||||||
|
|
|
@ -160,7 +160,4 @@ MODULE_FIRMWARE("nvidia/gm20b/gr/sw_ctx.bin");
|
||||||
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_nonctx.bin");
|
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_nonctx.bin");
|
||||||
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_bundle_init.bin");
|
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_bundle_init.bin");
|
||||||
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_method_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
|
#endif
|
||||||
|
|
|
@ -85,7 +85,4 @@ MODULE_FIRMWARE("nvidia/gp10b/gr/sw_ctx.bin");
|
||||||
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_nonctx.bin");
|
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_nonctx.bin");
|
||||||
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_bundle_init.bin");
|
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_bundle_init.bin");
|
||||||
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_method_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
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue