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