intel_uc.c 15.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * Copyright © 2016 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 */

25
#include "gt/intel_reset.h"
26
#include "intel_uc.h"
27
#include "intel_guc.h"
28 29
#include "intel_guc_ads.h"
#include "intel_guc_submission.h"
M
Michal Wajdeczko 已提交
30
#include "i915_drv.h"
31

32 33
static void guc_free_load_err_log(struct intel_guc *guc);

34 35 36 37 38 39 40
/* Reset GuC providing us with fresh state for both GuC and HuC.
 */
static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
{
	int ret;
	u32 guc_status;

41
	ret = intel_reset_guc(&dev_priv->gt);
42
	if (ret) {
43
		DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
44 45 46 47 48 49 50 51 52 53 54
		return ret;
	}

	guc_status = I915_READ(GUC_STATUS);
	WARN(!(guc_status & GS_MIA_IN_RESET),
	     "GuC status: 0x%x, MIA core expected to be in reset\n",
	     guc_status);

	return ret;
}

55
static int __get_platform_enable_guc(struct drm_i915_private *i915)
56
{
57 58
	struct intel_uc_fw *guc_fw = &i915->guc.fw;
	struct intel_uc_fw *huc_fw = &i915->huc.fw;
59
	int enable_guc = 0;
60

61 62 63 64 65 66 67
	if (!HAS_GUC(i915))
		return 0;

	/* We don't want to enable GuC/HuC on pre-Gen11 by default */
	if (INTEL_GEN(i915) < 11)
		return 0;

68
	if (intel_uc_fw_is_selected(guc_fw) && intel_uc_fw_is_selected(huc_fw))
69
		enable_guc |= ENABLE_GUC_LOAD_HUC;
70

71 72
	return enable_guc;
}
73

74
static int __get_default_guc_log_level(struct drm_i915_private *i915)
75
{
76
	int guc_log_level;
77

78
	if (!HAS_GUC(i915) || !intel_uc_is_using_guc(i915))
79 80 81 82 83 84
		guc_log_level = GUC_LOG_LEVEL_DISABLED;
	else if (IS_ENABLED(CONFIG_DRM_I915_DEBUG) ||
		 IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
		guc_log_level = GUC_LOG_LEVEL_MAX;
	else
		guc_log_level = GUC_LOG_LEVEL_NON_VERBOSE;
85 86 87 88 89 90

	/* Any platform specific fine-tuning can be done here */

	return guc_log_level;
}

91
/**
92
 * sanitize_options_early - sanitize uC related modparam options
93
 * @i915: device private
94 95 96 97 98 99
 *
 * In case of "enable_guc" option this function will attempt to modify
 * it only if it was initially set to "auto(-1)". Default value for this
 * modparam varies between platforms and it is hardcoded in driver code.
 * Any other modparam value is only monitored against availability of the
 * related hardware or firmware definitions.
100 101 102 103 104 105 106
 *
 * In case of "guc_log_level" option this function will attempt to modify
 * it only if it was initially set to "auto(-1)" or if initial value was
 * "enable(1..4)" on platforms without the GuC. Default value for this
 * modparam varies between platforms and is usually set to "disable(0)"
 * unless GuC is enabled on given platform and the driver is compiled with
 * debug config when this modparam will default to "enable(1..4)".
107
 */
108
static void sanitize_options_early(struct drm_i915_private *i915)
109
{
110 111
	struct intel_uc_fw *guc_fw = &i915->guc.fw;
	struct intel_uc_fw *huc_fw = &i915->huc.fw;
112 113

	/* A negative value means "use platform default" */
114
	if (i915_modparams.enable_guc < 0)
115
		i915_modparams.enable_guc = __get_platform_enable_guc(i915);
116 117 118

	DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s)\n",
			 i915_modparams.enable_guc,
119 120
			 yesno(intel_uc_is_using_guc_submission(i915)),
			 yesno(intel_uc_is_using_huc(i915)));
121 122

	/* Verify GuC firmware availability */
123
	if (intel_uc_is_using_guc(i915) && !intel_uc_fw_is_selected(guc_fw)) {
124 125
		DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
			 "enable_guc", i915_modparams.enable_guc,
126 127
			 !HAS_GUC(i915) ? "no GuC hardware" :
					  "no GuC firmware");
