xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c (revision 78a60497a020ff526ae067125eef0dee10df5771)
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>
15e0fb4013SJoachim Eastwood #include <linux/module.h>
163d40aed8SRob Herring #include <linux/of.h>
17e0fb4013SJoachim Eastwood #include <linux/platform_device.h>
187ad269eaSRoger Chen #include <linux/regulator/consumer.h>
197ad269eaSRoger Chen #include <linux/delay.h>
207ad269eaSRoger Chen #include <linux/mfd/syscon.h>
217ad269eaSRoger Chen #include <linux/regmap.h>
22aec3f415SPunit Agrawal #include <linux/pm_runtime.h>
237ad269eaSRoger Chen 
24e0fb4013SJoachim Eastwood #include "stmmac_platform.h"
25e0fb4013SJoachim Eastwood 
260fb98db1SHeiko Stübner struct rk_priv_data;
270fb98db1SHeiko Stübner struct rk_gmac_ops {
280fb98db1SHeiko Stübner 	void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
290fb98db1SHeiko Stübner 			     int tx_delay, int rx_delay);
300fb98db1SHeiko Stübner 	void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
310fb98db1SHeiko Stübner 	void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
320fb98db1SHeiko Stübner 	void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
332f2b60a0SDavid Wu 	void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input,
342f2b60a0SDavid Wu 				    bool enable);
35fecd4d7eSDavid Wu 	void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
360546b224SJohn Keeping 	bool regs_valid;
373bb3d6b1SDavid Wu 	u32 regs[];
380fb98db1SHeiko Stübner };
390fb98db1SHeiko Stübner 
40ea449f7fSSebastian Reichel static const char * const rk_clocks[] = {
41ea449f7fSSebastian Reichel 	"aclk_mac", "pclk_mac", "mac_clk_tx", "clk_mac_speed",
42ea449f7fSSebastian Reichel };
43ea449f7fSSebastian Reichel 
44ea449f7fSSebastian Reichel static const char * const rk_rmii_clocks[] = {
45ea449f7fSSebastian Reichel 	"mac_clk_rx", "clk_mac_ref", "clk_mac_refout",
46ea449f7fSSebastian Reichel };
47ea449f7fSSebastian Reichel 
48ea449f7fSSebastian Reichel enum rk_clocks_index {
49ea449f7fSSebastian Reichel 	RK_ACLK_MAC = 0,
50ea449f7fSSebastian Reichel 	RK_PCLK_MAC,
51ea449f7fSSebastian Reichel 	RK_MAC_CLK_TX,
52ea449f7fSSebastian Reichel 	RK_CLK_MAC_SPEED,
53ea449f7fSSebastian Reichel 	RK_MAC_CLK_RX,
54ea449f7fSSebastian Reichel 	RK_CLK_MAC_REF,
55ea449f7fSSebastian Reichel 	RK_CLK_MAC_REFOUT,
56ea449f7fSSebastian Reichel };
57ea449f7fSSebastian Reichel 
587ad269eaSRoger Chen struct rk_priv_data {
597ad269eaSRoger Chen 	struct platform_device *pdev;
600c65b2b9SAndrew Lunn 	phy_interface_t phy_iface;
613bb3d6b1SDavid Wu 	int id;
622e12f536SRomain Perier 	struct regulator *regulator;
63229666c1SVincent Palatin 	bool suspended;
6492c2588fSJoachim Eastwood 	const struct rk_gmac_ops *ops;
657ad269eaSRoger Chen 
667ad269eaSRoger Chen 	bool clk_enabled;
677ad269eaSRoger Chen 	bool clock_input;
68fecd4d7eSDavid Wu 	bool integrated_phy;
697ad269eaSRoger Chen 
70ea449f7fSSebastian Reichel 	struct clk_bulk_data *clks;
71ea449f7fSSebastian Reichel 	int num_clks;
727ad269eaSRoger Chen 	struct clk *clk_mac;
73fecd4d7eSDavid Wu 	struct clk *clk_phy;
74fecd4d7eSDavid Wu 
75fecd4d7eSDavid Wu 	struct reset_control *phy_reset;
767ad269eaSRoger Chen 
777ad269eaSRoger Chen 	int tx_delay;
787ad269eaSRoger Chen 	int rx_delay;
797ad269eaSRoger Chen 
807ad269eaSRoger Chen 	struct regmap *grf;
812f2b60a0SDavid Wu 	struct regmap *php_grf;
827ad269eaSRoger Chen };
837ad269eaSRoger Chen 
847ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \
857ad269eaSRoger Chen 		((val) << (shift) | (mask) << ((shift) + 16))
867ad269eaSRoger Chen 
877ad269eaSRoger Chen #define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
887ad269eaSRoger Chen #define GRF_CLR_BIT(nr)	(BIT(nr+16))
897ad269eaSRoger Chen 
90eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \
91eaf70ad1SWadim Egorov 	(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
92eaf70ad1SWadim Egorov 	 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
93eaf70ad1SWadim Egorov 
9423c94d63SDavid Wu #define PX30_GRF_GMAC_CON1		0x0904
9523c94d63SDavid Wu 
9623c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */
9723c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
9823c94d63SDavid Wu 					 GRF_BIT(6))
9923c94d63SDavid Wu #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
10023c94d63SDavid Wu #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
10123c94d63SDavid Wu 
10223c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
10323c94d63SDavid Wu {
10423c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10523c94d63SDavid Wu 
10623c94d63SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10723c94d63SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
10823c94d63SDavid Wu 		return;
10923c94d63SDavid Wu 	}
11023c94d63SDavid Wu 
11123c94d63SDavid Wu 	regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
11223c94d63SDavid Wu 		     PX30_GMAC_PHY_INTF_SEL_RMII);
11323c94d63SDavid Wu }
11423c94d63SDavid Wu 
11523c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
11623c94d63SDavid Wu {
117ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
11823c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
11923c94d63SDavid Wu 	int ret;
12023c94d63SDavid Wu 
121ea449f7fSSebastian Reichel 	if (!clk_mac_speed) {
12223c94d63SDavid Wu 		dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
12323c94d63SDavid Wu 		return;
12423c94d63SDavid Wu 	}
12523c94d63SDavid Wu 
12623c94d63SDavid Wu 	if (speed == 10) {
12723c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
12823c94d63SDavid Wu 			     PX30_GMAC_SPEED_10M);
12923c94d63SDavid Wu 
130ea449f7fSSebastian Reichel 		ret = clk_set_rate(clk_mac_speed, 2500000);
13123c94d63SDavid Wu 		if (ret)
13223c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n",
13323c94d63SDavid Wu 				__func__, ret);
13423c94d63SDavid Wu 	} else if (speed == 100) {
13523c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
13623c94d63SDavid Wu 			     PX30_GMAC_SPEED_100M);
13723c94d63SDavid Wu 
138ea449f7fSSebastian Reichel 		ret = clk_set_rate(clk_mac_speed, 25000000);
13923c94d63SDavid Wu 		if (ret)
14023c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n",
14123c94d63SDavid Wu 				__func__, ret);
14223c94d63SDavid Wu 
14323c94d63SDavid Wu 	} else {
14423c94d63SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
14523c94d63SDavid Wu 	}
14623c94d63SDavid Wu }
14723c94d63SDavid Wu 
14823c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = {
14923c94d63SDavid Wu 	.set_to_rmii = px30_set_to_rmii,
15023c94d63SDavid Wu 	.set_rmii_speed = px30_set_rmii_speed,
15123c94d63SDavid Wu };
15223c94d63SDavid Wu 
15305946876SDavid Wu #define RK3128_GRF_MAC_CON0	0x0168
15405946876SDavid Wu #define RK3128_GRF_MAC_CON1	0x016c
15505946876SDavid Wu 
15605946876SDavid Wu /* RK3128_GRF_MAC_CON0 */
15705946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE   GRF_BIT(14)
15805946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(14)
15905946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(15)
16005946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(15)
16105946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
16205946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
16305946876SDavid Wu 
16405946876SDavid Wu /* RK3128_GRF_MAC_CON1 */
16505946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII	\
16605946876SDavid Wu 		(GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
16705946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII	\
16805946876SDavid Wu 		(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
16905946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
17005946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
17105946876SDavid Wu #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
17205946876SDavid Wu #define RK3128_GMAC_SPEED_100M         GRF_BIT(10)
17305946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M       GRF_BIT(11)
17405946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M      GRF_CLR_BIT(11)
17505946876SDavid Wu #define RK3128_GMAC_CLK_125M           (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
17605946876SDavid Wu #define RK3128_GMAC_CLK_25M            (GRF_BIT(12) | GRF_BIT(13))
17705946876SDavid Wu #define RK3128_GMAC_CLK_2_5M           (GRF_CLR_BIT(12) | GRF_BIT(13))
17805946876SDavid Wu #define RK3128_GMAC_RMII_MODE          GRF_BIT(14)
17905946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR      GRF_CLR_BIT(14)
18005946876SDavid Wu 
18105946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
18205946876SDavid Wu 				int tx_delay, int rx_delay)
18305946876SDavid Wu {
18405946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
18505946876SDavid Wu 
18605946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
18705946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
18805946876SDavid Wu 		return;
18905946876SDavid Wu 	}
19005946876SDavid Wu 
19105946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
19205946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RGMII |
19305946876SDavid Wu 		     RK3128_GMAC_RMII_MODE_CLR);
19405946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
19505946876SDavid Wu 		     DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
19605946876SDavid Wu 		     RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
19705946876SDavid Wu 		     RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
19805946876SDavid Wu }
19905946876SDavid Wu 
20005946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
20105946876SDavid Wu {
20205946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
20305946876SDavid Wu 
20405946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
20505946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
20605946876SDavid Wu 		return;
20705946876SDavid Wu 	}
20805946876SDavid Wu 
20905946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21005946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
21105946876SDavid Wu }
21205946876SDavid Wu 
21305946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
21405946876SDavid Wu {
21505946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
21605946876SDavid Wu 
21705946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
21805946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
21905946876SDavid Wu 		return;
22005946876SDavid Wu 	}
22105946876SDavid Wu 
22205946876SDavid Wu 	if (speed == 10)
22305946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
22405946876SDavid Wu 			     RK3128_GMAC_CLK_2_5M);
22505946876SDavid Wu 	else if (speed == 100)
22605946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
22705946876SDavid Wu 			     RK3128_GMAC_CLK_25M);
22805946876SDavid Wu 	else if (speed == 1000)
22905946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23005946876SDavid Wu 			     RK3128_GMAC_CLK_125M);
23105946876SDavid Wu 	else
23205946876SDavid Wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
23305946876SDavid Wu }
23405946876SDavid Wu 
23505946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
23605946876SDavid Wu {
23705946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
23805946876SDavid Wu 
23905946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
24005946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
24105946876SDavid Wu 		return;
24205946876SDavid Wu 	}
24305946876SDavid Wu 
24405946876SDavid Wu 	if (speed == 10) {
24505946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
24605946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_2_5M |
24705946876SDavid Wu 			     RK3128_GMAC_SPEED_10M);
24805946876SDavid Wu 	} else if (speed == 100) {
24905946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
25005946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_25M |
25105946876SDavid Wu 			     RK3128_GMAC_SPEED_100M);
25205946876SDavid Wu 	} else {
25305946876SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
25405946876SDavid Wu 	}
25505946876SDavid Wu }
25605946876SDavid Wu 
25705946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = {
25805946876SDavid Wu 	.set_to_rgmii = rk3128_set_to_rgmii,
25905946876SDavid Wu 	.set_to_rmii = rk3128_set_to_rmii,
26005946876SDavid Wu 	.set_rgmii_speed = rk3128_set_rgmii_speed,
26105946876SDavid Wu 	.set_rmii_speed = rk3128_set_rmii_speed,
26205946876SDavid Wu };
26305946876SDavid Wu 
264e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0	0x0900
265e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1	0x0904
266e7ffd812SXing Zheng 
2676fa12c78SDavid Wu #define RK3228_GRF_CON_MUX	0x50
2686fa12c78SDavid Wu 
269e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */
270e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
271e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
272e7ffd812SXing Zheng 
273e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */
274e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII	\
275e7ffd812SXing Zheng 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
276e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII	\
277e7ffd812SXing Zheng 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
278e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
279e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
280e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
281e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M		GRF_BIT(2)
282e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M	GRF_BIT(7)
283e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
284e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M		(GRF_CLR_BIT(8) | GRF_CLR_BIT(9))
285e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M		(GRF_BIT(8) | GRF_BIT(9))
286e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M		(GRF_CLR_BIT(8) | GRF_BIT(9))
287e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE		GRF_BIT(10)
288e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(10)
289e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
290e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
291e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
292e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
293e7ffd812SXing Zheng 
2946fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */
2956fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY	GRF_BIT(15)
2966fa12c78SDavid Wu 
297e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
298e7ffd812SXing Zheng 				int tx_delay, int rx_delay)
299e7ffd812SXing Zheng {
300e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
301e7ffd812SXing Zheng 
302e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
303e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
304e7ffd812SXing Zheng 		return;
305e7ffd812SXing Zheng 	}
306e7ffd812SXing Zheng 
307e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
308e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RGMII |
309e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE_CLR |
310eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3228, tx_delay, rx_delay));
311e7ffd812SXing Zheng 
312e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
313e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
314e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
315e7ffd812SXing Zheng }
316e7ffd812SXing Zheng 
317e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
318e7ffd812SXing Zheng {
319e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
320e7ffd812SXing Zheng 
321e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
322e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
323e7ffd812SXing Zheng 		return;
324e7ffd812SXing Zheng 	}
325e7ffd812SXing Zheng 
326e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
327e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RMII |
328e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE);
329e7ffd812SXing Zheng 
330e7ffd812SXing Zheng 	/* set MAC to RMII mode */
331e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11));
332e7ffd812SXing Zheng }
333e7ffd812SXing Zheng 
334e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
335e7ffd812SXing Zheng {
336e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
337e7ffd812SXing Zheng 
338e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
339e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
340e7ffd812SXing Zheng 		return;
341e7ffd812SXing Zheng 	}
342e7ffd812SXing Zheng 
343e7ffd812SXing Zheng 	if (speed == 10)
344e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
345e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_2_5M);
346e7ffd812SXing Zheng 	else if (speed == 100)
347e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
348e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_25M);
349e7ffd812SXing Zheng 	else if (speed == 1000)
350e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
351e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_125M);
352e7ffd812SXing Zheng 	else
353e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
354e7ffd812SXing Zheng }
355e7ffd812SXing Zheng 
356e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
357e7ffd812SXing Zheng {
358e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
359e7ffd812SXing Zheng 
360e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
361e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
362e7ffd812SXing Zheng 		return;
363e7ffd812SXing Zheng 	}
364e7ffd812SXing Zheng 
365e7ffd812SXing Zheng 	if (speed == 10)
366e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
367e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_2_5M |
368e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_10M);
369e7ffd812SXing Zheng 	else if (speed == 100)
370e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
371e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_25M |
372e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_100M);
373e7ffd812SXing Zheng 	else
374e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
375e7ffd812SXing Zheng }
376e7ffd812SXing Zheng 
3776fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
3786fa12c78SDavid Wu {
3796fa12c78SDavid Wu 	regmap_write(priv->grf, RK3228_GRF_CON_MUX,
3806fa12c78SDavid Wu 		     RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
3816fa12c78SDavid Wu }
3826fa12c78SDavid Wu 
383e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = {
384e7ffd812SXing Zheng 	.set_to_rgmii = rk3228_set_to_rgmii,
385e7ffd812SXing Zheng 	.set_to_rmii = rk3228_set_to_rmii,
386e7ffd812SXing Zheng 	.set_rgmii_speed = rk3228_set_rgmii_speed,
387e7ffd812SXing Zheng 	.set_rmii_speed = rk3228_set_rmii_speed,
3886fa12c78SDavid Wu 	.integrated_phy_powerup =  rk3228_integrated_phy_powerup,
389e7ffd812SXing Zheng };
390e7ffd812SXing Zheng 
3917ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1	0x0248
3927ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3	0x0250
3937ad269eaSRoger Chen 
3947ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/
3950fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | \
3960fb98db1SHeiko Stübner 					 GRF_CLR_BIT(8))
3970fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
3980fb98db1SHeiko Stübner 					 GRF_BIT(8))
3990fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
4000fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
4010fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
4020fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M		GRF_BIT(10)
4030fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M	GRF_BIT(11)
4040fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
4050fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
4060fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
4070fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
4080fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE		GRF_BIT(14)
4090fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
4107ad269eaSRoger Chen 
4117ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/
4120fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
4130fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
4140fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
4150fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
4160fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
4170fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
4187ad269eaSRoger Chen 
4190fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
4207ad269eaSRoger Chen 				int tx_delay, int rx_delay)
4217ad269eaSRoger Chen {
4227ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4237ad269eaSRoger Chen 
4247ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
425d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4267ad269eaSRoger Chen 		return;
4277ad269eaSRoger Chen 	}
4287ad269eaSRoger Chen 
4297ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4300fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
4310fb98db1SHeiko Stübner 		     RK3288_GMAC_RMII_MODE_CLR);
4327ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
433eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
4340fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
4350fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
4367ad269eaSRoger Chen }
4377ad269eaSRoger Chen 
4380fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
4397ad269eaSRoger Chen {
4407ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4417ad269eaSRoger Chen 
4427ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
443d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4447ad269eaSRoger Chen 		return;
4457ad269eaSRoger Chen 	}
4467ad269eaSRoger Chen 
4477ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4480fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
4497ad269eaSRoger Chen }
4507ad269eaSRoger Chen 
4510fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
4527ad269eaSRoger Chen {
4537ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4547ad269eaSRoger Chen 
4557ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
456d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4577ad269eaSRoger Chen 		return;
4587ad269eaSRoger Chen 	}
4597ad269eaSRoger Chen 
4607ad269eaSRoger Chen 	if (speed == 10)
4610fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4620fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_2_5M);
4637ad269eaSRoger Chen 	else if (speed == 100)
4640fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4650fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_25M);
4667ad269eaSRoger Chen 	else if (speed == 1000)
4670fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4680fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_125M);
4697ad269eaSRoger Chen 	else
4707ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
4717ad269eaSRoger Chen }
4727ad269eaSRoger Chen 
4730fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
4747ad269eaSRoger Chen {
4757ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4767ad269eaSRoger Chen 
4777ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
478d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4797ad269eaSRoger Chen 		return;
4807ad269eaSRoger Chen 	}
4817ad269eaSRoger Chen 
4827ad269eaSRoger Chen 	if (speed == 10) {
4837ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4840fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_2_5M |
4850fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_10M);
4867ad269eaSRoger Chen 	} else if (speed == 100) {
4877ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4880fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_25M |
4890fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_100M);
4907ad269eaSRoger Chen 	} else {
4917ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
4927ad269eaSRoger Chen 	}
4937ad269eaSRoger Chen }
4947ad269eaSRoger Chen 
49592c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = {
4960fb98db1SHeiko Stübner 	.set_to_rgmii = rk3288_set_to_rgmii,
4970fb98db1SHeiko Stübner 	.set_to_rmii = rk3288_set_to_rmii,
4980fb98db1SHeiko Stübner 	.set_rgmii_speed = rk3288_set_rgmii_speed,
4990fb98db1SHeiko Stübner 	.set_rmii_speed = rk3288_set_rmii_speed,
5000fb98db1SHeiko Stübner };
5010fb98db1SHeiko Stübner 
502b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0		0x04a0
503b4ac9456STobias Schramm 
504b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */
505b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \
506b4ac9456STobias Schramm 					GRF_BIT(4))
507b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
508b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
509b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
510b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M		GRF_BIT(0)
511b4ac9456STobias Schramm 
512b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv)
513b4ac9456STobias Schramm {
514b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
515b4ac9456STobias Schramm 
516b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
517b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
518b4ac9456STobias Schramm 		return;
519b4ac9456STobias Schramm 	}
520b4ac9456STobias Schramm 
521b4ac9456STobias Schramm 	regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
522b4ac9456STobias Schramm 		     RK3308_GMAC_PHY_INTF_SEL_RMII);
523b4ac9456STobias Schramm }
524b4ac9456STobias Schramm 
525b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
526b4ac9456STobias Schramm {
527b4ac9456STobias Schramm 	struct device *dev = &bsp_priv->pdev->dev;
528b4ac9456STobias Schramm 
529b4ac9456STobias Schramm 	if (IS_ERR(bsp_priv->grf)) {
530b4ac9456STobias Schramm 		dev_err(dev, "Missing rockchip,grf property\n");
531b4ac9456STobias Schramm 		return;
532b4ac9456STobias Schramm 	}
533b4ac9456STobias Schramm 
534b4ac9456STobias Schramm 	if (speed == 10) {
535b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
536b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_10M);
537b4ac9456STobias Schramm 	} else if (speed == 100) {
538b4ac9456STobias Schramm 		regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
539b4ac9456STobias Schramm 			     RK3308_GMAC_SPEED_100M);
540b4ac9456STobias Schramm 	} else {
541b4ac9456STobias Schramm 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
542b4ac9456STobias Schramm 	}
543b4ac9456STobias Schramm }
544b4ac9456STobias Schramm 
545b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = {
546b4ac9456STobias Schramm 	.set_to_rmii = rk3308_set_to_rmii,
547b4ac9456STobias Schramm 	.set_rmii_speed = rk3308_set_rmii_speed,
548b4ac9456STobias Schramm };
549b4ac9456STobias Schramm 
550d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0	0x0900
551d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1	0x0904
5528bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2	0x0908
5538bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1	0xb04
554d4ff816eSdavid.wu 
555d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */
556d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
557d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
558d4ff816eSdavid.wu 
559d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */
560d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII	\
561d4ff816eSdavid.wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
562d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII	\
563d4ff816eSdavid.wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
564d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
565d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
566d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
567d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M		GRF_BIT(2)
568d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M	GRF_BIT(7)
569d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
570d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M		(GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
571d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M		(GRF_BIT(11) | GRF_BIT(12))
572d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M		(GRF_CLR_BIT(11) | GRF_BIT(12))
573d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE		GRF_BIT(9)
574d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(9)
575d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
576d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
577d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
578d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
579d4ff816eSdavid.wu 
5808bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */
5818bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE		GRF_BIT(9)
5828bdf63bdSDavid Wu 
583d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
584d4ff816eSdavid.wu 				int tx_delay, int rx_delay)
585d4ff816eSdavid.wu {
586d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
587d4ff816eSdavid.wu 
588d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
589d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
590d4ff816eSdavid.wu 		return;
591d4ff816eSdavid.wu 	}
592d4ff816eSdavid.wu 
593d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
594d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
595d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE_CLR |
596d4ff816eSdavid.wu 		     RK3328_GMAC_RXCLK_DLY_ENABLE |
597d4ff816eSdavid.wu 		     RK3328_GMAC_TXCLK_DLY_ENABLE);
598d4ff816eSdavid.wu 
599d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
600d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
601d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
602d4ff816eSdavid.wu }
603d4ff816eSdavid.wu 
604d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
605d4ff816eSdavid.wu {
606d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
6078bdf63bdSDavid Wu 	unsigned int reg;
608d4ff816eSdavid.wu 
609d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
610d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
611d4ff816eSdavid.wu 		return;
612d4ff816eSdavid.wu 	}
613d4ff816eSdavid.wu 
6148bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6158bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6168bdf63bdSDavid Wu 
6178bdf63bdSDavid Wu 	regmap_write(bsp_priv->grf, reg,
618d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RMII |
619d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE);
620d4ff816eSdavid.wu }
621d4ff816eSdavid.wu 
622d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
623d4ff816eSdavid.wu {
624d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
625d4ff816eSdavid.wu 
626d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
627d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
628d4ff816eSdavid.wu 		return;
629d4ff816eSdavid.wu 	}
630d4ff816eSdavid.wu 
631d4ff816eSdavid.wu 	if (speed == 10)
632d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
633d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_2_5M);
634d4ff816eSdavid.wu 	else if (speed == 100)
635d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
636d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_25M);
637d4ff816eSdavid.wu 	else if (speed == 1000)
638d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
639d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_125M);
640d4ff816eSdavid.wu 	else
641d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
642d4ff816eSdavid.wu }
643d4ff816eSdavid.wu 
644d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
645d4ff816eSdavid.wu {
646d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
6478bdf63bdSDavid Wu 	unsigned int reg;
648d4ff816eSdavid.wu 
649d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
650d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
651d4ff816eSdavid.wu 		return;
652d4ff816eSdavid.wu 	}
653d4ff816eSdavid.wu 
6548bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6558bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6568bdf63bdSDavid Wu 
657d4ff816eSdavid.wu 	if (speed == 10)
6588bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
659d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_2_5M |
660d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_10M);
661d4ff816eSdavid.wu 	else if (speed == 100)
6628bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
663d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_25M |
664d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_100M);
665d4ff816eSdavid.wu 	else
666d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
667d4ff816eSdavid.wu }
668d4ff816eSdavid.wu 
6698bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
6708bdf63bdSDavid Wu {
6718bdf63bdSDavid Wu 	regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
6728bdf63bdSDavid Wu 		     RK3328_MACPHY_RMII_MODE);
6738bdf63bdSDavid Wu }
6748bdf63bdSDavid Wu 
675d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = {
676d4ff816eSdavid.wu 	.set_to_rgmii = rk3328_set_to_rgmii,
677d4ff816eSdavid.wu 	.set_to_rmii = rk3328_set_to_rmii,
678d4ff816eSdavid.wu 	.set_rgmii_speed = rk3328_set_rgmii_speed,
679d4ff816eSdavid.wu 	.set_rmii_speed = rk3328_set_rmii_speed,
6808bdf63bdSDavid Wu 	.integrated_phy_powerup =  rk3328_integrated_phy_powerup,
681d4ff816eSdavid.wu };
682d4ff816eSdavid.wu 
683ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6	0x0418
684ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7	0x041c
685ba289af8SRoger Chen 
686ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */
687ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
688ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
689ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
690ba289af8SRoger Chen 					 GRF_BIT(11))
691ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
692ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
693ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
694ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M		GRF_BIT(7)
695ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M	GRF_BIT(3)
696ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
697ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
698ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
699ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
700ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE		GRF_BIT(6)
701ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
702ba289af8SRoger Chen 
703ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */
704ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
705ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
706ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
707ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
708ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
709ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
710ba289af8SRoger Chen 
711ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
712ba289af8SRoger Chen 				int tx_delay, int rx_delay)
713ba289af8SRoger Chen {
714ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
715ba289af8SRoger Chen 
716ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
717ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
718ba289af8SRoger Chen 		return;
719ba289af8SRoger Chen 	}
720ba289af8SRoger Chen 
721ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
722ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RGMII |
723ba289af8SRoger Chen 		     RK3366_GMAC_RMII_MODE_CLR);
724ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
725eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
726ba289af8SRoger Chen 		     RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
727ba289af8SRoger Chen 		     RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
728ba289af8SRoger Chen }
729ba289af8SRoger Chen 
730ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
731ba289af8SRoger Chen {
732ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
733ba289af8SRoger Chen 
734ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
735ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
736ba289af8SRoger Chen 		return;
737ba289af8SRoger Chen 	}
738ba289af8SRoger Chen 
739ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
740ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
741ba289af8SRoger Chen }
742ba289af8SRoger Chen 
743ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
744ba289af8SRoger Chen {
745ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
746ba289af8SRoger Chen 
747ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
748ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
749ba289af8SRoger Chen 		return;
750ba289af8SRoger Chen 	}
751ba289af8SRoger Chen 
752ba289af8SRoger Chen 	if (speed == 10)
753ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
754ba289af8SRoger Chen 			     RK3366_GMAC_CLK_2_5M);
755ba289af8SRoger Chen 	else if (speed == 100)
756ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
757ba289af8SRoger Chen 			     RK3366_GMAC_CLK_25M);
758ba289af8SRoger Chen 	else if (speed == 1000)
759ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
760ba289af8SRoger Chen 			     RK3366_GMAC_CLK_125M);
761ba289af8SRoger Chen 	else
762ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
763ba289af8SRoger Chen }
764ba289af8SRoger Chen 
765ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
766ba289af8SRoger Chen {
767ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
768ba289af8SRoger Chen 
769ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
770ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
771ba289af8SRoger Chen 		return;
772ba289af8SRoger Chen 	}
773ba289af8SRoger Chen 
774ba289af8SRoger Chen 	if (speed == 10) {
775ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
776ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_2_5M |
777ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_10M);
778ba289af8SRoger Chen 	} else if (speed == 100) {
779ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
780ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_25M |
781ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_100M);
782ba289af8SRoger Chen 	} else {
783ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
784ba289af8SRoger Chen 	}
785ba289af8SRoger Chen }
786ba289af8SRoger Chen 
787ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = {
788ba289af8SRoger Chen 	.set_to_rgmii = rk3366_set_to_rgmii,
789ba289af8SRoger Chen 	.set_to_rmii = rk3366_set_to_rmii,
790ba289af8SRoger Chen 	.set_rgmii_speed = rk3366_set_rgmii_speed,
791ba289af8SRoger Chen 	.set_rmii_speed = rk3366_set_rmii_speed,
792ba289af8SRoger Chen };
793ba289af8SRoger Chen 
794df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15	0x043c
795df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16	0x0440
796df558854SHeiko Stübner 
797df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */
798df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
799df558854SHeiko Stübner 					 GRF_CLR_BIT(11))
800df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
801df558854SHeiko Stübner 					 GRF_BIT(11))
802df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
803df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
804df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
805df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M		GRF_BIT(7)
806df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M	GRF_BIT(3)
807df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
808df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
809df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
810df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
811df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE		GRF_BIT(6)
812df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
813df558854SHeiko Stübner 
814df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */
815df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
816df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
817df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
818df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
819df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
820df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
821df558854SHeiko Stübner 
822df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
823df558854SHeiko Stübner 				int tx_delay, int rx_delay)
824df558854SHeiko Stübner {
825df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
826df558854SHeiko Stübner 
827df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
828df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
829df558854SHeiko Stübner 		return;
830df558854SHeiko Stübner 	}
831df558854SHeiko Stübner 
832df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
833df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
834df558854SHeiko Stübner 		     RK3368_GMAC_RMII_MODE_CLR);
835df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
836eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
837df558854SHeiko Stübner 		     RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
838df558854SHeiko Stübner 		     RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
839df558854SHeiko Stübner }
840df558854SHeiko Stübner 
841df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
842df558854SHeiko Stübner {
843df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
844df558854SHeiko Stübner 
845df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
846df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
847df558854SHeiko Stübner 		return;
848df558854SHeiko Stübner 	}
849df558854SHeiko Stübner 
850df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
851df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
852df558854SHeiko Stübner }
853df558854SHeiko Stübner 
854df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
855df558854SHeiko Stübner {
856df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
857df558854SHeiko Stübner 
858df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
859df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
860df558854SHeiko Stübner 		return;
861df558854SHeiko Stübner 	}
862df558854SHeiko Stübner 
863df558854SHeiko Stübner 	if (speed == 10)
864df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
865df558854SHeiko Stübner 			     RK3368_GMAC_CLK_2_5M);
866df558854SHeiko Stübner 	else if (speed == 100)
867df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
868df558854SHeiko Stübner 			     RK3368_GMAC_CLK_25M);
869df558854SHeiko Stübner 	else if (speed == 1000)
870df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
871df558854SHeiko Stübner 			     RK3368_GMAC_CLK_125M);
872df558854SHeiko Stübner 	else
873df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
874df558854SHeiko Stübner }
875df558854SHeiko Stübner 
876df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
877df558854SHeiko Stübner {
878df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
879df558854SHeiko Stübner 
880df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
881df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
882df558854SHeiko Stübner 		return;
883df558854SHeiko Stübner 	}
884df558854SHeiko Stübner 
885df558854SHeiko Stübner 	if (speed == 10) {
886df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
887df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_2_5M |
888df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_10M);
889df558854SHeiko Stübner 	} else if (speed == 100) {
890df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
891df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_25M |
892df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_100M);
893df558854SHeiko Stübner 	} else {
894df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
895df558854SHeiko Stübner 	}
896df558854SHeiko Stübner }
897df558854SHeiko Stübner 
89892c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = {
899df558854SHeiko Stübner 	.set_to_rgmii = rk3368_set_to_rgmii,
900df558854SHeiko Stübner 	.set_to_rmii = rk3368_set_to_rmii,
901df558854SHeiko Stübner 	.set_rgmii_speed = rk3368_set_rgmii_speed,
902df558854SHeiko Stübner 	.set_rmii_speed = rk3368_set_rmii_speed,
903df558854SHeiko Stübner };
904df558854SHeiko Stübner 
905ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5	0xc214
906ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6	0xc218
907ba289af8SRoger Chen 
908ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */
909ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
910ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
911ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
912ba289af8SRoger Chen 					 GRF_BIT(11))
913ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
914ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
915ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
916ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M		GRF_BIT(7)
917ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M	GRF_BIT(3)
918ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
919ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
920ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
921ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
922ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE		GRF_BIT(6)
923ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
924ba289af8SRoger Chen 
925ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */
926ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
927ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
928ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
929ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
930ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
931ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
932ba289af8SRoger Chen 
933ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
934ba289af8SRoger Chen 				int tx_delay, int rx_delay)
935ba289af8SRoger Chen {
936ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
937ba289af8SRoger Chen 
938ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
939ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
940ba289af8SRoger Chen 		return;
941ba289af8SRoger Chen 	}
942ba289af8SRoger Chen 
943ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
944ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RGMII |
945ba289af8SRoger Chen 		     RK3399_GMAC_RMII_MODE_CLR);
946ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
947eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
948ba289af8SRoger Chen 		     RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
949ba289af8SRoger Chen 		     RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
950ba289af8SRoger Chen }
951ba289af8SRoger Chen 
952ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
953ba289af8SRoger Chen {
954ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
955ba289af8SRoger Chen 
956ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
957ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
958ba289af8SRoger Chen 		return;
959ba289af8SRoger Chen 	}
960ba289af8SRoger Chen 
961ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
962ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
963ba289af8SRoger Chen }
964ba289af8SRoger Chen 
965ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
966ba289af8SRoger Chen {
967ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
968ba289af8SRoger Chen 
969ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
970ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
971ba289af8SRoger Chen 		return;
972ba289af8SRoger Chen 	}
973ba289af8SRoger Chen 
974ba289af8SRoger Chen 	if (speed == 10)
975ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
976ba289af8SRoger Chen 			     RK3399_GMAC_CLK_2_5M);
977ba289af8SRoger Chen 	else if (speed == 100)
978ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
979ba289af8SRoger Chen 			     RK3399_GMAC_CLK_25M);
980ba289af8SRoger Chen 	else if (speed == 1000)
981ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
982ba289af8SRoger Chen 			     RK3399_GMAC_CLK_125M);
983ba289af8SRoger Chen 	else
984ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
985ba289af8SRoger Chen }
986ba289af8SRoger Chen 
987ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
988ba289af8SRoger Chen {
989ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
990ba289af8SRoger Chen 
991ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
992ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
993ba289af8SRoger Chen 		return;
994ba289af8SRoger Chen 	}
995ba289af8SRoger Chen 
996ba289af8SRoger Chen 	if (speed == 10) {
997ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
998ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_2_5M |
999ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_10M);
1000ba289af8SRoger Chen 	} else if (speed == 100) {
1001ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
1002ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_25M |
1003ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_100M);
1004ba289af8SRoger Chen 	} else {
1005ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
1006ba289af8SRoger Chen 	}
1007ba289af8SRoger Chen }
1008ba289af8SRoger Chen 
1009ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = {
1010ba289af8SRoger Chen 	.set_to_rgmii = rk3399_set_to_rgmii,
1011ba289af8SRoger Chen 	.set_to_rmii = rk3399_set_to_rmii,
1012ba289af8SRoger Chen 	.set_rgmii_speed = rk3399_set_rgmii_speed,
1013ba289af8SRoger Chen 	.set_rmii_speed = rk3399_set_rmii_speed,
1014ba289af8SRoger Chen };
1015ba289af8SRoger Chen 
10163bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON0		0x0380
10173bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON1		0x0384
10183bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON0		0x0388
10193bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON1		0x038c
10203bb3d6b1SDavid Wu 
10213bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
10223bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RGMII	\
10233bb3d6b1SDavid Wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
10243bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RMII	\
10253bb3d6b1SDavid Wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
10263bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
10273bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
10283bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
10293bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_DISABLE		GRF_CLR_BIT(1)
10303bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_ENABLE		GRF_BIT(0)
10313bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_DISABLE		GRF_CLR_BIT(0)
10323bb3d6b1SDavid Wu 
10333bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
10343bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
10353bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
10363bb3d6b1SDavid Wu 
10373bb3d6b1SDavid Wu static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,
10383bb3d6b1SDavid Wu 				int tx_delay, int rx_delay)
10393bb3d6b1SDavid Wu {
10403bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10413bb3d6b1SDavid Wu 	u32 con0, con1;
10423bb3d6b1SDavid Wu 
10433bb3d6b1SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10443bb3d6b1SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
10453bb3d6b1SDavid Wu 		return;
10463bb3d6b1SDavid Wu 	}
10473bb3d6b1SDavid Wu 
10483bb3d6b1SDavid Wu 	con0 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON0 :
10493bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON0;
10503bb3d6b1SDavid Wu 	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10513bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON1;
10523bb3d6b1SDavid Wu 
10533bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con0,
10543bb3d6b1SDavid Wu 		     RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) |
10553bb3d6b1SDavid Wu 		     RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
10563bb3d6b1SDavid Wu 
10573bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con1,
10583bb3d6b1SDavid Wu 		     RK3568_GMAC_PHY_INTF_SEL_RGMII |
10593bb3d6b1SDavid Wu 		     RK3568_GMAC_RXCLK_DLY_ENABLE |
10603bb3d6b1SDavid Wu 		     RK3568_GMAC_TXCLK_DLY_ENABLE);
10613bb3d6b1SDavid Wu }
10623bb3d6b1SDavid Wu 
10633bb3d6b1SDavid Wu static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv)
10643bb3d6b1SDavid Wu {
10653bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10663bb3d6b1SDavid Wu 	u32 con1;
10673bb3d6b1SDavid Wu 
10683bb3d6b1SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10693bb3d6b1SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
10703bb3d6b1SDavid Wu 		return;
10713bb3d6b1SDavid Wu 	}
10723bb3d6b1SDavid Wu 
10733bb3d6b1SDavid Wu 	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10743bb3d6b1SDavid Wu 				     RK3568_GRF_GMAC0_CON1;
10753bb3d6b1SDavid Wu 	regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
10763bb3d6b1SDavid Wu }
10773bb3d6b1SDavid Wu 
10783bb3d6b1SDavid Wu static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
10793bb3d6b1SDavid Wu {
1080ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
10813bb3d6b1SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
10823bb3d6b1SDavid Wu 	unsigned long rate;
10833bb3d6b1SDavid Wu 	int ret;
10843bb3d6b1SDavid Wu 
10853bb3d6b1SDavid Wu 	switch (speed) {
10863bb3d6b1SDavid Wu 	case 10:
10873bb3d6b1SDavid Wu 		rate = 2500000;
10883bb3d6b1SDavid Wu 		break;
10893bb3d6b1SDavid Wu 	case 100:
10903bb3d6b1SDavid Wu 		rate = 25000000;
10913bb3d6b1SDavid Wu 		break;
10923bb3d6b1SDavid Wu 	case 1000:
10933bb3d6b1SDavid Wu 		rate = 125000000;
10943bb3d6b1SDavid Wu 		break;
10953bb3d6b1SDavid Wu 	default:
10963bb3d6b1SDavid Wu 		dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
10973bb3d6b1SDavid Wu 		return;
10983bb3d6b1SDavid Wu 	}
10993bb3d6b1SDavid Wu 
1100ea449f7fSSebastian Reichel 	ret = clk_set_rate(clk_mac_speed, rate);
11013bb3d6b1SDavid Wu 	if (ret)
11023bb3d6b1SDavid Wu 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
11033bb3d6b1SDavid Wu 			__func__, rate, ret);
11043bb3d6b1SDavid Wu }
11053bb3d6b1SDavid Wu 
11063bb3d6b1SDavid Wu static const struct rk_gmac_ops rk3568_ops = {
11073bb3d6b1SDavid Wu 	.set_to_rgmii = rk3568_set_to_rgmii,
11083bb3d6b1SDavid Wu 	.set_to_rmii = rk3568_set_to_rmii,
11093bb3d6b1SDavid Wu 	.set_rgmii_speed = rk3568_set_gmac_speed,
11103bb3d6b1SDavid Wu 	.set_rmii_speed = rk3568_set_gmac_speed,
11110546b224SJohn Keeping 	.regs_valid = true,
11123bb3d6b1SDavid Wu 	.regs = {
11133bb3d6b1SDavid Wu 		0xfe2a0000, /* gmac0 */
11143bb3d6b1SDavid Wu 		0xfe010000, /* gmac1 */
11153bb3d6b1SDavid Wu 		0x0, /* sentinel */
11163bb3d6b1SDavid Wu 	},
11173bb3d6b1SDavid Wu };
11183bb3d6b1SDavid Wu 
11192f2b60a0SDavid Wu /* sys_grf */
11202f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON7			0X031c
11212f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON8			0X0320
11222f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON9			0X0324
11232f2b60a0SDavid Wu 
11242f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 3)
11252f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 3)
11262f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 2)
11272f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 2)
11282f2b60a0SDavid Wu 
11292f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 8)
11302f2b60a0SDavid Wu #define RK3588_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 0)
11312f2b60a0SDavid Wu 
11322f2b60a0SDavid Wu /* php_grf */
11332f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON0			0X0008
11342f2b60a0SDavid Wu #define RK3588_GRF_CLK_CON1			0X0070
11352f2b60a0SDavid Wu 
11362f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
11372f2b60a0SDavid Wu 	(GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
11382f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
11392f2b60a0SDavid Wu 	(GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
11402f2b60a0SDavid Wu 
11412f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
11422f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
11432f2b60a0SDavid Wu 
1144*78a60497SDetlev Casanova #define RK3588_GMAC_CLK_SELECT_CRU(id)		GRF_BIT(5 * (id) + 4)
1145*78a60497SDetlev Casanova #define RK3588_GMAC_CLK_SELECT_IO(id)		GRF_CLR_BIT(5 * (id) + 4)
11462f2b60a0SDavid Wu 
11472f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV2(id)		GRF_BIT(5 * (id) + 2)
11482f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV20(id)		GRF_CLR_BIT(5 * (id) + 2)
11492f2b60a0SDavid Wu 
11502f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV1(id)		\
11512f2b60a0SDavid Wu 			(GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
11522f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV5(id)		\
11532f2b60a0SDavid Wu 			(GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
11542f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV50(id)		\
11552f2b60a0SDavid Wu 			(GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
11562f2b60a0SDavid Wu 
11572f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_GATE(id)		GRF_BIT(5 * (id) + 1)
11582f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_NOGATE(id)		GRF_CLR_BIT(5 * (id) + 1)
11592f2b60a0SDavid Wu 
11602f2b60a0SDavid Wu static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
11612f2b60a0SDavid Wu 				int tx_delay, int rx_delay)
11622f2b60a0SDavid Wu {
11632f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
11642f2b60a0SDavid Wu 	u32 offset_con, id = bsp_priv->id;
11652f2b60a0SDavid Wu 
11662f2b60a0SDavid Wu 	if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
11672f2b60a0SDavid Wu 		dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n");
11682f2b60a0SDavid Wu 		return;
11692f2b60a0SDavid Wu 	}
11702f2b60a0SDavid Wu 
11712f2b60a0SDavid Wu 	offset_con = bsp_priv->id == 1 ? RK3588_GRF_GMAC_CON9 :
11722f2b60a0SDavid Wu 					 RK3588_GRF_GMAC_CON8;
11732f2b60a0SDavid Wu 
11742f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
11752f2b60a0SDavid Wu 		     RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
11762f2b60a0SDavid Wu 
11772f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
11782f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RGMII_MODE(id));
11792f2b60a0SDavid Wu 
11802f2b60a0SDavid Wu 	regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7,
11812f2b60a0SDavid Wu 		     RK3588_GMAC_RXCLK_DLY_ENABLE(id) |
11822f2b60a0SDavid Wu 		     RK3588_GMAC_TXCLK_DLY_ENABLE(id));
11832f2b60a0SDavid Wu 
11842f2b60a0SDavid Wu 	regmap_write(bsp_priv->grf, offset_con,
11852f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
11862f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
11872f2b60a0SDavid Wu }
11882f2b60a0SDavid Wu 
11892f2b60a0SDavid Wu static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv)
11902f2b60a0SDavid Wu {
11912f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
11922f2b60a0SDavid Wu 
11932f2b60a0SDavid Wu 	if (IS_ERR(bsp_priv->php_grf)) {
11942f2b60a0SDavid Wu 		dev_err(dev, "%s: Missing rockchip,php_grf property\n", __func__);
11952f2b60a0SDavid Wu 		return;
11962f2b60a0SDavid Wu 	}
11972f2b60a0SDavid Wu 
11982f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
11992f2b60a0SDavid Wu 		     RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->id));
12002f2b60a0SDavid Wu 
12012f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
12022f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id));
12032f2b60a0SDavid Wu }
12042f2b60a0SDavid Wu 
12052f2b60a0SDavid Wu static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
12062f2b60a0SDavid Wu {
12072f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
12082f2b60a0SDavid Wu 	unsigned int val = 0, id = bsp_priv->id;
12092f2b60a0SDavid Wu 
12102f2b60a0SDavid Wu 	switch (speed) {
12112f2b60a0SDavid Wu 	case 10:
12122f2b60a0SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
12132f2b60a0SDavid Wu 			val = RK3588_GMA_CLK_RMII_DIV20(id);
12142f2b60a0SDavid Wu 		else
12152f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV50(id);
12162f2b60a0SDavid Wu 		break;
12172f2b60a0SDavid Wu 	case 100:
12182f2b60a0SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
12192f2b60a0SDavid Wu 			val = RK3588_GMA_CLK_RMII_DIV2(id);
12202f2b60a0SDavid Wu 		else
12212f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV5(id);
12222f2b60a0SDavid Wu 		break;
12232f2b60a0SDavid Wu 	case 1000:
12242f2b60a0SDavid Wu 		if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
12252f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV1(id);
12262f2b60a0SDavid Wu 		else
12272f2b60a0SDavid Wu 			goto err;
12282f2b60a0SDavid Wu 		break;
12292f2b60a0SDavid Wu 	default:
12302f2b60a0SDavid Wu 		goto err;
12312f2b60a0SDavid Wu 	}
12322f2b60a0SDavid Wu 
12332f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
12342f2b60a0SDavid Wu 
12352f2b60a0SDavid Wu 	return;
12362f2b60a0SDavid Wu err:
12372f2b60a0SDavid Wu 	dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
12382f2b60a0SDavid Wu }
12392f2b60a0SDavid Wu 
12402f2b60a0SDavid Wu static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input,
12412f2b60a0SDavid Wu 				       bool enable)
12422f2b60a0SDavid Wu {
1243*78a60497SDetlev Casanova 	unsigned int val = input ? RK3588_GMAC_CLK_SELECT_IO(bsp_priv->id) :
1244*78a60497SDetlev Casanova 				   RK3588_GMAC_CLK_SELECT_CRU(bsp_priv->id);
12452f2b60a0SDavid Wu 
12462f2b60a0SDavid Wu 	val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->id) :
12472f2b60a0SDavid Wu 			RK3588_GMAC_CLK_RMII_GATE(bsp_priv->id);
12482f2b60a0SDavid Wu 
12492f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
12502f2b60a0SDavid Wu }
12512f2b60a0SDavid Wu 
12522f2b60a0SDavid Wu static const struct rk_gmac_ops rk3588_ops = {
12532f2b60a0SDavid Wu 	.set_to_rgmii = rk3588_set_to_rgmii,
12542f2b60a0SDavid Wu 	.set_to_rmii = rk3588_set_to_rmii,
12552f2b60a0SDavid Wu 	.set_rgmii_speed = rk3588_set_gmac_speed,
12562f2b60a0SDavid Wu 	.set_rmii_speed = rk3588_set_gmac_speed,
12572f2b60a0SDavid Wu 	.set_clock_selection = rk3588_set_clock_selection,
125888619e77SBenjamin Gaignard 	.regs_valid = true,
125988619e77SBenjamin Gaignard 	.regs = {
126088619e77SBenjamin Gaignard 		0xfe1b0000, /* gmac0 */
126188619e77SBenjamin Gaignard 		0xfe1c0000, /* gmac1 */
126288619e77SBenjamin Gaignard 		0x0, /* sentinel */
126388619e77SBenjamin Gaignard 	},
12642f2b60a0SDavid Wu };
12652f2b60a0SDavid Wu 
126689c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0		0X0900
126789c9c163SDavid Wu 
126889c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */
126989c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
127089c9c163SDavid Wu 					GRF_BIT(6))
127189c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
127289c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
127389c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
127489c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M		GRF_BIT(2)
127589c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M	GRF_BIT(7)
127689c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
127789c9c163SDavid Wu 
127889c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
127989c9c163SDavid Wu {
128089c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
128189c9c163SDavid Wu 
128289c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
128389c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
128489c9c163SDavid Wu 		return;
128589c9c163SDavid Wu 	}
128689c9c163SDavid Wu 
128789c9c163SDavid Wu 	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
128889c9c163SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
128989c9c163SDavid Wu }
129089c9c163SDavid Wu 
129189c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
129289c9c163SDavid Wu {
129389c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
129489c9c163SDavid Wu 
129589c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
129689c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
129789c9c163SDavid Wu 		return;
129889c9c163SDavid Wu 	}
129989c9c163SDavid Wu 
130089c9c163SDavid Wu 	if (speed == 10) {
130189c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
130289c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_2_5M |
130389c9c163SDavid Wu 			     RV1108_GMAC_SPEED_10M);
130489c9c163SDavid Wu 	} else if (speed == 100) {
130589c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
130689c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_25M |
130789c9c163SDavid Wu 			     RV1108_GMAC_SPEED_100M);
130889c9c163SDavid Wu 	} else {
130989c9c163SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
131089c9c163SDavid Wu 	}
131189c9c163SDavid Wu }
131289c9c163SDavid Wu 
131389c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = {
131489c9c163SDavid Wu 	.set_to_rmii = rv1108_set_to_rmii,
131589c9c163SDavid Wu 	.set_rmii_speed = rv1108_set_rmii_speed,
131689c9c163SDavid Wu };
131789c9c163SDavid Wu 
1318c931b060SAnand Moon #define RV1126_GRF_GMAC_CON0		0X0070
1319c931b060SAnand Moon #define RV1126_GRF_GMAC_CON1		0X0074
1320c931b060SAnand Moon #define RV1126_GRF_GMAC_CON2		0X0078
1321c931b060SAnand Moon 
1322c931b060SAnand Moon /* RV1126_GRF_GMAC_CON0 */
1323c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RGMII	\
1324c931b060SAnand Moon 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
1325c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RMII	\
1326c931b060SAnand Moon 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
1327c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL			GRF_BIT(7)
1328c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(7)
1329c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE		GRF_BIT(1)
1330c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
1331c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_ENABLE		GRF_BIT(0)
1332c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
1333c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_ENABLE		GRF_BIT(3)
1334c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_DISABLE	GRF_CLR_BIT(3)
1335c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_ENABLE		GRF_BIT(2)
1336c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_DISABLE	GRF_CLR_BIT(2)
1337c931b060SAnand Moon 
1338c931b060SAnand Moon /* RV1126_GRF_GMAC_CON1 */
1339c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
1340c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
1341c931b060SAnand Moon /* RV1126_GRF_GMAC_CON2 */
1342c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
1343c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
1344c931b060SAnand Moon 
1345c931b060SAnand Moon static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
1346c931b060SAnand Moon 				int tx_delay, int rx_delay)
1347c931b060SAnand Moon {
1348c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1349c931b060SAnand Moon 
1350c931b060SAnand Moon 	if (IS_ERR(bsp_priv->grf)) {
1351c931b060SAnand Moon 		dev_err(dev, "Missing rockchip,grf property\n");
1352c931b060SAnand Moon 		return;
1353c931b060SAnand Moon 	}
1354c931b060SAnand Moon 
1355c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1356c931b060SAnand Moon 		     RV1126_GMAC_PHY_INTF_SEL_RGMII |
1357c931b060SAnand Moon 		     RV1126_GMAC_M0_RXCLK_DLY_ENABLE |
1358c931b060SAnand Moon 		     RV1126_GMAC_M0_TXCLK_DLY_ENABLE |
1359c931b060SAnand Moon 		     RV1126_GMAC_M1_RXCLK_DLY_ENABLE |
1360c931b060SAnand Moon 		     RV1126_GMAC_M1_TXCLK_DLY_ENABLE);
1361c931b060SAnand Moon 
1362c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1,
1363c931b060SAnand Moon 		     RV1126_GMAC_M0_CLK_RX_DL_CFG(rx_delay) |
1364c931b060SAnand Moon 		     RV1126_GMAC_M0_CLK_TX_DL_CFG(tx_delay));
1365c931b060SAnand Moon 
1366c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2,
1367c931b060SAnand Moon 		     RV1126_GMAC_M1_CLK_RX_DL_CFG(rx_delay) |
1368c931b060SAnand Moon 		     RV1126_GMAC_M1_CLK_TX_DL_CFG(tx_delay));
1369c931b060SAnand Moon }
1370c931b060SAnand Moon 
1371c931b060SAnand Moon static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv)
1372c931b060SAnand Moon {
1373c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1374c931b060SAnand Moon 
1375c931b060SAnand Moon 	if (IS_ERR(bsp_priv->grf)) {
1376c931b060SAnand Moon 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1377c931b060SAnand Moon 		return;
1378c931b060SAnand Moon 	}
1379c931b060SAnand Moon 
1380c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1381c931b060SAnand Moon 		     RV1126_GMAC_PHY_INTF_SEL_RMII);
1382c931b060SAnand Moon }
1383c931b060SAnand Moon 
1384c931b060SAnand Moon static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
1385c931b060SAnand Moon {
1386ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
1387c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1388c931b060SAnand Moon 	unsigned long rate;
1389c931b060SAnand Moon 	int ret;
1390c931b060SAnand Moon 
1391c931b060SAnand Moon 	switch (speed) {
1392c931b060SAnand Moon 	case 10:
1393c931b060SAnand Moon 		rate = 2500000;
1394c931b060SAnand Moon 		break;
1395c931b060SAnand Moon 	case 100:
1396c931b060SAnand Moon 		rate = 25000000;
1397c931b060SAnand Moon 		break;
1398c931b060SAnand Moon 	case 1000:
1399c931b060SAnand Moon 		rate = 125000000;
1400c931b060SAnand Moon 		break;
1401c931b060SAnand Moon 	default:
1402c931b060SAnand Moon 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1403c931b060SAnand Moon 		return;
1404c931b060SAnand Moon 	}
1405c931b060SAnand Moon 
1406ea449f7fSSebastian Reichel 	ret = clk_set_rate(clk_mac_speed, rate);
1407c931b060SAnand Moon 	if (ret)
1408c931b060SAnand Moon 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1409c931b060SAnand Moon 			__func__, rate, ret);
1410c931b060SAnand Moon }
1411c931b060SAnand Moon 
1412c931b060SAnand Moon static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
1413c931b060SAnand Moon {
1414ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
1415c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1416c931b060SAnand Moon 	unsigned long rate;
1417c931b060SAnand Moon 	int ret;
1418c931b060SAnand Moon 
1419c931b060SAnand Moon 	switch (speed) {
1420c931b060SAnand Moon 	case 10:
1421c931b060SAnand Moon 		rate = 2500000;
1422c931b060SAnand Moon 		break;
1423c931b060SAnand Moon 	case 100:
1424c931b060SAnand Moon 		rate = 25000000;
1425c931b060SAnand Moon 		break;
1426c931b060SAnand Moon 	default:
1427c931b060SAnand Moon 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1428c931b060SAnand Moon 		return;
1429c931b060SAnand Moon 	}
1430c931b060SAnand Moon 
1431ea449f7fSSebastian Reichel 	ret = clk_set_rate(clk_mac_speed, rate);
1432c931b060SAnand Moon 	if (ret)
1433c931b060SAnand Moon 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1434c931b060SAnand Moon 			__func__, rate, ret);
1435c931b060SAnand Moon }
1436c931b060SAnand Moon 
1437c931b060SAnand Moon static const struct rk_gmac_ops rv1126_ops = {
1438c931b060SAnand Moon 	.set_to_rgmii = rv1126_set_to_rgmii,
1439c931b060SAnand Moon 	.set_to_rmii = rv1126_set_to_rmii,
1440c931b060SAnand Moon 	.set_rgmii_speed = rv1126_set_rgmii_speed,
1441c931b060SAnand Moon 	.set_rmii_speed = rv1126_set_rmii_speed,
1442c931b060SAnand Moon };
1443c931b060SAnand Moon 
1444fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0		0xb00
1445fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1		0xb04
1446fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2		0xb08
1447fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3		0xb0c
1448fecd4d7eSDavid Wu 
1449fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE		GRF_BIT(0)
1450fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
1451fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
1452fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
1453fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID		HIWORD_UPDATE(0x1234, 0xffff, 0)
1454fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID		HIWORD_UPDATE(0x35, 0x3f, 0)
1455fecd4d7eSDavid Wu 
1456fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
14577ad269eaSRoger Chen {
1458fecd4d7eSDavid Wu 	if (priv->ops->integrated_phy_powerup)
1459fecd4d7eSDavid Wu 		priv->ops->integrated_phy_powerup(priv);
1460fecd4d7eSDavid Wu 
1461fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
1462fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
1463fecd4d7eSDavid Wu 
1464fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
1465fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
1466fecd4d7eSDavid Wu 
1467fecd4d7eSDavid Wu 	if (priv->phy_reset) {
1468fecd4d7eSDavid Wu 		/* PHY needs to be disabled before trying to reset it */
1469fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1470fecd4d7eSDavid Wu 		if (priv->phy_reset)
1471fecd4d7eSDavid Wu 			reset_control_assert(priv->phy_reset);
1472fecd4d7eSDavid Wu 		usleep_range(10, 20);
1473fecd4d7eSDavid Wu 		if (priv->phy_reset)
1474fecd4d7eSDavid Wu 			reset_control_deassert(priv->phy_reset);
1475fecd4d7eSDavid Wu 		usleep_range(10, 20);
1476fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
1477fecd4d7eSDavid Wu 		msleep(30);
1478fecd4d7eSDavid Wu 	}
1479fecd4d7eSDavid Wu }
1480fecd4d7eSDavid Wu 
1481fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
1482fecd4d7eSDavid Wu {
1483fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1484fecd4d7eSDavid Wu 	if (priv->phy_reset)
1485fecd4d7eSDavid Wu 		reset_control_assert(priv->phy_reset);
1486fecd4d7eSDavid Wu }
1487fecd4d7eSDavid Wu 
1488fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
1489fecd4d7eSDavid Wu {
1490fecd4d7eSDavid Wu 	struct rk_priv_data *bsp_priv = plat->bsp_priv;
14917ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
1492ea449f7fSSebastian Reichel 	int phy_iface = bsp_priv->phy_iface;
1493ea449f7fSSebastian Reichel 	int i, j, ret;
14947ad269eaSRoger Chen 
14957ad269eaSRoger Chen 	bsp_priv->clk_enabled = false;
14967ad269eaSRoger Chen 
1497ea449f7fSSebastian Reichel 	bsp_priv->num_clks = ARRAY_SIZE(rk_clocks);
1498ea449f7fSSebastian Reichel 	if (phy_iface == PHY_INTERFACE_MODE_RMII)
1499ea449f7fSSebastian Reichel 		bsp_priv->num_clks += ARRAY_SIZE(rk_rmii_clocks);
15007ad269eaSRoger Chen 
1501ea449f7fSSebastian Reichel 	bsp_priv->clks = devm_kcalloc(dev, bsp_priv->num_clks,
1502ea449f7fSSebastian Reichel 				      sizeof(*bsp_priv->clks), GFP_KERNEL);
1503ea449f7fSSebastian Reichel 	if (!bsp_priv->clks)
1504ea449f7fSSebastian Reichel 		return -ENOMEM;
15057ad269eaSRoger Chen 
1506ea449f7fSSebastian Reichel 	for (i = 0; i < ARRAY_SIZE(rk_clocks); i++)
1507ea449f7fSSebastian Reichel 		bsp_priv->clks[i].id = rk_clocks[i];
15087ad269eaSRoger Chen 
1509ea449f7fSSebastian Reichel 	if (phy_iface == PHY_INTERFACE_MODE_RMII) {
1510ea449f7fSSebastian Reichel 		for (j = 0; j < ARRAY_SIZE(rk_rmii_clocks); j++)
1511ea449f7fSSebastian Reichel 			bsp_priv->clks[i++].id = rk_rmii_clocks[j];
1512ea449f7fSSebastian Reichel 	}
15137ad269eaSRoger Chen 
1514ea449f7fSSebastian Reichel 	ret = devm_clk_bulk_get_optional(dev, bsp_priv->num_clks,
1515ea449f7fSSebastian Reichel 					 bsp_priv->clks);
1516ea449f7fSSebastian Reichel 	if (ret)
1517ea449f7fSSebastian Reichel 		return dev_err_probe(dev, ret, "Failed to get clocks\n");
1518ea449f7fSSebastian Reichel 
1519ea449f7fSSebastian Reichel 	/* "stmmaceth" will be enabled by the core */
15207ad269eaSRoger Chen 	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
1521ea449f7fSSebastian Reichel 	ret = PTR_ERR_OR_ZERO(bsp_priv->clk_mac);
1522ea449f7fSSebastian Reichel 	if (ret)
1523ea449f7fSSebastian Reichel 		return dev_err_probe(dev, ret, "Cannot get stmmaceth clock\n");
152423c94d63SDavid Wu 
15257ad269eaSRoger Chen 	if (bsp_priv->clock_input) {
1526d42202dcSRomain Perier 		dev_info(dev, "clock input from PHY\n");
1527ea449f7fSSebastian Reichel 	} else if (phy_iface == PHY_INTERFACE_MODE_RMII) {
1528c48fa33cSHeiko Stübner 		clk_set_rate(bsp_priv->clk_mac, 50000000);
15297ad269eaSRoger Chen 	}
15307ad269eaSRoger Chen 
1531fecd4d7eSDavid Wu 	if (plat->phy_node && bsp_priv->integrated_phy) {
1532fecd4d7eSDavid Wu 		bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
1533ea449f7fSSebastian Reichel 		ret = PTR_ERR_OR_ZERO(bsp_priv->clk_phy);
1534ea449f7fSSebastian Reichel 		if (ret)
1535ea449f7fSSebastian Reichel 			return dev_err_probe(dev, ret, "Cannot get PHY clock\n");
1536fecd4d7eSDavid Wu 		clk_set_rate(bsp_priv->clk_phy, 50000000);
1537fecd4d7eSDavid Wu 	}
1538fecd4d7eSDavid Wu 
15397ad269eaSRoger Chen 	return 0;
15407ad269eaSRoger Chen }
15417ad269eaSRoger Chen 
15427ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
15437ad269eaSRoger Chen {
1544ea449f7fSSebastian Reichel 	int ret;
15457ad269eaSRoger Chen 
15467ad269eaSRoger Chen 	if (enable) {
15477ad269eaSRoger Chen 		if (!bsp_priv->clk_enabled) {
1548ea449f7fSSebastian Reichel 			ret = clk_bulk_prepare_enable(bsp_priv->num_clks,
1549ea449f7fSSebastian Reichel 						      bsp_priv->clks);
1550ea449f7fSSebastian Reichel 			if (ret)
1551ea449f7fSSebastian Reichel 				return ret;
15527ad269eaSRoger Chen 
1553ea449f7fSSebastian Reichel 			ret = clk_prepare_enable(bsp_priv->clk_phy);
1554ea449f7fSSebastian Reichel 			if (ret)
1555ea449f7fSSebastian Reichel 				return ret;
155623c94d63SDavid Wu 
15572f2b60a0SDavid Wu 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
15582f2b60a0SDavid Wu 				bsp_priv->ops->set_clock_selection(bsp_priv,
15592f2b60a0SDavid Wu 					       bsp_priv->clock_input, true);
15602f2b60a0SDavid Wu 
15617ad269eaSRoger Chen 			mdelay(5);
15627ad269eaSRoger Chen 			bsp_priv->clk_enabled = true;
15637ad269eaSRoger Chen 		}
15647ad269eaSRoger Chen 	} else {
15657ad269eaSRoger Chen 		if (bsp_priv->clk_enabled) {
1566ea449f7fSSebastian Reichel 			clk_bulk_disable_unprepare(bsp_priv->num_clks,
1567ea449f7fSSebastian Reichel 						   bsp_priv->clks);
1568fecd4d7eSDavid Wu 			clk_disable_unprepare(bsp_priv->clk_phy);
1569fecd4d7eSDavid Wu 
15702f2b60a0SDavid Wu 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
15712f2b60a0SDavid Wu 				bsp_priv->ops->set_clock_selection(bsp_priv,
15722f2b60a0SDavid Wu 					      bsp_priv->clock_input, false);
1573ea449f7fSSebastian Reichel 
15747ad269eaSRoger Chen 			bsp_priv->clk_enabled = false;
15757ad269eaSRoger Chen 		}
15767ad269eaSRoger Chen 	}
15777ad269eaSRoger Chen 
15787ad269eaSRoger Chen 	return 0;
15797ad269eaSRoger Chen }
15807ad269eaSRoger Chen 
15817ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
15827ad269eaSRoger Chen {
15832e12f536SRomain Perier 	struct regulator *ldo = bsp_priv->regulator;
15847ad269eaSRoger Chen 	int ret;
15857ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
15867ad269eaSRoger Chen 
15877ad269eaSRoger Chen 	if (enable) {
15887ad269eaSRoger Chen 		ret = regulator_enable(ldo);
15892e12f536SRomain Perier 		if (ret)
1590d42202dcSRomain Perier 			dev_err(dev, "fail to enable phy-supply\n");
15917ad269eaSRoger Chen 	} else {
15927ad269eaSRoger Chen 		ret = regulator_disable(ldo);
15932e12f536SRomain Perier 		if (ret)
1594d42202dcSRomain Perier 			dev_err(dev, "fail to disable phy-supply\n");
15957ad269eaSRoger Chen 	}
15967ad269eaSRoger Chen 
15977ad269eaSRoger Chen 	return 0;
15987ad269eaSRoger Chen }
15997ad269eaSRoger Chen 
16000fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1601fecd4d7eSDavid Wu 					  struct plat_stmmacenet_data *plat,
160292c2588fSJoachim Eastwood 					  const struct rk_gmac_ops *ops)
16037ad269eaSRoger Chen {
16047ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv;
16057ad269eaSRoger Chen 	struct device *dev = &pdev->dev;
16063bb3d6b1SDavid Wu 	struct resource *res;
16077ad269eaSRoger Chen 	int ret;
16087ad269eaSRoger Chen 	const char *strings = NULL;
16097ad269eaSRoger Chen 	int value;
16107ad269eaSRoger Chen 
16117ad269eaSRoger Chen 	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
16127ad269eaSRoger Chen 	if (!bsp_priv)
16137ad269eaSRoger Chen 		return ERR_PTR(-ENOMEM);
16147ad269eaSRoger Chen 
16150c65b2b9SAndrew Lunn 	of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
16160fb98db1SHeiko Stübner 	bsp_priv->ops = ops;
16177ad269eaSRoger Chen 
16183bb3d6b1SDavid Wu 	/* Some SoCs have multiple MAC controllers, which need
16193bb3d6b1SDavid Wu 	 * to be distinguished.
16203bb3d6b1SDavid Wu 	 */
16213bb3d6b1SDavid Wu 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
16220546b224SJohn Keeping 	if (res && ops->regs_valid) {
16233bb3d6b1SDavid Wu 		int i = 0;
16243bb3d6b1SDavid Wu 
16253bb3d6b1SDavid Wu 		while (ops->regs[i]) {
16263bb3d6b1SDavid Wu 			if (ops->regs[i] == res->start) {
16273bb3d6b1SDavid Wu 				bsp_priv->id = i;
16283bb3d6b1SDavid Wu 				break;
16293bb3d6b1SDavid Wu 			}
16303bb3d6b1SDavid Wu 			i++;
16313bb3d6b1SDavid Wu 		}
16323bb3d6b1SDavid Wu 	}
16333bb3d6b1SDavid Wu 
1634db219732SSebastian Reichel 	bsp_priv->regulator = devm_regulator_get(dev, "phy");
16352e12f536SRomain Perier 	if (IS_ERR(bsp_priv->regulator)) {
1636db219732SSebastian Reichel 		ret = PTR_ERR(bsp_priv->regulator);
1637db219732SSebastian Reichel 		dev_err_probe(dev, ret, "failed to get phy regulator\n");
1638db219732SSebastian Reichel 		return ERR_PTR(ret);
16397ad269eaSRoger Chen 	}
16407ad269eaSRoger Chen 
16417ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
16427ad269eaSRoger Chen 	if (ret) {
1643d42202dcSRomain Perier 		dev_err(dev, "Can not read property: clock_in_out.\n");
16447ad269eaSRoger Chen 		bsp_priv->clock_input = true;
16457ad269eaSRoger Chen 	} else {
1646d42202dcSRomain Perier 		dev_info(dev, "clock input or output? (%s).\n",
1647d42202dcSRomain Perier 			 strings);
16487ad269eaSRoger Chen 		if (!strcmp(strings, "input"))
16497ad269eaSRoger Chen 			bsp_priv->clock_input = true;
16507ad269eaSRoger Chen 		else
16517ad269eaSRoger Chen 			bsp_priv->clock_input = false;
16527ad269eaSRoger Chen 	}
16537ad269eaSRoger Chen 
16547ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
16557ad269eaSRoger Chen 	if (ret) {
16567ad269eaSRoger Chen 		bsp_priv->tx_delay = 0x30;
1657d42202dcSRomain Perier 		dev_err(dev, "Can not read property: tx_delay.");
1658d42202dcSRomain Perier 		dev_err(dev, "set tx_delay to 0x%x\n",
1659d42202dcSRomain Perier 			bsp_priv->tx_delay);
16607ad269eaSRoger Chen 	} else {
1661d42202dcSRomain Perier 		dev_info(dev, "TX delay(0x%x).\n", value);
16627ad269eaSRoger Chen 		bsp_priv->tx_delay = value;
16637ad269eaSRoger Chen 	}
16647ad269eaSRoger Chen 
16657ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
16667ad269eaSRoger Chen 	if (ret) {
16677ad269eaSRoger Chen 		bsp_priv->rx_delay = 0x10;
1668d42202dcSRomain Perier 		dev_err(dev, "Can not read property: rx_delay.");
1669d42202dcSRomain Perier 		dev_err(dev, "set rx_delay to 0x%x\n",
1670d42202dcSRomain Perier 			bsp_priv->rx_delay);
16717ad269eaSRoger Chen 	} else {
1672d42202dcSRomain Perier 		dev_info(dev, "RX delay(0x%x).\n", value);
16737ad269eaSRoger Chen 		bsp_priv->rx_delay = value;
16747ad269eaSRoger Chen 	}
16757ad269eaSRoger Chen 
16767ad269eaSRoger Chen 	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
16777ad269eaSRoger Chen 							"rockchip,grf");
16782f2b60a0SDavid Wu 	bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
16792f2b60a0SDavid Wu 							    "rockchip,php-grf");
16807ad269eaSRoger Chen 
1681fecd4d7eSDavid Wu 	if (plat->phy_node) {
1682fecd4d7eSDavid Wu 		bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
1683fecd4d7eSDavid Wu 								 "phy-is-integrated");
1684fecd4d7eSDavid Wu 		if (bsp_priv->integrated_phy) {
1685fecd4d7eSDavid Wu 			bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
1686fecd4d7eSDavid Wu 			if (IS_ERR(bsp_priv->phy_reset)) {
1687fecd4d7eSDavid Wu 				dev_err(&pdev->dev, "No PHY reset control found.\n");
1688fecd4d7eSDavid Wu 				bsp_priv->phy_reset = NULL;
1689fecd4d7eSDavid Wu 			}
1690fecd4d7eSDavid Wu 		}
1691fecd4d7eSDavid Wu 	}
1692fecd4d7eSDavid Wu 	dev_info(dev, "integrated PHY? (%s).\n",
1693fecd4d7eSDavid Wu 		 bsp_priv->integrated_phy ? "yes" : "no");
1694fecd4d7eSDavid Wu 
1695fecd4d7eSDavid Wu 	bsp_priv->pdev = pdev;
169645383f52SRoger Chen 
169745383f52SRoger Chen 	return bsp_priv;
169845383f52SRoger Chen }
169945383f52SRoger Chen 
170037c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv)
170137c80d15SDavid Wu {
170237c80d15SDavid Wu 	switch (bsp_priv->phy_iface) {
170337c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII:
170437c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_ID:
170537c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_RXID:
170637c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_TXID:
170737c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rgmii)
170837c80d15SDavid Wu 			return -EINVAL;
170937c80d15SDavid Wu 		break;
171037c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RMII:
171137c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rmii)
171237c80d15SDavid Wu 			return -EINVAL;
171337c80d15SDavid Wu 		break;
171437c80d15SDavid Wu 	default:
171537c80d15SDavid Wu 		dev_err(&bsp_priv->pdev->dev,
171637c80d15SDavid Wu 			"unsupported interface %d", bsp_priv->phy_iface);
171737c80d15SDavid Wu 	}
171837c80d15SDavid Wu 	return 0;
171937c80d15SDavid Wu }
172037c80d15SDavid Wu 
172145383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
172245383f52SRoger Chen {
172345383f52SRoger Chen 	int ret;
172445383f52SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
172545383f52SRoger Chen 
172637c80d15SDavid Wu 	ret = rk_gmac_check_ops(bsp_priv);
172737c80d15SDavid Wu 	if (ret)
172837c80d15SDavid Wu 		return ret;
172937c80d15SDavid Wu 
1730f217bfdeSHeiko Stübner 	ret = gmac_clk_enable(bsp_priv, true);
1731f217bfdeSHeiko Stübner 	if (ret)
1732f217bfdeSHeiko Stübner 		return ret;
1733f217bfdeSHeiko Stübner 
17347ad269eaSRoger Chen 	/*rmii or rgmii*/
1735eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1736eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1737d42202dcSRomain Perier 		dev_info(dev, "init for RGMII\n");
17380fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
17390fb98db1SHeiko Stübner 					    bsp_priv->rx_delay);
1740eaf70ad1SWadim Egorov 		break;
1741eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1742eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_ID\n");
1743eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
1744eaf70ad1SWadim Egorov 		break;
1745eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1746eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_RXID\n");
1747eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
1748eaf70ad1SWadim Egorov 		break;
1749eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
1750eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_TXID\n");
1751eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
1752eaf70ad1SWadim Egorov 		break;
1753eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
1754d42202dcSRomain Perier 		dev_info(dev, "init for RMII\n");
17550fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rmii(bsp_priv);
1756eaf70ad1SWadim Egorov 		break;
1757eaf70ad1SWadim Egorov 	default:
1758d42202dcSRomain Perier 		dev_err(dev, "NO interface defined!\n");
17597ad269eaSRoger Chen 	}
17607ad269eaSRoger Chen 
17617ad269eaSRoger Chen 	ret = phy_power_on(bsp_priv, true);
1762c69c29a1SAlexey Khoroshilov 	if (ret) {
1763c69c29a1SAlexey Khoroshilov 		gmac_clk_enable(bsp_priv, false);
17647ad269eaSRoger Chen 		return ret;
1765c69c29a1SAlexey Khoroshilov 	}
17667ad269eaSRoger Chen 
1767aec3f415SPunit Agrawal 	pm_runtime_get_sync(dev);
1768aec3f415SPunit Agrawal 
1769fecd4d7eSDavid Wu 	if (bsp_priv->integrated_phy)
1770fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerup(bsp_priv);
1771fecd4d7eSDavid Wu 
17727ad269eaSRoger Chen 	return 0;
17737ad269eaSRoger Chen }
17747ad269eaSRoger Chen 
1775229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac)
17767ad269eaSRoger Chen {
1777fecd4d7eSDavid Wu 	if (gmac->integrated_phy)
1778fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerdown(gmac);
1779fecd4d7eSDavid Wu 
1780aec3f415SPunit Agrawal 	pm_runtime_put_sync(&gmac->pdev->dev);
1781aec3f415SPunit Agrawal 
17827ad269eaSRoger Chen 	phy_power_on(gmac, false);
17837ad269eaSRoger Chen 	gmac_clk_enable(gmac, false);
17847ad269eaSRoger Chen }
17857ad269eaSRoger Chen 
17861fc04a0bSShenwei Wang static void rk_fix_speed(void *priv, unsigned int speed, unsigned int mode)
17877ad269eaSRoger Chen {
17887ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
17897ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
17907ad269eaSRoger Chen 
1791eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1792eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1793eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1794eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1795eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
179637c80d15SDavid Wu 		if (bsp_priv->ops->set_rgmii_speed)
17970fb98db1SHeiko Stübner 			bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1798eaf70ad1SWadim Egorov 		break;
1799eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
180037c80d15SDavid Wu 		if (bsp_priv->ops->set_rmii_speed)
18010fb98db1SHeiko Stübner 			bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1802eaf70ad1SWadim Egorov 		break;
1803eaf70ad1SWadim Egorov 	default:
18047ad269eaSRoger Chen 		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
18057ad269eaSRoger Chen 	}
1806eaf70ad1SWadim Egorov }
18077ad269eaSRoger Chen 
180827ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev)
180927ffefd2SJoachim Eastwood {
181027ffefd2SJoachim Eastwood 	struct plat_stmmacenet_data *plat_dat;
181127ffefd2SJoachim Eastwood 	struct stmmac_resources stmmac_res;
1812f529f182SJoachim Eastwood 	const struct rk_gmac_ops *data;
181327ffefd2SJoachim Eastwood 	int ret;
181427ffefd2SJoachim Eastwood 
1815149adeddSJoachim Eastwood 	data = of_device_get_match_data(&pdev->dev);
1816149adeddSJoachim Eastwood 	if (!data) {
1817149adeddSJoachim Eastwood 		dev_err(&pdev->dev, "no of match data provided\n");
1818149adeddSJoachim Eastwood 		return -EINVAL;
1819149adeddSJoachim Eastwood 	}
1820149adeddSJoachim Eastwood 
182127ffefd2SJoachim Eastwood 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
182227ffefd2SJoachim Eastwood 	if (ret)
182327ffefd2SJoachim Eastwood 		return ret;
182427ffefd2SJoachim Eastwood 
18258eee20e1SJisheng Zhang 	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
182627ffefd2SJoachim Eastwood 	if (IS_ERR(plat_dat))
182727ffefd2SJoachim Eastwood 		return PTR_ERR(plat_dat);
182827ffefd2SJoachim Eastwood 
1829d6b06251SEzequiel Garcia 	/* If the stmmac is not already selected as gmac4,
1830d6b06251SEzequiel Garcia 	 * then make sure we fallback to gmac.
1831d6b06251SEzequiel Garcia 	 */
1832d6b06251SEzequiel Garcia 	if (!plat_dat->has_gmac4)
183327ffefd2SJoachim Eastwood 		plat_dat->has_gmac = true;
183427ffefd2SJoachim Eastwood 	plat_dat->fix_mac_speed = rk_fix_speed;
183527ffefd2SJoachim Eastwood 
1836fecd4d7eSDavid Wu 	plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
18378eee20e1SJisheng Zhang 	if (IS_ERR(plat_dat->bsp_priv))
18388eee20e1SJisheng Zhang 		return PTR_ERR(plat_dat->bsp_priv);
183927ffefd2SJoachim Eastwood 
1840fecd4d7eSDavid Wu 	ret = rk_gmac_clk_init(plat_dat);
1841fecd4d7eSDavid Wu 	if (ret)
18428eee20e1SJisheng Zhang 		return ret;
1843fecd4d7eSDavid Wu 
184407a5e769SJoachim Eastwood 	ret = rk_gmac_powerup(plat_dat->bsp_priv);
184527ffefd2SJoachim Eastwood 	if (ret)
18468eee20e1SJisheng Zhang 		return ret;
184727ffefd2SJoachim Eastwood 
18482d222656SJohan Hovold 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
18492d222656SJohan Hovold 	if (ret)
18502745529aSDavid S. Miller 		goto err_gmac_powerdown;
18512d222656SJohan Hovold 
18522d222656SJohan Hovold 	return 0;
18532d222656SJohan Hovold 
18542745529aSDavid S. Miller err_gmac_powerdown:
18552745529aSDavid S. Miller 	rk_gmac_powerdown(plat_dat->bsp_priv);
18562d222656SJohan Hovold 
18572d222656SJohan Hovold 	return ret;
185827ffefd2SJoachim Eastwood }
185927ffefd2SJoachim Eastwood 
1860903cc461SUwe Kleine-König static void rk_gmac_remove(struct platform_device *pdev)
18610de8c4c9SJoachim Eastwood {
18620de8c4c9SJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
1863ff0011cfSUwe Kleine-König 
1864ff0011cfSUwe Kleine-König 	stmmac_dvr_remove(&pdev->dev);
18650de8c4c9SJoachim Eastwood 
18660de8c4c9SJoachim Eastwood 	rk_gmac_powerdown(bsp_priv);
18670de8c4c9SJoachim Eastwood }
18680de8c4c9SJoachim Eastwood 
18695619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP
18705619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev)
18715619468aSJoachim Eastwood {
18725619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
18735619468aSJoachim Eastwood 	int ret = stmmac_suspend(dev);
18745619468aSJoachim Eastwood 
18755619468aSJoachim Eastwood 	/* Keep the PHY up if we use Wake-on-Lan. */
18765619468aSJoachim Eastwood 	if (!device_may_wakeup(dev)) {
18775619468aSJoachim Eastwood 		rk_gmac_powerdown(bsp_priv);
18785619468aSJoachim Eastwood 		bsp_priv->suspended = true;
18795619468aSJoachim Eastwood 	}
18805619468aSJoachim Eastwood 
18815619468aSJoachim Eastwood 	return ret;
18825619468aSJoachim Eastwood }
18835619468aSJoachim Eastwood 
18845619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev)
18855619468aSJoachim Eastwood {
18865619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
18875619468aSJoachim Eastwood 
18885619468aSJoachim Eastwood 	/* The PHY was up for Wake-on-Lan. */
18895619468aSJoachim Eastwood 	if (bsp_priv->suspended) {
18905619468aSJoachim Eastwood 		rk_gmac_powerup(bsp_priv);
18915619468aSJoachim Eastwood 		bsp_priv->suspended = false;
18925619468aSJoachim Eastwood 	}
18935619468aSJoachim Eastwood 
18945619468aSJoachim Eastwood 	return stmmac_resume(dev);
18955619468aSJoachim Eastwood }
18965619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */
18975619468aSJoachim Eastwood 
18985619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
18995619468aSJoachim Eastwood 
1900e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = {
190123c94d63SDavid Wu 	{ .compatible = "rockchip,px30-gmac",	.data = &px30_ops   },
190205946876SDavid Wu 	{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
1903e7ffd812SXing Zheng 	{ .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
1904f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
1905b4ac9456STobias Schramm 	{ .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops },
1906d4ff816eSdavid.wu 	{ .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
1907ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
1908f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
1909ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
19103bb3d6b1SDavid Wu 	{ .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
19112f2b60a0SDavid Wu 	{ .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops },
191289c9c163SDavid Wu 	{ .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
1913c931b060SAnand Moon 	{ .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops },
1914e0fb4013SJoachim Eastwood 	{ }
1915e0fb4013SJoachim Eastwood };
1916e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
1917e0fb4013SJoachim Eastwood 
1918e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = {
191927ffefd2SJoachim Eastwood 	.probe  = rk_gmac_probe,
1920903cc461SUwe Kleine-König 	.remove_new = rk_gmac_remove,
1921e0fb4013SJoachim Eastwood 	.driver = {
1922e0fb4013SJoachim Eastwood 		.name           = "rk_gmac-dwmac",
19235619468aSJoachim Eastwood 		.pm		= &rk_gmac_pm_ops,
1924e0fb4013SJoachim Eastwood 		.of_match_table = rk_gmac_dwmac_match,
1925e0fb4013SJoachim Eastwood 	},
1926e0fb4013SJoachim Eastwood };
1927e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver);
1928e0fb4013SJoachim Eastwood 
1929e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
1930e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
1931e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL");
1932