Linux-ARM-MSM Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v4 0/5] Add QCS404 interconnect provider driver
@ 2019-06-13 15:13 Georgi Djakov
  2019-06-13 15:13 ` [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings Georgi Djakov
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Georgi Djakov @ 2019-06-13 15:13 UTC (permalink / raw)
  To: robh+dt, bjorn.andersson, agross, georgi.djakov
  Cc: vkoul, evgreen, daidavid1, linux-pm, devicetree, linux-kernel,
	linux-arm-msm

Add drivers to support scaling of the on-chip interconnects on QCS404-based
platforms. Also add the necessary device-tree nodes, so that the driver for
each NoC can probe and register as interconnect-provider.

v4:
- Move DT headers into the dt-bindings patch (Bjorn)
- Pick Bjorn's r-b on some patches.
- Return error if platform_device_register_data() fails (Bjorn)
- Use platform_set_drvdata() only in the child device. (Bjorn)
- Hide the smd-rpm proxy driver from config menu. (Bjorn)
- Add remove() function to zero out the rpm handle. (Bjorn)
- Move move the qcs404 driver patch later in the serie. (Bjorn)
- Insert the DT nodes after rng to keep the list sorted by address. (Bjorn)

v3: https://lore.kernel.org/lkml/20190611164157.24656-1-georgi.djakov@linaro.org/
- Drop the patch introducing the qcom,qos DT property.
- Add two new patches to create an interconnect proxy device. This device is
  part of the RPM hardware and handles the communication of the bus bandwidth
  requests.
- Add a DT reg property and move the interconnect nodes under the "soc" node.

v2: https://lore.kernel.org/lkml/20190415104357.5305-1-georgi.djakov@linaro.org/
- Use the clk_bulk API. (Bjorn)
- Move the port IDs into the provider file. (Bjorn)
- Use ARRAY_SIZE in the macro to automagically count the num_links. (Bjorn)
- Improve code readability. (Bjorn)
- Add patch [4/4] introducing a qcom,qos DT property to represent the link to
  the MMIO QoS registers HW block.

v1: https://lore.kernel.org/lkml/20190405035446.31886-1-georgi.djakov@linaro.org/

Bjorn Andersson (1):
  interconnect: qcom: Add QCS404 interconnect provider driver

Georgi Djakov (4):
  dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings
  soc: qcom: smd-rpm: Create RPM interconnect proxy child device
  interconnect: qcom: Add interconnect SMD over SMD driver
  arm64: dts: qcs404: Add interconnect provider DT nodes

 .../bindings/interconnect/qcom,qcs404.txt     |  46 ++
 arch/arm64/boot/dts/qcom/qcs404.dtsi          |  28 +
 drivers/interconnect/qcom/Kconfig             |  12 +
 drivers/interconnect/qcom/Makefile            |   4 +
 drivers/interconnect/qcom/qcs404.c            | 539 ++++++++++++++++++
 drivers/interconnect/qcom/smd-rpm.c           |  80 +++
 drivers/interconnect/qcom/smd-rpm.h           |  15 +
 drivers/soc/qcom/smd-rpm.c                    |  17 +-
 .../dt-bindings/interconnect/qcom,qcs404.h    |  88 +++
 9 files changed, 828 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
 create mode 100644 drivers/interconnect/qcom/qcs404.c
 create mode 100644 drivers/interconnect/qcom/smd-rpm.c
 create mode 100644 drivers/interconnect/qcom/smd-rpm.h
 create mode 100644 include/dt-bindings/interconnect/qcom,qcs404.h


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings
  2019-06-13 15:13 [PATCH v4 0/5] Add QCS404 interconnect provider driver Georgi Djakov
@ 2019-06-13 15:13 ` Georgi Djakov
  2019-06-25 15:00   ` Georgi Djakov
  2019-07-08 19:26   ` Bjorn Andersson
  2019-06-13 15:13 ` [PATCH v4 2/5] soc: qcom: smd-rpm: Create RPM interconnect proxy child device Georgi Djakov
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 12+ messages in thread
From: Georgi Djakov @ 2019-06-13 15:13 UTC (permalink / raw)
  To: robh+dt, bjorn.andersson, agross, georgi.djakov
  Cc: vkoul, evgreen, daidavid1, linux-pm, devicetree, linux-kernel,
	linux-arm-msm

The Qualcomm QCS404 platform has several buses that could be controlled
and tuned according to the bandwidth demand.

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---

v4:
- Add the DT header into this patch.
- Pick Bjorn's r-b.

v3:
- Add a reg property and move the interconnect nodes under the "soc" node.

v2:
- No changes.

 .../bindings/interconnect/qcom,qcs404.txt     | 46 ++++++++++
 .../dt-bindings/interconnect/qcom,qcs404.h    | 88 +++++++++++++++++++
 2 files changed, 134 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
 create mode 100644 include/dt-bindings/interconnect/qcom,qcs404.h

diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
new file mode 100644
index 000000000000..14a827268dda
--- /dev/null
+++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
@@ -0,0 +1,46 @@
+Qualcomm QCS404 Network-On-Chip interconnect driver binding
+-----------------------------------------------------------
+
+Required properties :
+- compatible : shall contain only one of the following:
+			"qcom,qcs404-bimc"
+			"qcom,qcs404-pcnoc"
+			"qcom,qcs404-snoc"
+- #interconnect-cells : should contain 1
+
+Optional properties :
+reg : specifies the physical base address and size of registers
+clocks : list of phandles and specifiers to all interconnect bus clocks
+clock-names : clock names should include both "bus_clk" and "bus_a_clk"
+
+Example:
+
+soc {
+	...
+	bimc: interconnect@400000 {
+		reg = <0x00400000 0x80000>;
+		compatible = "qcom,qcs404-bimc";
+		#interconnect-cells = <1>;
+		clock-names = "bus_clk", "bus_a_clk";
+		clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
+			<&rpmcc RPM_SMD_BIMC_A_CLK>;
+	};
+
+	pnoc: interconnect@500000 {
+		reg = <0x00500000 0x15080>;
+		compatible = "qcom,qcs404-pcnoc";
+		#interconnect-cells = <1>;
+		clock-names = "bus_clk", "bus_a_clk";
+		clocks = <&rpmcc RPM_SMD_PNOC_CLK>,
+			<&rpmcc RPM_SMD_PNOC_A_CLK>;
+	};
+
+	snoc: interconnect@580000 {
+		reg = <0x00580000 0x23080>;
+		compatible = "qcom,qcs404-snoc";
+		#interconnect-cells = <1>;
+		clock-names = "bus_clk", "bus_a_clk";
+		clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
+			<&rpmcc RPM_SMD_SNOC_A_CLK>;
+	};
+};
diff --git a/include/dt-bindings/interconnect/qcom,qcs404.h b/include/dt-bindings/interconnect/qcom,qcs404.h
new file mode 100644
index 000000000000..960f6e39c5f2
--- /dev/null
+++ b/include/dt-bindings/interconnect/qcom,qcs404.h
@@ -0,0 +1,88 @@
+/* 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_QCS404_H
+#define __DT_BINDINGS_INTERCONNECT_QCOM_QCS404_H
+
+#define MASTER_AMPSS_M0			0
+#define MASTER_OXILI			1
+#define MASTER_MDP_PORT0		2
+#define MASTER_SNOC_BIMC_1		3
+#define MASTER_TCU_0			4
+#define SLAVE_EBI_CH0			5
+#define SLAVE_BIMC_SNOC			6
+
+#define MASTER_SPDM			0
+#define MASTER_BLSP_1			1
+#define MASTER_BLSP_2			2
+#define MASTER_XI_USB_HS1		3
+#define MASTER_CRYPT0			4
+#define MASTER_SDCC_1			5
+#define MASTER_SDCC_2			6
+#define MASTER_SNOC_PCNOC		7
+#define MASTER_QPIC			8
+#define PCNOC_INT_0			9
+#define PCNOC_INT_2			10
+#define PCNOC_INT_3			11
+#define PCNOC_S_0			12
+#define PCNOC_S_1			13
+#define PCNOC_S_2			14
+#define PCNOC_S_3			15
+#define PCNOC_S_4			16
+#define PCNOC_S_6			17
+#define PCNOC_S_7			18
+#define PCNOC_S_8			19
+#define PCNOC_S_9			20
+#define PCNOC_S_10			21
+#define PCNOC_S_11			22
+#define SLAVE_SPDM			23
+#define SLAVE_PDM			24
+#define SLAVE_PRNG			25
+#define SLAVE_TCSR			26
+#define SLAVE_SNOC_CFG			27
+#define SLAVE_MESSAGE_RAM		28
+#define SLAVE_DISP_SS_CFG		29
+#define SLAVE_GPU_CFG			30
+#define SLAVE_BLSP_1			31
+#define SLAVE_BLSP_2			32
+#define SLAVE_TLMM_NORTH		33
+#define SLAVE_PCIE			34
+#define SLAVE_ETHERNET			35
+#define SLAVE_TLMM_EAST			36
+#define SLAVE_TCU			37
+#define SLAVE_PMIC_ARB			38
+#define SLAVE_SDCC_1			39
+#define SLAVE_SDCC_2			40
+#define SLAVE_TLMM_SOUTH		41
+#define SLAVE_USB_HS			42
+#define SLAVE_USB3			43
+#define SLAVE_CRYPTO_0_CFG		44
+#define SLAVE_PCNOC_SNOC		45
+
+#define MASTER_QDSS_BAM			0
+#define MASTER_BIMC_SNOC		1
+#define MASTER_PCNOC_SNOC		2
+#define MASTER_QDSS_ETR			3
+#define MASTER_EMAC			4
+#define MASTER_PCIE			5
+#define MASTER_USB3			6
+#define QDSS_INT			7
+#define SNOC_INT_0			8
+#define SNOC_INT_1			9
+#define SNOC_INT_2			10
+#define SLAVE_KPSS_AHB			11
+#define SLAVE_WCSS			12
+#define SLAVE_SNOC_BIMC_1		13
+#define SLAVE_IMEM			14
+#define SLAVE_SNOC_PCNOC		15
+#define SLAVE_QDSS_STM			16
+#define SLAVE_CATS_0			17
+#define SLAVE_CATS_1			18
+#define SLAVE_LPASS			19
+
+#endif

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 2/5] soc: qcom: smd-rpm: Create RPM interconnect proxy child device
  2019-06-13 15:13 [PATCH v4 0/5] Add QCS404 interconnect provider driver Georgi Djakov
  2019-06-13 15:13 ` [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings Georgi Djakov
@ 2019-06-13 15:13 ` Georgi Djakov
  2019-06-13 15:40   ` Bjorn Andersson
  2019-06-13 15:13 ` [PATCH v4 3/5] interconnect: qcom: Add interconnect SMD over SMD driver Georgi Djakov
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Georgi Djakov @ 2019-06-13 15:13 UTC (permalink / raw)
  To: robh+dt, bjorn.andersson, agross, georgi.djakov
  Cc: vkoul, evgreen, daidavid1, linux-pm, devicetree, linux-kernel,
	linux-arm-msm

Register a platform device to handle the communication of bus bandwidth
requests with the remote processor. The interconnect proxy device is part
of this remote processor (RPM) hardware. Let's create a icc-smd-rpm proxy
child device to represent the bus throughput functionality that is provided
by the RPM.

Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---

v4:
- Return error if platform_device_register_data() fails
- Remove platform_set_drvdata() on the child device.

v3:
- New patch.

 drivers/soc/qcom/smd-rpm.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c
index fa9dd12b5e39..34cdd638a6c1 100644
--- a/drivers/soc/qcom/smd-rpm.c
+++ b/drivers/soc/qcom/smd-rpm.c
@@ -19,12 +19,14 @@
 /**
  * struct qcom_smd_rpm - state of the rpm device driver
  * @rpm_channel:	reference to the smd channel
+ * @icc:		interconnect proxy device
  * @ack:		completion for acks
  * @lock:		mutual exclusion around the send/complete pair
  * @ack_status:		result of the rpm request
  */
 struct qcom_smd_rpm {
 	struct rpmsg_endpoint *rpm_channel;
+	struct platform_device *icc;
 	struct device *dev;
 
 	struct completion ack;
@@ -193,6 +195,7 @@ static int qcom_smd_rpm_callback(struct rpmsg_device *rpdev,
 static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev)
 {
 	struct qcom_smd_rpm *rpm;
+	int ret;
 
 	rpm = devm_kzalloc(&rpdev->dev, sizeof(*rpm), GFP_KERNEL);
 	if (!rpm)
@@ -205,11 +208,23 @@ static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev)
 	rpm->rpm_channel = rpdev->ept;
 	dev_set_drvdata(&rpdev->dev, rpm);
 
-	return of_platform_populate(rpdev->dev.of_node, NULL, NULL, &rpdev->dev);
+	rpm->icc = platform_device_register_data(&rpdev->dev, "icc_smd_rpm", -1,
+						 NULL, 0);
+	if (IS_ERR(rpm->icc))
+		return PTR_ERR(rpm->icc);
+
+	ret = of_platform_populate(rpdev->dev.of_node, NULL, NULL, &rpdev->dev);
+	if (ret)
+		platform_device_unregister(rpm->icc);
+
+	return ret;
 }
 
 static void qcom_smd_rpm_remove(struct rpmsg_device *rpdev)
 {
+	struct qcom_smd_rpm *rpm = dev_get_drvdata(&rpdev->dev);
+
+	platform_device_unregister(rpm->icc);
 	of_platform_depopulate(&rpdev->dev);
 }
 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 3/5] interconnect: qcom: Add interconnect SMD over SMD driver
  2019-06-13 15:13 [PATCH v4 0/5] Add QCS404 interconnect provider driver Georgi Djakov
  2019-06-13 15:13 ` [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings Georgi Djakov
  2019-06-13 15:13 ` [PATCH v4 2/5] soc: qcom: smd-rpm: Create RPM interconnect proxy child device Georgi Djakov
@ 2019-06-13 15:13 ` Georgi Djakov
  2019-06-13 15:42   ` Bjorn Andersson
  2019-06-13 15:13 ` [PATCH v4 4/5] interconnect: qcom: Add QCS404 interconnect provider driver Georgi Djakov
  2019-06-13 15:13 ` [PATCH v4 5/5] arm64: dts: qcs404: Add interconnect provider DT nodes Georgi Djakov
  4 siblings, 1 reply; 12+ messages in thread
From: Georgi Djakov @ 2019-06-13 15:13 UTC (permalink / raw)
  To: robh+dt, bjorn.andersson, agross, georgi.djakov
  Cc: vkoul, evgreen, daidavid1, linux-pm, devicetree, linux-kernel,
	linux-arm-msm

On some Qualcomm SoCs, there is a remote processor, which controls some of
the Network-On-Chip interconnect resources. Other CPUs express their needs
by communicating with this processor. Add a driver to handle communication
with this remote processor.

Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---

v4:
- Hide the driver from config menu. It will be selected by other driver.
- Add remove() function to zero out the rpm handle.

v3:
- New patch.

 drivers/interconnect/qcom/Kconfig   |  3 ++
 drivers/interconnect/qcom/Makefile  |  2 +
 drivers/interconnect/qcom/smd-rpm.c | 80 +++++++++++++++++++++++++++++
 drivers/interconnect/qcom/smd-rpm.h | 15 ++++++
 4 files changed, 100 insertions(+)
 create mode 100644 drivers/interconnect/qcom/smd-rpm.c
 create mode 100644 drivers/interconnect/qcom/smd-rpm.h

diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig
index d5e70ebc2410..03fd67173494 100644
--- a/drivers/interconnect/qcom/Kconfig
+++ b/drivers/interconnect/qcom/Kconfig
@@ -12,3 +12,6 @@ config INTERCONNECT_QCOM_SDM845
 	help
 	  This is a driver for the Qualcomm Network-on-Chip on sdm845-based
 	  platforms.
+
+config INTERCONNECT_QCOM_SMD_RPM
+	tristate
diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile
index 1c1cea690f92..a600cf6cc272 100644
--- a/drivers/interconnect/qcom/Makefile
+++ b/drivers/interconnect/qcom/Makefile
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 qnoc-sdm845-objs			:= sdm845.o
+icc-smd-rpm-objs			:= smd-rpm.o
 
 obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o
+obj-$(CONFIG_INTERCONNECT_QCOM_SMD_RPM) += icc-smd-rpm.o
diff --git a/drivers/interconnect/qcom/smd-rpm.c b/drivers/interconnect/qcom/smd-rpm.c
new file mode 100644
index 000000000000..0a8c9547bd29
--- /dev/null
+++ b/drivers/interconnect/qcom/smd-rpm.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RPM over SMD communication wrapper for interconnects
+ *
+ * Copyright (C) 2019 Linaro Ltd
+ * Author: Georgi Djakov <georgi.djakov@linaro.org>
+ */
+
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/soc/qcom/smd-rpm.h>
+
+#include "smd-rpm.h"
+
+#define RPM_KEY_BW		0x00007762
+
+static struct qcom_smd_rpm *icc_smd_rpm;
+
+struct icc_rpm_smd_req {
+	__le32 key;
+	__le32 nbytes;
+	__le32 value;
+};
+
+bool qcom_icc_rpm_smd_available(void)
+{
+	if (!icc_smd_rpm)
+		return false;
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(qcom_icc_rpm_smd_available);
+
+int qcom_icc_rpm_smd_send(int ctx, int rsc_type, int id, u32 val)
+{
+	struct icc_rpm_smd_req req = {
+		.key = cpu_to_le32(RPM_KEY_BW),
+		.nbytes = cpu_to_le32(sizeof(u32)),
+		.value = cpu_to_le32(val),
+	};
+
+	return qcom_rpm_smd_write(icc_smd_rpm, ctx, rsc_type, id, &req,
+				  sizeof(req));
+}
+EXPORT_SYMBOL_GPL(qcom_icc_rpm_smd_send);
+
+static int qcom_icc_rpm_smd_remove(struct platform_device *pdev)
+{
+	icc_smd_rpm = NULL;
+
+	return 0;
+}
+
+static int qcom_icc_rpm_smd_probe(struct platform_device *pdev)
+{
+	icc_smd_rpm = dev_get_drvdata(pdev->dev.parent);
+
+	if (!icc_smd_rpm) {
+		dev_err(&pdev->dev, "unable to retrieve handle to RPM\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static struct platform_driver qcom_interconnect_rpm_smd_driver = {
+	.driver = {
+		.name		= "icc_smd_rpm",
+	},
+	.probe = qcom_icc_rpm_smd_probe,
+	.remove = qcom_icc_rpm_smd_remove,
+};
+module_platform_driver(qcom_interconnect_rpm_smd_driver);
+MODULE_AUTHOR("Georgi Djakov <georgi.djakov@linaro.org>");
+MODULE_DESCRIPTION("Qualcomm SMD RPM interconnect proxy driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:icc_smd_rpm");
diff --git a/drivers/interconnect/qcom/smd-rpm.h b/drivers/interconnect/qcom/smd-rpm.h
new file mode 100644
index 000000000000..ca9d0327b8ac
--- /dev/null
+++ b/drivers/interconnect/qcom/smd-rpm.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019, Linaro Ltd.
+ * Author: Georgi Djakov <georgi.djakov@linaro.org>
+ */
+
+#ifndef __DRIVERS_INTERCONNECT_QCOM_SMD_RPM_H
+#define __DRIVERS_INTERCONNECT_QCOM_SMD_RPM_H
+
+#include <linux/soc/qcom/smd-rpm.h>
+
+bool qcom_icc_rpm_smd_available(void);
+int qcom_icc_rpm_smd_send(int ctx, int rsc_type, int id, u32 val);
+
+#endif

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 4/5] interconnect: qcom: Add QCS404 interconnect provider driver
  2019-06-13 15:13 [PATCH v4 0/5] Add QCS404 interconnect provider driver Georgi Djakov
                   ` (2 preceding siblings ...)
  2019-06-13 15:13 ` [PATCH v4 3/5] interconnect: qcom: Add interconnect SMD over SMD driver Georgi Djakov
@ 2019-06-13 15:13 ` Georgi Djakov
  2019-06-13 15:47   ` Bjorn Andersson
  2019-06-13 15:13 ` [PATCH v4 5/5] arm64: dts: qcs404: Add interconnect provider DT nodes Georgi Djakov
  4 siblings, 1 reply; 12+ messages in thread
From: Georgi Djakov @ 2019-06-13 15:13 UTC (permalink / raw)
  To: robh+dt, bjorn.andersson, agross, georgi.djakov
  Cc: vkoul, evgreen, daidavid1, linux-pm, devicetree, linux-kernel,
	linux-arm-msm

From: Bjorn Andersson <bjorn.andersson@linaro.org>

Add driver for the interconnect buses found in Qualcomm QCS404-based
platforms. The topology consists of three NoCs that are controlled by
a remote processor. This remote processor collects the aggregated
bandwidth for each master-slave pairs.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---

v4:
- Select INTERCONNECT_QCOM_SMD_RPM from this driver.
- Move the DT header to the dt-bindings patch.
- Move this patch later in the series.

v3:
- Convert the #defines into enum. (Bjorn)
- Move the rpm-smd part into a separate interconnect proxy driver.

v2:
- Use the clk_bulk API. (Bjorn)
- Move the port IDs into the provider file. (Bjorn)
- Use ARRAY_SIZE in the macro to automagically count the num_links. (Bjorn)
- Improve code readability. (Bjorn)


 drivers/interconnect/qcom/Kconfig  |   9 +
 drivers/interconnect/qcom/Makefile |   2 +
 drivers/interconnect/qcom/qcs404.c | 539 +++++++++++++++++++++++++++++
 3 files changed, 550 insertions(+)
 create mode 100644 drivers/interconnect/qcom/qcs404.c

diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig
index 03fd67173494..339e8f10d4f3 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_QCS404
+	tristate "Qualcomm QCS404 interconnect driver"
+	depends on INTERCONNECT_QCOM
+	depends on QCOM_SMD_RPM || COMPILE_TEST
+	select INTERCONNECT_QCOM_SMD_RPM
+	help
+	  This is a driver for the Qualcomm Network-on-Chip on qcs404-based
+	  platforms.
+
 config INTERCONNECT_QCOM_SDM845
 	tristate "Qualcomm SDM845 interconnect driver"
 	depends on INTERCONNECT_QCOM
diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile
index a600cf6cc272..67dafb783dec 100644
--- a/drivers/interconnect/qcom/Makefile
+++ b/drivers/interconnect/qcom/Makefile
@@ -1,7 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 
+qnoc-qcs404-objs			:= qcs404.o
 qnoc-sdm845-objs			:= sdm845.o
 icc-smd-rpm-objs			:= smd-rpm.o
 
+obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
 obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o
 obj-$(CONFIG_INTERCONNECT_QCOM_SMD_RPM) += icc-smd-rpm.o
diff --git a/drivers/interconnect/qcom/qcs404.c b/drivers/interconnect/qcom/qcs404.c
new file mode 100644
index 000000000000..99be0928e2ad
--- /dev/null
+++ b/drivers/interconnect/qcom/qcs404.c
@@ -0,0 +1,539 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Linaro Ltd
+ */
+
+#include <dt-bindings/interconnect/qcom,qcs404.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 <linux/slab.h>
+
+#include "smd-rpm.h"
+
+#define RPM_BUS_MASTER_REQ	0x73616d62
+#define RPM_BUS_SLAVE_REQ	0x766c7362
+
+enum {
+	QCS404_MASTER_AMPSS_M0 = 1,
+	QCS404_MASTER_GRAPHICS_3D,
+	QCS404_MASTER_MDP_PORT0,
+	QCS404_SNOC_BIMC_1_MAS,
+	QCS404_MASTER_TCU_0,
+	QCS404_MASTER_SPDM,
+	QCS404_MASTER_BLSP_1,
+	QCS404_MASTER_BLSP_2,
+	QCS404_MASTER_XM_USB_HS1,
+	QCS404_MASTER_CRYPTO_CORE0,
+	QCS404_MASTER_SDCC_1,
+	QCS404_MASTER_SDCC_2,
+	QCS404_SNOC_PNOC_MAS,
+	QCS404_MASTER_QPIC,
+	QCS404_MASTER_QDSS_BAM,
+	QCS404_BIMC_SNOC_MAS,
+	QCS404_PNOC_SNOC_MAS,
+	QCS404_MASTER_QDSS_ETR,
+	QCS404_MASTER_EMAC,
+	QCS404_MASTER_PCIE,
+	QCS404_MASTER_USB3,
+	QCS404_PNOC_INT_0,
+	QCS404_PNOC_INT_2,
+	QCS404_PNOC_INT_3,
+	QCS404_PNOC_SLV_0,
+	QCS404_PNOC_SLV_1,
+	QCS404_PNOC_SLV_2,
+	QCS404_PNOC_SLV_3,
+	QCS404_PNOC_SLV_4,
+	QCS404_PNOC_SLV_6,
+	QCS404_PNOC_SLV_7,
+	QCS404_PNOC_SLV_8,
+	QCS404_PNOC_SLV_9,
+	QCS404_PNOC_SLV_10,
+	QCS404_PNOC_SLV_11,
+	QCS404_SNOC_QDSS_INT,
+	QCS404_SNOC_INT_0,
+	QCS404_SNOC_INT_1,
+	QCS404_SNOC_INT_2,
+	QCS404_SLAVE_EBI_CH0,
+	QCS404_BIMC_SNOC_SLV,
+	QCS404_SLAVE_SPDM_WRAPPER,
+	QCS404_SLAVE_PDM,
+	QCS404_SLAVE_PRNG,
+	QCS404_SLAVE_TCSR,
+	QCS404_SLAVE_SNOC_CFG,
+	QCS404_SLAVE_MESSAGE_RAM,
+	QCS404_SLAVE_DISPLAY_CFG,
+	QCS404_SLAVE_GRAPHICS_3D_CFG,
+	QCS404_SLAVE_BLSP_1,
+	QCS404_SLAVE_TLMM_NORTH,
+	QCS404_SLAVE_PCIE_1,
+	QCS404_SLAVE_EMAC_CFG,
+	QCS404_SLAVE_BLSP_2,
+	QCS404_SLAVE_TLMM_EAST,
+	QCS404_SLAVE_TCU,
+	QCS404_SLAVE_PMIC_ARB,
+	QCS404_SLAVE_SDCC_1,
+	QCS404_SLAVE_SDCC_2,
+	QCS404_SLAVE_TLMM_SOUTH,
+	QCS404_SLAVE_USB_HS,
+	QCS404_SLAVE_USB3,
+	QCS404_SLAVE_CRYPTO_0_CFG,
+	QCS404_PNOC_SNOC_SLV,
+	QCS404_SLAVE_APPSS,
+	QCS404_SLAVE_WCSS,
+	QCS404_SNOC_BIMC_1_SLV,
+	QCS404_SLAVE_OCIMEM,
+	QCS404_SNOC_PNOC_SLV,
+	QCS404_SLAVE_QDSS_STM,
+	QCS404_SLAVE_CATS_128,
+	QCS404_SLAVE_OCMEM_64,
+	QCS404_SLAVE_LPASS,
+};
+
+#define to_qcom_provider(_provider) \
+	container_of(_provider, struct qcom_icc_provider, provider)
+
+static const struct clk_bulk_data bus_clocks[] = {
+	{ .id = "bus_clk" },
+	{ .id = "bus_a_clk" },
+};
+
+/**
+ * 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 QCS404_MAX_LINKS	12
+
+/**
+ * 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[QCS404_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(mas_apps_proc, QCS404_MASTER_AMPSS_M0, 8, 0, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV);
+DEFINE_QNODE(mas_oxili, QCS404_MASTER_GRAPHICS_3D, 8, 6, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV);
+DEFINE_QNODE(mas_mdp, QCS404_MASTER_MDP_PORT0, 8, 8, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV);
+DEFINE_QNODE(mas_snoc_bimc_1, QCS404_SNOC_BIMC_1_MAS, 8, 76, -1, QCS404_SLAVE_EBI_CH0);
+DEFINE_QNODE(mas_tcu_0, QCS404_MASTER_TCU_0, 8, -1, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV);
+DEFINE_QNODE(mas_spdm, QCS404_MASTER_SPDM, 4, -1, -1, QCS404_PNOC_INT_3);
+DEFINE_QNODE(mas_blsp_1, QCS404_MASTER_BLSP_1, 4, 41, -1, QCS404_PNOC_INT_3);
+DEFINE_QNODE(mas_blsp_2, QCS404_MASTER_BLSP_2, 4, 39, -1, QCS404_PNOC_INT_3);
+DEFINE_QNODE(mas_xi_usb_hs1, QCS404_MASTER_XM_USB_HS1, 8, 138, -1, QCS404_PNOC_INT_0);
+DEFINE_QNODE(mas_crypto, QCS404_MASTER_CRYPTO_CORE0, 8, 23, -1, QCS404_PNOC_SNOC_SLV, QCS404_PNOC_INT_2);
+DEFINE_QNODE(mas_sdcc_1, QCS404_MASTER_SDCC_1, 8, 33, -1, QCS404_PNOC_INT_0);
+DEFINE_QNODE(mas_sdcc_2, QCS404_MASTER_SDCC_2, 8, 35, -1, QCS404_PNOC_INT_0);
+DEFINE_QNODE(mas_snoc_pcnoc, QCS404_SNOC_PNOC_MAS, 8, 77, -1, QCS404_PNOC_INT_2);
+DEFINE_QNODE(mas_qpic, QCS404_MASTER_QPIC, 4, -1, -1, QCS404_PNOC_INT_0);
+DEFINE_QNODE(mas_qdss_bam, QCS404_MASTER_QDSS_BAM, 4, -1, -1, QCS404_SNOC_QDSS_INT);
+DEFINE_QNODE(mas_bimc_snoc, QCS404_BIMC_SNOC_MAS, 8, 21, -1, QCS404_SLAVE_OCMEM_64, QCS404_SLAVE_CATS_128, QCS404_SNOC_INT_0, QCS404_SNOC_INT_1);
+DEFINE_QNODE(mas_pcnoc_snoc, QCS404_PNOC_SNOC_MAS, 8, 29, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_2, QCS404_SNOC_INT_0);
+DEFINE_QNODE(mas_qdss_etr, QCS404_MASTER_QDSS_ETR, 8, -1, -1, QCS404_SNOC_QDSS_INT);
+DEFINE_QNODE(mas_emac, QCS404_MASTER_EMAC, 8, -1, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_1);
+DEFINE_QNODE(mas_pcie, QCS404_MASTER_PCIE, 8, -1, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_1);
+DEFINE_QNODE(mas_usb3, QCS404_MASTER_USB3, 8, -1, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_1);
+DEFINE_QNODE(pcnoc_int_0, QCS404_PNOC_INT_0, 8, 85, 114, QCS404_PNOC_SNOC_SLV, QCS404_PNOC_INT_2);
+DEFINE_QNODE(pcnoc_int_2, QCS404_PNOC_INT_2, 8, 124, 184, QCS404_PNOC_SLV_10, QCS404_SLAVE_TCU, QCS404_PNOC_SLV_11, QCS404_PNOC_SLV_2, QCS404_PNOC_SLV_3, QCS404_PNOC_SLV_0, QCS404_PNOC_SLV_1, QCS404_PNOC_SLV_6, QCS404_PNOC_SLV_7, QCS404_PNOC_SLV_4, QCS404_PNOC_SLV_8, QCS404_PNOC_SLV_9);
+DEFINE_QNODE(pcnoc_int_3, QCS404_PNOC_INT_3, 8, 125, 185, QCS404_PNOC_SNOC_SLV);
+DEFINE_QNODE(pcnoc_s_0, QCS404_PNOC_SLV_0, 4, 89, 118, QCS404_SLAVE_PRNG, QCS404_SLAVE_SPDM_WRAPPER, QCS404_SLAVE_PDM);
+DEFINE_QNODE(pcnoc_s_1, QCS404_PNOC_SLV_1, 4, 90, 119, QCS404_SLAVE_TCSR);
+DEFINE_QNODE(pcnoc_s_2, QCS404_PNOC_SLV_2, 4, -1, -1, QCS404_SLAVE_GRAPHICS_3D_CFG);
+DEFINE_QNODE(pcnoc_s_3, QCS404_PNOC_SLV_3, 4, 92, 121, QCS404_SLAVE_MESSAGE_RAM);
+DEFINE_QNODE(pcnoc_s_4, QCS404_PNOC_SLV_4, 4, 93, 122, QCS404_SLAVE_SNOC_CFG);
+DEFINE_QNODE(pcnoc_s_6, QCS404_PNOC_SLV_6, 4, 94, 123, QCS404_SLAVE_BLSP_1, QCS404_SLAVE_TLMM_NORTH, QCS404_SLAVE_EMAC_CFG);
+DEFINE_QNODE(pcnoc_s_7, QCS404_PNOC_SLV_7, 4, 95, 124, QCS404_SLAVE_TLMM_SOUTH, QCS404_SLAVE_DISPLAY_CFG, QCS404_SLAVE_SDCC_1, QCS404_SLAVE_PCIE_1, QCS404_SLAVE_SDCC_2);
+DEFINE_QNODE(pcnoc_s_8, QCS404_PNOC_SLV_8, 4, 96, 125, QCS404_SLAVE_CRYPTO_0_CFG);
+DEFINE_QNODE(pcnoc_s_9, QCS404_PNOC_SLV_9, 4, 97, 126, QCS404_SLAVE_BLSP_2, QCS404_SLAVE_TLMM_EAST, QCS404_SLAVE_PMIC_ARB);
+DEFINE_QNODE(pcnoc_s_10, QCS404_PNOC_SLV_10, 4, 157, -1, QCS404_SLAVE_USB_HS);
+DEFINE_QNODE(pcnoc_s_11, QCS404_PNOC_SLV_11, 4, 158, 246, QCS404_SLAVE_USB3);
+DEFINE_QNODE(qdss_int, QCS404_SNOC_QDSS_INT, 8, -1, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_1);
+DEFINE_QNODE(snoc_int_0, QCS404_SNOC_INT_0, 8, 99, 130, QCS404_SLAVE_LPASS, QCS404_SLAVE_APPSS, QCS404_SLAVE_WCSS);
+DEFINE_QNODE(snoc_int_1, QCS404_SNOC_INT_1, 8, 100, 131, QCS404_SNOC_PNOC_SLV, QCS404_SNOC_INT_2);
+DEFINE_QNODE(snoc_int_2, QCS404_SNOC_INT_2, 8, 134, 197, QCS404_SLAVE_QDSS_STM, QCS404_SLAVE_OCIMEM);
+DEFINE_QNODE(slv_ebi, QCS404_SLAVE_EBI_CH0, 8, -1, 0, 0);
+DEFINE_QNODE(slv_bimc_snoc, QCS404_BIMC_SNOC_SLV, 8, -1, 2, QCS404_BIMC_SNOC_MAS);
+DEFINE_QNODE(slv_spdm, QCS404_SLAVE_SPDM_WRAPPER, 4, -1, -1, 0);
+DEFINE_QNODE(slv_pdm, QCS404_SLAVE_PDM, 4, -1, 41, 0);
+DEFINE_QNODE(slv_prng, QCS404_SLAVE_PRNG, 4, -1, 44, 0);
+DEFINE_QNODE(slv_tcsr, QCS404_SLAVE_TCSR, 4, -1, 50, 0);
+DEFINE_QNODE(slv_snoc_cfg, QCS404_SLAVE_SNOC_CFG, 4, -1, 70, 0);
+DEFINE_QNODE(slv_message_ram, QCS404_SLAVE_MESSAGE_RAM, 4, -1, 55, 0);
+DEFINE_QNODE(slv_disp_ss_cfg, QCS404_SLAVE_DISPLAY_CFG, 4, -1, -1, 0);
+DEFINE_QNODE(slv_gpu_cfg, QCS404_SLAVE_GRAPHICS_3D_CFG, 4, -1, -1, 0);
+DEFINE_QNODE(slv_blsp_1, QCS404_SLAVE_BLSP_1, 4, -1, 39, 0);
+DEFINE_QNODE(slv_tlmm_north, QCS404_SLAVE_TLMM_NORTH, 4, -1, 214, 0);
+DEFINE_QNODE(slv_pcie, QCS404_SLAVE_PCIE_1, 4, -1, -1, 0);
+DEFINE_QNODE(slv_ethernet, QCS404_SLAVE_EMAC_CFG, 4, -1, -1, 0);
+DEFINE_QNODE(slv_blsp_2, QCS404_SLAVE_BLSP_2, 4, -1, 37, 0);
+DEFINE_QNODE(slv_tlmm_east, QCS404_SLAVE_TLMM_EAST, 4, -1, 213, 0);
+DEFINE_QNODE(slv_tcu, QCS404_SLAVE_TCU, 8, -1, -1, 0);
+DEFINE_QNODE(slv_pmic_arb, QCS404_SLAVE_PMIC_ARB, 4, -1, 59, 0);
+DEFINE_QNODE(slv_sdcc_1, QCS404_SLAVE_SDCC_1, 4, -1, 31, 0);
+DEFINE_QNODE(slv_sdcc_2, QCS404_SLAVE_SDCC_2, 4, -1, 33, 0);
+DEFINE_QNODE(slv_tlmm_south, QCS404_SLAVE_TLMM_SOUTH, 4, -1, -1, 0);
+DEFINE_QNODE(slv_usb_hs, QCS404_SLAVE_USB_HS, 4, -1, 40, 0);
+DEFINE_QNODE(slv_usb3, QCS404_SLAVE_USB3, 4, -1, 22, 0);
+DEFINE_QNODE(slv_crypto_0_cfg, QCS404_SLAVE_CRYPTO_0_CFG, 4, -1, 52, 0);
+DEFINE_QNODE(slv_pcnoc_snoc, QCS404_PNOC_SNOC_SLV, 8, -1, 45, QCS404_PNOC_SNOC_MAS);
+DEFINE_QNODE(slv_kpss_ahb, QCS404_SLAVE_APPSS, 4, -1, -1, 0);
+DEFINE_QNODE(slv_wcss, QCS404_SLAVE_WCSS, 4, -1, 23, 0);
+DEFINE_QNODE(slv_snoc_bimc_1, QCS404_SNOC_BIMC_1_SLV, 8, -1, 104, QCS404_SNOC_BIMC_1_MAS);
+DEFINE_QNODE(slv_imem, QCS404_SLAVE_OCIMEM, 8, -1, 26, 0);
+DEFINE_QNODE(slv_snoc_pcnoc, QCS404_SNOC_PNOC_SLV, 8, -1, 28, QCS404_SNOC_PNOC_MAS);
+DEFINE_QNODE(slv_qdss_stm, QCS404_SLAVE_QDSS_STM, 4, -1, 30, 0);
+DEFINE_QNODE(slv_cats_0, QCS404_SLAVE_CATS_128, 16, -1, -1, 0);
+DEFINE_QNODE(slv_cats_1, QCS404_SLAVE_OCMEM_64, 8, -1, -1, 0);
+DEFINE_QNODE(slv_lpass, QCS404_SLAVE_LPASS, 4, -1, -1, 0);
+
+static struct qcom_icc_node *qcs404_bimc_nodes[] = {
+	[MASTER_AMPSS_M0] = &mas_apps_proc,
+	[MASTER_OXILI] = &mas_oxili,
+	[MASTER_MDP_PORT0] = &mas_mdp,
+	[MASTER_SNOC_BIMC_1] = &mas_snoc_bimc_1,
+	[MASTER_TCU_0] = &mas_tcu_0,
+	[SLAVE_EBI_CH0] = &slv_ebi,
+	[SLAVE_BIMC_SNOC] = &slv_bimc_snoc,
+};
+
+static struct qcom_icc_desc qcs404_bimc = {
+	.nodes = qcs404_bimc_nodes,
+	.num_nodes = ARRAY_SIZE(qcs404_bimc_nodes),
+};
+
+static struct qcom_icc_node *qcs404_pcnoc_nodes[] = {
+	[MASTER_SPDM] = &mas_spdm,
+	[MASTER_BLSP_1] = &mas_blsp_1,
+	[MASTER_BLSP_2] = &mas_blsp_2,
+	[MASTER_XI_USB_HS1] = &mas_xi_usb_hs1,
+	[MASTER_CRYPT0] = &mas_crypto,
+	[MASTER_SDCC_1] = &mas_sdcc_1,
+	[MASTER_SDCC_2] = &mas_sdcc_2,
+	[MASTER_SNOC_PCNOC] = &mas_snoc_pcnoc,
+	[MASTER_QPIC] = &mas_qpic,
+	[PCNOC_INT_0] = &pcnoc_int_0,
+	[PCNOC_INT_2] = &pcnoc_int_2,
+	[PCNOC_INT_3] = &pcnoc_int_3,
+	[PCNOC_S_0] = &pcnoc_s_0,
+	[PCNOC_S_1] = &pcnoc_s_1,
+	[PCNOC_S_2] = &pcnoc_s_2,
+	[PCNOC_S_3] = &pcnoc_s_3,
+	[PCNOC_S_4] = &pcnoc_s_4,
+	[PCNOC_S_6] = &pcnoc_s_6,
+	[PCNOC_S_7] = &pcnoc_s_7,
+	[PCNOC_S_8] = &pcnoc_s_8,
+	[PCNOC_S_9] = &pcnoc_s_9,
+	[PCNOC_S_10] = &pcnoc_s_10,
+	[PCNOC_S_11] = &pcnoc_s_11,
+	[SLAVE_SPDM] = &slv_spdm,
+	[SLAVE_PDM] = &slv_pdm,
+	[SLAVE_PRNG] = &slv_prng,
+	[SLAVE_TCSR] = &slv_tcsr,
+	[SLAVE_SNOC_CFG] = &slv_snoc_cfg,
+	[SLAVE_MESSAGE_RAM] = &slv_message_ram,
+	[SLAVE_DISP_SS_CFG] = &slv_disp_ss_cfg,
+	[SLAVE_GPU_CFG] = &slv_gpu_cfg,
+	[SLAVE_BLSP_1] = &slv_blsp_1,
+	[SLAVE_BLSP_2] = &slv_blsp_2,
+	[SLAVE_TLMM_NORTH] = &slv_tlmm_north,
+	[SLAVE_PCIE] = &slv_pcie,
+	[SLAVE_ETHERNET] = &slv_ethernet,
+	[SLAVE_TLMM_EAST] = &slv_tlmm_east,
+	[SLAVE_TCU] = &slv_tcu,
+	[SLAVE_PMIC_ARB] = &slv_pmic_arb,
+	[SLAVE_SDCC_1] = &slv_sdcc_1,
+	[SLAVE_SDCC_2] = &slv_sdcc_2,
+	[SLAVE_TLMM_SOUTH] = &slv_tlmm_south,
+	[SLAVE_USB_HS] = &slv_usb_hs,
+	[SLAVE_USB3] = &slv_usb3,
+	[SLAVE_CRYPTO_0_CFG] = &slv_crypto_0_cfg,
+	[SLAVE_PCNOC_SNOC] = &slv_pcnoc_snoc,
+};
+
+static struct qcom_icc_desc qcs404_pcnoc = {
+	.nodes = qcs404_pcnoc_nodes,
+	.num_nodes = ARRAY_SIZE(qcs404_pcnoc_nodes),
+};
+
+static struct qcom_icc_node *qcs404_snoc_nodes[] = {
+	[MASTER_QDSS_BAM] = &mas_qdss_bam,
+	[MASTER_BIMC_SNOC] = &mas_bimc_snoc,
+	[MASTER_PCNOC_SNOC] = &mas_pcnoc_snoc,
+	[MASTER_QDSS_ETR] = &mas_qdss_etr,
+	[MASTER_EMAC] = &mas_emac,
+	[MASTER_PCIE] = &mas_pcie,
+	[MASTER_USB3] = &mas_usb3,
+	[QDSS_INT] = &qdss_int,
+	[SNOC_INT_0] = &snoc_int_0,
+	[SNOC_INT_1] = &snoc_int_1,
+	[SNOC_INT_2] = &snoc_int_2,
+	[SLAVE_KPSS_AHB] = &slv_kpss_ahb,
+	[SLAVE_WCSS] = &slv_wcss,
+	[SLAVE_SNOC_BIMC_1] = &slv_snoc_bimc_1,
+	[SLAVE_IMEM] = &slv_imem,
+	[SLAVE_SNOC_PCNOC] = &slv_snoc_pcnoc,
+	[SLAVE_QDSS_STM] = &slv_qdss_stm,
+	[SLAVE_CATS_0] = &slv_cats_0,
+	[SLAVE_CATS_1] = &slv_cats_1,
+	[SLAVE_LPASS] = &slv_lpass,
+};
+
+static struct qcom_icc_desc qcs404_snoc = {
+	.nodes = qcs404_snoc_nodes,
+	.num_nodes = ARRAY_SIZE(qcs404_snoc_nodes),
+};
+
+static int qcom_icc_aggregate(struct icc_node *node, 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, 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_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_kcalloc(dev, num_nodes, sizeof(*node), 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:
+	list_for_each_entry(node, &provider->nodes, node_list) {
+		icc_node_del(node);
+		icc_node_destroy(node->id);
+	}
+	clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
+	icc_provider_del(provider);
+
+	return ret;
+}
+
+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 const struct of_device_id qcs404_noc_of_match[] = {
+	{ .compatible = "qcom,qcs404-bimc", .data = &qcs404_bimc },
+	{ .compatible = "qcom,qcs404-pcnoc", .data = &qcs404_pcnoc },
+	{ .compatible = "qcom,qcs404-snoc", .data = &qcs404_snoc },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, qcs404_noc_of_match);
+
+static struct platform_driver qcs404_noc_driver = {
+	.probe = qnoc_probe,
+	.remove = qnoc_remove,
+	.driver = {
+		.name = "qnoc-qcs404",
+		.of_match_table = qcs404_noc_of_match,
+	},
+};
+module_platform_driver(qcs404_noc_driver);
+MODULE_DESCRIPTION("Qualcomm QCS404 NoC driver");
+MODULE_LICENSE("GPL v2");

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v4 5/5] arm64: dts: qcs404: Add interconnect provider DT nodes
  2019-06-13 15:13 [PATCH v4 0/5] Add QCS404 interconnect provider driver Georgi Djakov
                   ` (3 preceding siblings ...)
  2019-06-13 15:13 ` [PATCH v4 4/5] interconnect: qcom: Add QCS404 interconnect provider driver Georgi Djakov
@ 2019-06-13 15:13 ` Georgi Djakov
  4 siblings, 0 replies; 12+ messages in thread
From: Georgi Djakov @ 2019-06-13 15:13 UTC (permalink / raw)
  To: robh+dt, bjorn.andersson, agross, georgi.djakov
  Cc: vkoul, evgreen, daidavid1, linux-pm, devicetree, linux-kernel,
	linux-arm-msm

Add the DT nodes for the network-on-chip interconnect buses found
on qcs404-based platforms.

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---

v4:
- Insert the NoC DT nodes after rng@ to keep the nodes sorted by address.
- Pick Bjorn's r-b.

v3:
- Update according to the new binding: add reg property and moved under the
  "soc" node.

 arch/arm64/boot/dts/qcom/qcs404.dtsi | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
index ffedf9640af7..da1dbf515bd9 100644
--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2018, Linaro Limited
 
+#include <dt-bindings/interconnect/qcom,qcs404.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/qcom,gcc-qcs404.h>
 #include <dt-bindings/clock/qcom,rpmcc.h>
@@ -266,6 +267,33 @@
 			clock-names = "core";
 		};
 
+		bimc: interconnect@400000 {
+			reg = <0x00400000 0x80000>;
+			compatible = "qcom,qcs404-bimc";
+			#interconnect-cells = <1>;
+			clock-names = "bus_clk", "bus_a_clk";
+			clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
+				<&rpmcc RPM_SMD_BIMC_A_CLK>;
+		};
+
+		pcnoc: interconnect@500000 {
+			reg = <0x00500000 0x15080>;
+			compatible = "qcom,qcs404-pcnoc";
+			#interconnect-cells = <1>;
+			clock-names = "bus_clk", "bus_a_clk";
+			clocks = <&rpmcc RPM_SMD_PNOC_CLK>,
+				<&rpmcc RPM_SMD_PNOC_A_CLK>;
+		};
+
+		snoc: interconnect@580000 {
+			reg = <0x00580000 0x23080>;
+			compatible = "qcom,qcs404-snoc";
+			#interconnect-cells = <1>;
+			clock-names = "bus_clk", "bus_a_clk";
+			clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
+				<&rpmcc RPM_SMD_SNOC_A_CLK>;
+		};
+
 		tlmm: pinctrl@1000000 {
 			compatible = "qcom,qcs404-pinctrl";
 			reg = <0x01000000 0x200000>,

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 2/5] soc: qcom: smd-rpm: Create RPM interconnect proxy child device
  2019-06-13 15:13 ` [PATCH v4 2/5] soc: qcom: smd-rpm: Create RPM interconnect proxy child device Georgi Djakov
@ 2019-06-13 15:40   ` Bjorn Andersson
  0 siblings, 0 replies; 12+ messages in thread
From: Bjorn Andersson @ 2019-06-13 15:40 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: robh+dt, agross, vkoul, evgreen, daidavid1, linux-pm, devicetree,
	linux-kernel, linux-arm-msm

On Thu 13 Jun 08:13 PDT 2019, Georgi Djakov wrote:

> Register a platform device to handle the communication of bus bandwidth
> requests with the remote processor. The interconnect proxy device is part
> of this remote processor (RPM) hardware. Let's create a icc-smd-rpm proxy
> child device to represent the bus throughput functionality that is provided
> by the RPM.
> 

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
> ---
> 
> v4:
> - Return error if platform_device_register_data() fails
> - Remove platform_set_drvdata() on the child device.
> 
> v3:
> - New patch.
> 
>  drivers/soc/qcom/smd-rpm.c | 17 ++++++++++++++++-
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c
> index fa9dd12b5e39..34cdd638a6c1 100644
> --- a/drivers/soc/qcom/smd-rpm.c
> +++ b/drivers/soc/qcom/smd-rpm.c
> @@ -19,12 +19,14 @@
>  /**
>   * struct qcom_smd_rpm - state of the rpm device driver
>   * @rpm_channel:	reference to the smd channel
> + * @icc:		interconnect proxy device
>   * @ack:		completion for acks
>   * @lock:		mutual exclusion around the send/complete pair
>   * @ack_status:		result of the rpm request
>   */
>  struct qcom_smd_rpm {
>  	struct rpmsg_endpoint *rpm_channel;
> +	struct platform_device *icc;
>  	struct device *dev;
>  
>  	struct completion ack;
> @@ -193,6 +195,7 @@ static int qcom_smd_rpm_callback(struct rpmsg_device *rpdev,
>  static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev)
>  {
>  	struct qcom_smd_rpm *rpm;
> +	int ret;
>  
>  	rpm = devm_kzalloc(&rpdev->dev, sizeof(*rpm), GFP_KERNEL);
>  	if (!rpm)
> @@ -205,11 +208,23 @@ static int qcom_smd_rpm_probe(struct rpmsg_device *rpdev)
>  	rpm->rpm_channel = rpdev->ept;
>  	dev_set_drvdata(&rpdev->dev, rpm);
>  
> -	return of_platform_populate(rpdev->dev.of_node, NULL, NULL, &rpdev->dev);
> +	rpm->icc = platform_device_register_data(&rpdev->dev, "icc_smd_rpm", -1,
> +						 NULL, 0);
> +	if (IS_ERR(rpm->icc))
> +		return PTR_ERR(rpm->icc);
> +
> +	ret = of_platform_populate(rpdev->dev.of_node, NULL, NULL, &rpdev->dev);
> +	if (ret)
> +		platform_device_unregister(rpm->icc);
> +
> +	return ret;
>  }
>  
>  static void qcom_smd_rpm_remove(struct rpmsg_device *rpdev)
>  {
> +	struct qcom_smd_rpm *rpm = dev_get_drvdata(&rpdev->dev);
> +
> +	platform_device_unregister(rpm->icc);
>  	of_platform_depopulate(&rpdev->dev);
>  }
>  

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 3/5] interconnect: qcom: Add interconnect SMD over SMD driver
  2019-06-13 15:13 ` [PATCH v4 3/5] interconnect: qcom: Add interconnect SMD over SMD driver Georgi Djakov
@ 2019-06-13 15:42   ` Bjorn Andersson
  0 siblings, 0 replies; 12+ messages in thread
From: Bjorn Andersson @ 2019-06-13 15:42 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: robh+dt, agross, vkoul, evgreen, daidavid1, linux-pm, devicetree,
	linux-kernel, linux-arm-msm

On Thu 13 Jun 08:13 PDT 2019, Georgi Djakov wrote:

> On some Qualcomm SoCs, there is a remote processor, which controls some of
> the Network-On-Chip interconnect resources. Other CPUs express their needs
> by communicating with this processor. Add a driver to handle communication
> with this remote processor.
> 
> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
> ---
> 
> v4:
> - Hide the driver from config menu. It will be selected by other driver.
> - Add remove() function to zero out the rpm handle.
> 
> v3:
> - New patch.
> 
>  drivers/interconnect/qcom/Kconfig   |  3 ++
>  drivers/interconnect/qcom/Makefile  |  2 +
>  drivers/interconnect/qcom/smd-rpm.c | 80 +++++++++++++++++++++++++++++
>  drivers/interconnect/qcom/smd-rpm.h | 15 ++++++
>  4 files changed, 100 insertions(+)
>  create mode 100644 drivers/interconnect/qcom/smd-rpm.c
>  create mode 100644 drivers/interconnect/qcom/smd-rpm.h
> 
> diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig
> index d5e70ebc2410..03fd67173494 100644
> --- a/drivers/interconnect/qcom/Kconfig
> +++ b/drivers/interconnect/qcom/Kconfig
> @@ -12,3 +12,6 @@ config INTERCONNECT_QCOM_SDM845
>  	help
>  	  This is a driver for the Qualcomm Network-on-Chip on sdm845-based
>  	  platforms.
> +
> +config INTERCONNECT_QCOM_SMD_RPM
> +	tristate
> diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile
> index 1c1cea690f92..a600cf6cc272 100644
> --- a/drivers/interconnect/qcom/Makefile
> +++ b/drivers/interconnect/qcom/Makefile
> @@ -1,5 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
>  
>  qnoc-sdm845-objs			:= sdm845.o
> +icc-smd-rpm-objs			:= smd-rpm.o
>  
>  obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o
> +obj-$(CONFIG_INTERCONNECT_QCOM_SMD_RPM) += icc-smd-rpm.o
> diff --git a/drivers/interconnect/qcom/smd-rpm.c b/drivers/interconnect/qcom/smd-rpm.c
> new file mode 100644
> index 000000000000..0a8c9547bd29
> --- /dev/null
> +++ b/drivers/interconnect/qcom/smd-rpm.c
> @@ -0,0 +1,80 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * RPM over SMD communication wrapper for interconnects
> + *
> + * Copyright (C) 2019 Linaro Ltd
> + * Author: Georgi Djakov <georgi.djakov@linaro.org>
> + */
> +
> +#include <linux/interconnect-provider.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/soc/qcom/smd-rpm.h>
> +
> +#include "smd-rpm.h"
> +
> +#define RPM_KEY_BW		0x00007762
> +
> +static struct qcom_smd_rpm *icc_smd_rpm;
> +
> +struct icc_rpm_smd_req {
> +	__le32 key;
> +	__le32 nbytes;
> +	__le32 value;
> +};
> +
> +bool qcom_icc_rpm_smd_available(void)
> +{
> +	if (!icc_smd_rpm)
> +		return false;
> +
> +	return true;

A more succinct form would have been:

	return !!icc_smd_rpm;


Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

> +}
> +EXPORT_SYMBOL_GPL(qcom_icc_rpm_smd_available);
> +
> +int qcom_icc_rpm_smd_send(int ctx, int rsc_type, int id, u32 val)
> +{
> +	struct icc_rpm_smd_req req = {
> +		.key = cpu_to_le32(RPM_KEY_BW),
> +		.nbytes = cpu_to_le32(sizeof(u32)),
> +		.value = cpu_to_le32(val),
> +	};
> +
> +	return qcom_rpm_smd_write(icc_smd_rpm, ctx, rsc_type, id, &req,
> +				  sizeof(req));
> +}
> +EXPORT_SYMBOL_GPL(qcom_icc_rpm_smd_send);
> +
> +static int qcom_icc_rpm_smd_remove(struct platform_device *pdev)
> +{
> +	icc_smd_rpm = NULL;
> +
> +	return 0;
> +}
> +
> +static int qcom_icc_rpm_smd_probe(struct platform_device *pdev)
> +{
> +	icc_smd_rpm = dev_get_drvdata(pdev->dev.parent);
> +
> +	if (!icc_smd_rpm) {
> +		dev_err(&pdev->dev, "unable to retrieve handle to RPM\n");
> +		return -ENODEV;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct platform_driver qcom_interconnect_rpm_smd_driver = {
> +	.driver = {
> +		.name		= "icc_smd_rpm",
> +	},
> +	.probe = qcom_icc_rpm_smd_probe,
> +	.remove = qcom_icc_rpm_smd_remove,
> +};
> +module_platform_driver(qcom_interconnect_rpm_smd_driver);
> +MODULE_AUTHOR("Georgi Djakov <georgi.djakov@linaro.org>");
> +MODULE_DESCRIPTION("Qualcomm SMD RPM interconnect proxy driver");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:icc_smd_rpm");
> diff --git a/drivers/interconnect/qcom/smd-rpm.h b/drivers/interconnect/qcom/smd-rpm.h
> new file mode 100644
> index 000000000000..ca9d0327b8ac
> --- /dev/null
> +++ b/drivers/interconnect/qcom/smd-rpm.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2019, Linaro Ltd.
> + * Author: Georgi Djakov <georgi.djakov@linaro.org>
> + */
> +
> +#ifndef __DRIVERS_INTERCONNECT_QCOM_SMD_RPM_H
> +#define __DRIVERS_INTERCONNECT_QCOM_SMD_RPM_H
> +
> +#include <linux/soc/qcom/smd-rpm.h>
> +
> +bool qcom_icc_rpm_smd_available(void);
> +int qcom_icc_rpm_smd_send(int ctx, int rsc_type, int id, u32 val);
> +
> +#endif

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 4/5] interconnect: qcom: Add QCS404 interconnect provider driver
  2019-06-13 15:13 ` [PATCH v4 4/5] interconnect: qcom: Add QCS404 interconnect provider driver Georgi Djakov
@ 2019-06-13 15:47   ` Bjorn Andersson
  0 siblings, 0 replies; 12+ messages in thread
From: Bjorn Andersson @ 2019-06-13 15:47 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: robh+dt, agross, vkoul, evgreen, daidavid1, linux-pm, devicetree,
	linux-kernel, linux-arm-msm

On Thu 13 Jun 08:13 PDT 2019, Georgi Djakov wrote:

> From: Bjorn Andersson <bjorn.andersson@linaro.org>
> 
> Add driver for the interconnect buses found in Qualcomm QCS404-based
> platforms. The topology consists of three NoCs that are controlled by
> a remote processor. This remote processor collects the aggregated
> bandwidth for each master-slave pairs.
> 

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
> ---
> 
> v4:
> - Select INTERCONNECT_QCOM_SMD_RPM from this driver.
> - Move the DT header to the dt-bindings patch.
> - Move this patch later in the series.
> 
> v3:
> - Convert the #defines into enum. (Bjorn)
> - Move the rpm-smd part into a separate interconnect proxy driver.
> 
> v2:
> - Use the clk_bulk API. (Bjorn)
> - Move the port IDs into the provider file. (Bjorn)
> - Use ARRAY_SIZE in the macro to automagically count the num_links. (Bjorn)
> - Improve code readability. (Bjorn)
> 
> 
>  drivers/interconnect/qcom/Kconfig  |   9 +
>  drivers/interconnect/qcom/Makefile |   2 +
>  drivers/interconnect/qcom/qcs404.c | 539 +++++++++++++++++++++++++++++
>  3 files changed, 550 insertions(+)
>  create mode 100644 drivers/interconnect/qcom/qcs404.c
> 
> diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig
> index 03fd67173494..339e8f10d4f3 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_QCS404
> +	tristate "Qualcomm QCS404 interconnect driver"
> +	depends on INTERCONNECT_QCOM
> +	depends on QCOM_SMD_RPM || COMPILE_TEST
> +	select INTERCONNECT_QCOM_SMD_RPM
> +	help
> +	  This is a driver for the Qualcomm Network-on-Chip on qcs404-based
> +	  platforms.
> +
>  config INTERCONNECT_QCOM_SDM845
>  	tristate "Qualcomm SDM845 interconnect driver"
>  	depends on INTERCONNECT_QCOM
> diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile
> index a600cf6cc272..67dafb783dec 100644
> --- a/drivers/interconnect/qcom/Makefile
> +++ b/drivers/interconnect/qcom/Makefile
> @@ -1,7 +1,9 @@
>  # SPDX-License-Identifier: GPL-2.0
>  
> +qnoc-qcs404-objs			:= qcs404.o
>  qnoc-sdm845-objs			:= sdm845.o
>  icc-smd-rpm-objs			:= smd-rpm.o
>  
> +obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
>  obj-$(CONFIG_INTERCONNECT_QCOM_SDM845) += qnoc-sdm845.o
>  obj-$(CONFIG_INTERCONNECT_QCOM_SMD_RPM) += icc-smd-rpm.o
> diff --git a/drivers/interconnect/qcom/qcs404.c b/drivers/interconnect/qcom/qcs404.c
> new file mode 100644
> index 000000000000..99be0928e2ad
> --- /dev/null
> +++ b/drivers/interconnect/qcom/qcs404.c
> @@ -0,0 +1,539 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2019 Linaro Ltd
> + */
> +
> +#include <dt-bindings/interconnect/qcom,qcs404.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 <linux/slab.h>
> +
> +#include "smd-rpm.h"
> +
> +#define RPM_BUS_MASTER_REQ	0x73616d62
> +#define RPM_BUS_SLAVE_REQ	0x766c7362
> +
> +enum {
> +	QCS404_MASTER_AMPSS_M0 = 1,
> +	QCS404_MASTER_GRAPHICS_3D,
> +	QCS404_MASTER_MDP_PORT0,
> +	QCS404_SNOC_BIMC_1_MAS,
> +	QCS404_MASTER_TCU_0,
> +	QCS404_MASTER_SPDM,
> +	QCS404_MASTER_BLSP_1,
> +	QCS404_MASTER_BLSP_2,
> +	QCS404_MASTER_XM_USB_HS1,
> +	QCS404_MASTER_CRYPTO_CORE0,
> +	QCS404_MASTER_SDCC_1,
> +	QCS404_MASTER_SDCC_2,
> +	QCS404_SNOC_PNOC_MAS,
> +	QCS404_MASTER_QPIC,
> +	QCS404_MASTER_QDSS_BAM,
> +	QCS404_BIMC_SNOC_MAS,
> +	QCS404_PNOC_SNOC_MAS,
> +	QCS404_MASTER_QDSS_ETR,
> +	QCS404_MASTER_EMAC,
> +	QCS404_MASTER_PCIE,
> +	QCS404_MASTER_USB3,
> +	QCS404_PNOC_INT_0,
> +	QCS404_PNOC_INT_2,
> +	QCS404_PNOC_INT_3,
> +	QCS404_PNOC_SLV_0,
> +	QCS404_PNOC_SLV_1,
> +	QCS404_PNOC_SLV_2,
> +	QCS404_PNOC_SLV_3,
> +	QCS404_PNOC_SLV_4,
> +	QCS404_PNOC_SLV_6,
> +	QCS404_PNOC_SLV_7,
> +	QCS404_PNOC_SLV_8,
> +	QCS404_PNOC_SLV_9,
> +	QCS404_PNOC_SLV_10,
> +	QCS404_PNOC_SLV_11,
> +	QCS404_SNOC_QDSS_INT,
> +	QCS404_SNOC_INT_0,
> +	QCS404_SNOC_INT_1,
> +	QCS404_SNOC_INT_2,
> +	QCS404_SLAVE_EBI_CH0,
> +	QCS404_BIMC_SNOC_SLV,
> +	QCS404_SLAVE_SPDM_WRAPPER,
> +	QCS404_SLAVE_PDM,
> +	QCS404_SLAVE_PRNG,
> +	QCS404_SLAVE_TCSR,
> +	QCS404_SLAVE_SNOC_CFG,
> +	QCS404_SLAVE_MESSAGE_RAM,
> +	QCS404_SLAVE_DISPLAY_CFG,
> +	QCS404_SLAVE_GRAPHICS_3D_CFG,
> +	QCS404_SLAVE_BLSP_1,
> +	QCS404_SLAVE_TLMM_NORTH,
> +	QCS404_SLAVE_PCIE_1,
> +	QCS404_SLAVE_EMAC_CFG,
> +	QCS404_SLAVE_BLSP_2,
> +	QCS404_SLAVE_TLMM_EAST,
> +	QCS404_SLAVE_TCU,
> +	QCS404_SLAVE_PMIC_ARB,
> +	QCS404_SLAVE_SDCC_1,
> +	QCS404_SLAVE_SDCC_2,
> +	QCS404_SLAVE_TLMM_SOUTH,
> +	QCS404_SLAVE_USB_HS,
> +	QCS404_SLAVE_USB3,
> +	QCS404_SLAVE_CRYPTO_0_CFG,
> +	QCS404_PNOC_SNOC_SLV,
> +	QCS404_SLAVE_APPSS,
> +	QCS404_SLAVE_WCSS,
> +	QCS404_SNOC_BIMC_1_SLV,
> +	QCS404_SLAVE_OCIMEM,
> +	QCS404_SNOC_PNOC_SLV,
> +	QCS404_SLAVE_QDSS_STM,
> +	QCS404_SLAVE_CATS_128,
> +	QCS404_SLAVE_OCMEM_64,
> +	QCS404_SLAVE_LPASS,
> +};
> +
> +#define to_qcom_provider(_provider) \
> +	container_of(_provider, struct qcom_icc_provider, provider)
> +
> +static const struct clk_bulk_data bus_clocks[] = {
> +	{ .id = "bus_clk" },
> +	{ .id = "bus_a_clk" },
> +};
> +
> +/**
> + * 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 QCS404_MAX_LINKS	12
> +
> +/**
> + * 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[QCS404_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(mas_apps_proc, QCS404_MASTER_AMPSS_M0, 8, 0, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV);
> +DEFINE_QNODE(mas_oxili, QCS404_MASTER_GRAPHICS_3D, 8, 6, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV);
> +DEFINE_QNODE(mas_mdp, QCS404_MASTER_MDP_PORT0, 8, 8, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV);
> +DEFINE_QNODE(mas_snoc_bimc_1, QCS404_SNOC_BIMC_1_MAS, 8, 76, -1, QCS404_SLAVE_EBI_CH0);
> +DEFINE_QNODE(mas_tcu_0, QCS404_MASTER_TCU_0, 8, -1, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV);
> +DEFINE_QNODE(mas_spdm, QCS404_MASTER_SPDM, 4, -1, -1, QCS404_PNOC_INT_3);
> +DEFINE_QNODE(mas_blsp_1, QCS404_MASTER_BLSP_1, 4, 41, -1, QCS404_PNOC_INT_3);
> +DEFINE_QNODE(mas_blsp_2, QCS404_MASTER_BLSP_2, 4, 39, -1, QCS404_PNOC_INT_3);
> +DEFINE_QNODE(mas_xi_usb_hs1, QCS404_MASTER_XM_USB_HS1, 8, 138, -1, QCS404_PNOC_INT_0);
> +DEFINE_QNODE(mas_crypto, QCS404_MASTER_CRYPTO_CORE0, 8, 23, -1, QCS404_PNOC_SNOC_SLV, QCS404_PNOC_INT_2);
> +DEFINE_QNODE(mas_sdcc_1, QCS404_MASTER_SDCC_1, 8, 33, -1, QCS404_PNOC_INT_0);
> +DEFINE_QNODE(mas_sdcc_2, QCS404_MASTER_SDCC_2, 8, 35, -1, QCS404_PNOC_INT_0);
> +DEFINE_QNODE(mas_snoc_pcnoc, QCS404_SNOC_PNOC_MAS, 8, 77, -1, QCS404_PNOC_INT_2);
> +DEFINE_QNODE(mas_qpic, QCS404_MASTER_QPIC, 4, -1, -1, QCS404_PNOC_INT_0);
> +DEFINE_QNODE(mas_qdss_bam, QCS404_MASTER_QDSS_BAM, 4, -1, -1, QCS404_SNOC_QDSS_INT);
> +DEFINE_QNODE(mas_bimc_snoc, QCS404_BIMC_SNOC_MAS, 8, 21, -1, QCS404_SLAVE_OCMEM_64, QCS404_SLAVE_CATS_128, QCS404_SNOC_INT_0, QCS404_SNOC_INT_1);
> +DEFINE_QNODE(mas_pcnoc_snoc, QCS404_PNOC_SNOC_MAS, 8, 29, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_2, QCS404_SNOC_INT_0);
> +DEFINE_QNODE(mas_qdss_etr, QCS404_MASTER_QDSS_ETR, 8, -1, -1, QCS404_SNOC_QDSS_INT);
> +DEFINE_QNODE(mas_emac, QCS404_MASTER_EMAC, 8, -1, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_1);
> +DEFINE_QNODE(mas_pcie, QCS404_MASTER_PCIE, 8, -1, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_1);
> +DEFINE_QNODE(mas_usb3, QCS404_MASTER_USB3, 8, -1, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_1);
> +DEFINE_QNODE(pcnoc_int_0, QCS404_PNOC_INT_0, 8, 85, 114, QCS404_PNOC_SNOC_SLV, QCS404_PNOC_INT_2);
> +DEFINE_QNODE(pcnoc_int_2, QCS404_PNOC_INT_2, 8, 124, 184, QCS404_PNOC_SLV_10, QCS404_SLAVE_TCU, QCS404_PNOC_SLV_11, QCS404_PNOC_SLV_2, QCS404_PNOC_SLV_3, QCS404_PNOC_SLV_0, QCS404_PNOC_SLV_1, QCS404_PNOC_SLV_6, QCS404_PNOC_SLV_7, QCS404_PNOC_SLV_4, QCS404_PNOC_SLV_8, QCS404_PNOC_SLV_9);
> +DEFINE_QNODE(pcnoc_int_3, QCS404_PNOC_INT_3, 8, 125, 185, QCS404_PNOC_SNOC_SLV);
> +DEFINE_QNODE(pcnoc_s_0, QCS404_PNOC_SLV_0, 4, 89, 118, QCS404_SLAVE_PRNG, QCS404_SLAVE_SPDM_WRAPPER, QCS404_SLAVE_PDM);
> +DEFINE_QNODE(pcnoc_s_1, QCS404_PNOC_SLV_1, 4, 90, 119, QCS404_SLAVE_TCSR);
> +DEFINE_QNODE(pcnoc_s_2, QCS404_PNOC_SLV_2, 4, -1, -1, QCS404_SLAVE_GRAPHICS_3D_CFG);
> +DEFINE_QNODE(pcnoc_s_3, QCS404_PNOC_SLV_3, 4, 92, 121, QCS404_SLAVE_MESSAGE_RAM);
> +DEFINE_QNODE(pcnoc_s_4, QCS404_PNOC_SLV_4, 4, 93, 122, QCS404_SLAVE_SNOC_CFG);
> +DEFINE_QNODE(pcnoc_s_6, QCS404_PNOC_SLV_6, 4, 94, 123, QCS404_SLAVE_BLSP_1, QCS404_SLAVE_TLMM_NORTH, QCS404_SLAVE_EMAC_CFG);
> +DEFINE_QNODE(pcnoc_s_7, QCS404_PNOC_SLV_7, 4, 95, 124, QCS404_SLAVE_TLMM_SOUTH, QCS404_SLAVE_DISPLAY_CFG, QCS404_SLAVE_SDCC_1, QCS404_SLAVE_PCIE_1, QCS404_SLAVE_SDCC_2);
> +DEFINE_QNODE(pcnoc_s_8, QCS404_PNOC_SLV_8, 4, 96, 125, QCS404_SLAVE_CRYPTO_0_CFG);
> +DEFINE_QNODE(pcnoc_s_9, QCS404_PNOC_SLV_9, 4, 97, 126, QCS404_SLAVE_BLSP_2, QCS404_SLAVE_TLMM_EAST, QCS404_SLAVE_PMIC_ARB);
> +DEFINE_QNODE(pcnoc_s_10, QCS404_PNOC_SLV_10, 4, 157, -1, QCS404_SLAVE_USB_HS);
> +DEFINE_QNODE(pcnoc_s_11, QCS404_PNOC_SLV_11, 4, 158, 246, QCS404_SLAVE_USB3);
> +DEFINE_QNODE(qdss_int, QCS404_SNOC_QDSS_INT, 8, -1, -1, QCS404_SNOC_BIMC_1_SLV, QCS404_SNOC_INT_1);
> +DEFINE_QNODE(snoc_int_0, QCS404_SNOC_INT_0, 8, 99, 130, QCS404_SLAVE_LPASS, QCS404_SLAVE_APPSS, QCS404_SLAVE_WCSS);
> +DEFINE_QNODE(snoc_int_1, QCS404_SNOC_INT_1, 8, 100, 131, QCS404_SNOC_PNOC_SLV, QCS404_SNOC_INT_2);
> +DEFINE_QNODE(snoc_int_2, QCS404_SNOC_INT_2, 8, 134, 197, QCS404_SLAVE_QDSS_STM, QCS404_SLAVE_OCIMEM);
> +DEFINE_QNODE(slv_ebi, QCS404_SLAVE_EBI_CH0, 8, -1, 0, 0);
> +DEFINE_QNODE(slv_bimc_snoc, QCS404_BIMC_SNOC_SLV, 8, -1, 2, QCS404_BIMC_SNOC_MAS);
> +DEFINE_QNODE(slv_spdm, QCS404_SLAVE_SPDM_WRAPPER, 4, -1, -1, 0);
> +DEFINE_QNODE(slv_pdm, QCS404_SLAVE_PDM, 4, -1, 41, 0);
> +DEFINE_QNODE(slv_prng, QCS404_SLAVE_PRNG, 4, -1, 44, 0);
> +DEFINE_QNODE(slv_tcsr, QCS404_SLAVE_TCSR, 4, -1, 50, 0);
> +DEFINE_QNODE(slv_snoc_cfg, QCS404_SLAVE_SNOC_CFG, 4, -1, 70, 0);
> +DEFINE_QNODE(slv_message_ram, QCS404_SLAVE_MESSAGE_RAM, 4, -1, 55, 0);
> +DEFINE_QNODE(slv_disp_ss_cfg, QCS404_SLAVE_DISPLAY_CFG, 4, -1, -1, 0);
> +DEFINE_QNODE(slv_gpu_cfg, QCS404_SLAVE_GRAPHICS_3D_CFG, 4, -1, -1, 0);
> +DEFINE_QNODE(slv_blsp_1, QCS404_SLAVE_BLSP_1, 4, -1, 39, 0);
> +DEFINE_QNODE(slv_tlmm_north, QCS404_SLAVE_TLMM_NORTH, 4, -1, 214, 0);
> +DEFINE_QNODE(slv_pcie, QCS404_SLAVE_PCIE_1, 4, -1, -1, 0);
> +DEFINE_QNODE(slv_ethernet, QCS404_SLAVE_EMAC_CFG, 4, -1, -1, 0);
> +DEFINE_QNODE(slv_blsp_2, QCS404_SLAVE_BLSP_2, 4, -1, 37, 0);
> +DEFINE_QNODE(slv_tlmm_east, QCS404_SLAVE_TLMM_EAST, 4, -1, 213, 0);
> +DEFINE_QNODE(slv_tcu, QCS404_SLAVE_TCU, 8, -1, -1, 0);
> +DEFINE_QNODE(slv_pmic_arb, QCS404_SLAVE_PMIC_ARB, 4, -1, 59, 0);
> +DEFINE_QNODE(slv_sdcc_1, QCS404_SLAVE_SDCC_1, 4, -1, 31, 0);
> +DEFINE_QNODE(slv_sdcc_2, QCS404_SLAVE_SDCC_2, 4, -1, 33, 0);
> +DEFINE_QNODE(slv_tlmm_south, QCS404_SLAVE_TLMM_SOUTH, 4, -1, -1, 0);
> +DEFINE_QNODE(slv_usb_hs, QCS404_SLAVE_USB_HS, 4, -1, 40, 0);
> +DEFINE_QNODE(slv_usb3, QCS404_SLAVE_USB3, 4, -1, 22, 0);
> +DEFINE_QNODE(slv_crypto_0_cfg, QCS404_SLAVE_CRYPTO_0_CFG, 4, -1, 52, 0);
> +DEFINE_QNODE(slv_pcnoc_snoc, QCS404_PNOC_SNOC_SLV, 8, -1, 45, QCS404_PNOC_SNOC_MAS);
> +DEFINE_QNODE(slv_kpss_ahb, QCS404_SLAVE_APPSS, 4, -1, -1, 0);
> +DEFINE_QNODE(slv_wcss, QCS404_SLAVE_WCSS, 4, -1, 23, 0);
> +DEFINE_QNODE(slv_snoc_bimc_1, QCS404_SNOC_BIMC_1_SLV, 8, -1, 104, QCS404_SNOC_BIMC_1_MAS);
> +DEFINE_QNODE(slv_imem, QCS404_SLAVE_OCIMEM, 8, -1, 26, 0);
> +DEFINE_QNODE(slv_snoc_pcnoc, QCS404_SNOC_PNOC_SLV, 8, -1, 28, QCS404_SNOC_PNOC_MAS);
> +DEFINE_QNODE(slv_qdss_stm, QCS404_SLAVE_QDSS_STM, 4, -1, 30, 0);
> +DEFINE_QNODE(slv_cats_0, QCS404_SLAVE_CATS_128, 16, -1, -1, 0);
> +DEFINE_QNODE(slv_cats_1, QCS404_SLAVE_OCMEM_64, 8, -1, -1, 0);
> +DEFINE_QNODE(slv_lpass, QCS404_SLAVE_LPASS, 4, -1, -1, 0);
> +
> +static struct qcom_icc_node *qcs404_bimc_nodes[] = {
> +	[MASTER_AMPSS_M0] = &mas_apps_proc,
> +	[MASTER_OXILI] = &mas_oxili,
> +	[MASTER_MDP_PORT0] = &mas_mdp,
> +	[MASTER_SNOC_BIMC_1] = &mas_snoc_bimc_1,
> +	[MASTER_TCU_0] = &mas_tcu_0,
> +	[SLAVE_EBI_CH0] = &slv_ebi,
> +	[SLAVE_BIMC_SNOC] = &slv_bimc_snoc,
> +};
> +
> +static struct qcom_icc_desc qcs404_bimc = {
> +	.nodes = qcs404_bimc_nodes,
> +	.num_nodes = ARRAY_SIZE(qcs404_bimc_nodes),
> +};
> +
> +static struct qcom_icc_node *qcs404_pcnoc_nodes[] = {
> +	[MASTER_SPDM] = &mas_spdm,
> +	[MASTER_BLSP_1] = &mas_blsp_1,
> +	[MASTER_BLSP_2] = &mas_blsp_2,
> +	[MASTER_XI_USB_HS1] = &mas_xi_usb_hs1,
> +	[MASTER_CRYPT0] = &mas_crypto,
> +	[MASTER_SDCC_1] = &mas_sdcc_1,
> +	[MASTER_SDCC_2] = &mas_sdcc_2,
> +	[MASTER_SNOC_PCNOC] = &mas_snoc_pcnoc,
> +	[MASTER_QPIC] = &mas_qpic,
> +	[PCNOC_INT_0] = &pcnoc_int_0,
> +	[PCNOC_INT_2] = &pcnoc_int_2,
> +	[PCNOC_INT_3] = &pcnoc_int_3,
> +	[PCNOC_S_0] = &pcnoc_s_0,
> +	[PCNOC_S_1] = &pcnoc_s_1,
> +	[PCNOC_S_2] = &pcnoc_s_2,
> +	[PCNOC_S_3] = &pcnoc_s_3,
> +	[PCNOC_S_4] = &pcnoc_s_4,
> +	[PCNOC_S_6] = &pcnoc_s_6,
> +	[PCNOC_S_7] = &pcnoc_s_7,
> +	[PCNOC_S_8] = &pcnoc_s_8,
> +	[PCNOC_S_9] = &pcnoc_s_9,
> +	[PCNOC_S_10] = &pcnoc_s_10,
> +	[PCNOC_S_11] = &pcnoc_s_11,
> +	[SLAVE_SPDM] = &slv_spdm,
> +	[SLAVE_PDM] = &slv_pdm,
> +	[SLAVE_PRNG] = &slv_prng,
> +	[SLAVE_TCSR] = &slv_tcsr,
> +	[SLAVE_SNOC_CFG] = &slv_snoc_cfg,
> +	[SLAVE_MESSAGE_RAM] = &slv_message_ram,
> +	[SLAVE_DISP_SS_CFG] = &slv_disp_ss_cfg,
> +	[SLAVE_GPU_CFG] = &slv_gpu_cfg,
> +	[SLAVE_BLSP_1] = &slv_blsp_1,
> +	[SLAVE_BLSP_2] = &slv_blsp_2,
> +	[SLAVE_TLMM_NORTH] = &slv_tlmm_north,
> +	[SLAVE_PCIE] = &slv_pcie,
> +	[SLAVE_ETHERNET] = &slv_ethernet,
> +	[SLAVE_TLMM_EAST] = &slv_tlmm_east,
> +	[SLAVE_TCU] = &slv_tcu,
> +	[SLAVE_PMIC_ARB] = &slv_pmic_arb,
> +	[SLAVE_SDCC_1] = &slv_sdcc_1,
> +	[SLAVE_SDCC_2] = &slv_sdcc_2,
> +	[SLAVE_TLMM_SOUTH] = &slv_tlmm_south,
> +	[SLAVE_USB_HS] = &slv_usb_hs,
> +	[SLAVE_USB3] = &slv_usb3,
> +	[SLAVE_CRYPTO_0_CFG] = &slv_crypto_0_cfg,
> +	[SLAVE_PCNOC_SNOC] = &slv_pcnoc_snoc,
> +};
> +
> +static struct qcom_icc_desc qcs404_pcnoc = {
> +	.nodes = qcs404_pcnoc_nodes,
> +	.num_nodes = ARRAY_SIZE(qcs404_pcnoc_nodes),
> +};
> +
> +static struct qcom_icc_node *qcs404_snoc_nodes[] = {
> +	[MASTER_QDSS_BAM] = &mas_qdss_bam,
> +	[MASTER_BIMC_SNOC] = &mas_bimc_snoc,
> +	[MASTER_PCNOC_SNOC] = &mas_pcnoc_snoc,
> +	[MASTER_QDSS_ETR] = &mas_qdss_etr,
> +	[MASTER_EMAC] = &mas_emac,
> +	[MASTER_PCIE] = &mas_pcie,
> +	[MASTER_USB3] = &mas_usb3,
> +	[QDSS_INT] = &qdss_int,
> +	[SNOC_INT_0] = &snoc_int_0,
> +	[SNOC_INT_1] = &snoc_int_1,
> +	[SNOC_INT_2] = &snoc_int_2,
> +	[SLAVE_KPSS_AHB] = &slv_kpss_ahb,
> +	[SLAVE_WCSS] = &slv_wcss,
> +	[SLAVE_SNOC_BIMC_1] = &slv_snoc_bimc_1,
> +	[SLAVE_IMEM] = &slv_imem,
> +	[SLAVE_SNOC_PCNOC] = &slv_snoc_pcnoc,
> +	[SLAVE_QDSS_STM] = &slv_qdss_stm,
> +	[SLAVE_CATS_0] = &slv_cats_0,
> +	[SLAVE_CATS_1] = &slv_cats_1,
> +	[SLAVE_LPASS] = &slv_lpass,
> +};
> +
> +static struct qcom_icc_desc qcs404_snoc = {
> +	.nodes = qcs404_snoc_nodes,
> +	.num_nodes = ARRAY_SIZE(qcs404_snoc_nodes),
> +};
> +
> +static int qcom_icc_aggregate(struct icc_node *node, 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, 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_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_kcalloc(dev, num_nodes, sizeof(*node), 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:
> +	list_for_each_entry(node, &provider->nodes, node_list) {
> +		icc_node_del(node);
> +		icc_node_destroy(node->id);
> +	}
> +	clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
> +	icc_provider_del(provider);
> +
> +	return ret;
> +}
> +
> +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 const struct of_device_id qcs404_noc_of_match[] = {
> +	{ .compatible = "qcom,qcs404-bimc", .data = &qcs404_bimc },
> +	{ .compatible = "qcom,qcs404-pcnoc", .data = &qcs404_pcnoc },
> +	{ .compatible = "qcom,qcs404-snoc", .data = &qcs404_snoc },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, qcs404_noc_of_match);
> +
> +static struct platform_driver qcs404_noc_driver = {
> +	.probe = qnoc_probe,
> +	.remove = qnoc_remove,
> +	.driver = {
> +		.name = "qnoc-qcs404",
> +		.of_match_table = qcs404_noc_of_match,
> +	},
> +};
> +module_platform_driver(qcs404_noc_driver);
> +MODULE_DESCRIPTION("Qualcomm QCS404 NoC driver");
> +MODULE_LICENSE("GPL v2");

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings
  2019-06-13 15:13 ` [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings Georgi Djakov
@ 2019-06-25 15:00   ` Georgi Djakov
  2019-07-08 19:26   ` Bjorn Andersson
  1 sibling, 0 replies; 12+ messages in thread
From: Georgi Djakov @ 2019-06-25 15:00 UTC (permalink / raw)
  To: robh+dt, devicetree
  Cc: bjorn.andersson, agross, vkoul, evgreen, daidavid1, linux-pm,
	linux-kernel, linux-arm-msm

Hi Rob,

On 6/13/19 18:13, Georgi Djakov wrote:
> The Qualcomm QCS404 platform has several buses that could be controlled
> and tuned according to the bandwidth demand.
> 
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
> ---
> 
> v4:
> - Add the DT header into this patch.
> - Pick Bjorn's r-b.
> 
> v3:
> - Add a reg property and move the interconnect nodes under the "soc" node.
> 
> v2:
> - No changes.
> 
>  .../bindings/interconnect/qcom,qcs404.txt     | 46 ++++++++++
>  .../dt-bindings/interconnect/qcom,qcs404.h    | 88 +++++++++++++++++++
>  2 files changed, 134 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
>  create mode 100644 include/dt-bindings/interconnect/qcom,qcs404.h
> 
> diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
> new file mode 100644
> index 000000000000..14a827268dda
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
> @@ -0,0 +1,46 @@
> +Qualcomm QCS404 Network-On-Chip interconnect driver binding
> +-----------------------------------------------------------
> +
> +Required properties :
> +- compatible : shall contain only one of the following:
> +			"qcom,qcs404-bimc"
> +			"qcom,qcs404-pcnoc"
> +			"qcom,qcs404-snoc"
> +- #interconnect-cells : should contain 1
> +
> +Optional properties :
> +reg : specifies the physical base address and size of registers
> +clocks : list of phandles and specifiers to all interconnect bus clocks
> +clock-names : clock names should include both "bus_clk" and "bus_a_clk"
> +
> +Example:
> +
> +soc {
> +	...
> +	bimc: interconnect@400000 {
> +		reg = <0x00400000 0x80000>;
> +		compatible = "qcom,qcs404-bimc";
> +		#interconnect-cells = <1>;
> +		clock-names = "bus_clk", "bus_a_clk";
> +		clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
> +			<&rpmcc RPM_SMD_BIMC_A_CLK>;
> +	};
> +
> +	pnoc: interconnect@500000 {
> +		reg = <0x00500000 0x15080>;
> +		compatible = "qcom,qcs404-pcnoc";
> +		#interconnect-cells = <1>;
> +		clock-names = "bus_clk", "bus_a_clk";
> +		clocks = <&rpmcc RPM_SMD_PNOC_CLK>,
> +			<&rpmcc RPM_SMD_PNOC_A_CLK>;
> +	};
> +
> +	snoc: interconnect@580000 {
> +		reg = <0x00580000 0x23080>;
> +		compatible = "qcom,qcs404-snoc";
> +		#interconnect-cells = <1>;
> +		clock-names = "bus_clk", "bus_a_clk";
> +		clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
> +			<&rpmcc RPM_SMD_SNOC_A_CLK>;
> +	};
> +};

Does this look ok from DT perspective?

Thanks,
Georgi

> diff --git a/include/dt-bindings/interconnect/qcom,qcs404.h b/include/dt-bindings/interconnect/qcom,qcs404.h
> new file mode 100644
> index 000000000000..960f6e39c5f2
> --- /dev/null
> +++ b/include/dt-bindings/interconnect/qcom,qcs404.h
> @@ -0,0 +1,88 @@
> +/* 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_QCS404_H
> +#define __DT_BINDINGS_INTERCONNECT_QCOM_QCS404_H
> +
> +#define MASTER_AMPSS_M0			0
> +#define MASTER_OXILI			1
> +#define MASTER_MDP_PORT0		2
> +#define MASTER_SNOC_BIMC_1		3
> +#define MASTER_TCU_0			4
> +#define SLAVE_EBI_CH0			5
> +#define SLAVE_BIMC_SNOC			6
> +
> +#define MASTER_SPDM			0
> +#define MASTER_BLSP_1			1
> +#define MASTER_BLSP_2			2
> +#define MASTER_XI_USB_HS1		3
> +#define MASTER_CRYPT0			4
> +#define MASTER_SDCC_1			5
> +#define MASTER_SDCC_2			6
> +#define MASTER_SNOC_PCNOC		7
> +#define MASTER_QPIC			8
> +#define PCNOC_INT_0			9
> +#define PCNOC_INT_2			10
> +#define PCNOC_INT_3			11
> +#define PCNOC_S_0			12
> +#define PCNOC_S_1			13
> +#define PCNOC_S_2			14
> +#define PCNOC_S_3			15
> +#define PCNOC_S_4			16
> +#define PCNOC_S_6			17
> +#define PCNOC_S_7			18
> +#define PCNOC_S_8			19
> +#define PCNOC_S_9			20
> +#define PCNOC_S_10			21
> +#define PCNOC_S_11			22
> +#define SLAVE_SPDM			23
> +#define SLAVE_PDM			24
> +#define SLAVE_PRNG			25
> +#define SLAVE_TCSR			26
> +#define SLAVE_SNOC_CFG			27
> +#define SLAVE_MESSAGE_RAM		28
> +#define SLAVE_DISP_SS_CFG		29
> +#define SLAVE_GPU_CFG			30
> +#define SLAVE_BLSP_1			31
> +#define SLAVE_BLSP_2			32
> +#define SLAVE_TLMM_NORTH		33
> +#define SLAVE_PCIE			34
> +#define SLAVE_ETHERNET			35
> +#define SLAVE_TLMM_EAST			36
> +#define SLAVE_TCU			37
> +#define SLAVE_PMIC_ARB			38
> +#define SLAVE_SDCC_1			39
> +#define SLAVE_SDCC_2			40
> +#define SLAVE_TLMM_SOUTH		41
> +#define SLAVE_USB_HS			42
> +#define SLAVE_USB3			43
> +#define SLAVE_CRYPTO_0_CFG		44
> +#define SLAVE_PCNOC_SNOC		45
> +
> +#define MASTER_QDSS_BAM			0
> +#define MASTER_BIMC_SNOC		1
> +#define MASTER_PCNOC_SNOC		2
> +#define MASTER_QDSS_ETR			3
> +#define MASTER_EMAC			4
> +#define MASTER_PCIE			5
> +#define MASTER_USB3			6
> +#define QDSS_INT			7
> +#define SNOC_INT_0			8
> +#define SNOC_INT_1			9
> +#define SNOC_INT_2			10
> +#define SLAVE_KPSS_AHB			11
> +#define SLAVE_WCSS			12
> +#define SLAVE_SNOC_BIMC_1		13
> +#define SLAVE_IMEM			14
> +#define SLAVE_SNOC_PCNOC		15
> +#define SLAVE_QDSS_STM			16
> +#define SLAVE_CATS_0			17
> +#define SLAVE_CATS_1			18
> +#define SLAVE_LPASS			19
> +
> +#endif
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings
  2019-06-13 15:13 ` [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings Georgi Djakov
  2019-06-25 15:00   ` Georgi Djakov
@ 2019-07-08 19:26   ` Bjorn Andersson
  2019-07-15 13:56     ` Georgi Djakov
  1 sibling, 1 reply; 12+ messages in thread
From: Bjorn Andersson @ 2019-07-08 19:26 UTC (permalink / raw)
  To: Georgi Djakov
  Cc: robh+dt, agross, vkoul, evgreen, daidavid1, linux-pm, devicetree,
	linux-kernel, linux-arm-msm

On Thu 13 Jun 08:13 PDT 2019, Georgi Djakov wrote:

> The Qualcomm QCS404 platform has several buses that could be controlled
> and tuned according to the bandwidth demand.
> 
> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
> ---
> 
> v4:
> - Add the DT header into this patch.
> - Pick Bjorn's r-b.
> 
> v3:
> - Add a reg property and move the interconnect nodes under the "soc" node.
> 
> v2:
> - No changes.
> 
>  .../bindings/interconnect/qcom,qcs404.txt     | 46 ++++++++++
>  .../dt-bindings/interconnect/qcom,qcs404.h    | 88 +++++++++++++++++++
>  2 files changed, 134 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
>  create mode 100644 include/dt-bindings/interconnect/qcom,qcs404.h
> 
> diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
> new file mode 100644
> index 000000000000..14a827268dda
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
> @@ -0,0 +1,46 @@
> +Qualcomm QCS404 Network-On-Chip interconnect driver binding
> +-----------------------------------------------------------
> +
> +Required properties :
> +- compatible : shall contain only one of the following:
> +			"qcom,qcs404-bimc"
> +			"qcom,qcs404-pcnoc"
> +			"qcom,qcs404-snoc"
> +- #interconnect-cells : should contain 1
> +
> +Optional properties :
> +reg : specifies the physical base address and size of registers
> +clocks : list of phandles and specifiers to all interconnect bus clocks
> +clock-names : clock names should include both "bus_clk" and "bus_a_clk"

Spoke to Rob about this patch, and I don't think these properties should
not be described as optional.

The reg isn't used unless we're implementing support for QoS, but let's
include them in the binding as required anyways.

Iirc the two clocks are required with the current implementation, but
shouldn't there be an iface clock as well, for accessing the QoS
register space?


PS. As I read this again, please drop _clk from the two clocks names -
we know they are clocks...

Regards,
Bjorn

> +
> +Example:
> +
> +soc {
> +	...
> +	bimc: interconnect@400000 {
> +		reg = <0x00400000 0x80000>;
> +		compatible = "qcom,qcs404-bimc";
> +		#interconnect-cells = <1>;
> +		clock-names = "bus_clk", "bus_a_clk";
> +		clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
> +			<&rpmcc RPM_SMD_BIMC_A_CLK>;
> +	};
> +
> +	pnoc: interconnect@500000 {
> +		reg = <0x00500000 0x15080>;
> +		compatible = "qcom,qcs404-pcnoc";
> +		#interconnect-cells = <1>;
> +		clock-names = "bus_clk", "bus_a_clk";
> +		clocks = <&rpmcc RPM_SMD_PNOC_CLK>,
> +			<&rpmcc RPM_SMD_PNOC_A_CLK>;
> +	};
> +
> +	snoc: interconnect@580000 {
> +		reg = <0x00580000 0x23080>;
> +		compatible = "qcom,qcs404-snoc";
> +		#interconnect-cells = <1>;
> +		clock-names = "bus_clk", "bus_a_clk";
> +		clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
> +			<&rpmcc RPM_SMD_SNOC_A_CLK>;
> +	};
> +};
> diff --git a/include/dt-bindings/interconnect/qcom,qcs404.h b/include/dt-bindings/interconnect/qcom,qcs404.h
> new file mode 100644
> index 000000000000..960f6e39c5f2
> --- /dev/null
> +++ b/include/dt-bindings/interconnect/qcom,qcs404.h
> @@ -0,0 +1,88 @@
> +/* 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_QCS404_H
> +#define __DT_BINDINGS_INTERCONNECT_QCOM_QCS404_H
> +
> +#define MASTER_AMPSS_M0			0
> +#define MASTER_OXILI			1
> +#define MASTER_MDP_PORT0		2
> +#define MASTER_SNOC_BIMC_1		3
> +#define MASTER_TCU_0			4
> +#define SLAVE_EBI_CH0			5
> +#define SLAVE_BIMC_SNOC			6
> +
> +#define MASTER_SPDM			0
> +#define MASTER_BLSP_1			1
> +#define MASTER_BLSP_2			2
> +#define MASTER_XI_USB_HS1		3
> +#define MASTER_CRYPT0			4
> +#define MASTER_SDCC_1			5
> +#define MASTER_SDCC_2			6
> +#define MASTER_SNOC_PCNOC		7
> +#define MASTER_QPIC			8
> +#define PCNOC_INT_0			9
> +#define PCNOC_INT_2			10
> +#define PCNOC_INT_3			11
> +#define PCNOC_S_0			12
> +#define PCNOC_S_1			13
> +#define PCNOC_S_2			14
> +#define PCNOC_S_3			15
> +#define PCNOC_S_4			16
> +#define PCNOC_S_6			17
> +#define PCNOC_S_7			18
> +#define PCNOC_S_8			19
> +#define PCNOC_S_9			20
> +#define PCNOC_S_10			21
> +#define PCNOC_S_11			22
> +#define SLAVE_SPDM			23
> +#define SLAVE_PDM			24
> +#define SLAVE_PRNG			25
> +#define SLAVE_TCSR			26
> +#define SLAVE_SNOC_CFG			27
> +#define SLAVE_MESSAGE_RAM		28
> +#define SLAVE_DISP_SS_CFG		29
> +#define SLAVE_GPU_CFG			30
> +#define SLAVE_BLSP_1			31
> +#define SLAVE_BLSP_2			32
> +#define SLAVE_TLMM_NORTH		33
> +#define SLAVE_PCIE			34
> +#define SLAVE_ETHERNET			35
> +#define SLAVE_TLMM_EAST			36
> +#define SLAVE_TCU			37
> +#define SLAVE_PMIC_ARB			38
> +#define SLAVE_SDCC_1			39
> +#define SLAVE_SDCC_2			40
> +#define SLAVE_TLMM_SOUTH		41
> +#define SLAVE_USB_HS			42
> +#define SLAVE_USB3			43
> +#define SLAVE_CRYPTO_0_CFG		44
> +#define SLAVE_PCNOC_SNOC		45
> +
> +#define MASTER_QDSS_BAM			0
> +#define MASTER_BIMC_SNOC		1
> +#define MASTER_PCNOC_SNOC		2
> +#define MASTER_QDSS_ETR			3
> +#define MASTER_EMAC			4
> +#define MASTER_PCIE			5
> +#define MASTER_USB3			6
> +#define QDSS_INT			7
> +#define SNOC_INT_0			8
> +#define SNOC_INT_1			9
> +#define SNOC_INT_2			10
> +#define SLAVE_KPSS_AHB			11
> +#define SLAVE_WCSS			12
> +#define SLAVE_SNOC_BIMC_1		13
> +#define SLAVE_IMEM			14
> +#define SLAVE_SNOC_PCNOC		15
> +#define SLAVE_QDSS_STM			16
> +#define SLAVE_CATS_0			17
> +#define SLAVE_CATS_1			18
> +#define SLAVE_LPASS			19
> +
> +#endif

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings
  2019-07-08 19:26   ` Bjorn Andersson
@ 2019-07-15 13:56     ` Georgi Djakov
  0 siblings, 0 replies; 12+ messages in thread
From: Georgi Djakov @ 2019-07-15 13:56 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: robh+dt, agross, vkoul, evgreen, daidavid1, linux-pm, devicetree,
	linux-kernel, linux-arm-msm

Hi Bjorn,

On 7/8/19 22:26, Bjorn Andersson wrote:
> On Thu 13 Jun 08:13 PDT 2019, Georgi Djakov wrote:
> 
>> The Qualcomm QCS404 platform has several buses that could be controlled
>> and tuned according to the bandwidth demand.
>>
>> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
>> Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
>> ---
>>
>> v4:
>> - Add the DT header into this patch.
>> - Pick Bjorn's r-b.
>>
>> v3:
>> - Add a reg property and move the interconnect nodes under the "soc" node.
>>
>> v2:
>> - No changes.
>>
>>  .../bindings/interconnect/qcom,qcs404.txt     | 46 ++++++++++
>>  .../dt-bindings/interconnect/qcom,qcs404.h    | 88 +++++++++++++++++++
>>  2 files changed, 134 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
>>  create mode 100644 include/dt-bindings/interconnect/qcom,qcs404.h
>>
>> diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
>> new file mode 100644
>> index 000000000000..14a827268dda
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs404.txt
>> @@ -0,0 +1,46 @@
>> +Qualcomm QCS404 Network-On-Chip interconnect driver binding
>> +-----------------------------------------------------------
>> +
>> +Required properties :
>> +- compatible : shall contain only one of the following:
>> +			"qcom,qcs404-bimc"
>> +			"qcom,qcs404-pcnoc"
>> +			"qcom,qcs404-snoc"
>> +- #interconnect-cells : should contain 1
>> +
>> +Optional properties :
>> +reg : specifies the physical base address and size of registers
>> +clocks : list of phandles and specifiers to all interconnect bus clocks
>> +clock-names : clock names should include both "bus_clk" and "bus_a_clk"
> 
> Spoke to Rob about this patch, and I don't think these properties should
> not be described as optional.
> 
> The reg isn't used unless we're implementing support for QoS, but let's
> include them in the binding as required anyways.

Ok, will do it!

> 
> Iirc the two clocks are required with the current implementation, but
> shouldn't there be an iface clock as well, for accessing the QoS
> register space?

Actually i expect this to be a list of AXI clocks of the IP blocks, whose QoS
ports we configure. For this platform, according to downstream, it would be just
<&gcc GCC_SYS_NOC_USB3_CLK>. For other platforms i see these are a few usb/ufs
clocks that should be enabled while we set QoS for usb/ufs.

> 
> PS. As I read this again, please drop _clk from the two clocks names -
> we know they are clocks...

Sure, will do it!

Thanks,
Georgi

> 
> Regards,
> Bjorn
> 
>> +
>> +Example:
>> +
>> +soc {
>> +	...
>> +	bimc: interconnect@400000 {
>> +		reg = <0x00400000 0x80000>;
>> +		compatible = "qcom,qcs404-bimc";
>> +		#interconnect-cells = <1>;
>> +		clock-names = "bus_clk", "bus_a_clk";
>> +		clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
>> +			<&rpmcc RPM_SMD_BIMC_A_CLK>;
>> +	};
>> +
>> +	pnoc: interconnect@500000 {
>> +		reg = <0x00500000 0x15080>;
>> +		compatible = "qcom,qcs404-pcnoc";
>> +		#interconnect-cells = <1>;
>> +		clock-names = "bus_clk", "bus_a_clk";
>> +		clocks = <&rpmcc RPM_SMD_PNOC_CLK>,
>> +			<&rpmcc RPM_SMD_PNOC_A_CLK>;
>> +	};
>> +
>> +	snoc: interconnect@580000 {
>> +		reg = <0x00580000 0x23080>;
>> +		compatible = "qcom,qcs404-snoc";
>> +		#interconnect-cells = <1>;
>> +		clock-names = "bus_clk", "bus_a_clk";
>> +		clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
>> +			<&rpmcc RPM_SMD_SNOC_A_CLK>;
>> +	};
>> +};
>> diff --git a/include/dt-bindings/interconnect/qcom,qcs404.h b/include/dt-bindings/interconnect/qcom,qcs404.h
>> new file mode 100644
>> index 000000000000..960f6e39c5f2
>> --- /dev/null
>> +++ b/include/dt-bindings/interconnect/qcom,qcs404.h
>> @@ -0,0 +1,88 @@
>> +/* 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_QCS404_H
>> +#define __DT_BINDINGS_INTERCONNECT_QCOM_QCS404_H
>> +
>> +#define MASTER_AMPSS_M0			0
>> +#define MASTER_OXILI			1
>> +#define MASTER_MDP_PORT0		2
>> +#define MASTER_SNOC_BIMC_1		3
>> +#define MASTER_TCU_0			4
>> +#define SLAVE_EBI_CH0			5
>> +#define SLAVE_BIMC_SNOC			6
>> +
>> +#define MASTER_SPDM			0
>> +#define MASTER_BLSP_1			1
>> +#define MASTER_BLSP_2			2
>> +#define MASTER_XI_USB_HS1		3
>> +#define MASTER_CRYPT0			4
>> +#define MASTER_SDCC_1			5
>> +#define MASTER_SDCC_2			6
>> +#define MASTER_SNOC_PCNOC		7
>> +#define MASTER_QPIC			8
>> +#define PCNOC_INT_0			9
>> +#define PCNOC_INT_2			10
>> +#define PCNOC_INT_3			11
>> +#define PCNOC_S_0			12
>> +#define PCNOC_S_1			13
>> +#define PCNOC_S_2			14
>> +#define PCNOC_S_3			15
>> +#define PCNOC_S_4			16
>> +#define PCNOC_S_6			17
>> +#define PCNOC_S_7			18
>> +#define PCNOC_S_8			19
>> +#define PCNOC_S_9			20
>> +#define PCNOC_S_10			21
>> +#define PCNOC_S_11			22
>> +#define SLAVE_SPDM			23
>> +#define SLAVE_PDM			24
>> +#define SLAVE_PRNG			25
>> +#define SLAVE_TCSR			26
>> +#define SLAVE_SNOC_CFG			27
>> +#define SLAVE_MESSAGE_RAM		28
>> +#define SLAVE_DISP_SS_CFG		29
>> +#define SLAVE_GPU_CFG			30
>> +#define SLAVE_BLSP_1			31
>> +#define SLAVE_BLSP_2			32
>> +#define SLAVE_TLMM_NORTH		33
>> +#define SLAVE_PCIE			34
>> +#define SLAVE_ETHERNET			35
>> +#define SLAVE_TLMM_EAST			36
>> +#define SLAVE_TCU			37
>> +#define SLAVE_PMIC_ARB			38
>> +#define SLAVE_SDCC_1			39
>> +#define SLAVE_SDCC_2			40
>> +#define SLAVE_TLMM_SOUTH		41
>> +#define SLAVE_USB_HS			42
>> +#define SLAVE_USB3			43
>> +#define SLAVE_CRYPTO_0_CFG		44
>> +#define SLAVE_PCNOC_SNOC		45
>> +
>> +#define MASTER_QDSS_BAM			0
>> +#define MASTER_BIMC_SNOC		1
>> +#define MASTER_PCNOC_SNOC		2
>> +#define MASTER_QDSS_ETR			3
>> +#define MASTER_EMAC			4
>> +#define MASTER_PCIE			5
>> +#define MASTER_USB3			6
>> +#define QDSS_INT			7
>> +#define SNOC_INT_0			8
>> +#define SNOC_INT_1			9
>> +#define SNOC_INT_2			10
>> +#define SLAVE_KPSS_AHB			11
>> +#define SLAVE_WCSS			12
>> +#define SLAVE_SNOC_BIMC_1		13
>> +#define SLAVE_IMEM			14
>> +#define SLAVE_SNOC_PCNOC		15
>> +#define SLAVE_QDSS_STM			16
>> +#define SLAVE_CATS_0			17
>> +#define SLAVE_CATS_1			18
>> +#define SLAVE_LPASS			19
>> +
>> +#endif

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, back to index

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-13 15:13 [PATCH v4 0/5] Add QCS404 interconnect provider driver Georgi Djakov
2019-06-13 15:13 ` [PATCH v4 1/5] dt-bindings: interconnect: Add Qualcomm QCS404 DT bindings Georgi Djakov
2019-06-25 15:00   ` Georgi Djakov
2019-07-08 19:26   ` Bjorn Andersson
2019-07-15 13:56     ` Georgi Djakov
2019-06-13 15:13 ` [PATCH v4 2/5] soc: qcom: smd-rpm: Create RPM interconnect proxy child device Georgi Djakov
2019-06-13 15:40   ` Bjorn Andersson
2019-06-13 15:13 ` [PATCH v4 3/5] interconnect: qcom: Add interconnect SMD over SMD driver Georgi Djakov
2019-06-13 15:42   ` Bjorn Andersson
2019-06-13 15:13 ` [PATCH v4 4/5] interconnect: qcom: Add QCS404 interconnect provider driver Georgi Djakov
2019-06-13 15:47   ` Bjorn Andersson
2019-06-13 15:13 ` [PATCH v4 5/5] arm64: dts: qcs404: Add interconnect provider DT nodes Georgi Djakov

Linux-ARM-MSM Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-arm-msm/0 linux-arm-msm/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-arm-msm linux-arm-msm/ https://lore.kernel.org/linux-arm-msm \
		linux-arm-msm@vger.kernel.org linux-arm-msm@archiver.kernel.org
	public-inbox-index linux-arm-msm


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-arm-msm


AGPL code for this site: git clone https://public-inbox.org/ public-inbox