4 * SPDX-License-Identifier: GPL-2.0+
6 * Copyright 2010-2011 Freescale Semiconductor, Inc.
14 #define PHY_AUTONEGOTIATE_TIMEOUT 5000
16 #define MII_MARVELL_PHY_PAGE 22
18 /* 88E1011 PHY Status Register */
19 #define MIIM_88E1xxx_PHY_STATUS 0x11
20 #define MIIM_88E1xxx_PHYSTAT_SPEED 0xc000
21 #define MIIM_88E1xxx_PHYSTAT_GBIT 0x8000
22 #define MIIM_88E1xxx_PHYSTAT_100 0x4000
23 #define MIIM_88E1xxx_PHYSTAT_DUPLEX 0x2000
24 #define MIIM_88E1xxx_PHYSTAT_SPDDONE 0x0800
25 #define MIIM_88E1xxx_PHYSTAT_LINK 0x0400
27 #define MIIM_88E1xxx_PHY_SCR 0x10
28 #define MIIM_88E1xxx_PHY_MDI_X_AUTO 0x0060
30 /* 88E1111 PHY LED Control Register */
31 #define MIIM_88E1111_PHY_LED_CONTROL 24
32 #define MIIM_88E1111_PHY_LED_DIRECT 0x4100
33 #define MIIM_88E1111_PHY_LED_COMBINE 0x411C
35 /* 88E1111 Extended PHY Specific Control Register */
36 #define MIIM_88E1111_PHY_EXT_CR 0x14
37 #define MIIM_88E1111_RX_DELAY 0x80
38 #define MIIM_88E1111_TX_DELAY 0x2
40 /* 88E1111 Extended PHY Specific Status Register */
41 #define MIIM_88E1111_PHY_EXT_SR 0x1b
42 #define MIIM_88E1111_HWCFG_MODE_MASK 0xf
43 #define MIIM_88E1111_HWCFG_MODE_COPPER_RGMII 0xb
44 #define MIIM_88E1111_HWCFG_MODE_FIBER_RGMII 0x3
45 #define MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK 0x4
46 #define MIIM_88E1111_HWCFG_MODE_COPPER_RTBI 0x9
47 #define MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO 0x8000
48 #define MIIM_88E1111_HWCFG_FIBER_COPPER_RES 0x2000
50 #define MIIM_88E1111_COPPER 0
51 #define MIIM_88E1111_FIBER 1
53 /* 88E1118 PHY defines */
54 #define MIIM_88E1118_PHY_PAGE 22
55 #define MIIM_88E1118_PHY_LED_PAGE 3
57 /* 88E1121 PHY LED Control Register */
58 #define MIIM_88E1121_PHY_LED_CTRL 16
59 #define MIIM_88E1121_PHY_LED_PAGE 3
60 #define MIIM_88E1121_PHY_LED_DEF 0x0030
62 /* 88E1121 PHY IRQ Enable/Status Register */
63 #define MIIM_88E1121_PHY_IRQ_EN 18
64 #define MIIM_88E1121_PHY_IRQ_STATUS 19
66 #define MIIM_88E1121_PHY_PAGE 22
68 /* 88E1145 Extended PHY Specific Control Register */
69 #define MIIM_88E1145_PHY_EXT_CR 20
70 #define MIIM_M88E1145_RGMII_RX_DELAY 0x0080
71 #define MIIM_M88E1145_RGMII_TX_DELAY 0x0002
73 #define MIIM_88E1145_PHY_LED_CONTROL 24
74 #define MIIM_88E1145_PHY_LED_DIRECT 0x4100
76 #define MIIM_88E1145_PHY_PAGE 29
77 #define MIIM_88E1145_PHY_CAL_OV 30
79 #define MIIM_88E1149_PHY_PAGE 29
81 /* 88E1310 PHY defines */
82 #define MIIM_88E1310_PHY_LED_CTRL 16
83 #define MIIM_88E1310_PHY_IRQ_EN 18
84 #define MIIM_88E1310_PHY_RGMII_CTRL 21
85 #define MIIM_88E1310_PHY_PAGE 22
87 /* 88E151x PHY defines */
88 /* Page 2 registers */
89 #define MIIM_88E151x_PHY_MSCR 21
90 #define MIIM_88E151x_RGMII_RX_DELAY BIT(5)
91 #define MIIM_88E151x_RGMII_TX_DELAY BIT(4)
92 #define MIIM_88E151x_RGMII_RXTX_DELAY (BIT(5) | BIT(4))
93 /* Page 3 registers */
94 #define MIIM_88E151x_LED_FUNC_CTRL 16
95 #define MIIM_88E151x_LED_FLD_SZ 4
96 #define MIIM_88E151x_LED0_OFFS (0 * MIIM_88E151x_LED_FLD_SZ)
97 #define MIIM_88E151x_LED1_OFFS (1 * MIIM_88E151x_LED_FLD_SZ)
98 #define MIIM_88E151x_LED0_ACT 3
99 #define MIIM_88E151x_LED1_100_1000_LINK 6
100 #define MIIM_88E151x_LED_TIMER_CTRL 18
101 #define MIIM_88E151x_INT_EN_OFFS 7
102 /* Page 18 registers */
103 #define MIIM_88E151x_GENERAL_CTRL 20
104 #define MIIM_88E151x_MODE_SGMII 1
105 #define MIIM_88E151x_RESET_OFFS 15
107 static int m88e1xxx_phy_extread(struct phy_device
*phydev
, int addr
,
108 int devaddr
, int regnum
)
110 int oldpage
= phy_read(phydev
, MDIO_DEVAD_NONE
, MII_MARVELL_PHY_PAGE
);
113 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_MARVELL_PHY_PAGE
, devaddr
);
114 val
= phy_read(phydev
, MDIO_DEVAD_NONE
, regnum
);
115 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_MARVELL_PHY_PAGE
, oldpage
);
120 static int m88e1xxx_phy_extwrite(struct phy_device
*phydev
, int addr
,
121 int devaddr
, int regnum
, u16 val
)
123 int oldpage
= phy_read(phydev
, MDIO_DEVAD_NONE
, MII_MARVELL_PHY_PAGE
);
125 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_MARVELL_PHY_PAGE
, devaddr
);
126 phy_write(phydev
, MDIO_DEVAD_NONE
, regnum
, val
);
127 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_MARVELL_PHY_PAGE
, oldpage
);
132 /* Marvell 88E1011S */
133 static int m88e1011s_config(struct phy_device
*phydev
)
135 /* Reset and configure the PHY */
136 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_BMCR
, BMCR_RESET
);
138 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x1d, 0x1f);
139 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x1e, 0x200c);
140 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x1d, 0x5);
141 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x1e, 0);
142 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x1e, 0x100);
144 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_BMCR
, BMCR_RESET
);
146 genphy_config_aneg(phydev
);
151 /* Parse the 88E1011's status register for speed and duplex
154 static int m88e1xxx_parse_status(struct phy_device
*phydev
)
157 unsigned int mii_reg
;
159 mii_reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1xxx_PHY_STATUS
);
161 if ((mii_reg
& MIIM_88E1xxx_PHYSTAT_LINK
) &&
162 !(mii_reg
& MIIM_88E1xxx_PHYSTAT_SPDDONE
)) {
165 puts("Waiting for PHY realtime link");
166 while (!(mii_reg
& MIIM_88E1xxx_PHYSTAT_SPDDONE
)) {
167 /* Timeout reached ? */
168 if (i
> PHY_AUTONEGOTIATE_TIMEOUT
) {
169 puts(" TIMEOUT !\n");
174 if ((i
++ % 1000) == 0)
177 mii_reg
= phy_read(phydev
, MDIO_DEVAD_NONE
,
178 MIIM_88E1xxx_PHY_STATUS
);
181 udelay(500000); /* another 500 ms (results in faster booting) */
183 if (mii_reg
& MIIM_88E1xxx_PHYSTAT_LINK
)
189 if (mii_reg
& MIIM_88E1xxx_PHYSTAT_DUPLEX
)
190 phydev
->duplex
= DUPLEX_FULL
;
192 phydev
->duplex
= DUPLEX_HALF
;
194 speed
= mii_reg
& MIIM_88E1xxx_PHYSTAT_SPEED
;
197 case MIIM_88E1xxx_PHYSTAT_GBIT
:
198 phydev
->speed
= SPEED_1000
;
200 case MIIM_88E1xxx_PHYSTAT_100
:
201 phydev
->speed
= SPEED_100
;
204 phydev
->speed
= SPEED_10
;
211 static int m88e1011s_startup(struct phy_device
*phydev
)
215 ret
= genphy_update_link(phydev
);
219 return m88e1xxx_parse_status(phydev
);
222 /* Marvell 88E1111S */
223 static int m88e1111s_config(struct phy_device
*phydev
)
227 if (phy_interface_is_rgmii(phydev
)) {
228 reg
= phy_read(phydev
,
229 MDIO_DEVAD_NONE
, MIIM_88E1111_PHY_EXT_CR
);
230 if ((phydev
->interface
== PHY_INTERFACE_MODE_RGMII
) ||
231 (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_ID
)) {
232 reg
|= (MIIM_88E1111_RX_DELAY
| MIIM_88E1111_TX_DELAY
);
233 } else if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_RXID
) {
234 reg
&= ~MIIM_88E1111_TX_DELAY
;
235 reg
|= MIIM_88E1111_RX_DELAY
;
236 } else if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_TXID
) {
237 reg
&= ~MIIM_88E1111_RX_DELAY
;
238 reg
|= MIIM_88E1111_TX_DELAY
;
242 MDIO_DEVAD_NONE
, MIIM_88E1111_PHY_EXT_CR
, reg
);
244 reg
= phy_read(phydev
,
245 MDIO_DEVAD_NONE
, MIIM_88E1111_PHY_EXT_SR
);
247 reg
&= ~(MIIM_88E1111_HWCFG_MODE_MASK
);
249 if (reg
& MIIM_88E1111_HWCFG_FIBER_COPPER_RES
)
250 reg
|= MIIM_88E1111_HWCFG_MODE_FIBER_RGMII
;
252 reg
|= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII
;
255 MDIO_DEVAD_NONE
, MIIM_88E1111_PHY_EXT_SR
, reg
);
258 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
) {
259 reg
= phy_read(phydev
,
260 MDIO_DEVAD_NONE
, MIIM_88E1111_PHY_EXT_SR
);
262 reg
&= ~(MIIM_88E1111_HWCFG_MODE_MASK
);
263 reg
|= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK
;
264 reg
|= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO
;
266 phy_write(phydev
, MDIO_DEVAD_NONE
,
267 MIIM_88E1111_PHY_EXT_SR
, reg
);
270 if (phydev
->interface
== PHY_INTERFACE_MODE_RTBI
) {
271 reg
= phy_read(phydev
,
272 MDIO_DEVAD_NONE
, MIIM_88E1111_PHY_EXT_CR
);
273 reg
|= (MIIM_88E1111_RX_DELAY
| MIIM_88E1111_TX_DELAY
);
275 MDIO_DEVAD_NONE
, MIIM_88E1111_PHY_EXT_CR
, reg
);
277 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
,
278 MIIM_88E1111_PHY_EXT_SR
);
279 reg
&= ~(MIIM_88E1111_HWCFG_MODE_MASK
|
280 MIIM_88E1111_HWCFG_FIBER_COPPER_RES
);
281 reg
|= 0x7 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO
;
282 phy_write(phydev
, MDIO_DEVAD_NONE
,
283 MIIM_88E1111_PHY_EXT_SR
, reg
);
288 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
,
289 MIIM_88E1111_PHY_EXT_SR
);
290 reg
&= ~(MIIM_88E1111_HWCFG_MODE_MASK
|
291 MIIM_88E1111_HWCFG_FIBER_COPPER_RES
);
292 reg
|= MIIM_88E1111_HWCFG_MODE_COPPER_RTBI
|
293 MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO
;
294 phy_write(phydev
, MDIO_DEVAD_NONE
,
295 MIIM_88E1111_PHY_EXT_SR
, reg
);
301 genphy_config_aneg(phydev
);
302 genphy_restart_aneg(phydev
);
308 * m88e1518_phy_writebits - write bits to a register
310 void m88e1518_phy_writebits(struct phy_device
*phydev
,
311 u8 reg_num
, u16 offset
, u16 len
, u16 data
)
315 if ((len
+ offset
) >= 16)
316 mask
= 0 - (1 << offset
);
318 mask
= (1 << (len
+ offset
)) - (1 << offset
);
320 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, reg_num
);
323 reg
|= data
<< offset
;
325 phy_write(phydev
, MDIO_DEVAD_NONE
, reg_num
, reg
);
328 static int m88e1518_config(struct phy_device
*phydev
)
333 * As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512
334 * /88E1514 Rev A0, Errata Section 3.1
337 /* EEE initialization */
338 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x00ff);
339 phy_write(phydev
, MDIO_DEVAD_NONE
, 17, 0x214B);
340 phy_write(phydev
, MDIO_DEVAD_NONE
, 16, 0x2144);
341 phy_write(phydev
, MDIO_DEVAD_NONE
, 17, 0x0C28);
342 phy_write(phydev
, MDIO_DEVAD_NONE
, 16, 0x2146);
343 phy_write(phydev
, MDIO_DEVAD_NONE
, 17, 0xB233);
344 phy_write(phydev
, MDIO_DEVAD_NONE
, 16, 0x214D);
345 phy_write(phydev
, MDIO_DEVAD_NONE
, 17, 0xCC0C);
346 phy_write(phydev
, MDIO_DEVAD_NONE
, 16, 0x2159);
347 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x0000);
349 /* SGMII-to-Copper mode initialization */
350 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
) {
352 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 18);
354 /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
355 m88e1518_phy_writebits(phydev
, MIIM_88E151x_GENERAL_CTRL
,
356 0, 3, MIIM_88E151x_MODE_SGMII
);
358 /* PHY reset is necessary after changing MODE[2:0] */
359 m88e1518_phy_writebits(phydev
, MIIM_88E151x_GENERAL_CTRL
,
360 MIIM_88E151x_RESET_OFFS
, 1, 1);
362 /* Reset page selection */
363 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0);
368 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
) {
369 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
,
370 MIIM_88E1111_PHY_EXT_SR
);
372 reg
&= ~(MIIM_88E1111_HWCFG_MODE_MASK
);
373 reg
|= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK
;
374 reg
|= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO
;
376 phy_write(phydev
, MDIO_DEVAD_NONE
,
377 MIIM_88E1111_PHY_EXT_SR
, reg
);
380 if (phy_interface_is_rgmii(phydev
)) {
381 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_MARVELL_PHY_PAGE
, 2);
383 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MIIM_88E151x_PHY_MSCR
);
384 reg
&= ~MIIM_88E151x_RGMII_RXTX_DELAY
;
385 if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_ID
)
386 reg
|= MIIM_88E151x_RGMII_RXTX_DELAY
;
387 else if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_RXID
)
388 reg
|= MIIM_88E151x_RGMII_RX_DELAY
;
389 else if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_TXID
)
390 reg
|= MIIM_88E151x_RGMII_TX_DELAY
;
391 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E151x_PHY_MSCR
, reg
);
393 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_MARVELL_PHY_PAGE
, 0);
399 genphy_config_aneg(phydev
);
400 genphy_restart_aneg(phydev
);
405 /* Marvell 88E1510 */
406 static int m88e1510_config(struct phy_device
*phydev
)
409 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
,
410 MIIM_88E1118_PHY_LED_PAGE
);
412 /* Enable INTn output on LED[2] */
413 m88e1518_phy_writebits(phydev
, MIIM_88E151x_LED_TIMER_CTRL
,
414 MIIM_88E151x_INT_EN_OFFS
, 1, 1);
417 /* LED[0]:0011 (ACT) */
418 m88e1518_phy_writebits(phydev
, MIIM_88E151x_LED_FUNC_CTRL
,
419 MIIM_88E151x_LED0_OFFS
, MIIM_88E151x_LED_FLD_SZ
,
420 MIIM_88E151x_LED0_ACT
);
421 /* LED[1]:0110 (LINK 100/1000 Mbps) */
422 m88e1518_phy_writebits(phydev
, MIIM_88E151x_LED_FUNC_CTRL
,
423 MIIM_88E151x_LED1_OFFS
, MIIM_88E151x_LED_FLD_SZ
,
424 MIIM_88E151x_LED1_100_1000_LINK
);
426 /* Reset page selection */
427 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0);
429 return m88e1518_config(phydev
);
432 /* Marvell 88E1118 */
433 static int m88e1118_config(struct phy_device
*phydev
)
435 /* Change Page Number */
436 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x0002);
437 /* Delay RGMII TX and RX */
438 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x15, 0x1070);
439 /* Change Page Number */
440 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x0003);
441 /* Adjust LED control */
442 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x10, 0x021e);
443 /* Change Page Number */
444 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x0000);
446 return genphy_config_aneg(phydev
);
449 static int m88e1118_startup(struct phy_device
*phydev
)
453 /* Change Page Number */
454 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x0000);
456 ret
= genphy_update_link(phydev
);
460 return m88e1xxx_parse_status(phydev
);
463 /* Marvell 88E1121R */
464 static int m88e1121_config(struct phy_device
*phydev
)
468 /* Configure the PHY */
469 genphy_config_aneg(phydev
);
471 /* Switch the page to access the led register */
472 pg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1121_PHY_PAGE
);
473 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1121_PHY_PAGE
,
474 MIIM_88E1121_PHY_LED_PAGE
);
476 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1121_PHY_LED_CTRL
,
477 MIIM_88E1121_PHY_LED_DEF
);
478 /* Restore the page pointer */
479 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1121_PHY_PAGE
, pg
);
481 /* Disable IRQs and de-assert interrupt */
482 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1121_PHY_IRQ_EN
, 0);
483 phy_read(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1121_PHY_IRQ_STATUS
);
488 /* Marvell 88E1145 */
489 static int m88e1145_config(struct phy_device
*phydev
)
494 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1145_PHY_PAGE
, 0x001b);
495 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1145_PHY_CAL_OV
, 0x418f);
496 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1145_PHY_PAGE
, 0x0016);
497 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1145_PHY_CAL_OV
, 0xa2da);
499 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1xxx_PHY_SCR
,
500 MIIM_88E1xxx_PHY_MDI_X_AUTO
);
502 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1145_PHY_EXT_CR
);
503 if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_ID
)
504 reg
|= MIIM_M88E1145_RGMII_RX_DELAY
|
505 MIIM_M88E1145_RGMII_TX_DELAY
;
506 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1145_PHY_EXT_CR
, reg
);
508 genphy_config_aneg(phydev
);
511 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MII_BMCR
);
513 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_BMCR
, reg
);
518 static int m88e1145_startup(struct phy_device
*phydev
)
522 ret
= genphy_update_link(phydev
);
526 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1145_PHY_LED_CONTROL
,
527 MIIM_88E1145_PHY_LED_DIRECT
);
528 return m88e1xxx_parse_status(phydev
);
531 /* Marvell 88E1149S */
532 static int m88e1149_config(struct phy_device
*phydev
)
534 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1149_PHY_PAGE
, 0x1f);
535 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x1e, 0x200c);
536 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1149_PHY_PAGE
, 0x5);
537 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x1e, 0x0);
538 phy_write(phydev
, MDIO_DEVAD_NONE
, 0x1e, 0x100);
540 genphy_config_aneg(phydev
);
547 /* Marvell 88E1310 */
548 static int m88e1310_config(struct phy_device
*phydev
)
552 /* LED link and activity */
553 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_PAGE
, 0x0003);
554 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_LED_CTRL
);
555 reg
= (reg
& ~0xf) | 0x1;
556 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_LED_CTRL
, reg
);
558 /* Set LED2/INT to INT mode, low active */
559 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_PAGE
, 0x0003);
560 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_IRQ_EN
);
561 reg
= (reg
& 0x77ff) | 0x0880;
562 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_IRQ_EN
, reg
);
564 /* Set RGMII delay */
565 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_PAGE
, 0x0002);
566 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_RGMII_CTRL
);
568 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_RGMII_CTRL
, reg
);
570 /* Ensure to return to page 0 */
571 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1310_PHY_PAGE
, 0x0000);
573 return genphy_config_aneg(phydev
);
576 static int m88e1680_config(struct phy_device
*phydev
)
579 * As per Marvell Release Notes - Alaska V 88E1680 Rev A2
585 /* Matrix LED mode (not neede if single LED mode is used */
586 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x0004);
587 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, 27);
589 phy_write(phydev
, MDIO_DEVAD_NONE
, 27, reg
);
591 /* QSGMII TX amplitude change */
592 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x00fd);
593 phy_write(phydev
, MDIO_DEVAD_NONE
, 8, 0x0b53);
594 phy_write(phydev
, MDIO_DEVAD_NONE
, 7, 0x200d);
595 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x0000);
597 /* EEE initialization */
598 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x00ff);
599 phy_write(phydev
, MDIO_DEVAD_NONE
, 17, 0xb030);
600 phy_write(phydev
, MDIO_DEVAD_NONE
, 16, 0x215c);
601 phy_write(phydev
, MDIO_DEVAD_NONE
, 22, 0x00fc);
602 phy_write(phydev
, MDIO_DEVAD_NONE
, 24, 0x888c);
603 phy_write(phydev
, MDIO_DEVAD_NONE
, 25, 0x888c);
604 phy_write(phydev
, MDIO_DEVAD_NONE
, MIIM_88E1118_PHY_PAGE
, 0x0000);
605 phy_write(phydev
, MDIO_DEVAD_NONE
, 0, 0x9140);
607 res
= genphy_config_aneg(phydev
);
612 reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MII_BMCR
);
614 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_BMCR
, reg
);
619 static struct phy_driver M88E1011S_driver
= {
620 .name
= "Marvell 88E1011S",
623 .features
= PHY_GBIT_FEATURES
,
624 .config
= &m88e1011s_config
,
625 .startup
= &m88e1011s_startup
,
626 .shutdown
= &genphy_shutdown
,
629 static struct phy_driver M88E1111S_driver
= {
630 .name
= "Marvell 88E1111S",
633 .features
= PHY_GBIT_FEATURES
,
634 .config
= &m88e1111s_config
,
635 .startup
= &m88e1011s_startup
,
636 .shutdown
= &genphy_shutdown
,
639 static struct phy_driver M88E1118_driver
= {
640 .name
= "Marvell 88E1118",
643 .features
= PHY_GBIT_FEATURES
,
644 .config
= &m88e1118_config
,
645 .startup
= &m88e1118_startup
,
646 .shutdown
= &genphy_shutdown
,
649 static struct phy_driver M88E1118R_driver
= {
650 .name
= "Marvell 88E1118R",
653 .features
= PHY_GBIT_FEATURES
,
654 .config
= &m88e1118_config
,
655 .startup
= &m88e1118_startup
,
656 .shutdown
= &genphy_shutdown
,
659 static struct phy_driver M88E1121R_driver
= {
660 .name
= "Marvell 88E1121R",
663 .features
= PHY_GBIT_FEATURES
,
664 .config
= &m88e1121_config
,
665 .startup
= &genphy_startup
,
666 .shutdown
= &genphy_shutdown
,
669 static struct phy_driver M88E1145_driver
= {
670 .name
= "Marvell 88E1145",
673 .features
= PHY_GBIT_FEATURES
,
674 .config
= &m88e1145_config
,
675 .startup
= &m88e1145_startup
,
676 .shutdown
= &genphy_shutdown
,
679 static struct phy_driver M88E1149S_driver
= {
680 .name
= "Marvell 88E1149S",
683 .features
= PHY_GBIT_FEATURES
,
684 .config
= &m88e1149_config
,
685 .startup
= &m88e1011s_startup
,
686 .shutdown
= &genphy_shutdown
,
689 static struct phy_driver M88E1510_driver
= {
690 .name
= "Marvell 88E1510",
693 .features
= PHY_GBIT_FEATURES
,
694 .config
= &m88e1510_config
,
695 .startup
= &m88e1011s_startup
,
696 .shutdown
= &genphy_shutdown
,
697 .readext
= &m88e1xxx_phy_extread
,
698 .writeext
= &m88e1xxx_phy_extwrite
,
703 * 88E1518, uid 0x1410dd1
704 * 88E1512, uid 0x1410dd4
706 static struct phy_driver M88E1518_driver
= {
707 .name
= "Marvell 88E1518",
710 .features
= PHY_GBIT_FEATURES
,
711 .config
= &m88e1518_config
,
712 .startup
= &m88e1011s_startup
,
713 .shutdown
= &genphy_shutdown
,
714 .readext
= &m88e1xxx_phy_extread
,
715 .writeext
= &m88e1xxx_phy_extwrite
,
718 static struct phy_driver M88E1310_driver
= {
719 .name
= "Marvell 88E1310",
722 .features
= PHY_GBIT_FEATURES
,
723 .config
= &m88e1310_config
,
724 .startup
= &m88e1011s_startup
,
725 .shutdown
= &genphy_shutdown
,
728 static struct phy_driver M88E1680_driver
= {
729 .name
= "Marvell 88E1680",
732 .features
= PHY_GBIT_FEATURES
,
733 .config
= &m88e1680_config
,
734 .startup
= &genphy_startup
,
735 .shutdown
= &genphy_shutdown
,
738 int phy_marvell_init(void)
740 phy_register(&M88E1310_driver
);
741 phy_register(&M88E1149S_driver
);
742 phy_register(&M88E1145_driver
);
743 phy_register(&M88E1121R_driver
);
744 phy_register(&M88E1118_driver
);
745 phy_register(&M88E1118R_driver
);
746 phy_register(&M88E1111S_driver
);
747 phy_register(&M88E1011S_driver
);
748 phy_register(&M88E1510_driver
);
749 phy_register(&M88E1518_driver
);
750 phy_register(&M88E1680_driver
);