128 129 130
	}

	/* Verify HuC firmware availability */
131
	if (intel_uc_is_using_huc(i915) && !intel_uc_fw_is_selected(huc_fw)) {
132 133
		DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
			 "enable_guc", i915_modparams.enable_guc,
134 135
			 !HAS_HUC(i915) ? "no HuC hardware" :
					  "no HuC firmware");
136 137
	}

138 139 140 141 142 143 144 145 146
	/* XXX: GuC submission is unavailable for now */
	if (intel_uc_is_using_guc_submission(i915)) {
		DRM_INFO("Incompatible option detected: %s=%d, %s!\n",
			 "enable_guc", i915_modparams.enable_guc,
			 "GuC submission not supported");
		DRM_INFO("Switching to non-GuC submission mode!\n");
		i915_modparams.enable_guc &= ~ENABLE_GUC_SUBMISSION;
	}

147 148 149
	/* A negative value means "use platform/config default" */
	if (i915_modparams.guc_log_level < 0)
		i915_modparams.guc_log_level =
150
			__get_default_guc_log_level(i915);
151

152
	if (i915_modparams.guc_log_level > 0 && !intel_uc_is_using_guc(i915)) {
153 154
		DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
			 "guc_log_level", i915_modparams.guc_log_level,
155 156
			 !HAS_GUC(i915) ? "no GuC hardware" :
					  "GuC not enabled");
157 158 159
		i915_modparams.guc_log_level = 0;
	}

160
	if (i915_modparams.guc_log_level > GUC_LOG_LEVEL_MAX) {
161 162 163
		DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
			 "guc_log_level", i915_modparams.guc_log_level,
			 "verbosity too high");
164
		i915_modparams.guc_log_level = GUC_LOG_LEVEL_MAX;
165 166
	}

167
	DRM_DEBUG_DRIVER("guc_log_level=%d (enabled:%s, verbose:%s, verbosity:%d)\n",
168 169
			 i915_modparams.guc_log_level,
			 yesno(i915_modparams.guc_log_level),
170
			 yesno(GUC_LOG_LEVEL_IS_VERBOSE(i915_modparams.guc_log_level)),
171
			 GUC_LOG_LEVEL_TO_VERBOSITY(i915_modparams.guc_log_level));
172

173 174
	/* Make sure that sanitization was done */
	GEM_BUG_ON(i915_modparams.enable_guc < 0);
175
	GEM_BUG_ON(i915_modparams.guc_log_level < 0);
176 177
}

178
void intel_uc_init_early(struct drm_i915_private *i915)
179
{
180 181
	struct intel_guc *guc = &i915->guc;
	struct intel_huc *huc = &i915->huc;
182

183 184
	intel_guc_init_early(guc);
	intel_huc_init_early(huc);
185

186
	sanitize_options_early(i915);
187 188
}

189
void intel_uc_cleanup_early(struct drm_i915_private *i915)
190
{
191
	struct intel_guc *guc = &i915->guc;
192

193
	guc_free_load_err_log(guc);
194 195
}

196 197
/**
 * intel_uc_init_mmio - setup uC MMIO access
198
 * @i915: device private
199 200 201 202
 *
 * Setup minimal state necessary for MMIO accesses later in the
 * initialization sequence.
 */
203
void intel_uc_init_mmio(struct drm_i915_private *i915)
204
{
205
	intel_guc_init_send_regs(&i915->guc);
206 207
}

208 209
static void guc_capture_load_err_log(struct intel_guc *guc)
{
210
	if (!guc->log.vma || !intel_guc_log_get_level(&guc->log))
211 212 213 214 215 216 217 218 219 220 221 222 223 224
		return;

	if (!guc->load_err_log)
		guc->load_err_log = i915_gem_object_get(guc->log.vma->obj);

	return;
}

static void guc_free_load_err_log(struct intel_guc *guc)
{
	if (guc->load_err_log)
		i915_gem_object_put(guc->load_err_log);
}

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
/*
 * Events triggered while CT buffers are disabled are logged in the SCRATCH_15
 * register using the same bits used in the CT message payload. Since our
 * communication channel with guc is turned off at this point, we can save the
 * message and handle it after we turn it back on.
 */
