xref: /linux/drivers/gpu/drm/xe/xe_uc.c (revision 1f20a5769446a1acae67ac9e63d07a594829a789)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5 
6 #include "xe_uc.h"
7 
8 #include "xe_device.h"
9 #include "xe_gsc.h"
10 #include "xe_gsc_proxy.h"
11 #include "xe_gt.h"
12 #include "xe_guc.h"
13 #include "xe_guc_db_mgr.h"
14 #include "xe_guc_pc.h"
15 #include "xe_guc_submit.h"
16 #include "xe_huc.h"
17 #include "xe_uc_fw.h"
18 #include "xe_wopcm.h"
19 
20 static struct xe_gt *
21 uc_to_gt(struct xe_uc *uc)
22 {
23 	return container_of(uc, struct xe_gt, uc);
24 }
25 
26 static struct xe_device *
27 uc_to_xe(struct xe_uc *uc)
28 {
29 	return gt_to_xe(uc_to_gt(uc));
30 }
31 
32 /* Should be called once at driver load only */
33 int xe_uc_init(struct xe_uc *uc)
34 {
35 	struct xe_device *xe = uc_to_xe(uc);
36 	int ret;
37 
38 	xe_device_mem_access_get(xe);
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 		goto err;
58 
59 	ret = xe_wopcm_init(&uc->wopcm);
60 	if (ret)
61 		goto err;
62 
63 	ret = xe_guc_submit_init(&uc->guc);
64 	if (ret)
65 		goto err;
66 
67 	ret = xe_guc_db_mgr_init(&uc->guc.dbm, ~0);
68 	if (ret)
69 		goto err;
70 
71 	xe_device_mem_access_put(xe);
72 
73 	return 0;
74 
75 err:
76 	xe_device_mem_access_put(xe);
77 
78 	return ret;
79 }
80 
81 /**
82  * xe_uc_init_post_hwconfig - init Uc post hwconfig load
83  * @uc: The UC object
84  *
85  * Return: 0 on success, negative error code on error.
86  */
87 int xe_uc_init_post_hwconfig(struct xe_uc *uc)
88 {
89 	int err;
90 
91 	/* GuC submission not enabled, nothing to do */
92 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
93 		return 0;
94 
95 	err = xe_uc_sanitize_reset(uc);
96 	if (err)
97 		return err;
98 
99 	err = xe_guc_init_post_hwconfig(&uc->guc);
100 	if (err)
101 		return err;
102 
103 	err = xe_huc_init_post_hwconfig(&uc->huc);
104 	if (err)
105 		return err;
106 
107 	return xe_gsc_init_post_hwconfig(&uc->gsc);
108 }
109 
110 static int uc_reset(struct xe_uc *uc)
111 {
112 	struct xe_device *xe = uc_to_xe(uc);
113 	int ret;
114 
115 	ret = xe_guc_reset(&uc->guc);
116 	if (ret) {
117 		drm_err(&xe->drm, "Failed to reset GuC, ret = %d\n", ret);
118 		return ret;
119 	}
120 
121 	return 0;
122 }
123 
124 static void xe_uc_sanitize(struct xe_uc *uc)
125 {
126 	xe_huc_sanitize(&uc->huc);
127 	xe_guc_sanitize(&uc->guc);
128 }
129 
130 int xe_uc_sanitize_reset(struct xe_uc *uc)
131 {
132 	xe_uc_sanitize(uc);
133 
134 	return uc_reset(uc);
135 }
136 
137 /**
138  * xe_uc_init_hwconfig - minimally init Uc, read and parse hwconfig
139  * @uc: The UC object
140  *
141  * Return: 0 on success, negative error code on error.
142  */
143 int xe_uc_init_hwconfig(struct xe_uc *uc)
144 {
145 	int ret;
146 
147 	/* GuC submission not enabled, nothing to do */
148 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
149 		return 0;
150 
151 	ret = xe_guc_min_load_for_hwconfig(&uc->guc);
152 	if (ret)
153 		return ret;
154 
155 	return 0;
156 }
157 
158 /*
159  * Should be called during driver load, after every GT reset, and after every
160  * suspend to reload / auth the firmwares.
161  */
162 int xe_uc_init_hw(struct xe_uc *uc)
163 {
164 	int ret;
165 
166 	/* GuC submission not enabled, nothing to do */
167 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
168 		return 0;
169 
170 	ret = xe_huc_upload(&uc->huc);
171 	if (ret)
172 		return ret;
173 
174 	ret = xe_guc_upload(&uc->guc);
175 	if (ret)
176 		return ret;
177 
178 	ret = xe_guc_enable_communication(&uc->guc);
179 	if (ret)
180 		return ret;
181 
182 	ret = xe_gt_record_default_lrcs(uc_to_gt(uc));
183 	if (ret)
184 		return ret;
185 
186 	ret = xe_guc_post_load_init(&uc->guc);
187 	if (ret)
188 		return ret;
189 
190 	ret = xe_guc_pc_start(&uc->guc.pc);
191 	if (ret)
192 		return ret;
193 
194 	/* We don't fail the driver load if HuC fails to auth, but let's warn */
195 	ret = xe_huc_auth(&uc->huc, XE_HUC_AUTH_VIA_GUC);
196 	xe_gt_assert(uc_to_gt(uc), !ret);
197 
198 	/* GSC load is async */
199 	xe_gsc_load_start(&uc->gsc);
200 
201 	return 0;
202 }
203 
204 int xe_uc_fini_hw(struct xe_uc *uc)
205 {
206 	return xe_uc_sanitize_reset(uc);
207 }
208 
209 int xe_uc_reset_prepare(struct xe_uc *uc)
210 {
211 	/* GuC submission not enabled, nothing to do */
212 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
213 		return 0;
214 
215 	return xe_guc_reset_prepare(&uc->guc);
216 }
217 
218 void xe_uc_gucrc_disable(struct xe_uc *uc)
219 {
220 	XE_WARN_ON(xe_guc_pc_gucrc_disable(&uc->guc.pc));
221 }
222 
223 void xe_uc_stop_prepare(struct xe_uc *uc)
224 {
225 	xe_gsc_wait_for_worker_completion(&uc->gsc);
226 	xe_guc_stop_prepare(&uc->guc);
227 }
228 
229 int xe_uc_stop(struct xe_uc *uc)
230 {
231 	/* GuC submission not enabled, nothing to do */
232 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
233 		return 0;
234 
235 	return xe_guc_stop(&uc->guc);
236 }
237 
238 int xe_uc_start(struct xe_uc *uc)
239 {
240 	/* GuC submission not enabled, nothing to do */
241 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
242 		return 0;
243 
244 	return xe_guc_start(&uc->guc);
245 }
246 
247 static void uc_reset_wait(struct xe_uc *uc)
248 {
249 	int ret;
250 
251 again:
252 	xe_guc_reset_wait(&uc->guc);
253 
254 	ret = xe_uc_reset_prepare(uc);
255 	if (ret)
256 		goto again;
257 }
258 
259 int xe_uc_suspend(struct xe_uc *uc)
260 {
261 	int ret;
262 
263 	/* GuC submission not enabled, nothing to do */
264 	if (!xe_device_uc_enabled(uc_to_xe(uc)))
265 		return 0;
266 
267 	uc_reset_wait(uc);
268 
269 	ret = xe_uc_stop(uc);
270 	if (ret)
271 		return ret;
272 
273 	return xe_guc_suspend(&uc->guc);
274 }
275 
276 /**
277  * xe_uc_remove() - Clean up the UC structures before driver removal
278  * @uc: the UC object
279  *
280  * This function should only act on objects/structures that must be cleaned
281  * before the driver removal callback is complete and therefore can't be
282  * deferred to a drmm action.
283  */
284 void xe_uc_remove(struct xe_uc *uc)
285 {
286 	xe_gsc_remove(&uc->gsc);
287 }
288