blob: 78447b711f5e51a8fca4f072d4622618ace28d41 [file] [log] [blame]
Andy Fleming9082eea2011-04-07 21:56:05 -05001/*
2 * Teranetics PHY drivers
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 *
19 * Copyright 2010-2011 Freescale Semiconductor, Inc.
20 * author Andy Fleming
21 *
22 */
23#include <config.h>
Timur Tabi2339e492011-10-07 15:35:21 -050024#include <common.h>
Andy Fleming9082eea2011-04-07 21:56:05 -050025#include <phy.h>
26
27#ifndef CONFIG_PHYLIB_10G
28#error The Teranetics PHY needs 10G support
29#endif
30
31int tn2020_config(struct phy_device *phydev)
32{
33 if (phydev->port == PORT_FIBRE) {
34 unsigned short restart_an = (MDIO_AN_CTRL1_RESTART |
35 MDIO_AN_CTRL1_ENABLE |
36 MDIO_AN_CTRL1_XNP);
37
38 phy_write(phydev, 30, 93, 2);
39 phy_write(phydev, MDIO_MMD_AN, MDIO_CTRL1, restart_an);
40 }
41
42 return 0;
43}
44
Andy Flemingebfdacb2011-04-20 18:41:17 -050045int tn2020_startup(struct phy_device *phydev)
46{
Timur Tabi2339e492011-10-07 15:35:21 -050047 unsigned int timeout = 5 * 1000; /* 5 second timeout */
48
49#define MDIO_PHYXS_LANE_READY (MDIO_PHYXS_LNSTAT_SYNC0 | \
50 MDIO_PHYXS_LNSTAT_SYNC1 | \
51 MDIO_PHYXS_LNSTAT_SYNC2 | \
52 MDIO_PHYXS_LNSTAT_SYNC3 | \
53 MDIO_PHYXS_LNSTAT_ALIGN)
54
55 /*
56 * Wait for the XAUI-SERDES lanes to align first. Under normal
57 * circumstances, this can take up to three seconds.
58 */
59 while (--timeout) {
60 int reg = phy_read(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_LNSTAT);
61 if (reg < 0) {
62 printf("TN2020: Error reading from PHY at "
63 "address %u\n", phydev->addr);
64 break;
65 }
66 if ((reg & MDIO_PHYXS_LANE_READY) == MDIO_PHYXS_LANE_READY)
67 break;
68 udelay(1000);
69 }
70 if (!timeout) {
71 /*
72 * A timeout is bad, but it may not be fatal, so don't
73 * return an error. Display a warning instead.
74 */
75 printf("TN2020: Timeout waiting for PHY at address %u to "
76 "align.\n", phydev->addr);
77 }
78
Andy Flemingebfdacb2011-04-20 18:41:17 -050079 if (phydev->port != PORT_FIBRE)
80 return gen10g_startup(phydev);
81
82 /*
83 * The TN2020 only pretends to support fiber.
84 * It works, but it doesn't look like it works,
85 * so the link status reports no link.
86 */
87 phydev->link = 1;
88
89 /* For now just lie and say it's 10G all the time */
90 phydev->speed = SPEED_10000;
91 phydev->duplex = DUPLEX_FULL;
92
93 return 0;
94}
95
Andy Fleming9082eea2011-04-07 21:56:05 -050096struct phy_driver tn2020_driver = {
97 .name = "Teranetics TN2020",
Timur Tabia8366262011-10-18 18:44:34 -050098 .uid = PHY_UID_TN2020,
Andy Fleming9082eea2011-04-07 21:56:05 -050099 .mask = 0xfffffff0,
100 .features = PHY_10G_FEATURES,
101 .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
102 MDIO_DEVS_PHYXS | MDIO_DEVS_AN |
103 MDIO_DEVS_VEND1 | MDIO_DEVS_VEND2),
104 .config = &tn2020_config,
Andy Flemingebfdacb2011-04-20 18:41:17 -0500105 .startup = &tn2020_startup,
Andy Fleming9082eea2011-04-07 21:56:05 -0500106 .shutdown = &gen10g_shutdown,
107};
108
109int phy_teranetics_init(void)
110{
111 phy_register(&tn2020_driver);
112
113 return 0;
114}