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