xref: /linux/drivers/gpu/drm/xe/xe_uc.c (revision ea34704d6ad7225421cc3543906deacae35a6ea2)
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(struct xe_uc * uc)36 int xe_uc_init(struct xe_uc *uc)
37 {
38 	int ret;
39 
40 	/*
41 	 * We call the GuC/HuC/GSC init functions even if GuC submission is off
42 	 * to correctly move our tracking of the FW state to "disabled".
43 	 */
44 	ret = xe_guc_init(&uc->guc);
45 	if (ret)
46 		goto err;
47 
48 	ret = xe_huc_init(&uc->huc);
49 	if (ret)
50 		goto err;
51 
52 	ret = xe_gsc_init(&uc->gsc);
53 	if (ret)
54 		goto err;
55 
56 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
57 		return 0;
58 
59 	if (IS_SRIOV_VF(uc_to_xe(uc)))
60 		return 0;
61 
62 	ret = xe_wopcm_init(&uc->wopcm);
63 	if (ret)
64 		goto err;
65 
66 	return 0;
67 
68 err:
69 	xe_gt_err(uc_to_gt(uc), "Failed to initialize uC (%pe)\n", ERR_PTR(ret));
70 	return ret;
71 }
72 
73 /**
74  * xe_uc_init_post_hwconfig - init Uc post hwconfig load
75  * @uc: The UC object
76  *
77  * Return: 0 on success, negative error code on error.
78  */
xe_uc_init_post_hwconfig(struct xe_uc * uc)79 int xe_uc_init_post_hwconfig(struct xe_uc *uc)
80 {
81 	int err;
82 
83 	/* GuC submission not enabled, nothing to do */
84 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
85 		return 0;
86 
87 	err = xe_uc_sanitize_reset(uc);
88 	if (err)
89 		return err;
90 
91 	err = xe_guc_init_post_hwconfig(&uc->guc);
92 	if (err)
93 		return err;
94 
95 	err = xe_huc_init_post_hwconfig(&uc->huc);
96 	if (err)
97 		return err;
98 
99 	return xe_gsc_init_post_hwconfig(&uc->gsc);
100 }
101 
uc_reset(struct xe_uc * uc)102 static int uc_reset(struct xe_uc *uc)
103 {
104 	struct xe_device *xe = uc_to_xe(uc);
105 	int ret;
106 
107 	ret = xe_guc_reset(&uc->guc);
108 	if (ret) {
109 		drm_err(&xe->drm, "Failed to reset GuC, ret = %d\n", ret);
110 		return ret;
111 	}
112 
113 	return 0;
114 }
115 
xe_uc_sanitize(struct xe_uc * uc)116 static void xe_uc_sanitize(struct xe_uc *uc)
117 {
118 	xe_huc_sanitize(&uc->huc);
119 	xe_guc_sanitize(&uc->guc);
120 }
121 
xe_uc_sanitize_reset(struct xe_uc * uc)122 int xe_uc_sanitize_reset(struct xe_uc *uc)
123 {
124 	xe_uc_sanitize(uc);
125 
126 	return uc_reset(uc);
127 }
128 
129 /**
130  * xe_uc_init_hwconfig - minimally init Uc, read and parse hwconfig
131  * @uc: The UC object
132  *
133  * Return: 0 on success, negative error code on error.
134  */
xe_uc_init_hwconfig(struct xe_uc * uc)135 int xe_uc_init_hwconfig(struct xe_uc *uc)
136 {
137 	int ret;
138 
139 	/* GuC submission not enabled, nothing to do */
140 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
141 		return 0;
142 
143 	ret = xe_guc_min_load_for_hwconfig(&uc->guc);
144 	if (ret)
145 		return ret;
146 
147 	return 0;
148 }
149 
vf_uc_init_hw(struct xe_uc * uc)150 static int vf_uc_init_hw(struct xe_uc *uc)
151 {
152 	int err;
153 
154 	err = xe_uc_sanitize_reset(uc);
155 	if (err)
156 		return err;
157 
158 	err = xe_guc_enable_communication(&uc->guc);
159 	if (err)
160 		return err;
161 
162 	err = xe_gt_sriov_vf_connect(uc_to_gt(uc));
163 	if (err)
164 		return err;
165 
166 	uc->guc.submission_state.enabled = true;
167 
168 	err = xe_gt_record_default_lrcs(uc_to_gt(uc));
169 	if (err)
170 		return err;
171 
172 	return 0;
173 }
174 
175 /*
176  * Should be called during driver load, after every GT reset, and after every
177  * suspend to reload / auth the firmwares.
178  */
xe_uc_init_hw(struct xe_uc * uc)179 int xe_uc_init_hw(struct xe_uc *uc)
180 {
181 	int ret;
182 
183 	/* GuC submission not enabled, nothing to do */
184 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
185 		return 0;
186 
187 	if (IS_SRIOV_VF(uc_to_xe(uc)))
188 		return vf_uc_init_hw(uc);
189 
190 	ret = xe_huc_upload(&uc->huc);
191 	if (ret)
192 		return ret;
193 
194 	ret = xe_guc_upload(&uc->guc);
195 	if (ret)
196 		return ret;
197 
198 	ret = xe_guc_enable_communication(&uc->guc);
199 	if (ret)
200 		return ret;
201 
202 	ret = xe_gt_record_default_lrcs(uc_to_gt(uc));
203 	if (ret)
204 		return ret;
205 
206 	ret = xe_guc_post_load_init(&uc->guc);
207 	if (ret)
208 		return ret;
209 
210 	ret = xe_guc_pc_start(&uc->guc.pc);
211 	if (ret)
212 		return ret;
213 
214 	xe_guc_engine_activity_enable_stats(&uc->guc);
215 
216 	/* We don't fail the driver load if HuC fails to auth, but let's warn */
217 	ret = xe_huc_auth(&uc->huc, XE_HUC_AUTH_VIA_GUC);
218 	xe_gt_assert(uc_to_gt(uc), !ret);
219 
220 	/* GSC load is async */
221 	xe_gsc_load_start(&uc->gsc);
222 
223 	return 0;
224 }
225 
xe_uc_fini_hw(struct xe_uc * uc)226 int xe_uc_fini_hw(struct xe_uc *uc)
227 {
228 	return xe_uc_sanitize_reset(uc);
229 }
230 
xe_uc_reset_prepare(struct xe_uc * uc)231 int xe_uc_reset_prepare(struct xe_uc *uc)
232 {
233 	/* GuC submission not enabled, nothing to do */
234 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
235 		return 0;
236 
237 	return xe_guc_reset_prepare(&uc->guc);
238 }
239 
xe_uc_gucrc_disable(struct xe_uc * uc)240 void xe_uc_gucrc_disable(struct xe_uc *uc)
241 {
242 	XE_WARN_ON(xe_guc_pc_gucrc_disable(&uc->guc.pc));
243 }
244 
xe_uc_stop_prepare(struct xe_uc * uc)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 
xe_uc_stop(struct xe_uc * uc)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 
xe_uc_start(struct xe_uc * uc)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 
uc_reset_wait(struct xe_uc * uc)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 
xe_uc_suspend_prepare(struct xe_uc * uc)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 
xe_uc_suspend(struct xe_uc * uc)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_declare_wedged() - Declare UC wedged
302  * @uc: the UC object
303  *
304  * Wedge the UC which stops all submission, saves desired debug state, and
305  * cleans up anything which could timeout.
306  */
xe_uc_declare_wedged(struct xe_uc * uc)307 void xe_uc_declare_wedged(struct xe_uc *uc)
308 {
309 	xe_gt_assert(uc_to_gt(uc), uc_to_xe(uc)->wedged.mode);
310 
311 	xe_guc_declare_wedged(&uc->guc);
312 }
313