drivers/accel/ivpu/ivpu_pm.c

Source file repositories/reference/linux-study-clean/drivers/accel/ivpu/ivpu_pm.c

File Facts

System
Linux kernel
Corpus path
drivers/accel/ivpu/ivpu_pm.c
Extension
.c
Size
12867 bytes
Lines
524
Domain
Driver Families
Bucket
drivers/accel
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 (time_after_eq(jiffies, timeout)) {
			ivpu_err(vdev, "Failed to enter idle on system suspend\n");
			return -EBUSY;
		}
	}

	ivpu_jsm_pwr_d0i3_enter(vdev);

	ivpu_suspend(vdev);
	ivpu_pm_prepare_warm_boot(vdev);

	ivpu_dbg(vdev, PM, "Suspend done.\n");
	trace_pm("suspend done");

	return 0;
}

int ivpu_pm_resume_cb(struct device *dev)
{
	struct drm_device *drm = dev_get_drvdata(dev);
	struct ivpu_device *vdev = to_ivpu_device(drm);
	int ret;

	trace_pm("resume");
	ivpu_dbg(vdev, PM, "Resume..\n");

	ret = ivpu_resume(vdev);
	if (ret)
		ivpu_err(vdev, "Failed to resume: %d\n", ret);

	ivpu_dbg(vdev, PM, "Resume done.\n");
	trace_pm("resume done");

	return ret;
}

int ivpu_pm_runtime_suspend_cb(struct device *dev)
{
	struct drm_device *drm = dev_get_drvdata(dev);
	struct ivpu_device *vdev = to_ivpu_device(drm);
	int ret, ret_d0i3;
	bool is_idle;

	drm_WARN_ON(&vdev->drm, !xa_empty(&vdev->submitted_jobs_xa));
	drm_WARN_ON(&vdev->drm, work_pending(&vdev->pm->recovery_work));

	trace_pm("runtime suspend");
	ivpu_dbg(vdev, PM, "Runtime suspend..\n");

	ivpu_mmu_disable(vdev);

	is_idle = ivpu_hw_is_idle(vdev) || vdev->pm->dct_active_percent;
	if (!is_idle)
		ivpu_err(vdev, "NPU is not idle before autosuspend\n");

	ret_d0i3 = ivpu_jsm_pwr_d0i3_enter(vdev);
	if (ret_d0i3)
		ivpu_err(vdev, "Failed to prepare for d0i3: %d\n", ret_d0i3);

	ret = ivpu_suspend(vdev);
	if (ret)
		ivpu_err(vdev, "Failed to suspend NPU: %d\n", ret);

	if (!is_idle || ret_d0i3) {
		ivpu_err(vdev, "Forcing cold boot due to previous errors\n");
		atomic_inc(&vdev->pm->reset_counter);
		ivpu_dev_coredump(vdev);
		ivpu_pm_prepare_cold_boot(vdev);
	} else {
		ivpu_pm_prepare_warm_boot(vdev);
	}

	ivpu_dbg(vdev, PM, "Runtime suspend done.\n");
	trace_pm("runtime suspend done");

	return 0;
}

int ivpu_pm_runtime_resume_cb(struct device *dev)
{
	struct drm_device *drm = dev_get_drvdata(dev);
	struct ivpu_device *vdev = to_ivpu_device(drm);
	int ret;

	trace_pm("runtime resume");
	ivpu_dbg(vdev, PM, "Runtime resume..\n");

	ret = ivpu_resume(vdev);
	if (ret)
		ivpu_err(vdev, "Failed to set RESUME state: %d\n", ret);

Annotation

Implementation Notes