summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_csr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_csr.c')
-rw-r--r--drivers/gpu/drm/i915/intel_csr.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
index cf9b600cca79..14cf4c367e36 100644
--- a/drivers/gpu/drm/i915/intel_csr.c
+++ b/drivers/gpu/drm/i915/intel_csr.c
@@ -55,7 +55,9 @@ MODULE_FIRMWARE(I915_CSR_BXT);
#define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7)
-#define CSR_MAX_FW_SIZE 0x2FFF
+#define BXT_CSR_MAX_FW_SIZE 0x3000
+#define GLK_CSR_MAX_FW_SIZE 0x4000
+#define ICL_CSR_MAX_FW_SIZE 0x6000
#define CSR_DEFAULT_FW_OFFSET 0xFFFFFFFF
struct intel_css_header {
@@ -279,6 +281,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
struct intel_csr *csr = &dev_priv->csr;
const struct stepping_info *si = intel_get_stepping_info(dev_priv);
uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes;
+ uint32_t max_fw_size = 0;
uint32_t i;
uint32_t *dmc_payload;
uint32_t required_version;
@@ -359,6 +362,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
si->stepping);
return NULL;
}
+ /* Convert dmc_offset into number of bytes. By default it is in dwords*/
+ dmc_offset *= 4;
readcount += dmc_offset;
/* Extract dmc_header information. */
@@ -391,8 +396,16 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
/* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
nbytes = dmc_header->fw_size * 4;
- if (nbytes > CSR_MAX_FW_SIZE) {
- DRM_ERROR("DMC firmware too big (%u bytes)\n", nbytes);
+ if (INTEL_GEN(dev_priv) >= 11)
+ max_fw_size = ICL_CSR_MAX_FW_SIZE;
+ else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
+ max_fw_size = GLK_CSR_MAX_FW_SIZE;
+ else if (IS_GEN9(dev_priv))
+ max_fw_size = BXT_CSR_MAX_FW_SIZE;
+ else
+ MISSING_CASE(INTEL_REVID(dev_priv));
+ if (nbytes > max_fw_size) {
+ DRM_ERROR("DMC FW too big (%u bytes)\n", nbytes);
return NULL;
}
csr->dmc_fw_size = dmc_header->fw_size;
@@ -468,12 +481,6 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
csr->fw_path = I915_CSR_SKL;
else if (IS_BROXTON(dev_priv))
csr->fw_path = I915_CSR_BXT;
- else {
- DRM_ERROR("Unexpected: no known CSR firmware for platform\n");
- return;
- }
-
- DRM_DEBUG_KMS("Loading %s\n", csr->fw_path);
/*
* Obtain a runtime pm reference, until CSR is loaded,
@@ -481,6 +488,14 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
*/
intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
+ if (csr->fw_path == NULL) {
+ DRM_DEBUG_KMS("No known CSR firmware for platform, disabling runtime PM\n");
+ WARN_ON(!IS_ALPHA_SUPPORT(INTEL_INFO(dev_priv)));
+
+ return;
+ }
+
+ DRM_DEBUG_KMS("Loading %s\n", csr->fw_path);
schedule_work(&dev_priv->csr.work);
}