File Index
Files and directories
Sign in
FILE

xe_uc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/xe/xe_uc.c C
  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
 23static struct xe_gt *
 24uc_to_gt(struct xe_uc *uc)
 25{
 26	return container_of(uc, struct xe_gt, uc);
 27}
 28
 29static struct xe_device *
 30uc_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 */
 36int 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
 47err:
 48	xe_gt_err(uc_to_gt(uc), "Failed to early initialize uC (%pe)\n", ERR_PTR(ret));
 49	return ret;
 50}
 51
 52int 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;
 86err:
 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 */
 97int 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
120static 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
134static void xe_uc_sanitize(struct xe_uc *uc)
135{
136	xe_huc_sanitize(&uc->huc);
137	xe_guc_sanitize(&uc->guc);
138}
139
140int xe_uc_sanitize_reset(struct xe_uc *uc)
141{
142	xe_uc_sanitize(uc);
143
144	return uc_reset(uc);
145}
146
147static 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
175err_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 */
184int 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
230err_out:
231	xe_guc_sanitize(&uc->guc);
232	return ret;
233}
234
235int 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
244void xe_uc_gucrc_disable(struct xe_uc *uc)
245{
246	XE_WARN_ON(xe_guc_pc_gucrc_disable(&uc->guc.pc));
247}
248
249void 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
255void 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
264int 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
273static void uc_reset_wait(struct xe_uc *uc)
274{
275	int ret;
276
277again:
278	xe_guc_reset_wait(&uc->guc);
279
280	ret = xe_uc_reset_prepare(uc);
281	if (ret)
282		goto again;
283}
284
285void 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
291int 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 */
311void 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}
~/ Read-only file preview.