* [PATCH v2 1/8] dt-bindings: memory: tegra210: Add memory client IDs
2025-09-03 19:50 [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay
@ 2025-09-03 19:50 ` Aaron Kling via B4 Relay
2025-09-04 8:20 ` Krzysztof Kozlowski
2025-09-03 19:50 ` [PATCH v2 2/8] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210 Aaron Kling via B4 Relay
` (7 subsequent siblings)
8 siblings, 1 reply; 16+ messages in thread
From: Aaron Kling via B4 Relay @ 2025-09-03 19:50 UTC (permalink / raw)
To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding,
Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park,
Chanwoo Choi, Dmitry Osipenko
Cc: linux-kernel, devicetree, linux-tegra, linux-pm, Aaron Kling
From: Aaron Kling <webgeek1234@gmail.com>
Each memory client has unique hardware ID, add these IDs.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
include/dt-bindings/memory/tegra210-mc.h | 58 ++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/include/dt-bindings/memory/tegra210-mc.h b/include/dt-bindings/memory/tegra210-mc.h
index 5e082547f1794cba1f72872782e04d8747863b6d..48474942a000e049142014e3bcc132b88bf1a92d 100644
--- a/include/dt-bindings/memory/tegra210-mc.h
+++ b/include/dt-bindings/memory/tegra210-mc.h
@@ -75,4 +75,62 @@
#define TEGRA210_MC_RESET_ETR 28
#define TEGRA210_MC_RESET_TSECB 29
+#define TEGRA210_MC_PTCR 0
+#define TEGRA210_MC_DISPLAY0A 1
+#define TEGRA210_MC_DISPLAY0AB 2
+#define TEGRA210_MC_DISPLAY0B 3
+#define TEGRA210_MC_DISPLAY0BB 4
+#define TEGRA210_MC_DISPLAY0C 5
+#define TEGRA210_MC_DISPLAY0CB 6
+#define TEGRA210_MC_AFIR 14
+#define TEGRA210_MC_AVPCARM7R 15
+#define TEGRA210_MC_DISPLAYHC 16
+#define TEGRA210_MC_DISPLAYHCB 17
+#define TEGRA210_MC_HDAR 21
+#define TEGRA210_MC_HOST1XDMAR 22
+#define TEGRA210_MC_HOST1XR 23
+#define TEGRA210_MC_NVENCSRD 28
+#define TEGRA210_MC_PPCSAHBDMAR 29
+#define TEGRA210_MC_PPCSAHBSLVR 30
+#define TEGRA210_MC_SATAR 31
+#define TEGRA210_MC_MPCORER 39
+#define TEGRA210_MC_NVENCSWR 43
+#define TEGRA210_MC_AFIW 49
+#define TEGRA210_MC_AVPCARM7W 50
+#define TEGRA210_MC_HDAW 53
+#define TEGRA210_MC_HOST1XW 54
+#define TEGRA210_MC_MPCOREW 57
+#define TEGRA210_MC_PPCSAHBDMAW 59
+#define TEGRA210_MC_PPCSAHBSLVW 60
+#define TEGRA210_MC_SATAW 61
+#define TEGRA210_MC_ISPRA 68
+#define TEGRA210_MC_ISPWA 70
+#define TEGRA210_MC_ISPWB 71
+#define TEGRA210_MC_XUSB_HOSTR 74
+#define TEGRA210_MC_XUSB_HOSTW 75
+#define TEGRA210_MC_XUSB_DEVR 76
+#define TEGRA210_MC_XUSB_DEVW 77
+#define TEGRA210_MC_ISPRAB 78
+#define TEGRA210_MC_ISPWAB 80
+#define TEGRA210_MC_ISPWBB 81
+#define TEGRA210_MC_TSECSRD 84
+#define TEGRA210_MC_TSECSWR 85
+#define TEGRA210_MC_A9AVPSCR 86
+#define TEGRA210_MC_A9AVPSCW 87
+#define TEGRA210_MC_GPUSRD 88
+#define TEGRA210_MC_GPUSWR 89
+#define TEGRA210_MC_DISPLAYT 90
+#define TEGRA210_MC_SDMMCRA 96
+#define TEGRA210_MC_SDMMCRAA 97
+#define TEGRA210_MC_SDMMCR 98
+#define TEGRA210_MC_SDMMCRAB 99
+#define TEGRA210_MC_SDMMCWA 100
+#define TEGRA210_MC_SDMMCWAA 101
+#define TEGRA210_MC_SDMMCW 102
+#define TEGRA210_MC_SDMMCWAB 103
+#define TEGRA210_MC_VICSRD 108
+#define TEGRA210_MC_VICSWR 109
+#define TEGRA210_MC_VIW 114
+#define TEGRA210_MC_DISPLAYD 115
+
#endif
--
2.50.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/8] dt-bindings: memory: tegra210: Add memory client IDs
2025-09-03 19:50 ` [PATCH v2 1/8] dt-bindings: memory: tegra210: Add memory client IDs Aaron Kling via B4 Relay
@ 2025-09-04 8:20 ` Krzysztof Kozlowski
2025-09-04 17:33 ` Aaron Kling
0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-09-04 8:20 UTC (permalink / raw)
To: Aaron Kling
Cc: Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter,
Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi,
Dmitry Osipenko, linux-kernel, devicetree, linux-tegra, linux-pm
On Wed, Sep 03, 2025 at 02:50:07PM -0500, Aaron Kling wrote:
> Each memory client has unique hardware ID, add these IDs.
>
> Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> ---
> include/dt-bindings/memory/tegra210-mc.h | 58 ++++++++++++++++++++++++++++++++
> 1 file changed, 58 insertions(+)
>
> diff --git a/include/dt-bindings/memory/tegra210-mc.h b/include/dt-bindings/memory/tegra210-mc.h
> index 5e082547f1794cba1f72872782e04d8747863b6d..48474942a000e049142014e3bcc132b88bf1a92d 100644
> --- a/include/dt-bindings/memory/tegra210-mc.h
> +++ b/include/dt-bindings/memory/tegra210-mc.h
> @@ -75,4 +75,62 @@
> #define TEGRA210_MC_RESET_ETR 28
> #define TEGRA210_MC_RESET_TSECB 29
>
> +#define TEGRA210_MC_PTCR 0
There is no driver user of this ABI, so does not look like a binding.
You have entire commit msg to clarify such unusual things, like lack of
users. Please use it.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/8] dt-bindings: memory: tegra210: Add memory client IDs
2025-09-04 8:20 ` Krzysztof Kozlowski
@ 2025-09-04 17:33 ` Aaron Kling
0 siblings, 0 replies; 16+ messages in thread
From: Aaron Kling @ 2025-09-04 17:33 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter,
Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi,
Dmitry Osipenko, linux-kernel, devicetree, linux-tegra, linux-pm
On Thu, Sep 4, 2025 at 3:20 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Wed, Sep 03, 2025 at 02:50:07PM -0500, Aaron Kling wrote:
> > Each memory client has unique hardware ID, add these IDs.
> >
> > Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> > ---
> > include/dt-bindings/memory/tegra210-mc.h | 58 ++++++++++++++++++++++++++++++++
> > 1 file changed, 58 insertions(+)
> >
> > diff --git a/include/dt-bindings/memory/tegra210-mc.h b/include/dt-bindings/memory/tegra210-mc.h
> > index 5e082547f1794cba1f72872782e04d8747863b6d..48474942a000e049142014e3bcc132b88bf1a92d 100644
> > --- a/include/dt-bindings/memory/tegra210-mc.h
> > +++ b/include/dt-bindings/memory/tegra210-mc.h
> > @@ -75,4 +75,62 @@
> > #define TEGRA210_MC_RESET_ETR 28
> > #define TEGRA210_MC_RESET_TSECB 29
> >
> > +#define TEGRA210_MC_PTCR 0
>
> There is no driver user of this ABI, so does not look like a binding.
>
> You have entire commit msg to clarify such unusual things, like lack of
> users. Please use it.
The tegra210-mc driver has these hardcoded and should probably be
updated to use the bindings instead, but I think that's outside of the
scope of this series. I will clarify such in the updated message.
Aaron
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 2/8] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210
2025-09-03 19:50 [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay
2025-09-03 19:50 ` [PATCH v2 1/8] dt-bindings: memory: tegra210: Add memory client IDs Aaron Kling via B4 Relay
@ 2025-09-03 19:50 ` Aaron Kling via B4 Relay
2025-09-04 8:09 ` Krzysztof Kozlowski
2025-09-03 19:50 ` [PATCH v2 3/8] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect Aaron Kling via B4 Relay
` (6 subsequent siblings)
8 siblings, 1 reply; 16+ messages in thread
From: Aaron Kling via B4 Relay @ 2025-09-03 19:50 UTC (permalink / raw)
To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding,
Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park,
Chanwoo Choi, Dmitry Osipenko
Cc: linux-kernel, devicetree, linux-tegra, linux-pm, Aaron Kling
From: Aaron Kling <webgeek1234@gmail.com>
The Tegra210 actmon is compatible with the existing Tegra124 driver.
Describe the compatibles as such.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
.../devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml b/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml
index e3379d1067283e36d1bee303187c0205b410f610..ea1dc86bc31f635f91a0e36f908f5c0c4f9a804c 100644
--- a/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml
+++ b/Documentation/devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml
@@ -19,11 +19,14 @@ description: |
properties:
compatible:
- enum:
- - nvidia,tegra30-actmon
- - nvidia,tegra114-actmon
- - nvidia,tegra124-actmon
- - nvidia,tegra210-actmon
+ oneOf:
+ - enum:
+ - nvidia,tegra30-actmon
+ - nvidia,tegra114-actmon
+ - nvidia,tegra124-actmon
+ - items:
+ - const: nvidia,tegra210-actmon
+ - const: nvidia,tegra124-actmon
reg:
maxItems: 1
--
2.50.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/8] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210
2025-09-03 19:50 ` [PATCH v2 2/8] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210 Aaron Kling via B4 Relay
@ 2025-09-04 8:09 ` Krzysztof Kozlowski
0 siblings, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-09-04 8:09 UTC (permalink / raw)
To: Aaron Kling
Cc: Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter,
Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi,
Dmitry Osipenko, linux-kernel, devicetree, linux-tegra, linux-pm
On Wed, Sep 03, 2025 at 02:50:08PM -0500, Aaron Kling wrote:
> The Tegra210 actmon is compatible with the existing Tegra124 driver.
> Describe the compatibles as such.
>
> Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> ---
> .../devicetree/bindings/devfreq/nvidia,tegra30-actmon.yaml | 13 ++++++++-----
> 1 file changed, 8 insertions(+), 5 deletions(-)
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 3/8] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect
2025-09-03 19:50 [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay
2025-09-03 19:50 ` [PATCH v2 1/8] dt-bindings: memory: tegra210: Add memory client IDs Aaron Kling via B4 Relay
2025-09-03 19:50 ` [PATCH v2 2/8] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210 Aaron Kling via B4 Relay
@ 2025-09-03 19:50 ` Aaron Kling via B4 Relay
2025-09-04 8:11 ` Krzysztof Kozlowski
2025-09-03 19:50 ` [PATCH v2 4/8] soc: tegra: fuse: speedo-tegra210: Add soc speedo 2 Aaron Kling via B4 Relay
` (5 subsequent siblings)
8 siblings, 1 reply; 16+ messages in thread
From: Aaron Kling via B4 Relay @ 2025-09-03 19:50 UTC (permalink / raw)
To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding,
Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park,
Chanwoo Choi, Dmitry Osipenko
Cc: linux-kernel, devicetree, linux-tegra, linux-pm, Aaron Kling
From: Aaron Kling <webgeek1234@gmail.com>
These are needed for dynamic frequency scaling of the EMC controller.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
.../bindings/memory-controllers/nvidia,tegra210-emc.yaml | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
index bc8477e7ab193b7880bb681037985f3fccebf02f..6cc1c7fc7a328bd18c7c0beb535c1ff918bcdb2a 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
@@ -33,6 +33,9 @@ properties:
items:
- description: EMC general interrupt
+ "#interconnect-cells":
+ const: 0
+
memory-region:
maxItems: 1
description:
@@ -44,12 +47,19 @@ properties:
description:
phandle of the memory controller node
+ 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
+ - "#interconnect-cells"
- nvidia,memory-controller
+ - operating-points-v2
additionalProperties: false
@@ -79,4 +89,7 @@ examples:
interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&emc_table>;
nvidia,memory-controller = <&mc>;
+ operating-points-v2 = <&dvfs_opp_table>;
+
+ #interconnect-cells = <0>;
};
--
2.50.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 3/8] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect
2025-09-03 19:50 ` [PATCH v2 3/8] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect Aaron Kling via B4 Relay
@ 2025-09-04 8:11 ` Krzysztof Kozlowski
0 siblings, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-09-04 8:11 UTC (permalink / raw)
To: Aaron Kling
Cc: Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter,
Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi,
Dmitry Osipenko, linux-kernel, devicetree, linux-tegra, linux-pm
On Wed, Sep 03, 2025 at 02:50:09PM -0500, Aaron Kling wrote:
> These are needed for dynamic frequency scaling of the EMC controller.
>
> Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> ---
> .../bindings/memory-controllers/nvidia,tegra210-emc.yaml | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
I asked to order patches within patchset in some logical way. First
patch was memory, second other, third again memory.
There are no dependencies explained, so this looks like groupping
unrelated patches, therefore SPLIT finally the patchset per subsystem.
>
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
> index bc8477e7ab193b7880bb681037985f3fccebf02f..6cc1c7fc7a328bd18c7c0beb535c1ff918bcdb2a 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
> @@ -33,6 +33,9 @@ properties:
> items:
> - description: EMC general interrupt
>
> + "#interconnect-cells":
> + const: 0
> +
> memory-region:
> maxItems: 1
> description:
> @@ -44,12 +47,19 @@ properties:
> description:
> phandle of the memory controller node
>
> + operating-points-v2:
> + description:
> + Should contain freqs and voltages and opp-supported-hw property, which
> + is a bitfield indicating SoC speedo ID mask.
> +
No opp-table?
> required:
> - compatible
> - reg
> - clocks
> - clock-names
> + - "#interconnect-cells"
That's ABI break without explanation.
> - nvidia,memory-controller
> + - operating-points-v2
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 4/8] soc: tegra: fuse: speedo-tegra210: Add soc speedo 2
2025-09-03 19:50 [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay
` (2 preceding siblings ...)
2025-09-03 19:50 ` [PATCH v2 3/8] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect Aaron Kling via B4 Relay
@ 2025-09-03 19:50 ` Aaron Kling via B4 Relay
2025-09-03 19:50 ` [PATCH v2 5/8] memory: tegra210: Support interconnect framework Aaron Kling via B4 Relay
` (4 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Aaron Kling via B4 Relay @ 2025-09-03 19:50 UTC (permalink / raw)
To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding,
Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park,
Chanwoo Choi, Dmitry Osipenko
Cc: linux-kernel, devicetree, linux-tegra, linux-pm, Aaron Kling
From: Aaron Kling <webgeek1234@gmail.com>
The Jetson Nano series of modules only have 2 emc table entries,
different from other soc sku's. As the emc driver uses the soc speedo to
populate the emc opp tables, add a new speedo id to uniquely identify
this.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
drivers/soc/tegra/fuse/speedo-tegra210.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/soc/tegra/fuse/speedo-tegra210.c b/drivers/soc/tegra/fuse/speedo-tegra210.c
index 60356159e00d2059e55eaacba27b5ca63bf96c90..c310bdabcfd06ea8f23facb4eaaf209f183dc4eb 100644
--- a/drivers/soc/tegra/fuse/speedo-tegra210.c
+++ b/drivers/soc/tegra/fuse/speedo-tegra210.c
@@ -97,6 +97,7 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info,
break;
case 0x8F:
+ sku_info->soc_speedo_id = 2;
sku_info->cpu_speedo_id = 9;
sku_info->gpu_speedo_id = 2;
break;
--
2.50.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 5/8] memory: tegra210: Support interconnect framework
2025-09-03 19:50 [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay
` (3 preceding siblings ...)
2025-09-03 19:50 ` [PATCH v2 4/8] soc: tegra: fuse: speedo-tegra210: Add soc speedo 2 Aaron Kling via B4 Relay
@ 2025-09-03 19:50 ` Aaron Kling via B4 Relay
2025-09-04 8:17 ` Krzysztof Kozlowski
2025-09-03 19:50 ` [PATCH v2 6/8] arm64: tegra: tegra210: Add actmon Aaron Kling via B4 Relay
` (3 subsequent siblings)
8 siblings, 1 reply; 16+ messages in thread
From: Aaron Kling via B4 Relay @ 2025-09-03 19:50 UTC (permalink / raw)
To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding,
Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park,
Chanwoo Choi, Dmitry Osipenko
Cc: linux-kernel, devicetree, linux-tegra, linux-pm, Aaron Kling
From: Aaron Kling <webgeek1234@gmail.com>
This makes mc and emc interconnect providers and allows for dynamic
memory clock scaling.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
drivers/memory/tegra/Kconfig | 1 +
drivers/memory/tegra/tegra210-emc-core.c | 274 ++++++++++++++++++++++++++++++-
drivers/memory/tegra/tegra210-emc.h | 23 +++
drivers/memory/tegra/tegra210.c | 81 +++++++++
4 files changed, 377 insertions(+), 2 deletions(-)
diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index fc5a277918267ee8240f9fb9efeb80275db4790b..2d0be29afe2b9ebf9a0630ef7fb6fb43ff359499 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -55,6 +55,7 @@ config TEGRA210_EMC
tristate "NVIDIA Tegra210 External Memory Controller driver"
depends on ARCH_TEGRA_210_SOC || COMPILE_TEST
select TEGRA210_EMC_TABLE
+ select PM_OPP
help
This driver is for the External Memory Controller (EMC) found on
Tegra210 chips. The EMC controls the external DRAM on the board.
diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c
index e96ca4157d48182574310f8caf72687bed7cc16a..f12e60b47fa87d629505cde57310d2bb68fc87f3 100644
--- a/drivers/memory/tegra/tegra210-emc-core.c
+++ b/drivers/memory/tegra/tegra210-emc-core.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/of_reserved_mem.h>
#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include <soc/tegra/fuse.h>
@@ -1569,6 +1570,79 @@ static int tegra210_emc_set_rate(struct device *dev,
return 0;
}
+static void tegra_emc_rate_requests_init(struct tegra210_emc *emc)
+{
+ unsigned int i;
+
+ for (i = 0; i < EMC_RATE_TYPE_MAX; i++) {
+ emc->requested_rate[i].min_rate = 0;
+ emc->requested_rate[i].max_rate = ULONG_MAX;
+ }
+}
+
+static int emc_request_rate(struct tegra210_emc *emc,
+ unsigned long new_min_rate,
+ unsigned long new_max_rate,
+ enum emc_rate_request_type type)
+{
+ struct emc_rate_request *req = emc->requested_rate;
+ unsigned long min_rate = 0, max_rate = ULONG_MAX;
+ unsigned int i;
+ int err;
+
+ /* select minimum and maximum rates among the requested rates */
+ for (i = 0; i < EMC_RATE_TYPE_MAX; i++, req++) {
+ if (i == type) {
+ min_rate = max(new_min_rate, min_rate);
+ max_rate = min(new_max_rate, max_rate);
+ } else {
+ min_rate = max(req->min_rate, min_rate);
+ max_rate = min(req->max_rate, max_rate);
+ }
+ }
+
+ if (min_rate > max_rate) {
+ dev_err_ratelimited(emc->dev, "%s: type %u: out of range: %lu %lu\n",
+ __func__, type, min_rate, max_rate);
+ return -ERANGE;
+ }
+
+ err = clk_set_rate(emc->clk, min_rate);
+ if (err)
+ return err;
+
+ emc->requested_rate[type].min_rate = new_min_rate;
+ emc->requested_rate[type].max_rate = new_max_rate;
+
+ return 0;
+}
+
+static int emc_set_min_rate(struct tegra210_emc *emc, unsigned long rate,
+ enum emc_rate_request_type type)
+{
+ struct emc_rate_request *req = &emc->requested_rate[type];
+ int ret;
+
+ mutex_lock(&emc->rate_lock);
+ ret = emc_request_rate(emc, rate, req->max_rate, type);
+ mutex_unlock(&emc->rate_lock);
+
+ return ret;
+}
+
+static int emc_set_max_rate(struct tegra210_emc *emc, unsigned long rate,
+ enum emc_rate_request_type type)
+{
+ struct emc_rate_request *req = &emc->requested_rate[type];
+ int ret;
+
+ mutex_lock(&emc->rate_lock);
+ ret = emc_request_rate(emc, req->min_rate, rate, type);
+ mutex_unlock(&emc->rate_lock);
+
+ return ret;
+}
+
/*
* debugfs interface
*
@@ -1641,7 +1715,7 @@ static int tegra210_emc_debug_min_rate_set(void *data, u64 rate)
if (!tegra210_emc_validate_rate(emc, rate))
return -EINVAL;
- err = clk_set_min_rate(emc->clk, rate);
+ err = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG);
if (err < 0)
return err;
@@ -1671,7 +1745,7 @@ static int tegra210_emc_debug_max_rate_set(void *data, u64 rate)
if (!tegra210_emc_validate_rate(emc, rate))
return -EINVAL;
- err = clk_set_max_rate(emc->clk, rate);
+ err = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG);
if (err < 0)
return err;
@@ -1758,6 +1832,193 @@ static void tegra210_emc_debugfs_init(struct tegra210_emc *emc)
&tegra210_emc_debug_temperature_fops);
}
+static inline struct tegra210_emc *
+to_tegra210_emc_provider(struct icc_provider *provider)
+{
+ return container_of(provider, struct tegra210_emc, icc_provider);
+}
+
+static struct icc_node_data *
+emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
+{
+ struct icc_provider *provider = data;
+ struct icc_node_data *ndata;
+ struct icc_node *node;
+
+ /* External Memory is the only possible ICC route */
+ list_for_each_entry(node, &provider->nodes, node_list) {
+ if (node->id != TEGRA_ICC_EMEM)
+ continue;
+
+ ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+ if (!ndata)
+ return ERR_PTR(-ENOMEM);
+
+ /*
+ * SRC and DST nodes should have matching TAG in order to have
+ * it set by default for a requested path.
+ */
+ ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+ ndata->node = node;
+
+ return ndata;
+ }
+
+ return ERR_PTR(-EPROBE_DEFER);
+}
+
+static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+ struct tegra210_emc *emc = to_tegra210_emc_provider(dst->provider);
+ unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
+ unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
+ unsigned long long rate = max(avg_bw, peak_bw);
+ const unsigned int ddr = 2;
+ int err;
+
+ /*
+ * Tegra210 memory layout can be 1 channel at 64-bit or 2 channels
+ * at 32-bit each. Either way, the total bus width will always be
+ * 64-bit.
+ */
+ const unsigned int dram_data_bus_width_bytes = 64 / 8;
+
+ /*
+ * Tegra210 EMC runs on a clock rate of SDRAM bus. This means that
+ * EMC clock rate is twice smaller than the peak data rate because
+ * data is sampled on both EMC clock edges.
+ */
+ do_div(rate, ddr * dram_data_bus_width_bytes);
+ rate = min_t(u64, rate, U32_MAX);
+
+ err = emc_set_min_rate(emc, rate, EMC_RATE_ICC);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int tegra_emc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak)
+{
+ *avg = 0;
+ *peak = 0;
+
+ return 0;
+}
+
+static int tegra_emc_interconnect_init(struct tegra210_emc *emc)
+{
+ const struct tegra_mc_soc *soc = emc->mc->soc;
+ struct icc_node *node;
+ int err;
+
+ emc->icc_provider.dev = emc->dev;
+ emc->icc_provider.set = emc_icc_set;
+ emc->icc_provider.data = &emc->icc_provider;
+ emc->icc_provider.aggregate = soc->icc_ops->aggregate;
+ emc->icc_provider.xlate_extended = emc_of_icc_xlate_extended;
+ emc->icc_provider.get_bw = tegra_emc_icc_get_init_bw;
+
+ icc_provider_init(&emc->icc_provider);
+
+ /* create External Memory Controller node */
+ node = icc_node_create(TEGRA_ICC_EMC);
+ if (IS_ERR(node)) {
+ err = PTR_ERR(node);
+ goto err_msg;
+ }
+
+ node->name = "External Memory Controller";
+ icc_node_add(node, &emc->icc_provider);
+
+ /* link External Memory Controller to External Memory (DRAM) */
+ err = icc_link_create(node, TEGRA_ICC_EMEM);
+ if (err)
+ goto remove_nodes;
+
+ /* create External Memory node */
+ node = icc_node_create(TEGRA_ICC_EMEM);
+ if (IS_ERR(node)) {
+ err = PTR_ERR(node);
+ goto remove_nodes;
+ }
+
+ node->name = "External Memory (DRAM)";
+ icc_node_add(node, &emc->icc_provider);
+
+ err = icc_provider_register(&emc->icc_provider);
+ if (err)
+ goto remove_nodes;
+
+ return 0;
+
+remove_nodes:
+ icc_nodes_remove(&emc->icc_provider);
+err_msg:
+ dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
+
+ return err;
+}
+
+static int tegra_emc_opp_table_init(struct tegra210_emc *emc)
+{
+ u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
+ struct dev_pm_opp *opp;
+ unsigned long rate;
+ int opp_token, err, max_opps, i;
+
+ err = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1);
+ if (err < 0) {
+ dev_err(emc->dev, "failed to set OPP supported HW: %d\n", err);
+ return err;
+ }
+ opp_token = err;
+
+ err = dev_pm_opp_of_add_table(emc->dev);
+ if (err) {
+ if (err == -ENODEV)
+ dev_err(emc->dev, "OPP table not found, please update your device tree\n");
+ else
+ dev_err(emc->dev, "failed to add OPP table: %d\n", err);
+
+ goto put_hw_table;
+ }
+
+ max_opps = dev_pm_opp_get_opp_count(emc->dev);
+ if (max_opps <= 0) {
+ dev_err(emc->dev, "Failed to add OPPs\n");
+ goto remove_table;
+ }
+
+ if (emc->num_timings != max_opps) {
+ dev_err(emc->dev, "OPP table does not match emc table\n");
+ goto remove_table;
+ }
+
+ for (i = 0; i < emc->num_timings; i++) {
+ rate = emc->timings[i].rate * 1000;
+ opp = dev_pm_opp_find_freq_exact(emc->dev, rate, true);
+ if (IS_ERR(opp)) {
+ dev_err(emc->dev, "Rate %lu not found in OPP table\n", rate);
+ goto remove_table;
+ }
+
+ dev_pm_opp_put(opp);
+ }
+
+ dev_info_once(emc->dev, "OPP HW ver. 0x%x, current clock rate %lu MHz\n",
+ hw_version, clk_get_rate(emc->clk) / 1000000);
+
+ return 0;
+
+remove_table:
+ dev_pm_opp_of_remove_table(emc->dev);
+put_hw_table:
+ dev_pm_opp_put_supported_hw(opp_token);
+
+ return err;
+}
+
static void tegra210_emc_detect(struct tegra210_emc *emc)
{
u32 value;
@@ -1964,8 +2225,16 @@ static int tegra210_emc_probe(struct platform_device *pdev)
timer_setup(&emc->training, tegra210_emc_train, 0);
+ err = tegra_emc_opp_table_init(emc);
+ if (err)
+ return err;
+
+ tegra_emc_rate_requests_init(emc);
+
tegra210_emc_debugfs_init(emc);
+ tegra_emc_interconnect_init(emc);
+
cd = devm_thermal_of_cooling_device_register(emc->dev, np, "emc", emc,
&tegra210_emc_cd_ops);
if (IS_ERR(cd)) {
@@ -2050,6 +2319,7 @@ static struct platform_driver tegra210_emc_driver = {
.name = "tegra210-emc",
.of_match_table = tegra210_emc_of_match,
.pm = &tegra210_emc_pm_ops,
+ .sync_state = icc_sync_state,
},
.probe = tegra210_emc_probe,
.remove = tegra210_emc_remove,
diff --git a/drivers/memory/tegra/tegra210-emc.h b/drivers/memory/tegra/tegra210-emc.h
index 8988bcf1529072a7bdc93b185ebe0d51d82c1763..3c9142bfd5ae5c57bbc139e69e62c893b50ce40c 100644
--- a/drivers/memory/tegra/tegra210-emc.h
+++ b/drivers/memory/tegra/tegra210-emc.h
@@ -8,6 +8,7 @@
#include <linux/clk.h>
#include <linux/clk/tegra.h>
+#include <linux/interconnect-provider.h>
#include <linux/io.h>
#include <linux/platform_device.h>
@@ -784,6 +785,17 @@ enum {
#define TRIM_REGS_SIZE 138
#define BURST_REGS_SIZE 221
+enum emc_rate_request_type {
+ EMC_RATE_DEBUG,
+ EMC_RATE_ICC,
+ EMC_RATE_TYPE_MAX,
+};
+
+struct emc_rate_request {
+ unsigned long min_rate;
+ unsigned long max_rate;
+};
+
struct tegra210_emc_per_channel_regs {
u16 bank;
u16 offset;
@@ -932,6 +944,17 @@ struct tegra210_emc {
} debugfs;
struct tegra210_clk_emc_provider provider;
+
+ struct icc_provider icc_provider;
+
+ /*
+ * There are multiple sources in the EMC driver which could request
+ * a min/max clock rate, these rates are contained in this array.
+ */
+ struct emc_rate_request requested_rate[EMC_RATE_TYPE_MAX];
+
+ /* protect shared rate-change code path */
+ struct mutex rate_lock;
};
struct tegra210_emc_sequence {
diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
index 8ab6498dbe7d2f410d4eb262926c18b77edb0b3d..c5f079b60363f86b9b1382182e71bfcea9e19829 100644
--- a/drivers/memory/tegra/tegra210.c
+++ b/drivers/memory/tegra/tegra210.c
@@ -3,6 +3,9 @@
* Copyright (C) 2015 NVIDIA CORPORATION. All rights reserved.
*/
+#include <linux/of.h>
+#include <linux/device.h>
+
#include <dt-bindings/memory/tegra210-mc.h>
#include "mc.h"
@@ -1273,6 +1276,83 @@ static const struct tegra_mc_reset tegra210_mc_resets[] = {
TEGRA210_MC_RESET(TSECB, 0x970, 0x974, 13),
};
+static int tegra210_mc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+ /* TODO: program PTSA */
+ return 0;
+}
+
+static int tegra210_mc_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+ u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+ /*
+ * ISO clients need to reserve extra bandwidth up-front because
+ * there could be high bandwidth pressure during initial filling
+ * of the client's FIFO buffers. Secondly, we need to take into
+ * account impurities of the memory subsystem.
+ */
+ if (tag & TEGRA_MC_ICC_TAG_ISO)
+ peak_bw = tegra_mc_scale_percents(peak_bw, 400);
+
+ *agg_avg += avg_bw;
+ *agg_peak = max(*agg_peak, peak_bw);
+
+ return 0;
+}
+
+static struct icc_node_data *
+tegra210_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
+{
+ struct tegra_mc *mc = icc_provider_to_tegra_mc(data);
+ const struct tegra_mc_client *client;
+ unsigned int i, idx = spec->args[0];
+ struct icc_node_data *ndata;
+ struct icc_node *node;
+
+ list_for_each_entry(node, &mc->provider.nodes, node_list) {
+ if (node->id != idx)
+ continue;
+
+ ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+ if (!ndata)
+ return ERR_PTR(-ENOMEM);
+
+ client = &mc->soc->clients[idx];
+ ndata->node = node;
+
+ switch (client->swgroup) {
+ case TEGRA_SWGROUP_DC:
+ case TEGRA_SWGROUP_DCB:
+ case TEGRA_SWGROUP_PTC:
+ case TEGRA_SWGROUP_VI:
+ /* these clients are isochronous by default */
+ ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+ break;
+
+ default:
+ ndata->tag = TEGRA_MC_ICC_TAG_DEFAULT;
+ break;
+ }
+
+ return ndata;
+ }
+
+ for (i = 0; i < mc->soc->num_clients; i++) {
+ if (mc->soc->clients[i].id == idx)
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+
+ dev_err(mc->dev, "invalid ICC client ID %u\n", idx);
+
+ return ERR_PTR(-EINVAL);
+}
+
+static const struct tegra_mc_icc_ops tegra210_mc_icc_ops = {
+ .xlate_extended = tegra210_mc_of_icc_xlate_extended,
+ .aggregate = tegra210_mc_icc_aggregate,
+ .set = tegra210_mc_icc_set,
+};
+
const struct tegra_mc_soc tegra210_mc_soc = {
.clients = tegra210_mc_clients,
.num_clients = ARRAY_SIZE(tegra210_mc_clients),
@@ -1286,5 +1366,6 @@ const struct tegra_mc_soc tegra210_mc_soc = {
.reset_ops = &tegra_mc_reset_ops_common,
.resets = tegra210_mc_resets,
.num_resets = ARRAY_SIZE(tegra210_mc_resets),
+ .icc_ops = &tegra210_mc_icc_ops,
.ops = &tegra30_mc_ops,
};
--
2.50.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 5/8] memory: tegra210: Support interconnect framework
2025-09-03 19:50 ` [PATCH v2 5/8] memory: tegra210: Support interconnect framework Aaron Kling via B4 Relay
@ 2025-09-04 8:17 ` Krzysztof Kozlowski
2025-09-04 17:28 ` Aaron Kling
0 siblings, 1 reply; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-09-04 8:17 UTC (permalink / raw)
To: Aaron Kling
Cc: Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter,
Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi,
Dmitry Osipenko, linux-kernel, devicetree, linux-tegra, linux-pm
On Wed, Sep 03, 2025 at 02:50:11PM -0500, Aaron Kling wrote:
> This makes mc and emc interconnect providers and allows for dynamic
> memory clock scaling.
>
> Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> ---
> drivers/memory/tegra/Kconfig | 1 +
> drivers/memory/tegra/tegra210-emc-core.c | 274 ++++++++++++++++++++++++++++++-
> drivers/memory/tegra/tegra210-emc.h | 23 +++
> drivers/memory/tegra/tegra210.c | 81 +++++++++
> 4 files changed, 377 insertions(+), 2 deletions(-)
Patch #3 was memory, patch #4 was soc, patch #5 is memory, so that
mixup pattern continues.
Please address the earlier feedback.
>
> diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
> index fc5a277918267ee8240f9fb9efeb80275db4790b..2d0be29afe2b9ebf9a0630ef7fb6fb43ff359499 100644
> --- a/drivers/memory/tegra/Kconfig
> +++ b/drivers/memory/tegra/Kconfig
> @@ -55,6 +55,7 @@ config TEGRA210_EMC
> tristate "NVIDIA Tegra210 External Memory Controller driver"
> depends on ARCH_TEGRA_210_SOC || COMPILE_TEST
> select TEGRA210_EMC_TABLE
> + select PM_OPP
> help
> This driver is for the External Memory Controller (EMC) found on
> Tegra210 chips. The EMC controls the external DRAM on the board.
> diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c
> index e96ca4157d48182574310f8caf72687bed7cc16a..f12e60b47fa87d629505cde57310d2bb68fc87f3 100644
> --- a/drivers/memory/tegra/tegra210-emc-core.c
> +++ b/drivers/memory/tegra/tegra210-emc-core.c
> @@ -13,6 +13,7 @@
> #include <linux/module.h>
> #include <linux/of_reserved_mem.h>
> #include <linux/platform_device.h>
> +#include <linux/pm_opp.h>
> #include <linux/slab.h>
> #include <linux/thermal.h>
> #include <soc/tegra/fuse.h>
> @@ -1569,6 +1570,79 @@ static int tegra210_emc_set_rate(struct device *dev,
> return 0;
> }
>
...
> @@ -1758,6 +1832,193 @@ static void tegra210_emc_debugfs_init(struct tegra210_emc *emc)
> &tegra210_emc_debug_temperature_fops);
> }
>
> +static inline struct tegra210_emc *
> +to_tegra210_emc_provider(struct icc_provider *provider)
> +{
> + return container_of(provider, struct tegra210_emc, icc_provider);
> +}
> +
> +static struct icc_node_data *
> +emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
> +{
> + struct icc_provider *provider = data;
> + struct icc_node_data *ndata;
> + struct icc_node *node;
> +
> + /* External Memory is the only possible ICC route */
> + list_for_each_entry(node, &provider->nodes, node_list) {
> + if (node->id != TEGRA_ICC_EMEM)
> + continue;
> +
> + ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
> + if (!ndata)
> + return ERR_PTR(-ENOMEM);
> +
> + /*
> + * SRC and DST nodes should have matching TAG in order to have
> + * it set by default for a requested path.
> + */
> + ndata->tag = TEGRA_MC_ICC_TAG_ISO;
> + ndata->node = node;
> +
> + return ndata;
> + }
> +
> + return ERR_PTR(-EPROBE_DEFER);
> +}
> +
> +static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> + struct tegra210_emc *emc = to_tegra210_emc_provider(dst->provider);
> + unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
> + unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
> + unsigned long long rate = max(avg_bw, peak_bw);
> + const unsigned int ddr = 2;
Just use defines in top part for this.
> + int err;
> +
> + /*
> + * Tegra210 memory layout can be 1 channel at 64-bit or 2 channels
> + * at 32-bit each. Either way, the total bus width will always be
> + * 64-bit.
> + */
> + const unsigned int dram_data_bus_width_bytes = 64 / 8;
Same here.
> +
> + /*
> + * Tegra210 EMC runs on a clock rate of SDRAM bus. This means that
> + * EMC clock rate is twice smaller than the peak data rate because
> + * data is sampled on both EMC clock edges.
> + */
> + do_div(rate, ddr * dram_data_bus_width_bytes);
> + rate = min_t(u64, rate, U32_MAX);
> +
> + err = emc_set_min_rate(emc, rate, EMC_RATE_ICC);
> + if (err)
> + return err;
> +
> + return 0;
> +}
> +
> +static int tegra_emc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak)
> +{
> + *avg = 0;
> + *peak = 0;
> +
> + return 0;
> +}
> +
> +static int tegra_emc_interconnect_init(struct tegra210_emc *emc)
> +{
> + const struct tegra_mc_soc *soc = emc->mc->soc;
> + struct icc_node *node;
> + int err;
> +
> + emc->icc_provider.dev = emc->dev;
> + emc->icc_provider.set = emc_icc_set;
> + emc->icc_provider.data = &emc->icc_provider;
> + emc->icc_provider.aggregate = soc->icc_ops->aggregate;
> + emc->icc_provider.xlate_extended = emc_of_icc_xlate_extended;
> + emc->icc_provider.get_bw = tegra_emc_icc_get_init_bw;
> +
> + icc_provider_init(&emc->icc_provider);
> +
> + /* create External Memory Controller node */
> + node = icc_node_create(TEGRA_ICC_EMC);
> + if (IS_ERR(node)) {
> + err = PTR_ERR(node);
> + goto err_msg;
> + }
> +
> + node->name = "External Memory Controller";
> + icc_node_add(node, &emc->icc_provider);
> +
> + /* link External Memory Controller to External Memory (DRAM) */
> + err = icc_link_create(node, TEGRA_ICC_EMEM);
> + if (err)
> + goto remove_nodes;
> +
> + /* create External Memory node */
> + node = icc_node_create(TEGRA_ICC_EMEM);
> + if (IS_ERR(node)) {
> + err = PTR_ERR(node);
> + goto remove_nodes;
> + }
> +
> + node->name = "External Memory (DRAM)";
> + icc_node_add(node, &emc->icc_provider);
> +
> + err = icc_provider_register(&emc->icc_provider);
> + if (err)
> + goto remove_nodes;
> +
> + return 0;
> +
> +remove_nodes:
> + icc_nodes_remove(&emc->icc_provider);
> +err_msg:
> + dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
> +
> + return err;
> +}
> +
> +static int tegra_emc_opp_table_init(struct tegra210_emc *emc)
> +{
> + u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
> + struct dev_pm_opp *opp;
> + unsigned long rate;
> + int opp_token, err, max_opps, i;
> +
> + err = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1);
> + if (err < 0) {
> + dev_err(emc->dev, "failed to set OPP supported HW: %d\n", err);
> + return err;
> + }
> + opp_token = err;
> +
> + err = dev_pm_opp_of_add_table(emc->dev);
> + if (err) {
> + if (err == -ENODEV)
> + dev_err(emc->dev, "OPP table not found, please update your device tree\n");
So this looks like the actual ABI break.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 5/8] memory: tegra210: Support interconnect framework
2025-09-04 8:17 ` Krzysztof Kozlowski
@ 2025-09-04 17:28 ` Aaron Kling
0 siblings, 0 replies; 16+ messages in thread
From: Aaron Kling @ 2025-09-04 17:28 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter,
Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi,
Dmitry Osipenko, linux-kernel, devicetree, linux-tegra, linux-pm
On Thu, Sep 4, 2025 at 3:17 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Wed, Sep 03, 2025 at 02:50:11PM -0500, Aaron Kling wrote:
> > This makes mc and emc interconnect providers and allows for dynamic
> > memory clock scaling.
> >
> > Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> > ---
> > drivers/memory/tegra/Kconfig | 1 +
> > drivers/memory/tegra/tegra210-emc-core.c | 274 ++++++++++++++++++++++++++++++-
> > drivers/memory/tegra/tegra210-emc.h | 23 +++
> > drivers/memory/tegra/tegra210.c | 81 +++++++++
> > 4 files changed, 377 insertions(+), 2 deletions(-)
>
> Patch #3 was memory, patch #4 was soc, patch #5 is memory, so that
> mixup pattern continues.
>
> Please address the earlier feedback.
Alright, I double check the docs and re-order this and my other series
for the next revisions. I had a misunderstanding how subsystems were
split up, which caused most but not all of the issues.
>
> >
> > diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
> > index fc5a277918267ee8240f9fb9efeb80275db4790b..2d0be29afe2b9ebf9a0630ef7fb6fb43ff359499 100644
> > --- a/drivers/memory/tegra/Kconfig
> > +++ b/drivers/memory/tegra/Kconfig
> > @@ -55,6 +55,7 @@ config TEGRA210_EMC
> > tristate "NVIDIA Tegra210 External Memory Controller driver"
> > depends on ARCH_TEGRA_210_SOC || COMPILE_TEST
> > select TEGRA210_EMC_TABLE
> > + select PM_OPP
> > help
> > This driver is for the External Memory Controller (EMC) found on
> > Tegra210 chips. The EMC controls the external DRAM on the board.
> > diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c
> > index e96ca4157d48182574310f8caf72687bed7cc16a..f12e60b47fa87d629505cde57310d2bb68fc87f3 100644
> > --- a/drivers/memory/tegra/tegra210-emc-core.c
> > +++ b/drivers/memory/tegra/tegra210-emc-core.c
> > @@ -13,6 +13,7 @@
> > #include <linux/module.h>
> > #include <linux/of_reserved_mem.h>
> > #include <linux/platform_device.h>
> > +#include <linux/pm_opp.h>
> > #include <linux/slab.h>
> > #include <linux/thermal.h>
> > #include <soc/tegra/fuse.h>
> > @@ -1569,6 +1570,79 @@ static int tegra210_emc_set_rate(struct device *dev,
> > return 0;
> > }
> >
>
> ...
>
> > @@ -1758,6 +1832,193 @@ static void tegra210_emc_debugfs_init(struct tegra210_emc *emc)
> > &tegra210_emc_debug_temperature_fops);
> > }
> >
> > +static inline struct tegra210_emc *
> > +to_tegra210_emc_provider(struct icc_provider *provider)
> > +{
> > + return container_of(provider, struct tegra210_emc, icc_provider);
> > +}
> > +
> > +static struct icc_node_data *
> > +emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data)
> > +{
> > + struct icc_provider *provider = data;
> > + struct icc_node_data *ndata;
> > + struct icc_node *node;
> > +
> > + /* External Memory is the only possible ICC route */
> > + list_for_each_entry(node, &provider->nodes, node_list) {
> > + if (node->id != TEGRA_ICC_EMEM)
> > + continue;
> > +
> > + ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
> > + if (!ndata)
> > + return ERR_PTR(-ENOMEM);
> > +
> > + /*
> > + * SRC and DST nodes should have matching TAG in order to have
> > + * it set by default for a requested path.
> > + */
> > + ndata->tag = TEGRA_MC_ICC_TAG_ISO;
> > + ndata->node = node;
> > +
> > + return ndata;
> > + }
> > +
> > + return ERR_PTR(-EPROBE_DEFER);
> > +}
> > +
> > +static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
> > +{
> > + struct tegra210_emc *emc = to_tegra210_emc_provider(dst->provider);
> > + unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
> > + unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
> > + unsigned long long rate = max(avg_bw, peak_bw);
> > + const unsigned int ddr = 2;
>
> Just use defines in top part for this.
>
> > + int err;
> > +
> > + /*
> > + * Tegra210 memory layout can be 1 channel at 64-bit or 2 channels
> > + * at 32-bit each. Either way, the total bus width will always be
> > + * 64-bit.
> > + */
> > + const unsigned int dram_data_bus_width_bytes = 64 / 8;
>
> Same here.
>
> > +
> > + /*
> > + * Tegra210 EMC runs on a clock rate of SDRAM bus. This means that
> > + * EMC clock rate is twice smaller than the peak data rate because
> > + * data is sampled on both EMC clock edges.
> > + */
> > + do_div(rate, ddr * dram_data_bus_width_bytes);
> > + rate = min_t(u64, rate, U32_MAX);
> > +
> > + err = emc_set_min_rate(emc, rate, EMC_RATE_ICC);
> > + if (err)
> > + return err;
> > +
> > + return 0;
> > +}
> > +
> > +static int tegra_emc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak)
> > +{
> > + *avg = 0;
> > + *peak = 0;
> > +
> > + return 0;
> > +}
> > +
> > +static int tegra_emc_interconnect_init(struct tegra210_emc *emc)
> > +{
> > + const struct tegra_mc_soc *soc = emc->mc->soc;
> > + struct icc_node *node;
> > + int err;
> > +
> > + emc->icc_provider.dev = emc->dev;
> > + emc->icc_provider.set = emc_icc_set;
> > + emc->icc_provider.data = &emc->icc_provider;
> > + emc->icc_provider.aggregate = soc->icc_ops->aggregate;
> > + emc->icc_provider.xlate_extended = emc_of_icc_xlate_extended;
> > + emc->icc_provider.get_bw = tegra_emc_icc_get_init_bw;
> > +
> > + icc_provider_init(&emc->icc_provider);
> > +
> > + /* create External Memory Controller node */
> > + node = icc_node_create(TEGRA_ICC_EMC);
> > + if (IS_ERR(node)) {
> > + err = PTR_ERR(node);
> > + goto err_msg;
> > + }
> > +
> > + node->name = "External Memory Controller";
> > + icc_node_add(node, &emc->icc_provider);
> > +
> > + /* link External Memory Controller to External Memory (DRAM) */
> > + err = icc_link_create(node, TEGRA_ICC_EMEM);
> > + if (err)
> > + goto remove_nodes;
> > +
> > + /* create External Memory node */
> > + node = icc_node_create(TEGRA_ICC_EMEM);
> > + if (IS_ERR(node)) {
> > + err = PTR_ERR(node);
> > + goto remove_nodes;
> > + }
> > +
> > + node->name = "External Memory (DRAM)";
> > + icc_node_add(node, &emc->icc_provider);
> > +
> > + err = icc_provider_register(&emc->icc_provider);
> > + if (err)
> > + goto remove_nodes;
> > +
> > + return 0;
> > +
> > +remove_nodes:
> > + icc_nodes_remove(&emc->icc_provider);
> > +err_msg:
> > + dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
> > +
> > + return err;
> > +}
> > +
> > +static int tegra_emc_opp_table_init(struct tegra210_emc *emc)
> > +{
> > + u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
> > + struct dev_pm_opp *opp;
> > + unsigned long rate;
> > + int opp_token, err, max_opps, i;
> > +
> > + err = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1);
> > + if (err < 0) {
> > + dev_err(emc->dev, "failed to set OPP supported HW: %d\n", err);
> > + return err;
> > + }
> > + opp_token = err;
> > +
> > + err = dev_pm_opp_of_add_table(emc->dev);
> > + if (err) {
> > + if (err == -ENODEV)
> > + dev_err(emc->dev, "OPP table not found, please update your device tree\n");
>
> So this looks like the actual ABI break.
Okay, so let's discuss this. For reference, I based this patch off the
tegra124 change [0], which also caused an abi break. I know past
changes don't justify current mistakes, but this is the context. This
series adds all new required dt properties to the arch common dtsi, so
any newly compiled dtb will work. Any old dtb with a new kernel would
fail to probe, however. I think it would be safe to just skip the
interconnect init if the opp table init returns ENODEV, then let probe
succeed, but I would have to verify that. Do I need to do that and
drop the new requires from the binding?
Aaron
[0] https://github.com/torvalds/linux/commit/380def2d4cf257663de42618e57134afeded32dd#diff-3ff603a1ea7654928390eb213cea0424b6a12251bccbb5fd3b9720402a3c076aR1435
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 6/8] arm64: tegra: tegra210: Add actmon
2025-09-03 19:50 [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay
` (4 preceding siblings ...)
2025-09-03 19:50 ` [PATCH v2 5/8] memory: tegra210: Support interconnect framework Aaron Kling via B4 Relay
@ 2025-09-03 19:50 ` Aaron Kling via B4 Relay
2025-09-03 19:50 ` [PATCH v2 7/8] arm64: tegra: Add interconnect properties to Tegra210 device-tree Aaron Kling via B4 Relay
` (2 subsequent siblings)
8 siblings, 0 replies; 16+ messages in thread
From: Aaron Kling via B4 Relay @ 2025-09-03 19:50 UTC (permalink / raw)
To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding,
Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park,
Chanwoo Choi, Dmitry Osipenko
Cc: linux-kernel, devicetree, linux-tegra, linux-pm, Aaron Kling
From: Aaron Kling <webgeek1234@gmail.com>
This enables the action monitor to facilitate dynamic frequency scaling.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 402b0ede1472af625d9d9e811f5af306d436cc98..6da10db893add44a98fde1666c382511212fd43c 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -485,6 +485,18 @@ flow-controller@60007000 {
reg = <0x0 0x60007000 0x0 0x1000>;
};
+ actmon@6000c800 {
+ compatible = "nvidia,tegra210-actmon", "nvidia,tegra124-actmon";
+ reg = <0x0 0x6000c800 0x0 0x400>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_ACTMON>,
+ <&tegra_car TEGRA210_CLK_EMC>;
+ clock-names = "actmon", "emc";
+ resets = <&tegra_car 119>;
+ reset-names = "actmon";
+ #cooling-cells = <2>;
+ };
+
gpio: gpio@6000d000 {
compatible = "nvidia,tegra210-gpio", "nvidia,tegra30-gpio";
reg = <0x0 0x6000d000 0x0 0x1000>;
--
2.50.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 7/8] arm64: tegra: Add interconnect properties to Tegra210 device-tree
2025-09-03 19:50 [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay
` (5 preceding siblings ...)
2025-09-03 19:50 ` [PATCH v2 6/8] arm64: tegra: tegra210: Add actmon Aaron Kling via B4 Relay
@ 2025-09-03 19:50 ` Aaron Kling via B4 Relay
2025-09-03 19:50 ` [PATCH v2 8/8] arm64: tegra: Add OPP tables on Tegra210 Aaron Kling via B4 Relay
2025-09-04 8:08 ` [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Krzysztof Kozlowski
8 siblings, 0 replies; 16+ messages in thread
From: Aaron Kling via B4 Relay @ 2025-09-03 19:50 UTC (permalink / raw)
To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding,
Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park,
Chanwoo Choi, Dmitry Osipenko
Cc: linux-kernel, devicetree, linux-tegra, linux-pm, Aaron Kling
From: Aaron Kling <webgeek1234@gmail.com>
Add interconnect properties to the Memory Controller, External Memory
Controller and the Display Controller nodes in order to describe hardware
interconnection.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 6da10db893add44a98fde1666c382511212fd43c..2fcc7a28690f7100d49e8b93c4fb77de7947b002 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -202,6 +202,19 @@ dc@54200000 {
nvidia,outputs = <&dsia &dsib &sor0 &sor1>;
nvidia,head = <0>;
+
+ interconnects = <&mc TEGRA210_MC_DISPLAY0A &emc>,
+ <&mc TEGRA210_MC_DISPLAY0B &emc>,
+ <&mc TEGRA210_MC_DISPLAY0C &emc>,
+ <&mc TEGRA210_MC_DISPLAYHC &emc>,
+ <&mc TEGRA210_MC_DISPLAYD &emc>,
+ <&mc TEGRA210_MC_DISPLAYT &emc>;
+ interconnect-names = "wina",
+ "winb",
+ "winc",
+ "cursor",
+ "wind",
+ "wint";
};
dc@54240000 {
@@ -217,6 +230,15 @@ dc@54240000 {
nvidia,outputs = <&dsia &dsib &sor0 &sor1>;
nvidia,head = <1>;
+
+ interconnects = <&mc TEGRA210_MC_DISPLAY0AB &emc>,
+ <&mc TEGRA210_MC_DISPLAY0BB &emc>,
+ <&mc TEGRA210_MC_DISPLAY0CB &emc>,
+ <&mc TEGRA210_MC_DISPLAYHCB &emc>;
+ interconnect-names = "wina",
+ "winb",
+ "winc",
+ "cursor";
};
dsia: dsi@54300000 {
@@ -990,6 +1012,7 @@ mc: memory-controller@70019000 {
#iommu-cells = <1>;
#reset-cells = <1>;
+ #interconnect-cells = <1>;
};
emc: external-memory-controller@7001b000 {
@@ -1001,6 +1024,7 @@ emc: external-memory-controller@7001b000 {
clock-names = "emc";
interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
nvidia,memory-controller = <&mc>;
+ #interconnect-cells = <0>;
#cooling-cells = <2>;
};
--
2.50.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 8/8] arm64: tegra: Add OPP tables on Tegra210
2025-09-03 19:50 [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay
` (6 preceding siblings ...)
2025-09-03 19:50 ` [PATCH v2 7/8] arm64: tegra: Add interconnect properties to Tegra210 device-tree Aaron Kling via B4 Relay
@ 2025-09-03 19:50 ` Aaron Kling via B4 Relay
2025-09-04 8:08 ` [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Krzysztof Kozlowski
8 siblings, 0 replies; 16+ messages in thread
From: Aaron Kling via B4 Relay @ 2025-09-03 19:50 UTC (permalink / raw)
To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding,
Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park,
Chanwoo Choi, Dmitry Osipenko
Cc: linux-kernel, devicetree, linux-tegra, linux-pm, Aaron Kling
From: Aaron Kling <webgeek1234@gmail.com>
This adds OPP tables for actmon and emc, enabling dynamic frequency
scaling for ram.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
.../boot/dts/nvidia/tegra210-peripherals-opp.dtsi | 135 +++++++++++++++++++++
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 7 ++
2 files changed, 142 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-peripherals-opp.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-peripherals-opp.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..bf2527d737932a1f41aa83d61f44d87ba52b0519
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra210-peripherals-opp.dtsi
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+ /* EMC DVFS OPP table */
+ emc_icc_dvfs_opp_table: opp-table-dvfs0 {
+ compatible = "operating-points-v2";
+
+ opp-40800000-800 {
+ opp-microvolt = <800000 800000 1150000>;
+ opp-hz = /bits/ 64 <40800000>;
+ opp-supported-hw = <0x0003>;
+ };
+
+ opp-68000000-800 {
+ opp-microvolt = <800000 800000 1150000>;
+ opp-hz = /bits/ 64 <68000000>;
+ opp-supported-hw = <0x0003>;
+ };
+
+ opp-102000000-800 {
+ opp-microvolt = <800000 800000 1150000>;
+ opp-hz = /bits/ 64 <102000000>;
+ opp-supported-hw = <0x0003>;
+ };
+
+ opp-204000000-800 {
+ opp-microvolt = <800000 800000 1150000>;
+ opp-hz = /bits/ 64 <204000000>;
+ opp-supported-hw = <0x0007>;
+ opp-suspend;
+ };
+
+ opp-408000000-812 {
+ opp-microvolt = <812000 812000 1150000>;
+ opp-hz = /bits/ 64 <408000000>;
+ opp-supported-hw = <0x0003>;
+ };
+
+ opp-665600000-825 {
+ opp-microvolt = <825000 825000 1150000>;
+ opp-hz = /bits/ 64 <665600000>;
+ opp-supported-hw = <0x0003>;
+ };
+
+ opp-800000000-825 {
+ opp-microvolt = <825000 825000 1150000>;
+ opp-hz = /bits/ 64 <800000000>;
+ opp-supported-hw = <0x0003>;
+ };
+
+ opp-1065600000-837 {
+ opp-microvolt = <837000 837000 1150000>;
+ opp-hz = /bits/ 64 <1065600000>;
+ opp-supported-hw = <0x0003>;
+ };
+
+ opp-1331200000-850 {
+ opp-microvolt = <850000 850000 1150000>;
+ opp-hz = /bits/ 64 <1331200000>;
+ opp-supported-hw = <0x0003>;
+ };
+
+ opp-1600000000-887 {
+ opp-microvolt = <887000 887000 1150000>;
+ opp-hz = /bits/ 64 <1600000000>;
+ opp-supported-hw = <0x0007>;
+ };
+ };
+
+ /* EMC bandwidth OPP table */
+ emc_bw_dfs_opp_table: opp-table-dvfs1 {
+ compatible = "operating-points-v2";
+
+ opp-40800000 {
+ opp-hz = /bits/ 64 <40800000>;
+ opp-supported-hw = <0x0003>;
+ opp-peak-kBps = <652800>;
+ };
+
+ opp-68000000 {
+ opp-hz = /bits/ 64 <68000000>;
+ opp-supported-hw = <0x0003>;
+ opp-peak-kBps = <1088000>;
+ };
+
+ opp-102000000 {
+ opp-hz = /bits/ 64 <102000000>;
+ opp-supported-hw = <0x0003>;
+ opp-peak-kBps = <1632000>;
+ };
+
+ opp-204000000 {
+ opp-hz = /bits/ 64 <204000000>;
+ opp-supported-hw = <0x0007>;
+ opp-peak-kBps = <3264000>;
+ opp-suspend;
+ };
+
+ opp-408000000 {
+ opp-hz = /bits/ 64 <408000000>;
+ opp-supported-hw = <0x0003>;
+ opp-peak-kBps = <6528000>;
+ };
+
+ opp-665600000 {
+ opp-hz = /bits/ 64 <665600000>;
+ opp-supported-hw = <0x0003>;
+ opp-peak-kBps = <10649600>;
+ };
+
+ opp-800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-supported-hw = <0x001F>;
+ opp-peak-kBps = <12800000>;
+ };
+
+ opp-1065600000 {
+ opp-hz = /bits/ 64 <1065600000>;
+ opp-supported-hw = <0x0003>;
+ opp-peak-kBps = <17049600>;
+ };
+
+ opp-1331200000 {
+ opp-hz = /bits/ 64 <1331200000>;
+ opp-supported-hw = <0x0003>;
+ opp-peak-kBps = <21299200>;
+ };
+
+ opp-1600000000 {
+ opp-hz = /bits/ 64 <1600000000>;
+ opp-supported-hw = <0x0007>;
+ opp-peak-kBps = <25600000>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 2fcc7a28690f7100d49e8b93c4fb77de7947b002..f2961c9e12db1cf91254b75389779955f2a0956d 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -9,6 +9,8 @@
#include <dt-bindings/thermal/tegra124-soctherm.h>
#include <dt-bindings/soc/tegra-pmc.h>
+#include "tegra210-peripherals-opp.dtsi"
+
/ {
compatible = "nvidia,tegra210";
interrupt-parent = <&lic>;
@@ -516,6 +518,9 @@ actmon@6000c800 {
clock-names = "actmon", "emc";
resets = <&tegra_car 119>;
reset-names = "actmon";
+ operating-points-v2 = <&emc_bw_dfs_opp_table>;
+ interconnects = <&mc TEGRA210_MC_MPCORER &emc>;
+ interconnect-names = "cpu-read";
#cooling-cells = <2>;
};
@@ -1024,6 +1029,8 @@ emc: external-memory-controller@7001b000 {
clock-names = "emc";
interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
nvidia,memory-controller = <&mc>;
+ operating-points-v2 = <&emc_icc_dvfs_opp_table>;
+
#interconnect-cells = <0>;
#cooling-cells = <2>;
};
--
2.50.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling
2025-09-03 19:50 [PATCH v2 0/8] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay
` (7 preceding siblings ...)
2025-09-03 19:50 ` [PATCH v2 8/8] arm64: tegra: Add OPP tables on Tegra210 Aaron Kling via B4 Relay
@ 2025-09-04 8:08 ` Krzysztof Kozlowski
8 siblings, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2025-09-04 8:08 UTC (permalink / raw)
To: Aaron Kling
Cc: Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter,
Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi,
Dmitry Osipenko, linux-kernel, devicetree, linux-tegra, linux-pm
On Wed, Sep 03, 2025 at 02:50:06PM -0500, Aaron Kling wrote:
> This series adds interconnect support to tegra210 MC and EMC, then
> enables actmon. This enables dynamic emc scaling.
>
> Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
I asked for explaining the dependencies and merging. I don't see
improvements here.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread