xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c (revision be709d48329a500621d2a05835283150ae137b45)
1 /*
2  * Synopsys DWC Ethernet Quality-of-Service v4.10a linux driver
3  *
4  * Copyright (C) 2016 Joao Pinto <jpinto@synopsys.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * You should have received a copy of the GNU General Public License
11  * along with this program. If not, see <http://www.gnu.org/licenses/>.
12  */
13 
14 #include <linux/clk.h>
15 #include <linux/clk-provider.h>
16 #include <linux/device.h>
17 #include <linux/gpio/consumer.h>
18 #include <linux/ethtool.h>
19 #include <linux/io.h>
20 #include <linux/iopoll.h>
21 #include <linux/ioport.h>
22 #include <linux/module.h>
23 #include <linux/of_device.h>
24 #include <linux/of_net.h>
25 #include <linux/mfd/syscon.h>
26 #include <linux/platform_device.h>
27 #include <linux/reset.h>
28 #include <linux/stmmac.h>
29 
30 #include "stmmac_platform.h"
31 #include "dwmac4.h"
32 
33 struct tegra_eqos {
34 	struct device *dev;
35 	void __iomem *regs;
36 
37 	struct reset_control *rst;
38 	struct clk *clk_master;
39 	struct clk *clk_slave;
40 	struct clk *clk_tx;
41 	struct clk *clk_rx;
42 
43 	struct gpio_desc *reset;
44 };
45 
46 static int dwc_eth_dwmac_config_dt(struct platform_device *pdev,
47 				   struct plat_stmmacenet_data *plat_dat)
48 {
49 	struct device_node *np = pdev->dev.of_node;
50 	u32 burst_map = 0;
51 	u32 bit_index = 0;
52 	u32 a_index = 0;
53 
54 	if (!plat_dat->axi) {
55 		plat_dat->axi = kzalloc(sizeof(struct stmmac_axi), GFP_KERNEL);
56 
57 		if (!plat_dat->axi)
58 			return -ENOMEM;
59 	}
60 
61 	plat_dat->axi->axi_lpi_en = of_property_read_bool(np, "snps,en-lpi");
62 	if (of_property_read_u32(np, "snps,write-requests",
63 				 &plat_dat->axi->axi_wr_osr_lmt)) {
64 		/**
65 		 * Since the register has a reset value of 1, if property
66 		 * is missing, default to 1.
67 		 */
68 		plat_dat->axi->axi_wr_osr_lmt = 1;
69 	} else {
70 		/**
71 		 * If property exists, to keep the behavior from dwc_eth_qos,
72 		 * subtract one after parsing.
73 		 */
74 		plat_dat->axi->axi_wr_osr_lmt--;
75 	}
76 
77 	if (of_property_read_u32(np, "snps,read-requests",
78 				 &plat_dat->axi->axi_rd_osr_lmt)) {
79 		/**
80 		 * Since the register has a reset value of 1, if property
81 		 * is missing, default to 1.
82 		 */
83 		plat_dat->axi->axi_rd_osr_lmt = 1;
84 	} else {
85 		/**
86 		 * If property exists, to keep the behavior from dwc_eth_qos,
87 		 * subtract one after parsing.
88 		 */
89 		plat_dat->axi->axi_rd_osr_lmt--;
90 	}
91 	of_property_read_u32(np, "snps,burst-map", &burst_map);
92 
93 	/* converts burst-map bitmask to burst array */
94 	for (bit_index = 0; bit_index < 7; bit_index++) {
95 		if (burst_map & (1 << bit_index)) {
96 			switch (bit_index) {
97 			case 0:
98 			plat_dat->axi->axi_blen[a_index] = 4; break;
99 			case 1:
100 			plat_dat->axi->axi_blen[a_index] = 8; break;
101 			case 2:
102 			plat_dat->axi->axi_blen[a_index] = 16; break;
103 			case 3:
104 			plat_dat->axi->axi_blen[a_index] = 32; break;
105 			case 4:
106 			plat_dat->axi->axi_blen[a_index] = 64; break;
107 			case 5:
108 			plat_dat->axi->axi_blen[a_index] = 128; break;
109 			case 6:
110 			plat_dat->axi->axi_blen[a_index] = 256; break;
111 			default:
112 			break;
113 			}
114 			a_index++;
115 		}
116 	}
117 
118 	/* dwc-qos needs GMAC4, AAL, TSO and PMT */
119 	plat_dat->has_gmac4 = 1;
120 	plat_dat->dma_cfg->aal = 1;
121 	plat_dat->tso_en = 1;
122 	plat_dat->pmt = 1;
123 
124 	return 0;
125 }
126 
127 static void *dwc_qos_probe(struct platform_device *pdev,
128 			   struct plat_stmmacenet_data *plat_dat,
129 			   struct stmmac_resources *stmmac_res)
130 {
131 	int err;
132 
133 	plat_dat->stmmac_clk = devm_clk_get(&pdev->dev, "apb_pclk");
134 	if (IS_ERR(plat_dat->stmmac_clk)) {
135 		dev_err(&pdev->dev, "apb_pclk clock not found.\n");
136 		return ERR_CAST(plat_dat->stmmac_clk);
137 	}
138 
139 	err = clk_prepare_enable(plat_dat->stmmac_clk);
140 	if (err < 0) {
141 		dev_err(&pdev->dev, "failed to enable apb_pclk clock: %d\n",
142 			err);
143 		return ERR_PTR(err);
144 	}
145 
146 	plat_dat->pclk = devm_clk_get(&pdev->dev, "phy_ref_clk");
147 	if (IS_ERR(plat_dat->pclk)) {
148 		dev_err(&pdev->dev, "phy_ref_clk clock not found.\n");
149 		err = PTR_ERR(plat_dat->pclk);
150 		goto disable;
151 	}
152 
153 	err = clk_prepare_enable(plat_dat->pclk);
154 	if (err < 0) {
155 		dev_err(&pdev->dev, "failed to enable phy_ref clock: %d\n",
156 			err);
157 		goto disable;
158 	}
159 
160 	return NULL;
161 
162 disable:
163 	clk_disable_unprepare(plat_dat->stmmac_clk);
164 	return ERR_PTR(err);
165 }
166 
167 static int dwc_qos_remove(struct platform_device *pdev)
168 {
169 	struct net_device *ndev = platform_get_drvdata(pdev);
170 	struct stmmac_priv *priv = netdev_priv(ndev);
171 
172 	clk_disable_unprepare(priv->plat->pclk);
173 	clk_disable_unprepare(priv->plat->stmmac_clk);
174 
175 	return 0;
176 }
177 
178 #define SDMEMCOMPPADCTRL 0x8800
179 #define  SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD BIT(31)
180 
181 #define AUTO_CAL_CONFIG 0x8804
182 #define  AUTO_CAL_CONFIG_START BIT(31)
183 #define  AUTO_CAL_CONFIG_ENABLE BIT(29)
184 
185 #define AUTO_CAL_STATUS 0x880c
186 #define  AUTO_CAL_STATUS_ACTIVE BIT(31)
187 
188 static void tegra_eqos_fix_speed(void *priv, unsigned int speed)
189 {
190 	struct tegra_eqos *eqos = priv;
191 	unsigned long rate = 125000000;
192 	bool needs_calibration = false;
193 	u32 value;
194 	int err;
195 
196 	switch (speed) {
197 	case SPEED_1000:
198 		needs_calibration = true;
199 		rate = 125000000;
200 		break;
201 
202 	case SPEED_100:
203 		needs_calibration = true;
204 		rate = 25000000;
205 		break;
206 
207 	case SPEED_10:
208 		rate = 2500000;
209 		break;
210 
211 	default:
212 		dev_err(eqos->dev, "invalid speed %u\n", speed);
213 		break;
214 	}
215 
216 	if (needs_calibration) {
217 		/* calibrate */
218 		value = readl(eqos->regs + SDMEMCOMPPADCTRL);
219 		value |= SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD;
220 		writel(value, eqos->regs + SDMEMCOMPPADCTRL);
221 
222 		udelay(1);
223 
224 		value = readl(eqos->regs + AUTO_CAL_CONFIG);
225 		value |= AUTO_CAL_CONFIG_START | AUTO_CAL_CONFIG_ENABLE;
226 		writel(value, eqos->regs + AUTO_CAL_CONFIG);
227 
228 		err = readl_poll_timeout_atomic(eqos->regs + AUTO_CAL_STATUS,
229 						value,
230 						value & AUTO_CAL_STATUS_ACTIVE,
231 						1, 10);
232 		if (err < 0) {
233 			dev_err(eqos->dev, "calibration did not start\n");
234 			goto failed;
235 		}
236 
237 		err = readl_poll_timeout_atomic(eqos->regs + AUTO_CAL_STATUS,
238 						value,
239 						(value & AUTO_CAL_STATUS_ACTIVE) == 0,
240 						20, 200);
241 		if (err < 0) {
242 			dev_err(eqos->dev, "calibration didn't finish\n");
243 			goto failed;
244 		}
245 
246 	failed:
247 		value = readl(eqos->regs + SDMEMCOMPPADCTRL);
248 		value &= ~SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD;
249 		writel(value, eqos->regs + SDMEMCOMPPADCTRL);
250 	} else {
251 		value = readl(eqos->regs + AUTO_CAL_CONFIG);
252 		value &= ~AUTO_CAL_CONFIG_ENABLE;
253 		writel(value, eqos->regs + AUTO_CAL_CONFIG);
254 	}
255 
256 	err = clk_set_rate(eqos->clk_tx, rate);
257 	if (err < 0)
258 		dev_err(eqos->dev, "failed to set TX rate: %d\n", err);
259 }
260 
261 static int tegra_eqos_init(struct platform_device *pdev, void *priv)
262 {
263 	struct tegra_eqos *eqos = priv;
264 	unsigned long rate;
265 	u32 value;
266 
267 	rate = clk_get_rate(eqos->clk_slave);
268 
269 	value = (rate / 1000000) - 1;
270 	writel(value, eqos->regs + GMAC_1US_TIC_COUNTER);
271 
272 	return 0;
273 }
274 
275 static void *tegra_eqos_probe(struct platform_device *pdev,
276 			      struct plat_stmmacenet_data *data,
277 			      struct stmmac_resources *res)
278 {
279 	struct tegra_eqos *eqos;
280 	int err;
281 
282 	eqos = devm_kzalloc(&pdev->dev, sizeof(*eqos), GFP_KERNEL);
283 	if (!eqos) {
284 		err = -ENOMEM;
285 		goto error;
286 	}
287 
288 	eqos->dev = &pdev->dev;
289 	eqos->regs = res->addr;
290 
291 	eqos->clk_master = devm_clk_get(&pdev->dev, "master_bus");
292 	if (IS_ERR(eqos->clk_master)) {
293 		err = PTR_ERR(eqos->clk_master);
294 		goto error;
295 	}
296 
297 	err = clk_prepare_enable(eqos->clk_master);
298 	if (err < 0)
299 		goto error;
300 
301 	eqos->clk_slave = devm_clk_get(&pdev->dev, "slave_bus");
302 	if (IS_ERR(eqos->clk_slave)) {
303 		err = PTR_ERR(eqos->clk_slave);
304 		goto disable_master;
305 	}
306 
307 	data->stmmac_clk = eqos->clk_slave;
308 
309 	err = clk_prepare_enable(eqos->clk_slave);
310 	if (err < 0)
311 		goto disable_master;
312 
313 	eqos->clk_rx = devm_clk_get(&pdev->dev, "rx");
314 	if (IS_ERR(eqos->clk_rx)) {
315 		err = PTR_ERR(eqos->clk_rx);
316 		goto disable_slave;
317 	}
318 
319 	err = clk_prepare_enable(eqos->clk_rx);
320 	if (err < 0)
321 		goto disable_slave;
322 
323 	eqos->clk_tx = devm_clk_get(&pdev->dev, "tx");
324 	if (IS_ERR(eqos->clk_tx)) {
325 		err = PTR_ERR(eqos->clk_tx);
326 		goto disable_rx;
327 	}
328 
329 	err = clk_prepare_enable(eqos->clk_tx);
330 	if (err < 0)
331 		goto disable_rx;
332 
333 	eqos->reset = devm_gpiod_get(&pdev->dev, "phy-reset", GPIOD_OUT_HIGH);
334 	if (IS_ERR(eqos->reset)) {
335 		err = PTR_ERR(eqos->reset);
336 		goto disable_tx;
337 	}
338 
339 	usleep_range(2000, 4000);
340 	gpiod_set_value(eqos->reset, 0);
341 
342 	eqos->rst = devm_reset_control_get(&pdev->dev, "eqos");
343 	if (IS_ERR(eqos->rst)) {
344 		err = PTR_ERR(eqos->rst);
345 		goto reset_phy;
346 	}
347 
348 	err = reset_control_assert(eqos->rst);
349 	if (err < 0)
350 		goto reset_phy;
351 
352 	usleep_range(2000, 4000);
353 
354 	err = reset_control_deassert(eqos->rst);
355 	if (err < 0)
356 		goto reset_phy;
357 
358 	usleep_range(2000, 4000);
359 
360 	data->fix_mac_speed = tegra_eqos_fix_speed;
361 	data->init = tegra_eqos_init;
362 	data->bsp_priv = eqos;
363 
364 	err = tegra_eqos_init(pdev, eqos);
365 	if (err < 0)
366 		goto reset;
367 
368 out:
369 	return eqos;
370 
371 reset:
372 	reset_control_assert(eqos->rst);
373 reset_phy:
374 	gpiod_set_value(eqos->reset, 1);
375 disable_tx:
376 	clk_disable_unprepare(eqos->clk_tx);
377 disable_rx:
378 	clk_disable_unprepare(eqos->clk_rx);
379 disable_slave:
380 	clk_disable_unprepare(eqos->clk_slave);
381 disable_master:
382 	clk_disable_unprepare(eqos->clk_master);
383 error:
384 	eqos = ERR_PTR(err);
385 	goto out;
386 }
387 
388 static int tegra_eqos_remove(struct platform_device *pdev)
389 {
390 	struct tegra_eqos *eqos = get_stmmac_bsp_priv(&pdev->dev);
391 
392 	reset_control_assert(eqos->rst);
393 	gpiod_set_value(eqos->reset, 1);
394 	clk_disable_unprepare(eqos->clk_tx);
395 	clk_disable_unprepare(eqos->clk_rx);
396 	clk_disable_unprepare(eqos->clk_slave);
397 	clk_disable_unprepare(eqos->clk_master);
398 
399 	return 0;
400 }
401 
402 struct dwc_eth_dwmac_data {
403 	void *(*probe)(struct platform_device *pdev,
404 		       struct plat_stmmacenet_data *data,
405 		       struct stmmac_resources *res);
406 	int (*remove)(struct platform_device *pdev);
407 };
408 
409 static const struct dwc_eth_dwmac_data dwc_qos_data = {
410 	.probe = dwc_qos_probe,
411 	.remove = dwc_qos_remove,
412 };
413 
414 static const struct dwc_eth_dwmac_data tegra_eqos_data = {
415 	.probe = tegra_eqos_probe,
416 	.remove = tegra_eqos_remove,
417 };
418 
419 static int dwc_eth_dwmac_probe(struct platform_device *pdev)
420 {
421 	const struct dwc_eth_dwmac_data *data;
422 	struct plat_stmmacenet_data *plat_dat;
423 	struct stmmac_resources stmmac_res;
424 	struct resource *res;
425 	void *priv;
426 	int ret;
427 
428 	data = of_device_get_match_data(&pdev->dev);
429 
430 	memset(&stmmac_res, 0, sizeof(struct stmmac_resources));
431 
432 	/**
433 	 * Since stmmac_platform supports name IRQ only, basic platform
434 	 * resource initialization is done in the glue logic.
435 	 */
436 	stmmac_res.irq = platform_get_irq(pdev, 0);
437 	if (stmmac_res.irq < 0) {
438 		if (stmmac_res.irq != -EPROBE_DEFER)
439 			dev_err(&pdev->dev,
440 				"IRQ configuration information not found\n");
441 
442 		return stmmac_res.irq;
443 	}
444 	stmmac_res.wol_irq = stmmac_res.irq;
445 
446 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
447 	stmmac_res.addr = devm_ioremap_resource(&pdev->dev, res);
448 	if (IS_ERR(stmmac_res.addr))
449 		return PTR_ERR(stmmac_res.addr);
450 
451 	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
452 	if (IS_ERR(plat_dat))
453 		return PTR_ERR(plat_dat);
454 
455 	priv = data->probe(pdev, plat_dat, &stmmac_res);
456 	if (IS_ERR(priv)) {
457 		ret = PTR_ERR(priv);
458 		dev_err(&pdev->dev, "failed to probe subdriver: %d\n", ret);
459 		goto remove_config;
460 	}
461 
462 	ret = dwc_eth_dwmac_config_dt(pdev, plat_dat);
463 	if (ret)
464 		goto remove;
465 
466 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
467 	if (ret)
468 		goto remove;
469 
470 	return ret;
471 
472 remove:
473 	data->remove(pdev);
474 remove_config:
475 	stmmac_remove_config_dt(pdev, plat_dat);
476 
477 	return ret;
478 }
479 
480 static int dwc_eth_dwmac_remove(struct platform_device *pdev)
481 {
482 	struct net_device *ndev = platform_get_drvdata(pdev);
483 	struct stmmac_priv *priv = netdev_priv(ndev);
484 	const struct dwc_eth_dwmac_data *data;
485 	int err;
486 
487 	data = of_device_get_match_data(&pdev->dev);
488 
489 	err = stmmac_dvr_remove(&pdev->dev);
490 	if (err < 0)
491 		dev_err(&pdev->dev, "failed to remove platform: %d\n", err);
492 
493 	err = data->remove(pdev);
494 	if (err < 0)
495 		dev_err(&pdev->dev, "failed to remove subdriver: %d\n", err);
496 
497 	stmmac_remove_config_dt(pdev, priv->plat);
498 
499 	return err;
500 }
501 
502 static const struct of_device_id dwc_eth_dwmac_match[] = {
503 	{ .compatible = "snps,dwc-qos-ethernet-4.10", .data = &dwc_qos_data },
504 	{ .compatible = "nvidia,tegra186-eqos", .data = &tegra_eqos_data },
505 	{ }
506 };
507 MODULE_DEVICE_TABLE(of, dwc_eth_dwmac_match);
508 
509 static struct platform_driver dwc_eth_dwmac_driver = {
510 	.probe  = dwc_eth_dwmac_probe,
511 	.remove = dwc_eth_dwmac_remove,
512 	.driver = {
513 		.name           = "dwc-eth-dwmac",
514 		.pm             = &stmmac_pltfr_pm_ops,
515 		.of_match_table = dwc_eth_dwmac_match,
516 	},
517 };
518 module_platform_driver(dwc_eth_dwmac_driver);
519 
520 MODULE_AUTHOR("Joao Pinto <jpinto@synopsys.com>");
521 MODULE_DESCRIPTION("Synopsys DWC Ethernet Quality-of-Service v4.10a driver");
522 MODULE_LICENSE("GPL v2");
523