[PATCH v2 2/2] net: stmmac: dwmac-meson: extend phy mode setting

2018-04-27 Thread Yixun Lan
  In the Meson-AXG SoC, the phy mode setting of PRG_ETH0 in the glue layer
is extended from bit[0] to bit[2:0].
  There is no problem if we configure it to the RGMII 1000M PHY mode,
since the register setting is coincidentally compatible with previous one,
but for the RMII 100M PHY mode, the configuration need to be changed to
value - b100.
  This patch was verified with a RTL8201F 100M ethernet PHY.

Signed-off-by: Yixun Lan 
---
 .../ethernet/stmicro/stmmac/dwmac-meson8b.c   | 120 +++---
 1 file changed, 104 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
index 7cb794094a70..4ff231df7322 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -29,6 +30,10 @@
 
 #define PRG_ETH0_RGMII_MODEBIT(0)
 
+#define PRG_ETH0_EXT_PHY_MODE_MASK GENMASK(2, 0)
+#define PRG_ETH0_EXT_RGMII_MODE1
+#define PRG_ETH0_EXT_RMII_MODE 4
+
 /* mux to choose between fclk_div2 (bit unset) and mpll2 (bit set) */
 #define PRG_ETH0_CLK_M250_SEL_SHIFT4
 #define PRG_ETH0_CLK_M250_SEL_MASK GENMASK(4, 4)
@@ -47,12 +52,20 @@
 
 #define MUX_CLK_NUM_PARENTS2
 
+struct meson8b_dwmac;
+
+struct meson8b_dwmac_data {
+   int (*set_phy_mode)(struct meson8b_dwmac *dwmac);
+};
+
 struct meson8b_dwmac {
-   struct device   *dev;
-   void __iomem*regs;
-   phy_interface_t phy_mode;
-   struct clk  *rgmii_tx_clk;
-   u32 tx_delay_ns;
+   struct device   *dev;
+   void __iomem*regs;
+
+   const struct meson8b_dwmac_data *data;
+   phy_interface_t phy_mode;
+   struct clk  *rgmii_tx_clk;
+   u32 tx_delay_ns;
 };
 
 struct meson8b_dwmac_clk_configs {
@@ -171,6 +184,59 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac 
*dwmac)
return 0;
 }
 
+static int meson8b_set_phy_mode(struct meson8b_dwmac *dwmac)
+{
+   switch (dwmac->phy_mode) {
+   case PHY_INTERFACE_MODE_RGMII:
+   case PHY_INTERFACE_MODE_RGMII_RXID:
+   case PHY_INTERFACE_MODE_RGMII_ID:
+   case PHY_INTERFACE_MODE_RGMII_TXID:
+   /* enable RGMII mode */
+   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
+   PRG_ETH0_RGMII_MODE,
+   PRG_ETH0_RGMII_MODE);
+   break;
+   case PHY_INTERFACE_MODE_RMII:
+   /* disable RGMII mode -> enables RMII mode */
+   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
+   PRG_ETH0_RGMII_MODE, 0);
+   break;
+   default:
+   dev_err(dwmac->dev, "fail to set phy-mode %s\n",
+   phy_modes(dwmac->phy_mode));
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int meson_axg_set_phy_mode(struct meson8b_dwmac *dwmac)
+{
+   switch (dwmac->phy_mode) {
+   case PHY_INTERFACE_MODE_RGMII:
+   case PHY_INTERFACE_MODE_RGMII_RXID:
+   case PHY_INTERFACE_MODE_RGMII_ID:
+   case PHY_INTERFACE_MODE_RGMII_TXID:
+   /* enable RGMII mode */
+   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
+   PRG_ETH0_EXT_PHY_MODE_MASK,
+   PRG_ETH0_EXT_RGMII_MODE);
+   break;
+   case PHY_INTERFACE_MODE_RMII:
+   /* disable RGMII mode -> enables RMII mode */
+   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
+   PRG_ETH0_EXT_PHY_MODE_MASK,
+   PRG_ETH0_EXT_RMII_MODE);
+   break;
+   default:
+   dev_err(dwmac->dev, "fail to set phy-mode %s\n",
+   phy_modes(dwmac->phy_mode));
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
 {
int ret;
@@ -188,10 +254,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
 
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_TXID:
-   /* enable RGMII mode */
-   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
-   PRG_ETH0_RGMII_MODE);
-
/* only relevant for RMII mode -> disable in RGMII mode */
meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
PRG_ETH0_INVERTED_RMII_CLK, 0);
@@ -224,10 +286,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
*dwmac)
break;
 
