Re: [PATCHv2 1/1] net: ethernet: stmmac: simplify phy modes management for stm32

From: Christophe ROULLIER
Date: Tue Mar 24 2020 - 03:05:56 EST


Hi,

Gentle reminder

Thanks in advance.
Christophe.



On 16/03/2020 10:09, Christophe Roullier wrote:
> No new feature, just to simplify stm32 part to be easier to use.
> Add by default all Ethernet clocks in DT, and activate or not in function
> of phy mode, clock frequency, if property "st,ext-phyclk" is set or not.
> Keep backward compatibility
> -----------------------------------------------------------------------
> |PHY_MODE | Normal | PHY wo crystal| PHY wo crystal | No 125Mhz |
> | | | 25MHz | 50MHz | from PHY |
> -----------------------------------------------------------------------
> | MII | - | eth-ck | n/a | n/a |
> | | | st,ext-phyclk | | |
> -----------------------------------------------------------------------
> | GMII | - | eth-ck | n/a | n/a |
> | | | st,ext-phyclk | | |
> -----------------------------------------------------------------------
> | RGMII | - | eth-ck | n/a | eth-ck |
> | | | st,ext-phyclk | |st,eth-clk-sel|
> | | | | | or |
> | | | | | st,ext-phyclk|
> ------------------------------------------------------------------------
> | RMII | - | eth-ck | eth-ck | n/a |
> | | | st,ext-phyclk | st,eth-ref-clk-sel | |
> | | | | or st,ext-phyclk | |
> ------------------------------------------------------------------------
>
> Signed-off-by: Christophe Roullier <christophe.roullier@xxxxxx>
>
> ---
> .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 74 +++++++++++--------
> 1 file changed, 44 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> index b2dc99289687..5d4df4c5254e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> @@ -29,6 +29,11 @@
> #define SYSCFG_PMCR_ETH_CLK_SEL BIT(16)
> #define SYSCFG_PMCR_ETH_REF_CLK_SEL BIT(17)
>
> +/* CLOCK feed to PHY*/
> +#define ETH_CK_F_25M 25000000
> +#define ETH_CK_F_50M 50000000
> +#define ETH_CK_F_125M 125000000
> +
> /* Ethernet PHY interface selection in register SYSCFG Configuration
> *------------------------------------------
> * src |BIT(23)| BIT(22)| BIT(21)|BIT(20)|
> @@ -58,33 +63,20 @@
> *| | | 25MHz | 50MHz | |
> * ---------------------------------------------------------------------------
> *| MII | - | eth-ck | n/a | n/a |
> - *| | | | | |
> + *| | | st,ext-phyclk | | |
> * ---------------------------------------------------------------------------
> *| GMII | - | eth-ck | n/a | n/a |
> - *| | | | | |
> + *| | | st,ext-phyclk | | |
> * ---------------------------------------------------------------------------
> - *| RGMII | - | eth-ck | n/a | eth-ck (no pin) |
> - *| | | | | st,eth-clk-sel |
> + *| RGMII | - | eth-ck | n/a | eth-ck |
> + *| | | st,ext-phyclk | | st,eth-clk-sel or|
> + *| | | | | st,ext-phyclk |
> * ---------------------------------------------------------------------------
> *| RMII | - | eth-ck | eth-ck | n/a |
> - *| | | | st,eth-ref-clk-sel | |
> + *| | | st,ext-phyclk | st,eth-ref-clk-sel | |
> + *| | | | or st,ext-phyclk | |
> * ---------------------------------------------------------------------------
> *
> - * BIT(17) : set this bit in RMII mode when you have PHY without crystal 50MHz
> - * BIT(16) : set this bit in GMII/RGMII PHY when you do not want use 125Mhz
> - * from PHY
> - *-----------------------------------------------------
> - * src | BIT(17) | BIT(16) |
> - *-----------------------------------------------------
> - * MII | n/a | n/a |
> - *-----------------------------------------------------
> - * GMII | n/a | st,eth-clk-sel |
> - *-----------------------------------------------------
> - * RGMII | n/a | st,eth-clk-sel |
> - *-----------------------------------------------------
> - * RMII | st,eth-ref-clk-sel | n/a |
> - *-----------------------------------------------------
> - *
> */
>
> struct stm32_dwmac {
> @@ -93,6 +85,8 @@ struct stm32_dwmac {
> struct clk *clk_eth_ck;
> struct clk *clk_ethstp;
> struct clk *syscfg_clk;
> + int ext_phyclk;
> + int enable_eth_ck;
> int eth_clk_sel_reg;
> int eth_ref_clk_sel_reg;
> int irq_pwr_wakeup;
> @@ -155,14 +149,17 @@ static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare)
> ret = clk_prepare_enable(dwmac->syscfg_clk);
> if (ret)
> return ret;
> - ret = clk_prepare_enable(dwmac->clk_eth_ck);
> - if (ret) {
> - clk_disable_unprepare(dwmac->syscfg_clk);
> - 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);
> - clk_disable_unprepare(dwmac->clk_eth_ck);
> + if (dwmac->enable_eth_ck)
> + clk_disable_unprepare(dwmac->clk_eth_ck);
> }
> return ret;
> }
> @@ -170,24 +167,34 @@ static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare)
> static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
> {
> struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
> - u32 reg = dwmac->mode_reg;
> + u32 reg = dwmac->mode_reg, clk_rate;
> int val;
>
> + clk_rate = clk_get_rate(dwmac->clk_eth_ck);
> + dwmac->enable_eth_ck = false;
> switch (plat_dat->interface) {
> case PHY_INTERFACE_MODE_MII:
> + if (clk_rate == ETH_CK_F_25M && 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)
> + if (clk_rate == ETH_CK_F_25M &&
> + (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
> + dwmac->enable_eth_ck = true;
> 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)
> + if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) &&
> + (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) {
> + dwmac->enable_eth_ck = true;
> val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
> + }
> pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n");
> break;
> case PHY_INTERFACE_MODE_RGMII:
> @@ -195,8 +202,11 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
> case PHY_INTERFACE_MODE_RGMII_RXID:
> case PHY_INTERFACE_MODE_RGMII_TXID:
> val = SYSCFG_PMCR_ETH_SEL_RGMII;
> - if (dwmac->eth_clk_sel_reg)
> + if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) &&
> + (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) {
> + dwmac->enable_eth_ck = true;
> val |= SYSCFG_PMCR_ETH_CLK_SEL;
> + }
> pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n");
> break;
> default:
> @@ -294,6 +304,9 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
> struct device_node *np = dev->of_node;
> int err = 0;
>
> + /* Ethernet PHY have no crystal */
> + dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
> +
> /* Gigabit Ethernet 125MHz clock selection. */
> dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel");
>
> @@ -431,7 +444,8 @@ static int stm32mp1_suspend(struct stm32_dwmac *dwmac)
>
> clk_disable_unprepare(dwmac->clk_tx);
> clk_disable_unprepare(dwmac->syscfg_clk);
> - clk_disable_unprepare(dwmac->clk_eth_ck);
> + if (dwmac->enable_eth_ck)
> + clk_disable_unprepare(dwmac->clk_eth_ck);
>
> return ret;
> }