[PATCH] net: stmmac: Fixed mtu channged by cache aligned

2021-01-12 Thread David Wu
Since the original mtu is not used when the mtu is updated,
the mtu is aligned with cache, this will get an incorrect.
For example, if you want to configure the mtu to be 1500,
but mtu 1536 is configured in fact.

Fixed: eaf4fac478077 ("net: stmmac: Do not accept invalid MTU values")
Signed-off-by: David Wu 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 5b1c12ff98c0..e8640123db76 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4025,7 +4025,7 @@ static void stmmac_set_rx_mode(struct net_device *dev)
 static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
 {
struct stmmac_priv *priv = netdev_priv(dev);
-   int txfifosz = priv->plat->tx_fifo_size;
+   int txfifosz = priv->plat->tx_fifo_size, mtu = new_mtu;
 
if (txfifosz == 0)
txfifosz = priv->dma_cap.tx_fifo_size;
@@ -4043,7 +4043,7 @@ static int stmmac_change_mtu(struct net_device *dev, int 
new_mtu)
if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB))
return -EINVAL;
 
-   dev->mtu = new_mtu;
+   dev->mtu = mtu;
 
netdev_update_features(dev);
 
-- 
2.19.1





Re: [PATCH] pwm: rockchip: simplify rockchip_pwm_get_state()

2020-06-02 Thread David Wu
This change is very good, thank you. The code continues from the 
original code(get_state_v1 and get_state_v2), didn’t make any changes at 
that time, and sorry I have not seen linux-rockc...@lists.infradead.org 
mail recently.


在 2020/6/2 下午8:39, Thierry Reding 写道:

On Thu, Sep 19, 2019 at 11:17:27AM +0200, Rasmus Villemoes wrote:

The way state->enabled is computed is rather convoluted and hard to
read - both branches of the if() actually do the exact same thing. So
remove the if(), and further simplify " ? true :
false" to "".

Signed-off-by: Rasmus Villemoes 
---
I stumbled on this while trying to understand how the pwm subsystem
works. This patch is a semantic no-op, but it's also possible that,
say, the first branch simply contains a "double negative" so either
the != should be == or the "false : true" should be "true : false".

  drivers/pwm/pwm-rockchip.c | 7 +--
  1 file changed, 1 insertion(+), 6 deletions(-)


I've applied this. Irrespective of any feedback David would have this is
correct and a nice simplification.

Thierry






Re: [PATCH 1/2] pinctrl: rockchip: allow specifying the regmap location for pin-routes

2018-11-14 Thread David Wu

Hi Heiko,

在 2018/11/12 上午5:00, Heiko Stuebner 写道:

From: Heiko Stuebner

Right now we expect the pin-rounting settings to be in the same area
as the iomux setting itself. And while that seems to be true for all
newer Rockchip socs, back in the wild west days of old this wasn't true.

Nowadays pin settings in the GRF normally stay in the GRF and the same
is true for pins configured from PMU registers. But old socs like the
rk3188 really sprinkle pin settings somewhat randomly through both
for its bank0.

Therefore add the option to specify a location for the route setting,
so that we can map older socs correctly. We'll keep "same" as the
default, so that we only need to specify a location in the corner-cases
described above.

Signed-off-by: Heiko Stuebner


Very good, for the mixed case, really need to do the supplement.

Reviewed-by: David Wu 



Re: [PATCH 1/2] pinctrl: rockchip: allow specifying the regmap location for pin-routes

2018-11-14 Thread David Wu

Hi Heiko,

在 2018/11/12 上午5:00, Heiko Stuebner 写道:

From: Heiko Stuebner

Right now we expect the pin-rounting settings to be in the same area
as the iomux setting itself. And while that seems to be true for all
newer Rockchip socs, back in the wild west days of old this wasn't true.

Nowadays pin settings in the GRF normally stay in the GRF and the same
is true for pins configured from PMU registers. But old socs like the
rk3188 really sprinkle pin settings somewhat randomly through both
for its bank0.

Therefore add the option to specify a location for the route setting,
so that we can map older socs correctly. We'll keep "same" as the
default, so that we only need to specify a location in the corner-cases
described above.

Signed-off-by: Heiko Stuebner


Very good, for the mixed case, really need to do the supplement.

Reviewed-by: David Wu 



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

2018-06-26 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 are moved slightly, and add the clk_mac_speed for selecting
mac speed.

Signed-off-by: David Wu 
---
Change in v3:
- Add the clock enable/disable for clk_mac_speed.

Change in v2:
- Fix some error in commit title and message.

 .../devicetree/bindings/net/rockchip-dwmac.txt |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 71 ++
 2 files changed, 72 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..fc5fef7 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 {
@@ -1094,6 +1157,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, 
bool enable)
if (!IS_ERR(bsp_priv->mac_clk_tx))
clk_prepare_enable(bsp_priv->mac_clk_tx);
 
+   if (!IS_ERR(bsp_priv->clk_mac_speed))
+   clk_prepare_enable(bsp_priv->clk_mac_speed);
+
/**
 * if

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

2018-06-26 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 are moved slightly, and add the clk_mac_speed for selecting
mac speed.

Signed-off-by: David Wu 
---
Change in v3:
- Add the clock enable/disable for clk_mac_speed.

Change in v2:
- Fix some error in commit title and message.

 .../devicetree/bindings/net/rockchip-dwmac.txt |  1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 71 ++
 2 files changed, 72 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..fc5fef7 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 {
@@ -1094,6 +1157,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, 
bool enable)
if (!IS_ERR(bsp_priv->mac_clk_tx))
clk_prepare_enable(bsp_priv->mac_clk_tx);
 
+   if (!IS_ERR(bsp_priv->clk_mac_speed))
+   clk_prepare_enable(bsp_priv->clk_mac_speed);
+
/**
 * if

Re: [PATCH v2] net: ethernet: stmmac: dwmac-rk: Add GMAC support for PX30

2018-06-22 Thread David Wu

Hi Heiko,

在 2018年06月22日 15:30, Heiko Stuebner 写道:

Hi David,

Am Mittwoch, 20. Juni 2018, 04:40:35 CEST schrieb David Wu:

在 2018年06月14日 16:30, Heiko Stübner 写道:

Am Donnerstag, 14. Juni 2018, 10:14:31 CEST schrieb David Wu:

Hi Heiko,

在 2018年06月14日 15:54, Heiko Stübner 写道:

I don't see that new clock documented in the dt-binding.
Also, which clock from the clock-controller does this connect to?


The clock is the "SCLK_GMAC_RMII" at the clock-controller, which could
be set rate by the link speed.


Hmm, while these huge number of clocks are somewhat strange,
shouldn't it be named something with _rmii instead of _speed then?


Okay, it is better to be named _speed.



Also, I don't see any clk_enable action for that new clock, so you could
end up with being off?


The new speed is the parent of the clk_tx_rx, to enable/disable
clk_tx_rx, the new clock would be also enabled/disabled.


Still it is nicer to really enable it, so that the clock-framework can keep
track of usage counts.

Because also no-one hinders the chip-designer from putting a gate in
between in one of the next socs ;-)



Okay, i will add the enable/disable for clk_mac_speed.
 ;-)



Heiko









Re: [PATCH v2] net: ethernet: stmmac: dwmac-rk: Add GMAC support for PX30

2018-06-22 Thread David Wu

Hi Heiko,

在 2018年06月22日 15:30, Heiko Stuebner 写道:

Hi David,

Am Mittwoch, 20. Juni 2018, 04:40:35 CEST schrieb David Wu:

在 2018年06月14日 16:30, Heiko Stübner 写道:

Am Donnerstag, 14. Juni 2018, 10:14:31 CEST schrieb David Wu:

Hi Heiko,

在 2018年06月14日 15:54, Heiko Stübner 写道:

I don't see that new clock documented in the dt-binding.
Also, which clock from the clock-controller does this connect to?


The clock is the "SCLK_GMAC_RMII" at the clock-controller, which could
be set rate by the link speed.


Hmm, while these huge number of clocks are somewhat strange,
shouldn't it be named something with _rmii instead of _speed then?


Okay, it is better to be named _speed.



Also, I don't see any clk_enable action for that new clock, so you could
end up with being off?


The new speed is the parent of the clk_tx_rx, to enable/disable
clk_tx_rx, the new clock would be also enabled/disabled.


Still it is nicer to really enable it, so that the clock-framework can keep
track of usage counts.

Because also no-one hinders the chip-designer from putting a gate in
between in one of the next socs ;-)



Okay, i will add the enable/disable for clk_mac_speed.
 ;-)



Heiko









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 },









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] 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 
---
 .../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 v2] PM / AVS: rockchip-io: add io selectors and supplies for PX30

2018-05-15 Thread David Wu
This adds the necessary data for handling io voltage domains on PX30.
As interesting tidbit, the PX30 contains two separate iodomain areas.
One in the regular General Register Files (GRF) and one in PMUGRF in the
pmu power domain.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 .../bindings/power/rockchip-io-domain.txt  | 15 +
 drivers/power/avs/rockchip-io-domain.c | 68 ++
 2 files changed, 83 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt 
b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
index 4a4766e..e66fd4e 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
@@ -31,6 +31,8 @@ SoC is on the same page.
 
 Required properties:
 - compatible: should be one of:
+  - "rockchip,px30-io-voltage-domain" for px30
+  - "rockchip,px30-pmu-io-voltage-domain" for px30 pmu-domains
   - "rockchip,rk3188-io-voltage-domain" for rk3188
   - "rockchip,rk3228-io-voltage-domain" for rk3228
   - "rockchip,rk3288-io-voltage-domain" for rk3288
@@ -51,6 +53,19 @@ a phandle the relevant regulator.  All specified supplies 
must be able
 to report their voltage.  The IO Voltage Domain for any non-specified
 supplies will be not be touched.
 
+Possible supplies for PX30:
+- vccio6-supply: The supply connected to VCCIO6.
+- vccio1-supply: The supply connected to VCCIO1.
+- vccio2-supply: The supply connected to VCCIO2.
+- vccio3-supply: The supply connected to VCCIO3.
+- vccio4-supply: The supply connected to VCCIO4.
+- vccio5-supply: The supply connected to VCCIO5.
+- vccio-oscgpi-supply: The supply connected to VCCIO_OSCGPI.
+
+Possible supplies for PX30 pmu-domains:
+- pmuio1-supply: The supply connected to PMUIO1.
+- pmuio2-supply: The supply connected to PMUIO2.
+
 Possible supplies for rk3188:
 - ap0-supply:The supply connected to AP0_VCC.
 - ap1-supply:The supply connected to AP1_VCC.
diff --git a/drivers/power/avs/rockchip-io-domain.c 
b/drivers/power/avs/rockchip-io-domain.c
index ed2b109..d6a5e6b 100644
--- a/drivers/power/avs/rockchip-io-domain.c
+++ b/drivers/power/avs/rockchip-io-domain.c
@@ -39,6 +39,10 @@
 #define MAX_VOLTAGE_1_8198
 #define MAX_VOLTAGE_3_3360
 
+#define PX30_IO_VSEL   0x180
+#define PX30_IO_VSEL_VCCIO6_SRCBIT(0)
+#define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1
+
 #define RK3288_SOC_CON20x24c
 #define RK3288_SOC_CON2_FLASH0 BIT(7)
 #define RK3288_SOC_FLASH_SUPPLY_NUM2
@@ -151,6 +155,25 @@ static int rockchip_iodomain_notify(struct notifier_block 
*nb,
return NOTIFY_OK;
 }
 
+static void px30_iodomain_init(struct rockchip_iodomain *iod)
+{
+   int ret;
+   u32 val;
+
+   /* if no VCCIO0 supply we should leave things alone */
+   if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg)
+   return;
+
+   /*
+* set vccio0 iodomain to also use this framework
+* instead of a special gpio.
+*/
+   val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16);
+   ret = regmap_write(iod->grf, PX30_IO_VSEL, val);
+   if (ret < 0)
+   dev_warn(iod->dev, "couldn't update vccio0 ctrl\n");
+}
+
 static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
 {
int ret;
@@ -227,6 +250,43 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n");
 }
 
