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