Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Synopsys DWC Ethernet Quality-of-Service v4.10a linux driver
0004  *
0005  * Copyright (C) 2016 Joao Pinto <jpinto@synopsys.com>
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          * Since the register has a reset value of 1, if property
0061          * is missing, default to 1.
0062          */
0063         plat_dat->axi->axi_wr_osr_lmt = 1;
0064     } else {
0065         /**
0066          * If property exists, to keep the behavior from dwc_eth_qos,
0067          * subtract one after parsing.
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          * Since the register has a reset value of 1, if property
0076          * is missing, default to 1.
0077          */
0078         plat_dat->axi->axi_rd_osr_lmt = 1;
0079     } else {
0080         /**
0081          * If property exists, to keep the behavior from dwc_eth_qos,
0082          * subtract one after parsing.
0083          */
0084         plat_dat->axi->axi_rd_osr_lmt--;
0085     }
0086     device_property_read_u32(dev, "snps,burst-map", &burst_map);
0087 
0088     /* converts burst-map bitmask to burst array */
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     /* dwc-qos needs GMAC4, AAL, TSO and PMT */
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         /* calibrate */
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     /* MDIO bus was already reset just above */
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      * Since stmmac_platform supports name IRQ only, basic platform
0431      * resource initialization is done in the glue logic.
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");