|
@@ -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
|