diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index e620e853efcb544baa3b5d101a6322160985ced1..25b6ba723e31554800089dd7d8827f568645f787 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -47,6 +47,8 @@ MODULE_FIRMWARE(I915_CSR_SKL); MODULE_FIRMWARE(I915_CSR_BXT); +#define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 23) + /* * SKL CSR registers for DC5 and DC6 */ @@ -303,10 +305,8 @@ static void finish_csr_load(const struct firmware *fw, void *context) uint32_t *dmc_payload; bool fw_loaded = false; - if (!fw) { - i915_firmware_load_error_print(csr->fw_path, 0); + if (!fw) goto out; - } if ((stepping == -ENODATA) || (substepping == -ENODATA)) { DRM_ERROR("Unknown stepping info, firmware loading failed\n"); @@ -324,6 +324,17 @@ static void finish_csr_load(const struct firmware *fw, void *context) csr->version = css_header->version; + if (IS_SKYLAKE(dev) && csr->version < SKL_CSR_VERSION_REQUIRED) { + DRM_INFO("Refusing to load old Skylake DMC firmware v%u.%u," + " please upgrade to v%u.%u or later" + " [https://01.org/linuxgraphics/intel-linux-graphics-firmwares].\n", + CSR_VERSION_MAJOR(csr->version), + CSR_VERSION_MINOR(csr->version), + CSR_VERSION_MAJOR(SKL_CSR_VERSION_REQUIRED), + CSR_VERSION_MINOR(SKL_CSR_VERSION_REQUIRED)); + goto out; + } + readcount += sizeof(struct intel_css_header); /* Extract Package Header information*/ @@ -405,17 +416,20 @@ static void finish_csr_load(const struct firmware *fw, void *context) intel_csr_load_program(dev); fw_loaded = true; - DRM_INFO("Finished loading %s (v%u.%u)\n", - dev_priv->csr.fw_path, - CSR_VERSION_MAJOR(csr->version), - CSR_VERSION_MINOR(csr->version)); - out: - if (fw_loaded) + if (fw_loaded) { intel_runtime_pm_put(dev_priv); - else + + DRM_INFO("Finished loading %s (v%u.%u)\n", + dev_priv->csr.fw_path, + CSR_VERSION_MAJOR(csr->version), + CSR_VERSION_MINOR(csr->version)); + } else { intel_csr_load_status_set(dev_priv, FW_FAILED); + i915_firmware_load_error_print(csr->fw_path, 0); + } + release_firmware(fw); }