OPP updates for 6.6
- Minor core cleanup and addition of new frequency related APIs (Viresh Kumar and Manivannan Sadhasivam). - Convert ti cpufreq/opp bindings to json schema (Nishanth Menon). -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEx73Crsp7f6M6scA70rkcPK6BEhwFAmTsdWEACgkQ0rkcPK6B EhyuNhAAtd3KqoIlE4L1fGQe1F3tukuPR8KCYyeDJzT+mvjlBTi6xcDJoMSdiE68 tRH6QI6+dzzFnyLbC3v3WULWosFkY1ETkZNVvmjyE+DE7v7mwRL5EdAQfJ2OoBH6 7906FHy5XN9+ch/LLJ8ja+d+z9jx38obkVB87nrEio3rocaYuPRYjesum57LWU/7 Bh+9VqiCFIMu0U4cDXHcmrsh9OEupWF4NQZ3N3QDlwKjiSd05jmzYcKx3tOO6oa4 NRNUoQ4AH1qk6BBc/V1igfFXCFSYTY1RRKslzeIDbocNrphXmY6qq2muBbnpmJ2P Ykyyc+q9cSzzgPV/VHH54g5woJh34oIvxmDPaieAjPVIzLNOJXW7zN2FjeKH4pXZ kTBtqpUcbqpcZuLryd91WclXIL9WsjdHaB4XkKnsWMFBVcWBrET3d/x4sR1HkD6c CU0ftr68qzuoT9vyeOs/636FeK+l4Bmsp2m30v5DsoO9DC5n5EMMEZqZHVD0Csvy bLoEHOhHSMtJwknK8QkRde6KdxwteEbHK2IR1VmKz+ppa87AFbLxfqR1zgtyZ8Ho 0/rtzPODfp2vd+gPfBXfiwhg/57cL1Knxmm0g/11PUQPAYreRxBE+ovPGDJ39oSo KX9tqqAokirIsdNXFV0v6GWivGZZlcMErGqBMY88Wt2zNkKm7vY= =b27+ -----END PGP SIGNATURE----- Merge tag 'opp-updates-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm Pull OPP updates for 6.6 from Viresh Kumar: "- Minor core cleanup and addition of new frequency related APIs (Viresh Kumar and Manivannan Sadhasivam). - Convert ti cpufreq/opp bindings to json schema (Nishanth Menon)." * tag 'opp-updates-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: dt-bindings: cpufreq: Convert ti-cpufreq to json schema dt-bindings: opp: Convert ti-omap5-opp-supply to json schema OPP: Fix argument name in doc comment dt-bindings: opp: Increase maxItems for opp-hz property OPP: Fix passing 0 to PTR_ERR in _opp_attach_genpd() OPP: Fix potential null ptr dereference in dev_pm_opp_get_required_pstate() OPP: Reuse dev_pm_opp_get_freq_indexed() OPP: Update _read_freq() to return the correct frequency OPP: Add dev_pm_opp_find_freq_exact_indexed() OPP: Introduce dev_pm_opp_get_freq_indexed() API OPP: Introduce dev_pm_opp_find_freq_{ceil/floor}_indexed() APIs OPP: Rearrange entries in pm_opp.h
This commit is contained in:
commit
422ec6fe27
@ -1,132 +0,0 @@
|
||||
TI CPUFreq and OPP bindings
|
||||
================================
|
||||
|
||||
Certain TI SoCs, like those in the am335x, am437x, am57xx, and dra7xx
|
||||
families support different OPPs depending on the silicon variant in use.
|
||||
The ti-cpufreq driver can use revision and an efuse value from the SoC to
|
||||
provide the OPP framework with supported hardware information. This is
|
||||
used to determine which OPPs from the operating-points-v2 table get enabled
|
||||
when it is parsed by the OPP framework.
|
||||
|
||||
Required properties:
|
||||
--------------------
|
||||
In 'cpus' nodes:
|
||||
- operating-points-v2: Phandle to the operating-points-v2 table to use.
|
||||
|
||||
In 'operating-points-v2' table:
|
||||
- compatible: Should be
|
||||
- 'operating-points-v2-ti-cpu' for am335x, am43xx, and dra7xx/am57xx,
|
||||
omap34xx, omap36xx and am3517 SoCs
|
||||
- syscon: A phandle pointing to a syscon node representing the control module
|
||||
register space of the SoC.
|
||||
|
||||
Optional properties:
|
||||
--------------------
|
||||
- "vdd-supply", "vbb-supply": to define two regulators for dra7xx
|
||||
- "cpu0-supply", "vbb-supply": to define two regulators for omap36xx
|
||||
|
||||
For each opp entry in 'operating-points-v2' table:
|
||||
- opp-supported-hw: Two bitfields indicating:
|
||||
1. Which revision of the SoC the OPP is supported by
|
||||
2. Which eFuse bits indicate this OPP is available
|
||||
|
||||
A bitwise AND is performed against these values and if any bit
|
||||
matches, the OPP gets enabled.
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
/* From arch/arm/boot/dts/am33xx.dtsi */
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cpu@0 {
|
||||
compatible = "arm,cortex-a8";
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
|
||||
clocks = <&dpll_mpu_ck>;
|
||||
clock-names = "cpu";
|
||||
|
||||
clock-latency = <300000>; /* From omap-cpufreq driver */
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* cpu0 has different OPPs depending on SoC revision and some on revisions
|
||||
* 0x2 and 0x4 have eFuse bits that indicate if they are available or not
|
||||
*/
|
||||
cpu0_opp_table: opp-table {
|
||||
compatible = "operating-points-v2-ti-cpu";
|
||||
syscon = <&scm_conf>;
|
||||
|
||||
/*
|
||||
* The three following nodes are marked with opp-suspend
|
||||
* because they can not be enabled simultaneously on a
|
||||
* single SoC.
|
||||
*/
|
||||
opp50-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
opp-microvolt = <950000 931000 969000>;
|
||||
opp-supported-hw = <0x06 0x0010>;
|
||||
opp-suspend;
|
||||
};
|
||||
|
||||
opp100-275000000 {
|
||||
opp-hz = /bits/ 64 <275000000>;
|
||||
opp-microvolt = <1100000 1078000 1122000>;
|
||||
opp-supported-hw = <0x01 0x00FF>;
|
||||
opp-suspend;
|
||||
};
|
||||
|
||||
opp100-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
opp-microvolt = <1100000 1078000 1122000>;
|
||||
opp-supported-hw = <0x06 0x0020>;
|
||||
opp-suspend;
|
||||
};
|
||||
|
||||
opp100-500000000 {
|
||||
opp-hz = /bits/ 64 <500000000>;
|
||||
opp-microvolt = <1100000 1078000 1122000>;
|
||||
opp-supported-hw = <0x01 0xFFFF>;
|
||||
};
|
||||
|
||||
opp100-600000000 {
|
||||
opp-hz = /bits/ 64 <600000000>;
|
||||
opp-microvolt = <1100000 1078000 1122000>;
|
||||
opp-supported-hw = <0x06 0x0040>;
|
||||
};
|
||||
|
||||
opp120-600000000 {
|
||||
opp-hz = /bits/ 64 <600000000>;
|
||||
opp-microvolt = <1200000 1176000 1224000>;
|
||||
opp-supported-hw = <0x01 0xFFFF>;
|
||||
};
|
||||
|
||||
opp120-720000000 {
|
||||
opp-hz = /bits/ 64 <720000000>;
|
||||
opp-microvolt = <1200000 1176000 1224000>;
|
||||
opp-supported-hw = <0x06 0x0080>;
|
||||
};
|
||||
|
||||
oppturbo-720000000 {
|
||||
opp-hz = /bits/ 64 <720000000>;
|
||||
opp-microvolt = <1260000 1234800 1285200>;
|
||||
opp-supported-hw = <0x01 0xFFFF>;
|
||||
};
|
||||
|
||||
oppturbo-800000000 {
|
||||
opp-hz = /bits/ 64 <800000000>;
|
||||
opp-microvolt = <1260000 1234800 1285200>;
|
||||
opp-supported-hw = <0x06 0x0100>;
|
||||
};
|
||||
|
||||
oppnitro-1000000000 {
|
||||
opp-hz = /bits/ 64 <1000000000>;
|
||||
opp-microvolt = <1325000 1298500 1351500>;
|
||||
opp-supported-hw = <0x04 0x0200>;
|
||||
};
|
||||
};
|
@ -0,0 +1,92 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/opp/operating-points-v2-ti-cpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI CPU OPP (Operating Performance Points)
|
||||
|
||||
description:
|
||||
TI SoCs, like those in the AM335x, AM437x, AM57xx, AM62x, and DRA7xx
|
||||
families, the CPU frequencies subset and the voltage value of each
|
||||
OPP vary based on the silicon variant used. The data sheet sections
|
||||
corresponding to "Operating Performance Points" describe the frequency
|
||||
and voltage values based on device type and speed bin information
|
||||
blown in corresponding eFuse bits as referred to by the Technical
|
||||
Reference Manual.
|
||||
|
||||
This document extends the operating-points-v2 binding by providing
|
||||
the hardware description for the scheme mentioned above.
|
||||
|
||||
maintainers:
|
||||
- Nishanth Menon <nm@ti.com>
|
||||
|
||||
allOf:
|
||||
- $ref: opp-v2-base.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: operating-points-v2-ti-cpu
|
||||
|
||||
syscon:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: |
|
||||
points to syscon node representing the control module
|
||||
register space of the SoC.
|
||||
|
||||
opp-shared: true
|
||||
|
||||
patternProperties:
|
||||
'^opp(-?[0-9]+)*$':
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
clock-latency-ns: true
|
||||
opp-hz: true
|
||||
opp-microvolt: true
|
||||
opp-supported-hw: true
|
||||
opp-suspend: true
|
||||
turbo-mode: true
|
||||
|
||||
required:
|
||||
- opp-hz
|
||||
- opp-supported-hw
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- syscon
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
opp-table {
|
||||
compatible = "operating-points-v2-ti-cpu";
|
||||
syscon = <&scm_conf>;
|
||||
|
||||
opp-300000000 {
|
||||
opp-hz = /bits/ 64 <300000000>;
|
||||
opp-microvolt = <1100000 1078000 1122000>;
|
||||
opp-supported-hw = <0x06 0x0020>;
|
||||
opp-suspend;
|
||||
};
|
||||
|
||||
opp-500000000 {
|
||||
opp-hz = /bits/ 64 <500000000>;
|
||||
opp-microvolt = <1100000 1078000 1122000>;
|
||||
opp-supported-hw = <0x01 0xFFFF>;
|
||||
};
|
||||
|
||||
opp-600000000 {
|
||||
opp-hz = /bits/ 64 <600000000>;
|
||||
opp-microvolt = <1100000 1078000 1122000>;
|
||||
opp-supported-hw = <0x06 0x0040>;
|
||||
};
|
||||
|
||||
opp-1000000000 {
|
||||
opp-hz = /bits/ 64 <1000000000>;
|
||||
opp-microvolt = <1325000 1298500 1351500>;
|
||||
opp-supported-hw = <0x04 0x0200>;
|
||||
};
|
||||
};
|
@ -56,7 +56,7 @@ patternProperties:
|
||||
need to be configured and that is left for the implementation
|
||||
specific binding.
|
||||
minItems: 1
|
||||
maxItems: 16
|
||||
maxItems: 32
|
||||
items:
|
||||
maxItems: 1
|
||||
|
||||
|
101
Documentation/devicetree/bindings/opp/ti,omap-opp-supply.yaml
Normal file
101
Documentation/devicetree/bindings/opp/ti,omap-opp-supply.yaml
Normal file
@ -0,0 +1,101 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/opp/ti,omap-opp-supply.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments OMAP compatible OPP supply
|
||||
|
||||
description:
|
||||
OMAP5, DRA7, and AM57 families of SoCs have Class 0 AVS eFuse
|
||||
registers, which contain OPP-specific voltage information tailored
|
||||
for the specific device. This binding provides the information
|
||||
needed to describe such a hardware values and relate them to program
|
||||
the primary regulator during an OPP transition.
|
||||
|
||||
Also, some supplies may have an associated vbb-supply, an Adaptive
|
||||
Body Bias regulator, which must transition in a specific sequence
|
||||
w.r.t the vdd-supply and clk when making an OPP transition. By
|
||||
supplying two regulators to the device that will undergo OPP
|
||||
transitions, we can use the multi-regulator support implemented by
|
||||
the OPP core to describe both regulators the platform needs. The
|
||||
OPP core binding Documentation/devicetree/bindings/opp/opp-v2.yaml
|
||||
provides further information (refer to Example 4 Handling multiple
|
||||
regulators).
|
||||
|
||||
maintainers:
|
||||
- Nishanth Menon <nm@ti.com>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: '^opp-supply(@[0-9a-f]+)?$'
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- description: Basic OPP supply controlling VDD and VBB
|
||||
const: ti,omap-opp-supply
|
||||
- description: OMAP5+ optimized voltages in efuse(Class 0) VDD along with
|
||||
VBB.
|
||||
const: ti,omap5-opp-supply
|
||||
- description: OMAP5+ optimized voltages in efuse(class0) VDD but no VBB
|
||||
const: ti,omap5-core-opp-supply
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
ti,absolute-max-voltage-uv:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Absolute maximum voltage for the OPP supply in micro-volts.
|
||||
minimum: 750000
|
||||
maximum: 1500000
|
||||
|
||||
ti,efuse-settings:
|
||||
description: An array of u32 tuple items providing information about
|
||||
optimized efuse configuration.
|
||||
minItems: 1
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-matrix
|
||||
items:
|
||||
items:
|
||||
- description: Reference voltage in micro-volts (OPP Voltage)
|
||||
minimum: 750000
|
||||
maximum: 1500000
|
||||
multipleOf: 10000
|
||||
- description: efuse offset where the optimized voltage is located
|
||||
multipleOf: 4
|
||||
maximum: 256
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- ti,absolute-max-voltage-uv
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ti,omap-opp-supply
|
||||
then:
|
||||
required:
|
||||
- reg
|
||||
- ti,efuse-settings
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
opp-supply {
|
||||
compatible = "ti,omap-opp-supply";
|
||||
ti,absolute-max-voltage-uv = <1375000>;
|
||||
};
|
||||
- |
|
||||
opp-supply@4a003b20 {
|
||||
compatible = "ti,omap5-opp-supply";
|
||||
reg = <0x4a003b20 0x8>;
|
||||
ti,efuse-settings =
|
||||
/* uV offset */
|
||||
<1060000 0x0>,
|
||||
<1160000 0x4>,
|
||||
<1210000 0x8>;
|
||||
ti,absolute-max-voltage-uv = <1500000>;
|
||||
};
|
@ -1,63 +0,0 @@
|
||||
Texas Instruments OMAP compatible OPP supply description
|
||||
|
||||
OMAP5, DRA7, and AM57 family of SoCs have Class0 AVS eFuse registers which
|
||||
contain data that can be used to adjust voltages programmed for some of their
|
||||
supplies for more efficient operation. This binding provides the information
|
||||
needed to read these values and use them to program the main regulator during
|
||||
an OPP transitions.
|
||||
|
||||
Also, some supplies may have an associated vbb-supply which is an Adaptive Body
|
||||
Bias regulator which much be transitioned in a specific sequence with regards
|
||||
to the vdd-supply and clk when making an OPP transition. By supplying two
|
||||
regulators to the device that will undergo OPP transitions we can make use
|
||||
of the multi regulator binding that is part of the OPP core described here [1]
|
||||
to describe both regulators needed by the platform.
|
||||
|
||||
[1] Documentation/devicetree/bindings/opp/opp-v2.yaml
|
||||
|
||||
Required Properties for Device Node:
|
||||
- vdd-supply: phandle to regulator controlling VDD supply
|
||||
- vbb-supply: phandle to regulator controlling Body Bias supply
|
||||
(Usually Adaptive Body Bias regulator)
|
||||
|
||||
Required Properties for opp-supply node:
|
||||
- compatible: Should be one of:
|
||||
"ti,omap-opp-supply" - basic OPP supply controlling VDD and VBB
|
||||
"ti,omap5-opp-supply" - OMAP5+ optimized voltages in efuse(class0)VDD
|
||||
along with VBB
|
||||
"ti,omap5-core-opp-supply" - OMAP5+ optimized voltages in efuse(class0) VDD
|
||||
but no VBB.
|
||||
- reg: Address and length of the efuse register set for the device (mandatory
|
||||
only for "ti,omap5-opp-supply")
|
||||
- ti,efuse-settings: An array of u32 tuple items providing information about
|
||||
optimized efuse configuration. Each item consists of the following:
|
||||
volt: voltage in uV - reference voltage (OPP voltage)
|
||||
efuse_offseet: efuse offset from reg where the optimized voltage is stored.
|
||||
- ti,absolute-max-voltage-uv: absolute maximum voltage for the OPP supply.
|
||||
|
||||
Example:
|
||||
|
||||
/* Device Node (CPU) */
|
||||
cpus {
|
||||
cpu0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
|
||||
...
|
||||
|
||||
vdd-supply = <&vcc>;
|
||||
vbb-supply = <&abb_mpu>;
|
||||
};
|
||||
};
|
||||
|
||||
/* OMAP OPP Supply with Class0 registers */
|
||||
opp_supply_mpu: opp_supply@4a003b20 {
|
||||
compatible = "ti,omap5-opp-supply";
|
||||
reg = <0x4a003b20 0x8>;
|
||||
ti,efuse-settings = <
|
||||
/* uV offset */
|
||||
1060000 0x0
|
||||
1160000 0x4
|
||||
1210000 0x8
|
||||
>;
|
||||
ti,absolute-max-voltage-uv = <1500000>;
|
||||
};
|
@ -177,25 +177,24 @@ unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp)
|
||||
EXPORT_SYMBOL_GPL(dev_pm_opp_get_power);
|
||||
|
||||
/**
|
||||
* dev_pm_opp_get_freq() - Gets the frequency corresponding to an available opp
|
||||
* @opp: opp for which frequency has to be returned for
|
||||
* dev_pm_opp_get_freq_indexed() - Gets the frequency corresponding to an
|
||||
* available opp with specified index
|
||||
* @opp: opp for which frequency has to be returned for
|
||||
* @index: index of the frequency within the required opp
|
||||
*
|
||||
* Return: frequency in hertz corresponding to the opp, else
|
||||
* return 0
|
||||
* Return: frequency in hertz corresponding to the opp with specified index,
|
||||
* else return 0
|
||||
*/
|
||||
unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
|
||||
unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(opp)) {
|
||||
if (IS_ERR_OR_NULL(opp) || index >= opp->opp_table->clk_count) {
|
||||
pr_err("%s: Invalid parameters\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!assert_single_clk(opp->opp_table))
|
||||
return 0;
|
||||
|
||||
return opp->rates[0];
|
||||
return opp->rates[index];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq);
|
||||
EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq_indexed);
|
||||
|
||||
/**
|
||||
* dev_pm_opp_get_level() - Gets the level corresponding to an available opp
|
||||
@ -227,20 +226,18 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_level);
|
||||
unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp,
|
||||
unsigned int index)
|
||||
{
|
||||
struct opp_table *opp_table = opp->opp_table;
|
||||
|
||||
if (IS_ERR_OR_NULL(opp) || !opp->available ||
|
||||
index >= opp_table->required_opp_count) {
|
||||
index >= opp->opp_table->required_opp_count) {
|
||||
pr_err("%s: Invalid parameters\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* required-opps not fully initialized yet */
|
||||
if (lazy_linking_pending(opp_table))
|
||||
if (lazy_linking_pending(opp->opp_table))
|
||||
return 0;
|
||||
|
||||
/* The required OPP table must belong to a genpd */
|
||||
if (unlikely(!opp_table->required_opp_tables[index]->is_genpd)) {
|
||||
if (unlikely(!opp->opp_table->required_opp_tables[index]->is_genpd)) {
|
||||
pr_err("%s: Performance state is only valid for genpds.\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
@ -450,7 +447,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count);
|
||||
/* Helpers to read keys */
|
||||
static unsigned long _read_freq(struct dev_pm_opp *opp, int index)
|
||||
{
|
||||
return opp->rates[0];
|
||||
return opp->rates[index];
|
||||
}
|
||||
|
||||
static unsigned long _read_level(struct dev_pm_opp *opp, int index)
|
||||
@ -626,6 +623,34 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact);
|
||||
|
||||
/**
|
||||
* dev_pm_opp_find_freq_exact_indexed() - Search for an exact freq for the
|
||||
* clock corresponding to the index
|
||||
* @dev: Device for which we do this operation
|
||||
* @freq: frequency to search for
|
||||
* @index: Clock index
|
||||
* @available: true/false - match for available opp
|
||||
*
|
||||
* Search for the matching exact OPP for the clock corresponding to the
|
||||
* specified index from a starting freq for a device.
|
||||
*
|
||||
* Return: matching *opp , else returns ERR_PTR in case of error and should be
|
||||
* handled using IS_ERR. Error return values can be:
|
||||
* EINVAL: for bad pointer
|
||||
* ERANGE: no match found for search
|
||||
* ENODEV: if device not found in list of registered devices
|
||||
*
|
||||
* The callers are required to call dev_pm_opp_put() for the returned OPP after
|
||||
* use.
|
||||
*/
|
||||
struct dev_pm_opp *
|
||||
dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq,
|
||||
u32 index, bool available)
|
||||
{
|
||||
return _find_key_exact(dev, freq, index, available, _read_freq, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact_indexed);
|
||||
|
||||
static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_table,
|
||||
unsigned long *freq)
|
||||
{
|
||||
@ -658,6 +683,34 @@ struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil);
|
||||
|
||||
/**
|
||||
* dev_pm_opp_find_freq_ceil_indexed() - Search for a rounded ceil freq for the
|
||||
* clock corresponding to the index
|
||||
* @dev: Device for which we do this operation
|
||||
* @freq: Start frequency
|
||||
* @index: Clock index
|
||||
*
|
||||
* Search for the matching ceil *available* OPP for the clock corresponding to
|
||||
* the specified index from a starting freq for a device.
|
||||
*
|
||||
* Return: matching *opp and refreshes *freq accordingly, else returns
|
||||
* ERR_PTR in case of error and should be handled using IS_ERR. Error return
|
||||
* values can be:
|
||||
* EINVAL: for bad pointer
|
||||
* ERANGE: no match found for search
|
||||
* ENODEV: if device not found in list of registered devices
|
||||
*
|
||||
* The callers are required to call dev_pm_opp_put() for the returned OPP after
|
||||
* use.
|
||||
*/
|
||||
struct dev_pm_opp *
|
||||
dev_pm_opp_find_freq_ceil_indexed(struct device *dev, unsigned long *freq,
|
||||
u32 index)
|
||||
{
|
||||
return _find_key_ceil(dev, freq, index, true, _read_freq, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil_indexed);
|
||||
|
||||
/**
|
||||
* dev_pm_opp_find_freq_floor() - Search for a rounded floor freq
|
||||
* @dev: device for which we do this operation
|
||||
@ -683,6 +736,34 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
|
||||
|
||||
/**
|
||||
* dev_pm_opp_find_freq_floor_indexed() - Search for a rounded floor freq for the
|
||||
* clock corresponding to the index
|
||||
* @dev: Device for which we do this operation
|
||||
* @freq: Start frequency
|
||||
* @index: Clock index
|
||||
*
|
||||
* Search for the matching floor *available* OPP for the clock corresponding to
|
||||
* the specified index from a starting freq for a device.
|
||||
*
|
||||
* Return: matching *opp and refreshes *freq accordingly, else returns
|
||||
* ERR_PTR in case of error and should be handled using IS_ERR. Error return
|
||||
* values can be:
|
||||
* EINVAL: for bad pointer
|
||||
* ERANGE: no match found for search
|
||||
* ENODEV: if device not found in list of registered devices
|
||||
*
|
||||
* The callers are required to call dev_pm_opp_put() for the returned OPP after
|
||||
* use.
|
||||
*/
|
||||
struct dev_pm_opp *
|
||||
dev_pm_opp_find_freq_floor_indexed(struct device *dev, unsigned long *freq,
|
||||
u32 index)
|
||||
{
|
||||
return _find_key_floor(dev, freq, index, true, _read_freq, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor_indexed);
|
||||
|
||||
/**
|
||||
* dev_pm_opp_find_level_exact() - search for an exact level
|
||||
* @dev: device for which we do this operation
|
||||
@ -2379,7 +2460,7 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev,
|
||||
|
||||
virt_dev = dev_pm_domain_attach_by_name(dev, *name);
|
||||
if (IS_ERR_OR_NULL(virt_dev)) {
|
||||
ret = PTR_ERR(virt_dev) ? : -ENODEV;
|
||||
ret = virt_dev ? PTR_ERR(virt_dev) : -ENODEV;
|
||||
dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
/**
|
||||
* dev_pm_opp_init_cpufreq_table() - create a cpufreq table for a device
|
||||
* @dev: device for which we do this operation
|
||||
* @table: Cpufreq table returned back to caller
|
||||
* @opp_table: Cpufreq table returned back to caller
|
||||
*
|
||||
* Generate a cpufreq table for a provided device- this assumes that the
|
||||
* opp table is already initialized and ready for usage.
|
||||
@ -89,7 +89,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table);
|
||||
/**
|
||||
* dev_pm_opp_free_cpufreq_table() - free the cpufreq table
|
||||
* @dev: device for which we do this operation
|
||||
* @table: table to free
|
||||
* @opp_table: table to free
|
||||
*
|
||||
* Free up the table allocated by dev_pm_opp_init_cpufreq_table
|
||||
*/
|
||||
|
@ -103,7 +103,7 @@ int dev_pm_opp_get_supplies(struct dev_pm_opp *opp, struct dev_pm_opp_supply *su
|
||||
|
||||
unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp);
|
||||
|
||||
unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp);
|
||||
unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index);
|
||||
|
||||
unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp);
|
||||
|
||||
@ -121,17 +121,29 @@ unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev);
|
||||
struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
|
||||
unsigned long freq,
|
||||
bool available);
|
||||
|
||||
struct dev_pm_opp *
|
||||
dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq,
|
||||
u32 index, bool available);
|
||||
|
||||
struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
|
||||
unsigned long *freq);
|
||||
|
||||
struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
|
||||
unsigned int level);
|
||||
struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev,
|
||||
unsigned int *level);
|
||||
struct dev_pm_opp *dev_pm_opp_find_freq_floor_indexed(struct device *dev,
|
||||
unsigned long *freq, u32 index);
|
||||
|
||||
struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
|
||||
unsigned long *freq);
|
||||
|
||||
struct dev_pm_opp *dev_pm_opp_find_freq_ceil_indexed(struct device *dev,
|
||||
unsigned long *freq, u32 index);
|
||||
|
||||
struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
|
||||
unsigned int level);
|
||||
|
||||
struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev,
|
||||
unsigned int *level);
|
||||
|
||||
struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev,
|
||||
unsigned int *bw, int index);
|
||||
|
||||
@ -200,7 +212,7 @@ static inline unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
|
||||
static inline unsigned long dev_pm_opp_get_freq_indexed(struct dev_pm_opp *opp, u32 index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -247,36 +259,55 @@ static inline unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
|
||||
unsigned int level)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev,
|
||||
unsigned int *level)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev,
|
||||
unsigned long freq, bool available)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *
|
||||
dev_pm_opp_find_freq_exact_indexed(struct device *dev, unsigned long freq,
|
||||
u32 index, bool available)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
|
||||
unsigned long *freq)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *
|
||||
dev_pm_opp_find_freq_floor_indexed(struct device *dev, unsigned long *freq, u32 index)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev,
|
||||
unsigned long *freq)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *
|
||||
dev_pm_opp_find_freq_ceil_indexed(struct device *dev, unsigned long *freq, u32 index)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev,
|
||||
unsigned int level)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev,
|
||||
unsigned int *level)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev,
|
||||
unsigned int *bw, int index)
|
||||
{
|
||||
@ -631,4 +662,9 @@ static inline void dev_pm_opp_put_prop_name(int token)
|
||||
dev_pm_opp_clear_config(token);
|
||||
}
|
||||
|
||||
static inline unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp)
|
||||
{
|
||||
return dev_pm_opp_get_freq_indexed(opp, 0);
|
||||
}
|
||||
|
||||
#endif /* __LINUX_OPP_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user