diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c | 98 |
1 files changed, 48 insertions, 50 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 7cf1492d3922..c0c25cf5404b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -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 |