net: gmac_rockchip: Add dwc_eth_qos support

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.wu@rock-chips.com>
Change-Id: I313674274fc2eddb7717ba76c537cd668d6a492b
This commit is contained in:
David Wu 2020-04-30 17:38:35 +08:00 committed by Joseph Chen
parent a494aeaa44
commit 6f0a52e952
2 changed files with 145 additions and 25 deletions

View File

@ -276,7 +276,7 @@ config PIC32_ETH
config GMAC_ROCKCHIP config GMAC_ROCKCHIP
bool "Rockchip Synopsys Designware Ethernet MAC" bool "Rockchip Synopsys Designware Ethernet MAC"
depends on DM_ETH && ETH_DESIGNWARE depends on DM_ETH && (ETH_DESIGNWARE || DWC_ETH_QOS)
help help
This driver provides Rockchip SoCs network support based on the This driver provides Rockchip SoCs network support based on the
Synopsys Designware driver. Synopsys Designware driver.

View File

@ -15,6 +15,9 @@
#include <asm/arch/periph.h> #include <asm/arch/periph.h>
#include <asm/arch/clock.h> #include <asm/arch/clock.h>
#include <asm/arch/hardware.h> #include <asm/arch/hardware.h>
#ifdef CONFIG_DWC_ETH_QOS
#include "dwc_eth_qos.h"
#else
#include <asm/arch/grf_px30.h> #include <asm/arch/grf_px30.h>
#include <asm/arch/grf_rk1808.h> #include <asm/arch/grf_rk1808.h>
#include <asm/arch/grf_rk322x.h> #include <asm/arch/grf_rk322x.h>
@ -24,26 +27,42 @@
#include <asm/arch/grf_rk3368.h> #include <asm/arch/grf_rk3368.h>
#include <asm/arch/grf_rk3399.h> #include <asm/arch/grf_rk3399.h>
#include <asm/arch/grf_rv1108.h> #include <asm/arch/grf_rv1108.h>
#include <dm/pinctrl.h>
#include <dt-bindings/clock/rk3288-cru.h>
#include "designware.h" #include "designware.h"
#include <dt-bindings/clock/rk3288-cru.h>
#endif
#include <dm/pinctrl.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
struct rockchip_eth_dev {
#ifdef CONFIG_DWC_ETH_QOS
struct eqos_priv eqos;
#else
struct dw_eth_dev dw;
#endif
};
/* /*
* Platform data for the gmac * Platform data for the gmac
* *
* dw_eth_pdata: Required platform data for designware driver (must be first) * dw_eth_pdata: Required platform data for designware driver (must be first)
*/ */
struct gmac_rockchip_platdata { struct gmac_rockchip_platdata {
#ifndef CONFIG_DWC_ETH_QOS
struct dw_eth_pdata dw_eth_pdata; struct dw_eth_pdata dw_eth_pdata;
#else
struct eth_pdata eth_pdata;
#endif
bool clock_input; bool clock_input;
int tx_delay; int tx_delay;
int rx_delay; int rx_delay;
}; };
struct rk_gmac_ops { struct rk_gmac_ops {
int (*fix_mac_speed)(struct dw_eth_dev *priv); #ifdef CONFIG_DWC_ETH_QOS
const struct eqos_config config;
#endif
int (*fix_mac_speed)(struct rockchip_eth_dev *dev);
void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
}; };
@ -81,11 +100,17 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
if (pdata->rx_delay == -ENOENT) if (pdata->rx_delay == -ENOENT)
pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10); pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
#ifdef CONFIG_DWC_ETH_QOS
return 0;
#else
return designware_eth_ofdata_to_platdata(dev); return designware_eth_ofdata_to_platdata(dev);
#endif
} }
static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) #ifndef CONFIG_DWC_ETH_QOS
static int px30_gmac_fix_mac_speed(struct rockchip_eth_dev *dev)
{ {
struct dw_eth_dev *priv = &dev->dw;
struct px30_grf *grf; struct px30_grf *grf;
struct clk clk_speed; struct clk clk_speed;
int speed, ret; int speed, ret;
@ -125,8 +150,9 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
return 0; return 0;
} }
static int rk1808_gmac_fix_mac_speed(struct dw_eth_dev *priv) static int rk1808_gmac_fix_mac_speed(struct rockchip_eth_dev *dev)
{ {
struct dw_eth_dev *priv = &dev->dw;
struct clk clk_speed; struct clk clk_speed;
int ret; int ret;
@ -159,8 +185,9 @@ static int rk1808_gmac_fix_mac_speed(struct dw_eth_dev *priv)
return 0; 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; struct rk322x_grf *grf;
int clk; int clk;
enum { enum {
@ -192,8 +219,9 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
return 0; 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; struct rk3288_grf *grf;
int clk; int clk;
@ -218,8 +246,9 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
return 0; 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 rk3308_grf *grf;
struct clk clk_speed; struct clk clk_speed;
int speed, ret; int speed, ret;
@ -259,8 +288,9 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv)
return 0; 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; struct rk3328_grf_regs *grf;
int clk; int clk;
enum { enum {
@ -292,8 +322,9 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
return 0; 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; struct rk3368_grf *grf;
int clk; int clk;
enum { enum {
@ -324,8 +355,9 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
return 0; 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; struct rk3399_grf_regs *grf;
int clk; int clk;
@ -350,8 +382,9 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
return 0; 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; struct rv1108_grf *grf;
int clk, speed; int clk, speed;
enum { enum {
@ -384,7 +417,9 @@ static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
return 0; return 0;
} }
#endif
#ifndef CONFIG_DWC_ETH_QOS
static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
{ {
struct px30_grf *grf; struct px30_grf *grf;
@ -638,18 +673,31 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
RV1108_GMAC_PHY_INTF_SEL_MASK, RV1108_GMAC_PHY_INTF_SEL_MASK,
RV1108_GMAC_PHY_INTF_SEL_RMII); RV1108_GMAC_PHY_INTF_SEL_RMII);
} }
#endif
static int gmac_rockchip_probe(struct udevice *dev) static int gmac_rockchip_probe(struct udevice *dev)
{ {
struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
struct rk_gmac_ops *ops = struct rk_gmac_ops *ops =
(struct rk_gmac_ops *)dev_get_driver_data(dev); (struct rk_gmac_ops *)dev_get_driver_data(dev);
struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev); #ifdef CONFIG_DWC_ETH_QOS
struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata; struct eqos_config *config;
#else
struct dw_eth_pdata *dw_pdata;
#endif
struct eth_pdata *eth_pdata;
struct clk clk; struct clk clk;
ulong rate; ulong rate;
int ret; int ret;
#ifdef CONFIG_DWC_ETH_QOS
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;
#endif
/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
ret = clk_set_defaults(dev); ret = clk_set_defaults(dev);
if (ret) if (ret)
@ -700,39 +748,108 @@ static int gmac_rockchip_probe(struct udevice *dev)
return -ENXIO; return -ENXIO;
} }
#ifdef CONFIG_DWC_ETH_QOS
return eqos_probe(dev);
#else
return designware_eth_probe(dev); return designware_eth_probe(dev);
#endif
}
static int gmac_rockchip_eth_write_hwaddr(struct udevice *dev)
{
#if defined(CONFIG_DWC_ETH_QOS)
return eqos_write_hwaddr(dev);
#else
return designware_eth_write_hwaddr(dev);
#endif
}
static int gmac_rockchip_eth_free_pkt(struct udevice *dev, uchar *packet,
int length)
{
#ifdef CONFIG_DWC_ETH_QOS
return eqos_free_pkt(dev, packet, length);
#else
return designware_eth_free_pkt(dev, packet, length);
#endif
}
static int gmac_rockchip_eth_send(struct udevice *dev, void *packet,
int length)
{
#ifdef CONFIG_DWC_ETH_QOS
return eqos_send(dev, packet, length);
#else
return designware_eth_send(dev, packet, length);
#endif
}
static int gmac_rockchip_eth_recv(struct udevice *dev, int flags,
uchar **packetp)
{
#ifdef CONFIG_DWC_ETH_QOS
return eqos_recv(dev, flags, packetp);
#else
return designware_eth_recv(dev, flags, packetp);
#endif
} }
static int gmac_rockchip_eth_start(struct udevice *dev) static int gmac_rockchip_eth_start(struct udevice *dev)
{ {
struct eth_pdata *pdata = dev_get_platdata(dev); struct rockchip_eth_dev *priv = dev_get_priv(dev);
struct dw_eth_dev *priv = dev_get_priv(dev);
struct rk_gmac_ops *ops = struct rk_gmac_ops *ops =
(struct rk_gmac_ops *)dev_get_driver_data(dev); (struct rk_gmac_ops *)dev_get_driver_data(dev);
#ifndef CONFIG_DWC_ETH_QOS
struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
struct dw_eth_pdata *dw_pdata;
struct eth_pdata *eth_pdata;
#endif
int ret; int ret;
ret = designware_eth_init(priv, pdata->enetaddr); #ifdef CONFIG_DWC_ETH_QOS
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);
#endif
if (ret) if (ret)
return ret; return ret;
ret = ops->fix_mac_speed(priv); ret = ops->fix_mac_speed(priv);
if (ret) if (ret)
return ret; return ret;
ret = designware_eth_enable(priv);
#ifdef CONFIG_DWC_ETH_QOS
eqos_enable(dev);
#else
ret = designware_eth_enable((struct dw_eth_dev *)priv);
if (ret) if (ret)
return ret; return ret;
#endif
return 0; return 0;
} }
static void gmac_rockchip_eth_stop(struct udevice *dev)
{
#ifdef CONFIG_DWC_ETH_QOS
eqos_stop(dev);
#else
designware_eth_stop(dev);
#endif
}
const struct eth_ops gmac_rockchip_eth_ops = { const struct eth_ops gmac_rockchip_eth_ops = {
.start = gmac_rockchip_eth_start, .start = gmac_rockchip_eth_start,
.send = designware_eth_send, .send = gmac_rockchip_eth_send,
.recv = designware_eth_recv, .recv = gmac_rockchip_eth_recv,
.free_pkt = designware_eth_free_pkt, .free_pkt = gmac_rockchip_eth_free_pkt,
.stop = designware_eth_stop, .stop = gmac_rockchip_eth_stop,
.write_hwaddr = designware_eth_write_hwaddr, .write_hwaddr = gmac_rockchip_eth_write_hwaddr,
}; };
#ifndef CONFIG_DWC_ETH_QOS
const struct rk_gmac_ops px30_gmac_ops = { const struct rk_gmac_ops px30_gmac_ops = {
.fix_mac_speed = px30_gmac_fix_mac_speed, .fix_mac_speed = px30_gmac_fix_mac_speed,
.set_to_rmii = px30_gmac_set_to_rmii, .set_to_rmii = px30_gmac_set_to_rmii,
@ -777,8 +894,10 @@ const struct rk_gmac_ops rv1108_gmac_ops = {
.fix_mac_speed = rv1108_set_rmii_speed, .fix_mac_speed = rv1108_set_rmii_speed,
.set_to_rmii = rv1108_gmac_set_to_rmii, .set_to_rmii = rv1108_gmac_set_to_rmii,
}; };
#endif
static const struct udevice_id rockchip_gmac_ids[] = { static const struct udevice_id rockchip_gmac_ids[] = {
#ifndef CONFIG_DWC_ETH_QOS
{ .compatible = "rockchip,px30-gmac", { .compatible = "rockchip,px30-gmac",
.data = (ulong)&px30_gmac_ops }, .data = (ulong)&px30_gmac_ops },
{ .compatible = "rockchip,rk1808-gmac", { .compatible = "rockchip,rk1808-gmac",
@ -797,6 +916,7 @@ static const struct udevice_id rockchip_gmac_ids[] = {
.data = (ulong)&rk3399_gmac_ops }, .data = (ulong)&rk3399_gmac_ops },
{ .compatible = "rockchip,rv1108-gmac", { .compatible = "rockchip,rv1108-gmac",
.data = (ulong)&rv1108_gmac_ops }, .data = (ulong)&rv1108_gmac_ops },
#endif
{ } { }
}; };
@ -807,7 +927,7 @@ U_BOOT_DRIVER(eth_gmac_rockchip) = {
.ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata, .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
.probe = gmac_rockchip_probe, .probe = gmac_rockchip_probe,
.ops = &gmac_rockchip_eth_ops, .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), .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
.flags = DM_FLAG_ALLOC_PRIV_DMA, .flags = DM_FLAG_ALLOC_PRIV_DMA,
}; };