+#define uc_fw_entry_no_ver(dir_, uc_, shortname_)
\
+ { fw_filename_no_ver(dir_, uc_, shortname_),
\
+ 0, 0 }
+
+/* All blobs need to be declared via MODULE_FIRMWARE() */
+#define XE_UC_MODULE_FIRMWARE(platform__, fw_filename)
\
+ MODULE_FIRMWARE(fw_filename);
+
+#define XE_UC_FW_ENTRY(platform__, entry__)
\
+ {
\
+ .platform = XE_ ## platform__,
\
+ entry__,
\
+ },
+
+XE_GUC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE,
\
+ fw_filename_mmp_ver, fw_filename_major_ver)
+XE_HUC_FIRMWARE_DEFS(XE_UC_MODULE_FIRMWARE,
\
+ fw_filename_mmp_ver, fw_filename_no_ver)
+
static struct xe_gt *
__uc_fw_to_gt(struct xe_uc_fw *uc_fw, enum xe_uc_fw_type type) { @@ -
37,123 +168,38 @@ static struct xe_device *uc_fw_to_xe(struct xe_uc_fw
*uc_fw)
return gt_to_xe(uc_fw_to_gt(uc_fw));
}
-/*
- * List of required GuC and HuC binaries per-platform.
- * Must be ordered based on platform, from newer to older.
- */
-#define XE_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
- fw_def(METEORLAKE, guc_def(mtl, 70, 5, 2)) \
- fw_def(PVC, guc_def(pvc, 70, 5, 2)) \
- fw_def(ALDERLAKE_P, guc_def(adlp, 70, 5, 2)) \
- fw_def(ALDERLAKE_S, guc_def(tgl, 70, 5, 2)) \
- fw_def(DG2, guc_def(dg2, 70, 5, 2)) \
- fw_def(DG1, guc_def(dg1, 70, 5, 2)) \
- fw_def(TIGERLAKE, guc_def(tgl, 70, 5, 2))
-
-#define XE_HUC_FIRMWARE_DEFS(fw_def, huc_def, huc_ver) \
- fw_def(ALDERLAKE_S, huc_def(tgl)) \
- fw_def(DG1, huc_def(dg1)) \
- fw_def(TIGERLAKE, huc_def(tgl))
-
-#define __MAKE_HUC_FW_PATH(prefix_, name_) \
- "i915/" \
- __stringify(prefix_) "_" name_ ".bin"
-
-#define __MAKE_UC_FW_PATH_MAJOR(prefix_, name_, major_) \
- "i915/" \
- __stringify(prefix_) "_" name_ "_" \
- __stringify(major_) ".bin"
-
-#define __MAKE_UC_FW_PATH_FULL_VER(prefix_, name_, major_, minor_,
patch_) \
- "i915/" \
- __stringify(prefix_) "_" name_ "_" \
- __stringify(major_) "." \
- __stringify(minor_) "." \
- __stringify(patch_) ".bin"
-
-#define MAKE_GUC_FW_PATH(prefix_, major_, minor_, patch_) \
- __MAKE_UC_FW_PATH_MAJOR(prefix_, "guc", major_)
-
-#define MAKE_HUC_FW_PATH(prefix_) \
- __MAKE_HUC_FW_PATH(prefix_, "huc")
-
-#define MAKE_HUC_FW_PATH_FULL_VER(prefix_, major_, minor_, patch_) \
- __MAKE_UC_FW_PATH_FULL_VER(prefix_, "huc", major_, minor_,
patch_)
-
-
-/* All blobs need to be declared via MODULE_FIRMWARE() */ -#define
XE_UC_MODULE_FW(platform_, uc_) \
- MODULE_FIRMWARE(uc_);
-
-XE_GUC_FIRMWARE_DEFS(XE_UC_MODULE_FW, MAKE_GUC_FW_PATH) -
XE_HUC_FIRMWARE_DEFS(XE_UC_MODULE_FW, MAKE_HUC_FW_PATH,
MAKE_HUC_FW_PATH_FULL_VER)
-
-/* The below structs and macros are used to iterate across the list of blobs */ -
struct __packed uc_fw_blob {
- u8 major;
- u8 minor;
- const char *path;
-};
-
-#define UC_FW_BLOB(major_, minor_, path_) \
- { .major = major_, .minor = minor_, .path = path_ }
-
-#define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
- UC_FW_BLOB(major_, minor_, \
- MAKE_GUC_FW_PATH(prefix_, major_, minor_, patch_))
-
-#define HUC_FW_BLOB(prefix_) \
- UC_FW_BLOB(0, 0, MAKE_HUC_FW_PATH(prefix_))
-
-#define HUC_FW_VERSION_BLOB(prefix_, major_, minor_, bld_num_) \
- UC_FW_BLOB(major_, minor_, \
- MAKE_HUC_FW_PATH_FULL_VER(prefix_, major_, minor_,
bld_num_))
-
-struct uc_fw_platform_requirement {
- enum xe_platform p;
- const struct uc_fw_blob blob;
-};
-
-#define MAKE_FW_LIST(platform_, uc_) \
-{ \
- .p = XE_##platform_, \
- .blob = uc_, \
-},
-
-struct fw_blobs_by_type {
- const struct uc_fw_platform_requirement *blobs;
- u32 count;
-};
-
static void
uc_fw_auto_select(struct xe_device *xe, struct xe_uc_fw *uc_fw) {
- static const struct uc_fw_platform_requirement blobs_guc[] = {
- XE_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB)
+ static const struct uc_fw_entry entries_guc[] = {
+ XE_GUC_FIRMWARE_DEFS(XE_UC_FW_ENTRY,
+ uc_fw_entry_mmp_ver,
+ uc_fw_entry_major_ver)
};
- static const struct uc_fw_platform_requirement blobs_huc[] = {
- XE_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB,
HUC_FW_VERSION_BLOB)
+ static const struct uc_fw_entry entries_huc[] = {
+ XE_HUC_FIRMWARE_DEFS(XE_UC_FW_ENTRY,
+ uc_fw_entry_mmp_ver,
+ uc_fw_entry_no_ver)
};
static const struct fw_blobs_by_type
blobs_all[XE_UC_FW_NUM_TYPES] = {
- [XE_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc)
},
- [XE_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc)
},
+ [XE_UC_FW_TYPE_GUC] = { entries_guc,
ARRAY_SIZE(entries_guc) },
+ [XE_UC_FW_TYPE_HUC] = { entries_huc,
ARRAY_SIZE(entries_huc) },
};
- static const struct uc_fw_platform_requirement *fw_blobs;
+ static const struct uc_fw_entry *entries;
enum xe_platform p = xe->info.platform;
- u32 fw_count;
+ u32 count;
int i;
XE_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all));
- fw_blobs = blobs_all[uc_fw->type].blobs;
- fw_count = blobs_all[uc_fw->type].count;
-
- for (i = 0; i < fw_count && p <= fw_blobs[i].p; i++) {
- if (p == fw_blobs[i].p) {
- const struct uc_fw_blob *blob = &fw_blobs[i].blob;
-
- uc_fw->path = blob->path;
- uc_fw->major_ver_wanted = blob->major;
- uc_fw->minor_ver_wanted = blob->minor;
+ entries = blobs_all[uc_fw->type].entries;
+ count = blobs_all[uc_fw->type].count;
+
+ for (i = 0; i < count && p <= entries[i].platform; i++) {
+ if (p == entries[i].platform) {
+ uc_fw->path = entries[i].path;
+ uc_fw->major_ver_wanted = entries[i].major;
+ uc_fw->minor_ver_wanted = entries[i].minor;
+ uc_fw->full_ver_required = entries[i].full_ver_required;
break;
}
}
@@ -227,6 +273,47 @@ static void guc_read_css_info(struct xe_uc_fw *uc_fw,
struct uc_css_header *css)
uc_fw->private_data_size = css->private_data_size; }
+static int uc_fw_check_version_requirements(struct xe_uc_fw *uc_fw) {
+ struct xe_device *xe = uc_fw_to_xe(uc_fw);
+
+ /* Driver has no requirement on any version, any is good. */
+ if (!uc_fw->major_ver_wanted)
+ return 0;
+
+ /*
+ * If full version is required, both major and minor should match.
+ * Otherwise, at least the major version.
+ */
+ if (uc_fw->major_ver_wanted != uc_fw->major_ver_found ||
+ (uc_fw->full_ver_required &&
+ uc_fw->minor_ver_wanted != uc_fw->minor_ver_found)) {
+ drm_notice(&xe->drm, "%s firmware %s: unexpected version:
%u.%u != %u.%u\n",
+ xe_uc_fw_type_repr(uc_fw->type), uc_fw->path,
+ uc_fw->major_ver_found, uc_fw->minor_ver_found,
+ uc_fw->major_ver_wanted, uc_fw-
>minor_ver_wanted);
+ goto fail;
+ }
+
+ if (uc_fw->minor_ver_wanted > uc_fw->minor_ver_found) {
+ drm_notice(&xe->drm, "%s firmware (%u.%u) is recommended,
but only (%u.%u) was found in %s\n",
+ xe_uc_fw_type_repr(uc_fw->type),
+ uc_fw->major_ver_wanted, uc_fw-
>minor_ver_wanted,
+ uc_fw->major_ver_found, uc_fw->minor_ver_found,
+ uc_fw->path);
+ drm_info(&xe->drm, "Consider updating your linux-firmware
pkg or downloading from %s\n",
+ XE_UC_FIRMWARE_URL);
+ }
+
+ return 0;
+
+fail:
+ if (xe_uc_fw_is_overridden(uc_fw))
+ return 0;
+
+ return -ENOEXEC;
+}
+
int xe_uc_fw_init(struct xe_uc_fw *uc_fw) {
struct xe_device *xe = uc_fw_to_xe(uc_fw); @@ -308,19 +395,9 @@
int xe_uc_fw_init(struct xe_uc_fw *uc_fw)
uc_fw->minor_ver_found = FIELD_GET(CSS_SW_VERSION_UC_MINOR,
css->sw_version);
- if (uc_fw->major_ver_wanted) {
- if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
- uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
- drm_notice(&xe->drm, "%s firmware %s: unexpected
version: %u.%u != %u.%u\n",
- xe_uc_fw_type_repr(uc_fw->type), uc_fw-
>path,
- uc_fw->major_ver_found, uc_fw-
>minor_ver_found,
- uc_fw->major_ver_wanted, uc_fw-
>minor_ver_wanted);
- if (!xe_uc_fw_is_overridden(uc_fw)) {
- err = -ENOEXEC;
- goto fail;
- }
- }
- }
+ err = uc_fw_check_version_requirements(uc_fw);
+ if (err)
+ goto fail;
if (uc_fw->type == XE_UC_FW_TYPE_GUC)
guc_read_css_info(uc_fw, css);
diff --git a/drivers/gpu/drm/xe/xe_uc_fw.h b/drivers/gpu/drm/xe/xe_uc_fw.h
index bf31c3bb0e0f..e16267e71280 100644
--- a/drivers/gpu/drm/xe/xe_uc_fw.h
+++ b/drivers/gpu/drm/xe/xe_uc_fw.h
@@ -175,6 +175,6 @@ static inline u32 xe_uc_fw_get_upload_size(struct
xe_uc_fw *uc_fw)
return __xe_uc_fw_get_upload_size(uc_fw);
}
-#define XE_UC_FIRMWARE_URL
"https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-
firmware.git/tree/i915"
+#define XE_UC_FIRMWARE_URL
"https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git"
#endif
diff --git a/drivers/gpu/drm/xe/xe_uc_fw_types.h
b/drivers/gpu/drm/xe/xe_uc_fw_types.h
index 1cfd30a655df..6c595aaa2399 100644
--- a/drivers/gpu/drm/xe/xe_uc_fw_types.h
+++ b/drivers/gpu/drm/xe/xe_uc_fw_types.h
@@ -78,6 +78,13 @@ struct xe_uc_fw {
const char *path;
/** @user_overridden: user provided path to uC firmware via
modparam */
bool user_overridden;
+ /**
+ * @full_version_required: driver still under development and not ready
+ * for backward-compatible firmware. To be used only for **new**
+ * platforms, i.e. still under require_force_probe protection and not
+ * supported by i915.
+ */
+ bool full_ver_required;
/** @size: size of uC firmware including css header */
size_t size;
--
2.39.0