From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp

---
 kernel/drivers/gpu/drm/i915/selftests/intel_uncore.c |  196 +++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 167 insertions(+), 29 deletions(-)

diff --git a/kernel/drivers/gpu/drm/i915/selftests/intel_uncore.c b/kernel/drivers/gpu/drm/i915/selftests/intel_uncore.c
index 81d9d31..0e4e6be 100644
--- a/kernel/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/kernel/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -67,6 +67,7 @@
 	} reg_lists[] = {
 		{ gen8_shadowed_regs, ARRAY_SIZE(gen8_shadowed_regs) },
 		{ gen11_shadowed_regs, ARRAY_SIZE(gen11_shadowed_regs) },
+		{ gen12_shadowed_regs, ARRAY_SIZE(gen12_shadowed_regs) },
 	};
 	const i915_reg_t *reg;
 	unsigned int i, j;
@@ -101,6 +102,7 @@
 		{ __chv_fw_ranges, ARRAY_SIZE(__chv_fw_ranges), false },
 		{ __gen9_fw_ranges, ARRAY_SIZE(__gen9_fw_ranges), true },
 		{ __gen11_fw_ranges, ARRAY_SIZE(__gen11_fw_ranges), true },
+		{ __gen12_fw_ranges, ARRAY_SIZE(__gen12_fw_ranges), true },
 	};
 	int err, i;
 
@@ -119,16 +121,150 @@
 	return 0;
 }
 
