blob: d63e2dbfaebfabc9c5e052a5f76800509138902d [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
54
Simon Glassaad29ae2020-12-03 16:55:21 -070055static int gmac_rockchip_of_to_plat(struct udevice *dev)
Sjoerd Simons54c46f92017-01-11 11:46:11 +010056{
Simon Glassb75b15b2020-12-03 16:55:23 -070057 struct gmac_rockchip_plat *pdata = dev_get_plat(dev);
David Wu672e4f22018-01-13 14:01:12 +080058 const char *string;
59
60 string = dev_read_string(dev, "clock_in_out");
61 if (!strcmp(string, "input"))
62 pdata->clock_input = true;
63 else
64 pdata->clock_input = false;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010065
Philipp Tomsich99cac582017-03-24 19:24:26 +010066 /* Check the new naming-style first... */
Philipp Tomsich150005b2017-06-07 18:46:01 +020067 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
68 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
Philipp Tomsich99cac582017-03-24 19:24:26 +010069
70 /* ... and fall back to the old naming style or default, if necessary */
71 if (pdata->tx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020072 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
Philipp Tomsich99cac582017-03-24 19:24:26 +010073 if (pdata->rx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020074 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
Sjoerd Simons54c46f92017-01-11 11:46:11 +010075
Simon Glassaad29ae2020-12-03 16:55:21 -070076 return designware_eth_of_to_plat(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +010077}
78
Heiko Stuebner0f03e422019-07-24 01:20:29 +020079static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
80{
81 struct px30_grf *grf;
82 struct clk clk_speed;
83 int speed, ret;
84 enum {
85 PX30_GMAC_SPEED_SHIFT = 0x2,
86 PX30_GMAC_SPEED_MASK = BIT(2),
87 PX30_GMAC_SPEED_10M = 0,
88 PX30_GMAC_SPEED_100M = BIT(2),
89 };
90
91 ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
92 &clk_speed);
93 if (ret)
94 return ret;
95
96 switch (priv->phydev->speed) {
97 case 10:
98 speed = PX30_GMAC_SPEED_10M;
99 ret = clk_set_rate(&clk_speed, 2500000);
100 if (ret)
101 return ret;
102 break;
103 case 100:
104 speed = PX30_GMAC_SPEED_100M;
105 ret = clk_set_rate(&clk_speed, 25000000);
106 if (ret)
107 return ret;
108 break;
109 default:
110 debug("Unknown phy speed: %d\n", priv->phydev->speed);
111 return -EINVAL;
112 }
113
114 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
115 rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed);
116
117 return 0;
118}
119
David Wuadcde492018-01-13 14:05:30 +0800120static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
121{
122 struct rk322x_grf *grf;
123 int clk;
124 enum {
125 RK3228_GMAC_CLK_SEL_SHIFT = 8,
126 RK3228_GMAC_CLK_SEL_MASK = GENMASK(9, 8),
127 RK3228_GMAC_CLK_SEL_125M = 0 << 8,
128 RK3228_GMAC_CLK_SEL_25M = 3 << 8,
129 RK3228_GMAC_CLK_SEL_2_5M = 2 << 8,
130 };
131
132 switch (priv->phydev->speed) {
133 case 10:
134 clk = RK3228_GMAC_CLK_SEL_2_5M;
135 break;
136 case 100:
137 clk = RK3228_GMAC_CLK_SEL_25M;
138 break;
139 case 1000:
140 clk = RK3228_GMAC_CLK_SEL_125M;
141 break;
142 default:
143 debug("Unknown phy speed: %d\n", priv->phydev->speed);
144 return -EINVAL;
145 }
146
147 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
148 rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk);
149
150 return 0;
151}
152
Philipp Tomsich99cac582017-03-24 19:24:26 +0100153static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100154{
155 struct rk3288_grf *grf;
156 int clk;
157
158 switch (priv->phydev->speed) {
159 case 10:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100160 clk = RK3288_GMAC_CLK_SEL_2_5M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100161 break;
162 case 100:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100163 clk = RK3288_GMAC_CLK_SEL_25M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100164 break;
165 case 1000:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100166 clk = RK3288_GMAC_CLK_SEL_125M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100167 break;
168 default:
169 debug("Unknown phy speed: %d\n", priv->phydev->speed);
170 return -EINVAL;
171 }
172
173 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100174 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
175
176 return 0;
177}
178
David Wu5d6d51f2019-11-26 09:39:49 +0800179static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv)
180{
181 struct rk3308_grf *grf;
182 struct clk clk_speed;
183 int speed, ret;
184 enum {
185 RK3308_GMAC_SPEED_SHIFT = 0x0,
186 RK3308_GMAC_SPEED_MASK = BIT(0),
187 RK3308_GMAC_SPEED_10M = 0,
188 RK3308_GMAC_SPEED_100M = BIT(0),
189 };
190
191 ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
192 &clk_speed);
193 if (ret)
194 return ret;
195
196 switch (priv->phydev->speed) {
197 case 10:
198 speed = RK3308_GMAC_SPEED_10M;
199 ret = clk_set_rate(&clk_speed, 2500000);
200 if (ret)
201 return ret;
202 break;
203 case 100:
204 speed = RK3308_GMAC_SPEED_100M;
205 ret = clk_set_rate(&clk_speed, 25000000);
206 if (ret)
207 return ret;
208 break;
209 default:
210 debug("Unknown phy speed: %d\n", priv->phydev->speed);
211 return -EINVAL;
212 }
213
214 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
215 rk_clrsetreg(&grf->mac_con0, RK3308_GMAC_SPEED_MASK, speed);
216
217 return 0;
218}
219
David Wubac972b2018-01-13 14:03:04 +0800220static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
221{
222 struct rk3328_grf_regs *grf;
223 int clk;
224 enum {
225 RK3328_GMAC_CLK_SEL_SHIFT = 11,
226 RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11),
227 RK3328_GMAC_CLK_SEL_125M = 0 << 11,
228 RK3328_GMAC_CLK_SEL_25M = 3 << 11,
229 RK3328_GMAC_CLK_SEL_2_5M = 2 << 11,
230 };
231
232 switch (priv->phydev->speed) {
233 case 10:
234 clk = RK3328_GMAC_CLK_SEL_2_5M;
235 break;
236 case 100:
237 clk = RK3328_GMAC_CLK_SEL_25M;
238 break;
239 case 1000:
240 clk = RK3328_GMAC_CLK_SEL_125M;
241 break;
242 default:
243 debug("Unknown phy speed: %d\n", priv->phydev->speed);
244 return -EINVAL;
245 }
246
247 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
248 rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
249
250 return 0;
251}
252
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200253static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
254{
255 struct rk3368_grf *grf;
256 int clk;
257 enum {
258 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
259 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
260 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
261 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
262 };
263
264 switch (priv->phydev->speed) {
265 case 10:
266 clk = RK3368_GMAC_CLK_SEL_2_5M;
267 break;
268 case 100:
269 clk = RK3368_GMAC_CLK_SEL_25M;
270 break;
271 case 1000:
272 clk = RK3368_GMAC_CLK_SEL_125M;
273 break;
274 default:
275 debug("Unknown phy speed: %d\n", priv->phydev->speed);
276 return -EINVAL;
277 }
278
279 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
280 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
281
282 return 0;
283}
284
Philipp Tomsich99cac582017-03-24 19:24:26 +0100285static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
286{
287 struct rk3399_grf_regs *grf;
288 int clk;
289
290 switch (priv->phydev->speed) {
291 case 10:
292 clk = RK3399_GMAC_CLK_SEL_2_5M;
293 break;
294 case 100:
295 clk = RK3399_GMAC_CLK_SEL_25M;
296 break;
297 case 1000:
298 clk = RK3399_GMAC_CLK_SEL_125M;
299 break;
300 default:
301 debug("Unknown phy speed: %d\n", priv->phydev->speed);
302 return -EINVAL;
303 }
304
305 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
306 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100307
308 return 0;
309}
310
David Wu672e4f22018-01-13 14:01:12 +0800311static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
312{
313 struct rv1108_grf *grf;
314 int clk, speed;
315 enum {
316 RV1108_GMAC_SPEED_MASK = BIT(2),
317 RV1108_GMAC_SPEED_10M = 0 << 2,
318 RV1108_GMAC_SPEED_100M = 1 << 2,
319 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
320 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
321 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
322 };
323
324 switch (priv->phydev->speed) {
325 case 10:
326 clk = RV1108_GMAC_CLK_SEL_2_5M;
327 speed = RV1108_GMAC_SPEED_10M;
328 break;
329 case 100:
330 clk = RV1108_GMAC_CLK_SEL_25M;
331 speed = RV1108_GMAC_SPEED_100M;
332 break;
333 default:
334 debug("Unknown phy speed: %d\n", priv->phydev->speed);
335 return -EINVAL;
336 }
337
338 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
339 rk_clrsetreg(&grf->gmac_con0,
340 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
341 clk | speed);
342
343 return 0;
344}
345
Simon Glassb75b15b2020-12-03 16:55:23 -0700346static void px30_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200347{
348 struct px30_grf *grf;
349 enum {
350 PX30_GMAC_PHY_INTF_SEL_SHIFT = 4,
351 PX30_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 6),
352 PX30_GMAC_PHY_INTF_SEL_RMII = BIT(6),
353 };
354
355 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
356
357 rk_clrsetreg(&grf->mac_con1,
358 PX30_GMAC_PHY_INTF_SEL_MASK,
359 PX30_GMAC_PHY_INTF_SEL_RMII);
360}
361
Simon Glassb75b15b2020-12-03 16:55:23 -0700362static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
David Wuadcde492018-01-13 14:05:30 +0800363{
364 struct rk322x_grf *grf;
365 enum {
366 RK3228_RMII_MODE_SHIFT = 10,
367 RK3228_RMII_MODE_MASK = BIT(10),
368
369 RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
370 RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
371 RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
372
373 RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
374 RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
375 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
376
377 RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
378 RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
379 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
380 };
381 enum {
382 RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
383 RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
384
385 RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
386 RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
387 };
388
389 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
390 rk_clrsetreg(&grf->mac_con[1],
391 RK3228_RMII_MODE_MASK |
392 RK3228_GMAC_PHY_INTF_SEL_MASK |
393 RK3228_RXCLK_DLY_ENA_GMAC_MASK |
394 RK3228_TXCLK_DLY_ENA_GMAC_MASK,
395 RK3228_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200396 DELAY_ENABLE(RK3228, pdata->tx_delay, pdata->rx_delay));
David Wuadcde492018-01-13 14:05:30 +0800397
398 rk_clrsetreg(&grf->mac_con[0],
399 RK3228_CLK_RX_DL_CFG_GMAC_MASK |
400 RK3228_CLK_TX_DL_CFG_GMAC_MASK,
401 pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
402 pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
403}
404
Simon Glassb75b15b2020-12-03 16:55:23 -0700405static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
Philipp Tomsich99cac582017-03-24 19:24:26 +0100406{
407 struct rk3288_grf *grf;
408
409 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
410 rk_clrsetreg(&grf->soc_con1,
411 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
412 RK3288_GMAC_PHY_INTF_SEL_RGMII);
413
414 rk_clrsetreg(&grf->soc_con3,
415 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
416 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
417 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
418 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200419 DELAY_ENABLE(RK3288, pdata->rx_delay, pdata->tx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100420 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
421 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
422}
423
Simon Glassb75b15b2020-12-03 16:55:23 -0700424static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
David Wu5d6d51f2019-11-26 09:39:49 +0800425{
426 struct rk3308_grf *grf;
427 enum {
428 RK3308_GMAC_PHY_INTF_SEL_SHIFT = 2,
429 RK3308_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 2),
430 RK3308_GMAC_PHY_INTF_SEL_RMII = BIT(4),
431 };
432
433 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
434
435 rk_clrsetreg(&grf->mac_con0,
436 RK3308_GMAC_PHY_INTF_SEL_MASK,
437 RK3308_GMAC_PHY_INTF_SEL_RMII);
438}
439
Simon Glassb75b15b2020-12-03 16:55:23 -0700440static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
David Wubac972b2018-01-13 14:03:04 +0800441{
442 struct rk3328_grf_regs *grf;
443 enum {
444 RK3328_RMII_MODE_SHIFT = 9,
445 RK3328_RMII_MODE_MASK = BIT(9),
446
447 RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4,
448 RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
449 RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
450
451 RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
452 RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
453 RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
454
455 RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
456 RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
457 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
458 };
459 enum {
460 RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
461 RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
462
463 RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
464 RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
465 };
466
467 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
468 rk_clrsetreg(&grf->mac_con[1],
469 RK3328_RMII_MODE_MASK |
470 RK3328_GMAC_PHY_INTF_SEL_MASK |
471 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
472 RK3328_TXCLK_DLY_ENA_GMAC_MASK,
473 RK3328_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200474 DELAY_ENABLE(RK3328, pdata->tx_delay, pdata->rx_delay));
David Wubac972b2018-01-13 14:03:04 +0800475
476 rk_clrsetreg(&grf->mac_con[0],
477 RK3328_CLK_RX_DL_CFG_GMAC_MASK |
478 RK3328_CLK_TX_DL_CFG_GMAC_MASK,
479 pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
480 pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
481}
482
Simon Glassb75b15b2020-12-03 16:55:23 -0700483static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200484{
485 struct rk3368_grf *grf;
486 enum {
487 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
488 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
489 RK3368_RMII_MODE_MASK = BIT(6),
490 RK3368_RMII_MODE = BIT(6),
491 };
492 enum {
493 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
494 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
495 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
496 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
497 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
498 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
499 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
500 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
501 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
502 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
503 };
504
505 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
506 rk_clrsetreg(&grf->soc_con15,
507 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
508 RK3368_GMAC_PHY_INTF_SEL_RGMII);
509
510 rk_clrsetreg(&grf->soc_con16,
511 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
512 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
513 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
514 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200515 DELAY_ENABLE(RK3368, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200516 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
517 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
518}
519
Simon Glassb75b15b2020-12-03 16:55:23 -0700520static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
Philipp Tomsich99cac582017-03-24 19:24:26 +0100521{
522 struct rk3399_grf_regs *grf;
523
524 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
525
526 rk_clrsetreg(&grf->soc_con5,
527 RK3399_GMAC_PHY_INTF_SEL_MASK,
528 RK3399_GMAC_PHY_INTF_SEL_RGMII);
529
530 rk_clrsetreg(&grf->soc_con6,
531 RK3399_RXCLK_DLY_ENA_GMAC_MASK |
532 RK3399_TXCLK_DLY_ENA_GMAC_MASK |
533 RK3399_CLK_RX_DL_CFG_GMAC_MASK |
534 RK3399_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200535 DELAY_ENABLE(RK3399, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100536 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
537 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
538}
539
Simon Glassb75b15b2020-12-03 16:55:23 -0700540static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
David Wu672e4f22018-01-13 14:01:12 +0800541{
542 struct rv1108_grf *grf;
543
544 enum {
545 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
546 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4,
547 };
548
549 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
550 rk_clrsetreg(&grf->gmac_con0,
551 RV1108_GMAC_PHY_INTF_SEL_MASK,
552 RV1108_GMAC_PHY_INTF_SEL_RMII);
553}
554
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100555static int gmac_rockchip_probe(struct udevice *dev)
556{
Simon Glassb75b15b2020-12-03 16:55:23 -0700557 struct gmac_rockchip_plat *pdata = dev_get_plat(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100558 struct rk_gmac_ops *ops =
559 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Simon Glassfa20e932020-12-03 16:55:20 -0700560 struct dw_eth_pdata *dw_pdata = dev_get_plat(dev);
David Wu672e4f22018-01-13 14:01:12 +0800561 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100562 struct clk clk;
David Wu672e4f22018-01-13 14:01:12 +0800563 ulong rate;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100564 int ret;
565
Sean Anderson08d531c2021-06-11 00:16:07 -0400566 ret = clk_set_defaults(dev, CLK_DEFAULTS_PRE);
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200567 if (ret)
568 debug("%s clk_set_defaults failed %d\n", __func__, ret);
569
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100570 ret = clk_get_by_index(dev, 0, &clk);
571 if (ret)
572 return ret;
573
David Wu672e4f22018-01-13 14:01:12 +0800574 switch (eth_pdata->phy_interface) {
575 case PHY_INTERFACE_MODE_RGMII:
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200576 /* Set to RGMII mode */
577 if (ops->set_to_rgmii)
578 ops->set_to_rgmii(pdata);
579 else
580 return -EPERM;
581
David Wu672e4f22018-01-13 14:01:12 +0800582 /*
583 * If the gmac clock is from internal pll, need to set and
584 * check the return value for gmac clock at RGMII mode. If
585 * the gmac clock is from external source, the clock rate
586 * is not set, because of it is bypassed.
587 */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200588
David Wu672e4f22018-01-13 14:01:12 +0800589 if (!pdata->clock_input) {
590 rate = clk_set_rate(&clk, 125000000);
591 if (rate != 125000000)
592 return -EINVAL;
593 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200594 break;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100595
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200596 case PHY_INTERFACE_MODE_RGMII_ID:
David Wu672e4f22018-01-13 14:01:12 +0800597 /* Set to RGMII mode */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200598 if (ops->set_to_rgmii) {
599 pdata->tx_delay = 0;
600 pdata->rx_delay = 0;
David Wu672e4f22018-01-13 14:01:12 +0800601 ops->set_to_rgmii(pdata);
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200602 } else
David Wu672e4f22018-01-13 14:01:12 +0800603 return -EPERM;
604
David Wu672e4f22018-01-13 14:01:12 +0800605 if (!pdata->clock_input) {
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200606 rate = clk_set_rate(&clk, 125000000);
607 if (rate != 125000000)
David Wu672e4f22018-01-13 14:01:12 +0800608 return -EINVAL;
609 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200610 break;
David Wu672e4f22018-01-13 14:01:12 +0800611
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200612 case PHY_INTERFACE_MODE_RMII:
David Wu672e4f22018-01-13 14:01:12 +0800613 /* Set to RMII mode */
614 if (ops->set_to_rmii)
615 ops->set_to_rmii(pdata);
616 else
617 return -EPERM;
618
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200619 if (!pdata->clock_input) {
620 rate = clk_set_rate(&clk, 50000000);
621 if (rate != 50000000)
622 return -EINVAL;
623 }
624 break;
625
626 case PHY_INTERFACE_MODE_RGMII_RXID:
627 /* Set to RGMII_RXID mode */
628 if (ops->set_to_rgmii) {
629 pdata->tx_delay = 0;
630 ops->set_to_rgmii(pdata);
631 } else
632 return -EPERM;
633
634 if (!pdata->clock_input) {
635 rate = clk_set_rate(&clk, 125000000);
636 if (rate != 125000000)
637 return -EINVAL;
638 }
David Wu672e4f22018-01-13 14:01:12 +0800639 break;
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200640
641 case PHY_INTERFACE_MODE_RGMII_TXID:
642 /* Set to RGMII_TXID mode */
643 if (ops->set_to_rgmii) {
644 pdata->rx_delay = 0;
645 ops->set_to_rgmii(pdata);
646 } else
647 return -EPERM;
648
649 if (!pdata->clock_input) {
650 rate = clk_set_rate(&clk, 125000000);
651 if (rate != 125000000)
652 return -EINVAL;
653 }
654 break;
655
David Wu672e4f22018-01-13 14:01:12 +0800656 default:
657 debug("NO interface defined!\n");
658 return -ENXIO;
659 }
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100660
661 return designware_eth_probe(dev);
662}
663
664static int gmac_rockchip_eth_start(struct udevice *dev)
665{
Simon Glassfa20e932020-12-03 16:55:20 -0700666 struct eth_pdata *pdata = dev_get_plat(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100667 struct dw_eth_dev *priv = dev_get_priv(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100668 struct rk_gmac_ops *ops =
669 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100670 int ret;
671
672 ret = designware_eth_init(priv, pdata->enetaddr);
673 if (ret)
674 return ret;
Philipp Tomsich99cac582017-03-24 19:24:26 +0100675 ret = ops->fix_mac_speed(priv);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100676 if (ret)
677 return ret;
678 ret = designware_eth_enable(priv);
679 if (ret)
680 return ret;
681
682 return 0;
683}
684
685const struct eth_ops gmac_rockchip_eth_ops = {
686 .start = gmac_rockchip_eth_start,
687 .send = designware_eth_send,
688 .recv = designware_eth_recv,
689 .free_pkt = designware_eth_free_pkt,
690 .stop = designware_eth_stop,
691 .write_hwaddr = designware_eth_write_hwaddr,
692};
693
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200694const struct rk_gmac_ops px30_gmac_ops = {
695 .fix_mac_speed = px30_gmac_fix_mac_speed,
696 .set_to_rmii = px30_gmac_set_to_rmii,
697};
698
David Wuadcde492018-01-13 14:05:30 +0800699const struct rk_gmac_ops rk3228_gmac_ops = {
700 .fix_mac_speed = rk3228_gmac_fix_mac_speed,
701 .set_to_rgmii = rk3228_gmac_set_to_rgmii,
702};
703
Philipp Tomsich99cac582017-03-24 19:24:26 +0100704const struct rk_gmac_ops rk3288_gmac_ops = {
705 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
706 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
707};
708
David Wu5d6d51f2019-11-26 09:39:49 +0800709const struct rk_gmac_ops rk3308_gmac_ops = {
710 .fix_mac_speed = rk3308_gmac_fix_mac_speed,
711 .set_to_rmii = rk3308_gmac_set_to_rmii,
712};
713
David Wubac972b2018-01-13 14:03:04 +0800714const struct rk_gmac_ops rk3328_gmac_ops = {
715 .fix_mac_speed = rk3328_gmac_fix_mac_speed,
716 .set_to_rgmii = rk3328_gmac_set_to_rgmii,
717};
718
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200719const struct rk_gmac_ops rk3368_gmac_ops = {
720 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
721 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
722};
723
Philipp Tomsich99cac582017-03-24 19:24:26 +0100724const struct rk_gmac_ops rk3399_gmac_ops = {
725 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
726 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
727};
728
David Wu672e4f22018-01-13 14:01:12 +0800729const struct rk_gmac_ops rv1108_gmac_ops = {
730 .fix_mac_speed = rv1108_set_rmii_speed,
731 .set_to_rmii = rv1108_gmac_set_to_rmii,
732};
733
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100734static const struct udevice_id rockchip_gmac_ids[] = {
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200735 { .compatible = "rockchip,px30-gmac",
736 .data = (ulong)&px30_gmac_ops },
David Wuadcde492018-01-13 14:05:30 +0800737 { .compatible = "rockchip,rk3228-gmac",
738 .data = (ulong)&rk3228_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100739 { .compatible = "rockchip,rk3288-gmac",
740 .data = (ulong)&rk3288_gmac_ops },
Jonas Karlmanc8c20092024-04-08 18:14:07 +0000741 { .compatible = "rockchip,rk3308-gmac",
David Wu5d6d51f2019-11-26 09:39:49 +0800742 .data = (ulong)&rk3308_gmac_ops },
David Wubac972b2018-01-13 14:03:04 +0800743 { .compatible = "rockchip,rk3328-gmac",
744 .data = (ulong)&rk3328_gmac_ops },
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200745 { .compatible = "rockchip,rk3368-gmac",
746 .data = (ulong)&rk3368_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100747 { .compatible = "rockchip,rk3399-gmac",
748 .data = (ulong)&rk3399_gmac_ops },
David Wu672e4f22018-01-13 14:01:12 +0800749 { .compatible = "rockchip,rv1108-gmac",
750 .data = (ulong)&rv1108_gmac_ops },
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100751 { }
752};
753
754U_BOOT_DRIVER(eth_gmac_rockchip) = {
755 .name = "gmac_rockchip",
756 .id = UCLASS_ETH,
757 .of_match = rockchip_gmac_ids,
Simon Glassaad29ae2020-12-03 16:55:21 -0700758 .of_to_plat = gmac_rockchip_of_to_plat,
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100759 .probe = gmac_rockchip_probe,
760 .ops = &gmac_rockchip_eth_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700761 .priv_auto = sizeof(struct dw_eth_dev),
Simon Glassb75b15b2020-12-03 16:55:23 -0700762 .plat_auto = sizeof(struct gmac_rockchip_plat),
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100763 .flags = DM_FLAG_ALLOC_PRIV_DMA,
764};