stm32: 6.12: refresh kernel patches

Drop upstreamed patches and refresh remaining ones.

Manually rebased:
- 033-ARM-dts-stm32-rtc-add-LSCO-to-WLAN-BT-module-on-stm3.patch
- 035-ARM-dts-stm32-rtc-add-pin-to-provide-LSCO-on-stm32mp.patch

Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
Link: https://github.com/openwrt/openwrt/pull/18740
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Thomas Richard 2025-05-07 17:53:47 +02:00 committed by Hauke Mehrtens
parent 234eadd07e
commit 1cdbddae6e
27 changed files with 20 additions and 6904 deletions

View file

@ -1,69 +0,0 @@
From 1ddced59ac1f7c739f21e930d87b126a30c561bb Mon Sep 17 00:00:00 2001
From: Jisheng Zhang <jszhang@kernel.org>
Date: Sat, 16 Sep 2023 15:58:23 +0800
Subject: [PATCH 1/8] net: stmmac: dwmac-stm32: use
devm_stmmac_probe_config_dt()
Simplify the driver's probe() function by using the devres
variant of stmmac_probe_config_dt().
Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -372,21 +372,18 @@ static int stm32_dwmac_probe(struct plat
if (ret)
return ret;
- plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
+ plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
if (IS_ERR(plat_dat))
return PTR_ERR(plat_dat);
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
- if (!dwmac) {
- ret = -ENOMEM;
- goto err_remove_config_dt;
- }
+ if (!dwmac)
+ return -ENOMEM;
data = of_device_get_match_data(&pdev->dev);
if (!data) {
dev_err(&pdev->dev, "no of match data provided\n");
- ret = -EINVAL;
- goto err_remove_config_dt;
+ return -EINVAL;
}
dwmac->ops = data;
@@ -395,14 +392,14 @@ static int stm32_dwmac_probe(struct plat
ret = stm32_dwmac_parse_data(dwmac, &pdev->dev);
if (ret) {
dev_err(&pdev->dev, "Unable to parse OF data\n");
- goto err_remove_config_dt;
+ return ret;
}
plat_dat->bsp_priv = dwmac;
ret = stm32_dwmac_init(plat_dat);
if (ret)
- goto err_remove_config_dt;
+ return ret;
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
@@ -412,8 +409,6 @@ static int stm32_dwmac_probe(struct plat
err_clk_disable:
stm32_dwmac_clk_disable(dwmac);
-err_remove_config_dt:
- stmmac_remove_config_dt(pdev, plat_dat);
return ret;
}

View file

@ -1,241 +0,0 @@
From 73c350e3fb32e9598b66f61081c7e06a7fba49f8 Mon Sep 17 00:00:00 2001
From: Ben Wolsieffer <ben.wolsieffer@hefring.com>
Date: Mon, 9 Oct 2023 10:59:04 -0400
Subject: [PATCH 2/8] net: stmmac: dwmac-stm32: refactor clock config
Currently, clock configuration is spread throughout the driver and
partially duplicated for the STM32MP1 and STM32 MCU variants. This makes
it difficult to keep track of which clocks need to be enabled or disabled
in various scenarios.
This patch adds symmetric stm32_dwmac_clk_enable/disable() functions
that handle all clock configuration, including quirks required while
suspending or resuming. syscfg_clk and clk_eth_ck are not present on
STM32 MCUs, but it is fine to try to configure them anyway since NULL
clocks are ignored.
Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 113 +++++++-----------
1 file changed, 45 insertions(+), 68 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -98,7 +98,6 @@ struct stm32_dwmac {
struct stm32_ops {
int (*set_mode)(struct plat_stmmacenet_data *plat_dat);
- int (*clk_prepare)(struct stm32_dwmac *dwmac, bool prepare);
int (*suspend)(struct stm32_dwmac *dwmac);
void (*resume)(struct stm32_dwmac *dwmac);
int (*parse_data)(struct stm32_dwmac *dwmac,
@@ -107,62 +106,55 @@ struct stm32_ops {
bool clk_rx_enable_in_suspend;
};
-static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
+static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume)
{
- struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
int ret;
- if (dwmac->ops->set_mode) {
- ret = dwmac->ops->set_mode(plat_dat);
- if (ret)
- return ret;
- }
-
ret = clk_prepare_enable(dwmac->clk_tx);
if (ret)
- return ret;
+ goto err_clk_tx;
- if (!dwmac->ops->clk_rx_enable_in_suspend ||
- !dwmac->dev->power.is_suspended) {
+ if (!dwmac->ops->clk_rx_enable_in_suspend || !resume) {
ret = clk_prepare_enable(dwmac->clk_rx);
- if (ret) {
- clk_disable_unprepare(dwmac->clk_tx);
- return ret;
- }
+ if (ret)
+ goto err_clk_rx;
}
- if (dwmac->ops->clk_prepare) {
- ret = dwmac->ops->clk_prepare(dwmac, true);
- if (ret) {
- clk_disable_unprepare(dwmac->clk_rx);
- clk_disable_unprepare(dwmac->clk_tx);
- }
+ ret = clk_prepare_enable(dwmac->syscfg_clk);
+ if (ret)
+ goto err_syscfg_clk;
+
+ if (dwmac->enable_eth_ck) {
+ ret = clk_prepare_enable(dwmac->clk_eth_ck);
+ if (ret)
+ goto err_clk_eth_ck;
}
return ret;
+
+err_clk_eth_ck:
+ clk_disable_unprepare(dwmac->syscfg_clk);
+err_syscfg_clk:
+ if (!dwmac->ops->clk_rx_enable_in_suspend || !resume)
+ clk_disable_unprepare(dwmac->clk_rx);
+err_clk_rx:
+ clk_disable_unprepare(dwmac->clk_tx);
+err_clk_tx:
+ return ret;
}
-static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare)
+static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat, bool resume)
{
- int ret = 0;
+ struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
+ int ret;
- if (prepare) {
- ret = clk_prepare_enable(dwmac->syscfg_clk);
+ if (dwmac->ops->set_mode) {
+ ret = dwmac->ops->set_mode(plat_dat);
if (ret)
return ret;
- if (dwmac->enable_eth_ck) {
- ret = clk_prepare_enable(dwmac->clk_eth_ck);
- if (ret) {
- clk_disable_unprepare(dwmac->syscfg_clk);
- return ret;
- }
- }
- } else {
- clk_disable_unprepare(dwmac->syscfg_clk);
- if (dwmac->enable_eth_ck)
- clk_disable_unprepare(dwmac->clk_eth_ck);
}
- return ret;
+
+ return stm32_dwmac_clk_enable(dwmac, resume);
}
static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
@@ -252,13 +244,15 @@ static int stm32mcu_set_mode(struct plat
dwmac->ops->syscfg_eth_mask, val << 23);
}
-static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac)
+static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend)
{
clk_disable_unprepare(dwmac->clk_tx);
- clk_disable_unprepare(dwmac->clk_rx);
+ if (!dwmac->ops->clk_rx_enable_in_suspend || !suspend)
+ clk_disable_unprepare(dwmac->clk_rx);
- if (dwmac->ops->clk_prepare)
- dwmac->ops->clk_prepare(dwmac, false);
+ clk_disable_unprepare(dwmac->syscfg_clk);
+ if (dwmac->enable_eth_ck)
+ clk_disable_unprepare(dwmac->clk_eth_ck);
}
static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
@@ -397,7 +391,7 @@ static int stm32_dwmac_probe(struct plat
plat_dat->bsp_priv = dwmac;
- ret = stm32_dwmac_init(plat_dat);
+ ret = stm32_dwmac_init(plat_dat, false);
if (ret)
return ret;
@@ -408,7 +402,7 @@ static int stm32_dwmac_probe(struct plat
return 0;
err_clk_disable:
- stm32_dwmac_clk_disable(dwmac);
+ stm32_dwmac_clk_disable(dwmac, false);
return ret;
}
@@ -421,7 +415,7 @@ static void stm32_dwmac_remove(struct pl
stmmac_dvr_remove(&pdev->dev);
- stm32_dwmac_clk_disable(priv->plat->bsp_priv);
+ stm32_dwmac_clk_disable(dwmac, false);
if (dwmac->irq_pwr_wakeup >= 0) {
dev_pm_clear_wake_irq(&pdev->dev);
@@ -431,18 +425,7 @@ static void stm32_dwmac_remove(struct pl
static int stm32mp1_suspend(struct stm32_dwmac *dwmac)
{
- int ret = 0;
-
- ret = clk_prepare_enable(dwmac->clk_ethstp);
- if (ret)
- return ret;
-
- clk_disable_unprepare(dwmac->clk_tx);
- clk_disable_unprepare(dwmac->syscfg_clk);
- if (dwmac->enable_eth_ck)
- clk_disable_unprepare(dwmac->clk_eth_ck);
-
- return ret;
+ return clk_prepare_enable(dwmac->clk_ethstp);
}
static void stm32mp1_resume(struct stm32_dwmac *dwmac)
@@ -450,14 +433,6 @@ static void stm32mp1_resume(struct stm32
clk_disable_unprepare(dwmac->clk_ethstp);
}
-static int stm32mcu_suspend(struct stm32_dwmac *dwmac)
-{
- clk_disable_unprepare(dwmac->clk_tx);
- clk_disable_unprepare(dwmac->clk_rx);
-
- return 0;
-}
-
#ifdef CONFIG_PM_SLEEP
static int stm32_dwmac_suspend(struct device *dev)
{
@@ -468,6 +443,10 @@ static int stm32_dwmac_suspend(struct de
int ret;
ret = stmmac_suspend(dev);
+ if (ret)
+ return ret;
+
+ stm32_dwmac_clk_disable(dwmac, true);
if (dwmac->ops->suspend)
ret = dwmac->ops->suspend(dwmac);
@@ -485,7 +464,7 @@ static int stm32_dwmac_resume(struct dev
if (dwmac->ops->resume)
dwmac->ops->resume(dwmac);
- ret = stm32_dwmac_init(priv->plat);
+ ret = stm32_dwmac_init(priv->plat, true);
if (ret)
return ret;
@@ -500,13 +479,11 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_
static struct stm32_ops stm32mcu_dwmac_data = {
.set_mode = stm32mcu_set_mode,
- .suspend = stm32mcu_suspend,
.syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
};
static struct stm32_ops stm32mp1_dwmac_data = {
.set_mode = stm32mp1_set_mode,
- .clk_prepare = stm32mp1_clk_prepare,
.suspend = stm32mp1_suspend,
.resume = stm32mp1_resume,
.parse_data = stm32mp1_parse_data,

View file

@ -1,125 +0,0 @@
From 23c08dc4ff28b5ca1aa5ee745a5e9688561e8f6a Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Tue, 11 Jun 2024 10:36:00 +0200
Subject: [PATCH 3/8] net: stmmac: dwmac-stm32: Separate out external clock
rate validation
Pull the external clock frequency validation into a separate function,
to avoid conflating it with external clock DT property decoding and
clock mux register configuration. This should make the code easier to
read and understand.
This does change the code behavior slightly. The clock mux PMCR register
setting now depends solely on the DT properties which configure the clock
mux between external clock and internal RCC generated clock. The mux PMCR
register settings no longer depend on the supplied clock frequency, that
supplied clock frequency is now only validated, and if the clock frequency
is invalid for a mode, it is rejected.
Previously, the code would switch the PMCR register clock mux to internal
RCC generated clock if external clock couldn't provide suitable frequency,
without checking whether the RCC generated clock frequency is correct. Such
behavior is risky at best, user should have configured their clock correctly
in the first place, so this behavior is removed here.
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 51 +++++++++++++++----
1 file changed, 41 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -157,25 +157,54 @@ static int stm32_dwmac_init(struct plat_
return stm32_dwmac_clk_enable(dwmac, resume);
}
+static int stm32mp1_validate_ethck_rate(struct plat_stmmacenet_data *plat_dat)
+{
+ struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
+ const u32 clk_rate = clk_get_rate(dwmac->clk_eth_ck);
+
+ switch (plat_dat->mac_interface) {
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_GMII:
+ if (clk_rate == ETH_CK_F_25M)
+ return 0;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M)
+ return 0;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M)
+ return 0;
+ break;
+ default:
+ break;
+ }
+
+ dev_err(dwmac->dev, "Mode %s does not match eth-ck frequency %d Hz",
+ phy_modes(plat_dat->mac_interface), clk_rate);
+ return -EINVAL;
+}
+
static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
- u32 reg = dwmac->mode_reg, clk_rate;
- int val;
+ u32 reg = dwmac->mode_reg;
+ int val, ret;
- clk_rate = clk_get_rate(dwmac->clk_eth_ck);
dwmac->enable_eth_ck = false;
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
- if (clk_rate == ETH_CK_F_25M && dwmac->ext_phyclk)
+ if (dwmac->ext_phyclk)
dwmac->enable_eth_ck = true;
val = SYSCFG_PMCR_ETH_SEL_MII;
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII;
- if (clk_rate == ETH_CK_F_25M &&
- (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
+ if (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk) {
dwmac->enable_eth_ck = true;
val |= SYSCFG_PMCR_ETH_CLK_SEL;
}
@@ -183,8 +212,7 @@ static int stm32mp1_set_mode(struct plat
break;
case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_PMCR_ETH_SEL_RMII;
- if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
- (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
+ if (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk) {
dwmac->enable_eth_ck = true;
val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
}
@@ -195,8 +223,7 @@ static int stm32mp1_set_mode(struct plat
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
val = SYSCFG_PMCR_ETH_SEL_RGMII;
- if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) &&
- (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
+ if (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk) {
dwmac->enable_eth_ck = true;
val |= SYSCFG_PMCR_ETH_CLK_SEL;
}
@@ -209,6 +236,10 @@ static int stm32mp1_set_mode(struct plat
return -EINVAL;
}
+ ret = stm32mp1_validate_ethck_rate(plat_dat);
+ if (ret)
+ return ret;
+
/* Need to update PMCCLRR (clear register) */
regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
dwmac->ops->syscfg_eth_mask);

View file

@ -1,132 +0,0 @@
From d23ba64e733580db2809e6f6dbf6f093fbd1b91b Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Tue, 11 Jun 2024 10:36:01 +0200
Subject: [PATCH 4/8] net: stmmac: dwmac-stm32: Separate out external clock
selector
Pull the external clock selector into a separate function, to avoid
conflating it with external clock rate validation and clock mux
register configuration. This should make the code easier to read and
understand.
The dwmac->enable_eth_ck variable in the end indicates whether the MAC
clock are supplied by external oscillator (true) or internal RCC clock
IP (false). The dwmac->enable_eth_ck value is set based on multiple DT
properties, some of them deprecated, some of them specific to bus mode.
The following DT properties and variables are taken into account. In
each case, if the property is present or true, MAC clock is supplied
by external oscillator.
- "st,ext-phyclk", assigned to variable dwmac->ext_phyclk
- Used in any mode (MII/RMII/GMII/RGMII)
- The only non-deprecated DT property of the three
- "st,eth-clk-sel", assigned to variable dwmac->eth_clk_sel_reg
- Valid only in GMII/RGMII mode
- Deprecated property, backward compatibility only
- "st,eth-ref-clk-sel", assigned to variable dwmac->eth_ref_clk_sel_reg
- Valid only in RMII mode
- Deprecated property, backward compatibility only
The stm32mp1_select_ethck_external() function handles the aforementioned
DT properties and sets dwmac->enable_eth_ck accordingly.
The stm32mp1_set_mode() is adjusted to call stm32mp1_select_ethck_external()
first and then only use dwmac->enable_eth_ck to determine hardware clock mux
settings.
No functional change intended.
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 50 ++++++++++++++-----
1 file changed, 38 insertions(+), 12 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -157,6 +157,37 @@ static int stm32_dwmac_init(struct plat_
return stm32_dwmac_clk_enable(dwmac, resume);
}
+static int stm32mp1_select_ethck_external(struct plat_stmmacenet_data *plat_dat)
+{
+ struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
+
+ switch (plat_dat->mac_interface) {
+ case PHY_INTERFACE_MODE_MII:
+ dwmac->enable_eth_ck = dwmac->ext_phyclk;
+ return 0;
+ case PHY_INTERFACE_MODE_GMII:
+ dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg ||
+ dwmac->ext_phyclk;
+ return 0;
+ case PHY_INTERFACE_MODE_RMII:
+ dwmac->enable_eth_ck = dwmac->eth_ref_clk_sel_reg ||
+ dwmac->ext_phyclk;
+ return 0;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg ||
+ dwmac->ext_phyclk;
+ return 0;
+ default:
+ dwmac->enable_eth_ck = false;
+ dev_err(dwmac->dev, "Mode %s not supported",
+ phy_modes(plat_dat->mac_interface));
+ return -EINVAL;
+ }
+}
+
static int stm32mp1_validate_ethck_rate(struct plat_stmmacenet_data *plat_dat)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
@@ -194,28 +225,25 @@ static int stm32mp1_set_mode(struct plat
u32 reg = dwmac->mode_reg;
int val, ret;
- dwmac->enable_eth_ck = false;
+ ret = stm32mp1_select_ethck_external(plat_dat);
+ if (ret)
+ return ret;
+
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
- if (dwmac->ext_phyclk)
- dwmac->enable_eth_ck = true;
val = SYSCFG_PMCR_ETH_SEL_MII;
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII;
- if (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk) {
- dwmac->enable_eth_ck = true;
+ if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL;
- }
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
break;
case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_PMCR_ETH_SEL_RMII;
- if (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk) {
- dwmac->enable_eth_ck = true;
+ if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
- }
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
break;
case PHY_INTERFACE_MODE_RGMII:
@@ -223,10 +251,8 @@ static int stm32mp1_set_mode(struct plat
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
val = SYSCFG_PMCR_ETH_SEL_RGMII;
- if (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk) {
- dwmac->enable_eth_ck = true;
+ if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL;
- }
pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
break;
default:

View file

@ -1,71 +0,0 @@
From bb7ab910631ee0ade0758a3c4aa8dadc3b6934b6 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Tue, 11 Jun 2024 10:36:02 +0200
Subject: [PATCH 5/8] net: stmmac: dwmac-stm32: Extract PMCR configuration
Pull the PMCR clock mux configuration into a separate function. This is
the final change of three, which moves external clock rate validation,
external clock selector decoding, and clock mux configuration into
separate functions. This should make the code easier to understand.
No functional change intended.
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 27 ++++++++++++-------
1 file changed, 17 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -219,15 +219,11 @@ static int stm32mp1_validate_ethck_rate(
return -EINVAL;
}
-static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
+static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
u32 reg = dwmac->mode_reg;
- int val, ret;
-
- ret = stm32mp1_select_ethck_external(plat_dat);
- if (ret)
- return ret;
+ int val;
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
@@ -262,10 +258,6 @@ static int stm32mp1_set_mode(struct plat
return -EINVAL;
}
- ret = stm32mp1_validate_ethck_rate(plat_dat);
- if (ret)
- return ret;
-
/* Need to update PMCCLRR (clear register) */
regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
dwmac->ops->syscfg_eth_mask);
@@ -275,6 +267,21 @@ static int stm32mp1_set_mode(struct plat
dwmac->ops->syscfg_eth_mask, val);
}
+static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
+{
+ int ret;
+
+ ret = stm32mp1_select_ethck_external(plat_dat);
+ if (ret)
+ return ret;
+
+ ret = stm32mp1_validate_ethck_rate(plat_dat);
+ if (ret)
+ return ret;
+
+ return stm32mp1_configure_pmcr(plat_dat);
+}
+
static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;

View file

@ -1,83 +0,0 @@
From 0476213f50452446fedd1a918b7bc72eb39a4c46 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex@denx.de>
Date: Tue, 11 Jun 2024 10:36:03 +0200
Subject: [PATCH 6/8] net: stmmac: dwmac-stm32: Clean up the debug prints
Use dev_err()/dev_dbg() and phy_modes() to print PHY mode instead of
pr_debug() and hand-written PHY mode decoding. This way, each debug
print has associated device with it and duplicated mode decoding is
removed.
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -228,19 +228,16 @@ static int stm32mp1_configure_pmcr(struc
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
val = SYSCFG_PMCR_ETH_SEL_MII;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII;
if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n");
break;
case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_PMCR_ETH_SEL_RMII;
if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
break;
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
@@ -249,15 +246,16 @@ static int stm32mp1_configure_pmcr(struc
val = SYSCFG_PMCR_ETH_SEL_RGMII;
if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
break;
default:
- pr_debug("SYSCFG init : Do not manage %d interface\n",
- plat_dat->mac_interface);
+ dev_err(dwmac->dev, "Mode %s not supported",
+ phy_modes(plat_dat->mac_interface));
/* Do not manage others interfaces */
return -EINVAL;
}
+ dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
+
/* Need to update PMCCLRR (clear register) */
regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
dwmac->ops->syscfg_eth_mask);
@@ -291,19 +289,19 @@ static int stm32mcu_set_mode(struct plat
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
val = SYSCFG_MCU_ETH_SEL_MII;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n");
break;
case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_MCU_ETH_SEL_RMII;
- pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
break;
default:
- pr_debug("SYSCFG init : Do not manage %d interface\n",
- plat_dat->mac_interface);
+ dev_err(dwmac->dev, "Mode %s not supported",
+ phy_modes(plat_dat->mac_interface));
/* Do not manage others interfaces */
return -EINVAL;
}
+ dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
+
return regmap_update_bits(dwmac->regmap, reg,
dwmac->ops->syscfg_eth_mask, val << 23);
}

View file

@ -1,101 +0,0 @@
From 796669a85c5c4fa80cb8790e9adcccbbd99750e8 Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Tue, 11 Jun 2024 10:36:05 +0200
Subject: [PATCH 7/8] net: stmmac: dwmac-stm32: Mask support for PMCR
configuration
Add possibility to have second argument in syscon property to manage
mask. This mask will be used to address right BITFIELDS of PMCR register.
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 28 +++++++++++++------
1 file changed, 19 insertions(+), 9 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -90,6 +90,7 @@ struct stm32_dwmac {
int eth_ref_clk_sel_reg;
int irq_pwr_wakeup;
u32 mode_reg; /* MAC glue-logic mode register */
+ u32 mode_mask;
struct regmap *regmap;
u32 speed;
const struct stm32_ops *ops;
@@ -102,8 +103,8 @@ struct stm32_ops {
void (*resume)(struct stm32_dwmac *dwmac);
int (*parse_data)(struct stm32_dwmac *dwmac,
struct device *dev);
- u32 syscfg_eth_mask;
bool clk_rx_enable_in_suspend;
+ u32 syscfg_clr_off;
};
static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume)
@@ -256,13 +257,16 @@ static int stm32mp1_configure_pmcr(struc
dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
+ /* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
+ val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);
+
/* Need to update PMCCLRR (clear register) */
- regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
- dwmac->ops->syscfg_eth_mask);
+ regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
+ dwmac->mode_mask);
/* Update PMCSETR (set register) */
return regmap_update_bits(dwmac->regmap, reg,
- dwmac->ops->syscfg_eth_mask, val);
+ dwmac->mode_mask, val);
}
static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
@@ -303,7 +307,7 @@ static int stm32mcu_set_mode(struct plat
dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
return regmap_update_bits(dwmac->regmap, reg,
- dwmac->ops->syscfg_eth_mask, val << 23);
+ SYSCFG_MCU_ETH_MASK, val << 23);
}
static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend)
@@ -348,8 +352,15 @@ static int stm32_dwmac_parse_data(struct
return PTR_ERR(dwmac->regmap);
err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg);
- if (err)
+ if (err) {
dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);
+ return err;
+ }
+
+ dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
+ err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
+ if (err)
+ dev_dbg(dev, "Warning sysconfig register mask not set\n");
return err;
}
@@ -540,8 +551,7 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_
stm32_dwmac_suspend, stm32_dwmac_resume);
static struct stm32_ops stm32mcu_dwmac_data = {
- .set_mode = stm32mcu_set_mode,
- .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
+ .set_mode = stm32mcu_set_mode
};
static struct stm32_ops stm32mp1_dwmac_data = {
@@ -549,7 +559,7 @@ static struct stm32_ops stm32mp1_dwmac_d
.suspend = stm32mp1_suspend,
.resume = stm32mp1_resume,
.parse_data = stm32mp1_parse_data,
- .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
+ .syscfg_clr_off = 0x44,
.clk_rx_enable_in_suspend = true
};

View file

@ -1,94 +0,0 @@
From 8d28aaf5d5dbfd1f452286fa6ac571df0bcf00ad Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Tue, 11 Jun 2024 10:36:06 +0200
Subject: [PATCH 8/8] net: stmmac: dwmac-stm32: add management of stm32mp13 for
stm32
Add Ethernet support for STM32MP13.
STM32MP13 is STM32 SOC with 2 GMACs instances.
GMAC IP version is SNPS 4.20.
GMAC IP configure with 1 RX and 1 TX queue.
DMA HW capability register supported
RX Checksum Offload Engine supported
TX Checksum insertion supported
Wake-Up On Lan supported
TSO supported
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 32 ++++++++++++++++---
1 file changed, 28 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -104,6 +104,7 @@ struct stm32_ops {
int (*parse_data)(struct stm32_dwmac *dwmac,
struct device *dev);
bool clk_rx_enable_in_suspend;
+ bool is_mp13;
u32 syscfg_clr_off;
};
@@ -224,11 +225,18 @@ static int stm32mp1_configure_pmcr(struc
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
u32 reg = dwmac->mode_reg;
- int val;
+ int val = 0;
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
- val = SYSCFG_PMCR_ETH_SEL_MII;
+ /*
+ * STM32MP15xx supports both MII and GMII, STM32MP13xx MII only.
+ * SYSCFG_PMCSETR ETH_SELMII is present only on STM32MP15xx and
+ * acts as a selector between 0:GMII and 1:MII. As STM32MP13xx
+ * supports only MII, ETH_SELMII is not present.
+ */
+ if (!dwmac->ops->is_mp13) /* Select MII mode on STM32MP15xx */
+ val |= SYSCFG_PMCR_ETH_SEL_MII;
break;
case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII;
@@ -359,8 +367,12 @@ static int stm32_dwmac_parse_data(struct
dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
- if (err)
- dev_dbg(dev, "Warning sysconfig register mask not set\n");
+ if (err) {
+ if (dwmac->ops->is_mp13)
+ dev_err(dev, "Sysconfig register mask must be set (%d)\n", err);
+ else
+ dev_dbg(dev, "Warning sysconfig register mask not set\n");
+ }
return err;
}
@@ -560,12 +572,24 @@ static struct stm32_ops stm32mp1_dwmac_d
.resume = stm32mp1_resume,
.parse_data = stm32mp1_parse_data,
.syscfg_clr_off = 0x44,
+ .is_mp13 = false,
+ .clk_rx_enable_in_suspend = true
+};
+
+static struct stm32_ops stm32mp13_dwmac_data = {
+ .set_mode = stm32mp1_set_mode,
+ .suspend = stm32mp1_suspend,
+ .resume = stm32mp1_resume,
+ .parse_data = stm32mp1_parse_data,
+ .syscfg_clr_off = 0x08,
+ .is_mp13 = true,
.clk_rx_enable_in_suspend = true
};
static const struct of_device_id stm32_dwmac_match[] = {
{ .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
{ .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
+ { .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data},
{ }
};
MODULE_DEVICE_TABLE(of, stm32_dwmac_match);

View file

@ -1,32 +0,0 @@
From 3cd1d4651cebe9776a0142ade36ff9f2e3545436 Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Mon, 1 Jul 2024 08:48:37 +0200
Subject: [PATCH] net: stmmac: dwmac-stm32: Add test to verify if ETHCK is used
before checking clk rate
When we want to use clock from RCC to clock Ethernet PHY (with ETHCK)
we need to check if value of clock rate is authorized.
If ETHCK is unused, the ETHCK frequency is 0Hz and validation fails.
It makes no sense to validate unused ETHCK, so skip the validation.
Fixes: 582ac134963e ("net: stmmac: dwmac-stm32: Separate out external clock rate validation")
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Tested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -195,6 +195,9 @@ static int stm32mp1_validate_ethck_rate(
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
const u32 clk_rate = clk_get_rate(dwmac->clk_eth_ck);
+ if (!dwmac->enable_eth_ck)
+ return 0;
+
switch (plat_dat->mac_interface) {
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:

View file

@ -1,39 +0,0 @@
From f8dbe58e2f1a3c091531b3f8ef86b393ceee67d1 Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Mon, 1 Jul 2024 08:48:38 +0200
Subject: [PATCH] net: stmmac: dwmac-stm32: update err status in case different
of stm32mp13
The mask parameter of syscfg property is mandatory for MP13 but
optional for all other cases.
The function should not return error code because for non-MP13
the missing syscfg phandle in DT is not considered an error.
So reset err to 0 in that case to support existing DTs without
syscfg phandle.
Fixes: 50bbc0393114 ("net: stmmac: dwmac-stm32: add management of stm32mp13 for stm32")
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Tested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -371,10 +371,12 @@ static int stm32_dwmac_parse_data(struct
dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
if (err) {
- if (dwmac->ops->is_mp13)
+ if (dwmac->ops->is_mp13) {
dev_err(dev, "Sysconfig register mask must be set (%d)\n", err);
- else
+ } else {
dev_dbg(dev, "Warning sysconfig register mask not set\n");
+ err = 0;
+ }
}
return err;

View file

@ -1,265 +0,0 @@
From 21ca3d7c59595d76237faebeff4f6a979cf7ae82 Mon Sep 17 00:00:00 2001
From: Alexandre Torgue <alexandre.torgue@foss.st.com>
Date: Fri, 5 Apr 2024 13:45:24 +0200
Subject: [PATCH 2/5] ARM: dts: stm32: put ETZPC as an access controller for
STM32MP13x boards
Reference ETZPC as an access-control-provider.
For more information on which peripheral is securable or supports MCU
isolation, please read the STM32MP13 reference manual
Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
---
arch/arm/boot/dts/st/stm32mp131.dtsi | 28 ++++++++++++++++++++++++++-
arch/arm/boot/dts/st/stm32mp133.dtsi | 1 +
arch/arm/boot/dts/st/stm32mp13xc.dtsi | 1 +
arch/arm/boot/dts/st/stm32mp13xf.dtsi | 1 +
4 files changed, 30 insertions(+), 1 deletion(-)
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -886,10 +886,11 @@
};
etzpc: bus@5c007000 {
- compatible = "simple-bus";
+ compatible = "st,stm32-etzpc", "simple-bus";
reg = <0x5c007000 0x400>;
#address-cells = <1>;
#size-cells = <1>;
+ #access-controller-cells = <1>;
ranges;
adc_2: adc@48004000 {
@@ -902,6 +903,7 @@
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ access-controllers = <&etzpc 33>;
status = "disabled";
adc2: adc@0 {
@@ -949,6 +951,7 @@
dr_mode = "otg";
otg-rev = <0x200>;
usb33d-supply = <&scmi_usb33>;
+ access-controllers = <&etzpc 34>;
status = "disabled";
};
@@ -962,6 +965,7 @@
dmas = <&dmamux1 41 0x400 0x5>,
<&dmamux1 42 0x400 0x1>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 16>;
status = "disabled";
};
@@ -975,6 +979,7 @@
dmas = <&dmamux1 43 0x400 0x5>,
<&dmamux1 44 0x400 0x1>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 17>;
status = "disabled";
};
@@ -986,6 +991,7 @@
dmas = <&dmamux1 83 0x400 0x01>,
<&dmamux1 84 0x400 0x01>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 13>;
status = "disabled";
};
@@ -1000,6 +1006,7 @@
dmas = <&dmamux1 83 0x400 0x01>,
<&dmamux1 84 0x400 0x01>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 18>;
status = "disabled";
};
@@ -1014,6 +1021,7 @@
dmas = <&dmamux1 85 0x400 0x01>,
<&dmamux1 86 0x400 0x01>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 19>;
status = "disabled";
};
@@ -1032,6 +1040,7 @@
dma-names = "rx", "tx";
st,syscfg-fmp = <&syscfg 0x4 0x4>;
i2c-analog-filter;
+ access-controllers = <&etzpc 20>;
status = "disabled";
};
@@ -1050,6 +1059,7 @@
dma-names = "rx", "tx";
st,syscfg-fmp = <&syscfg 0x4 0x8>;
i2c-analog-filter;
+ access-controllers = <&etzpc 21>;
status = "disabled";
};
@@ -1068,6 +1078,7 @@
dma-names = "rx", "tx";
st,syscfg-fmp = <&syscfg 0x4 0x10>;
i2c-analog-filter;
+ access-controllers = <&etzpc 22>;
status = "disabled";
};
@@ -1080,6 +1091,7 @@
interrupt-names = "global";
clocks = <&rcc TIM12_K>;
clock-names = "int";
+ access-controllers = <&etzpc 23>;
status = "disabled";
pwm {
@@ -1104,6 +1116,7 @@
interrupt-names = "global";
clocks = <&rcc TIM13_K>;
clock-names = "int";
+ access-controllers = <&etzpc 24>;
status = "disabled";
pwm {
@@ -1128,6 +1141,7 @@
interrupt-names = "global";
clocks = <&rcc TIM14_K>;
clock-names = "int";
+ access-controllers = <&etzpc 25>;
status = "disabled";
pwm {
@@ -1157,6 +1171,7 @@
<&dmamux1 107 0x400 0x1>,
<&dmamux1 108 0x400 0x1>;
dma-names = "ch1", "up", "trig", "com";
+ access-controllers = <&etzpc 26>;
status = "disabled";
pwm {
@@ -1184,6 +1199,7 @@
dmas = <&dmamux1 109 0x400 0x1>,
<&dmamux1 110 0x400 0x1>;
dma-names = "ch1", "up";
+ access-controllers = <&etzpc 27>;
status = "disabled";
pwm {
@@ -1211,6 +1227,7 @@
dmas = <&dmamux1 111 0x400 0x1>,
<&dmamux1 112 0x400 0x1>;
dma-names = "ch1", "up";
+ access-controllers = <&etzpc 28>;
status = "disabled";
pwm {
@@ -1235,6 +1252,7 @@
clocks = <&rcc LPTIM2_K>;
clock-names = "mux";
wakeup-source;
+ access-controllers = <&etzpc 1>;
status = "disabled";
pwm {
@@ -1269,6 +1287,7 @@
clocks = <&rcc LPTIM3_K>;
clock-names = "mux";
wakeup-source;
+ access-controllers = <&etzpc 2>;
status = "disabled";
pwm {
@@ -1297,6 +1316,7 @@
resets = <&rcc HASH1_R>;
dmas = <&mdma 30 0x2 0x1000a02 0x0 0x0>;
dma-names = "in";
+ access-controllers = <&etzpc 41>;
status = "disabled";
};
@@ -1305,6 +1325,7 @@
reg = <0x54004000 0x400>;
clocks = <&rcc RNG1_K>;
resets = <&rcc RNG1_R>;
+ access-controllers = <&etzpc 40>;
status = "disabled";
};
@@ -1320,6 +1341,7 @@
#size-cells = <1>;
clocks = <&rcc FMC_K>;
resets = <&rcc FMC_R>;
+ access-controllers = <&etzpc 54>;
status = "disabled";
nand-controller@4,0 {
@@ -1353,6 +1375,7 @@
dma-names = "tx", "rx";
clocks = <&rcc QSPI_K>;
resets = <&rcc QSPI_R>;
+ access-controllers = <&etzpc 55>;
status = "disabled";
};
@@ -1367,6 +1390,7 @@
cap-sd-highspeed;
cap-mmc-highspeed;
max-frequency = <130000000>;
+ access-controllers = <&etzpc 50>;
status = "disabled";
};
@@ -1381,6 +1405,7 @@
cap-sd-highspeed;
cap-mmc-highspeed;
max-frequency = <130000000>;
+ access-controllers = <&etzpc 51>;
status = "disabled";
};
@@ -1394,6 +1419,7 @@
resets = <&rcc USBPHY_R>;
vdda1v1-supply = <&scmi_reg11>;
vdda1v8-supply = <&scmi_reg18>;
+ access-controllers = <&etzpc 5>;
status = "disabled";
usbphyc_port0: usb-phy@0 {
--- a/arch/arm/boot/dts/st/stm32mp133.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp133.dtsi
@@ -47,6 +47,7 @@
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ access-controllers = <&etzpc 32>;
status = "disabled";
adc1: adc@0 {
--- a/arch/arm/boot/dts/st/stm32mp13xc.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13xc.dtsi
@@ -11,6 +11,7 @@
interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc CRYP1>;
resets = <&rcc CRYP1_R>;
+ access-controllers = <&etzpc 42>;
status = "disabled";
};
};
--- a/arch/arm/boot/dts/st/stm32mp13xf.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13xf.dtsi
@@ -11,6 +11,7 @@
interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc CRYP1>;
resets = <&rcc CRYP1_R>;
+ access-controllers = <&etzpc 42>;
status = "disabled";
};
};

View file

@ -1,126 +0,0 @@
From b1468a44e0c0f43a06e027efeff4183b3aee0cf7 Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Mon, 10 Jun 2024 10:03:08 +0200
Subject: [PATCH 3/5] ARM: dts: stm32: add ethernet1/2 RMII pins for
STM32MP13F-DK board
Those pins are used for Ethernet 1 and 2 on STM32MP13F-DK board.
ethernet1: RMII with crystal.
ethernet2: RMII without crystal.
Add analog gpio pin configuration ("sleep") to manage power mode on
stm32mp13.
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
---
arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi | 98 +++++++++++++++++++++
1 file changed, 98 insertions(+)
--- a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
@@ -13,6 +13,104 @@
};
};
+ eth1_rgmii_pins_a: eth1-rgmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
+ <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
+ <STM32_PINMUX('E', 5, AF10)>, /* ETH_RGMII_TXD3 */
+ <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
+ <STM32_PINMUX('C', 1, AF11)>, /* ETH_RGMII_GTX_CLK */
+ <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, AF11)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <2>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
+ <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
+ <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
+ <STM32_PINMUX('A', 7, AF11)>, /* ETH_RGMII_RX_CTL */
+ <STM32_PINMUX('D', 7, AF10)>; /* ETH_RGMII_RX_CLK */
+ bias-disable;
+ };
+
+ };
+
+ eth1_rmii_pins_a: eth1-rmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 14, AF11)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('B', 11, AF11)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('A', 1, AF11)>, /* ETH_RMII_REF_CLK */
+ <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, AF11)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('C', 5, AF11)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('C', 1, AF10)>; /* ETH_RMII_CRS_DV */
+ bias-disable;
+ };
+
+ };
+
+ eth1_rmii_sleep_pins_a: eth1-rmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RMII_REF_CLK */
+ <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 2, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('C', 1, ANALOG)>; /* ETH_RMII_CRS_DV */
+ };
+ };
+
+ eth2_rmii_pins_a: eth2-rmii-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, AF11)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 11, AF10)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('G', 8, AF13)>, /* ETH_RMII_ETHCK */
+ <STM32_PINMUX('F', 6, AF11)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('B', 2, AF11)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, AF10)>; /* ETH_MDC */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+
+ pins2 {
+ pinmux = <STM32_PINMUX('F', 4, AF11)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('E', 2, AF10)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('A', 12, AF11)>; /* ETH_RMII_CRS_DV */
+ bias-disable;
+ };
+ };
+
+ eth2_rmii_sleep_pins_a: eth2-rmii-sleep-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 7, ANALOG)>, /* ETH_RMII_TXD0 */
+ <STM32_PINMUX('G', 11, ANALOG)>, /* ETH_RMII_TXD1 */
+ <STM32_PINMUX('G', 8, ANALOG)>, /* ETH_RMII_ETHCK */
+ <STM32_PINMUX('F', 6, ANALOG)>, /* ETH_RMII_TX_EN */
+ <STM32_PINMUX('B', 2, ANALOG)>, /* ETH_MDIO */
+ <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_MDC */
+ <STM32_PINMUX('F', 4, ANALOG)>, /* ETH_RMII_RXD0 */
+ <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RMII_RXD1 */
+ <STM32_PINMUX('A', 12, ANALOG)>; /* ETH_RMII_CRS_DV */
+ };
+ };
+
i2c1_pins_a: i2c1-0 {
pins {
pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */

View file

@ -1,108 +0,0 @@
From fcf6ca2da4650d0a7a9cd62c8c72341860931159 Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Mon, 10 Jun 2024 10:03:07 +0200
Subject: [PATCH 4/5] ARM: dts: stm32: add ethernet1 and ethernet2 support on
stm32mp13
Both instances ethernet based on GMAC SNPS IP on stm32mp13.
GMAC IP version is SNPS 4.20.
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
---
arch/arm/boot/dts/st/stm32mp131.dtsi | 38 ++++++++++++++++++++++++++++
arch/arm/boot/dts/st/stm32mp133.dtsi | 31 +++++++++++++++++++++++
2 files changed, 69 insertions(+)
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -883,6 +883,12 @@
ts_cal2: calib@5e {
reg = <0x5e 0x2>;
};
+ ethernet_mac1_address: mac1@e4 {
+ reg = <0xe4 0x6>;
+ };
+ ethernet_mac2_address: mac2@ea {
+ reg = <0xea 0x6>;
+ };
};
etzpc: bus@5c007000 {
@@ -1409,6 +1415,38 @@
status = "disabled";
};
+ ethernet1: ethernet@5800a000 {
+ compatible = "st,stm32mp13-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800a000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+ <&exti 68 1>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc ETH1MAC>,
+ <&rcc ETH1TX>,
+ <&rcc ETH1RX>,
+ <&rcc ETH1STP>,
+ <&rcc ETH1CK_K>;
+ st,syscon = <&syscfg 0x4 0xff0000>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,axi-config = <&stmmac_axi_config_1>;
+ snps,tso;
+ access-controllers = <&etzpc 48>;
+ status = "disabled";
+
+ stmmac_axi_config_1: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,wr_osr_lmt = <0x7>;
+ };
+ };
+
usbphyc: usbphyc@5a006000 {
#address-cells = <1>;
#size-cells = <0>;
--- a/arch/arm/boot/dts/st/stm32mp133.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp133.dtsi
@@ -68,4 +68,35 @@
};
};
};
+
+ ethernet2: ethernet@5800e000 {
+ compatible = "st,stm32mp13-dwmac", "snps,dwmac-4.20a";
+ reg = <0x5800e000 0x2000>;
+ reg-names = "stmmaceth";
+ interrupts-extended = <&intc GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ clock-names = "stmmaceth",
+ "mac-clk-tx",
+ "mac-clk-rx",
+ "ethstp",
+ "eth-ck";
+ clocks = <&rcc ETH2MAC>,
+ <&rcc ETH2TX>,
+ <&rcc ETH2RX>,
+ <&rcc ETH2STP>,
+ <&rcc ETH2CK_K>;
+ st,syscon = <&syscfg 0x4 0xff000000>;
+ snps,mixed-burst;
+ snps,pbl = <2>;
+ snps,axi-config = <&stmmac_axi_config_2>;
+ snps,tso;
+ access-controllers = <&etzpc 49>;
+ status = "disabled";
+
+ stmmac_axi_config_2: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <0x7>;
+ snps,wr_osr_lmt = <0x7>;
+ };
+ };
};

