linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs
@ 2019-06-27 13:34 Sibi Sankar
  2019-06-27 13:34 ` [PATCH RFC 1/4] OPP: Add and export helper to update voltage Sibi Sankar
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Sibi Sankar @ 2019-06-27 13:34 UTC (permalink / raw)
  To: viresh.kumar, nm, sboyd, georgi.djakov
  Cc: agross, david.brown, robh+dt, mark.rutland, rjw, linux-arm-msm,
	devicetree, linux-kernel, linux-pm, saravanak, Sibi Sankar

This RFC series aims to extend cpu based scaling support to L3/DDR on
SDM845 SoCs. The patch series depends on "Introduce OPP bandwidth bindings"
series (https://patchwork.kernel.org/cover/10912993/). A part of the
series will still be applicable if we decide to go ahead with the proposal
from Saravana as well so I decided to post this out.

v2:
* Incorporated Viresh's comments from:
[1]https://lore.kernel.org/lkml/20190410102429.r6j6brm5kspmqxc3@vireshk-i7/
[2]https://lore.kernel.org/lkml/20190410112516.gnh77jcwawvld6et@vireshk-i7/


Sibi Sankar (4):
  OPP: Add and export helper to update voltage
  OPP: Add and export helper to set bandwidth
  cpufreq: qcom: Update the bandwidth levels on frequency change
  arm64: dts: qcom: sdm845: Add cpu OPP tables

 arch/arm64/boot/dts/qcom/sdm845.dtsi | 343 +++++++++++++++++++++++++++
 drivers/cpufreq/qcom-cpufreq-hw.c    |  77 +++++-
 drivers/opp/core.c                   |  98 ++++++++
 include/linux/pm_opp.h               |  16 ++
 4 files changed, 532 insertions(+), 2 deletions(-)

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


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

* [PATCH RFC 1/4] OPP: Add and export helper to update voltage
  2019-06-27 13:34 [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Sibi Sankar
@ 2019-06-27 13:34 ` Sibi Sankar
  2019-06-28  8:20   ` Rajendra Nayak
  2019-06-27 13:34 ` [PATCH RFC 2/4] OPP: Add and export helper to set bandwidth Sibi Sankar
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Sibi Sankar @ 2019-06-27 13:34 UTC (permalink / raw)
  To: viresh.kumar, nm, sboyd, georgi.djakov
  Cc: agross, david.brown, robh+dt, mark.rutland, rjw, linux-arm-msm,
	devicetree, linux-kernel, linux-pm, saravanak, Sibi Sankar

Add and export 'dev_pm_opp_update_voltage' to find and update voltage
of an opp for a given frequency. This will be useful to update the opps
with voltages read back from firmware.

Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
---
 drivers/opp/core.c     | 52 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/pm_opp.h | 10 ++++++++
 2 files changed, 62 insertions(+)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 68551d6366e6b..c85c04dc2c7de 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -2197,6 +2197,58 @@ int dev_pm_opp_disable(struct device *dev, unsigned long freq)
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_disable);
 
