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