summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/selftests/i915_selftest.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/selftests/i915_selftest.c')
-rw-r--r--drivers/gpu/drm/i915/selftests/i915_selftest.c84
1 files changed, 81 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/selftests/i915_selftest.c b/drivers/gpu/drm/i915/selftests/i915_selftest.c
index 39da0fb0d6d2..8460f0a70d04 100644
--- a/drivers/gpu/drm/i915/selftests/i915_selftest.c
+++ b/drivers/gpu/drm/i915/selftests/i915_selftest.c
@@ -23,11 +23,16 @@
#include <linux/random.h>
+#include "gt/intel_gt.h"
#include "gt/intel_gt_pm.h"
+#include "gt/intel_gt_regs.h"
+#include "gt/uc/intel_gsc_fw.h"
+
#include "i915_driver.h"
#include "i915_drv.h"
+#include "i915_jiffies.h"
#include "i915_selftest.h"
-
+#include "i915_wait_util.h"
#include "igt_flush_test.h"
struct i915_selftest i915_selftest __read_mostly = {
@@ -127,6 +132,55 @@ static void set_default_test_all(struct selftest *st, unsigned int count)
st[i].enabled = true;
}
+static bool
+__gsc_proxy_init_progressing(struct intel_gsc_uc *gsc)
+{
+ return intel_gsc_uc_fw_proxy_get_status(gsc) == -EAGAIN;
+}
+
+static void
+__wait_gsc_proxy_completed(struct drm_i915_private *i915)
+{
+ bool need_to_wait = (IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY) &&
+ i915->media_gt &&
+ HAS_ENGINE(i915->media_gt, GSC0) &&
+ intel_uc_fw_is_loadable(&i915->media_gt->uc.gsc.fw));
+ /*
+ * The gsc proxy component depends on the kernel component driver load ordering
+ * and in corner cases (the first time after an IFWI flash), init-completion
+ * firmware flows take longer.
+ */
+ unsigned long timeout_ms = 8000;
+
+ if (need_to_wait && wait_for(!__gsc_proxy_init_progressing(&i915->media_gt->uc.gsc),
+ timeout_ms))
+ pr_warn(DRIVER_NAME "Timed out waiting for gsc_proxy_completion!\n");
+}
+
+static void
+__wait_gsc_huc_load_completed(struct drm_i915_private *i915)
+{
+ /* this only applies to DG2, so we only care about GT0 */
+ struct intel_huc *huc = &to_gt(i915)->uc.huc;
+ bool need_to_wait = (IS_ENABLED(CONFIG_INTEL_MEI_PXP) &&
+ intel_huc_wait_required(huc));
+ /*
+ * The GSC and PXP mei bringup depends on the kernel boot ordering, so
+ * to account for the worst case scenario the HuC code waits for up to
+ * 10s for the GSC driver to load and then another 5s for the PXP
+ * component to bind before giving up, even though those steps normally
+ * complete in less than a second from the i915 load. We match that
+ * timeout here, but we expect to bail early due to the fence being
+ * signalled even in a failure case, as it is extremely unlikely that
+ * both components will use their full timeout.
+ */
+ unsigned long timeout_ms = 15000;
+
+ if (need_to_wait &&
+ wait_for(i915_sw_fence_done(&huc->delayed_load.fence), timeout_ms))
+ pr_warn(DRIVER_NAME "Timed out waiting for huc load via GSC!\n");
+}
+
static int __run_selftests(const char *name,
struct selftest *st,
unsigned int count,
@@ -201,12 +255,32 @@ int i915_mock_selftests(void)
int i915_live_selftests(struct pci_dev *pdev)
{
+ struct drm_i915_private *i915 = pdev_to_i915(pdev);
+ struct intel_uncore *uncore = &i915->uncore;
int err;
+ u32 pg_enable;
+ intel_wakeref_t wakeref;
if (!i915_selftest.live)
return 0;
- err = run_selftests(live, pdev_to_i915(pdev));
+ /*
+ * FIXME Disable render powergating, this is temporary wa and should be removed
+ * after fixing real cause of forcewake timeouts.
+ */
+ with_intel_runtime_pm(uncore->rpm, wakeref) {
+ if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 00), IP_VER(12, 74))) {
+ pg_enable = intel_uncore_read(uncore, GEN9_PG_ENABLE);
+ if (pg_enable & GEN9_RENDER_PG_ENABLE)
+ intel_uncore_write_fw(uncore, GEN9_PG_ENABLE,
+ pg_enable & ~GEN9_RENDER_PG_ENABLE);
+ }
+ }
+
+ __wait_gsc_proxy_completed(i915);
+ __wait_gsc_huc_load_completed(i915);
+
+ err = run_selftests(live, i915);
if (err) {
i915_selftest.live = err;
return err;
@@ -222,12 +296,16 @@ int i915_live_selftests(struct pci_dev *pdev)
int i915_perf_selftests(struct pci_dev *pdev)
{
+ struct drm_i915_private *i915 = pdev_to_i915(pdev);
int err;
if (!i915_selftest.perf)
return 0;
- err = run_selftests(perf, pdev_to_i915(pdev));
+ __wait_gsc_proxy_completed(i915);
+ __wait_gsc_huc_load_completed(i915);
+
+ err = run_selftests(perf, i915);
if (err) {
i915_selftest.perf = err;
return err;