Linux-i2c Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH V5 0/7] Add interconnect support to QSPI and QUP drivers
@ 2020-05-08  6:33 Akash Asthana
  2020-05-08  6:33 ` [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting Akash Asthana
                   ` (6 more replies)
  0 siblings, 7 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-08  6:33 UTC (permalink / raw)
  To: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland, robh+dt
  Cc: linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov,
	Akash Asthana

V5 depend on below patches. 
 - https://lore.kernel.org/patchwork/patch/1237642/ [Add helpers
   for enabling/disabling a path]
 - https://patchwork.kernel.org/patch/11491027/ [Add devm_of_icc_get()
   as exported API for users ]

dt-binding patch for QUP drivers.
 - https://patchwork.kernel.org/patch/11534149/ [Convert QUP bindings
        to YAML and add ICC, pin swap doc]

High level design:
 - QUP wrapper/common driver.
   Vote for QUP core on behalf of earlycon from probe.
   Remove BW vote during earlycon exit call

 - SERIAL driver.
   Vote only for CPU/CORE path because driver is in FIFO mode only
   Vote/unvote from qcom_geni_serial_pm func.
   Bump up the CPU vote from set_termios call based on real time need

 - I2C driver.
   Vote for CORE/CPU/DDR path
   Vote/unvote from runtime resume/suspend callback
   As bus speed for I2C is fixed from probe itself no need for bump up.

 - SPI QUP driver.
   Vote only for CPU/CORE path because driver is in FIFO mode only
   Vote/unvote from runtime resume/suspend callback
   Bump up CPU vote based on real time need per transfer.

 - QSPI driver.
   Vote only for CPU path
   Vote/unvote from runtime resume/suspend callback
   Bump up CPU vote based on real time need per transfer.

Changes in V2:
 - Add devm_of_icc_get() API interconnect core.
 - Add ICC support to common driver to fix earlyconsole crash.

Changes in V3:
 - Define common ICC APIs in geni-se driver and use it across geni based
   I2C,SPI and UART driver.

Changes in V4:
 - Add a patch to ICC core to scale peak requirement
   as twice of average if it is not mentioned explicilty.

Changes in V5:
 - As per Georgi's suggestion removed patch from ICC core for assuming
   peak_bw as twice of average when it's not mentioned, instead assume it
   equall to avg_bw and keep this assumption in ICC client itself.
 - As per Matthias suggestion use enum for GENI QUP ICC paths.

Akash Asthana (7):
  soc: qcom: geni: Support for ICC voting
  soc: qcom-geni-se: Add interconnect support to fix earlycon crash
  i2c: i2c-qcom-geni: Add interconnect support
  spi: spi-geni-qcom: Add interconnect support
  tty: serial: qcom_geni_serial: Add interconnect support
  spi: spi-qcom-qspi: Add interconnect support
  arm64: dts: sc7180: Add interconnect for QUP and QSPI

 arch/arm64/boot/dts/qcom/sc7180.dtsi  | 127 ++++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-qcom-geni.c    |  29 ++++++-
 drivers/soc/qcom/qcom-geni-se.c       | 155 ++++++++++++++++++++++++++++++++++
 drivers/spi/spi-geni-qcom.c           |  32 ++++++-
 drivers/spi/spi-qcom-qspi.c           |  59 ++++++++++++-
 drivers/tty/serial/qcom_geni_serial.c |  38 ++++++++-
 include/linux/qcom-geni-se.h          |  44 ++++++++++
 7 files changed, 478 insertions(+), 6 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting
  2020-05-08  6:33 [PATCH V5 0/7] Add interconnect support to QSPI and QUP drivers Akash Asthana
@ 2020-05-08  6:33 ` Akash Asthana
  2020-05-08 17:13   ` Matthias Kaehlcke
  2020-05-08 19:03   ` Matthias Kaehlcke
  2020-05-08  6:33 ` [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash Akash Asthana
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-08  6:33 UTC (permalink / raw)
  To: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland, robh+dt
  Cc: linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov,
	Akash Asthana

Add necessary macros and structure variables to support ICC BW
voting from individual SE drivers.

Signed-off-by: Akash Asthana <akashast@codeaurora.org>
---
Changes in V2:
 - As per Bjorn's comment dropped enums for ICC paths, given the three
   paths individual members

Changes in V3:
 - Add geni_icc_get, geni_icc_vote_on and geni_icc_vote_off as helper API.
 - Add geni_icc_path structure in common header

Changes in V4:
 - As per Bjorn's comment print error message in geni_icc_get if return
   value is not -EPROBE_DEFER.
 - As per Bjorn's comment remove NULL on path before calling icc_set_bw
   API.
 - As per Bjorn's comment drop __func__ print.
 - As per Matthias's comment, make ICC path a array instead of individual
   member entry in geni_se struct.

Note: I have ignored below check patch suggestion because it was throwing
      compilation error as 'icc_ddr' is not compile time comstant.

WARNING: char * array declaration might be better as static const
 - FILE: drivers/soc/qcom/qcom-geni-se.c:726:
 - const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};

Changes in V5:
 - As per Matthias's comment defined enums for ICC paths.
 - Integrate icc_enable/disable with power on/off call for driver.
 - As per Matthias's comment added icc_path_names array to print icc path name
   in failure case.
 - As per Georgi's suggestion assume peak_bw = avg_bw if not mentioned.

 drivers/soc/qcom/qcom-geni-se.c | 92 +++++++++++++++++++++++++++++++++++++++++
 include/linux/qcom-geni-se.h    | 42 +++++++++++++++++++
 2 files changed, 134 insertions(+)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 7d622ea..63403bf 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -92,6 +92,9 @@ struct geni_wrapper {
 	struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
 };
 
+static const char * const icc_path_names[] = {"qup-core", "qup-config",
+								"qup-memory"};
+
 #define QUP_HW_VER_REG			0x4
 
 /* Common SE registers */
@@ -720,6 +723,95 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
 }
 EXPORT_SYMBOL(geni_se_rx_dma_unprep);
 
