Change the original data structure so that Rockchip's Soc
gmac controller can support the designware.c and dwc_eth_qos.c
drivers, a Soc can only support one.

Signed-off-by: David Wu <david...@rock-chips.com>
---

Changes in v2:
- None

 drivers/net/Kconfig         |   2 +-
 drivers/net/gmac_rockchip.c | 160 ++++++++++++++++++++++++++++++------
 2 files changed, 135 insertions(+), 27 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 38f2bd6637..d29adebee0 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -490,7 +490,7 @@ config PIC32_ETH
 
 config GMAC_ROCKCHIP
        bool "Rockchip Synopsys Designware Ethernet MAC"
-       depends on DM_ETH && ETH_DESIGNWARE
+       depends on DM_ETH && (ETH_DESIGNWARE || DWC_ETH_QOS)
        help
          This driver provides Rockchip SoCs network support based on the
          Synopsys Designware driver.
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index e152faf083..aa2bab4203 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -25,26 +25,39 @@
 #include <dm/pinctrl.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 #include "designware.h"
+#include "dwc_eth_qos.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 #define DELAY_ENABLE(soc, tx, rx) \
        (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : 
soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \
        ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : 
soc##_RXCLK_DLY_ENA_GMAC_DISABLE))
 
+struct rockchip_eth_dev {
+       union {
+               struct eqos_priv eqos;
+               struct dw_eth_dev dw;
+       };
+};
+
 /*
  * Platform data for the gmac
  *
  * dw_eth_pdata: Required platform data for designware driver (must be first)
  */
 struct gmac_rockchip_platdata {
-       struct dw_eth_pdata dw_eth_pdata;
+       union {
+               struct dw_eth_pdata dw_eth_pdata;
+               struct eth_pdata eth_pdata;
+       };
+       bool has_gmac4;
        bool clock_input;
        int tx_delay;
        int rx_delay;
 };
 
 struct rk_gmac_ops {
-       int (*fix_mac_speed)(struct dw_eth_dev *priv);
+       const struct eqos_config config;
+       int (*fix_mac_speed)(struct rockchip_eth_dev *dev);
        void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
        void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
 };
@@ -55,6 +68,9 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice 
*dev)
        struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
        const char *string;
 
+       if (device_is_compatible(dev, "snps,dwmac-4.20a"))
+               pdata->has_gmac4 = true;
+
        string = dev_read_string(dev, "clock_in_out");
        if (!strcmp(string, "input"))
                pdata->clock_input = true;
@@ -71,11 +87,15 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice 
*dev)
        if (pdata->rx_delay == -ENOENT)
                pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
 
-       return designware_eth_ofdata_to_platdata(dev);
+       if (!pdata->has_gmac4)
+               return designware_eth_ofdata_to_platdata(dev);
+
+       return 0;
 }
 
-static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+static int px30_gmac_fix_mac_speed(struct rockchip_eth_dev *dev)
 {
+       struct dw_eth_dev *priv = &dev->dw;
        struct px30_grf *grf;
        struct clk clk_speed;
        int speed, ret;
@@ -115,8 +135,9 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
        return 0;
 }
 
-static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+static int rk3228_gmac_fix_mac_speed(struct rockchip_eth_dev *dev)
 {
+       struct dw_eth_dev *priv = &dev->dw;
        struct rk322x_grf *grf;
        int clk;
        enum {
@@ -148,8 +169,9 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev 
*priv)
        return 0;
 }
 
-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+static int rk3288_gmac_fix_mac_speed(struct rockchip_eth_dev *dev)
 {
+       struct dw_eth_dev *priv = &dev->dw;
        struct rk3288_grf *grf;
        int clk;
 
@@ -174,8 +196,9 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev 
*priv)
        return 0;
 }
 
-static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+static int rk3308_gmac_fix_mac_speed(struct rockchip_eth_dev *dev)
 {
+       struct dw_eth_dev *priv = &dev->dw;
        struct rk3308_grf *grf;
        struct clk clk_speed;
        int speed, ret;
@@ -215,8 +238,9 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev 
*priv)
        return 0;
 }
 
-static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+static int rk3328_gmac_fix_mac_speed(struct rockchip_eth_dev *dev)
 {
+       struct dw_eth_dev *priv = &dev->dw;
        struct rk3328_grf_regs *grf;
        int clk;
        enum {
@@ -248,8 +272,9 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev 
*priv)
        return 0;
 }
 
-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+static int rk3368_gmac_fix_mac_speed(struct rockchip_eth_dev *dev)
 {
+       struct dw_eth_dev *priv = &dev->dw;
        struct rk3368_grf *grf;
        int clk;
        enum {
@@ -280,8 +305,9 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev 
*priv)
        return 0;
 }
 
-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+static int rk3399_gmac_fix_mac_speed(struct rockchip_eth_dev *dev)
 {
+       struct dw_eth_dev *priv = &dev->dw;
        struct rk3399_grf_regs *grf;
        int clk;
 
@@ -306,8 +332,9 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev 
*priv)
        return 0;
 }
 
