xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c (revision 0546b224cc7717cc8a2db076b0bb069a9c430794)
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);
35fecd4d7eSDavid Wu 	void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
36*0546b224SJohn Keeping 	bool regs_valid;
373bb3d6b1SDavid Wu 	u32 regs[];
380fb98db1SHeiko Stübner };
390fb98db1SHeiko Stübner 
407ad269eaSRoger Chen struct rk_priv_data {
417ad269eaSRoger Chen 	struct platform_device *pdev;
420c65b2b9SAndrew Lunn 	phy_interface_t phy_iface;
433bb3d6b1SDavid Wu 	int id;
442e12f536SRomain Perier 	struct regulator *regulator;
45229666c1SVincent Palatin 	bool suspended;
4692c2588fSJoachim Eastwood 	const struct rk_gmac_ops *ops;
477ad269eaSRoger Chen 
487ad269eaSRoger Chen 	bool clk_enabled;
497ad269eaSRoger Chen 	bool clock_input;
50fecd4d7eSDavid Wu 	bool integrated_phy;
517ad269eaSRoger Chen 
527ad269eaSRoger Chen 	struct clk *clk_mac;
537ad269eaSRoger Chen 	struct clk *gmac_clkin;
547ad269eaSRoger Chen 	struct clk *mac_clk_rx;
557ad269eaSRoger Chen 	struct clk *mac_clk_tx;
567ad269eaSRoger Chen 	struct clk *clk_mac_ref;
577ad269eaSRoger Chen 	struct clk *clk_mac_refout;
5823c94d63SDavid Wu 	struct clk *clk_mac_speed;
597ad269eaSRoger Chen 	struct clk *aclk_mac;
607ad269eaSRoger Chen 	struct clk *pclk_mac;
61fecd4d7eSDavid Wu 	struct clk *clk_phy;
62fecd4d7eSDavid Wu 
63fecd4d7eSDavid Wu 	struct reset_control *phy_reset;
647ad269eaSRoger Chen 
657ad269eaSRoger Chen 	int tx_delay;
667ad269eaSRoger Chen 	int rx_delay;
677ad269eaSRoger Chen 
687ad269eaSRoger Chen 	struct regmap *grf;
697ad269eaSRoger Chen };
707ad269eaSRoger Chen 
717ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \
727ad269eaSRoger Chen 		((val) << (shift) | (mask) << ((shift) + 16))
737ad269eaSRoger Chen 
747ad269eaSRoger Chen #define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
757ad269eaSRoger Chen #define GRF_CLR_BIT(nr)	(BIT(nr+16))
767ad269eaSRoger Chen 
77eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \
78eaf70ad1SWadim Egorov 	(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
79eaf70ad1SWadim Egorov 	 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
80eaf70ad1SWadim Egorov 
8123c94d63SDavid Wu #define PX30_GRF_GMAC_CON1		0x0904
8223c94d63SDavid Wu 
8323c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */
8423c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
8523c94d63SDavid Wu 					 GRF_BIT(6))
8623c94d63SDavid Wu #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
8723c94d63SDavid Wu #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
8823c94d63SDavid Wu 
8923c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
9023c94d63SDavid Wu {
9123c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
9223c94d63SDavid Wu 
9323c94d63SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
9423c94d63SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
9523c94d63SDavid Wu 		return;
9623c94d63SDavid Wu 	}
9723c94d63SDavid Wu 
9823c94d63SDavid Wu 	regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
9923c94d63SDavid Wu 		     PX30_GMAC_PHY_INTF_SEL_RMII);
10023c94d63SDavid Wu }
10123c94d63SDavid Wu 
10223c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
10323c94d63SDavid Wu {
10423c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10523c94d63SDavid Wu 	int ret;
10623c94d63SDavid Wu 
10723c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed)) {
10823c94d63SDavid Wu 		dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
10923c94d63SDavid Wu 		return;
11023c94d63SDavid Wu 	}
11123c94d63SDavid Wu 
11223c94d63SDavid Wu 	if (speed == 10) {
11323c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
11423c94d63SDavid Wu 			     PX30_GMAC_SPEED_10M);
11523c94d63SDavid Wu 
11623c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
11723c94d63SDavid Wu 		if (ret)
11823c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n",
11923c94d63SDavid Wu 				__func__, ret);
12023c94d63SDavid Wu 	} else if (speed == 100) {
12123c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
12223c94d63SDavid Wu 			     PX30_GMAC_SPEED_100M);
12323c94d63SDavid Wu 
12423c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
12523c94d63SDavid Wu 		if (ret)
12623c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n",
12723c94d63SDavid Wu 				__func__, ret);
12823c94d63SDavid Wu 
12923c94d63SDavid Wu 	} else {
13023c94d63SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
13123c94d63SDavid Wu 	}
13223c94d63SDavid Wu }
13323c94d63SDavid Wu 
13423c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = {
13523c94d63SDavid Wu 	.set_to_rmii = px30_set_to_rmii,
13623c94d63SDavid Wu 	.set_rmii_speed = px30_set_rmii_speed,
13723c94d63SDavid Wu };
13823c94d63SDavid Wu 
13905946876SDavid Wu #define RK3128_GRF_MAC_CON0	0x0168
14005946876SDavid Wu #define RK3128_GRF_MAC_CON1	0x016c
14105946876SDavid Wu 
14205946876SDavid Wu /* RK3128_GRF_MAC_CON0 */
14305946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE   GRF_BIT(14)
14405946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(14)
14505946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(15)
14605946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(15)
14705946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
14805946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
14905946876SDavid Wu 
15005946876SDavid Wu /* RK3128_GRF_MAC_CON1 */
15105946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII	\
15205946876SDavid Wu 		(GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
15305946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII	\
15405946876SDavid Wu 		(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
15505946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
15605946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
15705946876SDavid Wu #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
15805946876SDavid Wu #define RK3128_GMAC_SPEED_100M         GRF_BIT(10)
15905946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M       GRF_BIT(11)
16005946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M      GRF_CLR_BIT(11)
16105946876SDavid Wu #define RK3128_GMAC_CLK_125M           (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
16205946876SDavid Wu #define RK3128_GMAC_CLK_25M            (GRF_BIT(12) | GRF_BIT(13))
16305946876SDavid Wu #define RK3128_GMAC_CLK_2_5M           (GRF_CLR_BIT(12) | GRF_BIT(13))
16405946876SDavid Wu #define RK3128_GMAC_RMII_MODE          GRF_BIT(14)
16505946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR      GRF_CLR_BIT(14)
16605946876SDavid Wu 
16705946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
16805946876SDavid Wu 				int tx_delay, int rx_delay)
16905946876SDavid Wu {
17005946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
17105946876SDavid Wu 
17205946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
17305946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
17405946876SDavid Wu 		return;
17505946876SDavid Wu 	}
17605946876SDavid Wu 
17705946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
17805946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RGMII |
17905946876SDavid Wu 		     RK3128_GMAC_RMII_MODE_CLR);
18005946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
18105946876SDavid Wu 		     DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
18205946876SDavid Wu 		     RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
18305946876SDavid Wu 		     RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
18405946876SDavid Wu }
18505946876SDavid Wu 
18605946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
18705946876SDavid Wu {
18805946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
18905946876SDavid Wu 
19005946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
19105946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
19205946876SDavid Wu 		return;
19305946876SDavid Wu 	}
19405946876SDavid Wu 
19505946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
19605946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
19705946876SDavid Wu }
19805946876SDavid Wu 
19905946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
20005946876SDavid Wu {
20105946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
20205946876SDavid Wu 
20305946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
20405946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
20505946876SDavid Wu 		return;
20605946876SDavid Wu 	}
20705946876SDavid Wu 
20805946876SDavid Wu 	if (speed == 10)
20905946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21005946876SDavid Wu 			     RK3128_GMAC_CLK_2_5M);
21105946876SDavid Wu 	else if (speed == 100)
21205946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21305946876SDavid Wu 			     RK3128_GMAC_CLK_25M);
21405946876SDavid Wu 	else if (speed == 1000)
21505946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21605946876SDavid Wu 			     RK3128_GMAC_CLK_125M);
21705946876SDavid Wu 	else
21805946876SDavid Wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
21905946876SDavid Wu }
22005946876SDavid Wu 
22105946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
22205946876SDavid Wu {
22305946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
22405946876SDavid Wu 
22505946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
22605946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
22705946876SDavid Wu 		return;
22805946876SDavid Wu 	}
22905946876SDavid Wu 
23005946876SDavid Wu 	if (speed == 10) {
23105946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23205946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_2_5M |
23305946876SDavid Wu 			     RK3128_GMAC_SPEED_10M);
23405946876SDavid Wu 	} else if (speed == 100) {
23505946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23605946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_25M |
23705946876SDavid Wu 			     RK3128_GMAC_SPEED_100M);
23805946876SDavid Wu 	} else {
23905946876SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
24005946876SDavid Wu 	}
24105946876SDavid Wu }
24205946876SDavid Wu 
24305946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = {
24405946876SDavid Wu 	.set_to_rgmii = rk3128_set_to_rgmii,
24505946876SDavid Wu 	.set_to_rmii = rk3128_set_to_rmii,
24605946876SDavid Wu 	.set_rgmii_speed = rk3128_set_rgmii_speed,
24705946876SDavid Wu 	.set_rmii_speed = rk3128_set_rmii_speed,
24805946876SDavid Wu };
24905946876SDavid Wu 
250e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0	0x0900
251e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1	0x0904
252e7ffd812SXing Zheng 
2536fa12c78SDavid Wu #define RK3228_GRF_CON_MUX	0x50
2546fa12c78SDavid Wu 
255e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */
256e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
257e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
258e7ffd812SXing Zheng 
259e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */
260e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII	\
261e7ffd812SXing Zheng 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
262e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII	\
263e7ffd812SXing Zheng 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
264e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
265e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
266e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
267e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M		GRF_BIT(2)
268e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M	GRF_BIT(7)
269e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
270e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M		(GRF_CLR_BIT(8) | GRF_CLR_BIT(9))
271e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M		(GRF_BIT(8) | GRF_BIT(9))
272e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M		(GRF_CLR_BIT(8) | GRF_BIT(9))
273e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE		GRF_BIT(10)
274e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(10)
275e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
276e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
277e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
278e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
279e7ffd812SXing Zheng 
2806fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */
2816fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY	GRF_BIT(15)
2826fa12c78SDavid Wu 
283e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
284e7ffd812SXing Zheng 				int tx_delay, int rx_delay)
285e7ffd812SXing Zheng {
286e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
287e7ffd812SXing Zheng 
288e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
289e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
290e7ffd812SXing Zheng 		return;
291e7ffd812SXing Zheng 	}
292e7ffd812SXing Zheng 
293e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
294e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RGMII |
295e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE_CLR |
296eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3228, tx_delay, rx_delay));
297e7ffd812SXing Zheng 
298e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
299e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
300e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
301e7ffd812SXing Zheng }
302e7ffd812SXing Zheng 
303e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
304e7ffd812SXing Zheng {
305e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
306e7ffd812SXing Zheng 
307e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
308e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
309e7ffd812SXing Zheng 		return;
310e7ffd812SXing Zheng 	}
311e7ffd812SXing Zheng 
312e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
313e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RMII |
314e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE);
315e7ffd812SXing Zheng 
316e7ffd812SXing Zheng 	/* set MAC to RMII mode */
317e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11));
318e7ffd812SXing Zheng }
319e7ffd812SXing Zheng 
320e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
321e7ffd812SXing Zheng {
322e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
323e7ffd812SXing Zheng 
324e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
325e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
326e7ffd812SXing Zheng 		return;
327e7ffd812SXing Zheng 	}
328e7ffd812SXing Zheng 
329e7ffd812SXing Zheng 	if (speed == 10)
330e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
331e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_2_5M);
332e7ffd812SXing Zheng 	else if (speed == 100)
333e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
334e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_25M);
335e7ffd812SXing Zheng 	else if (speed == 1000)
336e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
337e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_125M);
338e7ffd812SXing Zheng 	else
339e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
340e7ffd812SXing Zheng }
341e7ffd812SXing Zheng 
342e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
343e7ffd812SXing Zheng {
344e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
345e7ffd812SXing Zheng 
346e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
347e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
348e7ffd812SXing Zheng 		return;
349e7ffd812SXing Zheng 	}
350e7ffd812SXing Zheng 
351e7ffd812SXing Zheng 	if (speed == 10)
352e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
353e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_2_5M |
354e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_10M);
355e7ffd812SXing Zheng 	else if (speed == 100)
356e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
357e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_25M |
358e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_100M);
359e7ffd812SXing Zheng 	else
360e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
361e7ffd812SXing Zheng }
362e7ffd812SXing Zheng 
3636fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
3646fa12c78SDavid Wu {
3656fa12c78SDavid Wu 	regmap_write(priv->grf, RK3228_GRF_CON_MUX,
3666fa12c78SDavid Wu 		     RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
3676fa12c78SDavid Wu }
3686fa12c78SDavid Wu 
369e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = {
370e7ffd812SXing Zheng 	.set_to_rgmii = rk3228_set_to_rgmii,
371e7ffd812SXing Zheng 	.set_to_rmii = rk3228_set_to_rmii,
372e7ffd812SXing Zheng 	.set_rgmii_speed = rk3228_set_rgmii_speed,
373e7ffd812SXing Zheng 	.set_rmii_speed = rk3228_set_rmii_speed,
3746fa12c78SDavid Wu 	.integrated_phy_powerup =  rk3228_integrated_phy_powerup,
375e7ffd812SXing Zheng };
376e7ffd812SXing Zheng 
3777ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1	0x0248
3787ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3	0x0250
3797ad269eaSRoger Chen 
3807ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/
3810fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | \
3820fb98db1SHeiko Stübner 					 GRF_CLR_BIT(8))
3830fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
3840fb98db1SHeiko Stübner 					 GRF_BIT(8))
3850fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
3860fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
3870fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
3880fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M		GRF_BIT(10)
3890fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M	GRF_BIT(11)
3900fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
3910fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
3920fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
3930fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
3940fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE		GRF_BIT(14)
3950fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
3967ad269eaSRoger Chen 
3977ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/
3980fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
3990fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
4000fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
4010fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
4020fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
4030fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
4047ad269eaSRoger Chen 
4050fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
4067ad269eaSRoger Chen 				int tx_delay, int rx_delay)
4077ad269eaSRoger Chen {
4087ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4097ad269eaSRoger Chen 
4107ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
411d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4127ad269eaSRoger Chen 		return;
4137ad269eaSRoger Chen 	}
4147ad269eaSRoger Chen 
4157ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4160fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
4170fb98db1SHeiko Stübner 		     RK3288_GMAC_RMII_MODE_CLR);
4187ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
419eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
4200fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
4210fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
4227ad269eaSRoger Chen }
4237ad269eaSRoger Chen 
4240fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
4257ad269eaSRoger Chen {
4267ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4277ad269eaSRoger Chen 
4287ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
429d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4307ad269eaSRoger Chen 		return;
4317ad269eaSRoger Chen 	}
4327ad269eaSRoger Chen 
4337ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4340fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
4357ad269eaSRoger Chen }
4367ad269eaSRoger Chen 
4370fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
4387ad269eaSRoger Chen {
4397ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4407ad269eaSRoger Chen 
4417ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
442d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4437ad269eaSRoger Chen 		return;
4447ad269eaSRoger Chen 	}
4457ad269eaSRoger Chen 
4467ad269eaSRoger Chen 	if (speed == 10)
4470fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4480fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_2_5M);
4497ad269eaSRoger Chen 	else if (speed == 100)
4500fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4510fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_25M);
4527ad269eaSRoger Chen 	else if (speed == 1000)
4530fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4540fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_125M);
4557ad269eaSRoger Chen 	else
4567ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
4577ad269eaSRoger Chen }
4587ad269eaSRoger Chen 
4590fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
4607ad269eaSRoger Chen {
4617ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4627ad269eaSRoger Chen 
4637ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
464d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4657ad269eaSRoger Chen 		return;
4667ad269eaSRoger Chen 	}
4677ad269eaSRoger Chen 
4687ad269eaSRoger Chen 	if (speed == 10) {
4697ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4700fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_2_5M |
4710fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_10M);
4727ad269eaSRoger Chen 	} else if (speed == 100) {
4737ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4740fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_25M |
4750fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_100M);
4767ad269eaSRoger Chen 	} else {
4777ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
4787ad269eaSRoger Chen 	}
4797ad269eaSRoger Chen }
4807ad269eaSRoger Chen 
48192c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = {
4820fb98db1SHeiko Stübner 	.set_to_rgmii = rk3288_set_to_rgmii,
4830fb98db1SHeiko Stübner 	.set_to_rmii = rk3288_set_to_rmii,
4840fb98db1SHeiko Stübner 	.set_rgmii_speed = rk3288_set_rgmii_speed,
4850fb98db1SHeiko Stübner 	.set_rmii_speed = rk3288_set_rmii_speed,
4860fb98db1SHeiko Stübner };
4870fb98db1SHeiko Stübner 
488b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0		0x04a0
489b4ac9456STobias Schramm 
490b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */
491b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \
492b4ac9456STobias Schramm 					GRF_BIT(4))
493b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
494b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
495b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
496b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M		GRF_BIT(0)
497b4ac9456STobias Schramm 
498b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv)
499b4ac9456STobias Schramm {
500b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
501b4ac9456STobias Schramm 
502b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
503b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
504b4ac9456STobias Schramm 		return;
505b4ac9456STobias Schramm 	}
506b4ac9456STobias Schramm 
507b4ac9456STobias Schramm 	regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
508b4ac9456STobias Schramm 		     RK3308_GMAC_PHY_INTF_SEL_RMII);
509b4ac9456STobias Schramm }
510b4ac9456STobias Schramm 
511b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
512b4ac9456STobias Schramm {
513b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
514b4ac9456STobias Schramm 
515b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
516b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
517b4ac9456STobias Schramm 		return;
518b4ac9456STobias Schramm 	}
519b4ac9456STobias Schramm 
520b4ac9456STobias Schramm 	if (speed == 10) {
521b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
522b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_10M);
523b4ac9456STobias Schramm 	} else if (speed == 100) {
524b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
525b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_100M);
526b4ac9456STobias Schramm 	} else {
527b4ac9456STobias Schramm 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
528b4ac9456STobias Schramm 	}
529b4ac9456STobias Schramm }
530b4ac9456STobias Schramm 
531b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = {
532b4ac9456STobias Schramm 	.set_to_rmii = rk3308_set_to_rmii,
533b4ac9456STobias Schramm 	.set_rmii_speed = rk3308_set_rmii_speed,
534b4ac9456STobias Schramm };
535b4ac9456STobias Schramm 
536d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0	0x0900
537d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1	0x0904
5388bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2	0x0908
5398bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1	0xb04
540d4ff816eSdavid.wu 
541d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */
542d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
543d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
544d4ff816eSdavid.wu 
545d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */
546d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII	\
547d4ff816eSdavid.wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
548d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII	\
549d4ff816eSdavid.wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
550d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
551d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
552d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
553d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M		GRF_BIT(2)
554d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M	GRF_BIT(7)
555d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
556d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M		(GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
557d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M		(GRF_BIT(11) | GRF_BIT(12))
558d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M		(GRF_CLR_BIT(11) | GRF_BIT(12))
559d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE		GRF_BIT(9)
560d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(9)
561d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
562d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
563d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
564d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
565d4ff816eSdavid.wu 
5668bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */
5678bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE		GRF_BIT(9)
5688bdf63bdSDavid Wu 
569d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
570d4ff816eSdavid.wu 				int tx_delay, int rx_delay)
571d4ff816eSdavid.wu {
572d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
573d4ff816eSdavid.wu 
574d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
575d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
576d4ff816eSdavid.wu 		return;
577d4ff816eSdavid.wu 	}
578d4ff816eSdavid.wu 
579d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
580d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
581d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE_CLR |
582d4ff816eSdavid.wu 		     RK3328_GMAC_RXCLK_DLY_ENABLE |
583d4ff816eSdavid.wu 		     RK3328_GMAC_TXCLK_DLY_ENABLE);
584d4ff816eSdavid.wu 
585d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
586d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
587d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
588d4ff816eSdavid.wu }
589d4ff816eSdavid.wu 
590d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
591d4ff816eSdavid.wu {
592d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
5938bdf63bdSDavid Wu 	unsigned int reg;
594d4ff816eSdavid.wu 
595d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
596d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
597d4ff816eSdavid.wu 		return;
598d4ff816eSdavid.wu 	}
599d4ff816eSdavid.wu 
6008bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6018bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6028bdf63bdSDavid Wu 
6038bdf63bdSDavid Wu 	regmap_write(bsp_priv->grf, reg,
604d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RMII |
605d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE);
606d4ff816eSdavid.wu }
607d4ff816eSdavid.wu 
608d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
609d4ff816eSdavid.wu {
610d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
611d4ff816eSdavid.wu 
612d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
613d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
614d4ff816eSdavid.wu 		return;
615d4ff816eSdavid.wu 	}
616d4ff816eSdavid.wu 
617d4ff816eSdavid.wu 	if (speed == 10)
618d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
619d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_2_5M);
620d4ff816eSdavid.wu 	else if (speed == 100)
621d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
622d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_25M);
623d4ff816eSdavid.wu 	else if (speed == 1000)
624d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
625d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_125M);
626d4ff816eSdavid.wu 	else
627d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
628d4ff816eSdavid.wu }
629d4ff816eSdavid.wu 
630d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
631d4ff816eSdavid.wu {
632d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
6338bdf63bdSDavid Wu 	unsigned int reg;
634d4ff816eSdavid.wu 
635d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
636d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
637d4ff816eSdavid.wu 		return;
638d4ff816eSdavid.wu 	}
639d4ff816eSdavid.wu 
6408bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6418bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6428bdf63bdSDavid Wu 
643d4ff816eSdavid.wu 	if (speed == 10)
6448bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
645d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_2_5M |
646d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_10M);
647d4ff816eSdavid.wu 	else if (speed == 100)
6488bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
649d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_25M |
650d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_100M);
651d4ff816eSdavid.wu 	else
652d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
653d4ff816eSdavid.wu }
654d4ff816eSdavid.wu 
6558bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
6568bdf63bdSDavid Wu {
6578bdf63bdSDavid Wu 	regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
6588bdf63bdSDavid Wu 		     RK3328_MACPHY_RMII_MODE);
6598bdf63bdSDavid Wu }
6608bdf63bdSDavid Wu 
661d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = {
662d4ff816eSdavid.wu 	.set_to_rgmii = rk3328_set_to_rgmii,
663d4ff816eSdavid.wu 	.set_to_rmii = rk3328_set_to_rmii,
664d4ff816eSdavid.wu 	.set_rgmii_speed = rk3328_set_rgmii_speed,
665d4ff816eSdavid.wu 	.set_rmii_speed = rk3328_set_rmii_speed,
6668bdf63bdSDavid Wu 	.integrated_phy_powerup =  rk3328_integrated_phy_powerup,
667d4ff816eSdavid.wu };
668d4ff816eSdavid.wu 
669ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6	0x0418
670ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7	0x041c
671ba289af8SRoger Chen 
672ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */
673ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
674ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
675ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
676ba289af8SRoger Chen 					 GRF_BIT(11))
677ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
678ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
679ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
680ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M		GRF_BIT(7)
681ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M	GRF_BIT(3)
682ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
683ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
684ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
685ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
686ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE		GRF_BIT(6)
687ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
688ba289af8SRoger Chen 
689ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */
690ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
691ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
692ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
693ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
694ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
695ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
696ba289af8SRoger Chen 
697ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
698ba289af8SRoger Chen 				int tx_delay, int rx_delay)
699ba289af8SRoger Chen {
700ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
701ba289af8SRoger Chen 
702ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
703ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
704ba289af8SRoger Chen 		return;
705ba289af8SRoger Chen 	}
706ba289af8SRoger Chen 
707ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
708ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RGMII |
709ba289af8SRoger Chen 		     RK3366_GMAC_RMII_MODE_CLR);
710ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
711eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
712ba289af8SRoger Chen 		     RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
713ba289af8SRoger Chen 		     RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
714ba289af8SRoger Chen }
715ba289af8SRoger Chen 
716ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
717ba289af8SRoger Chen {
718ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
719ba289af8SRoger Chen 
720ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
721ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
722ba289af8SRoger Chen 		return;
723ba289af8SRoger Chen 	}
724ba289af8SRoger Chen 
725ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
726ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
727ba289af8SRoger Chen }
728ba289af8SRoger Chen 
729ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
730ba289af8SRoger Chen {
731ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
732ba289af8SRoger Chen 
733ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
734ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
735ba289af8SRoger Chen 		return;
736ba289af8SRoger Chen 	}
737ba289af8SRoger Chen 
738ba289af8SRoger Chen 	if (speed == 10)
739ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
740ba289af8SRoger Chen 			     RK3366_GMAC_CLK_2_5M);
741ba289af8SRoger Chen 	else if (speed == 100)
742ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
743ba289af8SRoger Chen 			     RK3366_GMAC_CLK_25M);
744ba289af8SRoger Chen 	else if (speed == 1000)
745ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
746ba289af8SRoger Chen 			     RK3366_GMAC_CLK_125M);
747ba289af8SRoger Chen 	else
748ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
749ba289af8SRoger Chen }
750ba289af8SRoger Chen 
751ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
752ba289af8SRoger Chen {
753ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
754ba289af8SRoger Chen 
755ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
756ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
757ba289af8SRoger Chen 		return;
758ba289af8SRoger Chen 	}
759ba289af8SRoger Chen 
760ba289af8SRoger Chen 	if (speed == 10) {
761ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
762ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_2_5M |
763ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_10M);
764ba289af8SRoger Chen 	} else if (speed == 100) {
765ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
766ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_25M |
767ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_100M);
768ba289af8SRoger Chen 	} else {
769ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
770ba289af8SRoger Chen 	}
771ba289af8SRoger Chen }
772ba289af8SRoger Chen 
773ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = {
774ba289af8SRoger Chen 	.set_to_rgmii = rk3366_set_to_rgmii,
775ba289af8SRoger Chen 	.set_to_rmii = rk3366_set_to_rmii,
776ba289af8SRoger Chen 	.set_rgmii_speed = rk3366_set_rgmii_speed,
777ba289af8SRoger Chen 	.set_rmii_speed = rk3366_set_rmii_speed,
778ba289af8SRoger Chen };
779ba289af8SRoger Chen 
780df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15	0x043c
781df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16	0x0440
782df558854SHeiko Stübner 
783df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */
784df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
785df558854SHeiko Stübner 					 GRF_CLR_BIT(11))
786df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
787df558854SHeiko Stübner 					 GRF_BIT(11))
788df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
789df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
790df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
791df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M		GRF_BIT(7)
792df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M	GRF_BIT(3)
793df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
794df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
795df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
796df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
797df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE		GRF_BIT(6)
798df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
799df558854SHeiko Stübner 
800df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */
801df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
802df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
803df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
804df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
805df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
806df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
807df558854SHeiko Stübner 
808df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
809df558854SHeiko Stübner 				int tx_delay, int rx_delay)
810df558854SHeiko Stübner {
811df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
812df558854SHeiko Stübner 
813df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
814df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
815df558854SHeiko Stübner 		return;
816df558854SHeiko Stübner 	}
817df558854SHeiko Stübner 
818df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
819df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
820df558854SHeiko Stübner 		     RK3368_GMAC_RMII_MODE_CLR);
821df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
822eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
823df558854SHeiko Stübner 		     RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
824df558854SHeiko Stübner 		     RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
825df558854SHeiko Stübner }
826df558854SHeiko Stübner 
827df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
828df558854SHeiko Stübner {
829df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
830df558854SHeiko Stübner 
831df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
832df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
833df558854SHeiko Stübner 		return;
834df558854SHeiko Stübner 	}
835df558854SHeiko Stübner 
836df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
837df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
838df558854SHeiko Stübner }
839df558854SHeiko Stübner 
840df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
841df558854SHeiko Stübner {
842df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
843df558854SHeiko Stübner 
844df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
845df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
846df558854SHeiko Stübner 		return;
847df558854SHeiko Stübner 	}
848df558854SHeiko Stübner 
849df558854SHeiko Stübner 	if (speed == 10)
850df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
851df558854SHeiko Stübner 			     RK3368_GMAC_CLK_2_5M);
852df558854SHeiko Stübner 	else if (speed == 100)
853df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
854df558854SHeiko Stübner 			     RK3368_GMAC_CLK_25M);
855df558854SHeiko Stübner 	else if (speed == 1000)
856df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
857df558854SHeiko Stübner 			     RK3368_GMAC_CLK_125M);
858df558854SHeiko Stübner 	else
859df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
860df558854SHeiko Stübner }
861df558854SHeiko Stübner 
862df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
863df558854SHeiko Stübner {
864df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
865df558854SHeiko Stübner 
866df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
867df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
868df558854SHeiko Stübner 		return;
869df558854SHeiko Stübner 	}
870df558854SHeiko Stübner 
871df558854SHeiko Stübner 	if (speed == 10) {
872df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
873df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_2_5M |
874df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_10M);
875df558854SHeiko Stübner 	} else if (speed == 100) {
876df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
877df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_25M |
878df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_100M);
879df558854SHeiko Stübner 	} else {
880df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
881df558854SHeiko Stübner 	}
882df558854SHeiko Stübner }
883df558854SHeiko Stübner 
88492c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = {
885df558854SHeiko Stübner 	.set_to_rgmii = rk3368_set_to_rgmii,
886df558854SHeiko Stübner 	.set_to_rmii = rk3368_set_to_rmii,
887df558854SHeiko Stübner 	.set_rgmii_speed = rk3368_set_rgmii_speed,
888df558854SHeiko Stübner 	.set_rmii_speed = rk3368_set_rmii_speed,
889df558854SHeiko Stübner };
890df558854SHeiko Stübner 
891ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5	0xc214
892ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6	0xc218
893ba289af8SRoger Chen 
894ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */
895ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
896ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
897ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
898ba289af8SRoger Chen 					 GRF_BIT(11))
899ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
900ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
901ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
902ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M		GRF_BIT(7)
903ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M	GRF_BIT(3)
904ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
905ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
906ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
907ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
908ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE		GRF_BIT(6)
909ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
910ba289af8SRoger Chen 
911ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */
912ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
913ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
914ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
915ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
916ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
917ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
918ba289af8SRoger Chen 
919ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
920ba289af8SRoger Chen 				int tx_delay, int rx_delay)
921ba289af8SRoger Chen {
922ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
923ba289af8SRoger Chen 
924ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
925ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
926ba289af8SRoger Chen 		return;
927ba289af8SRoger Chen 	}
928ba289af8SRoger Chen 
929ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
930ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RGMII |
931ba289af8SRoger Chen 		     RK3399_GMAC_RMII_MODE_CLR);
932ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
933eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
934ba289af8SRoger Chen 		     RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
935ba289af8SRoger Chen 		     RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
936ba289af8SRoger Chen }
937ba289af8SRoger Chen 
938ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
939ba289af8SRoger Chen {
940ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
941ba289af8SRoger Chen 
942ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
943ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
944ba289af8SRoger Chen 		return;
945ba289af8SRoger Chen 	}
946ba289af8SRoger Chen 
947ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
948ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
949ba289af8SRoger Chen }
950ba289af8SRoger Chen 
951ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
952ba289af8SRoger Chen {
953ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
954ba289af8SRoger Chen 
955ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
956ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
957ba289af8SRoger Chen 		return;
958ba289af8SRoger Chen 	}
959ba289af8SRoger Chen 
960ba289af8SRoger Chen 	if (speed == 10)
961ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
962ba289af8SRoger Chen 			     RK3399_GMAC_CLK_2_5M);
963ba289af8SRoger Chen 	else if (speed == 100)
964ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
965ba289af8SRoger Chen 			     RK3399_GMAC_CLK_25M);
966ba289af8SRoger Chen 	else if (speed == 1000)
967ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
968ba289af8SRoger Chen 			     RK3399_GMAC_CLK_125M);
969ba289af8SRoger Chen 	else
970ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
971ba289af8SRoger Chen }
972ba289af8SRoger Chen 
973ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
974ba289af8SRoger Chen {
975ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
976ba289af8SRoger Chen 
977ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
978ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
979ba289af8SRoger Chen 		return;
980ba289af8SRoger Chen 	}
981ba289af8SRoger Chen 
982ba289af8SRoger Chen 	if (speed == 10) {
983ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
984ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_2_5M |
985ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_10M);
986ba289af8SRoger Chen 	} else if (speed == 100) {
987ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
988ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_25M |
989ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_100M);
990ba289af8SRoger Chen 	} else {
991ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
992ba289af8SRoger Chen 	}
993ba289af8SRoger Chen }
994ba289af8SRoger Chen 
995ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = {
996ba289af8SRoger Chen 	.set_to_rgmii = rk3399_set_to_rgmii,
997ba289af8SRoger Chen 	.set_to_rmii = rk3399_set_to_rmii,
998ba289af8SRoger Chen 	.set_rgmii_speed = rk3399_set_rgmii_speed,
999ba289af8SRoger Chen 	.set_rmii_speed = rk3399_set_rmii_speed,
1000ba289af8SRoger Chen };
1001ba289af8SRoger Chen 
10023bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON0		0x0380
10033bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON1		0x0384
10043bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON0		0x0388
10053bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON1		0x038c
10063bb3d6b1SDavid Wu 
10073bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
10083bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RGMII	\
10093bb3d6b1SDavid Wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
10103bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RMII	\
10113bb3d6b1SDavid Wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
10123bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
10133bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
10143bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
10153bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_DISABLE		GRF_CLR_BIT(1)
10163bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_ENABLE		GRF_BIT(0)
10173bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_DISABLE		GRF_CLR_BIT(0)
10183bb3d6b1SDavid Wu 
10193bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
10203bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
10213bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
10223bb3d6b1SDavid Wu 
10233bb3d6b1SDavid Wu static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,
10243bb3d6b1SDavid Wu 				int tx_delay, int rx_delay)
10253bb3d6b1SDavid Wu {
10263bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10273bb3d6b1SDavid Wu 	u32 con0, con1;
10283bb3d6b1SDavid Wu 
10293bb3d6b1SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10303bb3d6b1SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
10313bb3d6b1SDavid Wu 		return;
10323bb3d6b1SDavid Wu 	}
10333bb3d6b1SDavid Wu 
10343bb3d6b1SDavid Wu 	con0 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON0 :
10353bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON0;
10363bb3d6b1SDavid Wu 	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10373bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON1;
10383bb3d6b1SDavid Wu 
10393bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con0,
10403bb3d6b1SDavid Wu 		     RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) |
10413bb3d6b1SDavid Wu 		     RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
10423bb3d6b1SDavid Wu 
10433bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con1,
10443bb3d6b1SDavid Wu 		     RK3568_GMAC_PHY_INTF_SEL_RGMII |
10453bb3d6b1SDavid Wu 		     RK3568_GMAC_RXCLK_DLY_ENABLE |
10463bb3d6b1SDavid Wu 		     RK3568_GMAC_TXCLK_DLY_ENABLE);
10473bb3d6b1SDavid Wu }
10483bb3d6b1SDavid Wu 
10493bb3d6b1SDavid Wu static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv)
10503bb3d6b1SDavid Wu {
10513bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10523bb3d6b1SDavid Wu 	u32 con1;
10533bb3d6b1SDavid Wu 
10543bb3d6b1SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10553bb3d6b1SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
10563bb3d6b1SDavid Wu 		return;
10573bb3d6b1SDavid Wu 	}
10583bb3d6b1SDavid Wu 
10593bb3d6b1SDavid Wu 	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10603bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON1;
10613bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
10623bb3d6b1SDavid Wu }
10633bb3d6b1SDavid Wu 
10643bb3d6b1SDavid Wu static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
10653bb3d6b1SDavid Wu {
10663bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10673bb3d6b1SDavid Wu 	unsigned long rate;
10683bb3d6b1SDavid Wu 	int ret;
10693bb3d6b1SDavid Wu 
10703bb3d6b1SDavid Wu 	switch (speed) {
10713bb3d6b1SDavid Wu 	case 10:
10723bb3d6b1SDavid Wu 		rate = 2500000;
10733bb3d6b1SDavid Wu 		break;
10743bb3d6b1SDavid Wu 	case 100:
10753bb3d6b1SDavid Wu 		rate = 25000000;
10763bb3d6b1SDavid Wu 		break;
10773bb3d6b1SDavid Wu 	case 1000:
10783bb3d6b1SDavid Wu 		rate = 125000000;
10793bb3d6b1SDavid Wu 		break;
10803bb3d6b1SDavid Wu 	default:
10813bb3d6b1SDavid Wu 		dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
10823bb3d6b1SDavid Wu 		return;
10833bb3d6b1SDavid Wu 	}
10843bb3d6b1SDavid Wu 
10853bb3d6b1SDavid Wu 	ret = clk_set_rate(bsp_priv->clk_mac_speed, rate);
10863bb3d6b1SDavid Wu 	if (ret)
10873bb3d6b1SDavid Wu 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
10883bb3d6b1SDavid Wu 			__func__, rate, ret);
10893bb3d6b1SDavid Wu }
10903bb3d6b1SDavid Wu 
10913bb3d6b1SDavid Wu static const struct rk_gmac_ops rk3568_ops = {
10923bb3d6b1SDavid Wu 	.set_to_rgmii = rk3568_set_to_rgmii,
10933bb3d6b1SDavid Wu 	.set_to_rmii = rk3568_set_to_rmii,
10943bb3d6b1SDavid Wu 	.set_rgmii_speed = rk3568_set_gmac_speed,
10953bb3d6b1SDavid Wu 	.set_rmii_speed = rk3568_set_gmac_speed,
1096*0546b224SJohn Keeping 	.regs_valid = true,
10973bb3d6b1SDavid Wu 	.regs = {
10983bb3d6b1SDavid Wu 		0xfe2a0000, /* gmac0 */
10993bb3d6b1SDavid Wu 		0xfe010000, /* gmac1 */
11003bb3d6b1SDavid Wu 		0x0, /* sentinel */
11013bb3d6b1SDavid Wu 	},
11023bb3d6b1SDavid Wu };
11033bb3d6b1SDavid Wu 
110489c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0		0X0900
110589c9c163SDavid Wu 
110689c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */
110789c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
110889c9c163SDavid Wu 					GRF_BIT(6))
110989c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
111089c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
111189c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
111289c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M		GRF_BIT(2)
111389c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M	GRF_BIT(7)
111489c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
111589c9c163SDavid Wu 
111689c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
111789c9c163SDavid Wu {
111889c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
111989c9c163SDavid Wu 
112089c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
112189c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
112289c9c163SDavid Wu 		return;
112389c9c163SDavid Wu 	}
112489c9c163SDavid Wu 
112589c9c163SDavid Wu 	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
112689c9c163SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
112789c9c163SDavid Wu }
112889c9c163SDavid Wu 
112989c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
113089c9c163SDavid Wu {
113189c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
113289c9c163SDavid Wu 
113389c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
113489c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
113589c9c163SDavid Wu 		return;
113689c9c163SDavid Wu 	}
113789c9c163SDavid Wu 
113889c9c163SDavid Wu 	if (speed == 10) {
113989c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
114089c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_2_5M |
114189c9c163SDavid Wu 			     RV1108_GMAC_SPEED_10M);
114289c9c163SDavid Wu 	} else if (speed == 100) {
114389c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
114489c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_25M |
114589c9c163SDavid Wu 			     RV1108_GMAC_SPEED_100M);
114689c9c163SDavid Wu 	} else {
114789c9c163SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
114889c9c163SDavid Wu 	}
114989c9c163SDavid Wu }
115089c9c163SDavid Wu 
115189c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = {
115289c9c163SDavid Wu 	.set_to_rmii = rv1108_set_to_rmii,
115389c9c163SDavid Wu 	.set_rmii_speed = rv1108_set_rmii_speed,
115489c9c163SDavid Wu };
115589c9c163SDavid Wu 
1156fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0		0xb00
1157fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1		0xb04
1158fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2		0xb08
1159fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3		0xb0c
1160fecd4d7eSDavid Wu 
1161fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE		GRF_BIT(0)
1162fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
1163fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
1164fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
1165fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID		HIWORD_UPDATE(0x1234, 0xffff, 0)
1166fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID		HIWORD_UPDATE(0x35, 0x3f, 0)
1167fecd4d7eSDavid Wu 
1168fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
11697ad269eaSRoger Chen {
1170fecd4d7eSDavid Wu 	if (priv->ops->integrated_phy_powerup)
1171fecd4d7eSDavid Wu 		priv->ops->integrated_phy_powerup(priv);
1172fecd4d7eSDavid Wu 
1173fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
1174fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
1175fecd4d7eSDavid Wu 
1176fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
1177fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
1178fecd4d7eSDavid Wu 
1179fecd4d7eSDavid Wu 	if (priv->phy_reset) {
1180fecd4d7eSDavid Wu 		/* PHY needs to be disabled before trying to reset it */
1181fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1182fecd4d7eSDavid Wu 		if (priv->phy_reset)
1183fecd4d7eSDavid Wu 			reset_control_assert(priv->phy_reset);
1184fecd4d7eSDavid Wu 		usleep_range(10, 20);
1185fecd4d7eSDavid Wu 		if (priv->phy_reset)
1186fecd4d7eSDavid Wu 			reset_control_deassert(priv->phy_reset);
1187fecd4d7eSDavid Wu 		usleep_range(10, 20);
1188fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
1189fecd4d7eSDavid Wu 		msleep(30);
1190fecd4d7eSDavid Wu 	}
1191fecd4d7eSDavid Wu }
1192fecd4d7eSDavid Wu 
1193fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
1194fecd4d7eSDavid Wu {
1195fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1196fecd4d7eSDavid Wu 	if (priv->phy_reset)
1197fecd4d7eSDavid Wu 		reset_control_assert(priv->phy_reset);
1198fecd4d7eSDavid Wu }
1199fecd4d7eSDavid Wu 
1200fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
1201fecd4d7eSDavid Wu {
1202fecd4d7eSDavid Wu 	struct rk_priv_data *bsp_priv = plat->bsp_priv;
12037ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
1204fecd4d7eSDavid Wu 	int ret;
12057ad269eaSRoger Chen 
12067ad269eaSRoger Chen 	bsp_priv->clk_enabled = false;
12077ad269eaSRoger Chen 
12087ad269eaSRoger Chen 	bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
12097ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_rx))
1210d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1211d42202dcSRomain Perier 			"mac_clk_rx");
12127ad269eaSRoger Chen 
12137ad269eaSRoger Chen 	bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
12147ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_tx))
1215d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1216d42202dcSRomain Perier 			"mac_clk_tx");
12177ad269eaSRoger Chen 
12187ad269eaSRoger Chen 	bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
12197ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->aclk_mac))
1220d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1221d42202dcSRomain Perier 			"aclk_mac");
12227ad269eaSRoger Chen 
12237ad269eaSRoger Chen 	bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
12247ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->pclk_mac))
1225d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1226d42202dcSRomain Perier 			"pclk_mac");
12277ad269eaSRoger Chen 
12287ad269eaSRoger Chen 	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
12297ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->clk_mac))
1230d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1231d42202dcSRomain Perier 			"stmmaceth");
12327ad269eaSRoger Chen 
12337ad269eaSRoger Chen 	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
12347ad269eaSRoger Chen 		bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
12357ad269eaSRoger Chen 		if (IS_ERR(bsp_priv->clk_mac_ref))
1236d42202dcSRomain Perier 			dev_err(dev, "cannot get clock %s\n",
1237d42202dcSRomain Perier 				"clk_mac_ref");
12387ad269eaSRoger Chen 
12397ad269eaSRoger Chen 		if (!bsp_priv->clock_input) {
12407ad269eaSRoger Chen 			bsp_priv->clk_mac_refout =
12417ad269eaSRoger Chen 				devm_clk_get(dev, "clk_mac_refout");
12427ad269eaSRoger Chen 			if (IS_ERR(bsp_priv->clk_mac_refout))
1243d42202dcSRomain Perier 				dev_err(dev, "cannot get clock %s\n",
1244d42202dcSRomain Perier 					"clk_mac_refout");
12457ad269eaSRoger Chen 		}
12467ad269eaSRoger Chen 	}
12477ad269eaSRoger Chen 
124823c94d63SDavid Wu 	bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
124923c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed))
125023c94d63SDavid Wu 		dev_err(dev, "cannot get clock %s\n", "clk_mac_speed");
125123c94d63SDavid Wu 
12527ad269eaSRoger Chen 	if (bsp_priv->clock_input) {
1253d42202dcSRomain Perier 		dev_info(dev, "clock input from PHY\n");
12547ad269eaSRoger Chen 	} else {
12557ad269eaSRoger Chen 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1256c48fa33cSHeiko Stübner 			clk_set_rate(bsp_priv->clk_mac, 50000000);
12577ad269eaSRoger Chen 	}
12587ad269eaSRoger Chen 
1259fecd4d7eSDavid Wu 	if (plat->phy_node && bsp_priv->integrated_phy) {
1260fecd4d7eSDavid Wu 		bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
1261fecd4d7eSDavid Wu 		if (IS_ERR(bsp_priv->clk_phy)) {
1262fecd4d7eSDavid Wu 			ret = PTR_ERR(bsp_priv->clk_phy);
1263fecd4d7eSDavid Wu 			dev_err(dev, "Cannot get PHY clock: %d\n", ret);
1264fecd4d7eSDavid Wu 			return -EINVAL;
1265fecd4d7eSDavid Wu 		}
1266fecd4d7eSDavid Wu 		clk_set_rate(bsp_priv->clk_phy, 50000000);
1267fecd4d7eSDavid Wu 	}
1268fecd4d7eSDavid Wu 
12697ad269eaSRoger Chen 	return 0;
12707ad269eaSRoger Chen }
12717ad269eaSRoger Chen 
12727ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
12737ad269eaSRoger Chen {
1274428ad1bcSLABBE Corentin 	int phy_iface = bsp_priv->phy_iface;
12757ad269eaSRoger Chen 
12767ad269eaSRoger Chen 	if (enable) {
12777ad269eaSRoger Chen 		if (!bsp_priv->clk_enabled) {
12787ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
12797ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->mac_clk_rx))
12807ad269eaSRoger Chen 					clk_prepare_enable(
12817ad269eaSRoger Chen 						bsp_priv->mac_clk_rx);
12827ad269eaSRoger Chen 
12837ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_ref))
12847ad269eaSRoger Chen 					clk_prepare_enable(
12857ad269eaSRoger Chen 						bsp_priv->clk_mac_ref);
12867ad269eaSRoger Chen 
12877ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_refout))
12887ad269eaSRoger Chen 					clk_prepare_enable(
12897ad269eaSRoger Chen 						bsp_priv->clk_mac_refout);
12907ad269eaSRoger Chen 			}
12917ad269eaSRoger Chen 
1292fecd4d7eSDavid Wu 			if (!IS_ERR(bsp_priv->clk_phy))
1293fecd4d7eSDavid Wu 				clk_prepare_enable(bsp_priv->clk_phy);
1294fecd4d7eSDavid Wu 
12957ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->aclk_mac))
12967ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->aclk_mac);
12977ad269eaSRoger Chen 
12987ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->pclk_mac))
12997ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->pclk_mac);
13007ad269eaSRoger Chen 
13017ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->mac_clk_tx))
13027ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->mac_clk_tx);
13037ad269eaSRoger Chen 
130423c94d63SDavid Wu 			if (!IS_ERR(bsp_priv->clk_mac_speed))
130523c94d63SDavid Wu 				clk_prepare_enable(bsp_priv->clk_mac_speed);
130623c94d63SDavid Wu 
13077ad269eaSRoger Chen 			/**
13087ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
13097ad269eaSRoger Chen 			 *	clk_prepare_enable(bsp_priv->clk_mac);
13107ad269eaSRoger Chen 			 */
13117ad269eaSRoger Chen 			mdelay(5);
13127ad269eaSRoger Chen 			bsp_priv->clk_enabled = true;
13137ad269eaSRoger Chen 		}
13147ad269eaSRoger Chen 	} else {
13157ad269eaSRoger Chen 		if (bsp_priv->clk_enabled) {
13167ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
131793120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->mac_clk_rx);
13187ad269eaSRoger Chen 
131993120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_ref);
13207ad269eaSRoger Chen 
132193120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_refout);
13227ad269eaSRoger Chen 			}
13237ad269eaSRoger Chen 
1324fecd4d7eSDavid Wu 			clk_disable_unprepare(bsp_priv->clk_phy);
1325fecd4d7eSDavid Wu 
13267ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->aclk_mac);
13277ad269eaSRoger Chen 
13287ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->pclk_mac);
13297ad269eaSRoger Chen 
13307ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->mac_clk_tx);
133123c94d63SDavid Wu 
133223c94d63SDavid Wu 			clk_disable_unprepare(bsp_priv->clk_mac_speed);
13337ad269eaSRoger Chen 			/**
13347ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
13357ad269eaSRoger Chen 			 *	clk_disable_unprepare(bsp_priv->clk_mac);
13367ad269eaSRoger Chen 			 */
13377ad269eaSRoger Chen 			bsp_priv->clk_enabled = false;
13387ad269eaSRoger Chen 		}
13397ad269eaSRoger Chen 	}
13407ad269eaSRoger Chen 
13417ad269eaSRoger Chen 	return 0;
13427ad269eaSRoger Chen }
13437ad269eaSRoger Chen 
13447ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
13457ad269eaSRoger Chen {
13462e12f536SRomain Perier 	struct regulator *ldo = bsp_priv->regulator;
13477ad269eaSRoger Chen 	int ret;
13487ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
13497ad269eaSRoger Chen 
13503b25528eSChen-Yu Tsai 	if (!ldo)
13513b25528eSChen-Yu Tsai 		return 0;
13527ad269eaSRoger Chen 
13537ad269eaSRoger Chen 	if (enable) {
13547ad269eaSRoger Chen 		ret = regulator_enable(ldo);
13552e12f536SRomain Perier 		if (ret)
1356d42202dcSRomain Perier 			dev_err(dev, "fail to enable phy-supply\n");
13577ad269eaSRoger Chen 	} else {
13587ad269eaSRoger Chen 		ret = regulator_disable(ldo);
13592e12f536SRomain Perier 		if (ret)
1360d42202dcSRomain Perier 			dev_err(dev, "fail to disable phy-supply\n");
13617ad269eaSRoger Chen 	}
13627ad269eaSRoger Chen 
13637ad269eaSRoger Chen 	return 0;
13647ad269eaSRoger Chen }
13657ad269eaSRoger Chen 
13660fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1367fecd4d7eSDavid Wu 					  struct plat_stmmacenet_data *plat,
136892c2588fSJoachim Eastwood 					  const struct rk_gmac_ops *ops)
13697ad269eaSRoger Chen {
13707ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv;
13717ad269eaSRoger Chen 	struct device *dev = &pdev->dev;
13723bb3d6b1SDavid Wu 	struct resource *res;
13737ad269eaSRoger Chen 	int ret;
13747ad269eaSRoger Chen 	const char *strings = NULL;
13757ad269eaSRoger Chen 	int value;
13767ad269eaSRoger Chen 
13777ad269eaSRoger Chen 	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
13787ad269eaSRoger Chen 	if (!bsp_priv)
13797ad269eaSRoger Chen 		return ERR_PTR(-ENOMEM);
13807ad269eaSRoger Chen 
13810c65b2b9SAndrew Lunn 	of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
13820fb98db1SHeiko Stübner 	bsp_priv->ops = ops;
13837ad269eaSRoger Chen 
13843bb3d6b1SDavid Wu 	/* Some SoCs have multiple MAC controllers, which need
13853bb3d6b1SDavid Wu 	 * to be distinguished.
13863bb3d6b1SDavid Wu 	 */
13873bb3d6b1SDavid Wu 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1388*0546b224SJohn Keeping 	if (res && ops->regs_valid) {
13893bb3d6b1SDavid Wu 		int i = 0;
13903bb3d6b1SDavid Wu 
13913bb3d6b1SDavid Wu 		while (ops->regs[i]) {
13923bb3d6b1SDavid Wu 			if (ops->regs[i] == res->start) {
13933bb3d6b1SDavid Wu 				bsp_priv->id = i;
13943bb3d6b1SDavid Wu 				break;
13953bb3d6b1SDavid Wu 			}
13963bb3d6b1SDavid Wu 			i++;
13973bb3d6b1SDavid Wu 		}
13983bb3d6b1SDavid Wu 	}
13993bb3d6b1SDavid Wu 
14002e12f536SRomain Perier 	bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
14012e12f536SRomain Perier 	if (IS_ERR(bsp_priv->regulator)) {
14022e12f536SRomain Perier 		if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) {
14032e12f536SRomain Perier 			dev_err(dev, "phy regulator is not available yet, deferred probing\n");
14042e12f536SRomain Perier 			return ERR_PTR(-EPROBE_DEFER);
14052e12f536SRomain Perier 		}
14062e12f536SRomain Perier 		dev_err(dev, "no regulator found\n");
14072e12f536SRomain Perier 		bsp_priv->regulator = NULL;
14087ad269eaSRoger Chen 	}
14097ad269eaSRoger Chen 
14107ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
14117ad269eaSRoger Chen 	if (ret) {
1412d42202dcSRomain Perier 		dev_err(dev, "Can not read property: clock_in_out.\n");
14137ad269eaSRoger Chen 		bsp_priv->clock_input = true;
14147ad269eaSRoger Chen 	} else {
1415d42202dcSRomain Perier 		dev_info(dev, "clock input or output? (%s).\n",
1416d42202dcSRomain Perier 			 strings);
14177ad269eaSRoger Chen 		if (!strcmp(strings, "input"))
14187ad269eaSRoger Chen 			bsp_priv->clock_input = true;
14197ad269eaSRoger Chen 		else
14207ad269eaSRoger Chen 			bsp_priv->clock_input = false;
14217ad269eaSRoger Chen 	}
14227ad269eaSRoger Chen 
14237ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
14247ad269eaSRoger Chen 	if (ret) {
14257ad269eaSRoger Chen 		bsp_priv->tx_delay = 0x30;
1426d42202dcSRomain Perier 		dev_err(dev, "Can not read property: tx_delay.");
1427d42202dcSRomain Perier 		dev_err(dev, "set tx_delay to 0x%x\n",
1428d42202dcSRomain Perier 			bsp_priv->tx_delay);
14297ad269eaSRoger Chen 	} else {
1430d42202dcSRomain Perier 		dev_info(dev, "TX delay(0x%x).\n", value);
14317ad269eaSRoger Chen 		bsp_priv->tx_delay = value;
14327ad269eaSRoger Chen 	}
14337ad269eaSRoger Chen 
14347ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
14357ad269eaSRoger Chen 	if (ret) {
14367ad269eaSRoger Chen 		bsp_priv->rx_delay = 0x10;
1437d42202dcSRomain Perier 		dev_err(dev, "Can not read property: rx_delay.");
1438d42202dcSRomain Perier 		dev_err(dev, "set rx_delay to 0x%x\n",
1439d42202dcSRomain Perier 			bsp_priv->rx_delay);
14407ad269eaSRoger Chen 	} else {
1441d42202dcSRomain Perier 		dev_info(dev, "RX delay(0x%x).\n", value);
14427ad269eaSRoger Chen 		bsp_priv->rx_delay = value;
14437ad269eaSRoger Chen 	}
14447ad269eaSRoger Chen 
14457ad269eaSRoger Chen 	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
14467ad269eaSRoger Chen 							"rockchip,grf");
14477ad269eaSRoger Chen 
1448fecd4d7eSDavid Wu 	if (plat->phy_node) {
1449fecd4d7eSDavid Wu 		bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
1450fecd4d7eSDavid Wu 								 "phy-is-integrated");
1451fecd4d7eSDavid Wu 		if (bsp_priv->integrated_phy) {
1452fecd4d7eSDavid Wu 			bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
1453fecd4d7eSDavid Wu 			if (IS_ERR(bsp_priv->phy_reset)) {
1454fecd4d7eSDavid Wu 				dev_err(&pdev->dev, "No PHY reset control found.\n");
1455fecd4d7eSDavid Wu 				bsp_priv->phy_reset = NULL;
1456fecd4d7eSDavid Wu 			}
1457fecd4d7eSDavid Wu 		}
1458fecd4d7eSDavid Wu 	}
1459fecd4d7eSDavid Wu 	dev_info(dev, "integrated PHY? (%s).\n",
1460fecd4d7eSDavid Wu 		 bsp_priv->integrated_phy ? "yes" : "no");
1461fecd4d7eSDavid Wu 
1462fecd4d7eSDavid Wu 	bsp_priv->pdev = pdev;
146345383f52SRoger Chen 
146445383f52SRoger Chen 	return bsp_priv;
146545383f52SRoger Chen }
146645383f52SRoger Chen 
146737c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv)
146837c80d15SDavid Wu {
146937c80d15SDavid Wu 	switch (bsp_priv->phy_iface) {
147037c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII:
147137c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_ID:
147237c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_RXID:
147337c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_TXID:
147437c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rgmii)
147537c80d15SDavid Wu 			return -EINVAL;
147637c80d15SDavid Wu 		break;
147737c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RMII:
147837c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rmii)
147937c80d15SDavid Wu 			return -EINVAL;
148037c80d15SDavid Wu 		break;
148137c80d15SDavid Wu 	default:
148237c80d15SDavid Wu 		dev_err(&bsp_priv->pdev->dev,
148337c80d15SDavid Wu 			"unsupported interface %d", bsp_priv->phy_iface);
148437c80d15SDavid Wu 	}
148537c80d15SDavid Wu 	return 0;
148637c80d15SDavid Wu }
148737c80d15SDavid Wu 
148845383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
148945383f52SRoger Chen {
149045383f52SRoger Chen 	int ret;
149145383f52SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
149245383f52SRoger Chen 
149337c80d15SDavid Wu 	ret = rk_gmac_check_ops(bsp_priv);
149437c80d15SDavid Wu 	if (ret)
149537c80d15SDavid Wu 		return ret;
149637c80d15SDavid Wu 
1497f217bfdeSHeiko Stübner 	ret = gmac_clk_enable(bsp_priv, true);
1498f217bfdeSHeiko Stübner 	if (ret)
1499f217bfdeSHeiko Stübner 		return ret;
1500f217bfdeSHeiko Stübner 
15017ad269eaSRoger Chen 	/*rmii or rgmii*/
1502eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1503eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1504d42202dcSRomain Perier 		dev_info(dev, "init for RGMII\n");
15050fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
15060fb98db1SHeiko Stübner 					    bsp_priv->rx_delay);
1507eaf70ad1SWadim Egorov 		break;
1508eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1509eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_ID\n");
1510eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
1511eaf70ad1SWadim Egorov 		break;
1512eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1513eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_RXID\n");
1514eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
1515eaf70ad1SWadim Egorov 		break;
1516eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
1517eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_TXID\n");
1518eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
1519eaf70ad1SWadim Egorov 		break;
1520eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
1521d42202dcSRomain Perier 		dev_info(dev, "init for RMII\n");
15220fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rmii(bsp_priv);
1523eaf70ad1SWadim Egorov 		break;
1524eaf70ad1SWadim Egorov 	default:
1525d42202dcSRomain Perier 		dev_err(dev, "NO interface defined!\n");
15267ad269eaSRoger Chen 	}
15277ad269eaSRoger Chen 
15287ad269eaSRoger Chen 	ret = phy_power_on(bsp_priv, true);
1529c69c29a1SAlexey Khoroshilov 	if (ret) {
1530c69c29a1SAlexey Khoroshilov 		gmac_clk_enable(bsp_priv, false);
15317ad269eaSRoger Chen 		return ret;
1532c69c29a1SAlexey Khoroshilov 	}
15337ad269eaSRoger Chen 
1534aec3f415SPunit Agrawal 	pm_runtime_get_sync(dev);
1535aec3f415SPunit Agrawal 
1536fecd4d7eSDavid Wu 	if (bsp_priv->integrated_phy)
1537fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerup(bsp_priv);
1538fecd4d7eSDavid Wu 
15397ad269eaSRoger Chen 	return 0;
15407ad269eaSRoger Chen }
15417ad269eaSRoger Chen 
1542229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac)
15437ad269eaSRoger Chen {
1544fecd4d7eSDavid Wu 	if (gmac->integrated_phy)
1545fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerdown(gmac);
1546fecd4d7eSDavid Wu 
1547aec3f415SPunit Agrawal 	pm_runtime_put_sync(&gmac->pdev->dev);
1548aec3f415SPunit Agrawal 
15497ad269eaSRoger Chen 	phy_power_on(gmac, false);
15507ad269eaSRoger Chen 	gmac_clk_enable(gmac, false);
15517ad269eaSRoger Chen }
15527ad269eaSRoger Chen 
15537ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed)
15547ad269eaSRoger Chen {
15557ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
15567ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
15577ad269eaSRoger Chen 
1558eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1559eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1560eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1561eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1562eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
156337c80d15SDavid Wu 		if (bsp_priv->ops->set_rgmii_speed)
15640fb98db1SHeiko Stübner 			bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1565eaf70ad1SWadim Egorov 		break;
1566eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
156737c80d15SDavid Wu 		if (bsp_priv->ops->set_rmii_speed)
15680fb98db1SHeiko Stübner 			bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1569eaf70ad1SWadim Egorov 		break;
1570eaf70ad1SWadim Egorov 	default:
15717ad269eaSRoger Chen 		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
15727ad269eaSRoger Chen 	}
1573eaf70ad1SWadim Egorov }
15747ad269eaSRoger Chen 
157527ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev)
157627ffefd2SJoachim Eastwood {
157727ffefd2SJoachim Eastwood 	struct plat_stmmacenet_data *plat_dat;
157827ffefd2SJoachim Eastwood 	struct stmmac_resources stmmac_res;
1579f529f182SJoachim Eastwood 	const struct rk_gmac_ops *data;
158027ffefd2SJoachim Eastwood 	int ret;
158127ffefd2SJoachim Eastwood 
1582149adeddSJoachim Eastwood 	data = of_device_get_match_data(&pdev->dev);
1583149adeddSJoachim Eastwood 	if (!data) {
1584149adeddSJoachim Eastwood 		dev_err(&pdev->dev, "no of match data provided\n");
1585149adeddSJoachim Eastwood 		return -EINVAL;
1586149adeddSJoachim Eastwood 	}
1587149adeddSJoachim Eastwood 
158827ffefd2SJoachim Eastwood 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
158927ffefd2SJoachim Eastwood 	if (ret)
159027ffefd2SJoachim Eastwood 		return ret;
159127ffefd2SJoachim Eastwood 
159283216e39SMichael Walle 	plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
159327ffefd2SJoachim Eastwood 	if (IS_ERR(plat_dat))
159427ffefd2SJoachim Eastwood 		return PTR_ERR(plat_dat);
159527ffefd2SJoachim Eastwood 
1596d6b06251SEzequiel Garcia 	/* If the stmmac is not already selected as gmac4,
1597d6b06251SEzequiel Garcia 	 * then make sure we fallback to gmac.
1598d6b06251SEzequiel Garcia 	 */
1599d6b06251SEzequiel Garcia 	if (!plat_dat->has_gmac4)
160027ffefd2SJoachim Eastwood 		plat_dat->has_gmac = true;
160127ffefd2SJoachim Eastwood 	plat_dat->fix_mac_speed = rk_fix_speed;
160227ffefd2SJoachim Eastwood 
1603fecd4d7eSDavid Wu 	plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
1604d2ed0a77SJohan Hovold 	if (IS_ERR(plat_dat->bsp_priv)) {
1605d2ed0a77SJohan Hovold 		ret = PTR_ERR(plat_dat->bsp_priv);
1606d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
1607d2ed0a77SJohan Hovold 	}
160827ffefd2SJoachim Eastwood 
1609fecd4d7eSDavid Wu 	ret = rk_gmac_clk_init(plat_dat);
1610fecd4d7eSDavid Wu 	if (ret)
16119de9aa48SEmil Renner Berthing 		goto err_remove_config_dt;
1612fecd4d7eSDavid Wu 
161307a5e769SJoachim Eastwood 	ret = rk_gmac_powerup(plat_dat->bsp_priv);
161427ffefd2SJoachim Eastwood 	if (ret)
1615d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
161627ffefd2SJoachim Eastwood 
16172d222656SJohan Hovold 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
16182d222656SJohan Hovold 	if (ret)
16192745529aSDavid S. Miller 		goto err_gmac_powerdown;
16202d222656SJohan Hovold 
16212d222656SJohan Hovold 	return 0;
16222d222656SJohan Hovold 
16232745529aSDavid S. Miller err_gmac_powerdown:
16242745529aSDavid S. Miller 	rk_gmac_powerdown(plat_dat->bsp_priv);
1625d2ed0a77SJohan Hovold err_remove_config_dt:
1626d2ed0a77SJohan Hovold 	stmmac_remove_config_dt(pdev, plat_dat);
16272d222656SJohan Hovold 
16282d222656SJohan Hovold 	return ret;
162927ffefd2SJoachim Eastwood }
163027ffefd2SJoachim Eastwood 
16310de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev)
16320de8c4c9SJoachim Eastwood {
16330de8c4c9SJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
16340de8c4c9SJoachim Eastwood 	int ret = stmmac_dvr_remove(&pdev->dev);
16350de8c4c9SJoachim Eastwood 
16360de8c4c9SJoachim Eastwood 	rk_gmac_powerdown(bsp_priv);
16370de8c4c9SJoachim Eastwood 
16380de8c4c9SJoachim Eastwood 	return ret;
16390de8c4c9SJoachim Eastwood }
16400de8c4c9SJoachim Eastwood 
16415619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP
16425619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev)
16435619468aSJoachim Eastwood {
16445619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
16455619468aSJoachim Eastwood 	int ret = stmmac_suspend(dev);
16465619468aSJoachim Eastwood 
16475619468aSJoachim Eastwood 	/* Keep the PHY up if we use Wake-on-Lan. */
16485619468aSJoachim Eastwood 	if (!device_may_wakeup(dev)) {
16495619468aSJoachim Eastwood 		rk_gmac_powerdown(bsp_priv);
16505619468aSJoachim Eastwood 		bsp_priv->suspended = true;
16515619468aSJoachim Eastwood 	}
16525619468aSJoachim Eastwood 
16535619468aSJoachim Eastwood 	return ret;
16545619468aSJoachim Eastwood }
16555619468aSJoachim Eastwood 
16565619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev)
16575619468aSJoachim Eastwood {
16585619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
16595619468aSJoachim Eastwood 
16605619468aSJoachim Eastwood 	/* The PHY was up for Wake-on-Lan. */
16615619468aSJoachim Eastwood 	if (bsp_priv->suspended) {
16625619468aSJoachim Eastwood 		rk_gmac_powerup(bsp_priv);
16635619468aSJoachim Eastwood 		bsp_priv->suspended = false;
16645619468aSJoachim Eastwood 	}
16655619468aSJoachim Eastwood 
16665619468aSJoachim Eastwood 	return stmmac_resume(dev);
16675619468aSJoachim Eastwood }
16685619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */
16695619468aSJoachim Eastwood 
16705619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
16715619468aSJoachim Eastwood 
1672e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = {
167323c94d63SDavid Wu 	{ .compatible = "rockchip,px30-gmac",	.data = &px30_ops   },
167405946876SDavid Wu 	{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
1675e7ffd812SXing Zheng 	{ .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
1676f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
1677b4ac9456STobias Schramm 	{ .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops },
1678d4ff816eSdavid.wu 	{ .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
1679ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
1680f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
1681ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
16823bb3d6b1SDavid Wu 	{ .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
168389c9c163SDavid Wu 	{ .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
1684e0fb4013SJoachim Eastwood 	{ }
1685e0fb4013SJoachim Eastwood };
1686e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
1687e0fb4013SJoachim Eastwood 
1688e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = {
168927ffefd2SJoachim Eastwood 	.probe  = rk_gmac_probe,
16900de8c4c9SJoachim Eastwood 	.remove = rk_gmac_remove,
1691e0fb4013SJoachim Eastwood 	.driver = {
1692e0fb4013SJoachim Eastwood 		.name           = "rk_gmac-dwmac",
16935619468aSJoachim Eastwood 		.pm		= &rk_gmac_pm_ops,
1694e0fb4013SJoachim Eastwood 		.of_match_table = rk_gmac_dwmac_match,
1695e0fb4013SJoachim Eastwood 	},
1696e0fb4013SJoachim Eastwood };
1697e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver);
1698e0fb4013SJoachim Eastwood 
1699e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
1700e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
1701e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL");
1702