]>
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; | |
175 | ||
176 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || | |
177 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || | |
178 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || | |
179 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { | |
fa12a08e ZRR |
180 | reg = phy_read(phydev, |
181 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR); | |
182 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || | |
183 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) { | |
184 | reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); | |
185 | } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { | |
186 | reg &= ~MIIM_88E1111_TX_DELAY; | |
187 | reg |= MIIM_88E1111_RX_DELAY; | |
188 | } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { | |
189 | reg &= ~MIIM_88E1111_RX_DELAY; | |
190 | reg |= MIIM_88E1111_TX_DELAY; | |
191 | } | |
192 | ||
193 | phy_write(phydev, | |
194 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg); | |
195 | ||
196 | reg = phy_read(phydev, | |
197 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR); | |
198 | ||
199 | reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); | |
200 | ||
201 | if (reg & MIIM_88E1111_HWCFG_FIBER_COPPER_RES) | |
202 | reg |= MIIM_88E1111_HWCFG_MODE_FIBER_RGMII; | |
203 | else | |
204 | reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII; | |
205 | ||
206 | phy_write(phydev, | |
207 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR, reg); | |
9082eeac AF |
208 | } |
209 | ||
fa12a08e ZRR |
210 | if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { |
211 | reg = phy_read(phydev, | |
212 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR); | |
213 | ||
214 | reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); | |
215 | reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK; | |
216 | reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; | |
217 | ||
218 | phy_write(phydev, MDIO_DEVAD_NONE, | |
219 | MIIM_88E1111_PHY_EXT_SR, reg); | |
220 | } | |
221 | ||
222 | if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { | |
223 | reg = phy_read(phydev, | |
224 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR); | |
225 | reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); | |
226 | phy_write(phydev, | |
227 | MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg); | |
228 | ||
229 | reg = phy_read(phydev, MDIO_DEVAD_NONE, | |
230 | MIIM_88E1111_PHY_EXT_SR); | |
231 | reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | | |
232 | MIIM_88E1111_HWCFG_FIBER_COPPER_RES); | |
233 | reg |= 0x7 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; | |
234 | phy_write(phydev, MDIO_DEVAD_NONE, | |
235 | MIIM_88E1111_PHY_EXT_SR, reg); | |
236 | ||
237 | /* soft reset */ | |
3089c47d | 238 | phy_reset(phydev); |
fa12a08e ZRR |
239 | |
240 | reg = phy_read(phydev, MDIO_DEVAD_NONE, | |
241 | MIIM_88E1111_PHY_EXT_SR); | |
242 | reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | | |
243 | MIIM_88E1111_HWCFG_FIBER_COPPER_RES); | |
244 | reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RTBI | | |
245 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; | |
246 | phy_write(phydev, MDIO_DEVAD_NONE, | |
247 | MIIM_88E1111_PHY_EXT_SR, reg); | |
248 | } | |
249 | ||
250 | /* soft reset */ | |
3089c47d | 251 | phy_reset(phydev); |
9082eeac AF |
252 | |
253 | genphy_config_aneg(phydev); | |
254 | ||
255 | phy_reset(phydev); | |
256 | ||
257 | return 0; | |
258 | } | |
259 | ||
35fa0dda HZ |
260 | /** |
261 | * m88e1518_phy_writebits - write bits to a register | |
262 | */ | |
263 | void m88e1518_phy_writebits(struct phy_device *phydev, | |
264 | u8 reg_num, u16 offset, u16 len, u16 data) | |
265 | { | |
266 | u16 reg, mask; | |
267 | ||
268 | if ((len + offset) >= 16) | |
269 | mask = 0 - (1 << offset); | |
270 | else | |
271 | mask = (1 << (len + offset)) - (1 << offset); | |
272 | ||
273 | reg = phy_read(phydev, MDIO_DEVAD_NONE, reg_num); | |
274 | ||
275 | reg &= ~mask; | |
276 | reg |= data << offset; | |
277 | ||
278 | phy_write(phydev, MDIO_DEVAD_NONE, reg_num, reg); | |
279 | } | |
280 | ||
281 | static int m88e1518_config(struct phy_device *phydev) | |
282 | { | |
283 | /* | |
284 | * As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512 | |
285 | * /88E1514 Rev A0, Errata Section 3.1 | |
286 | */ | |
90a94ef6 CG |
287 | |
288 | /* EEE initialization */ | |
289 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff); | |
290 | phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B); | |
291 | phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144); | |
292 | phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28); | |
293 | phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146); | |
294 | phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233); | |
295 | phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D); | |
296 | phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C); | |
297 | phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159); | |
298 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000); | |
299 | ||
300 | /* SGMII-to-Copper mode initialization */ | |
35fa0dda | 301 | if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { |
90a94ef6 CG |
302 | /* Select page 18 */ |
303 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 18); | |
304 | ||
305 | /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */ | |
35fa0dda HZ |
306 | m88e1518_phy_writebits(phydev, 20, 0, 3, 1); |
307 | ||
90a94ef6 | 308 | /* PHY reset is necessary after changing MODE[2:0] */ |
35fa0dda | 309 | m88e1518_phy_writebits(phydev, 20, 15, 1, 1); |
90a94ef6 CG |
310 | |
311 | /* Reset page selection */ | |
312 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); | |
313 | ||
35fa0dda HZ |
314 | udelay(100); |
315 | } | |
316 | ||
317 | return m88e1111s_config(phydev); | |
318 | } | |
319 | ||
8396d0ab CG |
320 | /* Marvell 88E1510 */ |
321 | static int m88e1510_config(struct phy_device *phydev) | |
322 | { | |
323 | /* Select page 3 */ | |
324 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 3); | |
325 | ||
326 | /* Enable INTn output on LED[2] */ | |
327 | m88e1518_phy_writebits(phydev, 18, 7, 1, 1); | |
328 | ||
329 | /* Configure LEDs */ | |
330 | m88e1518_phy_writebits(phydev, 16, 0, 4, 3); /* LED[0]:0011 (ACT) */ | |
331 | m88e1518_phy_writebits(phydev, 16, 4, 4, 6); /* LED[1]:0110 (LINK) */ | |
332 | ||
333 | /* Reset page selection */ | |
334 | phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); | |
335 | ||
336 | return m88e1518_config(phydev); | |
337 | } | |
338 | ||
9082eeac AF |
339 | /* Marvell 88E1118 */ |
340 | static int m88e1118_config(struct phy_device *phydev) | |
341 | { | |
342 | /* Change Page Number */ | |
343 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0002); | |
344 | /* Delay RGMII TX and RX */ | |
345 | phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x1070); | |
346 | /* Change Page Number */ | |
347 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0003); | |
348 | /* Adjust LED control */ | |
349 | phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x021e); | |
350 | /* Change Page Number */ | |
351 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); | |
352 | ||
353 | genphy_config_aneg(phydev); | |
354 | ||
355 | phy_reset(phydev); | |
356 | ||
357 | return 0; | |
358 | } | |
359 | ||
360 | static int m88e1118_startup(struct phy_device *phydev) | |
361 | { | |
362 | /* Change Page Number */ | |
363 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); | |
364 | ||
365 | genphy_update_link(phydev); | |
366 | m88e1xxx_parse_status(phydev); | |
367 | ||
368 | return 0; | |
369 | } | |
370 | ||
371 | /* Marvell 88E1121R */ | |
372 | static int m88e1121_config(struct phy_device *phydev) | |
373 | { | |
374 | int pg; | |
375 | ||
376 | /* Configure the PHY */ | |
377 | genphy_config_aneg(phydev); | |
378 | ||
379 | /* Switch the page to access the led register */ | |
380 | pg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE); | |
381 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, | |
382 | MIIM_88E1121_PHY_LED_PAGE); | |
383 | /* Configure leds */ | |
384 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_LED_CTRL, | |
385 | MIIM_88E1121_PHY_LED_DEF); | |
386 | /* Restore the page pointer */ | |
387 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, pg); | |
388 | ||
389 | /* Disable IRQs and de-assert interrupt */ | |
390 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_EN, 0); | |
391 | phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_STATUS); | |
392 | ||
393 | return 0; | |
394 | } | |
395 | ||
396 | /* Marvell 88E1145 */ | |
397 | static int m88e1145_config(struct phy_device *phydev) | |
398 | { | |
399 | int reg; | |
400 | ||
401 | /* Errata E0, E1 */ | |
402 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x001b); | |
403 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0x418f); | |
404 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x0016); | |
405 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0xa2da); | |
406 | ||
407 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_SCR, | |
408 | MIIM_88E1xxx_PHY_MDI_X_AUTO); | |
409 | ||
410 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR); | |
411 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) | |
412 | reg |= MIIM_M88E1145_RGMII_RX_DELAY | | |
413 | MIIM_M88E1145_RGMII_TX_DELAY; | |
414 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR, reg); | |
415 | ||
416 | genphy_config_aneg(phydev); | |
417 | ||
418 | phy_reset(phydev); | |
419 | ||
420 | return 0; | |
421 | } | |
422 | ||
423 | static int m88e1145_startup(struct phy_device *phydev) | |
424 | { | |
425 | genphy_update_link(phydev); | |
426 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_LED_CONTROL, | |
427 | MIIM_88E1145_PHY_LED_DIRECT); | |
428 | m88e1xxx_parse_status(phydev); | |
429 | ||
430 | return 0; | |
431 | } | |
432 | ||
433 | /* Marvell 88E1149S */ | |
434 | static int m88e1149_config(struct phy_device *phydev) | |
435 | { | |
436 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x1f); | |
437 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c); | |
438 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x5); | |
439 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x0); | |
440 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); | |
441 | ||
442 | genphy_config_aneg(phydev); | |
443 | ||
444 | phy_reset(phydev); | |
445 | ||
446 | return 0; | |
447 | } | |
448 | ||
aeceec0d SH |
449 | /* Marvell 88E1310 */ |
450 | static int m88e1310_config(struct phy_device *phydev) | |
451 | { | |
452 | u16 reg; | |
453 | ||
454 | /* LED link and activity */ | |
455 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003); | |
456 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL); | |
457 | reg = (reg & ~0xf) | 0x1; | |
458 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL, reg); | |
459 | ||
460 | /* Set LED2/INT to INT mode, low active */ | |
461 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003); | |
462 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN); | |
463 | reg = (reg & 0x77ff) | 0x0880; | |
464 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN, reg); | |
465 | ||
466 | /* Set RGMII delay */ | |
467 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0002); | |
468 | reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL); | |
469 | reg |= 0x0030; | |
470 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL, reg); | |
471 | ||
472 | /* Ensure to return to page 0 */ | |
473 | phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0000); | |
474 | ||
475 | genphy_config_aneg(phydev); | |
476 | phy_reset(phydev); | |
477 | ||
478 | return 0; | |
479 | } | |
9082eeac AF |
480 | |
481 | static struct phy_driver M88E1011S_driver = { | |
482 | .name = "Marvell 88E1011S", | |
483 | .uid = 0x1410c60, | |
484 | .mask = 0xffffff0, | |
485 | .features = PHY_GBIT_FEATURES, | |
486 | .config = &m88e1011s_config, | |
487 | .startup = &m88e1011s_startup, | |
488 | .shutdown = &genphy_shutdown, | |
489 | }; | |
490 | ||
491 | static struct phy_driver M88E1111S_driver = { | |
492 | .name = "Marvell 88E1111S", | |
493 | .uid = 0x1410cc0, | |
494 | .mask = 0xffffff0, | |
495 | .features = PHY_GBIT_FEATURES, | |
496 | .config = &m88e1111s_config, | |
497 | .startup = &m88e1011s_startup, | |
498 | .shutdown = &genphy_shutdown, | |
499 | }; | |
500 | ||
501 | static struct phy_driver M88E1118_driver = { | |
502 | .name = "Marvell 88E1118", | |
503 | .uid = 0x1410e10, | |
504 | .mask = 0xffffff0, | |
505 | .features = PHY_GBIT_FEATURES, | |
506 | .config = &m88e1118_config, | |
507 | .startup = &m88e1118_startup, | |
508 | .shutdown = &genphy_shutdown, | |
509 | }; | |
510 | ||
b4b81e83 MS |
511 | static struct phy_driver M88E1118R_driver = { |
512 | .name = "Marvell 88E1118R", | |
513 | .uid = 0x1410e40, | |
514 | .mask = 0xffffff0, | |
515 | .features = PHY_GBIT_FEATURES, | |
516 | .config = &m88e1118_config, | |
517 | .startup = &m88e1118_startup, | |
518 | .shutdown = &genphy_shutdown, | |
519 | }; | |
520 | ||
9082eeac AF |
521 | static struct phy_driver M88E1121R_driver = { |
522 | .name = "Marvell 88E1121R", | |
523 | .uid = 0x1410cb0, | |
524 | .mask = 0xffffff0, | |
525 | .features = PHY_GBIT_FEATURES, | |
526 | .config = &m88e1121_config, | |
527 | .startup = &genphy_startup, | |
528 | .shutdown = &genphy_shutdown, | |
529 | }; | |
530 | ||
531 | static struct phy_driver M88E1145_driver = { | |
532 | .name = "Marvell 88E1145", | |
533 | .uid = 0x1410cd0, | |
534 | .mask = 0xffffff0, | |
535 | .features = PHY_GBIT_FEATURES, | |
536 | .config = &m88e1145_config, | |
537 | .startup = &m88e1145_startup, | |
538 | .shutdown = &genphy_shutdown, | |
539 | }; | |
540 | ||
541 | static struct phy_driver M88E1149S_driver = { | |
542 | .name = "Marvell 88E1149S", | |
543 | .uid = 0x1410ca0, | |
544 | .mask = 0xffffff0, | |
545 | .features = PHY_GBIT_FEATURES, | |
546 | .config = &m88e1149_config, | |
547 | .startup = &m88e1011s_startup, | |
548 | .shutdown = &genphy_shutdown, | |
549 | }; | |
550 | ||
8396d0ab CG |
551 | static struct phy_driver M88E1510_driver = { |
552 | .name = "Marvell 88E1510", | |
553 | .uid = 0x1410dd0, | |
554 | .mask = 0xffffff0, | |
555 | .features = PHY_GBIT_FEATURES, | |
556 | .config = &m88e1510_config, | |
557 | .startup = &m88e1011s_startup, | |
558 | .shutdown = &genphy_shutdown, | |
559 | }; | |
560 | ||
1415107e MS |
561 | static struct phy_driver M88E1518_driver = { |
562 | .name = "Marvell 88E1518", | |
563 | .uid = 0x1410dd1, | |
564 | .mask = 0xffffff0, | |
565 | .features = PHY_GBIT_FEATURES, | |
35fa0dda | 566 | .config = &m88e1518_config, |
1415107e MS |
567 | .startup = &m88e1011s_startup, |
568 | .shutdown = &genphy_shutdown, | |
569 | }; | |
570 | ||
aeceec0d SH |
571 | static struct phy_driver M88E1310_driver = { |
572 | .name = "Marvell 88E1310", | |
573 | .uid = 0x01410e90, | |
574 | .mask = 0xffffff0, | |
575 | .features = PHY_GBIT_FEATURES, | |
576 | .config = &m88e1310_config, | |
577 | .startup = &m88e1011s_startup, | |
578 | .shutdown = &genphy_shutdown, | |
579 | }; | |
580 | ||
9082eeac AF |
581 | int phy_marvell_init(void) |
582 | { | |
aeceec0d | 583 | phy_register(&M88E1310_driver); |
9082eeac AF |
584 | phy_register(&M88E1149S_driver); |
585 | phy_register(&M88E1145_driver); | |
586 | phy_register(&M88E1121R_driver); | |
587 | phy_register(&M88E1118_driver); | |
b4b81e83 | 588 | phy_register(&M88E1118R_driver); |
9082eeac AF |
589 | phy_register(&M88E1111S_driver); |
590 | phy_register(&M88E1011S_driver); | |
8396d0ab | 591 | phy_register(&M88E1510_driver); |
1415107e | 592 | phy_register(&M88E1518_driver); |
9082eeac AF |
593 | |
594 | return 0; | |
595 | } |