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