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