6678147545699ba28a448f1b30c339b9af99ee3f
[oweals/u-boot.git] / drivers / net / phy / aquantia.c
1 /*
2  * Aquantia PHY drivers
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  *
6  * Copyright 2014 Freescale Semiconductor, Inc.
7  */
8 #include <config.h>
9 #include <common.h>
10 #include <dm.h>
11 #include <phy.h>
12
13 #ifndef CONFIG_PHYLIB_10G
14 #error The Aquantia PHY needs 10G support
15 #endif
16
17 #define AQUNTIA_10G_CTL         0x20
18 #define AQUNTIA_VENDOR_P1       0xc400
19
20 #define AQUNTIA_SPEED_LSB_MASK  0x2000
21 #define AQUNTIA_SPEED_MSB_MASK  0x40
22
23 int aquantia_config(struct phy_device *phydev)
24 {
25         u32 val = phy_read(phydev, MDIO_MMD_PMAPMD, MII_BMCR);
26
27         if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
28                 /* 1000BASE-T mode */
29                 phydev->advertising = SUPPORTED_1000baseT_Full;
30                 phydev->supported = phydev->advertising;
31
32                 val = (val & ~AQUNTIA_SPEED_LSB_MASK) | AQUNTIA_SPEED_MSB_MASK;
33                 phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val);
34         } else if (phydev->interface == PHY_INTERFACE_MODE_XGMII) {
35                 /* 10GBASE-T mode */
36                 phydev->advertising = SUPPORTED_10000baseT_Full;
37                 phydev->supported = phydev->advertising;
38
39                 if (!(val & AQUNTIA_SPEED_LSB_MASK) ||
40                     !(val & AQUNTIA_SPEED_MSB_MASK))
41                         phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR,
42                                   AQUNTIA_SPEED_LSB_MASK |
43                                   AQUNTIA_SPEED_MSB_MASK);
44         } else if (phydev->interface == PHY_INTERFACE_MODE_SGMII_2500) {
45                 /* 2.5GBASE-T mode */
46                 phydev->advertising = SUPPORTED_1000baseT_Full;
47                 phydev->supported = phydev->advertising;
48
49                 phy_write(phydev, MDIO_MMD_AN, AQUNTIA_10G_CTL, 1);
50                 phy_write(phydev, MDIO_MMD_AN, AQUNTIA_VENDOR_P1, 0x9440);
51         } else if (phydev->interface == PHY_INTERFACE_MODE_MII) {
52                 /* 100BASE-TX mode */
53                 phydev->advertising = SUPPORTED_100baseT_Full;
54                 phydev->supported = phydev->advertising;
55
56                 val = (val & ~AQUNTIA_SPEED_MSB_MASK) | AQUNTIA_SPEED_LSB_MASK;
57                 phy_write(phydev, MDIO_MMD_PMAPMD, MII_BMCR, val);
58         }
59         return 0;
60 }
61
62 int aquantia_startup(struct phy_device *phydev)
63 {
64         u32 reg, speed;
65         int i = 0;
66
67         phydev->duplex = DUPLEX_FULL;
68
69         /* if the AN is still in progress, wait till timeout. */
70         phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
71         reg = phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
72         if (!(reg & MDIO_AN_STAT1_COMPLETE)) {
73                 printf("%s Waiting for PHY auto negotiation to complete",
74                        phydev->dev->name);
75                 do {
76                         udelay(1000);
77                         reg = phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
78                         if ((i++ % 500) == 0)
79                                 printf(".");
80                 } while (!(reg & MDIO_AN_STAT1_COMPLETE) &&
81                          i < (4 * PHY_ANEG_TIMEOUT));
82
83                 if (i > PHY_ANEG_TIMEOUT)
84                         printf(" TIMEOUT !\n");
85         }
86
87         /* Read twice because link state is latched and a
88          * read moves the current state into the register */
89         phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
90         reg = phy_read(phydev, MDIO_MMD_AN, MDIO_STAT1);
91         if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
92                 phydev->link = 0;
93         else
94                 phydev->link = 1;
95
96         speed = phy_read(phydev, MDIO_MMD_PMAPMD, MII_BMCR);
97         if (speed & AQUNTIA_SPEED_MSB_MASK) {
98                 if (speed & AQUNTIA_SPEED_LSB_MASK)
99                         phydev->speed = SPEED_10000;
100                 else
101                         phydev->speed = SPEED_1000;
102         } else {
103                 if (speed & AQUNTIA_SPEED_LSB_MASK)
104                         phydev->speed = SPEED_100;
105                 else
106                         phydev->speed = SPEED_10;
107         }
108
109         return 0;
110 }
111
112 struct phy_driver aq1202_driver = {
113         .name = "Aquantia AQ1202",
114         .uid = 0x3a1b445,
115         .mask = 0xfffffff0,
116         .features = PHY_10G_FEATURES,
117         .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
118                         MDIO_MMD_PHYXS | MDIO_MMD_AN |
119                         MDIO_MMD_VEND1),
120         .config = &aquantia_config,
121         .startup = &aquantia_startup,
122         .shutdown = &gen10g_shutdown,
123 };
124
125 struct phy_driver aq2104_driver = {
126         .name = "Aquantia AQ2104",
127         .uid = 0x3a1b460,
128         .mask = 0xfffffff0,
129         .features = PHY_10G_FEATURES,
130         .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
131                         MDIO_MMD_PHYXS | MDIO_MMD_AN |
132                         MDIO_MMD_VEND1),
133         .config = &aquantia_config,
134         .startup = &aquantia_startup,
135         .shutdown = &gen10g_shutdown,
136 };
137
138 struct phy_driver aqr105_driver = {
139         .name = "Aquantia AQR105",
140         .uid = 0x3a1b4a2,
141         .mask = 0xfffffff0,
142         .features = PHY_10G_FEATURES,
143         .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
144                         MDIO_MMD_PHYXS | MDIO_MMD_AN |
145                         MDIO_MMD_VEND1),
146         .config = &aquantia_config,
147         .startup = &aquantia_startup,
148         .shutdown = &gen10g_shutdown,
149 };
150
151 struct phy_driver aqr106_driver = {
152         .name = "Aquantia AQR106",
153         .uid = 0x3a1b4d0,
154         .mask = 0xfffffff0,
155         .features = PHY_10G_FEATURES,
156         .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
157                         MDIO_MMD_PHYXS | MDIO_MMD_AN |
158                         MDIO_MMD_VEND1),
159         .config = &aquantia_config,
160         .startup = &aquantia_startup,
161         .shutdown = &gen10g_shutdown,
162 };
163
164 struct phy_driver aqr107_driver = {
165         .name = "Aquantia AQR107",
166         .uid = 0x3a1b4e0,
167         .mask = 0xfffffff0,
168         .features = PHY_10G_FEATURES,
169         .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
170                         MDIO_MMD_PHYXS | MDIO_MMD_AN |
171                         MDIO_MMD_VEND1),
172         .config = &aquantia_config,
173         .startup = &aquantia_startup,
174         .shutdown = &gen10g_shutdown,
175 };
176
177 struct phy_driver aqr405_driver = {
178         .name = "Aquantia AQR405",
179         .uid = 0x3a1b4b2,
180         .mask = 0xfffffff0,
181         .features = PHY_10G_FEATURES,
182         .mmds = (MDIO_MMD_PMAPMD | MDIO_MMD_PCS|
183                  MDIO_MMD_PHYXS | MDIO_MMD_AN |
184                  MDIO_MMD_VEND1),
185         .config = &aquantia_config,
186         .startup = &aquantia_startup,
187         .shutdown = &gen10g_shutdown,
188 };
189
190 int phy_aquantia_init(void)
191 {
192         phy_register(&aq1202_driver);
193         phy_register(&aq2104_driver);
194         phy_register(&aqr105_driver);
195         phy_register(&aqr106_driver);
196         phy_register(&aqr107_driver);
197         phy_register(&aqr405_driver);
198
199         return 0;
200 }