static void guc_clear_mmio_msg(struct intel_guc *guc)
{
	intel_uncore_write(&guc_to_i915(guc)->uncore, SOFT_SCRATCH(15), 0);
}

static void guc_get_mmio_msg(struct intel_guc *guc)
{
	u32 val;

	spin_lock_irq(&guc->irq_lock);

	val = intel_uncore_read(&guc_to_i915(guc)->uncore, SOFT_SCRATCH(15));
	guc->mmio_msg |= val & guc->msg_enabled_mask;

	/*
	 * clear all events, including the ones we're not currently servicing,
	 * to make sure we don't try to process a stale message if we enable
	 * handling of more events later.
	 */
	guc_clear_mmio_msg(guc);

	spin_unlock_irq(&guc->irq_lock);
}

static void guc_handle_mmio_msg(struct intel_guc *guc)
{
	struct drm_i915_private *i915 = guc_to_i915(guc);

	/* we need communication to be enabled to reply to GuC */
	GEM_BUG_ON(guc->handler == intel_guc_to_host_event_handler_nop);

	if (!guc->mmio_msg)
		return;

	spin_lock_irq(&i915->irq_lock);
	intel_guc_to_host_process_recv_msg(guc, &guc->mmio_msg, 1);
	spin_unlock_irq(&i915->irq_lock);

	guc->mmio_msg = 0;
}

272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
static void guc_reset_interrupts(struct intel_guc *guc)
{
	guc->interrupts.reset(guc_to_i915(guc));
}

static void guc_enable_interrupts(struct intel_guc *guc)
{
	guc->interrupts.enable(guc_to_i915(guc));
}

static void guc_disable_interrupts(struct intel_guc *guc)
{
	guc->interrupts.disable(guc_to_i915(guc));
}

287 288
static int guc_enable_communication(struct intel_guc *guc)
{
289
	struct drm_i915_private *i915 = guc_to_i915(guc);
290 291 292 293 294 295 296 297 298
	int ret;

	ret = intel_guc_ct_enable(&guc->ct);
	if (ret)
		return ret;

	guc->send = intel_guc_send_ct;
	guc->handler = intel_guc_to_host_event_handler_ct;

299 300 301 302
	/* check for mmio messages received before/during the CT enable */
	guc_get_mmio_msg(guc);
	guc_handle_mmio_msg(guc);

303
	guc_enable_interrupts(guc);
304

305 306 307 308 309
	/* check for CT messages received before we enabled interrupts */
	spin_lock_irq(&i915->irq_lock);
	intel_guc_to_host_event_handler_ct(guc);
	spin_unlock_irq(&i915->irq_lock);

310 311 312
	DRM_INFO("GuC communication enabled\n");

	return 0;
313 314
}

315 316
static void guc_stop_communication(struct intel_guc *guc)
{
317
	intel_guc_ct_stop(&guc->ct);
318 319 320

	guc->send = intel_guc_send_nop;
	guc->handler = intel_guc_to_host_event_handler_nop;
321 322

	guc_clear_mmio_msg(guc);
323 324
}

325 326
static void guc_disable_communication(struct intel_guc *guc)
{
327 328 329 330 331 332 333
	/*
	 * Events generated during or after CT disable are logged by guc in
	 * via mmio. Make sure the register is clear before disabling CT since
	 * all events we cared about have already been processed via CT.
	 */
	guc_clear_mmio_msg(guc);

334
	guc_disable_interrupts(guc);
335

336
	guc->send = intel_guc_send_nop;
337
	guc->handler = intel_guc_to_host_event_handler_nop;
338 339 340

	intel_guc_ct_disable(&guc->ct);

341 342 343 344 345 346 347 348
	/*
	 * Check for messages received during/after the CT disable. We do not
	 * expect any messages to have arrived via CT between the interrupt
	 * disable and the CT disable because GuC should've been idle until we
	 * triggered the CT disable protocol.
	 */
	guc_get_mmio_msg(guc);

349
	DRM_INFO("GuC communication disabled\n");
350 351
}

352
void intel_uc_fetch_firmwares(struct drm_i915_private *i915)
353
{
354
	if (!USES_GUC(i915))
355
		return;
356

357
	intel_uc_fw_fetch(i915, &i915->guc.fw);
358

359 360
	if (USES_HUC(i915))
		intel_uc_fw_fetch(i915, &i915->huc.fw);
361 362
}

