File Index
Files and directories
Sign in
FILE

xe_mocs.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/xe/tests/xe_mocs.c C
  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_FORCEWAKE_ALL);
 50	if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) {
 51		xe_force_wake_put(gt_to_fw(gt), fw_ref);
 52		KUNIT_FAIL_AND_ABORT(test, "Forcewake Failed.\n");
 53	}
 54
 55	for (i = 0; i < info->num_mocs_regs; i++) {
 56		if (!(i & 1)) {
 57			if (regs_are_mcr(gt))
 58				reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_LNCFCMOCS(i >> 1));
 59			else
 60				reg_val = xe_mmio_read32(&gt->mmio, XELP_LNCFCMOCS(i >> 1));
 61
 62			mocs_dbg(gt, "reg_val=0x%x\n", reg_val);
 63		} else {
 64			/* Just reuse value read on previous iteration */
 65			reg_val >>= 16;
 66		}
 67
 68		l3cc_expected = get_entry_l3cc(info, i);
 69		l3cc = reg_val & 0xffff;
 70
 71		mocs_dbg(gt, "[%u] expected=0x%x actual=0x%x\n",
 72			 i, l3cc_expected, l3cc);
 73
 74		KUNIT_EXPECT_EQ_MSG(test, l3cc_expected, l3cc,
 75				    "l3cc idx=%u has incorrect val.\n", i);
 76	}
 77	xe_force_wake_put(gt_to_fw(gt), fw_ref);
 78}
 79
 80static void read_mocs_table(struct xe_gt *gt,
 81			    const struct xe_mocs_info *info)
 82{
 83	struct kunit *test = kunit_get_current_test();
 84	u32 mocs, mocs_expected;
 85	unsigned int fw_ref, i;
 86	u32 reg_val;
 87
 88	KUNIT_EXPECT_TRUE_MSG(test, info->unused_entries_index,
 89			      "Unused entries index should have been defined\n");
 90
 91	fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
 92	KUNIT_ASSERT_NE_MSG(test, fw_ref, 0, "Forcewake Failed.\n");
 93
 94	for (i = 0; i < info->num_mocs_regs; i++) {
 95		if (regs_are_mcr(gt))
 96			reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_GLOBAL_MOCS(i));
 97		else
 98			reg_val = xe_mmio_read32(&gt->mmio, XELP_GLOBAL_MOCS(i));
 99
100		mocs_expected = get_entry_control(info, i);
101		mocs = reg_val;
102
103		mocs_dbg(gt, "[%u] expected=0x%x actual=0x%x\n",
104			 i, mocs_expected, mocs);
105
106		KUNIT_EXPECT_EQ_MSG(test, mocs_expected, mocs,
107				    "mocs reg 0x%x has incorrect val.\n", i);
108	}
109
110	xe_force_wake_put(gt_to_fw(gt), fw_ref);
111}
112
113static int mocs_kernel_test_run_device(struct xe_device *xe)
114{
115	/* Basic check the system is configured with the expected mocs table */
116
117	struct live_mocs mocs;
118	struct xe_gt *gt;
119
120	unsigned int flags;
121	int id;
122
123	xe_pm_runtime_get(xe);
124
125	for_each_gt(gt, xe, id) {
126		flags = live_mocs_init(&mocs, gt);
127		if (flags & HAS_GLOBAL_MOCS)
128			read_mocs_table(gt, &mocs.table);
129		if (flags & HAS_LNCF_MOCS)
130			read_l3cc_table(gt, &mocs.table);
131	}
132
133	xe_pm_runtime_put(xe);
134
135	return 0;
136}
137
138static void xe_live_mocs_kernel_kunit(struct kunit *test)
139{
140	struct xe_device *xe = test->priv;
141
142	if (IS_SRIOV_VF(xe))
143		kunit_skip(test, "this test is N/A for VF");
144
145	mocs_kernel_test_run_device(xe);
146}
147
148static int mocs_reset_test_run_device(struct xe_device *xe)
149{
150	/* Check the mocs setup is retained over GT reset */
151
152	struct live_mocs mocs;
153	struct xe_gt *gt;
154	unsigned int flags;
155	int id;
156	struct kunit *test = kunit_get_current_test();
157
158	xe_pm_runtime_get(xe);
159
160	for_each_gt(gt, xe, id) {
161		flags = live_mocs_init(&mocs, gt);
162		kunit_info(test, "mocs_reset_test before reset\n");
163		if (flags & HAS_GLOBAL_MOCS)
164			read_mocs_table(gt, &mocs.table);
165		if (flags & HAS_LNCF_MOCS)
166			read_l3cc_table(gt, &mocs.table);
167
168		xe_gt_reset(gt);
169
170		kunit_info(test, "mocs_reset_test after reset\n");
171		if (flags & HAS_GLOBAL_MOCS)
172			read_mocs_table(gt, &mocs.table);
173		if (flags & HAS_LNCF_MOCS)
174			read_l3cc_table(gt, &mocs.table);
175	}
176
177	xe_pm_runtime_put(xe);
178
179	return 0;
180}
181
182static void xe_live_mocs_reset_kunit(struct kunit *test)
183{
184	struct xe_device *xe = test->priv;
185
186	if (IS_SRIOV_VF(xe))
187		kunit_skip(test, "this test is N/A for VF");
188
189	mocs_reset_test_run_device(xe);
190}
191
192static struct kunit_case xe_mocs_tests[] = {
193	KUNIT_CASE_PARAM(xe_live_mocs_kernel_kunit, xe_pci_live_device_gen_param),
194	KUNIT_CASE_PARAM(xe_live_mocs_reset_kunit, xe_pci_live_device_gen_param),
195	{}
196};
197
198VISIBLE_IF_KUNIT
199struct kunit_suite xe_mocs_test_suite = {
200	.name = "xe_mocs",
201	.test_cases = xe_mocs_tests,
202	.init = xe_kunit_helper_xe_device_live_test_init,
203};
204EXPORT_SYMBOL_IF_KUNIT(xe_mocs_test_suite);
~/ Read-only file preview.