]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/phy/vitesse.c
net: Add Vitesse VSC8662 PHY support
[karo-tx-uboot.git] / drivers / net / phy / vitesse.c
1 /*
2  * Vitesse PHY drivers
3  *
4  * Copyright 2010-2012 Freescale Semiconductor, Inc.
5  * Author: Andy Fleming
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.
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
21  */
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 */
53 static 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
67 static 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
95 static int vitesse_startup(struct phy_device *phydev)
96 {
97         genphy_update_link(phydev);
98         vitesse_parse_status(phydev);
99
100         return 0;
101 }
102
103 static 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 */
126 int vsc8601_config(struct phy_device *phydev)
127 {
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
148 static 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
158 static 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
168 static 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
178 static 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
188 static 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
198 static 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
208 static 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
218 /* Vitesse bought Cicada, so we'll put these here */
219 static 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
229 static 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
239 int 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);
247         phy_register(&VSC8662_driver);
248         phy_register(&cis8201_driver);
249         phy_register(&cis8204_driver);
250
251         return 0;
252 }