Lines Matching +full:eth +full:- +full:mac

1 // SPDX-License-Identifier: GPL-2.0-only
3 * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU
37 *------------------------------------------
39 *------------------------------------------
41 *------------------------------------------
43 *------------------------------------------
45 *------------------------------------------
47 *------------------------------------------
74 * ---------------------------------------------------------------------------
75 *| MII | - | eth-ck | n/a | n/a |
76 *| | | st,ext-phyclk | | |
77 * ---------------------------------------------------------------------------
78 *| GMII | - | eth-ck | n/a | n/a |
79 *| | | st,ext-phyclk | | |
80 * ---------------------------------------------------------------------------
81 *| RGMII | - | eth-ck | n/a | eth-ck |
82 *| | | st,ext-phyclk | | st,eth-clk-sel or|
83 *| | | | | st,ext-phyclk |
84 * ---------------------------------------------------------------------------
85 *| RMII | - | eth-ck | eth-ck | n/a |
86 *| | | st,ext-phyclk | st,eth-ref-clk-sel | |
87 *| | | | or st,ext-phyclk | |
88 * ---------------------------------------------------------------------------
103 u32 mode_reg; /* MAC glue-logic mode register */
126 ret = clk_prepare_enable(dwmac->clk_tx); in stm32_dwmac_clk_enable()
130 ret = clk_prepare_enable(dwmac->clk_rx); in stm32_dwmac_clk_enable()
134 ret = clk_prepare_enable(dwmac->syscfg_clk); in stm32_dwmac_clk_enable()
138 if (dwmac->enable_eth_ck) { in stm32_dwmac_clk_enable()
139 ret = clk_prepare_enable(dwmac->clk_eth_ck); in stm32_dwmac_clk_enable()
147 clk_disable_unprepare(dwmac->syscfg_clk); in stm32_dwmac_clk_enable()
149 clk_disable_unprepare(dwmac->clk_rx); in stm32_dwmac_clk_enable()
151 clk_disable_unprepare(dwmac->clk_tx); in stm32_dwmac_clk_enable()
158 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; in stm32_dwmac_init()
161 if (dwmac->ops->set_mode) { in stm32_dwmac_init()
162 ret = dwmac->ops->set_mode(plat_dat); in stm32_dwmac_init()
172 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; in stm32mp1_select_ethck_external()
174 switch (plat_dat->mac_interface) { in stm32mp1_select_ethck_external()
176 dwmac->enable_eth_ck = dwmac->ext_phyclk; in stm32mp1_select_ethck_external()
179 dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg || in stm32mp1_select_ethck_external()
180 dwmac->ext_phyclk; in stm32mp1_select_ethck_external()
183 dwmac->enable_eth_ck = dwmac->eth_ref_clk_sel_reg || in stm32mp1_select_ethck_external()
184 dwmac->ext_phyclk; in stm32mp1_select_ethck_external()
190 dwmac->enable_eth_ck = dwmac->eth_clk_sel_reg || in stm32mp1_select_ethck_external()
191 dwmac->ext_phyclk; in stm32mp1_select_ethck_external()
194 dwmac->enable_eth_ck = false; in stm32mp1_select_ethck_external()
195 dev_err(dwmac->dev, "Mode %s not supported", in stm32mp1_select_ethck_external()
196 phy_modes(plat_dat->mac_interface)); in stm32mp1_select_ethck_external()
197 return -EINVAL; in stm32mp1_select_ethck_external()
203 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; in stm32mp1_validate_ethck_rate()
204 const u32 clk_rate = clk_get_rate(dwmac->clk_eth_ck); in stm32mp1_validate_ethck_rate()
206 if (!dwmac->enable_eth_ck) in stm32mp1_validate_ethck_rate()
209 switch (plat_dat->mac_interface) { in stm32mp1_validate_ethck_rate()
230 dev_err(dwmac->dev, "Mode %s does not match eth-ck frequency %d Hz", in stm32mp1_validate_ethck_rate()
231 phy_modes(plat_dat->mac_interface), clk_rate); in stm32mp1_validate_ethck_rate()
232 return -EINVAL; in stm32mp1_validate_ethck_rate()
237 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; in stm32mp1_configure_pmcr()
238 u32 reg = dwmac->mode_reg; in stm32mp1_configure_pmcr()
241 switch (plat_dat->mac_interface) { in stm32mp1_configure_pmcr()
249 if (!dwmac->ops->is_mp13) /* Select MII mode on STM32MP15xx */ in stm32mp1_configure_pmcr()
254 if (dwmac->enable_eth_ck) in stm32mp1_configure_pmcr()
259 if (dwmac->enable_eth_ck) in stm32mp1_configure_pmcr()
267 if (dwmac->enable_eth_ck) in stm32mp1_configure_pmcr()
271 dev_err(dwmac->dev, "Mode %s not supported", in stm32mp1_configure_pmcr()
272 phy_modes(plat_dat->mac_interface)); in stm32mp1_configure_pmcr()
274 return -EINVAL; in stm32mp1_configure_pmcr()
277 dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface)); in stm32mp1_configure_pmcr()
279 /* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */ in stm32mp1_configure_pmcr()
280 val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK); in stm32mp1_configure_pmcr()
283 regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off, in stm32mp1_configure_pmcr()
284 dwmac->mode_mask); in stm32mp1_configure_pmcr()
287 return regmap_update_bits(dwmac->regmap, reg, in stm32mp1_configure_pmcr()
288 dwmac->mode_mask, val); in stm32mp1_configure_pmcr()
293 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; in stm32mp2_configure_syscfg()
294 u32 reg = dwmac->mode_reg; in stm32mp2_configure_syscfg()
297 switch (plat_dat->mac_interface) { in stm32mp2_configure_syscfg()
303 if (dwmac->enable_eth_ck) { in stm32mp2_configure_syscfg()
315 if (dwmac->enable_eth_ck) { in stm32mp2_configure_syscfg()
321 dev_err(dwmac->dev, "Mode %s not supported", in stm32mp2_configure_syscfg()
322 phy_modes(plat_dat->mac_interface)); in stm32mp2_configure_syscfg()
324 return -EINVAL; in stm32mp2_configure_syscfg()
327 dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface)); in stm32mp2_configure_syscfg()
333 return regmap_update_bits(dwmac->regmap, reg, in stm32mp2_configure_syscfg()
339 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; in stm32mp1_set_mode()
350 if (!dwmac->ops->is_mp2) in stm32mp1_set_mode()
358 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; in stm32mcu_set_mode()
359 u32 reg = dwmac->mode_reg; in stm32mcu_set_mode()
362 switch (plat_dat->mac_interface) { in stm32mcu_set_mode()
370 dev_err(dwmac->dev, "Mode %s not supported", in stm32mcu_set_mode()
371 phy_modes(plat_dat->mac_interface)); in stm32mcu_set_mode()
373 return -EINVAL; in stm32mcu_set_mode()
376 dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface)); in stm32mcu_set_mode()
378 return regmap_update_bits(dwmac->regmap, reg, in stm32mcu_set_mode()
384 clk_disable_unprepare(dwmac->clk_tx); in stm32_dwmac_clk_disable()
385 clk_disable_unprepare(dwmac->clk_rx); in stm32_dwmac_clk_disable()
386 clk_disable_unprepare(dwmac->syscfg_clk); in stm32_dwmac_clk_disable()
387 if (dwmac->enable_eth_ck) in stm32_dwmac_clk_disable()
388 clk_disable_unprepare(dwmac->clk_eth_ck); in stm32_dwmac_clk_disable()
394 struct device_node *np = dev->of_node; in stm32_dwmac_parse_data()
398 dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx"); in stm32_dwmac_parse_data()
399 if (IS_ERR(dwmac->clk_tx)) { in stm32_dwmac_parse_data()
400 dev_err(dev, "No ETH Tx clock provided...\n"); in stm32_dwmac_parse_data()
401 return PTR_ERR(dwmac->clk_tx); in stm32_dwmac_parse_data()
404 dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx"); in stm32_dwmac_parse_data()
405 if (IS_ERR(dwmac->clk_rx)) { in stm32_dwmac_parse_data()
406 dev_err(dev, "No ETH Rx clock provided...\n"); in stm32_dwmac_parse_data()
407 return PTR_ERR(dwmac->clk_rx); in stm32_dwmac_parse_data()
410 if (dwmac->ops->parse_data) { in stm32_dwmac_parse_data()
411 err = dwmac->ops->parse_data(dwmac, dev); in stm32_dwmac_parse_data()
417 dwmac->regmap = syscon_regmap_lookup_by_phandle_args(np, "st,syscon", in stm32_dwmac_parse_data()
418 1, &dwmac->mode_reg); in stm32_dwmac_parse_data()
419 if (IS_ERR(dwmac->regmap)) in stm32_dwmac_parse_data()
420 return PTR_ERR(dwmac->regmap); in stm32_dwmac_parse_data()
422 if (dwmac->ops->is_mp2) in stm32_dwmac_parse_data()
425 dwmac->mode_mask = SYSCFG_MP1_ETH_MASK; in stm32_dwmac_parse_data()
426 err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask); in stm32_dwmac_parse_data()
428 if (dwmac->ops->is_mp13) { in stm32_dwmac_parse_data()
443 struct device_node *np = dev->of_node; in stm32mp1_parse_data()
447 dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); in stm32mp1_parse_data()
450 dwmac->eth_clk_sel_reg = of_property_read_bool(np, "st,eth-clk-sel"); in stm32mp1_parse_data()
453 dwmac->eth_ref_clk_sel_reg = in stm32mp1_parse_data()
454 of_property_read_bool(np, "st,eth-ref-clk-sel"); in stm32mp1_parse_data()
457 dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck"); in stm32mp1_parse_data()
458 if (IS_ERR(dwmac->clk_eth_ck)) { in stm32mp1_parse_data()
460 dwmac->clk_eth_ck = NULL; in stm32mp1_parse_data()
464 dwmac->clk_ethstp = devm_clk_get(dev, "ethstp"); in stm32mp1_parse_data()
465 if (IS_ERR(dwmac->clk_ethstp)) { in stm32mp1_parse_data()
467 "No ETH peripheral clock provided for CStop mode ...\n"); in stm32mp1_parse_data()
468 return PTR_ERR(dwmac->clk_ethstp); in stm32mp1_parse_data()
472 dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk"); in stm32mp1_parse_data()
473 if (IS_ERR(dwmac->syscfg_clk)) in stm32mp1_parse_data()
474 dwmac->syscfg_clk = NULL; in stm32mp1_parse_data()
479 dwmac->irq_pwr_wakeup = platform_get_irq_byname_optional(pdev, in stm32mp1_parse_data()
481 if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER) in stm32mp1_parse_data()
482 return -EPROBE_DEFER; in stm32mp1_parse_data()
484 if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) { in stm32mp1_parse_data()
485 err = device_init_wakeup(&pdev->dev, true); in stm32mp1_parse_data()
487 dev_err(&pdev->dev, "Failed to init wake up irq\n"); in stm32mp1_parse_data()
490 err = dev_pm_set_dedicated_wake_irq(&pdev->dev, in stm32mp1_parse_data()
491 dwmac->irq_pwr_wakeup); in stm32mp1_parse_data()
493 dev_err(&pdev->dev, "Failed to set wake up irq\n"); in stm32mp1_parse_data()
494 device_init_wakeup(&pdev->dev, false); in stm32mp1_parse_data()
496 device_set_wakeup_enable(&pdev->dev, false); in stm32mp1_parse_data()
513 plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac); in stm32_dwmac_probe()
517 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); in stm32_dwmac_probe()
519 return -ENOMEM; in stm32_dwmac_probe()
521 data = of_device_get_match_data(&pdev->dev); in stm32_dwmac_probe()
523 dev_err(&pdev->dev, "no of match data provided\n"); in stm32_dwmac_probe()
524 return -EINVAL; in stm32_dwmac_probe()
527 dwmac->ops = data; in stm32_dwmac_probe()
528 dwmac->dev = &pdev->dev; in stm32_dwmac_probe()
530 ret = stm32_dwmac_parse_data(dwmac, &pdev->dev); in stm32_dwmac_probe()
532 dev_err(&pdev->dev, "Unable to parse OF data\n"); in stm32_dwmac_probe()
536 plat_dat->flags |= STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP; in stm32_dwmac_probe()
537 plat_dat->bsp_priv = dwmac; in stm32_dwmac_probe()
547 if (dwmac->ops->clk_rx_enable_in_suspend) { in stm32_dwmac_probe()
548 ret = clk_prepare_enable(dwmac->clk_rx); in stm32_dwmac_probe()
553 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); in stm32_dwmac_probe()
560 if (dwmac->ops->clk_rx_enable_in_suspend) in stm32_dwmac_probe()
561 clk_disable_unprepare(dwmac->clk_rx); in stm32_dwmac_probe()
573 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; in stm32_dwmac_remove()
575 stmmac_dvr_remove(&pdev->dev); in stm32_dwmac_remove()
582 if (dwmac->ops->clk_rx_enable_in_suspend) in stm32_dwmac_remove()
583 clk_disable_unprepare(dwmac->clk_rx); in stm32_dwmac_remove()
587 if (dwmac->irq_pwr_wakeup >= 0) { in stm32_dwmac_remove()
588 dev_pm_clear_wake_irq(&pdev->dev); in stm32_dwmac_remove()
589 device_init_wakeup(&pdev->dev, false); in stm32_dwmac_remove()
595 return clk_prepare_enable(dwmac->clk_ethstp); in stm32mp1_suspend()
600 clk_disable_unprepare(dwmac->clk_ethstp); in stm32mp1_resume()
608 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; in stm32_dwmac_suspend()
618 if (dwmac->ops->suspend) in stm32_dwmac_suspend()
619 ret = dwmac->ops->suspend(dwmac); in stm32_dwmac_suspend()
628 struct stm32_dwmac *dwmac = priv->plat->bsp_priv; in stm32_dwmac_resume()
631 if (dwmac->ops->resume) in stm32_dwmac_resume()
632 dwmac->ops->resume(dwmac); in stm32_dwmac_resume()
634 ret = stm32_dwmac_init(priv->plat); in stm32_dwmac_resume()
681 { .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
682 { .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
683 { .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data},
684 { .compatible = "st,stm32mp25-dwmac", .data = &stm32mp25_dwmac_data},
693 .name = "stm32-dwmac",