drivers/gpu/drm/i915/gt/intel_gt_pm.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gt/intel_gt_pm.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gt/intel_gt_pm.c
Extension
.c
Size
10522 bytes
Lines
435
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (err) {
			gt_err(gt, "Failed to restart %s (%d)\n",
			       engine->name, err);
			goto err_wedged;
		}
	}

	intel_rc6_enable(&gt->rc6);

	intel_uc_resume(&gt->uc);

	user_forcewake(gt, false);

out_fw:
	intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL);
	intel_gt_pm_put(gt, wakeref);
	intel_gt_bind_context_set_ready(gt);
	return err;

err_wedged:
	intel_gt_set_wedged(gt);
	goto out_fw;
}

static void wait_for_suspend(struct intel_gt *gt)
{
	if (!intel_gt_pm_is_awake(gt))
		return;

	if (intel_gt_wait_for_idle(gt, I915_GT_SUSPEND_IDLE_TIMEOUT) == -ETIME) {
		/*
		 * Forcibly cancel outstanding work and leave
		 * the gpu quiet.
		 */
		intel_gt_set_wedged(gt);
		intel_gt_retire_requests(gt);
	}

	intel_gt_pm_wait_for_idle(gt);
}

void intel_gt_suspend_prepare(struct intel_gt *gt)
{
	intel_gt_bind_context_set_unready(gt);
	user_forcewake(gt, true);
	wait_for_suspend(gt);
}

static suspend_state_t pm_suspend_target(void)
{
#if IS_ENABLED(CONFIG_SUSPEND) && IS_ENABLED(CONFIG_PM_SLEEP)
	return pm_suspend_target_state;
#else
	return PM_SUSPEND_TO_IDLE;
#endif
}

void intel_gt_suspend_late(struct intel_gt *gt)
{
	intel_wakeref_t wakeref;

	/* We expect to be idle already; but also want to be independent */
	wait_for_suspend(gt);

	if (is_mock_gt(gt))
		return;

	GEM_BUG_ON(gt->awake);

	intel_uc_suspend(&gt->uc);

	/*
	 * On disabling the device, we want to turn off HW access to memory
	 * that we no longer own.
	 *
	 * However, not all suspend-states disable the device. S0 (s2idle)
	 * is effectively runtime-suspend, the device is left powered on
	 * but needs to be put into a low power state. We need to keep
	 * powermanagement enabled, but we also retain system state and so
	 * it remains safe to keep on using our allocated memory.
	 */
	if (pm_suspend_target() == PM_SUSPEND_TO_IDLE)
		return;

	with_intel_runtime_pm(gt->uncore->rpm, wakeref) {
		intel_rps_disable(&gt->rps);
		intel_rc6_disable(&gt->rc6);
		intel_llc_disable(&gt->llc);
	}

Annotation

Implementation Notes