Re: [PATCH] ethernet: stmmac: dwmac-rk: Add GMAC support for px30

2018-05-17 Thread David Wu


Hi Shawn,

Thanks for the suggestion, the most is okay.

在 2018年05月16日 14:34, Shawn Lin 写道:

Hi David,

On 2018/5/16 11:38, David Wu wrote:
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c

index 13133b3..4b2ab71 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -61,6 +61,7 @@ struct rk_priv_data {
  struct clk *mac_clk_tx;
  struct clk *clk_mac_ref;
  struct clk *clk_mac_refout;
+    struct clk *clk_mac_speed;


No need to do anything now but it seems you could consider doing some
cleanup by using clk bulk APIs in the future.


The use of this may seem to be less applicable because there are many 
scenarios using different clocks.





  struct clk *aclk_mac;
  struct clk *pclk_mac;
  struct clk *clk_phy;
@@ -83,6 +84,64 @@ struct rk_priv_data {
  (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : 
soc##_GMAC_TXCLK_DLY_DISABLE) | \
   ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : 
soc##_GMAC_RXCLK_DLY_DISABLE))

+#define PX30_GRF_GMAC_CON1    0X0904


s/0X0904/0x0904 , since the other constants in this file follow the
same format.


+
+/* PX30_GRF_GMAC_CON1 */
+#define PX30_GMAC_PHY_INTF_SEL_RMII    (GRF_CLR_BIT(4) | 
GRF_CLR_BIT(5) | \

+    GRF_BIT(6))
+#define PX30_GMAC_SPEED_10M    GRF_CLR_BIT(2)
+#define PX30_GMAC_SPEED_100M    GRF_BIT(2)
+
+static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+    struct device *dev = _priv->pdev->dev;
+
+    if (IS_ERR(bsp_priv->grf)) {
+    dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+    return;
+    }
+
+    regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
+ PX30_GMAC_PHY_INTF_SEL_RMII);
+}
+
+static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int 
speed)

+{
+    struct device *dev = _priv->pdev->dev;
+    int ret;
+
+    if (IS_ERR(bsp_priv->clk_mac_speed)) {
+    dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
+    return;
+    }
+
+    if (speed == 10) {
+    regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
+ PX30_GMAC_SPEED_10M);
+
+    ret = clk_set_rate(bsp_priv->clk_mac_speed, 250);
+    if (ret)
+    dev_err(dev, "%s: set clk_mac_speed rate 250 failed: 
%d\n",

+    __func__, ret);
+    } else if (speed == 100) {
+    regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
+ PX30_GMAC_SPEED_100M);
+
+    ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500);
+    if (ret)
+    dev_err(dev, "%s: set clk_mac_speed rate 2500 failed: 
%d\n",

+    __func__, ret);


I know it follows the existing examples, but IMHO it duplicates
unnecessary code as all the difference is PX30_GMAC_SPEED_*



i think the difference is the register offset and bits.


+
+    } else {
+    dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
+    }
+}
+
+static const struct rk_gmac_ops px30_ops = {
+    .set_to_rmii = px30_set_to_rmii,
+    .set_rmii_speed = px30_set_rmii_speed,
+};
+
  #define RK3128_GRF_MAC_CON0    0x0168
  #define RK3128_GRF_MAC_CON1    0x016c
@@ -1042,6 +1101,10 @@ static int rk_gmac_clk_init(struct 
plat_stmmacenet_data *plat)

  }
  }
+    bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");


Mightbe it'd be better to use "mac-speed" in DT bindings.


+    if (IS_ERR(bsp_priv->clk_mac_speed))
+    dev_err(dev, "cannot get clock %s\n", "clk_mac_speed");
+


Would you like to handle deferred probe >


No,


  if (bsp_priv->clock_input) {
  dev_info(dev, "clock input from PHY\n");
  } else {
@@ -1424,6 +1487,7 @@ static int rk_gmac_resume(struct device *dev)
  static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, 
rk_gmac_resume);

  static const struct of_device_id rk_gmac_dwmac_match[] = {
+    { .compatible = "rockchip,px30-gmac",    .data = _ops   },
  { .compatible = "rockchip,rk3128-gmac", .data = _ops },
  { .compatible = "rockchip,rk3228-gmac", .data = _ops },
  { .compatible = "rockchip,rk3288-gmac", .data = _ops },









[PATCH] ethernet: stmmac: dwmac-rk: Add GMAC support for px30

2018-05-15 Thread David Wu
Add constants and callback functions for the dwmac on px30 soc.
The base structure is the same, but registers and the bits in
them moved slightly, and add the clk_mac_speed for the select
of mac speed.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 .../devicetree/bindings/net/rockchip-dwmac.txt |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 64 ++
 2 files changed, 65 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt 
b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
index 9c16ee2..3b71da7 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -4,6 +4,7 @@ The device node has following properties.
 
 Required properties:
  - compatible: should be "rockchip,-gamc"
+   "rockchip,px30-gmac":   found on PX30 SoCs
"rockchip,rk3128-gmac": found on RK312x SoCs
"rockchip,rk3228-gmac": found on RK322x SoCs
"rockchip,rk3288-gmac": found on RK3288 SoCs
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 13133b3..4b2ab71 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -61,6 +61,7 @@ struct rk_priv_data {
struct clk *mac_clk_tx;
struct clk *clk_mac_ref;
struct clk *clk_mac_refout;
+   struct clk *clk_mac_speed;
struct clk *aclk_mac;
struct clk *pclk_mac;
struct clk *clk_phy;
@@ -83,6 +84,64 @@ struct rk_priv_data {
(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
 
+#define PX30_GRF_GMAC_CON1 0X0904
+
+/* PX30_GRF_GMAC_CON1 */
+#define PX30_GMAC_PHY_INTF_SEL_RMII(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
+   GRF_BIT(6))
+#define PX30_GMAC_SPEED_10MGRF_CLR_BIT(2)
+#define PX30_GMAC_SPEED_100M   GRF_BIT(2)
+
+static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   if (IS_ERR(bsp_priv->grf)) {
+   dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+   return;
+   }
+
+   regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
+PX30_GMAC_PHY_INTF_SEL_RMII);
+}
+
+static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+   struct device *dev = _priv->pdev->dev;
+   int ret;
+
+   if (IS_ERR(bsp_priv->clk_mac_speed)) {
+   dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
+   return;
+   }
+
+   if (speed == 10) {
+   regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
+PX30_GMAC_SPEED_10M);
+
+   ret = clk_set_rate(bsp_priv->clk_mac_speed, 250);
+   if (ret)
+   dev_err(dev, "%s: set clk_mac_speed rate 250 
failed: %d\n",
+   __func__, ret);
+   } else if (speed == 100) {
+   regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
+PX30_GMAC_SPEED_100M);
+
+   ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500);
+   if (ret)
+   dev_err(dev, "%s: set clk_mac_speed rate 2500 
failed: %d\n",
+   __func__, ret);
+
+   } else {
+   dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
+   }
+}
+
+static const struct rk_gmac_ops px30_ops = {
+   .set_to_rmii = px30_set_to_rmii,
+   .set_rmii_speed = px30_set_rmii_speed,
+};
+
 #define RK3128_GRF_MAC_CON00x0168
 #define RK3128_GRF_MAC_CON10x016c
 
@@ -1042,6 +1101,10 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data 
*plat)
}
}
 
+   bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
+   if (IS_ERR(bsp_priv->clk_mac_speed))
+   dev_err(dev, "cannot get clock %s\n", "clk_mac_speed");
+
if (bsp_priv->clock_input) {
dev_info(dev, "clock input from PHY\n");
} else {
@@ -1424,6 +1487,7 @@ static int rk_gmac_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
 
 static const struct of_device_id rk_gmac_dwmac_match[] = {
+   { .compatible = "rockchip,px30-gmac",   .data = _ops   },
{ .compatible = "rockchip,rk3128-gmac", .data = _ops },
{ .compatible = "rockchip,rk3228-gmac", .data = _ops },
{ .compatible = "rockchip,rk3288-gmac", .data = _ops },
-- 
2.7.4




[PATCH] net: stmmac: dwmac-rk: Add RK3128 GMAC support

2017-09-30 Thread David Wu
Add constants and callback functions for the dwmac on rk3128 soc.
As can be seen, the base structure is the same, only registers
and the bits in them moved slightly.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 .../devicetree/bindings/net/rockchip-dwmac.txt |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 112 +
 2 files changed, 113 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt 
b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
index 6af8eed..9c16ee2 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -4,6 +4,7 @@ The device node has following properties.
 
 Required properties:
  - compatible: should be "rockchip,-gamc"
+   "rockchip,rk3128-gmac": found on RK312x SoCs
"rockchip,rk3228-gmac": found on RK322x SoCs
"rockchip,rk3288-gmac": found on RK3288 SoCs
"rockchip,rk3328-gmac": found on RK3328 SoCs
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 99823f5..13133b3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -83,6 +83,117 @@ struct rk_priv_data {
(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
 
+#define RK3128_GRF_MAC_CON00x0168
+#define RK3128_GRF_MAC_CON10x016c
+
+/* RK3128_GRF_MAC_CON0 */
+#define RK3128_GMAC_TXCLK_DLY_ENABLE   GRF_BIT(14)
+#define RK3128_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(14)
+#define RK3128_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(15)
+#define RK3128_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(15)
+#define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
+#define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
+
+/* RK3128_GRF_MAC_CON1 */
+#define RK3128_GMAC_PHY_INTF_SEL_RGMII \
+   (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
+#define RK3128_GMAC_PHY_INTF_SEL_RMII  \
+   (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
+#define RK3128_GMAC_FLOW_CTRL  GRF_BIT(9)
+#define RK3128_GMAC_FLOW_CTRL_CLR  GRF_CLR_BIT(9)
+#define RK3128_GMAC_SPEED_10M  GRF_CLR_BIT(10)
+#define RK3128_GMAC_SPEED_100M GRF_BIT(10)
+#define RK3128_GMAC_RMII_CLK_25M   GRF_BIT(11)
+#define RK3128_GMAC_RMII_CLK_2_5M  GRF_CLR_BIT(11)
+#define RK3128_GMAC_CLK_125M   (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
+#define RK3128_GMAC_CLK_25M(GRF_BIT(12) | GRF_BIT(13))
+#define RK3128_GMAC_CLK_2_5M   (GRF_CLR_BIT(12) | GRF_BIT(13))
+#define RK3128_GMAC_RMII_MODE  GRF_BIT(14)
+#define RK3128_GMAC_RMII_MODE_CLR  GRF_CLR_BIT(14)
+
+static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
+   int tx_delay, int rx_delay)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   if (IS_ERR(bsp_priv->grf)) {
+   dev_err(dev, "Missing rockchip,grf property\n");
+   return;
+   }
+
+   regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
+RK3128_GMAC_PHY_INTF_SEL_RGMII |
+RK3128_GMAC_RMII_MODE_CLR);
+   regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
+DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
+RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
+RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
+}
+
+static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   if (IS_ERR(bsp_priv->grf)) {
+   dev_err(dev, "Missing rockchip,grf property\n");
+   return;
+   }
+
+   regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
+RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
+}
+
+static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   if (IS_ERR(bsp_priv->grf)) {
+   dev_err(dev, "Missing rockchip,grf property\n");
+   return;
+   }
+
+   if (speed == 10)
+   regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
+RK3128_GMAC_CLK_2_5M);
+   else if (speed == 100)
+   regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
+RK3128_GMAC_CLK_25M);
+   else if (speed == 1000)
+   regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
+RK3128_GMAC_CLK_125M);
+   else
+   dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
+}
+
+static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   

[PATCH] ARM: dts: rk3228-evb: Fix the compiling error

2017-08-22 Thread David Wu
This patch solves the following error:
arch/arm/boot/dts/rk3228-evb.dtb: ERROR (phandle_references): Reference to 
non-existent node or label "phy0"

Fixess db40f15b53e4 ("ARM: dts: rk3228-evb: Enable the integrated PHY for gmac")
Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/boot/dts/rk3228-evb.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
index 456ddf7..1be9daa 100644
--- a/arch/arm/boot/dts/rk3228-evb.dts
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -76,7 +76,7 @@
clock_in_out = "output";
phy-supply = <_phy>;
phy-mode = "rmii";
-   phy-handle = <>;
+   phy-handle = <>;
status = "okay";
 
mdio {
@@ -84,7 +84,7 @@
#address-cells = <1>;
#size-cells = <0>;
 
-   phy@0 {
+   phy: phy@0 {
compatible = "ethernet-phy-id1234.d400", 
"ethernet-phy-ieee802.3-c22";
reg = <0>;
clocks = < SCLK_MAC_PHY>;
-- 
1.9.1




[PATCH] net: ethernet: stmmac: dwmac-rk: Add rv1108 gmac support

2017-08-21 Thread David Wu
It only supports rmii interface. Add constants and callback functions
for the dwmac on rv1108 socs. As can be seen, the base structure is
the same, only registers and the bits in them moved slightly.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 .../devicetree/bindings/net/rockchip-dwmac.txt |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 53 ++
 2 files changed, 54 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt 
b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
index 8f42755..c132538 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -10,6 +10,7 @@ Required properties:
"rockchip,rk3366-gmac": found on RK3366 SoCs
"rockchip,rk3368-gmac": found on RK3368 SoCs
"rockchip,rk3399-gmac": found on RK3399 SoCs
+   "rockchip,rv1108-gmac": found on RV1108 SoCs
  - reg: addresses and length of the register sets for the device.
  - interrupts: Should contain the GMAC interrupts.
  - interrupt-names: Should contain the interrupt names "macirq".
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 2176403..99823f5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -787,6 +787,58 @@ static void rk3399_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
.set_rmii_speed = rk3399_set_rmii_speed,
 };
 
+#define RV1108_GRF_GMAC_CON0   0X0900
+
+/* RV1108_GRF_GMAC_CON0 */
+#define RV1108_GMAC_PHY_INTF_SEL_RMII  (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
+   GRF_BIT(6))
+#define RV1108_GMAC_FLOW_CTRL  GRF_BIT(3)
+#define RV1108_GMAC_FLOW_CTRL_CLR  GRF_CLR_BIT(3)
+#define RV1108_GMAC_SPEED_10M  GRF_CLR_BIT(2)
+#define RV1108_GMAC_SPEED_100M GRF_BIT(2)
+#define RV1108_GMAC_RMII_CLK_25M   GRF_BIT(7)
+#define RV1108_GMAC_RMII_CLK_2_5M  GRF_CLR_BIT(7)
+
+static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   if (IS_ERR(bsp_priv->grf)) {
+   dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+   return;
+   }
+
+   regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
+RV1108_GMAC_PHY_INTF_SEL_RMII);
+}
+
+static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   if (IS_ERR(bsp_priv->grf)) {
+   dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+   return;
+   }
+
+   if (speed == 10) {
+   regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
+RV1108_GMAC_RMII_CLK_2_5M |
+RV1108_GMAC_SPEED_10M);
+   } else if (speed == 100) {
+   regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
+RV1108_GMAC_RMII_CLK_25M |
+RV1108_GMAC_SPEED_100M);
+   } else {
+   dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
+   }
+}
+
+static const struct rk_gmac_ops rv1108_ops = {
+   .set_to_rmii = rv1108_set_to_rmii,
+   .set_rmii_speed = rv1108_set_rmii_speed,
+};
+
 #define RK_GRF_MACPHY_CON0 0xb00
 #define RK_GRF_MACPHY_CON1 0xb04
 #define RK_GRF_MACPHY_CON2 0xb08
