xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c (revision b4ac94565c142da9f050e2c2ffd85f7288d556d2)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
27ad269eaSRoger Chen /**
3d0ea5cbdSJesse Brandeburg  * DOC: dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
47ad269eaSRoger Chen  *
57ad269eaSRoger Chen  * Copyright (C) 2014 Chen-Zhi (Roger Chen)
67ad269eaSRoger Chen  *
77ad269eaSRoger Chen  * Chen-Zhi (Roger Chen)  <roger.chen@rock-chips.com>
87ad269eaSRoger Chen  */
97ad269eaSRoger Chen 
107ad269eaSRoger Chen #include <linux/stmmac.h>
117ad269eaSRoger Chen #include <linux/bitops.h>
127ad269eaSRoger Chen #include <linux/clk.h>
137ad269eaSRoger Chen #include <linux/phy.h>
147ad269eaSRoger Chen #include <linux/of_net.h>
157ad269eaSRoger Chen #include <linux/gpio.h>
16e0fb4013SJoachim Eastwood #include <linux/module.h>
177ad269eaSRoger Chen #include <linux/of_gpio.h>
187ad269eaSRoger Chen #include <linux/of_device.h>
19e0fb4013SJoachim Eastwood #include <linux/platform_device.h>
207ad269eaSRoger Chen #include <linux/regulator/consumer.h>
217ad269eaSRoger Chen #include <linux/delay.h>
227ad269eaSRoger Chen #include <linux/mfd/syscon.h>
237ad269eaSRoger Chen #include <linux/regmap.h>
242c896fb0SDavid Wu #include <linux/pm_runtime.h>
257ad269eaSRoger Chen 
26e0fb4013SJoachim Eastwood #include "stmmac_platform.h"
27e0fb4013SJoachim Eastwood 
280fb98db1SHeiko Stübner struct rk_priv_data;
290fb98db1SHeiko Stübner struct rk_gmac_ops {
300fb98db1SHeiko Stübner 	void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
310fb98db1SHeiko Stübner 			     int tx_delay, int rx_delay);
320fb98db1SHeiko Stübner 	void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
330fb98db1SHeiko Stübner 	void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
340fb98db1SHeiko Stübner 	void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
35fecd4d7eSDavid Wu 	void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
360fb98db1SHeiko Stübner };
370fb98db1SHeiko Stübner 
387ad269eaSRoger Chen struct rk_priv_data {
397ad269eaSRoger Chen 	struct platform_device *pdev;
400c65b2b9SAndrew Lunn 	phy_interface_t phy_iface;
412e12f536SRomain Perier 	struct regulator *regulator;
42229666c1SVincent Palatin 	bool suspended;
4392c2588fSJoachim Eastwood 	const struct rk_gmac_ops *ops;
447ad269eaSRoger Chen 
457ad269eaSRoger Chen 	bool clk_enabled;
467ad269eaSRoger Chen 	bool clock_input;
47fecd4d7eSDavid Wu 	bool integrated_phy;
487ad269eaSRoger Chen 
497ad269eaSRoger Chen 	struct clk *clk_mac;
507ad269eaSRoger Chen 	struct clk *gmac_clkin;
517ad269eaSRoger Chen 	struct clk *mac_clk_rx;
527ad269eaSRoger Chen 	struct clk *mac_clk_tx;
537ad269eaSRoger Chen 	struct clk *clk_mac_ref;
547ad269eaSRoger Chen 	struct clk *clk_mac_refout;
5523c94d63SDavid Wu 	struct clk *clk_mac_speed;
567ad269eaSRoger Chen 	struct clk *aclk_mac;
577ad269eaSRoger Chen 	struct clk *pclk_mac;
58fecd4d7eSDavid Wu 	struct clk *clk_phy;
59fecd4d7eSDavid Wu 
60fecd4d7eSDavid Wu 	struct reset_control *phy_reset;
617ad269eaSRoger Chen 
627ad269eaSRoger Chen 	int tx_delay;
637ad269eaSRoger Chen 	int rx_delay;
647ad269eaSRoger Chen 
657ad269eaSRoger Chen 	struct regmap *grf;
667ad269eaSRoger Chen };
677ad269eaSRoger Chen 
687ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \
697ad269eaSRoger Chen 		((val) << (shift) | (mask) << ((shift) + 16))
707ad269eaSRoger Chen 
717ad269eaSRoger Chen #define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
727ad269eaSRoger Chen #define GRF_CLR_BIT(nr)	(BIT(nr+16))
737ad269eaSRoger Chen 
74eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \
75eaf70ad1SWadim Egorov 	(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
76eaf70ad1SWadim Egorov 	 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
77eaf70ad1SWadim Egorov 
7823c94d63SDavid Wu #define PX30_GRF_GMAC_CON1		0x0904
7923c94d63SDavid Wu 
8023c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */
8123c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
8223c94d63SDavid Wu 					 GRF_BIT(6))
8323c94d63SDavid Wu #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
8423c94d63SDavid Wu #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
8523c94d63SDavid Wu 
8623c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
8723c94d63SDavid Wu {
8823c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
8923c94d63SDavid Wu 
9023c94d63SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
9123c94d63SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
9223c94d63SDavid Wu 		return;
9323c94d63SDavid Wu 	}
9423c94d63SDavid Wu 
9523c94d63SDavid Wu 	regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
9623c94d63SDavid Wu 		     PX30_GMAC_PHY_INTF_SEL_RMII);
9723c94d63SDavid Wu }
9823c94d63SDavid Wu 
9923c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
10023c94d63SDavid Wu {
10123c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10223c94d63SDavid Wu 	int ret;
10323c94d63SDavid Wu 
10423c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed)) {
10523c94d63SDavid Wu 		dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
10623c94d63SDavid Wu 		return;
10723c94d63SDavid Wu 	}
10823c94d63SDavid Wu 
10923c94d63SDavid Wu 	if (speed == 10) {
11023c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
11123c94d63SDavid Wu 			     PX30_GMAC_SPEED_10M);
11223c94d63SDavid Wu 
11323c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
11423c94d63SDavid Wu 		if (ret)
11523c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n",
11623c94d63SDavid Wu 				__func__, ret);
11723c94d63SDavid Wu 	} else if (speed == 100) {
11823c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
11923c94d63SDavid Wu 			     PX30_GMAC_SPEED_100M);
12023c94d63SDavid Wu 
12123c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
12223c94d63SDavid Wu 		if (ret)
12323c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n",
12423c94d63SDavid Wu 				__func__, ret);
12523c94d63SDavid Wu 
12623c94d63SDavid Wu 	} else {
12723c94d63SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
12823c94d63SDavid Wu 	}
12923c94d63SDavid Wu }
13023c94d63SDavid Wu 
13123c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = {
13223c94d63SDavid Wu 	.set_to_rmii = px30_set_to_rmii,
13323c94d63SDavid Wu 	.set_rmii_speed = px30_set_rmii_speed,
13423c94d63SDavid Wu };
13523c94d63SDavid Wu 
13605946876SDavid Wu #define RK3128_GRF_MAC_CON0	0x0168
13705946876SDavid Wu #define RK3128_GRF_MAC_CON1	0x016c
13805946876SDavid Wu 
13905946876SDavid Wu /* RK3128_GRF_MAC_CON0 */
14005946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE   GRF_BIT(14)
14105946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(14)
14205946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(15)
14305946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(15)
14405946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
14505946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
14605946876SDavid Wu 
14705946876SDavid Wu /* RK3128_GRF_MAC_CON1 */
14805946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII	\
14905946876SDavid Wu 		(GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
15005946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII	\
15105946876SDavid Wu 		(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
15205946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
15305946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
15405946876SDavid Wu #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
15505946876SDavid Wu #define RK3128_GMAC_SPEED_100M         GRF_BIT(10)
15605946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M       GRF_BIT(11)
15705946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M      GRF_CLR_BIT(11)
15805946876SDavid Wu #define RK3128_GMAC_CLK_125M           (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
15905946876SDavid Wu #define RK3128_GMAC_CLK_25M            (GRF_BIT(12) | GRF_BIT(13))
16005946876SDavid Wu #define RK3128_GMAC_CLK_2_5M           (GRF_CLR_BIT(12) | GRF_BIT(13))
16105946876SDavid Wu #define RK3128_GMAC_RMII_MODE          GRF_BIT(14)
16205946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR      GRF_CLR_BIT(14)
16305946876SDavid Wu 
16405946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
16505946876SDavid Wu 				int tx_delay, int rx_delay)
16605946876SDavid Wu {
16705946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
16805946876SDavid Wu 
16905946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
17005946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
17105946876SDavid Wu 		return;
17205946876SDavid Wu 	}
17305946876SDavid Wu 
17405946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
17505946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RGMII |
17605946876SDavid Wu 		     RK3128_GMAC_RMII_MODE_CLR);
17705946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
17805946876SDavid Wu 		     DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
17905946876SDavid Wu 		     RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
18005946876SDavid Wu 		     RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
18105946876SDavid Wu }
18205946876SDavid Wu 
18305946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
18405946876SDavid Wu {
18505946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
18605946876SDavid Wu 
18705946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
18805946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
18905946876SDavid Wu 		return;
19005946876SDavid Wu 	}
19105946876SDavid Wu 
19205946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
19305946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
19405946876SDavid Wu }
19505946876SDavid Wu 
19605946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
19705946876SDavid Wu {
19805946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
19905946876SDavid Wu 
20005946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
20105946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
20205946876SDavid Wu 		return;
20305946876SDavid Wu 	}
20405946876SDavid Wu 
20505946876SDavid Wu 	if (speed == 10)
20605946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
20705946876SDavid Wu 			     RK3128_GMAC_CLK_2_5M);
20805946876SDavid Wu 	else if (speed == 100)
20905946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21005946876SDavid Wu 			     RK3128_GMAC_CLK_25M);
21105946876SDavid Wu 	else if (speed == 1000)
21205946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21305946876SDavid Wu 			     RK3128_GMAC_CLK_125M);
21405946876SDavid Wu 	else
21505946876SDavid Wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
21605946876SDavid Wu }
21705946876SDavid Wu 
21805946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
21905946876SDavid Wu {
22005946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
22105946876SDavid Wu 
22205946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
22305946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
22405946876SDavid Wu 		return;
22505946876SDavid Wu 	}
22605946876SDavid Wu 
22705946876SDavid Wu 	if (speed == 10) {
22805946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
22905946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_2_5M |
23005946876SDavid Wu 			     RK3128_GMAC_SPEED_10M);
23105946876SDavid Wu 	} else if (speed == 100) {
23205946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23305946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_25M |
23405946876SDavid Wu 			     RK3128_GMAC_SPEED_100M);
23505946876SDavid Wu 	} else {
23605946876SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
23705946876SDavid Wu 	}
23805946876SDavid Wu }
23905946876SDavid Wu 
24005946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = {
24105946876SDavid Wu 	.set_to_rgmii = rk3128_set_to_rgmii,
24205946876SDavid Wu 	.set_to_rmii = rk3128_set_to_rmii,
24305946876SDavid Wu 	.set_rgmii_speed = rk3128_set_rgmii_speed,
24405946876SDavid Wu 	.set_rmii_speed = rk3128_set_rmii_speed,
24505946876SDavid Wu };
24605946876SDavid Wu 
247e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0	0x0900
248e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1	0x0904
249e7ffd812SXing Zheng 
2506fa12c78SDavid Wu #define RK3228_GRF_CON_MUX	0x50
2516fa12c78SDavid Wu 
252e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */
253e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
254e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
255e7ffd812SXing Zheng 
256e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */
257e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII	\
258e7ffd812SXing Zheng 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
259e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII	\
260e7ffd812SXing Zheng 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
261e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
262e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
263e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
264e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M		GRF_BIT(2)
265e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M	GRF_BIT(7)
266e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
267e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M		(GRF_CLR_BIT(8) | GRF_CLR_BIT(9))
268e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M		(GRF_BIT(8) | GRF_BIT(9))
269e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M		(GRF_CLR_BIT(8) | GRF_BIT(9))
270e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE		GRF_BIT(10)
271e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(10)
272e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
273e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
274e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
275e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
276e7ffd812SXing Zheng 
2776fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */
2786fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY	GRF_BIT(15)
2796fa12c78SDavid Wu 
280e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
281e7ffd812SXing Zheng 				int tx_delay, int rx_delay)
282e7ffd812SXing Zheng {
283e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
284e7ffd812SXing Zheng 
285e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
286e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
287e7ffd812SXing Zheng 		return;
288e7ffd812SXing Zheng 	}
289e7ffd812SXing Zheng 
290e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
291e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RGMII |
292e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE_CLR |
293eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3228, tx_delay, rx_delay));
294e7ffd812SXing Zheng 
295e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
296e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
297e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
298e7ffd812SXing Zheng }
299e7ffd812SXing Zheng 
300e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
301e7ffd812SXing Zheng {
302e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
303e7ffd812SXing Zheng 
304e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
305e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
306e7ffd812SXing Zheng 		return;
307e7ffd812SXing Zheng 	}
308e7ffd812SXing Zheng 
309e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
310e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RMII |
311e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE);
312e7ffd812SXing Zheng 
313e7ffd812SXing Zheng 	/* set MAC to RMII mode */
314e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11));
315e7ffd812SXing Zheng }
316e7ffd812SXing Zheng 
317e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
318e7ffd812SXing Zheng {
319e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
320e7ffd812SXing Zheng 
321e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
322e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
323e7ffd812SXing Zheng 		return;
324e7ffd812SXing Zheng 	}
325e7ffd812SXing Zheng 
326e7ffd812SXing Zheng 	if (speed == 10)
327e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
328e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_2_5M);
329e7ffd812SXing Zheng 	else if (speed == 100)
330e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
331e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_25M);
332e7ffd812SXing Zheng 	else if (speed == 1000)
333e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
334e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_125M);
335e7ffd812SXing Zheng 	else
336e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
337e7ffd812SXing Zheng }
338e7ffd812SXing Zheng 
339e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
340e7ffd812SXing Zheng {
341e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
342e7ffd812SXing Zheng 
343e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
344e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
345e7ffd812SXing Zheng 		return;
346e7ffd812SXing Zheng 	}
347e7ffd812SXing Zheng 
348e7ffd812SXing Zheng 	if (speed == 10)
349e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
350e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_2_5M |
351e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_10M);
352e7ffd812SXing Zheng 	else if (speed == 100)
353e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
354e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_25M |
355e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_100M);
356e7ffd812SXing Zheng 	else
357e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
358e7ffd812SXing Zheng }
359e7ffd812SXing Zheng 
3606fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
3616fa12c78SDavid Wu {
3626fa12c78SDavid Wu 	regmap_write(priv->grf, RK3228_GRF_CON_MUX,
3636fa12c78SDavid Wu 		     RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
3646fa12c78SDavid Wu }
3656fa12c78SDavid Wu 
366e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = {
367e7ffd812SXing Zheng 	.set_to_rgmii = rk3228_set_to_rgmii,
368e7ffd812SXing Zheng 	.set_to_rmii = rk3228_set_to_rmii,
369e7ffd812SXing Zheng 	.set_rgmii_speed = rk3228_set_rgmii_speed,
370e7ffd812SXing Zheng 	.set_rmii_speed = rk3228_set_rmii_speed,
3716fa12c78SDavid Wu 	.integrated_phy_powerup =  rk3228_integrated_phy_powerup,
372e7ffd812SXing Zheng };
373e7ffd812SXing Zheng 
3747ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1	0x0248
3757ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3	0x0250
3767ad269eaSRoger Chen 
3777ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/
3780fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | \
3790fb98db1SHeiko Stübner 					 GRF_CLR_BIT(8))
3800fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
3810fb98db1SHeiko Stübner 					 GRF_BIT(8))
3820fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
3830fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
3840fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
3850fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M		GRF_BIT(10)
3860fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M	GRF_BIT(11)
3870fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
3880fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
3890fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
3900fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
3910fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE		GRF_BIT(14)
3920fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
3937ad269eaSRoger Chen 
3947ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/
3950fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
3960fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
3970fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
3980fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
3990fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
4000fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
4017ad269eaSRoger Chen 
4020fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
4037ad269eaSRoger Chen 				int tx_delay, int rx_delay)
4047ad269eaSRoger Chen {
4057ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4067ad269eaSRoger Chen 
4077ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
408d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4097ad269eaSRoger Chen 		return;
4107ad269eaSRoger Chen 	}
4117ad269eaSRoger Chen 
4127ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4130fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
4140fb98db1SHeiko Stübner 		     RK3288_GMAC_RMII_MODE_CLR);
4157ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
416eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
4170fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
4180fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
4197ad269eaSRoger Chen }
4207ad269eaSRoger Chen 
4210fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
4227ad269eaSRoger Chen {
4237ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4247ad269eaSRoger Chen 
4257ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
426d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4277ad269eaSRoger Chen 		return;
4287ad269eaSRoger Chen 	}
4297ad269eaSRoger Chen 
4307ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4310fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
4327ad269eaSRoger Chen }
4337ad269eaSRoger Chen 
4340fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
4357ad269eaSRoger Chen {
4367ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4377ad269eaSRoger Chen 
4387ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
439d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4407ad269eaSRoger Chen 		return;
4417ad269eaSRoger Chen 	}
4427ad269eaSRoger Chen 
4437ad269eaSRoger Chen 	if (speed == 10)
4440fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4450fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_2_5M);
4467ad269eaSRoger Chen 	else if (speed == 100)
4470fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4480fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_25M);
4497ad269eaSRoger Chen 	else if (speed == 1000)
4500fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4510fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_125M);
4527ad269eaSRoger Chen 	else
4537ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
4547ad269eaSRoger Chen }
4557ad269eaSRoger Chen 
4560fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
4577ad269eaSRoger Chen {
4587ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4597ad269eaSRoger Chen 
4607ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
461d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4627ad269eaSRoger Chen 		return;
4637ad269eaSRoger Chen 	}
4647ad269eaSRoger Chen 
4657ad269eaSRoger Chen 	if (speed == 10) {
4667ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4670fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_2_5M |
4680fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_10M);
4697ad269eaSRoger Chen 	} else if (speed == 100) {
4707ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4710fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_25M |
4720fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_100M);
4737ad269eaSRoger Chen 	} else {
4747ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
4757ad269eaSRoger Chen 	}
4767ad269eaSRoger Chen }
4777ad269eaSRoger Chen 
47892c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = {
4790fb98db1SHeiko Stübner 	.set_to_rgmii = rk3288_set_to_rgmii,
4800fb98db1SHeiko Stübner 	.set_to_rmii = rk3288_set_to_rmii,
4810fb98db1SHeiko Stübner 	.set_rgmii_speed = rk3288_set_rgmii_speed,
4820fb98db1SHeiko Stübner 	.set_rmii_speed = rk3288_set_rmii_speed,
4830fb98db1SHeiko Stübner };
4840fb98db1SHeiko Stübner 
485*b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0		0x04a0
486*b4ac9456STobias Schramm 
487*b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */
488*b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \
489*b4ac9456STobias Schramm 					GRF_BIT(4))
490*b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
491*b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
492*b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
493*b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M		GRF_BIT(0)
494*b4ac9456STobias Schramm 
495*b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv)
496*b4ac9456STobias Schramm {
497*b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
498*b4ac9456STobias Schramm 
499*b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
500*b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
501*b4ac9456STobias Schramm 		return;
502*b4ac9456STobias Schramm 	}
503*b4ac9456STobias Schramm 
504*b4ac9456STobias Schramm 	regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
505*b4ac9456STobias Schramm 		     RK3308_GMAC_PHY_INTF_SEL_RMII);
506*b4ac9456STobias Schramm }
507*b4ac9456STobias Schramm 
508*b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
509*b4ac9456STobias Schramm {
510*b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
511*b4ac9456STobias Schramm 
512*b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
513*b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
514*b4ac9456STobias Schramm 		return;
515*b4ac9456STobias Schramm 	}
516*b4ac9456STobias Schramm 
517*b4ac9456STobias Schramm 	if (speed == 10) {
518*b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
519*b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_10M);
520*b4ac9456STobias Schramm 	} else if (speed == 100) {
521*b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
522*b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_100M);
523*b4ac9456STobias Schramm 	} else {
524*b4ac9456STobias Schramm 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
525*b4ac9456STobias Schramm 	}
526*b4ac9456STobias Schramm }
527*b4ac9456STobias Schramm 
528*b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = {
529*b4ac9456STobias Schramm 	.set_to_rmii = rk3308_set_to_rmii,
530*b4ac9456STobias Schramm 	.set_rmii_speed = rk3308_set_rmii_speed,
531*b4ac9456STobias Schramm };
532*b4ac9456STobias Schramm 
533d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0	0x0900
534d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1	0x0904
5358bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2	0x0908
5368bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1	0xb04
537d4ff816eSdavid.wu 
538d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */
539d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
540d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
541d4ff816eSdavid.wu 
542d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */
543d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII	\
544d4ff816eSdavid.wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
545d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII	\
546d4ff816eSdavid.wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
547d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
548d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
549d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
550d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M		GRF_BIT(2)
551d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M	GRF_BIT(7)
552d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
553d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M		(GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
554d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M		(GRF_BIT(11) | GRF_BIT(12))
555d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M		(GRF_CLR_BIT(11) | GRF_BIT(12))
556d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE		GRF_BIT(9)
557d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(9)
558d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
559d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
560d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
561d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
562d4ff816eSdavid.wu 
5638bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */
5648bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE		GRF_BIT(9)
5658bdf63bdSDavid Wu 
566d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
567d4ff816eSdavid.wu 				int tx_delay, int rx_delay)
568d4ff816eSdavid.wu {
569d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
570d4ff816eSdavid.wu 
571d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
572d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
573d4ff816eSdavid.wu 		return;
574d4ff816eSdavid.wu 	}
575d4ff816eSdavid.wu 
576d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
577d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
578d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE_CLR |
579d4ff816eSdavid.wu 		     RK3328_GMAC_RXCLK_DLY_ENABLE |
580d4ff816eSdavid.wu 		     RK3328_GMAC_TXCLK_DLY_ENABLE);
581d4ff816eSdavid.wu 
582d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
583d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
584d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
585d4ff816eSdavid.wu }
586d4ff816eSdavid.wu 
587d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
588d4ff816eSdavid.wu {
589d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
5908bdf63bdSDavid Wu 	unsigned int reg;
591d4ff816eSdavid.wu 
592d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
593d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
594d4ff816eSdavid.wu 		return;
595d4ff816eSdavid.wu 	}
596d4ff816eSdavid.wu 
5978bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
5988bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
5998bdf63bdSDavid Wu 
6008bdf63bdSDavid Wu 	regmap_write(bsp_priv->grf, reg,
601d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RMII |
602d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE);
603d4ff816eSdavid.wu }
604d4ff816eSdavid.wu 
605d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
606d4ff816eSdavid.wu {
607d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
608d4ff816eSdavid.wu 
609d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
610d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
611d4ff816eSdavid.wu 		return;
612d4ff816eSdavid.wu 	}
613d4ff816eSdavid.wu 
614d4ff816eSdavid.wu 	if (speed == 10)
615d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
616d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_2_5M);
617d4ff816eSdavid.wu 	else if (speed == 100)
618d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
619d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_25M);
620d4ff816eSdavid.wu 	else if (speed == 1000)
621d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
622d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_125M);
623d4ff816eSdavid.wu 	else
624d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
625d4ff816eSdavid.wu }
626d4ff816eSdavid.wu 
627d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
628d4ff816eSdavid.wu {
629d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
6308bdf63bdSDavid Wu 	unsigned int reg;
631d4ff816eSdavid.wu 
632d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
633d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
634d4ff816eSdavid.wu 		return;
635d4ff816eSdavid.wu 	}
636d4ff816eSdavid.wu 
6378bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6388bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6398bdf63bdSDavid Wu 
640d4ff816eSdavid.wu 	if (speed == 10)
6418bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
642d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_2_5M |
643d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_10M);
644d4ff816eSdavid.wu 	else if (speed == 100)
6458bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
646d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_25M |
647d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_100M);
648d4ff816eSdavid.wu 	else
649d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
650d4ff816eSdavid.wu }
651d4ff816eSdavid.wu 
6528bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
6538bdf63bdSDavid Wu {
6548bdf63bdSDavid Wu 	regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
6558bdf63bdSDavid Wu 		     RK3328_MACPHY_RMII_MODE);
6568bdf63bdSDavid Wu }
6578bdf63bdSDavid Wu 
658d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = {
659d4ff816eSdavid.wu 	.set_to_rgmii = rk3328_set_to_rgmii,
660d4ff816eSdavid.wu 	.set_to_rmii = rk3328_set_to_rmii,
661d4ff816eSdavid.wu 	.set_rgmii_speed = rk3328_set_rgmii_speed,
662d4ff816eSdavid.wu 	.set_rmii_speed = rk3328_set_rmii_speed,
6638bdf63bdSDavid Wu 	.integrated_phy_powerup =  rk3328_integrated_phy_powerup,
664d4ff816eSdavid.wu };
665d4ff816eSdavid.wu 
666ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6	0x0418
667ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7	0x041c
668ba289af8SRoger Chen 
669ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */
670ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
671ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
672ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
673ba289af8SRoger Chen 					 GRF_BIT(11))
674ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
675ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
676ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
677ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M		GRF_BIT(7)
678ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M	GRF_BIT(3)
679ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
680ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
681ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
682ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
683ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE		GRF_BIT(6)
684ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
685ba289af8SRoger Chen 
686ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */
687ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
688ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
689ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
690ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
691ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
692ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
693ba289af8SRoger Chen 
694ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
695ba289af8SRoger Chen 				int tx_delay, int rx_delay)
696ba289af8SRoger Chen {
697ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
698ba289af8SRoger Chen 
699ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
700ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
701ba289af8SRoger Chen 		return;
702ba289af8SRoger Chen 	}
703ba289af8SRoger Chen 
704ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
705ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RGMII |
706ba289af8SRoger Chen 		     RK3366_GMAC_RMII_MODE_CLR);
707ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
708eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
709ba289af8SRoger Chen 		     RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
710ba289af8SRoger Chen 		     RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
711ba289af8SRoger Chen }
712ba289af8SRoger Chen 
713ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
714ba289af8SRoger Chen {
715ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
716ba289af8SRoger Chen 
717ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
718ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
719ba289af8SRoger Chen 		return;
720ba289af8SRoger Chen 	}
721ba289af8SRoger Chen 
722ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
723ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
724ba289af8SRoger Chen }
725ba289af8SRoger Chen 
726ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
727ba289af8SRoger Chen {
728ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
729ba289af8SRoger Chen 
730ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
731ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
732ba289af8SRoger Chen 		return;
733ba289af8SRoger Chen 	}
734ba289af8SRoger Chen 
735ba289af8SRoger Chen 	if (speed == 10)
736ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
737ba289af8SRoger Chen 			     RK3366_GMAC_CLK_2_5M);
738ba289af8SRoger Chen 	else if (speed == 100)
739ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
740ba289af8SRoger Chen 			     RK3366_GMAC_CLK_25M);
741ba289af8SRoger Chen 	else if (speed == 1000)
742ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
743ba289af8SRoger Chen 			     RK3366_GMAC_CLK_125M);
744ba289af8SRoger Chen 	else
745ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
746ba289af8SRoger Chen }
747ba289af8SRoger Chen 
748ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
749ba289af8SRoger Chen {
750ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
751ba289af8SRoger Chen 
752ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
753ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
754ba289af8SRoger Chen 		return;
755ba289af8SRoger Chen 	}
756ba289af8SRoger Chen 
757ba289af8SRoger Chen 	if (speed == 10) {
758ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
759ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_2_5M |
760ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_10M);
761ba289af8SRoger Chen 	} else if (speed == 100) {
762ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
763ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_25M |
764ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_100M);
765ba289af8SRoger Chen 	} else {
766ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
767ba289af8SRoger Chen 	}
768ba289af8SRoger Chen }
769ba289af8SRoger Chen 
770ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = {
771ba289af8SRoger Chen 	.set_to_rgmii = rk3366_set_to_rgmii,
772ba289af8SRoger Chen 	.set_to_rmii = rk3366_set_to_rmii,
773ba289af8SRoger Chen 	.set_rgmii_speed = rk3366_set_rgmii_speed,
774ba289af8SRoger Chen 	.set_rmii_speed = rk3366_set_rmii_speed,
775ba289af8SRoger Chen };
776ba289af8SRoger Chen 
777df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15	0x043c
778df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16	0x0440
779df558854SHeiko Stübner 
780df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */
781df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
782df558854SHeiko Stübner 					 GRF_CLR_BIT(11))
783df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
784df558854SHeiko Stübner 					 GRF_BIT(11))
785df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
786df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
787df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
788df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M		GRF_BIT(7)
789df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M	GRF_BIT(3)
790df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
791df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
792df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
793df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
794df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE		GRF_BIT(6)
795df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
796df558854SHeiko Stübner 
797df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */
798df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
799df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
800df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
801df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
802df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
803df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
804df558854SHeiko Stübner 
805df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
806df558854SHeiko Stübner 				int tx_delay, int rx_delay)
807df558854SHeiko Stübner {
808df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
809df558854SHeiko Stübner 
810df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
811df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
812df558854SHeiko Stübner 		return;
813df558854SHeiko Stübner 	}
814df558854SHeiko Stübner 
815df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
816df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
817df558854SHeiko Stübner 		     RK3368_GMAC_RMII_MODE_CLR);
818df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
819eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
820df558854SHeiko Stübner 		     RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
821df558854SHeiko Stübner 		     RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
822df558854SHeiko Stübner }
823df558854SHeiko Stübner 
824df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
825df558854SHeiko Stübner {
826df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
827df558854SHeiko Stübner 
828df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
829df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
830df558854SHeiko Stübner 		return;
831df558854SHeiko Stübner 	}
832df558854SHeiko Stübner 
833df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
834df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
835df558854SHeiko Stübner }
836df558854SHeiko Stübner 
837df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
838df558854SHeiko Stübner {
839df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
840df558854SHeiko Stübner 
841df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
842df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
843df558854SHeiko Stübner 		return;
844df558854SHeiko Stübner 	}
845df558854SHeiko Stübner 
846df558854SHeiko Stübner 	if (speed == 10)
847df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
848df558854SHeiko Stübner 			     RK3368_GMAC_CLK_2_5M);
849df558854SHeiko Stübner 	else if (speed == 100)
850df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
851df558854SHeiko Stübner 			     RK3368_GMAC_CLK_25M);
852df558854SHeiko Stübner 	else if (speed == 1000)
853df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
854df558854SHeiko Stübner 			     RK3368_GMAC_CLK_125M);
855df558854SHeiko Stübner 	else
856df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
857df558854SHeiko Stübner }
858df558854SHeiko Stübner 
859df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
860df558854SHeiko Stübner {
861df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
862df558854SHeiko Stübner 
863df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
864df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
865df558854SHeiko Stübner 		return;
866df558854SHeiko Stübner 	}
867df558854SHeiko Stübner 
868df558854SHeiko Stübner 	if (speed == 10) {
869df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
870df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_2_5M |
871df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_10M);
872df558854SHeiko Stübner 	} else if (speed == 100) {
873df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
874df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_25M |
875df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_100M);
876df558854SHeiko Stübner 	} else {
877df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
878df558854SHeiko Stübner 	}
879df558854SHeiko Stübner }
880df558854SHeiko Stübner 
88192c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = {
882df558854SHeiko Stübner 	.set_to_rgmii = rk3368_set_to_rgmii,
883df558854SHeiko Stübner 	.set_to_rmii = rk3368_set_to_rmii,
884df558854SHeiko Stübner 	.set_rgmii_speed = rk3368_set_rgmii_speed,
885df558854SHeiko Stübner 	.set_rmii_speed = rk3368_set_rmii_speed,
886df558854SHeiko Stübner };
887df558854SHeiko Stübner 
888ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5	0xc214
889ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6	0xc218
890ba289af8SRoger Chen 
891ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */
892ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
893ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
894ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
895ba289af8SRoger Chen 					 GRF_BIT(11))
896ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
897ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
898ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
899ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M		GRF_BIT(7)
900ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M	GRF_BIT(3)
901ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
902ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
903ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
904ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
905ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE		GRF_BIT(6)
906ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
907ba289af8SRoger Chen 
908ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */
909ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
910ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
911ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
912ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
913ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
914ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
915ba289af8SRoger Chen 
916ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
917ba289af8SRoger Chen 				int tx_delay, int rx_delay)
918ba289af8SRoger Chen {
919ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
920ba289af8SRoger Chen 
921ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
922ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
923ba289af8SRoger Chen 		return;
924ba289af8SRoger Chen 	}
925ba289af8SRoger Chen 
926ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
927ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RGMII |
928ba289af8SRoger Chen 		     RK3399_GMAC_RMII_MODE_CLR);
929ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
930eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
931ba289af8SRoger Chen 		     RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
932ba289af8SRoger Chen 		     RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
933ba289af8SRoger Chen }
934ba289af8SRoger Chen 
935ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
936ba289af8SRoger Chen {
937ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
938ba289af8SRoger Chen 
939ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
940ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
941ba289af8SRoger Chen 		return;
942ba289af8SRoger Chen 	}
943ba289af8SRoger Chen 
944ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
945ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
946ba289af8SRoger Chen }
947ba289af8SRoger Chen 
948ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
949ba289af8SRoger Chen {
950ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
951ba289af8SRoger Chen 
952ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
953ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
954ba289af8SRoger Chen 		return;
955ba289af8SRoger Chen 	}
956ba289af8SRoger Chen 
957ba289af8SRoger Chen 	if (speed == 10)
958ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
959ba289af8SRoger Chen 			     RK3399_GMAC_CLK_2_5M);
960ba289af8SRoger Chen 	else if (speed == 100)
961ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
962ba289af8SRoger Chen 			     RK3399_GMAC_CLK_25M);
963ba289af8SRoger Chen 	else if (speed == 1000)
964ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
965ba289af8SRoger Chen 			     RK3399_GMAC_CLK_125M);
966ba289af8SRoger Chen 	else
967ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
968ba289af8SRoger Chen }
969ba289af8SRoger Chen 
970ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
971ba289af8SRoger Chen {
972ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
973ba289af8SRoger Chen 
974ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
975ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
976ba289af8SRoger Chen 		return;
977ba289af8SRoger Chen 	}
978ba289af8SRoger Chen 
979ba289af8SRoger Chen 	if (speed == 10) {
980ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
981ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_2_5M |
982ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_10M);
983ba289af8SRoger Chen 	} else if (speed == 100) {
984ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
985ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_25M |
986ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_100M);
987ba289af8SRoger Chen 	} else {
988ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
989ba289af8SRoger Chen 	}
990ba289af8SRoger Chen }
991ba289af8SRoger Chen 
992ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = {
993ba289af8SRoger Chen 	.set_to_rgmii = rk3399_set_to_rgmii,
994ba289af8SRoger Chen 	.set_to_rmii = rk3399_set_to_rmii,
995ba289af8SRoger Chen 	.set_rgmii_speed = rk3399_set_rgmii_speed,
996ba289af8SRoger Chen 	.set_rmii_speed = rk3399_set_rmii_speed,
997ba289af8SRoger Chen };
998ba289af8SRoger Chen 
99989c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0		0X0900
100089c9c163SDavid Wu 
100189c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */
100289c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
100389c9c163SDavid Wu 					GRF_BIT(6))
100489c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
100589c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
100689c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
100789c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M		GRF_BIT(2)
100889c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M	GRF_BIT(7)
100989c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
101089c9c163SDavid Wu 
101189c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
101289c9c163SDavid Wu {
101389c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
101489c9c163SDavid Wu 
101589c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
101689c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
101789c9c163SDavid Wu 		return;
101889c9c163SDavid Wu 	}
101989c9c163SDavid Wu 
102089c9c163SDavid Wu 	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
102189c9c163SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
102289c9c163SDavid Wu }
102389c9c163SDavid Wu 
102489c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
102589c9c163SDavid Wu {
102689c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
102789c9c163SDavid Wu 
102889c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
102989c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
103089c9c163SDavid Wu 		return;
103189c9c163SDavid Wu 	}
103289c9c163SDavid Wu 
103389c9c163SDavid Wu 	if (speed == 10) {
103489c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
103589c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_2_5M |
103689c9c163SDavid Wu 			     RV1108_GMAC_SPEED_10M);
103789c9c163SDavid Wu 	} else if (speed == 100) {
103889c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
103989c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_25M |
104089c9c163SDavid Wu 			     RV1108_GMAC_SPEED_100M);
104189c9c163SDavid Wu 	} else {
104289c9c163SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
104389c9c163SDavid Wu 	}
104489c9c163SDavid Wu }
104589c9c163SDavid Wu 
104689c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = {
104789c9c163SDavid Wu 	.set_to_rmii = rv1108_set_to_rmii,
104889c9c163SDavid Wu 	.set_rmii_speed = rv1108_set_rmii_speed,
104989c9c163SDavid Wu };
105089c9c163SDavid Wu 
1051fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0		0xb00
1052fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1		0xb04
1053fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2		0xb08
1054fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3		0xb0c
1055fecd4d7eSDavid Wu 
1056fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE		GRF_BIT(0)
1057fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
1058fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
1059fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
1060fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID		HIWORD_UPDATE(0x1234, 0xffff, 0)
1061fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID		HIWORD_UPDATE(0x35, 0x3f, 0)
1062fecd4d7eSDavid Wu 
1063fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
10647ad269eaSRoger Chen {
1065fecd4d7eSDavid Wu 	if (priv->ops->integrated_phy_powerup)
1066fecd4d7eSDavid Wu 		priv->ops->integrated_phy_powerup(priv);
1067fecd4d7eSDavid Wu 
1068fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
1069fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
1070fecd4d7eSDavid Wu 
1071fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
1072fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
1073fecd4d7eSDavid Wu 
1074fecd4d7eSDavid Wu 	if (priv->phy_reset) {
1075fecd4d7eSDavid Wu 		/* PHY needs to be disabled before trying to reset it */
1076fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1077fecd4d7eSDavid Wu 		if (priv->phy_reset)
1078fecd4d7eSDavid Wu 			reset_control_assert(priv->phy_reset);
1079fecd4d7eSDavid Wu 		usleep_range(10, 20);
1080fecd4d7eSDavid Wu 		if (priv->phy_reset)
1081fecd4d7eSDavid Wu 			reset_control_deassert(priv->phy_reset);
1082fecd4d7eSDavid Wu 		usleep_range(10, 20);
1083fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
1084fecd4d7eSDavid Wu 		msleep(30);
1085fecd4d7eSDavid Wu 	}
1086fecd4d7eSDavid Wu }
1087fecd4d7eSDavid Wu 
1088fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
1089fecd4d7eSDavid Wu {
1090fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1091fecd4d7eSDavid Wu 	if (priv->phy_reset)
1092fecd4d7eSDavid Wu 		reset_control_assert(priv->phy_reset);
1093fecd4d7eSDavid Wu }
1094fecd4d7eSDavid Wu 
1095fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
1096fecd4d7eSDavid Wu {
1097fecd4d7eSDavid Wu 	struct rk_priv_data *bsp_priv = plat->bsp_priv;
10987ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
1099fecd4d7eSDavid Wu 	int ret;
11007ad269eaSRoger Chen 
11017ad269eaSRoger Chen 	bsp_priv->clk_enabled = false;
11027ad269eaSRoger Chen 
11037ad269eaSRoger Chen 	bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
11047ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_rx))
1105d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1106d42202dcSRomain Perier 			"mac_clk_rx");
11077ad269eaSRoger Chen 
11087ad269eaSRoger Chen 	bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
11097ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_tx))
1110d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1111d42202dcSRomain Perier 			"mac_clk_tx");
11127ad269eaSRoger Chen 
11137ad269eaSRoger Chen 	bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
11147ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->aclk_mac))
1115d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1116d42202dcSRomain Perier 			"aclk_mac");
11177ad269eaSRoger Chen 
11187ad269eaSRoger Chen 	bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
11197ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->pclk_mac))
1120d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1121d42202dcSRomain Perier 			"pclk_mac");
11227ad269eaSRoger Chen 
11237ad269eaSRoger Chen 	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
11247ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->clk_mac))
1125d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1126d42202dcSRomain Perier 			"stmmaceth");
11277ad269eaSRoger Chen 
11287ad269eaSRoger Chen 	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
11297ad269eaSRoger Chen 		bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
11307ad269eaSRoger Chen 		if (IS_ERR(bsp_priv->clk_mac_ref))
1131d42202dcSRomain Perier 			dev_err(dev, "cannot get clock %s\n",
1132d42202dcSRomain Perier 				"clk_mac_ref");
11337ad269eaSRoger Chen 
11347ad269eaSRoger Chen 		if (!bsp_priv->clock_input) {
11357ad269eaSRoger Chen 			bsp_priv->clk_mac_refout =
11367ad269eaSRoger Chen 				devm_clk_get(dev, "clk_mac_refout");
11377ad269eaSRoger Chen 			if (IS_ERR(bsp_priv->clk_mac_refout))
1138d42202dcSRomain Perier 				dev_err(dev, "cannot get clock %s\n",
1139d42202dcSRomain Perier 					"clk_mac_refout");
11407ad269eaSRoger Chen 		}
11417ad269eaSRoger Chen 	}
11427ad269eaSRoger Chen 
114323c94d63SDavid Wu 	bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
114423c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed))
114523c94d63SDavid Wu 		dev_err(dev, "cannot get clock %s\n", "clk_mac_speed");
114623c94d63SDavid Wu 
11477ad269eaSRoger Chen 	if (bsp_priv->clock_input) {
1148d42202dcSRomain Perier 		dev_info(dev, "clock input from PHY\n");
11497ad269eaSRoger Chen 	} else {
11507ad269eaSRoger Chen 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1151c48fa33cSHeiko Stübner 			clk_set_rate(bsp_priv->clk_mac, 50000000);
11527ad269eaSRoger Chen 	}
11537ad269eaSRoger Chen 
1154fecd4d7eSDavid Wu 	if (plat->phy_node && bsp_priv->integrated_phy) {
1155fecd4d7eSDavid Wu 		bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
1156fecd4d7eSDavid Wu 		if (IS_ERR(bsp_priv->clk_phy)) {
1157fecd4d7eSDavid Wu 			ret = PTR_ERR(bsp_priv->clk_phy);
1158fecd4d7eSDavid Wu 			dev_err(dev, "Cannot get PHY clock: %d\n", ret);
1159fecd4d7eSDavid Wu 			return -EINVAL;
1160fecd4d7eSDavid Wu 		}
1161fecd4d7eSDavid Wu 		clk_set_rate(bsp_priv->clk_phy, 50000000);
1162fecd4d7eSDavid Wu 	}
1163fecd4d7eSDavid Wu 
11647ad269eaSRoger Chen 	return 0;
11657ad269eaSRoger Chen }
11667ad269eaSRoger Chen 
11677ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
11687ad269eaSRoger Chen {
1169428ad1bcSLABBE Corentin 	int phy_iface = bsp_priv->phy_iface;
11707ad269eaSRoger Chen 
11717ad269eaSRoger Chen 	if (enable) {
11727ad269eaSRoger Chen 		if (!bsp_priv->clk_enabled) {
11737ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
11747ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->mac_clk_rx))
11757ad269eaSRoger Chen 					clk_prepare_enable(
11767ad269eaSRoger Chen 						bsp_priv->mac_clk_rx);
11777ad269eaSRoger Chen 
11787ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_ref))
11797ad269eaSRoger Chen 					clk_prepare_enable(
11807ad269eaSRoger Chen 						bsp_priv->clk_mac_ref);
11817ad269eaSRoger Chen 
11827ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_refout))
11837ad269eaSRoger Chen 					clk_prepare_enable(
11847ad269eaSRoger Chen 						bsp_priv->clk_mac_refout);
11857ad269eaSRoger Chen 			}
11867ad269eaSRoger Chen 
1187fecd4d7eSDavid Wu 			if (!IS_ERR(bsp_priv->clk_phy))
1188fecd4d7eSDavid Wu 				clk_prepare_enable(bsp_priv->clk_phy);
1189fecd4d7eSDavid Wu 
11907ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->aclk_mac))
11917ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->aclk_mac);
11927ad269eaSRoger Chen 
11937ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->pclk_mac))
11947ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->pclk_mac);
11957ad269eaSRoger Chen 
11967ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->mac_clk_tx))
11977ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->mac_clk_tx);
11987ad269eaSRoger Chen 
119923c94d63SDavid Wu 			if (!IS_ERR(bsp_priv->clk_mac_speed))
120023c94d63SDavid Wu 				clk_prepare_enable(bsp_priv->clk_mac_speed);
120123c94d63SDavid Wu 
12027ad269eaSRoger Chen 			/**
12037ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
12047ad269eaSRoger Chen 			 *	clk_prepare_enable(bsp_priv->clk_mac);
12057ad269eaSRoger Chen 			 */
12067ad269eaSRoger Chen 			mdelay(5);
12077ad269eaSRoger Chen 			bsp_priv->clk_enabled = true;
12087ad269eaSRoger Chen 		}
12097ad269eaSRoger Chen 	} else {
12107ad269eaSRoger Chen 		if (bsp_priv->clk_enabled) {
12117ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
121293120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->mac_clk_rx);
12137ad269eaSRoger Chen 
121493120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_ref);
12157ad269eaSRoger Chen 
121693120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_refout);
12177ad269eaSRoger Chen 			}
12187ad269eaSRoger Chen 
1219fecd4d7eSDavid Wu 			clk_disable_unprepare(bsp_priv->clk_phy);
1220fecd4d7eSDavid Wu 
12217ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->aclk_mac);
12227ad269eaSRoger Chen 
12237ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->pclk_mac);
12247ad269eaSRoger Chen 
12257ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->mac_clk_tx);
122623c94d63SDavid Wu 
122723c94d63SDavid Wu 			clk_disable_unprepare(bsp_priv->clk_mac_speed);
12287ad269eaSRoger Chen 			/**
12297ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
12307ad269eaSRoger Chen 			 *	clk_disable_unprepare(bsp_priv->clk_mac);
12317ad269eaSRoger Chen 			 */
12327ad269eaSRoger Chen 			bsp_priv->clk_enabled = false;
12337ad269eaSRoger Chen 		}
12347ad269eaSRoger Chen 	}
12357ad269eaSRoger Chen 
12367ad269eaSRoger Chen 	return 0;
12377ad269eaSRoger Chen }
12387ad269eaSRoger Chen 
12397ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
12407ad269eaSRoger Chen {
12412e12f536SRomain Perier 	struct regulator *ldo = bsp_priv->regulator;
12427ad269eaSRoger Chen 	int ret;
12437ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
12447ad269eaSRoger Chen 
12453b25528eSChen-Yu Tsai 	if (!ldo)
12463b25528eSChen-Yu Tsai 		return 0;
12477ad269eaSRoger Chen 
12487ad269eaSRoger Chen 	if (enable) {
12497ad269eaSRoger Chen 		ret = regulator_enable(ldo);
12502e12f536SRomain Perier 		if (ret)
1251d42202dcSRomain Perier 			dev_err(dev, "fail to enable phy-supply\n");
12527ad269eaSRoger Chen 	} else {
12537ad269eaSRoger Chen 		ret = regulator_disable(ldo);
12542e12f536SRomain Perier 		if (ret)
1255d42202dcSRomain Perier 			dev_err(dev, "fail to disable phy-supply\n");
12567ad269eaSRoger Chen 	}
12577ad269eaSRoger Chen 
12587ad269eaSRoger Chen 	return 0;
12597ad269eaSRoger Chen }
12607ad269eaSRoger Chen 
12610fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1262fecd4d7eSDavid Wu 					  struct plat_stmmacenet_data *plat,
126392c2588fSJoachim Eastwood 					  const struct rk_gmac_ops *ops)
12647ad269eaSRoger Chen {
12657ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv;
12667ad269eaSRoger Chen 	struct device *dev = &pdev->dev;
12677ad269eaSRoger Chen 	int ret;
12687ad269eaSRoger Chen 	const char *strings = NULL;
12697ad269eaSRoger Chen 	int value;
12707ad269eaSRoger Chen 
12717ad269eaSRoger Chen 	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
12727ad269eaSRoger Chen 	if (!bsp_priv)
12737ad269eaSRoger Chen 		return ERR_PTR(-ENOMEM);
12747ad269eaSRoger Chen 
12750c65b2b9SAndrew Lunn 	of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
12760fb98db1SHeiko Stübner 	bsp_priv->ops = ops;
12777ad269eaSRoger Chen 
12782e12f536SRomain Perier 	bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
12792e12f536SRomain Perier 	if (IS_ERR(bsp_priv->regulator)) {
12802e12f536SRomain Perier 		if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) {
12812e12f536SRomain Perier 			dev_err(dev, "phy regulator is not available yet, deferred probing\n");
12822e12f536SRomain Perier 			return ERR_PTR(-EPROBE_DEFER);
12832e12f536SRomain Perier 		}
12842e12f536SRomain Perier 		dev_err(dev, "no regulator found\n");
12852e12f536SRomain Perier 		bsp_priv->regulator = NULL;
12867ad269eaSRoger Chen 	}
12877ad269eaSRoger Chen 
12887ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
12897ad269eaSRoger Chen 	if (ret) {
1290d42202dcSRomain Perier 		dev_err(dev, "Can not read property: clock_in_out.\n");
12917ad269eaSRoger Chen 		bsp_priv->clock_input = true;
12927ad269eaSRoger Chen 	} else {
1293d42202dcSRomain Perier 		dev_info(dev, "clock input or output? (%s).\n",
1294d42202dcSRomain Perier 			 strings);
12957ad269eaSRoger Chen 		if (!strcmp(strings, "input"))
12967ad269eaSRoger Chen 			bsp_priv->clock_input = true;
12977ad269eaSRoger Chen 		else
12987ad269eaSRoger Chen 			bsp_priv->clock_input = false;
12997ad269eaSRoger Chen 	}
13007ad269eaSRoger Chen 
13017ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
13027ad269eaSRoger Chen 	if (ret) {
13037ad269eaSRoger Chen 		bsp_priv->tx_delay = 0x30;
1304d42202dcSRomain Perier 		dev_err(dev, "Can not read property: tx_delay.");
1305d42202dcSRomain Perier 		dev_err(dev, "set tx_delay to 0x%x\n",
1306d42202dcSRomain Perier 			bsp_priv->tx_delay);
13077ad269eaSRoger Chen 	} else {
1308d42202dcSRomain Perier 		dev_info(dev, "TX delay(0x%x).\n", value);
13097ad269eaSRoger Chen 		bsp_priv->tx_delay = value;
13107ad269eaSRoger Chen 	}
13117ad269eaSRoger Chen 
13127ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
13137ad269eaSRoger Chen 	if (ret) {
13147ad269eaSRoger Chen 		bsp_priv->rx_delay = 0x10;
1315d42202dcSRomain Perier 		dev_err(dev, "Can not read property: rx_delay.");
1316d42202dcSRomain Perier 		dev_err(dev, "set rx_delay to 0x%x\n",
1317d42202dcSRomain Perier 			bsp_priv->rx_delay);
13187ad269eaSRoger Chen 	} else {
1319d42202dcSRomain Perier 		dev_info(dev, "RX delay(0x%x).\n", value);
13207ad269eaSRoger Chen 		bsp_priv->rx_delay = value;
13217ad269eaSRoger Chen 	}
13227ad269eaSRoger Chen 
13237ad269eaSRoger Chen 	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
13247ad269eaSRoger Chen 							"rockchip,grf");
13257ad269eaSRoger Chen 
1326fecd4d7eSDavid Wu 	if (plat->phy_node) {
1327fecd4d7eSDavid Wu 		bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
1328fecd4d7eSDavid Wu 								 "phy-is-integrated");
1329fecd4d7eSDavid Wu 		if (bsp_priv->integrated_phy) {
1330fecd4d7eSDavid Wu 			bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
1331fecd4d7eSDavid Wu 			if (IS_ERR(bsp_priv->phy_reset)) {
1332fecd4d7eSDavid Wu 				dev_err(&pdev->dev, "No PHY reset control found.\n");
1333fecd4d7eSDavid Wu 				bsp_priv->phy_reset = NULL;
1334fecd4d7eSDavid Wu 			}
1335fecd4d7eSDavid Wu 		}
1336fecd4d7eSDavid Wu 	}
1337fecd4d7eSDavid Wu 	dev_info(dev, "integrated PHY? (%s).\n",
1338fecd4d7eSDavid Wu 		 bsp_priv->integrated_phy ? "yes" : "no");
1339fecd4d7eSDavid Wu 
1340fecd4d7eSDavid Wu 	bsp_priv->pdev = pdev;
134145383f52SRoger Chen 
134245383f52SRoger Chen 	return bsp_priv;
134345383f52SRoger Chen }
134445383f52SRoger Chen 
134545383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
134645383f52SRoger Chen {
134745383f52SRoger Chen 	int ret;
134845383f52SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
134945383f52SRoger Chen 
1350f217bfdeSHeiko Stübner 	ret = gmac_clk_enable(bsp_priv, true);
1351f217bfdeSHeiko Stübner 	if (ret)
1352f217bfdeSHeiko Stübner 		return ret;
1353f217bfdeSHeiko Stübner 
13547ad269eaSRoger Chen 	/*rmii or rgmii*/
1355eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1356eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1357d42202dcSRomain Perier 		dev_info(dev, "init for RGMII\n");
13580fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
13590fb98db1SHeiko Stübner 					    bsp_priv->rx_delay);
1360eaf70ad1SWadim Egorov 		break;
1361eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1362eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_ID\n");
1363eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
1364eaf70ad1SWadim Egorov 		break;
1365eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1366eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_RXID\n");
1367eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
1368eaf70ad1SWadim Egorov 		break;
1369eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
1370eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_TXID\n");
1371eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
1372eaf70ad1SWadim Egorov 		break;
1373eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
1374d42202dcSRomain Perier 		dev_info(dev, "init for RMII\n");
13750fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rmii(bsp_priv);
1376eaf70ad1SWadim Egorov 		break;
1377eaf70ad1SWadim Egorov 	default:
1378d42202dcSRomain Perier 		dev_err(dev, "NO interface defined!\n");
13797ad269eaSRoger Chen 	}
13807ad269eaSRoger Chen 
13817ad269eaSRoger Chen 	ret = phy_power_on(bsp_priv, true);
1382c69c29a1SAlexey Khoroshilov 	if (ret) {
1383c69c29a1SAlexey Khoroshilov 		gmac_clk_enable(bsp_priv, false);
13847ad269eaSRoger Chen 		return ret;
1385c69c29a1SAlexey Khoroshilov 	}
13867ad269eaSRoger Chen 
13872c896fb0SDavid Wu 	pm_runtime_enable(dev);
13882c896fb0SDavid Wu 	pm_runtime_get_sync(dev);
13892c896fb0SDavid Wu 
1390fecd4d7eSDavid Wu 	if (bsp_priv->integrated_phy)
1391fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerup(bsp_priv);
1392fecd4d7eSDavid Wu 
13937ad269eaSRoger Chen 	return 0;
13947ad269eaSRoger Chen }
13957ad269eaSRoger Chen 
1396229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac)
13977ad269eaSRoger Chen {
13982c896fb0SDavid Wu 	struct device *dev = &gmac->pdev->dev;
13992c896fb0SDavid Wu 
1400fecd4d7eSDavid Wu 	if (gmac->integrated_phy)
1401fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerdown(gmac);
1402fecd4d7eSDavid Wu 
14032c896fb0SDavid Wu 	pm_runtime_put_sync(dev);
14042c896fb0SDavid Wu 	pm_runtime_disable(dev);
14052c896fb0SDavid Wu 
14067ad269eaSRoger Chen 	phy_power_on(gmac, false);
14077ad269eaSRoger Chen 	gmac_clk_enable(gmac, false);
14087ad269eaSRoger Chen }
14097ad269eaSRoger Chen 
14107ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed)
14117ad269eaSRoger Chen {
14127ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
14137ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
14147ad269eaSRoger Chen 
1415eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1416eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1417eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1418eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1419eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
14200fb98db1SHeiko Stübner 		bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1421eaf70ad1SWadim Egorov 		break;
1422eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
14230fb98db1SHeiko Stübner 		bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1424eaf70ad1SWadim Egorov 		break;
1425eaf70ad1SWadim Egorov 	default:
14267ad269eaSRoger Chen 		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
14277ad269eaSRoger Chen 	}
1428eaf70ad1SWadim Egorov }
14297ad269eaSRoger Chen 
143027ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev)
143127ffefd2SJoachim Eastwood {
143227ffefd2SJoachim Eastwood 	struct plat_stmmacenet_data *plat_dat;
143327ffefd2SJoachim Eastwood 	struct stmmac_resources stmmac_res;
1434f529f182SJoachim Eastwood 	const struct rk_gmac_ops *data;
143527ffefd2SJoachim Eastwood 	int ret;
143627ffefd2SJoachim Eastwood 
1437149adeddSJoachim Eastwood 	data = of_device_get_match_data(&pdev->dev);
1438149adeddSJoachim Eastwood 	if (!data) {
1439149adeddSJoachim Eastwood 		dev_err(&pdev->dev, "no of match data provided\n");
1440149adeddSJoachim Eastwood 		return -EINVAL;
1441149adeddSJoachim Eastwood 	}
1442149adeddSJoachim Eastwood 
144327ffefd2SJoachim Eastwood 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
144427ffefd2SJoachim Eastwood 	if (ret)
144527ffefd2SJoachim Eastwood 		return ret;
144627ffefd2SJoachim Eastwood 
144783216e39SMichael Walle 	plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
144827ffefd2SJoachim Eastwood 	if (IS_ERR(plat_dat))
144927ffefd2SJoachim Eastwood 		return PTR_ERR(plat_dat);
145027ffefd2SJoachim Eastwood 
145127ffefd2SJoachim Eastwood 	plat_dat->has_gmac = true;
145227ffefd2SJoachim Eastwood 	plat_dat->fix_mac_speed = rk_fix_speed;
145327ffefd2SJoachim Eastwood 
1454fecd4d7eSDavid Wu 	plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
1455d2ed0a77SJohan Hovold 	if (IS_ERR(plat_dat->bsp_priv)) {
1456d2ed0a77SJohan Hovold 		ret = PTR_ERR(plat_dat->bsp_priv);
1457d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
1458d2ed0a77SJohan Hovold 	}
145927ffefd2SJoachim Eastwood 
1460fecd4d7eSDavid Wu 	ret = rk_gmac_clk_init(plat_dat);
1461fecd4d7eSDavid Wu 	if (ret)
14629de9aa48SEmil Renner Berthing 		goto err_remove_config_dt;
1463fecd4d7eSDavid Wu 
146407a5e769SJoachim Eastwood 	ret = rk_gmac_powerup(plat_dat->bsp_priv);
146527ffefd2SJoachim Eastwood 	if (ret)
1466d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
146727ffefd2SJoachim Eastwood 
14682d222656SJohan Hovold 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
14692d222656SJohan Hovold 	if (ret)
14702745529aSDavid S. Miller 		goto err_gmac_powerdown;
14712d222656SJohan Hovold 
14722d222656SJohan Hovold 	return 0;
14732d222656SJohan Hovold 
14742745529aSDavid S. Miller err_gmac_powerdown:
14752745529aSDavid S. Miller 	rk_gmac_powerdown(plat_dat->bsp_priv);
1476d2ed0a77SJohan Hovold err_remove_config_dt:
1477d2ed0a77SJohan Hovold 	stmmac_remove_config_dt(pdev, plat_dat);
14782d222656SJohan Hovold 
14792d222656SJohan Hovold 	return ret;
148027ffefd2SJoachim Eastwood }
148127ffefd2SJoachim Eastwood 
14820de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev)
14830de8c4c9SJoachim Eastwood {
14840de8c4c9SJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
14850de8c4c9SJoachim Eastwood 	int ret = stmmac_dvr_remove(&pdev->dev);
14860de8c4c9SJoachim Eastwood 
14870de8c4c9SJoachim Eastwood 	rk_gmac_powerdown(bsp_priv);
14880de8c4c9SJoachim Eastwood 
14890de8c4c9SJoachim Eastwood 	return ret;
14900de8c4c9SJoachim Eastwood }
14910de8c4c9SJoachim Eastwood 
14925619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP
14935619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev)
14945619468aSJoachim Eastwood {
14955619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
14965619468aSJoachim Eastwood 	int ret = stmmac_suspend(dev);
14975619468aSJoachim Eastwood 
14985619468aSJoachim Eastwood 	/* Keep the PHY up if we use Wake-on-Lan. */
14995619468aSJoachim Eastwood 	if (!device_may_wakeup(dev)) {
15005619468aSJoachim Eastwood 		rk_gmac_powerdown(bsp_priv);
15015619468aSJoachim Eastwood 		bsp_priv->suspended = true;
15025619468aSJoachim Eastwood 	}
15035619468aSJoachim Eastwood 
15045619468aSJoachim Eastwood 	return ret;
15055619468aSJoachim Eastwood }
15065619468aSJoachim Eastwood 
15075619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev)
15085619468aSJoachim Eastwood {
15095619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
15105619468aSJoachim Eastwood 
15115619468aSJoachim Eastwood 	/* The PHY was up for Wake-on-Lan. */
15125619468aSJoachim Eastwood 	if (bsp_priv->suspended) {
15135619468aSJoachim Eastwood 		rk_gmac_powerup(bsp_priv);
15145619468aSJoachim Eastwood 		bsp_priv->suspended = false;
15155619468aSJoachim Eastwood 	}
15165619468aSJoachim Eastwood 
15175619468aSJoachim Eastwood 	return stmmac_resume(dev);
15185619468aSJoachim Eastwood }
15195619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */
15205619468aSJoachim Eastwood 
15215619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
15225619468aSJoachim Eastwood 
1523e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = {
152423c94d63SDavid Wu 	{ .compatible = "rockchip,px30-gmac",	.data = &px30_ops   },
152505946876SDavid Wu 	{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
1526e7ffd812SXing Zheng 	{ .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
1527f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
1528*b4ac9456STobias Schramm 	{ .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops },
1529d4ff816eSdavid.wu 	{ .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
1530ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
1531f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
1532ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
153389c9c163SDavid Wu 	{ .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
1534e0fb4013SJoachim Eastwood 	{ }
1535e0fb4013SJoachim Eastwood };
1536e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
1537e0fb4013SJoachim Eastwood 
1538e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = {
153927ffefd2SJoachim Eastwood 	.probe  = rk_gmac_probe,
15400de8c4c9SJoachim Eastwood 	.remove = rk_gmac_remove,
1541e0fb4013SJoachim Eastwood 	.driver = {
1542e0fb4013SJoachim Eastwood 		.name           = "rk_gmac-dwmac",
15435619468aSJoachim Eastwood 		.pm		= &rk_gmac_pm_ops,
1544e0fb4013SJoachim Eastwood 		.of_match_table = rk_gmac_dwmac_match,
1545e0fb4013SJoachim Eastwood 	},
1546e0fb4013SJoachim Eastwood };
1547e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver);
1548e0fb4013SJoachim Eastwood 
1549e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
1550e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
1551e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL");
1552