blob: d646d3ebac8721774b6b3aa28b70534674d19bc4 [file] [log] [blame]
Jonas Karlman098ee4f2023-10-01 19:17:19 +00001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright Contributors to the U-Boot project.
4 *
5 * rk_gmac_ops ported from linux drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
6 *
7 * Ported code is intentionally left as close as possible with linux counter
8 * part in order to simplify future porting of fixes and support for other SoCs.
9 */
10
Jonas Karlman098ee4f2023-10-01 19:17:19 +000011#include <clk.h>
12#include <dm.h>
13#include <dm/device_compat.h>
14#include <net.h>
15#include <phy.h>
16#include <regmap.h>
17#include <reset.h>
18#include <syscon.h>
19#include <asm/gpio.h>
20#include <linux/delay.h>
21
22#include "dwc_eth_qos.h"
23
24struct rk_gmac_ops {
25 const char *compatible;
26 int (*set_to_rgmii)(struct udevice *dev,
27 int tx_delay, int rx_delay);
28 int (*set_to_rmii)(struct udevice *dev);
29 int (*set_gmac_speed)(struct udevice *dev);
Jonas Karlman1b615702023-10-01 19:17:20 +000030 void (*set_clock_selection)(struct udevice *dev, bool enable);
Jonas Karlman098ee4f2023-10-01 19:17:19 +000031 u32 regs[3];
32};
33
34struct rockchip_platform_data {
35 struct reset_ctl_bulk resets;
36 const struct rk_gmac_ops *ops;
37 int id;
Jonas Karlman1b615702023-10-01 19:17:20 +000038 bool clock_input;
Jonas Karlman098ee4f2023-10-01 19:17:19 +000039 struct regmap *grf;
Jonas Karlman1b615702023-10-01 19:17:20 +000040 struct regmap *php_grf;
Jonas Karlman098ee4f2023-10-01 19:17:19 +000041};
42
43#define HIWORD_UPDATE(val, mask, shift) \
44 ((val) << (shift) | (mask) << ((shift) + 16))
45
46#define GRF_BIT(nr) (BIT(nr) | BIT((nr) + 16))
47#define GRF_CLR_BIT(nr) (BIT((nr) + 16))
48
Jonas Karlmane92bd1f2025-02-09 23:27:55 +000049#define DELAY_ENABLE(soc, tx, rx) \
50 (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
51 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
52
Jonas Karlmanee8fcc02025-04-07 22:47:01 +000053#define RK3528_VO_GRF_GMAC_CON 0x0018
54#define RK3528_VPU_GRF_GMAC_CON5 0x0018
55#define RK3528_VPU_GRF_GMAC_CON6 0x001c
56
57#define RK3528_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
58#define RK3528_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
59#define RK3528_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14)
60#define RK3528_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14)
61
62#define RK3528_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8)
63#define RK3528_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0)
64
65#define RK3528_GMAC0_PHY_INTF_SEL_RMII GRF_BIT(1)
66#define RK3528_GMAC1_PHY_INTF_SEL_RGMII GRF_CLR_BIT(8)
67#define RK3528_GMAC1_PHY_INTF_SEL_RMII GRF_BIT(8)
68
69#define RK3528_GMAC1_CLK_SELECT_CRU GRF_CLR_BIT(12)
70#define RK3528_GMAC1_CLK_SELECT_IO GRF_BIT(12)
71
72#define RK3528_GMAC0_CLK_RMII_DIV2 GRF_BIT(3)
73#define RK3528_GMAC0_CLK_RMII_DIV20 GRF_CLR_BIT(3)
74#define RK3528_GMAC1_CLK_RMII_DIV2 GRF_BIT(10)
75#define RK3528_GMAC1_CLK_RMII_DIV20 GRF_CLR_BIT(10)
76
77#define RK3528_GMAC1_CLK_RGMII_DIV1 (GRF_CLR_BIT(11) | GRF_CLR_BIT(10))
78#define RK3528_GMAC1_CLK_RGMII_DIV5 (GRF_BIT(11) | GRF_BIT(10))
79#define RK3528_GMAC1_CLK_RGMII_DIV50 (GRF_BIT(11) | GRF_CLR_BIT(10))
80
81#define RK3528_GMAC0_CLK_RMII_GATE GRF_BIT(2)
82#define RK3528_GMAC0_CLK_RMII_NOGATE GRF_CLR_BIT(2)
83#define RK3528_GMAC1_CLK_RMII_GATE GRF_BIT(9)
84#define RK3528_GMAC1_CLK_RMII_NOGATE GRF_CLR_BIT(9)
85
86static int rk3528_set_to_rgmii(struct udevice *dev,
87 int tx_delay, int rx_delay)
88{
89 struct eth_pdata *pdata = dev_get_plat(dev);
90 struct rockchip_platform_data *data = pdata->priv_pdata;
91
92 regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON5,
93 RK3528_GMAC1_PHY_INTF_SEL_RGMII);
94
95 regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON5,
96 DELAY_ENABLE(RK3528, tx_delay, rx_delay));
97
98 regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON6,
99 RK3528_GMAC_CLK_RX_DL_CFG(rx_delay) |
100 RK3528_GMAC_CLK_TX_DL_CFG(tx_delay));
101
102 return 0;
103}
104
105static int rk3528_set_to_rmii(struct udevice *dev)
106{
107 struct eth_pdata *pdata = dev_get_plat(dev);
108 struct rockchip_platform_data *data = pdata->priv_pdata;
109
110 if (data->id == 1)
111 regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON5,
112 RK3528_GMAC1_PHY_INTF_SEL_RMII);
113 else
114 regmap_write(data->grf, RK3528_VO_GRF_GMAC_CON,
115 RK3528_GMAC0_PHY_INTF_SEL_RMII |
116 RK3528_GMAC0_CLK_RMII_DIV2);
117
118 return 0;
119}
120
121static int rk3528_set_gmac_speed(struct udevice *dev)
122{
123 struct eqos_priv *eqos = dev_get_priv(dev);
124 struct eth_pdata *pdata = dev_get_plat(dev);
125 struct rockchip_platform_data *data = pdata->priv_pdata;
126 u32 val, reg;
127
128 switch (eqos->phy->speed) {
129 case SPEED_10:
130 if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
131 val = data->id == 1 ? RK3528_GMAC1_CLK_RMII_DIV20 :
132 RK3528_GMAC0_CLK_RMII_DIV20;
133 else
134 val = RK3528_GMAC1_CLK_RGMII_DIV50;
135 break;
136 case SPEED_100:
137 if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
138 val = data->id == 1 ? RK3528_GMAC1_CLK_RMII_DIV2 :
139 RK3528_GMAC0_CLK_RMII_DIV2;
140 else
141 val = RK3528_GMAC1_CLK_RGMII_DIV5;
142 break;
143 case SPEED_1000:
144 if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII)
145 val = RK3528_GMAC1_CLK_RGMII_DIV1;
146 else
147 return -EINVAL;
148 break;
149 default:
150 return -EINVAL;
151 }
152
153 reg = data->id == 1 ? RK3528_VPU_GRF_GMAC_CON5 :
154 RK3528_VO_GRF_GMAC_CON;
155 regmap_write(data->grf, reg, val);
156
157 return 0;
158}
159
160static void rk3528_set_clock_selection(struct udevice *dev, bool enable)
161{
162 struct eth_pdata *pdata = dev_get_plat(dev);
163 struct rockchip_platform_data *data = pdata->priv_pdata;
164 u32 val;
165
166 if (data->id == 1) {
167 val = data->clock_input ? RK3528_GMAC1_CLK_SELECT_IO :
168 RK3528_GMAC1_CLK_SELECT_CRU;
169 val |= enable ? RK3528_GMAC1_CLK_RMII_NOGATE :
170 RK3528_GMAC1_CLK_RMII_GATE;
171 regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON5, val);
172 } else {
173 val = enable ? RK3528_GMAC0_CLK_RMII_NOGATE :
174 RK3528_GMAC0_CLK_RMII_GATE;
175 regmap_write(data->grf, RK3528_VO_GRF_GMAC_CON, val);
176 }
177}
178
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000179#define RK3568_GRF_GMAC0_CON0 0x0380
180#define RK3568_GRF_GMAC0_CON1 0x0384
181#define RK3568_GRF_GMAC1_CON0 0x0388
182#define RK3568_GRF_GMAC1_CON1 0x038c
183
184/* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
185#define RK3568_GMAC_PHY_INTF_SEL_RGMII \
186 (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
187#define RK3568_GMAC_PHY_INTF_SEL_RMII \
188 (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
189#define RK3568_GMAC_FLOW_CTRL GRF_BIT(3)
190#define RK3568_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3)
191#define RK3568_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1)
192#define RK3568_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1)
193#define RK3568_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0)
194#define RK3568_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0)
195
196/* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
197#define RK3568_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
198#define RK3568_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
199
200static int rk3568_set_to_rgmii(struct udevice *dev,
201 int tx_delay, int rx_delay)
202{
203 struct eth_pdata *pdata = dev_get_plat(dev);
204 struct rockchip_platform_data *data = pdata->priv_pdata;
205 u32 con0, con1;
206
207 con0 = (data->id == 1) ? RK3568_GRF_GMAC1_CON0 :
208 RK3568_GRF_GMAC0_CON0;
209 con1 = (data->id == 1) ? RK3568_GRF_GMAC1_CON1 :
210 RK3568_GRF_GMAC0_CON1;
211
212 regmap_write(data->grf, con0,
213 RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) |
214 RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
215
216 regmap_write(data->grf, con1,
217 RK3568_GMAC_PHY_INTF_SEL_RGMII |
Jonas Karlmane92bd1f2025-02-09 23:27:55 +0000218 DELAY_ENABLE(RK3568, tx_delay, rx_delay));
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000219
220 return 0;
221}
222
223static int rk3568_set_to_rmii(struct udevice *dev)
224{
225 struct eth_pdata *pdata = dev_get_plat(dev);
226 struct rockchip_platform_data *data = pdata->priv_pdata;
227 u32 con1;
228
229 con1 = (data->id == 1) ? RK3568_GRF_GMAC1_CON1 :
230 RK3568_GRF_GMAC0_CON1;
231 regmap_write(data->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
232
233 return 0;
234}
235
236static int rk3568_set_gmac_speed(struct udevice *dev)
237{
238 struct eqos_priv *eqos = dev_get_priv(dev);
239 ulong rate;
240 int ret;
241
242 switch (eqos->phy->speed) {
243 case SPEED_10:
244 rate = 2500000;
245 break;
246 case SPEED_100:
247 rate = 25000000;
248 break;
249 case SPEED_1000:
250 rate = 125000000;
251 break;
252 default:
253 return -EINVAL;
254 }
255
256 ret = clk_set_rate(&eqos->clk_tx, rate);
257 if (ret < 0)
258 return ret;
259
260 return 0;
261}
262
Heiko Stuebner6ed69fe2025-04-15 23:51:24 +0200263/* VCCIO0_1_3_IOC */
264#define RK3576_VCCIO0_1_3_IOC_CON2 0x6408
265#define RK3576_VCCIO0_1_3_IOC_CON3 0x640c
266#define RK3576_VCCIO0_1_3_IOC_CON4 0x6410
267#define RK3576_VCCIO0_1_3_IOC_CON5 0x6414
268
269#define RK3576_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
270#define RK3576_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
271#define RK3576_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7)
272#define RK3576_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7)
273
274#define RK3576_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
275#define RK3576_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
276
277/* SDGMAC_GRF */
278#define RK3576_GRF_GMAC_CON0 0x0020
279#define RK3576_GRF_GMAC_CON1 0x0024
280
281#define RK3576_GMAC_RMII_MODE GRF_BIT(3)
282#define RK3576_GMAC_RGMII_MODE GRF_CLR_BIT(3)
283
284#define RK3576_GMAC_CLK_SELECT_IO GRF_BIT(7)
285#define RK3576_GMAC_CLK_SELECT_CRU GRF_CLR_BIT(7)
286
287#define RK3576_GMAC_CLK_RMII_DIV2 GRF_BIT(5)
288#define RK3576_GMAC_CLK_RMII_DIV20 GRF_CLR_BIT(5)
289
290#define RK3576_GMAC_CLK_RGMII_DIV1 \
291 (GRF_CLR_BIT(6) | GRF_CLR_BIT(5))
292#define RK3576_GMAC_CLK_RGMII_DIV5 \
293 (GRF_BIT(6) | GRF_BIT(5))
294#define RK3576_GMAC_CLK_RGMII_DIV50 \
295 (GRF_BIT(6) | GRF_CLR_BIT(5))
296
297#define RK3576_GMAC_CLK_RMII_GATE GRF_BIT(4)
298#define RK3576_GMAC_CLK_RMII_NOGATE GRF_CLR_BIT(4)
299
300static int rk3576_set_to_rgmii(struct udevice *dev,
301 int tx_delay, int rx_delay)
302{
303 struct eth_pdata *pdata = dev_get_plat(dev);
304 struct rockchip_platform_data *data = pdata->priv_pdata;
305 u32 offset_con;
306
307 offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 :
308 RK3576_GRF_GMAC_CON0;
309
310 regmap_write(data->grf, offset_con, RK3576_GMAC_RGMII_MODE);
311
312 offset_con = data->id == 1 ? RK3576_VCCIO0_1_3_IOC_CON4 :
313 RK3576_VCCIO0_1_3_IOC_CON2;
314
315 /* m0 && m1 delay enabled */
316 regmap_write(data->php_grf, offset_con,
317 DELAY_ENABLE(RK3576, tx_delay, rx_delay));
318 regmap_write(data->php_grf, offset_con + 0x4,
319 DELAY_ENABLE(RK3576, tx_delay, rx_delay));
320
321 /* m0 && m1 delay value */
322 regmap_write(data->php_grf, offset_con,
323 RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) |
324 RK3576_GMAC_CLK_RX_DL_CFG(rx_delay));
325 regmap_write(data->php_grf, offset_con + 0x4,
326 RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) |
327 RK3576_GMAC_CLK_RX_DL_CFG(rx_delay));
328
329 return 0;
330}
331
332static int rk3576_set_to_rmii(struct udevice *dev)
333{
334 struct eth_pdata *pdata = dev_get_plat(dev);
335 struct rockchip_platform_data *data = pdata->priv_pdata;
336 u32 offset_con;
337
338 offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 :
339 RK3576_GRF_GMAC_CON0;
340
341 regmap_write(data->grf, offset_con, RK3576_GMAC_RMII_MODE);
342
343 return 0;
344}
345
346static int rk3576_set_gmac_speed(struct udevice *dev)
347{
348 struct eqos_priv *eqos = dev_get_priv(dev);
349 struct eth_pdata *pdata = dev_get_plat(dev);
350 struct rockchip_platform_data *data = pdata->priv_pdata;
351 u32 val = 0, offset_con;
352
353 switch (eqos->phy->speed) {
354 case SPEED_10:
355 if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
356 val = RK3576_GMAC_CLK_RMII_DIV20;
357 else
358 val = RK3576_GMAC_CLK_RGMII_DIV50;
359 break;
360 case SPEED_100:
361 if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
362 val = RK3576_GMAC_CLK_RMII_DIV2;
363 else
364 val = RK3576_GMAC_CLK_RGMII_DIV5;
365 break;
366 case SPEED_1000:
367 if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII)
368 val = RK3576_GMAC_CLK_RGMII_DIV1;
369 else
370 return -EINVAL;
371 break;
372 default:
373 return -EINVAL;
374 }
375
376 offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 :
377 RK3576_GRF_GMAC_CON0;
378
379 regmap_write(data->grf, offset_con, val);
380
381 return 0;
382}
383
384static void rk3576_set_clock_selection(struct udevice *dev, bool enable)
385{
386 struct eth_pdata *pdata = dev_get_plat(dev);
387 struct rockchip_platform_data *data = pdata->priv_pdata;
388
389 u32 val = data->clock_input ? RK3576_GMAC_CLK_SELECT_IO :
390 RK3576_GMAC_CLK_SELECT_CRU;
391 u32 offset_con;
392
393 val |= enable ? RK3576_GMAC_CLK_RMII_NOGATE :
394 RK3576_GMAC_CLK_RMII_GATE;
395
396 offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 :
397 RK3576_GRF_GMAC_CON0;
398
399 regmap_write(data->grf, offset_con, val);
400}
401
Jonas Karlmand10173e2025-02-09 23:27:56 +0000402#define RK3588_DELAY_ENABLE(id, tx, rx) \
403 (((tx) ? RK3588_GMAC_TXCLK_DLY_ENABLE(id) : RK3588_GMAC_TXCLK_DLY_DISABLE(id)) | \
404 ((rx) ? RK3588_GMAC_RXCLK_DLY_ENABLE(id) : RK3588_GMAC_RXCLK_DLY_DISABLE(id)))
405
Jonas Karlman1b615702023-10-01 19:17:20 +0000406/* sys_grf */
407#define RK3588_GRF_GMAC_CON7 0x031c
408#define RK3588_GRF_GMAC_CON8 0x0320
409#define RK3588_GRF_GMAC_CON9 0x0324
410
411#define RK3588_GMAC_RXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 3)
412#define RK3588_GMAC_RXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 3)
413#define RK3588_GMAC_TXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 2)
414#define RK3588_GMAC_TXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 2)
415
416#define RK3588_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8)
417#define RK3588_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0)
418
419/* php_grf */
420#define RK3588_GRF_GMAC_CON0 0x0008
421#define RK3588_GRF_CLK_CON1 0x0070
422
423#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id) \
424 (GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
425#define RK3588_GMAC_PHY_INTF_SEL_RMII(id) \
426 (GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
427
428#define RK3588_GMAC_CLK_RMII_MODE(id) GRF_BIT(5 * (id))
429#define RK3588_GMAC_CLK_RGMII_MODE(id) GRF_CLR_BIT(5 * (id))
430
431#define RK3588_GMAC_CLK_SELET_CRU(id) GRF_BIT(5 * (id) + 4)
432#define RK3588_GMAC_CLK_SELET_IO(id) GRF_CLR_BIT(5 * (id) + 4)
433
434#define RK3588_GMAC_CLK_RMII_DIV2(id) GRF_BIT(5 * (id) + 2)
435#define RK3588_GMAC_CLK_RMII_DIV20(id) GRF_CLR_BIT(5 * (id) + 2)
436
437#define RK3588_GMAC_CLK_RGMII_DIV1(id) \
438 (GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
439#define RK3588_GMAC_CLK_RGMII_DIV5(id) \
440 (GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
441#define RK3588_GMAC_CLK_RGMII_DIV50(id) \
442 (GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
443
444#define RK3588_GMAC_CLK_RMII_GATE(id) GRF_BIT(5 * (id) + 1)
445#define RK3588_GMAC_CLK_RMII_NOGATE(id) GRF_CLR_BIT(5 * (id) + 1)
446
447static int rk3588_set_to_rgmii(struct udevice *dev,
448 int tx_delay, int rx_delay)
449{
450 struct eth_pdata *pdata = dev_get_plat(dev);
451 struct rockchip_platform_data *data = pdata->priv_pdata;
452 u32 offset_con, id = data->id;
453
454 offset_con = data->id == 1 ? RK3588_GRF_GMAC_CON9 :
455 RK3588_GRF_GMAC_CON8;
456
457 regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
458 RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
459
460 regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
461 RK3588_GMAC_CLK_RGMII_MODE(id));
462
463 regmap_write(data->grf, RK3588_GRF_GMAC_CON7,
Jonas Karlmand10173e2025-02-09 23:27:56 +0000464 RK3588_DELAY_ENABLE(id, tx_delay, rx_delay));
Jonas Karlman1b615702023-10-01 19:17:20 +0000465
466 regmap_write(data->grf, offset_con,
467 RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
468 RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
469
470 return 0;
471}
472
473static int rk3588_set_to_rmii(struct udevice *dev)
474{
475 struct eth_pdata *pdata = dev_get_plat(dev);
476 struct rockchip_platform_data *data = pdata->priv_pdata;
477
478 regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
479 RK3588_GMAC_PHY_INTF_SEL_RMII(data->id));
480
481 regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
482 RK3588_GMAC_CLK_RMII_MODE(data->id));
483
484 return 0;
485}
486
487static int rk3588_set_gmac_speed(struct udevice *dev)
488{
489 struct eqos_priv *eqos = dev_get_priv(dev);
490 struct eth_pdata *pdata = dev_get_plat(dev);
491 struct rockchip_platform_data *data = pdata->priv_pdata;
492 u32 val = 0, id = data->id;
493
494 switch (eqos->phy->speed) {
495 case SPEED_10:
496 if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
497 val = RK3588_GMAC_CLK_RMII_DIV20(id);
498 else
499 val = RK3588_GMAC_CLK_RGMII_DIV50(id);
500 break;
501 case SPEED_100:
502 if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
503 val = RK3588_GMAC_CLK_RMII_DIV2(id);
504 else
505 val = RK3588_GMAC_CLK_RGMII_DIV5(id);
506 break;
507 case SPEED_1000:
508 if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII)
509 val = RK3588_GMAC_CLK_RGMII_DIV1(id);
510 else
511 return -EINVAL;
512 break;
513 default:
514 return -EINVAL;
515 }
516
517 regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
518
519 return 0;
520}
521
522static void rk3588_set_clock_selection(struct udevice *dev, bool enable)
523{
524 struct eth_pdata *pdata = dev_get_plat(dev);
525 struct rockchip_platform_data *data = pdata->priv_pdata;
526
527 u32 val = data->clock_input ? RK3588_GMAC_CLK_SELET_IO(data->id) :
528 RK3588_GMAC_CLK_SELET_CRU(data->id);
529
530 val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(data->id) :
531 RK3588_GMAC_CLK_RMII_GATE(data->id);
532
533 regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
534}
535
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000536static const struct rk_gmac_ops rk_gmac_ops[] = {
537 {
Jonas Karlmanee8fcc02025-04-07 22:47:01 +0000538 .compatible = "rockchip,rk3528-gmac",
539 .set_to_rgmii = rk3528_set_to_rgmii,
540 .set_to_rmii = rk3528_set_to_rmii,
541 .set_gmac_speed = rk3528_set_gmac_speed,
542 .set_clock_selection = rk3528_set_clock_selection,
543 .regs = {
544 0xffbd0000, /* gmac0 */
545 0xffbe0000, /* gmac1 */
546 0x0, /* sentinel */
547 },
548 },
549 {
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000550 .compatible = "rockchip,rk3568-gmac",
551 .set_to_rgmii = rk3568_set_to_rgmii,
552 .set_to_rmii = rk3568_set_to_rmii,
553 .set_gmac_speed = rk3568_set_gmac_speed,
554 .regs = {
555 0xfe2a0000, /* gmac0 */
556 0xfe010000, /* gmac1 */
557 0x0, /* sentinel */
558 },
559 },
Jonas Karlman1b615702023-10-01 19:17:20 +0000560 {
Heiko Stuebner6ed69fe2025-04-15 23:51:24 +0200561 .compatible = "rockchip,rk3576-gmac",
562 .set_to_rgmii = rk3576_set_to_rgmii,
563 .set_to_rmii = rk3576_set_to_rmii,
564 .set_gmac_speed = rk3576_set_gmac_speed,
565 .set_clock_selection = rk3576_set_clock_selection,
566 .regs = {
567 0x2a220000, /* gmac0 */
568 0x2a230000, /* gmac1 */
569 0x0, /* sentinel */
570 },
571 },
572 {
Jonas Karlman1b615702023-10-01 19:17:20 +0000573 .compatible = "rockchip,rk3588-gmac",
574 .set_to_rgmii = rk3588_set_to_rgmii,
575 .set_to_rmii = rk3588_set_to_rmii,
576 .set_gmac_speed = rk3588_set_gmac_speed,
577 .set_clock_selection = rk3588_set_clock_selection,
578 .regs = {
579 0xfe1b0000, /* gmac0 */
580 0xfe1c0000, /* gmac1 */
581 0x0, /* sentinel */
582 },
583 },
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000584 { }
585};
586
587static const struct rk_gmac_ops *get_rk_gmac_ops(struct udevice *dev)
588{
589 const struct rk_gmac_ops *ops = rk_gmac_ops;
590
591 while (ops->compatible) {
592 if (device_is_compatible(dev, ops->compatible))
593 return ops;
594 ops++;
595 }
596
597 return NULL;
598}
599
600static int eqos_probe_resources_rk(struct udevice *dev)
601{
602 struct eqos_priv *eqos = dev_get_priv(dev);
603 struct eth_pdata *pdata = dev_get_plat(dev);
604 struct rockchip_platform_data *data;
Jonas Karlman1b615702023-10-01 19:17:20 +0000605 const char *clock_in_out;
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000606 int reset_flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
607 int ret;
608
Philip Oberfichtnerd6d22da2024-08-02 11:25:37 +0200609 ret = eqos_get_base_addr_dt(dev);
610 if (ret) {
611 dev_err(dev, "eqos_get_base_addr_dt failed: %d\n", ret);
612 return ret;
613 }
614
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000615 data = calloc(1, sizeof(struct rockchip_platform_data));
616 if (!data)
617 return -ENOMEM;
618
619 data->ops = get_rk_gmac_ops(dev);
620 if (!data->ops) {
621 ret = -EINVAL;
622 goto err_free;
623 }
624
625 for (int i = 0; data->ops->regs[i]; i++) {
626 if (data->ops->regs[i] == (u32)eqos->regs) {
627 data->id = i;
628 break;
629 }
630 }
631
632 pdata->priv_pdata = data;
633 pdata->phy_interface = eqos->config->interface(dev);
634 pdata->max_speed = eqos->max_speed;
635
636 if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) {
637 pr_err("Invalid PHY interface\n");
638 ret = -EINVAL;
639 goto err_free;
640 }
641
642 data->grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,grf");
643 if (IS_ERR(data->grf)) {
644 dev_err(dev, "Missing rockchip,grf property\n");
645 ret = -EINVAL;
646 goto err_free;
647 }
648
Heiko Stuebner6ed69fe2025-04-15 23:51:24 +0200649 if (device_is_compatible(dev, "rockchip,rk3588-gmac") ||
650 device_is_compatible(dev, "rockchip,rk3576-gmac")) {
Jonas Karlman1b615702023-10-01 19:17:20 +0000651 data->php_grf =
652 syscon_regmap_lookup_by_phandle(dev, "rockchip,php-grf");
653 if (IS_ERR(data->php_grf)) {
654 dev_err(dev, "Missing rockchip,php-grf property\n");
655 ret = -EINVAL;
656 goto err_free;
657 }
658 }
659
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000660 ret = reset_get_bulk(dev, &data->resets);
661 if (ret < 0)
662 goto err_free;
663
664 reset_assert_bulk(&data->resets);
665
666 ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
667 if (ret) {
668 dev_dbg(dev, "clk_get_by_name(stmmaceth) failed: %d", ret);
669 goto err_release_resets;
670 }
671
Jonas Karlman1b615702023-10-01 19:17:20 +0000672 if (device_is_compatible(dev, "rockchip,rk3568-gmac")) {
673 ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
674 if (ret) {
675 dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
Sean Andersond318eb32023-12-16 14:38:42 -0500676 goto err_release_resets;
Jonas Karlman1b615702023-10-01 19:17:20 +0000677 }
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000678 }
679
Jonas Karlman1b615702023-10-01 19:17:20 +0000680 clock_in_out = dev_read_string(dev, "clock_in_out");
681 if (clock_in_out && !strcmp(clock_in_out, "input"))
682 data->clock_input = true;
683 else
684 data->clock_input = false;
685
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000686 /* snps,reset props are deprecated, do bare minimum to support them */
687 if (dev_read_bool(dev, "snps,reset-active-low"))
688 reset_flags |= GPIOD_ACTIVE_LOW;
689
690 dev_read_u32_array(dev, "snps,reset-delays-us", eqos->reset_delays, 3);
691
692 gpio_request_by_name(dev, "snps,reset-gpio", 0,
693 &eqos->phy_reset_gpio, reset_flags);
694
695 return 0;
696
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000697err_release_resets:
698 reset_release_bulk(&data->resets);
699err_free:
700 free(data);
701
702 return ret;
703}
704
705static int eqos_remove_resources_rk(struct udevice *dev)
706{
707 struct eqos_priv *eqos = dev_get_priv(dev);
708 struct eth_pdata *pdata = dev_get_plat(dev);
709 struct rockchip_platform_data *data = pdata->priv_pdata;
710
711 if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
712 dm_gpio_free(dev, &eqos->phy_reset_gpio);
713
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000714 reset_release_bulk(&data->resets);
715 free(data);
716
717 return 0;
718}
719
720static int eqos_stop_resets_rk(struct udevice *dev)
721{
722 struct eth_pdata *pdata = dev_get_plat(dev);
723 struct rockchip_platform_data *data = pdata->priv_pdata;
724
725 return reset_assert_bulk(&data->resets);
726}
727
728static int eqos_start_resets_rk(struct udevice *dev)
729{
730 struct eth_pdata *pdata = dev_get_plat(dev);
731 struct rockchip_platform_data *data = pdata->priv_pdata;
732
733 return reset_deassert_bulk(&data->resets);
734}
735
736static int eqos_stop_clks_rk(struct udevice *dev)
737{
Jonas Karlman1b615702023-10-01 19:17:20 +0000738 struct eth_pdata *pdata = dev_get_plat(dev);
739 struct rockchip_platform_data *data = pdata->priv_pdata;
740
741 if (data->ops->set_clock_selection)
742 data->ops->set_clock_selection(dev, false);
743
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000744 return 0;
745}
746
747static int eqos_start_clks_rk(struct udevice *dev)
748{
749 struct eqos_priv *eqos = dev_get_priv(dev);
750 struct eth_pdata *pdata = dev_get_plat(dev);
751 struct rockchip_platform_data *data = pdata->priv_pdata;
752 int tx_delay, rx_delay, ret;
753
754 if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
755 udelay(eqos->reset_delays[1]);
756
757 ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
758 if (ret < 0)
759 return ret;
760
761 udelay(eqos->reset_delays[2]);
762 }
763
Jonas Karlman1b615702023-10-01 19:17:20 +0000764 if (data->ops->set_clock_selection)
765 data->ops->set_clock_selection(dev, true);
766
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000767 tx_delay = dev_read_u32_default(dev, "tx_delay", 0x30);
768 rx_delay = dev_read_u32_default(dev, "rx_delay", 0x10);
769
770 switch (pdata->phy_interface) {
771 case PHY_INTERFACE_MODE_RGMII:
772 return data->ops->set_to_rgmii(dev, tx_delay, rx_delay);
773 case PHY_INTERFACE_MODE_RGMII_ID:
774 return data->ops->set_to_rgmii(dev, 0, 0);
775 case PHY_INTERFACE_MODE_RGMII_RXID:
776 return data->ops->set_to_rgmii(dev, tx_delay, 0);
777 case PHY_INTERFACE_MODE_RGMII_TXID:
778 return data->ops->set_to_rgmii(dev, 0, rx_delay);
779 case PHY_INTERFACE_MODE_RMII:
780 return data->ops->set_to_rmii(dev);
781 }
782
783 return -EINVAL;
784}
785
786static int eqos_set_tx_clk_speed_rk(struct udevice *dev)
787{
788 struct eth_pdata *pdata = dev_get_plat(dev);
789 struct rockchip_platform_data *data = pdata->priv_pdata;
790
791 return data->ops->set_gmac_speed(dev);
792}
793
794static ulong eqos_get_tick_clk_rate_rk(struct udevice *dev)
795{
796 struct eqos_priv *eqos = dev_get_priv(dev);
797
798 return clk_get_rate(&eqos->clk_master_bus);
799}
800
801static struct eqos_ops eqos_rockchip_ops = {
802 .eqos_inval_desc = eqos_inval_desc_generic,
803 .eqos_flush_desc = eqos_flush_desc_generic,
804 .eqos_inval_buffer = eqos_inval_buffer_generic,
805 .eqos_flush_buffer = eqos_flush_buffer_generic,
806 .eqos_probe_resources = eqos_probe_resources_rk,
807 .eqos_remove_resources = eqos_remove_resources_rk,
808 .eqos_stop_resets = eqos_stop_resets_rk,
809 .eqos_start_resets = eqos_start_resets_rk,
810 .eqos_stop_clks = eqos_stop_clks_rk,
811 .eqos_start_clks = eqos_start_clks_rk,
812 .eqos_calibrate_pads = eqos_null_ops,
813 .eqos_disable_calibration = eqos_null_ops,
814 .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_rk,
815 .eqos_get_enetaddr = eqos_null_ops,
816 .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_rk,
817};
818
819struct eqos_config eqos_rockchip_config = {
820 .reg_access_always_ok = false,
821 .mdio_wait = 10,
822 .swr_wait = 50,
823 .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
824 .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_100_150,
825 .axi_bus_width = EQOS_AXI_WIDTH_64,
826 .interface = dev_read_phy_mode,
827 .ops = &eqos_rockchip_ops,
828};