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