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