diff options
20 files changed, 851 insertions, 957 deletions
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index 04ff0b55bb85..da6b2608f10b 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -172,7 +172,21 @@ properties: - const: qcom,apq8094 - items: - - const: qcom,msm8996-mtp + - enum: + - arrow,apq8096-db820c + - inforce,ifc6640 + - const: qcom,apq8096-sbc + - const: qcom,apq8096 + + - items: + - enum: + - qcom,msm8996-mtp + - sony,dora-row + - sony,kagura-row + - sony,keyaki-row + - xiaomi,gemini + - xiaomi,scorpio + - const: qcom,msm8996 - items: - enum: diff --git a/Documentation/devicetree/bindings/cpufreq/qcom-cpufreq-nvmem.yaml b/Documentation/devicetree/bindings/cpufreq/qcom-cpufreq-nvmem.yaml new file mode 100644 index 000000000000..a9a776da5505 --- /dev/null +++ b/Documentation/devicetree/bindings/cpufreq/qcom-cpufreq-nvmem.yaml @@ -0,0 +1,166 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/cpufreq/qcom-cpufreq-nvmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. NVMEM CPUFreq bindings + +maintainers: + - Ilia Lin <ilia.lin@kernel.org> + +description: | + In certain Qualcomm Technologies, Inc. SoCs such as QCS404, The CPU supply + voltage is dynamically configured by Core Power Reduction (CPR) depending on + current CPU frequency and efuse values. + CPR provides a power domain with multiple levels that are selected depending + on the CPU OPP in use. The CPUFreq driver sets the CPR power domain level + according to the required OPPs defined in the CPU OPP tables. + +select: + properties: + compatible: + contains: + enum: + - qcom,qcs404 + required: + - compatible + +properties: + cpus: + type: object + + patternProperties: + 'cpu@[0-9a-f]+': + type: object + + properties: + power-domains: + maxItems: 1 + + power-domain-names: + items: + - const: cpr + + required: + - power-domains + - power-domain-names + +patternProperties: + '^opp-table(-[a-z0-9]+)?$': + if: + properties: + compatible: + const: operating-points-v2-kryo-cpu + then: + patternProperties: + '^opp-?[0-9]+$': + required: + - required-opps + +additionalProperties: true + +examples: + - | + / { + model = "Qualcomm Technologies, Inc. QCS404"; + compatible = "qcom,qcs404"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + CPU0: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x100>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + next-level-cache = <&L2_0>; + #cooling-cells = <2>; + clocks = <&apcs_glb>; + operating-points-v2 = <&cpu_opp_table>; + power-domains = <&cpr>; + power-domain-names = "cpr"; + }; + + CPU1: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x101>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + next-level-cache = <&L2_0>; + #cooling-cells = <2>; + clocks = <&apcs_glb>; + operating-points-v2 = <&cpu_opp_table>; + power-domains = <&cpr>; + power-domain-names = "cpr"; + }; + + CPU2: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x102>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + next-level-cache = <&L2_0>; + #cooling-cells = <2>; + clocks = <&apcs_glb>; + operating-points-v2 = <&cpu_opp_table>; + power-domains = <&cpr>; + power-domain-names = "cpr"; + }; + + CPU3: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x103>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + next-level-cache = <&L2_0>; + #cooling-cells = <2>; + clocks = <&apcs_glb>; + operating-points-v2 = <&cpu_opp_table>; + power-domains = <&cpr>; + power-domain-names = "cpr"; + }; + }; + + cpu_opp_table: opp-table-cpu { + compatible = "operating-points-v2-kryo-cpu"; + opp-shared; + + opp-1094400000 { + opp-hz = /bits/ 64 <1094400000>; + required-opps = <&cpr_opp1>; + }; + opp-1248000000 { + opp-hz = /bits/ 64 <1248000000>; + required-opps = <&cpr_opp2>; + }; + opp-1401600000 { + opp-hz = /bits/ 64 <1401600000>; + required-opps = <&cpr_opp3>; + }; + }; + + cpr_opp_table: opp-table-cpr { + compatible = "operating-points-v2-qcom-level"; + + cpr_opp1: opp1 { + opp-level = <1>; + qcom,opp-fuse-level = <1>; + }; + cpr_opp2: opp2 { + opp-level = <2>; + qcom,opp-fuse-level = <2>; + }; + cpr_opp3: opp3 { + opp-level = <3>; + qcom,opp-fuse-level = <3>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/opp/opp-v2-base.yaml b/Documentation/devicetree/bindings/opp/opp-v2-base.yaml index 15a76bcd6d42..04a592c0f862 100644 --- a/Documentation/devicetree/bindings/opp/opp-v2-base.yaml +++ b/Documentation/devicetree/bindings/opp/opp-v2-base.yaml @@ -93,6 +93,21 @@ patternProperties: minItems: 1 maxItems: 8 # Should be enough regulators + opp-microwatt: + description: | + The power for the OPP in micro-Watts. + + Entries for multiple regulators shall be provided in the same field + separated by angular brackets <>. If current values aren't required + for a regulator, then it shall be filled with 0. If power values + aren't required for any of the regulators, then this field is not + required. The OPP binding doesn't provide any provisions to relate the + values to their power supplies or the order in which the supplies need + to be configured and that is left for the implementation specific + binding. + minItems: 1 + maxItems: 8 # Should be enough regulators + opp-level: description: A value representing the performance level of the device. @@ -203,6 +218,14 @@ patternProperties: minItems: 1 maxItems: 8 # Should be enough regulators + '^opp-microwatt': + description: + Named opp-microwatt property. Similar to opp-microamp property, + but for microwatt instead. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 8 # Should be enough regulators + dependencies: opp-avg-kBps: [ opp-peak-kBps ] diff --git a/Documentation/devicetree/bindings/opp/opp-v2-kryo-cpu.yaml b/Documentation/devicetree/bindings/opp/opp-v2-kryo-cpu.yaml new file mode 100644 index 000000000000..8c2e9ac5f68d --- /dev/null +++ b/Documentation/devicetree/bindings/opp/opp-v2-kryo-cpu.yaml @@ -0,0 +1,257 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/opp/opp-v2-kryo-cpu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. NVMEM OPP bindings + +maintainers: + - Ilia Lin <ilia.lin@kernel.org> + +allOf: + - $ref: opp-v2-base.yaml# + +description: | + In certain Qualcomm Technologies, Inc. SoCs like APQ8096 and MSM8996, + the CPU frequencies subset and voltage value of each OPP varies based on + the silicon variant in use. + Qualcomm Technologies, Inc. Process Voltage Scaling Tables + defines the voltage and frequency value based on the msm-id in SMEM + and speedbin blown in the efuse combination. + The qcom-cpufreq-nvmem driver reads the msm-id and efuse value from the SoC + to provide the OPP framework with required information (existing HW bitmap). + This is used to determine the voltage and frequency value for each OPP of + operating-points-v2 table when it is parsed by the OPP framework. + +properties: + compatible: + const: operating-points-v2-kryo-cpu + + nvmem-cells: + description: | + A phandle pointing to a nvmem-cells node representing the + efuse registers that has information about the + speedbin that is used to select the right frequency/voltage + value pair. + + opp-shared: true + +patternProperties: + '^opp-?[0-9]+$': + type: object + + properties: + opp-hz: true + + opp-microvolt: true + + opp-supported-hw: + description: | + A single 32 bit bitmap value, representing compatible HW. + Bitmap: + 0: MSM8996 V3, speedbin 0 + 1: MSM8996 V3, speedbin 1 + 2: MSM8996 V3, speedbin 2 + 3: unused + 4: MSM8996 SG, speedbin 0 + 5: MSM8996 SG, speedbin 1 + 6: MSM8996 SG, speedbin 2 + 7-31: unused + maximum: 0x77 + + clock-latency-ns: true + + required-opps: true + + required: + - opp-hz + +required: + - compatible + +if: + required: + - nvmem-cells +then: + patternProperties: + '^opp-?[0-9]+$': + required: + - opp-supported-hw + +additionalProperties: false + +examples: + - | + / { + model = "Qualcomm Technologies, Inc. DB820c"; + compatible = "arrow,apq8096-db820c", "qcom,apq8096-sbc", "qcom,apq8096"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x0>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + capacity-dmips-mhz = <1024>; + clocks = <&kryocc 0>; + operating-points-v2 = <&cluster0_opp>; + #cooling-cells = <2>; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; + }; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x1>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + capacity-dmips-mhz = <1024>; + clocks = <&kryocc 0>; + operating-points-v2 = <&cluster0_opp>; + #cooling-cells = <2>; + next-level-cache = <&L2_0>; + }; + + CPU2: cpu@100 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x100>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + capacity-dmips-mhz = <1024>; + clocks = <&kryocc 1>; + operating-points-v2 = <&cluster1_opp>; + #cooling-cells = <2>; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "cache"; + cache-level = <2>; + }; + }; + + CPU3: cpu@101 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x101>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + capacity-dmips-mhz = <1024>; + clocks = <&kryocc 1>; + operating-points-v2 = <&cluster1_opp>; + #cooling-cells = <2>; + next-level-cache = <&L2_1>; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + + core1 { + cpu = <&CPU1>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU2>; + }; + + core1 { + cpu = <&CPU3>; + }; + }; + }; + }; + + cluster0_opp: opp-table-0 { + compatible = "operating-points-v2-kryo-cpu"; + nvmem-cells = <&speedbin_efuse>; + opp-shared; + + opp-307200000 { + opp-hz = /bits/ 64 <307200000>; + opp-microvolt = <905000 905000 1140000>; + opp-supported-hw = <0x77>; + clock-latency-ns = <200000>; + }; + opp-1593600000 { + opp-hz = /bits/ 64 <1593600000>; + opp-microvolt = <1140000 905000 1140000>; + opp-supported-hw = <0x71>; + clock-latency-ns = <200000>; + }; + opp-2188800000 { + opp-hz = /bits/ 64 <2188800000>; + opp-microvolt = <1140000 905000 1140000>; + opp-supported-hw = <0x10>; + clock-latency-ns = <200000>; + }; + }; + + cluster1_opp: opp-table-1 { + compatible = "operating-points-v2-kryo-cpu"; + nvmem-cells = <&speedbin_efuse>; + opp-shared; + + opp-307200000 { + opp-hz = /bits/ 64 <307200000>; + opp-microvolt = <905000 905000 1140000>; + opp-supported-hw = <0x77>; + clock-latency-ns = <200000>; + }; + opp-1593600000 { + opp-hz = /bits/ 64 <1593600000>; + opp-microvolt = <1140000 905000 1140000>; + opp-supported-hw = <0x70>; + clock-latency-ns = <200000>; + }; + opp-2150400000 { + opp-hz = /bits/ 64 <2150400000>; + opp-microvolt = <1140000 905000 1140000>; + opp-supported-hw = <0x31>; + clock-latency-ns = <200000>; + }; + opp-2342400000 { + opp-hz = /bits/ 64 <2342400000>; + opp-microvolt = <1140000 905000 1140000>; + opp-supported-hw = <0x10>; + clock-latency-ns = <200000>; + }; + }; + + smem { + compatible = "qcom,smem"; + memory-region = <&smem_mem>; + hwlocks = <&tcsr_mutex 3>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + + qfprom: qfprom@74000 { + compatible = "qcom,msm8996-qfprom", "qcom,qfprom"; + reg = <0x00074000 0x8ff>; + #address-cells = <1>; + #size-cells = <1>; + + speedbin_efuse: speedbin@133 { + reg = <0x133 0x1>; + bits = <5 3>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml b/Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml new file mode 100644 index 000000000000..14a7a689ad6d --- /dev/null +++ b/Documentation/devicetree/bindings/opp/opp-v2-qcom-level.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/opp/opp-v2-qcom-level.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm OPP bindings to describe OPP nodes. + +maintainers: + - Niklas Cassel <nks@flawful.org> + +allOf: + - $ref: opp-v2-base.yaml# + +properties: + compatible: + const: operating-points-v2-qcom-level + +patternProperties: + '^opp-?[0-9]+$': + type: object + + properties: + opp-level: true + + qcom,opp-fuse-level: + description: | + A positive value representing the fuse corner/level associated with + this OPP node. Sometimes several corners/levels shares a certain fuse + corner/level. A fuse corner/level contains e.g. ref uV, min uV, + and max uV. + $ref: /schemas/types.yaml#/definitions/uint32 + + required: + - opp-level + - qcom,opp-fuse-level + +required: + - compatible + +additionalProperties: false + +examples: + - | + cpr_opp_table: opp-table-cpr { + compatible = "operating-points-v2-qcom-level"; + + cpr_opp1: opp1 { + opp-level = <1>; + qcom,opp-fuse-level = <1>; + }; + cpr_opp2: opp2 { + opp-level = <2>; + qcom,opp-fuse-level = <2>; + }; + cpr_opp3: opp3 { + opp-level = <3>; + qcom,opp-fuse-level = <3>; + }; + }; diff --git a/Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt b/Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt deleted file mode 100644 index 64f07417ecfb..000000000000 --- a/Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt +++ /dev/null @@ -1,796 +0,0 @@ -Qualcomm Technologies, Inc. NVMEM CPUFreq and OPP bindings -=================================== - -In Certain Qualcomm Technologies, Inc. SoCs like apq8096 and msm8996, -the CPU frequencies subset and voltage value of each OPP varies based on -the silicon variant in use. -Qualcomm Technologies, Inc. Process Voltage Scaling Tables -defines the voltage and frequency value based on the msm-id in SMEM -and speedbin blown in the efuse combination. -The qcom-cpufreq-nvmem driver reads the msm-id and efuse value from the SoC -to provide the OPP framework with required information (existing HW bitmap). -This is used to determine the voltage and frequency value for each OPP of -operating-points-v2 table when it is parsed by the OPP framework. - -Required properties: --------------------- -In 'cpu' nodes: -- operating-points-v2: Phandle to the operating-points-v2 table to use. - -In 'operating-points-v2' table: -- compatible: Should be - - 'operating-points-v2-kryo-cpu' for apq8096, msm8996, msm8974, - apq8064, ipq8064, msm8960 and ipq8074. - -Optional properties: --------------------- -In 'cpu' nodes: -- power-domains: A phandle pointing to the PM domain specifier which provides - the performance states available for active state management. - Please refer to the power-domains bindings - Documentation/devicetree/bindings/power/power_domain.txt - and also examples below. -- power-domain-names: Should be - - 'cpr' for qcs404. - -In 'operating-points-v2' table: -- nvmem-cells: A phandle pointing to a nvmem-cells node representing the - efuse registers that has information about the - speedbin that is used to select the right frequency/voltage - value pair. - Please refer the for nvmem-cells - bindings Documentation/devicetree/bindings/nvmem/nvmem.txt - and also examples below. - -In every OPP node: -- opp-supported-hw: A single 32 bit bitmap value, representing compatible HW. - Bitmap: - 0: MSM8996 V3, speedbin 0 - 1: MSM8996 V3, speedbin 1 - 2: MSM8996 V3, speedbin 2 - 3: unused - 4: MSM8996 SG, speedbin 0 - 5: MSM8996 SG, speedbin 1 - 6: MSM8996 SG, speedbin 2 - 7-31: unused - -Example 1: ---------- - - cpus { - #address-cells = <2>; - #size-cells = <0>; - - CPU0: cpu@0 { - device_type = "cpu"; - compatible = "qcom,kryo"; - reg = <0x0 0x0>; - enable-method = "psci"; - clocks = <&kryocc 0>; - cpu-supply = <&pm8994_s11_saw>; - operating-points-v2 = <&cluster0_opp>; - #cooling-cells = <2>; - next-level-cache = <&L2_0>; - L2_0: l2-cache { - compatible = "cache"; - cache-level = <2>; - }; - }; - - CPU1: cpu@1 { - device_type = "cpu"; - compatible = "qcom,kryo"; - reg = <0x0 0x1>; - enable-method = "psci"; - clocks = <&kryocc 0>; - cpu-supply = <&pm8994_s11_saw>; - operating-points-v2 = <&cluster0_opp>; - #cooling-cells = <2>; - next-level-cache = <&L2_0>; - }; - - CPU2: cpu@100 { - device_type = "cpu"; - compatible = "qcom,kryo"; - reg = <0x0 0x100>; - enable-method = "psci"; - clocks = <&kryocc 1>; - cpu-supply = <&pm8994_s11_saw>; - operating-points-v2 = <&cluster1_opp>; - #cooling-cells = <2>; - next-level-cache = <&L2_1>; - L2_1: l2-cache { - compatible = "cache"; - cache-level = <2>; - }; - }; - - CPU3: cpu@101 { - device_type = "cpu"; - compatible = "qcom,kryo"; - reg = <0x0 0x101>; - enable-method = "psci"; - clocks = <&kryocc 1>; - cpu-supply = <&pm8994_s11_saw>; - operating-points-v2 = <&cluster1_opp>; - #cooling-cells = <2>; - next-level-cache = <&L2_1>; - }; - - cpu-map { - cluster0 { - core0 { - cpu = <&CPU0>; - }; - - core1 { - cpu = <&CPU1>; - }; - }; - - cluster1 { - core0 { - cpu = <&CPU2>; - }; - - core1 { - cpu = <&CPU3>; - }; - }; - }; - }; - - cluster0_opp: opp_table0 { - compatible = "operating-points-v2-kryo-cpu"; - nvmem-cells = <&speedbin_efuse>; - opp-shared; - - opp-307200000 { - opp-hz = /bits/ 64 <307200000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x77>; - clock-latency-ns = <200000>; - }; - opp-384000000 { - opp-hz = /bits/ 64 <384000000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-422400000 { - opp-hz = /bits/ 64 <422400000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-460800000 { - opp-hz = /bits/ 64 <460800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-480000000 { - opp-hz = /bits/ 64 <480000000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-537600000 { - opp-hz = /bits/ 64 <537600000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-556800000 { - opp-hz = /bits/ 64 <556800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-614400000 { - opp-hz = /bits/ 64 <614400000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-652800000 { - opp-hz = /bits/ 64 <652800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-691200000 { - opp-hz = /bits/ 64 <691200000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-729600000 { - opp-hz = /bits/ 64 <729600000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-768000000 { - opp-hz = /bits/ 64 <768000000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-844800000 { - opp-hz = /bits/ 64 <844800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x77>; - clock-latency-ns = <200000>; - }; - opp-902400000 { - opp-hz = /bits/ 64 <902400000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-960000000 { - opp-hz = /bits/ 64 <960000000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-979200000 { - opp-hz = /bits/ 64 <979200000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1036800000 { - opp-hz = /bits/ 64 <1036800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1056000000 { - opp-hz = /bits/ 64 <1056000000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1113600000 { - opp-hz = /bits/ 64 <1113600000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1132800000 { - opp-hz = /bits/ 64 <1132800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1190400000 { - opp-hz = /bits/ 64 <1190400000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1209600000 { - opp-hz = /bits/ 64 <1209600000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1228800000 { - opp-hz = /bits/ 64 <1228800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1286400000 { - opp-hz = /bits/ 64 <1286400000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1324800000 { - opp-hz = /bits/ 64 <1324800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x5>; - clock-latency-ns = <200000>; - }; - opp-1363200000 { - opp-hz = /bits/ 64 <1363200000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x72>; - clock-latency-ns = <200000>; - }; - opp-1401600000 { - opp-hz = /bits/ 64 <1401600000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x5>; - clock-latency-ns = <200000>; - }; - opp-1440000000 { - opp-hz = /bits/ 64 <1440000000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1478400000 { - opp-hz = /bits/ 64 <1478400000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x1>; - clock-latency-ns = <200000>; - }; - opp-1497600000 { - opp-hz = /bits/ 64 <1497600000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x4>; - clock-latency-ns = <200000>; - }; - opp-1516800000 { - opp-hz = /bits/ 64 <1516800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1593600000 { - opp-hz = /bits/ 64 <1593600000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x71>; - clock-latency-ns = <200000>; - }; - opp-1996800000 { - opp-hz = /bits/ 64 <1996800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x20>; - clock-latency-ns = <200000>; - }; - opp-2188800000 { - opp-hz = /bits/ 64 <2188800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x10>; - clock-latency-ns = <200000>; - }; - }; - - cluster1_opp: opp_table1 { - compatible = "operating-points-v2-kryo-cpu"; - nvmem-cells = <&speedbin_efuse>; - opp-shared; - - opp-307200000 { - opp-hz = /bits/ 64 <307200000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x77>; - clock-latency-ns = <200000>; - }; - opp-384000000 { - opp-hz = /bits/ 64 <384000000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-403200000 { - opp-hz = /bits/ 64 <403200000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-460800000 { - opp-hz = /bits/ 64 <460800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-480000000 { - opp-hz = /bits/ 64 <480000000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-537600000 { - opp-hz = /bits/ 64 <537600000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-556800000 { - opp-hz = /bits/ 64 <556800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-614400000 { - opp-hz = /bits/ 64 <614400000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-652800000 { - opp-hz = /bits/ 64 <652800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-691200000 { - opp-hz = /bits/ 64 <691200000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-729600000 { - opp-hz = /bits/ 64 <729600000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-748800000 { - opp-hz = /bits/ 64 <748800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-806400000 { - opp-hz = /bits/ 64 <806400000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-825600000 { - opp-hz = /bits/ 64 <825600000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-883200000 { - opp-hz = /bits/ 64 <883200000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-902400000 { - opp-hz = /bits/ 64 <902400000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-940800000 { - opp-hz = /bits/ 64 <940800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-979200000 { - opp-hz = /bits/ 64 <979200000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1036800000 { - opp-hz = /bits/ 64 <1036800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1056000000 { - opp-hz = /bits/ 64 <1056000000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1113600000 { - opp-hz = /bits/ 64 <1113600000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1132800000 { - opp-hz = /bits/ 64 <1132800000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1190400000 { - opp-hz = /bits/ 64 <1190400000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1209600000 { - opp-hz = /bits/ 64 <1209600000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1248000000 { - opp-hz = /bits/ 64 <1248000000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1286400000 { - opp-hz = /bits/ 64 <1286400000>; - opp-microvolt = <905000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1324800000 { - opp-hz = /bits/ 64 <1324800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1363200000 { - opp-hz = /bits/ 64 <1363200000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1401600000 { - opp-hz = /bits/ 64 <1401600000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1440000000 { - opp-hz = /bits/ 64 <1440000000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1478400000 { - opp-hz = /bits/ 64 <1478400000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1516800000 { - opp-hz = /bits/ 64 <1516800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1555200000 { - opp-hz = /bits/ 64 <1555200000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1593600000 { - opp-hz = /bits/ 64 <1593600000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1632000000 { - opp-hz = /bits/ 64 <1632000000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1670400000 { - opp-hz = /bits/ 64 <1670400000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1708800000 { - opp-hz = /bits/ 64 <1708800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1747200000 { - opp-hz = /bits/ 64 <1747200000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x70>; - clock-latency-ns = <200000>; - }; - opp-1785600000 { - opp-hz = /bits/ 64 <1785600000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x7>; - clock-latency-ns = <200000>; - }; - opp-1804800000 { - opp-hz = /bits/ 64 <1804800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x6>; - clock-latency-ns = <200000>; - }; - opp-1824000000 { - opp-hz = /bits/ 64 <1824000000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x71>; - clock-latency-ns = <200000>; - }; - opp-1900800000 { - opp-hz = /bits/ 64 <1900800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x74>; - clock-latency-ns = <200000>; - }; - opp-1920000000 { - opp-hz = /bits/ 64 <1920000000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x1>; - clock-latency-ns = <200000>; - }; - opp-1977600000 { - opp-hz = /bits/ 64 <1977600000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x30>; - clock-latency-ns = <200000>; - }; - opp-1996800000 { - opp-hz = /bits/ 64 <1996800000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x1>; - clock-latency-ns = <200000>; - }; - opp-2054400000 { - opp-hz = /bits/ 64 <2054400000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x30>; - clock-latency-ns = <200000>; - }; - opp-2073600000 { - opp-hz = /bits/ 64 <2073600000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x1>; - clock-latency-ns = <200000>; - }; - opp-2150400000 { - opp-hz = /bits/ 64 <2150400000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x31>; - clock-latency-ns = <200000>; - }; - opp-2246400000 { - opp-hz = /bits/ 64 <2246400000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x10>; - clock-latency-ns = <200000>; - }; - opp-2342400000 { - opp-hz = /bits/ 64 <2342400000>; - opp-microvolt = <1140000 905000 1140000>; - opp-supported-hw = <0x10>; - clock-latency-ns = <200000>; - }; - }; - -.... - -reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; -.... - smem_mem: smem-mem@86000000 { - reg = <0x0 0x86000000 0x0 0x200000>; - no-map; - }; -.... -}; - -smem { - compatible = "qcom,smem"; - memory-region = <&smem_mem>; - hwlocks = <&tcsr_mutex 3>; -}; - -soc { -.... - qfprom: qfprom@74000 { - compatible = "qcom,qfprom"; - reg = <0x00074000 0x8ff>; - #address-cells = <1>; - #size-cells = <1>; - .... - speedbin_efuse: speedbin@133 { - reg = <0x133 0x1>; - bits = <5 3>; - }; - }; -}; - -Example 2: ---------- - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - CPU0: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x100>; - .... - clocks = <&apcs_glb>; - operating-points-v2 = <&cpu_opp_table>; - power-domains = <&cpr>; - power-domain-names = "cpr"; - }; - - CPU1: cpu@101 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x101>; - .... - clocks = <&apcs_glb>; - operating-points-v2 = <&cpu_opp_table>; - power-domains = <&cpr>; - power-domain-names = "cpr"; - }; - - CPU2: cpu@102 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x102>; - .... - clocks = <&apcs_glb>; - operating-points-v2 = <&cpu_opp_table>; - power-domains = <&cpr>; - power-domain-names = "cpr"; - }; - - CPU3: cpu@103 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x103>; - .... - clocks = <&apcs_glb>; - operating-points-v2 = <&cpu_opp_table>; - power-domains = <&cpr>; - power-domain-names = "cpr"; - }; - }; - - cpu_opp_table: cpu-opp-table { - compatible = "operating-points-v2-kryo-cpu"; - opp-shared; - - opp-1094400000 { - opp-hz = /bits/ 64 <1094400000>; - required-opps = <&cpr_opp1>; - }; - opp-1248000000 { - opp-hz = /bits/ 64 <1248000000>; - required-opps = <&cpr_opp2>; - }; - opp-1401600000 { - opp-hz = /bits/ 64 <1401600000>; - required-opps = <&cpr_opp3>; - }; - }; - - cpr_opp_table: cpr-opp-table { - compatible = "operating-points-v2-qcom-level"; - - cpr_opp1: opp1 { - opp-level = <1>; - qcom,opp-fuse-level = <1>; - }; - cpr_opp2: opp2 { - opp-level = <2>; - qcom,opp-fuse-level = <2>; - }; - cpr_opp3: opp3 { - opp-level = <3>; - qcom,opp-fuse-level = <3>; - }; - }; - -.... - -soc { -.... - cpr: power-controller@b018000 { - compatible = "qcom,qcs404-cpr", "qcom,cpr"; - reg = <0x0b018000 0x1000>; - .... - vdd-apc-supply = <&pms405_s3>; - #power-domain-cells = <0>; - operating-points-v2 = <&cpr_opp_table>; - .... - }; -}; diff --git a/Documentation/devicetree/bindings/opp/qcom-opp.txt b/Documentation/devicetree/bindings/opp/qcom-opp.txt deleted file mode 100644 index 41d3e4ff2dc3..000000000000 --- a/Documentation/devicetree/bindings/opp/qcom-opp.txt +++ /dev/null @@ -1,19 +0,0 @@ -Qualcomm OPP bindings to describe OPP nodes - -The bindings are based on top of the operating-points-v2 bindings -described in Documentation/devicetree/bindings/opp/opp-v2-base.yaml -Additional properties are described below. - -* OPP Table Node - -Required properties: -- compatible: Allow OPPs to express their compatibility. It should be: - "operating-points-v2-qcom-level" - -* OPP Node - -Required properties: -- qcom,opp-fuse-level: A positive value representing the fuse corner/level - associated with this OPP node. Sometimes several corners/levels shares - a certain fuse corner/level. A fuse corner/level contains e.g. ref uV, - min uV, and max uV. diff --git a/Documentation/devicetree/bindings/power/avs/qcom,cpr.txt b/Documentation/devicetree/bindings/power/avs/qcom,cpr.txt deleted file mode 100644 index ab0d5ebbad4e..000000000000 --- a/Documentation/devicetree/bindings/power/avs/qcom,cpr.txt +++ /dev/null @@ -1,130 +0,0 @@ -QCOM CPR (Core Power Reduction) - -CPR (Core Power Reduction) is a technology to reduce core power on a CPU -or other device. Each OPP of a device corresponds to a "corner" that has -a range of valid voltages for a particular frequency. While the device is -running at a particular frequency, CPR monitors dynamic factors such as -temperature, etc. and suggests adjustments to the voltage to save power -and meet silicon characteristic requirements. - -- compatible: - Usage: required - Value type: <string> - Definition: should be "qcom,qcs404-cpr", "qcom,cpr" for qcs404 - -- reg: - Usage: required - Value type: <prop-encoded-array> - Definition: base address and size of the rbcpr register region - -- interrupts: - Usage: required - Value type: <prop-encoded-array> - Definition: should specify the CPR interrupt - -- clocks: - Usage: required - Value type: <prop-encoded-array> - Definition: phandle to the reference clock - -- clock-names: - Usage: required - Value type: <stringlist> - Definition: must be "ref" - -- vdd-apc-supply: - Usage: required - Value type: <phandle> - Definition: phandle to the vdd-apc-supply regulator - -- #power-domain-cells: - Usage: required - Value type: <u32> - Definition: should be 0 - -- operating-points-v2: - Usage: required - Value type: <phandle> - Definition: A phandle to the OPP table containing the - performance states supported by the CPR - power domain - -- acc-syscon: - Usage: optional - Value type: <phandle> - Definition: phandle to syscon for writing ACC settings - -- nvmem-cells: - Usage: required - Value type: <phandle> - Definition: phandle to nvmem cells containing the data - that makes up a fuse corner, for each fuse corner. - As well as the CPR fuse revision. - -- nvmem-cell-names: - Usage: required - Value type: <stringlist> - Definition: should be "cpr_quotient_offset1", "cpr_quotient_offset2", - "cpr_quotient_offset3", "cpr_init_voltage1", - "cpr_init_voltage2", "cpr_init_voltage3", "cpr_quotient1", - "cpr_quotient2", "cpr_quotient3", "cpr_ring_osc1", - "cpr_ring_osc2", "cpr_ring_osc3", "cpr_fuse_revision" - for qcs404. - -Example: - - cpr_opp_table: cpr-opp-table { - compatible = "operating-points-v2-qcom-level"; - - cpr_opp1: opp1 { - opp-level = <1>; - qcom,opp-fuse-level = <1>; - }; - cpr_opp2: opp2 { - opp-level = <2>; - qcom,opp-fuse-level = <2>; - }; - cpr_opp3: opp3 { - opp-level = <3>; - qcom,opp-fuse-level = <3>; - }; - }; - - power-controller@b018000 { - compatible = "qcom,qcs404-cpr", "qcom,cpr"; - reg = <0x0b018000 0x1000>; - interrupts = <0 15 IRQ_TYPE_EDGE_RISING>; - clocks = <&xo_board>; - clock-names = "ref"; - vdd-apc-supply = <&pms405_s3>; - #power-domain-cells = <0>; - operating-points-v2 = <&cpr_opp_table>; - acc-syscon = <&tcsr>; - - nvmem-cells = <&cpr_efuse_quot_offset1>, - <&cpr_efuse_quot_offset2>, - <&cpr_efuse_quot_offset3>, - <&cpr_efuse_init_voltage1>, - <&cpr_efuse_init_voltage2>, - <&cpr_efuse_init_voltage3>, - <&cpr_efuse_quot1>, - <&cpr_efuse_quot2>, - <&cpr_efuse_quot3>, - <&cpr_efuse_ring1>, - <&cpr_efuse_ring2>, - <&cpr_efuse_ring3>, - <&cpr_efuse_revision>; - nvmem-cell-names = "cpr_quotient_offset1", - "cpr_quotient_offset2", - "cpr_quotient_offset3", - "cpr_init_voltage1", - "cpr_init_voltage2", - "cpr_init_voltage3", - "cpr_quotient1", - "cpr_quotient2", - "cpr_quotient3", - "cpr_ring_osc1", - "cpr_ring_osc2", - "cpr_ring_osc3", - "cpr_fuse_revision"; - }; diff --git a/Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml b/Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml new file mode 100644 index 000000000000..3301fa0c2653 --- /dev/null +++ b/Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml @@ -0,0 +1,160 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/avs/qcom,cpr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Core Power Reduction (CPR) bindings + +maintainers: + - Niklas Cassel <nks@flawful.org> + +description: | + CPR (Core Power Reduction) is a technology to reduce core power on a CPU + or other device. Each OPP of a device corresponds to a "corner" that has + a range of valid voltages for a particular frequency. While the device is + running at a particular frequency, CPR monitors dynamic factors such as + temperature, etc. and suggests adjustments to the voltage to save power + and meet silicon characteristic requirements. + +properties: + compatible: + items: + - enum: + - qcom,qcs404-cpr + - const: qcom,cpr + + reg: + description: Base address and size of the RBCPR register region. + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: Reference clock. + + clock-names: + items: + - const: ref + + vdd-apc-supply: + description: APC regulator supply. + + '#power-domain-cells': + const: 0 + + operating-points-v2: + description: | + A phandle to the OPP table containing the performance states + supported by the CPR power domain. + + acc-syscon: + description: A phandle to the syscon used for writing ACC settings. + + nvmem-cells: + items: + - description: Corner 1 quotient offset + - description: Corner 2 quotient offset + - description: Corner 3 quotient offset + - description: Corner 1 initial voltage + - description: Corner 2 initial voltage + - description: Corner 3 initial voltage + - description: Corner 1 quotient + - description: Corner 2 quotient + - description: Corner 3 quotient + - description: Corner 1 ring oscillator + - description: Corner 2 ring oscillator + - description: Corner 3 ring oscillator + - description: Fuse revision + + nvmem-cell-names: + items: + - const: cpr_quotient_offset1 + - const: cpr_quotient_offset2 + - const: cpr_quotient_offset3 + - const: cpr_init_voltage1 + - const: cpr_init_voltage2 + - const: cpr_init_voltage3 + - const: cpr_quotient1 + - const: cpr_quotient2 + - const: cpr_quotient3 + - const: cpr_ring_osc1 + - const: cpr_ring_osc2 + - const: cpr_ring_osc3 + - const: cpr_fuse_revision + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - vdd-apc-supply + - '#power-domain-cells' + - operating-points-v2 + - nvmem-cells + - nvmem-cell-names + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + + cpr_opp_table: opp-table-cpr { + compatible = "operating-points-v2-qcom-level"; + + cpr_opp1: opp1 { + opp-level = <1>; + qcom,opp-fuse-level = <1>; + }; + cpr_opp2: opp2 { + opp-level = <2>; + qcom,opp-fuse-level = <2>; + }; + cpr_opp3: opp3 { + opp-level = <3>; + qcom,opp-fuse-level = <3>; + }; + }; + + power-controller@b018000 { + compatible = "qcom,qcs404-cpr", "qcom,cpr"; + reg = <0x0b018000 0x1000>; + interrupts = <0 15 IRQ_TYPE_EDGE_RISING>; + clocks = <&xo_board>; + clock-names = "ref"; + vdd-apc-supply = <&pms405_s3>; + #power-domain-cells = <0>; + operating-points-v2 = <&cpr_opp_table>; + acc-syscon = <&tcsr>; + + nvmem-cells = <&cpr_efuse_quot_offset1>, + <&cpr_efuse_quot_offset2>, + <&cpr_efuse_quot_offset3>, + <&cpr_efuse_init_voltage1>, + <&cpr_efuse_init_voltage2>, + <&cpr_efuse_init_voltage3>, + <&cpr_efuse_quot1>, + <&cpr_efuse_quot2>, + <&cpr_efuse_quot3>, + <&cpr_efuse_ring1>, + <&cpr_efuse_ring2>, + <&cpr_efuse_ring3>, + <&cpr_efuse_revision>; + nvmem-cell-names = "cpr_quotient_offset1", + "cpr_quotient_offset2", + "cpr_quotient_offset3", + "cpr_init_voltage1", + "cpr_init_voltage2", + "cpr_init_voltage3", + "cpr_quotient1", + "cpr_quotient2", + "cpr_quotient3", + "cpr_ring_osc1", + "cpr_ring_osc2", + "cpr_ring_osc3", + "cpr_fuse_revision"; + }; diff --git a/Documentation/power/energy-model.rst b/Documentation/power/energy-model.rst index 5ac62a7b4b7c..49549aab41b4 100644 --- a/Documentation/power/energy-model.rst +++ b/Documentation/power/energy-model.rst @@ -113,6 +113,16 @@ to: return warning/error, stop working or panic. See Section 3. for an example of driver implementing this callback, or Section 2.4 for further documentation on this API +Registration of EM using DT +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The EM can also be registered using OPP framework and information in DT +"operating-points-v2". Each OPP entry in DT can be extended with a property +"opp-microwatt" containing micro-Watts power value. This OPP DT property +allows a platform to register EM power values which are reflecting total power +(static + dynamic). These power values might be coming directly from +experiments and measurements. + Registration of 'simple' EM ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/MAINTAINERS b/MAINTAINERS index 4e8d9b1d6138..881eebbd14ed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15971,14 +15971,15 @@ M: Niklas Cassel <nks@flawful.org> L: linux-pm@vger.kernel.org L: linux-arm-msm@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/power/avs/qcom,cpr.txt +F: Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml F: drivers/soc/qcom/cpr.c QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096 M: Ilia Lin <ilia.lin@kernel.org> L: linux-pm@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/opp/qcom-nvmem-cpufreq.txt +F: Documentation/devicetree/bindings/cpufreq/qcom-cpufreq-nvmem.yaml +F: Documentation/devicetree/bindings/opp/opp-v2-kryo-cpu.yaml F: drivers/cpufreq/qcom-cpufreq-nvmem.c QUALCOMM CRYPTO DRIVERS diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts index 7d9fc35bc7a0..6a1699a96c99 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts +++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts @@ -9,7 +9,7 @@ / { model = "Qualcomm Technologies, Inc. MSM 8996 MTP"; - compatible = "qcom,msm8996-mtp"; + compatible = "qcom,msm8996-mtp", "qcom,msm8996"; aliases { serial0 = &blsp2_uart2; diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 91bc974aeb0a..036de52c54f1 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -134,7 +134,7 @@ }; }; - cluster0_opp: opp_table0 { + cluster0_opp: opp-table-cluster0 { compatible = "operating-points-v2-kryo-cpu"; nvmem-cells = <&speedbin_efuse>; opp-shared; @@ -222,7 +222,7 @@ }; }; - cluster1_opp: opp_table1 { + cluster1_opp: opp-table-cluster1 { compatible = "operating-points-v2-kryo-cpu"; nvmem-cells = <&speedbin_efuse>; opp-shared; diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi index 6db753b49326..3f06f7cd3cf2 100644 --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -110,7 +110,7 @@ }; }; - cpu_opp_table: cpu-opp-table { + cpu_opp_table: opp-table-cpu { compatible = "operating-points-v2-kryo-cpu"; opp-shared; @@ -128,7 +128,7 @@ }; }; - cpr_opp_table: cpr-opp-table { + cpr_opp_table: opp-table-cpr { compatible = "operating-points-v2-qcom-level"; cpr_opp1: opp1 { diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 3057beabd370..740407252298 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -114,6 +114,31 @@ unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) EXPORT_SYMBOL_GPL(dev_pm_opp_get_voltage); /** + * dev_pm_opp_get_power() - Gets the power corresponding to an opp + * @opp: opp for which power has to be returned for + * + * Return: power in micro watt corresponding to the opp, else + * return 0 + * + * This is useful only for devices with single power supply. + */ +unsigned long dev_pm_opp_get_power(struct dev_pm_opp *opp) +{ + unsigned long opp_power = 0; + int i; + + if (IS_ERR_OR_NULL(opp)) { + pr_err("%s: Invalid parameters\n", __func__); + return 0; + } + for (i = 0; i < opp->opp_table->regulator_count; i++) + opp_power += opp->supplies[i].u_watt; + + return opp_power; +} +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 * diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c index 596c185b5dda..3fcc1f97f2d1 100644 --- a/drivers/opp/debugfs.c +++ b/drivers/opp/debugfs.c @@ -10,6 +10,7 @@ #include <linux/debugfs.h> #include <linux/device.h> #include <linux/err.h> +#include <linux/of.h> #include <linux/init.h> #include <linux/limits.h> #include <linux/slab.h> @@ -99,6 +100,9 @@ static void opp_debug_create_supplies(struct dev_pm_opp *opp, debugfs_create_ulong("u_amp", S_IRUGO, d, &opp->supplies[i].u_amp); + + debugfs_create_ulong("u_watt", S_IRUGO, d, + &opp->supplies[i].u_watt); } } @@ -131,9 +135,13 @@ void opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table) debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend); debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate); debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate); + debugfs_create_u32("level", S_IRUGO, d, &opp->level); debugfs_create_ulong("clock_latency_ns", S_IRUGO, d, &opp->clock_latency_ns); + opp->of_name = of_node_full_name(opp->np); + debugfs_create_str("of_name", S_IRUGO, d, (char **)&opp->of_name); + opp_debug_create_supplies(opp, opp_table, d); opp_debug_create_bw(opp, opp_table, d); diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 2f40afa4e65c..440ab5a03df9 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -575,8 +575,9 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table, static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, struct opp_table *opp_table) { - u32 *microvolt, *microamp = NULL; - int supplies = opp_table->regulator_count, vcount, icount, ret, i, j; + u32 *microvolt, *microamp = NULL, *microwatt = NULL; + int supplies = opp_table->regulator_count; + int vcount, icount, pcount, ret, i, j; struct property *prop = NULL; char name[NAME_MAX]; @@ -688,6 +689,43 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, } } + /* Search for "opp-microwatt" */ + sprintf(name, "opp-microwatt"); + prop = of_find_property(opp->np, name, NULL); + + if (prop) { + pcount = of_property_count_u32_elems(opp->np, name); + if (pcount < 0) { + dev_err(dev, "%s: Invalid %s property (%d)\n", __func__, + name, pcount); + ret = pcount; + goto free_microamp; + } + + if (pcount != supplies) { + dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n", + __func__, name, pcount, supplies); + ret = -EINVAL; + goto free_microamp; + } + + microwatt = kmalloc_array(pcount, sizeof(*microwatt), + GFP_KERNEL); + if (!microwatt) { + ret = -EINVAL; + goto free_microamp; + } + + ret = of_property_read_u32_array(opp->np, name, microwatt, + pcount); + if (ret) { + dev_err(dev, "%s: error parsing %s: %d\n", __func__, + name, ret); + ret = -EINVAL; + goto free_microwatt; + } + } + for (i = 0, j = 0; i < supplies; i++) { opp->supplies[i].u_volt = microvolt[j++]; @@ -701,8 +739,13 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, if (microamp) opp->supplies[i].u_amp = microamp[i]; + + if (microwatt) + opp->supplies[i].u_watt = microwatt[i]; } +free_microwatt: + kfree(microwatt); free_microamp: kfree(microamp); free_microvolt: @@ -1397,6 +1440,38 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node); /* * Callback function provided to the Energy Model framework upon registration. + * It provides the power used by @dev at @kHz if it is the frequency of an + * existing OPP, or at the frequency of the first OPP above @kHz otherwise + * (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled + * frequency and @mW to the associated power. + * + * Returns 0 on success or a proper -EINVAL value in case of error. + */ +static int __maybe_unused +_get_dt_power(unsigned long *mW, unsigned long *kHz, struct device *dev) +{ + struct dev_pm_opp *opp; + unsigned long opp_freq, opp_power; + + /* Find the right frequency and related OPP */ + opp_freq = *kHz * 1000; + opp = dev_pm_opp_find_freq_ceil(dev, &opp_freq); + if (IS_ERR(opp)) + return -EINVAL; + + opp_power = dev_pm_opp_get_power(opp); + dev_pm_opp_put(opp); + if (!opp_power) + return -EINVAL; + + *kHz = opp_freq / 1000; + *mW = opp_power / 1000; + + return 0; +} + +/* + * Callback function provided to the Energy Model framework upon registration. * This computes the power estimated by @dev at @kHz if it is the frequency * of an existing OPP, or at the frequency of the first OPP above @kHz otherwise * (see dev_pm_opp_find_freq_ceil()). This function updates @kHz to the ceiled @@ -1445,6 +1520,24 @@ static int __maybe_unused _get_power(unsigned long *mW, unsigned long *kHz, return 0; } +static bool _of_has_opp_microwatt_property(struct device *dev) +{ + unsigned long power, freq = 0; + struct dev_pm_opp *opp; + + /* Check if at least one OPP has needed property */ + opp = dev_pm_opp_find_freq_ceil(dev, &freq); + if (IS_ERR(opp)) + return false; + + power = dev_pm_opp_get_power(opp); + dev_pm_opp_put(opp); + if (!power) + return false; + + return true; +} + /** * dev_pm_opp_of_register_em() - Attempt to register an Energy Model * @dev : Device for which an Energy Model has to be registered @@ -1458,7 +1551,7 @@ static int __maybe_unused _get_power(unsigned long *mW, unsigned long *kHz, */ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus) { - struct em_data_callback em_cb = EM_DATA_CB(_get_power); + struct em_data_callback em_cb; struct device_node *np; int ret, nr_opp; u32 cap; @@ -1474,6 +1567,12 @@ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus) goto failed; } + /* First, try to find more precised Energy Model in DT */ + if (_of_has_opp_microwatt_property(dev)) { + EM_SET_ACTIVE_POWER_CB(em_cb, _get_dt_power); + goto register_em; + } + np = of_node_get(dev->of_node); if (!np) { ret = -EINVAL; @@ -1495,6 +1594,9 @@ int dev_pm_opp_of_register_em(struct device *dev, struct cpumask *cpus) goto failed; } + EM_SET_ACTIVE_POWER_CB(em_cb, _get_power); + +register_em: ret = em_dev_register_perf_domain(dev, nr_opp, &em_cb, cpus, true); if (ret) goto failed; diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 407c3bfe51d9..45e3a55239a1 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -96,6 +96,7 @@ struct dev_pm_opp { #ifdef CONFIG_DEBUG_FS struct dentry *dentry; + const char *of_name; #endif }; diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index 6377adc3b78d..9f3c400bc52d 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -116,6 +116,7 @@ struct em_data_callback { struct device *dev); }; #define EM_DATA_CB(_active_power_cb) { .active_power = &_active_power_cb } +#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) ((em_cb).active_power = cb) struct em_perf_domain *em_cpu_get(int cpu); struct em_perf_domain *em_pd_get(struct device *dev); @@ -264,6 +265,7 @@ static inline int em_pd_nr_perf_states(struct em_perf_domain *pd) #else struct em_data_callback {}; #define EM_DATA_CB(_active_power_cb) { } +#define EM_SET_ACTIVE_POWER_CB(em_cb, cb) do { } while (0) static inline int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 879c138c7b8e..0d85a63a1f78 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -32,14 +32,17 @@ enum dev_pm_opp_event { * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP * @u_amp: Maximum current drawn by the device in microamperes + * @u_watt: Power used by the device in microwatts * - * This structure stores the voltage/current values for a single power supply. + * This structure stores the voltage/current/power values for a single power + * supply. */ struct dev_pm_opp_supply { unsigned long u_volt; unsigned long u_volt_min; unsigned long u_volt_max; unsigned long u_amp; + unsigned long u_watt; }; /** @@ -94,6 +97,8 @@ void dev_pm_opp_put_opp_table(struct opp_table *opp_table); unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); +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 int dev_pm_opp_get_level(struct dev_pm_opp *opp); @@ -186,6 +191,11 @@ static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) return 0; } +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) { return 0; |