xref: /openbmc/linux/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c (revision c69c29a1a0a8f68cd87e98ba4a5a79fb8ef2a58c)
17ad269eaSRoger Chen /**
27ad269eaSRoger Chen  * dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
37ad269eaSRoger Chen  *
47ad269eaSRoger Chen  * Copyright (C) 2014 Chen-Zhi (Roger Chen)
57ad269eaSRoger Chen  *
67ad269eaSRoger Chen  * Chen-Zhi (Roger Chen)  <roger.chen@rock-chips.com>
77ad269eaSRoger Chen  *
87ad269eaSRoger Chen  * This program is free software; you can redistribute it and/or modify
97ad269eaSRoger Chen  * it under the terms of the GNU General Public License as published by
107ad269eaSRoger Chen  * the Free Software Foundation; either version 2 of the License, or
117ad269eaSRoger Chen  * (at your option) any later version.
127ad269eaSRoger Chen  *
137ad269eaSRoger Chen  * This program is distributed in the hope that it will be useful,
147ad269eaSRoger Chen  * but WITHOUT ANY WARRANTY; without even the implied warranty of
157ad269eaSRoger Chen  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
167ad269eaSRoger Chen  * GNU General Public License for more details.
177ad269eaSRoger Chen  */
187ad269eaSRoger Chen 
197ad269eaSRoger Chen #include <linux/stmmac.h>
207ad269eaSRoger Chen #include <linux/bitops.h>
217ad269eaSRoger Chen #include <linux/clk.h>
227ad269eaSRoger Chen #include <linux/phy.h>
237ad269eaSRoger Chen #include <linux/of_net.h>
247ad269eaSRoger Chen #include <linux/gpio.h>
25e0fb4013SJoachim Eastwood #include <linux/module.h>
267ad269eaSRoger Chen #include <linux/of_gpio.h>
277ad269eaSRoger Chen #include <linux/of_device.h>
28e0fb4013SJoachim Eastwood #include <linux/platform_device.h>
297ad269eaSRoger Chen #include <linux/regulator/consumer.h>
307ad269eaSRoger Chen #include <linux/delay.h>
317ad269eaSRoger Chen #include <linux/mfd/syscon.h>
327ad269eaSRoger Chen #include <linux/regmap.h>
332c896fb0SDavid Wu #include <linux/pm_runtime.h>
347ad269eaSRoger Chen 
35e0fb4013SJoachim Eastwood #include "stmmac_platform.h"
36e0fb4013SJoachim Eastwood 
370fb98db1SHeiko Stübner struct rk_priv_data;
380fb98db1SHeiko Stübner struct rk_gmac_ops {
390fb98db1SHeiko Stübner 	void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
400fb98db1SHeiko Stübner 			     int tx_delay, int rx_delay);
410fb98db1SHeiko Stübner 	void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
420fb98db1SHeiko Stübner 	void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
430fb98db1SHeiko Stübner 	void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
44fecd4d7eSDavid Wu 	void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
450fb98db1SHeiko Stübner };
460fb98db1SHeiko Stübner 
477ad269eaSRoger Chen struct rk_priv_data {
487ad269eaSRoger Chen 	struct platform_device *pdev;
497ad269eaSRoger Chen 	int phy_iface;
502e12f536SRomain Perier 	struct regulator *regulator;
51229666c1SVincent Palatin 	bool suspended;
5292c2588fSJoachim Eastwood 	const struct rk_gmac_ops *ops;
537ad269eaSRoger Chen 
547ad269eaSRoger Chen 	bool clk_enabled;
557ad269eaSRoger Chen 	bool clock_input;
56fecd4d7eSDavid Wu 	bool integrated_phy;
577ad269eaSRoger Chen 
587ad269eaSRoger Chen 	struct clk *clk_mac;
597ad269eaSRoger Chen 	struct clk *gmac_clkin;
607ad269eaSRoger Chen 	struct clk *mac_clk_rx;
617ad269eaSRoger Chen 	struct clk *mac_clk_tx;
627ad269eaSRoger Chen 	struct clk *clk_mac_ref;
637ad269eaSRoger Chen 	struct clk *clk_mac_refout;
6423c94d63SDavid Wu 	struct clk *clk_mac_speed;
657ad269eaSRoger Chen 	struct clk *aclk_mac;
667ad269eaSRoger Chen 	struct clk *pclk_mac;
67fecd4d7eSDavid Wu 	struct clk *clk_phy;
68fecd4d7eSDavid Wu 
69fecd4d7eSDavid Wu 	struct reset_control *phy_reset;
707ad269eaSRoger Chen 
717ad269eaSRoger Chen 	int tx_delay;
727ad269eaSRoger Chen 	int rx_delay;
737ad269eaSRoger Chen 
747ad269eaSRoger Chen 	struct regmap *grf;
757ad269eaSRoger Chen };
767ad269eaSRoger Chen 
777ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \
787ad269eaSRoger Chen 		((val) << (shift) | (mask) << ((shift) + 16))
797ad269eaSRoger Chen 
807ad269eaSRoger Chen #define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
817ad269eaSRoger Chen #define GRF_CLR_BIT(nr)	(BIT(nr+16))
827ad269eaSRoger Chen 
83eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \
84eaf70ad1SWadim Egorov 	(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
85eaf70ad1SWadim Egorov 	 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
86eaf70ad1SWadim Egorov 
8723c94d63SDavid Wu #define PX30_GRF_GMAC_CON1		0x0904
8823c94d63SDavid Wu 
8923c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */
9023c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
9123c94d63SDavid Wu 					 GRF_BIT(6))
9223c94d63SDavid Wu #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
9323c94d63SDavid Wu #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
9423c94d63SDavid Wu 
9523c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
9623c94d63SDavid Wu {
9723c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
9823c94d63SDavid Wu 
9923c94d63SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
10023c94d63SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
10123c94d63SDavid Wu 		return;
10223c94d63SDavid Wu 	}
10323c94d63SDavid Wu 
10423c94d63SDavid Wu 	regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
10523c94d63SDavid Wu 		     PX30_GMAC_PHY_INTF_SEL_RMII);
10623c94d63SDavid Wu }
10723c94d63SDavid Wu 
10823c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
10923c94d63SDavid Wu {
11023c94d63SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
11123c94d63SDavid Wu 	int ret;
11223c94d63SDavid Wu 
11323c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed)) {
11423c94d63SDavid Wu 		dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
11523c94d63SDavid Wu 		return;
11623c94d63SDavid Wu 	}
11723c94d63SDavid Wu 
11823c94d63SDavid Wu 	if (speed == 10) {
11923c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
12023c94d63SDavid Wu 			     PX30_GMAC_SPEED_10M);
12123c94d63SDavid Wu 
12223c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000);
12323c94d63SDavid Wu 		if (ret)
12423c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n",
12523c94d63SDavid Wu 				__func__, ret);
12623c94d63SDavid Wu 	} else if (speed == 100) {
12723c94d63SDavid Wu 		regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
12823c94d63SDavid Wu 			     PX30_GMAC_SPEED_100M);
12923c94d63SDavid Wu 
13023c94d63SDavid Wu 		ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000);
13123c94d63SDavid Wu 		if (ret)
13223c94d63SDavid Wu 			dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n",
13323c94d63SDavid Wu 				__func__, ret);
13423c94d63SDavid Wu 
13523c94d63SDavid Wu 	} else {
13623c94d63SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
13723c94d63SDavid Wu 	}
13823c94d63SDavid Wu }
13923c94d63SDavid Wu 
14023c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = {
14123c94d63SDavid Wu 	.set_to_rmii = px30_set_to_rmii,
14223c94d63SDavid Wu 	.set_rmii_speed = px30_set_rmii_speed,
14323c94d63SDavid Wu };
14423c94d63SDavid Wu 
14505946876SDavid Wu #define RK3128_GRF_MAC_CON0	0x0168
14605946876SDavid Wu #define RK3128_GRF_MAC_CON1	0x016c
14705946876SDavid Wu 
14805946876SDavid Wu /* RK3128_GRF_MAC_CON0 */
14905946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE   GRF_BIT(14)
15005946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(14)
15105946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(15)
15205946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(15)
15305946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
15405946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
15505946876SDavid Wu 
15605946876SDavid Wu /* RK3128_GRF_MAC_CON1 */
15705946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII	\
15805946876SDavid Wu 		(GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
15905946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII	\
16005946876SDavid Wu 		(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
16105946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
16205946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
16305946876SDavid Wu #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
16405946876SDavid Wu #define RK3128_GMAC_SPEED_100M         GRF_BIT(10)
16505946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M       GRF_BIT(11)
16605946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M      GRF_CLR_BIT(11)
16705946876SDavid Wu #define RK3128_GMAC_CLK_125M           (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
16805946876SDavid Wu #define RK3128_GMAC_CLK_25M            (GRF_BIT(12) | GRF_BIT(13))
16905946876SDavid Wu #define RK3128_GMAC_CLK_2_5M           (GRF_CLR_BIT(12) | GRF_BIT(13))
17005946876SDavid Wu #define RK3128_GMAC_RMII_MODE          GRF_BIT(14)
17105946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR      GRF_CLR_BIT(14)
17205946876SDavid Wu 
17305946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
17405946876SDavid Wu 				int tx_delay, int rx_delay)
17505946876SDavid Wu {
17605946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
17705946876SDavid Wu 
17805946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
17905946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
18005946876SDavid Wu 		return;
18105946876SDavid Wu 	}
18205946876SDavid Wu 
18305946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
18405946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RGMII |
18505946876SDavid Wu 		     RK3128_GMAC_RMII_MODE_CLR);
18605946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
18705946876SDavid Wu 		     DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
18805946876SDavid Wu 		     RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
18905946876SDavid Wu 		     RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
19005946876SDavid Wu }
19105946876SDavid Wu 
19205946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
19305946876SDavid Wu {
19405946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
19505946876SDavid Wu 
19605946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
19705946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
19805946876SDavid Wu 		return;
19905946876SDavid Wu 	}
20005946876SDavid Wu 
20105946876SDavid Wu 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
20205946876SDavid Wu 		     RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
20305946876SDavid Wu }
20405946876SDavid Wu 
20505946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
20605946876SDavid Wu {
20705946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
20805946876SDavid Wu 
20905946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
21005946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
21105946876SDavid Wu 		return;
21205946876SDavid Wu 	}
21305946876SDavid Wu 
21405946876SDavid Wu 	if (speed == 10)
21505946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21605946876SDavid Wu 			     RK3128_GMAC_CLK_2_5M);
21705946876SDavid Wu 	else if (speed == 100)
21805946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21905946876SDavid Wu 			     RK3128_GMAC_CLK_25M);
22005946876SDavid Wu 	else if (speed == 1000)
22105946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
22205946876SDavid Wu 			     RK3128_GMAC_CLK_125M);
22305946876SDavid Wu 	else
22405946876SDavid Wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
22505946876SDavid Wu }
22605946876SDavid Wu 
22705946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
22805946876SDavid Wu {
22905946876SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
23005946876SDavid Wu 
23105946876SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
23205946876SDavid Wu 		dev_err(dev, "Missing rockchip,grf property\n");
23305946876SDavid Wu 		return;
23405946876SDavid Wu 	}
23505946876SDavid Wu 
23605946876SDavid Wu 	if (speed == 10) {
23705946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23805946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_2_5M |
23905946876SDavid Wu 			     RK3128_GMAC_SPEED_10M);
24005946876SDavid Wu 	} else if (speed == 100) {
24105946876SDavid Wu 		regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
24205946876SDavid Wu 			     RK3128_GMAC_RMII_CLK_25M |
24305946876SDavid Wu 			     RK3128_GMAC_SPEED_100M);
24405946876SDavid Wu 	} else {
24505946876SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
24605946876SDavid Wu 	}
24705946876SDavid Wu }
24805946876SDavid Wu 
24905946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = {
25005946876SDavid Wu 	.set_to_rgmii = rk3128_set_to_rgmii,
25105946876SDavid Wu 	.set_to_rmii = rk3128_set_to_rmii,
25205946876SDavid Wu 	.set_rgmii_speed = rk3128_set_rgmii_speed,
25305946876SDavid Wu 	.set_rmii_speed = rk3128_set_rmii_speed,
25405946876SDavid Wu };
25505946876SDavid Wu 
256e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0	0x0900
257e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1	0x0904
258e7ffd812SXing Zheng 
2596fa12c78SDavid Wu #define RK3228_GRF_CON_MUX	0x50
2606fa12c78SDavid Wu 
261e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */
262e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
263e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
264e7ffd812SXing Zheng 
265e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */
266e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII	\
267e7ffd812SXing Zheng 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
268e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII	\
269e7ffd812SXing Zheng 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
270e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
271e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
272e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
273e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M		GRF_BIT(2)
274e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M	GRF_BIT(7)
275e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
276e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M		(GRF_CLR_BIT(8) | GRF_CLR_BIT(9))
277e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M		(GRF_BIT(8) | GRF_BIT(9))
278e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M		(GRF_CLR_BIT(8) | GRF_BIT(9))
279e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE		GRF_BIT(10)
280e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(10)
281e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
282e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
283e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
284e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(1)
285e7ffd812SXing Zheng 
2866fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */
2876fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY	GRF_BIT(15)
2886fa12c78SDavid Wu 
289e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
290e7ffd812SXing Zheng 				int tx_delay, int rx_delay)
291e7ffd812SXing Zheng {
292e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
293e7ffd812SXing Zheng 
294e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
295e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
296e7ffd812SXing Zheng 		return;
297e7ffd812SXing Zheng 	}
298e7ffd812SXing Zheng 
299e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
300e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RGMII |
301e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE_CLR |
302eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3228, tx_delay, rx_delay));
303e7ffd812SXing Zheng 
304e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
305e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
306e7ffd812SXing Zheng 		     RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
307e7ffd812SXing Zheng }
308e7ffd812SXing Zheng 
309e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
310e7ffd812SXing Zheng {
311e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
312e7ffd812SXing Zheng 
313e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
314e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
315e7ffd812SXing Zheng 		return;
316e7ffd812SXing Zheng 	}
317e7ffd812SXing Zheng 
318e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
319e7ffd812SXing Zheng 		     RK3228_GMAC_PHY_INTF_SEL_RMII |
320e7ffd812SXing Zheng 		     RK3228_GMAC_RMII_MODE);
321e7ffd812SXing Zheng 
322e7ffd812SXing Zheng 	/* set MAC to RMII mode */
323e7ffd812SXing Zheng 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11));
324e7ffd812SXing Zheng }
325e7ffd812SXing Zheng 
326e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
327e7ffd812SXing Zheng {
328e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
329e7ffd812SXing Zheng 
330e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
331e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
332e7ffd812SXing Zheng 		return;
333e7ffd812SXing Zheng 	}
334e7ffd812SXing Zheng 
335e7ffd812SXing Zheng 	if (speed == 10)
336e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
337e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_2_5M);
338e7ffd812SXing Zheng 	else if (speed == 100)
339e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
340e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_25M);
341e7ffd812SXing Zheng 	else if (speed == 1000)
342e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
343e7ffd812SXing Zheng 			     RK3228_GMAC_CLK_125M);
344e7ffd812SXing Zheng 	else
345e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
346e7ffd812SXing Zheng }
347e7ffd812SXing Zheng 
348e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
349e7ffd812SXing Zheng {
350e7ffd812SXing Zheng 	struct device *dev = &bsp_priv->pdev->dev;
351e7ffd812SXing Zheng 
352e7ffd812SXing Zheng 	if (IS_ERR(bsp_priv->grf)) {
353e7ffd812SXing Zheng 		dev_err(dev, "Missing rockchip,grf property\n");
354e7ffd812SXing Zheng 		return;
355e7ffd812SXing Zheng 	}
356e7ffd812SXing Zheng 
357e7ffd812SXing Zheng 	if (speed == 10)
358e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
359e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_2_5M |
360e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_10M);
361e7ffd812SXing Zheng 	else if (speed == 100)
362e7ffd812SXing Zheng 		regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
363e7ffd812SXing Zheng 			     RK3228_GMAC_RMII_CLK_25M |
364e7ffd812SXing Zheng 			     RK3228_GMAC_SPEED_100M);
365e7ffd812SXing Zheng 	else
366e7ffd812SXing Zheng 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
367e7ffd812SXing Zheng }
368e7ffd812SXing Zheng 
3696fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
3706fa12c78SDavid Wu {
3716fa12c78SDavid Wu 	regmap_write(priv->grf, RK3228_GRF_CON_MUX,
3726fa12c78SDavid Wu 		     RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
3736fa12c78SDavid Wu }
3746fa12c78SDavid Wu 
375e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = {
376e7ffd812SXing Zheng 	.set_to_rgmii = rk3228_set_to_rgmii,
377e7ffd812SXing Zheng 	.set_to_rmii = rk3228_set_to_rmii,
378e7ffd812SXing Zheng 	.set_rgmii_speed = rk3228_set_rgmii_speed,
379e7ffd812SXing Zheng 	.set_rmii_speed = rk3228_set_rmii_speed,
3806fa12c78SDavid Wu 	.integrated_phy_powerup =  rk3228_integrated_phy_powerup,
381e7ffd812SXing Zheng };
382e7ffd812SXing Zheng 
3837ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1	0x0248
3847ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3	0x0250
3857ad269eaSRoger Chen 
3867ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/
3870fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | \
3880fb98db1SHeiko Stübner 					 GRF_CLR_BIT(8))
3890fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
3900fb98db1SHeiko Stübner 					 GRF_BIT(8))
3910fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
3920fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
3930fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
3940fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M		GRF_BIT(10)
3950fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M	GRF_BIT(11)
3960fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
3970fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
3980fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
3990fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
4000fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE		GRF_BIT(14)
4010fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
4027ad269eaSRoger Chen 
4037ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/
4040fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
4050fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
4060fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
4070fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
4080fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
4090fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
4107ad269eaSRoger Chen 
4110fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
4127ad269eaSRoger Chen 				int tx_delay, int rx_delay)
4137ad269eaSRoger Chen {
4147ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4157ad269eaSRoger Chen 
4167ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
417d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4187ad269eaSRoger Chen 		return;
4197ad269eaSRoger Chen 	}
4207ad269eaSRoger Chen 
4217ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4220fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
4230fb98db1SHeiko Stübner 		     RK3288_GMAC_RMII_MODE_CLR);
4247ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
425eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
4260fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
4270fb98db1SHeiko Stübner 		     RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
4287ad269eaSRoger Chen }
4297ad269eaSRoger Chen 
4300fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
4317ad269eaSRoger Chen {
4327ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4337ad269eaSRoger Chen 
4347ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
435d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4367ad269eaSRoger Chen 		return;
4377ad269eaSRoger Chen 	}
4387ad269eaSRoger Chen 
4397ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4400fb98db1SHeiko Stübner 		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
4417ad269eaSRoger Chen }
4427ad269eaSRoger Chen 
4430fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
4447ad269eaSRoger Chen {
4457ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4467ad269eaSRoger Chen 
4477ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
448d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4497ad269eaSRoger Chen 		return;
4507ad269eaSRoger Chen 	}
4517ad269eaSRoger Chen 
4527ad269eaSRoger Chen 	if (speed == 10)
4530fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4540fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_2_5M);
4557ad269eaSRoger Chen 	else if (speed == 100)
4560fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4570fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_25M);
4587ad269eaSRoger Chen 	else if (speed == 1000)
4590fb98db1SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4600fb98db1SHeiko Stübner 			     RK3288_GMAC_CLK_125M);
4617ad269eaSRoger Chen 	else
4627ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
4637ad269eaSRoger Chen }
4647ad269eaSRoger Chen 
4650fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
4667ad269eaSRoger Chen {
4677ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
4687ad269eaSRoger Chen 
4697ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
470d42202dcSRomain Perier 		dev_err(dev, "Missing rockchip,grf property\n");
4717ad269eaSRoger Chen 		return;
4727ad269eaSRoger Chen 	}
4737ad269eaSRoger Chen 
4747ad269eaSRoger Chen 	if (speed == 10) {
4757ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4760fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_2_5M |
4770fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_10M);
4787ad269eaSRoger Chen 	} else if (speed == 100) {
4797ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4800fb98db1SHeiko Stübner 			     RK3288_GMAC_RMII_CLK_25M |
4810fb98db1SHeiko Stübner 			     RK3288_GMAC_SPEED_100M);
4827ad269eaSRoger Chen 	} else {
4837ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
4847ad269eaSRoger Chen 	}
4857ad269eaSRoger Chen }
4867ad269eaSRoger Chen 
48792c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = {
4880fb98db1SHeiko Stübner 	.set_to_rgmii = rk3288_set_to_rgmii,
4890fb98db1SHeiko Stübner 	.set_to_rmii = rk3288_set_to_rmii,
4900fb98db1SHeiko Stübner 	.set_rgmii_speed = rk3288_set_rgmii_speed,
4910fb98db1SHeiko Stübner 	.set_rmii_speed = rk3288_set_rmii_speed,
4920fb98db1SHeiko Stübner };
4930fb98db1SHeiko Stübner 
494d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0	0x0900
495d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1	0x0904
4968bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2	0x0908
4978bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1	0xb04
498d4ff816eSdavid.wu 
499d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */
500d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
501d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
502d4ff816eSdavid.wu 
503d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */
504d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII	\
505d4ff816eSdavid.wu 		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
506d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII	\
507d4ff816eSdavid.wu 		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
508d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
509d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
510d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
511d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M		GRF_BIT(2)
512d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M	GRF_BIT(7)
513d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
514d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M		(GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
515d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M		(GRF_BIT(11) | GRF_BIT(12))
516d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M		(GRF_CLR_BIT(11) | GRF_BIT(12))
517d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE		GRF_BIT(9)
518d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(9)
519d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
520d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
521d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(1)
522d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(0)
523d4ff816eSdavid.wu 
5248bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */
5258bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE		GRF_BIT(9)
5268bdf63bdSDavid Wu 
527d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
528d4ff816eSdavid.wu 				int tx_delay, int rx_delay)
529d4ff816eSdavid.wu {
530d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
531d4ff816eSdavid.wu 
532d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
533d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
534d4ff816eSdavid.wu 		return;
535d4ff816eSdavid.wu 	}
536d4ff816eSdavid.wu 
537d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
538d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
539d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE_CLR |
540d4ff816eSdavid.wu 		     RK3328_GMAC_RXCLK_DLY_ENABLE |
541d4ff816eSdavid.wu 		     RK3328_GMAC_TXCLK_DLY_ENABLE);
542d4ff816eSdavid.wu 
543d4ff816eSdavid.wu 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
544d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
545d4ff816eSdavid.wu 		     RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
546d4ff816eSdavid.wu }
547d4ff816eSdavid.wu 
548d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
549d4ff816eSdavid.wu {
550d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
5518bdf63bdSDavid Wu 	unsigned int reg;
552d4ff816eSdavid.wu 
553d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
554d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
555d4ff816eSdavid.wu 		return;
556d4ff816eSdavid.wu 	}
557d4ff816eSdavid.wu 
5588bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
5598bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
5608bdf63bdSDavid Wu 
5618bdf63bdSDavid Wu 	regmap_write(bsp_priv->grf, reg,
562d4ff816eSdavid.wu 		     RK3328_GMAC_PHY_INTF_SEL_RMII |
563d4ff816eSdavid.wu 		     RK3328_GMAC_RMII_MODE);
564d4ff816eSdavid.wu }
565d4ff816eSdavid.wu 
566d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
567d4ff816eSdavid.wu {
568d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
569d4ff816eSdavid.wu 
570d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
571d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
572d4ff816eSdavid.wu 		return;
573d4ff816eSdavid.wu 	}
574d4ff816eSdavid.wu 
575d4ff816eSdavid.wu 	if (speed == 10)
576d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
577d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_2_5M);
578d4ff816eSdavid.wu 	else if (speed == 100)
579d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
580d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_25M);
581d4ff816eSdavid.wu 	else if (speed == 1000)
582d4ff816eSdavid.wu 		regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
583d4ff816eSdavid.wu 			     RK3328_GMAC_CLK_125M);
584d4ff816eSdavid.wu 	else
585d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
586d4ff816eSdavid.wu }
587d4ff816eSdavid.wu 
588d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
589d4ff816eSdavid.wu {
590d4ff816eSdavid.wu 	struct device *dev = &bsp_priv->pdev->dev;
5918bdf63bdSDavid Wu 	unsigned int reg;
592d4ff816eSdavid.wu 
593d4ff816eSdavid.wu 	if (IS_ERR(bsp_priv->grf)) {
594d4ff816eSdavid.wu 		dev_err(dev, "Missing rockchip,grf property\n");
595d4ff816eSdavid.wu 		return;
596d4ff816eSdavid.wu 	}
597d4ff816eSdavid.wu 
5988bdf63bdSDavid Wu 	reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
5998bdf63bdSDavid Wu 		  RK3328_GRF_MAC_CON1;
6008bdf63bdSDavid Wu 
601d4ff816eSdavid.wu 	if (speed == 10)
6028bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
603d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_2_5M |
604d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_10M);
605d4ff816eSdavid.wu 	else if (speed == 100)
6068bdf63bdSDavid Wu 		regmap_write(bsp_priv->grf, reg,
607d4ff816eSdavid.wu 			     RK3328_GMAC_RMII_CLK_25M |
608d4ff816eSdavid.wu 			     RK3328_GMAC_SPEED_100M);
609d4ff816eSdavid.wu 	else
610d4ff816eSdavid.wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
611d4ff816eSdavid.wu }
612d4ff816eSdavid.wu 
6138bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
6148bdf63bdSDavid Wu {
6158bdf63bdSDavid Wu 	regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
6168bdf63bdSDavid Wu 		     RK3328_MACPHY_RMII_MODE);
6178bdf63bdSDavid Wu }
6188bdf63bdSDavid Wu 
619d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = {
620d4ff816eSdavid.wu 	.set_to_rgmii = rk3328_set_to_rgmii,
621d4ff816eSdavid.wu 	.set_to_rmii = rk3328_set_to_rmii,
622d4ff816eSdavid.wu 	.set_rgmii_speed = rk3328_set_rgmii_speed,
623d4ff816eSdavid.wu 	.set_rmii_speed = rk3328_set_rmii_speed,
6248bdf63bdSDavid Wu 	.integrated_phy_powerup =  rk3328_integrated_phy_powerup,
625d4ff816eSdavid.wu };
626d4ff816eSdavid.wu 
627ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6	0x0418
628ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7	0x041c
629ba289af8SRoger Chen 
630ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */
631ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
632ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
633ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
634ba289af8SRoger Chen 					 GRF_BIT(11))
635ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
636ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
637ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
638ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M		GRF_BIT(7)
639ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M	GRF_BIT(3)
640ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
641ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
642ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
643ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
644ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE		GRF_BIT(6)
645ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
646ba289af8SRoger Chen 
647ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */
648ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
649ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
650ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
651ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
652ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
653ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
654ba289af8SRoger Chen 
655ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
656ba289af8SRoger Chen 				int tx_delay, int rx_delay)
657ba289af8SRoger Chen {
658ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
659ba289af8SRoger Chen 
660ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
661ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
662ba289af8SRoger Chen 		return;
663ba289af8SRoger Chen 	}
664ba289af8SRoger Chen 
665ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
666ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RGMII |
667ba289af8SRoger Chen 		     RK3366_GMAC_RMII_MODE_CLR);
668ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
669eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
670ba289af8SRoger Chen 		     RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
671ba289af8SRoger Chen 		     RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
672ba289af8SRoger Chen }
673ba289af8SRoger Chen 
674ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
675ba289af8SRoger Chen {
676ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
677ba289af8SRoger Chen 
678ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
679ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
680ba289af8SRoger Chen 		return;
681ba289af8SRoger Chen 	}
682ba289af8SRoger Chen 
683ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
684ba289af8SRoger Chen 		     RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
685ba289af8SRoger Chen }
686ba289af8SRoger Chen 
687ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
688ba289af8SRoger Chen {
689ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
690ba289af8SRoger Chen 
691ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
692ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
693ba289af8SRoger Chen 		return;
694ba289af8SRoger Chen 	}
695ba289af8SRoger Chen 
696ba289af8SRoger Chen 	if (speed == 10)
697ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
698ba289af8SRoger Chen 			     RK3366_GMAC_CLK_2_5M);
699ba289af8SRoger Chen 	else if (speed == 100)
700ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
701ba289af8SRoger Chen 			     RK3366_GMAC_CLK_25M);
702ba289af8SRoger Chen 	else if (speed == 1000)
703ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
704ba289af8SRoger Chen 			     RK3366_GMAC_CLK_125M);
705ba289af8SRoger Chen 	else
706ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
707ba289af8SRoger Chen }
708ba289af8SRoger Chen 
709ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
710ba289af8SRoger Chen {
711ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
712ba289af8SRoger Chen 
713ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
714ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
715ba289af8SRoger Chen 		return;
716ba289af8SRoger Chen 	}
717ba289af8SRoger Chen 
718ba289af8SRoger Chen 	if (speed == 10) {
719ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
720ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_2_5M |
721ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_10M);
722ba289af8SRoger Chen 	} else if (speed == 100) {
723ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
724ba289af8SRoger Chen 			     RK3366_GMAC_RMII_CLK_25M |
725ba289af8SRoger Chen 			     RK3366_GMAC_SPEED_100M);
726ba289af8SRoger Chen 	} else {
727ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
728ba289af8SRoger Chen 	}
729ba289af8SRoger Chen }
730ba289af8SRoger Chen 
731ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = {
732ba289af8SRoger Chen 	.set_to_rgmii = rk3366_set_to_rgmii,
733ba289af8SRoger Chen 	.set_to_rmii = rk3366_set_to_rmii,
734ba289af8SRoger Chen 	.set_rgmii_speed = rk3366_set_rgmii_speed,
735ba289af8SRoger Chen 	.set_rmii_speed = rk3366_set_rmii_speed,
736ba289af8SRoger Chen };
737ba289af8SRoger Chen 
738df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15	0x043c
739df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16	0x0440
740df558854SHeiko Stübner 
741df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */
742df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
743df558854SHeiko Stübner 					 GRF_CLR_BIT(11))
744df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
745df558854SHeiko Stübner 					 GRF_BIT(11))
746df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
747df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
748df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
749df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M		GRF_BIT(7)
750df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M	GRF_BIT(3)
751df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
752df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
753df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
754df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
755df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE		GRF_BIT(6)
756df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
757df558854SHeiko Stübner 
758df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */
759df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
760df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
761df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
762df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
763df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
764df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
765df558854SHeiko Stübner 
766df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
767df558854SHeiko Stübner 				int tx_delay, int rx_delay)
768df558854SHeiko Stübner {
769df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
770df558854SHeiko Stübner 
771df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
772df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
773df558854SHeiko Stübner 		return;
774df558854SHeiko Stübner 	}
775df558854SHeiko Stübner 
776df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
777df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
778df558854SHeiko Stübner 		     RK3368_GMAC_RMII_MODE_CLR);
779df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
780eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
781df558854SHeiko Stübner 		     RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
782df558854SHeiko Stübner 		     RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
783df558854SHeiko Stübner }
784df558854SHeiko Stübner 
785df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
786df558854SHeiko Stübner {
787df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
788df558854SHeiko Stübner 
789df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
790df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
791df558854SHeiko Stübner 		return;
792df558854SHeiko Stübner 	}
793df558854SHeiko Stübner 
794df558854SHeiko Stübner 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
795df558854SHeiko Stübner 		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
796df558854SHeiko Stübner }
797df558854SHeiko Stübner 
798df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
799df558854SHeiko Stübner {
800df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
801df558854SHeiko Stübner 
802df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
803df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
804df558854SHeiko Stübner 		return;
805df558854SHeiko Stübner 	}
806df558854SHeiko Stübner 
807df558854SHeiko Stübner 	if (speed == 10)
808df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
809df558854SHeiko Stübner 			     RK3368_GMAC_CLK_2_5M);
810df558854SHeiko Stübner 	else if (speed == 100)
811df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
812df558854SHeiko Stübner 			     RK3368_GMAC_CLK_25M);
813df558854SHeiko Stübner 	else if (speed == 1000)
814df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
815df558854SHeiko Stübner 			     RK3368_GMAC_CLK_125M);
816df558854SHeiko Stübner 	else
817df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
818df558854SHeiko Stübner }
819df558854SHeiko Stübner 
820df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
821df558854SHeiko Stübner {
822df558854SHeiko Stübner 	struct device *dev = &bsp_priv->pdev->dev;
823df558854SHeiko Stübner 
824df558854SHeiko Stübner 	if (IS_ERR(bsp_priv->grf)) {
825df558854SHeiko Stübner 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
826df558854SHeiko Stübner 		return;
827df558854SHeiko Stübner 	}
828df558854SHeiko Stübner 
829df558854SHeiko Stübner 	if (speed == 10) {
830df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
831df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_2_5M |
832df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_10M);
833df558854SHeiko Stübner 	} else if (speed == 100) {
834df558854SHeiko Stübner 		regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
835df558854SHeiko Stübner 			     RK3368_GMAC_RMII_CLK_25M |
836df558854SHeiko Stübner 			     RK3368_GMAC_SPEED_100M);
837df558854SHeiko Stübner 	} else {
838df558854SHeiko Stübner 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
839df558854SHeiko Stübner 	}
840df558854SHeiko Stübner }
841df558854SHeiko Stübner 
84292c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = {
843df558854SHeiko Stübner 	.set_to_rgmii = rk3368_set_to_rgmii,
844df558854SHeiko Stübner 	.set_to_rmii = rk3368_set_to_rmii,
845df558854SHeiko Stübner 	.set_rgmii_speed = rk3368_set_rgmii_speed,
846df558854SHeiko Stübner 	.set_rmii_speed = rk3368_set_rmii_speed,
847df558854SHeiko Stübner };
848df558854SHeiko Stübner 
849ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5	0xc214
850ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6	0xc218
851ba289af8SRoger Chen 
852ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */
853ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
854ba289af8SRoger Chen 					 GRF_CLR_BIT(11))
855ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
856ba289af8SRoger Chen 					 GRF_BIT(11))
857ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
858ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
859ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
860ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M		GRF_BIT(7)
861ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M	GRF_BIT(3)
862ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
863ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
864ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
865ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
866ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE		GRF_BIT(6)
867ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
868ba289af8SRoger Chen 
869ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */
870ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(7)
871ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
872ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
873ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
874ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
875ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
876ba289af8SRoger Chen 
877ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
878ba289af8SRoger Chen 				int tx_delay, int rx_delay)
879ba289af8SRoger Chen {
880ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
881ba289af8SRoger Chen 
882ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
883ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
884ba289af8SRoger Chen 		return;
885ba289af8SRoger Chen 	}
886ba289af8SRoger Chen 
887ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
888ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RGMII |
889ba289af8SRoger Chen 		     RK3399_GMAC_RMII_MODE_CLR);
890ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
891eaf70ad1SWadim Egorov 		     DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
892ba289af8SRoger Chen 		     RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
893ba289af8SRoger Chen 		     RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
894ba289af8SRoger Chen }
895ba289af8SRoger Chen 
896ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
897ba289af8SRoger Chen {
898ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
899ba289af8SRoger Chen 
900ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
901ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
902ba289af8SRoger Chen 		return;
903ba289af8SRoger Chen 	}
904ba289af8SRoger Chen 
905ba289af8SRoger Chen 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
906ba289af8SRoger Chen 		     RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
907ba289af8SRoger Chen }
908ba289af8SRoger Chen 
909ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
910ba289af8SRoger Chen {
911ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
912ba289af8SRoger Chen 
913ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
914ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
915ba289af8SRoger Chen 		return;
916ba289af8SRoger Chen 	}
917ba289af8SRoger Chen 
918ba289af8SRoger Chen 	if (speed == 10)
919ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
920ba289af8SRoger Chen 			     RK3399_GMAC_CLK_2_5M);
921ba289af8SRoger Chen 	else if (speed == 100)
922ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
923ba289af8SRoger Chen 			     RK3399_GMAC_CLK_25M);
924ba289af8SRoger Chen 	else if (speed == 1000)
925ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
926ba289af8SRoger Chen 			     RK3399_GMAC_CLK_125M);
927ba289af8SRoger Chen 	else
928ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
929ba289af8SRoger Chen }
930ba289af8SRoger Chen 
931ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
932ba289af8SRoger Chen {
933ba289af8SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
934ba289af8SRoger Chen 
935ba289af8SRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
936ba289af8SRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
937ba289af8SRoger Chen 		return;
938ba289af8SRoger Chen 	}
939ba289af8SRoger Chen 
940ba289af8SRoger Chen 	if (speed == 10) {
941ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
942ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_2_5M |
943ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_10M);
944ba289af8SRoger Chen 	} else if (speed == 100) {
945ba289af8SRoger Chen 		regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
946ba289af8SRoger Chen 			     RK3399_GMAC_RMII_CLK_25M |
947ba289af8SRoger Chen 			     RK3399_GMAC_SPEED_100M);
948ba289af8SRoger Chen 	} else {
949ba289af8SRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
950ba289af8SRoger Chen 	}
951ba289af8SRoger Chen }
952ba289af8SRoger Chen 
953ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = {
954ba289af8SRoger Chen 	.set_to_rgmii = rk3399_set_to_rgmii,
955ba289af8SRoger Chen 	.set_to_rmii = rk3399_set_to_rmii,
956ba289af8SRoger Chen 	.set_rgmii_speed = rk3399_set_rgmii_speed,
957ba289af8SRoger Chen 	.set_rmii_speed = rk3399_set_rmii_speed,
958ba289af8SRoger Chen };
959ba289af8SRoger Chen 
96089c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0		0X0900
96189c9c163SDavid Wu 
96289c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */
96389c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
96489c9c163SDavid Wu 					GRF_BIT(6))
96589c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
96689c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
96789c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
96889c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M		GRF_BIT(2)
96989c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M	GRF_BIT(7)
97089c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
97189c9c163SDavid Wu 
97289c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
97389c9c163SDavid Wu {
97489c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
97589c9c163SDavid Wu 
97689c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
97789c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
97889c9c163SDavid Wu 		return;
97989c9c163SDavid Wu 	}
98089c9c163SDavid Wu 
98189c9c163SDavid Wu 	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
98289c9c163SDavid Wu 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
98389c9c163SDavid Wu }
98489c9c163SDavid Wu 
98589c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
98689c9c163SDavid Wu {
98789c9c163SDavid Wu 	struct device *dev = &bsp_priv->pdev->dev;
98889c9c163SDavid Wu 
98989c9c163SDavid Wu 	if (IS_ERR(bsp_priv->grf)) {
99089c9c163SDavid Wu 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
99189c9c163SDavid Wu 		return;
99289c9c163SDavid Wu 	}
99389c9c163SDavid Wu 
99489c9c163SDavid Wu 	if (speed == 10) {
99589c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
99689c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_2_5M |
99789c9c163SDavid Wu 			     RV1108_GMAC_SPEED_10M);
99889c9c163SDavid Wu 	} else if (speed == 100) {
99989c9c163SDavid Wu 		regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
100089c9c163SDavid Wu 			     RV1108_GMAC_RMII_CLK_25M |
100189c9c163SDavid Wu 			     RV1108_GMAC_SPEED_100M);
100289c9c163SDavid Wu 	} else {
100389c9c163SDavid Wu 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
100489c9c163SDavid Wu 	}
100589c9c163SDavid Wu }
100689c9c163SDavid Wu 
100789c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = {
100889c9c163SDavid Wu 	.set_to_rmii = rv1108_set_to_rmii,
100989c9c163SDavid Wu 	.set_rmii_speed = rv1108_set_rmii_speed,
101089c9c163SDavid Wu };
101189c9c163SDavid Wu 
1012fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0		0xb00
1013fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1		0xb04
1014fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2		0xb08
1015fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3		0xb0c
1016fecd4d7eSDavid Wu 
1017fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE		GRF_BIT(0)
1018fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
1019fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
1020fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
1021fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID		HIWORD_UPDATE(0x1234, 0xffff, 0)
1022fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID		HIWORD_UPDATE(0x35, 0x3f, 0)
1023fecd4d7eSDavid Wu 
1024fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
10257ad269eaSRoger Chen {
1026fecd4d7eSDavid Wu 	if (priv->ops->integrated_phy_powerup)
1027fecd4d7eSDavid Wu 		priv->ops->integrated_phy_powerup(priv);
1028fecd4d7eSDavid Wu 
1029fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
1030fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
1031fecd4d7eSDavid Wu 
1032fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
1033fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
1034fecd4d7eSDavid Wu 
1035fecd4d7eSDavid Wu 	if (priv->phy_reset) {
1036fecd4d7eSDavid Wu 		/* PHY needs to be disabled before trying to reset it */
1037fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1038fecd4d7eSDavid Wu 		if (priv->phy_reset)
1039fecd4d7eSDavid Wu 			reset_control_assert(priv->phy_reset);
1040fecd4d7eSDavid Wu 		usleep_range(10, 20);
1041fecd4d7eSDavid Wu 		if (priv->phy_reset)
1042fecd4d7eSDavid Wu 			reset_control_deassert(priv->phy_reset);
1043fecd4d7eSDavid Wu 		usleep_range(10, 20);
1044fecd4d7eSDavid Wu 		regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
1045fecd4d7eSDavid Wu 		msleep(30);
1046fecd4d7eSDavid Wu 	}
1047fecd4d7eSDavid Wu }
1048fecd4d7eSDavid Wu 
1049fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
1050fecd4d7eSDavid Wu {
1051fecd4d7eSDavid Wu 	regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1052fecd4d7eSDavid Wu 	if (priv->phy_reset)
1053fecd4d7eSDavid Wu 		reset_control_assert(priv->phy_reset);
1054fecd4d7eSDavid Wu }
1055fecd4d7eSDavid Wu 
1056fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
1057fecd4d7eSDavid Wu {
1058fecd4d7eSDavid Wu 	struct rk_priv_data *bsp_priv = plat->bsp_priv;
10597ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
1060fecd4d7eSDavid Wu 	int ret;
10617ad269eaSRoger Chen 
10627ad269eaSRoger Chen 	bsp_priv->clk_enabled = false;
10637ad269eaSRoger Chen 
10647ad269eaSRoger Chen 	bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
10657ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_rx))
1066d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1067d42202dcSRomain Perier 			"mac_clk_rx");
10687ad269eaSRoger Chen 
10697ad269eaSRoger Chen 	bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
10707ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_tx))
1071d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1072d42202dcSRomain Perier 			"mac_clk_tx");
10737ad269eaSRoger Chen 
10747ad269eaSRoger Chen 	bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
10757ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->aclk_mac))
1076d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1077d42202dcSRomain Perier 			"aclk_mac");
10787ad269eaSRoger Chen 
10797ad269eaSRoger Chen 	bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
10807ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->pclk_mac))
1081d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1082d42202dcSRomain Perier 			"pclk_mac");
10837ad269eaSRoger Chen 
10847ad269eaSRoger Chen 	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
10857ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->clk_mac))
1086d42202dcSRomain Perier 		dev_err(dev, "cannot get clock %s\n",
1087d42202dcSRomain Perier 			"stmmaceth");
10887ad269eaSRoger Chen 
10897ad269eaSRoger Chen 	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
10907ad269eaSRoger Chen 		bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
10917ad269eaSRoger Chen 		if (IS_ERR(bsp_priv->clk_mac_ref))
1092d42202dcSRomain Perier 			dev_err(dev, "cannot get clock %s\n",
1093d42202dcSRomain Perier 				"clk_mac_ref");
10947ad269eaSRoger Chen 
10957ad269eaSRoger Chen 		if (!bsp_priv->clock_input) {
10967ad269eaSRoger Chen 			bsp_priv->clk_mac_refout =
10977ad269eaSRoger Chen 				devm_clk_get(dev, "clk_mac_refout");
10987ad269eaSRoger Chen 			if (IS_ERR(bsp_priv->clk_mac_refout))
1099d42202dcSRomain Perier 				dev_err(dev, "cannot get clock %s\n",
1100d42202dcSRomain Perier 					"clk_mac_refout");
11017ad269eaSRoger Chen 		}
11027ad269eaSRoger Chen 	}
11037ad269eaSRoger Chen 
110423c94d63SDavid Wu 	bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
110523c94d63SDavid Wu 	if (IS_ERR(bsp_priv->clk_mac_speed))
110623c94d63SDavid Wu 		dev_err(dev, "cannot get clock %s\n", "clk_mac_speed");
110723c94d63SDavid Wu 
11087ad269eaSRoger Chen 	if (bsp_priv->clock_input) {
1109d42202dcSRomain Perier 		dev_info(dev, "clock input from PHY\n");
11107ad269eaSRoger Chen 	} else {
11117ad269eaSRoger Chen 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1112c48fa33cSHeiko Stübner 			clk_set_rate(bsp_priv->clk_mac, 50000000);
11137ad269eaSRoger Chen 	}
11147ad269eaSRoger Chen 
1115fecd4d7eSDavid Wu 	if (plat->phy_node && bsp_priv->integrated_phy) {
1116fecd4d7eSDavid Wu 		bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
1117fecd4d7eSDavid Wu 		if (IS_ERR(bsp_priv->clk_phy)) {
1118fecd4d7eSDavid Wu 			ret = PTR_ERR(bsp_priv->clk_phy);
1119fecd4d7eSDavid Wu 			dev_err(dev, "Cannot get PHY clock: %d\n", ret);
1120fecd4d7eSDavid Wu 			return -EINVAL;
1121fecd4d7eSDavid Wu 		}
1122fecd4d7eSDavid Wu 		clk_set_rate(bsp_priv->clk_phy, 50000000);
1123fecd4d7eSDavid Wu 	}
1124fecd4d7eSDavid Wu 
11257ad269eaSRoger Chen 	return 0;
11267ad269eaSRoger Chen }
11277ad269eaSRoger Chen 
11287ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
11297ad269eaSRoger Chen {
1130428ad1bcSLABBE Corentin 	int phy_iface = bsp_priv->phy_iface;
11317ad269eaSRoger Chen 
11327ad269eaSRoger Chen 	if (enable) {
11337ad269eaSRoger Chen 		if (!bsp_priv->clk_enabled) {
11347ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
11357ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->mac_clk_rx))
11367ad269eaSRoger Chen 					clk_prepare_enable(
11377ad269eaSRoger Chen 						bsp_priv->mac_clk_rx);
11387ad269eaSRoger Chen 
11397ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_ref))
11407ad269eaSRoger Chen 					clk_prepare_enable(
11417ad269eaSRoger Chen 						bsp_priv->clk_mac_ref);
11427ad269eaSRoger Chen 
11437ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_refout))
11447ad269eaSRoger Chen 					clk_prepare_enable(
11457ad269eaSRoger Chen 						bsp_priv->clk_mac_refout);
11467ad269eaSRoger Chen 			}
11477ad269eaSRoger Chen 
1148fecd4d7eSDavid Wu 			if (!IS_ERR(bsp_priv->clk_phy))
1149fecd4d7eSDavid Wu 				clk_prepare_enable(bsp_priv->clk_phy);
1150fecd4d7eSDavid Wu 
11517ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->aclk_mac))
11527ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->aclk_mac);
11537ad269eaSRoger Chen 
11547ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->pclk_mac))
11557ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->pclk_mac);
11567ad269eaSRoger Chen 
11577ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->mac_clk_tx))
11587ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->mac_clk_tx);
11597ad269eaSRoger Chen 
116023c94d63SDavid Wu 			if (!IS_ERR(bsp_priv->clk_mac_speed))
116123c94d63SDavid Wu 				clk_prepare_enable(bsp_priv->clk_mac_speed);
116223c94d63SDavid Wu 
11637ad269eaSRoger Chen 			/**
11647ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
11657ad269eaSRoger Chen 			 *	clk_prepare_enable(bsp_priv->clk_mac);
11667ad269eaSRoger Chen 			 */
11677ad269eaSRoger Chen 			mdelay(5);
11687ad269eaSRoger Chen 			bsp_priv->clk_enabled = true;
11697ad269eaSRoger Chen 		}
11707ad269eaSRoger Chen 	} else {
11717ad269eaSRoger Chen 		if (bsp_priv->clk_enabled) {
11727ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
117393120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->mac_clk_rx);
11747ad269eaSRoger Chen 
117593120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_ref);
11767ad269eaSRoger Chen 
117793120ebaSYueHaibing 				clk_disable_unprepare(bsp_priv->clk_mac_refout);
11787ad269eaSRoger Chen 			}
11797ad269eaSRoger Chen 
1180fecd4d7eSDavid Wu 			clk_disable_unprepare(bsp_priv->clk_phy);
1181fecd4d7eSDavid Wu 
11827ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->aclk_mac);
11837ad269eaSRoger Chen 
11847ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->pclk_mac);
11857ad269eaSRoger Chen 
11867ad269eaSRoger Chen 			clk_disable_unprepare(bsp_priv->mac_clk_tx);
118723c94d63SDavid Wu 
118823c94d63SDavid Wu 			clk_disable_unprepare(bsp_priv->clk_mac_speed);
11897ad269eaSRoger Chen 			/**
11907ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
11917ad269eaSRoger Chen 			 *	clk_disable_unprepare(bsp_priv->clk_mac);
11927ad269eaSRoger Chen 			 */
11937ad269eaSRoger Chen 			bsp_priv->clk_enabled = false;
11947ad269eaSRoger Chen 		}
11957ad269eaSRoger Chen 	}
11967ad269eaSRoger Chen 
11977ad269eaSRoger Chen 	return 0;
11987ad269eaSRoger Chen }
11997ad269eaSRoger Chen 
12007ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
12017ad269eaSRoger Chen {
12022e12f536SRomain Perier 	struct regulator *ldo = bsp_priv->regulator;
12037ad269eaSRoger Chen 	int ret;
12047ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
12057ad269eaSRoger Chen 
12062e12f536SRomain Perier 	if (!ldo) {
1207d42202dcSRomain Perier 		dev_err(dev, "no regulator found\n");
12087ad269eaSRoger Chen 		return -1;
12097ad269eaSRoger Chen 	}
12107ad269eaSRoger Chen 
12117ad269eaSRoger Chen 	if (enable) {
12127ad269eaSRoger Chen 		ret = regulator_enable(ldo);
12132e12f536SRomain Perier 		if (ret)
1214d42202dcSRomain Perier 			dev_err(dev, "fail to enable phy-supply\n");
12157ad269eaSRoger Chen 	} else {
12167ad269eaSRoger Chen 		ret = regulator_disable(ldo);
12172e12f536SRomain Perier 		if (ret)
1218d42202dcSRomain Perier 			dev_err(dev, "fail to disable phy-supply\n");
12197ad269eaSRoger Chen 	}
12207ad269eaSRoger Chen 
12217ad269eaSRoger Chen 	return 0;
12227ad269eaSRoger Chen }
12237ad269eaSRoger Chen 
12240fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1225fecd4d7eSDavid Wu 					  struct plat_stmmacenet_data *plat,
122692c2588fSJoachim Eastwood 					  const struct rk_gmac_ops *ops)
12277ad269eaSRoger Chen {
12287ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv;
12297ad269eaSRoger Chen 	struct device *dev = &pdev->dev;
12307ad269eaSRoger Chen 	int ret;
12317ad269eaSRoger Chen 	const char *strings = NULL;
12327ad269eaSRoger Chen 	int value;
12337ad269eaSRoger Chen 
12347ad269eaSRoger Chen 	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
12357ad269eaSRoger Chen 	if (!bsp_priv)
12367ad269eaSRoger Chen 		return ERR_PTR(-ENOMEM);
12377ad269eaSRoger Chen 
12387ad269eaSRoger Chen 	bsp_priv->phy_iface = of_get_phy_mode(dev->of_node);
12390fb98db1SHeiko Stübner 	bsp_priv->ops = ops;
12407ad269eaSRoger Chen 
12412e12f536SRomain Perier 	bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
12422e12f536SRomain Perier 	if (IS_ERR(bsp_priv->regulator)) {
12432e12f536SRomain Perier 		if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) {
12442e12f536SRomain Perier 			dev_err(dev, "phy regulator is not available yet, deferred probing\n");
12452e12f536SRomain Perier 			return ERR_PTR(-EPROBE_DEFER);
12462e12f536SRomain Perier 		}
12472e12f536SRomain Perier 		dev_err(dev, "no regulator found\n");
12482e12f536SRomain Perier 		bsp_priv->regulator = NULL;
12497ad269eaSRoger Chen 	}
12507ad269eaSRoger Chen 
12517ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
12527ad269eaSRoger Chen 	if (ret) {
1253d42202dcSRomain Perier 		dev_err(dev, "Can not read property: clock_in_out.\n");
12547ad269eaSRoger Chen 		bsp_priv->clock_input = true;
12557ad269eaSRoger Chen 	} else {
1256d42202dcSRomain Perier 		dev_info(dev, "clock input or output? (%s).\n",
1257d42202dcSRomain Perier 			 strings);
12587ad269eaSRoger Chen 		if (!strcmp(strings, "input"))
12597ad269eaSRoger Chen 			bsp_priv->clock_input = true;
12607ad269eaSRoger Chen 		else
12617ad269eaSRoger Chen 			bsp_priv->clock_input = false;
12627ad269eaSRoger Chen 	}
12637ad269eaSRoger Chen 
12647ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
12657ad269eaSRoger Chen 	if (ret) {
12667ad269eaSRoger Chen 		bsp_priv->tx_delay = 0x30;
1267d42202dcSRomain Perier 		dev_err(dev, "Can not read property: tx_delay.");
1268d42202dcSRomain Perier 		dev_err(dev, "set tx_delay to 0x%x\n",
1269d42202dcSRomain Perier 			bsp_priv->tx_delay);
12707ad269eaSRoger Chen 	} else {
1271d42202dcSRomain Perier 		dev_info(dev, "TX delay(0x%x).\n", value);
12727ad269eaSRoger Chen 		bsp_priv->tx_delay = value;
12737ad269eaSRoger Chen 	}
12747ad269eaSRoger Chen 
12757ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
12767ad269eaSRoger Chen 	if (ret) {
12777ad269eaSRoger Chen 		bsp_priv->rx_delay = 0x10;
1278d42202dcSRomain Perier 		dev_err(dev, "Can not read property: rx_delay.");
1279d42202dcSRomain Perier 		dev_err(dev, "set rx_delay to 0x%x\n",
1280d42202dcSRomain Perier 			bsp_priv->rx_delay);
12817ad269eaSRoger Chen 	} else {
1282d42202dcSRomain Perier 		dev_info(dev, "RX delay(0x%x).\n", value);
12837ad269eaSRoger Chen 		bsp_priv->rx_delay = value;
12847ad269eaSRoger Chen 	}
12857ad269eaSRoger Chen 
12867ad269eaSRoger Chen 	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
12877ad269eaSRoger Chen 							"rockchip,grf");
12887ad269eaSRoger Chen 
1289fecd4d7eSDavid Wu 	if (plat->phy_node) {
1290fecd4d7eSDavid Wu 		bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
1291fecd4d7eSDavid Wu 								 "phy-is-integrated");
1292fecd4d7eSDavid Wu 		if (bsp_priv->integrated_phy) {
1293fecd4d7eSDavid Wu 			bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
1294fecd4d7eSDavid Wu 			if (IS_ERR(bsp_priv->phy_reset)) {
1295fecd4d7eSDavid Wu 				dev_err(&pdev->dev, "No PHY reset control found.\n");
1296fecd4d7eSDavid Wu 				bsp_priv->phy_reset = NULL;
1297fecd4d7eSDavid Wu 			}
1298fecd4d7eSDavid Wu 		}
1299fecd4d7eSDavid Wu 	}
1300fecd4d7eSDavid Wu 	dev_info(dev, "integrated PHY? (%s).\n",
1301fecd4d7eSDavid Wu 		 bsp_priv->integrated_phy ? "yes" : "no");
1302fecd4d7eSDavid Wu 
1303fecd4d7eSDavid Wu 	bsp_priv->pdev = pdev;
130445383f52SRoger Chen 
130545383f52SRoger Chen 	return bsp_priv;
130645383f52SRoger Chen }
130745383f52SRoger Chen 
130845383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
130945383f52SRoger Chen {
131045383f52SRoger Chen 	int ret;
131145383f52SRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
131245383f52SRoger Chen 
1313f217bfdeSHeiko Stübner 	ret = gmac_clk_enable(bsp_priv, true);
1314f217bfdeSHeiko Stübner 	if (ret)
1315f217bfdeSHeiko Stübner 		return ret;
1316f217bfdeSHeiko Stübner 
13177ad269eaSRoger Chen 	/*rmii or rgmii*/
1318eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1319eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1320d42202dcSRomain Perier 		dev_info(dev, "init for RGMII\n");
13210fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
13220fb98db1SHeiko Stübner 					    bsp_priv->rx_delay);
1323eaf70ad1SWadim Egorov 		break;
1324eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1325eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_ID\n");
1326eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
1327eaf70ad1SWadim Egorov 		break;
1328eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1329eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_RXID\n");
1330eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
1331eaf70ad1SWadim Egorov 		break;
1332eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
1333eaf70ad1SWadim Egorov 		dev_info(dev, "init for RGMII_TXID\n");
1334eaf70ad1SWadim Egorov 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
1335eaf70ad1SWadim Egorov 		break;
1336eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
1337d42202dcSRomain Perier 		dev_info(dev, "init for RMII\n");
13380fb98db1SHeiko Stübner 		bsp_priv->ops->set_to_rmii(bsp_priv);
1339eaf70ad1SWadim Egorov 		break;
1340eaf70ad1SWadim Egorov 	default:
1341d42202dcSRomain Perier 		dev_err(dev, "NO interface defined!\n");
13427ad269eaSRoger Chen 	}
13437ad269eaSRoger Chen 
13447ad269eaSRoger Chen 	ret = phy_power_on(bsp_priv, true);
1345*c69c29a1SAlexey Khoroshilov 	if (ret) {
1346*c69c29a1SAlexey Khoroshilov 		gmac_clk_enable(bsp_priv, false);
13477ad269eaSRoger Chen 		return ret;
1348*c69c29a1SAlexey Khoroshilov 	}
13497ad269eaSRoger Chen 
13502c896fb0SDavid Wu 	pm_runtime_enable(dev);
13512c896fb0SDavid Wu 	pm_runtime_get_sync(dev);
13522c896fb0SDavid Wu 
1353fecd4d7eSDavid Wu 	if (bsp_priv->integrated_phy)
1354fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerup(bsp_priv);
1355fecd4d7eSDavid Wu 
13567ad269eaSRoger Chen 	return 0;
13577ad269eaSRoger Chen }
13587ad269eaSRoger Chen 
1359229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac)
13607ad269eaSRoger Chen {
13612c896fb0SDavid Wu 	struct device *dev = &gmac->pdev->dev;
13622c896fb0SDavid Wu 
1363fecd4d7eSDavid Wu 	if (gmac->integrated_phy)
1364fecd4d7eSDavid Wu 		rk_gmac_integrated_phy_powerdown(gmac);
1365fecd4d7eSDavid Wu 
13662c896fb0SDavid Wu 	pm_runtime_put_sync(dev);
13672c896fb0SDavid Wu 	pm_runtime_disable(dev);
13682c896fb0SDavid Wu 
13697ad269eaSRoger Chen 	phy_power_on(gmac, false);
13707ad269eaSRoger Chen 	gmac_clk_enable(gmac, false);
13717ad269eaSRoger Chen }
13727ad269eaSRoger Chen 
13737ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed)
13747ad269eaSRoger Chen {
13757ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
13767ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
13777ad269eaSRoger Chen 
1378eaf70ad1SWadim Egorov 	switch (bsp_priv->phy_iface) {
1379eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII:
1380eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_ID:
1381eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_RXID:
1382eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RGMII_TXID:
13830fb98db1SHeiko Stübner 		bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1384eaf70ad1SWadim Egorov 		break;
1385eaf70ad1SWadim Egorov 	case PHY_INTERFACE_MODE_RMII:
13860fb98db1SHeiko Stübner 		bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1387eaf70ad1SWadim Egorov 		break;
1388eaf70ad1SWadim Egorov 	default:
13897ad269eaSRoger Chen 		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
13907ad269eaSRoger Chen 	}
1391eaf70ad1SWadim Egorov }
13927ad269eaSRoger Chen 
139327ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev)
139427ffefd2SJoachim Eastwood {
139527ffefd2SJoachim Eastwood 	struct plat_stmmacenet_data *plat_dat;
139627ffefd2SJoachim Eastwood 	struct stmmac_resources stmmac_res;
1397f529f182SJoachim Eastwood 	const struct rk_gmac_ops *data;
139827ffefd2SJoachim Eastwood 	int ret;
139927ffefd2SJoachim Eastwood 
1400149adeddSJoachim Eastwood 	data = of_device_get_match_data(&pdev->dev);
1401149adeddSJoachim Eastwood 	if (!data) {
1402149adeddSJoachim Eastwood 		dev_err(&pdev->dev, "no of match data provided\n");
1403149adeddSJoachim Eastwood 		return -EINVAL;
1404149adeddSJoachim Eastwood 	}
1405149adeddSJoachim Eastwood 
140627ffefd2SJoachim Eastwood 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
140727ffefd2SJoachim Eastwood 	if (ret)
140827ffefd2SJoachim Eastwood 		return ret;
140927ffefd2SJoachim Eastwood 
141027ffefd2SJoachim Eastwood 	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
141127ffefd2SJoachim Eastwood 	if (IS_ERR(plat_dat))
141227ffefd2SJoachim Eastwood 		return PTR_ERR(plat_dat);
141327ffefd2SJoachim Eastwood 
141427ffefd2SJoachim Eastwood 	plat_dat->has_gmac = true;
141527ffefd2SJoachim Eastwood 	plat_dat->fix_mac_speed = rk_fix_speed;
141627ffefd2SJoachim Eastwood 
1417fecd4d7eSDavid Wu 	plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
1418d2ed0a77SJohan Hovold 	if (IS_ERR(plat_dat->bsp_priv)) {
1419d2ed0a77SJohan Hovold 		ret = PTR_ERR(plat_dat->bsp_priv);
1420d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
1421d2ed0a77SJohan Hovold 	}
142227ffefd2SJoachim Eastwood 
1423fecd4d7eSDavid Wu 	ret = rk_gmac_clk_init(plat_dat);
1424fecd4d7eSDavid Wu 	if (ret)
1425fecd4d7eSDavid Wu 		return ret;
1426fecd4d7eSDavid Wu 
142707a5e769SJoachim Eastwood 	ret = rk_gmac_powerup(plat_dat->bsp_priv);
142827ffefd2SJoachim Eastwood 	if (ret)
1429d2ed0a77SJohan Hovold 		goto err_remove_config_dt;
143027ffefd2SJoachim Eastwood 
14312d222656SJohan Hovold 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
14322d222656SJohan Hovold 	if (ret)
14332745529aSDavid S. Miller 		goto err_gmac_powerdown;
14342d222656SJohan Hovold 
14352d222656SJohan Hovold 	return 0;
14362d222656SJohan Hovold 
14372745529aSDavid S. Miller err_gmac_powerdown:
14382745529aSDavid S. Miller 	rk_gmac_powerdown(plat_dat->bsp_priv);
1439d2ed0a77SJohan Hovold err_remove_config_dt:
1440d2ed0a77SJohan Hovold 	stmmac_remove_config_dt(pdev, plat_dat);
14412d222656SJohan Hovold 
14422d222656SJohan Hovold 	return ret;
144327ffefd2SJoachim Eastwood }
144427ffefd2SJoachim Eastwood 
14450de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev)
14460de8c4c9SJoachim Eastwood {
14470de8c4c9SJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
14480de8c4c9SJoachim Eastwood 	int ret = stmmac_dvr_remove(&pdev->dev);
14490de8c4c9SJoachim Eastwood 
14500de8c4c9SJoachim Eastwood 	rk_gmac_powerdown(bsp_priv);
14510de8c4c9SJoachim Eastwood 
14520de8c4c9SJoachim Eastwood 	return ret;
14530de8c4c9SJoachim Eastwood }
14540de8c4c9SJoachim Eastwood 
14555619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP
14565619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev)
14575619468aSJoachim Eastwood {
14585619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
14595619468aSJoachim Eastwood 	int ret = stmmac_suspend(dev);
14605619468aSJoachim Eastwood 
14615619468aSJoachim Eastwood 	/* Keep the PHY up if we use Wake-on-Lan. */
14625619468aSJoachim Eastwood 	if (!device_may_wakeup(dev)) {
14635619468aSJoachim Eastwood 		rk_gmac_powerdown(bsp_priv);
14645619468aSJoachim Eastwood 		bsp_priv->suspended = true;
14655619468aSJoachim Eastwood 	}
14665619468aSJoachim Eastwood 
14675619468aSJoachim Eastwood 	return ret;
14685619468aSJoachim Eastwood }
14695619468aSJoachim Eastwood 
14705619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev)
14715619468aSJoachim Eastwood {
14725619468aSJoachim Eastwood 	struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
14735619468aSJoachim Eastwood 
14745619468aSJoachim Eastwood 	/* The PHY was up for Wake-on-Lan. */
14755619468aSJoachim Eastwood 	if (bsp_priv->suspended) {
14765619468aSJoachim Eastwood 		rk_gmac_powerup(bsp_priv);
14775619468aSJoachim Eastwood 		bsp_priv->suspended = false;
14785619468aSJoachim Eastwood 	}
14795619468aSJoachim Eastwood 
14805619468aSJoachim Eastwood 	return stmmac_resume(dev);
14815619468aSJoachim Eastwood }
14825619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */
14835619468aSJoachim Eastwood 
14845619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
14855619468aSJoachim Eastwood 
1486e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = {
148723c94d63SDavid Wu 	{ .compatible = "rockchip,px30-gmac",	.data = &px30_ops   },
148805946876SDavid Wu 	{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
1489e7ffd812SXing Zheng 	{ .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
1490f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
1491d4ff816eSdavid.wu 	{ .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
1492ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
1493f529f182SJoachim Eastwood 	{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
1494ba289af8SRoger Chen 	{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
149589c9c163SDavid Wu 	{ .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
1496e0fb4013SJoachim Eastwood 	{ }
1497e0fb4013SJoachim Eastwood };
1498e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
1499e0fb4013SJoachim Eastwood 
1500e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = {
150127ffefd2SJoachim Eastwood 	.probe  = rk_gmac_probe,
15020de8c4c9SJoachim Eastwood 	.remove = rk_gmac_remove,
1503e0fb4013SJoachim Eastwood 	.driver = {
1504e0fb4013SJoachim Eastwood 		.name           = "rk_gmac-dwmac",
15055619468aSJoachim Eastwood 		.pm		= &rk_gmac_pm_ops,
1506e0fb4013SJoachim Eastwood 		.of_match_table = rk_gmac_dwmac_match,
1507e0fb4013SJoachim Eastwood 	},
1508e0fb4013SJoachim Eastwood };
1509e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver);
1510e0fb4013SJoachim Eastwood 
1511e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
1512e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
1513e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL");
1514