xref: /rk3399_rockchip-uboot/drivers/net/gmac_rockchip.c (revision 18ae91c869a8eb55d8680e8180752b551ebe01ab)
10125bcf0SSjoerd Simons /*
20125bcf0SSjoerd Simons  * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
30125bcf0SSjoerd Simons  *
40125bcf0SSjoerd Simons  * SPDX-License-Identifier:	GPL-2.0+
50125bcf0SSjoerd Simons  *
60125bcf0SSjoerd Simons  * Rockchip GMAC ethernet IP driver for U-Boot
70125bcf0SSjoerd Simons  */
80125bcf0SSjoerd Simons 
90125bcf0SSjoerd Simons #include <common.h>
100125bcf0SSjoerd Simons #include <dm.h>
110125bcf0SSjoerd Simons #include <clk.h>
120125bcf0SSjoerd Simons #include <phy.h>
130125bcf0SSjoerd Simons #include <syscon.h>
140125bcf0SSjoerd Simons #include <asm/io.h>
150125bcf0SSjoerd Simons #include <asm/arch/periph.h>
160125bcf0SSjoerd Simons #include <asm/arch/clock.h>
171f08aa1cSPhilipp Tomsich #include <asm/arch/hardware.h>
18*18ae91c8SDavid Wu #include <asm/arch/grf_px30.h>
19af166ffaSDavid Wu #include <asm/arch/grf_rk322x.h>
200125bcf0SSjoerd Simons #include <asm/arch/grf_rk3288.h>
2123adb58fSDavid Wu #include <asm/arch/grf_rk3308.h>
22c36b26c0SDavid Wu #include <asm/arch/grf_rk3328.h>
23793f2fd2SPhilipp Tomsich #include <asm/arch/grf_rk3368.h>
241f08aa1cSPhilipp Tomsich #include <asm/arch/grf_rk3399.h>
250a33ce65SDavid Wu #include <asm/arch/grf_rv1108.h>
260125bcf0SSjoerd Simons #include <dm/pinctrl.h>
270125bcf0SSjoerd Simons #include <dt-bindings/clock/rk3288-cru.h>
280125bcf0SSjoerd Simons #include "designware.h"
290125bcf0SSjoerd Simons 
300125bcf0SSjoerd Simons DECLARE_GLOBAL_DATA_PTR;
310125bcf0SSjoerd Simons 
320125bcf0SSjoerd Simons /*
330125bcf0SSjoerd Simons  * Platform data for the gmac
340125bcf0SSjoerd Simons  *
350125bcf0SSjoerd Simons  * dw_eth_pdata: Required platform data for designware driver (must be first)
360125bcf0SSjoerd Simons  */
370125bcf0SSjoerd Simons struct gmac_rockchip_platdata {
380125bcf0SSjoerd Simons 	struct dw_eth_pdata dw_eth_pdata;
390a33ce65SDavid Wu 	bool clock_input;
400125bcf0SSjoerd Simons 	int tx_delay;
410125bcf0SSjoerd Simons 	int rx_delay;
420125bcf0SSjoerd Simons };
430125bcf0SSjoerd Simons 
441f08aa1cSPhilipp Tomsich struct rk_gmac_ops {
451f08aa1cSPhilipp Tomsich 	int (*fix_mac_speed)(struct dw_eth_dev *priv);
460a33ce65SDavid Wu 	void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
471f08aa1cSPhilipp Tomsich 	void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
481f08aa1cSPhilipp Tomsich };
491f08aa1cSPhilipp Tomsich 
501eb9d064SDavid Wu void gmac_set_rgmii(struct udevice *dev, u32 tx_delay, u32 rx_delay)
511eb9d064SDavid Wu {
521eb9d064SDavid Wu 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
531eb9d064SDavid Wu 	struct rk_gmac_ops *ops =
541eb9d064SDavid Wu 		(struct rk_gmac_ops *)dev_get_driver_data(dev);
551eb9d064SDavid Wu 
561eb9d064SDavid Wu 	pdata->tx_delay = tx_delay;
571eb9d064SDavid Wu 	pdata->rx_delay = rx_delay;
581eb9d064SDavid Wu 
591eb9d064SDavid Wu 	ops->set_to_rgmii(pdata);
601eb9d064SDavid Wu }
611f08aa1cSPhilipp Tomsich 
620125bcf0SSjoerd Simons static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
630125bcf0SSjoerd Simons {
640125bcf0SSjoerd Simons 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
650a33ce65SDavid Wu 	const char *string;
660a33ce65SDavid Wu 
670a33ce65SDavid Wu 	string = dev_read_string(dev, "clock_in_out");
680a33ce65SDavid Wu 	if (!strcmp(string, "input"))
690a33ce65SDavid Wu 		pdata->clock_input = true;
700a33ce65SDavid Wu 	else
710a33ce65SDavid Wu 		pdata->clock_input = false;
720125bcf0SSjoerd Simons 
731f08aa1cSPhilipp Tomsich 	/* Check the new naming-style first... */
747ad326a9SPhilipp Tomsich 	pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
757ad326a9SPhilipp Tomsich 	pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
761f08aa1cSPhilipp Tomsich 
771f08aa1cSPhilipp Tomsich 	/* ... and fall back to the old naming style or default, if necessary */
781f08aa1cSPhilipp Tomsich 	if (pdata->tx_delay == -ENOENT)
797ad326a9SPhilipp Tomsich 		pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
801f08aa1cSPhilipp Tomsich 	if (pdata->rx_delay == -ENOENT)
817ad326a9SPhilipp Tomsich 		pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
820125bcf0SSjoerd Simons 
830125bcf0SSjoerd Simons 	return designware_eth_ofdata_to_platdata(dev);
840125bcf0SSjoerd Simons }
850125bcf0SSjoerd Simons 
86*18ae91c8SDavid Wu static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
87*18ae91c8SDavid Wu {
88*18ae91c8SDavid Wu 	struct px30_grf *grf;
89*18ae91c8SDavid Wu 	struct clk clk_speed;
90*18ae91c8SDavid Wu 	int speed, ret;
91*18ae91c8SDavid Wu 	enum {
92*18ae91c8SDavid Wu 		PX30_GMAC_SPEED_SHIFT = 0x2,
93*18ae91c8SDavid Wu 		PX30_GMAC_SPEED_MASK  = BIT(2),
94*18ae91c8SDavid Wu 		PX30_GMAC_SPEED_10M   = 0,
95*18ae91c8SDavid Wu 		PX30_GMAC_SPEED_100M  = BIT(2),
96*18ae91c8SDavid Wu 	};
97*18ae91c8SDavid Wu 
98*18ae91c8SDavid Wu 	ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
99*18ae91c8SDavid Wu 			      &clk_speed);
100*18ae91c8SDavid Wu 	if (ret)
101*18ae91c8SDavid Wu 		return ret;
102*18ae91c8SDavid Wu 
103*18ae91c8SDavid Wu 	switch (priv->phydev->speed) {
104*18ae91c8SDavid Wu 	case 10:
105*18ae91c8SDavid Wu 		speed = PX30_GMAC_SPEED_10M;
106*18ae91c8SDavid Wu 		ret = clk_set_rate(&clk_speed, 2500000);
107*18ae91c8SDavid Wu 		if (ret)
108*18ae91c8SDavid Wu 			return ret;
109*18ae91c8SDavid Wu 		break;
110*18ae91c8SDavid Wu 	case 100:
111*18ae91c8SDavid Wu 		speed = PX30_GMAC_SPEED_100M;
112*18ae91c8SDavid Wu 		ret = clk_set_rate(&clk_speed, 25000000);
113*18ae91c8SDavid Wu 		if (ret)
114*18ae91c8SDavid Wu 			return ret;
115*18ae91c8SDavid Wu 		break;
116*18ae91c8SDavid Wu 	default:
117*18ae91c8SDavid Wu 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
118*18ae91c8SDavid Wu 		return -EINVAL;
119*18ae91c8SDavid Wu 	}
120*18ae91c8SDavid Wu 
121*18ae91c8SDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
122*18ae91c8SDavid Wu 	rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed);
123*18ae91c8SDavid Wu 
124*18ae91c8SDavid Wu 	return 0;
125*18ae91c8SDavid Wu }
126*18ae91c8SDavid Wu 
127af166ffaSDavid Wu static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
128af166ffaSDavid Wu {
129af166ffaSDavid Wu 	struct rk322x_grf *grf;
130af166ffaSDavid Wu 	int clk;
131af166ffaSDavid Wu 	enum {
132af166ffaSDavid Wu 		RK3228_GMAC_CLK_SEL_SHIFT = 8,
133af166ffaSDavid Wu 		RK3228_GMAC_CLK_SEL_MASK  = GENMASK(9, 8),
134af166ffaSDavid Wu 		RK3228_GMAC_CLK_SEL_125M  = 0 << 8,
135af166ffaSDavid Wu 		RK3228_GMAC_CLK_SEL_25M   = 3 << 8,
136af166ffaSDavid Wu 		RK3228_GMAC_CLK_SEL_2_5M  = 2 << 8,
137af166ffaSDavid Wu 	};
138af166ffaSDavid Wu 
139af166ffaSDavid Wu 	switch (priv->phydev->speed) {
140af166ffaSDavid Wu 	case 10:
141af166ffaSDavid Wu 		clk = RK3228_GMAC_CLK_SEL_2_5M;
142af166ffaSDavid Wu 		break;
143af166ffaSDavid Wu 	case 100:
144af166ffaSDavid Wu 		clk = RK3228_GMAC_CLK_SEL_25M;
145af166ffaSDavid Wu 		break;
146af166ffaSDavid Wu 	case 1000:
147af166ffaSDavid Wu 		clk = RK3228_GMAC_CLK_SEL_125M;
148af166ffaSDavid Wu 		break;
149af166ffaSDavid Wu 	default:
150af166ffaSDavid Wu 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
151af166ffaSDavid Wu 		return -EINVAL;
152af166ffaSDavid Wu 	}
153af166ffaSDavid Wu 
154af166ffaSDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
155af166ffaSDavid Wu 	rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk);
156af166ffaSDavid Wu 
157af166ffaSDavid Wu 	return 0;
158af166ffaSDavid Wu }
159af166ffaSDavid Wu 
1601f08aa1cSPhilipp Tomsich static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
1610125bcf0SSjoerd Simons {
1620125bcf0SSjoerd Simons 	struct rk3288_grf *grf;
1630125bcf0SSjoerd Simons 	int clk;
1640125bcf0SSjoerd Simons 
1650125bcf0SSjoerd Simons 	switch (priv->phydev->speed) {
1660125bcf0SSjoerd Simons 	case 10:
1671f08aa1cSPhilipp Tomsich 		clk = RK3288_GMAC_CLK_SEL_2_5M;
1680125bcf0SSjoerd Simons 		break;
1690125bcf0SSjoerd Simons 	case 100:
1701f08aa1cSPhilipp Tomsich 		clk = RK3288_GMAC_CLK_SEL_25M;
1710125bcf0SSjoerd Simons 		break;
1720125bcf0SSjoerd Simons 	case 1000:
1731f08aa1cSPhilipp Tomsich 		clk = RK3288_GMAC_CLK_SEL_125M;
1740125bcf0SSjoerd Simons 		break;
1750125bcf0SSjoerd Simons 	default:
1760125bcf0SSjoerd Simons 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
1770125bcf0SSjoerd Simons 		return -EINVAL;
1780125bcf0SSjoerd Simons 	}
1790125bcf0SSjoerd Simons 
1800125bcf0SSjoerd Simons 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
1811f08aa1cSPhilipp Tomsich 	rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
1820125bcf0SSjoerd Simons 
1830125bcf0SSjoerd Simons 	return 0;
1840125bcf0SSjoerd Simons }
1850125bcf0SSjoerd Simons 
18623adb58fSDavid Wu static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv)
18723adb58fSDavid Wu {
18823adb58fSDavid Wu 	struct rk3308_grf *grf;
18923adb58fSDavid Wu 	struct clk clk_speed;
19023adb58fSDavid Wu 	int speed, ret;
19123adb58fSDavid Wu 	enum {
19223adb58fSDavid Wu 		RK3308_GMAC_SPEED_SHIFT = 0x0,
19323adb58fSDavid Wu 		RK3308_GMAC_SPEED_MASK  = BIT(0),
19423adb58fSDavid Wu 		RK3308_GMAC_SPEED_10M   = 0,
19523adb58fSDavid Wu 		RK3308_GMAC_SPEED_100M  = BIT(0),
19623adb58fSDavid Wu 	};
19723adb58fSDavid Wu 
19823adb58fSDavid Wu 	ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
19923adb58fSDavid Wu 			      &clk_speed);
20023adb58fSDavid Wu 	if (ret)
20123adb58fSDavid Wu 		return ret;
20223adb58fSDavid Wu 
20323adb58fSDavid Wu 	switch (priv->phydev->speed) {
20423adb58fSDavid Wu 	case 10:
20523adb58fSDavid Wu 		speed = RK3308_GMAC_SPEED_10M;
20623adb58fSDavid Wu 		ret = clk_set_rate(&clk_speed, 2500000);
20723adb58fSDavid Wu 		if (ret)
20823adb58fSDavid Wu 			return ret;
20923adb58fSDavid Wu 		break;
21023adb58fSDavid Wu 	case 100:
21123adb58fSDavid Wu 		speed = RK3308_GMAC_SPEED_100M;
21223adb58fSDavid Wu 		ret = clk_set_rate(&clk_speed, 25000000);
21323adb58fSDavid Wu 		if (ret)
21423adb58fSDavid Wu 			return ret;
21523adb58fSDavid Wu 		break;
21623adb58fSDavid Wu 	default:
21723adb58fSDavid Wu 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
21823adb58fSDavid Wu 		return -EINVAL;
21923adb58fSDavid Wu 	}
22023adb58fSDavid Wu 
22123adb58fSDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
22223adb58fSDavid Wu 	rk_clrsetreg(&grf->mac_con0, RK3308_GMAC_SPEED_MASK, speed);
22323adb58fSDavid Wu 
22423adb58fSDavid Wu 	return 0;
22523adb58fSDavid Wu }
22623adb58fSDavid Wu 
227c36b26c0SDavid Wu static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv)
228c36b26c0SDavid Wu {
229c36b26c0SDavid Wu 	struct rk3328_grf_regs *grf;
230c36b26c0SDavid Wu 	int clk;
231c36b26c0SDavid Wu 	enum {
232c36b26c0SDavid Wu 		RK3328_GMAC_CLK_SEL_SHIFT = 11,
233c36b26c0SDavid Wu 		RK3328_GMAC_CLK_SEL_MASK  = GENMASK(12, 11),
234c36b26c0SDavid Wu 		RK3328_GMAC_CLK_SEL_125M  = 0 << 11,
235c36b26c0SDavid Wu 		RK3328_GMAC_CLK_SEL_25M   = 3 << 11,
236c36b26c0SDavid Wu 		RK3328_GMAC_CLK_SEL_2_5M  = 2 << 11,
237c36b26c0SDavid Wu 	};
238c36b26c0SDavid Wu 
239c36b26c0SDavid Wu 	switch (priv->phydev->speed) {
240c36b26c0SDavid Wu 	case 10:
241c36b26c0SDavid Wu 		clk = RK3328_GMAC_CLK_SEL_2_5M;
242c36b26c0SDavid Wu 		break;
243c36b26c0SDavid Wu 	case 100:
244c36b26c0SDavid Wu 		clk = RK3328_GMAC_CLK_SEL_25M;
245c36b26c0SDavid Wu 		break;
246c36b26c0SDavid Wu 	case 1000:
247c36b26c0SDavid Wu 		clk = RK3328_GMAC_CLK_SEL_125M;
248c36b26c0SDavid Wu 		break;
249c36b26c0SDavid Wu 	default:
250c36b26c0SDavid Wu 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
251c36b26c0SDavid Wu 		return -EINVAL;
252c36b26c0SDavid Wu 	}
253c36b26c0SDavid Wu 
254c36b26c0SDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
255c36b26c0SDavid Wu 	rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk);
256c36b26c0SDavid Wu 
257c36b26c0SDavid Wu 	return 0;
258c36b26c0SDavid Wu }
259c36b26c0SDavid Wu 
260793f2fd2SPhilipp Tomsich static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
261793f2fd2SPhilipp Tomsich {
262793f2fd2SPhilipp Tomsich 	struct rk3368_grf *grf;
263793f2fd2SPhilipp Tomsich 	int clk;
264793f2fd2SPhilipp Tomsich 	enum {
265793f2fd2SPhilipp Tomsich 		RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
266793f2fd2SPhilipp Tomsich 		RK3368_GMAC_CLK_SEL_25M = 3 << 4,
267793f2fd2SPhilipp Tomsich 		RK3368_GMAC_CLK_SEL_125M = 0 << 4,
268793f2fd2SPhilipp Tomsich 		RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
269793f2fd2SPhilipp Tomsich 	};
270793f2fd2SPhilipp Tomsich 
271793f2fd2SPhilipp Tomsich 	switch (priv->phydev->speed) {
272793f2fd2SPhilipp Tomsich 	case 10:
273793f2fd2SPhilipp Tomsich 		clk = RK3368_GMAC_CLK_SEL_2_5M;
274793f2fd2SPhilipp Tomsich 		break;
275793f2fd2SPhilipp Tomsich 	case 100:
276793f2fd2SPhilipp Tomsich 		clk = RK3368_GMAC_CLK_SEL_25M;
277793f2fd2SPhilipp Tomsich 		break;
278793f2fd2SPhilipp Tomsich 	case 1000:
279793f2fd2SPhilipp Tomsich 		clk = RK3368_GMAC_CLK_SEL_125M;
280793f2fd2SPhilipp Tomsich 		break;
281793f2fd2SPhilipp Tomsich 	default:
282793f2fd2SPhilipp Tomsich 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
283793f2fd2SPhilipp Tomsich 		return -EINVAL;
284793f2fd2SPhilipp Tomsich 	}
285793f2fd2SPhilipp Tomsich 
286793f2fd2SPhilipp Tomsich 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
287793f2fd2SPhilipp Tomsich 	rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
288793f2fd2SPhilipp Tomsich 
289793f2fd2SPhilipp Tomsich 	return 0;
290793f2fd2SPhilipp Tomsich }
291793f2fd2SPhilipp Tomsich 
2921f08aa1cSPhilipp Tomsich static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
2931f08aa1cSPhilipp Tomsich {
2941f08aa1cSPhilipp Tomsich 	struct rk3399_grf_regs *grf;
2951f08aa1cSPhilipp Tomsich 	int clk;
2961f08aa1cSPhilipp Tomsich 
2971f08aa1cSPhilipp Tomsich 	switch (priv->phydev->speed) {
2981f08aa1cSPhilipp Tomsich 	case 10:
2991f08aa1cSPhilipp Tomsich 		clk = RK3399_GMAC_CLK_SEL_2_5M;
3001f08aa1cSPhilipp Tomsich 		break;
3011f08aa1cSPhilipp Tomsich 	case 100:
3021f08aa1cSPhilipp Tomsich 		clk = RK3399_GMAC_CLK_SEL_25M;
3031f08aa1cSPhilipp Tomsich 		break;
3041f08aa1cSPhilipp Tomsich 	case 1000:
3051f08aa1cSPhilipp Tomsich 		clk = RK3399_GMAC_CLK_SEL_125M;
3061f08aa1cSPhilipp Tomsich 		break;
3071f08aa1cSPhilipp Tomsich 	default:
3081f08aa1cSPhilipp Tomsich 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
3091f08aa1cSPhilipp Tomsich 		return -EINVAL;
3101f08aa1cSPhilipp Tomsich 	}
3111f08aa1cSPhilipp Tomsich 
3121f08aa1cSPhilipp Tomsich 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
3131f08aa1cSPhilipp Tomsich 	rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
3141f08aa1cSPhilipp Tomsich 
3151f08aa1cSPhilipp Tomsich 	return 0;
3161f08aa1cSPhilipp Tomsich }
3171f08aa1cSPhilipp Tomsich 
3180a33ce65SDavid Wu static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
3190a33ce65SDavid Wu {
3200a33ce65SDavid Wu 	struct rv1108_grf *grf;
3210a33ce65SDavid Wu 	int clk, speed;
3220a33ce65SDavid Wu 	enum {
3230a33ce65SDavid Wu 		RV1108_GMAC_SPEED_MASK		= BIT(2),
3240a33ce65SDavid Wu 		RV1108_GMAC_SPEED_10M		= 0 << 2,
3250a33ce65SDavid Wu 		RV1108_GMAC_SPEED_100M		= 1 << 2,
3260a33ce65SDavid Wu 		RV1108_GMAC_CLK_SEL_MASK	= BIT(7),
3270a33ce65SDavid Wu 		RV1108_GMAC_CLK_SEL_2_5M	= 0 << 7,
3280a33ce65SDavid Wu 		RV1108_GMAC_CLK_SEL_25M		= 1 << 7,
3290a33ce65SDavid Wu 	};
3300a33ce65SDavid Wu 
3310a33ce65SDavid Wu 	switch (priv->phydev->speed) {
3320a33ce65SDavid Wu 	case 10:
3330a33ce65SDavid Wu 		clk = RV1108_GMAC_CLK_SEL_2_5M;
3340a33ce65SDavid Wu 		speed = RV1108_GMAC_SPEED_10M;
3350a33ce65SDavid Wu 		break;
3360a33ce65SDavid Wu 	case 100:
3370a33ce65SDavid Wu 		clk = RV1108_GMAC_CLK_SEL_25M;
3380a33ce65SDavid Wu 		speed = RV1108_GMAC_SPEED_100M;
3390a33ce65SDavid Wu 		break;
3400a33ce65SDavid Wu 	default:
3410a33ce65SDavid Wu 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
3420a33ce65SDavid Wu 		return -EINVAL;
3430a33ce65SDavid Wu 	}
3440a33ce65SDavid Wu 
3450a33ce65SDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
3460a33ce65SDavid Wu 	rk_clrsetreg(&grf->gmac_con0,
3470a33ce65SDavid Wu 		     RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
3480a33ce65SDavid Wu 		     clk | speed);
3490a33ce65SDavid Wu 
3500a33ce65SDavid Wu 	return 0;
3510a33ce65SDavid Wu }
3520a33ce65SDavid Wu 
353*18ae91c8SDavid Wu static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
354*18ae91c8SDavid Wu {
355*18ae91c8SDavid Wu 	struct px30_grf *grf;
356*18ae91c8SDavid Wu 	enum {
357*18ae91c8SDavid Wu 		px30_GMAC_PHY_INTF_SEL_SHIFT = 4,
358*18ae91c8SDavid Wu 		px30_GMAC_PHY_INTF_SEL_MASK  = GENMASK(4, 6),
359*18ae91c8SDavid Wu 		px30_GMAC_PHY_INTF_SEL_RMII  = BIT(6),
360*18ae91c8SDavid Wu 	};
361*18ae91c8SDavid Wu 
362*18ae91c8SDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
363*18ae91c8SDavid Wu 
364*18ae91c8SDavid Wu 	rk_clrsetreg(&grf->mac_con1,
365*18ae91c8SDavid Wu 		     px30_GMAC_PHY_INTF_SEL_MASK,
366*18ae91c8SDavid Wu 		     px30_GMAC_PHY_INTF_SEL_RMII);
367*18ae91c8SDavid Wu }
368*18ae91c8SDavid Wu 
369af166ffaSDavid Wu static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
370af166ffaSDavid Wu {
371af166ffaSDavid Wu 	struct rk322x_grf *grf;
372af166ffaSDavid Wu 	enum {
373af166ffaSDavid Wu 		RK3228_RMII_MODE_SHIFT = 10,
374af166ffaSDavid Wu 		RK3228_RMII_MODE_MASK  = BIT(10),
375af166ffaSDavid Wu 
376af166ffaSDavid Wu 		RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4,
377af166ffaSDavid Wu 		RK3228_GMAC_PHY_INTF_SEL_MASK  = GENMASK(6, 4),
378af166ffaSDavid Wu 		RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
379af166ffaSDavid Wu 
380af166ffaSDavid Wu 		RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
381af166ffaSDavid Wu 		RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
382af166ffaSDavid Wu 		RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
383af166ffaSDavid Wu 
384af166ffaSDavid Wu 		RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
385af166ffaSDavid Wu 		RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
386af166ffaSDavid Wu 		RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
387af166ffaSDavid Wu 	};
388af166ffaSDavid Wu 	enum {
389af166ffaSDavid Wu 		RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
390af166ffaSDavid Wu 		RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
391af166ffaSDavid Wu 
392af166ffaSDavid Wu 		RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
393af166ffaSDavid Wu 		RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
394af166ffaSDavid Wu 	};
395af166ffaSDavid Wu 
396af166ffaSDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
397af166ffaSDavid Wu 	rk_clrsetreg(&grf->mac_con[1],
398af166ffaSDavid Wu 		     RK3228_RMII_MODE_MASK |
399af166ffaSDavid Wu 		     RK3228_GMAC_PHY_INTF_SEL_MASK |
400af166ffaSDavid Wu 		     RK3228_RXCLK_DLY_ENA_GMAC_MASK |
401af166ffaSDavid Wu 		     RK3228_TXCLK_DLY_ENA_GMAC_MASK,
402af166ffaSDavid Wu 		     RK3228_GMAC_PHY_INTF_SEL_RGMII |
403af166ffaSDavid Wu 		     RK3228_RXCLK_DLY_ENA_GMAC_ENABLE |
404af166ffaSDavid Wu 		     RK3228_TXCLK_DLY_ENA_GMAC_ENABLE);
405af166ffaSDavid Wu 
406af166ffaSDavid Wu 	rk_clrsetreg(&grf->mac_con[0],
407af166ffaSDavid Wu 		     RK3228_CLK_RX_DL_CFG_GMAC_MASK |
408af166ffaSDavid Wu 		     RK3228_CLK_TX_DL_CFG_GMAC_MASK,
409af166ffaSDavid Wu 		     pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT |
410af166ffaSDavid Wu 		     pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT);
411af166ffaSDavid Wu }
412af166ffaSDavid Wu 
4131f08aa1cSPhilipp Tomsich static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
4141f08aa1cSPhilipp Tomsich {
4151f08aa1cSPhilipp Tomsich 	struct rk3288_grf *grf;
4161f08aa1cSPhilipp Tomsich 
4171f08aa1cSPhilipp Tomsich 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
4181f08aa1cSPhilipp Tomsich 	rk_clrsetreg(&grf->soc_con1,
4191f08aa1cSPhilipp Tomsich 		     RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
4201f08aa1cSPhilipp Tomsich 		     RK3288_GMAC_PHY_INTF_SEL_RGMII);
4211f08aa1cSPhilipp Tomsich 
4221f08aa1cSPhilipp Tomsich 	rk_clrsetreg(&grf->soc_con3,
4231f08aa1cSPhilipp Tomsich 		     RK3288_RXCLK_DLY_ENA_GMAC_MASK |
4241f08aa1cSPhilipp Tomsich 		     RK3288_TXCLK_DLY_ENA_GMAC_MASK |
4251f08aa1cSPhilipp Tomsich 		     RK3288_CLK_RX_DL_CFG_GMAC_MASK |
4261f08aa1cSPhilipp Tomsich 		     RK3288_CLK_TX_DL_CFG_GMAC_MASK,
4271f08aa1cSPhilipp Tomsich 		     RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
4281f08aa1cSPhilipp Tomsich 		     RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
4291f08aa1cSPhilipp Tomsich 		     pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
4301f08aa1cSPhilipp Tomsich 		     pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
4311f08aa1cSPhilipp Tomsich }
4321f08aa1cSPhilipp Tomsich 
43323adb58fSDavid Wu static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
43423adb58fSDavid Wu {
43523adb58fSDavid Wu 	struct rk3308_grf *grf;
43623adb58fSDavid Wu 	enum {
43723adb58fSDavid Wu 		RK3308_GMAC_PHY_INTF_SEL_SHIFT = 2,
43823adb58fSDavid Wu 		RK3308_GMAC_PHY_INTF_SEL_MASK  = GENMASK(4, 2),
43923adb58fSDavid Wu 		RK3308_GMAC_PHY_INTF_SEL_RMII  = BIT(4),
44023adb58fSDavid Wu 	};
44123adb58fSDavid Wu 
44223adb58fSDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
44323adb58fSDavid Wu 
44423adb58fSDavid Wu 	rk_clrsetreg(&grf->mac_con0,
44523adb58fSDavid Wu 		     RK3308_GMAC_PHY_INTF_SEL_MASK,
44623adb58fSDavid Wu 		     RK3308_GMAC_PHY_INTF_SEL_RMII);
44723adb58fSDavid Wu }
44823adb58fSDavid Wu 
449c36b26c0SDavid Wu static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
450c36b26c0SDavid Wu {
451c36b26c0SDavid Wu 	struct rk3328_grf_regs *grf;
452c36b26c0SDavid Wu 	enum {
453c36b26c0SDavid Wu 		RK3328_RMII_MODE_SHIFT = 9,
454c36b26c0SDavid Wu 		RK3328_RMII_MODE_MASK  = BIT(9),
455c36b26c0SDavid Wu 
456c36b26c0SDavid Wu 		RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4,
457c36b26c0SDavid Wu 		RK3328_GMAC_PHY_INTF_SEL_MASK  = GENMASK(6, 4),
458c36b26c0SDavid Wu 		RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4),
459c36b26c0SDavid Wu 
460c36b26c0SDavid Wu 		RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1),
461c36b26c0SDavid Wu 		RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
462c36b26c0SDavid Wu 		RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1),
463c36b26c0SDavid Wu 
464c36b26c0SDavid Wu 		RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0),
465c36b26c0SDavid Wu 		RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
466c36b26c0SDavid Wu 		RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0),
467c36b26c0SDavid Wu 	};
468c36b26c0SDavid Wu 	enum {
469c36b26c0SDavid Wu 		RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
470c36b26c0SDavid Wu 		RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7),
471c36b26c0SDavid Wu 
472c36b26c0SDavid Wu 		RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
473c36b26c0SDavid Wu 		RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
474c36b26c0SDavid Wu 	};
475c36b26c0SDavid Wu 
476c36b26c0SDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
477c36b26c0SDavid Wu 	rk_clrsetreg(&grf->mac_con[1],
478c36b26c0SDavid Wu 		     RK3328_RMII_MODE_MASK |
479c36b26c0SDavid Wu 		     RK3328_GMAC_PHY_INTF_SEL_MASK |
480c36b26c0SDavid Wu 		     RK3328_RXCLK_DLY_ENA_GMAC_MASK |
481c36b26c0SDavid Wu 		     RK3328_TXCLK_DLY_ENA_GMAC_MASK,
482c36b26c0SDavid Wu 		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
483c36b26c0SDavid Wu 		     RK3328_RXCLK_DLY_ENA_GMAC_MASK |
484c36b26c0SDavid Wu 		     RK3328_TXCLK_DLY_ENA_GMAC_ENABLE);
485c36b26c0SDavid Wu 
486c36b26c0SDavid Wu 	rk_clrsetreg(&grf->mac_con[0],
487c36b26c0SDavid Wu 		     RK3328_CLK_RX_DL_CFG_GMAC_MASK |
488c36b26c0SDavid Wu 		     RK3328_CLK_TX_DL_CFG_GMAC_MASK,
489c36b26c0SDavid Wu 		     pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT |
490c36b26c0SDavid Wu 		     pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT);
491c36b26c0SDavid Wu }
492c36b26c0SDavid Wu 
493793f2fd2SPhilipp Tomsich static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
494793f2fd2SPhilipp Tomsich {
495793f2fd2SPhilipp Tomsich 	struct rk3368_grf *grf;
496793f2fd2SPhilipp Tomsich 	enum {
497793f2fd2SPhilipp Tomsich 		RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
498793f2fd2SPhilipp Tomsich 		RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
499793f2fd2SPhilipp Tomsich 		RK3368_RMII_MODE_MASK  = BIT(6),
500793f2fd2SPhilipp Tomsich 		RK3368_RMII_MODE       = BIT(6),
501793f2fd2SPhilipp Tomsich 	};
502793f2fd2SPhilipp Tomsich 	enum {
503793f2fd2SPhilipp Tomsich 		RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
504793f2fd2SPhilipp Tomsich 		RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
505793f2fd2SPhilipp Tomsich 		RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
506793f2fd2SPhilipp Tomsich 		RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
507793f2fd2SPhilipp Tomsich 		RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
508793f2fd2SPhilipp Tomsich 		RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
509793f2fd2SPhilipp Tomsich 		RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
510793f2fd2SPhilipp Tomsich 		RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
511793f2fd2SPhilipp Tomsich 		RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
512793f2fd2SPhilipp Tomsich 		RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
513793f2fd2SPhilipp Tomsich 	};
514793f2fd2SPhilipp Tomsich 
515793f2fd2SPhilipp Tomsich 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
516793f2fd2SPhilipp Tomsich 	rk_clrsetreg(&grf->soc_con15,
517793f2fd2SPhilipp Tomsich 		     RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
518793f2fd2SPhilipp Tomsich 		     RK3368_GMAC_PHY_INTF_SEL_RGMII);
519793f2fd2SPhilipp Tomsich 
520793f2fd2SPhilipp Tomsich 	rk_clrsetreg(&grf->soc_con16,
521793f2fd2SPhilipp Tomsich 		     RK3368_RXCLK_DLY_ENA_GMAC_MASK |
522793f2fd2SPhilipp Tomsich 		     RK3368_TXCLK_DLY_ENA_GMAC_MASK |
523793f2fd2SPhilipp Tomsich 		     RK3368_CLK_RX_DL_CFG_GMAC_MASK |
524793f2fd2SPhilipp Tomsich 		     RK3368_CLK_TX_DL_CFG_GMAC_MASK,
525793f2fd2SPhilipp Tomsich 		     RK3368_RXCLK_DLY_ENA_GMAC_ENABLE |
526793f2fd2SPhilipp Tomsich 		     RK3368_TXCLK_DLY_ENA_GMAC_ENABLE |
527793f2fd2SPhilipp Tomsich 		     pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
528793f2fd2SPhilipp Tomsich 		     pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
529793f2fd2SPhilipp Tomsich }
530793f2fd2SPhilipp Tomsich 
5311f08aa1cSPhilipp Tomsich static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
5321f08aa1cSPhilipp Tomsich {
5331f08aa1cSPhilipp Tomsich 	struct rk3399_grf_regs *grf;
5341f08aa1cSPhilipp Tomsich 
5351f08aa1cSPhilipp Tomsich 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
5361f08aa1cSPhilipp Tomsich 
5371f08aa1cSPhilipp Tomsich 	rk_clrsetreg(&grf->soc_con5,
5381f08aa1cSPhilipp Tomsich 		     RK3399_GMAC_PHY_INTF_SEL_MASK,
5391f08aa1cSPhilipp Tomsich 		     RK3399_GMAC_PHY_INTF_SEL_RGMII);
5401f08aa1cSPhilipp Tomsich 
5411f08aa1cSPhilipp Tomsich 	rk_clrsetreg(&grf->soc_con6,
5421f08aa1cSPhilipp Tomsich 		     RK3399_RXCLK_DLY_ENA_GMAC_MASK |
5431f08aa1cSPhilipp Tomsich 		     RK3399_TXCLK_DLY_ENA_GMAC_MASK |
5441f08aa1cSPhilipp Tomsich 		     RK3399_CLK_RX_DL_CFG_GMAC_MASK |
5451f08aa1cSPhilipp Tomsich 		     RK3399_CLK_TX_DL_CFG_GMAC_MASK,
5461f08aa1cSPhilipp Tomsich 		     RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
5471f08aa1cSPhilipp Tomsich 		     RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
5481f08aa1cSPhilipp Tomsich 		     pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
5491f08aa1cSPhilipp Tomsich 		     pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
5501f08aa1cSPhilipp Tomsich }
5511f08aa1cSPhilipp Tomsich 
5520a33ce65SDavid Wu static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
5530a33ce65SDavid Wu {
5540a33ce65SDavid Wu 	struct rv1108_grf *grf;
5550a33ce65SDavid Wu 
5560a33ce65SDavid Wu 	enum {
5570a33ce65SDavid Wu 		RV1108_GMAC_PHY_INTF_SEL_MASK  = GENMASK(6, 4),
5580a33ce65SDavid Wu 		RV1108_GMAC_PHY_INTF_SEL_RMII  = 4 << 4,
5590a33ce65SDavid Wu 	};
5600a33ce65SDavid Wu 
5610a33ce65SDavid Wu 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
5620a33ce65SDavid Wu 	rk_clrsetreg(&grf->gmac_con0,
5630a33ce65SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_MASK,
5640a33ce65SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
5650a33ce65SDavid Wu }
5660a33ce65SDavid Wu 
5670125bcf0SSjoerd Simons static int gmac_rockchip_probe(struct udevice *dev)
5680125bcf0SSjoerd Simons {
5690125bcf0SSjoerd Simons 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
5701f08aa1cSPhilipp Tomsich 	struct rk_gmac_ops *ops =
5711f08aa1cSPhilipp Tomsich 		(struct rk_gmac_ops *)dev_get_driver_data(dev);
5720a33ce65SDavid Wu 	struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
5730a33ce65SDavid Wu 	struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
5740125bcf0SSjoerd Simons 	struct clk clk;
5750a33ce65SDavid Wu 	ulong rate;
5760125bcf0SSjoerd Simons 	int ret;
5770125bcf0SSjoerd Simons 
578cadc8d74SKever Yang 	/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
579cadc8d74SKever Yang 	ret = clk_set_defaults(dev);
580cadc8d74SKever Yang 	if (ret)
581cadc8d74SKever Yang 		debug("%s clk_set_defaults failed %d\n", __func__, ret);
582cadc8d74SKever Yang 
5830125bcf0SSjoerd Simons 	ret = clk_get_by_index(dev, 0, &clk);
5840125bcf0SSjoerd Simons 	if (ret)
5850125bcf0SSjoerd Simons 		return ret;
5860125bcf0SSjoerd Simons 
5870a33ce65SDavid Wu 	switch (eth_pdata->phy_interface) {
5880a33ce65SDavid Wu 	case PHY_INTERFACE_MODE_RGMII:
5890a33ce65SDavid Wu 		/*
5900a33ce65SDavid Wu 		 * If the gmac clock is from internal pll, need to set and
5910a33ce65SDavid Wu 		 * check the return value for gmac clock at RGMII mode. If
5920a33ce65SDavid Wu 		 * the gmac clock is from external source, the clock rate
5930a33ce65SDavid Wu 		 * is not set, because of it is bypassed.
5940a33ce65SDavid Wu 		 */
5950a33ce65SDavid Wu 		if (!pdata->clock_input) {
5960a33ce65SDavid Wu 			rate = clk_set_rate(&clk, 125000000);
5970a33ce65SDavid Wu 			if (rate != 125000000)
5980a33ce65SDavid Wu 				return -EINVAL;
5990a33ce65SDavid Wu 		}
6000125bcf0SSjoerd Simons 
6010125bcf0SSjoerd Simons 		/* Set to RGMII mode */
6020a33ce65SDavid Wu 		if (ops->set_to_rgmii)
6031f08aa1cSPhilipp Tomsich 			ops->set_to_rgmii(pdata);
6040a33ce65SDavid Wu 		else
6050a33ce65SDavid Wu 			return -EPERM;
6060a33ce65SDavid Wu 
6070a33ce65SDavid Wu 		break;
6080a33ce65SDavid Wu 	case PHY_INTERFACE_MODE_RMII:
6090a33ce65SDavid Wu 		/* The commet is the same as RGMII mode */
6100a33ce65SDavid Wu 		if (!pdata->clock_input) {
6110a33ce65SDavid Wu 			rate = clk_set_rate(&clk, 50000000);
6120a33ce65SDavid Wu 			if (rate != 50000000)
6130a33ce65SDavid Wu 				return -EINVAL;
6140a33ce65SDavid Wu 		}
6150a33ce65SDavid Wu 
6160a33ce65SDavid Wu 		/* Set to RMII mode */
6170a33ce65SDavid Wu 		if (ops->set_to_rmii)
6180a33ce65SDavid Wu 			ops->set_to_rmii(pdata);
6190a33ce65SDavid Wu 		else
6200a33ce65SDavid Wu 			return -EPERM;
6210a33ce65SDavid Wu 
6220a33ce65SDavid Wu 		break;
6230a33ce65SDavid Wu 	default:
6240a33ce65SDavid Wu 		debug("NO interface defined!\n");
6250a33ce65SDavid Wu 		return -ENXIO;
6260a33ce65SDavid Wu 	}
6270125bcf0SSjoerd Simons 
6280125bcf0SSjoerd Simons 	return designware_eth_probe(dev);
6290125bcf0SSjoerd Simons }
6300125bcf0SSjoerd Simons 
6310125bcf0SSjoerd Simons static int gmac_rockchip_eth_start(struct udevice *dev)
6320125bcf0SSjoerd Simons {
6330125bcf0SSjoerd Simons 	struct eth_pdata *pdata = dev_get_platdata(dev);
6340125bcf0SSjoerd Simons 	struct dw_eth_dev *priv = dev_get_priv(dev);
6351f08aa1cSPhilipp Tomsich 	struct rk_gmac_ops *ops =
6361f08aa1cSPhilipp Tomsich 		(struct rk_gmac_ops *)dev_get_driver_data(dev);
6370125bcf0SSjoerd Simons 	int ret;
6380125bcf0SSjoerd Simons 
6390125bcf0SSjoerd Simons 	ret = designware_eth_init(priv, pdata->enetaddr);
6400125bcf0SSjoerd Simons 	if (ret)
6410125bcf0SSjoerd Simons 		return ret;
6421f08aa1cSPhilipp Tomsich 	ret = ops->fix_mac_speed(priv);
6430125bcf0SSjoerd Simons 	if (ret)
6440125bcf0SSjoerd Simons 		return ret;
6450125bcf0SSjoerd Simons 	ret = designware_eth_enable(priv);
6460125bcf0SSjoerd Simons 	if (ret)
6470125bcf0SSjoerd Simons 		return ret;
6480125bcf0SSjoerd Simons 
6490125bcf0SSjoerd Simons 	return 0;
6500125bcf0SSjoerd Simons }
6510125bcf0SSjoerd Simons 
6520125bcf0SSjoerd Simons const struct eth_ops gmac_rockchip_eth_ops = {
6530125bcf0SSjoerd Simons 	.start			= gmac_rockchip_eth_start,
6540125bcf0SSjoerd Simons 	.send			= designware_eth_send,
6550125bcf0SSjoerd Simons 	.recv			= designware_eth_recv,
6560125bcf0SSjoerd Simons 	.free_pkt		= designware_eth_free_pkt,
6570125bcf0SSjoerd Simons 	.stop			= designware_eth_stop,
6580125bcf0SSjoerd Simons 	.write_hwaddr		= designware_eth_write_hwaddr,
6590125bcf0SSjoerd Simons };
6600125bcf0SSjoerd Simons 
661*18ae91c8SDavid Wu const struct rk_gmac_ops px30_gmac_ops = {
662*18ae91c8SDavid Wu 	.fix_mac_speed = px30_gmac_fix_mac_speed,
663*18ae91c8SDavid Wu 	.set_to_rmii = px30_gmac_set_to_rmii,
664*18ae91c8SDavid Wu };
665*18ae91c8SDavid Wu 
666af166ffaSDavid Wu const struct rk_gmac_ops rk3228_gmac_ops = {
667af166ffaSDavid Wu 	.fix_mac_speed = rk3228_gmac_fix_mac_speed,
668af166ffaSDavid Wu 	.set_to_rgmii = rk3228_gmac_set_to_rgmii,
669af166ffaSDavid Wu };
670af166ffaSDavid Wu 
6711f08aa1cSPhilipp Tomsich const struct rk_gmac_ops rk3288_gmac_ops = {
6721f08aa1cSPhilipp Tomsich 	.fix_mac_speed = rk3288_gmac_fix_mac_speed,
6731f08aa1cSPhilipp Tomsich 	.set_to_rgmii = rk3288_gmac_set_to_rgmii,
6741f08aa1cSPhilipp Tomsich };
6751f08aa1cSPhilipp Tomsich 
67623adb58fSDavid Wu const struct rk_gmac_ops rk3308_gmac_ops = {
67723adb58fSDavid Wu 	.fix_mac_speed = rk3308_gmac_fix_mac_speed,
67823adb58fSDavid Wu 	.set_to_rmii = rk3308_gmac_set_to_rmii,
67923adb58fSDavid Wu };
68023adb58fSDavid Wu 
681c36b26c0SDavid Wu const struct rk_gmac_ops rk3328_gmac_ops = {
682c36b26c0SDavid Wu 	.fix_mac_speed = rk3328_gmac_fix_mac_speed,
683c36b26c0SDavid Wu 	.set_to_rgmii = rk3328_gmac_set_to_rgmii,
684c36b26c0SDavid Wu };
685c36b26c0SDavid Wu 
686793f2fd2SPhilipp Tomsich const struct rk_gmac_ops rk3368_gmac_ops = {
687793f2fd2SPhilipp Tomsich 	.fix_mac_speed = rk3368_gmac_fix_mac_speed,
688793f2fd2SPhilipp Tomsich 	.set_to_rgmii = rk3368_gmac_set_to_rgmii,
689793f2fd2SPhilipp Tomsich };
690793f2fd2SPhilipp Tomsich 
6911f08aa1cSPhilipp Tomsich const struct rk_gmac_ops rk3399_gmac_ops = {
6921f08aa1cSPhilipp Tomsich 	.fix_mac_speed = rk3399_gmac_fix_mac_speed,
6931f08aa1cSPhilipp Tomsich 	.set_to_rgmii = rk3399_gmac_set_to_rgmii,
6941f08aa1cSPhilipp Tomsich };
6951f08aa1cSPhilipp Tomsich 
6960a33ce65SDavid Wu const struct rk_gmac_ops rv1108_gmac_ops = {
6970a33ce65SDavid Wu 	.fix_mac_speed = rv1108_set_rmii_speed,
6980a33ce65SDavid Wu 	.set_to_rmii = rv1108_gmac_set_to_rmii,
6990a33ce65SDavid Wu };
7000a33ce65SDavid Wu 
7010125bcf0SSjoerd Simons static const struct udevice_id rockchip_gmac_ids[] = {
702*18ae91c8SDavid Wu 	{ .compatible = "rockchip,px30-gmac",
703*18ae91c8SDavid Wu 	  .data = (ulong)&px30_gmac_ops },
704af166ffaSDavid Wu 	{ .compatible = "rockchip,rk3228-gmac",
705af166ffaSDavid Wu 	  .data = (ulong)&rk3228_gmac_ops },
7061f08aa1cSPhilipp Tomsich 	{ .compatible = "rockchip,rk3288-gmac",
7071f08aa1cSPhilipp Tomsich 	  .data = (ulong)&rk3288_gmac_ops },
70823adb58fSDavid Wu 	{ .compatible = "rockchip,rk3308-mac",
70923adb58fSDavid Wu 	  .data = (ulong)&rk3308_gmac_ops },
710c36b26c0SDavid Wu 	{ .compatible = "rockchip,rk3328-gmac",
711c36b26c0SDavid Wu 	  .data = (ulong)&rk3328_gmac_ops },
712793f2fd2SPhilipp Tomsich 	{ .compatible = "rockchip,rk3368-gmac",
713793f2fd2SPhilipp Tomsich 	  .data = (ulong)&rk3368_gmac_ops },
7141f08aa1cSPhilipp Tomsich 	{ .compatible = "rockchip,rk3399-gmac",
7151f08aa1cSPhilipp Tomsich 	  .data = (ulong)&rk3399_gmac_ops },
7160a33ce65SDavid Wu 	{ .compatible = "rockchip,rv1108-gmac",
7170a33ce65SDavid Wu 	  .data = (ulong)&rv1108_gmac_ops },
7180125bcf0SSjoerd Simons 	{ }
7190125bcf0SSjoerd Simons };
7200125bcf0SSjoerd Simons 
7210125bcf0SSjoerd Simons U_BOOT_DRIVER(eth_gmac_rockchip) = {
7220125bcf0SSjoerd Simons 	.name	= "gmac_rockchip",
7230125bcf0SSjoerd Simons 	.id	= UCLASS_ETH,
7240125bcf0SSjoerd Simons 	.of_match = rockchip_gmac_ids,
7250125bcf0SSjoerd Simons 	.ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
7260125bcf0SSjoerd Simons 	.probe	= gmac_rockchip_probe,
7270125bcf0SSjoerd Simons 	.ops	= &gmac_rockchip_eth_ops,
7280125bcf0SSjoerd Simons 	.priv_auto_alloc_size = sizeof(struct dw_eth_dev),
7290125bcf0SSjoerd Simons 	.platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
7300125bcf0SSjoerd Simons 	.flags = DM_FLAG_ALLOC_PRIV_DMA,
7310125bcf0SSjoerd Simons };
732