blob: 683e820108f9a2a4ec60cc14ad1345520621b5bb [file] [log] [blame]
Sjoerd Simons0125bcf2017-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 Tomsich1f08aa12017-03-24 19:24:26 +010017#include <asm/arch/hardware.h>
David Wud12d7c02018-01-13 14:05:30 +080018#include <asm/arch/grf_rk322x.h>
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010019#include <asm/arch/grf_rk3288.h>
David Wub3d2a6d2018-01-13 14:03:04 +080020#include <asm/arch/grf_rk3328.h>
Philipp Tomsich793f2fd2017-07-25 17:02:51 +020021#include <asm/arch/grf_rk3368.h>
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010022#include <asm/arch/grf_rk3399.h>
David Wucaf74612018-01-13 14:01:12 +080023#include <asm/arch/grf_rv1108.h>
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010024#include <dm/pinctrl.h>
25#include <dt-bindings/clock/rk3288-cru.h>
26#include "designware.h"
27
28DECLARE_GLOBAL_DATA_PTR;
29
30/*
31 * Platform data for the gmac
32 *
33 * dw_eth_pdata: Required platform data for designware driver (must be first)
34 */
35struct gmac_rockchip_platdata {
36 struct dw_eth_pdata dw_eth_pdata;
David Wucaf74612018-01-13 14:01:12 +080037 bool clock_input;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010038 int tx_delay;
39 int rx_delay;
40};
41
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010042struct rk_gmac_ops {
43 int (*fix_mac_speed)(struct dw_eth_dev *priv);
David Wucaf74612018-01-13 14:01:12 +080044 void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010045 void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
46};
47
48
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010049static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
50{
51 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
David Wucaf74612018-01-13 14:01:12 +080052 const char *string;
53
54 string = dev_read_string(dev, "clock_in_out");
55 if (!strcmp(string, "input"))
56 pdata->clock_input = true;
57 else
58 pdata->clock_input = false;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010059
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010060 /* Check the new naming-style first... */
Philipp Tomsich7ad326a2017-06-07 18:46:01 +020061 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
62 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010063
64 /* ... and fall back to the old naming style or default, if necessary */
65 if (pdata->tx_delay == -ENOENT)
Philipp Tomsich7ad326a2017-06-07 18:46:01 +020066 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +010067 if (pdata->rx_delay == -ENOENT)
Philipp Tomsich7ad326a2017-06-07 18:46:01 +020068 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
Sjoerd Simons0125bcf2017-01-11 11:46:11 +010069
70 return designware_eth_ofdata_to_platdata(dev);
71}
72
David Wud12d7c02018-01-13 14:05:30 +080073static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
74{
75 struct rk322x_grf *grf;
76 int clk;
77 enum {
78 RK3228_GMAC_CLK_SEL_SHIFT = 8,
79 RK3228_GMAC_CLK_SEL_MASK = GENMASK(9, 8),
80 RK3228_GMAC_CLK_SEL_125M = 0 << 8,
81 RK3228_GMAC_CLK_SEL_25M = 3 << 8,
82 RK3228_GMAC_CLK_SEL_2_5M = 2 << 8,
83 };
84
85 switch (priv->phydev->speed) {
86 case 10:
87 clk = RK3228_GMAC_CLK_SEL_2_5M;
88 break;
89 case 100:
90 clk = RK3228_GMAC_CLK_SEL_25M;
91 break;
92 case 1000:
93 clk = RK3228_GMAC_CLK_SEL_125M;
94 break;
95 default:
96 debug("Unknown phy speed: %d\n", priv->phydev->speed);
97 return -EINVAL;
98 }
99
100 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
101 rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk);
102
103 return 0;
104}
105
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100106static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100107{
108 struct rk3288_grf *grf;
109 int clk;
110
111 switch (priv->phydev->speed) {
112 case 10:
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100113 clk = RK3288_GMAC_CLK_SEL_2_5M;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100114 break;
115 case 100:
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100116 clk = RK3288_GMAC_CLK_SEL_25M;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100117 break;
118 case 1000:
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100119 clk = RK3288_GMAC_CLK_SEL_125M;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100120 break;
121 default:
122 debug("Unknown phy speed: %d\n", priv->phydev->speed);
123 return -EINVAL;
124 }
125
126 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100127 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100128
129 return 0;
130}
131
David Wub3d2a6d2018-01-13 14:03:04 +0800132static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
133{
134 struct rk3328_grf_regs *grf;
135 int clk;
136 enum {
137 RK3328_GMAC_CLK_SEL_SHIFT = 11,
138 RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11),
139 RK3328_GMAC_CLK_SEL_125M = 0 << 11,
140 RK3328_GMAC_CLK_SEL_25M = 3 << 11,
141 RK3328_GMAC_CLK_SEL_2_5M = 2 << 11,
142 };
143
144 switch (priv->phydev->speed) {
145 case 10:
146 clk = RK3328_GMAC_CLK_SEL_2_5M;
147 break;
148 case 100:
149 clk = RK3328_GMAC_CLK_SEL_25M;
150 break;
151 case 1000:
152 clk = RK3328_GMAC_CLK_SEL_125M;
153 break;
154 default:
155 debug("Unknown phy speed: %d\n", priv->phydev->speed);
156 return -EINVAL;
157 }
158
159 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
160 rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
161
162 return 0;
163}
164
Philipp Tomsich793f2fd2017-07-25 17:02:51 +0200165static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
166{
167 struct rk3368_grf *grf;
168 int clk;
169 enum {
170 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
171 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
172 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
173 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
174 };
175
176 switch (priv->phydev->speed) {
177 case 10:
178 clk = RK3368_GMAC_CLK_SEL_2_5M;
179 break;
180 case 100:
181 clk = RK3368_GMAC_CLK_SEL_25M;
182 break;
183 case 1000:
184 clk = RK3368_GMAC_CLK_SEL_125M;
185 break;
186 default:
187 debug("Unknown phy speed: %d\n", priv->phydev->speed);
188 return -EINVAL;
189 }
190
191 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
192 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
193
194 return 0;
195}
196
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100197static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
198{
199 struct rk3399_grf_regs *grf;
200 int clk;
201
202 switch (priv->phydev->speed) {
203 case 10:
204 clk = RK3399_GMAC_CLK_SEL_2_5M;
205 break;
206 case 100:
207 clk = RK3399_GMAC_CLK_SEL_25M;
208 break;
209 case 1000:
210 clk = RK3399_GMAC_CLK_SEL_125M;
211 break;
212 default:
213 debug("Unknown phy speed: %d\n", priv->phydev->speed);
214 return -EINVAL;
215 }
216
217 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
218 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
219
220 return 0;
221}
222
David Wucaf74612018-01-13 14:01:12 +0800223static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
224{
225 struct rv1108_grf *grf;
226 int clk, speed;
227 enum {
228 RV1108_GMAC_SPEED_MASK = BIT(2),
229 RV1108_GMAC_SPEED_10M = 0 << 2,
230 RV1108_GMAC_SPEED_100M = 1 << 2,
231 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
232 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
233 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
234 };
235
236 switch (priv->phydev->speed) {
237 case 10:
238 clk = RV1108_GMAC_CLK_SEL_2_5M;
239 speed = RV1108_GMAC_SPEED_10M;
240 break;
241 case 100:
242 clk = RV1108_GMAC_CLK_SEL_25M;
243 speed = RV1108_GMAC_SPEED_100M;
244 break;
245 default:
246 debug("Unknown phy speed: %d\n", priv->phydev->speed);
247 return -EINVAL;
248 }
249
250 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
251 rk_clrsetreg(&grf->gmac_con0,
252 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
253 clk | speed);
254
255 return 0;
256}
257
David Wud12d7c02018-01-13 14:05:30 +0800258static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
259{
260 struct rk322x_grf *grf;
261 enum {
262 RK3228_RMII_MODE_SHIFT = 10,
263 RK3228_RMII_MODE_MASK = BIT(10),
264
265 RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
266 RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
267 RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
268
269 RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
270 RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
271 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
272
273 RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
274 RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
275 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
276 };
277 enum {
278 RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
279 RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
280
281 RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
282 RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
283 };
284
285 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
286 rk_clrsetreg(&grf->mac_con[1],
287 RK3228_RMII_MODE_MASK |
288 RK3228_GMAC_PHY_INTF_SEL_MASK |
289 RK3228_RXCLK_DLY_ENA_GMAC_MASK |
290 RK3228_TXCLK_DLY_ENA_GMAC_MASK,
291 RK3228_GMAC_PHY_INTF_SEL_RGMII |
292 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE |
293 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE);
294
295 rk_clrsetreg(&grf->mac_con[0],
296 RK3228_CLK_RX_DL_CFG_GMAC_MASK |
297 RK3228_CLK_TX_DL_CFG_GMAC_MASK,
298 pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
299 pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
300}
301
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100302static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
303{
304 struct rk3288_grf *grf;
305
306 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
307 rk_clrsetreg(&grf->soc_con1,
308 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
309 RK3288_GMAC_PHY_INTF_SEL_RGMII);
310
311 rk_clrsetreg(&grf->soc_con3,
312 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
313 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
314 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
315 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
316 RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
317 RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
318 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
319 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
320}
321
David Wub3d2a6d2018-01-13 14:03:04 +0800322static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
323{
324 struct rk3328_grf_regs *grf;
325 enum {
326 RK3328_RMII_MODE_SHIFT = 9,
327 RK3328_RMII_MODE_MASK = BIT(9),
328
329 RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4,
330 RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
331 RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
332
333 RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
334 RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
335 RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
336
337 RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
338 RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
339 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
340 };
341 enum {
342 RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
343 RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
344
345 RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
346 RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
347 };
348
349 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
350 rk_clrsetreg(&grf->mac_con[1],
351 RK3328_RMII_MODE_MASK |
352 RK3328_GMAC_PHY_INTF_SEL_MASK |
353 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
354 RK3328_TXCLK_DLY_ENA_GMAC_MASK,
355 RK3328_GMAC_PHY_INTF_SEL_RGMII |
356 RK3328_RXCLK_DLY_ENA_GMAC_MASK |
357 RK3328_TXCLK_DLY_ENA_GMAC_ENABLE);
358
359 rk_clrsetreg(&grf->mac_con[0],
360 RK3328_CLK_RX_DL_CFG_GMAC_MASK |
361 RK3328_CLK_TX_DL_CFG_GMAC_MASK,
362 pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
363 pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
364}
365
Philipp Tomsich793f2fd2017-07-25 17:02:51 +0200366static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
367{
368 struct rk3368_grf *grf;
369 enum {
370 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
371 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
372 RK3368_RMII_MODE_MASK = BIT(6),
373 RK3368_RMII_MODE = BIT(6),
374 };
375 enum {
376 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
377 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
378 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
379 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
380 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
381 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
382 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
383 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
384 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
385 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
386 };
387
388 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
389 rk_clrsetreg(&grf->soc_con15,
390 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
391 RK3368_GMAC_PHY_INTF_SEL_RGMII);
392
393 rk_clrsetreg(&grf->soc_con16,
394 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
395 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
396 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
397 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
398 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE |
399 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE |
400 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
401 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
402}
403
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100404static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
405{
406 struct rk3399_grf_regs *grf;
407
408 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
409
410 rk_clrsetreg(&grf->soc_con5,
411 RK3399_GMAC_PHY_INTF_SEL_MASK,
412 RK3399_GMAC_PHY_INTF_SEL_RGMII);
413
414 rk_clrsetreg(&grf->soc_con6,
415 RK3399_RXCLK_DLY_ENA_GMAC_MASK |
416 RK3399_TXCLK_DLY_ENA_GMAC_MASK |
417 RK3399_CLK_RX_DL_CFG_GMAC_MASK |
418 RK3399_CLK_TX_DL_CFG_GMAC_MASK,
419 RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
420 RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
421 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
422 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
423}
424
David Wucaf74612018-01-13 14:01:12 +0800425static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
426{
427 struct rv1108_grf *grf;
428
429 enum {
430 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
431 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4,
432 };
433
434 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
435 rk_clrsetreg(&grf->gmac_con0,
436 RV1108_GMAC_PHY_INTF_SEL_MASK,
437 RV1108_GMAC_PHY_INTF_SEL_RMII);
438}
439
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100440static int gmac_rockchip_probe(struct udevice *dev)
441{
442 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100443 struct rk_gmac_ops *ops =
444 (struct rk_gmac_ops *)dev_get_driver_data(dev);
David Wucaf74612018-01-13 14:01:12 +0800445 struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
446 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100447 struct clk clk;
David Wucaf74612018-01-13 14:01:12 +0800448 ulong rate;
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100449 int ret;
450
451 ret = clk_get_by_index(dev, 0, &clk);
452 if (ret)
453 return ret;
454
David Wucaf74612018-01-13 14:01:12 +0800455 switch (eth_pdata->phy_interface) {
456 case PHY_INTERFACE_MODE_RGMII:
457 /*
458 * If the gmac clock is from internal pll, need to set and
459 * check the return value for gmac clock at RGMII mode. If
460 * the gmac clock is from external source, the clock rate
461 * is not set, because of it is bypassed.
462 */
463 if (!pdata->clock_input) {
464 rate = clk_set_rate(&clk, 125000000);
465 if (rate != 125000000)
466 return -EINVAL;
467 }
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100468
David Wucaf74612018-01-13 14:01:12 +0800469 /* Set to RGMII mode */
470 if (ops->set_to_rgmii)
471 ops->set_to_rgmii(pdata);
472 else
473 return -EPERM;
474
475 break;
476 case PHY_INTERFACE_MODE_RMII:
477 /* The commet is the same as RGMII mode */
478 if (!pdata->clock_input) {
479 rate = clk_set_rate(&clk, 50000000);
480 if (rate != 50000000)
481 return -EINVAL;
482 }
483
484 /* Set to RMII mode */
485 if (ops->set_to_rmii)
486 ops->set_to_rmii(pdata);
487 else
488 return -EPERM;
489
490 break;
491 default:
492 debug("NO interface defined!\n");
493 return -ENXIO;
494 }
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100495
496 return designware_eth_probe(dev);
497}
498
499static int gmac_rockchip_eth_start(struct udevice *dev)
500{
501 struct eth_pdata *pdata = dev_get_platdata(dev);
502 struct dw_eth_dev *priv = dev_get_priv(dev);
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100503 struct rk_gmac_ops *ops =
504 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100505 int ret;
506
507 ret = designware_eth_init(priv, pdata->enetaddr);
508 if (ret)
509 return ret;
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100510 ret = ops->fix_mac_speed(priv);
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100511 if (ret)
512 return ret;
513 ret = designware_eth_enable(priv);
514 if (ret)
515 return ret;
516
517 return 0;
518}
519
520const struct eth_ops gmac_rockchip_eth_ops = {
521 .start = gmac_rockchip_eth_start,
522 .send = designware_eth_send,
523 .recv = designware_eth_recv,
524 .free_pkt = designware_eth_free_pkt,
525 .stop = designware_eth_stop,
526 .write_hwaddr = designware_eth_write_hwaddr,
527};
528
David Wud12d7c02018-01-13 14:05:30 +0800529const struct rk_gmac_ops rk3228_gmac_ops = {
530 .fix_mac_speed = rk3228_gmac_fix_mac_speed,
531 .set_to_rgmii = rk3228_gmac_set_to_rgmii,
532};
533
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100534const struct rk_gmac_ops rk3288_gmac_ops = {
535 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
536 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
537};
538
David Wub3d2a6d2018-01-13 14:03:04 +0800539const struct rk_gmac_ops rk3328_gmac_ops = {
540 .fix_mac_speed = rk3328_gmac_fix_mac_speed,
541 .set_to_rgmii = rk3328_gmac_set_to_rgmii,
542};
543
Philipp Tomsich793f2fd2017-07-25 17:02:51 +0200544const struct rk_gmac_ops rk3368_gmac_ops = {
545 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
546 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
547};
548
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100549const struct rk_gmac_ops rk3399_gmac_ops = {
550 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
551 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
552};
553
David Wucaf74612018-01-13 14:01:12 +0800554const struct rk_gmac_ops rv1108_gmac_ops = {
555 .fix_mac_speed = rv1108_set_rmii_speed,
556 .set_to_rmii = rv1108_gmac_set_to_rmii,
557};
558
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100559static const struct udevice_id rockchip_gmac_ids[] = {
David Wud12d7c02018-01-13 14:05:30 +0800560 { .compatible = "rockchip,rk3228-gmac",
561 .data = (ulong)&rk3228_gmac_ops },
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100562 { .compatible = "rockchip,rk3288-gmac",
563 .data = (ulong)&rk3288_gmac_ops },
David Wub3d2a6d2018-01-13 14:03:04 +0800564 { .compatible = "rockchip,rk3328-gmac",
565 .data = (ulong)&rk3328_gmac_ops },
Philipp Tomsich793f2fd2017-07-25 17:02:51 +0200566 { .compatible = "rockchip,rk3368-gmac",
567 .data = (ulong)&rk3368_gmac_ops },
Philipp Tomsich1f08aa12017-03-24 19:24:26 +0100568 { .compatible = "rockchip,rk3399-gmac",
569 .data = (ulong)&rk3399_gmac_ops },
David Wucaf74612018-01-13 14:01:12 +0800570 { .compatible = "rockchip,rv1108-gmac",
571 .data = (ulong)&rv1108_gmac_ops },
Sjoerd Simons0125bcf2017-01-11 11:46:11 +0100572 { }
573};
574
575U_BOOT_DRIVER(eth_gmac_rockchip) = {
576 .name = "gmac_rockchip",
577 .id = UCLASS_ETH,
578 .of_match = rockchip_gmac_ids,
579 .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
580 .probe = gmac_rockchip_probe,
581 .ops = &gmac_rockchip_eth_ops,
582 .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
583 .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
584 .flags = DM_FLAG_ALLOC_PRIV_DMA,
585};