blob: 5ed3049fa682bdc04e20db3ad3ee2e792bb14c7b [file] [log] [blame]
Sjoerd Simons54c46f92017-01-11 11:46:11 +01001/*
2 * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 *
6 * Rockchip GMAC ethernet IP driver for U-Boot
7 */
8
9#include <common.h>
10#include <dm.h>
11#include <clk.h>
12#include <phy.h>
13#include <syscon.h>
14#include <asm/io.h>
15#include <asm/arch/periph.h>
16#include <asm/arch/clock.h>
Philipp Tomsich99cac582017-03-24 19:24:26 +010017#include <asm/arch/hardware.h>
David Wuadcde492018-01-13 14:05:30 +080018#include <asm/arch/grf_rk322x.h>
Sjoerd Simons54c46f92017-01-11 11:46:11 +010019#include <asm/arch/grf_rk3288.h>
David Wubac972b2018-01-13 14:03:04 +080020#include <asm/arch/grf_rk3328.h>
Philipp Tomsich821c4c42017-07-25 17:02:51 +020021#include <asm/arch/grf_rk3368.h>
Philipp Tomsich99cac582017-03-24 19:24:26 +010022#include <asm/arch/grf_rk3399.h>
David Wu672e4f22018-01-13 14:01:12 +080023#include <asm/arch/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
Sjoerd Simons54c46f92017-01-11 11:46:11 +010028/*
29 * Platform data for the gmac
30 *
31 * dw_eth_pdata: Required platform data for designware driver (must be first)
32 */
33struct gmac_rockchip_platdata {
34 struct dw_eth_pdata dw_eth_pdata;
David Wu672e4f22018-01-13 14:01:12 +080035 bool clock_input;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010036 int tx_delay;
37 int rx_delay;
38};
39
Philipp Tomsich99cac582017-03-24 19:24:26 +010040struct rk_gmac_ops {
41 int (*fix_mac_speed)(struct dw_eth_dev *priv);
David Wu672e4f22018-01-13 14:01:12 +080042 void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
Philipp Tomsich99cac582017-03-24 19:24:26 +010043 void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
44};
45
46
Sjoerd Simons54c46f92017-01-11 11:46:11 +010047static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
48{
49 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
David Wu672e4f22018-01-13 14:01:12 +080050 const char *string;
51
52 string = dev_read_string(dev, "clock_in_out");
53 if (!strcmp(string, "input"))
54 pdata->clock_input = true;
55 else
56 pdata->clock_input = false;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010057
Philipp Tomsich99cac582017-03-24 19:24:26 +010058 /* Check the new naming-style first... */
Philipp Tomsich150005b2017-06-07 18:46:01 +020059 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
60 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
Philipp Tomsich99cac582017-03-24 19:24:26 +010061
62 /* ... and fall back to the old naming style or default, if necessary */
63 if (pdata->tx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020064 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
Philipp Tomsich99cac582017-03-24 19:24:26 +010065 if (pdata->rx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020066 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
Sjoerd Simons54c46f92017-01-11 11:46:11 +010067
68 return designware_eth_ofdata_to_platdata(dev);
69}
70
David Wuadcde492018-01-13 14:05:30 +080071static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
72{
73 struct rk322x_grf *grf;
74 int clk;
75 enum {
76 RK3228_GMAC_CLK_SEL_SHIFT = 8,
77 RK3228_GMAC_CLK_SEL_MASK = GENMASK(9, 8),
78 RK3228_GMAC_CLK_SEL_125M = 0 << 8,
79 RK3228_GMAC_CLK_SEL_25M = 3 << 8,
80 RK3228_GMAC_CLK_SEL_2_5M = 2 << 8,
81 };
82
83 switch (priv->phydev->speed) {
84 case 10:
85 clk = RK3228_GMAC_CLK_SEL_2_5M;
86 break;
87 case 100:
88 clk = RK3228_GMAC_CLK_SEL_25M;
89 break;
90 case 1000:
91 clk = RK3228_GMAC_CLK_SEL_125M;
92 break;
93 default:
94 debug("Unknown phy speed: %d\n", priv->phydev->speed);
95 return -EINVAL;
96 }
97
98 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
99 rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk);
100
101 return 0;
102}
103
Philipp Tomsich99cac582017-03-24 19:24:26 +0100104static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100105{
106 struct rk3288_grf *grf;
107 int clk;
108
109 switch (priv->phydev->speed) {
110 case 10:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100111 clk = RK3288_GMAC_CLK_SEL_2_5M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100112 break;
113 case 100:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100114 clk = RK3288_GMAC_CLK_SEL_25M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100115 break;
116 case 1000:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100117 clk = RK3288_GMAC_CLK_SEL_125M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100118 break;
119 default:
120 debug("Unknown phy speed: %d\n", priv->phydev->speed);
121 return -EINVAL;
122 }
123
124 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100125 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
126
127 return 0;
128}
129
David Wubac972b2018-01-13 14:03:04 +0800130static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
131{
132 struct rk3328_grf_regs *grf;
133 int clk;
134 enum {
135 RK3328_GMAC_CLK_SEL_SHIFT = 11,
136 RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11),
137 RK3328_GMAC_CLK_SEL_125M = 0 << 11,
138 RK3328_GMAC_CLK_SEL_25M = 3 << 11,
139 RK3328_GMAC_CLK_SEL_2_5M = 2 << 11,
140 };
141
142 switch (priv->phydev->speed) {
143 case 10:
144 clk = RK3328_GMAC_CLK_SEL_2_5M;
145 break;
146 case 100:
147 clk = RK3328_GMAC_CLK_SEL_25M;
148 break;
149 case 1000:
150 clk = RK3328_GMAC_CLK_SEL_125M;
151 break;
152 default:
153 debug("Unknown phy speed: %d\n", priv->phydev->speed);
154 return -EINVAL;
155 }
156
157 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
158 rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
159
160 return 0;
161}
162
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200163static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
164{
165 struct rk3368_grf *grf;
166 int clk;
167 enum {
168 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
169 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
170 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
171 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
172 };
173
174 switch (priv->phydev->speed) {
175 case 10:
176 clk = RK3368_GMAC_CLK_SEL_2_5M;
177 break;
178 case 100:
179 clk = RK3368_GMAC_CLK_SEL_25M;
180 break;
181 case 1000:
182 clk = RK3368_GMAC_CLK_SEL_125M;
183 break;
184 default:
185 debug("Unknown phy speed: %d\n", priv->phydev->speed);
186 return -EINVAL;
187 }
188
189 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
190 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
191
192 return 0;
193}
194
Philipp Tomsich99cac582017-03-24 19:24:26 +0100195static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
196{
197 struct rk3399_grf_regs *grf;
198 int clk;
199
200 switch (priv->phydev->speed) {
201 case 10:
202 clk = RK3399_GMAC_CLK_SEL_2_5M;
203 break;
204 case 100:
205 clk = RK3399_GMAC_CLK_SEL_25M;
206 break;
207 case 1000:
208 clk = RK3399_GMAC_CLK_SEL_125M;
209 break;
210 default:
211 debug("Unknown phy speed: %d\n", priv->phydev->speed);
212 return -EINVAL;
213 }
214
215 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
216 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100217
218 return 0;
219}
220
David Wu672e4f22018-01-13 14:01:12 +0800221static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
222{
223 struct rv1108_grf *grf;
224 int clk, speed;
225 enum {
226 RV1108_GMAC_SPEED_MASK = BIT(2),
227 RV1108_GMAC_SPEED_10M = 0 << 2,
228 RV1108_GMAC_SPEED_100M = 1 << 2,
229 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
230 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
231 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
232 };
233
234 switch (priv->phydev->speed) {
235 case 10:
236 clk = RV1108_GMAC_CLK_SEL_2_5M;
237 speed = RV1108_GMAC_SPEED_10M;
238 break;
239 case 100:
240 clk = RV1108_GMAC_CLK_SEL_25M;
241 speed = RV1108_GMAC_SPEED_100M;
242 break;
243 default:
244 debug("Unknown phy speed: %d\n", priv->phydev->speed);
245 return -EINVAL;
246 }
247
248 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
249 rk_clrsetreg(&grf->gmac_con0,
250 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
251 clk | speed);
252
253 return 0;
254}
255
David Wuadcde492018-01-13 14:05:30 +0800256static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
257{
258 struct rk322x_grf *grf;
259 enum {
260 RK3228_RMII_MODE_SHIFT = 10,
261 RK3228_RMII_MODE_MASK = BIT(10),
262
263 RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
264 RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
265 RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
266
267 RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
268 RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
269 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
270
271 RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
272 RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
273 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
274 };
275 enum {
276 RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
277 RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
278
279 RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
280 RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
281 };
282
283 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
284 rk_clrsetreg(&grf->mac_con[1],
285 RK3228_RMII_MODE_MASK |
286 RK3228_GMAC_PHY_INTF_SEL_MASK |
287 RK3228_RXCLK_DLY_ENA_GMAC_MASK |
288 RK3228_TXCLK_DLY_ENA_GMAC_MASK,
289 RK3228_GMAC_PHY_INTF_SEL_RGMII |
290 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE |
291 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE);
292
293 rk_clrsetreg(&grf->mac_con[0],
294 RK3228_CLK_RX_DL_CFG_GMAC_MASK |
295 RK3228_CLK_TX_DL_CFG_GMAC_MASK,
296 pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
297 pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
298}
299
Philipp Tomsich99cac582017-03-24 19:24:26 +0100300static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
301{
302 struct rk3288_grf *grf;
303
304 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
305 rk_clrsetreg(&grf->soc_con1,
306 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
307 RK3288_GMAC_PHY_INTF_SEL_RGMII);
308
309 rk_clrsetreg(&grf->soc_con3,
310 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
311 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
312 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
313 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
314 RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
315 RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
316 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
317 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
318}
319
David Wubac972b2018-01-13 14:03:04 +0800320static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
321{
322 struct rk3328_grf_regs *grf;
323 enum {
324 RK3328_RMII_MODE_SHIFT = 9,
325 RK3328_RMII_MODE_MASK = BIT(9),
326
327 RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4,
328 RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
329 RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
330
331 RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
332 RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
333 RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
334
335 RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
336 RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
337 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
338 };
339 enum {
340 RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
341 RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
342
343 RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
344 RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
345 };
346
347 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
348 rk_clrsetreg(&grf->mac_con[1],
349 RK3328_RMII_MODE_MASK |
350 RK3328_GMAC_PHY_INTF_SEL_MASK |
351 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
352 RK3328_TXCLK_DLY_ENA_GMAC_MASK,
353 RK3328_GMAC_PHY_INTF_SEL_RGMII |
354 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
355 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE);
356
357 rk_clrsetreg(&grf->mac_con[0],
358 RK3328_CLK_RX_DL_CFG_GMAC_MASK |
359 RK3328_CLK_TX_DL_CFG_GMAC_MASK,
360 pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
361 pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
362}
363
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200364static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
365{
366 struct rk3368_grf *grf;
367 enum {
368 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
369 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
370 RK3368_RMII_MODE_MASK = BIT(6),
371 RK3368_RMII_MODE = BIT(6),
372 };
373 enum {
374 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
375 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
376 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
377 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
378 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
379 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
380 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
381 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
382 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
383 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
384 };
385
386 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
387 rk_clrsetreg(&grf->soc_con15,
388 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
389 RK3368_GMAC_PHY_INTF_SEL_RGMII);
390
391 rk_clrsetreg(&grf->soc_con16,
392 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
393 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
394 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
395 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
396 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE |
397 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE |
398 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
399 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
400}
401
Philipp Tomsich99cac582017-03-24 19:24:26 +0100402static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
403{
404 struct rk3399_grf_regs *grf;
405
406 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
407
408 rk_clrsetreg(&grf->soc_con5,
409 RK3399_GMAC_PHY_INTF_SEL_MASK,
410 RK3399_GMAC_PHY_INTF_SEL_RGMII);
411
412 rk_clrsetreg(&grf->soc_con6,
413 RK3399_RXCLK_DLY_ENA_GMAC_MASK |
414 RK3399_TXCLK_DLY_ENA_GMAC_MASK |
415 RK3399_CLK_RX_DL_CFG_GMAC_MASK |
416 RK3399_CLK_TX_DL_CFG_GMAC_MASK,
417 RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
418 RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
419 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
420 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
421}
422
David Wu672e4f22018-01-13 14:01:12 +0800423static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
424{
425 struct rv1108_grf *grf;
426
427 enum {
428 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
429 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4,
430 };
431
432 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
433 rk_clrsetreg(&grf->gmac_con0,
434 RV1108_GMAC_PHY_INTF_SEL_MASK,
435 RV1108_GMAC_PHY_INTF_SEL_RMII);
436}
437
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100438static int gmac_rockchip_probe(struct udevice *dev)
439{
440 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100441 struct rk_gmac_ops *ops =
442 (struct rk_gmac_ops *)dev_get_driver_data(dev);
David Wu672e4f22018-01-13 14:01:12 +0800443 struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
444 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100445 struct clk clk;
David Wu672e4f22018-01-13 14:01:12 +0800446 ulong rate;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100447 int ret;
448
449 ret = clk_get_by_index(dev, 0, &clk);
450 if (ret)
451 return ret;
452
David Wu672e4f22018-01-13 14:01:12 +0800453 switch (eth_pdata->phy_interface) {
454 case PHY_INTERFACE_MODE_RGMII:
455 /*
456 * If the gmac clock is from internal pll, need to set and
457 * check the return value for gmac clock at RGMII mode. If
458 * the gmac clock is from external source, the clock rate
459 * is not set, because of it is bypassed.
460 */
461 if (!pdata->clock_input) {
462 rate = clk_set_rate(&clk, 125000000);
463 if (rate != 125000000)
464 return -EINVAL;
465 }
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100466
David Wu672e4f22018-01-13 14:01:12 +0800467 /* Set to RGMII mode */
468 if (ops->set_to_rgmii)
469 ops->set_to_rgmii(pdata);
470 else
471 return -EPERM;
472
473 break;
474 case PHY_INTERFACE_MODE_RMII:
475 /* The commet is the same as RGMII mode */
476 if (!pdata->clock_input) {
477 rate = clk_set_rate(&clk, 50000000);
478 if (rate != 50000000)
479 return -EINVAL;
480 }
481
482 /* Set to RMII mode */
483 if (ops->set_to_rmii)
484 ops->set_to_rmii(pdata);
485 else
486 return -EPERM;
487
488 break;
489 default:
490 debug("NO interface defined!\n");
491 return -ENXIO;
492 }
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100493
494 return designware_eth_probe(dev);
495}
496
497static int gmac_rockchip_eth_start(struct udevice *dev)
498{
499 struct eth_pdata *pdata = dev_get_platdata(dev);
500 struct dw_eth_dev *priv = dev_get_priv(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100501 struct rk_gmac_ops *ops =
502 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100503 int ret;
504
505 ret = designware_eth_init(priv, pdata->enetaddr);
506 if (ret)
507 return ret;
Philipp Tomsich99cac582017-03-24 19:24:26 +0100508 ret = ops->fix_mac_speed(priv);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100509 if (ret)
510 return ret;
511 ret = designware_eth_enable(priv);
512 if (ret)
513 return ret;
514
515 return 0;
516}
517
518const struct eth_ops gmac_rockchip_eth_ops = {
519 .start = gmac_rockchip_eth_start,
520 .send = designware_eth_send,
521 .recv = designware_eth_recv,
522 .free_pkt = designware_eth_free_pkt,
523 .stop = designware_eth_stop,
524 .write_hwaddr = designware_eth_write_hwaddr,
525};
526
David Wuadcde492018-01-13 14:05:30 +0800527const struct rk_gmac_ops rk3228_gmac_ops = {
528 .fix_mac_speed = rk3228_gmac_fix_mac_speed,
529 .set_to_rgmii = rk3228_gmac_set_to_rgmii,
530};
531
Philipp Tomsich99cac582017-03-24 19:24:26 +0100532const struct rk_gmac_ops rk3288_gmac_ops = {
533 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
534 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
535};
536
David Wubac972b2018-01-13 14:03:04 +0800537const struct rk_gmac_ops rk3328_gmac_ops = {
538 .fix_mac_speed = rk3328_gmac_fix_mac_speed,
539 .set_to_rgmii = rk3328_gmac_set_to_rgmii,
540};
541
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200542const struct rk_gmac_ops rk3368_gmac_ops = {
543 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
544 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
545};
546
Philipp Tomsich99cac582017-03-24 19:24:26 +0100547const struct rk_gmac_ops rk3399_gmac_ops = {
548 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
549 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
550};
551
David Wu672e4f22018-01-13 14:01:12 +0800552const struct rk_gmac_ops rv1108_gmac_ops = {
553 .fix_mac_speed = rv1108_set_rmii_speed,
554 .set_to_rmii = rv1108_gmac_set_to_rmii,
555};
556
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100557static const struct udevice_id rockchip_gmac_ids[] = {
David Wuadcde492018-01-13 14:05:30 +0800558 { .compatible = "rockchip,rk3228-gmac",
559 .data = (ulong)&rk3228_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100560 { .compatible = "rockchip,rk3288-gmac",
561 .data = (ulong)&rk3288_gmac_ops },
David Wubac972b2018-01-13 14:03:04 +0800562 { .compatible = "rockchip,rk3328-gmac",
563 .data = (ulong)&rk3328_gmac_ops },
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200564 { .compatible = "rockchip,rk3368-gmac",
565 .data = (ulong)&rk3368_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100566 { .compatible = "rockchip,rk3399-gmac",
567 .data = (ulong)&rk3399_gmac_ops },
David Wu672e4f22018-01-13 14:01:12 +0800568 { .compatible = "rockchip,rv1108-gmac",
569 .data = (ulong)&rv1108_gmac_ops },
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100570 { }
571};
572
573U_BOOT_DRIVER(eth_gmac_rockchip) = {
574 .name = "gmac_rockchip",
575 .id = UCLASS_ETH,
576 .of_match = rockchip_gmac_ids,
577 .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
578 .probe = gmac_rockchip_probe,
579 .ops = &gmac_rockchip_eth_ops,
580 .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
581 .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
582 .flags = DM_FLAG_ALLOC_PRIV_DMA,
583};