Commit 89cd6e20 authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Ben Skeggs

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: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 0296b5d9
......@@ -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;
......
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