1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU 4 * 5 * Copyright (C) STMicroelectronics SA 2017 6 * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics. 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/kernel.h> 11 #include <linux/mfd/syscon.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/of_net.h> 15 #include <linux/phy.h> 16 #include <linux/platform_device.h> 17 #include <linux/pm_wakeirq.h> 18 #include <linux/regmap.h> 19 #include <linux/slab.h> 20 #include <linux/stmmac.h> 21 22 #include "stmmac_platform.h" 23 24 #define SYSCFG_MCU_ETH_MASK BIT(23) 25 #define SYSCFG_MP1_ETH_MASK GENMASK(23, 16) 26 #define SYSCFG_PMCCLRR_OFFSET 0x40 27 28 #define SYSCFG_PMCR_ETH_CLK_SEL BIT(16) 29 #define SYSCFG_PMCR_ETH_REF_CLK_SEL BIT(17) 30 31 /* CLOCK feed to PHY*/ 32 #define ETH_CK_F_25M 25000000 33 #define ETH_CK_F_50M 50000000 34 #define ETH_CK_F_125M 125000000 35 36 /* Ethernet PHY interface selection in register SYSCFG Configuration 37 *------------------------------------------ 38 * src |BIT(23)| BIT(22)| BIT(21)|BIT(20)| 39 *------------------------------------------ 40 * MII | 0 | 0 | 0 | 1 | 41 *------------------------------------------ 42 * GMII | 0 | 0 | 0 | 0 | 43 *------------------------------------------ 44 * RGMII | 0 | 0 | 1 | n/a | 45 *------------------------------------------ 46 * RMII | 1 | 0 | 0 | n/a | 47 *------------------------------------------ 48 */ 49 #define SYSCFG_PMCR_ETH_SEL_MII BIT(20) 50 #define SYSCFG_PMCR_ETH_SEL_RGMII BIT(21) 51 #define SYSCFG_PMCR_ETH_SEL_RMII BIT(23) 52 #define SYSCFG_PMCR_ETH_SEL_GMII 0 53 #define SYSCFG_MCU_ETH_SEL_MII 0 54 #define SYSCFG_MCU_ETH_SEL_RMII 1 55 56 /* STM32MP1 register definitions 57 * 58 * Below table summarizes the clock requirement and clock sources for 59 * supported phy interface modes. 60 * __________________________________________________________________________ 61 *|PHY_MODE | Normal | PHY wo crystal| PHY wo crystal |No 125MHz from PHY| 62 *| | | 25MHz | 50MHz | | 63 * --------------------------------------------------------------------------- 64 *| MII | - | eth-ck | n/a | n/a | 65 *| | | st,ext-phyclk | | | 66 * --------------------------------------------------------------------------- 67 *| GMII | - | eth-ck | n/a | n/a | 68 *| | | st,ext-phyclk | | | 69 * --------------------------------------------------------------------------- 70 *| RGMII | - | eth-ck | n/a | eth-ck | 71 *| | | st,ext-phyclk | | st,eth-clk-sel or| 72 *| | | | | st,ext-phyclk | 73 * --------------------------------------------------------------------------- 74 *| RMII | - | eth-ck | eth-ck | n/a | 75 *| | | st,ext-phyclk | st,eth-ref-clk-sel | | 76 *| | | | or st,ext-phyclk | | 77 * --------------------------------------------------------------------------- 78 * 79 */ 80 81 struct stm32_dwmac { 82 struct clk *clk_tx; 83 struct clk *clk_rx; 84 struct clk *clk_eth_ck; 85 struct clk *clk_ethstp; 86 struct clk *syscfg_clk; 87 int ext_phyclk; 88 int enable_eth_ck; 89 int eth_clk_sel_reg; 90 int eth_ref_clk_sel_reg; 91 int irq_pwr_wakeup; 92 u32 mode_reg; /* MAC glue-logic mode register */ 93 u32 mode_mask; 94 struct regmap *regmap; 95 u32 speed; 96 const struct stm32_ops *ops; 97 struct device *dev; 98 }; 99 100 struct stm32_ops { 101 int (*set_mode)(struct plat_stmmacenet_data *plat_dat); 102 int (*suspend)(struct stm32_dwmac *dwmac); 103 void (*resume)(struct stm32_dwmac *dwmac); 104 int (*parse_data)(struct stm32_dwmac *dwmac, 105 struct device *dev); 106 bool clk_rx_enable_in_suspend; 107 bool is_mp13; 108 u32 syscfg_clr_off; 109 }; 110 111 static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume) 112 { 113 int ret; 114 115 ret = clk_prepare_enable(dwmac->clk_tx); 116 if (ret) 117 goto err_clk_tx; 118 119 if (!dwmac->ops->clk_rx_enable_in_suspend || !resume) { 120 ret = clk_prepare_enable(dwmac->clk_rx); 121 if (ret) 122 goto err_clk_rx; 123 } 124 125 ret = clk_prepare_enable(dwmac->syscfg_clk); 126 if (ret) 127 goto err_syscfg_clk; 128 129 if (dwmac->enable_eth_ck) { 130 ret = clk_prepare_enable(dwmac->clk_eth_ck); 131 if (ret) 132 goto err_clk_eth_ck; 133 } 134 135 return ret; 136 137 err_clk_eth_ck: 138 clk_disable_unprepare(dwmac->syscfg_clk); 139 err_syscfg_clk: 140 if (!dwmac->ops->clk_rx_enable_in_suspend || !resume) 141 clk_disable_unprepare(dwmac->clk_rx); 142 err_clk_rx: 143 clk_disable_unprepare(dwmac->clk_tx); 144 err_clk_tx: 145 return ret; 146 } 147 148 static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat, bool resume) 149 { 150 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 151 int ret; 152 153 if (dwmac->ops->set_mode) { 154 ret = dwmac->ops->set_mode(plat_dat); 155 if (ret) 156 return ret; 157 } 158 159 return stm32_dwmac_clk_enable(dwmac, resume); 160 } 161 162 static int stm32mp1_select_ethck_external(struct plat_stmmacenet_data *plat_dat) 163 { 164 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 165 166 switch (plat_dat->mac_interface) { 167 case PHY_INTERFACE_MODE_MII: 168 dwmac->enable_eth_ck = dwmac->ext_phyclk; 169 return 0; 170 case PHY_INTERFACE_MODE_GMII: 171 dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg || 172 dwmac->ext_phyclk; 173 return 0; 174 case PHY_INTERFACE_MODE_RMII: 175 dwmac->enable_eth_ck = dwmac->eth_ref_clk_sel_reg || 176 dwmac->ext_phyclk; 177 return 0; 178 case PHY_INTERFACE_MODE_RGMII: 179 case PHY_INTERFACE_MODE_RGMII_ID: 180 case PHY_INTERFACE_MODE_RGMII_RXID: 181 case PHY_INTERFACE_MODE_RGMII_TXID: 182 dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg || 183 dwmac->ext_phyclk; 184 return 0; 185 default: 186 dwmac->enable_eth_ck = false; 187 dev_err(dwmac->dev, "Mode %s not supported", 188 phy_modes(plat_dat->mac_interface)); 189 return -EINVAL; 190 } 191 } 192 193 static int stm32mp1_validate_ethck_rate(struct plat_stmmacenet_data *plat_dat) 194 { 195 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 196 const u32 clk_rate = clk_get_rate(dwmac->clk_eth_ck); 197 198 switch (plat_dat->mac_interface) { 199 case PHY_INTERFACE_MODE_MII: 200 case PHY_INTERFACE_MODE_GMII: 201 if (clk_rate == ETH_CK_F_25M) 202 return 0; 203 break; 204 case PHY_INTERFACE_MODE_RMII: 205 if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) 206 return 0; 207 break; 208 case PHY_INTERFACE_MODE_RGMII: 209 case PHY_INTERFACE_MODE_RGMII_ID: 210 case PHY_INTERFACE_MODE_RGMII_RXID: 211 case PHY_INTERFACE_MODE_RGMII_TXID: 212 if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) 213 return 0; 214 break; 215 default: 216 break; 217 } 218 219 dev_err(dwmac->dev, "Mode %s does not match eth-ck frequency %d Hz", 220 phy_modes(plat_dat->mac_interface), clk_rate); 221 return -EINVAL; 222 } 223 224 static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat) 225 { 226 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 227 u32 reg = dwmac->mode_reg; 228 int val = 0; 229 230 switch (plat_dat->mac_interface) { 231 case PHY_INTERFACE_MODE_MII: 232 /* 233 * STM32MP15xx supports both MII and GMII, STM32MP13xx MII only. 234 * SYSCFG_PMCSETR ETH_SELMII is present only on STM32MP15xx and 235 * acts as a selector between 0:GMII and 1:MII. As STM32MP13xx 236 * supports only MII, ETH_SELMII is not present. 237 */ 238 if (!dwmac->ops->is_mp13) /* Select MII mode on STM32MP15xx */ 239 val |= SYSCFG_PMCR_ETH_SEL_MII; 240 break; 241 case PHY_INTERFACE_MODE_GMII: 242 val = SYSCFG_PMCR_ETH_SEL_GMII; 243 if (dwmac->enable_eth_ck) 244 val |= SYSCFG_PMCR_ETH_CLK_SEL; 245 break; 246 case PHY_INTERFACE_MODE_RMII: 247 val = SYSCFG_PMCR_ETH_SEL_RMII; 248 if (dwmac->enable_eth_ck) 249 val |= SYSCFG_PMCR_ETH_REF_CLK_SEL; 250 break; 251 case PHY_INTERFACE_MODE_RGMII: 252 case PHY_INTERFACE_MODE_RGMII_ID: 253 case PHY_INTERFACE_MODE_RGMII_RXID: 254 case PHY_INTERFACE_MODE_RGMII_TXID: 255 val = SYSCFG_PMCR_ETH_SEL_RGMII; 256 if (dwmac->enable_eth_ck) 257 val |= SYSCFG_PMCR_ETH_CLK_SEL; 258 break; 259 default: 260 dev_err(dwmac->dev, "Mode %s not supported", 261 phy_modes(plat_dat->mac_interface)); 262 /* Do not manage others interfaces */ 263 return -EINVAL; 264 } 265 266 dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface)); 267 268 /* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */ 269 val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK); 270 271 /* Need to update PMCCLRR (clear register) */ 272 regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off, 273 dwmac->mode_mask); 274 275 /* Update PMCSETR (set register) */ 276 return regmap_update_bits(dwmac->regmap, reg, 277 dwmac->mode_mask, val); 278 } 279 280 static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) 281 { 282 int ret; 283 284 ret = stm32mp1_select_ethck_external(plat_dat); 285 if (ret) 286 return ret; 287 288 ret = stm32mp1_validate_ethck_rate(plat_dat); 289 if (ret) 290 return ret; 291 292 return stm32mp1_configure_pmcr(plat_dat); 293 } 294 295 static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat) 296 { 297 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 298 u32 reg = dwmac->mode_reg; 299 int val; 300 301 switch (plat_dat->mac_interface) { 302 case PHY_INTERFACE_MODE_MII: 303 val = SYSCFG_MCU_ETH_SEL_MII; 304 break; 305 case PHY_INTERFACE_MODE_RMII: 306 val = SYSCFG_MCU_ETH_SEL_RMII; 307 break; 308 default: 309 dev_err(dwmac->dev, "Mode %s not supported", 310 phy_modes(plat_dat->mac_interface)); 311 /* Do not manage others interfaces */ 312 return -EINVAL; 313 } 314 315 dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface)); 316 317 return regmap_update_bits(dwmac->regmap, reg, 318 SYSCFG_MCU_ETH_MASK, val << 23); 319 } 320 321 static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend) 322 { 323 clk_disable_unprepare(dwmac->clk_tx); 324 if (!dwmac->ops->clk_rx_enable_in_suspend || !suspend) 325 clk_disable_unprepare(dwmac->clk_rx); 326 327 clk_disable_unprepare(dwmac->syscfg_clk); 328 if (dwmac->enable_eth_ck) 329 clk_disable_unprepare(dwmac->clk_eth_ck); 330 } 331 332 static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, 333 struct device *dev) 334 { 335 struct device_node *np = dev->of_node; 336 int err; 337 338 /* Get TX/RX clocks */ 339 dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx"); 340 if (IS_ERR(dwmac->clk_tx)) { 341 dev_err(dev, "No ETH Tx clock provided...\n"); 342 return PTR_ERR(dwmac->clk_tx); 343 } 344 345 dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx"); 346 if (IS_ERR(dwmac->clk_rx)) { 347 dev_err(dev, "No ETH Rx clock provided...\n"); 348 return PTR_ERR(dwmac->clk_rx); 349 } 350 351 if (dwmac->ops->parse_data) { 352 err = dwmac->ops->parse_data(dwmac, dev); 353 if (err) 354 return err; 355 } 356 357 /* Get mode register */ 358 dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); 359 if (IS_ERR(dwmac->regmap)) 360 return PTR_ERR(dwmac->regmap); 361 362 err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); 363 if (err) { 364 dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err); 365 return err; 366 } 367 368 dwmac->mode_mask = SYSCFG_MP1_ETH_MASK; 369 err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask); 370 if (err) { 371 if (dwmac->ops->is_mp13) 372 dev_err(dev, "Sysconfig register mask must be set (%d)\n", err); 373 else 374 dev_dbg(dev, "Warning sysconfig register mask not set\n"); 375 } 376 377 return err; 378 } 379 380 static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, 381 struct device *dev) 382 { 383 struct platform_device *pdev = to_platform_device(dev); 384 struct device_node *np = dev->of_node; 385 int err = 0; 386 387 /* Ethernet PHY have no crystal */ 388 dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); 389 390 /* Gigabit Ethernet 125MHz clock selection. */ 391 dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel"); 392 393 /* Ethernet 50MHz RMII clock selection */ 394 dwmac->eth_ref_clk_sel_reg = 395 of_property_read_bool(np, "st,eth-ref-clk-sel"); 396 397 /* Get ETH_CLK clocks */ 398 dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck"); 399 if (IS_ERR(dwmac->clk_eth_ck)) { 400 dev_info(dev, "No phy clock provided...\n"); 401 dwmac->clk_eth_ck = NULL; 402 } 403 404 /* Clock used for low power mode */ 405 dwmac->clk_ethstp = devm_clk_get(dev, "ethstp"); 406 if (IS_ERR(dwmac->clk_ethstp)) { 407 dev_err(dev, 408 "No ETH peripheral clock provided for CStop mode ...\n"); 409 return PTR_ERR(dwmac->clk_ethstp); 410 } 411 412 /* Optional Clock for sysconfig */ 413 dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk"); 414 if (IS_ERR(dwmac->syscfg_clk)) 415 dwmac->syscfg_clk = NULL; 416 417 /* Get IRQ information early to have an ability to ask for deferred 418 * probe if needed before we went too far with resource allocation. 419 */ 420 dwmac->irq_pwr_wakeup = platform_get_irq_byname_optional(pdev, 421 "stm32_pwr_wakeup"); 422 if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER) 423 return -EPROBE_DEFER; 424 425 if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) { 426 err = device_init_wakeup(&pdev->dev, true); 427 if (err) { 428 dev_err(&pdev->dev, "Failed to init wake up irq\n"); 429 return err; 430 } 431 err = dev_pm_set_dedicated_wake_irq(&pdev->dev, 432 dwmac->irq_pwr_wakeup); 433 if (err) { 434 dev_err(&pdev->dev, "Failed to set wake up irq\n"); 435 device_init_wakeup(&pdev->dev, false); 436 } 437 device_set_wakeup_enable(&pdev->dev, false); 438 } 439 return err; 440 } 441 442 static int stm32_dwmac_probe(struct platform_device *pdev) 443 { 444 struct plat_stmmacenet_data *plat_dat; 445 struct stmmac_resources stmmac_res; 446 struct stm32_dwmac *dwmac; 447 const struct stm32_ops *data; 448 int ret; 449 450 ret = stmmac_get_platform_resources(pdev, &stmmac_res); 451 if (ret) 452 return ret; 453 454 plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac); 455 if (IS_ERR(plat_dat)) 456 return PTR_ERR(plat_dat); 457 458 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); 459 if (!dwmac) 460 return -ENOMEM; 461 462 data = of_device_get_match_data(&pdev->dev); 463 if (!data) { 464 dev_err(&pdev->dev, "no of match data provided\n"); 465 return -EINVAL; 466 } 467 468 dwmac->ops = data; 469 dwmac->dev = &pdev->dev; 470 471 ret = stm32_dwmac_parse_data(dwmac, &pdev->dev); 472 if (ret) { 473 dev_err(&pdev->dev, "Unable to parse OF data\n"); 474 return ret; 475 } 476 477 plat_dat->bsp_priv = dwmac; 478 479 ret = stm32_dwmac_init(plat_dat, false); 480 if (ret) 481 return ret; 482 483 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 484 if (ret) 485 goto err_clk_disable; 486 487 return 0; 488 489 err_clk_disable: 490 stm32_dwmac_clk_disable(dwmac, false); 491 492 return ret; 493 } 494 495 static void stm32_dwmac_remove(struct platform_device *pdev) 496 { 497 struct net_device *ndev = platform_get_drvdata(pdev); 498 struct stmmac_priv *priv = netdev_priv(ndev); 499 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 500 501 stmmac_dvr_remove(&pdev->dev); 502 503 stm32_dwmac_clk_disable(dwmac, false); 504 505 if (dwmac->irq_pwr_wakeup >= 0) { 506 dev_pm_clear_wake_irq(&pdev->dev); 507 device_init_wakeup(&pdev->dev, false); 508 } 509 } 510 511 static int stm32mp1_suspend(struct stm32_dwmac *dwmac) 512 { 513 return clk_prepare_enable(dwmac->clk_ethstp); 514 } 515 516 static void stm32mp1_resume(struct stm32_dwmac *dwmac) 517 { 518 clk_disable_unprepare(dwmac->clk_ethstp); 519 } 520 521 #ifdef CONFIG_PM_SLEEP 522 static int stm32_dwmac_suspend(struct device *dev) 523 { 524 struct net_device *ndev = dev_get_drvdata(dev); 525 struct stmmac_priv *priv = netdev_priv(ndev); 526 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 527 528 int ret; 529 530 ret = stmmac_suspend(dev); 531 if (ret) 532 return ret; 533 534 stm32_dwmac_clk_disable(dwmac, true); 535 536 if (dwmac->ops->suspend) 537 ret = dwmac->ops->suspend(dwmac); 538 539 return ret; 540 } 541 542 static int stm32_dwmac_resume(struct device *dev) 543 { 544 struct net_device *ndev = dev_get_drvdata(dev); 545 struct stmmac_priv *priv = netdev_priv(ndev); 546 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 547 int ret; 548 549 if (dwmac->ops->resume) 550 dwmac->ops->resume(dwmac); 551 552 ret = stm32_dwmac_init(priv->plat, true); 553 if (ret) 554 return ret; 555 556 ret = stmmac_resume(dev); 557 558 return ret; 559 } 560 #endif /* CONFIG_PM_SLEEP */ 561 562 static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops, 563 stm32_dwmac_suspend, stm32_dwmac_resume); 564 565 static struct stm32_ops stm32mcu_dwmac_data = { 566 .set_mode = stm32mcu_set_mode 567 }; 568 569 static struct stm32_ops stm32mp1_dwmac_data = { 570 .set_mode = stm32mp1_set_mode, 571 .suspend = stm32mp1_suspend, 572 .resume = stm32mp1_resume, 573 .parse_data = stm32mp1_parse_data, 574 .syscfg_clr_off = 0x44, 575 .is_mp13 = false, 576 .clk_rx_enable_in_suspend = true 577 }; 578 579 static struct stm32_ops stm32mp13_dwmac_data = { 580 .set_mode = stm32mp1_set_mode, 581 .suspend = stm32mp1_suspend, 582 .resume = stm32mp1_resume, 583 .parse_data = stm32mp1_parse_data, 584 .syscfg_clr_off = 0x08, 585 .is_mp13 = true, 586 .clk_rx_enable_in_suspend = true 587 }; 588 589 static const struct of_device_id stm32_dwmac_match[] = { 590 { .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data}, 591 { .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data}, 592 { .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data}, 593 { } 594 }; 595 MODULE_DEVICE_TABLE(of, stm32_dwmac_match); 596 597 static struct platform_driver stm32_dwmac_driver = { 598 .probe = stm32_dwmac_probe, 599 .remove_new = stm32_dwmac_remove, 600 .driver = { 601 .name = "stm32-dwmac", 602 .pm = &stm32_dwmac_pm_ops, 603 .of_match_table = stm32_dwmac_match, 604 }, 605 }; 606 module_platform_driver(stm32_dwmac_driver); 607 608 MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@gmail.com>"); 609 MODULE_AUTHOR("Christophe Roullier <christophe.roullier@st.com>"); 610 MODULE_DESCRIPTION("STMicroelectronics STM32 DWMAC Specific Glue layer"); 611 MODULE_LICENSE("GPL v2"); 612