+int geni_icc_get(struct geni_se *se, const char *icc_ddr)
+{
+	int i, icc_err;
+	const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
+
+	for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
+		if (!icc_names[i])
+			continue;
+
+		se->icc_paths[i].path = devm_of_icc_get(se->dev, icc_names[i]);
+		if (IS_ERR(se->icc_paths[i].path))
+			goto icc_get_failure;
+	}
+
+	return 0;
+
+icc_get_failure:
+	icc_err = PTR_ERR(se->icc_paths[i].path);
+	if (icc_err != -EPROBE_DEFER)
+		dev_err_ratelimited(se->dev, "Failed to get ICC path:%s, ret:%d\n",
+					icc_names[i], icc_err);
+	return icc_err;
+
+}
+EXPORT_SYMBOL(geni_icc_get);
+
+void geni_icc_bw_init(struct geni_icc_path *icc_paths, unsigned int avg_bw,
+			unsigned int peak_bw)
+{
+	if (!peak_bw)
+		peak_bw = avg_bw;
+	icc_paths->avg_bw = avg_bw;
+	icc_paths->peak_bw = peak_bw;
+}
+EXPORT_SYMBOL(geni_icc_bw_init);
+
+int geni_icc_set_bw(struct geni_se *se)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
+		ret = icc_set_bw(se->icc_paths[i].path,
+			se->icc_paths[i].avg_bw, se->icc_paths[i].peak_bw);
+		if (ret) {
+			dev_err_ratelimited(se->dev, "ICC BW voting failed on path:%s, ret:%d\n",
+					icc_path_names[i], ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(geni_icc_set_bw);
+
+/* To do: Replace this by icc_bulk_enable once it's implemented in ICC core */
+int geni_icc_enable(struct geni_se *se)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
+		ret = icc_enable(se->icc_paths[i].path);
+		if (ret) {
+			dev_err_ratelimited(se->dev, "ICC enable failed on path:%s, ret:%d\n",
+					icc_path_names[i], ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(geni_icc_enable);
+
+int geni_icc_disable(struct geni_se *se)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
+		ret = icc_disable(se->icc_paths[i].path);
+		if (ret) {
+			dev_err_ratelimited(se->dev, "ICC disable failed on path:%s, ret:%d\n",
+					icc_path_names[i], ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(geni_icc_disable);
+
 static int geni_se_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h
index dd46494..7afa08d 100644
--- a/include/linux/qcom-geni-se.h
+++ b/include/linux/qcom-geni-se.h
@@ -6,6 +6,8 @@
 #ifndef _LINUX_QCOM_GENI_SE
 #define _LINUX_QCOM_GENI_SE
 
+#include <linux/interconnect.h>
+
 /* Transfer mode supported by GENI Serial Engines */
 enum geni_se_xfer_mode {
 	GENI_SE_INVALID,
@@ -25,6 +27,18 @@ enum geni_se_protocol_type {
 struct geni_wrapper;
 struct clk;
 
+enum geni_icc_path_index {
+	GENI_TO_CORE,
+	CPU_TO_GENI,
+	GENI_TO_DDR
+};
+
+struct geni_icc_path {
+	struct icc_path *path;
+	unsigned int avg_bw;
+	unsigned int peak_bw;
+};
+
 /**
  * struct geni_se - GENI Serial Engine
  * @base:		Base Address of the Serial Engine's register block
@@ -33,6 +47,7 @@ struct clk;
  * @clk:		Handle to the core serial engine clock
  * @num_clk_levels:	Number of valid clock levels in clk_perf_tbl
  * @clk_perf_tbl:	Table of clock frequency input to serial engine clock
+ * @icc_paths:		Array of ICC paths for SE
  */
 struct geni_se {
 	void __iomem *base;
@@ -41,6 +56,7 @@ struct geni_se {
 	struct clk *clk;
 	unsigned int num_clk_levels;
 	unsigned long *clk_perf_tbl;
+	struct geni_icc_path icc_paths[3];
 };
 
 /* Common SE registers */
@@ -229,6 +245,21 @@ struct geni_se {
 #define GENI_SE_VERSION_MINOR(ver) ((ver & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT)
 #define GENI_SE_VERSION_STEP(ver) (ver & HW_VER_STEP_MASK)
 
+/*
+ * Define bandwidth thresholds that cause the underlying Core 2X interconnect
+ * clock to run at the named frequency. These baseline values are recommended
+ * by the hardware team, and are not dynamically scaled with GENI bandwidth
+ * beyond basic on/off.
+ */
+#define CORE_2X_19_2_MHZ		960
+#define CORE_2X_50_MHZ			2500
+#define CORE_2X_100_MHZ			5000
+#define CORE_2X_150_MHZ			7500
+#define CORE_2X_200_MHZ			10000
+#define CORE_2X_236_MHZ			16383
+
+#define GENI_DEFAULT_BW			Bps_to_icc(1000)
+
 #if IS_ENABLED(CONFIG_QCOM_GENI_SE)
 
 u32 geni_se_get_qup_hw_version(struct geni_se *se);
@@ -416,5 +447,16 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
 void geni_se_tx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len);
 
 void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len);
+
+int geni_icc_get(struct geni_se *se, const char *icc_ddr);
+
+int geni_icc_set_bw(struct geni_se *se);
+
+void geni_icc_bw_init(struct geni_icc_path *icc_paths, unsigned int avg_bw,
+			unsigned int peak_bw);
+
+int geni_icc_enable(struct geni_se *se);
+
+int geni_icc_disable(struct geni_se *se);
 #endif
 #endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash
  2020-05-08  6:33 [PATCH V5 0/7] Add interconnect support to QSPI and QUP drivers Akash Asthana
  2020-05-08  6:33 ` [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting Akash Asthana
@ 2020-05-08  6:33 ` Akash Asthana
  2020-05-08 17:59   ` Matthias Kaehlcke
  2020-05-09 12:11   ` Andy Shevchenko
  2020-05-08  6:33 ` [PATCH V5 3/7] i2c: i2c-qcom-geni: Add interconnect support Akash Asthana
                   ` (4 subsequent siblings)
  6 siblings, 2 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-08  6:33 UTC (permalink / raw)
  To: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland, robh+dt
  Cc: linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov,
	Akash Asthana

QUP core clock is shared among all the SE drivers present on particular
QUP wrapper, the system will reset(unclocked access) if earlycon used after
QUP core clock is put to 0 from other SE drivers before real console comes
up.

As earlycon can't vote for it's QUP core need, to fix this add ICC
support to common/QUP wrapper driver and put vote for QUP core from
probe on behalf of earlycon and remove vote during earlycon exit call.

Signed-off-by: Akash Asthana <akashast@codeaurora.org>
Reported-by: Matthias Kaehlcke <mka@chromium.org>
---
Change in V3:
 - Add geni_remove_earlycon_icc_vote API that will be used by earlycon
   exit function to remove ICC vote for earlyconsole.
 - Remove suspend/resume hook for geni-se driver as we are no longer
   removing earlyconsole ICC vote from system suspend, we are removing
   from earlycon exit.

Change in V4:
 - As per Matthias comment make 'earlycon_wrapper' as static structure.

Changes in V5:
 - Vote for core path only after checking whether "qcom_geni" earlycon is
   actually present or not by traversing over structure "console_drivers".

 drivers/soc/qcom/qcom-geni-se.c       | 63 +++++++++++++++++++++++++++++++++++
 drivers/tty/serial/qcom_geni_serial.c |  7 ++++
 include/linux/qcom-geni-se.h          |  2 ++
 3 files changed, 72 insertions(+)

diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
index 63403bf..66fe6f2 100644
--- a/drivers/soc/qcom/qcom-geni-se.c
+++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -3,6 +3,7 @@
 
 #include <linux/acpi.h>
 #include <linux/clk.h>
+#include <linux/console.h>
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
@@ -90,11 +91,14 @@ struct geni_wrapper {
 	struct device *dev;
 	void __iomem *base;
 	struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
+	struct geni_icc_path to_core;
 };
 
 static const char * const icc_path_names[] = {"qup-core", "qup-config",
 								"qup-memory"};
 
+static struct geni_wrapper *earlycon_wrapper;
+
 #define QUP_HW_VER_REG			0x4
 
 /* Common SE registers */
@@ -812,11 +816,33 @@ int geni_icc_disable(struct geni_se *se)
 }
 EXPORT_SYMBOL(geni_icc_disable);
 
+void geni_remove_earlycon_icc_vote(void)
+{
+	struct geni_wrapper *wrapper = earlycon_wrapper;
+	struct device_node *parent = of_get_next_parent(wrapper->dev->of_node);
+	struct device_node *child;
+
+	for_each_child_of_node(parent, child) {
+		if (of_device_is_compatible(child, "qcom,geni-se-qup")) {
+			wrapper = platform_get_drvdata(of_find_device_by_node(
+					child));
+			icc_put(wrapper->to_core.path);
+			wrapper->to_core.path = NULL;
+		}
+	}
+	of_node_put(parent);
+
+	earlycon_wrapper = NULL;
+}
+EXPORT_SYMBOL(geni_remove_earlycon_icc_vote);
+
 static int geni_se_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct resource *res;
 	struct geni_wrapper *wrapper;
+	struct console *bcon;
+	int earlycon_present = 0;
 	int ret;
 
 	wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
@@ -839,6 +865,43 @@ static int geni_se_probe(struct platform_device *pdev)
 		}
 	}
 
+#ifdef CONFIG_SERIAL_EARLYCON
+	if (console_drivers)
+		for_each_console(bcon)
+			if (!strcmp(bcon->name, "qcom_geni")) {
+				earlycon_present = 1;
+				break;
+			}
+	if (!earlycon_present)
+		goto exit;
+
+	wrapper->to_core.path = devm_of_icc_get(dev, "qup-core");
+	if (IS_ERR(wrapper->to_core.path))
+		return PTR_ERR(wrapper->to_core.path);
+	/*
+	 * Put minmal BW request on core clocks on behalf of early console.
+	 * The vote will be removed earlycon exit function.
+	 *
+	 * Note: We are putting vote on each QUP wrapper instead only to which
+	 * earlycon is connected because QUP core clock of different wrapper
+	 * share same voltage domain. If core1 is put to 0, then core2 will
+	 * also run at 0, if not voted. Default ICC vote will be removed ASA
+	 * we touch any of the core clock.
+	 * core1 = core2 = max(core1, core2)
+	 */
+	ret = icc_set_bw(wrapper->to_core.path, GENI_DEFAULT_BW,
+							GENI_DEFAULT_BW);
+	if (ret) {
+		dev_err(&pdev->dev, "%s: ICC BW voting failed for core\n",
+			__func__);
+		return ret;
+	}
+
+	if (of_get_compatible_child(pdev->dev.of_node, "qcom,geni-debug-uart"))
+		earlycon_wrapper = wrapper;
+	of_node_put(pdev->dev.of_node);
+#endif
+exit:
 	dev_set_drvdata(dev, wrapper);
 	dev_dbg(dev, "GENI SE Driver probed\n");
 	return devm_of_platform_populate(dev);
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 6119090..8c5d97c 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1090,6 +1090,12 @@ static void qcom_geni_serial_earlycon_write(struct console *con,
 	__qcom_geni_serial_console_write(&dev->port, s, n);
 }
 
+static int qcom_geni_serial_earlycon_exit(struct console *con)
+{
+	geni_remove_earlycon_icc_vote();
+	return 0;
+}
+
 static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev,
 								const char *opt)
 {
@@ -1135,6 +1141,7 @@ static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev,
 	writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
 
 	dev->con->write = qcom_geni_serial_earlycon_write;
+	dev->con->exit = qcom_geni_serial_earlycon_exit;
 	dev->con->setup = NULL;
 	return 0;
 }
diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h
index 7afa08d..51e9e9b 100644
--- a/include/linux/qcom-geni-se.h
+++ b/include/linux/qcom-geni-se.h
@@ -458,5 +458,7 @@ void geni_icc_bw_init(struct geni_icc_path *icc_paths, unsigned int avg_bw,
 int geni_icc_enable(struct geni_se *se);
 
 int geni_icc_disable(struct geni_se *se);
+
+void geni_remove_earlycon_icc_vote(void);
 #endif
 #endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* [PATCH V5 3/7] i2c: i2c-qcom-geni: Add interconnect support
  2020-05-08  6:33 [PATCH V5 0/7] Add interconnect support to QSPI and QUP drivers Akash Asthana
  2020-05-08  6:33 ` [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting Akash Asthana
  2020-05-08  6:33 ` [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash Akash Asthana
@ 2020-05-08  6:33 ` Akash Asthana
  2020-05-08 18:16   ` Matthias Kaehlcke
  2020-05-15 10:03   ` Wolfram Sang
  2020-05-08  6:33 ` [PATCH V5 4/7] spi: spi-geni-qcom: " Akash Asthana
                   ` (3 subsequent siblings)
  6 siblings, 2 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-08  6:33 UTC (permalink / raw)
  To: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland, robh+dt
  Cc: linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov,
	Akash Asthana

Get the interconnect paths for I2C based Serial Engine device
and vote according to the bus speed of the driver.

Signed-off-by: Akash Asthana <akashast@codeaurora.org>
---
Changes in V2:
 - As per Bjorn's comment, removed se == NULL check from geni_i2c_icc_get
 - As per Bjorn's comment, removed code to set se->icc_path* to NULL in failure
 - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
   path handle
 - As per Matthias comment, added error handling for icc_set_bw call

Changes in V3:
 - As per Matthias comment, use common library APIs defined in geni-se
   driver for ICC functionality.

Changes in V4:
 - Move peak_bw guess as twice of avg_bw if nothing mentioned explicitly
   to ICC core.

Changes in V5:
 - Use icc_enable/disable in power on/off call.

 drivers/i2c/busses/i2c-qcom-geni.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 18d1e4f..f2e786d 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -557,6 +557,25 @@ static int geni_i2c_probe(struct platform_device *pdev)
 	gi2c->adap.dev.of_node = dev->of_node;
 	strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
 
+	ret = geni_icc_get(&gi2c->se, "qup-memory");
+	if (ret)
+		return ret;
+	/*
+	 * Set the bus quota for core and cpu to a reasonable value for
+	 * register access.
+	 * Set quota for DDR based on bus speed.
+	 */
+	geni_icc_bw_init(&gi2c->se.icc_paths[GENI_TO_CORE], GENI_DEFAULT_BW,
+				0);
+	geni_icc_bw_init(&gi2c->se.icc_paths[CPU_TO_GENI], GENI_DEFAULT_BW,
+				0);
+	geni_icc_bw_init(&gi2c->se.icc_paths[GENI_TO_DDR],
+				Bps_to_icc(gi2c->clk_freq_out), 0);
+
+	ret = geni_icc_set_bw(&gi2c->se);
+	if (ret)
+		return ret;
+
 	ret = geni_se_resources_on(&gi2c->se);
 	if (ret) {
 		dev_err(dev, "Error turning on resources %d\n", ret);
@@ -579,6 +598,10 @@ static int geni_i2c_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	ret = geni_icc_disable(&gi2c->se);
+	if (ret)
+		return ret;
+
 	dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth);
 
 	gi2c->suspended = 1;
@@ -623,7 +646,7 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)
 		gi2c->suspended = 1;
 	}
 
-	return 0;
+	return geni_icc_disable(&gi2c->se);
 }
 
 static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
@@ -631,6 +654,10 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
 	int ret;
 	struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
 
+	ret = geni_icc_enable(&gi2c->se);
+	if (ret)
+		return ret;
+
 	ret = geni_se_resources_on(&gi2c->se);
 	if (ret)
 		return ret;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* [PATCH V5 4/7] spi: spi-geni-qcom: Add interconnect support
  2020-05-08  6:33 [PATCH V5 0/7] Add interconnect support to QSPI and QUP drivers Akash Asthana
                   ` (2 preceding siblings ...)
  2020-05-08  6:33 ` [PATCH V5 3/7] i2c: i2c-qcom-geni: Add interconnect support Akash Asthana
@ 2020-05-08  6:33 ` Akash Asthana
  2020-05-08 10:16   ` Mark Brown
  2020-05-08 18:25   ` Matthias Kaehlcke
  2020-05-08  6:33 ` [PATCH V5 5/7] tty: serial: qcom_geni_serial: " Akash Asthana
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-08  6:33 UTC (permalink / raw)
  To: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland, robh+dt
  Cc: linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov,
	Akash Asthana

Get the interconnect paths for SPI based Serial Engine device
and vote according to the current bus speed of the driver.

Signed-off-by: Akash Asthana <akashast@codeaurora.org>
---
Changes in V2:
 - As per Bjorn's comment, removed se == NULL check from geni_spi_icc_get
 - As per Bjorn's comment, removed code to set se->icc_path* to NULL in failure
 - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
   path handle
 - As per Matthias comment, added error handling for icc_set_bw call

Changes in V3:
 - As per Matthias's comment, use helper ICC function from geni-se driver.

Changes in V4:
 - Move peak_bw guess as twice of avg_bw if nothing mentioned explicitly
   to ICC core.

Changes in V5:
 - Use icc_enable/disable in power on/off call.
 - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
   from probe so that when resume/icc_enable is called NOC are running at
   some non-zero value. No need to call icc_disable after BW vote because
   device will resume and suspend before probe return and will leave ICC in
   disabled state.

 drivers/spi/spi-geni-qcom.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index c397242..5dfa1fb 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -234,6 +234,13 @@ static int setup_fifo_params(struct spi_device *spi_slv,
 		return ret;
 	}
 
+	/* Set BW quota for CPU as driver supports FIFO mode only. */
+	geni_icc_bw_init(&se->icc_paths[CPU_TO_GENI],
+				Bps_to_icc(mas->cur_speed_hz), 0);
+	ret = geni_icc_set_bw(se);
+	if (ret)
+		return ret;
+
 	clk_sel = idx & CLK_SEL_MSK;
 	m_clk_cfg = (div << CLK_DIV_SHFT) | SER_CLK_EN;
 	spi_setup_word_len(mas, spi_slv->mode, spi_slv->bits_per_word);
@@ -578,6 +585,19 @@ static int spi_geni_probe(struct platform_device *pdev)
 	spin_lock_init(&mas->lock);
 	pm_runtime_enable(dev);
 
+	ret = geni_icc_get(&mas->se, NULL);
+	if (ret)
+		goto spi_geni_probe_runtime_disable;
+	/* Set the bus quota to a reasonable value for register access */
+	geni_icc_bw_init(&mas->se.icc_paths[GENI_TO_CORE],
+			Bps_to_icc(CORE_2X_50_MHZ), 0);
+	geni_icc_bw_init(&mas->se.icc_paths[CPU_TO_GENI], GENI_DEFAULT_BW, 0);
+
+	/* Set BW for register access */
+	ret = geni_icc_set_bw(&mas->se);
+	if (ret)
+		goto spi_geni_probe_runtime_disable;
+
 	ret = spi_geni_init(mas);
 	if (ret)
 		goto spi_geni_probe_runtime_disable;
@@ -616,14 +636,24 @@ static int __maybe_unused spi_geni_runtime_suspend(struct device *dev)
 {
 	struct spi_master *spi = dev_get_drvdata(dev);
 	struct spi_geni_master *mas = spi_master_get_devdata(spi);
+	int ret;
+
+	ret = geni_se_resources_off(&mas->se);
+	if (ret)
+		return ret;
 
-	return geni_se_resources_off(&mas->se);
+	return geni_icc_disable(&mas->se);
 }
 
 static int __maybe_unused spi_geni_runtime_resume(struct device *dev)
 {
 	struct spi_master *spi = dev_get_drvdata(dev);
 	struct spi_geni_master *mas = spi_master_get_devdata(spi);
+	int ret;
+
+	ret = geni_icc_enable(&mas->se);
+	if (ret)
+		return ret;
 
 	return geni_se_resources_on(&mas->se);
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* [PATCH V5 5/7] tty: serial: qcom_geni_serial: Add interconnect support
  2020-05-08  6:33 [PATCH V5 0/7] Add interconnect support to QSPI and QUP drivers Akash Asthana
                   ` (3 preceding siblings ...)
  2020-05-08  6:33 ` [PATCH V5 4/7] spi: spi-geni-qcom: " Akash Asthana
@ 2020-05-08  6:33 ` Akash Asthana
  2020-05-08 18:38   ` Matthias Kaehlcke
  2020-05-08  6:33 ` [PATCH V5 6/7] spi: spi-qcom-qspi: " Akash Asthana
  2020-05-08  6:33 ` [PATCH V5 7/7] arm64: dts: sc7180: Add interconnect for QUP and QSPI Akash Asthana
  6 siblings, 1 reply; 27+ messages in thread
From: Akash Asthana @ 2020-05-08  6:33 UTC (permalink / raw)
  To: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland, robh+dt
  Cc: linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov,
	Akash Asthana

Get the interconnect paths for Uart based Serial Engine device
and vote according to the baud rate requirement of the driver.

Signed-off-by: Akash Asthana <akashast@codeaurora.org>
---
Changes in V2:
 - As per Bjorn's comment, removed se == NULL check from geni_serial_icc_get
 - As per Bjorn's comment, removed code to set se->icc_path* to NULL in failure
 - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
   path handle
 - As per Matthias comment, added error handling for icc_set_bw call

Changes in V3:
 - As per Matthias comment, use common library APIs defined in geni-se
   driver for ICC functionality.

Changes in V4:
 - As per Mark's comment move peak_bw guess as twice of avg_bw if
   nothing mentioned explicitly to ICC core.
 - As per Matthias's comment select core clock BW based on baud rate.
   If it's less than 115200 go for GENI_DEFAULT_BW else CORE_2X_50_MHZ

Changes in V5:
 - Add icc_enable/disable to power on/off call.
 - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
   from probe so that when resume/icc_enable is called NOC are running at
   some non-zero value. No need to call icc_disable after BW vote because
   console devices are expected to be in active state from the probe itself
   and qcom_geni_serial_pm(STATE_OFF) will be called for non-console ones.

 drivers/tty/serial/qcom_geni_serial.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 8c5d97c..2a1da36 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -944,6 +944,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
 	unsigned long clk_rate;
 	u32 ver, sampling_rate;
+	unsigned int avg_bw_core;
 
 	qcom_geni_serial_stop_rx(uport);
 	/* baud rate */
@@ -965,6 +966,16 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 	ser_clk_cfg = SER_CLK_EN;
 	ser_clk_cfg |= clk_div << CLK_DIV_SHFT;
 
+	/*
+	 * Bump up BW vote on CPU and CORE path as driver supports FIFO mode
+	 * only.
+	 */
+	avg_bw_core = (baud > 115200) ? Bps_to_icc(CORE_2X_50_MHZ)
+						: GENI_DEFAULT_BW;
+	geni_icc_bw_init(&port->se.icc_paths[GENI_TO_CORE], avg_bw_core, 0);
+	geni_icc_bw_init(&port->se.icc_paths[CPU_TO_GENI], Bps_to_icc(baud), 0);
+	geni_icc_set_bw(&port->se);
+
 	/* parity */
 	tx_trans_cfg = readl(uport->membase + SE_UART_TX_TRANS_CFG);
 	tx_parity_cfg = readl(uport->membase + SE_UART_TX_PARITY_CFG);
@@ -1202,11 +1213,14 @@ static void qcom_geni_serial_pm(struct uart_port *uport,
 	if (old_state == UART_PM_STATE_UNDEFINED)
 		old_state = UART_PM_STATE_OFF;
 
-	if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
+	if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF) {
+		geni_icc_enable(&port->se);
 		geni_se_resources_on(&port->se);
-	else if (new_state == UART_PM_STATE_OFF &&
-			old_state == UART_PM_STATE_ON)
+	} else if (new_state == UART_PM_STATE_OFF &&
+			old_state == UART_PM_STATE_ON) {
 		geni_se_resources_off(&port->se);
+		geni_icc_disable(&port->se);
+	}
 }
 
 static const struct uart_ops qcom_geni_console_pops = {
@@ -1304,6 +1318,17 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
 			return -ENOMEM;
 	}
 
+	ret = geni_icc_get(&port->se, NULL);
+	if (ret)
+		return ret;
+	geni_icc_bw_init(&port->se.icc_paths[GENI_TO_CORE], GENI_DEFAULT_BW, 0);
+	geni_icc_bw_init(&port->se.icc_paths[CPU_TO_GENI], GENI_DEFAULT_BW, 0);
+
+	/* Set BW for register access */
+	ret = geni_icc_set_bw(&port->se);
+	if (ret)
+		return ret;
+
 	port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
 			"qcom_geni_serial_%s%d",
 			uart_console(uport) ? "console" : "uart", uport->line);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* [PATCH V5 6/7] spi: spi-qcom-qspi: Add interconnect support
  2020-05-08  6:33 [PATCH V5 0/7] Add interconnect support to QSPI and QUP drivers Akash Asthana
                   ` (4 preceding siblings ...)
  2020-05-08  6:33 ` [PATCH V5 5/7] tty: serial: qcom_geni_serial: " Akash Asthana
@ 2020-05-08  6:33 ` Akash Asthana
  2020-05-08 10:16   ` Mark Brown
  2020-05-08 18:53   ` Matthias Kaehlcke
  2020-05-08  6:33 ` [PATCH V5 7/7] arm64: dts: sc7180: Add interconnect for QUP and QSPI Akash Asthana
  6 siblings, 2 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-08  6:33 UTC (permalink / raw)
  To: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland, robh+dt
  Cc: linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov,
	Akash Asthana

Get the interconnect paths for QSPI device and vote according to the
current bus speed of the driver.

Signed-off-by: Akash Asthana <akashast@codeaurora.org>
---
Changes in V2:
 - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
   path handle
 - As per Matthias comment, added error handling for icc_set_bw call

Changes in V3:
 - No Change.

Changes in V4:
 - As per Mark's comment move peak_bw guess as twice of avg_bw if
   nothing mentioned explicitly to ICC core.

Changes in V5:
 - Add icc_enable/disable to power on/off call.
 - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
   from probe so that when resume/icc_enable is called NOC are running at
   some non-zero value.

 drivers/spi/spi-qcom-qspi.c | 59 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c
index 3c4f83b..6e299f4 100644
--- a/drivers/spi/spi-qcom-qspi.c
+++ b/drivers/spi/spi-qcom-qspi.c
@@ -2,6 +2,7 @@
 // Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
 
 #include <linux/clk.h>
+#include <linux/interconnect.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -139,7 +140,10 @@ struct qcom_qspi {
 	struct device *dev;
 	struct clk_bulk_data *clks;
 	struct qspi_xfer xfer;
-	/* Lock to protect xfer and IRQ accessed registers */
+	struct icc_path *icc_path_cpu_to_qspi;
+	unsigned int avg_bw_cpu;
+	unsigned int peak_bw_cpu;
+	/* Lock to protect data accessed by IRQs */
 	spinlock_t lock;
 };
 
@@ -241,6 +245,20 @@ static int qcom_qspi_transfer_one(struct spi_master *master,
 		return ret;
 	}
 
+	/*
+	 * Set BW quota for CPU as driver supports FIFO mode only.
+	 * We don't have explicit peak requirement so keep it equal to avg_bw.
+	 */
+	ctrl->avg_bw_cpu = Bps_to_icc(speed_hz);
+	ctrl->peak_bw_cpu = ctrl->avg_bw_cpu;
+	ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, ctrl->avg_bw_cpu,
+		ctrl->peak_bw_cpu);
+	if (ret) {
+		dev_err(ctrl->dev, "%s: ICC BW voting failed for cpu\n",
+			__func__);
+		return ret;
+	}
+
 	spin_lock_irqsave(&ctrl->lock, flags);
 
 	/* We are half duplex, so either rx or tx will be set */
@@ -458,6 +476,29 @@ static int qcom_qspi_probe(struct platform_device *pdev)
 	if (ret)
 		goto exit_probe_master_put;
 
+	ctrl->icc_path_cpu_to_qspi = devm_of_icc_get(dev, "qspi-config");
+	if (IS_ERR(ctrl->icc_path_cpu_to_qspi)) {
+		ret = PTR_ERR(ctrl->icc_path_cpu_to_qspi);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Failed to get cpu path, ret:%d\n", ret);
+		goto exit_probe_master_put;
+	}
+	/* Set BW vote for register access */
+	ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, Bps_to_icc(1000),
+				Bps_to_icc(1000));
+	if (ret) {
+		dev_err(ctrl->dev, "%s: ICC BW voting failed for cpu ret:%d\n",
+				__func__, ret);
+		goto exit_probe_master_put;
+	}
+
+	ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
+	if (ret) {
+		dev_err(ctrl->dev, "%s: ICC disable failed for cpu ret:%d\n",
+				__func__, ret);
+		goto exit_probe_master_put;
+	}
+
 	ret = platform_get_irq(pdev, 0);
 	if (ret < 0)
 		goto exit_probe_master_put;
@@ -511,9 +552,17 @@ static int __maybe_unused qcom_qspi_runtime_suspend(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct qcom_qspi *ctrl = spi_master_get_devdata(master);
+	int ret;
 
 	clk_bulk_disable_unprepare(QSPI_NUM_CLKS, ctrl->clks);
 
+	ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
+	if (ret) {
+		dev_err_ratelimited(ctrl->dev, "%s: ICC disable failed for cpu ret:%d\n",
+			__func__, ret);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -521,6 +570,14 @@ static int __maybe_unused qcom_qspi_runtime_resume(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct qcom_qspi *ctrl = spi_master_get_devdata(master);
+	int ret;
+
+	ret = icc_enable(ctrl->icc_path_cpu_to_qspi);
+	if (ret) {
+		dev_err_ratelimited(ctrl->dev, "%s: ICC enable failed for cpu ret:%d\n",
+			__func__, ret);
+		return ret;
+	}
 
 	return clk_bulk_prepare_enable(QSPI_NUM_CLKS, ctrl->clks);
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* [PATCH V5 7/7] arm64: dts: sc7180: Add interconnect for QUP and QSPI
  2020-05-08  6:33 [PATCH V5 0/7] Add interconnect support to QSPI and QUP drivers Akash Asthana
                   ` (5 preceding siblings ...)
  2020-05-08  6:33 ` [PATCH V5 6/7] spi: spi-qcom-qspi: " Akash Asthana
@ 2020-05-08  6:33 ` Akash Asthana
  6 siblings, 0 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-08  6:33 UTC (permalink / raw)
  To: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland, robh+dt
  Cc: linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov,
	Akash Asthana

Add interconnect ports for GENI QUPs and QSPI to set bus capabilities.

Signed-off-by: Akash Asthana <akashast@codeaurora.org>
---
Changes in V2:
 - As per Bjorn's comment, ignoring 80 char limit in defining interconnects
   paths.

Changes in V3:
 - No change.

Change in V4:
 - No change.

Changes in V5:
 - No change.

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

diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index 4216b57..21ed9a1 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -506,6 +506,8 @@
 			#size-cells = <2>;
 			ranges;
 			iommus = <&apps_smmu 0x43 0x0>;
+			interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>;
+			interconnect-names = "qup-core";
 			status = "disabled";
 
 			i2c0: i2c@880000 {
@@ -518,6 +520,11 @@
 				interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>,
+						<&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -531,6 +538,9 @@
 				interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -542,6 +552,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart0_default>;
 				interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -555,6 +568,11 @@
 				interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>,
+						<&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -568,6 +586,9 @@
 				interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -579,6 +600,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart1_default>;
 				interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -592,6 +616,11 @@
 				interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>,
+						<&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -603,6 +632,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart2_default>;
 				interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -616,6 +648,11 @@
 				interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>,
+						<&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -629,6 +666,9 @@
 				interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -640,6 +680,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart3_default>;
 				interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -653,6 +696,11 @@
 				interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>,
+						<&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -664,6 +712,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart4_default>;
 				interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -677,6 +728,11 @@
 				interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>,
+						<&aggre1_noc MASTER_QUP_0 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -690,6 +746,9 @@
 				interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -701,6 +760,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart5_default>;
 				interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_0 &qup_virt SLAVE_QUP_CORE_0>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_0>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 		};
@@ -715,6 +777,8 @@
 			#size-cells = <2>;
 			ranges;
 			iommus = <&apps_smmu 0x4c3 0x0>;
+			interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>;
+			interconnect-names = "qup-core";
 			status = "disabled";
 
 			i2c6: i2c@a80000 {
@@ -727,6 +791,11 @@
 				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>,
+						<&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -740,6 +809,9 @@
 				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -751,6 +823,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart6_default>;
 				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -764,6 +839,11 @@
 				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>,
+						<&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -775,6 +855,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart7_default>;
 				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -788,6 +871,11 @@
 				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>,
+						<&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -801,6 +889,9 @@
 				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -812,6 +903,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart8_default>;
 				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -825,6 +919,11 @@
 				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>,
+						<&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -836,6 +935,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart9_default>;
 				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -849,6 +951,11 @@
 				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>,
+						<&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -862,6 +969,9 @@
 				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -873,6 +983,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart10_default>;
 				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -886,6 +999,11 @@
 				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>,
+						<&aggre2_noc MASTER_QUP_1 &mc_virt SLAVE_EBI1>;
+				interconnect-names = "qup-core", "qup-config",
+							"qup-memory";
 				status = "disabled";
 			};
 
@@ -899,6 +1017,9 @@
 				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 
@@ -910,6 +1031,9 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart11_default>;
 				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&qup_virt MASTER_QUP_CORE_1 &qup_virt SLAVE_QUP_CORE_1>,
+						<&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_QUP_1>;
+				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
 		};
@@ -1885,6 +2009,9 @@
 			clocks = <&gcc GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
 				 <&gcc GCC_QSPI_CORE_CLK>;
 			clock-names = "iface", "core";
+			interconnects = <&gem_noc MASTER_APPSS_PROC
+					&config_noc SLAVE_QSPI_0>;
+			interconnect-names = "qspi-config";
 			status = "disabled";
 		};
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* Re: [PATCH V5 4/7] spi: spi-geni-qcom: Add interconnect support
  2020-05-08  6:33 ` [PATCH V5 4/7] spi: spi-geni-qcom: " Akash Asthana
@ 2020-05-08 10:16   ` Mark Brown
  2020-05-08 18:25   ` Matthias Kaehlcke
  1 sibling, 0 replies; 27+ messages in thread
From: Mark Brown @ 2020-05-08 10:16 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, mark.rutland, robh+dt,
	linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov


[-- Attachment #1: Type: text/plain, Size: 231 bytes --]

On Fri, May 08, 2020 at 12:03:36PM +0530, Akash Asthana wrote:
> Get the interconnect paths for SPI based Serial Engine device
> and vote according to the current bus speed of the driver.

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH V5 6/7] spi: spi-qcom-qspi: Add interconnect support
  2020-05-08  6:33 ` [PATCH V5 6/7] spi: spi-qcom-qspi: " Akash Asthana
@ 2020-05-08 10:16   ` Mark Brown
  2020-05-08 18:53   ` Matthias Kaehlcke
  1 sibling, 0 replies; 27+ messages in thread
From: Mark Brown @ 2020-05-08 10:16 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, mark.rutland, robh+dt,
	linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov


[-- Attachment #1: Type: text/plain, Size: 212 bytes --]

On Fri, May 08, 2020 at 12:03:38PM +0530, Akash Asthana wrote:
> Get the interconnect paths for QSPI device and vote according to the
> current bus speed of the driver.

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting
  2020-05-08  6:33 ` [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting Akash Asthana
@ 2020-05-08 17:13   ` Matthias Kaehlcke
  2020-05-12 14:02     ` Akash Asthana
  2020-05-08 19:03   ` Matthias Kaehlcke
  1 sibling, 1 reply; 27+ messages in thread
From: Matthias Kaehlcke @ 2020-05-08 17:13 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

Hi Akash,

note: my comments below are clearly entering bikeshed territory. Please
take what you agree with and feel free to ignore the rest.

On Fri, May 08, 2020 at 12:03:33PM +0530, Akash Asthana wrote:
> Add necessary macros and structure variables to support ICC BW
> voting from individual SE drivers.
> 
> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
> ---
> Changes in V2:
>  - As per Bjorn's comment dropped enums for ICC paths, given the three
>    paths individual members
> 
> Changes in V3:
>  - Add geni_icc_get, geni_icc_vote_on and geni_icc_vote_off as helper API.
>  - Add geni_icc_path structure in common header
> 
> Changes in V4:
>  - As per Bjorn's comment print error message in geni_icc_get if return
>    value is not -EPROBE_DEFER.
>  - As per Bjorn's comment remove NULL on path before calling icc_set_bw
>    API.
>  - As per Bjorn's comment drop __func__ print.
>  - As per Matthias's comment, make ICC path a array instead of individual
>    member entry in geni_se struct.
> 
> Note: I have ignored below check patch suggestion because it was throwing
>       compilation error as 'icc_ddr' is not compile time comstant.
> 
> WARNING: char * array declaration might be better as static const
>  - FILE: drivers/soc/qcom/qcom-geni-se.c:726:
>  - const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
> 
> Changes in V5:
>  - As per Matthias's comment defined enums for ICC paths.
>  - Integrate icc_enable/disable with power on/off call for driver.
>  - As per Matthias's comment added icc_path_names array to print icc path name
>    in failure case.
>  - As per Georgi's suggestion assume peak_bw = avg_bw if not mentioned.
> 
>  drivers/soc/qcom/qcom-geni-se.c | 92 +++++++++++++++++++++++++++++++++++++++++
>  include/linux/qcom-geni-se.h    | 42 +++++++++++++++++++
>  2 files changed, 134 insertions(+)
> 
> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
> index 7d622ea..63403bf 100644
> --- a/drivers/soc/qcom/qcom-geni-se.c
> +++ b/drivers/soc/qcom/qcom-geni-se.c
> @@ -92,6 +92,9 @@ struct geni_wrapper {
>  	struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
>  };
>  
> +static const char * const icc_path_names[] = {"qup-core", "qup-config",
> +								"qup-memory"};

nit: the indentation is a bit odd. I would align it either with "qup-core" or
at a tab stop nearby.

> +
>  #define QUP_HW_VER_REG			0x4
>  
>  /* Common SE registers */
> @@ -720,6 +723,95 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
>  }
>  EXPORT_SYMBOL(geni_se_rx_dma_unprep);
>  
> +int geni_icc_get(struct geni_se *se, const char *icc_ddr)
> +{
> +	int i, icc_err;

nit: the 'icc_' prefix doesn't add value here, just 'err' would be less
'noisy' IMO.

> +	const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};

nit: you could avoid repeating the first to strings by referencing
icc_path_names[GENI_TO_CORE] and icc_path_names[CPU_TO_GENI]. Not sure
if it's really better, it avoids the redundant names, but is slightly
less readable.

> +
> +	for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
> +		if (!icc_names[i])
> +			continue;
> +
> +		se->icc_paths[i].path = devm_of_icc_get(se->dev, icc_names[i]);
> +		if (IS_ERR(se->icc_paths[i].path))
> +			goto icc_get_failure;

nit: since there is only a single label it isn't really necessary to be so
precise. 'goto err' is very common in the kernel, 'err_icc_get' would be
another alternative.

> +	}
> +
> +	return 0;
> +
> +icc_get_failure:
> +	icc_err = PTR_ERR(se->icc_paths[i].path);
> +	if (icc_err != -EPROBE_DEFER)
> +		dev_err_ratelimited(se->dev, "Failed to get ICC path:%s, ret:%d\n",

All the logs in this patch result in something like "... path:qup-core, ret:42".
For humans I think it is more intuitive to parse "... path 'qup-core': 42".

Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

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

* Re: [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash
  2020-05-08  6:33 ` [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash Akash Asthana
@ 2020-05-08 17:59   ` Matthias Kaehlcke
  2020-05-08 19:14     ` Matthias Kaehlcke
  2020-05-14  6:45     ` Akash Asthana
  2020-05-09 12:11   ` Andy Shevchenko
  1 sibling, 2 replies; 27+ messages in thread
From: Matthias Kaehlcke @ 2020-05-08 17:59 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

Hi Akash,

overall this looks good to me, a few comments inline

On Fri, May 08, 2020 at 12:03:34PM +0530, Akash Asthana wrote:
> QUP core clock is shared among all the SE drivers present on particular
> QUP wrapper, the system will reset(unclocked access) if earlycon used after
> QUP core clock is put to 0 from other SE drivers before real console comes
> up.
> 
> As earlycon can't vote for it's QUP core need, to fix this add ICC
> support to common/QUP wrapper driver and put vote for QUP core from
> probe on behalf of earlycon and remove vote during earlycon exit call.
> 
> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
> Reported-by: Matthias Kaehlcke <mka@chromium.org>
> ---
> Change in V3:
>  - Add geni_remove_earlycon_icc_vote API that will be used by earlycon
>    exit function to remove ICC vote for earlyconsole.
>  - Remove suspend/resume hook for geni-se driver as we are no longer
>    removing earlyconsole ICC vote from system suspend, we are removing
>    from earlycon exit.
> 
> Change in V4:
>  - As per Matthias comment make 'earlycon_wrapper' as static structure.
> 
> Changes in V5:
>  - Vote for core path only after checking whether "qcom_geni" earlycon is
>    actually present or not by traversing over structure "console_drivers".
> 
>  drivers/soc/qcom/qcom-geni-se.c       | 63 +++++++++++++++++++++++++++++++++++
>  drivers/tty/serial/qcom_geni_serial.c |  7 ++++
>  include/linux/qcom-geni-se.h          |  2 ++
>  3 files changed, 72 insertions(+)
> 
> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
> index 63403bf..66fe6f2 100644
> --- a/drivers/soc/qcom/qcom-geni-se.c
> +++ b/drivers/soc/qcom/qcom-geni-se.c
> @@ -3,6 +3,7 @@
>  
>  #include <linux/acpi.h>
>  #include <linux/clk.h>
> +#include <linux/console.h>
>  #include <linux/slab.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/io.h>
> @@ -90,11 +91,14 @@ struct geni_wrapper {
>  	struct device *dev;
>  	void __iomem *base;
>  	struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
> +	struct geni_icc_path to_core;
>  };
>  
>  static const char * const icc_path_names[] = {"qup-core", "qup-config",
>  								"qup-memory"};
>  
> +static struct geni_wrapper *earlycon_wrapper;
> +
>  #define QUP_HW_VER_REG			0x4
>  
>  /* Common SE registers */
> @@ -812,11 +816,33 @@ int geni_icc_disable(struct geni_se *se)
>  }
>  EXPORT_SYMBOL(geni_icc_disable);
>  
> +void geni_remove_earlycon_icc_vote(void)
> +{
> +	struct geni_wrapper *wrapper = earlycon_wrapper;
> +	struct device_node *parent = of_get_next_parent(wrapper->dev->of_node);

Do we need to check that earlycon_wrapper != NULL before dereferencing it?
In theory this should not happen, but better be safe.

> +	struct device_node *child;
> +
> +	for_each_child_of_node(parent, child) {
> +		if (of_device_is_compatible(child, "qcom,geni-se-qup")) {
> +			wrapper = platform_get_drvdata(of_find_device_by_node(
> +					child));
> +			icc_put(wrapper->to_core.path);
> +			wrapper->to_core.path = NULL;

nit: setting the path to NULL isn't really needed IIUC.

> +		}
> +	}
> +	of_node_put(parent);
> +
> +	earlycon_wrapper = NULL;
> +}
> +EXPORT_SYMBOL(geni_remove_earlycon_icc_vote);
> +
>  static int geni_se_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
>  	struct resource *res;
>  	struct geni_wrapper *wrapper;
> +	struct console *bcon;
> +	int earlycon_present = 0;

use bool & true/false

The variable is only used when CONFIG_SERIAL_EARLYCON is set, I think
you need to add '__maybe_unused' to avoid a compiler warning then earlycon
support is disabled.

bikeshed: 'has_earlycon' would be slightly more concise (feel free to ignore).

>  	int ret;
>  
>  	wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
> @@ -839,6 +865,43 @@ static int geni_se_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> +#ifdef CONFIG_SERIAL_EARLYCON
> +	if (console_drivers)

The loop should have curly braces ("use braces when a loop contains more than
a single simple statement"), even though the compiler doesn't need them in
this case. This is not a loop, but I was told by a maintainer that it equally
applies, which makes sense.

You could avoid one level of indentation through:

if (!console_drivers)
	goto exit;

> +		for_each_console(bcon)

ditto (braces)

> +			if (!strcmp(bcon->name, "qcom_geni")) {
> +				earlycon_present = 1;
> +				break;
> +			}
> +	if (!earlycon_present)
> +		goto exit;
> +
> +	wrapper->to_core.path = devm_of_icc_get(dev, "qup-core");
> +	if (IS_ERR(wrapper->to_core.path))
> +		return PTR_ERR(wrapper->to_core.path);
> +	/*
> +	 * Put minmal BW request on core clocks on behalf of early console.
> +	 * The vote will be removed earlycon exit function.
> +	 *
> +	 * Note: We are putting vote on each QUP wrapper instead only to which
> +	 * earlycon is connected because QUP core clock of different wrapper
> +	 * share same voltage domain. If core1 is put to 0, then core2 will
> +	 * also run at 0, if not voted. Default ICC vote will be removed ASA
> +	 * we touch any of the core clock.
> +	 * core1 = core2 = max(core1, core2)
> +	 */
> +	ret = icc_set_bw(wrapper->to_core.path, GENI_DEFAULT_BW,
> +							GENI_DEFAULT_BW);

nit: the indentation is a bit odd. Align with 'wrapper->to_core.path' or a
nearby tab stop?

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

* Re: [PATCH V5 3/7] i2c: i2c-qcom-geni: Add interconnect support
  2020-05-08  6:33 ` [PATCH V5 3/7] i2c: i2c-qcom-geni: Add interconnect support Akash Asthana
@ 2020-05-08 18:16   ` Matthias Kaehlcke
  2020-05-15 10:03   ` Wolfram Sang
  1 sibling, 0 replies; 27+ messages in thread
From: Matthias Kaehlcke @ 2020-05-08 18:16 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

On Fri, May 08, 2020 at 12:03:35PM +0530, Akash Asthana wrote:
> Get the interconnect paths for I2C based Serial Engine device
> and vote according to the bus speed of the driver.
> 
> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
> ---
> Changes in V2:
>  - As per Bjorn's comment, removed se == NULL check from geni_i2c_icc_get
>  - As per Bjorn's comment, removed code to set se->icc_path* to NULL in failure
>  - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
>    path handle
>  - As per Matthias comment, added error handling for icc_set_bw call
> 
> Changes in V3:
>  - As per Matthias comment, use common library APIs defined in geni-se
>    driver for ICC functionality.
> 
> Changes in V4:
>  - Move peak_bw guess as twice of avg_bw if nothing mentioned explicitly
>    to ICC core.
> 
> Changes in V5:
>  - Use icc_enable/disable in power on/off call.
> 
>  drivers/i2c/busses/i2c-qcom-geni.c | 29 ++++++++++++++++++++++++++++-
>  1 file changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
> index 18d1e4f..f2e786d 100644
> --- a/drivers/i2c/busses/i2c-qcom-geni.c
> +++ b/drivers/i2c/busses/i2c-qcom-geni.c
> @@ -557,6 +557,25 @@ static int geni_i2c_probe(struct platform_device *pdev)
>  	gi2c->adap.dev.of_node = dev->of_node;
>  	strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
>  
> +	ret = geni_icc_get(&gi2c->se, "qup-memory");
> +	if (ret)
> +		return ret;
> +	/*
> +	 * Set the bus quota for core and cpu to a reasonable value for
> +	 * register access.
> +	 * Set quota for DDR based on bus speed.
> +	 */
> +	geni_icc_bw_init(&gi2c->se.icc_paths[GENI_TO_CORE], GENI_DEFAULT_BW,
> +				0);
> +	geni_icc_bw_init(&gi2c->se.icc_paths[CPU_TO_GENI], GENI_DEFAULT_BW,
> +				0);
> +	geni_icc_bw_init(&gi2c->se.icc_paths[GENI_TO_DDR],
> +				Bps_to_icc(gi2c->clk_freq_out), 0);
> +
> +	ret = geni_icc_set_bw(&gi2c->se);
> +	if (ret)
> +		return ret;
> +
>  	ret = geni_se_resources_on(&gi2c->se);
>  	if (ret) {
>  		dev_err(dev, "Error turning on resources %d\n", ret);
> @@ -579,6 +598,10 @@ static int geni_i2c_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	ret = geni_icc_disable(&gi2c->se);
> +	if (ret)
> +		return ret;
> +
>  	dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth);
>  
>  	gi2c->suspended = 1;
> @@ -623,7 +646,7 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev)
>  		gi2c->suspended = 1;
>  	}
>  
> -	return 0;
> +	return geni_icc_disable(&gi2c->se);
>  }
>  
>  static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
> @@ -631,6 +654,10 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev)
>  	int ret;
>  	struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
>  
> +	ret = geni_icc_enable(&gi2c->se);
> +	if (ret)
> +		return ret;
> +
>  	ret = geni_se_resources_on(&gi2c->se);
>  	if (ret)
>  		return ret;

Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

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

* Re: [PATCH V5 4/7] spi: spi-geni-qcom: Add interconnect support
  2020-05-08  6:33 ` [PATCH V5 4/7] spi: spi-geni-qcom: " Akash Asthana
  2020-05-08 10:16   ` Mark Brown
@ 2020-05-08 18:25   ` Matthias Kaehlcke
  2020-05-14  7:37     ` Akash Asthana
  1 sibling, 1 reply; 27+ messages in thread
From: Matthias Kaehlcke @ 2020-05-08 18:25 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

On Fri, May 08, 2020 at 12:03:36PM +0530, Akash Asthana wrote:
> Get the interconnect paths for SPI based Serial Engine device
> and vote according to the current bus speed of the driver.
> 
> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
> ---
> Changes in V2:
>  - As per Bjorn's comment, removed se == NULL check from geni_spi_icc_get
>  - As per Bjorn's comment, removed code to set se->icc_path* to NULL in failure
>  - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
>    path handle
>  - As per Matthias comment, added error handling for icc_set_bw call
> 
> Changes in V3:
>  - As per Matthias's comment, use helper ICC function from geni-se driver.
> 
> Changes in V4:
>  - Move peak_bw guess as twice of avg_bw if nothing mentioned explicitly
>    to ICC core.
> 
> Changes in V5:
>  - Use icc_enable/disable in power on/off call.
>  - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
>    from probe so that when resume/icc_enable is called NOC are running at
>    some non-zero value. No need to call icc_disable after BW vote because
>    device will resume and suspend before probe return and will leave ICC in
>    disabled state.
> 
>  drivers/spi/spi-geni-qcom.c | 32 +++++++++++++++++++++++++++++++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
> index c397242..5dfa1fb 100644
> --- a/drivers/spi/spi-geni-qcom.c
> +++ b/drivers/spi/spi-geni-qcom.c
> @@ -234,6 +234,13 @@ static int setup_fifo_params(struct spi_device *spi_slv,
>  		return ret;
>  	}
>  
> +	/* Set BW quota for CPU as driver supports FIFO mode only. */
> +	geni_icc_bw_init(&se->icc_paths[CPU_TO_GENI],
> +				Bps_to_icc(mas->cur_speed_hz), 0);
> +	ret = geni_icc_set_bw(se);
> +	if (ret)
> +		return ret;
> +
>  	clk_sel = idx & CLK_SEL_MSK;
>  	m_clk_cfg = (div << CLK_DIV_SHFT) | SER_CLK_EN;
>  	spi_setup_word_len(mas, spi_slv->mode, spi_slv->bits_per_word);
> @@ -578,6 +585,19 @@ static int spi_geni_probe(struct platform_device *pdev)
>  	spin_lock_init(&mas->lock);
>  	pm_runtime_enable(dev);
>  
> +	ret = geni_icc_get(&mas->se, NULL);
> +	if (ret)
> +		goto spi_geni_probe_runtime_disable;
> +	/* Set the bus quota to a reasonable value for register access */
> +	geni_icc_bw_init(&mas->se.icc_paths[GENI_TO_CORE],
> +			Bps_to_icc(CORE_2X_50_MHZ), 0);
> +	geni_icc_bw_init(&mas->se.icc_paths[CPU_TO_GENI], GENI_DEFAULT_BW, 0);
> +
> +	/* Set BW for register access */

This comment doesn't add any value. Register access is mentioned a few lines
above and from the function name it's evident that it sets the ICC bandwidth.

> +	ret = geni_icc_set_bw(&mas->se);
> +	if (ret)
> +		goto spi_geni_probe_runtime_disable;
> +
>  	ret = spi_geni_init(mas);
>  	if (ret)
>  		goto spi_geni_probe_runtime_disable;
> @@ -616,14 +636,24 @@ static int __maybe_unused spi_geni_runtime_suspend(struct device *dev)
>  {
>  	struct spi_master *spi = dev_get_drvdata(dev);
>  	struct spi_geni_master *mas = spi_master_get_devdata(spi);
> +	int ret;
> +
> +	ret = geni_se_resources_off(&mas->se);
> +	if (ret)
> +		return ret;
>  
> -	return geni_se_resources_off(&mas->se);
> +	return geni_icc_disable(&mas->se);
>  }
>  
>  static int __maybe_unused spi_geni_runtime_resume(struct device *dev)
>  {
>  	struct spi_master *spi = dev_get_drvdata(dev);
>  	struct spi_geni_master *mas = spi_master_get_devdata(spi);
> +	int ret;
> +
> +	ret = geni_icc_enable(&mas->se);
> +	if (ret)
> +		return ret;
>  
>  	return geni_se_resources_on(&mas->se);
>  }

Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

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

* Re: [PATCH V5 5/7] tty: serial: qcom_geni_serial: Add interconnect support
  2020-05-08  6:33 ` [PATCH V5 5/7] tty: serial: qcom_geni_serial: " Akash Asthana
@ 2020-05-08 18:38   ` Matthias Kaehlcke
  0 siblings, 0 replies; 27+ messages in thread
From: Matthias Kaehlcke @ 2020-05-08 18:38 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

On Fri, May 08, 2020 at 12:03:37PM +0530, Akash Asthana wrote:
> Get the interconnect paths for Uart based Serial Engine device
> and vote according to the baud rate requirement of the driver.
> 
> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
> ---
> Changes in V2:
>  - As per Bjorn's comment, removed se == NULL check from geni_serial_icc_get
>  - As per Bjorn's comment, removed code to set se->icc_path* to NULL in failure
>  - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
>    path handle
>  - As per Matthias comment, added error handling for icc_set_bw call
> 
> Changes in V3:
>  - As per Matthias comment, use common library APIs defined in geni-se
>    driver for ICC functionality.
> 
> Changes in V4:
>  - As per Mark's comment move peak_bw guess as twice of avg_bw if
>    nothing mentioned explicitly to ICC core.
>  - As per Matthias's comment select core clock BW based on baud rate.
>    If it's less than 115200 go for GENI_DEFAULT_BW else CORE_2X_50_MHZ
> 
> Changes in V5:
>  - Add icc_enable/disable to power on/off call.
>  - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
>    from probe so that when resume/icc_enable is called NOC are running at
>    some non-zero value. No need to call icc_disable after BW vote because
>    console devices are expected to be in active state from the probe itself
>    and qcom_geni_serial_pm(STATE_OFF) will be called for non-console ones.
> 
>  drivers/tty/serial/qcom_geni_serial.c | 31 ++++++++++++++++++++++++++++---
>  1 file changed, 28 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
> index 8c5d97c..2a1da36 100644
> --- a/drivers/tty/serial/qcom_geni_serial.c
> +++ b/drivers/tty/serial/qcom_geni_serial.c
> @@ -944,6 +944,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
>  	struct qcom_geni_serial_port *port = to_dev_port(uport, uport);
>  	unsigned long clk_rate;
>  	u32 ver, sampling_rate;
> +	unsigned int avg_bw_core;
>  
>  	qcom_geni_serial_stop_rx(uport);
>  	/* baud rate */
> @@ -965,6 +966,16 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
>  	ser_clk_cfg = SER_CLK_EN;
>  	ser_clk_cfg |= clk_div << CLK_DIV_SHFT;
>  
> +	/*
> +	 * Bump up BW vote on CPU and CORE path as driver supports FIFO mode
> +	 * only.
> +	 */
> +	avg_bw_core = (baud > 115200) ? Bps_to_icc(CORE_2X_50_MHZ)
> +						: GENI_DEFAULT_BW;
> +	geni_icc_bw_init(&port->se.icc_paths[GENI_TO_CORE], avg_bw_core, 0);
> +	geni_icc_bw_init(&port->se.icc_paths[CPU_TO_GENI], Bps_to_icc(baud), 0);
> +	geni_icc_set_bw(&port->se);
> +
>  	/* parity */
>  	tx_trans_cfg = readl(uport->membase + SE_UART_TX_TRANS_CFG);
>  	tx_parity_cfg = readl(uport->membase + SE_UART_TX_PARITY_CFG);
> @@ -1202,11 +1213,14 @@ static void qcom_geni_serial_pm(struct uart_port *uport,
>  	if (old_state == UART_PM_STATE_UNDEFINED)
>  		old_state = UART_PM_STATE_OFF;
>  
> -	if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF)
> +	if (new_state == UART_PM_STATE_ON && old_state == UART_PM_STATE_OFF) {
> +		geni_icc_enable(&port->se);
>  		geni_se_resources_on(&port->se);
> -	else if (new_state == UART_PM_STATE_OFF &&
> -			old_state == UART_PM_STATE_ON)
> +	} else if (new_state == UART_PM_STATE_OFF &&
> +			old_state == UART_PM_STATE_ON) {
>  		geni_se_resources_off(&port->se);
> +		geni_icc_disable(&port->se);
> +	}
>  }
>  
>  static const struct uart_ops qcom_geni_console_pops = {
> @@ -1304,6 +1318,17 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
>  			return -ENOMEM;
>  	}
>  
> +	ret = geni_icc_get(&port->se, NULL);
> +	if (ret)
> +		return ret;
> +	geni_icc_bw_init(&port->se.icc_paths[GENI_TO_CORE], GENI_DEFAULT_BW, 0);
> +	geni_icc_bw_init(&port->se.icc_paths[CPU_TO_GENI], GENI_DEFAULT_BW, 0);
> +
> +	/* Set BW for register access */
> +	ret = geni_icc_set_bw(&port->se);
> +	if (ret)
> +		return ret;
> +
>  	port->name = devm_kasprintf(uport->dev, GFP_KERNEL,
>  			"qcom_geni_serial_%s%d",
>  			uart_console(uport) ? "console" : "uart", uport->line);

Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

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