363
void intel_uc_cleanup_firmwares(struct drm_i915_private *i915)
364
{
365
	if (!USES_GUC(i915))
366 367
		return;

368
	if (USES_HUC(i915))
369
		intel_uc_fw_cleanup_fetch(&i915->huc.fw);
370

371
	intel_uc_fw_cleanup_fetch(&i915->guc.fw);
372 373
}

374
int intel_uc_init(struct drm_i915_private *i915)
375
{
376
	struct intel_guc *guc = &i915->guc;
377
	struct intel_huc *huc = &i915->huc;
378
	int ret;
379

380
	if (!USES_GUC(i915))
381 382
		return 0;

383
	if (!HAS_GUC(i915))
384
		return -ENODEV;
385

386 387 388
	/* XXX: GuC submission is unavailable for now */
	GEM_BUG_ON(USES_GUC_SUBMISSION(i915));

389 390
	ret = intel_guc_init(guc);
	if (ret)
391
		return ret;
392

393 394 395 396 397 398
	if (USES_HUC(i915)) {
		ret = intel_huc_init(huc);
		if (ret)
			goto err_guc;
	}

399
	if (USES_GUC_SUBMISSION(i915)) {
400 401 402 403
		/*
		 * This is stuff we need to have available at fw load time
		 * if we are planning to enable submission later
		 */
404
		ret = intel_guc_submission_init(guc);
405 406
		if (ret)
			goto err_huc;
407
	}
408

409
	return 0;
410 411 412 413 414 415 416

err_huc:
	if (USES_HUC(i915))
		intel_huc_fini(huc);
err_guc:
	intel_guc_fini(guc);
	return ret;
417 418
}

419
void intel_uc_fini(struct drm_i915_private *i915)
420
{
421
	struct intel_guc *guc = &i915->guc;
422

423
	if (!USES_GUC(i915))
424 425
		return;

426
	GEM_BUG_ON(!HAS_GUC(i915));
427

428
	if (USES_GUC_SUBMISSION(i915))
429 430
		intel_guc_submission_fini(guc);

431 432 433
	if (USES_HUC(i915))
		intel_huc_fini(&i915->huc);

434 435 436
	intel_guc_fini(guc);
}

437
static void __uc_sanitize(struct drm_i915_private *i915)
438 439 440 441 442 443 444 445 446 447 448 449
{
	struct intel_guc *guc = &i915->guc;
	struct intel_huc *huc = &i915->huc;

	GEM_BUG_ON(!HAS_GUC(i915));

	intel_huc_sanitize(huc);
	intel_guc_sanitize(guc);

	__intel_uc_reset_hw(i915);
}

450 451 452 453 454 455 456 457
void intel_uc_sanitize(struct drm_i915_private *i915)
{
	if (!USES_GUC(i915))
		return;

	__uc_sanitize(i915);
}

458
int intel_uc_init_hw(struct drm_i915_private *i915)
459
{
460 461
	struct intel_guc *guc = &i915->guc;
	struct intel_huc *huc = &i915->huc;
462 463
	int ret, attempts;

464
	if (!USES_GUC(i915))
465 466
		return 0;

467
	GEM_BUG_ON(!HAS_GUC(i915));
468

469
	guc_reset_interrupts(guc);
470

471 472
	/* WaEnableuKernelHeaderValidFix:skl */
	/* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
473
	if (IS_GEN(i915, 9))
474 475 476 477 478 479 480 481 482
		attempts = 3;
	else
		attempts = 1;

	while (attempts--) {
		/*
		 * Always reset the GuC just before (re)loading, so
		 * that the state and timing are fairly predictable
		 */
483
		ret = __intel_uc_reset_hw(i915);
484
		if (ret)
485
			goto err_out;
486

487
		if (USES_HUC(i915)) {
488
			ret = intel_huc_fw_upload(huc);
489
			if (ret)
490
				goto err_out;
491 492
		}

493
		intel_guc_ads_reset(guc);
494
		intel_guc_init_params(guc);
495
		ret = intel_guc_fw_upload(guc);
496
		if (ret == 0)
497 498 499 500 501 502 503 504
			break;

		DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
				 "retry %d more time(s)\n", ret, attempts);
	}

	/* Did we succeded or run out of retries? */
	if (ret)
