Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  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_gt.h"
 11#include "xe_guc.h"
 12#include "xe_guc_pc.h"
 13#include "xe_guc_submit.h"
 14#include "xe_huc.h"
 15#include "xe_uc_fw.h"
 16#include "xe_wopcm.h"
 17
 18static struct xe_gt *
 19uc_to_gt(struct xe_uc *uc)
 20{
 21	return container_of(uc, struct xe_gt, uc);
 22}
 23
 24static struct xe_device *
 25uc_to_xe(struct xe_uc *uc)
 26{
 27	return gt_to_xe(uc_to_gt(uc));
 28}
 29
 30/* Should be called once at driver load only */
 31int xe_uc_init(struct xe_uc *uc)
 32{
 33	int ret;
 34
 35	/*
 36	 * We call the GuC/HuC/GSC init functions even if GuC submission is off
 37	 * to correctly move our tracking of the FW state to "disabled".
 38	 */
 39
 40	ret = xe_guc_init(&uc->guc);
 41	if (ret)
 42		goto err;
 43
 44	ret = xe_huc_init(&uc->huc);
 45	if (ret)
 46		goto err;
 47
 48	ret = xe_gsc_init(&uc->gsc);
 49	if (ret)
 50		goto err;
 51
 52	if (!xe_device_uc_enabled(uc_to_xe(uc)))
 53		return 0;
 54
 55	ret = xe_wopcm_init(&uc->wopcm);
 56	if (ret)
 57		goto err;
 58
 59	ret = xe_guc_submit_init(&uc->guc);
 60	if (ret)
 61		goto err;
 62
 63	return 0;
 64
 65err:
 66	return ret;
 67}
 68
 69/**
 70 * xe_uc_init_post_hwconfig - init Uc post hwconfig load
 71 * @uc: The UC object
 72 *
 73 * Return: 0 on success, negative error code on error.
 74 */
 75int xe_uc_init_post_hwconfig(struct xe_uc *uc)
 76{
 77	int err;
 78
 79	/* GuC submission not enabled, nothing to do */
 80	if (!xe_device_uc_enabled(uc_to_xe(uc)))
 81		return 0;
 82
 83	err = xe_uc_sanitize_reset(uc);
 84	if (err)
 85		return err;
 86
 87	err = xe_guc_init_post_hwconfig(&uc->guc);
 88	if (err)
 89		return err;
 90
 91	return xe_gsc_init_post_hwconfig(&uc->gsc);
 92}
 93
 94static int uc_reset(struct xe_uc *uc)
 95{
 96	struct xe_device *xe = uc_to_xe(uc);
 97	int ret;
 98
 99	ret = xe_guc_reset(&uc->guc);
100	if (ret) {
101		drm_err(&xe->drm, "Failed to reset GuC, ret = %d\n", ret);
102		return ret;
103	}
104
105	return 0;
106}
107
108static void xe_uc_sanitize(struct xe_uc *uc)
109{
110	xe_huc_sanitize(&uc->huc);
111	xe_guc_sanitize(&uc->guc);
112}
113
114int xe_uc_sanitize_reset(struct xe_uc *uc)
115{
116	xe_uc_sanitize(uc);
117
118	return uc_reset(uc);
119}
120
121/**
122 * xe_uc_init_hwconfig - minimally init Uc, read and parse hwconfig
123 * @uc: The UC object
124 *
125 * Return: 0 on success, negative error code on error.
126 */
127int xe_uc_init_hwconfig(struct xe_uc *uc)
128{
129	int ret;
130
131	/* GuC submission not enabled, nothing to do */
132	if (!xe_device_uc_enabled(uc_to_xe(uc)))
133		return 0;
134
135	ret = xe_guc_min_load_for_hwconfig(&uc->guc);
136	if (ret)
137		return ret;
138
139	return 0;
140}
141
142/*
143 * Should be called during driver load, after every GT reset, and after every
144 * suspend to reload / auth the firmwares.
145 */
146int xe_uc_init_hw(struct xe_uc *uc)
147{
148	int ret;
149
150	/* GuC submission not enabled, nothing to do */
151	if (!xe_device_uc_enabled(uc_to_xe(uc)))
152		return 0;
153
154	ret = xe_huc_upload(&uc->huc);
155	if (ret)
156		return ret;
157
158	ret = xe_guc_upload(&uc->guc);
159	if (ret)
160		return ret;
161
162	ret = xe_guc_enable_communication(&uc->guc);
163	if (ret)
164		return ret;
165
166	ret = xe_gt_record_default_lrcs(uc_to_gt(uc));
167	if (ret)
168		return ret;
169
170	ret = xe_guc_post_load_init(&uc->guc);
171	if (ret)
172		return ret;
173
174	ret = xe_guc_pc_start(&uc->guc.pc);
175	if (ret)
176		return ret;
177
178	/* We don't fail the driver load if HuC fails to auth, but let's warn */
179	ret = xe_huc_auth(&uc->huc, XE_HUC_AUTH_VIA_GUC);
180	xe_gt_assert(uc_to_gt(uc), !ret);
181
182	/* GSC load is async */
183	xe_gsc_load_start(&uc->gsc);
184
185	return 0;
186}
187
188int xe_uc_fini_hw(struct xe_uc *uc)
189{
190	return xe_uc_sanitize_reset(uc);
191}
192
193int xe_uc_reset_prepare(struct xe_uc *uc)
194{
195	/* GuC submission not enabled, nothing to do */
196	if (!xe_device_uc_enabled(uc_to_xe(uc)))
197		return 0;
198
199	return xe_guc_reset_prepare(&uc->guc);
200}
201
202void xe_uc_gucrc_disable(struct xe_uc *uc)
203{
204	XE_WARN_ON(xe_guc_pc_gucrc_disable(&uc->guc.pc));
205}
206
207void xe_uc_stop_prepare(struct xe_uc *uc)
208{
209	xe_gsc_wait_for_worker_completion(&uc->gsc);
210	xe_guc_stop_prepare(&uc->guc);
211}
212
213int xe_uc_stop(struct xe_uc *uc)
214{
215	/* GuC submission not enabled, nothing to do */
216	if (!xe_device_uc_enabled(uc_to_xe(uc)))
217		return 0;
218
219	return xe_guc_stop(&uc->guc);
220}
221
222int xe_uc_start(struct xe_uc *uc)
223{
224	/* GuC submission not enabled, nothing to do */
225	if (!xe_device_uc_enabled(uc_to_xe(uc)))
226		return 0;
227
228	return xe_guc_start(&uc->guc);
229}
230
231static void uc_reset_wait(struct xe_uc *uc)
232{
233	int ret;
234
235again:
236	xe_guc_reset_wait(&uc->guc);
237
238	ret = xe_uc_reset_prepare(uc);
239	if (ret)
240		goto again;
241}
242
243int xe_uc_suspend(struct xe_uc *uc)
244{
245	int ret;
246
247	/* GuC submission not enabled, nothing to do */
248	if (!xe_device_uc_enabled(uc_to_xe(uc)))
249		return 0;
250
251	uc_reset_wait(uc);
252
253	ret = xe_uc_stop(uc);
254	if (ret)
255		return ret;
256
257	return xe_guc_suspend(&uc->guc);
258}