-static int intel_uncore_check_forcewake_domains(struct drm_i915_private *dev_priv)
+static int live_forcewake_ops(void *arg)
+{
+	static const struct reg {
+		const char *name;
+		unsigned long platforms;
+		unsigned int offset;
+	} registers[] = {
+		{
+			"RING_START",
+			INTEL_GEN_MASK(6, 7),
+			0x38,
+		},
+		{
+			"RING_MI_MODE",
+			INTEL_GEN_MASK(8, BITS_PER_LONG),
+			0x9c,
+		}
+	};
+	const struct reg *r;
+	struct intel_gt *gt = arg;
+	struct intel_uncore_forcewake_domain *domain;
+	struct intel_uncore *uncore = gt->uncore;
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+	intel_wakeref_t wakeref;
+	unsigned int tmp;
+	int err = 0;
+
+	GEM_BUG_ON(gt->awake);
+
+	/* vlv/chv with their pcu behave differently wrt reads */
+	if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915)) {
+		pr_debug("PCU fakes forcewake badly; skipping\n");
+		return 0;
+	}
+
+	/*
+	 * Not quite as reliable across the gen as one would hope.
+	 *
+	 * Either our theory of operation is incorrect, or there remain
+	 * external parties interfering with the powerwells.
+	 *
+	 * https://bugs.freedesktop.org/show_bug.cgi?id=110210
+	 */
+	if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN))
+		return 0;
+
+	/* We have to pick carefully to get the exact behaviour we need */
+	for (r = registers; r->name; r++)
+		if (r->platforms & INTEL_INFO(gt->i915)->gen_mask)
+			break;
+	if (!r->name) {
+		pr_debug("Forcewaked register not known for %s; skipping\n",
+			 intel_platform_name(INTEL_INFO(gt->i915)->platform));
+		return 0;
+	}
+
+	wakeref = intel_runtime_pm_get(uncore->rpm);
+
+	for_each_fw_domain(domain, uncore, tmp) {
+		smp_store_mb(domain->active, false);
+		if (!hrtimer_cancel(&domain->timer))
+			continue;
+
+		intel_uncore_fw_release_timer(&domain->timer);
+	}
+
+	for_each_engine(engine, gt, id) {
+		i915_reg_t mmio = _MMIO(engine->mmio_base + r->offset);
+		u32 __iomem *reg = uncore->regs + engine->mmio_base + r->offset;
+		enum forcewake_domains fw_domains;
+		u32 val;
+
+		if (!engine->default_state)
+			continue;
+
+		fw_domains = intel_uncore_forcewake_for_reg(uncore, mmio,
+							    FW_REG_READ);
+		if (!fw_domains)
+			continue;
+
+		for_each_fw_domain_masked(domain, fw_domains, uncore, tmp) {
+			if (!domain->wake_count)
+				continue;
+
+			pr_err("fw_domain %s still active, aborting test!\n",
+			       intel_uncore_forcewake_domain_to_str(domain->id));
+			err = -EINVAL;
+			goto out_rpm;
+		}
+
+		intel_uncore_forcewake_get(uncore, fw_domains);
+		val = readl(reg);
+		intel_uncore_forcewake_put(uncore, fw_domains);
+
+		/* Flush the forcewake release (delayed onto a timer) */
+		for_each_fw_domain_masked(domain, fw_domains, uncore, tmp) {
+			smp_store_mb(domain->active, false);
+			if (hrtimer_cancel(&domain->timer))
+				intel_uncore_fw_release_timer(&domain->timer);
+
+			preempt_disable();
+			err = wait_ack_clear(domain, FORCEWAKE_KERNEL);
+			preempt_enable();
+			if (err) {
+				pr_err("Failed to clear fw_domain %s\n",
+				       intel_uncore_forcewake_domain_to_str(domain->id));
+				goto out_rpm;
+			}
+		}
+
+		if (!val) {
+			pr_err("%s:%s was zero while fw was held!\n",
+			       engine->name, r->name);
+			err = -EINVAL;
+			goto out_rpm;
+		}
+
+		/* We then expect the read to return 0 outside of the fw */
+		if (wait_for(readl(reg) == 0, 100)) {
+			pr_err("%s:%s=%0x, fw_domains 0x%x still up after 100ms!\n",
+			       engine->name, r->name, readl(reg), fw_domains);
+			err = -ETIMEDOUT;
+			goto out_rpm;
+		}
+	}
+
+out_rpm:
+	intel_runtime_pm_put(uncore->rpm, wakeref);
+	return err;
+}
+
+static int live_forcewake_domains(void *arg)
 {
 #define FW_RANGE 0x40000
+	struct intel_gt *gt = arg;
+	struct intel_uncore *uncore = gt->uncore;
 	unsigned long *valid;
 	u32 offset;
 	int err;
 
-	if (!HAS_FPGA_DBG_UNCLAIMED(dev_priv) &&
-	    !IS_VALLEYVIEW(dev_priv) &&
-	    !IS_CHERRYVIEW(dev_priv))
+	if (!HAS_FPGA_DBG_UNCLAIMED(gt->i915) &&
+	    !IS_VALLEYVIEW(gt->i915) &&
+	    !IS_CHERRYVIEW(gt->i915))
 		return 0;
 
 	/*
@@ -137,60 +273,62 @@
 	if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN))
 		return 0;
 
-	valid = kcalloc(BITS_TO_LONGS(FW_RANGE), sizeof(*valid),
-			GFP_KERNEL);
+	valid = bitmap_zalloc(FW_RANGE, GFP_KERNEL);
 	if (!valid)
 		return -ENOMEM;
 
-	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
 
-	check_for_unclaimed_mmio(dev_priv);
+	check_for_unclaimed_mmio(uncore);
 	for (offset = 0; offset < FW_RANGE; offset += 4) {
 		i915_reg_t reg = { offset };
 
-		(void)I915_READ_FW(reg);
-		if (!check_for_unclaimed_mmio(dev_priv))
+		intel_uncore_posting_read_fw(uncore, reg);
+		if (!check_for_unclaimed_mmio(uncore))
 			set_bit(offset, valid);
 	}
 
-	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
 
 	err = 0;
 	for_each_set_bit(offset, valid, FW_RANGE) {
 		i915_reg_t reg = { offset };
 
 		iosf_mbi_punit_acquire();
-		intel_uncore_forcewake_reset(dev_priv);
+		intel_uncore_forcewake_reset(uncore);
 		iosf_mbi_punit_release();
 
-		check_for_unclaimed_mmio(dev_priv);
+		check_for_unclaimed_mmio(uncore);
 
-		(void)I915_READ(reg);
-		if (check_for_unclaimed_mmio(dev_priv)) {
+		intel_uncore_posting_read_fw(uncore, reg);
+		if (check_for_unclaimed_mmio(uncore)) {
 			pr_err("Unclaimed mmio read to register 0x%04x\n",
 			       offset);
 			err = -EINVAL;
 		}
 	}
 
-	kfree(valid);
+	bitmap_free(valid);
 	return err;
+}
+
+static int live_fw_table(void *arg)
+{
+	struct intel_gt *gt = arg;
+
+	/* Confirm the table we load is still valid */
+	return intel_fw_table_check(gt->uncore->fw_domains_table,
+				    gt->uncore->fw_domains_table_entries,
+				    INTEL_GEN(gt->i915) >= 9);
 }
 
 int intel_uncore_live_selftests(struct drm_i915_private *i915)
 {
-	int err;
+	static const struct i915_subtest tests[] = {
+		SUBTEST(live_fw_table),
+		SUBTEST(live_forcewake_ops),
+		SUBTEST(live_forcewake_domains),
+	};
 
-	/* Confirm the table we load is still valid */
-	err = intel_fw_table_check(i915->uncore.fw_domains_table,
-				   i915->uncore.fw_domains_table_entries,
-				   INTEL_GEN(i915) >= 9);
-	if (err)
-		return err;
-
-	err = intel_uncore_check_forcewake_domains(i915);
-	if (err)
-		return err;
-
-	return 0;
+	return intel_gt_live_subtests(tests, &i915->gt);
 }

--
Gitblit v1.6.2