xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/i915/gt/uc/intel_uc.c (revision 41ec02673d281bbb3d38e6c78504ce6e30c228c1)
1 /*	$NetBSD: intel_uc.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $	*/
2 
3 // SPDX-License-Identifier: MIT
4 /*
5  * Copyright © 2016-2019 Intel Corporation
6  */
7 
8 #include <sys/cdefs.h>
9 __KERNEL_RCSID(0, "$NetBSD: intel_uc.c,v 1.2 2021/12/18 23:45:31 riastradh Exp $");
10 
11 #include "gt/intel_gt.h"
12 #include "gt/intel_reset.h"
13 #include "intel_guc.h"
14 #include "intel_guc_ads.h"
15 #include "intel_guc_submission.h"
16 #include "intel_uc.h"
17 
18 #include "i915_drv.h"
19 
20 static const struct intel_uc_ops uc_ops_off;
21 static const struct intel_uc_ops uc_ops_on;
22 
23 /* Reset GuC providing us with fresh state for both GuC and HuC.
24  */
__intel_uc_reset_hw(struct intel_uc * uc)25 static int __intel_uc_reset_hw(struct intel_uc *uc)
26 {
27 	struct intel_gt *gt = uc_to_gt(uc);
28 	int ret;
29 	u32 guc_status;
30 
31 	ret = i915_inject_probe_error(gt->i915, -ENXIO);
32 	if (ret)
33 		return ret;
34 
35 	ret = intel_reset_guc(gt);
36 	if (ret) {
37 		DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
38 		return ret;
39 	}
40 
41 	guc_status = intel_uncore_read(gt->uncore, GUC_STATUS);
42 	WARN(!(guc_status & GS_MIA_IN_RESET),
43 	     "GuC status: 0x%x, MIA core expected to be in reset\n",
44 	     guc_status);
45 
46 	return ret;
47 }
48 
__confirm_options(struct intel_uc * uc)49 static void __confirm_options(struct intel_uc *uc)
50 {
51 	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
52 
53 	DRM_DEV_DEBUG_DRIVER(i915->drm.dev,
54 			     "enable_guc=%d (guc:%s submission:%s huc:%s)\n",
55 			     i915_modparams.enable_guc,
56 			     yesno(intel_uc_uses_guc(uc)),
57 			     yesno(intel_uc_uses_guc_submission(uc)),
58 			     yesno(intel_uc_uses_huc(uc)));
59 
60 	if (i915_modparams.enable_guc == -1)
61 		return;
62 
63 	if (i915_modparams.enable_guc == 0) {
64 		GEM_BUG_ON(intel_uc_uses_guc(uc));
65 		GEM_BUG_ON(intel_uc_uses_guc_submission(uc));
66 		GEM_BUG_ON(intel_uc_uses_huc(uc));
67 		return;
68 	}
69 
70 	if (!intel_uc_supports_guc(uc))
71 		dev_info(i915->drm.dev,
72 			 "Incompatible option enable_guc=%d - %s\n",
73 			 i915_modparams.enable_guc, "GuC is not supported!");
74 
75 	if (i915_modparams.enable_guc & ENABLE_GUC_LOAD_HUC &&
76 	    !intel_uc_supports_huc(uc))
77 		dev_info(i915->drm.dev,
78 			 "Incompatible option enable_guc=%d - %s\n",
79 			 i915_modparams.enable_guc, "HuC is not supported!");
80 
81 	if (i915_modparams.enable_guc & ENABLE_GUC_SUBMISSION &&
82 	    !intel_uc_supports_guc_submission(uc))
83 		dev_info(i915->drm.dev,
84 			 "Incompatible option enable_guc=%d - %s\n",
85 			 i915_modparams.enable_guc, "GuC submission is N/A");
86 
87 	if (i915_modparams.enable_guc & ~(ENABLE_GUC_SUBMISSION |
88 					  ENABLE_GUC_LOAD_HUC))
89 		dev_info(i915->drm.dev,
90 			 "Incompatible option enable_guc=%d - %s\n",
91 			 i915_modparams.enable_guc, "undocumented flag");
92 }
93 
intel_uc_init_early(struct intel_uc * uc)94 void intel_uc_init_early(struct intel_uc *uc)
95 {
96 	intel_guc_init_early(&uc->guc);
97 	intel_huc_init_early(&uc->huc);
98 
99 	__confirm_options(uc);
100 
101 	if (intel_uc_uses_guc(uc))
102 		uc->ops = &uc_ops_on;
103 	else
104 		uc->ops = &uc_ops_off;
105 }
106 
intel_uc_driver_late_release(struct intel_uc * uc)107 void intel_uc_driver_late_release(struct intel_uc *uc)
108 {
109 }
110 
111 /**
112  * intel_uc_init_mmio - setup uC MMIO access
113  * @uc: the intel_uc structure
114  *
115  * Setup minimal state necessary for MMIO accesses later in the
116  * initialization sequence.
117  */
intel_uc_init_mmio(struct intel_uc * uc)118 void intel_uc_init_mmio(struct intel_uc *uc)
119 {
120 	intel_guc_init_send_regs(&uc->guc);
121 }
122 
__uc_capture_load_err_log(struct intel_uc * uc)123 static void __uc_capture_load_err_log(struct intel_uc *uc)
124 {
125 	struct intel_guc *guc = &uc->guc;
126 
127 	if (guc->log.vma && !uc->load_err_log)
128 		uc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
129 }
130 
__uc_free_load_err_log(struct intel_uc * uc)131 static void __uc_free_load_err_log(struct intel_uc *uc)
132 {
133 	struct drm_i915_gem_object *log = fetch_and_zero(&uc->load_err_log);
134 
135 	if (log)
136 		i915_gem_object_put(log);
137 }
138 
guc_communication_enabled(struct intel_guc * guc)139 static inline bool guc_communication_enabled(struct intel_guc *guc)
140 {
141 	return intel_guc_ct_enabled(&guc->ct);
142 }
143 
144 /*
145  * Events triggered while CT buffers are disabled are logged in the SCRATCH_15
146  * register using the same bits used in the CT message payload. Since our
147  * communication channel with guc is turned off at this point, we can save the
148  * message and handle it after we turn it back on.
149  */
guc_clear_mmio_msg(struct intel_guc * guc)150 static void guc_clear_mmio_msg(struct intel_guc *guc)
151 {
152 	intel_uncore_write(guc_to_gt(guc)->uncore, SOFT_SCRATCH(15), 0);
153 }
154 
guc_get_mmio_msg(struct intel_guc * guc)155 static void guc_get_mmio_msg(struct intel_guc *guc)
156 {
157 	u32 val;
158 
159 	spin_lock_irq(&guc->irq_lock);
160 
161 	val = intel_uncore_read(guc_to_gt(guc)->uncore, SOFT_SCRATCH(15));
162 	guc->mmio_msg |= val & guc->msg_enabled_mask;
163 
164 	/*
165 	 * clear all events, including the ones we're not currently servicing,
166 	 * to make sure we don't try to process a stale message if we enable
167 	 * handling of more events later.
168 	 */
169 	guc_clear_mmio_msg(guc);
170 
171 	spin_unlock_irq(&guc->irq_lock);
172 }
173 
guc_handle_mmio_msg(struct intel_guc * guc)174 static void guc_handle_mmio_msg(struct intel_guc *guc)
175 {
176 	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
177 
178 	/* we need communication to be enabled to reply to GuC */
179 	GEM_BUG_ON(!guc_communication_enabled(guc));
180 
181 	if (!guc->mmio_msg)
182 		return;
183 
184 	spin_lock_irq(&i915->irq_lock);
185 	intel_guc_to_host_process_recv_msg(guc, &guc->mmio_msg, 1);
186 	spin_unlock_irq(&i915->irq_lock);
187 
188 	guc->mmio_msg = 0;
189 }
190 
guc_reset_interrupts(struct intel_guc * guc)191 static void guc_reset_interrupts(struct intel_guc *guc)
192 {
193 	guc->interrupts.reset(guc);
194 }
195 
guc_enable_interrupts(struct intel_guc * guc)196 static void guc_enable_interrupts(struct intel_guc *guc)
197 {
198 	guc->interrupts.enable(guc);
199 }
200 
guc_disable_interrupts(struct intel_guc * guc)201 static void guc_disable_interrupts(struct intel_guc *guc)
202 {
203 	guc->interrupts.disable(guc);
204 }
205 
guc_enable_communication(struct intel_guc * guc)206 static int guc_enable_communication(struct intel_guc *guc)
207 {
208 	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
209 	int ret;
210 
211 	GEM_BUG_ON(guc_communication_enabled(guc));
212 
213 	ret = i915_inject_probe_error(i915, -ENXIO);
214 	if (ret)
215 		return ret;
216 
217 	ret = intel_guc_ct_enable(&guc->ct);
218 	if (ret)
219 		return ret;
220 
221 	/* check for mmio messages received before/during the CT enable */
222 	guc_get_mmio_msg(guc);
223 	guc_handle_mmio_msg(guc);
224 
225 	guc_enable_interrupts(guc);
226 
227 	/* check for CT messages received before we enabled interrupts */
228 	spin_lock_irq(&i915->irq_lock);
229 	intel_guc_ct_event_handler(&guc->ct);
230 	spin_unlock_irq(&i915->irq_lock);
231 
232 	DRM_INFO("GuC communication enabled\n");
233 
234 	return 0;
235 }
236 
guc_disable_communication(struct intel_guc * guc)237 static void guc_disable_communication(struct intel_guc *guc)
238 {
239 	/*
240 	 * Events generated during or after CT disable are logged by guc in
241 	 * via mmio. Make sure the register is clear before disabling CT since
242 	 * all events we cared about have already been processed via CT.
243 	 */
244 	guc_clear_mmio_msg(guc);
245 
246 	guc_disable_interrupts(guc);
247 
248 	intel_guc_ct_disable(&guc->ct);
249 
250 	/*
251 	 * Check for messages received during/after the CT disable. We do not
252 	 * expect any messages to have arrived via CT between the interrupt
253 	 * disable and the CT disable because GuC should've been idle until we
254 	 * triggered the CT disable protocol.
255 	 */
256 	guc_get_mmio_msg(guc);
257 
258 	DRM_INFO("GuC communication disabled\n");
259 }
260 
__uc_fetch_firmwares(struct intel_uc * uc)261 static void __uc_fetch_firmwares(struct intel_uc *uc)
262 {
263 	int err;
264 
265 	GEM_BUG_ON(!intel_uc_uses_guc(uc));
266 
267 	err = intel_uc_fw_fetch(&uc->guc.fw);
268 	if (err)
269 		return;
270 
271 	if (intel_uc_uses_huc(uc))
272 		intel_uc_fw_fetch(&uc->huc.fw);
273 }
274 
__uc_cleanup_firmwares(struct intel_uc * uc)275 static void __uc_cleanup_firmwares(struct intel_uc *uc)
276 {
277 	intel_uc_fw_cleanup_fetch(&uc->huc.fw);
278 	intel_uc_fw_cleanup_fetch(&uc->guc.fw);
279 }
280 
__uc_init(struct intel_uc * uc)281 static void __uc_init(struct intel_uc *uc)
282 {
283 	struct intel_guc *guc = &uc->guc;
284 	struct intel_huc *huc = &uc->huc;
285 	int ret;
286 
287 	GEM_BUG_ON(!intel_uc_uses_guc(uc));
288 
289 	/* XXX: GuC submission is unavailable for now */
290 	GEM_BUG_ON(intel_uc_supports_guc_submission(uc));
291 
292 	ret = intel_guc_init(guc);
293 	if (ret) {
294 		intel_uc_fw_cleanup_fetch(&huc->fw);
295 		return;
296 	}
297 
298 	if (intel_uc_uses_huc(uc))
299 		intel_huc_init(huc);
300 }
301 
__uc_fini(struct intel_uc * uc)302 static void __uc_fini(struct intel_uc *uc)
303 {
304 	intel_huc_fini(&uc->huc);
305 	intel_guc_fini(&uc->guc);
306 
307 	__uc_free_load_err_log(uc);
308 }
309 
__uc_sanitize(struct intel_uc * uc)310 static int __uc_sanitize(struct intel_uc *uc)
311 {
312 	struct intel_guc *guc = &uc->guc;
313 	struct intel_huc *huc = &uc->huc;
314 
315 	GEM_BUG_ON(!intel_uc_supports_guc(uc));
316 
317 	intel_huc_sanitize(huc);
318 	intel_guc_sanitize(guc);
319 
320 	return __intel_uc_reset_hw(uc);
321 }
322 
323 /* Initialize and verify the uC regs related to uC positioning in WOPCM */
uc_init_wopcm(struct intel_uc * uc)324 static int uc_init_wopcm(struct intel_uc *uc)
325 {
326 	struct intel_gt *gt = uc_to_gt(uc);
327 	struct intel_uncore *uncore = gt->uncore;
328 	u32 base = intel_wopcm_guc_base(&gt->i915->wopcm);
329 	u32 size = intel_wopcm_guc_size(&gt->i915->wopcm);
330 	u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
331 	u32 mask;
332 	int err;
333 
334 	if (unlikely(!base || !size)) {
335 		i915_probe_error(gt->i915, "Unsuccessful WOPCM partitioning\n");
336 		return -E2BIG;
337 	}
338 
339 	GEM_BUG_ON(!intel_uc_supports_guc(uc));
340 	GEM_BUG_ON(!(base & GUC_WOPCM_OFFSET_MASK));
341 	GEM_BUG_ON(base & ~GUC_WOPCM_OFFSET_MASK);
342 	GEM_BUG_ON(!(size & GUC_WOPCM_SIZE_MASK));
343 	GEM_BUG_ON(size & ~GUC_WOPCM_SIZE_MASK);
344 
345 	err = i915_inject_probe_error(gt->i915, -ENXIO);
346 	if (err)
347 		return err;
348 
349 	mask = GUC_WOPCM_SIZE_MASK | GUC_WOPCM_SIZE_LOCKED;
350 	err = intel_uncore_write_and_verify(uncore, GUC_WOPCM_SIZE, size, mask,
351 					    size | GUC_WOPCM_SIZE_LOCKED);
352 	if (err)
353 		goto err_out;
354 
355 	mask = GUC_WOPCM_OFFSET_MASK | GUC_WOPCM_OFFSET_VALID | huc_agent;
356 	err = intel_uncore_write_and_verify(uncore, DMA_GUC_WOPCM_OFFSET,
357 					    base | huc_agent, mask,
358 					    base | huc_agent |
359 					    GUC_WOPCM_OFFSET_VALID);
360 	if (err)
361 		goto err_out;
362 
363 	return 0;
364 
365 err_out:
366 	i915_probe_error(gt->i915, "Failed to init uC WOPCM registers!\n");
367 	i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "DMA_GUC_WOPCM_OFFSET",
368 			 i915_mmio_reg_offset(DMA_GUC_WOPCM_OFFSET),
369 			 intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET));
370 	i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "GUC_WOPCM_SIZE",
371 			 i915_mmio_reg_offset(GUC_WOPCM_SIZE),
372 			 intel_uncore_read(uncore, GUC_WOPCM_SIZE));
373 
374 	return err;
375 }
376 
uc_is_wopcm_locked(struct intel_uc * uc)377 static bool uc_is_wopcm_locked(struct intel_uc *uc)
378 {
379 	struct intel_gt *gt = uc_to_gt(uc);
380 	struct intel_uncore *uncore = gt->uncore;
381 
382 	return (intel_uncore_read(uncore, GUC_WOPCM_SIZE) & GUC_WOPCM_SIZE_LOCKED) ||
383 	       (intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET) & GUC_WOPCM_OFFSET_VALID);
384 }
385 
__uc_check_hw(struct intel_uc * uc)386 static int __uc_check_hw(struct intel_uc *uc)
387 {
388 	if (!intel_uc_supports_guc(uc))
389 		return 0;
390 
391 	/*
392 	 * We can silently continue without GuC only if it was never enabled
393 	 * before on this system after reboot, otherwise we risk GPU hangs.
394 	 * To check if GuC was loaded before we look at WOPCM registers.
395 	 */
396 	if (uc_is_wopcm_locked(uc))
397 		return -EIO;
398 
399 	return 0;
400 }
401 
__uc_init_hw(struct intel_uc * uc)402 static int __uc_init_hw(struct intel_uc *uc)
403 {
404 	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
405 	struct intel_guc *guc = &uc->guc;
406 	struct intel_huc *huc = &uc->huc;
407 	int ret, attempts;
408 
409 	GEM_BUG_ON(!intel_uc_supports_guc(uc));
410 	GEM_BUG_ON(!intel_uc_uses_guc(uc));
411 
412 	if (!intel_uc_fw_is_available(&guc->fw)) {
413 		ret = __uc_check_hw(uc) ||
414 		      intel_uc_fw_is_overridden(&guc->fw) ||
415 		      intel_uc_supports_guc_submission(uc) ?
416 		      intel_uc_fw_status_to_error(guc->fw.status) : 0;
417 		goto err_out;
418 	}
419 
420 	ret = uc_init_wopcm(uc);
421 	if (ret)
422 		goto err_out;
423 
424 	guc_reset_interrupts(guc);
425 
426 	/* WaEnableuKernelHeaderValidFix:skl */
427 	/* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
428 	if (IS_GEN(i915, 9))
429 		attempts = 3;
430 	else
431 		attempts = 1;
432 
433 	while (attempts--) {
434 		/*
435 		 * Always reset the GuC just before (re)loading, so
436 		 * that the state and timing are fairly predictable
437 		 */
438 		ret = __uc_sanitize(uc);
439 		if (ret)
440 			goto err_out;
441 
442 		intel_huc_fw_upload(huc);
443 		intel_guc_ads_reset(guc);
444 		intel_guc_write_params(guc);
445 		ret = intel_guc_fw_upload(guc);
446 		if (ret == 0)
447 			break;
448 
449 		DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
450 				 "retry %d more time(s)\n", ret, attempts);
451 	}
452 
453 	/* Did we succeded or run out of retries? */
454 	if (ret)
455 		goto err_log_capture;
456 
457 	ret = guc_enable_communication(guc);
458 	if (ret)
459 		goto err_log_capture;
460 
461 	intel_huc_auth(huc);
462 
463 	ret = intel_guc_sample_forcewake(guc);
464 	if (ret)
465 		goto err_communication;
466 
467 	if (intel_uc_supports_guc_submission(uc))
468 		intel_guc_submission_enable(guc);
469 
470 	dev_info(i915->drm.dev, "%s firmware %s version %u.%u %s:%s\n",
471 		 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_GUC), guc->fw.path,
472 		 guc->fw.major_ver_found, guc->fw.minor_ver_found,
473 		 "submission",
474 		 enableddisabled(intel_uc_supports_guc_submission(uc)));
475 
476 	if (intel_uc_uses_huc(uc)) {
477 		dev_info(i915->drm.dev, "%s firmware %s version %u.%u %s:%s\n",
478 			 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
479 			 huc->fw.path,
480 			 huc->fw.major_ver_found, huc->fw.minor_ver_found,
481 			 "authenticated",
482 			 yesno(intel_huc_is_authenticated(huc)));
483 	}
484 
485 	return 0;
486 
487 	/*
488 	 * We've failed to load the firmware :(
489 	 */
490 err_communication:
491 	guc_disable_communication(guc);
492 err_log_capture:
493 	__uc_capture_load_err_log(uc);
494 err_out:
495 	__uc_sanitize(uc);
496 
497 	if (!ret) {
498 		dev_notice(i915->drm.dev, "GuC is uninitialized\n");
499 		/* We want to run without GuC submission */
500 		return 0;
501 	}
502 
503 	i915_probe_error(i915, "GuC initialization failed %d\n", ret);
504 
505 	/* We want to keep KMS alive */
506 	return -EIO;
507 }
508 
__uc_fini_hw(struct intel_uc * uc)509 static void __uc_fini_hw(struct intel_uc *uc)
510 {
511 	struct intel_guc *guc = &uc->guc;
512 
513 	if (!intel_guc_is_running(guc))
514 		return;
515 
516 	if (intel_uc_supports_guc_submission(uc))
517 		intel_guc_submission_disable(guc);
518 
519 	if (guc_communication_enabled(guc))
520 		guc_disable_communication(guc);
521 
522 	__uc_sanitize(uc);
523 }
524 
525 /**
526  * intel_uc_reset_prepare - Prepare for reset
527  * @uc: the intel_uc structure
528  *
529  * Preparing for full gpu reset.
530  */
intel_uc_reset_prepare(struct intel_uc * uc)531 void intel_uc_reset_prepare(struct intel_uc *uc)
532 {
533 	struct intel_guc *guc = &uc->guc;
534 
535 	if (!intel_guc_is_running(guc))
536 		return;
537 
538 	guc_disable_communication(guc);
539 	__uc_sanitize(uc);
540 }
541 
intel_uc_runtime_suspend(struct intel_uc * uc)542 void intel_uc_runtime_suspend(struct intel_uc *uc)
543 {
544 	struct intel_guc *guc = &uc->guc;
545 	int err;
546 
547 	if (!intel_guc_is_running(guc))
548 		return;
549 
550 	err = intel_guc_suspend(guc);
551 	if (err)
552 		DRM_DEBUG_DRIVER("Failed to suspend GuC, err=%d", err);
553 
554 	guc_disable_communication(guc);
555 }
556 
intel_uc_suspend(struct intel_uc * uc)557 void intel_uc_suspend(struct intel_uc *uc)
558 {
559 	struct intel_guc *guc = &uc->guc;
560 	intel_wakeref_t wakeref;
561 
562 	if (!intel_guc_is_running(guc))
563 		return;
564 
565 	with_intel_runtime_pm(uc_to_gt(uc)->uncore->rpm, wakeref)
566 		intel_uc_runtime_suspend(uc);
567 }
568 
__uc_resume(struct intel_uc * uc,bool enable_communication)569 static int __uc_resume(struct intel_uc *uc, bool enable_communication)
570 {
571 	struct intel_guc *guc = &uc->guc;
572 	int err;
573 
574 	if (!intel_guc_is_running(guc))
575 		return 0;
576 
577 	/* Make sure we enable communication if and only if it's disabled */
578 	GEM_BUG_ON(enable_communication == guc_communication_enabled(guc));
579 
580 	if (enable_communication)
581 		guc_enable_communication(guc);
582 
583 	err = intel_guc_resume(guc);
584 	if (err) {
585 		DRM_DEBUG_DRIVER("Failed to resume GuC, err=%d", err);
586 		return err;
587 	}
588 
589 	return 0;
590 }
591 
intel_uc_resume(struct intel_uc * uc)592 int intel_uc_resume(struct intel_uc *uc)
593 {
594 	/*
595 	 * When coming out of S3/S4 we sanitize and re-init the HW, so
596 	 * communication is already re-enabled at this point.
597 	 */
598 	return __uc_resume(uc, false);
599 }
600 
intel_uc_runtime_resume(struct intel_uc * uc)601 int intel_uc_runtime_resume(struct intel_uc *uc)
602 {
603 	/*
604 	 * During runtime resume we don't sanitize, so we need to re-init
605 	 * communication as well.
606 	 */
607 	return __uc_resume(uc, true);
608 }
609 
610 static const struct intel_uc_ops uc_ops_off = {
611 	.init_hw = __uc_check_hw,
612 };
613 
614 static const struct intel_uc_ops uc_ops_on = {
615 	.sanitize = __uc_sanitize,
616 
617 	.init_fw = __uc_fetch_firmwares,
618 	.fini_fw = __uc_cleanup_firmwares,
619 
620 	.init = __uc_init,
621 	.fini = __uc_fini,
622 
623 	.init_hw = __uc_init_hw,
624 	.fini_hw = __uc_fini_hw,
625 };
626