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