Commit ccdc0431 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/pmu: move init() falcon reset to non-nvfw code

Cleanup before falcon changes.

- fixes (attempt at?) reset of pmu while rtos is running, on gm20b

v2:
- remove extra whitespace
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent b7f44ef7
......@@ -81,6 +81,9 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
{
struct nvkm_pmu *pmu = nvkm_pmu(subdev);
if (!subdev->use.enabled)
return 0;
if (pmu->func->fini)
pmu->func->fini(pmu);
......@@ -94,42 +97,14 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
return 0;
}
static void
nvkm_pmu_reset(struct nvkm_pmu *pmu)
{
struct nvkm_device *device = pmu->subdev.device;
/* Reset. */
if (pmu->func->reset)
pmu->func->reset(pmu);
/* Wait for IMEM/DMEM scrubbing to be complete. */
nvkm_msec(device, 2000,
if (!(nvkm_rd32(device, 0x10a10c) & 0x00000006))
break;
);
}
static int
nvkm_pmu_init(struct nvkm_subdev *subdev)
{
struct nvkm_pmu *pmu = nvkm_pmu(subdev);
struct nvkm_device *device = pmu->subdev.device;
if (!pmu->func->init)
return 0;
if (pmu->func->enabled(pmu)) {
/* Inhibit interrupts, and wait for idle. */
nvkm_wr32(device, 0x10a014, 0x0000ffff);
nvkm_msec(device, 2000,
if (!nvkm_rd32(device, 0x10a04c))
break;
);
nvkm_pmu_reset(pmu);
}
return pmu->func->init(pmu);
}
......
......@@ -197,7 +197,6 @@ gk20a_dvfs_data= {
static const struct nvkm_pmu_func
gk20a_pmu = {
.flcn = &gt215_pmu_flcn,
.enabled = gf100_pmu_enabled,
.init = gk20a_pmu_init,
.fini = gk20a_pmu_fini,
.reset = gf100_pmu_reset,
......
......@@ -55,11 +55,9 @@ gm200_pmu_flcn = {
static const struct nvkm_pmu_func
gm200_pmu = {
.flcn = &gm200_pmu_flcn,
.enabled = gf100_pmu_enabled,
.reset = gf100_pmu_reset,
};
int
gm200_pmu_nofw(struct nvkm_pmu *pmu, int ver, const struct nvkm_pmu_fwif *fwif)
{
......
......@@ -166,7 +166,7 @@ gm20b_pmu_acr_init_wpr(struct nvkm_pmu *pmu)
gm20b_pmu_acr_init_wpr_callback, pmu, 0);
}
int
static int
gm20b_pmu_initmsg(struct nvkm_pmu *pmu)
{
struct nv_pmu_init_msg msg;
......@@ -192,7 +192,7 @@ gm20b_pmu_initmsg(struct nvkm_pmu *pmu)
return gm20b_pmu_acr_init_wpr(pmu);
}
void
static void
gm20b_pmu_recv(struct nvkm_pmu *pmu)
{
if (!pmu->initmsg_received) {
......@@ -209,10 +209,9 @@ gm20b_pmu_recv(struct nvkm_pmu *pmu)
nvkm_falcon_msgq_recv(pmu->msgq);
}
static const struct nvkm_pmu_func
const struct nvkm_pmu_func
gm20b_pmu = {
.flcn = &gm200_pmu_flcn,
.enabled = gf100_pmu_enabled,
.intr = gt215_pmu_intr,
.recv = gm20b_pmu_recv,
.initmsg = gm20b_pmu_initmsg,
......
......@@ -31,16 +31,9 @@ gp102_pmu_reset(struct nvkm_pmu *pmu)
nvkm_mask(device, 0x10a3c0, 0x00000001, 0x00000000);
}
static bool
gp102_pmu_enabled(struct nvkm_pmu *pmu)
{
return !(nvkm_rd32(pmu->subdev.device, 0x10a3c0) & 0x00000001);
}
static const struct nvkm_pmu_func
gp102_pmu = {
.flcn = &gm200_pmu_flcn,
.enabled = gp102_pmu_enabled,
.reset = gp102_pmu_reset,
};
......
......@@ -76,16 +76,6 @@ gp10b_pmu_acr = {
.bootstrap_multiple_falcons = gp10b_pmu_acr_bootstrap_multiple_falcons,
};
static const struct nvkm_pmu_func
gp10b_pmu = {
.flcn = &gm200_pmu_flcn,
.enabled = gf100_pmu_enabled,
.intr = gt215_pmu_intr,
.recv = gm20b_pmu_recv,
.initmsg = gm20b_pmu_initmsg,
.reset = gp102_pmu_reset,
};
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
MODULE_FIRMWARE("nvidia/gp10b/pmu/desc.bin");
MODULE_FIRMWARE("nvidia/gp10b/pmu/image.bin");
......@@ -94,8 +84,8 @@ MODULE_FIRMWARE("nvidia/gp10b/pmu/sig.bin");
static const struct nvkm_pmu_fwif
gp10b_pmu_fwif[] = {
{ 0, gm20b_pmu_load, &gp10b_pmu, &gp10b_pmu_acr },
{ -1, gm200_pmu_nofw, &gp10b_pmu },
{ 0, gm20b_pmu_load, &gm20b_pmu, &gp10b_pmu_acr },
{ -1, gm200_pmu_nofw, &gm20b_pmu },
{}
};
......
......@@ -184,6 +184,7 @@ static void
gt215_pmu_reset(struct nvkm_pmu *pmu)
{
struct nvkm_device *device = pmu->subdev.device;
nvkm_mask(device, 0x022210, 0x00000001, 0x00000000);
nvkm_mask(device, 0x022210, 0x00000001, 0x00000001);
nvkm_rd32(device, 0x022210);
......@@ -201,6 +202,23 @@ gt215_pmu_init(struct nvkm_pmu *pmu)
struct nvkm_device *device = pmu->subdev.device;
int i;
/* Inhibit interrupts, and wait for idle. */
if (pmu->func->enabled(pmu)) {
nvkm_wr32(device, 0x10a014, 0x0000ffff);
nvkm_msec(device, 2000,
if (!nvkm_rd32(device, 0x10a04c))
break;
);
}
pmu->func->reset(pmu);
/* Wait for IMEM/DMEM scrubbing to be complete. */
nvkm_msec(device, 2000,
if (!(nvkm_rd32(device, 0x10a10c) & 0x00000006))
break;
);
/* upload data segment */
nvkm_wr32(device, 0x10a1c0, 0x01000000);
for (i = 0; i < pmu->func->data.size / 4; i++)
......@@ -243,20 +261,6 @@ gt215_pmu_init(struct nvkm_pmu *pmu)
const struct nvkm_falcon_func
gt215_pmu_flcn = {
.debug = 0xc08,
.fbif = 0xe00,
.load_imem = nvkm_falcon_v1_load_imem,
.load_dmem = nvkm_falcon_v1_load_dmem,
.read_dmem = nvkm_falcon_v1_read_dmem,
.bind_context = nvkm_falcon_v1_bind_context,
.wait_for_halt = nvkm_falcon_v1_wait_for_halt,
.clear_interrupt = nvkm_falcon_v1_clear_interrupt,
.set_start_addr = nvkm_falcon_v1_set_start_addr,
.start = nvkm_falcon_v1_start,
.enable = nvkm_falcon_v1_enable,
.disable = nvkm_falcon_v1_disable,
.cmdq = { 0x4a0, 0x4b0, 4 },
.msgq = { 0x4c8, 0x4cc, 0 },
};
static const struct nvkm_pmu_func
......
......@@ -47,12 +47,11 @@ void gk110_pmu_pgob(struct nvkm_pmu *, bool);
extern const struct nvkm_falcon_func gm200_pmu_flcn;
extern const struct nvkm_pmu_func gm20b_pmu;
void gm20b_pmu_acr_bld_patch(struct nvkm_acr *, u32, s64);
void gm20b_pmu_acr_bld_write(struct nvkm_acr *, u32, struct nvkm_acr_lsfw *);
int gm20b_pmu_acr_boot(struct nvkm_falcon *);
int gm20b_pmu_acr_bootstrap_falcon(struct nvkm_falcon *, enum nvkm_acr_lsf_id);
void gm20b_pmu_recv(struct nvkm_pmu *);
int gm20b_pmu_initmsg(struct nvkm_pmu *);
struct nvkm_pmu_fwif {
int version;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment