drm/i915/gsc: ARL-H and ARL-U need a newer GSC FW.

All MTL and ARL SKUs share the same GSC FW, but the newer platforms are
only supported in newer blobs. In particular, ARL-S is supported
starting from 102.0.10.1878 (which is already the minimum required
version for ARL in the code), while ARL-H and ARL-U are supported from
102.1.15.1926. Therefore, the driver needs to check which specific ARL
subplatform its running on when verifying that the GSC FW is new enough
for it.

Fixes: 2955ae8186 ("drm/i915: ARL requires a newer GSC firmware")
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: John Harrison <John.C.Harrison@Intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: John Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241028233132.149745-1-daniele.ceraolospurio@intel.com
(cherry picked from commit 3c1d5ced18)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
This commit is contained in:
Daniele Ceraolo Spurio 2024-10-28 16:31:32 -07:00 committed by Joonas Lahtinen
parent 2d5404caa8
commit db0fc586ed
5 changed files with 75 additions and 30 deletions

View File

@ -80,6 +80,7 @@ int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void *data, s
const struct intel_gsc_cpd_header_v2 *cpd_header = NULL; const struct intel_gsc_cpd_header_v2 *cpd_header = NULL;
const struct intel_gsc_cpd_entry *cpd_entry = NULL; const struct intel_gsc_cpd_entry *cpd_entry = NULL;
const struct intel_gsc_manifest_header *manifest; const struct intel_gsc_manifest_header *manifest;
struct intel_uc_fw_ver min_ver = { 0 };
size_t min_size = sizeof(*layout); size_t min_size = sizeof(*layout);
int i; int i;
@ -212,33 +213,46 @@ int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void *data, s
} }
} }
if (IS_ARROWLAKE(gt->i915)) { /*
* ARL SKUs require newer firmwares, but the blob is actually common
* across all MTL and ARL SKUs, so we need to do an explicit version check
* here rather than using a separate table entry. If a too old version
* is found, then just don't use GSC rather than aborting the driver load.
* Note that the major number in the GSC FW version is used to indicate
* the platform, so we expect it to always be 102 for MTL/ARL binaries.
*/
if (IS_ARROWLAKE_S(gt->i915))
min_ver = (struct intel_uc_fw_ver){ 102, 0, 10, 1878 };
else if (IS_ARROWLAKE_H(gt->i915) || IS_ARROWLAKE_U(gt->i915))
min_ver = (struct intel_uc_fw_ver){ 102, 1, 15, 1926 };
if (IS_METEORLAKE(gt->i915) && gsc->release.major != 102) {
gt_info(gt, "Invalid GSC firmware for MTL/ARL, got %d.%d.%d.%d but need 102.x.x.x",
gsc->release.major, gsc->release.minor,
gsc->release.patch, gsc->release.build);
return -EINVAL;
}
if (min_ver.major) {
bool too_old = false; bool too_old = false;
/* if (gsc->release.minor < min_ver.minor) {
* ARL requires a newer firmware than MTL did (102.0.10.1878) but the
* firmware is actually common. So, need to do an explicit version check
* here rather than using a separate table entry. And if the older
* MTL-only version is found, then just don't use GSC rather than aborting
* the driver load.
*/
if (gsc->release.major < 102) {
too_old = true; too_old = true;
} else if (gsc->release.major == 102) { } else if (gsc->release.minor == min_ver.minor) {
if (gsc->release.minor == 0) { if (gsc->release.patch < min_ver.patch) {
if (gsc->release.patch < 10) { too_old = true;
} else if (gsc->release.patch == min_ver.patch) {
if (gsc->release.build < min_ver.build)
too_old = true; too_old = true;
} else if (gsc->release.patch == 10) {
if (gsc->release.build < 1878)
too_old = true;
}
} }
} }
if (too_old) { if (too_old) {
gt_info(gt, "GSC firmware too old for ARL, got %d.%d.%d.%d but need at least 102.0.10.1878", gt_info(gt, "GSC firmware too old for ARL, got %d.%d.%d.%d but need at least %d.%d.%d.%d",
gsc->release.major, gsc->release.minor, gsc->release.major, gsc->release.minor,
gsc->release.patch, gsc->release.build); gsc->release.patch, gsc->release.build,
min_ver.major, min_ver.minor,
min_ver.patch, min_ver.build);
return -EINVAL; return -EINVAL;
} }
} }

View File

@ -540,8 +540,12 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
#define IS_LUNARLAKE(i915) (0 && i915) #define IS_LUNARLAKE(i915) (0 && i915)
#define IS_BATTLEMAGE(i915) (0 && i915) #define IS_BATTLEMAGE(i915) (0 && i915)
#define IS_ARROWLAKE(i915) \ #define IS_ARROWLAKE_H(i915) \
IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_ARL) IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_ARL_H)
#define IS_ARROWLAKE_U(i915) \
IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_ARL_U)
#define IS_ARROWLAKE_S(i915) \
IS_SUBPLATFORM(i915, INTEL_METEORLAKE, INTEL_SUBPLATFORM_ARL_S)
#define IS_DG2_G10(i915) \ #define IS_DG2_G10(i915) \
IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G10) IS_SUBPLATFORM(i915, INTEL_DG2, INTEL_SUBPLATFORM_G10)
#define IS_DG2_G11(i915) \ #define IS_DG2_G11(i915) \

