* [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling
@ 2025-09-06 20:16 Aaron Kling via B4 Relay
2025-09-06 20:16 ` [PATCH v3 1/9] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210 Aaron Kling via B4 Relay
` (8 more replies)
0 siblings, 9 replies; 17+ messages in thread
From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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,
Chanwoo Choi, Krzysztof Kozlowski
This series adds interconnect support to tegra210 MC and EMC, then
enables actmon. This enables dynamic emc scaling.
There are no cross-subsystem hard dependencies, only logical relations.
The subsystems can be merged in any order.
Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
---
Changes in v3:
- In patch 5, don't fail mc probe if opp tables are missing
- Add more mc bindings to patch 1
- Add patch to use tegra210-mc bindings in the mc driver
- Re-order series to align patches within a subsystem to each other
- Link to v2: https://lore.kernel.org/r/20250903-t210-actmon-v2-0-e0d534d4f8ea@gmail.com
Changes in v2:
- Assume 64-bit dram bus width in patch 4
- Add dt-bindings patch to document the new properties on the
tegra210-emc node.
- Link to v1: https://lore.kernel.org/r/20250828-t210-actmon-v1-0-aeb19ec1f244@gmail.com
---
Aaron Kling (9):
dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210
dt-bindings: memory: tegra210: emc: Document OPP table and interconnect
dt-bindings: memory: tegra210: Add memory client IDs
memory: tegra210: Use bindings for client ids
memory: tegra210: Support interconnect framework
soc: tegra: fuse: speedo-tegra210: Add soc speedo 2
arm64: tegra: tegra210: Add actmon
arm64: tegra: Add interconnect properties to Tegra210 device-tree
arm64: tegra: Add OPP tables on Tegra210
.../bindings/devfreq/nvidia,tegra30-actmon.yaml | 13 +-
.../memory-controllers/nvidia,tegra210-emc.yaml | 11 +
.../boot/dts/nvidia/tegra210-peripherals-opp.dtsi | 135 ++++++++++
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 43 ++++
drivers/memory/tegra/Kconfig | 1 +
drivers/memory/tegra/tegra210-emc-core.c | 272 ++++++++++++++++++++-
drivers/memory/tegra/tegra210-emc.h | 23 ++
drivers/memory/tegra/tegra210.c | 227 +++++++++++------
drivers/soc/tegra/fuse/speedo-tegra210.c | 1 +
include/dt-bindings/memory/tegra210-mc.h | 74 ++++++
10 files changed, 720 insertions(+), 80 deletions(-)
---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250822-t210-actmon-34904ce7ed0c
prerequisite-change-id: 20250812-tegra210-speedo-470691e8b8cc:v3
prerequisite-patch-id: f693f138b5d40cdc45d9066ce48cbcff782253f8
Best regards,
--
Aaron Kling <webgeek1234@gmail.com>
^ permalink raw reply [flat|nested] 17+ messages in thread* [PATCH v3 1/9] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay @ 2025-09-06 20:16 ` Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 2/9] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect Aaron Kling via B4 Relay ` (7 subsequent siblings) 8 siblings, 0 replies; 17+ messages in thread From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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, Chanwoo Choi, Krzysztof Kozlowski From: Aaron Kling <webgeek1234@gmail.com> The Tegra210 actmon is compatible with the existing Tegra124 driver. Describe the compatibles as such. Acked-by: Chanwoo Choi <cw00c.choi@samsung.com> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> 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] 17+ messages in thread
* [PATCH v3 2/9] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 1/9] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210 Aaron Kling via B4 Relay @ 2025-09-06 20:16 ` Aaron Kling via B4 Relay 2025-09-10 9:41 ` (subset) " Krzysztof Kozlowski 2025-09-06 20:16 ` [PATCH v3 3/9] dt-bindings: memory: tegra210: Add memory client IDs Aaron Kling via B4 Relay ` (6 subsequent siblings) 8 siblings, 1 reply; 17+ messages in thread From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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 | 11 +++++++++++ 1 file changed, 11 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..4e4fb4acd7f9d376379a19b5f8e0256baaed5697 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,6 +47,11 @@ 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 @@ -79,4 +87,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] 17+ messages in thread
* Re: (subset) [PATCH v3 2/9] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect 2025-09-06 20:16 ` [PATCH v3 2/9] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect Aaron Kling via B4 Relay @ 2025-09-10 9:41 ` Krzysztof Kozlowski 0 siblings, 0 replies; 17+ messages in thread From: Krzysztof Kozlowski @ 2025-09-10 9:41 UTC (permalink / raw) To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Dmitry Osipenko, Aaron Kling Cc: linux-kernel, devicetree, linux-tegra, linux-pm On Sat, 06 Sep 2025 15:16:52 -0500, Aaron Kling wrote: > These are needed for dynamic frequency scaling of the EMC controller. > > Applied, thanks! [2/9] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect https://git.kernel.org/krzk/linux-mem-ctrl/c/550faad18505aac40a1551a5b467e0a63bf2d639 Best regards, -- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 3/9] dt-bindings: memory: tegra210: Add memory client IDs 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 1/9] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210 Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 2/9] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect Aaron Kling via B4 Relay @ 2025-09-06 20:16 ` Aaron Kling via B4 Relay 2025-09-10 9:41 ` (subset) " Krzysztof Kozlowski 2025-09-06 20:16 ` [PATCH v3 4/9] memory: tegra210: Use bindings for client ids Aaron Kling via B4 Relay ` (5 subsequent siblings) 8 siblings, 1 reply; 17+ messages in thread From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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 | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/include/dt-bindings/memory/tegra210-mc.h b/include/dt-bindings/memory/tegra210-mc.h index 5e082547f1794cba1f72872782e04d8747863b6d..881bf78aa8b2636bb71954968b0251145d72fecd 100644 --- a/include/dt-bindings/memory/tegra210-mc.h +++ b/include/dt-bindings/memory/tegra210-mc.h @@ -75,4 +75,78 @@ #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 +#define TEGRA210_MC_NVDECSRD 120 +#define TEGRA210_MC_NVDECSWR 121 +#define TEGRA210_MC_APER 122 +#define TEGRA210_MC_APEW 123 +#define TEGRA210_MC_NVJPGRD 126 +#define TEGRA210_MC_NVJPGWR 127 +#define TEGRA210_MC_SESRD 128 +#define TEGRA210_MC_SESWR 129 +#define TEGRA210_MC_AXIAPR 130 +#define TEGRA210_MC_AXIAPW 131 +#define TEGRA210_MC_ETRR 132 +#define TEGRA210_MC_ETRW 133 +#define TEGRA210_MC_TSECSRDB 134 +#define TEGRA210_MC_TSECSWRB 135 +#define TEGRA210_MC_GPUSRD2 136 +#define TEGRA210_MC_GPUSWR2 137 + #endif -- 2.50.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: (subset) [PATCH v3 3/9] dt-bindings: memory: tegra210: Add memory client IDs 2025-09-06 20:16 ` [PATCH v3 3/9] dt-bindings: memory: tegra210: Add memory client IDs Aaron Kling via B4 Relay @ 2025-09-10 9:41 ` Krzysztof Kozlowski 0 siblings, 0 replies; 17+ messages in thread From: Krzysztof Kozlowski @ 2025-09-10 9:41 UTC (permalink / raw) To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Dmitry Osipenko, Aaron Kling Cc: linux-kernel, devicetree, linux-tegra, linux-pm On Sat, 06 Sep 2025 15:16:53 -0500, Aaron Kling wrote: > Each memory client has unique hardware ID, add these IDs. > > Applied, thanks! [3/9] dt-bindings: memory: tegra210: Add memory client IDs https://git.kernel.org/krzk/linux-mem-ctrl/c/5f5598d945e2a69f764aa5c2074dad73e23bcfcb Best regards, -- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 4/9] memory: tegra210: Use bindings for client ids 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay ` (2 preceding siblings ...) 2025-09-06 20:16 ` [PATCH v3 3/9] dt-bindings: memory: tegra210: Add memory client IDs Aaron Kling via B4 Relay @ 2025-09-06 20:16 ` Aaron Kling via B4 Relay 2025-09-10 9:41 ` (subset) " Krzysztof Kozlowski 2025-09-06 20:16 ` [PATCH v3 5/9] memory: tegra210: Support interconnect framework Aaron Kling via B4 Relay ` (4 subsequent siblings) 8 siblings, 1 reply; 17+ messages in thread From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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> Since the related binding is being added, use that for the client ids instead of hardcoded magic numbers. Signed-off-by: Aaron Kling <webgeek1234@gmail.com> --- drivers/memory/tegra/tegra210.c | 146 ++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c index 8ab6498dbe7d2f410d4eb262926c18b77edb0b3d..cfa61dd885577a8fbd79c396a1316101197ca1f2 100644 --- a/drivers/memory/tegra/tegra210.c +++ b/drivers/memory/tegra/tegra210.c @@ -9,11 +9,11 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { { - .id = 0x00, + .id = TEGRA210_MC_PTCR, .name = "ptcr", .swgroup = TEGRA_SWGROUP_PTC, }, { - .id = 0x01, + .id = TEGRA210_MC_DISPLAY0A, .name = "display0a", .swgroup = TEGRA_SWGROUP_DC, .regs = { @@ -29,7 +29,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x02, + .id = TEGRA210_MC_DISPLAY0AB, .name = "display0ab", .swgroup = TEGRA_SWGROUP_DCB, .regs = { @@ -45,7 +45,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x03, + .id = TEGRA210_MC_DISPLAY0B, .name = "display0b", .swgroup = TEGRA_SWGROUP_DC, .regs = { @@ -61,7 +61,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x04, + .id = TEGRA210_MC_DISPLAY0BB, .name = "display0bb", .swgroup = TEGRA_SWGROUP_DCB, .regs = { @@ -77,7 +77,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x05, + .id = TEGRA210_MC_DISPLAY0C, .name = "display0c", .swgroup = TEGRA_SWGROUP_DC, .regs = { @@ -93,7 +93,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x06, + .id = TEGRA210_MC_DISPLAY0CB, .name = "display0cb", .swgroup = TEGRA_SWGROUP_DCB, .regs = { @@ -109,7 +109,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x0e, + .id = TEGRA210_MC_AFIR, .name = "afir", .swgroup = TEGRA_SWGROUP_AFI, .regs = { @@ -125,7 +125,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x0f, + .id = TEGRA210_MC_AVPCARM7R, .name = "avpcarm7r", .swgroup = TEGRA_SWGROUP_AVPC, .regs = { @@ -141,7 +141,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x10, + .id = TEGRA210_MC_DISPLAYHC, .name = "displayhc", .swgroup = TEGRA_SWGROUP_DC, .regs = { @@ -157,7 +157,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x11, + .id = TEGRA210_MC_DISPLAYHCB, .name = "displayhcb", .swgroup = TEGRA_SWGROUP_DCB, .regs = { @@ -173,7 +173,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x15, + .id = TEGRA210_MC_HDAR, .name = "hdar", .swgroup = TEGRA_SWGROUP_HDA, .regs = { @@ -189,7 +189,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x16, + .id = TEGRA210_MC_HOST1XDMAR, .name = "host1xdmar", .swgroup = TEGRA_SWGROUP_HC, .regs = { @@ -205,7 +205,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x17, + .id = TEGRA210_MC_HOST1XR, .name = "host1xr", .swgroup = TEGRA_SWGROUP_HC, .regs = { @@ -221,7 +221,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x1c, + .id = TEGRA210_MC_NVENCSRD, .name = "nvencsrd", .swgroup = TEGRA_SWGROUP_NVENC, .regs = { @@ -237,7 +237,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x1d, + .id = TEGRA210_MC_PPCSAHBDMAR, .name = "ppcsahbdmar", .swgroup = TEGRA_SWGROUP_PPCS, .regs = { @@ -253,7 +253,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x1e, + .id = TEGRA210_MC_PPCSAHBSLVR, .name = "ppcsahbslvr", .swgroup = TEGRA_SWGROUP_PPCS, .regs = { @@ -269,7 +269,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x1f, + .id = TEGRA210_MC_SATAR, .name = "satar", .swgroup = TEGRA_SWGROUP_SATA, .regs = { @@ -285,7 +285,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x27, + .id = TEGRA210_MC_MPCORER, .name = "mpcorer", .swgroup = TEGRA_SWGROUP_MPCORE, .regs = { @@ -297,7 +297,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x2b, + .id = TEGRA210_MC_NVENCSWR, .name = "nvencswr", .swgroup = TEGRA_SWGROUP_NVENC, .regs = { @@ -313,7 +313,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x31, + .id = TEGRA210_MC_AFIW, .name = "afiw", .swgroup = TEGRA_SWGROUP_AFI, .regs = { @@ -329,7 +329,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x32, + .id = TEGRA210_MC_AVPCARM7W, .name = "avpcarm7w", .swgroup = TEGRA_SWGROUP_AVPC, .regs = { @@ -345,7 +345,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x35, + .id = TEGRA210_MC_HDAW, .name = "hdaw", .swgroup = TEGRA_SWGROUP_HDA, .regs = { @@ -361,7 +361,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x36, + .id = TEGRA210_MC_HOST1XW, .name = "host1xw", .swgroup = TEGRA_SWGROUP_HC, .regs = { @@ -377,7 +377,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x39, + .id = TEGRA210_MC_MPCOREW, .name = "mpcorew", .swgroup = TEGRA_SWGROUP_MPCORE, .regs = { @@ -389,7 +389,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x3b, + .id = TEGRA210_MC_PPCSAHBDMAW, .name = "ppcsahbdmaw", .swgroup = TEGRA_SWGROUP_PPCS, .regs = { @@ -405,7 +405,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x3c, + .id = TEGRA210_MC_PPCSAHBSLVW, .name = "ppcsahbslvw", .swgroup = TEGRA_SWGROUP_PPCS, .regs = { @@ -421,7 +421,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x3d, + .id = TEGRA210_MC_SATAW, .name = "sataw", .swgroup = TEGRA_SWGROUP_SATA, .regs = { @@ -437,7 +437,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x44, + .id = TEGRA210_MC_ISPRA, .name = "ispra", .swgroup = TEGRA_SWGROUP_ISP2, .regs = { @@ -453,7 +453,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x46, + .id = TEGRA210_MC_ISPWA, .name = "ispwa", .swgroup = TEGRA_SWGROUP_ISP2, .regs = { @@ -469,7 +469,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x47, + .id = TEGRA210_MC_ISPWB, .name = "ispwb", .swgroup = TEGRA_SWGROUP_ISP2, .regs = { @@ -485,7 +485,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x4a, + .id = TEGRA210_MC_XUSB_HOSTR, .name = "xusb_hostr", .swgroup = TEGRA_SWGROUP_XUSB_HOST, .regs = { @@ -501,7 +501,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x4b, + .id = TEGRA210_MC_XUSB_HOSTW, .name = "xusb_hostw", .swgroup = TEGRA_SWGROUP_XUSB_HOST, .regs = { @@ -517,7 +517,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x4c, + .id = TEGRA210_MC_XUSB_DEVR, .name = "xusb_devr", .swgroup = TEGRA_SWGROUP_XUSB_DEV, .regs = { @@ -533,7 +533,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x4d, + .id = TEGRA210_MC_XUSB_DEVW, .name = "xusb_devw", .swgroup = TEGRA_SWGROUP_XUSB_DEV, .regs = { @@ -549,7 +549,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x4e, + .id = TEGRA210_MC_ISPRAB, .name = "isprab", .swgroup = TEGRA_SWGROUP_ISP2B, .regs = { @@ -565,7 +565,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x50, + .id = TEGRA210_MC_ISPWAB, .name = "ispwab", .swgroup = TEGRA_SWGROUP_ISP2B, .regs = { @@ -581,7 +581,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x51, + .id = TEGRA210_MC_ISPWBB, .name = "ispwbb", .swgroup = TEGRA_SWGROUP_ISP2B, .regs = { @@ -597,7 +597,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x54, + .id = TEGRA210_MC_TSECSRD, .name = "tsecsrd", .swgroup = TEGRA_SWGROUP_TSEC, .regs = { @@ -613,7 +613,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x55, + .id = TEGRA210_MC_TSECSWR, .name = "tsecswr", .swgroup = TEGRA_SWGROUP_TSEC, .regs = { @@ -629,7 +629,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x56, + .id = TEGRA210_MC_A9AVPSCR, .name = "a9avpscr", .swgroup = TEGRA_SWGROUP_A9AVP, .regs = { @@ -645,7 +645,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x57, + .id = TEGRA210_MC_A9AVPSCW, .name = "a9avpscw", .swgroup = TEGRA_SWGROUP_A9AVP, .regs = { @@ -661,7 +661,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x58, + .id = TEGRA210_MC_GPUSRD, .name = "gpusrd", .swgroup = TEGRA_SWGROUP_GPU, .regs = { @@ -678,7 +678,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x59, + .id = TEGRA210_MC_GPUSWR, .name = "gpuswr", .swgroup = TEGRA_SWGROUP_GPU, .regs = { @@ -695,7 +695,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x5a, + .id = TEGRA210_MC_DISPLAYT, .name = "displayt", .swgroup = TEGRA_SWGROUP_DC, .regs = { @@ -711,7 +711,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x60, + .id = TEGRA210_MC_SDMMCRA, .name = "sdmmcra", .swgroup = TEGRA_SWGROUP_SDMMC1A, .regs = { @@ -727,7 +727,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x61, + .id = TEGRA210_MC_SDMMCRAA, .name = "sdmmcraa", .swgroup = TEGRA_SWGROUP_SDMMC2A, .regs = { @@ -743,7 +743,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x62, + .id = TEGRA210_MC_SDMMCR, .name = "sdmmcr", .swgroup = TEGRA_SWGROUP_SDMMC3A, .regs = { @@ -759,7 +759,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x63, + .id = TEGRA210_MC_SDMMCRAB, .swgroup = TEGRA_SWGROUP_SDMMC4A, .name = "sdmmcrab", .regs = { @@ -775,7 +775,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x64, + .id = TEGRA210_MC_SDMMCWA, .name = "sdmmcwa", .swgroup = TEGRA_SWGROUP_SDMMC1A, .regs = { @@ -791,7 +791,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x65, + .id = TEGRA210_MC_SDMMCWAA, .name = "sdmmcwaa", .swgroup = TEGRA_SWGROUP_SDMMC2A, .regs = { @@ -807,7 +807,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x66, + .id = TEGRA210_MC_SDMMCW, .name = "sdmmcw", .swgroup = TEGRA_SWGROUP_SDMMC3A, .regs = { @@ -823,7 +823,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x67, + .id = TEGRA210_MC_SDMMCWAB, .name = "sdmmcwab", .swgroup = TEGRA_SWGROUP_SDMMC4A, .regs = { @@ -839,7 +839,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x6c, + .id = TEGRA210_MC_VICSRD, .name = "vicsrd", .swgroup = TEGRA_SWGROUP_VIC, .regs = { @@ -855,7 +855,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x6d, + .id = TEGRA210_MC_VICSWR, .name = "vicswr", .swgroup = TEGRA_SWGROUP_VIC, .regs = { @@ -871,7 +871,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x72, + .id = TEGRA210_MC_VIW, .name = "viw", .swgroup = TEGRA_SWGROUP_VI, .regs = { @@ -887,7 +887,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x73, + .id = TEGRA210_MC_DISPLAYD, .name = "displayd", .swgroup = TEGRA_SWGROUP_DC, .regs = { @@ -903,7 +903,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x78, + .id = TEGRA210_MC_NVDECSRD, .name = "nvdecsrd", .swgroup = TEGRA_SWGROUP_NVDEC, .regs = { @@ -919,7 +919,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x79, + .id = TEGRA210_MC_NVDECSWR, .name = "nvdecswr", .swgroup = TEGRA_SWGROUP_NVDEC, .regs = { @@ -935,7 +935,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x7a, + .id = TEGRA210_MC_APER, .name = "aper", .swgroup = TEGRA_SWGROUP_APE, .regs = { @@ -951,7 +951,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x7b, + .id = TEGRA210_MC_APEW, .name = "apew", .swgroup = TEGRA_SWGROUP_APE, .regs = { @@ -967,7 +967,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x7e, + .id = TEGRA210_MC_NVJPGRD, .name = "nvjpgsrd", .swgroup = TEGRA_SWGROUP_NVJPG, .regs = { @@ -983,7 +983,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x7f, + .id = TEGRA210_MC_NVJPGWR, .name = "nvjpgswr", .swgroup = TEGRA_SWGROUP_NVJPG, .regs = { @@ -999,7 +999,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x80, + .id = TEGRA210_MC_SESRD, .name = "sesrd", .swgroup = TEGRA_SWGROUP_SE, .regs = { @@ -1015,7 +1015,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x81, + .id = TEGRA210_MC_SESRD, .name = "seswr", .swgroup = TEGRA_SWGROUP_SE, .regs = { @@ -1031,7 +1031,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x82, + .id = TEGRA210_MC_AXIAPR, .name = "axiapr", .swgroup = TEGRA_SWGROUP_AXIAP, .regs = { @@ -1047,7 +1047,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x83, + .id = TEGRA210_MC_AXIAPW, .name = "axiapw", .swgroup = TEGRA_SWGROUP_AXIAP, .regs = { @@ -1063,7 +1063,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x84, + .id = TEGRA210_MC_ETRR, .name = "etrr", .swgroup = TEGRA_SWGROUP_ETR, .regs = { @@ -1079,7 +1079,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x85, + .id = TEGRA210_MC_ETRR, .name = "etrw", .swgroup = TEGRA_SWGROUP_ETR, .regs = { @@ -1095,7 +1095,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x86, + .id = TEGRA210_MC_TSECSRDB, .name = "tsecsrdb", .swgroup = TEGRA_SWGROUP_TSECB, .regs = { @@ -1111,7 +1111,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x87, + .id = TEGRA210_MC_TSECSWRB, .name = "tsecswrb", .swgroup = TEGRA_SWGROUP_TSECB, .regs = { @@ -1127,7 +1127,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x88, + .id = TEGRA210_MC_GPUSRD2, .name = "gpusrd2", .swgroup = TEGRA_SWGROUP_GPU, .regs = { @@ -1144,7 +1144,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = { }, }, }, { - .id = 0x89, + .id = TEGRA210_MC_GPUSWR2, .name = "gpuswr2", .swgroup = TEGRA_SWGROUP_GPU, .regs = { -- 2.50.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: (subset) [PATCH v3 4/9] memory: tegra210: Use bindings for client ids 2025-09-06 20:16 ` [PATCH v3 4/9] memory: tegra210: Use bindings for client ids Aaron Kling via B4 Relay @ 2025-09-10 9:41 ` Krzysztof Kozlowski 0 siblings, 0 replies; 17+ messages in thread From: Krzysztof Kozlowski @ 2025-09-10 9:41 UTC (permalink / raw) To: Krzysztof Kozlowski, Rob Herring, Conor Dooley, Thierry Reding, Jonathan Hunter, Krzysztof Kozlowski, MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Dmitry Osipenko, Aaron Kling Cc: linux-kernel, devicetree, linux-tegra, linux-pm On Sat, 06 Sep 2025 15:16:54 -0500, Aaron Kling wrote: > Since the related binding is being added, use that for the client ids > instead of hardcoded magic numbers. > > Applied, thanks! [4/9] memory: tegra210: Use bindings for client ids https://git.kernel.org/krzk/linux-mem-ctrl/c/3804cef4c59742cf695e7b41a9aabe8d5bb25ca2 Best regards, -- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/9] memory: tegra210: Support interconnect framework 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay ` (3 preceding siblings ...) 2025-09-06 20:16 ` [PATCH v3 4/9] memory: tegra210: Use bindings for client ids Aaron Kling via B4 Relay @ 2025-09-06 20:16 ` Aaron Kling via B4 Relay 2025-09-10 9:39 ` Krzysztof Kozlowski 2025-09-06 20:16 ` [PATCH v3 6/9] soc: tegra: fuse: speedo-tegra210: Add soc speedo 2 Aaron Kling via B4 Relay ` (3 subsequent siblings) 8 siblings, 1 reply; 17+ messages in thread From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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 | 272 ++++++++++++++++++++++++++++++- drivers/memory/tegra/tegra210-emc.h | 23 +++ drivers/memory/tegra/tegra210.c | 81 +++++++++ 4 files changed, 375 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..8991592794c888f75b9e7d2e59d911e364ffba92 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> @@ -87,6 +88,13 @@ #define LPDDR2_MR4_SRR GENMASK(2, 0) +/* + * 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. + */ +#define DRAM_DATA_BUS_WIDTH_BYTES (64 / 8) +#define DDR 2 + static const struct tegra210_emc_sequence *tegra210_emc_sequences[] = { &tegra210_emc_r21021, }; @@ -1569,6 +1577,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 +1722,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 +1752,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 +1839,185 @@ 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); + int err; + + /* + * 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_warn(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; @@ -1966,6 +2226,13 @@ static int tegra210_emc_probe(struct platform_device *pdev) tegra210_emc_debugfs_init(emc); + err = tegra_emc_opp_table_init(emc); + if (!err) { + tegra_emc_rate_requests_init(emc); + tegra_emc_interconnect_init(emc); + } else if (err != -ENODEV) + return err; + cd = devm_thermal_of_cooling_device_register(emc->dev, np, "emc", emc, &tegra210_emc_cd_ops); if (IS_ERR(cd)) { @@ -2050,6 +2317,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 cfa61dd885577a8fbd79c396a1316101197ca1f2..20828a07d2d0cafa739b534c20c12f065b276669 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] 17+ messages in thread
* Re: [PATCH v3 5/9] memory: tegra210: Support interconnect framework 2025-09-06 20:16 ` [PATCH v3 5/9] memory: tegra210: Support interconnect framework Aaron Kling via B4 Relay @ 2025-09-10 9:39 ` Krzysztof Kozlowski 2025-09-10 10:06 ` Krzysztof Kozlowski 0 siblings, 1 reply; 17+ messages in thread From: Krzysztof Kozlowski @ 2025-09-10 9:39 UTC (permalink / raw) To: webgeek1234, 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 On 06/09/2025 22:16, Aaron Kling via B4 Relay wrote: > + > +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; return dev_err_probe > + } > + > + 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); Write descriptive error messages or skip it. It's printing errors also on ENOMEM. I will send a patch to fix existing code. > + > + 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; return dev_err_probe > + } > + opp_token = err; > + > + err = dev_pm_opp_of_add_table(emc->dev); > + if (err) { > + if (err == -ENODEV) > + dev_warn(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; > +} > + ... > diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c > index cfa61dd885577a8fbd79c396a1316101197ca1f2..20828a07d2d0cafa739b534c20c12f065b276669 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); This feels like more reasonable use of deferred probe, but I wonder how is this condition possible. This xlate is called at earliest after MC ICC is registered. At this tage all nodes are created, so previous list_for_each_entry() should succeed and return. If previous list_for_each_entry() did not return, how can you find a matching client for which the node will be added later, thus deferred probe? This is again existing code, of course :) Best regards, Krzysztof ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 5/9] memory: tegra210: Support interconnect framework 2025-09-10 9:39 ` Krzysztof Kozlowski @ 2025-09-10 10:06 ` Krzysztof Kozlowski 2025-09-15 6:08 ` Aaron Kling 0 siblings, 1 reply; 17+ messages in thread From: Krzysztof Kozlowski @ 2025-09-10 10:06 UTC (permalink / raw) To: webgeek1234, 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 On 10/09/2025 11:39, Krzysztof Kozlowski wrote: > On 06/09/2025 22:16, Aaron Kling via B4 Relay wrote: >> + >> +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; > > return dev_err_probe I will send patches to fix existing code. I also found some more issues which I would like to implement here. I apologize for coming with all this at v3. I should point out things a bit earlier, although how this patchset was organized also affected review. Anyway my comments are mostly non-critical things, so v3 is late to bring these, I understand. That's on me. I appreciate your work and please do not get discouraged with my comments. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 5/9] memory: tegra210: Support interconnect framework 2025-09-10 10:06 ` Krzysztof Kozlowski @ 2025-09-15 6:08 ` Aaron Kling 2025-09-15 7:24 ` Krzysztof Kozlowski 0 siblings, 1 reply; 17+ messages in thread From: Aaron Kling @ 2025-09-15 6:08 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 Wed, Sep 10, 2025 at 5:07 AM Krzysztof Kozlowski <krzk@kernel.org> wrote: > > On 10/09/2025 11:39, Krzysztof Kozlowski wrote: > > On 06/09/2025 22:16, Aaron Kling via B4 Relay wrote: > >> + > >> +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; > > > > return dev_err_probe > > > I will send patches to fix existing code. I also found some more issues > which I would like to implement here. > > I apologize for coming with all this at v3. I should point out things a > bit earlier, although how this patchset was organized also affected review. > > Anyway my comments are mostly non-critical things, so v3 is late to > bring these, I understand. That's on me. I appreciate your work and > please do not get discouraged with my comments. I understand and that's fine. Get it done right the first time so it doesn't have to be redone later. I will try to get a new revision out this week once I cycle back around to the relevant devices here. Aaron ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v3 5/9] memory: tegra210: Support interconnect framework 2025-09-15 6:08 ` Aaron Kling @ 2025-09-15 7:24 ` Krzysztof Kozlowski 0 siblings, 0 replies; 17+ messages in thread From: Krzysztof Kozlowski @ 2025-09-15 7:24 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 15/09/2025 08:08, Aaron Kling wrote: > On Wed, Sep 10, 2025 at 5:07 AM Krzysztof Kozlowski <krzk@kernel.org> wrote: >>>> + 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; >>> >>> return dev_err_probe >> >> >> I will send patches to fix existing code. I also found some more issues >> which I would like to implement here. >> >> I apologize for coming with all this at v3. I should point out things a >> bit earlier, although how this patchset was organized also affected review. >> >> Anyway my comments are mostly non-critical things, so v3 is late to >> bring these, I understand. That's on me. I appreciate your work and >> please do not get discouraged with my comments. > > I understand and that's fine. Get it done right the first time so it > doesn't have to be redone later. I will try to get a new revision out > this week once I cycle back around to the relevant devices here. > Just FYI, I closed my tree already so I will take anything after merge window earliest. Best regards, Krzysztof ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 6/9] soc: tegra: fuse: speedo-tegra210: Add soc speedo 2 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay ` (4 preceding siblings ...) 2025-09-06 20:16 ` [PATCH v3 5/9] memory: tegra210: Support interconnect framework Aaron Kling via B4 Relay @ 2025-09-06 20:16 ` Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 7/9] arm64: tegra: tegra210: Add actmon Aaron Kling via B4 Relay ` (2 subsequent siblings) 8 siblings, 0 replies; 17+ messages in thread From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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] 17+ messages in thread
* [PATCH v3 7/9] arm64: tegra: tegra210: Add actmon 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay ` (5 preceding siblings ...) 2025-09-06 20:16 ` [PATCH v3 6/9] soc: tegra: fuse: speedo-tegra210: Add soc speedo 2 Aaron Kling via B4 Relay @ 2025-09-06 20:16 ` Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 8/9] arm64: tegra: Add interconnect properties to Tegra210 device-tree Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 9/9] arm64: tegra: Add OPP tables on Tegra210 Aaron Kling via B4 Relay 8 siblings, 0 replies; 17+ messages in thread From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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] 17+ messages in thread
* [PATCH v3 8/9] arm64: tegra: Add interconnect properties to Tegra210 device-tree 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay ` (6 preceding siblings ...) 2025-09-06 20:16 ` [PATCH v3 7/9] arm64: tegra: tegra210: Add actmon Aaron Kling via B4 Relay @ 2025-09-06 20:16 ` Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 9/9] arm64: tegra: Add OPP tables on Tegra210 Aaron Kling via B4 Relay 8 siblings, 0 replies; 17+ messages in thread From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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] 17+ messages in thread
* [PATCH v3 9/9] arm64: tegra: Add OPP tables on Tegra210 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay ` (7 preceding siblings ...) 2025-09-06 20:16 ` [PATCH v3 8/9] arm64: tegra: Add interconnect properties to Tegra210 device-tree Aaron Kling via B4 Relay @ 2025-09-06 20:16 ` Aaron Kling via B4 Relay 8 siblings, 0 replies; 17+ messages in thread From: Aaron Kling via B4 Relay @ 2025-09-06 20:16 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] 17+ messages in thread
end of thread, other threads:[~2025-09-15 7:24 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-09-06 20:16 [PATCH v3 0/9] Support Tegra210 actmon for dynamic EMC scaling Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 1/9] dt-bindings: devfreq: tegra30-actmon: Add Tegra124 fallback for Tegra210 Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 2/9] dt-bindings: memory: tegra210: emc: Document OPP table and interconnect Aaron Kling via B4 Relay 2025-09-10 9:41 ` (subset) " Krzysztof Kozlowski 2025-09-06 20:16 ` [PATCH v3 3/9] dt-bindings: memory: tegra210: Add memory client IDs Aaron Kling via B4 Relay 2025-09-10 9:41 ` (subset) " Krzysztof Kozlowski 2025-09-06 20:16 ` [PATCH v3 4/9] memory: tegra210: Use bindings for client ids Aaron Kling via B4 Relay 2025-09-10 9:41 ` (subset) " Krzysztof Kozlowski 2025-09-06 20:16 ` [PATCH v3 5/9] memory: tegra210: Support interconnect framework Aaron Kling via B4 Relay 2025-09-10 9:39 ` Krzysztof Kozlowski 2025-09-10 10:06 ` Krzysztof Kozlowski 2025-09-15 6:08 ` Aaron Kling 2025-09-15 7:24 ` Krzysztof Kozlowski 2025-09-06 20:16 ` [PATCH v3 6/9] soc: tegra: fuse: speedo-tegra210: Add soc speedo 2 Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 7/9] arm64: tegra: tegra210: Add actmon Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 8/9] arm64: tegra: Add interconnect properties to Tegra210 device-tree Aaron Kling via B4 Relay 2025-09-06 20:16 ` [PATCH v3 9/9] arm64: tegra: Add OPP tables on Tegra210 Aaron Kling via B4 Relay
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).