Message ID | 20240614130812.72425-3-christophe.roullier@foss.st.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Series to deliver Ethernet for STM32MP25 | expand |
On 6/14/24 3:08 PM, Christophe Roullier wrote: [...] > +static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data *plat_dat) > +{ > + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; > + u32 reg = dwmac->mode_reg; > + int val = 0; > + > + switch (plat_dat->mac_interface) { > + case PHY_INTERFACE_MODE_MII: > + break; dwmac->enable_eth_ck does not apply to MII mode ? Why ? > + case PHY_INTERFACE_MODE_GMII: > + if (dwmac->enable_eth_ck) > + val |= SYSCFG_ETHCR_ETH_CLK_SEL; > + break; > + case PHY_INTERFACE_MODE_RMII: > + val = SYSCFG_ETHCR_ETH_SEL_RMII; > + if (dwmac->enable_eth_ck) > + val |= SYSCFG_ETHCR_ETH_REF_CLK_SEL; > + break; > + case PHY_INTERFACE_MODE_RGMII: > + case PHY_INTERFACE_MODE_RGMII_ID: > + case PHY_INTERFACE_MODE_RGMII_RXID: > + case PHY_INTERFACE_MODE_RGMII_TXID: > + val = SYSCFG_ETHCR_ETH_SEL_RGMII; > + if (dwmac->enable_eth_ck) > + val |= SYSCFG_ETHCR_ETH_CLK_SEL; > + break; > + default: > + 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)); > + > + /* select PTP (IEEE1588) clock selection from RCC (ck_ker_ethxptp) */ Drop extra leading space. Sentence starts with capital letter. > + val |= SYSCFG_ETHCR_ETH_PTP_CLK_SEL; > + > + /* Update ETHCR (set register) */ > + return regmap_update_bits(dwmac->regmap, reg, > + SYSCFG_MP2_ETH_MASK, val); > +} > + > static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) > { > int ret; > @@ -292,6 +346,21 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) > return stm32mp1_configure_pmcr(plat_dat); > } > > +static int stm32mp2_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; Is it necessary to duplicate this entire function instead of some: if (is_mp2) return stm32mp2_configure_syscfg(plat_dat); else return stm32mp1_configure_syscfg(plat_dat); ? > + return stm32mp2_configure_syscfg(plat_dat); > +} > + > static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat) > { > struct stm32_dwmac *dwmac = plat_dat->bsp_priv; > @@ -348,12 +417,6 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, > return PTR_ERR(dwmac->clk_rx); > } > > - if (dwmac->ops->parse_data) { > - err = dwmac->ops->parse_data(dwmac, dev); > - if (err) > - return err; > - } > - > /* Get mode register */ > dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); > if (IS_ERR(dwmac->regmap)) > @@ -365,20 +428,14 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, > return err; > } > > - 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) > - dev_err(dev, "Sysconfig register mask must be set (%d)\n", err); > - else > - dev_dbg(dev, "Warning sysconfig register mask not set\n"); > - } > + if (dwmac->ops->parse_data) > + err = dwmac->ops->parse_data(dwmac, dev); Why is this change here ? What is the purpose ? This should be documented in commit message too. The indirect call is not necessary either, simply do if (is_mp2) return err; ... do mp15/13 stuff here ... return err; [...]
Hi Marek, On 6/14/24 15:58, Marek Vasut wrote: > On 6/14/24 3:08 PM, Christophe Roullier wrote: > > [...] > >> +static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data >> *plat_dat) >> +{ >> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; >> + u32 reg = dwmac->mode_reg; >> + int val = 0; >> + >> + switch (plat_dat->mac_interface) { >> + case PHY_INTERFACE_MODE_MII: >> + break; > > dwmac->enable_eth_ck does not apply to MII mode ? Why ? It is like MP1 and MP13, nothing to set in syscfg register for case MII mode wo crystal. > >> + case PHY_INTERFACE_MODE_GMII: >> + if (dwmac->enable_eth_ck) >> + val |= SYSCFG_ETHCR_ETH_CLK_SEL; >> + break; >> + case PHY_INTERFACE_MODE_RMII: >> + val = SYSCFG_ETHCR_ETH_SEL_RMII; >> + if (dwmac->enable_eth_ck) >> + val |= SYSCFG_ETHCR_ETH_REF_CLK_SEL; >> + break; >> + case PHY_INTERFACE_MODE_RGMII: >> + case PHY_INTERFACE_MODE_RGMII_ID: >> + case PHY_INTERFACE_MODE_RGMII_RXID: >> + case PHY_INTERFACE_MODE_RGMII_TXID: >> + val = SYSCFG_ETHCR_ETH_SEL_RGMII; >> + if (dwmac->enable_eth_ck) >> + val |= SYSCFG_ETHCR_ETH_CLK_SEL; >> + break; >> + default: >> + 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)); >> + >> + /* select PTP (IEEE1588) clock selection from RCC >> (ck_ker_ethxptp) */ > > Drop extra leading space. > Sentence starts with capital letter. ok > >> + val |= SYSCFG_ETHCR_ETH_PTP_CLK_SEL; >> + >> + /* Update ETHCR (set register) */ >> + return regmap_update_bits(dwmac->regmap, reg, >> + SYSCFG_MP2_ETH_MASK, val); >> +} >> + >> static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) >> { >> int ret; >> @@ -292,6 +346,21 @@ static int stm32mp1_set_mode(struct >> plat_stmmacenet_data *plat_dat) >> return stm32mp1_configure_pmcr(plat_dat); >> } >> +static int stm32mp2_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; > > > Is it necessary to duplicate this entire function instead of some: > > if (is_mp2) > return stm32mp2_configure_syscfg(plat_dat); > else > return stm32mp1_configure_syscfg(plat_dat); > > ? ok I would like to avoid to use is_mp2 boolean but you are right it is simplify visibility of the code. > >> + return stm32mp2_configure_syscfg(plat_dat); >> +} >> + >> static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat) >> { >> struct stm32_dwmac *dwmac = plat_dat->bsp_priv; >> @@ -348,12 +417,6 @@ static int stm32_dwmac_parse_data(struct >> stm32_dwmac *dwmac, >> return PTR_ERR(dwmac->clk_rx); >> } >> - if (dwmac->ops->parse_data) { >> - err = dwmac->ops->parse_data(dwmac, dev); >> - if (err) >> - return err; >> - } >> - >> /* Get mode register */ >> dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); >> if (IS_ERR(dwmac->regmap)) >> @@ -365,20 +428,14 @@ static int stm32_dwmac_parse_data(struct >> stm32_dwmac *dwmac, >> return err; >> } >> - 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) >> - dev_err(dev, "Sysconfig register mask must be set >> (%d)\n", err); >> - else >> - dev_dbg(dev, "Warning sysconfig register mask not set\n"); >> - } >> + if (dwmac->ops->parse_data) >> + err = dwmac->ops->parse_data(dwmac, dev); > > Why is this change here ? What is the purpose ? > This should be documented in commit message too. > > The indirect call is not necessary either, simply do > > if (is_mp2) > return err; > > ... do mp15/13 stuff here ... > > return err; Right, with use of is_mp2 variable it is more simple > > [...]
On 6/17/24 1:23 PM, Christophe ROULLIER wrote: Hi, >>> +static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data >>> *plat_dat) >>> +{ >>> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; >>> + u32 reg = dwmac->mode_reg; >>> + int val = 0; >>> + >>> + switch (plat_dat->mac_interface) { >>> + case PHY_INTERFACE_MODE_MII: >>> + break; >> >> dwmac->enable_eth_ck does not apply to MII mode ? Why ? > > It is like MP1 and MP13, nothing to set in syscfg register for case MII > mode wo crystal. Have a look at STM32MP15xx RM0436 Figure 83. Peripheral clock distribution for Ethernet. If RCC (top-left corner of the figure) generates 25 MHz MII clock (yellow line) on eth_clk_fb (top-right corner), can I set ETH_REF_CLK_SEL to position '1' and ETH_SEL[2] to '0' and feed ETH (right side) clk_rx_i input with 25 MHz clock that way ? I seems like this should be possible, at least theoretically. Can you check with the hardware/silicon people ? As a result, the MII/RMII mode would behave in a very similar way, and so would GMII/RGMII mode behave in a very similar way. Effectively you would end up with this (notice the fallthrough statements): + case PHY_INTERFACE_MODE_RMII: + val = SYSCFG_ETHCR_ETH_SEL_RMII; + fallthrough; + case PHY_INTERFACE_MODE_MII: + if (dwmac->enable_eth_ck) + val |= SYSCFG_ETHCR_ETH_REF_CLK_SEL; + break; + + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + val = SYSCFG_ETHCR_ETH_SEL_RGMII; + fallthrough; + case PHY_INTERFACE_MODE_GMII: + if (dwmac->enable_eth_ck) + val |= SYSCFG_ETHCR_ETH_CLK_SEL; + break; [...]
Hi Marek, On 6/17/24 17:57, Marek Vasut wrote: > On 6/17/24 1:23 PM, Christophe ROULLIER wrote: > > Hi, > >>>> +static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data >>>> *plat_dat) >>>> +{ >>>> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; >>>> + u32 reg = dwmac->mode_reg; >>>> + int val = 0; >>>> + >>>> + switch (plat_dat->mac_interface) { >>>> + case PHY_INTERFACE_MODE_MII: >>>> + break; >>> >>> dwmac->enable_eth_ck does not apply to MII mode ? Why ? >> >> It is like MP1 and MP13, nothing to set in syscfg register for case >> MII mode wo crystal. > > Have a look at STM32MP15xx RM0436 Figure 83. Peripheral clock > distribution for Ethernet. > > If RCC (top-left corner of the figure) generates 25 MHz MII clock > (yellow line) on eth_clk_fb (top-right corner), can I set > ETH_REF_CLK_SEL to position '1' and ETH_SEL[2] to '0' and feed ETH > (right side) clk_rx_i input with 25 MHz clock that way ? > > I seems like this should be possible, at least theoretically. Can you > check with the hardware/silicon people ? No it is not possible (it will work if speed (and frequency) is fixed 25Mhz=100Mbps, but for speed 10Mbps (2,5MHz) it will not work. (you can see than diviser are only for RMII mode) > > As a result, the MII/RMII mode would behave in a very similar way, and > so would GMII/RGMII mode behave in a very similar way. Effectively you > would end up with this (notice the fallthrough statements): > > + case PHY_INTERFACE_MODE_RMII: > + val = SYSCFG_ETHCR_ETH_SEL_RMII; > + fallthrough; > + case PHY_INTERFACE_MODE_MII: > + if (dwmac->enable_eth_ck) > + val |= SYSCFG_ETHCR_ETH_REF_CLK_SEL; > + break; > + > + case PHY_INTERFACE_MODE_RGMII: > + case PHY_INTERFACE_MODE_RGMII_ID: > + case PHY_INTERFACE_MODE_RGMII_RXID: > + case PHY_INTERFACE_MODE_RGMII_TXID: > + val = SYSCFG_ETHCR_ETH_SEL_RGMII; > + fallthrough; > + case PHY_INTERFACE_MODE_GMII: > + if (dwmac->enable_eth_ck) > + val |= SYSCFG_ETHCR_ETH_CLK_SEL; > + break; > > [...]
On 6/18/24 11:09 AM, Christophe ROULLIER wrote: Hi, >>>>> +static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data >>>>> *plat_dat) >>>>> +{ >>>>> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; >>>>> + u32 reg = dwmac->mode_reg; >>>>> + int val = 0; >>>>> + >>>>> + switch (plat_dat->mac_interface) { >>>>> + case PHY_INTERFACE_MODE_MII: >>>>> + break; >>>> >>>> dwmac->enable_eth_ck does not apply to MII mode ? Why ? >>> >>> It is like MP1 and MP13, nothing to set in syscfg register for case >>> MII mode wo crystal. >> >> Have a look at STM32MP15xx RM0436 Figure 83. Peripheral clock >> distribution for Ethernet. >> >> If RCC (top-left corner of the figure) generates 25 MHz MII clock >> (yellow line) on eth_clk_fb (top-right corner), can I set >> ETH_REF_CLK_SEL to position '1' and ETH_SEL[2] to '0' and feed ETH >> (right side) clk_rx_i input with 25 MHz clock that way ? >> >> I seems like this should be possible, at least theoretically. Can you >> check with the hardware/silicon people ? > No it is not possible (it will work if speed (and frequency) is fixed > 25Mhz=100Mbps, but for speed 10Mbps (2,5MHz) it will not work. Could the pll4_p_ck or pll3_q_ck generate either 25 MHz or 2.5 MHz as needed in that case ? Then it would work, right ? > (you can > see than diviser are only for RMII mode) Do you refer to /2 and /20 dividers to the left of mac_speed_o[0] ?
Hi Marek, On 6/18/24 17:00, Marek Vasut wrote: > On 6/18/24 11:09 AM, Christophe ROULLIER wrote: > > Hi, > >>>>>> +static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data >>>>>> *plat_dat) >>>>>> +{ >>>>>> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; >>>>>> + u32 reg = dwmac->mode_reg; >>>>>> + int val = 0; >>>>>> + >>>>>> + switch (plat_dat->mac_interface) { >>>>>> + case PHY_INTERFACE_MODE_MII: >>>>>> + break; >>>>> >>>>> dwmac->enable_eth_ck does not apply to MII mode ? Why ? >>>> >>>> It is like MP1 and MP13, nothing to set in syscfg register for case >>>> MII mode wo crystal. >>> >>> Have a look at STM32MP15xx RM0436 Figure 83. Peripheral clock >>> distribution for Ethernet. >>> >>> If RCC (top-left corner of the figure) generates 25 MHz MII clock >>> (yellow line) on eth_clk_fb (top-right corner), can I set >>> ETH_REF_CLK_SEL to position '1' and ETH_SEL[2] to '0' and feed ETH >>> (right side) clk_rx_i input with 25 MHz clock that way ? >>> >>> I seems like this should be possible, at least theoretically. Can >>> you check with the hardware/silicon people ? >> No it is not possible (it will work if speed (and frequency) is fixed >> 25Mhz=100Mbps, but for speed 10Mbps (2,5MHz) it will not work. > > Could the pll4_p_ck or pll3_q_ck generate either 25 MHz or 2.5 MHz as > needed in that case ? Then it would work, right ? Yes you can set frequency you want for pll4 or pll3, if you set 25MHz and auto-negotiation of speed is 100Mbps it should work (pad ETH_CK of 25MHz clock the PHY and eth_clk_fb set to 25MHz for clk_RX) but if autoneg of speed is 10Mbps, then 2.5MHz is needed for clk_RX (you will provide 25Mhz). For RMII case, frequency from pll (eth_clk_fb) is automatically adjust in function of speed value, thanks to diviser /2, /20 with mac_speed_o. > >> (you can see than diviser are only for RMII mode) > > Do you refer to /2 and /20 dividers to the left of mac_speed_o[0] ?
On 6/19/24 9:41 AM, Christophe ROULLIER wrote: Hi, >>>>>>> +static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data >>>>>>> *plat_dat) >>>>>>> +{ >>>>>>> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; >>>>>>> + u32 reg = dwmac->mode_reg; >>>>>>> + int val = 0; >>>>>>> + >>>>>>> + switch (plat_dat->mac_interface) { >>>>>>> + case PHY_INTERFACE_MODE_MII: >>>>>>> + break; >>>>>> >>>>>> dwmac->enable_eth_ck does not apply to MII mode ? Why ? >>>>> >>>>> It is like MP1 and MP13, nothing to set in syscfg register for case >>>>> MII mode wo crystal. >>>> >>>> Have a look at STM32MP15xx RM0436 Figure 83. Peripheral clock >>>> distribution for Ethernet. >>>> >>>> If RCC (top-left corner of the figure) generates 25 MHz MII clock >>>> (yellow line) on eth_clk_fb (top-right corner), can I set >>>> ETH_REF_CLK_SEL to position '1' and ETH_SEL[2] to '0' and feed ETH >>>> (right side) clk_rx_i input with 25 MHz clock that way ? >>>> >>>> I seems like this should be possible, at least theoretically. Can >>>> you check with the hardware/silicon people ? >>> No it is not possible (it will work if speed (and frequency) is fixed >>> 25Mhz=100Mbps, but for speed 10Mbps (2,5MHz) it will not work. >> >> Could the pll4_p_ck or pll3_q_ck generate either 25 MHz or 2.5 MHz as >> needed in that case ? Then it would work, right ? > > Yes you can set frequency you want for pll4 or pll3, if you set 25MHz > and auto-negotiation of speed is 100Mbps it should work (pad ETH_CK of > 25MHz clock the PHY and eth_clk_fb set to 25MHz for clk_RX) > > but if autoneg of speed is 10Mbps, then 2.5MHz is needed for clk_RX (you > will provide 25Mhz) What if: - Aneg is 10 Mbps - PLL4_P_CK/PLL3_Q_CK = 2.5 MHz - ETH_REF_CLK_SEL = 1 - ETH_SEL[2] = 0 ? Then, clk_rx_i is 2.5 MHz, right ? Does this configuration work ? > . For RMII case, frequency from pll (eth_clk_fb) is > automatically adjust in function of speed value, thanks to diviser /2, > /20 with mac_speed_o.
On 6/19/24 15:14, Marek Vasut wrote: > On 6/19/24 9:41 AM, Christophe ROULLIER wrote: > > Hi, > >>>>>>>> +static int stm32mp2_configure_syscfg(struct >>>>>>>> plat_stmmacenet_data *plat_dat) >>>>>>>> +{ >>>>>>>> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; >>>>>>>> + u32 reg = dwmac->mode_reg; >>>>>>>> + int val = 0; >>>>>>>> + >>>>>>>> + switch (plat_dat->mac_interface) { >>>>>>>> + case PHY_INTERFACE_MODE_MII: >>>>>>>> + break; >>>>>>> >>>>>>> dwmac->enable_eth_ck does not apply to MII mode ? Why ? >>>>>> >>>>>> It is like MP1 and MP13, nothing to set in syscfg register for >>>>>> case MII mode wo crystal. >>>>> >>>>> Have a look at STM32MP15xx RM0436 Figure 83. Peripheral clock >>>>> distribution for Ethernet. >>>>> >>>>> If RCC (top-left corner of the figure) generates 25 MHz MII clock >>>>> (yellow line) on eth_clk_fb (top-right corner), can I set >>>>> ETH_REF_CLK_SEL to position '1' and ETH_SEL[2] to '0' and feed ETH >>>>> (right side) clk_rx_i input with 25 MHz clock that way ? >>>>> >>>>> I seems like this should be possible, at least theoretically. Can >>>>> you check with the hardware/silicon people ? >>>> No it is not possible (it will work if speed (and frequency) is >>>> fixed 25Mhz=100Mbps, but for speed 10Mbps (2,5MHz) it will not work. >>> >>> Could the pll4_p_ck or pll3_q_ck generate either 25 MHz or 2.5 MHz >>> as needed in that case ? Then it would work, right ? >> >> Yes you can set frequency you want for pll4 or pll3, if you set 25MHz >> and auto-negotiation of speed is 100Mbps it should work (pad ETH_CK >> of 25MHz clock the PHY and eth_clk_fb set to 25MHz for clk_RX) >> >> but if autoneg of speed is 10Mbps, then 2.5MHz is needed for clk_RX >> (you will provide 25Mhz) > > What if: > > - Aneg is 10 Mbps > - PLL4_P_CK/PLL3_Q_CK = 2.5 MHz > - ETH_REF_CLK_SEL = 1 > - ETH_SEL[2] = 0 > > ? > > Then, clk_rx_i is 2.5 MHz, right ? Yes that right > > Does this configuration work ? For me no, because PHY Ethernet Oscillator/cristal need in PAD 25Mhz or 50Mhz, I think it is does not work if oscillator frequency provided is 2.5MHz (To my knowledge there is no Ethernet PHY which have oscillator working to 2.5MHz) > >> . For RMII case, frequency from pll (eth_clk_fb) is automatically >> adjust in function of speed value, thanks to diviser /2, /20 with >> mac_speed_o.
On 6/19/24 5:40 PM, Christophe ROULLIER wrote: > > On 6/19/24 15:14, Marek Vasut wrote: >> On 6/19/24 9:41 AM, Christophe ROULLIER wrote: >> >> Hi, >> >>>>>>>>> +static int stm32mp2_configure_syscfg(struct >>>>>>>>> plat_stmmacenet_data *plat_dat) >>>>>>>>> +{ >>>>>>>>> + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; >>>>>>>>> + u32 reg = dwmac->mode_reg; >>>>>>>>> + int val = 0; >>>>>>>>> + >>>>>>>>> + switch (plat_dat->mac_interface) { >>>>>>>>> + case PHY_INTERFACE_MODE_MII: >>>>>>>>> + break; >>>>>>>> >>>>>>>> dwmac->enable_eth_ck does not apply to MII mode ? Why ? >>>>>>> >>>>>>> It is like MP1 and MP13, nothing to set in syscfg register for >>>>>>> case MII mode wo crystal. >>>>>> >>>>>> Have a look at STM32MP15xx RM0436 Figure 83. Peripheral clock >>>>>> distribution for Ethernet. >>>>>> >>>>>> If RCC (top-left corner of the figure) generates 25 MHz MII clock >>>>>> (yellow line) on eth_clk_fb (top-right corner), can I set >>>>>> ETH_REF_CLK_SEL to position '1' and ETH_SEL[2] to '0' and feed ETH >>>>>> (right side) clk_rx_i input with 25 MHz clock that way ? >>>>>> >>>>>> I seems like this should be possible, at least theoretically. Can >>>>>> you check with the hardware/silicon people ? >>>>> No it is not possible (it will work if speed (and frequency) is >>>>> fixed 25Mhz=100Mbps, but for speed 10Mbps (2,5MHz) it will not work. >>>> >>>> Could the pll4_p_ck or pll3_q_ck generate either 25 MHz or 2.5 MHz >>>> as needed in that case ? Then it would work, right ? >>> >>> Yes you can set frequency you want for pll4 or pll3, if you set 25MHz >>> and auto-negotiation of speed is 100Mbps it should work (pad ETH_CK >>> of 25MHz clock the PHY and eth_clk_fb set to 25MHz for clk_RX) >>> >>> but if autoneg of speed is 10Mbps, then 2.5MHz is needed for clk_RX >>> (you will provide 25Mhz) >> >> What if: >> >> - Aneg is 10 Mbps >> - PLL4_P_CK/PLL3_Q_CK = 2.5 MHz >> - ETH_REF_CLK_SEL = 1 >> - ETH_SEL[2] = 0 >> >> ? >> >> Then, clk_rx_i is 2.5 MHz, right ? > Yes that right >> >> Does this configuration work ? > For me no, because PHY Ethernet Oscillator/cristal need in PAD 25Mhz or > 50Mhz, I think it is does not work if oscillator frequency provided is > 2.5MHz (To my knowledge there is no Ethernet PHY which have oscillator > working to 2.5MHz) Would it work if the PHY had a dedicated Xtal , while the clocking of the MAC was done using RCC ?
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c index b2db0e26c4e4..49685fc9c7ee 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -53,7 +53,18 @@ #define SYSCFG_MCU_ETH_SEL_MII 0 #define SYSCFG_MCU_ETH_SEL_RMII 1 -/* STM32MP1 register definitions +/* STM32MP2 register definitions */ +#define SYSCFG_MP2_ETH_MASK GENMASK(31, 0) + +#define SYSCFG_ETHCR_ETH_PTP_CLK_SEL BIT(2) +#define SYSCFG_ETHCR_ETH_CLK_SEL BIT(1) +#define SYSCFG_ETHCR_ETH_REF_CLK_SEL BIT(0) + +#define SYSCFG_ETHCR_ETH_SEL_MII 0 +#define SYSCFG_ETHCR_ETH_SEL_RGMII BIT(4) +#define SYSCFG_ETHCR_ETH_SEL_RMII BIT(6) + +/* STM32MPx register definitions * * Below table summarizes the clock requirement and clock sources for * supported phy interface modes. @@ -277,6 +288,49 @@ static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat) dwmac->mode_mask, val); } +static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data *plat_dat) +{ + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; + u32 reg = dwmac->mode_reg; + int val = 0; + + switch (plat_dat->mac_interface) { + case PHY_INTERFACE_MODE_MII: + break; + case PHY_INTERFACE_MODE_GMII: + if (dwmac->enable_eth_ck) + val |= SYSCFG_ETHCR_ETH_CLK_SEL; + break; + case PHY_INTERFACE_MODE_RMII: + val = SYSCFG_ETHCR_ETH_SEL_RMII; + if (dwmac->enable_eth_ck) + val |= SYSCFG_ETHCR_ETH_REF_CLK_SEL; + break; + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + val = SYSCFG_ETHCR_ETH_SEL_RGMII; + if (dwmac->enable_eth_ck) + val |= SYSCFG_ETHCR_ETH_CLK_SEL; + break; + default: + 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)); + + /* select PTP (IEEE1588) clock selection from RCC (ck_ker_ethxptp) */ + val |= SYSCFG_ETHCR_ETH_PTP_CLK_SEL; + + /* Update ETHCR (set register) */ + return regmap_update_bits(dwmac->regmap, reg, + SYSCFG_MP2_ETH_MASK, val); +} + static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) { int ret; @@ -292,6 +346,21 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) return stm32mp1_configure_pmcr(plat_dat); } +static int stm32mp2_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 stm32mp2_configure_syscfg(plat_dat); +} + static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat) { struct stm32_dwmac *dwmac = plat_dat->bsp_priv; @@ -348,12 +417,6 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, return PTR_ERR(dwmac->clk_rx); } - if (dwmac->ops->parse_data) { - err = dwmac->ops->parse_data(dwmac, dev); - if (err) - return err; - } - /* Get mode register */ dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); if (IS_ERR(dwmac->regmap)) @@ -365,20 +428,14 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, return err; } - 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) - dev_err(dev, "Sysconfig register mask must be set (%d)\n", err); - else - dev_dbg(dev, "Warning sysconfig register mask not set\n"); - } + if (dwmac->ops->parse_data) + err = dwmac->ops->parse_data(dwmac, dev); return err; } -static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, - struct device *dev) +static int stm32mpx_common_parse_data(struct stm32_dwmac *dwmac, + struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct device_node *np = dev->of_node; @@ -439,6 +496,27 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, return err; } +static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, + struct device *dev) +{ + struct device_node *np = dev->of_node; + int err = 0; + + if (stm32mpx_common_parse_data(dwmac, dev)) + return err; + + 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) + 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; +} + static int stm32_dwmac_probe(struct platform_device *pdev) { struct plat_stmmacenet_data *plat_dat; @@ -586,10 +664,19 @@ static struct stm32_ops stm32mp13_dwmac_data = { .clk_rx_enable_in_suspend = true }; +static struct stm32_ops stm32mp25_dwmac_data = { + .set_mode = stm32mp2_set_mode, + .suspend = stm32mp1_suspend, + .resume = stm32mp1_resume, + .parse_data = stm32mpx_common_parse_data, + .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}, + { .compatible = "st,stm32mp25-dwmac", .data = &stm32mp25_dwmac_data}, { } }; MODULE_DEVICE_TABLE(of, stm32_dwmac_match);
Add Ethernet support for STM32MP25. STM32MP25 is STM32 SOC with 2 GMACs instances. GMAC IP version is SNPS 5.3x. GMAC IP configure with 2 RX and 4 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> --- .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 121 +++++++++++++++--- 1 file changed, 104 insertions(+), 17 deletions(-)