View File

@ -200,8 +200,16 @@ static const u16 subplatform_g12_ids[] = {
INTEL_DG2_G12_IDS(ID), INTEL_DG2_G12_IDS(ID),
}; };
static const u16 subplatform_arl_ids[] = { static const u16 subplatform_arl_h_ids[] = {
INTEL_ARL_IDS(ID), INTEL_ARL_H_IDS(ID),
};
static const u16 subplatform_arl_u_ids[] = {
INTEL_ARL_U_IDS(ID),
};
static const u16 subplatform_arl_s_ids[] = {
INTEL_ARL_S_IDS(ID),
}; };
static bool find_devid(u16 id, const u16 *p, unsigned int num) static bool find_devid(u16 id, const u16 *p, unsigned int num)
@ -261,9 +269,15 @@ static void intel_device_info_subplatform_init(struct drm_i915_private *i915)
} else if (find_devid(devid, subplatform_g12_ids, } else if (find_devid(devid, subplatform_g12_ids,
ARRAY_SIZE(subplatform_g12_ids))) { ARRAY_SIZE(subplatform_g12_ids))) {
mask = BIT(INTEL_SUBPLATFORM_G12); mask = BIT(INTEL_SUBPLATFORM_G12);
} else if (find_devid(devid, subplatform_arl_ids, } else if (find_devid(devid, subplatform_arl_h_ids,
ARRAY_SIZE(subplatform_arl_ids))) { ARRAY_SIZE(subplatform_arl_h_ids))) {
mask = BIT(INTEL_SUBPLATFORM_ARL); mask = BIT(INTEL_SUBPLATFORM_ARL_H);
} else if (find_devid(devid, subplatform_arl_u_ids,
ARRAY_SIZE(subplatform_arl_u_ids))) {
mask = BIT(INTEL_SUBPLATFORM_ARL_U);
} else if (find_devid(devid, subplatform_arl_s_ids,
ARRAY_SIZE(subplatform_arl_s_ids))) {
mask = BIT(INTEL_SUBPLATFORM_ARL_S);
} }
GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_MASK); GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_MASK);

View File

@ -128,7 +128,9 @@ enum intel_platform {
#define INTEL_SUBPLATFORM_RPLU 2 #define INTEL_SUBPLATFORM_RPLU 2
/* MTL */ /* MTL */
#define INTEL_SUBPLATFORM_ARL 0 #define INTEL_SUBPLATFORM_ARL_H 0
#define INTEL_SUBPLATFORM_ARL_U 1
#define INTEL_SUBPLATFORM_ARL_S 2
enum intel_ppgtt_type { enum intel_ppgtt_type {
INTEL_PPGTT_NONE = I915_GEM_PPGTT_NONE, INTEL_PPGTT_NONE = I915_GEM_PPGTT_NONE,

View File

@ -771,13 +771,24 @@
INTEL_ATS_M150_IDS(MACRO__, ## __VA_ARGS__), \ INTEL_ATS_M150_IDS(MACRO__, ## __VA_ARGS__), \
INTEL_ATS_M75_IDS(MACRO__, ## __VA_ARGS__) INTEL_ATS_M75_IDS(MACRO__, ## __VA_ARGS__)
/* MTL */ /* ARL */
#define INTEL_ARL_IDS(MACRO__, ...) \ #define INTEL_ARL_H_IDS(MACRO__, ...) \
MACRO__(0x7D41, ## __VA_ARGS__), \
MACRO__(0x7D51, ## __VA_ARGS__), \ MACRO__(0x7D51, ## __VA_ARGS__), \
MACRO__(0x7D67, ## __VA_ARGS__), \
MACRO__(0x7DD1, ## __VA_ARGS__) MACRO__(0x7DD1, ## __VA_ARGS__)
#define INTEL_ARL_U_IDS(MACRO__, ...) \
MACRO__(0x7D41, ## __VA_ARGS__) \
#define INTEL_ARL_S_IDS(MACRO__, ...) \
MACRO__(0x7D67, ## __VA_ARGS__), \
MACRO__(0xB640, ## __VA_ARGS__)
#define INTEL_ARL_IDS(MACRO__, ...) \
INTEL_ARL_H_IDS(MACRO__, ## __VA_ARGS__), \
INTEL_ARL_U_IDS(MACRO__, ## __VA_ARGS__), \
INTEL_ARL_S_IDS(MACRO__, ## __VA_ARGS__)
/* MTL */
#define INTEL_MTL_IDS(MACRO__, ...) \ #define INTEL_MTL_IDS(MACRO__, ...) \
INTEL_ARL_IDS(MACRO__, ## __VA_ARGS__), \ INTEL_ARL_IDS(MACRO__, ## __VA_ARGS__), \
MACRO__(0x7D40, ## __VA_ARGS__), \ MACRO__(0x7D40, ## __VA_ARGS__), \