[U-Boot] [PATCH v7 0/5] net: fec_mxc: Convert to DM

From: Jagan Teki jagan@amarulasolutions.com
This series convert fec_mxc to DM and tested both dm and non-dm code and it is on top of [1] with u-boot-imx/master branch.
Changes for v7: - Remove fec_set_dev_name in dm probe
Changes for v6: - Add Acked-by tags in commit message
Changes for v5: - Add stub fec calls to minimize the #ifdef's - Use same func names on eth_ops - Remove reset_gpio in fec_mxc.h - Add new patches, for cleanup driver
Changes for v4: - rebase to u-boot-imx/master
Changes for v3: - Add ARM: dts: imx6qdl-icore: Add FEC support - icorem6: Use CONFIG_DM_ETH support
Changes for v2: - Add TODO for implementing the enet reset code
[1] [PATCH v7 00/21] imx6: Add Engicam i.CoreM6 QDL support
Jagan Teki (5): net: fec_mxc: Remove unneeded eth_device arg from fec_get_hwaddr net: fec_mxc: Convert into driver model net: fec_mxc: Driver cleanups ARM: dts: imx6qdl-icore: Add FEC support icorem6: Use CONFIG_DM_ETH support
arch/arm/cpu/armv7/mx6/Kconfig | 1 + arch/arm/dts/imx6qdl-icore.dtsi | 24 ++ board/engicam/icorem6/icorem6.c | 71 ----- configs/imx6qdl_icore_mmc_defconfig | 1 - configs/imx6qdl_icore_nand_defconfig | 1 - drivers/net/fec_mxc.c | 516 +++++++++++++++++++++++------------ drivers/net/fec_mxc.h | 31 +-- 7 files changed, 378 insertions(+), 267 deletions(-)

