1dd08ebf6SMatthew Brost /* SPDX-License-Identifier: MIT */ 2dd08ebf6SMatthew Brost /* 3dd08ebf6SMatthew Brost * Copyright © 2022 Intel Corporation 4dd08ebf6SMatthew Brost */ 5dd08ebf6SMatthew Brost 6dd08ebf6SMatthew Brost #ifndef _XE_UC_FW_H_ 7dd08ebf6SMatthew Brost #define _XE_UC_FW_H_ 8dd08ebf6SMatthew Brost 9dd08ebf6SMatthew Brost #include <linux/errno.h> 10dd08ebf6SMatthew Brost 11dd08ebf6SMatthew Brost #include "xe_macros.h" 12ea9f879dSLucas De Marchi #include "xe_uc_fw_abi.h" 13ea9f879dSLucas De Marchi #include "xe_uc_fw_types.h" 14dd08ebf6SMatthew Brost 15dd08ebf6SMatthew Brost struct drm_printer; 16dd08ebf6SMatthew Brost 17dd08ebf6SMatthew Brost int xe_uc_fw_init(struct xe_uc_fw *uc_fw); 18dd08ebf6SMatthew Brost size_t xe_uc_fw_copy_rsa(struct xe_uc_fw *uc_fw, void *dst, u32 max_len); 19dd08ebf6SMatthew Brost int xe_uc_fw_upload(struct xe_uc_fw *uc_fw, u32 offset, u32 dma_flags); 200881cbe0SDaniele Ceraolo Spurio int xe_uc_fw_check_version_requirements(struct xe_uc_fw *uc_fw); 21dd08ebf6SMatthew Brost void xe_uc_fw_print(struct xe_uc_fw *uc_fw, struct drm_printer *p); 22dd08ebf6SMatthew Brost xe_uc_fw_rsa_offset(struct xe_uc_fw * uc_fw)23dd08ebf6SMatthew Broststatic inline u32 xe_uc_fw_rsa_offset(struct xe_uc_fw *uc_fw) 24dd08ebf6SMatthew Brost { 25484ecffaSDaniele Ceraolo Spurio return sizeof(struct uc_css_header) + uc_fw->ucode_size + uc_fw->css_offset; 26dd08ebf6SMatthew Brost } 27dd08ebf6SMatthew Brost xe_uc_fw_change_status(struct xe_uc_fw * uc_fw,enum xe_uc_fw_status status)28dd08ebf6SMatthew Broststatic inline void xe_uc_fw_change_status(struct xe_uc_fw *uc_fw, 29dd08ebf6SMatthew Brost enum xe_uc_fw_status status) 30dd08ebf6SMatthew Brost { 31dd08ebf6SMatthew Brost uc_fw->__status = status; 32dd08ebf6SMatthew Brost } 33dd08ebf6SMatthew Brost 34dd08ebf6SMatthew Brost static inline xe_uc_fw_status_repr(enum xe_uc_fw_status status)35dd08ebf6SMatthew Brostconst char *xe_uc_fw_status_repr(enum xe_uc_fw_status status) 36dd08ebf6SMatthew Brost { 37dd08ebf6SMatthew Brost switch (status) { 38dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_NOT_SUPPORTED: 39dd08ebf6SMatthew Brost return "N/A"; 40dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_UNINITIALIZED: 41dd08ebf6SMatthew Brost return "UNINITIALIZED"; 42dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_DISABLED: 43dd08ebf6SMatthew Brost return "DISABLED"; 44dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_SELECTED: 45dd08ebf6SMatthew Brost return "SELECTED"; 46dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_MISSING: 47dd08ebf6SMatthew Brost return "MISSING"; 48dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_ERROR: 49dd08ebf6SMatthew Brost return "ERROR"; 50dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_AVAILABLE: 51dd08ebf6SMatthew Brost return "AVAILABLE"; 52dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_INIT_FAIL: 53dd08ebf6SMatthew Brost return "INIT FAIL"; 54dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_LOADABLE: 55dd08ebf6SMatthew Brost return "LOADABLE"; 56dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_LOAD_FAIL: 57dd08ebf6SMatthew Brost return "LOAD FAIL"; 58dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_TRANSFERRED: 59dd08ebf6SMatthew Brost return "TRANSFERRED"; 60dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_RUNNING: 61dd08ebf6SMatthew Brost return "RUNNING"; 6266cb3ca9SMichal Wajdeczko case XE_UC_FIRMWARE_PRELOADED: 6366cb3ca9SMichal Wajdeczko return "PRELOADED"; 64dd08ebf6SMatthew Brost } 65dd08ebf6SMatthew Brost return "<invalid>"; 66dd08ebf6SMatthew Brost } 67dd08ebf6SMatthew Brost xe_uc_fw_status_to_error(const enum xe_uc_fw_status status)68*529bf8d1SDaniele Ceraolo Spuriostatic inline int xe_uc_fw_status_to_error(const enum xe_uc_fw_status status) 69dd08ebf6SMatthew Brost { 70dd08ebf6SMatthew Brost switch (status) { 71dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_NOT_SUPPORTED: 72dd08ebf6SMatthew Brost return -ENODEV; 73dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_UNINITIALIZED: 74dd08ebf6SMatthew Brost return -EACCES; 75dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_DISABLED: 76dd08ebf6SMatthew Brost return -EPERM; 77dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_MISSING: 78dd08ebf6SMatthew Brost return -ENOENT; 79dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_ERROR: 80dd08ebf6SMatthew Brost return -ENOEXEC; 81dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_INIT_FAIL: 82dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_LOAD_FAIL: 83dd08ebf6SMatthew Brost return -EIO; 84dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_SELECTED: 85dd08ebf6SMatthew Brost return -ESTALE; 86dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_AVAILABLE: 87dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_LOADABLE: 88dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_TRANSFERRED: 89dd08ebf6SMatthew Brost case XE_UC_FIRMWARE_RUNNING: 9066cb3ca9SMichal Wajdeczko case XE_UC_FIRMWARE_PRELOADED: 91dd08ebf6SMatthew Brost return 0; 92dd08ebf6SMatthew Brost } 93dd08ebf6SMatthew Brost return -EINVAL; 94dd08ebf6SMatthew Brost } 95dd08ebf6SMatthew Brost xe_uc_fw_type_repr(enum xe_uc_fw_type type)96dd08ebf6SMatthew Broststatic inline const char *xe_uc_fw_type_repr(enum xe_uc_fw_type type) 97dd08ebf6SMatthew Brost { 98dd08ebf6SMatthew Brost switch (type) { 99dd08ebf6SMatthew Brost case XE_UC_FW_TYPE_GUC: 100dd08ebf6SMatthew Brost return "GuC"; 101dd08ebf6SMatthew Brost case XE_UC_FW_TYPE_HUC: 102dd08ebf6SMatthew Brost return "HuC"; 1030d1caff4SDaniele Ceraolo Spurio case XE_UC_FW_TYPE_GSC: 1040d1caff4SDaniele Ceraolo Spurio return "GSC"; 1050d1caff4SDaniele Ceraolo Spurio default: 106dd08ebf6SMatthew Brost return "uC"; 107dd08ebf6SMatthew Brost } 1080d1caff4SDaniele Ceraolo Spurio } 109dd08ebf6SMatthew Brost 110dd08ebf6SMatthew Brost static inline enum xe_uc_fw_status __xe_uc_fw_status(const struct xe_uc_fw * uc_fw)111*529bf8d1SDaniele Ceraolo Spurio__xe_uc_fw_status(const struct xe_uc_fw *uc_fw) 112dd08ebf6SMatthew Brost { 113dd08ebf6SMatthew Brost /* shouldn't call this before checking hw/blob availability */ 11499fea682SFrancois Dugast XE_WARN_ON(uc_fw->status == XE_UC_FIRMWARE_UNINITIALIZED); 115dd08ebf6SMatthew Brost return uc_fw->status; 116dd08ebf6SMatthew Brost } 117dd08ebf6SMatthew Brost xe_uc_fw_is_supported(struct xe_uc_fw * uc_fw)118dd08ebf6SMatthew Broststatic inline bool xe_uc_fw_is_supported(struct xe_uc_fw *uc_fw) 119dd08ebf6SMatthew Brost { 120dd08ebf6SMatthew Brost return __xe_uc_fw_status(uc_fw) != XE_UC_FIRMWARE_NOT_SUPPORTED; 121dd08ebf6SMatthew Brost } 122dd08ebf6SMatthew Brost xe_uc_fw_is_enabled(struct xe_uc_fw * uc_fw)123dd08ebf6SMatthew Broststatic inline bool xe_uc_fw_is_enabled(struct xe_uc_fw *uc_fw) 124dd08ebf6SMatthew Brost { 125dd08ebf6SMatthew Brost return __xe_uc_fw_status(uc_fw) > XE_UC_FIRMWARE_DISABLED; 126dd08ebf6SMatthew Brost } 127dd08ebf6SMatthew Brost xe_uc_fw_is_disabled(struct xe_uc_fw * uc_fw)128dd08ebf6SMatthew Broststatic inline bool xe_uc_fw_is_disabled(struct xe_uc_fw *uc_fw) 129dd08ebf6SMatthew Brost { 130dd08ebf6SMatthew Brost return __xe_uc_fw_status(uc_fw) == XE_UC_FIRMWARE_DISABLED; 131dd08ebf6SMatthew Brost } 132dd08ebf6SMatthew Brost xe_uc_fw_is_available(struct xe_uc_fw * uc_fw)133dd08ebf6SMatthew Broststatic inline bool xe_uc_fw_is_available(struct xe_uc_fw *uc_fw) 134dd08ebf6SMatthew Brost { 135dd08ebf6SMatthew Brost return __xe_uc_fw_status(uc_fw) >= XE_UC_FIRMWARE_AVAILABLE; 136dd08ebf6SMatthew Brost } 137dd08ebf6SMatthew Brost xe_uc_fw_is_loadable(struct xe_uc_fw * uc_fw)138dd08ebf6SMatthew Broststatic inline bool xe_uc_fw_is_loadable(struct xe_uc_fw *uc_fw) 139dd08ebf6SMatthew Brost { 14066cb3ca9SMichal Wajdeczko return __xe_uc_fw_status(uc_fw) >= XE_UC_FIRMWARE_LOADABLE && 14166cb3ca9SMichal Wajdeczko __xe_uc_fw_status(uc_fw) != XE_UC_FIRMWARE_PRELOADED; 142dd08ebf6SMatthew Brost } 143dd08ebf6SMatthew Brost xe_uc_fw_is_loaded(struct xe_uc_fw * uc_fw)144dd08ebf6SMatthew Broststatic inline bool xe_uc_fw_is_loaded(struct xe_uc_fw *uc_fw) 145dd08ebf6SMatthew Brost { 146dd08ebf6SMatthew Brost return __xe_uc_fw_status(uc_fw) >= XE_UC_FIRMWARE_TRANSFERRED; 147dd08ebf6SMatthew Brost } 148dd08ebf6SMatthew Brost xe_uc_fw_is_running(struct xe_uc_fw * uc_fw)149dd08ebf6SMatthew Broststatic inline bool xe_uc_fw_is_running(struct xe_uc_fw *uc_fw) 150dd08ebf6SMatthew Brost { 15166cb3ca9SMichal Wajdeczko return __xe_uc_fw_status(uc_fw) >= XE_UC_FIRMWARE_RUNNING; 152dd08ebf6SMatthew Brost } 153dd08ebf6SMatthew Brost xe_uc_fw_is_overridden(const struct xe_uc_fw * uc_fw)154dd08ebf6SMatthew Broststatic inline bool xe_uc_fw_is_overridden(const struct xe_uc_fw *uc_fw) 155dd08ebf6SMatthew Brost { 156dd08ebf6SMatthew Brost return uc_fw->user_overridden; 157dd08ebf6SMatthew Brost } 158dd08ebf6SMatthew Brost xe_uc_fw_is_in_error_state(const struct xe_uc_fw * uc_fw)159*529bf8d1SDaniele Ceraolo Spuriostatic inline bool xe_uc_fw_is_in_error_state(const struct xe_uc_fw *uc_fw) 160*529bf8d1SDaniele Ceraolo Spurio { 161*529bf8d1SDaniele Ceraolo Spurio return xe_uc_fw_status_to_error(__xe_uc_fw_status(uc_fw)) < 0; 162*529bf8d1SDaniele Ceraolo Spurio } 163*529bf8d1SDaniele Ceraolo Spurio xe_uc_fw_sanitize(struct xe_uc_fw * uc_fw)164dd08ebf6SMatthew Broststatic inline void xe_uc_fw_sanitize(struct xe_uc_fw *uc_fw) 165dd08ebf6SMatthew Brost { 1660d2ca8fdSMichal Wajdeczko if (xe_uc_fw_is_loadable(uc_fw)) 167dd08ebf6SMatthew Brost xe_uc_fw_change_status(uc_fw, XE_UC_FIRMWARE_LOADABLE); 168dd08ebf6SMatthew Brost } 169dd08ebf6SMatthew Brost __xe_uc_fw_get_upload_size(struct xe_uc_fw * uc_fw)170dd08ebf6SMatthew Broststatic inline u32 __xe_uc_fw_get_upload_size(struct xe_uc_fw *uc_fw) 171dd08ebf6SMatthew Brost { 172dd08ebf6SMatthew Brost return sizeof(struct uc_css_header) + uc_fw->ucode_size; 173dd08ebf6SMatthew Brost } 174dd08ebf6SMatthew Brost 175dd08ebf6SMatthew Brost /** 176dd08ebf6SMatthew Brost * xe_uc_fw_get_upload_size() - Get size of firmware needed to be uploaded. 177dd08ebf6SMatthew Brost * @uc_fw: uC firmware. 178dd08ebf6SMatthew Brost * 179dd08ebf6SMatthew Brost * Get the size of the firmware and header that will be uploaded to WOPCM. 180dd08ebf6SMatthew Brost * 181dd08ebf6SMatthew Brost * Return: Upload firmware size, or zero on firmware fetch failure. 182dd08ebf6SMatthew Brost */ xe_uc_fw_get_upload_size(struct xe_uc_fw * uc_fw)183dd08ebf6SMatthew Broststatic inline u32 xe_uc_fw_get_upload_size(struct xe_uc_fw *uc_fw) 184dd08ebf6SMatthew Brost { 185dd08ebf6SMatthew Brost if (!xe_uc_fw_is_available(uc_fw)) 186dd08ebf6SMatthew Brost return 0; 187dd08ebf6SMatthew Brost 188dd08ebf6SMatthew Brost return __xe_uc_fw_get_upload_size(uc_fw); 189dd08ebf6SMatthew Brost } 190dd08ebf6SMatthew Brost 191ad55ead7SLucas De Marchi #define XE_UC_FIRMWARE_URL "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git" 192dd08ebf6SMatthew Brost 193dd08ebf6SMatthew Brost #endif 194