xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c (revision 9410645520e9b820069761f3450ef6661418e279)
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 
px30_set_to_rmii(struct rk_priv_data * bsp_priv)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 
px30_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3128_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)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 
rk3128_set_to_rmii(struct rk_priv_data * bsp_priv)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 
rk3128_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3128_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3228_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)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 
rk3228_set_to_rmii(struct rk_priv_data * bsp_priv)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 
rk3228_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3228_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3228_integrated_phy_powerup(struct rk_priv_data * priv)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 
rk3288_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)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 
rk3288_set_to_rmii(struct rk_priv_data * bsp_priv)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 
rk3288_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3288_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3308_set_to_rmii(struct rk_priv_data * bsp_priv)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 
rk3308_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3328_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)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 
rk3328_set_to_rmii(struct rk_priv_data * bsp_priv)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 
rk3328_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3328_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3328_integrated_phy_powerup(struct rk_priv_data * priv)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 
rk3366_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)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 
rk3366_set_to_rmii(struct rk_priv_data * bsp_priv)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 
rk3366_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3366_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3368_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)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 
rk3368_set_to_rmii(struct rk_priv_data * bsp_priv)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 
rk3368_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3368_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3399_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)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 
rk3399_set_to_rmii(struct rk_priv_data * bsp_priv)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 
rk3399_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3399_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)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 
rk3568_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)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 
rk3568_set_to_rmii(struct rk_priv_data * bsp_priv)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 
rk3568_set_gmac_speed(struct rk_priv_data * bsp_priv,int speed)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 
1119*f9cc9997SDavid Wu /* VCCIO0_1_3_IOC */
1120*f9cc9997SDavid Wu #define RK3576_VCCIO0_1_3_IOC_CON2		0X6408
1121*f9cc9997SDavid Wu #define RK3576_VCCIO0_1_3_IOC_CON3		0X640c
1122*f9cc9997SDavid Wu #define RK3576_VCCIO0_1_3_IOC_CON4		0X6410
1123*f9cc9997SDavid Wu #define RK3576_VCCIO0_1_3_IOC_CON5		0X6414
1124*f9cc9997SDavid Wu 
1125*f9cc9997SDavid Wu #define RK3576_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(15)
1126*f9cc9997SDavid Wu #define RK3576_GMAC_RXCLK_DLY_DISABLE		GRF_CLR_BIT(15)
1127*f9cc9997SDavid Wu #define RK3576_GMAC_TXCLK_DLY_ENABLE		GRF_BIT(7)
1128*f9cc9997SDavid Wu #define RK3576_GMAC_TXCLK_DLY_DISABLE		GRF_CLR_BIT(7)
1129*f9cc9997SDavid Wu 
1130*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0x7F, 8)
1131*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0x7F, 0)
1132*f9cc9997SDavid Wu 
1133*f9cc9997SDavid Wu /* SDGMAC_GRF */
1134*f9cc9997SDavid Wu #define RK3576_GRF_GMAC_CON0			0X0020
1135*f9cc9997SDavid Wu #define RK3576_GRF_GMAC_CON1			0X0024
1136*f9cc9997SDavid Wu 
1137*f9cc9997SDavid Wu #define RK3576_GMAC_RMII_MODE			GRF_BIT(3)
1138*f9cc9997SDavid Wu #define RK3576_GMAC_RGMII_MODE			GRF_CLR_BIT(3)
1139*f9cc9997SDavid Wu 
1140*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_SELECT_IO		GRF_BIT(7)
1141*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_SELECT_CRU		GRF_CLR_BIT(7)
1142*f9cc9997SDavid Wu 
1143*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RMII_DIV2		GRF_BIT(5)
1144*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RMII_DIV20		GRF_CLR_BIT(5)
1145*f9cc9997SDavid Wu 
1146*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RGMII_DIV1		\
1147*f9cc9997SDavid Wu 			(GRF_CLR_BIT(6) | GRF_CLR_BIT(5))
1148*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RGMII_DIV5		\
1149*f9cc9997SDavid Wu 			(GRF_BIT(6) | GRF_BIT(5))
1150*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RGMII_DIV50		\
1151*f9cc9997SDavid Wu 			(GRF_BIT(6) | GRF_CLR_BIT(5))
1152*f9cc9997SDavid Wu 
1153*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RMII_GATE		GRF_BIT(4)
1154*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RMII_NOGATE		GRF_CLR_BIT(4)
1155*f9cc9997SDavid Wu 
rk3576_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)1156*f9cc9997SDavid Wu static void rk3576_set_to_rgmii(struct rk_priv_data *bsp_priv,
1157*f9cc9997SDavid Wu 				int tx_delay, int rx_delay)
1158*f9cc9997SDavid Wu {
1159*f9cc9997SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
1160*f9cc9997SDavid Wu 	unsigned int offset_con;
1161*f9cc9997SDavid Wu 
1162*f9cc9997SDavid Wu 	if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
1163*f9cc9997SDavid Wu 		dev_err(dev, "Missing rockchip,grf or rockchip,php-grf property\n");
1164*f9cc9997SDavid Wu 		return;
1165*f9cc9997SDavid Wu 	}
1166*f9cc9997SDavid Wu 
1167*f9cc9997SDavid Wu 	offset_con = bsp_priv->id == 1 ? RK3576_GRF_GMAC_CON1 :
1168*f9cc9997SDavid Wu 					 RK3576_GRF_GMAC_CON0;
1169*f9cc9997SDavid Wu 
1170*f9cc9997SDavid Wu 	regmap_write(bsp_priv->grf, offset_con, RK3576_GMAC_RGMII_MODE);
1171*f9cc9997SDavid Wu 
1172*f9cc9997SDavid Wu 	offset_con = bsp_priv->id == 1 ? RK3576_VCCIO0_1_3_IOC_CON4 :
1173*f9cc9997SDavid Wu 					 RK3576_VCCIO0_1_3_IOC_CON2;
1174*f9cc9997SDavid Wu 
1175*f9cc9997SDavid Wu 	/* m0 && m1 delay enabled */
1176*f9cc9997SDavid Wu 	regmap_write(bsp_priv->php_grf, offset_con,
1177*f9cc9997SDavid Wu 		     DELAY_ENABLE(RK3576, tx_delay, rx_delay));
1178*f9cc9997SDavid Wu 	regmap_write(bsp_priv->php_grf, offset_con + 0x4,
1179*f9cc9997SDavid Wu 		     DELAY_ENABLE(RK3576, tx_delay, rx_delay));
1180*f9cc9997SDavid Wu 
1181*f9cc9997SDavid Wu 	/* m0 && m1 delay value */
1182*f9cc9997SDavid Wu 	regmap_write(bsp_priv->php_grf, offset_con,
1183*f9cc9997SDavid Wu 		     RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) |
1184*f9cc9997SDavid Wu 		     RK3576_GMAC_CLK_RX_DL_CFG(rx_delay));
1185*f9cc9997SDavid Wu 	regmap_write(bsp_priv->php_grf, offset_con + 0x4,
1186*f9cc9997SDavid Wu 		     RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) |
1187*f9cc9997SDavid Wu 		     RK3576_GMAC_CLK_RX_DL_CFG(rx_delay));
1188*f9cc9997SDavid Wu }
1189*f9cc9997SDavid Wu 
rk3576_set_to_rmii(struct rk_priv_data * bsp_priv)1190*f9cc9997SDavid Wu static void rk3576_set_to_rmii(struct rk_priv_data *bsp_priv)
1191*f9cc9997SDavid Wu {
1192*f9cc9997SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
1193*f9cc9997SDavid Wu 	unsigned int offset_con;
1194*f9cc9997SDavid Wu 
1195*f9cc9997SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
1196*f9cc9997SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1197*f9cc9997SDavid Wu 		return;
1198*f9cc9997SDavid Wu 	}
1199*f9cc9997SDavid Wu 
1200*f9cc9997SDavid Wu 	offset_con = bsp_priv->id == 1 ? RK3576_GRF_GMAC_CON1 :
1201*f9cc9997SDavid Wu 					 RK3576_GRF_GMAC_CON0;
1202*f9cc9997SDavid Wu 
1203*f9cc9997SDavid Wu 	regmap_write(bsp_priv->grf, offset_con, RK3576_GMAC_RMII_MODE);
1204*f9cc9997SDavid Wu }
1205*f9cc9997SDavid Wu 
rk3576_set_gmac_speed(struct rk_priv_data * bsp_priv,int speed)1206*f9cc9997SDavid Wu static void rk3576_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
1207*f9cc9997SDavid Wu {
1208*f9cc9997SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
1209*f9cc9997SDavid Wu 	unsigned int val = 0, offset_con;
1210*f9cc9997SDavid Wu 
1211*f9cc9997SDavid Wu 	switch (speed) {
1212*f9cc9997SDavid Wu 	case 10:
1213*f9cc9997SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1214*f9cc9997SDavid Wu 			val = RK3576_GMAC_CLK_RMII_DIV20;
1215*f9cc9997SDavid Wu 		else
1216*f9cc9997SDavid Wu 			val = RK3576_GMAC_CLK_RGMII_DIV50;
1217*f9cc9997SDavid Wu 		break;
1218*f9cc9997SDavid Wu 	case 100:
1219*f9cc9997SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1220*f9cc9997SDavid Wu 			val = RK3576_GMAC_CLK_RMII_DIV2;
1221*f9cc9997SDavid Wu 		else
1222*f9cc9997SDavid Wu 			val = RK3576_GMAC_CLK_RGMII_DIV5;
1223*f9cc9997SDavid Wu 		break;
1224*f9cc9997SDavid Wu 	case 1000:
1225*f9cc9997SDavid Wu 		if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
1226*f9cc9997SDavid Wu 			val = RK3576_GMAC_CLK_RGMII_DIV1;
1227*f9cc9997SDavid Wu 		else
1228*f9cc9997SDavid Wu 			goto err;
1229*f9cc9997SDavid Wu 		break;
1230*f9cc9997SDavid Wu 	default:
1231*f9cc9997SDavid Wu 		goto err;
1232*f9cc9997SDavid Wu 	}
1233*f9cc9997SDavid Wu 
1234*f9cc9997SDavid Wu 	offset_con = bsp_priv->id == 1 ? RK3576_GRF_GMAC_CON1 :
1235*f9cc9997SDavid Wu 					 RK3576_GRF_GMAC_CON0;
1236*f9cc9997SDavid Wu 
1237*f9cc9997SDavid Wu 	regmap_write(bsp_priv->grf, offset_con, val);
1238*f9cc9997SDavid Wu 
1239*f9cc9997SDavid Wu 	return;
1240*f9cc9997SDavid Wu err:
1241*f9cc9997SDavid Wu 	dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
1242*f9cc9997SDavid Wu }
1243*f9cc9997SDavid Wu 
rk3576_set_clock_selection(struct rk_priv_data * bsp_priv,bool input,bool enable)1244*f9cc9997SDavid Wu static void rk3576_set_clock_selection(struct rk_priv_data *bsp_priv, bool input,
1245*f9cc9997SDavid Wu 				       bool enable)
1246*f9cc9997SDavid Wu {
1247*f9cc9997SDavid Wu 	unsigned int val = input ? RK3576_GMAC_CLK_SELECT_IO :
1248*f9cc9997SDavid Wu 				   RK3576_GMAC_CLK_SELECT_CRU;
1249*f9cc9997SDavid Wu 	unsigned int offset_con;
1250*f9cc9997SDavid Wu 
1251*f9cc9997SDavid Wu 	val |= enable ? RK3576_GMAC_CLK_RMII_NOGATE :
1252*f9cc9997SDavid Wu 			RK3576_GMAC_CLK_RMII_GATE;
1253*f9cc9997SDavid Wu 
1254*f9cc9997SDavid Wu 	offset_con = bsp_priv->id == 1 ? RK3576_GRF_GMAC_CON1 :
1255*f9cc9997SDavid Wu 					 RK3576_GRF_GMAC_CON0;
1256*f9cc9997SDavid Wu 
1257*f9cc9997SDavid Wu 	regmap_write(bsp_priv->grf, offset_con, val);
1258*f9cc9997SDavid Wu }
1259*f9cc9997SDavid Wu 
1260*f9cc9997SDavid Wu static const struct rk_gmac_ops rk3576_ops = {
1261*f9cc9997SDavid Wu 	.set_to_rgmii = rk3576_set_to_rgmii,
1262*f9cc9997SDavid Wu 	.set_to_rmii = rk3576_set_to_rmii,
1263*f9cc9997SDavid Wu 	.set_rgmii_speed = rk3576_set_gmac_speed,
1264*f9cc9997SDavid Wu 	.set_rmii_speed = rk3576_set_gmac_speed,
1265*f9cc9997SDavid Wu 	.set_clock_selection = rk3576_set_clock_selection,
1266*f9cc9997SDavid Wu 	.regs_valid = true,
1267*f9cc9997SDavid Wu 	.regs = {
1268*f9cc9997SDavid Wu 		0x2a220000, /* gmac0 */
1269*f9cc9997SDavid Wu 		0x2a230000, /* gmac1 */
1270*f9cc9997SDavid Wu 		0x0, /* sentinel */
1271*f9cc9997SDavid Wu 	},
1272*f9cc9997SDavid Wu };
1273*f9cc9997SDavid Wu 
12742f2b60a0SDavid Wu /* sys_grf */
12752f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON7			0X031c
12762f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON8			0X0320
12772f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON9			0X0324
12782f2b60a0SDavid Wu 
12792f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 3)
12802f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 3)
12812f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 2)
12822f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 2)
12832f2b60a0SDavid Wu 
12842f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 8)
12852f2b60a0SDavid Wu #define RK3588_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 0)
12862f2b60a0SDavid Wu 
12872f2b60a0SDavid Wu /* php_grf */
12882f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON0			0X0008
12892f2b60a0SDavid Wu #define RK3588_GRF_CLK_CON1			0X0070
12902f2b60a0SDavid Wu 
12912f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
12922f2b60a0SDavid Wu 	(GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
12932f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
12942f2b60a0SDavid Wu 	(GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
12952f2b60a0SDavid Wu 
12962f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
12972f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
12982f2b60a0SDavid Wu 
129978a60497SDetlev Casanova #define RK3588_GMAC_CLK_SELECT_CRU(id)		GRF_BIT(5 * (id) + 4)
130078a60497SDetlev Casanova #define RK3588_GMAC_CLK_SELECT_IO(id)		GRF_CLR_BIT(5 * (id) + 4)
13012f2b60a0SDavid Wu 
13022f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV2(id)		GRF_BIT(5 * (id) + 2)
13032f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV20(id)		GRF_CLR_BIT(5 * (id) + 2)
13042f2b60a0SDavid Wu 
13052f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV1(id)		\
13062f2b60a0SDavid Wu 			(GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
13072f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV5(id)		\
13082f2b60a0SDavid Wu 			(GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
13092f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV50(id)		\
13102f2b60a0SDavid Wu 			(GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
13112f2b60a0SDavid Wu 
13122f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_GATE(id)		GRF_BIT(5 * (id) + 1)
13132f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_NOGATE(id)		GRF_CLR_BIT(5 * (id) + 1)
13142f2b60a0SDavid Wu 
rk3588_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)13152f2b60a0SDavid Wu static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
13162f2b60a0SDavid Wu 				int tx_delay, int rx_delay)
13172f2b60a0SDavid Wu {
13182f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
13192f2b60a0SDavid Wu 	u32 offset_con, id = bsp_priv->id;
13202f2b60a0SDavid Wu 
13212f2b60a0SDavid Wu 	if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
13222f2b60a0SDavid Wu 		dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n");
13232f2b60a0SDavid Wu 		return;
13242f2b60a0SDavid Wu 	}
13252f2b60a0SDavid Wu 
13262f2b60a0SDavid Wu 	offset_con = bsp_priv->id == 1 ? RK3588_GRF_GMAC_CON9 :
13272f2b60a0SDavid Wu 					 RK3588_GRF_GMAC_CON8;
13282f2b60a0SDavid Wu 
13292f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
13302f2b60a0SDavid Wu 		     RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
13312f2b60a0SDavid Wu 
13322f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
13332f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RGMII_MODE(id));
13342f2b60a0SDavid Wu 
13352f2b60a0SDavid Wu 	regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7,
13362f2b60a0SDavid Wu 		     RK3588_GMAC_RXCLK_DLY_ENABLE(id) |
13372f2b60a0SDavid Wu 		     RK3588_GMAC_TXCLK_DLY_ENABLE(id));
13382f2b60a0SDavid Wu 
13392f2b60a0SDavid Wu 	regmap_write(bsp_priv->grf, offset_con,
13402f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
13412f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
13422f2b60a0SDavid Wu }
13432f2b60a0SDavid Wu 
rk3588_set_to_rmii(struct rk_priv_data * bsp_priv)13442f2b60a0SDavid Wu static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv)
13452f2b60a0SDavid Wu {
13462f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
13472f2b60a0SDavid Wu 
13482f2b60a0SDavid Wu 	if (IS_ERR(bsp_priv->php_grf)) {
13492f2b60a0SDavid Wu 		dev_err(dev, "%s: Missing rockchip,php_grf property\n", __func__);
13502f2b60a0SDavid Wu 		return;
13512f2b60a0SDavid Wu 	}
13522f2b60a0SDavid Wu 
13532f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
13542f2b60a0SDavid Wu 		     RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->id));
13552f2b60a0SDavid Wu 
13562f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
13572f2b60a0SDavid Wu 		     RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id));
13582f2b60a0SDavid Wu }
13592f2b60a0SDavid Wu 
rk3588_set_gmac_speed(struct rk_priv_data * bsp_priv,int speed)13602f2b60a0SDavid Wu static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
13612f2b60a0SDavid Wu {
13622f2b60a0SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
13632f2b60a0SDavid Wu 	unsigned int val = 0, id = bsp_priv->id;
13642f2b60a0SDavid Wu 
13652f2b60a0SDavid Wu 	switch (speed) {
13662f2b60a0SDavid Wu 	case 10:
13672f2b60a0SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
13682f2b60a0SDavid Wu 			val = RK3588_GMA_CLK_RMII_DIV20(id);
13692f2b60a0SDavid Wu 		else
13702f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV50(id);
13712f2b60a0SDavid Wu 		break;
13722f2b60a0SDavid Wu 	case 100:
13732f2b60a0SDavid Wu 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
13742f2b60a0SDavid Wu 			val = RK3588_GMA_CLK_RMII_DIV2(id);
13752f2b60a0SDavid Wu 		else
13762f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV5(id);
13772f2b60a0SDavid Wu 		break;
13782f2b60a0SDavid Wu 	case 1000:
13792f2b60a0SDavid Wu 		if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
13802f2b60a0SDavid Wu 			val = RK3588_GMAC_CLK_RGMII_DIV1(id);
13812f2b60a0SDavid Wu 		else
13822f2b60a0SDavid Wu 			goto err;
13832f2b60a0SDavid Wu 		break;
13842f2b60a0SDavid Wu 	default:
13852f2b60a0SDavid Wu 		goto err;
13862f2b60a0SDavid Wu 	}
13872f2b60a0SDavid Wu 
13882f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
13892f2b60a0SDavid Wu 
13902f2b60a0SDavid Wu 	return;
13912f2b60a0SDavid Wu err:
13922f2b60a0SDavid Wu 	dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
13932f2b60a0SDavid Wu }
13942f2b60a0SDavid Wu 
rk3588_set_clock_selection(struct rk_priv_data * bsp_priv,bool input,bool enable)13952f2b60a0SDavid Wu static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input,
13962f2b60a0SDavid Wu 				       bool enable)
13972f2b60a0SDavid Wu {
139878a60497SDetlev Casanova 	unsigned int val = input ? RK3588_GMAC_CLK_SELECT_IO(bsp_priv->id) :
139978a60497SDetlev Casanova 				   RK3588_GMAC_CLK_SELECT_CRU(bsp_priv->id);
14002f2b60a0SDavid Wu 
14012f2b60a0SDavid Wu 	val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->id) :
14022f2b60a0SDavid Wu 			RK3588_GMAC_CLK_RMII_GATE(bsp_priv->id);
14032f2b60a0SDavid Wu 
14042f2b60a0SDavid Wu 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
14052f2b60a0SDavid Wu }
14062f2b60a0SDavid Wu 
14072f2b60a0SDavid Wu static const struct rk_gmac_ops rk3588_ops = {
14082f2b60a0SDavid Wu 	.set_to_rgmii = rk3588_set_to_rgmii,
14092f2b60a0SDavid Wu 	.set_to_rmii = rk3588_set_to_rmii,
14102f2b60a0SDavid Wu 	.set_rgmii_speed = rk3588_set_gmac_speed,
14112f2b60a0SDavid Wu 	.set_rmii_speed = rk3588_set_gmac_speed,
14122f2b60a0SDavid Wu 	.set_clock_selection = rk3588_set_clock_selection,
141388619e77SBenjamin Gaignard 	.regs_valid = true,
141488619e77SBenjamin Gaignard 	.regs = {
141588619e77SBenjamin Gaignard 		0xfe1b0000, /* gmac0 */
141688619e77SBenjamin Gaignard 		0xfe1c0000, /* gmac1 */
141788619e77SBenjamin Gaignard 		0x0, /* sentinel */
141888619e77SBenjamin Gaignard 	},
14192f2b60a0SDavid Wu };
14202f2b60a0SDavid Wu 
142189c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0		0X0900
142289c9c163SDavid Wu 
142389c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */
142489c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
142589c9c163SDavid Wu 					GRF_BIT(6))
142689c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
142789c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
142889c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
142989c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M		GRF_BIT(2)
143089c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M	GRF_BIT(7)
143189c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
143289c9c163SDavid Wu 
rv1108_set_to_rmii(struct rk_priv_data * bsp_priv)143389c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
143489c9c163SDavid Wu {
143589c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
143689c9c163SDavid Wu 
143789c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
143889c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
143989c9c163SDavid Wu 		return;
144089c9c163SDavid Wu 	}
144189c9c163SDavid Wu 
144289c9c163SDavid Wu 	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
144389c9c163SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
144489c9c163SDavid Wu }
144589c9c163SDavid Wu 
rv1108_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)144689c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
144789c9c163SDavid Wu {
144889c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
144989c9c163SDavid Wu 
145089c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
145189c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
145289c9c163SDavid Wu 		return;
145389c9c163SDavid Wu 	}
145489c9c163SDavid Wu 
145589c9c163SDavid Wu 	if (speed == 10) {
145689c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
145789c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_2_5M |
145889c9c163SDavid Wu 			     RV1108_GMAC_SPEED_10M);
145989c9c163SDavid Wu 	} else if (speed == 100) {
146089c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
146189c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_25M |
146289c9c163SDavid Wu 			     RV1108_GMAC_SPEED_100M);
146389c9c163SDavid Wu 	} else {
146489c9c163SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
146589c9c163SDavid Wu 	}
146689c9c163SDavid Wu }
146789c9c163SDavid Wu 
146889c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = {
146989c9c163SDavid Wu 	.set_to_rmii = rv1108_set_to_rmii,
147089c9c163SDavid Wu 	.set_rmii_speed = rv1108_set_rmii_speed,
147189c9c163SDavid Wu };
147289c9c163SDavid Wu 
1473c931b060SAnand Moon #define RV1126_GRF_GMAC_CON0		0X0070
1474c931b060SAnand Moon #define RV1126_GRF_GMAC_CON1		0X0074
1475c931b060SAnand Moon #define RV1126_GRF_GMAC_CON2		0X0078
1476c931b060SAnand Moon 
1477c931b060SAnand Moon /* RV1126_GRF_GMAC_CON0 */
1478c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RGMII	\
1479c931b060SAnand Moon 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
1480c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RMII	\
1481c931b060SAnand Moon 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
1482c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL			GRF_BIT(7)
1483c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(7)
1484c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE		GRF_BIT(1)
1485c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
1486c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_ENABLE		GRF_BIT(0)
1487c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
1488c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_ENABLE		GRF_BIT(3)
1489c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_DISABLE	GRF_CLR_BIT(3)
1490c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_ENABLE		GRF_BIT(2)
1491c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_DISABLE	GRF_CLR_BIT(2)
1492c931b060SAnand Moon 
1493c931b060SAnand Moon /* RV1126_GRF_GMAC_CON1 */
1494c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
1495c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
1496c931b060SAnand Moon /* RV1126_GRF_GMAC_CON2 */
1497c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
1498c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
1499c931b060SAnand Moon 
rv1126_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)1500c931b060SAnand Moon static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
1501c931b060SAnand Moon 				int tx_delay, int rx_delay)
1502c931b060SAnand Moon {
1503c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1504c931b060SAnand Moon 
1505c931b060SAnand Moon 	if (IS_ERR(bsp_priv->grf)) {
1506c931b060SAnand Moon 		dev_err(dev, "Missing rockchip,grf property\n");
1507c931b060SAnand Moon 		return;
1508c931b060SAnand Moon 	}
1509c931b060SAnand Moon 
1510c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1511c931b060SAnand Moon 		     RV1126_GMAC_PHY_INTF_SEL_RGMII |
1512c931b060SAnand Moon 		     RV1126_GMAC_M0_RXCLK_DLY_ENABLE |
1513c931b060SAnand Moon 		     RV1126_GMAC_M0_TXCLK_DLY_ENABLE |
1514c931b060SAnand Moon 		     RV1126_GMAC_M1_RXCLK_DLY_ENABLE |
1515c931b060SAnand Moon 		     RV1126_GMAC_M1_TXCLK_DLY_ENABLE);
1516c931b060SAnand Moon 
1517c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1,
1518c931b060SAnand Moon 		     RV1126_GMAC_M0_CLK_RX_DL_CFG(rx_delay) |
1519c931b060SAnand Moon 		     RV1126_GMAC_M0_CLK_TX_DL_CFG(tx_delay));
1520c931b060SAnand Moon 
1521c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2,
1522c931b060SAnand Moon 		     RV1126_GMAC_M1_CLK_RX_DL_CFG(rx_delay) |
1523c931b060SAnand Moon 		     RV1126_GMAC_M1_CLK_TX_DL_CFG(tx_delay));
1524c931b060SAnand Moon }
1525c931b060SAnand Moon 
rv1126_set_to_rmii(struct rk_priv_data * bsp_priv)1526c931b060SAnand Moon static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv)
1527c931b060SAnand Moon {
1528c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1529c931b060SAnand Moon 
1530c931b060SAnand Moon 	if (IS_ERR(bsp_priv->grf)) {
1531c931b060SAnand Moon 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1532c931b060SAnand Moon 		return;
1533c931b060SAnand Moon 	}
1534c931b060SAnand Moon 
1535c931b060SAnand Moon 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1536c931b060SAnand Moon 		     RV1126_GMAC_PHY_INTF_SEL_RMII);
1537c931b060SAnand Moon }
1538c931b060SAnand Moon 
rv1126_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)1539c931b060SAnand Moon static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
1540c931b060SAnand Moon {
1541ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
1542c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1543c931b060SAnand Moon 	unsigned long rate;
1544c931b060SAnand Moon 	int ret;
1545c931b060SAnand Moon 
1546c931b060SAnand Moon 	switch (speed) {
1547c931b060SAnand Moon 	case 10:
1548c931b060SAnand Moon 		rate = 2500000;
1549c931b060SAnand Moon 		break;
1550c931b060SAnand Moon 	case 100:
1551c931b060SAnand Moon 		rate = 25000000;
1552c931b060SAnand Moon 		break;
1553c931b060SAnand Moon 	case 1000:
1554c931b060SAnand Moon 		rate = 125000000;
1555c931b060SAnand Moon 		break;
1556c931b060SAnand Moon 	default:
1557c931b060SAnand Moon 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1558c931b060SAnand Moon 		return;
1559c931b060SAnand Moon 	}
1560c931b060SAnand Moon 
1561ea449f7fSSebastian Reichel 	ret = clk_set_rate(clk_mac_speed, rate);
1562c931b060SAnand Moon 	if (ret)
1563c931b060SAnand Moon 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1564c931b060SAnand Moon 			__func__, rate, ret);
1565c931b060SAnand Moon }
1566c931b060SAnand Moon 
rv1126_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)1567c931b060SAnand Moon static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
1568c931b060SAnand Moon {
1569ea449f7fSSebastian Reichel 	struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
1570c931b060SAnand Moon 	struct device *dev = &bsp_priv->pdev->dev;
1571c931b060SAnand Moon 	unsigned long rate;
1572c931b060SAnand Moon 	int ret;
1573c931b060SAnand Moon 
1574c931b060SAnand Moon 	switch (speed) {
1575c931b060SAnand Moon 	case 10:
1576c931b060SAnand Moon 		rate = 2500000;
1577c931b060SAnand Moon 		break;
1578c931b060SAnand Moon 	case 100:
1579c931b060SAnand Moon 		rate = 25000000;
1580c931b060SAnand Moon 		break;
1581c931b060SAnand Moon 	default:
1582c931b060SAnand Moon 		dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1583c931b060SAnand Moon 		return;
1584c931b060SAnand Moon 	}
1585c931b060SAnand Moon 
1586ea449f7fSSebastian Reichel 	ret = clk_set_rate(clk_mac_speed, rate);
1587c931b060SAnand Moon 	if (ret)
1588c931b060SAnand Moon 		dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1589c931b060SAnand Moon 			__func__, rate, ret);
1590c931b060SAnand Moon }
1591c931b060SAnand Moon 
1592c931b060SAnand Moon static const struct rk_gmac_ops rv1126_ops = {
1593c931b060SAnand Moon 	.set_to_rgmii = rv1126_set_to_rgmii,
1594c931b060SAnand Moon 	.set_to_rmii = rv1126_set_to_rmii,
1595c931b060SAnand Moon 	.set_rgmii_speed = rv1126_set_rgmii_speed,
1596c931b060SAnand Moon 	.set_rmii_speed = rv1126_set_rmii_speed,
1597c931b060SAnand Moon };
1598c931b060SAnand Moon 
1599fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0		0xb00
1600fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1		0xb04
1601fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2		0xb08
1602fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3		0xb0c
1603fecd4d7eSDavid Wu 
1604fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE		GRF_BIT(0)
1605fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
1606fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
1607fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
1608fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID		HIWORD_UPDATE(0x1234, 0xffff, 0)
1609fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID		HIWORD_UPDATE(0x35, 0x3f, 0)
1610fecd4d7eSDavid Wu 
rk_gmac_integrated_phy_powerup(struct rk_priv_data * priv)1611fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
16127ad269eaSRoger Chen {
1613fecd4d7eSDavid Wu 	if (priv->ops->integrated_phy_powerup)
1614fecd4d7eSDavid Wu 		priv->ops->integrated_phy_powerup(priv);
1615fecd4d7eSDavid Wu 
1616fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
1617fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
1618fecd4d7eSDavid Wu 
1619fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
1620fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
1621fecd4d7eSDavid Wu 
1622fecd4d7eSDavid Wu 	if (priv->phy_reset) {
1623fecd4d7eSDavid Wu 		/* PHY needs to be disabled before trying to reset it */
1624fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1625fecd4d7eSDavid Wu 		if (priv->phy_reset)
1626fecd4d7eSDavid Wu 			reset_control_assert(priv->phy_reset);
1627fecd4d7eSDavid Wu 		usleep_range(10, 20);
1628fecd4d7eSDavid Wu 		if (priv->phy_reset)
1629fecd4d7eSDavid Wu 			reset_control_deassert(priv->phy_reset);
1630fecd4d7eSDavid Wu 		usleep_range(10, 20);
1631fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
1632fecd4d7eSDavid Wu 		msleep(30);
1633fecd4d7eSDavid Wu 	}
1634fecd4d7eSDavid Wu }
1635fecd4d7eSDavid Wu 
rk_gmac_integrated_phy_powerdown(struct rk_priv_data * priv)1636fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
1637fecd4d7eSDavid Wu {
1638fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1639fecd4d7eSDavid Wu 	if (priv->phy_reset)
1640fecd4d7eSDavid Wu 		reset_control_assert(priv->phy_reset);
1641fecd4d7eSDavid Wu }
1642fecd4d7eSDavid Wu 
rk_gmac_clk_init(struct plat_stmmacenet_data * plat)1643fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
1644fecd4d7eSDavid Wu {
1645fecd4d7eSDavid Wu 	struct rk_priv_data *bsp_priv = plat->bsp_priv;
16467ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
1647ea449f7fSSebastian Reichel 	int phy_iface = bsp_priv->phy_iface;
1648ea449f7fSSebastian Reichel 	int i, j, ret;
16497ad269eaSRoger Chen 
16507ad269eaSRoger Chen 	bsp_priv->clk_enabled = false;
16517ad269eaSRoger Chen 
1652ea449f7fSSebastian Reichel 	bsp_priv->num_clks = ARRAY_SIZE(rk_clocks);
1653ea449f7fSSebastian Reichel 	if (phy_iface == PHY_INTERFACE_MODE_RMII)
1654ea449f7fSSebastian Reichel 		bsp_priv->num_clks += ARRAY_SIZE(rk_rmii_clocks);
16557ad269eaSRoger Chen 
1656ea449f7fSSebastian Reichel 	bsp_priv->clks = devm_kcalloc(dev, bsp_priv->num_clks,
1657ea449f7fSSebastian Reichel 				      sizeof(*bsp_priv->clks), GFP_KERNEL);
1658ea449f7fSSebastian Reichel 	if (!bsp_priv->clks)
1659ea449f7fSSebastian Reichel 		return -ENOMEM;
16607ad269eaSRoger Chen 
1661ea449f7fSSebastian Reichel 	for (i = 0; i < ARRAY_SIZE(rk_clocks); i++)
1662ea449f7fSSebastian Reichel 		bsp_priv->clks[i].id = rk_clocks[i];
16637ad269eaSRoger Chen 
1664ea449f7fSSebastian Reichel 	if (phy_iface == PHY_INTERFACE_MODE_RMII) {
1665ea449f7fSSebastian Reichel 		for (j = 0; j < ARRAY_SIZE(rk_rmii_clocks); j++)
1666ea449f7fSSebastian Reichel 			bsp_priv->clks[i++].id = rk_rmii_clocks[j];
1667ea449f7fSSebastian Reichel 	}
16687ad269eaSRoger Chen 
1669ea449f7fSSebastian Reichel 	ret = devm_clk_bulk_get_optional(dev, bsp_priv->num_clks,
1670ea449f7fSSebastian Reichel 					 bsp_priv->clks);
1671ea449f7fSSebastian Reichel 	if (ret)
1672ea449f7fSSebastian Reichel 		return dev_err_probe(dev, ret, "Failed to get clocks\n");
1673ea449f7fSSebastian Reichel 
1674ea449f7fSSebastian Reichel 	/* "stmmaceth" will be enabled by the core */
16757ad269eaSRoger Chen 	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
1676ea449f7fSSebastian Reichel 	ret = PTR_ERR_OR_ZERO(bsp_priv->clk_mac);
1677ea449f7fSSebastian Reichel 	if (ret)
1678ea449f7fSSebastian Reichel 		return dev_err_probe(dev, ret, "Cannot get stmmaceth clock\n");
167923c94d63SDavid Wu 
16807ad269eaSRoger Chen 	if (bsp_priv->clock_input) {
1681d42202dcSRomain Perier 		dev_info(dev, "clock input from PHY\n");
1682ea449f7fSSebastian Reichel 	} else if (phy_iface == PHY_INTERFACE_MODE_RMII) {
1683c48fa33cSHeiko Stübner 		clk_set_rate(bsp_priv->clk_mac, 50000000);
16847ad269eaSRoger Chen 	}
16857ad269eaSRoger Chen 
1686fecd4d7eSDavid Wu 	if (plat->phy_node && bsp_priv->integrated_phy) {
1687fecd4d7eSDavid Wu 		bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
1688ea449f7fSSebastian Reichel 		ret = PTR_ERR_OR_ZERO(bsp_priv->clk_phy);
1689ea449f7fSSebastian Reichel 		if (ret)
1690ea449f7fSSebastian Reichel 			return dev_err_probe(dev, ret, "Cannot get PHY clock\n");
1691fecd4d7eSDavid Wu 		clk_set_rate(bsp_priv->clk_phy, 50000000);
1692fecd4d7eSDavid Wu 	}
1693fecd4d7eSDavid Wu 
16947ad269eaSRoger Chen 	return 0;
16957ad269eaSRoger Chen }
16967ad269eaSRoger Chen 
gmac_clk_enable(struct rk_priv_data * bsp_priv,bool enable)16977ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
16987ad269eaSRoger Chen {
1699ea449f7fSSebastian Reichel 	int ret;
17007ad269eaSRoger Chen 
17017ad269eaSRoger Chen 	if (enable) {
17027ad269eaSRoger Chen 		if (!bsp_priv->clk_enabled) {
1703ea449f7fSSebastian Reichel 			ret = clk_bulk_prepare_enable(bsp_priv->num_clks,
1704ea449f7fSSebastian Reichel 						      bsp_priv->clks);
1705ea449f7fSSebastian Reichel 			if (ret)
1706ea449f7fSSebastian Reichel 				return ret;
17077ad269eaSRoger Chen 
1708ea449f7fSSebastian Reichel 			ret = clk_prepare_enable(bsp_priv->clk_phy);
1709ea449f7fSSebastian Reichel 			if (ret)
1710ea449f7fSSebastian Reichel 				return ret;
171123c94d63SDavid Wu 
17122f2b60a0SDavid Wu 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
17132f2b60a0SDavid Wu 				bsp_priv->ops->set_clock_selection(bsp_priv,
17142f2b60a0SDavid Wu 					       bsp_priv->clock_input, true);
17152f2b60a0SDavid Wu 
17167ad269eaSRoger Chen 			mdelay(5);
17177ad269eaSRoger Chen 			bsp_priv->clk_enabled = true;
17187ad269eaSRoger Chen 		}
17197ad269eaSRoger Chen 	} else {
17207ad269eaSRoger Chen 		if (bsp_priv->clk_enabled) {
1721ea449f7fSSebastian Reichel 			clk_bulk_disable_unprepare(bsp_priv->num_clks,
1722ea449f7fSSebastian Reichel 						   bsp_priv->clks);
1723fecd4d7eSDavid Wu 			clk_disable_unprepare(bsp_priv->clk_phy);
1724fecd4d7eSDavid Wu 
17252f2b60a0SDavid Wu 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
17262f2b60a0SDavid Wu 				bsp_priv->ops->set_clock_selection(bsp_priv,
17272f2b60a0SDavid Wu 					      bsp_priv->clock_input, false);
1728ea449f7fSSebastian Reichel 
17297ad269eaSRoger Chen 			bsp_priv->clk_enabled = false;
17307ad269eaSRoger Chen 		}
17317ad269eaSRoger Chen 	}
17327ad269eaSRoger Chen 
17337ad269eaSRoger Chen 	return 0;
17347ad269eaSRoger Chen }
17357ad269eaSRoger Chen 
phy_power_on(struct rk_priv_data * bsp_priv,bool enable)17367ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
17377ad269eaSRoger Chen {
17382e12f536SRomain Perier 	struct regulator *ldo = bsp_priv->regulator;
17397ad269eaSRoger Chen 	int ret;
17407ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
17417ad269eaSRoger Chen 
17427ad269eaSRoger Chen 	if (enable) {
17437ad269eaSRoger Chen 		ret = regulator_enable(ldo);
17442e12f536SRomain Perier 		if (ret)
1745d42202dcSRomain Perier 			dev_err(dev, "fail to enable phy-supply\n");
17467ad269eaSRoger Chen 	} else {
17477ad269eaSRoger Chen 		ret = regulator_disable(ldo);
17482e12f536SRomain Perier 		if (ret)
1749d42202dcSRomain Perier 			dev_err(dev, "fail to disable phy-supply\n");
17507ad269eaSRoger Chen 	}
17517ad269eaSRoger Chen 
17527ad269eaSRoger Chen 	return 0;
17537ad269eaSRoger Chen }
17547ad269eaSRoger Chen 
rk_gmac_setup(struct platform_device * pdev,struct plat_stmmacenet_data * plat,const struct rk_gmac_ops * ops)17550fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1756fecd4d7eSDavid Wu 					  struct plat_stmmacenet_data *plat,
175792c2588fSJoachim Eastwood 					  const struct rk_gmac_ops *ops)
17587ad269eaSRoger Chen {
17597ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv;
17607ad269eaSRoger Chen 	struct device *dev = &pdev->dev;
17613bb3d6b1SDavid Wu 	struct resource *res;
17627ad269eaSRoger Chen 	int ret;
17637ad269eaSRoger Chen 	const char *strings = NULL;
17647ad269eaSRoger Chen 	int value;
17657ad269eaSRoger Chen 
17667ad269eaSRoger Chen 	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
17677ad269eaSRoger Chen 	if (!bsp_priv)
17687ad269eaSRoger Chen 		return ERR_PTR(-ENOMEM);
17697ad269eaSRoger Chen 
17700c65b2b9SAndrew Lunn 	of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
17710fb98db1SHeiko Stübner 	bsp_priv->ops = ops;
17727ad269eaSRoger Chen 
17733bb3d6b1SDavid Wu 	/* Some SoCs have multiple MAC controllers, which need
17743bb3d6b1SDavid Wu 	 * to be distinguished.
17753bb3d6b1SDavid Wu 	 */
17763bb3d6b1SDavid Wu 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
17770546b224SJohn Keeping 	if (res && ops->regs_valid) {
17783bb3d6b1SDavid Wu 		int i = 0;
17793bb3d6b1SDavid Wu 
17803bb3d6b1SDavid Wu 		while (ops->regs[i]) {
17813bb3d6b1SDavid Wu 			if (ops->regs[i] == res->start) {
17823bb3d6b1SDavid Wu 				bsp_priv->id = i;
17833bb3d6b1SDavid Wu 				break;
17843bb3d6b1SDavid Wu 			}
17853bb3d6b1SDavid Wu 			i++;
17863bb3d6b1SDavid Wu 		}
17873bb3d6b1SDavid Wu 	}
17883bb3d6b1SDavid Wu 
1789db219732SSebastian Reichel 	bsp_priv->regulator = devm_regulator_get(dev, "phy");
17902e12f536SRomain Perier 	if (IS_ERR(bsp_priv->regulator)) {
1791db219732SSebastian Reichel 		ret = PTR_ERR(bsp_priv->regulator);
1792db219732SSebastian Reichel 		dev_err_probe(dev, ret, "failed to get phy regulator\n");
1793db219732SSebastian Reichel 		return ERR_PTR(ret);
17947ad269eaSRoger Chen 	}
17957ad269eaSRoger Chen 
17967ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
17977ad269eaSRoger Chen 	if (ret) {
1798d42202dcSRomain Perier 		dev_err(dev, "Can not read property: clock_in_out.\n");
17997ad269eaSRoger Chen 		bsp_priv->clock_input = true;
18007ad269eaSRoger Chen 	} else {
1801d42202dcSRomain Perier 		dev_info(dev, "clock input or output? (%s).\n",
1802d42202dcSRomain Perier 			 strings);
18037ad269eaSRoger Chen 		if (!strcmp(strings, "input"))
18047ad269eaSRoger Chen 			bsp_priv->clock_input = true;
18057ad269eaSRoger Chen 		else
18067ad269eaSRoger Chen 			bsp_priv->clock_input = false;
18077ad269eaSRoger Chen 	}
18087ad269eaSRoger Chen 
18097ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
18107ad269eaSRoger Chen 	if (ret) {
18117ad269eaSRoger Chen 		bsp_priv->tx_delay = 0x30;
1812d42202dcSRomain Perier 		dev_err(dev, "Can not read property: tx_delay.");
1813d42202dcSRomain Perier 		dev_err(dev, "set tx_delay to 0x%x\n",
1814d42202dcSRomain Perier 			bsp_priv->tx_delay);
18157ad269eaSRoger Chen 	} else {
1816d42202dcSRomain Perier 		dev_info(dev, "TX delay(0x%x).\n", value);
18177ad269eaSRoger Chen 		bsp_priv->tx_delay = value;
18187ad269eaSRoger Chen 	}
18197ad269eaSRoger Chen 
18207ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
18217ad269eaSRoger Chen 	if (ret) {
18227ad269eaSRoger Chen 		bsp_priv->rx_delay = 0x10;
1823d42202dcSRomain Perier 		dev_err(dev, "Can not read property: rx_delay.");
1824d42202dcSRomain Perier 		dev_err(dev, "set rx_delay to 0x%x\n",
1825d42202dcSRomain Perier 			bsp_priv->rx_delay);
18267ad269eaSRoger Chen 	} else {
1827d42202dcSRomain Perier 		dev_info(dev, "RX delay(0x%x).\n", value);
18287ad269eaSRoger Chen 		bsp_priv->rx_delay = value;
18297ad269eaSRoger Chen 	}
18307ad269eaSRoger Chen 
18317ad269eaSRoger Chen 	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
18327ad269eaSRoger Chen 							"rockchip,grf");
18332f2b60a0SDavid Wu 	bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
18342f2b60a0SDavid Wu 							    "rockchip,php-grf");
18357ad269eaSRoger Chen 
1836fecd4d7eSDavid Wu 	if (plat->phy_node) {
1837fecd4d7eSDavid Wu 		bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
1838fecd4d7eSDavid Wu 								 "phy-is-integrated");
1839fecd4d7eSDavid Wu 		if (bsp_priv->integrated_phy) {
1840fecd4d7eSDavid Wu 			bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
1841fecd4d7eSDavid Wu 			if (IS_ERR(bsp_priv->phy_reset)) {
1842fecd4d7eSDavid Wu 				dev_err(&pdev->dev, "No PHY reset control found.\n");
1843fecd4d7eSDavid Wu 				bsp_priv->phy_reset = NULL;
1844fecd4d7eSDavid Wu 			}
1845fecd4d7eSDavid Wu 		}
1846fecd4d7eSDavid Wu 	}
1847fecd4d7eSDavid Wu 	dev_info(dev, "integrated PHY? (%s).\n",
1848fecd4d7eSDavid Wu 		 bsp_priv->integrated_phy ? "yes" : "no");
1849fecd4d7eSDavid Wu 
1850fecd4d7eSDavid Wu 	bsp_priv->pdev = pdev;
185145383f52SRoger Chen 
185245383f52SRoger Chen 	return bsp_priv;
185345383f52SRoger Chen }
185445383f52SRoger Chen 
rk_gmac_check_ops(struct rk_priv_data * bsp_priv)185537c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv)
185637c80d15SDavid Wu {
185737c80d15SDavid Wu 	switch (bsp_priv->phy_iface) {
185837c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII:
185937c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_ID:
186037c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_RXID:
186137c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RGMII_TXID:
186237c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rgmii)
186337c80d15SDavid Wu 			return -EINVAL;
186437c80d15SDavid Wu 		break;
186537c80d15SDavid Wu 	case PHY_INTERFACE_MODE_RMII:
186637c80d15SDavid Wu 		if (!bsp_priv->ops->set_to_rmii)
186737c80d15SDavid Wu 			return -EINVAL;
186837c80d15SDavid Wu 		break;
186937c80d15SDavid Wu 	default:
187037c80d15SDavid Wu 		dev_err(&bsp_priv->pdev->dev,
187137c80d15SDavid Wu 			"unsupported interface %d", bsp_priv->phy_iface);
187237c80d15SDavid Wu 	}
187337c80d15SDavid Wu 	return 0;
187437c80d15SDavid Wu }
187537c80d15SDavid Wu 
rk_gmac_powerup(struct rk_priv_data * bsp_priv)187645383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
187745383f52SRoger Chen {
187845383f52SRoger Chen 	int ret;
187945383f52SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
188045383f52SRoger Chen 
188137c80d15SDavid Wu 	ret = rk_gmac_check_ops(bsp_priv);
188237c80d15SDavid Wu 	if (ret)
188337c80d15SDavid Wu 		return ret;
188437c80d15SDavid Wu 
1885f217bfdeSHeiko Stübner 	ret = gmac_clk_enable(bsp_priv, true);
1886f217bfdeSHeiko Stübner 	if (ret)
1887f217bfdeSHeiko Stübner 		return ret;
1888f217bfdeSHeiko Stübner 
18897ad269eaSRoger Chen 	/*rmii or rgmii*/
1890eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1891eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1892d42202dcSRomain Perier 		dev_info(dev, "init for RGMII\n");
18930fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
18940fb98db1SHeiko Stübner 					    bsp_priv->rx_delay);
1895eaf70ad1SWadim Egorov 		break;
1896eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1897eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_ID\n");
1898eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
1899eaf70ad1SWadim Egorov 		break;
1900eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1901eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_RXID\n");
1902eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
1903eaf70ad1SWadim Egorov 		break;
1904eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
1905eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_TXID\n");
1906eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
1907eaf70ad1SWadim Egorov 		break;
1908eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
1909d42202dcSRomain Perier 		dev_info(dev, "init for RMII\n");
19100fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rmii(bsp_priv);
1911eaf70ad1SWadim Egorov 		break;
1912eaf70ad1SWadim Egorov 	default:
1913d42202dcSRomain Perier 		dev_err(dev, "NO interface defined!\n");
19147ad269eaSRoger Chen 	}
19157ad269eaSRoger Chen 
19167ad269eaSRoger Chen 	ret = phy_power_on(bsp_priv, true);
1917c69c29a1SAlexey Khoroshilov 	if (ret) {
1918c69c29a1SAlexey Khoroshilov 		gmac_clk_enable(bsp_priv, false);
19197ad269eaSRoger Chen 		return ret;
1920c69c29a1SAlexey Khoroshilov 	}
19217ad269eaSRoger Chen 
1922aec3f415SPunit Agrawal 	pm_runtime_get_sync(dev);
1923aec3f415SPunit Agrawal 
1924fecd4d7eSDavid Wu 	if (bsp_priv->integrated_phy)
1925fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerup(bsp_priv);
1926fecd4d7eSDavid Wu 
19277ad269eaSRoger Chen 	return 0;
19287ad269eaSRoger Chen }
19297ad269eaSRoger Chen 
rk_gmac_powerdown(struct rk_priv_data * gmac)1930229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac)
19317ad269eaSRoger Chen {
1932fecd4d7eSDavid Wu 	if (gmac->integrated_phy)
1933fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerdown(gmac);
1934fecd4d7eSDavid Wu 
1935aec3f415SPunit Agrawal 	pm_runtime_put_sync(&gmac->pdev->dev);
1936aec3f415SPunit Agrawal 
19377ad269eaSRoger Chen 	phy_power_on(gmac, false);
19387ad269eaSRoger Chen 	gmac_clk_enable(gmac, false);
19397ad269eaSRoger Chen }
19407ad269eaSRoger Chen 
rk_fix_speed(void * priv,unsigned int speed,unsigned int mode)19411fc04a0bSShenwei Wang static void rk_fix_speed(void *priv, unsigned int speed, unsigned int mode)
19427ad269eaSRoger Chen {
19437ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
19447ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
19457ad269eaSRoger Chen 
1946eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1947eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1948eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1949eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1950eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
195137c80d15SDavid Wu 		if (bsp_priv->ops->set_rgmii_speed)
19520fb98db1SHeiko Stübner 			bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1953eaf70ad1SWadim Egorov 		break;
1954eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
195537c80d15SDavid Wu 		if (bsp_priv->ops->set_rmii_speed)
19560fb98db1SHeiko Stübner 			bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1957eaf70ad1SWadim Egorov 		break;
1958eaf70ad1SWadim Egorov 	default:
19597ad269eaSRoger Chen 		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
19607ad269eaSRoger Chen 	}
1961eaf70ad1SWadim Egorov }
19627ad269eaSRoger Chen 
rk_gmac_probe(struct platform_device * pdev)196327ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev)
196427ffefd2SJoachim Eastwood {
196527ffefd2SJoachim Eastwood 	struct plat_stmmacenet_data *plat_dat;
196627ffefd2SJoachim Eastwood 	struct stmmac_resources stmmac_res;
1967f529f182SJoachim Eastwood 	const struct rk_gmac_ops *data;
196827ffefd2SJoachim Eastwood 	int ret;
196927ffefd2SJoachim Eastwood 
1970149adeddSJoachim Eastwood 	data = of_device_get_match_data(&pdev->dev);
1971149adeddSJoachim Eastwood 	if (!data) {
1972149adeddSJoachim Eastwood 		dev_err(&pdev->dev, "no of match data provided\n");
1973149adeddSJoachim Eastwood 		return -EINVAL;
1974149adeddSJoachim Eastwood 	}
1975149adeddSJoachim Eastwood 
197627ffefd2SJoachim Eastwood 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
197727ffefd2SJoachim Eastwood 	if (ret)
197827ffefd2SJoachim Eastwood 		return ret;
197927ffefd2SJoachim Eastwood 
19808eee20e1SJisheng Zhang 	plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
198127ffefd2SJoachim Eastwood 	if (IS_ERR(plat_dat))
198227ffefd2SJoachim Eastwood 		return PTR_ERR(plat_dat);
198327ffefd2SJoachim Eastwood 
1984d6b06251SEzequiel Garcia 	/* If the stmmac is not already selected as gmac4,
1985d6b06251SEzequiel Garcia 	 * then make sure we fallback to gmac.
1986d6b06251SEzequiel Garcia 	 */
1987d6b06251SEzequiel Garcia 	if (!plat_dat->has_gmac4)
198827ffefd2SJoachim Eastwood 		plat_dat->has_gmac = true;
198927ffefd2SJoachim Eastwood 	plat_dat->fix_mac_speed = rk_fix_speed;
199027ffefd2SJoachim Eastwood 
1991fecd4d7eSDavid Wu 	plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
19928eee20e1SJisheng Zhang 	if (IS_ERR(plat_dat->bsp_priv))
19938eee20e1SJisheng Zhang 		return PTR_ERR(plat_dat->bsp_priv);
199427ffefd2SJoachim Eastwood 
1995fecd4d7eSDavid Wu 	ret = rk_gmac_clk_init(plat_dat);
1996fecd4d7eSDavid Wu 	if (ret)
19978eee20e1SJisheng Zhang 		return ret;
1998fecd4d7eSDavid Wu 
199907a5e769SJoachim Eastwood 	ret = rk_gmac_powerup(plat_dat->bsp_priv);
200027ffefd2SJoachim Eastwood 	if (ret)
20018eee20e1SJisheng Zhang 		return ret;
200227ffefd2SJoachim Eastwood 
20032d222656SJohan Hovold 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
20042d222656SJohan Hovold 	if (ret)
20052745529aSDavid S. Miller 		goto err_gmac_powerdown;
20062d222656SJohan Hovold 
20072d222656SJohan Hovold 	return 0;
20082d222656SJohan Hovold 
20092745529aSDavid S. Miller err_gmac_powerdown:
20102745529aSDavid S. Miller 	rk_gmac_powerdown(plat_dat->bsp_priv);
20112d222656SJohan Hovold 
20122d222656SJohan Hovold 	return ret;
201327ffefd2SJoachim Eastwood }
201427ffefd2SJoachim Eastwood 
rk_gmac_remove(struct platform_device * pdev)2015903cc461SUwe Kleine-König static void rk_gmac_remove(struct platform_device *pdev)
20160de8c4c9SJoachim Eastwood {
20170de8c4c9SJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
2018ff0011cfSUwe Kleine-König 
2019ff0011cfSUwe Kleine-König 	stmmac_dvr_remove(&pdev->dev);
20200de8c4c9SJoachim Eastwood 
20210de8c4c9SJoachim Eastwood 	rk_gmac_powerdown(bsp_priv);
20220de8c4c9SJoachim Eastwood }
20230de8c4c9SJoachim Eastwood 
20245619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP
rk_gmac_suspend(struct device * dev)20255619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev)
20265619468aSJoachim Eastwood {
20275619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
20285619468aSJoachim Eastwood 	int ret = stmmac_suspend(dev);
20295619468aSJoachim Eastwood 
20305619468aSJoachim Eastwood 	/* Keep the PHY up if we use Wake-on-Lan. */
20315619468aSJoachim Eastwood 	if (!device_may_wakeup(dev)) {
20325619468aSJoachim Eastwood 		rk_gmac_powerdown(bsp_priv);
20335619468aSJoachim Eastwood 		bsp_priv->suspended = true;
20345619468aSJoachim Eastwood 	}
20355619468aSJoachim Eastwood 
20365619468aSJoachim Eastwood 	return ret;
20375619468aSJoachim Eastwood }
20385619468aSJoachim Eastwood 
rk_gmac_resume(struct device * dev)20395619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev)
20405619468aSJoachim Eastwood {
20415619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
20425619468aSJoachim Eastwood 
20435619468aSJoachim Eastwood 	/* The PHY was up for Wake-on-Lan. */
20445619468aSJoachim Eastwood 	if (bsp_priv->suspended) {
20455619468aSJoachim Eastwood 		rk_gmac_powerup(bsp_priv);
20465619468aSJoachim Eastwood 		bsp_priv->suspended = false;
20475619468aSJoachim Eastwood 	}
20485619468aSJoachim Eastwood 
20495619468aSJoachim Eastwood 	return stmmac_resume(dev);
20505619468aSJoachim Eastwood }
20515619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */
20525619468aSJoachim Eastwood 
20535619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
20545619468aSJoachim Eastwood 
2055e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = {
205623c94d63SDavid Wu 	{ .compatible = "rockchip,px30-gmac",	.data = &px30_ops   },
205705946876SDavid Wu 	{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
2058e7ffd812SXing Zheng 	{ .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
2059f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
2060b4ac9456STobias Schramm 	{ .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops },
2061d4ff816eSdavid.wu 	{ .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
2062ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
2063f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
2064ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
20653bb3d6b1SDavid Wu 	{ .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
2066*f9cc9997SDavid Wu 	{ .compatible = "rockchip,rk3576-gmac", .data = &rk3576_ops },
20672f2b60a0SDavid Wu 	{ .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops },
206889c9c163SDavid Wu 	{ .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
2069c931b060SAnand Moon 	{ .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops },
2070e0fb4013SJoachim Eastwood 	{ }
2071e0fb4013SJoachim Eastwood };
2072e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
2073e0fb4013SJoachim Eastwood 
2074e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = {
207527ffefd2SJoachim Eastwood 	.probe  = rk_gmac_probe,
2076903cc461SUwe Kleine-König 	.remove_new = rk_gmac_remove,
2077e0fb4013SJoachim Eastwood 	.driver = {
2078e0fb4013SJoachim Eastwood 		.name           = "rk_gmac-dwmac",
20795619468aSJoachim Eastwood 		.pm		= &rk_gmac_pm_ops,
2080e0fb4013SJoachim Eastwood 		.of_match_table = rk_gmac_dwmac_match,
2081e0fb4013SJoachim Eastwood 	},
2082e0fb4013SJoachim Eastwood };
2083e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver);
2084e0fb4013SJoachim Eastwood 
2085e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
2086e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
2087e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL");
2088