case PHY_INTERFACE_MODE_RMII:
-   /* disable 

Re: [PATCH v2 2/2] net: stmmac: dwmac-meson: extend phy mode setting

2018-05-01 Thread Martin Blumenstingl
Hello Yixun,

On Sat, Apr 28, 2018 at 12:21 PM, Yixun Lan  wrote:
>   In the Meson-AXG SoC, the phy mode setting of PRG_ETH0 in the glue layer
> is extended from bit[0] to bit[2:0].
>   There is no problem if we configure it to the RGMII 1000M PHY mode,
> since the register setting is coincidentally compatible with previous one,
> but for the RMII 100M PHY mode, the configuration need to be changed to
> value - b100.
>   This patch was verified with a RTL8201F 100M ethernet PHY.
>
> Signed-off-by: Yixun Lan 
> ---
>  .../ethernet/stmicro/stmmac/dwmac-meson8b.c   | 120 +++---
>  1 file changed, 104 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c 
> b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> index 7cb794094a70..4ff231df7322 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
> @@ -18,6 +18,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -29,6 +30,10 @@
>
>  #define PRG_ETH0_RGMII_MODEBIT(0)
>
> +#define PRG_ETH0_EXT_PHY_MODE_MASK GENMASK(2, 0)
> +#define PRG_ETH0_EXT_RGMII_MODE1
> +#define PRG_ETH0_EXT_RMII_MODE 4
> +
>  /* mux to choose between fclk_div2 (bit unset) and mpll2 (bit set) */
>  #define PRG_ETH0_CLK_M250_SEL_SHIFT4
>  #define PRG_ETH0_CLK_M250_SEL_MASK GENMASK(4, 4)
> @@ -47,12 +52,20 @@
>
>  #define MUX_CLK_NUM_PARENTS2
>
> +struct meson8b_dwmac;
> +
> +struct meson8b_dwmac_data {
> +   int (*set_phy_mode)(struct meson8b_dwmac *dwmac);
> +};
> +
>  struct meson8b_dwmac {
> -   struct device   *dev;
> -   void __iomem*regs;
> -   phy_interface_t phy_mode;
> -   struct clk  *rgmii_tx_clk;
> -   u32 tx_delay_ns;
> +   struct device   *dev;
> +   void __iomem*regs;
> +
> +   const struct meson8b_dwmac_data *data;
> +   phy_interface_t phy_mode;
> +   struct clk  *rgmii_tx_clk;
> +   u32 tx_delay_ns;
>  };
>
>  struct meson8b_dwmac_clk_configs {
> @@ -171,6 +184,59 @@ static int meson8b_init_rgmii_tx_clk(struct 
> meson8b_dwmac *dwmac)
> return 0;
>  }
>
> +static int meson8b_set_phy_mode(struct meson8b_dwmac *dwmac)
> +{
> +   switch (dwmac->phy_mode) {
> +   case PHY_INTERFACE_MODE_RGMII:
> +   case PHY_INTERFACE_MODE_RGMII_RXID:
> +   case PHY_INTERFACE_MODE_RGMII_ID:
> +   case PHY_INTERFACE_MODE_RGMII_TXID:
> +   /* enable RGMII mode */
> +   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
> +   PRG_ETH0_RGMII_MODE,
> +   PRG_ETH0_RGMII_MODE);
> +   break;
> +   case PHY_INTERFACE_MODE_RMII:
> +   /* disable RGMII mode -> enables RMII mode */
> +   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
> +   PRG_ETH0_RGMII_MODE, 0);
> +   break;
> +   default:
> +   dev_err(dwmac->dev, "fail to set phy-mode %s\n",
> +   phy_modes(dwmac->phy_mode));
> +   return -EINVAL;
> +   }
> +
> +   return 0;
> +}
> +
> +static int meson_axg_set_phy_mode(struct meson8b_dwmac *dwmac)
> +{
> +   switch (dwmac->phy_mode) {
> +   case PHY_INTERFACE_MODE_RGMII:
> +   case PHY_INTERFACE_MODE_RGMII_RXID:
> +   case PHY_INTERFACE_MODE_RGMII_ID:
> +   case PHY_INTERFACE_MODE_RGMII_TXID:
> +   /* enable RGMII mode */
> +   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
> +   PRG_ETH0_EXT_PHY_MODE_MASK,
> +   PRG_ETH0_EXT_RGMII_MODE);
> +   break;
> +   case PHY_INTERFACE_MODE_RMII:
> +   /* disable RGMII mode -> enables RMII mode */
if you have to re-send it for whatever reason:
maybe you could remove the comments from meson_axg_set_phy_mode. the
"older" register layout requires un-setting RGMII mode to enable RMII
mode. however, for AXG there seem to be two dedicated values (1 and 4)
for each mode

apart from that:
Acked-by: Martin Blumenstingl 

> +   meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
> +   PRG_ETH0_EXT_PHY_MODE_MASK,
> +   PRG_ETH0_EXT_RMII_MODE);
> +   break;
> +   default:
> +   dev_err(dwmac->dev, "fail to set phy-mode %s\n",
> +   phy_modes(dwmac->phy_mode));
> +   return -EINVAL;
> +   }
> +
> +   return 0;
> +}
> +
>  static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
>  {
> int ret;
> @@ -188,10 +254,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac 
> *dwmac)
>
> case PHY_I