Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1// SPDX-License-Identifier: GPL-2.0 AND MIT
  2/*
  3 * Copyright © 2022 Intel Corporation
  4 */
  5
  6#include <kunit/test.h>
  7#include <kunit/visibility.h>
  8
  9#include "tests/xe_kunit_helpers.h"
 10#include "tests/xe_pci_test.h"
 11#include "tests/xe_test.h"
 12
 13#include "xe_device.h"
 14#include "xe_gt.h"
 15#include "xe_mocs.h"
 16#include "xe_pci.h"
 17#include "xe_pm.h"
 18
 19struct live_mocs {
 20	struct xe_mocs_info table;
 21};
 22
 23static int live_mocs_init(struct live_mocs *arg, struct xe_gt *gt)
 24{
 25	unsigned int flags;
 26	struct kunit *test = kunit_get_current_test();
 27
 28	memset(arg, 0, sizeof(*arg));
 29
 30	flags = get_mocs_settings(gt_to_xe(gt), &arg->table);
 31
 32	kunit_info(test, "gt %d", gt->info.id);
 33	kunit_info(test, "gt type %d", gt->info.type);
 34	kunit_info(test, "table size %d", arg->table.table_size);
 35	kunit_info(test, "table uc_index %d", arg->table.uc_index);
 36	kunit_info(test, "table num_mocs_regs %d", arg->table.num_mocs_regs);
 37
 38	return flags;
 39}
 40
 41static void read_l3cc_table(struct xe_gt *gt,
 42			    const struct xe_mocs_info *info)
 43{
 44	struct kunit *test = kunit_get_current_test();
 45	u32 l3cc, l3cc_expected;
 46	unsigned int fw_ref, i;
 47	u32 reg_val;
 48
 49	fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
 50	KUNIT_ASSERT_NE_MSG(test, fw_ref, 0, "Forcewake Failed.\n");
 51
 52	for (i = 0; i < info->num_mocs_regs; i++) {
 53		if (!(i & 1)) {
 54			if (regs_are_mcr(gt))
 55				reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_LNCFCMOCS(i >> 1));
 56			else
 57				reg_val = xe_mmio_read32(&gt->mmio, XELP_LNCFCMOCS(i >> 1));
 58
 59			mocs_dbg(gt, "reg_val=0x%x\n", reg_val);
 60		} else {
 61			/* Just re-use value read on previous iteration */
 62			reg_val >>= 16;
 63		}
 64
 65		l3cc_expected = get_entry_l3cc(info, i);
 66		l3cc = reg_val & 0xffff;
 67
 68		mocs_dbg(gt, "[%u] expected=0x%x actual=0x%x\n",
 69			 i, l3cc_expected, l3cc);
 70
 71		KUNIT_EXPECT_EQ_MSG(test, l3cc_expected, l3cc,
 72				    "l3cc idx=%u has incorrect val.\n", i);
 73	}
 74	xe_force_wake_put(gt_to_fw(gt), fw_ref);
 75}
 76
 77static void read_mocs_table(struct xe_gt *gt,
 78			    const struct xe_mocs_info *info)
 79{
 80	struct kunit *test = kunit_get_current_test();
 81	u32 mocs, mocs_expected;
 82	unsigned int fw_ref, i;
 83	u32 reg_val;
 84
 85	KUNIT_EXPECT_TRUE_MSG(test, info->unused_entries_index,
 86			      "Unused entries index should have been defined\n");
 87
 88	fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
 89	KUNIT_ASSERT_NE_MSG(test, fw_ref, 0, "Forcewake Failed.\n");
 90
 91	for (i = 0; i < info->num_mocs_regs; i++) {
 92		if (regs_are_mcr(gt))
 93			reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_GLOBAL_MOCS(i));
 94		else
 95			reg_val = xe_mmio_read32(&gt->mmio, XELP_GLOBAL_MOCS(i));
 96
 97		mocs_expected = get_entry_control(info, i);
 98		mocs = reg_val;
 99
100		mocs_dbg(gt, "[%u] expected=0x%x actual=0x%x\n",
101			 i, mocs_expected, mocs);
102
103		KUNIT_EXPECT_EQ_MSG(test, mocs_expected, mocs,
104				    "mocs reg 0x%x has incorrect val.\n", i);
105	}
106
107	xe_force_wake_put(gt_to_fw(gt), fw_ref);
108}
109
110static int mocs_kernel_test_run_device(struct xe_device *xe)
111{
112	/* Basic check the system is configured with the expected mocs table */
113
114	struct live_mocs mocs;
115	struct xe_gt *gt;
116
117	unsigned int flags;
118	int id;
119
120	xe_pm_runtime_get(xe);
121
122	for_each_gt(gt, xe, id) {
123		flags = live_mocs_init(&mocs, gt);
124		if (flags & HAS_GLOBAL_MOCS)
125			read_mocs_table(gt, &mocs.table);
126		if (flags & HAS_LNCF_MOCS)
127			read_l3cc_table(gt, &mocs.table);
128	}
129
130	xe_pm_runtime_put(xe);
131
132	return 0;
133}
134
135static void xe_live_mocs_kernel_kunit(struct kunit *test)
136{
137	struct xe_device *xe = test->priv;
138
139	if (IS_SRIOV_VF(xe))
140		kunit_skip(test, "this test is N/A for VF");
141
142	mocs_kernel_test_run_device(xe);
143}
144
145static int mocs_reset_test_run_device(struct xe_device *xe)
146{
147	/* Check the mocs setup is retained over GT reset */
148
149	struct live_mocs mocs;
150	struct xe_gt *gt;
151	unsigned int flags;
152	int id;
153	struct kunit *test = kunit_get_current_test();
154
155	xe_pm_runtime_get(xe);
156
157	for_each_gt(gt, xe, id) {
158		flags = live_mocs_init(&mocs, gt);
159		kunit_info(test, "mocs_reset_test before reset\n");
160		if (flags & HAS_GLOBAL_MOCS)
161			read_mocs_table(gt, &mocs.table);
162		if (flags & HAS_LNCF_MOCS)
163			read_l3cc_table(gt, &mocs.table);
164
165		xe_gt_reset(gt);
166
167		kunit_info(test, "mocs_reset_test after reset\n");
168		if (flags & HAS_GLOBAL_MOCS)
169			read_mocs_table(gt, &mocs.table);
170		if (flags & HAS_LNCF_MOCS)
171			read_l3cc_table(gt, &mocs.table);
172	}
173
174	xe_pm_runtime_put(xe);
175
176	return 0;
177}
178
179static void xe_live_mocs_reset_kunit(struct kunit *test)
180{
181	struct xe_device *xe = test->priv;
182
183	if (IS_SRIOV_VF(xe))
184		kunit_skip(test, "this test is N/A for VF");
185
186	mocs_reset_test_run_device(xe);
187}
188
189static struct kunit_case xe_mocs_tests[] = {
190	KUNIT_CASE_PARAM(xe_live_mocs_kernel_kunit, xe_pci_live_device_gen_param),
191	KUNIT_CASE_PARAM(xe_live_mocs_reset_kunit, xe_pci_live_device_gen_param),
192	{}
193};
194
195VISIBLE_IF_KUNIT
196struct kunit_suite xe_mocs_test_suite = {
197	.name = "xe_mocs",
198	.test_cases = xe_mocs_tests,
199	.init = xe_kunit_helper_xe_device_live_test_init,
200};
201EXPORT_SYMBOL_IF_KUNIT(xe_mocs_test_suite);