@@ -1267,6 +1319,7 @@ static int rk_gmac_resume(struct device *dev)
{ .compatible = "rockchip,rk3366-gmac", .data = _ops },
{ .compatible = "rockchip,rk3368-gmac", .data = _ops },
{ .compatible = "rockchip,rk3399-gmac", .data = _ops },
+   { .compatible = "rockchip,rv1108-gmac", .data = _ops },
{ }
 };
 MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
-- 
1.9.1




[PATCH v5 11/11] ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

2017-08-10 Thread David Wu
Enable the gmac2phy, make the gmac2phy work on
the rk3328-evb board.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 17 +
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index cf27239..b9f36da 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -50,6 +50,23 @@
chosen {
stdout-path = "serial2:150n8";
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   regulator-name = "vcc_phy";
+   regulator-always-on;
+   regulator-boot-on;
+   };
+};
+
+ {
+   phy-supply = <_phy>;
+   clock_in_out = "output";
+   assigned-clocks = < SCLK_MAC2PHY_SRC>;
+   assigned-clock-rate = <5000>;
+   assigned-clocks = < SCLK_MAC2PHY>;
+   assigned-clock-parents = < SCLK_MAC2PHY_SRC>;
+   status = "okay";
 };
 
  {
-- 
1.9.1




[PATCH v5 10/11] ARM64: dts: rockchip: Add gmac2phy node support for rk3328

2017-08-10 Thread David Wu
The gmac2phy controller of rk3328 is connected to integrated PHY
directly inside, add the node for the integrated PHY support.

Signed-off-by: David Wu <david...@rock-chips.com>
---
changes in v5:
 - Use phy-is-integrated property via PHY node.
 - Move the PHY clock, reset control, pinctrl to PHY node. 

 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 39 
 1 file changed, 39 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0be96ce..d48bf5d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -63,6 +63,8 @@
i2c1 = 
i2c2 = 
i2c3 = 
+   ethernet0 = 
+   ethernet1 = 
};
 
cpus {
@@ -424,6 +426,43 @@
status = "disabled";
};
 
+   gmac2phy: ethernet@ff55 {
+   compatible = "rockchip,rk3328-gmac";
+   reg = <0x0 0xff55 0x0 0x1>;
+   rockchip,grf = <>;
+   interrupts = ;
+   interrupt-names = "macirq";
+   clocks = < SCLK_MAC2PHY_SRC>, < SCLK_MAC2PHY_RXTX>,
+< SCLK_MAC2PHY_RXTX>, < SCLK_MAC2PHY_REF>,
+< ACLK_MAC2PHY>, < PCLK_MAC2PHY>,
+< SCLK_MAC2PHY_OUT>;
+   clock-names = "stmmaceth", "mac_clk_rx",
+ "mac_clk_tx", "clk_mac_ref",
+ "aclk_mac", "pclk_mac",
+ "clk_macphy";
+   resets = < SRST_GMAC2PHY_A>, < SRST_MACPHY>;
+   reset-names = "stmmaceth", "mac-phy";
+   phy-mode = "rmii";
+   phy-handle = <>;
+   status = "disabled";
+
+   mdio {
+   compatible = "snps,dwmac-mdio";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   phy: phy@0 {
+   compatible = "ethernet-phy-id1234.d400", 
"ethernet-phy-ieee802.3-c22";
+   reg = <0>;
+   clocks = < SCLK_MAC2PHY_OUT>;
+   resets = < SRST_MACPHY>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_rxm1 _linkm1>;
+   phy-is-integrated;
+   };
+   };
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
1.9.1




[PATCH v5 09/11] ARM: dts: rk3228-evb: Enable the integrated PHY for gmac

2017-08-10 Thread David Wu
This patch enables the integrated PHY for rk3228 evb board
by default.
To use the external 1000M PHY on evb board, need to make
some switch of evb board to be on.

Signed-off-by: David Wu <david...@rock-chips.com>
Reviewed-by: Florian Fainelli <f.faine...@gmail.com>
---
changes in v5:
 - Use phy-is-integrated property via PHY node.
 - Move the PHY clock and reset control to PHY node.

 arch/arm/boot/dts/rk3228-evb.dts | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
index 5883433..456ddf7 100644
--- a/arch/arm/boot/dts/rk3228-evb.dts
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -50,6 +50,16 @@
device_type = "memory";
reg = <0x6000 0x4000>;
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   enable-active-high;
+   regulator-name = "vcc_phy";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-always-on;
+   regulator-boot-on;
+   };
 };
 
  {
@@ -60,6 +70,30 @@
status = "okay";
 };
 
+ {
+   assigned-clocks = < SCLK_MAC_SRC>;
+   assigned-clock-rates = <5000>;
+   clock_in_out = "output";
+   phy-supply = <_phy>;
+   phy-mode = "rmii";
+   phy-handle = <>;
+   status = "okay";
+
+   mdio {
+   compatible = "snps,dwmac-mdio";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   phy@0 {
+   compatible = "ethernet-phy-id1234.d400", 
"ethernet-phy-ieee802.3-c22";
+   reg = <0>;
+   clocks = < SCLK_MAC_PHY>;
+   resets = < SRST_MACPHY>;
+   phy-is-integrated;
+   };
+   };
+};
+
  {
status = "okay";
 
-- 
1.9.1




[PATCH v5 07/11] net: stmmac: dwmac-rk: Add integrated PHY support for rk3228

2017-08-10 Thread David Wu
There is only one mac controller in rk3228, which could connect to
external PHY or integrated PHY, use the grf_com_mux bit15 to route
external/integrated PHY.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 9019917..b6db3ff 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -86,6 +86,8 @@ struct rk_priv_data {
 #define RK3228_GRF_MAC_CON00x0900
 #define RK3228_GRF_MAC_CON10x0904
 
+#define RK3228_GRF_CON_MUX 0x50
+
 /* RK3228_GRF_MAC_CON0 */
 #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
 #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
@@ -111,6 +113,9 @@ struct rk_priv_data {
 #define RK3228_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3228_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(1)
 
+/* RK3228_GRF_COM_MUX */
+#define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY GRF_BIT(15)
+
 static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -191,11 +196,18 @@ static void rk3228_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3228_GRF_CON_MUX,
+RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
+}
+
 static const struct rk_gmac_ops rk3228_ops = {
.set_to_rgmii = rk3228_set_to_rgmii,
.set_to_rmii = rk3228_set_to_rmii,
.set_rgmii_speed = rk3228_set_rgmii_speed,
.set_rmii_speed = rk3228_set_rmii_speed,
+   .integrated_phy_powerup =  rk3228_integrated_phy_powerup,
 };
 
 #define RK3288_GRF_SOC_CON10x0248
-- 
1.9.1




[PATCH v5 08/11] net: stmmac: dwmac-rk: Add integrated PHY supprot for rk3328

2017-08-10 Thread David Wu
There are two mac controllers in the rk3328, the one connects
to external PHY, and the other one connects to integrated PHY.
Like the mac of external PHY, the integrated PHY's mac also
needs to configure the related mac registers at GRF.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index b6db3ff..2176403 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -323,6 +323,8 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 
 #define RK3328_GRF_MAC_CON00x0900
 #define RK3328_GRF_MAC_CON10x0904
+#define RK3328_GRF_MAC_CON20x0908
+#define RK3328_GRF_MACPHY_CON1 0xb04
 
 /* RK3328_GRF_MAC_CON0 */
 #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
@@ -349,6 +351,9 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 #define RK3328_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3328_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(0)
 
+/* RK3328_GRF_MACPHY_CON1 */
+#define RK3328_MACPHY_RMII_MODEGRF_BIT(9)
+
 static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -373,13 +378,17 @@ static void rk3328_set_to_rgmii(struct rk_priv_data 
*bsp_priv,
 static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
 }
@@ -409,29 +418,40 @@ static void rk3328_set_rgmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
+   reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
if (speed == 10)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_2_5M |
 RK3328_GMAC_SPEED_10M);
else if (speed == 100)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_25M |
 RK3328_GMAC_SPEED_100M);
else
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
+RK3328_MACPHY_RMII_MODE);
+}
+
 static const struct rk_gmac_ops rk3328_ops = {
.set_to_rgmii = rk3328_set_to_rgmii,
.set_to_rmii = rk3328_set_to_rmii,
.set_rgmii_speed = rk3328_set_rgmii_speed,
.set_rmii_speed = rk3328_set_rmii_speed,
+   .integrated_phy_powerup =  rk3328_integrated_phy_powerup,
 };
 
 #define RK3366_GRF_SOC_CON60x0418
-- 
1.9.1




[PATCH v5 06/11] net: stmmac: dwmac-rk: Add integrated PHY support

2017-08-10 Thread David Wu
To make integrated PHY work, need to configure the PHY clock,
PHY cru reset and related registers.

Signed-off-by: David Wu <david...@rock-chips.com>
---
change in v4:
 - PHY is internal or not base on the phy-is-internal property via phy node.

changes in v5:
 - Use phy-is-integrated property via PHY node.
 - Get the PHY clock and reset control from PHY node of device tree.
 - Rename internal to integrated.

 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 99 --
 1 file changed, 95 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index a8e8fd5..9019917 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -41,6 +41,7 @@ struct rk_gmac_ops {
void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
+   void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
 };
 
 struct rk_priv_data {
@@ -52,6 +53,7 @@ struct rk_priv_data {
 
bool clk_enabled;
bool clock_input;
+   bool integrated_phy;
 
struct clk *clk_mac;
struct clk *gmac_clkin;
@@ -61,6 +63,9 @@ struct rk_priv_data {
struct clk *clk_mac_refout;
struct clk *aclk_mac;
struct clk *pclk_mac;
+   struct clk *clk_phy;
+
+   struct reset_control *phy_reset;
 
int tx_delay;
int rx_delay;
@@ -750,9 +755,55 @@ static void rk3399_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
.set_rmii_speed = rk3399_set_rmii_speed,
 };
 
-static int gmac_clk_init(struct rk_priv_data *bsp_priv)
+#define RK_GRF_MACPHY_CON0 0xb00
+#define RK_GRF_MACPHY_CON1 0xb04
+#define RK_GRF_MACPHY_CON2 0xb08
+#define RK_GRF_MACPHY_CON3 0xb0c
+
+#define RK_MACPHY_ENABLE   GRF_BIT(0)
+#define RK_MACPHY_DISABLE  GRF_CLR_BIT(0)
+#define RK_MACPHY_CFG_CLK_50M  GRF_BIT(14)
+#define RK_GMAC2PHY_RMII_MODE  (GRF_BIT(6) | GRF_CLR_BIT(7))
+#define RK_GRF_CON2_MACPHY_ID  HIWORD_UPDATE(0x1234, 0x, 0)
+#define RK_GRF_CON3_MACPHY_ID  HIWORD_UPDATE(0x35, 0x3f, 0)
+
+static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
+{
+   if (priv->ops->integrated_phy_powerup)
+   priv->ops->integrated_phy_powerup(priv);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
+
+   if (priv->phy_reset) {
+   /* PHY needs to be disabled before trying to reset it */
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->phy_reset)
+   reset_control_assert(priv->phy_reset);
+   usleep_range(10, 20);
+   if (priv->phy_reset)
+   reset_control_deassert(priv->phy_reset);
+   usleep_range(10, 20);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
+   msleep(30);
+   }
+}
+
+static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
 {
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->phy_reset)
+   reset_control_assert(priv->phy_reset);
+}
+
+static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
+{
+   struct rk_priv_data *bsp_priv = plat->bsp_priv;
struct device *dev = _priv->pdev->dev;
+   int ret;
 
bsp_priv->clk_enabled = false;
 
@@ -803,6 +854,16 @@ static int gmac_clk_init(struct rk_priv_data *bsp_priv)
clk_set_rate(bsp_priv->clk_mac, 5000);
}
 
+   if (plat->phy_node && bsp_priv->integrated_phy) {
+   bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
+   if (IS_ERR(bsp_priv->clk_phy)) {
+   ret = PTR_ERR(bsp_priv->clk_phy);
+   dev_err(dev, "Cannot get PHY clock: %d\n", ret);
+   return -EINVAL;
+   }
+   clk_set_rate(bsp_priv->clk_phy, 5000);
+   }
+
return 0;
 }
 
@@ -826,6 +887,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, 
bool enable)
bsp_priv->clk_mac_refout);
}
 
