blob: 6c5cb99774d8afde8224d190d2f647e70db3d828 [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
51
52/* CIS8201 */
53static int vitesse_config(struct phy_device *phydev)
54{
55 /* Override PHY config settings */
56 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT,
57 MIIM_CIS82xx_AUXCONSTAT_INIT);
58 /* Set up the interface mode */
59 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_EXT_CON1,
60 MIIM_CIS8201_EXTCON1_INIT);
61
62 genphy_config_aneg(phydev);
63
64 return 0;
65}
66
67static int vitesse_parse_status(struct phy_device *phydev)
68{
69 int speed;
70 int mii_reg;
71
72 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT);
73
74 if (mii_reg & MIIM_CIS82xx_AUXCONSTAT_DUPLEX)
75 phydev->duplex = DUPLEX_FULL;
76 else
77 phydev->duplex = DUPLEX_HALF;
78
79 speed = mii_reg & MIIM_CIS82xx_AUXCONSTAT_SPEED;
80 switch (speed) {
81 case MIIM_CIS82xx_AUXCONSTAT_GBIT:
82 phydev->speed = SPEED_1000;
83 break;
84 case MIIM_CIS82xx_AUXCONSTAT_100:
85 phydev->speed = SPEED_100;
86 break;
87 default:
88 phydev->speed = SPEED_10;
89 break;
90 }
91
92 return 0;
93}
94
95static int vitesse_startup(struct phy_device *phydev)
96{
97 genphy_update_link(phydev);
98 vitesse_parse_status(phydev);
99
100 return 0;
101}
102
103static int cis8204_config(struct phy_device *phydev)
104{
105 /* Override PHY config settings */
106 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS82xx_AUX_CONSTAT,
107 MIIM_CIS82xx_AUXCONSTAT_INIT);
108
109 genphy_config_aneg(phydev);
110
111 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
112 (phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
113 (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
114 (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
115 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
116 MIIM_CIS8204_EPHYCON_INIT |
117 MIIM_CIS8204_EPHYCON_RGMII);
118 else
119 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
120 MIIM_CIS8204_EPHYCON_INIT);
121
122 return 0;
123}
124
125/* Vitesse VSC8601 */
Kim Phillips914b0782012-10-29 13:34:34 +0000126static int vsc8601_config(struct phy_device *phydev)
Andy Fleming60ca78b2011-04-07 21:56:05 -0500127{
128 /* Configure some basic stuff */
129#ifdef CONFIG_SYS_VSC8601_SKEWFIX
130 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_EPHY_CON,
131 MIIM_VSC8601_EPHY_CON_INIT_SKEW);
132#if defined(CONFIG_SYS_VSC8601_SKEW_TX) && defined(CONFIG_SYS_VSC8601_SKEW_RX)
133 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 1);
134#define VSC8101_SKEW \
135 ((CONFIG_SYS_VSC8601_SKEW_TX << 14) \
136 | (CONFIG_SYS_VSC8601_SKEW_RX << 12))
137 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_SKEW_CTRL,
138 VSC8101_SKEW);
139 phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0);
140#endif
141#endif
142
143 genphy_config_aneg(phydev);
144
145 return 0;
146}
147
148static struct phy_driver VSC8211_driver = {
149 .name = "Vitesse VSC8211",
150 .uid = 0xfc4b0,
151 .mask = 0xffff0,
152 .features = PHY_GBIT_FEATURES,
153 .config = &vitesse_config,
154 .startup = &vitesse_startup,
155 .shutdown = &genphy_shutdown,
156};
157
158static struct phy_driver VSC8221_driver = {
159 .name = "Vitesse VSC8221",
160 .uid = 0xfc550,
161 .mask = 0xffff0,
162 .features = PHY_GBIT_FEATURES,
163 .config = &genphy_config_aneg,
164 .startup = &vitesse_startup,
165 .shutdown = &genphy_shutdown,
166};
167
168static struct phy_driver VSC8244_driver = {
169 .name = "Vitesse VSC8244",
170 .uid = 0xfc6c0,
171 .mask = 0xffff0,
172 .features = PHY_GBIT_FEATURES,
173 .config = &genphy_config_aneg,
174 .startup = &vitesse_startup,
175 .shutdown = &genphy_shutdown,
176};
177
178static struct phy_driver VSC8234_driver = {
179 .name = "Vitesse VSC8234",
180 .uid = 0xfc620,
181 .mask = 0xffff0,
182 .features = PHY_GBIT_FEATURES,
183 .config = &genphy_config_aneg,
184 .startup = &vitesse_startup,
185 .shutdown = &genphy_shutdown,
186};
187
188static struct phy_driver VSC8601_driver = {
189 .name = "Vitesse VSC8601",
190 .uid = 0x70420,
191 .mask = 0xffff0,
192 .features = PHY_GBIT_FEATURES,
193 .config = &vsc8601_config,
194 .startup = &vitesse_startup,
195 .shutdown = &genphy_shutdown,
196};
197
198static struct phy_driver VSC8641_driver = {
199 .name = "Vitesse VSC8641",
200 .uid = 0x70430,
201 .mask = 0xffff0,
202 .features = PHY_GBIT_FEATURES,
203 .config = &genphy_config_aneg,
204 .startup = &vitesse_startup,
205 .shutdown = &genphy_shutdown,
206};
207
Priyanka Jain56867572012-08-17 08:28:56 +0000208static struct phy_driver VSC8662_driver = {
209 .name = "Vitesse VSC8662",
210 .uid = 0x70660,
211 .mask = 0xffff0,
212 .features = PHY_GBIT_FEATURES,
213 .config = &genphy_config_aneg,
214 .startup = &vitesse_startup,
215 .shutdown = &genphy_shutdown,
216};
217
Andy Fleming60ca78b2011-04-07 21:56:05 -0500218/* Vitesse bought Cicada, so we'll put these here */
219static struct phy_driver cis8201_driver = {
220 .name = "CIS8201",
221 .uid = 0xfc410,
222 .mask = 0xffff0,
223 .features = PHY_GBIT_FEATURES,
224 .config = &vitesse_config,
225 .startup = &vitesse_startup,
226 .shutdown = &genphy_shutdown,
227};
228
229static struct phy_driver cis8204_driver = {
230 .name = "Cicada Cis8204",
231 .uid = 0xfc440,
232 .mask = 0xffff0,
233 .features = PHY_GBIT_FEATURES,
234 .config = &cis8204_config,
235 .startup = &vitesse_startup,
236 .shutdown = &genphy_shutdown,
237};
238
239int phy_vitesse_init(void)
240{
241 phy_register(&VSC8641_driver);
242 phy_register(&VSC8601_driver);
243 phy_register(&VSC8234_driver);
244 phy_register(&VSC8244_driver);
245 phy_register(&VSC8211_driver);
246 phy_register(&VSC8221_driver);
Priyanka Jain56867572012-08-17 08:28:56 +0000247 phy_register(&VSC8662_driver);
Andy Fleming60ca78b2011-04-07 21:56:05 -0500248 phy_register(&cis8201_driver);
249 phy_register(&cis8204_driver);
250
251 return 0;
252}