xref: /linux/drivers/gpu/drm/xe/tests/xe_mocs.c (revision 431547134ef7b9cff90d5a7ab95d145136f2bec7)
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 
9a6a4ea6dSRuthuvikas Ravikumar #include "tests/xe_mocs_test.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;
26a6a4ea6dSRuthuvikas Ravikumar 	struct kunit *test = xe_cur_kunit();
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 
32*43154713SMatt Roper 	kunit_info(test, "gt %d", gt->info.id);
33*43154713SMatt Roper 	kunit_info(test, "gt type %d", gt->info.type);
34a6a4ea6dSRuthuvikas Ravikumar 	kunit_info(test, "table size %d", arg->table.size);
35a6a4ea6dSRuthuvikas Ravikumar 	kunit_info(test, "table uc_index %d", arg->table.uc_index);
36a6a4ea6dSRuthuvikas Ravikumar 	kunit_info(test, "table n_entries %d", arg->table.n_entries);
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 {
4450a9ffe6SLucas De Marchi 	struct kunit *test = xe_cur_kunit();
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 
5350a9ffe6SLucas De Marchi 	for (i = 0; i < info->n_entries; 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 
60*43154713SMatt 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 
69*43154713SMatt 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 {
8150a9ffe6SLucas De Marchi 	struct kunit *test = xe_cur_kunit();
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 
9325664e32SLucas De Marchi 	for (i = 0; i < info->n_entries; 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 
102*43154713SMatt 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 
137a6a4ea6dSRuthuvikas Ravikumar void xe_live_mocs_kernel_kunit(struct kunit *test)
138a6a4ea6dSRuthuvikas Ravikumar {
139a6a4ea6dSRuthuvikas Ravikumar 	xe_call_for_each_device(mocs_kernel_test_run_device);
140a6a4ea6dSRuthuvikas Ravikumar }
141a6a4ea6dSRuthuvikas Ravikumar EXPORT_SYMBOL_IF_KUNIT(xe_live_mocs_kernel_kunit);
1420d68d065SRuthuvikas Ravikumar 
1430d68d065SRuthuvikas Ravikumar static int mocs_reset_test_run_device(struct xe_device *xe)
1440d68d065SRuthuvikas Ravikumar {
1450d68d065SRuthuvikas Ravikumar 	/* Check the mocs setup is retained over GT reset */
1460d68d065SRuthuvikas Ravikumar 
1470d68d065SRuthuvikas Ravikumar 	struct live_mocs mocs;
1480d68d065SRuthuvikas Ravikumar 	struct xe_gt *gt;
1490d68d065SRuthuvikas Ravikumar 	unsigned int flags;
1500d68d065SRuthuvikas Ravikumar 	int id;
1510d68d065SRuthuvikas Ravikumar 	struct kunit *test = xe_cur_kunit();
1520d68d065SRuthuvikas Ravikumar 
1536a0784e6SRodrigo Vivi 	xe_pm_runtime_get(xe);
1546a0784e6SRodrigo Vivi 
1550d68d065SRuthuvikas Ravikumar 	for_each_gt(gt, xe, id) {
1560d68d065SRuthuvikas Ravikumar 		flags = live_mocs_init(&mocs, gt);
1570d68d065SRuthuvikas Ravikumar 		kunit_info(test, "mocs_reset_test before reset\n");
1580d68d065SRuthuvikas Ravikumar 		if (flags & HAS_GLOBAL_MOCS)
1590d68d065SRuthuvikas Ravikumar 			read_mocs_table(gt, &mocs.table);
1600d68d065SRuthuvikas Ravikumar 		if (flags & HAS_LNCF_MOCS)
1610d68d065SRuthuvikas Ravikumar 			read_l3cc_table(gt, &mocs.table);
1620d68d065SRuthuvikas Ravikumar 
1630d68d065SRuthuvikas Ravikumar 		xe_gt_reset_async(gt);
1640d68d065SRuthuvikas Ravikumar 		flush_work(&gt->reset.worker);
1650d68d065SRuthuvikas Ravikumar 
1660d68d065SRuthuvikas Ravikumar 		kunit_info(test, "mocs_reset_test after reset\n");
1670d68d065SRuthuvikas Ravikumar 		if (flags & HAS_GLOBAL_MOCS)
1680d68d065SRuthuvikas Ravikumar 			read_mocs_table(gt, &mocs.table);
1690d68d065SRuthuvikas Ravikumar 		if (flags & HAS_LNCF_MOCS)
1700d68d065SRuthuvikas Ravikumar 			read_l3cc_table(gt, &mocs.table);
1710d68d065SRuthuvikas Ravikumar 	}
1726a0784e6SRodrigo Vivi 
1736a0784e6SRodrigo Vivi 	xe_pm_runtime_put(xe);
1746a0784e6SRodrigo Vivi 
1750d68d065SRuthuvikas Ravikumar 	return 0;
1760d68d065SRuthuvikas Ravikumar }
1770d68d065SRuthuvikas Ravikumar 
1780d68d065SRuthuvikas Ravikumar void xe_live_mocs_reset_kunit(struct kunit *test)
1790d68d065SRuthuvikas Ravikumar {
1800d68d065SRuthuvikas Ravikumar 	xe_call_for_each_device(mocs_reset_test_run_device);
1810d68d065SRuthuvikas Ravikumar }
1820d68d065SRuthuvikas Ravikumar EXPORT_SYMBOL_IF_KUNIT(xe_live_mocs_reset_kunit);
183