blob: d2c52b4c46f878b47cede7e2d6783c5dca77f627 [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
8#include <common.h>
9#include <dm.h>
10#include <clk.h>
11#include <phy.h>
12#include <syscon.h>
13#include <asm/io.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080014#include <asm/arch-rockchip/periph.h>
15#include <asm/arch-rockchip/clock.h>
16#include <asm/arch-rockchip/hardware.h>
Heiko Stuebner0f03e422019-07-24 01:20:29 +020017#include <asm/arch-rockchip/grf_px30.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080018#include <asm/arch-rockchip/grf_rk322x.h>
19#include <asm/arch-rockchip/grf_rk3288.h>
20#include <asm/arch-rockchip/grf_rk3328.h>
21#include <asm/arch-rockchip/grf_rk3368.h>
22#include <asm/arch-rockchip/grf_rk3399.h>
23#include <asm/arch-rockchip/grf_rv1108.h>
Sjoerd Simons54c46f92017-01-11 11:46:11 +010024#include <dm/pinctrl.h>
25#include <dt-bindings/clock/rk3288-cru.h>
26#include "designware.h"
27
Janine Hagemannb6a6dc82018-08-28 08:25:05 +020028DECLARE_GLOBAL_DATA_PTR;
29#define DELAY_ENABLE(soc, tx, rx) \
30 (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \
31 ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE))
32
Sjoerd Simons54c46f92017-01-11 11:46:11 +010033/*
34 * Platform data for the gmac
35 *
36 * dw_eth_pdata: Required platform data for designware driver (must be first)
37 */
38struct gmac_rockchip_platdata {
39 struct dw_eth_pdata dw_eth_pdata;
David Wu672e4f22018-01-13 14:01:12 +080040 bool clock_input;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010041 int tx_delay;
42 int rx_delay;
43};
44
Philipp Tomsich99cac582017-03-24 19:24:26 +010045struct rk_gmac_ops {
46 int (*fix_mac_speed)(struct dw_eth_dev *priv);
David Wu672e4f22018-01-13 14:01:12 +080047 void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
Philipp Tomsich99cac582017-03-24 19:24:26 +010048 void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
49};
50
51
Sjoerd Simons54c46f92017-01-11 11:46:11 +010052static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
53{
54 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
David Wu672e4f22018-01-13 14:01:12 +080055 const char *string;
56
57 string = dev_read_string(dev, "clock_in_out");
58 if (!strcmp(string, "input"))
59 pdata->clock_input = true;
60 else
61 pdata->clock_input = false;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010062
Philipp Tomsich99cac582017-03-24 19:24:26 +010063 /* Check the new naming-style first... */
Philipp Tomsich150005b2017-06-07 18:46:01 +020064 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
65 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
Philipp Tomsich99cac582017-03-24 19:24:26 +010066
67 /* ... and fall back to the old naming style or default, if necessary */
68 if (pdata->tx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020069 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
Philipp Tomsich99cac582017-03-24 19:24:26 +010070 if (pdata->rx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020071 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
Sjoerd Simons54c46f92017-01-11 11:46:11 +010072
73 return designware_eth_ofdata_to_platdata(dev);
74}
75
Heiko Stuebner0f03e422019-07-24 01:20:29 +020076static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
77{
78 struct px30_grf *grf;
79 struct clk clk_speed;
80 int speed, ret;
81 enum {
82 PX30_GMAC_SPEED_SHIFT = 0x2,
83 PX30_GMAC_SPEED_MASK = BIT(2),
84 PX30_GMAC_SPEED_10M = 0,
85 PX30_GMAC_SPEED_100M = BIT(2),
86 };
87
88 ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
89 &clk_speed);
90 if (ret)
91 return ret;
92
93 switch (priv->phydev->speed) {
94 case 10:
95 speed = PX30_GMAC_SPEED_10M;
96 ret = clk_set_rate(&clk_speed, 2500000);
97 if (ret)
98 return ret;
99 break;
100 case 100:
101 speed = PX30_GMAC_SPEED_100M;
102 ret = clk_set_rate(&clk_speed, 25000000);
103 if (ret)
104 return ret;
105 break;
106 default:
107 debug("Unknown phy speed: %d\n", priv->phydev->speed);
108 return -EINVAL;
109 }
110
111 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
112 rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed);
113
114 return 0;
115}
116
David Wuadcde492018-01-13 14:05:30 +0800117static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
118{
119 struct rk322x_grf *grf;
120 int clk;
121 enum {
122 RK3228_GMAC_CLK_SEL_SHIFT = 8,
123 RK3228_GMAC_CLK_SEL_MASK = GENMASK(9, 8),
124 RK3228_GMAC_CLK_SEL_125M = 0 << 8,
125 RK3228_GMAC_CLK_SEL_25M = 3 << 8,
126 RK3228_GMAC_CLK_SEL_2_5M = 2 << 8,
127 };
128
129 switch (priv->phydev->speed) {
130 case 10:
131 clk = RK3228_GMAC_CLK_SEL_2_5M;
132 break;
133 case 100:
134 clk = RK3228_GMAC_CLK_SEL_25M;
135 break;
136 case 1000:
137 clk = RK3228_GMAC_CLK_SEL_125M;
138 break;
139 default:
140 debug("Unknown phy speed: %d\n", priv->phydev->speed);
141 return -EINVAL;
142 }
143
144 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
145 rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk);
146
147 return 0;
148}
149
Philipp Tomsich99cac582017-03-24 19:24:26 +0100150static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100151{
152 struct rk3288_grf *grf;
153 int clk;
154
155 switch (priv->phydev->speed) {
156 case 10:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100157 clk = RK3288_GMAC_CLK_SEL_2_5M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100158 break;
159 case 100:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100160 clk = RK3288_GMAC_CLK_SEL_25M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100161 break;
162 case 1000:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100163 clk = RK3288_GMAC_CLK_SEL_125M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100164 break;
165 default:
166 debug("Unknown phy speed: %d\n", priv->phydev->speed);
167 return -EINVAL;
168 }
169
170 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100171 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
172
173 return 0;
174}
175
David Wubac972b2018-01-13 14:03:04 +0800176static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
177{
178 struct rk3328_grf_regs *grf;
179 int clk;
180 enum {
181 RK3328_GMAC_CLK_SEL_SHIFT = 11,
182 RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11),
183 RK3328_GMAC_CLK_SEL_125M = 0 << 11,
184 RK3328_GMAC_CLK_SEL_25M = 3 << 11,
185 RK3328_GMAC_CLK_SEL_2_5M = 2 << 11,
186 };
187
188 switch (priv->phydev->speed) {
189 case 10:
190 clk = RK3328_GMAC_CLK_SEL_2_5M;
191 break;
192 case 100:
193 clk = RK3328_GMAC_CLK_SEL_25M;
194 break;
195 case 1000:
196 clk = RK3328_GMAC_CLK_SEL_125M;
197 break;
198 default:
199 debug("Unknown phy speed: %d\n", priv->phydev->speed);
200 return -EINVAL;
201 }
202
203 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
204 rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
205
206 return 0;
207}
208
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200209static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
210{
211 struct rk3368_grf *grf;
212 int clk;
213 enum {
214 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
215 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
216 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
217 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
218 };
219
220 switch (priv->phydev->speed) {
221 case 10:
222 clk = RK3368_GMAC_CLK_SEL_2_5M;
223 break;
224 case 100:
225 clk = RK3368_GMAC_CLK_SEL_25M;
226 break;
227 case 1000:
228 clk = RK3368_GMAC_CLK_SEL_125M;
229 break;
230 default:
231 debug("Unknown phy speed: %d\n", priv->phydev->speed);
232 return -EINVAL;
233 }
234
235 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
236 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
237
238 return 0;
239}
240
Philipp Tomsich99cac582017-03-24 19:24:26 +0100241static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
242{
243 struct rk3399_grf_regs *grf;
244 int clk;
245
246 switch (priv->phydev->speed) {
247 case 10:
248 clk = RK3399_GMAC_CLK_SEL_2_5M;
249 break;
250 case 100:
251 clk = RK3399_GMAC_CLK_SEL_25M;
252 break;
253 case 1000:
254 clk = RK3399_GMAC_CLK_SEL_125M;
255 break;
256 default:
257 debug("Unknown phy speed: %d\n", priv->phydev->speed);
258 return -EINVAL;
259 }
260
261 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
262 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100263
264 return 0;
265}
266
David Wu672e4f22018-01-13 14:01:12 +0800267static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
268{
269 struct rv1108_grf *grf;
270 int clk, speed;
271 enum {
272 RV1108_GMAC_SPEED_MASK = BIT(2),
273 RV1108_GMAC_SPEED_10M = 0 << 2,
274 RV1108_GMAC_SPEED_100M = 1 << 2,
275 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
276 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
277 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
278 };
279
280 switch (priv->phydev->speed) {
281 case 10:
282 clk = RV1108_GMAC_CLK_SEL_2_5M;
283 speed = RV1108_GMAC_SPEED_10M;
284 break;
285 case 100:
286 clk = RV1108_GMAC_CLK_SEL_25M;
287 speed = RV1108_GMAC_SPEED_100M;
288 break;
289 default:
290 debug("Unknown phy speed: %d\n", priv->phydev->speed);
291 return -EINVAL;
292 }
293
294 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
295 rk_clrsetreg(&grf->gmac_con0,
296 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
297 clk | speed);
298
299 return 0;
300}
301
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200302static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
303{
304 struct px30_grf *grf;
305 enum {
306 PX30_GMAC_PHY_INTF_SEL_SHIFT = 4,
307 PX30_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 6),
308 PX30_GMAC_PHY_INTF_SEL_RMII = BIT(6),
309 };
310
311 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
312
313 rk_clrsetreg(&grf->mac_con1,
314 PX30_GMAC_PHY_INTF_SEL_MASK,
315 PX30_GMAC_PHY_INTF_SEL_RMII);
316}
317
David Wuadcde492018-01-13 14:05:30 +0800318static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
319{
320 struct rk322x_grf *grf;
321 enum {
322 RK3228_RMII_MODE_SHIFT = 10,
323 RK3228_RMII_MODE_MASK = BIT(10),
324
325 RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
326 RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
327 RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
328
329 RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
330 RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
331 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
332
333 RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
334 RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
335 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
336 };
337 enum {
338 RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
339 RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
340
341 RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
342 RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
343 };
344
345 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
346 rk_clrsetreg(&grf->mac_con[1],
347 RK3228_RMII_MODE_MASK |
348 RK3228_GMAC_PHY_INTF_SEL_MASK |
349 RK3228_RXCLK_DLY_ENA_GMAC_MASK |
350 RK3228_TXCLK_DLY_ENA_GMAC_MASK,
351 RK3228_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200352 DELAY_ENABLE(RK3228, pdata->tx_delay, pdata->rx_delay));
David Wuadcde492018-01-13 14:05:30 +0800353
354 rk_clrsetreg(&grf->mac_con[0],
355 RK3228_CLK_RX_DL_CFG_GMAC_MASK |
356 RK3228_CLK_TX_DL_CFG_GMAC_MASK,
357 pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
358 pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
359}
360
Philipp Tomsich99cac582017-03-24 19:24:26 +0100361static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
362{
363 struct rk3288_grf *grf;
364
365 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
366 rk_clrsetreg(&grf->soc_con1,
367 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
368 RK3288_GMAC_PHY_INTF_SEL_RGMII);
369
370 rk_clrsetreg(&grf->soc_con3,
371 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
372 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
373 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
374 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200375 DELAY_ENABLE(RK3288, pdata->rx_delay, pdata->tx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100376 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
377 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
378}
379
David Wubac972b2018-01-13 14:03:04 +0800380static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
381{
382 struct rk3328_grf_regs *grf;
383 enum {
384 RK3328_RMII_MODE_SHIFT = 9,
385 RK3328_RMII_MODE_MASK = BIT(9),
386
387 RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4,
388 RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
389 RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
390
391 RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
392 RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
393 RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
394
395 RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
396 RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
397 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
398 };
399 enum {
400 RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
401 RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
402
403 RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
404 RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
405 };
406
407 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
408 rk_clrsetreg(&grf->mac_con[1],
409 RK3328_RMII_MODE_MASK |
410 RK3328_GMAC_PHY_INTF_SEL_MASK |
411 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
412 RK3328_TXCLK_DLY_ENA_GMAC_MASK,
413 RK3328_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200414 DELAY_ENABLE(RK3328, pdata->tx_delay, pdata->rx_delay));
David Wubac972b2018-01-13 14:03:04 +0800415
416 rk_clrsetreg(&grf->mac_con[0],
417 RK3328_CLK_RX_DL_CFG_GMAC_MASK |
418 RK3328_CLK_TX_DL_CFG_GMAC_MASK,
419 pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
420 pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
421}
422
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200423static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
424{
425 struct rk3368_grf *grf;
426 enum {
427 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
428 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
429 RK3368_RMII_MODE_MASK = BIT(6),
430 RK3368_RMII_MODE = BIT(6),
431 };
432 enum {
433 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
434 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
435 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
436 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
437 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
438 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
439 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
440 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
441 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
442 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
443 };
444
445 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
446 rk_clrsetreg(&grf->soc_con15,
447 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
448 RK3368_GMAC_PHY_INTF_SEL_RGMII);
449
450 rk_clrsetreg(&grf->soc_con16,
451 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
452 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
453 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
454 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200455 DELAY_ENABLE(RK3368, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200456 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
457 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
458}
459
Philipp Tomsich99cac582017-03-24 19:24:26 +0100460static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
461{
462 struct rk3399_grf_regs *grf;
463
464 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
465
466 rk_clrsetreg(&grf->soc_con5,
467 RK3399_GMAC_PHY_INTF_SEL_MASK,
468 RK3399_GMAC_PHY_INTF_SEL_RGMII);
469
470 rk_clrsetreg(&grf->soc_con6,
471 RK3399_RXCLK_DLY_ENA_GMAC_MASK |
472 RK3399_TXCLK_DLY_ENA_GMAC_MASK |
473 RK3399_CLK_RX_DL_CFG_GMAC_MASK |
474 RK3399_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200475 DELAY_ENABLE(RK3399, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100476 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
477 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
478}
479
David Wu672e4f22018-01-13 14:01:12 +0800480static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
481{
482 struct rv1108_grf *grf;
483
484 enum {
485 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
486 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4,
487 };
488
489 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
490 rk_clrsetreg(&grf->gmac_con0,
491 RV1108_GMAC_PHY_INTF_SEL_MASK,
492 RV1108_GMAC_PHY_INTF_SEL_RMII);
493}
494
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100495static int gmac_rockchip_probe(struct udevice *dev)
496{
497 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100498 struct rk_gmac_ops *ops =
499 (struct rk_gmac_ops *)dev_get_driver_data(dev);
David Wu672e4f22018-01-13 14:01:12 +0800500 struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
501 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100502 struct clk clk;
David Wu672e4f22018-01-13 14:01:12 +0800503 ulong rate;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100504 int ret;
505
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200506 ret = clk_set_defaults(dev, 0);
507 if (ret)
508 debug("%s clk_set_defaults failed %d\n", __func__, ret);
509
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100510 ret = clk_get_by_index(dev, 0, &clk);
511 if (ret)
512 return ret;
513
David Wu672e4f22018-01-13 14:01:12 +0800514 switch (eth_pdata->phy_interface) {
515 case PHY_INTERFACE_MODE_RGMII:
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200516 /* Set to RGMII mode */
517 if (ops->set_to_rgmii)
518 ops->set_to_rgmii(pdata);
519 else
520 return -EPERM;
521
David Wu672e4f22018-01-13 14:01:12 +0800522 /*
523 * If the gmac clock is from internal pll, need to set and
524 * check the return value for gmac clock at RGMII mode. If
525 * the gmac clock is from external source, the clock rate
526 * is not set, because of it is bypassed.
527 */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200528
David Wu672e4f22018-01-13 14:01:12 +0800529 if (!pdata->clock_input) {
530 rate = clk_set_rate(&clk, 125000000);
531 if (rate != 125000000)
532 return -EINVAL;
533 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200534 break;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100535
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200536 case PHY_INTERFACE_MODE_RGMII_ID:
David Wu672e4f22018-01-13 14:01:12 +0800537 /* Set to RGMII mode */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200538 if (ops->set_to_rgmii) {
539 pdata->tx_delay = 0;
540 pdata->rx_delay = 0;
David Wu672e4f22018-01-13 14:01:12 +0800541 ops->set_to_rgmii(pdata);
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200542 } else
David Wu672e4f22018-01-13 14:01:12 +0800543 return -EPERM;
544
David Wu672e4f22018-01-13 14:01:12 +0800545 if (!pdata->clock_input) {
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200546 rate = clk_set_rate(&clk, 125000000);
547 if (rate != 125000000)
David Wu672e4f22018-01-13 14:01:12 +0800548 return -EINVAL;
549 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200550 break;
David Wu672e4f22018-01-13 14:01:12 +0800551
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200552 case PHY_INTERFACE_MODE_RMII:
David Wu672e4f22018-01-13 14:01:12 +0800553 /* Set to RMII mode */
554 if (ops->set_to_rmii)
555 ops->set_to_rmii(pdata);
556 else
557 return -EPERM;
558
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200559 if (!pdata->clock_input) {
560 rate = clk_set_rate(&clk, 50000000);
561 if (rate != 50000000)
562 return -EINVAL;
563 }
564 break;
565
566 case PHY_INTERFACE_MODE_RGMII_RXID:
567 /* Set to RGMII_RXID mode */
568 if (ops->set_to_rgmii) {
569 pdata->tx_delay = 0;
570 ops->set_to_rgmii(pdata);
571 } else
572 return -EPERM;
573
574 if (!pdata->clock_input) {
575 rate = clk_set_rate(&clk, 125000000);
576 if (rate != 125000000)
577 return -EINVAL;
578 }
David Wu672e4f22018-01-13 14:01:12 +0800579 break;
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200580
581 case PHY_INTERFACE_MODE_RGMII_TXID:
582 /* Set to RGMII_TXID mode */
583 if (ops->set_to_rgmii) {
584 pdata->rx_delay = 0;
585 ops->set_to_rgmii(pdata);
586 } else
587 return -EPERM;
588
589 if (!pdata->clock_input) {
590 rate = clk_set_rate(&clk, 125000000);
591 if (rate != 125000000)
592 return -EINVAL;
593 }
594 break;
595
David Wu672e4f22018-01-13 14:01:12 +0800596 default:
597 debug("NO interface defined!\n");
598 return -ENXIO;
599 }
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100600
601 return designware_eth_probe(dev);
602}
603
604static int gmac_rockchip_eth_start(struct udevice *dev)
605{
606 struct eth_pdata *pdata = dev_get_platdata(dev);
607 struct dw_eth_dev *priv = dev_get_priv(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100608 struct rk_gmac_ops *ops =
609 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100610 int ret;
611
612 ret = designware_eth_init(priv, pdata->enetaddr);
613 if (ret)
614 return ret;
Philipp Tomsich99cac582017-03-24 19:24:26 +0100615 ret = ops->fix_mac_speed(priv);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100616 if (ret)
617 return ret;
618 ret = designware_eth_enable(priv);
619 if (ret)
620 return ret;
621
622 return 0;
623}
624
625const struct eth_ops gmac_rockchip_eth_ops = {
626 .start = gmac_rockchip_eth_start,
627 .send = designware_eth_send,
628 .recv = designware_eth_recv,
629 .free_pkt = designware_eth_free_pkt,
630 .stop = designware_eth_stop,
631 .write_hwaddr = designware_eth_write_hwaddr,
632};
633
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200634const struct rk_gmac_ops px30_gmac_ops = {
635 .fix_mac_speed = px30_gmac_fix_mac_speed,
636 .set_to_rmii = px30_gmac_set_to_rmii,
637};
638
David Wuadcde492018-01-13 14:05:30 +0800639const struct rk_gmac_ops rk3228_gmac_ops = {
640 .fix_mac_speed = rk3228_gmac_fix_mac_speed,
641 .set_to_rgmii = rk3228_gmac_set_to_rgmii,
642};
643
Philipp Tomsich99cac582017-03-24 19:24:26 +0100644const struct rk_gmac_ops rk3288_gmac_ops = {
645 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
646 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
647};
648
David Wubac972b2018-01-13 14:03:04 +0800649const struct rk_gmac_ops rk3328_gmac_ops = {
650 .fix_mac_speed = rk3328_gmac_fix_mac_speed,
651 .set_to_rgmii = rk3328_gmac_set_to_rgmii,
652};
653
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200654const struct rk_gmac_ops rk3368_gmac_ops = {
655 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
656 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
657};
658
Philipp Tomsich99cac582017-03-24 19:24:26 +0100659const struct rk_gmac_ops rk3399_gmac_ops = {
660 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
661 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
662};
663
David Wu672e4f22018-01-13 14:01:12 +0800664const struct rk_gmac_ops rv1108_gmac_ops = {
665 .fix_mac_speed = rv1108_set_rmii_speed,
666 .set_to_rmii = rv1108_gmac_set_to_rmii,
667};
668
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100669static const struct udevice_id rockchip_gmac_ids[] = {
Heiko Stuebner0f03e422019-07-24 01:20:29 +0200670 { .compatible = "rockchip,px30-gmac",
671 .data = (ulong)&px30_gmac_ops },
David Wuadcde492018-01-13 14:05:30 +0800672 { .compatible = "rockchip,rk3228-gmac",
673 .data = (ulong)&rk3228_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100674 { .compatible = "rockchip,rk3288-gmac",
675 .data = (ulong)&rk3288_gmac_ops },
David Wubac972b2018-01-13 14:03:04 +0800676 { .compatible = "rockchip,rk3328-gmac",
677 .data = (ulong)&rk3328_gmac_ops },
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200678 { .compatible = "rockchip,rk3368-gmac",
679 .data = (ulong)&rk3368_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100680 { .compatible = "rockchip,rk3399-gmac",
681 .data = (ulong)&rk3399_gmac_ops },
David Wu672e4f22018-01-13 14:01:12 +0800682 { .compatible = "rockchip,rv1108-gmac",
683 .data = (ulong)&rv1108_gmac_ops },
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100684 { }
685};
686
687U_BOOT_DRIVER(eth_gmac_rockchip) = {
688 .name = "gmac_rockchip",
689 .id = UCLASS_ETH,
690 .of_match = rockchip_gmac_ids,
691 .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
692 .probe = gmac_rockchip_probe,
693 .ops = &gmac_rockchip_eth_ops,
694 .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
695 .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
696 .flags = DM_FLAG_ALLOC_PRIV_DMA,
697};