This patch series aims to extend cpu based scaling support to L3/DDR on
SDM845 and SC7180 SoCs.
Patches [1-3] - Blacklist SDM845 and SC7180 in cpufreq-dt-platdev
Patches [4-8] - Update bw levels based on cpu frequency change
Patches [9-10] - Add tag setting support to OPP
Patches [11-12] - Add the cpu opp tables for SDM845 and SC7180 SoCs.
Depends on the following series:
https://lore.kernel.org/patchwork/cover/1230626/
Georgi,
Would it make sense to include tag support patches [9-10] in your next
re-spin?
V4:
* Migrate to using Georgi's new bindings
* Misc fixups based on Matthias comments
* API fixups based on Bjorn's comments on v2
* Picked up a few R-bs from Matthias
v3:
* Migrated to using Saravana's opp-kBps bindings [1]
* Fixed some misc comments from Rajendra
* Added support for SC7180
v2:
* Incorporated Viresh's comments from:
https://lore.kernel.org/lkml/20190410102429.r6j6brm5kspmqxc3@vireshk-i7/
https://lore.kernel.org/lkml/20190410112516.gnh77jcwawvld6et@vireshk-i7/
* Dropped cpufreq-map passive governor
Sibi Sankar (12):
arm64: dts: qcom: sdm845: Add SoC compatible to MTP
cpufreq: blacklist SDM845 in cpufreq-dt-platdev
cpufreq: blacklist SC7180 in cpufreq-dt-platdev
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
OPP: Add and export helper to get icc path count
cpufreq: qcom: Disable fast switch when scaling ddr/l3
dt-bindings: interconnect: Add interconnect-tags bindings
OPP: Add support for setting interconnect-tags
arm64: dts: qcom: sdm845: Add cpu OPP tables
arm64: dts: qcom: sc7180: Add cpu OPP tables
.../bindings/interconnect/interconnect.txt | 5 +
arch/arm64/boot/dts/qcom/sc7180.dtsi | 168 ++++++++++++
arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 2 +-
arch/arm64/boot/dts/qcom/sdm845.dtsi | 258 ++++++++++++++++++
drivers/cpufreq/cpufreq-dt-platdev.c | 2 +
drivers/cpufreq/qcom-cpufreq-hw.c | 89 +++++-
drivers/opp/core.c | 114 ++++++++
drivers/opp/of.c | 25 +-
include/linux/pm_opp.h | 22 ++
9 files changed, 675 insertions(+), 10 deletions(-)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Add SDM845 to cpufreq-dt-platdev blacklist since the actual scaling is
handled by the 'qcom-cpufreq-hw' driver.
Reviewed-by: Matthias Kaehlcke <[email protected]>
Signed-off-by: Sibi Sankar <[email protected]>
---
v4:
* Updated commit message [Matthias]
* Picked up R-b from Matthias
drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index 5c8baf603e056..6ed68bc906f8d 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -131,6 +131,7 @@ static const struct of_device_id blacklist[] __initconst = {
{ .compatible = "qcom,apq8096", },
{ .compatible = "qcom,msm8996", },
{ .compatible = "qcom,qcs404", },
+ { .compatible = "qcom,sdm845", },
{ .compatible = "st,stih407", },
{ .compatible = "st,stih410", },
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
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 <[email protected]>
---
v4:
https://patchwork.kernel.org/patch/11019737/
* Pass device opp to set bw levels [Bjorn]
drivers/opp/core.c | 43 ++++++++++++++++++++++++++++++++++++++++++
include/linux/pm_opp.h | 6 ++++++
2 files changed, 49 insertions(+)
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 7f7060079bb28..f157e2d768d76 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -791,6 +791,49 @@ static int _set_required_opps(struct device *dev,
return ret;
}
+/**
+ * dev_pm_opp_set_bw() - sets bandwidth levels corresponding to an available opp
+ * @dev: device for which we do this operation
+ * @opp: opp based on which the bandwidth levels are to be configured
+ *
+ * This configures the bandwidth to the levels specified
+ * by the OPP.
+ *
+ * Return: 0 on success or a negative error value.
+ */
+int dev_pm_opp_set_bw(struct device *dev, struct dev_pm_opp *opp)
+{
+ struct opp_table *opp_table;
+ int ret = -EINVAL;
+ int i;
+
+ if (IS_ERR_OR_NULL(opp) || !opp->available) {
+ dev_err(dev, "%s: Invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+
+ opp_table = _find_opp_table(dev);
+ if (IS_ERR(opp_table)) {
+ dev_err(dev, "%s: device opp table doesn't exist\n", __func__);
+ return PTR_ERR(opp_table);
+ }
+
+ if (opp_table->paths) {
+ 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);
+ if (ret)
+ dev_err(dev, "Failed to set bandwidth[%d]: %d\n",
+ i, ret);
+ }
+ }
+
+ dev_pm_opp_put_opp_table(opp_table);
+ 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 639bc0382ee02..87ba295080a2b 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -154,6 +154,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, struct dev_pm_opp *opp);
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);
@@ -352,6 +353,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, struct dev_pm_opp *opp)
+{
+ 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
Add support to parse optional OPP table attached to the cpu node when
the OPP bandwidth values are populated. This allows for scaling of
DDR/L3 bandwidth levels with frequency change.
Signed-off-by: Sibi Sankar <[email protected]>
---
v4:
* Split fast switch disable into another patch [Lukasz]
drivers/cpufreq/qcom-cpufreq-hw.c | 85 ++++++++++++++++++++++++++++++-
1 file changed, 83 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index fc92a8842e252..4fb489b69bc61 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>
@@ -31,6 +32,63 @@
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)
+{
+ unsigned long freq_hz = freq_khz * 1000;
+ struct dev_pm_opp *opp;
+ struct device *dev;
+ int ret;
+
+ dev = get_cpu_device(policy->cpu);
+ if (!dev)
+ return -ENODEV;
+
+ opp = dev_pm_opp_find_freq_exact(dev, freq_hz, true);
+ if (IS_ERR(opp))
+ return PTR_ERR(opp);
+
+ ret = dev_pm_opp_set_bw(dev, opp);
+ dev_pm_opp_put(opp);
+ return ret;
+}
+
+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);
+}
+
+/* Check for optional interconnect paths on CPU0 */
+static int qcom_cpufreq_verify_icc_paths(struct device *dev)
+{
+ struct device *cpu_dev;
+ struct icc_path *path;
+ int ret;
+
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev)
+ return -EPROBE_DEFER;
+
+ path = of_icc_get(cpu_dev, NULL);
+ ret = PTR_ERR_OR_ZERO(path);
+ if (ret) {
+ if (ret != -EPROBE_DEFER)
+ dev_err(cpu_dev, "Failed to get paths ddr/l3 scaling off\n");
+ return ret;
+ }
+
+ icc_put(path);
+ return ret;
+}
+
static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
unsigned int index)
{
@@ -39,6 +97,8 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
writel_relaxed(index, perf_state_reg);
+ qcom_cpufreq_set_bw(policy, freq);
+
arch_set_freq_scale(policy->related_cpus, freq,
policy->cpuinfo.max_freq);
return 0;
@@ -88,12 +148,27 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
{
u32 data, src, lval, i, core_count, prev_freq = 0, freq;
u32 volt;
+ u64 rate;
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);
+ if (!ret)
+ dev_pm_opp_disable(cpu_dev, rate);
+ }
+ of_node_put(opp_table_np);
+ }
+
for (i = 0; i < LUT_MAX_ENTRIES; i++) {
data = readl_relaxed(base + REG_FREQ_LUT +
i * LUT_ROW_SIZE);
@@ -112,7 +187,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
if (freq != prev_freq && core_count != LUT_TURBO_IND) {
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 if (core_count == LUT_TURBO_IND) {
@@ -133,7 +208,8 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
if (prev->frequency == CPUFREQ_ENTRY_INVALID) {
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;
@@ -254,6 +330,7 @@ static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
void __iomem *base = policy->driver_data - REG_PERF_STATE;
dev_pm_opp_remove_all_dynamic(cpu_dev);
+ dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
kfree(policy->freq_table);
devm_iounmap(&global_pdev->dev, base);
@@ -301,6 +378,10 @@ static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
global_pdev = pdev;
+ ret = qcom_cpufreq_verify_icc_paths(&pdev->dev);
+ if (ret)
+ return ret;
+
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
Add interconnect-tags bindings to enable passing of optional
tag information to the interconnect framework.
Signed-off-by: Sibi Sankar <[email protected]>
---
.../devicetree/bindings/interconnect/interconnect.txt | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/interconnect/interconnect.txt b/Documentation/devicetree/bindings/interconnect/interconnect.txt
index 6f5d23a605b75..c1a226a934e50 100644
--- a/Documentation/devicetree/bindings/interconnect/interconnect.txt
+++ b/Documentation/devicetree/bindings/interconnect/interconnect.txt
@@ -55,6 +55,11 @@ interconnect-names : List of interconnect path name strings sorted in the same
* dma-mem: Path from the device to the main memory of
the system
+interconnect-tags : List of interconnect path tags sorted in the same order as the
+ interconnects property. Consumers can append a specific tag to
+ the path and pass this information to the interconnect framework
+ to do aggregation based on the attached tag.
+
Example:
sdhci@7864000 {
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Add OPP tables required to scale DDR/L3 per freq-domain on SC7180 SoCs.
Signed-off-by: Sibi Sankar <[email protected]>
---
v4:
https://lore.kernel.org/patchwork/cover/1230626/
* Reworked based on Georgi's bindings
arch/arm64/boot/dts/qcom/sc7180.dtsi | 168 +++++++++++++++++++++++++++
1 file changed, 168 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index 4216b574c0803..2421b7bb7dd83 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -10,6 +10,7 @@
#include <dt-bindings/clock/qcom,gpucc-sc7180.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,videocc-sc7180.h>
+#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sc7180.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/phy/phy-qcom-qusb2.h>
@@ -100,6 +101,10 @@ &LITTLE_CPU_SLEEP_1
&CLUSTER_SLEEP_0>;
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <100>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
next-level-cache = <&L2_0>;
#cooling-cells = <2>;
qcom,freq-domain = <&cpufreq_hw 0>;
@@ -123,6 +128,10 @@ &LITTLE_CPU_SLEEP_1
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <100>;
next-level-cache = <&L2_100>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
#cooling-cells = <2>;
qcom,freq-domain = <&cpufreq_hw 0>;
L2_100: l2-cache {
@@ -142,6 +151,10 @@ &LITTLE_CPU_SLEEP_1
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <100>;
next-level-cache = <&L2_200>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
#cooling-cells = <2>;
qcom,freq-domain = <&cpufreq_hw 0>;
L2_200: l2-cache {
@@ -161,6 +174,10 @@ &LITTLE_CPU_SLEEP_1
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <100>;
next-level-cache = <&L2_300>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
#cooling-cells = <2>;
qcom,freq-domain = <&cpufreq_hw 0>;
L2_300: l2-cache {
@@ -180,6 +197,10 @@ &LITTLE_CPU_SLEEP_1
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <100>;
next-level-cache = <&L2_400>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
#cooling-cells = <2>;
qcom,freq-domain = <&cpufreq_hw 0>;
L2_400: l2-cache {
@@ -199,6 +220,10 @@ &LITTLE_CPU_SLEEP_1
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <100>;
next-level-cache = <&L2_500>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
#cooling-cells = <2>;
qcom,freq-domain = <&cpufreq_hw 0>;
L2_500: l2-cache {
@@ -218,6 +243,10 @@ &BIG_CPU_SLEEP_1
capacity-dmips-mhz = <1740>;
dynamic-power-coefficient = <405>;
next-level-cache = <&L2_600>;
+ operating-points-v2 = <&cpu6_opp_table>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
#cooling-cells = <2>;
qcom,freq-domain = <&cpufreq_hw 1>;
L2_600: l2-cache {
@@ -237,6 +266,10 @@ &BIG_CPU_SLEEP_1
capacity-dmips-mhz = <1740>;
dynamic-power-coefficient = <405>;
next-level-cache = <&L2_700>;
+ operating-points-v2 = <&cpu6_opp_table>;
+ interconnects = <&gem_noc MASTER_APPSS_PROC &mc_virt SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
#cooling-cells = <2>;
qcom,freq-domain = <&cpufreq_hw 1>;
L2_700: l2-cache {
@@ -336,6 +369,141 @@ CLUSTER_SLEEP_0: cluster-sleep-0 {
};
};
+ cpu0_opp_table: cpu0_opp_table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ cpu0_opp1: opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-peak-kBps = <1200000 4800000>;
+ };
+
+ cpu0_opp2: opp-576000000 {
+ opp-hz = /bits/ 64 <576000000>;
+ opp-peak-kBps = <1200000 4800000>;
+ };
+
+ cpu0_opp3: opp-768000000 {
+ opp-hz = /bits/ 64 <768000000>;
+ opp-peak-kBps = <1200000 4800000>;
+ };
+
+ cpu0_opp4: opp-1017600000 {
+ opp-hz = /bits/ 64 <1017600000>;
+ opp-peak-kBps = <1804000 8908800>;
+ };
+
+ cpu0_opp5: opp-1248000000 {
+ opp-hz = /bits/ 64 <1248000000>;
+ opp-peak-kBps = <2188000 12902400>;
+ };
+
+ cpu0_opp6: opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+ opp-peak-kBps = <2188000 12902400>;
+ };
+
+ cpu0_opp7: opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-peak-kBps = <3072000 15052800>;
+ };
+
+ cpu0_opp8: opp-1612800000 {
+ opp-hz = /bits/ 64 <1612800000>;
+ opp-peak-kBps = <3072000 15052800>;
+ };
+
+ cpu0_opp9: opp-1708800000 {
+ opp-hz = /bits/ 64 <1708800000>;
+ opp-peak-kBps = <3072000 15052800>;
+ };
+
+ cpu0_opp10: opp-1804800000 {
+ opp-hz = /bits/ 64 <1804800000>;
+ opp-peak-kBps = <4068000 22425600>;
+ };
+ };
+
+ cpu6_opp_table: cpu6_opp_table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ cpu6_opp1: opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-peak-kBps = <2188000 8908800>;
+ };
+
+ cpu6_opp2: opp-652800000 {
+ opp-hz = /bits/ 64 <652800000>;
+ opp-peak-kBps = <2188000 8908800>;
+ };
+
+ cpu6_opp3: opp-825600000 {
+ opp-hz = /bits/ 64 <825600000>;
+ opp-peak-kBps = <2188000 8908800>;
+ };
+
+ cpu6_opp4: opp-979200000 {
+ opp-hz = /bits/ 64 <979200000>;
+ opp-peak-kBps = <2188000 8908800>;
+ };
+
+ cpu6_opp5: opp-1113600000 {
+ opp-hz = /bits/ 64 <1113600000>;
+ opp-peak-kBps = <2188000 8908800>;
+ };
+
+ cpu6_opp6: opp-1267200000 {
+ opp-hz = /bits/ 64 <1267200000>;
+ opp-peak-kBps = <4068000 12902400>;
+ };
+
+ cpu6_opp7: opp-1555200000 {
+ opp-hz = /bits/ 64 <1555200000>;
+ opp-peak-kBps = <4068000 15052800>;
+ };
+
+ cpu6_opp8: opp-1708800000 {
+ opp-hz = /bits/ 64 <1708800000>;
+ opp-peak-kBps = <6220000 19353600>;
+ };
+
+ cpu6_opp9: opp-1843200000 {
+ opp-hz = /bits/ 64 <1843200000>;
+ opp-peak-kBps = <6220000 19353600>;
+ };
+
+ cpu6_opp10: opp-1900800000 {
+ opp-hz = /bits/ 64 <1900800000>;
+ opp-peak-kBps = <6220000 22425600>;
+ };
+
+ cpu6_opp11: opp-1996800000 {
+ opp-hz = /bits/ 64 <1996800000>;
+ opp-peak-kBps = <6220000 22425600>;
+ };
+
+ cpu6_opp12: opp-2112000000 {
+ opp-hz = /bits/ 64 <2112000000>;
+ opp-peak-kBps = <6220000 22425600>;
+ };
+
+ cpu6_opp13: opp-2208000000 {
+ opp-hz = /bits/ 64 <2208000000>;
+ opp-peak-kBps = <7216000 22425600>;
+ };
+
+ cpu6_opp14: opp-2323200000 {
+ opp-hz = /bits/ 64 <2323200000>;
+ opp-peak-kBps = <7216000 22425600>;
+ };
+
+ cpu6_opp15: opp-2400000000 {
+ opp-hz = /bits/ 64 <2400000000>;
+ opp-peak-kBps = <8532000 23347200>;
+ };
+ };
+
memory@80000000 {
device_type = "memory";
/* We expect the bootloader to fill in the size */
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Disable fast switch when the icc paths required for scaling ddr/l3
are populated.
Signed-off-by: Sibi Sankar <[email protected]>
---
drivers/cpufreq/qcom-cpufreq-hw.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 4fb489b69bc61..4b2c23dab3728 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -316,7 +316,9 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
dev_pm_opp_of_register_em(policy->cpus);
- policy->fast_switch_possible = true;
+ ret = dev_pm_opp_get_path_count(cpu_dev);
+ if (ret <= 0)
+ policy->fast_switch_possible = true;
return 0;
error:
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Add OPP tables required to scale DDR/L3 per freq-domain on SDM845 SoCs.
Signed-off-by: Sibi Sankar <[email protected]>
---
v4:
https://lore.kernel.org/patchwork/cover/1230626/
* Reworked based on Georgi's bindings
arch/arm64/boot/dts/qcom/sdm845.dtsi | 258 +++++++++++++++++++++++++++
1 file changed, 258 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 71dfdfcf2033f..f457a15a8d2b3 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -12,6 +12,7 @@
#include <dt-bindings/clock/qcom,lpass-sdm845.h>
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/clock/qcom,videocc-sdm845.h>
+#include <dt-bindings/interconnect/qcom,osm-l3.h>
#include <dt-bindings/interconnect/qcom,sdm845.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/phy/phy-qcom-qusb2.h>
@@ -200,6 +201,10 @@ &LITTLE_CPU_SLEEP_1
qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
next-level-cache = <&L2_0>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
L2_0: l2-cache {
compatible = "cache";
next-level-cache = <&L3_0>;
@@ -222,6 +227,10 @@ &LITTLE_CPU_SLEEP_1
qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
next-level-cache = <&L2_100>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
L2_100: l2-cache {
compatible = "cache";
next-level-cache = <&L3_0>;
@@ -241,6 +250,10 @@ &LITTLE_CPU_SLEEP_1
qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
next-level-cache = <&L2_200>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
L2_200: l2-cache {
compatible = "cache";
next-level-cache = <&L3_0>;
@@ -260,6 +273,10 @@ &LITTLE_CPU_SLEEP_1
qcom,freq-domain = <&cpufreq_hw 0>;
#cooling-cells = <2>;
next-level-cache = <&L2_300>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
L2_300: l2-cache {
compatible = "cache";
next-level-cache = <&L3_0>;
@@ -279,6 +296,10 @@ &BIG_CPU_SLEEP_1
qcom,freq-domain = <&cpufreq_hw 1>;
#cooling-cells = <2>;
next-level-cache = <&L2_400>;
+ operating-points-v2 = <&cpu4_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
L2_400: l2-cache {
compatible = "cache";
next-level-cache = <&L3_0>;
@@ -298,6 +319,10 @@ &BIG_CPU_SLEEP_1
qcom,freq-domain = <&cpufreq_hw 1>;
#cooling-cells = <2>;
next-level-cache = <&L2_500>;
+ operating-points-v2 = <&cpu4_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
L2_500: l2-cache {
compatible = "cache";
next-level-cache = <&L3_0>;
@@ -317,6 +342,10 @@ &BIG_CPU_SLEEP_1
qcom,freq-domain = <&cpufreq_hw 1>;
#cooling-cells = <2>;
next-level-cache = <&L2_600>;
+ operating-points-v2 = <&cpu4_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
L2_600: l2-cache {
compatible = "cache";
next-level-cache = <&L3_0>;
@@ -336,6 +365,10 @@ &BIG_CPU_SLEEP_1
qcom,freq-domain = <&cpufreq_hw 1>;
#cooling-cells = <2>;
next-level-cache = <&L2_700>;
+ operating-points-v2 = <&cpu4_opp_table>;
+ interconnects = <&gladiator_noc MASTER_APPSS_PROC &mem_noc SLAVE_EBI1>,
+ <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
+ interconnect-tags = <3 0>;
L2_700: l2-cache {
compatible = "cache";
next-level-cache = <&L3_0>;
@@ -433,6 +466,231 @@ CLUSTER_SLEEP_0: cluster-sleep-0 {
};
};
+ cpu0_opp_table: cpu0_opp_table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ cpu0_opp1: opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ opp-peak-kBps = <800000 4800000>;
+ };
+
+ cpu0_opp2: opp-403200000 {
+ opp-hz = /bits/ 64 <403200000>;
+ opp-peak-kBps = <800000 4800000>;
+ };
+
+ cpu0_opp3: opp-480000000 {
+ opp-hz = /bits/ 64 <480000000>;
+ opp-peak-kBps = <800000 6451200>;
+ };
+
+ cpu0_opp4: opp-576000000 {
+ opp-hz = /bits/ 64 <576000000>;
+ opp-peak-kBps = <800000 6451200>;
+ };
+
+ cpu0_opp5: opp-652800000 {
+ opp-hz = /bits/ 64 <652800000>;
+ opp-peak-kBps = <800000 7680000>;
+ };
+
+ cpu0_opp6: opp-748800000 {
+ opp-hz = /bits/ 64 <748800000>;
+ opp-peak-kBps = <1804000 9216000>;
+ };
+
+ cpu0_opp7: opp-825600000 {
+ opp-hz = /bits/ 64 <825600000>;
+ opp-peak-kBps = <1804000 9216000>;
+ };
+
+ cpu0_opp8: opp-902400000 {
+ opp-hz = /bits/ 64 <902400000>;
+ opp-peak-kBps = <1804000 10444800>;
+ };
+
+ cpu0_opp9: opp-979200000 {
+ opp-hz = /bits/ 64 <979200000>;
+ opp-peak-kBps = <1804000 11980800>;
+ };
+
+ cpu0_opp10: opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-peak-kBps = <1804000 11980800>;
+ };
+
+ cpu0_opp11: opp-1132800000 {
+ opp-hz = /bits/ 64 <1132800000>;
+ opp-peak-kBps = <2188000 13516800>;
+ };
+
+ cpu0_opp12: opp-1228800000 {
+ opp-hz = /bits/ 64 <1228800000>;
+ opp-peak-kBps = <2188000 15052800>;
+ };
+
+ cpu0_opp13: opp-1324800000 {
+ opp-hz = /bits/ 64 <1324800000>;
+ opp-peak-kBps = <2188000 16588800>;
+ };
+
+ cpu0_opp14: opp-1420800000 {
+ opp-hz = /bits/ 64 <1420800000>;
+ opp-peak-kBps = <2188000 18124800>;
+ };
+
+ cpu0_opp15: opp-1516800000 {
+ opp-hz = /bits/ 64 <1516800000>;
+ opp-peak-kBps = <2724000 19353600>;
+ };
+
+ cpu0_opp16: opp-1612800000 {
+ opp-hz = /bits/ 64 <1612800000>;
+ opp-peak-kBps = <4068000 19353600>;
+ };
+
+ cpu0_opp17: opp-1689600000 {
+ opp-hz = /bits/ 64 <1689600000>;
+ opp-peak-kBps = <4068000 20889600>;
+ };
+
+ cpu0_opp18: opp-1766400000 {
+ opp-hz = /bits/ 64 <1766400000>;
+ opp-peak-kBps = <4068000 22425600>;
+ };
+ };
+
+ cpu4_opp_table: cpu4_opp_table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ cpu4_opp1: opp-825600000 {
+ opp-hz = /bits/ 64 <825600000>;
+ opp-peak-kBps = <1200000 9216000>;
+ };
+
+ cpu4_opp2: opp-902400000 {
+ opp-hz = /bits/ 64 <902400000>;
+ opp-peak-kBps = <1200000 9216000>;
+ };
+
+ cpu4_opp3: opp-979200000 {
+ opp-hz = /bits/ 64 <979200000>;
+ opp-peak-kBps = <1200000 9216000>;
+ };
+
+ cpu4_opp4: opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-peak-kBps = <3072000 11980800>;
+ };
+
+ cpu4_opp5: opp-1209600000 {
+ opp-hz = /bits/ 64 <1209600000>;
+ opp-peak-kBps = <4068000 11980800>;
+ };
+
+ cpu4_opp6: opp-1286400000 {
+ opp-hz = /bits/ 64 <1286400000>;
+ opp-peak-kBps = <4068000 11980800>;
+ };
+
+ cpu4_opp7: opp-1363200000 {
+ opp-hz = /bits/ 64 <1363200000>;
+ opp-peak-kBps = <4068000 15052800>;
+ };
+
+ cpu4_opp8: opp-1459200000 {
+ opp-hz = /bits/ 64 <1459200000>;
+ opp-peak-kBps = <4068000 15052800>;
+ };
+
+ cpu4_opp9: opp-1536000000 {
+ opp-hz = /bits/ 64 <1536000000>;
+ opp-peak-kBps = <4068000 15052800>;
+ };
+
+ cpu4_opp10: opp-1612800000 {
+ opp-hz = /bits/ 64 <1612800000>;
+ opp-peak-kBps = <5184000 15052800>;
+ };
+
+ cpu4_opp11: opp-1689600000 {
+ opp-hz = /bits/ 64 <1689600000>;
+ opp-peak-kBps = <5184000 19353600>;
+ };
+
+ cpu4_opp12: opp-1766400000 {
+ opp-hz = /bits/ 64 <1766400000>;
+ opp-peak-kBps = <6220000 19353600>;
+ };
+
+ cpu4_opp13: opp-1843200000 {
+ opp-hz = /bits/ 64 <1843200000>;
+ opp-peak-kBps = <6220000 19353600>;
+ };
+
+ cpu4_opp14: opp-1920000000 {
+ opp-hz = /bits/ 64 <1920000000>;
+ opp-peak-kBps = <6220000 19353600>;
+ };
+
+ cpu4_opp15: opp-1996800000 {
+ opp-hz = /bits/ 64 <1996800000>;
+ opp-peak-kBps = <7216000 20889600>;
+ };
+
+ cpu4_opp16: opp-2092800000 {
+ opp-hz = /bits/ 64 <2092800000>;
+ opp-peak-kBps = <7216000 20889600>;
+ };
+
+ cpu4_opp17: opp-2169600000 {
+ opp-hz = /bits/ 64 <2169600000>;
+ opp-peak-kBps = <7216000 20889600>;
+ };
+
+ cpu4_opp18: opp-2246400000 {
+ opp-hz = /bits/ 64 <2246400000>;
+ opp-peak-kBps = <7216000 20889600>;
+ };
+
+ cpu4_opp19: opp-2323200000 {
+ opp-hz = /bits/ 64 <2323200000>;
+ opp-peak-kBps = <7216000 20889600>;
+ };
+
+ cpu4_opp20: opp-2400000000 {
+ opp-hz = /bits/ 64 <2400000000>;
+ opp-peak-kBps = <7216000 22425600>;
+ };
+
+ cpu4_opp21: opp-2476800000 {
+ opp-hz = /bits/ 64 <2476800000>;
+ opp-peak-kBps = <7216000 22425600>;
+ };
+
+ cpu4_opp22: opp-2553600000 {
+ opp-hz = /bits/ 64 <2553600000>;
+ opp-peak-kBps = <7216000 22425600>;
+ };
+
+ cpu4_opp23: opp-2649600000 {
+ opp-hz = /bits/ 64 <2649600000>;
+ opp-peak-kBps = <7216000 22425600>;
+ };
+
+ cpu4_opp24: opp-2745600000 {
+ opp-hz = /bits/ 64 <2745600000>;
+ opp-peak-kBps = <7216000 23654400>;
+ };
+
+ cpu4_opp25: opp-2803200000 {
+ opp-hz = /bits/ 64 <2803200000>;
+ opp-peak-kBps = <7216000 23654400>;
+ };
+ };
+
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
Add support for setting tags on icc paths associated with
the opp_table.
Signed-off-by: Sibi Sankar <[email protected]>
---
drivers/opp/of.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index 2b590fe2e69ae..5273b46f11025 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -336,6 +336,7 @@ int _of_find_paths(struct opp_table *opp_table, struct device *dev)
{
struct device_node *np;
int ret, i, count, num_paths;
+ u32 tag;
np = of_node_get(dev->of_node);
if (!np)
@@ -343,22 +344,26 @@ int _of_find_paths(struct opp_table *opp_table, struct device *dev)
count = of_count_phandle_with_args(np, "interconnects",
"#interconnect-cells");
- of_node_put(np);
- if (count < 0)
- return 0;
+ if (count < 0) {
+ ret = 0;
+ goto put_np;
+ }
/* two phandles when #interconnect-cells = <1> */
if (count % 2) {
dev_err(dev, "%s: Invalid interconnects values\n",
__func__);
- return -EINVAL;
+ ret = -EINVAL;
+ goto put_np;
}
num_paths = count / 2;
opp_table->paths = kcalloc(num_paths, sizeof(*opp_table->paths),
GFP_KERNEL);
- if (!opp_table->paths)
- return -ENOMEM;
+ if (!opp_table->paths) {
+ ret = -ENOMEM;
+ goto put_np;
+ }
for (i = 0; i < num_paths; i++) {
opp_table->paths[i] = of_icc_get_by_index(dev, i);
@@ -370,8 +375,14 @@ int _of_find_paths(struct opp_table *opp_table, struct device *dev)
}
goto err;
}
+
+ /* Set tag if present */
+ if (!of_property_read_u32_index(np, "interconnect-tags",
+ i, &tag))
+ icc_set_tag(opp_table->paths[i], tag);
}
opp_table->path_count = num_paths;
+ of_node_put(np);
return 0;
@@ -381,6 +392,8 @@ int _of_find_paths(struct opp_table *opp_table, struct device *dev)
kfree(opp_table->paths);
opp_table->paths = NULL;
+put_np:
+ of_node_put(np);
return ret;
}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
Add and export 'dev_pm_opp_get_path_count' to get the icc path count
associated with the device.
Signed-off-by: Sibi Sankar <[email protected]>
---
drivers/opp/core.c | 20 ++++++++++++++++++++
include/linux/pm_opp.h | 6 ++++++
2 files changed, 26 insertions(+)
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index f157e2d768d76..6106146a582d5 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -343,6 +343,26 @@ int dev_pm_opp_get_opp_count(struct device *dev)
}
EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count);
+int dev_pm_opp_get_path_count(struct device *dev)
+{
+ struct opp_table *opp_table;
+ int count;
+
+ opp_table = _find_opp_table(dev);
+ if (IS_ERR(opp_table)) {
+ count = PTR_ERR(opp_table);
+ dev_dbg(dev, "%s: OPP table not found (%d)\n",
+ __func__, count);
+ return count;
+ }
+
+ count = opp_table->path_count;
+ dev_pm_opp_put_opp_table(opp_table);
+
+ return count;
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_get_path_count);
+
/**
* dev_pm_opp_find_freq_exact() - search for an exact frequency
* @dev: device for which we do this operation
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 87ba295080a2b..ffd075c8da0ca 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -101,6 +101,7 @@ unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp);
bool dev_pm_opp_is_turbo(struct dev_pm_opp *opp);
int dev_pm_opp_get_opp_count(struct device *dev);
+int dev_pm_opp_get_path_count(struct device *dev);
unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev);
unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev);
unsigned long dev_pm_opp_get_max_transition_latency(struct device *dev);
@@ -197,6 +198,11 @@ static inline int dev_pm_opp_get_opp_count(struct device *dev)
return 0;
}
+static inline int dev_pm_opp_get_path_count(struct device *dev)
+{
+ return 0;
+}
+
static inline unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev)
{
return 0;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
On Mon, May 4, 2020 at 1:24 PM Sibi Sankar <[email protected]> wrote:
>
> Add and export 'dev_pm_opp_get_path_count' to get the icc path count
> associated with the device.
This is not related to OPP. You should add this helper function to ICC
framework?
-Saravana
On 05-05-20, 01:52, Sibi Sankar wrote:
> Add support to parse optional OPP table attached to the cpu node when
> the OPP bandwidth values are populated. This allows for scaling of
> DDR/L3 bandwidth levels with frequency change.
>
> Signed-off-by: Sibi Sankar <[email protected]>
What about using opp_set_rate instead ?
--
viresh
On 05-05-20, 01:52, Sibi Sankar wrote:
> Add support for setting tags on icc paths associated with
> the opp_table.
>
> Signed-off-by: Sibi Sankar <[email protected]>
> ---
> drivers/opp/of.c | 25 +++++++++++++++++++------
> 1 file changed, 19 insertions(+), 6 deletions(-)
Maybe this should be part of Georgi's series ?
--
viresh
On 2020-05-05 10:26, Viresh Kumar wrote:
> On 05-05-20, 01:52, Sibi Sankar wrote:
>> Add support for setting tags on icc paths associated with
>> the opp_table.
>>
>> Signed-off-by: Sibi Sankar <[email protected]>
>> ---
>> drivers/opp/of.c | 25 +++++++++++++++++++------
>> 1 file changed, 19 insertions(+), 6 deletions(-)
>
> Maybe this should be part of Georgi's series ?
yes, I've requested for the
same in my cover-letter.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project.
On 2020-05-05 10:20, Viresh Kumar wrote:
> On 05-05-20, 01:52, Sibi Sankar wrote:
>> Add support to parse optional OPP table attached to the cpu node when
>> the OPP bandwidth values are populated. This allows for scaling of
>> DDR/L3 bandwidth levels with frequency change.
>>
>> Signed-off-by: Sibi Sankar <[email protected]>
>
> What about using opp_set_rate instead ?
I can't use opp_set_rate since
the cpu dev does not have a
clock associated with it and the
scaling is done through writing
on perf state register.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project.
On 2020-05-05 03:33, Saravana Kannan wrote:
> On Mon, May 4, 2020 at 1:24 PM Sibi Sankar <[email protected]>
> wrote:
>>
>> Add and export 'dev_pm_opp_get_path_count' to get the icc path count
>> associated with the device.
>
> This is not related to OPP. You should add this helper function to ICC
> framework?
yes it should be, I'll work with
Georgi so that it gets re-used in
his series as well.
>
> -Saravana
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project.
On Tue, May 5, 2020 at 1:54 AM Sibi Sankar <[email protected]> wrote:
>
> This patch series aims to extend cpu based scaling support to L3/DDR on
> SDM845 and SC7180 SoCs.
>
> Patches [1-3] - Blacklist SDM845 and SC7180 in cpufreq-dt-platdev
> Patches [4-8] - Update bw levels based on cpu frequency change
> Patches [9-10] - Add tag setting support to OPP
> Patches [11-12] - Add the cpu opp tables for SDM845 and SC7180 SoCs.
>
> Depends on the following series:
> https://lore.kernel.org/patchwork/cover/1230626/
Are there any other dependencies for this series? I tried applying
this on top of Georgi's series on v5.7-rc3. Patch 12 didn't apply
cleanly and needed a manual fixup for the include change.
Compilation failed with:
Error: /home/amit/work/sources/worktree-review-pipeline/arch/arm64/boot/dts/qcom/sc7180.dtsi:101.30-31
syntax error
FATAL ERROR: Unable to parse input tree
I've been squinting at the offending lines with no success:
interconnects = <&gem_noc MASTER_APPSS_PROC
&mc_virt SLAVE_EBI1>,
<&osm_l3 MASTER_OSM_L3_APPS
&osm_l3 SLAVE_OSM_L3>;
> Georgi,
> Would it make sense to include tag support patches [9-10] in your next
> re-spin?
>
> V4:
> * Migrate to using Georgi's new bindings
> * Misc fixups based on Matthias comments
> * API fixups based on Bjorn's comments on v2
> * Picked up a few R-bs from Matthias
>
> v3:
> * Migrated to using Saravana's opp-kBps bindings [1]
> * Fixed some misc comments from Rajendra
> * Added support for SC7180
>
> v2:
> * Incorporated Viresh's comments from:
> https://lore.kernel.org/lkml/20190410102429.r6j6brm5kspmqxc3@vireshk-i7/
> https://lore.kernel.org/lkml/20190410112516.gnh77jcwawvld6et@vireshk-i7/
> * Dropped cpufreq-map passive governor
>
> Sibi Sankar (12):
> arm64: dts: qcom: sdm845: Add SoC compatible to MTP
> cpufreq: blacklist SDM845 in cpufreq-dt-platdev
> cpufreq: blacklist SC7180 in cpufreq-dt-platdev
> 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
> OPP: Add and export helper to get icc path count
> cpufreq: qcom: Disable fast switch when scaling ddr/l3
> dt-bindings: interconnect: Add interconnect-tags bindings
> OPP: Add support for setting interconnect-tags
> arm64: dts: qcom: sdm845: Add cpu OPP tables
> arm64: dts: qcom: sc7180: Add cpu OPP tables
>
> .../bindings/interconnect/interconnect.txt | 5 +
> arch/arm64/boot/dts/qcom/sc7180.dtsi | 168 ++++++++++++
> arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 2 +-
> arch/arm64/boot/dts/qcom/sdm845.dtsi | 258 ++++++++++++++++++
> drivers/cpufreq/cpufreq-dt-platdev.c | 2 +
> drivers/cpufreq/qcom-cpufreq-hw.c | 89 +++++-
> drivers/opp/core.c | 114 ++++++++
> drivers/opp/of.c | 25 +-
> include/linux/pm_opp.h | 22 ++
> 9 files changed, 675 insertions(+), 10 deletions(-)
>
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
On Tue, May 5, 2020 at 1:54 AM Sibi Sankar <[email protected]> wrote:
>
> Add SDM845 to cpufreq-dt-platdev blacklist since the actual scaling is
> handled by the 'qcom-cpufreq-hw' driver.
>
> Reviewed-by: Matthias Kaehlcke <[email protected]>
> Signed-off-by: Sibi Sankar <[email protected]>
Reviewed-by: Amit Kucheria <[email protected]>
> ---
>
> v4:
> * Updated commit message [Matthias]
> * Picked up R-b from Matthias
>
> drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
> index 5c8baf603e056..6ed68bc906f8d 100644
> --- a/drivers/cpufreq/cpufreq-dt-platdev.c
> +++ b/drivers/cpufreq/cpufreq-dt-platdev.c
> @@ -131,6 +131,7 @@ static const struct of_device_id blacklist[] __initconst = {
> { .compatible = "qcom,apq8096", },
> { .compatible = "qcom,msm8996", },
> { .compatible = "qcom,qcs404", },
> + { .compatible = "qcom,sdm845", },
>
> { .compatible = "st,stih407", },
> { .compatible = "st,stih410", },
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
Hey Amit,
Thanks for taking time to review
the series!
On 2020-05-06 18:08, Amit Kucheria wrote:
> On Tue, May 5, 2020 at 1:54 AM Sibi Sankar <[email protected]>
> wrote:
>>
>> This patch series aims to extend cpu based scaling support to L3/DDR
>> on
>> SDM845 and SC7180 SoCs.
>>
>> Patches [1-3] - Blacklist SDM845 and SC7180 in cpufreq-dt-platdev
>> Patches [4-8] - Update bw levels based on cpu frequency change
>> Patches [9-10] - Add tag setting support to OPP
>> Patches [11-12] - Add the cpu opp tables for SDM845 and SC7180 SoCs.
>>
>> Depends on the following series:
>> https://lore.kernel.org/patchwork/cover/1230626/
>
> Are there any other dependencies for this series? I tried applying
> this on top of Georgi's series on v5.7-rc3. Patch 12 didn't apply
> cleanly and needed a manual fixup for the include change.
>
When I posted out it was based on
next-20200428 tree, there shouldn't
be any other dependency needed.
> Compilation failed with:
> Error:
> /home/amit/work/sources/worktree-review-pipeline/arch/arm64/boot/dts/qcom/sc7180.dtsi:101.30-31
> syntax error
> FATAL ERROR: Unable to parse input tree
>
> I've been squinting at the offending lines with no success:
> interconnects = <&gem_noc MASTER_APPSS_PROC
> &mc_virt SLAVE_EBI1>,
> <&osm_l3 MASTER_OSM_L3_APPS
> &osm_l3 SLAVE_OSM_L3>;
>
#include <dt-bindings/interconnect/qcom,sc7180.h>
You are probably missing ^^ which
is present in next.
>> Georgi,
>> Would it make sense to include tag support patches [9-10] in your
>> next
>> re-spin?
>>
>> V4:
>> * Migrate to using Georgi's new bindings
>> * Misc fixups based on Matthias comments
>> * API fixups based on Bjorn's comments on v2
>> * Picked up a few R-bs from Matthias
>>
>> v3:
>> * Migrated to using Saravana's opp-kBps bindings [1]
>> * Fixed some misc comments from Rajendra
>> * Added support for SC7180
>>
>> v2:
>> * Incorporated Viresh's comments from:
>>
>> https://lore.kernel.org/lkml/20190410102429.r6j6brm5kspmqxc3@vireshk-i7/
>>
>> https://lore.kernel.org/lkml/20190410112516.gnh77jcwawvld6et@vireshk-i7/
>> * Dropped cpufreq-map passive governor
>>
>> Sibi Sankar (12):
>> arm64: dts: qcom: sdm845: Add SoC compatible to MTP
>> cpufreq: blacklist SDM845 in cpufreq-dt-platdev
>> cpufreq: blacklist SC7180 in cpufreq-dt-platdev
>> 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
>> OPP: Add and export helper to get icc path count
>> cpufreq: qcom: Disable fast switch when scaling ddr/l3
>> dt-bindings: interconnect: Add interconnect-tags bindings
>> OPP: Add support for setting interconnect-tags
>> arm64: dts: qcom: sdm845: Add cpu OPP tables
>> arm64: dts: qcom: sc7180: Add cpu OPP tables
>>
>> .../bindings/interconnect/interconnect.txt | 5 +
>> arch/arm64/boot/dts/qcom/sc7180.dtsi | 168 ++++++++++++
>> arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 2 +-
>> arch/arm64/boot/dts/qcom/sdm845.dtsi | 258
>> ++++++++++++++++++
>> drivers/cpufreq/cpufreq-dt-platdev.c | 2 +
>> drivers/cpufreq/qcom-cpufreq-hw.c | 89 +++++-
>> drivers/opp/core.c | 114 ++++++++
>> drivers/opp/of.c | 25 +-
>> include/linux/pm_opp.h | 22 ++
>> 9 files changed, 675 insertions(+), 10 deletions(-)
>>
>> --
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
>> Forum,
>> a Linux Foundation Collaborative Project
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project.
On 2020-05-05 12:49, Sibi Sankar wrote:
> On 2020-05-05 10:20, Viresh Kumar wrote:
>> On 05-05-20, 01:52, Sibi Sankar wrote:
>>> Add support to parse optional OPP table attached to the cpu node when
>>> the OPP bandwidth values are populated. This allows for scaling of
>>> DDR/L3 bandwidth levels with frequency change.
>>>
>>> Signed-off-by: Sibi Sankar <[email protected]>
>>
>> What about using opp_set_rate instead ?
>
> I can't use opp_set_rate since
> the cpu dev does not have a
> clock associated with it and the
> scaling is done through writing
> on perf state register.
Viresh,
https://patchwork.kernel.org/cover/11548479/
GPU driver uses Georgi's series
for scaling and will need a way to
remove the icc votes in the suspend
path, (this looks like a pattern
that might be used by other clients
as well) I could probably update
opp_set_bw to support removing bw
when NULL opp is specified. Similarly
opp_set_rate will need to support
set bw to 0 when set_rate is passed
0 as target freq for the same use case.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project.
On 27-05-20, 09:23, Viresh Kumar wrote:
> On 26-05-20, 23:18, Sibi Sankar wrote:
> > https://patchwork.kernel.org/cover/11548479/
> > GPU driver uses Georgi's series
> > for scaling and will need a way to
> > remove the icc votes in the suspend
> > path, (this looks like a pattern
> > that might be used by other clients
> > as well) I could probably update
> > opp_set_bw to support removing bw
> > when NULL opp is specified. Similarly
> > opp_set_rate will need to support
> > set bw to 0 when set_rate is passed
> > 0 as target freq for the same use case.
>
> Sure, please send a patch for that.
On a second thought, here is the patch. Please test it.
-------------------------8<-------------------------
Subject: [PATCH] opp: Remove bandwidth votes when target_freq is zero
We already drop several votes when target_freq is set to zero, drop
bandwidth votes as well.
Reported-by: Sibi Sankar <[email protected]>
Signed-off-by: Viresh Kumar <[email protected]>
---
drivers/opp/core.c | 47 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 36 insertions(+), 11 deletions(-)
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 56d3022c1ca2..0c259d5ed232 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -725,6 +725,34 @@ static int _generic_set_opp_regulator(struct opp_table *opp_table,
return ret;
}
+static int _set_opp_bw(const struct opp_table *opp_table,
+ struct dev_pm_opp *opp, bool remove)
+{
+ u32 avg, peak;
+ int i, ret;
+
+ if (!opp_table->paths)
+ return 0;
+
+ for (i = 0; i < opp_table->path_count; i++) {
+ if (remove) {
+ avg = 0;
+ peak = 0;
+ } else {
+ avg = opp->bandwidth[i].avg;
+ peak = opp->bandwidth[i].peak;
+ }
+ ret = icc_set_bw(opp_table->paths[i], avg, peak);
+ if (ret) {
+ dev_err(dev, "Failed to %s bandwidth[%d]: %d\n",
+ remove ? "remove" : "set", i, ret);
+ retrun ret;
+ }
+ }
+
+ return 0;
+}
+
static int _set_opp_custom(const struct opp_table *opp_table,
struct device *dev, unsigned long old_freq,
unsigned long freq,
@@ -837,12 +865,17 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
if (!_get_opp_count(opp_table))
return 0;
- if (!opp_table->required_opp_tables && !opp_table->regulators) {
+ if (!opp_table->required_opp_tables && !opp_table->regulators &&
+ !opp_table->paths) {
dev_err(dev, "target frequency can't be 0\n");
ret = -EINVAL;
goto put_opp_table;
}
+ ret = _set_opp_bw(opp_table, opp, true);
+ if (ret)
+ return ret;
+
if (opp_table->regulator_enabled) {
regulator_disable(opp_table->regulators[0]);
opp_table->regulator_enabled = false;
@@ -932,16 +965,8 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
dev_err(dev, "Failed to set required opps: %d\n", ret);
}
- if (!ret && opp_table->paths) {
- 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);
- if (ret)
- dev_err(dev, "Failed to set bandwidth[%d]: %d\n",
- i, ret);
- }
- }
+ if (!ret)
+ ret = _set_opp_bw(opp_table, opp, false);
put_opp:
dev_pm_opp_put(opp);
On 26-05-20, 23:18, Sibi Sankar wrote:
> https://patchwork.kernel.org/cover/11548479/
> GPU driver uses Georgi's series
> for scaling and will need a way to
> remove the icc votes in the suspend
> path, (this looks like a pattern
> that might be used by other clients
> as well) I could probably update
> opp_set_bw to support removing bw
> when NULL opp is specified. Similarly
> opp_set_rate will need to support
> set bw to 0 when set_rate is passed
> 0 as target freq for the same use case.
Sure, please send a patch for that.
--
viresh