Merge tag 'u-boot-rockchip-20200501' of https://gitlab.denx.de/u-boot/custodians...
[platform/kernel/u-boot.git] / drivers / net / fm / memac_phy.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2012 Freescale Semiconductor, Inc.
4  *      Andy Fleming <afleming@gmail.com>
5  *      Roy Zang <tie-fei.zang@freescale.com>
6  * Some part is taken from tsec.c
7  */
8 #include <common.h>
9 #include <miiphy.h>
10 #include <phy.h>
11 #include <asm/io.h>
12 #include <fsl_memac.h>
13 #include <fm_eth.h>
14
15 #ifdef CONFIG_SYS_MEMAC_LITTLE_ENDIAN
16 #define memac_out_32(a, v)      out_le32(a, v)
17 #define memac_clrbits_32(a, v)  clrbits_le32(a, v)
18 #define memac_setbits_32(a, v)  setbits_le32(a, v)
19 #else
20 #define memac_out_32(a, v)      out_be32(a, v)
21 #define memac_clrbits_32(a, v)  clrbits_be32(a, v)
22 #define memac_setbits_32(a, v)  setbits_be32(a, v)
23 #endif
24
25 #ifdef CONFIG_DM_ETH
26 struct fm_mdio_priv {
27         struct memac_mdio_controller *regs;
28 };
29 #endif
30
31 static u32 memac_in_32(u32 *reg)
32 {
33 #ifdef CONFIG_SYS_MEMAC_LITTLE_ENDIAN
34         return in_le32(reg);
35 #else
36         return in_be32(reg);
37 #endif
38 }
39
40 /*
41  * Write value to the PHY for this device to the register at regnum, waiting
42  * until the write is done before it returns.  All PHY configuration has to be
43  * done through the TSEC1 MIIM regs
44  */
45 int memac_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr,
46                         int regnum, u16 value)
47 {
48         struct memac_mdio_controller *regs;
49         u32 mdio_ctl;
50         u32 c45 = 1; /* Default to 10G interface */
51
52 #ifndef CONFIG_DM_ETH
53         regs = bus->priv;
54 #else
55         struct fm_mdio_priv *priv;
56
57         if (!bus->priv)
58                 return -EINVAL;
59         priv = dev_get_priv(bus->priv);
60         regs = priv->regs;
61         debug("memac_mdio_write(regs %p, port %d, dev %d, reg %d, val %#x)\n",
62               regs, port_addr, dev_addr, regnum, value);
63 #endif
64
65         if (dev_addr == MDIO_DEVAD_NONE) {
66                 c45 = 0; /* clause 22 */
67                 dev_addr = regnum & 0x1f;
68                 memac_clrbits_32(&regs->mdio_stat, MDIO_STAT_ENC);
69         } else
70                 memac_setbits_32(&regs->mdio_stat, MDIO_STAT_ENC);
71
72         /* Wait till the bus is free */
73         while ((memac_in_32(&regs->mdio_stat)) & MDIO_STAT_BSY)
74                 ;
75
76         /* Set the port and dev addr */
77         mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
78         memac_out_32(&regs->mdio_ctl, mdio_ctl);
79
80         /* Set the register address */
81         if (c45)
82                 memac_out_32(&regs->mdio_addr, regnum & 0xffff);
83
84         /* Wait till the bus is free */
85         while ((memac_in_32(&regs->mdio_stat)) & MDIO_STAT_BSY)
86                 ;
87
88         /* Write the value to the register */
89         memac_out_32(&regs->mdio_data, MDIO_DATA(value));
90
91         /* Wait till the MDIO write is complete */
92         while ((memac_in_32(&regs->mdio_data)) & MDIO_DATA_BSY)
93                 ;
94
95         return 0;
96 }
97
98 /*
99  * Reads from register regnum in the PHY for device dev, returning the value.
100  * Clears miimcom first.  All PHY configuration has to be done through the
101  * TSEC1 MIIM regs
102  */
103 int memac_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr,
104                         int regnum)
105 {
106         struct memac_mdio_controller *regs;
107         u32 mdio_ctl;
108         u32 c45 = 1;
109
110 #ifndef CONFIG_DM_ETH
111         regs = bus->priv;
112 #else
113         struct fm_mdio_priv *priv;
114
115         if (!bus->priv)
116                 return -EINVAL;
117         priv = dev_get_priv(bus->priv);
118         regs = priv->regs;
119 #endif
120
121         if (dev_addr == MDIO_DEVAD_NONE) {
122 #ifndef CONFIG_DM_ETH
123                 if (!strcmp(bus->name, DEFAULT_FM_TGEC_MDIO_NAME))
124                         return 0xffff;
125 #endif
126                 c45 = 0; /* clause 22 */
127                 dev_addr = regnum & 0x1f;
128                 memac_clrbits_32(&regs->mdio_stat, MDIO_STAT_ENC);
129         } else
130                 memac_setbits_32(&regs->mdio_stat, MDIO_STAT_ENC);
131
132         /* Wait till the bus is free */
133         while ((memac_in_32(&regs->mdio_stat)) & MDIO_STAT_BSY)
134                 ;
135
136         /* Set the Port and Device Addrs */
137         mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
138         memac_out_32(&regs->mdio_ctl, mdio_ctl);
139
140         /* Set the register address */
141         if (c45)
142                 memac_out_32(&regs->mdio_addr, regnum & 0xffff);
143
144         /* Wait till the bus is free */
145         while ((memac_in_32(&regs->mdio_stat)) & MDIO_STAT_BSY)
146                 ;
147
148         /* Initiate the read */
149         mdio_ctl |= MDIO_CTL_READ;
150         memac_out_32(&regs->mdio_ctl, mdio_ctl);
151
152         /* Wait till the MDIO write is complete */
153         while ((memac_in_32(&regs->mdio_data)) & MDIO_DATA_BSY)
154                 ;
155
156         /* Return all Fs if nothing was there */
157         if (memac_in_32(&regs->mdio_stat) & MDIO_STAT_RD_ER)
158                 return 0xffff;
159
160         return memac_in_32(&regs->mdio_data) & 0xffff;
161 }
162
163 int memac_mdio_reset(struct mii_dev *bus)
164 {
165         return 0;
166 }
167
168 #ifndef CONFIG_DM_ETH
169 int fm_memac_mdio_init(bd_t *bis, struct memac_mdio_info *info)
170 {
171         struct mii_dev *bus = mdio_alloc();
172
173         if (!bus) {
174                 printf("Failed to allocate FM TGEC MDIO bus\n");
175                 return -1;
176         }
177
178         bus->read = memac_mdio_read;
179         bus->write = memac_mdio_write;
180         bus->reset = memac_mdio_reset;
181         strcpy(bus->name, info->name);
182
183         bus->priv = info->regs;
184
185         /*
186          * On some platforms like B4860, default value of MDIO_CLK_DIV bits
187          * in mdio_stat(mdio_cfg) register generates MDIO clock too high
188          * (much higher than 2.5MHz), violating the IEEE specs.
189          * On other platforms like T1040, default value of MDIO_CLK_DIV bits
190          * is zero, so MDIO clock is disabled.
191          * So, for proper functioning of MDIO, MDIO_CLK_DIV bits needs to
192          * be properly initialized.
193          * NEG bit default should be '1' as per FMAN-v3 RM, but on platform
194          * like T2080QDS, this bit default is '0', which leads to MDIO failure
195          * on XAUI PHY, so set this bit definitely.
196          */
197         memac_setbits_32(
198                 &((struct memac_mdio_controller *)info->regs)->mdio_stat,
199                 MDIO_STAT_CLKDIV(258) | MDIO_STAT_NEG);
200
201         return mdio_register(bus);
202 }
203
204 #else /* CONFIG_DM_ETH */
205 #if defined(CONFIG_PHYLIB) && defined(CONFIG_DM_MDIO)
206 static int fm_mdio_read(struct udevice *dev, int addr, int devad, int reg)
207 {
208         struct mdio_perdev_priv *pdata = (dev) ? dev_get_uclass_priv(dev) :
209                                                  NULL;
210
211         if (pdata && pdata->mii_bus)
212                 return memac_mdio_read(pdata->mii_bus, addr, devad, reg);
213
214         return -1;
215 }
216
217 static int fm_mdio_write(struct udevice *dev, int addr, int devad, int reg,
218                          u16 val)
219 {
220         struct mdio_perdev_priv *pdata = (dev) ? dev_get_uclass_priv(dev) :
221                                                  NULL;
222
223         if (pdata && pdata->mii_bus)
224                 return memac_mdio_write(pdata->mii_bus, addr, devad, reg, val);
225
226         return -1;
227 }
228
229 static int fm_mdio_reset(struct udevice *dev)
230 {
231         struct mdio_perdev_priv *pdata = (dev) ? dev_get_uclass_priv(dev) :
232                                                  NULL;
233
234         if (pdata && pdata->mii_bus)
235                 return memac_mdio_reset(pdata->mii_bus);
236
237         return -1;
238 }
239
240 static const struct mdio_ops fm_mdio_ops = {
241         .read = fm_mdio_read,
242         .write = fm_mdio_write,
243         .reset = fm_mdio_reset,
244 };
245
246 static const struct udevice_id fm_mdio_ids[] = {
247         { .compatible = "fsl,fman-memac-mdio" },
248         {}
249 };
250
251 static int fm_mdio_probe(struct udevice *dev)
252 {
253         struct fm_mdio_priv *priv = (dev) ? dev_get_priv(dev) : NULL;
254         struct mdio_perdev_priv *pdata = (dev) ? dev_get_uclass_priv(dev) :
255                                                  NULL;
256
257         if (!dev) {
258                 printf("%s dev = NULL\n", __func__);
259                 return -1;
260         }
261         if (!priv) {
262                 printf("dev_get_priv(dev %p) = NULL\n", dev);
263                 return -1;
264         }
265         priv->regs = (void *)(uintptr_t)dev_read_addr(dev);
266         debug("%s priv %p @ regs %p, pdata %p\n", __func__,
267               priv, priv->regs, pdata);
268
269         /*
270          * On some platforms like B4860, default value of MDIO_CLK_DIV bits
271          * in mdio_stat(mdio_cfg) register generates MDIO clock too high
272          * (much higher than 2.5MHz), violating the IEEE specs.
273          * On other platforms like T1040, default value of MDIO_CLK_DIV bits
274          * is zero, so MDIO clock is disabled.
275          * So, for proper functioning of MDIO, MDIO_CLK_DIV bits needs to
276          * be properly initialized.
277          * The default NEG bit should be '1' as per FMANv3 RM, but on platforms
278          * like T2080QDS, this bit default is '0', which leads to MDIO failure
279          * on XAUI PHY, so set this bit definitely.
280          */
281         if (priv && priv->regs && priv->regs->mdio_stat)
282                 memac_setbits_32(&priv->regs->mdio_stat,
283                                  MDIO_STAT_CLKDIV(258) | MDIO_STAT_NEG);
284
285         return 0;
286 }
287
288 static int fm_mdio_remove(struct udevice *dev)
289 {
290         return 0;
291 }
292
293 U_BOOT_DRIVER(fman_mdio) = {
294         .name = "fman_mdio",
295         .id = UCLASS_MDIO,
296         .of_match = fm_mdio_ids,
297         .probe = fm_mdio_probe,
298         .remove = fm_mdio_remove,
299         .ops = &fm_mdio_ops,
300         .priv_auto_alloc_size = sizeof(struct fm_mdio_priv),
301         .platdata_auto_alloc_size = sizeof(struct mdio_perdev_priv),
302 };
303 #endif /* CONFIG_PHYLIB && CONFIG_DM_MDIO */
304 #endif /* CONFIG_DM_ETH */