drm/xe: Add test for GT workarounds and tunings
authorLucas De Marchi <lucas.demarchi@intel.com>
Sat, 1 Apr 2023 08:51:51 +0000 (01:51 -0700)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 19 Dec 2023 23:31:32 +0000 (18:31 -0500)
In order to avoid mistakes when populating the workarounds, it's good to
be able to test if the entries added are all compatible for a certain
platform. The platform itself is not needed as long as we create fake
devices with enough configuration for the RTP helpers to process the
tables.  Common mistakes that can be avoided:

- Entries clashing the bitfields being updated
- Register type being mixed (MCR vs regular / masked vs regular)
- Unexpected errors while adding the reg_sr entry

To test, inject a duplicate entry in gt_was, but with platform == tigerlake
rather than the currenct graphics version check:

       { XE_RTP_NAME("14011059788"),
 XE_RTP_RULES(PLATFORM(TIGERLAKE)),
 XE_RTP_ACTIONS(SET(GEN10_DFR_RATIO_EN_AND_CHICKEN, DFR_DISABLE))
       },

This produces the following result:

$  ./tools/testing/kunit/kunit.py run \
--kunitconfig drivers/gpu/drm/xe/.kunitconfig  xe_wa

[14:18:02] Starting KUnit Kernel (1/1)...
[14:18:02] ============================================================
[14:18:02] ==================== xe_wa (1 subtest) =====================
[14:18:02] ======================== xe_wa_gt  =========================
[14:18:02] [drm:xe_reg_sr_add] *ERROR* Discarding save-restore reg 9550 (clear: 00000200, set: 00000200, masked: no): ret=-22
[14:18:02]     # xe_wa_gt: ASSERTION FAILED at drivers/gpu/drm/xe/tests/xe_wa_test.c:116
[14:18:02]     Expected gt->reg_sr.errors == 0, but
[14:18:02]         gt->reg_sr.errors == 1 (0x1)
[14:18:02] [FAILED] TIGERLAKE (B0)
[14:18:02] [PASSED] DG1 (A0)
[14:18:02] [PASSED] DG1 (B0)
...

Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Michał Winiarski <michal.winiarski@intel.com>
Link: https://lore.kernel.org/r/20230401085151.1786204-8-lucas.demarchi@intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/tests/Makefile
drivers/gpu/drm/xe/tests/xe_wa_test.c [new file with mode: 0644]
drivers/gpu/drm/xe/xe_tuning.c
drivers/gpu/drm/xe/xe_wa.c

index c5c2f108d017e4e72d044516cd8b5b2eab5ff395..56919abb3f2a5e292c04df6d1b73b654bb0f3767 100644 (file)
@@ -4,4 +4,5 @@ obj-$(CONFIG_DRM_XE_KUNIT_TEST) += \
        xe_bo_test.o \
        xe_dma_buf_test.o \
        xe_migrate_test.o \
