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