summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFugang Duan <B38611@freescale.com>2011-11-25 18:38:26 +0800
committerFugang Duan <B38611@freescale.com>2011-11-25 19:45:10 +0800
commitf1229ce6330c3e66eadf92d85881519c894e93cb (patch)
treee932bd574a6210abede069e93037d47211fdf724
parent6f3add03329b8449e955a817388d95ca5d5d793a (diff)
downloadu-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.c32
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);