diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_csr.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_csr.c | 162 |
1 files changed, 88 insertions, 74 deletions
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index d48186e9ddad..a516697bf57d 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c | |||
@@ -34,34 +34,38 @@ | |||
34 | * low-power state and comes back to normal. | 34 | * low-power state and comes back to normal. |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #define I915_CSR_ICL "i915/icl_dmc_ver1_07.bin" | 37 | #define GEN12_CSR_MAX_FW_SIZE ICL_CSR_MAX_FW_SIZE |
38 | MODULE_FIRMWARE(I915_CSR_ICL); | ||
39 | #define ICL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) | ||
40 | 38 | ||
41 | #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" | 39 | #define ICL_CSR_PATH "i915/icl_dmc_ver1_07.bin" |
42 | MODULE_FIRMWARE(I915_CSR_GLK); | 40 | #define ICL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) |
43 | #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) | 41 | #define ICL_CSR_MAX_FW_SIZE 0x6000 |
42 | MODULE_FIRMWARE(ICL_CSR_PATH); | ||
44 | 43 | ||
45 | #define I915_CSR_CNL "i915/cnl_dmc_ver1_07.bin" | 44 | #define CNL_CSR_PATH "i915/cnl_dmc_ver1_07.bin" |
46 | MODULE_FIRMWARE(I915_CSR_CNL); | ||
47 | #define CNL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) | 45 | #define CNL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) |
46 | #define CNL_CSR_MAX_FW_SIZE GLK_CSR_MAX_FW_SIZE | ||
47 | MODULE_FIRMWARE(CNL_CSR_PATH); | ||
48 | |||
49 | #define GLK_CSR_PATH "i915/glk_dmc_ver1_04.bin" | ||
50 | #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) | ||
51 | #define GLK_CSR_MAX_FW_SIZE 0x4000 | ||
52 | MODULE_FIRMWARE(GLK_CSR_PATH); | ||
48 | 53 | ||
49 | #define I915_CSR_KBL "i915/kbl_dmc_ver1_04.bin" | 54 | #define KBL_CSR_PATH "i915/kbl_dmc_ver1_04.bin" |
50 | MODULE_FIRMWARE(I915_CSR_KBL); | ||
51 | #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) | 55 | #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) |
56 | #define KBL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE | ||
57 | MODULE_FIRMWARE(KBL_CSR_PATH); | ||
52 | 58 | ||
53 | #define I915_CSR_SKL "i915/skl_dmc_ver1_27.bin" | 59 | #define SKL_CSR_PATH "i915/skl_dmc_ver1_27.bin" |
54 | MODULE_FIRMWARE(I915_CSR_SKL); | ||
55 | #define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 27) | 60 | #define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 27) |
61 | #define SKL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE | ||
62 | MODULE_FIRMWARE(SKL_CSR_PATH); | ||
56 | 63 | ||
57 | #define I915_CSR_BXT "i915/bxt_dmc_ver1_07.bin" | 64 | #define BXT_CSR_PATH "i915/bxt_dmc_ver1_07.bin" |
58 | MODULE_FIRMWARE(I915_CSR_BXT); | ||
59 | #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) | 65 | #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) |
60 | |||
61 | |||
62 | #define BXT_CSR_MAX_FW_SIZE 0x3000 | 66 | #define BXT_CSR_MAX_FW_SIZE 0x3000 |
63 | #define GLK_CSR_MAX_FW_SIZE 0x4000 | 67 | MODULE_FIRMWARE(BXT_CSR_PATH); |
64 | #define ICL_CSR_MAX_FW_SIZE 0x6000 | 68 | |
65 | #define CSR_DEFAULT_FW_OFFSET 0xFFFFFFFF | 69 | #define CSR_DEFAULT_FW_OFFSET 0xFFFFFFFF |
66 | 70 | ||
67 | struct intel_css_header { | 71 | struct intel_css_header { |
@@ -190,6 +194,12 @@ static const struct stepping_info bxt_stepping_info[] = { | |||
190 | {'B', '0'}, {'B', '1'}, {'B', '2'} | 194 | {'B', '0'}, {'B', '1'}, {'B', '2'} |
191 | }; | 195 | }; |
192 | 196 | ||
197 | static const struct stepping_info icl_stepping_info[] = { | ||
198 | {'A', '0'}, {'A', '1'}, {'A', '2'}, | ||
199 | {'B', '0'}, {'B', '2'}, | ||
200 | {'C', '0'} | ||
201 | }; | ||
202 | |||
193 | static const struct stepping_info no_stepping_info = { '*', '*' }; | 203 | static const struct stepping_info no_stepping_info = { '*', '*' }; |
194 | 204 | ||
195 | static const struct stepping_info * | 205 | static const struct stepping_info * |
@@ -198,7 +208,10 @@ intel_get_stepping_info(struct drm_i915_private *dev_priv) | |||
198 | const struct stepping_info *si; | 208 | const struct stepping_info *si; |
199 | unsigned int size; | 209 | unsigned int size; |
200 | 210 | ||
201 | if (IS_SKYLAKE(dev_priv)) { | 211 | if (IS_ICELAKE(dev_priv)) { |
212 | size = ARRAY_SIZE(icl_stepping_info); | ||
213 | si = icl_stepping_info; | ||
214 | } else if (IS_SKYLAKE(dev_priv)) { | ||
202 | size = ARRAY_SIZE(skl_stepping_info); | 215 | size = ARRAY_SIZE(skl_stepping_info); |
203 | si = skl_stepping_info; | 216 | si = skl_stepping_info; |
204 | } else if (IS_BROXTON(dev_priv)) { | 217 | } else if (IS_BROXTON(dev_priv)) { |
@@ -285,10 +298,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, | |||
285 | struct intel_csr *csr = &dev_priv->csr; | 298 | struct intel_csr *csr = &dev_priv->csr; |
286 | const struct stepping_info *si = intel_get_stepping_info(dev_priv); | 299 | const struct stepping_info *si = intel_get_stepping_info(dev_priv); |
287 | uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; | 300 | uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; |
288 | uint32_t max_fw_size = 0; | ||
289 | uint32_t i; | 301 | uint32_t i; |
290 | uint32_t *dmc_payload; | 302 | uint32_t *dmc_payload; |
291 | uint32_t required_version; | ||
292 | 303 | ||
293 | if (!fw) | 304 | if (!fw) |
294 | return NULL; | 305 | return NULL; |
@@ -303,38 +314,19 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, | |||
303 | return NULL; | 314 | return NULL; |
304 | } | 315 | } |
305 | 316 | ||
306 | csr->version = css_header->version; | 317 | if (csr->required_version && |
307 | 318 | css_header->version != csr->required_version) { | |
308 | if (csr->fw_path == i915_modparams.dmc_firmware_path) { | ||
309 | /* Bypass version check for firmware override. */ | ||
310 | required_version = csr->version; | ||
311 | } else if (IS_ICELAKE(dev_priv)) { | ||
312 | required_version = ICL_CSR_VERSION_REQUIRED; | ||
313 | } else if (IS_CANNONLAKE(dev_priv)) { | ||
314 | required_version = CNL_CSR_VERSION_REQUIRED; | ||
315 | } else if (IS_GEMINILAKE(dev_priv)) { | ||
316 | required_version = GLK_CSR_VERSION_REQUIRED; | ||
317 | } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { | ||
318 | required_version = KBL_CSR_VERSION_REQUIRED; | ||
319 | } else if (IS_SKYLAKE(dev_priv)) { | ||
320 | required_version = SKL_CSR_VERSION_REQUIRED; | ||
321 | } else if (IS_BROXTON(dev_priv)) { | ||
322 | required_version = BXT_CSR_VERSION_REQUIRED; | ||
323 | } else { | ||
324 | MISSING_CASE(INTEL_REVID(dev_priv)); | ||
325 | required_version = 0; | ||
326 | } | ||
327 | |||
328 | if (csr->version != required_version) { | ||
329 | DRM_INFO("Refusing to load DMC firmware v%u.%u," | 319 | DRM_INFO("Refusing to load DMC firmware v%u.%u," |
330 | " please use v%u.%u\n", | 320 | " please use v%u.%u\n", |
331 | CSR_VERSION_MAJOR(csr->version), | 321 | CSR_VERSION_MAJOR(css_header->version), |
332 | CSR_VERSION_MINOR(csr->version), | 322 | CSR_VERSION_MINOR(css_header->version), |
333 | CSR_VERSION_MAJOR(required_version), | 323 | CSR_VERSION_MAJOR(csr->required_version), |
334 | CSR_VERSION_MINOR(required_version)); | 324 | CSR_VERSION_MINOR(csr->required_version)); |
335 | return NULL; | 325 | return NULL; |
336 | } | 326 | } |
337 | 327 | ||
328 | csr->version = css_header->version; | ||
329 | |||
338 | readcount += sizeof(struct intel_css_header); | 330 | readcount += sizeof(struct intel_css_header); |
339 | 331 | ||
340 | /* Extract Package Header information*/ | 332 | /* Extract Package Header information*/ |
@@ -402,15 +394,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, | |||
402 | 394 | ||
403 | /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */ | 395 | /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */ |
404 | nbytes = dmc_header->fw_size * 4; | 396 | nbytes = dmc_header->fw_size * 4; |
405 | if (INTEL_GEN(dev_priv) >= 11) | 397 | if (nbytes > csr->max_fw_size) { |
406 | max_fw_size = ICL_CSR_MAX_FW_SIZE; | ||
407 | else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) | ||
408 | max_fw_size = GLK_CSR_MAX_FW_SIZE; | ||
409 | else if (IS_GEN9(dev_priv)) | ||
410 | max_fw_size = BXT_CSR_MAX_FW_SIZE; | ||
411 | else | ||
412 | MISSING_CASE(INTEL_REVID(dev_priv)); | ||
413 | if (nbytes > max_fw_size) { | ||
414 | DRM_ERROR("DMC FW too big (%u bytes)\n", nbytes); | 398 | DRM_ERROR("DMC FW too big (%u bytes)\n", nbytes); |
415 | return NULL; | 399 | return NULL; |
416 | } | 400 | } |
@@ -475,27 +459,57 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) | |||
475 | if (!HAS_CSR(dev_priv)) | 459 | if (!HAS_CSR(dev_priv)) |
476 | return; | 460 | return; |
477 | 461 | ||
478 | if (i915_modparams.dmc_firmware_path) | ||
479 | csr->fw_path = i915_modparams.dmc_firmware_path; | ||
480 | else if (IS_ICELAKE(dev_priv)) | ||
481 | csr->fw_path = I915_CSR_ICL; | ||
482 | else if (IS_CANNONLAKE(dev_priv)) | ||
483 | csr->fw_path = I915_CSR_CNL; | ||
484 | else if (IS_GEMINILAKE(dev_priv)) | ||
485 | csr->fw_path = I915_CSR_GLK; | ||
486 | else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) | ||
487 | csr->fw_path = I915_CSR_KBL; | ||
488 | else if (IS_SKYLAKE(dev_priv)) | ||
489 | csr->fw_path = I915_CSR_SKL; | ||
490 | else if (IS_BROXTON(dev_priv)) | ||
491 | csr->fw_path = I915_CSR_BXT; | ||
492 | |||
493 | /* | 462 | /* |
494 | * Obtain a runtime pm reference, until CSR is loaded, | 463 | * Obtain a runtime pm reference, until CSR is loaded, to avoid entering |
495 | * to avoid entering runtime-suspend. | 464 | * runtime-suspend. |
465 | * | ||
466 | * On error, we return with the rpm wakeref held to prevent runtime | ||
467 | * suspend as runtime suspend *requires* a working CSR for whatever | ||
468 | * reason. | ||
496 | */ | 469 | */ |
497 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); | 470 | intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); |
498 | 471 | ||
472 | if (INTEL_GEN(dev_priv) >= 12) { | ||
473 | /* Allow to load fw via parameter using the last known size */ | ||
474 | csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE; | ||
475 | } else if (IS_ICELAKE(dev_priv)) { | ||
476 | csr->fw_path = ICL_CSR_PATH; | ||
477 | csr->required_version = ICL_CSR_VERSION_REQUIRED; | ||
478 | csr->max_fw_size = ICL_CSR_MAX_FW_SIZE; | ||
479 | } else if (IS_CANNONLAKE(dev_priv)) { | ||
480 | csr->fw_path = CNL_CSR_PATH; | ||
481 | csr->required_version = CNL_CSR_VERSION_REQUIRED; | ||
482 | csr->max_fw_size = CNL_CSR_MAX_FW_SIZE; | ||
483 | } else if (IS_GEMINILAKE(dev_priv)) { | ||
484 | csr->fw_path = GLK_CSR_PATH; | ||
485 | csr->required_version = GLK_CSR_VERSION_REQUIRED; | ||
486 | csr->max_fw_size = GLK_CSR_MAX_FW_SIZE; | ||
487 | } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { | ||
488 | csr->fw_path = KBL_CSR_PATH; | ||
489 | csr->required_version = KBL_CSR_VERSION_REQUIRED; | ||
490 | csr->max_fw_size = KBL_CSR_MAX_FW_SIZE; | ||
491 | } else if (IS_SKYLAKE(dev_priv)) { | ||
492 | csr->fw_path = SKL_CSR_PATH; | ||
493 | csr->required_version = SKL_CSR_VERSION_REQUIRED; | ||
494 | csr->max_fw_size = SKL_CSR_MAX_FW_SIZE; | ||
495 | } else if (IS_BROXTON(dev_priv)) { | ||
496 | csr->fw_path = BXT_CSR_PATH; | ||
497 | csr->required_version = BXT_CSR_VERSION_REQUIRED; | ||
498 | csr->max_fw_size = BXT_CSR_MAX_FW_SIZE; | ||
499 | } | ||
500 | |||
501 | if (i915_modparams.dmc_firmware_path) { | ||
502 | if (strlen(i915_modparams.dmc_firmware_path) == 0) { | ||
503 | csr->fw_path = NULL; | ||
504 | DRM_INFO("Disabling CSR firmware and runtime PM\n"); | ||
505 | return; | ||
506 | } | ||
507 | |||
508 | csr->fw_path = i915_modparams.dmc_firmware_path; | ||
509 | /* Bypass version check for firmware override. */ | ||
510 | csr->required_version = 0; | ||
511 | } | ||
512 | |||
499 | if (csr->fw_path == NULL) { | 513 | if (csr->fw_path == NULL) { |
500 | DRM_DEBUG_KMS("No known CSR firmware for platform, disabling runtime PM\n"); | 514 | DRM_DEBUG_KMS("No known CSR firmware for platform, disabling runtime PM\n"); |
501 | WARN_ON(!IS_ALPHA_SUPPORT(INTEL_INFO(dev_priv))); | 515 | WARN_ON(!IS_ALPHA_SUPPORT(INTEL_INFO(dev_priv))); |