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_device.h> 15 #include <linux/of_net.h> 16 #include <linux/phy.h> 17 #include <linux/platform_device.h> 18 #include <linux/pm_wakeirq.h> 19 #include <linux/regmap.h> 20 #include <linux/slab.h> 21 #include <linux/stmmac.h> 22 23 #include "stmmac_platform.h" 24 25 #define SYSCFG_MCU_ETH_MASK BIT(23) 26 #define SYSCFG_MP1_ETH_MASK GENMASK(23, 16) 27 #define SYSCFG_PMCCLRR_OFFSET 0x40 28 29 #define SYSCFG_PMCR_ETH_CLK_SEL BIT(16) 30 #define SYSCFG_PMCR_ETH_REF_CLK_SEL BIT(17) 31 32 /* CLOCK feed to PHY*/ 33 #define ETH_CK_F_25M 25000000 34 #define ETH_CK_F_50M 50000000 35 #define ETH_CK_F_125M 125000000 36 37 /* Ethernet PHY interface selection in register SYSCFG Configuration 38 *------------------------------------------ 39 * src |BIT(23)| BIT(22)| BIT(21)|BIT(20)| 40 *------------------------------------------ 41 * MII | 0 | 0 | 0 | 1 | 42 *------------------------------------------ 43 * GMII | 0 | 0 | 0 | 0 | 44 *------------------------------------------ 45 * RGMII | 0 | 0 | 1 | n/a | 46 *------------------------------------------ 47 * RMII | 1 | 0 | 0 | n/a | 48 *------------------------------------------ 49 */ 50 #define SYSCFG_PMCR_ETH_SEL_MII BIT(20) 51 #define SYSCFG_PMCR_ETH_SEL_RGMII BIT(21) 52 #define SYSCFG_PMCR_ETH_SEL_RMII BIT(23) 53 #define SYSCFG_PMCR_ETH_SEL_GMII 0 54 #define SYSCFG_MCU_ETH_SEL_MII 0 55 #define SYSCFG_MCU_ETH_SEL_RMII 1 56 57 /* STM32MP1 register definitions 58 * 59 * Below table summarizes the clock requirement and clock sources for 60 * supported phy interface modes. 61 * __________________________________________________________________________ 62 *|PHY_MODE | Normal | PHY wo crystal| PHY wo crystal |No 125Mhz from PHY| 63 *| | | 25MHz | 50MHz | | 64 * --------------------------------------------------------------------------- 65 *| MII | - | eth-ck | n/a | n/a | 66 *| | | st,ext-phyclk | | | 67 * --------------------------------------------------------------------------- 68 *| GMII | - | eth-ck | n/a | n/a | 69 *| | | st,ext-phyclk | | | 70 * --------------------------------------------------------------------------- 71 *| RGMII | - | eth-ck | n/a | eth-ck | 72 *| | | st,ext-phyclk | | st,eth-clk-sel or| 73 *| | | | | st,ext-phyclk | 74 * --------------------------------------------------------------------------- 75 *| RMII | - | eth-ck | eth-ck | n/a | 76 *| | | st,ext-phyclk | st,eth-ref-clk-sel | | 77 *| | | | or st,ext-phyclk | | 78 * --------------------------------------------------------------------------- 79 * 80 */ 81 82 struct stm32_dwmac { 83 struct clk *clk_tx; 84 struct clk *clk_rx; 85 struct clk *clk_eth_ck; 86 struct clk *clk_ethstp; 87 struct clk *syscfg_clk; 88 int ext_phyclk; 89 int enable_eth_ck; 90 int eth_clk_sel_reg; 91 int eth_ref_clk_sel_reg; 92 int irq_pwr_wakeup; 93 u32 mode_reg; /* MAC glue-logic mode register */ 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 (*clk_prepare)(struct stm32_dwmac *dwmac, bool prepare); 103 int (*suspend)(struct stm32_dwmac *dwmac); 104 void (*resume)(struct stm32_dwmac *dwmac); 105 int (*parse_data)(struct stm32_dwmac *dwmac, 106 struct device *dev); 107 u32 syscfg_eth_mask; 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->dev->power.is_suspended) { 126 ret = clk_prepare_enable(dwmac->clk_rx); 127 if (ret) { 128 clk_disable_unprepare(dwmac->clk_tx); 129 return ret; 130 } 131 } 132 133 if (dwmac->ops->clk_prepare) { 134 ret = dwmac->ops->clk_prepare(dwmac, true); 135 if (ret) { 136 clk_disable_unprepare(dwmac->clk_rx); 137 clk_disable_unprepare(dwmac->clk_tx); 138 } 139 } 140 141 return ret; 142 } 143 144 static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare) 145 { 146 int ret = 0; 147 148 if (prepare) { 149 ret = clk_prepare_enable(dwmac->syscfg_clk); 150 if (ret) 151 return ret; 152 if (dwmac->enable_eth_ck) { 153 ret = clk_prepare_enable(dwmac->clk_eth_ck); 154 if (ret) { 155 clk_disable_unprepare(dwmac->syscfg_clk); 156 return ret; 157 } 158 } 159 } else { 160 clk_disable_unprepare(dwmac->syscfg_clk); 161 if (dwmac->enable_eth_ck) 162 clk_disable_unprepare(dwmac->clk_eth_ck); 163 } 164 return ret; 165 } 166 167 static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat) 168 { 169 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 170 u32 reg = dwmac->mode_reg, clk_rate; 171 int val; 172 173 clk_rate = clk_get_rate(dwmac->clk_eth_ck); 174 dwmac->enable_eth_ck = false; 175 switch (plat_dat->interface) { 176 case PHY_INTERFACE_MODE_MII: 177 if (clk_rate == ETH_CK_F_25M && dwmac->ext_phyclk) 178 dwmac->enable_eth_ck = true; 179 val = SYSCFG_PMCR_ETH_SEL_MII; 180 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n"); 181 break; 182 case PHY_INTERFACE_MODE_GMII: 183 val = SYSCFG_PMCR_ETH_SEL_GMII; 184 if (clk_rate == ETH_CK_F_25M && 185 (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) { 186 dwmac->enable_eth_ck = true; 187 val |= SYSCFG_PMCR_ETH_CLK_SEL; 188 } 189 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_GMII\n"); 190 break; 191 case PHY_INTERFACE_MODE_RMII: 192 val = SYSCFG_PMCR_ETH_SEL_RMII; 193 if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) && 194 (dwmac->eth_ref_clk_sel_reg || dwmac->ext_phyclk)) { 195 dwmac->enable_eth_ck = true; 196 val |= SYSCFG_PMCR_ETH_REF_CLK_SEL; 197 } 198 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n"); 199 break; 200 case PHY_INTERFACE_MODE_RGMII: 201 case PHY_INTERFACE_MODE_RGMII_ID: 202 case PHY_INTERFACE_MODE_RGMII_RXID: 203 case PHY_INTERFACE_MODE_RGMII_TXID: 204 val = SYSCFG_PMCR_ETH_SEL_RGMII; 205 if ((clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) && 206 (dwmac->eth_clk_sel_reg || dwmac->ext_phyclk)) { 207 dwmac->enable_eth_ck = true; 208 val |= SYSCFG_PMCR_ETH_CLK_SEL; 209 } 210 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RGMII\n"); 211 break; 212 default: 213 pr_debug("SYSCFG init : Do not manage %d interface\n", 214 plat_dat->interface); 215 /* Do not manage others interfaces */ 216 return -EINVAL; 217 } 218 219 /* Need to update PMCCLRR (clear register) */ 220 regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET, 221 dwmac->ops->syscfg_eth_mask); 222 223 /* Update PMCSETR (set register) */ 224 return regmap_update_bits(dwmac->regmap, reg, 225 dwmac->ops->syscfg_eth_mask, val); 226 } 227 228 static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat) 229 { 230 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 231 u32 reg = dwmac->mode_reg; 232 int val; 233 234 switch (plat_dat->interface) { 235 case PHY_INTERFACE_MODE_MII: 236 val = SYSCFG_MCU_ETH_SEL_MII; 237 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_MII\n"); 238 break; 239 case PHY_INTERFACE_MODE_RMII: 240 val = SYSCFG_MCU_ETH_SEL_RMII; 241 pr_debug("SYSCFG init : PHY_INTERFACE_MODE_RMII\n"); 242 break; 243 default: 244 pr_debug("SYSCFG init : Do not manage %d interface\n", 245 plat_dat->interface); 246 /* Do not manage others interfaces */ 247 return -EINVAL; 248 } 249 250 return regmap_update_bits(dwmac->regmap, reg, 251 dwmac->ops->syscfg_eth_mask, val << 23); 252 } 253 254 static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) 255 { 256 clk_disable_unprepare(dwmac->clk_tx); 257 clk_disable_unprepare(dwmac->clk_rx); 258 259 if (dwmac->ops->clk_prepare) 260 dwmac->ops->clk_prepare(dwmac, false); 261 } 262 263 static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, 264 struct device *dev) 265 { 266 struct device_node *np = dev->of_node; 267 int err; 268 269 /* Get TX/RX clocks */ 270 dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx"); 271 if (IS_ERR(dwmac->clk_tx)) { 272 dev_err(dev, "No ETH Tx clock provided...\n"); 273 return PTR_ERR(dwmac->clk_tx); 274 } 275 276 dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx"); 277 if (IS_ERR(dwmac->clk_rx)) { 278 dev_err(dev, "No ETH Rx clock provided...\n"); 279 return PTR_ERR(dwmac->clk_rx); 280 } 281 282 if (dwmac->ops->parse_data) { 283 err = dwmac->ops->parse_data(dwmac, dev); 284 if (err) 285 return err; 286 } 287 288 /* Get mode register */ 289 dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); 290 if (IS_ERR(dwmac->regmap)) 291 return PTR_ERR(dwmac->regmap); 292 293 err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); 294 if (err) 295 dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err); 296 297 return err; 298 } 299 300 static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, 301 struct device *dev) 302 { 303 struct platform_device *pdev = to_platform_device(dev); 304 struct device_node *np = dev->of_node; 305 int err = 0; 306 307 /* Ethernet PHY have no crystal */ 308 dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); 309 310 /* Gigabit Ethernet 125MHz clock selection. */ 311 dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel"); 312 313 /* Ethernet 50Mhz RMII clock selection */ 314 dwmac->eth_ref_clk_sel_reg = 315 of_property_read_bool(np, "st,eth-ref-clk-sel"); 316 317 /* Get ETH_CLK clocks */ 318 dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck"); 319 if (IS_ERR(dwmac->clk_eth_ck)) { 320 dev_info(dev, "No phy clock provided...\n"); 321 dwmac->clk_eth_ck = NULL; 322 } 323 324 /* Clock used for low power mode */ 325 dwmac->clk_ethstp = devm_clk_get(dev, "ethstp"); 326 if (IS_ERR(dwmac->clk_ethstp)) { 327 dev_err(dev, 328 "No ETH peripheral clock provided for CStop mode ...\n"); 329 return PTR_ERR(dwmac->clk_ethstp); 330 } 331 332 /* Optional Clock for sysconfig */ 333 dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk"); 334 if (IS_ERR(dwmac->syscfg_clk)) 335 dwmac->syscfg_clk = NULL; 336 337 /* Get IRQ information early to have an ability to ask for deferred 338 * probe if needed before we went too far with resource allocation. 339 */ 340 dwmac->irq_pwr_wakeup = platform_get_irq_byname_optional(pdev, 341 "stm32_pwr_wakeup"); 342 if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER) 343 return -EPROBE_DEFER; 344 345 if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) { 346 err = device_init_wakeup(&pdev->dev, true); 347 if (err) { 348 dev_err(&pdev->dev, "Failed to init wake up irq\n"); 349 return err; 350 } 351 err = dev_pm_set_dedicated_wake_irq(&pdev->dev, 352 dwmac->irq_pwr_wakeup); 353 if (err) { 354 dev_err(&pdev->dev, "Failed to set wake up irq\n"); 355 device_init_wakeup(&pdev->dev, false); 356 } 357 device_set_wakeup_enable(&pdev->dev, false); 358 } 359 return err; 360 } 361 362 static int stm32_dwmac_probe(struct platform_device *pdev) 363 { 364 struct plat_stmmacenet_data *plat_dat; 365 struct stmmac_resources stmmac_res; 366 struct stm32_dwmac *dwmac; 367 const struct stm32_ops *data; 368 int ret; 369 370 ret = stmmac_get_platform_resources(pdev, &stmmac_res); 371 if (ret) 372 return ret; 373 374 plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac); 375 if (IS_ERR(plat_dat)) 376 return PTR_ERR(plat_dat); 377 378 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); 379 if (!dwmac) { 380 ret = -ENOMEM; 381 goto err_remove_config_dt; 382 } 383 384 data = of_device_get_match_data(&pdev->dev); 385 if (!data) { 386 dev_err(&pdev->dev, "no of match data provided\n"); 387 ret = -EINVAL; 388 goto err_remove_config_dt; 389 } 390 391 dwmac->ops = data; 392 dwmac->dev = &pdev->dev; 393 394 ret = stm32_dwmac_parse_data(dwmac, &pdev->dev); 395 if (ret) { 396 dev_err(&pdev->dev, "Unable to parse OF data\n"); 397 goto err_remove_config_dt; 398 } 399 400 plat_dat->bsp_priv = dwmac; 401 402 ret = stm32_dwmac_init(plat_dat); 403 if (ret) 404 goto err_remove_config_dt; 405 406 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 407 if (ret) 408 goto err_clk_disable; 409 410 return 0; 411 412 err_clk_disable: 413 stm32_dwmac_clk_disable(dwmac); 414 err_remove_config_dt: 415 stmmac_remove_config_dt(pdev, plat_dat); 416 417 return ret; 418 } 419 420 static int stm32_dwmac_remove(struct platform_device *pdev) 421 { 422 struct net_device *ndev = platform_get_drvdata(pdev); 423 struct stmmac_priv *priv = netdev_priv(ndev); 424 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 425 426 stmmac_dvr_remove(&pdev->dev); 427 428 stm32_dwmac_clk_disable(priv->plat->bsp_priv); 429 430 if (dwmac->irq_pwr_wakeup >= 0) { 431 dev_pm_clear_wake_irq(&pdev->dev); 432 device_init_wakeup(&pdev->dev, false); 433 } 434 435 return 0; 436 } 437 438 static int stm32mp1_suspend(struct stm32_dwmac *dwmac) 439 { 440 int ret = 0; 441 442 ret = clk_prepare_enable(dwmac->clk_ethstp); 443 if (ret) 444 return ret; 445 446 clk_disable_unprepare(dwmac->clk_tx); 447 clk_disable_unprepare(dwmac->syscfg_clk); 448 if (dwmac->enable_eth_ck) 449 clk_disable_unprepare(dwmac->clk_eth_ck); 450 451 return ret; 452 } 453 454 static void stm32mp1_resume(struct stm32_dwmac *dwmac) 455 { 456 clk_disable_unprepare(dwmac->clk_ethstp); 457 } 458 459 static int stm32mcu_suspend(struct stm32_dwmac *dwmac) 460 { 461 clk_disable_unprepare(dwmac->clk_tx); 462 clk_disable_unprepare(dwmac->clk_rx); 463 464 return 0; 465 } 466 467 #ifdef CONFIG_PM_SLEEP 468 static int stm32_dwmac_suspend(struct device *dev) 469 { 470 struct net_device *ndev = dev_get_drvdata(dev); 471 struct stmmac_priv *priv = netdev_priv(ndev); 472 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 473 474 int ret; 475 476 ret = stmmac_suspend(dev); 477 478 if (dwmac->ops->suspend) 479 ret = dwmac->ops->suspend(dwmac); 480 481 return ret; 482 } 483 484 static int stm32_dwmac_resume(struct device *dev) 485 { 486 struct net_device *ndev = dev_get_drvdata(dev); 487 struct stmmac_priv *priv = netdev_priv(ndev); 488 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; 489 int ret; 490 491 if (dwmac->ops->resume) 492 dwmac->ops->resume(dwmac); 493 494 ret = stm32_dwmac_init(priv->plat); 495 if (ret) 496 return ret; 497 498 ret = stmmac_resume(dev); 499 500 return ret; 501 } 502 #endif /* CONFIG_PM_SLEEP */ 503 504 static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops, 505 stm32_dwmac_suspend, stm32_dwmac_resume); 506 507 static struct stm32_ops stm32mcu_dwmac_data = { 508 .set_mode = stm32mcu_set_mode, 509 .suspend = stm32mcu_suspend, 510 .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK 511 }; 512 513 static struct stm32_ops stm32mp1_dwmac_data = { 514 .set_mode = stm32mp1_set_mode, 515 .clk_prepare = stm32mp1_clk_prepare, 516 .suspend = stm32mp1_suspend, 517 .resume = stm32mp1_resume, 518 .parse_data = stm32mp1_parse_data, 519 .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK 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 = 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