Branch data Line data Source code
1 : : /* SPDX-License-Identifier: MIT */ 2 : : /* 3 : : * Copyright © 2014-2019 Intel Corporation 4 : : */ 5 : : 6 : : #ifndef _INTEL_UC_FW_H_ 7 : : #define _INTEL_UC_FW_H_ 8 : : 9 : : #include <linux/types.h> 10 : : #include "intel_uc_fw_abi.h" 11 : : #include "intel_device_info.h" 12 : : #include "i915_gem.h" 13 : : 14 : : struct drm_printer; 15 : : struct drm_i915_private; 16 : : struct intel_gt; 17 : : 18 : : /* Home of GuC, HuC and DMC firmwares */ 19 : : #define INTEL_UC_FIRMWARE_URL "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/i915" 20 : : 21 : : /* 22 : : * +------------+---------------------------------------------------+ 23 : : * | PHASE | FIRMWARE STATUS TRANSITIONS | 24 : : * +============+===================================================+ 25 : : * | | UNINITIALIZED | 26 : : * +------------+- / | \ -+ 27 : : * | | DISABLED <--/ | \--> NOT_SUPPORTED | 28 : : * | init_early | V | 29 : : * | | SELECTED | 30 : : * +------------+- / | \ -+ 31 : : * | | MISSING <--/ | \--> ERROR | 32 : : * | fetch | | | 33 : : * | | /------> AVAILABLE <---<-----------\ | 34 : : * +------------+- \ / \ \ \ -+ 35 : : * | | FAIL <--< \--> TRANSFERRED \ | 36 : : * | upload | \ / \ / | 37 : : * | | \---------/ \--> RUNNING | 38 : : * +------------+---------------------------------------------------+ 39 : : */ 40 : : 41 : : enum intel_uc_fw_status { 42 : : INTEL_UC_FIRMWARE_NOT_SUPPORTED = -1, /* no uc HW */ 43 : : INTEL_UC_FIRMWARE_UNINITIALIZED = 0, /* used to catch checks done too early */ 44 : : INTEL_UC_FIRMWARE_DISABLED, /* disabled */ 45 : : INTEL_UC_FIRMWARE_SELECTED, /* selected the blob we want to load */ 46 : : INTEL_UC_FIRMWARE_MISSING, /* blob not found on the system */ 47 : : INTEL_UC_FIRMWARE_ERROR, /* invalid format or version */ 48 : : INTEL_UC_FIRMWARE_AVAILABLE, /* blob found and copied in mem */ 49 : : INTEL_UC_FIRMWARE_FAIL, /* failed to xfer or init/auth the fw */ 50 : : INTEL_UC_FIRMWARE_TRANSFERRED, /* dma xfer done */ 51 : : INTEL_UC_FIRMWARE_RUNNING /* init/auth done */ 52 : : }; 53 : : 54 : : enum intel_uc_fw_type { 55 : : INTEL_UC_FW_TYPE_GUC = 0, 56 : : INTEL_UC_FW_TYPE_HUC 57 : : }; 58 : : #define INTEL_UC_FW_NUM_TYPES 2 59 : : 60 : : /* 61 : : * This structure encapsulates all the data needed during the process 62 : : * of fetching, caching, and loading the firmware image into the uC. 63 : : */ 64 : : struct intel_uc_fw { 65 : : enum intel_uc_fw_type type; 66 : : union { 67 : : const enum intel_uc_fw_status status; 68 : : enum intel_uc_fw_status __status; /* no accidental overwrites */ 69 : : }; 70 : : const char *path; 71 : : bool user_overridden; 72 : : size_t size; 73 : : struct drm_i915_gem_object *obj; 74 : : 75 : : /* 76 : : * The firmware build process will generate a version header file with major and 77 : : * minor version defined. The versions are built into CSS header of firmware. 78 : : * i915 kernel driver set the minimal firmware version required per platform. 79 : : */ 80 : : u16 major_ver_wanted; 81 : : u16 minor_ver_wanted; 82 : : u16 major_ver_found; 83 : : u16 minor_ver_found; 84 : : 85 : : u32 rsa_size; 86 : : u32 ucode_size; 87 : : }; 88 : : 89 : : #ifdef CONFIG_DRM_I915_DEBUG_GUC 90 : : void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw, 91 : : enum intel_uc_fw_status status); 92 : : #else 93 : 0 : static inline void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw, 94 : : enum intel_uc_fw_status status) 95 : : { 96 [ # # # ]: 0 : uc_fw->__status = status; 97 : 0 : } 98 : : #endif 99 : : 100 : : static inline 101 : 0 : const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status) 102 : : { 103 [ # # ]: 0 : switch (status) { 104 : : case INTEL_UC_FIRMWARE_NOT_SUPPORTED: 105 : : return "N/A"; 106 : : case INTEL_UC_FIRMWARE_UNINITIALIZED: 107 : : return "UNINITIALIZED"; 108 : : case INTEL_UC_FIRMWARE_DISABLED: 109 : : return "DISABLED"; 110 : : case INTEL_UC_FIRMWARE_SELECTED: 111 : : return "SELECTED"; 112 : : case INTEL_UC_FIRMWARE_MISSING: 113 : : return "MISSING"; 114 : : case INTEL_UC_FIRMWARE_ERROR: 115 : : return "ERROR"; 116 : : case INTEL_UC_FIRMWARE_AVAILABLE: 117 : : return "AVAILABLE"; 118 : : case INTEL_UC_FIRMWARE_FAIL: 119 : : return "FAIL"; 120 : : case INTEL_UC_FIRMWARE_TRANSFERRED: 121 : : return "TRANSFERRED"; 122 : : case INTEL_UC_FIRMWARE_RUNNING: 123 : : return "RUNNING"; 124 : : } 125 : : return "<invalid>"; 126 : : } 127 : : 128 : 0 : static inline int intel_uc_fw_status_to_error(enum intel_uc_fw_status status) 129 : : { 130 [ # # ]: 0 : switch (status) { 131 : : case INTEL_UC_FIRMWARE_NOT_SUPPORTED: 132 : : return -ENODEV; 133 : : case INTEL_UC_FIRMWARE_UNINITIALIZED: 134 : : return -EACCES; 135 : : case INTEL_UC_FIRMWARE_DISABLED: 136 : : return -EPERM; 137 : : case INTEL_UC_FIRMWARE_MISSING: 138 : : return -ENOENT; 139 : : case INTEL_UC_FIRMWARE_ERROR: 140 : : return -ENOEXEC; 141 : : case INTEL_UC_FIRMWARE_FAIL: 142 : : return -EIO; 143 : : case INTEL_UC_FIRMWARE_SELECTED: 144 : : return -ESTALE; 145 : : case INTEL_UC_FIRMWARE_AVAILABLE: 146 : : case INTEL_UC_FIRMWARE_TRANSFERRED: 147 : : case INTEL_UC_FIRMWARE_RUNNING: 148 : : return 0; 149 : : } 150 : : return -EINVAL; 151 : : } 152 : : 153 : 0 : static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type type) 154 : : { 155 [ # # # # : 0 : switch (type) { # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ] 156 : : case INTEL_UC_FW_TYPE_GUC: 157 : : return "GuC"; 158 : 0 : case INTEL_UC_FW_TYPE_HUC: 159 : 0 : return "HuC"; 160 : : } 161 : 0 : return "uC"; 162 : : } 163 : : 164 : : static inline enum intel_uc_fw_status 165 : 0 : __intel_uc_fw_status(struct intel_uc_fw *uc_fw) 166 : : { 167 : : /* shouldn't call this before checking hw/blob availability */ 168 : 0 : GEM_BUG_ON(uc_fw->status == INTEL_UC_FIRMWARE_UNINITIALIZED); 169 : 0 : return uc_fw->status; 170 : : } 171 : : 172 : 0 : static inline bool intel_uc_fw_is_supported(struct intel_uc_fw *uc_fw) 173 : : { 174 [ # # # # : 0 : return __intel_uc_fw_status(uc_fw) != INTEL_UC_FIRMWARE_NOT_SUPPORTED; # # # # ] 175 : : } 176 : : 177 : 0 : static inline bool intel_uc_fw_is_enabled(struct intel_uc_fw *uc_fw) 178 : : { 179 [ # # # # : 0 : return __intel_uc_fw_status(uc_fw) > INTEL_UC_FIRMWARE_DISABLED; # # # # # # # # # # ] 180 : : } 181 : : 182 : 0 : static inline bool intel_uc_fw_is_available(struct intel_uc_fw *uc_fw) 183 : : { 184 [ # # # # : 0 : return __intel_uc_fw_status(uc_fw) >= INTEL_UC_FIRMWARE_AVAILABLE; # # # # ] 185 : : } 186 : : 187 : 0 : static inline bool intel_uc_fw_is_loaded(struct intel_uc_fw *uc_fw) 188 : : { 189 [ # # ]: 0 : return __intel_uc_fw_status(uc_fw) >= INTEL_UC_FIRMWARE_TRANSFERRED; 190 : : } 191 : : 192 : 0 : static inline bool intel_uc_fw_is_running(struct intel_uc_fw *uc_fw) 193 : : { 194 [ # # # # : 0 : return __intel_uc_fw_status(uc_fw) == INTEL_UC_FIRMWARE_RUNNING; # # # # # # # # ] 195 : : } 196 : : 197 : 0 : static inline bool intel_uc_fw_is_overridden(const struct intel_uc_fw *uc_fw) 198 : : { 199 [ # # ]: 0 : return uc_fw->user_overridden; 200 : : } 201 : : 202 : 0 : static inline void intel_uc_fw_sanitize(struct intel_uc_fw *uc_fw) 203 : : { 204 [ # # # # : 0 : if (intel_uc_fw_is_loaded(uc_fw)) # # # # ] 205 : 0 : intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_AVAILABLE); 206 : : } 207 : : 208 : 0 : static inline u32 __intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw) 209 : : { 210 [ # # ]: 0 : return sizeof(struct uc_css_header) + uc_fw->ucode_size; 211 : : } 212 : : 213 : : /** 214 : : * intel_uc_fw_get_upload_size() - Get size of firmware needed to be uploaded. 215 : : * @uc_fw: uC firmware. 216 : : * 217 : : * Get the size of the firmware and header that will be uploaded to WOPCM. 218 : : * 219 : : * Return: Upload firmware size, or zero on firmware fetch failure. 220 : : */ 221 : 0 : static inline u32 intel_uc_fw_get_upload_size(struct intel_uc_fw *uc_fw) 222 : : { 223 [ # # # # ]: 0 : if (!intel_uc_fw_is_available(uc_fw)) 224 : : return 0; 225 : : 226 : 0 : return __intel_uc_fw_get_upload_size(uc_fw); 227 : : } 228 : : 229 : : void intel_uc_fw_init_early(struct intel_uc_fw *uc_fw, 230 : : enum intel_uc_fw_type type, bool supported, 231 : : enum intel_platform platform, u8 rev); 232 : : int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw); 233 : : void intel_uc_fw_cleanup_fetch(struct intel_uc_fw *uc_fw); 234 : : int intel_uc_fw_upload(struct intel_uc_fw *uc_fw, u32 offset, u32 dma_flags); 235 : : int intel_uc_fw_init(struct intel_uc_fw *uc_fw); 236 : : void intel_uc_fw_fini(struct intel_uc_fw *uc_fw); 237 : : size_t intel_uc_fw_copy_rsa(struct intel_uc_fw *uc_fw, void *dst, u32 max_len); 238 : : void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct drm_printer *p); 239 : : 240 : : #endif