drm/i915: Add 4th pipe and transcoder
[linux-2.6-block.git] / drivers / gpu / drm / i915 / intel_device_info.c
CommitLineData
94b4f3ba
CW
1/*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
a8c9b849
MW
25#include <drm/drm_print.h>
26
b978520d 27#include "intel_device_info.h"
94b4f3ba
CW
28#include "i915_drv.h"
29
2e0d26f8
JN
30#define PLATFORM_NAME(x) [INTEL_##x] = #x
31static const char * const platform_names[] = {
32 PLATFORM_NAME(I830),
33 PLATFORM_NAME(I845G),
34 PLATFORM_NAME(I85X),
35 PLATFORM_NAME(I865G),
36 PLATFORM_NAME(I915G),
37 PLATFORM_NAME(I915GM),
38 PLATFORM_NAME(I945G),
39 PLATFORM_NAME(I945GM),
40 PLATFORM_NAME(G33),
41 PLATFORM_NAME(PINEVIEW),
c0f86832
JN
42 PLATFORM_NAME(I965G),
43 PLATFORM_NAME(I965GM),
f69c11ae
JN
44 PLATFORM_NAME(G45),
45 PLATFORM_NAME(GM45),
2e0d26f8
JN
46 PLATFORM_NAME(IRONLAKE),
47 PLATFORM_NAME(SANDYBRIDGE),
48 PLATFORM_NAME(IVYBRIDGE),
49 PLATFORM_NAME(VALLEYVIEW),
50 PLATFORM_NAME(HASWELL),
51 PLATFORM_NAME(BROADWELL),
52 PLATFORM_NAME(CHERRYVIEW),
53 PLATFORM_NAME(SKYLAKE),
54 PLATFORM_NAME(BROXTON),
55 PLATFORM_NAME(KABYLAKE),
56 PLATFORM_NAME(GEMINILAKE),
71851fa8 57 PLATFORM_NAME(COFFEELAKE),
413f3c19 58 PLATFORM_NAME(CANNONLAKE),
41231001 59 PLATFORM_NAME(ICELAKE),
897f2961 60 PLATFORM_NAME(ELKHARTLAKE),
2e0d26f8
JN
61};
62#undef PLATFORM_NAME
63
64const char *intel_platform_name(enum intel_platform platform)
65{
9160095c
JN
66 BUILD_BUG_ON(ARRAY_SIZE(platform_names) != INTEL_MAX_PLATFORMS);
67
2e0d26f8
JN
68 if (WARN_ON_ONCE(platform >= ARRAY_SIZE(platform_names) ||
69 platform_names[platform] == NULL))
70 return "<unknown>";
71
72 return platform_names[platform];
73}
74
a8c9b849
MW
75void intel_device_info_dump_flags(const struct intel_device_info *info,
76 struct drm_printer *p)
77{
78#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->name));
79 DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG);
80#undef PRINT_FLAG
d53db442
JRS
81
82#define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, yesno(info->display.name));
83 DEV_INFO_DISPLAY_FOR_EACH_FLAG(PRINT_FLAG);
84#undef PRINT_FLAG
a8c9b849
MW
85}
86
5fbbe8d4
MW
87static void sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p)
88{
8cc76693
LL
89 int s;
90
0ef904bb
TU
91 drm_printf(p, "slice total: %u, mask=%04x\n",
92 hweight8(sseu->slice_mask), sseu->slice_mask);
0040fd19 93 drm_printf(p, "subslice total: %u\n", intel_sseu_subslice_total(sseu));
0ef904bb 94 for (s = 0; s < sseu->max_slices; s++) {
a10f361d 95 drm_printf(p, "slice%d: %u subslices, mask=%04x\n",
b5ab1abe 96 s, intel_sseu_subslices_per_slice(sseu, s),
a10f361d 97 sseu->subslice_mask[s]);
8cc76693 98 }
5fbbe8d4
MW
99 drm_printf(p, "EU total: %u\n", sseu->eu_total);
100 drm_printf(p, "EU per subslice: %u\n", sseu->eu_per_subslice);
101 drm_printf(p, "has slice power gating: %s\n",
102 yesno(sseu->has_slice_pg));
103 drm_printf(p, "has subslice power gating: %s\n",
104 yesno(sseu->has_subslice_pg));
105 drm_printf(p, "has EU power gating: %s\n", yesno(sseu->has_eu_pg));
106}
107
0258404f 108void intel_device_info_dump_runtime(const struct intel_runtime_info *info,
5fbbe8d4
MW
109 struct drm_printer *p)
110{
111 sseu_dump(&info->sseu, p);
112
113 drm_printf(p, "CS timestamp frequency: %u kHz\n",
114 info->cs_timestamp_frequency_khz);
115}
116
0040fd19
SS
117static int sseu_eu_idx(const struct sseu_dev_info *sseu, int slice,
118 int subslice)
119{
a10f361d
JN
120 int subslice_stride = GEN_SSEU_STRIDE(sseu->max_eus_per_subslice);
121 int slice_stride = sseu->max_subslices * subslice_stride;
0040fd19 122
a10f361d 123 return slice * slice_stride + subslice * subslice_stride;
0040fd19
SS
124}
125
126static u16 sseu_get_eus(const struct sseu_dev_info *sseu, int slice,
127 int subslice)
128{
129 int i, offset = sseu_eu_idx(sseu, slice, subslice);
130 u16 eu_mask = 0;
131
a10f361d 132 for (i = 0; i < GEN_SSEU_STRIDE(sseu->max_eus_per_subslice); i++) {
0040fd19
SS
133 eu_mask |= ((u16)sseu->eu_mask[offset + i]) <<
134 (i * BITS_PER_BYTE);
135 }
136
137 return eu_mask;
138}
139
140static void sseu_set_eus(struct sseu_dev_info *sseu, int slice, int subslice,
141 u16 eu_mask)
142{
143 int i, offset = sseu_eu_idx(sseu, slice, subslice);
144
a10f361d 145 for (i = 0; i < GEN_SSEU_STRIDE(sseu->max_eus_per_subslice); i++) {
0040fd19
SS
146 sseu->eu_mask[offset + i] =
147 (eu_mask >> (BITS_PER_BYTE * i)) & 0xff;
148 }
149}
150
79e9cd5f
LL
151void intel_device_info_dump_topology(const struct sseu_dev_info *sseu,
152 struct drm_printer *p)
153{
154 int s, ss;
155
156 if (sseu->max_slices == 0) {
157 drm_printf(p, "Unavailable\n");
158 return;
159 }
160
161 for (s = 0; s < sseu->max_slices; s++) {
a10f361d 162 drm_printf(p, "slice%d: %u subslice(s) (0x%hhx):\n",
b5ab1abe 163 s, intel_sseu_subslices_per_slice(sseu, s),
a10f361d 164 sseu->subslice_mask[s]);
79e9cd5f
LL
165
166 for (ss = 0; ss < sseu->max_subslices; ss++) {
167 u16 enabled_eus = sseu_get_eus(sseu, s, ss);
168
169 drm_printf(p, "\tsubslice%d: %u EUs (0x%hx)\n",
170 ss, hweight16(enabled_eus), enabled_eus);
171 }
172 }
173}
174
8cc76693
LL
175static u16 compute_eu_total(const struct sseu_dev_info *sseu)
176{
177 u16 i, total = 0;
178
179 for (i = 0; i < ARRAY_SIZE(sseu->eu_mask); i++)
180 total += hweight8(sseu->eu_mask[i]);
181
182 return total;
183}
184
8b5eb5e2
KG
185static void gen11_sseu_info_init(struct drm_i915_private *dev_priv)
186{
0258404f 187 struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
8b5eb5e2
KG
188 u8 s_en;
189 u32 ss_en, ss_en_mask;
190 u8 eu_en;
191 int s;
192
a10f361d
JN
193 if (IS_ELKHARTLAKE(dev_priv)) {
194 sseu->max_slices = 1;
195 sseu->max_subslices = 4;
196 sseu->max_eus_per_subslice = 8;
197 } else {
198 sseu->max_slices = 1;
199 sseu->max_subslices = 8;
200 sseu->max_eus_per_subslice = 8;
201 }
8b5eb5e2
KG
202
203 s_en = I915_READ(GEN11_GT_SLICE_ENABLE) & GEN11_GT_S_ENA_MASK;
204 ss_en = ~I915_READ(GEN11_GT_SUBSLICE_DISABLE);
205 ss_en_mask = BIT(sseu->max_subslices) - 1;
206 eu_en = ~(I915_READ(GEN11_EU_DISABLE) & GEN11_EU_DIS_MASK);
207
208 for (s = 0; s < sseu->max_slices; s++) {
209 if (s_en & BIT(s)) {
a10f361d 210 int ss_idx = sseu->max_subslices * s;
8b5eb5e2
KG
211 int ss;
212
213 sseu->slice_mask |= BIT(s);
a10f361d
JN
214 sseu->subslice_mask[s] = (ss_en >> ss_idx) & ss_en_mask;
215 for (ss = 0; ss < sseu->max_subslices; ss++) {
216 if (sseu->subslice_mask[s] & BIT(ss))
8b5eb5e2 217 sseu_set_eus(sseu, s, ss, eu_en);
a10f361d 218 }
8b5eb5e2
KG
219 }
220 }
221 sseu->eu_per_subslice = hweight8(eu_en);
222 sseu->eu_total = compute_eu_total(sseu);
223
224 /* ICL has no power gating restrictions. */
225 sseu->has_slice_pg = 1;
226 sseu->has_subslice_pg = 1;
227 sseu->has_eu_pg = 1;
228}
229
4e9767bc
BW
230static void gen10_sseu_info_init(struct drm_i915_private *dev_priv)
231{
0258404f 232 struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
4e9767bc 233 const u32 fuse2 = I915_READ(GEN8_FUSE2);
8cc76693
LL
234 int s, ss;
235 const int eu_mask = 0xff;
236 u32 subslice_mask, eu_en;
4e9767bc
BW
237
238 sseu->slice_mask = (fuse2 & GEN10_F2_S_ENA_MASK) >>
239 GEN10_F2_S_ENA_SHIFT;
a10f361d
JN
240 sseu->max_slices = 6;
241 sseu->max_subslices = 4;
242 sseu->max_eus_per_subslice = 8;
243
244 subslice_mask = (1 << 4) - 1;
245 subslice_mask &= ~((fuse2 & GEN10_F2_SS_DIS_MASK) >>
246 GEN10_F2_SS_DIS_SHIFT);
247
248 /*
249 * Slice0 can have up to 3 subslices, but there are only 2 in
250 * slice1/2.
251 */
252 sseu->subslice_mask[0] = subslice_mask;
253 for (s = 1; s < sseu->max_slices; s++)
254 sseu->subslice_mask[s] = subslice_mask & 0x3;
8cc76693
LL
255
256 /* Slice0 */
257 eu_en = ~I915_READ(GEN8_EU_DISABLE0);
258 for (ss = 0; ss < sseu->max_subslices; ss++)
259 sseu_set_eus(sseu, 0, ss, (eu_en >> (8 * ss)) & eu_mask);
260 /* Slice1 */
261 sseu_set_eus(sseu, 1, 0, (eu_en >> 24) & eu_mask);
262 eu_en = ~I915_READ(GEN8_EU_DISABLE1);
263 sseu_set_eus(sseu, 1, 1, eu_en & eu_mask);
264 /* Slice2 */
265 sseu_set_eus(sseu, 2, 0, (eu_en >> 8) & eu_mask);
266 sseu_set_eus(sseu, 2, 1, (eu_en >> 16) & eu_mask);
267 /* Slice3 */
268 sseu_set_eus(sseu, 3, 0, (eu_en >> 24) & eu_mask);
269 eu_en = ~I915_READ(GEN8_EU_DISABLE2);
270 sseu_set_eus(sseu, 3, 1, eu_en & eu_mask);
271 /* Slice4 */
272 sseu_set_eus(sseu, 4, 0, (eu_en >> 8) & eu_mask);
273 sseu_set_eus(sseu, 4, 1, (eu_en >> 16) & eu_mask);
274 /* Slice5 */
275 sseu_set_eus(sseu, 5, 0, (eu_en >> 24) & eu_mask);
276 eu_en = ~I915_READ(GEN10_EU_DISABLE3);
277 sseu_set_eus(sseu, 5, 1, eu_en & eu_mask);
278
a10f361d
JN
279 /* Do a second pass where we mark the subslices disabled if all their
280 * eus are off.
281 */
8cc76693
LL
282 for (s = 0; s < sseu->max_slices; s++) {
283 for (ss = 0; ss < sseu->max_subslices; ss++) {
284 if (sseu_get_eus(sseu, s, ss) == 0)
a10f361d 285 sseu->subslice_mask[s] &= ~BIT(ss);
8cc76693
LL
286 }
287 }
288
289 sseu->eu_total = compute_eu_total(sseu);
4e9767bc
BW
290
291 /*
292 * CNL is expected to always have a uniform distribution
293 * of EU across subslices with the exception that any one
294 * EU in any one subslice may be fused off for die
295 * recovery.
296 */
0040fd19 297 sseu->eu_per_subslice = intel_sseu_subslice_total(sseu) ?
4e9767bc 298 DIV_ROUND_UP(sseu->eu_total,
0040fd19
SS
299 intel_sseu_subslice_total(sseu)) :
300 0;
4e9767bc
BW
301
302 /* No restrictions on Power Gating */
303 sseu->has_slice_pg = 1;
304 sseu->has_subslice_pg = 1;
305 sseu->has_eu_pg = 1;
306}
307
94b4f3ba
CW
308static void cherryview_sseu_info_init(struct drm_i915_private *dev_priv)
309{
0258404f 310 struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
8cc76693 311 u32 fuse;
94b4f3ba
CW
312
313 fuse = I915_READ(CHV_FUSE_GT);
314
f08a0c92 315 sseu->slice_mask = BIT(0);
a10f361d
JN
316 sseu->max_slices = 1;
317 sseu->max_subslices = 2;
318 sseu->max_eus_per_subslice = 8;
94b4f3ba
CW
319
320 if (!(fuse & CHV_FGT_DISABLE_SS0)) {
8cc76693
LL
321 u8 disabled_mask =
322 ((fuse & CHV_FGT_EU_DIS_SS0_R0_MASK) >>
323 CHV_FGT_EU_DIS_SS0_R0_SHIFT) |
324 (((fuse & CHV_FGT_EU_DIS_SS0_R1_MASK) >>
325 CHV_FGT_EU_DIS_SS0_R1_SHIFT) << 4);
326
a10f361d 327 sseu->subslice_mask[0] |= BIT(0);
8cc76693 328 sseu_set_eus(sseu, 0, 0, ~disabled_mask);
94b4f3ba
CW
329 }
330
331 if (!(fuse & CHV_FGT_DISABLE_SS1)) {
8cc76693
LL
332 u8 disabled_mask =
333 ((fuse & CHV_FGT_EU_DIS_SS1_R0_MASK) >>
334 CHV_FGT_EU_DIS_SS1_R0_SHIFT) |
335 (((fuse & CHV_FGT_EU_DIS_SS1_R1_MASK) >>
336 CHV_FGT_EU_DIS_SS1_R1_SHIFT) << 4);
337
a10f361d 338 sseu->subslice_mask[0] |= BIT(1);
8cc76693 339 sseu_set_eus(sseu, 0, 1, ~disabled_mask);
94b4f3ba
CW
340 }
341
8cc76693
LL
342 sseu->eu_total = compute_eu_total(sseu);
343
94b4f3ba
CW
344 /*
345 * CHV expected to always have a uniform distribution of EU
346 * across subslices.
347 */
0040fd19
SS
348 sseu->eu_per_subslice = intel_sseu_subslice_total(sseu) ?
349 sseu->eu_total /
350 intel_sseu_subslice_total(sseu) :
94b4f3ba
CW
351 0;
352 /*
353 * CHV supports subslice power gating on devices with more than
354 * one subslice, and supports EU power gating on devices with
355 * more than one EU pair per subslice.
356 */
43b67998 357 sseu->has_slice_pg = 0;
0040fd19 358 sseu->has_subslice_pg = intel_sseu_subslice_total(sseu) > 1;
43b67998 359 sseu->has_eu_pg = (sseu->eu_per_subslice > 2);
94b4f3ba
CW
360}
361
362static void gen9_sseu_info_init(struct drm_i915_private *dev_priv)
363{
364 struct intel_device_info *info = mkwrite_device_info(dev_priv);
0258404f 365 struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
94b4f3ba 366 int s, ss;
8cc76693
LL
367 u32 fuse2, eu_disable, subslice_mask;
368 const u8 eu_mask = 0xff;
94b4f3ba
CW
369
370 fuse2 = I915_READ(GEN8_FUSE2);
f08a0c92 371 sseu->slice_mask = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
94b4f3ba 372
8cc76693 373 /* BXT has a single slice and at most 3 subslices. */
a10f361d
JN
374 sseu->max_slices = IS_GEN9_LP(dev_priv) ? 1 : 3;
375 sseu->max_subslices = IS_GEN9_LP(dev_priv) ? 3 : 4;
376 sseu->max_eus_per_subslice = 8;
8cc76693 377
94b4f3ba
CW
378 /*
379 * The subslice disable field is global, i.e. it applies
380 * to each of the enabled slices.
381 */
8cc76693
LL
382 subslice_mask = (1 << sseu->max_subslices) - 1;
383 subslice_mask &= ~((fuse2 & GEN9_F2_SS_DIS_MASK) >>
384 GEN9_F2_SS_DIS_SHIFT);
94b4f3ba
CW
385
386 /*
387 * Iterate through enabled slices and subslices to
388 * count the total enabled EU.
389 */
8cc76693 390 for (s = 0; s < sseu->max_slices; s++) {
f08a0c92 391 if (!(sseu->slice_mask & BIT(s)))
94b4f3ba
CW
392 /* skip disabled slice */
393 continue;
394
a10f361d 395 sseu->subslice_mask[s] = subslice_mask;
8cc76693 396
94b4f3ba 397 eu_disable = I915_READ(GEN9_EU_DISABLE(s));
8cc76693 398 for (ss = 0; ss < sseu->max_subslices; ss++) {
94b4f3ba 399 int eu_per_ss;
8cc76693 400 u8 eu_disabled_mask;
94b4f3ba 401
a10f361d 402 if (!(sseu->subslice_mask[s] & BIT(ss)))
94b4f3ba
CW
403 /* skip disabled subslice */
404 continue;
405
b3e7f866 406 eu_disabled_mask = (eu_disable >> (ss * 8)) & eu_mask;
8cc76693
LL
407
408 sseu_set_eus(sseu, s, ss, ~eu_disabled_mask);
409
410 eu_per_ss = sseu->max_eus_per_subslice -
411 hweight8(eu_disabled_mask);
94b4f3ba
CW
412
413 /*
414 * Record which subslice(s) has(have) 7 EUs. we
415 * can tune the hash used to spread work among
416 * subslices if they are unbalanced.
417 */
418 if (eu_per_ss == 7)
43b67998 419 sseu->subslice_7eu[s] |= BIT(ss);
94b4f3ba
CW
420 }
421 }
422
8cc76693
LL
423 sseu->eu_total = compute_eu_total(sseu);
424
94b4f3ba
CW
425 /*
426 * SKL is expected to always have a uniform distribution
427 * of EU across subslices with the exception that any one
428 * EU in any one subslice may be fused off for die
429 * recovery. BXT is expected to be perfectly uniform in EU
430 * distribution.
431 */
0040fd19 432 sseu->eu_per_subslice = intel_sseu_subslice_total(sseu) ?
43b67998 433 DIV_ROUND_UP(sseu->eu_total,
0040fd19
SS
434 intel_sseu_subslice_total(sseu)) :
435 0;
94b4f3ba 436 /*
c7ae7e9a 437 * SKL+ supports slice power gating on devices with more than
94b4f3ba 438 * one slice, and supports EU power gating on devices with
c7ae7e9a 439 * more than one EU pair per subslice. BXT+ supports subslice
94b4f3ba
CW
440 * power gating on devices with more than one subslice, and
441 * supports EU power gating on devices with more than one EU
442 * pair per subslice.
443 */
43b67998 444 sseu->has_slice_pg =
c7ae7e9a 445 !IS_GEN9_LP(dev_priv) && hweight8(sseu->slice_mask) > 1;
43b67998 446 sseu->has_subslice_pg =
0040fd19 447 IS_GEN9_LP(dev_priv) && intel_sseu_subslice_total(sseu) > 1;
43b67998 448 sseu->has_eu_pg = sseu->eu_per_subslice > 2;
94b4f3ba 449
234516af 450 if (IS_GEN9_LP(dev_priv)) {
8cc76693
LL
451#define IS_SS_DISABLED(ss) (!(sseu->subslice_mask[0] & BIT(ss)))
452 info->has_pooled_eu = hweight8(sseu->subslice_mask[0]) == 3;
234516af 453
43b67998 454 sseu->min_eu_in_pool = 0;
94b4f3ba 455 if (info->has_pooled_eu) {
57ec171e 456 if (IS_SS_DISABLED(2) || IS_SS_DISABLED(0))
43b67998 457 sseu->min_eu_in_pool = 3;
57ec171e 458 else if (IS_SS_DISABLED(1))
43b67998 459 sseu->min_eu_in_pool = 6;
94b4f3ba 460 else
43b67998 461 sseu->min_eu_in_pool = 9;
94b4f3ba
CW
462 }
463#undef IS_SS_DISABLED
464 }
465}
466
467static void broadwell_sseu_info_init(struct drm_i915_private *dev_priv)
468{
0258404f 469 struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
94b4f3ba 470 int s, ss;
8cc76693 471 u32 fuse2, subslice_mask, eu_disable[3]; /* s_max */
94b4f3ba
CW
472
473 fuse2 = I915_READ(GEN8_FUSE2);
f08a0c92 474 sseu->slice_mask = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
a10f361d
JN
475 sseu->max_slices = 3;
476 sseu->max_subslices = 3;
477 sseu->max_eus_per_subslice = 8;
8cc76693 478
57ec171e
ID
479 /*
480 * The subslice disable field is global, i.e. it applies
481 * to each of the enabled slices.
482 */
8cc76693
LL
483 subslice_mask = GENMASK(sseu->max_subslices - 1, 0);
484 subslice_mask &= ~((fuse2 & GEN8_F2_SS_DIS_MASK) >>
485 GEN8_F2_SS_DIS_SHIFT);
94b4f3ba
CW
486
487 eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK;
488 eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) |
489 ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) <<
490 (32 - GEN8_EU_DIS0_S1_SHIFT));
491 eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) |
492 ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) <<
493 (32 - GEN8_EU_DIS1_S2_SHIFT));
494
94b4f3ba
CW
495 /*
496 * Iterate through enabled slices and subslices to
497 * count the total enabled EU.
498 */
8cc76693 499 for (s = 0; s < sseu->max_slices; s++) {
f08a0c92 500 if (!(sseu->slice_mask & BIT(s)))
94b4f3ba
CW
501 /* skip disabled slice */
502 continue;
503
a10f361d 504 sseu->subslice_mask[s] = subslice_mask;
8cc76693
LL
505
506 for (ss = 0; ss < sseu->max_subslices; ss++) {
507 u8 eu_disabled_mask;
94b4f3ba
CW
508 u32 n_disabled;
509
a10f361d 510 if (!(sseu->subslice_mask[s] & BIT(ss)))
94b4f3ba
CW
511 /* skip disabled subslice */
512 continue;
513
8cc76693 514 eu_disabled_mask =
a10f361d 515 eu_disable[s] >> (ss * sseu->max_eus_per_subslice);
8cc76693
LL
516
517 sseu_set_eus(sseu, s, ss, ~eu_disabled_mask);
518
519 n_disabled = hweight8(eu_disabled_mask);
94b4f3ba
CW
520
521 /*
522 * Record which subslices have 7 EUs.
523 */
8cc76693 524 if (sseu->max_eus_per_subslice - n_disabled == 7)
43b67998 525 sseu->subslice_7eu[s] |= 1 << ss;
94b4f3ba
CW
526 }
527 }
528
8cc76693
LL
529 sseu->eu_total = compute_eu_total(sseu);
530
94b4f3ba
CW
531 /*
532 * BDW is expected to always have a uniform distribution of EU across
533 * subslices with the exception that any one EU in any one subslice may
534 * be fused off for die recovery.
535 */
0040fd19 536 sseu->eu_per_subslice = intel_sseu_subslice_total(sseu) ?
57ec171e 537 DIV_ROUND_UP(sseu->eu_total,
0040fd19
SS
538 intel_sseu_subslice_total(sseu)) :
539 0;
94b4f3ba
CW
540
541 /*
542 * BDW supports slice power gating on devices with more than
543 * one slice.
544 */
f08a0c92 545 sseu->has_slice_pg = hweight8(sseu->slice_mask) > 1;
43b67998
ID
546 sseu->has_subslice_pg = 0;
547 sseu->has_eu_pg = 0;
94b4f3ba
CW
548}
549
b8ec759e
LL
550static void haswell_sseu_info_init(struct drm_i915_private *dev_priv)
551{
0258404f 552 struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu;
b8ec759e 553 u32 fuse1;
8cc76693 554 int s, ss;
b8ec759e
LL
555
556 /*
557 * There isn't a register to tell us how many slices/subslices. We
558 * work off the PCI-ids here.
559 */
0258404f 560 switch (INTEL_INFO(dev_priv)->gt) {
b8ec759e 561 default:
0258404f 562 MISSING_CASE(INTEL_INFO(dev_priv)->gt);
b8ec759e
LL
563 /* fall through */
564 case 1:
565 sseu->slice_mask = BIT(0);
a10f361d 566 sseu->subslice_mask[0] = BIT(0);
b8ec759e
LL
567 break;
568 case 2:
569 sseu->slice_mask = BIT(0);
a10f361d 570 sseu->subslice_mask[0] = BIT(0) | BIT(1);
b8ec759e
LL
571 break;
572 case 3:
573 sseu->slice_mask = BIT(0) | BIT(1);
a10f361d
JN
574 sseu->subslice_mask[0] = BIT(0) | BIT(1);
575 sseu->subslice_mask[1] = BIT(0) | BIT(1);
b8ec759e
LL
576 break;
577 }
578
a10f361d
JN
579 sseu->max_slices = hweight8(sseu->slice_mask);
580 sseu->max_subslices = hweight8(sseu->subslice_mask[0]);
581
b8ec759e
LL
582 fuse1 = I915_READ(HSW_PAVP_FUSE1);
583 switch ((fuse1 & HSW_F1_EU_DIS_MASK) >> HSW_F1_EU_DIS_SHIFT) {
584 default:
585 MISSING_CASE((fuse1 & HSW_F1_EU_DIS_MASK) >>
586 HSW_F1_EU_DIS_SHIFT);
587 /* fall through */
588 case HSW_F1_EU_DIS_10EUS:
589 sseu->eu_per_subslice = 10;
590 break;
591 case HSW_F1_EU_DIS_8EUS:
592 sseu->eu_per_subslice = 8;
593 break;
594 case HSW_F1_EU_DIS_6EUS:
595 sseu->eu_per_subslice = 6;
596 break;
597 }
a10f361d 598 sseu->max_eus_per_subslice = sseu->eu_per_subslice;
8cc76693
LL
599
600 for (s = 0; s < sseu->max_slices; s++) {
601 for (ss = 0; ss < sseu->max_subslices; ss++) {
602 sseu_set_eus(sseu, s, ss,
603 (1UL << sseu->eu_per_subslice) - 1);
604 }
605 }
b8ec759e 606
8cc76693 607 sseu->eu_total = compute_eu_total(sseu);
b8ec759e
LL
608
609 /* No powergating for you. */
610 sseu->has_slice_pg = 0;
611 sseu->has_subslice_pg = 0;
612 sseu->has_eu_pg = 0;
613}
614
f577a03b 615static u32 read_reference_ts_freq(struct drm_i915_private *dev_priv)
dab91783
LL
616{
617 u32 ts_override = I915_READ(GEN9_TIMESTAMP_OVERRIDE);
f577a03b 618 u32 base_freq, frac_freq;
dab91783
LL
619
620 base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >>
621 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1;
f577a03b 622 base_freq *= 1000;
dab91783
LL
623
624 frac_freq = ((ts_override &
625 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >>
626 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT);
f577a03b 627 frac_freq = 1000 / (frac_freq + 1);
dab91783
LL
628
629 return base_freq + frac_freq;
630}
631
d775a7b1
PZ
632static u32 gen10_get_crystal_clock_freq(struct drm_i915_private *dev_priv,
633 u32 rpm_config_reg)
634{
635 u32 f19_2_mhz = 19200;
636 u32 f24_mhz = 24000;
637 u32 crystal_clock = (rpm_config_reg &
638 GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>
639 GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;
640
641 switch (crystal_clock) {
642 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
643 return f19_2_mhz;
644 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
645 return f24_mhz;
646 default:
647 MISSING_CASE(crystal_clock);
648 return 0;
649 }
650}
651
652static u32 gen11_get_crystal_clock_freq(struct drm_i915_private *dev_priv,
653 u32 rpm_config_reg)
654{
655 u32 f19_2_mhz = 19200;
656 u32 f24_mhz = 24000;
657 u32 f25_mhz = 25000;
658 u32 f38_4_mhz = 38400;
659 u32 crystal_clock = (rpm_config_reg &
660 GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>
661 GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;
662
663 switch (crystal_clock) {
664 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
665 return f24_mhz;
666 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
667 return f19_2_mhz;
668 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ:
669 return f38_4_mhz;
670 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ:
671 return f25_mhz;
672 default:
673 MISSING_CASE(crystal_clock);
674 return 0;
675 }
676}
677
f577a03b 678static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv)
dab91783 679{
f577a03b
LL
680 u32 f12_5_mhz = 12500;
681 u32 f19_2_mhz = 19200;
682 u32 f24_mhz = 24000;
dab91783
LL
683
684 if (INTEL_GEN(dev_priv) <= 4) {
685 /* PRMs say:
686 *
687 * "The value in this register increments once every 16
688 * hclks." (through the “Clocking Configuration”
689 * (“CLKCFG”) MCHBAR register)
690 */
f577a03b 691 return dev_priv->rawclk_freq / 16;
dab91783
LL
692 } else if (INTEL_GEN(dev_priv) <= 8) {
693 /* PRMs say:
694 *
695 * "The PCU TSC counts 10ns increments; this timestamp
696 * reflects bits 38:3 of the TSC (i.e. 80ns granularity,
697 * rolling over every 1.5 hours).
698 */
699 return f12_5_mhz;
700 } else if (INTEL_GEN(dev_priv) <= 9) {
701 u32 ctc_reg = I915_READ(CTC_MODE);
f577a03b 702 u32 freq = 0;
dab91783
LL
703
704 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {
705 freq = read_reference_ts_freq(dev_priv);
706 } else {
707 freq = IS_GEN9_LP(dev_priv) ? f19_2_mhz : f24_mhz;
708
709 /* Now figure out how the command stream's timestamp
710 * register increments from this frequency (it might
711 * increment only every few clock cycle).
712 */
713 freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >>
714 CTC_SHIFT_PARAMETER_SHIFT);
715 }
716
717 return freq;
d775a7b1 718 } else if (INTEL_GEN(dev_priv) <= 11) {
dab91783 719 u32 ctc_reg = I915_READ(CTC_MODE);
f577a03b 720 u32 freq = 0;
dab91783
LL
721
722 /* First figure out the reference frequency. There are 2 ways
723 * we can compute the frequency, either through the
724 * TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE
725 * tells us which one we should use.
726 */
727 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {
728 freq = read_reference_ts_freq(dev_priv);
729 } else {
d775a7b1
PZ
730 u32 rpm_config_reg = I915_READ(RPM_CONFIG0);
731
732 if (INTEL_GEN(dev_priv) <= 10)
733 freq = gen10_get_crystal_clock_freq(dev_priv,
734 rpm_config_reg);
735 else
736 freq = gen11_get_crystal_clock_freq(dev_priv,
737 rpm_config_reg);
dab91783 738
53ff2641
LL
739 /* Now figure out how the command stream's timestamp
740 * register increments from this frequency (it might
741 * increment only every few clock cycle).
742 */
743 freq >>= 3 - ((rpm_config_reg &
744 GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >>
745 GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT);
746 }
dab91783
LL
747
748 return freq;
749 }
750
fe66e928 751 MISSING_CASE("Unknown gen, unable to read command streamer timestamp frequency\n");
dab91783
LL
752 return 0;
753}
754
805446c8
TU
755#undef INTEL_VGA_DEVICE
756#define INTEL_VGA_DEVICE(id, info) (id)
757
758static const u16 subplatform_ult_ids[] = {
759 INTEL_HSW_ULT_GT1_IDS(0),
760 INTEL_HSW_ULT_GT2_IDS(0),
761 INTEL_HSW_ULT_GT3_IDS(0),
762 INTEL_BDW_ULT_GT1_IDS(0),
763 INTEL_BDW_ULT_GT2_IDS(0),
764 INTEL_BDW_ULT_GT3_IDS(0),
765 INTEL_BDW_ULT_RSVD_IDS(0),
766 INTEL_SKL_ULT_GT1_IDS(0),
767 INTEL_SKL_ULT_GT2_IDS(0),
768 INTEL_SKL_ULT_GT3_IDS(0),
769 INTEL_KBL_ULT_GT1_IDS(0),
770 INTEL_KBL_ULT_GT2_IDS(0),
771 INTEL_KBL_ULT_GT3_IDS(0),
772 INTEL_CFL_U_GT2_IDS(0),
773 INTEL_CFL_U_GT3_IDS(0),
774 INTEL_WHL_U_GT1_IDS(0),
775 INTEL_WHL_U_GT2_IDS(0),
c3ad8d29 776 INTEL_WHL_U_GT3_IDS(0),
805446c8
TU
777};
778
779static const u16 subplatform_ulx_ids[] = {
780 INTEL_HSW_ULX_GT1_IDS(0),
781 INTEL_HSW_ULX_GT2_IDS(0),
782 INTEL_BDW_ULX_GT1_IDS(0),
783 INTEL_BDW_ULX_GT2_IDS(0),
784 INTEL_BDW_ULX_GT3_IDS(0),
785 INTEL_BDW_ULX_RSVD_IDS(0),
786 INTEL_SKL_ULX_GT1_IDS(0),
787 INTEL_SKL_ULX_GT2_IDS(0),
788 INTEL_KBL_ULX_GT1_IDS(0),
c3ad8d29 789 INTEL_KBL_ULX_GT2_IDS(0),
805446c8 790 INTEL_AML_KBL_GT2_IDS(0),
c3ad8d29 791 INTEL_AML_CFL_GT2_IDS(0),
805446c8
TU
792};
793
794static const u16 subplatform_portf_ids[] = {
795 INTEL_CNL_PORT_F_IDS(0),
c3ad8d29 796 INTEL_ICL_PORT_F_IDS(0),
805446c8
TU
797};
798
799static bool find_devid(u16 id, const u16 *p, unsigned int num)
800{
801 for (; num; num--, p++) {
802 if (*p == id)
803 return true;
804 }
805
806 return false;
807}
808
809void intel_device_info_subplatform_init(struct drm_i915_private *i915)
810{
811 const struct intel_device_info *info = INTEL_INFO(i915);
812 const struct intel_runtime_info *rinfo = RUNTIME_INFO(i915);
813 const unsigned int pi = __platform_mask_index(rinfo, info->platform);
814 const unsigned int pb = __platform_mask_bit(rinfo, info->platform);
815 u16 devid = INTEL_DEVID(i915);
640cde65 816 u32 mask = 0;
805446c8
TU
817
818 /* Make sure IS_<platform> checks are working. */
819 RUNTIME_INFO(i915)->platform_mask[pi] = BIT(pb);
820
821 /* Find and mark subplatform bits based on the PCI device id. */
822 if (find_devid(devid, subplatform_ult_ids,
823 ARRAY_SIZE(subplatform_ult_ids))) {
824 mask = BIT(INTEL_SUBPLATFORM_ULT);
825 } else if (find_devid(devid, subplatform_ulx_ids,
826 ARRAY_SIZE(subplatform_ulx_ids))) {
827 mask = BIT(INTEL_SUBPLATFORM_ULX);
828 if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
829 /* ULX machines are also considered ULT. */
830 mask |= BIT(INTEL_SUBPLATFORM_ULT);
831 }
805446c8
TU
832 } else if (find_devid(devid, subplatform_portf_ids,
833 ARRAY_SIZE(subplatform_portf_ids))) {
834 mask = BIT(INTEL_SUBPLATFORM_PORTF);
835 }
836
837 GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_BITS);
838
839 RUNTIME_INFO(i915)->platform_mask[pi] |= mask;
840}
841
6a7e51f3
MW
842/**
843 * intel_device_info_runtime_init - initialize runtime info
963cc126 844 * @dev_priv: the i915 device
6a7e51f3 845 *
94b4f3ba
CW
846 * Determine various intel_device_info fields at runtime.
847 *
848 * Use it when either:
849 * - it's judged too laborious to fill n static structures with the limit
850 * when a simple if statement does the job,
851 * - run-time checks (eg read fuse/strap registers) are needed.
852 *
853 * This function needs to be called:
854 * - after the MMIO has been setup as we are reading registers,
855 * - after the PCH has been detected,
856 * - before the first usage of the fields it can tweak.
857 */
1400cc7e 858void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
94b4f3ba 859{
1400cc7e 860 struct intel_device_info *info = mkwrite_device_info(dev_priv);
0258404f 861 struct intel_runtime_info *runtime = RUNTIME_INFO(dev_priv);
94b4f3ba
CW
862 enum pipe pipe;
863
6e7406db
MK
864 if (INTEL_GEN(dev_priv) >= 10) {
865 for_each_pipe(dev_priv, pipe)
0258404f 866 runtime->num_scalers[pipe] = 2;
cf819eff 867 } else if (IS_GEN(dev_priv, 9)) {
0258404f
JN
868 runtime->num_scalers[PIPE_A] = 2;
869 runtime->num_scalers[PIPE_B] = 2;
870 runtime->num_scalers[PIPE_C] = 1;
0bf0230e
ACO
871 }
872
8a68d464 873 BUILD_BUG_ON(BITS_PER_TYPE(intel_engine_mask_t) < I915_NUM_ENGINES);
022d3093 874
2dd24a9c 875 if (INTEL_GEN(dev_priv) >= 11)
6711bd73 876 for_each_pipe(dev_priv, pipe)
0258404f 877 runtime->num_sprites[pipe] = 6;
cf819eff 878 else if (IS_GEN(dev_priv, 10) || IS_GEMINILAKE(dev_priv))
e9c98825 879 for_each_pipe(dev_priv, pipe)
0258404f 880 runtime->num_sprites[pipe] = 3;
e9c98825 881 else if (IS_BROXTON(dev_priv)) {
6711bd73
ML
882 /*
883 * Skylake and Broxton currently don't expose the topmost plane as its
884 * use is exclusive with the legacy cursor and we only want to expose
885 * one of those, not both. Until we can safely expose the topmost plane
886 * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
887 * we don't expose the topmost plane at all to prevent ABI breakage
888 * down the line.
889 */
890
0258404f
JN
891 runtime->num_sprites[PIPE_A] = 2;
892 runtime->num_sprites[PIPE_B] = 2;
893 runtime->num_sprites[PIPE_C] = 1;
33edc24d 894 } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
94b4f3ba 895 for_each_pipe(dev_priv, pipe)
0258404f 896 runtime->num_sprites[pipe] = 2;
ab33081a 897 } else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) {
94b4f3ba 898 for_each_pipe(dev_priv, pipe)
0258404f 899 runtime->num_sprites[pipe] = 1;
33edc24d 900 }
94b4f3ba 901
4f044a88 902 if (i915_modparams.disable_display) {
94b4f3ba
CW
903 DRM_INFO("Display disabled (module parameter)\n");
904 info->num_pipes = 0;
e1bf094b 905 } else if (HAS_DISPLAY(dev_priv) &&
f3ce44a0 906 (IS_GEN_RANGE(dev_priv, 7, 8)) &&
94b4f3ba
CW
907 HAS_PCH_SPLIT(dev_priv)) {
908 u32 fuse_strap = I915_READ(FUSE_STRAP);
909 u32 sfuse_strap = I915_READ(SFUSE_STRAP);
910
911 /*
912 * SFUSE_STRAP is supposed to have a bit signalling the display
913 * is fused off. Unfortunately it seems that, at least in
914 * certain cases, fused off display means that PCH display
915 * reads don't land anywhere. In that case, we read 0s.
916 *
917 * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
918 * should be set when taking over after the firmware.
919 */
920 if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
921 sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
b9eb89b2 922 (HAS_PCH_CPT(dev_priv) &&
94b4f3ba
CW
923 !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
924 DRM_INFO("Display fused off, disabling\n");
925 info->num_pipes = 0;
926 } else if (fuse_strap & IVB_PIPE_C_DISABLE) {
927 DRM_INFO("PipeC fused off\n");
928 info->num_pipes -= 1;
929 }
bea68f4a 930 } else if (HAS_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 9) {
94b4f3ba 931 u32 dfsm = I915_READ(SKL_DFSM);
501ec325 932 u8 enabled_mask = BIT(info->num_pipes) - 1;
94b4f3ba
CW
933
934 if (dfsm & SKL_DFSM_PIPE_A_DISABLE)
501ec325 935 enabled_mask &= ~BIT(PIPE_A);
94b4f3ba 936 if (dfsm & SKL_DFSM_PIPE_B_DISABLE)
501ec325 937 enabled_mask &= ~BIT(PIPE_B);
94b4f3ba 938 if (dfsm & SKL_DFSM_PIPE_C_DISABLE)
501ec325 939 enabled_mask &= ~BIT(PIPE_C);
94b4f3ba 940
501ec325
LDM
941 /*
942 * At least one pipe should be enabled and if there are
943 * disabled pipes, they should be the last ones, with no holes
944 * in the mask.
945 */
946 if (enabled_mask == 0 || !is_power_of_2(enabled_mask + 1))
947 DRM_ERROR("invalid pipe fuse configuration: enabled_mask=0x%x\n",
948 enabled_mask);
94b4f3ba 949 else
501ec325 950 info->num_pipes = hweight8(enabled_mask);
94b4f3ba
CW
951 }
952
953 /* Initialize slice/subslice/EU info */
b8ec759e
LL
954 if (IS_HASWELL(dev_priv))
955 haswell_sseu_info_init(dev_priv);
956 else if (IS_CHERRYVIEW(dev_priv))
94b4f3ba
CW
957 cherryview_sseu_info_init(dev_priv);
958 else if (IS_BROADWELL(dev_priv))
959 broadwell_sseu_info_init(dev_priv);
cf819eff 960 else if (IS_GEN(dev_priv, 9))
94b4f3ba 961 gen9_sseu_info_init(dev_priv);
cf819eff 962 else if (IS_GEN(dev_priv, 10))
4e9767bc 963 gen10_sseu_info_init(dev_priv);
f60fa408 964 else if (INTEL_GEN(dev_priv) >= 11)
8b5eb5e2 965 gen11_sseu_info_init(dev_priv);
94b4f3ba 966
cf819eff 967 if (IS_GEN(dev_priv, 6) && intel_vtd_active()) {
4bdafb9d 968 DRM_INFO("Disabling ppGTT for VT-d support\n");
cbecbcca 969 info->ppgtt_type = INTEL_PPGTT_NONE;
4bdafb9d
CW
970 }
971
dab91783 972 /* Initialize command stream timestamp frequency */
0258404f 973 runtime->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv);
94b4f3ba 974}
3fed1808
CW
975
976void intel_driver_caps_print(const struct intel_driver_caps *caps,
977 struct drm_printer *p)
978{
481827b4
CW
979 drm_printf(p, "Has logical contexts? %s\n",
980 yesno(caps->has_logical_contexts));
3fed1808
CW
981 drm_printf(p, "scheduler: %x\n", caps->scheduler);
982}
26376a7e
OM
983
984/*
985 * Determine which engines are fused off in our particular hardware. Since the
986 * fuse register is in the blitter powerwell, we need forcewake to be ready at
987 * this point (but later we need to prune the forcewake domains for engines that
988 * are indeed fused off).
989 */
990void intel_device_info_init_mmio(struct drm_i915_private *dev_priv)
991{
992 struct intel_device_info *info = mkwrite_device_info(dev_priv);
57b19d55 993 unsigned int logical_vdbox = 0;
9213e4f5 994 unsigned int i;
57b19d55 995 u32 media_fuse;
97ee6e92
DCS
996 u16 vdbox_mask;
997 u16 vebox_mask;
26376a7e
OM
998
999 if (INTEL_GEN(dev_priv) < 11)
1000 return;
1001
9213e4f5 1002 media_fuse = ~I915_READ(GEN11_GT_VEBOX_VDBOX_DISABLE);
26376a7e 1003
97ee6e92
DCS
1004 vdbox_mask = media_fuse & GEN11_GT_VDBOX_DISABLE_MASK;
1005 vebox_mask = (media_fuse & GEN11_GT_VEBOX_DISABLE_MASK) >>
1006 GEN11_GT_VEBOX_DISABLE_SHIFT;
26376a7e 1007
26376a7e
OM
1008 for (i = 0; i < I915_MAX_VCS; i++) {
1009 if (!HAS_ENGINE(dev_priv, _VCS(i)))
1010 continue;
1011
97ee6e92 1012 if (!(BIT(i) & vdbox_mask)) {
8a68d464 1013 info->engine_mask &= ~BIT(_VCS(i));
9213e4f5 1014 DRM_DEBUG_DRIVER("vcs%u fused off\n", i);
57b19d55 1015 continue;
9213e4f5 1016 }
57b19d55
OM
1017
1018 /*
1019 * In Gen11, only even numbered logical VDBOXes are
1020 * hooked up to an SFC (Scaler & Format Converter) unit.
1021 */
1022 if (logical_vdbox++ % 2 == 0)
0258404f 1023 RUNTIME_INFO(dev_priv)->vdbox_sfc_access |= BIT(i);
26376a7e 1024 }
9511cb64
CW
1025 DRM_DEBUG_DRIVER("vdbox enable: %04x, instances: %04lx\n",
1026 vdbox_mask, VDBOX_MASK(dev_priv));
1027 GEM_BUG_ON(vdbox_mask != VDBOX_MASK(dev_priv));
26376a7e 1028
26376a7e
OM
1029 for (i = 0; i < I915_MAX_VECS; i++) {
1030 if (!HAS_ENGINE(dev_priv, _VECS(i)))
1031 continue;
1032
97ee6e92 1033 if (!(BIT(i) & vebox_mask)) {
8a68d464 1034 info->engine_mask &= ~BIT(_VECS(i));
9213e4f5
TU
1035 DRM_DEBUG_DRIVER("vecs%u fused off\n", i);
1036 }
26376a7e 1037 }
9511cb64
CW
1038 DRM_DEBUG_DRIVER("vebox enable: %04x, instances: %04lx\n",
1039 vebox_mask, VEBOX_MASK(dev_priv));
1040 GEM_BUG_ON(vebox_mask != VEBOX_MASK(dev_priv));
26376a7e 1041}