]> git.sur5r.net Git - u-boot/blob - drivers/net/gmac_rockchip.c
net: gmac_rockchip: Add support for the RV1108 GMAC
[u-boot] / drivers / net / gmac_rockchip.c
1 /*
2  * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  *
6  * Rockchip GMAC ethernet IP driver for U-Boot
7  */
8
9 #include <common.h>
10 #include <dm.h>
11 #include <clk.h>
12 #include <phy.h>
13 #include <syscon.h>
14 #include <asm/io.h>
15 #include <asm/arch/periph.h>
16 #include <asm/arch/clock.h>
17 #include <asm/arch/hardware.h>
18 #include <asm/arch/grf_rk3288.h>
19 #include <asm/arch/grf_rk3368.h>
20 #include <asm/arch/grf_rk3399.h>
21 #include <asm/arch/grf_rv1108.h>
22 #include <dm/pinctrl.h>
23 #include <dt-bindings/clock/rk3288-cru.h>
24 #include "designware.h"
25
26 DECLARE_GLOBAL_DATA_PTR;
27
28 /*
29  * Platform data for the gmac
30  *
31  * dw_eth_pdata: Required platform data for designware driver (must be first)
32  */
33 struct gmac_rockchip_platdata {
34         struct dw_eth_pdata dw_eth_pdata;
35         bool clock_input;
36         int tx_delay;
37         int rx_delay;
38 };
39
40 struct rk_gmac_ops {
41         int (*fix_mac_speed)(struct dw_eth_dev *priv);
42         void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
43         void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
44 };
45
46
47 static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
48 {
49         struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
50         const char *string;
51
52         string = dev_read_string(dev, "clock_in_out");
53         if (!strcmp(string, "input"))
54                 pdata->clock_input = true;
55         else
56                 pdata->clock_input = false;
57
58         /* Check the new naming-style first... */
59         pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
60         pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
61
62         /* ... and fall back to the old naming style or default, if necessary */
63         if (pdata->tx_delay == -ENOENT)
64                 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
65         if (pdata->rx_delay == -ENOENT)
66                 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
67
68         return designware_eth_ofdata_to_platdata(dev);
69 }
70
71 static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
72 {
73         struct rk3288_grf *grf;
74         int clk;
75
76         switch (priv->phydev->speed) {
77         case 10:
78                 clk = RK3288_GMAC_CLK_SEL_2_5M;
79                 break;
80         case 100:
81                 clk = RK3288_GMAC_CLK_SEL_25M;
82                 break;
83         case 1000:
84                 clk = RK3288_GMAC_CLK_SEL_125M;
85                 break;
86         default:
87                 debug("Unknown phy speed: %d\n", priv->phydev->speed);
88                 return -EINVAL;
89         }
90
91         grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
92         rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
93
94         return 0;
95 }
96
97 static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
98 {
99         struct rk3368_grf *grf;
100         int clk;
101         enum {
102                 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
103                 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
104                 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
105                 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
106         };
107
108         switch (priv->phydev->speed) {
109         case 10:
110                 clk = RK3368_GMAC_CLK_SEL_2_5M;
111                 break;
112         case 100:
113                 clk = RK3368_GMAC_CLK_SEL_25M;
114                 break;
115         case 1000:
116                 clk = RK3368_GMAC_CLK_SEL_125M;
117                 break;
118         default:
119                 debug("Unknown phy speed: %d\n", priv->phydev->speed);
120                 return -EINVAL;
121         }
122
123         grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
124         rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
125
126         return 0;
127 }
128
129 static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
130 {
131         struct rk3399_grf_regs *grf;
132         int clk;
133
134         switch (priv->phydev->speed) {
135         case 10:
136                 clk = RK3399_GMAC_CLK_SEL_2_5M;
137                 break;
138         case 100:
139                 clk = RK3399_GMAC_CLK_SEL_25M;
140                 break;
141         case 1000:
142                 clk = RK3399_GMAC_CLK_SEL_125M;
143                 break;
144         default:
145                 debug("Unknown phy speed: %d\n", priv->phydev->speed);
146                 return -EINVAL;
147         }
148
149         grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
150         rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
151
152         return 0;
153 }
154
155 static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
156 {
157         struct rv1108_grf *grf;
158         int clk, speed;
159         enum {
160                 RV1108_GMAC_SPEED_MASK          = BIT(2),
161                 RV1108_GMAC_SPEED_10M           = 0 << 2,
162                 RV1108_GMAC_SPEED_100M          = 1 << 2,
163                 RV1108_GMAC_CLK_SEL_MASK        = BIT(7),
164                 RV1108_GMAC_CLK_SEL_2_5M        = 0 << 7,
165                 RV1108_GMAC_CLK_SEL_25M         = 1 << 7,
166         };
167
168         switch (priv->phydev->speed) {
169         case 10:
170                 clk = RV1108_GMAC_CLK_SEL_2_5M;
171                 speed = RV1108_GMAC_SPEED_10M;
172                 break;
173         case 100:
174                 clk = RV1108_GMAC_CLK_SEL_25M;
175                 speed = RV1108_GMAC_SPEED_100M;
176                 break;
177         default:
178                 debug("Unknown phy speed: %d\n", priv->phydev->speed);
179                 return -EINVAL;
180         }
181
182         grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
183         rk_clrsetreg(&grf->gmac_con0,
184                      RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
185                      clk | speed);
186
187         return 0;
188 }
189
190 static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
191 {
192         struct rk3288_grf *grf;
193
194         grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
195         rk_clrsetreg(&grf->soc_con1,
196                      RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
197                      RK3288_GMAC_PHY_INTF_SEL_RGMII);
198
199         rk_clrsetreg(&grf->soc_con3,
200                      RK3288_RXCLK_DLY_ENA_GMAC_MASK |
201                      RK3288_TXCLK_DLY_ENA_GMAC_MASK |
202                      RK3288_CLK_RX_DL_CFG_GMAC_MASK |
203                      RK3288_CLK_TX_DL_CFG_GMAC_MASK,
204                      RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
205                      RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
206                      pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
207                      pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
208 }
209
210 static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
211 {
212         struct rk3368_grf *grf;
213         enum {
214                 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
215                 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
216                 RK3368_RMII_MODE_MASK  = BIT(6),
217                 RK3368_RMII_MODE       = BIT(6),
218         };
219         enum {
220                 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
221                 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
222                 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
223                 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
224                 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
225                 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
226                 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
227                 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
228                 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
229                 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
230         };
231
232         grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
233         rk_clrsetreg(&grf->soc_con15,
234                      RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
235                      RK3368_GMAC_PHY_INTF_SEL_RGMII);
236
237         rk_clrsetreg(&grf->soc_con16,
238                      RK3368_RXCLK_DLY_ENA_GMAC_MASK |
239                      RK3368_TXCLK_DLY_ENA_GMAC_MASK |
240                      RK3368_CLK_RX_DL_CFG_GMAC_MASK |
241                      RK3368_CLK_TX_DL_CFG_GMAC_MASK,
242                      RK3368_RXCLK_DLY_ENA_GMAC_ENABLE |
243                      RK3368_TXCLK_DLY_ENA_GMAC_ENABLE |
244                      pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
245                      pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
246 }
247
248 static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
249 {
250         struct rk3399_grf_regs *grf;
251
252         grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
253
254         rk_clrsetreg(&grf->soc_con5,
255                      RK3399_GMAC_PHY_INTF_SEL_MASK,
256                      RK3399_GMAC_PHY_INTF_SEL_RGMII);
257
258         rk_clrsetreg(&grf->soc_con6,
259                      RK3399_RXCLK_DLY_ENA_GMAC_MASK |
260                      RK3399_TXCLK_DLY_ENA_GMAC_MASK |
261                      RK3399_CLK_RX_DL_CFG_GMAC_MASK |
262                      RK3399_CLK_TX_DL_CFG_GMAC_MASK,
263                      RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
264                      RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
265                      pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
266                      pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
267 }
268
269 static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
270 {
271         struct rv1108_grf *grf;
272
273         enum {
274                 RV1108_GMAC_PHY_INTF_SEL_MASK  = GENMASK(6, 4),
275                 RV1108_GMAC_PHY_INTF_SEL_RMII  = 4 << 4,
276         };
277
278         grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
279         rk_clrsetreg(&grf->gmac_con0,
280                      RV1108_GMAC_PHY_INTF_SEL_MASK,
281                      RV1108_GMAC_PHY_INTF_SEL_RMII);
282 }
283
284 static int gmac_rockchip_probe(struct udevice *dev)
285 {
286         struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
287         struct rk_gmac_ops *ops =
288                 (struct rk_gmac_ops *)dev_get_driver_data(dev);
289         struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
290         struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
291         struct clk clk;
292         ulong rate;
293         int ret;
294
295         ret = clk_get_by_index(dev, 0, &clk);
296         if (ret)
297                 return ret;
298
299         switch (eth_pdata->phy_interface) {
300         case PHY_INTERFACE_MODE_RGMII:
301                 /*
302                  * If the gmac clock is from internal pll, need to set and
303                  * check the return value for gmac clock at RGMII mode. If
304                  * the gmac clock is from external source, the clock rate
305                  * is not set, because of it is bypassed.
306                  */
307                 if (!pdata->clock_input) {
308                         rate = clk_set_rate(&clk, 125000000);
309                         if (rate != 125000000)
310                                 return -EINVAL;
311                 }
312
313                 /* Set to RGMII mode */
314                 if (ops->set_to_rgmii)
315                         ops->set_to_rgmii(pdata);
316                 else
317                         return -EPERM;
318
319                 break;
320         case PHY_INTERFACE_MODE_RMII:
321                 /* The commet is the same as RGMII mode */
322                 if (!pdata->clock_input) {
323                         rate = clk_set_rate(&clk, 50000000);
324                         if (rate != 50000000)
325                                 return -EINVAL;
326                 }
327
328                 /* Set to RMII mode */
329                 if (ops->set_to_rmii)
330                         ops->set_to_rmii(pdata);
331                 else
332                         return -EPERM;
333
334                 break;
335         default:
336                 debug("NO interface defined!\n");
337                 return -ENXIO;
338         }
339
340         return designware_eth_probe(dev);
341 }
342
343 static int gmac_rockchip_eth_start(struct udevice *dev)
344 {
345         struct eth_pdata *pdata = dev_get_platdata(dev);
346         struct dw_eth_dev *priv = dev_get_priv(dev);
347         struct rk_gmac_ops *ops =
348                 (struct rk_gmac_ops *)dev_get_driver_data(dev);
349         int ret;
350
351         ret = designware_eth_init(priv, pdata->enetaddr);
352         if (ret)
353                 return ret;
354         ret = ops->fix_mac_speed(priv);
355         if (ret)
356                 return ret;
357         ret = designware_eth_enable(priv);
358         if (ret)
359                 return ret;
360
361         return 0;
362 }
363
364 const struct eth_ops gmac_rockchip_eth_ops = {
365         .start                  = gmac_rockchip_eth_start,
366         .send                   = designware_eth_send,
367         .recv                   = designware_eth_recv,
368         .free_pkt               = designware_eth_free_pkt,
369         .stop                   = designware_eth_stop,
370         .write_hwaddr           = designware_eth_write_hwaddr,
371 };
372
373 const struct rk_gmac_ops rk3288_gmac_ops = {
374         .fix_mac_speed = rk3288_gmac_fix_mac_speed,
375         .set_to_rgmii = rk3288_gmac_set_to_rgmii,
376 };
377
378 const struct rk_gmac_ops rk3368_gmac_ops = {
379         .fix_mac_speed = rk3368_gmac_fix_mac_speed,
380         .set_to_rgmii = rk3368_gmac_set_to_rgmii,
381 };
382
383 const struct rk_gmac_ops rk3399_gmac_ops = {
384         .fix_mac_speed = rk3399_gmac_fix_mac_speed,
385         .set_to_rgmii = rk3399_gmac_set_to_rgmii,
386 };
387
388 const struct rk_gmac_ops rv1108_gmac_ops = {
389         .fix_mac_speed = rv1108_set_rmii_speed,
390         .set_to_rmii = rv1108_gmac_set_to_rmii,
391 };
392
393 static const struct udevice_id rockchip_gmac_ids[] = {
394         { .compatible = "rockchip,rk3288-gmac",
395           .data = (ulong)&rk3288_gmac_ops },
396         { .compatible = "rockchip,rk3368-gmac",
397           .data = (ulong)&rk3368_gmac_ops },
398         { .compatible = "rockchip,rk3399-gmac",
399           .data = (ulong)&rk3399_gmac_ops },
400         { .compatible = "rockchip,rv1108-gmac",
401           .data = (ulong)&rv1108_gmac_ops },
402         { }
403 };
404
405 U_BOOT_DRIVER(eth_gmac_rockchip) = {
406         .name   = "gmac_rockchip",
407         .id     = UCLASS_ETH,
408         .of_match = rockchip_gmac_ids,
409         .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
410         .probe  = gmac_rockchip_probe,
411         .ops    = &gmac_rockchip_eth_ops,
412         .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
413         .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
414         .flags = DM_FLAG_ALLOC_PRIV_DMA,
415 };