blob: 8cfeeffe95b93f19aac5d2e81cf60abb67da9be9 [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{
154 struct rk3288_grf *grf;
155 int clk;
156
157 switch (priv->phydev->speed) {
158 case 10:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100159 clk = RK3288_GMAC_CLK_SEL_2_5M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100160 break;
161 case 100:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100162 clk = RK3288_GMAC_CLK_SEL_25M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100163 break;
164 case 1000:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100165 clk = RK3288_GMAC_CLK_SEL_125M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100166 break;
167 default:
168 debug("Unknown phy speed: %d\n", priv->phydev->speed);
169 return -EINVAL;
170 }
171
172 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100173 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
174
175 return 0;
176}
177
David Wu5d6d51f2019-11-26 09:39:49 +0800178static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv)
179{
180 struct rk3308_grf *grf;
181 struct clk clk_speed;
182 int speed, ret;
183 enum {
184 RK3308_GMAC_SPEED_SHIFT = 0x0,
185 RK3308_GMAC_SPEED_MASK = BIT(0),
186 RK3308_GMAC_SPEED_10M = 0,
187 RK3308_GMAC_SPEED_100M = BIT(0),
188 };
189
190 ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
191 &clk_speed);
192 if (ret)
193 return ret;
194
195 switch (priv->phydev->speed) {
196 case 10:
197 speed = RK3308_GMAC_SPEED_10M;
198 ret = clk_set_rate(&clk_speed, 2500000);
199 if (ret)
200 return ret;
201 break;
202 case 100:
203 speed = RK3308_GMAC_SPEED_100M;
204 ret = clk_set_rate(&clk_speed, 25000000);
205 if (ret)
206 return ret;
207 break;
208 default:
209 debug("Unknown phy speed: %d\n", priv->phydev->speed);
210 return -EINVAL;
211 }
212
213 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
214 rk_clrsetreg(&grf->mac_con0, RK3308_GMAC_SPEED_MASK, speed);
215
216 return 0;
217}
218
David Wubac972b2018-01-13 14:03:04 +0800219static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
220{
221 struct rk3328_grf_regs *grf;
222 int clk;
223 enum {
224 RK3328_GMAC_CLK_SEL_SHIFT = 11,
225 RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11),
226 RK3328_GMAC_CLK_SEL_125M = 0 << 11,
227 RK3328_GMAC_CLK_SEL_25M = 3 << 11,
228 RK3328_GMAC_CLK_SEL_2_5M = 2 << 11,
229 };
230
231 switch (priv->phydev->speed) {
232 case 10:
233 clk = RK3328_GMAC_CLK_SEL_2_5M;
234 break;
235 case 100:
236 clk = RK3328_GMAC_CLK_SEL_25M;
237 break;
238 case 1000:
239 clk = RK3328_GMAC_CLK_SEL_125M;
240 break;
241 default:
242 debug("Unknown phy speed: %d\n", priv->phydev->speed);
243 return -EINVAL;
244 }
245
246 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
247 rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
248
249 return 0;
250}
251
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200252static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
253{
254 struct rk3368_grf *grf;
255 int clk;
256 enum {
257 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
258 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
259 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
260 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
261 };
262
263 switch (priv->phydev->speed) {
264 case 10:
265 clk = RK3368_GMAC_CLK_SEL_2_5M;
266 break;
267 case 100:
268 clk = RK3368_GMAC_CLK_SEL_25M;
269 break;
270 case 1000:
271 clk = RK3368_GMAC_CLK_SEL_125M;
272 break;
273 default:
274 debug("Unknown phy speed: %d\n", priv->phydev->speed);
275 return -EINVAL;
276 }
277
278 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
279 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
280
281 return 0;
282}
283
Philipp Tomsich99cac582017-03-24 19:24:26 +0100284static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
285{
286 struct rk3399_grf_regs *grf;
287 int clk;
288
289 switch (priv->phydev->speed) {
290 case 10:
291 clk = RK3399_GMAC_CLK_SEL_2_5M;
292 break;
293 case 100:
294 clk = RK3399_GMAC_CLK_SEL_25M;
295 break;
296 case 1000:
297 clk = RK3399_GMAC_CLK_SEL_125M;
298 break;
299 default:
300 debug("Unknown phy speed: %d\n", priv->phydev->speed);
301 return -EINVAL;
302 }
303
304 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
305 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100306
307 return 0;
308}
309
David Wu672e4f22018-01-13 14:01:12 +0800310static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
311{
312 struct rv1108_grf *grf;
313 int clk, speed;
314 enum {
315 RV1108_GMAC_SPEED_MASK = BIT(2),
316 RV1108_GMAC_SPEED_10M = 0 << 2,
317 RV1108_GMAC_SPEED_100M = 1 << 2,
318 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
319 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
320 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
321 };
322
323 switch (priv->phydev->speed) {
324 case 10:
325 clk = RV1108_GMAC_CLK_SEL_2_5M;
326 speed = RV1108_GMAC_SPEED_10M;
327 break;
328 case 100:
329 clk = RV1108_GMAC_CLK_SEL_25M;
330 speed = RV1108_GMAC_SPEED_100M;
331 break;
332 default:
333 debug("Unknown phy speed: %d\n", priv->phydev->speed);
334 return -EINVAL;
335 }
336
337 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
338 rk_clrsetreg(&grf->gmac_con0,
339 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
340 clk | speed);
341
342 return 0;
343}
344
Simon Glassb75b15b2020-12-03 16:55:23 -0700345static void px30_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200346{
347 struct px30_grf *grf;
348 enum {
349 PX30_GMAC_PHY_INTF_SEL_SHIFT = 4,
350 PX30_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 6),
351 PX30_GMAC_PHY_INTF_SEL_RMII = BIT(6),
352 };
353
354 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
355
356 rk_clrsetreg(&grf->mac_con1,
357 PX30_GMAC_PHY_INTF_SEL_MASK,
358 PX30_GMAC_PHY_INTF_SEL_RMII);
359}
360
Simon Glassb75b15b2020-12-03 16:55:23 -0700361static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
David Wuadcde492018-01-13 14:05:30 +0800362{
363 struct rk322x_grf *grf;
364 enum {
365 RK3228_RMII_MODE_SHIFT = 10,
366 RK3228_RMII_MODE_MASK = BIT(10),
367
368 RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
369 RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
370 RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
371
372 RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
373 RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
374 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
375
376 RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
377 RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
378 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
379 };
380 enum {
381 RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
382 RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
383
384 RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
385 RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
386 };
387
388 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
389 rk_clrsetreg(&grf->mac_con[1],
390 RK3228_RMII_MODE_MASK |
391 RK3228_GMAC_PHY_INTF_SEL_MASK |
392 RK3228_RXCLK_DLY_ENA_GMAC_MASK |
393 RK3228_TXCLK_DLY_ENA_GMAC_MASK,
394 RK3228_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200395 DELAY_ENABLE(RK3228, pdata->tx_delay, pdata->rx_delay));
David Wuadcde492018-01-13 14:05:30 +0800396
397 rk_clrsetreg(&grf->mac_con[0],
398 RK3228_CLK_RX_DL_CFG_GMAC_MASK |
399 RK3228_CLK_TX_DL_CFG_GMAC_MASK,
400 pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
401 pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
402}
403
Simon Glassb75b15b2020-12-03 16:55:23 -0700404static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
Philipp Tomsich99cac582017-03-24 19:24:26 +0100405{
406 struct rk3288_grf *grf;
407
408 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
409 rk_clrsetreg(&grf->soc_con1,
410 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
411 RK3288_GMAC_PHY_INTF_SEL_RGMII);
412
413 rk_clrsetreg(&grf->soc_con3,
414 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
415 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
416 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
417 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200418 DELAY_ENABLE(RK3288, pdata->rx_delay, pdata->tx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100419 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
420 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
421}
422
Simon Glassb75b15b2020-12-03 16:55:23 -0700423static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
David Wu5d6d51f2019-11-26 09:39:49 +0800424{
425 struct rk3308_grf *grf;
426 enum {
427 RK3308_GMAC_PHY_INTF_SEL_SHIFT = 2,
428 RK3308_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 2),
429 RK3308_GMAC_PHY_INTF_SEL_RMII = BIT(4),
430 };
431
432 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
433
434 rk_clrsetreg(&grf->mac_con0,
435 RK3308_GMAC_PHY_INTF_SEL_MASK,
436 RK3308_GMAC_PHY_INTF_SEL_RMII);
437}
438
Simon Glassb75b15b2020-12-03 16:55:23 -0700439static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
David Wubac972b2018-01-13 14:03:04 +0800440{
441 struct rk3328_grf_regs *grf;
442 enum {
443 RK3328_RMII_MODE_SHIFT = 9,
444 RK3328_RMII_MODE_MASK = BIT(9),
445
446 RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4,
447 RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
448 RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
449
450 RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
451 RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
452 RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
453
454 RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
455 RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
456 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
457 };
458 enum {
459 RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
460 RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
461
462 RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
463 RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
464 };
465
466 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
467 rk_clrsetreg(&grf->mac_con[1],
468 RK3328_RMII_MODE_MASK |
469 RK3328_GMAC_PHY_INTF_SEL_MASK |
470 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
471 RK3328_TXCLK_DLY_ENA_GMAC_MASK,
472 RK3328_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200473 DELAY_ENABLE(RK3328, pdata->tx_delay, pdata->rx_delay));
David Wubac972b2018-01-13 14:03:04 +0800474
475 rk_clrsetreg(&grf->mac_con[0],
476 RK3328_CLK_RX_DL_CFG_GMAC_MASK |
477 RK3328_CLK_TX_DL_CFG_GMAC_MASK,
478 pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
479 pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
480}
481
Simon Glassb75b15b2020-12-03 16:55:23 -0700482static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200483{
484 struct rk3368_grf *grf;
485 enum {
486 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
487 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
488 RK3368_RMII_MODE_MASK = BIT(6),
489 RK3368_RMII_MODE = BIT(6),
490 };
491 enum {
492 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
493 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
494 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
495 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
496 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
497 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
498 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
499 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
500 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
501 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
502 };
503
504 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
505 rk_clrsetreg(&grf->soc_con15,
506 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
507 RK3368_GMAC_PHY_INTF_SEL_RGMII);
508
509 rk_clrsetreg(&grf->soc_con16,
510 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
511 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
512 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
513 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200514 DELAY_ENABLE(RK3368, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200515 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
516 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
517}
518
Simon Glassb75b15b2020-12-03 16:55:23 -0700519static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata)
Philipp Tomsich99cac582017-03-24 19:24:26 +0100520{
521 struct rk3399_grf_regs *grf;
522
523 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
524
525 rk_clrsetreg(&grf->soc_con5,
526 RK3399_GMAC_PHY_INTF_SEL_MASK,
527 RK3399_GMAC_PHY_INTF_SEL_RGMII);
528
529 rk_clrsetreg(&grf->soc_con6,
530 RK3399_RXCLK_DLY_ENA_GMAC_MASK |
531 RK3399_TXCLK_DLY_ENA_GMAC_MASK |
532 RK3399_CLK_RX_DL_CFG_GMAC_MASK |
533 RK3399_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200534 DELAY_ENABLE(RK3399, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100535 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
536 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
537}
538
Simon Glassb75b15b2020-12-03 16:55:23 -0700539static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata)
David Wu672e4f22018-01-13 14:01:12 +0800540{
541 struct rv1108_grf *grf;
542
543 enum {
544 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
545 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4,
546 };
547
548 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
549 rk_clrsetreg(&grf->gmac_con0,
550 RV1108_GMAC_PHY_INTF_SEL_MASK,
551 RV1108_GMAC_PHY_INTF_SEL_RMII);
552}
553
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100554static int gmac_rockchip_probe(struct udevice *dev)
555{
Simon Glassb75b15b2020-12-03 16:55:23 -0700556 struct gmac_rockchip_plat *pdata = dev_get_plat(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100557 struct rk_gmac_ops *ops =
558 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Simon Glassfa20e932020-12-03 16:55:20 -0700559 struct dw_eth_pdata *dw_pdata = dev_get_plat(dev);
David Wu672e4f22018-01-13 14:01:12 +0800560 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100561 struct clk clk;
David Wu672e4f22018-01-13 14:01:12 +0800562 ulong rate;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100563 int ret;
564
Sean Anderson08d531c2021-06-11 00:16:07 -0400565 ret = clk_set_defaults(dev, CLK_DEFAULTS_PRE);
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200566 if (ret)
567 debug("%s clk_set_defaults failed %d\n", __func__, ret);
568
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100569 ret = clk_get_by_index(dev, 0, &clk);
570 if (ret)
571 return ret;
572
David Wu672e4f22018-01-13 14:01:12 +0800573 switch (eth_pdata->phy_interface) {
574 case PHY_INTERFACE_MODE_RGMII:
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200575 /* Set to RGMII mode */
576 if (ops->set_to_rgmii)
577 ops->set_to_rgmii(pdata);
578 else
579 return -EPERM;
580
David Wu672e4f22018-01-13 14:01:12 +0800581 /*
582 * If the gmac clock is from internal pll, need to set and
583 * check the return value for gmac clock at RGMII mode. If
584 * the gmac clock is from external source, the clock rate
585 * is not set, because of it is bypassed.
586 */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200587
David Wu672e4f22018-01-13 14:01:12 +0800588 if (!pdata->clock_input) {
589 rate = clk_set_rate(&clk, 125000000);
590 if (rate != 125000000)
591 return -EINVAL;
592 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200593 break;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100594
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200595 case PHY_INTERFACE_MODE_RGMII_ID:
David Wu672e4f22018-01-13 14:01:12 +0800596 /* Set to RGMII mode */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200597 if (ops->set_to_rgmii) {
598 pdata->tx_delay = 0;
599 pdata->rx_delay = 0;
David Wu672e4f22018-01-13 14:01:12 +0800600 ops->set_to_rgmii(pdata);
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200601 } else
David Wu672e4f22018-01-13 14:01:12 +0800602 return -EPERM;
603
David Wu672e4f22018-01-13 14:01:12 +0800604 if (!pdata->clock_input) {
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200605 rate = clk_set_rate(&clk, 125000000);
606 if (rate != 125000000)
David Wu672e4f22018-01-13 14:01:12 +0800607 return -EINVAL;
608 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200609 break;
David Wu672e4f22018-01-13 14:01:12 +0800610
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200611 case PHY_INTERFACE_MODE_RMII:
David Wu672e4f22018-01-13 14:01:12 +0800612 /* Set to RMII mode */
613 if (ops->set_to_rmii)
614 ops->set_to_rmii(pdata);
615 else
616 return -EPERM;
617
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200618 if (!pdata->clock_input) {
619 rate = clk_set_rate(&clk, 50000000);
620 if (rate != 50000000)
621 return -EINVAL;
622 }
623 break;
624
625 case PHY_INTERFACE_MODE_RGMII_RXID:
626 /* Set to RGMII_RXID mode */
627 if (ops->set_to_rgmii) {
628 pdata->tx_delay = 0;
629 ops->set_to_rgmii(pdata);
630 } else
631 return -EPERM;
632
633 if (!pdata->clock_input) {
634 rate = clk_set_rate(&clk, 125000000);
635 if (rate != 125000000)
636 return -EINVAL;
637 }
David Wu672e4f22018-01-13 14:01:12 +0800638 break;
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200639
640 case PHY_INTERFACE_MODE_RGMII_TXID:
641 /* Set to RGMII_TXID mode */
642 if (ops->set_to_rgmii) {
643 pdata->rx_delay = 0;
644 ops->set_to_rgmii(pdata);
645 } else
646 return -EPERM;
647
648 if (!pdata->clock_input) {
649 rate = clk_set_rate(&clk, 125000000);
650 if (rate != 125000000)
651 return -EINVAL;
652 }
653 break;
654
David Wu672e4f22018-01-13 14:01:12 +0800655 default:
656 debug("NO interface defined!\n");
657 return -ENXIO;
658 }
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100659
660 return designware_eth_probe(dev);
661}
662
663static int gmac_rockchip_eth_start(struct udevice *dev)
664{
Simon Glassfa20e932020-12-03 16:55:20 -0700665 struct eth_pdata *pdata = dev_get_plat(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100666 struct dw_eth_dev *priv = dev_get_priv(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100667 struct rk_gmac_ops *ops =
668 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100669 int ret;
670
671 ret = designware_eth_init(priv, pdata->enetaddr);
672 if (ret)
673 return ret;
Philipp Tomsich99cac582017-03-24 19:24:26 +0100674 ret = ops->fix_mac_speed(priv);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100675 if (ret)
676 return ret;
677 ret = designware_eth_enable(priv);
678 if (ret)
679 return ret;
680
681 return 0;
682}
683
684const struct eth_ops gmac_rockchip_eth_ops = {
685 .start = gmac_rockchip_eth_start,
686 .send = designware_eth_send,
687 .recv = designware_eth_recv,
688 .free_pkt = designware_eth_free_pkt,
689 .stop = designware_eth_stop,
690 .write_hwaddr = designware_eth_write_hwaddr,
691};
692
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200693const struct rk_gmac_ops px30_gmac_ops = {
694 .fix_mac_speed = px30_gmac_fix_mac_speed,
695 .set_to_rmii = px30_gmac_set_to_rmii,
696};
697
David Wuadcde492018-01-13 14:05:30 +0800698const struct rk_gmac_ops rk3228_gmac_ops = {
699 .fix_mac_speed = rk3228_gmac_fix_mac_speed,
700 .set_to_rgmii = rk3228_gmac_set_to_rgmii,
701};
702
Philipp Tomsich99cac582017-03-24 19:24:26 +0100703const struct rk_gmac_ops rk3288_gmac_ops = {
704 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
705 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
706};
707
David Wu5d6d51f2019-11-26 09:39:49 +0800708const struct rk_gmac_ops rk3308_gmac_ops = {
709 .fix_mac_speed = rk3308_gmac_fix_mac_speed,
710 .set_to_rmii = rk3308_gmac_set_to_rmii,
711};
712
David Wubac972b2018-01-13 14:03:04 +0800713const struct rk_gmac_ops rk3328_gmac_ops = {
714 .fix_mac_speed = rk3328_gmac_fix_mac_speed,
715 .set_to_rgmii = rk3328_gmac_set_to_rgmii,
716};
717
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200718const struct rk_gmac_ops rk3368_gmac_ops = {
719 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
720 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
721};
722
Philipp Tomsich99cac582017-03-24 19:24:26 +0100723const struct rk_gmac_ops rk3399_gmac_ops = {
724 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
725 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
726};
727
David Wu672e4f22018-01-13 14:01:12 +0800728const struct rk_gmac_ops rv1108_gmac_ops = {
729 .fix_mac_speed = rv1108_set_rmii_speed,
730 .set_to_rmii = rv1108_gmac_set_to_rmii,
731};
732
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100733static const struct udevice_id rockchip_gmac_ids[] = {
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200734 { .compatible = "rockchip,px30-gmac",
735 .data = (ulong)&px30_gmac_ops },
David Wuadcde492018-01-13 14:05:30 +0800736 { .compatible = "rockchip,rk3228-gmac",
737 .data = (ulong)&rk3228_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100738 { .compatible = "rockchip,rk3288-gmac",
739 .data = (ulong)&rk3288_gmac_ops },
Jonas Karlmanc8c20092024-04-08 18:14:07 +0000740 { .compatible = "rockchip,rk3308-gmac",
David Wu5d6d51f2019-11-26 09:39:49 +0800741 .data = (ulong)&rk3308_gmac_ops },
David Wubac972b2018-01-13 14:03:04 +0800742 { .compatible = "rockchip,rk3328-gmac",
743 .data = (ulong)&rk3328_gmac_ops },
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200744 { .compatible = "rockchip,rk3368-gmac",
745 .data = (ulong)&rk3368_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100746 { .compatible = "rockchip,rk3399-gmac",
747 .data = (ulong)&rk3399_gmac_ops },
David Wu672e4f22018-01-13 14:01:12 +0800748 { .compatible = "rockchip,rv1108-gmac",
749 .data = (ulong)&rv1108_gmac_ops },
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100750 { }
751};
752
753U_BOOT_DRIVER(eth_gmac_rockchip) = {
754 .name = "gmac_rockchip",
755 .id = UCLASS_ETH,
756 .of_match = rockchip_gmac_ids,
Simon Glassaad29ae2020-12-03 16:55:21 -0700757 .of_to_plat = gmac_rockchip_of_to_plat,
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100758 .probe = gmac_rockchip_probe,
759 .ops = &gmac_rockchip_eth_ops,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700760 .priv_auto = sizeof(struct dw_eth_dev),
Simon Glassb75b15b2020-12-03 16:55:23 -0700761 .plat_auto = sizeof(struct gmac_rockchip_plat),
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100762 .flags = DM_FLAG_ALLOC_PRIV_DMA,
763};