xref: /linux/drivers/gpu/drm/i915/intel_step.c (revision f6e8dc9edf963dbc99085e54f6ced6da9daa6100)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2020,2021 Intel Corporation
4  */
5 
6 #include <drm/drm_print.h>
7 
8 #include "i915_drv.h"
9 #include "intel_step.h"
10 
11 /*
12  * Some platforms have unusual ways of mapping PCI revision ID to GT/display
13  * steppings.  E.g., in some cases a higher PCI revision may translate to a
14  * lower stepping of the GT and/or display IP.  This file provides lookup
15  * tables to map the PCI revision into a standard set of stepping values that
16  * can be compared numerically.
17  *
18  * Also note that some revisions/steppings may have been set aside as
19  * placeholders but never materialized in real hardware; in those cases there
20  * may be jumps in the revision IDs or stepping values in the tables below.
21  */
22 
23 /*
24  * Some platforms always have the same stepping value for GT and display;
25  * use a macro to define these to make it easier to identify the platforms
26  * where the two steppings can deviate.
27  */
28 #define COMMON_STEP(x)  .graphics_step = STEP_##x, .media_step = STEP_##x
29 
30 static const struct intel_step_info skl_revids[] = {
31 	[0x6] = { COMMON_STEP(G0) },
32 	[0x7] = { COMMON_STEP(H0) },
33 	[0x9] = { COMMON_STEP(J0) },
34 	[0xA] = { COMMON_STEP(I1) },
35 };
36 
37 static const struct intel_step_info kbl_revids[] = {
38 	[1] = { COMMON_STEP(B0) },
39 	[2] = { COMMON_STEP(C0) },
40 	[3] = { COMMON_STEP(D0) },
41 	[4] = { COMMON_STEP(F0) },
42 	[5] = { COMMON_STEP(C0) },
43 	[6] = { COMMON_STEP(D1) },
44 	[7] = { COMMON_STEP(G0) },
45 };
46 
47 static const struct intel_step_info bxt_revids[] = {
48 	[0xA] = { COMMON_STEP(C0) },
49 	[0xB] = { COMMON_STEP(C0) },
50 	[0xC] = { COMMON_STEP(D0) },
51 	[0xD] = { COMMON_STEP(E0) },
52 };
53 
54 static const struct intel_step_info glk_revids[] = {
55 	[3] = { COMMON_STEP(B0) },
56 };
57 
58 static const struct intel_step_info icl_revids[] = {
59 	[7] = { COMMON_STEP(D0) },
60 };
61 
62 static const struct intel_step_info jsl_ehl_revids[] = {
63 	[0] = { COMMON_STEP(A0) },
64 	[1] = { COMMON_STEP(B0) },
65 };
66 
67 static const struct intel_step_info tgl_uy_revids[] = {
68 	[0] = { COMMON_STEP(A0) },
69 	[1] = { COMMON_STEP(B0) },
70 	[2] = { COMMON_STEP(B1) },
71 	[3] = { COMMON_STEP(C0) },
72 };
73 
74 /* Same GT stepping between tgl_uy_revids and tgl_revids don't mean the same HW */
75 static const struct intel_step_info tgl_revids[] = {
76 	[0] = { COMMON_STEP(A0) },
77 	[1] = { COMMON_STEP(B0) },
78 };
79 
80 static const struct intel_step_info rkl_revids[] = {
81 	[0] = { COMMON_STEP(A0) },
82 	[1] = { COMMON_STEP(B0) },
83 	[4] = { COMMON_STEP(C0) },
84 };
85 
86 static const struct intel_step_info dg1_revids[] = {
87 	[0] = { COMMON_STEP(A0) },
88 	[1] = { COMMON_STEP(B0) },
89 };
90 
91 static const struct intel_step_info adls_revids[] = {
92 	[0x0] = { COMMON_STEP(A0) },
93 	[0x1] = { COMMON_STEP(A0) },
94 	[0x4] = { COMMON_STEP(B0) },
95 	[0x8] = { COMMON_STEP(C0) },
96 	[0xC] = { COMMON_STEP(D0) },
97 };
98 
99 static const struct intel_step_info adlp_revids[] = {
100 	[0x0] = { COMMON_STEP(A0) },
101 	[0x4] = { COMMON_STEP(B0) },
102 	[0x8] = { COMMON_STEP(C0) },
103 	[0xC] = { COMMON_STEP(C0) },
104 };
105 
106 static const struct intel_step_info dg2_g10_revid_step_tbl[] = {
107 	[0x0] = { COMMON_STEP(A0) },
108 	[0x1] = { COMMON_STEP(A1) },
109 	[0x4] = { COMMON_STEP(B0) },
110 	[0x8] = { COMMON_STEP(C0) },
111 };
112 
113 static const struct intel_step_info dg2_g11_revid_step_tbl[] = {
114 	[0x0] = { COMMON_STEP(A0) },
115 	[0x4] = { COMMON_STEP(B0) },
116 	[0x5] = { COMMON_STEP(B1) },
117 };
118 
119 static const struct intel_step_info dg2_g12_revid_step_tbl[] = {
120 	[0x0] = { COMMON_STEP(A0) },
121 	[0x1] = { COMMON_STEP(A1) },
122 };
123 
124 static const struct intel_step_info adls_rpls_revids[] = {
125 	[0x4] = { COMMON_STEP(D0) },
126 	[0xC] = { COMMON_STEP(D0) },
127 };
128 
129 static const struct intel_step_info adlp_rplp_revids[] = {
130 	[0x4] = { COMMON_STEP(C0) },
131 };
132 
133 static const struct intel_step_info adlp_n_revids[] = {
134 	[0x0] = { COMMON_STEP(A0) },
135 };
136 
137 static u8 gmd_to_intel_step(struct drm_i915_private *i915,
138 			    struct intel_ip_version *gmd)
139 {
140 	u8 step = gmd->step + STEP_A0;
141 
142 	if (step >= STEP_FUTURE) {
143 		drm_dbg(&i915->drm, "Using future steppings\n");
144 		return STEP_FUTURE;
145 	}
146 
147 	return step;
148 }
149 
150 void intel_step_init(struct drm_i915_private *i915)
151 {
152 	const struct intel_step_info *revids = NULL;
153 	int size = 0;
154 	int revid = INTEL_REVID(i915);
155 	struct intel_step_info step = {};
156 
157 	if (HAS_GMD_ID(i915)) {
158 		step.graphics_step = gmd_to_intel_step(i915,
159 						       &RUNTIME_INFO(i915)->graphics.ip);
160 		step.media_step = gmd_to_intel_step(i915,
161 						    &RUNTIME_INFO(i915)->media.ip);
162 
163 		RUNTIME_INFO(i915)->step = step;
164 
165 		return;
166 	}
167 
168 	if (IS_DG2_G10(i915)) {
169 		revids = dg2_g10_revid_step_tbl;
170 		size = ARRAY_SIZE(dg2_g10_revid_step_tbl);
171 	} else if (IS_DG2_G11(i915)) {
172 		revids = dg2_g11_revid_step_tbl;
173 		size = ARRAY_SIZE(dg2_g11_revid_step_tbl);
174 	} else if (IS_DG2_G12(i915)) {
175 		revids = dg2_g12_revid_step_tbl;
176 		size = ARRAY_SIZE(dg2_g12_revid_step_tbl);
177 	} else if (IS_ALDERLAKE_P_N(i915)) {
178 		revids = adlp_n_revids;
179 		size = ARRAY_SIZE(adlp_n_revids);
180 	} else if (IS_RAPTORLAKE_P(i915)) {
181 		revids = adlp_rplp_revids;
182 		size = ARRAY_SIZE(adlp_rplp_revids);
183 	} else if (IS_ALDERLAKE_P(i915)) {
184 		revids = adlp_revids;
185 		size = ARRAY_SIZE(adlp_revids);
186 	} else if (IS_RAPTORLAKE_S(i915)) {
187 		revids = adls_rpls_revids;
188 		size = ARRAY_SIZE(adls_rpls_revids);
189 	} else if (IS_ALDERLAKE_S(i915)) {
190 		revids = adls_revids;
191 		size = ARRAY_SIZE(adls_revids);
192 	} else if (IS_DG1(i915)) {
193 		revids = dg1_revids;
194 		size = ARRAY_SIZE(dg1_revids);
195 	} else if (IS_ROCKETLAKE(i915)) {
196 		revids = rkl_revids;
197 		size = ARRAY_SIZE(rkl_revids);
198 	} else if (IS_TIGERLAKE_UY(i915)) {
199 		revids = tgl_uy_revids;
200 		size = ARRAY_SIZE(tgl_uy_revids);
201 	} else if (IS_TIGERLAKE(i915)) {
202 		revids = tgl_revids;
203 		size = ARRAY_SIZE(tgl_revids);
204 	} else if (IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) {
205 		revids = jsl_ehl_revids;
206 		size = ARRAY_SIZE(jsl_ehl_revids);
207 	} else if (IS_ICELAKE(i915)) {
208 		revids = icl_revids;
209 		size = ARRAY_SIZE(icl_revids);
210 	} else if (IS_GEMINILAKE(i915)) {
211 		revids = glk_revids;
212 		size = ARRAY_SIZE(glk_revids);
213 	} else if (IS_BROXTON(i915)) {
214 		revids = bxt_revids;
215 		size = ARRAY_SIZE(bxt_revids);
216 	} else if (IS_KABYLAKE(i915)) {
217 		revids = kbl_revids;
218 		size = ARRAY_SIZE(kbl_revids);
219 	} else if (IS_SKYLAKE(i915)) {
220 		revids = skl_revids;
221 		size = ARRAY_SIZE(skl_revids);
222 	}
223 
224 	/* Not using the stepping scheme for the platform yet. */
225 	if (!revids)
226 		return;
227 
228 	if (revid < size && revids[revid].graphics_step != STEP_NONE) {
229 		step = revids[revid];
230 	} else {
231 		drm_warn(&i915->drm, "Unknown revid 0x%02x\n", revid);
232 
233 		/*
234 		 * If we hit a gap in the revid array, use the information for
235 		 * the next revid.
236 		 *
237 		 * This may be wrong in all sorts of ways, especially if the
238 		 * steppings in the array are not monotonically increasing, but
239 		 * it's better than defaulting to 0.
240 		 */
241 		while (revid < size && revids[revid].graphics_step == STEP_NONE)
242 			revid++;
243 
244 		if (revid < size) {
245 			drm_dbg(&i915->drm, "Using steppings for revid 0x%02x\n",
246 				revid);
247 			step = revids[revid];
248 		} else {
249 			drm_dbg(&i915->drm, "Using future steppings\n");
250 			step.graphics_step = STEP_FUTURE;
251 		}
252 	}
253 
254 	if (drm_WARN_ON(&i915->drm, step.graphics_step == STEP_NONE))
255 		return;
256 
257 	RUNTIME_INFO(i915)->step = step;
258 }
259 
260 #define STEP_NAME_CASE(name)	\
261 	case STEP_##name:	\
262 		return #name;
263 
264 const char *intel_step_name(enum intel_step step)
265 {
266 	switch (step) {
267 	STEP_NAME_LIST(STEP_NAME_CASE);
268 
269 	default:
270 		return "**";
271 	}
272 }
273