Commit | Line | Data |
---|---|---|
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 | ||
01fabda8 LDM |
25 | #include <linux/string_helpers.h> |
26 | ||
a8c9b849 | 27 | #include <drm/drm_print.h> |
aef8dc43 | 28 | #include <drm/intel/i915_pciids.h> |
a8c9b849 | 29 | |
c2c70752 | 30 | #include "gt/intel_gt_regs.h" |
94b4f3ba | 31 | #include "i915_drv.h" |
801543b2 | 32 | #include "i915_reg.h" |
a7f46d5b | 33 | #include "i915_utils.h" |
801543b2 | 34 | #include "intel_device_info.h" |
94b4f3ba | 35 | |
2e0d26f8 JN |
36 | #define PLATFORM_NAME(x) [INTEL_##x] = #x |
37 | static const char * const platform_names[] = { | |
38 | PLATFORM_NAME(I830), | |
39 | PLATFORM_NAME(I845G), | |
40 | PLATFORM_NAME(I85X), | |
41 | PLATFORM_NAME(I865G), | |
42 | PLATFORM_NAME(I915G), | |
43 | PLATFORM_NAME(I915GM), | |
44 | PLATFORM_NAME(I945G), | |
45 | PLATFORM_NAME(I945GM), | |
46 | PLATFORM_NAME(G33), | |
47 | PLATFORM_NAME(PINEVIEW), | |
c0f86832 JN |
48 | PLATFORM_NAME(I965G), |
49 | PLATFORM_NAME(I965GM), | |
f69c11ae JN |
50 | PLATFORM_NAME(G45), |
51 | PLATFORM_NAME(GM45), | |
2e0d26f8 JN |
52 | PLATFORM_NAME(IRONLAKE), |
53 | PLATFORM_NAME(SANDYBRIDGE), | |
54 | PLATFORM_NAME(IVYBRIDGE), | |
55 | PLATFORM_NAME(VALLEYVIEW), | |
56 | PLATFORM_NAME(HASWELL), | |
57 | PLATFORM_NAME(BROADWELL), | |
58 | PLATFORM_NAME(CHERRYVIEW), | |
59 | PLATFORM_NAME(SKYLAKE), | |
60 | PLATFORM_NAME(BROXTON), | |
61 | PLATFORM_NAME(KABYLAKE), | |
62 | PLATFORM_NAME(GEMINILAKE), | |
71851fa8 | 63 | PLATFORM_NAME(COFFEELAKE), |
5f4ae270 | 64 | PLATFORM_NAME(COMETLAKE), |
41231001 | 65 | PLATFORM_NAME(ICELAKE), |
897f2961 | 66 | PLATFORM_NAME(ELKHARTLAKE), |
24ea098b | 67 | PLATFORM_NAME(JASPERLAKE), |
abd3a0fe | 68 | PLATFORM_NAME(TIGERLAKE), |
123f62de | 69 | PLATFORM_NAME(ROCKETLAKE), |
05e26584 | 70 | PLATFORM_NAME(DG1), |
0883d63b | 71 | PLATFORM_NAME(ALDERLAKE_S), |
bdd27cad | 72 | PLATFORM_NAME(ALDERLAKE_P), |
9e22cfc5 | 73 | PLATFORM_NAME(DG2), |
bcf9b296 | 74 | PLATFORM_NAME(METEORLAKE), |
2e0d26f8 JN |
75 | }; |
76 | #undef PLATFORM_NAME | |
77 | ||
78 | const char *intel_platform_name(enum intel_platform platform) | |
79 | { | |
9160095c JN |
80 | BUILD_BUG_ON(ARRAY_SIZE(platform_names) != INTEL_MAX_PLATFORMS); |
81 | ||
2e0d26f8 JN |
82 | if (WARN_ON_ONCE(platform >= ARRAY_SIZE(platform_names) || |
83 | platform_names[platform] == NULL)) | |
84 | return "<unknown>"; | |
85 | ||
86 | return platform_names[platform]; | |
87 | } | |
88 | ||
c7d3c844 JN |
89 | void intel_device_info_print(const struct intel_device_info *info, |
90 | const struct intel_runtime_info *runtime, | |
91 | struct drm_printer *p) | |
72404978 | 92 | { |
f9e932a8 RS |
93 | if (runtime->graphics.ip.rel) |
94 | drm_printf(p, "graphics version: %u.%02u\n", | |
95 | runtime->graphics.ip.ver, | |
96 | runtime->graphics.ip.rel); | |
ca6374e2 | 97 | else |
f9e932a8 RS |
98 | drm_printf(p, "graphics version: %u\n", |
99 | runtime->graphics.ip.ver); | |
ca6374e2 | 100 | |
f9e932a8 RS |
101 | if (runtime->media.ip.rel) |
102 | drm_printf(p, "media version: %u.%02u\n", | |
103 | runtime->media.ip.ver, | |
104 | runtime->media.ip.rel); | |
ca6374e2 | 105 | else |
f9e932a8 RS |
106 | drm_printf(p, "media version: %u\n", |
107 | runtime->media.ip.ver); | |
ca6374e2 | 108 | |
3cd7cb2a VS |
109 | drm_printf(p, "graphics stepping: %s\n", intel_step_name(runtime->step.graphics_step)); |
110 | drm_printf(p, "media stepping: %s\n", intel_step_name(runtime->step.media_step)); | |
3cd7cb2a | 111 | |
72404978 | 112 | drm_printf(p, "gt: %d\n", info->gt); |
8776711e | 113 | drm_printf(p, "memory-regions: 0x%x\n", info->memory_regions); |
2cfd1b38 | 114 | drm_printf(p, "page-sizes: 0x%x\n", runtime->page_sizes); |
72404978 | 115 | drm_printf(p, "platform: %s\n", intel_platform_name(info->platform)); |
268c67e5 JN |
116 | drm_printf(p, "ppgtt-size: %d\n", runtime->ppgtt_size); |
117 | drm_printf(p, "ppgtt-type: %d\n", runtime->ppgtt_type); | |
31a02eb7 | 118 | drm_printf(p, "dma_mask_size: %u\n", info->dma_mask_size); |
72404978 | 119 | |
01fabda8 | 120 | #define PRINT_FLAG(name) drm_printf(p, "%s: %s\n", #name, str_yes_no(info->name)) |
a8c9b849 MW |
121 | DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG); |
122 | #undef PRINT_FLAG | |
d53db442 | 123 | |
39a445bb | 124 | drm_printf(p, "has_pooled_eu: %s\n", str_yes_no(runtime->has_pooled_eu)); |
dab91783 LL |
125 | } |
126 | ||
3c7bbd4c | 127 | #define ID(id) (id) |
805446c8 TU |
128 | |
129 | static const u16 subplatform_ult_ids[] = { | |
3c7bbd4c JN |
130 | INTEL_HSW_ULT_GT1_IDS(ID), |
131 | INTEL_HSW_ULT_GT2_IDS(ID), | |
132 | INTEL_HSW_ULT_GT3_IDS(ID), | |
133 | INTEL_BDW_ULT_GT1_IDS(ID), | |
134 | INTEL_BDW_ULT_GT2_IDS(ID), | |
135 | INTEL_BDW_ULT_GT3_IDS(ID), | |
136 | INTEL_BDW_ULT_RSVD_IDS(ID), | |
137 | INTEL_SKL_ULT_GT1_IDS(ID), | |
138 | INTEL_SKL_ULT_GT2_IDS(ID), | |
139 | INTEL_SKL_ULT_GT3_IDS(ID), | |
140 | INTEL_KBL_ULT_GT1_IDS(ID), | |
141 | INTEL_KBL_ULT_GT2_IDS(ID), | |
142 | INTEL_KBL_ULT_GT3_IDS(ID), | |
143 | INTEL_CFL_U_GT2_IDS(ID), | |
144 | INTEL_CFL_U_GT3_IDS(ID), | |
145 | INTEL_WHL_U_GT1_IDS(ID), | |
146 | INTEL_WHL_U_GT2_IDS(ID), | |
147 | INTEL_WHL_U_GT3_IDS(ID), | |
148 | INTEL_CML_U_GT1_IDS(ID), | |
149 | INTEL_CML_U_GT2_IDS(ID), | |
805446c8 TU |
150 | }; |
151 | ||
152 | static const u16 subplatform_ulx_ids[] = { | |
3c7bbd4c JN |
153 | INTEL_HSW_ULX_GT1_IDS(ID), |
154 | INTEL_HSW_ULX_GT2_IDS(ID), | |
155 | INTEL_BDW_ULX_GT1_IDS(ID), | |
156 | INTEL_BDW_ULX_GT2_IDS(ID), | |
157 | INTEL_BDW_ULX_GT3_IDS(ID), | |
158 | INTEL_BDW_ULX_RSVD_IDS(ID), | |
159 | INTEL_SKL_ULX_GT1_IDS(ID), | |
160 | INTEL_SKL_ULX_GT2_IDS(ID), | |
161 | INTEL_KBL_ULX_GT1_IDS(ID), | |
162 | INTEL_KBL_ULX_GT2_IDS(ID), | |
163 | INTEL_AML_KBL_GT2_IDS(ID), | |
164 | INTEL_AML_CFL_GT2_IDS(ID), | |
805446c8 TU |
165 | }; |
166 | ||
167 | static const u16 subplatform_portf_ids[] = { | |
3c7bbd4c | 168 | INTEL_ICL_PORT_F_IDS(ID), |
805446c8 TU |
169 | }; |
170 | ||
b9ef8939 | 171 | static const u16 subplatform_uy_ids[] = { |
3c7bbd4c | 172 | INTEL_TGL_GT2_IDS(ID), |
b9ef8939 JRS |
173 | }; |
174 | ||
7e28d0b2 | 175 | static const u16 subplatform_n_ids[] = { |
3c7bbd4c | 176 | INTEL_ADLN_IDS(ID), |
7e28d0b2 TU |
177 | }; |
178 | ||
72c3c8d6 | 179 | static const u16 subplatform_rpl_ids[] = { |
3c7bbd4c JN |
180 | INTEL_RPLS_IDS(ID), |
181 | INTEL_RPLU_IDS(ID), | |
182 | INTEL_RPLP_IDS(ID), | |
52407c22 AS |
183 | }; |
184 | ||
61b795a9 | 185 | static const u16 subplatform_rplu_ids[] = { |
3c7bbd4c | 186 | INTEL_RPLU_IDS(ID), |
61b795a9 CKB |
187 | }; |
188 | ||
1bc4ae0c | 189 | static const u16 subplatform_g10_ids[] = { |
3c7bbd4c JN |
190 | INTEL_DG2_G10_IDS(ID), |
191 | INTEL_ATS_M150_IDS(ID), | |
1bc4ae0c MR |
192 | }; |
193 | ||
194 | static const u16 subplatform_g11_ids[] = { | |
3c7bbd4c JN |
195 | INTEL_DG2_G11_IDS(ID), |
196 | INTEL_ATS_M75_IDS(ID), | |
1bc4ae0c MR |
197 | }; |
198 | ||
199 | static const u16 subplatform_g12_ids[] = { | |
3c7bbd4c | 200 | INTEL_DG2_G12_IDS(ID), |
52407c22 AS |
201 | }; |
202 | ||
67733d7a JH |
203 | static const u16 subplatform_arl_ids[] = { |
204 | INTEL_ARL_IDS(ID), | |
205 | }; | |
206 | ||
805446c8 TU |
207 | static bool find_devid(u16 id, const u16 *p, unsigned int num) |
208 | { | |
209 | for (; num; num--, p++) { | |
210 | if (*p == id) | |
211 | return true; | |
212 | } | |
213 | ||
214 | return false; | |
215 | } | |
216 | ||
c2c70752 | 217 | static void intel_device_info_subplatform_init(struct drm_i915_private *i915) |
805446c8 TU |
218 | { |
219 | const struct intel_device_info *info = INTEL_INFO(i915); | |
220 | const struct intel_runtime_info *rinfo = RUNTIME_INFO(i915); | |
221 | const unsigned int pi = __platform_mask_index(rinfo, info->platform); | |
222 | const unsigned int pb = __platform_mask_bit(rinfo, info->platform); | |
223 | u16 devid = INTEL_DEVID(i915); | |
640cde65 | 224 | u32 mask = 0; |
805446c8 TU |
225 | |
226 | /* Make sure IS_<platform> checks are working. */ | |
227 | RUNTIME_INFO(i915)->platform_mask[pi] = BIT(pb); | |
228 | ||
229 | /* Find and mark subplatform bits based on the PCI device id. */ | |
230 | if (find_devid(devid, subplatform_ult_ids, | |
231 | ARRAY_SIZE(subplatform_ult_ids))) { | |
232 | mask = BIT(INTEL_SUBPLATFORM_ULT); | |
233 | } else if (find_devid(devid, subplatform_ulx_ids, | |
234 | ARRAY_SIZE(subplatform_ulx_ids))) { | |
235 | mask = BIT(INTEL_SUBPLATFORM_ULX); | |
236 | if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { | |
237 | /* ULX machines are also considered ULT. */ | |
238 | mask |= BIT(INTEL_SUBPLATFORM_ULT); | |
239 | } | |
805446c8 TU |
240 | } else if (find_devid(devid, subplatform_portf_ids, |
241 | ARRAY_SIZE(subplatform_portf_ids))) { | |
242 | mask = BIT(INTEL_SUBPLATFORM_PORTF); | |
b9ef8939 JRS |
243 | } else if (find_devid(devid, subplatform_uy_ids, |
244 | ARRAY_SIZE(subplatform_uy_ids))) { | |
245 | mask = BIT(INTEL_SUBPLATFORM_UY); | |
7e28d0b2 TU |
246 | } else if (find_devid(devid, subplatform_n_ids, |
247 | ARRAY_SIZE(subplatform_n_ids))) { | |
248 | mask = BIT(INTEL_SUBPLATFORM_N); | |
72c3c8d6 MA |
249 | } else if (find_devid(devid, subplatform_rpl_ids, |
250 | ARRAY_SIZE(subplatform_rpl_ids))) { | |
251 | mask = BIT(INTEL_SUBPLATFORM_RPL); | |
61b795a9 CKB |
252 | if (find_devid(devid, subplatform_rplu_ids, |
253 | ARRAY_SIZE(subplatform_rplu_ids))) | |
254 | mask |= BIT(INTEL_SUBPLATFORM_RPLU); | |
1bc4ae0c MR |
255 | } else if (find_devid(devid, subplatform_g10_ids, |
256 | ARRAY_SIZE(subplatform_g10_ids))) { | |
257 | mask = BIT(INTEL_SUBPLATFORM_G10); | |
258 | } else if (find_devid(devid, subplatform_g11_ids, | |
259 | ARRAY_SIZE(subplatform_g11_ids))) { | |
260 | mask = BIT(INTEL_SUBPLATFORM_G11); | |
261 | } else if (find_devid(devid, subplatform_g12_ids, | |
262 | ARRAY_SIZE(subplatform_g12_ids))) { | |
263 | mask = BIT(INTEL_SUBPLATFORM_G12); | |
67733d7a JH |
264 | } else if (find_devid(devid, subplatform_arl_ids, |
265 | ARRAY_SIZE(subplatform_arl_ids))) { | |
266 | mask = BIT(INTEL_SUBPLATFORM_ARL); | |
805446c8 TU |
267 | } |
268 | ||
56afa701 | 269 | GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_MASK); |
805446c8 TU |
270 | |
271 | RUNTIME_INFO(i915)->platform_mask[pi] |= mask; | |
272 | } | |
273 | ||
ef7e222c | 274 | static void ip_ver_read(struct drm_i915_private *i915, u32 offset, struct intel_ip_version *ip) |
c2c70752 MR |
275 | { |
276 | struct pci_dev *pdev = to_pci_dev(i915->drm.dev); | |
277 | void __iomem *addr; | |
278 | u32 val; | |
279 | u8 expected_ver = ip->ver; | |
280 | u8 expected_rel = ip->rel; | |
281 | ||
282 | addr = pci_iomap_range(pdev, 0, offset, sizeof(u32)); | |
283 | if (drm_WARN_ON(&i915->drm, !addr)) | |
284 | return; | |
285 | ||
286 | val = ioread32(addr); | |
287 | pci_iounmap(pdev, addr); | |
288 | ||
289 | ip->ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val); | |
290 | ip->rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val); | |
291 | ip->step = REG_FIELD_GET(GMD_ID_STEP, val); | |
292 | ||
293 | /* Sanity check against expected versions from device info */ | |
294 | if (IP_VER(ip->ver, ip->rel) < IP_VER(expected_ver, expected_rel)) | |
295 | drm_dbg(&i915->drm, | |
296 | "Hardware reports GMD IP version %u.%u (REG[0x%x] = 0x%08x) but minimum expected is %u.%u\n", | |
297 | ip->ver, ip->rel, offset, val, expected_ver, expected_rel); | |
298 | } | |
299 | ||
300 | /* | |
301 | * Setup the graphics version for the current device. This must be done before | |
302 | * any code that performs checks on GRAPHICS_VER or DISPLAY_VER, so this | |
303 | * function should be called very early in the driver initialization sequence. | |
304 | * | |
305 | * Regular MMIO access is not yet setup at the point this function is called so | |
306 | * we peek at the appropriate MMIO offset directly. The GMD_ID register is | |
307 | * part of an 'always on' power well by design, so we don't need to worry about | |
308 | * forcewake while reading it. | |
309 | */ | |
310 | static void intel_ipver_early_init(struct drm_i915_private *i915) | |
311 | { | |
312 | struct intel_runtime_info *runtime = RUNTIME_INFO(i915); | |
313 | ||
80c1fb2e RS |
314 | if (!HAS_GMD_ID(i915)) { |
315 | drm_WARN_ON(&i915->drm, RUNTIME_INFO(i915)->graphics.ip.ver > 12); | |
316 | /* | |
317 | * On older platforms, graphics and media share the same ip | |
318 | * version and release. | |
319 | */ | |
320 | RUNTIME_INFO(i915)->media.ip = | |
321 | RUNTIME_INFO(i915)->graphics.ip; | |
c2c70752 | 322 | return; |
80c1fb2e | 323 | } |
c2c70752 MR |
324 | |
325 | ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_GRAPHICS), | |
326 | &runtime->graphics.ip); | |
41bb543f MR |
327 | /* Wa_22012778468 */ |
328 | if (runtime->graphics.ip.ver == 0x0 && | |
329 | INTEL_INFO(i915)->platform == INTEL_METEORLAKE) { | |
330 | RUNTIME_INFO(i915)->graphics.ip.ver = 12; | |
331 | RUNTIME_INFO(i915)->graphics.ip.rel = 70; | |
332 | } | |
c2c70752 MR |
333 | ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_MEDIA), |
334 | &runtime->media.ip); | |
335 | } | |
336 | ||
337 | /** | |
338 | * intel_device_info_runtime_init_early - initialize early runtime info | |
339 | * @i915: the i915 device | |
340 | * | |
341 | * Determine early intel_device_info fields at runtime. This function needs | |
342 | * to be called before the MMIO has been setup. | |
343 | */ | |
344 | void intel_device_info_runtime_init_early(struct drm_i915_private *i915) | |
345 | { | |
346 | intel_ipver_early_init(i915); | |
347 | intel_device_info_subplatform_init(i915); | |
348 | } | |
349 | ||
6a7e51f3 MW |
350 | /** |
351 | * intel_device_info_runtime_init - initialize runtime info | |
963cc126 | 352 | * @dev_priv: the i915 device |
6a7e51f3 | 353 | * |
94b4f3ba CW |
354 | * Determine various intel_device_info fields at runtime. |
355 | * | |
356 | * Use it when either: | |
357 | * - it's judged too laborious to fill n static structures with the limit | |
358 | * when a simple if statement does the job, | |
359 | * - run-time checks (eg read fuse/strap registers) are needed. | |
360 | * | |
361 | * This function needs to be called: | |
362 | * - after the MMIO has been setup as we are reading registers, | |
363 | * - after the PCH has been detected, | |
364 | * - before the first usage of the fields it can tweak. | |
365 | */ | |
1400cc7e | 366 | void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) |
94b4f3ba | 367 | { |
0258404f | 368 | struct intel_runtime_info *runtime = RUNTIME_INFO(dev_priv); |
022d3093 | 369 | |
2d0cdf60 | 370 | BUILD_BUG_ON(BITS_PER_TYPE(intel_engine_mask_t) < I915_NUM_ENGINES); |
94b4f3ba | 371 | |
a7f46d5b | 372 | if (GRAPHICS_VER(dev_priv) == 6 && i915_vtd_active(dev_priv)) { |
68b32717 WK |
373 | drm_info(&dev_priv->drm, |
374 | "Disabling ppGTT for VT-d support\n"); | |
268c67e5 | 375 | runtime->ppgtt_type = INTEL_PPGTT_NONE; |
4bdafb9d | 376 | } |
94b4f3ba | 377 | } |
3fed1808 | 378 | |
446a20c9 JN |
379 | /* |
380 | * Set up device info and initial runtime info at driver create. | |
381 | * | |
382 | * Note: i915 is only an allocated blob of memory at this point. | |
383 | */ | |
384 | void intel_device_info_driver_create(struct drm_i915_private *i915, | |
385 | u16 device_id, | |
386 | const struct intel_device_info *match_info) | |
387 | { | |
446a20c9 JN |
388 | struct intel_runtime_info *runtime; |
389 | ||
0c4f52ba JN |
390 | /* Setup INTEL_INFO() */ |
391 | i915->__info = match_info; | |
446a20c9 JN |
392 | |
393 | /* Initialize initial runtime info from static const data and pdev. */ | |
394 | runtime = RUNTIME_INFO(i915); | |
395 | memcpy(runtime, &INTEL_INFO(i915)->__runtime, sizeof(*runtime)); | |
69d43981 | 396 | |
446a20c9 JN |
397 | runtime->device_id = device_id; |
398 | } | |
399 | ||
3fed1808 CW |
400 | void intel_driver_caps_print(const struct intel_driver_caps *caps, |
401 | struct drm_printer *p) | |
402 | { | |
481827b4 | 403 | drm_printf(p, "Has logical contexts? %s\n", |
01fabda8 | 404 | str_yes_no(caps->has_logical_contexts)); |
2cfd1b38 | 405 | drm_printf(p, "scheduler: 0x%x\n", caps->scheduler); |
3fed1808 | 406 | } |