+/**
+ * dev_pm_opp_update_voltage() - Find and update voltage
+ * @dev:	device for which we do this operation
+ * @freq:	OPP frequency to update voltage
+ * @u_volt:	voltage requested for this opp
+ *
+ * Find and update voltage of a disabled opp corresponding to the given
+ * frequency. This is useful only for devices with single power supply.
+ *
+ * Return: 0 if no modification was done OR modification was
+ * successful or a negative error value.
+ */
+int dev_pm_opp_update_voltage(struct device *dev, unsigned long freq,
+			      unsigned long u_volt)
+{
+	struct dev_pm_opp *opp = ERR_PTR(-ENODEV);
+	struct opp_table *opp_table;
+	unsigned long tol;
+	int ret = 0;
+
+	opp = dev_pm_opp_find_freq_exact(dev, freq, false);
+	if (IS_ERR(opp))
+		return PTR_ERR(opp);
+
+	/* Find the opp_table */
+	opp_table = _find_opp_table(dev);
+	if (IS_ERR(opp_table)) {
+		ret = PTR_ERR(opp_table);
+		dev_err(dev, "%s: OPP table not found (%d)\n", __func__, ret);
+		goto put_opp;
+	}
+
+	mutex_lock(&opp_table->lock);
+
+	/* update only if the opp is disabled */
+	if (opp->available)
+		goto unlock;
+
+	tol = u_volt * opp_table->voltage_tolerance_v1 / 100;
+	opp->supplies[0].u_volt_min = u_volt - tol;
+	opp->supplies[0].u_volt = u_volt;
+	opp->supplies[0].u_volt_min = u_volt + tol;
+
+unlock:
+	mutex_unlock(&opp_table->lock);
+	dev_pm_opp_put_opp_table(opp_table);
+put_opp:
+	dev_pm_opp_put(opp);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_update_voltage);
+
 /**
  * dev_pm_opp_register_notifier() - Register OPP notifier for the device
  * @dev:	Device for which notifier needs to be registered
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 87fa09d93d8c2..a17c462974851 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -130,6 +130,9 @@ int dev_pm_opp_enable(struct device *dev, unsigned long freq);
 
 int dev_pm_opp_disable(struct device *dev, unsigned long freq);
 
+int dev_pm_opp_update_voltage(struct device *dev, unsigned long freq,
+			      unsigned long u_volt);
+
 int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb);
 int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb);
 
@@ -261,6 +264,13 @@ static inline int dev_pm_opp_disable(struct device *dev, unsigned long freq)
 	return 0;
 }
 
+static inline int dev_pm_opp_update_voltage(struct device *dev,
+					    unsigned long freq,
+					    unsigned long u_volt)
+{
+	return 0;
+}
+
 static inline int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb)
 {
 	return -ENOTSUPP;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


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

* [PATCH RFC 2/4] OPP: Add and export helper to set bandwidth
  2019-06-27 13:34 [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Sibi Sankar
  2019-06-27 13:34 ` [PATCH RFC 1/4] OPP: Add and export helper to update voltage Sibi Sankar
@ 2019-06-27 13:34 ` Sibi Sankar
  2019-07-11 17:40   ` Bjorn Andersson
  2019-06-27 13:34 ` [PATCH RFC 3/4] cpufreq: qcom: Update the bandwidth levels on frequency change Sibi Sankar
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Sibi Sankar @ 2019-06-27 13:34 UTC (permalink / raw)
  To: viresh.kumar, nm, sboyd, georgi.djakov
  Cc: agross, david.brown, robh+dt, mark.rutland, rjw, linux-arm-msm,
	devicetree, linux-kernel, linux-pm, saravanak, Sibi Sankar

Add and export 'dev_pm_opp_set_bw' to set the bandwidth
levels associated with an OPP for a given frequency.

Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
---
 drivers/opp/core.c     | 46 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/pm_opp.h |  6 ++++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index c85c04dc2c7de..78f42960860d1 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -746,6 +746,52 @@ static int _set_required_opps(struct device *dev,
 	return ret;
 }
 
+/**
+ * dev_pm_opp_set_bw() - Configures OPP bandwidth levels
+ * @dev:	device for which we do this operation
+ * @freq:	bandwidth values to set with matching 'freq'
+ *
+ * This configures the bandwidth to the levels specified
+ * by the OPP corresponding to the given frequency.
+ *
+ * Return: 0 on success or a negative error value.
+ */
+int dev_pm_opp_set_bw(struct device *dev, unsigned long freq)
+{
+	struct opp_table *opp_table;
+	struct dev_pm_opp *opp;
+	int ret = 0;
+	int i;
+
+	opp = dev_pm_opp_find_freq_exact(dev, freq, true);
+	if (IS_ERR(opp))
+		return PTR_ERR(opp);
+
+	opp_table = _find_opp_table(dev);
+	if (IS_ERR(opp_table)) {
+		dev_err(dev, "%s: device opp table doesn't exist\n", __func__);
+		ret = PTR_ERR(opp_table);
+		goto put_opp;
+	}
+
+	if (IS_ERR_OR_NULL(opp_table->paths)) {
+		ret = -ENODEV;
+		goto put_opp_table;
+	}
+
+	for (i = 0; i < opp_table->path_count; i++) {
+		ret = icc_set_bw(opp_table->paths[i], opp->bandwidth[i].avg,
+				 opp->bandwidth[i].peak);
+	}
+
+put_opp_table:
+	dev_pm_opp_put_opp_table(opp_table);
+put_opp:
+	dev_pm_opp_put(opp);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_set_bw);
+
 /**
  * dev_pm_opp_set_rate() - Configure new OPP based on frequency
  * @dev:	 device for which we do this operation
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index a17c462974851..1cdc2d0a2b20e 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -152,6 +152,7 @@ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names
 void dev_pm_opp_detach_genpd(struct opp_table *opp_table);
 int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate);
 int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
+int dev_pm_opp_set_bw(struct device *dev, unsigned long freq);
 int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
 int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
 void dev_pm_opp_remove_table(struct device *dev);
@@ -336,6 +337,11 @@ static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_f
 	return -ENOTSUPP;
 }
 
+static inline int dev_pm_opp_set_bw(struct device *dev, unsigned long freq)
+{
+	return -ENOTSUPP;
+}
+
 static inline int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask)
 {
 	return -ENOTSUPP;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


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

* [PATCH RFC 3/4] cpufreq: qcom: Update the bandwidth levels on frequency change
  2019-06-27 13:34 [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Sibi Sankar
  2019-06-27 13:34 ` [PATCH RFC 1/4] OPP: Add and export helper to update voltage Sibi Sankar
  2019-06-27 13:34 ` [PATCH RFC 2/4] OPP: Add and export helper to set bandwidth Sibi Sankar
@ 2019-06-27 13:34 ` Sibi Sankar
  2019-06-28  8:25   ` Rajendra Nayak
  2019-06-27 13:34 ` [PATCH RFC 4/4] arm64: dts: qcom: sdm845: Add cpu OPP tables Sibi Sankar
  2019-07-01  9:29 ` [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Viresh Kumar
  4 siblings, 1 reply; 10+ messages in thread
From: Sibi Sankar @ 2019-06-27 13:34 UTC (permalink / raw)
  To: viresh.kumar, nm, sboyd, georgi.djakov
  Cc: agross, david.brown, robh+dt, mark.rutland, rjw, linux-arm-msm,
	devicetree, linux-kernel, linux-pm, saravanak, Sibi Sankar

Add support to parse and update optional OPP tables attached to the
cpu nodes when the OPP bandwidth values are populated to enable
scaling of DDR/L3 bandwidth levels with frequency change.

Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
---
 drivers/cpufreq/qcom-cpufreq-hw.c | 77 ++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 4b0b50403901b..eacc75fac9b00 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -6,6 +6,7 @@
 #include <linux/bitfield.h>
 #include <linux/cpufreq.h>
 #include <linux/init.h>
+#include <linux/interconnect.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
@@ -30,13 +31,41 @@
 static unsigned long cpu_hw_rate, xo_rate;
 static struct platform_device *global_pdev;
 
+static int qcom_cpufreq_set_bw(struct cpufreq_policy *policy,
+			       unsigned long freq_khz)
+{
+	struct device *dev;
+
+	dev = get_cpu_device(policy->cpu);
+	if (!dev)
+		return -ENODEV;
+
+	return dev_pm_opp_set_bw(dev, freq_khz * 1000);
+}
+
+static int qcom_cpufreq_update_opp(struct device *cpu_dev,
+				   unsigned long freq_khz,
+				   unsigned long volt)
+{
+	unsigned long freq_hz = freq_khz * 1000;
+
+	if (dev_pm_opp_update_voltage(cpu_dev, freq_hz, volt))
+		return dev_pm_opp_add(cpu_dev, freq_hz, volt);
+
+	/* Enable the opp after voltage update*/
+	return dev_pm_opp_enable(cpu_dev, freq_hz);
+}
+
 static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
 					unsigned int index)
 {
 	void __iomem *perf_state_reg = policy->driver_data;
+	u32 freq = policy->freq_table[index].frequency;
 
 	writel_relaxed(index, perf_state_reg);
 
+	qcom_cpufreq_set_bw(policy, freq);
+
 	return 0;
 }
 
