[Nouveau] [PATCH 7/8] gr/gf100: use falcon library

Alexandre Courbot acourbot at nvidia.com
Tue Dec 6 05:35:44 UTC 2016


Use the falcon library functions in GR instead of poking registers
directly.

Ideally GR should keep the FECS and GPCCS falcons for as long as it is
running, but the lack of a proper fini() function makes this difficult.
For now we keep the falcons for the call of gf100_gr_init_ctxctl().

Signed-off-by: Alexandre Courbot <acourbot at nvidia.com>
---
 drm/nouveau/nvkm/engine/gr/gf100.c | 72 +++++++++----------------------
 drm/nouveau/nvkm/engine/gr/gf100.h |  2 +-
 2 files changed, 25 insertions(+), 49 deletions(-)

diff --git a/drm/nouveau/nvkm/engine/gr/gf100.c b/drm/nouveau/nvkm/engine/gr/gf100.c
index 71b19f4cebe9..036aaeadcea7 100644
--- a/drm/nouveau/nvkm/engine/gr/gf100.c
+++ b/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -1385,26 +1385,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
@@ -1465,14 +1450,14 @@ gf100_gr_init_ctxctl_ext(struct gf100_gr *gr)
 	if (nvkm_secboot_is_managed(sb, NVKM_FALCON_FECS))
 		ret = nvkm_secboot_reset(sb, NVKM_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_FALCON_GPCCS))
 		ret = nvkm_secboot_reset(sb, NVKM_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;
 
@@ -1483,14 +1468,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_FALCON_GPCCS))
-		nvkm_secboot_start(sb, NVKM_FALCON_GPCCS);
-	else
-		nvkm_wr32(device, 0x41a100, 0x00000002);
-	if (nvkm_secboot_is_managed(sb, NVKM_FALCON_FECS))
-		nvkm_secboot_start(sb, NVKM_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;
@@ -1580,7 +1560,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;
@@ -1588,28 +1567,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 */
@@ -1644,13 +1611,20 @@ gf100_gr_init_ctxctl_int(struct gf100_gr *gr)
 int
 gf100_gr_init_ctxctl(struct gf100_gr *gr)
 {
+	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
 	int ret;
 
+	gr->fecs = nvkm_falcon_get(subdev, NVKM_FALCON_FECS);
+	gr->gpccs = nvkm_falcon_get(subdev, NVKM_FALCON_GPCCS);
+
 	if (gr->firmware)
 		ret = gf100_gr_init_ctxctl_ext(gr);
 	else
 		ret = gf100_gr_init_ctxctl_int(gr);
 
+	nvkm_falcon_put(gr->gpccs);
+	nvkm_falcon_put(gr->fecs);
+
 	return ret;
 }
 
diff --git a/drm/nouveau/nvkm/engine/gr/gf100.h b/drm/nouveau/nvkm/engine/gr/gf100.h
index 268b8d60ff73..5f484398021d 100644
--- a/drm/nouveau/nvkm/engine/gr/gf100.h
+++ b/drm/nouveau/nvkm/engine/gr/gf100.h
@@ -75,6 +75,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;
-- 
git-series 0.8.10


More information about the Nouveau mailing list