+   if (!IS_ERR(bsp_priv->clk_phy))
+   clk_prepare_enable(bsp_priv->clk_phy);
+
if (!IS_ERR(bs

[PATCH v5 05/11] Documentation: net: phy: Add phy-is-integrated binding

2017-08-10 Thread David Wu
Add the documentation for integrated PHY. A boolean property indicates
the PHY is integrated into the same physical package as the Ethernet
MAC. If needed, muxers should be configured to ensure the integrated
PHY is used. The absence of this property indicates the muxers should
be configured so that the external PHY is used.

Signed-off-by: David Wu <david...@rock-chips.com>
---
change in v5:
 - Use phy-is-integrated boolean property.

 Documentation/devicetree/bindings/net/phy.txt | 5 +
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/phy.txt 
b/Documentation/devicetree/bindings/net/phy.txt
index b558576..d3c24d5 100644
--- a/Documentation/devicetree/bindings/net/phy.txt
+++ b/Documentation/devicetree/bindings/net/phy.txt
@@ -52,6 +52,11 @@ Optional Properties:
   Mark the corresponding energy efficient ethernet mode as broken and
   request the ethernet to stop advertising it.
 
+- phy-is-integrated: If set, indicates that the PHY is integrated into the same
+  physical package as the Ethernet MAC. If needed, muxers should be configured
+  to ensure the integrated PHY is used. The absence of this property indicates
+  the muxers should be configured so that the external PHY is used.
+
 Example:
 
 ethernet-phy@0 {
-- 
1.9.1




[PATCH v5 01/11] net: phy: Add rockchip PHY driver support

2017-08-10 Thread David Wu
Support integrated ethernet PHY currently.

Signed-off-by: David Wu <david...@rock-chips.com>
---
changes in v4:
 - Remove SUPPORTED_[Asym_]Pause.
 - Some minor fix like defines.

changes in v5:
 - Rename internal to integrated.
 - Remove PHY_IS_INTERNAL flag.

 drivers/net/phy/Kconfig|   5 +
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/rockchip.c | 233 +
 3 files changed, 239 insertions(+)
 create mode 100644 drivers/net/phy/rockchip.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 2dda720..255ac3a 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -334,6 +334,11 @@ config REALTEK_PHY
---help---
  Supports the Realtek 821x PHY.
 
+config ROCKCHIP_PHY
+tristate "Driver for Rockchip Ethernet PHYs"
+---help---
+  Currently supports the integrated Ethernet PHY.
+
 config SMSC_PHY
tristate "SMSC PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 8e9b9f3..350520e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_MICROSEMI_PHY)   += mscc.o
 obj-$(CONFIG_NATIONAL_PHY) += national.o
 obj-$(CONFIG_QSEMI_PHY)+= qsemi.o
 obj-$(CONFIG_REALTEK_PHY)  += realtek.o
+obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
 obj-$(CONFIG_SMSC_PHY) += smsc.o
 obj-$(CONFIG_STE10XP)  += ste10Xp.o
 obj-$(CONFIG_TERANETICS_PHY)   += teranetics.o
diff --git a/drivers/net/phy/rockchip.c b/drivers/net/phy/rockchip.c
new file mode 100644
index 000..c092af1
--- /dev/null
+++ b/drivers/net/phy/rockchip.c
@@ -0,0 +1,233 @@
+/**
+ * drivers/net/phy/rockchip.c
+ *
+ * Driver for ROCKCHIP Ethernet PHYs
+ *
+ * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * David Wu <david...@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define INTERNAL_EPHY_ID   0x1234d400
+
+#define MII_INTERNAL_CTRL_STATUS   17
+#define SMI_ADDR_TSTCNTL   20
+#define SMI_ADDR_TSTREAD1  21
+#define SMI_ADDR_TSTREAD2  22
+#define SMI_ADDR_TSTWRITE  23
+#define MII_SPECIAL_CONTROL_STATUS 31
+
+#define MII_AUTO_MDIX_EN   BIT(7)
+#define MII_MDIX_ENBIT(6)
+
+#define MII_SPEED_10   BIT(2)
+#define MII_SPEED_100  BIT(3)
+
+#define TSTCNTL_RD (BIT(15) | BIT(10))
+#define TSTCNTL_WR (BIT(14) | BIT(10))
+
+#define TSTMODE_ENABLE 0x400
+#define TSTMODE_DISABLE0x0
+
+#define WR_ADDR_A7CFG  0x18
+
+static int rockchip_init_tstmode(struct phy_device *phydev)
+{
+   int ret;
+
+   /* Enable access to Analog and DSP register banks */
+   ret = phy_write(phydev, SMI_ADDR_TSTCNTL, TSTMODE_ENABLE);
+   if (ret)
+   return ret;
+
+   ret = phy_write(phydev, SMI_ADDR_TSTCNTL, TSTMODE_DISABLE);
+   if (ret)
+   return ret;
+
+   return phy_write(phydev, SMI_ADDR_TSTCNTL, TSTMODE_ENABLE);
+}
+
+static int rockchip_close_tstmode(struct phy_device *phydev)
+{
+   /* Back to basic register bank */
+   return phy_write(phydev, SMI_ADDR_TSTCNTL, TSTMODE_DISABLE);
+}
+
+static int rockchip_integrated_phy_analog_init(struct phy_device *phydev)
+{
+   int ret;
+
+   ret = rockchip_init_tstmode(phydev);
+   if (ret)
+   return ret;
+
+   /*
+* Adjust tx amplitude to make sginal better,
+* the default value is 0x8.
+*/
+   ret = phy_write(phydev, SMI_ADDR_TSTWRITE, 0xB);
+   if (ret)
+   return ret;
+   ret = phy_write(phydev, SMI_ADDR_TSTCNTL, TSTCNTL_WR | WR_ADDR_A7CFG);
+   if (ret)
+   return ret;
+
+   return rockchip_close_tstmode(phydev);
+}
+
+static int rockchip_integrated_phy_config_init(struct phy_device *phydev)
+{
+   int val, ret;
+
+   /*
+* The auto MIDX has linked problem on some board,
+* workround to disable auto MDIX.
+*/
+   val = phy_read(phydev, MII_INTERNAL_CTRL_STATUS);
+   if (val < 0)
+   return val;
+   val &= ~MII_AUTO_MDIX_EN;
+   ret = phy_write(phydev, MII_INTERNAL_CTRL_STATUS, val);
+   if (ret)
+   return ret;
+
+   return rockchip_integrated_phy_analog_init(phydev);
+}
+
+static void rockchip_link_change_notify(struct phy_device *phydev)
+{
+   int

[PATCH v5 02/11] multi_v7_defconfig: Make rockchip PHY built-in

2017-08-10 Thread David Wu
Enable the rockchip PHY driver for multi_v7_defconfig builds.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index 4d19c1b..94d7e71 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -270,6 +270,7 @@ CONFIG_ICPLUS_PHY=y
 CONFIG_REALTEK_PHY=y
 CONFIG_MICREL_PHY=y
 CONFIG_FIXED_PHY=y
+CONFIG_ROCKCHIP_PHY=y
 CONFIG_USB_PEGASUS=y
 CONFIG_USB_RTL8152=m
 CONFIG_USB_USBNET=y
-- 
1.9.1




[PATCH v5 04/11] net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()

2017-08-10 Thread David Wu
This is wrong setting for rk3328_set_to_rmii(), so remove it.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index f0df519..a8e8fd5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -365,9 +365,6 @@ static void rk3328_set_to_rmii(struct rk_priv_data 
*bsp_priv)
regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
-
-   /* set MAC to RMII mode */
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, GRF_BIT(11));
 }
 
 static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
-- 
1.9.1




[PATCH v5 03/11] arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY

2017-08-10 Thread David Wu
Make the rockchip PHY driver built into the kernel.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6c7d147..925bd478 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -203,6 +203,7 @@ CONFIG_MARVELL_PHY=m
 CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
 CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_PHY=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
-- 
1.9.1




[PATCH v5 00/11] Add the integrated PHY support

2017-08-10 Thread David Wu
The rk3228 and rk3328 support integrated PHY inside, let's enable
it to work. And the integrated PHY need to do some special setting,
so register the rockchip integrated PHY driver.

David Wu (11):
  net: phy: Add rockchip PHY driver support
  multi_v7_defconfig: Make rockchip PHY built-in
  arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY
  net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()
  Documentation: net: phy: Add phy-is-integrated binding
  net: stmmac: dwmac-rk: Add integrated PHY support
  net: stmmac: dwmac-rk: Add integrated PHY support for rk3228
  net: stmmac: dwmac-rk: Add integrated PHY supprot for rk3328
  ARM: dts: rk3228-evb: Enable the integrated PHY for gmac
  ARM64: dts: rockchip: Add gmac2phy node support for rk3328
  ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

 Documentation/devicetree/bindings/net/phy.txt  |   5 +
 arch/arm/boot/dts/rk3228-evb.dts   |  34 
 arch/arm/configs/multi_v7_defconfig|   1 +
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts|  17 ++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   |  39 +
 arch/arm64/configs/defconfig   |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 140 +--
 drivers/net/phy/Kconfig|   5 +
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/rockchip.c | 233 +
 10 files changed, 466 insertions(+), 10 deletions(-)
 create mode 100644 drivers/net/phy/rockchip.c

-- 
1.9.1




[PATCH v4 12/12] ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

2017-08-09 Thread David Wu
Enable the gmac2phy, make the gmac2phy work on
the rk3328-evb board.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 17 +
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index cf27239..b9f36da 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -50,6 +50,23 @@
chosen {
stdout-path = "serial2:150n8";
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   regulator-name = "vcc_phy";
+   regulator-always-on;
+   regulator-boot-on;
+   };
+};
+
+ {
+   phy-supply = <_phy>;
+   clock_in_out = "output";
+   assigned-clocks = < SCLK_MAC2PHY_SRC>;
+   assigned-clock-rate = <5000>;
+   assigned-clocks = < SCLK_MAC2PHY>;
+   assigned-clock-parents = < SCLK_MAC2PHY_SRC>;
+   status = "okay";
 };
 
  {
-- 
1.9.1




[PATCH v4 11/12] ARM64: dts: rockchip: Add gmac2phy node support for rk3328

2017-08-09 Thread David Wu
The gmac2phy controller of rk3328 is connected to internal phy
directly inside, add the node for the internal phy support.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 37 
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0be96ce..903aaae 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -63,6 +63,8 @@
i2c1 = 
i2c2 = 
i2c3 = 
+   ethernet0 = 
+   ethernet1 = 
};
 
cpus {
@@ -424,6 +426,41 @@
status = "disabled";
};
 
+   gmac2phy: ethernet@ff55 {
+   compatible = "rockchip,rk3328-gmac";
+   reg = <0x0 0xff55 0x0 0x1>;
+   rockchip,grf = <>;
+   interrupts = ;
+   interrupt-names = "macirq";
+   clocks = < SCLK_MAC2PHY_SRC>, < SCLK_MAC2PHY_RXTX>,
+< SCLK_MAC2PHY_RXTX>, < SCLK_MAC2PHY_REF>,
+< ACLK_MAC2PHY>, < PCLK_MAC2PHY>,
+< SCLK_MAC2PHY_OUT>;
+   clock-names = "stmmaceth", "mac_clk_rx",
+ "mac_clk_tx", "clk_mac_ref",
+ "aclk_mac", "pclk_mac",
+ "clk_macphy";
+   resets = < SRST_GMAC2PHY_A>, < SRST_MACPHY>;
+   reset-names = "stmmaceth", "mac-phy";
+   phy-mode = "rmii";
+   pinctrl-names = "default";
+   pinctrl-0 = <_rxm1 _linkm1>;
+   phy-handle = <>;
+   status = "disabled";
+
+   mdio {
+   compatible = "snps,dwmac-mdio";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   phy: phy@0 {
+   compatible = "ethernet-phy-id1234.d400", 
"ethernet-phy-802.3-c22";
+   reg = <0>;
+   phy-is-internal;
+   };
+   };
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
1.9.1




[PATCH v4 10/12] ARM: dts: rk3228-evb: Enable the internal phy for gmac

2017-08-09 Thread David Wu
This patch enables the internal phy for rk3228 evb board
by default.
To use the external 1000M phy on evb board, need to make
some switch of evb board to be on.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/boot/dts/rk3228-evb.dts | 32 
 1 file changed, 32 insertions(+)

diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
index 5883433..3784f26 100644
--- a/arch/arm/boot/dts/rk3228-evb.dts
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -50,6 +50,16 @@
device_type = "memory";
reg = <0x6000 0x4000>;
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   enable-active-high;
+   regulator-name = "vcc_phy";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-always-on;
+   regulator-boot-on;
+   };
 };
 
  {
@@ -60,6 +70,28 @@
status = "okay";
 };
 
+ {
+   assigned-clocks = < SCLK_MAC_SRC>;
+   assigned-clock-rates = <5000>;
+   clock_in_out = "output";
+   phy-supply = <_phy>;
+   phy-mode = "rmii";
+   phy-handle = <>;
+   status = "okay";
+
+   mdio {
+   compatible = "snps,dwmac-mdio";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   phy@0 {
+   compatible = "ethernet-phy-id1234.d400", 
"ethernet-phy-802.3-c22";
+   reg = <0>;
+   phy-is-internal;
+   };
+   };
+};
+
  {
status = "okay";
 
-- 
1.9.1




[PATCH v4 09/12] ARM: dts: rk322x: Add support internal phy for gmac

2017-08-09 Thread David Wu
This patch adds internal mac phy clock and internal mac phy reset
for rk gmac using.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/boot/dts/rk322x.dtsi | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index f3e4ffd..3778f7d 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -611,13 +611,13 @@
clocks = < SCLK_MAC>, < SCLK_MAC_RX>,
< SCLK_MAC_TX>, < SCLK_MAC_REF>,
< SCLK_MAC_REFOUT>, < ACLK_GMAC>,
-   < PCLK_GMAC>;
+   < PCLK_GMAC>, < SCLK_MAC_PHY>;
clock-names = "stmmaceth", "mac_clk_rx",
"mac_clk_tx", "clk_mac_ref",
"clk_mac_refout", "aclk_mac",
-   "pclk_mac";
-   resets = < SRST_GMAC>;
-   reset-names = "stmmaceth";
+   "pclk_mac", "clk_macphy";
+   resets = < SRST_GMAC>, < SRST_MACPHY>;
+   reset-names = "stmmaceth", "mac-phy";
rockchip,grf = <>;
status = "disabled";
};
-- 
1.9.1




[PATCH v4 08/12] net: stmmac: dwmac-rk: Add internal phy supprot for rk3328

2017-08-09 Thread David Wu
There are two mac controllers in the rk3328, the one connects
to external phy, and the other one connects to internal phy.
Like the mac of external phy, the internal phy's mac also needs to
configure the related mac registers at GRF.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 5372631..be60fd7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -323,6 +323,8 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 
 #define RK3328_GRF_MAC_CON00x0900
 #define RK3328_GRF_MAC_CON10x0904
+#define RK3328_GRF_MAC_CON20x0908
+#define RK3328_GRF_MACPHY_CON1 0xb04
 
 /* RK3328_GRF_MAC_CON0 */
 #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
@@ -349,6 +351,9 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 #define RK3328_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3328_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(0)
 
+/* RK3328_GRF_MACPHY_CON1 */
+#define RK3328_MACPHY_RMII_MODEGRF_BIT(9)
+
 static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -373,13 +378,17 @@ static void rk3328_set_to_rgmii(struct rk_priv_data 
*bsp_priv,
 static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
 }
@@ -409,29 +418,40 @@ static void rk3328_set_rgmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
+   reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
if (speed == 10)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_2_5M |
 RK3328_GMAC_SPEED_10M);
else if (speed == 100)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_25M |
 RK3328_GMAC_SPEED_100M);
else
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3328_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
+RK3328_MACPHY_RMII_MODE);
+}
+
 static const struct rk_gmac_ops rk3328_ops = {
.set_to_rgmii = rk3328_set_to_rgmii,
.set_to_rmii = rk3328_set_to_rmii,
.set_rgmii_speed = rk3328_set_rgmii_speed,
.set_rmii_speed = rk3328_set_rmii_speed,
+   .internal_phy_powerup =  rk3328_internal_phy_powerup,
 };
 
 #define RK3366_GRF_SOC_CON60x0418
-- 
1.9.1




[PATCH v4 07/12] net: stmmac: dwmac-rk: Add internal phy support for rk3228

2017-08-09 Thread David Wu
There is only one mac controller in rk3228, which could connect to
external phy or internal phy, use the grf_com_mux bit15 to route
external/internal phy.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index a856362..5372631 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -86,6 +86,8 @@ struct rk_priv_data {
 #define RK3228_GRF_MAC_CON00x0900
 #define RK3228_GRF_MAC_CON10x0904
 
+#define RK3228_GRF_CON_MUX 0x50
+
 /* RK3228_GRF_MAC_CON0 */
 #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
 #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
@@ -111,6 +113,9 @@ struct rk_priv_data {
 #define RK3228_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3228_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(1)
 
+/* RK3228_GRF_COM_MUX */
+#define RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY   GRF_BIT(15)
+
 static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -191,11 +196,18 @@ static void rk3228_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3228_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3228_GRF_CON_MUX,
+RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY);
+}
+
 static const struct rk_gmac_ops rk3228_ops = {
.set_to_rgmii = rk3228_set_to_rgmii,
.set_to_rmii = rk3228_set_to_rmii,
.set_rgmii_speed = rk3228_set_rgmii_speed,
.set_rmii_speed = rk3228_set_rmii_speed,
+   .internal_phy_powerup =  rk3228_internal_phy_powerup,
 };
 
 #define RK3288_GRF_SOC_CON10x0248
-- 
1.9.1




[PATCH v4 06/12] net: stmmac: dwmac-rk: Add internal phy support

2017-08-09 Thread David Wu
To make internal phy work, need to configure the phy_clock,
phy cru_reset and related registers.

Signed-off-by: David Wu <david...@rock-chips.com>
---
change in v4:
 - PHY is internal or not base on the phy-is-internal property via phy node.

 .../devicetree/bindings/net/rockchip-dwmac.txt |  4 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 88 ++
 2 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt 
