Просмотр исходного кода

econet: add clock/reset support

This is in preparation for the next update to EcoNet Ethernet driver
which will be using real resets rather than bit-bashing. Patches are
backported up to the current state of clk-next because I intend on
upstreaming these patches soon.

Signed-off-by: Caleb James DeLisle <[email protected]>
Link: https://github.com/openwrt/openwrt/pull/21545
Signed-off-by: Hauke Mehrtens <[email protected]>
Caleb James DeLisle 4 недель назад
Родитель
Сommit
b4b12a8239
15 измененных файлов с 1420 добавлено и 0 удалено
  1. 24 0
      target/linux/econet/dts/en751221.dtsi
  2. 2 0
      target/linux/econet/en751221/config-6.12
  3. 179 0
      target/linux/econet/patches-6.12/012-v6.13-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch
  4. 89 0
      target/linux/econet/patches-6.12/013-v6.13-clk-en7523-map-io-region-in-a-single-block.patch
  5. 47 0
      target/linux/econet/patches-6.12/014-v6.14-PCI-mediatek-gen3-Move-reset-delay-in-mtk_pcie_en758.patch
  6. 88 0
      target/linux/econet/patches-6.12/015-v6.14-clk-en7523-Rework-clock-handling-for-different-clock.patch
  7. 46 0
      target/linux/econet/patches-6.12/016-v6.14-clk-en7523-Add-clock-for-eMMC-for-EN7581.patch
  8. 138 0
      target/linux/econet/patches-6.12/017-v6.19rc1-clk-en7523-Add-reset-controller-support-for-EN7523-S.patch
  9. 40 0
      target/linux/econet/patches-6.12/018-v6.19rc1-dt-bindings-clock-airoha-Add-reset-support-to-EN7523.patch
  10. 79 0
      target/linux/econet/patches-6.12/019-v6.13-dt-bindings-clock-airoha-Update-reg-mapping-for-EN75.patch
  11. 87 0
      target/linux/econet/patches-6.12/020-v6.19rc1-dt-bindings-clock-airoha-Add-reset-support-to-EN7523.patch
  12. 31 0
      target/linux/econet/patches-6.12/021-v6.14-dt-bindings-clock-drop-NUM_CLOCKS-define-for-EN7581.patch
  13. 30 0
      target/linux/econet/patches-6.12/022-v6.14-dt-bindings-clock-add-ID-for-eMMC-for-EN7581.patch
  14. 176 0
      target/linux/econet/patches-6.12/910-dt-bindings-clock-reset-add-econet-en751221-bindings.patch
  15. 364 0
      target/linux/econet/patches-6.12/911-clk-airoha-add-econet-en751221-clock-reset-support-t.patch

+ 24 - 0
target/linux/econet/dts/en751221.dtsi

@@ -1,4 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include <dt-bindings/reset/econet,en751221-scu.h>
+
 /dts-v1/;
 
 / {
@@ -45,6 +48,11 @@
 		};
 	};
 
+	chip_scu: syscon@1fa20000 {
+		compatible = "econet,en751221-chip-scu", "syscon";
+		reg = <0x1fa20000 0x388>;
+	};
+
 	intc: interrupt-controller@1fb40000 {
 		compatible = "econet,en751221-intc";
 		reg = <0x1fb40000 0x100>;
@@ -56,10 +64,26 @@
 		econet,shadow-interrupts = <7 2>, <8 3>, <13 12>, <30 29>;
 	};
 
