Merge tag 'pinctrl-v6.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[linux-block.git] / drivers / gpu / drm / xe / xe_uc.c
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 }