b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
index 8f42755..4f51305 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -25,7 +25,8 @@ Required properties:
  - clock-names: One name for each entry in the clocks property.
  - phy-mode: See ethernet.txt file in the same directory.
  - pinctrl-names: Names corresponding to the numbered pinctrl states.
- - pinctrl-0: pin-control mode. can be <_pins> or <_pins>.
+ - pinctrl-0: pin-control mode. can be <_pins>, <_pins> or led pins
+   for internal phy mode.
  - clock_in_out: For RGMII, it must be "input", means main clock(125MHz)
is not sourced from SoC's PLL, but input from PHY; For RMII, "input" means
PHY provides the reference clock(50MHz), "output" means GMAC provides the
@@ -40,6 +41,7 @@ Optional properties:
  - tx_delay: Delay value for TXD timing. Range value is 0~0x7F, 0x30 as 
default.
  - rx_delay: Delay value for RXD timing. Range value is 0~0x7F, 0x10 as 
default.
  - phy-supply: phandle to a regulator if the PHY needs one
+ - clocks: < MAC_PHY>: Clock selector for internal macphy
 
 Example:
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index a8e8fd5..a856362 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -41,6 +41,7 @@ struct rk_gmac_ops {
void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
+   void (*internal_phy_powerup)(struct rk_priv_data *bsp_priv);
 };
 
 struct rk_priv_data {
@@ -52,6 +53,7 @@ struct rk_priv_data {
 
bool clk_enabled;
bool clock_input;
+   bool internal_phy;
 
struct clk *clk_mac;
struct clk *gmac_clkin;
@@ -61,6 +63,9 @@ struct rk_priv_data {
struct clk *clk_mac_refout;
struct clk *aclk_mac;
struct clk *pclk_mac;
+   struct clk *clk_macphy;
+
+   struct reset_control *macphy_reset;
 
int tx_delay;
int rx_delay;
@@ -750,6 +755,50 @@ static void rk3399_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
.set_rmii_speed = rk3399_set_rmii_speed,
 };
 
+#define RK_GRF_MACPHY_CON0 0xb00
+#define RK_GRF_MACPHY_CON1 0xb04
+#define RK_GRF_MACPHY_CON2 0xb08
+#define RK_GRF_MACPHY_CON3 0xb0c
+
+#define RK_MACPHY_ENABLE   GRF_BIT(0)
+#define RK_MACPHY_DISABLE  GRF_CLR_BIT(0)
+#define RK_MACPHY_CFG_CLK_50M  GRF_BIT(14)
+#define RK_GMAC2PHY_RMII_MODE  (GRF_BIT(6) | GRF_CLR_BIT(7))
+#define RK_GRF_CON2_MACPHY_ID  HIWORD_UPDATE(0x1234, 0x, 0)
+#define RK_GRF_CON3_MACPHY_ID  HIWORD_UPDATE(0x35, 0x3f, 0)
+
+static void rk_gmac_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   if (priv->ops->internal_phy_powerup)
+   priv->ops->internal_phy_powerup(priv);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
+
+   if (priv->macphy_reset) {
+   /* macphy needs to be disabled before trying to reset it */
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->macphy_reset)
+   reset_control_assert(priv->macphy_reset);
+   usleep_range(10, 20);
+   if (priv->macphy_reset)
+   reset_control_deassert(priv->macphy_reset);
+   usleep_range(10, 20);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
+   msleep(30);
+   }
+}
+
+static void rk_gmac_internal_phy_powerdown(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->macphy_reset)
+   reset_control_assert(priv->macphy_reset);
+}
+
 static int gmac_clk_init(struct rk_priv_data *bsp_priv)
 {
struct device *dev = _priv->pdev->dev;
@@ -8

[PATCH v4 05/12] Documentation: net: phy: Add phy-is-internal binding

2017-08-09 Thread David Wu
Add the documentation for internal phy. A boolean property
indicates that a internal phy will be used.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 Documentation/devicetree/bindings/net/phy.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/phy.txt 
b/Documentation/devicetree/bindings/net/phy.txt
index b558576..942c892 100644
--- a/Documentation/devicetree/bindings/net/phy.txt
+++ b/Documentation/devicetree/bindings/net/phy.txt
@@ -52,6 +52,9 @@ Optional Properties:
   Mark the corresponding energy efficient ethernet mode as broken and
   request the ethernet to stop advertising it.
 
+- phy-is-internal: If set, indicates that phy will connect to the MAC as a
+  internal phy.
+
 Example:
 
 ethernet-phy@0 {
-- 
1.9.1




[PATCH v4 01/12] net: phy: Add rockchip phy driver support

2017-08-09 Thread David Wu
Support internal ethernet phy currently.

Signed-off-by: David Wu <david...@rock-chips.com>
---
changes in v4:
 - Remove SUPPORTED_[Asym_]Pause flag
 - Some minor fix like defines

 drivers/net/phy/Kconfig|   5 +
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/rockchip.c | 233 +
 3 files changed, 239 insertions(+)
 create mode 100644 drivers/net/phy/rockchip.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 2dda720..22cc702 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -334,6 +334,11 @@ config REALTEK_PHY
---help---
  Supports the Realtek 821x PHY.
 
+config ROCKCHIP_PHY
+tristate "Driver for Rockchip Ethernet PHYs"
+---help---
+  Currently supports the internal Ethernet PHY.
+
 config SMSC_PHY
tristate "SMSC PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 8e9b9f3..350520e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_MICROSEMI_PHY)   += mscc.o
 obj-$(CONFIG_NATIONAL_PHY) += national.o
 obj-$(CONFIG_QSEMI_PHY)+= qsemi.o
 obj-$(CONFIG_REALTEK_PHY)  += realtek.o
+obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
 obj-$(CONFIG_SMSC_PHY) += smsc.o
 obj-$(CONFIG_STE10XP)  += ste10Xp.o
 obj-$(CONFIG_TERANETICS_PHY)   += teranetics.o
diff --git a/drivers/net/phy/rockchip.c b/drivers/net/phy/rockchip.c
new file mode 100644
index 000..36c8626
--- /dev/null
+++ b/drivers/net/phy/rockchip.c
@@ -0,0 +1,233 @@
+/**
+ * drivers/net/phy/rockchip.c
+ *
+ * Driver for ROCKCHIP Ethernet PHYs
+ *
+ * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * David Wu <david...@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define INTERNAL_EPHY_ID   0x1234d400
+
+#define MII_INTERNAL_CTRL_STATUS   17
+#define SMI_ADDR_TSTCNTL   20
+#define SMI_ADDR_TSTREAD1  21
+#define SMI_ADDR_TSTREAD2  22
+#define SMI_ADDR_TSTWRITE  23
+#define MII_SPECIAL_CONTROL_STATUS 31
+
+#define MII_AUTO_MDIX_EN   BIT(7)
+#define MII_MDIX_ENBIT(6)
+
+#define MII_SPEED_10   BIT(2)
+#define MII_SPEED_100  BIT(3)
+
+#define TSTCNTL_RD (BIT(15) | BIT(10))
+#define TSTCNTL_WR (BIT(14) | BIT(10))
+
+#define TSTMODE_ENABLE 0x400
+#define TSTMODE_DISABLE0x0
+
+#define WR_ADDR_A7CFG  0x18
+
+static int rockchip_init_tstmode(struct phy_device *phydev)
+{
+   int ret;
+
+   /* Enable access to Analog and DSP register banks */
+   ret = phy_write(phydev, SMI_ADDR_TSTCNTL, TSTMODE_ENABLE);
+   if (ret)
+   return ret;
+
+   ret = phy_write(phydev, SMI_ADDR_TSTCNTL, TSTMODE_DISABLE);
+   if (ret)
+   return ret;
+
+   return phy_write(phydev, SMI_ADDR_TSTCNTL, TSTMODE_ENABLE);
+}
+
+static int rockchip_close_tstmode(struct phy_device *phydev)
+{
+   /* Back to basic register bank */
+   return phy_write(phydev, SMI_ADDR_TSTCNTL, TSTMODE_DISABLE);
+}
+
+static int rockchip_internal_phy_analog_init(struct phy_device *phydev)
+{
+   int ret;
+
+   ret = rockchip_init_tstmode(phydev);
+   if (ret)
+   return ret;
+
+   /*
+* Adjust tx amplitude to make sginal better,
+* the default value is 0x8.
+*/
+   ret = phy_write(phydev, SMI_ADDR_TSTWRITE, 0xB);
+   if (ret)
+   return ret;
+   ret = phy_write(phydev, SMI_ADDR_TSTCNTL, TSTCNTL_WR | WR_ADDR_A7CFG);
+   if (ret)
+   return ret;
+
+   return rockchip_close_tstmode(phydev);
+}
+
+static int rockchip_internal_phy_config_init(struct phy_device *phydev)
+{
+   int val, ret;
+
+   /*
+* The auto MIDX has linked problem on some board,
+* workround to disable auto MDIX.
+*/
+   val = phy_read(phydev, MII_INTERNAL_CTRL_STATUS);
+   if (val < 0)
+   return val;
+   val &= ~MII_AUTO_MDIX_EN;
+   ret = phy_write(phydev, MII_INTERNAL_CTRL_STATUS, val);
+   if (ret)
+   return ret;
+
+   return rockchip_internal_phy_analog_init(phydev);
+}
+
+static void rockchip_link_change_notify(struct phy_device *phydev)
+{
+   int speed = SPEED_10;
+
+   if (phydev->autoneg == AUTONEG_ENABLE) {

[PATCH v4 02/12] multi_v7_defconfig: Make rockchip phy built-in

2017-08-09 Thread David Wu
Enable the rockchip phy for multi_v7_defconfig builds.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index 4d19c1b..94d7e71 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -270,6 +270,7 @@ CONFIG_ICPLUS_PHY=y
 CONFIG_REALTEK_PHY=y
 CONFIG_MICREL_PHY=y
 CONFIG_FIXED_PHY=y
+CONFIG_ROCKCHIP_PHY=y
 CONFIG_USB_PEGASUS=y
 CONFIG_USB_RTL8152=m
 CONFIG_USB_USBNET=y
-- 
1.9.1




[PATCH v4 03/12] arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY

2017-08-09 Thread David Wu
Make the rockchip phy driver built into the kernel.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6c7d147..925bd478 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -203,6 +203,7 @@ CONFIG_MARVELL_PHY=m
 CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
 CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_PHY=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
-- 
1.9.1




[PATCH v4 00/12] Add the internal phy support

2017-08-09 Thread David Wu
The rk3228 and rk3328 support internal phy inside, let's enable
it to work. And the internal phy need to do some special setting, so
register the rockchip internal phy driver.

David Wu (12):
  net: phy: Add rockchip phy driver support
  multi_v7_defconfig: Make rockchip phy built-in
  arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY
  net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()
  Documentation: net: phy: Add phy-is-internal binding
  net: stmmac: dwmac-rk: Add internal phy support
  net: stmmac: dwmac-rk: Add internal phy support for rk3228
  net: stmmac: dwmac-rk: Add internal phy supprot for rk3328
  ARM: dts: rk322x: Add support internal phy for gmac
  ARM: dts: rk3228-evb: Enable the internal phy for gmac
  ARM64: dts: rockchip: Add gmac2phy node support for rk3328
  ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

 Documentation/devicetree/bindings/net/phy.txt  |   3 +
 .../devicetree/bindings/net/rockchip-dwmac.txt |   4 +-
 arch/arm/boot/dts/rk3228-evb.dts   |  32 +++
 arch/arm/boot/dts/rk322x.dtsi  |   8 +-
 arch/arm/configs/multi_v7_defconfig|   1 +
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts|  17 ++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   |  37 
 arch/arm64/configs/defconfig   |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 129 +++-
 drivers/net/phy/Kconfig|   5 +
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/rockchip.c | 233 +
 12 files changed, 460 insertions(+), 11 deletions(-)
 create mode 100644 drivers/net/phy/rockchip.c

-- 
1.9.1




[PATCH v4 04/12] net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()

2017-08-09 Thread David Wu
This is wrong setting for rk3328_set_to_rmii(), so remove it.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index f0df519..a8e8fd5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -365,9 +365,6 @@ static void rk3328_set_to_rmii(struct rk_priv_data 
*bsp_priv)
regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
-
-   /* set MAC to RMII mode */
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, GRF_BIT(11));
 }
 
 static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
-- 
1.9.1




[PATCH v3 11/11] ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

2017-08-02 Thread David Wu
Enable the gmac2phy, make the gmac2phy work on
the rk3328-evb board.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 17 +
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index cf27239..b9f36da 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -50,6 +50,23 @@
chosen {
stdout-path = "serial2:150n8";
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   regulator-name = "vcc_phy";
+   regulator-always-on;
+   regulator-boot-on;
+   };
+};
+
+ {
+   phy-supply = <_phy>;
+   clock_in_out = "output";
+   assigned-clocks = < SCLK_MAC2PHY_SRC>;
+   assigned-clock-rate = <5000>;
+   assigned-clocks = < SCLK_MAC2PHY>;
+   assigned-clock-parents = < SCLK_MAC2PHY_SRC>;
+   status = "okay";
 };
 
  {
-- 
1.9.1




[PATCH v3 10/11] ARM64: dts: rockchip: Add gmac2phy node support for rk3328

2017-08-02 Thread David Wu
The gmac2phy controller of rk3328 is connected to internal phy
directly inside, add the node for the internal phy support.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0be96ce..51c8c66 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -63,6 +63,8 @@
i2c1 = 
i2c2 = 
i2c3 = 
+   ethernet0 = 
+   ethernet1 = 
};
 
cpus {
@@ -424,6 +426,29 @@
status = "disabled";
};
 
+   gmac2phy: eth@ff55 {
+   compatible = "rockchip,rk3328-gmac";
+   reg = <0x0 0xff55 0x0 0x1>;
+   rockchip,grf = <>;
+   interrupts = ;
+   interrupt-names = "macirq";
+   clocks = < SCLK_MAC2PHY_SRC>, < SCLK_MAC2PHY_RXTX>,
+< SCLK_MAC2PHY_RXTX>, < SCLK_MAC2PHY_REF>,
+< ACLK_MAC2PHY>, < PCLK_MAC2PHY>,
+< SCLK_MAC2PHY_OUT>;
+   clock-names = "stmmaceth", "mac_clk_rx",
+ "mac_clk_tx", "clk_mac_ref",
+ "aclk_mac", "pclk_mac",
+ "clk_macphy";
+   resets = < SRST_GMAC2PHY_A>, < SRST_MACPHY>;
+   reset-names = "stmmaceth", "mac-phy";
+   phy-mode = "rmii";
+   phy-is-internal;
+   pinctrl-names = "default";
+   pinctrl-0 = <_rxm1 _linkm1>;
+   status = "disabled";
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
1.9.1




[PATCH v3 09/11] ARM: dts: rk3228-evb: Enable the internal phy for gmac

2017-08-02 Thread David Wu
This patch enables the internal phy for rk3228 evb board
by default.
To use the external 1000M phy on evb board, need to make
some switch of evb board to be on.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/boot/dts/rk3228-evb.dts | 20 
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
index 5883433..48b3adb 100644
--- a/arch/arm/boot/dts/rk3228-evb.dts
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -50,6 +50,16 @@
device_type = "memory";
reg = <0x6000 0x4000>;
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   enable-active-high;
+   regulator-name = "vcc_phy";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-always-on;
+   regulator-boot-on;
+   };
 };
 
  {
@@ -60,6 +70,16 @@
status = "okay";
 };
 
