summaryrefslogtreecommitdiff
path: root/drivers/qe/uec.c
diff options
context:
space:
mode:
authorKim Phillips <kim.phillips@freescale.com>2008-01-15 14:11:00 -0600
committerBen Warren <biggerbadderben@gmail.com>2008-01-16 16:54:20 -0500
commitee62ed3286f83b98b7785e0318dc6379e78f7ff6 (patch)
treeb3cdde40e5e3eeb227186d9171f0c9d0f2d105b5 /drivers/qe/uec.c
parent55fe7c57a8b99a130925052dcdbb77f053dc50e3 (diff)
downloadu-boot-imx-ee62ed3286f83b98b7785e0318dc6379e78f7ff6.zip
u-boot-imx-ee62ed3286f83b98b7785e0318dc6379e78f7ff6.tar.gz
u-boot-imx-ee62ed3286f83b98b7785e0318dc6379e78f7ff6.tar.bz2
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.c')
-rw-r--r--drivers/qe/uec.c69
1 files changed, 43 insertions, 26 deletions
diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c
index 9094643..55f37cb 100644
--- a/drivers/qe/uec.c
+++ b/drivers/qe/uec.c
@@ -512,6 +512,8 @@ static int init_phy(struct eth_device *dev)
uec->mii_info = mii_info;
+ qe_set_mii_clk_src(uec->uec_info->uf_info.ucc_num);
+
if (init_mii_management_configuration(umii_regs)) {
printf("%s: The MII Bus is stuck!", dev->name);
err = -1;
@@ -618,21 +620,12 @@ static void adjust_link(struct eth_device *dev)
static void phy_change(struct eth_device *dev)
{
uec_private_t *uec = (uec_private_t *)dev->priv;
- uec_t *uec_regs;
- int result = 0;
-
- uec_regs = uec->uec_regs;
-
- /* Delay 5s to give the PHY a chance to change the register state */
- udelay(5000000);
/* Update the link, speed, duplex */
- result = uec->mii_info->phyinfo->read_status(uec->mii_info);
+ uec->mii_info->phyinfo->read_status(uec->mii_info);
/* Adjust the interface according to speed */
- if ((0 == result) || (uec->mii_info->link == 0)) {
- adjust_link(dev);
- }
+ adjust_link(dev);
}
static int uec_set_mac_address(uec_private_t *uec, u8 *mac_addr)
@@ -1157,27 +1150,59 @@ static int uec_startup(uec_private_t *uec)
static int uec_init(struct eth_device* dev, bd_t *bd)
{
uec_private_t *uec;
- int err;
+ int err, i;
+ struct phy_info *curphy;
uec = (uec_private_t *)dev->priv;
if (uec->the_first_run == 0) {
- /* Set up the MAC address */
- if (dev->enetaddr[0] & 0x01) {
- printf("%s: MacAddress is multcast address\n",
- __FUNCTION__);
- return -1;
+ err = init_phy(dev);
+ if (err) {
+ printf("%s: Cannot initialize PHY, aborting.\n",
+ dev->name);
+ return err;
}
- uec_set_mac_address(uec, dev->enetaddr);
+
+ curphy = uec->mii_info->phyinfo;
+
+ if (curphy->config_aneg) {
+ err = curphy->config_aneg(uec->mii_info);
+ if (err) {
+ printf("%s: Can't negotiate PHY\n", dev->name);
+ return err;
+ }
+ }
+
+ /* Give PHYs up to 5 sec to report a link */
+ i = 50;
+ do {
+ err = curphy->read_status(uec->mii_info);
+ udelay(100000);
+ } while (((i-- > 0) && !uec->mii_info->link) || err);
+
+ if (err || i <= 0)
+ printf("warning: %s: timeout on PHY link\n", dev->name);
+
uec->the_first_run = 1;
}
+ /* Set up the MAC address */
+ if (dev->enetaddr[0] & 0x01) {
+ printf("%s: MacAddress is multcast address\n",
+ __FUNCTION__);
+ return -1;
+ }
+ uec_set_mac_address(uec, dev->enetaddr);
+
+
err = uec_open(uec, COMM_DIR_RX_AND_TX);
if (err) {
printf("%s: cannot enable UEC device\n", dev->name);
return -1;
}
+ phy_change(dev);
+
return (uec->mii_info->link ? 0 : -1);
}
@@ -1330,14 +1355,6 @@ int uec_initialize(int index)
return err;
}
- err = init_phy(dev);
- if (err) {
- printf("%s: Cannot initialize PHY, aborting.\n", dev->name);
- return err;
- }
-
- phy_change(dev);
-
return 1;
}
#endif /* CONFIG_QE */