xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c (revision 7ad269ea1a2b7ddc8ae26794162c21bad2d9b2e5)
1*7ad269eaSRoger Chen /**
2*7ad269eaSRoger Chen  * dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
3*7ad269eaSRoger Chen  *
4*7ad269eaSRoger Chen  * Copyright (C) 2014 Chen-Zhi (Roger Chen)
5*7ad269eaSRoger Chen  *
6*7ad269eaSRoger Chen  * Chen-Zhi (Roger Chen)  <roger.chen@rock-chips.com>
7*7ad269eaSRoger Chen  *
8*7ad269eaSRoger Chen  * This program is free software; you can redistribute it and/or modify
9*7ad269eaSRoger Chen  * it under the terms of the GNU General Public License as published by
10*7ad269eaSRoger Chen  * the Free Software Foundation; either version 2 of the License, or
11*7ad269eaSRoger Chen  * (at your option) any later version.
12*7ad269eaSRoger Chen  *
13*7ad269eaSRoger Chen  * This program is distributed in the hope that it will be useful,
14*7ad269eaSRoger Chen  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*7ad269eaSRoger Chen  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*7ad269eaSRoger Chen  * GNU General Public License for more details.
17*7ad269eaSRoger Chen  */
18*7ad269eaSRoger Chen 
19*7ad269eaSRoger Chen #include <linux/stmmac.h>
20*7ad269eaSRoger Chen #include <linux/bitops.h>
21*7ad269eaSRoger Chen #include <linux/clk.h>
22*7ad269eaSRoger Chen #include <linux/phy.h>
23*7ad269eaSRoger Chen #include <linux/of_net.h>
24*7ad269eaSRoger Chen #include <linux/gpio.h>
25*7ad269eaSRoger Chen #include <linux/of_gpio.h>
26*7ad269eaSRoger Chen #include <linux/of_device.h>
27*7ad269eaSRoger Chen #include <linux/regulator/consumer.h>
28*7ad269eaSRoger Chen #include <linux/delay.h>
29*7ad269eaSRoger Chen #include <linux/mfd/syscon.h>
30*7ad269eaSRoger Chen #include <linux/regmap.h>
31*7ad269eaSRoger Chen 
32*7ad269eaSRoger Chen struct rk_priv_data {
33*7ad269eaSRoger Chen 	struct platform_device *pdev;
34*7ad269eaSRoger Chen 	int phy_iface;
35*7ad269eaSRoger Chen 	char regulator[32];
36*7ad269eaSRoger Chen 
37*7ad269eaSRoger Chen 	bool clk_enabled;
38*7ad269eaSRoger Chen 	bool clock_input;
39*7ad269eaSRoger Chen 
40*7ad269eaSRoger Chen 	struct clk *clk_mac;
41*7ad269eaSRoger Chen 	struct clk *clk_mac_pll;
42*7ad269eaSRoger Chen 	struct clk *gmac_clkin;
43*7ad269eaSRoger Chen 	struct clk *mac_clk_rx;
44*7ad269eaSRoger Chen 	struct clk *mac_clk_tx;
45*7ad269eaSRoger Chen 	struct clk *clk_mac_ref;
46*7ad269eaSRoger Chen 	struct clk *clk_mac_refout;
47*7ad269eaSRoger Chen 	struct clk *aclk_mac;
48*7ad269eaSRoger Chen 	struct clk *pclk_mac;
49*7ad269eaSRoger Chen 
50*7ad269eaSRoger Chen 	int tx_delay;
51*7ad269eaSRoger Chen 	int rx_delay;
52*7ad269eaSRoger Chen 
53*7ad269eaSRoger Chen 	struct regmap *grf;
54*7ad269eaSRoger Chen };
55*7ad269eaSRoger Chen 
56*7ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \
57*7ad269eaSRoger Chen 		((val) << (shift) | (mask) << ((shift) + 16))
58*7ad269eaSRoger Chen 
59*7ad269eaSRoger Chen #define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
60*7ad269eaSRoger Chen #define GRF_CLR_BIT(nr)	(BIT(nr+16))
61*7ad269eaSRoger Chen 
62*7ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1	0x0248
63*7ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3	0x0250
64*7ad269eaSRoger Chen #define RK3288_GRF_GPIO3D_E	0x01ec
65*7ad269eaSRoger Chen #define RK3288_GRF_GPIO4A_E	0x01f0
66*7ad269eaSRoger Chen #define RK3288_GRF_GPIO4B_E	0x01f4
67*7ad269eaSRoger Chen 
68*7ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/
69*7ad269eaSRoger Chen #define GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
70*7ad269eaSRoger Chen #define GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
71*7ad269eaSRoger Chen #define GMAC_FLOW_CTRL		GRF_BIT(9)
72*7ad269eaSRoger Chen #define GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
73*7ad269eaSRoger Chen #define GMAC_SPEED_10M		GRF_CLR_BIT(10)
74*7ad269eaSRoger Chen #define GMAC_SPEED_100M		GRF_BIT(10)
75*7ad269eaSRoger Chen #define GMAC_RMII_CLK_25M	GRF_BIT(11)
76*7ad269eaSRoger Chen #define GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
77*7ad269eaSRoger Chen #define GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
78*7ad269eaSRoger Chen #define GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
79*7ad269eaSRoger Chen #define GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
80*7ad269eaSRoger Chen #define GMAC_RMII_MODE		GRF_BIT(14)
81*7ad269eaSRoger Chen #define GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
82*7ad269eaSRoger Chen 
83*7ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/
84*7ad269eaSRoger Chen #define GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
85*7ad269eaSRoger Chen #define GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
86*7ad269eaSRoger Chen #define GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
87*7ad269eaSRoger Chen #define GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
88*7ad269eaSRoger Chen #define GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
89*7ad269eaSRoger Chen #define GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
90*7ad269eaSRoger Chen 
91*7ad269eaSRoger Chen static void set_to_rgmii(struct rk_priv_data *bsp_priv,
92*7ad269eaSRoger Chen 			 int tx_delay, int rx_delay)
93*7ad269eaSRoger Chen {
94*7ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
95*7ad269eaSRoger Chen 
96*7ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
97*7ad269eaSRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
98*7ad269eaSRoger Chen 		return;
99*7ad269eaSRoger Chen 	}
100*7ad269eaSRoger Chen 
101*7ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
102*7ad269eaSRoger Chen 		     GMAC_PHY_INTF_SEL_RGMII | GMAC_RMII_MODE_CLR);
103*7ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
104*7ad269eaSRoger Chen 		     GMAC_RXCLK_DLY_ENABLE | GMAC_TXCLK_DLY_ENABLE |
105*7ad269eaSRoger Chen 		     GMAC_CLK_RX_DL_CFG(rx_delay) |
106*7ad269eaSRoger Chen 		     GMAC_CLK_TX_DL_CFG(tx_delay));
107*7ad269eaSRoger Chen }
108*7ad269eaSRoger Chen 
109*7ad269eaSRoger Chen static void set_to_rmii(struct rk_priv_data *bsp_priv)
110*7ad269eaSRoger Chen {
111*7ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
112*7ad269eaSRoger Chen 
113*7ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
114*7ad269eaSRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
115*7ad269eaSRoger Chen 		return;
116*7ad269eaSRoger Chen 	}
117*7ad269eaSRoger Chen 
118*7ad269eaSRoger Chen 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
119*7ad269eaSRoger Chen 		     GMAC_PHY_INTF_SEL_RMII | GMAC_RMII_MODE);
120*7ad269eaSRoger Chen }
121*7ad269eaSRoger Chen 
122*7ad269eaSRoger Chen static void set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
123*7ad269eaSRoger Chen {
124*7ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
125*7ad269eaSRoger Chen 
126*7ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
127*7ad269eaSRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
128*7ad269eaSRoger Chen 		return;
129*7ad269eaSRoger Chen 	}
130*7ad269eaSRoger Chen 
131*7ad269eaSRoger Chen 	if (speed == 10)
132*7ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_2_5M);
133*7ad269eaSRoger Chen 	else if (speed == 100)
134*7ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_25M);
135*7ad269eaSRoger Chen 	else if (speed == 1000)
136*7ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_125M);
137*7ad269eaSRoger Chen 	else
138*7ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
139*7ad269eaSRoger Chen }
140*7ad269eaSRoger Chen 
141*7ad269eaSRoger Chen static void set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
142*7ad269eaSRoger Chen {
143*7ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
144*7ad269eaSRoger Chen 
145*7ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->grf)) {
146*7ad269eaSRoger Chen 		dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
147*7ad269eaSRoger Chen 		return;
148*7ad269eaSRoger Chen 	}
149*7ad269eaSRoger Chen 
150*7ad269eaSRoger Chen 	if (speed == 10) {
151*7ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
152*7ad269eaSRoger Chen 			     GMAC_RMII_CLK_2_5M | GMAC_SPEED_10M);
153*7ad269eaSRoger Chen 	} else if (speed == 100) {
154*7ad269eaSRoger Chen 		regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
155*7ad269eaSRoger Chen 			     GMAC_RMII_CLK_25M | GMAC_SPEED_100M);
156*7ad269eaSRoger Chen 	} else {
157*7ad269eaSRoger Chen 		dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
158*7ad269eaSRoger Chen 	}
159*7ad269eaSRoger Chen }
160*7ad269eaSRoger Chen 
161*7ad269eaSRoger Chen static int gmac_clk_init(struct rk_priv_data *bsp_priv)
162*7ad269eaSRoger Chen {
163*7ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
164*7ad269eaSRoger Chen 
165*7ad269eaSRoger Chen 	bsp_priv->clk_enabled = false;
166*7ad269eaSRoger Chen 
167*7ad269eaSRoger Chen 	bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
168*7ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_rx))
169*7ad269eaSRoger Chen 		dev_err(dev, "%s: cannot get clock %s\n",
170*7ad269eaSRoger Chen 			__func__, "mac_clk_rx");
171*7ad269eaSRoger Chen 
172*7ad269eaSRoger Chen 	bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
173*7ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->mac_clk_tx))
174*7ad269eaSRoger Chen 		dev_err(dev, "%s: cannot get clock %s\n",
175*7ad269eaSRoger Chen 			__func__, "mac_clk_tx");
176*7ad269eaSRoger Chen 
177*7ad269eaSRoger Chen 	bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
178*7ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->aclk_mac))
179*7ad269eaSRoger Chen 		dev_err(dev, "%s: cannot get clock %s\n",
180*7ad269eaSRoger Chen 			__func__, "aclk_mac");
181*7ad269eaSRoger Chen 
182*7ad269eaSRoger Chen 	bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
183*7ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->pclk_mac))
184*7ad269eaSRoger Chen 		dev_err(dev, "%s: cannot get clock %s\n",
185*7ad269eaSRoger Chen 			__func__, "pclk_mac");
186*7ad269eaSRoger Chen 
187*7ad269eaSRoger Chen 	bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
188*7ad269eaSRoger Chen 	if (IS_ERR(bsp_priv->clk_mac))
189*7ad269eaSRoger Chen 		dev_err(dev, "%s: cannot get clock %s\n",
190*7ad269eaSRoger Chen 			__func__, "stmmaceth");
191*7ad269eaSRoger Chen 
192*7ad269eaSRoger Chen 	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
193*7ad269eaSRoger Chen 		bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
194*7ad269eaSRoger Chen 		if (IS_ERR(bsp_priv->clk_mac_ref))
195*7ad269eaSRoger Chen 			dev_err(dev, "%s: cannot get clock %s\n",
196*7ad269eaSRoger Chen 				__func__, "clk_mac_ref");
197*7ad269eaSRoger Chen 
198*7ad269eaSRoger Chen 		if (!bsp_priv->clock_input) {
199*7ad269eaSRoger Chen 			bsp_priv->clk_mac_refout =
200*7ad269eaSRoger Chen 				devm_clk_get(dev, "clk_mac_refout");
201*7ad269eaSRoger Chen 			if (IS_ERR(bsp_priv->clk_mac_refout))
202*7ad269eaSRoger Chen 				dev_err(dev, "%s: cannot get clock %s\n",
203*7ad269eaSRoger Chen 					__func__, "clk_mac_refout");
204*7ad269eaSRoger Chen 		}
205*7ad269eaSRoger Chen 	}
206*7ad269eaSRoger Chen 
207*7ad269eaSRoger Chen 	if (bsp_priv->clock_input) {
208*7ad269eaSRoger Chen 		dev_info(dev, "%s: clock input from PHY\n", __func__);
209*7ad269eaSRoger Chen 	} else {
210*7ad269eaSRoger Chen 		if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
211*7ad269eaSRoger Chen 			clk_set_rate(bsp_priv->clk_mac_pll, 50000000);
212*7ad269eaSRoger Chen 	}
213*7ad269eaSRoger Chen 
214*7ad269eaSRoger Chen 	return 0;
215*7ad269eaSRoger Chen }
216*7ad269eaSRoger Chen 
217*7ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
218*7ad269eaSRoger Chen {
219*7ad269eaSRoger Chen 	int phy_iface = phy_iface = bsp_priv->phy_iface;
220*7ad269eaSRoger Chen 
221*7ad269eaSRoger Chen 	if (enable) {
222*7ad269eaSRoger Chen 		if (!bsp_priv->clk_enabled) {
223*7ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
224*7ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->mac_clk_rx))
225*7ad269eaSRoger Chen 					clk_prepare_enable(
226*7ad269eaSRoger Chen 						bsp_priv->mac_clk_rx);
227*7ad269eaSRoger Chen 
228*7ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_ref))
229*7ad269eaSRoger Chen 					clk_prepare_enable(
230*7ad269eaSRoger Chen 						bsp_priv->clk_mac_ref);
231*7ad269eaSRoger Chen 
232*7ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_refout))
233*7ad269eaSRoger Chen 					clk_prepare_enable(
234*7ad269eaSRoger Chen 						bsp_priv->clk_mac_refout);
235*7ad269eaSRoger Chen 			}
236*7ad269eaSRoger Chen 
237*7ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->aclk_mac))
238*7ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->aclk_mac);
239*7ad269eaSRoger Chen 
240*7ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->pclk_mac))
241*7ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->pclk_mac);
242*7ad269eaSRoger Chen 
243*7ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->mac_clk_tx))
244*7ad269eaSRoger Chen 				clk_prepare_enable(bsp_priv->mac_clk_tx);
245*7ad269eaSRoger Chen 
246*7ad269eaSRoger Chen 			/**
247*7ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
248*7ad269eaSRoger Chen 			 *	clk_prepare_enable(bsp_priv->clk_mac);
249*7ad269eaSRoger Chen 			 */
250*7ad269eaSRoger Chen 			mdelay(5);
251*7ad269eaSRoger Chen 			bsp_priv->clk_enabled = true;
252*7ad269eaSRoger Chen 		}
253*7ad269eaSRoger Chen 	} else {
254*7ad269eaSRoger Chen 		if (bsp_priv->clk_enabled) {
255*7ad269eaSRoger Chen 			if (phy_iface == PHY_INTERFACE_MODE_RMII) {
256*7ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->mac_clk_rx))
257*7ad269eaSRoger Chen 					clk_disable_unprepare(
258*7ad269eaSRoger Chen 						bsp_priv->mac_clk_rx);
259*7ad269eaSRoger Chen 
260*7ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_ref))
261*7ad269eaSRoger Chen 					clk_disable_unprepare(
262*7ad269eaSRoger Chen 						bsp_priv->clk_mac_ref);
263*7ad269eaSRoger Chen 
264*7ad269eaSRoger Chen 				if (!IS_ERR(bsp_priv->clk_mac_refout))
265*7ad269eaSRoger Chen 					clk_disable_unprepare(
266*7ad269eaSRoger Chen 						bsp_priv->clk_mac_refout);
267*7ad269eaSRoger Chen 			}
268*7ad269eaSRoger Chen 
269*7ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->aclk_mac))
270*7ad269eaSRoger Chen 				clk_disable_unprepare(bsp_priv->aclk_mac);
271*7ad269eaSRoger Chen 
272*7ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->pclk_mac))
273*7ad269eaSRoger Chen 				clk_disable_unprepare(bsp_priv->pclk_mac);
274*7ad269eaSRoger Chen 
275*7ad269eaSRoger Chen 			if (!IS_ERR(bsp_priv->mac_clk_tx))
276*7ad269eaSRoger Chen 				clk_disable_unprepare(bsp_priv->mac_clk_tx);
277*7ad269eaSRoger Chen 			/**
278*7ad269eaSRoger Chen 			 * if (!IS_ERR(bsp_priv->clk_mac))
279*7ad269eaSRoger Chen 			 *	clk_disable_unprepare(bsp_priv->clk_mac);
280*7ad269eaSRoger Chen 			 */
281*7ad269eaSRoger Chen 			bsp_priv->clk_enabled = false;
282*7ad269eaSRoger Chen 		}
283*7ad269eaSRoger Chen 	}
284*7ad269eaSRoger Chen 
285*7ad269eaSRoger Chen 	return 0;
286*7ad269eaSRoger Chen }
287*7ad269eaSRoger Chen 
288*7ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
289*7ad269eaSRoger Chen {
290*7ad269eaSRoger Chen 	struct regulator *ldo;
291*7ad269eaSRoger Chen 	char *ldostr = bsp_priv->regulator;
292*7ad269eaSRoger Chen 	int ret;
293*7ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
294*7ad269eaSRoger Chen 
295*7ad269eaSRoger Chen 	if (!ldostr) {
296*7ad269eaSRoger Chen 		dev_err(dev, "%s: no ldo found\n", __func__);
297*7ad269eaSRoger Chen 		return -1;
298*7ad269eaSRoger Chen 	}
299*7ad269eaSRoger Chen 
300*7ad269eaSRoger Chen 	ldo = regulator_get(NULL, ldostr);
301*7ad269eaSRoger Chen 	if (!ldo) {
302*7ad269eaSRoger Chen 		dev_err(dev, "\n%s get ldo %s failed\n", __func__, ldostr);
303*7ad269eaSRoger Chen 	} else {
304*7ad269eaSRoger Chen 		if (enable) {
305*7ad269eaSRoger Chen 			if (!regulator_is_enabled(ldo)) {
306*7ad269eaSRoger Chen 				regulator_set_voltage(ldo, 3300000, 3300000);
307*7ad269eaSRoger Chen 				ret = regulator_enable(ldo);
308*7ad269eaSRoger Chen 				if (ret != 0)
309*7ad269eaSRoger Chen 					dev_err(dev, "%s: fail to enable %s\n",
310*7ad269eaSRoger Chen 						__func__, ldostr);
311*7ad269eaSRoger Chen 				else
312*7ad269eaSRoger Chen 					dev_info(dev, "turn on ldo done.\n");
313*7ad269eaSRoger Chen 			} else {
314*7ad269eaSRoger Chen 				dev_warn(dev, "%s is enabled before enable",
315*7ad269eaSRoger Chen 					 ldostr);
316*7ad269eaSRoger Chen 			}
317*7ad269eaSRoger Chen 		} else {
318*7ad269eaSRoger Chen 			if (regulator_is_enabled(ldo)) {
319*7ad269eaSRoger Chen 				ret = regulator_disable(ldo);
320*7ad269eaSRoger Chen 				if (ret != 0)
321*7ad269eaSRoger Chen 					dev_err(dev, "%s: fail to disable %s\n",
322*7ad269eaSRoger Chen 						__func__, ldostr);
323*7ad269eaSRoger Chen 				else
324*7ad269eaSRoger Chen 					dev_info(dev, "turn off ldo done.\n");
325*7ad269eaSRoger Chen 			} else {
326*7ad269eaSRoger Chen 				dev_warn(dev, "%s is disabled before disable",
327*7ad269eaSRoger Chen 					 ldostr);
328*7ad269eaSRoger Chen 			}
329*7ad269eaSRoger Chen 		}
330*7ad269eaSRoger Chen 		regulator_put(ldo);
331*7ad269eaSRoger Chen 	}
332*7ad269eaSRoger Chen 
333*7ad269eaSRoger Chen 	return 0;
334*7ad269eaSRoger Chen }
335*7ad269eaSRoger Chen 
336*7ad269eaSRoger Chen static void *rk_gmac_setup(struct platform_device *pdev)
337*7ad269eaSRoger Chen {
338*7ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv;
339*7ad269eaSRoger Chen 	struct device *dev = &pdev->dev;
340*7ad269eaSRoger Chen 	int ret;
341*7ad269eaSRoger Chen 	const char *strings = NULL;
342*7ad269eaSRoger Chen 	int value;
343*7ad269eaSRoger Chen 
344*7ad269eaSRoger Chen 	bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
345*7ad269eaSRoger Chen 	if (!bsp_priv)
346*7ad269eaSRoger Chen 		return ERR_PTR(-ENOMEM);
347*7ad269eaSRoger Chen 
348*7ad269eaSRoger Chen 	bsp_priv->phy_iface = of_get_phy_mode(dev->of_node);
349*7ad269eaSRoger Chen 
350*7ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "phy_regulator", &strings);
351*7ad269eaSRoger Chen 	if (ret) {
352*7ad269eaSRoger Chen 		dev_warn(dev, "%s: Can not read property: phy_regulator.\n",
353*7ad269eaSRoger Chen 			 __func__);
354*7ad269eaSRoger Chen 	} else {
355*7ad269eaSRoger Chen 		dev_info(dev, "%s: PHY power controlled by regulator(%s).\n",
356*7ad269eaSRoger Chen 			 __func__, strings);
357*7ad269eaSRoger Chen 		strcpy(bsp_priv->regulator, strings);
358*7ad269eaSRoger Chen 	}
359*7ad269eaSRoger Chen 
360*7ad269eaSRoger Chen 	ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
361*7ad269eaSRoger Chen 	if (ret) {
362*7ad269eaSRoger Chen 		dev_err(dev, "%s: Can not read property: clock_in_out.\n",
363*7ad269eaSRoger Chen 			__func__);
364*7ad269eaSRoger Chen 		bsp_priv->clock_input = true;
365*7ad269eaSRoger Chen 	} else {
366*7ad269eaSRoger Chen 		dev_info(dev, "%s: clock input or output? (%s).\n",
367*7ad269eaSRoger Chen 			 __func__, strings);
368*7ad269eaSRoger Chen 		if (!strcmp(strings, "input"))
369*7ad269eaSRoger Chen 			bsp_priv->clock_input = true;
370*7ad269eaSRoger Chen 		else
371*7ad269eaSRoger Chen 			bsp_priv->clock_input = false;
372*7ad269eaSRoger Chen 	}
373*7ad269eaSRoger Chen 
374*7ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
375*7ad269eaSRoger Chen 	if (ret) {
376*7ad269eaSRoger Chen 		bsp_priv->tx_delay = 0x30;
377*7ad269eaSRoger Chen 		dev_err(dev, "%s: Can not read property: tx_delay.", __func__);
378*7ad269eaSRoger Chen 		dev_err(dev, "%s: set tx_delay to 0x%x\n",
379*7ad269eaSRoger Chen 			__func__, bsp_priv->tx_delay);
380*7ad269eaSRoger Chen 	} else {
381*7ad269eaSRoger Chen 		dev_info(dev, "%s: TX delay(0x%x).\n", __func__, value);
382*7ad269eaSRoger Chen 		bsp_priv->tx_delay = value;
383*7ad269eaSRoger Chen 	}
384*7ad269eaSRoger Chen 
385*7ad269eaSRoger Chen 	ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
386*7ad269eaSRoger Chen 	if (ret) {
387*7ad269eaSRoger Chen 		bsp_priv->rx_delay = 0x10;
388*7ad269eaSRoger Chen 		dev_err(dev, "%s: Can not read property: rx_delay.", __func__);
389*7ad269eaSRoger Chen 		dev_err(dev, "%s: set rx_delay to 0x%x\n",
390*7ad269eaSRoger Chen 			__func__, bsp_priv->rx_delay);
391*7ad269eaSRoger Chen 	} else {
392*7ad269eaSRoger Chen 		dev_info(dev, "%s: RX delay(0x%x).\n", __func__, value);
393*7ad269eaSRoger Chen 		bsp_priv->rx_delay = value;
394*7ad269eaSRoger Chen 	}
395*7ad269eaSRoger Chen 
396*7ad269eaSRoger Chen 	bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
397*7ad269eaSRoger Chen 							"rockchip,grf");
398*7ad269eaSRoger Chen 	bsp_priv->pdev = pdev;
399*7ad269eaSRoger Chen 
400*7ad269eaSRoger Chen 	/*rmii or rgmii*/
401*7ad269eaSRoger Chen 	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) {
402*7ad269eaSRoger Chen 		dev_info(dev, "%s: init for RGMII\n", __func__);
403*7ad269eaSRoger Chen 		set_to_rgmii(bsp_priv, bsp_priv->tx_delay, bsp_priv->rx_delay);
404*7ad269eaSRoger Chen 	} else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
405*7ad269eaSRoger Chen 		dev_info(dev, "%s: init for RMII\n", __func__);
406*7ad269eaSRoger Chen 		set_to_rmii(bsp_priv);
407*7ad269eaSRoger Chen 	} else {
408*7ad269eaSRoger Chen 		dev_err(dev, "%s: NO interface defined!\n", __func__);
409*7ad269eaSRoger Chen 	}
410*7ad269eaSRoger Chen 
411*7ad269eaSRoger Chen 	gmac_clk_init(bsp_priv);
412*7ad269eaSRoger Chen 
413*7ad269eaSRoger Chen 	return bsp_priv;
414*7ad269eaSRoger Chen }
415*7ad269eaSRoger Chen 
416*7ad269eaSRoger Chen static int rk_gmac_init(struct platform_device *pdev, void *priv)
417*7ad269eaSRoger Chen {
418*7ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
419*7ad269eaSRoger Chen 	int ret;
420*7ad269eaSRoger Chen 
421*7ad269eaSRoger Chen 	ret = phy_power_on(bsp_priv, true);
422*7ad269eaSRoger Chen 	if (ret)
423*7ad269eaSRoger Chen 		return ret;
424*7ad269eaSRoger Chen 
425*7ad269eaSRoger Chen 	ret = gmac_clk_enable(bsp_priv, true);
426*7ad269eaSRoger Chen 	if (ret)
427*7ad269eaSRoger Chen 		return ret;
428*7ad269eaSRoger Chen 
429*7ad269eaSRoger Chen 	return 0;
430*7ad269eaSRoger Chen }
431*7ad269eaSRoger Chen 
432*7ad269eaSRoger Chen static void rk_gmac_exit(struct platform_device *pdev, void *priv)
433*7ad269eaSRoger Chen {
434*7ad269eaSRoger Chen 	struct rk_priv_data *gmac = priv;
435*7ad269eaSRoger Chen 
436*7ad269eaSRoger Chen 	phy_power_on(gmac, false);
437*7ad269eaSRoger Chen 	gmac_clk_enable(gmac, false);
438*7ad269eaSRoger Chen }
439*7ad269eaSRoger Chen 
440*7ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed)
441*7ad269eaSRoger Chen {
442*7ad269eaSRoger Chen 	struct rk_priv_data *bsp_priv = priv;
443*7ad269eaSRoger Chen 	struct device *dev = &bsp_priv->pdev->dev;
444*7ad269eaSRoger Chen 
445*7ad269eaSRoger Chen 	if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII)
446*7ad269eaSRoger Chen 		set_rgmii_speed(bsp_priv, speed);
447*7ad269eaSRoger Chen 	else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
448*7ad269eaSRoger Chen 		set_rmii_speed(bsp_priv, speed);
449*7ad269eaSRoger Chen 	else
450*7ad269eaSRoger Chen 		dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
451*7ad269eaSRoger Chen }
452*7ad269eaSRoger Chen 
453*7ad269eaSRoger Chen const struct stmmac_of_data rk3288_gmac_data = {
454*7ad269eaSRoger Chen 	.has_gmac = 1,
455*7ad269eaSRoger Chen 	.fix_mac_speed = rk_fix_speed,
456*7ad269eaSRoger Chen 	.setup = rk_gmac_setup,
457*7ad269eaSRoger Chen 	.init = rk_gmac_init,
458*7ad269eaSRoger Chen 	.exit = rk_gmac_exit,
459*7ad269eaSRoger Chen };
460