diff options
author | Kim Phillips <kim.phillips@freescale.com> | 2008-01-15 20:11:00 (GMT) |
---|---|---|
committer | Ben Warren <biggerbadderben@gmail.com> | 2008-01-16 21:54:20 (GMT) |
commit | ee62ed3286f83b98b7785e0318dc6379e78f7ff6 (patch) | |
tree | b3cdde40e5e3eeb227186d9171f0c9d0f2d105b5 /drivers/qe/uec_phy.c | |
parent | 55fe7c57a8b99a130925052dcdbb77f053dc50e3 (diff) | |
download | u-boot-ee62ed3286f83b98b7785e0318dc6379e78f7ff6.tar.xz |
net: reduce boot latency on QE UEC based boards
actually polling for PHY autonegotiation to finish enables us to remove the
5 second boot prompt latency present on QE based boards.
call to qe_set_mii_clk_src in init_phy, and mv call to init_phy from
uec_initialize to uec_init by Joakim Tjernlund; autonegotiation wait
code shamelessly stolen from tsec driver.
also rm unused CONFIG_RMII_MODE code.
Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Signed-off-by: Ben Warren <biggerbadderben@gmail.com>
Diffstat (limited to 'drivers/qe/uec_phy.c')
-rw-r--r-- | drivers/qe/uec_phy.c | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c index ca6faa6..f890d4f 100644 --- a/drivers/qe/uec_phy.c +++ b/drivers/qe/uec_phy.c @@ -77,11 +77,10 @@ void uec_write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int valu /* Setting up the MII Mangement Control Register with the value */ out_be32 (&ug_regs->miimcon, (u32) value); + sync(); /* Wait till MII management write is complete */ while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY); - - udelay (100000); } /* Reads from register regnum in the PHY for device dev, */ @@ -101,16 +100,17 @@ int uec_read_phy_reg (struct eth_device *dev, int mii_id, int regnum) tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg; out_be32 (&ug_regs->miimadd, tmp_reg); - /* Perform an MII management read cycle */ + /* clear MII management command cycle */ out_be32 (&ug_regs->miimcom, 0); + sync(); + + /* Perform an MII management read cycle */ out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE); /* Wait till MII management write is complete */ while ((in_be32 (&ug_regs->miimind)) & (MIIMIND_NOT_VALID | MIIMIND_BUSY)); - udelay (100000); - /* Read MII management status */ value = (u16) in_be32 (&ug_regs->miimstat); if (value == 0xffff) @@ -270,20 +270,38 @@ static int genmii_update_link (struct uec_mii_info *mii_info) { u16 status; - /* Do a fake read */ + /* Status is read once to clear old link state */ phy_read (mii_info, PHY_BMSR); - /* Read link and autonegotiation status */ - status = phy_read (mii_info, PHY_BMSR); - if ((status & PHY_BMSR_LS) == 0) - mii_info->link = 0; - else + /* + * Wait if the link is up, and autonegotiation is in progress + * (ie - we're capable and it's not done) + */ + status = phy_read(mii_info, PHY_BMSR); + if ((status & PHY_BMSR_LS) && (status & PHY_BMSR_AUTN_ABLE) + && !(status & PHY_BMSR_AUTN_COMP)) { + int i = 0; + + while (!(status & PHY_BMSR_AUTN_COMP)) { + /* + * Timeout reached ? + */ + if (i > UGETH_AN_TIMEOUT) { + mii_info->link = 0; + return 0; + } + + udelay(1000); /* 1 ms */ + status = phy_read(mii_info, PHY_BMSR); + } mii_info->link = 1; - - /* If we are autonegotiating, and not done, - * return an error */ - if (mii_info->autoneg && !(status & PHY_BMSR_AUTN_COMP)) - return -EAGAIN; + udelay(500000); /* another 500 ms (results in faster booting) */ + } else { + if (status & PHY_BMSR_LS) + mii_info->link = 1; + else + mii_info->link = 0; + } return 0; } @@ -389,16 +407,12 @@ static int dm9161_init (struct uec_mii_info *mii_info) /* PHY and MAC connect */ phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) & ~PHY_BMCR_ISO); -#ifdef CONFIG_RMII_MODE - phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_RMII_INIT); -#else + phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT); -#endif + config_genmii_advert (mii_info); /* Start/restart aneg */ genmii_config_aneg (mii_info); - /* Delay to wait the aneg compeleted */ - udelay (3000000); return 0; } |