xref: /openbmc/u-boot/drivers/net/gmac_rockchip.c (revision caf74617)
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 <asm/arch/grf_rv1108.h>
22 #include <dm/pinctrl.h>
23 #include <dt-bindings/clock/rk3288-cru.h>
24 #include "designware.h"
25 
26 DECLARE_GLOBAL_DATA_PTR;
27 
28 /*
29  * Platform data for the gmac
30  *
31  * dw_eth_pdata: Required platform data for designware driver (must be first)
32  */
33 struct gmac_rockchip_platdata {
34 	struct dw_eth_pdata dw_eth_pdata;
35 	bool clock_input;
36 	int tx_delay;
37 	int rx_delay;
38 };
39 
40 struct rk_gmac_ops {
41 	int (*fix_mac_speed)(struct dw_eth_dev *priv);
42 	void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata);
43 	void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
44 };
45 
46 
47 static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
48 {
49 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
50 	const char *string;
51 
52 	string = dev_read_string(dev, "clock_in_out");
53 	if (!strcmp(string, "input"))
54 		pdata->clock_input = true;
55 	else
56 		pdata->clock_input = false;
57 
58 	/* Check the new naming-style first... */
59 	pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT);
60 	pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT);
61 
62 	/* ... and fall back to the old naming style or default, if necessary */
63 	if (pdata->tx_delay == -ENOENT)
64 		pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30);
65 	if (pdata->rx_delay == -ENOENT)
66 		pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10);
67 
68 	return designware_eth_ofdata_to_platdata(dev);
69 }
70 
71 static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
72 {
73 	struct rk3288_grf *grf;
74 	int clk;
75 
76 	switch (priv->phydev->speed) {
77 	case 10:
78 		clk = RK3288_GMAC_CLK_SEL_2_5M;
79 		break;
80 	case 100:
81 		clk = RK3288_GMAC_CLK_SEL_25M;
82 		break;
83 	case 1000:
84 		clk = RK3288_GMAC_CLK_SEL_125M;
85 		break;
86 	default:
87 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
88 		return -EINVAL;
89 	}
90 
91 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
92 	rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
93 
94 	return 0;
95 }
96 
97 static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv)
98 {
99 	struct rk3368_grf *grf;
100 	int clk;
101 	enum {
102 		RK3368_GMAC_CLK_SEL_2_5M = 2 << 4,
103 		RK3368_GMAC_CLK_SEL_25M = 3 << 4,
104 		RK3368_GMAC_CLK_SEL_125M = 0 << 4,
105 		RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4),
106 	};
107 
108 	switch (priv->phydev->speed) {
109 	case 10:
110 		clk = RK3368_GMAC_CLK_SEL_2_5M;
111 		break;
112 	case 100:
113 		clk = RK3368_GMAC_CLK_SEL_25M;
114 		break;
115 	case 1000:
116 		clk = RK3368_GMAC_CLK_SEL_125M;
117 		break;
118 	default:
119 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
120 		return -EINVAL;
121 	}
122 
123 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
124 	rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk);
125 
126 	return 0;
127 }
128 
129 static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
130 {
131 	struct rk3399_grf_regs *grf;
132 	int clk;
133 
134 	switch (priv->phydev->speed) {
135 	case 10:
136 		clk = RK3399_GMAC_CLK_SEL_2_5M;
137 		break;
138 	case 100:
139 		clk = RK3399_GMAC_CLK_SEL_25M;
140 		break;
141 	case 1000:
142 		clk = RK3399_GMAC_CLK_SEL_125M;
143 		break;
144 	default:
145 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
146 		return -EINVAL;
147 	}
148 
149 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
150 	rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
151 
152 	return 0;
153 }
154 
155 static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
156 {
157 	struct rv1108_grf *grf;
158 	int clk, speed;
159 	enum {
160 		RV1108_GMAC_SPEED_MASK		= BIT(2),
161 		RV1108_GMAC_SPEED_10M		= 0 << 2,
162 		RV1108_GMAC_SPEED_100M		= 1 << 2,
163 		RV1108_GMAC_CLK_SEL_MASK	= BIT(7),
164 		RV1108_GMAC_CLK_SEL_2_5M	= 0 << 7,
165 		RV1108_GMAC_CLK_SEL_25M		= 1 << 7,
166 	};
167 
168 	switch (priv->phydev->speed) {
169 	case 10:
170 		clk = RV1108_GMAC_CLK_SEL_2_5M;
171 		speed = RV1108_GMAC_SPEED_10M;
172 		break;
173 	case 100:
174 		clk = RV1108_GMAC_CLK_SEL_25M;
175 		speed = RV1108_GMAC_SPEED_100M;
176 		break;
177 	default:
178 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
179 		return -EINVAL;
180 	}
181 
182 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
183 	rk_clrsetreg(&grf->gmac_con0,
184 		     RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK,
185 		     clk | speed);
186 
187 	return 0;
188 }
189 
190 static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
191 {
192 	struct rk3288_grf *grf;
193 
194 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
195 	rk_clrsetreg(&grf->soc_con1,
196 		     RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
197 		     RK3288_GMAC_PHY_INTF_SEL_RGMII);
198 
199 	rk_clrsetreg(&grf->soc_con3,
200 		     RK3288_RXCLK_DLY_ENA_GMAC_MASK |
201 		     RK3288_TXCLK_DLY_ENA_GMAC_MASK |
202 		     RK3288_CLK_RX_DL_CFG_GMAC_MASK |
203 		     RK3288_CLK_TX_DL_CFG_GMAC_MASK,
204 		     RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
205 		     RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
206 		     pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
207 		     pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
208 }
209 
210 static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
211 {
212 	struct rk3368_grf *grf;
213 	enum {
214 		RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9,
215 		RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9),
216 		RK3368_RMII_MODE_MASK  = BIT(6),
217 		RK3368_RMII_MODE       = BIT(6),
218 	};
219 	enum {
220 		RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15),
221 		RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
222 		RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15),
223 		RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7),
224 		RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
225 		RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7),
226 		RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
227 		RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8),
228 		RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
229 		RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0),
230 	};
231 
232 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
233 	rk_clrsetreg(&grf->soc_con15,
234 		     RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK,
235 		     RK3368_GMAC_PHY_INTF_SEL_RGMII);
236 
237 	rk_clrsetreg(&grf->soc_con16,
238 		     RK3368_RXCLK_DLY_ENA_GMAC_MASK |
239 		     RK3368_TXCLK_DLY_ENA_GMAC_MASK |
240 		     RK3368_CLK_RX_DL_CFG_GMAC_MASK |
241 		     RK3368_CLK_TX_DL_CFG_GMAC_MASK,
242 		     RK3368_RXCLK_DLY_ENA_GMAC_ENABLE |
243 		     RK3368_TXCLK_DLY_ENA_GMAC_ENABLE |
244 		     pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT |
245 		     pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT);
246 }
247 
248 static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
249 {
250 	struct rk3399_grf_regs *grf;
251 
252 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
253 
254 	rk_clrsetreg(&grf->soc_con5,
255 		     RK3399_GMAC_PHY_INTF_SEL_MASK,
256 		     RK3399_GMAC_PHY_INTF_SEL_RGMII);
257 
258 	rk_clrsetreg(&grf->soc_con6,
259 		     RK3399_RXCLK_DLY_ENA_GMAC_MASK |
260 		     RK3399_TXCLK_DLY_ENA_GMAC_MASK |
261 		     RK3399_CLK_RX_DL_CFG_GMAC_MASK |
262 		     RK3399_CLK_TX_DL_CFG_GMAC_MASK,
263 		     RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
264 		     RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
265 		     pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
266 		     pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
267 }
268 
269 static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
270 {
271 	struct rv1108_grf *grf;
272 
273 	enum {
274 		RV1108_GMAC_PHY_INTF_SEL_MASK  = GENMASK(6, 4),
275 		RV1108_GMAC_PHY_INTF_SEL_RMII  = 4 << 4,
276 	};
277 
278 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
279 	rk_clrsetreg(&grf->gmac_con0,
280 		     RV1108_GMAC_PHY_INTF_SEL_MASK,
281 		     RV1108_GMAC_PHY_INTF_SEL_RMII);
282 }
283 
284 static int gmac_rockchip_probe(struct udevice *dev)
285 {
286 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
287 	struct rk_gmac_ops *ops =
288 		(struct rk_gmac_ops *)dev_get_driver_data(dev);
289 	struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev);
290 	struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata;
291 	struct clk clk;
292 	ulong rate;
293 	int ret;
294 
295 	ret = clk_get_by_index(dev, 0, &clk);
296 	if (ret)
297 		return ret;
298 
299 	switch (eth_pdata->phy_interface) {
300 	case PHY_INTERFACE_MODE_RGMII:
301 		/*
302 		 * If the gmac clock is from internal pll, need to set and
303 		 * check the return value for gmac clock at RGMII mode. If
304 		 * the gmac clock is from external source, the clock rate
305 		 * is not set, because of it is bypassed.
306 		 */
307 		if (!pdata->clock_input) {
308 			rate = clk_set_rate(&clk, 125000000);
309 			if (rate != 125000000)
310 				return -EINVAL;
311 		}
312 
313 		/* Set to RGMII mode */
314 		if (ops->set_to_rgmii)
315 			ops->set_to_rgmii(pdata);
316 		else
317 			return -EPERM;
318 
319 		break;
320 	case PHY_INTERFACE_MODE_RMII:
321 		/* The commet is the same as RGMII mode */
322 		if (!pdata->clock_input) {
323 			rate = clk_set_rate(&clk, 50000000);
324 			if (rate != 50000000)
325 				return -EINVAL;
326 		}
327 
328 		/* Set to RMII mode */
329 		if (ops->set_to_rmii)
330 			ops->set_to_rmii(pdata);
331 		else
332 			return -EPERM;
333 
334 		break;
335 	default:
336 		debug("NO interface defined!\n");
337 		return -ENXIO;
338 	}
339 
340 	return designware_eth_probe(dev);
341 }
342 
343 static int gmac_rockchip_eth_start(struct udevice *dev)
344 {
345 	struct eth_pdata *pdata = dev_get_platdata(dev);
346 	struct dw_eth_dev *priv = dev_get_priv(dev);
347 	struct rk_gmac_ops *ops =
348 		(struct rk_gmac_ops *)dev_get_driver_data(dev);
349 	int ret;
350 
351 	ret = designware_eth_init(priv, pdata->enetaddr);
352 	if (ret)
353 		return ret;
354 	ret = ops->fix_mac_speed(priv);
355 	if (ret)
356 		return ret;
357 	ret = designware_eth_enable(priv);
358 	if (ret)
359 		return ret;
360 
361 	return 0;
362 }
363 
364 const struct eth_ops gmac_rockchip_eth_ops = {
365 	.start			= gmac_rockchip_eth_start,
366 	.send			= designware_eth_send,
367 	.recv			= designware_eth_recv,
368 	.free_pkt		= designware_eth_free_pkt,
369 	.stop			= designware_eth_stop,
370 	.write_hwaddr		= designware_eth_write_hwaddr,
371 };
372 
373 const struct rk_gmac_ops rk3288_gmac_ops = {
374 	.fix_mac_speed = rk3288_gmac_fix_mac_speed,
375 	.set_to_rgmii = rk3288_gmac_set_to_rgmii,
376 };
377 
378 const struct rk_gmac_ops rk3368_gmac_ops = {
379 	.fix_mac_speed = rk3368_gmac_fix_mac_speed,
380 	.set_to_rgmii = rk3368_gmac_set_to_rgmii,
381 };
382 
383 const struct rk_gmac_ops rk3399_gmac_ops = {
384 	.fix_mac_speed = rk3399_gmac_fix_mac_speed,
385 	.set_to_rgmii = rk3399_gmac_set_to_rgmii,
386 };
387 
388 const struct rk_gmac_ops rv1108_gmac_ops = {
389 	.fix_mac_speed = rv1108_set_rmii_speed,
390 	.set_to_rmii = rv1108_gmac_set_to_rmii,
391 };
392 
393 static const struct udevice_id rockchip_gmac_ids[] = {
394 	{ .compatible = "rockchip,rk3288-gmac",
395 	  .data = (ulong)&rk3288_gmac_ops },
396 	{ .compatible = "rockchip,rk3368-gmac",
397 	  .data = (ulong)&rk3368_gmac_ops },
398 	{ .compatible = "rockchip,rk3399-gmac",
399 	  .data = (ulong)&rk3399_gmac_ops },
400 	{ .compatible = "rockchip,rv1108-gmac",
401 	  .data = (ulong)&rv1108_gmac_ops },
402 	{ }
403 };
404 
405 U_BOOT_DRIVER(eth_gmac_rockchip) = {
406 	.name	= "gmac_rockchip",
407 	.id	= UCLASS_ETH,
408 	.of_match = rockchip_gmac_ids,
409 	.ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata,
410 	.probe	= gmac_rockchip_probe,
411 	.ops	= &gmac_rockchip_eth_ops,
412 	.priv_auto_alloc_size = sizeof(struct dw_eth_dev),
413 	.platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata),
414 	.flags = DM_FLAG_ALLOC_PRIV_DMA,
415 };
416