Re: [PATCHv2 1/1] net: ethernet: stmmac: simplify phy modes management for stm32
From: Christophe ROULLIER
Date: Tue Apr 14 2020 - 11:11:22 EST
Hi,
Gentle reminder
Thanks,
Christophe.
On 01/04/2020 16:17, Alexandre Torgue wrote:
> Hi Christophe
>
> On 3/16/20 10:09 AM, 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>
>>
>> ---
>
> Acked-by: Alexandre TORGUE <alexandre.torgue@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;
>> Â }
>>