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

Submitted by Alexandre Courbot on Dec. 6, 2016, 5:35 a.m.

Details

Message ID 28f11950c6672413f767594807563004bfc5cae5.1480998636.git-series.acourbot@nvidia.com
State New
Headers show
Series "Falcon library" ( rev: 2 1 ) in Nouveau

Not browsing as part of any series.

Commit Message

Alexandre Courbot Dec. 6, 2016, 5:35 a.m.
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@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(-)

Patch hide | download patch | download mbox

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;