linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement
@ 2025-11-14 16:53 Nicolas Frattaroli
  2025-11-14 16:53 ` [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
                   ` (12 more replies)
  0 siblings, 13 replies; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:53 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>
---
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: d8a3d478ec9200b852095cb96d166ca7909f57e0
change-id: 20251114-mt8196-dvfsrc-59fc8901774c

Best regards,
-- 
Nicolas Frattaroli <nicolas.frattaroli@collabora.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
@ 2025-11-14 16:53 ` Nicolas Frattaroli
  2025-11-19  7:41   ` Krzysztof Kozlowski
  2025-11-14 16:53 ` [PATCH 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock Nicolas Frattaroli
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:53 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>
---
 .../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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
  2025-11-14 16:53 ` [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
@ 2025-11-14 16:53 ` Nicolas Frattaroli
  2025-11-17 12:48   ` AngeloGioacchino Del Regno
  2025-11-20  0:11   ` Rob Herring (Arm)
  2025-11-14 16:53 ` [PATCH 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI Nicolas Frattaroli
                   ` (10 subsequent siblings)
  12 siblings, 2 replies; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:53 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.

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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
  2025-11-14 16:53 ` [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
  2025-11-14 16:53 ` [PATCH 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock Nicolas Frattaroli
@ 2025-11-14 16:53 ` Nicolas Frattaroli
  2025-11-20  0:11   ` Rob Herring (Arm)
  2025-11-14 16:53 ` [PATCH 04/13] soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd Nicolas Frattaroli
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:53 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>
---
 .../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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 04/13] soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (2 preceding siblings ...)
  2025-11-14 16:53 ` [PATCH 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI Nicolas Frattaroli
@ 2025-11-14 16:53 ` Nicolas Frattaroli
  2025-11-14 16:53 ` [PATCH 05/13] soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type Nicolas Frattaroli
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:53 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>
---
 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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 05/13] soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (3 preceding siblings ...)
  2025-11-14 16:53 ` [PATCH 04/13] soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd Nicolas Frattaroli
@ 2025-11-14 16:53 ` Nicolas Frattaroli
  2025-11-14 16:54 ` [PATCH 06/13] soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw Nicolas Frattaroli
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:53 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>
---
 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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 06/13] soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (4 preceding siblings ...)
  2025-11-14 16:53 ` [PATCH 05/13] soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type Nicolas Frattaroli
@ 2025-11-14 16:54 ` Nicolas Frattaroli
  2025-11-14 16:54 ` [PATCH 07/13] soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present Nicolas Frattaroli
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:54 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>
---
 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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 07/13] soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (5 preceding siblings ...)
  2025-11-14 16:54 ` [PATCH 06/13] soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw Nicolas Frattaroli
@ 2025-11-14 16:54 ` Nicolas Frattaroli
  2025-11-14 16:54 ` [PATCH 08/13] soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196 Nicolas Frattaroli
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:54 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>
---
 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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 08/13] soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (6 preceding siblings ...)
  2025-11-14 16:54 ` [PATCH 07/13] soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present Nicolas Frattaroli
@ 2025-11-14 16:54 ` Nicolas Frattaroli
  2025-11-14 16:54 ` [PATCH 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock Nicolas Frattaroli
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:54 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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (7 preceding siblings ...)
  2025-11-14 16:54 ` [PATCH 08/13] soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196 Nicolas Frattaroli
