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