162306a36Sopenharmony_ci=============================== 262306a36Sopenharmony_ciPM Quality Of Service Interface 362306a36Sopenharmony_ci=============================== 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciThis interface provides a kernel and user mode interface for registering 662306a36Sopenharmony_ciperformance expectations by drivers, subsystems and user space applications on 762306a36Sopenharmony_cione of the parameters. 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciTwo different PM QoS frameworks are available: 1062306a36Sopenharmony_ci * CPU latency QoS. 1162306a36Sopenharmony_ci * The per-device PM QoS framework provides the API to manage the 1262306a36Sopenharmony_ci per-device latency constraints and PM QoS flags. 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciThe latency unit used in the PM QoS framework is the microsecond (usec). 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci1. PM QoS framework 1862306a36Sopenharmony_ci=================== 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ciA global list of CPU latency QoS requests is maintained along with an aggregated 2162306a36Sopenharmony_ci(effective) target value. The aggregated target value is updated with changes 2262306a36Sopenharmony_cito the request list or elements of the list. For CPU latency QoS, the 2362306a36Sopenharmony_ciaggregated target value is simply the min of the request values held in the list 2462306a36Sopenharmony_cielements. 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ciNote: the aggregated target value is implemented as an atomic variable so that 2762306a36Sopenharmony_cireading the aggregated value does not require any locking mechanism. 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ciFrom kernel space the use of this interface is simple: 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_civoid cpu_latency_qos_add_request(handle, target_value): 3262306a36Sopenharmony_ci Will insert an element into the CPU latency QoS list with the target value. 3362306a36Sopenharmony_ci Upon change to this list the new target is recomputed and any registered 3462306a36Sopenharmony_ci notifiers are called only if the target value is now different. 3562306a36Sopenharmony_ci Clients of PM QoS need to save the returned handle for future use in other 3662306a36Sopenharmony_ci PM QoS API functions. 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_civoid cpu_latency_qos_update_request(handle, new_target_value): 3962306a36Sopenharmony_ci Will update the list element pointed to by the handle with the new target 4062306a36Sopenharmony_ci value and recompute the new aggregated target, calling the notification tree 4162306a36Sopenharmony_ci if the target is changed. 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_civoid cpu_latency_qos_remove_request(handle): 4462306a36Sopenharmony_ci Will remove the element. After removal it will update the aggregate target 4562306a36Sopenharmony_ci and call the notification tree if the target was changed as a result of 4662306a36Sopenharmony_ci removing the request. 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ciint cpu_latency_qos_limit(): 4962306a36Sopenharmony_ci Returns the aggregated value for the CPU latency QoS. 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ciint cpu_latency_qos_request_active(handle): 5262306a36Sopenharmony_ci Returns if the request is still active, i.e. it has not been removed from the 5362306a36Sopenharmony_ci CPU latency QoS list. 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ciint cpu_latency_qos_add_notifier(notifier): 5662306a36Sopenharmony_ci Adds a notification callback function to the CPU latency QoS. The callback is 5762306a36Sopenharmony_ci called when the aggregated value for the CPU latency QoS is changed. 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ciint cpu_latency_qos_remove_notifier(notifier): 6062306a36Sopenharmony_ci Removes the notification callback function from the CPU latency QoS. 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ciFrom user space: 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciThe infrastructure exposes one device node, /dev/cpu_dma_latency, for the CPU 6662306a36Sopenharmony_cilatency QoS. 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ciOnly processes can register a PM QoS request. To provide for automatic 6962306a36Sopenharmony_cicleanup of a process, the interface requires the process to register its 7062306a36Sopenharmony_ciparameter requests as follows. 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciTo register the default PM QoS target for the CPU latency QoS, the process must 7362306a36Sopenharmony_ciopen /dev/cpu_dma_latency. 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ciAs long as the device node is held open that process has a registered 7662306a36Sopenharmony_cirequest on the parameter. 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ciTo change the requested target value, the process needs to write an s32 value to 7962306a36Sopenharmony_cithe open device node. Alternatively, it can write a hex string for the value 8062306a36Sopenharmony_ciusing the 10 char long format e.g. "0x12345678". This translates to a 8162306a36Sopenharmony_cicpu_latency_qos_update_request() call. 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ciTo remove the user mode request for a target value simply close the device 8462306a36Sopenharmony_cinode. 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci2. PM QoS per-device latency and flags framework 8862306a36Sopenharmony_ci================================================ 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ciFor each device, there are three lists of PM QoS requests. Two of them are 9162306a36Sopenharmony_cimaintained along with the aggregated targets of resume latency and active 9262306a36Sopenharmony_cistate latency tolerance (in microseconds) and the third one is for PM QoS flags. 9362306a36Sopenharmony_ciValues are updated in response to changes of the request list. 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ciThe target values of resume latency and active state latency tolerance are 9662306a36Sopenharmony_cisimply the minimum of the request values held in the parameter list elements. 9762306a36Sopenharmony_ciThe PM QoS flags aggregate value is a gather (bitwise OR) of all list elements' 9862306a36Sopenharmony_civalues. One device PM QoS flag is defined currently: PM_QOS_FLAG_NO_POWER_OFF. 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ciNote: The aggregated target values are implemented in such a way that reading 10162306a36Sopenharmony_cithe aggregated value does not require any locking mechanism. 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciFrom kernel mode the use of this interface is the following: 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ciint dev_pm_qos_add_request(device, handle, type, value): 10762306a36Sopenharmony_ci Will insert an element into the list for that identified device with the 10862306a36Sopenharmony_ci target value. Upon change to this list the new target is recomputed and any 10962306a36Sopenharmony_ci registered notifiers are called only if the target value is now different. 11062306a36Sopenharmony_ci Clients of dev_pm_qos need to save the handle for future use in other 11162306a36Sopenharmony_ci dev_pm_qos API functions. 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ciint dev_pm_qos_update_request(handle, new_value): 11462306a36Sopenharmony_ci Will update the list element pointed to by the handle with the new target 11562306a36Sopenharmony_ci value and recompute the new aggregated target, calling the notification 11662306a36Sopenharmony_ci trees if the target is changed. 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciint dev_pm_qos_remove_request(handle): 11962306a36Sopenharmony_ci Will remove the element. After removal it will update the aggregate target 12062306a36Sopenharmony_ci and call the notification trees if the target was changed as a result of 12162306a36Sopenharmony_ci removing the request. 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cis32 dev_pm_qos_read_value(device, type): 12462306a36Sopenharmony_ci Returns the aggregated value for a given device's constraints list. 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cienum pm_qos_flags_status dev_pm_qos_flags(device, mask) 12762306a36Sopenharmony_ci Check PM QoS flags of the given device against the given mask of flags. 12862306a36Sopenharmony_ci The meaning of the return values is as follows: 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci PM_QOS_FLAGS_ALL: 13162306a36Sopenharmony_ci All flags from the mask are set 13262306a36Sopenharmony_ci PM_QOS_FLAGS_SOME: 13362306a36Sopenharmony_ci Some flags from the mask are set 13462306a36Sopenharmony_ci PM_QOS_FLAGS_NONE: 13562306a36Sopenharmony_ci No flags from the mask are set 13662306a36Sopenharmony_ci PM_QOS_FLAGS_UNDEFINED: 13762306a36Sopenharmony_ci The device's PM QoS structure has not been initialized 13862306a36Sopenharmony_ci or the list of requests is empty. 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ciint dev_pm_qos_add_ancestor_request(dev, handle, type, value) 14162306a36Sopenharmony_ci Add a PM QoS request for the first direct ancestor of the given device whose 14262306a36Sopenharmony_ci power.ignore_children flag is unset (for DEV_PM_QOS_RESUME_LATENCY requests) 14362306a36Sopenharmony_ci or whose power.set_latency_tolerance callback pointer is not NULL (for 14462306a36Sopenharmony_ci DEV_PM_QOS_LATENCY_TOLERANCE requests). 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ciint dev_pm_qos_expose_latency_limit(device, value) 14762306a36Sopenharmony_ci Add a request to the device's PM QoS list of resume latency constraints and 14862306a36Sopenharmony_ci create a sysfs attribute pm_qos_resume_latency_us under the device's power 14962306a36Sopenharmony_ci directory allowing user space to manipulate that request. 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_civoid dev_pm_qos_hide_latency_limit(device) 15262306a36Sopenharmony_ci Drop the request added by dev_pm_qos_expose_latency_limit() from the device's 15362306a36Sopenharmony_ci PM QoS list of resume latency constraints and remove sysfs attribute 15462306a36Sopenharmony_ci pm_qos_resume_latency_us from the device's power directory. 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ciint dev_pm_qos_expose_flags(device, value) 15762306a36Sopenharmony_ci Add a request to the device's PM QoS list of flags and create sysfs attribute 15862306a36Sopenharmony_ci pm_qos_no_power_off under the device's power directory allowing user space to 15962306a36Sopenharmony_ci change the value of the PM_QOS_FLAG_NO_POWER_OFF flag. 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_civoid dev_pm_qos_hide_flags(device) 16262306a36Sopenharmony_ci Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS 16362306a36Sopenharmony_ci list of flags and remove sysfs attribute pm_qos_no_power_off from the device's 16462306a36Sopenharmony_ci power directory. 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ciNotification mechanisms: 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ciThe per-device PM QoS framework has a per-device notification tree. 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ciint dev_pm_qos_add_notifier(device, notifier, type): 17162306a36Sopenharmony_ci Adds a notification callback function for the device for a particular request 17262306a36Sopenharmony_ci type. 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci The callback is called when the aggregated value of the device constraints 17562306a36Sopenharmony_ci list is changed. 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ciint dev_pm_qos_remove_notifier(device, notifier, type): 17862306a36Sopenharmony_ci Removes the notification callback function for the device. 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ciActive state latency tolerance 18262306a36Sopenharmony_ci^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ciThis device PM QoS type is used to support systems in which hardware may switch 18562306a36Sopenharmony_cito energy-saving operation modes on the fly. In those systems, if the operation 18662306a36Sopenharmony_cimode chosen by the hardware attempts to save energy in an overly aggressive way, 18762306a36Sopenharmony_ciit may cause excess latencies to be visible to software, causing it to miss 18862306a36Sopenharmony_cicertain protocol requirements or target frame or sample rates etc. 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ciIf there is a latency tolerance control mechanism for a given device available 19162306a36Sopenharmony_cito software, the .set_latency_tolerance callback in that device's dev_pm_info 19262306a36Sopenharmony_cistructure should be populated. The routine pointed to by it is should implement 19362306a36Sopenharmony_ciwhatever is necessary to transfer the effective requirement value to the 19462306a36Sopenharmony_cihardware. 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ciWhenever the effective latency tolerance changes for the device, its 19762306a36Sopenharmony_ci.set_latency_tolerance() callback will be executed and the effective value will 19862306a36Sopenharmony_cibe passed to it. If that value is negative, which means that the list of 19962306a36Sopenharmony_cilatency tolerance requirements for the device is empty, the callback is expected 20062306a36Sopenharmony_cito switch the underlying hardware latency tolerance control mechanism to an 20162306a36Sopenharmony_ciautonomous mode if available. If that value is PM_QOS_LATENCY_ANY, in turn, and 20262306a36Sopenharmony_cithe hardware supports a special "no requirement" setting, the callback is 20362306a36Sopenharmony_ciexpected to use it. That allows software to prevent the hardware from 20462306a36Sopenharmony_ciautomatically updating the device's latency tolerance in response to its power 20562306a36Sopenharmony_cistate changes (e.g. during transitions from D3cold to D0), which generally may 20662306a36Sopenharmony_cibe done in the autonomous latency tolerance control mode. 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ciIf .set_latency_tolerance() is present for the device, sysfs attribute 20962306a36Sopenharmony_cipm_qos_latency_tolerance_us will be present in the devivce's power directory. 21062306a36Sopenharmony_ciThen, user space can use that attribute to specify its latency tolerance 21162306a36Sopenharmony_cirequirement for the device, if any. Writing "any" to it means "no requirement, 21262306a36Sopenharmony_cibut do not let the hardware control latency tolerance" and writing "auto" to it 21362306a36Sopenharmony_ciallows the hardware to be switched to the autonomous mode if there are no other 21462306a36Sopenharmony_cirequirements from the kernel side in the device's list. 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ciKernel code can use the functions described above along with the 21762306a36Sopenharmony_ciDEV_PM_QOS_LATENCY_TOLERANCE device PM QoS type to add, remove and update 21862306a36Sopenharmony_cilatency tolerance requirements for devices. 219