@ 2025-11-14 16:54 ` Nicolas Frattaroli
  2025-11-17 12:38   ` AngeloGioacchino Del Regno
  2025-11-14 16:54 ` [PATCH 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations Nicolas Frattaroli
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:54 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.

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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (8 preceding siblings ...)
  2025-11-14 16:54 ` [PATCH 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock Nicolas Frattaroli
@ 2025-11-14 16:54 ` Nicolas Frattaroli
  2025-11-17 12:39   ` AngeloGioacchino Del Regno
  2025-11-14 16:54 ` [PATCH 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC Nicolas Frattaroli
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:54 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.

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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (9 preceding siblings ...)
  2025-11-14 16:54 ` [PATCH 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations Nicolas Frattaroli
@ 2025-11-14 16:54 ` Nicolas Frattaroli
  2025-11-14 16:54 ` [PATCH 12/13] interconnect: mediatek: Don't hijack parent device Nicolas Frattaroli
  2025-11-14 16:54 ` [PATCH 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add Nicolas Frattaroli
  12 siblings, 0 replies; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:54 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>
---
 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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 12/13] interconnect: mediatek: Don't hijack parent device
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (10 preceding siblings ...)
  2025-11-14 16:54 ` [PATCH 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC Nicolas Frattaroli
@ 2025-11-14 16:54 ` Nicolas Frattaroli
  2025-11-17 12:39   ` AngeloGioacchino Del Regno
  2025-11-14 16:54 ` [PATCH 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add Nicolas Frattaroli
  12 siblings, 1 reply; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:54 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")
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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add
  2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
                   ` (11 preceding siblings ...)
  2025-11-14 16:54 ` [PATCH 12/13] interconnect: mediatek: Don't hijack parent device Nicolas Frattaroli
@ 2025-11-14 16:54 ` Nicolas Frattaroli
  2025-11-17 12:39   ` AngeloGioacchino Del Regno
  12 siblings, 1 reply; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-14 16:54 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")
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.51.2



^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock
  2025-11-14 16:54 ` [PATCH 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock Nicolas Frattaroli
@ 2025-11-17 12:38   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 26+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-11-17 12:38 UTC (permalink / raw)
  To: Nicolas Frattaroli, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, Henry Chen, Georgi Djakov
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-pm

Il 14/11/25 17:54, Nicolas Frattaroli ha scritto:
> 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.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations
  2025-11-14 16:54 ` [PATCH 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations Nicolas Frattaroli
@ 2025-11-17 12:39   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 26+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-11-17 12:39 UTC (permalink / raw)
  To: Nicolas Frattaroli, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, Henry Chen, Georgi Djakov
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-pm

Il 14/11/25 17:54, Nicolas Frattaroli ha scritto:
> 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.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 12/13] interconnect: mediatek: Don't hijack parent device
  2025-11-14 16:54 ` [PATCH 12/13] interconnect: mediatek: Don't hijack parent device Nicolas Frattaroli
@ 2025-11-17 12:39   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 26+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-11-17 12:39 UTC (permalink / raw)
  To: Nicolas Frattaroli, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, Henry Chen, Georgi Djakov
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-pm

Il 14/11/25 17:54, Nicolas Frattaroli ha scritto:
> 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")
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add
  2025-11-14 16:54 ` [PATCH 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add Nicolas Frattaroli
@ 2025-11-17 12:39   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 26+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-11-17 12:39 UTC (permalink / raw)
  To: Nicolas Frattaroli, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, Henry Chen, Georgi Djakov
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-pm

Il 14/11/25 17:54, Nicolas Frattaroli ha scritto:
> 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")
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock
  2025-11-14 16:53 ` [PATCH 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock Nicolas Frattaroli
@ 2025-11-17 12:48   ` AngeloGioacchino Del Regno
  2025-11-20  0:11   ` Rob Herring (Arm)
  1 sibling, 0 replies; 26+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-11-17 12:48 UTC (permalink / raw)
  To: Nicolas Frattaroli, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, Henry Chen, Georgi Djakov
  Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-pm

Il 14/11/25 17:53, Nicolas Frattaroli ha scritto:
> 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.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196
  2025-11-14 16:53 ` [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
@ 2025-11-19  7:41   ` Krzysztof Kozlowski
  2025-11-19  8:32     ` AngeloGioacchino Del Regno
  0 siblings, 1 reply; 26+ messages in thread
From: Krzysztof Kozlowski @ 2025-11-19  7:41 UTC (permalink / raw)
  To: Nicolas Frattaroli
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Henry Chen, Georgi Djakov, kernel,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm

On Fri, Nov 14, 2025 at 05:53:55PM +0100, Nicolas Frattaroli wrote:
> 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>

Incomplete DCO chain.

Best regards,
Krzysztof



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196
  2025-11-19  7:41   ` Krzysztof Kozlowski
@ 2025-11-19  8:32     ` AngeloGioacchino Del Regno
  2025-11-19  8:33       ` AngeloGioacchino Del Regno
  2025-11-19 12:29       ` Nicolas Frattaroli
  0 siblings, 2 replies; 26+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-11-19  8:32 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Nicolas Frattaroli
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	Henry Chen, Georgi Djakov, kernel, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, linux-pm

Il 19/11/25 08:41, Krzysztof Kozlowski ha scritto:
> On Fri, Nov 14, 2025 at 05:53:55PM +0100, Nicolas Frattaroli wrote:
>> 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>
> 
> Incomplete DCO chain.
> 
> Best regards,
> Krzysztof
> 

Eh yes, Nicolas forgot to add his SoC on all of my commits, whoops :-)

Cheers,
Angelo


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196
  2025-11-19  8:32     ` AngeloGioacchino Del Regno
@ 2025-11-19  8:33       ` AngeloGioacchino Del Regno
  2025-11-19 12:29       ` Nicolas Frattaroli
  1 sibling, 0 replies; 26+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-11-19  8:33 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Nicolas Frattaroli
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	Henry Chen, Georgi Djakov, kernel, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, linux-pm

Il 19/11/25 09:32, AngeloGioacchino Del Regno ha scritto:
> Il 19/11/25 08:41, Krzysztof Kozlowski ha scritto:
>> On Fri, Nov 14, 2025 at 05:53:55PM +0100, Nicolas Frattaroli wrote:
>>> 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>
>>
>> Incomplete DCO chain.
>>
>> Best regards,
>> Krzysztof
>>
> 
> Eh yes, Nicolas forgot to add his SoC on all of my commits, whoops :-)

his SoC!??!?! Ugh. I meant SoB, and I should sleep more, lol

> 
> Cheers,
> Angelo



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196
  2025-11-19  8:32     ` AngeloGioacchino Del Regno
  2025-11-19  8:33       ` AngeloGioacchino Del Regno
@ 2025-11-19 12:29       ` Nicolas Frattaroli
  2025-11-19 12:32         ` Krzysztof Kozlowski
  1 sibling, 1 reply; 26+ messages in thread
From: Nicolas Frattaroli @ 2025-11-19 12:29 UTC (permalink / raw)
  To: Krzysztof Kozlowski, AngeloGioacchino Del Regno
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	Henry Chen, Georgi Djakov, kernel, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, linux-pm

On Wednesday, 19 November 2025 09:32:46 Central European Standard Time AngeloGioacchino Del Regno wrote:
> Il 19/11/25 08:41, Krzysztof Kozlowski ha scritto:
> > On Fri, Nov 14, 2025 at 05:53:55PM +0100, Nicolas Frattaroli wrote:
> >> 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>
> > 
> > Incomplete DCO chain.
> > 
> > Best regards,
> > Krzysztof
> > 
> 
> Eh yes, Nicolas forgot to add his SoC on all of my commits, whoops :-)
> 
> Cheers,
> Angelo
> 

And here I hoped b4 would do that when sending these out, oh well.





^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196
  2025-11-19 12:29       ` Nicolas Frattaroli
@ 2025-11-19 12:32         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 26+ messages in thread
From: Krzysztof Kozlowski @ 2025-11-19 12:32 UTC (permalink / raw)
  To: Nicolas Frattaroli, AngeloGioacchino Del Regno
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	Henry Chen, Georgi Djakov, kernel, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, linux-pm

On 19/11/2025 13:29, Nicolas Frattaroli wrote:
> On Wednesday, 19 November 2025 09:32:46 Central European Standard Time AngeloGioacchino Del Regno wrote:
>> Il 19/11/25 08:41, Krzysztof Kozlowski ha scritto:
>>> On Fri, Nov 14, 2025 at 05:53:55PM +0100, Nicolas Frattaroli wrote:
>>>> 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>
>>>
>>> Incomplete DCO chain.
>>>
>>> Best regards,
>>> Krzysztof
>>>
>>
>> Eh yes, Nicolas forgot to add his SoC on all of my commits, whoops :-)
>>
>> Cheers,
>> Angelo
>>
> 
> And here I hoped b4 would do that when sending these out, oh well.

b4 cannot certify something for you. You must add it explicitly yourself
because certification must be your intentional act (which also means you
know what you certify).

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock
  2025-11-14 16:53 ` [PATCH 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock Nicolas Frattaroli
  2025-11-17 12:48   ` AngeloGioacchino Del Regno
@ 2025-11-20  0:11   ` Rob Herring (Arm)
  1 sibling, 0 replies; 26+ messages in thread
From: Rob Herring (Arm) @ 2025-11-20  0:11 UTC (permalink / raw)
  To: Nicolas Frattaroli
  Cc: Matthias Brugger, linux-kernel, AngeloGioacchino Del Regno,
	linux-arm-kernel, devicetree, Georgi Djakov, Henry Chen,
	Krzysztof Kozlowski, linux-pm, Conor Dooley, kernel,
	linux-mediatek


On Fri, 14 Nov 2025 17:53:56 +0100, Nicolas Frattaroli wrote:
> 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.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
> ---
>  .../devicetree/bindings/soc/mediatek/mediatek,mt8183-dvfsrc.yaml    | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI
  2025-11-14 16:53 ` [PATCH 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI Nicolas Frattaroli
@ 2025-11-20  0:11   ` Rob Herring (Arm)
  0 siblings, 0 replies; 26+ messages in thread
From: Rob Herring (Arm) @ 2025-11-20  0:11 UTC (permalink / raw)
  To: Nicolas Frattaroli
  Cc: Conor Dooley, devicetree, Matthias Brugger, kernel, Georgi Djakov,
	linux-mediatek, Krzysztof Kozlowski, Henry Chen, linux-kernel,
	linux-pm, linux-arm-kernel, AngeloGioacchino Del Regno


On Fri, 14 Nov 2025 17:53:57 +0100, Nicolas Frattaroli wrote:
> 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>
> ---
>  .../bindings/interconnect/mediatek,mt8183-emi.yaml |  1 +
>  include/dt-bindings/interconnect/mediatek,mt8196.h | 48 ++++++++++++++++++++++
>  2 files changed, 49 insertions(+)
> 

Acked-by: Rob Herring (Arm) <robh@kernel.org>



^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2025-11-20  0:11 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-14 16:53 [PATCH 00/13] MediaTek Interconnect Cleanup and MT8196 Enablement Nicolas Frattaroli
2025-11-14 16:53 ` [PATCH 01/13] dt-bindings: soc: mediatek: dvfsrc: Add support for MT8196 Nicolas Frattaroli
2025-11-19  7:41   ` Krzysztof Kozlowski
2025-11-19  8:32     ` AngeloGioacchino Del Regno
2025-11-19  8:33       ` AngeloGioacchino Del Regno
2025-11-19 12:29       ` Nicolas Frattaroli
2025-11-19 12:32         ` Krzysztof Kozlowski
2025-11-14 16:53 ` [PATCH 02/13] dt-bindings: soc: mediatek: dvfsrc: Document clock Nicolas Frattaroli
2025-11-17 12:48   ` AngeloGioacchino Del Regno
2025-11-20  0:11   ` Rob Herring (Arm)
2025-11-14 16:53 ` [PATCH 03/13] dt-bindings: interconnect: mt8183-emi: Add support for MT8196 EMI Nicolas Frattaroli
2025-11-20  0:11   ` Rob Herring (Arm)
2025-11-14 16:53 ` [PATCH 04/13] soc: mediatek: mtk-dvfsrc: Change error check for DVFSRCv4 START cmd Nicolas Frattaroli
2025-11-14 16:53 ` [PATCH 05/13] soc: mediatek: mtk-dvfsrc: Add and propagate DVFSRC bandwidth type Nicolas Frattaroli
2025-11-14 16:54 ` [PATCH 06/13] soc: mediatek: mtk-dvfsrc: Add a new callback for calc_dram_bw Nicolas Frattaroli
2025-11-14 16:54 ` [PATCH 07/13] soc: mediatek: mtk-dvfsrc: Write bandwidth to EMI DDR if present Nicolas Frattaroli
2025-11-14 16:54 ` [PATCH 08/13] soc: mediatek: mtk-dvfsrc: Add support for DVFSRCv4 and MT8196 Nicolas Frattaroli
2025-11-14 16:54 ` [PATCH 09/13] soc: mediatek: mtk-dvfsrc: Get and Enable DVFSRC clock Nicolas Frattaroli
2025-11-17 12:38   ` AngeloGioacchino Del Regno
2025-11-14 16:54 ` [PATCH 10/13] soc: mediatek: mtk-dvfsrc: Rework bandwidth calculations Nicolas Frattaroli
2025-11-17 12:39   ` AngeloGioacchino Del Regno
2025-11-14 16:54 ` [PATCH 11/13] interconnect: mediatek: Add support for MediaTek MT8196 EMI ICC Nicolas Frattaroli
2025-11-14 16:54 ` [PATCH 12/13] interconnect: mediatek: Don't hijack parent device Nicolas Frattaroli
2025-11-17 12:39   ` AngeloGioacchino Del Regno
2025-11-14 16:54 ` [PATCH 13/13] interconnect: mediatek: Aggregate bandwidth with saturating add Nicolas Frattaroli
2025-11-17 12:39   ` 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;
as well as URLs for NNTP newsgroup(s).