Runtime Power Management

Xe PM implements the main routines for both system level suspend states andfor the opportunistic runtime suspend states.

System Level Suspend (S-States) - In general this is OS initiated suspenddriven by ACPI for achieving S0ix (a.k.a. S2idle, freeze), S3 (suspend to ram),S4 (disk). The main functions here arexe_pm_suspend andxe_pm_resume. Theyare the main point for the suspend to and resume from these states.

PCI Device Suspend (D-States) - This is the opportunistic PCIe device low powerstate D3, controlled by the PCI subsystem and ACPI with the help from theruntime_pm infrastructure.PCI D3 is special and can mean D3hot, where Vcc power is on for keeping memoryalive and quicker low latency resume or D3Cold where Vcc power is off forbetter power savings.The Vcc control of PCI hierarchy can only be controlled at the PCI root portlevel, while the device driver can be behind multiple bridges/switches andpaired with other devices. For this reason, the PCI subsystem cannot performthe transition towards D3Cold. The lowest runtime PM possible from the PCIsubsystem is D3hot. Then, if all these paired devices in the same root portare in D3hot, ACPI will assist here and run its own methods (_PR3 and _OFF)to perform the transition from D3hot to D3cold. Xe may disallow thistransition by calling pci_d3cold_disable(root_pdev) before going to runtimesuspend. It will be based on runtime conditions such as VRAM usage for aquick and low latency resume for instance.

Runtime PM - This infrastructure provided by the Linux kernel allows thedevice drivers to indicate when the can be runtime suspended, so the devicecould be put at D3 (if supported), or allow deeper package sleep states(PC-states), and/or other low level power states. Xe PM component providesxe_pm_runtime_suspend andxe_pm_runtime_resume functions that PCIsubsystem will call before transition to/from runtime suspend.

Also, Xe PM provides get and put functions that Xe driver will use toindicate activity. In order to avoid locking complications with the memorymanagement, whenever possible, these get and put functions needs to be calledfrom the higher/outer levels.The main cases that need to be protected from the outer levels are: IOCTL,sysfs, debugfs, dma-buf sharing, GPU execution.

This component is not responsible for GT idleness (RC6) nor GT frequencymanagement (RPS).

Internal API

voidxe_pm_might_block_on_suspend(void)

Annotate that the code might block on suspend

Parameters

void

no arguments

Description

Annotation to use where the code might block or seize to makeprogress pending resume completion.

intxe_pm_block_on_suspend(structxe_device*xe)

Block pending suspend.

Parameters

structxe_device*xe

The xe device about to be suspended.

Description

Block if the pm notifier has start evicting bos, to avoidracing and validating those bos back. The function isannotated to ensure no locks are held that are also grabbedin the pm notifier or the device suspend / resume.This is intended to be used by freezable tasks only.(Not freezable workqueues), with the intention that the functionreturns-ERESTARTSYS when tasks are frozen during suspend,and allows the task to freeze. The caller must be able tohandle the-ERESTARTSYS.

Return

0 on success,-ERESTARTSYS on signal pending orif freezing requested.

boolxe_rpm_reclaim_safe(conststructxe_device*xe)

Whether runtime resume can be done from reclaim context

Parameters

conststructxe_device*xe

The xe device.

Return

true if it is safe to runtime resume from reclaim context.false otherwise.

intxe_pm_suspend(structxe_device*xe)

Helper for System suspend, i.e. S0->S3 / S0->S2idle

Parameters

structxe_device*xe

xe device instance

Return

0 on success

intxe_pm_resume(structxe_device*xe)

Helper for System resume S3->S0 / S2idle->S0

Parameters

structxe_device*xe

xe device instance

Return

0 on success

intxe_pm_init(structxe_device*xe)

Initialize Xe Power Management

Parameters

structxe_device*xe

xe device instance

Description

This component is responsible for System and Device sleep states.

Returns 0 for success, negative error code otherwise.

voidxe_pm_fini(structxe_device*xe)

Finalize PM

Parameters

structxe_device*xe

xe device instance

boolxe_pm_runtime_suspended(structxe_device*xe)

Check if runtime_pm state is suspended

Parameters

structxe_device*xe

xe device instance

Description