+ {
+   assigned-clocks = < SCLK_MAC_SRC>;
+   assigned-clock-rates = <5000>;
+   clock_in_out = "output";
+   phy-supply = <_phy>;
+   phy-mode = "rmii";
+   phy-is-internal;
+   status = "okay";
+};
+
  {
status = "okay";
 
-- 
1.9.1




[PATCH v3 08/11] ARM: dts: rk322x: Add support internal phy for gmac

2017-08-02 Thread David Wu
This patch adds internal mac phy clock and internal mac phy reset
for rk gmac using.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/boot/dts/rk322x.dtsi | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index f3e4ffd..3778f7d 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -611,13 +611,13 @@
clocks = < SCLK_MAC>, < SCLK_MAC_RX>,
< SCLK_MAC_TX>, < SCLK_MAC_REF>,
< SCLK_MAC_REFOUT>, < ACLK_GMAC>,
-   < PCLK_GMAC>;
+   < PCLK_GMAC>, < SCLK_MAC_PHY>;
clock-names = "stmmaceth", "mac_clk_rx",
"mac_clk_tx", "clk_mac_ref",
"clk_mac_refout", "aclk_mac",
-   "pclk_mac";
-   resets = < SRST_GMAC>;
-   reset-names = "stmmaceth";
+   "pclk_mac", "clk_macphy";
+   resets = < SRST_GMAC>, < SRST_MACPHY>;
+   reset-names = "stmmaceth", "mac-phy";
rockchip,grf = <>;
status = "disabled";
};
-- 
1.9.1




[PATCH v3 07/11] net: stmmac: dwmac-rk: Add internal phy supprot for rk3328

2017-08-02 Thread David Wu
There are two mac controllers in the rk3328, the one connects
to external phy, and the other one connects to internal phy.
Like the mac of external phy, the internal phy's mac also needs to
configure the related mac registers at GRF.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 74cf0bb..83471f3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -323,6 +323,8 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 
 #define RK3328_GRF_MAC_CON00x0900
 #define RK3328_GRF_MAC_CON10x0904
+#define RK3328_GRF_MAC_CON20x0908
+#define RK3328_GRF_MACPHY_CON1 0xb04
 
 /* RK3328_GRF_MAC_CON0 */
 #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
@@ -349,6 +351,9 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 #define RK3328_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3328_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(0)
 
+/* RK3328_GRF_MACPHY_CON1 */
+#define RK3328_MACPHY_RMII_MODEGRF_BIT(9)
+
 static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -373,13 +378,17 @@ static void rk3328_set_to_rgmii(struct rk_priv_data 
*bsp_priv,
 static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
 }
@@ -409,29 +418,40 @@ static void rk3328_set_rgmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
+   reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
if (speed == 10)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_2_5M |
 RK3328_GMAC_SPEED_10M);
else if (speed == 100)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_25M |
 RK3328_GMAC_SPEED_100M);
else
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3328_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
+RK3328_MACPHY_RMII_MODE);
+}
+
 static const struct rk_gmac_ops rk3328_ops = {
.set_to_rgmii = rk3328_set_to_rgmii,
.set_to_rmii = rk3328_set_to_rmii,
.set_rgmii_speed = rk3328_set_rgmii_speed,
.set_rmii_speed = rk3328_set_rmii_speed,
+   .internal_phy_powerup =  rk3328_internal_phy_powerup,
 };
 
 #define RK3366_GRF_SOC_CON60x0418
-- 
1.9.1




[PATCH v3 06/11] net: stmmac: dwmac-rk: Add internal phy support for rk3228

2017-08-02 Thread David Wu
There is only one mac controller in rk3228, which could connect to
external phy or internal phy, use the grf_com_mux bit15 to route
external/internal phy.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 7b80ab9..74cf0bb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -86,6 +86,8 @@ struct rk_priv_data {
 #define RK3228_GRF_MAC_CON00x0900
 #define RK3228_GRF_MAC_CON10x0904
 
+#define RK3228_GRF_CON_MUX 0x50
+
 /* RK3228_GRF_MAC_CON0 */
 #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
 #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
@@ -111,6 +113,9 @@ struct rk_priv_data {
 #define RK3228_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3228_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(1)
 
+/* RK3228_GRF_COM_MUX */
+#define RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY   GRF_BIT(15)
+
 static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -191,11 +196,18 @@ static void rk3228_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3228_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3228_GRF_CON_MUX,
+RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY);
+}
+
 static const struct rk_gmac_ops rk3228_ops = {
.set_to_rgmii = rk3228_set_to_rgmii,
.set_to_rmii = rk3228_set_to_rmii,
.set_rgmii_speed = rk3228_set_rgmii_speed,
.set_rmii_speed = rk3228_set_rmii_speed,
+   .internal_phy_powerup =  rk3228_internal_phy_powerup,
 };
 
 #define RK3288_GRF_SOC_CON10x0248
-- 
1.9.1




[PATCH v3 05/11] net: stmmac: dwmac-rk: Add internal phy support

2017-08-02 Thread David Wu
To make internal phy work, need to configure the phy_clock,
phy cru_reset and related registers.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 .../devicetree/bindings/net/rockchip-dwmac.txt |  6 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 81 ++
 2 files changed, 86 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt 
b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
index 8f42755..ec39b31 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -25,7 +25,8 @@ Required properties:
  - clock-names: One name for each entry in the clocks property.
  - phy-mode: See ethernet.txt file in the same directory.
  - pinctrl-names: Names corresponding to the numbered pinctrl states.
- - pinctrl-0: pin-control mode. can be <_pins> or <_pins>.
+ - pinctrl-0: pin-control mode. can be <_pins>, <_pins> or led pins
+   for internal phy mode.
  - clock_in_out: For RGMII, it must be "input", means main clock(125MHz)
is not sourced from SoC's PLL, but input from PHY; For RMII, "input" means
PHY provides the reference clock(50MHz), "output" means GMAC provides the
@@ -40,6 +41,9 @@ Optional properties:
  - tx_delay: Delay value for TXD timing. Range value is 0~0x7F, 0x30 as 
default.
  - rx_delay: Delay value for RXD timing. Range value is 0~0x7F, 0x10 as 
default.
  - phy-supply: phandle to a regulator if the PHY needs one
+ - clocks: < MAC_PHY>: Clock selector for internal macphy
+ - phy-is-internal: A boolean property allows us to know that MAC will connect 
to
+   internal phy.
 
 Example:
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index a8e8fd5..7b80ab9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -41,6 +41,7 @@ struct rk_gmac_ops {
void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
+   void (*internal_phy_powerup)(struct rk_priv_data *bsp_priv);
 };
 
 struct rk_priv_data {
@@ -52,6 +53,7 @@ struct rk_priv_data {
 
bool clk_enabled;
bool clock_input;
+   bool internal_phy;
 
struct clk *clk_mac;
struct clk *gmac_clkin;
@@ -61,6 +63,9 @@ struct rk_priv_data {
struct clk *clk_mac_refout;
struct clk *aclk_mac;
struct clk *pclk_mac;
+   struct clk *clk_macphy;
+
+   struct reset_control *macphy_reset;
 
int tx_delay;
int rx_delay;
@@ -750,6 +755,50 @@ static void rk3399_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
.set_rmii_speed = rk3399_set_rmii_speed,
 };
 
+#define RK_GRF_MACPHY_CON0 0xb00
+#define RK_GRF_MACPHY_CON1 0xb04
+#define RK_GRF_MACPHY_CON2 0xb08
+#define RK_GRF_MACPHY_CON3 0xb0c
+
+#define RK_MACPHY_ENABLE   GRF_BIT(0)
+#define RK_MACPHY_DISABLE  GRF_CLR_BIT(0)
+#define RK_MACPHY_CFG_CLK_50M  GRF_BIT(14)
+#define RK_GMAC2PHY_RMII_MODE  (GRF_BIT(6) | GRF_CLR_BIT(7))
+#define RK_GRF_CON2_MACPHY_ID  HIWORD_UPDATE(0x1234, 0x, 0)
+#define RK_GRF_CON3_MACPHY_ID  HIWORD_UPDATE(0x35, 0x3f, 0)
+
+static void rk_gmac_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   if (priv->ops->internal_phy_powerup)
+   priv->ops->internal_phy_powerup(priv);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
+
+   if (priv->macphy_reset) {
+   /* macphy needs to be disabled before trying to reset it */
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->macphy_reset)
+   reset_control_assert(priv->macphy_reset);
+   usleep_range(10, 20);
+   if (priv->macphy_reset)
+   reset_control_deassert(priv->macphy_reset);
+   usleep_range(10, 20);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
+   msleep(30);
+   }
+}
+
+static void rk_gmac_internal_phy_powerdown(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->macphy_reset)
+   reset_control_assert(priv->macphy_reset);
+}
+
 static int gmac_clk_init(struct rk_priv_data *bsp_priv)
 {
struct device *dev = _priv->pdev->d

[PATCH v3 00/11] Add the internal phy support

2017-08-02 Thread David Wu
The rk3228 and rk3328 support internal phy inside, let's enable
it to work. And the internal phy need to do some special setting, so
register the rockchip internal phy driver.

David Wu (11):
  net: phy: Add rockchip phy driver support
  multi_v7_defconfig: Make rockchip phy built-in
  arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY
  net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()
  net: stmmac: dwmac-rk: Add internal phy support
  net: stmmac: dwmac-rk: Add internal phy support for rk3228
  net: stmmac: dwmac-rk: Add internal phy supprot for rk3328
  ARM: dts: rk322x: Add support internal phy for gmac
  ARM: dts: rk3228-evb: Enable the internal phy for gmac
  ARM64: dts: rockchip: Add gmac2phy node support for rk3328
  ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

 .../devicetree/bindings/net/rockchip-dwmac.txt |   6 +-
 arch/arm/boot/dts/rk3228-evb.dts   |  20 ++
 arch/arm/boot/dts/rk322x.dtsi  |   8 +-
 arch/arm/configs/multi_v7_defconfig|   1 +
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts|  17 ++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   |  25 +++
 arch/arm64/configs/defconfig   |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 122 ++-
 drivers/net/phy/Kconfig|   5 +
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/rockchip.c | 229 +
 11 files changed, 424 insertions(+), 11 deletions(-)
 create mode 100644 drivers/net/phy/rockchip.c

-- 
1.9.1




[PATCH v3 01/11] net: phy: Add rockchip phy driver support

2017-08-02 Thread David Wu
Support internal ethernet phy currently.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/phy/Kconfig|   5 +
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/rockchip.c | 229 +
 3 files changed, 235 insertions(+)
 create mode 100644 drivers/net/phy/rockchip.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 2dda720..22cc702 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -334,6 +334,11 @@ config REALTEK_PHY
---help---
  Supports the Realtek 821x PHY.
 
+config ROCKCHIP_PHY
+tristate "Driver for Rockchip Ethernet PHYs"
+---help---
+  Currently supports the internal Ethernet PHY.
+
 config SMSC_PHY
tristate "SMSC PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 8e9b9f3..350520e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_MICROSEMI_PHY)   += mscc.o
 obj-$(CONFIG_NATIONAL_PHY) += national.o
 obj-$(CONFIG_QSEMI_PHY)+= qsemi.o
 obj-$(CONFIG_REALTEK_PHY)  += realtek.o
+obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
 obj-$(CONFIG_SMSC_PHY) += smsc.o
 obj-$(CONFIG_STE10XP)  += ste10Xp.o
 obj-$(CONFIG_TERANETICS_PHY)   += teranetics.o
diff --git a/drivers/net/phy/rockchip.c b/drivers/net/phy/rockchip.c
new file mode 100644
index 000..c1f07d6
--- /dev/null
+++ b/drivers/net/phy/rockchip.c
@@ -0,0 +1,229 @@
+/**
+ * drivers/net/phy/rockchip.c
+ *
+ * Driver for ROCKCHIP Ethernet PHYs
+ *
+ * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * David Wu <david...@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MII_INTERNAL_CTRL_STATUS   17
+#define SMI_ADDR_TSTCNTL   20
+#define SMI_ADDR_TSTREAD1  21
+#define SMI_ADDR_TSTREAD2  22
+#define SMI_ADDR_TSTWRITE  23
+#define MII_SPECIAL_CONTROL_STATUS 31
+
+#define MII_AUTO_MDIX_EN   BIT(7)
+#define MII_MDIX_ENBIT(6)
+
+#define MII_SPEED_10   BIT(2)
+#define MII_SPEED_100  BIT(3)
+
+#define TSTCNTL_RD (BIT(15) | BIT(10))
+#define TSTCNTL_WR (BIT(14) | BIT(10))
+
+#define WR_ADDR_A7CFG  0x18
+
+static int rockchip_init_tstmode(struct phy_device *phydev)
+{
+   int ret;
+
+   /* Enable access to Analog and DSP register banks */
+   ret = phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0400);
+   if (ret)
+   return ret;
+
+   ret = phy_write(phydev, SMI_ADDR_TSTCNTL, 0x);
+   if (ret)
+   return ret;
+
+   return phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0400);
+}
+
+static int rockchip_close_tstmode(struct phy_device *phydev)
+{
+   /* Back to basic register bank */
+   return phy_write(phydev, SMI_ADDR_TSTCNTL, 0x);
+}
+
+static int rockchip_internal_phy_analog_init(struct phy_device *phydev)
+{
+   int ret;
+
+   ret = rockchip_init_tstmode(phydev);
+   if (ret)
+   return ret;
+
+   /*
+* Adjust tx amplitude to make sginal better,
+* the default value is 0x8.
+*/
+   ret = phy_write(phydev, SMI_ADDR_TSTWRITE, 0xB);
+   if (ret)
+   return ret;
+   ret = phy_write(phydev, SMI_ADDR_TSTCNTL, TSTCNTL_WR | WR_ADDR_A7CFG);
+   if (ret)
+   return ret;
+
+   return rockchip_close_tstmode(phydev);
+}
+
+static int rockchip_internal_phy_config_init(struct phy_device *phydev)
+{
+   int val, ret;
+
+   /*
+* The auto MIDX has linked problem on some board,
+* workround to disable auto MDIX.
+*/
+   val = phy_read(phydev, MII_INTERNAL_CTRL_STATUS);
+   if (val < 0)
+   return val;
+   val &= ~MII_AUTO_MDIX_EN;
+   ret = phy_write(phydev, MII_INTERNAL_CTRL_STATUS, val);
+   if (ret)
+   return ret;
+
+   return rockchip_internal_phy_analog_init(phydev);
+}
+
+static void rockchip_link_change_notify(struct phy_device *phydev)
+{
+   int speed = SPEED_10;
+
+   if (phydev->autoneg == AUTONEG_ENABLE) {
+   int reg = phy_read(phydev, MII_SPECIAL_CONTROL_STATUS);
+
+   if (reg < 0) {
+   phydev_err(phydev, "phy_read err: %d.\n", reg);
+   return;
+   }
+
+   if (reg & MII_SPEED_100)
+   speed = SPEED_100;
+   else if (reg & MII_SPEED_10)
+   speed = SPEED_

[PATCH v3 02/11] multi_v7_defconfig: Make rockchip phy built-in

2017-08-02 Thread David Wu
Enable the rockchip phy for multi_v7_defconfig builds.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index 4d19c1b..94d7e71 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -270,6 +270,7 @@ CONFIG_ICPLUS_PHY=y
 CONFIG_REALTEK_PHY=y
 CONFIG_MICREL_PHY=y
 CONFIG_FIXED_PHY=y
+CONFIG_ROCKCHIP_PHY=y
 CONFIG_USB_PEGASUS=y
 CONFIG_USB_RTL8152=m
 CONFIG_USB_USBNET=y
-- 
1.9.1




[PATCH v3 04/11] net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()

2017-08-02 Thread David Wu
This is wrong setting for rk3328_set_to_rmii(), so remove it.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index f0df519..a8e8fd5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -365,9 +365,6 @@ static void rk3328_set_to_rmii(struct rk_priv_data 
*bsp_priv)
regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
-
-   /* set MAC to RMII mode */
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, GRF_BIT(11));
 }
 
 static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