+static const struct rockchip_iodomain_soc_data soc_data_px30 = {
+   .grf_offset = 0x180,
+   .supply_names = {
+   NULL,
+   "vccio6",
+   "vccio1",
+   "vccio2",
+   "vccio3",
+   "vccio4",
+   "vccio5",
+   "vccio-oscgpi",
+   },
+   .init = px30_iodomain_init,
+};
+
+static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = {
+   .grf_offset = 0x100,
+   .supply_names = {
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   "pmuio1",
+   "pmuio2",
+   },
+};
+
 /*
  * On the rk3188 the io-domains are handled by a shared register with the
  * lower 8 bits being still being continuing drive-strength settings.
@@ -381,6 +441,14 @@ static const struct rockchip_iodomain_soc_data 
soc_data_rv1108_pmu = {
 
 static const struct of_device_id rockchip_iodomain_match[] = {
{
+

[PATCH v2] PM / AVS: rockchip-io: add io selectors and supplies for PX30

2018-05-15 Thread David Wu
This adds the necessary data for handling io voltage domains on PX30.
As interesting tidbit, the PX30 contains two separate iodomain areas.
One in the regular General Register Files (GRF) and one in PMUGRF in the
pmu power domain.

Signed-off-by: David Wu 
---
 .../bindings/power/rockchip-io-domain.txt  | 15 +
 drivers/power/avs/rockchip-io-domain.c | 68 ++
 2 files changed, 83 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt 
b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
index 4a4766e..e66fd4e 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
@@ -31,6 +31,8 @@ SoC is on the same page.
 
 Required properties:
 - compatible: should be one of:
+  - "rockchip,px30-io-voltage-domain" for px30
+  - "rockchip,px30-pmu-io-voltage-domain" for px30 pmu-domains
   - "rockchip,rk3188-io-voltage-domain" for rk3188
   - "rockchip,rk3228-io-voltage-domain" for rk3228
   - "rockchip,rk3288-io-voltage-domain" for rk3288
@@ -51,6 +53,19 @@ a phandle the relevant regulator.  All specified supplies 
must be able
 to report their voltage.  The IO Voltage Domain for any non-specified
 supplies will be not be touched.
 
+Possible supplies for PX30:
+- vccio6-supply: The supply connected to VCCIO6.
+- vccio1-supply: The supply connected to VCCIO1.
+- vccio2-supply: The supply connected to VCCIO2.
+- vccio3-supply: The supply connected to VCCIO3.
+- vccio4-supply: The supply connected to VCCIO4.
+- vccio5-supply: The supply connected to VCCIO5.
+- vccio-oscgpi-supply: The supply connected to VCCIO_OSCGPI.
+
+Possible supplies for PX30 pmu-domains:
+- pmuio1-supply: The supply connected to PMUIO1.
+- pmuio2-supply: The supply connected to PMUIO2.
+
 Possible supplies for rk3188:
 - ap0-supply:The supply connected to AP0_VCC.
 - ap1-supply:The supply connected to AP1_VCC.
diff --git a/drivers/power/avs/rockchip-io-domain.c 
b/drivers/power/avs/rockchip-io-domain.c
index ed2b109..d6a5e6b 100644
--- a/drivers/power/avs/rockchip-io-domain.c
+++ b/drivers/power/avs/rockchip-io-domain.c
@@ -39,6 +39,10 @@
 #define MAX_VOLTAGE_1_8198
 #define MAX_VOLTAGE_3_3360
 
+#define PX30_IO_VSEL   0x180
+#define PX30_IO_VSEL_VCCIO6_SRCBIT(0)
+#define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1
+
 #define RK3288_SOC_CON20x24c
 #define RK3288_SOC_CON2_FLASH0 BIT(7)
 #define RK3288_SOC_FLASH_SUPPLY_NUM2
@@ -151,6 +155,25 @@ static int rockchip_iodomain_notify(struct notifier_block 
*nb,
return NOTIFY_OK;
 }
 
+static void px30_iodomain_init(struct rockchip_iodomain *iod)
+{
+   int ret;
+   u32 val;
+
+   /* if no VCCIO0 supply we should leave things alone */
+   if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg)
+   return;
+
+   /*
+* set vccio0 iodomain to also use this framework
+* instead of a special gpio.
+*/
+   val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16);
+   ret = regmap_write(iod->grf, PX30_IO_VSEL, val);
+   if (ret < 0)
+   dev_warn(iod->dev, "couldn't update vccio0 ctrl\n");
+}
+
 static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
 {
int ret;
@@ -227,6 +250,43 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n");
 }
 
+static const struct rockchip_iodomain_soc_data soc_data_px30 = {
+   .grf_offset = 0x180,
+   .supply_names = {
+   NULL,
+   "vccio6",
+   "vccio1",
+   "vccio2",
+   "vccio3",
+   "vccio4",
+   "vccio5",
+   "vccio-oscgpi",
+   },
+   .init = px30_iodomain_init,
+};
+
+static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = {
+   .grf_offset = 0x100,
+   .supply_names = {
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   "pmuio1",
+   "pmuio2",
+   },
+};
+
 /*
  * On the rk3188 the io-domains are handled by a shared register with the
  * lower 8 bits being still being continuing drive-strength settings.
@@ -381,6 +441,14 @@ static const struct rockchip_iodomain_soc_data 
soc_data_rv1108_pmu = {
 
 static const struct of_device_id rockchip_iodomain_match[] = {
{
+ 

[PATCH] PM / AVS: rockchip-io: add io selectors and supplies for PX30

2018-05-15 Thread David Wu
This adds the necessary data for handling io voltage domains on PX30.
As interesting tidbit, the PX30 contains two separate iodomain areas.
One in the regular General Register Files (GRF) and one in PMUGRF in the
pmu power domain.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 .../bindings/power/rockchip-io-domain.txt  |  2 +
 drivers/power/avs/rockchip-io-domain.c | 68 ++
 2 files changed, 70 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt 
b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
index 4a4766e..c2595ba 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
@@ -31,6 +31,8 @@ SoC is on the same page.
 
 Required properties:
 - compatible: should be one of:
+  - "rockchip,px30-io-voltage-domain" for px30
+  - "rockchip,px30-pmu-io-voltage-domain" for px30 pmu-domains
   - "rockchip,rk3188-io-voltage-domain" for rk3188
   - "rockchip,rk3228-io-voltage-domain" for rk3228
   - "rockchip,rk3288-io-voltage-domain" for rk3288
diff --git a/drivers/power/avs/rockchip-io-domain.c 
b/drivers/power/avs/rockchip-io-domain.c
index ed2b109..41c2b83 100644
--- a/drivers/power/avs/rockchip-io-domain.c
+++ b/drivers/power/avs/rockchip-io-domain.c
@@ -39,6 +39,10 @@
 #define MAX_VOLTAGE_1_8198
 #define MAX_VOLTAGE_3_3360
 
+#define PX30_IO_VSEL   0x180
+#define PX30_IO_VSEL_VCCIO6_SRCBIT(0)
+#define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1
+
 #define RK3288_SOC_CON20x24c
 #define RK3288_SOC_CON2_FLASH0 BIT(7)
 #define RK3288_SOC_FLASH_SUPPLY_NUM2
@@ -151,6 +155,25 @@ static int rockchip_iodomain_notify(struct notifier_block 
*nb,
return NOTIFY_OK;
 }
 
+static void px30_iodomain_init(struct rockchip_iodomain *iod)
+{
+   int ret;
+   u32 val;
+
+   /* if no VCCIO0 supply we should leave things alone */
+   if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg)
+   return;
+
+   /*
+* set vccio0 iodomain to also use this framework
+* instead of a special gpio.
+*/
+   val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16);
+   ret = regmap_write(iod->grf, PX30_IO_VSEL, val);
+   if (ret < 0)
+   dev_warn(iod->dev, "couldn't update vccio0 ctrl\n");
+}
+
 static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
 {
int ret;
@@ -227,6 +250,43 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n");
 }
 
+static const struct rockchip_iodomain_soc_data soc_data_px30 = {
+   .grf_offset = 0x180,
+   .supply_names = {
+   NULL,
+   "vccio6",
+   "vccio1",
+   "vccio2",
+   "vccio3",
+   "vccio4",
+   "vccio5",
+   "vccio_oscgpi",
+   },
+   .init = px30_iodomain_init,
+};
+
+static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = {
+   .grf_offset = 0x100,
+   .supply_names = {
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   "pmuio1",
+   "pmuio2",
+   },
+};
+
 /*
  * On the rk3188 the io-domains are handled by a shared register with the
  * lower 8 bits being still being continuing drive-strength settings.
@@ -381,6 +441,14 @@ static const struct rockchip_iodomain_soc_data 
soc_data_rv1108_pmu = {
 
 static const struct of_device_id rockchip_iodomain_match[] = {
{
+   .compatible = "rockchip,px30-io-voltage-domain",
+   .data = (void *)_data_px30
+   },
+   {
+   .compatible = "rockchip,px30-pmu-io-voltage-domain",
+   .data = (void *)_data_px30_pmu
+   },
+   {
.compatible = "rockchip,rk3188-io-voltage-domain",
.data = _data_rk3188
},
-- 
2.7.4




[PATCH] PM / AVS: rockchip-io: add io selectors and supplies for PX30

2018-05-15 Thread David Wu
This adds the necessary data for handling io voltage domains on PX30.
As interesting tidbit, the PX30 contains two separate iodomain areas.
One in the regular General Register Files (GRF) and one in PMUGRF in the
pmu power domain.

Signed-off-by: David Wu 
---
 .../bindings/power/rockchip-io-domain.txt  |  2 +
 drivers/power/avs/rockchip-io-domain.c | 68 ++
 2 files changed, 70 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt 
b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
index 4a4766e..c2595ba 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
@@ -31,6 +31,8 @@ SoC is on the same page.
 
 Required properties:
 - compatible: should be one of:
+  - "rockchip,px30-io-voltage-domain" for px30
+  - "rockchip,px30-pmu-io-voltage-domain" for px30 pmu-domains
   - "rockchip,rk3188-io-voltage-domain" for rk3188
   - "rockchip,rk3228-io-voltage-domain" for rk3228
   - "rockchip,rk3288-io-voltage-domain" for rk3288
diff --git a/drivers/power/avs/rockchip-io-domain.c 
b/drivers/power/avs/rockchip-io-domain.c
index ed2b109..41c2b83 100644
--- a/drivers/power/avs/rockchip-io-domain.c
+++ b/drivers/power/avs/rockchip-io-domain.c
@@ -39,6 +39,10 @@
 #define MAX_VOLTAGE_1_8198
 #define MAX_VOLTAGE_3_3360
 
+#define PX30_IO_VSEL   0x180
+#define PX30_IO_VSEL_VCCIO6_SRCBIT(0)
+#define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1
+
 #define RK3288_SOC_CON20x24c
 #define RK3288_SOC_CON2_FLASH0 BIT(7)
 #define RK3288_SOC_FLASH_SUPPLY_NUM2
@@ -151,6 +155,25 @@ static int rockchip_iodomain_notify(struct notifier_block 
*nb,
return NOTIFY_OK;
 }
 
+static void px30_iodomain_init(struct rockchip_iodomain *iod)
+{
+   int ret;
+   u32 val;
+
+   /* if no VCCIO0 supply we should leave things alone */
+   if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg)
+   return;
+
+   /*
+* set vccio0 iodomain to also use this framework
+* instead of a special gpio.
+*/
+   val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16);
+   ret = regmap_write(iod->grf, PX30_IO_VSEL, val);
+   if (ret < 0)
+   dev_warn(iod->dev, "couldn't update vccio0 ctrl\n");
+}
+
 static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
 {
int ret;
@@ -227,6 +250,43 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n");
 }
 
