4 * Copyright 2010-2012 Freescale Semiconductor, Inc.
6 * Add vsc8662 phy support - Priyanka Jain
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 /* Cicada Auxiliary Control/Status Register */
25 #define MIIM_CIS82xx_AUX_CONSTAT 0x1c
26 #define MIIM_CIS82xx_AUXCONSTAT_INIT 0x0004
27 #define MIIM_CIS82xx_AUXCONSTAT_DUPLEX 0x0020
28 #define MIIM_CIS82xx_AUXCONSTAT_SPEED 0x0018
29 #define MIIM_CIS82xx_AUXCONSTAT_GBIT 0x0010
30 #define MIIM_CIS82xx_AUXCONSTAT_100 0x0008
32 /* Cicada Extended Control Register 1 */
33 #define MIIM_CIS82xx_EXT_CON1 0x17
34 #define MIIM_CIS8201_EXTCON1_INIT 0x0000
36 /* Cicada 8204 Extended PHY Control Register 1 */
37 #define MIIM_CIS8204_EPHY_CON 0x17
38 #define MIIM_CIS8204_EPHYCON_INIT 0x0006
39 #define MIIM_CIS8204_EPHYCON_RGMII 0x1100
41 /* Cicada 8204 Serial LED Control Register */
42 #define MIIM_CIS8204_SLED_CON 0x1b
43 #define MIIM_CIS8204_SLEDCON_INIT 0x1115
45 /* Vitesse VSC8601 Extended PHY Control Register 1 */
46 #define MIIM_VSC8601_EPHY_CON 0x17
47 #define MIIM_VSC8601_EPHY_CON_INIT_SKEW 0x1120
48 #define MIIM_VSC8601_SKEW_CTRL 0x1c
50 #define PHY_EXT_PAGE_ACCESS 0x1f
51 #define PHY_EXT_PAGE_ACCESS_GENERAL 0x10
52 #define PHY_EXT_PAGE_ACCESS_EXTENDED3 0x3
54 /* Vitesse VSC8574 control register */
55 #define MIIM_VSC8574_MAC_SERDES_CON 0x10
56 #define MIIM_VSC8574_MAC_SERDES_ANEG 0x80
57 #define MIIM_VSC8574_GENERAL18 0x12
58 #define MIIM_VSC8574_GENERAL19 0x13
60 /* Vitesse VSC8574 gerenal purpose register 18 */
61 #define MIIM_VSC8574_18G_SGMII 0x80f0
62 #define MIIM_VSC8574_18G_QSGMII 0x80e0
63 #define MIIM_VSC8574_18G_CMDSTAT 0x8000
66 static int vitesse_config(struct phy_device *phydev)
68 /* Override PHY config settings */
69 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT,
70 MIIM_CIS82xx_AUXCONSTAT_INIT);
71 /* Set up the interface mode */
72 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_EXT_CON1,
73 MIIM_CIS8201_EXTCON1_INIT);
75 genphy_config_aneg(phydev);
80 static int vitesse_parse_status(struct phy_device *phydev)
85 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT);
87 if (mii_reg & MIIM_CIS82xx_AUXCONSTAT_DUPLEX)
88 phydev->duplex = DUPLEX_FULL;
90 phydev->duplex = DUPLEX_HALF;
92 speed = mii_reg & MIIM_CIS82xx_AUXCONSTAT_SPEED;
94 case MIIM_CIS82xx_AUXCONSTAT_GBIT:
95 phydev->speed = SPEED_1000;
97 case MIIM_CIS82xx_AUXCONSTAT_100:
98 phydev->speed = SPEED_100;
101 phydev->speed = SPEED_10;
108 static int vitesse_startup(struct phy_device *phydev)
110 genphy_update_link(phydev);
111 vitesse_parse_status(phydev);
116 static int cis8204_config(struct phy_device *phydev)
118 /* Override PHY config settings */
119 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT,
120 MIIM_CIS82xx_AUXCONSTAT_INIT);
122 genphy_config_aneg(phydev);
124 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
125 (phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
126 (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
127 (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
128 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
129 MIIM_CIS8204_EPHYCON_INIT |
130 MIIM_CIS8204_EPHYCON_RGMII);
132 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
133 MIIM_CIS8204_EPHYCON_INIT);
138 /* Vitesse VSC8601 */
139 static int vsc8601_config(struct phy_device *phydev)
141 /* Configure some basic stuff */
142 #ifdef CONFIG_SYS_VSC8601_SKEWFIX
143 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_EPHY_CON,
144 MIIM_VSC8601_EPHY_CON_INIT_SKEW);
145 #if defined(CONFIG_SYS_VSC8601_SKEW_TX) && defined(CONFIG_SYS_VSC8601_SKEW_RX)
146 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 1);
147 #define VSC8101_SKEW \
148 ((CONFIG_SYS_VSC8601_SKEW_TX << 14) \
149 | (CONFIG_SYS_VSC8601_SKEW_RX << 12))
150 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_SKEW_CTRL,
152 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
156 genphy_config_aneg(phydev);
161 static int vsc8574_config(struct phy_device *phydev)
164 /* configure regiser 19G for MAC */
165 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
166 PHY_EXT_PAGE_ACCESS_GENERAL);
168 val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19);
169 if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) {
170 /* set bit 15:14 to '01' for QSGMII mode */
171 val = (val & 0x3fff) | (1 << 14);
172 phy_write(phydev, MDIO_DEVAD_NONE,
173 MIIM_VSC8574_GENERAL19, val);
174 /* Enable 4 ports MAC QSGMII */
175 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18,
176 MIIM_VSC8574_18G_QSGMII);
178 /* set bit 15:14 to '00' for SGMII mode */
180 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL19, val);
181 /* Enable 4 ports MAC SGMII */
182 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18,
183 MIIM_VSC8574_18G_SGMII);
185 val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18);
186 /* When bit 15 is cleared the command has completed */
187 while (val & MIIM_VSC8574_18G_CMDSTAT)
188 val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_GENERAL18);
190 /* Enable Serdes Auto-negotiation */
191 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
192 PHY_EXT_PAGE_ACCESS_EXTENDED3);
193 val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON);
194 val = val | MIIM_VSC8574_MAC_SERDES_ANEG;
195 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8574_MAC_SERDES_CON, val);
197 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
199 genphy_config_aneg(phydev);
204 static struct phy_driver VSC8211_driver = {
205 .name = "Vitesse VSC8211",
208 .features = PHY_GBIT_FEATURES,
209 .config = &vitesse_config,
210 .startup = &vitesse_startup,
211 .shutdown = &genphy_shutdown,
214 static struct phy_driver VSC8221_driver = {
215 .name = "Vitesse VSC8221",
218 .features = PHY_GBIT_FEATURES,
219 .config = &genphy_config_aneg,
220 .startup = &vitesse_startup,
221 .shutdown = &genphy_shutdown,
224 static struct phy_driver VSC8244_driver = {
225 .name = "Vitesse VSC8244",
228 .features = PHY_GBIT_FEATURES,
229 .config = &genphy_config_aneg,
230 .startup = &vitesse_startup,
231 .shutdown = &genphy_shutdown,
234 static struct phy_driver VSC8234_driver = {
235 .name = "Vitesse VSC8234",
238 .features = PHY_GBIT_FEATURES,
239 .config = &genphy_config_aneg,
240 .startup = &vitesse_startup,
241 .shutdown = &genphy_shutdown,
244 static struct phy_driver VSC8574_driver = {
245 .name = "Vitesse VSC8574",
248 .features = PHY_GBIT_FEATURES,
249 .config = &vsc8574_config,
250 .startup = &vitesse_startup,
251 .shutdown = &genphy_shutdown,
254 static struct phy_driver VSC8601_driver = {
255 .name = "Vitesse VSC8601",
258 .features = PHY_GBIT_FEATURES,
259 .config = &vsc8601_config,
260 .startup = &vitesse_startup,
261 .shutdown = &genphy_shutdown,
264 static struct phy_driver VSC8641_driver = {
265 .name = "Vitesse VSC8641",
268 .features = PHY_GBIT_FEATURES,
269 .config = &genphy_config_aneg,
270 .startup = &vitesse_startup,
271 .shutdown = &genphy_shutdown,
274 static struct phy_driver VSC8662_driver = {
275 .name = "Vitesse VSC8662",
278 .features = PHY_GBIT_FEATURES,
279 .config = &genphy_config_aneg,
280 .startup = &vitesse_startup,
281 .shutdown = &genphy_shutdown,
284 /* Vitesse bought Cicada, so we'll put these here */
285 static struct phy_driver cis8201_driver = {
289 .features = PHY_GBIT_FEATURES,
290 .config = &vitesse_config,
291 .startup = &vitesse_startup,
292 .shutdown = &genphy_shutdown,
295 static struct phy_driver cis8204_driver = {
296 .name = "Cicada Cis8204",
299 .features = PHY_GBIT_FEATURES,
300 .config = &cis8204_config,
301 .startup = &vitesse_startup,
302 .shutdown = &genphy_shutdown,
305 int phy_vitesse_init(void)
307 phy_register(&VSC8641_driver);
308 phy_register(&VSC8601_driver);
309 phy_register(&VSC8234_driver);
310 phy_register(&VSC8244_driver);
311 phy_register(&VSC8211_driver);
312 phy_register(&VSC8221_driver);
313 phy_register(&VSC8574_driver);
314 phy_register(&VSC8662_driver);
315 phy_register(&cis8201_driver);
316 phy_register(&cis8204_driver);