提交 1bb4308e 编写于 作者: C Chris Wilson 提交者: Imre Deak

drm/i915/csr: Allow matching unknown HW steppings with generic firmware

If the firmware is generic and has a run-anywhere mode, enable it rather
than completely failing on unknown HW revisions.
Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
Cc: Damien Lespiau <damien.lespiau@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Sunil Kamath <sunil.kamath@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: NImre Deak <imre.deak@intel.com>
Signed-off-by: NImre Deak <imre.deak@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1457352357-8433-1-git-send-email-chris@chris-wilson.co.uk
上级 7cc96139
...@@ -188,28 +188,31 @@ static const struct stepping_info bxt_stepping_info[] = { ...@@ -188,28 +188,31 @@ static const struct stepping_info bxt_stepping_info[] = {
{'B', '0'}, {'B', '1'}, {'B', '2'} {'B', '0'}, {'B', '1'}, {'B', '2'}
}; };
static const struct stepping_info *intel_get_stepping_info(struct drm_device *dev) static const struct stepping_info no_stepping_info = { '*', '*' };
static const struct stepping_info *
intel_get_stepping_info(struct drm_i915_private *dev_priv)
{ {
const struct stepping_info *si; const struct stepping_info *si;
unsigned int size; unsigned int size;
if (IS_KABYLAKE(dev)) { if (IS_KABYLAKE(dev_priv)) {
size = ARRAY_SIZE(kbl_stepping_info); size = ARRAY_SIZE(kbl_stepping_info);
si = kbl_stepping_info; si = kbl_stepping_info;
} else if (IS_SKYLAKE(dev)) { } else if (IS_SKYLAKE(dev_priv)) {
size = ARRAY_SIZE(skl_stepping_info); size = ARRAY_SIZE(skl_stepping_info);
si = skl_stepping_info; si = skl_stepping_info;
} else if (IS_BROXTON(dev)) { } else if (IS_BROXTON(dev_priv)) {
size = ARRAY_SIZE(bxt_stepping_info); size = ARRAY_SIZE(bxt_stepping_info);
si = bxt_stepping_info; si = bxt_stepping_info;
} else { } else {
return NULL; size = 0;
} }
if (INTEL_REVID(dev) < size) if (INTEL_REVID(dev_priv) < size)
return si + INTEL_REVID(dev); return si + INTEL_REVID(dev_priv);
return NULL; return &no_stepping_info;
} }
static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv) static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv)
...@@ -270,13 +273,11 @@ void intel_csr_load_program(struct drm_i915_private *dev_priv) ...@@ -270,13 +273,11 @@ void intel_csr_load_program(struct drm_i915_private *dev_priv)
static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
const struct firmware *fw) const struct firmware *fw)
{ {
struct drm_device *dev = dev_priv->dev;
struct intel_css_header *css_header; struct intel_css_header *css_header;
struct intel_package_header *package_header; struct intel_package_header *package_header;
struct intel_dmc_header *dmc_header; struct intel_dmc_header *dmc_header;
struct intel_csr *csr = &dev_priv->csr; struct intel_csr *csr = &dev_priv->csr;
const struct stepping_info *stepping_info = intel_get_stepping_info(dev); const struct stepping_info *si = intel_get_stepping_info(dev_priv);
char stepping, substepping;
uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes;
uint32_t i; uint32_t i;
uint32_t *dmc_payload; uint32_t *dmc_payload;
...@@ -284,14 +285,6 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, ...@@ -284,14 +285,6 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
if (!fw) if (!fw)
return NULL; return NULL;
if (!stepping_info) {
DRM_ERROR("Unknown stepping info, firmware loading failed\n");
return NULL;
}
stepping = stepping_info->stepping;
substepping = stepping_info->substepping;
/* Extract CSS Header information*/ /* Extract CSS Header information*/
css_header = (struct intel_css_header *)fw->data; css_header = (struct intel_css_header *)fw->data;
if (sizeof(struct intel_css_header) != if (sizeof(struct intel_css_header) !=
...@@ -303,7 +296,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, ...@@ -303,7 +296,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
csr->version = css_header->version; csr->version = css_header->version;
if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && if ((IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) &&
csr->version < SKL_CSR_VERSION_REQUIRED) { csr->version < SKL_CSR_VERSION_REQUIRED) {
DRM_INFO("Refusing to load old Skylake DMC firmware v%u.%u," DRM_INFO("Refusing to load old Skylake DMC firmware v%u.%u,"
" please upgrade to v%u.%u or later" " please upgrade to v%u.%u or later"
...@@ -331,11 +324,11 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, ...@@ -331,11 +324,11 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
/* Search for dmc_offset to find firware binary. */ /* Search for dmc_offset to find firware binary. */
for (i = 0; i < package_header->num_entries; i++) { for (i = 0; i < package_header->num_entries; i++) {
if (package_header->fw_info[i].substepping == '*' && if (package_header->fw_info[i].substepping == '*' &&
stepping == package_header->fw_info[i].stepping) { si->stepping == package_header->fw_info[i].stepping) {
dmc_offset = package_header->fw_info[i].offset; dmc_offset = package_header->fw_info[i].offset;
break; break;
} else if (stepping == package_header->fw_info[i].stepping && } else if (si->stepping == package_header->fw_info[i].stepping &&
substepping == package_header->fw_info[i].substepping) { si->substepping == package_header->fw_info[i].substepping) {
dmc_offset = package_header->fw_info[i].offset; dmc_offset = package_header->fw_info[i].offset;
break; break;
} else if (package_header->fw_info[i].stepping == '*' && } else if (package_header->fw_info[i].stepping == '*' &&
...@@ -343,7 +336,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, ...@@ -343,7 +336,8 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
dmc_offset = package_header->fw_info[i].offset; dmc_offset = package_header->fw_info[i].offset;
} }
if (dmc_offset == CSR_DEFAULT_FW_OFFSET) { if (dmc_offset == CSR_DEFAULT_FW_OFFSET) {
DRM_ERROR("Firmware not supported for %c stepping\n", stepping); DRM_ERROR("Firmware not supported for %c stepping\n",
si->stepping);
return NULL; return NULL;
} }
readcount += dmc_offset; readcount += dmc_offset;
...@@ -389,9 +383,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, ...@@ -389,9 +383,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
return NULL; return NULL;
} }
memcpy(dmc_payload, &fw->data[readcount], nbytes); return memcpy(dmc_payload, &fw->data[readcount], nbytes);
return dmc_payload;
} }
static void csr_load_work_fn(struct work_struct *work) static void csr_load_work_fn(struct work_struct *work)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册