blob: c283d823b2c92a6285d20a6a00c69803ed74a1b0 [file] [log] [blame]
Andy Fleming60ca78b2011-04-07 21:56:05 -05001/*
2 * Vitesse PHY drivers
3 *
Priyanka Jain56867572012-08-17 08:28:56 +00004 * Copyright 2010-2012 Freescale Semiconductor, Inc.
5 * Author: Andy Fleming
6 * Add vsc8662 phy support - Priyanka Jain
Andy Fleming60ca78b2011-04-07 21:56:05 -05007 * 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.
11 *
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.
16 *
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,
20 * MA 02111-1307 USA
Andy Fleming60ca78b2011-04-07 21:56:05 -050021 */
22#include <miiphy.h>
23
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
31
32/* Cicada Extended Control Register 1 */
33#define MIIM_CIS82xx_EXT_CON1 0x17
34#define MIIM_CIS8201_EXTCON1_INIT 0x0000
35
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
40
41/* Cicada 8204 Serial LED Control Register */
42#define MIIM_CIS8204_SLED_CON 0x1b
43#define MIIM_CIS8204_SLEDCON_INIT 0x1115
44
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
49
50#define PHY_EXT_PAGE_ACCESS 0x1f
Shaohui Xieaab42572013-03-25 07:39:31 +000051#define PHY_EXT_PAGE_ACCESS_GENERAL 0x10
52#define PHY_EXT_PAGE_ACCESS_EXTENDED3 0x3
53
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
59
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
Andy Fleming60ca78b2011-04-07 21:56:05 -050064
65/* CIS8201 */
66static int vitesse_config(struct phy_device *phydev)
67{
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);
74
75 genphy_config_aneg(phydev);
76
77 return 0;
78}
79
80static int vitesse_parse_status(struct phy_device *phydev)
81{
82 int speed;
83 int mii_reg;
84
85 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT);
86
87 if (mii_reg & MIIM_CIS82xx_AUXCONSTAT_DUPLEX)
88 phydev->duplex = DUPLEX_FULL;
89 else
90 phydev->duplex = DUPLEX_HALF;
91
92 speed = mii_reg & MIIM_CIS82xx_AUXCONSTAT_SPEED;
93 switch (speed) {
94 case MIIM_CIS82xx_AUXCONSTAT_GBIT:
95 phydev->speed = SPEED_1000;
96 break;
97 case MIIM_CIS82xx_AUXCONSTAT_100:
98 phydev->speed = SPEED_100;
99 break;
100 default:
101 phydev->speed = SPEED_10;
102 break;
103 }
104
105 return 0;
106}
107
108static int vitesse_startup(struct phy_device *phydev)
109{
110 genphy_update_link(phydev);
111 vitesse_parse_status(phydev);
112
113 return 0;
114}
115
116static int cis8204_config(struct phy_device *phydev)
117{
118 /* Override PHY config settings */
119 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT,
120 MIIM_CIS82xx_AUXCONSTAT_INIT);
121
122 genphy_config_aneg(phydev);
123
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);
131 else
132 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
133 MIIM_CIS8204_EPHYCON_INIT);
134
135 return 0;
136}
137
138/* Vitesse VSC8601 */
Kim Phillips914b0782012-10-29 13:34:34 +0000139static int vsc8601_config(struct phy_device *phydev)
Andy Fleming60ca78b2011-04-07 21:56:05 -0500140{
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,
151 VSC8101_SKEW);
152 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
153#endif
154#endif
155
156 genphy_config_aneg(phydev);
157
158 return 0;
159}
160
Shaohui Xieaab42572013-03-25 07:39:31 +0000161static int vsc8574_config(struct phy_device *phydev)
162{
163 u32 val;
164 /* configure regiser 19G for MAC */
165 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS,
166 PHY_EXT_PAGE_ACCESS_GENERAL);
167
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);
177 } else {
178 /* set bit 15:14 to '00' for SGMII mode */
179 val = val & 0x3fff;
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);
184 }
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);
189
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);
196
197 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
198
199 genphy_config_aneg(phydev);
200
201 return 0;
202}
203
Andy Fleming60ca78b2011-04-07 21:56:05 -0500204static struct phy_driver VSC8211_driver = {
205 .name = "Vitesse VSC8211",
206 .uid = 0xfc4b0,
207 .mask = 0xffff0,
208 .features = PHY_GBIT_FEATURES,
209 .config = &vitesse_config,
210 .startup = &vitesse_startup,
211 .shutdown = &genphy_shutdown,
212};
213
214static struct phy_driver VSC8221_driver = {
215 .name = "Vitesse VSC8221",
216 .uid = 0xfc550,
217 .mask = 0xffff0,
218 .features = PHY_GBIT_FEATURES,
219 .config = &genphy_config_aneg,
220 .startup = &vitesse_startup,
221 .shutdown = &genphy_shutdown,
222};
223
224static struct phy_driver VSC8244_driver = {
225 .name = "Vitesse VSC8244",
226 .uid = 0xfc6c0,
227 .mask = 0xffff0,
228 .features = PHY_GBIT_FEATURES,
229 .config = &genphy_config_aneg,
230 .startup = &vitesse_startup,
231 .shutdown = &genphy_shutdown,
232};
233
234static struct phy_driver VSC8234_driver = {
235 .name = "Vitesse VSC8234",
236 .uid = 0xfc620,
237 .mask = 0xffff0,
238 .features = PHY_GBIT_FEATURES,
239 .config = &genphy_config_aneg,
240 .startup = &vitesse_startup,
241 .shutdown = &genphy_shutdown,
242};
243
Shaohui Xieaab42572013-03-25 07:39:31 +0000244static struct phy_driver VSC8574_driver = {
245 .name = "Vitesse VSC8574",
246 .uid = 0x704a0,
247 .mask = 0xffff0,
248 .features = PHY_GBIT_FEATURES,
249 .config = &vsc8574_config,
250 .startup = &vitesse_startup,
251 .shutdown = &genphy_shutdown,
252};
253
Andy Fleming60ca78b2011-04-07 21:56:05 -0500254static struct phy_driver VSC8601_driver = {
255 .name = "Vitesse VSC8601",
256 .uid = 0x70420,
257 .mask = 0xffff0,
258 .features = PHY_GBIT_FEATURES,
259 .config = &vsc8601_config,
260 .startup = &vitesse_startup,
261 .shutdown = &genphy_shutdown,
262};
263
264static struct phy_driver VSC8641_driver = {
265 .name = "Vitesse VSC8641",
266 .uid = 0x70430,
267 .mask = 0xffff0,
268 .features = PHY_GBIT_FEATURES,
269 .config = &genphy_config_aneg,
270 .startup = &vitesse_startup,
271 .shutdown = &genphy_shutdown,
272};
273
Priyanka Jain56867572012-08-17 08:28:56 +0000274static struct phy_driver VSC8662_driver = {
275 .name = "Vitesse VSC8662",
276 .uid = 0x70660,
277 .mask = 0xffff0,
278 .features = PHY_GBIT_FEATURES,
279 .config = &genphy_config_aneg,
280 .startup = &vitesse_startup,
281 .shutdown = &genphy_shutdown,
282};
283
Andy Fleming60ca78b2011-04-07 21:56:05 -0500284/* Vitesse bought Cicada, so we'll put these here */
285static struct phy_driver cis8201_driver = {
286 .name = "CIS8201",
287 .uid = 0xfc410,
288 .mask = 0xffff0,
289 .features = PHY_GBIT_FEATURES,
290 .config = &vitesse_config,
291 .startup = &vitesse_startup,
292 .shutdown = &genphy_shutdown,
293};
294
295static struct phy_driver cis8204_driver = {
296 .name = "Cicada Cis8204",
297 .uid = 0xfc440,
298 .mask = 0xffff0,
299 .features = PHY_GBIT_FEATURES,
300 .config = &cis8204_config,
301 .startup = &vitesse_startup,
302 .shutdown = &genphy_shutdown,
303};
304
305int phy_vitesse_init(void)
306{
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);
Shaohui Xieaab42572013-03-25 07:39:31 +0000313 phy_register(&VSC8574_driver);
Priyanka Jain56867572012-08-17 08:28:56 +0000314 phy_register(&VSC8662_driver);
Andy Fleming60ca78b2011-04-07 21:56:05 -0500315 phy_register(&cis8201_driver);
316 phy_register(&cis8204_driver);
317
318 return 0;
319}