-static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
+static int rv1108_set_rmii_speed(struct rockchip_eth_dev *dev)
 {
+       struct dw_eth_dev *priv = &dev->dw;
        struct rv1108_grf *grf;
        int clk, speed;
        enum {
@@ -555,12 +582,22 @@ static int gmac_rockchip_probe(struct udevice *dev)
        struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
        struct rk_gmac_ops *ops =
                (struct rk_gmac_ops *)dev_get_driver_data(dev);
-       struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
-       struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
+       struct dw_eth_pdata *dw_pdata;
+       struct eth_pdata *eth_pdata;
+       struct eqos_config *config;
        struct clk clk;
        ulong rate;
        int ret;
 
+       if (pdata->has_gmac4) {
+               eth_pdata = &pdata->eth_pdata;
+               config = (struct eqos_config *)&ops->config;
+               eth_pdata->phy_interface = config->ops->eqos_get_interface(dev);
+       } else {
+               dw_pdata = &pdata->dw_eth_pdata;
+               eth_pdata = &dw_pdata->eth_pdata;
+       }
+
        ret = clk_set_defaults(dev, 0);
        if (ret)
                debug("%s clk_set_defaults failed %d\n", __func__, ret);
@@ -656,37 +693,108 @@ static int gmac_rockchip_probe(struct udevice *dev)
                return -ENXIO;
        }
 
-       return designware_eth_probe(dev);
+       if (pdata->has_gmac4)
+               return eqos_probe(dev);
+       else
+               return designware_eth_probe(dev);
+}
+
+static int gmac_rockchip_eth_write_hwaddr(struct udevice *dev)
+{
+       struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
+
+       if (pdata->has_gmac4)
+               return eqos_write_hwaddr(dev);
+       else
+               return designware_eth_write_hwaddr(dev);
+}
+
+static int gmac_rockchip_eth_free_pkt(struct udevice *dev, uchar *packet,
+                                     int length)
+{
+       struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
+
+       if (pdata->has_gmac4)
+               return eqos_free_pkt(dev, packet, length);
+       else
+               return designware_eth_free_pkt(dev, packet, length);
+}
+
+static int gmac_rockchip_eth_send(struct udevice *dev, void *packet,
+                                 int length)
+{
+       struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
+
+       if (pdata->has_gmac4)
+               return eqos_send(dev, packet, length);
+       else
+               return designware_eth_send(dev, packet, length);
+}
+
+static int gmac_rockchip_eth_recv(struct udevice *dev, int flags,
+                                 uchar **packetp)
+{
+       struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
+
+       if (pdata->has_gmac4)
+               return eqos_recv(dev, flags, packetp);
+       else
+               return designware_eth_recv(dev, flags, packetp);
 }
 
 static int gmac_rockchip_eth_start(struct udevice *dev)
 {
-       struct eth_pdata *pdata = dev_get_platdata(dev);
-       struct dw_eth_dev *priv = dev_get_priv(dev);
+       struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
+       struct rockchip_eth_dev *priv = dev_get_priv(dev);
        struct rk_gmac_ops *ops =
                (struct rk_gmac_ops *)dev_get_driver_data(dev);
+       struct dw_eth_pdata *dw_pdata;
+       struct eth_pdata *eth_pdata;
        int ret;
 
-       ret = designware_eth_init(priv, pdata->enetaddr);
+       if (pdata->has_gmac4) {
+               ret = eqos_init(dev);
+       } else {
+               dw_pdata = &pdata->dw_eth_pdata;
+               eth_pdata = &dw_pdata->eth_pdata;
+               ret = designware_eth_init((struct dw_eth_dev *)priv,
+                                         eth_pdata->enetaddr);
+       }
        if (ret)
                return ret;
+
        ret = ops->fix_mac_speed(priv);
        if (ret)
                return ret;
-       ret = designware_eth_enable(priv);
-       if (ret)
-               return ret;
+
+       if (pdata->has_gmac4) {
+               eqos_enable(dev);
+       } else {
+               ret = designware_eth_enable((struct dw_eth_dev *)priv);
+               if (ret)
+                       return ret;
+       }
 
        return 0;
 }
 
+static void gmac_rockchip_eth_stop(struct udevice *dev)
+{
+       struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
+
+       if (pdata->has_gmac4)
+               eqos_stop(dev);
+       else
+               designware_eth_stop(dev);
+}
+
 const struct eth_ops gmac_rockchip_eth_ops = {
        .start                  = gmac_rockchip_eth_start,
-       .send                   = designware_eth_send,
-       .recv                   = designware_eth_recv,
-       .free_pkt               = designware_eth_free_pkt,
-       .stop                   = designware_eth_stop,
-       .write_hwaddr           = designware_eth_write_hwaddr,
+       .send                   = gmac_rockchip_eth_send,
+       .recv                   = gmac_rockchip_eth_recv,
+       .free_pkt               = gmac_rockchip_eth_free_pkt,
+       .stop                   = gmac_rockchip_eth_stop,
+       .write_hwaddr           = gmac_rockchip_eth_write_hwaddr,
 };
 
 const struct rk_gmac_ops px30_gmac_ops = {
@@ -756,7 +864,7 @@ U_BOOT_DRIVER(eth_gmac_rockchip) = {
        .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
        .probe  = gmac_rockchip_probe,
        .ops    = &gmac_rockchip_eth_ops,
-       .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
+       .priv_auto_alloc_size = sizeof(struct rockchip_eth_dev),
        .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
        .flags = DM_FLAG_ALLOC_PRIV_DMA,
 };
-- 
2.19.1



Reply via email to