On 24/02/2021 20:33, Neil Armstrong wrote: > This adds a proper glue driver for the Designware DWMAC ethernet MAC IP > found in the Amlogic Meson8, GXBB, GXL, GXM, G12A, G12B & SM1 SoCs. > > This is aimed to replace the static ethernet link setup found on the board > init code for the Amlogic SoC based boards. > > Tested on a libretech-cc (S905x Internal RMII 10/100 PHY) and Khadas VIM3 > (A113d > with external 10/100/1000 RGMII PHY) to cover the most extreme setups. > > Signed-off-by: Neil Armstrong <narmstr...@baylibre.com> > --- > drivers/net/Kconfig | 8 ++ > drivers/net/Makefile | 1 + > drivers/net/dwmac_meson8b.c | 150 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 159 insertions(+) > create mode 100644 drivers/net/dwmac_meson8b.c > > diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig > index e1d3b26687..cf062fad4d 100644 > --- a/drivers/net/Kconfig > +++ b/drivers/net/Kconfig > @@ -271,6 +271,14 @@ config ETH_DESIGNWARE > 100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to > provide the PHY (physical media interface). > > +config ETH_DESIGNWARE_MESON8B > + bool "Amlogic Meson8b and later glue driver for Synopsys Designware > Ethernet MAC" > + depends on DM_ETH > + select ETH_DESIGNWARE > + help > + This provides glue layer to use Synopsys Designware Ethernet MAC > + present on the Amlogic Meson8b, GX, AXG & G12A SoCs. > + > config ETH_DESIGNWARE_SOCFPGA > select REGMAP > select SYSCON > diff --git a/drivers/net/Makefile b/drivers/net/Makefile > index 070ae7662c..ce7b9e3478 100644 > --- a/drivers/net/Makefile > +++ b/drivers/net/Makefile > @@ -18,6 +18,7 @@ obj-$(CONFIG_CORTINA_NI_ENET) += cortina_ni.o > obj-$(CONFIG_CS8900) += cs8900.o > obj-$(CONFIG_TULIP) += dc2114x.o > obj-$(CONFIG_ETH_DESIGNWARE) += designware.o > +obj-$(CONFIG_ETH_DESIGNWARE_MESON8B) += dwmac_meson8b.o > obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o > obj-$(CONFIG_ETH_DESIGNWARE_S700) += dwmac_s700.o > obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o > diff --git a/drivers/net/dwmac_meson8b.c b/drivers/net/dwmac_meson8b.c > new file mode 100644 > index 0000000000..c0b6ef4994 > --- /dev/null > +++ b/drivers/net/dwmac_meson8b.c > @@ -0,0 +1,150 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2021 BayLibre, SAS > + */ > + > +#include <common.h> > +#include <asm/io.h> > +#include <dm.h> > +#include <phy.h> > +#include "designware.h" > +#include <dm/device_compat.h> > +#include <linux/err.h> > + > +#define ETH_REG_0 0x0 > +#define ETH_REG_1 0x4 > +#define ETH_REG_2 0x18 > +#define ETH_REG_3 0x1c > + > +#define GX_ETH_REG_0_PHY_INTF BIT(0) > +#define GX_ETH_REG_0_TX_PHASE(x) (((x) & 3) << 5) > +#define GX_ETH_REG_0_TX_RATIO(x) (((x) & 7) << 7) > +#define GX_ETH_REG_0_PHY_CLK_EN BIT(10) > +#define GX_ETH_REG_0_INVERT_RMII_CLK BIT(11) > +#define GX_ETH_REG_0_CLK_EN BIT(12) > + > +#define AXG_ETH_REG_0_PHY_INTF_RGMII BIT(0) > +#define AXG_ETH_REG_0_PHY_INTF_RMII BIT(2) > +#define AXG_ETH_REG_0_TX_PHASE(x) (((x) & 3) << 5) > +#define AXG_ETH_REG_0_TX_RATIO(x) (((x) & 7) << 7) > +#define AXG_ETH_REG_0_PHY_CLK_EN BIT(10) > +#define AXG_ETH_REG_0_INVERT_RMII_CLK BIT(11) > +#define AXG_ETH_REG_0_CLK_EN BIT(12) > + > +struct dwmac_meson8b_plat { > + struct dw_eth_pdata dw_eth_pdata; > + int (*dwmac_setup)(struct udevice *dev, struct eth_pdata *edata); > + void *regs; > +}; > + > +static int dwmac_meson8b_of_to_plat(struct udevice *dev) > +{ > + struct dwmac_meson8b_plat *pdata = dev_get_plat(dev); > + > + pdata->regs = (void *)dev_read_addr_index(dev, 1); > + if ((fdt_addr_t)pdata->regs == FDT_ADDR_T_NONE) > + return -EINVAL; > + > + pdata->dwmac_setup = (void *)dev_get_driver_data(dev); > + if (!pdata->dwmac_setup) > + return -EINVAL; > + > + return designware_eth_of_to_plat(dev); > +} > + > +static int dwmac_setup_axg(struct udevice *dev, struct eth_pdata *edata) > +{ > + struct dwmac_meson8b_plat *plat = dev_get_plat(dev); > + > + switch (edata->phy_interface) { > + case PHY_INTERFACE_MODE_RGMII: > + case PHY_INTERFACE_MODE_RGMII_ID: > + case PHY_INTERFACE_MODE_RGMII_RXID: > + case PHY_INTERFACE_MODE_RGMII_TXID: > + /* Set RGMII mode */ > + setbits_le32(plat->regs + ETH_REG_0, > AXG_ETH_REG_0_PHY_INTF_RGMII | > + AXG_ETH_REG_0_TX_PHASE(1) | > + AXG_ETH_REG_0_TX_RATIO(4) | > + AXG_ETH_REG_0_PHY_CLK_EN | > + AXG_ETH_REG_0_CLK_EN); > + break; > + > + case PHY_INTERFACE_MODE_RMII: > + /* Set RMII mode */ > + out_le32(plat->regs + ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RMII | > + AXG_ETH_REG_0_INVERT_RMII_CLK | > + AXG_ETH_REG_0_CLK_EN); > + break; > + default: > + dev_err(dev, "Unsupported PHY mode\n"); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int dwmac_setup_gx(struct udevice *dev, struct eth_pdata *edata) > +{ > + struct dwmac_meson8b_plat *plat = dev_get_plat(dev); > + > + switch (edata->phy_interface) { > + case PHY_INTERFACE_MODE_RGMII: > + case PHY_INTERFACE_MODE_RGMII_ID: > + case PHY_INTERFACE_MODE_RGMII_RXID: > + case PHY_INTERFACE_MODE_RGMII_TXID: > + /* Set RGMII mode */ > + setbits_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_PHY_INTF | > + GX_ETH_REG_0_TX_PHASE(1) | > + GX_ETH_REG_0_TX_RATIO(4) | > + GX_ETH_REG_0_PHY_CLK_EN | > + GX_ETH_REG_0_CLK_EN); > + > + break; > + > + case PHY_INTERFACE_MODE_RMII: > + /* Set RMII mode */ > + out_le32(plat->regs + ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK | > + GX_ETH_REG_0_CLK_EN); > + > + if (!IS_ENABLED(CONFIG_MESON_GXBB)) > + writel(0x10110181, plat->regs + ETH_REG_2); > + > + break; > + default: > + dev_err(dev, "Unsupported PHY mode\n"); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int dwmac_meson8b_probe(struct udevice *dev) > +{ > + struct dwmac_meson8b_plat *pdata = dev_get_plat(dev); > + struct eth_pdata *edata = &pdata->dw_eth_pdata.eth_pdata; > + int ret; > + > + ret = pdata->dwmac_setup(dev, edata); > + if (ret) > + return ret; > + > + return designware_eth_probe(dev); > +} > + > +static const struct udevice_id dwmac_meson8b_ids[] = { > + { .compatible = "amlogic,meson-gxbb-dwmac", .data = > (ulong)dwmac_setup_gx }, > + { .compatible = "amlogic,meson-axg-dwmac", .data = > (ulong)dwmac_setup_axg }, > + { } > +}; > + > +U_BOOT_DRIVER(dwmac_meson8b) = { > + .name = "dwmac_meson8b", > + .id = UCLASS_ETH, > + .of_match = dwmac_meson8b_ids, > + .of_to_plat = dwmac_meson8b_of_to_plat, > + .probe = dwmac_meson8b_probe, > + .ops = &designware_eth_ops, > + .priv_auto = sizeof(struct dw_eth_dev), > + .plat_auto = sizeof(struct dwmac_meson8b_plat), > + .flags = DM_FLAG_ALLOC_PRIV_DMA, > +}; >
Applied to u-boot-amlogic-next