1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
27ad269eaSRoger Chen /**
37ad269eaSRoger Chen  * dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
47ad269eaSRoger Chen  *
57ad269eaSRoger Chen  * Copyright (C) 2014 Chen-Zhi (Roger Chen)
67ad269eaSRoger Chen  *
77ad269eaSRoger Chen  * Chen-Zhi (Roger Chen)  <roger.chen@rock-chips.com>
87ad269eaSRoger Chen  */
97ad269eaSRoger Chen 
107ad269eaSRoger Chen #include <linux/stmmac.h>
117ad269eaSRoger Chen #include <linux/bitops.h>
127ad269eaSRoger Chen #include <linux/clk.h>
137ad269eaSRoger Chen #include <linux/phy.h>
147ad269eaSRoger Chen #include <linux/of_net.h>
157ad269eaSRoger Chen #include <linux/gpio.h>
16e0fb4013SJoachim Eastwood #include <linux/module.h>
177ad269eaSRoger Chen #include <linux/of_gpio.h>
187ad269eaSRoger Chen #include <linux/of_device.h>
19e0fb4013SJoachim Eastwood #include <linux/platform_device.h>
207ad269eaSRoger Chen #include <linux/regulator/consumer.h>
217ad269eaSRoger Chen #include <linux/delay.h>
227ad269eaSRoger Chen #include <linux/mfd/syscon.h>
237ad269eaSRoger Chen #include <linux/regmap.h>
242c896fb0SDavid Wu #include <linux/pm_runtime.h>
257ad269eaSRoger Chen 
26e0fb4013SJoachim Eastwood #include "stmmac_platform.h"
27e0fb4013SJoachim Eastwood 
280fb98db1SHeiko Stübner struct rk_priv_data;
290fb98db1SHeiko Stübner struct rk_gmac_ops {
300fb98db1SHeiko Stübner 	void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
310fb98db1SHeiko Stübner 			     int tx_delay, int rx_delay);
320fb98db1SHeiko Stübner 	void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
330fb98db1SHeiko Stübner 	void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
340fb98db1SHeiko Stübner 	void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
35fecd4d7eSDavid Wu 	void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
360fb98db1SHeiko Stübner };
370fb98db1SHeiko Stübner 
387ad269eaSRoger Chen struct rk_priv_data {
397ad269eaSRoger Chen 	struct platform_device *pdev;
400c65b2b9SAndrew Lunn 	phy_interface_t phy_iface;
412e12f536SRomain Perier 	struct regulator *regulator;
42229666c1SVincent Palatin 	bool suspended;
4392c2588fSJoachim Eastwood 	const struct rk_gmac_ops *ops;
447ad269eaSRoger Chen 
457ad269eaSRoger Chen 	bool clk_enabled;
467ad269eaSRoger Chen 	bool clock_input;
47fecd4d7eSDavid Wu 	bool integrated_phy;
487ad269eaSRoger Chen 
497ad269eaSRoger Chen 	struct clk *clk_mac;
507ad269eaSRoger Chen 	struct clk *gmac_clkin;
517ad269eaSRoger Chen 	struct clk *mac_clk_rx;
527ad269eaSRoger Chen 	struct clk *mac_clk_tx;
537ad269eaSRoger Chen 	struct clk *clk_mac_ref;
547ad269eaSRoger Chen 	struct clk *clk_mac_refout;
5523c94d63SDavid Wu 	struct clk *clk_mac_speed;
567ad269eaSRoger Chen 	struct clk *aclk_mac;
577ad269eaSRoger Chen 	struct clk *pclk_mac;
58fecd4d7eSDavid Wu 	struct clk *clk_phy;
59fecd4d7eSDavid Wu 
60fecd4d7eSDavid Wu 	struct reset_control *phy_reset;
617ad269eaSRoger Chen 
627ad269eaSRoger Chen 	int tx_delay;
637ad269eaSRoger Chen 	int rx_delay;
647ad269eaSRoger Chen 
657ad269eaSRoger Chen 	struct regmap *grf;
667ad269eaSRoger Chen };
677ad269eaSRoger Chen 
687ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \
697ad269eaSRoger Chen 		((val) << (shift) | (mask) << ((shift) + 16))
707ad269eaSRoger Chen 
717ad269eaSRoger Chen #define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
727ad269eaSRoger Chen #define GRF_CLR_BIT(nr)	(BIT(nr+16))
737ad269eaSRoger Chen 
74eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \
75eaf70ad1SWadim Egorov 	(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
76eaf70ad1SWadim Egorov 	 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
77eaf70ad1SWadim Egorov 
7823c94d63SDavid Wu #define PX30_GRF_GMAC_CON1		0x0904
7923c94d63SDavid Wu 
8023c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */
8123c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
8223c94d63SDavid Wu 					 GRF_BIT(6))
8323c94d63SDavid Wu #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
8423c94d63SDavid Wu #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
8523c94d63SDavid Wu 
8623c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
8723c94d63SDavid Wu {
8823c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
8923c94d63SDavid Wu 
9023c94d63SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
9123c94d63SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
9223c94d63SDavid Wu 		return;
9323c94d63SDavid Wu 	}
9423c94d63SDavid Wu 
9523c94d63SDavid Wu 	regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
9623c94d63SDavid Wu 		     PX30_GMAC_PHY_INTF_SEL_RMII);
9723c94d63SDavid Wu }
9823c94d63SDavid Wu 
9923c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
10023c94d63SDavid Wu {
10123c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10223c94d63SDavid Wu 	int ret;
10323c94d63SDavid Wu 
10423c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed)) {
10523c94d63SDavid Wu 		dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
10623c94d63SDavid Wu 		return;
10723c94d63SDavid Wu 	}
10823c94d63SDavid Wu 
10923c94d63SDavid Wu 	if (speed == 10) {
11023c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
11123c94d63SDavid Wu 			     PX30_GMAC_SPEED_10M);
11223c94d63SDavid Wu 
11323c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
11423c94d63SDavid Wu 		if (ret)
11523c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n",
11623c94d63SDavid Wu 				__func__, ret);
11723c94d63SDavid Wu 	} else if (speed == 100) {
11823c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
11923c94d63SDavid Wu 			     PX30_GMAC_SPEED_100M);
12023c94d63SDavid Wu 
12123c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
12223c94d63SDavid Wu 		if (ret)
12323c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n",
12423c94d63SDavid Wu 				__func__, ret);
12523c94d63SDavid Wu 
12623c94d63SDavid Wu 	} else {
12723c94d63SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
12823c94d63SDavid Wu 	}
12923c94d63SDavid Wu }
13023c94d63SDavid Wu 
13123c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = {
13223c94d63SDavid Wu 	.set_to_rmii = px30_set_to_rmii,
13323c94d63SDavid Wu 	.set_rmii_speed = px30_set_rmii_speed,
13423c94d63SDavid Wu };
13523c94d63SDavid Wu 
13605946876SDavid Wu #define RK3128_GRF_MAC_CON0	0x0168
13705946876SDavid Wu #define RK3128_GRF_MAC_CON1	0x016c
13805946876SDavid Wu 
13905946876SDavid Wu /* RK3128_GRF_MAC_CON0 */
14005946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE   GRF_BIT(14)
14105946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(14)
14205946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(15)
14305946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(15)
14405946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
14505946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
14605946876SDavid Wu 
14705946876SDavid Wu /* RK3128_GRF_MAC_CON1 */
14805946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII	\
14905946876SDavid Wu 		(GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
15005946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII	\
15105946876SDavid Wu 		(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
15205946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
15305946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
15405946876SDavid Wu #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
15505946876SDavid Wu #define RK3128_GMAC_SPEED_100M         GRF_BIT(10)
15605946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M       GRF_BIT(11)
15705946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M      GRF_CLR_BIT(11)
15805946876SDavid Wu #define RK3128_GMAC_CLK_125M           (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
15905946876SDavid Wu #define RK3128_GMAC_CLK_25M            (GRF_BIT(12) | GRF_BIT(13))
16005946876SDavid Wu #define RK3128_GMAC_CLK_2_5M           (GRF_CLR_BIT(12) | GRF_BIT(13))
16105946876SDavid Wu #define RK3128_GMAC_RMII_MODE          GRF_BIT(14)
16205946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR      GRF_CLR_BIT(14)
16305946876SDavid Wu 
16405946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
16505946876SDavid Wu 				int tx_delay, int rx_delay)
16605946876SDavid Wu {
16705946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
16805946876SDavid Wu 
16905946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
17005946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
17105946876SDavid Wu 		return;
17205946876SDavid Wu 	}
17305946876SDavid Wu 
17405946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
17505946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RGMII |
17605946876SDavid Wu 		     RK3128_GMAC_RMII_MODE_CLR);
17705946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
17805946876SDavid Wu 		     DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
17905946876SDavid Wu 		     RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
18005946876SDavid Wu 		     RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
18105946876SDavid Wu }
18205946876SDavid Wu 
18305946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
18405946876SDavid Wu {
18505946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
18605946876SDavid Wu 
18705946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
18805946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
18905946876SDavid Wu 		return;
19005946876SDavid Wu 	}
19105946876SDavid Wu 
19205946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
19305946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
19405946876SDavid Wu }
19505946876SDavid Wu 
19605946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
19705946876SDavid Wu {
19805946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
19905946876SDavid Wu 
20005946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
20105946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
20205946876SDavid Wu 		return;
20305946876SDavid Wu 	}
20405946876SDavid Wu 
20505946876SDavid Wu 	if (speed == 10)
20605946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
20705946876SDavid Wu 			     RK3128_GMAC_CLK_2_5M);
20805946876SDavid Wu 	else if (speed == 100)
20905946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21005946876SDavid Wu 			     RK3128_GMAC_CLK_25M);
21105946876SDavid Wu 	else if (speed == 1000)
21205946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21305946876SDavid Wu 			     RK3128_GMAC_CLK_125M);
21405946876SDavid Wu 	else
21505946876SDavid Wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
21605946876SDavid Wu }
21705946876SDavid Wu 
21805946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
21905946876SDavid Wu {
22005946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
22105946876SDavid Wu 
22205946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
22305946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
22405946876SDavid Wu 		return;
22505946876SDavid Wu 	}
22605946876SDavid Wu 
22705946876SDavid Wu 	if (speed == 10) {
22805946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
22905946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_2_5M |
23005946876SDavid Wu 			     RK3128_GMAC_SPEED_10M);
23105946876SDavid Wu 	} else if (speed == 100) {
23205946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23305946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_25M |
23405946876SDavid Wu 			     RK3128_GMAC_SPEED_100M);
23505946876SDavid Wu 	} else {
23605946876SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
23705946876SDavid Wu 	}
23805946876SDavid Wu }
23905946876SDavid Wu 
24005946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = {
24105946876SDavid Wu 	.set_to_rgmii = rk3128_set_to_rgmii,
24205946876SDavid Wu 	.set_to_rmii = rk3128_set_to_rmii,
24305946876SDavid Wu 	.set_rgmii_speed = rk3128_set_rgmii_speed,
24405946876SDavid Wu 	.set_rmii_speed = rk3128_set_rmii_speed,
24505946876SDavid Wu };
24605946876SDavid Wu 
247e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0	0x0900
248e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1	0x0904
249e7ffd812SXing Zheng 
2506fa12c78SDavid Wu #define RK3228_GRF_CON_MUX	0x50
2516fa12c78SDavid Wu 
252e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */
253e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
254e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
255e7ffd812SXing Zheng 
256e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */
257e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII	\
258e7ffd812SXing Zheng 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
259e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII	\
260e7ffd812SXing Zheng 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
261e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
262e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
263e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
264e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M		GRF_BIT(2)
265e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M	GRF_BIT(7)
266e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
267e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M		(GRF_CLR_BIT(8) | GRF_CLR_BIT(9))
268e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M		(GRF_BIT(8) | GRF_BIT(9))
269e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M		(GRF_CLR_BIT(8) | GRF_BIT(9))
270e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE		GRF_BIT(10)
271e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(10)
272e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
273e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
274e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
275e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
276e7ffd812SXing Zheng 
2776fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */
2786fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY	GRF_BIT(15)
2796fa12c78SDavid Wu 
280e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
281e7ffd812SXing Zheng 				int tx_delay, int rx_delay)
282e7ffd812SXing Zheng {
283e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
284e7ffd812SXing Zheng 
285e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
286e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
287e7ffd812SXing Zheng 		return;
288e7ffd812SXing Zheng 	}
289e7ffd812SXing Zheng 
290e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
291e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RGMII |
292e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE_CLR |
293eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3228, tx_delay, rx_delay));
294e7ffd812SXing Zheng 
295e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
296e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
297e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
298e7ffd812SXing Zheng }
299e7ffd812SXing Zheng 
300e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
301e7ffd812SXing Zheng {
302e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
303e7ffd812SXing Zheng 
304e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
305e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
306e7ffd812SXing Zheng 		return;
307e7ffd812SXing Zheng 	}
308e7ffd812SXing Zheng 
309e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
310e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RMII |
311e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE);
312e7ffd812SXing Zheng 
313e7ffd812SXing Zheng 	/* set MAC to RMII mode */
314e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11));
315e7ffd812SXing Zheng }
316e7ffd812SXing Zheng 
317e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
318e7ffd812SXing Zheng {
319e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
320e7ffd812SXing Zheng 
321e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
322e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
323e7ffd812SXing Zheng 		return;
324e7ffd812SXing Zheng 	}
325e7ffd812SXing Zheng 
326e7ffd812SXing Zheng 	if (speed == 10)
327e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
328e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_2_5M);
329e7ffd812SXing Zheng 	else if (speed == 100)
330e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
331e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_25M);
332e7ffd812SXing Zheng 	else if (speed == 1000)
333e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
334e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_125M);
335e7ffd812SXing Zheng 	else
336e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
337e7ffd812SXing Zheng }
338e7ffd812SXing Zheng 
339e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
340e7ffd812SXing Zheng {
341e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
342e7ffd812SXing Zheng 
343e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
344e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
345e7ffd812SXing Zheng 		return;
346e7ffd812SXing Zheng 	}
347e7ffd812SXing Zheng 
348e7ffd812SXing Zheng 	if (speed == 10)
349e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
350e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_2_5M |
351e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_10M);
352e7ffd812SXing Zheng 	else if (speed == 100)
353e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
354e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_25M |
355e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_100M);
356e7ffd812SXing Zheng 	else
357e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
358e7ffd812SXing Zheng }
359e7ffd812SXing Zheng 
3606fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
3616fa12c78SDavid Wu {
3626fa12c78SDavid Wu 	regmap_write(priv->grf, RK3228_GRF_CON_MUX,
3636fa12c78SDavid Wu 		     RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
3646fa12c78SDavid Wu }
3656fa12c78SDavid Wu 
366e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = {
367e7ffd812SXing Zheng 	.set_to_rgmii = rk3228_set_to_rgmii,
368e7ffd812SXing Zheng 	.set_to_rmii = rk3228_set_to_rmii,
369e7ffd812SXing Zheng 	.set_rgmii_speed = rk3228_set_rgmii_speed,
370e7ffd812SXing Zheng 	.set_rmii_speed = rk3228_set_rmii_speed,
3716fa12c78SDavid Wu 	.integrated_phy_powerup =  rk3228_integrated_phy_powerup,
372e7ffd812SXing Zheng };
373e7ffd812SXing Zheng 
3747ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1	0x0248
3757ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3	0x0250
3767ad269eaSRoger Chen 
3777ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/
3780fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | \
3790fb98db1SHeiko Stübner 					 GRF_CLR_BIT(8))
3800fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
3810fb98db1SHeiko Stübner 					 GRF_BIT(8))
3820fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
3830fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
3840fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
3850fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M		GRF_BIT(10)
3860fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M	GRF_BIT(11)
3870fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
3880fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
3890fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
3900fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
3910fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE		GRF_BIT(14)
3920fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
3937ad269eaSRoger Chen 
3947ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/
3950fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
3960fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
3970fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
3980fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
3990fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
4000fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
4017ad269eaSRoger Chen 
4020fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
4037ad269eaSRoger Chen 				int tx_delay, int rx_delay)
4047ad269eaSRoger Chen {
4057ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4067ad269eaSRoger Chen 
4077ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
408d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4097ad269eaSRoger Chen 		return;
4107ad269eaSRoger Chen 	}
4117ad269eaSRoger Chen 
4127ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4130fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
4140fb98db1SHeiko Stübner 		     RK3288_GMAC_RMII_MODE_CLR);
4157ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
416eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
4170fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
4180fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
4197ad269eaSRoger Chen }
4207ad269eaSRoger Chen 
4210fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
4227ad269eaSRoger Chen {
4237ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4247ad269eaSRoger Chen 
4257ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
426d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4277ad269eaSRoger Chen 		return;
4287ad269eaSRoger Chen 	}
4297ad269eaSRoger Chen 
4307ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4310fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
4327ad269eaSRoger Chen }
4337ad269eaSRoger Chen 
4340fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
4357ad269eaSRoger Chen {
4367ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4377ad269eaSRoger Chen 
4387ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
439d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4407ad269eaSRoger Chen 		return;
4417ad269eaSRoger Chen 	}
4427ad269eaSRoger Chen 
4437ad269eaSRoger Chen 	if (speed == 10)
4440fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4450fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_2_5M);
4467ad269eaSRoger Chen 	else if (speed == 100)
4470fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4480fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_25M);
4497ad269eaSRoger Chen 	else if (speed == 1000)
4500fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4510fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_125M);
4527ad269eaSRoger Chen 	else
4537ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
4547ad269eaSRoger Chen }
4557ad269eaSRoger Chen 
4560fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
4577ad269eaSRoger Chen {
4587ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4597ad269eaSRoger Chen 
4607ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
461d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4627ad269eaSRoger Chen 		return;
4637ad269eaSRoger Chen 	}
4647ad269eaSRoger Chen 
4657ad269eaSRoger Chen 	if (speed == 10) {
4667ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4670fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_2_5M |
4680fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_10M);
4697ad269eaSRoger Chen 	} else if (speed == 100) {
4707ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4710fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_25M |
4720fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_100M);
4737ad269eaSRoger Chen 	} else {
4747ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
4757ad269eaSRoger Chen 	}
4767ad269eaSRoger Chen }
4777ad269eaSRoger Chen 
47892c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = {
4790fb98db1SHeiko Stübner 	.set_to_rgmii = rk3288_set_to_rgmii,
4800fb98db1SHeiko Stübner 	.set_to_rmii = rk3288_set_to_rmii,
4810fb98db1SHeiko Stübner 	.set_rgmii_speed = rk3288_set_rgmii_speed,
4820fb98db1SHeiko Stübner 	.set_rmii_speed = rk3288_set_rmii_speed,
4830fb98db1SHeiko Stübner };
4840fb98db1SHeiko Stübner 
485d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0	0x0900
486d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1	0x0904
4878bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2	0x0908
4888bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1	0xb04
489d4ff816eSdavid.wu 
490d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */
491d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
492d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
493d4ff816eSdavid.wu 
494d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */
495d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII	\
496d4ff816eSdavid.wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
497d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII	\
498d4ff816eSdavid.wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
499d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
500d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
501d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
502d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M		GRF_BIT(2)
503d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M	GRF_BIT(7)
504d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
505d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M		(GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
506d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M		(GRF_BIT(11) | GRF_BIT(12))
507d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M		(GRF_CLR_BIT(11) | GRF_BIT(12))
508d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE		GRF_BIT(9)
509d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(9)
510d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
511d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
512d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
513d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
514d4ff816eSdavid.wu 
5158bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */
5168bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE		GRF_BIT(9)
5178bdf63bdSDavid Wu 
518d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
519d4ff816eSdavid.wu 				int tx_delay, int rx_delay)
520d4ff816eSdavid.wu {
521d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
522d4ff816eSdavid.wu 
523d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
524d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
525d4ff816eSdavid.wu 		return;
526d4ff816eSdavid.wu 	}
527d4ff816eSdavid.wu 
528d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
529d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
530d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE_CLR |
531d4ff816eSdavid.wu 		     RK3328_GMAC_RXCLK_DLY_ENABLE |
532d4ff816eSdavid.wu 		     RK3328_GMAC_TXCLK_DLY_ENABLE);
533d4ff816eSdavid.wu 
534d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
535d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
536d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
537d4ff816eSdavid.wu }
538d4ff816eSdavid.wu 
539d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
540d4ff816eSdavid.wu {
541d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
5428bdf63bdSDavid Wu 	unsigned int reg;
543d4ff816eSdavid.wu 
544d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
545d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
546d4ff816eSdavid.wu 		return;
547d4ff816eSdavid.wu 	}
548d4ff816eSdavid.wu 
5498bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
5508bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
5518bdf63bdSDavid Wu 
5528bdf63bdSDavid Wu 	regmap_write(bsp_priv->grf, reg,
553d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RMII |
554d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE);
555d4ff816eSdavid.wu }
556d4ff816eSdavid.wu 
557d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
558d4ff816eSdavid.wu {
559d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
560d4ff816eSdavid.wu 
561d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
562d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
563d4ff816eSdavid.wu 		return;
564d4ff816eSdavid.wu 	}
565d4ff816eSdavid.wu 
566d4ff816eSdavid.wu 	if (speed == 10)
567d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
568d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_2_5M);
569d4ff816eSdavid.wu 	else if (speed == 100)
570d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
571d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_25M);
572d4ff816eSdavid.wu 	else if (speed == 1000)
573d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
574d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_125M);
575d4ff816eSdavid.wu 	else
576d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
577d4ff816eSdavid.wu }
578d4ff816eSdavid.wu 
579d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
580d4ff816eSdavid.wu {
581d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
5828bdf63bdSDavid Wu 	unsigned int reg;
583d4ff816eSdavid.wu 
584d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
585d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
586d4ff816eSdavid.wu 		return;
587d4ff816eSdavid.wu 	}
588d4ff816eSdavid.wu 
5898bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
5908bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
5918bdf63bdSDavid Wu 
592d4ff816eSdavid.wu 	if (speed == 10)
5938bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
594d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_2_5M |
595d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_10M);
596d4ff816eSdavid.wu 	else if (speed == 100)
5978bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
598d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_25M |
599d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_100M);
600d4ff816eSdavid.wu 	else
601d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
602d4ff816eSdavid.wu }
603d4ff816eSdavid.wu 
6048bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
6058bdf63bdSDavid Wu {
6068bdf63bdSDavid Wu 	regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
6078bdf63bdSDavid Wu 		     RK3328_MACPHY_RMII_MODE);
6088bdf63bdSDavid Wu }
6098bdf63bdSDavid Wu 
610d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = {
611d4ff816eSdavid.wu 	.set_to_rgmii = rk3328_set_to_rgmii,
612d4ff816eSdavid.wu 	.set_to_rmii = rk3328_set_to_rmii,
613d4ff816eSdavid.wu 	.set_rgmii_speed = rk3328_set_rgmii_speed,
614d4ff816eSdavid.wu 	.set_rmii_speed = rk3328_set_rmii_speed,
6158bdf63bdSDavid Wu 	.integrated_phy_powerup =  rk3328_integrated_phy_powerup,
616d4ff816eSdavid.wu };
617d4ff816eSdavid.wu 
618ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6	0x0418
619ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7	0x041c
620ba289af8SRoger Chen 
621ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */
622ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
623ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
624ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
625ba289af8SRoger Chen 					 GRF_BIT(11))
626ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
627ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
628ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
629ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M		GRF_BIT(7)
630ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M	GRF_BIT(3)
631ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
632ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
633ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
634ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
635ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE		GRF_BIT(6)
636ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
637ba289af8SRoger Chen 
638ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */
639ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
640ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
641ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
642ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
643ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
644ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
645ba289af8SRoger Chen 
646ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
647ba289af8SRoger Chen 				int tx_delay, int rx_delay)
648ba289af8SRoger Chen {
649ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
650ba289af8SRoger Chen 
651ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
652ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
653ba289af8SRoger Chen 		return;
654ba289af8SRoger Chen 	}
655ba289af8SRoger Chen 
656ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
657ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RGMII |
658ba289af8SRoger Chen 		     RK3366_GMAC_RMII_MODE_CLR);
659ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
660eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
661ba289af8SRoger Chen 		     RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
662ba289af8SRoger Chen 		     RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
663ba289af8SRoger Chen }
664ba289af8SRoger Chen 
665ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
666ba289af8SRoger Chen {
667ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
668ba289af8SRoger Chen 
669ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
670ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
671ba289af8SRoger Chen 		return;
672ba289af8SRoger Chen 	}
673ba289af8SRoger Chen 
674ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
675ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
676ba289af8SRoger Chen }
677ba289af8SRoger Chen 
678ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
679ba289af8SRoger Chen {
680ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
681ba289af8SRoger Chen 
682ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
683ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
684ba289af8SRoger Chen 		return;
685ba289af8SRoger Chen 	}
686ba289af8SRoger Chen 
687ba289af8SRoger Chen 	if (speed == 10)
688ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
689ba289af8SRoger Chen 			     RK3366_GMAC_CLK_2_5M);
690ba289af8SRoger Chen 	else if (speed == 100)
691ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
692ba289af8SRoger Chen 			     RK3366_GMAC_CLK_25M);
693ba289af8SRoger Chen 	else if (speed == 1000)
694ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
695ba289af8SRoger Chen 			     RK3366_GMAC_CLK_125M);
696ba289af8SRoger Chen 	else
697ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
698ba289af8SRoger Chen }
699ba289af8SRoger Chen 
700ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
701ba289af8SRoger Chen {
702ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
703ba289af8SRoger Chen 
704ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
705ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
706ba289af8SRoger Chen 		return;
707ba289af8SRoger Chen 	}
708ba289af8SRoger Chen 
709ba289af8SRoger Chen 	if (speed == 10) {
710ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
711ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_2_5M |
712ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_10M);
713ba289af8SRoger Chen 	} else if (speed == 100) {
714ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
715ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_25M |
716ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_100M);
717ba289af8SRoger Chen 	} else {
718ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
719ba289af8SRoger Chen 	}
720ba289af8SRoger Chen }
721ba289af8SRoger Chen 
722ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = {
723ba289af8SRoger Chen 	.set_to_rgmii = rk3366_set_to_rgmii,
724ba289af8SRoger Chen 	.set_to_rmii = rk3366_set_to_rmii,
725ba289af8SRoger Chen 	.set_rgmii_speed = rk3366_set_rgmii_speed,
726ba289af8SRoger Chen 	.set_rmii_speed = rk3366_set_rmii_speed,
727ba289af8SRoger Chen };
728ba289af8SRoger Chen 
729df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15	0x043c
730df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16	0x0440
731df558854SHeiko Stübner 
732df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */
733df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
734df558854SHeiko Stübner 					 GRF_CLR_BIT(11))
735df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
736df558854SHeiko Stübner 					 GRF_BIT(11))
737df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
738df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
739df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
740df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M		GRF_BIT(7)
741df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M	GRF_BIT(3)
742df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
743df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
744df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
745df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
746df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE		GRF_BIT(6)
747df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
748df558854SHeiko Stübner 
749df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */
750df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
751df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
752df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
753df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
754df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
755df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
756df558854SHeiko Stübner 
757df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
758df558854SHeiko Stübner 				int tx_delay, int rx_delay)
759df558854SHeiko Stübner {
760df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
761df558854SHeiko Stübner 
762df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
763df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
764df558854SHeiko Stübner 		return;
765df558854SHeiko Stübner 	}
766df558854SHeiko Stübner 
767df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
768df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
769df558854SHeiko Stübner 		     RK3368_GMAC_RMII_MODE_CLR);
770df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
771eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
772df558854SHeiko Stübner 		     RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
773df558854SHeiko Stübner 		     RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
774df558854SHeiko Stübner }
775df558854SHeiko Stübner 
776df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
777df558854SHeiko Stübner {
778df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
779df558854SHeiko Stübner 
780df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
781df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
782df558854SHeiko Stübner 		return;
783df558854SHeiko Stübner 	}
784df558854SHeiko Stübner 
785df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
786df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
787df558854SHeiko Stübner }
788df558854SHeiko Stübner 
789df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
790df558854SHeiko Stübner {
791df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
792df558854SHeiko Stübner 
793df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
794df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
795df558854SHeiko Stübner 		return;
796df558854SHeiko Stübner 	}
797df558854SHeiko Stübner 
798df558854SHeiko Stübner 	if (speed == 10)
799df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
800df558854SHeiko Stübner 			     RK3368_GMAC_CLK_2_5M);
801df558854SHeiko Stübner 	else if (speed == 100)
802df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
803df558854SHeiko Stübner 			     RK3368_GMAC_CLK_25M);
804df558854SHeiko Stübner 	else if (speed == 1000)
805df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
806df558854SHeiko Stübner 			     RK3368_GMAC_CLK_125M);
807df558854SHeiko Stübner 	else
808df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
809df558854SHeiko Stübner }
810df558854SHeiko Stübner 
811df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
812df558854SHeiko Stübner {
813df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
814df558854SHeiko Stübner 
815df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
816df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
817df558854SHeiko Stübner 		return;
818df558854SHeiko Stübner 	}
819df558854SHeiko Stübner 
820df558854SHeiko Stübner 	if (speed == 10) {
821df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
822df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_2_5M |
823df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_10M);
824df558854SHeiko Stübner 	} else if (speed == 100) {
825df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
826df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_25M |
827df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_100M);
828df558854SHeiko Stübner 	} else {
829df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
830df558854SHeiko Stübner 	}
831df558854SHeiko Stübner }
832df558854SHeiko Stübner 
83392c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = {
834df558854SHeiko Stübner 	.set_to_rgmii = rk3368_set_to_rgmii,
835df558854SHeiko Stübner 	.set_to_rmii = rk3368_set_to_rmii,
836df558854SHeiko Stübner 	.set_rgmii_speed = rk3368_set_rgmii_speed,
837df558854SHeiko Stübner 	.set_rmii_speed = rk3368_set_rmii_speed,
838df558854SHeiko Stübner };
839df558854SHeiko Stübner 
840ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5	0xc214
841ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6	0xc218
842ba289af8SRoger Chen 
843ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */
844ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
845ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
846ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
847ba289af8SRoger Chen 					 GRF_BIT(11))
848ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
849ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
850ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
851ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M		GRF_BIT(7)
852ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M	GRF_BIT(3)
853ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
854ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
855ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
856ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
857ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE		GRF_BIT(6)
858ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
859ba289af8SRoger Chen 
860ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */
861ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
862ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
863ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
864ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
865ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
866ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
867ba289af8SRoger Chen 
868ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
869ba289af8SRoger Chen 				int tx_delay, int rx_delay)
870ba289af8SRoger Chen {
871ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
872ba289af8SRoger Chen 
873ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
874ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
875ba289af8SRoger Chen 		return;
876ba289af8SRoger Chen 	}
877ba289af8SRoger Chen 
878ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
879ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RGMII |
880ba289af8SRoger Chen 		     RK3399_GMAC_RMII_MODE_CLR);
881ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
882eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
883ba289af8SRoger Chen 		     RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
884ba289af8SRoger Chen 		     RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
885ba289af8SRoger Chen }
886ba289af8SRoger Chen 
887ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
888ba289af8SRoger Chen {
889ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
890ba289af8SRoger Chen 
891ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
892ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
893ba289af8SRoger Chen 		return;
894ba289af8SRoger Chen 	}
895ba289af8SRoger Chen 
896ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
897ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
898ba289af8SRoger Chen }
899ba289af8SRoger Chen 
900ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
901ba289af8SRoger Chen {
902ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
903ba289af8SRoger Chen 
904ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
905ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
906ba289af8SRoger Chen 		return;
907ba289af8SRoger Chen 	}
908ba289af8SRoger Chen 
909ba289af8SRoger Chen 	if (speed == 10)
910ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
911ba289af8SRoger Chen 			     RK3399_GMAC_CLK_2_5M);
912ba289af8SRoger Chen 	else if (speed == 100)
913ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
914ba289af8SRoger Chen 			     RK3399_GMAC_CLK_25M);
915ba289af8SRoger Chen 	else if (speed == 1000)
916ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
917ba289af8SRoger Chen 			     RK3399_GMAC_CLK_125M);
918ba289af8SRoger Chen 	else
919ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
920ba289af8SRoger Chen }
921ba289af8SRoger Chen 
922ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
923ba289af8SRoger Chen {
924ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
925ba289af8SRoger Chen 
926ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
927ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
928ba289af8SRoger Chen 		return;
929ba289af8SRoger Chen 	}
930ba289af8SRoger Chen 
931ba289af8SRoger Chen 	if (speed == 10) {
932ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
933ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_2_5M |
934ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_10M);
935ba289af8SRoger Chen 	} else if (speed == 100) {
936ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
937ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_25M |
938ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_100M);
939ba289af8SRoger Chen 	} else {
940ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
941ba289af8SRoger Chen 	}
942ba289af8SRoger Chen }
943ba289af8SRoger Chen 
944ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = {
945ba289af8SRoger Chen 	.set_to_rgmii = rk3399_set_to_rgmii,
946ba289af8SRoger Chen 	.set_to_rmii = rk3399_set_to_rmii,
947ba289af8SRoger Chen 	.set_rgmii_speed = rk3399_set_rgmii_speed,
948ba289af8SRoger Chen 	.set_rmii_speed = rk3399_set_rmii_speed,
949ba289af8SRoger Chen };
950ba289af8SRoger Chen 
95189c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0		0X0900
95289c9c163SDavid Wu 
95389c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */
95489c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
95589c9c163SDavid Wu 					GRF_BIT(6))
95689c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
95789c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
95889c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
95989c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M		GRF_BIT(2)
96089c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M	GRF_BIT(7)
96189c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
96289c9c163SDavid Wu 
96389c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
96489c9c163SDavid Wu {
96589c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
96689c9c163SDavid Wu 
96789c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
96889c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
96989c9c163SDavid Wu 		return;
97089c9c163SDavid Wu 	}
97189c9c163SDavid Wu 
97289c9c163SDavid Wu 	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
97389c9c163SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
97489c9c163SDavid Wu }
97589c9c163SDavid Wu 
97689c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
97789c9c163SDavid Wu {
97889c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
97989c9c163SDavid Wu 
98089c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
98189c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
98289c9c163SDavid Wu 		return;
98389c9c163SDavid Wu 	}
98489c9c163SDavid Wu 
98589c9c163SDavid Wu 	if (speed == 10) {
98689c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
98789c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_2_5M |
98889c9c163SDavid Wu 			     RV1108_GMAC_SPEED_10M);
98989c9c163SDavid Wu 	} else if (speed == 100) {
99089c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
99189c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_25M |
99289c9c163SDavid Wu 			     RV1108_GMAC_SPEED_100M);
99389c9c163SDavid Wu 	} else {
99489c9c163SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
99589c9c163SDavid Wu 	}
99689c9c163SDavid Wu }
99789c9c163SDavid Wu 
99889c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = {
99989c9c163SDavid Wu 	.set_to_rmii = rv1108_set_to_rmii,
100089c9c163SDavid Wu 	.set_rmii_speed = rv1108_set_rmii_speed,
100189c9c163SDavid Wu };
100289c9c163SDavid Wu 
1003fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0		0xb00
1004fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1		0xb04
1005fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2		0xb08
1006fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3		0xb0c
1007fecd4d7eSDavid Wu 
1008fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE		GRF_BIT(0)
1009fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
1010fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
1011fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
1012fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID		HIWORD_UPDATE(0x1234, 0xffff, 0)
1013fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID		HIWORD_UPDATE(0x35, 0x3f, 0)
1014fecd4d7eSDavid Wu 
1015fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
10167ad269eaSRoger Chen {
1017fecd4d7eSDavid Wu 	if (priv->ops->integrated_phy_powerup)
1018fecd4d7eSDavid Wu 		priv->ops->integrated_phy_powerup(priv);
1019fecd4d7eSDavid Wu 
1020fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
1021fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
1022fecd4d7eSDavid Wu 
1023fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
1024fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
1025fecd4d7eSDavid Wu 
1026fecd4d7eSDavid Wu 	if (priv->phy_reset) {
1027fecd4d7eSDavid Wu 		/* PHY needs to be disabled before trying to reset it */
1028fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1029fecd4d7eSDavid Wu 		if (priv->phy_reset)
1030fecd4d7eSDavid Wu 			reset_control_assert(priv->phy_reset);
1031fecd4d7eSDavid Wu 		usleep_range(10, 20);
1032fecd4d7eSDavid Wu 		if (priv->phy_reset)
1033fecd4d7eSDavid Wu 			reset_control_deassert(priv->phy_reset);
1034fecd4d7eSDavid Wu 		usleep_range(10, 20);
1035fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
1036fecd4d7eSDavid Wu 		msleep(30);
1037fecd4d7eSDavid Wu 	}
1038fecd4d7eSDavid Wu }
1039fecd4d7eSDavid Wu 
1040fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
1041fecd4d7eSDavid Wu {
1042fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1043fecd4d7eSDavid Wu 	if (priv->phy_reset)
1044fecd4d7eSDavid Wu 		reset_control_assert(priv->phy_reset);
1045fecd4d7eSDavid Wu }
1046fecd4d7eSDavid Wu 
1047fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
1048fecd4d7eSDavid Wu {
1049fecd4d7eSDavid Wu 	struct rk_priv_data *bsp_priv = plat->bsp_priv;
10507ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
1051fecd4d7eSDavid Wu 	int ret;
10527ad269eaSRoger Chen 
10537ad269eaSRoger Chen 	bsp_priv->clk_enabled = false;
10547ad269eaSRoger Chen 
10557ad269eaSRoger Chen 	bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
10567ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_rx))
1057d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1058d42202dcSRomain Perier 			"mac_clk_rx");
10597ad269eaSRoger Chen 
10607ad269eaSRoger Chen 	bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
10617ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_tx))
1062d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1063d42202dcSRomain Perier 			"mac_clk_tx");
10647ad269eaSRoger Chen 
10657ad269eaSRoger Chen 	bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
10667ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->aclk_mac))
1067d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1068d42202dcSRomain Perier 			"aclk_mac");
10697ad269eaSRoger Chen 
10707ad269eaSRoger Chen 	bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
10717ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->pclk_mac))
1072d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1073d42202dcSRomain Perier 			"pclk_mac");
10747ad269eaSRoger Chen 
10757ad269eaSRoger Chen 	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
10767ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->clk_mac))
1077d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1078d42202dcSRomain Perier 			"stmmaceth");
10797ad269eaSRoger Chen 
10807ad269eaSRoger Chen 	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
10817ad269eaSRoger Chen 		bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
10827ad269eaSRoger Chen 		if (IS_ERR(bsp_priv->clk_mac_ref))
1083d42202dcSRomain Perier 			dev_err(dev, "cannot get clock %s\n",
1084d42202dcSRomain Perier 				"clk_mac_ref");
10857ad269eaSRoger Chen 
10867ad269eaSRoger Chen 		if (!bsp_priv->clock_input) {
10877ad269eaSRoger Chen 			bsp_priv->clk_mac_refout =
10887ad269eaSRoger Chen 				devm_clk_get(dev, "clk_mac_refout");
10897ad269eaSRoger Chen 			if (IS_ERR(bsp_priv->clk_mac_refout))
1090d42202dcSRomain Perier 				dev_err(dev, "cannot get clock %s\n",
1091d42202dcSRomain Perier 					"clk_mac_refout");
10927ad269eaSRoger Chen 		}
10937ad269eaSRoger Chen 	}
10947ad269eaSRoger Chen 
109523c94d63SDavid Wu 	bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
109623c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed))
109723c94d63SDavid Wu 		dev_err(dev, "cannot get clock %s\n", "clk_mac_speed");
109823c94d63SDavid Wu 
10997ad269eaSRoger Chen 	if (bsp_priv->clock_input) {
1100d42202dcSRomain Perier 		dev_info(dev, "clock input from PHY\n");
11017ad269eaSRoger Chen 	} else {
11027ad269eaSRoger Chen 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1103c48fa33cSHeiko Stübner 			clk_set_rate(bsp_priv->clk_mac, 50000000);
11047ad269eaSRoger Chen 	}
11057ad269eaSRoger Chen 
1106fecd4d7eSDavid Wu 	if (plat->phy_node && bsp_priv->integrated_phy) {
1107fecd4d7eSDavid Wu 		bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
1108fecd4d7eSDavid Wu 		if (IS_ERR(bsp_priv->clk_phy)) {
1109fecd4d7eSDavid Wu 			ret = PTR_ERR(bsp_priv->clk_phy);
1110fecd4d7eSDavid Wu 			dev_err(dev, "Cannot get PHY clock: %d\n", ret);
1111fecd4d7eSDavid Wu 			return -EINVAL;
1112fecd4d7eSDavid Wu 		}
1113fecd4d7eSDavid Wu 		clk_set_rate(bsp_priv->clk_phy, 50000000);
1114fecd4d7eSDavid Wu 	}
1115fecd4d7eSDavid Wu 
11167ad269eaSRoger Chen 	return 0;
11177ad269eaSRoger Chen }
11187ad269eaSRoger Chen 
11197ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
11207ad269eaSRoger Chen {
1121428ad1bcSLABBE Corentin 	int phy_iface = bsp_priv->phy_iface;
11227ad269eaSRoger Chen 
11237ad269eaSRoger Chen 	if (enable) {
11247ad269eaSRoger Chen 		if (!bsp_priv->clk_enabled) {
11257ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
11267ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->mac_clk_rx))
11277ad269eaSRoger Chen 					clk_prepare_enable(
11287ad269eaSRoger Chen 						bsp_priv->mac_clk_rx);
11297ad269eaSRoger Chen 
11307ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_ref))
11317ad269eaSRoger Chen 					clk_prepare_enable(
11327ad269eaSRoger Chen 						bsp_priv->clk_mac_ref);
11337ad269eaSRoger Chen 
11347ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_refout))
11357ad269eaSRoger Chen 					clk_prepare_enable(
11367ad269eaSRoger Chen 						bsp_priv->clk_mac_refout);
11377ad269eaSRoger Chen 			}
11387ad269eaSRoger Chen 
1139fecd4d7eSDavid Wu 			if (!IS_ERR(bsp_priv->clk_phy))
1140fecd4d7eSDavid Wu 				clk_prepare_enable(bsp_priv->clk_phy);
1141fecd4d7eSDavid Wu 
11427ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->aclk_mac))
11437ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->aclk_mac);
11447ad269eaSRoger Chen 
11457ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->pclk_mac))
11467ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->pclk_mac);
11477ad269eaSRoger Chen 
11487ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->mac_clk_tx))
11497ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->mac_clk_tx);
11507ad269eaSRoger Chen 
115123c94d63SDavid Wu 			if (!IS_ERR(bsp_priv->clk_mac_speed))
115223c94d63SDavid Wu 				clk_prepare_enable(bsp_priv->clk_mac_speed);
115323c94d63SDavid Wu 
11547ad269eaSRoger Chen 			/**
11557ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
11567ad269eaSRoger Chen 			 *	clk_prepare_enable(bsp_priv->clk_mac);
11577ad269eaSRoger Chen 			 */
11587ad269eaSRoger Chen 			mdelay(5);
11597ad269eaSRoger Chen 			bsp_priv->clk_enabled = true;
11607ad269eaSRoger Chen 		}
11617ad269eaSRoger Chen 	} else {
11627ad269eaSRoger Chen 		if (bsp_priv->clk_enabled) {
11637ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
116493120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->mac_clk_rx);
11657ad269eaSRoger Chen 
116693120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_ref);
11677ad269eaSRoger Chen 
116893120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_refout);
11697ad269eaSRoger Chen 			}
11707ad269eaSRoger Chen 
1171fecd4d7eSDavid Wu 			clk_disable_unprepare(bsp_priv->clk_phy);
1172fecd4d7eSDavid Wu 
11737ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->aclk_mac);
11747ad269eaSRoger Chen 
11757ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->pclk_mac);
11767ad269eaSRoger Chen 
11777ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->mac_clk_tx);
117823c94d63SDavid Wu 
117923c94d63SDavid Wu 			clk_disable_unprepare(bsp_priv->clk_mac_speed);
11807ad269eaSRoger Chen 			/**
11817ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
11827ad269eaSRoger Chen 			 *	clk_disable_unprepare(bsp_priv->clk_mac);
11837ad269eaSRoger Chen 			 */
11847ad269eaSRoger Chen 			bsp_priv->clk_enabled = false;
11857ad269eaSRoger Chen 		}
11867ad269eaSRoger Chen 	}
11877ad269eaSRoger Chen 
11887ad269eaSRoger Chen 	return 0;
11897ad269eaSRoger Chen }
11907ad269eaSRoger Chen 
11917ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
11927ad269eaSRoger Chen {
11932e12f536SRomain Perier 	struct regulator *ldo = bsp_priv->regulator;
11947ad269eaSRoger Chen 	int ret;
11957ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
11967ad269eaSRoger Chen 
11973b25528eSChen-Yu Tsai 	if (!ldo)
11983b25528eSChen-Yu Tsai 		return 0;
11997ad269eaSRoger Chen 
12007ad269eaSRoger Chen 	if (enable) {
12017ad269eaSRoger Chen 		ret = regulator_enable(ldo);
12022e12f536SRomain Perier 		if (ret)
1203d42202dcSRomain Perier 			dev_err(dev, "fail to enable phy-supply\n");
12047ad269eaSRoger Chen 	} else {
12057ad269eaSRoger Chen 		ret = regulator_disable(ldo);
12062e12f536SRomain Perier 		if (ret)
1207d42202dcSRomain Perier 			dev_err(dev, "fail to disable phy-supply\n");
12087ad269eaSRoger Chen 	}
12097ad269eaSRoger Chen 
12107ad269eaSRoger Chen 	return 0;
12117ad269eaSRoger Chen }
12127ad269eaSRoger Chen 
12130fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1214fecd4d7eSDavid Wu 					  struct plat_stmmacenet_data *plat,
121592c2588fSJoachim Eastwood 					  const struct rk_gmac_ops *ops)
12167ad269eaSRoger Chen {
12177ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv;
12187ad269eaSRoger Chen 	struct device *dev = &pdev->dev;
12197ad269eaSRoger Chen 	int ret;
12207ad269eaSRoger Chen 	const char *strings = NULL;
12217ad269eaSRoger Chen 	int value;
12227ad269eaSRoger Chen 
12237ad269eaSRoger Chen 	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
12247ad269eaSRoger Chen 	if (!bsp_priv)
12257ad269eaSRoger Chen 		return ERR_PTR(-ENOMEM);
12267ad269eaSRoger Chen 
12270c65b2b9SAndrew Lunn 	of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
12280fb98db1SHeiko Stübner 	bsp_priv->ops = ops;
12297ad269eaSRoger Chen 
12302e12f536SRomain Perier 	bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
12312e12f536SRomain Perier 	if (IS_ERR(bsp_priv->regulator)) {
12322e12f536SRomain Perier 		if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) {
12332e12f536SRomain Perier 			dev_err(dev, "phy regulator is not available yet, deferred probing\n");
12342e12f536SRomain Perier 			return ERR_PTR(-EPROBE_DEFER);
12352e12f536SRomain Perier 		}
12362e12f536SRomain Perier 		dev_err(dev, "no regulator found\n");
12372e12f536SRomain Perier 		bsp_priv->regulator = NULL;
12387ad269eaSRoger Chen 	}
12397ad269eaSRoger Chen 
12407ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
12417ad269eaSRoger Chen 	if (ret) {
1242d42202dcSRomain Perier 		dev_err(dev, "Can not read property: clock_in_out.\n");
12437ad269eaSRoger Chen 		bsp_priv->clock_input = true;
12447ad269eaSRoger Chen 	} else {
1245d42202dcSRomain Perier 		dev_info(dev, "clock input or output? (%s).\n",
1246d42202dcSRomain Perier 			 strings);
12477ad269eaSRoger Chen 		if (!strcmp(strings, "input"))
12487ad269eaSRoger Chen 			bsp_priv->clock_input = true;
12497ad269eaSRoger Chen 		else
12507ad269eaSRoger Chen 			bsp_priv->clock_input = false;
12517ad269eaSRoger Chen 	}
12527ad269eaSRoger Chen 
12537ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
12547ad269eaSRoger Chen 	if (ret) {
12557ad269eaSRoger Chen 		bsp_priv->tx_delay = 0x30;
1256d42202dcSRomain Perier 		dev_err(dev, "Can not read property: tx_delay.");
1257d42202dcSRomain Perier 		dev_err(dev, "set tx_delay to 0x%x\n",
1258d42202dcSRomain Perier 			bsp_priv->tx_delay);
12597ad269eaSRoger Chen 	} else {
1260d42202dcSRomain Perier 		dev_info(dev, "TX delay(0x%x).\n", value);
12617ad269eaSRoger Chen 		bsp_priv->tx_delay = value;
12627ad269eaSRoger Chen 	}
12637ad269eaSRoger Chen 
12647ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
12657ad269eaSRoger Chen 	if (ret) {
12667ad269eaSRoger Chen 		bsp_priv->rx_delay = 0x10;
1267d42202dcSRomain Perier 		dev_err(dev, "Can not read property: rx_delay.");
1268d42202dcSRomain Perier 		dev_err(dev, "set rx_delay to 0x%x\n",
1269d42202dcSRomain Perier 			bsp_priv->rx_delay);
12707ad269eaSRoger Chen 	} else {
1271d42202dcSRomain Perier 		dev_info(dev, "RX delay(0x%x).\n", value);
12727ad269eaSRoger Chen 		bsp_priv->rx_delay = value;
12737ad269eaSRoger Chen 	}
12747ad269eaSRoger Chen 
12757ad269eaSRoger Chen 	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
12767ad269eaSRoger Chen 							"rockchip,grf");
12777ad269eaSRoger Chen 
1278fecd4d7eSDavid Wu 	if (plat->phy_node) {
1279fecd4d7eSDavid Wu 		bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
1280fecd4d7eSDavid Wu 								 "phy-is-integrated");
1281fecd4d7eSDavid Wu 		if (bsp_priv->integrated_phy) {
1282fecd4d7eSDavid Wu 			bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
1283fecd4d7eSDavid Wu 			if (IS_ERR(bsp_priv->phy_reset)) {
1284fecd4d7eSDavid Wu 				dev_err(&pdev->dev, "No PHY reset control found.\n");
1285fecd4d7eSDavid Wu 				bsp_priv->phy_reset = NULL;
1286fecd4d7eSDavid Wu 			}
1287fecd4d7eSDavid Wu 		}
1288fecd4d7eSDavid Wu 	}
1289fecd4d7eSDavid Wu 	dev_info(dev, "integrated PHY? (%s).\n",
1290fecd4d7eSDavid Wu 		 bsp_priv->integrated_phy ? "yes" : "no");
1291fecd4d7eSDavid Wu 
1292fecd4d7eSDavid Wu 	bsp_priv->pdev = pdev;
129345383f52SRoger Chen 
129445383f52SRoger Chen 	return bsp_priv;
129545383f52SRoger Chen }
129645383f52SRoger Chen 
129745383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
129845383f52SRoger Chen {
129945383f52SRoger Chen 	int ret;
130045383f52SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
130145383f52SRoger Chen 
1302f217bfdeSHeiko Stübner 	ret = gmac_clk_enable(bsp_priv, true);
1303f217bfdeSHeiko Stübner 	if (ret)
1304f217bfdeSHeiko Stübner 		return ret;
1305f217bfdeSHeiko Stübner 
13067ad269eaSRoger Chen 	/*rmii or rgmii*/
1307eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1308eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1309d42202dcSRomain Perier 		dev_info(dev, "init for RGMII\n");
13100fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
13110fb98db1SHeiko Stübner 					    bsp_priv->rx_delay);
1312eaf70ad1SWadim Egorov 		break;
1313eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1314eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_ID\n");
1315eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
1316eaf70ad1SWadim Egorov 		break;
1317eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1318eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_RXID\n");
1319eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
1320eaf70ad1SWadim Egorov 		break;
1321eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
1322eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_TXID\n");
1323eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
1324eaf70ad1SWadim Egorov 		break;
1325eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
1326d42202dcSRomain Perier 		dev_info(dev, "init for RMII\n");
13270fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rmii(bsp_priv);
1328eaf70ad1SWadim Egorov 		break;
1329eaf70ad1SWadim Egorov 	default:
1330d42202dcSRomain Perier 		dev_err(dev, "NO interface defined!\n");
13317ad269eaSRoger Chen 	}
13327ad269eaSRoger Chen 
13337ad269eaSRoger Chen 	ret = phy_power_on(bsp_priv, true);
1334c69c29a1SAlexey Khoroshilov 	if (ret) {
1335c69c29a1SAlexey Khoroshilov 		gmac_clk_enable(bsp_priv, false);
13367ad269eaSRoger Chen 		return ret;
1337c69c29a1SAlexey Khoroshilov 	}
13387ad269eaSRoger Chen 
13392c896fb0SDavid Wu 	pm_runtime_enable(dev);
13402c896fb0SDavid Wu 	pm_runtime_get_sync(dev);
13412c896fb0SDavid Wu 
1342fecd4d7eSDavid Wu 	if (bsp_priv->integrated_phy)
1343fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerup(bsp_priv);
1344fecd4d7eSDavid Wu 
13457ad269eaSRoger Chen 	return 0;
13467ad269eaSRoger Chen }
13477ad269eaSRoger Chen 
1348229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac)
13497ad269eaSRoger Chen {
13502c896fb0SDavid Wu 	struct device *dev = &gmac->pdev->dev;
13512c896fb0SDavid Wu 
1352fecd4d7eSDavid Wu 	if (gmac->integrated_phy)
1353fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerdown(gmac);
1354fecd4d7eSDavid Wu 
13552c896fb0SDavid Wu 	pm_runtime_put_sync(dev);
13562c896fb0SDavid Wu 	pm_runtime_disable(dev);
13572c896fb0SDavid Wu 
13587ad269eaSRoger Chen 	phy_power_on(gmac, false);
13597ad269eaSRoger Chen 	gmac_clk_enable(gmac, false);
13607ad269eaSRoger Chen }
13617ad269eaSRoger Chen 
13627ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed)
13637ad269eaSRoger Chen {
13647ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
13657ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
13667ad269eaSRoger Chen 
1367eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1368eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1369eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1370eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1371eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
13720fb98db1SHeiko Stübner 		bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1373eaf70ad1SWadim Egorov 		break;
1374eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
13750fb98db1SHeiko Stübner 		bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1376eaf70ad1SWadim Egorov 		break;
1377eaf70ad1SWadim Egorov 	default:
13787ad269eaSRoger Chen 		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
13797ad269eaSRoger Chen 	}
1380eaf70ad1SWadim Egorov }
13817ad269eaSRoger Chen 
138227ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev)
138327ffefd2SJoachim Eastwood {
138427ffefd2SJoachim Eastwood 	struct plat_stmmacenet_data *plat_dat;
138527ffefd2SJoachim Eastwood 	struct stmmac_resources stmmac_res;
1386f529f182SJoachim Eastwood 	const struct rk_gmac_ops *data;
138727ffefd2SJoachim Eastwood 	int ret;
138827ffefd2SJoachim Eastwood 
1389149adeddSJoachim Eastwood 	data = of_device_get_match_data(&pdev->dev);
1390149adeddSJoachim Eastwood 	if (!data) {
1391149adeddSJoachim Eastwood 		dev_err(&pdev->dev, "no of match data provided\n");
1392149adeddSJoachim Eastwood 		return -EINVAL;
1393149adeddSJoachim Eastwood 	}
1394149adeddSJoachim Eastwood 
139527ffefd2SJoachim Eastwood 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
139627ffefd2SJoachim Eastwood 	if (ret)
139727ffefd2SJoachim Eastwood 		return ret;
139827ffefd2SJoachim Eastwood 
139927ffefd2SJoachim Eastwood 	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
140027ffefd2SJoachim Eastwood 	if (IS_ERR(plat_dat))
140127ffefd2SJoachim Eastwood 		return PTR_ERR(plat_dat);
140227ffefd2SJoachim Eastwood 
140327ffefd2SJoachim Eastwood 	plat_dat->has_gmac = true;
140427ffefd2SJoachim Eastwood 	plat_dat->fix_mac_speed = rk_fix_speed;
140527ffefd2SJoachim Eastwood 
1406fecd4d7eSDavid Wu 	plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
1407d2ed0a77SJohan Hovold 	if (IS_ERR(plat_dat->bsp_priv)) {
1408d2ed0a77SJohan Hovold 		ret = PTR_ERR(plat_dat->bsp_priv);
1409d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
1410d2ed0a77SJohan Hovold 	}
141127ffefd2SJoachim Eastwood 
1412fecd4d7eSDavid Wu 	ret = rk_gmac_clk_init(plat_dat);
1413fecd4d7eSDavid Wu 	if (ret)
1414fecd4d7eSDavid Wu 		return ret;
1415fecd4d7eSDavid Wu 
141607a5e769SJoachim Eastwood 	ret = rk_gmac_powerup(plat_dat->bsp_priv);
141727ffefd2SJoachim Eastwood 	if (ret)
1418d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
141927ffefd2SJoachim Eastwood 
14202d222656SJohan Hovold 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
14212d222656SJohan Hovold 	if (ret)
14222745529aSDavid S. Miller 		goto err_gmac_powerdown;
14232d222656SJohan Hovold 
14242d222656SJohan Hovold 	return 0;
14252d222656SJohan Hovold 
14262745529aSDavid S. Miller err_gmac_powerdown:
14272745529aSDavid S. Miller 	rk_gmac_powerdown(plat_dat->bsp_priv);
1428d2ed0a77SJohan Hovold err_remove_config_dt:
1429d2ed0a77SJohan Hovold 	stmmac_remove_config_dt(pdev, plat_dat);
14302d222656SJohan Hovold 
14312d222656SJohan Hovold 	return ret;
143227ffefd2SJoachim Eastwood }
143327ffefd2SJoachim Eastwood 
14340de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev)
14350de8c4c9SJoachim Eastwood {
14360de8c4c9SJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
14370de8c4c9SJoachim Eastwood 	int ret = stmmac_dvr_remove(&pdev->dev);
14380de8c4c9SJoachim Eastwood 
14390de8c4c9SJoachim Eastwood 	rk_gmac_powerdown(bsp_priv);
14400de8c4c9SJoachim Eastwood 
14410de8c4c9SJoachim Eastwood 	return ret;
14420de8c4c9SJoachim Eastwood }
14430de8c4c9SJoachim Eastwood 
14445619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP
14455619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev)
14465619468aSJoachim Eastwood {
14475619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
14485619468aSJoachim Eastwood 	int ret = stmmac_suspend(dev);
14495619468aSJoachim Eastwood 
14505619468aSJoachim Eastwood 	/* Keep the PHY up if we use Wake-on-Lan. */
14515619468aSJoachim Eastwood 	if (!device_may_wakeup(dev)) {
14525619468aSJoachim Eastwood 		rk_gmac_powerdown(bsp_priv);
14535619468aSJoachim Eastwood 		bsp_priv->suspended = true;
14545619468aSJoachim Eastwood 	}
14555619468aSJoachim Eastwood 
14565619468aSJoachim Eastwood 	return ret;
14575619468aSJoachim Eastwood }
14585619468aSJoachim Eastwood 
14595619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev)
14605619468aSJoachim Eastwood {
14615619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
14625619468aSJoachim Eastwood 
14635619468aSJoachim Eastwood 	/* The PHY was up for Wake-on-Lan. */
14645619468aSJoachim Eastwood 	if (bsp_priv->suspended) {
14655619468aSJoachim Eastwood 		rk_gmac_powerup(bsp_priv);
14665619468aSJoachim Eastwood 		bsp_priv->suspended = false;
14675619468aSJoachim Eastwood 	}
14685619468aSJoachim Eastwood 
14695619468aSJoachim Eastwood 	return stmmac_resume(dev);
14705619468aSJoachim Eastwood }
14715619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */
14725619468aSJoachim Eastwood 
14735619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
14745619468aSJoachim Eastwood 
1475e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = {
147623c94d63SDavid Wu 	{ .compatible = "rockchip,px30-gmac",	.data = &px30_ops   },
147705946876SDavid Wu 	{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
1478e7ffd812SXing Zheng 	{ .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
1479f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
1480d4ff816eSdavid.wu 	{ .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
1481ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
1482f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
1483ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
148489c9c163SDavid Wu 	{ .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
1485e0fb4013SJoachim Eastwood 	{ }
1486e0fb4013SJoachim Eastwood };
1487e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
1488e0fb4013SJoachim Eastwood 
1489e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = {
149027ffefd2SJoachim Eastwood 	.probe  = rk_gmac_probe,
14910de8c4c9SJoachim Eastwood 	.remove = rk_gmac_remove,
1492e0fb4013SJoachim Eastwood 	.driver = {
1493e0fb4013SJoachim Eastwood 		.name           = "rk_gmac-dwmac",
14945619468aSJoachim Eastwood 		.pm		= &rk_gmac_pm_ops,
1495e0fb4013SJoachim Eastwood 		.of_match_table = rk_gmac_dwmac_match,
1496e0fb4013SJoachim Eastwood 	},
1497e0fb4013SJoachim Eastwood };
1498e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver);
1499e0fb4013SJoachim Eastwood 
1500e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
1501e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
1502e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL");
1503