From b41b0ce5982693e27307cfe0aaf49bc8e3a20900 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Wed, 29 Jul 2020 15:34:39 +0300 Subject: interconnect: Add bulk API helpers There are drivers which just need to get multiple interconnect paths, request some predefined amounts of bandwidth and then just toggle the paths between enabled/disabled state. The aim of this patch is simplify the above and to allow drivers to put all the path names and bandwidth data into a single static icc_bulk_data table and call the icc_bulk_* functions on that table in order to scale all the interconnect paths in parallel. Suggested-by: Evan Green Suggested-by: Bjorn Andersson Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20200729123439.9961-1-georgi.djakov@linaro.org Signed-off-by: Georgi Djakov --- include/linux/interconnect.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include') diff --git a/include/linux/interconnect.h b/include/linux/interconnect.h index 3a63d98613fc..f2dd2fc8d3cd 100644 --- a/include/linux/interconnect.h +++ b/include/linux/interconnect.h @@ -23,6 +23,28 @@ struct icc_path; struct device; +/** + * struct icc_bulk_data - Data used for bulk icc operations. + * + * @path: reference to the interconnect path (internal use) + * @name: the name from the "interconnect-names" DT property + * @avg_bw: average bandwidth in icc units + * @peak_bw: peak bandwidth in icc units + */ +struct icc_bulk_data { + struct icc_path *path; + const char *name; + u32 avg_bw; + u32 peak_bw; +}; + +int __must_check of_icc_bulk_get(struct device *dev, int num_paths, + struct icc_bulk_data *paths); +void icc_bulk_put(int num_paths, struct icc_bulk_data *paths); +int icc_bulk_set_bw(int num_paths, const struct icc_bulk_data *paths); +int icc_bulk_enable(int num_paths, const struct icc_bulk_data *paths); +void icc_bulk_disable(int num_paths, const struct icc_bulk_data *paths); + #if IS_ENABLED(CONFIG_INTERCONNECT) struct icc_path *icc_get(struct device *dev, const int src_id, -- cgit v1.2.3 From 3fe3578c8a3e18d809ad4541ff708918509e89dd Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Mon, 27 Jul 2020 22:38:01 -0400 Subject: dt-bindings: interconnect: Add Qualcomm SM8150 DT bindings The Qualcomm SM8150 platform has several bus fabrics that could be controlled and tuned dynamically according to the bandwidth demand. Signed-off-by: Jonathan Marek Reviewed-by: Rob Herring Reviewed-by: Sibi Sankar Link: https://lore.kernel.org/r/20200728023811.5607-3-jonathan@marek.ca Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom,rpmh.yaml | 11 ++ include/dt-bindings/interconnect/qcom,sm8150.h | 162 +++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 include/dt-bindings/interconnect/qcom,sm8150.h (limited to 'include') diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml index 580703fa36e7..e698c0973a5f 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml @@ -45,6 +45,17 @@ properties: - qcom,sdm845-mem-noc - qcom,sdm845-mmss-noc - qcom,sdm845-system-noc + - qcom,sm8150-aggre1-noc + - qcom,sm8150-aggre2-noc + - qcom,sm8150-camnoc-noc + - qcom,sm8150-compute-noc + - qcom,sm8150-config-noc + - qcom,sm8150-dc-noc + - qcom,sm8150-gem-noc + - qcom,sm8150-ipa-virt + - qcom,sm8150-mc-virt + - qcom,sm8150-mmss-noc + - qcom,sm8150-system-noc '#interconnect-cells': const: 1 diff --git a/include/dt-bindings/interconnect/qcom,sm8150.h b/include/dt-bindings/interconnect/qcom,sm8150.h new file mode 100644 index 000000000000..a25684680c42 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,sm8150.h @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Qualcomm SM8150 interconnect IDs + * + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_SM8150_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_SM8150_H + +#define MASTER_A1NOC_CFG 0 +#define MASTER_QUP_0 1 +#define MASTER_EMAC 2 +#define MASTER_UFS_MEM 3 +#define MASTER_USB3 4 +#define MASTER_USB3_1 5 +#define A1NOC_SNOC_SLV 6 +#define SLAVE_SERVICE_A1NOC 7 + +#define MASTER_A2NOC_CFG 0 +#define MASTER_QDSS_BAM 1 +#define MASTER_QSPI 2 +#define MASTER_QUP_1 3 +#define MASTER_QUP_2 4 +#define MASTER_SENSORS_AHB 5 +#define MASTER_TSIF 6 +#define MASTER_CNOC_A2NOC 7 +#define MASTER_CRYPTO_CORE_0 8 +#define MASTER_IPA 9 +#define MASTER_PCIE 10 +#define MASTER_PCIE_1 11 +#define MASTER_QDSS_ETR 12 +#define MASTER_SDCC_2 13 +#define MASTER_SDCC_4 14 +#define A2NOC_SNOC_SLV 15 +#define SLAVE_ANOC_PCIE_GEM_NOC 16 +#define SLAVE_SERVICE_A2NOC 17 + +#define MASTER_CAMNOC_HF0_UNCOMP 0 +#define MASTER_CAMNOC_HF1_UNCOMP 1 +#define MASTER_CAMNOC_SF_UNCOMP 2 +#define SLAVE_CAMNOC_UNCOMP 3 + +#define MASTER_NPU 0 +#define SLAVE_CDSP_MEM_NOC 1 + +#define MASTER_SPDM 0 +#define SNOC_CNOC_MAS 1 +#define MASTER_QDSS_DAP 2 +#define SLAVE_A1NOC_CFG 3 +#define SLAVE_A2NOC_CFG 4 +#define SLAVE_AHB2PHY_SOUTH 5 +#define SLAVE_AOP 6 +#define SLAVE_AOSS 7 +#define SLAVE_CAMERA_CFG 8 +#define SLAVE_CLK_CTL 9 +#define SLAVE_CDSP_CFG 10 +#define SLAVE_RBCPR_CX_CFG 11 +#define SLAVE_RBCPR_MMCX_CFG 12 +#define SLAVE_RBCPR_MX_CFG 13 +#define SLAVE_CRYPTO_0_CFG 14 +#define SLAVE_CNOC_DDRSS 15 +#define SLAVE_DISPLAY_CFG 16 +#define SLAVE_EMAC_CFG 17 +#define SLAVE_GLM 18 +#define SLAVE_GRAPHICS_3D_CFG 19 +#define SLAVE_IMEM_CFG 20 +#define SLAVE_IPA_CFG 21 +#define SLAVE_CNOC_MNOC_CFG 22 +#define SLAVE_NPU_CFG 23 +#define SLAVE_PCIE_0_CFG 24 +#define SLAVE_PCIE_1_CFG 25 +#define SLAVE_NORTH_PHY_CFG 26 +#define SLAVE_PIMEM_CFG 27 +#define SLAVE_PRNG 28 +#define SLAVE_QDSS_CFG 29 +#define SLAVE_QSPI 30 +#define SLAVE_QUP_2 31 +#define SLAVE_QUP_1 32 +#define SLAVE_QUP_0 33 +#define SLAVE_SDCC_2 34 +#define SLAVE_SDCC_4 35 +#define SLAVE_SNOC_CFG 36 +#define SLAVE_SPDM_WRAPPER 37 +#define SLAVE_SPSS_CFG 38 +#define SLAVE_SSC_CFG 39 +#define SLAVE_TCSR 40 +#define SLAVE_TLMM_EAST 41 +#define SLAVE_TLMM_NORTH 42 +#define SLAVE_TLMM_SOUTH 43 +#define SLAVE_TLMM_WEST 44 +#define SLAVE_TSIF 45 +#define SLAVE_UFS_CARD_CFG 46 +#define SLAVE_UFS_MEM_CFG 47 +#define SLAVE_USB3 48 +#define SLAVE_USB3_1 49 +#define SLAVE_VENUS_CFG 50 +#define SLAVE_VSENSE_CTRL_CFG 51 +#define SLAVE_CNOC_A2NOC 52 +#define SLAVE_SERVICE_CNOC 53 + +#define MASTER_CNOC_DC_NOC 0 +#define SLAVE_LLCC_CFG 1 +#define SLAVE_GEM_NOC_CFG 2 + +#define MASTER_AMPSS_M0 0 +#define MASTER_GPU_TCU 1 +#define MASTER_SYS_TCU 2 +#define MASTER_GEM_NOC_CFG 3 +#define MASTER_COMPUTE_NOC 4 +#define MASTER_GRAPHICS_3D 5 +#define MASTER_MNOC_HF_MEM_NOC 6 +#define MASTER_MNOC_SF_MEM_NOC 7 +#define MASTER_GEM_NOC_PCIE_SNOC 8 +#define MASTER_SNOC_GC_MEM_NOC 9 +#define MASTER_SNOC_SF_MEM_NOC 10 +#define MASTER_ECC 11 +#define SLAVE_MSS_PROC_MS_MPU_CFG 12 +#define SLAVE_ECC 13 +#define SLAVE_GEM_NOC_SNOC 14 +#define SLAVE_LLCC 15 +#define SLAVE_SERVICE_GEM_NOC 16 + +#define MASTER_IPA_CORE 0 +#define SLAVE_IPA_CORE 1 + +#define MASTER_LLCC 0 +#define SLAVE_EBI_CH0 1 + +#define MASTER_CNOC_MNOC_CFG 0 +#define MASTER_CAMNOC_HF0 1 +#define MASTER_CAMNOC_HF1 2 +#define MASTER_CAMNOC_SF 3 +#define MASTER_MDP_PORT0 4 +#define MASTER_MDP_PORT1 5 +#define MASTER_ROTATOR 6 +#define MASTER_VIDEO_P0 7 +#define MASTER_VIDEO_P1 8 +#define MASTER_VIDEO_PROC 9 +#define SLAVE_MNOC_SF_MEM_NOC 10 +#define SLAVE_MNOC_HF_MEM_NOC 11 +#define SLAVE_SERVICE_MNOC 12 + +#define MASTER_SNOC_CFG 0 +#define A1NOC_SNOC_MAS 1 +#define A2NOC_SNOC_MAS 2 +#define MASTER_GEM_NOC_SNOC 3 +#define MASTER_PIMEM 4 +#define MASTER_GIC 5 +#define SLAVE_APPSS 6 +#define SNOC_CNOC_SLV 7 +#define SLAVE_SNOC_GEM_NOC_GC 8 +#define SLAVE_SNOC_GEM_NOC_SF 9 +#define SLAVE_OCIMEM 10 +#define SLAVE_PIMEM 11 +#define SLAVE_SERVICE_SNOC 12 +#define SLAVE_PCIE_0 13 +#define SLAVE_PCIE_1 14 +#define SLAVE_QDSS_STM 15 +#define SLAVE_TCU 16 + +#endif -- cgit v1.2.3 From cb6ffd717c9ea48f2a4f577bb128a51b3ed33fc3 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Mon, 27 Jul 2020 22:38:02 -0400 Subject: dt-bindings: interconnect: Add Qualcomm SM8250 DT bindings The Qualcomm SM8250 platform has several bus fabrics that could be controlled and tuned dynamically according to the bandwidth demand. Signed-off-by: Jonathan Marek Reviewed-by: Rob Herring Reviewed-by: Sibi Sankar Link: https://lore.kernel.org/r/20200728023811.5607-4-jonathan@marek.ca Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom,rpmh.yaml | 11 ++ include/dt-bindings/interconnect/qcom,sm8250.h | 172 +++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 include/dt-bindings/interconnect/qcom,sm8250.h (limited to 'include') diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml index e698c0973a5f..30c2a092d2d3 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml @@ -56,6 +56,17 @@ properties: - qcom,sm8150-mc-virt - qcom,sm8150-mmss-noc - qcom,sm8150-system-noc + - qcom,sm8250-aggre1-noc + - qcom,sm8250-aggre2-noc + - qcom,sm8250-compute-noc + - qcom,sm8250-config-noc + - qcom,sm8250-dc-noc + - qcom,sm8250-gem-noc + - qcom,sm8250-ipa-virt + - qcom,sm8250-mc-virt + - qcom,sm8250-mmss-noc + - qcom,sm8250-npu-noc + - qcom,sm8250-system-noc '#interconnect-cells': const: 1 diff --git a/include/dt-bindings/interconnect/qcom,sm8250.h b/include/dt-bindings/interconnect/qcom,sm8250.h new file mode 100644 index 000000000000..1b4d9fbe888d --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,sm8250.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Qualcomm SM8250 interconnect IDs + * + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_SM8250_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_SM8250_H + +#define MASTER_A1NOC_CFG 0 +#define MASTER_QSPI_0 1 +#define MASTER_QUP_1 2 +#define MASTER_QUP_2 3 +#define MASTER_TSIF 4 +#define MASTER_PCIE_2 5 +#define MASTER_SDCC_4 6 +#define MASTER_UFS_MEM 7 +#define MASTER_USB3 8 +#define MASTER_USB3_1 9 +#define A1NOC_SNOC_SLV 10 +#define SLAVE_ANOC_PCIE_GEM_NOC_1 11 +#define SLAVE_SERVICE_A1NOC 12 + +#define MASTER_A2NOC_CFG 0 +#define MASTER_QDSS_BAM 1 +#define MASTER_QUP_0 2 +#define MASTER_CNOC_A2NOC 3 +#define MASTER_CRYPTO_CORE_0 4 +#define MASTER_IPA 5 +#define MASTER_PCIE 6 +#define MASTER_PCIE_1 7 +#define MASTER_QDSS_ETR 8 +#define MASTER_SDCC_2 9 +#define MASTER_UFS_CARD 10 +#define A2NOC_SNOC_SLV 11 +#define SLAVE_ANOC_PCIE_GEM_NOC 12 +#define SLAVE_SERVICE_A2NOC 13 + +#define MASTER_NPU 0 +#define SLAVE_CDSP_MEM_NOC 1 + +#define SNOC_CNOC_MAS 0 +#define MASTER_QDSS_DAP 1 +#define SLAVE_A1NOC_CFG 2 +#define SLAVE_A2NOC_CFG 3 +#define SLAVE_AHB2PHY_SOUTH 4 +#define SLAVE_AHB2PHY_NORTH 5 +#define SLAVE_AOSS 6 +#define SLAVE_CAMERA_CFG 7 +#define SLAVE_CLK_CTL 8 +#define SLAVE_CDSP_CFG 9 +#define SLAVE_RBCPR_CX_CFG 10 +#define SLAVE_RBCPR_MMCX_CFG 11 +#define SLAVE_RBCPR_MX_CFG 12 +#define SLAVE_CRYPTO_0_CFG 13 +#define SLAVE_CX_RDPM 14 +#define SLAVE_DCC_CFG 15 +#define SLAVE_CNOC_DDRSS 16 +#define SLAVE_DISPLAY_CFG 17 +#define SLAVE_GRAPHICS_3D_CFG 18 +#define SLAVE_IMEM_CFG 19 +#define SLAVE_IPA_CFG 20 +#define SLAVE_IPC_ROUTER_CFG 21 +#define SLAVE_LPASS 22 +#define SLAVE_CNOC_MNOC_CFG 23 +#define SLAVE_NPU_CFG 24 +#define SLAVE_PCIE_0_CFG 25 +#define SLAVE_PCIE_1_CFG 26 +#define SLAVE_PCIE_2_CFG 27 +#define SLAVE_PDM 28 +#define SLAVE_PIMEM_CFG 29 +#define SLAVE_PRNG 30 +#define SLAVE_QDSS_CFG 31 +#define SLAVE_QSPI_0 32 +#define SLAVE_QUP_0 33 +#define SLAVE_QUP_1 34 +#define SLAVE_QUP_2 35 +#define SLAVE_SDCC_2 36 +#define SLAVE_SDCC_4 37 +#define SLAVE_SNOC_CFG 38 +#define SLAVE_TCSR 39 +#define SLAVE_TLMM_NORTH 40 +#define SLAVE_TLMM_SOUTH 41 +#define SLAVE_TLMM_WEST 42 +#define SLAVE_TSIF 43 +#define SLAVE_UFS_CARD_CFG 44 +#define SLAVE_UFS_MEM_CFG 45 +#define SLAVE_USB3 46 +#define SLAVE_USB3_1 47 +#define SLAVE_VENUS_CFG 48 +#define SLAVE_VSENSE_CTRL_CFG 49 +#define SLAVE_CNOC_A2NOC 50 +#define SLAVE_SERVICE_CNOC 51 + +#define MASTER_CNOC_DC_NOC 0 +#define SLAVE_LLCC_CFG 1 +#define SLAVE_GEM_NOC_CFG 2 + +#define MASTER_GPU_TCU 0 +#define MASTER_SYS_TCU 1 +#define MASTER_AMPSS_M0 2 +#define MASTER_GEM_NOC_CFG 3 +#define MASTER_COMPUTE_NOC 4 +#define MASTER_GRAPHICS_3D 5 +#define MASTER_MNOC_HF_MEM_NOC 6 +#define MASTER_MNOC_SF_MEM_NOC 7 +#define MASTER_ANOC_PCIE_GEM_NOC 8 +#define MASTER_SNOC_GC_MEM_NOC 9 +#define MASTER_SNOC_SF_MEM_NOC 10 +#define SLAVE_GEM_NOC_SNOC 11 +#define SLAVE_LLCC 12 +#define SLAVE_MEM_NOC_PCIE_SNOC 13 +#define SLAVE_SERVICE_GEM_NOC_1 14 +#define SLAVE_SERVICE_GEM_NOC_2 15 +#define SLAVE_SERVICE_GEM_NOC 16 + +#define MASTER_IPA_CORE 0 +#define SLAVE_IPA_CORE 1 + +#define MASTER_LLCC 0 +#define SLAVE_EBI_CH0 1 + +#define MASTER_CNOC_MNOC_CFG 0 +#define MASTER_CAMNOC_HF 1 +#define MASTER_CAMNOC_ICP 2 +#define MASTER_CAMNOC_SF 3 +#define MASTER_VIDEO_P0 4 +#define MASTER_VIDEO_P1 5 +#define MASTER_VIDEO_PROC 6 +#define MASTER_MDP_PORT0 7 +#define MASTER_MDP_PORT1 8 +#define MASTER_ROTATOR 9 +#define SLAVE_MNOC_HF_MEM_NOC 10 +#define SLAVE_MNOC_SF_MEM_NOC 11 +#define SLAVE_SERVICE_MNOC 12 + +#define MASTER_NPU_SYS 0 +#define MASTER_NPU_CDP 1 +#define MASTER_NPU_NOC_CFG 2 +#define SLAVE_NPU_CAL_DP0 3 +#define SLAVE_NPU_CAL_DP1 4 +#define SLAVE_NPU_CP 5 +#define SLAVE_NPU_INT_DMA_BWMON_CFG 6 +#define SLAVE_NPU_DPM 7 +#define SLAVE_ISENSE_CFG 8 +#define SLAVE_NPU_LLM_CFG 9 +#define SLAVE_NPU_TCM 10 +#define SLAVE_NPU_COMPUTE_NOC 11 +#define SLAVE_SERVICE_NPU_NOC 12 + +#define MASTER_SNOC_CFG 0 +#define A1NOC_SNOC_MAS 1 +#define A2NOC_SNOC_MAS 2 +#define MASTER_GEM_NOC_SNOC 3 +#define MASTER_GEM_NOC_PCIE_SNOC 4 +#define MASTER_PIMEM 5 +#define MASTER_GIC 6 +#define SLAVE_APPSS 7 +#define SNOC_CNOC_SLV 8 +#define SLAVE_SNOC_GEM_NOC_GC 9 +#define SLAVE_SNOC_GEM_NOC_SF 10 +#define SLAVE_OCIMEM 11 +#define SLAVE_PIMEM 12 +#define SLAVE_SERVICE_SNOC 13 +#define SLAVE_PCIE_0 14 +#define SLAVE_PCIE_1 15 +#define SLAVE_PCIE_2 16 +#define SLAVE_QDSS_STM 17 +#define SLAVE_TCU 18 + +#endif -- cgit v1.2.3 From 65e0e4d67983dca775fc9ea39f092bc76caa495f Mon Sep 17 00:00:00 2001 From: Mike Tipton Date: Thu, 3 Sep 2020 12:21:45 -0700 Subject: dt-bindings: interconnect: Add generic qcom bindings Add generic qcom interconnect bindings that are common across platforms. In particular, these include QCOM_ICC_TAG_* macros that clients can use when calling icc_set_tag(). Signed-off-by: Mike Tipton Acked-by: Rob Herring Link: https://lore.kernel.org/r/20200903192149.30385-3-mdtipton@codeaurora.org Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/icc-rpmh.h | 18 ++---------------- include/dt-bindings/interconnect/qcom,icc.h | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 include/dt-bindings/interconnect/qcom,icc.h (limited to 'include') diff --git a/drivers/interconnect/qcom/icc-rpmh.h b/drivers/interconnect/qcom/icc-rpmh.h index 903d25e61984..cb736b745e1a 100644 --- a/drivers/interconnect/qcom/icc-rpmh.h +++ b/drivers/interconnect/qcom/icc-rpmh.h @@ -6,6 +6,8 @@ #ifndef __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__ #define __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__ +#include + #define to_qcom_provider(_provider) \ container_of(_provider, struct qcom_icc_provider, provider) @@ -44,22 +46,6 @@ struct bcm_db { #define MAX_BCM_PER_NODE 3 #define MAX_VCD 10 -/* - * The AMC bucket denotes constraints that are applied to hardware when - * icc_set_bw() completes, whereas the WAKE and SLEEP constraints are applied - * when the execution environment transitions between active and low power mode. - */ -#define QCOM_ICC_BUCKET_AMC 0 -#define QCOM_ICC_BUCKET_WAKE 1 -#define QCOM_ICC_BUCKET_SLEEP 2 -#define QCOM_ICC_NUM_BUCKETS 3 -#define QCOM_ICC_TAG_AMC BIT(QCOM_ICC_BUCKET_AMC) -#define QCOM_ICC_TAG_WAKE BIT(QCOM_ICC_BUCKET_WAKE) -#define QCOM_ICC_TAG_SLEEP BIT(QCOM_ICC_BUCKET_SLEEP) -#define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE) -#define QCOM_ICC_TAG_ALWAYS (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\ - QCOM_ICC_TAG_SLEEP) - /** * struct qcom_icc_node - Qualcomm specific interconnect nodes * @name: the node name used in debugfs diff --git a/include/dt-bindings/interconnect/qcom,icc.h b/include/dt-bindings/interconnect/qcom,icc.h new file mode 100644 index 000000000000..cd34f36daaaa --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,icc.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_ICC_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_ICC_H + +/* + * The AMC bucket denotes constraints that are applied to hardware when + * icc_set_bw() completes, whereas the WAKE and SLEEP constraints are applied + * when the execution environment transitions between active and low power mode. + */ +#define QCOM_ICC_BUCKET_AMC 0 +#define QCOM_ICC_BUCKET_WAKE 1 +#define QCOM_ICC_BUCKET_SLEEP 2 +#define QCOM_ICC_NUM_BUCKETS 3 + +#define QCOM_ICC_TAG_AMC (1 << QCOM_ICC_BUCKET_AMC) +#define QCOM_ICC_TAG_WAKE (1 << QCOM_ICC_BUCKET_WAKE) +#define QCOM_ICC_TAG_SLEEP (1 << QCOM_ICC_BUCKET_SLEEP) +#define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE) +#define QCOM_ICC_TAG_ALWAYS (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\ + QCOM_ICC_TAG_SLEEP) + +#endif -- cgit v1.2.3 From 1521e22bfa12db6225002ba3b040572a78dff996 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Thu, 3 Sep 2020 16:31:28 +0300 Subject: interconnect: Introduce xlate_extended() callback Currently there is the xlate() callback, which is used by providers for mapping the nodes from phandle arguments. That's fine for simple mappings, but the phandle arguments could contain an additional data, such as tag information. Let's create another callback xlate_extended() for the cases where providers want also populate the path tag data. Tested-by: Sibi Sankar Reviewed-by: Sibi Sankar Reviewed-by: Matthias Kaehlcke Tested-by: Matthias Kaehlcke Link: https://lore.kernel.org/r/20200903133134.17201-2-georgi.djakov@linaro.org Signed-off-by: Georgi Djakov --- drivers/interconnect/core.c | 73 ++++++++++++++++++++++++----------- include/linux/interconnect-provider.h | 17 +++++++- 2 files changed, 65 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c index cf07491b7415..7642f3601dbf 100644 --- a/drivers/interconnect/core.c +++ b/drivers/interconnect/core.c @@ -342,12 +342,13 @@ EXPORT_SYMBOL_GPL(of_icc_xlate_onecell); * Looks for interconnect provider under the node specified by @spec and if * found, uses xlate function of the provider to map phandle args to node. * - * Returns a valid pointer to struct icc_node on success or ERR_PTR() + * Returns a valid pointer to struct icc_node_data on success or ERR_PTR() * on failure. */ -struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec) +struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec) { struct icc_node *node = ERR_PTR(-EPROBE_DEFER); + struct icc_node_data *data = NULL; struct icc_provider *provider; if (!spec) @@ -355,14 +356,33 @@ struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec) mutex_lock(&icc_lock); list_for_each_entry(provider, &icc_providers, provider_list) { - if (provider->dev->of_node == spec->np) - node = provider->xlate(spec, provider->data); - if (!IS_ERR(node)) - break; + if (provider->dev->of_node == spec->np) { + if (provider->xlate_extended) { + data = provider->xlate_extended(spec, provider->data); + if (!IS_ERR(data)) { + node = data->node; + break; + } + } else { + node = provider->xlate(spec, provider->data); + if (!IS_ERR(node)) + break; + } + } } mutex_unlock(&icc_lock); - return node; + if (IS_ERR(node)) + return ERR_CAST(node); + + if (!data) { + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return ERR_PTR(-ENOMEM); + data->node = node; + } + + return data; } EXPORT_SYMBOL_GPL(of_icc_get_from_provider); @@ -409,7 +429,7 @@ EXPORT_SYMBOL_GPL(devm_of_icc_get); struct icc_path *of_icc_get_by_index(struct device *dev, int idx) { struct icc_path *path; - struct icc_node *src_node, *dst_node; + struct icc_node_data *src_data, *dst_data; struct device_node *np; struct of_phandle_args src_args, dst_args; int ret; @@ -447,39 +467,46 @@ struct icc_path *of_icc_get_by_index(struct device *dev, int idx) of_node_put(dst_args.np); - src_node = of_icc_get_from_provider(&src_args); + src_data = of_icc_get_from_provider(&src_args); - if (IS_ERR(src_node)) { - if (PTR_ERR(src_node) != -EPROBE_DEFER) + if (IS_ERR(src_data)) { + if (PTR_ERR(src_data) != -EPROBE_DEFER) dev_err(dev, "error finding src node: %ld\n", - PTR_ERR(src_node)); - return ERR_CAST(src_node); + PTR_ERR(src_data)); + return ERR_CAST(src_data); } - dst_node = of_icc_get_from_provider(&dst_args); + dst_data = of_icc_get_from_provider(&dst_args); - if (IS_ERR(dst_node)) { - if (PTR_ERR(dst_node) != -EPROBE_DEFER) + if (IS_ERR(dst_data)) { + if (PTR_ERR(dst_data) != -EPROBE_DEFER) dev_err(dev, "error finding dst node: %ld\n", - PTR_ERR(dst_node)); - return ERR_CAST(dst_node); + PTR_ERR(dst_data)); + kfree(src_data); + return ERR_CAST(dst_data); } mutex_lock(&icc_lock); - path = path_find(dev, src_node, dst_node); + path = path_find(dev, src_data->node, dst_data->node); mutex_unlock(&icc_lock); if (IS_ERR(path)) { dev_err(dev, "%s: invalid path=%ld\n", __func__, PTR_ERR(path)); - return path; + goto free_icc_data; } + if (src_data->tag && src_data->tag == dst_data->tag) + icc_set_tag(path, src_data->tag); + path->name = kasprintf(GFP_KERNEL, "%s-%s", - src_node->name, dst_node->name); + src_data->node->name, dst_data->node->name); if (!path->name) { kfree(path); - return ERR_PTR(-ENOMEM); + path = ERR_PTR(-ENOMEM); } +free_icc_data: + kfree(src_data); + kfree(dst_data); return path; } EXPORT_SYMBOL_GPL(of_icc_get_by_index); @@ -981,7 +1008,7 @@ int icc_provider_add(struct icc_provider *provider) { if (WARN_ON(!provider->set)) return -EINVAL; - if (WARN_ON(!provider->xlate)) + if (WARN_ON(!provider->xlate && !provider->xlate_extended)) return -EINVAL; mutex_lock(&icc_lock); diff --git a/include/linux/interconnect-provider.h b/include/linux/interconnect-provider.h index 4735518de515..4d535fddd5d3 100644 --- a/include/linux/interconnect-provider.h +++ b/include/linux/interconnect-provider.h @@ -14,6 +14,17 @@ struct icc_node; struct of_phandle_args; +/** + * struct icc_node_data - icc node data + * + * @node: icc node + * @tag: tag + */ +struct icc_node_data { + struct icc_node *node; + u32 tag; +}; + /** * struct icc_onecell_data - driver data for onecell interconnect providers * @@ -39,6 +50,7 @@ struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec, * @pre_aggregate: pointer to device specific function that is called * before the aggregation begins (optional) * @xlate: provider-specific callback for mapping nodes from phandle arguments + * @xlate_extended: vendor-specific callback for mapping node data from phandle arguments * @dev: the device this interconnect provider belongs to * @users: count of active users * @inter_set: whether inter-provider pairs will be configured with @set @@ -52,6 +64,7 @@ struct icc_provider { u32 peak_bw, u32 *agg_avg, u32 *agg_peak); void (*pre_aggregate)(struct icc_node *node); struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data); + struct icc_node_data* (*xlate_extended)(struct of_phandle_args *spec, void *data); struct device *dev; int users; bool inter_set; @@ -105,7 +118,7 @@ void icc_node_del(struct icc_node *node); int icc_nodes_remove(struct icc_provider *provider); int icc_provider_add(struct icc_provider *provider); int icc_provider_del(struct icc_provider *provider); -struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec); +struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec); #else @@ -157,7 +170,7 @@ static inline int icc_provider_del(struct icc_provider *provider) return -ENOTSUPP; } -static inline struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec) +static inline struct icc_node_data *of_icc_get_from_provider(struct of_phandle_args *spec) { return ERR_PTR(-ENOTSUPP); } -- cgit v1.2.3 From c4877059e0a4b88b59bc208f2608dc489553cf29 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Tue, 8 Sep 2020 16:29:01 +0300 Subject: dt-bindings: interconnect: Add EPSS L3 DT binding on SM8250 Add Epoch Subsystem (EPSS) L3 interconnect provider binding on SM8250 SoCs. Signed-off-by: Sibi Sankar Acked-by: Rob Herring Link: https://lore.kernel.org/r/20200801123049.32398-5-sibis@codeaurora.org Signed-off-by: Georgi Djakov --- Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml | 1 + include/dt-bindings/interconnect/qcom,osm-l3.h | 3 +++ 2 files changed, 4 insertions(+) (limited to 'include') diff --git a/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml b/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml index b6945c11eb46..d6a95c3cb26f 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml @@ -20,6 +20,7 @@ properties: - qcom,sc7180-osm-l3 - qcom,sdm845-osm-l3 - qcom,sm8150-osm-l3 + - qcom,sm8250-epss-l3 reg: maxItems: 1 diff --git a/include/dt-bindings/interconnect/qcom,osm-l3.h b/include/dt-bindings/interconnect/qcom,osm-l3.h index 54858ff7674d..61ef649ae565 100644 --- a/include/dt-bindings/interconnect/qcom,osm-l3.h +++ b/include/dt-bindings/interconnect/qcom,osm-l3.h @@ -9,4 +9,7 @@ #define MASTER_OSM_L3_APPS 0 #define SLAVE_OSM_L3 1 +#define MASTER_EPSS_L3_APPS 0 +#define SLAVE_EPSS_L3_SHARED 1 + #endif -- cgit v1.2.3 From cc80d10d6fcf6f47a2a3efe2c4139e50906a4764 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Tue, 25 Aug 2020 20:01:50 +0300 Subject: interconnect: Add get_bw() callback The interconnect controller hardware may support querying the current bandwidth settings, so add a callback for providers to implement this functionality if supported. Link: https://lore.kernel.org/r/20200825170152.6434-2-georgi.djakov@linaro.org Reviewed-by: Saravana Kannan Signed-off-by: Georgi Djakov --- include/linux/interconnect-provider.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/interconnect-provider.h b/include/linux/interconnect-provider.h index 4735518de515..520f70fe5a31 100644 --- a/include/linux/interconnect-provider.h +++ b/include/linux/interconnect-provider.h @@ -38,6 +38,7 @@ struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec, * @aggregate: pointer to device specific aggregate operation function * @pre_aggregate: pointer to device specific function that is called * before the aggregation begins (optional) + * @get_bw: pointer to device specific function to get current bandwidth * @xlate: provider-specific callback for mapping nodes from phandle arguments * @dev: the device this interconnect provider belongs to * @users: count of active users @@ -51,6 +52,7 @@ struct icc_provider { int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw, u32 peak_bw, u32 *agg_avg, u32 *agg_peak); void (*pre_aggregate)(struct icc_node *node); + int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak); struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data); struct device *dev; int users; -- cgit v1.2.3 From b1d681d8d32499bcf284462d92aeb5f9fe72bf5b Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Tue, 25 Aug 2020 20:01:51 +0300 Subject: interconnect: Add sync state support The bootloaders often do some initial configuration of the interconnects in the system and we want to keep this configuration until all consumers have probed and expressed their bandwidth needs. This is because we don't want to change the configuration by starting to disable unused paths until every user had a chance to request the amount of bandwidth it needs. To accomplish this we will implement an interconnect specific sync_state callback which will synchronize (aggregate and set) the current bandwidth settings when all consumers have been probed. Link: https://lore.kernel.org/r/20200825170152.6434-3-georgi.djakov@linaro.org Reviewed-by: Saravana Kannan Signed-off-by: Georgi Djakov --- drivers/interconnect/core.c | 67 +++++++++++++++++++++++++++++++++++ include/linux/interconnect-provider.h | 5 +++ 2 files changed, 72 insertions(+) (limited to 'include') diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c index cf07491b7415..b94c6c2b8ff9 100644 --- a/drivers/interconnect/core.c +++ b/drivers/interconnect/core.c @@ -26,6 +26,8 @@ static DEFINE_IDR(icc_idr); static LIST_HEAD(icc_providers); +static int providers_count; +static bool synced_state; static DEFINE_MUTEX(icc_lock); static struct dentry *icc_debugfs_dir; @@ -267,6 +269,12 @@ static int aggregate_requests(struct icc_node *node) } p->aggregate(node, r->tag, avg_bw, peak_bw, &node->avg_bw, &node->peak_bw); + + /* during boot use the initial bandwidth as a floor value */ + if (!synced_state) { + node->avg_bw = max(node->avg_bw, node->init_avg); + node->peak_bw = max(node->peak_bw, node->init_peak); + } } return 0; @@ -931,6 +939,19 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider) node->provider = provider; list_add_tail(&node->node_list, &provider->nodes); + /* get the initial bandwidth values and sync them with hardware */ + if (provider->get_bw) { + provider->get_bw(node, &node->init_avg, &node->init_peak); + } else { + node->init_avg = INT_MAX; + node->init_peak = INT_MAX; + } + node->avg_bw = node->init_avg; + node->peak_bw = node->init_peak; + provider->set(node, node); + node->avg_bw = 0; + node->peak_bw = 0; + mutex_unlock(&icc_lock); } EXPORT_SYMBOL_GPL(icc_node_add); @@ -1026,8 +1047,54 @@ int icc_provider_del(struct icc_provider *provider) } EXPORT_SYMBOL_GPL(icc_provider_del); +static int of_count_icc_providers(struct device_node *np) +{ + struct device_node *child; + int count = 0; + + for_each_available_child_of_node(np, child) { + if (of_property_read_bool(child, "#interconnect-cells")) + count++; + count += of_count_icc_providers(child); + } + of_node_put(np); + + return count; +} + +void icc_sync_state(struct device *dev) +{ + struct icc_provider *p; + struct icc_node *n; + static int count; + + count++; + + if (count < providers_count) + return; + + mutex_lock(&icc_lock); + synced_state = true; + list_for_each_entry(p, &icc_providers, provider_list) { + dev_dbg(p->dev, "interconnect provider is in synced state\n"); + list_for_each_entry(n, &p->nodes, node_list) { + if (n->init_avg || n->init_peak) { + aggregate_requests(n); + p->set(n, n); + } + } + } + mutex_unlock(&icc_lock); +} +EXPORT_SYMBOL_GPL(icc_sync_state); + static int __init icc_init(void) { + struct device_node *root = of_find_node_by_path("/"); + + providers_count = of_count_icc_providers(root); + of_node_put(root); + icc_debugfs_dir = debugfs_create_dir("interconnect", NULL); debugfs_create_file("interconnect_summary", 0444, icc_debugfs_dir, NULL, &icc_summary_fops); diff --git a/include/linux/interconnect-provider.h b/include/linux/interconnect-provider.h index 520f70fe5a31..f713308b8a8f 100644 --- a/include/linux/interconnect-provider.h +++ b/include/linux/interconnect-provider.h @@ -75,6 +75,8 @@ struct icc_provider { * @req_list: a list of QoS constraint requests associated with this node * @avg_bw: aggregated value of average bandwidth requests from all consumers * @peak_bw: aggregated value of peak bandwidth requests from all consumers + * @init_avg: average bandwidth value that is read from the hardware during init + * @init_peak: peak bandwidth value that is read from the hardware during init * @data: pointer to private data */ struct icc_node { @@ -91,6 +93,8 @@ struct icc_node { struct hlist_head req_list; u32 avg_bw; u32 peak_bw; + u32 init_avg; + u32 init_peak; void *data; }; @@ -108,6 +112,7 @@ int icc_nodes_remove(struct icc_provider *provider); int icc_provider_add(struct icc_provider *provider); int icc_provider_del(struct icc_provider *provider); struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec); +void icc_sync_state(struct device *dev); #else -- cgit v1.2.3