@@ -79,13 +108,29 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
 {
 	u32 data, src, lval, i, core_count, prev_cc = 0, prev_freq = 0, freq;
 	u32 volt;
+	u64 rate;
 	unsigned int max_cores = cpumask_weight(policy->cpus);
 	struct cpufreq_frequency_table	*table;
+	struct device_node *opp_table_np, *np;
+	int ret;
 
 	table = kcalloc(LUT_MAX_ENTRIES + 1, sizeof(*table), GFP_KERNEL);
 	if (!table)
 		return -ENOMEM;
 
+	ret = dev_pm_opp_of_add_table(cpu_dev);
+	if (!ret) {
+		/* Disable all opps and cross-validate against LUT */
+		opp_table_np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+		for_each_available_child_of_node(opp_table_np, np) {
+			ret = of_property_read_u64(np, "opp-hz", &rate);
+			dev_pm_opp_disable(cpu_dev, rate);
+		}
+		of_node_put(opp_table_np);
+	} else {
+		dev_err(cpu_dev, "Couldn't add OPP table from dt\n");
+	}
+
 	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
 		data = readl_relaxed(base + REG_FREQ_LUT +
 				      i * LUT_ROW_SIZE);
@@ -104,7 +149,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
 
 		if (freq != prev_freq && core_count == max_cores) {
 			table[i].frequency = freq;
-			dev_pm_opp_add(cpu_dev, freq * 1000, volt);
+			qcom_cpufreq_update_opp(cpu_dev, freq, volt);
 			dev_dbg(cpu_dev, "index=%d freq=%d, core_count %d\n", i,
 				freq, core_count);
 		} else {
@@ -125,7 +170,8 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
 			if (prev_cc != max_cores) {
 				prev->frequency = prev_freq;
 				prev->flags = CPUFREQ_BOOST_FREQ;
-				dev_pm_opp_add(cpu_dev,	prev_freq * 1000, volt);
+				qcom_cpufreq_update_opp(cpu_dev, prev_freq,
+							volt);
 			}
 
 			break;
@@ -168,6 +214,7 @@ static void qcom_get_related_cpus(int index, struct cpumask *m)
 static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 {
 	struct device *dev = &global_pdev->dev;
+	struct opp_table *opp_table = NULL;
 	struct of_phandle_args args;
 	struct device_node *cpu_np;
 	struct device *cpu_dev;
@@ -202,6 +249,8 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 	if (!base)
 		return -ENOMEM;
 
+	opp_table = dev_pm_opp_set_paths(cpu_dev);
+
 	/* HW should be in enabled state to proceed */
 	if (!(readl_relaxed(base + REG_ENABLE) & 0x1)) {
 		dev_err(dev, "Domain-%d cpufreq hardware not enabled\n", index);
@@ -237,6 +286,8 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 
 	return 0;
 error:
+	if (opp_table)
+		dev_pm_opp_put_paths(opp_table);
 	devm_iounmap(dev, base);
 	return ret;
 }
@@ -275,6 +326,8 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = {
 
 static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
 {
+	struct opp_table *opp_table = NULL;
+	struct device *cpu_dev;
 	struct clk *clk;
 	int ret;
 
@@ -294,6 +347,26 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
 
 	global_pdev = pdev;
 
+	/* Check for optional interconnect paths on CPU0 */
+	cpu_dev = get_cpu_device(0);
+	if (!cpu_dev) {
+		dev_err(&pdev->dev, "failed to get cpu0 device\n");
+		return -ENODEV;
+	}
+
+	opp_table = dev_pm_opp_set_paths(cpu_dev);
+	if (IS_ERR(opp_table)) {
+		ret = PTR_ERR(opp_table);
+		if (ret == -EPROBE_DEFER) {
+			dev_dbg(&pdev->dev, "defer icc set paths: %d\n", ret);
+			return ret;
+		}
+		dev_err(&pdev->dev, "set paths failed ddr/l3 scaling off: %d\n",
+			ret);
+	} else {
+		dev_pm_opp_put_paths(opp_table);
+	}
+
 	ret = cpufreq_register_driver(&cpufreq_qcom_hw_driver);
 	if (ret)
 		dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


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

* [PATCH RFC 4/4] arm64: dts: qcom: sdm845: Add cpu OPP tables
  2019-06-27 13:34 [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Sibi Sankar
                   ` (2 preceding siblings ...)
  2019-06-27 13:34 ` [PATCH RFC 3/4] cpufreq: qcom: Update the bandwidth levels on frequency change Sibi Sankar
@ 2019-06-27 13:34 ` Sibi Sankar
  2019-07-01  9:29 ` [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Viresh Kumar
  4 siblings, 0 replies; 10+ messages in thread
From: Sibi Sankar @ 2019-06-27 13:34 UTC (permalink / raw)
  To: viresh.kumar, nm, sboyd, georgi.djakov
  Cc: agross, david.brown, robh+dt, mark.rutland, rjw, linux-arm-msm,
	devicetree, linux-kernel, linux-pm, saravanak, Sibi Sankar

Add OPP tables for the cpu nodes.

Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 343 +++++++++++++++++++++++++++
 1 file changed, 343 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 471cbb7d9bc39..8cabbb274d3e7 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -197,6 +197,10 @@
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			#cooling-cells = <2>;
 			next-level-cache = <&L2_0>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			/* path between CPU and DDR memory and CPU and L3 */
+			interconnects = <&rsc_hlos MASTER_APPSS_PROC &rsc_hlos SLAVE_EBI1>,
+					<&rsc_hlos MASTER_APPSS_PROC &osm_l3 SLAVE_OSM_L3>;
 			L2_0: l2-cache {
 				compatible = "cache";
 				next-level-cache = <&L3_0>;
@@ -218,6 +222,10 @@
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			#cooling-cells = <2>;
 			next-level-cache = <&L2_100>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			/* path between CPU and DDR memory and CPU and L3 */
+			interconnects = <&rsc_hlos MASTER_APPSS_PROC &rsc_hlos SLAVE_EBI1>,
+					<&rsc_hlos MASTER_APPSS_PROC &osm_l3 SLAVE_OSM_L3>;
 			L2_100: l2-cache {
 				compatible = "cache";
 				next-level-cache = <&L3_0>;
@@ -236,6 +244,10 @@
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			#cooling-cells = <2>;
 			next-level-cache = <&L2_200>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			/* path between CPU and DDR memory and CPU and L3 */
+			interconnects = <&rsc_hlos MASTER_APPSS_PROC &rsc_hlos SLAVE_EBI1>,
+					<&rsc_hlos MASTER_APPSS_PROC &osm_l3 SLAVE_OSM_L3>;
 			L2_200: l2-cache {
 				compatible = "cache";
 				next-level-cache = <&L3_0>;
@@ -254,6 +266,10 @@
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			#cooling-cells = <2>;
 			next-level-cache = <&L2_300>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			/* path between CPU and DDR memory and CPU and L3 */
+			interconnects = <&rsc_hlos MASTER_APPSS_PROC &rsc_hlos SLAVE_EBI1>,
+					<&rsc_hlos MASTER_APPSS_PROC &osm_l3 SLAVE_OSM_L3>;
 			L2_300: l2-cache {
 				compatible = "cache";
 				next-level-cache = <&L3_0>;
@@ -272,6 +288,10 @@
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			#cooling-cells = <2>;
 			next-level-cache = <&L2_400>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			/* path between CPU and DDR memory and CPU and L3 */
+			interconnects = <&rsc_hlos MASTER_APPSS_PROC &rsc_hlos SLAVE_EBI1>,
+					<&rsc_hlos MASTER_APPSS_PROC &osm_l3 SLAVE_OSM_L3>;
 			L2_400: l2-cache {
 				compatible = "cache";
 				next-level-cache = <&L3_0>;
@@ -290,6 +310,10 @@
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			#cooling-cells = <2>;
 			next-level-cache = <&L2_500>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			/* path between CPU and DDR memory and CPU and L3 */
+			interconnects = <&rsc_hlos MASTER_APPSS_PROC &rsc_hlos SLAVE_EBI1>,
+					<&rsc_hlos MASTER_APPSS_PROC &osm_l3 SLAVE_OSM_L3>;
 			L2_500: l2-cache {
 				compatible = "cache";
 				next-level-cache = <&L3_0>;
@@ -308,6 +332,10 @@
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			#cooling-cells = <2>;
 			next-level-cache = <&L2_600>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			/* path between CPU and DDR memory and CPU and L3 */
+			interconnects = <&rsc_hlos MASTER_APPSS_PROC &rsc_hlos SLAVE_EBI1>,
+					<&rsc_hlos MASTER_APPSS_PROC &osm_l3 SLAVE_OSM_L3>;
 			L2_600: l2-cache {
 				compatible = "cache";
 				next-level-cache = <&L3_0>;
@@ -326,6 +354,10 @@
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			#cooling-cells = <2>;
 			next-level-cache = <&L2_700>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			/* path between CPU and DDR memory and CPU and L3 */
+			interconnects = <&rsc_hlos MASTER_APPSS_PROC &rsc_hlos SLAVE_EBI1>,
+					<&rsc_hlos MASTER_APPSS_PROC &osm_l3 SLAVE_OSM_L3>;
 			L2_700: l2-cache {
 				compatible = "cache";
 				next-level-cache = <&L3_0>;
@@ -423,6 +455,317 @@
 		};
 	};
 
+	cpu0_opp_table: cpu0_opp_table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		cpu0_opp1: opp-300000000 {
+			opp-hz = /bits/ 64 <300000000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 762 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 4577 MB/s peak */
+			bandwidth-MBps = <0 762>, <0 4577>;
+		};
+
+		cpu0_opp2: opp-403200000 {
+			opp-hz = /bits/ 64 <403200000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 762 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 4577 MB/s peak */
+			bandwidth-MBps = <0 762>, <0 4577>;
+		};
+
+		cpu0_opp3: opp-480000000 {
+			opp-hz = /bits/ 64 <480000000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 762 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 6152 MB/s peak */
+			bandwidth-MBps = <0 762>, <0 6152>;
+		};
+
+		cpu0_opp4: opp-576000000 {
+			opp-hz = /bits/ 64 <576000000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 762 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 6152 MB/s peak */
+			bandwidth-MBps = <0 762>, <0 6152>;
+		};
+
+		cpu0_opp5: opp-652800000 {
+			opp-hz = /bits/ 64 <652800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 762 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 7324 MB/s peak */
+			bandwidth-MBps = <0 762>, <0 7324>;
+		};
+
+		cpu0_opp6: opp-748800000 {
+			opp-hz = /bits/ 64 <748800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 1720 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 8789 MB/s peak */
+			bandwidth-MBps = <0 1720>, <0 8789>;
+		};
+
+		cpu0_opp7: opp-825600000 {
+			opp-hz = /bits/ 64 <825600000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 1720 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 8789 MB/s peak */
+			bandwidth-MBps = <0 1720>, <0 8789>;
+		};
+
+		cpu0_opp8: opp-902400000 {
+			opp-hz = /bits/ 64 <902400000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 1720 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 9960 MB/s peak */
+			bandwidth-MBps = <0 1720>, <0 9960>;
+		};
+
+		cpu0_opp9: opp-979200000 {
+			opp-hz = /bits/ 64 <979200000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 1720 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 11425 MB/s peak */
+			bandwidth-MBps = <0 1720>, <0 11425>;
+		};
+
+		cpu0_opp10: opp-1056000000 {
+			opp-hz = /bits/ 64 <1056000000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 1720 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 11425 MB/s peak */
+			bandwidth-MBps = <0 1720>, <0 11425>;
+		};
+
+		cpu0_opp11: opp-1132800000 {
+			opp-hz = /bits/ 64 <1132800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 2086 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 12890 MB/s peak */
+			bandwidth-MBps = <0 2086>, <0 12890>;
+		};
+
+		cpu0_opp12: opp-1228800000 {
+			opp-hz = /bits/ 64 <1228800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 2086 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 14355 MB/s peak */
+			bandwidth-MBps = <0 2086>, <0 14355>;
+		};
+
+		cpu0_opp13: opp-1324800000 {
+			opp-hz = /bits/ 64 <1324800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 2086 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 15820 MB/s peak */
+			bandwidth-MBps = <0 2086>, <0 15820>;
+		};
+
+		cpu0_opp14: opp-1420800000 {
+			opp-hz = /bits/ 64 <1420800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 2086 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 17285 MB/s peak */
+			bandwidth-MBps = <0 2086>, <0 17285>;
+		};
+
+		cpu0_opp15: opp-1516800000 {
+			opp-hz = /bits/ 64 <1516800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 2597 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 18457 MB/s peak */
+			bandwidth-MBps = <0 2597>, <0 18457>;
+		};
+
+		cpu0_opp16: opp-1612800000 {
+			opp-hz = /bits/ 64 <1612800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 3879 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 18457 MB/s peak */
+			bandwidth-MBps = <0 3879>, <0 18457>;
+		};
+
+		cpu0_opp17: opp-1689600000 {
+			opp-hz = /bits/ 64 <1689600000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 3879 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 19921 MB/s peak */
+			bandwidth-MBps = <0 3879>, <0 19921>;
+		};
+
+		cpu0_opp18: opp-1766400000 {
+			opp-hz = /bits/ 64 <1766400000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 3879 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 21386 MB/s peak */
+			bandwidth-MBps = <0 3879>, <0 21386>;
+		};
+	};
+
+	cpu4_opp_table: cpu4_opp_table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		cpu4_opp1: opp-825600000 {
+			opp-hz = /bits/ 64 <825600000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 1144 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 8789 MB/s peak */
+			bandwidth-MBps = <0 1144>, <0 8789>;
+		};
+
+		cpu4_opp2: opp-902400000 {
+			opp-hz = /bits/ 64 <902400000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 1144 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 8789 MB/s peak */
+			bandwidth-MBps = <0 1144>, <0 8789>;
+		};
+
+		cpu4_opp3: opp-979200000 {
+			opp-hz = /bits/ 64 <979200000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 1144 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 8789 MB/s peak */
+			bandwidth-MBps = <0 1144>, <0 8789>;
+		};
+
+		cpu4_opp4: opp-1056000000 {
+			opp-hz = /bits/ 64 <1056000000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 2929 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 11425 MB/s peak */
+			bandwidth-MBps = <0 2929>, <0 11425>;
+		};
+
+		cpu4_opp5: opp-1209600000 {
+			opp-hz = /bits/ 64 <1209600000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 3879 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 11425 MB/s peak */
+			bandwidth-MBps = <0 3879>, <0 11425>;
+		};
+
+		cpu4_opp6: opp-1286400000 {
+			opp-hz = /bits/ 64 <1286400000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 3879 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 11425 MB/s peak */
+			bandwidth-MBps = <0 3879>, <0 11425>;
+		};
+
+		cpu4_opp7: opp-1363200000 {
+			opp-hz = /bits/ 64 <1363200000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 3879 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 14355 MB/s peak */
+			bandwidth-MBps = <0 3879>, <0 14355>;
+		};
+
+		cpu4_opp8: opp-1459200000 {
+			opp-hz = /bits/ 64 <1459200000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 3879 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 14355 MB/s peak */
+			bandwidth-MBps = <0 3879>, <0 14355>;
+		};
+
+		cpu4_opp9: opp-1536000000 {
+			opp-hz = /bits/ 64 <1536000000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 3879 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 14355 MB/s peak */
+			bandwidth-MBps = <0 3879>, <0 14355>;
+		};
+
+		cpu4_opp10: opp-1612800000 {
+			opp-hz = /bits/ 64 <1612800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 4943 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 14355 MB/s peak */
+			bandwidth-MBps = <0 4943>, <0 14355>;
+		};
+
+		cpu4_opp11: opp-1689600000 {
+			opp-hz = /bits/ 64 <1689600000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 4943 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 18457 MB/s peak */
+			bandwidth-MBps = <0 4943>, <0 18457>;
+		};
+
+		cpu4_opp12: opp-1766400000 {
+			opp-hz = /bits/ 64 <1766400000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 5931 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 18457 MB/s peak */
+			bandwidth-MBps = <0 5931>, <0 18457>;
+		};
+
+		cpu4_opp13: opp-1843200000 {
+			opp-hz = /bits/ 64 <1843200000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 5931 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 18457 MB/s peak */
+			bandwidth-MBps = <0 5931>, <0 18457>;
+		};
+
+		cpu4_opp14: opp-1920000000 {
+			opp-hz = /bits/ 64 <1920000000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 5931 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 18457 MB/s peak */
+			bandwidth-MBps = <0 5931>, <0 18457>;
+		};
+
+		cpu4_opp15: opp-1996800000 {
+			opp-hz = /bits/ 64 <1996800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 19921 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 19921>;
+		};
+
+		cpu4_opp16: opp-2092800000 {
+			opp-hz = /bits/ 64 <2092800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 19921 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 19921>;
+		};
+
+		cpu4_opp17: opp-2169600000 {
+			opp-hz = /bits/ 64 <2169600000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 19921 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 19921>;
+		};
+
+		cpu4_opp18: opp-2246400000 {
+			opp-hz = /bits/ 64 <2246400000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 19921 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 19921>;
+		};
+
+		cpu4_opp19: opp-2323200000 {
+			opp-hz = /bits/ 64 <2323200000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 19921 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 19921>;
+		};
+
+		cpu4_opp20: opp-2400000000 {
+			opp-hz = /bits/ 64 <2400000000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 21386 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 21386>;
+		};
+
+		cpu4_opp21: opp-2476800000 {
+			opp-hz = /bits/ 64 <2476800000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 21386 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 21386>;
+		};
+
+		cpu4_opp22: opp-2553600000 {
+			opp-hz = /bits/ 64 <2553600000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 21386 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 21386>;
+		};
+
+		cpu4_opp23: opp-2649600000 {
+			opp-hz = /bits/ 64 <2649600000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 21386 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 21386>;
+		};
+
+		cpu4_opp24: opp-2745600000 {
+			opp-hz = /bits/ 64 <2745600000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 22558 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 22558>;
+		};
+
+		cpu4_opp25: opp-2803200000 {
+			opp-hz = /bits/ 64 <2803200000>;
+			/* CPU<->DDR bandwidth: 0 MB/s average, 6881 MB/s peak */
+			/* CPU<->L3 bandwidth: 0 MB/s average, 22558 MB/s peak */
+			bandwidth-MBps = <0 6881>, <0 22558>;
+		};
+	};
+
 	pmu {
 		compatible = "arm,armv8-pmuv3";
 		interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH>;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


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

* Re: [PATCH RFC 1/4] OPP: Add and export helper to update voltage
  2019-06-27 13:34 ` [PATCH RFC 1/4] OPP: Add and export helper to update voltage Sibi Sankar
@ 2019-06-28  8:20   ` Rajendra Nayak
  0 siblings, 0 replies; 10+ messages in thread
From: Rajendra Nayak @ 2019-06-28  8:20 UTC (permalink / raw)
  To: Sibi Sankar, viresh.kumar, nm, sboyd, georgi.djakov
  Cc: agross, david.brown, robh+dt, mark.rutland, rjw, linux-arm-msm,
	devicetree, linux-kernel, linux-pm, saravanak



On 6/27/2019 7:04 PM, Sibi Sankar wrote:
> Add and export 'dev_pm_opp_update_voltage' to find and update voltage
> of an opp for a given frequency. This will be useful to update the opps
> with voltages read back from firmware.
> 
> Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
> ---
>   drivers/opp/core.c     | 52 ++++++++++++++++++++++++++++++++++++++++++
>   include/linux/pm_opp.h | 10 ++++++++
>   2 files changed, 62 insertions(+)
> 
> diff --git a/drivers/opp/core.c b/drivers/opp/core.c
> index 68551d6366e6b..c85c04dc2c7de 100644
> --- a/drivers/opp/core.c
> +++ b/drivers/opp/core.c
> @@ -2197,6 +2197,58 @@ int dev_pm_opp_disable(struct device *dev, unsigned long freq)
>   }
>   EXPORT_SYMBOL_GPL(dev_pm_opp_disable);
>   
> +/**
> + * dev_pm_opp_update_voltage() - Find and update voltage
> + * @dev:	device for which we do this operation
> + * @freq:	OPP frequency to update voltage
> + * @u_volt:	voltage requested for this opp
> + *
> + * Find and update voltage of a disabled opp corresponding to the given
> + * frequency. This is useful only for devices with single power supply.
> + *
> + * Return: 0 if no modification was done OR modification was
> + * successful or a negative error value.
> + */
> +int dev_pm_opp_update_voltage(struct device *dev, unsigned long freq,
> +			      unsigned long u_volt)
> +{
> +	struct dev_pm_opp *opp = ERR_PTR(-ENODEV);
> +	struct opp_table *opp_table;
> +	unsigned long tol;
> +	int ret = 0;
> +
> +	opp = dev_pm_opp_find_freq_exact(dev, freq, false);
> +	if (IS_ERR(opp))
> +		return PTR_ERR(opp);
> +
> +	/* Find the opp_table */
> +	opp_table = _find_opp_table(dev);

maybe you should look for the opp_table first and then the
opp? otherwise this check seems pretty redundant given the
above call would have failed if the opp table did not exist.

> +	if (IS_ERR(opp_table)) {
> +		ret = PTR_ERR(opp_table);
> +		dev_err(dev, "%s: OPP table not found (%d)\n", __func__, ret);
> +		goto put_opp;
> +	}
> +
> +	mutex_lock(&opp_table->lock);
> +
> +	/* update only if the opp is disabled */
> +	if (opp->available)
> +		goto unlock;

should this throw a warning/error to indicate someone tried to
update this at a wrong time? and perhaps return an error instead of
success.

> +
> +	tol = u_volt * opp_table->voltage_tolerance_v1 / 100;
> +	opp->supplies[0].u_volt_min = u_volt - tol;
> +	opp->supplies[0].u_volt = u_volt;
> +	opp->supplies[0].u_volt_min = u_volt + tol;
> +
> +unlock:
> +	mutex_unlock(&opp_table->lock);
> +	dev_pm_opp_put_opp_table(opp_table);
> +put_opp:
> +	dev_pm_opp_put(opp);
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(dev_pm_opp_update_voltage);
> +
>   /**
>    * dev_pm_opp_register_notifier() - Register OPP notifier for the device
>    * @dev:	Device for which notifier needs to be registered
> diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
> index 87fa09d93d8c2..a17c462974851 100644
> --- a/include/linux/pm_opp.h
> +++ b/include/linux/pm_opp.h
> @@ -130,6 +130,9 @@ int dev_pm_opp_enable(struct device *dev, unsigned long freq);
>   
>   int dev_pm_opp_disable(struct device *dev, unsigned long freq);
>   
> +int dev_pm_opp_update_voltage(struct device *dev, unsigned long freq,
> +			      unsigned long u_volt);
> +
>   int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb);
>   int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb);
>   
> @@ -261,6 +264,13 @@ static inline int dev_pm_opp_disable(struct device *dev, unsigned long freq)
>   	return 0;
>   }
>   
> +static inline int dev_pm_opp_update_voltage(struct device *dev,
> +					    unsigned long freq,
> +					    unsigned long u_volt)
> +{
> +	return 0;
> +}
> +
>   static inline int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block *nb)
>   {
>   	return -ENOTSUPP;
> 

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH RFC 3/4] cpufreq: qcom: Update the bandwidth levels on frequency change
  2019-06-27 13:34 ` [PATCH RFC 3/4] cpufreq: qcom: Update the bandwidth levels on frequency change Sibi Sankar
@ 2019-06-28  8:25   ` Rajendra Nayak
  0 siblings, 0 replies; 10+ messages in thread
From: Rajendra Nayak @ 2019-06-28  8:25 UTC (permalink / raw)
  To: Sibi Sankar, viresh.kumar, nm, sboyd, georgi.djakov
  Cc: agross, david.brown, robh+dt, mark.rutland, rjw, linux-arm-msm,
	devicetree, linux-kernel, linux-pm, saravanak


On 6/27/2019 7:04 PM, Sibi Sankar wrote:
> Add support to parse and update optional OPP tables attached to the
> cpu nodes when the OPP bandwidth values are populated to enable
> scaling of DDR/L3 bandwidth levels with frequency change.
> 
> Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
> ---
[]...

>   
> @@ -79,13 +108,29 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
>   {
>   	u32 data, src, lval, i, core_count, prev_cc = 0, prev_freq = 0, freq;
>   	u32 volt;
> +	u64 rate;
>   	unsigned int max_cores = cpumask_weight(policy->cpus);
>   	struct cpufreq_frequency_table	*table;
> +	struct device_node *opp_table_np, *np;
> +	int ret;
>   
>   	table = kcalloc(LUT_MAX_ENTRIES + 1, sizeof(*table), GFP_KERNEL);
>   	if (!table)
>   		return -ENOMEM;
>   
> +	ret = dev_pm_opp_of_add_table(cpu_dev);
> +	if (!ret) {
> +		/* Disable all opps and cross-validate against LUT */
> +		opp_table_np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
> +		for_each_available_child_of_node(opp_table_np, np) {
> +			ret = of_property_read_u64(np, "opp-hz", &rate);
> +			dev_pm_opp_disable(cpu_dev, rate);
> +		}
> +		of_node_put(opp_table_np);
> +	} else {
> +		dev_err(cpu_dev, "Couldn't add OPP table from dt\n");

The changelog seems to suggest specifying OPP tables in DT is optional,
but here we seem to error out if the tables are missing.

> +	}
> +
>   	for (i = 0; i < LUT_MAX_ENTRIES; i++) {
>   		data = readl_relaxed(base + REG_FREQ_LUT +
>   				      i * LUT_ROW_SIZE);
> @@ -104,7 +149,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
>   
>   		if (freq != prev_freq && core_count == max_cores) {
>   			table[i].frequency = freq;
> -			dev_pm_opp_add(cpu_dev, freq * 1000, volt);
> +			qcom_cpufreq_update_opp(cpu_dev, freq, volt);
>   			dev_dbg(cpu_dev, "index=%d freq=%d, core_count %d\n", i,
>   				freq, core_count);
>   		} else {
> @@ -125,7 +170,8 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
>   			if (prev_cc != max_cores) {
>   				prev->frequency = prev_freq;
>   				prev->flags = CPUFREQ_BOOST_FREQ;
> -				dev_pm_opp_add(cpu_dev,	prev_freq * 1000, volt);
> +				qcom_cpufreq_update_opp(cpu_dev, prev_freq,
> +							volt);
>   			}
>   
>   			break;
> @@ -168,6 +214,7 @@ static void qcom_get_related_cpus(int index, struct cpumask *m)
>   static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
>   {
>   	struct device *dev = &global_pdev->dev;
> +	struct opp_table *opp_table = NULL;
>   	struct of_phandle_args args;
>   	struct device_node *cpu_np;
>   	struct device *cpu_dev;
> @@ -202,6 +249,8 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
>   	if (!base)
>   		return -ENOMEM;
>   
> +	opp_table = dev_pm_opp_set_paths(cpu_dev);
> +
>   	/* HW should be in enabled state to proceed */
>   	if (!(readl_relaxed(base + REG_ENABLE) & 0x1)) {
>   		dev_err(dev, "Domain-%d cpufreq hardware not enabled\n", index);
> @@ -237,6 +286,8 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
>   
>   	return 0;
>   error:
> +	if (opp_table)
> +		dev_pm_opp_put_paths(opp_table);
>   	devm_iounmap(dev, base);
>   	return ret;
>   }
> @@ -275,6 +326,8 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = {
>   
>   static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
>   {
> +	struct opp_table *opp_table = NULL;
> +	struct device *cpu_dev;
>   	struct clk *clk;
>   	int ret;
>   
> @@ -294,6 +347,26 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
>   
>   	global_pdev = pdev;
>   
> +	/* Check for optional interconnect paths on CPU0 */
> +	cpu_dev = get_cpu_device(0);
> +	if (!cpu_dev) {
> +		dev_err(&pdev->dev, "failed to get cpu0 device\n");
> +		return -ENODEV;
> +	}
> +
> +	opp_table = dev_pm_opp_set_paths(cpu_dev);
> +	if (IS_ERR(opp_table)) {
> +		ret = PTR_ERR(opp_table);
> +		if (ret == -EPROBE_DEFER) {
> +			dev_dbg(&pdev->dev, "defer icc set paths: %d\n", ret);
> +			return ret;
> +		}
> +		dev_err(&pdev->dev, "set paths failed ddr/l3 scaling off: %d\n",
> +			ret);

Here again, the interconnect paths don't seem to be optional as the comment
above suggests.

> +	} else {
> +		dev_pm_opp_put_paths(opp_table);
> +	}
> +
>   	ret = cpufreq_register_driver(&cpufreq_qcom_hw_driver);
>   	if (ret)
>   		dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n");
> 

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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

* Re: [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs
  2019-06-27 13:34 [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Sibi Sankar
                   ` (3 preceding siblings ...)
  2019-06-27 13:34 ` [PATCH RFC 4/4] arm64: dts: qcom: sdm845: Add cpu OPP tables Sibi Sankar
@ 2019-07-01  9:29 ` Viresh Kumar
  2019-07-10 14:14   ` Sibi Sankar
  4 siblings, 1 reply; 10+ messages in thread
From: Viresh Kumar @ 2019-07-01  9:29 UTC (permalink / raw)
  To: Sibi Sankar
  Cc: nm, sboyd, georgi.djakov, agross, david.brown, robh+dt,
	mark.rutland, rjw, linux-arm-msm, devicetree, linux-kernel,
	linux-pm, saravanak

On 27-06-19, 19:04, Sibi Sankar wrote:
> This RFC series aims to extend cpu based scaling support to L3/DDR on
> SDM845 SoCs. The patch series depends on "Introduce OPP bandwidth bindings"
> series (https://patchwork.kernel.org/cover/10912993/). A part of the
> series will still be applicable if we decide to go ahead with the proposal
> from Saravana as well so I decided to post this out.
> 
> v2:
> * Incorporated Viresh's comments from:
> [1]https://lore.kernel.org/lkml/20190410102429.r6j6brm5kspmqxc3@vireshk-i7/
> [2]https://lore.kernel.org/lkml/20190410112516.gnh77jcwawvld6et@vireshk-i7/

Did you get a chance to look at this ?

lore.kernel.org/lkml/20190622003449.33707-1-saravanak@google.com

-- 
viresh

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

* Re: [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs
  2019-07-01  9:29 ` [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Viresh Kumar
@ 2019-07-10 14:14   ` Sibi Sankar
  0 siblings, 0 replies; 10+ messages in thread
From: Sibi Sankar @ 2019-07-10 14:14 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: nm, sboyd, georgi.djakov, agross, david.brown, robh+dt,
	mark.rutland, rjw, linux-arm-msm, devicetree, linux-kernel,
	linux-pm, saravanak, linux-kernel-owner, adharmap

Hey Viresh,

On 2019-07-01 14:59, Viresh Kumar wrote:
> On 27-06-19, 19:04, Sibi Sankar wrote:
>> This RFC series aims to extend cpu based scaling support to L3/DDR on
>> SDM845 SoCs. The patch series depends on "Introduce OPP bandwidth 
>> bindings"
>> series (https://patchwork.kernel.org/cover/10912993/). A part of the
>> series will still be applicable if we decide to go ahead with the 
>> proposal
>> from Saravana as well so I decided to post this out.
>> 
>> v2:
>> * Incorporated Viresh's comments from:
>> [1]https://lore.kernel.org/lkml/20190410102429.r6j6brm5kspmqxc3@vireshk-i7/
>> [2]https://lore.kernel.org/lkml/20190410112516.gnh77jcwawvld6et@vireshk-i7/
> 
> Did you get a chance to look at this ?
> 
> lore.kernel.org/lkml/20190622003449.33707-1-saravanak@google.com

Yes, I have v2 of cpufreq passive governor
patch in the works based on Saravana's
series. I plan on posting it out end of
week. I had sent this series out
since a portion (specifically update_
voltage helper and adding opp_tables
to cpufreq-hw driver) would remain
constant irrespective of the path
we choose.

FWIW, on SDM845 SoCs we cannot use a
rpmh_write_batch based icc_set on
cpufreq fast switch pathw since it
uses the "wait_for_completion" api.


-- 
-- Sibi Sankar --
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project.

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

* Re: [PATCH RFC 2/4] OPP: Add and export helper to set bandwidth
  2019-06-27 13:34 ` [PATCH RFC 2/4] OPP: Add and export helper to set bandwidth Sibi Sankar
@ 2019-07-11 17:40   ` Bjorn Andersson
  0 siblings, 0 replies; 10+ messages in thread
From: Bjorn Andersson @ 2019-07-11 17:40 UTC (permalink / raw)
  To: Sibi Sankar
  Cc: viresh.kumar, nm, sboyd, georgi.djakov, agross, david.brown,
	robh+dt, mark.rutland, rjw, linux-arm-msm, devicetree,
	linux-kernel, linux-pm, saravanak

On Thu 27 Jun 06:34 PDT 2019, Sibi Sankar wrote:

> Add and export 'dev_pm_opp_set_bw' to set the bandwidth
> levels associated with an OPP for a given frequency.
> 

While this looks quite reasonable I'm uncertain about the overall OPP
API.

With the profiling based (bwmon/llcc) approach we would acquire the peak
bandwidth from the OPP table and calculate the average dynamically,
based on measurements and heuristics.

For that I think we will have a struct dev_pm_opp at hand (e.g. from
devfreq_recommended_opp() or similar), from which we want to read the
peak value and then apply the icc vote. Or would we want to update the
avg bw and then apply the opp using a method like this? (In which case
we probably don't want to pass a freq, but a struct dev_pm_opp *, to
avoid the additional lookup)

Regards,
Bjorn

> Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
> ---
>  drivers/opp/core.c     | 46 ++++++++++++++++++++++++++++++++++++++++++
>  include/linux/pm_opp.h |  6 ++++++
>  2 files changed, 52 insertions(+)
> 
> diff --git a/drivers/opp/core.c b/drivers/opp/core.c
> index c85c04dc2c7de..78f42960860d1 100644
> --- a/drivers/opp/core.c
> +++ b/drivers/opp/core.c
> @@ -746,6 +746,52 @@ static int _set_required_opps(struct device *dev,
>  	return ret;
>  }
>  
> +/**
> + * dev_pm_opp_set_bw() - Configures OPP bandwidth levels
> + * @dev:	device for which we do this operation
> + * @freq:	bandwidth values to set with matching 'freq'
> + *
> + * This configures the bandwidth to the levels specified
> + * by the OPP corresponding to the given frequency.
> + *
> + * Return: 0 on success or a negative error value.
> + */
> +int dev_pm_opp_set_bw(struct device *dev, unsigned long freq)
> +{
> +	struct opp_table *opp_table;
> +	struct dev_pm_opp *opp;
> +	int ret = 0;
> +	int i;
> +
> +	opp = dev_pm_opp_find_freq_exact(dev, freq, true);
> +	if (IS_ERR(opp))
> +		return PTR_ERR(opp);
> +
> +	opp_table = _find_opp_table(dev);
> +	if (IS_ERR(opp_table)) {
> +		dev_err(dev, "%s: device opp table doesn't exist\n", __func__);
> +		ret = PTR_ERR(opp_table);
> +		goto put_opp;
> +	}
> +
> +	if (IS_ERR_OR_NULL(opp_table->paths)) {
> +		ret = -ENODEV;
> +		goto put_opp_table;
> +	}
> +
> +	for (i = 0; i < opp_table->path_count; i++) {
> +		ret = icc_set_bw(opp_table->paths[i], opp->bandwidth[i].avg,
> +				 opp->bandwidth[i].peak);
> +	}
> +
> +put_opp_table:
> +	dev_pm_opp_put_opp_table(opp_table);
> +put_opp:
> +	dev_pm_opp_put(opp);
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(dev_pm_opp_set_bw);
> +
>  /**
>   * dev_pm_opp_set_rate() - Configure new OPP based on frequency
>   * @dev:	 device for which we do this operation
> diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
> index a17c462974851..1cdc2d0a2b20e 100644
> --- a/include/linux/pm_opp.h
> +++ b/include/linux/pm_opp.h
> @@ -152,6 +152,7 @@ struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names
>  void dev_pm_opp_detach_genpd(struct opp_table *opp_table);
>  int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate);
>  int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
> +int dev_pm_opp_set_bw(struct device *dev, unsigned long freq);
>  int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
>  int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
>  void dev_pm_opp_remove_table(struct device *dev);
> @@ -336,6 +337,11 @@ static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_f
>  	return -ENOTSUPP;
>  }
>  
> +static inline int dev_pm_opp_set_bw(struct device *dev, unsigned long freq)
> +{
> +	return -ENOTSUPP;
> +}
> +
>  static inline int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask)
>  {
>  	return -ENOTSUPP;
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 

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

end of thread, other threads:[~2019-07-11 17:39 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-27 13:34 [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Sibi Sankar
2019-06-27 13:34 ` [PATCH RFC 1/4] OPP: Add and export helper to update voltage Sibi Sankar
2019-06-28  8:20   ` Rajendra Nayak
2019-06-27 13:34 ` [PATCH RFC 2/4] OPP: Add and export helper to set bandwidth Sibi Sankar
2019-07-11 17:40   ` Bjorn Andersson
2019-06-27 13:34 ` [PATCH RFC 3/4] cpufreq: qcom: Update the bandwidth levels on frequency change Sibi Sankar
2019-06-28  8:25   ` Rajendra Nayak
2019-06-27 13:34 ` [PATCH RFC 4/4] arm64: dts: qcom: sdm845: Add cpu OPP tables Sibi Sankar
2019-07-01  9:29 ` [PATCH RFC 0/4] DDR/L3 Scaling support on SDM845 SoCs Viresh Kumar
2019-07-10 14:14   ` Sibi Sankar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).