1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "gt/intel_reset.h"
26#include "intel_uc.h"
27#include "intel_guc.h"
28#include "intel_guc_ads.h"
29#include "intel_guc_submission.h"
30#include "i915_drv.h"
31
32static void guc_free_load_err_log(struct intel_guc *guc);
33
34
35
36static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
37{
38 int ret;
39 u32 guc_status;
40
41 ret = intel_reset_guc(dev_priv);
42 if (ret) {
43 DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
44 return ret;
45 }
46
47 guc_status = I915_READ(GUC_STATUS);
48 WARN(!(guc_status & GS_MIA_IN_RESET),
49 "GuC status: 0x%x, MIA core expected to be in reset\n",
50 guc_status);
51
52 return ret;
53}
54
55static int __get_platform_enable_guc(struct drm_i915_private *i915)
56{
57 struct intel_uc_fw *guc_fw = &i915->guc.fw;
58 struct intel_uc_fw *huc_fw = &i915->huc.fw;
59 int enable_guc = 0;
60
61
62 if (intel_uc_fw_is_selected(guc_fw) && intel_uc_fw_is_selected(huc_fw))
63 enable_guc |= ENABLE_GUC_LOAD_HUC;
64
65
66
67 return enable_guc;
68}
69
70static int __get_default_guc_log_level(struct drm_i915_private *i915)
71{
72 int guc_log_level;
73
74 if (!HAS_GUC(i915) || !intel_uc_is_using_guc(i915))
75 guc_log_level = GUC_LOG_LEVEL_DISABLED;
76 else if (IS_ENABLED(CONFIG_DRM_I915_DEBUG) ||
77 IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
78 guc_log_level = GUC_LOG_LEVEL_MAX;
79 else
80 guc_log_level = GUC_LOG_LEVEL_NON_VERBOSE;
81
82
83
84 return guc_log_level;
85}
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104static void sanitize_options_early(struct drm_i915_private *i915)
105{
106 struct intel_uc_fw *guc_fw = &i915->guc.fw;
107 struct intel_uc_fw *huc_fw = &i915->huc.fw;
108
109
110 if (i915_modparams.enable_guc < 0)
111 i915_modparams.enable_guc = __get_platform_enable_guc(i915);
112
113 DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s)\n",
114 i915_modparams.enable_guc,
115 yesno(intel_uc_is_using_guc_submission(i915)),
116 yesno(intel_uc_is_using_huc(i915)));
117
118
119 if (intel_uc_is_using_guc(i915) && !intel_uc_fw_is_selected(guc_fw)) {
120 DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
121 "enable_guc", i915_modparams.enable_guc,
122 !HAS_GUC(i915) ? "no GuC hardware" :
123 "no GuC firmware");
124 }
125
126
127 if (intel_uc_is_using_huc(i915) && !intel_uc_fw_is_selected(huc_fw)) {
128 DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
129 "enable_guc", i915_modparams.enable_guc,
130 !HAS_HUC(i915) ? "no HuC hardware" :
131 "no HuC firmware");
132 }
133
134
135 if (intel_uc_is_using_guc_submission(i915)) {
136 DRM_INFO("Incompatible option detected: %s=%d, %s!\n",
137 "enable_guc", i915_modparams.enable_guc,
138 "GuC submission not supported");
139 DRM_INFO("Switching to non-GuC submission mode!\n");
140 i915_modparams.enable_guc &= ~ENABLE_GUC_SUBMISSION;
141 }
142
143
144 if (i915_modparams.guc_log_level < 0)
145 i915_modparams.guc_log_level =
146 __get_default_guc_log_level(i915);
147
148 if (i915_modparams.guc_log_level > 0 && !intel_uc_is_using_guc(i915)) {
149 DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
150 "guc_log_level", i915_modparams.guc_log_level,
151 !HAS_GUC(i915) ? "no GuC hardware" :
152 "GuC not enabled");
153 i915_modparams.guc_log_level = 0;
154 }
155
156 if (i915_modparams.guc_log_level > GUC_LOG_LEVEL_MAX) {
157 DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
158 "guc_log_level", i915_modparams.guc_log_level,
159 "verbosity too high");
160 i915_modparams.guc_log_level = GUC_LOG_LEVEL_MAX;
161 }
162
163 DRM_DEBUG_DRIVER("guc_log_level=%d (enabled:%s, verbose:%s, verbosity:%d)\n",
164 i915_modparams.guc_log_level,
165 yesno(i915_modparams.guc_log_level),
166 yesno(GUC_LOG_LEVEL_IS_VERBOSE(i915_modparams.guc_log_level)),
167 GUC_LOG_LEVEL_TO_VERBOSITY(i915_modparams.guc_log_level));
168
169
170 GEM_BUG_ON(i915_modparams.enable_guc < 0);
171 GEM_BUG_ON(i915_modparams.guc_log_level < 0);
172}
173
174void intel_uc_init_early(struct drm_i915_private *i915)
175{
176 struct intel_guc *guc = &i915->guc;
177 struct intel_huc *huc = &i915->huc;
178
179 intel_guc_init_early(guc);
180 intel_huc_init_early(huc);
181
182 sanitize_options_early(i915);
183}
184
185void intel_uc_cleanup_early(struct drm_i915_private *i915)
186{
187 struct intel_guc *guc = &i915->guc;
188
189 guc_free_load_err_log(guc);
190}
191
192
193
194
195
196
197
198
199void intel_uc_init_mmio(struct drm_i915_private *i915)
200{
201 intel_guc_init_send_regs(&i915->guc);
202}
203
204static void guc_capture_load_err_log(struct intel_guc *guc)
205{
206 if (!guc->log.vma || !intel_guc_log_get_level(&guc->log))
207 return;
208
209 if (!guc->load_err_log)
210 guc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
211
212 return;
213}
214
215static void guc_free_load_err_log(struct intel_guc *guc)
216{
217 if (guc->load_err_log)
218 i915_gem_object_put(guc->load_err_log);
219}
220
221static void guc_reset_interrupts(struct intel_guc *guc)
222{
223 guc->interrupts.reset(guc_to_i915(guc));
224}
225
226static void guc_enable_interrupts(struct intel_guc *guc)
227{
228 guc->interrupts.enable(guc_to_i915(guc));
229}
230
231static void guc_disable_interrupts(struct intel_guc *guc)
232{
233 guc->interrupts.disable(guc_to_i915(guc));
234}
235
236static int guc_enable_communication(struct intel_guc *guc)
237{
238 guc_enable_interrupts(guc);
239
240 return intel_guc_ct_enable(&guc->ct);
241}
242
243static void guc_stop_communication(struct intel_guc *guc)
244{
245 intel_guc_ct_stop(&guc->ct);
246
247 guc->send = intel_guc_send_nop;
248 guc->handler = intel_guc_to_host_event_handler_nop;
249}
250
251static void guc_disable_communication(struct intel_guc *guc)
252{
253 intel_guc_ct_disable(&guc->ct);
254
255 guc_disable_interrupts(guc);
256
257 guc->send = intel_guc_send_nop;
258 guc->handler = intel_guc_to_host_event_handler_nop;
259}
260
261int intel_uc_init_misc(struct drm_i915_private *i915)
262{
263 struct intel_guc *guc = &i915->guc;
264 struct intel_huc *huc = &i915->huc;
265 int ret;
266
267 if (!USES_GUC(i915))
268 return 0;
269
270 ret = intel_guc_init_misc(guc);
271 if (ret)
272 return ret;
273
274 if (USES_HUC(i915)) {
275 ret = intel_huc_init_misc(huc);
276 if (ret)
277 goto err_guc;
278 }
279
280 return 0;
281
282err_guc:
283 intel_guc_fini_misc(guc);
284 return ret;
285}
286
287void intel_uc_fini_misc(struct drm_i915_private *i915)
288{
289 struct intel_guc *guc = &i915->guc;
290 struct intel_huc *huc = &i915->huc;
291
292 if (!USES_GUC(i915))
293 return;
294
295 if (USES_HUC(i915))
296 intel_huc_fini_misc(huc);
297
298 intel_guc_fini_misc(guc);
299}
300
301int intel_uc_init(struct drm_i915_private *i915)
302{
303 struct intel_guc *guc = &i915->guc;
304 struct intel_huc *huc = &i915->huc;
305 int ret;
306
307 if (!USES_GUC(i915))
308 return 0;
309
310 if (!HAS_GUC(i915))
311 return -ENODEV;
312
313
314 GEM_BUG_ON(USES_GUC_SUBMISSION(i915));
315
316 ret = intel_guc_init(guc);
317 if (ret)
318 return ret;
319
320 if (USES_HUC(i915)) {
321 ret = intel_huc_init(huc);
322 if (ret)
323 goto err_guc;
324 }
325
326 if (USES_GUC_SUBMISSION(i915)) {
327
328
329
330
331 ret = intel_guc_submission_init(guc);
332 if (ret)
333 goto err_huc;
334 }
335
336 return 0;
337
338err_huc:
339 if (USES_HUC(i915))
340 intel_huc_fini(huc);
341err_guc:
342 intel_guc_fini(guc);
343 return ret;
344}
345
346void intel_uc_fini(struct drm_i915_private *i915)
347{
348 struct intel_guc *guc = &i915->guc;
349
350 if (!USES_GUC(i915))
351 return;
352
353 GEM_BUG_ON(!HAS_GUC(i915));
354
355 if (USES_GUC_SUBMISSION(i915))
356 intel_guc_submission_fini(guc);
357
358 if (USES_HUC(i915))
359 intel_huc_fini(&i915->huc);
360
361 intel_guc_fini(guc);
362}
363
364static void __uc_sanitize(struct drm_i915_private *i915)
365{
366 struct intel_guc *guc = &i915->guc;
367 struct intel_huc *huc = &i915->huc;
368
369 GEM_BUG_ON(!HAS_GUC(i915));
370
371 intel_huc_sanitize(huc);
372 intel_guc_sanitize(guc);
373
374 __intel_uc_reset_hw(i915);
375}
376
377void intel_uc_sanitize(struct drm_i915_private *i915)
378{
379 if (!USES_GUC(i915))
380 return;
381
382 __uc_sanitize(i915);
383}
384
385int intel_uc_init_hw(struct drm_i915_private *i915)
386{
387 struct intel_guc *guc = &i915->guc;
388 struct intel_huc *huc = &i915->huc;
389 int ret, attempts;
390
391 if (!USES_GUC(i915))
392 return 0;
393
394 GEM_BUG_ON(!HAS_GUC(i915));
395
396 guc_reset_interrupts(guc);
397
398
399
400 if (IS_GEN(i915, 9))
401 attempts = 3;
402 else
403 attempts = 1;
404
405 while (attempts--) {
406
407
408
409
410 ret = __intel_uc_reset_hw(i915);
411 if (ret)
412 goto err_out;
413
414 if (USES_HUC(i915)) {
415 ret = intel_huc_fw_upload(huc);
416 if (ret)
417 goto err_out;
418 }
419
420 intel_guc_ads_reset(guc);
421 intel_guc_init_params(guc);
422 ret = intel_guc_fw_upload(guc);
423 if (ret == 0)
424 break;
425
426 DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
427 "retry %d more time(s)\n", ret, attempts);
428 }
429
430
431 if (ret)
432 goto err_log_capture;
433
434 ret = guc_enable_communication(guc);
435 if (ret)
436 goto err_log_capture;
437
438 if (USES_HUC(i915)) {
439 ret = intel_huc_auth(huc);
440 if (ret)
441 goto err_communication;
442 }
443
444 ret = intel_guc_sample_forcewake(guc);
445 if (ret)
446 goto err_communication;
447
448 if (USES_GUC_SUBMISSION(i915)) {
449 ret = intel_guc_submission_enable(guc);
450 if (ret)
451 goto err_communication;
452 }
453
454 dev_info(i915->drm.dev, "GuC firmware version %u.%u\n",
455 guc->fw.major_ver_found, guc->fw.minor_ver_found);
456 dev_info(i915->drm.dev, "GuC submission %s\n",
457 enableddisabled(USES_GUC_SUBMISSION(i915)));
458 dev_info(i915->drm.dev, "HuC %s\n",
459 enableddisabled(USES_HUC(i915)));
460
461 return 0;
462
463
464
465
466err_communication:
467 guc_disable_communication(guc);
468err_log_capture:
469 guc_capture_load_err_log(guc);
470err_out:
471 __uc_sanitize(i915);
472
473
474
475
476
477 if (GEM_WARN_ON(ret == -EIO))
478 ret = -EINVAL;
479
480 dev_err(i915->drm.dev, "GuC initialization failed %d\n", ret);
481 return ret;
482}
483
484void intel_uc_fini_hw(struct drm_i915_private *i915)
485{
486 struct intel_guc *guc = &i915->guc;
487
488 if (!intel_guc_is_loaded(guc))
489 return;
490
491 GEM_BUG_ON(!HAS_GUC(i915));
492
493 if (USES_GUC_SUBMISSION(i915))
494 intel_guc_submission_disable(guc);
495
496 guc_disable_communication(guc);
497 __uc_sanitize(i915);
498}
499
500
501
502
503
504
505
506void intel_uc_reset_prepare(struct drm_i915_private *i915)
507{
508 struct intel_guc *guc = &i915->guc;
509
510 if (!intel_guc_is_loaded(guc))
511 return;
512
513 guc_stop_communication(guc);
514 __uc_sanitize(i915);
515}
516
517void intel_uc_runtime_suspend(struct drm_i915_private *i915)
518{
519 struct intel_guc *guc = &i915->guc;
520 int err;
521
522 if (!intel_guc_is_loaded(guc))
523 return;
524
525 err = intel_guc_suspend(guc);
526 if (err)
527 DRM_DEBUG_DRIVER("Failed to suspend GuC, err=%d", err);
528
529 guc_disable_communication(guc);
530}
531
532void intel_uc_suspend(struct drm_i915_private *i915)
533{
534 struct intel_guc *guc = &i915->guc;
535 intel_wakeref_t wakeref;
536
537 if (!intel_guc_is_loaded(guc))
538 return;
539
540 with_intel_runtime_pm(&i915->runtime_pm, wakeref)
541 intel_uc_runtime_suspend(i915);
542}
543
544int intel_uc_resume(struct drm_i915_private *i915)
545{
546 struct intel_guc *guc = &i915->guc;
547 int err;
548
549 if (!intel_guc_is_loaded(guc))
550 return 0;
551
552 guc_enable_communication(guc);
553
554 err = intel_guc_resume(guc);
555 if (err) {
556 DRM_DEBUG_DRIVER("Failed to resume GuC, err=%d", err);
557 return err;
558 }
559
560 return 0;
561}
562