View file

@ -1,58 +0,0 @@
From b255afeeb33efaa974b1b2454b1f58252d783b67 Mon Sep 17 00:00:00 2001
From: Christophe Roullier <christophe.roullier@foss.st.com>
Date: Mon, 10 Jun 2024 10:03:09 +0200
Subject: [PATCH 5/5] ARM: dts: stm32: add ethernet1 for STM32MP135F-DK board
Ethernet1: RMII with crystal
Ethernet2: RMII with no cristal, need "phy-supply" property to work,
today this property was managed by Ethernet glue, but should be present
and managed in PHY node. So I will push second Ethernet in next step.
PHYs used are SMSC (LAN8742A)
Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
---
arch/arm/boot/dts/st/stm32mp135f-dk.dts | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -19,6 +19,7 @@
compatible = "st,stm32mp135f-dk", "st,stm32mp135";
aliases {
+ ethernet0 = &ethernet1;
serial0 = &uart4;
serial1 = &usart1;
serial2 = &uart8;
@@ -92,6 +93,28 @@
};
};
};
+
+&ethernet1 {
+ status = "okay";
+ pinctrl-0 = <&eth1_rmii_pins_a>;
+ pinctrl-1 = <&eth1_rmii_sleep_pins_a>;
+ pinctrl-names = "default", "sleep";
+ phy-mode = "rmii";
+ phy-handle = <&phy0_eth1>;
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ phy0_eth1: ethernet-phy@0 {
+ compatible = "ethernet-phy-id0007.c131";
+ reg = <0>;
+ reset-gpios = <&mcp23017 9 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+ };
+};
&i2c1 {
pinctrl-names = "default", "sleep";

View file

@ -1,189 +0,0 @@
From c15671ce05a038b8c92a6f1e24b0b850a154ba59 Mon Sep 17 00:00:00 2001
From: Valentin Caron <valentin.caron@foss.st.com>
Date: Mon, 22 Jul 2024 18:00:20 +0200
Subject: [PATCH] rtc: stm32: add pinctrl and pinmux interfaces
STM32 RTC is capable to handle 3 specific pins of the soc.
"out1, out2 and out2_rmp". To handle this, we use pinctrl framework.
There is a single pin per group.
Signed-off-by: Valentin Caron <valentin.caron@foss.st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20240722160022.454226-3-valentin.caron@foss.st.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
drivers/rtc/Kconfig | 5 ++
drivers/rtc/rtc-stm32.c | 120 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 125 insertions(+)
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1887,6 +1887,11 @@ config RTC_DRV_STM32
tristate "STM32 RTC"
select REGMAP_MMIO
depends on ARCH_STM32 || COMPILE_TEST
+ depends on OF
+ depends on PINCTRL
+ select PINMUX
+ select PINCONF
+ select GENERIC_PINCONF
help
If you say yes here you get support for the STM32 On-Chip
Real Time Clock.
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -12,6 +12,9 @@
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/pm_wakeirq.h>
#include <linux/regmap.h>
@@ -94,6 +97,14 @@
/* STM32 RTC driver time helpers */
#define SEC_PER_DAY (24 * 60 * 60)
+/* STM32 RTC pinctrl helpers */
+#define STM32_RTC_PINMUX(_name, _action, ...) { \
+ .name = (_name), \
+ .action = (_action), \
+ .groups = ((const char *[]){ __VA_ARGS__ }), \
+ .num_groups = ARRAY_SIZE(((const char *[]){ __VA_ARGS__ })), \
+}
+
struct stm32_rtc;
struct stm32_rtc_registers {
@@ -149,6 +160,106 @@ static void stm32_rtc_wpr_lock(struct st
writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
}
+enum stm32_rtc_pin_name {
+ NONE,
+ OUT1,
+ OUT2,
+ OUT2_RMP
+};
+
+static const struct pinctrl_pin_desc stm32_rtc_pinctrl_pins[] = {
+ PINCTRL_PIN(OUT1, "out1"),
+ PINCTRL_PIN(OUT2, "out2"),
+ PINCTRL_PIN(OUT2_RMP, "out2_rmp"),
+};
+
+static int stm32_rtc_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ return ARRAY_SIZE(stm32_rtc_pinctrl_pins);
+}
+
+static const char *stm32_rtc_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ return stm32_rtc_pinctrl_pins[selector].name;
+}
+
+static int stm32_rtc_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const unsigned int **pins,
+ unsigned int *num_pins)
+{
+ *pins = &stm32_rtc_pinctrl_pins[selector].number;
+ *num_pins = 1;
+ return 0;
+}
+
+static const struct pinctrl_ops stm32_rtc_pinctrl_ops = {
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = pinconf_generic_dt_free_map,
+ .get_groups_count = stm32_rtc_pinctrl_get_groups_count,
+ .get_group_name = stm32_rtc_pinctrl_get_group_name,
+ .get_group_pins = stm32_rtc_pinctrl_get_group_pins,
+};
+
+struct stm32_rtc_pinmux_func {
+ const char *name;
+ const char * const *groups;
+ const unsigned int num_groups;
+ int (*action)(struct pinctrl_dev *pctl_dev, unsigned int pin);
+};
+
+static const struct stm32_rtc_pinmux_func stm32_rtc_pinmux_functions[] = {
+};
+
+static int stm32_rtc_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
+{
+ return ARRAY_SIZE(stm32_rtc_pinmux_functions);
+}
+
+static const char *stm32_rtc_pinmux_get_fname(struct pinctrl_dev *pctldev, unsigned int selector)
+{
+ return stm32_rtc_pinmux_functions[selector].name;
+}
+
+static int stm32_rtc_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned int selector,
+ const char * const **groups, unsigned int * const num_groups)
+{
+ *groups = stm32_rtc_pinmux_functions[selector].groups;
+ *num_groups = stm32_rtc_pinmux_functions[selector].num_groups;
+ return 0;
+}
+
+static int stm32_rtc_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
+ unsigned int group)
+{
+ struct stm32_rtc_pinmux_func selected_func = stm32_rtc_pinmux_functions[selector];
+ struct pinctrl_pin_desc pin = stm32_rtc_pinctrl_pins[group];
+
+ /* Call action */
+ if (selected_func.action)
+ return selected_func.action(pctldev, pin.number);
+
+ return -EINVAL;
+}
+
+static const struct pinmux_ops stm32_rtc_pinmux_ops = {
+ .get_functions_count = stm32_rtc_pinmux_get_functions_count,
+ .get_function_name = stm32_rtc_pinmux_get_fname,
+ .get_function_groups = stm32_rtc_pinmux_get_groups,
+ .set_mux = stm32_rtc_pinmux_set_mux,
+ .strict = true,
+};
+
+static struct pinctrl_desc stm32_rtc_pdesc = {
+ .name = DRIVER_NAME,
+ .pins = stm32_rtc_pinctrl_pins,
+ .npins = ARRAY_SIZE(stm32_rtc_pinctrl_pins),
+ .owner = THIS_MODULE,
+ .pctlops = &stm32_rtc_pinctrl_ops,
+ .pmxops = &stm32_rtc_pinmux_ops,
+};
+
static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
{
const struct stm32_rtc_registers *regs = &rtc->data->regs;
@@ -723,6 +834,7 @@ static int stm32_rtc_probe(struct platfo
{
struct stm32_rtc *rtc;
const struct stm32_rtc_registers *regs;
+ struct pinctrl_dev *pctl;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
@@ -834,6 +946,14 @@ static int stm32_rtc_probe(struct platfo
goto err;
}
+ ret = devm_pinctrl_register_and_init(&pdev->dev, &stm32_rtc_pdesc, rtc, &pctl);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pinctrl register failed");
+
+ ret = pinctrl_enable(pctl);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "pinctrl enable failed");
+
/*
* If INITS flag is reset (calendar year field set to 0x00), calendar
* must be initialized

View file

@ -1,253 +0,0 @@
From 229476a4de2e237ebadddca8a82d20afa9298f71 Mon Sep 17 00:00:00 2001
From: Valentin Caron <valentin.caron@foss.st.com>
Date: Mon, 22 Jul 2024 18:00:21 +0200
Subject: [PATCH] rtc: stm32: add Low Speed Clock Output (LSCO) support
RTC is able to output on a pin the "LSE" internal clock.
STM32 RTC is now registered as a clock provider.
It provides rtc_lsco clock, that means RTC_LSCO is output on either
RTC_OUT1 or RTC_OUT2_RMP, depending on pinmux DT property.
The clock is marked as CLK_IGNORE_UNUSED and CLK_IS_CRITICAL because
RTC_LSCO can be early required by devices needed it to init.
Add LSCO in pinmux functions.
Add "stm32_rtc_clean_outs" to disable LSCO. As RTC is part of "backup"
power domain, it is not reset during shutdown or reboot. So force LSCO
disable at probe.
Co-developed-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
Signed-off-by: Valentin Caron <valentin.caron@foss.st.com>
Link: https://lore.kernel.org/r/20240722160022.454226-4-valentin.caron@foss.st.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
drivers/rtc/Kconfig | 1 +
drivers/rtc/rtc-stm32.c | 99 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+)
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1892,6 +1892,7 @@ config RTC_DRV_STM32
select PINMUX
select PINCONF
select GENERIC_PINCONF
+ depends on COMMON_CLK
help
If you say yes here you get support for the STM32 On-Chip
Real Time Clock.
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -6,6 +6,7 @@
#include <linux/bcd.h>
#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/errno.h>
#include <linux/iopoll.h>
#include <linux/ioport.h>
@@ -44,6 +45,10 @@
#define STM32_RTC_CR_FMT BIT(6)
#define STM32_RTC_CR_ALRAE BIT(8)
#define STM32_RTC_CR_ALRAIE BIT(12)
+#define STM32_RTC_CR_OSEL GENMASK(22, 21)
+#define STM32_RTC_CR_COE BIT(23)
+#define STM32_RTC_CR_TAMPOE BIT(26)
+#define STM32_RTC_CR_OUT2EN BIT(31)
/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
#define STM32_RTC_ISR_ALRAWF BIT(0)
@@ -80,6 +85,12 @@
/* STM32_RTC_SR/_SCR bit fields */
#define STM32_RTC_SR_ALRA BIT(0)
+/* STM32_RTC_CFGR bit fields */
+#define STM32_RTC_CFGR_OUT2_RMP BIT(0)
+#define STM32_RTC_CFGR_LSCOEN GENMASK(2, 1)
+#define STM32_RTC_CFGR_LSCOEN_OUT1 1
+#define STM32_RTC_CFGR_LSCOEN_OUT2_RMP 2
+
/* STM32_RTC_VERR bit fields */
#define STM32_RTC_VERR_MINREV_SHIFT 0
#define STM32_RTC_VERR_MINREV GENMASK(3, 0)
@@ -117,6 +128,7 @@ struct stm32_rtc_registers {
u16 wpr;
u16 sr;
u16 scr;
+ u16 cfgr;
u16 verr;
};
@@ -131,6 +143,7 @@ struct stm32_rtc_data {
bool has_pclk;
bool need_dbp;
bool need_accuracy;
+ bool has_lsco;
};
struct stm32_rtc {
@@ -143,6 +156,7 @@ struct stm32_rtc {
struct clk *rtc_ck;
const struct stm32_rtc_data *data;
int irq_alarm;
+ struct clk *clk_lsco;
};
static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
@@ -209,7 +223,68 @@ struct stm32_rtc_pinmux_func {
int (*action)(struct pinctrl_dev *pctl_dev, unsigned int pin);
};
+static int stm32_rtc_pinmux_lsco_available(struct pinctrl_dev *pctldev, unsigned int pin)
+{
+ struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
+ struct stm32_rtc_registers regs = rtc->data->regs;
+ unsigned int cr = readl_relaxed(rtc->base + regs.cr);
+ unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
+ unsigned int calib = STM32_RTC_CR_COE;
+ unsigned int tampalrm = STM32_RTC_CR_TAMPOE | STM32_RTC_CR_OSEL;
+
+ switch (pin) {
+ case OUT1:
+ if ((!(cr & STM32_RTC_CR_OUT2EN) &&
+ ((cr & calib) || cr & tampalrm)) ||
+ ((cr & calib) && (cr & tampalrm)))
+ return -EBUSY;
+ break;
+ case OUT2_RMP:
+ if ((cr & STM32_RTC_CR_OUT2EN) &&
+ (cfgr & STM32_RTC_CFGR_OUT2_RMP) &&
+ ((cr & calib) || (cr & tampalrm)))
+ return -EBUSY;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (clk_get_rate(rtc->rtc_ck) != 32768)
+ return -ERANGE;
+
+ return 0;
+}
+
+static int stm32_rtc_pinmux_action_lsco(struct pinctrl_dev *pctldev, unsigned int pin)
+{
+ struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
+ struct stm32_rtc_registers regs = rtc->data->regs;
+ struct device *dev = rtc->rtc_dev->dev.parent;
+ u8 lscoen;
+ int ret;
+
+ if (!rtc->data->has_lsco)
+ return -EPERM;
+
+ ret = stm32_rtc_pinmux_lsco_available(pctldev, pin);
+ if (ret)
+ return ret;
+
+ lscoen = (pin == OUT1) ? STM32_RTC_CFGR_LSCOEN_OUT1 : STM32_RTC_CFGR_LSCOEN_OUT2_RMP;
+
+ rtc->clk_lsco = clk_register_gate(dev, "rtc_lsco", __clk_get_name(rtc->rtc_ck),
+ CLK_IGNORE_UNUSED | CLK_IS_CRITICAL,
+ rtc->base + regs.cfgr, lscoen, 0, NULL);
+ if (IS_ERR(rtc->clk_lsco))
+ return PTR_ERR(rtc->clk_lsco);
+
+ of_clk_add_provider(dev->of_node, of_clk_src_simple_get, rtc->clk_lsco);
+
+ return 0;
+}
+
static const struct stm32_rtc_pinmux_func stm32_rtc_pinmux_functions[] = {
+ STM32_RTC_PINMUX("lsco", &stm32_rtc_pinmux_action_lsco, "out1", "out2_rmp"),
};
static int stm32_rtc_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
@@ -664,6 +739,7 @@ static const struct stm32_rtc_data stm32
.has_pclk = false,
.need_dbp = true,
.need_accuracy = false,
+ .has_lsco = false,
.regs = {
.tr = 0x00,
.dr = 0x04,
@@ -674,6 +750,7 @@ static const struct stm32_rtc_data stm32
.wpr = 0x24,
.sr = 0x0C, /* set to ISR offset to ease alarm management */
.scr = UNDEF_REG,
+ .cfgr = UNDEF_REG,
.verr = UNDEF_REG,
},
.events = {
@@ -686,6 +763,7 @@ static const struct stm32_rtc_data stm32
.has_pclk = true,
.need_dbp = true,
.need_accuracy = false,
+ .has_lsco = false,
.regs = {
.tr = 0x00,
.dr = 0x04,
@@ -696,6 +774,7 @@ static const struct stm32_rtc_data stm32
.wpr = 0x24,
.sr = 0x0C, /* set to ISR offset to ease alarm management */
.scr = UNDEF_REG,
+ .cfgr = UNDEF_REG,
.verr = UNDEF_REG,
},
.events = {
@@ -717,6 +796,7 @@ static const struct stm32_rtc_data stm32
.has_pclk = true,
.need_dbp = false,
.need_accuracy = true,
+ .has_lsco = true,
.regs = {
.tr = 0x00,
.dr = 0x04,
@@ -727,6 +807,7 @@ static const struct stm32_rtc_data stm32
.wpr = 0x24,
.sr = 0x50,
.scr = 0x5C,
+ .cfgr = 0x60,
.verr = 0x3F4,
},
.events = {
@@ -743,6 +824,19 @@ static const struct of_device_id stm32_r
};
MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
+static void stm32_rtc_clean_outs(struct stm32_rtc *rtc)
+{
+ struct stm32_rtc_registers regs = rtc->data->regs;
+
+ if (regs.cfgr != UNDEF_REG) {
+ unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
+
+ cfgr &= ~STM32_RTC_CFGR_LSCOEN;
+ cfgr &= ~STM32_RTC_CFGR_OUT2_RMP;
+ writel_relaxed(cfgr, rtc->base + regs.cfgr);
+ }
+}
+
static int stm32_rtc_init(struct platform_device *pdev,
struct stm32_rtc *rtc)
{
@@ -946,6 +1040,8 @@ static int stm32_rtc_probe(struct platfo
goto err;
}
+ stm32_rtc_clean_outs(rtc);
+
ret = devm_pinctrl_register_and_init(&pdev->dev, &stm32_rtc_pdesc, rtc, &pctl);
if (ret)
return dev_err_probe(&pdev->dev, ret, "pinctrl register failed");
@@ -992,6 +1088,9 @@ static void stm32_rtc_remove(struct plat
const struct stm32_rtc_registers *regs = &rtc->data->regs;
unsigned int cr;
+ if (!IS_ERR_OR_NULL(rtc->clk_lsco))
+ clk_unregister_gate(rtc->clk_lsco);
+
/* Disable interrupts */
stm32_rtc_wpr_unlock(rtc);
cr = readl_relaxed(rtc->base + regs->cr);

View file

@ -15,17 +15,17 @@ Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
--- a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi --- a/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi +++ b/arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
@@ -212,6 +212,13 @@ @@ -595,6 +595,13 @@
};
}; };
+ /omit-if-no-ref/ /omit-if-no-ref/
+ rtc_rsvd_pins_a: rtc-rsvd-0 { + rtc_rsvd_pins_a: rtc-rsvd-0 {
+ pins { + pins {
+ pinmux = <STM32_PINMUX('I', 1, ANALOG)>; /* RTC_OUT2_RMP */ + pinmux = <STM32_PINMUX('I', 1, ANALOG)>; /* RTC_OUT2_RMP */
+ }; + };
+ }; + };
+ +
sdmmc1_b4_pins_a: sdmmc1-b4-0 { + /omit-if-no-ref/
sai1a_pins_a: sai1a-0 {
pins { pins {
pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */ pinmux = <STM32_PINMUX('A', 4, AF12)>, /* SAI1_SCK_A */

View file

@ -17,7 +17,7 @@ Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts --- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts +++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -184,7 +184,14 @@ @@ -346,7 +346,14 @@
}; };
&rtc { &rtc {

View file

@ -16,8 +16,8 @@ Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts --- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts +++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -67,6 +67,19 @@ @@ -121,6 +121,19 @@
default-state = "off"; };
}; };
}; };
+ +
@ -36,7 +36,7 @@ Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
}; };
&adc_1 { &adc_1 {
@@ -230,6 +243,30 @@ @@ -392,6 +405,30 @@
status = "okay"; status = "okay";
}; };
@ -67,7 +67,7 @@ Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
&spi5 { &spi5 {
pinctrl-names = "default", "sleep"; pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi5_pins_a>; pinctrl-0 = <&spi5_pins_a>;
@@ -332,6 +369,14 @@ @@ -498,6 +535,14 @@
pinctrl-2 = <&usart2_idle_pins_a>; pinctrl-2 = <&usart2_idle_pins_a>;
uart-has-rtscts; uart-has-rtscts;
status = "okay"; status = "okay";

View file

@ -14,17 +14,17 @@ Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
--- a/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi --- a/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi +++ b/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi
@@ -1467,6 +1467,13 @@ @@ -1697,6 +1697,13 @@
};
}; };
+ /omit-if-no-ref/ /omit-if-no-ref/
+ rtc_rsvd_pins_a: rtc-rsvd-0 { + rtc_rsvd_pins_a: rtc-rsvd-0 {
+ pins { + pins {
+ pinmux = <STM32_PINMUX('I', 8, ANALOG)>; /* RTC_OUT2_RMP */ + pinmux = <STM32_PINMUX('I', 8, ANALOG)>; /* RTC_OUT2_RMP */
+ }; + };
+ }; + };
+ +
+ /omit-if-no-ref/
sai2a_pins_a: sai2a-0 { sai2a_pins_a: sai2a-0 {
pins { pins {
pinmux = <STM32_PINMUX('I', 5, AF10)>, /* SAI2_SCK_A */ pinmux = <STM32_PINMUX('I', 5, AF10)>, /* SAI2_SCK_A */

View file

@ -1,566 +0,0 @@
From 91ddf8509d0308e297f1876a024645cc3478e358 Mon Sep 17 00:00:00 2001
From: Gatien Chevallier <gatien.chevallier@foss.st.com>
Date: Fri, 5 Jan 2024 14:04:02 +0100
Subject: [PATCH] ARM: dts: stm32: put ETZPC as an access controller for
STM32MP15x boards
Reference ETZPC as an access-control-provider.
For more information on which peripheral is securable or supports MCU
isolation, please read the STM32MP15 reference manual
Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
---
arch/arm/boot/dts/st/stm32mp151.dtsi | 66 ++++++++++++++++++++++++++-
arch/arm/boot/dts/st/stm32mp153.dtsi | 2 +
arch/arm/boot/dts/st/stm32mp15xc.dtsi | 1 +
3 files changed, 68 insertions(+), 1 deletion(-)
--- a/arch/arm/boot/dts/st/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp151.dtsi
@@ -331,10 +331,11 @@
};
etzpc: bus@5c007000 {
- compatible = "simple-bus";
+ compatible = "st,stm32-etzpc", "simple-bus";
reg = <0x5c007000 0x400>;
#address-cells = <1>;
#size-cells = <1>;
+ #access-controller-cells = <1>;
ranges;
timers2: timer@40000000 {
@@ -352,6 +353,7 @@
<&dmamux1 21 0x400 0x1>,
<&dmamux1 22 0x400 0x1>;
dma-names = "ch1", "ch2", "ch3", "ch4", "up";
+ access-controllers = <&etzpc 16>;
status = "disabled";
pwm {
@@ -388,6 +390,7 @@
<&dmamux1 27 0x400 0x1>,
<&dmamux1 28 0x400 0x1>;
dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
+ access-controllers = <&etzpc 17>;
status = "disabled";
pwm {
@@ -422,6 +425,7 @@
<&dmamux1 31 0x400 0x1>,
<&dmamux1 32 0x400 0x1>;
dma-names = "ch1", "ch2", "ch3", "ch4";
+ access-controllers = <&etzpc 18>;
status = "disabled";
pwm {
@@ -458,6 +462,7 @@
<&dmamux1 59 0x400 0x1>,
<&dmamux1 60 0x400 0x1>;
dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
+ access-controllers = <&etzpc 19>;
status = "disabled";
pwm {
@@ -489,6 +494,7 @@
clock-names = "int";
dmas = <&dmamux1 69 0x400 0x1>;
dma-names = "up";
+ access-controllers = <&etzpc 20>;
status = "disabled";
timer@5 {
@@ -509,6 +515,7 @@
clock-names = "int";
dmas = <&dmamux1 70 0x400 0x1>;
dma-names = "up";
+ access-controllers = <&etzpc 21>;
status = "disabled";
timer@6 {
@@ -527,6 +534,7 @@
interrupt-names = "global";
clocks = <&rcc TIM12_K>;
clock-names = "int";
+ access-controllers = <&etzpc 22>;
status = "disabled";
pwm {
@@ -551,6 +559,7 @@
interrupt-names = "global";
clocks = <&rcc TIM13_K>;
clock-names = "int";
+ access-controllers = <&etzpc 23>;
status = "disabled";
pwm {
@@ -575,6 +584,7 @@
interrupt-names = "global";
clocks = <&rcc TIM14_K>;
clock-names = "int";
+ access-controllers = <&etzpc 24>;
status = "disabled";
pwm {
@@ -599,6 +609,7 @@
clocks = <&rcc LPTIM1_K>;
clock-names = "mux";
wakeup-source;
+ access-controllers = <&etzpc 25>;
status = "disabled";
pwm {
@@ -627,6 +638,7 @@
dmas = <&dmamux1 39 0x400 0x01>,
<&dmamux1 40 0x400 0x01>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 27>;
status = "disabled";
};
@@ -641,6 +653,7 @@
dmas = <&dmamux1 39 0x400 0x05>,
<&dmamux1 40 0x400 0x05>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 27>;
status = "disabled";
};
@@ -652,6 +665,7 @@
dmas = <&dmamux1 61 0x400 0x01>,
<&dmamux1 62 0x400 0x01>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 28>;
status = "disabled";
};
@@ -666,6 +680,7 @@
dmas = <&dmamux1 61 0x400 0x05>,
<&dmamux1 62 0x400 0x05>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 28>;
status = "disabled";
};
@@ -679,6 +694,7 @@
dmas = <&dmamux1 93 0x400 0x01>,
<&dmamux1 94 0x400 0x01>;
dma-names = "rx", "rx-ctrl";
+ access-controllers = <&etzpc 29>;
status = "disabled";
};
@@ -691,6 +707,7 @@
dmas = <&dmamux1 43 0x400 0x15>,
<&dmamux1 44 0x400 0x11>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 30>;
status = "disabled";
};
@@ -703,6 +720,7 @@
dmas = <&dmamux1 45 0x400 0x15>,
<&dmamux1 46 0x400 0x11>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 31>;
status = "disabled";
};
@@ -715,6 +733,7 @@
dmas = <&dmamux1 63 0x400 0x15>,
<&dmamux1 64 0x400 0x11>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 32>;
status = "disabled";
};
@@ -727,6 +746,7 @@
dmas = <&dmamux1 65 0x400 0x15>,
<&dmamux1 66 0x400 0x11>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 33>;
status = "disabled";
};
@@ -743,6 +763,7 @@
st,syscfg-fmp = <&syscfg 0x4 0x1>;
wakeup-source;
i2c-analog-filter;
+ access-controllers = <&etzpc 34>;
status = "disabled";
};
@@ -759,6 +780,7 @@
st,syscfg-fmp = <&syscfg 0x4 0x2>;
wakeup-source;
i2c-analog-filter;
+ access-controllers = <&etzpc 35>;
status = "disabled";
};
@@ -775,6 +797,7 @@
st,syscfg-fmp = <&syscfg 0x4 0x4>;
wakeup-source;
i2c-analog-filter;
+ access-controllers = <&etzpc 36>;
status = "disabled";
};
@@ -791,6 +814,7 @@
st,syscfg-fmp = <&syscfg 0x4 0x10>;
wakeup-source;
i2c-analog-filter;
+ access-controllers = <&etzpc 37>;
status = "disabled";
};
@@ -800,6 +824,7 @@
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc CEC_K>, <&rcc CEC>;
clock-names = "cec", "hdmi-cec";
+ access-controllers = <&etzpc 38>;
status = "disabled";
};
@@ -810,6 +835,7 @@
clock-names = "pclk";
#address-cells = <1>;
#size-cells = <0>;
+ access-controllers = <&etzpc 39>;
status = "disabled";
dac1: dac@1 {
@@ -836,6 +862,7 @@
dmas = <&dmamux1 79 0x400 0x15>,
<&dmamux1 80 0x400 0x11>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 40>;
status = "disabled";
};
@@ -848,6 +875,7 @@
dmas = <&dmamux1 81 0x400 0x15>,
<&dmamux1 82 0x400 0x11>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 41>;
status = "disabled";
};
@@ -872,6 +900,7 @@
<&dmamux1 17 0x400 0x1>;
dma-names = "ch1", "ch2", "ch3", "ch4",
"up", "trig", "com";
+ access-controllers = <&etzpc 48>;
status = "disabled";
pwm {
@@ -913,6 +942,7 @@
<&dmamux1 53 0x400 0x1>;
dma-names = "ch1", "ch2", "ch3", "ch4",
"up", "trig", "com";
+ access-controllers = <&etzpc 49>;
status = "disabled";
pwm {
@@ -942,6 +972,7 @@
dmas = <&dmamux1 71 0x400 0x15>,
<&dmamux1 72 0x400 0x11>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 51>;
status = "disabled";
};
@@ -953,6 +984,7 @@
dmas = <&dmamux1 37 0x400 0x01>,
<&dmamux1 38 0x400 0x01>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 52>;
status = "disabled";
};
@@ -967,6 +999,7 @@
dmas = <&dmamux1 37 0x400 0x05>,
<&dmamux1 38 0x400 0x05>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 52>;
status = "disabled";
};
@@ -981,6 +1014,7 @@
dmas = <&dmamux1 83 0x400 0x05>,
<&dmamux1 84 0x400 0x05>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 53>;
status = "disabled";
};
@@ -998,6 +1032,7 @@
<&dmamux1 107 0x400 0x1>,
<&dmamux1 108 0x400 0x1>;
dma-names = "ch1", "up", "trig", "com";
+ access-controllers = <&etzpc 54>;
status = "disabled";
pwm {
@@ -1025,6 +1060,7 @@
dmas = <&dmamux1 109 0x400 0x1>,
<&dmamux1 110 0x400 0x1>;
dma-names = "ch1", "up";
+ access-controllers = <&etzpc 55>;
status = "disabled";
pwm {
@@ -1051,6 +1087,7 @@
dmas = <&dmamux1 111 0x400 0x1>,
<&dmamux1 112 0x400 0x1>;
dma-names = "ch1", "up";
+ access-controllers = <&etzpc 56>;
status = "disabled";
pwm {
@@ -1077,6 +1114,7 @@
dmas = <&dmamux1 85 0x400 0x05>,
<&dmamux1 86 0x400 0x05>;
dma-names = "rx", "tx";
+ access-controllers = <&etzpc 57>;
status = "disabled";
};
@@ -1088,6 +1126,7 @@
reg = <0x4400a000 0x4>, <0x4400a3f0 0x10>;
interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
resets = <&rcc SAI1_R>;
+ access-controllers = <&etzpc 58>;
status = "disabled";
sai1a: audio-controller@4400a004 {
@@ -1120,6 +1159,7 @@
reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>;
interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
resets = <&rcc SAI2_R>;
+ access-controllers = <&etzpc 59>;
status = "disabled";
sai2a: audio-controller@4400b004 {
@@ -1151,6 +1191,7 @@
reg = <0x4400c000 0x4>, <0x4400c3f0 0x10>;
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
resets = <&rcc SAI3_R>;
+ access-controllers = <&etzpc 60>;
status = "disabled";
sai3a: audio-controller@4400c004 {
@@ -1181,6 +1222,7 @@
clock-names = "dfsdm";
#address-cells = <1>;
#size-cells = <0>;
+ access-controllers = <&etzpc 61>;
status = "disabled";
dfsdm0: filter@0 {
@@ -1260,6 +1302,7 @@
#dma-cells = <4>;
st,mem2mem;
dma-requests = <8>;
+ access-controllers = <&etzpc 88>;
};
dma2: dma-controller@48001000 {
@@ -1278,6 +1321,7 @@
#dma-cells = <4>;
st,mem2mem;
dma-requests = <8>;
+ access-controllers = <&etzpc 89>;
};
dmamux1: dma-router@48002000 {
@@ -1289,6 +1333,7 @@
dma-channels = <16>;
clocks = <&rcc DMAMUX>;
resets = <&rcc DMAMUX_R>;
+ access-controllers = <&etzpc 90>;
};
adc: adc@48003000 {
@@ -1303,6 +1348,7 @@
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
+ access-controllers = <&etzpc 72>;
status = "disabled";
adc1: adc@0 {
@@ -1353,6 +1399,7 @@
cap-sd-highspeed;
cap-mmc-highspeed;
max-frequency = <120000000>;
+ access-controllers = <&etzpc 86>;
status = "disabled";
};
@@ -1370,6 +1417,7 @@
dr_mode = "otg";
otg-rev = <0x200>;
usb33d-supply = <&usb33>;
+ access-controllers = <&etzpc 85>;
status = "disabled";
};
@@ -1382,6 +1430,7 @@
clock-names = "mclk";
dmas = <&dmamux1 75 0x400 0x01>;
dma-names = "tx";
+ access-controllers = <&etzpc 70>;
status = "disabled";
};
@@ -1394,6 +1443,7 @@
clocks = <&rcc LPTIM2_K>;
clock-names = "mux";
wakeup-source;
+ access-controllers = <&etzpc 64>;
status = "disabled";
pwm {
@@ -1423,6 +1473,7 @@
clocks = <&rcc LPTIM3_K>;
clock-names = "mux";
wakeup-source;
+ access-controllers = <&etzpc 65>;
status = "disabled";
pwm {
@@ -1445,6 +1496,7 @@
clocks = <&rcc LPTIM4_K>;
clock-names = "mux";
wakeup-source;
+ access-controllers = <&etzpc 66>;
status = "disabled";
pwm {
@@ -1461,6 +1513,7 @@
clocks = <&rcc LPTIM5_K>;
clock-names = "mux";
wakeup-source;
+ access-controllers = <&etzpc 67>;
status = "disabled";
pwm {
@@ -1476,6 +1529,7 @@
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2500000>;
clocks = <&rcc VREF>;
+ access-controllers = <&etzpc 69>;
status = "disabled";
};
@@ -1487,6 +1541,7 @@
reg = <0x50027000 0x4>, <0x500273f0 0x10>;
interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
resets = <&rcc SAI4_R>;
+ access-controllers = <&etzpc 68>;
status = "disabled";
sai4a: audio-controller@50027004 {
@@ -1519,6 +1574,7 @@
dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0>;
dma-names = "in";
dma-maxburst = <2>;
+ access-controllers = <&etzpc 8>;
status = "disabled";
};
@@ -1527,6 +1583,7 @@
reg = <0x54003000 0x400>;
clocks = <&rcc RNG1_K>;
resets = <&rcc RNG1_R>;
+ access-controllers = <&etzpc 7>;
status = "disabled";
};
@@ -1537,6 +1594,7 @@
reg = <0x58002000 0x1000>;
clocks = <&rcc FMC_K>;
resets = <&rcc FMC_R>;
+ access-controllers = <&etzpc 91>;
status = "disabled";
ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */
@@ -1576,6 +1634,7 @@
resets = <&rcc QSPI_R>;
#address-cells = <1>;
#size-cells = <0>;
+ access-controllers = <&etzpc 92>;
status = "disabled";
};
@@ -1603,6 +1662,7 @@
snps,en-tx-lpi-clockgating;
snps,axi-config = <&stmmac_axi_config_0>;
snps,tso;
+ access-controllers = <&etzpc 94>;
status = "disabled";
stmmac_axi_config_0: stmmac-axi-config {
@@ -1618,6 +1678,7 @@
interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc USART1_K>;
wakeup-source;
+ access-controllers = <&etzpc 3>;
status = "disabled";
};
@@ -1631,6 +1692,7 @@
resets = <&rcc SPI6_R>;
dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>,
<&mdma1 35 0x0 0x40002 0x0 0x0>;
+ access-controllers = <&etzpc 4>;
dma-names = "rx", "tx";
status = "disabled";
};
@@ -1648,6 +1710,7 @@
st,syscfg-fmp = <&syscfg 0x4 0x8>;
wakeup-source;
i2c-analog-filter;
+ access-controllers = <&etzpc 5>;
status = "disabled";
};
@@ -1664,6 +1727,7 @@
st,syscfg-fmp = <&syscfg 0x4 0x20>;
wakeup-source;
i2c-analog-filter;
+ access-controllers = <&etzpc 12>;
status = "disabled";
};
};
--- a/arch/arm/boot/dts/st/stm32mp153.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp153.dtsi
@@ -41,6 +41,7 @@
clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
clock-names = "hclk", "cclk";
bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
+ access-controllers = <&etzpc 62>;
status = "disabled";
};
@@ -54,6 +55,7 @@
clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
clock-names = "hclk", "cclk";
bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
+ access-controllers = <&etzpc 62>;
status = "disabled";
};
};
--- a/arch/arm/boot/dts/st/stm32mp15xc.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xc.dtsi
@@ -11,6 +11,7 @@
interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&rcc CRYP1>;
resets = <&rcc CRYP1_R>;
+ access-controllers = <&etzpc 9>;
status = "disabled";
};
};