505
		goto err_log_capture;
506

507 508
	ret = guc_enable_communication(guc);
	if (ret)
509
		goto err_log_capture;
510

511
	if (USES_HUC(i915)) {
512 513 514 515 516
		ret = intel_huc_auth(huc);
		if (ret)
			goto err_communication;
	}

517 518 519 520
	ret = intel_guc_sample_forcewake(guc);
	if (ret)
		goto err_communication;

521
	if (USES_GUC_SUBMISSION(i915)) {
522
		ret = intel_guc_submission_enable(guc);
523
		if (ret)
524
			goto err_communication;
525 526
	}

527
	dev_info(i915->drm.dev, "GuC firmware version %u.%u\n",
528
		 guc->fw.major_ver_found, guc->fw.minor_ver_found);
529 530 531 532
	dev_info(i915->drm.dev, "GuC submission %s\n",
		 enableddisabled(USES_GUC_SUBMISSION(i915)));
	dev_info(i915->drm.dev, "HuC %s\n",
		 enableddisabled(USES_HUC(i915)));
533

534 535 536 537 538
	return 0;

	/*
	 * We've failed to load the firmware :(
	 */
539 540
err_communication:
	guc_disable_communication(guc);
541 542
err_log_capture:
	guc_capture_load_err_log(guc);
543
err_out:
544 545
	__uc_sanitize(i915);

546 547 548 549 550 551
	/*
	 * Note that there is no fallback as either user explicitly asked for
	 * the GuC or driver default option was to run with the GuC enabled.
	 */
	if (GEM_WARN_ON(ret == -EIO))
		ret = -EINVAL;
552

553
	dev_err(i915->drm.dev, "GuC initialization failed %d\n", ret);
554 555 556
	return ret;
}

557
void intel_uc_fini_hw(struct drm_i915_private *i915)
558
{
559
	struct intel_guc *guc = &i915->guc;
560

561
	if (!intel_guc_is_loaded(guc))
562 563
		return;

564
	GEM_BUG_ON(!HAS_GUC(i915));
565

566
	if (USES_GUC_SUBMISSION(i915))
567
		intel_guc_submission_disable(guc);
568

569
	guc_disable_communication(guc);
570
	__uc_sanitize(i915);
571
}
572

573 574 575 576 577 578 579 580 581 582
/**
 * intel_uc_reset_prepare - Prepare for reset
 * @i915: device private
 *
 * Preparing for full gpu reset.
 */
void intel_uc_reset_prepare(struct drm_i915_private *i915)
{
	struct intel_guc *guc = &i915->guc;

583
	if (!intel_guc_is_loaded(guc))
584 585
		return;

586
	guc_stop_communication(guc);
587
	__uc_sanitize(i915);
588 589
}

C
Chris Wilson 已提交
590
void intel_uc_runtime_suspend(struct drm_i915_private *i915)
591 592 593 594
{
	struct intel_guc *guc = &i915->guc;
	int err;

595
	if (!intel_guc_is_loaded(guc))
596
		return;
597

C
Chris Wilson 已提交
598 599 600
	err = intel_guc_suspend(guc);
	if (err)
		DRM_DEBUG_DRIVER("Failed to suspend GuC, err=%d", err);
601

C
Chris Wilson 已提交
602 603 604 605 606 607 608 609
	guc_disable_communication(guc);
}

void intel_uc_suspend(struct drm_i915_private *i915)
{
	struct intel_guc *guc = &i915->guc;
	intel_wakeref_t wakeref;

610
	if (!intel_guc_is_loaded(guc))
C
Chris Wilson 已提交
611 612
		return;

613
	with_intel_runtime_pm(&i915->runtime_pm, wakeref)
C
Chris Wilson 已提交
614
		intel_uc_runtime_suspend(i915);
615 616 617 618 619 620 621
}

int intel_uc_resume(struct drm_i915_private *i915)
{
	struct intel_guc *guc = &i915->guc;
	int err;

622
	if (!intel_guc_is_loaded(guc))
623 624
		return 0;

625
	guc_enable_communication(guc);
626 627 628 629 630 631 632 633 634

	err = intel_guc_resume(guc);
	if (err) {
		DRM_DEBUG_DRIVER("Failed to resume GuC, err=%d", err);
		return err;
	}

	return 0;
}