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