1
0
Fork 0
forked from mirror/openwrt

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 <cjd@cjdns.fr>
Link: https://github.com/openwrt/openwrt/pull/21545
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Caleb James DeLisle 2026-01-14 23:20:52 +00:00 committed by Hauke Mehrtens
parent 609deedd87
commit b4b12a8239
15 changed files with 1420 additions and 0 deletions

View file

@ -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>;

View file

@ -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

View file

@ -0,0 +1,179 @@
From 82e6bf912d5846646892becea659b39d178d79e3 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
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 <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-6-8ada5e394ae4@kernel.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
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

View file

@ -0,0 +1,89 @@
From a9eaf305017a5ebe73ab34e85bd5414055a88f29 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
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 <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-7-8ada5e394ae4@kernel.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
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

View file

@ -0,0 +1,47 @@
From 90d4e466c9ea2010f33880a36317a8486ccbe082 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
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/20250108-pcie-en7581-fixes-v6-4-21ac939a3b9b@kernel.org
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Acked-by: Stephen Boyd <sboyd@kernel.org>
---
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

View file

@ -0,0 +1,88 @@
From e4a9748e7103c47e575459db2b6a77d14f34da2b Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
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 <ansuelsmth@gmail.com>
Link: https://lore.kernel.org/r/20250113231030.6735-2-ansuelsmth@gmail.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
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

View file

@ -0,0 +1,46 @@
From bfe257f9780d8f77045a7da6ec959ee0659d2f98 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
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 <ansuelsmth@gmail.com>
Link: https://lore.kernel.org/r/20250113231030.6735-5-ansuelsmth@gmail.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
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

View file

@ -0,0 +1,138 @@
From 1c0608d860db973ad09b5a9ccb19b76ae07622a3 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
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 <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
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

View file

@ -0,0 +1,40 @@
From 947643509279a605a09959a06d332bf027e8be57 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
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 <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
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

View file

@ -0,0 +1,79 @@
From 0f7c637d1103d79829dec198e5f1b678c1feb5f2 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
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 <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/20241112-clk-en7581-syscon-v2-1-8ada5e394ae4@kernel.org
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
.../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

View file

@ -0,0 +1,87 @@
From 947643509279a605a09959a06d332bf027e8be57 Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
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 <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
.../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 <mikhail.kshevetskiy@iopsys.eu>
+ *
+ * based on
+ * include/dt-bindings/reset/airoha,en7581-reset.h
+ * by Lorenzo Bianconi <lorenzo@kernel.org>
+ */
+
+#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

View file

@ -0,0 +1,31 @@
From 02d3b7557ce28c373ea1e925ae16ab5988284313 Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
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 <ansuelsmth@gmail.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20250113231030.6735-3-ansuelsmth@gmail.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
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

View file

@ -0,0 +1,30 @@
From 82108ad3285f58f314ad41398f44017c7dbe44de Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
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 <ansuelsmth@gmail.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20250113231030.6735-4-ansuelsmth@gmail.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
---
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

View file

@ -0,0 +1,176 @@
From f3fa5911b1f094e164c497f7b10d94d92852e285 Mon Sep 17 00:00:00 2001
From: Caleb James DeLisle <cjd@cjdns.fr>
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 <cjd@cjdns.fr>
---
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 <cjd@cjdns.fr>
+
+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_ */

View file

@ -0,0 +1,364 @@
From 1dfb29374a040ba80d378b3465f4e0bcb67f4ba3 Mon Sep 17 00:00:00 2001
From: Caleb James DeLisle <cjd@cjdns.fr>
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 <cjd@cjdns.fr>
---
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 */ }
};