File Index
Files and directories
Sign in
FILE

xe_step.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/xe/xe_step.c C
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2022 Intel Corporation
  4 */
  5
  6#include "xe_step.h"
  7
  8#include <kunit/visibility.h>
  9#include <linux/bitfield.h>
 10
 11#include "xe_device.h"
 12#include "xe_platform_types.h"
 13
 14/*
 15 * Provide mapping between PCI's revision ID to the individual GMD
 16 * (Graphics/Media/Display) stepping values that can be compared numerically.
 17 *
 18 * Some platforms may have unusual ways of mapping PCI revision ID to GMD
 19 * steppings.  E.g., in some cases a higher PCI revision may translate to a
 20 * lower stepping of the GT and/or display IP.
 21 *
 22 * Also note that some revisions/steppings may have been set aside as
 23 * placeholders but never materialized in real hardware; in those cases there
 24 * may be jumps in the revision IDs or stepping values in the tables below.
 25 */
 26
 27/*
 28 * Some platforms always have the same stepping value for GT and display;
 29 * use a macro to define these to make it easier to identify the platforms
 30 * where the two steppings can deviate.
 31 */
 32#define COMMON_STEP(x_)			\
 33	.graphics = STEP_##x_,		\
 34	.media = STEP_##x_
 35
 36__diag_push();
 37__diag_ignore_all("-Woverride-init", "Allow field overrides in table");
 38
 39/* Same GT stepping between tgl_uy_revids and tgl_revids don't mean the same HW */
 40static const struct xe_step_info tgl_revids[] = {
 41	[0] = { COMMON_STEP(A0) },
 42	[1] = { COMMON_STEP(B0) },
 43};
 44
 45static const struct xe_step_info dg1_revids[] = {
 46	[0] = { COMMON_STEP(A0) },
 47	[1] = { COMMON_STEP(B0) },
 48};
 49
 50static const struct xe_step_info adls_revids[] = {
 51	[0x0] = { COMMON_STEP(A0) },
 52	[0x1] = { COMMON_STEP(A0) },
 53	[0x4] = { COMMON_STEP(B0) },
 54	[0x8] = { COMMON_STEP(C0) },
 55	[0xC] = { COMMON_STEP(D0) },
 56};
 57
 58static const struct xe_step_info adls_rpls_revids[] = {
 59	[0x4] = { COMMON_STEP(D0) },
 60	[0xC] = { COMMON_STEP(D0) },
 61};
 62
 63static const struct xe_step_info adlp_revids[] = {
 64	[0x0] = { COMMON_STEP(A0) },
 65	[0x4] = { COMMON_STEP(B0) },
 66	[0x8] = { COMMON_STEP(C0) },
 67	[0xC] = { COMMON_STEP(C0) },
 68};
 69
 70static const struct xe_step_info adlp_rpl_revids[] = {
 71	[0x4] = { COMMON_STEP(C0) },
 72};
 73
 74static const struct xe_step_info adln_revids[] = {
 75	[0x0] = { COMMON_STEP(A0) },
 76};
 77
 78static const struct xe_step_info dg2_g10_revid_step_tbl[] = {
 79	[0x0] = { COMMON_STEP(A0) },
 80	[0x1] = { COMMON_STEP(A1) },
 81	[0x4] = { COMMON_STEP(B0) },
 82	[0x8] = { COMMON_STEP(C0) },
 83};
 84
 85static const struct xe_step_info dg2_g11_revid_step_tbl[] = {
 86	[0x0] = { COMMON_STEP(A0) },
 87	[0x4] = { COMMON_STEP(B0) },
 88	[0x5] = { COMMON_STEP(B1) },
 89};
 90
 91static const struct xe_step_info dg2_g12_revid_step_tbl[] = {
 92	[0x0] = { COMMON_STEP(A0) },
 93	[0x1] = { COMMON_STEP(A1) },
 94};
 95
 96static const struct xe_step_info pvc_revid_step_tbl[] = {
 97	[0x5] = { .graphics = STEP_B0 },
 98	[0x6] = { .graphics = STEP_B1 },
 99	[0x7] = { .graphics = STEP_C0 },
100};
101
102static const int pvc_basedie_subids[] = {
103	[0x3] = STEP_B0,
104	[0x4] = STEP_B1,
105	[0x5] = STEP_B3,
106};
107
108__diag_pop();
109
110/**
111 * xe_step_pre_gmdid_get - Determine IP steppings from PCI revid
112 * @xe: Xe device
113 *
114 * Convert the PCI revid into proper IP steppings.  This should only be
115 * used on platforms that do not have GMD_ID support.
116 */
117struct xe_step_info xe_step_pre_gmdid_get(struct xe_device *xe)
118{
119	const struct xe_step_info *revids = NULL;
120	struct xe_step_info step = {};
121	u16 revid = xe->info.revid;
122	int size = 0;
123	const int *basedie_info = NULL;
124	int basedie_size = 0;
125	int baseid = 0;
126
127	if (xe->info.platform == XE_PVC) {
128		baseid = FIELD_GET(GENMASK(5, 3), xe->info.revid);
129		revid = FIELD_GET(GENMASK(2, 0), xe->info.revid);
130		revids = pvc_revid_step_tbl;
131		size = ARRAY_SIZE(pvc_revid_step_tbl);
132		basedie_info = pvc_basedie_subids;
133		basedie_size = ARRAY_SIZE(pvc_basedie_subids);
134	} else if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G10) {
135		revids = dg2_g10_revid_step_tbl;
136		size = ARRAY_SIZE(dg2_g10_revid_step_tbl);
137	} else if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G11) {
138		revids = dg2_g11_revid_step_tbl;
139		size = ARRAY_SIZE(dg2_g11_revid_step_tbl);
140	} else if (xe->info.subplatform == XE_SUBPLATFORM_DG2_G12) {
141		revids = dg2_g12_revid_step_tbl;
142		size = ARRAY_SIZE(dg2_g12_revid_step_tbl);
143	} else if (xe->info.platform == XE_ALDERLAKE_N) {
144		revids = adln_revids;
145		size = ARRAY_SIZE(adln_revids);
146	} else if (xe->info.subplatform == XE_SUBPLATFORM_ALDERLAKE_S_RPLS) {
147		revids = adls_rpls_revids;
148		size = ARRAY_SIZE(adls_rpls_revids);
149	} else if (xe->info.subplatform == XE_SUBPLATFORM_ALDERLAKE_P_RPLU) {
150		revids = adlp_rpl_revids;
151		size = ARRAY_SIZE(adlp_rpl_revids);
152	} else if (xe->info.platform == XE_ALDERLAKE_P) {
153		revids = adlp_revids;
154		size = ARRAY_SIZE(adlp_revids);
155	} else if (xe->info.platform == XE_ALDERLAKE_S) {
156		revids = adls_revids;
157		size = ARRAY_SIZE(adls_revids);
158	} else if (xe->info.platform == XE_DG1) {
159		revids = dg1_revids;
160		size = ARRAY_SIZE(dg1_revids);
161	} else if (xe->info.platform == XE_TIGERLAKE) {
162		revids = tgl_revids;
163		size = ARRAY_SIZE(tgl_revids);
164	}
165
166	/* Not using the stepping scheme for the platform yet. */
167	if (!revids)
168		return step;
169
170	if (revid < size && revids[revid].graphics != STEP_NONE) {
171		step = revids[revid];
172	} else {
173		drm_warn(&xe->drm, "Unknown revid 0x%02x\n", revid);
174
175		/*
176		 * If we hit a gap in the revid array, use the information for
177		 * the next revid.
178		 *
179		 * This may be wrong in all sorts of ways, especially if the
180		 * steppings in the array are not monotonically increasing, but
181		 * it's better than defaulting to 0.
182		 */
183		while (revid < size && revids[revid].graphics == STEP_NONE)
184			revid++;
185
186		if (revid < size) {
187			drm_dbg(&xe->drm, "Using steppings for revid 0x%02x\n",
188				revid);
189			step = revids[revid];
190		} else {
191			drm_dbg(&xe->drm, "Using future steppings\n");
192			step.graphics = STEP_FUTURE;
193		}
194	}
195
196	drm_WARN_ON(&xe->drm, step.graphics == STEP_NONE);
197
198	if (basedie_info && basedie_size) {
199		if (baseid < basedie_size && basedie_info[baseid] != STEP_NONE) {
200			step.basedie = basedie_info[baseid];
201		} else {
202			drm_warn(&xe->drm, "Unknown baseid 0x%02x\n", baseid);
203			step.basedie = STEP_FUTURE;
204		}
205	}
206
207	return step;
208}
209
210/**
211 * xe_step_gmdid_get - Determine IP steppings from GMD_ID revid fields
212 * @xe: Xe device
213 * @graphics_gmdid_revid: value of graphics GMD_ID register's revid field
214 * @media_gmdid_revid: value of media GMD_ID register's revid field
215 *
216 * Convert the revid fields of the GMD_ID registers into proper IP steppings.
217 *
218 * GMD_ID revid values are currently expected to have consistent meanings on
219 * all platforms:  major steppings (A0, B0, etc.) are 4 apart, with minor
220 * steppings (A1, A2, etc.) taking the values in between.
221 */
222struct xe_step_info xe_step_gmdid_get(struct xe_device *xe,
223				      u32 graphics_gmdid_revid,
224				      u32 media_gmdid_revid)
225{
226	struct xe_step_info step = {
227		.graphics = STEP_A0 + graphics_gmdid_revid,
228		.media = STEP_A0 + media_gmdid_revid,
229	};
230
231	if (step.graphics >= STEP_FUTURE) {
232		step.graphics = STEP_FUTURE;
233		drm_dbg(&xe->drm, "Graphics GMD_ID revid value %d treated as future stepping\n",
234			graphics_gmdid_revid);
235	}
236
237	if (step.media >= STEP_FUTURE) {
238		step.media = STEP_FUTURE;
239		drm_dbg(&xe->drm, "Media GMD_ID revid value %d treated as future stepping\n",
240			media_gmdid_revid);
241	}
242
243	return step;
244}
245
246#define STEP_NAME_CASE(name)	\
247	case STEP_##name:	\
248		return #name;
249
250const char *xe_step_name(enum xe_step step)
251{
252	switch (step) {
253	STEP_NAME_LIST(STEP_NAME_CASE);
254
255	default:
256		return "**";
257	}
258}
259EXPORT_SYMBOL_IF_KUNIT(xe_step_name);
~/ Read-only file preview.