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}