Blob Blame History Raw
From ebd83762367a5f49183f2e9d8713265148f255ee Mon Sep 17 00:00:00 2001
From: Ben Skeggs <bskeggs@redhat.com>
Date: Tue, 16 Jun 2020 14:57:31 +1000
Subject: drm/nouveau/acr: store a mask of LS falcons the controlling LSFW can
Git-commit: de088372da017df35f6545516815ee012ec92ff6
Patch-mainline: v5.9-rc1
References: jsc#SLE-12680, jsc#SLE-12880, jsc#SLE-12882, jsc#SLE-12883, jsc#SLE-13496, jsc#SLE-15322
 bootstrap

This will prevent some pain with broken firmware trees, as under some
circumstances the HSFW can fail and leave the GPU in a state we don't
know how to recover from.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 .../gpu/drm/nouveau/include/nvkm/subdev/acr.h |  3 ++
 .../gpu/drm/nouveau/nvkm/engine/sec2/gp102.c  |  6 ++++
 .../gpu/drm/nouveau/nvkm/subdev/acr/base.c    | 29 +++++++++++++++----
 .../gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c   |  3 ++
 .../gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c   |  3 ++
 5 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/acr.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/acr.h
index 5d9c3a966de6..836d8b932822 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/acr.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/acr.h
@@ -39,6 +39,8 @@ struct nvkm_acr {
 	struct list_head hsfw, hsf;
 	struct list_head lsfw, lsf;
 
+	u64 managed_falcons;
+
 	struct nvkm_memory *wpr;
 	u64 wpr_start;
 	u64 wpr_end;
@@ -107,6 +109,7 @@ struct nvkm_acr_lsf_func {
 	void (*bld_write)(struct nvkm_acr *, u32 bld, struct nvkm_acr_lsfw *);
 	void (*bld_patch)(struct nvkm_acr *, u32 bld, s64 adjust);
 	int (*boot)(struct nvkm_falcon *);
+	u64 bootstrap_falcons;
 	int (*bootstrap_falcon)(struct nvkm_falcon *, enum nvkm_acr_lsf_id);
 	int (*bootstrap_multiple_falcons)(struct nvkm_falcon *, u32 mask);
 };
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c
index a2a9a8418777..36b31bf7bc62 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/gp102.c
@@ -115,6 +115,9 @@ gp102_sec2_acr_0 = {
 	.bld_write = gp102_sec2_acr_bld_write,
 	.bld_patch = gp102_sec2_acr_bld_patch,
 	.boot = gp102_sec2_acr_boot,
+	.bootstrap_falcons = BIT_ULL(NVKM_ACR_LSF_FECS) |
+			     BIT_ULL(NVKM_ACR_LSF_GPCCS) |
+			     BIT_ULL(NVKM_ACR_LSF_SEC2),
 	.bootstrap_falcon = gp102_sec2_acr_bootstrap_falcon,
 };
 
@@ -294,6 +297,9 @@ gp102_sec2_acr_1 = {
 	.bld_write = gp102_sec2_acr_bld_write_1,
 	.bld_patch = gp102_sec2_acr_bld_patch_1,
 	.boot = gp102_sec2_acr_boot,
+	.bootstrap_falcons = BIT_ULL(NVKM_ACR_LSF_FECS) |
+			     BIT_ULL(NVKM_ACR_LSF_GPCCS) |
+			     BIT_ULL(NVKM_ACR_LSF_SEC2),
 	.bootstrap_falcon = gp102_sec2_acr_bootstrap_falcon,
 };
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c
index 51a669e7bf6a..c962df9910dd 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c
@@ -156,6 +156,9 @@ nvkm_acr_bootstrap_falcons(struct nvkm_device *device, unsigned long mask)
 		return -ENOSYS;
 	}
 
