0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/clk.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/device.h>
0011 #include <linux/gpio/consumer.h>
0012 #include <linux/ethtool.h>
0013 #include <linux/io.h>
0014 #include <linux/iopoll.h>
0015 #include <linux/ioport.h>
0016 #include <linux/module.h>
0017 #include <linux/of_device.h>
0018 #include <linux/of_net.h>
0019 #include <linux/mfd/syscon.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/reset.h>
0022 #include <linux/stmmac.h>
0023
0024 #include "stmmac_platform.h"
0025 #include "dwmac4.h"
0026
0027 struct tegra_eqos {
0028 struct device *dev;
0029 void __iomem *regs;
0030
0031 struct reset_control *rst;
0032 struct clk *clk_master;
0033 struct clk *clk_slave;
0034 struct clk *clk_tx;
0035 struct clk *clk_rx;
0036
0037 struct gpio_desc *reset;
0038 };
0039
0040 static int dwc_eth_dwmac_config_dt(struct platform_device *pdev,
0041 struct plat_stmmacenet_data *plat_dat)
0042 {
0043 struct device *dev = &pdev->dev;
0044 u32 burst_map = 0;
0045 u32 bit_index = 0;
0046 u32 a_index = 0;
0047
0048 if (!plat_dat->axi) {
0049 plat_dat->axi = kzalloc(sizeof(struct stmmac_axi), GFP_KERNEL);
0050
0051 if (!plat_dat->axi)
0052 return -ENOMEM;
0053 }
0054
0055 plat_dat->axi->axi_lpi_en = device_property_read_bool(dev,
0056 "snps,en-lpi");
0057 if (device_property_read_u32(dev, "snps,write-requests",
0058 &plat_dat->axi->axi_wr_osr_lmt)) {
0059
0060
0061
0062
0063 plat_dat->axi->axi_wr_osr_lmt = 1;
0064 } else {
0065
0066
0067
0068
0069 plat_dat->axi->axi_wr_osr_lmt--;
0070 }
0071
0072 if (device_property_read_u32(dev, "snps,read-requests",
0073 &plat_dat->axi->axi_rd_osr_lmt)) {
0074
0075
0076
0077
0078 plat_dat->axi->axi_rd_osr_lmt = 1;
0079 } else {
0080
0081
0082
0083
0084 plat_dat->axi->axi_rd_osr_lmt--;
0085 }
0086 device_property_read_u32(dev, "snps,burst-map", &burst_map);
0087
0088
0089 for (bit_index = 0; bit_index < 7; bit_index++) {
0090 if (burst_map & (1 << bit_index)) {
0091 switch (bit_index) {
0092 case 0:
0093 plat_dat->axi->axi_blen[a_index] = 4; break;
0094 case 1:
0095 plat_dat->axi->axi_blen[a_index] = 8; break;
0096 case 2:
0097 plat_dat->axi->axi_blen[a_index] = 16; break;
0098 case 3:
0099 plat_dat->axi->axi_blen[a_index] = 32; break;
0100 case 4:
0101 plat_dat->axi->axi_blen[a_index] = 64; break;
0102 case 5:
0103 plat_dat->axi->axi_blen[a_index] = 128; break;
0104 case 6:
0105 plat_dat->axi->axi_blen[a_index] = 256; break;
0106 default:
0107 break;
0108 }
0109 a_index++;
0110 }
0111 }
0112
0113
0114 plat_dat->has_gmac4 = 1;
0115 plat_dat->dma_cfg->aal = 1;
0116 plat_dat->tso_en = 1;
0117 plat_dat->pmt = 1;
0118
0119 return 0;
0120 }
0121
0122 static int dwc_qos_probe(struct platform_device *pdev,
0123 struct plat_stmmacenet_data *plat_dat,
0124 struct stmmac_resources *stmmac_res)
0125 {
0126 int err;
0127
0128 plat_dat->stmmac_clk = devm_clk_get(&pdev->dev, "apb_pclk");
0129 if (IS_ERR(plat_dat->stmmac_clk)) {
0130 dev_err(&pdev->dev, "apb_pclk clock not found.\n");
0131 return PTR_ERR(plat_dat->stmmac_clk);
0132 }
0133
0134 err = clk_prepare_enable(plat_dat->stmmac_clk);
0135 if (err < 0) {
0136 dev_err(&pdev->dev, "failed to enable apb_pclk clock: %d\n",
0137 err);
0138 return err;
0139 }
0140
0141 plat_dat->pclk = devm_clk_get(&pdev->dev, "phy_ref_clk");
0142 if (IS_ERR(plat_dat->pclk)) {
0143 dev_err(&pdev->dev, "phy_ref_clk clock not found.\n");
0144 err = PTR_ERR(plat_dat->pclk);
0145 goto disable;
0146 }
0147
0148 err = clk_prepare_enable(plat_dat->pclk);
0149 if (err < 0) {
0150 dev_err(&pdev->dev, "failed to enable phy_ref clock: %d\n",
0151 err);
0152 goto disable;
0153 }
0154
0155 return 0;
0156
0157 disable:
0158 clk_disable_unprepare(plat_dat->stmmac_clk);
0159 return err;
0160 }
0161
0162 static int dwc_qos_remove(struct platform_device *pdev)
0163 {
0164 struct net_device *ndev = platform_get_drvdata(pdev);
0165 struct stmmac_priv *priv = netdev_priv(ndev);
0166
0167 clk_disable_unprepare(priv->plat->pclk);
0168 clk_disable_unprepare(priv->plat->stmmac_clk);
0169
0170 return 0;
0171 }
0172
0173 #define SDMEMCOMPPADCTRL 0x8800
0174 #define SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD BIT(31)
0175
0176 #define AUTO_CAL_CONFIG 0x8804
0177 #define AUTO_CAL_CONFIG_START BIT(31)
0178 #define AUTO_CAL_CONFIG_ENABLE BIT(29)
0179
0180 #define AUTO_CAL_STATUS 0x880c
0181 #define AUTO_CAL_STATUS_ACTIVE BIT(31)
0182
0183 static void tegra_eqos_fix_speed(void *priv, unsigned int speed)
0184 {
0185 struct tegra_eqos *eqos = priv;
0186 unsigned long rate = 125000000;
0187 bool needs_calibration = false;
0188 u32 value;
0189 int err;
0190
0191 switch (speed) {
0192 case SPEED_1000:
0193 needs_calibration = true;
0194 rate = 125000000;
0195 break;
0196
0197 case SPEED_100:
0198 needs_calibration = true;
0199 rate = 25000000;
0200 break;
0201
0202 case SPEED_10:
0203 rate = 2500000;
0204 break;
0205
0206 default:
0207 dev_err(eqos->dev, "invalid speed %u\n", speed);
0208 break;
0209 }
0210
0211 if (needs_calibration) {
0212
0213 value = readl(eqos->regs + SDMEMCOMPPADCTRL);
0214 value |= SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD;
0215 writel(value, eqos->regs + SDMEMCOMPPADCTRL);
0216
0217 udelay(1);
0218
0219 value = readl(eqos->regs + AUTO_CAL_CONFIG);
0220 value |= AUTO_CAL_CONFIG_START | AUTO_CAL_CONFIG_ENABLE;
0221 writel(value, eqos->regs + AUTO_CAL_CONFIG);
0222
0223 err = readl_poll_timeout_atomic(eqos->regs + AUTO_CAL_STATUS,
0224 value,
0225 value & AUTO_CAL_STATUS_ACTIVE,
0226 1, 10);
0227 if (err < 0) {
0228 dev_err(eqos->dev, "calibration did not start\n");
0229 goto failed;
0230 }
0231
0232 err = readl_poll_timeout_atomic(eqos->regs + AUTO_CAL_STATUS,
0233 value,
0234 (value & AUTO_CAL_STATUS_ACTIVE) == 0,
0235 20, 200);
0236 if (err < 0) {
0237 dev_err(eqos->dev, "calibration didn't finish\n");
0238 goto failed;
0239 }
0240
0241 failed:
0242 value = readl(eqos->regs + SDMEMCOMPPADCTRL);
0243 value &= ~SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD;
0244 writel(value, eqos->regs + SDMEMCOMPPADCTRL);
0245 } else {
0246 value = readl(eqos->regs + AUTO_CAL_CONFIG);
0247 value &= ~AUTO_CAL_CONFIG_ENABLE;
0248 writel(value, eqos->regs + AUTO_CAL_CONFIG);
0249 }
0250
0251 err = clk_set_rate(eqos->clk_tx, rate);
0252 if (err < 0)
0253 dev_err(eqos->dev, "failed to set TX rate: %d\n", err);
0254 }
0255
0256 static int tegra_eqos_init(struct platform_device *pdev, void *priv)
0257 {
0258 struct tegra_eqos *eqos = priv;
0259 unsigned long rate;
0260 u32 value;
0261
0262 rate = clk_get_rate(eqos->clk_slave);
0263
0264 value = (rate / 1000000) - 1;
0265 writel(value, eqos->regs + GMAC_1US_TIC_COUNTER);
0266
0267 return 0;
0268 }
0269
0270 static int tegra_eqos_probe(struct platform_device *pdev,
0271 struct plat_stmmacenet_data *data,
0272 struct stmmac_resources *res)
0273 {
0274 struct device *dev = &pdev->dev;
0275 struct tegra_eqos *eqos;
0276 int err;
0277
0278 eqos = devm_kzalloc(&pdev->dev, sizeof(*eqos), GFP_KERNEL);
0279 if (!eqos)
0280 return -ENOMEM;
0281
0282 eqos->dev = &pdev->dev;
0283 eqos->regs = res->addr;
0284
0285 if (!is_of_node(dev->fwnode))
0286 goto bypass_clk_reset_gpio;
0287
0288 eqos->clk_master = devm_clk_get(&pdev->dev, "master_bus");
0289 if (IS_ERR(eqos->clk_master)) {
0290 err = PTR_ERR(eqos->clk_master);
0291 goto error;
0292 }
0293
0294 err = clk_prepare_enable(eqos->clk_master);
0295 if (err < 0)
0296 goto error;
0297
0298 eqos->clk_slave = devm_clk_get(&pdev->dev, "slave_bus");
0299 if (IS_ERR(eqos->clk_slave)) {
0300 err = PTR_ERR(eqos->clk_slave);
0301 goto disable_master;
0302 }
0303
0304 data->stmmac_clk = eqos->clk_slave;
0305
0306 err = clk_prepare_enable(eqos->clk_slave);
0307 if (err < 0)
0308 goto disable_master;
0309
0310 eqos->clk_rx = devm_clk_get(&pdev->dev, "rx");
0311 if (IS_ERR(eqos->clk_rx)) {
0312 err = PTR_ERR(eqos->clk_rx);
0313 goto disable_slave;
0314 }
0315
0316 err = clk_prepare_enable(eqos->clk_rx);
0317 if (err < 0)
0318 goto disable_slave;
0319
0320 eqos->clk_tx = devm_clk_get(&pdev->dev, "tx");
0321 if (IS_ERR(eqos->clk_tx)) {
0322 err = PTR_ERR(eqos->clk_tx);
0323 goto disable_rx;
0324 }
0325
0326 err = clk_prepare_enable(eqos->clk_tx);
0327 if (err < 0)
0328 goto disable_rx;
0329
0330 eqos->reset = devm_gpiod_get(&pdev->dev, "phy-reset", GPIOD_OUT_HIGH);
0331 if (IS_ERR(eqos->reset)) {
0332 err = PTR_ERR(eqos->reset);
0333 goto disable_tx;
0334 }
0335
0336 usleep_range(2000, 4000);
0337 gpiod_set_value(eqos->reset, 0);
0338
0339
0340 data->mdio_bus_data->needs_reset = false;
0341
0342 eqos->rst = devm_reset_control_get(&pdev->dev, "eqos");
0343 if (IS_ERR(eqos->rst)) {
0344 err = PTR_ERR(eqos->rst);
0345 goto reset_phy;
0346 }
0347
0348 err = reset_control_assert(eqos->rst);
0349 if (err < 0)
0350 goto reset_phy;
0351
0352 usleep_range(2000, 4000);
0353
0354 err = reset_control_deassert(eqos->rst);
0355 if (err < 0)
0356 goto reset_phy;
0357
0358 usleep_range(2000, 4000);
0359
0360 bypass_clk_reset_gpio:
0361 data->fix_mac_speed = tegra_eqos_fix_speed;
0362 data->init = tegra_eqos_init;
0363 data->bsp_priv = eqos;
0364 data->sph_disable = 1;
0365
0366 err = tegra_eqos_init(pdev, eqos);
0367 if (err < 0)
0368 goto reset;
0369
0370 return 0;
0371 reset:
0372 reset_control_assert(eqos->rst);
0373 reset_phy:
0374 gpiod_set_value(eqos->reset, 1);
0375 disable_tx:
0376 clk_disable_unprepare(eqos->clk_tx);
0377 disable_rx:
0378 clk_disable_unprepare(eqos->clk_rx);
0379 disable_slave:
0380 clk_disable_unprepare(eqos->clk_slave);
0381 disable_master:
0382 clk_disable_unprepare(eqos->clk_master);
0383 error:
0384 return err;
0385 }
0386
0387 static int tegra_eqos_remove(struct platform_device *pdev)
0388 {
0389 struct tegra_eqos *eqos = get_stmmac_bsp_priv(&pdev->dev);
0390
0391 reset_control_assert(eqos->rst);
0392 gpiod_set_value(eqos->reset, 1);
0393 clk_disable_unprepare(eqos->clk_tx);
0394 clk_disable_unprepare(eqos->clk_rx);
0395 clk_disable_unprepare(eqos->clk_slave);
0396 clk_disable_unprepare(eqos->clk_master);
0397
0398 return 0;
0399 }
0400
0401 struct dwc_eth_dwmac_data {
0402 int (*probe)(struct platform_device *pdev,
0403 struct plat_stmmacenet_data *data,
0404 struct stmmac_resources *res);
0405 int (*remove)(struct platform_device *pdev);
0406 };
0407
0408 static const struct dwc_eth_dwmac_data dwc_qos_data = {
0409 .probe = dwc_qos_probe,
0410 .remove = dwc_qos_remove,
0411 };
0412
0413 static const struct dwc_eth_dwmac_data tegra_eqos_data = {
0414 .probe = tegra_eqos_probe,
0415 .remove = tegra_eqos_remove,
0416 };
0417
0418 static int dwc_eth_dwmac_probe(struct platform_device *pdev)
0419 {
0420 const struct dwc_eth_dwmac_data *data;
0421 struct plat_stmmacenet_data *plat_dat;
0422 struct stmmac_resources stmmac_res;
0423 int ret;
0424
0425 data = device_get_match_data(&pdev->dev);
0426
0427 memset(&stmmac_res, 0, sizeof(struct stmmac_resources));
0428
0429
0430
0431
0432
0433 stmmac_res.irq = platform_get_irq(pdev, 0);
0434 if (stmmac_res.irq < 0)
0435 return stmmac_res.irq;
0436 stmmac_res.wol_irq = stmmac_res.irq;
0437
0438 stmmac_res.addr = devm_platform_ioremap_resource(pdev, 0);
0439 if (IS_ERR(stmmac_res.addr))
0440 return PTR_ERR(stmmac_res.addr);
0441
0442 plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
0443 if (IS_ERR(plat_dat))
0444 return PTR_ERR(plat_dat);
0445
0446 ret = data->probe(pdev, plat_dat, &stmmac_res);
0447 if (ret < 0) {
0448 if (ret != -EPROBE_DEFER)
0449 dev_err(&pdev->dev, "failed to probe subdriver: %d\n",
0450 ret);
0451
0452 goto remove_config;
0453 }
0454
0455 ret = dwc_eth_dwmac_config_dt(pdev, plat_dat);
0456 if (ret)
0457 goto remove;
0458
0459 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
0460 if (ret)
0461 goto remove;
0462
0463 return ret;
0464
0465 remove:
0466 data->remove(pdev);
0467 remove_config:
0468 stmmac_remove_config_dt(pdev, plat_dat);
0469
0470 return ret;
0471 }
0472
0473 static int dwc_eth_dwmac_remove(struct platform_device *pdev)
0474 {
0475 struct net_device *ndev = platform_get_drvdata(pdev);
0476 struct stmmac_priv *priv = netdev_priv(ndev);
0477 const struct dwc_eth_dwmac_data *data;
0478 int err;
0479
0480 data = device_get_match_data(&pdev->dev);
0481
0482 err = stmmac_dvr_remove(&pdev->dev);
0483 if (err < 0)
0484 dev_err(&pdev->dev, "failed to remove platform: %d\n", err);
0485
0486 err = data->remove(pdev);
0487 if (err < 0)
0488 dev_err(&pdev->dev, "failed to remove subdriver: %d\n", err);
0489
0490 stmmac_remove_config_dt(pdev, priv->plat);
0491
0492 return err;
0493 }
0494
0495 static const struct of_device_id dwc_eth_dwmac_match[] = {
0496 { .compatible = "snps,dwc-qos-ethernet-4.10", .data = &dwc_qos_data },
0497 { .compatible = "nvidia,tegra186-eqos", .data = &tegra_eqos_data },
0498 { }
0499 };
0500 MODULE_DEVICE_TABLE(of, dwc_eth_dwmac_match);
0501
0502 static struct platform_driver dwc_eth_dwmac_driver = {
0503 .probe = dwc_eth_dwmac_probe,
0504 .remove = dwc_eth_dwmac_remove,
0505 .driver = {
0506 .name = "dwc-eth-dwmac",
0507 .pm = &stmmac_pltfr_pm_ops,
0508 .of_match_table = dwc_eth_dwmac_match,
0509 },
0510 };
0511 module_platform_driver(dwc_eth_dwmac_driver);
0512
0513 MODULE_AUTHOR("Joao Pinto <jpinto@synopsys.com>");
0514 MODULE_DESCRIPTION("Synopsys DWC Ethernet Quality-of-Service v4.10a driver");
0515 MODULE_LICENSE("GPL v2");