blob: 30a24d1947e6bb76d07eaccc50f96582c05f9372 [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>
14#include <asm/arch/periph.h>
15#include <asm/arch/clock.h>
Philipp Tomsich99cac582017-03-24 19:24:26 +010016#include <asm/arch/hardware.h>
David Wuadcde492018-01-13 14:05:30 +080017#include <asm/arch/grf_rk322x.h>
Sjoerd Simons54c46f92017-01-11 11:46:11 +010018#include <asm/arch/grf_rk3288.h>
David Wubac972b2018-01-13 14:03:04 +080019#include <asm/arch/grf_rk3328.h>
Philipp Tomsich821c4c42017-07-25 17:02:51 +020020#include <asm/arch/grf_rk3368.h>
Philipp Tomsich99cac582017-03-24 19:24:26 +010021#include <asm/arch/grf_rk3399.h>
David Wu672e4f22018-01-13 14:01:12 +080022#include <asm/arch/grf_rv1108.h>
Sjoerd Simons54c46f92017-01-11 11:46:11 +010023#include <dm/pinctrl.h>
24#include <dt-bindings/clock/rk3288-cru.h>
25#include "designware.h"
26
Sjoerd Simons54c46f92017-01-11 11:46:11 +010027/*
28 * Platform data for the gmac
29 *
30 * dw_eth_pdata: Required platform data for designware driver (must be first)
31 */
32struct gmac_rockchip_platdata {
33 struct dw_eth_pdata dw_eth_pdata;
David Wu672e4f22018-01-13 14:01:12 +080034 bool clock_input;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010035 int tx_delay;
36 int rx_delay;
37};
38
Philipp Tomsich99cac582017-03-24 19:24:26 +010039struct rk_gmac_ops {
40 int (*fix_mac_speed)(struct dw_eth_dev *priv);
David Wu672e4f22018-01-13 14:01:12 +080041 void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
Philipp Tomsich99cac582017-03-24 19:24:26 +010042 void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
43};
44
45
Sjoerd Simons54c46f92017-01-11 11:46:11 +010046static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
47{
48 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
David Wu672e4f22018-01-13 14:01:12 +080049 const char *string;
50
51 string = dev_read_string(dev, "clock_in_out");
52 if (!strcmp(string, "input"))
53 pdata->clock_input = true;
54 else
55 pdata->clock_input = false;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010056
Philipp Tomsich99cac582017-03-24 19:24:26 +010057 /* Check the new naming-style first... */
Philipp Tomsich150005b2017-06-07 18:46:01 +020058 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
59 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
Philipp Tomsich99cac582017-03-24 19:24:26 +010060
61 /* ... and fall back to the old naming style or default, if necessary */
62 if (pdata->tx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020063 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
Philipp Tomsich99cac582017-03-24 19:24:26 +010064 if (pdata->rx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020065 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
Sjoerd Simons54c46f92017-01-11 11:46:11 +010066
67 return designware_eth_ofdata_to_platdata(dev);
68}
69
David Wuadcde492018-01-13 14:05:30 +080070static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
71{
72 struct rk322x_grf *grf;
73 int clk;
74 enum {
75 RK3228_GMAC_CLK_SEL_SHIFT = 8,
76 RK3228_GMAC_CLK_SEL_MASK = GENMASK(9, 8),
77 RK3228_GMAC_CLK_SEL_125M = 0 << 8,
78 RK3228_GMAC_CLK_SEL_25M = 3 << 8,
79 RK3228_GMAC_CLK_SEL_2_5M = 2 << 8,
80 };
81
82 switch (priv->phydev->speed) {
83 case 10:
84 clk = RK3228_GMAC_CLK_SEL_2_5M;
85 break;
86 case 100:
87 clk = RK3228_GMAC_CLK_SEL_25M;
88 break;
89 case 1000:
90 clk = RK3228_GMAC_CLK_SEL_125M;
91 break;
92 default:
93 debug("Unknown phy speed: %d\n", priv->phydev->speed);
94 return -EINVAL;
95 }
96
97 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
98 rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk);
99
100 return 0;
101}
102
Philipp Tomsich99cac582017-03-24 19:24:26 +0100103static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100104{
105 struct rk3288_grf *grf;
106 int clk;
107
108 switch (priv->phydev->speed) {
109 case 10:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100110 clk = RK3288_GMAC_CLK_SEL_2_5M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100111 break;
112 case 100:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100113 clk = RK3288_GMAC_CLK_SEL_25M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100114 break;
115 case 1000:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100116 clk = RK3288_GMAC_CLK_SEL_125M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100117 break;
118 default:
119 debug("Unknown phy speed: %d\n", priv->phydev->speed);
120 return -EINVAL;
121 }
122
123 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100124 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
125
126 return 0;
127}
128
David Wubac972b2018-01-13 14:03:04 +0800129static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
130{
131 struct rk3328_grf_regs *grf;
132 int clk;
133 enum {
134 RK3328_GMAC_CLK_SEL_SHIFT = 11,
135 RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11),
136 RK3328_GMAC_CLK_SEL_125M = 0 << 11,
137 RK3328_GMAC_CLK_SEL_25M = 3 << 11,
138 RK3328_GMAC_CLK_SEL_2_5M = 2 << 11,
139 };
140
141 switch (priv->phydev->speed) {
142 case 10:
143 clk = RK3328_GMAC_CLK_SEL_2_5M;
144 break;
145 case 100:
146 clk = RK3328_GMAC_CLK_SEL_25M;
147 break;
148 case 1000:
149 clk = RK3328_GMAC_CLK_SEL_125M;
150 break;
151 default:
152 debug("Unknown phy speed: %d\n", priv->phydev->speed);
153 return -EINVAL;
154 }
155
156 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
157 rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
158
159 return 0;
160}
161
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200162static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
163{
164 struct rk3368_grf *grf;
165 int clk;
166 enum {
167 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
168 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
169 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
170 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
171 };
172
173 switch (priv->phydev->speed) {
174 case 10:
175 clk = RK3368_GMAC_CLK_SEL_2_5M;
176 break;
177 case 100:
178 clk = RK3368_GMAC_CLK_SEL_25M;
179 break;
180 case 1000:
181 clk = RK3368_GMAC_CLK_SEL_125M;
182 break;
183 default:
184 debug("Unknown phy speed: %d\n", priv->phydev->speed);
185 return -EINVAL;
186 }
187
188 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
189 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
190
191 return 0;
192}
193
Philipp Tomsich99cac582017-03-24 19:24:26 +0100194static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
195{
196 struct rk3399_grf_regs *grf;
197 int clk;
198
199 switch (priv->phydev->speed) {
200 case 10:
201 clk = RK3399_GMAC_CLK_SEL_2_5M;
202 break;
203 case 100:
204 clk = RK3399_GMAC_CLK_SEL_25M;
205 break;
206 case 1000:
207 clk = RK3399_GMAC_CLK_SEL_125M;
208 break;
209 default:
210 debug("Unknown phy speed: %d\n", priv->phydev->speed);
211 return -EINVAL;
212 }
213
214 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
215 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100216
217 return 0;
218}
219
David Wu672e4f22018-01-13 14:01:12 +0800220static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
221{
222 struct rv1108_grf *grf;
223 int clk, speed;
224 enum {
225 RV1108_GMAC_SPEED_MASK = BIT(2),
226 RV1108_GMAC_SPEED_10M = 0 << 2,
227 RV1108_GMAC_SPEED_100M = 1 << 2,
228 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
229 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
230 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
231 };
232
233 switch (priv->phydev->speed) {
234 case 10:
235 clk = RV1108_GMAC_CLK_SEL_2_5M;
236 speed = RV1108_GMAC_SPEED_10M;
237 break;
238 case 100:
239 clk = RV1108_GMAC_CLK_SEL_25M;
240 speed = RV1108_GMAC_SPEED_100M;
241 break;
242 default:
243 debug("Unknown phy speed: %d\n", priv->phydev->speed);
244 return -EINVAL;
245 }
246
247 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
248 rk_clrsetreg(&grf->gmac_con0,
249 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
250 clk | speed);
251
252 return 0;
253}
254
David Wuadcde492018-01-13 14:05:30 +0800255static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
256{
257 struct rk322x_grf *grf;
258 enum {
259 RK3228_RMII_MODE_SHIFT = 10,
260 RK3228_RMII_MODE_MASK = BIT(10),
261
262 RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
263 RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
264 RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
265
266 RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
267 RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
268 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
269
270 RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
271 RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
272 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
273 };
274 enum {
275 RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
276 RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
277
278 RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
279 RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
280 };
281
282 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
283 rk_clrsetreg(&grf->mac_con[1],
284 RK3228_RMII_MODE_MASK |
285 RK3228_GMAC_PHY_INTF_SEL_MASK |
286 RK3228_RXCLK_DLY_ENA_GMAC_MASK |
287 RK3228_TXCLK_DLY_ENA_GMAC_MASK,
288 RK3228_GMAC_PHY_INTF_SEL_RGMII |
289 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE |
290 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE);
291
292 rk_clrsetreg(&grf->mac_con[0],
293 RK3228_CLK_RX_DL_CFG_GMAC_MASK |
294 RK3228_CLK_TX_DL_CFG_GMAC_MASK,
295 pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
296 pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
297}
298
Philipp Tomsich99cac582017-03-24 19:24:26 +0100299static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
300{
301 struct rk3288_grf *grf;
302
303 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
304 rk_clrsetreg(&grf->soc_con1,
305 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
306 RK3288_GMAC_PHY_INTF_SEL_RGMII);
307
308 rk_clrsetreg(&grf->soc_con3,
309 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
310 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
311 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
312 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
313 RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
314 RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
315 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
316 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
317}
318
David Wubac972b2018-01-13 14:03:04 +0800319static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
320{
321 struct rk3328_grf_regs *grf;
322 enum {
323 RK3328_RMII_MODE_SHIFT = 9,
324 RK3328_RMII_MODE_MASK = BIT(9),
325
326 RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4,
327 RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
328 RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
329
330 RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
331 RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
332 RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
333
334 RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
335 RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
336 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
337 };
338 enum {
339 RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
340 RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
341
342 RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
343 RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
344 };
345
346 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
347 rk_clrsetreg(&grf->mac_con[1],
348 RK3328_RMII_MODE_MASK |
349 RK3328_GMAC_PHY_INTF_SEL_MASK |
350 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
351 RK3328_TXCLK_DLY_ENA_GMAC_MASK,
352 RK3328_GMAC_PHY_INTF_SEL_RGMII |
353 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
354 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE);
355
356 rk_clrsetreg(&grf->mac_con[0],
357 RK3328_CLK_RX_DL_CFG_GMAC_MASK |
358 RK3328_CLK_TX_DL_CFG_GMAC_MASK,
359 pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
360 pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
361}
362
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200363static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
364{
365 struct rk3368_grf *grf;
366 enum {
367 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
368 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
369 RK3368_RMII_MODE_MASK = BIT(6),
370 RK3368_RMII_MODE = BIT(6),
371 };
372 enum {
373 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
374 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
375 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
376 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
377 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
378 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
379 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
380 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
381 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
382 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
383 };
384
385 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
386 rk_clrsetreg(&grf->soc_con15,
387 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
388 RK3368_GMAC_PHY_INTF_SEL_RGMII);
389
390 rk_clrsetreg(&grf->soc_con16,
391 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
392 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
393 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
394 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
395 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE |
396 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE |
397 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
398 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
399}
400
Philipp Tomsich99cac582017-03-24 19:24:26 +0100401static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
402{
403 struct rk3399_grf_regs *grf;
404
405 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
406
407 rk_clrsetreg(&grf->soc_con5,
408 RK3399_GMAC_PHY_INTF_SEL_MASK,
409 RK3399_GMAC_PHY_INTF_SEL_RGMII);
410
411 rk_clrsetreg(&grf->soc_con6,
412 RK3399_RXCLK_DLY_ENA_GMAC_MASK |
413 RK3399_TXCLK_DLY_ENA_GMAC_MASK |
414 RK3399_CLK_RX_DL_CFG_GMAC_MASK |
415 RK3399_CLK_TX_DL_CFG_GMAC_MASK,
416 RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
417 RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
418 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
419 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
420}
421
David Wu672e4f22018-01-13 14:01:12 +0800422static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
423{
424 struct rv1108_grf *grf;
425
426 enum {
427 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
428 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4,
429 };
430
431 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
432 rk_clrsetreg(&grf->gmac_con0,
433 RV1108_GMAC_PHY_INTF_SEL_MASK,
434 RV1108_GMAC_PHY_INTF_SEL_RMII);
435}
436
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100437static int gmac_rockchip_probe(struct udevice *dev)
438{
439 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100440 struct rk_gmac_ops *ops =
441 (struct rk_gmac_ops *)dev_get_driver_data(dev);
David Wu672e4f22018-01-13 14:01:12 +0800442 struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
443 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100444 struct clk clk;
David Wu672e4f22018-01-13 14:01:12 +0800445 ulong rate;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100446 int ret;
447
448 ret = clk_get_by_index(dev, 0, &clk);
449 if (ret)
450 return ret;
451
David Wu672e4f22018-01-13 14:01:12 +0800452 switch (eth_pdata->phy_interface) {
453 case PHY_INTERFACE_MODE_RGMII:
454 /*
455 * If the gmac clock is from internal pll, need to set and
456 * check the return value for gmac clock at RGMII mode. If
457 * the gmac clock is from external source, the clock rate
458 * is not set, because of it is bypassed.
459 */
460 if (!pdata->clock_input) {
461 rate = clk_set_rate(&clk, 125000000);
462 if (rate != 125000000)
463 return -EINVAL;
464 }
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100465
David Wu672e4f22018-01-13 14:01:12 +0800466 /* Set to RGMII mode */
467 if (ops->set_to_rgmii)
468 ops->set_to_rgmii(pdata);
469 else
470 return -EPERM;
471
472 break;
473 case PHY_INTERFACE_MODE_RMII:
474 /* The commet is the same as RGMII mode */
475 if (!pdata->clock_input) {
476 rate = clk_set_rate(&clk, 50000000);
477 if (rate != 50000000)
478 return -EINVAL;
479 }
480
481 /* Set to RMII mode */
482 if (ops->set_to_rmii)
483 ops->set_to_rmii(pdata);
484 else
485 return -EPERM;
486
487 break;
488 default:
489 debug("NO interface defined!\n");
490 return -ENXIO;
491 }
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100492
493 return designware_eth_probe(dev);
494}
495
496static int gmac_rockchip_eth_start(struct udevice *dev)
497{
498 struct eth_pdata *pdata = dev_get_platdata(dev);
499 struct dw_eth_dev *priv = dev_get_priv(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100500 struct rk_gmac_ops *ops =
501 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100502 int ret;
503
504 ret = designware_eth_init(priv, pdata->enetaddr);
505 if (ret)
506 return ret;
Philipp Tomsich99cac582017-03-24 19:24:26 +0100507 ret = ops->fix_mac_speed(priv);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100508 if (ret)
509 return ret;
510 ret = designware_eth_enable(priv);
511 if (ret)
512 return ret;
513
514 return 0;
515}
516
517const struct eth_ops gmac_rockchip_eth_ops = {
518 .start = gmac_rockchip_eth_start,
519 .send = designware_eth_send,
520 .recv = designware_eth_recv,
521 .free_pkt = designware_eth_free_pkt,
522 .stop = designware_eth_stop,
523 .write_hwaddr = designware_eth_write_hwaddr,
524};
525
David Wuadcde492018-01-13 14:05:30 +0800526const struct rk_gmac_ops rk3228_gmac_ops = {
527 .fix_mac_speed = rk3228_gmac_fix_mac_speed,
528 .set_to_rgmii = rk3228_gmac_set_to_rgmii,
529};
530
Philipp Tomsich99cac582017-03-24 19:24:26 +0100531const struct rk_gmac_ops rk3288_gmac_ops = {
532 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
533 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
534};
535
David Wubac972b2018-01-13 14:03:04 +0800536const struct rk_gmac_ops rk3328_gmac_ops = {
537 .fix_mac_speed = rk3328_gmac_fix_mac_speed,
538 .set_to_rgmii = rk3328_gmac_set_to_rgmii,
539};
540
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200541const struct rk_gmac_ops rk3368_gmac_ops = {
542 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
543 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
544};
545
Philipp Tomsich99cac582017-03-24 19:24:26 +0100546const struct rk_gmac_ops rk3399_gmac_ops = {
547 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
548 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
549};
550
David Wu672e4f22018-01-13 14:01:12 +0800551const struct rk_gmac_ops rv1108_gmac_ops = {
552 .fix_mac_speed = rv1108_set_rmii_speed,
553 .set_to_rmii = rv1108_gmac_set_to_rmii,
554};
555
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100556static const struct udevice_id rockchip_gmac_ids[] = {
David Wuadcde492018-01-13 14:05:30 +0800557 { .compatible = "rockchip,rk3228-gmac",
558 .data = (ulong)&rk3228_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100559 { .compatible = "rockchip,rk3288-gmac",
560 .data = (ulong)&rk3288_gmac_ops },
David Wubac972b2018-01-13 14:03:04 +0800561 { .compatible = "rockchip,rk3328-gmac",
562 .data = (ulong)&rk3328_gmac_ops },
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200563 { .compatible = "rockchip,rk3368-gmac",
564 .data = (ulong)&rk3368_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100565 { .compatible = "rockchip,rk3399-gmac",
566 .data = (ulong)&rk3399_gmac_ops },
David Wu672e4f22018-01-13 14:01:12 +0800567 { .compatible = "rockchip,rv1108-gmac",
568 .data = (ulong)&rv1108_gmac_ops },
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100569 { }
570};
571
572U_BOOT_DRIVER(eth_gmac_rockchip) = {
573 .name = "gmac_rockchip",
574 .id = UCLASS_ETH,
575 .of_match = rockchip_gmac_ids,
576 .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
577 .probe = gmac_rockchip_probe,
578 .ops = &gmac_rockchip_eth_ops,
579 .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
580 .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
581 .flags = DM_FLAG_ALLOC_PRIV_DMA,
582};