View file

@ -1,166 +0,0 @@
From 1bcfbfd7c9aa716f61a01682345a1b329f6a6e66 Mon Sep 17 00:00:00 2001
From: Christophe Kerello <christophe.kerello@foss.st.com>
Date: Wed, 8 Nov 2023 15:16:37 +0100
Subject: [PATCH] mmc: mmci: stm32: add SDIO in-band interrupt mode
Add the support of SDIO in-band interrupt mode for STM32 and Ux500
variants.
It allows the SD I/O card to interrupt the host on SDMMC_D1 data line.
It is not enabled by default on Ux500 variant as this is unstable and
Ux500 users should use out-of-band IRQs.
Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
Signed-off-by: Yann Gautier <yann.gautier@foss.st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20231108141637.119497-1-yann.gautier@foss.st.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
drivers/mmc/host/mmci.c | 69 +++++++++++++++++++++++++++++++++++++++--
drivers/mmc/host/mmci.h | 2 ++
2 files changed, 69 insertions(+), 2 deletions(-)
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -272,6 +272,7 @@ static struct variant_data variant_stm32
.datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN,
.stm32_idmabsize_mask = GENMASK(12, 5),
.stm32_idmabsize_align = BIT(5),
+ .supports_sdio_irq = true,
.busy_timeout = true,
.busy_detect = true,
.busy_detect_flag = MCI_STM32_BUSYD0,
@@ -299,6 +300,7 @@ static struct variant_data variant_stm32
.datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN,
.stm32_idmabsize_mask = GENMASK(16, 5),
.stm32_idmabsize_align = BIT(5),
+ .supports_sdio_irq = true,
.dma_lli = true,
.busy_timeout = true,
.busy_detect = true,
@@ -327,6 +329,7 @@ static struct variant_data variant_stm32
.datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN,
.stm32_idmabsize_mask = GENMASK(16, 6),
.stm32_idmabsize_align = BIT(6),
+ .supports_sdio_irq = true,
.dma_lli = true,
.busy_timeout = true,
.busy_detect = true,
@@ -420,8 +423,9 @@ void mmci_write_pwrreg(struct mmci_host
*/
static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl)
{
- /* Keep busy mode in DPSM if enabled */
- datactrl |= host->datactrl_reg & host->variant->busy_dpsm_flag;
+ /* Keep busy mode in DPSM and SDIO mask if enabled */
+ datactrl |= host->datactrl_reg & (host->variant->busy_dpsm_flag |
+ host->variant->datactrl_mask_sdio);
if (host->datactrl_reg != datactrl) {
host->datactrl_reg = datactrl;
@@ -1761,6 +1765,25 @@ static irqreturn_t mmci_pio_irq(int irq,
return IRQ_HANDLED;
}
+static void mmci_write_sdio_irq_bit(struct mmci_host *host, int enable)
+{
+ void __iomem *base = host->base;
+ u32 mask = readl_relaxed(base + MMCIMASK0);
+
+ if (enable)
+ writel_relaxed(mask | MCI_ST_SDIOITMASK, base + MMCIMASK0);
+ else
+ writel_relaxed(mask & ~MCI_ST_SDIOITMASK, base + MMCIMASK0);
+}
+
+static void mmci_signal_sdio_irq(struct mmci_host *host, u32 status)
+{
+ if (status & MCI_ST_SDIOIT) {
+ mmci_write_sdio_irq_bit(host, 0);
+ sdio_signal_irq(host->mmc);
+ }
+}
+
/*
* Handle completion of command and data transfers.
*/
@@ -1805,6 +1828,9 @@ static irqreturn_t mmci_irq(int irq, voi
mmci_data_irq(host, host->data, status);
}
+ if (host->variant->supports_sdio_irq)
+ mmci_signal_sdio_irq(host, status);
+
/*
* Busy detection has been handled by mmci_cmd_irq() above.
* Clear the status bit to prevent polling in IRQ context.
@@ -2041,6 +2067,35 @@ static int mmci_sig_volt_switch(struct m
return ret;
}
+static void mmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct mmci_host *host = mmc_priv(mmc);
+ unsigned long flags;
+
+ if (enable)
+ /* Keep the SDIO mode bit if SDIO irqs are enabled */
+ pm_runtime_get_sync(mmc_dev(mmc));
+
+ spin_lock_irqsave(&host->lock, flags);
+ mmci_write_sdio_irq_bit(host, enable);
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ if (!enable) {
+ pm_runtime_mark_last_busy(mmc_dev(mmc));
+ pm_runtime_put_autosuspend(mmc_dev(mmc));
+ }
+}
+
+static void mmci_ack_sdio_irq(struct mmc_host *mmc)
+{
+ struct mmci_host *host = mmc_priv(mmc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ mmci_write_sdio_irq_bit(host, 1);
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
static struct mmc_host_ops mmci_ops = {
.request = mmci_request,
.pre_req = mmci_pre_request,
@@ -2316,6 +2371,16 @@ static int mmci_probe(struct amba_device
mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
}
+ if (variant->supports_sdio_irq && host->mmc->caps & MMC_CAP_SDIO_IRQ) {
+ mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
+
+ mmci_ops.enable_sdio_irq = mmci_enable_sdio_irq;
+ mmci_ops.ack_sdio_irq = mmci_ack_sdio_irq;
+
+ mmci_write_datactrlreg(host,
+ host->variant->datactrl_mask_sdio);
+ }
+
/* Variants with mandatory busy timeout in HW needs R1B responses. */
if (variant->busy_timeout)
mmc->caps |= MMC_CAP_NEED_RSP_BUSY;
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -331,6 +331,7 @@ enum mmci_busy_state {
* register.
* @opendrain: bitmask identifying the OPENDRAIN bit inside MMCIPOWER register
* @dma_lli: true if variant has dma link list feature.
+ * @supports_sdio_irq: allow SD I/O card to interrupt the host
* @stm32_idmabsize_mask: stm32 sdmmc idma buffer size.
*/
struct variant_data {
@@ -376,6 +377,7 @@ struct variant_data {
u32 start_err;
u32 opendrain;
u8 dma_lli:1;
+ bool supports_sdio_irq;
u32 stm32_idmabsize_mask;
u32 stm32_idmabsize_align;
void (*init)(struct mmci_host *host);

View file

@ -21,7 +21,7 @@ Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
#include <linux/pm_wakeirq.h> #include <linux/pm_wakeirq.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/slab.h> #include <linux/slab.h>
@@ -92,6 +93,7 @@ struct stm32_dwmac { @@ -103,6 +104,7 @@ struct stm32_dwmac {
u32 mode_reg; /* MAC glue-logic mode register */ u32 mode_reg; /* MAC glue-logic mode register */
u32 mode_mask; u32 mode_mask;
struct regmap *regmap; struct regmap *regmap;
@ -29,7 +29,7 @@ Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
u32 speed; u32 speed;
const struct stm32_ops *ops; const struct stm32_ops *ops;
struct device *dev; struct device *dev;
@@ -379,6 +381,16 @@ static int stm32_dwmac_parse_data(struct @@ -443,6 +445,16 @@ static int stm32_dwmac_parse_data(struct
} }
} }
@ -46,7 +46,7 @@ Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
return err; return err;
} }
@@ -444,6 +456,28 @@ static int stm32mp1_parse_data(struct st @@ -508,6 +520,28 @@ static int stm32mp1_parse_data(struct st
return err; return err;
} }
@ -75,7 +75,7 @@ Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
static int stm32_dwmac_probe(struct platform_device *pdev) static int stm32_dwmac_probe(struct platform_device *pdev)
{ {
struct plat_stmmacenet_data *plat_dat; struct plat_stmmacenet_data *plat_dat;
@@ -485,12 +519,18 @@ static int stm32_dwmac_probe(struct plat @@ -549,12 +583,18 @@ static int stm32_dwmac_probe(struct plat
if (ret) if (ret)
return ret; return ret;
@ -95,7 +95,7 @@ Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
err_clk_disable: err_clk_disable:
stm32_dwmac_clk_disable(dwmac, false); stm32_dwmac_clk_disable(dwmac, false);
@@ -511,6 +551,8 @@ static void stm32_dwmac_remove(struct pl @@ -575,6 +615,8 @@ static void stm32_dwmac_remove(struct pl
dev_pm_clear_wake_irq(&pdev->dev); dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false); device_init_wakeup(&pdev->dev, false);
} }

View file

@ -20,7 +20,7 @@ Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
serial0 = &uart4; serial0 = &uart4;
serial1 = &usart1; serial1 = &usart1;
serial2 = &uart8; serial2 = &uart8;
@@ -129,6 +130,30 @@ @@ -208,6 +209,30 @@
}; };
}; };

View file

@ -11,7 +11,7 @@ Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
--- a/arch/arm/boot/dts/st/stm32mp151.dtsi --- a/arch/arm/boot/dts/st/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp151.dtsi +++ b/arch/arm/boot/dts/st/stm32mp151.dtsi
@@ -1642,8 +1642,10 @@ @@ -1721,8 +1721,10 @@
compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
reg = <0x5800a000 0x2000>; reg = <0x5800a000 0x2000>;
reg-names = "stmmaceth"; reg-names = "stmmaceth";