Merge tag 'drm-intel-next-2018-09-06-2' of git://anongit.freedesktop.org/drm/drm...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / intel_csr.c
index cf9b600cca79f22adbe01ecf05fede19c5560392..14cf4c367e368ae4549c03a439a84d55d9882bf7 100644 (file)
@@ -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);
 }