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_gsc_proxy.h"
12 #include "xe_gt.h"
13 #include "xe_gt_printk.h"
14 #include "xe_gt_sriov_vf.h"
15 #include "xe_guc.h"
16 #include "xe_guc_pc.h"
17 #include "xe_guc_engine_activity.h"
18 #include "xe_huc.h"
19 #include "xe_sriov.h"
20 #include "xe_uc_fw.h"
21 #include "xe_wopcm.h"
22
23 static struct xe_gt *
uc_to_gt(struct xe_uc * uc)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 *
uc_to_xe(struct xe_uc * uc)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 */
xe_uc_init_noalloc(struct xe_uc * uc)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
xe_uc_init(struct xe_uc * uc)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 */
xe_uc_init_post_hwconfig(struct xe_uc * uc)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
uc_reset(struct xe_uc * uc)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
xe_uc_sanitize(struct xe_uc * uc)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
xe_uc_sanitize_reset(struct xe_uc * uc)140 int xe_uc_sanitize_reset(struct xe_uc *uc)
141 {
142 xe_uc_sanitize(uc);
143
144 return uc_reset(uc);
145 }
146
vf_uc_load_hw(struct xe_uc * uc)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 goto err_out;
162
163 uc->guc.submission_state.enabled = true;
164
165 err = xe_guc_opt_in_features_enable(&uc->guc);
166 if (err)
167 goto err_out;
168
169 err = xe_gt_record_default_lrcs(uc_to_gt(uc));
170 if (err)
171 goto err_out;
172
173 return 0;
174
175 err_out:
176 xe_guc_sanitize(&uc->guc);
177 return err;
178 }
179
180 /*
181 * Should be called during driver load, after every GT reset, and after every
182 * suspend to reload / auth the firmwares.
183 */
xe_uc_load_hw(struct xe_uc * uc)184 int xe_uc_load_hw(struct xe_uc *uc)
185 {
186 int ret;
187
188 /* GuC submission not enabled, nothing to do */
189 if (!xe_device_uc_enabled(uc_to_xe(uc)))
190 return 0;
191
192 if (IS_SRIOV_VF(uc_to_xe(uc)))
193 return vf_uc_load_hw(uc);
194
195 ret = xe_huc_upload(&uc->huc);
196 if (ret)
197 return ret;
198
199 ret = xe_guc_upload(&uc->guc);
200 if (ret)
201 return ret;
202
203 ret = xe_guc_enable_communication(&uc->guc);
204 if (ret)
205 return ret;
206
207 ret = xe_gt_record_default_lrcs(uc_to_gt(uc));
208 if (ret)
209 goto err_out;
210
211 ret = xe_guc_post_load_init(&uc->guc);
212 if (ret)
213 goto err_out;
214
215 ret = xe_guc_pc_start(&uc->guc.pc);
216 if (ret)
217 goto err_out;
218
219 xe_guc_engine_activity_enable_stats(&uc->guc);
220
221 /* We don't fail the driver load if HuC fails to auth, but let's warn */
222 ret = xe_huc_auth(&uc->huc, XE_HUC_AUTH_VIA_GUC);
223 xe_gt_assert(uc_to_gt(uc), !ret);
224
225 /* GSC load is async */
226 xe_gsc_load_start(&uc->gsc);
227
228 return 0;
229
230 err_out:
231 xe_guc_sanitize(&uc->guc);
232 return ret;
233 }
234
xe_uc_reset_prepare(struct xe_uc * uc)235 int xe_uc_reset_prepare(struct xe_uc *uc)
236 {
237 /* GuC submission not enabled, nothing to do */
238 if (!xe_device_uc_enabled(uc_to_xe(uc)))
239 return 0;
240
241 return xe_guc_reset_prepare(&uc->guc);
242 }
243
xe_uc_gucrc_disable(struct xe_uc * uc)244 void xe_uc_gucrc_disable(struct xe_uc *uc)
245 {
246 XE_WARN_ON(xe_guc_pc_gucrc_disable(&uc->guc.pc));
247 }
248
xe_uc_stop_prepare(struct xe_uc * uc)249 void xe_uc_stop_prepare(struct xe_uc *uc)
250 {
251 xe_gsc_stop_prepare(&uc->gsc);
252 xe_guc_stop_prepare(&uc->guc);
253 }
254
xe_uc_stop(struct xe_uc * uc)255 void xe_uc_stop(struct xe_uc *uc)
256 {
257 /* GuC submission not enabled, nothing to do */
258 if (!xe_device_uc_enabled(uc_to_xe(uc)))
259 return;
260
261 xe_guc_stop(&uc->guc);
262 }
263
xe_uc_start(struct xe_uc * uc)264 int xe_uc_start(struct xe_uc *uc)
265 {
266 /* GuC submission not enabled, nothing to do */
267 if (!xe_device_uc_enabled(uc_to_xe(uc)))
268 return 0;
269
270 return xe_guc_start(&uc->guc);
271 }
272
uc_reset_wait(struct xe_uc * uc)273 static void uc_reset_wait(struct xe_uc *uc)
274 {
275 int ret;
276
277 again:
278 xe_guc_reset_wait(&uc->guc);
279
280 ret = xe_uc_reset_prepare(uc);
281 if (ret)
282 goto again;
283 }
284
xe_uc_suspend_prepare(struct xe_uc * uc)285 void xe_uc_suspend_prepare(struct xe_uc *uc)
286 {
287 xe_gsc_wait_for_worker_completion(&uc->gsc);
288 xe_guc_stop_prepare(&uc->guc);
289 }
290
xe_uc_suspend(struct xe_uc * uc)291 int xe_uc_suspend(struct xe_uc *uc)
292 {
293 /* GuC submission not enabled, nothing to do */
294 if (!xe_device_uc_enabled(uc_to_xe(uc)))
295 return 0;
296
297 uc_reset_wait(uc);
298
299 xe_uc_stop(uc);
300
301 return xe_guc_suspend(&uc->guc);
302 }
303
304 /**
305 * xe_uc_declare_wedged() - Declare UC wedged
306 * @uc: the UC object
307 *
308 * Wedge the UC which stops all submission, saves desired debug state, and
309 * cleans up anything which could timeout.
310 */
xe_uc_declare_wedged(struct xe_uc * uc)311 void xe_uc_declare_wedged(struct xe_uc *uc)
312 {
313 xe_gt_assert(uc_to_gt(uc), uc_to_xe(uc)->wedged.mode);
314
315 xe_guc_declare_wedged(&uc->guc);
316 }
317