* [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement
@ 2025-11-24 11:06 Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
` (13 more replies)
0 siblings, 14 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
This series is a combination of binding changes, driver cleanups and new
driver code to enable the interconnect on the MediaTek MT8196 SoC.
This series currently does not add any users of it (i.e., no bandwidth
requests being made in affected device drivers), as the only one I
quickly whippd up is in the UFS driver, which is undergoing some major
refactoring upstream in a different series of mine.
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
Changes in v2:
- Added missing submitter SoB (i.e. mine)
- Link to v1: https://lore.kernel.org/r/20251114-mt8196-dvfsrc-v1-0-b956d4631468@collabora.com
---
AngeloGioacchino Del Regno (8):
dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196
dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI
soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd
soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type
soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw
soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present
soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196
interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC
Nicolas Frattaroli (5):
dt-bindings: soc: mediatek: dvfsrc: Document clock
soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock
soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations
interconnect: mediatek: Don't hijack parent device
interconnect: mediatek: Aggregate bandwidth with saturating add
.../bindings/interconnect/mediatek,mt8183-emi.yaml | 1 +
.../soc/mediatek/mediatek,mt8183-dvfsrc.yaml | 7 +
drivers/interconnect/mediatek/Kconfig | 7 +
drivers/interconnect/mediatek/Makefile | 1 +
drivers/interconnect/mediatek/icc-emi.c | 9 +-
drivers/interconnect/mediatek/mt8196.c | 383 +++++++++++++++++++++
drivers/soc/mediatek/mtk-dvfsrc.c | 364 ++++++++++++++++++--
include/dt-bindings/interconnect/mediatek,mt8196.h | 48 +++
8 files changed, 785 insertions(+), 35 deletions(-)
---
base-commit: e93f8002e4d244f0642224635f457bc8b135c98b
change-id: 20251114-mt8196-dvfsrc-59fc8901774c
Best regards,
--
Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2026-01-08 9:29 ` AngeloGioacchino Del Regno
2025-11-24 11:06 ` [PATCH v2 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock Nicolas Frattaroli
` (12 subsequent siblings)
13 siblings, 1 reply; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Add a compatible for the MediaTek MT8196 Chromebook SoC's
DVFSRC hardware, introducing capability to communicate with it.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
.../devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml
index 4c96d4917967..5673d242afcb 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml
@@ -26,6 +26,7 @@ properties:
- mediatek,mt6893-dvfsrc
- mediatek,mt8183-dvfsrc
- mediatek,mt8195-dvfsrc
+ - mediatek,mt8196-dvfsrc
- items:
- const: mediatek,mt8192-dvfsrc
- const: mediatek,mt8195-dvfsrc
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI Nicolas Frattaroli
` (11 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
The DVFSRC hardware has a clock on all platforms.
Instead or proliferating the culture of omitting clock descriptions in
the clock controller drivers or marking them critical instead of
declaring these types of relationships, add this one to the binding.
Any device that wishes to use this binding should figure out their
incomplete or incorrect clock situation first before piling more
features on top.
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
.../devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml
index 5673d242afcb..d5c42f992a21 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml
@@ -35,6 +35,10 @@ properties:
maxItems: 1
description: DVFSRC common register address and length.
+ clocks:
+ items:
+ - description: Clock that drives the DVFSRC MCU
+
regulators:
type: object
$ref: /schemas/regulator/mediatek,mt6873-dvfsrc-regulator.yaml#
@@ -51,6 +55,7 @@ additionalProperties: false
examples:
- |
+ #include <dt-bindings/clock/mt8195-clk.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
@@ -58,6 +63,7 @@ examples:
system-controller@10012000 {
compatible = "mediatek,mt8195-dvfsrc";
reg = <0 0x10012000 0 0x1000>;
+ clocks = <&topckgen CLK_TOP_DVFSRC>;
regulators {
compatible = "mediatek,mt8195-dvfsrc-regulator";
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 04/13] soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd Nicolas Frattaroli
` (10 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Add a new compatible for the External Memory Interface Interconnect
found on the MediaTek MT8196 Chromebook SoC.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
.../bindings/interconnect/mediatek,mt8183-emi.yaml | 1 +
include/dt-bindings/interconnect/mediatek,mt8196.h | 48 ++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/Documentation/devicetree/bindings/interconnect/mediatek,mt8183-emi.yaml b/Documentation/devicetree/bindings/interconnect/mediatek,mt8183-emi.yaml
index 017c8478b2a7..1fb8ccb558fb 100644
--- a/Documentation/devicetree/bindings/interconnect/mediatek,mt8183-emi.yaml
+++ b/Documentation/devicetree/bindings/interconnect/mediatek,mt8183-emi.yaml
@@ -40,6 +40,7 @@ properties:
enum:
- mediatek,mt8183-emi
- mediatek,mt8195-emi
+ - mediatek,mt8196-emi
'#interconnect-cells':
const: 1
diff --git a/include/dt-bindings/interconnect/mediatek,mt8196.h b/include/dt-bindings/interconnect/mediatek,mt8196.h
new file mode 100644
index 000000000000..de700fa73223
--- /dev/null
+++ b/include/dt-bindings/interconnect/mediatek,mt8196.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2025 Collabora Ltd.
+ * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_MEDIATEK_MT8196_H
+#define __DT_BINDINGS_INTERCONNECT_MEDIATEK_MT8196_H
+
+#define SLAVE_DDR_EMI 0
+#define MASTER_MCUSYS 1
+#define MASTER_MCU_0 2
+#define MASTER_MCU_1 3
+#define MASTER_MCU_2 4
+#define MASTER_MCU_3 5
+#define MASTER_MCU_4 6
+#define MASTER_GPUSYS 7
+#define MASTER_MMSYS 8
+#define MASTER_MM_VPU 9
+#define MASTER_MM_DISP 10
+#define MASTER_MM_VDEC 11
+#define MASTER_MM_VENC 12
+#define MASTER_MM_CAM 13
+#define MASTER_MM_IMG 14
+#define MASTER_MM_MDP 15
+#define MASTER_VPUSYS 16
+#define MASTER_VPU_0 17
+#define MASTER_VPU_1 18
+#define MASTER_MDLASYS 19
+#define MASTER_MDLA_0 20
+#define MASTER_UFS 21
+#define MASTER_PCIE 22
+#define MASTER_USB 23
+#define MASTER_WIFI 24
+#define MASTER_BT 25
+#define MASTER_NETSYS 26
+#define MASTER_DBGIF 27
+#define SLAVE_HRT_DDR_EMI 28
+#define MASTER_HRT_MMSYS 29
+#define MASTER_HRT_MM_DISP 30
+#define MASTER_HRT_MM_VDEC 31
+#define MASTER_HRT_MM_VENC 32
+#define MASTER_HRT_MM_CAM 33
+#define MASTER_HRT_MM_IMG 34
+#define MASTER_HRT_MM_MDP 35
+#define MASTER_HRT_ADSP 36
+#define MASTER_HRT_DBGIF 37
+#endif
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 04/13] soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (2 preceding siblings ...)
2025-11-24 11:06 ` [PATCH v2 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 05/13] soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type Nicolas Frattaroli
` (9 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
In preparation for adding support for DVFSRC Version 4, change the
error check for the MTK_SIP_DVFSRC_START command in the probe
function to error out only if BIT(0) is set: this is still valid
for the previous DVFSRC versions, as those always set this bit in
a fail reply anyway.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/soc/mediatek/mtk-dvfsrc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index 41add5636b03..7708b07ab2d6 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -440,7 +440,7 @@ static int mtk_dvfsrc_probe(struct platform_device *pdev)
/* Everything is set up - make it run! */
arm_smccc_smc(MTK_SIP_DVFSRC_VCOREFS_CONTROL, MTK_SIP_DVFSRC_START,
0, 0, 0, 0, 0, 0, &ares);
- if (ares.a0)
+ if (ares.a0 & BIT(0))
return dev_err_probe(&pdev->dev, -EINVAL, "Cannot start DVFSRC: %lu\n", ares.a0);
return 0;
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 05/13] soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (3 preceding siblings ...)
2025-11-24 11:06 ` [PATCH v2 04/13] soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 06/13] soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw Nicolas Frattaroli
` (8 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
In preparation for adding support for DVFSRC Version 4, add a new
mtk_dvfsrc_bw_type enumeration, and propagate it from specific bw
setting callbacks to __dvfsrc_set_dram_bw_v1(), which will use it
to choose calculation multipliers and dividers in v4 callbacks.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/soc/mediatek/mtk-dvfsrc.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index 7708b07ab2d6..a684e405daf7 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -36,6 +36,13 @@
#define MTK_SIP_DVFSRC_INIT 0x0
#define MTK_SIP_DVFSRC_START 0x1
+enum mtk_dvfsrc_bw_type {
+ DVFSRC_BW_AVG,
+ DVFSRC_BW_PEAK,
+ DVFSRC_BW_HRT,
+ DVFSRC_BW_MAX,
+};
+
struct dvfsrc_bw_constraints {
u16 max_dram_nom_bw;
u16 max_dram_peak_bw;
@@ -268,7 +275,7 @@ static void dvfsrc_set_vscp_level_v2(struct mtk_dvfsrc *dvfsrc, u32 level)
}
static void __dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u32 reg,
- u16 max_bw, u16 min_bw, u64 bw)
+ int type, u16 max_bw, u16 min_bw, u64 bw)
{
u32 new_bw = (u32)div_u64(bw, 100 * 1000);
@@ -285,21 +292,21 @@ static void dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
{
u64 max_bw = dvfsrc->dvd->bw_constraints->max_dram_nom_bw;
- __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_BW, max_bw, 0, bw);
+ __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_BW, DVFSRC_BW_AVG, max_bw, 0, bw);
};
static void dvfsrc_set_dram_peak_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
{
u64 max_bw = dvfsrc->dvd->bw_constraints->max_dram_peak_bw;
- __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_PEAK_BW, max_bw, 0, bw);
+ __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_PEAK_BW, DVFSRC_BW_PEAK, max_bw, 0, bw);
}
static void dvfsrc_set_dram_hrt_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
{
u64 max_bw = dvfsrc->dvd->bw_constraints->max_dram_hrt_bw;
- __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_HRT_BW, max_bw, 0, bw);
+ __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_HRT_BW, DVFSRC_BW_HRT, max_bw, 0, bw);
}
static void dvfsrc_set_opp_level_v1(struct mtk_dvfsrc *dvfsrc, u32 level)
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 06/13] soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (4 preceding siblings ...)
2025-11-24 11:06 ` [PATCH v2 05/13] soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 07/13] soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present Nicolas Frattaroli
` (7 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
In preparation for adding support for DVFSRC Version 4, add a new
callback for calculating the dram bandwidth, assign the current
calculation algo to all of the currently supported SoCs, and use
this in __dvfsrc_set_dram_bw_v1().
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/soc/mediatek/mtk-dvfsrc.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index a684e405daf7..3cbccbb7469a 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -73,6 +73,7 @@ struct mtk_dvfsrc {
struct dvfsrc_soc_data {
const int *regs;
const struct dvfsrc_opp_desc *opps_desc;
+ u32 (*calc_dram_bw)(struct mtk_dvfsrc *dvfsrc, int type, u64 bw);
u32 (*get_target_level)(struct mtk_dvfsrc *dvfsrc);
u32 (*get_current_level)(struct mtk_dvfsrc *dvfsrc);
u32 (*get_vcore_level)(struct mtk_dvfsrc *dvfsrc);
@@ -274,10 +275,15 @@ static void dvfsrc_set_vscp_level_v2(struct mtk_dvfsrc *dvfsrc, u32 level)
dvfsrc_writel(dvfsrc, DVFSRC_VCORE, val);
}
+static u32 dvfsrc_calc_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, int type, u64 bw)
+{
+ return (u32)div_u64(bw, 100 * 1000);
+}
+
static void __dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u32 reg,
int type, u16 max_bw, u16 min_bw, u64 bw)
{
- u32 new_bw = (u32)div_u64(bw, 100 * 1000);
+ u32 new_bw = dvfsrc->dvd->calc_dram_bw(dvfsrc, type, bw);
/* If bw constraints (in mbps) are defined make sure to respect them */
if (max_bw)
@@ -519,6 +525,7 @@ static const struct dvfsrc_opp_desc dvfsrc_opp_mt8183_desc[] = {
static const struct dvfsrc_soc_data mt8183_data = {
.opps_desc = dvfsrc_opp_mt8183_desc,
.regs = dvfsrc_mt8183_regs,
+ .calc_dram_bw = dvfsrc_calc_dram_bw_v1,
.get_target_level = dvfsrc_get_target_level_v1,
.get_current_level = dvfsrc_get_current_level_v1,
.get_vcore_level = dvfsrc_get_vcore_level_v1,
@@ -549,6 +556,7 @@ static const struct dvfsrc_opp_desc dvfsrc_opp_mt8195_desc[] = {
static const struct dvfsrc_soc_data mt8195_data = {
.opps_desc = dvfsrc_opp_mt8195_desc,
.regs = dvfsrc_mt8195_regs,
+ .calc_dram_bw = dvfsrc_calc_dram_bw_v1,
.get_target_level = dvfsrc_get_target_level_v2,
.get_current_level = dvfsrc_get_current_level_v2,
.get_vcore_level = dvfsrc_get_vcore_level_v2,
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 07/13] soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (5 preceding siblings ...)
2025-11-24 11:06 ` [PATCH v2 06/13] soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 08/13] soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196 Nicolas Frattaroli
` (6 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
In preparation for adding support for DVFSRC Version 4, add a new
`has_emi_ddr` member to struct dvfsrc_soc_data: if true, write the
DRAM bandwidth both to the BW_AVG and to the newly defined EMI_BW
register, present only on DVFSRC v4.
Currently supported SoCs will not use this, as has_emi_ddr is left
out from their platform data, hence reading false.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/soc/mediatek/mtk-dvfsrc.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index 3cbccbb7469a..bf0e7b01d255 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -72,6 +72,7 @@ struct mtk_dvfsrc {
struct dvfsrc_soc_data {
const int *regs;
+ const bool has_emi_ddr;
const struct dvfsrc_opp_desc *opps_desc;
u32 (*calc_dram_bw)(struct mtk_dvfsrc *dvfsrc, int type, u64 bw);
u32 (*get_target_level)(struct mtk_dvfsrc *dvfsrc);
@@ -107,6 +108,7 @@ enum dvfsrc_regs {
DVFSRC_SW_BW,
DVFSRC_SW_PEAK_BW,
DVFSRC_SW_HRT_BW,
+ DVFSRC_SW_EMI_BW,
DVFSRC_VCORE,
DVFSRC_REGS_MAX,
};
@@ -292,6 +294,9 @@ static void __dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u32 reg,
new_bw = max(new_bw, min_bw);
dvfsrc_writel(dvfsrc, reg, new_bw);
+
+ if (type == DVFSRC_BW_AVG && dvfsrc->dvd->has_emi_ddr)
+ dvfsrc_writel(dvfsrc, DVFSRC_SW_EMI_BW, bw);
}
static void dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 08/13] soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (6 preceding siblings ...)
2025-11-24 11:06 ` [PATCH v2 07/13] soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock Nicolas Frattaroli
` (5 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Add support for the DVFSRC Version 4 by adding new functions for
vcore/dram levels (in v4, called gears instead), and for readout
of pre-programmed dvfsrc_opp entries, corresponding to each gear.
In the probe function, for v4, the curr_opps is initialized from
the get_hw_opps() function instead of platform data.
In order to make use of the new DVFSRCv4 code, also add support
for the MediaTek MT8196 SoC.
Co-developed-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/soc/mediatek/mtk-dvfsrc.c | 248 +++++++++++++++++++++++++++++++++++++-
1 file changed, 247 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index bf0e7b01d255..3a83fd4baf54 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -15,11 +15,17 @@
#include <linux/soc/mediatek/dvfsrc.h>
#include <linux/soc/mediatek/mtk_sip_svc.h>
+/* DVFSRC_BASIC_CONTROL */
+#define DVFSRC_V4_BASIC_CTRL_OPP_COUNT GENMASK(26, 20)
+
/* DVFSRC_LEVEL */
#define DVFSRC_V1_LEVEL_TARGET_LEVEL GENMASK(15, 0)
#define DVFSRC_TGT_LEVEL_IDLE 0x00
#define DVFSRC_V1_LEVEL_CURRENT_LEVEL GENMASK(31, 16)
+#define DVFSRC_V4_LEVEL_TARGET_LEVEL GENMASK(15, 8)
+#define DVFSRC_V4_LEVEL_TARGET_PRESENT BIT(16)
+
/* DVFSRC_SW_REQ, DVFSRC_SW_REQ2 */
#define DVFSRC_V1_SW_REQ2_DRAM_LEVEL GENMASK(1, 0)
#define DVFSRC_V1_SW_REQ2_VCORE_LEVEL GENMASK(3, 2)
@@ -27,9 +33,23 @@
#define DVFSRC_V2_SW_REQ_DRAM_LEVEL GENMASK(3, 0)
#define DVFSRC_V2_SW_REQ_VCORE_LEVEL GENMASK(6, 4)
+#define DVFSRC_V4_SW_REQ_EMI_LEVEL GENMASK(3, 0)
+#define DVFSRC_V4_SW_REQ_DRAM_LEVEL GENMASK(15, 12)
+
/* DVFSRC_VCORE */
#define DVFSRC_V2_VCORE_REQ_VSCP_LEVEL GENMASK(14, 12)
+/* DVFSRC_TARGET_GEAR */
+#define DVFSRC_V4_GEAR_TARGET_DRAM GENMASK(7, 0)
+#define DVFSRC_V4_GEAR_TARGET_VCORE GENMASK(15, 8)
+
+/* DVFSRC_GEAR_INFO */
+#define DVFSRC_V4_GEAR_INFO_REG_WIDTH 0x4
+#define DVFSRC_V4_GEAR_INFO_REG_LEVELS 64
+#define DVFSRC_V4_GEAR_INFO_VCORE GENMASK(3, 0)
+#define DVFSRC_V4_GEAR_INFO_EMI GENMASK(7, 4)
+#define DVFSRC_V4_GEAR_INFO_DRAM GENMASK(15, 12)
+
#define DVFSRC_POLL_TIMEOUT_US 1000
#define STARTUP_TIME_US 1
@@ -52,6 +72,7 @@ struct dvfsrc_bw_constraints {
struct dvfsrc_opp {
u32 vcore_opp;
u32 dram_opp;
+ u32 emi_opp;
};
struct dvfsrc_opp_desc {
@@ -72,6 +93,7 @@ struct mtk_dvfsrc {
struct dvfsrc_soc_data {
const int *regs;
+ const u8 *bw_units;
const bool has_emi_ddr;
const struct dvfsrc_opp_desc *opps_desc;
u32 (*calc_dram_bw)(struct mtk_dvfsrc *dvfsrc, int type, u64 bw);
@@ -79,6 +101,8 @@ struct dvfsrc_soc_data {
u32 (*get_current_level)(struct mtk_dvfsrc *dvfsrc);
u32 (*get_vcore_level)(struct mtk_dvfsrc *dvfsrc);
u32 (*get_vscp_level)(struct mtk_dvfsrc *dvfsrc);
+ u32 (*get_opp_count)(struct mtk_dvfsrc *dvfsrc);
+ int (*get_hw_opps)(struct mtk_dvfsrc *dvfsrc);
void (*set_dram_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
void (*set_dram_peak_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
void (*set_dram_hrt_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
@@ -101,6 +125,7 @@ static void dvfsrc_writel(struct mtk_dvfsrc *dvfs, u32 offset, u32 val)
}
enum dvfsrc_regs {
+ DVFSRC_BASIC_CONTROL,
DVFSRC_SW_REQ,
DVFSRC_SW_REQ2,
DVFSRC_LEVEL,
@@ -110,6 +135,9 @@ enum dvfsrc_regs {
DVFSRC_SW_HRT_BW,
DVFSRC_SW_EMI_BW,
DVFSRC_VCORE,
+ DVFSRC_TARGET_GEAR,
+ DVFSRC_GEAR_INFO_L,
+ DVFSRC_GEAR_INFO_H,
DVFSRC_REGS_MAX,
};
@@ -130,6 +158,22 @@ static const int dvfsrc_mt8195_regs[] = {
[DVFSRC_TARGET_LEVEL] = 0xd48,
};
+static const int dvfsrc_mt8196_regs[] = {
+ [DVFSRC_BASIC_CONTROL] = 0x0,
+ [DVFSRC_SW_REQ] = 0x18,
+ [DVFSRC_VCORE] = 0x80,
+ [DVFSRC_GEAR_INFO_L] = 0xfc,
+ [DVFSRC_SW_BW] = 0x1e8,
+ [DVFSRC_SW_PEAK_BW] = 0x1f4,
+ [DVFSRC_SW_HRT_BW] = 0x20c,
+ [DVFSRC_LEVEL] = 0x5f0,
+ [DVFSRC_TARGET_LEVEL] = 0x5f0,
+ [DVFSRC_SW_REQ2] = 0x604,
+ [DVFSRC_SW_EMI_BW] = 0x60c,
+ [DVFSRC_TARGET_GEAR] = 0x6ac,
+ [DVFSRC_GEAR_INFO_H] = 0x6b0,
+};
+
static const struct dvfsrc_opp *dvfsrc_get_current_opp(struct mtk_dvfsrc *dvfsrc)
{
u32 level = dvfsrc->dvd->get_current_level(dvfsrc);
@@ -137,6 +181,20 @@ static const struct dvfsrc_opp *dvfsrc_get_current_opp(struct mtk_dvfsrc *dvfsrc
return &dvfsrc->curr_opps->opps[level];
}
+static u32 dvfsrc_get_current_target_vcore_gear(struct mtk_dvfsrc *dvfsrc)
+{
+ u32 val = dvfsrc_readl(dvfsrc, DVFSRC_TARGET_GEAR);
+
+ return FIELD_GET(DVFSRC_V4_GEAR_TARGET_VCORE, val);
+}
+
+static u32 dvfsrc_get_current_target_dram_gear(struct mtk_dvfsrc *dvfsrc)
+{
+ u32 val = dvfsrc_readl(dvfsrc, DVFSRC_TARGET_GEAR);
+
+ return FIELD_GET(DVFSRC_V4_GEAR_TARGET_DRAM, val);
+}
+
static bool dvfsrc_is_idle(struct mtk_dvfsrc *dvfsrc)
{
if (!dvfsrc->dvd->get_target_level)
@@ -193,6 +251,24 @@ static int dvfsrc_wait_for_opp_level_v2(struct mtk_dvfsrc *dvfsrc, u32 level)
return 0;
}
+static int dvfsrc_wait_for_vcore_level_v4(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+ u32 val;
+
+ return readx_poll_timeout_atomic(dvfsrc_get_current_target_vcore_gear,
+ dvfsrc, val, val >= level,
+ STARTUP_TIME_US, DVFSRC_POLL_TIMEOUT_US);
+}
+
+static int dvfsrc_wait_for_opp_level_v4(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+ u32 val;
+
+ return readx_poll_timeout_atomic(dvfsrc_get_current_target_dram_gear,
+ dvfsrc, val, val >= level,
+ STARTUP_TIME_US, DVFSRC_POLL_TIMEOUT_US);
+}
+
static u32 dvfsrc_get_target_level_v1(struct mtk_dvfsrc *dvfsrc)
{
u32 val = dvfsrc_readl(dvfsrc, DVFSRC_LEVEL);
@@ -226,6 +302,27 @@ static u32 dvfsrc_get_current_level_v2(struct mtk_dvfsrc *dvfsrc)
return 0;
}
+static u32 dvfsrc_get_target_level_v4(struct mtk_dvfsrc *dvfsrc)
+{
+ u32 val = dvfsrc_readl(dvfsrc, DVFSRC_TARGET_LEVEL);
+
+ if (val & DVFSRC_V4_LEVEL_TARGET_PRESENT)
+ return FIELD_GET(DVFSRC_V4_LEVEL_TARGET_LEVEL, val) + 1;
+ return 0;
+}
+
+static u32 dvfsrc_get_current_level_v4(struct mtk_dvfsrc *dvfsrc)
+{
+ u32 level = dvfsrc_readl(dvfsrc, DVFSRC_LEVEL) + 1;
+
+ /* Valid levels */
+ if (level < dvfsrc->curr_opps->num_opp)
+ return dvfsrc->curr_opps->num_opp - level;
+
+ /* Zero for level 0 or invalid level */
+ return 0;
+}
+
static u32 dvfsrc_get_vcore_level_v1(struct mtk_dvfsrc *dvfsrc)
{
u32 val = dvfsrc_readl(dvfsrc, DVFSRC_SW_REQ2);
@@ -277,11 +374,30 @@ static void dvfsrc_set_vscp_level_v2(struct mtk_dvfsrc *dvfsrc, u32 level)
dvfsrc_writel(dvfsrc, DVFSRC_VCORE, val);
}
+static u32 dvfsrc_get_opp_count_v4(struct mtk_dvfsrc *dvfsrc)
+{
+ u32 val = dvfsrc_readl(dvfsrc, DVFSRC_BASIC_CONTROL);
+
+ return FIELD_GET(DVFSRC_V4_BASIC_CTRL_OPP_COUNT, val) + 1;
+}
+
static u32 dvfsrc_calc_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, int type, u64 bw)
{
return (u32)div_u64(bw, 100 * 1000);
}
+static u32 dvfsrc_calc_dram_bw_v4(struct mtk_dvfsrc *dvfsrc, int type, u64 bw)
+{
+ u8 bw_unit = dvfsrc->dvd->bw_units[type];
+ u64 bw_mbps;
+
+ if (type < DVFSRC_BW_AVG || type >= DVFSRC_BW_MAX)
+ return 0;
+
+ bw_mbps = div_u64(bw, 1000);
+ return (u32)div_u64((bw_mbps + bw_unit - 1), bw_unit);
+}
+
static void __dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u32 reg,
int type, u16 max_bw, u16 min_bw, u64 bw)
{
@@ -333,6 +449,100 @@ static void dvfsrc_set_opp_level_v1(struct mtk_dvfsrc *dvfsrc, u32 level)
dvfsrc_writel(dvfsrc, DVFSRC_SW_REQ, val);
}
+static u32 dvfsrc_get_opp_gear(struct mtk_dvfsrc *dvfsrc, u8 level)
+{
+ u32 reg_ofst, val;
+ u8 idx;
+
+ /* Calculate register offset and index for requested gear */
+ if (level < DVFSRC_V4_GEAR_INFO_REG_LEVELS) {
+ reg_ofst = dvfsrc->dvd->regs[DVFSRC_GEAR_INFO_L];
+ idx = level;
+ } else {
+ reg_ofst = dvfsrc->dvd->regs[DVFSRC_GEAR_INFO_H];
+ idx = level - DVFSRC_V4_GEAR_INFO_REG_LEVELS;
+ }
+ reg_ofst += DVFSRC_V4_GEAR_INFO_REG_WIDTH * (level / 2);
+
+ /* Read the corresponding gear register */
+ val = readl(dvfsrc->regs + reg_ofst);
+
+ /* Each register contains two sets of data, 16 bits per gear */
+ val >>= 16 * (idx % 2);
+
+ return val;
+}
+
+static int dvfsrc_get_hw_opps_v4(struct mtk_dvfsrc *dvfsrc)
+{
+ struct dvfsrc_opp *dvfsrc_opps;
+ struct dvfsrc_opp_desc *desc;
+ u32 num_opps, gear_info;
+ u8 num_vcore, num_dram;
+ u8 num_emi;
+ int i;
+
+ num_opps = dvfsrc_get_opp_count_v4(dvfsrc);
+ if (num_opps == 0) {
+ dev_err(dvfsrc->dev, "No OPPs programmed in DVFSRC MCU.\n");
+ return -EINVAL;
+ }
+
+ /*
+ * The first 16 bits set in the gear info table says how many OPPs
+ * and how many vcore, dram and emi table entries are available.
+ */
+ gear_info = dvfsrc_readl(dvfsrc, DVFSRC_GEAR_INFO_L);
+ if (gear_info == 0) {
+ dev_err(dvfsrc->dev, "No gear info in DVFSRC MCU.\n");
+ return -EINVAL;
+ }
+
+ num_vcore = FIELD_GET(DVFSRC_V4_GEAR_INFO_VCORE, gear_info) + 1;
+ num_dram = FIELD_GET(DVFSRC_V4_GEAR_INFO_DRAM, gear_info) + 1;
+ num_emi = FIELD_GET(DVFSRC_V4_GEAR_INFO_EMI, gear_info) + 1;
+ dev_info(dvfsrc->dev,
+ "Discovered %u gears and %u vcore, %u dram, %u emi table entries.\n",
+ num_opps, num_vcore, num_dram, num_emi);
+
+ /* Allocate everything now as anything else after that cannot fail */
+ desc = devm_kzalloc(dvfsrc->dev, sizeof(*desc), GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ dvfsrc_opps = devm_kcalloc(dvfsrc->dev, num_opps + 1,
+ sizeof(*dvfsrc_opps), GFP_KERNEL);
+ if (!dvfsrc_opps)
+ return -ENOMEM;
+
+ /* Read the OPP table gear indices */
+ for (i = 0; i <= num_opps; i++) {
+ gear_info = dvfsrc_get_opp_gear(dvfsrc, num_opps - i);
+ dvfsrc_opps[i].vcore_opp = FIELD_GET(DVFSRC_V4_GEAR_INFO_VCORE, gear_info);
+ dvfsrc_opps[i].dram_opp = FIELD_GET(DVFSRC_V4_GEAR_INFO_DRAM, gear_info);
+ dvfsrc_opps[i].emi_opp = FIELD_GET(DVFSRC_V4_GEAR_INFO_EMI, gear_info);
+ };
+ desc->num_opp = num_opps + 1;
+ desc->opps = dvfsrc_opps;
+
+ /* Assign to main structure now that everything is done! */
+ dvfsrc->curr_opps = desc;
+
+ return 0;
+}
+
+static void dvfsrc_set_dram_level_v4(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+ u32 val = dvfsrc_readl(dvfsrc, DVFSRC_SW_REQ);
+
+ val &= ~DVFSRC_V4_SW_REQ_DRAM_LEVEL;
+ val |= FIELD_PREP(DVFSRC_V4_SW_REQ_DRAM_LEVEL, level);
+
+ dev_dbg(dvfsrc->dev, "%s level=%u\n", __func__, level);
+
+ dvfsrc_writel(dvfsrc, DVFSRC_SW_REQ, val);
+}
+
int mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data)
{
struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
@@ -448,7 +658,14 @@ static int mtk_dvfsrc_probe(struct platform_device *pdev)
dvfsrc->dram_type = ares.a1;
dev_dbg(&pdev->dev, "DRAM Type: %d\n", dvfsrc->dram_type);
- dvfsrc->curr_opps = &dvfsrc->dvd->opps_desc[dvfsrc->dram_type];
+ /* Newer versions of the DVFSRC MCU have pre-programmed gear tables */
+ if (dvfsrc->dvd->get_hw_opps) {
+ ret = dvfsrc->dvd->get_hw_opps(dvfsrc);
+ if (ret)
+ return ret;
+ } else {
+ dvfsrc->curr_opps = &dvfsrc->dvd->opps_desc[dvfsrc->dram_type];
+ }
platform_set_drvdata(pdev, dvfsrc);
ret = devm_of_platform_populate(&pdev->dev);
@@ -576,10 +793,39 @@ static const struct dvfsrc_soc_data mt8195_data = {
.bw_constraints = &dvfsrc_bw_constr_v2,
};
+static const u8 mt8196_bw_units[] = {
+ [DVFSRC_BW_AVG] = 64,
+ [DVFSRC_BW_PEAK] = 64,
+ [DVFSRC_BW_HRT] = 30,
+};
+
+static const struct dvfsrc_soc_data mt8196_data = {
+ .regs = dvfsrc_mt8196_regs,
+ .bw_units = mt8196_bw_units,
+ .has_emi_ddr = true,
+ .get_target_level = dvfsrc_get_target_level_v4,
+ .get_current_level = dvfsrc_get_current_level_v4,
+ .get_vcore_level = dvfsrc_get_vcore_level_v2,
+ .get_vscp_level = dvfsrc_get_vscp_level_v2,
+ .get_opp_count = dvfsrc_get_opp_count_v4,
+ .get_hw_opps = dvfsrc_get_hw_opps_v4,
+ .calc_dram_bw = dvfsrc_calc_dram_bw_v4,
+ .set_dram_bw = dvfsrc_set_dram_bw_v1,
+ .set_dram_peak_bw = dvfsrc_set_dram_peak_bw_v1,
+ .set_dram_hrt_bw = dvfsrc_set_dram_hrt_bw_v1,
+ .set_opp_level = dvfsrc_set_dram_level_v4,
+ .set_vcore_level = dvfsrc_set_vcore_level_v2,
+ .set_vscp_level = dvfsrc_set_vscp_level_v2,
+ .wait_for_opp_level = dvfsrc_wait_for_opp_level_v4,
+ .wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v4,
+ .bw_constraints = &dvfsrc_bw_constr_v1,
+};
+
static const struct of_device_id mtk_dvfsrc_of_match[] = {
{ .compatible = "mediatek,mt6893-dvfsrc", .data = &mt6893_data },
{ .compatible = "mediatek,mt8183-dvfsrc", .data = &mt8183_data },
{ .compatible = "mediatek,mt8195-dvfsrc", .data = &mt8195_data },
+ { .compatible = "mediatek,mt8196-dvfsrc", .data = &mt8196_data },
{ /* sentinel */ }
};
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (7 preceding siblings ...)
2025-11-24 11:06 ` [PATCH v2 08/13] soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196 Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations Nicolas Frattaroli
` (4 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
The DVFSRC has a clock on all platforms.
Get and enable it in the probe function, so that Linux's common clock
framework knows we're a user of it.
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/soc/mediatek/mtk-dvfsrc.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index 3a83fd4baf54..a43d6f913914 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -7,6 +7,7 @@
#include <linux/arm-smccc.h>
#include <linux/bitfield.h>
+#include <linux/clk.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -83,6 +84,7 @@ struct dvfsrc_opp_desc {
struct dvfsrc_soc_data;
struct mtk_dvfsrc {
struct device *dev;
+ struct clk *clk;
struct platform_device *icc;
struct platform_device *regulator;
const struct dvfsrc_soc_data *dvd;
@@ -650,6 +652,11 @@ static int mtk_dvfsrc_probe(struct platform_device *pdev)
if (IS_ERR(dvfsrc->regs))
return PTR_ERR(dvfsrc->regs);
+ dvfsrc->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(dvfsrc->clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(dvfsrc->clk),
+ "Couldn't get and enable DVFSRC clock\n");
+
arm_smccc_smc(MTK_SIP_DVFSRC_VCOREFS_CONTROL, MTK_SIP_DVFSRC_INIT,
0, 0, 0, 0, 0, 0, &ares);
if (ares.a0)
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (8 preceding siblings ...)
2025-11-24 11:06 ` [PATCH v2 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock Nicolas Frattaroli
@ 2025-11-24 11:06 ` Nicolas Frattaroli
2025-11-24 11:07 ` [PATCH v2 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC Nicolas Frattaroli
` (3 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:06 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
The code, as it is, plays fast and loose with bandwidth units. It also
doesn't specify its constraints in the actual maximum hardware value,
but as some roundabout thing that then ends up multiplied into the
actual hardware value constraint after some indirections. In part, this
is due to the use of individual members for storing each limit, instead
of making it possible to index them by type.
Rework all of this by adding const array members indexed by the
bandwidth type enum to the soc_data struct. This array expresses the
actual hardware value limitations, not a factor thereof.
Use the clamp function macro to clamp the values between the minimum and
maximum constraints after all the calculations, which also means the
code doesn't write nonsense to a hardware register when the math is
wrong, as it'll constrain after all the calculations.
Pass the type as the actual enum type as well, and not as an int. If
there's some type checking that can be extracted from the function
signature, then we may as well use it.
Don't needlessly explicitly cast return values to the return type
either; this is both unnecessary and makes it harder to spot type safety
issues.
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/soc/mediatek/mtk-dvfsrc.c | 107 ++++++++++++++++++++++++--------------
1 file changed, 67 insertions(+), 40 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
index a43d6f913914..548a28f50242 100644
--- a/drivers/soc/mediatek/mtk-dvfsrc.c
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -64,12 +64,6 @@ enum mtk_dvfsrc_bw_type {
DVFSRC_BW_MAX,
};
-struct dvfsrc_bw_constraints {
- u16 max_dram_nom_bw;
- u16 max_dram_peak_bw;
- u16 max_dram_hrt_bw;
-};
-
struct dvfsrc_opp {
u32 vcore_opp;
u32 dram_opp;
@@ -98,7 +92,7 @@ struct dvfsrc_soc_data {
const u8 *bw_units;
const bool has_emi_ddr;
const struct dvfsrc_opp_desc *opps_desc;
- u32 (*calc_dram_bw)(struct mtk_dvfsrc *dvfsrc, int type, u64 bw);
+ u32 (*calc_dram_bw)(struct mtk_dvfsrc *dvfsrc, enum mtk_dvfsrc_bw_type type, u64 bw);
u32 (*get_target_level)(struct mtk_dvfsrc *dvfsrc);
u32 (*get_current_level)(struct mtk_dvfsrc *dvfsrc);
u32 (*get_vcore_level)(struct mtk_dvfsrc *dvfsrc);
@@ -113,7 +107,22 @@ struct dvfsrc_soc_data {
void (*set_vscp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
int (*wait_for_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
int (*wait_for_vcore_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
- const struct dvfsrc_bw_constraints *bw_constraints;
+
+ /**
+ * @bw_max_constraints - array of maximum bandwidth for this hardware
+ *
+ * indexed by &enum mtk_dvfsrc_bw_type, storing the maximum permissible
+ * hardware value for each bandwidth type.
+ */
+ const u32 *const bw_max_constraints;
+
+ /**
+ * @bw_min_constraints - array of minimum bandwidth for this hardware
+ *
+ * indexed by &enum mtk_dvfsrc_bw_type, storing the minimum permissible
+ * hardware value for each bandwidth type.
+ */
+ const u32 *const bw_min_constraints;
};
static u32 dvfsrc_readl(struct mtk_dvfsrc *dvfs, u32 offset)
@@ -383,59 +392,62 @@ static u32 dvfsrc_get_opp_count_v4(struct mtk_dvfsrc *dvfsrc)
return FIELD_GET(DVFSRC_V4_BASIC_CTRL_OPP_COUNT, val) + 1;
}
-static u32 dvfsrc_calc_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, int type, u64 bw)
+static u32
+dvfsrc_calc_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, enum mtk_dvfsrc_bw_type type, u64 bw)
{
- return (u32)div_u64(bw, 100 * 1000);
+ return clamp_val(div_u64(bw, 100 * 1000), dvfsrc->dvd->bw_min_constraints[type],
+ dvfsrc->dvd->bw_max_constraints[type]);
}
-static u32 dvfsrc_calc_dram_bw_v4(struct mtk_dvfsrc *dvfsrc, int type, u64 bw)
+/**
+ * dvfsrc_calc_dram_bw_v4 - convert kbps to hardware register bandwidth value
+ * @dvfsrc: pointer to the &struct mtk_dvfsrc of this driver instance
+ * @type: one of %DVFSRC_BW_AVG, %DVFSRC_BW_PEAK, or %DVFSRC_BW_HRT
+ * @bw: the bandwidth in kilobits per second
+ *
+ * Returns the hardware register value appropriate for expressing @bw, clamped
+ * to hardware limits.
+ */
+static u32
+dvfsrc_calc_dram_bw_v4(struct mtk_dvfsrc *dvfsrc, enum mtk_dvfsrc_bw_type type, u64 bw)
{
u8 bw_unit = dvfsrc->dvd->bw_units[type];
u64 bw_mbps;
+ u32 bw_hw;
if (type < DVFSRC_BW_AVG || type >= DVFSRC_BW_MAX)
return 0;
bw_mbps = div_u64(bw, 1000);
- return (u32)div_u64((bw_mbps + bw_unit - 1), bw_unit);
+ bw_hw = div_u64((bw_mbps + bw_unit - 1), bw_unit);
+ return clamp_val(bw_hw, dvfsrc->dvd->bw_min_constraints[type],
+ dvfsrc->dvd->bw_max_constraints[type]);
}
static void __dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u32 reg,
- int type, u16 max_bw, u16 min_bw, u64 bw)
+ enum mtk_dvfsrc_bw_type type, u64 bw)
{
- u32 new_bw = dvfsrc->dvd->calc_dram_bw(dvfsrc, type, bw);
-
- /* If bw constraints (in mbps) are defined make sure to respect them */
- if (max_bw)
- new_bw = min(new_bw, max_bw);
- if (min_bw && new_bw > 0)
- new_bw = max(new_bw, min_bw);
+ u32 bw_hw = dvfsrc->dvd->calc_dram_bw(dvfsrc, type, bw);
- dvfsrc_writel(dvfsrc, reg, new_bw);
+ dvfsrc_writel(dvfsrc, reg, bw_hw);
if (type == DVFSRC_BW_AVG && dvfsrc->dvd->has_emi_ddr)
- dvfsrc_writel(dvfsrc, DVFSRC_SW_EMI_BW, bw);
+ dvfsrc_writel(dvfsrc, DVFSRC_SW_EMI_BW, bw_hw);
}
static void dvfsrc_set_dram_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
{
- u64 max_bw = dvfsrc->dvd->bw_constraints->max_dram_nom_bw;
-
- __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_BW, DVFSRC_BW_AVG, max_bw, 0, bw);
+ __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_BW, DVFSRC_BW_AVG, bw);
};
static void dvfsrc_set_dram_peak_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
{
- u64 max_bw = dvfsrc->dvd->bw_constraints->max_dram_peak_bw;
-
- __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_PEAK_BW, DVFSRC_BW_PEAK, max_bw, 0, bw);
+ __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_PEAK_BW, DVFSRC_BW_PEAK, bw);
}
static void dvfsrc_set_dram_hrt_bw_v1(struct mtk_dvfsrc *dvfsrc, u64 bw)
{
- u64 max_bw = dvfsrc->dvd->bw_constraints->max_dram_hrt_bw;
-
- __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_HRT_BW, DVFSRC_BW_HRT, max_bw, 0, bw);
+ __dvfsrc_set_dram_bw_v1(dvfsrc, DVFSRC_SW_HRT_BW, DVFSRC_BW_HRT, bw);
}
static void dvfsrc_set_opp_level_v1(struct mtk_dvfsrc *dvfsrc, u32 level)
@@ -688,11 +700,22 @@ static int mtk_dvfsrc_probe(struct platform_device *pdev)
return 0;
}
-static const struct dvfsrc_bw_constraints dvfsrc_bw_constr_v1 = { 0, 0, 0 };
-static const struct dvfsrc_bw_constraints dvfsrc_bw_constr_v2 = {
- .max_dram_nom_bw = 255,
- .max_dram_peak_bw = 255,
- .max_dram_hrt_bw = 1023,
+static const u32 dvfsrc_bw_min_constr_none[DVFSRC_BW_MAX] = {
+ [DVFSRC_BW_AVG] = 0,
+ [DVFSRC_BW_PEAK] = 0,
+ [DVFSRC_BW_HRT] = 0,
+};
+
+static const u32 dvfsrc_bw_max_constr_v1[DVFSRC_BW_MAX] = {
+ [DVFSRC_BW_AVG] = U32_MAX,
+ [DVFSRC_BW_PEAK] = U32_MAX,
+ [DVFSRC_BW_HRT] = U32_MAX,
+};
+
+static const u32 dvfsrc_bw_max_constr_v2[DVFSRC_BW_MAX] = {
+ [DVFSRC_BW_AVG] = 65535,
+ [DVFSRC_BW_PEAK] = 65535,
+ [DVFSRC_BW_HRT] = 1023,
};
static const struct dvfsrc_opp dvfsrc_opp_mt6893_lp4[] = {
@@ -725,7 +748,8 @@ static const struct dvfsrc_soc_data mt6893_data = {
.set_vscp_level = dvfsrc_set_vscp_level_v2,
.wait_for_opp_level = dvfsrc_wait_for_opp_level_v2,
.wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v1,
- .bw_constraints = &dvfsrc_bw_constr_v2,
+ .bw_max_constraints = dvfsrc_bw_max_constr_v2,
+ .bw_min_constraints = dvfsrc_bw_min_constr_none,
};
static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp4[] = {
@@ -763,7 +787,8 @@ static const struct dvfsrc_soc_data mt8183_data = {
.set_vcore_level = dvfsrc_set_vcore_level_v1,
.wait_for_opp_level = dvfsrc_wait_for_opp_level_v1,
.wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v1,
- .bw_constraints = &dvfsrc_bw_constr_v1,
+ .bw_max_constraints = dvfsrc_bw_max_constr_v1,
+ .bw_min_constraints = dvfsrc_bw_min_constr_none,
};
static const struct dvfsrc_opp dvfsrc_opp_mt8195_lp4[] = {
@@ -797,7 +822,8 @@ static const struct dvfsrc_soc_data mt8195_data = {
.set_vscp_level = dvfsrc_set_vscp_level_v2,
.wait_for_opp_level = dvfsrc_wait_for_opp_level_v2,
.wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v1,
- .bw_constraints = &dvfsrc_bw_constr_v2,
+ .bw_max_constraints = dvfsrc_bw_max_constr_v2,
+ .bw_min_constraints = dvfsrc_bw_min_constr_none,
};
static const u8 mt8196_bw_units[] = {
@@ -825,7 +851,8 @@ static const struct dvfsrc_soc_data mt8196_data = {
.set_vscp_level = dvfsrc_set_vscp_level_v2,
.wait_for_opp_level = dvfsrc_wait_for_opp_level_v4,
.wait_for_vcore_level = dvfsrc_wait_for_vcore_level_v4,
- .bw_constraints = &dvfsrc_bw_constr_v1,
+ .bw_max_constraints = dvfsrc_bw_max_constr_v2,
+ .bw_min_constraints = dvfsrc_bw_min_constr_none,
};
static const struct of_device_id mtk_dvfsrc_of_match[] = {
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (9 preceding siblings ...)
2025-11-24 11:06 ` [PATCH v2 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations Nicolas Frattaroli
@ 2025-11-24 11:07 ` Nicolas Frattaroli
2026-01-09 16:30 ` Georgi Djakov
2025-11-24 11:07 ` [PATCH v2 12/13] interconnect: mediatek: Don't hijack parent device Nicolas Frattaroli
` (2 subsequent siblings)
13 siblings, 1 reply; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:07 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Add a new driver with data to register the External Memory
Interface (EMI) Interconnect on the MediaTek MT8196 Chromebook
SoC.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/interconnect/mediatek/Kconfig | 7 +
drivers/interconnect/mediatek/Makefile | 1 +
drivers/interconnect/mediatek/mt8196.c | 383 +++++++++++++++++++++++++++++++++
3 files changed, 391 insertions(+)
diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
index 985c849efac3..9fd3f2170443 100644
--- a/drivers/interconnect/mediatek/Kconfig
+++ b/drivers/interconnect/mediatek/Kconfig
@@ -27,3 +27,10 @@ config INTERCONNECT_MTK_MT8195
help
This is a driver for the MediaTek bus interconnect on MT8195-based
platforms.
+
+config INTERCONNECT_MTK_MT8196
+ tristate "MediaTek MT8196 interconnect driver"
+ depends on INTERCONNECT_MTK_DVFSRC_EMI
+ help
+ This is a driver for the MediaTek bus interconnect on MT8196-based
+ platforms.
diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
index 8e2283a9a5b5..6bd656668f5d 100644
--- a/drivers/interconnect/mediatek/Makefile
+++ b/drivers/interconnect/mediatek/Makefile
@@ -3,3 +3,4 @@
obj-$(CONFIG_INTERCONNECT_MTK_DVFSRC_EMI) += icc-emi.o
obj-$(CONFIG_INTERCONNECT_MTK_MT8183) += mt8183.o
obj-$(CONFIG_INTERCONNECT_MTK_MT8195) += mt8195.o
+obj-$(CONFIG_INTERCONNECT_MTK_MT8195) += mt8196.o
diff --git a/drivers/interconnect/mediatek/mt8196.c b/drivers/interconnect/mediatek/mt8196.c
new file mode 100644
index 000000000000..e9af32065be1
--- /dev/null
+++ b/drivers/interconnect/mediatek/mt8196.c
@@ -0,0 +1,383 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Collabora Ltd.
+ * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <linux/device.h>
+#include <linux/interconnect.h>
+#include <linux/interconnect-provider.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/interconnect/mediatek,mt8196.h>
+
+#include "icc-emi.h"
+
+static struct mtk_icc_node ddr_emi = {
+ .name = "ddr-emi",
+ .id = SLAVE_DDR_EMI,
+ .ep = 1,
+};
+
+static struct mtk_icc_node mcusys = {
+ .name = "mcusys",
+ .id = MASTER_MCUSYS,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node mcu_port0 = {
+ .name = "mcu-port0",
+ .id = MASTER_MCU_0,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node mcu_port1 = {
+ .name = "mcu-port1",
+ .id = MASTER_MCU_1,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node mcu_port2 = {
+ .name = "mcu-port2",
+ .id = MASTER_MCU_2,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node mcu_port3 = {
+ .name = "mcu-port3",
+ .id = MASTER_MCU_3,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node mcu_port4 = {
+ .name = "mcu-port4",
+ .id = MASTER_MCU_4,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node gpu = {
+ .name = "gpu",
+ .id = MASTER_GPUSYS,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node mmsys = {
+ .name = "mmsys",
+ .id = MASTER_MMSYS,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node mm_vpu = {
+ .name = "mm-vpu",
+ .id = MASTER_MM_VPU,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_MMSYS }
+};
+
+static struct mtk_icc_node mm_disp = {
+ .name = "mm-disp",
+ .id = MASTER_MM_DISP,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_MMSYS }
+};
+
+static struct mtk_icc_node mm_vdec = {
+ .name = "mm-vdec",
+ .id = MASTER_MM_VDEC,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_MMSYS }
+};
+
+static struct mtk_icc_node mm_venc = {
+ .name = "mm-venc",
+ .id = MASTER_MM_VENC,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_MMSYS }
+};
+
+static struct mtk_icc_node mm_cam = {
+ .name = "mm-cam",
+ .id = MASTER_MM_CAM,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_MMSYS }
+};
+
+static struct mtk_icc_node mm_img = {
+ .name = "mm-img",
+ .id = MASTER_MM_IMG,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_MMSYS }
+};
+
+static struct mtk_icc_node mm_mdp = {
+ .name = "mm-mdp",
+ .id = MASTER_MM_MDP,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_MMSYS }
+};
+
+static struct mtk_icc_node vpusys = {
+ .name = "vpusys",
+ .id = MASTER_VPUSYS,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node vpu_port0 = {
+ .name = "vpu-port0",
+ .id = MASTER_VPU_0,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_VPUSYS }
+};
+
+static struct mtk_icc_node vpu_port1 = {
+ .name = "vpu-port1",
+ .id = MASTER_VPU_1,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_VPUSYS }
+};
+
+static struct mtk_icc_node mdlasys = {
+ .name = "mdlasys",
+ .id = MASTER_MDLASYS,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node mdla_port0 = {
+ .name = "mdla-port0",
+ .id = MASTER_MDLA_0,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_MDLASYS }
+};
+
+static struct mtk_icc_node ufs = {
+ .name = "ufs",
+ .id = MASTER_UFS,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node pcie = {
+ .name = "pcie",
+ .id = MASTER_PCIE,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node usb = {
+ .name = "usb",
+ .id = MASTER_USB,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node wifi = {
+ .name = "wifi",
+ .id = MASTER_WIFI,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node bt = {
+ .name = "bt",
+ .id = MASTER_BT,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node netsys = {
+ .name = "netsys",
+ .id = MASTER_NETSYS,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node dbgif = {
+ .name = "dbgif",
+ .id = MASTER_DBGIF,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_DDR_EMI }
+};
+
+static struct mtk_icc_node hrt_ddr_emi = {
+ .name = "hrt-ddr-emi",
+ .id = SLAVE_HRT_DDR_EMI,
+ .ep = 2,
+};
+
+static struct mtk_icc_node hrt_mmsys = {
+ .name = "hrt-mmsys",
+ .id = MASTER_HRT_MMSYS,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_HRT_DDR_EMI }
+};
+
+static struct mtk_icc_node hrt_mm_disp = {
+ .name = "hrt-mm-disp",
+ .id = MASTER_HRT_MM_DISP,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_HRT_MMSYS }
+};
+
+static struct mtk_icc_node hrt_mm_vdec = {
+ .name = "hrt-mm-vdec",
+ .id = MASTER_HRT_MM_VDEC,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_HRT_MMSYS }
+};
+
+static struct mtk_icc_node hrt_mm_venc = {
+ .name = "hrt-mm-venc",
+ .id = MASTER_HRT_MM_VENC,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_HRT_MMSYS }
+};
+
+static struct mtk_icc_node hrt_mm_cam = {
+ .name = "hrt-mm-cam",
+ .id = MASTER_HRT_MM_CAM,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_HRT_MMSYS }
+};
+
+static struct mtk_icc_node hrt_mm_img = {
+ .name = "hrt-mm-img",
+ .id = MASTER_HRT_MM_IMG,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_HRT_MMSYS }
+};
+
+static struct mtk_icc_node hrt_mm_mdp = {
+ .name = "hrt-mm-mdp",
+ .id = MASTER_HRT_MM_MDP,
+ .ep = 0,
+ .num_links = 1,
+ .links = { MASTER_HRT_MMSYS }
+};
+
+static struct mtk_icc_node hrt_adsp = {
+ .name = "hrt-adsp",
+ .id = MASTER_HRT_ADSP,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_HRT_DDR_EMI }
+};
+
+static struct mtk_icc_node hrt_dbgif = {
+ .name = "hrt-dbgif",
+ .id = MASTER_HRT_DBGIF,
+ .ep = 0,
+ .num_links = 1,
+ .links = { SLAVE_HRT_DDR_EMI }
+};
+
+static struct mtk_icc_node *mt8196_emi_icc_nodes[] = {
+ [SLAVE_DDR_EMI] = &ddr_emi,
+ [MASTER_MCUSYS] = &mcusys,
+ [MASTER_MCU_0] = &mcu_port0,
+ [MASTER_MCU_1] = &mcu_port1,
+ [MASTER_MCU_2] = &mcu_port2,
+ [MASTER_MCU_3] = &mcu_port3,
+ [MASTER_MCU_4] = &mcu_port4,
+ [MASTER_GPUSYS] = &gpu,
+ [MASTER_MMSYS] = &mmsys,
+ [MASTER_MM_VPU] = &mm_vpu,
+ [MASTER_MM_DISP] = &mm_disp,
+ [MASTER_MM_VDEC] = &mm_vdec,
+ [MASTER_MM_VENC] = &mm_venc,
+ [MASTER_MM_CAM] = &mm_cam,
+ [MASTER_MM_IMG] = &mm_img,
+ [MASTER_MM_MDP] = &mm_mdp,
+ [MASTER_VPUSYS] = &vpusys,
+ [MASTER_VPU_0] = &vpu_port0,
+ [MASTER_VPU_1] = &vpu_port1,
+ [MASTER_MDLASYS] = &mdlasys,
+ [MASTER_MDLA_0] = &mdla_port0,
+ [MASTER_UFS] = &ufs,
+ [MASTER_PCIE] = &pcie,
+ [MASTER_USB] = &usb,
+ [MASTER_WIFI] = &wifi,
+ [MASTER_BT] = &bt,
+ [MASTER_NETSYS] = &netsys,
+ [MASTER_DBGIF] = &dbgif,
+ [SLAVE_HRT_DDR_EMI] = &hrt_ddr_emi,
+ [MASTER_HRT_MMSYS] = &hrt_mmsys,
+ [MASTER_HRT_MM_DISP] = &hrt_mm_disp,
+ [MASTER_HRT_MM_VDEC] = &hrt_mm_vdec,
+ [MASTER_HRT_MM_VENC] = &hrt_mm_venc,
+ [MASTER_HRT_MM_CAM] = &hrt_mm_cam,
+ [MASTER_HRT_MM_IMG] = &hrt_mm_img,
+ [MASTER_HRT_MM_MDP] = &hrt_mm_mdp,
+ [MASTER_HRT_ADSP] = &hrt_adsp,
+ [MASTER_HRT_DBGIF] = &hrt_dbgif
+};
+
+static struct mtk_icc_desc mt8196_emi_icc = {
+ .nodes = mt8196_emi_icc_nodes,
+ .num_nodes = ARRAY_SIZE(mt8196_emi_icc_nodes),
+};
+
+static const struct of_device_id mtk_mt8196_emi_icc_of_match[] = {
+ { .compatible = "mediatek,mt8196-emi", .data = &mt8196_emi_icc },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_mt8196_emi_icc_of_match);
+
+static struct platform_driver mtk_emi_icc_mt8196_driver = {
+ .driver = {
+ .name = "emi-icc-mt8196",
+ .of_match_table = mtk_mt8196_emi_icc_of_match,
+ .sync_state = icc_sync_state,
+ },
+ .probe = mtk_emi_icc_probe,
+ .remove = mtk_emi_icc_remove,
+
+};
+module_platform_driver(mtk_emi_icc_mt8196_driver);
+
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
+MODULE_DESCRIPTION("MediaTek MT8196 EMI ICC driver");
+MODULE_LICENSE("GPL");
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 12/13] interconnect: mediatek: Don't hijack parent device
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (10 preceding siblings ...)
2025-11-24 11:07 ` [PATCH v2 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC Nicolas Frattaroli
@ 2025-11-24 11:07 ` Nicolas Frattaroli
2025-11-24 11:07 ` [PATCH v2 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add Nicolas Frattaroli
2026-01-08 9:28 ` (subset) [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement AngeloGioacchino Del Regno
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:07 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
If the intention is that users of the interconnect declare their
relationship to the child icc_emi node of the dvfsrc controller, then
this code never worked. That's because it uses the parent dvfsrc device
as the device it passes to the interconnect core framework, which means
all the OF parsing is broken.
Use the actual device instead, and pass the dvfsrc parent into the
dvfsrc calls.
Fixes: b45293799f75 ("interconnect: mediatek: Add MediaTek MT8183/8195 EMI Interconnect driver")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/interconnect/mediatek/icc-emi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/interconnect/mediatek/icc-emi.c b/drivers/interconnect/mediatek/icc-emi.c
index 7da740b5fa8d..182aa2b0623a 100644
--- a/drivers/interconnect/mediatek/icc-emi.c
+++ b/drivers/interconnect/mediatek/icc-emi.c
@@ -40,7 +40,7 @@ static int mtk_emi_icc_set(struct icc_node *src, struct icc_node *dst)
if (unlikely(!src->provider))
return -EINVAL;
- dev = src->provider->dev;
+ dev = src->provider->dev->parent;
switch (node->ep) {
case 0:
@@ -97,7 +97,7 @@ int mtk_emi_icc_probe(struct platform_device *pdev)
if (!data)
return -ENOMEM;
- provider->dev = pdev->dev.parent;
+ provider->dev = dev;
provider->set = mtk_emi_icc_set;
provider->aggregate = mtk_emi_icc_aggregate;
provider->xlate = of_icc_xlate_onecell;
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (11 preceding siblings ...)
2025-11-24 11:07 ` [PATCH v2 12/13] interconnect: mediatek: Don't hijack parent device Nicolas Frattaroli
@ 2025-11-24 11:07 ` Nicolas Frattaroli
2026-01-08 9:28 ` (subset) [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement AngeloGioacchino Del Regno
13 siblings, 0 replies; 17+ messages in thread
From: Nicolas Frattaroli @ 2025-11-24 11:07 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli
By using a regular non-overflow-checking add, the MediaTek icc-emi
driver will happy wrap at U32_MAX + 1 to 0. As it's common for the
interconnect core to fill in INT_MAX values, this is not a hypothetical
situation, but something that actually happens in regular use. This
would be pretty disasterous if anything used this driver.
Replace the addition with an overflow-checked addition from overflow.h,
and saturate to U32_MAX if an overflow is detected.
Fixes: b45293799f75 ("interconnect: mediatek: Add MediaTek MT8183/8195 EMI Interconnect driver")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
drivers/interconnect/mediatek/icc-emi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/interconnect/mediatek/icc-emi.c b/drivers/interconnect/mediatek/icc-emi.c
index 182aa2b0623a..dfa3a9cd9399 100644
--- a/drivers/interconnect/mediatek/icc-emi.c
+++ b/drivers/interconnect/mediatek/icc-emi.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/overflow.h>
#include <linux/platform_device.h>
#include <linux/soc/mediatek/dvfsrc.h>
@@ -22,7 +23,9 @@ static int mtk_emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
{
struct mtk_icc_node *in = node->data;
- *agg_avg += avg_bw;
+ if (check_add_overflow(*agg_avg, avg_bw, agg_avg))
+ *agg_avg = U32_MAX;
+
*agg_peak = max_t(u32, *agg_peak, peak_bw);
in->sum_avg = *agg_avg;
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: (subset) [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
` (12 preceding siblings ...)
2025-11-24 11:07 ` [PATCH v2 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add Nicolas Frattaroli
@ 2026-01-08 9:28 ` AngeloGioacchino Del Regno
13 siblings, 0 replies; 17+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-08 9:28 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
Henry Chen, Georgi Djakov, Nicolas Frattaroli
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm
On Mon, 24 Nov 2025 12:06:49 +0100, Nicolas Frattaroli wrote:
> This series is a combination of binding changes, driver cleanups and new
> driver code to enable the interconnect on the MediaTek MT8196 SoC.
>
> This series currently does not add any users of it (i.e., no bandwidth
> requests being made in affected device drivers), as the only one I
> quickly whippd up is in the UFS driver, which is undergoing some major
> refactoring upstream in a different series of mine.
>
> [...]
Applied to v6.19-next/soc, thanks!
[02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock
commit: 831ee17036e259da23a6313e28a3cbdda221a88c
[04/13] soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd
commit: 23f1b4922a9135515e37d3bbad766e311845071f
[05/13] soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type
commit: c2488fecba681d632a3dbb6b2f33c39df2cb7be9
[06/13] soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw
commit: ddb5862a43b1f40ca0a5cc16882277d8d07b966a
[07/13] soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present
commit: 7cf9db2aca552f5f537d46f1e52e0ab08ddc2d64
[08/13] soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196
commit: 75cf308fee7e4b3038741f96fd90afc3bd871e64
[09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock
commit: 39aa8c4e762ea9b00d66cc55957527167ed89435
[10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations
commit: 3da293d70005496317d1ff3a49b89c29dd7c21e8
Cheers,
Angelo
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196
2025-11-24 11:06 ` [PATCH v2 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
@ 2026-01-08 9:29 ` AngeloGioacchino Del Regno
0 siblings, 0 replies; 17+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-08 9:29 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Nicolas Frattaroli, Henry Chen,
Matthias Brugger, Georgi Djakov
Il 24/11/25 12:06, Nicolas Frattaroli ha scritto:
> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>
> Add a compatible for the MediaTek MT8196 Chromebook SoC's
> DVFSRC hardware, introducing capability to communicate with it.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
dt maintainers, please, can anyone ack this patch so that I can pick it?
Thanks,
Angelo
> ---
> .../devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml
> index 4c96d4917967..5673d242afcb 100644
> --- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml
> +++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml
> @@ -26,6 +26,7 @@ properties:
> - mediatek,mt6893-dvfsrc
> - mediatek,mt8183-dvfsrc
> - mediatek,mt8195-dvfsrc
> + - mediatek,mt8196-dvfsrc
> - items:
> - const: mediatek,mt8192-dvfsrc
> - const: mediatek,mt8195-dvfsrc
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC
2025-11-24 11:07 ` [PATCH v2 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC Nicolas Frattaroli
@ 2026-01-09 16:30 ` Georgi Djakov
0 siblings, 0 replies; 17+ messages in thread
From: Georgi Djakov @ 2026-01-09 16:30 UTC (permalink / raw)
To: Nicolas Frattaroli, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Henry Chen
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm
On 11/24/25 1:07 PM, Nicolas Frattaroli wrote:
> From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
>
> Add a new driver with data to register the External Memory
> Interface (EMI) Interconnect on the MediaTek MT8196 Chromebook
> SoC.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
The interconnect patches look good to me and there is no build dependency,
so i picked them. On a side note, we recently added support for dynamic
node ids in the framework, so maybe switch to that in the future.
Thanks!
Georgi
> ---
> drivers/interconnect/mediatek/Kconfig | 7 +
> drivers/interconnect/mediatek/Makefile | 1 +
> drivers/interconnect/mediatek/mt8196.c | 383 +++++++++++++++++++++++++++++++++
> 3 files changed, 391 insertions(+)
>
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-01-09 16:31 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-24 11:06 [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
2026-01-08 9:29 ` AngeloGioacchino Del Regno
2025-11-24 11:06 ` [PATCH v2 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 04/13] soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 05/13] soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 06/13] soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 07/13] soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 08/13] soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196 Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock Nicolas Frattaroli
2025-11-24 11:06 ` [PATCH v2 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations Nicolas Frattaroli
2025-11-24 11:07 ` [PATCH v2 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC Nicolas Frattaroli
2026-01-09 16:30 ` Georgi Djakov
2025-11-24 11:07 ` [PATCH v2 12/13] interconnect: mediatek: Don't hijack parent device Nicolas Frattaroli
2025-11-24 11:07 ` [PATCH v2 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add Nicolas Frattaroli
2026-01-08 9:28 ` (subset) [PATCH v2 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement AngeloGioacchino Del Regno
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox