Merge branch 'master' of git://git.denx.de/u-boot-net
[oweals/u-boot.git] / drivers / net / phy / micrel.c
1 /*
2  * Micrel PHY drivers
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  *
6  * Copyright 2010-2011 Freescale Semiconductor, Inc.
7  * author Andy Fleming
8  * (C) 2012 NetModule AG, David Andrey, added KSZ9031
9  */
10 #include <config.h>
11 #include <common.h>
12 #include <micrel.h>
13 #include <phy.h>
14
15 static struct phy_driver KSZ804_driver = {
16         .name = "Micrel KSZ804",
17         .uid = 0x221510,
18         .mask = 0xfffff0,
19         .features = PHY_BASIC_FEATURES,
20         .config = &genphy_config,
21         .startup = &genphy_startup,
22         .shutdown = &genphy_shutdown,
23 };
24
25 static struct phy_driver KSZ8031_driver = {
26         .name = "Micrel KSZ8021/KSZ8031",
27         .uid = 0x221550,
28         .mask = 0xfffff0,
29         .features = PHY_BASIC_FEATURES,
30         .config = &genphy_config,
31         .startup = &genphy_startup,
32         .shutdown = &genphy_shutdown,
33 };
34
35 /**
36  * KSZ8051
37  */
38 #define MII_KSZ8051_PHY_OMSO                    0x16
39 #define MII_KSZ8051_PHY_OMSO_NAND_TREE_ON       (1 << 5)
40
41 static int ksz8051_config(struct phy_device *phydev)
42 {
43         unsigned val;
44
45         /* Disable NAND-tree */
46         val = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO);
47         val &= ~MII_KSZ8051_PHY_OMSO_NAND_TREE_ON;
48         phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO, val);
49
50         return genphy_config(phydev);
51 }
52
53 static struct phy_driver KSZ8051_driver = {
54         .name = "Micrel KSZ8051",
55         .uid = 0x221550,
56         .mask = 0xfffff0,
57         .features = PHY_BASIC_FEATURES,
58         .config = &ksz8051_config,
59         .startup = &genphy_startup,
60         .shutdown = &genphy_shutdown,
61 };
62
63 static struct phy_driver KSZ8081_driver = {
64         .name = "Micrel KSZ8081",
65         .uid = 0x221560,
66         .mask = 0xfffff0,
67         .features = PHY_BASIC_FEATURES,
68         .config = &genphy_config,
69         .startup = &genphy_startup,
70         .shutdown = &genphy_shutdown,
71 };
72
73 /**
74  * KSZ8895
75  */
76
77 static unsigned short smireg_to_phy(unsigned short reg)
78 {
79         return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5);
80 }
81
82 static unsigned short smireg_to_reg(unsigned short reg)
83 {
84         return reg & 0x1F;
85 }
86
87 static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val)
88 {
89         phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE,
90                                                 smireg_to_reg(smireg), val);
91 }
92
93 #if 0
94 static int ksz8895_read_smireg(struct phy_device *phydev, int smireg)
95 {
96         return phydev->bus->read(phydev->bus, smireg_to_phy(smireg),
97                                         MDIO_DEVAD_NONE, smireg_to_reg(smireg));
98 }
99 #endif
100
101 int ksz8895_config(struct phy_device *phydev)
102 {
103         /* we are connected directly to the switch without
104          * dedicated PHY. SCONF1 == 001 */
105         phydev->link = 1;
106         phydev->duplex = DUPLEX_FULL;
107         phydev->speed = SPEED_100;
108
109         /* Force the switch to start */
110         ksz8895_write_smireg(phydev, 1, 1);
111
112         return 0;
113 }
114
115 static int ksz8895_startup(struct phy_device *phydev)
116 {
117         return 0;
118 }
119
120 static struct phy_driver ksz8895_driver = {
121         .name = "Micrel KSZ8895/KSZ8864",
122         .uid  = 0x221450,
123         .mask = 0xffffe1,
124         .features = PHY_BASIC_FEATURES,
125         .config   = &ksz8895_config,
126         .startup  = &ksz8895_startup,
127         .shutdown = &genphy_shutdown,
128 };
129
130 #ifndef CONFIG_PHY_MICREL_KSZ9021
131 /*
132  * I can't believe Micrel used the exact same part number
133  * for the KSZ9021. Shame Micrel, Shame!
134  */
135 static struct phy_driver KS8721_driver = {
136         .name = "Micrel KS8721BL",
137         .uid = 0x221610,
138         .mask = 0xfffff0,
139         .features = PHY_BASIC_FEATURES,
140         .config = &genphy_config,
141         .startup = &genphy_startup,
142         .shutdown = &genphy_shutdown,
143 };
144 #endif
145
146
147 /*
148  * KSZ9021 - KSZ9031 common
149  */
150
151 #define MII_KSZ90xx_PHY_CTL             0x1f
152 #define MIIM_KSZ90xx_PHYCTL_1000        (1 << 6)
153 #define MIIM_KSZ90xx_PHYCTL_100         (1 << 5)
154 #define MIIM_KSZ90xx_PHYCTL_10          (1 << 4)
155 #define MIIM_KSZ90xx_PHYCTL_DUPLEX      (1 << 3)
156
157 static int ksz90xx_startup(struct phy_device *phydev)
158 {
159         unsigned phy_ctl;
160         genphy_update_link(phydev);
161         phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
162
163         if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)
164                 phydev->duplex = DUPLEX_FULL;
165         else
166                 phydev->duplex = DUPLEX_HALF;
167
168         if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000)
169                 phydev->speed = SPEED_1000;
170         else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100)
171                 phydev->speed = SPEED_100;
172         else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10)
173                 phydev->speed = SPEED_10;
174         return 0;
175 }
176
177 #ifdef CONFIG_PHY_MICREL_KSZ9021
178 /*
179  * KSZ9021
180  */
181
182 /* PHY Registers */
183 #define MII_KSZ9021_EXTENDED_CTRL       0x0b
184 #define MII_KSZ9021_EXTENDED_DATAW      0x0c
185 #define MII_KSZ9021_EXTENDED_DATAR      0x0d
186
187 #define CTRL1000_PREFER_MASTER          (1 << 10)
188 #define CTRL1000_CONFIG_MASTER          (1 << 11)
189 #define CTRL1000_MANUAL_CONFIG          (1 << 12)
190
191 int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
192 {
193         /* extended registers */
194         phy_write(phydev, MDIO_DEVAD_NONE,
195                 MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
196         return phy_write(phydev, MDIO_DEVAD_NONE,
197                 MII_KSZ9021_EXTENDED_DATAW, val);
198 }
199
200 int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
201 {
202         /* extended registers */
203         phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
204         return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
205 }
206
207
208 static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr,
209                               int regnum)
210 {
211         return ksz9021_phy_extended_read(phydev, regnum);
212 }
213
214 static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr,
215                                int devaddr, int regnum, u16 val)
216 {
217         return ksz9021_phy_extended_write(phydev, regnum, val);
218 }
219
220 /* Micrel ksz9021 */
221 static int ksz9021_config(struct phy_device *phydev)
222 {
223         unsigned ctrl1000 = 0;
224         const unsigned master = CTRL1000_PREFER_MASTER |
225                         CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
226         unsigned features = phydev->drv->features;
227
228         if (getenv("disable_giga"))
229                 features &= ~(SUPPORTED_1000baseT_Half |
230                                 SUPPORTED_1000baseT_Full);
231         /* force master mode for 1000BaseT due to chip errata */
232         if (features & SUPPORTED_1000baseT_Half)
233                 ctrl1000 |= ADVERTISE_1000HALF | master;
234         if (features & SUPPORTED_1000baseT_Full)
235                 ctrl1000 |= ADVERTISE_1000FULL | master;
236         phydev->advertising = phydev->supported = features;
237         phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
238         genphy_config_aneg(phydev);
239         genphy_restart_aneg(phydev);
240         return 0;
241 }
242
243 static struct phy_driver ksz9021_driver = {
244         .name = "Micrel ksz9021",
245         .uid  = 0x221610,
246         .mask = 0xfffff0,
247         .features = PHY_GBIT_FEATURES,
248         .config = &ksz9021_config,
249         .startup = &ksz90xx_startup,
250         .shutdown = &genphy_shutdown,
251         .writeext = &ksz9021_phy_extwrite,
252         .readext = &ksz9021_phy_extread,
253 };
254 #endif
255
256 /**
257  * KSZ9031
258  */
259 /* PHY Registers */
260 #define MII_KSZ9031_MMD_ACCES_CTRL      0x0d
261 #define MII_KSZ9031_MMD_REG_DATA        0x0e
262
263 /* Accessors to extended registers*/
264 int ksz9031_phy_extended_write(struct phy_device *phydev,
265                                int devaddr, int regnum, u16 mode, u16 val)
266 {
267         /*select register addr for mmd*/
268         phy_write(phydev, MDIO_DEVAD_NONE,
269                   MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
270         /*select register for mmd*/
271         phy_write(phydev, MDIO_DEVAD_NONE,
272                   MII_KSZ9031_MMD_REG_DATA, regnum);
273         /*setup mode*/
274         phy_write(phydev, MDIO_DEVAD_NONE,
275                   MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr));
276         /*write the value*/
277         return  phy_write(phydev, MDIO_DEVAD_NONE,
278                 MII_KSZ9031_MMD_REG_DATA, val);
279 }
280
281 int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,
282                               int regnum, u16 mode)
283 {
284         phy_write(phydev, MDIO_DEVAD_NONE,
285                   MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
286         phy_write(phydev, MDIO_DEVAD_NONE,
287                   MII_KSZ9031_MMD_REG_DATA, regnum);
288         phy_write(phydev, MDIO_DEVAD_NONE,
289                   MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode));
290         return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);
291 }
292
293 static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr,
294                                int regnum)
295 {
296         return ksz9031_phy_extended_read(phydev, devaddr, regnum,
297                                          MII_KSZ9031_MOD_DATA_NO_POST_INC);
298 };
299
300 static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr,
301                                 int devaddr, int regnum, u16 val)
302 {
303         return ksz9031_phy_extended_write(phydev, devaddr, regnum,
304                                          MII_KSZ9031_MOD_DATA_POST_INC_RW, val);
305 };
306
307
308 static struct phy_driver ksz9031_driver = {
309         .name = "Micrel ksz9031",
310         .uid  = 0x221620,
311         .mask = 0xfffff0,
312         .features = PHY_GBIT_FEATURES,
313         .config   = &genphy_config,
314         .startup  = &ksz90xx_startup,
315         .shutdown = &genphy_shutdown,
316         .writeext = &ksz9031_phy_extwrite,
317         .readext = &ksz9031_phy_extread,
318 };
319
320 int phy_micrel_init(void)
321 {
322         phy_register(&KSZ804_driver);
323         phy_register(&KSZ8031_driver);
324         phy_register(&KSZ8051_driver);
325         phy_register(&KSZ8081_driver);
326 #ifdef CONFIG_PHY_MICREL_KSZ9021
327         phy_register(&ksz9021_driver);
328 #else
329         phy_register(&KS8721_driver);
330 #endif
331         phy_register(&ksz9031_driver);
332         phy_register(&ksz8895_driver);
333         return 0;
334 }