blob: c8cfe7448d4daa7e793b3fba8380de6545dd55d0 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Sjoerd Simons54c46f92017-01-11 11:46:11 +01002/*
3 * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
4 *
Sjoerd Simons54c46f92017-01-11 11:46:11 +01005 * Rockchip GMAC ethernet IP driver for U-Boot
6 */
7
Sjoerd Simons54c46f92017-01-11 11:46:11 +01008#include <dm.h>
9#include <clk.h>
Simon Glass0f2af882020-05-10 11:40:05 -060010#include <log.h>
Simon Glass274e0b02020-05-10 11:39:56 -060011#include <net.h>
Sjoerd Simons54c46f92017-01-11 11:46:11 +010012#include <phy.h>
13#include <syscon.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060014#include <asm/global_data.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080015#include <asm/arch-rockchip/periph.h>
16#include <asm/arch-rockchip/clock.h>
17#include <asm/arch-rockchip/hardware.h>
Heiko Stuebner0f03e422019-07-24 01:20:29 +020018#include <asm/arch-rockchip/grf_px30.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080019#include <asm/arch-rockchip/grf_rk322x.h>
20#include <asm/arch-rockchip/grf_rk3288.h>
Jonas Karlman0333e3b2024-04-08 18:14:11 +000021#include <asm/arch-rockchip/grf_rk3308.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080022#include <asm/arch-rockchip/grf_rk3328.h>
23#include <asm/arch-rockchip/grf_rk3368.h>
24#include <asm/arch-rockchip/grf_rk3399.h>
25#include <asm/arch-rockchip/grf_rv1108.h>
Sjoerd Simons54c46f92017-01-11 11:46:11 +010026#include <dm/pinctrl.h>
27#include <dt-bindings/clock/rk3288-cru.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060028#include <linux/bitops.h>
Sjoerd Simons54c46f92017-01-11 11:46:11 +010029#include "designware.h"
30
Janine Hagemannb6a6dc82018-08-28 08:25:05 +020031DECLARE_GLOBAL_DATA_PTR;
32#define DELAY_ENABLE(soc, tx, rx) \
33 (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \
34 ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE))
35
Sjoerd Simons54c46f92017-01-11 11:46:11 +010036/*
37 * Platform data for the gmac
38 *
39 * dw_eth_pdata: Required platform data for designware driver (must be first)
40 */
Simon Glassb75b15b2020-12-03 16:55:23 -070041struct gmac_rockchip_plat {
Sjoerd Simons54c46f92017-01-11 11:46:11 +010042 struct dw_eth_pdata dw_eth_pdata;
David Wu672e4f22018-01-13 14:01:12 +080043 bool clock_input;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010044 int tx_delay;
45 int rx_delay;
46};
47
Philipp Tomsich99cac582017-03-24 19:24:26 +010048struct rk_gmac_ops {
49 int (*fix_mac_speed)(struct dw_eth_dev *priv);
Simon Glassb75b15b2020-12-03 16:55:23 -070050 void (*set_to_rmii)(struct gmac_rockchip_plat *pdata);
51 void (*set_to_rgmii)(struct gmac_rockchip_plat *pdata);
Philipp Tomsich99cac582017-03-24 19:24:26 +010052};
53
Simon Glassaad29ae2020-12-03 16:55:21 -070054static int gmac_rockchip_of_to_plat(struct udevice *dev)
Sjoerd Simons54c46f92017-01-11 11:46:11 +010055{
Simon Glassb75b15b2020-12-03 16:55:23 -070056 struct gmac_rockchip_plat *pdata = dev_get_plat(dev);
David Wu672e4f22018-01-13 14:01:12 +080057 const char *string;
58
59 string = dev_read_string(dev, "clock_in_out");
60 if (!strcmp(string, "input"))
61 pdata->clock_input = true;
62 else
63 pdata->clock_input = false;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010064
Philipp Tomsich99cac582017-03-24 19:24:26 +010065 /* Check the new naming-style first... */
Philipp Tomsich150005b2017-06-07 18:46:01 +020066 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
67 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
Philipp Tomsich99cac582017-03-24 19:24:26 +010068
69 /* ... and fall back to the old naming style or default, if necessary */
70 if (pdata->tx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020071 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
Philipp Tomsich99cac582017-03-24 19:24:26 +010072 if (pdata->rx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020073 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
Sjoerd Simons54c46f92017-01-11 11:46:11 +010074
Simon Glassaad29ae2020-12-03 16:55:21 -070075 return designware_eth_of_to_plat(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +010076}
77
Heiko Stuebner0f03e422019-07-24 01:20:29 +020078static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
79{
80 struct px30_grf *grf;
81 struct clk clk_speed;
82 int speed, ret;
83 enum {
84 PX30_GMAC_SPEED_SHIFT = 0x2,
85 PX30_GMAC_SPEED_MASK = BIT(2),
86 PX30_GMAC_SPEED_10M = 0,
87 PX30_GMAC_SPEED_100M = BIT(2),
88 };
89
90 ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
91 &clk_speed);
92 if (ret)
93 return ret;
94
95 switch (priv->phydev->speed) {
96 case 10:
97 speed = PX30_GMAC_SPEED_10M;
98 ret = clk_set_rate(&clk_speed, 2500000);
99 if (ret)
100 return ret;
101 break;
102 case 100:
103 speed = PX30_GMAC_SPEED_100M;
104 ret = clk_set_rate(&clk_speed, 25000000);
105 if (ret)
106 return ret;
107 break;
108 default:
109 debug("Unknown phy speed: %d\n", priv->phydev->speed);
110 return -EINVAL;
111 }
112
113 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
114 rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed);
115
116 return 0;
117}
118
David Wuadcde492018-01-13 14:05:30 +0800119static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
120{
121 struct rk322x_grf *grf;
122 int clk;
123 enum {
124 RK3228_GMAC_CLK_SEL_SHIFT = 8,
125 RK3228_GMAC_CLK_SEL_MASK = GENMASK(9, 8),
126 RK3228_GMAC_CLK_SEL_125M = 0 << 8,
127 RK3228_GMAC_CLK_SEL_25M = 3 << 8,
128 RK3228_GMAC_CLK_SEL_2_5M = 2 << 8,
129 };
130
131 switch (priv->phydev->speed) {
132 case 10:
133 clk = RK3228_GMAC_CLK_SEL_2_5M;
134 break;
135 case 100:
136 clk = RK3228_GMAC_CLK_SEL_25M;
137 break;
138 case 1000:
139 clk = RK3228_GMAC_CLK_SEL_125M;
140 break;
141 default:
142 debug("Unknown phy speed: %d\n", priv->phydev->speed);
143 return -EINVAL;
144 }
145
146 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
147 rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk);
148
149 return 0;
150}
151
Philipp Tomsich99cac582017-03-24 19:24:26 +0100152static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100153{
Christoph Fritz38bf1382025-04-16 13:45:35 +0200154 struct dw_eth_pdata *dw_pdata = dev_get_plat(priv->dev);
155 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100156 struct rk3288_grf *grf;
Christoph Fritz38bf1382025-04-16 13:45:35 +0200157 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100158 int clk;
159
Christoph Fritz38bf1382025-04-16 13:45:35 +0200160 if (eth_pdata->phy_interface == PHY_INTERFACE_MODE_RMII) {
161 switch (priv->phydev->speed) {
162 case 10:
163 rk_clrsetreg(&grf->soc_con1,
164 RK3288_RMII_CLK_SEL_MASK |
165 RK3288_GMAC_SPEED_MASK,
166 RK3288_RMII_CLK_SEL_2_5M |
167 RK3288_GMAC_SPEED_10M);
168 break;
169 case 100:
170 rk_clrsetreg(&grf->soc_con1,
171 RK3288_RMII_CLK_SEL_MASK |
172 RK3288_GMAC_SPEED_MASK,
173 RK3288_RMII_CLK_SEL_25M |
174 RK3288_GMAC_SPEED_100M);
175 break;
176 default:
177 debug("Unknown phy speed: %d\n", priv->phydev->speed);
178 return -EINVAL;
179 }
180 } else {
181 switch (priv->phydev->speed) {
182 case 10:
183 clk = RK3288_GMAC_CLK_SEL_2_5M;
184 break;
185 case 100:
186 clk = RK3288_GMAC_CLK_SEL_25M;
187 break;
188 case 1000:
189 clk = RK3288_GMAC_CLK_SEL_125M;
190 break;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100191
Christoph Fritz38bf1382025-04-16 13:45:35 +0200192 default:
193 debug("Unknown phy speed: %d\n", priv->phydev->speed);
194 return -EINVAL;
195 }
196
197 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
198 }
Philipp Tomsich99cac582017-03-24 19:24:26 +0100199
200 return 0;
201}
202
David Wu5d6d51f2019-11-26 09:39:49 +0800203static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv)
204{
205 struct rk3308_grf *grf;
206 struct clk clk_speed;
207 int speed, ret;
208 enum {
209 RK3308_GMAC_SPEED_SHIFT = 0x0,
210 RK3308_GMAC_SPEED_MASK = BIT(0),
211 RK3308_GMAC_SPEED_10M = 0,
212 RK3308_GMAC_SPEED_100M = BIT(0),
213 };
214
215 ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
216 &clk_speed);
217 if (ret)
218 return ret;
219
220 switch (priv->phydev->speed) {
221 case 10:
222 speed = RK3308_GMAC_SPEED_10M;
223 ret = clk_set_rate(&clk_speed, 2500000);
224 if (ret)
225 return ret;
226 break;
227 case 100:
228 speed = RK3308_GMAC_SPEED_100M;
229 ret = clk_set_rate(&clk_speed, 25000000);
230 if (ret)
231 return ret;
232 break;
233 default:
234 debug("Unknown phy speed: %d\n", priv->phydev->speed);
235 return -EINVAL;
236 }
237
238 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
239 rk_clrsetreg(&grf->mac_con0, RK3308_GMAC_SPEED_MASK, speed);
240
241 return 0;
242}
243
David Wubac972b2018-01-13 14:03:04 +0800244static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
245{
246 struct rk3328_grf_regs *grf;
247 int clk;
248 enum {
249 RK3328_GMAC_CLK_SEL_SHIFT = 11,
250 RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11),
251 RK3328_GMAC_CLK_SEL_125M = 0 << 11,
252 RK3328_GMAC_CLK_SEL_25M = 3 << 11,
253 RK3328_GMAC_CLK_SEL_2_5M = 2 << 11,
254 };
255
256 switch (priv->phydev->speed) {
257 case 10:
258 clk = RK3328_GMAC_CLK_SEL_2_5M;
259 break;
260 case 100:
261 clk = RK3328_GMAC_CLK_SEL_25M;
262 break;
263 case 1000:
264 clk = RK3328_GMAC_CLK_SEL_125M;
265 break;
266 default:
267 debug("Unknown phy speed: %d\n", priv->phydev->speed);
268 return -EINVAL;
269 }
270
271 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
272 rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
273
274 return 0;
275}
276
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200277static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
278{
279 struct rk3368_grf *grf;
280 int clk;
281 enum {
282 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
283 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
284 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
285 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
286 };
287
288 switch (priv->phydev->speed) {
289 case 10:
290 clk = RK3368_GMAC_CLK_SEL_2_5M;
291 break;
292 case 100:
293 clk = RK3368_GMAC_CLK_SEL_25M;
294 break;
295 case 1000:
296 clk = RK3368_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_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
305
306 return 0;
307}
308
Philipp Tomsich99cac582017-03-24 19:24:26 +0100309static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
310{
311 struct rk3399_grf_regs *grf;
312 int clk;
313
314 switch (priv->phydev->speed) {
315 case 10:
316 clk = RK3399_GMAC_CLK_SEL_2_5M;
317 break;
318 case 100:
319 clk = RK3399_GMAC_CLK_SEL_25M;
320 break;
321 case 1000:
322 clk = RK3399_GMAC_CLK_SEL_125M;
323 break;
324 default:
325 debug("Unknown phy speed: %d\n", priv->phydev->speed);
326 return -EINVAL;
327 }
328
329 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
330 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100331
332 return 0;
333}
334
David Wu672e4f22018-01-13 14:01:12 +0800335static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
336{
337 struct rv1108_grf *grf;
338 int clk, speed;
339 enum {
340 RV1108_GMAC_SPEED_MASK = BIT(2),
341 RV1108_GMAC_SPEED_10M = 0 << 2,
342 RV1108_GMAC_SPEED_100M = 1 << 2,
343 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
344 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
345 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
346 };
347
348 switch (priv->phydev->speed) {
349 case 10:
350 clk = RV1108_GMAC_CLK_SEL_2_5M;
351 speed = RV1108_GMAC_SPEED_10M;
352 break;
353 case 100:
354 clk = RV1108_GMAC_CLK_SEL_25M;
355 speed = RV1108_GMAC_SPEED_100M;
356 break;
357 default:
358 debug("Unknown phy speed: %d\n", priv->phydev->speed);
359 return -EINVAL;
360 }
361
362 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
363 rk_clrsetreg(&grf->gmac_con0,
364 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
365 clk | speed);
366
367 return 0;
368}
369
Simon Glassb75b15b2020-12-03 16:55:23 -0700370static void px30_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200371{
372 struct px30_grf *grf;
373 enum {
374 PX30_GMAC_PHY_INTF_SEL_SHIFT = 4,
375 PX30_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 6),
376 PX30_GMAC_PHY_INTF_SEL_RMII = BIT(6),
377 };
378
379 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
380
381 rk_clrsetreg(&grf->mac_con1,
382 PX30_GMAC_PHY_INTF_SEL_MASK,
383 PX30_GMAC_PHY_INTF_SEL_RMII);
384}
385
Simon Glassb75b15b2020-12-03 16:55:23 -0700386static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
David Wuadcde492018-01-13 14:05:30 +0800387{
388 struct rk322x_grf *grf;
389 enum {
390 RK3228_RMII_MODE_SHIFT = 10,
391 RK3228_RMII_MODE_MASK = BIT(10),
392
393 RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
394 RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
395 RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
396
397 RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
398 RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
399 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
400
401 RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
402 RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
403 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
404 };
405 enum {
406 RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
407 RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
408
409 RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
410 RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
411 };
412
413 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
414 rk_clrsetreg(&grf->mac_con[1],
415 RK3228_RMII_MODE_MASK |
416 RK3228_GMAC_PHY_INTF_SEL_MASK |
417 RK3228_RXCLK_DLY_ENA_GMAC_MASK |
418 RK3228_TXCLK_DLY_ENA_GMAC_MASK,
419 RK3228_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200420 DELAY_ENABLE(RK3228, pdata->tx_delay, pdata->rx_delay));
David Wuadcde492018-01-13 14:05:30 +0800421
422 rk_clrsetreg(&grf->mac_con[0],
423 RK3228_CLK_RX_DL_CFG_GMAC_MASK |
424 RK3228_CLK_TX_DL_CFG_GMAC_MASK,
425 pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
426 pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
427}
428
Christoph Fritz38bf1382025-04-16 13:45:35 +0200429static void rk3288_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
430{
431 struct rk3288_grf *grf;
432
433 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
434
435 rk_clrsetreg(&grf->soc_con1,
436 RK3288_GMAC_PHY_INTF_SEL_MASK | RK3288_RMII_MODE_MASK,
437 RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_RMII_MODE);
438}
439
Simon Glassb75b15b2020-12-03 16:55:23 -0700440static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
Philipp Tomsich99cac582017-03-24 19:24:26 +0100441{
442 struct rk3288_grf *grf;
443
444 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
445 rk_clrsetreg(&grf->soc_con1,
446 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
447 RK3288_GMAC_PHY_INTF_SEL_RGMII);
448
449 rk_clrsetreg(&grf->soc_con3,
450 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
451 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
452 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
453 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200454 DELAY_ENABLE(RK3288, pdata->rx_delay, pdata->tx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100455 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
456 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
457}
458
Simon Glassb75b15b2020-12-03 16:55:23 -0700459static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
David Wu5d6d51f2019-11-26 09:39:49 +0800460{
461 struct rk3308_grf *grf;
462 enum {
463 RK3308_GMAC_PHY_INTF_SEL_SHIFT = 2,
464 RK3308_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 2),
465 RK3308_GMAC_PHY_INTF_SEL_RMII = BIT(4),
466 };
467
468 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
469
470 rk_clrsetreg(&grf->mac_con0,
471 RK3308_GMAC_PHY_INTF_SEL_MASK,
472 RK3308_GMAC_PHY_INTF_SEL_RMII);
473}
474
Simon Glassb75b15b2020-12-03 16:55:23 -0700475static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
David Wubac972b2018-01-13 14:03:04 +0800476{
477 struct rk3328_grf_regs *grf;
478 enum {
479 RK3328_RMII_MODE_SHIFT = 9,
480 RK3328_RMII_MODE_MASK = BIT(9),
481
482 RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4,
483 RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
484 RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
485
486 RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
487 RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
488 RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
489
490 RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
491 RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
492 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
493 };
494 enum {
495 RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
496 RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
497
498 RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
499 RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
500 };
501
502 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
503 rk_clrsetreg(&grf->mac_con[1],
504 RK3328_RMII_MODE_MASK |
505 RK3328_GMAC_PHY_INTF_SEL_MASK |
506 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
507 RK3328_TXCLK_DLY_ENA_GMAC_MASK,
508 RK3328_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200509 DELAY_ENABLE(RK3328, pdata->tx_delay, pdata->rx_delay));
David Wubac972b2018-01-13 14:03:04 +0800510
511 rk_clrsetreg(&grf->mac_con[0],
512 RK3328_CLK_RX_DL_CFG_GMAC_MASK |
513 RK3328_CLK_TX_DL_CFG_GMAC_MASK,
514 pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
515 pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
516}
517
Simon Glassb75b15b2020-12-03 16:55:23 -0700518static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200519{
520 struct rk3368_grf *grf;
521 enum {
522 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
523 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
524 RK3368_RMII_MODE_MASK = BIT(6),
525 RK3368_RMII_MODE = BIT(6),
526 };
527 enum {
528 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
529 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
530 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
531 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
532 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
533 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
534 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
535 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
536 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
537 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
538 };
539
540 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
541 rk_clrsetreg(&grf->soc_con15,
542 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
543 RK3368_GMAC_PHY_INTF_SEL_RGMII);
544
545 rk_clrsetreg(&grf->soc_con16,
546 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
547 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
548 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
549 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200550 DELAY_ENABLE(RK3368, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200551 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
552 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
553}
554
Simon Glassb75b15b2020-12-03 16:55:23 -0700555static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
Philipp Tomsich99cac582017-03-24 19:24:26 +0100556{
557 struct rk3399_grf_regs *grf;
558
559 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
560
561 rk_clrsetreg(&grf->soc_con5,
562 RK3399_GMAC_PHY_INTF_SEL_MASK,
563 RK3399_GMAC_PHY_INTF_SEL_RGMII);
564
565 rk_clrsetreg(&grf->soc_con6,
566 RK3399_RXCLK_DLY_ENA_GMAC_MASK |
567 RK3399_TXCLK_DLY_ENA_GMAC_MASK |
568 RK3399_CLK_RX_DL_CFG_GMAC_MASK |
569 RK3399_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200570 DELAY_ENABLE(RK3399, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100571 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
572 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
573}
574
Simon Glassb75b15b2020-12-03 16:55:23 -0700575static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
David Wu672e4f22018-01-13 14:01:12 +0800576{
577 struct rv1108_grf *grf;
578
579 enum {
580 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
581 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4,
582 };
583
584 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
585 rk_clrsetreg(&grf->gmac_con0,
586 RV1108_GMAC_PHY_INTF_SEL_MASK,
587 RV1108_GMAC_PHY_INTF_SEL_RMII);
588}
589
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100590static int gmac_rockchip_probe(struct udevice *dev)
591{
Simon Glassb75b15b2020-12-03 16:55:23 -0700592 struct gmac_rockchip_plat *pdata = dev_get_plat(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100593 struct rk_gmac_ops *ops =
594 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Simon Glassfa20e932020-12-03 16:55:20 -0700595 struct dw_eth_pdata *dw_pdata = dev_get_plat(dev);
David Wu672e4f22018-01-13 14:01:12 +0800596 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100597 struct clk clk;
David Wu672e4f22018-01-13 14:01:12 +0800598 ulong rate;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100599 int ret;
600
Sean Anderson08d531c2021-06-11 00:16:07 -0400601 ret = clk_set_defaults(dev, CLK_DEFAULTS_PRE);
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200602 if (ret)
603 debug("%s clk_set_defaults failed %d\n", __func__, ret);
604
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100605 ret = clk_get_by_index(dev, 0, &clk);
606 if (ret)
607 return ret;
608
David Wu672e4f22018-01-13 14:01:12 +0800609 switch (eth_pdata->phy_interface) {
610 case PHY_INTERFACE_MODE_RGMII:
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200611 /* Set to RGMII mode */
612 if (ops->set_to_rgmii)
613 ops->set_to_rgmii(pdata);
614 else
615 return -EPERM;
616
David Wu672e4f22018-01-13 14:01:12 +0800617 /*
618 * If the gmac clock is from internal pll, need to set and
619 * check the return value for gmac clock at RGMII mode. If
620 * the gmac clock is from external source, the clock rate
621 * is not set, because of it is bypassed.
622 */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200623
David Wu672e4f22018-01-13 14:01:12 +0800624 if (!pdata->clock_input) {
625 rate = clk_set_rate(&clk, 125000000);
626 if (rate != 125000000)
627 return -EINVAL;
628 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200629 break;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100630
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200631 case PHY_INTERFACE_MODE_RGMII_ID:
David Wu672e4f22018-01-13 14:01:12 +0800632 /* Set to RGMII mode */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200633 if (ops->set_to_rgmii) {
634 pdata->tx_delay = 0;
635 pdata->rx_delay = 0;
David Wu672e4f22018-01-13 14:01:12 +0800636 ops->set_to_rgmii(pdata);
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200637 } else
David Wu672e4f22018-01-13 14:01:12 +0800638 return -EPERM;
639
David Wu672e4f22018-01-13 14:01:12 +0800640 if (!pdata->clock_input) {
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200641 rate = clk_set_rate(&clk, 125000000);
642 if (rate != 125000000)
David Wu672e4f22018-01-13 14:01:12 +0800643 return -EINVAL;
644 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200645 break;
David Wu672e4f22018-01-13 14:01:12 +0800646
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200647 case PHY_INTERFACE_MODE_RMII:
David Wu672e4f22018-01-13 14:01:12 +0800648 /* Set to RMII mode */
649 if (ops->set_to_rmii)
650 ops->set_to_rmii(pdata);
651 else
652 return -EPERM;
653
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200654 if (!pdata->clock_input) {
655 rate = clk_set_rate(&clk, 50000000);
656 if (rate != 50000000)
657 return -EINVAL;
658 }
659 break;
660
661 case PHY_INTERFACE_MODE_RGMII_RXID:
662 /* Set to RGMII_RXID mode */
663 if (ops->set_to_rgmii) {
664 pdata->tx_delay = 0;
665 ops->set_to_rgmii(pdata);
666 } else
667 return -EPERM;
668
669 if (!pdata->clock_input) {
670 rate = clk_set_rate(&clk, 125000000);
671 if (rate != 125000000)
672 return -EINVAL;
673 }
David Wu672e4f22018-01-13 14:01:12 +0800674 break;
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200675
676 case PHY_INTERFACE_MODE_RGMII_TXID:
677 /* Set to RGMII_TXID mode */
678 if (ops->set_to_rgmii) {
679 pdata->rx_delay = 0;
680 ops->set_to_rgmii(pdata);
681 } else
682 return -EPERM;
683
684 if (!pdata->clock_input) {
685 rate = clk_set_rate(&clk, 125000000);
686 if (rate != 125000000)
687 return -EINVAL;
688 }
689 break;
690
David Wu672e4f22018-01-13 14:01:12 +0800691 default:
692 debug("NO interface defined!\n");
693 return -ENXIO;
694 }
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100695
696 return designware_eth_probe(dev);
697}
698
699static int gmac_rockchip_eth_start(struct udevice *dev)
700{
Simon Glassfa20e932020-12-03 16:55:20 -0700701 struct eth_pdata *pdata = dev_get_plat(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100702 struct dw_eth_dev *priv = dev_get_priv(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100703 struct rk_gmac_ops *ops =
704 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100705 int ret;
706
707 ret = designware_eth_init(priv, pdata->enetaddr);
708 if (ret)
709 return ret;
Philipp Tomsich99cac582017-03-24 19:24:26 +0100710 ret = ops->fix_mac_speed(priv);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100711 if (ret)
712 return ret;
713 ret = designware_eth_enable(priv);
714 if (ret)
715 return ret;
716
717 return 0;
718}
719
720const struct eth_ops gmac_rockchip_eth_ops = {
721 .start = gmac_rockchip_eth_start,
722 .send = designware_eth_send,
723 .recv = designware_eth_recv,
724 .free_pkt = designware_eth_free_pkt,
725 .stop = designware_eth_stop,
726 .write_hwaddr = designware_eth_write_hwaddr,
727};
728
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200729const struct rk_gmac_ops px30_gmac_ops = {
730 .fix_mac_speed = px30_gmac_fix_mac_speed,
731 .set_to_rmii = px30_gmac_set_to_rmii,
732};
733
David Wuadcde492018-01-13 14:05:30 +0800734const struct rk_gmac_ops rk3228_gmac_ops = {
735 .fix_mac_speed = rk3228_gmac_fix_mac_speed,
736 .set_to_rgmii = rk3228_gmac_set_to_rgmii,
737};
738
Philipp Tomsich99cac582017-03-24 19:24:26 +0100739const struct rk_gmac_ops rk3288_gmac_ops = {
740 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
741 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
Christoph Fritz38bf1382025-04-16 13:45:35 +0200742 .set_to_rmii = rk3288_gmac_set_to_rmii,
Philipp Tomsich99cac582017-03-24 19:24:26 +0100743};
744
David Wu5d6d51f2019-11-26 09:39:49 +0800745const struct rk_gmac_ops rk3308_gmac_ops = {
746 .fix_mac_speed = rk3308_gmac_fix_mac_speed,
747 .set_to_rmii = rk3308_gmac_set_to_rmii,
748};
749
David Wubac972b2018-01-13 14:03:04 +0800750const struct rk_gmac_ops rk3328_gmac_ops = {
751 .fix_mac_speed = rk3328_gmac_fix_mac_speed,
752 .set_to_rgmii = rk3328_gmac_set_to_rgmii,
753};
754
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200755const struct rk_gmac_ops rk3368_gmac_ops = {
756 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
757 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
758};
759
Philipp Tomsich99cac582017-03-24 19:24:26 +0100760const struct rk_gmac_ops rk3399_gmac_ops = {
761 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
762 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
763};
764
David Wu672e4f22018-01-13 14:01:12 +0800765const struct rk_gmac_ops rv1108_gmac_ops = {
766 .fix_mac_speed = rv1108_set_rmii_speed,
767 .set_to_rmii = rv1108_gmac_set_to_rmii,
768};
769
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100770static const struct udevice_id rockchip_gmac_ids[] = {
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200771 { .compatible = "rockchip,px30-gmac",
772 .data = (ulong)&px30_gmac_ops },
David Wuadcde492018-01-13 14:05:30 +0800773 { .compatible = "rockchip,rk3228-gmac",
774 .data = (ulong)&rk3228_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100775 { .compatible = "rockchip,rk3288-gmac",
776 .data = (ulong)&rk3288_gmac_ops },
Jonas Karlmanc8c20092024-04-08 18:14:07 +0000777 { .compatible = "rockchip,rk3308-gmac",
David Wu5d6d51f2019-11-26 09:39:49 +0800778 .data = (ulong)&rk3308_gmac_ops },
David Wubac972b2018-01-13 14:03:04 +0800779 { .compatible = "rockchip,rk3328-gmac",
780 .data = (ulong)&rk3328_gmac_ops },
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200781 { .compatible = "rockchip,rk3368-gmac",
782 .data = (ulong)&rk3368_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100783 { .compatible = "rockchip,rk3399-gmac",
784 .data = (ulong)&rk3399_gmac_ops },
David Wu672e4f22018-01-13 14:01:12 +0800785 { .compatible = "rockchip,rv1108-gmac",
786 .data = (ulong)&rv1108_gmac_ops },
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100787 { }
788};
789
790U_BOOT_DRIVER(eth_gmac_rockchip) = {
791 .name = "gmac_rockchip",
792 .id = UCLASS_ETH,
793 .of_match = rockchip_gmac_ids,
Simon Glassaad29ae2020-12-03 16:55:21 -0700794 .of_to_plat = gmac_rockchip_of_to_plat,
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100795 .probe = gmac_rockchip_probe,
796 .ops = &gmac_rockchip_eth_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700797 .priv_auto = sizeof(struct dw_eth_dev),
Simon Glassb75b15b2020-12-03 16:55:23 -0700798 .plat_auto = sizeof(struct gmac_rockchip_plat),
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100799 .flags = DM_FLAG_ALLOC_PRIV_DMA,
800};