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 
xe_uc_fw_rsa_offset(struct xe_uc_fw * uc_fw)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 
xe_uc_fw_change_status(struct xe_uc_fw * uc_fw,enum xe_uc_fw_status status)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
xe_uc_fw_status_repr(enum xe_uc_fw_status status)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 
xe_uc_fw_status_to_error(const enum xe_uc_fw_status status)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 
xe_uc_fw_type_repr(enum xe_uc_fw_type type)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
__xe_uc_fw_status(const struct xe_uc_fw * uc_fw)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 
xe_uc_fw_is_supported(struct xe_uc_fw * uc_fw)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 
xe_uc_fw_is_enabled(struct xe_uc_fw * uc_fw)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 
xe_uc_fw_is_disabled(struct xe_uc_fw * uc_fw)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 
xe_uc_fw_is_available(struct xe_uc_fw * uc_fw)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 
xe_uc_fw_is_loadable(struct xe_uc_fw * uc_fw)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 
xe_uc_fw_is_loaded(struct xe_uc_fw * uc_fw)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 
xe_uc_fw_is_running(struct xe_uc_fw * uc_fw)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 
xe_uc_fw_is_overridden(const struct xe_uc_fw * uc_fw)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 
xe_uc_fw_is_in_error_state(const struct xe_uc_fw * uc_fw)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 
xe_uc_fw_sanitize(struct xe_uc_fw * uc_fw)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 
__xe_uc_fw_get_upload_size(struct xe_uc_fw * uc_fw)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  */
xe_uc_fw_get_upload_size(struct xe_uc_fw * uc_fw)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