* Re: [PATCH V5 6/7] spi: spi-qcom-qspi: Add interconnect support
  2020-05-08  6:33 ` [PATCH V5 6/7] spi: spi-qcom-qspi: " Akash Asthana
  2020-05-08 10:16   ` Mark Brown
@ 2020-05-08 18:53   ` Matthias Kaehlcke
  2020-05-18 13:10     ` Akash Asthana
  1 sibling, 1 reply; 27+ messages in thread
From: Matthias Kaehlcke @ 2020-05-08 18:53 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

On Fri, May 08, 2020 at 12:03:38PM +0530, Akash Asthana wrote:
> Get the interconnect paths for QSPI device and vote according to the
> current bus speed of the driver.
> 
> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
> ---
> Changes in V2:
>  - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
>    path handle
>  - As per Matthias comment, added error handling for icc_set_bw call
> 
> Changes in V3:
>  - No Change.
> 
> Changes in V4:
>  - As per Mark's comment move peak_bw guess as twice of avg_bw if
>    nothing mentioned explicitly to ICC core.
> 
> Changes in V5:
>  - Add icc_enable/disable to power on/off call.
>  - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
>    from probe so that when resume/icc_enable is called NOC are running at
>    some non-zero value.
> 
>  drivers/spi/spi-qcom-qspi.c | 59 ++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 58 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c
> index 3c4f83b..6e299f4 100644
> --- a/drivers/spi/spi-qcom-qspi.c
> +++ b/drivers/spi/spi-qcom-qspi.c
> @@ -2,6 +2,7 @@
>  // Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
>  
>  #include <linux/clk.h>
> +#include <linux/interconnect.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
> @@ -139,7 +140,10 @@ struct qcom_qspi {
>  	struct device *dev;
>  	struct clk_bulk_data *clks;
>  	struct qspi_xfer xfer;
> -	/* Lock to protect xfer and IRQ accessed registers */
> +	struct icc_path *icc_path_cpu_to_qspi;
> +	unsigned int avg_bw_cpu;
> +	unsigned int peak_bw_cpu;

There is no point in having two fields, 'peak_bw_cpu' is always assigned
to 'avg_bw_cpu' and passed to icc_set_bw(). Just make it a single field
'icc_bw_cpu'.

> +	/* Lock to protect data accessed by IRQs */
>  	spinlock_t lock;
>  };
>  
> @@ -241,6 +245,20 @@ static int qcom_qspi_transfer_one(struct spi_master *master,
>  		return ret;
>  	}
>  
> +	/*
> +	 * Set BW quota for CPU as driver supports FIFO mode only.
> +	 * We don't have explicit peak requirement so keep it equal to avg_bw.
> +	 */
> +	ctrl->avg_bw_cpu = Bps_to_icc(speed_hz);
> +	ctrl->peak_bw_cpu = ctrl->avg_bw_cpu;
> +	ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, ctrl->avg_bw_cpu,
> +		ctrl->peak_bw_cpu);
> +	if (ret) {
> +		dev_err(ctrl->dev, "%s: ICC BW voting failed for cpu\n",
> +			__func__);

the logging in this patch is inconsistent. Here the error is not printed,
at all, in other cases it's "<error>, ret:-42" or "<error> ret:-42".
Please stick to a common format (unless there is no error). My
suggestion would be "<error>: -42", in my perception "ret:" just adds
noise.

> +		return ret;
> +	}
> +
>  	spin_lock_irqsave(&ctrl->lock, flags);
>  
>  	/* We are half duplex, so either rx or tx will be set */
> @@ -458,6 +476,29 @@ static int qcom_qspi_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto exit_probe_master_put;
>  
> +	ctrl->icc_path_cpu_to_qspi = devm_of_icc_get(dev, "qspi-config");
> +	if (IS_ERR(ctrl->icc_path_cpu_to_qspi)) {
> +		ret = PTR_ERR(ctrl->icc_path_cpu_to_qspi);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "Failed to get cpu path, ret:%d\n", ret);
> +		goto exit_probe_master_put;
> +	}
> +	/* Set BW vote for register access */
> +	ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, Bps_to_icc(1000),
> +				Bps_to_icc(1000));
> +	if (ret) {
> +		dev_err(ctrl->dev, "%s: ICC BW voting failed for cpu ret:%d\n",
> +				__func__, ret);
> +		goto exit_probe_master_put;
> +	}
> +
> +	ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
> +	if (ret) {
> +		dev_err(ctrl->dev, "%s: ICC disable failed for cpu ret:%d\n",
> +				__func__, ret);
> +		goto exit_probe_master_put;
> +	}
> +
>  	ret = platform_get_irq(pdev, 0);
>  	if (ret < 0)
>  		goto exit_probe_master_put;
> @@ -511,9 +552,17 @@ static int __maybe_unused qcom_qspi_runtime_suspend(struct device *dev)
>  {
>  	struct spi_master *master = dev_get_drvdata(dev);
>  	struct qcom_qspi *ctrl = spi_master_get_devdata(master);
> +	int ret;
>  
>  	clk_bulk_disable_unprepare(QSPI_NUM_CLKS, ctrl->clks);
>  
> +	ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
> +	if (ret) {
> +		dev_err_ratelimited(ctrl->dev, "%s: ICC disable failed for cpu ret:%d\n",
> +			__func__, ret);
> +		return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -521,6 +570,14 @@ static int __maybe_unused qcom_qspi_runtime_resume(struct device *dev)
>  {
>  	struct spi_master *master = dev_get_drvdata(dev);
>  	struct qcom_qspi *ctrl = spi_master_get_devdata(master);
> +	int ret;
> +
> +	ret = icc_enable(ctrl->icc_path_cpu_to_qspi);
> +	if (ret) {
> +		dev_err_ratelimited(ctrl->dev, "%s: ICC enable failed for cpu ret:%d\n",
> +			__func__, ret);
> +		return ret;
> +	}
>  
>  	return clk_bulk_prepare_enable(QSPI_NUM_CLKS, ctrl->clks);
>  }

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

* Re: [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting
  2020-05-08  6:33 ` [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting Akash Asthana
  2020-05-08 17:13   ` Matthias Kaehlcke
@ 2020-05-08 19:03   ` Matthias Kaehlcke
  2020-05-12 14:26     ` Akash Asthana
  1 sibling, 1 reply; 27+ messages in thread
From: Matthias Kaehlcke @ 2020-05-08 19:03 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

On Fri, May 08, 2020 at 12:03:33PM +0530, Akash Asthana wrote:
> Add necessary macros and structure variables to support ICC BW
> voting from individual SE drivers.
> 
> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
> ---
> Changes in V2:
>  - As per Bjorn's comment dropped enums for ICC paths, given the three
>    paths individual members
> 
> Changes in V3:
>  - Add geni_icc_get, geni_icc_vote_on and geni_icc_vote_off as helper API.
>  - Add geni_icc_path structure in common header
> 
> Changes in V4:
>  - As per Bjorn's comment print error message in geni_icc_get if return
>    value is not -EPROBE_DEFER.
>  - As per Bjorn's comment remove NULL on path before calling icc_set_bw
>    API.
>  - As per Bjorn's comment drop __func__ print.
>  - As per Matthias's comment, make ICC path a array instead of individual
>    member entry in geni_se struct.
> 
> Note: I have ignored below check patch suggestion because it was throwing
>       compilation error as 'icc_ddr' is not compile time comstant.
> 
> WARNING: char * array declaration might be better as static const
>  - FILE: drivers/soc/qcom/qcom-geni-se.c:726:
>  - const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
> 
> Changes in V5:
>  - As per Matthias's comment defined enums for ICC paths.
>  - Integrate icc_enable/disable with power on/off call for driver.
>  - As per Matthias's comment added icc_path_names array to print icc path name
>    in failure case.
>  - As per Georgi's suggestion assume peak_bw = avg_bw if not mentioned.
> 
>  drivers/soc/qcom/qcom-geni-se.c | 92 +++++++++++++++++++++++++++++++++++++++++
>  include/linux/qcom-geni-se.h    | 42 +++++++++++++++++++
>  2 files changed, 134 insertions(+)
> 
> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
> index 7d622ea..63403bf 100644
> --- a/drivers/soc/qcom/qcom-geni-se.c
> +++ b/drivers/soc/qcom/qcom-geni-se.c
> @@ -92,6 +92,9 @@ struct geni_wrapper {
>  	struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
>  };
>  
> +static const char * const icc_path_names[] = {"qup-core", "qup-config",
> +								"qup-memory"};
> +
>  #define QUP_HW_VER_REG			0x4
>  
>  /* Common SE registers */
> @@ -720,6 +723,95 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
>  }
>  EXPORT_SYMBOL(geni_se_rx_dma_unprep);
>  
> +int geni_icc_get(struct geni_se *se, const char *icc_ddr)
> +{
> +	int i, icc_err;
> +	const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
> +
> +	for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
> +		if (!icc_names[i])
> +			continue;
> +
> +		se->icc_paths[i].path = devm_of_icc_get(se->dev, icc_names[i]);
> +		if (IS_ERR(se->icc_paths[i].path))
> +			goto icc_get_failure;
> +	}
> +
> +	return 0;
> +
> +icc_get_failure:
> +	icc_err = PTR_ERR(se->icc_paths[i].path);
> +	if (icc_err != -EPROBE_DEFER)
> +		dev_err_ratelimited(se->dev, "Failed to get ICC path:%s, ret:%d\n",
> +					icc_names[i], icc_err);
> +	return icc_err;
> +
> +}
> +EXPORT_SYMBOL(geni_icc_get);
> +
> +void geni_icc_bw_init(struct geni_icc_path *icc_paths, unsigned int avg_bw,
> +			unsigned int peak_bw)

I noticed that all callers of geni_icc_bw_init() pass 0 as
'peak_pw' (aka peak == avg). Unless there are plans to use other
values for the peak bandwidth in the future it is pointless to
track the bandwidth(s) in two variables. And if the bandwidth is
tracked in a single variable this function is not needed.

> +{
> +	if (!peak_bw)
> +		peak_bw = avg_bw;
> +	icc_paths->avg_bw = avg_bw;
> +	icc_paths->peak_bw = peak_bw;
> +}
> +EXPORT_SYMBOL(geni_icc_bw_init);

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

* Re: [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash
  2020-05-08 17:59   ` Matthias Kaehlcke
@ 2020-05-08 19:14     ` Matthias Kaehlcke
  2020-05-14  7:03       ` Akash Asthana
  2020-05-14  6:45     ` Akash Asthana
  1 sibling, 1 reply; 27+ messages in thread
From: Matthias Kaehlcke @ 2020-05-08 19:14 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

On Fri, May 08, 2020 at 10:59:38AM -0700, Matthias Kaehlcke wrote:
> Hi Akash,
> 
> overall this looks good to me, a few comments inline
> 
> On Fri, May 08, 2020 at 12:03:34PM +0530, Akash Asthana wrote:
> > QUP core clock is shared among all the SE drivers present on particular
> > QUP wrapper, the system will reset(unclocked access) if earlycon used after
> > QUP core clock is put to 0 from other SE drivers before real console comes
> > up.
> > 
> > As earlycon can't vote for it's QUP core need, to fix this add ICC
> > support to common/QUP wrapper driver and put vote for QUP core from
> > probe on behalf of earlycon and remove vote during earlycon exit call.
> > 
> > Signed-off-by: Akash Asthana <akashast@codeaurora.org>
> > Reported-by: Matthias Kaehlcke <mka@chromium.org>
> > ---
> > Change in V3:
> >  - Add geni_remove_earlycon_icc_vote API that will be used by earlycon
> >    exit function to remove ICC vote for earlyconsole.
> >  - Remove suspend/resume hook for geni-se driver as we are no longer
> >    removing earlyconsole ICC vote from system suspend, we are removing
> >    from earlycon exit.
> > 
> > Change in V4:
> >  - As per Matthias comment make 'earlycon_wrapper' as static structure.
> > 
> > Changes in V5:
> >  - Vote for core path only after checking whether "qcom_geni" earlycon is
> >    actually present or not by traversing over structure "console_drivers".
> > 
> >  drivers/soc/qcom/qcom-geni-se.c       | 63 +++++++++++++++++++++++++++++++++++
> >  drivers/tty/serial/qcom_geni_serial.c |  7 ++++
> >  include/linux/qcom-geni-se.h          |  2 ++
> >  3 files changed, 72 insertions(+)
> > 
> > diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
> > index 63403bf..66fe6f2 100644
> > --- a/drivers/soc/qcom/qcom-geni-se.c
> > +++ b/drivers/soc/qcom/qcom-geni-se.c

...

> > +#ifdef CONFIG_SERIAL_EARLYCON
> > +	if (console_drivers)
> 
> The loop should have curly braces ("use braces when a loop contains more than
> a single simple statement"), even though the compiler doesn't need them in
> this case. This is not a loop, but I was told by a maintainer that it equally
> applies, which makes sense.
> 
> You could avoid one level of indentation through:
> 
> if (!console_drivers)
> 	goto exit;
> 
> > +		for_each_console(bcon)

Actually the NULL check of 'console_drivers' is not needed:

#define for_each_console(con) \
        for (con = console_drivers; con != NULL; con = con->next)

see also:

commit caa72c3bc584bc28b557bcf1a47532a7a6f37e6f
Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Date:   Mon Feb 3 15:31:25 2020 +0200

    console: Drop double check for console_drivers being non-NULL

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

* Re: [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash
  2020-05-08  6:33 ` [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash Akash Asthana
  2020-05-08 17:59   ` Matthias Kaehlcke
@ 2020-05-09 12:11   ` Andy Shevchenko
  2020-05-14  7:34     ` Akash Asthana
  1 sibling, 1 reply; 27+ messages in thread
From: Andy Shevchenko @ 2020-05-09 12:11 UTC (permalink / raw)
  To: Akash Asthana
  Cc: Greg Kroah-Hartman, agross, Bjorn Andersson, Wolfram Sang,
	Mark Brown, Mark Rutland, Rob Herring, linux-i2c, linux-spi,
	devicetree, Stephen Boyd, mgautam, linux-arm-msm,
	open list:SERIAL DRIVERS, Matthias Kaehlcke, Douglas Anderson,
	Evan Green, Georgi Djakov

On Fri, May 8, 2020 at 9:34 AM Akash Asthana <akashast@codeaurora.org> wrote:
>
> QUP core clock is shared among all the SE drivers present on particular
> QUP wrapper, the system will reset(unclocked access) if earlycon used after
> QUP core clock is put to 0 from other SE drivers before real console comes
> up.
>
> As earlycon can't vote for it's QUP core need, to fix this add ICC
> support to common/QUP wrapper driver and put vote for QUP core from
> probe on behalf of earlycon and remove vote during earlycon exit call.

...

> +       for_each_child_of_node(parent, child) {

> +               if (of_device_is_compatible(child, "qcom,geni-se-qup")) {

if (!...)
 continue;

will save you a readability of the loop body.

Or...

> +                       wrapper = platform_get_drvdata(of_find_device_by_node(
> +                                       child));

...leave this on one line

> +                       icc_put(wrapper->to_core.path);
> +                       wrapper->to_core.path = NULL;
> +               }

And here is the question, what do you want to do if you find more
devices with the same compatible string?

> +       }

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting
  2020-05-08 17:13   ` Matthias Kaehlcke
@ 2020-05-12 14:02     ` Akash Asthana
  0 siblings, 0 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-12 14:02 UTC (permalink / raw)
  To: Matthias Kaehlcke
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov


On 5/8/2020 10:43 PM, Matthias Kaehlcke wrote:
> Hi Akash,
>
> note: my comments below are clearly entering bikeshed territory. Please
> take what you agree with and feel free to ignore the rest.
>
> On Fri, May 08, 2020 at 12:03:33PM +0530, Akash Asthana wrote:
>> Add necessary macros and structure variables to support ICC BW
>> voting from individual SE drivers.
>>
>> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
>> ---
>> Changes in V2:
>>   - As per Bjorn's comment dropped enums for ICC paths, given the three
>>     paths individual members
>>
>> Changes in V3:
>>   - Add geni_icc_get, geni_icc_vote_on and geni_icc_vote_off as helper API.
>>   - Add geni_icc_path structure in common header
>>
>> Changes in V4:
>>   - As per Bjorn's comment print error message in geni_icc_get if return
>>     value is not -EPROBE_DEFER.
>>   - As per Bjorn's comment remove NULL on path before calling icc_set_bw
>>     API.
>>   - As per Bjorn's comment drop __func__ print.
>>   - As per Matthias's comment, make ICC path a array instead of individual
>>     member entry in geni_se struct.
>>
>> Note: I have ignored below check patch suggestion because it was throwing
>>        compilation error as 'icc_ddr' is not compile time comstant.
>>
>> WARNING: char * array declaration might be better as static const
>>   - FILE: drivers/soc/qcom/qcom-geni-se.c:726:
>>   - const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
>>
>> Changes in V5:
>>   - As per Matthias's comment defined enums for ICC paths.
>>   - Integrate icc_enable/disable with power on/off call for driver.
>>   - As per Matthias's comment added icc_path_names array to print icc path name
>>     in failure case.
>>   - As per Georgi's suggestion assume peak_bw = avg_bw if not mentioned.
>>
>>   drivers/soc/qcom/qcom-geni-se.c | 92 +++++++++++++++++++++++++++++++++++++++++
>>   include/linux/qcom-geni-se.h    | 42 +++++++++++++++++++
>>   2 files changed, 134 insertions(+)
>>
>> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
>> index 7d622ea..63403bf 100644
>> --- a/drivers/soc/qcom/qcom-geni-se.c
>> +++ b/drivers/soc/qcom/qcom-geni-se.c
>> @@ -92,6 +92,9 @@ struct geni_wrapper {
>>   	struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
>>   };
>>   
>> +static const char * const icc_path_names[] = {"qup-core", "qup-config",
>> +								"qup-memory"};
> nit: the indentation is a bit odd. I would align it either with "qup-core" or
> at a tab stop nearby.
ok
>
>> +
>>   #define QUP_HW_VER_REG			0x4
>>   
>>   /* Common SE registers */
>> @@ -720,6 +723,95 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
>>   }
>>   EXPORT_SYMBOL(geni_se_rx_dma_unprep);
>>   
>> +int geni_icc_get(struct geni_se *se, const char *icc_ddr)
>> +{
>> +	int i, icc_err;
> nit: the 'icc_' prefix doesn't add value here, just 'err' would be less
> 'noisy' IMO.
ok
>
>> +	const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
> nit: you could avoid repeating the first to strings by referencing
> icc_path_names[GENI_TO_CORE] and icc_path_names[CPU_TO_GENI]. Not sure
> if it's really better, it avoids the redundant names, but is slightly
> less readable.
I thought of that but current implementation looks neater to me.
>
>> +
>> +	for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
>> +		if (!icc_names[i])
>> +			continue;
>> +
>> +		se->icc_paths[i].path = devm_of_icc_get(se->dev, icc_names[i]);
>> +		if (IS_ERR(se->icc_paths[i].path))
>> +			goto icc_get_failure;
> nit: since there is only a single label it isn't really necessary to be so
> precise. 'goto err' is very common in the kernel, 'err_icc_get' would be
> another alternative.
okay
>
>> +	}
>> +
>> +	return 0;
>> +
>> +icc_get_failure:
>> +	icc_err = PTR_ERR(se->icc_paths[i].path);
>> +	if (icc_err != -EPROBE_DEFER)
>> +		dev_err_ratelimited(se->dev, "Failed to get ICC path:%s, ret:%d\n",
> All the logs in this patch result in something like "... path:qup-core, ret:42".
> For humans I think it is more intuitive to parse "... path 'qup-core': 42".

ok

Thanks for review and feedback

Regards,

Akash

>
> Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* Re: [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting
  2020-05-08 19:03   ` Matthias Kaehlcke
@ 2020-05-12 14:26     ` Akash Asthana
  0 siblings, 0 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-12 14:26 UTC (permalink / raw)
  To: Matthias Kaehlcke
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

Hi Matthias,

On 5/9/2020 12:33 AM, Matthias Kaehlcke wrote:
> On Fri, May 08, 2020 at 12:03:33PM +0530, Akash Asthana wrote:
>> Add necessary macros and structure variables to support ICC BW
>> voting from individual SE drivers.
>>
>> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
>> ---
>> Changes in V2:
>>   - As per Bjorn's comment dropped enums for ICC paths, given the three
>>     paths individual members
>>
>> Changes in V3:
>>   - Add geni_icc_get, geni_icc_vote_on and geni_icc_vote_off as helper API.
>>   - Add geni_icc_path structure in common header
>>
>> Changes in V4:
>>   - As per Bjorn's comment print error message in geni_icc_get if return
>>     value is not -EPROBE_DEFER.
>>   - As per Bjorn's comment remove NULL on path before calling icc_set_bw
>>     API.
>>   - As per Bjorn's comment drop __func__ print.
>>   - As per Matthias's comment, make ICC path a array instead of individual
>>     member entry in geni_se struct.
>>
>> Note: I have ignored below check patch suggestion because it was throwing
>>        compilation error as 'icc_ddr' is not compile time comstant.
>>
>> WARNING: char * array declaration might be better as static const
>>   - FILE: drivers/soc/qcom/qcom-geni-se.c:726:
>>   - const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
>>
>> Changes in V5:
>>   - As per Matthias's comment defined enums for ICC paths.
>>   - Integrate icc_enable/disable with power on/off call for driver.
>>   - As per Matthias's comment added icc_path_names array to print icc path name
>>     in failure case.
>>   - As per Georgi's suggestion assume peak_bw = avg_bw if not mentioned.
>>
>>   drivers/soc/qcom/qcom-geni-se.c | 92 +++++++++++++++++++++++++++++++++++++++++
>>   include/linux/qcom-geni-se.h    | 42 +++++++++++++++++++
>>   2 files changed, 134 insertions(+)
>>
>> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
>> index 7d622ea..63403bf 100644
>> --- a/drivers/soc/qcom/qcom-geni-se.c
>> +++ b/drivers/soc/qcom/qcom-geni-se.c
>> @@ -92,6 +92,9 @@ struct geni_wrapper {
>>   	struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
>>   };
>>   
>> +static const char * const icc_path_names[] = {"qup-core", "qup-config",
>> +								"qup-memory"};
>> +
>>   #define QUP_HW_VER_REG			0x4
>>   
>>   /* Common SE registers */
>> @@ -720,6 +723,95 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len)
>>   }
>>   EXPORT_SYMBOL(geni_se_rx_dma_unprep);
>>   
>> +int geni_icc_get(struct geni_se *se, const char *icc_ddr)
>> +{
>> +	int i, icc_err;
>> +	const char *icc_names[] = {"qup-core", "qup-config", icc_ddr};
>> +
>> +	for (i = 0; i < ARRAY_SIZE(se->icc_paths); i++) {
>> +		if (!icc_names[i])
>> +			continue;
>> +
>> +		se->icc_paths[i].path = devm_of_icc_get(se->dev, icc_names[i]);
>> +		if (IS_ERR(se->icc_paths[i].path))
>> +			goto icc_get_failure;
>> +	}
>> +
>> +	return 0;
>> +
>> +icc_get_failure:
>> +	icc_err = PTR_ERR(se->icc_paths[i].path);
>> +	if (icc_err != -EPROBE_DEFER)
>> +		dev_err_ratelimited(se->dev, "Failed to get ICC path:%s, ret:%d\n",
>> +					icc_names[i], icc_err);
>> +	return icc_err;
>> +
>> +}
>> +EXPORT_SYMBOL(geni_icc_get);
>> +
>> +void geni_icc_bw_init(struct geni_icc_path *icc_paths, unsigned int avg_bw,
>> +			unsigned int peak_bw)
> I noticed that all callers of geni_icc_bw_init() pass 0 as
> 'peak_pw' (aka peak == avg). Unless there are plans to use other
> values for the peak bandwidth in the future it is pointless to
> track the bandwidth(s) in two variables. And if the bandwidth is
> tracked in a single variable this function is not needed.

As of now we are not aware of our peak requirement(avg requirement works 
good for us) so I am passing (peak = avg) as per Georgi's suggestion.

But I wanted to make this feature more generic and keeping the 
possibilty open that we might have to use other peak(!=0) value in future.

Regards,

Akash

>
>> +{
>> +	if (!peak_bw)
>> +		peak_bw = avg_bw;
>> +	icc_paths->avg_bw = avg_bw;
>> +	icc_paths->peak_bw = peak_bw;
>> +}
>> +EXPORT_SYMBOL(geni_icc_bw_init);

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* Re: [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash
  2020-05-08 17:59   ` Matthias Kaehlcke
  2020-05-08 19:14     ` Matthias Kaehlcke
@ 2020-05-14  6:45     ` Akash Asthana
  1 sibling, 0 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-14  6:45 UTC (permalink / raw)
  To: Matthias Kaehlcke
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

Hi Matthias,

On 5/8/2020 11:29 PM, Matthias Kaehlcke wrote:
> Hi Akash,
>
> overall this looks good to me, a few comments inline
>
> On Fri, May 08, 2020 at 12:03:34PM +0530, Akash Asthana wrote:
>> QUP core clock is shared among all the SE drivers present on particular
>> QUP wrapper, the system will reset(unclocked access) if earlycon used after
>> QUP core clock is put to 0 from other SE drivers before real console comes
>> up.
>>
>> As earlycon can't vote for it's QUP core need, to fix this add ICC
>> support to common/QUP wrapper driver and put vote for QUP core from
>> probe on behalf of earlycon and remove vote during earlycon exit call.
>>
>> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
>> Reported-by: Matthias Kaehlcke <mka@chromium.org>
>> ---
>> Change in V3:
>>   - Add geni_remove_earlycon_icc_vote API that will be used by earlycon
>>     exit function to remove ICC vote for earlyconsole.
>>   - Remove suspend/resume hook for geni-se driver as we are no longer
>>     removing earlyconsole ICC vote from system suspend, we are removing
>>     from earlycon exit.
>>
>> Change in V4:
>>   - As per Matthias comment make 'earlycon_wrapper' as static structure.
>>
>> Changes in V5:
>>   - Vote for core path only after checking whether "qcom_geni" earlycon is
>>     actually present or not by traversing over structure "console_drivers".
>>
>>   drivers/soc/qcom/qcom-geni-se.c       | 63 +++++++++++++++++++++++++++++++++++
>>   drivers/tty/serial/qcom_geni_serial.c |  7 ++++
>>   include/linux/qcom-geni-se.h          |  2 ++
>>   3 files changed, 72 insertions(+)
>>
>> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c
>> index 63403bf..66fe6f2 100644
>> --- a/drivers/soc/qcom/qcom-geni-se.c
>> +++ b/drivers/soc/qcom/qcom-geni-se.c
>> @@ -3,6 +3,7 @@
>>   
>>   #include <linux/acpi.h>
>>   #include <linux/clk.h>
>> +#include <linux/console.h>
>>   #include <linux/slab.h>
>>   #include <linux/dma-mapping.h>
>>   #include <linux/io.h>
>> @@ -90,11 +91,14 @@ struct geni_wrapper {
>>   	struct device *dev;
>>   	void __iomem *base;
>>   	struct clk_bulk_data ahb_clks[NUM_AHB_CLKS];
>> +	struct geni_icc_path to_core;
>>   };
>>   
>>   static const char * const icc_path_names[] = {"qup-core", "qup-config",
>>   								"qup-memory"};
>>   
>> +static struct geni_wrapper *earlycon_wrapper;
>> +
>>   #define QUP_HW_VER_REG			0x4
>>   
>>   /* Common SE registers */
>> @@ -812,11 +816,33 @@ int geni_icc_disable(struct geni_se *se)
>>   }
>>   EXPORT_SYMBOL(geni_icc_disable);
>>   
>> +void geni_remove_earlycon_icc_vote(void)
>> +{
>> +	struct geni_wrapper *wrapper = earlycon_wrapper;
>> +	struct device_node *parent = of_get_next_parent(wrapper->dev->of_node);
> Do we need to check that earlycon_wrapper != NULL before dereferencing it?
> In theory this should not happen, but better be safe.
Ok, I will add NULL check.
>
>> +	struct device_node *child;
>> +
>> +	for_each_child_of_node(parent, child) {
>> +		if (of_device_is_compatible(child, "qcom,geni-se-qup")) {
>> +			wrapper = platform_get_drvdata(of_find_device_by_node(
>> +					child));
>> +			icc_put(wrapper->to_core.path);
>> +			wrapper->to_core.path = NULL;
> nit: setting the path to NULL isn't really needed IIUC.
icc_put just free the path and don't reinitialize the path to NULL, if 
the path is used after it is put target will crash. So just for safety I 
am setting this path to NULL.
>
>> +		}
>> +	}
>> +	of_node_put(parent);
>> +
>> +	earlycon_wrapper = NULL;
>> +}
>> +EXPORT_SYMBOL(geni_remove_earlycon_icc_vote);
>> +
>>   static int geni_se_probe(struct platform_device *pdev)
>>   {
>>   	struct device *dev = &pdev->dev;
>>   	struct resource *res;
>>   	struct geni_wrapper *wrapper;
>> +	struct console *bcon;
>> +	int earlycon_present = 0;
> use bool & true/false
>
> The variable is only used when CONFIG_SERIAL_EARLYCON is set, I think
> you need to add '__maybe_unused' to avoid a compiler warning then earlycon
> support is disabled.
>
> bikeshed: 'has_earlycon' would be slightly more concise (feel free to ignore).
Ok
>
>>   	int ret;
>>   
>>   	wrapper = devm_kzalloc(dev, sizeof(*wrapper), GFP_KERNEL);
>> @@ -839,6 +865,43 @@ static int geni_se_probe(struct platform_device *pdev)
>>   		}
>>   	}
>>   
>> +#ifdef CONFIG_SERIAL_EARLYCON
>> +	if (console_drivers)
> The loop should have curly braces ("use braces when a loop contains more than
> a single simple statement"), even though the compiler doesn't need them in
> this case. This is not a loop, but I was told by a maintainer that it equally
> applies, which makes sense.
>
> You could avoid one level of indentation through:
Ok
>
> if (!console_drivers)
> 	goto exit;

I think I can omit this extra check because "for_each_console" will take 
care of this.

>
>> +		for_each_console(bcon)
> ditto (braces)
>
>> +			if (!strcmp(bcon->name, "qcom_geni")) {
>> +				earlycon_present = 1;
>> +				break;
>> +			}
>> +	if (!earlycon_present)
>> +		goto exit;
>> +
>> +	wrapper->to_core.path = devm_of_icc_get(dev, "qup-core");
>> +	if (IS_ERR(wrapper->to_core.path))
>> +		return PTR_ERR(wrapper->to_core.path);
>> +	/*
>> +	 * Put minmal BW request on core clocks on behalf of early console.
>> +	 * The vote will be removed earlycon exit function.
>> +	 *
>> +	 * Note: We are putting vote on each QUP wrapper instead only to which
>> +	 * earlycon is connected because QUP core clock of different wrapper
>> +	 * share same voltage domain. If core1 is put to 0, then core2 will
>> +	 * also run at 0, if not voted. Default ICC vote will be removed ASA
>> +	 * we touch any of the core clock.
>> +	 * core1 = core2 = max(core1, core2)
>> +	 */
>> +	ret = icc_set_bw(wrapper->to_core.path, GENI_DEFAULT_BW,
>> +							GENI_DEFAULT_BW);
> nit: the indentation is a bit odd. Align with 'wrapper->to_core.path' or a
> nearby tab stop?

ok


Thanks for providing the feedback.

Regards,

Akash

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project


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

* Re: [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash
  2020-05-08 19:14     ` Matthias Kaehlcke
@ 2020-05-14  7:03       ` Akash Asthana
  0 siblings, 0 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-14  7:03 UTC (permalink / raw)
  To: Matthias Kaehlcke
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

Hi Matthias,


>> The loop should have curly braces ("use braces when a loop contains more than
>> a single simple statement"), even though the compiler doesn't need them in
>> this case. This is not a loop, but I was told by a maintainer that it equally
>> applies, which makes sense.
>>
>> You could avoid one level of indentation through:
>>
>> if (!console_drivers)
>> 	goto exit;
>>
>>> +		for_each_console(bcon)
> Actually the NULL check of 'console_drivers' is not needed:
>
> #define for_each_console(con) \
>          for (con = console_drivers; con != NULL; con = con->next)

Ok, I will remove this check.


Regards,

Akash

>
> see also:
>
> commit caa72c3bc584bc28b557bcf1a47532a7a6f37e6f
> Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Date:   Mon Feb 3 15:31:25 2020 +0200
>
>      console: Drop double check for console_drivers being non-NULL

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* Re: [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash
  2020-05-09 12:11   ` Andy Shevchenko
@ 2020-05-14  7:34     ` Akash Asthana
  0 siblings, 0 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-14  7:34 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Greg Kroah-Hartman, agross, Bjorn Andersson, Wolfram Sang,
	Mark Brown, Mark Rutland, Rob Herring, linux-i2c, linux-spi,
	devicetree, Stephen Boyd, mgautam, linux-arm-msm,
	open list:SERIAL DRIVERS, Matthias Kaehlcke, Douglas Anderson,
	Evan Green, Georgi Djakov

Hi Andy,

On 5/9/2020 5:41 PM, Andy Shevchenko wrote:
> On Fri, May 8, 2020 at 9:34 AM Akash Asthana <akashast@codeaurora.org> wrote:
>> QUP core clock is shared among all the SE drivers present on particular
>> QUP wrapper, the system will reset(unclocked access) if earlycon used after
>> QUP core clock is put to 0 from other SE drivers before real console comes
>> up.
>>
>> As earlycon can't vote for it's QUP core need, to fix this add ICC
>> support to common/QUP wrapper driver and put vote for QUP core from
>> probe on behalf of earlycon and remove vote during earlycon exit call.
> ...
>
>> +       for_each_child_of_node(parent, child) {
>> +               if (of_device_is_compatible(child, "qcom,geni-se-qup")) {
> if (!...)
>   continue;
> will save you a readability of the loop body.
>
> Or...
Ok.
>
>> +                       wrapper = platform_get_drvdata(of_find_device_by_node(
>> +                                       child));
> ...leave this on one line
ok
>
>> +                       icc_put(wrapper->to_core.path);
>> +                       wrapper->to_core.path = NULL;
>> +               }
> And here is the question, what do you want to do if you find more
> devices with the same compatible string?

We are voting on core path (from probe *geni_se_probe*) for all the 
devices which are compatible to string "qcom,geni-se-qup" so, here we'll 
remove those vote and release the icc_path for all the those devices

We have to vote on each qup device instead ones to which console is 
connected because all the qup shares the same core clocks. You may refer 
previous thread@ https://www.spinics.net/lists/linux-spi/msg21000.html 
for more info on this limitation.

Thankyou for taking time out and reviewing the patch.

Regards,

Akash

>
>> +       }

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* Re: [PATCH V5 4/7] spi: spi-geni-qcom: Add interconnect support
  2020-05-08 18:25   ` Matthias Kaehlcke
@ 2020-05-14  7:37     ` Akash Asthana
  0 siblings, 0 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-14  7:37 UTC (permalink / raw)
  To: Matthias Kaehlcke
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

Hi Matthias,

....

;
>>   
>> +	ret = geni_icc_get(&mas->se, NULL);
>> +	if (ret)
>> +		goto spi_geni_probe_runtime_disable;
>> +	/* Set the bus quota to a reasonable value for register access */
>> +	geni_icc_bw_init(&mas->se.icc_paths[GENI_TO_CORE],
>> +			Bps_to_icc(CORE_2X_50_MHZ), 0);
>> +	geni_icc_bw_init(&mas->se.icc_paths[CPU_TO_GENI], GENI_DEFAULT_BW, 0);
>> +
>> +	/* Set BW for register access */
> This comment doesn't add any value. Register access is mentioned a few lines
> above and from the function name it's evident that it sets the ICC bandwidth.
ok
>
>> +	ret = geni_icc_set_bw(&mas->se);
>>
>> +		return ret;
>>   
>>   	return geni_se_resources_on(&mas->se);
>>   }
> Reviewed-by: Matthias Kaehlcke <mka@chromium.org>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

* Re: [PATCH V5 3/7] i2c: i2c-qcom-geni: Add interconnect support
  2020-05-08  6:33 ` [PATCH V5 3/7] i2c: i2c-qcom-geni: Add interconnect support Akash Asthana
  2020-05-08 18:16   ` Matthias Kaehlcke
@ 2020-05-15 10:03   ` Wolfram Sang
  1 sibling, 0 replies; 27+ messages in thread
From: Wolfram Sang @ 2020-05-15 10:03 UTC (permalink / raw)
  To: Akash Asthana
  Cc: gregkh, agross, bjorn.andersson, broonie, mark.rutland, robh+dt,
	linux-i2c, linux-spi, devicetree, swboyd, mgautam, linux-arm-msm,
	linux-serial, mka, dianders, evgreen, georgi.djakov


[-- Attachment #1: Type: text/plain, Size: 302 bytes --]

On Fri, May 08, 2020 at 12:03:35PM +0530, Akash Asthana wrote:
> Get the interconnect paths for I2C based Serial Engine device
> and vote according to the bus speed of the driver.
> 
> Signed-off-by: Akash Asthana <akashast@codeaurora.org>

For I2C:

Acked-by: Wolfram Sang <wsa@kernel.org>


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH V5 6/7] spi: spi-qcom-qspi: Add interconnect support
  2020-05-08 18:53   ` Matthias Kaehlcke
@ 2020-05-18 13:10     ` Akash Asthana
  0 siblings, 0 replies; 27+ messages in thread
From: Akash Asthana @ 2020-05-18 13:10 UTC (permalink / raw)
  To: Matthias Kaehlcke
  Cc: gregkh, agross, bjorn.andersson, wsa, broonie, mark.rutland,
	robh+dt, linux-i2c, linux-spi, devicetree, swboyd, mgautam,
	linux-arm-msm, linux-serial, dianders, evgreen, georgi.djakov

Hi Matthias,

On 5/9/2020 12:23 AM, Matthias Kaehlcke wrote:
> On Fri, May 08, 2020 at 12:03:38PM +0530, Akash Asthana wrote:
>> Get the interconnect paths for QSPI device and vote according to the
>> current bus speed of the driver.
>>
>> Signed-off-by: Akash Asthana <akashast@codeaurora.org>
>> ---
>> Changes in V2:
>>   - As per Bjorn's comment, introduced and using devm_of_icc_get API for getting
>>     path handle
>>   - As per Matthias comment, added error handling for icc_set_bw call
>>
>> Changes in V3:
>>   - No Change.
>>
>> Changes in V4:
>>   - As per Mark's comment move peak_bw guess as twice of avg_bw if
>>     nothing mentioned explicitly to ICC core.
>>
>> Changes in V5:
>>   - Add icc_enable/disable to power on/off call.
>>   - Save some non-zero avg/peak value to ICC core by calling geni_icc_set_bw
>>     from probe so that when resume/icc_enable is called NOC are running at
>>     some non-zero value.
>>
>>   drivers/spi/spi-qcom-qspi.c | 59 ++++++++++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 58 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c
>> index 3c4f83b..6e299f4 100644
>> --- a/drivers/spi/spi-qcom-qspi.c
>> +++ b/drivers/spi/spi-qcom-qspi.c
>> @@ -2,6 +2,7 @@
>>   // Copyright (c) 2017-2018, The Linux foundation. All rights reserved.
>>   
>>   #include <linux/clk.h>
>> +#include <linux/interconnect.h>
>>   #include <linux/interrupt.h>
>>   #include <linux/io.h>
>>   #include <linux/module.h>
>> @@ -139,7 +140,10 @@ struct qcom_qspi {
>>   	struct device *dev;
>>   	struct clk_bulk_data *clks;
>>   	struct qspi_xfer xfer;
>> -	/* Lock to protect xfer and IRQ accessed registers */
>> +	struct icc_path *icc_path_cpu_to_qspi;
>> +	unsigned int avg_bw_cpu;
>> +	unsigned int peak_bw_cpu;
> There is no point in having two fields, 'peak_bw_cpu' is always assigned
> to 'avg_bw_cpu' and passed to icc_set_bw(). Just make it a single field
> 'icc_bw_cpu'.
Agree that we are not using peak_bw voting as of now but probably we may 
use it in future, currently we are using only avg_bw for our need but if 
in future power team shares some data or ask us to reduce our power 
consumption, then with help of peak_bw we can tune ICC voting where 
power and performance both can be met as per requirement.
>
>> +	/* Lock to protect data accessed by IRQs */
>>   	spinlock_t lock;
>>   };
>>   
>> @@ -241,6 +245,20 @@ static int qcom_qspi_transfer_one(struct spi_master *master,
>>   		return ret;
>>   	}
>>   
>> +	/*
>> +	 * Set BW quota for CPU as driver supports FIFO mode only.
>> +	 * We don't have explicit peak requirement so keep it equal to avg_bw.
>> +	 */
>> +	ctrl->avg_bw_cpu = Bps_to_icc(speed_hz);
>> +	ctrl->peak_bw_cpu = ctrl->avg_bw_cpu;
>> +	ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, ctrl->avg_bw_cpu,
>> +		ctrl->peak_bw_cpu);
>> +	if (ret) {
>> +		dev_err(ctrl->dev, "%s: ICC BW voting failed for cpu\n",
>> +			__func__);
> the logging in this patch is inconsistent. Here the error is not printed,
> at all, in other cases it's "<error>, ret:-42" or "<error> ret:-42".
> Please stick to a common format (unless there is no error). My
> suggestion would be "<error>: -42", in my perception "ret:" just adds
> noise.

Okay.

Regards,

Akash

>
>> +		return ret;
>> +	}
>> +
>>   	spin_lock_irqsave(&ctrl->lock, flags);
>>   
>>   	/* We are half duplex, so either rx or tx will be set */
>> @@ -458,6 +476,29 @@ static int qcom_qspi_probe(struct platform_device *pdev)
>>   	if (ret)
>>   		goto exit_probe_master_put;
>>   
>> +	ctrl->icc_path_cpu_to_qspi = devm_of_icc_get(dev, "qspi-config");
>> +	if (IS_ERR(ctrl->icc_path_cpu_to_qspi)) {
>> +		ret = PTR_ERR(ctrl->icc_path_cpu_to_qspi);
>> +		if (ret != -EPROBE_DEFER)
>> +			dev_err(dev, "Failed to get cpu path, ret:%d\n", ret);
>> +		goto exit_probe_master_put;
>> +	}
>> +	/* Set BW vote for register access */
>> +	ret = icc_set_bw(ctrl->icc_path_cpu_to_qspi, Bps_to_icc(1000),
>> +				Bps_to_icc(1000));
>> +	if (ret) {
>> +		dev_err(ctrl->dev, "%s: ICC BW voting failed for cpu ret:%d\n",
>> +				__func__, ret);
>> +		goto exit_probe_master_put;
>> +	}
>> +
>> +	ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
>> +	if (ret) {
>> +		dev_err(ctrl->dev, "%s: ICC disable failed for cpu ret:%d\n",
>> +				__func__, ret);
>> +		goto exit_probe_master_put;
>> +	}
>> +
>>   	ret = platform_get_irq(pdev, 0);
>>   	if (ret < 0)
>>   		goto exit_probe_master_put;
>> @@ -511,9 +552,17 @@ static int __maybe_unused qcom_qspi_runtime_suspend(struct device *dev)
>>   {
>>   	struct spi_master *master = dev_get_drvdata(dev);
>>   	struct qcom_qspi *ctrl = spi_master_get_devdata(master);
>> +	int ret;
>>   
>>   	clk_bulk_disable_unprepare(QSPI_NUM_CLKS, ctrl->clks);
>>   
>> +	ret = icc_disable(ctrl->icc_path_cpu_to_qspi);
>> +	if (ret) {
>> +		dev_err_ratelimited(ctrl->dev, "%s: ICC disable failed for cpu ret:%d\n",
>> +			__func__, ret);
>> +		return ret;
>> +	}
>> +
>>   	return 0;
>>   }
>>   
>> @@ -521,6 +570,14 @@ static int __maybe_unused qcom_qspi_runtime_resume(struct device *dev)
>>   {
>>   	struct spi_master *master = dev_get_drvdata(dev);
>>   	struct qcom_qspi *ctrl = spi_master_get_devdata(master);
>> +	int ret;
>> +
>> +	ret = icc_enable(ctrl->icc_path_cpu_to_qspi);
>> +	if (ret) {
>> +		dev_err_ratelimited(ctrl->dev, "%s: ICC enable failed for cpu ret:%d\n",
>> +			__func__, ret);
>> +		return ret;
>> +	}
>>   
>>   	return clk_bulk_prepare_enable(QSPI_NUM_CLKS, ctrl->clks);
>>   }

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,\na Linux Foundation Collaborative Project

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

end of thread, back to index

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-08  6:33 [PATCH V5 0/7] Add interconnect support to QSPI and QUP drivers Akash Asthana
2020-05-08  6:33 ` [PATCH V5 1/7] soc: qcom: geni: Support for ICC voting Akash Asthana
2020-05-08 17:13   ` Matthias Kaehlcke
2020-05-12 14:02     ` Akash Asthana
2020-05-08 19:03   ` Matthias Kaehlcke
2020-05-12 14:26     ` Akash Asthana
2020-05-08  6:33 ` [PATCH V5 2/7] soc: qcom-geni-se: Add interconnect support to fix earlycon crash Akash Asthana
2020-05-08 17:59   ` Matthias Kaehlcke
2020-05-08 19:14     ` Matthias Kaehlcke
2020-05-14  7:03       ` Akash Asthana
2020-05-14  6:45     ` Akash Asthana
2020-05-09 12:11   ` Andy Shevchenko
2020-05-14  7:34     ` Akash Asthana
2020-05-08  6:33 ` [PATCH V5 3/7] i2c: i2c-qcom-geni: Add interconnect support Akash Asthana
2020-05-08 18:16   ` Matthias Kaehlcke
2020-05-15 10:03   ` Wolfram Sang
2020-05-08  6:33 ` [PATCH V5 4/7] spi: spi-geni-qcom: " Akash Asthana
2020-05-08 10:16   ` Mark Brown
2020-05-08 18:25   ` Matthias Kaehlcke
2020-05-14  7:37     ` Akash Asthana
2020-05-08  6:33 ` [PATCH V5 5/7] tty: serial: qcom_geni_serial: " Akash Asthana
2020-05-08 18:38   ` Matthias Kaehlcke
2020-05-08  6:33 ` [PATCH V5 6/7] spi: spi-qcom-qspi: " Akash Asthana
2020-05-08 10:16   ` Mark Brown
2020-05-08 18:53   ` Matthias Kaehlcke
2020-05-18 13:10     ` Akash Asthana
2020-05-08  6:33 ` [PATCH V5 7/7] arm64: dts: sc7180: Add interconnect for QUP and QSPI Akash Asthana

Linux-i2c Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-i2c/0 linux-i2c/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-i2c linux-i2c/ https://lore.kernel.org/linux-i2c \
		linux-i2c@vger.kernel.org
	public-inbox-index linux-i2c

Example config snippet for mirrors

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


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