Message ID | 20240326120745.27581-4-marex@denx.de |
---|---|
State | Accepted |
Commit | d100c1abb778f408691f983c9bf34ed9b4869493 |
Delegated to: | Patrice Chotard |
Headers | show |
Series | net: dwc_eth_qos: Clean up STM32 glue code and add STM32MP13xx support | expand |
On 3/26/24 13:07, Marek Vasut wrote: > Move board_interface_eth_init() into eqos_probe_syscfg_stm32() in STM32 > driver glue code. The eqos_probe_syscfg_stm32() parses STM32 specific DT > properties of this MAC and configures SYSCFG registers accordingly, there > is nothing board specific happening in this function, move it into generic > driver code instead. Drop the now unused duplicates from board files. > > Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com> > Signed-off-by: Marek Vasut <marex@denx.de> > --- > Cc: Christophe Roullier <christophe.roullier@st.com> > Cc: Joe Hershberger <joe.hershberger@ni.com> > Cc: Patrice Chotard <patrice.chotard@foss.st.com> > Cc: Patrick Delaunay <patrick.delaunay@foss.st.com> > Cc: Ramon Fried <rfried.dev@gmail.com> > Cc: u-boot@dh-electronics.com > Cc: uboot-stm32@st-md-mailman.stormreply.com > --- > V2: Add RB from Patrice > --- > board/dhelectronics/dh_stm32mp1/board.c | 82 ----------------------- > board/st/stm32mp1/stm32mp1.c | 82 ----------------------- > drivers/net/dwc_eth_qos_stm32.c | 86 ++++++++++++++++++++++++- > 3 files changed, 84 insertions(+), 166 deletions(-) > > diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c > index d1f662d9701..f179c857116 100644 > --- a/board/dhelectronics/dh_stm32mp1/board.c > +++ b/board/dhelectronics/dh_stm32mp1/board.c > @@ -48,12 +48,10 @@ > > /* SYSCFG registers */ > #define SYSCFG_BOOTR 0x00 > -#define SYSCFG_PMCSETR 0x04 > #define SYSCFG_IOCTRLSETR 0x18 > #define SYSCFG_ICNR 0x1C > #define SYSCFG_CMPCR 0x20 > #define SYSCFG_CMPENSETR 0x24 > -#define SYSCFG_PMCCLRR 0x44 > > #define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) > #define SYSCFG_BOOTR_BOOTPD_SHIFT 4 > @@ -69,16 +67,6 @@ > > #define SYSCFG_CMPENSETR_MPU_EN BIT(0) > > -#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16) > -#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17) > - > -#define SYSCFG_PMCSETR_ETH_SELMII BIT(20) > - > -#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21) > -#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0 > -#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21) > -#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23) > - > #define KS_CCR 0x08 > #define KS_CCR_EEPROM BIT(9) > #define KS_BE0 BIT(12) > @@ -679,76 +667,6 @@ void board_quiesce_devices(void) > #endif > } > > -/* eth init function : weak called in eqos driver */ > -int board_interface_eth_init(struct udevice *dev, > - phy_interface_t interface_type) > -{ > - u8 *syscfg; > - u32 value; > - bool eth_clk_sel_reg = false; > - bool eth_ref_clk_sel_reg = false; > - > - /* Gigabit Ethernet 125MHz clock selection. */ > - eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel"); > - > - /* Ethernet 50Mhz RMII clock selection */ > - eth_ref_clk_sel_reg = > - dev_read_bool(dev, "st,eth-ref-clk-sel"); > - > - syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); > - > - if (!syscfg) > - return -ENODEV; > - > - switch (interface_type) { > - case PHY_INTERFACE_MODE_MII: > - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | > - SYSCFG_PMCSETR_ETH_REF_CLK_SEL; > - debug("%s: PHY_INTERFACE_MODE_MII\n", __func__); > - break; > - case PHY_INTERFACE_MODE_GMII: > - if (eth_clk_sel_reg) > - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | > - SYSCFG_PMCSETR_ETH_CLK_SEL; > - else > - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII; > - debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__); > - break; > - case PHY_INTERFACE_MODE_RMII: > - if (eth_ref_clk_sel_reg) > - value = SYSCFG_PMCSETR_ETH_SEL_RMII | > - SYSCFG_PMCSETR_ETH_REF_CLK_SEL; > - else > - value = SYSCFG_PMCSETR_ETH_SEL_RMII; > - debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__); > - 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 (eth_clk_sel_reg) > - value = SYSCFG_PMCSETR_ETH_SEL_RGMII | > - SYSCFG_PMCSETR_ETH_CLK_SEL; > - else > - value = SYSCFG_PMCSETR_ETH_SEL_RGMII; > - debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__); > - break; > - default: > - debug("%s: Do not manage %d interface\n", > - __func__, interface_type); > - /* Do not manage others interfaces */ > - return -EINVAL; > - } > - > - /* clear and set ETH configuration bits */ > - writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII | > - SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL, > - syscfg + SYSCFG_PMCCLRR); > - writel(value, syscfg + SYSCFG_PMCSETR); > - > - return 0; > -} > - > #if defined(CONFIG_OF_BOARD_SETUP) > int ft_board_setup(void *blob, struct bd_info *bd) > { > diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c > index a17c314daeb..f284b0dfd28 100644 > --- a/board/st/stm32mp1/stm32mp1.c > +++ b/board/st/stm32mp1/stm32mp1.c > @@ -52,12 +52,10 @@ > > /* SYSCFG registers */ > #define SYSCFG_BOOTR 0x00 > -#define SYSCFG_PMCSETR 0x04 > #define SYSCFG_IOCTRLSETR 0x18 > #define SYSCFG_ICNR 0x1C > #define SYSCFG_CMPCR 0x20 > #define SYSCFG_CMPENSETR 0x24 > -#define SYSCFG_PMCCLRR 0x44 > > #define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) > #define SYSCFG_BOOTR_BOOTPD_SHIFT 4 > @@ -73,16 +71,6 @@ > > #define SYSCFG_CMPENSETR_MPU_EN BIT(0) > > -#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16) > -#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17) > - > -#define SYSCFG_PMCSETR_ETH_SELMII BIT(20) > - > -#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21) > -#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0 > -#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21) > -#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23) > - > #define USB_LOW_THRESHOLD_UV 200000 > #define USB_WARNING_LOW_THRESHOLD_UV 660000 > #define USB_START_LOW_THRESHOLD_UV 1230000 > @@ -742,76 +730,6 @@ void board_quiesce_devices(void) > setup_led(LEDST_OFF); > } > > -/* eth init function : weak called in eqos driver */ > -int board_interface_eth_init(struct udevice *dev, > - phy_interface_t interface_type) > -{ > - u8 *syscfg; > - u32 value; > - bool eth_clk_sel_reg = false; > - bool eth_ref_clk_sel_reg = false; > - > - /* Gigabit Ethernet 125MHz clock selection. */ > - eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel"); > - > - /* Ethernet 50Mhz RMII clock selection */ > - eth_ref_clk_sel_reg = > - dev_read_bool(dev, "st,eth-ref-clk-sel"); > - > - syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); > - > - if (!syscfg) > - return -ENODEV; > - > - switch (interface_type) { > - case PHY_INTERFACE_MODE_MII: > - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | > - SYSCFG_PMCSETR_ETH_REF_CLK_SEL; > - log_debug("PHY_INTERFACE_MODE_MII\n"); > - break; > - case PHY_INTERFACE_MODE_GMII: > - if (eth_clk_sel_reg) > - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | > - SYSCFG_PMCSETR_ETH_CLK_SEL; > - else > - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII; > - log_debug("PHY_INTERFACE_MODE_GMII\n"); > - break; > - case PHY_INTERFACE_MODE_RMII: > - if (eth_ref_clk_sel_reg) > - value = SYSCFG_PMCSETR_ETH_SEL_RMII | > - SYSCFG_PMCSETR_ETH_REF_CLK_SEL; > - else > - value = SYSCFG_PMCSETR_ETH_SEL_RMII; > - log_debug("PHY_INTERFACE_MODE_RMII\n"); > - 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 (eth_clk_sel_reg) > - value = SYSCFG_PMCSETR_ETH_SEL_RGMII | > - SYSCFG_PMCSETR_ETH_CLK_SEL; > - else > - value = SYSCFG_PMCSETR_ETH_SEL_RGMII; > - log_debug("PHY_INTERFACE_MODE_RGMII\n"); > - break; > - default: > - log_debug("Do not manage %d interface\n", > - interface_type); > - /* Do not manage others interfaces */ > - return -EINVAL; > - } > - > - /* clear and set ETH configuration bits */ > - writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII | > - SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL, > - syscfg + SYSCFG_PMCCLRR); > - writel(value, syscfg + SYSCFG_PMCSETR); > - > - return 0; > -} > - > enum env_location env_get_location(enum env_operation op, int prio) > { > u32 bootmode = get_bootmode(); > diff --git a/drivers/net/dwc_eth_qos_stm32.c b/drivers/net/dwc_eth_qos_stm32.c > index fd29a604987..7520a136ed0 100644 > --- a/drivers/net/dwc_eth_qos_stm32.c > +++ b/drivers/net/dwc_eth_qos_stm32.c > @@ -24,11 +24,26 @@ > #include <netdev.h> > #include <phy.h> > #include <reset.h> > +#include <syscon.h> > #include <wait_bit.h> > #include <linux/delay.h> > > #include "dwc_eth_qos.h" > > +/* SYSCFG registers */ > +#define SYSCFG_PMCSETR 0x04 > +#define SYSCFG_PMCCLRR 0x44 > + > +#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16) > +#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17) > + > +#define SYSCFG_PMCSETR_ETH_SELMII BIT(20) > + > +#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21) > +#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0 > +#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21) > +#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23) > + > static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev) > { > #ifdef CONFIG_CLK > @@ -108,11 +123,78 @@ static int eqos_stop_clks_stm32(struct udevice *dev) > return 0; > } > > +static int eqos_probe_syscfg_stm32(struct udevice *dev, > + phy_interface_t interface_type) > +{ > + bool eth_ref_clk_sel_reg = false; > + bool eth_clk_sel_reg = false; > + u8 *syscfg; > + u32 value; > + > + /* Gigabit Ethernet 125MHz clock selection. */ > + eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel"); > + > + /* Ethernet 50Mhz RMII clock selection */ > + eth_ref_clk_sel_reg = dev_read_bool(dev, "st,eth-ref-clk-sel"); > + > + syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); > + if (!syscfg) > + return -ENODEV; > + > + switch (interface_type) { > + case PHY_INTERFACE_MODE_MII: > + value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | > + SYSCFG_PMCSETR_ETH_REF_CLK_SEL; > + log_debug("PHY_INTERFACE_MODE_MII\n"); > + break; > + case PHY_INTERFACE_MODE_GMII: > + if (eth_clk_sel_reg) > + value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | > + SYSCFG_PMCSETR_ETH_CLK_SEL; > + else > + value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII; > + log_debug("PHY_INTERFACE_MODE_GMII\n"); > + break; > + case PHY_INTERFACE_MODE_RMII: > + if (eth_ref_clk_sel_reg) > + value = SYSCFG_PMCSETR_ETH_SEL_RMII | > + SYSCFG_PMCSETR_ETH_REF_CLK_SEL; > + else > + value = SYSCFG_PMCSETR_ETH_SEL_RMII; > + log_debug("PHY_INTERFACE_MODE_RMII\n"); > + 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 (eth_clk_sel_reg) > + value = SYSCFG_PMCSETR_ETH_SEL_RGMII | > + SYSCFG_PMCSETR_ETH_CLK_SEL; > + else > + value = SYSCFG_PMCSETR_ETH_SEL_RGMII; > + log_debug("PHY_INTERFACE_MODE_RGMII\n"); > + break; > + default: > + log_debug("Do not manage %d interface\n", > + interface_type); > + /* Do not manage others interfaces */ > + return -EINVAL; > + } > + > + /* clear and set ETH configuration bits */ > + writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII | > + SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL, > + syscfg + SYSCFG_PMCCLRR); > + writel(value, syscfg + SYSCFG_PMCSETR); > + > + return 0; > +} > + > static int eqos_probe_resources_stm32(struct udevice *dev) > { > struct eqos_priv *eqos = dev_get_priv(dev); > - int ret; > phy_interface_t interface; > + int ret; > > debug("%s(dev=%p):\n", __func__, dev); > > @@ -123,7 +205,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev) > return -EINVAL; > } > > - ret = board_interface_eth_init(dev, interface); > + ret = eqos_probe_syscfg_stm32(dev, interface); > if (ret) > return -EINVAL; > Applied on u-boot-stm32/master
diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index d1f662d9701..f179c857116 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -48,12 +48,10 @@ /* SYSCFG registers */ #define SYSCFG_BOOTR 0x00 -#define SYSCFG_PMCSETR 0x04 #define SYSCFG_IOCTRLSETR 0x18 #define SYSCFG_ICNR 0x1C #define SYSCFG_CMPCR 0x20 #define SYSCFG_CMPENSETR 0x24 -#define SYSCFG_PMCCLRR 0x44 #define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) #define SYSCFG_BOOTR_BOOTPD_SHIFT 4 @@ -69,16 +67,6 @@ #define SYSCFG_CMPENSETR_MPU_EN BIT(0) -#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16) -#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17) - -#define SYSCFG_PMCSETR_ETH_SELMII BIT(20) - -#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21) -#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0 -#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21) -#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23) - #define KS_CCR 0x08 #define KS_CCR_EEPROM BIT(9) #define KS_BE0 BIT(12) @@ -679,76 +667,6 @@ void board_quiesce_devices(void) #endif } -/* eth init function : weak called in eqos driver */ -int board_interface_eth_init(struct udevice *dev, - phy_interface_t interface_type) -{ - u8 *syscfg; - u32 value; - bool eth_clk_sel_reg = false; - bool eth_ref_clk_sel_reg = false; - - /* Gigabit Ethernet 125MHz clock selection. */ - eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel"); - - /* Ethernet 50Mhz RMII clock selection */ - eth_ref_clk_sel_reg = - dev_read_bool(dev, "st,eth-ref-clk-sel"); - - syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); - - if (!syscfg) - return -ENODEV; - - switch (interface_type) { - case PHY_INTERFACE_MODE_MII: - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | - SYSCFG_PMCSETR_ETH_REF_CLK_SEL; - debug("%s: PHY_INTERFACE_MODE_MII\n", __func__); - break; - case PHY_INTERFACE_MODE_GMII: - if (eth_clk_sel_reg) - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | - SYSCFG_PMCSETR_ETH_CLK_SEL; - else - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII; - debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__); - break; - case PHY_INTERFACE_MODE_RMII: - if (eth_ref_clk_sel_reg) - value = SYSCFG_PMCSETR_ETH_SEL_RMII | - SYSCFG_PMCSETR_ETH_REF_CLK_SEL; - else - value = SYSCFG_PMCSETR_ETH_SEL_RMII; - debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__); - 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 (eth_clk_sel_reg) - value = SYSCFG_PMCSETR_ETH_SEL_RGMII | - SYSCFG_PMCSETR_ETH_CLK_SEL; - else - value = SYSCFG_PMCSETR_ETH_SEL_RGMII; - debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__); - break; - default: - debug("%s: Do not manage %d interface\n", - __func__, interface_type); - /* Do not manage others interfaces */ - return -EINVAL; - } - - /* clear and set ETH configuration bits */ - writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII | - SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL, - syscfg + SYSCFG_PMCCLRR); - writel(value, syscfg + SYSCFG_PMCSETR); - - return 0; -} - #if defined(CONFIG_OF_BOARD_SETUP) int ft_board_setup(void *blob, struct bd_info *bd) { diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index a17c314daeb..f284b0dfd28 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -52,12 +52,10 @@ /* SYSCFG registers */ #define SYSCFG_BOOTR 0x00 -#define SYSCFG_PMCSETR 0x04 #define SYSCFG_IOCTRLSETR 0x18 #define SYSCFG_ICNR 0x1C #define SYSCFG_CMPCR 0x20 #define SYSCFG_CMPENSETR 0x24 -#define SYSCFG_PMCCLRR 0x44 #define SYSCFG_BOOTR_BOOT_MASK GENMASK(2, 0) #define SYSCFG_BOOTR_BOOTPD_SHIFT 4 @@ -73,16 +71,6 @@ #define SYSCFG_CMPENSETR_MPU_EN BIT(0) -#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16) -#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17) - -#define SYSCFG_PMCSETR_ETH_SELMII BIT(20) - -#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21) -#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0 -#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21) -#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23) - #define USB_LOW_THRESHOLD_UV 200000 #define USB_WARNING_LOW_THRESHOLD_UV 660000 #define USB_START_LOW_THRESHOLD_UV 1230000 @@ -742,76 +730,6 @@ void board_quiesce_devices(void) setup_led(LEDST_OFF); } -/* eth init function : weak called in eqos driver */ -int board_interface_eth_init(struct udevice *dev, - phy_interface_t interface_type) -{ - u8 *syscfg; - u32 value; - bool eth_clk_sel_reg = false; - bool eth_ref_clk_sel_reg = false; - - /* Gigabit Ethernet 125MHz clock selection. */ - eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel"); - - /* Ethernet 50Mhz RMII clock selection */ - eth_ref_clk_sel_reg = - dev_read_bool(dev, "st,eth-ref-clk-sel"); - - syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); - - if (!syscfg) - return -ENODEV; - - switch (interface_type) { - case PHY_INTERFACE_MODE_MII: - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | - SYSCFG_PMCSETR_ETH_REF_CLK_SEL; - log_debug("PHY_INTERFACE_MODE_MII\n"); - break; - case PHY_INTERFACE_MODE_GMII: - if (eth_clk_sel_reg) - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | - SYSCFG_PMCSETR_ETH_CLK_SEL; - else - value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII; - log_debug("PHY_INTERFACE_MODE_GMII\n"); - break; - case PHY_INTERFACE_MODE_RMII: - if (eth_ref_clk_sel_reg) - value = SYSCFG_PMCSETR_ETH_SEL_RMII | - SYSCFG_PMCSETR_ETH_REF_CLK_SEL; - else - value = SYSCFG_PMCSETR_ETH_SEL_RMII; - log_debug("PHY_INTERFACE_MODE_RMII\n"); - 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 (eth_clk_sel_reg) - value = SYSCFG_PMCSETR_ETH_SEL_RGMII | - SYSCFG_PMCSETR_ETH_CLK_SEL; - else - value = SYSCFG_PMCSETR_ETH_SEL_RGMII; - log_debug("PHY_INTERFACE_MODE_RGMII\n"); - break; - default: - log_debug("Do not manage %d interface\n", - interface_type); - /* Do not manage others interfaces */ - return -EINVAL; - } - - /* clear and set ETH configuration bits */ - writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII | - SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL, - syscfg + SYSCFG_PMCCLRR); - writel(value, syscfg + SYSCFG_PMCSETR); - - return 0; -} - enum env_location env_get_location(enum env_operation op, int prio) { u32 bootmode = get_bootmode(); diff --git a/drivers/net/dwc_eth_qos_stm32.c b/drivers/net/dwc_eth_qos_stm32.c index fd29a604987..7520a136ed0 100644 --- a/drivers/net/dwc_eth_qos_stm32.c +++ b/drivers/net/dwc_eth_qos_stm32.c @@ -24,11 +24,26 @@ #include <netdev.h> #include <phy.h> #include <reset.h> +#include <syscon.h> #include <wait_bit.h> #include <linux/delay.h> #include "dwc_eth_qos.h" +/* SYSCFG registers */ +#define SYSCFG_PMCSETR 0x04 +#define SYSCFG_PMCCLRR 0x44 + +#define SYSCFG_PMCSETR_ETH_CLK_SEL BIT(16) +#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL BIT(17) + +#define SYSCFG_PMCSETR_ETH_SELMII BIT(20) + +#define SYSCFG_PMCSETR_ETH_SEL_MASK GENMASK(23, 21) +#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0 +#define SYSCFG_PMCSETR_ETH_SEL_RGMII BIT(21) +#define SYSCFG_PMCSETR_ETH_SEL_RMII BIT(23) + static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev) { #ifdef CONFIG_CLK @@ -108,11 +123,78 @@ static int eqos_stop_clks_stm32(struct udevice *dev) return 0; } +static int eqos_probe_syscfg_stm32(struct udevice *dev, + phy_interface_t interface_type) +{ + bool eth_ref_clk_sel_reg = false; + bool eth_clk_sel_reg = false; + u8 *syscfg; + u32 value; + + /* Gigabit Ethernet 125MHz clock selection. */ + eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel"); + + /* Ethernet 50Mhz RMII clock selection */ + eth_ref_clk_sel_reg = dev_read_bool(dev, "st,eth-ref-clk-sel"); + + syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG); + if (!syscfg) + return -ENODEV; + + switch (interface_type) { + case PHY_INTERFACE_MODE_MII: + value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | + SYSCFG_PMCSETR_ETH_REF_CLK_SEL; + log_debug("PHY_INTERFACE_MODE_MII\n"); + break; + case PHY_INTERFACE_MODE_GMII: + if (eth_clk_sel_reg) + value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII | + SYSCFG_PMCSETR_ETH_CLK_SEL; + else + value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII; + log_debug("PHY_INTERFACE_MODE_GMII\n"); + break; + case PHY_INTERFACE_MODE_RMII: + if (eth_ref_clk_sel_reg) + value = SYSCFG_PMCSETR_ETH_SEL_RMII | + SYSCFG_PMCSETR_ETH_REF_CLK_SEL; + else + value = SYSCFG_PMCSETR_ETH_SEL_RMII; + log_debug("PHY_INTERFACE_MODE_RMII\n"); + 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 (eth_clk_sel_reg) + value = SYSCFG_PMCSETR_ETH_SEL_RGMII | + SYSCFG_PMCSETR_ETH_CLK_SEL; + else + value = SYSCFG_PMCSETR_ETH_SEL_RGMII; + log_debug("PHY_INTERFACE_MODE_RGMII\n"); + break; + default: + log_debug("Do not manage %d interface\n", + interface_type); + /* Do not manage others interfaces */ + return -EINVAL; + } + + /* clear and set ETH configuration bits */ + writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII | + SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL, + syscfg + SYSCFG_PMCCLRR); + writel(value, syscfg + SYSCFG_PMCSETR); + + return 0; +} + static int eqos_probe_resources_stm32(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); - int ret; phy_interface_t interface; + int ret; debug("%s(dev=%p):\n", __func__, dev); @@ -123,7 +205,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev) return -EINVAL; } - ret = board_interface_eth_init(dev, interface); + ret = eqos_probe_syscfg_stm32(dev, interface); if (ret) return -EINVAL;