1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
27ad269eaSRoger Chen /**
3d0ea5cbdSJesse Brandeburg  * DOC: dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
47ad269eaSRoger Chen  *
57ad269eaSRoger Chen  * Copyright (C) 2014 Chen-Zhi (Roger Chen)
67ad269eaSRoger Chen  *
77ad269eaSRoger Chen  * Chen-Zhi (Roger Chen)  <roger.chen@rock-chips.com>
87ad269eaSRoger Chen  */
97ad269eaSRoger Chen 
107ad269eaSRoger Chen #include <linux/stmmac.h>
117ad269eaSRoger Chen #include <linux/bitops.h>
127ad269eaSRoger Chen #include <linux/clk.h>
137ad269eaSRoger Chen #include <linux/phy.h>
147ad269eaSRoger Chen #include <linux/of_net.h>
157ad269eaSRoger Chen #include <linux/gpio.h>
16e0fb4013SJoachim Eastwood #include <linux/module.h>
177ad269eaSRoger Chen #include <linux/of_gpio.h>
187ad269eaSRoger Chen #include <linux/of_device.h>
19e0fb4013SJoachim Eastwood #include <linux/platform_device.h>
207ad269eaSRoger Chen #include <linux/regulator/consumer.h>
217ad269eaSRoger Chen #include <linux/delay.h>
227ad269eaSRoger Chen #include <linux/mfd/syscon.h>
237ad269eaSRoger Chen #include <linux/regmap.h>
24aec3f415SPunit Agrawal #include <linux/pm_runtime.h>
257ad269eaSRoger Chen 
26e0fb4013SJoachim Eastwood #include "stmmac_platform.h"
27e0fb4013SJoachim Eastwood 
280fb98db1SHeiko Stübner struct rk_priv_data;
290fb98db1SHeiko Stübner struct rk_gmac_ops {
300fb98db1SHeiko Stübner 	void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
310fb98db1SHeiko Stübner 			     int tx_delay, int rx_delay);
320fb98db1SHeiko Stübner 	void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
330fb98db1SHeiko Stübner 	void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
340fb98db1SHeiko Stübner 	void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
352f2b60a0SDavid Wu 	void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input,
362f2b60a0SDavid Wu 				    bool enable);
37fecd4d7eSDavid Wu 	void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
380546b224SJohn Keeping 	bool regs_valid;
393bb3d6b1SDavid Wu 	u32 regs[];
400fb98db1SHeiko Stübner };
410fb98db1SHeiko Stübner 
42ea449f7fSSebastian Reichel static const char * const rk_clocks[] = {
43ea449f7fSSebastian Reichel 	"aclk_mac", "pclk_mac", "mac_clk_tx", "clk_mac_speed",
44ea449f7fSSebastian Reichel };
45ea449f7fSSebastian Reichel 
46ea449f7fSSebastian Reichel static const char * const rk_rmii_clocks[] = {
47ea449f7fSSebastian Reichel 	"mac_clk_rx", "clk_mac_ref", "clk_mac_refout",
48ea449f7fSSebastian Reichel };
49ea449f7fSSebastian Reichel 
50ea449f7fSSebastian Reichel enum rk_clocks_index {
51ea449f7fSSebastian Reichel 	RK_ACLK_MAC = 0,
52ea449f7fSSebastian Reichel 	RK_PCLK_MAC,
53ea449f7fSSebastian Reichel 	RK_MAC_CLK_TX,
54ea449f7fSSebastian Reichel 	RK_CLK_MAC_SPEED,
55ea449f7fSSebastian Reichel 	RK_MAC_CLK_RX,
56ea449f7fSSebastian Reichel 	RK_CLK_MAC_REF,
57ea449f7fSSebastian Reichel 	RK_CLK_MAC_REFOUT,
58ea449f7fSSebastian Reichel };
59ea449f7fSSebastian Reichel 
607ad269eaSRoger Chen struct rk_priv_data {
617ad269eaSRoger Chen 	struct platform_device *pdev;
620c65b2b9SAndrew Lunn 	phy_interface_t phy_iface;
633bb3d6b1SDavid Wu 	int id;
642e12f536SRomain Perier 	struct regulator *regulator;
65229666c1SVincent Palatin 	bool suspended;
6692c2588fSJoachim Eastwood 	const struct rk_gmac_ops *ops;
677ad269eaSRoger Chen 
687ad269eaSRoger Chen 	bool clk_enabled;
697ad269eaSRoger Chen 	bool clock_input;
70fecd4d7eSDavid Wu 	bool integrated_phy;
717ad269eaSRoger Chen 
72ea449f7fSSebastian Reichel 	struct clk_bulk_data *clks;
73ea449f7fSSebastian Reichel 	int num_clks;
747ad269eaSRoger Chen 	struct clk *clk_mac;
75fecd4d7eSDavid Wu 	struct clk *clk_phy;
76fecd4d7eSDavid Wu 
77fecd4d7eSDavid Wu 	struct reset_control *phy_reset;
787ad269eaSRoger Chen 
797ad269eaSRoger Chen 	int tx_delay;
807ad269eaSRoger Chen 	int rx_delay;
817ad269eaSRoger Chen 
827ad269eaSRoger Chen 	struct regmap *grf;
832f2b60a0SDavid Wu 	struct regmap *php_grf;
847ad269eaSRoger Chen };
857ad269eaSRoger Chen 
867ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \
877ad269eaSRoger Chen 		((val) << (shift) | (mask) << ((shift) + 16))
887ad269eaSRoger Chen 
897ad269eaSRoger Chen #define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
907ad269eaSRoger Chen #define GRF_CLR_BIT(nr)	(BIT(nr+16))
917ad269eaSRoger Chen 
92eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \
93eaf70ad1SWadim Egorov 	(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
94eaf70ad1SWadim Egorov 	 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
95eaf70ad1SWadim Egorov 
9623c94d63SDavid Wu #define PX30_GRF_GMAC_CON1		0x0904
9723c94d63SDavid Wu 
9823c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */
9923c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
10023c94d63SDavid Wu 					 GRF_BIT(6))
10123c94d63SDavid Wu #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
10223c94d63SDavid Wu #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
10323c94d63SDavid Wu 
10423c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
10523c94d63SDavid Wu {
10623c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10723c94d63SDavid Wu 
10823c94d63SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10923c94d63SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
11023c94d63SDavid Wu 		return;
11123c94d63SDavid Wu 	}
11223c94d63SDavid Wu 
11323c94d63SDavid Wu 	regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
11423c94d63SDavid Wu 		     PX30_GMAC_PHY_INTF_SEL_RMII);
11523c94d63SDavid Wu }
11623c94d63SDavid Wu 
11723c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
11823c94d63SDavid Wu {
119ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
12023c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
12123c94d63SDavid Wu 	int ret;
12223c94d63SDavid Wu 
123ea449f7fSSebastian Reichel 	if (!clk_mac_speed) {
12423c94d63SDavid Wu 		dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
12523c94d63SDavid Wu 		return;
12623c94d63SDavid Wu 	}
12723c94d63SDavid Wu 
12823c94d63SDavid Wu 	if (speed == 10) {
12923c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
13023c94d63SDavid Wu 			     PX30_GMAC_SPEED_10M);
13123c94d63SDavid Wu 
132ea449f7fSSebastian Reichel 		ret = clk_set_rate(clk_mac_speed, 2500000);
13323c94d63SDavid Wu 		if (ret)
13423c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n",
13523c94d63SDavid Wu 				__func__, ret);
13623c94d63SDavid Wu 	} else if (speed == 100) {
13723c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
13823c94d63SDavid Wu 			     PX30_GMAC_SPEED_100M);
13923c94d63SDavid Wu 
140ea449f7fSSebastian Reichel 		ret = clk_set_rate(clk_mac_speed, 25000000);
14123c94d63SDavid Wu 		if (ret)
14223c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n",
14323c94d63SDavid Wu 				__func__, ret);
14423c94d63SDavid Wu 
14523c94d63SDavid Wu 	} else {
14623c94d63SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
14723c94d63SDavid Wu 	}
14823c94d63SDavid Wu }
14923c94d63SDavid Wu 
15023c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = {
15123c94d63SDavid Wu 	.set_to_rmii = px30_set_to_rmii,
15223c94d63SDavid Wu 	.set_rmii_speed = px30_set_rmii_speed,
15323c94d63SDavid Wu };
15423c94d63SDavid Wu 
15505946876SDavid Wu #define RK3128_GRF_MAC_CON0	0x0168
15605946876SDavid Wu #define RK3128_GRF_MAC_CON1	0x016c
15705946876SDavid Wu 
15805946876SDavid Wu /* RK3128_GRF_MAC_CON0 */
15905946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE   GRF_BIT(14)
16005946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(14)
16105946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(15)
16205946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(15)
16305946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
16405946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
16505946876SDavid Wu 
16605946876SDavid Wu /* RK3128_GRF_MAC_CON1 */
16705946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII	\
16805946876SDavid Wu 		(GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
16905946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII	\
17005946876SDavid Wu 		(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
17105946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
17205946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
17305946876SDavid Wu #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
17405946876SDavid Wu #define RK3128_GMAC_SPEED_100M         GRF_BIT(10)
17505946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M       GRF_BIT(11)
17605946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M      GRF_CLR_BIT(11)
17705946876SDavid Wu #define RK3128_GMAC_CLK_125M           (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
17805946876SDavid Wu #define RK3128_GMAC_CLK_25M            (GRF_BIT(12) | GRF_BIT(13))
17905946876SDavid Wu #define RK3128_GMAC_CLK_2_5M           (GRF_CLR_BIT(12) | GRF_BIT(13))
18005946876SDavid Wu #define RK3128_GMAC_RMII_MODE          GRF_BIT(14)
18105946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR      GRF_CLR_BIT(14)
18205946876SDavid Wu 
18305946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
18405946876SDavid Wu 				int tx_delay, int rx_delay)
18505946876SDavid Wu {
18605946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
18705946876SDavid Wu 
18805946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
18905946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
19005946876SDavid Wu 		return;
19105946876SDavid Wu 	}
19205946876SDavid Wu 
19305946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
19405946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RGMII |
19505946876SDavid Wu 		     RK3128_GMAC_RMII_MODE_CLR);
19605946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
19705946876SDavid Wu 		     DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
19805946876SDavid Wu 		     RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
19905946876SDavid Wu 		     RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
20005946876SDavid Wu }
20105946876SDavid Wu 
20205946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
20305946876SDavid Wu {
20405946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
20505946876SDavid Wu 
20605946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
20705946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
20805946876SDavid Wu 		return;
20905946876SDavid Wu 	}
21005946876SDavid Wu 
21105946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21205946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
21305946876SDavid Wu }
21405946876SDavid Wu 
21505946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
21605946876SDavid Wu {
21705946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
21805946876SDavid Wu 
21905946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
22005946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
22105946876SDavid Wu 		return;
22205946876SDavid Wu 	}
22305946876SDavid Wu 
22405946876SDavid Wu 	if (speed == 10)
22505946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
22605946876SDavid Wu 			     RK3128_GMAC_CLK_2_5M);
22705946876SDavid Wu 	else if (speed == 100)
22805946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
22905946876SDavid Wu 			     RK3128_GMAC_CLK_25M);
23005946876SDavid Wu 	else if (speed == 1000)
23105946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23205946876SDavid Wu 			     RK3128_GMAC_CLK_125M);
23305946876SDavid Wu 	else
23405946876SDavid Wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
23505946876SDavid Wu }
23605946876SDavid Wu 
23705946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
23805946876SDavid Wu {
23905946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
24005946876SDavid Wu 
24105946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
24205946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
24305946876SDavid Wu 		return;
24405946876SDavid Wu 	}
24505946876SDavid Wu 
24605946876SDavid Wu 	if (speed == 10) {
24705946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
24805946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_2_5M |
24905946876SDavid Wu 			     RK3128_GMAC_SPEED_10M);
25005946876SDavid Wu 	} else if (speed == 100) {
25105946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
25205946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_25M |
25305946876SDavid Wu 			     RK3128_GMAC_SPEED_100M);
25405946876SDavid Wu 	} else {
25505946876SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
25605946876SDavid Wu 	}
25705946876SDavid Wu }
25805946876SDavid Wu 
25905946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = {
26005946876SDavid Wu 	.set_to_rgmii = rk3128_set_to_rgmii,
26105946876SDavid Wu 	.set_to_rmii = rk3128_set_to_rmii,
26205946876SDavid Wu 	.set_rgmii_speed = rk3128_set_rgmii_speed,
26305946876SDavid Wu 	.set_rmii_speed = rk3128_set_rmii_speed,
26405946876SDavid Wu };
26505946876SDavid Wu 
266e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0	0x0900
267e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1	0x0904
268e7ffd812SXing Zheng 
2696fa12c78SDavid Wu #define RK3228_GRF_CON_MUX	0x50
2706fa12c78SDavid Wu 
271e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */
272e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
273e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
274e7ffd812SXing Zheng 
275e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */
276e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII	\
277e7ffd812SXing Zheng 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
278e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII	\
279e7ffd812SXing Zheng 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
280e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
281e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
282e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
283e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M		GRF_BIT(2)
284e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M	GRF_BIT(7)
285e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
286e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M		(GRF_CLR_BIT(8) | GRF_CLR_BIT(9))
287e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M		(GRF_BIT(8) | GRF_BIT(9))
288e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M		(GRF_CLR_BIT(8) | GRF_BIT(9))
289e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE		GRF_BIT(10)
290e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(10)
291e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
292e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
293e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
294e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
295e7ffd812SXing Zheng 
2966fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */
2976fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY	GRF_BIT(15)
2986fa12c78SDavid Wu 
299e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
300e7ffd812SXing Zheng 				int tx_delay, int rx_delay)
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_RGMII |
311e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE_CLR |
312eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3228, tx_delay, rx_delay));
313e7ffd812SXing Zheng 
314e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
315e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
316e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
317e7ffd812SXing Zheng }
318e7ffd812SXing Zheng 
319e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
320e7ffd812SXing Zheng {
321e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
322e7ffd812SXing Zheng 
323e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
324e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
325e7ffd812SXing Zheng 		return;
326e7ffd812SXing Zheng 	}
327e7ffd812SXing Zheng 
328e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
329e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RMII |
330e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE);
331e7ffd812SXing Zheng 
332e7ffd812SXing Zheng 	/* set MAC to RMII mode */
333e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11));
334e7ffd812SXing Zheng }
335e7ffd812SXing Zheng 
336e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
337e7ffd812SXing Zheng {
338e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
339e7ffd812SXing Zheng 
340e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
341e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
342e7ffd812SXing Zheng 		return;
343e7ffd812SXing Zheng 	}
344e7ffd812SXing Zheng 
345e7ffd812SXing Zheng 	if (speed == 10)
346e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
347e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_2_5M);
348e7ffd812SXing Zheng 	else if (speed == 100)
349e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
350e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_25M);
351e7ffd812SXing Zheng 	else if (speed == 1000)
352e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
353e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_125M);
354e7ffd812SXing Zheng 	else
355e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
356e7ffd812SXing Zheng }
357e7ffd812SXing Zheng 
358e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
359e7ffd812SXing Zheng {
360e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
361e7ffd812SXing Zheng 
362e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
363e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
364e7ffd812SXing Zheng 		return;
365e7ffd812SXing Zheng 	}
366e7ffd812SXing Zheng 
367e7ffd812SXing Zheng 	if (speed == 10)
368e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
369e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_2_5M |
370e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_10M);
371e7ffd812SXing Zheng 	else if (speed == 100)
372e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
373e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_25M |
374e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_100M);
375e7ffd812SXing Zheng 	else
376e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
377e7ffd812SXing Zheng }
378e7ffd812SXing Zheng 
3796fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
3806fa12c78SDavid Wu {
3816fa12c78SDavid Wu 	regmap_write(priv->grf, RK3228_GRF_CON_MUX,
3826fa12c78SDavid Wu 		     RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
3836fa12c78SDavid Wu }
3846fa12c78SDavid Wu 
385e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = {
386e7ffd812SXing Zheng 	.set_to_rgmii = rk3228_set_to_rgmii,
387e7ffd812SXing Zheng 	.set_to_rmii = rk3228_set_to_rmii,
388e7ffd812SXing Zheng 	.set_rgmii_speed = rk3228_set_rgmii_speed,
389e7ffd812SXing Zheng 	.set_rmii_speed = rk3228_set_rmii_speed,
3906fa12c78SDavid Wu 	.integrated_phy_powerup =  rk3228_integrated_phy_powerup,
391e7ffd812SXing Zheng };
392e7ffd812SXing Zheng 
3937ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1	0x0248
3947ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3	0x0250
3957ad269eaSRoger Chen 
3967ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/
3970fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | \
3980fb98db1SHeiko Stübner 					 GRF_CLR_BIT(8))
3990fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
4000fb98db1SHeiko Stübner 					 GRF_BIT(8))
4010fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
4020fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
4030fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
4040fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M		GRF_BIT(10)
4050fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M	GRF_BIT(11)
4060fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
4070fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
4080fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
4090fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
4100fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE		GRF_BIT(14)
4110fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
4127ad269eaSRoger Chen 
4137ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/
4140fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
4150fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
4160fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
4170fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
4180fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
4190fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
4207ad269eaSRoger Chen 
4210fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
4227ad269eaSRoger Chen 				int tx_delay, int rx_delay)
4237ad269eaSRoger Chen {
4247ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4257ad269eaSRoger Chen 
4267ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
427d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4287ad269eaSRoger Chen 		return;
4297ad269eaSRoger Chen 	}
4307ad269eaSRoger Chen 
4317ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4320fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
4330fb98db1SHeiko Stübner 		     RK3288_GMAC_RMII_MODE_CLR);
4347ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
435eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
4360fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
4370fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
4387ad269eaSRoger Chen }
4397ad269eaSRoger Chen 
4400fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
4417ad269eaSRoger Chen {
4427ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4437ad269eaSRoger Chen 
4447ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
445d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4467ad269eaSRoger Chen 		return;
4477ad269eaSRoger Chen 	}
4487ad269eaSRoger Chen 
4497ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4500fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
4517ad269eaSRoger Chen }
4527ad269eaSRoger Chen 
4530fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
4547ad269eaSRoger Chen {
4557ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4567ad269eaSRoger Chen 
4577ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
458d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4597ad269eaSRoger Chen 		return;
4607ad269eaSRoger Chen 	}
4617ad269eaSRoger Chen 
4627ad269eaSRoger Chen 	if (speed == 10)
4630fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4640fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_2_5M);
4657ad269eaSRoger Chen 	else if (speed == 100)
4660fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4670fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_25M);
4687ad269eaSRoger Chen 	else if (speed == 1000)
4690fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4700fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_125M);
4717ad269eaSRoger Chen 	else
4727ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
4737ad269eaSRoger Chen }
4747ad269eaSRoger Chen 
4750fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
4767ad269eaSRoger Chen {
4777ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4787ad269eaSRoger Chen 
4797ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
480d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4817ad269eaSRoger Chen 		return;
4827ad269eaSRoger Chen 	}
4837ad269eaSRoger Chen 
4847ad269eaSRoger Chen 	if (speed == 10) {
4857ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4860fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_2_5M |
4870fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_10M);
4887ad269eaSRoger Chen 	} else if (speed == 100) {
4897ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4900fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_25M |
4910fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_100M);
4927ad269eaSRoger Chen 	} else {
4937ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
4947ad269eaSRoger Chen 	}
4957ad269eaSRoger Chen }
4967ad269eaSRoger Chen 
49792c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = {
4980fb98db1SHeiko Stübner 	.set_to_rgmii = rk3288_set_to_rgmii,
4990fb98db1SHeiko Stübner 	.set_to_rmii = rk3288_set_to_rmii,
5000fb98db1SHeiko Stübner 	.set_rgmii_speed = rk3288_set_rgmii_speed,
5010fb98db1SHeiko Stübner 	.set_rmii_speed = rk3288_set_rmii_speed,
5020fb98db1SHeiko Stübner };
5030fb98db1SHeiko Stübner 
504b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0		0x04a0
505b4ac9456STobias Schramm 
506b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */
507b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \
508b4ac9456STobias Schramm 					GRF_BIT(4))
509b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
510b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
511b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
512b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M		GRF_BIT(0)
513b4ac9456STobias Schramm 
514b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv)
515b4ac9456STobias Schramm {
516b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
517b4ac9456STobias Schramm 
518b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
519b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
520b4ac9456STobias Schramm 		return;
521b4ac9456STobias Schramm 	}
522b4ac9456STobias Schramm 
523b4ac9456STobias Schramm 	regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
524b4ac9456STobias Schramm 		     RK3308_GMAC_PHY_INTF_SEL_RMII);
525b4ac9456STobias Schramm }
526b4ac9456STobias Schramm 
527b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
528b4ac9456STobias Schramm {
529b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
530b4ac9456STobias Schramm 
531b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
532b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
533b4ac9456STobias Schramm 		return;
534b4ac9456STobias Schramm 	}
535b4ac9456STobias Schramm 
536b4ac9456STobias Schramm 	if (speed == 10) {
537b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
538b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_10M);
539b4ac9456STobias Schramm 	} else if (speed == 100) {
540b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
541b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_100M);
542b4ac9456STobias Schramm 	} else {
543b4ac9456STobias Schramm 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
544b4ac9456STobias Schramm 	}
545b4ac9456STobias Schramm }
546b4ac9456STobias Schramm 
547b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = {
548b4ac9456STobias Schramm 	.set_to_rmii = rk3308_set_to_rmii,
549b4ac9456STobias Schramm 	.set_rmii_speed = rk3308_set_rmii_speed,
550b4ac9456STobias Schramm };
551b4ac9456STobias Schramm 
552d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0	0x0900
553d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1	0x0904
5548bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2	0x0908
5558bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1	0xb04
556d4ff816eSdavid.wu 
557d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */
558d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
559d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
560d4ff816eSdavid.wu 
561d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */
562d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII	\
563d4ff816eSdavid.wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
564d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII	\
565d4ff816eSdavid.wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
566d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
567d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
568d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
569d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M		GRF_BIT(2)
570d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M	GRF_BIT(7)
571d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
572d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M		(GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
573d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M		(GRF_BIT(11) | GRF_BIT(12))
574d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M		(GRF_CLR_BIT(11) | GRF_BIT(12))
575d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE		GRF_BIT(9)
576d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(9)
577d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
578d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
579d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
580d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
581d4ff816eSdavid.wu 
5828bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */
5838bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE		GRF_BIT(9)
5848bdf63bdSDavid Wu 
585d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
586d4ff816eSdavid.wu 				int tx_delay, int rx_delay)
587d4ff816eSdavid.wu {
588d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
589d4ff816eSdavid.wu 
590d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
591d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
592d4ff816eSdavid.wu 		return;
593d4ff816eSdavid.wu 	}
594d4ff816eSdavid.wu 
595d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
596d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
597d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE_CLR |
598d4ff816eSdavid.wu 		     RK3328_GMAC_RXCLK_DLY_ENABLE |
599d4ff816eSdavid.wu 		     RK3328_GMAC_TXCLK_DLY_ENABLE);
600d4ff816eSdavid.wu 
601d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
602d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
603d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
604d4ff816eSdavid.wu }
605d4ff816eSdavid.wu 
606d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
607d4ff816eSdavid.wu {
608d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
6098bdf63bdSDavid Wu 	unsigned int reg;
610d4ff816eSdavid.wu 
611d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
612d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
613d4ff816eSdavid.wu 		return;
614d4ff816eSdavid.wu 	}
615d4ff816eSdavid.wu 
6168bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6178bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6188bdf63bdSDavid Wu 
6198bdf63bdSDavid Wu 	regmap_write(bsp_priv->grf, reg,
620d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RMII |
621d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE);
622d4ff816eSdavid.wu }
623d4ff816eSdavid.wu 
624d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
625d4ff816eSdavid.wu {
626d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
627d4ff816eSdavid.wu 
628d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
629d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
630d4ff816eSdavid.wu 		return;
631d4ff816eSdavid.wu 	}
632d4ff816eSdavid.wu 
633d4ff816eSdavid.wu 	if (speed == 10)
634d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
635d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_2_5M);
636d4ff816eSdavid.wu 	else if (speed == 100)
637d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
638d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_25M);
639d4ff816eSdavid.wu 	else if (speed == 1000)
640d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
641d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_125M);
642d4ff816eSdavid.wu 	else
643d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
644d4ff816eSdavid.wu }
645d4ff816eSdavid.wu 
646d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
647d4ff816eSdavid.wu {
648d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
6498bdf63bdSDavid Wu 	unsigned int reg;
650d4ff816eSdavid.wu 
651d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
652d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
653d4ff816eSdavid.wu 		return;
654d4ff816eSdavid.wu 	}
655d4ff816eSdavid.wu 
6568bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6578bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6588bdf63bdSDavid Wu 
659d4ff816eSdavid.wu 	if (speed == 10)
6608bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
661d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_2_5M |
662d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_10M);
663d4ff816eSdavid.wu 	else if (speed == 100)
6648bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
665d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_25M |
666d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_100M);
667d4ff816eSdavid.wu 	else
668d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
669d4ff816eSdavid.wu }
670d4ff816eSdavid.wu 
6718bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
6728bdf63bdSDavid Wu {
6738bdf63bdSDavid Wu 	regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
6748bdf63bdSDavid Wu 		     RK3328_MACPHY_RMII_MODE);
6758bdf63bdSDavid Wu }
6768bdf63bdSDavid Wu 
677d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = {
678d4ff816eSdavid.wu 	.set_to_rgmii = rk3328_set_to_rgmii,
679d4ff816eSdavid.wu 	.set_to_rmii = rk3328_set_to_rmii,
680d4ff816eSdavid.wu 	.set_rgmii_speed = rk3328_set_rgmii_speed,
681d4ff816eSdavid.wu 	.set_rmii_speed = rk3328_set_rmii_speed,
6828bdf63bdSDavid Wu 	.integrated_phy_powerup =  rk3328_integrated_phy_powerup,
683d4ff816eSdavid.wu };
684d4ff816eSdavid.wu 
685ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6	0x0418
686ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7	0x041c
687ba289af8SRoger Chen 
688ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */
689ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
690ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
691ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
692ba289af8SRoger Chen 					 GRF_BIT(11))
693ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
694ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
695ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
696ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M		GRF_BIT(7)
697ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M	GRF_BIT(3)
698ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
699ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
700ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
701ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
702ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE		GRF_BIT(6)
703ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
704ba289af8SRoger Chen 
705ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */
706ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
707ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
708ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
709ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
710ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
711ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
712ba289af8SRoger Chen 
713ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
714ba289af8SRoger Chen 				int tx_delay, int rx_delay)
715ba289af8SRoger Chen {
716ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
717ba289af8SRoger Chen 
718ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
719ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
720ba289af8SRoger Chen 		return;
721ba289af8SRoger Chen 	}
722ba289af8SRoger Chen 
723ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
724ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RGMII |
725ba289af8SRoger Chen 		     RK3366_GMAC_RMII_MODE_CLR);
726ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
727eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
728ba289af8SRoger Chen 		     RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
729ba289af8SRoger Chen 		     RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
730ba289af8SRoger Chen }
731ba289af8SRoger Chen 
732ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
733ba289af8SRoger Chen {
734ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
735ba289af8SRoger Chen 
736ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
737ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
738ba289af8SRoger Chen 		return;
739ba289af8SRoger Chen 	}
740ba289af8SRoger Chen 
741ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
742ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
743ba289af8SRoger Chen }
744ba289af8SRoger Chen 
745ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
746ba289af8SRoger Chen {
747ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
748ba289af8SRoger Chen 
749ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
750ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
751ba289af8SRoger Chen 		return;
752ba289af8SRoger Chen 	}
753ba289af8SRoger Chen 
754ba289af8SRoger Chen 	if (speed == 10)
755ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
756ba289af8SRoger Chen 			     RK3366_GMAC_CLK_2_5M);
757ba289af8SRoger Chen 	else if (speed == 100)
758ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
759ba289af8SRoger Chen 			     RK3366_GMAC_CLK_25M);
760ba289af8SRoger Chen 	else if (speed == 1000)
761ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
762ba289af8SRoger Chen 			     RK3366_GMAC_CLK_125M);
763ba289af8SRoger Chen 	else
764ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
765ba289af8SRoger Chen }
766ba289af8SRoger Chen 
767ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
768ba289af8SRoger Chen {
769ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
770ba289af8SRoger Chen 
771ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
772ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
773ba289af8SRoger Chen 		return;
774ba289af8SRoger Chen 	}
775ba289af8SRoger Chen 
776ba289af8SRoger Chen 	if (speed == 10) {
777ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
778ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_2_5M |
779ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_10M);
780ba289af8SRoger Chen 	} else if (speed == 100) {
781ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
782ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_25M |
783ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_100M);
784ba289af8SRoger Chen 	} else {
785ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
786ba289af8SRoger Chen 	}
787ba289af8SRoger Chen }
788ba289af8SRoger Chen 
789ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = {
790ba289af8SRoger Chen 	.set_to_rgmii = rk3366_set_to_rgmii,
791ba289af8SRoger Chen 	.set_to_rmii = rk3366_set_to_rmii,
792ba289af8SRoger Chen 	.set_rgmii_speed = rk3366_set_rgmii_speed,
793ba289af8SRoger Chen 	.set_rmii_speed = rk3366_set_rmii_speed,
794ba289af8SRoger Chen };
795ba289af8SRoger Chen 
796df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15	0x043c
797df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16	0x0440
798df558854SHeiko Stübner 
799df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */
800df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
801df558854SHeiko Stübner 					 GRF_CLR_BIT(11))
802df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
803df558854SHeiko Stübner 					 GRF_BIT(11))
804df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
805df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
806df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
807df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M		GRF_BIT(7)
808df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M	GRF_BIT(3)
809df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
810df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
811df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
812df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
813df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE		GRF_BIT(6)
814df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
815df558854SHeiko Stübner 
816df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */
817df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
818df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
819df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
820df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
821df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
822df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
823df558854SHeiko Stübner 
824df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
825df558854SHeiko Stübner 				int tx_delay, int rx_delay)
826df558854SHeiko Stübner {
827df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
828df558854SHeiko Stübner 
829df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
830df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
831df558854SHeiko Stübner 		return;
832df558854SHeiko Stübner 	}
833df558854SHeiko Stübner 
834df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
835df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
836df558854SHeiko Stübner 		     RK3368_GMAC_RMII_MODE_CLR);
837df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
838eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
839df558854SHeiko Stübner 		     RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
840df558854SHeiko Stübner 		     RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
841df558854SHeiko Stübner }
842df558854SHeiko Stübner 
843df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
844df558854SHeiko Stübner {
845df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
846df558854SHeiko Stübner 
847df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
848df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
849df558854SHeiko Stübner 		return;
850df558854SHeiko Stübner 	}
851df558854SHeiko Stübner 
852df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
853df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
854df558854SHeiko Stübner }
855df558854SHeiko Stübner 
856df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
857df558854SHeiko Stübner {
858df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
859df558854SHeiko Stübner 
860df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
861df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
862df558854SHeiko Stübner 		return;
863df558854SHeiko Stübner 	}
864df558854SHeiko Stübner 
865df558854SHeiko Stübner 	if (speed == 10)
866df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
867df558854SHeiko Stübner 			     RK3368_GMAC_CLK_2_5M);
868df558854SHeiko Stübner 	else if (speed == 100)
869df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
870df558854SHeiko Stübner 			     RK3368_GMAC_CLK_25M);
871df558854SHeiko Stübner 	else if (speed == 1000)
872df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
873df558854SHeiko Stübner 			     RK3368_GMAC_CLK_125M);
874df558854SHeiko Stübner 	else
875df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
876df558854SHeiko Stübner }
877df558854SHeiko Stübner 
878df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
879df558854SHeiko Stübner {
880df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
881df558854SHeiko Stübner 
882df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
883df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
884df558854SHeiko Stübner 		return;
885df558854SHeiko Stübner 	}
886df558854SHeiko Stübner 
887df558854SHeiko Stübner 	if (speed == 10) {
888df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
889df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_2_5M |
890df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_10M);
891df558854SHeiko Stübner 	} else if (speed == 100) {
892df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
893df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_25M |
894df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_100M);
895df558854SHeiko Stübner 	} else {
896df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
897df558854SHeiko Stübner 	}
898df558854SHeiko Stübner }
899df558854SHeiko Stübner 
90092c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = {
901df558854SHeiko Stübner 	.set_to_rgmii = rk3368_set_to_rgmii,
902df558854SHeiko Stübner 	.set_to_rmii = rk3368_set_to_rmii,
903df558854SHeiko Stübner 	.set_rgmii_speed = rk3368_set_rgmii_speed,
904df558854SHeiko Stübner 	.set_rmii_speed = rk3368_set_rmii_speed,
905df558854SHeiko Stübner };
906df558854SHeiko Stübner 
907ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5	0xc214
908ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6	0xc218
909ba289af8SRoger Chen 
910ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */
911ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
912ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
913ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
914ba289af8SRoger Chen 					 GRF_BIT(11))
915ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
916ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
917ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
918ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M		GRF_BIT(7)
919ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M	GRF_BIT(3)
920ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
921ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
922ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
923ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
924ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE		GRF_BIT(6)
925ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
926ba289af8SRoger Chen 
927ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */
928ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
929ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
930ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
931ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
932ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
933ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
934ba289af8SRoger Chen 
935ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
936ba289af8SRoger Chen 				int tx_delay, int rx_delay)
937ba289af8SRoger Chen {
938ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
939ba289af8SRoger Chen 
940ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
941ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
942ba289af8SRoger Chen 		return;
943ba289af8SRoger Chen 	}
944ba289af8SRoger Chen 
945ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
946ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RGMII |
947ba289af8SRoger Chen 		     RK3399_GMAC_RMII_MODE_CLR);
948ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
949eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
950ba289af8SRoger Chen 		     RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
951ba289af8SRoger Chen 		     RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
952ba289af8SRoger Chen }
953ba289af8SRoger Chen 
954ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
955ba289af8SRoger Chen {
956ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
957ba289af8SRoger Chen 
958ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
959ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
960ba289af8SRoger Chen 		return;
961ba289af8SRoger Chen 	}
962ba289af8SRoger Chen 
963ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
964ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
965ba289af8SRoger Chen }
966ba289af8SRoger Chen 
967ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
968ba289af8SRoger Chen {
969ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
970ba289af8SRoger Chen 
971ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
972ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
973ba289af8SRoger Chen 		return;
974ba289af8SRoger Chen 	}
975ba289af8SRoger Chen 
976ba289af8SRoger Chen 	if (speed == 10)
977ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
978ba289af8SRoger Chen 			     RK3399_GMAC_CLK_2_5M);
979ba289af8SRoger Chen 	else if (speed == 100)
980ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
981ba289af8SRoger Chen 			     RK3399_GMAC_CLK_25M);
982ba289af8SRoger Chen 	else if (speed == 1000)
983ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
984ba289af8SRoger Chen 			     RK3399_GMAC_CLK_125M);
985ba289af8SRoger Chen 	else
986ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
987ba289af8SRoger Chen }
988ba289af8SRoger Chen 
989ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
990ba289af8SRoger Chen {
991ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
992ba289af8SRoger Chen 
993ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
994ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
995ba289af8SRoger Chen 		return;
996ba289af8SRoger Chen 	}
997ba289af8SRoger Chen 
998ba289af8SRoger Chen 	if (speed == 10) {
999ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
1000ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_2_5M |
1001ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_10M);
1002ba289af8SRoger Chen 	} else if (speed == 100) {
1003ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
1004ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_25M |
1005ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_100M);
1006ba289af8SRoger Chen 	} else {
1007ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
1008ba289af8SRoger Chen 	}
1009ba289af8SRoger Chen }
1010ba289af8SRoger Chen 
1011ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = {
1012ba289af8SRoger Chen 	.set_to_rgmii = rk3399_set_to_rgmii,
1013ba289af8SRoger Chen 	.set_to_rmii = rk3399_set_to_rmii,
1014ba289af8SRoger Chen 	.set_rgmii_speed = rk3399_set_rgmii_speed,
1015ba289af8SRoger Chen 	.set_rmii_speed = rk3399_set_rmii_speed,
1016ba289af8SRoger Chen };
1017ba289af8SRoger Chen 
10183bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON0		0x0380
10193bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON1		0x0384
10203bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON0		0x0388
10213bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON1		0x038c
10223bb3d6b1SDavid Wu 
10233bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
10243bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RGMII	\
10253bb3d6b1SDavid Wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
10263bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RMII	\
10273bb3d6b1SDavid Wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
10283bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
10293bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
10303bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
10313bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_DISABLE		GRF_CLR_BIT(1)
10323bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_ENABLE		GRF_BIT(0)
10333bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_DISABLE		GRF_CLR_BIT(0)
10343bb3d6b1SDavid Wu 
10353bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
10363bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
10373bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
10383bb3d6b1SDavid Wu 
10393bb3d6b1SDavid Wu static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,
10403bb3d6b1SDavid Wu 				int tx_delay, int rx_delay)
10413bb3d6b1SDavid Wu {
10423bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10433bb3d6b1SDavid Wu 	u32 con0, con1;
10443bb3d6b1SDavid Wu 
10453bb3d6b1SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10463bb3d6b1SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
10473bb3d6b1SDavid Wu 		return;
10483bb3d6b1SDavid Wu 	}
10493bb3d6b1SDavid Wu 
10503bb3d6b1SDavid Wu 	con0 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON0 :
10513bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON0;
10523bb3d6b1SDavid Wu 	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10533bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON1;
10543bb3d6b1SDavid Wu 
10553bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con0,
10563bb3d6b1SDavid Wu 		     RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) |
10573bb3d6b1SDavid Wu 		     RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
10583bb3d6b1SDavid Wu 
10593bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con1,
10603bb3d6b1SDavid Wu 		     RK3568_GMAC_PHY_INTF_SEL_RGMII |
10613bb3d6b1SDavid Wu 		     RK3568_GMAC_RXCLK_DLY_ENABLE |
10623bb3d6b1SDavid Wu 		     RK3568_GMAC_TXCLK_DLY_ENABLE);
10633bb3d6b1SDavid Wu }
10643bb3d6b1SDavid Wu 
10653bb3d6b1SDavid Wu static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv)
10663bb3d6b1SDavid Wu {
10673bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10683bb3d6b1SDavid Wu 	u32 con1;
10693bb3d6b1SDavid Wu 
10703bb3d6b1SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10713bb3d6b1SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
10723bb3d6b1SDavid Wu 		return;
10733bb3d6b1SDavid Wu 	}
10743bb3d6b1SDavid Wu 
10753bb3d6b1SDavid Wu 	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10763bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON1;
10773bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
10783bb3d6b1SDavid Wu }
10793bb3d6b1SDavid Wu 
10803bb3d6b1SDavid Wu static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
10813bb3d6b1SDavid Wu {
1082ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
10833bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10843bb3d6b1SDavid Wu 	unsigned long rate;
10853bb3d6b1SDavid Wu 	int ret;
10863bb3d6b1SDavid Wu 
10873bb3d6b1SDavid Wu 	switch (speed) {
10883bb3d6b1SDavid Wu 	case 10:
10893bb3d6b1SDavid Wu 		rate = 2500000;
10903bb3d6b1SDavid Wu 		break;
10913bb3d6b1SDavid Wu 	case 100:
10923bb3d6b1SDavid Wu 		rate = 25000000;
10933bb3d6b1SDavid Wu 		break;
10943bb3d6b1SDavid Wu 	case 1000:
10953bb3d6b1SDavid Wu 		rate = 125000000;
10963bb3d6b1SDavid Wu 		break;
10973bb3d6b1SDavid Wu 	default:
10983bb3d6b1SDavid Wu 		dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
10993bb3d6b1SDavid Wu 		return;
11003bb3d6b1SDavid Wu 	}
11013bb3d6b1SDavid Wu 
1102ea449f7fSSebastian Reichel 	ret = clk_set_rate(clk_mac_speed, rate);
11033bb3d6b1SDavid Wu 	if (ret)
11043bb3d6b1SDavid Wu 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
11053bb3d6b1SDavid Wu 			__func__, rate, ret);
11063bb3d6b1SDavid Wu }
11073bb3d6b1SDavid Wu 
11083bb3d6b1SDavid Wu static const struct rk_gmac_ops rk3568_ops = {
11093bb3d6b1SDavid Wu 	.set_to_rgmii = rk3568_set_to_rgmii,
11103bb3d6b1SDavid Wu 	.set_to_rmii = rk3568_set_to_rmii,
11113bb3d6b1SDavid Wu 	.set_rgmii_speed = rk3568_set_gmac_speed,
11123bb3d6b1SDavid Wu 	.set_rmii_speed = rk3568_set_gmac_speed,
11130546b224SJohn Keeping 	.regs_valid = true,
11143bb3d6b1SDavid Wu 	.regs = {
11153bb3d6b1SDavid Wu 		0xfe2a0000, /* gmac0 */
11163bb3d6b1SDavid Wu 		0xfe010000, /* gmac1 */
11173bb3d6b1SDavid Wu 		0x0, /* sentinel */
11183bb3d6b1SDavid Wu 	},
11193bb3d6b1SDavid Wu };
11203bb3d6b1SDavid Wu 
11212f2b60a0SDavid Wu /* sys_grf */
11222f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON7			0X031c
11232f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON8			0X0320
11242f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON9			0X0324
11252f2b60a0SDavid Wu 
11262f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 3)
11272f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 3)
11282f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 2)
11292f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 2)
11302f2b60a0SDavid Wu 
11312f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 8)
11322f2b60a0SDavid Wu #define RK3588_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 0)
11332f2b60a0SDavid Wu 
11342f2b60a0SDavid Wu /* php_grf */
11352f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON0			0X0008
11362f2b60a0SDavid Wu #define RK3588_GRF_CLK_CON1			0X0070
11372f2b60a0SDavid Wu 
11382f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
11392f2b60a0SDavid Wu 	(GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
11402f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
11412f2b60a0SDavid Wu 	(GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
11422f2b60a0SDavid Wu 
11432f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
11442f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
11452f2b60a0SDavid Wu 
11462f2b60a0SDavid Wu #define RK3588_GMAC_CLK_SELET_CRU(id)		GRF_BIT(5 * (id) + 4)
11472f2b60a0SDavid Wu #define RK3588_GMAC_CLK_SELET_IO(id)		GRF_CLR_BIT(5 * (id) + 4)
11482f2b60a0SDavid Wu 
11492f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV2(id)		GRF_BIT(5 * (id) + 2)
11502f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV20(id)		GRF_CLR_BIT(5 * (id) + 2)
11512f2b60a0SDavid Wu 
11522f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV1(id)		\
11532f2b60a0SDavid Wu 			(GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
11542f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV5(id)		\
11552f2b60a0SDavid Wu 			(GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
11562f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV50(id)		\
11572f2b60a0SDavid Wu 			(GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
11582f2b60a0SDavid Wu 
11592f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_GATE(id)		GRF_BIT(5 * (id) + 1)
11602f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_NOGATE(id)		GRF_CLR_BIT(5 * (id) + 1)
11612f2b60a0SDavid Wu 
11622f2b60a0SDavid Wu static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
11632f2b60a0SDavid Wu 				int tx_delay, int rx_delay)
11642f2b60a0SDavid Wu {
11652f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
11662f2b60a0SDavid Wu 	u32 offset_con, id = bsp_priv->id;
11672f2b60a0SDavid Wu 
11682f2b60a0SDavid Wu 	if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
11692f2b60a0SDavid Wu 		dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n");
11702f2b60a0SDavid Wu 		return;
11712f2b60a0SDavid Wu 	}
11722f2b60a0SDavid Wu 
11732f2b60a0SDavid Wu 	offset_con = bsp_priv->id == 1 ? RK3588_GRF_GMAC_CON9 :
11742f2b60a0SDavid Wu 					 RK3588_GRF_GMAC_CON8;
11752f2b60a0SDavid Wu 
11762f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
11772f2b60a0SDavid Wu 		     RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
11782f2b60a0SDavid Wu 
11792f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
11802f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RGMII_MODE(id));
11812f2b60a0SDavid Wu 
11822f2b60a0SDavid Wu 	regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7,
11832f2b60a0SDavid Wu 		     RK3588_GMAC_RXCLK_DLY_ENABLE(id) |
11842f2b60a0SDavid Wu 		     RK3588_GMAC_TXCLK_DLY_ENABLE(id));
11852f2b60a0SDavid Wu 
11862f2b60a0SDavid Wu 	regmap_write(bsp_priv->grf, offset_con,
11872f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
11882f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
11892f2b60a0SDavid Wu }
11902f2b60a0SDavid Wu 
11912f2b60a0SDavid Wu static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv)
11922f2b60a0SDavid Wu {
11932f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
11942f2b60a0SDavid Wu 
11952f2b60a0SDavid Wu 	if (IS_ERR(bsp_priv->php_grf)) {
11962f2b60a0SDavid Wu 		dev_err(dev, "%s: Missing rockchip,php_grf property\n", __func__);
11972f2b60a0SDavid Wu 		return;
11982f2b60a0SDavid Wu 	}
11992f2b60a0SDavid Wu 
12002f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
12012f2b60a0SDavid Wu 		     RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->id));
12022f2b60a0SDavid Wu 
12032f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
12042f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id));
12052f2b60a0SDavid Wu }
12062f2b60a0SDavid Wu 
12072f2b60a0SDavid Wu static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
12082f2b60a0SDavid Wu {
12092f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
12102f2b60a0SDavid Wu 	unsigned int val = 0, id = bsp_priv->id;
12112f2b60a0SDavid Wu 
12122f2b60a0SDavid Wu 	switch (speed) {
12132f2b60a0SDavid Wu 	case 10:
12142f2b60a0SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
12152f2b60a0SDavid Wu 			val = RK3588_GMA_CLK_RMII_DIV20(id);
12162f2b60a0SDavid Wu 		else
12172f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV50(id);
12182f2b60a0SDavid Wu 		break;
12192f2b60a0SDavid Wu 	case 100:
12202f2b60a0SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
12212f2b60a0SDavid Wu 			val = RK3588_GMA_CLK_RMII_DIV2(id);
12222f2b60a0SDavid Wu 		else
12232f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV5(id);
12242f2b60a0SDavid Wu 		break;
12252f2b60a0SDavid Wu 	case 1000:
12262f2b60a0SDavid Wu 		if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
12272f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV1(id);
12282f2b60a0SDavid Wu 		else
12292f2b60a0SDavid Wu 			goto err;
12302f2b60a0SDavid Wu 		break;
12312f2b60a0SDavid Wu 	default:
12322f2b60a0SDavid Wu 		goto err;
12332f2b60a0SDavid Wu 	}
12342f2b60a0SDavid Wu 
12352f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
12362f2b60a0SDavid Wu 
12372f2b60a0SDavid Wu 	return;
12382f2b60a0SDavid Wu err:
12392f2b60a0SDavid Wu 	dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
12402f2b60a0SDavid Wu }
12412f2b60a0SDavid Wu 
12422f2b60a0SDavid Wu static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input,
12432f2b60a0SDavid Wu 				       bool enable)
12442f2b60a0SDavid Wu {
12452f2b60a0SDavid Wu 	unsigned int val = input ? RK3588_GMAC_CLK_SELET_IO(bsp_priv->id) :
12462f2b60a0SDavid Wu 				   RK3588_GMAC_CLK_SELET_CRU(bsp_priv->id);
12472f2b60a0SDavid Wu 
12482f2b60a0SDavid Wu 	val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->id) :
12492f2b60a0SDavid Wu 			RK3588_GMAC_CLK_RMII_GATE(bsp_priv->id);
12502f2b60a0SDavid Wu 
12512f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
12522f2b60a0SDavid Wu }
12532f2b60a0SDavid Wu 
12542f2b60a0SDavid Wu static const struct rk_gmac_ops rk3588_ops = {
12552f2b60a0SDavid Wu 	.set_to_rgmii = rk3588_set_to_rgmii,
12562f2b60a0SDavid Wu 	.set_to_rmii = rk3588_set_to_rmii,
12572f2b60a0SDavid Wu 	.set_rgmii_speed = rk3588_set_gmac_speed,
12582f2b60a0SDavid Wu 	.set_rmii_speed = rk3588_set_gmac_speed,
12592f2b60a0SDavid Wu 	.set_clock_selection = rk3588_set_clock_selection,
126088619e77SBenjamin Gaignard 	.regs_valid = true,
126188619e77SBenjamin Gaignard 	.regs = {
126288619e77SBenjamin Gaignard 		0xfe1b0000, /* gmac0 */
126388619e77SBenjamin Gaignard 		0xfe1c0000, /* gmac1 */
126488619e77SBenjamin Gaignard 		0x0, /* sentinel */
126588619e77SBenjamin Gaignard 	},
12662f2b60a0SDavid Wu };
12672f2b60a0SDavid Wu 
126889c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0		0X0900
126989c9c163SDavid Wu 
127089c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */
127189c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
127289c9c163SDavid Wu 					GRF_BIT(6))
127389c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
127489c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
127589c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
127689c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M		GRF_BIT(2)
127789c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M	GRF_BIT(7)
127889c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
127989c9c163SDavid Wu 
128089c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
128189c9c163SDavid Wu {
128289c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
128389c9c163SDavid Wu 
128489c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
128589c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
128689c9c163SDavid Wu 		return;
128789c9c163SDavid Wu 	}
128889c9c163SDavid Wu 
128989c9c163SDavid Wu 	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
129089c9c163SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
129189c9c163SDavid Wu }
129289c9c163SDavid Wu 
129389c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
129489c9c163SDavid Wu {
129589c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
129689c9c163SDavid Wu 
129789c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
129889c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
129989c9c163SDavid Wu 		return;
130089c9c163SDavid Wu 	}
130189c9c163SDavid Wu 
130289c9c163SDavid Wu 	if (speed == 10) {
130389c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
130489c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_2_5M |
130589c9c163SDavid Wu 			     RV1108_GMAC_SPEED_10M);
130689c9c163SDavid Wu 	} else if (speed == 100) {
130789c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
130889c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_25M |
130989c9c163SDavid Wu 			     RV1108_GMAC_SPEED_100M);
131089c9c163SDavid Wu 	} else {
131189c9c163SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
131289c9c163SDavid Wu 	}
131389c9c163SDavid Wu }
131489c9c163SDavid Wu 
131589c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = {
131689c9c163SDavid Wu 	.set_to_rmii = rv1108_set_to_rmii,
131789c9c163SDavid Wu 	.set_rmii_speed = rv1108_set_rmii_speed,
131889c9c163SDavid Wu };
131989c9c163SDavid Wu 
1320c931b060SAnand Moon #define RV1126_GRF_GMAC_CON0		0X0070
1321c931b060SAnand Moon #define RV1126_GRF_GMAC_CON1		0X0074
1322c931b060SAnand Moon #define RV1126_GRF_GMAC_CON2		0X0078
1323c931b060SAnand Moon 
1324c931b060SAnand Moon /* RV1126_GRF_GMAC_CON0 */
1325c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RGMII	\
1326c931b060SAnand Moon 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
1327c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RMII	\
1328c931b060SAnand Moon 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
1329c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL			GRF_BIT(7)
1330c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(7)
1331c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE		GRF_BIT(1)
1332c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
1333c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_ENABLE		GRF_BIT(0)
1334c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
1335c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_ENABLE		GRF_BIT(3)
1336c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_DISABLE	GRF_CLR_BIT(3)
1337c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_ENABLE		GRF_BIT(2)
1338c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_DISABLE	GRF_CLR_BIT(2)
1339c931b060SAnand Moon 
1340c931b060SAnand Moon /* RV1126_GRF_GMAC_CON1 */
1341c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
1342c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
1343c931b060SAnand Moon /* RV1126_GRF_GMAC_CON2 */
1344c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
1345c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
1346c931b060SAnand Moon 
1347c931b060SAnand Moon static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
1348c931b060SAnand Moon 				int tx_delay, int rx_delay)
1349c931b060SAnand Moon {
1350c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1351c931b060SAnand Moon 
1352c931b060SAnand Moon 	if (IS_ERR(bsp_priv->grf)) {
1353c931b060SAnand Moon 		dev_err(dev, "Missing rockchip,grf property\n");
1354c931b060SAnand Moon 		return;
1355c931b060SAnand Moon 	}
1356c931b060SAnand Moon 
1357c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1358c931b060SAnand Moon 		     RV1126_GMAC_PHY_INTF_SEL_RGMII |
1359c931b060SAnand Moon 		     RV1126_GMAC_M0_RXCLK_DLY_ENABLE |
1360c931b060SAnand Moon 		     RV1126_GMAC_M0_TXCLK_DLY_ENABLE |
1361c931b060SAnand Moon 		     RV1126_GMAC_M1_RXCLK_DLY_ENABLE |
1362c931b060SAnand Moon 		     RV1126_GMAC_M1_TXCLK_DLY_ENABLE);
1363c931b060SAnand Moon 
1364c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1,
1365c931b060SAnand Moon 		     RV1126_GMAC_M0_CLK_RX_DL_CFG(rx_delay) |
1366c931b060SAnand Moon 		     RV1126_GMAC_M0_CLK_TX_DL_CFG(tx_delay));
1367c931b060SAnand Moon 
1368c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2,
1369c931b060SAnand Moon 		     RV1126_GMAC_M1_CLK_RX_DL_CFG(rx_delay) |
1370c931b060SAnand Moon 		     RV1126_GMAC_M1_CLK_TX_DL_CFG(tx_delay));
1371c931b060SAnand Moon }
1372c931b060SAnand Moon 
1373c931b060SAnand Moon static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv)
1374c931b060SAnand Moon {
1375c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1376c931b060SAnand Moon 
1377c931b060SAnand Moon 	if (IS_ERR(bsp_priv->grf)) {
1378c931b060SAnand Moon 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1379c931b060SAnand Moon 		return;
1380c931b060SAnand Moon 	}
1381c931b060SAnand Moon 
1382c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1383c931b060SAnand Moon 		     RV1126_GMAC_PHY_INTF_SEL_RMII);
1384c931b060SAnand Moon }
1385c931b060SAnand Moon 
1386c931b060SAnand Moon static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
1387c931b060SAnand Moon {
1388ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
1389c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1390c931b060SAnand Moon 	unsigned long rate;
1391c931b060SAnand Moon 	int ret;
1392c931b060SAnand Moon 
1393c931b060SAnand Moon 	switch (speed) {
1394c931b060SAnand Moon 	case 10:
1395c931b060SAnand Moon 		rate = 2500000;
1396c931b060SAnand Moon 		break;
1397c931b060SAnand Moon 	case 100:
1398c931b060SAnand Moon 		rate = 25000000;
1399c931b060SAnand Moon 		break;
1400c931b060SAnand Moon 	case 1000:
1401c931b060SAnand Moon 		rate = 125000000;
1402c931b060SAnand Moon 		break;
1403c931b060SAnand Moon 	default:
1404c931b060SAnand Moon 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1405c931b060SAnand Moon 		return;
1406c931b060SAnand Moon 	}
1407c931b060SAnand Moon 
1408ea449f7fSSebastian Reichel 	ret = clk_set_rate(clk_mac_speed, rate);
1409c931b060SAnand Moon 	if (ret)
1410c931b060SAnand Moon 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1411c931b060SAnand Moon 			__func__, rate, ret);
1412c931b060SAnand Moon }
1413c931b060SAnand Moon 
1414c931b060SAnand Moon static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
1415c931b060SAnand Moon {
1416ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
1417c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1418c931b060SAnand Moon 	unsigned long rate;
1419c931b060SAnand Moon 	int ret;
1420c931b060SAnand Moon 
1421c931b060SAnand Moon 	switch (speed) {
1422c931b060SAnand Moon 	case 10:
1423c931b060SAnand Moon 		rate = 2500000;
1424c931b060SAnand Moon 		break;
1425c931b060SAnand Moon 	case 100:
1426c931b060SAnand Moon 		rate = 25000000;
1427c931b060SAnand Moon 		break;
1428c931b060SAnand Moon 	default:
1429c931b060SAnand Moon 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1430c931b060SAnand Moon 		return;
1431c931b060SAnand Moon 	}
1432c931b060SAnand Moon 
1433ea449f7fSSebastian Reichel 	ret = clk_set_rate(clk_mac_speed, rate);
1434c931b060SAnand Moon 	if (ret)
1435c931b060SAnand Moon 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1436c931b060SAnand Moon 			__func__, rate, ret);
1437c931b060SAnand Moon }
1438c931b060SAnand Moon 
1439c931b060SAnand Moon static const struct rk_gmac_ops rv1126_ops = {
1440c931b060SAnand Moon 	.set_to_rgmii = rv1126_set_to_rgmii,
1441c931b060SAnand Moon 	.set_to_rmii = rv1126_set_to_rmii,
1442c931b060SAnand Moon 	.set_rgmii_speed = rv1126_set_rgmii_speed,
1443c931b060SAnand Moon 	.set_rmii_speed = rv1126_set_rmii_speed,
1444c931b060SAnand Moon };
1445c931b060SAnand Moon 
1446fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0		0xb00
1447fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1		0xb04
1448fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2		0xb08
1449fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3		0xb0c
1450fecd4d7eSDavid Wu 
1451fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE		GRF_BIT(0)
1452fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
1453fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
1454fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
1455fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID		HIWORD_UPDATE(0x1234, 0xffff, 0)
1456fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID		HIWORD_UPDATE(0x35, 0x3f, 0)
1457fecd4d7eSDavid Wu 
1458fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
14597ad269eaSRoger Chen {
1460fecd4d7eSDavid Wu 	if (priv->ops->integrated_phy_powerup)
1461fecd4d7eSDavid Wu 		priv->ops->integrated_phy_powerup(priv);
1462fecd4d7eSDavid Wu 
1463fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
1464fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
1465fecd4d7eSDavid Wu 
1466fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
1467fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
1468fecd4d7eSDavid Wu 
1469fecd4d7eSDavid Wu 	if (priv->phy_reset) {
1470fecd4d7eSDavid Wu 		/* PHY needs to be disabled before trying to reset it */
1471fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1472fecd4d7eSDavid Wu 		if (priv->phy_reset)
1473fecd4d7eSDavid Wu 			reset_control_assert(priv->phy_reset);
1474fecd4d7eSDavid Wu 		usleep_range(10, 20);
1475fecd4d7eSDavid Wu 		if (priv->phy_reset)
1476fecd4d7eSDavid Wu 			reset_control_deassert(priv->phy_reset);
1477fecd4d7eSDavid Wu 		usleep_range(10, 20);
1478fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
1479fecd4d7eSDavid Wu 		msleep(30);
1480fecd4d7eSDavid Wu 	}
1481fecd4d7eSDavid Wu }
1482fecd4d7eSDavid Wu 
1483fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
1484fecd4d7eSDavid Wu {
1485fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1486fecd4d7eSDavid Wu 	if (priv->phy_reset)
1487fecd4d7eSDavid Wu 		reset_control_assert(priv->phy_reset);
1488fecd4d7eSDavid Wu }
1489fecd4d7eSDavid Wu 
1490fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
1491fecd4d7eSDavid Wu {
1492fecd4d7eSDavid Wu 	struct rk_priv_data *bsp_priv = plat->bsp_priv;
14937ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
1494ea449f7fSSebastian Reichel 	int phy_iface = bsp_priv->phy_iface;
1495ea449f7fSSebastian Reichel 	int i, j, ret;
14967ad269eaSRoger Chen 
14977ad269eaSRoger Chen 	bsp_priv->clk_enabled = false;
14987ad269eaSRoger Chen 
1499ea449f7fSSebastian Reichel 	bsp_priv->num_clks = ARRAY_SIZE(rk_clocks);
1500ea449f7fSSebastian Reichel 	if (phy_iface == PHY_INTERFACE_MODE_RMII)
1501ea449f7fSSebastian Reichel 		bsp_priv->num_clks += ARRAY_SIZE(rk_rmii_clocks);
15027ad269eaSRoger Chen 
1503ea449f7fSSebastian Reichel 	bsp_priv->clks = devm_kcalloc(dev, bsp_priv->num_clks,
1504ea449f7fSSebastian Reichel 				      sizeof(*bsp_priv->clks), GFP_KERNEL);
1505ea449f7fSSebastian Reichel 	if (!bsp_priv->clks)
1506ea449f7fSSebastian Reichel 		return -ENOMEM;
15077ad269eaSRoger Chen 
1508ea449f7fSSebastian Reichel 	for (i = 0; i < ARRAY_SIZE(rk_clocks); i++)
1509ea449f7fSSebastian Reichel 		bsp_priv->clks[i].id = rk_clocks[i];
15107ad269eaSRoger Chen 
1511ea449f7fSSebastian Reichel 	if (phy_iface == PHY_INTERFACE_MODE_RMII) {
1512ea449f7fSSebastian Reichel 		for (j = 0; j < ARRAY_SIZE(rk_rmii_clocks); j++)
1513ea449f7fSSebastian Reichel 			bsp_priv->clks[i++].id = rk_rmii_clocks[j];
1514ea449f7fSSebastian Reichel 	}
15157ad269eaSRoger Chen 
1516ea449f7fSSebastian Reichel 	ret = devm_clk_bulk_get_optional(dev, bsp_priv->num_clks,
1517ea449f7fSSebastian Reichel 					 bsp_priv->clks);
1518ea449f7fSSebastian Reichel 	if (ret)
1519ea449f7fSSebastian Reichel 		return dev_err_probe(dev, ret, "Failed to get clocks\n");
1520ea449f7fSSebastian Reichel 
1521ea449f7fSSebastian Reichel 	/* "stmmaceth" will be enabled by the core */
15227ad269eaSRoger Chen 	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
1523ea449f7fSSebastian Reichel 	ret = PTR_ERR_OR_ZERO(bsp_priv->clk_mac);
1524ea449f7fSSebastian Reichel 	if (ret)
1525ea449f7fSSebastian Reichel 		return dev_err_probe(dev, ret, "Cannot get stmmaceth clock\n");
152623c94d63SDavid Wu 
15277ad269eaSRoger Chen 	if (bsp_priv->clock_input) {
1528d42202dcSRomain Perier 		dev_info(dev, "clock input from PHY\n");
1529ea449f7fSSebastian Reichel 	} else if (phy_iface == PHY_INTERFACE_MODE_RMII) {
1530c48fa33cSHeiko Stübner 		clk_set_rate(bsp_priv->clk_mac, 50000000);
15317ad269eaSRoger Chen 	}
15327ad269eaSRoger Chen 
1533fecd4d7eSDavid Wu 	if (plat->phy_node && bsp_priv->integrated_phy) {
1534fecd4d7eSDavid Wu 		bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
1535ea449f7fSSebastian Reichel 		ret = PTR_ERR_OR_ZERO(bsp_priv->clk_phy);
1536ea449f7fSSebastian Reichel 		if (ret)
1537ea449f7fSSebastian Reichel 			return dev_err_probe(dev, ret, "Cannot get PHY clock\n");
1538fecd4d7eSDavid Wu 		clk_set_rate(bsp_priv->clk_phy, 50000000);
1539fecd4d7eSDavid Wu 	}
1540fecd4d7eSDavid Wu 
15417ad269eaSRoger Chen 	return 0;
15427ad269eaSRoger Chen }
15437ad269eaSRoger Chen 
15447ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
15457ad269eaSRoger Chen {
1546ea449f7fSSebastian Reichel 	int ret;
15477ad269eaSRoger Chen 
15487ad269eaSRoger Chen 	if (enable) {
15497ad269eaSRoger Chen 		if (!bsp_priv->clk_enabled) {
1550ea449f7fSSebastian Reichel 			ret = clk_bulk_prepare_enable(bsp_priv->num_clks,
1551ea449f7fSSebastian Reichel 						      bsp_priv->clks);
1552ea449f7fSSebastian Reichel 			if (ret)
1553ea449f7fSSebastian Reichel 				return ret;
15547ad269eaSRoger Chen 
1555ea449f7fSSebastian Reichel 			ret = clk_prepare_enable(bsp_priv->clk_phy);
1556ea449f7fSSebastian Reichel 			if (ret)
1557ea449f7fSSebastian Reichel 				return ret;
155823c94d63SDavid Wu 
15592f2b60a0SDavid Wu 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
15602f2b60a0SDavid Wu 				bsp_priv->ops->set_clock_selection(bsp_priv,
15612f2b60a0SDavid Wu 					       bsp_priv->clock_input, true);
15622f2b60a0SDavid Wu 
15637ad269eaSRoger Chen 			mdelay(5);
15647ad269eaSRoger Chen 			bsp_priv->clk_enabled = true;
15657ad269eaSRoger Chen 		}
15667ad269eaSRoger Chen 	} else {
15677ad269eaSRoger Chen 		if (bsp_priv->clk_enabled) {
1568ea449f7fSSebastian Reichel 			clk_bulk_disable_unprepare(bsp_priv->num_clks,
1569ea449f7fSSebastian Reichel 						   bsp_priv->clks);
1570fecd4d7eSDavid Wu 			clk_disable_unprepare(bsp_priv->clk_phy);
1571fecd4d7eSDavid Wu 
15722f2b60a0SDavid Wu 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
15732f2b60a0SDavid Wu 				bsp_priv->ops->set_clock_selection(bsp_priv,
15742f2b60a0SDavid Wu 					      bsp_priv->clock_input, false);
1575ea449f7fSSebastian Reichel 
15767ad269eaSRoger Chen 			bsp_priv->clk_enabled = false;
15777ad269eaSRoger Chen 		}
15787ad269eaSRoger Chen 	}
15797ad269eaSRoger Chen 
15807ad269eaSRoger Chen 	return 0;
15817ad269eaSRoger Chen }
15827ad269eaSRoger Chen 
15837ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
15847ad269eaSRoger Chen {
15852e12f536SRomain Perier 	struct regulator *ldo = bsp_priv->regulator;
15867ad269eaSRoger Chen 	int ret;
15877ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
15887ad269eaSRoger Chen 
15897ad269eaSRoger Chen 	if (enable) {
15907ad269eaSRoger Chen 		ret = regulator_enable(ldo);
15912e12f536SRomain Perier 		if (ret)
1592d42202dcSRomain Perier 			dev_err(dev, "fail to enable phy-supply\n");
15937ad269eaSRoger Chen 	} else {
15947ad269eaSRoger Chen 		ret = regulator_disable(ldo);
15952e12f536SRomain Perier 		if (ret)
1596d42202dcSRomain Perier 			dev_err(dev, "fail to disable phy-supply\n");
15977ad269eaSRoger Chen 	}
15987ad269eaSRoger Chen 
15997ad269eaSRoger Chen 	return 0;
16007ad269eaSRoger Chen }
16017ad269eaSRoger Chen 
16020fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1603fecd4d7eSDavid Wu 					  struct plat_stmmacenet_data *plat,
160492c2588fSJoachim Eastwood 					  const struct rk_gmac_ops *ops)
16057ad269eaSRoger Chen {
16067ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv;
16077ad269eaSRoger Chen 	struct device *dev = &pdev->dev;
16083bb3d6b1SDavid Wu 	struct resource *res;
16097ad269eaSRoger Chen 	int ret;
16107ad269eaSRoger Chen 	const char *strings = NULL;
16117ad269eaSRoger Chen 	int value;
16127ad269eaSRoger Chen 
16137ad269eaSRoger Chen 	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
16147ad269eaSRoger Chen 	if (!bsp_priv)
16157ad269eaSRoger Chen 		return ERR_PTR(-ENOMEM);
16167ad269eaSRoger Chen 
16170c65b2b9SAndrew Lunn 	of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
16180fb98db1SHeiko Stübner 	bsp_priv->ops = ops;
16197ad269eaSRoger Chen 
16203bb3d6b1SDavid Wu 	/* Some SoCs have multiple MAC controllers, which need
16213bb3d6b1SDavid Wu 	 * to be distinguished.
16223bb3d6b1SDavid Wu 	 */
16233bb3d6b1SDavid Wu 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
16240546b224SJohn Keeping 	if (res && ops->regs_valid) {
16253bb3d6b1SDavid Wu 		int i = 0;
16263bb3d6b1SDavid Wu 
16273bb3d6b1SDavid Wu 		while (ops->regs[i]) {
16283bb3d6b1SDavid Wu 			if (ops->regs[i] == res->start) {
16293bb3d6b1SDavid Wu 				bsp_priv->id = i;
16303bb3d6b1SDavid Wu 				break;
16313bb3d6b1SDavid Wu 			}
16323bb3d6b1SDavid Wu 			i++;
16333bb3d6b1SDavid Wu 		}
16343bb3d6b1SDavid Wu 	}
16353bb3d6b1SDavid Wu 
1636db219732SSebastian Reichel 	bsp_priv->regulator = devm_regulator_get(dev, "phy");
16372e12f536SRomain Perier 	if (IS_ERR(bsp_priv->regulator)) {
1638db219732SSebastian Reichel 		ret = PTR_ERR(bsp_priv->regulator);
1639db219732SSebastian Reichel 		dev_err_probe(dev, ret, "failed to get phy regulator\n");
1640db219732SSebastian Reichel 		return ERR_PTR(ret);
16417ad269eaSRoger Chen 	}
16427ad269eaSRoger Chen 
16437ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
16447ad269eaSRoger Chen 	if (ret) {
1645d42202dcSRomain Perier 		dev_err(dev, "Can not read property: clock_in_out.\n");
16467ad269eaSRoger Chen 		bsp_priv->clock_input = true;
16477ad269eaSRoger Chen 	} else {
1648d42202dcSRomain Perier 		dev_info(dev, "clock input or output? (%s).\n",
1649d42202dcSRomain Perier 			 strings);
16507ad269eaSRoger Chen 		if (!strcmp(strings, "input"))
16517ad269eaSRoger Chen 			bsp_priv->clock_input = true;
16527ad269eaSRoger Chen 		else
16537ad269eaSRoger Chen 			bsp_priv->clock_input = false;
16547ad269eaSRoger Chen 	}
16557ad269eaSRoger Chen 
16567ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
16577ad269eaSRoger Chen 	if (ret) {
16587ad269eaSRoger Chen 		bsp_priv->tx_delay = 0x30;
1659d42202dcSRomain Perier 		dev_err(dev, "Can not read property: tx_delay.");
1660d42202dcSRomain Perier 		dev_err(dev, "set tx_delay to 0x%x\n",
1661d42202dcSRomain Perier 			bsp_priv->tx_delay);
16627ad269eaSRoger Chen 	} else {
1663d42202dcSRomain Perier 		dev_info(dev, "TX delay(0x%x).\n", value);
16647ad269eaSRoger Chen 		bsp_priv->tx_delay = value;
16657ad269eaSRoger Chen 	}
16667ad269eaSRoger Chen 
16677ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
16687ad269eaSRoger Chen 	if (ret) {
16697ad269eaSRoger Chen 		bsp_priv->rx_delay = 0x10;
1670d42202dcSRomain Perier 		dev_err(dev, "Can not read property: rx_delay.");
1671d42202dcSRomain Perier 		dev_err(dev, "set rx_delay to 0x%x\n",
1672d42202dcSRomain Perier 			bsp_priv->rx_delay);
16737ad269eaSRoger Chen 	} else {
1674d42202dcSRomain Perier 		dev_info(dev, "RX delay(0x%x).\n", value);
16757ad269eaSRoger Chen 		bsp_priv->rx_delay = value;
16767ad269eaSRoger Chen 	}
16777ad269eaSRoger Chen 
16787ad269eaSRoger Chen 	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
16797ad269eaSRoger Chen 							"rockchip,grf");
16802f2b60a0SDavid Wu 	bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
16812f2b60a0SDavid Wu 							    "rockchip,php-grf");
16827ad269eaSRoger Chen 
1683fecd4d7eSDavid Wu 	if (plat->phy_node) {
1684fecd4d7eSDavid Wu 		bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
1685fecd4d7eSDavid Wu 								 "phy-is-integrated");
1686fecd4d7eSDavid Wu 		if (bsp_priv->integrated_phy) {
1687fecd4d7eSDavid Wu 			bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
1688fecd4d7eSDavid Wu 			if (IS_ERR(bsp_priv->phy_reset)) {
1689fecd4d7eSDavid Wu 				dev_err(&pdev->dev, "No PHY reset control found.\n");
1690fecd4d7eSDavid Wu 				bsp_priv->phy_reset = NULL;
1691fecd4d7eSDavid Wu 			}
1692fecd4d7eSDavid Wu 		}
1693fecd4d7eSDavid Wu 	}
1694fecd4d7eSDavid Wu 	dev_info(dev, "integrated PHY? (%s).\n",
1695fecd4d7eSDavid Wu 		 bsp_priv->integrated_phy ? "yes" : "no");
1696fecd4d7eSDavid Wu 
1697fecd4d7eSDavid Wu 	bsp_priv->pdev = pdev;
169845383f52SRoger Chen 
169945383f52SRoger Chen 	return bsp_priv;
170045383f52SRoger Chen }
170145383f52SRoger Chen 
170237c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv)
170337c80d15SDavid Wu {
170437c80d15SDavid Wu 	switch (bsp_priv->phy_iface) {
170537c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII:
170637c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_ID:
170737c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_RXID:
170837c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_TXID:
170937c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rgmii)
171037c80d15SDavid Wu 			return -EINVAL;
171137c80d15SDavid Wu 		break;
171237c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RMII:
171337c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rmii)
171437c80d15SDavid Wu 			return -EINVAL;
171537c80d15SDavid Wu 		break;
171637c80d15SDavid Wu 	default:
171737c80d15SDavid Wu 		dev_err(&bsp_priv->pdev->dev,
171837c80d15SDavid Wu 			"unsupported interface %d", bsp_priv->phy_iface);
171937c80d15SDavid Wu 	}
172037c80d15SDavid Wu 	return 0;
172137c80d15SDavid Wu }
172237c80d15SDavid Wu 
172345383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
172445383f52SRoger Chen {
172545383f52SRoger Chen 	int ret;
172645383f52SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
172745383f52SRoger Chen 
172837c80d15SDavid Wu 	ret = rk_gmac_check_ops(bsp_priv);
172937c80d15SDavid Wu 	if (ret)
173037c80d15SDavid Wu 		return ret;
173137c80d15SDavid Wu 
1732f217bfdeSHeiko Stübner 	ret = gmac_clk_enable(bsp_priv, true);
1733f217bfdeSHeiko Stübner 	if (ret)
1734f217bfdeSHeiko Stübner 		return ret;
1735f217bfdeSHeiko Stübner 
17367ad269eaSRoger Chen 	/*rmii or rgmii*/
1737eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1738eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1739d42202dcSRomain Perier 		dev_info(dev, "init for RGMII\n");
17400fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
17410fb98db1SHeiko Stübner 					    bsp_priv->rx_delay);
1742eaf70ad1SWadim Egorov 		break;
1743eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1744eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_ID\n");
1745eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
1746eaf70ad1SWadim Egorov 		break;
1747eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1748eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_RXID\n");
1749eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
1750eaf70ad1SWadim Egorov 		break;
1751eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
1752eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_TXID\n");
1753eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
1754eaf70ad1SWadim Egorov 		break;
1755eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
1756d42202dcSRomain Perier 		dev_info(dev, "init for RMII\n");
17570fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rmii(bsp_priv);
1758eaf70ad1SWadim Egorov 		break;
1759eaf70ad1SWadim Egorov 	default:
1760d42202dcSRomain Perier 		dev_err(dev, "NO interface defined!\n");
17617ad269eaSRoger Chen 	}
17627ad269eaSRoger Chen 
17637ad269eaSRoger Chen 	ret = phy_power_on(bsp_priv, true);
1764c69c29a1SAlexey Khoroshilov 	if (ret) {
1765c69c29a1SAlexey Khoroshilov 		gmac_clk_enable(bsp_priv, false);
17667ad269eaSRoger Chen 		return ret;
1767c69c29a1SAlexey Khoroshilov 	}
17687ad269eaSRoger Chen 
1769aec3f415SPunit Agrawal 	pm_runtime_get_sync(dev);
1770aec3f415SPunit Agrawal 
1771fecd4d7eSDavid Wu 	if (bsp_priv->integrated_phy)
1772fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerup(bsp_priv);
1773fecd4d7eSDavid Wu 
17747ad269eaSRoger Chen 	return 0;
17757ad269eaSRoger Chen }
17767ad269eaSRoger Chen 
1777229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac)
17787ad269eaSRoger Chen {
1779fecd4d7eSDavid Wu 	if (gmac->integrated_phy)
1780fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerdown(gmac);
1781fecd4d7eSDavid Wu 
1782aec3f415SPunit Agrawal 	pm_runtime_put_sync(&gmac->pdev->dev);
1783aec3f415SPunit Agrawal 
17847ad269eaSRoger Chen 	phy_power_on(gmac, false);
17857ad269eaSRoger Chen 	gmac_clk_enable(gmac, false);
17867ad269eaSRoger Chen }
17877ad269eaSRoger Chen 
17887ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed)
17897ad269eaSRoger Chen {
17907ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
17917ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
17927ad269eaSRoger Chen 
1793eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1794eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1795eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1796eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1797eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
179837c80d15SDavid Wu 		if (bsp_priv->ops->set_rgmii_speed)
17990fb98db1SHeiko Stübner 			bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1800eaf70ad1SWadim Egorov 		break;
1801eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
180237c80d15SDavid Wu 		if (bsp_priv->ops->set_rmii_speed)
18030fb98db1SHeiko Stübner 			bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1804eaf70ad1SWadim Egorov 		break;
1805eaf70ad1SWadim Egorov 	default:
18067ad269eaSRoger Chen 		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
18077ad269eaSRoger Chen 	}
1808eaf70ad1SWadim Egorov }
18097ad269eaSRoger Chen 
181027ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev)
181127ffefd2SJoachim Eastwood {
181227ffefd2SJoachim Eastwood 	struct plat_stmmacenet_data *plat_dat;
181327ffefd2SJoachim Eastwood 	struct stmmac_resources stmmac_res;
1814f529f182SJoachim Eastwood 	const struct rk_gmac_ops *data;
181527ffefd2SJoachim Eastwood 	int ret;
181627ffefd2SJoachim Eastwood 
1817149adeddSJoachim Eastwood 	data = of_device_get_match_data(&pdev->dev);
1818149adeddSJoachim Eastwood 	if (!data) {
1819149adeddSJoachim Eastwood 		dev_err(&pdev->dev, "no of match data provided\n");
1820149adeddSJoachim Eastwood 		return -EINVAL;
1821149adeddSJoachim Eastwood 	}
1822149adeddSJoachim Eastwood 
182327ffefd2SJoachim Eastwood 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
182427ffefd2SJoachim Eastwood 	if (ret)
182527ffefd2SJoachim Eastwood 		return ret;
182627ffefd2SJoachim Eastwood 
182783216e39SMichael Walle 	plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
182827ffefd2SJoachim Eastwood 	if (IS_ERR(plat_dat))
182927ffefd2SJoachim Eastwood 		return PTR_ERR(plat_dat);
183027ffefd2SJoachim Eastwood 
1831d6b06251SEzequiel Garcia 	/* If the stmmac is not already selected as gmac4,
1832d6b06251SEzequiel Garcia 	 * then make sure we fallback to gmac.
1833d6b06251SEzequiel Garcia 	 */
1834d6b06251SEzequiel Garcia 	if (!plat_dat->has_gmac4)
183527ffefd2SJoachim Eastwood 		plat_dat->has_gmac = true;
183627ffefd2SJoachim Eastwood 	plat_dat->fix_mac_speed = rk_fix_speed;
183727ffefd2SJoachim Eastwood 
1838fecd4d7eSDavid Wu 	plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
1839d2ed0a77SJohan Hovold 	if (IS_ERR(plat_dat->bsp_priv)) {
1840d2ed0a77SJohan Hovold 		ret = PTR_ERR(plat_dat->bsp_priv);
1841d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
1842d2ed0a77SJohan Hovold 	}
184327ffefd2SJoachim Eastwood 
1844fecd4d7eSDavid Wu 	ret = rk_gmac_clk_init(plat_dat);
1845fecd4d7eSDavid Wu 	if (ret)
18469de9aa48SEmil Renner Berthing 		goto err_remove_config_dt;
1847fecd4d7eSDavid Wu 
184807a5e769SJoachim Eastwood 	ret = rk_gmac_powerup(plat_dat->bsp_priv);
184927ffefd2SJoachim Eastwood 	if (ret)
1850d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
185127ffefd2SJoachim Eastwood 
18522d222656SJohan Hovold 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
18532d222656SJohan Hovold 	if (ret)
18542745529aSDavid S. Miller 		goto err_gmac_powerdown;
18552d222656SJohan Hovold 
18562d222656SJohan Hovold 	return 0;
18572d222656SJohan Hovold 
18582745529aSDavid S. Miller err_gmac_powerdown:
18592745529aSDavid S. Miller 	rk_gmac_powerdown(plat_dat->bsp_priv);
1860d2ed0a77SJohan Hovold err_remove_config_dt:
1861d2ed0a77SJohan Hovold 	stmmac_remove_config_dt(pdev, plat_dat);
18622d222656SJohan Hovold 
18632d222656SJohan Hovold 	return ret;
186427ffefd2SJoachim Eastwood }
186527ffefd2SJoachim Eastwood 
1866*903cc461SUwe Kleine-König static void rk_gmac_remove(struct platform_device *pdev)
18670de8c4c9SJoachim Eastwood {
18680de8c4c9SJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
1869ff0011cfSUwe Kleine-König 
1870ff0011cfSUwe Kleine-König 	stmmac_dvr_remove(&pdev->dev);
18710de8c4c9SJoachim Eastwood 
18720de8c4c9SJoachim Eastwood 	rk_gmac_powerdown(bsp_priv);
18730de8c4c9SJoachim Eastwood }
18740de8c4c9SJoachim Eastwood 
18755619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP
18765619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev)
18775619468aSJoachim Eastwood {
18785619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
18795619468aSJoachim Eastwood 	int ret = stmmac_suspend(dev);
18805619468aSJoachim Eastwood 
18815619468aSJoachim Eastwood 	/* Keep the PHY up if we use Wake-on-Lan. */
18825619468aSJoachim Eastwood 	if (!device_may_wakeup(dev)) {
18835619468aSJoachim Eastwood 		rk_gmac_powerdown(bsp_priv);
18845619468aSJoachim Eastwood 		bsp_priv->suspended = true;
18855619468aSJoachim Eastwood 	}
18865619468aSJoachim Eastwood 
18875619468aSJoachim Eastwood 	return ret;
18885619468aSJoachim Eastwood }
18895619468aSJoachim Eastwood 
18905619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev)
18915619468aSJoachim Eastwood {
18925619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
18935619468aSJoachim Eastwood 
18945619468aSJoachim Eastwood 	/* The PHY was up for Wake-on-Lan. */
18955619468aSJoachim Eastwood 	if (bsp_priv->suspended) {
18965619468aSJoachim Eastwood 		rk_gmac_powerup(bsp_priv);
18975619468aSJoachim Eastwood 		bsp_priv->suspended = false;
18985619468aSJoachim Eastwood 	}
18995619468aSJoachim Eastwood 
19005619468aSJoachim Eastwood 	return stmmac_resume(dev);
19015619468aSJoachim Eastwood }
19025619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */
19035619468aSJoachim Eastwood 
19045619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
19055619468aSJoachim Eastwood 
1906e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = {
190723c94d63SDavid Wu 	{ .compatible = "rockchip,px30-gmac",	.data = &px30_ops   },
190805946876SDavid Wu 	{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
1909e7ffd812SXing Zheng 	{ .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
1910f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
1911b4ac9456STobias Schramm 	{ .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops },
1912d4ff816eSdavid.wu 	{ .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
1913ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
1914f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
1915ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
19163bb3d6b1SDavid Wu 	{ .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
19172f2b60a0SDavid Wu 	{ .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops },
191889c9c163SDavid Wu 	{ .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
1919c931b060SAnand Moon 	{ .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops },
1920e0fb4013SJoachim Eastwood 	{ }
1921e0fb4013SJoachim Eastwood };
1922e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
1923e0fb4013SJoachim Eastwood 
1924e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = {
192527ffefd2SJoachim Eastwood 	.probe  = rk_gmac_probe,
1926*903cc461SUwe Kleine-König 	.remove_new = rk_gmac_remove,
1927e0fb4013SJoachim Eastwood 	.driver = {
1928e0fb4013SJoachim Eastwood 		.name           = "rk_gmac-dwmac",
19295619468aSJoachim Eastwood 		.pm		= &rk_gmac_pm_ops,
1930e0fb4013SJoachim Eastwood 		.of_match_table = rk_gmac_dwmac_match,
1931e0fb4013SJoachim Eastwood 	},
1932e0fb4013SJoachim Eastwood };
1933e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver);
1934e0fb4013SJoachim Eastwood 
1935e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
1936e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
1937e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL");
1938