This does not provide any guarantee that the device is going to remainsuspended as it might be racing with the runtime state transitions.It can be used only as a non-reliable assertion, to ensure that we are not inthe sleep state while trying to access some memory for instance.

Returns true if PCI device is suspended, false otherwise.

intxe_pm_runtime_suspend(structxe_device*xe)

Prepare our device for D3hot/D3Cold

Parameters

structxe_device*xe

xe device instance

Description

Returns 0 for success, negative error code otherwise.

intxe_pm_runtime_resume(structxe_device*xe)

Waking up from D3hot/D3Cold

Parameters

structxe_device*xe

xe device instance

Description

Returns 0 for success, negative error code otherwise.

voidxe_pm_runtime_get(structxe_device*xe)

Get a runtime_pm reference and resume synchronously

Parameters

structxe_device*xe

xe device instance

Description

When possible, scope-based runtime PM (through guard(xe_pm_runtime)) isbe preferred over direct usage of this function. Manual get/put handlingshould only be used when the function contains goto-based logic whichcan break scope-based handling, or when the lifetime of the runtime PMreference does not match a specific scope (e.g., runtime PM obtained in onefunction and released in a different one).

voidxe_pm_runtime_put(structxe_device*xe)

Put the runtime_pm reference back and mark as idle

Parameters

structxe_device*xe

xe device instance

intxe_pm_runtime_get_ioctl(structxe_device*xe)

Get a runtime_pm reference before ioctl

Parameters

structxe_device*xe

xe device instance

Description

When possible, scope-based runtime PM (throughACQUIRE(xe_pm_runtime_ioctl, ...)) is be preferred over direct usage of thisfunction. Manual get/put handling should only be used when the functioncontains goto-based logic which can break scope-based handling, or when thelifetime of the runtime PM reference does not match a specific scope (e.g.,runtime PM obtained in one function and released in a different one).

Return

Any number greater than or equal to 0 for success, negative errorcode otherwise.

boolxe_pm_runtime_get_if_active(structxe_device*xe)

Get a runtime_pm reference if device active

Parameters

structxe_device*xe

xe device instance

Return

True if device is awake (regardless the previous number of references)and a new reference was taken, false otherwise.

boolxe_pm_runtime_get_if_in_use(structxe_device*xe)

Get a new reference if device is active with previous ref taken

Parameters

structxe_device*xe

xe device instance

Return

True if device is awake, a previous reference had been already taken,and a new reference was now taken, false otherwise.

voidxe_pm_runtime_get_noresume(structxe_device*xe)

Bump runtime PM usage counter without resuming

Parameters

structxe_device*xe

xe device instance

Description

This function should be used in inner places where it is surely alreadyprotected by outer-bound callers ofxe_pm_runtime_get.It will warn if not protected.The reference should be put back after this function regardless, since itwill always bump the usage counter, regardless.

When possible, scope-based runtime PM (through guard(xe_pm_runtime_noresume))is be preferred over direct usage of this function. Manual get/put handlingshould only be used when the function contains goto-based logic which canbreak scope-based handling, or when the lifetime of the runtime PM referencedoes not match a specific scope (e.g., runtime PM obtained in one functionand released in a different one).

boolxe_pm_runtime_resume_and_get(structxe_device*xe)

Resume, then get a runtime_pm ref if awake.

Parameters

structxe_device*xe

xe device instance

Return

True if device is awake and the reference was taken, false otherwise.

voidxe_pm_assert_unbounded_bridge(structxe_device*xe)

Disable PM on unbounded pcie parent bridge

Parameters

structxe_device*xe

xe device instance

intxe_pm_set_vram_threshold(structxe_device*xe,u32threshold)

Set a VRAM threshold for allowing/blocking D3Cold

Parameters

structxe_device*xe

xe device instance

u32threshold

VRAM size in MiB for the D3cold threshold

Return

  • 0 - success

  • -EINVAL
    • invalid argument

voidxe_pm_d3cold_allowed_toggle(structxe_device*xe)

Check conditions to toggle d3cold.allowed

Parameters

structxe_device*xe

xe device instance

Description

To be called during runtime_pm idle callback.Check for all the D3Cold conditions ahead of runtime suspend.

intxe_pm_module_init(void)

Perform xe_pm specific module initialization.

Parameters

void

no arguments

Return

0 on success. Currently doesn’t fail.