Commit a64f8887 authored by Jyoti Yadav's avatar Jyoti Yadav Committed by Imre Deak

drm/i915/intel_csr.c Fix DMC FW Loading issue on ICL.

This patch resolves the DMC FW loading issue.
Earlier DMC FW package have only one DMC FW for one stepping. But as such
there is no such restriction from Package side.
For ICL icl_dmc_ver1_07.bin binary package has DMC FW for 2 steppings.
So while reading the dmc_offset from package header, for 1st stepping
offset used to come 0x0 and was working fine till now.
But for second stepping and other steppings, offset is non zero number
and is in dwords. So we need to convert into bytes to fetch correct DMC
FW from correct place.

v2 : Added check for DMC FW max size for various gen. (Imre Deak)
v3 : Corrected naming convention for various gen. (Imre Deak)
v4 : Initialized max_fw_size to 0
v5 : Corrected DMC FW MAX_SIZE for various gen. (Imre Deak)
v6 : Fixed the typo issues.
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarJyoti Yadav <jyoti.r.yadav@intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1535695223-4648-1-git-send-email-jyoti.r.yadav@intel.com
parent 3f51b7e1
...@@ -55,7 +55,9 @@ MODULE_FIRMWARE(I915_CSR_BXT); ...@@ -55,7 +55,9 @@ MODULE_FIRMWARE(I915_CSR_BXT);
#define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) #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 #define CSR_DEFAULT_FW_OFFSET 0xFFFFFFFF
struct intel_css_header { struct intel_css_header {
...@@ -279,6 +281,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, ...@@ -279,6 +281,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
struct intel_csr *csr = &dev_priv->csr; struct intel_csr *csr = &dev_priv->csr;
const struct stepping_info *si = intel_get_stepping_info(dev_priv); const struct stepping_info *si = intel_get_stepping_info(dev_priv);
uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes;
uint32_t max_fw_size = 0;
uint32_t i; uint32_t i;
uint32_t *dmc_payload; uint32_t *dmc_payload;
uint32_t required_version; uint32_t required_version;
...@@ -359,6 +362,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, ...@@ -359,6 +362,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
si->stepping); si->stepping);
return NULL; return NULL;
} }
/* Convert dmc_offset into number of bytes. By default it is in dwords*/
dmc_offset *= 4;
readcount += dmc_offset; readcount += dmc_offset;
/* Extract dmc_header information. */ /* Extract dmc_header information. */
...@@ -391,8 +396,16 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, ...@@ -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. */ /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
nbytes = dmc_header->fw_size * 4; nbytes = dmc_header->fw_size * 4;
if (nbytes > CSR_MAX_FW_SIZE) { if (INTEL_GEN(dev_priv) >= 11)
DRM_ERROR("DMC firmware too big (%u bytes)\n", nbytes); 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; return NULL;
} }
csr->dmc_fw_size = dmc_header->fw_size; csr->dmc_fw_size = dmc_header->fw_size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment