* [PATCH v10 0/3] Add MSM8916 interconnect provider driver @ 2019-10-30 15:39 Georgi Djakov 2019-10-30 15:39 ` [PATCH v10 1/3] dt-bindings: interconnect: Add Qualcomm MSM8916 DT bindings Georgi Djakov ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Georgi Djakov @ 2019-10-30 15:39 UTC (permalink / raw) To: robh+dt, linux-pm Cc: agross, bjorn.andersson, evgreen, daidavid1, vincent.guittot, linux-arm-msm, devicetree, linux-kernel, georgi.djakov Add driver to support scaling of the on-chip interconnects on the MSM8916-based platforms. Also add the necessary device-tree nodes, so that the driver for each NoC can probe and register as interconnect provider. v10: - Converted binding to DT schema. - Use local number space per each NoC in DT. - Rebased the old patch and resolved conflicts. - Dropped some unused QoS related code. - Switched to using the clk_bulk API. - Improved commit texts. - Minor changes. v9: https://lore.kernel.org/r/20180831140151.13972-7-georgi.djakov@linaro.org https://lore.kernel.org/r/20180831140151.13972-8-georgi.djakov@linaro.org Georgi Djakov (3): dt-bindings: interconnect: Add Qualcomm MSM8916 DT bindings interconnect: qcom: Add MSM8916 interconnect provider driver arm64: dts: msm8916: Add interconnect provider DT nodes .../bindings/interconnect/qcom,msm8916.yaml | 77 +++ arch/arm64/boot/dts/qcom/msm8916.dtsi | 28 + drivers/interconnect/qcom/Kconfig | 9 + drivers/interconnect/qcom/Makefile | 2 + drivers/interconnect/qcom/msm8916.c | 572 ++++++++++++++++++ .../dt-bindings/interconnect/qcom,msm8916.h | 100 +++ 6 files changed, 788 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml create mode 100644 drivers/interconnect/qcom/msm8916.c create mode 100644 include/dt-bindings/interconnect/qcom,msm8916.h ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v10 1/3] dt-bindings: interconnect: Add Qualcomm MSM8916 DT bindings 2019-10-30 15:39 [PATCH v10 0/3] Add MSM8916 interconnect provider driver Georgi Djakov @ 2019-10-30 15:39 ` Georgi Djakov 2019-11-04 21:28 ` Rob Herring 2019-10-30 15:39 ` [PATCH v10 2/3] interconnect: qcom: Add MSM8916 interconnect provider driver Georgi Djakov 2019-10-30 15:39 ` [PATCH v10 3/3] arm64: dts: msm8916: Add interconnect provider DT nodes Georgi Djakov 2 siblings, 1 reply; 7+ messages in thread From: Georgi Djakov @ 2019-10-30 15:39 UTC (permalink / raw) To: robh+dt, linux-pm Cc: agross, bjorn.andersson, evgreen, daidavid1, vincent.guittot, linux-arm-msm, devicetree, linux-kernel, georgi.djakov The Qualcomm MSM8916 platform has several bus fabrics that could be controlled and tuned dynamically according to the bandwidth demand. Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> --- .../bindings/interconnect/qcom,msm8916.yaml | 77 ++++++++++++++ .../dt-bindings/interconnect/qcom,msm8916.h | 100 ++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml create mode 100644 include/dt-bindings/interconnect/qcom,msm8916.h diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml new file mode 100644 index 000000000000..4107e60cab12 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,msm8916.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm MSM8916 Network-On-Chip interconnect + +maintainers: + - Georgi Djakov <georgi.djakov@linaro.org> + +description: | + The Qualcomm MSM8916 interconnect providers support adjusting the + bandwidth requirements between the various NoC fabrics. + +properties: + compatible: + enum: + - qcom,msm8916-bimc + - qcom,msm8916-pcnoc + - qcom,msm8916-snoc + + reg: + maxItems: 1 + + '#interconnect-cells': + const: 1 + + clock-names: + items: + - const: bus + - const: bus_a + + clocks: + items: + - description: Bus Clock + - description: Bus A Clock + +required: + - compatible + - reg + - '#interconnect-cells' + - clock-names + - clocks + +additionalProperties: 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>; + }; diff --git a/include/dt-bindings/interconnect/qcom,msm8916.h b/include/dt-bindings/interconnect/qcom,msm8916.h new file mode 100644 index 000000000000..359a75feb198 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,msm8916.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Qualcomm interconnect IDs + * + * Copyright (c) 2019, Linaro Ltd. + * Author: Georgi Djakov <georgi.djakov@linaro.org> + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_MSM8916_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_MSM8916_H + +#define BIMC_SNOC_SLV 0 +#define MASTER_JPEG 1 +#define MASTER_MDP_PORT0 2 +#define MASTER_QDSS_BAM 3 +#define MASTER_QDSS_ETR 4 +#define MASTER_SNOC_CFG 5 +#define MASTER_VFE 6 +#define MASTER_VIDEO_P0 7 +#define SNOC_MM_INT_0 8 +#define SNOC_MM_INT_1 9 +#define SNOC_MM_INT_2 10 +#define SNOC_MM_INT_BIMC 11 +#define PCNOC_SNOC_SLV 12 +#define SLAVE_APSS 13 +#define SLAVE_CATS_128 14 +#define SLAVE_OCMEM_64 15 +#define SLAVE_IMEM 16 +#define SLAVE_QDSS_STM 17 +#define SLAVE_SRVC_SNOC 18 +#define SNOC_BIMC_0_MAS 19 +#define SNOC_BIMC_1_MAS 20 +#define SNOC_INT_0 21 +#define SNOC_INT_1 22 +#define SNOC_INT_BIMC 23 +#define SNOC_PCNOC_MAS 24 +#define SNOC_QDSS_INT 25 + +#define BIMC_SNOC_MAS 0 +#define MASTER_AMPSS_M0 1 +#define MASTER_GRAPHICS_3D 2 +#define MASTER_TCU0 3 +#define MASTER_TCU1 4 +#define SLAVE_AMPSS_L2 5 +#define SLAVE_EBI_CH0 6 +#define SNOC_BIMC_0_SLV 7 +#define SNOC_BIMC_1_SLV 8 + +#define MASTER_BLSP_1 0 +#define MASTER_DEHR 1 +#define MASTER_LPASS 2 +#define MASTER_CRYPTO_CORE0 3 +#define MASTER_SDCC_1 4 +#define MASTER_SDCC_2 5 +#define MASTER_SPDM 6 +#define MASTER_USB_HS 7 +#define PCNOC_INT_0 8 +#define PCNOC_INT_1 9 +#define PCNOC_MAS_0 10 +#define PCNOC_MAS_1 11 +#define PCNOC_SLV_0 12 +#define PCNOC_SLV_1 13 +#define PCNOC_SLV_2 14 +#define PCNOC_SLV_3 15 +#define PCNOC_SLV_4 16 +#define PCNOC_SLV_8 17 +#define PCNOC_SLV_9 18 +#define PCNOC_SNOC_MAS 19 +#define SLAVE_BIMC_CFG 20 +#define SLAVE_BLSP_1 21 +#define SLAVE_BOOT_ROM 22 +#define SLAVE_CAMERA_CFG 23 +#define SLAVE_CLK_CTL 24 +#define SLAVE_CRYPTO_0_CFG 25 +#define SLAVE_DEHR_CFG 26 +#define SLAVE_DISPLAY_CFG 27 +#define SLAVE_GRAPHICS_3D_CFG 28 +#define SLAVE_IMEM_CFG 29 +#define SLAVE_LPASS 30 +#define SLAVE_MPM 31 +#define SLAVE_MSG_RAM 32 +#define SLAVE_MSS 33 +#define SLAVE_PDM 34 +#define SLAVE_PMIC_ARB 35 +#define SLAVE_PCNOC_CFG 36 +#define SLAVE_PRNG 37 +#define SLAVE_QDSS_CFG 38 +#define SLAVE_RBCPR_CFG 39 +#define SLAVE_SDCC_1 40 +#define SLAVE_SDCC_2 41 +#define SLAVE_SECURITY 42 +#define SLAVE_SNOC_CFG 43 +#define SLAVE_SPDM 44 +#define SLAVE_TCSR 45 +#define SLAVE_TLMM 46 +#define SLAVE_USB_HS 47 +#define SLAVE_VENUS_CFG 48 +#define SNOC_PCNOC_SLV 49 + +#endif ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v10 1/3] dt-bindings: interconnect: Add Qualcomm MSM8916 DT bindings 2019-10-30 15:39 ` [PATCH v10 1/3] dt-bindings: interconnect: Add Qualcomm MSM8916 DT bindings Georgi Djakov @ 2019-11-04 21:28 ` Rob Herring 0 siblings, 0 replies; 7+ messages in thread From: Rob Herring @ 2019-11-04 21:28 UTC (permalink / raw) To: Georgi Djakov Cc: robh+dt, linux-pm, agross, bjorn.andersson, evgreen, daidavid1, vincent.guittot, linux-arm-msm, devicetree, linux-kernel, georgi.djakov On Wed, 30 Oct 2019 17:39:02 +0200, Georgi Djakov wrote: > The Qualcomm MSM8916 platform has several bus fabrics that could be > controlled and tuned dynamically according to the bandwidth demand. > > Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> > --- > .../bindings/interconnect/qcom,msm8916.yaml | 77 ++++++++++++++ > .../dt-bindings/interconnect/qcom,msm8916.h | 100 ++++++++++++++++++ > 2 files changed, 177 insertions(+) > create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,msm8916.yaml > create mode 100644 include/dt-bindings/interconnect/qcom,msm8916.h > Reviewed-by: Rob Herring <robh@kernel.org> ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v10 2/3] interconnect: qcom: Add MSM8916 interconnect provider driver 2019-10-30 15:39 [PATCH v10 0/3] Add MSM8916 interconnect provider driver Georgi Djakov 2019-10-30 15:39 ` [PATCH v10 1/3] dt-bindings: interconnect: Add Qualcomm MSM8916 DT bindings Georgi Djakov @ 2019-10-30 15:39 ` Georgi Djakov 2019-11-13 13:03 ` Dmitry Osipenko 2019-10-30 15:39 ` [PATCH v10 3/3] arm64: dts: msm8916: Add interconnect provider DT nodes Georgi Djakov 2 siblings, 1 reply; 7+ messages in thread From: Georgi Djakov @ 2019-10-30 15:39 UTC (permalink / raw) To: robh+dt, linux-pm Cc: agross, bjorn.andersson, evgreen, daidavid1, vincent.guittot, linux-arm-msm, devicetree, linux-kernel, georgi.djakov Add driver for the Qualcomm interconnect buses found in MSM8916 based platforms. The topology consists of three NoCs that are controlled by a remote processor that collects the aggregated bandwidth for each master-slave pairs. Reviewed-by: Evan Green <evgreen@chromium.org> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> --- drivers/interconnect/qcom/Kconfig | 9 + drivers/interconnect/qcom/Makefile | 2 + drivers/interconnect/qcom/msm8916.c | 572 ++++++++++++++++++++++++++++ 3 files changed, 583 insertions(+) create mode 100644 drivers/interconnect/qcom/msm8916.c diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig index ecf057d7e240..aa395733613e 100644 --- a/drivers/interconnect/qcom/Kconfig +++ b/drivers/interconnect/qcom/Kconfig @@ -5,6 +5,15 @@ config INTERCONNECT_QCOM help Support for Qualcomm's Network-on-Chip interconnect hardware. +config INTERCONNECT_QCOM_MSM8916 + tristate "Qualcomm MSM8916 interconnect driver" + depends on INTERCONNECT_QCOM + depends on QCOM_SMD_RPM + select INTERCONNECT_QCOM_SMD_RPM + help + This is a driver for the Qualcomm Network-on-Chip on msm8916-based + platforms. + config INTERCONNECT_QCOM_QCS404 tristate "Qualcomm QCS404 interconnect driver" depends on INTERCONNECT_QCOM diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile index 9adf9e380545..e8271575e3d8 100644 --- a/drivers/interconnect/qcom/Makefile +++ b/drivers/interconnect/qcom/Makefile @@ -1,10 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 +qnoc-msm8916-objs := msm8916.o qnoc-msm8974-objs := msm8974.o qnoc-qcs404-objs := qcs404.o qnoc-sdm845-objs := sdm845.o icc-smd-rpm-objs := smd-rpm.o +obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916) += qnoc-msm8916.o obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o diff --git a/drivers/interconnect/qcom/msm8916.c b/drivers/interconnect/qcom/msm8916.c new file mode 100644 index 000000000000..752012c87e63 --- /dev/null +++ b/drivers/interconnect/qcom/msm8916.c @@ -0,0 +1,572 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018-2019 Linaro Ltd + * Author: Georgi Djakov <georgi.djakov@linaro.org> + */ + +#include <dt-bindings/interconnect/qcom,msm8916.h> +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/interconnect-provider.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> + +#include "smd-rpm.h" + +#define RPM_BUS_MASTER_REQ 0x73616d62 +#define RPM_BUS_SLAVE_REQ 0x766c7362 + +enum { + MSM8916_BIMC_SNOC_MAS = 1, + MSM8916_BIMC_SNOC_SLV, + MSM8916_MASTER_AMPSS_M0, + MSM8916_MASTER_LPASS, + MSM8916_MASTER_BLSP_1, + MSM8916_MASTER_DEHR, + MSM8916_MASTER_GRAPHICS_3D, + MSM8916_MASTER_JPEG, + MSM8916_MASTER_MDP_PORT0, + MSM8916_MASTER_CRYPTO_CORE0, + MSM8916_MASTER_SDCC_1, + MSM8916_MASTER_SDCC_2, + MSM8916_MASTER_QDSS_BAM, + MSM8916_MASTER_QDSS_ETR, + MSM8916_MASTER_SNOC_CFG, + MSM8916_MASTER_SPDM, + MSM8916_MASTER_TCU0, + MSM8916_MASTER_TCU1, + MSM8916_MASTER_USB_HS, + MSM8916_MASTER_VFE, + MSM8916_MASTER_VIDEO_P0, + MSM8916_SNOC_MM_INT_0, + MSM8916_SNOC_MM_INT_1, + MSM8916_SNOC_MM_INT_2, + MSM8916_SNOC_MM_INT_BIMC, + MSM8916_PNOC_INT_0, + MSM8916_PNOC_INT_1, + MSM8916_PNOC_MAS_0, + MSM8916_PNOC_MAS_1, + MSM8916_PNOC_SLV_0, + MSM8916_PNOC_SLV_1, + MSM8916_PNOC_SLV_2, + MSM8916_PNOC_SLV_3, + MSM8916_PNOC_SLV_4, + MSM8916_PNOC_SLV_8, + MSM8916_PNOC_SLV_9, + MSM8916_PNOC_SNOC_MAS, + MSM8916_PNOC_SNOC_SLV, + MSM8916_SNOC_QDSS_INT, + MSM8916_SLAVE_AMPSS_L2, + MSM8916_SLAVE_APSS, + MSM8916_SLAVE_LPASS, + MSM8916_SLAVE_BIMC_CFG, + MSM8916_SLAVE_BLSP_1, + MSM8916_SLAVE_BOOT_ROM, + MSM8916_SLAVE_CAMERA_CFG, + MSM8916_SLAVE_CATS_128, + MSM8916_SLAVE_OCMEM_64, + MSM8916_SLAVE_CLK_CTL, + MSM8916_SLAVE_CRYPTO_0_CFG, + MSM8916_SLAVE_DEHR_CFG, + MSM8916_SLAVE_DISPLAY_CFG, + MSM8916_SLAVE_EBI_CH0, + MSM8916_SLAVE_GRAPHICS_3D_CFG, + MSM8916_SLAVE_IMEM_CFG, + MSM8916_SLAVE_IMEM, + MSM8916_SLAVE_MPM, + MSM8916_SLAVE_MSG_RAM, + MSM8916_SLAVE_MSS, + MSM8916_SLAVE_PDM, + MSM8916_SLAVE_PMIC_ARB, + MSM8916_SLAVE_PNOC_CFG, + MSM8916_SLAVE_PRNG, + MSM8916_SLAVE_QDSS_CFG, + MSM8916_SLAVE_QDSS_STM, + MSM8916_SLAVE_RBCPR_CFG, + MSM8916_SLAVE_SDCC_1, + MSM8916_SLAVE_SDCC_2, + MSM8916_SLAVE_SECURITY, + MSM8916_SLAVE_SNOC_CFG, + MSM8916_SLAVE_SPDM, + MSM8916_SLAVE_SRVC_SNOC, + MSM8916_SLAVE_TCSR, + MSM8916_SLAVE_TLMM, + MSM8916_SLAVE_USB_HS, + MSM8916_SLAVE_VENUS_CFG, + MSM8916_SNOC_BIMC_0_MAS, + MSM8916_SNOC_BIMC_0_SLV, + MSM8916_SNOC_BIMC_1_MAS, + MSM8916_SNOC_BIMC_1_SLV, + MSM8916_SNOC_INT_0, + MSM8916_SNOC_INT_1, + MSM8916_SNOC_INT_BIMC, + MSM8916_SNOC_PNOC_MAS, + MSM8916_SNOC_PNOC_SLV, +}; + +#define to_qcom_provider(_provider) \ + container_of(_provider, struct qcom_icc_provider, provider) + +static const struct clk_bulk_data bus_clocks[] = { + { .id = "bus" }, + { .id = "bus_a" }, +}; + +/** + * struct qcom_icc_provider - Qualcomm specific interconnect provider + * @provider: generic interconnect provider + * @bus_clks: the clk_bulk_data table of bus clocks + * @num_clks: the total number of clk_bulk_data entries + */ +struct qcom_icc_provider { + struct icc_provider provider; + struct clk_bulk_data *bus_clks; + int num_clks; +}; + +#define MSM8916_MAX_LINKS 8 + +/** + * struct qcom_icc_node - Qualcomm specific interconnect nodes + * @name: the node name used in debugfs + * @id: a unique node identifier + * @links: an array of nodes where we can go next while traversing + * @num_links: the total number of @links + * @buswidth: width of the interconnect between a node and the bus (bytes) + * @mas_rpm_id: RPM id for devices that are bus masters + * @slv_rpm_id: RPM id for devices that are bus slaves + * @rate: current bus clock rate in Hz + */ +struct qcom_icc_node { + unsigned char *name; + u16 id; + u16 links[MSM8916_MAX_LINKS]; + u16 num_links; + u16 buswidth; + int mas_rpm_id; + int slv_rpm_id; + u64 rate; +}; + +struct qcom_icc_desc { + struct qcom_icc_node **nodes; + size_t num_nodes; +}; + +#define DEFINE_QNODE(_name, _id, _buswidth, _mas_rpm_id, _slv_rpm_id, \ + ...) \ + static struct qcom_icc_node _name = { \ + .name = #_name, \ + .id = _id, \ + .buswidth = _buswidth, \ + .mas_rpm_id = _mas_rpm_id, \ + .slv_rpm_id = _slv_rpm_id, \ + .num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })), \ + .links = { __VA_ARGS__ }, \ + } + +DEFINE_QNODE(bimc_snoc_mas, MSM8916_BIMC_SNOC_MAS, 8, -1, -1, MSM8916_BIMC_SNOC_SLV); +DEFINE_QNODE(bimc_snoc_slv, MSM8916_BIMC_SNOC_SLV, 8, -1, -1, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_1); +DEFINE_QNODE(mas_apss, MSM8916_MASTER_AMPSS_M0, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2); +DEFINE_QNODE(mas_audio, MSM8916_MASTER_LPASS, 4, -1, -1, MSM8916_PNOC_MAS_0); +DEFINE_QNODE(mas_blsp_1, MSM8916_MASTER_BLSP_1, 4, -1, -1, MSM8916_PNOC_MAS_1); +DEFINE_QNODE(mas_dehr, MSM8916_MASTER_DEHR, 4, -1, -1, MSM8916_PNOC_MAS_0); +DEFINE_QNODE(mas_gfx, MSM8916_MASTER_GRAPHICS_3D, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2); +DEFINE_QNODE(mas_jpeg, MSM8916_MASTER_JPEG, 16, -1, -1, MSM8916_SNOC_MM_INT_0, MSM8916_SNOC_MM_INT_2); +DEFINE_QNODE(mas_mdp, MSM8916_MASTER_MDP_PORT0, 16, -1, -1, MSM8916_SNOC_MM_INT_0, MSM8916_SNOC_MM_INT_2); +DEFINE_QNODE(mas_pcnoc_crypto_0, MSM8916_MASTER_CRYPTO_CORE0, 8, -1, -1, MSM8916_PNOC_INT_1); +DEFINE_QNODE(mas_pcnoc_sdcc_1, MSM8916_MASTER_SDCC_1, 8, -1, -1, MSM8916_PNOC_INT_1); +DEFINE_QNODE(mas_pcnoc_sdcc_2, MSM8916_MASTER_SDCC_2, 8, -1, -1, MSM8916_PNOC_INT_1); +DEFINE_QNODE(mas_qdss_bam, MSM8916_MASTER_QDSS_BAM, 8, -1, -1, MSM8916_SNOC_QDSS_INT); +DEFINE_QNODE(mas_qdss_etr, MSM8916_MASTER_QDSS_ETR, 8, -1, -1, MSM8916_SNOC_QDSS_INT); +DEFINE_QNODE(mas_snoc_cfg, MSM8916_MASTER_SNOC_CFG, 4, 20, -1, MSM8916_SNOC_QDSS_INT); +DEFINE_QNODE(mas_spdm, MSM8916_MASTER_SPDM, 4, -1, -1, MSM8916_PNOC_MAS_0); +DEFINE_QNODE(mas_tcu0, MSM8916_MASTER_TCU0, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2); +DEFINE_QNODE(mas_tcu1, MSM8916_MASTER_TCU1, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2); +DEFINE_QNODE(mas_usb_hs, MSM8916_MASTER_USB_HS, 4, -1, -1, MSM8916_PNOC_MAS_1); +DEFINE_QNODE(mas_vfe, MSM8916_MASTER_VFE, 16, -1, -1, MSM8916_SNOC_MM_INT_1, MSM8916_SNOC_MM_INT_2); +DEFINE_QNODE(mas_video, MSM8916_MASTER_VIDEO_P0, 16, -1, -1, MSM8916_SNOC_MM_INT_0, MSM8916_SNOC_MM_INT_2); +DEFINE_QNODE(mm_int_0, MSM8916_SNOC_MM_INT_0, 16, -1, -1, MSM8916_SNOC_MM_INT_BIMC); +DEFINE_QNODE(mm_int_1, MSM8916_SNOC_MM_INT_1, 16, -1, -1, MSM8916_SNOC_MM_INT_BIMC); +DEFINE_QNODE(mm_int_2, MSM8916_SNOC_MM_INT_2, 16, -1, -1, MSM8916_SNOC_INT_0); +DEFINE_QNODE(mm_int_bimc, MSM8916_SNOC_MM_INT_BIMC, 16, -1, -1, MSM8916_SNOC_BIMC_1_MAS); +DEFINE_QNODE(pcnoc_int_0, MSM8916_PNOC_INT_0, 8, -1, -1, MSM8916_PNOC_SNOC_MAS, MSM8916_PNOC_SLV_0, MSM8916_PNOC_SLV_1, MSM8916_PNOC_SLV_2, MSM8916_PNOC_SLV_3, MSM8916_PNOC_SLV_4, MSM8916_PNOC_SLV_8, MSM8916_PNOC_SLV_9); +DEFINE_QNODE(pcnoc_int_1, MSM8916_PNOC_INT_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS); +DEFINE_QNODE(pcnoc_m_0, MSM8916_PNOC_MAS_0, 8, -1, -1, MSM8916_PNOC_INT_0); +DEFINE_QNODE(pcnoc_m_1, MSM8916_PNOC_MAS_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS); +DEFINE_QNODE(pcnoc_s_0, MSM8916_PNOC_SLV_0, 8, -1, -1, MSM8916_SLAVE_CLK_CTL, MSM8916_SLAVE_TLMM, MSM8916_SLAVE_TCSR, MSM8916_SLAVE_SECURITY, MSM8916_SLAVE_MSS); +DEFINE_QNODE(pcnoc_s_1, MSM8916_PNOC_SLV_1, 8, -1, -1, MSM8916_SLAVE_IMEM_CFG, MSM8916_SLAVE_CRYPTO_0_CFG, MSM8916_SLAVE_MSG_RAM, MSM8916_SLAVE_PDM, MSM8916_SLAVE_PRNG); +DEFINE_QNODE(pcnoc_s_2, MSM8916_PNOC_SLV_2, 8, -1, -1, MSM8916_SLAVE_SPDM, MSM8916_SLAVE_BOOT_ROM, MSM8916_SLAVE_BIMC_CFG, MSM8916_SLAVE_PNOC_CFG, MSM8916_SLAVE_PMIC_ARB); +DEFINE_QNODE(pcnoc_s_3, MSM8916_PNOC_SLV_3, 8, -1, -1, MSM8916_SLAVE_MPM, MSM8916_SLAVE_SNOC_CFG, MSM8916_SLAVE_RBCPR_CFG, MSM8916_SLAVE_QDSS_CFG, MSM8916_SLAVE_DEHR_CFG); +DEFINE_QNODE(pcnoc_s_4, MSM8916_PNOC_SLV_4, 8, -1, -1, MSM8916_SLAVE_VENUS_CFG, MSM8916_SLAVE_CAMERA_CFG, MSM8916_SLAVE_DISPLAY_CFG); +DEFINE_QNODE(pcnoc_s_8, MSM8916_PNOC_SLV_8, 8, -1, -1, MSM8916_SLAVE_USB_HS, MSM8916_SLAVE_SDCC_1, MSM8916_SLAVE_BLSP_1); +DEFINE_QNODE(pcnoc_s_9, MSM8916_PNOC_SLV_9, 8, -1, -1, MSM8916_SLAVE_SDCC_2, MSM8916_SLAVE_LPASS, MSM8916_SLAVE_GRAPHICS_3D_CFG); +DEFINE_QNODE(pcnoc_snoc_mas, MSM8916_PNOC_SNOC_MAS, 8, 29, -1, MSM8916_PNOC_SNOC_SLV); +DEFINE_QNODE(pcnoc_snoc_slv, MSM8916_PNOC_SNOC_SLV, 8, -1, 45, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC, MSM8916_SNOC_INT_1); +DEFINE_QNODE(qdss_int, MSM8916_SNOC_QDSS_INT, 8, -1, -1, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC); +DEFINE_QNODE(slv_apps_l2, MSM8916_SLAVE_AMPSS_L2, 8, -1, -1, 0); +DEFINE_QNODE(slv_apss, MSM8916_SLAVE_APSS, 4, -1, 20, 0); +DEFINE_QNODE(slv_audio, MSM8916_SLAVE_LPASS, 4, -1, -1, 0); +DEFINE_QNODE(slv_bimc_cfg, MSM8916_SLAVE_BIMC_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_blsp_1, MSM8916_SLAVE_BLSP_1, 4, -1, -1, 0); +DEFINE_QNODE(slv_boot_rom, MSM8916_SLAVE_BOOT_ROM, 4, -1, -1, 0); +DEFINE_QNODE(slv_camera_cfg, MSM8916_SLAVE_CAMERA_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_cats_0, MSM8916_SLAVE_CATS_128, 16, -1, 106, 0); +DEFINE_QNODE(slv_cats_1, MSM8916_SLAVE_OCMEM_64, 8, -1, 107, 0); +DEFINE_QNODE(slv_clk_ctl, MSM8916_SLAVE_CLK_CTL, 4, -1, -1, 0); +DEFINE_QNODE(slv_crypto_0_cfg, MSM8916_SLAVE_CRYPTO_0_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_dehr_cfg, MSM8916_SLAVE_DEHR_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_display_cfg, MSM8916_SLAVE_DISPLAY_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_ebi_ch0, MSM8916_SLAVE_EBI_CH0, 8, -1, 0, 0); +DEFINE_QNODE(slv_gfx_cfg, MSM8916_SLAVE_GRAPHICS_3D_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_imem_cfg, MSM8916_SLAVE_IMEM_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_imem, MSM8916_SLAVE_IMEM, 8, -1, 26, 0); +DEFINE_QNODE(slv_mpm, MSM8916_SLAVE_MPM, 4, -1, -1, 0); +DEFINE_QNODE(slv_msg_ram, MSM8916_SLAVE_MSG_RAM, 4, -1, -1, 0); +DEFINE_QNODE(slv_mss, MSM8916_SLAVE_MSS, 4, -1, -1, 0); +DEFINE_QNODE(slv_pdm, MSM8916_SLAVE_PDM, 4, -1, -1, 0); +DEFINE_QNODE(slv_pmic_arb, MSM8916_SLAVE_PMIC_ARB, 4, -1, -1, 0); +DEFINE_QNODE(slv_pcnoc_cfg, MSM8916_SLAVE_PNOC_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_prng, MSM8916_SLAVE_PRNG, 4, -1, -1, 0); +DEFINE_QNODE(slv_qdss_cfg, MSM8916_SLAVE_QDSS_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_qdss_stm, MSM8916_SLAVE_QDSS_STM, 4, -1, 30, 0); +DEFINE_QNODE(slv_rbcpr_cfg, MSM8916_SLAVE_RBCPR_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_sdcc_1, MSM8916_SLAVE_SDCC_1, 4, -1, -1, 0); +DEFINE_QNODE(slv_sdcc_2, MSM8916_SLAVE_SDCC_2, 4, -1, -1, 0); +DEFINE_QNODE(slv_security, MSM8916_SLAVE_SECURITY, 4, -1, -1, 0); +DEFINE_QNODE(slv_snoc_cfg, MSM8916_SLAVE_SNOC_CFG, 4, -1, -1, 0); +DEFINE_QNODE(slv_spdm, MSM8916_SLAVE_SPDM, 4, -1, -1, 0); +DEFINE_QNODE(slv_srvc_snoc, MSM8916_SLAVE_SRVC_SNOC, 8, -1, 29, 0); +DEFINE_QNODE(slv_tcsr, MSM8916_SLAVE_TCSR, 4, -1, -1, 0); +DEFINE_QNODE(slv_tlmm, MSM8916_SLAVE_TLMM, 4, -1, -1, 0); +DEFINE_QNODE(slv_usb_hs, MSM8916_SLAVE_USB_HS, 4, -1, -1, 0); +DEFINE_QNODE(slv_venus_cfg, MSM8916_SLAVE_VENUS_CFG, 4, -1, -1, 0); +DEFINE_QNODE(snoc_bimc_0_mas, MSM8916_SNOC_BIMC_0_MAS, 8, 3, -1, MSM8916_SNOC_BIMC_0_SLV); +DEFINE_QNODE(snoc_bimc_0_slv, MSM8916_SNOC_BIMC_0_SLV, 8, -1, 24, MSM8916_SLAVE_EBI_CH0); +DEFINE_QNODE(snoc_bimc_1_mas, MSM8916_SNOC_BIMC_1_MAS, 16, -1, -1, MSM8916_SNOC_BIMC_1_SLV); +DEFINE_QNODE(snoc_bimc_1_slv, MSM8916_SNOC_BIMC_1_SLV, 8, -1, -1, MSM8916_SLAVE_EBI_CH0); +DEFINE_QNODE(snoc_int_0, MSM8916_SNOC_INT_0, 8, 99, 130, MSM8916_SLAVE_QDSS_STM, MSM8916_SLAVE_IMEM, MSM8916_SNOC_PNOC_MAS); +DEFINE_QNODE(snoc_int_1, MSM8916_SNOC_INT_1, 8, 100, 131, MSM8916_SLAVE_APSS, MSM8916_SLAVE_CATS_128, MSM8916_SLAVE_OCMEM_64); +DEFINE_QNODE(snoc_int_bimc, MSM8916_SNOC_INT_BIMC, 8, 101, 132, MSM8916_SNOC_BIMC_0_MAS); +DEFINE_QNODE(snoc_pcnoc_mas, MSM8916_SNOC_PNOC_MAS, 8, -1, -1, MSM8916_SNOC_PNOC_SLV); +DEFINE_QNODE(snoc_pcnoc_slv, MSM8916_SNOC_PNOC_SLV, 8, -1, -1, MSM8916_PNOC_INT_0); + +static struct qcom_icc_node *msm8916_snoc_nodes[] = { + [BIMC_SNOC_SLV] = &bimc_snoc_slv, + [MASTER_JPEG] = &mas_jpeg, + [MASTER_MDP_PORT0] = &mas_mdp, + [MASTER_QDSS_BAM] = &mas_qdss_bam, + [MASTER_QDSS_ETR] = &mas_qdss_etr, + [MASTER_SNOC_CFG] = &mas_snoc_cfg, + [MASTER_VFE] = &mas_vfe, + [MASTER_VIDEO_P0] = &mas_video, + [SNOC_MM_INT_0] = &mm_int_0, + [SNOC_MM_INT_1] = &mm_int_1, + [SNOC_MM_INT_2] = &mm_int_2, + [SNOC_MM_INT_BIMC] = &mm_int_bimc, + [PCNOC_SNOC_SLV] = &pcnoc_snoc_slv, + [SLAVE_APSS] = &slv_apss, + [SLAVE_CATS_128] = &slv_cats_0, + [SLAVE_OCMEM_64] = &slv_cats_1, + [SLAVE_IMEM] = &slv_imem, + [SLAVE_QDSS_STM] = &slv_qdss_stm, + [SLAVE_SRVC_SNOC] = &slv_srvc_snoc, + [SNOC_BIMC_0_MAS] = &snoc_bimc_0_mas, + [SNOC_BIMC_1_MAS] = &snoc_bimc_1_mas, + [SNOC_INT_0] = &snoc_int_0, + [SNOC_INT_1] = &snoc_int_1, + [SNOC_INT_BIMC] = &snoc_int_bimc, + [SNOC_PCNOC_MAS] = &snoc_pcnoc_mas, + [SNOC_QDSS_INT] = &qdss_int, +}; + +static struct qcom_icc_desc msm8916_snoc = { + .nodes = msm8916_snoc_nodes, + .num_nodes = ARRAY_SIZE(msm8916_snoc_nodes), +}; + +static struct qcom_icc_node *msm8916_bimc_nodes[] = { + [BIMC_SNOC_MAS] = &bimc_snoc_mas, + [MASTER_AMPSS_M0] = &mas_apss, + [MASTER_GRAPHICS_3D] = &mas_gfx, + [MASTER_TCU0] = &mas_tcu0, + [MASTER_TCU1] = &mas_tcu1, + [SLAVE_AMPSS_L2] = &slv_apps_l2, + [SLAVE_EBI_CH0] = &slv_ebi_ch0, + [SNOC_BIMC_0_SLV] = &snoc_bimc_0_slv, + [SNOC_BIMC_1_SLV] = &snoc_bimc_1_slv, +}; + +static struct qcom_icc_desc msm8916_bimc = { + .nodes = msm8916_bimc_nodes, + .num_nodes = ARRAY_SIZE(msm8916_bimc_nodes), +}; + +static struct qcom_icc_node *msm8916_pcnoc_nodes[] = { + [MASTER_BLSP_1] = &mas_blsp_1, + [MASTER_DEHR] = &mas_dehr, + [MASTER_LPASS] = &mas_audio, + [MASTER_CRYPTO_CORE0] = &mas_pcnoc_crypto_0, + [MASTER_SDCC_1] = &mas_pcnoc_sdcc_1, + [MASTER_SDCC_2] = &mas_pcnoc_sdcc_2, + [MASTER_SPDM] = &mas_spdm, + [MASTER_USB_HS] = &mas_usb_hs, + [PCNOC_INT_0] = &pcnoc_int_0, + [PCNOC_INT_1] = &pcnoc_int_1, + [PCNOC_MAS_0] = &pcnoc_m_0, + [PCNOC_MAS_1] = &pcnoc_m_1, + [PCNOC_SLV_0] = &pcnoc_s_0, + [PCNOC_SLV_1] = &pcnoc_s_1, + [PCNOC_SLV_2] = &pcnoc_s_2, + [PCNOC_SLV_3] = &pcnoc_s_3, + [PCNOC_SLV_4] = &pcnoc_s_4, + [PCNOC_SLV_8] = &pcnoc_s_8, + [PCNOC_SLV_9] = &pcnoc_s_9, + [PCNOC_SNOC_MAS] = &pcnoc_snoc_mas, + [SLAVE_BIMC_CFG] = &slv_bimc_cfg, + [SLAVE_BLSP_1] = &slv_blsp_1, + [SLAVE_BOOT_ROM] = &slv_boot_rom, + [SLAVE_CAMERA_CFG] = &slv_camera_cfg, + [SLAVE_CLK_CTL] = &slv_clk_ctl, + [SLAVE_CRYPTO_0_CFG] = &slv_crypto_0_cfg, + [SLAVE_DEHR_CFG] = &slv_dehr_cfg, + [SLAVE_DISPLAY_CFG] = &slv_display_cfg, + [SLAVE_GRAPHICS_3D_CFG] = &slv_gfx_cfg, + [SLAVE_IMEM_CFG] = &slv_imem_cfg, + [SLAVE_LPASS] = &slv_audio, + [SLAVE_MPM] = &slv_mpm, + [SLAVE_MSG_RAM] = &slv_msg_ram, + [SLAVE_MSS] = &slv_mss, + [SLAVE_PDM] = &slv_pdm, + [SLAVE_PMIC_ARB] = &slv_pmic_arb, + [SLAVE_PCNOC_CFG] = &slv_pcnoc_cfg, + [SLAVE_PRNG] = &slv_prng, + [SLAVE_QDSS_CFG] = &slv_qdss_cfg, + [SLAVE_RBCPR_CFG] = &slv_rbcpr_cfg, + [SLAVE_SDCC_1] = &slv_sdcc_1, + [SLAVE_SDCC_2] = &slv_sdcc_2, + [SLAVE_SECURITY] = &slv_security, + [SLAVE_SNOC_CFG] = &slv_snoc_cfg, + [SLAVE_SPDM] = &slv_spdm, + [SLAVE_TCSR] = &slv_tcsr, + [SLAVE_TLMM] = &slv_tlmm, + [SLAVE_USB_HS] = &slv_usb_hs, + [SLAVE_VENUS_CFG] = &slv_venus_cfg, + [SNOC_PCNOC_SLV] = &snoc_pcnoc_slv, +}; + +static struct qcom_icc_desc msm8916_pcnoc = { + .nodes = msm8916_pcnoc_nodes, + .num_nodes = ARRAY_SIZE(msm8916_pcnoc_nodes), +}; + +static int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, + u32 peak_bw, u32 *agg_avg, u32 *agg_peak) +{ + *agg_avg += avg_bw; + *agg_peak = max(*agg_peak, peak_bw); + + return 0; +} + +static int qcom_icc_set(struct icc_node *src, struct icc_node *dst) +{ + struct qcom_icc_provider *qp; + struct qcom_icc_node *qn; + struct icc_provider *provider; + struct icc_node *n; + u64 sum_bw; + u64 max_peak_bw; + u64 rate; + u32 agg_avg = 0; + u32 agg_peak = 0; + int ret, i; + + qn = src->data; + provider = src->provider; + qp = to_qcom_provider(provider); + + list_for_each_entry(n, &provider->nodes, node_list) + qcom_icc_aggregate(n, 0, n->avg_bw, n->peak_bw, + &agg_avg, &agg_peak); + + sum_bw = icc_units_to_bps(agg_avg); + max_peak_bw = icc_units_to_bps(agg_peak); + + /* send bandwidth request message to the RPM processor */ + if (qn->mas_rpm_id != -1) { + ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE, + RPM_BUS_MASTER_REQ, + qn->mas_rpm_id, + sum_bw); + if (ret) { + pr_err("qcom_icc_rpm_smd_send mas %d error %d\n", + qn->mas_rpm_id, ret); + return ret; + } + } + + if (qn->slv_rpm_id != -1) { + ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE, + RPM_BUS_SLAVE_REQ, + qn->slv_rpm_id, + sum_bw); + if (ret) { + pr_err("qcom_icc_rpm_smd_send slv error %d\n", + ret); + return ret; + } + } + + rate = max(sum_bw, max_peak_bw); + + do_div(rate, qn->buswidth); + + if (qn->rate == rate) + return 0; + + for (i = 0; i < qp->num_clks; i++) { + ret = clk_set_rate(qp->bus_clks[i].clk, rate); + if (ret) { + pr_err("%s clk_set_rate error: %d\n", + qp->bus_clks[i].id, ret); + return ret; + } + } + + qn->rate = rate; + + return 0; +} + +static int qnoc_remove(struct platform_device *pdev) +{ + struct qcom_icc_provider *qp = platform_get_drvdata(pdev); + struct icc_provider *provider = &qp->provider; + struct icc_node *n; + + list_for_each_entry(n, &provider->nodes, node_list) { + icc_node_del(n); + icc_node_destroy(n->id); + } + clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks); + + return icc_provider_del(provider); +} + +static int qnoc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct qcom_icc_desc *desc; + struct icc_onecell_data *data; + struct icc_provider *provider; + struct qcom_icc_node **qnodes; + struct qcom_icc_provider *qp; + struct icc_node *node; + size_t num_nodes, i; + int ret; + + /* wait for the RPM proxy */ + if (!qcom_icc_rpm_smd_available()) + return -EPROBE_DEFER; + + desc = of_device_get_match_data(dev); + if (!desc) + return -EINVAL; + + qnodes = desc->nodes; + num_nodes = desc->num_nodes; + + qp = devm_kzalloc(dev, sizeof(*qp), GFP_KERNEL); + if (!qp) + return -ENOMEM; + + data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + qp->bus_clks = devm_kmemdup(dev, bus_clocks, sizeof(bus_clocks), + GFP_KERNEL); + if (!qp->bus_clks) + return -ENOMEM; + + qp->num_clks = ARRAY_SIZE(bus_clocks); + ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks); + if (ret) + return ret; + + ret = clk_bulk_prepare_enable(qp->num_clks, qp->bus_clks); + if (ret) + return ret; + + provider = &qp->provider; + INIT_LIST_HEAD(&provider->nodes); + provider->dev = dev; + provider->set = qcom_icc_set; + provider->aggregate = qcom_icc_aggregate; + provider->xlate = of_icc_xlate_onecell; + provider->data = data; + + ret = icc_provider_add(provider); + if (ret) { + dev_err(dev, "error adding interconnect provider: %d\n", ret); + clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks); + return ret; + } + + for (i = 0; i < num_nodes; i++) { + size_t j; + + node = icc_node_create(qnodes[i]->id); + if (IS_ERR(node)) { + ret = PTR_ERR(node); + goto err; + } + + node->name = qnodes[i]->name; + node->data = qnodes[i]; + icc_node_add(node, provider); + + dev_dbg(dev, "registered node %s\n", node->name); + + /* populate links */ + for (j = 0; j < qnodes[i]->num_links; j++) + icc_link_create(node, qnodes[i]->links[j]); + + data->nodes[i] = node; + } + data->num_nodes = num_nodes; + + platform_set_drvdata(pdev, qp); + + return 0; +err: + qnoc_remove(pdev); + + return ret; +} + +static const struct of_device_id msm8916_noc_of_match[] = { + { .compatible = "qcom,msm8916-bimc", .data = &msm8916_bimc }, + { .compatible = "qcom,msm8916-pcnoc", .data = &msm8916_pcnoc }, + { .compatible = "qcom,msm8916-snoc", .data = &msm8916_snoc }, + { }, +}; +MODULE_DEVICE_TABLE(of, msm8916_noc_of_match); + +static struct platform_driver msm8916_noc_driver = { + .probe = qnoc_probe, + .remove = qnoc_remove, + .driver = { + .name = "qnoc-msm8916", + .of_match_table = msm8916_noc_of_match, + }, +}; +module_platform_driver(msm8916_noc_driver); +MODULE_AUTHOR("Georgi Djakov <georgi.djakov@linaro.org>"); +MODULE_DESCRIPTION("Qualcomm MSM8916 NoC driver"); +MODULE_LICENSE("GPL v2"); ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v10 2/3] interconnect: qcom: Add MSM8916 interconnect provider driver 2019-10-30 15:39 ` [PATCH v10 2/3] interconnect: qcom: Add MSM8916 interconnect provider driver Georgi Djakov @ 2019-11-13 13:03 ` Dmitry Osipenko 2019-11-13 13:24 ` Georgi Djakov 0 siblings, 1 reply; 7+ messages in thread From: Dmitry Osipenko @ 2019-11-13 13:03 UTC (permalink / raw) To: Georgi Djakov, robh+dt, linux-pm Cc: agross, bjorn.andersson, evgreen, daidavid1, vincent.guittot, linux-arm-msm, devicetree, linux-kernel 30.10.2019 18:39, Georgi Djakov пишет: > Add driver for the Qualcomm interconnect buses found in MSM8916 based > platforms. The topology consists of three NoCs that are controlled by > a remote processor that collects the aggregated bandwidth for each > master-slave pairs. > > Reviewed-by: Evan Green <evgreen@chromium.org> > Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> > --- > drivers/interconnect/qcom/Kconfig | 9 + > drivers/interconnect/qcom/Makefile | 2 + > drivers/interconnect/qcom/msm8916.c | 572 ++++++++++++++++++++++++++++ > 3 files changed, 583 insertions(+) > create mode 100644 drivers/interconnect/qcom/msm8916.c > > diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig > index ecf057d7e240..aa395733613e 100644 > --- a/drivers/interconnect/qcom/Kconfig > +++ b/drivers/interconnect/qcom/Kconfig > @@ -5,6 +5,15 @@ config INTERCONNECT_QCOM > help > Support for Qualcomm's Network-on-Chip interconnect hardware. > > +config INTERCONNECT_QCOM_MSM8916 > + tristate "Qualcomm MSM8916 interconnect driver" > + depends on INTERCONNECT_QCOM > + depends on QCOM_SMD_RPM > + select INTERCONNECT_QCOM_SMD_RPM > + help > + This is a driver for the Qualcomm Network-on-Chip on msm8916-based > + platforms. > + > config INTERCONNECT_QCOM_QCS404 > tristate "Qualcomm QCS404 interconnect driver" > depends on INTERCONNECT_QCOM > diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile > index 9adf9e380545..e8271575e3d8 100644 > --- a/drivers/interconnect/qcom/Makefile > +++ b/drivers/interconnect/qcom/Makefile > @@ -1,10 +1,12 @@ > # SPDX-License-Identifier: GPL-2.0 > > +qnoc-msm8916-objs := msm8916.o > qnoc-msm8974-objs := msm8974.o > qnoc-qcs404-objs := qcs404.o > qnoc-sdm845-objs := sdm845.o > icc-smd-rpm-objs := smd-rpm.o > > +obj-$(CONFIG_INTERCONNECT_QCOM_MSM8916) += qnoc-msm8916.o > obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o > obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o > obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o > diff --git a/drivers/interconnect/qcom/msm8916.c b/drivers/interconnect/qcom/msm8916.c > new file mode 100644 > index 000000000000..752012c87e63 > --- /dev/null > +++ b/drivers/interconnect/qcom/msm8916.c > @@ -0,0 +1,572 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018-2019 Linaro Ltd > + * Author: Georgi Djakov <georgi.djakov@linaro.org> > + */ > + > +#include <dt-bindings/interconnect/qcom,msm8916.h> > +#include <linux/clk.h> > +#include <linux/device.h> > +#include <linux/interconnect-provider.h> > +#include <linux/io.h> > +#include <linux/module.h> > +#include <linux/of_device.h> > +#include <linux/of_platform.h> > +#include <linux/platform_device.h> > + > +#include "smd-rpm.h" > + > +#define RPM_BUS_MASTER_REQ 0x73616d62 > +#define RPM_BUS_SLAVE_REQ 0x766c7362 > + > +enum { > + MSM8916_BIMC_SNOC_MAS = 1, > + MSM8916_BIMC_SNOC_SLV, > + MSM8916_MASTER_AMPSS_M0, > + MSM8916_MASTER_LPASS, > + MSM8916_MASTER_BLSP_1, > + MSM8916_MASTER_DEHR, > + MSM8916_MASTER_GRAPHICS_3D, > + MSM8916_MASTER_JPEG, > + MSM8916_MASTER_MDP_PORT0, > + MSM8916_MASTER_CRYPTO_CORE0, > + MSM8916_MASTER_SDCC_1, > + MSM8916_MASTER_SDCC_2, > + MSM8916_MASTER_QDSS_BAM, > + MSM8916_MASTER_QDSS_ETR, > + MSM8916_MASTER_SNOC_CFG, > + MSM8916_MASTER_SPDM, > + MSM8916_MASTER_TCU0, > + MSM8916_MASTER_TCU1, > + MSM8916_MASTER_USB_HS, > + MSM8916_MASTER_VFE, > + MSM8916_MASTER_VIDEO_P0, > + MSM8916_SNOC_MM_INT_0, > + MSM8916_SNOC_MM_INT_1, > + MSM8916_SNOC_MM_INT_2, > + MSM8916_SNOC_MM_INT_BIMC, > + MSM8916_PNOC_INT_0, > + MSM8916_PNOC_INT_1, > + MSM8916_PNOC_MAS_0, > + MSM8916_PNOC_MAS_1, > + MSM8916_PNOC_SLV_0, > + MSM8916_PNOC_SLV_1, > + MSM8916_PNOC_SLV_2, > + MSM8916_PNOC_SLV_3, > + MSM8916_PNOC_SLV_4, > + MSM8916_PNOC_SLV_8, > + MSM8916_PNOC_SLV_9, > + MSM8916_PNOC_SNOC_MAS, > + MSM8916_PNOC_SNOC_SLV, > + MSM8916_SNOC_QDSS_INT, > + MSM8916_SLAVE_AMPSS_L2, > + MSM8916_SLAVE_APSS, > + MSM8916_SLAVE_LPASS, > + MSM8916_SLAVE_BIMC_CFG, > + MSM8916_SLAVE_BLSP_1, > + MSM8916_SLAVE_BOOT_ROM, > + MSM8916_SLAVE_CAMERA_CFG, > + MSM8916_SLAVE_CATS_128, > + MSM8916_SLAVE_OCMEM_64, > + MSM8916_SLAVE_CLK_CTL, > + MSM8916_SLAVE_CRYPTO_0_CFG, > + MSM8916_SLAVE_DEHR_CFG, > + MSM8916_SLAVE_DISPLAY_CFG, > + MSM8916_SLAVE_EBI_CH0, > + MSM8916_SLAVE_GRAPHICS_3D_CFG, > + MSM8916_SLAVE_IMEM_CFG, > + MSM8916_SLAVE_IMEM, > + MSM8916_SLAVE_MPM, > + MSM8916_SLAVE_MSG_RAM, > + MSM8916_SLAVE_MSS, > + MSM8916_SLAVE_PDM, > + MSM8916_SLAVE_PMIC_ARB, > + MSM8916_SLAVE_PNOC_CFG, > + MSM8916_SLAVE_PRNG, > + MSM8916_SLAVE_QDSS_CFG, > + MSM8916_SLAVE_QDSS_STM, > + MSM8916_SLAVE_RBCPR_CFG, > + MSM8916_SLAVE_SDCC_1, > + MSM8916_SLAVE_SDCC_2, > + MSM8916_SLAVE_SECURITY, > + MSM8916_SLAVE_SNOC_CFG, > + MSM8916_SLAVE_SPDM, > + MSM8916_SLAVE_SRVC_SNOC, > + MSM8916_SLAVE_TCSR, > + MSM8916_SLAVE_TLMM, > + MSM8916_SLAVE_USB_HS, > + MSM8916_SLAVE_VENUS_CFG, > + MSM8916_SNOC_BIMC_0_MAS, > + MSM8916_SNOC_BIMC_0_SLV, > + MSM8916_SNOC_BIMC_1_MAS, > + MSM8916_SNOC_BIMC_1_SLV, > + MSM8916_SNOC_INT_0, > + MSM8916_SNOC_INT_1, > + MSM8916_SNOC_INT_BIMC, > + MSM8916_SNOC_PNOC_MAS, > + MSM8916_SNOC_PNOC_SLV, > +}; > + > +#define to_qcom_provider(_provider) \ > + container_of(_provider, struct qcom_icc_provider, provider) > + > +static const struct clk_bulk_data bus_clocks[] = { > + { .id = "bus" }, > + { .id = "bus_a" }, > +}; > + > +/** > + * struct qcom_icc_provider - Qualcomm specific interconnect provider > + * @provider: generic interconnect provider > + * @bus_clks: the clk_bulk_data table of bus clocks > + * @num_clks: the total number of clk_bulk_data entries > + */ > +struct qcom_icc_provider { > + struct icc_provider provider; > + struct clk_bulk_data *bus_clks; > + int num_clks; > +}; > + > +#define MSM8916_MAX_LINKS 8 > + > +/** > + * struct qcom_icc_node - Qualcomm specific interconnect nodes > + * @name: the node name used in debugfs > + * @id: a unique node identifier > + * @links: an array of nodes where we can go next while traversing > + * @num_links: the total number of @links > + * @buswidth: width of the interconnect between a node and the bus (bytes) > + * @mas_rpm_id: RPM id for devices that are bus masters > + * @slv_rpm_id: RPM id for devices that are bus slaves > + * @rate: current bus clock rate in Hz > + */ > +struct qcom_icc_node { > + unsigned char *name; > + u16 id; > + u16 links[MSM8916_MAX_LINKS]; > + u16 num_links; > + u16 buswidth; > + int mas_rpm_id; > + int slv_rpm_id; > + u64 rate; > +}; > + > +struct qcom_icc_desc { > + struct qcom_icc_node **nodes; > + size_t num_nodes; > +}; > + > +#define DEFINE_QNODE(_name, _id, _buswidth, _mas_rpm_id, _slv_rpm_id, \ > + ...) \ > + static struct qcom_icc_node _name = { \ > + .name = #_name, \ > + .id = _id, \ > + .buswidth = _buswidth, \ > + .mas_rpm_id = _mas_rpm_id, \ > + .slv_rpm_id = _slv_rpm_id, \ > + .num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })), \ > + .links = { __VA_ARGS__ }, \ > + } > + > +DEFINE_QNODE(bimc_snoc_mas, MSM8916_BIMC_SNOC_MAS, 8, -1, -1, MSM8916_BIMC_SNOC_SLV); > +DEFINE_QNODE(bimc_snoc_slv, MSM8916_BIMC_SNOC_SLV, 8, -1, -1, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_1); > +DEFINE_QNODE(mas_apss, MSM8916_MASTER_AMPSS_M0, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2); > +DEFINE_QNODE(mas_audio, MSM8916_MASTER_LPASS, 4, -1, -1, MSM8916_PNOC_MAS_0); > +DEFINE_QNODE(mas_blsp_1, MSM8916_MASTER_BLSP_1, 4, -1, -1, MSM8916_PNOC_MAS_1); > +DEFINE_QNODE(mas_dehr, MSM8916_MASTER_DEHR, 4, -1, -1, MSM8916_PNOC_MAS_0); > +DEFINE_QNODE(mas_gfx, MSM8916_MASTER_GRAPHICS_3D, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2); > +DEFINE_QNODE(mas_jpeg, MSM8916_MASTER_JPEG, 16, -1, -1, MSM8916_SNOC_MM_INT_0, MSM8916_SNOC_MM_INT_2); > +DEFINE_QNODE(mas_mdp, MSM8916_MASTER_MDP_PORT0, 16, -1, -1, MSM8916_SNOC_MM_INT_0, MSM8916_SNOC_MM_INT_2); > +DEFINE_QNODE(mas_pcnoc_crypto_0, MSM8916_MASTER_CRYPTO_CORE0, 8, -1, -1, MSM8916_PNOC_INT_1); > +DEFINE_QNODE(mas_pcnoc_sdcc_1, MSM8916_MASTER_SDCC_1, 8, -1, -1, MSM8916_PNOC_INT_1); > +DEFINE_QNODE(mas_pcnoc_sdcc_2, MSM8916_MASTER_SDCC_2, 8, -1, -1, MSM8916_PNOC_INT_1); > +DEFINE_QNODE(mas_qdss_bam, MSM8916_MASTER_QDSS_BAM, 8, -1, -1, MSM8916_SNOC_QDSS_INT); > +DEFINE_QNODE(mas_qdss_etr, MSM8916_MASTER_QDSS_ETR, 8, -1, -1, MSM8916_SNOC_QDSS_INT); > +DEFINE_QNODE(mas_snoc_cfg, MSM8916_MASTER_SNOC_CFG, 4, 20, -1, MSM8916_SNOC_QDSS_INT); > +DEFINE_QNODE(mas_spdm, MSM8916_MASTER_SPDM, 4, -1, -1, MSM8916_PNOC_MAS_0); > +DEFINE_QNODE(mas_tcu0, MSM8916_MASTER_TCU0, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2); > +DEFINE_QNODE(mas_tcu1, MSM8916_MASTER_TCU1, 8, -1, -1, MSM8916_SLAVE_EBI_CH0, MSM8916_BIMC_SNOC_MAS, MSM8916_SLAVE_AMPSS_L2); > +DEFINE_QNODE(mas_usb_hs, MSM8916_MASTER_USB_HS, 4, -1, -1, MSM8916_PNOC_MAS_1); > +DEFINE_QNODE(mas_vfe, MSM8916_MASTER_VFE, 16, -1, -1, MSM8916_SNOC_MM_INT_1, MSM8916_SNOC_MM_INT_2); > +DEFINE_QNODE(mas_video, MSM8916_MASTER_VIDEO_P0, 16, -1, -1, MSM8916_SNOC_MM_INT_0, MSM8916_SNOC_MM_INT_2); > +DEFINE_QNODE(mm_int_0, MSM8916_SNOC_MM_INT_0, 16, -1, -1, MSM8916_SNOC_MM_INT_BIMC); > +DEFINE_QNODE(mm_int_1, MSM8916_SNOC_MM_INT_1, 16, -1, -1, MSM8916_SNOC_MM_INT_BIMC); > +DEFINE_QNODE(mm_int_2, MSM8916_SNOC_MM_INT_2, 16, -1, -1, MSM8916_SNOC_INT_0); > +DEFINE_QNODE(mm_int_bimc, MSM8916_SNOC_MM_INT_BIMC, 16, -1, -1, MSM8916_SNOC_BIMC_1_MAS); > +DEFINE_QNODE(pcnoc_int_0, MSM8916_PNOC_INT_0, 8, -1, -1, MSM8916_PNOC_SNOC_MAS, MSM8916_PNOC_SLV_0, MSM8916_PNOC_SLV_1, MSM8916_PNOC_SLV_2, MSM8916_PNOC_SLV_3, MSM8916_PNOC_SLV_4, MSM8916_PNOC_SLV_8, MSM8916_PNOC_SLV_9); > +DEFINE_QNODE(pcnoc_int_1, MSM8916_PNOC_INT_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS); > +DEFINE_QNODE(pcnoc_m_0, MSM8916_PNOC_MAS_0, 8, -1, -1, MSM8916_PNOC_INT_0); > +DEFINE_QNODE(pcnoc_m_1, MSM8916_PNOC_MAS_1, 8, -1, -1, MSM8916_PNOC_SNOC_MAS); > +DEFINE_QNODE(pcnoc_s_0, MSM8916_PNOC_SLV_0, 8, -1, -1, MSM8916_SLAVE_CLK_CTL, MSM8916_SLAVE_TLMM, MSM8916_SLAVE_TCSR, MSM8916_SLAVE_SECURITY, MSM8916_SLAVE_MSS); > +DEFINE_QNODE(pcnoc_s_1, MSM8916_PNOC_SLV_1, 8, -1, -1, MSM8916_SLAVE_IMEM_CFG, MSM8916_SLAVE_CRYPTO_0_CFG, MSM8916_SLAVE_MSG_RAM, MSM8916_SLAVE_PDM, MSM8916_SLAVE_PRNG); > +DEFINE_QNODE(pcnoc_s_2, MSM8916_PNOC_SLV_2, 8, -1, -1, MSM8916_SLAVE_SPDM, MSM8916_SLAVE_BOOT_ROM, MSM8916_SLAVE_BIMC_CFG, MSM8916_SLAVE_PNOC_CFG, MSM8916_SLAVE_PMIC_ARB); > +DEFINE_QNODE(pcnoc_s_3, MSM8916_PNOC_SLV_3, 8, -1, -1, MSM8916_SLAVE_MPM, MSM8916_SLAVE_SNOC_CFG, MSM8916_SLAVE_RBCPR_CFG, MSM8916_SLAVE_QDSS_CFG, MSM8916_SLAVE_DEHR_CFG); > +DEFINE_QNODE(pcnoc_s_4, MSM8916_PNOC_SLV_4, 8, -1, -1, MSM8916_SLAVE_VENUS_CFG, MSM8916_SLAVE_CAMERA_CFG, MSM8916_SLAVE_DISPLAY_CFG); > +DEFINE_QNODE(pcnoc_s_8, MSM8916_PNOC_SLV_8, 8, -1, -1, MSM8916_SLAVE_USB_HS, MSM8916_SLAVE_SDCC_1, MSM8916_SLAVE_BLSP_1); > +DEFINE_QNODE(pcnoc_s_9, MSM8916_PNOC_SLV_9, 8, -1, -1, MSM8916_SLAVE_SDCC_2, MSM8916_SLAVE_LPASS, MSM8916_SLAVE_GRAPHICS_3D_CFG); > +DEFINE_QNODE(pcnoc_snoc_mas, MSM8916_PNOC_SNOC_MAS, 8, 29, -1, MSM8916_PNOC_SNOC_SLV); > +DEFINE_QNODE(pcnoc_snoc_slv, MSM8916_PNOC_SNOC_SLV, 8, -1, 45, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC, MSM8916_SNOC_INT_1); > +DEFINE_QNODE(qdss_int, MSM8916_SNOC_QDSS_INT, 8, -1, -1, MSM8916_SNOC_INT_0, MSM8916_SNOC_INT_BIMC); > +DEFINE_QNODE(slv_apps_l2, MSM8916_SLAVE_AMPSS_L2, 8, -1, -1, 0); > +DEFINE_QNODE(slv_apss, MSM8916_SLAVE_APSS, 4, -1, 20, 0); > +DEFINE_QNODE(slv_audio, MSM8916_SLAVE_LPASS, 4, -1, -1, 0); > +DEFINE_QNODE(slv_bimc_cfg, MSM8916_SLAVE_BIMC_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_blsp_1, MSM8916_SLAVE_BLSP_1, 4, -1, -1, 0); > +DEFINE_QNODE(slv_boot_rom, MSM8916_SLAVE_BOOT_ROM, 4, -1, -1, 0); > +DEFINE_QNODE(slv_camera_cfg, MSM8916_SLAVE_CAMERA_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_cats_0, MSM8916_SLAVE_CATS_128, 16, -1, 106, 0); > +DEFINE_QNODE(slv_cats_1, MSM8916_SLAVE_OCMEM_64, 8, -1, 107, 0); > +DEFINE_QNODE(slv_clk_ctl, MSM8916_SLAVE_CLK_CTL, 4, -1, -1, 0); > +DEFINE_QNODE(slv_crypto_0_cfg, MSM8916_SLAVE_CRYPTO_0_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_dehr_cfg, MSM8916_SLAVE_DEHR_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_display_cfg, MSM8916_SLAVE_DISPLAY_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_ebi_ch0, MSM8916_SLAVE_EBI_CH0, 8, -1, 0, 0); > +DEFINE_QNODE(slv_gfx_cfg, MSM8916_SLAVE_GRAPHICS_3D_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_imem_cfg, MSM8916_SLAVE_IMEM_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_imem, MSM8916_SLAVE_IMEM, 8, -1, 26, 0); > +DEFINE_QNODE(slv_mpm, MSM8916_SLAVE_MPM, 4, -1, -1, 0); > +DEFINE_QNODE(slv_msg_ram, MSM8916_SLAVE_MSG_RAM, 4, -1, -1, 0); > +DEFINE_QNODE(slv_mss, MSM8916_SLAVE_MSS, 4, -1, -1, 0); > +DEFINE_QNODE(slv_pdm, MSM8916_SLAVE_PDM, 4, -1, -1, 0); > +DEFINE_QNODE(slv_pmic_arb, MSM8916_SLAVE_PMIC_ARB, 4, -1, -1, 0); > +DEFINE_QNODE(slv_pcnoc_cfg, MSM8916_SLAVE_PNOC_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_prng, MSM8916_SLAVE_PRNG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_qdss_cfg, MSM8916_SLAVE_QDSS_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_qdss_stm, MSM8916_SLAVE_QDSS_STM, 4, -1, 30, 0); > +DEFINE_QNODE(slv_rbcpr_cfg, MSM8916_SLAVE_RBCPR_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_sdcc_1, MSM8916_SLAVE_SDCC_1, 4, -1, -1, 0); > +DEFINE_QNODE(slv_sdcc_2, MSM8916_SLAVE_SDCC_2, 4, -1, -1, 0); > +DEFINE_QNODE(slv_security, MSM8916_SLAVE_SECURITY, 4, -1, -1, 0); > +DEFINE_QNODE(slv_snoc_cfg, MSM8916_SLAVE_SNOC_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(slv_spdm, MSM8916_SLAVE_SPDM, 4, -1, -1, 0); > +DEFINE_QNODE(slv_srvc_snoc, MSM8916_SLAVE_SRVC_SNOC, 8, -1, 29, 0); > +DEFINE_QNODE(slv_tcsr, MSM8916_SLAVE_TCSR, 4, -1, -1, 0); > +DEFINE_QNODE(slv_tlmm, MSM8916_SLAVE_TLMM, 4, -1, -1, 0); > +DEFINE_QNODE(slv_usb_hs, MSM8916_SLAVE_USB_HS, 4, -1, -1, 0); > +DEFINE_QNODE(slv_venus_cfg, MSM8916_SLAVE_VENUS_CFG, 4, -1, -1, 0); > +DEFINE_QNODE(snoc_bimc_0_mas, MSM8916_SNOC_BIMC_0_MAS, 8, 3, -1, MSM8916_SNOC_BIMC_0_SLV); > +DEFINE_QNODE(snoc_bimc_0_slv, MSM8916_SNOC_BIMC_0_SLV, 8, -1, 24, MSM8916_SLAVE_EBI_CH0); > +DEFINE_QNODE(snoc_bimc_1_mas, MSM8916_SNOC_BIMC_1_MAS, 16, -1, -1, MSM8916_SNOC_BIMC_1_SLV); > +DEFINE_QNODE(snoc_bimc_1_slv, MSM8916_SNOC_BIMC_1_SLV, 8, -1, -1, MSM8916_SLAVE_EBI_CH0); > +DEFINE_QNODE(snoc_int_0, MSM8916_SNOC_INT_0, 8, 99, 130, MSM8916_SLAVE_QDSS_STM, MSM8916_SLAVE_IMEM, MSM8916_SNOC_PNOC_MAS); > +DEFINE_QNODE(snoc_int_1, MSM8916_SNOC_INT_1, 8, 100, 131, MSM8916_SLAVE_APSS, MSM8916_SLAVE_CATS_128, MSM8916_SLAVE_OCMEM_64); > +DEFINE_QNODE(snoc_int_bimc, MSM8916_SNOC_INT_BIMC, 8, 101, 132, MSM8916_SNOC_BIMC_0_MAS); > +DEFINE_QNODE(snoc_pcnoc_mas, MSM8916_SNOC_PNOC_MAS, 8, -1, -1, MSM8916_SNOC_PNOC_SLV); > +DEFINE_QNODE(snoc_pcnoc_slv, MSM8916_SNOC_PNOC_SLV, 8, -1, -1, MSM8916_PNOC_INT_0); > + > +static struct qcom_icc_node *msm8916_snoc_nodes[] = { > + [BIMC_SNOC_SLV] = &bimc_snoc_slv, > + [MASTER_JPEG] = &mas_jpeg, > + [MASTER_MDP_PORT0] = &mas_mdp, > + [MASTER_QDSS_BAM] = &mas_qdss_bam, > + [MASTER_QDSS_ETR] = &mas_qdss_etr, > + [MASTER_SNOC_CFG] = &mas_snoc_cfg, > + [MASTER_VFE] = &mas_vfe, > + [MASTER_VIDEO_P0] = &mas_video, > + [SNOC_MM_INT_0] = &mm_int_0, > + [SNOC_MM_INT_1] = &mm_int_1, > + [SNOC_MM_INT_2] = &mm_int_2, > + [SNOC_MM_INT_BIMC] = &mm_int_bimc, > + [PCNOC_SNOC_SLV] = &pcnoc_snoc_slv, > + [SLAVE_APSS] = &slv_apss, > + [SLAVE_CATS_128] = &slv_cats_0, > + [SLAVE_OCMEM_64] = &slv_cats_1, > + [SLAVE_IMEM] = &slv_imem, > + [SLAVE_QDSS_STM] = &slv_qdss_stm, > + [SLAVE_SRVC_SNOC] = &slv_srvc_snoc, > + [SNOC_BIMC_0_MAS] = &snoc_bimc_0_mas, > + [SNOC_BIMC_1_MAS] = &snoc_bimc_1_mas, > + [SNOC_INT_0] = &snoc_int_0, > + [SNOC_INT_1] = &snoc_int_1, > + [SNOC_INT_BIMC] = &snoc_int_bimc, > + [SNOC_PCNOC_MAS] = &snoc_pcnoc_mas, > + [SNOC_QDSS_INT] = &qdss_int, > +}; > + > +static struct qcom_icc_desc msm8916_snoc = { > + .nodes = msm8916_snoc_nodes, > + .num_nodes = ARRAY_SIZE(msm8916_snoc_nodes), > +}; > + > +static struct qcom_icc_node *msm8916_bimc_nodes[] = { > + [BIMC_SNOC_MAS] = &bimc_snoc_mas, > + [MASTER_AMPSS_M0] = &mas_apss, > + [MASTER_GRAPHICS_3D] = &mas_gfx, > + [MASTER_TCU0] = &mas_tcu0, > + [MASTER_TCU1] = &mas_tcu1, > + [SLAVE_AMPSS_L2] = &slv_apps_l2, > + [SLAVE_EBI_CH0] = &slv_ebi_ch0, > + [SNOC_BIMC_0_SLV] = &snoc_bimc_0_slv, > + [SNOC_BIMC_1_SLV] = &snoc_bimc_1_slv, > +}; > + > +static struct qcom_icc_desc msm8916_bimc = { > + .nodes = msm8916_bimc_nodes, > + .num_nodes = ARRAY_SIZE(msm8916_bimc_nodes), > +}; > + > +static struct qcom_icc_node *msm8916_pcnoc_nodes[] = { > + [MASTER_BLSP_1] = &mas_blsp_1, > + [MASTER_DEHR] = &mas_dehr, > + [MASTER_LPASS] = &mas_audio, > + [MASTER_CRYPTO_CORE0] = &mas_pcnoc_crypto_0, > + [MASTER_SDCC_1] = &mas_pcnoc_sdcc_1, > + [MASTER_SDCC_2] = &mas_pcnoc_sdcc_2, > + [MASTER_SPDM] = &mas_spdm, > + [MASTER_USB_HS] = &mas_usb_hs, > + [PCNOC_INT_0] = &pcnoc_int_0, > + [PCNOC_INT_1] = &pcnoc_int_1, > + [PCNOC_MAS_0] = &pcnoc_m_0, > + [PCNOC_MAS_1] = &pcnoc_m_1, > + [PCNOC_SLV_0] = &pcnoc_s_0, > + [PCNOC_SLV_1] = &pcnoc_s_1, > + [PCNOC_SLV_2] = &pcnoc_s_2, > + [PCNOC_SLV_3] = &pcnoc_s_3, > + [PCNOC_SLV_4] = &pcnoc_s_4, > + [PCNOC_SLV_8] = &pcnoc_s_8, > + [PCNOC_SLV_9] = &pcnoc_s_9, > + [PCNOC_SNOC_MAS] = &pcnoc_snoc_mas, > + [SLAVE_BIMC_CFG] = &slv_bimc_cfg, > + [SLAVE_BLSP_1] = &slv_blsp_1, > + [SLAVE_BOOT_ROM] = &slv_boot_rom, > + [SLAVE_CAMERA_CFG] = &slv_camera_cfg, > + [SLAVE_CLK_CTL] = &slv_clk_ctl, > + [SLAVE_CRYPTO_0_CFG] = &slv_crypto_0_cfg, > + [SLAVE_DEHR_CFG] = &slv_dehr_cfg, > + [SLAVE_DISPLAY_CFG] = &slv_display_cfg, > + [SLAVE_GRAPHICS_3D_CFG] = &slv_gfx_cfg, > + [SLAVE_IMEM_CFG] = &slv_imem_cfg, > + [SLAVE_LPASS] = &slv_audio, > + [SLAVE_MPM] = &slv_mpm, > + [SLAVE_MSG_RAM] = &slv_msg_ram, > + [SLAVE_MSS] = &slv_mss, > + [SLAVE_PDM] = &slv_pdm, > + [SLAVE_PMIC_ARB] = &slv_pmic_arb, > + [SLAVE_PCNOC_CFG] = &slv_pcnoc_cfg, > + [SLAVE_PRNG] = &slv_prng, > + [SLAVE_QDSS_CFG] = &slv_qdss_cfg, > + [SLAVE_RBCPR_CFG] = &slv_rbcpr_cfg, > + [SLAVE_SDCC_1] = &slv_sdcc_1, > + [SLAVE_SDCC_2] = &slv_sdcc_2, > + [SLAVE_SECURITY] = &slv_security, > + [SLAVE_SNOC_CFG] = &slv_snoc_cfg, > + [SLAVE_SPDM] = &slv_spdm, > + [SLAVE_TCSR] = &slv_tcsr, > + [SLAVE_TLMM] = &slv_tlmm, > + [SLAVE_USB_HS] = &slv_usb_hs, > + [SLAVE_VENUS_CFG] = &slv_venus_cfg, > + [SNOC_PCNOC_SLV] = &snoc_pcnoc_slv, > +}; > + > +static struct qcom_icc_desc msm8916_pcnoc = { > + .nodes = msm8916_pcnoc_nodes, > + .num_nodes = ARRAY_SIZE(msm8916_pcnoc_nodes), > +}; > + > +static int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, > + u32 peak_bw, u32 *agg_avg, u32 *agg_peak) > +{ > + *agg_avg += avg_bw; > + *agg_peak = max(*agg_peak, peak_bw); > + > + return 0; > +} > + > +static int qcom_icc_set(struct icc_node *src, struct icc_node *dst) > +{ > + struct qcom_icc_provider *qp; > + struct qcom_icc_node *qn; > + struct icc_provider *provider; > + struct icc_node *n; > + u64 sum_bw; > + u64 max_peak_bw; > + u64 rate; > + u32 agg_avg = 0; > + u32 agg_peak = 0; > + int ret, i; > + > + qn = src->data; > + provider = src->provider; > + qp = to_qcom_provider(provider); > + > + list_for_each_entry(n, &provider->nodes, node_list) > + qcom_icc_aggregate(n, 0, n->avg_bw, n->peak_bw, > + &agg_avg, &agg_peak); > + > + sum_bw = icc_units_to_bps(agg_avg); > + max_peak_bw = icc_units_to_bps(agg_peak); > + > + /* send bandwidth request message to the RPM processor */ > + if (qn->mas_rpm_id != -1) { > + ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE, > + RPM_BUS_MASTER_REQ, > + qn->mas_rpm_id, > + sum_bw); > + if (ret) { > + pr_err("qcom_icc_rpm_smd_send mas %d error %d\n", > + qn->mas_rpm_id, ret); > + return ret; > + } > + } > + > + if (qn->slv_rpm_id != -1) { > + ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE, > + RPM_BUS_SLAVE_REQ, > + qn->slv_rpm_id, > + sum_bw); > + if (ret) { > + pr_err("qcom_icc_rpm_smd_send slv error %d\n", > + ret); > + return ret; > + } > + } > + > + rate = max(sum_bw, max_peak_bw); > + > + do_div(rate, qn->buswidth); > + > + if (qn->rate == rate) > + return 0; > + > + for (i = 0; i < qp->num_clks; i++) { > + ret = clk_set_rate(qp->bus_clks[i].clk, rate); > + if (ret) { > + pr_err("%s clk_set_rate error: %d\n", > + qp->bus_clks[i].id, ret); > + return ret; > + } > + } > + > + qn->rate = rate; > + > + return 0; > +} > + > +static int qnoc_remove(struct platform_device *pdev) > +{ > + struct qcom_icc_provider *qp = platform_get_drvdata(pdev); > + struct icc_provider *provider = &qp->provider; > + struct icc_node *n; > + > + list_for_each_entry(n, &provider->nodes, node_list) { > + icc_node_del(n); > + icc_node_destroy(n->id); > + } Hello Georgi, While examining the interconnect API and current drivers' code, I noticed that everybody are copying this chunk of code which should crash kernel because removing node from a list during the traverse is allowed only when list_for_each_entry_safe() is used. Seems the IMX driver (which is under review now on the ML) is the only driver that does the removing procedure correctly. Maybe it won't hurt to factor out the removal of provider's nodes into a common helper. [snip] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v10 2/3] interconnect: qcom: Add MSM8916 interconnect provider driver 2019-11-13 13:03 ` Dmitry Osipenko @ 2019-11-13 13:24 ` Georgi Djakov 0 siblings, 0 replies; 7+ messages in thread From: Georgi Djakov @ 2019-11-13 13:24 UTC (permalink / raw) To: Dmitry Osipenko, robh+dt, linux-pm Cc: agross, bjorn.andersson, evgreen, daidavid1, vincent.guittot, linux-arm-msm, devicetree, linux-kernel Hi Dmitry, On 13.11.19 г. 15:03 ч., Dmitry Osipenko wrote: > 30.10.2019 18:39, Georgi Djakov пишет: >> Add driver for the Qualcomm interconnect buses found in MSM8916 based >> platforms. The topology consists of three NoCs that are controlled by >> a remote processor that collects the aggregated bandwidth for each >> master-slave pairs. >> [..] >> +static int qnoc_remove(struct platform_device *pdev) >> +{ >> + struct qcom_icc_provider *qp = platform_get_drvdata(pdev); >> + struct icc_provider *provider = &qp->provider; >> + struct icc_node *n; >> + >> + list_for_each_entry(n, &provider->nodes, node_list) { >> + icc_node_del(n); >> + icc_node_destroy(n->id); >> + } > > Hello Georgi, > > While examining the interconnect API and current drivers' code, I > noticed that everybody are copying this chunk of code which should crash > kernel because removing node from a list during the traverse is allowed > only when list_for_each_entry_safe() is used. Nice catch. Thank you! > Seems the IMX driver (which is under review now on the ML) is the only > driver that does the removing procedure correctly. > > Maybe it won't hurt to factor out the removal of provider's nodes into a > common helper. > Yes, this is a very good idea. Will do it. Thanks, Georgi ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v10 3/3] arm64: dts: msm8916: Add interconnect provider DT nodes 2019-10-30 15:39 [PATCH v10 0/3] Add MSM8916 interconnect provider driver Georgi Djakov 2019-10-30 15:39 ` [PATCH v10 1/3] dt-bindings: interconnect: Add Qualcomm MSM8916 DT bindings Georgi Djakov 2019-10-30 15:39 ` [PATCH v10 2/3] interconnect: qcom: Add MSM8916 interconnect provider driver Georgi Djakov @ 2019-10-30 15:39 ` Georgi Djakov 2 siblings, 0 replies; 7+ messages in thread From: Georgi Djakov @ 2019-10-30 15:39 UTC (permalink / raw) To: robh+dt, linux-pm Cc: agross, bjorn.andersson, evgreen, daidavid1, vincent.guittot, linux-arm-msm, devicetree, linux-kernel, georgi.djakov Add nodes for the network-on-chip interconnect buses present on MSM8916-based platforms. Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org> --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 5ea9fb8f2f87..9c4d89319e7c 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/interconnect/qcom,msm8916.h> #include <dt-bindings/clock/qcom,gcc-msm8916.h> #include <dt-bindings/reset/qcom,gcc-msm8916.h> #include <dt-bindings/clock/qcom,rpmcc.h> @@ -364,11 +365,38 @@ ranges = <0 0 0 0xffffffff>; compatible = "simple-bus"; + 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>; + }; + restart@4ab000 { compatible = "qcom,pshold"; reg = <0x4ab000 0x4>; }; + 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>; + }; + msmgpio: pinctrl@1000000 { compatible = "qcom,msm8916-pinctrl"; reg = <0x1000000 0x300000>; ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2019-11-13 13:24 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-10-30 15:39 [PATCH v10 0/3] Add MSM8916 interconnect provider driver Georgi Djakov 2019-10-30 15:39 ` [PATCH v10 1/3] dt-bindings: interconnect: Add Qualcomm MSM8916 DT bindings Georgi Djakov 2019-11-04 21:28 ` Rob Herring 2019-10-30 15:39 ` [PATCH v10 2/3] interconnect: qcom: Add MSM8916 interconnect provider driver Georgi Djakov 2019-11-13 13:03 ` Dmitry Osipenko 2019-11-13 13:24 ` Georgi Djakov 2019-10-30 15:39 ` [PATCH v10 3/3] arm64: dts: msm8916: Add interconnect provider DT nodes Georgi Djakov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).