-- 
1.9.1




[PATCH v3 03/11] arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY

2017-08-02 Thread David Wu
Make the rockchip phy driver built into the kernel.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6c7d147..925bd478 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -203,6 +203,7 @@ CONFIG_MARVELL_PHY=m
 CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
 CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_PHY=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
-- 
1.9.1




[PATCH v2 11/11] ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

2017-07-27 Thread David Wu
Enable the gmac2phy, make the gmac2phy work on
the rk3328-evb board.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 17 +
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index cf27239..b9f36da 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -50,6 +50,23 @@
chosen {
stdout-path = "serial2:150n8";
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   regulator-name = "vcc_phy";
+   regulator-always-on;
+   regulator-boot-on;
+   };
+};
+
+ {
+   phy-supply = <_phy>;
+   clock_in_out = "output";
+   assigned-clocks = < SCLK_MAC2PHY_SRC>;
+   assigned-clock-rate = <5000>;
+   assigned-clocks = < SCLK_MAC2PHY>;
+   assigned-clock-parents = < SCLK_MAC2PHY_SRC>;
+   status = "okay";
 };
 
  {
-- 
1.9.1




[PATCH v2 10/11] ARM64: dts: rockchip: Add gmac2phy node support for rk3328

2017-07-27 Thread David Wu
The gmac2phy controller of rk3328 is connected to internal phy
directly inside, add the node for the internal phy support.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 24 
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 0be96ce..4349492 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -63,6 +63,8 @@
i2c1 = 
i2c2 = 
i2c3 = 
+   ethernet0 = 
+   ethernet1 = 
};
 
cpus {
@@ -424,6 +426,28 @@
status = "disabled";
};
 
+   gmac2phy: eth@ff55 {
+   compatible = "rockchip,rk3328-gmac";
+   reg = <0x0 0xff55 0x0 0x1>;
+   rockchip,grf = <>;
+   interrupts = ;
+   interrupt-names = "macirq";
+   clocks = < SCLK_MAC2PHY_SRC>, < SCLK_MAC2PHY_RXTX>,
+< SCLK_MAC2PHY_RXTX>, < SCLK_MAC2PHY_REF>,
+< ACLK_MAC2PHY>, < PCLK_MAC2PHY>,
+< SCLK_MAC2PHY_OUT>;
+   clock-names = "stmmaceth", "mac_clk_rx",
+ "mac_clk_tx", "clk_mac_ref",
+ "aclk_mac", "pclk_mac",
+ "clk_macphy";
+   resets = < SRST_GMAC2PHY_A>, < SRST_MACPHY>;
+   reset-names = "stmmaceth", "mac-phy";
+   phy-mode = "internal";
+   pinctrl-names = "default";
+   pinctrl-0 = <_rxm1 _linkm1>;
+   status = "disabled";
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
1.9.1




[PATCH v2 05/11] net: stmmac: dwmac-rk: Add internal phy support

2017-07-27 Thread David Wu
To make internal phy work, need to configure the phy_clock,
phy cru_reset and related registers.

Signed-off-by: David Wu <david...@rock-chips.com>
---
changes in v2:
 - Use the standard "phy-mode" property for internal phy. (Florian)
 - Move the internal macphy clock to the optional properties. (Heiko)

 .../devicetree/bindings/net/rockchip-dwmac.txt |  4 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 94 +-
 2 files changed, 93 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt 
b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
index 8f42755..ecebab8 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -25,7 +25,8 @@ Required properties:
  - clock-names: One name for each entry in the clocks property.
  - phy-mode: See ethernet.txt file in the same directory.
  - pinctrl-names: Names corresponding to the numbered pinctrl states.
- - pinctrl-0: pin-control mode. can be <_pins> or <_pins>.
+ - pinctrl-0: pin-control mode. can be <_pins>, <_pins> or led pins
+   for internal phy mode.
  - clock_in_out: For RGMII, it must be "input", means main clock(125MHz)
is not sourced from SoC's PLL, but input from PHY; For RMII, "input" means
PHY provides the reference clock(50MHz), "output" means GMAC provides the
@@ -40,6 +41,7 @@ Optional properties:
  - tx_delay: Delay value for TXD timing. Range value is 0~0x7F, 0x30 as 
default.
  - rx_delay: Delay value for RXD timing. Range value is 0~0x7F, 0x10 as 
default.
  - phy-supply: phandle to a regulator if the PHY needs one
+ - clocks: < MAC_PHY>: clock for internal macphy
 
 Example:
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index a8e8fd5..ec280d1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -41,6 +41,7 @@ struct rk_gmac_ops {
void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
+   void (*internal_phy_powerup)(struct rk_priv_data *bsp_priv);
 };
 
 struct rk_priv_data {
@@ -52,6 +53,7 @@ struct rk_priv_data {
 
bool clk_enabled;
bool clock_input;
+   bool internal_phy;
 
struct clk *clk_mac;
struct clk *gmac_clkin;
@@ -61,6 +63,9 @@ struct rk_priv_data {
struct clk *clk_mac_refout;
struct clk *aclk_mac;
struct clk *pclk_mac;
+   struct clk *clk_macphy;
+
+   struct reset_control *macphy_reset;
 
int tx_delay;
int rx_delay;
@@ -750,6 +755,50 @@ static void rk3399_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
.set_rmii_speed = rk3399_set_rmii_speed,
 };
 
+#define RK_GRF_MACPHY_CON0 0xb00
+#define RK_GRF_MACPHY_CON1 0xb04
+#define RK_GRF_MACPHY_CON2 0xb08
+#define RK_GRF_MACPHY_CON3 0xb0c
+
+#define RK_MACPHY_ENABLE   GRF_BIT(0)
+#define RK_MACPHY_DISABLE  GRF_CLR_BIT(0)
+#define RK_MACPHY_CFG_CLK_50M  GRF_BIT(14)
+#define RK_GMAC2PHY_RMII_MODE  (GRF_BIT(6) | GRF_CLR_BIT(7))
+#define RK_GRF_CON2_MACPHY_ID  HIWORD_UPDATE(0x1234, 0x, 0)
+#define RK_GRF_CON3_MACPHY_ID  HIWORD_UPDATE(0x35, 0x3f, 0)
+
+static void rk_gmac_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   if (priv->ops->internal_phy_powerup)
+   priv->ops->internal_phy_powerup(priv);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
+
+   if (priv->macphy_reset) {
+   /* macphy needs to be disabled before trying to reset it */
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->macphy_reset)
+   reset_control_assert(priv->macphy_reset);
+   usleep_range(10, 20);
+   if (priv->macphy_reset)
+   reset_control_deassert(priv->macphy_reset);
+   usleep_range(10, 20);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
+   msleep(30);
+   }
+}
+
+static void rk_gmac_internal_phy_powerdown(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->macphy_reset)
+   reset_control_assert(priv->macphy_reset);
+}
+
 static int gmac_clk_init(struct rk_priv_data *bsp_

[PATCH v2 06/11] net: stmmac: dwmac-rk: Add internal phy support for rk3228

2017-07-27 Thread David Wu
There is only one mac controller in rk3228, which could connect to
external phy or internal phy, use the grf_com_mux bit15 to route
external/internal phy.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index ec280d1..3ec9cd8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -86,6 +86,8 @@ struct rk_priv_data {
 #define RK3228_GRF_MAC_CON00x0900
 #define RK3228_GRF_MAC_CON10x0904
 
+#define RK3228_GRF_CON_MUX 0x50
+
 /* RK3228_GRF_MAC_CON0 */
 #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
 #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
@@ -111,6 +113,9 @@ struct rk_priv_data {
 #define RK3228_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3228_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(1)
 
+/* RK3228_GRF_COM_MUX */
+#define RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY   GRF_BIT(15)
+
 static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -191,11 +196,18 @@ static void rk3228_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3228_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3228_GRF_CON_MUX,
+RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY);
+}
+
 static const struct rk_gmac_ops rk3228_ops = {
.set_to_rgmii = rk3228_set_to_rgmii,
.set_to_rmii = rk3228_set_to_rmii,
.set_rgmii_speed = rk3228_set_rgmii_speed,
.set_rmii_speed = rk3228_set_rmii_speed,
+   .internal_phy_powerup =  rk3228_internal_phy_powerup,
 };
 
 #define RK3288_GRF_SOC_CON10x0248
-- 
1.9.1




[PATCH v2 09/11] ARM: dts: rk3228-evb: Enable the internal phy for gmac

2017-07-27 Thread David Wu
This patch enables the internal phy for rk3228 evb board
by default.
To use the external 1000M phy on evb board, need to make
some switch of evb board to be on.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/boot/dts/rk3228-evb.dts | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
index 5883433..73b88d3 100644
--- a/arch/arm/boot/dts/rk3228-evb.dts
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -50,6 +50,16 @@
device_type = "memory";
reg = <0x6000 0x4000>;
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   enable-active-high;
+   regulator-name = "vcc_phy";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-always-on;
+   regulator-boot-on;
+   };
 };
 
  {
@@ -60,6 +70,15 @@
status = "okay";
 };
 
+ {
+   assigned-clocks = < SCLK_MAC_SRC>;
+   assigned-clock-rates = <5000>;
+   clock_in_out = "output";
+   phy-supply = <_phy>;
+   phy-mode = "internal";
+   status = "okay";
+};
+
  {
status = "okay";
 
-- 
1.9.1




[PATCH v2 07/11] net: stmmac: dwmac-rk: Add internal phy supprot for rk3328

2017-07-27 Thread David Wu
There are two mac controllers in the rk3328, the one connects
to external phy, and the other one connects to internal phy.
Like the mac of external phy, the internal phy's mac also needs to
configure the related mac registers at GRF.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 3ec9cd8..67066a3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -323,6 +323,8 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 
 #define RK3328_GRF_MAC_CON00x0900
 #define RK3328_GRF_MAC_CON10x0904
+#define RK3328_GRF_MAC_CON20x0908
+#define RK3328_GRF_MACPHY_CON1 0xb04
 
 /* RK3328_GRF_MAC_CON0 */
 #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
@@ -349,6 +351,9 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 #define RK3328_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3328_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(0)
 
+/* RK3328_GRF_MACPHY_CON1 */
+#define RK3328_MACPHY_RMII_MODEGRF_BIT(9)
+
 static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -373,13 +378,17 @@ static void rk3328_set_to_rgmii(struct rk_priv_data 
*bsp_priv,
 static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
 }
@@ -409,29 +418,40 @@ static void rk3328_set_rgmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
+   reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
if (speed == 10)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_2_5M |
 RK3328_GMAC_SPEED_10M);
else if (speed == 100)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_25M |
 RK3328_GMAC_SPEED_100M);
else
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3328_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
+RK3328_MACPHY_RMII_MODE);
+}
+
 static const struct rk_gmac_ops rk3328_ops = {
.set_to_rgmii = rk3328_set_to_rgmii,
.set_to_rmii = rk3328_set_to_rmii,
.set_rgmii_speed = rk3328_set_rgmii_speed,
.set_rmii_speed = rk3328_set_rmii_speed,
+   .internal_phy_powerup =  rk3328_internal_phy_powerup,
 };
 
 #define RK3366_GRF_SOC_CON60x0418
-- 
1.9.1




[PATCH v2 08/11] ARM: dts: rk322x: Add support internal phy for gmac

2017-07-27 Thread David Wu
This patch adds internal mac phy clock and internal mac phy reset
for rk gmac using.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/boot/dts/rk322x.dtsi | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index f3e4ffd..3778f7d 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -611,13 +611,13 @@
clocks = < SCLK_MAC>, < SCLK_MAC_RX>,
< SCLK_MAC_TX>, < SCLK_MAC_REF>,
< SCLK_MAC_REFOUT>, < ACLK_GMAC>,
-   < PCLK_GMAC>;
+   < PCLK_GMAC>, < SCLK_MAC_PHY>;
clock-names = "stmmaceth", "mac_clk_rx",
"mac_clk_tx", "clk_mac_ref",
"clk_mac_refout", "aclk_mac",
-   "pclk_mac";
-   resets = < SRST_GMAC>;
-   reset-names = "stmmaceth";
+   "pclk_mac", "clk_macphy";
+   resets = < SRST_GMAC>, < SRST_MACPHY>;
+   reset-names = "stmmaceth", "mac-phy";
rockchip,grf = <>;
status = "disabled";
};
-- 
1.9.1




[PATCH v2 01/11] net: phy: Add rockchip phy driver support

2017-07-27 Thread David Wu
Support internal ephy currently.

Signed-off-by: David Wu <david...@rock-chips.com>
---
changes in v2:
 - Alphabetic order for Kconfig and Makefile.
 - Add analog register init.
 - Disable auto-mdix for workround.
 - Rename config

 drivers/net/phy/Kconfig|   5 ++
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/rockchip.c | 128 +
 3 files changed, 134 insertions(+)
 create mode 100644 drivers/net/phy/rockchip.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 2dda720..8dc6cd7 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -334,6 +334,11 @@ config REALTEK_PHY
---help---
  Supports the Realtek 821x PHY.
 
+config ROCKCHIP_PHY
+tristate "Drivers for ROCKCHIP PHYs"
+---help---
+  Currently supports the internal ephy.
+
 config SMSC_PHY
tristate "SMSC PHYs"
---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 8e9b9f3..350520e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_MICROSEMI_PHY)   += mscc.o
 obj-$(CONFIG_NATIONAL_PHY) += national.o
 obj-$(CONFIG_QSEMI_PHY)+= qsemi.o
 obj-$(CONFIG_REALTEK_PHY)  += realtek.o
+obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o
 obj-$(CONFIG_SMSC_PHY) += smsc.o
 obj-$(CONFIG_STE10XP)  += ste10Xp.o
 obj-$(CONFIG_TERANETICS_PHY)   += teranetics.o