+static const struct rockchip_iodomain_soc_data soc_data_px30 = {
+   .grf_offset = 0x180,
+   .supply_names = {
+   NULL,
+   "vccio6",
+   "vccio1",
+   "vccio2",
+   "vccio3",
+   "vccio4",
+   "vccio5",
+   "vccio_oscgpi",
+   },
+   .init = px30_iodomain_init,
+};
+
+static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = {
+   .grf_offset = 0x100,
+   .supply_names = {
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   "pmuio1",
+   "pmuio2",
+   },
+};
+
 /*
  * On the rk3188 the io-domains are handled by a shared register with the
  * lower 8 bits being still being continuing drive-strength settings.
@@ -381,6 +441,14 @@ static const struct rockchip_iodomain_soc_data 
soc_data_rv1108_pmu = {
 
 static const struct of_device_id rockchip_iodomain_match[] = {
{
+   .compatible = "rockchip,px30-io-voltage-domain",
+   .data = (void *)_data_px30
+   },
+   {
+   .compatible = "rockchip,px30-pmu-io-voltage-domain",
+   .data = (void *)_data_px30_pmu
+   },
+   {
.compatible = "rockchip,rk3188-io-voltage-domain",
.data = _data_rk3188
},
-- 
2.7.4




[PATCH] pinctrl: rockchip: Add pinctrl support for PX30

2018-05-14 Thread David Wu
There are 4 banks (GPIO0 ~ GPIO3), bank0 is in PD_PMU
subsystem, bank1/bank2/bank3 are in PD_BUS subsystem.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 .../bindings/pinctrl/rockchip,pinctrl.txt  |   1 +
 drivers/pinctrl/pinctrl-rockchip.c | 194 +
 2 files changed, 195 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
index a01a3b8..0919db2 100644
--- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
@@ -20,6 +20,7 @@ defined as gpio sub-nodes of the pinmux controller.
 
 Required properties for iomux controller:
   - compatible: should be
+   "rockchip,px30-pinctrl":for Rockchip PX30
"rockchip,rv1108-pinctrl":  for Rockchip RV1108
"rockchip,rk2928-pinctrl":  for Rockchip RK2928
"rockchip,rk3066a-pinctrl": for Rockchip RK3066a
diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index 3924779..88d4077 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -59,6 +59,7 @@
 #define GPIO_LS_SYNC   0x60
 
 enum rockchip_pinctrl_type {
+   PX30,
RV1108,
RK2928,
RK3066B,
@@ -701,6 +702,66 @@ static void rockchip_get_recalced_mux(struct 
rockchip_pin_bank *bank, int pin,
*bit = data->bit;
 }
 
+static struct rockchip_mux_route_data px30_mux_route_data[] = {
+   {
+   /* cif-d2m0 */
+   .bank_num = 2,
+   .pin = 0,
+   .func = 1,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 7),
+   }, {
+   /* cif-d2m1 */
+   .bank_num = 3,
+   .pin = 3,
+   .func = 3,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 7) | BIT(7),
+   }, {
+   /* pdm-m0 */
+   .bank_num = 3,
+   .pin = 22,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 8),
+   }, {
+   /* pdm-m1 */
+   .bank_num = 2,
+   .pin = 22,
+   .func = 1,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 8) | BIT(8),
+   }, {
+   /* uart2-rxm0 */
+   .bank_num = 1,
+   .pin = 27,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 10),
+   }, {
+   /* uart2-rxm1 */
+   .bank_num = 2,
+   .pin = 14,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 10) | BIT(10),
+   }, {
+   /* uart3-rxm0 */
+   .bank_num = 0,
+   .pin = 17,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 9),
+   }, {
+   /* uart3-rxm1 */
+   .bank_num = 1,
+   .pin = 15,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 9) | BIT(9),
+   },
+};
+
 static struct rockchip_mux_route_data rk3128_mux_route_data[] = {
{
/* spi-0 */
@@ -1202,6 +1263,97 @@ static int rockchip_set_mux(struct rockchip_pin_bank 
*bank, int pin, int mux)
return ret;
 }
 
+#define PX30_PULL_PMU_OFFSET   0x10
+#define PX30_PULL_GRF_OFFSET   0x60
+#define PX30_PULL_BITS_PER_PIN 2
+#define PX30_PULL_PINS_PER_REG 8
+#define PX30_PULL_BANK_STRIDE  16
+
+static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+  int pin_num, struct regmap **regmap,
+  int *reg, u8 *bit)
+{
+   struct rockchip_pinctrl *info = bank->drvdata;
+
+   /* The first 32 pins of the first bank are located in PMU */
+   if (bank->bank_num == 0) {
+   *regmap = info->regmap_pmu;
+   *reg = PX30_PULL_PMU_OFFSET;
+   } else {
+   *regmap = info->regmap_base;
+   *reg = PX30_PULL_GRF_OFFSET;
+
+   /* correct the offset, as we're starting with the 2nd bank */
+   *reg -= 0x10;
+   *reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
+   }
+
+   *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
+   *bit = (pin_num % PX30_PULL_PINS_PER_REG);
+   *bit *= PX30_PULL_BITS_PER_PIN;
+}
+
+#define PX30_DRV_PMU_OFFSET0x20
+#define PX30_DRV_GRF_OFFSET0xf0
+#define PX30_DRV_BITS_PER_PIN  2
+#define PX30_DRV_PINS_PER_REG  8
+#define PX30_DRV_BANK_STRIDE   16
+
+stat

[PATCH] pinctrl: rockchip: Add pinctrl support for PX30

2018-05-14 Thread David Wu
There are 4 banks (GPIO0 ~ GPIO3), bank0 is in PD_PMU
subsystem, bank1/bank2/bank3 are in PD_BUS subsystem.

Signed-off-by: David Wu 
---
 .../bindings/pinctrl/rockchip,pinctrl.txt  |   1 +
 drivers/pinctrl/pinctrl-rockchip.c | 194 +
 2 files changed, 195 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
index a01a3b8..0919db2 100644
--- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt
@@ -20,6 +20,7 @@ defined as gpio sub-nodes of the pinmux controller.
 
 Required properties for iomux controller:
   - compatible: should be
