Lines Matching +full:version +full:- +full:major

1 // SPDX-License-Identifier: MIT
7 #include <linux/fault-inject.h>
27 * List of required GuC and HuC binaries per-platform. They must be ordered
31 * Documentation/driver-api/firmware/firmware-usage-guidelines.rst. There is a
34 * driver (under force-probe), use the mmp_ver(): the firmware autoselect logic
36 * "mpp version", i.e. major.minor.patch. mmp_ver() should only be used for
40 * ever contains the major version (GuC) or no version at all (HuC).
43 * The major version needs to match a major version supported by the driver (if
44 * any). The minor version is also checked and a notice emitted to the log if
45 * the version found is smaller than the version wanted. This is done only for
51 * 1) Platform officially supported by i915 - using Tigerlake as example.
54 * - i915/tgl_guc_<major>.bin
55 * - i915/tgl_huc.bin
57 * <major> number for GuC is checked that it matches the version inside
58 * the blob. <minor> version is checked and if smaller than the expected
62 * "wipplat" as a short-name. Driver loads the following firmware blobs
65 * - xe/wipplat_guc_<major>.<minor>.<patch>.bin
66 * - xe/wipplat_huc_<major>.<minor>.<patch>.bin
68 * <major> and <minor> are checked that they match the version inside
72 * 3) Platform officially supported by xe and out of force-probe. Using
73 * "plat" as a short-name. Except for the different directory, the
77 * - xe/plat_guc_<major>.bin
78 * - xe/plat_huc.bin
80 * <major> number for GuC is checked that it matches the version inside
81 * the blob. <minor> version is checked and if smaller than the expected
84 * For the platforms already released with a major version, they should never be
88 * TODO: Currently there's no fallback on major version. That's because xe
89 * driver only supports the one major version of each firmware in the table.
90 * This needs to be fixed when the major version of GuC is updated.
97 u16 major; member
131 /* for the GSC FW we match the compatibility version and not the release one */
196 return __uc_fw_to_gt(uc_fw, uc_fw->type); in uc_fw_to_gt()
226 enum xe_platform p = xe->info.platform; in uc_fw_auto_select()
230 xe_assert(xe, uc_fw->type < ARRAY_SIZE(blobs_all)); in uc_fw_auto_select()
231 entries = blobs_all[uc_fw->type].entries; in uc_fw_auto_select()
232 count = blobs_all[uc_fw->type].count; in uc_fw_auto_select()
236 uc_fw->path = entries[i].path; in uc_fw_auto_select()
237 uc_fw->versions.wanted.major = entries[i].major; in uc_fw_auto_select()
238 uc_fw->versions.wanted.minor = entries[i].minor; in uc_fw_auto_select()
239 uc_fw->versions.wanted.patch = entries[i].patch; in uc_fw_auto_select()
240 uc_fw->full_ver_required = entries[i].full_ver_required; in uc_fw_auto_select()
242 if (uc_fw->type == XE_UC_FW_TYPE_GSC) in uc_fw_auto_select()
243 uc_fw->versions.wanted_type = XE_UC_FW_VER_COMPATIBILITY; in uc_fw_auto_select()
245 uc_fw->versions.wanted_type = XE_UC_FW_VER_RELEASE; in uc_fw_auto_select()
258 switch (uc_fw->type) { in uc_fw_override()
274 uc_fw->path = path_override; in uc_fw_override()
275 uc_fw->user_overridden = true; in uc_fw_override()
280 * xe_uc_fw_copy_rsa - copy fw RSA to buffer
291 u32 size = min_t(u32, uc_fw->rsa_size, max_len); in xe_uc_fw_copy_rsa()
296 xe_map_memcpy_from(xe, dst, &uc_fw->bo->vmap, in xe_uc_fw_copy_rsa()
315 struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE]; in guc_read_css_info()
316 struct xe_uc_fw_version *compatibility = &uc_fw->versions.found[XE_UC_FW_VER_COMPATIBILITY]; in guc_read_css_info()
318 xe_gt_assert(gt, uc_fw->type == XE_UC_FW_TYPE_GUC); in guc_read_css_info()
323 release->major, release->minor, release->patch); in guc_read_css_info()
324 return -EINVAL; in guc_read_css_info()
327 compatibility->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css->submission_version); in guc_read_css_info()
328 compatibility->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css->submission_version); in guc_read_css_info()
329 compatibility->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css->submission_version); in guc_read_css_info()
331 uc_fw->private_data_size = css->private_data_size; in guc_read_css_info()
339 struct xe_uc_fw_version *wanted = &uc_fw->versions.wanted; in xe_uc_fw_check_version_requirements()
340 struct xe_uc_fw_version *found = &uc_fw->versions.found[uc_fw->versions.wanted_type]; in xe_uc_fw_check_version_requirements()
342 /* Driver has no requirement on any version, any is good. */ in xe_uc_fw_check_version_requirements()
343 if (!wanted->major) in xe_uc_fw_check_version_requirements()
347 * If full version is required, both major and minor should match. in xe_uc_fw_check_version_requirements()
348 * Otherwise, at least the major version. in xe_uc_fw_check_version_requirements()
350 if (wanted->major != found->major || in xe_uc_fw_check_version_requirements()
351 (uc_fw->full_ver_required && in xe_uc_fw_check_version_requirements()
352 ((wanted->minor != found->minor) || in xe_uc_fw_check_version_requirements()
353 (wanted->patch != found->patch)))) { in xe_uc_fw_check_version_requirements()
354 drm_notice(&xe->drm, "%s firmware %s: unexpected version: %u.%u.%u != %u.%u.%u\n", in xe_uc_fw_check_version_requirements()
355 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, in xe_uc_fw_check_version_requirements()
356 found->major, found->minor, found->patch, in xe_uc_fw_check_version_requirements()
357 wanted->major, wanted->minor, wanted->patch); in xe_uc_fw_check_version_requirements()
361 if (wanted->minor > found->minor || in xe_uc_fw_check_version_requirements()
362 (wanted->minor == found->minor && wanted->patch > found->patch)) { in xe_uc_fw_check_version_requirements()
363 …drm_notice(&xe->drm, "%s firmware (%u.%u.%u) is recommended, but only (%u.%u.%u) was found in %s\n… in xe_uc_fw_check_version_requirements()
364 xe_uc_fw_type_repr(uc_fw->type), in xe_uc_fw_check_version_requirements()
365 wanted->major, wanted->minor, wanted->patch, in xe_uc_fw_check_version_requirements()
366 found->major, found->minor, found->patch, in xe_uc_fw_check_version_requirements()
367 uc_fw->path); in xe_uc_fw_check_version_requirements()
368 drm_info(&xe->drm, "Consider updating your linux-firmware pkg or downloading from %s\n", in xe_uc_fw_check_version_requirements()
378 return -ENOEXEC; in xe_uc_fw_check_version_requirements()
381 /* Refer to the "CSS-based Firmware Layout" documentation entry for details */
385 struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE]; in parse_css_header()
391 drm_warn(&xe->drm, "%s firmware %s: invalid size: %zu < %zu\n", in parse_css_header()
392 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, in parse_css_header()
394 return -ENODATA; in parse_css_header()
400 size = (css->header_size_dw - css->key_size_dw - css->modulus_size_dw - in parse_css_header()
401 css->exponent_size_dw) * sizeof(u32); in parse_css_header()
403 drm_warn(&xe->drm, in parse_css_header()
405 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, in parse_css_header()
407 return -EPROTO; in parse_css_header()
411 uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32); in parse_css_header()
414 uc_fw->rsa_size = css->key_size_dw * sizeof(u32); in parse_css_header()
417 size = sizeof(struct uc_css_header) + uc_fw->ucode_size + in parse_css_header()
418 uc_fw->rsa_size; in parse_css_header()
420 drm_warn(&xe->drm, "%s firmware %s: invalid size: %zu < %zu\n", in parse_css_header()
421 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, in parse_css_header()
423 return -ENOEXEC; in parse_css_header()
426 /* Get version numbers from the CSS header */ in parse_css_header()
427 release->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css->sw_version); in parse_css_header()
428 release->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css->sw_version); in parse_css_header()
429 release->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css->sw_version); in parse_css_header()
431 if (uc_fw->type == XE_UC_FW_TYPE_GUC) in parse_css_header()
449 entry = (void *)header + header->header_length; in entry_offset()
451 for (i = 0; i < header->num_of_entries; i++, entry++) in entry_offset()
452 if (strcmp(entry->name, name) == 0) in entry_offset()
453 return entry->offset & GSC_CPD_ENTRY_OFFSET_MASK; in entry_offset()
458 /* Refer to the "GSC-based Firmware Layout" documentation entry for details */
465 struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE]; in parse_cpd_header()
474 return -ENOENT; in parse_cpd_header()
476 if (header->header_length < sizeof(struct gsc_cpd_header_v2)) { in parse_cpd_header()
477 xe_gt_err(gt, "invalid CPD header length %u!\n", header->header_length); in parse_cpd_header()
478 return -EINVAL; in parse_cpd_header()
481 min_size = header->header_length + sizeof(struct gsc_cpd_entry) * header->num_of_entries; in parse_cpd_header()
484 return -ENODATA; in parse_cpd_header()
491 xe_uc_fw_type_repr(uc_fw->type)); in parse_cpd_header()
492 return -ENODATA; in parse_cpd_header()
498 return -ENODATA; in parse_cpd_header()
503 release->major = manifest->fw_version.major; in parse_cpd_header()
504 release->minor = manifest->fw_version.minor; in parse_cpd_header()
505 release->patch = manifest->fw_version.hotfix; in parse_cpd_header()
507 if (uc_fw->type == XE_UC_FW_TYPE_GSC) { in parse_cpd_header()
510 release->build = manifest->fw_version.build; in parse_cpd_header()
511 gsc->security_version = manifest->security_version; in parse_cpd_header()
523 xe_assert(xe, xe->info.platform != XE_DG2); in parse_cpd_header()
530 return -ENODATA; in parse_cpd_header()
533 ret = parse_css_header(uc_fw, data + offset, size - offset); in parse_cpd_header()
537 uc_fw->css_offset = offset; in parse_cpd_header()
540 uc_fw->has_gsc_headers = true; in parse_cpd_header()
556 return -ENODATA; in parse_gsc_layout()
559 min_size = layout->boot1.offset + layout->boot1.size; in parse_gsc_layout()
563 return -ENODATA; in parse_gsc_layout()
567 if (layout->boot1.size < min_size) { in parse_gsc_layout()
569 layout->boot1.size, min_size); in parse_gsc_layout()
570 return -ENODATA; in parse_gsc_layout()
573 bpdt_header = data + layout->boot1.offset; in parse_gsc_layout()
574 if (bpdt_header->signature != GSC_BPDT_HEADER_SIGNATURE) { in parse_gsc_layout()
576 bpdt_header->signature); in parse_gsc_layout()
577 return -EINVAL; in parse_gsc_layout()
580 min_size += sizeof(*bpdt_entry) * bpdt_header->descriptor_count; in parse_gsc_layout()
581 if (layout->boot1.size < min_size) { in parse_gsc_layout()
583 layout->boot1.size, min_size); in parse_gsc_layout()
584 return -ENODATA; in parse_gsc_layout()
588 for (i = 0; i < bpdt_header->descriptor_count; i++, bpdt_entry++) { in parse_gsc_layout()
589 if ((bpdt_entry->type & GSC_BPDT_ENTRY_TYPE_MASK) != in parse_gsc_layout()
593 min_size = bpdt_entry->sub_partition_offset; in parse_gsc_layout()
596 if (layout->boot1.size < min_size) { in parse_gsc_layout()
598 layout->boot1.size, min_size); in parse_gsc_layout()
599 return -ENODATA; in parse_gsc_layout()
604 layout->boot1.size - min_size, in parse_gsc_layout()
609 return -ENODATA; in parse_gsc_layout()
620 switch (uc_fw->type) { in parse_headers()
622 return parse_gsc_layout(uc_fw, fw->data, fw->size); in parse_headers()
624 ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", "huc_fw"); in parse_headers()
625 if (!ret || ret != -ENOENT) in parse_headers()
629 return parse_css_header(uc_fw, fw->data, fw->size); in parse_headers()
631 return -EINVAL; in parse_headers()
640 if (ver_->build) \
641 drm_printf(p_, prefix_ " version %u.%u.%u.%u\n", ##__VA_ARGS__, \
642 ver_->major, ver_->minor, \
643 ver_->patch, ver_->build); \
645 drm_printf(p_, prefix_ " version %u.%u.%u\n", ##__VA_ARGS__, \
646 ver_->major, ver_->minor, ver_->patch); \
652 struct device *dev = xe->drm.dev; in uc_fw_request()
658 * we use FIRMWARE_UNINITIALIZED to detect checks against uc_fw->status in uc_fw_request()
662 xe_assert(xe, !uc_fw->status); in uc_fw_request()
663 xe_assert(xe, !uc_fw->path); in uc_fw_request()
669 if (uc_fw->type != XE_UC_FW_TYPE_GUC && in uc_fw_request()
670 uc_fw->type != XE_UC_FW_TYPE_HUC) in uc_fw_request()
671 uc_fw->path = NULL; in uc_fw_request()
673 xe_uc_fw_change_status(uc_fw, uc_fw->path ? in uc_fw_request()
681 xe_uc_fw_change_status(uc_fw, uc_fw->path ? in uc_fw_request()
686 if (uc_fw->type == XE_UC_FW_TYPE_GUC) { in uc_fw_request()
687 drm_err(&xe->drm, "No GuC firmware defined for platform\n"); in uc_fw_request()
688 return -ENOENT; in uc_fw_request()
694 if (!xe_device_uc_enabled(xe) || !(*uc_fw->path)) { in uc_fw_request()
696 drm_dbg(&xe->drm, "%s disabled", xe_uc_fw_type_repr(uc_fw->type)); in uc_fw_request()
700 err = request_firmware(&fw, uc_fw->path, dev); in uc_fw_request()
709 &uc_fw->versions.found[XE_UC_FW_VER_RELEASE], in uc_fw_request()
711 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path); in uc_fw_request()
713 /* for GSC FW we want the compatibility version, which we query after load */ in uc_fw_request()
714 if (uc_fw->type != XE_UC_FW_TYPE_GSC) { in uc_fw_request()
725 xe_uc_fw_change_status(uc_fw, err == -ENOENT ? in uc_fw_request()
729 drm_notice(&xe->drm, "%s firmware %s: fetch failed with error %d\n", in uc_fw_request()
730 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, err); in uc_fw_request()
731 drm_info(&xe->drm, "%s firmware(s) can be downloaded from %s\n", in uc_fw_request()
732 xe_uc_fw_type_repr(uc_fw->type), XE_UC_FIRMWARE_URL); in uc_fw_request()
754 drm_notice(&xe->drm, "%s firmware %s: failed to create / populate bo", in uc_fw_copy()
755 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path); in uc_fw_copy()
760 uc_fw->bo = obj; in uc_fw_copy()
761 uc_fw->size = size; in uc_fw_copy()
765 err = drmm_add_action_or_reset(&xe->drm, uc_fw_fini, uc_fw); in uc_fw_copy()
773 drm_notice(&xe->drm, "%s firmware %s: copy failed with error %d\n", in uc_fw_copy()
774 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, err); in uc_fw_copy()
792 err = uc_fw_copy(uc_fw, fw->data, fw->size, in xe_uc_fw_init()
804 return xe_bo_ggtt_addr(uc_fw->bo); in uc_fw_ggtt_offset()
811 struct xe_mmio *mmio = &gt->mmio; in uc_fw_xfer()
819 src_offset = uc_fw_ggtt_offset(uc_fw) + uc_fw->css_offset; in uc_fw_xfer()
833 sizeof(struct uc_css_header) + uc_fw->ucode_size); in uc_fw_xfer()
843 drm_err(&xe->drm, "DMA for %s fw failed, DMA_CTRL=%u\n", in uc_fw_xfer()
844 xe_uc_fw_type_repr(uc_fw->type), dma_ctrl); in uc_fw_xfer()
861 return -ENOEXEC; in xe_uc_fw_upload()
872 drm_err(&xe->drm, "Failed to load %s firmware %s (%d)\n", in xe_uc_fw_upload()
873 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, in xe_uc_fw_upload()
887 return "Unknown version type"; in version_type_repr()
896 xe_uc_fw_type_repr(uc_fw->type), uc_fw->path); in xe_uc_fw_print()
898 xe_uc_fw_status_repr(uc_fw->status)); in xe_uc_fw_print()
900 print_uc_fw_version(p, &uc_fw->versions.wanted, "\twanted %s", in xe_uc_fw_print()
901 version_type_repr(uc_fw->versions.wanted_type)); in xe_uc_fw_print()
904 struct xe_uc_fw_version *ver = &uc_fw->versions.found[i]; in xe_uc_fw_print()
906 if (ver->major) in xe_uc_fw_print()
911 if (uc_fw->ucode_size) in xe_uc_fw_print()
912 drm_printf(p, "\tuCode: %u bytes\n", uc_fw->ucode_size); in xe_uc_fw_print()
913 if (uc_fw->rsa_size) in xe_uc_fw_print()
914 drm_printf(p, "\tRSA: %u bytes\n", uc_fw->rsa_size); in xe_uc_fw_print()