diff --git a/drivers/net/phy/rockchip.c b/drivers/net/phy/rockchip.c
new file mode 100644
index 000..3f74658
--- /dev/null
+++ b/drivers/net/phy/rockchip.c
@@ -0,0 +1,128 @@
+/**
+ * drivers/net/phy/rockchip.c
+ *
+ * Driver for ROCKCHIP PHY
+ *
+ * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * David Wu<david...@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MII_INTERNAL_CTRL_STATUS   17
+#define SMI_ADDR_TSTCNTL   20
+#define SMI_ADDR_TSTREAD1  21
+#define SMI_ADDR_TSTREAD2  22
+#define SMI_ADDR_TSTWRITE  23
+
+#define AUTOMDIX_ENBIT(7)
+#define TSTCNTL_RD (BIT(15) | BIT(10))
+#define TSTCNTL_WR (BIT(14) | BIT(10))
+
+#define WR_ADDR_A7CFG  0x18
+
+static void rockchip_init_tstmode(struct phy_device *phydev)
+{
+   /* Enable access to Analog and DSP register banks */
+   phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0400);
+   phy_write(phydev, SMI_ADDR_TSTCNTL, 0x);
+   phy_write(phydev, SMI_ADDR_TSTCNTL, 0x0400);
+}
+
+static void  rockchip_close_tstmode(struct phy_device *phydev)
+{
+   /* Back to basic register bank */
+   phy_write(phydev, SMI_ADDR_TSTCNTL, 0x);
+}
+
+static void rockchip_internal_phy_analog_init(struct phy_device *phydev)
+{
+   rockchip_init_tstmode(phydev);
+
+   /*
+* Adjust tx amplitude to make sginal better,
+* the default value is 0x8.
+*/
+   phy_write(phydev, SMI_ADDR_TSTWRITE, 0xB);
+   phy_write(phydev, SMI_ADDR_TSTCNTL, TSTCNTL_WR | WR_ADDR_A7CFG);
+
+   rockchip_close_tstmode(phydev);
+}
+
+static int rockchip_internal_phy_config_init(struct phy_device *phydev)
+{
+   int val;
+
+   /*
+* The auto MIDX has linked problem on some board,
+* workround to disable auto MDIX.
+*/
+   val = phy_read(phydev, MII_INTERNAL_CTRL_STATUS);
+   val &= ~AUTOMDIX_EN;
+   phy_write(phydev, MII_INTERNAL_CTRL_STATUS, val);
+
+   rockchip_internal_phy_analog_init(phydev);
+
+   return 0;
+}
+
+static int rockchip_internal_phy_read_status(struct phy_device *phydev)
+{
+   int ret, old_speed;
+
+   old_speed = phydev->speed;
+   ret = genphy_read_status(phydev);
+   if (ret)
+   return ret;
+
+   /*
+* If mode switch happens from 10BT to 100BT, all DSP/AFE
+* registers are set to default values. So any AFE/DSP
+* registers have to be re-initialized in this case.
+*/
+   if ((old_speed == SPEED_10) && (phydev->speed == SPEED_100))
+   rockchip_internal_phy_analog_init(phydev);
+
+   return ret;
+}
+
+static struct phy_driver rockchip_phy_driver[] = {
+{
+   .phy_id = 0x1234d400,
+   .phy_id_mask= 0x,
+   .name   = "rockchip internal ephy",
+   .features   = (PHY_BASIC_FEATURES | SUPPORTED_Pause
+ | SUPPORTED_Asym_Pause),
+   .soft_reset = genphy_soft_reset,
+   .config_init= rockchip_internal_phy_config_init,
+ 

[PATCH v2 00/11] Add the internal phy support

2017-07-27 Thread David Wu
The rk3228 and rk3328 support internal phy inside, let's enable
it to work. And the internal phy need to do some special setting, so
register the rockchip internal phy driver.

David Wu (11):
  net: phy: Add rockchip phy driver support
  multi_v7_defconfig: Make rockchip phy built-in
  arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY
  net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()
  net: stmmac: dwmac-rk: Add internal phy support
  net: stmmac: dwmac-rk: Add internal phy support for rk3228
  net: stmmac: dwmac-rk: Add internal phy supprot for rk3328
  ARM: dts: rk322x: Add support internal phy for gmac
  ARM: dts: rk3228-evb: Enable the internal phy for gmac
  ARM64: dts: rockchip: Add gmac2phy node support for rk3328
  ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

 .../devicetree/bindings/net/rockchip-dwmac.txt |   4 +-
 arch/arm/boot/dts/rk3228-evb.dts   |  19 +++
 arch/arm/boot/dts/rk322x.dtsi  |   8 +-
 arch/arm/configs/multi_v7_defconfig|   1 +
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts|  17 +++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   |  24 
 arch/arm64/configs/defconfig   |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 135 +++--
 drivers/net/phy/Kconfig|   5 +
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/rockchip.c | 128 +++
 11 files changed, 328 insertions(+), 15 deletions(-)
 create mode 100644 drivers/net/phy/rockchip.c

-- 
1.9.1




[PATCH v2 02/11] multi_v7_defconfig: Make rockchip phy built-in

2017-07-27 Thread David Wu
Enable the rockchip phy for multi_v7_defconfig builds.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index 4d19c1b..94d7e71 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -270,6 +270,7 @@ CONFIG_ICPLUS_PHY=y
 CONFIG_REALTEK_PHY=y
 CONFIG_MICREL_PHY=y
 CONFIG_FIXED_PHY=y
+CONFIG_ROCKCHIP_PHY=y
 CONFIG_USB_PEGASUS=y
 CONFIG_USB_RTL8152=m
 CONFIG_USB_USBNET=y
-- 
1.9.1




[PATCH v2 03/11] arm64: defconfig: Enable CONFIG_ROCKCHIP_PHY

2017-07-27 Thread David Wu
Make the rockchip phy driver built into the kernel.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6c7d147..925bd478 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -203,6 +203,7 @@ CONFIG_MARVELL_PHY=m
 CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
 CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_PHY=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
-- 
1.9.1




[PATCH v2 04/11] net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()

2017-07-27 Thread David Wu
This is wrong setting for rk3328_set_to_rmii(), so remove it.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index f0df519..a8e8fd5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -365,9 +365,6 @@ static void rk3328_set_to_rmii(struct rk_priv_data 
*bsp_priv)
regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
-
-   /* set MAC to RMII mode */
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, GRF_BIT(11));
 }
 
 static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
-- 
1.9.1




[PATCH 11/11] ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

2017-06-22 Thread David Wu
Let's enable the gmac2phy, make the gmac2phy work on
the rk3328-evb board.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts | 17 +
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts 
b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index cf27239..b9f36da 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -50,6 +50,23 @@
chosen {
stdout-path = "serial2:150n8";
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   regulator-name = "vcc_phy";
+   regulator-always-on;
+   regulator-boot-on;
+   };
+};
+
+ {
+   phy-supply = <_phy>;
+   clock_in_out = "output";
+   assigned-clocks = < SCLK_MAC2PHY_SRC>;
+   assigned-clock-rate = <5000>;
+   assigned-clocks = < SCLK_MAC2PHY>;
+   assigned-clock-parents = < SCLK_MAC2PHY_SRC>;
+   status = "okay";
 };
 
  {
-- 
1.9.1




[PATCH 10/11] ARM64: dts: rockchip: Add gmac2phy node support for rk3328

2017-06-22 Thread David Wu
The gmac2phy controller of rk3328 is connected to internal phy
directly inside, add the node for the internal phy support.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 25 +
 1 file changed, 25 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 7e69f1f..29b3800 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -63,6 +63,8 @@
i2c1 = 
i2c2 = 
i2c3 = 
+   ethernet0 = 
+   ethernet1 = 
};
 
cpus {
@@ -391,6 +393,29 @@
status = "disabled";
};
 
+   gmac2phy: eth@ff55 {
+   compatible = "rockchip,rk3328-gmac";
+   reg = <0x0 0xff55 0x0 0x1>;
+   rockchip,grf = <>;
+   interrupts = ;
+   interrupt-names = "macirq";
+   clocks = < SCLK_MAC2PHY_SRC>, < SCLK_MAC2PHY_RXTX>,
+< SCLK_MAC2PHY_RXTX>, < SCLK_MAC2PHY_REF>,
+< ACLK_MAC2PHY>, < PCLK_MAC2PHY>,
+< SCLK_MAC2PHY_OUT>;
+   clock-names = "stmmaceth", "mac_clk_rx",
+ "mac_clk_tx", "clk_mac_ref",
+ "aclk_mac", "pclk_mac",
+ "clk_macphy";
+   resets = < SRST_GMAC2PHY_A>, < SRST_MACPHY>;
+   reset-names = "stmmaceth", "mac-phy";
+   phy-mode = "rmii";
+   phy-type = "internal";
+   pinctrl-names = "default";
+   pinctrl-0 = <_rxm1 _linkm1>;
+   status = "disabled";
+   };
+
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
-- 
1.9.1




[PATCH 09/11] ARM: dts: rk3228-evb: Enable the internal phy for gmac

2017-06-22 Thread David Wu
This patch enables the internal phy for rk3228 evb board
by default.
To use the external 1000M phy on evb board, need to make
some switch of evb board to be on.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/boot/dts/rk3228-evb.dts | 20 
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts
index 5883433..c4002da 100644
--- a/arch/arm/boot/dts/rk3228-evb.dts
+++ b/arch/arm/boot/dts/rk3228-evb.dts
@@ -50,6 +50,16 @@
device_type = "memory";
reg = <0x6000 0x4000>;
};
+
+   vcc_phy: vcc-phy-regulator {
+   compatible = "regulator-fixed";
+   enable-active-high;
+   regulator-name = "vcc_phy";
+   regulator-min-microvolt = <180>;
+   regulator-max-microvolt = <180>;
+   regulator-always-on;
+   regulator-boot-on;
+   };
 };
 
  {
@@ -60,6 +70,16 @@
status = "okay";
 };
 
+ {
+   assigned-clocks = < SCLK_MAC_SRC>;
+   assigned-clock-rates = <5000>;
+   clock_in_out = "output";
+   phy-supply = <_phy>;
+   phy-mode = "rmii";
+   phy-type = "internal";
+   status = "okay";
+};
+
  {
status = "okay";
 
-- 
1.9.1




[PATCH 08/11] ARM: dts: rk322x: Add support internal phy for gmac

2017-06-22 Thread David Wu
This patch adds internal mac phy clock and internal mac phy reset
for rk gmac using.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/boot/dts/rk322x.dtsi | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi
index 48a0c1c..203a583 100644
--- a/arch/arm/boot/dts/rk322x.dtsi
+++ b/arch/arm/boot/dts/rk322x.dtsi
@@ -427,13 +427,13 @@
clocks = < SCLK_MAC>, < SCLK_MAC_RX>,
< SCLK_MAC_TX>, < SCLK_MAC_REF>,
< SCLK_MAC_REFOUT>, < ACLK_GMAC>,
-   < PCLK_GMAC>;
+   < PCLK_GMAC>, < SCLK_MAC_PHY>;
clock-names = "stmmaceth", "mac_clk_rx",
"mac_clk_tx", "clk_mac_ref",
"clk_mac_refout", "aclk_mac",
-   "pclk_mac";
-   resets = < SRST_GMAC>;
-   reset-names = "stmmaceth";
+   "pclk_mac", "clk_macphy";
+   resets = < SRST_GMAC>, < SRST_MACPHY>;
+   reset-names = "stmmaceth", "mac-phy";
rockchip,grf = <>;
status = "disabled";
};
-- 
1.9.1




[PATCH 07/11] net: stmmac: dwmac-rk: Add internal phy supprot for rk3328

2017-06-22 Thread David Wu
There are two mac controllers in the rk3328, the one connects
to external phy, and the other one connects to internal phy.
Like the mac of external phy, the internal phy's mac also needs to
configure the related mac registers at GRF.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 90e1fc8..c4c58a2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -323,6 +323,8 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 
 #define RK3328_GRF_MAC_CON00x0900
 #define RK3328_GRF_MAC_CON10x0904
+#define RK3328_GRF_MAC_CON20x0908
+#define RK3328_GRF_MACPHY_CON1 0xb04
 
 /* RK3328_GRF_MAC_CON0 */
 #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
@@ -349,6 +351,9 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 #define RK3328_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3328_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(0)
 
+/* RK3328_GRF_MACPHY_CON1 */
+#define RK3328_MACPHY_RMII_MODEGRF_BIT(9)
+
 static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -373,13 +378,17 @@ static void rk3328_set_to_rgmii(struct rk_priv_data 
*bsp_priv,
 static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
 }
@@ -409,29 +418,40 @@ static void rk3328_set_rgmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
 static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
 {
struct device *dev = _priv->pdev->dev;
+   unsigned int reg;
 
if (IS_ERR(bsp_priv->grf)) {
dev_err(dev, "Missing rockchip,grf property\n");
return;
}
 
+   reg = bsp_priv->internal_phy ? RK3328_GRF_MAC_CON2 :
+ RK3328_GRF_MAC_CON1;
+
if (speed == 10)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_2_5M |
 RK3328_GMAC_SPEED_10M);
else if (speed == 100)
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+   regmap_write(bsp_priv->grf, reg,
 RK3328_GMAC_RMII_CLK_25M |
 RK3328_GMAC_SPEED_100M);
else
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3328_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
+RK3328_MACPHY_RMII_MODE);
+}
+
 static const struct rk_gmac_ops rk3328_ops = {
.set_to_rgmii = rk3328_set_to_rgmii,
.set_to_rmii = rk3328_set_to_rmii,
.set_rgmii_speed = rk3328_set_rgmii_speed,
.set_rmii_speed = rk3328_set_rmii_speed,
+   .internal_phy_powerup =  rk3328_internal_phy_powerup,
 };
 
 #define RK3366_GRF_SOC_CON60x0418
-- 
1.9.1




[PATCH 06/11] net: stmmac: dwmac-rk: Add internal phy support for rk3228

2017-06-22 Thread David Wu
There is only one mac controller in rk3228, which could connect to
external phy or internal phy, use the grf_com_mux bit15 to route
external/internal phy.

Change-Id: I3a366677047b8032eb535abb0c3e56fa7722aa2e
Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index c1a1413..90e1fc8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -86,6 +86,8 @@ struct rk_priv_data {
 #define RK3228_GRF_MAC_CON00x0900
 #define RK3228_GRF_MAC_CON10x0904
 
+#define RK3228_GRF_CON_MUX 0x50
+
 /* RK3228_GRF_MAC_CON0 */
 #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
 #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
@@ -111,6 +113,9 @@ struct rk_priv_data {
 #define RK3228_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
 #define RK3228_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(1)
 
+/* RK3228_GRF_COM_MUX */
+#define RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY   GRF_BIT(15)
+
 static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
 {
@@ -191,11 +196,18 @@ static void rk3228_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
 }
 
+static void rk3228_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK3228_GRF_CON_MUX,
+RK3228_GRF_CON_MUX_GMAC_INTERNAL_PHY);
+}
+
 static const struct rk_gmac_ops rk3228_ops = {
.set_to_rgmii = rk3228_set_to_rgmii,
.set_to_rmii = rk3228_set_to_rmii,
.set_rgmii_speed = rk3228_set_rgmii_speed,
.set_rmii_speed = rk3228_set_rmii_speed,
+   .internal_phy_powerup =  rk3228_internal_phy_powerup,
 };
 
 #define RK3288_GRF_SOC_CON10x0248
-- 
1.9.1




[PATCH 05/11] net: stmmac: dwmac-rk: Add internal phy support

2017-06-22 Thread David Wu
To make internal phy worked, need to configure the phy_clock,
phy cru_reset and related registers.

Change-Id: I6971c0a769754b824b1b908b56080cbaf7867d13
Signed-off-by: David Wu <david...@rock-chips.com>
---
 .../devicetree/bindings/net/rockchip-dwmac.txt |  3 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 82 ++
 2 files changed, 85 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt 
b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
index 8f42755..0514f69 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -22,6 +22,7 @@ Required properties:
   < SCLK_MACREF_OUT> clock gate for RMII reference clock output
   < ACLK_GMAC>: AXI clock gate for GMAC
   < PCLK_GMAC>: APB clock gate for GMAC
