xref: /linux/drivers/gpu/drm/xe/tests/xe_mocs.c (revision cf1e6edbd1c8ba654f97071ccb748d87ef0115aa)
1a6a4ea6dSRuthuvikas Ravikumar // SPDX-License-Identifier: GPL-2.0 AND MIT
2a6a4ea6dSRuthuvikas Ravikumar /*
3a6a4ea6dSRuthuvikas Ravikumar  * Copyright © 2022 Intel Corporation
4a6a4ea6dSRuthuvikas Ravikumar  */
5a6a4ea6dSRuthuvikas Ravikumar 
6a6a4ea6dSRuthuvikas Ravikumar #include <kunit/test.h>
7a6a4ea6dSRuthuvikas Ravikumar #include <kunit/visibility.h>
8a6a4ea6dSRuthuvikas Ravikumar 
957ecead3SMichal Wajdeczko #include "tests/xe_kunit_helpers.h"
10a6a4ea6dSRuthuvikas Ravikumar #include "tests/xe_pci_test.h"
11a6a4ea6dSRuthuvikas Ravikumar #include "tests/xe_test.h"
12a6a4ea6dSRuthuvikas Ravikumar 
136a0784e6SRodrigo Vivi #include "xe_device.h"
14a6a4ea6dSRuthuvikas Ravikumar #include "xe_gt.h"
15a6a4ea6dSRuthuvikas Ravikumar #include "xe_mocs.h"
166a0784e6SRodrigo Vivi #include "xe_pci.h"
176a0784e6SRodrigo Vivi #include "xe_pm.h"
18a6a4ea6dSRuthuvikas Ravikumar 
19a6a4ea6dSRuthuvikas Ravikumar struct live_mocs {
20a6a4ea6dSRuthuvikas Ravikumar 	struct xe_mocs_info table;
21a6a4ea6dSRuthuvikas Ravikumar };
22a6a4ea6dSRuthuvikas Ravikumar 
23a6a4ea6dSRuthuvikas Ravikumar static int live_mocs_init(struct live_mocs *arg, struct xe_gt *gt)
24a6a4ea6dSRuthuvikas Ravikumar {
25a6a4ea6dSRuthuvikas Ravikumar 	unsigned int flags;
26bd85e00fSMichal Wajdeczko 	struct kunit *test = kunit_get_current_test();
27a6a4ea6dSRuthuvikas Ravikumar 
28a6a4ea6dSRuthuvikas Ravikumar 	memset(arg, 0, sizeof(*arg));
29a6a4ea6dSRuthuvikas Ravikumar 
30a6a4ea6dSRuthuvikas Ravikumar 	flags = get_mocs_settings(gt_to_xe(gt), &arg->table);
31a6a4ea6dSRuthuvikas Ravikumar 
3243154713SMatt Roper 	kunit_info(test, "gt %d", gt->info.id);
3343154713SMatt Roper 	kunit_info(test, "gt type %d", gt->info.type);
344279635eSMatt Roper 	kunit_info(test, "table size %d", arg->table.table_size);
35a6a4ea6dSRuthuvikas Ravikumar 	kunit_info(test, "table uc_index %d", arg->table.uc_index);
364279635eSMatt Roper 	kunit_info(test, "table num_mocs_regs %d", arg->table.num_mocs_regs);
37a6a4ea6dSRuthuvikas Ravikumar 
38a6a4ea6dSRuthuvikas Ravikumar 	return flags;
39a6a4ea6dSRuthuvikas Ravikumar }
40a6a4ea6dSRuthuvikas Ravikumar 
41a6a4ea6dSRuthuvikas Ravikumar static void read_l3cc_table(struct xe_gt *gt,
42a6a4ea6dSRuthuvikas Ravikumar 			    const struct xe_mocs_info *info)
43a6a4ea6dSRuthuvikas Ravikumar {
44bd85e00fSMichal Wajdeczko 	struct kunit *test = kunit_get_current_test();
4550a9ffe6SLucas De Marchi 	u32 l3cc, l3cc_expected;
46a6a4ea6dSRuthuvikas Ravikumar 	unsigned int i;
47a6a4ea6dSRuthuvikas Ravikumar 	u32 reg_val;
48a6a4ea6dSRuthuvikas Ravikumar 	u32 ret;
49a6a4ea6dSRuthuvikas Ravikumar 
50a6a4ea6dSRuthuvikas Ravikumar 	ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
51a6a4ea6dSRuthuvikas Ravikumar 	KUNIT_ASSERT_EQ_MSG(test, ret, 0, "Forcewake Failed.\n");
5225664e32SLucas De Marchi 
534279635eSMatt Roper 	for (i = 0; i < info->num_mocs_regs; i++) {
5450a9ffe6SLucas De Marchi 		if (!(i & 1)) {
5500e9062eSMatt Roper 			if (regs_are_mcr(gt))
5650a9ffe6SLucas De Marchi 				reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_LNCFCMOCS(i >> 1));
57a6a4ea6dSRuthuvikas Ravikumar 			else
5850a9ffe6SLucas De Marchi 				reg_val = xe_mmio_read32(gt, XELP_LNCFCMOCS(i >> 1));
5950a9ffe6SLucas De Marchi 
6043154713SMatt Roper 			mocs_dbg(gt, "reg_val=0x%x\n", reg_val);
6150a9ffe6SLucas De Marchi 		} else {
6250a9ffe6SLucas De Marchi 			/* Just re-use value read on previous iteration */
6350a9ffe6SLucas De Marchi 			reg_val >>= 16;
6450a9ffe6SLucas De Marchi 		}
6550a9ffe6SLucas De Marchi 
6650a9ffe6SLucas De Marchi 		l3cc_expected = get_entry_l3cc(info, i);
6750a9ffe6SLucas De Marchi 		l3cc = reg_val & 0xffff;
6850a9ffe6SLucas De Marchi 
6943154713SMatt Roper 		mocs_dbg(gt, "[%u] expected=0x%x actual=0x%x\n",
7050a9ffe6SLucas De Marchi 			 i, l3cc_expected, l3cc);
7150a9ffe6SLucas De Marchi 
7250a9ffe6SLucas De Marchi 		KUNIT_EXPECT_EQ_MSG(test, l3cc_expected, l3cc,
7350a9ffe6SLucas De Marchi 				    "l3cc idx=%u has incorrect val.\n", i);
74a6a4ea6dSRuthuvikas Ravikumar 	}
75a6a4ea6dSRuthuvikas Ravikumar 	xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
76a6a4ea6dSRuthuvikas Ravikumar }
77a6a4ea6dSRuthuvikas Ravikumar 
78a6a4ea6dSRuthuvikas Ravikumar static void read_mocs_table(struct xe_gt *gt,
79a6a4ea6dSRuthuvikas Ravikumar 			    const struct xe_mocs_info *info)
80a6a4ea6dSRuthuvikas Ravikumar {
81bd85e00fSMichal Wajdeczko 	struct kunit *test = kunit_get_current_test();
8250a9ffe6SLucas De Marchi 	u32 mocs, mocs_expected;
83a6a4ea6dSRuthuvikas Ravikumar 	unsigned int i;
84a6a4ea6dSRuthuvikas Ravikumar 	u32 reg_val;
85a6a4ea6dSRuthuvikas Ravikumar 	u32 ret;
86a6a4ea6dSRuthuvikas Ravikumar 
8717c20e3bSLucas De Marchi 	KUNIT_EXPECT_TRUE_MSG(test, info->unused_entries_index,
8817c20e3bSLucas De Marchi 			      "Unused entries index should have been defined\n");
8917c20e3bSLucas De Marchi 
90a6a4ea6dSRuthuvikas Ravikumar 	ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
91a6a4ea6dSRuthuvikas Ravikumar 	KUNIT_ASSERT_EQ_MSG(test, ret, 0, "Forcewake Failed.\n");
9225664e32SLucas De Marchi 
934279635eSMatt Roper 	for (i = 0; i < info->num_mocs_regs; i++) {
9400e9062eSMatt Roper 		if (regs_are_mcr(gt))
95a6a4ea6dSRuthuvikas Ravikumar 			reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_GLOBAL_MOCS(i));
96a6a4ea6dSRuthuvikas Ravikumar 		else
97a6a4ea6dSRuthuvikas Ravikumar 			reg_val = xe_mmio_read32(gt, XELP_GLOBAL_MOCS(i));
9850a9ffe6SLucas De Marchi 
9950a9ffe6SLucas De Marchi 		mocs_expected = get_entry_control(info, i);
10050a9ffe6SLucas De Marchi 		mocs = reg_val;
10150a9ffe6SLucas De Marchi 
10243154713SMatt Roper 		mocs_dbg(gt, "[%u] expected=0x%x actual=0x%x\n",
10350a9ffe6SLucas De Marchi 			 i, mocs_expected, mocs);
10450a9ffe6SLucas De Marchi 
10550a9ffe6SLucas De Marchi 		KUNIT_EXPECT_EQ_MSG(test, mocs_expected, mocs,
10650a9ffe6SLucas De Marchi 				    "mocs reg 0x%x has incorrect val.\n", i);
107a6a4ea6dSRuthuvikas Ravikumar 	}
10850a9ffe6SLucas De Marchi 
109a6a4ea6dSRuthuvikas Ravikumar 	xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
110a6a4ea6dSRuthuvikas Ravikumar }
111a6a4ea6dSRuthuvikas Ravikumar 
112a6a4ea6dSRuthuvikas Ravikumar static int mocs_kernel_test_run_device(struct xe_device *xe)
113a6a4ea6dSRuthuvikas Ravikumar {
114a6a4ea6dSRuthuvikas Ravikumar 	/* Basic check the system is configured with the expected mocs table */
115a6a4ea6dSRuthuvikas Ravikumar 
116a6a4ea6dSRuthuvikas Ravikumar 	struct live_mocs mocs;
117a6a4ea6dSRuthuvikas Ravikumar 	struct xe_gt *gt;
118a6a4ea6dSRuthuvikas Ravikumar 
119a6a4ea6dSRuthuvikas Ravikumar 	unsigned int flags;
120a6a4ea6dSRuthuvikas Ravikumar 	int id;
121a6a4ea6dSRuthuvikas Ravikumar 
1226a0784e6SRodrigo Vivi 	xe_pm_runtime_get(xe);
1236a0784e6SRodrigo Vivi 
124a6a4ea6dSRuthuvikas Ravikumar 	for_each_gt(gt, xe, id) {
125a6a4ea6dSRuthuvikas Ravikumar 		flags = live_mocs_init(&mocs, gt);
126a6a4ea6dSRuthuvikas Ravikumar 		if (flags & HAS_GLOBAL_MOCS)
127a6a4ea6dSRuthuvikas Ravikumar 			read_mocs_table(gt, &mocs.table);
128a6a4ea6dSRuthuvikas Ravikumar 		if (flags & HAS_LNCF_MOCS)
129a6a4ea6dSRuthuvikas Ravikumar 			read_l3cc_table(gt, &mocs.table);
130a6a4ea6dSRuthuvikas Ravikumar 	}
1316a0784e6SRodrigo Vivi 
1326a0784e6SRodrigo Vivi 	xe_pm_runtime_put(xe);
1336a0784e6SRodrigo Vivi 
134a6a4ea6dSRuthuvikas Ravikumar 	return 0;
135a6a4ea6dSRuthuvikas Ravikumar }
136a6a4ea6dSRuthuvikas Ravikumar 
137e97701a0SMichal Wajdeczko static void xe_live_mocs_kernel_kunit(struct kunit *test)
138a6a4ea6dSRuthuvikas Ravikumar {
13957ecead3SMichal Wajdeczko 	struct xe_device *xe = test->priv;
14057ecead3SMichal Wajdeczko 
141*cf1e6edbSMichal Wajdeczko 	if (IS_SRIOV_VF(xe))
142*cf1e6edbSMichal Wajdeczko 		kunit_skip(test, "this test is N/A for VF");
143*cf1e6edbSMichal Wajdeczko 
14457ecead3SMichal Wajdeczko 	mocs_kernel_test_run_device(xe);
145a6a4ea6dSRuthuvikas Ravikumar }
1460d68d065SRuthuvikas Ravikumar 
1470d68d065SRuthuvikas Ravikumar static int mocs_reset_test_run_device(struct xe_device *xe)
1480d68d065SRuthuvikas Ravikumar {
1490d68d065SRuthuvikas Ravikumar 	/* Check the mocs setup is retained over GT reset */
1500d68d065SRuthuvikas Ravikumar 
1510d68d065SRuthuvikas Ravikumar 	struct live_mocs mocs;
1520d68d065SRuthuvikas Ravikumar 	struct xe_gt *gt;
1530d68d065SRuthuvikas Ravikumar 	unsigned int flags;
1540d68d065SRuthuvikas Ravikumar 	int id;
155bd85e00fSMichal Wajdeczko 	struct kunit *test = kunit_get_current_test();
1560d68d065SRuthuvikas Ravikumar 
1576a0784e6SRodrigo Vivi 	xe_pm_runtime_get(xe);
1586a0784e6SRodrigo Vivi 
1590d68d065SRuthuvikas Ravikumar 	for_each_gt(gt, xe, id) {
1600d68d065SRuthuvikas Ravikumar 		flags = live_mocs_init(&mocs, gt);
1610d68d065SRuthuvikas Ravikumar 		kunit_info(test, "mocs_reset_test before reset\n");
1620d68d065SRuthuvikas Ravikumar 		if (flags & HAS_GLOBAL_MOCS)
1630d68d065SRuthuvikas Ravikumar 			read_mocs_table(gt, &mocs.table);
1640d68d065SRuthuvikas Ravikumar 		if (flags & HAS_LNCF_MOCS)
1650d68d065SRuthuvikas Ravikumar 			read_l3cc_table(gt, &mocs.table);
1660d68d065SRuthuvikas Ravikumar 
1670d68d065SRuthuvikas Ravikumar 		xe_gt_reset_async(gt);
1680d68d065SRuthuvikas Ravikumar 		flush_work(&gt->reset.worker);
1690d68d065SRuthuvikas Ravikumar 
1700d68d065SRuthuvikas Ravikumar 		kunit_info(test, "mocs_reset_test after reset\n");
1710d68d065SRuthuvikas Ravikumar 		if (flags & HAS_GLOBAL_MOCS)
1720d68d065SRuthuvikas Ravikumar 			read_mocs_table(gt, &mocs.table);
1730d68d065SRuthuvikas Ravikumar 		if (flags & HAS_LNCF_MOCS)
1740d68d065SRuthuvikas Ravikumar 			read_l3cc_table(gt, &mocs.table);
1750d68d065SRuthuvikas Ravikumar 	}
1766a0784e6SRodrigo Vivi 
1776a0784e6SRodrigo Vivi 	xe_pm_runtime_put(xe);
1786a0784e6SRodrigo Vivi 
1790d68d065SRuthuvikas Ravikumar 	return 0;
1800d68d065SRuthuvikas Ravikumar }
1810d68d065SRuthuvikas Ravikumar 
182e97701a0SMichal Wajdeczko static void xe_live_mocs_reset_kunit(struct kunit *test)
1830d68d065SRuthuvikas Ravikumar {
18457ecead3SMichal Wajdeczko 	struct xe_device *xe = test->priv;
18557ecead3SMichal Wajdeczko 
186*cf1e6edbSMichal Wajdeczko 	if (IS_SRIOV_VF(xe))
187*cf1e6edbSMichal Wajdeczko 		kunit_skip(test, "this test is N/A for VF");
188*cf1e6edbSMichal Wajdeczko 
18957ecead3SMichal Wajdeczko 	mocs_reset_test_run_device(xe);
1900d68d065SRuthuvikas Ravikumar }
191e97701a0SMichal Wajdeczko 
192e97701a0SMichal Wajdeczko static struct kunit_case xe_mocs_tests[] = {
19357ecead3SMichal Wajdeczko 	KUNIT_CASE_PARAM(xe_live_mocs_kernel_kunit, xe_pci_live_device_gen_param),
19457ecead3SMichal Wajdeczko 	KUNIT_CASE_PARAM(xe_live_mocs_reset_kunit, xe_pci_live_device_gen_param),
195e97701a0SMichal Wajdeczko 	{}
196e97701a0SMichal Wajdeczko };
197e97701a0SMichal Wajdeczko 
198e97701a0SMichal Wajdeczko VISIBLE_IF_KUNIT
199e97701a0SMichal Wajdeczko struct kunit_suite xe_mocs_test_suite = {
200e97701a0SMichal Wajdeczko 	.name = "xe_mocs",
201e97701a0SMichal Wajdeczko 	.test_cases = xe_mocs_tests,
20257ecead3SMichal Wajdeczko 	.init = xe_kunit_helper_xe_device_live_test_init,
203e97701a0SMichal Wajdeczko };
204e97701a0SMichal Wajdeczko EXPORT_SYMBOL_IF_KUNIT(xe_mocs_test_suite);
205