drm/nouveau/gr/gf100: instantiate and reserve GR falcons
Create instances for the FECS and GPCCS falcons and use the init() and fini() hooks to reserve them for as long as GR controls them. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
0296b5d985
commit
89cd6e2071
|
@ -1391,26 +1391,11 @@ gf100_gr_intr(struct nvkm_gr *base)
|
|||
}
|
||||
|
||||
static void
|
||||
gf100_gr_init_fw(struct gf100_gr *gr, u32 fuc_base,
|
||||
gf100_gr_init_fw(struct nvkm_falcon *falcon,
|
||||
struct gf100_gr_fuc *code, struct gf100_gr_fuc *data)
|
||||
{
|
||||
struct nvkm_device *device = gr->base.engine.subdev.device;
|
||||
int i;
|
||||
|
||||
nvkm_wr32(device, fuc_base + 0x01c0, 0x01000000);
|
||||
for (i = 0; i < data->size / 4; i++)
|
||||
nvkm_wr32(device, fuc_base + 0x01c4, data->data[i]);
|
||||
|
||||
nvkm_wr32(device, fuc_base + 0x0180, 0x01000000);
|
||||
for (i = 0; i < code->size / 4; i++) {
|
||||
if ((i & 0x3f) == 0)
|
||||
nvkm_wr32(device, fuc_base + 0x0188, i >> 6);
|
||||
nvkm_wr32(device, fuc_base + 0x0184, code->data[i]);
|
||||
}
|
||||
|
||||
/* code must be padded to 0x40 words */
|
||||
for (; i & 0x3f; i++)
|
||||
nvkm_wr32(device, fuc_base + 0x0184, 0);
|
||||
nvkm_falcon_load_dmem(falcon, data->data, 0x0, data->size, 0);
|
||||
nvkm_falcon_load_imem(falcon, code->data, 0x0, code->size, 0, 0, false);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1471,14 +1456,14 @@ gf100_gr_init_ctxctl_ext(struct gf100_gr *gr)
|
|||
if (nvkm_secboot_is_managed(sb, NVKM_SECBOOT_FALCON_FECS))
|
||||
ret = nvkm_secboot_reset(sb, NVKM_SECBOOT_FALCON_FECS);
|
||||
else
|
||||
gf100_gr_init_fw(gr, 0x409000, &gr->fuc409c, &gr->fuc409d);
|
||||
gf100_gr_init_fw(gr->fecs, &gr->fuc409c, &gr->fuc409d);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (nvkm_secboot_is_managed(sb, NVKM_SECBOOT_FALCON_GPCCS))
|
||||
ret = nvkm_secboot_reset(sb, NVKM_SECBOOT_FALCON_GPCCS);
|
||||
else
|
||||
gf100_gr_init_fw(gr, 0x41a000, &gr->fuc41ac, &gr->fuc41ad);
|
||||
gf100_gr_init_fw(gr->gpccs, &gr->fuc41ac, &gr->fuc41ad);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1489,14 +1474,9 @@ gf100_gr_init_ctxctl_ext(struct gf100_gr *gr)
|
|||
nvkm_wr32(device, 0x41a10c, 0x00000000);
|
||||
nvkm_wr32(device, 0x40910c, 0x00000000);
|
||||
|
||||
if (nvkm_secboot_is_managed(sb, NVKM_SECBOOT_FALCON_GPCCS))
|
||||
nvkm_secboot_start(sb, NVKM_SECBOOT_FALCON_GPCCS);
|
||||
else
|
||||
nvkm_wr32(device, 0x41a100, 0x00000002);
|
||||
if (nvkm_secboot_is_managed(sb, NVKM_SECBOOT_FALCON_FECS))
|
||||
nvkm_secboot_start(sb, NVKM_SECBOOT_FALCON_FECS);
|
||||
else
|
||||
nvkm_wr32(device, 0x409100, 0x00000002);
|
||||
nvkm_falcon_start(gr->gpccs);
|
||||
nvkm_falcon_start(gr->fecs);
|
||||
|
||||
if (nvkm_msec(device, 2000,
|
||||
if (nvkm_rd32(device, 0x409800) & 0x00000001)
|
||||
break;
|
||||
|
@ -1586,7 +1566,6 @@ gf100_gr_init_ctxctl_int(struct gf100_gr *gr)
|
|||
const struct gf100_grctx_func *grctx = gr->func->grctx;
|
||||
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
int i;
|
||||
|
||||
if (!gr->func->fecs.ucode) {
|
||||
return -ENOSYS;
|
||||
|
@ -1594,28 +1573,16 @@ gf100_gr_init_ctxctl_int(struct gf100_gr *gr)
|
|||
|
||||
/* load HUB microcode */
|
||||
nvkm_mc_unk260(device, 0);
|
||||
nvkm_wr32(device, 0x4091c0, 0x01000000);
|
||||
for (i = 0; i < gr->func->fecs.ucode->data.size / 4; i++)
|
||||
nvkm_wr32(device, 0x4091c4, gr->func->fecs.ucode->data.data[i]);
|
||||
|
||||
nvkm_wr32(device, 0x409180, 0x01000000);
|
||||
for (i = 0; i < gr->func->fecs.ucode->code.size / 4; i++) {
|
||||
if ((i & 0x3f) == 0)
|
||||
nvkm_wr32(device, 0x409188, i >> 6);
|
||||
nvkm_wr32(device, 0x409184, gr->func->fecs.ucode->code.data[i]);
|
||||
}
|
||||
nvkm_falcon_load_dmem(gr->fecs, gr->func->fecs.ucode->data.data, 0x0,
|
||||
gr->func->fecs.ucode->data.size, 0);
|
||||
nvkm_falcon_load_imem(gr->fecs, gr->func->fecs.ucode->code.data, 0x0,
|
||||
gr->func->fecs.ucode->code.size, 0, 0, false);
|
||||
|
||||
/* load GPC microcode */
|
||||
nvkm_wr32(device, 0x41a1c0, 0x01000000);
|
||||
for (i = 0; i < gr->func->gpccs.ucode->data.size / 4; i++)
|
||||
nvkm_wr32(device, 0x41a1c4, gr->func->gpccs.ucode->data.data[i]);
|
||||
|
||||
nvkm_wr32(device, 0x41a180, 0x01000000);
|
||||
for (i = 0; i < gr->func->gpccs.ucode->code.size / 4; i++) {
|
||||
if ((i & 0x3f) == 0)
|
||||
nvkm_wr32(device, 0x41a188, i >> 6);
|
||||
nvkm_wr32(device, 0x41a184, gr->func->gpccs.ucode->code.data[i]);
|
||||
}
|
||||
nvkm_falcon_load_dmem(gr->gpccs, gr->func->gpccs.ucode->data.data, 0x0,
|
||||
gr->func->gpccs.ucode->data.size, 0);
|
||||
nvkm_falcon_load_imem(gr->gpccs, gr->func->gpccs.ucode->code.data, 0x0,
|
||||
gr->func->gpccs.ucode->code.size, 0, 0, false);
|
||||
nvkm_mc_unk260(device, 1);
|
||||
|
||||
/* load register lists */
|
||||
|
@ -1729,10 +1696,32 @@ static int
|
|||
gf100_gr_init_(struct nvkm_gr *base)
|
||||
{
|
||||
struct gf100_gr *gr = gf100_gr(base);
|
||||
struct nvkm_subdev *subdev = &base->engine.subdev;
|
||||
u32 ret;
|
||||
|
||||
nvkm_pmu_pgob(gr->base.engine.subdev.device->pmu, false);
|
||||
|
||||
ret = nvkm_falcon_get(gr->fecs, subdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nvkm_falcon_get(gr->gpccs, subdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return gr->func->init(gr);
|
||||
}
|
||||
|
||||
static int
|
||||
gf100_gr_fini_(struct nvkm_gr *base, bool suspend)
|
||||
{
|
||||
struct gf100_gr *gr = gf100_gr(base);
|
||||
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
|
||||
nvkm_falcon_put(gr->gpccs, subdev);
|
||||
nvkm_falcon_put(gr->fecs, subdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gf100_gr_dtor_fw(struct gf100_gr_fuc *fuc)
|
||||
{
|
||||
|
@ -1755,6 +1744,9 @@ gf100_gr_dtor(struct nvkm_gr *base)
|
|||
gr->func->dtor(gr);
|
||||
kfree(gr->data);
|
||||
|
||||
nvkm_falcon_del(&gr->gpccs);
|
||||
nvkm_falcon_del(&gr->fecs);
|
||||
|
||||
gf100_gr_dtor_fw(&gr->fuc409c);
|
||||
gf100_gr_dtor_fw(&gr->fuc409d);
|
||||
gf100_gr_dtor_fw(&gr->fuc41ac);
|
||||
|
@ -1773,6 +1765,7 @@ gf100_gr_ = {
|
|||
.dtor = gf100_gr_dtor,
|
||||
.oneinit = gf100_gr_oneinit,
|
||||
.init = gf100_gr_init_,
|
||||
.fini = gf100_gr_fini_,
|
||||
.intr = gf100_gr_intr,
|
||||
.units = gf100_gr_units,
|
||||
.chan_new = gf100_gr_chan_new,
|
||||
|
@ -1846,6 +1839,7 @@ int
|
|||
gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device,
|
||||
int index, struct gf100_gr *gr)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
|
||||
int ret;
|
||||
|
||||
gr->func = func;
|
||||
|
@ -1858,7 +1852,11 @@ gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
ret = nvkm_falcon_v1_new(subdev, "FECS", 0x409000, &gr->fecs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return nvkm_falcon_v1_new(subdev, "GPCCS", 0x41a000, &gr->gpccs);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <core/gpuobj.h>
|
||||
#include <subdev/ltc.h>
|
||||
#include <subdev/mmu.h>
|
||||
#include <engine/falcon.h>
|
||||
|
||||
#define GPC_MAX 32
|
||||
#define TPC_MAX_PER_GPC 8
|
||||
|
@ -75,6 +76,8 @@ struct gf100_gr {
|
|||
const struct gf100_gr_func *func;
|
||||
struct nvkm_gr base;
|
||||
|
||||
struct nvkm_falcon *fecs;
|
||||
struct nvkm_falcon *gpccs;
|
||||
struct gf100_gr_fuc fuc409c;
|
||||
struct gf100_gr_fuc fuc409d;
|
||||
struct gf100_gr_fuc fuc41ac;
|
||||
|
|
Loading…
Reference in New Issue