xref: /linux/drivers/gpu/drm/xe/xe_uc_fw.h (revision bba2c3615bd6cfee7456d1130f2e6b01b3f4e9ba)
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