diff options
author | Fugang Duan <B38611@freescale.com> | 2011-11-25 18:38:26 +0800 |
---|---|---|
committer | Fugang Duan <B38611@freescale.com> | 2011-11-25 19:45:10 +0800 |
commit | f1229ce6330c3e66eadf92d85881519c894e93cb (patch) | |
tree | e932bd574a6210abede069e93037d47211fdf724 | |
parent | 6f3add03329b8449e955a817388d95ca5d5d793a (diff) | |
download | u-boot-imx-f1229ce6330c3e66eadf92d85881519c894e93cb.zip u-boot-imx-f1229ce6330c3e66eadf92d85881519c894e93cb.tar.gz u-boot-imx-f1229ce6330c3e66eadf92d85881519c894e93cb.tar.bz2 |
ENGR00163040 - FEC : Fix ethernet cannot work after system sleep.
- Descript:
Ethernet can't work in uboot and kernel DHCP throught press
'reset' key when send sleep command 'echo mem > /sys/power/state'
- Cause:
FEC driver will power down phy when system sleep. If just reset the
board, FEC driver cannot run resume function. So, need power on phy
in uboot and linux driver.
Signed-off-by: Fugang Duan <B38611@freescale.com>
-rw-r--r-- | drivers/net/mxc_fec.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/net/mxc_fec.c b/drivers/net/mxc_fec.c index 071c795..43ae26b 100644 --- a/drivers/net/mxc_fec.c +++ b/drivers/net/mxc_fec.c @@ -168,6 +168,10 @@ struct fec_info_s fec_info[] = { }, }; +static int mxc_fec_mii_read(char *devname, unsigned char addr, + unsigned char reg, unsigned short *value); +static int mxc_fec_mii_write(char *devname, unsigned char addr, + unsigned char reg, unsigned short value); int fec_send(struct eth_device *dev, volatile void *packet, int length); int fec_recv(struct eth_device *dev); int fec_init(struct eth_device *dev, bd_t *bd); @@ -182,6 +186,14 @@ static void mxc_fec_mii_init(volatile fec_t *fecp) fecp->mscr = (fecp->mscr & (~0x7E)) | (((clk + 499999) / 5000000) << 1); } +static void mxc_fec_phy_powerup(char *devname, int phy_addr) +{ + unsigned short value; + mxc_fec_mii_read(devname, phy_addr, PHY_BMCR, &value); + if (value & PHY_BMCR_POWD) + mxc_fec_mii_write(devname, phy_addr, PHY_BMCR, (value & ~PHY_BMCR_POWD)); +} + static inline int __fec_mii_read(volatile fec_t *fecp, unsigned char addr, unsigned char reg, unsigned short *value) { @@ -818,22 +830,31 @@ void dbgFecRegs(struct eth_device *dev) } #endif -int fec_init(struct eth_device *dev, bd_t *bd) +static void fec_mii_phy_init(struct eth_device *dev) { struct fec_info_s *info = dev->priv; volatile fec_t *fecp = (fec_t *) (info->iobase); - int i; - u8 *ea = NULL; fec_reset(dev); - - fec_localhw_setup((fec_t *)fecp); + fec_localhw_setup(fecp); #if defined (CONFIG_CMD_MII) || defined (CONFIG_MII) || \ defined (CONFIG_DISCOVER_PHY) mxc_fec_mii_init(fecp); #if defined (CONFIG_MX6Q) mx6_rgmii_rework(dev->name, info->phy_addr); #endif + mxc_fec_phy_powerup(dev->name, info->phy_addr); + +} + +int fec_init(struct eth_device *dev, bd_t *bd) +{ + struct fec_info_s *info = dev->priv; + volatile fec_t *fecp = (fec_t *) (info->iobase); + int i; + u8 *ea = NULL; + + fec_mii_phy_init(dev); #ifdef CONFIG_DISCOVER_PHY if (info->phy_addr < 0 || info->phy_addr > 0x1F) @@ -1038,7 +1059,6 @@ int mxc_fec_initialize(bd_t *bis) miiphy_register(dev->name, mxc_fec_mii_read, mxc_fec_mii_write); #endif - if (fec_get_hwaddr(dev, ethaddr) == 0) { printf("got MAC address from IIM: %pM\n", ethaddr); memcpy(dev->enetaddr, ethaddr, 6); |