xref: /rk3399_rockchip-uboot/drivers/net/gmac_rockchip.c (revision 5821df21ae36d9ef252d346a5abb76be773c5d69)
1 /*
2  * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  *
6  * Rockchip GMAC ethernet IP driver for U-Boot
7  */
8 
9 #include <common.h>
10 #include <dm.h>
11 #include <clk.h>
12 #include <phy.h>
13 #include <syscon.h>
14 #include <asm/io.h>
15 #include <asm/arch/periph.h>
16 #include <asm/arch/clock.h>
17 #include <asm/arch/hardware.h>
18 #include <asm/arch/grf_rk3288.h>
19 #include <asm/arch/grf_rk3368.h>
20 #include <asm/arch/grf_rk3399.h>
21 #include <dm/pinctrl.h>
22 #include <dt-bindings/clock/rk3288-cru.h>
23 #include "designware.h"
24 
25 DECLARE_GLOBAL_DATA_PTR;
26 
27 /*
28  * Platform data for the gmac
29  *
30  * dw_eth_pdata: Required platform data for designware driver (must be first)
31  */
32 struct gmac_rockchip_platdata {
33 	struct dw_eth_pdata dw_eth_pdata;
34 	int tx_delay;
35 	int rx_delay;
36 };
37 
38 struct rk_gmac_ops {
39 	int (*fix_mac_speed)(struct dw_eth_dev *priv);
40 	void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
41 };
42 
43 void gmac_set_rgmii(struct udevice *dev, u32 tx_delay, u32 rx_delay)
44 {
45 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
46 	struct rk_gmac_ops *ops =
47 		(struct rk_gmac_ops *)dev_get_driver_data(dev);
48 
49 	pdata->tx_delay = tx_delay;
50 	pdata->rx_delay = rx_delay;
51 
52 	ops->set_to_rgmii(pdata);
53 }
54 
55 static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
56 {
57 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
58 
59 	/* Check the new naming-style first... */
60 	pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
61 	pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
62 
63 	/* ... and fall back to the old naming style or default, if necessary */
64 	if (pdata->tx_delay == -ENOENT)
65 		pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
66 	if (pdata->rx_delay == -ENOENT)
67 		pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
68 
69 	return designware_eth_ofdata_to_platdata(dev);
70 }
71 
72 static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
73 {
74 	struct rk3288_grf *grf;
75 	int clk;
76 
77 	switch (priv->phydev->speed) {
78 	case 10:
79 		clk = RK3288_GMAC_CLK_SEL_2_5M;
80 		break;
81 	case 100:
82 		clk = RK3288_GMAC_CLK_SEL_25M;
83 		break;
84 	case 1000:
85 		clk = RK3288_GMAC_CLK_SEL_125M;
86 		break;
87 	default:
88 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
89 		return -EINVAL;
90 	}
91 
92 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
93 	rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
94 
95 	return 0;
96 }
97 
98 static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
99 {
100 	struct rk3368_grf *grf;
101 	int clk;
102 	enum {
103 		RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
104 		RK3368_GMAC_CLK_SEL_25M = 3 << 4,
105 		RK3368_GMAC_CLK_SEL_125M = 0 << 4,
106 		RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
107 	};
108 
109 	switch (priv->phydev->speed) {
110 	case 10:
111 		clk = RK3368_GMAC_CLK_SEL_2_5M;
112 		break;
113 	case 100:
114 		clk = RK3368_GMAC_CLK_SEL_25M;
115 		break;
116 	case 1000:
117 		clk = RK3368_GMAC_CLK_SEL_125M;
118 		break;
119 	default:
120 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
121 		return -EINVAL;
122 	}
123 
124 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
125 	rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
126 
127 	return 0;
128 }
129 
130 static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
131 {
132 	struct rk3399_grf_regs *grf;
133 	int clk;
134 
135 	switch (priv->phydev->speed) {
136 	case 10:
137 		clk = RK3399_GMAC_CLK_SEL_2_5M;
138 		break;
139 	case 100:
140 		clk = RK3399_GMAC_CLK_SEL_25M;
141 		break;
142 	case 1000:
143 		clk = RK3399_GMAC_CLK_SEL_125M;
144 		break;
145 	default:
146 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
147 		return -EINVAL;
148 	}
149 
150 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
151 	rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
152 
153 	return 0;
154 }
155 
156 static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
157 {
158 	struct rk3288_grf *grf;
159 
160 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
161 	rk_clrsetreg(&grf->soc_con1,
162 		     RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
163 		     RK3288_GMAC_PHY_INTF_SEL_RGMII);
164 
165 	rk_clrsetreg(&grf->soc_con3,
166 		     RK3288_RXCLK_DLY_ENA_GMAC_MASK |
167 		     RK3288_TXCLK_DLY_ENA_GMAC_MASK |
168 		     RK3288_CLK_RX_DL_CFG_GMAC_MASK |
169 		     RK3288_CLK_TX_DL_CFG_GMAC_MASK,
170 		     RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
171 		     RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
172 		     pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
173 		     pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
174 }
175 
176 static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
177 {
178 	struct rk3368_grf *grf;
179 	enum {
180 		RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
181 		RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
182 		RK3368_RMII_MODE_MASK  = BIT(6),
183 		RK3368_RMII_MODE       = BIT(6),
184 	};
185 	enum {
186 		RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
187 		RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
188 		RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
189 		RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
190 		RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
191 		RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
192 		RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
193 		RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
194 		RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
195 		RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
196 	};
197 
198 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
199 	rk_clrsetreg(&grf->soc_con15,
200 		     RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
201 		     RK3368_GMAC_PHY_INTF_SEL_RGMII);
202 
203 	rk_clrsetreg(&grf->soc_con16,
204 		     RK3368_RXCLK_DLY_ENA_GMAC_MASK |
205 		     RK3368_TXCLK_DLY_ENA_GMAC_MASK |
206 		     RK3368_CLK_RX_DL_CFG_GMAC_MASK |
207 		     RK3368_CLK_TX_DL_CFG_GMAC_MASK,
208 		     RK3368_RXCLK_DLY_ENA_GMAC_ENABLE |
209 		     RK3368_TXCLK_DLY_ENA_GMAC_ENABLE |
210 		     pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
211 		     pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
212 }
213 
214 static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
215 {
216 	struct rk3399_grf_regs *grf;
217 
218 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
219 
220 	rk_clrsetreg(&grf->soc_con5,
221 		     RK3399_GMAC_PHY_INTF_SEL_MASK,
222 		     RK3399_GMAC_PHY_INTF_SEL_RGMII);
223 
224 	rk_clrsetreg(&grf->soc_con6,
225 		     RK3399_RXCLK_DLY_ENA_GMAC_MASK |
226 		     RK3399_TXCLK_DLY_ENA_GMAC_MASK |
227 		     RK3399_CLK_RX_DL_CFG_GMAC_MASK |
228 		     RK3399_CLK_TX_DL_CFG_GMAC_MASK,
229 		     RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
230 		     RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
231 		     pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
232 		     pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
233 }
234 
235 static int gmac_rockchip_probe(struct udevice *dev)
236 {
237 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
238 	struct rk_gmac_ops *ops =
239 		(struct rk_gmac_ops *)dev_get_driver_data(dev);
240 	struct clk clk;
241 	int ret;
242 
243 	ret = clk_get_by_index(dev, 0, &clk);
244 	if (ret)
245 		return ret;
246 
247 	/* Since mac_clk is fed by an external clock we can use 0 here */
248 	ret = clk_set_rate(&clk, 0);
249 	if (ret)
250 		return ret;
251 
252 	/* Set to RGMII mode */
253 	ops->set_to_rgmii(pdata);
254 
255 	return designware_eth_probe(dev);
256 }
257 
258 static int gmac_rockchip_eth_start(struct udevice *dev)
259 {
260 	struct eth_pdata *pdata = dev_get_platdata(dev);
261 	struct dw_eth_dev *priv = dev_get_priv(dev);
262 	struct rk_gmac_ops *ops =
263 		(struct rk_gmac_ops *)dev_get_driver_data(dev);
264 	int ret;
265 
266 	ret = designware_eth_init(priv, pdata->enetaddr);
267 	if (ret)
268 		return ret;
269 	ret = ops->fix_mac_speed(priv);
270 	if (ret)
271 		return ret;
272 	ret = designware_eth_enable(priv);
273 	if (ret)
274 		return ret;
275 
276 	return 0;
277 }
278 
279 const struct eth_ops gmac_rockchip_eth_ops = {
280 	.start			= gmac_rockchip_eth_start,
281 	.send			= designware_eth_send,
282 	.recv			= designware_eth_recv,
283 	.free_pkt		= designware_eth_free_pkt,
284 	.stop			= designware_eth_stop,
285 	.write_hwaddr		= designware_eth_write_hwaddr,
286 };
287 
288 const struct rk_gmac_ops rk3288_gmac_ops = {
289 	.fix_mac_speed = rk3288_gmac_fix_mac_speed,
290 	.set_to_rgmii = rk3288_gmac_set_to_rgmii,
291 };
292 
293 const struct rk_gmac_ops rk3368_gmac_ops = {
294 	.fix_mac_speed = rk3368_gmac_fix_mac_speed,
295 	.set_to_rgmii = rk3368_gmac_set_to_rgmii,
296 };
297 
298 const struct rk_gmac_ops rk3399_gmac_ops = {
299 	.fix_mac_speed = rk3399_gmac_fix_mac_speed,
300 	.set_to_rgmii = rk3399_gmac_set_to_rgmii,
301 };
302 
303 static const struct udevice_id rockchip_gmac_ids[] = {
304 	{ .compatible = "rockchip,rk3288-gmac",
305 	  .data = (ulong)&rk3288_gmac_ops },
306 	{ .compatible = "rockchip,rk3368-gmac",
307 	  .data = (ulong)&rk3368_gmac_ops },
308 	{ .compatible = "rockchip,rk3399-gmac",
309 	  .data = (ulong)&rk3399_gmac_ops },
310 	{ }
311 };
312 
313 U_BOOT_DRIVER(eth_gmac_rockchip) = {
314 	.name	= "gmac_rockchip",
315 	.id	= UCLASS_ETH,
316 	.of_match = rockchip_gmac_ids,
317 	.ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
318 	.probe	= gmac_rockchip_probe,
319 	.ops	= &gmac_rockchip_eth_ops,
320 	.priv_auto_alloc_size = sizeof(struct dw_eth_dev),
321 	.platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
322 	.flags = DM_FLAG_ALLOC_PRIV_DMA,
323 };
324