blob: 26a612117506bf4059654cb48648bd290badab67 [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>
17#include <asm/arch-rockchip/grf_rk322x.h>
18#include <asm/arch-rockchip/grf_rk3288.h>
19#include <asm/arch-rockchip/grf_rk3328.h>
20#include <asm/arch-rockchip/grf_rk3368.h>
21#include <asm/arch-rockchip/grf_rk3399.h>
22#include <asm/arch-rockchip/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
Janine Hagemannb6a6dc82018-08-28 08:25:05 +020027DECLARE_GLOBAL_DATA_PTR;
28#define DELAY_ENABLE(soc, tx, rx) \
29 (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \
30 ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE))
31
Sjoerd Simons54c46f92017-01-11 11:46:11 +010032/*
33 * Platform data for the gmac
34 *
35 * dw_eth_pdata: Required platform data for designware driver (must be first)
36 */
37struct gmac_rockchip_platdata {
38 struct dw_eth_pdata dw_eth_pdata;
David Wu672e4f22018-01-13 14:01:12 +080039 bool clock_input;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010040 int tx_delay;
41 int rx_delay;
42};
43
Philipp Tomsich99cac582017-03-24 19:24:26 +010044struct rk_gmac_ops {
45 int (*fix_mac_speed)(struct dw_eth_dev *priv);
David Wu672e4f22018-01-13 14:01:12 +080046 void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
Philipp Tomsich99cac582017-03-24 19:24:26 +010047 void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
48};
49
50
Sjoerd Simons54c46f92017-01-11 11:46:11 +010051static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
52{
53 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
David Wu672e4f22018-01-13 14:01:12 +080054 const char *string;
55
56 string = dev_read_string(dev, "clock_in_out");
57 if (!strcmp(string, "input"))
58 pdata->clock_input = true;
59 else
60 pdata->clock_input = false;
Sjoerd Simons54c46f92017-01-11 11:46:11 +010061
Philipp Tomsich99cac582017-03-24 19:24:26 +010062 /* Check the new naming-style first... */
Philipp Tomsich150005b2017-06-07 18:46:01 +020063 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
64 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
Philipp Tomsich99cac582017-03-24 19:24:26 +010065
66 /* ... and fall back to the old naming style or default, if necessary */
67 if (pdata->tx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020068 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
Philipp Tomsich99cac582017-03-24 19:24:26 +010069 if (pdata->rx_delay == -ENOENT)
Philipp Tomsich150005b2017-06-07 18:46:01 +020070 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
Sjoerd Simons54c46f92017-01-11 11:46:11 +010071
72 return designware_eth_ofdata_to_platdata(dev);
73}
74
David Wuadcde492018-01-13 14:05:30 +080075static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
76{
77 struct rk322x_grf *grf;
78 int clk;
79 enum {
80 RK3228_GMAC_CLK_SEL_SHIFT = 8,
81 RK3228_GMAC_CLK_SEL_MASK = GENMASK(9, 8),
82 RK3228_GMAC_CLK_SEL_125M = 0 << 8,
83 RK3228_GMAC_CLK_SEL_25M = 3 << 8,
84 RK3228_GMAC_CLK_SEL_2_5M = 2 << 8,
85 };
86
87 switch (priv->phydev->speed) {
88 case 10:
89 clk = RK3228_GMAC_CLK_SEL_2_5M;
90 break;
91 case 100:
92 clk = RK3228_GMAC_CLK_SEL_25M;
93 break;
94 case 1000:
95 clk = RK3228_GMAC_CLK_SEL_125M;
96 break;
97 default:
98 debug("Unknown phy speed: %d\n", priv->phydev->speed);
99 return -EINVAL;
100 }
101
102 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
103 rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk);
104
105 return 0;
106}
107
Philipp Tomsich99cac582017-03-24 19:24:26 +0100108static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100109{
110 struct rk3288_grf *grf;
111 int clk;
112
113 switch (priv->phydev->speed) {
114 case 10:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100115 clk = RK3288_GMAC_CLK_SEL_2_5M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100116 break;
117 case 100:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100118 clk = RK3288_GMAC_CLK_SEL_25M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100119 break;
120 case 1000:
Philipp Tomsich99cac582017-03-24 19:24:26 +0100121 clk = RK3288_GMAC_CLK_SEL_125M;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100122 break;
123 default:
124 debug("Unknown phy speed: %d\n", priv->phydev->speed);
125 return -EINVAL;
126 }
127
128 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100129 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
130
131 return 0;
132}
133
David Wubac972b2018-01-13 14:03:04 +0800134static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
135{
136 struct rk3328_grf_regs *grf;
137 int clk;
138 enum {
139 RK3328_GMAC_CLK_SEL_SHIFT = 11,
140 RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11),
141 RK3328_GMAC_CLK_SEL_125M = 0 << 11,
142 RK3328_GMAC_CLK_SEL_25M = 3 << 11,
143 RK3328_GMAC_CLK_SEL_2_5M = 2 << 11,
144 };
145
146 switch (priv->phydev->speed) {
147 case 10:
148 clk = RK3328_GMAC_CLK_SEL_2_5M;
149 break;
150 case 100:
151 clk = RK3328_GMAC_CLK_SEL_25M;
152 break;
153 case 1000:
154 clk = RK3328_GMAC_CLK_SEL_125M;
155 break;
156 default:
157 debug("Unknown phy speed: %d\n", priv->phydev->speed);
158 return -EINVAL;
159 }
160
161 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
162 rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
163
164 return 0;
165}
166
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200167static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
168{
169 struct rk3368_grf *grf;
170 int clk;
171 enum {
172 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
173 RK3368_GMAC_CLK_SEL_25M = 3 << 4,
174 RK3368_GMAC_CLK_SEL_125M = 0 << 4,
175 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
176 };
177
178 switch (priv->phydev->speed) {
179 case 10:
180 clk = RK3368_GMAC_CLK_SEL_2_5M;
181 break;
182 case 100:
183 clk = RK3368_GMAC_CLK_SEL_25M;
184 break;
185 case 1000:
186 clk = RK3368_GMAC_CLK_SEL_125M;
187 break;
188 default:
189 debug("Unknown phy speed: %d\n", priv->phydev->speed);
190 return -EINVAL;
191 }
192
193 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
194 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
195
196 return 0;
197}
198
Philipp Tomsich99cac582017-03-24 19:24:26 +0100199static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
200{
201 struct rk3399_grf_regs *grf;
202 int clk;
203
204 switch (priv->phydev->speed) {
205 case 10:
206 clk = RK3399_GMAC_CLK_SEL_2_5M;
207 break;
208 case 100:
209 clk = RK3399_GMAC_CLK_SEL_25M;
210 break;
211 case 1000:
212 clk = RK3399_GMAC_CLK_SEL_125M;
213 break;
214 default:
215 debug("Unknown phy speed: %d\n", priv->phydev->speed);
216 return -EINVAL;
217 }
218
219 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
220 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100221
222 return 0;
223}
224
David Wu672e4f22018-01-13 14:01:12 +0800225static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
226{
227 struct rv1108_grf *grf;
228 int clk, speed;
229 enum {
230 RV1108_GMAC_SPEED_MASK = BIT(2),
231 RV1108_GMAC_SPEED_10M = 0 << 2,
232 RV1108_GMAC_SPEED_100M = 1 << 2,
233 RV1108_GMAC_CLK_SEL_MASK = BIT(7),
234 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7,
235 RV1108_GMAC_CLK_SEL_25M = 1 << 7,
236 };
237
238 switch (priv->phydev->speed) {
239 case 10:
240 clk = RV1108_GMAC_CLK_SEL_2_5M;
241 speed = RV1108_GMAC_SPEED_10M;
242 break;
243 case 100:
244 clk = RV1108_GMAC_CLK_SEL_25M;
245 speed = RV1108_GMAC_SPEED_100M;
246 break;
247 default:
248 debug("Unknown phy speed: %d\n", priv->phydev->speed);
249 return -EINVAL;
250 }
251
252 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
253 rk_clrsetreg(&grf->gmac_con0,
254 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
255 clk | speed);
256
257 return 0;
258}
259
David Wuadcde492018-01-13 14:05:30 +0800260static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
261{
262 struct rk322x_grf *grf;
263 enum {
264 RK3228_RMII_MODE_SHIFT = 10,
265 RK3228_RMII_MODE_MASK = BIT(10),
266
267 RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
268 RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4),
269 RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
270
271 RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
272 RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
273 RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
274
275 RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
276 RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
277 RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
278 };
279 enum {
280 RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
281 RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
282
283 RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
284 RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
285 };
286
287 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
288 rk_clrsetreg(&grf->mac_con[1],
289 RK3228_RMII_MODE_MASK |
290 RK3228_GMAC_PHY_INTF_SEL_MASK |
291 RK3228_RXCLK_DLY_ENA_GMAC_MASK |
292 RK3228_TXCLK_DLY_ENA_GMAC_MASK,
293 RK3228_GMAC_PHY_INTF_SEL_RGMII |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200294 DELAY_ENABLE(RK3228, pdata->tx_delay, pdata->rx_delay));
David Wuadcde492018-01-13 14:05:30 +0800295
296 rk_clrsetreg(&grf->mac_con[0],
297 RK3228_CLK_RX_DL_CFG_GMAC_MASK |
298 RK3228_CLK_TX_DL_CFG_GMAC_MASK,
299 pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
300 pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
301}
302
Philipp Tomsich99cac582017-03-24 19:24:26 +0100303static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
304{
305 struct rk3288_grf *grf;
306
307 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
308 rk_clrsetreg(&grf->soc_con1,
309 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
310 RK3288_GMAC_PHY_INTF_SEL_RGMII);
311
312 rk_clrsetreg(&grf->soc_con3,
313 RK3288_RXCLK_DLY_ENA_GMAC_MASK |
314 RK3288_TXCLK_DLY_ENA_GMAC_MASK |
315 RK3288_CLK_RX_DL_CFG_GMAC_MASK |
316 RK3288_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200317 DELAY_ENABLE(RK3288, pdata->rx_delay, pdata->tx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100318 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
319 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
320}
321
David Wubac972b2018-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 |
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200356 DELAY_ENABLE(RK3328, pdata->tx_delay, pdata->rx_delay));
David Wubac972b2018-01-13 14:03:04 +0800357
358 rk_clrsetreg(&grf->mac_con[0],
359 RK3328_CLK_RX_DL_CFG_GMAC_MASK |
360 RK3328_CLK_TX_DL_CFG_GMAC_MASK,
361 pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
362 pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
363}
364
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200365static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
366{
367 struct rk3368_grf *grf;
368 enum {
369 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
370 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
371 RK3368_RMII_MODE_MASK = BIT(6),
372 RK3368_RMII_MODE = BIT(6),
373 };
374 enum {
375 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
376 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
377 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
378 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
379 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
380 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
381 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
382 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
383 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
384 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
385 };
386
387 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
388 rk_clrsetreg(&grf->soc_con15,
389 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
390 RK3368_GMAC_PHY_INTF_SEL_RGMII);
391
392 rk_clrsetreg(&grf->soc_con16,
393 RK3368_RXCLK_DLY_ENA_GMAC_MASK |
394 RK3368_TXCLK_DLY_ENA_GMAC_MASK |
395 RK3368_CLK_RX_DL_CFG_GMAC_MASK |
396 RK3368_CLK_TX_DL_CFG_GMAC_MASK,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200397 DELAY_ENABLE(RK3368, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200398 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,
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200417 DELAY_ENABLE(RK3399, pdata->tx_delay, pdata->rx_delay) |
Philipp Tomsich99cac582017-03-24 19:24:26 +0100418 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:
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200454 /* Set to RGMII mode */
455 if (ops->set_to_rgmii)
456 ops->set_to_rgmii(pdata);
457 else
458 return -EPERM;
459
David Wu672e4f22018-01-13 14:01:12 +0800460 /*
461 * If the gmac clock is from internal pll, need to set and
462 * check the return value for gmac clock at RGMII mode. If
463 * the gmac clock is from external source, the clock rate
464 * is not set, because of it is bypassed.
465 */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200466
David Wu672e4f22018-01-13 14:01:12 +0800467 if (!pdata->clock_input) {
468 rate = clk_set_rate(&clk, 125000000);
469 if (rate != 125000000)
470 return -EINVAL;
471 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200472 break;
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100473
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200474 case PHY_INTERFACE_MODE_RGMII_ID:
David Wu672e4f22018-01-13 14:01:12 +0800475 /* Set to RGMII mode */
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200476 if (ops->set_to_rgmii) {
477 pdata->tx_delay = 0;
478 pdata->rx_delay = 0;
David Wu672e4f22018-01-13 14:01:12 +0800479 ops->set_to_rgmii(pdata);
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200480 } else
David Wu672e4f22018-01-13 14:01:12 +0800481 return -EPERM;
482
David Wu672e4f22018-01-13 14:01:12 +0800483 if (!pdata->clock_input) {
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200484 rate = clk_set_rate(&clk, 125000000);
485 if (rate != 125000000)
David Wu672e4f22018-01-13 14:01:12 +0800486 return -EINVAL;
487 }
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200488 break;
David Wu672e4f22018-01-13 14:01:12 +0800489
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200490 case PHY_INTERFACE_MODE_RMII:
David Wu672e4f22018-01-13 14:01:12 +0800491 /* Set to RMII mode */
492 if (ops->set_to_rmii)
493 ops->set_to_rmii(pdata);
494 else
495 return -EPERM;
496
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200497 if (!pdata->clock_input) {
498 rate = clk_set_rate(&clk, 50000000);
499 if (rate != 50000000)
500 return -EINVAL;
501 }
502 break;
503
504 case PHY_INTERFACE_MODE_RGMII_RXID:
505 /* Set to RGMII_RXID mode */
506 if (ops->set_to_rgmii) {
507 pdata->tx_delay = 0;
508 ops->set_to_rgmii(pdata);
509 } else
510 return -EPERM;
511
512 if (!pdata->clock_input) {
513 rate = clk_set_rate(&clk, 125000000);
514 if (rate != 125000000)
515 return -EINVAL;
516 }
David Wu672e4f22018-01-13 14:01:12 +0800517 break;
Janine Hagemannb6a6dc82018-08-28 08:25:05 +0200518
519 case PHY_INTERFACE_MODE_RGMII_TXID:
520 /* Set to RGMII_TXID mode */
521 if (ops->set_to_rgmii) {
522 pdata->rx_delay = 0;
523 ops->set_to_rgmii(pdata);
524 } else
525 return -EPERM;
526
527 if (!pdata->clock_input) {
528 rate = clk_set_rate(&clk, 125000000);
529 if (rate != 125000000)
530 return -EINVAL;
531 }
532 break;
533
David Wu672e4f22018-01-13 14:01:12 +0800534 default:
535 debug("NO interface defined!\n");
536 return -ENXIO;
537 }
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100538
539 return designware_eth_probe(dev);
540}
541
542static int gmac_rockchip_eth_start(struct udevice *dev)
543{
544 struct eth_pdata *pdata = dev_get_platdata(dev);
545 struct dw_eth_dev *priv = dev_get_priv(dev);
Philipp Tomsich99cac582017-03-24 19:24:26 +0100546 struct rk_gmac_ops *ops =
547 (struct rk_gmac_ops *)dev_get_driver_data(dev);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100548 int ret;
549
550 ret = designware_eth_init(priv, pdata->enetaddr);
551 if (ret)
552 return ret;
Philipp Tomsich99cac582017-03-24 19:24:26 +0100553 ret = ops->fix_mac_speed(priv);
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100554 if (ret)
555 return ret;
556 ret = designware_eth_enable(priv);
557 if (ret)
558 return ret;
559
560 return 0;
561}
562
563const struct eth_ops gmac_rockchip_eth_ops = {
564 .start = gmac_rockchip_eth_start,
565 .send = designware_eth_send,
566 .recv = designware_eth_recv,
567 .free_pkt = designware_eth_free_pkt,
568 .stop = designware_eth_stop,
569 .write_hwaddr = designware_eth_write_hwaddr,
570};
571
David Wuadcde492018-01-13 14:05:30 +0800572const struct rk_gmac_ops rk3228_gmac_ops = {
573 .fix_mac_speed = rk3228_gmac_fix_mac_speed,
574 .set_to_rgmii = rk3228_gmac_set_to_rgmii,
575};
576
Philipp Tomsich99cac582017-03-24 19:24:26 +0100577const struct rk_gmac_ops rk3288_gmac_ops = {
578 .fix_mac_speed = rk3288_gmac_fix_mac_speed,
579 .set_to_rgmii = rk3288_gmac_set_to_rgmii,
580};
581
David Wubac972b2018-01-13 14:03:04 +0800582const struct rk_gmac_ops rk3328_gmac_ops = {
583 .fix_mac_speed = rk3328_gmac_fix_mac_speed,
584 .set_to_rgmii = rk3328_gmac_set_to_rgmii,
585};
586
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200587const struct rk_gmac_ops rk3368_gmac_ops = {
588 .fix_mac_speed = rk3368_gmac_fix_mac_speed,
589 .set_to_rgmii = rk3368_gmac_set_to_rgmii,
590};
591
Philipp Tomsich99cac582017-03-24 19:24:26 +0100592const struct rk_gmac_ops rk3399_gmac_ops = {
593 .fix_mac_speed = rk3399_gmac_fix_mac_speed,
594 .set_to_rgmii = rk3399_gmac_set_to_rgmii,
595};
596
David Wu672e4f22018-01-13 14:01:12 +0800597const struct rk_gmac_ops rv1108_gmac_ops = {
598 .fix_mac_speed = rv1108_set_rmii_speed,
599 .set_to_rmii = rv1108_gmac_set_to_rmii,
600};
601
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100602static const struct udevice_id rockchip_gmac_ids[] = {
David Wuadcde492018-01-13 14:05:30 +0800603 { .compatible = "rockchip,rk3228-gmac",
604 .data = (ulong)&rk3228_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100605 { .compatible = "rockchip,rk3288-gmac",
606 .data = (ulong)&rk3288_gmac_ops },
David Wubac972b2018-01-13 14:03:04 +0800607 { .compatible = "rockchip,rk3328-gmac",
608 .data = (ulong)&rk3328_gmac_ops },
Philipp Tomsich821c4c42017-07-25 17:02:51 +0200609 { .compatible = "rockchip,rk3368-gmac",
610 .data = (ulong)&rk3368_gmac_ops },
Philipp Tomsich99cac582017-03-24 19:24:26 +0100611 { .compatible = "rockchip,rk3399-gmac",
612 .data = (ulong)&rk3399_gmac_ops },
David Wu672e4f22018-01-13 14:01:12 +0800613 { .compatible = "rockchip,rv1108-gmac",
614 .data = (ulong)&rv1108_gmac_ops },
Sjoerd Simons54c46f92017-01-11 11:46:11 +0100615 { }
616};
617
618U_BOOT_DRIVER(eth_gmac_rockchip) = {
619 .name = "gmac_rockchip",
620 .id = UCLASS_ETH,
621 .of_match = rockchip_gmac_ids,
622 .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
623 .probe = gmac_rockchip_probe,
624 .ops = &gmac_rockchip_eth_ops,
625 .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
626 .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
627 .flags = DM_FLAG_ALLOC_PRIV_DMA,
628};