1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright Altera Corporation (C) 2014. All rights reserved. 3 * 4 * Adopted from dwmac-sti.c 5 */ 6 7 #include <linux/mfd/altera-sysmgr.h> 8 #include <linux/of.h> 9 #include <linux/of_address.h> 10 #include <linux/of_net.h> 11 #include <linux/phy.h> 12 #include <linux/regmap.h> 13 #include <linux/reset.h> 14 #include <linux/stmmac.h> 15 16 #include "stmmac.h" 17 #include "stmmac_platform.h" 18 19 #include "altr_tse_pcs.h" 20 21 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0 22 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1 23 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2 24 #define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2 25 #define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003 26 #define SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x00000010 27 #define SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK 0x00000100 28 29 #define SYSMGR_FPGAGRP_MODULE_REG 0x00000028 30 #define SYSMGR_FPGAGRP_MODULE_EMAC 0x00000004 31 #define SYSMGR_FPGAINTF_EMAC_REG 0x00000070 32 #define SYSMGR_FPGAINTF_EMAC_BIT 0x1 33 34 #define EMAC_SPLITTER_CTRL_REG 0x0 35 #define EMAC_SPLITTER_CTRL_SPEED_MASK 0x3 36 #define EMAC_SPLITTER_CTRL_SPEED_10 0x2 37 #define EMAC_SPLITTER_CTRL_SPEED_100 0x3 38 #define EMAC_SPLITTER_CTRL_SPEED_1000 0x0 39 40 struct socfpga_dwmac; 41 struct socfpga_dwmac_ops { 42 int (*set_phy_mode)(struct socfpga_dwmac *dwmac_priv); 43 }; 44 45 struct socfpga_dwmac { 46 u32 reg_offset; 47 u32 reg_shift; 48 struct device *dev; 49 struct regmap *sys_mgr_base_addr; 50 struct reset_control *stmmac_rst; 51 struct reset_control *stmmac_ocp_rst; 52 void __iomem *splitter_base; 53 bool f2h_ptp_ref_clk; 54 struct tse_pcs pcs; 55 const struct socfpga_dwmac_ops *ops; 56 }; 57 58 static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed) 59 { 60 struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)priv; 61 void __iomem *splitter_base = dwmac->splitter_base; 62 void __iomem *sgmii_adapter_base = dwmac->pcs.sgmii_adapter_base; 63 struct device *dev = dwmac->dev; 64 struct net_device *ndev = dev_get_drvdata(dev); 65 struct phy_device *phy_dev = ndev->phydev; 66 u32 val; 67 68 writew(SGMII_ADAPTER_DISABLE, 69 sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); 70 71 if (splitter_base) { 72 val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG); 73 val &= ~EMAC_SPLITTER_CTRL_SPEED_MASK; 74 75 switch (speed) { 76 case 1000: 77 val |= EMAC_SPLITTER_CTRL_SPEED_1000; 78 break; 79 case 100: 80 val |= EMAC_SPLITTER_CTRL_SPEED_100; 81 break; 82 case 10: 83 val |= EMAC_SPLITTER_CTRL_SPEED_10; 84 break; 85 default: 86 return; 87 } 88 writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG); 89 } 90 91 writew(SGMII_ADAPTER_ENABLE, 92 sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); 93 if (phy_dev) 94 tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed); 95 } 96 97 static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) 98 { 99 struct device_node *np = dev->of_node; 100 struct regmap *sys_mgr_base_addr; 101 u32 reg_offset, reg_shift; 102 int ret, index; 103 struct device_node *np_splitter = NULL; 104 struct device_node *np_sgmii_adapter = NULL; 105 struct resource res_splitter; 106 struct resource res_tse_pcs; 107 struct resource res_sgmii_adapter; 108 109 sys_mgr_base_addr = 110 altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); 111 if (IS_ERR(sys_mgr_base_addr)) { 112 dev_info(dev, "No sysmgr-syscon node found\n"); 113 return PTR_ERR(sys_mgr_base_addr); 114 } 115 116 ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, ®_offset); 117 if (ret) { 118 dev_info(dev, "Could not read reg_offset from sysmgr-syscon!\n"); 119 return -EINVAL; 120 } 121 122 ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, ®_shift); 123 if (ret) { 124 dev_info(dev, "Could not read reg_shift from sysmgr-syscon!\n"); 125 return -EINVAL; 126 } 127 128 dwmac->f2h_ptp_ref_clk = of_property_read_bool(np, "altr,f2h_ptp_ref_clk"); 129 130 np_splitter = of_parse_phandle(np, "altr,emac-splitter", 0); 131 if (np_splitter) { 132 ret = of_address_to_resource(np_splitter, 0, &res_splitter); 133 of_node_put(np_splitter); 134 if (ret) { 135 dev_info(dev, "Missing emac splitter address\n"); 136 return -EINVAL; 137 } 138 139 dwmac->splitter_base = devm_ioremap_resource(dev, &res_splitter); 140 if (IS_ERR(dwmac->splitter_base)) { 141 dev_info(dev, "Failed to mapping emac splitter\n"); 142 return PTR_ERR(dwmac->splitter_base); 143 } 144 } 145 146 np_sgmii_adapter = of_parse_phandle(np, 147 "altr,gmii-to-sgmii-converter", 0); 148 if (np_sgmii_adapter) { 149 index = of_property_match_string(np_sgmii_adapter, "reg-names", 150 "hps_emac_interface_splitter_avalon_slave"); 151 152 if (index >= 0) { 153 if (of_address_to_resource(np_sgmii_adapter, index, 154 &res_splitter)) { 155 dev_err(dev, 156 "%s: ERROR: missing emac splitter address\n", 157 __func__); 158 ret = -EINVAL; 159 goto err_node_put; 160 } 161 162 dwmac->splitter_base = 163 devm_ioremap_resource(dev, &res_splitter); 164 165 if (IS_ERR(dwmac->splitter_base)) { 166 ret = PTR_ERR(dwmac->splitter_base); 167 goto err_node_put; 168 } 169 } 170 171 index = of_property_match_string(np_sgmii_adapter, "reg-names", 172 "gmii_to_sgmii_adapter_avalon_slave"); 173 174 if (index >= 0) { 175 if (of_address_to_resource(np_sgmii_adapter, index, 176 &res_sgmii_adapter)) { 177 dev_err(dev, 178 "%s: ERROR: failed mapping adapter\n", 179 __func__); 180 ret = -EINVAL; 181 goto err_node_put; 182 } 183 184 dwmac->pcs.sgmii_adapter_base = 185 devm_ioremap_resource(dev, &res_sgmii_adapter); 186 187 if (IS_ERR(dwmac->pcs.sgmii_adapter_base)) { 188 ret = PTR_ERR(dwmac->pcs.sgmii_adapter_base); 189 goto err_node_put; 190 } 191 } 192 193 index = of_property_match_string(np_sgmii_adapter, "reg-names", 194 "eth_tse_control_port"); 195 196 if (index >= 0) { 197 if (of_address_to_resource(np_sgmii_adapter, index, 198 &res_tse_pcs)) { 199 dev_err(dev, 200 "%s: ERROR: failed mapping tse control port\n", 201 __func__); 202 ret = -EINVAL; 203 goto err_node_put; 204 } 205 206 dwmac->pcs.tse_pcs_base = 207 devm_ioremap_resource(dev, &res_tse_pcs); 208 209 if (IS_ERR(dwmac->pcs.tse_pcs_base)) { 210 ret = PTR_ERR(dwmac->pcs.tse_pcs_base); 211 goto err_node_put; 212 } 213 } 214 } 215 dwmac->reg_offset = reg_offset; 216 dwmac->reg_shift = reg_shift; 217 dwmac->sys_mgr_base_addr = sys_mgr_base_addr; 218 dwmac->dev = dev; 219 of_node_put(np_sgmii_adapter); 220 221 return 0; 222 223 err_node_put: 224 of_node_put(np_sgmii_adapter); 225 return ret; 226 } 227 228 static int socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac) 229 { 230 struct net_device *ndev = dev_get_drvdata(dwmac->dev); 231 struct stmmac_priv *priv = netdev_priv(ndev); 232 233 return priv->plat->interface; 234 } 235 236 static int socfpga_set_phy_mode_common(int phymode, u32 *val) 237 { 238 switch (phymode) { 239 case PHY_INTERFACE_MODE_RGMII: 240 case PHY_INTERFACE_MODE_RGMII_ID: 241 case PHY_INTERFACE_MODE_RGMII_RXID: 242 case PHY_INTERFACE_MODE_RGMII_TXID: 243 *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; 244 break; 245 case PHY_INTERFACE_MODE_MII: 246 case PHY_INTERFACE_MODE_GMII: 247 case PHY_INTERFACE_MODE_SGMII: 248 *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 249 break; 250 case PHY_INTERFACE_MODE_RMII: 251 *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; 252 break; 253 default: 254 return -EINVAL; 255 } 256 return 0; 257 } 258 259 static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac) 260 { 261 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr; 262 int phymode = socfpga_get_plat_phymode(dwmac); 263 u32 reg_offset = dwmac->reg_offset; 264 u32 reg_shift = dwmac->reg_shift; 265 u32 ctrl, val, module; 266 267 if (socfpga_set_phy_mode_common(phymode, &val)) { 268 dev_err(dwmac->dev, "bad phy mode %d\n", phymode); 269 return -EINVAL; 270 } 271 272 /* Overwrite val to GMII if splitter core is enabled. The phymode here 273 * is the actual phy mode on phy hardware, but phy interface from 274 * EMAC core is GMII. 275 */ 276 if (dwmac->splitter_base) 277 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 278 279 /* Assert reset to the enet controller before changing the phy mode */ 280 reset_control_assert(dwmac->stmmac_ocp_rst); 281 reset_control_assert(dwmac->stmmac_rst); 282 283 regmap_read(sys_mgr_base_addr, reg_offset, &ctrl); 284 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift); 285 ctrl |= val << reg_shift; 286 287 if (dwmac->f2h_ptp_ref_clk || 288 phymode == PHY_INTERFACE_MODE_MII || 289 phymode == PHY_INTERFACE_MODE_GMII || 290 phymode == PHY_INTERFACE_MODE_SGMII) { 291 regmap_read(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG, 292 &module); 293 module |= (SYSMGR_FPGAGRP_MODULE_EMAC << (reg_shift / 2)); 294 regmap_write(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG, 295 module); 296 } 297 298 if (dwmac->f2h_ptp_ref_clk) 299 ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2); 300 else 301 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << 302 (reg_shift / 2)); 303 304 regmap_write(sys_mgr_base_addr, reg_offset, ctrl); 305 306 /* Deassert reset for the phy configuration to be sampled by 307 * the enet controller, and operation to start in requested mode 308 */ 309 reset_control_deassert(dwmac->stmmac_ocp_rst); 310 reset_control_deassert(dwmac->stmmac_rst); 311 if (phymode == PHY_INTERFACE_MODE_SGMII) { 312 if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs) != 0) { 313 dev_err(dwmac->dev, "Unable to initialize TSE PCS"); 314 return -EINVAL; 315 } 316 } 317 318 return 0; 319 } 320 321 static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac) 322 { 323 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr; 324 int phymode = socfpga_get_plat_phymode(dwmac); 325 u32 reg_offset = dwmac->reg_offset; 326 u32 reg_shift = dwmac->reg_shift; 327 u32 ctrl, val, module; 328 329 if (socfpga_set_phy_mode_common(phymode, &val)) 330 return -EINVAL; 331 332 /* Overwrite val to GMII if splitter core is enabled. The phymode here 333 * is the actual phy mode on phy hardware, but phy interface from 334 * EMAC core is GMII. 335 */ 336 if (dwmac->splitter_base) 337 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 338 339 /* Assert reset to the enet controller before changing the phy mode */ 340 reset_control_assert(dwmac->stmmac_ocp_rst); 341 reset_control_assert(dwmac->stmmac_rst); 342 343 regmap_read(sys_mgr_base_addr, reg_offset, &ctrl); 344 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK); 345 ctrl |= val; 346 347 if (dwmac->f2h_ptp_ref_clk || 348 phymode == PHY_INTERFACE_MODE_MII || 349 phymode == PHY_INTERFACE_MODE_GMII || 350 phymode == PHY_INTERFACE_MODE_SGMII) { 351 ctrl |= SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK; 352 regmap_read(sys_mgr_base_addr, SYSMGR_FPGAINTF_EMAC_REG, 353 &module); 354 module |= (SYSMGR_FPGAINTF_EMAC_BIT << reg_shift); 355 regmap_write(sys_mgr_base_addr, SYSMGR_FPGAINTF_EMAC_REG, 356 module); 357 } else { 358 ctrl &= ~SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK; 359 } 360 361 regmap_write(sys_mgr_base_addr, reg_offset, ctrl); 362 363 /* Deassert reset for the phy configuration to be sampled by 364 * the enet controller, and operation to start in requested mode 365 */ 366 reset_control_deassert(dwmac->stmmac_ocp_rst); 367 reset_control_deassert(dwmac->stmmac_rst); 368 if (phymode == PHY_INTERFACE_MODE_SGMII) { 369 if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs) != 0) { 370 dev_err(dwmac->dev, "Unable to initialize TSE PCS"); 371 return -EINVAL; 372 } 373 } 374 return 0; 375 } 376 377 static int socfpga_dwmac_probe(struct platform_device *pdev) 378 { 379 struct plat_stmmacenet_data *plat_dat; 380 struct stmmac_resources stmmac_res; 381 struct device *dev = &pdev->dev; 382 int ret; 383 struct socfpga_dwmac *dwmac; 384 struct net_device *ndev; 385 struct stmmac_priv *stpriv; 386 const struct socfpga_dwmac_ops *ops; 387 388 ops = device_get_match_data(&pdev->dev); 389 if (!ops) { 390 dev_err(&pdev->dev, "no of match data provided\n"); 391 return -EINVAL; 392 } 393 394 ret = stmmac_get_platform_resources(pdev, &stmmac_res); 395 if (ret) 396 return ret; 397 398 plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac); 399 if (IS_ERR(plat_dat)) 400 return PTR_ERR(plat_dat); 401 402 dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL); 403 if (!dwmac) { 404 ret = -ENOMEM; 405 goto err_remove_config_dt; 406 } 407 408 dwmac->stmmac_ocp_rst = devm_reset_control_get_optional(dev, "stmmaceth-ocp"); 409 if (IS_ERR(dwmac->stmmac_ocp_rst)) { 410 ret = PTR_ERR(dwmac->stmmac_ocp_rst); 411 dev_err(dev, "error getting reset control of ocp %d\n", ret); 412 goto err_remove_config_dt; 413 } 414 415 reset_control_deassert(dwmac->stmmac_ocp_rst); 416 417 ret = socfpga_dwmac_parse_data(dwmac, dev); 418 if (ret) { 419 dev_err(dev, "Unable to parse OF data\n"); 420 goto err_remove_config_dt; 421 } 422 423 dwmac->ops = ops; 424 plat_dat->bsp_priv = dwmac; 425 plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; 426 427 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 428 if (ret) 429 goto err_remove_config_dt; 430 431 ndev = platform_get_drvdata(pdev); 432 stpriv = netdev_priv(ndev); 433 434 /* The socfpga driver needs to control the stmmac reset to set the phy 435 * mode. Create a copy of the core reset handle so it can be used by 436 * the driver later. 437 */ 438 dwmac->stmmac_rst = stpriv->plat->stmmac_rst; 439 440 ret = ops->set_phy_mode(dwmac); 441 if (ret) 442 goto err_dvr_remove; 443 444 return 0; 445 446 err_dvr_remove: 447 stmmac_dvr_remove(&pdev->dev); 448 err_remove_config_dt: 449 stmmac_remove_config_dt(pdev, plat_dat); 450 451 return ret; 452 } 453 454 #ifdef CONFIG_PM_SLEEP 455 static int socfpga_dwmac_resume(struct device *dev) 456 { 457 struct net_device *ndev = dev_get_drvdata(dev); 458 struct stmmac_priv *priv = netdev_priv(ndev); 459 struct socfpga_dwmac *dwmac_priv = get_stmmac_bsp_priv(dev); 460 461 dwmac_priv->ops->set_phy_mode(priv->plat->bsp_priv); 462 463 /* Before the enet controller is suspended, the phy is suspended. 464 * This causes the phy clock to be gated. The enet controller is 465 * resumed before the phy, so the clock is still gated "off" when 466 * the enet controller is resumed. This code makes sure the phy 467 * is "resumed" before reinitializing the enet controller since 468 * the enet controller depends on an active phy clock to complete 469 * a DMA reset. A DMA reset will "time out" if executed 470 * with no phy clock input on the Synopsys enet controller. 471 * Verified through Synopsys Case #8000711656. 472 * 473 * Note that the phy clock is also gated when the phy is isolated. 474 * Phy "suspend" and "isolate" controls are located in phy basic 475 * control register 0, and can be modified by the phy driver 476 * framework. 477 */ 478 if (ndev->phydev) 479 phy_resume(ndev->phydev); 480 481 return stmmac_resume(dev); 482 } 483 #endif /* CONFIG_PM_SLEEP */ 484 485 static int __maybe_unused socfpga_dwmac_runtime_suspend(struct device *dev) 486 { 487 struct net_device *ndev = dev_get_drvdata(dev); 488 struct stmmac_priv *priv = netdev_priv(ndev); 489 490 stmmac_bus_clks_config(priv, false); 491 492 return 0; 493 } 494 495 static int __maybe_unused socfpga_dwmac_runtime_resume(struct device *dev) 496 { 497 struct net_device *ndev = dev_get_drvdata(dev); 498 struct stmmac_priv *priv = netdev_priv(ndev); 499 500 return stmmac_bus_clks_config(priv, true); 501 } 502 503 static const struct dev_pm_ops socfpga_dwmac_pm_ops = { 504 SET_SYSTEM_SLEEP_PM_OPS(stmmac_suspend, socfpga_dwmac_resume) 505 SET_RUNTIME_PM_OPS(socfpga_dwmac_runtime_suspend, socfpga_dwmac_runtime_resume, NULL) 506 }; 507 508 static const struct socfpga_dwmac_ops socfpga_gen5_ops = { 509 .set_phy_mode = socfpga_gen5_set_phy_mode, 510 }; 511 512 static const struct socfpga_dwmac_ops socfpga_gen10_ops = { 513 .set_phy_mode = socfpga_gen10_set_phy_mode, 514 }; 515 516 static const struct of_device_id socfpga_dwmac_match[] = { 517 { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gen5_ops }, 518 { .compatible = "altr,socfpga-stmmac-a10-s10", .data = &socfpga_gen10_ops }, 519 { } 520 }; 521 MODULE_DEVICE_TABLE(of, socfpga_dwmac_match); 522 523 static struct platform_driver socfpga_dwmac_driver = { 524 .probe = socfpga_dwmac_probe, 525 .remove = stmmac_pltfr_remove, 526 .driver = { 527 .name = "socfpga-dwmac", 528 .pm = &socfpga_dwmac_pm_ops, 529 .of_match_table = socfpga_dwmac_match, 530 }, 531 }; 532 module_platform_driver(socfpga_dwmac_driver); 533 534 MODULE_LICENSE("GPL v2"); 535