blob: e152faf083dac0582a04715e1bfd62f200293ce4 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Sjoerd Simons0125bcf2017-01-11 11:46:11 +01002/*
3 * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
4 *
Sjoerd Simons0125bcf2017-01-11 11:46:11 +01005 * Rockchip GMAC ethernet IP driver for U-Boot
6 */
7
8#include <common.h>
9#include <dm.h>
10#include <clk.h>
11#include <phy.h>
12#include <syscon.h>
13#include <asm/io.h>
Kever Yang15f09a12019-03-28 11:01:23 +080014#include <asm/arch-rockchip/periph.h>
15#include <asm/arch-rockchip/clock.h>
16#include <asm/arch-rockchip/hardware.h>
Heiko Stuebnerb0791182019-07-24 01:20:29 +020017#include <asm/arch-rockchip/grf_px30.h>
Kever Yang15f09a12019-03-28 11:01:23 +080018#include <asm/arch-rockchip/grf_rk322x.h>
19#include <asm/arch-rockchip/grf_rk3288.h>
David Wu0ed8f1e2019-11-26 09:39:49 +080020#include <asm/arch-rk3308/grf_rk3308.h>
Kever Yang15f09a12019-03-28 11:01:23 +080021#include <asm/arch-rockchip/grf_rk3328.h>
22#include <asm/arch-rockchip/grf_rk3368.h>
23#include <asm/arch-rockchip/grf_rk3399.h>
24#include <asm/arch-rockchip/grf_rv1108.h>
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010025#include <dm/pinctrl.h>
26#include <dt-bindings/clock/rk3288-cru.h>
27#include "designware.h"
28
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +020029DECLARE_GLOBAL_DATA_PTR;
30#define DELAY_ENABLE(soc, tx, rx) \
31 (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \
32 ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE))
33
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010034/*
35 * Platform data for the gmac
36 *
37 * dw_eth_pdata: Required platform data for designware driver (must be first)
38 */
39struct gmac_rockchip_platdata {
40 struct dw_eth_pdata dw_eth_pdata;
David Wucaf74612018-01-13 14:01:12 +080041 bool clock_input;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010042 int tx_delay;
43 int rx_delay;
44};
45
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010046struct rk_gmac_ops {
47 int (*fix_mac_speed)(struct dw_eth_dev *priv);
David Wucaf74612018-01-13 14:01:12 +080048 void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010049 void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
50};
51
52
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010053static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
54{
55 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
David Wucaf74612018-01-13 14:01:12 +080056 const char *string;
57
58 string = dev_read_string(dev, "clock_in_out");
59 if (!strcmp(string, "input"))
60 pdata->clock_input = true;
61 else
62 pdata->clock_input = false;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010063
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010064 /* Check the new naming-style first... */
Philipp Tomsich7ad326a2017-06-07 18:46:01 +020065 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
66 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010067
68 /* ... and fall back to the old naming style or default, if necessary */
69 if (pdata->tx_delay == -ENOENT)
Philipp Tomsich7ad326a2017-06-07 18:46:01 +020070 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010071 if (pdata->rx_delay == -ENOENT)
Philipp Tomsich7ad326a2017-06-07 18:46:01 +020072 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010073
74 return designware_eth_ofdata_to_platdata(dev);
75}
76
Heiko Stuebnerb0791182019-07-24 01:20:29 +020077static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
78{
79 struct px30_grf *grf;
80 struct clk clk_speed;
81 int speed, ret;
82 enum {
83 PX30_GMAC_SPEED_SHIFT = 0x2,
84 PX30_GMAC_SPEED_MASK = BIT(2),
85 PX30_GMAC_SPEED_10M = 0,
86 PX30_GMAC_SPEED_100M = BIT(2),
87 };
88
89 ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
90 &clk_speed);
91 if (ret)
92 return ret;
93
94 switch (priv->phydev->speed) {
95 case 10:
96 speed = PX30_GMAC_SPEED_10M;
97 ret = clk_set_rate(&clk_speed, 2500000);
98 if (ret)
99 return ret;
100 break;
101 case 100:
102 speed = PX30_GMAC_SPEED_100M;
103 ret = clk_set_rate(&clk_speed, 25000000);
104 if (ret)
105 return ret;
106 break;
107 default:
108 debug("Unknown phy speed: %d\n", priv->phydev->speed);
109 return -EINVAL;
110 }
111
112 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
113 rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed);
114
115 return 0;
116}
117
David Wud12d7c02018-01-13 14:05:30 +0800118static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
119{
120 struct rk322x_grf *grf;
121 int clk;
122 enum {
123 RK3228_GMAC_CLK_SEL_SHIFT = 8,
124 RK3228_GMAC_CLK_SEL_MASK = GENMASK(9, 8),
125 RK3228_GMAC_CLK_SEL_125M = 0 << 8,
126 RK3228_GMAC_CLK_SEL_25M = 3 << 8,
127 RK3228_GMAC_CLK_SEL_2_5M = 2 << 8,
128 };
129
130 switch (priv->phydev->speed) {
131 case 10:
132 clk = RK3228_GMAC_CLK_SEL_2_5M;
133 break;
134 case 100:
135 clk = RK3228_GMAC_CLK_SEL_25M;
136 break;
137 case 1000:
138 clk = RK3228_GMAC_CLK_SEL_125M;
139 break;
140 default:
141 debug("Unknown phy speed: %d\n", priv->phydev->speed);
142 return -EINVAL;
143 }
144
145 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
146 rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk);
147
148 return 0;
149}
150
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100151static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100152{
153 struct rk3288_grf *grf;
154 int clk;
155
156 switch (priv->phydev->speed) {
157 case 10:
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100158 clk = RK3288_GMAC_CLK_SEL_2_5M;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100159 break;
160 case 100:
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100161 clk = RK3288_GMAC_CLK_SEL_25M;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100162 break;
163 case 1000:
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100164 clk = RK3288_GMAC_CLK_SEL_125M;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100165 break;
166 default:
167 debug("Unknown phy speed: %d\n", priv->phydev->speed);
168 return -EINVAL;
169 }
170
171 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100172 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100173
174 return 0;
175}
176
David Wu0ed8f1e2019-11-26 09:39:49 +0800177static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv)
178{
179 struct rk3308_grf *grf;
180 struct clk clk_speed;
181 int speed, ret;
182 enum {
183 RK3308_GMAC_SPEED_SHIFT = 0x0,
184 RK3308_GMAC_SPEED_MASK = BIT(0),
185 RK3308_GMAC_SPEED_10M = 0,
186 RK3308_GMAC_SPEED_100M = BIT(0),
187 };
188
189 ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
190 &clk_speed);
191 if (ret)
192 return ret;
193
194 switch (priv->phydev->speed) {
195 case 10:
196 speed = RK3308_GMAC_SPEED_10M;
197 ret = clk_set_rate(&clk_speed, 2500000);
198 if (ret)
199 return ret;
200 break;
201 case 100:
202 speed = RK3308_GMAC_SPEED_100M;
203 ret = clk_set_rate(&clk_speed, 25000000);
204 if (ret)
205 return ret;
206 break;
207 default:
208 debug("Unknown phy speed: %d\n", priv->phydev->speed);
209 return -EINVAL;
210 }
211
212 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
213 rk_clrsetreg(&grf->mac_con0, RK3308_GMAC_SPEED_MASK, speed);
214
215 return 0;
216}
217
David Wub3d2a6d2018-01-13 14:03:04 +0800218static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
219{
220 struct rk3328_grf_regs *grf;
221 int clk;
222 enum {
223 RK3328_GMAC_CLK_SEL_SHIFT = 11,
224 RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11),
225 RK3328_GMAC_CLK_SEL_125M = 0 << 11,
226 RK3328_GMAC_CLK_SEL_25M = 3 << 11,
227 RK3328_GMAC_CLK_SEL_2_5M = 2 << 11,
228 };
229
230 switch (priv->phydev->speed) {
231 case 10:
232 clk = RK3328_GMAC_CLK_SEL_2_5M;
233 break;
234 case 100:
235 clk = RK3328_GMAC_CLK_SEL_25M;
236 break;
237 case 1000:
238 clk = RK3328_GMAC_CLK_SEL_125M;
239 break;
240 default:
241 debug("Unknown phy speed: %d\n", priv->phydev->speed);
242 return -EINVAL;
243 }
244
245 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
246 rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
247
248 return 0;
249}
250
Philipp Tomsich793f2fd2017-07-25 17:02:51 +0200251static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
252{
253 struct rk3368_grf *grf;
254 int clk;
255 enum {
256 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
257 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
258 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
259 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
260 };
261
262 switch (priv->phydev->speed) {
263 case 10:
264 clk = RK3368_GMAC_CLK_SEL_2_5M;
265 break;
266 case 100:
267 clk = RK3368_GMAC_CLK_SEL_25M;
268 break;
269 case 1000:
270 clk = RK3368_GMAC_CLK_SEL_125M;
271 break;
272 default:
273 debug("Unknown phy speed: %d\n", priv->phydev->speed);
274 return -EINVAL;
275 }
276
277 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
278 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
279
280 return 0;
281}
282
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100283static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
284{
285 struct rk3399_grf_regs *grf;
286 int clk;
287
288 switch (priv->phydev->speed) {
289 case 10:
290 clk = RK3399_GMAC_CLK_SEL_2_5M;
291 break;
292 case 100:
293 clk = RK3399_GMAC_CLK_SEL_25M;
294 break;
295 case 1000:
296 clk = RK3399_GMAC_CLK_SEL_125M;
297 break;
298 default:
299 debug("Unknown phy speed: %d\n", priv->phydev->speed);
300 return -EINVAL;
301 }
302
303 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
304 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
305
306 return 0;
307}
308
David Wucaf74612018-01-13 14:01:12 +0800309static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
310{
311 struct rv1108_grf *grf;
312 int clk, speed;
313 enum {
314 RV1108_GMAC_SPEED_MASK = BIT(2),
315 RV1108_GMAC_SPEED_10M = 0 << 2,
316 RV1108_GMAC_SPEED_100M = 1 << 2,
317 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
318 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
319 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
320 };
321
322 switch (priv->phydev->speed) {
323 case 10:
324 clk = RV1108_GMAC_CLK_SEL_2_5M;
325 speed = RV1108_GMAC_SPEED_10M;
326 break;
327 case 100:
328 clk = RV1108_GMAC_CLK_SEL_25M;
329 speed = RV1108_GMAC_SPEED_100M;
330 break;
331 default:
332 debug("Unknown phy speed: %d\n", priv->phydev->speed);
333 return -EINVAL;
334 }
335
336 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
337 rk_clrsetreg(&grf->gmac_con0,
338 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
339 clk | speed);
340
341 return 0;
342}
343
Heiko Stuebnerb0791182019-07-24 01:20:29 +0200344static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
345{
346 struct px30_grf *grf;
347 enum {
348 PX30_GMAC_PHY_INTF_SEL_SHIFT = 4,
349 PX30_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 6),
350 PX30_GMAC_PHY_INTF_SEL_RMII = BIT(6),
351 };
352
353 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
354
355 rk_clrsetreg(&grf->mac_con1,
356 PX30_GMAC_PHY_INTF_SEL_MASK,
357 PX30_GMAC_PHY_INTF_SEL_RMII);
358}
359
David Wud12d7c02018-01-13 14:05:30 +0800360static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
361{
362 struct rk322x_grf *grf;
363 enum {
364 RK3228_RMII_MODE_SHIFT = 10,
365 RK3228_RMII_MODE_MASK = BIT(10),
366
367 RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
368 RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
369 RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
370
371 RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
372 RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
373 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
374
375 RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
376 RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
377 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
378 };
379 enum {
380 RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
381 RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
382
383 RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
384 RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
385 };
386
387 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
388 rk_clrsetreg(&grf->mac_con[1],
389 RK3228_RMII_MODE_MASK |
390 RK3228_GMAC_PHY_INTF_SEL_MASK |
391 RK3228_RXCLK_DLY_ENA_GMAC_MASK |
392 RK3228_TXCLK_DLY_ENA_GMAC_MASK,
393 RK3228_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200394 DELAY_ENABLE(RK3228, pdata->tx_delay, pdata->rx_delay));
David Wud12d7c02018-01-13 14:05:30 +0800395
396 rk_clrsetreg(&grf->mac_con[0],
397 RK3228_CLK_RX_DL_CFG_GMAC_MASK |
398 RK3228_CLK_TX_DL_CFG_GMAC_MASK,
399 pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
400 pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
401}
402
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100403static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
404{
405 struct rk3288_grf *grf;
406
407 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
408 rk_clrsetreg(&grf->soc_con1,
409 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
410 RK3288_GMAC_PHY_INTF_SEL_RGMII);
411
412 rk_clrsetreg(&grf->soc_con3,
413 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
414 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
415 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
416 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200417 DELAY_ENABLE(RK3288, pdata->rx_delay, pdata->tx_delay) |
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100418 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
419 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
420}
421
David Wu0ed8f1e2019-11-26 09:39:49 +0800422static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
423{
424 struct rk3308_grf *grf;
425 enum {
426 RK3308_GMAC_PHY_INTF_SEL_SHIFT = 2,
427 RK3308_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 2),
428 RK3308_GMAC_PHY_INTF_SEL_RMII = BIT(4),
429 };
430
431 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
432
433 rk_clrsetreg(&grf->mac_con0,
434 RK3308_GMAC_PHY_INTF_SEL_MASK,
435 RK3308_GMAC_PHY_INTF_SEL_RMII);
436}
437
David Wub3d2a6d2018-01-13 14:03:04 +0800438static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
439{
440 struct rk3328_grf_regs *grf;
441 enum {
442 RK3328_RMII_MODE_SHIFT = 9,
443 RK3328_RMII_MODE_MASK = BIT(9),
444
445 RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4,
446 RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
447 RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
448
449 RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
450 RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
451 RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
452
453 RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
454 RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
455 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
456 };
457 enum {
458 RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
459 RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
460
461 RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
462 RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
463 };
464
465 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
466 rk_clrsetreg(&grf->mac_con[1],
467 RK3328_RMII_MODE_MASK |
468 RK3328_GMAC_PHY_INTF_SEL_MASK |
469 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
470 RK3328_TXCLK_DLY_ENA_GMAC_MASK,
471 RK3328_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200472 DELAY_ENABLE(RK3328, pdata->tx_delay, pdata->rx_delay));
David Wub3d2a6d2018-01-13 14:03:04 +0800473
474 rk_clrsetreg(&grf->mac_con[0],
475 RK3328_CLK_RX_DL_CFG_GMAC_MASK |
476 RK3328_CLK_TX_DL_CFG_GMAC_MASK,
477 pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
478 pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
479}
480
Philipp Tomsich793f2fd2017-07-25 17:02:51 +0200481static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
482{
483 struct rk3368_grf *grf;
484 enum {
485 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
486 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
487 RK3368_RMII_MODE_MASK = BIT(6),
488 RK3368_RMII_MODE = BIT(6),
489 };
490 enum {
491 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
492 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
493 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
494 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
495 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
496 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
497 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
498 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
499 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
500 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
501 };
502
503 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
504 rk_clrsetreg(&grf->soc_con15,
505 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
506 RK3368_GMAC_PHY_INTF_SEL_RGMII);
507
508 rk_clrsetreg(&grf->soc_con16,
509 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
510 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
511 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
512 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200513 DELAY_ENABLE(RK3368, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich793f2fd2017-07-25 17:02:51 +0200514 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
515 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
516}
517
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100518static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
519{
520 struct rk3399_grf_regs *grf;
521
522 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
523
524 rk_clrsetreg(&grf->soc_con5,
525 RK3399_GMAC_PHY_INTF_SEL_MASK,
526 RK3399_GMAC_PHY_INTF_SEL_RGMII);
527
528 rk_clrsetreg(&grf->soc_con6,
529 RK3399_RXCLK_DLY_ENA_GMAC_MASK |
530 RK3399_TXCLK_DLY_ENA_GMAC_MASK |
531 RK3399_CLK_RX_DL_CFG_GMAC_MASK |
532 RK3399_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200533 DELAY_ENABLE(RK3399, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100534 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
535 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
536}
537
David Wucaf74612018-01-13 14:01:12 +0800538static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
539{
540 struct rv1108_grf *grf;
541
542 enum {
543 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
544 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4,
545 };
546
547 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
548 rk_clrsetreg(&grf->gmac_con0,
549 RV1108_GMAC_PHY_INTF_SEL_MASK,
550 RV1108_GMAC_PHY_INTF_SEL_RMII);
551}
552
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100553static int gmac_rockchip_probe(struct udevice *dev)
554{
555 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100556 struct rk_gmac_ops *ops =
557 (struct rk_gmac_ops *)dev_get_driver_data(dev);
David Wucaf74612018-01-13 14:01:12 +0800558 struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
559 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100560 struct clk clk;
David Wucaf74612018-01-13 14:01:12 +0800561 ulong rate;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100562 int ret;
563
Heiko Stuebnerb0791182019-07-24 01:20:29 +0200564 ret = clk_set_defaults(dev, 0);
565 if (ret)
566 debug("%s clk_set_defaults failed %d\n", __func__, ret);
567
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100568 ret = clk_get_by_index(dev, 0, &clk);
569 if (ret)
570 return ret;
571
David Wucaf74612018-01-13 14:01:12 +0800572 switch (eth_pdata->phy_interface) {
573 case PHY_INTERFACE_MODE_RGMII:
David Wucaf74612018-01-13 14:01:12 +0800574 /* Set to RGMII mode */
575 if (ops->set_to_rgmii)
576 ops->set_to_rgmii(pdata);
577 else
578 return -EPERM;
579
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200580 /*
581 * If the gmac clock is from internal pll, need to set and
582 * check the return value for gmac clock at RGMII mode. If
583 * the gmac clock is from external source, the clock rate
584 * is not set, because of it is bypassed.
585 */
586
David Wucaf74612018-01-13 14:01:12 +0800587 if (!pdata->clock_input) {
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200588 rate = clk_set_rate(&clk, 125000000);
589 if (rate != 125000000)
David Wucaf74612018-01-13 14:01:12 +0800590 return -EINVAL;
591 }
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200592 break;
David Wucaf74612018-01-13 14:01:12 +0800593
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200594 case PHY_INTERFACE_MODE_RGMII_ID:
595 /* Set to RGMII mode */
596 if (ops->set_to_rgmii) {
597 pdata->tx_delay = 0;
598 pdata->rx_delay = 0;
599 ops->set_to_rgmii(pdata);
600 } else
601 return -EPERM;
602
603 if (!pdata->clock_input) {
604 rate = clk_set_rate(&clk, 125000000);
605 if (rate != 125000000)
606 return -EINVAL;
607 }
608 break;
609
610 case PHY_INTERFACE_MODE_RMII:
David Wucaf74612018-01-13 14:01:12 +0800611 /* Set to RMII mode */
612 if (ops->set_to_rmii)
613 ops->set_to_rmii(pdata);
614 else
615 return -EPERM;
616
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200617 if (!pdata->clock_input) {
618 rate = clk_set_rate(&clk, 50000000);
619 if (rate != 50000000)
620 return -EINVAL;
621 }
David Wucaf74612018-01-13 14:01:12 +0800622 break;
Janine Hagemann3d1bd5b2018-08-28 08:25:05 +0200623
624 case PHY_INTERFACE_MODE_RGMII_RXID:
625 /* Set to RGMII_RXID mode */
626 if (ops->set_to_rgmii) {
627 pdata->tx_delay = 0;
628 ops->set_to_rgmii(pdata);
629 } else
630 return -EPERM;
631
632 if (!pdata->clock_input) {
633 rate = clk_set_rate(&clk, 125000000);
634 if (rate != 125000000)
635 return -EINVAL;
636 }
637 break;
638
639 case PHY_INTERFACE_MODE_RGMII_TXID:
640 /* Set to RGMII_TXID mode */
641 if (ops->set_to_rgmii) {
642 pdata->rx_delay = 0;
643 ops->set_to_rgmii(pdata);
644 } else
645 return -EPERM;
646
647 if (!pdata->clock_input) {
648 rate = clk_set_rate(&clk, 125000000);
649 if (rate != 125000000)
650 return -EINVAL;
651 }
652 break;
653
David Wucaf74612018-01-13 14:01:12 +0800654 default:
655 debug("NO interface defined!\n");
656 return -ENXIO;
657 }
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100658
659 return designware_eth_probe(dev);
660}
661
662static int gmac_rockchip_eth_start(struct udevice *dev)
663{
664 struct eth_pdata *pdata = dev_get_platdata(dev);
665 struct dw_eth_dev *priv = dev_get_priv(dev);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100666 struct rk_gmac_ops *ops =
667 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100668 int ret;
669
670 ret = designware_eth_init(priv, pdata->enetaddr);
671 if (ret)
672 return ret;
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100673 ret = ops->fix_mac_speed(priv);
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100674 if (ret)
675 return ret;
676 ret = designware_eth_enable(priv);
677 if (ret)
678 return ret;
679
680 return 0;
681}
682
683const struct eth_ops gmac_rockchip_eth_ops = {
684 .start = gmac_rockchip_eth_start,
685 .send = designware_eth_send,
686 .recv = designware_eth_recv,
687 .free_pkt = designware_eth_free_pkt,
688 .stop = designware_eth_stop,
689 .write_hwaddr = designware_eth_write_hwaddr,
690};
691
Heiko Stuebnerb0791182019-07-24 01:20:29 +0200692const struct rk_gmac_ops px30_gmac_ops = {
693 .fix_mac_speed = px30_gmac_fix_mac_speed,
694 .set_to_rmii = px30_gmac_set_to_rmii,
695};
696
David Wud12d7c02018-01-13 14:05:30 +0800697const struct rk_gmac_ops rk3228_gmac_ops = {
698 .fix_mac_speed = rk3228_gmac_fix_mac_speed,
699 .set_to_rgmii = rk3228_gmac_set_to_rgmii,
700};
701
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100702const struct rk_gmac_ops rk3288_gmac_ops = {
703 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
704 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
705};
706
David Wu0ed8f1e2019-11-26 09:39:49 +0800707const struct rk_gmac_ops rk3308_gmac_ops = {
708 .fix_mac_speed = rk3308_gmac_fix_mac_speed,
709 .set_to_rmii = rk3308_gmac_set_to_rmii,
710};
711
David Wub3d2a6d2018-01-13 14:03:04 +0800712const struct rk_gmac_ops rk3328_gmac_ops = {
713 .fix_mac_speed = rk3328_gmac_fix_mac_speed,
714 .set_to_rgmii = rk3328_gmac_set_to_rgmii,
715};
716
Philipp Tomsich793f2fd2017-07-25 17:02:51 +0200717const struct rk_gmac_ops rk3368_gmac_ops = {
718 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
719 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
720};
721
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100722const struct rk_gmac_ops rk3399_gmac_ops = {
723 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
724 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
725};
726
David Wucaf74612018-01-13 14:01:12 +0800727const struct rk_gmac_ops rv1108_gmac_ops = {
728 .fix_mac_speed = rv1108_set_rmii_speed,
729 .set_to_rmii = rv1108_gmac_set_to_rmii,
730};
731
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100732static const struct udevice_id rockchip_gmac_ids[] = {
Heiko Stuebnerb0791182019-07-24 01:20:29 +0200733 { .compatible = "rockchip,px30-gmac",
734 .data = (ulong)&px30_gmac_ops },
David Wud12d7c02018-01-13 14:05:30 +0800735 { .compatible = "rockchip,rk3228-gmac",
736 .data = (ulong)&rk3228_gmac_ops },
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100737 { .compatible = "rockchip,rk3288-gmac",
738 .data = (ulong)&rk3288_gmac_ops },
David Wu0ed8f1e2019-11-26 09:39:49 +0800739 { .compatible = "rockchip,rk3308-mac",
740 .data = (ulong)&rk3308_gmac_ops },
David Wub3d2a6d2018-01-13 14:03:04 +0800741 { .compatible = "rockchip,rk3328-gmac",
742 .data = (ulong)&rk3328_gmac_ops },
Philipp Tomsich793f2fd2017-07-25 17:02:51 +0200743 { .compatible = "rockchip,rk3368-gmac",
744 .data = (ulong)&rk3368_gmac_ops },
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100745 { .compatible = "rockchip,rk3399-gmac",
746 .data = (ulong)&rk3399_gmac_ops },
David Wucaf74612018-01-13 14:01:12 +0800747 { .compatible = "rockchip,rv1108-gmac",
748 .data = (ulong)&rv1108_gmac_ops },
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100749 { }
750};
751
752U_BOOT_DRIVER(eth_gmac_rockchip) = {
753 .name = "gmac_rockchip",
754 .id = UCLASS_ETH,
755 .of_match = rockchip_gmac_ids,
756 .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
757 .probe = gmac_rockchip_probe,
758 .ops = &gmac_rockchip_eth_ops,
759 .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
760 .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
761 .flags = DM_FLAG_ALLOC_PRIV_DMA,
762};