+   "rockchip,px30-pinctrl":for Rockchip PX30
"rockchip,rv1108-pinctrl":  for Rockchip RV1108
"rockchip,rk2928-pinctrl":  for Rockchip RK2928
"rockchip,rk3066a-pinctrl": for Rockchip RK3066a
diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index 3924779..88d4077 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -59,6 +59,7 @@
 #define GPIO_LS_SYNC   0x60
 
 enum rockchip_pinctrl_type {
+   PX30,
RV1108,
RK2928,
RK3066B,
@@ -701,6 +702,66 @@ static void rockchip_get_recalced_mux(struct 
rockchip_pin_bank *bank, int pin,
*bit = data->bit;
 }
 
+static struct rockchip_mux_route_data px30_mux_route_data[] = {
+   {
+   /* cif-d2m0 */
+   .bank_num = 2,
+   .pin = 0,
+   .func = 1,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 7),
+   }, {
+   /* cif-d2m1 */
+   .bank_num = 3,
+   .pin = 3,
+   .func = 3,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 7) | BIT(7),
+   }, {
+   /* pdm-m0 */
+   .bank_num = 3,
+   .pin = 22,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 8),
+   }, {
+   /* pdm-m1 */
+   .bank_num = 2,
+   .pin = 22,
+   .func = 1,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 8) | BIT(8),
+   }, {
+   /* uart2-rxm0 */
+   .bank_num = 1,
+   .pin = 27,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 10),
+   }, {
+   /* uart2-rxm1 */
+   .bank_num = 2,
+   .pin = 14,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 10) | BIT(10),
+   }, {
+   /* uart3-rxm0 */
+   .bank_num = 0,
+   .pin = 17,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 9),
+   }, {
+   /* uart3-rxm1 */
+   .bank_num = 1,
+   .pin = 15,
+   .func = 2,
+   .route_offset = 0x184,
+   .route_val = BIT(16 + 9) | BIT(9),
+   },
+};
+
 static struct rockchip_mux_route_data rk3128_mux_route_data[] = {
{
/* spi-0 */
@@ -1202,6 +1263,97 @@ static int rockchip_set_mux(struct rockchip_pin_bank 
*bank, int pin, int mux)
return ret;
 }
 
+#define PX30_PULL_PMU_OFFSET   0x10
+#define PX30_PULL_GRF_OFFSET   0x60
+#define PX30_PULL_BITS_PER_PIN 2
+#define PX30_PULL_PINS_PER_REG 8
+#define PX30_PULL_BANK_STRIDE  16
+
+static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+  int pin_num, struct regmap **regmap,
+  int *reg, u8 *bit)
+{
+   struct rockchip_pinctrl *info = bank->drvdata;
+
+   /* The first 32 pins of the first bank are located in PMU */
+   if (bank->bank_num == 0) {
+   *regmap = info->regmap_pmu;
+   *reg = PX30_PULL_PMU_OFFSET;
+   } else {
+   *regmap = info->regmap_base;
+   *reg = PX30_PULL_GRF_OFFSET;
+
+   /* correct the offset, as we're starting with the 2nd bank */
+   *reg -= 0x10;
+   *reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
+   }
+
+   *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
+   *bit = (pin_num % PX30_PULL_PINS_PER_REG);
+   *bit *= PX30_PULL_BITS_PER_PIN;
+}
+
+#define PX30_DRV_PMU_OFFSET0x20
+#define PX30_DRV_GRF_OFFSET0xf0
+#define PX30_DRV_BITS_PER_PIN  2
+#define PX30_DRV_PINS_PER_REG  8
+#define PX30_DRV_BANK_STRIDE   16
+
+static void px30_calc_drv_reg_and_bit(struct rockchip_pin_ban

[PATCH 2/2] pinctrl: rockchip: Fix the correct routing config for the gmac-m1 pins of rmii and rgmii

2017-09-30 Thread David Wu
If the gmac-m1 optimization(bit10) is selected, the gpio function
of gmac pins is not valid. We may use the rmii mode for gmac interface,
the pins such as rx_d2, rx_d3, which the rgmii mode used, but rmii not
used could be taken as gpio function. So gmac_rxd0m1 selects the bit2,
and gmac_rxd0m3 select bit10 is more correct.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index c7c9beb..9e0cabf 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -900,12 +900,19 @@ static void rockchip_get_recalced_mux(struct 
rockchip_pin_bank *bank, int pin,
.route_offset = 0x50,
.route_val = BIT(16) | BIT(16 + 1) | BIT(0),
}, {
-   /* gmac-m1-optimized_rxd0 */
+   /* gmac-m1_rxd0 */
.bank_num = 1,
.pin = 11,
.func = 2,
.route_offset = 0x50,
-   .route_val = BIT(16 + 2) | BIT(16 + 10) | BIT(2) | BIT(10),
+   .route_val = BIT(16 + 2) | BIT(2),
+   }, {
+   /* gmac-m1-optimized_rxd3 */
+   .bank_num = 1,
+   .pin = 14,
+   .func = 2,
+   .route_offset = 0x50,
+   .route_val = BIT(16 + 10) | BIT(10),
}, {
/* pdm_sdi0m0 */
.bank_num = 2,
-- 
1.9.1




[PATCH 2/2] pinctrl: rockchip: Fix the correct routing config for the gmac-m1 pins of rmii and rgmii

2017-09-30 Thread David Wu
If the gmac-m1 optimization(bit10) is selected, the gpio function
of gmac pins is not valid. We may use the rmii mode for gmac interface,
the pins such as rx_d2, rx_d3, which the rgmii mode used, but rmii not
used could be taken as gpio function. So gmac_rxd0m1 selects the bit2,
and gmac_rxd0m3 select bit10 is more correct.

Signed-off-by: David Wu 
---
 drivers/pinctrl/pinctrl-rockchip.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index c7c9beb..9e0cabf 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -900,12 +900,19 @@ static void rockchip_get_recalced_mux(struct 
rockchip_pin_bank *bank, int pin,
.route_offset = 0x50,
.route_val = BIT(16) | BIT(16 + 1) | BIT(0),
}, {
-   /* gmac-m1-optimized_rxd0 */
+   /* gmac-m1_rxd0 */
.bank_num = 1,
.pin = 11,
.func = 2,
.route_offset = 0x50,
-   .route_val = BIT(16 + 2) | BIT(16 + 10) | BIT(2) | BIT(10),
+   .route_val = BIT(16 + 2) | BIT(2),
+   }, {
+   /* gmac-m1-optimized_rxd3 */
+   .bank_num = 1,
+   .pin = 14,
+   .func = 2,
+   .route_offset = 0x50,
+   .route_val = BIT(16 + 10) | BIT(10),
}, {
/* pdm_sdi0m0 */
.bank_num = 2,
-- 
1.9.1




[PATCH 1/2] pinctrl: rockchip: Fix the rk3399 gpio0 and gpio1 banks' drv_offset at pmu grf

2017-09-30 Thread David Wu
The offset of gpio0 and gpio1 bank drive strength is 0x8, not 0x4.
But the mux is 0x4, we couldn't use the IOMUX_WIDTH_4BIT flag, so
we give them actual offset.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index b5cb785..c7c9beb 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -3456,8 +3456,8 @@ static int rockchip_pinctrl_probe(struct platform_device 
*pdev)
 DRV_TYPE_IO_1V8_ONLY,
 DRV_TYPE_IO_DEFAULT,
 DRV_TYPE_IO_DEFAULT,
-0x0,
-0x8,
+0x80,
+0x88,
 -1,
 -1,
 PULL_TYPE_IO_1V8_ONLY,
@@ -3473,10 +3473,10 @@ static int rockchip_pinctrl_probe(struct 
platform_device *pdev)
DRV_TYPE_IO_1V8_OR_3V0,
DRV_TYPE_IO_1V8_OR_3V0,
DRV_TYPE_IO_1V8_OR_3V0,
-   0x20,
-   0x28,
-   0x30,
-   0x38
+   0xa0,
+   0xa8,
+   0xb0,
+   0xb8
),
PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
  DRV_TYPE_IO_1V8_OR_3V0,
-- 
1.9.1




[PATCH 1/2] pinctrl: rockchip: Fix the rk3399 gpio0 and gpio1 banks' drv_offset at pmu grf

2017-09-30 Thread David Wu
The offset of gpio0 and gpio1 bank drive strength is 0x8, not 0x4.
But the mux is 0x4, we couldn't use the IOMUX_WIDTH_4BIT flag, so
we give them actual offset.

Signed-off-by: David Wu 
---
 drivers/pinctrl/pinctrl-rockchip.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index b5cb785..c7c9beb 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -3456,8 +3456,8 @@ static int rockchip_pinctrl_probe(struct platform_device 
*pdev)
 DRV_TYPE_IO_1V8_ONLY,
 DRV_TYPE_IO_DEFAULT,
 DRV_TYPE_IO_DEFAULT,
-0x0,
-0x8,
+0x80,
+0x88,
 -1,
 -1,
 PULL_TYPE_IO_1V8_ONLY,
@@ -3473,10 +3473,10 @@ static int rockchip_pinctrl_probe(struct 
platform_device *pdev)
DRV_TYPE_IO_1V8_OR_3V0,
DRV_TYPE_IO_1V8_OR_3V0,
DRV_TYPE_IO_1V8_OR_3V0,
-   0x20,
-   0x28,
-   0x30,
-   0x38
+   0xa0,
+   0xa8,
+   0xb0,
+   0xb8
),
PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
  DRV_TYPE_IO_1V8_OR_3V0,
-- 
1.9.1




[PATCH 0/2] Fix two pinctrl issues

2017-09-30 Thread David Wu
They are:
1. Fix the rk3399 gpio0 and gpio1 banks' drive strength offset.
2. Fix the correct routing config for the gmac-m1 pins between rmii and rgmii.

David Wu (2):
  pinctrl: rockchip: Fix the rk3399 gpio0 and gpio1 banks' drv_offset at
pmu grf
  pinctrl: rockchip: Fix the correct routing config for the gmac-m1 pins
of rmii and rgmii

 drivers/pinctrl/pinctrl-rockchip.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

-- 
1.9.1




[PATCH 0/2] Fix two pinctrl issues

2017-09-30 Thread David Wu
They are:
1. Fix the rk3399 gpio0 and gpio1 banks' drive strength offset.
2. Fix the correct routing config for the gmac-m1 pins between rmii and rgmii.

David Wu (2):
  pinctrl: rockchip: Fix the rk3399 gpio0 and gpio1 banks' drv_offset at
pmu grf
  pinctrl: rockchip: Fix the correct routing config for the gmac-m1 pins
of rmii and rgmii

 drivers/pinctrl/pinctrl-rockchip.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

-- 
1.9.1




[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] 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 
---
 .../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;
+
+   if (IS_ERR(b

[PATCH v2] pinctrl: rockchip: Add rv1108 recalculated iomux support

2017-08-23 Thread David Wu
The pins from GPIO1A0 to GPIO1B1 are special, need to recalculate
iomux. And the register offset is larger than the u8 range, so changed
to u32.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 68 +-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index c6f472e..b5cb785 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -301,7 +301,7 @@ struct rockchip_pin_bank {
 struct rockchip_mux_recalced_data {
u8 num;
u8 pin;
-   u8 reg;
+   u32 reg;
u8 bit;
u8 mask;
 };
@@ -558,6 +558,70 @@ static void rockchip_dt_free_map(struct pinctrl_dev 
*pctldev,
  * Hardware access
  */
 
+static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
+   {
+   .num = 1,
+   .pin = 0,
+   .reg = 0x418,
+   .bit = 0,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 1,
+   .reg = 0x418,
+   .bit = 2,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 2,
+   .reg = 0x418,
+   .bit = 4,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 3,
+   .reg = 0x418,
+   .bit = 6,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 4,
+   .reg = 0x418,
+   .bit = 8,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 5,
+   .reg = 0x418,
+   .bit = 10,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 6,
+   .reg = 0x418,
+   .bit = 12,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 7,
+   .reg = 0x418,
+   .bit = 14,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 8,
+   .reg = 0x41c,
+   .bit = 0,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 9,
+   .reg = 0x41c,
+   .bit = 2,
+   .mask = 0x3
+   },
+};
+
 static  struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = {
{
.num = 2,
@@ -3162,6 +3226,8 @@ static int rockchip_pinctrl_probe(struct platform_device 
*pdev)
.type   = RV1108,
.grf_mux_offset = 0x10,
.pmu_mux_offset = 0x0,
+   .iomux_recalced = rv1108_mux_recalced_data,
+   .niomux_recalced= ARRAY_SIZE(rv1108_mux_recalced_data),
.pull_calc_reg  = rv1108_calc_pull_reg_and_bit,
.drv_calc_reg   = rv1108_calc_drv_reg_and_bit,
.schmitt_calc_reg   = rv1108_calc_schmitt_reg_and_bit,
-- 
1.9.1




[PATCH v2] pinctrl: rockchip: Add rv1108 recalculated iomux support

2017-08-23 Thread David Wu
The pins from GPIO1A0 to GPIO1B1 are special, need to recalculate
iomux. And the register offset is larger than the u8 range, so changed
to u32.

Signed-off-by: David Wu 
---
 drivers/pinctrl/pinctrl-rockchip.c | 68 +-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index c6f472e..b5cb785 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -301,7 +301,7 @@ struct rockchip_pin_bank {
 struct rockchip_mux_recalced_data {
u8 num;
u8 pin;
-   u8 reg;
+   u32 reg;
u8 bit;
u8 mask;
 };
@@ -558,6 +558,70 @@ static void rockchip_dt_free_map(struct pinctrl_dev 
*pctldev,
  * Hardware access
  */
 
+static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
+   {
+   .num = 1,
+   .pin = 0,
+   .reg = 0x418,
+   .bit = 0,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 1,
+   .reg = 0x418,
+   .bit = 2,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 2,
+   .reg = 0x418,
+   .bit = 4,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 3,
+   .reg = 0x418,
+   .bit = 6,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 4,
+   .reg = 0x418,
+   .bit = 8,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 5,
+   .reg = 0x418,
+   .bit = 10,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 6,
+   .reg = 0x418,
+   .bit = 12,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 7,
+   .reg = 0x418,
+   .bit = 14,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 8,
+   .reg = 0x41c,
+   .bit = 0,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 9,
+   .reg = 0x41c,
+   .bit = 2,
+   .mask = 0x3
+   },
+};
+
 static  struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = {
{
.num = 2,
@@ -3162,6 +3226,8 @@ static int rockchip_pinctrl_probe(struct platform_device 
*pdev)
.type   = RV1108,
.grf_mux_offset = 0x10,
.pmu_mux_offset = 0x0,
+   .iomux_recalced = rv1108_mux_recalced_data,
+   .niomux_recalced= ARRAY_SIZE(rv1108_mux_recalced_data),
.pull_calc_reg  = rv1108_calc_pull_reg_and_bit,
.drv_calc_reg   = rv1108_calc_drv_reg_and_bit,
.schmitt_calc_reg   = rv1108_calc_schmitt_reg_and_bit,
-- 
1.9.1




[PATCH] pinctrl: rockchip: Add rv1108 recalced iomux support

2017-08-22 Thread David Wu
The pins from GPIO1A0 to GPIO1B1 are special, need to recalculate
iomux. And the register offset is larger than the u8 range, so changed
to u32.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 68 +-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index c6f472e..9f411b5 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -301,7 +301,7 @@ struct rockchip_pin_bank {
 struct rockchip_mux_recalced_data {
u8 num;
u8 pin;
-   u8 reg;
+   u32 reg;
u8 bit;
u8 mask;
 };
@@ -614,6 +614,70 @@ static void rockchip_dt_free_map(struct pinctrl_dev 
*pctldev,
},
 };
 
+static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
+   {
+   .num = 1,
+   .pin = 0,
+   .reg = 0x418,
+   .bit = 0,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 1,
+   .reg = 0x418,
+   .bit = 2,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 2,
+   .reg = 0x418,
+   .bit = 4,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 3,
+   .reg = 0x418,
+   .bit = 6,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 4,
+   .reg = 0x418,
+   .bit = 8,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 5,
+   .reg = 0x418,
+   .bit = 10,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 6,
+   .reg = 0x418,
+   .bit = 12,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 7,
+   .reg = 0x418,
+   .bit = 14,
+   .mask = 0x3
+   },  {
+   .num = 1,
+   .pin = 8,
+   .reg = 0x41c,
+   .bit = 0,
+   .mask = 0x3
+   },  {
+   .num = 1,
+   .pin = 9,
+   .reg = 0x41c,
+   .bit = 2,
+   .mask = 0x3
+   },
+};
+
 static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
  int *reg, u8 *bit, int *mask)
 {
@@ -3162,6 +3226,8 @@ static int rockchip_pinctrl_probe(struct platform_device 
*pdev)
.type   = RV1108,
.grf_mux_offset = 0x10,
.pmu_mux_offset = 0x0,
+   .iomux_recalced = rv1108_mux_recalced_data,
+   .niomux_recalced= ARRAY_SIZE(rv1108_mux_recalced_data),
.pull_calc_reg  = rv1108_calc_pull_reg_and_bit,
.drv_calc_reg   = rv1108_calc_drv_reg_and_bit,
.schmitt_calc_reg   = rv1108_calc_schmitt_reg_and_bit,
-- 
1.9.1




[PATCH] pinctrl: rockchip: Add rv1108 recalced iomux support

2017-08-22 Thread David Wu
The pins from GPIO1A0 to GPIO1B1 are special, need to recalculate
iomux. And the register offset is larger than the u8 range, so changed
to u32.

Signed-off-by: David Wu 
---
 drivers/pinctrl/pinctrl-rockchip.c | 68 +-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
index c6f472e..9f411b5 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -301,7 +301,7 @@ struct rockchip_pin_bank {
 struct rockchip_mux_recalced_data {
u8 num;
u8 pin;
-   u8 reg;
+   u32 reg;
u8 bit;
u8 mask;
 };
@@ -614,6 +614,70 @@ static void rockchip_dt_free_map(struct pinctrl_dev 
*pctldev,
},
 };
 
+static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
+   {
+   .num = 1,
+   .pin = 0,
+   .reg = 0x418,
+   .bit = 0,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 1,
+   .reg = 0x418,
+   .bit = 2,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 2,
+   .reg = 0x418,
+   .bit = 4,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 3,
+   .reg = 0x418,
+   .bit = 6,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 4,
+   .reg = 0x418,
+   .bit = 8,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 5,
+   .reg = 0x418,
+   .bit = 10,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 6,
+   .reg = 0x418,
+   .bit = 12,
+   .mask = 0x3
+   }, {
+   .num = 1,
+   .pin = 7,
+   .reg = 0x418,
+   .bit = 14,
+   .mask = 0x3
+   },  {
+   .num = 1,
+   .pin = 8,
+   .reg = 0x41c,
+   .bit = 0,
+   .mask = 0x3
+   },  {
+   .num = 1,
+   .pin = 9,
+   .reg = 0x41c,
+   .bit = 2,
+   .mask = 0x3
+   },
+};
+
 static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
  int *reg, u8 *bit, int *mask)
 {
@@ -3162,6 +3226,8 @@ static int rockchip_pinctrl_probe(struct platform_device 
*pdev)
.type   = RV1108,
.grf_mux_offset = 0x10,
.pmu_mux_offset = 0x0,
+   .iomux_recalced = rv1108_mux_recalced_data,
+   .niomux_recalced= ARRAY_SIZE(rv1108_mux_recalced_data),
.pull_calc_reg  = rv1108_calc_pull_reg_and_bit,
.drv_calc_reg   = rv1108_calc_drv_reg_and_bit,
.schmitt_calc_reg   = rv1108_calc_schmitt_reg_and_bit,
-- 
1.9.1




[PATCH v2] PM / AVS: rockchip-io: add io selectors and supplies for RV1108

2017-08-21 Thread David Wu
This adds the necessary data for handling io voltage domains on the RV1108.

Signed-off-by: David Wu <david...@rock-chips.com>
---
change in v2:
 - Alphabetic order for the binding string

 .../bindings/power/rockchip-io-domain.txt  |  2 ++
 drivers/power/avs/rockchip-io-domain.c | 38 ++
 2 files changed, 40 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt 
b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
index 43c21fb..4a4766e 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
@@ -39,6 +39,8 @@ Required properties:
   - "rockchip,rk3368-pmu-io-voltage-domain" for rk3368 pmu-domains
   - "rockchip,rk3399-io-voltage-domain" for rk3399
   - "rockchip,rk3399-pmu-io-voltage-domain" for rk3399 pmu-domains
+  - "rockchip,rv1108-io-voltage-domain" for rv1108
+  - "rockchip,rv1108-pmu-io-voltage-domain" for rv1108 pmu-domains
 
 Deprecated properties:
 - rockchip,grf: phandle to the syscon managing the "general register files"
diff --git a/drivers/power/avs/rockchip-io-domain.c 
b/drivers/power/avs/rockchip-io-domain.c
index 031a343..75f63e3 100644
--- a/drivers/power/avs/rockchip-io-domain.c
+++ b/drivers/power/avs/rockchip-io-domain.c
@@ -349,6 +349,36 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
.init = rk3399_pmu_iodomain_init,
 };
 
+static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
+   .grf_offset = 0x404,
+   .supply_names = {
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   "vccio1",
+   "vccio2",
+   "vccio3",
+   "vccio5",
+   "vccio6",
+   },
+
+};
+
+static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
+   .grf_offset = 0x104,
+   .supply_names = {
+   "pmu",
+   },
+};
+
 static const struct of_device_id rockchip_iodomain_match[] = {
{
.compatible = "rockchip,rk3188-io-voltage-domain",
@@ -382,6 +412,14 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
.compatible = "rockchip,rk3399-pmu-io-voltage-domain",
.data = (void *)_data_rk3399_pmu
},
+   {
+   .compatible = "rockchip,rv1108-io-voltage-domain",
+   .data = (void *)_data_rv1108
+   },
+   {
+   .compatible = "rockchip,rv1108-pmu-io-voltage-domain",
+   .data = (void *)_data_rv1108_pmu
+   },
{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, rockchip_iodomain_match);
-- 
1.9.1




[PATCH v2] PM / AVS: rockchip-io: add io selectors and supplies for RV1108

2017-08-21 Thread David Wu
This adds the necessary data for handling io voltage domains on the RV1108.

Signed-off-by: David Wu 
---
change in v2:
 - Alphabetic order for the binding string

 .../bindings/power/rockchip-io-domain.txt  |  2 ++
 drivers/power/avs/rockchip-io-domain.c | 38 ++
 2 files changed, 40 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt 
b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
index 43c21fb..4a4766e 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
@@ -39,6 +39,8 @@ Required properties:
   - "rockchip,rk3368-pmu-io-voltage-domain" for rk3368 pmu-domains
   - "rockchip,rk3399-io-voltage-domain" for rk3399
   - "rockchip,rk3399-pmu-io-voltage-domain" for rk3399 pmu-domains
+  - "rockchip,rv1108-io-voltage-domain" for rv1108
+  - "rockchip,rv1108-pmu-io-voltage-domain" for rv1108 pmu-domains
 
 Deprecated properties:
 - rockchip,grf: phandle to the syscon managing the "general register files"
diff --git a/drivers/power/avs/rockchip-io-domain.c 
b/drivers/power/avs/rockchip-io-domain.c
index 031a343..75f63e3 100644
--- a/drivers/power/avs/rockchip-io-domain.c
+++ b/drivers/power/avs/rockchip-io-domain.c
@@ -349,6 +349,36 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
.init = rk3399_pmu_iodomain_init,
 };
 
+static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
+   .grf_offset = 0x404,
+   .supply_names = {
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   "vccio1",
+   "vccio2",
+   "vccio3",
+   "vccio5",
+   "vccio6",
+   },
+
+};
+
+static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
+   .grf_offset = 0x104,
+   .supply_names = {
+   "pmu",
+   },
+};
+
 static const struct of_device_id rockchip_iodomain_match[] = {
{
.compatible = "rockchip,rk3188-io-voltage-domain",
@@ -382,6 +412,14 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
.compatible = "rockchip,rk3399-pmu-io-voltage-domain",
.data = (void *)_data_rk3399_pmu
},
+   {
+   .compatible = "rockchip,rv1108-io-voltage-domain",
+   .data = (void *)_data_rv1108
+   },
+   {
+   .compatible = "rockchip,rv1108-pmu-io-voltage-domain",
+   .data = (void *)_data_rv1108_pmu
+   },
{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, rockchip_iodomain_match);
-- 
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] 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 
---
 .../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] PM / AVS: rockchip-io: add io selectors and supplies for rv1108

2017-08-17 Thread David Wu
This adds the necessary data for handling io voltage domains on the rv1108.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 .../bindings/power/rockchip-io-domain.txt  |  2 ++
 drivers/power/avs/rockchip-io-domain.c | 38 ++
 2 files changed, 40 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt 
b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
index 43c21fb..d9d96fd 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
@@ -31,6 +31,8 @@ SoC is on the same page.
 
 Required properties:
 - compatible: should be one of:
+  - "rockchip,rv1108-io-voltage-domain" for rv1108
+  - "rockchip,rv1108-pmu-io-voltage-domain" for rv1108 pmu-domains
   - "rockchip,rk3188-io-voltage-domain" for rk3188
   - "rockchip,rk3228-io-voltage-domain" for rk3228
   - "rockchip,rk3288-io-voltage-domain" for rk3288
diff --git a/drivers/power/avs/rockchip-io-domain.c 
b/drivers/power/avs/rockchip-io-domain.c
index 031a343..a55205eb 100644
--- a/drivers/power/avs/rockchip-io-domain.c
+++ b/drivers/power/avs/rockchip-io-domain.c
@@ -227,6 +227,36 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n");
 }
 
