net: fec_mxc: Convert to DM
Subsystems (3)
v6 cover net: fec_mxc: Convert to DM
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 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 | 517 +++++++++++++++++++++++------------ drivers/net/fec_mxc.h | 31 +-- 7 files changed, 379 insertions(+), 267 deletions(-)
Signature · 1 line
2.7.4
PATCH v6 1/5 net: fec_mxc: Remove unneeded eth_device arg from fec_get_hwaddr
fec_get_hwaddr never used eth_device argument, hence removed.
--- drivers/net/fec_mxc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/fec_mxc.c +2 -3
@@ -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" ))
Signature · 1 line
2.7.4
PATCH v6 2/5 net: fec_mxc: Convert into driver model
In reply to Jagan TekiFrom: Jagan Teki <[email protected]>
This patch add driver model support for fec_mxc driver.
--- drivers/net/fec_mxc.c | 314 ++++++++++++++++++++++++++++++++++++++++++-------- drivers/net/fec_mxc.h | 4 + 2 files changed, 271 insertions(+), 47 deletions(-)
drivers/net/fec_mxc.c +267 -47
@@ -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,191 @@ 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); +fec_set_dev_name ((char *)dev->name, dev_id); + 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
drivers/net/fec_mxc.h +4 -0
@@ -264,6 +264,10 @@ struct fec_priv {int phy_id;int (*mii_postcall)(int );#endif + +#ifdef CONFIG_DM_ETH +u32 interface; +#endif };/**
Signature · 1 line
2.7.4
PATCH v6 3/5 net: fec_mxc: Driver cleanups
In reply to Jagan TekiFrom: Jagan Teki <[email protected]>
- 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
--- drivers/net/fec_mxc.c | 200 +++++++++++++++++++------------------------------- drivers/net/fec_mxc.h | 27 ++----- 2 files changed, 82 insertions(+), 145 deletions(-)
drivers/net/fec_mxc.c +74 -126
@@ -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 )) {
drivers/net/fec_mxc.h +8 -19
@@ -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 *
Signature · 1 line
2.7.4
PATCH v6 4/5 ARM: dts: imx6qdl-icore: Add FEC support
In reply to Jagan TekiFrom: Jagan Teki <[email protected]>
Add FEC dts support for Engicam i.CoreM6 dql modules.
--- arch/arm/dts/imx6qdl-icore.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
arch/arm/dts/imx6qdl-icore.dtsi +24 -0
@@ -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
Signature · 1 line
2.7.4
PATCH v6 5/5 icorem6: Use CONFIG_DM_ETH support
In reply to Jagan TekiFrom: Jagan Teki <[email protected]>
Use CONFIG_DM_ETH and remove board_eth_init code from board files.
--- 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(-)
arch/arm/cpu/armv7/mx6/Kconfig +1 -0
@@ -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
board/engicam/icorem6/icorem6.c +0 -71
88 lines not on this page · raw message
configs/imx6qdl_icore_mmc_defconfig +0 -1
@@ -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
configs/imx6qdl_icore_nand_defconfig +0 -1
@@ -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
Signature · 1 line
2.7.4