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