xref: /linux/drivers/gpu/drm/xe/xe_uc.c (revision f4cdf7ca9a1fdcca413157df19753f388a5a224e)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5 
6 #include "xe_uc.h"
7 
8 #include "xe_assert.h"
9 #include "xe_device.h"
10 #include "xe_gsc.h"
11 #include "xe_gt.h"
12 #include "xe_gt_printk.h"
13 #include "xe_gt_sriov_vf.h"
14 #include "xe_guc.h"
15 #include "xe_guc_pc.h"
16 #include "xe_guc_rc.h"
17 #include "xe_guc_engine_activity.h"
18 #include "xe_guc_submit.h"
19 #include "xe_huc.h"
20 #include "xe_sriov.h"
21 #include "xe_wopcm.h"
22 
23 static struct xe_gt *
24 uc_to_gt(struct xe_uc *uc)
25 {
26 	return container_of(uc, struct xe_gt, uc);
27 }
28 
29 static struct xe_device *
30 uc_to_xe(struct xe_uc *uc)
31 {
32 	return gt_to_xe(uc_to_gt(uc));
33 }
34 
35 /* Should be called once at driver load only */
36 int xe_uc_init_noalloc(struct xe_uc *uc)
37 {
38 	int ret;
39 
40 	ret = xe_guc_init_noalloc(&uc->guc);
41 	if (ret)
42 		goto err;
43 
44 	/* HuC and GSC have no early dependencies and will be initialized during xe_uc_init(). */
45 	return 0;
46 
47 err:
48 	xe_gt_err(uc_to_gt(uc), "Failed to early initialize uC (%pe)\n", ERR_PTR(ret));
49 	return ret;
50 }
51 
52 int xe_uc_init(struct xe_uc *uc)
53 {
54 	int ret;
55 
56 	/*
57 	 * We call the GuC/HuC/GSC init functions even if GuC submission is off
58 	 * to correctly move our tracking of the FW state to "disabled".
59 	 */
60 	ret = xe_guc_init(&uc->guc);
61 	if (ret)
62 		goto err;
63 
64 	ret = xe_huc_init(&uc->huc);
65 	if (ret)
66 		goto err;
67 
68 	ret = xe_gsc_init(&uc->gsc);
69 	if (ret)
70 		goto err;
71 
72 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
73 		return 0;
74 
75 	if (!IS_SRIOV_VF(uc_to_xe(uc))) {
76 		ret = xe_wopcm_init(&uc->wopcm);
77 		if (ret)
78 			goto err;
79 	}
80 
81 	ret = xe_guc_min_load_for_hwconfig(&uc->guc);
82 	if (ret)
83 		goto err;
84 
85 	return 0;
86 err:
87 	xe_gt_err(uc_to_gt(uc), "Failed to initialize uC (%pe)\n", ERR_PTR(ret));
88 	return ret;
89 }
90 
91 /**
92  * xe_uc_init_post_hwconfig - init Uc post hwconfig load
93  * @uc: The UC object
94  *
95  * Return: 0 on success, negative error code on error.
96  */
97 int xe_uc_init_post_hwconfig(struct xe_uc *uc)
98 {
99 	int err;
100 
101 	/* GuC submission not enabled, nothing to do */
102 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
103 		return 0;
104 
105 	err = xe_uc_sanitize_reset(uc);
106 	if (err)
107 		return err;
108 
109 	err = xe_guc_init_post_hwconfig(&uc->guc);
110 	if (err)
111 		return err;
112 
113 	err = xe_huc_init_post_hwconfig(&uc->huc);
114 	if (err)
115 		return err;
116 
117 	return xe_gsc_init_post_hwconfig(&uc->gsc);
118 }
119 
120 static int uc_reset(struct xe_uc *uc)
121 {
122 	struct xe_device *xe = uc_to_xe(uc);
123 	int ret;
124 
125 	ret = xe_guc_reset(&uc->guc);
126 	if (ret) {
127 		drm_err(&xe->drm, "Failed to reset GuC, ret = %d\n", ret);
128 		return ret;
129 	}
130 
131 	return 0;
132 }
133 
134 static void xe_uc_sanitize(struct xe_uc *uc)
135 {
136 	xe_huc_sanitize(&uc->huc);
137 	xe_guc_sanitize(&uc->guc);
138 }
139 
140 int xe_uc_sanitize_reset(struct xe_uc *uc)
141 {
142 	xe_uc_sanitize(uc);
143 
144 	return uc_reset(uc);
145 }
146 
147 static int vf_uc_load_hw(struct xe_uc *uc)
148 {
149 	int err;
150 
151 	err = xe_uc_sanitize_reset(uc);
152 	if (err)
153 		return err;
154 
155 	err = xe_guc_enable_communication(&uc->guc);
156 	if (err)
157 		return err;
158 
159 	err = xe_gt_sriov_vf_connect(uc_to_gt(uc));
160 	if (err)
161 		return err;
162 
163 	err = xe_guc_opt_in_features_enable(&uc->guc);
164 	if (err)
165 		return err;
166 
167 	err = xe_guc_submit_enable(&uc->guc);
168 	if (err)
169 		return err;
170 
171 	err = xe_gt_record_default_lrcs(uc_to_gt(uc));
172 	if (err)
173 		return err;
174 
175 	return 0;
176 }
177 
178 /*
179  * Should be called during driver load, after every GT reset, and after every
180  * suspend to reload / auth the firmwares.
181  */
182 int xe_uc_load_hw(struct xe_uc *uc)
183 {
184 	int ret;
185 
186 	/* GuC submission not enabled, nothing to do */
187 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
188 		return 0;
189 
190 	if (IS_SRIOV_VF(uc_to_xe(uc)))
191 		return vf_uc_load_hw(uc);
192 
193 	ret = xe_huc_upload(&uc->huc);
194 	if (ret)
195 		return ret;
196 
197 	ret = xe_guc_upload(&uc->guc);
198 	if (ret)
199 		return ret;
200 
201 	ret = xe_guc_enable_communication(&uc->guc);
202 	if (ret)
203 		return ret;
204 
205 	ret = xe_gt_record_default_lrcs(uc_to_gt(uc));
206 	if (ret)
207 		return ret;
208 
209 	ret = xe_guc_post_load_init(&uc->guc);
210 	if (ret)
211 		return ret;
212 
213 	ret = xe_guc_pc_start(&uc->guc.pc);
214 	if (ret)
215 		return ret;
216 
217 	ret = xe_guc_rc_enable(&uc->guc);
218 	if (ret)
219 		return ret;
220 
221 	xe_guc_engine_activity_enable_stats(&uc->guc);
222 
223 	/* We don't fail the driver load if HuC fails to auth */
224 	ret = xe_huc_auth(&uc->huc, XE_HUC_AUTH_VIA_GUC);
225 	if (ret)
226 		xe_gt_err(uc_to_gt(uc),
227 			  "HuC authentication failed (%pe), continuing with no HuC\n",
228 			  ERR_PTR(ret));
229 
230 	/* GSC load is async */
231 	xe_gsc_load_start(&uc->gsc);
232 
233 	return 0;
234 }
235 
236 int xe_uc_reset_prepare(struct xe_uc *uc)
237 {
238 	/* GuC submission not enabled, nothing to do */
239 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
240 		return 0;
241 
242 	return xe_guc_reset_prepare(&uc->guc);
243 }
244 
245 void xe_uc_stop_prepare(struct xe_uc *uc)
246 {
247 	xe_gsc_stop_prepare(&uc->gsc);
248 	xe_guc_stop_prepare(&uc->guc);
249 }
250 
251 void xe_uc_stop(struct xe_uc *uc)
252 {
253 	/* GuC submission not enabled, nothing to do */
254 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
255 		return;
256 
257 	xe_guc_stop(&uc->guc);
258 }
259 
260 int xe_uc_start(struct xe_uc *uc)
261 {
262 	/* GuC submission not enabled, nothing to do */
263 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
264 		return 0;
265 
266 	return xe_guc_start(&uc->guc);
267 }
268 
269 static void uc_reset_wait(struct xe_uc *uc)
270 {
271 	int ret;
272 
273 again:
274 	xe_guc_reset_wait(&uc->guc);
275 
276 	ret = xe_uc_reset_prepare(uc);
277 	if (ret)
278 		goto again;
279 }
280 
281 void xe_uc_suspend_prepare(struct xe_uc *uc)
282 {
283 	xe_gsc_wait_for_worker_completion(&uc->gsc);
284 	xe_guc_stop_prepare(&uc->guc);
285 }
286 
287 int xe_uc_suspend(struct xe_uc *uc)
288 {
289 	/* GuC submission not enabled, nothing to do */
290 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
291 		return 0;
292 
293 	uc_reset_wait(uc);
294 
295 	xe_uc_stop(uc);
296 
297 	return xe_guc_suspend(&uc->guc);
298 }
299 
300 /**
301  * xe_uc_runtime_suspend() - UC runtime suspend
302  * @uc: the UC object
303  *
304  * Runtime suspend all UCs.
305  */
306 void xe_uc_runtime_suspend(struct xe_uc *uc)
307 {
308 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
309 		return;
310 
311 	xe_guc_runtime_suspend(&uc->guc);
312 }
313 
314 /**
315  * xe_uc_runtime_resume() - UC runtime resume
316  * @uc: the UC object
317  *
318  * Runtime resume all UCs.
319  */
320 void xe_uc_runtime_resume(struct xe_uc *uc)
321 {
322 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
323 		return;
324 
325 	xe_guc_runtime_resume(&uc->guc);
326 }
327 
328 /**
329  * xe_uc_declare_wedged() - Declare UC wedged
330  * @uc: the UC object
331  *
332  * Wedge the UC which stops all submission, saves desired debug state, and
333  * cleans up anything which could timeout.
334  */
335 void xe_uc_declare_wedged(struct xe_uc *uc)
336 {
337 	xe_gt_assert(uc_to_gt(uc), uc_to_xe(uc)->wedged.mode);
338 
339 	xe_guc_declare_wedged(&uc->guc);
340 }
341