Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* Copyright Altera Corporation (C) 2014. All rights reserved.
0003  *
0004  * Adopted from dwmac-sti.c
0005  */
0006 
0007 #include <linux/mfd/altera-sysmgr.h>
0008 #include <linux/of.h>
0009 #include <linux/of_address.h>
0010 #include <linux/of_net.h>
0011 #include <linux/phy.h>
0012 #include <linux/regmap.h>
0013 #include <linux/reset.h>
0014 #include <linux/stmmac.h>
0015 
0016 #include "stmmac.h"
0017 #include "stmmac_platform.h"
0018 
0019 #include "altr_tse_pcs.h"
0020 
0021 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
0022 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
0023 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2
0024 #define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2
0025 #define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003
0026 #define SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x00000010
0027 #define SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x00000100
0028 
0029 #define SYSMGR_FPGAGRP_MODULE_REG  0x00000028
0030 #define SYSMGR_FPGAGRP_MODULE_EMAC 0x00000004
0031 #define SYSMGR_FPGAINTF_EMAC_REG    0x00000070
0032 #define SYSMGR_FPGAINTF_EMAC_BIT    0x1
0033 
0034 #define EMAC_SPLITTER_CTRL_REG          0x0
0035 #define EMAC_SPLITTER_CTRL_SPEED_MASK       0x3
0036 #define EMAC_SPLITTER_CTRL_SPEED_10     0x2
0037 #define EMAC_SPLITTER_CTRL_SPEED_100        0x3
0038 #define EMAC_SPLITTER_CTRL_SPEED_1000       0x0
0039 
0040 struct socfpga_dwmac;
0041 struct socfpga_dwmac_ops {
0042     int (*set_phy_mode)(struct socfpga_dwmac *dwmac_priv);
0043 };
0044 
0045 struct socfpga_dwmac {
0046     u32 reg_offset;
0047     u32 reg_shift;
0048     struct  device *dev;
0049     struct regmap *sys_mgr_base_addr;
0050     struct reset_control *stmmac_rst;
0051     struct reset_control *stmmac_ocp_rst;
0052     void __iomem *splitter_base;
0053     bool f2h_ptp_ref_clk;
0054     struct tse_pcs pcs;
0055     const struct socfpga_dwmac_ops *ops;
0056 };
0057 
0058 static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed)
0059 {
0060     struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)priv;
0061     void __iomem *splitter_base = dwmac->splitter_base;
0062     void __iomem *sgmii_adapter_base = dwmac->pcs.sgmii_adapter_base;
0063     struct device *dev = dwmac->dev;
0064     struct net_device *ndev = dev_get_drvdata(dev);
0065     struct phy_device *phy_dev = ndev->phydev;
0066     u32 val;
0067 
0068     if (sgmii_adapter_base)
0069         writew(SGMII_ADAPTER_DISABLE,
0070                sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
0071 
0072     if (splitter_base) {
0073         val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG);
0074         val &= ~EMAC_SPLITTER_CTRL_SPEED_MASK;
0075 
0076         switch (speed) {
0077         case 1000:
0078             val |= EMAC_SPLITTER_CTRL_SPEED_1000;
0079             break;
0080         case 100:
0081             val |= EMAC_SPLITTER_CTRL_SPEED_100;
0082             break;
0083         case 10:
0084             val |= EMAC_SPLITTER_CTRL_SPEED_10;
0085             break;
0086         default:
0087             return;
0088         }
0089         writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG);
0090     }
0091 
0092     if (phy_dev && sgmii_adapter_base) {
0093         writew(SGMII_ADAPTER_ENABLE,
0094                sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG);
0095         tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed);
0096     }
0097 }
0098 
0099 static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
0100 {
0101     struct device_node *np = dev->of_node;
0102     struct regmap *sys_mgr_base_addr;
0103     u32 reg_offset, reg_shift;
0104     int ret, index;
0105     struct device_node *np_splitter = NULL;
0106     struct device_node *np_sgmii_adapter = NULL;
0107     struct resource res_splitter;
0108     struct resource res_tse_pcs;
0109     struct resource res_sgmii_adapter;
0110 
0111     sys_mgr_base_addr =
0112         altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
0113     if (IS_ERR(sys_mgr_base_addr)) {
0114         dev_info(dev, "No sysmgr-syscon node found\n");
0115         return PTR_ERR(sys_mgr_base_addr);
0116     }
0117 
0118     ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, &reg_offset);
0119     if (ret) {
0120         dev_info(dev, "Could not read reg_offset from sysmgr-syscon!\n");
0121         return -EINVAL;
0122     }
0123 
0124     ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, &reg_shift);
0125     if (ret) {
0126         dev_info(dev, "Could not read reg_shift from sysmgr-syscon!\n");
0127         return -EINVAL;
0128     }
0129 
0130     dwmac->f2h_ptp_ref_clk = of_property_read_bool(np, "altr,f2h_ptp_ref_clk");
0131 
0132     np_splitter = of_parse_phandle(np, "altr,emac-splitter", 0);
0133     if (np_splitter) {
0134         ret = of_address_to_resource(np_splitter, 0, &res_splitter);
0135         of_node_put(np_splitter);
0136         if (ret) {
0137             dev_info(dev, "Missing emac splitter address\n");
0138             return -EINVAL;
0139         }
0140 
0141         dwmac->splitter_base = devm_ioremap_resource(dev, &res_splitter);
0142         if (IS_ERR(dwmac->splitter_base)) {
0143             dev_info(dev, "Failed to mapping emac splitter\n");
0144             return PTR_ERR(dwmac->splitter_base);
0145         }
0146     }
0147 
0148     np_sgmii_adapter = of_parse_phandle(np,
0149                         "altr,gmii-to-sgmii-converter", 0);
0150     if (np_sgmii_adapter) {
0151         index = of_property_match_string(np_sgmii_adapter, "reg-names",
0152                          "hps_emac_interface_splitter_avalon_slave");
0153 
0154         if (index >= 0) {
0155             if (of_address_to_resource(np_sgmii_adapter, index,
0156                            &res_splitter)) {
0157                 dev_err(dev,
0158                     "%s: ERROR: missing emac splitter address\n",
0159                     __func__);
0160                 ret = -EINVAL;
0161                 goto err_node_put;
0162             }
0163 
0164             dwmac->splitter_base =
0165                 devm_ioremap_resource(dev, &res_splitter);
0166 
0167             if (IS_ERR(dwmac->splitter_base)) {
0168                 ret = PTR_ERR(dwmac->splitter_base);
0169                 goto err_node_put;
0170             }
0171         }
0172 
0173         index = of_property_match_string(np_sgmii_adapter, "reg-names",
0174                          "gmii_to_sgmii_adapter_avalon_slave");
0175 
0176         if (index >= 0) {
0177             if (of_address_to_resource(np_sgmii_adapter, index,
0178                            &res_sgmii_adapter)) {
0179                 dev_err(dev,
0180                     "%s: ERROR: failed mapping adapter\n",
0181                     __func__);
0182                 ret = -EINVAL;
0183                 goto err_node_put;
0184             }
0185 
0186             dwmac->pcs.sgmii_adapter_base =
0187                 devm_ioremap_resource(dev, &res_sgmii_adapter);
0188 
0189             if (IS_ERR(dwmac->pcs.sgmii_adapter_base)) {
0190                 ret = PTR_ERR(dwmac->pcs.sgmii_adapter_base);
0191                 goto err_node_put;
0192             }
0193         }
0194 
0195         index = of_property_match_string(np_sgmii_adapter, "reg-names",
0196                          "eth_tse_control_port");
0197 
0198         if (index >= 0) {
0199             if (of_address_to_resource(np_sgmii_adapter, index,
0200                            &res_tse_pcs)) {
0201                 dev_err(dev,
0202                     "%s: ERROR: failed mapping tse control port\n",
0203                     __func__);
0204                 ret = -EINVAL;
0205                 goto err_node_put;
0206             }
0207 
0208             dwmac->pcs.tse_pcs_base =
0209                 devm_ioremap_resource(dev, &res_tse_pcs);
0210 
0211             if (IS_ERR(dwmac->pcs.tse_pcs_base)) {
0212                 ret = PTR_ERR(dwmac->pcs.tse_pcs_base);
0213                 goto err_node_put;
0214             }
0215         }
0216     }
0217     dwmac->reg_offset = reg_offset;
0218     dwmac->reg_shift = reg_shift;
0219     dwmac->sys_mgr_base_addr = sys_mgr_base_addr;
0220     dwmac->dev = dev;
0221     of_node_put(np_sgmii_adapter);
0222 
0223     return 0;
0224 
0225 err_node_put:
0226     of_node_put(np_sgmii_adapter);
0227     return ret;
0228 }
0229 
0230 static int socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac)
0231 {
0232     struct net_device *ndev = dev_get_drvdata(dwmac->dev);
0233     struct stmmac_priv *priv = netdev_priv(ndev);
0234 
0235     return priv->plat->interface;
0236 }
0237 
0238 static int socfpga_set_phy_mode_common(int phymode, u32 *val)
0239 {
0240     switch (phymode) {
0241     case PHY_INTERFACE_MODE_RGMII:
0242     case PHY_INTERFACE_MODE_RGMII_ID:
0243     case PHY_INTERFACE_MODE_RGMII_RXID:
0244     case PHY_INTERFACE_MODE_RGMII_TXID:
0245         *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
0246         break;
0247     case PHY_INTERFACE_MODE_MII:
0248     case PHY_INTERFACE_MODE_GMII:
0249     case PHY_INTERFACE_MODE_SGMII:
0250         *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
0251         break;
0252     case PHY_INTERFACE_MODE_RMII:
0253         *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
0254         break;
0255     default:
0256         return -EINVAL;
0257     }
0258     return 0;
0259 }
0260 
0261 static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
0262 {
0263     struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
0264     int phymode = socfpga_get_plat_phymode(dwmac);
0265     u32 reg_offset = dwmac->reg_offset;
0266     u32 reg_shift = dwmac->reg_shift;
0267     u32 ctrl, val, module;
0268 
0269     if (socfpga_set_phy_mode_common(phymode, &val)) {
0270         dev_err(dwmac->dev, "bad phy mode %d\n", phymode);
0271         return -EINVAL;
0272     }
0273 
0274     /* Overwrite val to GMII if splitter core is enabled. The phymode here
0275      * is the actual phy mode on phy hardware, but phy interface from
0276      * EMAC core is GMII.
0277      */
0278     if (dwmac->splitter_base)
0279         val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
0280 
0281     /* Assert reset to the enet controller before changing the phy mode */
0282     reset_control_assert(dwmac->stmmac_ocp_rst);
0283     reset_control_assert(dwmac->stmmac_rst);
0284 
0285     regmap_read(sys_mgr_base_addr, reg_offset, &ctrl);
0286     ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
0287     ctrl |= val << reg_shift;
0288 
0289     if (dwmac->f2h_ptp_ref_clk ||
0290         phymode == PHY_INTERFACE_MODE_MII ||
0291         phymode == PHY_INTERFACE_MODE_GMII ||
0292         phymode == PHY_INTERFACE_MODE_SGMII) {
0293         regmap_read(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG,
0294                 &module);
0295         module |= (SYSMGR_FPGAGRP_MODULE_EMAC << (reg_shift / 2));
0296         regmap_write(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG,
0297                  module);
0298     }
0299 
0300     if (dwmac->f2h_ptp_ref_clk)
0301         ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2);
0302     else
0303         ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK <<
0304               (reg_shift / 2));
0305 
0306     regmap_write(sys_mgr_base_addr, reg_offset, ctrl);
0307 
0308     /* Deassert reset for the phy configuration to be sampled by
0309      * the enet controller, and operation to start in requested mode
0310      */
0311     reset_control_deassert(dwmac->stmmac_ocp_rst);
0312     reset_control_deassert(dwmac->stmmac_rst);
0313     if (phymode == PHY_INTERFACE_MODE_SGMII) {
0314         if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs) != 0) {
0315             dev_err(dwmac->dev, "Unable to initialize TSE PCS");
0316             return -EINVAL;
0317         }
0318     }
0319 
0320     return 0;
0321 }
0322 
0323 static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac)
0324 {
0325     struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
0326     int phymode = socfpga_get_plat_phymode(dwmac);
0327     u32 reg_offset = dwmac->reg_offset;
0328     u32 reg_shift = dwmac->reg_shift;
0329     u32 ctrl, val, module;
0330 
0331     if (socfpga_set_phy_mode_common(phymode, &val))
0332         return -EINVAL;
0333 
0334     /* Overwrite val to GMII if splitter core is enabled. The phymode here
0335      * is the actual phy mode on phy hardware, but phy interface from
0336      * EMAC core is GMII.
0337      */
0338     if (dwmac->splitter_base)
0339         val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
0340 
0341     /* Assert reset to the enet controller before changing the phy mode */
0342     reset_control_assert(dwmac->stmmac_ocp_rst);
0343     reset_control_assert(dwmac->stmmac_rst);
0344 
0345     regmap_read(sys_mgr_base_addr, reg_offset, &ctrl);
0346     ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK);
0347     ctrl |= val;
0348 
0349     if (dwmac->f2h_ptp_ref_clk ||
0350         phymode == PHY_INTERFACE_MODE_MII ||
0351         phymode == PHY_INTERFACE_MODE_GMII ||
0352         phymode == PHY_INTERFACE_MODE_SGMII) {
0353         ctrl |= SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK;
0354         regmap_read(sys_mgr_base_addr, SYSMGR_FPGAINTF_EMAC_REG,
0355                 &module);
0356         module |= (SYSMGR_FPGAINTF_EMAC_BIT << reg_shift);
0357         regmap_write(sys_mgr_base_addr, SYSMGR_FPGAINTF_EMAC_REG,
0358                  module);
0359     } else {
0360         ctrl &= ~SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK;
0361     }
0362 
0363     regmap_write(sys_mgr_base_addr, reg_offset, ctrl);
0364 
0365     /* Deassert reset for the phy configuration to be sampled by
0366      * the enet controller, and operation to start in requested mode
0367      */
0368     reset_control_deassert(dwmac->stmmac_ocp_rst);
0369     reset_control_deassert(dwmac->stmmac_rst);
0370     if (phymode == PHY_INTERFACE_MODE_SGMII) {
0371         if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs) != 0) {
0372             dev_err(dwmac->dev, "Unable to initialize TSE PCS");
0373             return -EINVAL;
0374         }
0375     }
0376     return 0;
0377 }
0378 
0379 static int socfpga_dwmac_probe(struct platform_device *pdev)
0380 {
0381     struct plat_stmmacenet_data *plat_dat;
0382     struct stmmac_resources stmmac_res;
0383     struct device       *dev = &pdev->dev;
0384     int         ret;
0385     struct socfpga_dwmac    *dwmac;
0386     struct net_device   *ndev;
0387     struct stmmac_priv  *stpriv;
0388     const struct socfpga_dwmac_ops *ops;
0389 
0390     ops = device_get_match_data(&pdev->dev);
0391     if (!ops) {
0392         dev_err(&pdev->dev, "no of match data provided\n");
0393         return -EINVAL;
0394     }
0395 
0396     ret = stmmac_get_platform_resources(pdev, &stmmac_res);
0397     if (ret)
0398         return ret;
0399 
0400     plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
0401     if (IS_ERR(plat_dat))
0402         return PTR_ERR(plat_dat);
0403 
0404     dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
0405     if (!dwmac) {
0406         ret = -ENOMEM;
0407         goto err_remove_config_dt;
0408     }
0409 
0410     dwmac->stmmac_ocp_rst = devm_reset_control_get_optional(dev, "stmmaceth-ocp");
0411     if (IS_ERR(dwmac->stmmac_ocp_rst)) {
0412         ret = PTR_ERR(dwmac->stmmac_ocp_rst);
0413         dev_err(dev, "error getting reset control of ocp %d\n", ret);
0414         goto err_remove_config_dt;
0415     }
0416 
0417     reset_control_deassert(dwmac->stmmac_ocp_rst);
0418 
0419     ret = socfpga_dwmac_parse_data(dwmac, dev);
0420     if (ret) {
0421         dev_err(dev, "Unable to parse OF data\n");
0422         goto err_remove_config_dt;
0423     }
0424 
0425     dwmac->ops = ops;
0426     plat_dat->bsp_priv = dwmac;
0427     plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
0428 
0429     ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
0430     if (ret)
0431         goto err_remove_config_dt;
0432 
0433     ndev = platform_get_drvdata(pdev);
0434     stpriv = netdev_priv(ndev);
0435 
0436     /* The socfpga driver needs to control the stmmac reset to set the phy
0437      * mode. Create a copy of the core reset handle so it can be used by
0438      * the driver later.
0439      */
0440     dwmac->stmmac_rst = stpriv->plat->stmmac_rst;
0441 
0442     ret = ops->set_phy_mode(dwmac);
0443     if (ret)
0444         goto err_dvr_remove;
0445 
0446     return 0;
0447 
0448 err_dvr_remove:
0449     stmmac_dvr_remove(&pdev->dev);
0450 err_remove_config_dt:
0451     stmmac_remove_config_dt(pdev, plat_dat);
0452 
0453     return ret;
0454 }
0455 
0456 #ifdef CONFIG_PM_SLEEP
0457 static int socfpga_dwmac_resume(struct device *dev)
0458 {
0459     struct net_device *ndev = dev_get_drvdata(dev);
0460     struct stmmac_priv *priv = netdev_priv(ndev);
0461     struct socfpga_dwmac *dwmac_priv = get_stmmac_bsp_priv(dev);
0462 
0463     dwmac_priv->ops->set_phy_mode(priv->plat->bsp_priv);
0464 
0465     /* Before the enet controller is suspended, the phy is suspended.
0466      * This causes the phy clock to be gated. The enet controller is
0467      * resumed before the phy, so the clock is still gated "off" when
0468      * the enet controller is resumed. This code makes sure the phy
0469      * is "resumed" before reinitializing the enet controller since
0470      * the enet controller depends on an active phy clock to complete
0471      * a DMA reset. A DMA reset will "time out" if executed
0472      * with no phy clock input on the Synopsys enet controller.
0473      * Verified through Synopsys Case #8000711656.
0474      *
0475      * Note that the phy clock is also gated when the phy is isolated.
0476      * Phy "suspend" and "isolate" controls are located in phy basic
0477      * control register 0, and can be modified by the phy driver
0478      * framework.
0479      */
0480     if (ndev->phydev)
0481         phy_resume(ndev->phydev);
0482 
0483     return stmmac_resume(dev);
0484 }
0485 #endif /* CONFIG_PM_SLEEP */
0486 
0487 static int __maybe_unused socfpga_dwmac_runtime_suspend(struct device *dev)
0488 {
0489     struct net_device *ndev = dev_get_drvdata(dev);
0490     struct stmmac_priv *priv = netdev_priv(ndev);
0491 
0492     stmmac_bus_clks_config(priv, false);
0493 
0494     return 0;
0495 }
0496 
0497 static int __maybe_unused socfpga_dwmac_runtime_resume(struct device *dev)
0498 {
0499     struct net_device *ndev = dev_get_drvdata(dev);
0500     struct stmmac_priv *priv = netdev_priv(ndev);
0501 
0502     return stmmac_bus_clks_config(priv, true);
0503 }
0504 
0505 static const struct dev_pm_ops socfpga_dwmac_pm_ops = {
0506     SET_SYSTEM_SLEEP_PM_OPS(stmmac_suspend, socfpga_dwmac_resume)
0507     SET_RUNTIME_PM_OPS(socfpga_dwmac_runtime_suspend, socfpga_dwmac_runtime_resume, NULL)
0508 };
0509 
0510 static const struct socfpga_dwmac_ops socfpga_gen5_ops = {
0511     .set_phy_mode = socfpga_gen5_set_phy_mode,
0512 };
0513 
0514 static const struct socfpga_dwmac_ops socfpga_gen10_ops = {
0515     .set_phy_mode = socfpga_gen10_set_phy_mode,
0516 };
0517 
0518 static const struct of_device_id socfpga_dwmac_match[] = {
0519     { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gen5_ops },
0520     { .compatible = "altr,socfpga-stmmac-a10-s10", .data = &socfpga_gen10_ops },
0521     { }
0522 };
0523 MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);
0524 
0525 static struct platform_driver socfpga_dwmac_driver = {
0526     .probe  = socfpga_dwmac_probe,
0527     .remove = stmmac_pltfr_remove,
0528     .driver = {
0529         .name           = "socfpga-dwmac",
0530         .pm     = &socfpga_dwmac_pm_ops,
0531         .of_match_table = socfpga_dwmac_match,
0532     },
0533 };
0534 module_platform_driver(socfpga_dwmac_driver);
0535 
0536 MODULE_LICENSE("GPL v2");