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