fec_get_hwaddr never used eth_device argument, hence removed.
Cc: Simon Glass sjg@chromium.org Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Michael Trimarchi michael@amarulasolutions.com Acked-by: Joe Hershberger joe.hershberger@ni.com Signed-off-by: Jagan Teki jteki@openedev.com --- drivers/net/fec_mxc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 8e3b839..0838d58 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -362,8 +362,7 @@ static void fec_rbd_clean(int last, struct fec_bd *pRbd) writew(0, &pRbd->data_length); }
-static int fec_get_hwaddr(struct eth_device *dev, int dev_id, - unsigned char *mac) +static int fec_get_hwaddr(int dev_id, unsigned char *mac) { imx_get_mac_from_fuse(dev_id, mac); return !is_valid_ethaddr(mac); @@ -1045,7 +1044,7 @@ static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr, #endif eth_register(edev);
- if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) { + if (fec_get_hwaddr(dev_id, ethaddr) == 0) { debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr); memcpy(edev->enetaddr, ethaddr, 6); if (!getenv("ethaddr"))

From: Jagan Teki jagan@amarulasolutions.com
This patch add driver model support for fec_mxc driver.
Cc: Simon Glass sjg@chromium.org Cc: Joe Hershberger joe.hershberger@ni.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Michael Trimarchi michael@amarulasolutions.com Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- drivers/net/fec_mxc.c | 313 ++++++++++++++++++++++++++++++++++++++++++-------- drivers/net/fec_mxc.h | 4 + 2 files changed, 270 insertions(+), 47 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 0838d58..8c0927c 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -9,6 +9,7 @@ */
#include <common.h> +#include <dm.h> #include <malloc.h> #include <memalign.h> #include <net.h> @@ -368,11 +369,8 @@ static int fec_get_hwaddr(int dev_id, unsigned char *mac) return !is_valid_ethaddr(mac); }
-static int fec_set_hwaddr(struct eth_device *dev) +static int _fec_set_hwaddr(struct fec_priv *fec, uchar *mac) { - uchar *mac = dev->enetaddr; - struct fec_priv *fec = (struct fec_priv *)dev->priv; - writel(0, &fec->eth->iaddr1); writel(0, &fec->eth->iaddr2); writel(0, &fec->eth->gaddr1); @@ -426,9 +424,8 @@ static void fec_reg_setup(struct fec_priv *fec) * Start the FEC engine * @param[in] dev Our device to handle */ -static int fec_open(struct eth_device *edev) +static int fec_open(struct fec_priv *fec) { - struct fec_priv *fec = (struct fec_priv *)edev->priv; int speed; uint32_t addr, size; int i; @@ -534,14 +531,13 @@ static int fec_open(struct eth_device *edev) return 0; }
-static int fec_init(struct eth_device *dev, bd_t* bd) +static int _fec_init(struct fec_priv *fec, uchar *mac) { - struct fec_priv *fec = (struct fec_priv *)dev->priv; uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop; int i;
/* Initialize MAC address */ - fec_set_hwaddr(dev); + _fec_set_hwaddr(fec, mac);
/* * Setup transmit descriptors, there are two in total. @@ -587,7 +583,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd) if (fec->xcv_type != SEVENWIRE) miiphy_restart_aneg(dev); #endif - fec_open(dev); + fec_open(fec); return 0; }
@@ -595,9 +591,8 @@ static int fec_init(struct eth_device *dev, bd_t* bd) * Halt the FEC engine * @param[in] dev Our device to handle */ -static void fec_halt(struct eth_device *dev) +static void _fec_halt(struct fec_priv *fec) { - struct fec_priv *fec = (struct fec_priv *)dev->priv; int counter = 0xffff;
/* @@ -637,7 +632,7 @@ static void fec_halt(struct eth_device *dev) * @param[in] length Data count in bytes * @return 0 on success */ -static int fec_send(struct eth_device *dev, void *packet, int length) +static int _fec_send(struct fec_priv *fec, void *packet, int length) { unsigned int status; uint32_t size, end; @@ -649,8 +644,6 @@ static int fec_send(struct eth_device *dev, void *packet, int length) * This routine transmits one frame. This routine only accepts * 6-byte Ethernet addresses. */ - struct fec_priv *fec = (struct fec_priv *)dev->priv; - /* * Check for valid length of data. */ @@ -777,14 +770,14 @@ out: return ret; }
+ /** * Pull one frame from the card * @param[in] dev Our ethernet device to handle * @return Length of packet read */ -static int fec_recv(struct eth_device *dev) +static int _fec_recv(struct fec_priv *fec, uchar *mac) { - struct fec_priv *fec = (struct fec_priv *)dev->priv; struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index]; unsigned long ievent; int frame_length, len = 0; @@ -800,8 +793,8 @@ static int fec_recv(struct eth_device *dev) writel(ievent, &fec->eth->ievent); debug("fec_recv: ievent 0x%lx\n", ievent); if (ievent & FEC_IEVENT_BABR) { - fec_halt(dev); - fec_init(dev, fec->bd); + _fec_halt(fec); + _fec_init(fec, mac); printf("some error: 0x%08lx\n", ievent); return 0; } @@ -813,10 +806,10 @@ static int fec_recv(struct eth_device *dev) if (ievent & FEC_IEVENT_GRA) { /* Graceful stop complete */ if (readl(&fec->eth->x_cntrl) & 0x00000001) { - fec_halt(dev); + _fec_halt(fec); writel(~0x00000001 & readl(&fec->eth->x_cntrl), &fec->eth->x_cntrl); - fec_init(dev, fec->bd); + _fec_init(fec, mac); } }
@@ -970,6 +963,71 @@ static void fec_free_descs(struct fec_priv *fec) free(fec->tbd_base); }
+struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) +{ + struct ethernet_regs *eth = (struct ethernet_regs *)base_addr; + struct mii_dev *bus; + int ret; + + bus = mdio_alloc(); + if (!bus) { + printf("mdio_alloc failed\n"); + return NULL; + } + bus->read = fec_phy_read; + bus->write = fec_phy_write; + bus->priv = eth; + fec_set_dev_name(bus->name, dev_id); + + ret = mdio_register(bus); + if (ret) { + printf("mdio_register failed\n"); + free(bus); + return NULL; + } + fec_mii_setspeed(eth); + return bus; +} + +#ifndef CONFIG_DM_ETH +static int fec_recv(struct eth_device *dev) +{ + struct fec_priv *fec = (struct fec_priv *)dev->priv; + uchar *mac = dev->enetaddr; + + return _fec_recv(fec, mac); +} + +static int fec_send(struct eth_device *dev, void *packet, int length) +{ + struct fec_priv *fec = (struct fec_priv *)dev->priv; + + return _fec_send(fec, packet, length); +} + +static void fec_halt(struct eth_device *dev) +{ + struct fec_priv *fec = (struct fec_priv *)dev->priv; + + _fec_halt(fec); +} + +static int fec_set_hwaddr(struct eth_device *dev) +{ + struct fec_priv *fec = (struct fec_priv *)dev->priv; + uchar *mac = dev->enetaddr; + + return _fec_set_hwaddr(fec, mac); +} + +static int fec_init(struct eth_device *dev, bd_t *bd) +{ + struct fec_priv *fec = (struct fec_priv *)dev->priv; + uchar *mac = dev->enetaddr; + + return _fec_init(fec, mac); +} + #ifdef CONFIG_PHYLIB int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr, struct mii_dev *bus, struct phy_device *phydev) @@ -1061,32 +1119,6 @@ err1: return ret; }
-struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) -{ - struct ethernet_regs *eth = (struct ethernet_regs *)base_addr; - struct mii_dev *bus; - int ret; - - bus = mdio_alloc(); - if (!bus) { - printf("mdio_alloc failed\n"); - return NULL; - } - bus->read = fec_phy_read; - bus->write = fec_phy_write; - bus->priv = eth; - fec_set_dev_name(bus->name, dev_id); - - ret = mdio_register(bus); - if (ret) { - printf("mdio_register failed\n"); - free(bus); - return NULL; - } - fec_mii_setspeed(eth); - return bus; -} - int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr) { uint32_t base_mii; @@ -1146,3 +1178,190 @@ int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int)) return 0; } #endif + +#else + +static int fec_set_hwaddr(struct udevice *dev) +{ + struct fec_priv *fec = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + uchar *mac = pdata->enetaddr; + + return _fec_set_hwaddr(fec, mac); +} + +static void fec_halt(struct udevice *dev) +{ + struct fec_priv *fec = dev_get_priv(dev); + + _fec_halt(fec); +} + +static int fec_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct fec_priv *fec = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + uchar *mac = pdata->enetaddr; + + return _fec_recv(fec, mac); +} + +static int fec_send(struct udevice *dev, void *packet, int length) +{ + struct fec_priv *fec = dev_get_priv(dev); + + return _fec_send(fec, packet, length); +} + +static int fec_init(struct udevice *dev) +{ + struct fec_priv *fec = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + uchar *mac = pdata->enetaddr; + + return _fec_init(fec, mac); +} + +static const struct eth_ops fecmxc_ops = { + .start = fec_init, + .send = fec_send, + .recv = fec_recv, + .stop = fec_halt, + .write_hwaddr = fec_set_hwaddr, +}; + +static int fec_phy_init(struct fec_priv *priv, struct udevice *dev) +{ + struct phy_device *phydev; + int mask = 0xffffffff; + +#ifdef CONFIG_PHYLIB + mask = 1 << CONFIG_FEC_MXC_PHYADDR; +#endif + + phydev = phy_find_by_mask(priv->bus, mask, priv->interface); + if (!phydev) + return -ENODEV; + + phy_connect_dev(phydev, dev); + + priv->phydev = phydev; + phy_config(phydev); + + return 0; +} + +static int fecmxc_probe(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct fec_priv *priv = dev_get_priv(dev); + struct mii_dev *bus = NULL; + int dev_id = -1; + unsigned char ethaddr[6]; + uint32_t start; + int ret; + + ret = fec_alloc_descs(priv); + if (ret) + return ret; + + bus = fec_get_miibus((uint32_t)priv->eth, dev_id); + if (!bus) + goto err_mii; + + priv->bus = bus; + priv->xcv_type = CONFIG_FEC_XCV_TYPE; + priv->interface = pdata->phy_interface; + ret = fec_phy_init(priv, dev); + if (ret) + goto err_phy; + + /* Reset chip. */ + writel(readl(&priv->eth->ecntrl) | FEC_ECNTRL_RESET, &priv->eth->ecntrl); + start = get_timer(0); + while (readl(&priv->eth->ecntrl) & FEC_ECNTRL_RESET) { + if (get_timer(start) > (CONFIG_SYS_HZ * 5)) { + printf("FEC MXC: Timeout reseting chip\n"); + goto err_timeout; + } + udelay(10); + } + + fec_reg_setup(priv); + priv->dev_id = (dev_id == -1) ? 0 : dev_id; + + ret = fec_get_hwaddr(dev_id, ethaddr); + if (!ret) { + debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr); + memcpy(pdata->enetaddr, ethaddr, 6); + if (!getenv("ethaddr")) + eth_setenv_enetaddr("ethaddr", ethaddr); + } + + return 0; + +err_timeout: + free(priv->phydev); +err_phy: + mdio_unregister(bus); + free(bus); +err_mii: + fec_free_descs(priv); + return ret; +} + +static int fecmxc_remove(struct udevice *dev) +{ + struct fec_priv *priv = dev_get_priv(dev); + + free(priv->phydev); + fec_free_descs(priv); + mdio_unregister(priv->bus); + mdio_free(priv->bus); + + return 0; +} + +static int fecmxc_ofdata_to_platdata(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct fec_priv *priv = dev_get_priv(dev); + const char *phy_mode; + + pdata->iobase = (phys_addr_t)dev_get_addr(dev); + priv->eth = (struct ethernet_regs *)pdata->iobase; + + pdata->phy_interface = -1; + phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL); + if (phy_mode) + pdata->phy_interface = phy_get_interface_by_name(phy_mode); + if (pdata->phy_interface == -1) { + debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); + return -EINVAL; + } + + /* TODO + * Need to get the reset-gpio and related properties from DT + * and implemet the enet reset code on .probe call + */ + + return 0; +} + +static const struct udevice_id fecmxc_ids[] = { + { .compatible = "fsl,imx6q-fec" }, + { } +}; + +U_BOOT_DRIVER(fec_gem) = { + .name = "fecmxc", + .id = UCLASS_ETH, + .of_match = fecmxc_ids, + .ofdata_to_platdata = fecmxc_ofdata_to_platdata, + .probe = fecmxc_probe, + .remove = fecmxc_remove, + .ops = &fecmxc_ops, + .priv_auto_alloc_size = sizeof(struct fec_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; +#endif diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 0717cc6..9fc6153 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -264,6 +264,10 @@ struct fec_priv { int phy_id; int (*mii_postcall)(int); #endif + +#ifdef CONFIG_DM_ETH + u32 interface; +#endif };
/**

Hi Joe,
On Wed, Oct 19, 2016 at 4:53 PM, Jagan Teki jteki@openedev.com wrote:
From: Jagan Teki jagan@amarulasolutions.com
This patch add driver model support for fec_mxc driver.
Cc: Simon Glass sjg@chromium.org Cc: Joe Hershberger joe.hershberger@ni.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Michael Trimarchi michael@amarulasolutions.com Signed-off-by: Jagan Teki jagan@amarulasolutions.com
drivers/net/fec_mxc.c | 313 ++++++++++++++++++++++++++++++++++++++++++-------- drivers/net/fec_mxc.h | 4 + 2 files changed, 270 insertions(+), 47 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 0838d58..8c0927c 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -9,6 +9,7 @@ */
#include <common.h> +#include <dm.h> #include <malloc.h> #include <memalign.h> #include <net.h> @@ -368,11 +369,8 @@ static int fec_get_hwaddr(int dev_id, unsigned char *mac) return !is_valid_ethaddr(mac); }
-static int fec_set_hwaddr(struct eth_device *dev) +static int _fec_set_hwaddr(struct fec_priv *fec, uchar *mac) {
uchar *mac = dev->enetaddr;
struct fec_priv *fec = (struct fec_priv *)dev->priv;
writel(0, &fec->eth->iaddr1); writel(0, &fec->eth->iaddr2); writel(0, &fec->eth->gaddr1);
@@ -426,9 +424,8 @@ static void fec_reg_setup(struct fec_priv *fec)
- Start the FEC engine
- @param[in] dev Our device to handle
*/ -static int fec_open(struct eth_device *edev) +static int fec_open(struct fec_priv *fec) {
struct fec_priv *fec = (struct fec_priv *)edev->priv; int speed; uint32_t addr, size; int i;
@@ -534,14 +531,13 @@ static int fec_open(struct eth_device *edev) return 0; }
-static int fec_init(struct eth_device *dev, bd_t* bd) +static int _fec_init(struct fec_priv *fec, uchar *mac) {
struct fec_priv *fec = (struct fec_priv *)dev->priv; uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop; int i; /* Initialize MAC address */
fec_set_hwaddr(dev);
_fec_set_hwaddr(fec, mac); /* * Setup transmit descriptors, there are two in total.
@@ -587,7 +583,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd) if (fec->xcv_type != SEVENWIRE) miiphy_restart_aneg(dev); #endif
fec_open(dev);
fec_open(fec); return 0;
}
@@ -595,9 +591,8 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
- Halt the FEC engine
- @param[in] dev Our device to handle
*/ -static void fec_halt(struct eth_device *dev) +static void _fec_halt(struct fec_priv *fec) {
struct fec_priv *fec = (struct fec_priv *)dev->priv; int counter = 0xffff; /*
@@ -637,7 +632,7 @@ static void fec_halt(struct eth_device *dev)
- @param[in] length Data count in bytes
- @return 0 on success
*/ -static int fec_send(struct eth_device *dev, void *packet, int length) +static int _fec_send(struct fec_priv *fec, void *packet, int length) { unsigned int status; uint32_t size, end; @@ -649,8 +644,6 @@ static int fec_send(struct eth_device *dev, void *packet, int length) * This routine transmits one frame. This routine only accepts * 6-byte Ethernet addresses. */
struct fec_priv *fec = (struct fec_priv *)dev->priv;
/* * Check for valid length of data. */
@@ -777,14 +770,14 @@ out: return ret; }
/**
- Pull one frame from the card
- @param[in] dev Our ethernet device to handle
- @return Length of packet read
*/ -static int fec_recv(struct eth_device *dev) +static int _fec_recv(struct fec_priv *fec, uchar *mac) {
struct fec_priv *fec = (struct fec_priv *)dev->priv; struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index]; unsigned long ievent; int frame_length, len = 0;
@@ -800,8 +793,8 @@ static int fec_recv(struct eth_device *dev) writel(ievent, &fec->eth->ievent); debug("fec_recv: ievent 0x%lx\n", ievent); if (ievent & FEC_IEVENT_BABR) {
fec_halt(dev);
fec_init(dev, fec->bd);
_fec_halt(fec);
_fec_init(fec, mac); printf("some error: 0x%08lx\n", ievent); return 0; }
@@ -813,10 +806,10 @@ static int fec_recv(struct eth_device *dev) if (ievent & FEC_IEVENT_GRA) { /* Graceful stop complete */ if (readl(&fec->eth->x_cntrl) & 0x00000001) {
fec_halt(dev);
_fec_halt(fec); writel(~0x00000001 & readl(&fec->eth->x_cntrl), &fec->eth->x_cntrl);
fec_init(dev, fec->bd);
_fec_init(fec, mac); } }
@@ -970,6 +963,71 @@ static void fec_free_descs(struct fec_priv *fec) free(fec->tbd_base); }
+struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) +{
struct ethernet_regs *eth = (struct ethernet_regs *)base_addr;
struct mii_dev *bus;
int ret;
bus = mdio_alloc();
if (!bus) {
printf("mdio_alloc failed\n");
return NULL;
}
bus->read = fec_phy_read;
bus->write = fec_phy_write;
bus->priv = eth;
fec_set_dev_name(bus->name, dev_id);
ret = mdio_register(bus);
if (ret) {
printf("mdio_register failed\n");
free(bus);
return NULL;
}
fec_mii_setspeed(eth);
return bus;
+}
+#ifndef CONFIG_DM_ETH +static int fec_recv(struct eth_device *dev) +{
struct fec_priv *fec = (struct fec_priv *)dev->priv;
uchar *mac = dev->enetaddr;
return _fec_recv(fec, mac);
+}
+static int fec_send(struct eth_device *dev, void *packet, int length) +{
struct fec_priv *fec = (struct fec_priv *)dev->priv;
return _fec_send(fec, packet, length);
+}
+static void fec_halt(struct eth_device *dev) +{
struct fec_priv *fec = (struct fec_priv *)dev->priv;
_fec_halt(fec);
+}
+static int fec_set_hwaddr(struct eth_device *dev) +{
struct fec_priv *fec = (struct fec_priv *)dev->priv;
uchar *mac = dev->enetaddr;
return _fec_set_hwaddr(fec, mac);
+}
+static int fec_init(struct eth_device *dev, bd_t *bd) +{
struct fec_priv *fec = (struct fec_priv *)dev->priv;
uchar *mac = dev->enetaddr;
return _fec_init(fec, mac);
+}
#ifdef CONFIG_PHYLIB int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr, struct mii_dev *bus, struct phy_device *phydev) @@ -1061,32 +1119,6 @@ err1: return ret; }
-struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id) -{
struct ethernet_regs *eth = (struct ethernet_regs *)base_addr;
struct mii_dev *bus;
int ret;
bus = mdio_alloc();
if (!bus) {
printf("mdio_alloc failed\n");
return NULL;
}
bus->read = fec_phy_read;
bus->write = fec_phy_write;
bus->priv = eth;
fec_set_dev_name(bus->name, dev_id);
ret = mdio_register(bus);
if (ret) {
printf("mdio_register failed\n");
free(bus);
return NULL;
}
fec_mii_setspeed(eth);
return bus;
-}
int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr) { uint32_t base_mii; @@ -1146,3 +1178,190 @@ int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int)) return 0; } #endif
+#else
+static int fec_set_hwaddr(struct udevice *dev) +{
struct fec_priv *fec = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
uchar *mac = pdata->enetaddr;
return _fec_set_hwaddr(fec, mac);
+}
+static void fec_halt(struct udevice *dev) +{
struct fec_priv *fec = dev_get_priv(dev);
_fec_halt(fec);
+}
+static int fec_recv(struct udevice *dev, int flags, uchar **packetp) +{
struct fec_priv *fec = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
uchar *mac = pdata->enetaddr;
return _fec_recv(fec, mac);
+}
+static int fec_send(struct udevice *dev, void *packet, int length) +{
struct fec_priv *fec = dev_get_priv(dev);
return _fec_send(fec, packet, length);
+}
+static int fec_init(struct udevice *dev) +{
struct fec_priv *fec = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_platdata(dev);
uchar *mac = pdata->enetaddr;
return _fec_init(fec, mac);
+}
+static const struct eth_ops fecmxc_ops = {
.start = fec_init,
.send = fec_send,
.recv = fec_recv,
.stop = fec_halt,
.write_hwaddr = fec_set_hwaddr,
+};
+static int fec_phy_init(struct fec_priv *priv, struct udevice *dev) +{
struct phy_device *phydev;
int mask = 0xffffffff;
+#ifdef CONFIG_PHYLIB
mask = 1 << CONFIG_FEC_MXC_PHYADDR;
+#endif
phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
if (!phydev)
return -ENODEV;
phy_connect_dev(phydev, dev);
priv->phydev = phydev;
phy_config(phydev);
return 0;
+}
+static int fecmxc_probe(struct udevice *dev) +{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct fec_priv *priv = dev_get_priv(dev);
struct mii_dev *bus = NULL;
int dev_id = -1;
unsigned char ethaddr[6];
uint32_t start;
int ret;
ret = fec_alloc_descs(priv);
if (ret)
return ret;
bus = fec_get_miibus((uint32_t)priv->eth, dev_id);
if (!bus)
goto err_mii;
priv->bus = bus;
priv->xcv_type = CONFIG_FEC_XCV_TYPE;
priv->interface = pdata->phy_interface;
ret = fec_phy_init(priv, dev);
if (ret)
goto err_phy;
/* Reset chip. */
writel(readl(&priv->eth->ecntrl) | FEC_ECNTRL_RESET, &priv->eth->ecntrl);
start = get_timer(0);
while (readl(&priv->eth->ecntrl) & FEC_ECNTRL_RESET) {
if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
printf("FEC MXC: Timeout reseting chip\n");
goto err_timeout;
}
udelay(10);
}
fec_reg_setup(priv);
priv->dev_id = (dev_id == -1) ? 0 : dev_id;
ret = fec_get_hwaddr(dev_id, ethaddr);
if (!ret) {
debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
memcpy(pdata->enetaddr, ethaddr, 6);
if (!getenv("ethaddr"))
eth_setenv_enetaddr("ethaddr", ethaddr);
}
return 0;
+err_timeout:
free(priv->phydev);
+err_phy:
mdio_unregister(bus);
free(bus);
+err_mii:
fec_free_descs(priv);
return ret;
+}
+static int fecmxc_remove(struct udevice *dev) +{
struct fec_priv *priv = dev_get_priv(dev);
free(priv->phydev);
fec_free_descs(priv);
mdio_unregister(priv->bus);
mdio_free(priv->bus);
return 0;
+}
+static int fecmxc_ofdata_to_platdata(struct udevice *dev) +{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct fec_priv *priv = dev_get_priv(dev);
const char *phy_mode;
pdata->iobase = (phys_addr_t)dev_get_addr(dev);
priv->eth = (struct ethernet_regs *)pdata->iobase;
pdata->phy_interface = -1;
phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
if (phy_mode)
pdata->phy_interface = phy_get_interface_by_name(phy_mode);
if (pdata->phy_interface == -1) {
debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
return -EINVAL;
}
/* TODO
* Need to get the reset-gpio and related properties from DT
* and implemet the enet reset code on .probe call
*/
return 0;
+}
+static const struct udevice_id fecmxc_ids[] = {
{ .compatible = "fsl,imx6q-fec" },
{ }
+};
+U_BOOT_DRIVER(fec_gem) = {
.name = "fecmxc",
.id = UCLASS_ETH,
.of_match = fecmxc_ids,
.ofdata_to_platdata = fecmxc_ofdata_to_platdata,
.probe = fecmxc_probe,
.remove = fecmxc_remove,
.ops = &fecmxc_ops,
.priv_auto_alloc_size = sizeof(struct fec_priv),
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
+}; +#endif diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 0717cc6..9fc6153 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -264,6 +264,10 @@ struct fec_priv { int phy_id; int (*mii_postcall)(int); #endif
+#ifdef CONFIG_DM_ETH
u32 interface;
+#endif };
Any comment, otherwise please add Acked/Reviewd - We would like to apply this trough Stefanos'.
thanks!

