]>
Commit | Line | Data |
---|---|---|
0fae2508 YY |
1 | /* |
2 | * ICPlus PHY drivers | |
3 | * | |
1a459660 | 4 | * SPDX-License-Identifier: GPL-2.0+ |
0fae2508 YY |
5 | * |
6 | * Copyright (c) 2007 Freescale Semiconductor, Inc. | |
0fae2508 YY |
7 | */ |
8 | #include <phy.h> | |
9 | ||
10 | /* IP101A/G - IP1001 */ | |
11 | #define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ | |
12 | #define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ | |
13 | #define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ | |
14 | #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ | |
15 | #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ | |
16 | #define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ | |
17 | #define IP101A_G_IRQ_PIN_USED (1<<15) /* INTR pin used */ | |
18 | #define IP101A_G_IRQ_DEFAULT IP101A_G_IRQ_PIN_USED | |
19 | ||
20 | static int ip1001_config(struct phy_device *phydev) | |
21 | { | |
22 | int c; | |
23 | ||
24 | /* Enable Auto Power Saving mode */ | |
25 | c = phy_read(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2); | |
26 | if (c < 0) | |
27 | return c; | |
28 | c |= IP1001_APS_ON; | |
29 | c = phy_write(phydev, MDIO_DEVAD_NONE, IP1001_SPEC_CTRL_STATUS_2, c); | |
30 | if (c < 0) | |
31 | return c; | |
32 | ||
33 | /* INTR pin used: speed/link/duplex will cause an interrupt */ | |
34 | c = phy_write(phydev, MDIO_DEVAD_NONE, IP101A_G_IRQ_CONF_STATUS, | |
35 | IP101A_G_IRQ_DEFAULT); | |
36 | if (c < 0) | |
37 | return c; | |
38 | ||
39 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { | |
40 | /* | |
41 | * Additional delay (2ns) used to adjust RX clock phase | |
42 | * at RGMII interface | |
43 | */ | |
44 | c = phy_read(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS); | |
45 | if (c < 0) | |
46 | return c; | |
47 | ||
48 | c |= IP1001_PHASE_SEL_MASK; | |
49 | c = phy_write(phydev, MDIO_DEVAD_NONE, IP10XX_SPEC_CTRL_STATUS, | |
50 | c); | |
51 | if (c < 0) | |
52 | return c; | |
53 | } | |
54 | ||
55 | return 0; | |
56 | } | |
57 | ||
58 | static int ip1001_startup(struct phy_device *phydev) | |
59 | { | |
60 | genphy_update_link(phydev); | |
61 | genphy_parse_link(phydev); | |
62 | ||
63 | return 0; | |
64 | } | |
65 | static struct phy_driver IP1001_driver = { | |
66 | .name = "ICPlus IP1001", | |
67 | .uid = 0x02430d90, | |
68 | .mask = 0x0ffffff0, | |
69 | .features = PHY_GBIT_FEATURES, | |
70 | .config = &ip1001_config, | |
71 | .startup = &ip1001_startup, | |
72 | .shutdown = &genphy_shutdown, | |
73 | }; | |
74 | ||
75 | int phy_icplus_init(void) | |
76 | { | |
77 | phy_register(&IP1001_driver); | |
78 | ||
79 | return 0; | |
80 | } |