+	scuclk: clock-controller@1fb00000 {
+		compatible = "econet,en751221-scu", "syscon";
+		reg = <0x1fb00000 0x970>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
 	ethernet: ethernet@1fb50000 {
 		compatible = "econet,en751221-eth";
 		reg = <0x1fb50000 0x10000>;
 
+		resets = <&scuclk EN751221_FE_RST>,
+			 <&scuclk EN751221_FE_QDMA1_RST>,
+			 <&scuclk EN751221_FE_QDMA2_RST>,
+			 <&scuclk EN751221_GSW_RST>,
+			 <&scuclk EN751221_XPON_MAC_RST>,
+			 <&scuclk EN751221_XPON_PHY_RST>;
+		reset-names = "fe", "qdma0", "qdma1", "gsw",
+			      "xpon-mac", "xpon-phy";
+
 		#address-cells = <1>;
 		#size-cells = <0>;
 

+ 2 - 0
target/linux/econet/en751221/config-6.12

@@ -5,6 +5,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
 CONFIG_CLKSRC_MMIO=y
 CONFIG_CLONE_BACKWARDS=y
 CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_EN7523=y
 CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
 CONFIG_COMPAT_32BIT_TIME=y
 CONFIG_CONTEXT_TRACKING=y
@@ -142,6 +143,7 @@ CONFIG_QUEUED_RWLOCKS=y
 CONFIG_QUEUED_SPINLOCKS=y
 CONFIG_RANDSTRUCT_NONE=y
 CONFIG_RATIONAL=y
+CONFIG_RESET_CONTROLLER=y
 CONFIG_RFS_ACCEL=y
 CONFIG_RPS=y
 CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES=y

+ 179 - 0
target/linux/econet/patches-6.12/012-v6.13-clk-en7523-move-en7581_reset_register-in-en7581_clk_.patch

@@ -0,0 +1,179 @@
+From 82e6bf912d5846646892becea659b39d178d79e3 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <[email protected]>
+Date: Tue, 12 Nov 2024 01:08:53 +0100
+Subject: [PATCH 5/8] clk: en7523: move en7581_reset_register() in
+ en7581_clk_hw_init()
+
+Move en7581_reset_register routine in en7581_clk_hw_init() since reset
+feature is supported just by EN7581 SoC.
+Get rid of reset struct in en_clk_soc_data data struct.
+
+Signed-off-by: Lorenzo Bianconi <[email protected]>
+Link: https://lore.kernel.org/r/[email protected]
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ drivers/clk/clk-en7523.c | 93 ++++++++++++++--------------------------
+ 1 file changed, 33 insertions(+), 60 deletions(-)
+
+diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
+index fdd8ea989ed2..60dc938144d7 100644
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -76,11 +76,6 @@ struct en_rst_data {
+ 
+ struct en_clk_soc_data {
+ 	const struct clk_ops pcie_ops;
+-	struct {
+-		const u16 *bank_ofs;
+-		const u16 *idx_map;
+-		u16 idx_map_nr;
+-	} reset;
+ 	int (*hw_init)(struct platform_device *pdev,
+ 		       struct clk_hw_onecell_data *clk_data);
+ };
+@@ -595,32 +590,6 @@ static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_dat
+ 	clk_data->num = EN7523_NUM_CLOCKS;
+ }
+ 
+-static int en7581_clk_hw_init(struct platform_device *pdev,
+-			      struct clk_hw_onecell_data *clk_data)
+-{
+-	void __iomem *np_base;
+-	struct regmap *map;
+-	u32 val;
+-
+-	map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
+-	if (IS_ERR(map))
+-		return PTR_ERR(map);
+-
+-	np_base = devm_platform_ioremap_resource(pdev, 0);
+-	if (IS_ERR(np_base))
+-		return PTR_ERR(np_base);
+-
+-	en7581_register_clocks(&pdev->dev, clk_data, map, np_base);
+-
+-	val = readl(np_base + REG_NP_SCU_SSTR);
+-	val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
+-	writel(val, np_base + REG_NP_SCU_SSTR);
+-	val = readl(np_base + REG_NP_SCU_PCIC);
+-	writel(val | 3, np_base + REG_NP_SCU_PCIC);
+-
+-	return 0;
+-}
+-
+ static int en7523_reset_update(struct reset_controller_dev *rcdev,
+ 			       unsigned long id, bool assert)
+ {
+@@ -670,23 +639,18 @@ static int en7523_reset_xlate(struct reset_controller_dev *rcdev,
+ 	return rst_data->idx_map[reset_spec->args[0]];
+ }
+ 
+-static const struct reset_control_ops en7523_reset_ops = {
++static const struct reset_control_ops en7581_reset_ops = {
+ 	.assert = en7523_reset_assert,
+ 	.deassert = en7523_reset_deassert,
+ 	.status = en7523_reset_status,
+ };
+ 
+-static int en7523_reset_register(struct platform_device *pdev,
+-				 const struct en_clk_soc_data *soc_data)
++static int en7581_reset_register(struct platform_device *pdev)
+ {
+ 	struct device *dev = &pdev->dev;
+ 	struct en_rst_data *rst_data;
+ 	void __iomem *base;
+ 
+-	/* no reset lines available */
+-	if (!soc_data->reset.idx_map_nr)
+-		return 0;
+-
+ 	base = devm_platform_ioremap_resource(pdev, 1);
+ 	if (IS_ERR(base))
+ 		return PTR_ERR(base);
+@@ -695,13 +659,13 @@ static int en7523_reset_register(struct platform_device *pdev,
+ 	if (!rst_data)
+ 		return -ENOMEM;
+ 
+-	rst_data->bank_ofs = soc_data->reset.bank_ofs;
+-	rst_data->idx_map = soc_data->reset.idx_map;
++	rst_data->bank_ofs = en7581_rst_ofs;
++	rst_data->idx_map = en7581_rst_map;
+ 	rst_data->base = base;
+ 
+-	rst_data->rcdev.nr_resets = soc_data->reset.idx_map_nr;
++	rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map);
+ 	rst_data->rcdev.of_xlate = en7523_reset_xlate;
+-	rst_data->rcdev.ops = &en7523_reset_ops;
++	rst_data->rcdev.ops = &en7581_reset_ops;
+ 	rst_data->rcdev.of_node = dev->of_node;
+ 	rst_data->rcdev.of_reset_n_cells = 1;
+ 	rst_data->rcdev.owner = THIS_MODULE;
+@@ -710,6 +674,32 @@ static int en7523_reset_register(struct platform_device *pdev,
+ 	return devm_reset_controller_register(dev, &rst_data->rcdev);
+ }
+ 
++static int en7581_clk_hw_init(struct platform_device *pdev,
++			      struct clk_hw_onecell_data *clk_data)
++{
++	void __iomem *np_base;
++	struct regmap *map;
++	u32 val;
++
++	map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
++	if (IS_ERR(map))
++		return PTR_ERR(map);
++
++	np_base = devm_platform_ioremap_resource(pdev, 0);
++	if (IS_ERR(np_base))
++		return PTR_ERR(np_base);
++
++	en7581_register_clocks(&pdev->dev, clk_data, map, np_base);
++
++	val = readl(np_base + REG_NP_SCU_SSTR);
++	val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
++	writel(val, np_base + REG_NP_SCU_SSTR);
++	val = readl(np_base + REG_NP_SCU_PCIC);
++	writel(val | 3, np_base + REG_NP_SCU_PCIC);
++
++	return en7581_reset_register(pdev);
++}
++
+ static int en7523_clk_probe(struct platform_device *pdev)
+ {
+ 	struct device_node *node = pdev->dev.of_node;
+@@ -728,19 +718,7 @@ static int en7523_clk_probe(struct platform_device *pdev)
+ 	if (r)
+ 		return r;
+ 
+-	r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+-	if (r)
+-		return dev_err_probe(&pdev->dev, r, "Could not register clock provider: %s\n",
+-				     pdev->name);
+-
+-	r = en7523_reset_register(pdev, soc_data);
+-	if (r) {
+-		of_clk_del_provider(node);
+-		return dev_err_probe(&pdev->dev, r, "Could not register reset controller: %s\n",
+-				     pdev->name);
+-	}
+-
+-	return 0;
++	return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+ }
+ 
+ static const struct en_clk_soc_data en7523_data = {
+@@ -758,11 +736,6 @@ static const struct en_clk_soc_data en7581_data = {
+ 		.enable = en7581_pci_enable,
+ 		.disable = en7581_pci_disable,
+ 	},
+-	.reset = {
+-		.bank_ofs = en7581_rst_ofs,
+-		.idx_map = en7581_rst_map,
+-		.idx_map_nr = ARRAY_SIZE(en7581_rst_map),
+-	},
+ 	.hw_init = en7581_clk_hw_init,
+ };
+ 
+-- 
+2.39.5
+

+ 89 - 0
target/linux/econet/patches-6.12/013-v6.13-clk-en7523-map-io-region-in-a-single-block.patch

@@ -0,0 +1,89 @@
+From a9eaf305017a5ebe73ab34e85bd5414055a88f29 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <[email protected]>
+Date: Tue, 12 Nov 2024 01:08:54 +0100
+Subject: [PATCH 6/8] clk: en7523: map io region in a single block
+
+Map all clock-controller memory region in a single block.
+This patch does not introduce any backward incompatibility since the dts
+for EN7581 SoC is not upstream yet.
+
+Signed-off-by: Lorenzo Bianconi <[email protected]>
+Link: https://lore.kernel.org/r/[email protected]
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ drivers/clk/clk-en7523.c | 32 +++++++++++++-------------------
+ 1 file changed, 13 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
+index 60dc938144d7..e52c5460e927 100644
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -39,8 +39,8 @@
+ #define REG_PCIE_XSI1_SEL_MASK		GENMASK(12, 11)
+ #define REG_CRYPTO_CLKSRC2		0x20c
+ 
+-#define REG_RST_CTRL2			0x00
+-#define REG_RST_CTRL1			0x04
++#define REG_RST_CTRL2			0x830
++#define REG_RST_CTRL1			0x834
+ 
+ struct en_clk_desc {
+ 	int id;
+@@ -645,15 +645,9 @@ static const struct reset_control_ops en7581_reset_ops = {
+ 	.status = en7523_reset_status,
+ };
+ 
+-static int en7581_reset_register(struct platform_device *pdev)
++static int en7581_reset_register(struct device *dev, void __iomem *base)
+ {
+-	struct device *dev = &pdev->dev;
+ 	struct en_rst_data *rst_data;
+-	void __iomem *base;
+-
+-	base = devm_platform_ioremap_resource(pdev, 1);
+-	if (IS_ERR(base))
+-		return PTR_ERR(base);
+ 
+ 	rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL);
+ 	if (!rst_data)
+@@ -677,27 +671,27 @@ static int en7581_reset_register(struct platform_device *pdev)
+ static int en7581_clk_hw_init(struct platform_device *pdev,
+ 			      struct clk_hw_onecell_data *clk_data)
+ {
+-	void __iomem *np_base;
+ 	struct regmap *map;
++	void __iomem *base;
+ 	u32 val;
+ 
+ 	map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu");
+ 	if (IS_ERR(map))
+ 		return PTR_ERR(map);
+ 
+-	np_base = devm_platform_ioremap_resource(pdev, 0);
+-	if (IS_ERR(np_base))
+-		return PTR_ERR(np_base);
++	base = devm_platform_ioremap_resource(pdev, 0);
++	if (IS_ERR(base))
++		return PTR_ERR(base);
+ 
+-	en7581_register_clocks(&pdev->dev, clk_data, map, np_base);
++	en7581_register_clocks(&pdev->dev, clk_data, map, base);
+ 
+-	val = readl(np_base + REG_NP_SCU_SSTR);
++	val = readl(base + REG_NP_SCU_SSTR);
+ 	val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK);
+-	writel(val, np_base + REG_NP_SCU_SSTR);
+-	val = readl(np_base + REG_NP_SCU_PCIC);
+-	writel(val | 3, np_base + REG_NP_SCU_PCIC);
++	writel(val, base + REG_NP_SCU_SSTR);
++	val = readl(base + REG_NP_SCU_PCIC);
++	writel(val | 3, base + REG_NP_SCU_PCIC);
+ 
+-	return en7581_reset_register(pdev);
++	return en7581_reset_register(&pdev->dev, base);
+ }
+ 
+ static int en7523_clk_probe(struct platform_device *pdev)
+-- 
+2.39.5
+

+ 47 - 0
target/linux/econet/patches-6.12/014-v6.14-PCI-mediatek-gen3-Move-reset-delay-in-mtk_pcie_en758.patch

@@ -0,0 +1,47 @@
+From 90d4e466c9ea2010f33880a36317a8486ccbe082 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <[email protected]>
+Date: Wed, 8 Jan 2025 10:50:43 +0100
+Subject: [PATCH 1/3] PCI: mediatek-gen3: Move reset delay in
+ mtk_pcie_en7581_power_up()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal
+causing occasional PCIe link down issues. In order to overcome the
+problem, PCIe block is reset using REG_PCI_CONTROL (0x88) and
+REG_RESET_CONTROL (0x834) registers available in the clock module
+running clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up().
+
+In order to make the code more readable, move the wait for the time
+needed to complete the PCIe reset from en7581_pci_enable() to
+mtk_pcie_en7581_power_up().
+
+Reduce reset timeout from 250ms to the standard PCIE_T_PVPERL_MS value
+(100ms) since it has no impact on the driver behavior.
+
+Link: https://lore.kernel.org/r/[email protected]
+Signed-off-by: Lorenzo Bianconi <[email protected]>
+Signed-off-by: Krzysztof Wilczyński <[email protected]>
+Reviewed-by: AngeloGioacchino Del Regno <[email protected]>
+Reviewed-by: Manivannan Sadhasivam <[email protected]>
+Acked-by: Stephen Boyd <[email protected]>
+---
+ drivers/clk/clk-en7523.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
+index e52c5460e927..513730e5b953 100644
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -477,7 +477,6 @@ static int en7581_pci_enable(struct clk_hw *hw)
+ 	       REG_PCI_CONTROL_PERSTOUT;
+ 	val = readl(np_base + REG_PCI_CONTROL);
+ 	writel(val | mask, np_base + REG_PCI_CONTROL);
+-	msleep(250);
+ 
+ 	return 0;
+ }
+-- 
+2.39.5
+

+ 88 - 0
target/linux/econet/patches-6.12/015-v6.14-clk-en7523-Rework-clock-handling-for-different-clock.patch

@@ -0,0 +1,88 @@
+From e4a9748e7103c47e575459db2b6a77d14f34da2b Mon Sep 17 00:00:00 2001
+From: Christian Marangi <[email protected]>
+Date: Tue, 14 Jan 2025 00:10:02 +0100
+Subject: [PATCH 2/3] clk: en7523: Rework clock handling for different clock
+ numbers
+
+Airoha EN7581 SoC have additional clock compared to EN7523 but current
+driver permits to only support up to EN7523 clock numbers.
+
+To handle this, rework the clock handling and permit to declare the
+clocks number in match_data and alloca clk_data based on the compatible
+match_data.
+
+Signed-off-by: Christian Marangi <[email protected]>
+Link: https://lore.kernel.org/r/[email protected]
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ drivers/clk/clk-en7523.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
+index 495c0d607c7d..3a4b7ed40af4 100644
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -75,6 +75,7 @@ struct en_rst_data {
+ };
+ 
+ struct en_clk_soc_data {
++	u32 num_clocks;
+ 	const struct clk_ops pcie_ops;
+ 	int (*hw_init)(struct platform_device *pdev,
+ 		       struct clk_hw_onecell_data *clk_data);
+@@ -504,8 +505,6 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat
+ 	u32 rate;
+ 	int i;
+ 
+-	clk_data->num = EN7523_NUM_CLOCKS;
+-
+ 	for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
+ 		const struct en_clk_desc *desc = &en7523_base_clks[i];
+ 		u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg;
+@@ -587,8 +586,6 @@ static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_dat
+ 
+ 	hw = en7523_register_pcie_clk(dev, base);
+ 	clk_data->hws[EN7523_CLK_PCIE] = hw;
+-
+-	clk_data->num = EN7523_NUM_CLOCKS;
+ }
+ 
+ static int en7523_reset_update(struct reset_controller_dev *rcdev,
+@@ -702,13 +699,15 @@ static int en7523_clk_probe(struct platform_device *pdev)
+ 	struct clk_hw_onecell_data *clk_data;
+ 	int r;
+ 
++	soc_data = device_get_match_data(&pdev->dev);
++
+ 	clk_data = devm_kzalloc(&pdev->dev,
+-				struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
++				struct_size(clk_data, hws, soc_data->num_clocks),
+ 				GFP_KERNEL);
+ 	if (!clk_data)
+ 		return -ENOMEM;
+ 
+-	soc_data = device_get_match_data(&pdev->dev);
++	clk_data->num = soc_data->num_clocks;
+ 	r = soc_data->hw_init(pdev, clk_data);
+ 	if (r)
+ 		return r;
+@@ -717,6 +716,7 @@ static int en7523_clk_probe(struct platform_device *pdev)
+ }
+ 
+ static const struct en_clk_soc_data en7523_data = {
++	.num_clocks = ARRAY_SIZE(en7523_base_clks) + 1,
+ 	.pcie_ops = {
+ 		.is_enabled = en7523_pci_is_enabled,
+ 		.prepare = en7523_pci_prepare,
+@@ -726,6 +726,8 @@ static const struct en_clk_soc_data en7523_data = {
+ };
+ 
+ static const struct en_clk_soc_data en7581_data = {
++	/* We increment num_clocks by 1 to account for additional PCIe clock */
++	.num_clocks = ARRAY_SIZE(en7581_base_clks) + 1,
+ 	.pcie_ops = {
+ 		.is_enabled = en7581_pci_is_enabled,
+ 		.enable = en7581_pci_enable,
+-- 
+2.39.5
+

+ 46 - 0
target/linux/econet/patches-6.12/016-v6.14-clk-en7523-Add-clock-for-eMMC-for-EN7581.patch

@@ -0,0 +1,46 @@
+From bfe257f9780d8f77045a7da6ec959ee0659d2f98 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <[email protected]>
+Date: Tue, 14 Jan 2025 00:10:05 +0100
+Subject: [PATCH 3/3] clk: en7523: Add clock for eMMC for EN7581
+
+Add clock for eMMC for EN7581. This is used to give info of the current
+eMMC source clock and to switch it from 200MHz or 150MHz.
+
+Signed-off-by: Christian Marangi <[email protected]>
+Link: https://lore.kernel.org/r/[email protected]
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ drivers/clk/clk-en7523.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
+index 3a4b7ed40af4..6a763bc9ac1a 100644
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -91,6 +91,7 @@ static const u32 emi7581_base[] = { 540000000, 480000000, 400000000, 300000000 }
+ static const u32 bus7581_base[] = { 600000000, 540000000 };
+ static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 };
+ static const u32 crypto_base[] = { 540000000, 480000000 };
++static const u32 emmc7581_base[] = { 200000000, 150000000 };
+ 
+ static const struct en_clk_desc en7523_base_clks[] = {
+ 	{
+@@ -281,6 +282,15 @@ static const struct en_clk_desc en7581_base_clks[] = {
+ 		.base_shift = 0,
+ 		.base_values = crypto_base,
+ 		.n_base_values = ARRAY_SIZE(crypto_base),
++	}, {
++		.id = EN7581_CLK_EMMC,
++		.name = "emmc",
++
++		.base_reg = REG_CRYPTO_CLKSRC2,
++		.base_bits = 1,
++		.base_shift = 12,
++		.base_values = emmc7581_base,
++		.n_base_values = ARRAY_SIZE(emmc7581_base),
+ 	}
+ };
+ 
+-- 
+2.39.5
+

+ 138 - 0
target/linux/econet/patches-6.12/017-v6.19rc1-clk-en7523-Add-reset-controller-support-for-EN7523-S.patch

@@ -0,0 +1,138 @@
+From 1c0608d860db973ad09b5a9ccb19b76ae07622a3 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <[email protected]>
+Date: Mon, 10 Nov 2025 06:56:44 +0300
+Subject: [PATCH] clk: en7523: Add reset-controller support for EN7523 SoC
+
+Introduce reset API support to EN7523 clock driver. EN7523 uses the
+same reset logic as EN7581, so just reuse existing code.
+
+Signed-off-by: Mikhail Kshevetskiy <[email protected]>
+Reviewed-by: AngeloGioacchino Del Regno <[email protected]>
+Reviewed-by: Philipp Zabel <[email protected]>
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ drivers/clk/clk-en7523.c | 64 ++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 59 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
+index 15bbdeb60b8e..08cc8e5acf43 100644
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -9,6 +9,7 @@
+ #include <linux/regmap.h>
+ #include <linux/reset-controller.h>
+ #include <dt-bindings/clock/en7523-clk.h>
++#include <dt-bindings/reset/airoha,en7523-reset.h>
+ #include <dt-bindings/reset/airoha,en7581-reset.h>
+ 
+ #define RST_NR_PER_BANK			32
+@@ -299,6 +300,53 @@ static const u16 en7581_rst_ofs[] = {
+ 	REG_RST_CTRL1,
+ };
+ 
++static const u16 en7523_rst_map[] = {
++	/* RST_CTRL2 */
++	[EN7523_XPON_PHY_RST]		= 0,
++	[EN7523_XSI_MAC_RST]		= 7,
++	[EN7523_XSI_PHY_RST]		= 8,
++	[EN7523_NPU_RST]		= 9,
++	[EN7523_I2S_RST]		= 10,
++	[EN7523_TRNG_RST]		= 11,
++	[EN7523_TRNG_MSTART_RST]	= 12,
++	[EN7523_DUAL_HSI0_RST]		= 13,
++	[EN7523_DUAL_HSI1_RST]		= 14,
++	[EN7523_HSI_RST]		= 15,
++	[EN7523_DUAL_HSI0_MAC_RST]	= 16,
++	[EN7523_DUAL_HSI1_MAC_RST]	= 17,
++	[EN7523_HSI_MAC_RST]		= 18,
++	[EN7523_WDMA_RST]		= 19,
++	[EN7523_WOE0_RST]		= 20,
++	[EN7523_WOE1_RST]		= 21,
++	[EN7523_HSDMA_RST]		= 22,
++	[EN7523_I2C2RBUS_RST]		= 23,
++	[EN7523_TDMA_RST]		= 24,
++	/* RST_CTRL1 */
++	[EN7523_PCM1_ZSI_ISI_RST]	= RST_NR_PER_BANK + 0,
++	[EN7523_FE_PDMA_RST]		= RST_NR_PER_BANK + 1,
++	[EN7523_FE_QDMA_RST]		= RST_NR_PER_BANK + 2,
++	[EN7523_PCM_SPIWP_RST]		= RST_NR_PER_BANK + 4,
++	[EN7523_CRYPTO_RST]		= RST_NR_PER_BANK + 6,
++	[EN7523_TIMER_RST]		= RST_NR_PER_BANK + 8,
++	[EN7523_PCM1_RST]		= RST_NR_PER_BANK + 11,
++	[EN7523_UART_RST]		= RST_NR_PER_BANK + 12,
++	[EN7523_GPIO_RST]		= RST_NR_PER_BANK + 13,
++	[EN7523_GDMA_RST]		= RST_NR_PER_BANK + 14,
++	[EN7523_I2C_MASTER_RST]		= RST_NR_PER_BANK + 16,
++	[EN7523_PCM2_ZSI_ISI_RST]	= RST_NR_PER_BANK + 17,
++	[EN7523_SFC_RST]		= RST_NR_PER_BANK + 18,
++	[EN7523_UART2_RST]		= RST_NR_PER_BANK + 19,
++	[EN7523_GDMP_RST]		= RST_NR_PER_BANK + 20,
++	[EN7523_FE_RST]			= RST_NR_PER_BANK + 21,
++	[EN7523_USB_HOST_P0_RST]	= RST_NR_PER_BANK + 22,
++	[EN7523_GSW_RST]		= RST_NR_PER_BANK + 23,
++	[EN7523_SFC2_PCM_RST]		= RST_NR_PER_BANK + 25,
++	[EN7523_PCIE0_RST]		= RST_NR_PER_BANK + 26,
++	[EN7523_PCIE1_RST]		= RST_NR_PER_BANK + 27,
++	[EN7523_PCIE_HB_RST]		= RST_NR_PER_BANK + 29,
++	[EN7523_XPON_MAC_RST]		= RST_NR_PER_BANK + 31,
++};
++
+ static const u16 en7581_rst_map[] = {
+ 	/* RST_CTRL2 */
+ 	[EN7581_XPON_PHY_RST]		= 0,
+@@ -357,6 +405,9 @@ static const u16 en7581_rst_map[] = {
+ 	[EN7581_XPON_MAC_RST]		= RST_NR_PER_BANK + 31,
+ };
+ 
++static int en7581_reset_register(struct device *dev, void __iomem *base,
++				 const u16 *rst_map, int nr_resets);
++
+ static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val)
+ {
+ 	if (!desc->base_bits)
+@@ -552,7 +603,8 @@ static int en7523_clk_hw_init(struct platform_device *pdev,
+ 
+ 	en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
+ 
+-	return 0;
++	return en7581_reset_register(&pdev->dev, np_base, en7523_rst_map,
++				     ARRAY_SIZE(en7523_rst_map));
+ }
+ 
+ static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
+@@ -652,7 +704,8 @@ static const struct reset_control_ops en7581_reset_ops = {
+ 	.status = en7523_reset_status,
+ };
+ 
+-static int en7581_reset_register(struct device *dev, void __iomem *base)
++static int en7581_reset_register(struct device *dev, void __iomem *base,
++				 const u16 *rst_map, int nr_resets)
+ {
+ 	struct en_rst_data *rst_data;
+ 
+@@ -661,10 +714,10 @@ static int en7581_reset_register(struct device *dev, void __iomem *base)
+ 		return -ENOMEM;
+ 
+ 	rst_data->bank_ofs = en7581_rst_ofs;
+-	rst_data->idx_map = en7581_rst_map;
++	rst_data->idx_map = rst_map;
+ 	rst_data->base = base;
+ 
+-	rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map);
++	rst_data->rcdev.nr_resets = nr_resets;
+ 	rst_data->rcdev.of_xlate = en7523_reset_xlate;
+ 	rst_data->rcdev.ops = &en7581_reset_ops;
+ 	rst_data->rcdev.of_node = dev->of_node;
+@@ -698,7 +751,8 @@ static int en7581_clk_hw_init(struct platform_device *pdev,
+ 	val = readl(base + REG_NP_SCU_PCIC);
+ 	writel(val | 3, base + REG_NP_SCU_PCIC);
+ 
+-	return en7581_reset_register(&pdev->dev, base);
++	return en7581_reset_register(&pdev->dev, base, en7581_rst_map,
++				     ARRAY_SIZE(en7581_rst_map));
+ }
+ 
+ static int en7523_clk_probe(struct platform_device *pdev)
+-- 
+2.39.5
+

+ 40 - 0
target/linux/econet/patches-6.12/018-v6.19rc1-dt-bindings-clock-airoha-Add-reset-support-to-EN7523.patch

@@ -0,0 +1,40 @@
+From 947643509279a605a09959a06d332bf027e8be57 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <[email protected]>
+Date: Mon, 10 Nov 2025 06:56:43 +0300
+Subject: [PATCH] dt-bindings: clock: airoha: Add reset support to EN7523 clock
+ binding
+
+Introduce reset capability to EN7523 device-tree clock binding
+documentation.
+
+Signed-off-by: Mikhail Kshevetskiy <[email protected]>
+Reviewed-by: Rob Herring (Arm) <[email protected]>
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+index fe2c5c1baf43..a8471367175b 100644
+--- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
++++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+@@ -64,8 +64,6 @@ allOf:
+         reg:
+           minItems: 2
+ 
+-        '#reset-cells': false
+-
+   - if:
+       properties:
+         compatible:
+@@ -85,6 +83,7 @@ examples:
+       reg = <0x1fa20000 0x400>,
+             <0x1fb00000 0x1000>;
+       #clock-cells = <1>;
++      #reset-cells = <1>;
+     };
+ 
+   - |
+-- 
+2.39.5
+

+ 79 - 0
target/linux/econet/patches-6.12/019-v6.13-dt-bindings-clock-airoha-Update-reg-mapping-for-EN75.patch

@@ -0,0 +1,79 @@
+From 0f7c637d1103d79829dec198e5f1b678c1feb5f2 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <[email protected]>
+Date: Tue, 12 Nov 2024 01:08:48 +0100
+Subject: [PATCH] dt-bindings: clock: airoha: Update reg mapping for EN7581
+ SoC.
+
+clk-en7523 driver for EN7581 SoC is mapping all the scu memory region
+while it is configuring the chip-scu one via a syscon. Update the reg
+mapping definition for this device. This patch does not introduce any
+backward incompatibility since the dts for EN7581 SoC is not upstream
+yet.
+
+Signed-off-by: Lorenzo Bianconi <[email protected]>
+Link: https://lore.kernel.org/r/[email protected]
+Reviewed-by: Rob Herring (Arm) <[email protected]>
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ .../bindings/clock/airoha,en7523-scu.yaml     | 23 +++++++------------
+ 1 file changed, 8 insertions(+), 15 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+index 84353fd09428..fe2c5c1baf43 100644
+--- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
++++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+@@ -34,8 +34,10 @@ properties:
+           - airoha,en7581-scu
+ 
+   reg:
+-    minItems: 2
+-    maxItems: 4
++    items:
++      - description: scu base address
++      - description: misc scu base address
++    minItems: 1
+ 
+   "#clock-cells":
+     description:
+@@ -60,9 +62,7 @@ allOf:
+     then:
+       properties:
+         reg:
+-          items:
+-            - description: scu base address
+-            - description: misc scu base address
++          minItems: 2
+ 
+         '#reset-cells': false
+ 
+@@ -73,11 +73,7 @@ allOf:
+     then:
+       properties:
+         reg:
+-          items:
+-            - description: scu base address
+-            - description: misc scu base address
+-            - description: reset base address
+-            - description: pb scu base address
++          maxItems: 1
+ 
+ additionalProperties: false
+ 
+@@ -96,12 +92,9 @@ examples:
+       #address-cells = <2>;
+       #size-cells = <2>;
+ 
+-      scuclk: clock-controller@1fa20000 {
++      scuclk: clock-controller@1fb00000 {
+         compatible = "airoha,en7581-scu";
+-        reg = <0x0 0x1fa20000 0x0 0x400>,
+-              <0x0 0x1fb00000 0x0 0x90>,
+-              <0x0 0x1fb00830 0x0 0x8>,
+-              <0x0 0x1fbe3400 0x0 0xfc>;
++        reg = <0x0 0x1fb00000 0x0 0x970>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+       };
+-- 
+2.39.5
+

+ 87 - 0
target/linux/econet/patches-6.12/020-v6.19rc1-dt-bindings-clock-airoha-Add-reset-support-to-EN7523.patch

@@ -0,0 +1,87 @@
+From 947643509279a605a09959a06d332bf027e8be57 Mon Sep 17 00:00:00 2001
+From: Mikhail Kshevetskiy <[email protected]>
+Date: Mon, 10 Nov 2025 06:56:43 +0300
+Subject: [PATCH] dt-bindings: clock: airoha: Add reset support to EN7523 clock
+ binding
+
+Introduce reset capability to EN7523 device-tree clock binding
+documentation.
+
+Signed-off-by: Mikhail Kshevetskiy <[email protected]>
+Reviewed-by: Rob Herring (Arm) <[email protected]>
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ .../dt-bindings/reset/airoha,en7523-reset.h   | 61 +++++++++++++++++++
+ 1 file changed, 61 insertions(+)
+ create mode 100644 include/dt-bindings/reset/airoha,en7523-reset.h
+
+diff --git a/include/dt-bindings/reset/airoha,en7523-reset.h b/include/dt-bindings/reset/airoha,en7523-reset.h
+new file mode 100644
+index 000000000000..211e8a23a21c
+--- /dev/null
++++ b/include/dt-bindings/reset/airoha,en7523-reset.h
+@@ -0,0 +1,61 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2024 iopsys Software Solutions AB.
++ * Copyright (C) 2025 Genexis AB.
++ *
++ * Author: Mikhail Kshevetskiy <[email protected]>
++ *
++ * based on
++ *   include/dt-bindings/reset/airoha,en7581-reset.h
++ * by Lorenzo Bianconi <[email protected]>
++ */
++
++#ifndef __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_
++#define __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_
++
++/* RST_CTRL2 */
++#define EN7523_XPON_PHY_RST		 0
++#define EN7523_XSI_MAC_RST		 1
++#define EN7523_XSI_PHY_RST		 2
++#define EN7523_NPU_RST			 3
++#define EN7523_I2S_RST			 4
++#define EN7523_TRNG_RST			 5
++#define EN7523_TRNG_MSTART_RST		 6
++#define EN7523_DUAL_HSI0_RST		 7
++#define EN7523_DUAL_HSI1_RST		 8
++#define EN7523_HSI_RST			 9
++#define EN7523_DUAL_HSI0_MAC_RST	10
++#define EN7523_DUAL_HSI1_MAC_RST	11
++#define EN7523_HSI_MAC_RST		12
++#define EN7523_WDMA_RST			13
++#define EN7523_WOE0_RST			14
++#define EN7523_WOE1_RST			15
++#define EN7523_HSDMA_RST		16
++#define EN7523_I2C2RBUS_RST		17
++#define EN7523_TDMA_RST			18
++/* RST_CTRL1 */
++#define EN7523_PCM1_ZSI_ISI_RST		19
++#define EN7523_FE_PDMA_RST		20
++#define EN7523_FE_QDMA_RST		21
++#define EN7523_PCM_SPIWP_RST		22
++#define EN7523_CRYPTO_RST		23
++#define EN7523_TIMER_RST		24
++#define EN7523_PCM1_RST			25
++#define EN7523_UART_RST			26
++#define EN7523_GPIO_RST			27
++#define EN7523_GDMA_RST			28
++#define EN7523_I2C_MASTER_RST		29
++#define EN7523_PCM2_ZSI_ISI_RST		30
++#define EN7523_SFC_RST			31
++#define EN7523_UART2_RST		32
++#define EN7523_GDMP_RST			33
++#define EN7523_FE_RST			34
++#define EN7523_USB_HOST_P0_RST		35
++#define EN7523_GSW_RST			36
++#define EN7523_SFC2_PCM_RST		37
++#define EN7523_PCIE0_RST		38
++#define EN7523_PCIE1_RST		39
++#define EN7523_PCIE_HB_RST		40
++#define EN7523_XPON_MAC_RST		41
++
++#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7523_H_ */
+-- 
+2.39.5
+

+ 31 - 0
target/linux/econet/patches-6.12/021-v6.14-dt-bindings-clock-drop-NUM_CLOCKS-define-for-EN7581.patch

@@ -0,0 +1,31 @@
+From 02d3b7557ce28c373ea1e925ae16ab5988284313 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <[email protected]>
+Date: Tue, 14 Jan 2025 00:10:03 +0100
+Subject: [PATCH 1/2] dt-bindings: clock: drop NUM_CLOCKS define for EN7581
+
+Drop NUM_CLOCKS define for EN7581 include. This is not a binding and
+should not be placed here. Value is derived internally in the user
+driver.
+
+Signed-off-by: Christian Marangi <[email protected]>
+Acked-by: Krzysztof Kozlowski <[email protected]>
+Link: https://lore.kernel.org/r/[email protected]
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ include/dt-bindings/clock/en7523-clk.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/include/dt-bindings/clock/en7523-clk.h b/include/dt-bindings/clock/en7523-clk.h
+index 717d23a5e5ae..28e56745ccff 100644
+--- a/include/dt-bindings/clock/en7523-clk.h
++++ b/include/dt-bindings/clock/en7523-clk.h
+@@ -12,6 +12,4 @@
+ #define EN7523_CLK_CRYPTO	6
+ #define EN7523_CLK_PCIE		7
+ 
+-#define EN7523_NUM_CLOCKS	8
+-
+ #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */
+-- 
+2.39.5
+

+ 30 - 0
target/linux/econet/patches-6.12/022-v6.14-dt-bindings-clock-add-ID-for-eMMC-for-EN7581.patch

@@ -0,0 +1,30 @@
+From 82108ad3285f58f314ad41398f44017c7dbe44de Mon Sep 17 00:00:00 2001
+From: Christian Marangi <[email protected]>
+Date: Tue, 14 Jan 2025 00:10:04 +0100
+Subject: [PATCH 2/2] dt-bindings: clock: add ID for eMMC for EN7581
+
+Add ID for eMMC for EN7581. This is to control clock selection of eMMC
+between 200MHz and 150MHz.
+
+Signed-off-by: Christian Marangi <[email protected]>
+Acked-by: Conor Dooley <[email protected]>
+Link: https://lore.kernel.org/r/[email protected]
+Signed-off-by: Stephen Boyd <[email protected]>
+---
+ include/dt-bindings/clock/en7523-clk.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/dt-bindings/clock/en7523-clk.h b/include/dt-bindings/clock/en7523-clk.h
+index 28e56745ccff..edfa64045f52 100644
+--- a/include/dt-bindings/clock/en7523-clk.h
++++ b/include/dt-bindings/clock/en7523-clk.h
+@@ -12,4 +12,6 @@
+ #define EN7523_CLK_CRYPTO	6
+ #define EN7523_CLK_PCIE		7
+ 
++#define EN7581_CLK_EMMC		8
++
+ #endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */
+-- 
+2.39.5
+

+ 176 - 0
target/linux/econet/patches-6.12/910-dt-bindings-clock-reset-add-econet-en751221-bindings.patch

@@ -0,0 +1,176 @@
+From f3fa5911b1f094e164c497f7b10d94d92852e285 Mon Sep 17 00:00:00 2001
+From: Caleb James DeLisle <[email protected]>
+Date: Wed, 14 Jan 2026 17:54:05 +0000
+Subject: [PATCH] dt-bindings: clock, reset: Add econet EN751221 bindings
+
+Add clock and reset bindings for EN751221 based on the Airoha EN7523 SCU
+driver.
+
+Signed-off-by: Caleb James DeLisle <[email protected]>
+---
+The EN751221 has the same bifurcation of SCU as EN7581 so we use
+the same chip-scu as airoha,en7581-chip-scu.
+---
+ .../bindings/clock/airoha,en7523-scu.yaml     | 17 +++++++-
+ .../mips/econet,en751221-chip-scu.yaml        | 42 +++++++++++++++++++
+ .../dt-bindings/clock/econet,en751221-scu.h   | 14 +++++++
+ .../dt-bindings/reset/econet,en751221-scu.h   | 41 ++++++++++++++++++
+ 4 files changed, 113 insertions(+), 1 deletion(-)
+ create mode 100644 Documentation/devicetree/bindings/mips/econet,en751221-chip-scu.yaml
+ create mode 100644 include/dt-bindings/clock/econet,en751221-scu.h
+ create mode 100644 include/dt-bindings/reset/econet,en751221-scu.h
+
+--- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
++++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+@@ -32,6 +32,7 @@ properties:
+       - enum:
+           - airoha,en7523-scu
+           - airoha,en7581-scu
++          - econet,en751221-scu
+ 
+   reg:
+     items:
+@@ -67,7 +68,10 @@ allOf:
+   - if:
+       properties:
+         compatible:
+-          const: airoha,en7581-scu
++          items:
++            - enum:
++                - airoha,en7581-scu
++                - econet,en751221-scu
+     then:
+       properties:
+         reg:
+@@ -98,3 +102,14 @@ examples:
+               #reset-cells = <1>;
+       };
+     };
++
++  - |
++    soc {
++      #address-cells = <1>;
++      #size-cells = <1>;
++
++      scuclk: clock-controller@1fb00000 {
++        compatible = "econet,en751221-scu";
++        reg = <0x1fb00000 0x970>;
++      };
++    };
+\ No newline at end of file
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mips/econet,en751221-chip-scu.yaml
+@@ -0,0 +1,42 @@
++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/arm/airoha,en7581-chip-scu.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: EcoNet Chip SCU Controller for EN751221 SoC
++
++maintainers:
++  - Caleb James DeLisle <[email protected]>
++
++description:
++  The EcoNet chip-scu block provides a configuration interface for clock,
++  io-muxing and other functionalities used by multiple controllers (e.g. clock,
++  pinctrl, ecc) on EN751221 SoC.
++
++properties:
++  compatible:
++    items:
++      - enum:
++          - econet,en751221-chip-scu
++      - const: syscon
++
++  reg:
++    maxItems: 1
++
++required:
++  - compatible
++  - reg
++
++additionalProperties: false
++
++examples:
++  - |
++    soc {
++      #address-cells = <1>;
++      #size-cells = <1>;
++      syscon@1fa20000 {
++        compatible = "econet,en751221-chip-scu", "syscon";
++        reg = <0x1fa20000 0x388>;
++      };
++    };
+--- /dev/null
++++ b/include/dt-bindings/clock/econet,en751221-scu.h
+@@ -0,0 +1,15 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++
++#ifndef _DT_BINDINGS_CLOCK_ECONET_EN751221_SCU_H_
++#define _DT_BINDINGS_CLOCK_ECONET_EN751221_SCU_H_
++
++#define EN751221_CLK_PCIE	0
++#define EN751221_CLK_SPI	1
++#define EN751221_CLK_BUS	2
++#define EN751221_CLK_CPU	3
++#define EN751221_CLK_HPT	4
++#define EN751221_CLK_GSW	5
++
++#define EN751221_MAX_CLKS	6
++
++#endif /* _DT_BINDINGS_CLOCK_ECONET_EN751221_SCU_H_ */
+\ No newline at end of file
+--- /dev/null
++++ b/include/dt-bindings/reset/econet,en751221-scu.h
+@@ -0,0 +1,49 @@
++/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
++
++#ifndef __DT_BINDINGS_RESET_CONTROLLER_ECONET_EN751221_H_
++#define __DT_BINDINGS_RESET_CONTROLLER_ECONET_EN751221_H_
++
++#define EN751221_XPON_PHY_RST		 0
++#define EN751221_PCM1_ZSI_ISI_RST	 1
++#define EN751221_FE_QDMA1_RST		 2
++#define EN751221_FE_QDMA2_RST		 3
++#define EN751221_FE_UNZIP_RST		 4
++#define EN751221_PCM2_RST		 5
++#define EN751221_PTM_MAC_RST		 6
++#define EN751221_CRYPTO_RST		 7
++#define EN751221_SAR_RST		 8
++#define EN751221_TIMER_RST		 9
++#define EN751221_INTC_RST		10
++#define EN751221_BONDING_RST		11
++#define EN751221_PCM1_RST		12
++#define EN751221_UART_RST		13
++#define EN751221_GPIO_RST		14
++#define EN751221_GDMA_RST		15
++#define EN751221_I2C_MASTER_RST		16
++#define EN751221_PCM2_ZSI_ISI_RST	17
++#define EN751221_SFC_RST		18
++#define EN751221_UART2_RST		19
++#define EN751221_GDMP_RST		20
++#define EN751221_FE_RST			21
++#define EN751221_USB_HOST_P0_RST	22
++#define EN751221_GSW_RST		23
++#define EN751221_SFC2_PCM_RST		24
++#define EN751221_PCIE0_RST		25
++#define EN751221_PCIE1_RST		26
++#define EN751221_CPU_TIMER_RST		27
++#define EN751221_PCIE_HB_RST		28
++#define EN751221_SIMIF_RST		29
++#define EN751221_XPON_MAC_RST		30
++#define EN751221_GFAST_RST		31
++#define EN751221_CPU_TIMER2_RST		32
++#define EN751221_UART3_RST		33
++#define EN751221_UART4_RST		34
++#define EN751221_UART5_RST		35
++#define EN751221_I2C2_RST		36
++#define EN751221_XSI_MAC_RST		37
++#define EN751221_XSI_PHY_RST		38
++#define EN751221_DMT_RST		39
++#define EN751221_USB_PHY_P0_RST		40
++#define EN751221_USB_PHY_P1_RST		41
++
++#endif /* __DT_BINDINGS_RESET_CONTROLLER_ECONET_EN751221_H_ */

+ 364 - 0
target/linux/econet/patches-6.12/911-clk-airoha-add-econet-en751221-clock-reset-support-t.patch

@@ -0,0 +1,364 @@
+From 1dfb29374a040ba80d378b3465f4e0bcb67f4ba3 Mon Sep 17 00:00:00 2001
+From: Caleb James DeLisle <[email protected]>
+Date: Wed, 14 Jan 2026 18:06:13 +0000
+Subject: [PATCH] clk: airoha: Add econet EN751221 clock/reset support to
+ en7523-scu
+
+EcoNet EN751221 clock/reset driver is significantly similar to the
+EN7523 / EN7581, however the EN751221 does not have a neat batch of clock
+divider registers so there are fewer known clocks, and the frequency of
+each clock is derived differently. This clock driver will probably work
+correctly on EN751627, EN7528, and EN7580.
+
+Signed-off-by: Caleb James DeLisle <[email protected]>
+---
+ drivers/clk/Kconfig      |   6 +-
+ drivers/clk/clk-en7523.c | 182 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 185 insertions(+), 3 deletions(-)
+
+--- a/drivers/clk/Kconfig
++++ b/drivers/clk/Kconfig
+@@ -210,13 +210,13 @@ config COMMON_CLK_CS2000_CP
+ 	  If you say yes here you get support for the CS2000 clock multiplier.
+ 
+ config COMMON_CLK_EN7523
+-	bool "Clock driver for Airoha EN7523 SoC system clocks"
++	bool "Clock driver for Airoha/EcoNet SoC system clocks"
+ 	depends on OF
+-	depends on ARCH_AIROHA || COMPILE_TEST
++	depends on ARCH_AIROHA || ECONET || COMPILE_TEST
+ 	default ARCH_AIROHA
+ 	help
+ 	  This driver provides the fixed clocks and gates present on Airoha
+-	  ARM silicon.
++	  and EcoNet silicon.
+ 
+ config COMMON_CLK_EP93XX
+ 	tristate "Clock driver for Cirrus Logic ep93xx SoC"
+--- a/drivers/clk/clk-en7523.c
++++ b/drivers/clk/clk-en7523.c
+@@ -1,5 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ 
++#include <linux/bitfield.h>
+ #include <linux/delay.h>
+ #include <linux/clk-provider.h>
+ #include <linux/io.h>
+@@ -11,6 +12,8 @@
+ #include <dt-bindings/clock/en7523-clk.h>
+ #include <dt-bindings/reset/airoha,en7523-reset.h>
+ #include <dt-bindings/reset/airoha,en7581-reset.h>
++#include <dt-bindings/clock/econet,en751221-scu.h>
++#include <dt-bindings/reset/econet,en751221-scu.h>
+ 
+ #define RST_NR_PER_BANK			32
+ 
+@@ -33,15 +36,47 @@
+ #define   REG_RESET_CONTROL_PCIEHB	BIT(29)
+ #define   REG_RESET_CONTROL_PCIE1	BIT(27)
+ #define   REG_RESET_CONTROL_PCIE2	BIT(26)
++#define REG_HIR				0x064
++#define   REG_HIR_MASK			GENMASK(31, 16)
+ /* EN7581 */
+ #define REG_NP_SCU_PCIC			0x88
+ #define REG_NP_SCU_SSTR			0x9c
+ #define REG_PCIE_XSI0_SEL_MASK		GENMASK(14, 13)
+ #define REG_PCIE_XSI1_SEL_MASK		GENMASK(12, 11)
+ #define REG_CRYPTO_CLKSRC2		0x20c
++/* EN751221 */
++#define EN751221_REG_SPI_DIV		0x0cc
++#define EN751221_REG_SPI_DIV_MASK	GENMASK(31,8)
++#define EN751221_SPI_BASE		500000000
++#define EN751221_SPI_BASE_EN7526C	400000000
++#define EN751221_REG_BUS		0x284
++#define EN751221_REG_BUS_MASK		GENMASK(21,12)
++#define EN751221_REG_SSR3		0x094
++#define EN751221_REG_SSR3_GSW_MASK	GENMASK(9,8)
+ 
+ #define REG_RST_CTRL2			0x830
+ #define REG_RST_CTRL1			0x834
++#define EN751221_REG_RST_DMT		0x84
++#define EN751221_REG_RST_USB		0xec
++
++enum en_hir {
++	HIR_UNKNOWN	= -1,
++	HIR_TC3169	= 0,
++	HIR_TC3182	= 1,
++	HIR_RT65168	= 2,
++	HIR_RT63165	= 3,
++	HIR_RT63365	= 4,
++	HIR_MT751020	= 5,
++	HIR_MT7505	= 6,
++	HIR_EN751221	= 7,
++	HIR_EN7526C	= 8,
++	HIR_EN751627	= 9,
++	HIR_EN7580	= 10,
++	HIR_EN7528	= 11,
++	HIR_EN7523	= 12,
++	HIR_EN7581	= 13,
++	HIR_MAX		= 14,
++};
+ 
+ struct en_clk_desc {
+ 	int id;
+@@ -93,6 +128,8 @@ static const u32 bus7581_base[] = { 6000
+ static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 };
+ static const u32 crypto_base[] = { 540000000, 480000000 };
+ static const u32 emmc7581_base[] = { 200000000, 150000000 };
++/* EN751221 */
++static const u32 gsw751221_base[] = { 500000000, 250000000, 400000000, 200000000 };
+ 
+ static const struct en_clk_desc en7523_base_clks[] = {
+ 	{
+@@ -300,6 +337,13 @@ static const u16 en7581_rst_ofs[] = {
+ 	REG_RST_CTRL1,
+ };
+ 
++static const u16 en751221_rst_ofs[] = {
++	REG_RST_CTRL2,
++	REG_RST_CTRL1,
++	EN751221_REG_RST_DMT,
++	EN751221_REG_RST_USB,
++};
++
+ static const u16 en7523_rst_map[] = {
+ 	/* RST_CTRL2 */
+ 	[EN7523_XPON_PHY_RST]		= 0,
+@@ -405,8 +449,61 @@ static const u16 en7581_rst_map[] = {
+ 	[EN7581_XPON_MAC_RST]		= RST_NR_PER_BANK + 31,
+ };
+ 
++static const u16 en751221_rst_map[] = {
++	/* RST_CTRL2 */
++	[EN751221_XPON_PHY_RST]		= 0,
++	[EN751221_GFAST_RST]		= 1,
++	[EN751221_CPU_TIMER2_RST]	= 2,
++	[EN751221_UART3_RST]		= 3,
++	[EN751221_UART4_RST]		= 4,
++	[EN751221_UART5_RST]		= 5,
++	[EN751221_I2C2_RST]		= 6,
++	[EN751221_XSI_MAC_RST]		= 7,
++	[EN751221_XSI_PHY_RST]		= 8,
++
++	/* RST_CTRL1 */
++	[EN751221_PCM1_ZSI_ISI_RST]	= RST_NR_PER_BANK + 0,
++	[EN751221_FE_QDMA1_RST]		= RST_NR_PER_BANK + 1,
++	[EN751221_FE_QDMA2_RST]		= RST_NR_PER_BANK + 2,
++	[EN751221_FE_UNZIP_RST]		= RST_NR_PER_BANK + 3,
++	[EN751221_PCM2_RST]		= RST_NR_PER_BANK + 4,
++	[EN751221_PTM_MAC_RST]		= RST_NR_PER_BANK + 5,
++	[EN751221_CRYPTO_RST]		= RST_NR_PER_BANK + 6,
++	[EN751221_SAR_RST]		= RST_NR_PER_BANK + 7,
++	[EN751221_TIMER_RST]		= RST_NR_PER_BANK + 8,
++	[EN751221_INTC_RST]		= RST_NR_PER_BANK + 9,
++	[EN751221_BONDING_RST]		= RST_NR_PER_BANK + 10,
++	[EN751221_PCM1_RST]		= RST_NR_PER_BANK + 11,
++	[EN751221_UART_RST]		= RST_NR_PER_BANK + 12,
++	[EN751221_GPIO_RST]		= RST_NR_PER_BANK + 13,
++	[EN751221_GDMA_RST]		= RST_NR_PER_BANK + 14,
++	[EN751221_I2C_MASTER_RST]	= RST_NR_PER_BANK + 16,
++	[EN751221_PCM2_ZSI_ISI_RST]	= RST_NR_PER_BANK + 17,
++	[EN751221_SFC_RST]		= RST_NR_PER_BANK + 18,
++	[EN751221_UART2_RST]		= RST_NR_PER_BANK + 19,
++	[EN751221_GDMP_RST]		= RST_NR_PER_BANK + 20,
++	[EN751221_FE_RST]		= RST_NR_PER_BANK + 21,
++	[EN751221_USB_HOST_P0_RST]	= RST_NR_PER_BANK + 22,
++	[EN751221_GSW_RST]		= RST_NR_PER_BANK + 23,
++	[EN751221_SFC2_PCM_RST]		= RST_NR_PER_BANK + 25,
++	[EN751221_PCIE0_RST]		= RST_NR_PER_BANK + 26,
++	[EN751221_PCIE1_RST]		= RST_NR_PER_BANK + 27,
++	[EN751221_CPU_TIMER_RST]	= RST_NR_PER_BANK + 28,
++	[EN751221_PCIE_HB_RST]		= RST_NR_PER_BANK + 29,
++	[EN751221_SIMIF_RST]		= RST_NR_PER_BANK + 30,
++	[EN751221_XPON_MAC_RST]		= RST_NR_PER_BANK + 31,
++
++	/* RST_DMT */
++	[EN751221_DMT_RST]		= 2 * RST_NR_PER_BANK + 0,
++
++	/* RST_USB */
++	[EN751221_USB_PHY_P0_RST]	= 3 * RST_NR_PER_BANK + 6,
++	[EN751221_USB_PHY_P1_RST]	= 3 * RST_NR_PER_BANK + 7,
++};
++
+ static int en7581_reset_register(struct device *dev, void __iomem *base,
+-				 const u16 *rst_map, int nr_resets);
++				 const u16 *rst_map, int nr_resets,
++				 const u16 *rst_reg_ofs);
+ 
+ static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val)
+ {
+@@ -604,7 +701,8 @@ static int en7523_clk_hw_init(struct pla
+ 	en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
+ 
+ 	return en7581_reset_register(&pdev->dev, np_base, en7523_rst_map,
+-				     ARRAY_SIZE(en7523_rst_map));
++				     ARRAY_SIZE(en7523_rst_map),
++				     en7581_rst_ofs);
+ }
+ 
+ static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
+@@ -705,7 +803,8 @@ static const struct reset_control_ops en
+ };
+ 
+ static int en7581_reset_register(struct device *dev, void __iomem *base,
+-				 const u16 *rst_map, int nr_resets)
++				 const u16 *rst_map, int nr_resets,
++				 const u16 *rst_reg_ofs)
+ {
+ 	struct en_rst_data *rst_data;
+ 
+@@ -713,7 +812,7 @@ static int en7581_reset_register(struct
+ 	if (!rst_data)
+ 		return -ENOMEM;
+ 
+-	rst_data->bank_ofs = en7581_rst_ofs;
++	rst_data->bank_ofs = rst_reg_ofs;
+ 	rst_data->idx_map = rst_map;
+ 	rst_data->base = base;
+ 
+@@ -752,7 +851,123 @@ static int en7581_clk_hw_init(struct pla
+ 	writel(val | 3, base + REG_NP_SCU_PCIC);
+ 
+ 	return en7581_reset_register(&pdev->dev, base, en7581_rst_map,
+-				     ARRAY_SIZE(en7581_rst_map));
++				     ARRAY_SIZE(en7581_rst_map),
++				     en7581_rst_ofs);
++}
++
++static enum en_hir get_hw_id(void __iomem *np_base)
++{
++	u32 val = FIELD_GET(REG_HIR_MASK, readl(np_base + REG_HIR));
++
++	if (val < HIR_MAX)
++		return (enum en_hir) val;
++
++	return HIR_UNKNOWN;
++}
++
++static void en751221_try_register_clk(struct device *dev, int key,
++				      struct clk_hw_onecell_data *clk_data,
++				      const char *name, u32 rate)
++{
++	struct clk_hw *hw;
++
++	hw = clk_hw_register_fixed_rate(dev, name, NULL, 0, rate);
++	if (IS_ERR(hw))
++		pr_err("Failed to register clk %s: %pe\n", name, hw);
++	else
++		clk_data->hws[key] = hw;
++}
++
++static void en751221_register_clocks(struct device *dev,
++				     struct clk_hw_onecell_data *clk_data,
++				     struct regmap *map, void __iomem *np_base)
++{
++	enum en_hir hid = get_hw_id(np_base);
++	struct clk_hw *hw;
++	u32 rate;
++	u32 div;
++	int err;
++
++	/* PCI */
++	hw = en7523_register_pcie_clk(dev, np_base);
++	clk_data->hws[EN751221_CLK_PCIE] = hw;
++
++	/* SPI */
++	rate = EN751221_SPI_BASE;
++	if (hid == HIR_EN7526C)
++		rate = EN751221_SPI_BASE_EN7526C;
++
++	err = regmap_read(map, EN751221_REG_SPI_DIV, &div);
++	if (err) {
++		pr_err("Failed reading fixed clk div %s: %d\n",
++		       "spi", err);
++	} else {
++		div = FIELD_GET(EN751221_REG_SPI_DIV_MASK, div) * 2;
++		if (!div)
++			div = 40;
++
++		en751221_try_register_clk(dev, EN751221_CLK_SPI, clk_data,
++					  "spi", rate / div);
++	}
++
++	/* BUS */
++	rate = FIELD_GET(EN751221_REG_BUS_MASK,
++			 readl(np_base + EN751221_REG_BUS));
++	rate *= 1000000;
++	en751221_try_register_clk(dev, EN751221_CLK_BUS, clk_data, "bus",
++				  rate);
++
++	/* CPU */
++	en751221_try_register_clk(dev, EN751221_CLK_CPU, clk_data, "cpu",
++				  rate * 4);
++
++	/* HPT */
++	switch (hid) {
++		case HIR_EN751221:
++		case HIR_EN751627:
++		case HIR_EN7526C:
++		case HIR_EN7580:
++		case HIR_EN7528:
++			rate = 200000000;
++			break;
++		case HIR_MT7505:
++			rate = 100000000;
++			break;
++		case HIR_MT751020:
++			rate = 800000000 / 3;
++			break;
++		default:
++			rate = 250000000;
++	}
++	en751221_try_register_clk(dev, EN751221_CLK_HPT, clk_data, "hpt",
++				  rate);
++
++	/* GSW */
++	rate = FIELD_GET(EN751221_REG_SSR3_GSW_MASK,
++			 readl(np_base + EN751221_REG_SSR3));
++	en751221_try_register_clk(dev, EN751221_CLK_GSW, clk_data, "gsw",
++				  gsw751221_base[rate]);
++}
++
++static int en751221_clk_hw_init(struct platform_device *pdev,
++				struct clk_hw_onecell_data *clk_data)
++{
++	struct regmap *map;
++	void __iomem *base;
++
++	map = syscon_regmap_lookup_by_compatible("econet,en751221-chip-scu");
++	if (IS_ERR(map))
++		return PTR_ERR(map);
++
++	base = devm_platform_ioremap_resource(pdev, 0);
++	if (IS_ERR(base))
++		return PTR_ERR(base);
++
++	en751221_register_clocks(&pdev->dev, clk_data, map, base);
++
++	return en7581_reset_register(&pdev->dev, base, en751221_rst_map,
++				     ARRAY_SIZE(en751221_rst_map),
++				     en751221_rst_ofs);
+ }
+ 
+ static int en7523_clk_probe(struct platform_device *pdev)
+@@ -799,9 +1014,20 @@ static const struct en_clk_soc_data en75
+ 	.hw_init = en7581_clk_hw_init,
+ };
+ 
++static const struct en_clk_soc_data en751221_data = {
++	.num_clocks = EN751221_MAX_CLKS,
++	.pcie_ops = {
++		.is_enabled = en7523_pci_is_enabled,
++		.prepare = en7523_pci_prepare,
++		.unprepare = en7523_pci_unprepare,
++	},
++	.hw_init = en751221_clk_hw_init,
++};
++
+ static const struct of_device_id of_match_clk_en7523[] = {
+ 	{ .compatible = "airoha,en7523-scu", .data = &en7523_data },
+ 	{ .compatible = "airoha,en7581-scu", .data = &en7581_data },
++	{ .compatible = "econet,en751221-scu", .data = &en751221_data },
+ 	{ /* sentinel */ }
+ };
+