xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c (revision ff0011cf56014b4dfe88adc35e36a25df63d5005)
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>
24aec3f415SPunit Agrawal #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);
352f2b60a0SDavid Wu 	void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input,
362f2b60a0SDavid Wu 				    bool enable);
37fecd4d7eSDavid Wu 	void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
380546b224SJohn Keeping 	bool regs_valid;
393bb3d6b1SDavid Wu 	u32 regs[];
400fb98db1SHeiko Stübner };
410fb98db1SHeiko Stübner 
427ad269eaSRoger Chen struct rk_priv_data {
437ad269eaSRoger Chen 	struct platform_device *pdev;
440c65b2b9SAndrew Lunn 	phy_interface_t phy_iface;
453bb3d6b1SDavid Wu 	int id;
462e12f536SRomain Perier 	struct regulator *regulator;
47229666c1SVincent Palatin 	bool suspended;
4892c2588fSJoachim Eastwood 	const struct rk_gmac_ops *ops;
497ad269eaSRoger Chen 
507ad269eaSRoger Chen 	bool clk_enabled;
517ad269eaSRoger Chen 	bool clock_input;
52fecd4d7eSDavid Wu 	bool integrated_phy;
537ad269eaSRoger Chen 
547ad269eaSRoger Chen 	struct clk *clk_mac;
557ad269eaSRoger Chen 	struct clk *gmac_clkin;
567ad269eaSRoger Chen 	struct clk *mac_clk_rx;
577ad269eaSRoger Chen 	struct clk *mac_clk_tx;
587ad269eaSRoger Chen 	struct clk *clk_mac_ref;
597ad269eaSRoger Chen 	struct clk *clk_mac_refout;
6023c94d63SDavid Wu 	struct clk *clk_mac_speed;
617ad269eaSRoger Chen 	struct clk *aclk_mac;
627ad269eaSRoger Chen 	struct clk *pclk_mac;
63fecd4d7eSDavid Wu 	struct clk *clk_phy;
64fecd4d7eSDavid Wu 
65fecd4d7eSDavid Wu 	struct reset_control *phy_reset;
667ad269eaSRoger Chen 
677ad269eaSRoger Chen 	int tx_delay;
687ad269eaSRoger Chen 	int rx_delay;
697ad269eaSRoger Chen 
707ad269eaSRoger Chen 	struct regmap *grf;
712f2b60a0SDavid Wu 	struct regmap *php_grf;
727ad269eaSRoger Chen };
737ad269eaSRoger Chen 
747ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \
757ad269eaSRoger Chen 		((val) << (shift) | (mask) << ((shift) + 16))
767ad269eaSRoger Chen 
777ad269eaSRoger Chen #define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
787ad269eaSRoger Chen #define GRF_CLR_BIT(nr)	(BIT(nr+16))
797ad269eaSRoger Chen 
80eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \
81eaf70ad1SWadim Egorov 	(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
82eaf70ad1SWadim Egorov 	 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
83eaf70ad1SWadim Egorov 
8423c94d63SDavid Wu #define PX30_GRF_GMAC_CON1		0x0904
8523c94d63SDavid Wu 
8623c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */
8723c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
8823c94d63SDavid Wu 					 GRF_BIT(6))
8923c94d63SDavid Wu #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
9023c94d63SDavid Wu #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
9123c94d63SDavid Wu 
9223c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
9323c94d63SDavid Wu {
9423c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
9523c94d63SDavid Wu 
9623c94d63SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
9723c94d63SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
9823c94d63SDavid Wu 		return;
9923c94d63SDavid Wu 	}
10023c94d63SDavid Wu 
10123c94d63SDavid Wu 	regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
10223c94d63SDavid Wu 		     PX30_GMAC_PHY_INTF_SEL_RMII);
10323c94d63SDavid Wu }
10423c94d63SDavid Wu 
10523c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
10623c94d63SDavid Wu {
10723c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10823c94d63SDavid Wu 	int ret;
10923c94d63SDavid Wu 
11023c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed)) {
11123c94d63SDavid Wu 		dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
11223c94d63SDavid Wu 		return;
11323c94d63SDavid Wu 	}
11423c94d63SDavid Wu 
11523c94d63SDavid Wu 	if (speed == 10) {
11623c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
11723c94d63SDavid Wu 			     PX30_GMAC_SPEED_10M);
11823c94d63SDavid Wu 
11923c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
12023c94d63SDavid Wu 		if (ret)
12123c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n",
12223c94d63SDavid Wu 				__func__, ret);
12323c94d63SDavid Wu 	} else if (speed == 100) {
12423c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
12523c94d63SDavid Wu 			     PX30_GMAC_SPEED_100M);
12623c94d63SDavid Wu 
12723c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
12823c94d63SDavid Wu 		if (ret)
12923c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n",
13023c94d63SDavid Wu 				__func__, ret);
13123c94d63SDavid Wu 
13223c94d63SDavid Wu 	} else {
13323c94d63SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
13423c94d63SDavid Wu 	}
13523c94d63SDavid Wu }
13623c94d63SDavid Wu 
13723c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = {
13823c94d63SDavid Wu 	.set_to_rmii = px30_set_to_rmii,
13923c94d63SDavid Wu 	.set_rmii_speed = px30_set_rmii_speed,
14023c94d63SDavid Wu };
14123c94d63SDavid Wu 
14205946876SDavid Wu #define RK3128_GRF_MAC_CON0	0x0168
14305946876SDavid Wu #define RK3128_GRF_MAC_CON1	0x016c
14405946876SDavid Wu 
14505946876SDavid Wu /* RK3128_GRF_MAC_CON0 */
14605946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE   GRF_BIT(14)
14705946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(14)
14805946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(15)
14905946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(15)
15005946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
15105946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
15205946876SDavid Wu 
15305946876SDavid Wu /* RK3128_GRF_MAC_CON1 */
15405946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII	\
15505946876SDavid Wu 		(GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
15605946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII	\
15705946876SDavid Wu 		(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
15805946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
15905946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
16005946876SDavid Wu #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
16105946876SDavid Wu #define RK3128_GMAC_SPEED_100M         GRF_BIT(10)
16205946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M       GRF_BIT(11)
16305946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M      GRF_CLR_BIT(11)
16405946876SDavid Wu #define RK3128_GMAC_CLK_125M           (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
16505946876SDavid Wu #define RK3128_GMAC_CLK_25M            (GRF_BIT(12) | GRF_BIT(13))
16605946876SDavid Wu #define RK3128_GMAC_CLK_2_5M           (GRF_CLR_BIT(12) | GRF_BIT(13))
16705946876SDavid Wu #define RK3128_GMAC_RMII_MODE          GRF_BIT(14)
16805946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR      GRF_CLR_BIT(14)
16905946876SDavid Wu 
17005946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
17105946876SDavid Wu 				int tx_delay, int rx_delay)
17205946876SDavid Wu {
17305946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
17405946876SDavid Wu 
17505946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
17605946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
17705946876SDavid Wu 		return;
17805946876SDavid Wu 	}
17905946876SDavid Wu 
18005946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
18105946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RGMII |
18205946876SDavid Wu 		     RK3128_GMAC_RMII_MODE_CLR);
18305946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
18405946876SDavid Wu 		     DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
18505946876SDavid Wu 		     RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
18605946876SDavid Wu 		     RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
18705946876SDavid Wu }
18805946876SDavid Wu 
18905946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
19005946876SDavid Wu {
19105946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
19205946876SDavid Wu 
19305946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
19405946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
19505946876SDavid Wu 		return;
19605946876SDavid Wu 	}
19705946876SDavid Wu 
19805946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
19905946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
20005946876SDavid Wu }
20105946876SDavid Wu 
20205946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
20305946876SDavid Wu {
20405946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
20505946876SDavid Wu 
20605946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
20705946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
20805946876SDavid Wu 		return;
20905946876SDavid Wu 	}
21005946876SDavid Wu 
21105946876SDavid Wu 	if (speed == 10)
21205946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21305946876SDavid Wu 			     RK3128_GMAC_CLK_2_5M);
21405946876SDavid Wu 	else if (speed == 100)
21505946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21605946876SDavid Wu 			     RK3128_GMAC_CLK_25M);
21705946876SDavid Wu 	else if (speed == 1000)
21805946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21905946876SDavid Wu 			     RK3128_GMAC_CLK_125M);
22005946876SDavid Wu 	else
22105946876SDavid Wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
22205946876SDavid Wu }
22305946876SDavid Wu 
22405946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
22505946876SDavid Wu {
22605946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
22705946876SDavid Wu 
22805946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
22905946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
23005946876SDavid Wu 		return;
23105946876SDavid Wu 	}
23205946876SDavid Wu 
23305946876SDavid Wu 	if (speed == 10) {
23405946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23505946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_2_5M |
23605946876SDavid Wu 			     RK3128_GMAC_SPEED_10M);
23705946876SDavid Wu 	} else if (speed == 100) {
23805946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23905946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_25M |
24005946876SDavid Wu 			     RK3128_GMAC_SPEED_100M);
24105946876SDavid Wu 	} else {
24205946876SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
24305946876SDavid Wu 	}
24405946876SDavid Wu }
24505946876SDavid Wu 
24605946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = {
24705946876SDavid Wu 	.set_to_rgmii = rk3128_set_to_rgmii,
24805946876SDavid Wu 	.set_to_rmii = rk3128_set_to_rmii,
24905946876SDavid Wu 	.set_rgmii_speed = rk3128_set_rgmii_speed,
25005946876SDavid Wu 	.set_rmii_speed = rk3128_set_rmii_speed,
25105946876SDavid Wu };
25205946876SDavid Wu 
253e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0	0x0900
254e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1	0x0904
255e7ffd812SXing Zheng 
2566fa12c78SDavid Wu #define RK3228_GRF_CON_MUX	0x50
2576fa12c78SDavid Wu 
258e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */
259e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
260e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
261e7ffd812SXing Zheng 
262e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */
263e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII	\
264e7ffd812SXing Zheng 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
265e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII	\
266e7ffd812SXing Zheng 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
267e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
268e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
269e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
270e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M		GRF_BIT(2)
271e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M	GRF_BIT(7)
272e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
273e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M		(GRF_CLR_BIT(8) | GRF_CLR_BIT(9))
274e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M		(GRF_BIT(8) | GRF_BIT(9))
275e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M		(GRF_CLR_BIT(8) | GRF_BIT(9))
276e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE		GRF_BIT(10)
277e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(10)
278e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
279e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
280e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
281e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
282e7ffd812SXing Zheng 
2836fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */
2846fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY	GRF_BIT(15)
2856fa12c78SDavid Wu 
286e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
287e7ffd812SXing Zheng 				int tx_delay, int rx_delay)
288e7ffd812SXing Zheng {
289e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
290e7ffd812SXing Zheng 
291e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
292e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
293e7ffd812SXing Zheng 		return;
294e7ffd812SXing Zheng 	}
295e7ffd812SXing Zheng 
296e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
297e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RGMII |
298e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE_CLR |
299eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3228, tx_delay, rx_delay));
300e7ffd812SXing Zheng 
301e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
302e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
303e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
304e7ffd812SXing Zheng }
305e7ffd812SXing Zheng 
306e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
307e7ffd812SXing Zheng {
308e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
309e7ffd812SXing Zheng 
310e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
311e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
312e7ffd812SXing Zheng 		return;
313e7ffd812SXing Zheng 	}
314e7ffd812SXing Zheng 
315e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
316e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RMII |
317e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE);
318e7ffd812SXing Zheng 
319e7ffd812SXing Zheng 	/* set MAC to RMII mode */
320e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11));
321e7ffd812SXing Zheng }
322e7ffd812SXing Zheng 
323e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
324e7ffd812SXing Zheng {
325e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
326e7ffd812SXing Zheng 
327e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
328e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
329e7ffd812SXing Zheng 		return;
330e7ffd812SXing Zheng 	}
331e7ffd812SXing Zheng 
332e7ffd812SXing Zheng 	if (speed == 10)
333e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
334e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_2_5M);
335e7ffd812SXing Zheng 	else if (speed == 100)
336e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
337e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_25M);
338e7ffd812SXing Zheng 	else if (speed == 1000)
339e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
340e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_125M);
341e7ffd812SXing Zheng 	else
342e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
343e7ffd812SXing Zheng }
344e7ffd812SXing Zheng 
345e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
346e7ffd812SXing Zheng {
347e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
348e7ffd812SXing Zheng 
349e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
350e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
351e7ffd812SXing Zheng 		return;
352e7ffd812SXing Zheng 	}
353e7ffd812SXing Zheng 
354e7ffd812SXing Zheng 	if (speed == 10)
355e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
356e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_2_5M |
357e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_10M);
358e7ffd812SXing Zheng 	else if (speed == 100)
359e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
360e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_25M |
361e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_100M);
362e7ffd812SXing Zheng 	else
363e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
364e7ffd812SXing Zheng }
365e7ffd812SXing Zheng 
3666fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
3676fa12c78SDavid Wu {
3686fa12c78SDavid Wu 	regmap_write(priv->grf, RK3228_GRF_CON_MUX,
3696fa12c78SDavid Wu 		     RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
3706fa12c78SDavid Wu }
3716fa12c78SDavid Wu 
372e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = {
373e7ffd812SXing Zheng 	.set_to_rgmii = rk3228_set_to_rgmii,
374e7ffd812SXing Zheng 	.set_to_rmii = rk3228_set_to_rmii,
375e7ffd812SXing Zheng 	.set_rgmii_speed = rk3228_set_rgmii_speed,
376e7ffd812SXing Zheng 	.set_rmii_speed = rk3228_set_rmii_speed,
3776fa12c78SDavid Wu 	.integrated_phy_powerup =  rk3228_integrated_phy_powerup,
378e7ffd812SXing Zheng };
379e7ffd812SXing Zheng 
3807ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1	0x0248
3817ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3	0x0250
3827ad269eaSRoger Chen 
3837ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/
3840fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | \
3850fb98db1SHeiko Stübner 					 GRF_CLR_BIT(8))
3860fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
3870fb98db1SHeiko Stübner 					 GRF_BIT(8))
3880fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
3890fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
3900fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
3910fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M		GRF_BIT(10)
3920fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M	GRF_BIT(11)
3930fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
3940fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
3950fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
3960fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
3970fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE		GRF_BIT(14)
3980fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
3997ad269eaSRoger Chen 
4007ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/
4010fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
4020fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
4030fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
4040fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
4050fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
4060fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
4077ad269eaSRoger Chen 
4080fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
4097ad269eaSRoger Chen 				int tx_delay, int rx_delay)
4107ad269eaSRoger Chen {
4117ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4127ad269eaSRoger Chen 
4137ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
414d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4157ad269eaSRoger Chen 		return;
4167ad269eaSRoger Chen 	}
4177ad269eaSRoger Chen 
4187ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4190fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
4200fb98db1SHeiko Stübner 		     RK3288_GMAC_RMII_MODE_CLR);
4217ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
422eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
4230fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
4240fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
4257ad269eaSRoger Chen }
4267ad269eaSRoger Chen 
4270fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
4287ad269eaSRoger Chen {
4297ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4307ad269eaSRoger Chen 
4317ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
432d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4337ad269eaSRoger Chen 		return;
4347ad269eaSRoger Chen 	}
4357ad269eaSRoger Chen 
4367ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4370fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
4387ad269eaSRoger Chen }
4397ad269eaSRoger Chen 
4400fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
4417ad269eaSRoger Chen {
4427ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4437ad269eaSRoger Chen 
4447ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
445d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4467ad269eaSRoger Chen 		return;
4477ad269eaSRoger Chen 	}
4487ad269eaSRoger Chen 
4497ad269eaSRoger Chen 	if (speed == 10)
4500fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4510fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_2_5M);
4527ad269eaSRoger Chen 	else if (speed == 100)
4530fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4540fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_25M);
4557ad269eaSRoger Chen 	else if (speed == 1000)
4560fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4570fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_125M);
4587ad269eaSRoger Chen 	else
4597ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
4607ad269eaSRoger Chen }
4617ad269eaSRoger Chen 
4620fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
4637ad269eaSRoger Chen {
4647ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4657ad269eaSRoger Chen 
4667ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
467d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4687ad269eaSRoger Chen 		return;
4697ad269eaSRoger Chen 	}
4707ad269eaSRoger Chen 
4717ad269eaSRoger Chen 	if (speed == 10) {
4727ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4730fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_2_5M |
4740fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_10M);
4757ad269eaSRoger Chen 	} else if (speed == 100) {
4767ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4770fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_25M |
4780fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_100M);
4797ad269eaSRoger Chen 	} else {
4807ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
4817ad269eaSRoger Chen 	}
4827ad269eaSRoger Chen }
4837ad269eaSRoger Chen 
48492c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = {
4850fb98db1SHeiko Stübner 	.set_to_rgmii = rk3288_set_to_rgmii,
4860fb98db1SHeiko Stübner 	.set_to_rmii = rk3288_set_to_rmii,
4870fb98db1SHeiko Stübner 	.set_rgmii_speed = rk3288_set_rgmii_speed,
4880fb98db1SHeiko Stübner 	.set_rmii_speed = rk3288_set_rmii_speed,
4890fb98db1SHeiko Stübner };
4900fb98db1SHeiko Stübner 
491b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0		0x04a0
492b4ac9456STobias Schramm 
493b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */
494b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \
495b4ac9456STobias Schramm 					GRF_BIT(4))
496b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
497b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
498b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
499b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M		GRF_BIT(0)
500b4ac9456STobias Schramm 
501b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv)
502b4ac9456STobias Schramm {
503b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
504b4ac9456STobias Schramm 
505b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
506b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
507b4ac9456STobias Schramm 		return;
508b4ac9456STobias Schramm 	}
509b4ac9456STobias Schramm 
510b4ac9456STobias Schramm 	regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
511b4ac9456STobias Schramm 		     RK3308_GMAC_PHY_INTF_SEL_RMII);
512b4ac9456STobias Schramm }
513b4ac9456STobias Schramm 
514b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
515b4ac9456STobias Schramm {
516b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
517b4ac9456STobias Schramm 
518b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
519b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
520b4ac9456STobias Schramm 		return;
521b4ac9456STobias Schramm 	}
522b4ac9456STobias Schramm 
523b4ac9456STobias Schramm 	if (speed == 10) {
524b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
525b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_10M);
526b4ac9456STobias Schramm 	} else if (speed == 100) {
527b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
528b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_100M);
529b4ac9456STobias Schramm 	} else {
530b4ac9456STobias Schramm 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
531b4ac9456STobias Schramm 	}
532b4ac9456STobias Schramm }
533b4ac9456STobias Schramm 
534b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = {
535b4ac9456STobias Schramm 	.set_to_rmii = rk3308_set_to_rmii,
536b4ac9456STobias Schramm 	.set_rmii_speed = rk3308_set_rmii_speed,
537b4ac9456STobias Schramm };
538b4ac9456STobias Schramm 
539d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0	0x0900
540d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1	0x0904
5418bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2	0x0908
5428bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1	0xb04
543d4ff816eSdavid.wu 
544d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */
545d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
546d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
547d4ff816eSdavid.wu 
548d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */
549d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII	\
550d4ff816eSdavid.wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
551d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII	\
552d4ff816eSdavid.wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
553d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
554d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
555d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
556d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M		GRF_BIT(2)
557d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M	GRF_BIT(7)
558d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
559d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M		(GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
560d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M		(GRF_BIT(11) | GRF_BIT(12))
561d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M		(GRF_CLR_BIT(11) | GRF_BIT(12))
562d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE		GRF_BIT(9)
563d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(9)
564d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
565d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
566d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
567d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
568d4ff816eSdavid.wu 
5698bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */
5708bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE		GRF_BIT(9)
5718bdf63bdSDavid Wu 
572d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
573d4ff816eSdavid.wu 				int tx_delay, int rx_delay)
574d4ff816eSdavid.wu {
575d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
576d4ff816eSdavid.wu 
577d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
578d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
579d4ff816eSdavid.wu 		return;
580d4ff816eSdavid.wu 	}
581d4ff816eSdavid.wu 
582d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
583d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
584d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE_CLR |
585d4ff816eSdavid.wu 		     RK3328_GMAC_RXCLK_DLY_ENABLE |
586d4ff816eSdavid.wu 		     RK3328_GMAC_TXCLK_DLY_ENABLE);
587d4ff816eSdavid.wu 
588d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
589d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
590d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
591d4ff816eSdavid.wu }
592d4ff816eSdavid.wu 
593d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
594d4ff816eSdavid.wu {
595d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
5968bdf63bdSDavid Wu 	unsigned int reg;
597d4ff816eSdavid.wu 
598d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
599d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
600d4ff816eSdavid.wu 		return;
601d4ff816eSdavid.wu 	}
602d4ff816eSdavid.wu 
6038bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6048bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6058bdf63bdSDavid Wu 
6068bdf63bdSDavid Wu 	regmap_write(bsp_priv->grf, reg,
607d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RMII |
608d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE);
609d4ff816eSdavid.wu }
610d4ff816eSdavid.wu 
611d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
612d4ff816eSdavid.wu {
613d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
614d4ff816eSdavid.wu 
615d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
616d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
617d4ff816eSdavid.wu 		return;
618d4ff816eSdavid.wu 	}
619d4ff816eSdavid.wu 
620d4ff816eSdavid.wu 	if (speed == 10)
621d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
622d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_2_5M);
623d4ff816eSdavid.wu 	else if (speed == 100)
624d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
625d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_25M);
626d4ff816eSdavid.wu 	else if (speed == 1000)
627d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
628d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_125M);
629d4ff816eSdavid.wu 	else
630d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
631d4ff816eSdavid.wu }
632d4ff816eSdavid.wu 
633d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
634d4ff816eSdavid.wu {
635d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
6368bdf63bdSDavid Wu 	unsigned int reg;
637d4ff816eSdavid.wu 
638d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
639d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
640d4ff816eSdavid.wu 		return;
641d4ff816eSdavid.wu 	}
642d4ff816eSdavid.wu 
6438bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6448bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6458bdf63bdSDavid Wu 
646d4ff816eSdavid.wu 	if (speed == 10)
6478bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
648d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_2_5M |
649d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_10M);
650d4ff816eSdavid.wu 	else if (speed == 100)
6518bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
652d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_25M |
653d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_100M);
654d4ff816eSdavid.wu 	else
655d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
656d4ff816eSdavid.wu }
657d4ff816eSdavid.wu 
6588bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
6598bdf63bdSDavid Wu {
6608bdf63bdSDavid Wu 	regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
6618bdf63bdSDavid Wu 		     RK3328_MACPHY_RMII_MODE);
6628bdf63bdSDavid Wu }
6638bdf63bdSDavid Wu 
664d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = {
665d4ff816eSdavid.wu 	.set_to_rgmii = rk3328_set_to_rgmii,
666d4ff816eSdavid.wu 	.set_to_rmii = rk3328_set_to_rmii,
667d4ff816eSdavid.wu 	.set_rgmii_speed = rk3328_set_rgmii_speed,
668d4ff816eSdavid.wu 	.set_rmii_speed = rk3328_set_rmii_speed,
6698bdf63bdSDavid Wu 	.integrated_phy_powerup =  rk3328_integrated_phy_powerup,
670d4ff816eSdavid.wu };
671d4ff816eSdavid.wu 
672ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6	0x0418
673ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7	0x041c
674ba289af8SRoger Chen 
675ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */
676ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
677ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
678ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
679ba289af8SRoger Chen 					 GRF_BIT(11))
680ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
681ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
682ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
683ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M		GRF_BIT(7)
684ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M	GRF_BIT(3)
685ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
686ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
687ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
688ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
689ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE		GRF_BIT(6)
690ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
691ba289af8SRoger Chen 
692ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */
693ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
694ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
695ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
696ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
697ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
698ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
699ba289af8SRoger Chen 
700ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
701ba289af8SRoger Chen 				int tx_delay, int rx_delay)
702ba289af8SRoger Chen {
703ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
704ba289af8SRoger Chen 
705ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
706ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
707ba289af8SRoger Chen 		return;
708ba289af8SRoger Chen 	}
709ba289af8SRoger Chen 
710ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
711ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RGMII |
712ba289af8SRoger Chen 		     RK3366_GMAC_RMII_MODE_CLR);
713ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
714eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
715ba289af8SRoger Chen 		     RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
716ba289af8SRoger Chen 		     RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
717ba289af8SRoger Chen }
718ba289af8SRoger Chen 
719ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
720ba289af8SRoger Chen {
721ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
722ba289af8SRoger Chen 
723ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
724ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
725ba289af8SRoger Chen 		return;
726ba289af8SRoger Chen 	}
727ba289af8SRoger Chen 
728ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
729ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
730ba289af8SRoger Chen }
731ba289af8SRoger Chen 
732ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
733ba289af8SRoger Chen {
734ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
735ba289af8SRoger Chen 
736ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
737ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
738ba289af8SRoger Chen 		return;
739ba289af8SRoger Chen 	}
740ba289af8SRoger Chen 
741ba289af8SRoger Chen 	if (speed == 10)
742ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
743ba289af8SRoger Chen 			     RK3366_GMAC_CLK_2_5M);
744ba289af8SRoger Chen 	else if (speed == 100)
745ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
746ba289af8SRoger Chen 			     RK3366_GMAC_CLK_25M);
747ba289af8SRoger Chen 	else if (speed == 1000)
748ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
749ba289af8SRoger Chen 			     RK3366_GMAC_CLK_125M);
750ba289af8SRoger Chen 	else
751ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
752ba289af8SRoger Chen }
753ba289af8SRoger Chen 
754ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
755ba289af8SRoger Chen {
756ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
757ba289af8SRoger Chen 
758ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
759ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
760ba289af8SRoger Chen 		return;
761ba289af8SRoger Chen 	}
762ba289af8SRoger Chen 
763ba289af8SRoger Chen 	if (speed == 10) {
764ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
765ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_2_5M |
766ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_10M);
767ba289af8SRoger Chen 	} else if (speed == 100) {
768ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
769ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_25M |
770ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_100M);
771ba289af8SRoger Chen 	} else {
772ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
773ba289af8SRoger Chen 	}
774ba289af8SRoger Chen }
775ba289af8SRoger Chen 
776ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = {
777ba289af8SRoger Chen 	.set_to_rgmii = rk3366_set_to_rgmii,
778ba289af8SRoger Chen 	.set_to_rmii = rk3366_set_to_rmii,
779ba289af8SRoger Chen 	.set_rgmii_speed = rk3366_set_rgmii_speed,
780ba289af8SRoger Chen 	.set_rmii_speed = rk3366_set_rmii_speed,
781ba289af8SRoger Chen };
782ba289af8SRoger Chen 
783df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15	0x043c
784df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16	0x0440
785df558854SHeiko Stübner 
786df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */
787df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
788df558854SHeiko Stübner 					 GRF_CLR_BIT(11))
789df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
790df558854SHeiko Stübner 					 GRF_BIT(11))
791df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
792df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
793df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
794df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M		GRF_BIT(7)
795df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M	GRF_BIT(3)
796df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
797df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
798df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
799df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
800df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE		GRF_BIT(6)
801df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
802df558854SHeiko Stübner 
803df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */
804df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
805df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
806df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
807df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
808df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
809df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
810df558854SHeiko Stübner 
811df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
812df558854SHeiko Stübner 				int tx_delay, int rx_delay)
813df558854SHeiko Stübner {
814df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
815df558854SHeiko Stübner 
816df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
817df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
818df558854SHeiko Stübner 		return;
819df558854SHeiko Stübner 	}
820df558854SHeiko Stübner 
821df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
822df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
823df558854SHeiko Stübner 		     RK3368_GMAC_RMII_MODE_CLR);
824df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
825eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
826df558854SHeiko Stübner 		     RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
827df558854SHeiko Stübner 		     RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
828df558854SHeiko Stübner }
829df558854SHeiko Stübner 
830df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
831df558854SHeiko Stübner {
832df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
833df558854SHeiko Stübner 
834df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
835df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
836df558854SHeiko Stübner 		return;
837df558854SHeiko Stübner 	}
838df558854SHeiko Stübner 
839df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
840df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
841df558854SHeiko Stübner }
842df558854SHeiko Stübner 
843df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
844df558854SHeiko Stübner {
845df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
846df558854SHeiko Stübner 
847df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
848df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
849df558854SHeiko Stübner 		return;
850df558854SHeiko Stübner 	}
851df558854SHeiko Stübner 
852df558854SHeiko Stübner 	if (speed == 10)
853df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
854df558854SHeiko Stübner 			     RK3368_GMAC_CLK_2_5M);
855df558854SHeiko Stübner 	else if (speed == 100)
856df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
857df558854SHeiko Stübner 			     RK3368_GMAC_CLK_25M);
858df558854SHeiko Stübner 	else if (speed == 1000)
859df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
860df558854SHeiko Stübner 			     RK3368_GMAC_CLK_125M);
861df558854SHeiko Stübner 	else
862df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
863df558854SHeiko Stübner }
864df558854SHeiko Stübner 
865df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
866df558854SHeiko Stübner {
867df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
868df558854SHeiko Stübner 
869df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
870df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
871df558854SHeiko Stübner 		return;
872df558854SHeiko Stübner 	}
873df558854SHeiko Stübner 
874df558854SHeiko Stübner 	if (speed == 10) {
875df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
876df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_2_5M |
877df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_10M);
878df558854SHeiko Stübner 	} else if (speed == 100) {
879df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
880df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_25M |
881df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_100M);
882df558854SHeiko Stübner 	} else {
883df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
884df558854SHeiko Stübner 	}
885df558854SHeiko Stübner }
886df558854SHeiko Stübner 
88792c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = {
888df558854SHeiko Stübner 	.set_to_rgmii = rk3368_set_to_rgmii,
889df558854SHeiko Stübner 	.set_to_rmii = rk3368_set_to_rmii,
890df558854SHeiko Stübner 	.set_rgmii_speed = rk3368_set_rgmii_speed,
891df558854SHeiko Stübner 	.set_rmii_speed = rk3368_set_rmii_speed,
892df558854SHeiko Stübner };
893df558854SHeiko Stübner 
894ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5	0xc214
895ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6	0xc218
896ba289af8SRoger Chen 
897ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */
898ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
899ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
900ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
901ba289af8SRoger Chen 					 GRF_BIT(11))
902ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
903ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
904ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
905ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M		GRF_BIT(7)
906ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M	GRF_BIT(3)
907ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
908ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
909ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
910ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
911ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE		GRF_BIT(6)
912ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
913ba289af8SRoger Chen 
914ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */
915ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
916ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
917ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
918ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
919ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
920ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
921ba289af8SRoger Chen 
922ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
923ba289af8SRoger Chen 				int tx_delay, int rx_delay)
924ba289af8SRoger Chen {
925ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
926ba289af8SRoger Chen 
927ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
928ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
929ba289af8SRoger Chen 		return;
930ba289af8SRoger Chen 	}
931ba289af8SRoger Chen 
932ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
933ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RGMII |
934ba289af8SRoger Chen 		     RK3399_GMAC_RMII_MODE_CLR);
935ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
936eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
937ba289af8SRoger Chen 		     RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
938ba289af8SRoger Chen 		     RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
939ba289af8SRoger Chen }
940ba289af8SRoger Chen 
941ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
942ba289af8SRoger Chen {
943ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
944ba289af8SRoger Chen 
945ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
946ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
947ba289af8SRoger Chen 		return;
948ba289af8SRoger Chen 	}
949ba289af8SRoger Chen 
950ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
951ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
952ba289af8SRoger Chen }
953ba289af8SRoger Chen 
954ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
955ba289af8SRoger Chen {
956ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
957ba289af8SRoger Chen 
958ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
959ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
960ba289af8SRoger Chen 		return;
961ba289af8SRoger Chen 	}
962ba289af8SRoger Chen 
963ba289af8SRoger Chen 	if (speed == 10)
964ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
965ba289af8SRoger Chen 			     RK3399_GMAC_CLK_2_5M);
966ba289af8SRoger Chen 	else if (speed == 100)
967ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
968ba289af8SRoger Chen 			     RK3399_GMAC_CLK_25M);
969ba289af8SRoger Chen 	else if (speed == 1000)
970ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
971ba289af8SRoger Chen 			     RK3399_GMAC_CLK_125M);
972ba289af8SRoger Chen 	else
973ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
974ba289af8SRoger Chen }
975ba289af8SRoger Chen 
976ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
977ba289af8SRoger Chen {
978ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
979ba289af8SRoger Chen 
980ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
981ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
982ba289af8SRoger Chen 		return;
983ba289af8SRoger Chen 	}
984ba289af8SRoger Chen 
985ba289af8SRoger Chen 	if (speed == 10) {
986ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
987ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_2_5M |
988ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_10M);
989ba289af8SRoger Chen 	} else if (speed == 100) {
990ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
991ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_25M |
992ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_100M);
993ba289af8SRoger Chen 	} else {
994ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
995ba289af8SRoger Chen 	}
996ba289af8SRoger Chen }
997ba289af8SRoger Chen 
998ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = {
999ba289af8SRoger Chen 	.set_to_rgmii = rk3399_set_to_rgmii,
1000ba289af8SRoger Chen 	.set_to_rmii = rk3399_set_to_rmii,
1001ba289af8SRoger Chen 	.set_rgmii_speed = rk3399_set_rgmii_speed,
1002ba289af8SRoger Chen 	.set_rmii_speed = rk3399_set_rmii_speed,
1003ba289af8SRoger Chen };
1004ba289af8SRoger Chen 
10053bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON0		0x0380
10063bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON1		0x0384
10073bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON0		0x0388
10083bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON1		0x038c
10093bb3d6b1SDavid Wu 
10103bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
10113bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RGMII	\
10123bb3d6b1SDavid Wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
10133bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RMII	\
10143bb3d6b1SDavid Wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
10153bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
10163bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
10173bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
10183bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_DISABLE		GRF_CLR_BIT(1)
10193bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_ENABLE		GRF_BIT(0)
10203bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_DISABLE		GRF_CLR_BIT(0)
10213bb3d6b1SDavid Wu 
10223bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
10233bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
10243bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
10253bb3d6b1SDavid Wu 
10263bb3d6b1SDavid Wu static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,
10273bb3d6b1SDavid Wu 				int tx_delay, int rx_delay)
10283bb3d6b1SDavid Wu {
10293bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10303bb3d6b1SDavid Wu 	u32 con0, con1;
10313bb3d6b1SDavid Wu 
10323bb3d6b1SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10333bb3d6b1SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
10343bb3d6b1SDavid Wu 		return;
10353bb3d6b1SDavid Wu 	}
10363bb3d6b1SDavid Wu 
10373bb3d6b1SDavid Wu 	con0 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON0 :
10383bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON0;
10393bb3d6b1SDavid Wu 	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10403bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON1;
10413bb3d6b1SDavid Wu 
10423bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con0,
10433bb3d6b1SDavid Wu 		     RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) |
10443bb3d6b1SDavid Wu 		     RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
10453bb3d6b1SDavid Wu 
10463bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con1,
10473bb3d6b1SDavid Wu 		     RK3568_GMAC_PHY_INTF_SEL_RGMII |
10483bb3d6b1SDavid Wu 		     RK3568_GMAC_RXCLK_DLY_ENABLE |
10493bb3d6b1SDavid Wu 		     RK3568_GMAC_TXCLK_DLY_ENABLE);
10503bb3d6b1SDavid Wu }
10513bb3d6b1SDavid Wu 
10523bb3d6b1SDavid Wu static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv)
10533bb3d6b1SDavid Wu {
10543bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10553bb3d6b1SDavid Wu 	u32 con1;
10563bb3d6b1SDavid Wu 
10573bb3d6b1SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10583bb3d6b1SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
10593bb3d6b1SDavid Wu 		return;
10603bb3d6b1SDavid Wu 	}
10613bb3d6b1SDavid Wu 
10623bb3d6b1SDavid Wu 	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10633bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON1;
10643bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
10653bb3d6b1SDavid Wu }
10663bb3d6b1SDavid Wu 
10673bb3d6b1SDavid Wu static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
10683bb3d6b1SDavid Wu {
10693bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10703bb3d6b1SDavid Wu 	unsigned long rate;
10713bb3d6b1SDavid Wu 	int ret;
10723bb3d6b1SDavid Wu 
10733bb3d6b1SDavid Wu 	switch (speed) {
10743bb3d6b1SDavid Wu 	case 10:
10753bb3d6b1SDavid Wu 		rate = 2500000;
10763bb3d6b1SDavid Wu 		break;
10773bb3d6b1SDavid Wu 	case 100:
10783bb3d6b1SDavid Wu 		rate = 25000000;
10793bb3d6b1SDavid Wu 		break;
10803bb3d6b1SDavid Wu 	case 1000:
10813bb3d6b1SDavid Wu 		rate = 125000000;
10823bb3d6b1SDavid Wu 		break;
10833bb3d6b1SDavid Wu 	default:
10843bb3d6b1SDavid Wu 		dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
10853bb3d6b1SDavid Wu 		return;
10863bb3d6b1SDavid Wu 	}
10873bb3d6b1SDavid Wu 
10883bb3d6b1SDavid Wu 	ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
10893bb3d6b1SDavid Wu 	if (ret)
10903bb3d6b1SDavid Wu 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
10913bb3d6b1SDavid Wu 			__func__, rate, ret);
10923bb3d6b1SDavid Wu }
10933bb3d6b1SDavid Wu 
10943bb3d6b1SDavid Wu static const struct rk_gmac_ops rk3568_ops = {
10953bb3d6b1SDavid Wu 	.set_to_rgmii = rk3568_set_to_rgmii,
10963bb3d6b1SDavid Wu 	.set_to_rmii = rk3568_set_to_rmii,
10973bb3d6b1SDavid Wu 	.set_rgmii_speed = rk3568_set_gmac_speed,
10983bb3d6b1SDavid Wu 	.set_rmii_speed = rk3568_set_gmac_speed,
10990546b224SJohn Keeping 	.regs_valid = true,
11003bb3d6b1SDavid Wu 	.regs = {
11013bb3d6b1SDavid Wu 		0xfe2a0000, /* gmac0 */
11023bb3d6b1SDavid Wu 		0xfe010000, /* gmac1 */
11033bb3d6b1SDavid Wu 		0x0, /* sentinel */
11043bb3d6b1SDavid Wu 	},
11053bb3d6b1SDavid Wu };
11063bb3d6b1SDavid Wu 
11072f2b60a0SDavid Wu /* sys_grf */
11082f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON7			0X031c
11092f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON8			0X0320
11102f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON9			0X0324
11112f2b60a0SDavid Wu 
11122f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 3)
11132f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 3)
11142f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 2)
11152f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 2)
11162f2b60a0SDavid Wu 
11172f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 8)
11182f2b60a0SDavid Wu #define RK3588_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 0)
11192f2b60a0SDavid Wu 
11202f2b60a0SDavid Wu /* php_grf */
11212f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON0			0X0008
11222f2b60a0SDavid Wu #define RK3588_GRF_CLK_CON1			0X0070
11232f2b60a0SDavid Wu 
11242f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
11252f2b60a0SDavid Wu 	(GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
11262f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
11272f2b60a0SDavid Wu 	(GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
11282f2b60a0SDavid Wu 
11292f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
11302f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
11312f2b60a0SDavid Wu 
11322f2b60a0SDavid Wu #define RK3588_GMAC_CLK_SELET_CRU(id)		GRF_BIT(5 * (id) + 4)
11332f2b60a0SDavid Wu #define RK3588_GMAC_CLK_SELET_IO(id)		GRF_CLR_BIT(5 * (id) + 4)
11342f2b60a0SDavid Wu 
11352f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV2(id)		GRF_BIT(5 * (id) + 2)
11362f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV20(id)		GRF_CLR_BIT(5 * (id) + 2)
11372f2b60a0SDavid Wu 
11382f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV1(id)		\
11392f2b60a0SDavid Wu 			(GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
11402f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV5(id)		\
11412f2b60a0SDavid Wu 			(GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
11422f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV50(id)		\
11432f2b60a0SDavid Wu 			(GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
11442f2b60a0SDavid Wu 
11452f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_GATE(id)		GRF_BIT(5 * (id) + 1)
11462f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_NOGATE(id)		GRF_CLR_BIT(5 * (id) + 1)
11472f2b60a0SDavid Wu 
11482f2b60a0SDavid Wu static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
11492f2b60a0SDavid Wu 				int tx_delay, int rx_delay)
11502f2b60a0SDavid Wu {
11512f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
11522f2b60a0SDavid Wu 	u32 offset_con, id = bsp_priv->id;
11532f2b60a0SDavid Wu 
11542f2b60a0SDavid Wu 	if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
11552f2b60a0SDavid Wu 		dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n");
11562f2b60a0SDavid Wu 		return;
11572f2b60a0SDavid Wu 	}
11582f2b60a0SDavid Wu 
11592f2b60a0SDavid Wu 	offset_con = bsp_priv->id == 1 ? RK3588_GRF_GMAC_CON9 :
11602f2b60a0SDavid Wu 					 RK3588_GRF_GMAC_CON8;
11612f2b60a0SDavid Wu 
11622f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
11632f2b60a0SDavid Wu 		     RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
11642f2b60a0SDavid Wu 
11652f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
11662f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RGMII_MODE(id));
11672f2b60a0SDavid Wu 
11682f2b60a0SDavid Wu 	regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7,
11692f2b60a0SDavid Wu 		     RK3588_GMAC_RXCLK_DLY_ENABLE(id) |
11702f2b60a0SDavid Wu 		     RK3588_GMAC_TXCLK_DLY_ENABLE(id));
11712f2b60a0SDavid Wu 
11722f2b60a0SDavid Wu 	regmap_write(bsp_priv->grf, offset_con,
11732f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
11742f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
11752f2b60a0SDavid Wu }
11762f2b60a0SDavid Wu 
11772f2b60a0SDavid Wu static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv)
11782f2b60a0SDavid Wu {
11792f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
11802f2b60a0SDavid Wu 
11812f2b60a0SDavid Wu 	if (IS_ERR(bsp_priv->php_grf)) {
11822f2b60a0SDavid Wu 		dev_err(dev, "%s: Missing rockchip,php_grf property\n", __func__);
11832f2b60a0SDavid Wu 		return;
11842f2b60a0SDavid Wu 	}
11852f2b60a0SDavid Wu 
11862f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
11872f2b60a0SDavid Wu 		     RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->id));
11882f2b60a0SDavid Wu 
11892f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
11902f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id));
11912f2b60a0SDavid Wu }
11922f2b60a0SDavid Wu 
11932f2b60a0SDavid Wu static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
11942f2b60a0SDavid Wu {
11952f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
11962f2b60a0SDavid Wu 	unsigned int val = 0, id = bsp_priv->id;
11972f2b60a0SDavid Wu 
11982f2b60a0SDavid Wu 	switch (speed) {
11992f2b60a0SDavid Wu 	case 10:
12002f2b60a0SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
12012f2b60a0SDavid Wu 			val = RK3588_GMA_CLK_RMII_DIV20(id);
12022f2b60a0SDavid Wu 		else
12032f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV50(id);
12042f2b60a0SDavid Wu 		break;
12052f2b60a0SDavid Wu 	case 100:
12062f2b60a0SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
12072f2b60a0SDavid Wu 			val = RK3588_GMA_CLK_RMII_DIV2(id);
12082f2b60a0SDavid Wu 		else
12092f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV5(id);
12102f2b60a0SDavid Wu 		break;
12112f2b60a0SDavid Wu 	case 1000:
12122f2b60a0SDavid Wu 		if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
12132f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV1(id);
12142f2b60a0SDavid Wu 		else
12152f2b60a0SDavid Wu 			goto err;
12162f2b60a0SDavid Wu 		break;
12172f2b60a0SDavid Wu 	default:
12182f2b60a0SDavid Wu 		goto err;
12192f2b60a0SDavid Wu 	}
12202f2b60a0SDavid Wu 
12212f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
12222f2b60a0SDavid Wu 
12232f2b60a0SDavid Wu 	return;
12242f2b60a0SDavid Wu err:
12252f2b60a0SDavid Wu 	dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
12262f2b60a0SDavid Wu }
12272f2b60a0SDavid Wu 
12282f2b60a0SDavid Wu static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input,
12292f2b60a0SDavid Wu 				       bool enable)
12302f2b60a0SDavid Wu {
12312f2b60a0SDavid Wu 	unsigned int val = input ? RK3588_GMAC_CLK_SELET_IO(bsp_priv->id) :
12322f2b60a0SDavid Wu 				   RK3588_GMAC_CLK_SELET_CRU(bsp_priv->id);
12332f2b60a0SDavid Wu 
12342f2b60a0SDavid Wu 	val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->id) :
12352f2b60a0SDavid Wu 			RK3588_GMAC_CLK_RMII_GATE(bsp_priv->id);
12362f2b60a0SDavid Wu 
12372f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
12382f2b60a0SDavid Wu }
12392f2b60a0SDavid Wu 
12402f2b60a0SDavid Wu static const struct rk_gmac_ops rk3588_ops = {
12412f2b60a0SDavid Wu 	.set_to_rgmii = rk3588_set_to_rgmii,
12422f2b60a0SDavid Wu 	.set_to_rmii = rk3588_set_to_rmii,
12432f2b60a0SDavid Wu 	.set_rgmii_speed = rk3588_set_gmac_speed,
12442f2b60a0SDavid Wu 	.set_rmii_speed = rk3588_set_gmac_speed,
12452f2b60a0SDavid Wu 	.set_clock_selection = rk3588_set_clock_selection,
124688619e77SBenjamin Gaignard 	.regs_valid = true,
124788619e77SBenjamin Gaignard 	.regs = {
124888619e77SBenjamin Gaignard 		0xfe1b0000, /* gmac0 */
124988619e77SBenjamin Gaignard 		0xfe1c0000, /* gmac1 */
125088619e77SBenjamin Gaignard 		0x0, /* sentinel */
125188619e77SBenjamin Gaignard 	},
12522f2b60a0SDavid Wu };
12532f2b60a0SDavid Wu 
125489c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0		0X0900
125589c9c163SDavid Wu 
125689c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */
125789c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
125889c9c163SDavid Wu 					GRF_BIT(6))
125989c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
126089c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
126189c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
126289c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M		GRF_BIT(2)
126389c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M	GRF_BIT(7)
126489c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
126589c9c163SDavid Wu 
126689c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
126789c9c163SDavid Wu {
126889c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
126989c9c163SDavid Wu 
127089c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
127189c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
127289c9c163SDavid Wu 		return;
127389c9c163SDavid Wu 	}
127489c9c163SDavid Wu 
127589c9c163SDavid Wu 	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
127689c9c163SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
127789c9c163SDavid Wu }
127889c9c163SDavid Wu 
127989c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
128089c9c163SDavid Wu {
128189c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
128289c9c163SDavid Wu 
128389c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
128489c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
128589c9c163SDavid Wu 		return;
128689c9c163SDavid Wu 	}
128789c9c163SDavid Wu 
128889c9c163SDavid Wu 	if (speed == 10) {
128989c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
129089c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_2_5M |
129189c9c163SDavid Wu 			     RV1108_GMAC_SPEED_10M);
129289c9c163SDavid Wu 	} else if (speed == 100) {
129389c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
129489c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_25M |
129589c9c163SDavid Wu 			     RV1108_GMAC_SPEED_100M);
129689c9c163SDavid Wu 	} else {
129789c9c163SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
129889c9c163SDavid Wu 	}
129989c9c163SDavid Wu }
130089c9c163SDavid Wu 
130189c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = {
130289c9c163SDavid Wu 	.set_to_rmii = rv1108_set_to_rmii,
130389c9c163SDavid Wu 	.set_rmii_speed = rv1108_set_rmii_speed,
130489c9c163SDavid Wu };
130589c9c163SDavid Wu 
1306c931b060SAnand Moon #define RV1126_GRF_GMAC_CON0		0X0070
1307c931b060SAnand Moon #define RV1126_GRF_GMAC_CON1		0X0074
1308c931b060SAnand Moon #define RV1126_GRF_GMAC_CON2		0X0078
1309c931b060SAnand Moon 
1310c931b060SAnand Moon /* RV1126_GRF_GMAC_CON0 */
1311c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RGMII	\
1312c931b060SAnand Moon 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
1313c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RMII	\
1314c931b060SAnand Moon 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
1315c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL			GRF_BIT(7)
1316c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(7)
1317c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE		GRF_BIT(1)
1318c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
1319c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_ENABLE		GRF_BIT(0)
1320c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
1321c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_ENABLE		GRF_BIT(3)
1322c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_DISABLE	GRF_CLR_BIT(3)
1323c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_ENABLE		GRF_BIT(2)
1324c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_DISABLE	GRF_CLR_BIT(2)
1325c931b060SAnand Moon 
1326c931b060SAnand Moon /* RV1126_GRF_GMAC_CON1 */
1327c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
1328c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
1329c931b060SAnand Moon /* RV1126_GRF_GMAC_CON2 */
1330c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
1331c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
1332c931b060SAnand Moon 
1333c931b060SAnand Moon static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
1334c931b060SAnand Moon 				int tx_delay, int rx_delay)
1335c931b060SAnand Moon {
1336c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1337c931b060SAnand Moon 
1338c931b060SAnand Moon 	if (IS_ERR(bsp_priv->grf)) {
1339c931b060SAnand Moon 		dev_err(dev, "Missing rockchip,grf property\n");
1340c931b060SAnand Moon 		return;
1341c931b060SAnand Moon 	}
1342c931b060SAnand Moon 
1343c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1344c931b060SAnand Moon 		     RV1126_GMAC_PHY_INTF_SEL_RGMII |
1345c931b060SAnand Moon 		     RV1126_GMAC_M0_RXCLK_DLY_ENABLE |
1346c931b060SAnand Moon 		     RV1126_GMAC_M0_TXCLK_DLY_ENABLE |
1347c931b060SAnand Moon 		     RV1126_GMAC_M1_RXCLK_DLY_ENABLE |
1348c931b060SAnand Moon 		     RV1126_GMAC_M1_TXCLK_DLY_ENABLE);
1349c931b060SAnand Moon 
1350c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1,
1351c931b060SAnand Moon 		     RV1126_GMAC_M0_CLK_RX_DL_CFG(rx_delay) |
1352c931b060SAnand Moon 		     RV1126_GMAC_M0_CLK_TX_DL_CFG(tx_delay));
1353c931b060SAnand Moon 
1354c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2,
1355c931b060SAnand Moon 		     RV1126_GMAC_M1_CLK_RX_DL_CFG(rx_delay) |
1356c931b060SAnand Moon 		     RV1126_GMAC_M1_CLK_TX_DL_CFG(tx_delay));
1357c931b060SAnand Moon }
1358c931b060SAnand Moon 
1359c931b060SAnand Moon static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv)
1360c931b060SAnand Moon {
1361c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1362c931b060SAnand Moon 
1363c931b060SAnand Moon 	if (IS_ERR(bsp_priv->grf)) {
1364c931b060SAnand Moon 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1365c931b060SAnand Moon 		return;
1366c931b060SAnand Moon 	}
1367c931b060SAnand Moon 
1368c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1369c931b060SAnand Moon 		     RV1126_GMAC_PHY_INTF_SEL_RMII);
1370c931b060SAnand Moon }
1371c931b060SAnand Moon 
1372c931b060SAnand Moon static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
1373c931b060SAnand Moon {
1374c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1375c931b060SAnand Moon 	unsigned long rate;
1376c931b060SAnand Moon 	int ret;
1377c931b060SAnand Moon 
1378c931b060SAnand Moon 	switch (speed) {
1379c931b060SAnand Moon 	case 10:
1380c931b060SAnand Moon 		rate = 2500000;
1381c931b060SAnand Moon 		break;
1382c931b060SAnand Moon 	case 100:
1383c931b060SAnand Moon 		rate = 25000000;
1384c931b060SAnand Moon 		break;
1385c931b060SAnand Moon 	case 1000:
1386c931b060SAnand Moon 		rate = 125000000;
1387c931b060SAnand Moon 		break;
1388c931b060SAnand Moon 	default:
1389c931b060SAnand Moon 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1390c931b060SAnand Moon 		return;
1391c931b060SAnand Moon 	}
1392c931b060SAnand Moon 
1393c931b060SAnand Moon 	ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
1394c931b060SAnand Moon 	if (ret)
1395c931b060SAnand Moon 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1396c931b060SAnand Moon 			__func__, rate, ret);
1397c931b060SAnand Moon }
1398c931b060SAnand Moon 
1399c931b060SAnand Moon static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
1400c931b060SAnand Moon {
1401c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1402c931b060SAnand Moon 	unsigned long rate;
1403c931b060SAnand Moon 	int ret;
1404c931b060SAnand Moon 
1405c931b060SAnand Moon 	switch (speed) {
1406c931b060SAnand Moon 	case 10:
1407c931b060SAnand Moon 		rate = 2500000;
1408c931b060SAnand Moon 		break;
1409c931b060SAnand Moon 	case 100:
1410c931b060SAnand Moon 		rate = 25000000;
1411c931b060SAnand Moon 		break;
1412c931b060SAnand Moon 	default:
1413c931b060SAnand Moon 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1414c931b060SAnand Moon 		return;
1415c931b060SAnand Moon 	}
1416c931b060SAnand Moon 
1417c931b060SAnand Moon 	ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
1418c931b060SAnand Moon 	if (ret)
1419c931b060SAnand Moon 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1420c931b060SAnand Moon 			__func__, rate, ret);
1421c931b060SAnand Moon }
1422c931b060SAnand Moon 
1423c931b060SAnand Moon static const struct rk_gmac_ops rv1126_ops = {
1424c931b060SAnand Moon 	.set_to_rgmii = rv1126_set_to_rgmii,
1425c931b060SAnand Moon 	.set_to_rmii = rv1126_set_to_rmii,
1426c931b060SAnand Moon 	.set_rgmii_speed = rv1126_set_rgmii_speed,
1427c931b060SAnand Moon 	.set_rmii_speed = rv1126_set_rmii_speed,
1428c931b060SAnand Moon };
1429c931b060SAnand Moon 
1430fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0		0xb00
1431fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1		0xb04
1432fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2		0xb08
1433fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3		0xb0c
1434fecd4d7eSDavid Wu 
1435fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE		GRF_BIT(0)
1436fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
1437fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
1438fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
1439fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID		HIWORD_UPDATE(0x1234, 0xffff, 0)
1440fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID		HIWORD_UPDATE(0x35, 0x3f, 0)
1441fecd4d7eSDavid Wu 
1442fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
14437ad269eaSRoger Chen {
1444fecd4d7eSDavid Wu 	if (priv->ops->integrated_phy_powerup)
1445fecd4d7eSDavid Wu 		priv->ops->integrated_phy_powerup(priv);
1446fecd4d7eSDavid Wu 
1447fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
1448fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
1449fecd4d7eSDavid Wu 
1450fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
1451fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
1452fecd4d7eSDavid Wu 
1453fecd4d7eSDavid Wu 	if (priv->phy_reset) {
1454fecd4d7eSDavid Wu 		/* PHY needs to be disabled before trying to reset it */
1455fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1456fecd4d7eSDavid Wu 		if (priv->phy_reset)
1457fecd4d7eSDavid Wu 			reset_control_assert(priv->phy_reset);
1458fecd4d7eSDavid Wu 		usleep_range(10, 20);
1459fecd4d7eSDavid Wu 		if (priv->phy_reset)
1460fecd4d7eSDavid Wu 			reset_control_deassert(priv->phy_reset);
1461fecd4d7eSDavid Wu 		usleep_range(10, 20);
1462fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
1463fecd4d7eSDavid Wu 		msleep(30);
1464fecd4d7eSDavid Wu 	}
1465fecd4d7eSDavid Wu }
1466fecd4d7eSDavid Wu 
1467fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
1468fecd4d7eSDavid Wu {
1469fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1470fecd4d7eSDavid Wu 	if (priv->phy_reset)
1471fecd4d7eSDavid Wu 		reset_control_assert(priv->phy_reset);
1472fecd4d7eSDavid Wu }
1473fecd4d7eSDavid Wu 
1474fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
1475fecd4d7eSDavid Wu {
1476fecd4d7eSDavid Wu 	struct rk_priv_data *bsp_priv = plat->bsp_priv;
14777ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
1478fecd4d7eSDavid Wu 	int ret;
14797ad269eaSRoger Chen 
14807ad269eaSRoger Chen 	bsp_priv->clk_enabled = false;
14817ad269eaSRoger Chen 
14827ad269eaSRoger Chen 	bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
14837ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_rx))
1484d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1485d42202dcSRomain Perier 			"mac_clk_rx");
14867ad269eaSRoger Chen 
14877ad269eaSRoger Chen 	bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
14887ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_tx))
1489d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1490d42202dcSRomain Perier 			"mac_clk_tx");
14917ad269eaSRoger Chen 
14927ad269eaSRoger Chen 	bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
14937ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->aclk_mac))
1494d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1495d42202dcSRomain Perier 			"aclk_mac");
14967ad269eaSRoger Chen 
14977ad269eaSRoger Chen 	bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
14987ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->pclk_mac))
1499d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1500d42202dcSRomain Perier 			"pclk_mac");
15017ad269eaSRoger Chen 
15027ad269eaSRoger Chen 	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
15037ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->clk_mac))
1504d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1505d42202dcSRomain Perier 			"stmmaceth");
15067ad269eaSRoger Chen 
15077ad269eaSRoger Chen 	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
15087ad269eaSRoger Chen 		bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
15097ad269eaSRoger Chen 		if (IS_ERR(bsp_priv->clk_mac_ref))
1510d42202dcSRomain Perier 			dev_err(dev, "cannot get clock %s\n",
1511d42202dcSRomain Perier 				"clk_mac_ref");
15127ad269eaSRoger Chen 
15137ad269eaSRoger Chen 		if (!bsp_priv->clock_input) {
15147ad269eaSRoger Chen 			bsp_priv->clk_mac_refout =
15157ad269eaSRoger Chen 				devm_clk_get(dev, "clk_mac_refout");
15167ad269eaSRoger Chen 			if (IS_ERR(bsp_priv->clk_mac_refout))
1517d42202dcSRomain Perier 				dev_err(dev, "cannot get clock %s\n",
1518d42202dcSRomain Perier 					"clk_mac_refout");
15197ad269eaSRoger Chen 		}
15207ad269eaSRoger Chen 	}
15217ad269eaSRoger Chen 
152223c94d63SDavid Wu 	bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
152323c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed))
152423c94d63SDavid Wu 		dev_err(dev, "cannot get clock %s\n", "clk_mac_speed");
152523c94d63SDavid Wu 
15267ad269eaSRoger Chen 	if (bsp_priv->clock_input) {
1527d42202dcSRomain Perier 		dev_info(dev, "clock input from PHY\n");
15287ad269eaSRoger Chen 	} else {
15297ad269eaSRoger Chen 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1530c48fa33cSHeiko Stübner 			clk_set_rate(bsp_priv->clk_mac, 50000000);
15317ad269eaSRoger Chen 	}
15327ad269eaSRoger Chen 
1533fecd4d7eSDavid Wu 	if (plat->phy_node && bsp_priv->integrated_phy) {
1534fecd4d7eSDavid Wu 		bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
1535fecd4d7eSDavid Wu 		if (IS_ERR(bsp_priv->clk_phy)) {
1536fecd4d7eSDavid Wu 			ret = PTR_ERR(bsp_priv->clk_phy);
1537fecd4d7eSDavid Wu 			dev_err(dev, "Cannot get PHY clock: %d\n", ret);
1538fecd4d7eSDavid Wu 			return -EINVAL;
1539fecd4d7eSDavid Wu 		}
1540fecd4d7eSDavid Wu 		clk_set_rate(bsp_priv->clk_phy, 50000000);
1541fecd4d7eSDavid Wu 	}
1542fecd4d7eSDavid Wu 
15437ad269eaSRoger Chen 	return 0;
15447ad269eaSRoger Chen }
15457ad269eaSRoger Chen 
15467ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
15477ad269eaSRoger Chen {
1548428ad1bcSLABBE Corentin 	int phy_iface = bsp_priv->phy_iface;
15497ad269eaSRoger Chen 
15507ad269eaSRoger Chen 	if (enable) {
15517ad269eaSRoger Chen 		if (!bsp_priv->clk_enabled) {
15527ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
15537ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->mac_clk_rx))
15547ad269eaSRoger Chen 					clk_prepare_enable(
15557ad269eaSRoger Chen 						bsp_priv->mac_clk_rx);
15567ad269eaSRoger Chen 
15577ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_ref))
15587ad269eaSRoger Chen 					clk_prepare_enable(
15597ad269eaSRoger Chen 						bsp_priv->clk_mac_ref);
15607ad269eaSRoger Chen 
15617ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_refout))
15627ad269eaSRoger Chen 					clk_prepare_enable(
15637ad269eaSRoger Chen 						bsp_priv->clk_mac_refout);
15647ad269eaSRoger Chen 			}
15657ad269eaSRoger Chen 
1566fecd4d7eSDavid Wu 			if (!IS_ERR(bsp_priv->clk_phy))
1567fecd4d7eSDavid Wu 				clk_prepare_enable(bsp_priv->clk_phy);
1568fecd4d7eSDavid Wu 
15697ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->aclk_mac))
15707ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->aclk_mac);
15717ad269eaSRoger Chen 
15727ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->pclk_mac))
15737ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->pclk_mac);
15747ad269eaSRoger Chen 
15757ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->mac_clk_tx))
15767ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->mac_clk_tx);
15777ad269eaSRoger Chen 
157823c94d63SDavid Wu 			if (!IS_ERR(bsp_priv->clk_mac_speed))
157923c94d63SDavid Wu 				clk_prepare_enable(bsp_priv->clk_mac_speed);
158023c94d63SDavid Wu 
15812f2b60a0SDavid Wu 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
15822f2b60a0SDavid Wu 				bsp_priv->ops->set_clock_selection(bsp_priv,
15832f2b60a0SDavid Wu 					       bsp_priv->clock_input, true);
15842f2b60a0SDavid Wu 
15857ad269eaSRoger Chen 			/**
15867ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
15877ad269eaSRoger Chen 			 *	clk_prepare_enable(bsp_priv->clk_mac);
15887ad269eaSRoger Chen 			 */
15897ad269eaSRoger Chen 			mdelay(5);
15907ad269eaSRoger Chen 			bsp_priv->clk_enabled = true;
15917ad269eaSRoger Chen 		}
15927ad269eaSRoger Chen 	} else {
15937ad269eaSRoger Chen 		if (bsp_priv->clk_enabled) {
15947ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
159593120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->mac_clk_rx);
15967ad269eaSRoger Chen 
159793120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_ref);
15987ad269eaSRoger Chen 
159993120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_refout);
16007ad269eaSRoger Chen 			}
16017ad269eaSRoger Chen 
1602fecd4d7eSDavid Wu 			clk_disable_unprepare(bsp_priv->clk_phy);
1603fecd4d7eSDavid Wu 
16047ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->aclk_mac);
16057ad269eaSRoger Chen 
16067ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->pclk_mac);
16077ad269eaSRoger Chen 
16087ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->mac_clk_tx);
160923c94d63SDavid Wu 
161023c94d63SDavid Wu 			clk_disable_unprepare(bsp_priv->clk_mac_speed);
16112f2b60a0SDavid Wu 
16122f2b60a0SDavid Wu 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
16132f2b60a0SDavid Wu 				bsp_priv->ops->set_clock_selection(bsp_priv,
16142f2b60a0SDavid Wu 					      bsp_priv->clock_input, false);
16157ad269eaSRoger Chen 			/**
16167ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
16177ad269eaSRoger Chen 			 *	clk_disable_unprepare(bsp_priv->clk_mac);
16187ad269eaSRoger Chen 			 */
16197ad269eaSRoger Chen 			bsp_priv->clk_enabled = false;
16207ad269eaSRoger Chen 		}
16217ad269eaSRoger Chen 	}
16227ad269eaSRoger Chen 
16237ad269eaSRoger Chen 	return 0;
16247ad269eaSRoger Chen }
16257ad269eaSRoger Chen 
16267ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
16277ad269eaSRoger Chen {
16282e12f536SRomain Perier 	struct regulator *ldo = bsp_priv->regulator;
16297ad269eaSRoger Chen 	int ret;
16307ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
16317ad269eaSRoger Chen 
16323b25528eSChen-Yu Tsai 	if (!ldo)
16333b25528eSChen-Yu Tsai 		return 0;
16347ad269eaSRoger Chen 
16357ad269eaSRoger Chen 	if (enable) {
16367ad269eaSRoger Chen 		ret = regulator_enable(ldo);
16372e12f536SRomain Perier 		if (ret)
1638d42202dcSRomain Perier 			dev_err(dev, "fail to enable phy-supply\n");
16397ad269eaSRoger Chen 	} else {
16407ad269eaSRoger Chen 		ret = regulator_disable(ldo);
16412e12f536SRomain Perier 		if (ret)
1642d42202dcSRomain Perier 			dev_err(dev, "fail to disable phy-supply\n");
16437ad269eaSRoger Chen 	}
16447ad269eaSRoger Chen 
16457ad269eaSRoger Chen 	return 0;
16467ad269eaSRoger Chen }
16477ad269eaSRoger Chen 
16480fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1649fecd4d7eSDavid Wu 					  struct plat_stmmacenet_data *plat,
165092c2588fSJoachim Eastwood 					  const struct rk_gmac_ops *ops)
16517ad269eaSRoger Chen {
16527ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv;
16537ad269eaSRoger Chen 	struct device *dev = &pdev->dev;
16543bb3d6b1SDavid Wu 	struct resource *res;
16557ad269eaSRoger Chen 	int ret;
16567ad269eaSRoger Chen 	const char *strings = NULL;
16577ad269eaSRoger Chen 	int value;
16587ad269eaSRoger Chen 
16597ad269eaSRoger Chen 	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
16607ad269eaSRoger Chen 	if (!bsp_priv)
16617ad269eaSRoger Chen 		return ERR_PTR(-ENOMEM);
16627ad269eaSRoger Chen 
16630c65b2b9SAndrew Lunn 	of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
16640fb98db1SHeiko Stübner 	bsp_priv->ops = ops;
16657ad269eaSRoger Chen 
16663bb3d6b1SDavid Wu 	/* Some SoCs have multiple MAC controllers, which need
16673bb3d6b1SDavid Wu 	 * to be distinguished.
16683bb3d6b1SDavid Wu 	 */
16693bb3d6b1SDavid Wu 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
16700546b224SJohn Keeping 	if (res && ops->regs_valid) {
16713bb3d6b1SDavid Wu 		int i = 0;
16723bb3d6b1SDavid Wu 
16733bb3d6b1SDavid Wu 		while (ops->regs[i]) {
16743bb3d6b1SDavid Wu 			if (ops->regs[i] == res->start) {
16753bb3d6b1SDavid Wu 				bsp_priv->id = i;
16763bb3d6b1SDavid Wu 				break;
16773bb3d6b1SDavid Wu 			}
16783bb3d6b1SDavid Wu 			i++;
16793bb3d6b1SDavid Wu 		}
16803bb3d6b1SDavid Wu 	}
16813bb3d6b1SDavid Wu 
16822e12f536SRomain Perier 	bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
16832e12f536SRomain Perier 	if (IS_ERR(bsp_priv->regulator)) {
16842e12f536SRomain Perier 		if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) {
16852e12f536SRomain Perier 			dev_err(dev, "phy regulator is not available yet, deferred probing\n");
16862e12f536SRomain Perier 			return ERR_PTR(-EPROBE_DEFER);
16872e12f536SRomain Perier 		}
16882e12f536SRomain Perier 		dev_err(dev, "no regulator found\n");
16892e12f536SRomain Perier 		bsp_priv->regulator = NULL;
16907ad269eaSRoger Chen 	}
16917ad269eaSRoger Chen 
16927ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
16937ad269eaSRoger Chen 	if (ret) {
1694d42202dcSRomain Perier 		dev_err(dev, "Can not read property: clock_in_out.\n");
16957ad269eaSRoger Chen 		bsp_priv->clock_input = true;
16967ad269eaSRoger Chen 	} else {
1697d42202dcSRomain Perier 		dev_info(dev, "clock input or output? (%s).\n",
1698d42202dcSRomain Perier 			 strings);
16997ad269eaSRoger Chen 		if (!strcmp(strings, "input"))
17007ad269eaSRoger Chen 			bsp_priv->clock_input = true;
17017ad269eaSRoger Chen 		else
17027ad269eaSRoger Chen 			bsp_priv->clock_input = false;
17037ad269eaSRoger Chen 	}
17047ad269eaSRoger Chen 
17057ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
17067ad269eaSRoger Chen 	if (ret) {
17077ad269eaSRoger Chen 		bsp_priv->tx_delay = 0x30;
1708d42202dcSRomain Perier 		dev_err(dev, "Can not read property: tx_delay.");
1709d42202dcSRomain Perier 		dev_err(dev, "set tx_delay to 0x%x\n",
1710d42202dcSRomain Perier 			bsp_priv->tx_delay);
17117ad269eaSRoger Chen 	} else {
1712d42202dcSRomain Perier 		dev_info(dev, "TX delay(0x%x).\n", value);
17137ad269eaSRoger Chen 		bsp_priv->tx_delay = value;
17147ad269eaSRoger Chen 	}
17157ad269eaSRoger Chen 
17167ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
17177ad269eaSRoger Chen 	if (ret) {
17187ad269eaSRoger Chen 		bsp_priv->rx_delay = 0x10;
1719d42202dcSRomain Perier 		dev_err(dev, "Can not read property: rx_delay.");
1720d42202dcSRomain Perier 		dev_err(dev, "set rx_delay to 0x%x\n",
1721d42202dcSRomain Perier 			bsp_priv->rx_delay);
17227ad269eaSRoger Chen 	} else {
1723d42202dcSRomain Perier 		dev_info(dev, "RX delay(0x%x).\n", value);
17247ad269eaSRoger Chen 		bsp_priv->rx_delay = value;
17257ad269eaSRoger Chen 	}
17267ad269eaSRoger Chen 
17277ad269eaSRoger Chen 	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
17287ad269eaSRoger Chen 							"rockchip,grf");
17292f2b60a0SDavid Wu 	bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
17302f2b60a0SDavid Wu 							    "rockchip,php-grf");
17317ad269eaSRoger Chen 
1732fecd4d7eSDavid Wu 	if (plat->phy_node) {
1733fecd4d7eSDavid Wu 		bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
1734fecd4d7eSDavid Wu 								 "phy-is-integrated");
1735fecd4d7eSDavid Wu 		if (bsp_priv->integrated_phy) {
1736fecd4d7eSDavid Wu 			bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
1737fecd4d7eSDavid Wu 			if (IS_ERR(bsp_priv->phy_reset)) {
1738fecd4d7eSDavid Wu 				dev_err(&pdev->dev, "No PHY reset control found.\n");
1739fecd4d7eSDavid Wu 				bsp_priv->phy_reset = NULL;
1740fecd4d7eSDavid Wu 			}
1741fecd4d7eSDavid Wu 		}
1742fecd4d7eSDavid Wu 	}
1743fecd4d7eSDavid Wu 	dev_info(dev, "integrated PHY? (%s).\n",
1744fecd4d7eSDavid Wu 		 bsp_priv->integrated_phy ? "yes" : "no");
1745fecd4d7eSDavid Wu 
1746fecd4d7eSDavid Wu 	bsp_priv->pdev = pdev;
174745383f52SRoger Chen 
174845383f52SRoger Chen 	return bsp_priv;
174945383f52SRoger Chen }
175045383f52SRoger Chen 
175137c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv)
175237c80d15SDavid Wu {
175337c80d15SDavid Wu 	switch (bsp_priv->phy_iface) {
175437c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII:
175537c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_ID:
175637c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_RXID:
175737c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_TXID:
175837c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rgmii)
175937c80d15SDavid Wu 			return -EINVAL;
176037c80d15SDavid Wu 		break;
176137c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RMII:
176237c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rmii)
176337c80d15SDavid Wu 			return -EINVAL;
176437c80d15SDavid Wu 		break;
176537c80d15SDavid Wu 	default:
176637c80d15SDavid Wu 		dev_err(&bsp_priv->pdev->dev,
176737c80d15SDavid Wu 			"unsupported interface %d", bsp_priv->phy_iface);
176837c80d15SDavid Wu 	}
176937c80d15SDavid Wu 	return 0;
177037c80d15SDavid Wu }
177137c80d15SDavid Wu 
177245383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
177345383f52SRoger Chen {
177445383f52SRoger Chen 	int ret;
177545383f52SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
177645383f52SRoger Chen 
177737c80d15SDavid Wu 	ret = rk_gmac_check_ops(bsp_priv);
177837c80d15SDavid Wu 	if (ret)
177937c80d15SDavid Wu 		return ret;
178037c80d15SDavid Wu 
1781f217bfdeSHeiko Stübner 	ret = gmac_clk_enable(bsp_priv, true);
1782f217bfdeSHeiko Stübner 	if (ret)
1783f217bfdeSHeiko Stübner 		return ret;
1784f217bfdeSHeiko Stübner 
17857ad269eaSRoger Chen 	/*rmii or rgmii*/
1786eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1787eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1788d42202dcSRomain Perier 		dev_info(dev, "init for RGMII\n");
17890fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
17900fb98db1SHeiko Stübner 					    bsp_priv->rx_delay);
1791eaf70ad1SWadim Egorov 		break;
1792eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1793eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_ID\n");
1794eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
1795eaf70ad1SWadim Egorov 		break;
1796eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1797eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_RXID\n");
1798eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
1799eaf70ad1SWadim Egorov 		break;
1800eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
1801eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_TXID\n");
1802eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
1803eaf70ad1SWadim Egorov 		break;
1804eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
1805d42202dcSRomain Perier 		dev_info(dev, "init for RMII\n");
18060fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rmii(bsp_priv);
1807eaf70ad1SWadim Egorov 		break;
1808eaf70ad1SWadim Egorov 	default:
1809d42202dcSRomain Perier 		dev_err(dev, "NO interface defined!\n");
18107ad269eaSRoger Chen 	}
18117ad269eaSRoger Chen 
18127ad269eaSRoger Chen 	ret = phy_power_on(bsp_priv, true);
1813c69c29a1SAlexey Khoroshilov 	if (ret) {
1814c69c29a1SAlexey Khoroshilov 		gmac_clk_enable(bsp_priv, false);
18157ad269eaSRoger Chen 		return ret;
1816c69c29a1SAlexey Khoroshilov 	}
18177ad269eaSRoger Chen 
1818aec3f415SPunit Agrawal 	pm_runtime_get_sync(dev);
1819aec3f415SPunit Agrawal 
1820fecd4d7eSDavid Wu 	if (bsp_priv->integrated_phy)
1821fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerup(bsp_priv);
1822fecd4d7eSDavid Wu 
18237ad269eaSRoger Chen 	return 0;
18247ad269eaSRoger Chen }
18257ad269eaSRoger Chen 
1826229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac)
18277ad269eaSRoger Chen {
1828fecd4d7eSDavid Wu 	if (gmac->integrated_phy)
1829fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerdown(gmac);
1830fecd4d7eSDavid Wu 
1831aec3f415SPunit Agrawal 	pm_runtime_put_sync(&gmac->pdev->dev);
1832aec3f415SPunit Agrawal 
18337ad269eaSRoger Chen 	phy_power_on(gmac, false);
18347ad269eaSRoger Chen 	gmac_clk_enable(gmac, false);
18357ad269eaSRoger Chen }
18367ad269eaSRoger Chen 
18377ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed)
18387ad269eaSRoger Chen {
18397ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
18407ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
18417ad269eaSRoger Chen 
1842eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1843eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1844eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1845eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1846eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
184737c80d15SDavid Wu 		if (bsp_priv->ops->set_rgmii_speed)
18480fb98db1SHeiko Stübner 			bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1849eaf70ad1SWadim Egorov 		break;
1850eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
185137c80d15SDavid Wu 		if (bsp_priv->ops->set_rmii_speed)
18520fb98db1SHeiko Stübner 			bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1853eaf70ad1SWadim Egorov 		break;
1854eaf70ad1SWadim Egorov 	default:
18557ad269eaSRoger Chen 		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
18567ad269eaSRoger Chen 	}
1857eaf70ad1SWadim Egorov }
18587ad269eaSRoger Chen 
185927ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev)
186027ffefd2SJoachim Eastwood {
186127ffefd2SJoachim Eastwood 	struct plat_stmmacenet_data *plat_dat;
186227ffefd2SJoachim Eastwood 	struct stmmac_resources stmmac_res;
1863f529f182SJoachim Eastwood 	const struct rk_gmac_ops *data;
186427ffefd2SJoachim Eastwood 	int ret;
186527ffefd2SJoachim Eastwood 
1866149adeddSJoachim Eastwood 	data = of_device_get_match_data(&pdev->dev);
1867149adeddSJoachim Eastwood 	if (!data) {
1868149adeddSJoachim Eastwood 		dev_err(&pdev->dev, "no of match data provided\n");
1869149adeddSJoachim Eastwood 		return -EINVAL;
1870149adeddSJoachim Eastwood 	}
1871149adeddSJoachim Eastwood 
187227ffefd2SJoachim Eastwood 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
187327ffefd2SJoachim Eastwood 	if (ret)
187427ffefd2SJoachim Eastwood 		return ret;
187527ffefd2SJoachim Eastwood 
187683216e39SMichael Walle 	plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
187727ffefd2SJoachim Eastwood 	if (IS_ERR(plat_dat))
187827ffefd2SJoachim Eastwood 		return PTR_ERR(plat_dat);
187927ffefd2SJoachim Eastwood 
1880d6b06251SEzequiel Garcia 	/* If the stmmac is not already selected as gmac4,
1881d6b06251SEzequiel Garcia 	 * then make sure we fallback to gmac.
1882d6b06251SEzequiel Garcia 	 */
1883d6b06251SEzequiel Garcia 	if (!plat_dat->has_gmac4)
188427ffefd2SJoachim Eastwood 		plat_dat->has_gmac = true;
188527ffefd2SJoachim Eastwood 	plat_dat->fix_mac_speed = rk_fix_speed;
188627ffefd2SJoachim Eastwood 
1887fecd4d7eSDavid Wu 	plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
1888d2ed0a77SJohan Hovold 	if (IS_ERR(plat_dat->bsp_priv)) {
1889d2ed0a77SJohan Hovold 		ret = PTR_ERR(plat_dat->bsp_priv);
1890d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
1891d2ed0a77SJohan Hovold 	}
189227ffefd2SJoachim Eastwood 
1893fecd4d7eSDavid Wu 	ret = rk_gmac_clk_init(plat_dat);
1894fecd4d7eSDavid Wu 	if (ret)
18959de9aa48SEmil Renner Berthing 		goto err_remove_config_dt;
1896fecd4d7eSDavid Wu 
189707a5e769SJoachim Eastwood 	ret = rk_gmac_powerup(plat_dat->bsp_priv);
189827ffefd2SJoachim Eastwood 	if (ret)
1899d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
190027ffefd2SJoachim Eastwood 
19012d222656SJohan Hovold 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
19022d222656SJohan Hovold 	if (ret)
19032745529aSDavid S. Miller 		goto err_gmac_powerdown;
19042d222656SJohan Hovold 
19052d222656SJohan Hovold 	return 0;
19062d222656SJohan Hovold 
19072745529aSDavid S. Miller err_gmac_powerdown:
19082745529aSDavid S. Miller 	rk_gmac_powerdown(plat_dat->bsp_priv);
1909d2ed0a77SJohan Hovold err_remove_config_dt:
1910d2ed0a77SJohan Hovold 	stmmac_remove_config_dt(pdev, plat_dat);
19112d222656SJohan Hovold 
19122d222656SJohan Hovold 	return ret;
191327ffefd2SJoachim Eastwood }
191427ffefd2SJoachim Eastwood 
19150de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev)
19160de8c4c9SJoachim Eastwood {
19170de8c4c9SJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
1918*ff0011cfSUwe Kleine-König 
1919*ff0011cfSUwe Kleine-König 	stmmac_dvr_remove(&pdev->dev);
19200de8c4c9SJoachim Eastwood 
19210de8c4c9SJoachim Eastwood 	rk_gmac_powerdown(bsp_priv);
19220de8c4c9SJoachim Eastwood 
1923*ff0011cfSUwe Kleine-König 	return 0;
19240de8c4c9SJoachim Eastwood }
19250de8c4c9SJoachim Eastwood 
19265619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP
19275619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev)
19285619468aSJoachim Eastwood {
19295619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
19305619468aSJoachim Eastwood 	int ret = stmmac_suspend(dev);
19315619468aSJoachim Eastwood 
19325619468aSJoachim Eastwood 	/* Keep the PHY up if we use Wake-on-Lan. */
19335619468aSJoachim Eastwood 	if (!device_may_wakeup(dev)) {
19345619468aSJoachim Eastwood 		rk_gmac_powerdown(bsp_priv);
19355619468aSJoachim Eastwood 		bsp_priv->suspended = true;
19365619468aSJoachim Eastwood 	}
19375619468aSJoachim Eastwood 
19385619468aSJoachim Eastwood 	return ret;
19395619468aSJoachim Eastwood }
19405619468aSJoachim Eastwood 
19415619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev)
19425619468aSJoachim Eastwood {
19435619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
19445619468aSJoachim Eastwood 
19455619468aSJoachim Eastwood 	/* The PHY was up for Wake-on-Lan. */
19465619468aSJoachim Eastwood 	if (bsp_priv->suspended) {
19475619468aSJoachim Eastwood 		rk_gmac_powerup(bsp_priv);
19485619468aSJoachim Eastwood 		bsp_priv->suspended = false;
19495619468aSJoachim Eastwood 	}
19505619468aSJoachim Eastwood 
19515619468aSJoachim Eastwood 	return stmmac_resume(dev);
19525619468aSJoachim Eastwood }
19535619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */
19545619468aSJoachim Eastwood 
19555619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
19565619468aSJoachim Eastwood 
1957e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = {
195823c94d63SDavid Wu 	{ .compatible = "rockchip,px30-gmac",	.data = &px30_ops   },
195905946876SDavid Wu 	{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
1960e7ffd812SXing Zheng 	{ .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
1961f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
1962b4ac9456STobias Schramm 	{ .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops },
1963d4ff816eSdavid.wu 	{ .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
1964ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
1965f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
1966ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
19673bb3d6b1SDavid Wu 	{ .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
19682f2b60a0SDavid Wu 	{ .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops },
196989c9c163SDavid Wu 	{ .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
1970c931b060SAnand Moon 	{ .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops },
1971e0fb4013SJoachim Eastwood 	{ }
1972e0fb4013SJoachim Eastwood };
1973e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
1974e0fb4013SJoachim Eastwood 
1975e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = {
197627ffefd2SJoachim Eastwood 	.probe  = rk_gmac_probe,
19770de8c4c9SJoachim Eastwood 	.remove = rk_gmac_remove,
1978e0fb4013SJoachim Eastwood 	.driver = {
1979e0fb4013SJoachim Eastwood 		.name           = "rk_gmac-dwmac",
19805619468aSJoachim Eastwood 		.pm		= &rk_gmac_pm_ops,
1981e0fb4013SJoachim Eastwood 		.of_match_table = rk_gmac_dwmac_match,
1982e0fb4013SJoachim Eastwood 	},
1983e0fb4013SJoachim Eastwood };
1984e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver);
1985e0fb4013SJoachim Eastwood 
1986e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
1987e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
1988e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL");
1989