On Wed, Oct 19, 2016 at 6:23 AM, Jagan Teki jteki@openedev.com wrote:
From: Jagan Teki jagan@amarulasolutions.com
This patch add driver model support for fec_mxc driver.
Cc: Simon Glass sjg@chromium.org Cc: Joe Hershberger joe.hershberger@ni.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Michael Trimarchi michael@amarulasolutions.com Signed-off-by: Jagan Teki jagan@amarulasolutions.com
Acked-by: Joe Hershberger joe.hershberger@ni.com

From: Jagan Teki jagan@amarulasolutions.com
- Remove exctra space - Add space - Add tab space - Fix single line comments quotes - Fix 'CHECK: Avoid CamelCase' - Fix 'CHECK: Alignment should match open parenthesis' - Fix 'WARNING: line over 80 characters' - Re-arrage header include files
Cc: Simon Glass sjg@chromium.org Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Michael Trimarchi michael@amarulasolutions.com Acked-by: Joe Hershberger joe.hershberger@ni.com Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- drivers/net/fec_mxc.c | 200 +++++++++++++++++++------------------------------- drivers/net/fec_mxc.h | 27 ++----- 2 files changed, 82 insertions(+), 145 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 8c0927c..23fa609 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -12,18 +12,19 @@ #include <dm.h> #include <malloc.h> #include <memalign.h> +#include <miiphy.h> #include <net.h> #include <netdev.h> -#include <miiphy.h> #include "fec_mxc.h"
-#include <asm/arch/clock.h> -#include <asm/arch/imx-regs.h> -#include <asm/imx-common/sys_proto.h> #include <asm/io.h> #include <linux/errno.h> #include <linux/compiler.h>
+#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/imx-common/sys_proto.h> + DECLARE_GLOBAL_DATA_PTR;
/* @@ -80,11 +81,9 @@ static void swap_packet(uint32_t *packet, int length) } #endif
-/* - * MII-interface related functions - */ -static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr, - uint8_t regAddr) +/* MII-interface related functions */ +static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyaddr, + uint8_t regaddr) { uint32_t reg; /* convenient holder for the PHY register */ uint32_t phy; /* convenient holder for the PHY */ @@ -96,15 +95,13 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr, * programming the FEC's MII data register. */ writel(FEC_IEVENT_MII, ð->ievent); - reg = regAddr << FEC_MII_DATA_RA_SHIFT; - phy = phyAddr << FEC_MII_DATA_PA_SHIFT; + reg = regaddr << FEC_MII_DATA_RA_SHIFT; + phy = phyaddr << FEC_MII_DATA_PA_SHIFT;
writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy | reg, ð->mii_data);
- /* - * wait for the related interrupt - */ + /* wait for the related interrupt */ start = get_timer(0); while (!(readl(ð->ievent) & FEC_IEVENT_MII)) { if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) { @@ -113,17 +110,13 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr, } }
- /* - * clear mii interrupt bit - */ + /* clear mii interrupt bit */ writel(FEC_IEVENT_MII, ð->ievent);
- /* - * it's now safe to read the PHY's register - */ + /* it's now safe to read the PHY's register */ val = (unsigned short)readl(ð->mii_data); - debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr, - regAddr, val); + debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyaddr, + regaddr, val); return val; }
@@ -154,22 +147,20 @@ static void fec_mii_setspeed(struct ethernet_regs *eth) debug("%s: mii_speed %08x\n", __func__, readl(ð->mii_speed)); }
-static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr, - uint8_t regAddr, uint16_t data) +static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyaddr, + uint8_t regaddr, uint16_t data) { uint32_t reg; /* convenient holder for the PHY register */ uint32_t phy; /* convenient holder for the PHY */ uint32_t start;
- reg = regAddr << FEC_MII_DATA_RA_SHIFT; - phy = phyAddr << FEC_MII_DATA_PA_SHIFT; + reg = regaddr << FEC_MII_DATA_RA_SHIFT; + phy = phyaddr << FEC_MII_DATA_PA_SHIFT;
writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | FEC_MII_DATA_TA | phy | reg | data, ð->mii_data);
- /* - * wait for the MII interrupt - */ + /* wait for the MII interrupt */ start = get_timer(0); while (!(readl(ð->ievent) & FEC_IEVENT_MII)) { if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) { @@ -178,26 +169,24 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr, } }
- /* - * clear MII interrupt bit - */ + /* clear MII interrupt bit */ writel(FEC_IEVENT_MII, ð->ievent); - debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr, - regAddr, data); + debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyaddr, + regaddr, data);
return 0; }
-static int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, - int regAddr) +static int fec_phy_read(struct mii_dev *bus, int phyaddr, int dev_addr, + int regaddr) { - return fec_mdio_read(bus->priv, phyAddr, regAddr); + return fec_mdio_read(bus->priv, phyaddr, regaddr); }
-static int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, - int regAddr, u16 data) +static int fec_phy_write(struct mii_dev *bus, int phyaddr, int dev_addr, + int regaddr, u16 data) { - return fec_mdio_write(bus->priv, phyAddr, regAddr, data); + return fec_mdio_write(bus->priv, phyaddr, regaddr, data); }
#ifndef CONFIG_PHYLIB @@ -218,14 +207,12 @@ static int miiphy_restart_aneg(struct eth_device *dev) fec_mdio_write(eth, fec->phy_id, MII_BMCR, BMCR_RESET); udelay(1000);
- /* - * Set the auto-negotiation advertisement register bits - */ + /* Set the auto-negotiation advertisement register bits */ fec_mdio_write(eth, fec->phy_id, MII_ADVERTISE, - LPA_100FULL | LPA_100HALF | LPA_10FULL | - LPA_10HALF | PHY_ANLPAR_PSB_802_3); + LPA_100FULL | LPA_100HALF | LPA_10FULL | + LPA_10HALF | PHY_ANLPAR_PSB_802_3); fec_mdio_write(eth, fec->phy_id, MII_BMCR, - BMCR_ANENABLE | BMCR_ANRESTART); + BMCR_ANENABLE | BMCR_ANRESTART);
if (fec->mii_postcall) ret = fec->mii_postcall(fec->phy_id); @@ -242,9 +229,7 @@ static int miiphy_wait_aneg(struct eth_device *dev) struct fec_priv *fec = (struct fec_priv *)dev->priv; struct ethernet_regs *eth = fec->bus->priv;
- /* - * Wait for AN completion - */ + /* Wait for AN completion */ start = get_timer(0); do { if (get_timer(start) > (CONFIG_SYS_HZ * 5)) { @@ -255,7 +240,7 @@ static int miiphy_wait_aneg(struct eth_device *dev) status = fec_mdio_read(eth, fec->phy_id, MII_BMSR); if (status < 0) { printf("%s: Autonegotiation failed. status: %d\n", - dev->name, status); + dev->name, status); return -1; } } while (!(status & BMSR_LSTATUS)); @@ -352,15 +337,15 @@ static void fec_tbd_init(struct fec_priv *fec) /** * Mark the given read buffer descriptor as free * @param[in] last 1 if this is the last buffer descriptor in the chain, else 0 - * @param[in] pRbd buffer descriptor to mark free again + * @param[in] prbd buffer descriptor to mark free again */ -static void fec_rbd_clean(int last, struct fec_bd *pRbd) +static void fec_rbd_clean(int last, struct fec_bd *prbd) { unsigned short flags = FEC_RBD_EMPTY; if (last) flags |= FEC_RBD_WRAP; - writew(flags, &pRbd->status); - writew(0, &pRbd->data_length); + writew(flags, &prbd->status); + writew(0, &prbd->data_length); }
static int fec_get_hwaddr(int dev_id, unsigned char *mac) @@ -376,37 +361,26 @@ static int _fec_set_hwaddr(struct fec_priv *fec, uchar *mac) writel(0, &fec->eth->gaddr1); writel(0, &fec->eth->gaddr2);
- /* - * Set physical address - */ + /* Set physical address */ writel((mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3], - &fec->eth->paddr1); + &fec->eth->paddr1); writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, &fec->eth->paddr2);
return 0; }
-/* - * Do initial configuration of the FEC registers - */ +/* Do initial configuration of the FEC registers */ static void fec_reg_setup(struct fec_priv *fec) { uint32_t rcntrl;
- /* - * Set interrupt mask register - */ + /* Set interrupt mask register */ writel(0x00000000, &fec->eth->imask);
- /* - * Clear FEC-Lite interrupt event register(IEVENT) - */ + /* Clear FEC-Lite interrupt event register(IEVENT) */ writel(0xffffffff, &fec->eth->ievent);
- - /* - * Set FEC-Lite receive control register(R_CNTRL): - */ + /* Set FEC-Lite receive control register(R_CNTRL): */
/* Start with frame length = 1518, common for all modes. */ rcntrl = PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT; @@ -449,22 +423,19 @@ static int fec_open(struct fec_priv *fec) #ifdef FEC_QUIRK_ENET_MAC /* Enable ENET HW endian SWAP */ writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP, - &fec->eth->ecntrl); + &fec->eth->ecntrl); /* Enable ENET store and forward mode */ writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD, - &fec->eth->x_wmrk); + &fec->eth->x_wmrk); #endif - /* - * Enable FEC-Lite controller - */ + /* Enable FEC-Lite controller */ writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN, - &fec->eth->ecntrl); + &fec->eth->ecntrl); + #if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL) udelay(100); - /* - * setup the MII gasket for RMII mode - */
+ /* setup the MII gasket for RMII mode */ /* disable the gasket */ writew(0, &fec->eth->miigsk_enr);
@@ -522,9 +493,7 @@ static int fec_open(struct fec_priv *fec) #endif debug("%s:Speed=%i\n", __func__, speed);
- /* - * Enable SmartDMA receive task - */ + /* Enable SmartDMA receive task */ fec_rx_task_enable(fec);
udelay(100000); @@ -539,9 +508,7 @@ static int _fec_init(struct fec_priv *fec, uchar *mac) /* Initialize MAC address */ _fec_set_hwaddr(fec, mac);
- /* - * Setup transmit descriptors, there are two in total. - */ + /* Setup transmit descriptors, there are two in total. */ fec_tbd_init(fec);
/* Setup receive descriptors. */ @@ -552,18 +519,14 @@ static int _fec_init(struct fec_priv *fec, uchar *mac) if (fec->xcv_type != SEVENWIRE) fec_mii_setspeed(fec->bus->priv);
- /* - * Set Opcode/Pause Duration Register - */ + /* Set Opcode/Pause Duration Register */ writel(0x00010020, &fec->eth->op_pause); /* FIXME 0xffff0020; */ writel(0x2, &fec->eth->x_wmrk); - /* - * Set multicast address filter - */ + + /* Set multicast address filter */ writel(0x00000000, &fec->eth->gaddr1); writel(0x00000000, &fec->eth->gaddr2);
- /* Do not access reserved register for i.MX6UL */ if (!is_mx6ul()) { /* clear MIB RAM */ @@ -595,22 +558,16 @@ static void _fec_halt(struct fec_priv *fec) { int counter = 0xffff;
- /* - * issue graceful stop command to the FEC transmitter if necessary - */ + /* issue graceful stop command to the FEC transmitter if necessary */ writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl), - &fec->eth->x_cntrl); + &fec->eth->x_cntrl);
debug("eth_halt: wait for stop regs\n"); - /* - * wait for graceful stop to register - */ + /* wait for graceful stop to register */ while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA))) udelay(1);
- /* - * Disable SmartDMA tasks - */ + /* Disable SmartDMA tasks */ fec_tx_task_disable(fec); fec_rx_task_disable(fec);
@@ -619,7 +576,7 @@ static void _fec_halt(struct fec_priv *fec) * Note: this will also reset the BD index counter! */ writel(readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN, - &fec->eth->ecntrl); + &fec->eth->ecntrl); fec->rbd_index = 0; fec->tbd_index = 0; debug("eth_halt: done\n"); @@ -712,9 +669,7 @@ static int _fec_send(struct fec_priv *fec, void *packet, int length) */ readl(addr + size - 4);
- /* - * Enable SmartDMA transmit task - */ + /* Enable SmartDMA transmit task */ fec_tx_task_enable(fec);
/* @@ -759,8 +714,8 @@ static int _fec_send(struct fec_priv *fec, void *packet, int length)
out: debug("fec_send: status 0x%x index %d ret %i\n", - readw(&fec->tbd_base[fec->tbd_index].status), - fec->tbd_index, ret); + readw(&fec->tbd_base[fec->tbd_index].status), + fec->tbd_index, ret); /* for next transmission use the other buffer */ if (fec->tbd_index) fec->tbd_index = 0; @@ -786,9 +741,7 @@ static int _fec_recv(struct fec_priv *fec, uchar *mac) int i; ALLOC_CACHE_ALIGN_BUFFER(uchar, buff, FEC_MAX_PKT_SIZE);
- /* - * Check if any critical events have happened - */ + /* Check if any critical events have happened */ ievent = readl(&fec->eth->ievent); writel(ievent, &fec->eth->ievent); debug("fec_recv: ievent 0x%lx\n", ievent); @@ -801,14 +754,14 @@ static int _fec_recv(struct fec_priv *fec, uchar *mac) if (ievent & FEC_IEVENT_HBERR) { /* Heartbeat error */ writel(0x00000001 | readl(&fec->eth->x_cntrl), - &fec->eth->x_cntrl); + &fec->eth->x_cntrl); } if (ievent & FEC_IEVENT_GRA) { /* Graceful stop complete */ if (readl(&fec->eth->x_cntrl) & 0x00000001) { _fec_halt(fec); writel(~0x00000001 & readl(&fec->eth->x_cntrl), - &fec->eth->x_cntrl); + &fec->eth->x_cntrl); _fec_init(fec, mac); } } @@ -836,22 +789,16 @@ static int _fec_recv(struct fec_priv *fec, uchar *mac)
if (!(bd_status & FEC_RBD_EMPTY)) { if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) && - ((readw(&rbd->data_length) - 4) > 14)) { - /* - * Get buffer address and size - */ + ((readw(&rbd->data_length) - 4) > 14)) { + /* Get buffer address and size */ addr = readl(&rbd->data_pointer); frame_length = readw(&rbd->data_length) - 4; - /* - * Invalidate data cache over the buffer - */ + /* Invalidate data cache over the buffer */ end = roundup(addr + frame_length, ARCH_DMA_MINALIGN); addr &= ~(ARCH_DMA_MINALIGN - 1); invalidate_dcache_range(addr, end);
- /* - * Fill the buffer and pass it to upper layers - */ + /* Fill the buffer and pass it to upper layers */ #ifdef CONFIG_FEC_MXC_SWAP_PACKET swap_packet((uint32_t *)addr, frame_length); #endif @@ -879,7 +826,7 @@ static int _fec_recv(struct fec_priv *fec, uchar *mac) &fec->rbd_base[i]); } flush_dcache_range(addr, - addr + ARCH_DMA_MINALIGN); + addr + ARCH_DMA_MINALIGN); }
fec_rx_task_enable(fec); @@ -1277,7 +1224,8 @@ static int fecmxc_probe(struct udevice *dev) goto err_phy;
/* Reset chip. */ - writel(readl(&priv->eth->ecntrl) | FEC_ECNTRL_RESET, &priv->eth->ecntrl); + writel(readl(&priv->eth->ecntrl) | FEC_ECNTRL_RESET, + &priv->eth->ecntrl); start = get_timer(0); while (readl(&priv->eth->ecntrl) & FEC_ECNTRL_RESET) { if (get_timer(start) > (CONFIG_SYS_HZ * 5)) { diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 9fc6153..43a7d7b 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -14,21 +14,14 @@ * SPDX-License-Identifier: GPL-2.0+ */
- #ifndef __FEC_MXC_H #define __FEC_MXC_H
-void imx_get_mac_from_fuse(int dev_id, unsigned char *mac); - -/** - * Layout description of the FEC - */ +/* Layout description of the FEC */ struct ethernet_regs { + /* [10:2]addr = 00 */
-/* [10:2]addr = 00 */ - -/* Control and status Registers (offset 000-1FF) */ - + /* Control and status Registers (offset 000-1FF) */ uint32_t res0[1]; /* MBAR_ETH + 0x000 */ uint32_t ievent; /* MBAR_ETH + 0x004 */ uint32_t imask; /* MBAR_ETH + 0x008 */ @@ -71,8 +64,7 @@ struct ethernet_regs { uint32_t emrbr; /* MBAR_ETH + 0x188 */ uint32_t res12[29]; /* MBAR_ETH + 0x18C-1FC */
-/* MIB COUNTERS (Offset 200-2FF) */ - + /* MIB COUNTERS (Offset 200-2FF) */ uint32_t rmon_t_drop; /* MBAR_ETH + 0x200 */ uint32_t rmon_t_packets; /* MBAR_ETH + 0x204 */ uint32_t rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */ @@ -174,7 +166,6 @@ struct ethernet_regs { #define FEC_IMASKT_RL 0x00100000 #define FEC_IMASK_UN 0x00080000
- #define FEC_RCNTRL_MAX_FL_SHIFT 16 #define FEC_RCNTRL_LOOP 0x00000001 #define FEC_RCNTRL_DRT 0x00000002 @@ -233,9 +224,7 @@ struct fec_bd { uint32_t data_pointer; /* payload's buffer address */ };
-/** - * Supported phy types on this platform - */ +/* Supported phy types on this platform */ enum xceiver_type { SEVENWIRE, /* 7-wire */ MII10, /* MII 10Mbps */ @@ -244,9 +233,7 @@ enum xceiver_type { RGMII, /* RGMII */ };
-/** - * @brief i.MX27-FEC private structure - */ +/* @brief i.MX27-FEC private structure */ struct fec_priv { struct ethernet_regs *eth; /* pointer to register'S base */ enum xceiver_type xcv_type; /* transceiver type */ @@ -270,6 +257,8 @@ struct fec_priv { #endif };
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac); + /** * @brief Numbers of buffer descriptors for receiving *

From: Jagan Teki jagan@amarulasolutions.com
Add FEC dts support for Engicam i.CoreM6 dql modules.
Cc: Stefano Babic sbabic@denx.de Cc: Matteo Lisi matteo.lisi@engicam.com Cc: Michael Trimarchi michael@amarulasolutions.com Acked-by: Joe Hershberger joe.hershberger@ni.com Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- arch/arm/dts/imx6qdl-icore.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/arch/arm/dts/imx6qdl-icore.dtsi b/arch/arm/dts/imx6qdl-icore.dtsi index f424cd5..a485c3e 100644 --- a/arch/arm/dts/imx6qdl-icore.dtsi +++ b/arch/arm/dts/imx6qdl-icore.dtsi @@ -75,6 +75,14 @@ assigned-clock-parents = <&clks IMX6QDL_CLK_OSC>; };
+&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>; + phy-mode = "rmii"; + status = "okay"; +}; + &gpmi { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpmi_nand>; @@ -118,6 +126,22 @@ };
&iomuxc { + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x1b0b1 + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0 + MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0 + MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0 + MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0 + MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1b0b0 + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0 + >; + }; + pinctrl_flexcan1: flexcan1grp { fsl,pins = < MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX 0x1b020

From: Jagan Teki jagan@amarulasolutions.com
Use CONFIG_DM_ETH and remove board_eth_init code from board files.
Cc: Joe Hershberger joe.hershberger@ni.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Michael Trimarchi michael@amarulasolutions.com Acked-by: Joe Hershberger joe.hershberger@ni.com Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- arch/arm/cpu/armv7/mx6/Kconfig | 1 + board/engicam/icorem6/icorem6.c | 71 ------------------------------------ configs/imx6qdl_icore_mmc_defconfig | 1 - configs/imx6qdl_icore_nand_defconfig | 1 - 4 files changed, 1 insertion(+), 73 deletions(-)
diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig index 762a581..8456b0e 100644 --- a/arch/arm/cpu/armv7/mx6/Kconfig +++ b/arch/arm/cpu/armv7/mx6/Kconfig @@ -100,6 +100,7 @@ config TARGET_MX6Q_ICORE select MX6QDL select OF_CONTROL select DM + select DM_ETH select DM_GPIO select DM_MMC select DM_THERMAL diff --git a/board/engicam/icorem6/icorem6.c b/board/engicam/icorem6/icorem6.c index c152007..587775e 100644 --- a/board/engicam/icorem6/icorem6.c +++ b/board/engicam/icorem6/icorem6.c @@ -7,8 +7,6 @@ */
#include <common.h> -#include <miiphy.h> -#include <netdev.h>
#include <asm/io.h> #include <asm/gpio.h> @@ -27,80 +25,11 @@ DECLARE_GLOBAL_DATA_PTR; PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
-#define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ - PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm | PAD_CTL_HYS) - static iomux_v3_cfg_t const uart4_pads[] = { IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), };
-static iomux_v3_cfg_t const enet_pads[] = { - IOMUX_PADS(PAD_ENET_CRS_DV__ENET_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_GPIO_16__ENET_REF_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL | PAD_CTL_SRE_FAST)), - IOMUX_PADS(PAD_ENET_TX_EN__ENET_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_ENET_RXD1__ENET_RX_DATA1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_ENET_RXD0__ENET_RX_DATA0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_ENET_TXD1__ENET_TX_DATA1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_ENET_TXD0__ENET_TX_DATA0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL)), -}; - -#ifdef CONFIG_FEC_MXC -#define ENET_PHY_RST IMX_GPIO_NR(7, 12) -static int setup_fec(void) -{ - struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; - s32 timeout = 100000; - u32 reg = 0; - int ret; - - /* Enable fec clock */ - setbits_le32(&ccm->CCGR1, MXC_CCM_CCGR1_ENET_MASK); - - /* use 50MHz */ - ret = enable_fec_anatop_clock(0, ENET_50MHZ); - if (ret) - return ret; - - /* Enable PLLs */ - reg = readl(&anatop->pll_enet); - reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN; - writel(reg, &anatop->pll_enet); - reg = readl(&anatop->pll_enet); - reg |= BM_ANADIG_PLL_SYS_ENABLE; - while (timeout--) { - if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_SYS_LOCK) - break; - } - if (timeout <= 0) - return -EIO; - reg &= ~BM_ANADIG_PLL_SYS_BYPASS; - writel(reg, &anatop->pll_enet); - - /* reset the phy */ - gpio_direction_output(ENET_PHY_RST, 0); - udelay(10000); - gpio_set_value(ENET_PHY_RST, 1); - - return 0; -} - -int board_eth_init(bd_t *bis) -{ - int ret; - - SETUP_IOMUX_PADS(enet_pads); - setup_fec(); - - return ret = cpu_eth_init(bis); -} -#endif - #ifdef CONFIG_NAND_MXS
#define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP) diff --git a/configs/imx6qdl_icore_mmc_defconfig b/configs/imx6qdl_icore_mmc_defconfig index 221ea7e..fbcbdc8 100644 --- a/configs/imx6qdl_icore_mmc_defconfig +++ b/configs/imx6qdl_icore_mmc_defconfig @@ -28,7 +28,6 @@ CONFIG_CMD_FS_GENERIC=y CONFIG_OF_LIBFDT=y CONFIG_FEC_MXC=y CONFIG_MXC_UART=y -CONFIG_NETDEVICES=y CONFIG_IMX_THERMAL=y CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y diff --git a/configs/imx6qdl_icore_nand_defconfig b/configs/imx6qdl_icore_nand_defconfig index 8ac3099..4b544fc 100644 --- a/configs/imx6qdl_icore_nand_defconfig +++ b/configs/imx6qdl_icore_nand_defconfig @@ -24,7 +24,6 @@ CONFIG_OF_LIBFDT=y CONFIG_FEC_MXC=y CONFIG_MXC_UART=y CONFIG_NAND_MXS=y -CONFIG_NETDEVICES=y CONFIG_IMX_THERMAL=y CONFIG_PINCTRL=y CONFIG_PINCTRL_IMX6=y

Hi Stefano,
On Wed, Oct 19, 2016 at 4:53 PM, Jagan Teki jteki@openedev.com wrote:
From: Jagan Teki jagan@amarulasolutions.com
This series convert fec_mxc to DM and tested both dm and non-dm code and it is on top of [1] with u-boot-imx/master branch.
Changes for v7:
- Remove fec_set_dev_name in dm probe
Changes for v6:
- Add Acked-by tags in commit message
Changes for v5:
- Add stub fec calls to minimize the #ifdef's
- Use same func names on eth_ops
- Remove reset_gpio in fec_mxc.h
- Add new patches, for cleanup driver
Changes for v4:
- rebase to u-boot-imx/master
Changes for v3:
- Add ARM: dts: imx6qdl-icore: Add FEC support
- icorem6: Use CONFIG_DM_ETH support
Changes for v2:
- Add TODO for implementing the enet reset code
[1] [PATCH v7 00/21] imx6: Add Engicam i.CoreM6 QDL support
Jagan Teki (5): net: fec_mxc: Remove unneeded eth_device arg from fec_get_hwaddr net: fec_mxc: Convert into driver model net: fec_mxc: Driver cleanups ARM: dts: imx6qdl-icore: Add FEC support icorem6: Use CONFIG_DM_ETH support
arch/arm/cpu/armv7/mx6/Kconfig | 1 + arch/arm/dts/imx6qdl-icore.dtsi | 24 ++ board/engicam/icorem6/icorem6.c | 71 ----- configs/imx6qdl_icore_mmc_defconfig | 1 - configs/imx6qdl_icore_nand_defconfig | 1 - drivers/net/fec_mxc.c | 516 +++++++++++++++++++++++------------ drivers/net/fec_mxc.h | 31 +-- 7 files changed, 378 insertions(+), 267 deletions(-)
Please apply this series along with [1]
[1] [PATCH v7 00/21] imx6: Add Engicam i.CoreM6 QDL support
thanks!

Hi Stefano,
On Thu, Oct 20, 2016 at 11:29 AM, Jagan Teki jagan@openedev.com wrote:
Hi Stefano,
On Wed, Oct 19, 2016 at 4:53 PM, Jagan Teki jteki@openedev.com wrote:
From: Jagan Teki jagan@amarulasolutions.com
This series convert fec_mxc to DM and tested both dm and non-dm code and it is on top of [1] with u-boot-imx/master branch.
Changes for v7:
- Remove fec_set_dev_name in dm probe
Changes for v6:
- Add Acked-by tags in commit message
Changes for v5:
- Add stub fec calls to minimize the #ifdef's
- Use same func names on eth_ops
- Remove reset_gpio in fec_mxc.h
- Add new patches, for cleanup driver
Changes for v4:
- rebase to u-boot-imx/master
Changes for v3:
- Add ARM: dts: imx6qdl-icore: Add FEC support
- icorem6: Use CONFIG_DM_ETH support
Changes for v2:
- Add TODO for implementing the enet reset code
[1] [PATCH v7 00/21] imx6: Add Engicam i.CoreM6 QDL support
Jagan Teki (5): net: fec_mxc: Remove unneeded eth_device arg from fec_get_hwaddr net: fec_mxc: Convert into driver model net: fec_mxc: Driver cleanups ARM: dts: imx6qdl-icore: Add FEC support icorem6: Use CONFIG_DM_ETH support
arch/arm/cpu/armv7/mx6/Kconfig | 1 + arch/arm/dts/imx6qdl-icore.dtsi | 24 ++ board/engicam/icorem6/icorem6.c | 71 ----- configs/imx6qdl_icore_mmc_defconfig | 1 - configs/imx6qdl_icore_nand_defconfig | 1 - drivers/net/fec_mxc.c | 516 +++++++++++++++++++++++------------ drivers/net/fec_mxc.h | 31 +-- 7 files changed, 378 insertions(+), 267 deletions(-)
Please apply this series along with [1]
Can you please apply.
thanks!

Hi Jagan,
On 19/10/2016 13:23, Jagan Teki wrote:
From: Jagan Teki jagan@amarulasolutions.com
This series convert fec_mxc to DM and tested both dm and non-dm code and it is on top of [1] with u-boot-imx/master branch.
Changes for v7:
- Remove fec_set_dev_name in dm probe
Changes for v6:
- Add Acked-by tags in commit message
Changes for v5:
- Add stub fec calls to minimize the #ifdef's
- Use same func names on eth_ops
- Remove reset_gpio in fec_mxc.h
- Add new patches, for cleanup driver
Changes for v4:
- rebase to u-boot-imx/master
Changes for v3:
- Add ARM: dts: imx6qdl-icore: Add FEC support
- icorem6: Use CONFIG_DM_ETH support
Changes for v2:
- Add TODO for implementing the enet reset code
[1] [PATCH v7 00/21] imx6: Add Engicam i.CoreM6 QDL support
Jagan Teki (5): net: fec_mxc: Remove unneeded eth_device arg from fec_get_hwaddr net: fec_mxc: Convert into driver model net: fec_mxc: Driver cleanups ARM: dts: imx6qdl-icore: Add FEC support icorem6: Use CONFIG_DM_ETH support
arch/arm/cpu/armv7/mx6/Kconfig | 1 + arch/arm/dts/imx6qdl-icore.dtsi | 24 ++ board/engicam/icorem6/icorem6.c | 71 ----- configs/imx6qdl_icore_mmc_defconfig | 1 - configs/imx6qdl_icore_nand_defconfig | 1 - drivers/net/fec_mxc.c | 516 +++++++++++++++++++++++------------ drivers/net/fec_mxc.h | 31 +-- 7 files changed, 378 insertions(+), 267 deletions(-)
Applied to u-boot-imx, -next branch, thanks !
Best regards, Stefano Babic
participants (4)
-
Jagan Teki
-
Jagan Teki
-
Joe Hershberger
-
Stefano Babic