ACPI defines performance states for processors and devices but only provides standard bindings for processor performance states via P-States and CPPC bindings. For devices, performance states are defined by the buses like PCIe, USB, etc., and no standard bindings are defined by ACPI.
In this section, we are exploring generic ACPI-related bindings to define performance states for platform devices.
ACPI Definition for Device Performance States
From section 2.3.1 Device Performance States:
Device performance states (Px states) are power consumption and capability states within the active (D0) device power state. Performance states allow OSPM to make tradeoffs between performance and energy conservation. Device performance states have the greatest impact when the implementation is such that the states invoke different device efficiency levels as opposed to a linear scaling of performance and energy consumption. Since performance state transitions occur in the active device states, care must be taken to ensure that performance state transitions do not adversely impact the system. Device performance states, when necessary, are defined on a per device class basis (See Appendix A: Device Class Specifications for more information).
ACPI Device Performance States Proposal
_DPT
ACPI object to describe polling time in milliseconds.
This will be the frequency at which the OSPM will poll the device and change the performance states.
_DPS
ACPI object to get supported device performance states (Px)
The format of each Px state is defined as follows
...
Device Frequency
...
Device core frequency in MHz
...
Power
...
Power dissipation in Milliwatts
...
Latency
...
Performance state transition latency in nanoseconds
Code Block |
---|
Name (_DPS, Package()
{
P0,
P1,
...
Pn
}) |
Device Frequency and Power are only indica’s current utilization in percentage.
Code Block |
---|
Method(_DUT, 0, Serialized)
{
....
} |
_DPA
OSPM can use this method to check the available device performance levels.
Code Block |
---|
Method(_DPA, 0, Serialized)
{
Return <available starting Px index>
}
|
_DPA will return the first available Px index that OSPM can use for dynamic performance level setting.
_DPD
OSPM can use this method to get the delivered performance level.
Code Block |
---|
Method(_DPD)
{
Return <Px index>
} |
This method is optional if there are other ways for OSPM to derive delivered performance. For example, if ClockInput resources are provided for the device in _CRS method then OSPM can utilize that to know the delivered performance.
Example with I.MX8MP DDR Controller
Device utilization is derived from PMU counters.
TF-A implements functions that can be invoked from AML via FFH/SMCC to collect the device utilization and configure the DDR frequency.
ASL Code
...
This page captures some of the new proposals to ACPI to support device performance states.
The changes have been prototyped with Linux kernel DVFS framework and have not yet been discussed on public forums yet.
Device Performance States
Device performance states support is implemented through two optional objects
Device Performance Control Object ( _DPC )
Device Performance States Object ( _DPS )
If the platform and device support multiple performance states then the above two objects should be implemented for the device.
Device Performance Control Object ( _DPC )
_DPC provides the binding to place the device in a specific performance state along with various metadata.
Arguments:
None
Returns:
A package containing performance control information for the device.
Code Block |
---|
Package { NumEntries, Name (_HID, "NXP099") // _HID:Integer Hardware ID Revision, Name (_UID, One) // _UID:Integer Unique ID NominalPerformance, // Integer or MethodBuffer (_STAResource Descriptor) NominalFrequency, { // Integer or Buffer Return(0xF(Resource Descriptor) DesiredPerformance, // }Buffer (Resource Descriptor) DeliveredPerformance, // MethodBuffer (_CRS, 0x0, NotSerializedResource Descriptor) SustainedPerformance, // Buffer (Resource {Descriptor) PerformanceDomain, // Integer or NameBuffer (Resource RBUF, ResourceTemplate () { ClockInput(100000, 1, Hz, Variable, “\\_SB.CLK”,) }) Return(RBUF) } // Polling time in miliseconds Name(_DPT, 12) // Get Device Performance States Name (_DPS, Package() Descriptor) }) |
Element | Object Type | Description |
---|---|---|
Num Entries | Integer | Number of entries in the _DPC package |
Revision | Integer | Revision number |
Nominal Performance | Integer or Register Buffer | Performance level value that corresponds to the highest sustained performance level without considering any contraints. |
Nominal Frequency | Integer or Register Buffer | Base frequency (KHz) corresponding to the nominal performance level. |
Desired Performance | Register Buffer | Register to write the desired performance level. |
Delivered Performance | Register Buffer | Register to read to get the current delivered performance level. |
Sustained Performance | Register Buffer | This is an optional object providing OSPM the current maximum sustained performance level taking into account all known external constraints (power budgeting, thermal constraints, power source, etc.). A notify event will generated by the platform if the sustained performance changes. |
Performance Domain | Integer or Register Buffer | This is an optional object providing the performance domain identifier. OSPM can use this to coordinate performance states transition for devices in same performance domain. |
All _DPC registers can be in PCC, System Memory, System IO, or Functional Fixed Hardware address spaces.
Device Performance States Object ( _DPS )
_DPS defines all of the supported device performance states for the device.
Arguments:
None
Returns:
A variable-length Package containing a list of performance states sub-packages as described below
Code Block |
---|
Package { P0, Package(){200, 1800 P1, 100}, // Performance State zero (P0) ... Package(){400, 1800, 100}, // Performance State zero (P1) Pn }) |
Each performance state sub-Package contains the elements described below:
Performance Level | Performance level provided on an abstract integer scale. The implementation can decide the scale it represents, it can be actual frequencies or in percentage of the maximum performance domain etc. However, the scales must be linear. |
Power | Power dissipation in Milliwatts |
Latency | Performance state transition latency in microseconds |
Example
Code Block |
---|
Device(DDR1) { |
...
Name (_HID, "LIN0002") // |
...
_HID: |
...
Hardware |
...
ID |
...
Name |
...
(_UID, One) // |
...
_UID: |
...
Unique |
...
ID |
...
|
...
Method (_STA) { |
...
Return(0xF) |
...
} // Device performance |
...
states |
...
|
...
Name |
...
(_DPS, Package() { |
...
|
...
|
...
/* performance level(abstract), power cost(mW), transition latency(us) */ |
...
|
...
|
...
Package(){25, |
...
1800, 0}, |
...
|
...
|
...
|
...
Package(){100, 1800, 0}, |
...
|
...
Package(){750, 1800, 0} |
...
}) Name |
...
(_DPC, Package () { |
...
|
...
|
...
// |
...
Num Entries |
...
9, |
...
|
...
|
...
|
...
// |
...
Revision |
...
0, |
...
|
...
|
...
// |
...
Nominal Performance (abstract scale) - Highest sustained performance level 750, |
...
|
...
// |
...
Nominal Frequency (KHz) |
...
750000, // |
...
Desired |
...
Performance Register |
...
ResourceTemplate(){Register(FFixedHW, |
...
0, |
...
0, |
...
0xFFFFFFFFC200000E)}, // Delivered |
...
Performance Register |
...
ResourceTemplate(){Register(FFixedHW, 0, 0, 0xFFFFFFFFC200000F)}, |
...
|
...
|
...
// Sustained |
...
Performance Level Register (Optional) - Current max. perf considering all constraints |
...
|
...
|
...
|
...
|
...
|
...
ResourceTemplate(){Register(FFixedHW, 0, 0, 0xFFFFFFFFC2000011)}, // |
...
Performance |
...
Domain Index (Optional) |
...
1, }) |
...
} |
Linux Kernel Prototype
The changes are currently in the following merge request
https://gitlab.com/LinaroLtd/clientpc/linux/-/merge_requests/10
It contains following changes
Prototype implementation of device performance state framework
An example implementation of I.MX DDR DevFreq driver with ACPI device performance states
Bug fixes to Linux OPP framework
Note: The prototype uses a specific FFH address space for SMC calls and is not part of ARM FFH spec yet.