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