]>
Commit | Line | Data |
---|---|---|
9082eeac AF |
1 | /* |
2 | * Marvell PHY drivers | |
3 | * | |
1a459660 | 4 | * SPDX-License-Identifier: GPL-2.0+ |
9082eeac AF |
5 | * |
6 | * Copyright 2010-2011 Freescale Semiconductor, Inc. | |
7 | * author Andy Fleming | |
9082eeac AF |
8 | */ |
9 | #include <config.h> | |
10 | #include <common.h> | |
11 | #include <phy.h> | |
12 | ||
13 | #define PHY_AUTONEGOTIATE_TIMEOUT 5000 | |
14 | ||
15 | /* 88E1011 PHY Status Register */ | |
16 | #define MIIM_88E1xxx_PHY_STATUS 0x11 | |
17 | #define MIIM_88E1xxx_PHYSTAT_SPEED 0xc000 | |
18 | #define MIIM_88E1xxx_PHYSTAT_GBIT 0x8000 | |
19 | #define MIIM_88E1xxx_PHYSTAT_100 0x4000 | |
20 | #define MIIM_88E1xxx_PHYSTAT_DUPLEX 0x2000 | |
21 | #define MIIM_88E1xxx_PHYSTAT_SPDDONE 0x0800 | |
22 | #define MIIM_88E1xxx_PHYSTAT_LINK 0x0400 | |
23 | ||
24 | #define MIIM_88E1xxx_PHY_SCR 0x10 | |
25 | #define MIIM_88E1xxx_PHY_MDI_X_AUTO 0x0060 | |
26 | ||
27 | /* 88E1111 PHY LED Control Register */ | |
28 | #define MIIM_88E1111_PHY_LED_CONTROL 24 | |
29 | #define MIIM_88E1111_PHY_LED_DIRECT 0x4100 | |
30 | #define MIIM_88E1111_PHY_LED_COMBINE 0x411C | |
31 | ||
fa12a08e ZRR |
32 | /* 88E1111 Extended PHY Specific Control Register */ |
33 | #define MIIM_88E1111_PHY_EXT_CR 0x14 | |
34 | #define MIIM_88E1111_RX_DELAY 0x80 | |
35 | #define MIIM_88E1111_TX_DELAY 0x2 | |
36 | ||
37 | /* 88E1111 Extended PHY Specific Status Register */ | |
38 | #define MIIM_88E1111_PHY_EXT_SR 0x1b | |
39 | #define MIIM_88E1111_HWCFG_MODE_MASK 0xf | |
40 | #define MIIM_88E1111_HWCFG_MODE_COPPER_RGMII 0xb | |
41 | #define MIIM_88E1111_HWCFG_MODE_FIBER_RGMII 0x3 | |
42 | #define MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK 0x4 | |
43 | #define MIIM_88E1111_HWCFG_MODE_COPPER_RTBI 0x9 | |
44 | #define MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO 0x8000 | |
45 | #define MIIM_88E1111_HWCFG_FIBER_COPPER_RES 0x2000 | |
46 | ||
47 | #define MIIM_88E1111_COPPER 0 | |
48 | #define MIIM_88E1111_FIBER 1 | |
49 | ||
9082eeac AF |
50 | /* 88E1118 PHY defines */ |
51 | #define MIIM_88E1118_PHY_PAGE 22 | |
52 | #define MIIM_88E1118_PHY_LED_PAGE 3 | |
53 | ||
54 | /* 88E1121 PHY LED Control Register */ | |
55 | #define MIIM_88E1121_PHY_LED_CTRL 16 | |
56 | #define MIIM_88E1121_PHY_LED_PAGE 3 | |
57 | #define MIIM_88E1121_PHY_LED_DEF 0x0030 | |
58 | ||
59 | /* 88E1121 PHY IRQ Enable/Status Register */ | |
60 | #define MIIM_88E1121_PHY_IRQ_EN 18 | |
61 | #define MIIM_88E1121_PHY_IRQ_STATUS 19 | |
62 | ||
63 | #define MIIM_88E1121_PHY_PAGE 22 | |
64 | ||
65 | /* 88E1145 Extended PHY Specific Control Register */ | |
66 | #define MIIM_88E1145_PHY_EXT_CR 20 | |
67 | #define MIIM_M88E1145_RGMII_RX_DELAY 0x0080 | |
68 | #define MIIM_M88E1145_RGMII_TX_DELAY 0x0002 | |
69 | ||
70 | #define MIIM_88E1145_PHY_LED_CONTROL 24 | |
71 | #define MIIM_88E1145_PHY_LED_DIRECT 0x4100 | |
72 | ||
73 | #define MIIM_88E1145_PHY_PAGE 29 | |
74 | #define MIIM_88E1145_PHY_CAL_OV 30 | |
75 | ||
76 | #define MIIM_88E1149_PHY_PAGE 29 | |
77 | ||
aeceec0d SH |
78 | /* 88E1310 PHY defines */ |
79 | #define MIIM_88E1310_PHY_LED_CTRL 16 | |
80 | #define MIIM_88E1310_PHY_IRQ_EN 18 | |
81 | #define MIIM_88E1310_PHY_RGMII_CTRL 21 | |
82 | #define MIIM_88E1310_PHY_PAGE 22 | |
83 | ||
9082eeac AF |
84 | /* Marvell 88E1011S */ |
85 | static int m88e1011s_config(struct phy_device *phydev) | |
86 | { | |
87 | /* Reset and configure the PHY */ | |
88 | phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); | |
89 | ||
90 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); | |
91 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c); | |
92 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); | |
93 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0); | |
94 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); | |
95 | ||
96 | phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); | |
97 | ||
98 | genphy_config_aneg(phydev); | |
99 | ||
100 | return 0; | |
101 | } | |
102 | ||
103 | /* Parse the 88E1011's status register for speed and duplex | |
104 | * information | |
105 | */ | |
106 | static uint m88e1xxx_parse_status(struct phy_device *phydev) | |
107 | { | |
108 | unsigned int speed; | |
109 | unsigned int mii_reg; | |
110 | ||
111 | mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_STATUS); | |
112 | ||
113 | if ((mii_reg & MIIM_88E1xxx_PHYSTAT_LINK) && | |
114 | !(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) { | |
115 | int i = 0; | |
116 | ||
117 | puts("Waiting for PHY realtime link"); | |
118 | while (!(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) { | |
119 | /* Timeout reached ? */ | |
120 | if (i > PHY_AUTONEGOTIATE_TIMEOUT) { | |
121 | puts(" TIMEOUT !\n"); | |
122 | phydev->link = 0; | |
123 | break; | |
124 | } | |
125 | ||
126 | if ((i++ % 1000) == 0) | |
127 | putc('.'); | |
128 | udelay(1000); | |
129 | mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, | |
130 | MIIM_88E1xxx_PHY_STATUS); | |
131 | } | |
132 | puts(" done\n"); | |
133 | udelay(500000); /* another 500 ms (results in faster booting) */ | |
134 | } else { | |
135 | if (mii_reg & MIIM_88E1xxx_PHYSTAT_LINK) | |
136 | phydev->link = 1; | |
137 | else | |
138 | phydev->link = 0; | |
139 | } | |
140 | ||
141 | if (mii_reg & MIIM_88E1xxx_PHYSTAT_DUPLEX) | |
142 | phydev->duplex = DUPLEX_FULL; | |
143 | else | |
144 | phydev->duplex = DUPLEX_HALF; | |
145 | ||
146 | speed = mii_reg & MIIM_88E1xxx_PHYSTAT_SPEED; | |
147 | ||
148 | switch (speed) { | |
149 | case MIIM_88E1xxx_PHYSTAT_GBIT: | |
150 | phydev->speed = SPEED_1000; | |
151 | break; | |
152 | case MIIM_88E1xxx_PHYSTAT_100: | |
153 | phydev->speed = SPEED_100; | |
154 | break; | |
155 | default: | |
156 | phydev->speed = SPEED_10; | |
157 | break; | |
158 | } | |
159 | ||
160 | return 0; | |
161 | } | |
162 | ||
163 | static int m88e1011s_startup(struct phy_device *phydev) | |
164 | { | |
165 | genphy_update_link(phydev); | |
166 | m88e1xxx_parse_status(phydev); | |
167 | ||
168 | return 0; | |
169 | } | |
170 | ||
171 | /* Marvell 88E1111S */ | |
172 | static int m88e1111s_config(struct phy_device *phydev) | |
173 | { | |
174 | int reg; | |
fa12a08e | 175 | int timeout; |
9082eeac AF |
176 | |
177 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || | |
178 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || | |
179 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || | |
180 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { | |
fa12a08e ZRR |
181 | reg = phy_read(phydev, |
182 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR); | |
183 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || | |
184 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) { | |
185 | reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); | |
186 | } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { | |
187 | reg &= ~MIIM_88E1111_TX_DELAY; | |
188 | reg |= MIIM_88E1111_RX_DELAY; | |
189 | } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { | |
190 | reg &= ~MIIM_88E1111_RX_DELAY; | |
191 | reg |= MIIM_88E1111_TX_DELAY; | |
192 | } | |
193 | ||
194 | phy_write(phydev, | |
195 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg); | |
196 | ||
197 | reg = phy_read(phydev, | |
198 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR); | |
199 | ||
200 | reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); | |
201 | ||
202 | if (reg & MIIM_88E1111_HWCFG_FIBER_COPPER_RES) | |
203 | reg |= MIIM_88E1111_HWCFG_MODE_FIBER_RGMII; | |
204 | else | |
205 | reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII; | |
206 | ||
207 | phy_write(phydev, | |
208 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR, reg); | |
9082eeac AF |
209 | } |
210 | ||
fa12a08e ZRR |
211 | if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { |
212 | reg = phy_read(phydev, | |
213 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR); | |
214 | ||
215 | reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); | |
216 | reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK; | |
217 | reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; | |
218 | ||
219 | phy_write(phydev, MDIO_DEVAD_NONE, | |
220 | MIIM_88E1111_PHY_EXT_SR, reg); | |
221 | } | |
222 | ||
223 | if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { | |
224 | reg = phy_read(phydev, | |
225 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR); | |
226 | reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); | |
227 | phy_write(phydev, | |
228 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg); | |
229 | ||
230 | reg = phy_read(phydev, MDIO_DEVAD_NONE, | |
231 | MIIM_88E1111_PHY_EXT_SR); | |
232 | reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | | |
233 | MIIM_88E1111_HWCFG_FIBER_COPPER_RES); | |
234 | reg |= 0x7 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; | |
235 | phy_write(phydev, MDIO_DEVAD_NONE, | |
236 | MIIM_88E1111_PHY_EXT_SR, reg); | |
237 | ||
238 | /* soft reset */ | |
239 | timeout = 1000; | |
240 | phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); | |
241 | udelay(1000); | |
242 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); | |
243 | while ((reg & BMCR_RESET) && --timeout) { | |
244 | udelay(1000); | |
245 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); | |
246 | } | |
247 | if (!timeout) | |
248 | printf("%s: phy soft reset timeout\n", __func__); | |
249 | ||
250 | reg = phy_read(phydev, MDIO_DEVAD_NONE, | |
251 | MIIM_88E1111_PHY_EXT_SR); | |
252 | reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | | |
253 | MIIM_88E1111_HWCFG_FIBER_COPPER_RES); | |
254 | reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RTBI | | |
255 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; | |
256 | phy_write(phydev, MDIO_DEVAD_NONE, | |
257 | MIIM_88E1111_PHY_EXT_SR, reg); | |
258 | } | |
259 | ||
260 | /* soft reset */ | |
261 | timeout = 1000; | |
262 | phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); | |
263 | udelay(1000); | |
264 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); | |
265 | while ((reg & BMCR_RESET) && --timeout) { | |
266 | udelay(1000); | |
267 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); | |
268 | } | |
269 | if (!timeout) | |
270 | printf("%s: phy soft reset timeout\n", __func__); | |
9082eeac AF |
271 | |
272 | genphy_config_aneg(phydev); | |
273 | ||
274 | phy_reset(phydev); | |
275 | ||
276 | return 0; | |
277 | } | |
278 | ||
35fa0dda HZ |
279 | /** |
280 | * m88e1518_phy_writebits - write bits to a register | |
281 | */ | |
282 | void m88e1518_phy_writebits(struct phy_device *phydev, | |
283 | u8 reg_num, u16 offset, u16 len, u16 data) | |
284 | { | |
285 | u16 reg, mask; | |
286 | ||
287 | if ((len + offset) >= 16) | |
288 | mask = 0 - (1 << offset); | |
289 | else | |
290 | mask = (1 << (len + offset)) - (1 << offset); | |
291 | ||
292 | reg = phy_read(phydev, MDIO_DEVAD_NONE, reg_num); | |
293 | ||
294 | reg &= ~mask; | |
295 | reg |= data << offset; | |
296 | ||
297 | phy_write(phydev, MDIO_DEVAD_NONE, reg_num, reg); | |
298 | } | |
299 | ||
300 | static int m88e1518_config(struct phy_device *phydev) | |
301 | { | |
302 | /* | |
303 | * As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512 | |
304 | * /88E1514 Rev A0, Errata Section 3.1 | |
305 | */ | |
306 | if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { | |
307 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff); /* page 0xff */ | |
308 | phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B); | |
309 | phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144); | |
310 | phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28); | |
311 | phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146); | |
312 | phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233); | |
313 | phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D); | |
314 | phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C); | |
315 | phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159); | |
316 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000); /* reg page 0 */ | |
317 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 18); /* reg page 18 */ | |
318 | /* Write HWCFG_MODE = SGMII to Copper */ | |
319 | m88e1518_phy_writebits(phydev, 20, 0, 3, 1); | |
320 | ||
321 | /* Phy reset */ | |
322 | m88e1518_phy_writebits(phydev, 20, 15, 1, 1); | |
323 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); /* reg page 18 */ | |
324 | udelay(100); | |
325 | } | |
326 | ||
327 | return m88e1111s_config(phydev); | |
328 | } | |
329 | ||
9082eeac AF |
330 | /* Marvell 88E1118 */ |
331 | static int m88e1118_config(struct phy_device *phydev) | |
332 | { | |
333 | /* Change Page Number */ | |
334 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0002); | |
335 | /* Delay RGMII TX and RX */ | |
336 | phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x1070); | |
337 | /* Change Page Number */ | |
338 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0003); | |
339 | /* Adjust LED control */ | |
340 | phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x021e); | |
341 | /* Change Page Number */ | |
342 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); | |
343 | ||
344 | genphy_config_aneg(phydev); | |
345 | ||
346 | phy_reset(phydev); | |
347 | ||
348 | return 0; | |
349 | } | |
350 | ||
351 | static int m88e1118_startup(struct phy_device *phydev) | |
352 | { | |
353 | /* Change Page Number */ | |
354 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); | |
355 | ||
356 | genphy_update_link(phydev); | |
357 | m88e1xxx_parse_status(phydev); | |
358 | ||
359 | return 0; | |
360 | } | |
361 | ||
362 | /* Marvell 88E1121R */ | |
363 | static int m88e1121_config(struct phy_device *phydev) | |
364 | { | |
365 | int pg; | |
366 | ||
367 | /* Configure the PHY */ | |
368 | genphy_config_aneg(phydev); | |
369 | ||
370 | /* Switch the page to access the led register */ | |
371 | pg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE); | |
372 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, | |
373 | MIIM_88E1121_PHY_LED_PAGE); | |
374 | /* Configure leds */ | |
375 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_LED_CTRL, | |
376 | MIIM_88E1121_PHY_LED_DEF); | |
377 | /* Restore the page pointer */ | |
378 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, pg); | |
379 | ||
380 | /* Disable IRQs and de-assert interrupt */ | |
381 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_EN, 0); | |
382 | phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_STATUS); | |
383 | ||
384 | return 0; | |
385 | } | |
386 | ||
387 | /* Marvell 88E1145 */ | |
388 | static int m88e1145_config(struct phy_device *phydev) | |
389 | { | |
390 | int reg; | |
391 | ||
392 | /* Errata E0, E1 */ | |
393 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x001b); | |
394 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0x418f); | |
395 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x0016); | |
396 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0xa2da); | |
397 | ||
398 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_SCR, | |
399 | MIIM_88E1xxx_PHY_MDI_X_AUTO); | |
400 | ||
401 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR); | |
402 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) | |
403 | reg |= MIIM_M88E1145_RGMII_RX_DELAY | | |
404 | MIIM_M88E1145_RGMII_TX_DELAY; | |
405 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR, reg); | |
406 | ||
407 | genphy_config_aneg(phydev); | |
408 | ||
409 | phy_reset(phydev); | |
410 | ||
411 | return 0; | |
412 | } | |
413 | ||
414 | static int m88e1145_startup(struct phy_device *phydev) | |
415 | { | |
416 | genphy_update_link(phydev); | |
417 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_LED_CONTROL, | |
418 | MIIM_88E1145_PHY_LED_DIRECT); | |
419 | m88e1xxx_parse_status(phydev); | |
420 | ||
421 | return 0; | |
422 | } | |
423 | ||
424 | /* Marvell 88E1149S */ | |
425 | static int m88e1149_config(struct phy_device *phydev) | |
426 | { | |
427 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x1f); | |
428 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c); | |
429 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x5); | |
430 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x0); | |
431 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); | |
432 | ||
433 | genphy_config_aneg(phydev); | |
434 | ||
435 | phy_reset(phydev); | |
436 | ||
437 | return 0; | |
438 | } | |
439 | ||
aeceec0d SH |
440 | /* Marvell 88E1310 */ |
441 | static int m88e1310_config(struct phy_device *phydev) | |
442 | { | |
443 | u16 reg; | |
444 | ||
445 | /* LED link and activity */ | |
446 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003); | |
447 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL); | |
448 | reg = (reg & ~0xf) | 0x1; | |
449 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL, reg); | |
450 | ||
451 | /* Set LED2/INT to INT mode, low active */ | |
452 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003); | |
453 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN); | |
454 | reg = (reg & 0x77ff) | 0x0880; | |
455 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN, reg); | |
456 | ||
457 | /* Set RGMII delay */ | |
458 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0002); | |
459 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL); | |
460 | reg |= 0x0030; | |
461 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL, reg); | |
462 | ||
463 | /* Ensure to return to page 0 */ | |
464 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0000); | |
465 | ||
466 | genphy_config_aneg(phydev); | |
467 | phy_reset(phydev); | |
468 | ||
469 | return 0; | |
470 | } | |
9082eeac AF |
471 | |
472 | static struct phy_driver M88E1011S_driver = { | |
473 | .name = "Marvell 88E1011S", | |
474 | .uid = 0x1410c60, | |
475 | .mask = 0xffffff0, | |
476 | .features = PHY_GBIT_FEATURES, | |
477 | .config = &m88e1011s_config, | |
478 | .startup = &m88e1011s_startup, | |
479 | .shutdown = &genphy_shutdown, | |
480 | }; | |
481 | ||
482 | static struct phy_driver M88E1111S_driver = { | |
483 | .name = "Marvell 88E1111S", | |
484 | .uid = 0x1410cc0, | |
485 | .mask = 0xffffff0, | |
486 | .features = PHY_GBIT_FEATURES, | |
487 | .config = &m88e1111s_config, | |
488 | .startup = &m88e1011s_startup, | |
489 | .shutdown = &genphy_shutdown, | |
490 | }; | |
491 | ||
492 | static struct phy_driver M88E1118_driver = { | |
493 | .name = "Marvell 88E1118", | |
494 | .uid = 0x1410e10, | |
495 | .mask = 0xffffff0, | |
496 | .features = PHY_GBIT_FEATURES, | |
497 | .config = &m88e1118_config, | |
498 | .startup = &m88e1118_startup, | |
499 | .shutdown = &genphy_shutdown, | |
500 | }; | |
501 | ||
b4b81e83 MS |
502 | static struct phy_driver M88E1118R_driver = { |
503 | .name = "Marvell 88E1118R", | |
504 | .uid = 0x1410e40, | |
505 | .mask = 0xffffff0, | |
506 | .features = PHY_GBIT_FEATURES, | |
507 | .config = &m88e1118_config, | |
508 | .startup = &m88e1118_startup, | |
509 | .shutdown = &genphy_shutdown, | |
510 | }; | |
511 | ||
9082eeac AF |
512 | static struct phy_driver M88E1121R_driver = { |
513 | .name = "Marvell 88E1121R", | |
514 | .uid = 0x1410cb0, | |
515 | .mask = 0xffffff0, | |
516 | .features = PHY_GBIT_FEATURES, | |
517 | .config = &m88e1121_config, | |
518 | .startup = &genphy_startup, | |
519 | .shutdown = &genphy_shutdown, | |
520 | }; | |
521 | ||
522 | static struct phy_driver M88E1145_driver = { | |
523 | .name = "Marvell 88E1145", | |
524 | .uid = 0x1410cd0, | |
525 | .mask = 0xffffff0, | |
526 | .features = PHY_GBIT_FEATURES, | |
527 | .config = &m88e1145_config, | |
528 | .startup = &m88e1145_startup, | |
529 | .shutdown = &genphy_shutdown, | |
530 | }; | |
531 | ||
532 | static struct phy_driver M88E1149S_driver = { | |
533 | .name = "Marvell 88E1149S", | |
534 | .uid = 0x1410ca0, | |
535 | .mask = 0xffffff0, | |
536 | .features = PHY_GBIT_FEATURES, | |
537 | .config = &m88e1149_config, | |
538 | .startup = &m88e1011s_startup, | |
539 | .shutdown = &genphy_shutdown, | |
540 | }; | |
541 | ||
1415107e MS |
542 | static struct phy_driver M88E1518_driver = { |
543 | .name = "Marvell 88E1518", | |
544 | .uid = 0x1410dd1, | |
545 | .mask = 0xffffff0, | |
546 | .features = PHY_GBIT_FEATURES, | |
35fa0dda | 547 | .config = &m88e1518_config, |
1415107e MS |
548 | .startup = &m88e1011s_startup, |
549 | .shutdown = &genphy_shutdown, | |
550 | }; | |
551 | ||
aeceec0d SH |
552 | static struct phy_driver M88E1310_driver = { |
553 | .name = "Marvell 88E1310", | |
554 | .uid = 0x01410e90, | |
555 | .mask = 0xffffff0, | |
556 | .features = PHY_GBIT_FEATURES, | |
557 | .config = &m88e1310_config, | |
558 | .startup = &m88e1011s_startup, | |
559 | .shutdown = &genphy_shutdown, | |
560 | }; | |
561 | ||
9082eeac AF |
562 | int phy_marvell_init(void) |
563 | { | |
aeceec0d | 564 | phy_register(&M88E1310_driver); |
9082eeac AF |
565 | phy_register(&M88E1149S_driver); |
566 | phy_register(&M88E1145_driver); | |
567 | phy_register(&M88E1121R_driver); | |
568 | phy_register(&M88E1118_driver); | |
b4b81e83 | 569 | phy_register(&M88E1118R_driver); |
9082eeac AF |
570 | phy_register(&M88E1111S_driver); |
571 | phy_register(&M88E1011S_driver); | |
1415107e | 572 | phy_register(&M88E1518_driver); |
9082eeac AF |
573 | |
574 | return 0; | |
575 | } |