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 *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; 245 break; 246 case PHY_INTERFACE_MODE_MII: 247 case PHY_INTERFACE_MODE_GMII: 248 case PHY_INTERFACE_MODE_SGMII: 249 *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 250 break; 251 case PHY_INTERFACE_MODE_RMII: 252 *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII; 253 break; 254 default: 255 return -EINVAL; 256 } 257 return 0; 258 } 259 260 static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac) 261 { 262 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr; 263 int phymode = socfpga_get_plat_phymode(dwmac); 264 u32 reg_offset = dwmac->reg_offset; 265 u32 reg_shift = dwmac->reg_shift; 266 u32 ctrl, val, module; 267 268 if (socfpga_set_phy_mode_common(phymode, &val)) { 269 dev_err(dwmac->dev, "bad phy mode %d\n", phymode); 270 return -EINVAL; 271 } 272 273 /* Overwrite val to GMII if splitter core is enabled. The phymode here 274 * is the actual phy mode on phy hardware, but phy interface from 275 * EMAC core is GMII. 276 */ 277 if (dwmac->splitter_base) 278 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 279 280 /* Assert reset to the enet controller before changing the phy mode */ 281 reset_control_assert(dwmac->stmmac_ocp_rst); 282 reset_control_assert(dwmac->stmmac_rst); 283 284 regmap_read(sys_mgr_base_addr, reg_offset, &ctrl); 285 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift); 286 ctrl |= val << reg_shift; 287 288 if (dwmac->f2h_ptp_ref_clk || 289 phymode == PHY_INTERFACE_MODE_MII || 290 phymode == PHY_INTERFACE_MODE_GMII || 291 phymode == PHY_INTERFACE_MODE_SGMII) { 292 ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2); 293 regmap_read(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG, 294 &module); 295 module |= (SYSMGR_FPGAGRP_MODULE_EMAC << (reg_shift / 2)); 296 regmap_write(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG, 297 module); 298 } else { 299 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2)); 300 } 301 302 regmap_write(sys_mgr_base_addr, reg_offset, ctrl); 303 304 /* Deassert reset for the phy configuration to be sampled by 305 * the enet controller, and operation to start in requested mode 306 */ 307 reset_control_deassert(dwmac->stmmac_ocp_rst); 308 reset_control_deassert(dwmac->stmmac_rst); 309 if (phymode == PHY_INTERFACE_MODE_SGMII) { 310 if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs) != 0) { 311 dev_err(dwmac->dev, "Unable to initialize TSE PCS"); 312 return -EINVAL; 313 } 314 } 315 316 return 0; 317 } 318 319 static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac) 320 { 321 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr; 322 int phymode = socfpga_get_plat_phymode(dwmac); 323 u32 reg_offset = dwmac->reg_offset; 324 u32 reg_shift = dwmac->reg_shift; 325 u32 ctrl, val, module; 326 327 if (socfpga_set_phy_mode_common(phymode, &val)) 328 return -EINVAL; 329 330 /* Overwrite val to GMII if splitter core is enabled. The phymode here 331 * is the actual phy mode on phy hardware, but phy interface from 332 * EMAC core is GMII. 333 */ 334 if (dwmac->splitter_base) 335 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 336 337 /* Assert reset to the enet controller before changing the phy mode */ 338 reset_control_assert(dwmac->stmmac_ocp_rst); 339 reset_control_assert(dwmac->stmmac_rst); 340 341 regmap_read(sys_mgr_base_addr, reg_offset, &ctrl); 342 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK); 343 ctrl |= val; 344 345 if (dwmac->f2h_ptp_ref_clk || 346 phymode == PHY_INTERFACE_MODE_MII || 347 phymode == PHY_INTERFACE_MODE_GMII || 348 phymode == PHY_INTERFACE_MODE_SGMII) { 349 ctrl |= SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK; 350 regmap_read(sys_mgr_base_addr, SYSMGR_FPGAINTF_EMAC_REG, 351 &module); 352 module |= (SYSMGR_FPGAINTF_EMAC_BIT << reg_shift); 353 regmap_write(sys_mgr_base_addr, SYSMGR_FPGAINTF_EMAC_REG, 354 module); 355 } else { 356 ctrl &= ~SYSMGR_GEN10_EMACGRP_CTRL_PTP_REF_CLK_MASK; 357 } 358 359 regmap_write(sys_mgr_base_addr, reg_offset, ctrl); 360 361 /* Deassert reset for the phy configuration to be sampled by 362 * the enet controller, and operation to start in requested mode 363 */ 364 reset_control_deassert(dwmac->stmmac_ocp_rst); 365 reset_control_deassert(dwmac->stmmac_rst); 366 if (phymode == PHY_INTERFACE_MODE_SGMII) { 367 if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs) != 0) { 368 dev_err(dwmac->dev, "Unable to initialize TSE PCS"); 369 return -EINVAL; 370 } 371 } 372 return 0; 373 } 374 375 static int socfpga_dwmac_probe(struct platform_device *pdev) 376 { 377 struct plat_stmmacenet_data *plat_dat; 378 struct stmmac_resources stmmac_res; 379 struct device *dev = &pdev->dev; 380 int ret; 381 struct socfpga_dwmac *dwmac; 382 struct net_device *ndev; 383 struct stmmac_priv *stpriv; 384 const struct socfpga_dwmac_ops *ops; 385 386 ops = device_get_match_data(&pdev->dev); 387 if (!ops) { 388 dev_err(&pdev->dev, "no of match data provided\n"); 389 return -EINVAL; 390 } 391 392 ret = stmmac_get_platform_resources(pdev, &stmmac_res); 393 if (ret) 394 return ret; 395 396 plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); 397 if (IS_ERR(plat_dat)) 398 return PTR_ERR(plat_dat); 399 400 dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL); 401 if (!dwmac) { 402 ret = -ENOMEM; 403 goto err_remove_config_dt; 404 } 405 406 dwmac->stmmac_ocp_rst = devm_reset_control_get_optional(dev, "stmmaceth-ocp"); 407 if (IS_ERR(dwmac->stmmac_ocp_rst)) { 408 ret = PTR_ERR(dwmac->stmmac_ocp_rst); 409 dev_err(dev, "error getting reset control of ocp %d\n", ret); 410 goto err_remove_config_dt; 411 } 412 413 reset_control_deassert(dwmac->stmmac_ocp_rst); 414 415 ret = socfpga_dwmac_parse_data(dwmac, dev); 416 if (ret) { 417 dev_err(dev, "Unable to parse OF data\n"); 418 goto err_remove_config_dt; 419 } 420 421 dwmac->ops = ops; 422 plat_dat->bsp_priv = dwmac; 423 plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; 424 425 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 426 if (ret) 427 goto err_remove_config_dt; 428 429 ndev = platform_get_drvdata(pdev); 430 stpriv = netdev_priv(ndev); 431 432 /* The socfpga driver needs to control the stmmac reset to set the phy 433 * mode. Create a copy of the core reset handle so it can be used by 434 * the driver later. 435 */ 436 dwmac->stmmac_rst = stpriv->plat->stmmac_rst; 437 438 ret = ops->set_phy_mode(dwmac); 439 if (ret) 440 goto err_dvr_remove; 441 442 return 0; 443 444 err_dvr_remove: 445 stmmac_dvr_remove(&pdev->dev); 446 err_remove_config_dt: 447 stmmac_remove_config_dt(pdev, plat_dat); 448 449 return ret; 450 } 451 452 #ifdef CONFIG_PM_SLEEP 453 static int socfpga_dwmac_resume(struct device *dev) 454 { 455 struct net_device *ndev = dev_get_drvdata(dev); 456 struct stmmac_priv *priv = netdev_priv(ndev); 457 struct socfpga_dwmac *dwmac_priv = get_stmmac_bsp_priv(dev); 458 459 dwmac_priv->ops->set_phy_mode(priv->plat->bsp_priv); 460 461 /* Before the enet controller is suspended, the phy is suspended. 462 * This causes the phy clock to be gated. The enet controller is 463 * resumed before the phy, so the clock is still gated "off" when 464 * the enet controller is resumed. This code makes sure the phy 465 * is "resumed" before reinitializing the enet controller since 466 * the enet controller depends on an active phy clock to complete 467 * a DMA reset. A DMA reset will "time out" if executed 468 * with no phy clock input on the Synopsys enet controller. 469 * Verified through Synopsys Case #8000711656. 470 * 471 * Note that the phy clock is also gated when the phy is isolated. 472 * Phy "suspend" and "isolate" controls are located in phy basic 473 * control register 0, and can be modified by the phy driver 474 * framework. 475 */ 476 if (ndev->phydev) 477 phy_resume(ndev->phydev); 478 479 return stmmac_resume(dev); 480 } 481 #endif /* CONFIG_PM_SLEEP */ 482 483 static SIMPLE_DEV_PM_OPS(socfpga_dwmac_pm_ops, stmmac_suspend, 484 socfpga_dwmac_resume); 485 486 static const struct socfpga_dwmac_ops socfpga_gen5_ops = { 487 .set_phy_mode = socfpga_gen5_set_phy_mode, 488 }; 489 490 static const struct socfpga_dwmac_ops socfpga_gen10_ops = { 491 .set_phy_mode = socfpga_gen10_set_phy_mode, 492 }; 493 494 static const struct of_device_id socfpga_dwmac_match[] = { 495 { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gen5_ops }, 496 { .compatible = "altr,socfpga-stmmac-a10-s10", .data = &socfpga_gen10_ops }, 497 { } 498 }; 499 MODULE_DEVICE_TABLE(of, socfpga_dwmac_match); 500 501 static struct platform_driver socfpga_dwmac_driver = { 502 .probe = socfpga_dwmac_probe, 503 .remove = stmmac_pltfr_remove, 504 .driver = { 505 .name = "socfpga-dwmac", 506 .pm = &socfpga_dwmac_pm_ops, 507 .of_match_table = socfpga_dwmac_match, 508 }, 509 }; 510 module_platform_driver(socfpga_dwmac_driver); 511 512 MODULE_LICENSE("GPL v2"); 513