+static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
+   .grf_offset = 0x404,
+   .supply_names = {
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   "vccio1",
+   "vccio2",
+   "vccio3",
+   "vccio5",
+   "vccio6",
+   },
+
+};
+
+static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
+   .grf_offset = 0x104,
+   .supply_names = {
+   "pmu",
+   },
+};
+
 /*
  * On the rk3188 the io-domains are handled by a shared register with the
  * lower 8 bits being still being continuing drive-strength settings.
@@ -351,6 +381,14 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
 
 static const struct of_device_id rockchip_iodomain_match[] = {
{
+   .compatible = "rockchip,rv1108-io-voltage-domain",
+   .data = (void *)_data_rv1108
+   },
+   {
+   .compatible = "rockchip,rv1108-pmu-io-voltage-domain",
+   .data = (void *)_data_rv1108_pmu
+   },
+   {
.compatible = "rockchip,rk3188-io-voltage-domain",
.data = (void *)_data_rk3188
},
-- 
1.9.1




[PATCH] PM / AVS: rockchip-io: add io selectors and supplies for rv1108

2017-08-17 Thread David Wu
This adds the necessary data for handling io voltage domains on the rv1108.

Signed-off-by: David Wu 
---
 .../bindings/power/rockchip-io-domain.txt  |  2 ++
 drivers/power/avs/rockchip-io-domain.c | 38 ++
 2 files changed, 40 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt 
b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
index 43c21fb..d9d96fd 100644
--- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
+++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt
@@ -31,6 +31,8 @@ SoC is on the same page.
 
 Required properties:
 - compatible: should be one of:
+  - "rockchip,rv1108-io-voltage-domain" for rv1108
+  - "rockchip,rv1108-pmu-io-voltage-domain" for rv1108 pmu-domains
   - "rockchip,rk3188-io-voltage-domain" for rk3188
   - "rockchip,rk3228-io-voltage-domain" for rk3228
   - "rockchip,rk3288-io-voltage-domain" for rk3288
diff --git a/drivers/power/avs/rockchip-io-domain.c 
b/drivers/power/avs/rockchip-io-domain.c
index 031a343..a55205eb 100644
--- a/drivers/power/avs/rockchip-io-domain.c
+++ b/drivers/power/avs/rockchip-io-domain.c
@@ -227,6 +227,36 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n");
 }
 
+static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
+   .grf_offset = 0x404,
+   .supply_names = {
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   "vccio1",
+   "vccio2",
+   "vccio3",
+   "vccio5",
+   "vccio6",
+   },
+
+};
+
+static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
+   .grf_offset = 0x104,
+   .supply_names = {
+   "pmu",
+   },
+};
+
 /*
  * On the rk3188 the io-domains are handled by a shared register with the
  * lower 8 bits being still being continuing drive-strength settings.
@@ -351,6 +381,14 @@ static void rk3399_pmu_iodomain_init(struct 
rockchip_iodomain *iod)
 
 static const struct of_device_id rockchip_iodomain_match[] = {
{
+   .compatible = "rockchip,rv1108-io-voltage-domain",
+   .data = (void *)_data_rv1108
+   },
+   {
+   .compatible = "rockchip,rv1108-pmu-io-voltage-domain",
+   .data = (void *)_data_rv1108_pmu
+   },
+   {
.compatible = "rockchip,rk3188-io-voltage-domain",
.data = (void *)_data_rk3188
},
-- 
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 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 
---
 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 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 
---
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 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 
Reviewed-by: Florian Fainelli 
---
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 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 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 
---
 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 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 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 
---
 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 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 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 
---
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(bsp_priv->aclk_mac))

[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 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 
---
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 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 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 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 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 
---
 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 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 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 
---
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 
+ *
+ * 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 speed = SPEED_10;
+
+   if (phydev->autoneg == AUTONEG_ENA

[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 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 
---
 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 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 
---
 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 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 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 
---
 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 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 
---
 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 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 
---
 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 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 
---
 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 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 
---
 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 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 
---
 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 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 
---
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;
@@ -803,6 +852,14 @@ 

[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 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 
---
 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 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 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 
---
 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 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 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 
---
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 
+ *
+ * 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) {
+   int reg = phy_read(phydev, MII_SPECIAL_CONTROL_STATUS);

[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 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 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 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 
---
 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 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 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 
---
 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 1/7] pwm: rockchip: Add APB and function both clocks support

2017-08-08 Thread David Wu
New PWM module provides two individual clocks for APB clock
and function clock.

Signed-off-by: David Wu <david...@rock-chips.com>
Acked-by: Rob Herring <r...@kernel.org>
---
changes in v3:
 - clk_get with NULL argument again if it was error, when clk_get with "pwm" 
argument.
 - To get clk count, use of_count_phandle_with_args instead of 
of_property_count_strings.

 .../devicetree/bindings/pwm/pwm-rockchip.txt   |  8 ++-
 drivers/pwm/pwm-rockchip.c | 58 ++
 2 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt 
b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
index b8be3d0..2350ef9 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
@@ -6,7 +6,13 @@ Required properties:
"rockchip,rk3288-pwm": found on RK3288 SoC
"rockchip,vop-pwm": found integrated in VOP on RK3288 SoC
  - reg: physical base address and length of the controller's registers
- - clocks: phandle and clock specifier of the PWM reference clock
+ - clocks: See ../clock/clock-bindings.txt
+   - For older hardware (rk2928, rk3066, rk3188, rk3228, rk3288, rk3399):
+ - There is one clock that's used both to derive the functional clock
+   for the device and as the bus clock.
+   - For newer hardware (rk3328 and future socs): specified by name
+ - "pwm": This is used to derive the functional clock.
+ - "pclk": This is the APB bus clock.
  - #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.txt in this directory
for a description of the cell format.
 
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 744d561..ac3cd5e 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -33,6 +33,7 @@
 struct rockchip_pwm_chip {
struct pwm_chip chip;
struct clk *clk;
+   struct clk *pclk;
const struct rockchip_pwm_data *data;
void __iomem *base;
 };
@@ -145,7 +146,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
u64 tmp;
int ret;
 
-   ret = clk_enable(pc->clk);
+   ret = clk_enable(pc->pclk);
if (ret)
return;
 
@@ -161,7 +162,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
 
pc->data->get_state(chip, pwm, state);
 
-   clk_disable(pc->clk);
+   clk_disable(pc->pclk);
 }
 
 static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -224,7 +225,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
pwm_get_state(pwm, );
enabled = curstate.enabled;
 
-   ret = clk_enable(pc->clk);
+   ret = clk_enable(pc->pclk);
if (ret)
return ret;
 
@@ -257,7 +258,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
rockchip_pwm_get_state(chip, pwm, state);
 
 out:
-   clk_disable(pc->clk);
+   clk_disable(pc->pclk);
 
return ret;
 }
@@ -328,7 +329,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
const struct of_device_id *id;
struct rockchip_pwm_chip *pc;
struct resource *r;
-   int ret;
+   int ret, count;
 
id = of_match_device(rockchip_pwm_dt_ids, >dev);
if (!id)
@@ -343,13 +344,43 @@ static int rockchip_pwm_probe(struct platform_device 
*pdev)
if (IS_ERR(pc->base))
return PTR_ERR(pc->base);
 
-   pc->clk = devm_clk_get(>dev, NULL);
-   if (IS_ERR(pc->clk))
-   return PTR_ERR(pc->clk);
+   pc->clk = devm_clk_get(>dev, "pwm");
+   if (IS_ERR(pc->clk)) {
+   pc->clk = devm_clk_get(>dev, NULL);
+   if (IS_ERR(pc->clk)) {
+   ret = PTR_ERR(pc->clk);
+   if (ret != -EPROBE_DEFER)
+   dev_err(>dev, "Can't get bus clk: %d\n",
+   ret);
+   return ret;
+   }
+   }
+
+   count = of_count_phandle_with_args(pdev->dev.of_node,
+  "clocks", "#clock-cells");
+   if (count == 2)
+   pc->pclk = devm_clk_get(>dev, "pclk");
+   else
+   pc->pclk = pc->clk;
+
+   if (IS_ERR(pc->pclk)) {
+   ret = PTR_ERR(pc->pclk);
+   if (ret != -EPROBE_DEFER)
+   dev_err(>dev, "Can't get APB clk: %d\n", ret);
+   return ret;
+   }
 
ret = clk_prepare_enable(pc->clk);
-   if (ret)
+   if (ret) {
+   dev_err(>dev, "Can't prepare enable bus clk: %d\n", ret);
return ret;

[PATCH v3 1/7] pwm: rockchip: Add APB and function both clocks support

2017-08-08 Thread David Wu
New PWM module provides two individual clocks for APB clock
and function clock.

Signed-off-by: David Wu 
Acked-by: Rob Herring 
---
changes in v3:
 - clk_get with NULL argument again if it was error, when clk_get with "pwm" 
argument.
 - To get clk count, use of_count_phandle_with_args instead of 
of_property_count_strings.

 .../devicetree/bindings/pwm/pwm-rockchip.txt   |  8 ++-
 drivers/pwm/pwm-rockchip.c | 58 ++
 2 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt 
b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
index b8be3d0..2350ef9 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt
@@ -6,7 +6,13 @@ Required properties:
"rockchip,rk3288-pwm": found on RK3288 SoC
"rockchip,vop-pwm": found integrated in VOP on RK3288 SoC
  - reg: physical base address and length of the controller's registers
- - clocks: phandle and clock specifier of the PWM reference clock
+ - clocks: See ../clock/clock-bindings.txt
+   - For older hardware (rk2928, rk3066, rk3188, rk3228, rk3288, rk3399):
+ - There is one clock that's used both to derive the functional clock
+   for the device and as the bus clock.
+   - For newer hardware (rk3328 and future socs): specified by name
+ - "pwm": This is used to derive the functional clock.
+ - "pclk": This is the APB bus clock.
  - #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.txt in this directory
for a description of the cell format.
 
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 744d561..ac3cd5e 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -33,6 +33,7 @@
 struct rockchip_pwm_chip {
struct pwm_chip chip;
struct clk *clk;
+   struct clk *pclk;
const struct rockchip_pwm_data *data;
void __iomem *base;
 };
@@ -145,7 +146,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
u64 tmp;
int ret;
 
-   ret = clk_enable(pc->clk);
+   ret = clk_enable(pc->pclk);
if (ret)
return;
 
@@ -161,7 +162,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
 
pc->data->get_state(chip, pwm, state);
 
-   clk_disable(pc->clk);
+   clk_disable(pc->pclk);
 }
 
 static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -224,7 +225,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
pwm_get_state(pwm, );
enabled = curstate.enabled;
 
-   ret = clk_enable(pc->clk);
+   ret = clk_enable(pc->pclk);
if (ret)
return ret;
 
@@ -257,7 +258,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
rockchip_pwm_get_state(chip, pwm, state);
 
 out:
-   clk_disable(pc->clk);
+   clk_disable(pc->pclk);
 
return ret;
 }
@@ -328,7 +329,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev)
const struct of_device_id *id;
struct rockchip_pwm_chip *pc;
struct resource *r;
-   int ret;
+   int ret, count;
 
id = of_match_device(rockchip_pwm_dt_ids, >dev);
if (!id)
@@ -343,13 +344,43 @@ static int rockchip_pwm_probe(struct platform_device 
*pdev)
if (IS_ERR(pc->base))
return PTR_ERR(pc->base);
 
-   pc->clk = devm_clk_get(>dev, NULL);
-   if (IS_ERR(pc->clk))
-   return PTR_ERR(pc->clk);
+   pc->clk = devm_clk_get(>dev, "pwm");
+   if (IS_ERR(pc->clk)) {
+   pc->clk = devm_clk_get(>dev, NULL);
+   if (IS_ERR(pc->clk)) {
+   ret = PTR_ERR(pc->clk);
+   if (ret != -EPROBE_DEFER)
+   dev_err(>dev, "Can't get bus clk: %d\n",
+   ret);
+   return ret;
+   }
+   }
+
+   count = of_count_phandle_with_args(pdev->dev.of_node,
+  "clocks", "#clock-cells");
+   if (count == 2)
+   pc->pclk = devm_clk_get(>dev, "pclk");
+   else
+   pc->pclk = pc->clk;
+
+   if (IS_ERR(pc->pclk)) {
+   ret = PTR_ERR(pc->pclk);
+   if (ret != -EPROBE_DEFER)
+   dev_err(>dev, "Can't get APB clk: %d\n", ret);
+   return ret;
+   }
 
ret = clk_prepare_enable(pc->clk);
-   if (ret)
+   if (ret) {
+   dev_err(>dev, "Can't prepare enable bus clk: %d\n", ret);
return ret;
+   }
+
+   ret = clk_prepare(pc->pclk);

[PATCH v3 3/7] pwm: rockchip: Use pwm_apply instead of the pwm_enable

2017-08-08 Thread David Wu
Drop the custom hook of pwm_enable and implement
pwm_apply_v1 and pwm_apply_v2 instead.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/pwm/pwm-rockchip.c | 141 +
 1 file changed, 77 insertions(+), 64 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 33bbb5a..4bbecbd 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -51,11 +51,10 @@ struct rockchip_pwm_data {
bool supports_polarity;
const struct pwm_ops *ops;
 
-   void (*set_enable)(struct pwm_chip *chip,
-  struct pwm_device *pwm, bool enable,
-  enum pwm_polarity polarity);
void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
  struct pwm_state *state);
+   int (*pwm_apply)(struct pwm_chip *chip, struct pwm_device *pwm,
+struct pwm_state *state);
 };
 
 static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip 
*c)
@@ -63,24 +62,6 @@ static inline struct rockchip_pwm_chip 
*to_rockchip_pwm_chip(struct pwm_chip *c)
return container_of(c, struct rockchip_pwm_chip, chip);
 }
 
-static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip,
-  struct pwm_device *pwm, bool enable,
-  enum pwm_polarity polarity)
-{
-   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
-   u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
-   u32 val;
-
-   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
-
-   if (enable)
-   val |= enable_conf;
-   else
-   val &= ~enable_conf;
-
-   writel_relaxed(val, pc->base + pc->data->regs.ctrl);
-}
-
 static void rockchip_pwm_get_state_v1(struct pwm_chip *chip,
  struct pwm_device *pwm,
  struct pwm_state *state)
@@ -94,30 +75,6 @@ static void rockchip_pwm_get_state_v1(struct pwm_chip *chip,
state->enabled = true;
 }
 
-static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip,
-  struct pwm_device *pwm, bool enable,
-  enum pwm_polarity polarity)
-{
-   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
-   u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
- PWM_CONTINUOUS;
-   u32 val;
-
-   if (polarity == PWM_POLARITY_INVERSED)
-   enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSITIVE;
-   else
-   enable_conf |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
-
-   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
-
-   if (enable)
-   val |= enable_conf;
-   else
-   val &= ~enable_conf;
-
-   writel_relaxed(val, pc->base + pc->data->regs.ctrl);
-}
-
 static void rockchip_pwm_get_state_v2(struct pwm_chip *chip,
  struct pwm_device *pwm,
  struct pwm_state *state)
@@ -193,10 +150,12 @@ static void rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
 static int rockchip_pwm_enable(struct pwm_chip *chip,
 struct pwm_device *pwm,
 bool enable,
-enum pwm_polarity polarity)
+enum pwm_polarity polarity,
+u32 enable_conf)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
int ret;
+   u32 val;
 
if (enable) {
ret = clk_enable(pc->clk);
@@ -204,7 +163,23 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
return ret;
}
 
-   pc->data->set_enable(chip, pwm, enable, polarity);
+   if (pc->data->supports_polarity) {
+   if (polarity == PWM_POLARITY_INVERSED)
+   enable_conf |= PWM_DUTY_NEGATIVE |
+  PWM_INACTIVE_POSITIVE;
+   else
+   enable_conf |= PWM_DUTY_POSITIVE |
+  PWM_INACTIVE_NEGATIVE;
+   }
+
+   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
+
+   if (enable)
+   val |= enable_conf;
+   else
+   val &= ~enable_conf;
+
+   writel_relaxed(val, pc->base + pc->data->regs.ctrl);
 
if (!enable)
clk_disable(pc->clk);
@@ -212,37 +187,75 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
return 0;
 }
 
-static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int rockchip_pwm_apply_v1(struct pwm_chip *chip, struct

[PATCH v3 3/7] pwm: rockchip: Use pwm_apply instead of the pwm_enable

2017-08-08 Thread David Wu
Drop the custom hook of pwm_enable and implement
pwm_apply_v1 and pwm_apply_v2 instead.

Signed-off-by: David Wu 
---
 drivers/pwm/pwm-rockchip.c | 141 +
 1 file changed, 77 insertions(+), 64 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index 33bbb5a..4bbecbd 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -51,11 +51,10 @@ struct rockchip_pwm_data {
bool supports_polarity;
const struct pwm_ops *ops;
 
-   void (*set_enable)(struct pwm_chip *chip,
-  struct pwm_device *pwm, bool enable,
-  enum pwm_polarity polarity);
void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
  struct pwm_state *state);
+   int (*pwm_apply)(struct pwm_chip *chip, struct pwm_device *pwm,
+struct pwm_state *state);
 };
 
 static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip 
*c)
@@ -63,24 +62,6 @@ static inline struct rockchip_pwm_chip 
*to_rockchip_pwm_chip(struct pwm_chip *c)
return container_of(c, struct rockchip_pwm_chip, chip);
 }
 
-static void rockchip_pwm_set_enable_v1(struct pwm_chip *chip,
-  struct pwm_device *pwm, bool enable,
-  enum pwm_polarity polarity)
-{
-   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
-   u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
-   u32 val;
-
-   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
-
-   if (enable)
-   val |= enable_conf;
-   else
-   val &= ~enable_conf;
-
-   writel_relaxed(val, pc->base + pc->data->regs.ctrl);
-}
-
 static void rockchip_pwm_get_state_v1(struct pwm_chip *chip,
  struct pwm_device *pwm,
  struct pwm_state *state)
@@ -94,30 +75,6 @@ static void rockchip_pwm_get_state_v1(struct pwm_chip *chip,
state->enabled = true;
 }
 
-static void rockchip_pwm_set_enable_v2(struct pwm_chip *chip,
-  struct pwm_device *pwm, bool enable,
-  enum pwm_polarity polarity)
-{
-   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
-   u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
- PWM_CONTINUOUS;
-   u32 val;
-
-   if (polarity == PWM_POLARITY_INVERSED)
-   enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSITIVE;
-   else
-   enable_conf |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
-
-   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
-
-   if (enable)
-   val |= enable_conf;
-   else
-   val &= ~enable_conf;
-
-   writel_relaxed(val, pc->base + pc->data->regs.ctrl);
-}
-
 static void rockchip_pwm_get_state_v2(struct pwm_chip *chip,
  struct pwm_device *pwm,
  struct pwm_state *state)
@@ -193,10 +150,12 @@ static void rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
 static int rockchip_pwm_enable(struct pwm_chip *chip,
 struct pwm_device *pwm,
 bool enable,
-enum pwm_polarity polarity)
+enum pwm_polarity polarity,
+u32 enable_conf)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
int ret;
+   u32 val;
 
if (enable) {
ret = clk_enable(pc->clk);
@@ -204,7 +163,23 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
return ret;
}
 
-   pc->data->set_enable(chip, pwm, enable, polarity);
+   if (pc->data->supports_polarity) {
+   if (polarity == PWM_POLARITY_INVERSED)
+   enable_conf |= PWM_DUTY_NEGATIVE |
+  PWM_INACTIVE_POSITIVE;
+   else
+   enable_conf |= PWM_DUTY_POSITIVE |
+  PWM_INACTIVE_NEGATIVE;
+   }
+
+   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
+
+   if (enable)
+   val |= enable_conf;
+   else
+   val &= ~enable_conf;
+
+   writel_relaxed(val, pc->base + pc->data->regs.ctrl);
 
if (!enable)
clk_disable(pc->clk);
@@ -212,37 +187,75 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
return 0;
 }
 
-static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state)
+static int rockchip_pwm_apply_v1(struct pwm_chip *chip, struct pwm_device *pwm,
+ 

[PATCH v3 0/7] Add rk3328 pwm support

2017-08-08 Thread David Wu
There are two features of rk3328 pwm module.
 - PWM APB and function clocks are different.
 - Add pwm atomic hardware update

David Wu (7):
  pwm: rockchip: Add APB and function both clocks support
  pwm: rockchip: Remove the judge from return value of pwm_config
  pwm: rockchip: Use pwm_apply instead of the pwm_enable
  pwm: rockchip: Move the configuration of polarity from
rockchip_pwm_set_enable() to rockchip_pwm_config()
  pwm: rockchip: Use same pwm ops for each IP
  pwm: rockchip: Add rk3328 pwm support
  arm64: dts: rockchip: Add pwm nodes for rk3328

 .../devicetree/bindings/pwm/pwm-rockchip.txt   |   8 +-
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   |  45 
 drivers/pwm/pwm-rockchip.c | 281 +++--
 3 files changed, 199 insertions(+), 135 deletions(-)

-- 
1.9.1




[PATCH v3 0/7] Add rk3328 pwm support

2017-08-08 Thread David Wu
There are two features of rk3328 pwm module.
 - PWM APB and function clocks are different.
 - Add pwm atomic hardware update

David Wu (7):
  pwm: rockchip: Add APB and function both clocks support
  pwm: rockchip: Remove the judge from return value of pwm_config
  pwm: rockchip: Use pwm_apply instead of the pwm_enable
  pwm: rockchip: Move the configuration of polarity from
rockchip_pwm_set_enable() to rockchip_pwm_config()
  pwm: rockchip: Use same pwm ops for each IP
  pwm: rockchip: Add rk3328 pwm support
  arm64: dts: rockchip: Add pwm nodes for rk3328

 .../devicetree/bindings/pwm/pwm-rockchip.txt   |   8 +-
 arch/arm64/boot/dts/rockchip/rk3328.dtsi   |  45 
 drivers/pwm/pwm-rockchip.c | 281 +++--
 3 files changed, 199 insertions(+), 135 deletions(-)

-- 
1.9.1




[PATCH v3 2/7] pwm: rockchip: Remove the judge from return value of pwm_config

2017-08-08 Thread David Wu
It seems the rockchip_pwm_config always returns the result 0,
so remove the judge.

Signed-off-by: David Wu <david...@rock-chips.com>
Acked-by: Boris Brezillon <boris.brezil...@free-electrons.com>
---
 drivers/pwm/pwm-rockchip.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index ac3cd5e..33bbb5a 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -165,7 +165,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
clk_disable(pc->pclk);
 }
 
-static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
   int duty_ns, int period_ns)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
@@ -188,8 +188,6 @@ static int rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
 
writel(period, pc->base + pc->data->regs.period);
writel(duty, pc->base + pc->data->regs.duty);
-
-   return 0;
 }
 
 static int rockchip_pwm_enable(struct pwm_chip *chip,
@@ -236,13 +234,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, 
struct pwm_device *pwm,
enabled = false;
}
 
-   ret = rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period);
-   if (ret) {
-   if (enabled != curstate.enabled)
-   rockchip_pwm_enable(chip, pwm, !enabled,
- state->polarity);
-   goto out;
-   }
+   rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period);
 
if (state->enabled != enabled) {
ret = rockchip_pwm_enable(chip, pwm, state->enabled,
-- 
1.9.1




[PATCH v3 2/7] pwm: rockchip: Remove the judge from return value of pwm_config

2017-08-08 Thread David Wu
It seems the rockchip_pwm_config always returns the result 0,
so remove the judge.

Signed-off-by: David Wu 
Acked-by: Boris Brezillon 
---
 drivers/pwm/pwm-rockchip.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index ac3cd5e..33bbb5a 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -165,7 +165,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
clk_disable(pc->pclk);
 }
 
-static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
   int duty_ns, int period_ns)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
@@ -188,8 +188,6 @@ static int rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
 
writel(period, pc->base + pc->data->regs.period);
writel(duty, pc->base + pc->data->regs.duty);
-
-   return 0;
 }
 
 static int rockchip_pwm_enable(struct pwm_chip *chip,
@@ -236,13 +234,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, 
struct pwm_device *pwm,
enabled = false;
}
 
-   ret = rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period);
-   if (ret) {
-   if (enabled != curstate.enabled)
-   rockchip_pwm_enable(chip, pwm, !enabled,
- state->polarity);
-   goto out;
-   }
+   rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period);
 
if (state->enabled != enabled) {
ret = rockchip_pwm_enable(chip, pwm, state->enabled,
-- 
1.9.1




[PATCH v3 7/7] arm64: dts: rockchip: Add pwm nodes for rk3328

2017-08-08 Thread David Wu
There are 4 pwm channels built in rk3328 soc, need to configure
the both APB clock and bus clock.

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

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 7e69f1f..1f945d3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -308,6 +308,51 @@
interrupts = ;
};
 
+   pwm0: pwm@ff1b {
+   compatible = "rockchip,rk3328-pwm";
+   reg = <0x0 0xff1b 0x0 0x10>;
+   #pwm-cells = <3>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pin>;
+   clocks = < SCLK_PWM>, < PCLK_PWM>;
+   clock-names = "pwm", "pclk";
+   status = "disabled";
+   };
+
+   pwm1: pwm@ff1b0010 {
+   compatible = "rockchip,rk3328-pwm";
+   reg = <0x0 0xff1b0010 0x0 0x10>;
+   #pwm-cells = <3>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pin>;
+   clocks = < SCLK_PWM>, < PCLK_PWM>;
+   clock-names = "pwm", "pclk";
+   status = "disabled";
+   };
+
+   pwm2: pwm@ff1b0020 {
+   compatible = "rockchip,rk3328-pwm";
+   reg = <0x0 0xff1b0020 0x0 0x10>;
+   #pwm-cells = <3>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pin>;
+   clocks = < SCLK_PWM>, < PCLK_PWM>;
+   clock-names = "pwm", "pclk";
+   status = "disabled";
+   };
+
+   pwm3: pwm@ff1b0030 {
+   compatible = "rockchip,rk3328-pwm";
+   reg = <0x0 0xff1b0030 0x0 0x10>;
+   interrupts = ;
+   #pwm-cells = <3>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pin>;
+   clocks = < SCLK_PWM>, < PCLK_PWM>;
+   clock-names = "pwm", "pclk";
+   status = "disabled";
+   };
+
saradc: adc@ff28 {
compatible = "rockchip,rk3328-saradc", "rockchip,rk3399-saradc";
reg = <0x0 0xff28 0x0 0x100>;
-- 
1.9.1




[PATCH v3 7/7] arm64: dts: rockchip: Add pwm nodes for rk3328

2017-08-08 Thread David Wu
There are 4 pwm channels built in rk3328 soc, need to configure
the both APB clock and bus clock.

Signed-off-by: David Wu 
---
 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 45 
 1 file changed, 45 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 7e69f1f..1f945d3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -308,6 +308,51 @@
interrupts = ;
};
 
+   pwm0: pwm@ff1b {
+   compatible = "rockchip,rk3328-pwm";
+   reg = <0x0 0xff1b 0x0 0x10>;
+   #pwm-cells = <3>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pin>;
+   clocks = < SCLK_PWM>, < PCLK_PWM>;
+   clock-names = "pwm", "pclk";
+   status = "disabled";
+   };
+
+   pwm1: pwm@ff1b0010 {
+   compatible = "rockchip,rk3328-pwm";
+   reg = <0x0 0xff1b0010 0x0 0x10>;
+   #pwm-cells = <3>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pin>;
+   clocks = < SCLK_PWM>, < PCLK_PWM>;
+   clock-names = "pwm", "pclk";
+   status = "disabled";
+   };
+
+   pwm2: pwm@ff1b0020 {
+   compatible = "rockchip,rk3328-pwm";
+   reg = <0x0 0xff1b0020 0x0 0x10>;
+   #pwm-cells = <3>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pin>;
+   clocks = < SCLK_PWM>, < PCLK_PWM>;
+   clock-names = "pwm", "pclk";
+   status = "disabled";
+   };
+
+   pwm3: pwm@ff1b0030 {
+   compatible = "rockchip,rk3328-pwm";
+   reg = <0x0 0xff1b0030 0x0 0x10>;
+   interrupts = ;
+   #pwm-cells = <3>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pin>;
+   clocks = < SCLK_PWM>, < PCLK_PWM>;
+   clock-names = "pwm", "pclk";
+   status = "disabled";
+   };
+
saradc: adc@ff28 {
compatible = "rockchip,rk3328-saradc", "rockchip,rk3399-saradc";
reg = <0x0 0xff28 0x0 0x100>;
-- 
1.9.1




[PATCH v3 6/7] pwm: rockchip: Add rk3328 pwm support

2017-08-08 Thread David Wu
The rk3328 soc supports atomic update, we could lock the configuration
of period and duty at first, after unlock is configured, the period and
duty are effective at the same time.

If the polarity, period and duty need to be configured together,
the way for atomic update is "configure lock and old polarity" ->
"configure period and duty" -> "configure unlock and new polarity".

Signed-off-by: David Wu <david...@rock-chips.com>
Acked-by: Rob Herring <r...@kernel.org>
---
 drivers/pwm/pwm-rockchip.c | 43 +--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index a3fcb40..4d99d46 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -29,6 +29,7 @@
 #define PWM_INACTIVE_POSITIVE  (1 << 4)
 #define PWM_POLARITY_MASK  (PWM_DUTY_POSITIVE | PWM_INACTIVE_POSITIVE)
 #define PWM_OUTPUT_LEFT(0 << 5)
+#define PWM_LOCK_EN(1 << 6)
 #define PWM_LP_DISABLE (0 << 8)
 
 struct rockchip_pwm_chip {
@@ -50,6 +51,7 @@ struct rockchip_pwm_data {
struct rockchip_pwm_regs regs;
unsigned int prescaler;
bool supports_polarity;
+   bool supports_lock;
u32 enable_conf;
 };
 
@@ -121,10 +123,19 @@ static void rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
div = clk_rate * state->duty_cycle;
duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
 
+   /*
+* Lock the period and duty of previous configuration, then
+* change the duty and period, that would not be effective.
+*/
+   ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
+   if (pc->data->supports_lock) {
+   ctrl |= PWM_LOCK_EN;
+   writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl);
+   }
+
writel(period, pc->base + pc->data->regs.period);
writel(duty, pc->base + pc->data->regs.duty);
 