+  < MAC_PHY>: clock for internal macphy
  - clock-names: One name for each entry in the clocks property.
  - phy-mode: See ethernet.txt file in the same directory.
  - pinctrl-names: Names corresponding to the numbered pinctrl states.
@@ -35,6 +36,8 @@ Required properties:
  - assigned-clocks: main clock, should be < SCLK_MAC>;
  - assigned-clock-parents = parent of main clock.
can be <_gmac> or < SCLK_MAC_PLL>.
+ - phy-type: For internal phy, it must be "internal"; For external phy, no need
+   to configure this.
 
 Optional properties:
  - tx_delay: Delay value for TXD timing. Range value is 0~0x7F, 0x30 as 
default.
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index a8e8fd5..c1a1413 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -41,6 +41,7 @@ struct rk_gmac_ops {
void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
+   void (*internal_phy_powerup)(struct rk_priv_data *bsp_priv);
 };
 
 struct rk_priv_data {
@@ -52,6 +53,7 @@ struct rk_priv_data {
 
bool clk_enabled;
bool clock_input;
+   bool internal_phy;
 
struct clk *clk_mac;
struct clk *gmac_clkin;
@@ -61,6 +63,9 @@ struct rk_priv_data {
struct clk *clk_mac_refout;
struct clk *aclk_mac;
struct clk *pclk_mac;
+   struct clk *clk_macphy;
+
+   struct reset_control *macphy_reset;
 
int tx_delay;
int rx_delay;
@@ -750,6 +755,48 @@ static void rk3399_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
.set_rmii_speed = rk3399_set_rmii_speed,
 };
 
+#define RK_GRF_MACPHY_CON0 0xb00
+#define RK_GRF_MACPHY_CON1 0xb04
+#define RK_GRF_MACPHY_CON2 0xb08
+#define RK_GRF_MACPHY_CON3 0xb0c
+
+#define RK_MACPHY_ENABLE   GRF_BIT(0)
+#define RK_MACPHY_DISABLE  GRF_CLR_BIT(0)
+#define RK_MACPHY_CFG_CLK_50M  GRF_BIT(14)
+#define RK_GMAC2PHY_RMII_MODE  (GRF_BIT(6) | GRF_CLR_BIT(7))
+#define RK_GRF_CON2_MACPHY_ID  HIWORD_UPDATE(0x1234, 0x, 0)
+#define RK_GRF_CON3_MACPHY_ID  HIWORD_UPDATE(0x35, 0x3f, 0)
+
+static void rk_gmac_internal_phy_powerup(struct rk_priv_data *priv)
+{
+   if (priv->ops->internal_phy_powerup)
+   priv->ops->internal_phy_powerup(priv);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
+
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
+
+   /* disable macphy, the default value is enabled */
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->macphy_reset)
+   reset_control_assert(priv->macphy_reset);
+   usleep_range(10, 20);
+   if (priv->macphy_reset)
+   reset_control_deassert(priv->macphy_reset);
+   usleep_range(10, 20);
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
+   msleep(30);
+}
+
+static void rk_gmac_internal_phy_powerdown(struct rk_priv_data *priv)
+{
+   regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+   if (priv->macphy_reset)
+   reset_control_assert(priv->macphy_reset);
+}
+
 static int gmac_clk_init(struct rk_priv_data *bsp_priv)
 {
struct device *dev = _priv->pdev->dev;
@@ -803,6 +850,14 @@ static int gmac_clk_init(struct rk_priv_data *bsp_priv)
clk_set_rate(bsp_priv->clk_mac, 5000);
}
 
+   if (bsp_priv->internal_phy) {
+   bsp_priv->clk_macphy = devm_clk_get(dev, "clk_macphy");
+

[PATCH 04/11] net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()

2017-06-22 Thread David Wu
This is wrong setting for rk3328_set_to_rmii(), so remove it.

Change-Id: I9953784ea44335d90710e5473960c95b3d68a5fd
Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index f0df519..a8e8fd5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -365,9 +365,6 @@ static void rk3328_set_to_rmii(struct rk_priv_data 
*bsp_priv)
regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
 RK3328_GMAC_PHY_INTF_SEL_RMII |
 RK3328_GMAC_RMII_MODE);
-
-   /* set MAC to RMII mode */
-   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, GRF_BIT(11));
 }
 
 static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
-- 
1.9.1




[PATCH 03/11] arm64: defconfig: Enable CONFIG_ROCKCHIP_MAC_PHY

2017-06-22 Thread David Wu
Make the rockchip mac phy driver built into the kernel.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 97c123e..b4abe7f 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -195,6 +195,7 @@ CONFIG_MDIO_BUS_MUX_MMIOREG=y
 CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
 CONFIG_REALTEK_PHY=m
+CONFIG_ROCKCHIP_MAC_PHY=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
-- 
1.9.1




[PATCH 00/11] Add the mac internal ephy support

2017-06-22 Thread David Wu
The rk3228 and rk3328 support internal mac phy inside, let's enable
it to work. And the internal phy need to do some special setting, so
register the rockchip mac internal phy driver, not use the genphy driver. 

David Wu (11):
  net: phy: Add rockchip phy driver support
  multi_v7_defconfig: Make rockchip mac phy built-in
  arm64: defconfig: Enable CONFIG_ROCKCHIP_MAC_PHY
  net: stmmac: dwmac-rk: Remove unwanted code for rk3328_set_to_rmii()
  net: stmmac: dwmac-rk: Add internal phy support
  net: stmmac: dwmac-rk: Add internal phy support for rk3228
  net: stmmac: dwmac-rk: Add internal phy supprot for rk3328
  ARM: dts: rk322x: Add support internal phy for gmac
  ARM: dts: rk3228-evb: Enable the internal phy for gmac
  ARM64: dts: rockchip: Add gmac2phy node support for rk3328
  ARM64: dts: rockchip: Enable gmac2phy for rk3328-evb

 .../devicetree/bindings/net/rockchip-dwmac.txt |   3 +
 arch/arm/boot/dts/rk3228-evb.dts   |  20 
 arch/arm/boot/dts/rk322x.dtsi  |   8 +-
 arch/arm/configs/multi_v7_defconfig|   1 +
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts|  17 +++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   |  25 +
 arch/arm64/configs/defconfig   |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 123 -
 drivers/net/phy/Kconfig|   4 +
 drivers/net/phy/Makefile   |   1 +
 drivers/net/phy/rockchip.c |  94 
 11 files changed, 287 insertions(+), 10 deletions(-)
 create mode 100644 drivers/net/phy/rockchip.c

-- 
1.9.1




[PATCH 02/11] multi_v7_defconfig: Make rockchip mac phy built-in

2017-06-22 Thread David Wu
Enable the rockchip mac phy for multi_v7_defconfig builds

Signed-off-by: David Wu <david...@rock-chips.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index 2685e03..fc1986c 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -267,6 +267,7 @@ CONFIG_ICPLUS_PHY=y
 CONFIG_REALTEK_PHY=y
 CONFIG_MICREL_PHY=y
 CONFIG_FIXED_PHY=y
+CONFIG_ROCKCHIP_MAC_PHY=y
 CONFIG_USB_PEGASUS=y
 CONFIG_USB_RTL8152=m
 CONFIG_USB_USBNET=y
-- 
1.9.1




[PATCH 01/11] net: phy: Add rockchip phy driver support

2017-06-22 Thread David Wu
Support internal ephy currently.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/net/phy/Kconfig|  4 ++
 drivers/net/phy/Makefile   |  1 +
 drivers/net/phy/rockchip.c | 94 ++
 3 files changed, 99 insertions(+)
 create mode 100644 drivers/net/phy/rockchip.c

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index c360dd6..86010d4 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -350,6 +350,10 @@ config XILINX_GMII2RGMII
  the Reduced Gigabit Media Independent Interface(RGMII) between
  Ethernet physical media devices and the Gigabit Ethernet controller.
 
+config ROCKCHIP_MAC_PHY
+   tristate "Drivers for ROCKCHIP MAC PHY"
+   ---help---
+ Currently supports the mac internal ephy.
 endif # PHYLIB
 
 config MICREL_KS8995MA
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index e36db9a..6d96779 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -69,3 +69,4 @@ obj-$(CONFIG_STE10XP) += ste10Xp.o
 obj-$(CONFIG_TERANETICS_PHY)   += teranetics.o
 obj-$(CONFIG_VITESSE_PHY)  += vitesse.o
 obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
+obj-$(CONFIG_ROCKCHIP_MAC_PHY) += rockchip.o
diff --git a/drivers/net/phy/rockchip.c b/drivers/net/phy/rockchip.c
new file mode 100644
index 000..69e96ec
--- /dev/null
+++ b/drivers/net/phy/rockchip.c
@@ -0,0 +1,94 @@
+/**
+ * Rockchip mac phy driver
+ *
+ * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * David Wu<david...@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int internal_config_init(struct phy_device *phydev)
+{
+   int val;
+   u32 features;
+
+   /*enable auto mdix*/
+   phy_write(phydev, 0x11, 0x0080);
+
+   features = (SUPPORTED_TP | SUPPORTED_MII
+   | SUPPORTED_AUI | SUPPORTED_FIBRE |
+   SUPPORTED_BNC);
+
+   /* Do we support autonegotiation? */
+   val = phy_read(phydev, MII_BMSR);
+   if (val < 0)
+   return val;
+
+   if (val & BMSR_ANEGCAPABLE)
+   features |= SUPPORTED_Autoneg;
+
+   if (val & BMSR_100FULL)
+   features |= SUPPORTED_100baseT_Full;
+   if (val & BMSR_100HALF)
+   features |= SUPPORTED_100baseT_Half;
+   if (val & BMSR_10FULL)
+   features |= SUPPORTED_10baseT_Full;
+   if (val & BMSR_10HALF)
+   features |= SUPPORTED_10baseT_Half;
+
+   if (val & BMSR_ESTATEN) {
+   val = phy_read(phydev, MII_ESTATUS);
+   if (val < 0)
+   return val;
+
+   if (val & ESTATUS_1000_TFULL)
+   features |= SUPPORTED_1000baseT_Full;
+   if (val & ESTATUS_1000_THALF)
+   features |= SUPPORTED_1000baseT_Half;
+   }
+
+   phydev->supported = features;
+   phydev->advertising = features;
+
+   return 0;
+}
+
+static struct phy_driver rockchip_phy_driver[] = {
+{
+   .phy_id = 0x1234d400,
+   .phy_id_mask= 0x,
+   .name   = "rockchip internal ephy",
+   .features   = 0,
+   .config_init= internal_config_init,
+   .config_aneg= genphy_config_aneg,
+   .read_status= genphy_read_status,
+   .suspend= genphy_suspend,
+   .resume = genphy_resume,
+},
+};
+
+module_phy_driver(rockchip_phy_driver);
+
+static struct mdio_device_id __maybe_unused rockchip_phy_tbl[] = {
+   { 0x1234d400, 0x },
+   { }
+};
+
+MODULE_DEVICE_TABLE(mdio, rockchip_phy_tbl);
+
+MODULE_AUTHOR("David Wu<david...@rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip mac phy driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1




[PATCH] net: ethernet: stmmac: dwmac-rk: Add RK3328 gmac support

2017-02-17 Thread David Wu
From: "david.wu" 

Add constants and callback functions for the dwmac on rk3328 socs.
As can be seen, the base structure is the same, only registers and the
bits in them moved slightly.

Signed-off-by: david.wu 
---
 .../devicetree/bindings/net/rockchip-dwmac.txt |   1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 117 +
 2 files changed, 118 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt 
b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
index 95383c5..8f42755 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt
@@ -6,6 +6,7 @@ Required properties:
  - compatible: should be "rockchip,-gamc"
"rockchip,rk3228-gmac": found on RK322x SoCs
"rockchip,rk3288-gmac": found on RK3288 SoCs
+   "rockchip,rk3328-gmac": found on RK3328 SoCs
"rockchip,rk3366-gmac": found on RK3366 SoCs
"rockchip,rk3368-gmac": found on RK3368 SoCs
"rockchip,rk3399-gmac": found on RK3399 SoCs
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index fa6e970..e5db6ac 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -302,6 +302,122 @@ static void rk3288_set_rmii_speed(struct rk_priv_data 
*bsp_priv, int speed)
.set_rmii_speed = rk3288_set_rmii_speed,
 };
 
+#define RK3328_GRF_MAC_CON00x0900
+#define RK3328_GRF_MAC_CON10x0904
+
+/* RK3328_GRF_MAC_CON0 */
+#define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
+#define RK3328_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
+
+/* RK3328_GRF_MAC_CON1 */
+#define RK3328_GMAC_PHY_INTF_SEL_RGMII \
+   (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
+#define RK3328_GMAC_PHY_INTF_SEL_RMII  \
+   (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
+#define RK3328_GMAC_FLOW_CTRL  GRF_BIT(3)
+#define RK3328_GMAC_FLOW_CTRL_CLR  GRF_CLR_BIT(3)
+#define RK3328_GMAC_SPEED_10M  GRF_CLR_BIT(2)
+#define RK3328_GMAC_SPEED_100M GRF_BIT(2)
+#define RK3328_GMAC_RMII_CLK_25M   GRF_BIT(7)
+#define RK3328_GMAC_RMII_CLK_2_5M  GRF_CLR_BIT(7)
+#define RK3328_GMAC_CLK_125M   (GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
+#define RK3328_GMAC_CLK_25M(GRF_BIT(11) | GRF_BIT(12))
+#define RK3328_GMAC_CLK_2_5M   (GRF_CLR_BIT(11) | GRF_BIT(12))
+#define RK3328_GMAC_RMII_MODE  GRF_BIT(9)
+#define RK3328_GMAC_RMII_MODE_CLR  GRF_CLR_BIT(9)
+#define RK3328_GMAC_TXCLK_DLY_ENABLE   GRF_BIT(0)
+#define RK3328_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(0)
+#define RK3328_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(1)
+#define RK3328_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(0)
+
+static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
+   int tx_delay, int rx_delay)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   if (IS_ERR(bsp_priv->grf)) {
+   dev_err(dev, "Missing rockchip,grf property\n");
+   return;
+   }
+
+   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+RK3328_GMAC_PHY_INTF_SEL_RGMII |
+RK3328_GMAC_RMII_MODE_CLR |
+RK3328_GMAC_RXCLK_DLY_ENABLE |
+RK3328_GMAC_TXCLK_DLY_ENABLE);
+
+   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
+RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
+RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
+}
+
+static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   if (IS_ERR(bsp_priv->grf)) {
+   dev_err(dev, "Missing rockchip,grf property\n");
+   return;
+   }
+
+   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+RK3328_GMAC_PHY_INTF_SEL_RMII |
+RK3328_GMAC_RMII_MODE);
+
+   /* set MAC to RMII mode */
+   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, GRF_BIT(11));
+}
+
+static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+   struct device *dev = _priv->pdev->dev;
+
+   if (IS_ERR(bsp_priv->grf)) {
+   dev_err(dev, "Missing rockchip,grf property\n");
+   return;
+   }
+
+   if (speed == 10)
+   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+RK3328_GMAC_CLK_2_5M);
+   else if (speed == 100)
+   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+RK3328_GMAC_CLK_25M);
+   else if (speed == 1000)
+   regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
+RK3328_GMAC_CLK_125M);
+   else
+   dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
+}
+
+static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int