This PERFORMANCE service group is used to manage the performance of a
group of devices or application processors that operate in the same performance
domain. Unlike traditional performance control mechanisms, where the OS is
responsible to directly controlling voltages and clocks, this mechanism instead
operates on an metric less integer performance scale. Each integer value on this
scale represents a performance operating point. What this scale represents and
the metric is entirely platform-dependent. Values on this scale are discrete,
and the platform has complete control over mapping these performance operating
points to performance states, which are eventually converted into hardware
parameters such as voltage and frequency. For example, the mapping between
levels and frequencies can be as straightforward as using a multiplication
factor of 1000
.
The CPPC service group is designed for performance control, but it is only intended for application processors. This service group is primarily meant for devices such as GPUs and accelerators, though it can also be used for application processors.
It is important to distinguish between performance domains and power domains. A performance domain refers to a set of devices that must always operate at the same performance level, whereas a power domain refers to a set of devices that can be turned on or off together for power management purposes.
The following table lists the services in the PERFORMANCE service group:
Service ID | Service Name | Request Type |
---|---|---|
0x01 |
PERF_ENABLE_NOTIFICATION |
NORMAL_REQUEST |
0x02 |
PERF_GET_NUM_DOMAINS |
NORMAL_REQUEST |
0x03 |
PERF_GET_ATTRIBUTES |
NORMAL_REQUEST |
0x04 |
PERF_GET_SUPPORTED_LEVELS |
NORMAL_REQUEST |
0x05 |
PERF_GET_LEVEL |
NORMAL_REQUEST |
0x06 |
PERF_SET_LEVEL |
NORMAL_REQUEST |
0x07 |
PERF_GET_LIMIT |
NORMAL_REQUEST |
0x08 |
PERF_SET_LIMIT |
NORMAL_REQUEST |
0x09 |
PERF_GET_FAST_CHANNEL_ATTRIBUTES |
NORMAL_REQUEST |
The following table shows the structure of a single performance level.
Word | Name | Description |
---|---|---|
0 |
CLOCK_FREQ |
Clock frequency (kHz) |
1 |
POWER_COST |
Power cost (uW) |
2 |
TRANSITION_LATENCY |
Transition latency (us) |
This section provides an overview of the properties associated with the fast-channel for PERFORMANCE service group.
- Supported Services
-
The fast-channel currently supports only the following PERFORMANCE services:
-
PERF_GET_LEVEL
-
PERF_SET_LEVEL
-
PERF_GET_LIMIT
-
PERF_SET_LIMIT
-
- Platform Dependency
-
-
Not all performance domains or performance services are required to support fast-channel functionality.
-
Support for fast-channel depends on the platform implementation.
-
- Discovering Fast-channel
-
-
Fast-channels support are discoverable through PERFORMANCE service calls.
-
To determine if a platform supports fast-channel for a specific performance domain, use the
PERF_GET_ATTRIBUTES
service call. -
If fast-channel support is available, retrieve fast-channel attributes for specific PERFORMANCE service call using the
PERF_GET_FAST_CHANNEL_ATTRIBUTES
service call.
-
- Doorbell Support
-
-
Doorbell support is not available for
PERF_GET_LEVEL
andPERF_GET_LIMIT
service calls. -
When fast-channels are implemented for
PERF_GET_LEVEL
andPERF_GET_LIMIT
service calls, the last known valid performance level or performance limits are always accessible via the fast-channel without requiring a doorbell trigger. -
For other PERFORMANCE service calls that support fast-channel, doorbell support is optional.
-
- Payload Requirements
-
-
The payload of a fast-channel should exclusively include message specific parameters and exclude the
DOMAIN_ID
. Since a fast-channel is specific to bothDOMAIN_ID
andSERVICE_ID
, there is no need to includeDOMAIN_ID
or any other channel specific and message specific headers when using a fast-channel. For instance, the payload of thePERF_SET_LIMIT
message should consist of a 32-bitMAX_PERF_LEVEL
and a 32-bitMIN_PERF_LEVEL
.
-
When a client registers for performance change notifications, the platform will send notification to the client whenever there is a change in the performance level, performance limit or the performance power of a specific performance domain. This notification is typically sent by the platform microcontroller to inform clients in the system about changes in the performance domain.
Event ID | Name | Event Data | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x01 |
PERF_POWER_CHANGE |
|
Performance power changed notification. |
||||||||||||
0x02 |
PERF_LIMIT_CHANGE |
|
Performance limit changed notification. |
||||||||||||
0x03 |
PERF_LEVEL_CHANGE |
|
Performance level changed notification. |
This service allows the application processor to subscribe to PERFORMANCE
service group notifications. The platform may optionally support notifications
for events that may occur. The platform microcontroller can send these
notification messages to the application processor if they are implemented and
the application processor has subscribed to them. The supported events are
described in Notifications.
Word | Name | Type | Description |
---|---|---|---|
0 |
EVENT_ID |
uint32 |
The event to be subscribed for notification. |
1 |
REQ_STATE |
uint32 |
Requested event notification state 0: Disable 1: Enable 2: Return current state. Any other values of |
Word | Name | Type | Description | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
0 |
STATUS |
int32 |
Return error code
|
||||||||
1 |
CURRENT_STATE |
uint32 |
Current 0: Notification is disabled 1: Notification is enabled. In case of |
This service returns the number of performance domains supported by the system. The number of performance domains may vary depending on the hardware platform and its implementation. In general, performance domains are used to group related hardware components, such as CPUs, GPUs, memory, and peripherals, into separate domains that can be independently controlled and managed. This allows for more fine-grained control over the performance of specific components, which can be important for optimizing system performance and power consumption.
NA |
---|
Word | Name | Type | Description | ||||
---|---|---|---|---|---|---|---|
0 |
STATUS |
int32 |
Return error code
|
||||
1 |
NUM_DOMAINS |
uint32 |
Number of performance domains. |
This service is used to retrieve the attributes of a specific performance domain. These attributes provide information about the performance capabilities and constraints of the domain, such as the performance limit and performance level.
Word | Name | Type | Description |
---|---|---|---|
0 |
DOMAIN_ID |
uint32 |
Performance domain ID |
Word | Name | Type | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 |
STATUS |
int32 |
Return error code
|
||||||||||||
1 |
FLAGS |
uint32 |
|
||||||||||||
2 |
RATE_LIMIT_US |
uint32 |
Minimum amount of time that needs to pass between two consecutive requests, in microseconds (us). |
||||||||||||
3:6 |
DOMAIN_NAME |
uint8[16] |
Performance domain name, a NULL-terminated ASCII string up to 16-bytes. |
This service provides a list of the available performance levels or also called operating performance points (OPPs) for a specific performance domain. These represent different performance levels that can be set for the components in the domain, and are defined by a combination of frequency, power cost and other parameters. By using this information, the OS can select the optimal performance level based on the system’s workload and power constraints.
/* Pseudocode to retrieve the list of the supported performance levels. */
index = 0;
num = 0;
/* Allocate a buffer based on the value returned from the flags[7:0] */
total_num_levels = perf_domain_attributes.flags[7:0];
loop:
list = get_domain_opp_list(index, domain_id);
entry_num = 0;
for (i = 0; i < list.returned; i++, num++) {
opp[num].freq = list.entry[entry_num++];
opp[num].power = list.entry[entry_num++];
opp[num].rate_limit = list.entry[entry_num++];
}
/* Check if there are remaining OPP to be read */
if (list.remaining) {
index += list.returned;
goto loop;
}
The pseudocode above demonstrates the process for retrieving the level
information for a specific performance domain. First, the number of
performance levels is determined by checking the FLAGS[7:0]
parameter
returned by the PERF_GET_ATTRIBUTES
service.
The total number of performance levels included in one message must not exceed
the available word count in the message’s DATA
field. If the performance levels
exceed this limit, the platform microcontroller will return the number of
levels that can be accommodated in one message and set the REMAINING
field
accordingly. When the REMAINING
field is not zero, the application processor
must call this service again with the appropriate PERF_LEVEL_INDEX
to retrieve
the remaining levels. Multiple service calls may be required to obtain all the
levels.
Word | Name | Type | Description |
---|---|---|---|
0 |
DOMAIN_ID |
uint32 |
Performance domain ID |
1 |
PERF_LEVEL_INDEX |
uint32 |
Start array index to read. The first index starts at zero. |
Word | Name | Type | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
0 |
STATUS |
int32 |
Return error code
|
||||||
1 |
FLAGS |
uint32 |
Reserved and must be |
||||||
2 |
REMAINING |
uint32 |
Remaining number of levels (number of arrays). |
||||||
3 |
RETURNED |
uint32 |
Number of levels returned (number of arrays). |
||||||
4 |
LEVEL[N] |
uint32[3] |
List of performance levels. Refer to Performance Level for the structure of performance level. |
This service is used to obtain the current performance level of a specific performance domain in the system.
Word | Name | Type | Description |
---|---|---|---|
0 |
DOMAIN_ID |
uint32 |
Performance domain ID |
Word | Name | Type | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
0 |
STATUS |
int32 |
Return error code
|
||||||
1 |
LEVEL |
uint32 |
Current performance level of the domain. |
This service is used to set the current performance level of a specific performance domain in the system.
Word | Name | Type | Description |
---|---|---|---|
0 |
DOMAIN_ID |
uint32 |
Performance domain ID |
1 |
LEVEL |
uint32 |
Performance level |
Word | Name | Type | Description | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 |
STATUS |
int32 |
Return error code
|
This service is used to obtain the current performance limit of a specific performance domain in the system.
Word | Name | Type | Description |
---|---|---|---|
0 |
DOMAIN_ID |
uint32 |
Performance domain ID |
Word | Name | Type | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
0 |
STATUS |
int32 |
Return error code
|
||||||
1 |
MAX_PERF_LEVEL |
uint32 |
Maximum allowed performance level. |
||||||
2 |
MIN_PERF_LEVEL |
uint32 |
Minimum allowed performance level. |
This service is used to set the performance limit of a specific performance domain in the system.
Word | Name | Type | Description |
---|---|---|---|
0 |
DOMAIN_ID |
uint32 |
Performance domain ID |
1 |
MAX_PERF_LEVEL |
uint32 |
Maximum allowed performance level. |
2 |
MIN_PERF_LEVEL |
uint32 |
Minimum allowed performance level. |
Word | Name | Type | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 |
STATUS |
int32 |
Return error code
|
This service allows clients to query attributes of the fast-channel for a specific performance domain and performance service.
Word | Name | Type | Description |
---|---|---|---|
0 |
DOMAIN_ID |
uint32 |
Performance domain ID |
1 |
SERVICE_ID |
uint32 |
Performance Service ID, see service ID in PERFORMANCE Services |
Word | Name | Type | Description | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
0 |
STATUS |
int32 |
Return error code
|
||||||||
1 |
FLAGS |
uint32 |
|
||||||||
2 |
PHYS_ADDR_LOW |
uint32 |
Lower 32-bit of physical address. |
||||||||
3 |
PHYS_ADDR_HIGH |
uint32 |
Upper 32-bit of physical address. |
||||||||
4 |
DB_ADDR_LOW |
uint32 |
Lower 32-bit of doorbell address. This field is unused if the doorbell is not supported. |
||||||||
5 |
DB_ADDR_HIGH |
uint32 |
Upper 32-bit of doorbell address. This field is unused if the doorbell is not supported. |
||||||||
6 |
DB_ID_LOW |
uint32 |
Lower 32-bit of doorbell ID. This field is unused if the doorbell is not supported. |
||||||||
7 |
DB_ID_HIGH |
uint32 |
Upper 32-bit of doorbell ID. This field is unused if the doorbell is not supported. |
||||||||
8 |
DB_PRESERVED_LOW |
uint32 |
A lower 32-bit doorbell preserved mask to apply for this service before ringing the doorbell. This field is unused if the doorbell is not supported. |
||||||||
9 |
DB_PRESERVED_HIGH |
uint32 |
An upper 32-bit doorbell preserved mask to apply for this service before ringing the doorbell. This field is only valid if the doorbell register width is 64-bit. This field is unused if the doorbell is not supported. |