-   ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
if (pc->data->supports_polarity) {
ctrl &= ~PWM_POLARITY_MASK;
if (state->polarity == PWM_POLARITY_INVERSED)
@@ -132,6 +143,15 @@ static void rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
else
ctrl |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
}
+
+   /*
+* Unlock and set polarity at the same time,
+* the configuration of duty, period and polarity
+* would be effective together at next period.
+*/
+   if (pc->data->supports_lock)
+   ctrl &= ~PWM_LOCK_EN;
+
writel(ctrl, pc->base + pc->data->regs.ctrl);
 }
 
@@ -180,7 +200,8 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
pwm_get_state(pwm, );
enabled = curstate.enabled;
 
-   if (state->polarity != curstate.polarity && enabled) {
+   if (state->polarity != curstate.polarity && enabled &&
+   !pc->data->supports_lock) {
ret = rockchip_pwm_enable(chip, pwm, false);
if (ret)
goto out;
@@ -221,6 +242,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
},
.prescaler = 2,
.supports_polarity = false,
+   .supports_lock = false,
.enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN,
 };
 
@@ -233,6 +255,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
},
.prescaler = 1,
.supports_polarity = true,
+   .supports_lock = false,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
   PWM_CONTINUOUS,
 };
@@ -246,6 +269,21 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, 
struct pwm_device *pwm,
},
.prescaler = 1,
.supports_polarity = true,
+   .supports_lock = false,
+   .enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
+  PWM_CONTINUOUS,
+};
+
+static const struct rockchip_pwm_data pwm_data_v3 = {
+   .regs = {
+   .duty = 0x08,
+   .period = 0x04,
+   .cntr = 0x00,
+   .ctrl = 0x0c,
+   },
+   .prescaler = 1,
+   .supports_polarity = true,
+   .supports_lock = true,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
   PWM_CONTINUOUS,
 };
