1 // SPDX-License-Identifier: GPL-2.0-only
3 * Synopsys DWC Ethernet Quality-of-Service v4.10a linux driver
5 * Copyright (C) 2016 Joao Pinto <jpinto@synopsys.com>
9 #include <linux/clk-provider.h>
10 #include <linux/device.h>
11 #include <linux/gpio/consumer.h>
12 #include <linux/ethtool.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>
24 #include "stmmac_platform.h"
31 struct reset_control
*rst
;
32 struct clk
*clk_master
;
33 struct clk
*clk_slave
;
37 struct gpio_desc
*reset
;
40 static int dwc_eth_dwmac_config_dt(struct platform_device
*pdev
,
41 struct plat_stmmacenet_data
*plat_dat
)
43 struct device
*dev
= &pdev
->dev
;
49 plat_dat
->axi
= kzalloc(sizeof(struct stmmac_axi
), GFP_KERNEL
);
55 plat_dat
->axi
->axi_lpi_en
= device_property_read_bool(dev
,
57 if (device_property_read_u32(dev
, "snps,write-requests",
58 &plat_dat
->axi
->axi_wr_osr_lmt
)) {
60 * Since the register has a reset value of 1, if property
61 * is missing, default to 1.
63 plat_dat
->axi
->axi_wr_osr_lmt
= 1;
66 * If property exists, to keep the behavior from dwc_eth_qos,
67 * subtract one after parsing.
69 plat_dat
->axi
->axi_wr_osr_lmt
--;
72 if (device_property_read_u32(dev
, "snps,read-requests",
73 &plat_dat
->axi
->axi_rd_osr_lmt
)) {
75 * Since the register has a reset value of 1, if property
76 * is missing, default to 1.
78 plat_dat
->axi
->axi_rd_osr_lmt
= 1;
81 * If property exists, to keep the behavior from dwc_eth_qos,
82 * subtract one after parsing.
84 plat_dat
->axi
->axi_rd_osr_lmt
--;
86 device_property_read_u32(dev
, "snps,burst-map", &burst_map
);
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
)) {
93 plat_dat
->axi
->axi_blen
[a_index
] = 4; break;
95 plat_dat
->axi
->axi_blen
[a_index
] = 8; break;
97 plat_dat
->axi
->axi_blen
[a_index
] = 16; break;
99 plat_dat
->axi
->axi_blen
[a_index
] = 32; break;
101 plat_dat
->axi
->axi_blen
[a_index
] = 64; break;
103 plat_dat
->axi
->axi_blen
[a_index
] = 128; break;
105 plat_dat
->axi
->axi_blen
[a_index
] = 256; break;
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
->tso_en
= 1;
122 static void *dwc_qos_probe(struct platform_device
*pdev
,
123 struct plat_stmmacenet_data
*plat_dat
,
124 struct stmmac_resources
*stmmac_res
)
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 ERR_CAST(plat_dat
->stmmac_clk
);
134 err
= clk_prepare_enable(plat_dat
->stmmac_clk
);
136 dev_err(&pdev
->dev
, "failed to enable apb_pclk clock: %d\n",
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
);
148 err
= clk_prepare_enable(plat_dat
->pclk
);
150 dev_err(&pdev
->dev
, "failed to enable phy_ref clock: %d\n",
158 clk_disable_unprepare(plat_dat
->stmmac_clk
);
162 static int dwc_qos_remove(struct platform_device
*pdev
)
164 struct net_device
*ndev
= platform_get_drvdata(pdev
);
165 struct stmmac_priv
*priv
= netdev_priv(ndev
);
167 clk_disable_unprepare(priv
->plat
->pclk
);
168 clk_disable_unprepare(priv
->plat
->stmmac_clk
);
173 #define SDMEMCOMPPADCTRL 0x8800
174 #define SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD BIT(31)
176 #define AUTO_CAL_CONFIG 0x8804
177 #define AUTO_CAL_CONFIG_START BIT(31)
178 #define AUTO_CAL_CONFIG_ENABLE BIT(29)
180 #define AUTO_CAL_STATUS 0x880c
181 #define AUTO_CAL_STATUS_ACTIVE BIT(31)
183 static void tegra_eqos_fix_speed(void *priv
, unsigned int speed
)
185 struct tegra_eqos
*eqos
= priv
;
186 unsigned long rate
= 125000000;
187 bool needs_calibration
= false;
193 needs_calibration
= true;
198 needs_calibration
= true;
207 dev_err(eqos
->dev
, "invalid speed %u\n", speed
);
211 if (needs_calibration
) {
213 value
= readl(eqos
->regs
+ SDMEMCOMPPADCTRL
);
214 value
|= SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD
;
215 writel(value
, eqos
->regs
+ SDMEMCOMPPADCTRL
);
219 value
= readl(eqos
->regs
+ AUTO_CAL_CONFIG
);
220 value
|= AUTO_CAL_CONFIG_START
| AUTO_CAL_CONFIG_ENABLE
;
221 writel(value
, eqos
->regs
+ AUTO_CAL_CONFIG
);
223 err
= readl_poll_timeout_atomic(eqos
->regs
+ AUTO_CAL_STATUS
,
225 value
& AUTO_CAL_STATUS_ACTIVE
,
228 dev_err(eqos
->dev
, "calibration did not start\n");
232 err
= readl_poll_timeout_atomic(eqos
->regs
+ AUTO_CAL_STATUS
,
234 (value
& AUTO_CAL_STATUS_ACTIVE
) == 0,
237 dev_err(eqos
->dev
, "calibration didn't finish\n");
242 value
= readl(eqos
->regs
+ SDMEMCOMPPADCTRL
);
243 value
&= ~SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD
;
244 writel(value
, eqos
->regs
+ SDMEMCOMPPADCTRL
);
246 value
= readl(eqos
->regs
+ AUTO_CAL_CONFIG
);
247 value
&= ~AUTO_CAL_CONFIG_ENABLE
;
248 writel(value
, eqos
->regs
+ AUTO_CAL_CONFIG
);
251 err
= clk_set_rate(eqos
->clk_tx
, rate
);
253 dev_err(eqos
->dev
, "failed to set TX rate: %d\n", err
);
256 static int tegra_eqos_init(struct platform_device
*pdev
, void *priv
)
258 struct tegra_eqos
*eqos
= priv
;
262 rate
= clk_get_rate(eqos
->clk_slave
);
264 value
= (rate
/ 1000000) - 1;
265 writel(value
, eqos
->regs
+ GMAC_1US_TIC_COUNTER
);
270 static void *tegra_eqos_probe(struct platform_device
*pdev
,
271 struct plat_stmmacenet_data
*data
,
272 struct stmmac_resources
*res
)
274 struct device
*dev
= &pdev
->dev
;
275 struct tegra_eqos
*eqos
;
278 eqos
= devm_kzalloc(&pdev
->dev
, sizeof(*eqos
), GFP_KERNEL
);
284 eqos
->dev
= &pdev
->dev
;
285 eqos
->regs
= res
->addr
;
287 if (!is_of_node(dev
->fwnode
))
288 goto bypass_clk_reset_gpio
;
290 eqos
->clk_master
= devm_clk_get(&pdev
->dev
, "master_bus");
291 if (IS_ERR(eqos
->clk_master
)) {
292 err
= PTR_ERR(eqos
->clk_master
);
296 err
= clk_prepare_enable(eqos
->clk_master
);
300 eqos
->clk_slave
= devm_clk_get(&pdev
->dev
, "slave_bus");
301 if (IS_ERR(eqos
->clk_slave
)) {
302 err
= PTR_ERR(eqos
->clk_slave
);
306 data
->stmmac_clk
= eqos
->clk_slave
;
308 err
= clk_prepare_enable(eqos
->clk_slave
);
312 eqos
->clk_rx
= devm_clk_get(&pdev
->dev
, "rx");
313 if (IS_ERR(eqos
->clk_rx
)) {
314 err
= PTR_ERR(eqos
->clk_rx
);
318 err
= clk_prepare_enable(eqos
->clk_rx
);
322 eqos
->clk_tx
= devm_clk_get(&pdev
->dev
, "tx");
323 if (IS_ERR(eqos
->clk_tx
)) {
324 err
= PTR_ERR(eqos
->clk_tx
);
328 err
= clk_prepare_enable(eqos
->clk_tx
);
332 eqos
->reset
= devm_gpiod_get(&pdev
->dev
, "phy-reset", GPIOD_OUT_HIGH
);
333 if (IS_ERR(eqos
->reset
)) {
334 err
= PTR_ERR(eqos
->reset
);
338 usleep_range(2000, 4000);
339 gpiod_set_value(eqos
->reset
, 0);
341 /* MDIO bus was already reset just above */
342 data
->mdio_bus_data
->needs_reset
= false;
344 eqos
->rst
= devm_reset_control_get(&pdev
->dev
, "eqos");
345 if (IS_ERR(eqos
->rst
)) {
346 err
= PTR_ERR(eqos
->rst
);
350 err
= reset_control_assert(eqos
->rst
);
354 usleep_range(2000, 4000);
356 err
= reset_control_deassert(eqos
->rst
);
360 usleep_range(2000, 4000);
362 bypass_clk_reset_gpio
:
363 data
->fix_mac_speed
= tegra_eqos_fix_speed
;
364 data
->init
= tegra_eqos_init
;
365 data
->bsp_priv
= eqos
;
367 err
= tegra_eqos_init(pdev
, eqos
);
375 reset_control_assert(eqos
->rst
);
377 gpiod_set_value(eqos
->reset
, 1);
379 clk_disable_unprepare(eqos
->clk_tx
);
381 clk_disable_unprepare(eqos
->clk_rx
);
383 clk_disable_unprepare(eqos
->clk_slave
);
385 clk_disable_unprepare(eqos
->clk_master
);
391 static int tegra_eqos_remove(struct platform_device
*pdev
)
393 struct tegra_eqos
*eqos
= get_stmmac_bsp_priv(&pdev
->dev
);
395 reset_control_assert(eqos
->rst
);
396 gpiod_set_value(eqos
->reset
, 1);
397 clk_disable_unprepare(eqos
->clk_tx
);
398 clk_disable_unprepare(eqos
->clk_rx
);
399 clk_disable_unprepare(eqos
->clk_slave
);
400 clk_disable_unprepare(eqos
->clk_master
);
405 struct dwc_eth_dwmac_data
{
406 void *(*probe
)(struct platform_device
*pdev
,
407 struct plat_stmmacenet_data
*data
,
408 struct stmmac_resources
*res
);
409 int (*remove
)(struct platform_device
*pdev
);
412 static const struct dwc_eth_dwmac_data dwc_qos_data
= {
413 .probe
= dwc_qos_probe
,
414 .remove
= dwc_qos_remove
,
417 static const struct dwc_eth_dwmac_data tegra_eqos_data
= {
418 .probe
= tegra_eqos_probe
,
419 .remove
= tegra_eqos_remove
,
422 static int dwc_eth_dwmac_probe(struct platform_device
*pdev
)
424 const struct dwc_eth_dwmac_data
*data
;
425 struct plat_stmmacenet_data
*plat_dat
;
426 struct stmmac_resources stmmac_res
;
430 data
= device_get_match_data(&pdev
->dev
);
432 memset(&stmmac_res
, 0, sizeof(struct stmmac_resources
));
435 * Since stmmac_platform supports name IRQ only, basic platform
436 * resource initialization is done in the glue logic.
438 stmmac_res
.irq
= platform_get_irq(pdev
, 0);
439 if (stmmac_res
.irq
< 0)
440 return stmmac_res
.irq
;
441 stmmac_res
.wol_irq
= stmmac_res
.irq
;
443 stmmac_res
.addr
= devm_platform_ioremap_resource(pdev
, 0);
444 if (IS_ERR(stmmac_res
.addr
))
445 return PTR_ERR(stmmac_res
.addr
);
447 plat_dat
= stmmac_probe_config_dt(pdev
, &stmmac_res
.mac
);
448 if (IS_ERR(plat_dat
))
449 return PTR_ERR(plat_dat
);
451 priv
= data
->probe(pdev
, plat_dat
, &stmmac_res
);
455 if (ret
!= -EPROBE_DEFER
)
456 dev_err(&pdev
->dev
, "failed to probe subdriver: %d\n",
462 ret
= dwc_eth_dwmac_config_dt(pdev
, plat_dat
);
466 ret
= stmmac_dvr_probe(&pdev
->dev
, plat_dat
, &stmmac_res
);
475 stmmac_remove_config_dt(pdev
, plat_dat
);
480 static int dwc_eth_dwmac_remove(struct platform_device
*pdev
)
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
;
487 data
= device_get_match_data(&pdev
->dev
);
489 err
= stmmac_dvr_remove(&pdev
->dev
);
491 dev_err(&pdev
->dev
, "failed to remove platform: %d\n", err
);
493 err
= data
->remove(pdev
);
495 dev_err(&pdev
->dev
, "failed to remove subdriver: %d\n", err
);
497 stmmac_remove_config_dt(pdev
, priv
->plat
);
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
},
507 MODULE_DEVICE_TABLE(of
, dwc_eth_dwmac_match
);
509 static struct platform_driver dwc_eth_dwmac_driver
= {
510 .probe
= dwc_eth_dwmac_probe
,
511 .remove
= dwc_eth_dwmac_remove
,
513 .name
= "dwc-eth-dwmac",
514 .pm
= &stmmac_pltfr_pm_ops
,
515 .of_match_table
= dwc_eth_dwmac_match
,
518 module_platform_driver(dwc_eth_dwmac_driver
);
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");