* [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).