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) ...@@ -81,6 +81,9 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
{ {
struct nvkm_pmu *pmu = nvkm_pmu(subdev); struct nvkm_pmu *pmu = nvkm_pmu(subdev);
if (!subdev->use.enabled)
return 0;
if (pmu->func->fini) if (pmu->func->fini)
pmu->func->fini(pmu); pmu->func->fini(pmu);
...@@ -94,42 +97,14 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend) ...@@ -94,42 +97,14 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend)
return 0; 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 static int
nvkm_pmu_init(struct nvkm_subdev *subdev) nvkm_pmu_init(struct nvkm_subdev *subdev)
{ {
struct nvkm_pmu *pmu = nvkm_pmu(subdev); struct nvkm_pmu *pmu = nvkm_pmu(subdev);
struct nvkm_device *device = pmu->subdev.device;
if (!pmu->func->init) if (!pmu->func->init)
return 0; 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); return pmu->func->init(pmu);
} }
......
...@@ -197,7 +197,6 @@ gk20a_dvfs_data= { ...@@ -197,7 +197,6 @@ gk20a_dvfs_data= {
static const struct nvkm_pmu_func static const struct nvkm_pmu_func
gk20a_pmu = { gk20a_pmu = {
.flcn = &gt215_pmu_flcn, .flcn = &gt215_pmu_flcn,
.enabled = gf100_pmu_enabled,
.init = gk20a_pmu_init, .init = gk20a_pmu_init,
.fini = gk20a_pmu_fini, .fini = gk20a_pmu_fini,
.reset = gf100_pmu_reset, .reset = gf100_pmu_reset,
......
...@@ -55,11 +55,9 @@ gm200_pmu_flcn = { ...@@ -55,11 +55,9 @@ gm200_pmu_flcn = {
static const struct nvkm_pmu_func static const struct nvkm_pmu_func
gm200_pmu = { gm200_pmu = {
.flcn = &gm200_pmu_flcn, .flcn = &gm200_pmu_flcn,
.enabled = gf100_pmu_enabled,
.reset = gf100_pmu_reset, .reset = gf100_pmu_reset,
}; };
int int
gm200_pmu_nofw(struct nvkm_pmu *pmu, int ver, const struct nvkm_pmu_fwif *fwif) 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) ...@@ -166,7 +166,7 @@ gm20b_pmu_acr_init_wpr(struct nvkm_pmu *pmu)
gm20b_pmu_acr_init_wpr_callback, pmu, 0); gm20b_pmu_acr_init_wpr_callback, pmu, 0);
} }
int static int
gm20b_pmu_initmsg(struct nvkm_pmu *pmu) gm20b_pmu_initmsg(struct nvkm_pmu *pmu)
{ {
struct nv_pmu_init_msg msg; struct nv_pmu_init_msg msg;
...@@ -192,7 +192,7 @@ gm20b_pmu_initmsg(struct nvkm_pmu *pmu) ...@@ -192,7 +192,7 @@ gm20b_pmu_initmsg(struct nvkm_pmu *pmu)
return gm20b_pmu_acr_init_wpr(pmu); return gm20b_pmu_acr_init_wpr(pmu);
} }
void static void
gm20b_pmu_recv(struct nvkm_pmu *pmu) gm20b_pmu_recv(struct nvkm_pmu *pmu)
{ {
if (!pmu->initmsg_received) { if (!pmu->initmsg_received) {
...@@ -209,10 +209,9 @@ gm20b_pmu_recv(struct nvkm_pmu *pmu) ...@@ -209,10 +209,9 @@ gm20b_pmu_recv(struct nvkm_pmu *pmu)
nvkm_falcon_msgq_recv(pmu->msgq); nvkm_falcon_msgq_recv(pmu->msgq);
} }
static const struct nvkm_pmu_func const struct nvkm_pmu_func
gm20b_pmu = { gm20b_pmu = {
.flcn = &gm200_pmu_flcn, .flcn = &gm200_pmu_flcn,
.enabled = gf100_pmu_enabled,
.intr = gt215_pmu_intr, .intr = gt215_pmu_intr,
.recv = gm20b_pmu_recv, .recv = gm20b_pmu_recv,
.initmsg = gm20b_pmu_initmsg, .initmsg = gm20b_pmu_initmsg,
......
...@@ -31,16 +31,9 @@ gp102_pmu_reset(struct nvkm_pmu *pmu) ...@@ -31,16 +31,9 @@ gp102_pmu_reset(struct nvkm_pmu *pmu)
nvkm_mask(device, 0x10a3c0, 0x00000001, 0x00000000); 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 static const struct nvkm_pmu_func
gp102_pmu = { gp102_pmu = {
.flcn = &gm200_pmu_flcn, .flcn = &gm200_pmu_flcn,
.enabled = gp102_pmu_enabled,
.reset = gp102_pmu_reset, .reset = gp102_pmu_reset,
}; };
......
...@@ -76,16 +76,6 @@ gp10b_pmu_acr = { ...@@ -76,16 +76,6 @@ gp10b_pmu_acr = {
.bootstrap_multiple_falcons = gp10b_pmu_acr_bootstrap_multiple_falcons, .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) #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
MODULE_FIRMWARE("nvidia/gp10b/pmu/desc.bin"); MODULE_FIRMWARE("nvidia/gp10b/pmu/desc.bin");
MODULE_FIRMWARE("nvidia/gp10b/pmu/image.bin"); MODULE_FIRMWARE("nvidia/gp10b/pmu/image.bin");
...@@ -94,8 +84,8 @@ MODULE_FIRMWARE("nvidia/gp10b/pmu/sig.bin"); ...@@ -94,8 +84,8 @@ MODULE_FIRMWARE("nvidia/gp10b/pmu/sig.bin");
static const struct nvkm_pmu_fwif static const struct nvkm_pmu_fwif
gp10b_pmu_fwif[] = { gp10b_pmu_fwif[] = {
{ 0, gm20b_pmu_load, &gp10b_pmu, &gp10b_pmu_acr }, { 0, gm20b_pmu_load, &gm20b_pmu, &gp10b_pmu_acr },
{ -1, gm200_pmu_nofw, &gp10b_pmu }, { -1, gm200_pmu_nofw, &gm20b_pmu },
{} {}
}; };
......
...@@ -184,6 +184,7 @@ static void ...@@ -184,6 +184,7 @@ static void
gt215_pmu_reset(struct nvkm_pmu *pmu) gt215_pmu_reset(struct nvkm_pmu *pmu)
{ {
struct nvkm_device *device = pmu->subdev.device; struct nvkm_device *device = pmu->subdev.device;
nvkm_mask(device, 0x022210, 0x00000001, 0x00000000); nvkm_mask(device, 0x022210, 0x00000001, 0x00000000);
nvkm_mask(device, 0x022210, 0x00000001, 0x00000001); nvkm_mask(device, 0x022210, 0x00000001, 0x00000001);
nvkm_rd32(device, 0x022210); nvkm_rd32(device, 0x022210);
...@@ -201,6 +202,23 @@ gt215_pmu_init(struct nvkm_pmu *pmu) ...@@ -201,6 +202,23 @@ gt215_pmu_init(struct nvkm_pmu *pmu)
struct nvkm_device *device = pmu->subdev.device; struct nvkm_device *device = pmu->subdev.device;
int i; 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 */ /* upload data segment */
nvkm_wr32(device, 0x10a1c0, 0x01000000); nvkm_wr32(device, 0x10a1c0, 0x01000000);
for (i = 0; i < pmu->func->data.size / 4; i++) for (i = 0; i < pmu->func->data.size / 4; i++)
...@@ -243,20 +261,6 @@ gt215_pmu_init(struct nvkm_pmu *pmu) ...@@ -243,20 +261,6 @@ gt215_pmu_init(struct nvkm_pmu *pmu)
const struct nvkm_falcon_func const struct nvkm_falcon_func
gt215_pmu_flcn = { 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 static const struct nvkm_pmu_func
......
...@@ -47,12 +47,11 @@ void gk110_pmu_pgob(struct nvkm_pmu *, bool); ...@@ -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_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_patch(struct nvkm_acr *, u32, s64);
void gm20b_pmu_acr_bld_write(struct nvkm_acr *, u32, struct nvkm_acr_lsfw *); 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_boot(struct nvkm_falcon *);
int gm20b_pmu_acr_bootstrap_falcon(struct nvkm_falcon *, enum nvkm_acr_lsf_id); 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 { struct nvkm_pmu_fwif {
int version; 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