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 = devm_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 return -ENOMEM; 382 383 data = of_device_get_match_data(&pdev->dev); 384 if (!data) { 385 dev_err(&pdev->dev, "no of match data provided\n"); 386 return -EINVAL; 387 } 388 389 dwmac->ops = data; 390 dwmac->dev = &pdev->dev; 391 392 ret = stm32_dwmac_parse_data(dwmac, &pdev->dev); 393 if (ret) { 394 dev_err(&pdev->dev, "Unable to parse OF data\n"); 395 return ret; 396 } 397 398 plat_dat->bsp_priv = dwmac; 399 400 ret = stm32_dwmac_init(plat_dat); 401 if (ret) 402 return ret; 403 404 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 405 if (ret) 406 goto err_clk_disable; 407 408 return 0; 409 410 err_clk_disable: 411 stm32_dwmac_clk_disable(dwmac); 412 413 return ret; 414 } 415 416 static void stm32_dwmac_remove(struct platform_device *pdev) 417 { 418 struct net_device *ndev = platform_get_drvdata(pdev); 419 struct stmmac_priv *priv = netdev_priv(ndev); 420 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 421 422 stmmac_dvr_remove(&pdev->dev); 423 424 stm32_dwmac_clk_disable(priv->plat->bsp_priv); 425 426 if (dwmac->irq_pwr_wakeup >= 0) { 427 dev_pm_clear_wake_irq(&pdev->dev); 428 device_init_wakeup(&pdev->dev, false); 429 } 430 } 431 432 static int stm32mp1_suspend(struct stm32_dwmac *dwmac) 433 { 434 int ret = 0; 435 436 ret = clk_prepare_enable(dwmac->clk_ethstp); 437 if (ret) 438 return ret; 439 440 clk_disable_unprepare(dwmac->clk_tx); 441 clk_disable_unprepare(dwmac->syscfg_clk); 442 if (dwmac->enable_eth_ck) 443 clk_disable_unprepare(dwmac->clk_eth_ck); 444 445 return ret; 446 } 447 448 static void stm32mp1_resume(struct stm32_dwmac *dwmac) 449 { 450 clk_disable_unprepare(dwmac->clk_ethstp); 451 } 452 453 static int stm32mcu_suspend(struct stm32_dwmac *dwmac) 454 { 455 clk_disable_unprepare(dwmac->clk_tx); 456 clk_disable_unprepare(dwmac->clk_rx); 457 458 return 0; 459 } 460 461 #ifdef CONFIG_PM_SLEEP 462 static int stm32_dwmac_suspend(struct device *dev) 463 { 464 struct net_device *ndev = dev_get_drvdata(dev); 465 struct stmmac_priv *priv = netdev_priv(ndev); 466 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 467 468 int ret; 469 470 ret = stmmac_suspend(dev); 471 472 if (dwmac->ops->suspend) 473 ret = dwmac->ops->suspend(dwmac); 474 475 return ret; 476 } 477 478 static int stm32_dwmac_resume(struct device *dev) 479 { 480 struct net_device *ndev = dev_get_drvdata(dev); 481 struct stmmac_priv *priv = netdev_priv(ndev); 482 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 483 int ret; 484 485 if (dwmac->ops->resume) 486 dwmac->ops->resume(dwmac); 487 488 ret = stm32_dwmac_init(priv->plat); 489 if (ret) 490 return ret; 491 492 ret = stmmac_resume(dev); 493 494 return ret; 495 } 496 #endif /* CONFIG_PM_SLEEP */ 497 498 static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops, 499 stm32_dwmac_suspend, stm32_dwmac_resume); 500 501 static struct stm32_ops stm32mcu_dwmac_data = { 502 .set_mode = stm32mcu_set_mode, 503 .suspend = stm32mcu_suspend, 504 .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK 505 }; 506 507 static struct stm32_ops stm32mp1_dwmac_data = { 508 .set_mode = stm32mp1_set_mode, 509 .clk_prepare = stm32mp1_clk_prepare, 510 .suspend = stm32mp1_suspend, 511 .resume = stm32mp1_resume, 512 .parse_data = stm32mp1_parse_data, 513 .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK, 514 .clk_rx_enable_in_suspend = true 515 }; 516 517 static const struct of_device_id stm32_dwmac_match[] = { 518 { .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data}, 519 { .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data}, 520 { } 521 }; 522 MODULE_DEVICE_TABLE(of, stm32_dwmac_match); 523 524 static struct platform_driver stm32_dwmac_driver = { 525 .probe = stm32_dwmac_probe, 526 .remove_new = stm32_dwmac_remove, 527 .driver = { 528 .name = "stm32-dwmac", 529 .pm = &stm32_dwmac_pm_ops, 530 .of_match_table = stm32_dwmac_match, 531 }, 532 }; 533 module_platform_driver(stm32_dwmac_driver); 534 535 MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@gmail.com>"); 536 MODULE_AUTHOR("Christophe Roullier <christophe.roullier@st.com>"); 537 MODULE_DESCRIPTION("STMicroelectronics STM32 DWMAC Specific Glue layer"); 538 MODULE_LICENSE("GPL v2"); 539