Commit de088372 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/acr: store a mask of LS falcons the controlling LSFW can 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: default avatarBen Skeggs <bskeggs@redhat.com>
parent 587debc9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);
};
+6 −0
Original line number Diff line number Diff line
@@ -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,
};

+23 −6
Original line number Diff line number Diff line
@@ -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,14 +177,11 @@ 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)
		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);
+3 −0
Original line number Diff line number Diff line
@@ -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,
};

+3 −0
Original line number Diff line number Diff line
@@ -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,
};