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