diff options
23 files changed, 466 insertions, 309 deletions
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8939.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8939.yaml new file mode 100644 index 000000000000..fd15ab5014fb --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8939.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,msm8939.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm MSM8939 Network-On-Chip interconnect + +maintainers: + - Konrad Dybcio <[email protected]> + +description: | + The Qualcomm MSM8939 interconnect providers support adjusting the + bandwidth requirements between the various NoC fabrics. + +allOf: + - $ref: qcom,rpm-common.yaml# + +properties: + compatible: + enum: + - qcom,msm8939-bimc + - qcom,msm8939-pcnoc + - qcom,msm8939-snoc + + reg: + maxItems: 1 + +patternProperties: + '^interconnect-[a-z0-9\-]+$': + type: object + $ref: qcom,rpm-common.yaml# + description: + The interconnect providers do not have a separate QoS register space, + but share parent's space. + + allOf: + - $ref: qcom,rpm-common.yaml# + + properties: + compatible: + const: qcom,msm8939-snoc-mm + + required: + - compatible + + unevaluatedProperties: false + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/clock/qcom,rpmcc.h> + + snoc: interconnect@580000 { + compatible = "qcom,msm8939-snoc"; + reg = <0x00580000 0x14000>; + #interconnect-cells = <1>; + }; + + bimc: interconnect@400000 { + compatible = "qcom,msm8939-bimc"; + reg = <0x00400000 0x62000>; + #interconnect-cells = <1>; + + snoc_mm: interconnect-snoc { + compatible = "qcom,msm8939-snoc-mm"; + #interconnect-cells = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8996.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8996.yaml new file mode 100644 index 000000000000..e3f964aaad1b --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8996.yaml @@ -0,0 +1,126 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,msm8996.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm MSM8996 Network-On-Chip interconnect + +maintainers: + - Konrad Dybcio <[email protected]> + +description: | + The Qualcomm MSM8996 interconnect providers support adjusting the + bandwidth requirements between the various NoC fabrics. + +properties: + compatible: + enum: + - qcom,msm8996-a0noc + - qcom,msm8996-a1noc + - qcom,msm8996-a2noc + - qcom,msm8996-bimc + - qcom,msm8996-cnoc + - qcom,msm8996-mnoc + - qcom,msm8996-pnoc + - qcom,msm8996-snoc + + reg: + maxItems: 1 + + clock-names: + minItems: 1 + maxItems: 3 + + clocks: + minItems: 1 + maxItems: 3 + + power-domains: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +allOf: + - $ref: qcom,rpm-common.yaml# + - if: + properties: + compatible: + const: qcom,msm8996-a0noc + + then: + properties: + clocks: + items: + - description: Aggregate0 System NoC AXI Clock. + - description: Aggregate0 Config NoC AHB Clock. + - description: Aggregate0 NoC MPU Clock. + + clock-names: + items: + - const: aggre0_snoc_axi + - const: aggre0_cnoc_ahb + - const: aggre0_noc_mpu_cfg + + required: + - power-domains + + - if: + properties: + compatible: + const: qcom,msm8996-mnoc + + then: + properties: + clocks: + items: + - description: CPU-NoC High-performance Bus Clock. + + clock-names: + const: iface + + - if: + properties: + compatible: + const: qcom,msm8996-a2noc + + then: + properties: + clocks: + items: + - description: Aggregate2 NoC UFS AXI Clock + - description: UFS AXI Clock + + clock-names: + items: + - const: aggre2_ufs_axi + - const: ufs_axi + +examples: + - | + #include <dt-bindings/clock/qcom,gcc-msm8996.h> + #include <dt-bindings/clock/qcom,mmcc-msm8996.h> + #include <dt-bindings/clock/qcom,rpmcc.h> + + bimc: interconnect@408000 { + compatible = "qcom,msm8996-bimc"; + reg = <0x00408000 0x5a000>; + #interconnect-cells = <1>; + }; + + a0noc: interconnect@543000 { + compatible = "qcom,msm8996-a0noc"; + reg = <0x00543000 0x6000>; + #interconnect-cells = <1>; + clocks = <&gcc GCC_AGGRE0_SNOC_AXI_CLK>, + <&gcc GCC_AGGRE0_CNOC_AHB_CLK>, + <&gcc GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK>; + clock-names = "aggre0_snoc_axi", + "aggre0_cnoc_ahb", + "aggre0_noc_mpu_cfg"; + power-domains = <&gcc AGGRE0_NOC_GDSC>; + }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcm2290.yaml b/Documentation/devicetree/bindings/interconnect/qcom,qcm2290.yaml index f65a2fe846de..b6c15314c5c5 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,qcm2290.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,qcm2290.yaml @@ -13,6 +13,9 @@ description: | The Qualcomm QCM2290 interconnect providers support adjusting the bandwidth requirements between the various NoC fabrics. +allOf: + - $ref: qcom,rpm-common.yaml# + properties: reg: maxItems: 1 @@ -23,19 +26,6 @@ properties: - qcom,qcm2290-cnoc - qcom,qcm2290-snoc - '#interconnect-cells': - const: 1 - - clock-names: - items: - - const: bus - - const: bus_a - - clocks: - items: - - description: Bus Clock - - description: Bus A Clock - # Child node's properties patternProperties: '^interconnect-[a-z0-9]+$': @@ -44,6 +34,9 @@ patternProperties: The interconnect providers do not have a separate QoS register space, but share parent's space. + allOf: + - $ref: qcom,rpm-common.yaml# + properties: compatible: enum: @@ -51,35 +44,16 @@ patternProperties: - qcom,qcm2290-mmrt-virt - qcom,qcm2290-mmnrt-virt - '#interconnect-cells': - const: 1 - - clock-names: - items: - - const: bus - - const: bus_a - - clocks: - items: - - description: Bus Clock - - description: Bus A Clock - required: - compatible - - '#interconnect-cells' - - clock-names - - clocks - additionalProperties: false + unevaluatedProperties: false required: - compatible - reg - - '#interconnect-cells' - - clock-names - - clocks -additionalProperties: false +unevaluatedProperties: false examples: - | @@ -89,32 +63,20 @@ examples: compatible = "qcom,qcm2290-snoc"; reg = <0x01880000 0x60200>; #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_SNOC_CLK>, - <&rpmcc RPM_SMD_SNOC_A_CLK>; qup_virt: interconnect-qup { compatible = "qcom,qcm2290-qup-virt"; #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_QUP_CLK>, - <&rpmcc RPM_SMD_QUP_A_CLK>; }; mmnrt_virt: interconnect-mmnrt { compatible = "qcom,qcm2290-mmnrt-virt"; #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_MMNRT_CLK>, - <&rpmcc RPM_SMD_MMNRT_A_CLK>; }; mmrt_virt: interconnect-mmrt { compatible = "qcom,qcm2290-mmrt-virt"; #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_MMRT_CLK>, - <&rpmcc RPM_SMD_MMRT_A_CLK>; }; }; @@ -122,16 +84,10 @@ examples: compatible = "qcom,qcm2290-cnoc"; reg = <0x01900000 0x8200>; #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_CNOC_CLK>, - <&rpmcc RPM_SMD_CNOC_A_CLK>; }; bimc: interconnect@4480000 { compatible = "qcom,qcm2290-bimc"; reg = <0x04480000 0x80000>; #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_BIMC_CLK>, - <&rpmcc RPM_SMD_BIMC_A_CLK>; }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpm-common.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpm-common.yaml new file mode 100644 index 000000000000..1ea52b091609 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpm-common.yaml @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,rpm-common.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm RPMh Network-On-Chip Interconnect + +maintainers: + - Konrad Dybcio <[email protected]> + +description: + RPM interconnect providers support for managing system bandwidth requirements + through manual requests based on either predefined values or as indicated by + the bus monitor hardware. Each provider node represents a NoC bus master, + driven by a dedicated clock source. + +properties: + '#interconnect-cells': + oneOf: + - const: 2 + - const: 1 + deprecated: true + +required: + - '#interconnect-cells' + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml index 4f95d512012a..08c1c6b9d7cf 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml @@ -7,13 +7,16 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm RPM Network-On-Chip Interconnect maintainers: - - Georgi Djakov <[email protected]> + - Georgi Djakov <[email protected]> description: | RPM interconnect providers support system bandwidth requirements through RPM processor. The provider is able to communicate with the RPM through the RPM shared memory device. +allOf: + - $ref: qcom,rpm-common.yaml# + properties: reg: maxItems: 1 @@ -23,259 +26,22 @@ properties: - qcom,msm8916-bimc - qcom,msm8916-pcnoc - qcom,msm8916-snoc - - qcom,msm8939-bimc - - qcom,msm8939-pcnoc - - qcom,msm8939-snoc - - qcom,msm8996-a0noc - - qcom,msm8996-a1noc - - qcom,msm8996-a2noc - - qcom,msm8996-bimc - - qcom,msm8996-cnoc - - qcom,msm8996-mnoc - - qcom,msm8996-pnoc - - qcom,msm8996-snoc - qcom,qcs404-bimc - qcom,qcs404-pcnoc - qcom,qcs404-snoc - - qcom,sdm660-a2noc - - qcom,sdm660-bimc - - qcom,sdm660-cnoc - - qcom,sdm660-gnoc - - qcom,sdm660-mnoc - - qcom,sdm660-snoc - - '#interconnect-cells': - description: | - Value: <1> is one cell in an interconnect specifier for the - interconnect node id, <2> requires the interconnect node id and an - extra path tag. - enum: [ 1, 2 ] - - clocks: - minItems: 2 - maxItems: 7 - - clock-names: - minItems: 2 - maxItems: 7 - - power-domains: - maxItems: 1 - -# Child node's properties -patternProperties: - '^interconnect-[a-z0-9]+$': - type: object - additionalProperties: false - description: - snoc-mm is a child of snoc, sharing snoc's register address space. - - properties: - compatible: - enum: - - qcom,msm8939-snoc-mm - - '#interconnect-cells': - const: 1 - - clock-names: - items: - - const: bus - - const: bus_a - - clocks: - items: - - description: Bus Clock - - description: Bus A Clock - - required: - - compatible - - '#interconnect-cells' - - clock-names - - clocks required: - compatible - reg - - '#interconnect-cells' - - clock-names - - clocks - -additionalProperties: false - -allOf: - - if: - properties: - compatible: - contains: - enum: - - qcom,msm8916-bimc - - qcom,msm8916-pcnoc - - qcom,msm8916-snoc - - qcom,msm8939-bimc - - qcom,msm8939-pcnoc - - qcom,msm8939-snoc - - qcom,msm8996-a1noc - - qcom,msm8996-bimc - - qcom,msm8996-cnoc - - qcom,msm8996-pnoc - - qcom,msm8996-snoc - - qcom,qcs404-bimc - - qcom,qcs404-pcnoc - - qcom,qcs404-snoc - - qcom,sdm660-bimc - - qcom,sdm660-cnoc - - qcom,sdm660-gnoc - - qcom,sdm660-snoc - - then: - properties: - clock-names: - items: - - const: bus - - const: bus_a - - clocks: - items: - - description: Bus Clock - - description: Bus A Clock - - if: - properties: - compatible: - contains: - enum: - - qcom,msm8996-mnoc - - qcom,sdm660-mnoc - - then: - properties: - clock-names: - items: - - const: bus - - const: bus_a - - const: iface - - clocks: - items: - - description: Bus Clock. - - description: Bus A Clock. - - description: CPU-NoC High-performance Bus Clock. - - - if: - properties: - compatible: - contains: - enum: - - qcom,msm8996-a0noc - - then: - properties: - clock-names: - items: - - const: aggre0_snoc_axi - - const: aggre0_cnoc_ahb - - const: aggre0_noc_mpu_cfg - - clocks: - items: - - description: Aggregate0 System NoC AXI Clock. - - description: Aggregate0 Config NoC AHB Clock. - - description: Aggregate0 NoC MPU Clock. - - required: - - power-domains - - - if: - properties: - compatible: - contains: - enum: - - qcom,msm8996-a2noc - - then: - properties: - clock-names: - items: - - const: bus - - const: bus_a - - const: aggre2_ufs_axi - - const: ufs_axi - - clocks: - items: - - description: Bus Clock - - description: Bus A Clock - - description: Aggregate2 NoC UFS AXI Clock - - description: UFS AXI Clock - - - if: - properties: - compatible: - contains: - enum: - - qcom,sdm660-a2noc - - then: - properties: - clock-names: - items: - - const: bus - - const: bus_a - - const: ipa - - const: ufs_axi - - const: aggre2_ufs_axi - - const: aggre2_usb3_axi - - const: cfg_noc_usb2_axi - - clocks: - items: - - description: Bus Clock. - - description: Bus A Clock. - - description: IPA Clock. - - description: UFS AXI Clock. - - description: Aggregate2 UFS AXI Clock. - - description: Aggregate2 USB3 AXI Clock. - - description: Config NoC USB2 AXI Clock. - - - if: - not: - properties: - compatible: - contains: - enum: - - qcom,msm8939-snoc - then: - patternProperties: - '^interconnect-[a-z0-9]+$': false +unevaluatedProperties: false examples: - | #include <dt-bindings/clock/qcom,rpmcc.h> bimc: interconnect@400000 { - compatible = "qcom,msm8916-bimc"; - reg = <0x00400000 0x62000>; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_BIMC_CLK>, - <&rpmcc RPM_SMD_BIMC_A_CLK>; - }; - - pcnoc: interconnect@500000 { - compatible = "qcom,msm8916-pcnoc"; - reg = <0x00500000 0x11000>; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_PCNOC_CLK>, - <&rpmcc RPM_SMD_PCNOC_A_CLK>; - }; - - snoc: interconnect@580000 { - compatible = "qcom,msm8916-snoc"; - reg = <0x00580000 0x14000>; - #interconnect-cells = <1>; - clock-names = "bus", "bus_a"; - clocks = <&rpmcc RPM_SMD_SNOC_CLK>, - <&rpmcc RPM_SMD_SNOC_A_CLK>; + compatible = "qcom,msm8916-bimc"; + reg = <0x00400000 0x62000>; + #interconnect-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml b/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml new file mode 100644 index 000000000000..8f6bc6399626 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,sdm660.yaml @@ -0,0 +1,108 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,sdm660.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm SDM660 Network-On-Chip interconnect + +maintainers: + - Konrad Dybcio <[email protected]> + +description: | + The Qualcomm SDM660 interconnect providers support adjusting the + bandwidth requirements between the various NoC fabrics. + +properties: + compatible: + enum: + - qcom,sdm660-a2noc + - qcom,sdm660-bimc + - qcom,sdm660-cnoc + - qcom,sdm660-gnoc + - qcom,sdm660-mnoc + - qcom,sdm660-snoc + + reg: + maxItems: 1 + + clock-names: + minItems: 1 + maxItems: 5 + + clocks: + minItems: 1 + maxItems: 5 + +required: + - compatible + - reg + +unevaluatedProperties: false + +allOf: + - $ref: qcom,rpm-common.yaml# + - if: + properties: + compatible: + const: qcom,sdm660-mnoc + + then: + properties: + clocks: + items: + - description: CPU-NoC High-performance Bus Clock. + + clock-names: + const: iface + + - if: + properties: + compatible: + const: qcom,sdm660-a2noc + + then: + properties: + clocks: + items: + - description: IPA Clock. + - description: UFS AXI Clock. + - description: Aggregate2 UFS AXI Clock. + - description: Aggregate2 USB3 AXI Clock. + - description: Config NoC USB2 AXI Clock. + + clock-names: + items: + - const: ipa + - const: ufs_axi + - const: aggre2_ufs_axi + - const: aggre2_usb3_axi + - const: cfg_noc_usb2_axi + +examples: + - | + #include <dt-bindings/clock/qcom,gcc-sdm660.h> + #include <dt-bindings/clock/qcom,mmcc-sdm660.h> + #include <dt-bindings/clock/qcom,rpmcc.h> + + bimc: interconnect@1008000 { + compatible = "qcom,sdm660-bimc"; + reg = <0x01008000 0x78000>; + #interconnect-cells = <1>; + }; + + a2noc: interconnect@1704000 { + compatible = "qcom,sdm660-a2noc"; + reg = <0x01704000 0xc100>; + #interconnect-cells = <1>; + clocks = <&rpmcc RPM_SMD_IPA_CLK>, + <&gcc GCC_UFS_AXI_CLK>, + <&gcc GCC_AGGRE2_UFS_AXI_CLK>, + <&gcc GCC_AGGRE2_USB3_AXI_CLK>, + <&gcc GCC_CFG_NOC_USB2_AXI_CLK>; + clock-names = "ipa", + "ufs_axi", + "aggre2_ufs_axi", + "aggre2_usb3_axi", + "cfg_noc_usb2_axi"; + }; diff --git a/drivers/interconnect/qcom/icc-rpm-clocks.c b/drivers/interconnect/qcom/icc-rpm-clocks.c index 63c82a91bbc7..ac1677de7dfd 100644 --- a/drivers/interconnect/qcom/icc-rpm-clocks.c +++ b/drivers/interconnect/qcom/icc-rpm-clocks.c @@ -25,6 +25,12 @@ const struct rpm_clk_resource bimc_clk = { }; EXPORT_SYMBOL_GPL(bimc_clk); +const struct rpm_clk_resource mem_1_clk = { + .resource_type = QCOM_SMD_RPM_MEM_CLK, + .clock_id = 1, +}; +EXPORT_SYMBOL_GPL(mem_1_clk); + const struct rpm_clk_resource bus_0_clk = { .resource_type = QCOM_SMD_RPM_BUS_CLK, .clock_id = 0, diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c index 2c16917ba1fd..9c40314e03b5 100644 --- a/drivers/interconnect/qcom/icc-rpm.c +++ b/drivers/interconnect/qcom/icc-rpm.c @@ -291,6 +291,32 @@ static int qcom_icc_bw_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, return 0; } +static u64 qcom_icc_calc_rate(struct qcom_icc_provider *qp, struct qcom_icc_node *qn, int ctx) +{ + u64 agg_avg_rate, agg_peak_rate, agg_rate; + + if (qn->channels) + agg_avg_rate = div_u64(qn->sum_avg[ctx], qn->channels); + else + agg_avg_rate = qn->sum_avg[ctx]; + + if (qn->ab_coeff) { + agg_avg_rate = agg_avg_rate * qn->ab_coeff; + agg_avg_rate = div_u64(agg_avg_rate, 100); + } + + if (qn->ib_coeff) { + agg_peak_rate = qn->max_peak[ctx] * 100; + agg_peak_rate = div_u64(qn->max_peak[ctx], qn->ib_coeff); + } else { + agg_peak_rate = qn->max_peak[ctx]; + } + + agg_rate = max_t(u64, agg_avg_rate, agg_peak_rate); + + return div_u64(agg_rate, qn->buswidth); +} + /** * qcom_icc_bus_aggregate - calculate bus clock rates by traversing all nodes * @provider: generic interconnect provider @@ -298,10 +324,10 @@ static int qcom_icc_bw_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, */ static void qcom_icc_bus_aggregate(struct icc_provider *provider, u64 *agg_clk_rate) { - u64 agg_avg_rate, agg_rate; + struct qcom_icc_provider *qp = to_qcom_provider(provider); struct qcom_icc_node *qn; struct icc_node *node; - int i; + int ctx; /* * Iterate nodes on the provider, aggregate bandwidth requests for @@ -309,16 +335,9 @@ static void qcom_icc_bus_aggregate(struct icc_provider *provider, u64 *agg_clk_r */ list_for_each_entry(node, &provider->nodes, node_list) { qn = node->data; - for (i = 0; i < QCOM_SMD_RPM_STATE_NUM; i++) { - if (qn->channels) - agg_avg_rate = div_u64(qn->sum_avg[i], qn->channels); - else - agg_avg_rate = qn->sum_avg[i]; - - agg_rate = max_t(u64, agg_avg_rate, qn->max_peak[i]); - do_div(agg_rate, qn->buswidth); - - agg_clk_rate[i] = max_t(u64, agg_clk_rate[i], agg_rate); + for (ctx = 0; ctx < QCOM_SMD_RPM_STATE_NUM; ctx++) { + agg_clk_rate[ctx] = max_t(u64, agg_clk_rate[ctx], + qcom_icc_calc_rate(qp, qn, ctx)); } } } @@ -395,6 +414,33 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst) qp->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE] = sleep_rate; } + /* Handle the node-specific clock */ + if (!src_qn->bus_clk_desc) + return 0; + + active_rate = qcom_icc_calc_rate(qp, src_qn, QCOM_SMD_RPM_ACTIVE_STATE); + sleep_rate = qcom_icc_calc_rate(qp, src_qn, QCOM_SMD_RPM_SLEEP_STATE); + + if (active_rate != src_qn->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE]) { + ret = qcom_icc_rpm_set_bus_rate(src_qn->bus_clk_desc, QCOM_SMD_RPM_ACTIVE_STATE, + active_rate); + if (ret) + return ret; + + /* Cache the rate after we've successfully committed it to RPM */ + src_qn->bus_clk_rate[QCOM_SMD_RPM_ACTIVE_STATE] = active_rate; + } + + if (sleep_rate != src_qn->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE]) { + ret = qcom_icc_rpm_set_bus_rate(src_qn->bus_clk_desc, QCOM_SMD_RPM_SLEEP_STATE, + sleep_rate); + if (ret) + return ret; + + /* Cache the rate after we've successfully committed it to RPM */ + src_qn->bus_clk_rate[QCOM_SMD_RPM_SLEEP_STATE] = sleep_rate; + } + return 0; } @@ -517,6 +563,12 @@ regmap_done: for (i = 0; i < num_nodes; i++) { size_t j; + if (!qnodes[i]->ab_coeff) + qnodes[i]->ab_coeff = qp->ab_coeff; + + if (!qnodes[i]->ib_coeff) + qnodes[i]->ib_coeff = qp->ib_coeff; + node = icc_node_create(qnodes[i]->id); if (IS_ERR(node)) { ret = PTR_ERR(node); diff --git a/drivers/interconnect/qcom/icc-rpm.h b/drivers/interconnect/qcom/icc-rpm.h index eed3451af3e6..a13768cfd231 100644 --- a/drivers/interconnect/qcom/icc-rpm.h +++ b/drivers/interconnect/qcom/icc-rpm.h @@ -44,6 +44,8 @@ struct rpm_clk_resource { * @type: the ICC provider type * @regmap: regmap for QoS registers read/write access * @qos_offset: offset to QoS registers + * @ab_coeff: a percentage-based coefficient for compensating the AB calculations + * @ib_coeff: an inverse-percentage-based coefficient for compensating the IB calculations * @bus_clk_rate: bus clock rate in Hz * @bus_clk_desc: a pointer to a rpm_clk_resource description of bus clocks * @bus_clk: a pointer to a HLOS-owned bus clock @@ -57,6 +59,8 @@ struct qcom_icc_provider { enum qcom_icc_type type; struct regmap *regmap; unsigned int qos_offset; + u16 ab_coeff; + u16 ib_coeff; u32 bus_clk_rate[QCOM_SMD_RPM_STATE_NUM]; const struct rpm_clk_resource *bus_clk_desc; struct clk *bus_clk; @@ -93,11 +97,15 @@ struct qcom_icc_qos { * @num_links: the total number of @links * @channels: number of channels at this node (e.g. DDR channels) * @buswidth: width of the interconnect between a node and the bus (bytes) + * @bus_clk_desc: a pointer to a rpm_clk_resource description of bus clocks * @sum_avg: current sum aggregate value of all avg bw requests * @max_peak: current max aggregate value of all peak bw requests * @mas_rpm_id: RPM id for devices that are bus masters * @slv_rpm_id: RPM id for devices that are bus slaves * @qos: NoC QoS setting parameters + * @ab_coeff: a percentage-based coefficient for compensating the AB calculations + * @ib_coeff: an inverse-percentage-based coefficient for compensating the IB calculations + * @bus_clk_rate: a pointer to an array containing bus clock rates in Hz */ struct qcom_icc_node { unsigned char *name; @@ -106,11 +114,15 @@ struct qcom_icc_node { u16 num_links; u16 channels; u16 buswidth; + const struct rpm_clk_resource *bus_clk_desc; u64 sum_avg[QCOM_SMD_RPM_STATE_NUM]; u64 max_peak[QCOM_SMD_RPM_STATE_NUM]; int mas_rpm_id; int slv_rpm_id; struct qcom_icc_qos qos; + u16 ab_coeff; + u16 ib_coeff; + u32 bus_clk_rate[QCOM_SMD_RPM_STATE_NUM]; }; struct qcom_icc_desc { @@ -123,6 +135,8 @@ struct qcom_icc_desc { enum qcom_icc_type type; const struct regmap_config *regmap_cfg; unsigned int qos_offset; + u16 ab_coeff; + u16 ib_coeff; }; /* Valid for all bus types */ @@ -138,6 +152,7 @@ extern const struct rpm_clk_resource bimc_clk; extern const struct rpm_clk_resource bus_0_clk; extern const struct rpm_clk_resource bus_1_clk; extern const struct rpm_clk_resource bus_2_clk; +extern const struct rpm_clk_resource mem_1_clk; extern const struct rpm_clk_resource mmaxi_0_clk; extern const struct rpm_clk_resource mmaxi_1_clk; extern const struct rpm_clk_resource qup_clk; diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c index 88683dfa468f..b73566c9b21f 100644 --- a/drivers/interconnect/qcom/msm8996.c +++ b/drivers/interconnect/qcom/msm8996.c @@ -448,6 +448,7 @@ static struct qcom_icc_node mas_mdp_p0 = { .name = "mas_mdp_p0", .id = MSM8996_MASTER_MDP_PORT0, .buswidth = 32, + .ib_coeff = 25, .mas_rpm_id = 8, .slv_rpm_id = -1, .qos.ap_owned = true, @@ -463,6 +464,7 @@ static struct qcom_icc_node mas_mdp_p1 = { .name = "mas_mdp_p1", .id = MSM8996_MASTER_MDP_PORT1, .buswidth = 32, + .ib_coeff = 25, .mas_rpm_id = 61, .slv_rpm_id = -1, .qos.ap_owned = true, @@ -1889,7 +1891,8 @@ static const struct qcom_icc_desc msm8996_bimc = { .nodes = bimc_nodes, .num_nodes = ARRAY_SIZE(bimc_nodes), .bus_clk_desc = &bimc_clk, - .regmap_cfg = &msm8996_bimc_regmap_config + .regmap_cfg = &msm8996_bimc_regmap_config, + .ab_coeff = 154, }; static struct qcom_icc_node * const cnoc_nodes[] = { @@ -2004,7 +2007,8 @@ static const struct qcom_icc_desc msm8996_mnoc = { .bus_clk_desc = &mmaxi_0_clk, .intf_clocks = mm_intf_clocks, .num_intf_clocks = ARRAY_SIZE(mm_intf_clocks), - .regmap_cfg = &msm8996_mnoc_regmap_config + .regmap_cfg = &msm8996_mnoc_regmap_config, + .ab_coeff = 154, }; static struct qcom_icc_node * const pnoc_nodes[] = { diff --git a/drivers/interconnect/qcom/qcm2290.c b/drivers/interconnect/qcom/qcm2290.c index 5bc4b7516608..b88cf9a022e0 100644 --- a/drivers/interconnect/qcom/qcm2290.c +++ b/drivers/interconnect/qcom/qcm2290.c @@ -112,6 +112,9 @@ static struct qcom_icc_node mas_appss_proc = { .qos.qos_mode = NOC_QOS_MODE_FIXED, .qos.prio_level = 0, .qos.areq_prio = 0, + .bus_clk_desc = &mem_1_clk, + .ab_coeff = 159, + .ib_coeff = 96, .mas_rpm_id = 0, .slv_rpm_id = -1, .num_links = ARRAY_SIZE(mas_appss_proc_links), @@ -675,7 +678,8 @@ static struct qcom_icc_node mas_gfx3d = { static struct qcom_icc_node slv_ebi1 = { .name = "slv_ebi1", .id = QCM2290_SLAVE_EBI1, - .buswidth = 8, + .buswidth = 4, + .channels = 2, .mas_rpm_id = -1, .slv_rpm_id = 0, }; @@ -1199,6 +1203,7 @@ static const struct qcom_icc_desc qcm2290_bimc = { .keep_alive = true, /* M_REG_BASE() in vendor msm_bus_bimc_adhoc driver */ .qos_offset = 0x8000, + .ab_coeff = 153, }; static struct qcom_icc_node * const qcm2290_cnoc_nodes[] = { @@ -1329,6 +1334,7 @@ static const struct qcom_icc_desc qcm2290_mmnrt_virt = { .regmap_cfg = &qcm2290_snoc_regmap_config, .keep_alive = true, .qos_offset = 0x15000, + .ab_coeff = 142, }; static struct qcom_icc_node * const qcm2290_mmrt_virt_nodes[] = { @@ -1345,6 +1351,7 @@ static const struct qcom_icc_desc qcm2290_mmrt_virt = { .regmap_cfg = &qcm2290_snoc_regmap_config, .keep_alive = true, .qos_offset = 0x15000, + .ab_coeff = 139, }; static const struct of_device_id qcm2290_noc_of_match[] = { diff --git a/drivers/interconnect/qcom/qdu1000.c b/drivers/interconnect/qcom/qdu1000.c index bf800dd7d4ba..a7392eb73d4a 100644 --- a/drivers/interconnect/qcom/qdu1000.c +++ b/drivers/interconnect/qcom/qdu1000.c @@ -769,6 +769,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .num_nodes = 1, .nodes = { &ebi }, }; diff --git a/drivers/interconnect/qcom/sc7180.c b/drivers/interconnect/qcom/sc7180.c index d94ab9b39f3d..af2be1543840 100644 --- a/drivers/interconnect/qcom/sc7180.c +++ b/drivers/interconnect/qcom/sc7180.c @@ -1238,6 +1238,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .keepalive = false, .num_nodes = 1, .nodes = { &ebi }, diff --git a/drivers/interconnect/qcom/sc7280.c b/drivers/interconnect/qcom/sc7280.c index 6592839b4d94..a626dbc71999 100644 --- a/drivers/interconnect/qcom/sc7280.c +++ b/drivers/interconnect/qcom/sc7280.c @@ -1285,6 +1285,7 @@ static struct qcom_icc_node srvc_snoc = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .num_nodes = 1, .nodes = { &ebi }, }; diff --git a/drivers/interconnect/qcom/sc8180x.c b/drivers/interconnect/qcom/sc8180x.c index 0fb4898dabcf..bdd3471d4ac8 100644 --- a/drivers/interconnect/qcom/sc8180x.c +++ b/drivers/interconnect/qcom/sc8180x.c @@ -1345,6 +1345,7 @@ static struct qcom_icc_node slv_qup_core_2 = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .num_nodes = 1, .nodes = { &slv_ebi } }; diff --git a/drivers/interconnect/qcom/sc8280xp.c b/drivers/interconnect/qcom/sc8280xp.c index b82c5493cbb5..0270f6c64481 100644 --- a/drivers/interconnect/qcom/sc8280xp.c +++ b/drivers/interconnect/qcom/sc8280xp.c @@ -1712,6 +1712,7 @@ static struct qcom_icc_node srvc_snoc = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .num_nodes = 1, .nodes = { &ebi }, }; diff --git a/drivers/interconnect/qcom/sdm660.c b/drivers/interconnect/qcom/sdm660.c index 36962f7bd7bb..7392bebba334 100644 --- a/drivers/interconnect/qcom/sdm660.c +++ b/drivers/interconnect/qcom/sdm660.c @@ -602,6 +602,7 @@ static struct qcom_icc_node mas_mdp_p0 = { .name = "mas_mdp_p0", .id = SDM660_MASTER_MDP_P0, .buswidth = 16, + .ib_coeff = 50, .mas_rpm_id = 8, .slv_rpm_id = -1, .qos.ap_owned = true, @@ -621,6 +622,7 @@ static struct qcom_icc_node mas_mdp_p1 = { .name = "mas_mdp_p1", .id = SDM660_MASTER_MDP_P1, .buswidth = 16, + .ib_coeff = 50, .mas_rpm_id = 61, .slv_rpm_id = -1, .qos.ap_owned = true, @@ -1540,6 +1542,7 @@ static const struct qcom_icc_desc sdm660_bimc = { .num_nodes = ARRAY_SIZE(sdm660_bimc_nodes), .bus_clk_desc = &bimc_clk, .regmap_cfg = &sdm660_bimc_regmap_config, + .ab_coeff = 153, }; static struct qcom_icc_node * const sdm660_cnoc_nodes[] = { @@ -1659,6 +1662,7 @@ static const struct qcom_icc_desc sdm660_mnoc = { .intf_clocks = mm_intf_clocks, .num_intf_clocks = ARRAY_SIZE(mm_intf_clocks), .regmap_cfg = &sdm660_mnoc_regmap_config, + .ab_coeff = 153, }; static struct qcom_icc_node * const sdm660_snoc_nodes[] = { diff --git a/drivers/interconnect/qcom/sdm670.c b/drivers/interconnect/qcom/sdm670.c index 540a2108b77c..907e1ff4ff81 100644 --- a/drivers/interconnect/qcom/sdm670.c +++ b/drivers/interconnect/qcom/sdm670.c @@ -1047,6 +1047,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .keepalive = false, .num_nodes = 1, .nodes = { &ebi }, diff --git a/drivers/interconnect/qcom/sdm845.c b/drivers/interconnect/qcom/sdm845.c index b9243c0aa626..855802be93fe 100644 --- a/drivers/interconnect/qcom/sdm845.c +++ b/drivers/interconnect/qcom/sdm845.c @@ -1265,6 +1265,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .keepalive = false, .num_nodes = 1, .nodes = { &ebi }, diff --git a/drivers/interconnect/qcom/sm6350.c b/drivers/interconnect/qcom/sm6350.c index 49aed492e9b8..f41d7e19ba26 100644 --- a/drivers/interconnect/qcom/sm6350.c +++ b/drivers/interconnect/qcom/sm6350.c @@ -1164,6 +1164,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .keepalive = false, .num_nodes = 1, .nodes = { &ebi }, diff --git a/drivers/interconnect/qcom/sm8150.c b/drivers/interconnect/qcom/sm8150.c index c7c9cf7f746b..edfe824cad35 100644 --- a/drivers/interconnect/qcom/sm8150.c +++ b/drivers/interconnect/qcom/sm8150.c @@ -1282,6 +1282,7 @@ static struct qcom_icc_node xs_sys_tcu_cfg = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .keepalive = false, .num_nodes = 1, .nodes = { &ebi }, diff --git a/drivers/interconnect/qcom/sm8250.c b/drivers/interconnect/qcom/sm8250.c index d4a4ecef11f0..661dc18d99db 100644 --- a/drivers/interconnect/qcom/sm8250.c +++ b/drivers/interconnect/qcom/sm8250.c @@ -1397,6 +1397,7 @@ static struct qcom_icc_node qup2_core_slave = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .keepalive = false, .num_nodes = 1, .nodes = { &ebi }, diff --git a/drivers/interconnect/qcom/sm8350.c b/drivers/interconnect/qcom/sm8350.c index bdf75839e6d1..562322d4fc3c 100644 --- a/drivers/interconnect/qcom/sm8350.c +++ b/drivers/interconnect/qcom/sm8350.c @@ -1356,6 +1356,7 @@ static struct qcom_icc_node qns_mem_noc_sf_disp = { static struct qcom_icc_bcm bcm_acv = { .name = "ACV", + .enable_mask = BIT(3), .keepalive = false, .num_nodes = 1, .nodes = { &ebi }, |