@@ -254,6 +292,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
{ .compatible = "rockchip,rk2928-pwm", .data = _data_v1},
{ .compatible = "rockchip,rk3288-pwm", .data = _data_v2},
{ .compatible = "rockchip,vop-pwm", .data = _data_vop},
+   { .compatible = "rockchip,rk3328-pwm", .data = _data_v3},
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids);
-- 
1.9.1




[PATCH v3 6/7] pwm: rockchip: Add rk3328 pwm support

2017-08-08 Thread David Wu
The rk3328 soc supports atomic update, we could lock the configuration
of period and duty at first, after unlock is configured, the period and
duty are effective at the same time.

If the polarity, period and duty need to be configured together,
the way for atomic update is "configure lock and old polarity" ->
"configure period and duty" -> "configure unlock and new polarity".

Signed-off-by: David Wu 
Acked-by: Rob Herring 
---
 drivers/pwm/pwm-rockchip.c | 43 +--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index a3fcb40..4d99d46 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -29,6 +29,7 @@
 #define PWM_INACTIVE_POSITIVE  (1 << 4)
 #define PWM_POLARITY_MASK  (PWM_DUTY_POSITIVE | PWM_INACTIVE_POSITIVE)
 #define PWM_OUTPUT_LEFT(0 << 5)
