blob: 3a9c46a01ec3ff22f3049768fe4cf603921270f4 [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
Jonas Karlmand10173e2025-02-09 23:27:56 +0000263#define RK3588_DELAY_ENABLE(id, tx, rx) \
264 (((tx) ? RK3588_GMAC_TXCLK_DLY_ENABLE(id) : RK3588_GMAC_TXCLK_DLY_DISABLE(id)) | \
265 ((rx) ? RK3588_GMAC_RXCLK_DLY_ENABLE(id) : RK3588_GMAC_RXCLK_DLY_DISABLE(id)))
266
Jonas Karlman1b615702023-10-01 19:17:20 +0000267/* sys_grf */
268#define RK3588_GRF_GMAC_CON7 0x031c
269#define RK3588_GRF_GMAC_CON8 0x0320
270#define RK3588_GRF_GMAC_CON9 0x0324
271
272#define RK3588_GMAC_RXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 3)
273#define RK3588_GMAC_RXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 3)
274#define RK3588_GMAC_TXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 2)
275#define RK3588_GMAC_TXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 2)
276
277#define RK3588_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8)
278#define RK3588_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0)
279
280/* php_grf */
281#define RK3588_GRF_GMAC_CON0 0x0008
282#define RK3588_GRF_CLK_CON1 0x0070
283
284#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id) \
285 (GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
286#define RK3588_GMAC_PHY_INTF_SEL_RMII(id) \
287 (GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
288
289#define RK3588_GMAC_CLK_RMII_MODE(id) GRF_BIT(5 * (id))
290#define RK3588_GMAC_CLK_RGMII_MODE(id) GRF_CLR_BIT(5 * (id))
291
292#define RK3588_GMAC_CLK_SELET_CRU(id) GRF_BIT(5 * (id) + 4)
293#define RK3588_GMAC_CLK_SELET_IO(id) GRF_CLR_BIT(5 * (id) + 4)
294
295#define RK3588_GMAC_CLK_RMII_DIV2(id) GRF_BIT(5 * (id) + 2)
296#define RK3588_GMAC_CLK_RMII_DIV20(id) GRF_CLR_BIT(5 * (id) + 2)
297
298#define RK3588_GMAC_CLK_RGMII_DIV1(id) \
299 (GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
300#define RK3588_GMAC_CLK_RGMII_DIV5(id) \
301 (GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
302#define RK3588_GMAC_CLK_RGMII_DIV50(id) \
303 (GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
304
305#define RK3588_GMAC_CLK_RMII_GATE(id) GRF_BIT(5 * (id) + 1)
306#define RK3588_GMAC_CLK_RMII_NOGATE(id) GRF_CLR_BIT(5 * (id) + 1)
307
308static int rk3588_set_to_rgmii(struct udevice *dev,
309 int tx_delay, int rx_delay)
310{
311 struct eth_pdata *pdata = dev_get_plat(dev);
312 struct rockchip_platform_data *data = pdata->priv_pdata;
313 u32 offset_con, id = data->id;
314
315 offset_con = data->id == 1 ? RK3588_GRF_GMAC_CON9 :
316 RK3588_GRF_GMAC_CON8;
317
318 regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
319 RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
320
321 regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
322 RK3588_GMAC_CLK_RGMII_MODE(id));
323
324 regmap_write(data->grf, RK3588_GRF_GMAC_CON7,
Jonas Karlmand10173e2025-02-09 23:27:56 +0000325 RK3588_DELAY_ENABLE(id, tx_delay, rx_delay));
Jonas Karlman1b615702023-10-01 19:17:20 +0000326
327 regmap_write(data->grf, offset_con,
328 RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
329 RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
330
331 return 0;
332}
333
334static int rk3588_set_to_rmii(struct udevice *dev)
335{
336 struct eth_pdata *pdata = dev_get_plat(dev);
337 struct rockchip_platform_data *data = pdata->priv_pdata;
338
339 regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
340 RK3588_GMAC_PHY_INTF_SEL_RMII(data->id));
341
342 regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
343 RK3588_GMAC_CLK_RMII_MODE(data->id));
344
345 return 0;
346}
347
348static int rk3588_set_gmac_speed(struct udevice *dev)
349{
350 struct eqos_priv *eqos = dev_get_priv(dev);
351 struct eth_pdata *pdata = dev_get_plat(dev);
352 struct rockchip_platform_data *data = pdata->priv_pdata;
353 u32 val = 0, id = data->id;
354
355 switch (eqos->phy->speed) {
356 case SPEED_10:
357 if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
358 val = RK3588_GMAC_CLK_RMII_DIV20(id);
359 else
360 val = RK3588_GMAC_CLK_RGMII_DIV50(id);
361 break;
362 case SPEED_100:
363 if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
364 val = RK3588_GMAC_CLK_RMII_DIV2(id);
365 else
366 val = RK3588_GMAC_CLK_RGMII_DIV5(id);
367 break;
368 case SPEED_1000:
369 if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII)
370 val = RK3588_GMAC_CLK_RGMII_DIV1(id);
371 else
372 return -EINVAL;
373 break;
374 default:
375 return -EINVAL;
376 }
377
378 regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
379
380 return 0;
381}
382
383static void rk3588_set_clock_selection(struct udevice *dev, bool enable)
384{
385 struct eth_pdata *pdata = dev_get_plat(dev);
386 struct rockchip_platform_data *data = pdata->priv_pdata;
387
388 u32 val = data->clock_input ? RK3588_GMAC_CLK_SELET_IO(data->id) :
389 RK3588_GMAC_CLK_SELET_CRU(data->id);
390
391 val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(data->id) :
392 RK3588_GMAC_CLK_RMII_GATE(data->id);
393
394 regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
395}
396
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000397static const struct rk_gmac_ops rk_gmac_ops[] = {
398 {
Jonas Karlmanee8fcc02025-04-07 22:47:01 +0000399 .compatible = "rockchip,rk3528-gmac",
400 .set_to_rgmii = rk3528_set_to_rgmii,
401 .set_to_rmii = rk3528_set_to_rmii,
402 .set_gmac_speed = rk3528_set_gmac_speed,
403 .set_clock_selection = rk3528_set_clock_selection,
404 .regs = {
405 0xffbd0000, /* gmac0 */
406 0xffbe0000, /* gmac1 */
407 0x0, /* sentinel */
408 },
409 },
410 {
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000411 .compatible = "rockchip,rk3568-gmac",
412 .set_to_rgmii = rk3568_set_to_rgmii,
413 .set_to_rmii = rk3568_set_to_rmii,
414 .set_gmac_speed = rk3568_set_gmac_speed,
415 .regs = {
416 0xfe2a0000, /* gmac0 */
417 0xfe010000, /* gmac1 */
418 0x0, /* sentinel */
419 },
420 },
Jonas Karlman1b615702023-10-01 19:17:20 +0000421 {
422 .compatible = "rockchip,rk3588-gmac",
423 .set_to_rgmii = rk3588_set_to_rgmii,
424 .set_to_rmii = rk3588_set_to_rmii,
425 .set_gmac_speed = rk3588_set_gmac_speed,
426 .set_clock_selection = rk3588_set_clock_selection,
427 .regs = {
428 0xfe1b0000, /* gmac0 */
429 0xfe1c0000, /* gmac1 */
430 0x0, /* sentinel */
431 },
432 },
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000433 { }
434};
435
436static const struct rk_gmac_ops *get_rk_gmac_ops(struct udevice *dev)
437{
438 const struct rk_gmac_ops *ops = rk_gmac_ops;
439
440 while (ops->compatible) {
441 if (device_is_compatible(dev, ops->compatible))
442 return ops;
443 ops++;
444 }
445
446 return NULL;
447}
448
449static int eqos_probe_resources_rk(struct udevice *dev)
450{
451 struct eqos_priv *eqos = dev_get_priv(dev);
452 struct eth_pdata *pdata = dev_get_plat(dev);
453 struct rockchip_platform_data *data;
Jonas Karlman1b615702023-10-01 19:17:20 +0000454 const char *clock_in_out;
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000455 int reset_flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
456 int ret;
457
Philip Oberfichtnerd6d22da2024-08-02 11:25:37 +0200458 ret = eqos_get_base_addr_dt(dev);
459 if (ret) {
460 dev_err(dev, "eqos_get_base_addr_dt failed: %d\n", ret);
461 return ret;
462 }
463
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000464 data = calloc(1, sizeof(struct rockchip_platform_data));
465 if (!data)
466 return -ENOMEM;
467
468 data->ops = get_rk_gmac_ops(dev);
469 if (!data->ops) {
470 ret = -EINVAL;
471 goto err_free;
472 }
473
474 for (int i = 0; data->ops->regs[i]; i++) {
475 if (data->ops->regs[i] == (u32)eqos->regs) {
476 data->id = i;
477 break;
478 }
479 }
480
481 pdata->priv_pdata = data;
482 pdata->phy_interface = eqos->config->interface(dev);
483 pdata->max_speed = eqos->max_speed;
484
485 if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) {
486 pr_err("Invalid PHY interface\n");
487 ret = -EINVAL;
488 goto err_free;
489 }
490
491 data->grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,grf");
492 if (IS_ERR(data->grf)) {
493 dev_err(dev, "Missing rockchip,grf property\n");
494 ret = -EINVAL;
495 goto err_free;
496 }
497
Jonas Karlman1b615702023-10-01 19:17:20 +0000498 if (device_is_compatible(dev, "rockchip,rk3588-gmac")) {
499 data->php_grf =
500 syscon_regmap_lookup_by_phandle(dev, "rockchip,php-grf");
501 if (IS_ERR(data->php_grf)) {
502 dev_err(dev, "Missing rockchip,php-grf property\n");
503 ret = -EINVAL;
504 goto err_free;
505 }
506 }
507
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000508 ret = reset_get_bulk(dev, &data->resets);
509 if (ret < 0)
510 goto err_free;
511
512 reset_assert_bulk(&data->resets);
513
514 ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
515 if (ret) {
516 dev_dbg(dev, "clk_get_by_name(stmmaceth) failed: %d", ret);
517 goto err_release_resets;
518 }
519
Jonas Karlman1b615702023-10-01 19:17:20 +0000520 if (device_is_compatible(dev, "rockchip,rk3568-gmac")) {
521 ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
522 if (ret) {
523 dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
Sean Andersond318eb32023-12-16 14:38:42 -0500524 goto err_release_resets;
Jonas Karlman1b615702023-10-01 19:17:20 +0000525 }
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000526 }
527
Jonas Karlman1b615702023-10-01 19:17:20 +0000528 clock_in_out = dev_read_string(dev, "clock_in_out");
529 if (clock_in_out && !strcmp(clock_in_out, "input"))
530 data->clock_input = true;
531 else
532 data->clock_input = false;
533
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000534 /* snps,reset props are deprecated, do bare minimum to support them */
535 if (dev_read_bool(dev, "snps,reset-active-low"))
536 reset_flags |= GPIOD_ACTIVE_LOW;
537
538 dev_read_u32_array(dev, "snps,reset-delays-us", eqos->reset_delays, 3);
539
540 gpio_request_by_name(dev, "snps,reset-gpio", 0,
541 &eqos->phy_reset_gpio, reset_flags);
542
543 return 0;
544
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000545err_release_resets:
546 reset_release_bulk(&data->resets);
547err_free:
548 free(data);
549
550 return ret;
551}
552
553static int eqos_remove_resources_rk(struct udevice *dev)
554{
555 struct eqos_priv *eqos = dev_get_priv(dev);
556 struct eth_pdata *pdata = dev_get_plat(dev);
557 struct rockchip_platform_data *data = pdata->priv_pdata;
558
559 if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
560 dm_gpio_free(dev, &eqos->phy_reset_gpio);
561
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000562 reset_release_bulk(&data->resets);
563 free(data);
564
565 return 0;
566}
567
568static int eqos_stop_resets_rk(struct udevice *dev)
569{
570 struct eth_pdata *pdata = dev_get_plat(dev);
571 struct rockchip_platform_data *data = pdata->priv_pdata;
572
573 return reset_assert_bulk(&data->resets);
574}
575
576static int eqos_start_resets_rk(struct udevice *dev)
577{
578 struct eth_pdata *pdata = dev_get_plat(dev);
579 struct rockchip_platform_data *data = pdata->priv_pdata;
580
581 return reset_deassert_bulk(&data->resets);
582}
583
584static int eqos_stop_clks_rk(struct udevice *dev)
585{
Jonas Karlman1b615702023-10-01 19:17:20 +0000586 struct eth_pdata *pdata = dev_get_plat(dev);
587 struct rockchip_platform_data *data = pdata->priv_pdata;
588
589 if (data->ops->set_clock_selection)
590 data->ops->set_clock_selection(dev, false);
591
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000592 return 0;
593}
594
595static int eqos_start_clks_rk(struct udevice *dev)
596{
597 struct eqos_priv *eqos = dev_get_priv(dev);
598 struct eth_pdata *pdata = dev_get_plat(dev);
599 struct rockchip_platform_data *data = pdata->priv_pdata;
600 int tx_delay, rx_delay, ret;
601
602 if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
603 udelay(eqos->reset_delays[1]);
604
605 ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
606 if (ret < 0)
607 return ret;
608
609 udelay(eqos->reset_delays[2]);
610 }
611
Jonas Karlman1b615702023-10-01 19:17:20 +0000612 if (data->ops->set_clock_selection)
613 data->ops->set_clock_selection(dev, true);
614
Jonas Karlman098ee4f2023-10-01 19:17:19 +0000615 tx_delay = dev_read_u32_default(dev, "tx_delay", 0x30);
616 rx_delay = dev_read_u32_default(dev, "rx_delay", 0x10);
617
618 switch (pdata->phy_interface) {
619 case PHY_INTERFACE_MODE_RGMII:
620 return data->ops->set_to_rgmii(dev, tx_delay, rx_delay);
621 case PHY_INTERFACE_MODE_RGMII_ID:
622 return data->ops->set_to_rgmii(dev, 0, 0);
623 case PHY_INTERFACE_MODE_RGMII_RXID:
624 return data->ops->set_to_rgmii(dev, tx_delay, 0);
625 case PHY_INTERFACE_MODE_RGMII_TXID:
626 return data->ops->set_to_rgmii(dev, 0, rx_delay);
627 case PHY_INTERFACE_MODE_RMII:
628 return data->ops->set_to_rmii(dev);
629 }
630
631 return -EINVAL;
632}
633
634static int eqos_set_tx_clk_speed_rk(struct udevice *dev)
635{
636 struct eth_pdata *pdata = dev_get_plat(dev);
637 struct rockchip_platform_data *data = pdata->priv_pdata;
638
639 return data->ops->set_gmac_speed(dev);
640}
641
642static ulong eqos_get_tick_clk_rate_rk(struct udevice *dev)
643{
644 struct eqos_priv *eqos = dev_get_priv(dev);
645
646 return clk_get_rate(&eqos->clk_master_bus);
647}
648
649static struct eqos_ops eqos_rockchip_ops = {
650 .eqos_inval_desc = eqos_inval_desc_generic,
651 .eqos_flush_desc = eqos_flush_desc_generic,
652 .eqos_inval_buffer = eqos_inval_buffer_generic,
653 .eqos_flush_buffer = eqos_flush_buffer_generic,
654 .eqos_probe_resources = eqos_probe_resources_rk,
655 .eqos_remove_resources = eqos_remove_resources_rk,
656 .eqos_stop_resets = eqos_stop_resets_rk,
657 .eqos_start_resets = eqos_start_resets_rk,
658 .eqos_stop_clks = eqos_stop_clks_rk,
659 .eqos_start_clks = eqos_start_clks_rk,
660 .eqos_calibrate_pads = eqos_null_ops,
661 .eqos_disable_calibration = eqos_null_ops,
662 .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_rk,
663 .eqos_get_enetaddr = eqos_null_ops,
664 .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_rk,
665};
666
667struct eqos_config eqos_rockchip_config = {
668 .reg_access_always_ok = false,
669 .mdio_wait = 10,
670 .swr_wait = 50,
671 .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
672 .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_100_150,
673 .axi_bus_width = EQOS_AXI_WIDTH_64,
674 .interface = dev_read_phy_mode,
675 .ops = &eqos_rockchip_ops,
676};