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