+	if ((mask & acrflcn->func->bootstrap_falcons) != mask)
+		return -ENOSYS;
+
 	if (acrflcn->func->bootstrap_multiple_falcons) {
 		return acrflcn->func->
 			bootstrap_multiple_falcons(acrflcn->falcon, mask);
@@ -174,13 +177,10 @@ bool
 nvkm_acr_managed_falcon(struct nvkm_device *device, enum nvkm_acr_lsf_id id)
 {
 	struct nvkm_acr *acr = device->acr;
-	struct nvkm_acr_lsf *lsf;
 
 	if (acr) {
-		list_for_each_entry(lsf, &acr->lsf, head) {
-			if (lsf->id == id)
-				return true;
-		}
+		if (acr->managed_falcons & BIT_ULL(id))
+			return true;
 	}
 
 	return false;
@@ -220,6 +220,7 @@ nvkm_acr_oneinit(struct nvkm_subdev *subdev)
 	struct nvkm_acr_lsfw *lsfw, *lsft;
 	struct nvkm_acr_lsf *lsf;
 	u32 wpr_size = 0;
+	u64 falcons;
 	int ret, i;
 
 	if (list_empty(&acr->hsfw)) {
@@ -255,12 +256,28 @@ nvkm_acr_oneinit(struct nvkm_subdev *subdev)
 		lsf->falcon = lsfw->falcon;
 		lsf->id = lsfw->id;
 		list_add_tail(&lsf->head, &acr->lsf);
+		acr->managed_falcons |= BIT_ULL(lsf->id);
 	}
 
 	/* Ensure the falcon that'll provide ACR functions is booted first. */
 	lsf = nvkm_acr_falcon(device);
-	if (lsf)
+	if (lsf) {
+		falcons = lsf->func->bootstrap_falcons;
 		list_move(&lsf->head, &acr->lsf);
+	} else {
+		falcons = acr->func->bootstrap_falcons;
+	}
+
+	/* Cull falcons that can't be bootstrapped, or the HSFW can fail to
+	 * boot and leave the GPU in a weird state.
+	 */
+	list_for_each_entry_safe(lsfw, lsft, &acr->lsfw, head) {
+		if (!(falcons & BIT_ULL(lsfw->id))) {
+			nvkm_warn(subdev, "%s falcon cannot be bootstrapped\n",
+				  nvkm_acr_lsf_id(lsfw->id));
+			nvkm_acr_lsfw_del(lsfw);
+		}
+	}
 
 	if (!acr->wpr_fw || acr->wpr_comp)
 		wpr_size = acr->func->wpr_layout(acr);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
index 3a0cca3d3c3b..cf91fd322c98 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c
@@ -126,6 +126,9 @@ gm20b_pmu_acr = {
 	.bld_write = gm20b_pmu_acr_bld_write,
 	.bld_patch = gm20b_pmu_acr_bld_patch,
 	.boot = gm20b_pmu_acr_boot,
+	.bootstrap_falcons = BIT_ULL(NVKM_ACR_LSF_PMU) |
+			     BIT_ULL(NVKM_ACR_LSF_FECS) |
+			     BIT_ULL(NVKM_ACR_LSF_GPCCS),
 	.bootstrap_falcon = gm20b_pmu_acr_bootstrap_falcon,
 };
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c
index fdfb1470587a..9a4aca2ad831 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp10b.c
@@ -69,6 +69,9 @@ gp10b_pmu_acr = {
 	.bld_write = gm20b_pmu_acr_bld_write,
 	.bld_patch = gm20b_pmu_acr_bld_patch,
 	.boot = gm20b_pmu_acr_boot,
+	.bootstrap_falcons = BIT_ULL(NVKM_ACR_LSF_PMU) |
+			     BIT_ULL(NVKM_ACR_LSF_FECS) |
+			     BIT_ULL(NVKM_ACR_LSF_GPCCS),
 	.bootstrap_falcon = gm20b_pmu_acr_bootstrap_falcon,
 	.bootstrap_multiple_falcons = gp10b_pmu_acr_bootstrap_multiple_falcons,
 };
-- 
2.29.2