From 18b380ed61f892ed06838d1f1a5124d966292ed3 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 14 May 2021 14:48:43 +0800 Subject: [PATCH 1/8] PM / devfreq: Add missing error code in devfreq_add_device() Set err code in the error path before jumping to the end of the function. Fixes: 4dc3bab8687f ("PM / devfreq: Add support delayed timer for polling mode") Signed-off-by: YueHaibing Signed-off-by: Chanwoo Choi --- drivers/devfreq/devfreq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index fe08c46642f7c..28f3e0ba6cdd9 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -823,6 +823,7 @@ struct devfreq *devfreq_add_device(struct device *dev, if (devfreq->profile->timer < 0 || devfreq->profile->timer >= DEVFREQ_TIMER_NUM) { mutex_unlock(&devfreq->lock); + err = -EINVAL; goto err_dev; } From 7dbc0d246891acbb8ae5840b3237881b7a0787df Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Wed, 19 May 2021 15:05:44 +0800 Subject: [PATCH 2/8] PM / devfreq: imx-bus: Remove imx_bus_get_dev_status Current driver actually does not support simple ondemand governor as it's unable to provide device load information. So removing the unnecessary callback to avoid confusing. Right now the driver is using userspace governor by default. polling_ms was also dropped as it's not needed for non-ondemand governor. Signed-off-by: Dong Aisheng Signed-off-by: Chanwoo Choi --- drivers/devfreq/imx-bus.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/devfreq/imx-bus.c b/drivers/devfreq/imx-bus.c index 3fc3fd77492d5..f3f6e25053ed2 100644 --- a/drivers/devfreq/imx-bus.c +++ b/drivers/devfreq/imx-bus.c @@ -45,18 +45,6 @@ static int imx_bus_get_cur_freq(struct device *dev, unsigned long *freq) return 0; } -static int imx_bus_get_dev_status(struct device *dev, - struct devfreq_dev_status *stat) -{ - struct imx_bus *priv = dev_get_drvdata(dev); - - stat->busy_time = 0; - stat->total_time = 0; - stat->current_frequency = clk_get_rate(priv->clk); - - return 0; -} - static void imx_bus_exit(struct device *dev) { struct imx_bus *priv = dev_get_drvdata(dev); @@ -129,9 +117,7 @@ static int imx_bus_probe(struct platform_device *pdev) return ret; } - priv->profile.polling_ms = 1000; priv->profile.target = imx_bus_target; - priv->profile.get_dev_status = imx_bus_get_dev_status; priv->profile.exit = imx_bus_exit; priv->profile.get_cur_freq = imx_bus_get_cur_freq; priv->profile.initial_freq = clk_get_rate(priv->clk); From 5e480ab94db8102baa73da33534e708a8636c2f9 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Tue, 11 May 2021 00:10:02 +0300 Subject: [PATCH 3/8] PM / devfreq: tegra30: Support thermal cooling Expose ACTMON devfreq device as a cooling device in order to throttle memory freq on overheat. Throttling of memory freq has a significant cooling effect on NVIDIA Tegra SoCs since higher memory freqs require higher SoC core voltage which is one of the main causes of the heating. Signed-off-by: Dmitry Osipenko Signed-off-by: Chanwoo Choi --- drivers/devfreq/tegra30-devfreq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c index ce83f883ca654..10661eb2aed87 100644 --- a/drivers/devfreq/tegra30-devfreq.c +++ b/drivers/devfreq/tegra30-devfreq.c @@ -688,6 +688,7 @@ static struct devfreq_dev_profile tegra_devfreq_profile = { .polling_ms = ACTMON_SAMPLING_PERIOD, .target = tegra_devfreq_target, .get_dev_status = tegra_devfreq_get_dev_status, + .is_cooling_device = true, }; static int tegra_governor_get_target(struct devfreq *devfreq, From a15fc9aa5b384e305ea25f42f744bb301fe39da0 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Fri, 21 May 2021 11:16:39 +0800 Subject: [PATCH 4/8] PM / devfreq: imx8m-ddrc: Remove DEVFREQ_GOV_SIMPLE_ONDEMAND dependency The driver can't support simple ondemand governor due to missing .get_dev_status() capability. Signed-off-by: Dong Aisheng Signed-off-by: Chanwoo Choi --- drivers/devfreq/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 20373a893b445..e87d01c0b76a5 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -103,7 +103,6 @@ config ARM_IMX8M_DDRC_DEVFREQ tristate "i.MX8M DDRC DEVFREQ Driver" depends on (ARCH_MXC && HAVE_ARM_SMCCC) || \ (COMPILE_TEST && HAVE_ARM_SMCCC) - select DEVFREQ_GOV_SIMPLE_ONDEMAND select DEVFREQ_GOV_USERSPACE help This adds the DEVFREQ driver for the i.MX8M DDR Controller. It allows From 1ad4f329fccb5d9eb7b0a38d7fdf0f4688c6b341 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 24 May 2021 10:11:58 +0800 Subject: [PATCH 5/8] PM / devfreq: userspace: Use DEVICE_ATTR_RW macro Use DEVICE_ATTR_RW helper instead of plain DEVICE_ATTR, which makes the code a bit shorter and easier to read. Signed-off-by: YueHaibing Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_userspace.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 0fd6c48510711..ab9db7adb3ade 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -31,8 +31,8 @@ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq) return 0; } -static ssize_t store_freq(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t set_freq_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct devfreq *devfreq = to_devfreq(dev); struct userspace_data *data; @@ -52,8 +52,8 @@ static ssize_t store_freq(struct device *dev, struct device_attribute *attr, return err; } -static ssize_t show_freq(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t set_freq_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct devfreq *devfreq = to_devfreq(dev); struct userspace_data *data; @@ -70,7 +70,7 @@ static ssize_t show_freq(struct device *dev, struct device_attribute *attr, return err; } -static DEVICE_ATTR(set_freq, 0644, show_freq, store_freq); +static DEVICE_ATTR_RW(set_freq); static struct attribute *dev_entries[] = { &dev_attr_set_freq.attr, NULL, From 271ca53cb0c8b3a45c73e1140fc3336c2da42315 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Tue, 1 Jun 2021 05:23:18 +0300 Subject: [PATCH 6/8] dt-bindings: devfreq: tegra30-actmon: Convert to schema Convert NVIDIA Tegra ACTMON binding to schema. Reviewed-by: Rob Herring Acked-by: Chanwoo Choi Acked-by: Thierry Reding Signed-off-by: Dmitry Osipenko Signed-off-by: Chanwoo Choi --- .../arm/tegra/nvidia,tegra30-actmon.txt | 57 --------- .../devfreq/nvidia,tegra30-actmon.yaml | 121 ++++++++++++++++++ 2 files changed, 121 insertions(+), 57 deletions(-) delete mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt create mode 100644 Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt deleted file mode 100644 index 897eedfa2bc8a..0000000000000 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt +++ /dev/null @@ -1,57 +0,0 @@ -NVIDIA Tegra Activity Monitor - -The activity monitor block collects statistics about the behaviour of other -components in the system. This information can be used to derive the rate at -which the external memory needs to be clocked in order to serve all requests -from the monitored clients. - -Required properties: -- compatible: should be "nvidia,tegra-actmon" -- reg: offset and length of the register set for the device -- interrupts: standard interrupt property -- clocks: Must contain a phandle and clock specifier pair for each entry in -clock-names. See ../../clock/clock-bindings.txt for details. -- clock-names: Must include the following entries: - - actmon - - emc -- resets: Must contain an entry for each entry in reset-names. See -../../reset/reset.txt for details. -- reset-names: Must include the following entries: - - actmon -- operating-points-v2: See ../bindings/opp/opp.txt for details. -- interconnects: Should contain entries for memory clients sitting on - MC->EMC memory interconnect path. -- interconnect-names: Should include name of the interconnect path for each - interconnect entry. Consult TRM documentation for - information about available memory clients, see MEMORY - CONTROLLER section. - -For each opp entry in 'operating-points-v2' table: -- opp-supported-hw: bitfield indicating SoC speedo ID mask -- opp-peak-kBps: peak bandwidth of the memory channel - -Example: - dfs_opp_table: opp-table { - compatible = "operating-points-v2"; - - opp@12750000 { - opp-hz = /bits/ 64 <12750000>; - opp-supported-hw = <0x000F>; - opp-peak-kBps = <51000>; - }; - ... - }; - - actmon@6000c800 { - compatible = "nvidia,tegra124-actmon"; - reg = <0x0 0x6000c800 0x0 0x400>; - interrupts = ; - clocks = <&tegra_car TEGRA124_CLK_ACTMON>, - <&tegra_car TEGRA124_CLK_EMC>; - clock-names = "actmon", "emc"; - resets = <&tegra_car 119>; - reset-names = "actmon"; - operating-points-v2 = <&dfs_opp_table>; - interconnects = <&mc TEGRA124_MC_MPCORER &emc>; - interconnect-names = "cpu"; - }; diff --git a/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml b/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml new file mode 100644 index 0000000000000..ba938eed28ee7 --- /dev/null +++ b/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml @@ -0,0 +1,121 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/devfreq/nvidia,tegra30-actmon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVIDIA Tegra30 Activity Monitor + +maintainers: + - Dmitry Osipenko + - Jon Hunter + - Thierry Reding + +description: | + The activity monitor block collects statistics about the behaviour of other + components in the system. This information can be used to derive the rate at + which the external memory needs to be clocked in order to serve all requests + from the monitored clients. + +properties: + compatible: + enum: + - nvidia,tegra30-actmon + - nvidia,tegra114-actmon + - nvidia,tegra124-actmon + - nvidia,tegra210-actmon + + reg: + maxItems: 1 + + clocks: + maxItems: 2 + + clock-names: + items: + - const: actmon + - const: emc + + resets: + maxItems: 1 + + reset-names: + items: + - const: actmon + + interrupts: + maxItems: 1 + + interconnects: + minItems: 1 + maxItems: 12 + + interconnect-names: + minItems: 1 + maxItems: 12 + description: + Should include name of the interconnect path for each interconnect + entry. Consult TRM documentation for information about available + memory clients, see MEMORY CONTROLLER and ACTIVITY MONITOR sections. + + operating-points-v2: + description: + Should contain freqs and voltages and opp-supported-hw property, which + is a bitfield indicating SoC speedo ID mask. + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - interrupts + - interconnects + - interconnect-names + - operating-points-v2 + +additionalProperties: false + +examples: + - | + #include + + mc: memory-controller@7000f000 { + compatible = "nvidia,tegra30-mc"; + reg = <0x7000f000 0x400>; + clocks = <&clk 32>; + clock-names = "mc"; + + interrupts = <0 77 4>; + + #iommu-cells = <1>; + #reset-cells = <1>; + #interconnect-cells = <1>; + }; + + emc: external-memory-controller@7000f400 { + compatible = "nvidia,tegra30-emc"; + reg = <0x7000f400 0x400>; + interrupts = <0 78 4>; + clocks = <&clk 57>; + + nvidia,memory-controller = <&mc>; + operating-points-v2 = <&dvfs_opp_table>; + power-domains = <&domain>; + + #interconnect-cells = <0>; + }; + + actmon@6000c800 { + compatible = "nvidia,tegra30-actmon"; + reg = <0x6000c800 0x400>; + interrupts = <0 45 4>; + clocks = <&clk 119>, <&clk 57>; + clock-names = "actmon", "emc"; + resets = <&rst 119>; + reset-names = "actmon"; + operating-points-v2 = <&dvfs_opp_table>; + interconnects = <&mc TEGRA30_MC_MPCORER &emc>; + interconnect-names = "cpu-read"; + }; From 6b61f55ecbe693d9d0d7ae14ebce01dabe10ecf1 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Tue, 1 Jun 2021 05:23:19 +0300 Subject: [PATCH 7/8] dt-bindings: devfreq: tegra30-actmon: Add cooling-cells The ACTMON watches activity of memory clients. Decisions about a minimum required frequency are made based on the info from ACTMON. We can use ACTMON as a thermal cooling device by limiting the required frequency. Document new cooling-cells property of NVIDIA Tegra ACTMON hardware unit. Reviewed-by: Rob Herring Acked-by: Chanwoo Choi Acked-by: Thierry Reding Signed-off-by: Dmitry Osipenko Signed-off-by: Chanwoo Choi --- .../devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml b/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml index ba938eed28ee7..e3379d1067283 100644 --- a/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml +++ b/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml @@ -63,6 +63,9 @@ properties: Should contain freqs and voltages and opp-supported-hw property, which is a bitfield indicating SoC speedo ID mask. + "#cooling-cells": + const: 2 + required: - compatible - reg @@ -74,6 +77,7 @@ required: - interconnects - interconnect-names - operating-points-v2 + - "#cooling-cells" additionalProperties: false @@ -118,4 +122,5 @@ examples: operating-points-v2 = <&dvfs_opp_table>; interconnects = <&mc TEGRA30_MC_MPCORER &emc>; interconnect-names = "cpu-read"; + #cooling-cells = <2>; }; From 8c37d01e1a86073d15ea7084390fba58d9a1665f Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Thu, 17 Jun 2021 15:05:43 +0900 Subject: [PATCH 8/8] PM / devfreq: passive: Fix get_target_freq when not using required-opp The 86ad9a24f21e ("PM / devfreq: Add required OPPs support to passive governor") supported the required-opp property for using devfreq passive governor. But, 86ad9a24f21e has caused the problem on use-case when required-opp is not used such as exynos-bus.c devfreq driver. So that fix the get_target_freq of passive governor for supporting the case of when required-opp is not used. Fixes: 86ad9a24f21e ("PM / devfreq: Add required OPPs support to passive governor") Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index b094132bd20b3..fc09324a03e03 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -65,7 +65,7 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, dev_pm_opp_put(p_opp); if (IS_ERR(opp)) - return PTR_ERR(opp); + goto no_required_opp; *freq = dev_pm_opp_get_freq(opp); dev_pm_opp_put(opp); @@ -73,6 +73,7 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, return 0; } +no_required_opp: /* * Get the OPP table's index of decided frequency by governor * of parent device.