-       xe_rtp_test.o
+       xe_rtp_test.o \
+       xe_wa_test.o
diff --git a/drivers/gpu/drm/xe/tests/xe_wa_test.c b/drivers/gpu/drm/xe/tests/xe_wa_test.c
new file mode 100644 (file)
index 0000000..7a86be8
--- /dev/null
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include <drm/drm_drv.h>
+#include <drm/drm_kunit_helpers.h>
+
+#include <kunit/test.h>
+
+#include "xe_device.h"
+#include "xe_pci_test.h"
+#include "xe_reg_sr.h"
+#include "xe_tuning.h"
+#include "xe_wa.h"
+
+struct platform_test_case {
+       const char *name;
+       enum xe_platform platform;
+       enum xe_subplatform subplatform;
+       struct xe_step_info step;
+};
+
+#define PLATFORM_CASE(platform__, graphics_step__)                             \
+       {                                                                       \
+               .name = #platform__ " (" #graphics_step__ ")",                  \
+               .platform = XE_ ## platform__,                                  \
+               .subplatform = XE_SUBPLATFORM_NONE,                             \
+               .step = { .graphics = STEP_ ## graphics_step__ }                \
+       }
+
+
+#define SUBPLATFORM_CASE(platform__, subplatform__, graphics_step__)                   \
+       {                                                                               \
+               .name = #platform__ "_" #subplatform__ " (" #graphics_step__ ")",       \
+               .platform = XE_ ## platform__,                                          \
+               .subplatform = XE_SUBPLATFORM_ ## platform__ ## _ ## subplatform__,     \
+               .step = { .graphics = STEP_ ## graphics_step__ }                        \
+       }
+
+static const struct platform_test_case cases[] = {
+       PLATFORM_CASE(TIGERLAKE, B0),
+       PLATFORM_CASE(DG1, A0),
+       PLATFORM_CASE(DG1, B0),
+       PLATFORM_CASE(ALDERLAKE_S, A0),
+       PLATFORM_CASE(ALDERLAKE_S, B0),
+       PLATFORM_CASE(ALDERLAKE_S, C0),
+       PLATFORM_CASE(ALDERLAKE_S, D0),
+       SUBPLATFORM_CASE(DG2, G10, A0),
+       SUBPLATFORM_CASE(DG2, G10, A1),
+       SUBPLATFORM_CASE(DG2, G10, B0),
+       SUBPLATFORM_CASE(DG2, G10, C0),
+       SUBPLATFORM_CASE(DG2, G11, A0),
+       SUBPLATFORM_CASE(DG2, G11, B0),
+       SUBPLATFORM_CASE(DG2, G11, B1),
+       SUBPLATFORM_CASE(DG2, G12, A0),
+       SUBPLATFORM_CASE(DG2, G12, A1),
+       PLATFORM_CASE(PVC, B0),
+       PLATFORM_CASE(PVC, B1),
+       PLATFORM_CASE(PVC, C0),
+};
+
+static void platform_desc(const struct platform_test_case *t, char *desc)
+{
+       strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
+}
+
+KUNIT_ARRAY_PARAM(platform, cases, platform_desc);
+
+static int xe_wa_test_init(struct kunit *test)
+{
+       const struct platform_test_case *param = test->param_value;
+       struct xe_device *xe;
+       struct device *dev;
+       int ret;
+
+       dev = drm_kunit_helper_alloc_device(test);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+       xe = drm_kunit_helper_alloc_drm_device(test, dev,
+                                              struct xe_device,
+                                              drm, DRIVER_GEM);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xe);
+
+       ret = xe_pci_fake_device_init(xe, param->platform, param->subplatform);
+       KUNIT_ASSERT_EQ(test, ret, 0);
+
+       xe->info.step = param->step;
+
+       /* TODO: init hw engines for engine/LRC WAs */
+       xe->drm.dev = dev;
+       test->priv = xe;
+
+       return 0;
+}
+
+static void xe_wa_test_exit(struct kunit *test)
+{
+       struct xe_device *xe = test->priv;
+
+       drm_kunit_helper_free_device(test, xe->drm.dev);
+}
+
+static void xe_wa_gt(struct kunit *test)
+{
+       struct xe_device *xe = test->priv;
+       struct xe_gt *gt;
+       int id;
+
+       for_each_gt(gt, xe, id) {
+               xe_reg_sr_init(&gt->reg_sr, "GT", xe);
+
+               xe_wa_process_gt(gt);
+               xe_tuning_process_gt(gt);
+
+               KUNIT_ASSERT_EQ(test, gt->reg_sr.errors, 0);
+       }
+}
+
+static struct kunit_case xe_wa_tests[] = {
+       KUNIT_CASE_PARAM(xe_wa_gt, platform_gen_params),
+       {}
+};
+
+static struct kunit_suite xe_rtp_test_suite = {
+       .name = "xe_wa",
+       .init = xe_wa_test_init,
+       .exit = xe_wa_test_exit,
+       .test_cases = xe_wa_tests,
+};
+
+kunit_test_suite(xe_rtp_test_suite);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
index 7ff5eb762da547f148360ac2136e12ed86653cbc..27cf1330facd627af7fc54c3682d0eba7e9f4f7d 100644 (file)
@@ -5,6 +5,8 @@
 
 #include "xe_tuning.h"
 
+#include <kunit/visibility.h>
+
 #include "regs/xe_gt_regs.h"
 #include "xe_gt_types.h"
 #include "xe_platform_types.h"
@@ -62,6 +64,7 @@ void xe_tuning_process_gt(struct xe_gt *gt)
 {
        xe_rtp_process(gt_tunings, &gt->reg_sr, gt, NULL);
 }
+EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_gt);
 
 /**
  * xe_tuning_process_lrc - process lrc tunings
index 59d2daab5929132b48735333b3f282b7fe2f89e6..a7d681b7538d48168196624d38ddc026310e57aa 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "xe_wa.h"
 
+#include <kunit/visibility.h>
 #include <linux/compiler_types.h>
 
 #include "regs/xe_engine_regs.h"
@@ -628,6 +629,7 @@ void xe_wa_process_gt(struct xe_gt *gt)
 {
        xe_rtp_process(gt_was, &gt->reg_sr, gt, NULL);
 }
+EXPORT_SYMBOL_IF_KUNIT(xe_wa_process_gt);
 
 /**
  * xe_wa_process_engine - process engine workaround table