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 struct regmap *regmap; 94 u32 speed; 95 const struct stm32_ops *ops; 96 struct device *dev; 97 }; 98 99 struct stm32_ops { 100 int (*set_mode)(struct plat_stmmacenet_data *plat_dat); 101 int (*clk_prepare)(struct stm32_dwmac *dwmac, bool prepare); 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 u32 syscfg_eth_mask; 107 bool clk_rx_enable_in_suspend; 108 }; 109 110 static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) 111 { 112 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 113 int ret; 114 115 if (dwmac->ops->set_mode) { 116 ret = dwmac->ops->set_mode(plat_dat); 117 if (ret) 118 return ret; 119 } 120 121 ret = clk_prepare_enable(dwmac->clk_tx); 122 if (ret) 123 return ret; 124 125 if (!dwmac->ops->clk_rx_enable_in_suspend || 126 !dwmac->dev->power.is_suspended) { 127 ret = clk_prepare_enable(dwmac->clk_rx); 128 if (ret) { 129 clk_disable_unprepare(dwmac->clk_tx); 130 return ret; 131 } 132 } 133 134 if (dwmac->ops->clk_prepare) { 135 ret = dwmac->ops->clk_prepare(dwmac, true); 136 if (ret) { 137 clk_disable_unprepare(dwmac->clk_rx); 138 clk_disable_unprepare(dwmac->clk_tx); 139 } 140 } 141 142 return ret; 143 } 144 145 static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare) 146 { 147 int ret = 0; 148 149 if (prepare) { 150 ret = clk_prepare_enable(dwmac->syscfg_clk); 151 if (ret) 152 return ret; 153 if (dwmac->enable_eth_ck) { 154 ret = clk_prepare_enable(dwmac->clk_eth_ck); 155 if (ret) { 156 clk_disable_unprepare(dwmac->syscfg_clk); 157 return ret; 158 } 159 } 160 } else { 161 clk_disable_unprepare(dwmac->syscfg_clk); 162 if (dwmac->enable_eth_ck) 163 clk_disable_unprepare(dwmac->clk_eth_ck); 164 } 165 return ret; 166 } 167 168 static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) 169 { 170 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 171 u32 reg = dwmac->mode_reg, clk_rate; 172 int val; 173 174 clk_rate = clk_get_rate(dwmac->clk_eth_ck); 175 dwmac->enable_eth_ck = false; 176 switch (plat_dat->mac_interface) { 177 case PHY_INTERFACE_MODE_MII: 178 if (clk_rate == ETH_CK_F_25M && dwmac->ext_phyclk) 179 dwmac->enable_eth_ck = true; 180 val = SYSCFG_PMCR_ETH_SEL_MII; 181 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n"); 182 break; 183 case PHY_INTERFACE_MODE_GMII: 184 val = SYSCFG_PMCR_ETH_SEL_GMII; 185 if (clk_rate == ETH_CK_F_25M && 186 (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) { 187 dwmac->enable_eth_ck = true; 188 val |= SYSCFG_PMCR_ETH_CLK_SEL; 189 } 190 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n"); 191 break; 192 case PHY_INTERFACE_MODE_RMII: 193 val = SYSCFG_PMCR_ETH_SEL_RMII; 194 if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) && 195 (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) { 196 dwmac->enable_eth_ck = true; 197 val |= SYSCFG_PMCR_ETH_REF_CLK_SEL; 198 } 199 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n"); 200 break; 201 case PHY_INTERFACE_MODE_RGMII: 202 case PHY_INTERFACE_MODE_RGMII_ID: 203 case PHY_INTERFACE_MODE_RGMII_RXID: 204 case PHY_INTERFACE_MODE_RGMII_TXID: 205 val = SYSCFG_PMCR_ETH_SEL_RGMII; 206 if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) && 207 (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) { 208 dwmac->enable_eth_ck = true; 209 val |= SYSCFG_PMCR_ETH_CLK_SEL; 210 } 211 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n"); 212 break; 213 default: 214 pr_debug("SYSCFG init : Do not manage %d interface\n", 215 plat_dat->mac_interface); 216 /* Do not manage others interfaces */ 217 return -EINVAL; 218 } 219 220 /* Need to update PMCCLRR (clear register) */ 221 regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET, 222 dwmac->ops->syscfg_eth_mask); 223 224 /* Update PMCSETR (set register) */ 225 return regmap_update_bits(dwmac->regmap, reg, 226 dwmac->ops->syscfg_eth_mask, val); 227 } 228 229 static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat) 230 { 231 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 232 u32 reg = dwmac->mode_reg; 233 int val; 234 235 switch (plat_dat->mac_interface) { 236 case PHY_INTERFACE_MODE_MII: 237 val = SYSCFG_MCU_ETH_SEL_MII; 238 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n"); 239 break; 240 case PHY_INTERFACE_MODE_RMII: 241 val = SYSCFG_MCU_ETH_SEL_RMII; 242 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n"); 243 break; 244 default: 245 pr_debug("SYSCFG init : Do not manage %d interface\n", 246 plat_dat->mac_interface); 247 /* Do not manage others interfaces */ 248 return -EINVAL; 249 } 250 251 return regmap_update_bits(dwmac->regmap, reg, 252 dwmac->ops->syscfg_eth_mask, val << 23); 253 } 254 255 static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) 256 { 257 clk_disable_unprepare(dwmac->clk_tx); 258 clk_disable_unprepare(dwmac->clk_rx); 259 260 if (dwmac->ops->clk_prepare) 261 dwmac->ops->clk_prepare(dwmac, false); 262 } 263 264 static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, 265 struct device *dev) 266 { 267 struct device_node *np = dev->of_node; 268 int err; 269 270 /* Get TX/RX clocks */ 271 dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx"); 272 if (IS_ERR(dwmac->clk_tx)) { 273 dev_err(dev, "No ETH Tx clock provided...\n"); 274 return PTR_ERR(dwmac->clk_tx); 275 } 276 277 dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx"); 278 if (IS_ERR(dwmac->clk_rx)) { 279 dev_err(dev, "No ETH Rx clock provided...\n"); 280 return PTR_ERR(dwmac->clk_rx); 281 } 282 283 if (dwmac->ops->parse_data) { 284 err = dwmac->ops->parse_data(dwmac, dev); 285 if (err) 286 return err; 287 } 288 289 /* Get mode register */ 290 dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); 291 if (IS_ERR(dwmac->regmap)) 292 return PTR_ERR(dwmac->regmap); 293 294 err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); 295 if (err) 296 dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err); 297 298 return err; 299 } 300 301 static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, 302 struct device *dev) 303 { 304 struct platform_device *pdev = to_platform_device(dev); 305 struct device_node *np = dev->of_node; 306 int err = 0; 307 308 /* Ethernet PHY have no crystal */ 309 dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); 310 311 /* Gigabit Ethernet 125MHz clock selection. */ 312 dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel"); 313 314 /* Ethernet 50Mhz RMII clock selection */ 315 dwmac->eth_ref_clk_sel_reg = 316 of_property_read_bool(np, "st,eth-ref-clk-sel"); 317 318 /* Get ETH_CLK clocks */ 319 dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck"); 320 if (IS_ERR(dwmac->clk_eth_ck)) { 321 dev_info(dev, "No phy clock provided...\n"); 322 dwmac->clk_eth_ck = NULL; 323 } 324 325 /* Clock used for low power mode */ 326 dwmac->clk_ethstp = devm_clk_get(dev, "ethstp"); 327 if (IS_ERR(dwmac->clk_ethstp)) { 328 dev_err(dev, 329 "No ETH peripheral clock provided for CStop mode ...\n"); 330 return PTR_ERR(dwmac->clk_ethstp); 331 } 332 333 /* Optional Clock for sysconfig */ 334 dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk"); 335 if (IS_ERR(dwmac->syscfg_clk)) 336 dwmac->syscfg_clk = NULL; 337 338 /* Get IRQ information early to have an ability to ask for deferred 339 * probe if needed before we went too far with resource allocation. 340 */ 341 dwmac->irq_pwr_wakeup = platform_get_irq_byname_optional(pdev, 342 "stm32_pwr_wakeup"); 343 if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER) 344 return -EPROBE_DEFER; 345 346 if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) { 347 err = device_init_wakeup(&pdev->dev, true); 348 if (err) { 349 dev_err(&pdev->dev, "Failed to init wake up irq\n"); 350 return err; 351 } 352 err = dev_pm_set_dedicated_wake_irq(&pdev->dev, 353 dwmac->irq_pwr_wakeup); 354 if (err) { 355 dev_err(&pdev->dev, "Failed to set wake up irq\n"); 356 device_init_wakeup(&pdev->dev, false); 357 } 358 device_set_wakeup_enable(&pdev->dev, false); 359 } 360 return err; 361 } 362 363 static int stm32_dwmac_probe(struct platform_device *pdev) 364 { 365 struct plat_stmmacenet_data *plat_dat; 366 struct stmmac_resources stmmac_res; 367 struct stm32_dwmac *dwmac; 368 const struct stm32_ops *data; 369 int ret; 370 371 ret = stmmac_get_platform_resources(pdev, &stmmac_res); 372 if (ret) 373 return ret; 374 375 plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac); 376 if (IS_ERR(plat_dat)) 377 return PTR_ERR(plat_dat); 378 379 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); 380 if (!dwmac) { 381 ret = -ENOMEM; 382 goto err_remove_config_dt; 383 } 384 385 data = of_device_get_match_data(&pdev->dev); 386 if (!data) { 387 dev_err(&pdev->dev, "no of match data provided\n"); 388 ret = -EINVAL; 389 goto err_remove_config_dt; 390 } 391 392 dwmac->ops = data; 393 dwmac->dev = &pdev->dev; 394 395 ret = stm32_dwmac_parse_data(dwmac, &pdev->dev); 396 if (ret) { 397 dev_err(&pdev->dev, "Unable to parse OF data\n"); 398 goto err_remove_config_dt; 399 } 400 401 plat_dat->bsp_priv = dwmac; 402 403 ret = stm32_dwmac_init(plat_dat); 404 if (ret) 405 goto err_remove_config_dt; 406 407 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 408 if (ret) 409 goto err_clk_disable; 410 411 return 0; 412 413 err_clk_disable: 414 stm32_dwmac_clk_disable(dwmac); 415 err_remove_config_dt: 416 stmmac_remove_config_dt(pdev, plat_dat); 417 418 return ret; 419 } 420 421 static void stm32_dwmac_remove(struct platform_device *pdev) 422 { 423 struct net_device *ndev = platform_get_drvdata(pdev); 424 struct stmmac_priv *priv = netdev_priv(ndev); 425 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 426 427 stmmac_dvr_remove(&pdev->dev); 428 429 stm32_dwmac_clk_disable(priv->plat->bsp_priv); 430 431 if (dwmac->irq_pwr_wakeup >= 0) { 432 dev_pm_clear_wake_irq(&pdev->dev); 433 device_init_wakeup(&pdev->dev, false); 434 } 435 } 436 437 static int stm32mp1_suspend(struct stm32_dwmac *dwmac) 438 { 439 int ret = 0; 440 441 ret = clk_prepare_enable(dwmac->clk_ethstp); 442 if (ret) 443 return ret; 444 445 clk_disable_unprepare(dwmac->clk_tx); 446 clk_disable_unprepare(dwmac->syscfg_clk); 447 if (dwmac->enable_eth_ck) 448 clk_disable_unprepare(dwmac->clk_eth_ck); 449 450 return ret; 451 } 452 453 static void stm32mp1_resume(struct stm32_dwmac *dwmac) 454 { 455 clk_disable_unprepare(dwmac->clk_ethstp); 456 } 457 458 static int stm32mcu_suspend(struct stm32_dwmac *dwmac) 459 { 460 clk_disable_unprepare(dwmac->clk_tx); 461 clk_disable_unprepare(dwmac->clk_rx); 462 463 return 0; 464 } 465 466 #ifdef CONFIG_PM_SLEEP 467 static int stm32_dwmac_suspend(struct device *dev) 468 { 469 struct net_device *ndev = dev_get_drvdata(dev); 470 struct stmmac_priv *priv = netdev_priv(ndev); 471 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 472 473 int ret; 474 475 ret = stmmac_suspend(dev); 476 477 if (dwmac->ops->suspend) 478 ret = dwmac->ops->suspend(dwmac); 479 480 return ret; 481 } 482 483 static int stm32_dwmac_resume(struct device *dev) 484 { 485 struct net_device *ndev = dev_get_drvdata(dev); 486 struct stmmac_priv *priv = netdev_priv(ndev); 487 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 488 int ret; 489 490 if (dwmac->ops->resume) 491 dwmac->ops->resume(dwmac); 492 493 ret = stm32_dwmac_init(priv->plat); 494 if (ret) 495 return ret; 496 497 ret = stmmac_resume(dev); 498 499 return ret; 500 } 501 #endif /* CONFIG_PM_SLEEP */ 502 503 static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops, 504 stm32_dwmac_suspend, stm32_dwmac_resume); 505 506 static struct stm32_ops stm32mcu_dwmac_data = { 507 .set_mode = stm32mcu_set_mode, 508 .suspend = stm32mcu_suspend, 509 .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK 510 }; 511 512 static struct stm32_ops stm32mp1_dwmac_data = { 513 .set_mode = stm32mp1_set_mode, 514 .clk_prepare = stm32mp1_clk_prepare, 515 .suspend = stm32mp1_suspend, 516 .resume = stm32mp1_resume, 517 .parse_data = stm32mp1_parse_data, 518 .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK, 519 .clk_rx_enable_in_suspend = true 520 }; 521 522 static const struct of_device_id stm32_dwmac_match[] = { 523 { .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data}, 524 { .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data}, 525 { } 526 }; 527 MODULE_DEVICE_TABLE(of, stm32_dwmac_match); 528 529 static struct platform_driver stm32_dwmac_driver = { 530 .probe = stm32_dwmac_probe, 531 .remove_new = stm32_dwmac_remove, 532 .driver = { 533 .name = "stm32-dwmac", 534 .pm = &stm32_dwmac_pm_ops, 535 .of_match_table = stm32_dwmac_match, 536 }, 537 }; 538 module_platform_driver(stm32_dwmac_driver); 539 540 MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@gmail.com>"); 541 MODULE_AUTHOR("Christophe Roullier <christophe.roullier@st.com>"); 542 MODULE_DESCRIPTION("STMicroelectronics STM32 DWMAC Specific Glue layer"); 543 MODULE_LICENSE("GPL v2"); 544