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