+#define PWM_LOCK_EN(1 << 6)
 #define PWM_LP_DISABLE (0 << 8)
 
 struct rockchip_pwm_chip {
@@ -50,6 +51,7 @@ struct rockchip_pwm_data {
struct rockchip_pwm_regs regs;
unsigned int prescaler;
bool supports_polarity;
+   bool supports_lock;
u32 enable_conf;
 };
 
@@ -121,10 +123,19 @@ static void rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
div = clk_rate * state->duty_cycle;
duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC);
 
+   /*
+* Lock the period and duty of previous configuration, then
+* change the duty and period, that would not be effective.
+*/
+   ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
+   if (pc->data->supports_lock) {
+   ctrl |= PWM_LOCK_EN;
+   writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl);
+   }
+
writel(period, pc->base + pc->data->regs.period);
writel(duty, pc->base + pc->data->regs.duty);
 
-   ctrl = readl_relaxed(pc->base + pc->data->regs.ctrl);
if (pc->data->supports_polarity) {
ctrl &= ~PWM_POLARITY_MASK;
if (state->polarity == PWM_POLARITY_INVERSED)
@@ -132,6 +143,15 @@ static void rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
else
ctrl |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE;
}
+
+   /*
+* Unlock and set polarity at the same time,
+* the configuration of duty, period and polarity
+* would be effective together at next period.
+*/
+   if (pc->data->supports_lock)
+   ctrl &= ~PWM_LOCK_EN;
+
writel(ctrl, pc->base + pc->data->regs.ctrl);
 }
 
@@ -180,7 +200,8 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
pwm_get_state(pwm, );
enabled = curstate.enabled;
 
-   if (state->polarity != curstate.polarity && enabled) {
+   if (state->polarity != curstate.polarity && enabled &&
+   !pc->data->supports_lock) {
ret = rockchip_pwm_enable(chip, pwm, false);
if (ret)
goto out;
@@ -221,6 +242,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
},
.prescaler = 2,
.supports_polarity = false,
+   .supports_lock = false,
.enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN,
 };
 
@@ -233,6 +255,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
},
.prescaler = 1,
.supports_polarity = true,
+   .supports_lock = false,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
   PWM_CONTINUOUS,
 };
@@ -246,6 +269,21 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, 
struct pwm_device *pwm,
},
.prescaler = 1,
.supports_polarity = true,
+   .supports_lock = false,
+   .enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
+  PWM_CONTINUOUS,
+};
+
+static const struct rockchip_pwm_data pwm_data_v3 = {
+   .regs = {
+   .duty = 0x08,
+   .period = 0x04,
+   .cntr = 0x00,
+   .ctrl = 0x0c,
+   },
+   .prescaler = 1,
+   .supports_polarity = true,
+   .supports_lock = true,
.enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
   PWM_CONTINUOUS,
 };
@@ -254,6 +292,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct 
pwm_device *pwm,
{ .compatible = "rockchip,rk2928-pwm", .data = _data_v1},
{ .compatible = "rockchip,rk3288-pwm", .data = _data_v2},
{ .compatible = "rockchip,vop-pwm", .data = _data_vop},
+   { .compatible = "rockchip,rk3328-pwm", .data = _data_v3},
{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids);
-- 
1.9.1




[PATCH v3 5/7] pwm: rockchip: Use same pwm ops for each IP

2017-08-08 Thread David Wu
Just use the same pwm ops for each IP, and get rid of the
ops in the struct of rockchip_pwm_data, but still define
the 3 different rockchip_pwm_data to use common interface
for each IP.

Signed-off-by: David Wu <david...@rock-chips.com>
---
 drivers/pwm/pwm-rockchip.c | 147 -
 1 file changed, 38 insertions(+), 109 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index fbd9c1a..a3fcb40 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -50,12 +50,7 @@ struct rockchip_pwm_data {
struct rockchip_pwm_regs regs;
unsigned int prescaler;
bool supports_polarity;
-   const struct pwm_ops *ops;
-
-   void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state);
-   int (*pwm_apply)(struct pwm_chip *chip, struct pwm_device *pwm,
-struct pwm_state *state);
+   u32 enable_conf;
 };
 
 static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip 
*c)
@@ -63,45 +58,15 @@ static inline struct rockchip_pwm_chip 
*to_rockchip_pwm_chip(struct pwm_chip *c)
return container_of(c, struct rockchip_pwm_chip, chip);
 }
 
-static void rockchip_pwm_get_state_v1(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
-{
-   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
-   u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
-   u32 val;
-
-   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
-   if ((val & enable_conf) == enable_conf)
-   state->enabled = true;
-}
-
-static void rockchip_pwm_get_state_v2(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
-{
-   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
-   u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
- PWM_CONTINUOUS;
-   u32 val;
-
-   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
-   if ((val & enable_conf) != enable_conf)
-   return;
-
-   state->enabled = true;
-
-   if (!(val & PWM_DUTY_POSITIVE))
-   state->polarity = PWM_POLARITY_INVERSED;
-}
-
 static void rockchip_pwm_get_state(struct pwm_chip *chip,
   struct pwm_device *pwm,
   struct pwm_state *state)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+   u32 enable_conf = pc->data->enable_conf;
unsigned long clk_rate;
u64 tmp;
+   u32 val;
int ret;
 
ret = clk_enable(pc->pclk);
@@ -116,9 +81,20 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
 
tmp = readl_relaxed(pc->base + pc->data->regs.duty);
tmp *= pc->data->prescaler * NSEC_PER_SEC;
-   state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
+   state->duty_cycle =  DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
 
-   pc->data->get_state(chip, pwm, state);
+   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
+   if (pc->data->supports_polarity)
+   state->enabled = ((val & enable_conf) != enable_conf) ?
+false : true;
+   else
+   state->enabled = ((val & enable_conf) == enable_conf) ?
+true : false;
+
+   if (pc->data->supports_polarity) {
+   if (!(val & PWM_DUTY_POSITIVE))
+   state->polarity = PWM_POLARITY_INVERSED;
+   }
 
clk_disable(pc->pclk);
 }
@@ -161,10 +137,10 @@ static void rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
 
 static int rockchip_pwm_enable(struct pwm_chip *chip,
   struct pwm_device *pwm,
-  bool enable,
-  u32 enable_conf)
+  bool enable)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+   u32 enable_conf = pc->data->enable_conf;
int ret;
u32 val;
 
@@ -189,73 +165,35 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
return 0;
 }
 
-static int rockchip_pwm_apply_v1(struct pwm_chip *chip, struct pwm_device *pwm,
-struct pwm_state *state)
+static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
 {
-   u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
+   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
struct pwm_state curstate;
bool enabled;
int ret = 0

[PATCH v3 5/7] pwm: rockchip: Use same pwm ops for each IP

2017-08-08 Thread David Wu
Just use the same pwm ops for each IP, and get rid of the
ops in the struct of rockchip_pwm_data, but still define
the 3 different rockchip_pwm_data to use common interface
for each IP.

Signed-off-by: David Wu 
---
 drivers/pwm/pwm-rockchip.c | 147 -
 1 file changed, 38 insertions(+), 109 deletions(-)

diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c
index fbd9c1a..a3fcb40 100644
--- a/drivers/pwm/pwm-rockchip.c
+++ b/drivers/pwm/pwm-rockchip.c
@@ -50,12 +50,7 @@ struct rockchip_pwm_data {
struct rockchip_pwm_regs regs;
unsigned int prescaler;
bool supports_polarity;
-   const struct pwm_ops *ops;
-
-   void (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm,
- struct pwm_state *state);
-   int (*pwm_apply)(struct pwm_chip *chip, struct pwm_device *pwm,
-struct pwm_state *state);
+   u32 enable_conf;
 };
 
 static inline struct rockchip_pwm_chip *to_rockchip_pwm_chip(struct pwm_chip 
*c)
@@ -63,45 +58,15 @@ static inline struct rockchip_pwm_chip 
*to_rockchip_pwm_chip(struct pwm_chip *c)
return container_of(c, struct rockchip_pwm_chip, chip);
 }
 
-static void rockchip_pwm_get_state_v1(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
-{
-   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
-   u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
-   u32 val;
-
-   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
-   if ((val & enable_conf) == enable_conf)
-   state->enabled = true;
-}
-
-static void rockchip_pwm_get_state_v2(struct pwm_chip *chip,
- struct pwm_device *pwm,
- struct pwm_state *state)
-{
-   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
-   u32 enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE |
- PWM_CONTINUOUS;
-   u32 val;
-
-   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
-   if ((val & enable_conf) != enable_conf)
-   return;
-
-   state->enabled = true;
-
-   if (!(val & PWM_DUTY_POSITIVE))
-   state->polarity = PWM_POLARITY_INVERSED;
-}
-
 static void rockchip_pwm_get_state(struct pwm_chip *chip,
   struct pwm_device *pwm,
   struct pwm_state *state)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+   u32 enable_conf = pc->data->enable_conf;
unsigned long clk_rate;
u64 tmp;
+   u32 val;
int ret;
 
ret = clk_enable(pc->pclk);
@@ -116,9 +81,20 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip,
 
tmp = readl_relaxed(pc->base + pc->data->regs.duty);
tmp *= pc->data->prescaler * NSEC_PER_SEC;
-   state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
+   state->duty_cycle =  DIV_ROUND_CLOSEST_ULL(tmp, clk_rate);
 
-   pc->data->get_state(chip, pwm, state);
+   val = readl_relaxed(pc->base + pc->data->regs.ctrl);
+   if (pc->data->supports_polarity)
+   state->enabled = ((val & enable_conf) != enable_conf) ?
+false : true;
+   else
+   state->enabled = ((val & enable_conf) == enable_conf) ?
+true : false;
+
+   if (pc->data->supports_polarity) {
+   if (!(val & PWM_DUTY_POSITIVE))
+   state->polarity = PWM_POLARITY_INVERSED;
+   }
 
clk_disable(pc->pclk);
 }
@@ -161,10 +137,10 @@ static void rockchip_pwm_config(struct pwm_chip *chip, 
struct pwm_device *pwm,
 
 static int rockchip_pwm_enable(struct pwm_chip *chip,
   struct pwm_device *pwm,
-  bool enable,
-  u32 enable_conf)
+  bool enable)
 {
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
+   u32 enable_conf = pc->data->enable_conf;
int ret;
u32 val;
 
@@ -189,73 +165,35 @@ static int rockchip_pwm_enable(struct pwm_chip *chip,
return 0;
 }
 
-static int rockchip_pwm_apply_v1(struct pwm_chip *chip, struct pwm_device *pwm,
-struct pwm_state *state)
+static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ struct pwm_state *state)
 {
-   u32 enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN;
+   struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
struct pwm_state curstate;
bool enabled;
int ret = 0;
 
+   ret = clk_ena

  1   2   3   4   >