2 * Synopsys DWC Ethernet Quality-of-Service v4.10a linux driver
4 * Copyright (C) 2016 Joao Pinto <jpinto@synopsys.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * You should have received a copy of the GNU General Public License
11 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #include <linux/clk.h>
15 #include <linux/clk-provider.h>
16 #include <linux/device.h>
17 #include <linux/gpio/consumer.h>
18 #include <linux/ethtool.h>
20 #include <linux/iopoll.h>
21 #include <linux/ioport.h>
22 #include <linux/module.h>
23 #include <linux/of_device.h>
24 #include <linux/of_net.h>
25 #include <linux/mfd/syscon.h>
26 #include <linux/platform_device.h>
27 #include <linux/reset.h>
28 #include <linux/stmmac.h>
30 #include "stmmac_platform.h"
37 struct reset_control
*rst
;
38 struct clk
*clk_master
;
39 struct clk
*clk_slave
;
43 struct gpio_desc
*reset
;
46 static int dwc_eth_dwmac_config_dt(struct platform_device
*pdev
,
47 struct plat_stmmacenet_data
*plat_dat
)
49 struct device_node
*np
= pdev
->dev
.of_node
;
55 plat_dat
->axi
= kzalloc(sizeof(struct stmmac_axi
), GFP_KERNEL
);
61 plat_dat
->axi
->axi_lpi_en
= of_property_read_bool(np
, "snps,en-lpi");
62 if (of_property_read_u32(np
, "snps,write-requests",
63 &plat_dat
->axi
->axi_wr_osr_lmt
)) {
65 * Since the register has a reset value of 1, if property
66 * is missing, default to 1.
68 plat_dat
->axi
->axi_wr_osr_lmt
= 1;
71 * If property exists, to keep the behavior from dwc_eth_qos,
72 * subtract one after parsing.
74 plat_dat
->axi
->axi_wr_osr_lmt
--;
77 if (of_property_read_u32(np
, "snps,read-requests",
78 &plat_dat
->axi
->axi_rd_osr_lmt
)) {
80 * Since the register has a reset value of 1, if property
81 * is missing, default to 1.
83 plat_dat
->axi
->axi_rd_osr_lmt
= 1;
86 * If property exists, to keep the behavior from dwc_eth_qos,
87 * subtract one after parsing.
89 plat_dat
->axi
->axi_rd_osr_lmt
--;
91 of_property_read_u32(np
, "snps,burst-map", &burst_map
);
93 /* converts burst-map bitmask to burst array */
94 for (bit_index
= 0; bit_index
< 7; bit_index
++) {
95 if (burst_map
& (1 << bit_index
)) {
98 plat_dat
->axi
->axi_blen
[a_index
] = 4; break;
100 plat_dat
->axi
->axi_blen
[a_index
] = 8; break;
102 plat_dat
->axi
->axi_blen
[a_index
] = 16; break;
104 plat_dat
->axi
->axi_blen
[a_index
] = 32; break;
106 plat_dat
->axi
->axi_blen
[a_index
] = 64; break;
108 plat_dat
->axi
->axi_blen
[a_index
] = 128; break;
110 plat_dat
->axi
->axi_blen
[a_index
] = 256; break;
118 /* dwc-qos needs GMAC4, AAL, TSO and PMT */
119 plat_dat
->has_gmac4
= 1;
120 plat_dat
->dma_cfg
->aal
= 1;
121 plat_dat
->tso_en
= 1;
127 static void *dwc_qos_probe(struct platform_device
*pdev
,
128 struct plat_stmmacenet_data
*plat_dat
,
129 struct stmmac_resources
*stmmac_res
)
133 plat_dat
->stmmac_clk
= devm_clk_get(&pdev
->dev
, "apb_pclk");
134 if (IS_ERR(plat_dat
->stmmac_clk
)) {
135 dev_err(&pdev
->dev
, "apb_pclk clock not found.\n");
136 return ERR_CAST(plat_dat
->stmmac_clk
);
139 err
= clk_prepare_enable(plat_dat
->stmmac_clk
);
141 dev_err(&pdev
->dev
, "failed to enable apb_pclk clock: %d\n",
146 plat_dat
->pclk
= devm_clk_get(&pdev
->dev
, "phy_ref_clk");
147 if (IS_ERR(plat_dat
->pclk
)) {
148 dev_err(&pdev
->dev
, "phy_ref_clk clock not found.\n");
149 err
= PTR_ERR(plat_dat
->pclk
);
153 err
= clk_prepare_enable(plat_dat
->pclk
);
155 dev_err(&pdev
->dev
, "failed to enable phy_ref clock: %d\n",
163 clk_disable_unprepare(plat_dat
->stmmac_clk
);
167 static int dwc_qos_remove(struct platform_device
*pdev
)
169 struct net_device
*ndev
= platform_get_drvdata(pdev
);
170 struct stmmac_priv
*priv
= netdev_priv(ndev
);
172 clk_disable_unprepare(priv
->plat
->pclk
);
173 clk_disable_unprepare(priv
->plat
->stmmac_clk
);
178 #define SDMEMCOMPPADCTRL 0x8800
179 #define SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD BIT(31)
181 #define AUTO_CAL_CONFIG 0x8804
182 #define AUTO_CAL_CONFIG_START BIT(31)
183 #define AUTO_CAL_CONFIG_ENABLE BIT(29)
185 #define AUTO_CAL_STATUS 0x880c
186 #define AUTO_CAL_STATUS_ACTIVE BIT(31)
188 static void tegra_eqos_fix_speed(void *priv
, unsigned int speed
)
190 struct tegra_eqos
*eqos
= priv
;
191 unsigned long rate
= 125000000;
192 bool needs_calibration
= false;
198 needs_calibration
= true;
203 needs_calibration
= true;
212 dev_err(eqos
->dev
, "invalid speed %u\n", speed
);
216 if (needs_calibration
) {
218 value
= readl(eqos
->regs
+ SDMEMCOMPPADCTRL
);
219 value
|= SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD
;
220 writel(value
, eqos
->regs
+ SDMEMCOMPPADCTRL
);
224 value
= readl(eqos
->regs
+ AUTO_CAL_CONFIG
);
225 value
|= AUTO_CAL_CONFIG_START
| AUTO_CAL_CONFIG_ENABLE
;
226 writel(value
, eqos
->regs
+ AUTO_CAL_CONFIG
);
228 err
= readl_poll_timeout_atomic(eqos
->regs
+ AUTO_CAL_STATUS
,
230 value
& AUTO_CAL_STATUS_ACTIVE
,
233 dev_err(eqos
->dev
, "calibration did not start\n");
237 err
= readl_poll_timeout_atomic(eqos
->regs
+ AUTO_CAL_STATUS
,
239 (value
& AUTO_CAL_STATUS_ACTIVE
) == 0,
242 dev_err(eqos
->dev
, "calibration didn't finish\n");
247 value
= readl(eqos
->regs
+ SDMEMCOMPPADCTRL
);
248 value
&= ~SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD
;
249 writel(value
, eqos
->regs
+ SDMEMCOMPPADCTRL
);
251 value
= readl(eqos
->regs
+ AUTO_CAL_CONFIG
);
252 value
&= ~AUTO_CAL_CONFIG_ENABLE
;
253 writel(value
, eqos
->regs
+ AUTO_CAL_CONFIG
);
256 err
= clk_set_rate(eqos
->clk_tx
, rate
);
258 dev_err(eqos
->dev
, "failed to set TX rate: %d\n", err
);
261 static int tegra_eqos_init(struct platform_device
*pdev
, void *priv
)
263 struct tegra_eqos
*eqos
= priv
;
267 rate
= clk_get_rate(eqos
->clk_slave
);
269 value
= (rate
/ 1000000) - 1;
270 writel(value
, eqos
->regs
+ GMAC_1US_TIC_COUNTER
);
275 static void *tegra_eqos_probe(struct platform_device
*pdev
,
276 struct plat_stmmacenet_data
*data
,
277 struct stmmac_resources
*res
)
279 struct tegra_eqos
*eqos
;
282 eqos
= devm_kzalloc(&pdev
->dev
, sizeof(*eqos
), GFP_KERNEL
);
288 eqos
->dev
= &pdev
->dev
;
289 eqos
->regs
= res
->addr
;
291 eqos
->clk_master
= devm_clk_get(&pdev
->dev
, "master_bus");
292 if (IS_ERR(eqos
->clk_master
)) {
293 err
= PTR_ERR(eqos
->clk_master
);
297 err
= clk_prepare_enable(eqos
->clk_master
);
301 eqos
->clk_slave
= devm_clk_get(&pdev
->dev
, "slave_bus");
302 if (IS_ERR(eqos
->clk_slave
)) {
303 err
= PTR_ERR(eqos
->clk_slave
);
307 data
->stmmac_clk
= eqos
->clk_slave
;
309 err
= clk_prepare_enable(eqos
->clk_slave
);
313 eqos
->clk_rx
= devm_clk_get(&pdev
->dev
, "rx");
314 if (IS_ERR(eqos
->clk_rx
)) {
315 err
= PTR_ERR(eqos
->clk_rx
);
319 err
= clk_prepare_enable(eqos
->clk_rx
);
323 eqos
->clk_tx
= devm_clk_get(&pdev
->dev
, "tx");
324 if (IS_ERR(eqos
->clk_tx
)) {
325 err
= PTR_ERR(eqos
->clk_tx
);
329 err
= clk_prepare_enable(eqos
->clk_tx
);
333 eqos
->reset
= devm_gpiod_get(&pdev
->dev
, "phy-reset", GPIOD_OUT_HIGH
);
334 if (IS_ERR(eqos
->reset
)) {
335 err
= PTR_ERR(eqos
->reset
);
339 usleep_range(2000, 4000);
340 gpiod_set_value(eqos
->reset
, 0);
342 eqos
->rst
= devm_reset_control_get(&pdev
->dev
, "eqos");
343 if (IS_ERR(eqos
->rst
)) {
344 err
= PTR_ERR(eqos
->rst
);
348 err
= reset_control_assert(eqos
->rst
);
352 usleep_range(2000, 4000);
354 err
= reset_control_deassert(eqos
->rst
);
358 usleep_range(2000, 4000);
360 data
->fix_mac_speed
= tegra_eqos_fix_speed
;
361 data
->init
= tegra_eqos_init
;
362 data
->bsp_priv
= eqos
;
364 err
= tegra_eqos_init(pdev
, eqos
);
372 reset_control_assert(eqos
->rst
);
374 gpiod_set_value(eqos
->reset
, 1);
376 clk_disable_unprepare(eqos
->clk_tx
);
378 clk_disable_unprepare(eqos
->clk_rx
);
380 clk_disable_unprepare(eqos
->clk_slave
);
382 clk_disable_unprepare(eqos
->clk_master
);
388 static int tegra_eqos_remove(struct platform_device
*pdev
)
390 struct tegra_eqos
*eqos
= get_stmmac_bsp_priv(&pdev
->dev
);
392 reset_control_assert(eqos
->rst
);
393 gpiod_set_value(eqos
->reset
, 1);
394 clk_disable_unprepare(eqos
->clk_tx
);
395 clk_disable_unprepare(eqos
->clk_rx
);
396 clk_disable_unprepare(eqos
->clk_slave
);
397 clk_disable_unprepare(eqos
->clk_master
);
402 struct dwc_eth_dwmac_data
{
403 void *(*probe
)(struct platform_device
*pdev
,
404 struct plat_stmmacenet_data
*data
,
405 struct stmmac_resources
*res
);
406 int (*remove
)(struct platform_device
*pdev
);
409 static const struct dwc_eth_dwmac_data dwc_qos_data
= {
410 .probe
= dwc_qos_probe
,
411 .remove
= dwc_qos_remove
,
414 static const struct dwc_eth_dwmac_data tegra_eqos_data
= {
415 .probe
= tegra_eqos_probe
,
416 .remove
= tegra_eqos_remove
,
419 static int dwc_eth_dwmac_probe(struct platform_device
*pdev
)
421 const struct dwc_eth_dwmac_data
*data
;
422 struct plat_stmmacenet_data
*plat_dat
;
423 struct stmmac_resources stmmac_res
;
424 struct resource
*res
;
428 data
= of_device_get_match_data(&pdev
->dev
);
430 memset(&stmmac_res
, 0, sizeof(struct stmmac_resources
));
433 * Since stmmac_platform supports name IRQ only, basic platform
434 * resource initialization is done in the glue logic.
436 stmmac_res
.irq
= platform_get_irq(pdev
, 0);
437 if (stmmac_res
.irq
< 0) {
438 if (stmmac_res
.irq
!= -EPROBE_DEFER
)
440 "IRQ configuration information not found\n");
442 return stmmac_res
.irq
;
444 stmmac_res
.wol_irq
= stmmac_res
.irq
;
446 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
447 stmmac_res
.addr
= devm_ioremap_resource(&pdev
->dev
, res
);
448 if (IS_ERR(stmmac_res
.addr
))
449 return PTR_ERR(stmmac_res
.addr
);
451 plat_dat
= stmmac_probe_config_dt(pdev
, &stmmac_res
.mac
);
452 if (IS_ERR(plat_dat
))
453 return PTR_ERR(plat_dat
);
455 priv
= data
->probe(pdev
, plat_dat
, &stmmac_res
);
458 dev_err(&pdev
->dev
, "failed to probe subdriver: %d\n", ret
);
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
= of_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");