switch (plat_dat->mac_interface) { case PHY_INTERFACE_MODE_MII: case PHY_INTERFACE_MODE_GMII: if (clk_rate == ETH_CK_F_25M) return 0; break; case PHY_INTERFACE_MODE_RMII: if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_50M) return 0; break; case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID: if (clk_rate == ETH_CK_F_25M || clk_rate == ETH_CK_F_125M) return 0; break; default: break;
}
dev_err(dwmac->dev, "Mode %s does not match eth-ck frequency %d Hz",
phy_modes(plat_dat->mac_interface), clk_rate); return -EINVAL;
}
staticint stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
{ struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
u32 reg = dwmac->mode_reg; int val = 0;
switch (plat_dat->mac_interface) { case PHY_INTERFACE_MODE_MII: /* * STM32MP15xx supports both MII and GMII, STM32MP13xx MII only. * SYSCFG_PMCSETR ETH_SELMII is present only on STM32MP15xx and * acts as a selector between 0:GMII and 1:MII. As STM32MP13xx * supports only MII, ETH_SELMII is not present.
*/ if (!dwmac->ops->is_mp13) /* Select MII mode on STM32MP15xx */
val |= SYSCFG_PMCR_ETH_SEL_MII; break; case PHY_INTERFACE_MODE_GMII:
val = SYSCFG_PMCR_ETH_SEL_GMII; if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL; break; case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_PMCR_ETH_SEL_RMII; if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_REF_CLK_SEL; break; case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID:
val = SYSCFG_PMCR_ETH_SEL_RGMII; if (dwmac->enable_eth_ck)
val |= SYSCFG_PMCR_ETH_CLK_SEL; break; default:
dev_err(dwmac->dev, "Mode %s not supported",
phy_modes(plat_dat->mac_interface)); /* Do not manage others interfaces */ return -EINVAL;
}
staticint stm32mp2_configure_syscfg(struct plat_stmmacenet_data *plat_dat)
{ struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
u32 reg = dwmac->mode_reg; int val = 0;
switch (plat_dat->mac_interface) { case PHY_INTERFACE_MODE_MII: /* ETH_REF_CLK_SEL bit in SYSCFG register is not applicable in MII mode */ break; case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_ETHCR_ETH_SEL_RMII; if (dwmac->enable_eth_ck) { /* Internal clock ETH_CLK of 50MHz from RCC is used */
val |= SYSCFG_ETHCR_ETH_REF_CLK_SEL;
} break; case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID:
val = SYSCFG_ETHCR_ETH_SEL_RGMII;
fallthrough; case PHY_INTERFACE_MODE_GMII: if (dwmac->enable_eth_ck) { /* Internal clock ETH_CLK of 125MHz from RCC is used */
val |= SYSCFG_ETHCR_ETH_CLK_SEL;
} break; default:
dev_err(dwmac->dev, "Mode %s not supported",
phy_modes(plat_dat->mac_interface)); /* Do not manage others interfaces */ return -EINVAL;
}
switch (plat_dat->mac_interface) { case PHY_INTERFACE_MODE_MII:
val = SYSCFG_MCU_ETH_SEL_MII; break; case PHY_INTERFACE_MODE_RMII:
val = SYSCFG_MCU_ETH_SEL_RMII; break; default:
dev_err(dwmac->dev, "Mode %s not supported",
phy_modes(plat_dat->mac_interface)); /* Do not manage others interfaces */ return -EINVAL;
}
/* Get ETH_CLK clocks */
dwmac->clk_eth_ck = devm_clk_get(dev, "eth-ck"); if (IS_ERR(dwmac->clk_eth_ck)) {
dev_info(dev, "No phy clock provided...\n");
dwmac->clk_eth_ck = NULL;
}
/* Clock used for low power mode */
dwmac->clk_ethstp = devm_clk_get(dev, "ethstp"); if (IS_ERR(dwmac->clk_ethstp)) {
dev_err(dev, "No ETH peripheral clock provided for CStop mode ...\n"); return PTR_ERR(dwmac->clk_ethstp);
}
/* Optional Clock for sysconfig */
dwmac->syscfg_clk = devm_clk_get(dev, "syscfg-clk"); if (IS_ERR(dwmac->syscfg_clk))
dwmac->syscfg_clk = NULL;
/* Get IRQ information early to have an ability to ask for deferred * probe if needed before we went too far with resource allocation.
*/
dwmac->irq_pwr_wakeup = platform_get_irq_byname_optional(pdev, "stm32_pwr_wakeup"); if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER) return -EPROBE_DEFER;
if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) {
err = device_init_wakeup(&pdev->dev, true); if (err) {
dev_err(&pdev->dev, "Failed to init wake up irq\n"); return err;
}
err = dev_pm_set_dedicated_wake_irq(&pdev->dev,
dwmac->irq_pwr_wakeup); if (err) {
dev_err(&pdev->dev, "Failed to set wake up irq\n");
device_init_wakeup(&pdev->dev, false);
}
device_set_wakeup_enable(&pdev->dev, false);
} return err;
}
ret = stm32_dwmac_init(plat_dat); if (ret) return ret;
/* If this platform requires the clock to be running in suspend, * prepare and enable the receive clock an additional time to keep * it running.
*/ if (dwmac->ops->clk_rx_enable_in_suspend) {
ret = clk_prepare_enable(dwmac->clk_rx); if (ret) goto err_clk_disable;
}
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); if (ret) goto err_clk_disable_suspend;
return 0;
err_clk_disable_suspend: if (dwmac->ops->clk_rx_enable_in_suspend)
clk_disable_unprepare(dwmac->clk_rx);
/* If this platform requires the clock to be running in suspend, * we need to disable and unprepare the receive clock an additional * time to balance the extra clk_prepare_enable() in the probe * function.
*/ if (dwmac->ops->clk_rx_enable_in_suspend)
clk_disable_unprepare(dwmac->clk_rx);
stm32_dwmac_clk_disable(dwmac);
if (dwmac->irq_pwr_wakeup >= 0) {
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.