Merge branch 'net-stmmac-convert-glue-drivers-to-use-stmmac_get_phy_intf_sel'

Russell King says:

====================
net: stmmac: convert glue drivers to use stmmac_get_phy_intf_sel()

This series converts the remaining glue drivers that support
multi-interface to use stmmac_get_phy_intf_sel(). The reason these
drivers are not converted to the set_phy_intf_sel() method is
because it is unclear whether there are ordering dependencies that
would prevent it.

For example, reading the stm32mp2 documentation, it is required to
set the ETH1_SEL field while the dwmac core is in reset and before
clocks are enabled. This requirement can not be satsified at the
moment (but could with further changes.)
====================

Link: https://patch.msgid.link/aRLvrfx6tOa-RhrY@shell.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2025-11-12 18:13:44 -08:00
5 changed files with 69 additions and 118 deletions

View File

@@ -38,8 +38,6 @@
#define GMAC_SHUT BIT(6)
#define PHY_INTF_SELI GENMASK(30, 28)
#define PHY_INTF_MII FIELD_PREP(PHY_INTF_SELI, 0)
#define PHY_INTF_RMII FIELD_PREP(PHY_INTF_SELI, 4)
struct ls1x_dwmac {
struct plat_stmmacenet_data *plat_dat;
@@ -140,22 +138,18 @@ static int ls1c_dwmac_syscon_init(struct platform_device *pdev, void *priv)
struct ls1x_dwmac *dwmac = priv;
struct plat_stmmacenet_data *plat = dwmac->plat_dat;
struct regmap *regmap = dwmac->regmap;
int phy_intf_sel;
switch (plat->phy_interface) {
case PHY_INTERFACE_MODE_MII:
regmap_update_bits(regmap, LS1X_SYSCON1, PHY_INTF_SELI,
PHY_INTF_MII);
break;
case PHY_INTERFACE_MODE_RMII:
regmap_update_bits(regmap, LS1X_SYSCON1, PHY_INTF_SELI,
PHY_INTF_RMII);
break;
default:
phy_intf_sel = stmmac_get_phy_intf_sel(plat->phy_interface);
if (phy_intf_sel != PHY_INTF_SEL_GMII_MII &&
phy_intf_sel != PHY_INTF_SEL_RMII) {
dev_err(&pdev->dev, "Unsupported PHY-mode %u\n",
plat->phy_interface);
return -EOPNOTSUPP;
}
regmap_update_bits(regmap, LS1X_SYSCON1, PHY_INTF_SELI,
FIELD_PREP(PHY_INTF_SELI, phy_intf_sel));
regmap_update_bits(regmap, LS1X_SYSCON0, GMAC0_SHUT, 0);
return 0;

View File

@@ -17,9 +17,6 @@
/* Peri Configuration register for mt2712 */
#define PERI_ETH_PHY_INTF_SEL 0x418
#define PHY_INTF_MII 0
#define PHY_INTF_RGMII 1
#define PHY_INTF_RMII 4
#define RMII_CLK_SRC_RXC BIT(4)
#define RMII_CLK_SRC_INTERNAL BIT(5)
@@ -88,7 +85,8 @@ struct mediatek_dwmac_plat_data {
};
struct mediatek_dwmac_variant {
int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data *plat);
int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data *plat,
u8 phy_intf_sel);
int (*dwmac_set_delay)(struct mediatek_dwmac_plat_data *plat);
/* clock ids to be requested */
@@ -109,29 +107,16 @@ static const char * const mt8195_dwmac_clk_l[] = {
"axi", "apb", "mac_cg", "mac_main", "ptp_ref"
};
static int mt2712_set_interface(struct mediatek_dwmac_plat_data *plat)
static int mt2712_set_interface(struct mediatek_dwmac_plat_data *plat,
u8 phy_intf_sel)
{
int rmii_clk_from_mac = plat->rmii_clk_from_mac ? RMII_CLK_SRC_INTERNAL : 0;
int rmii_rxc = plat->rmii_rxc ? RMII_CLK_SRC_RXC : 0;
u32 intf_val = 0;
u32 intf_val = phy_intf_sel;
/* select phy interface in top control domain */
switch (plat->phy_mode) {
case PHY_INTERFACE_MODE_MII:
intf_val |= PHY_INTF_MII;
break;
case PHY_INTERFACE_MODE_RMII:
intf_val |= (PHY_INTF_RMII | rmii_rxc | rmii_clk_from_mac);
break;
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_TXID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_ID:
intf_val |= PHY_INTF_RGMII;
break;
default:
dev_err(plat->dev, "phy interface not supported\n");
return -EINVAL;
if (phy_intf_sel == PHY_INTF_SEL_RMII) {
if (plat->rmii_clk_from_mac)
intf_val |= RMII_CLK_SRC_INTERNAL;
if (plat->rmii_rxc)
intf_val |= RMII_CLK_SRC_RXC;
}
regmap_write(plat->peri_regmap, PERI_ETH_PHY_INTF_SEL, intf_val);
@@ -288,30 +273,16 @@ static const struct mediatek_dwmac_variant mt2712_gmac_variant = {
.tx_delay_max = 17600,
};
static int mt8195_set_interface(struct mediatek_dwmac_plat_data *plat)
static int mt8195_set_interface(struct mediatek_dwmac_plat_data *plat,
u8 phy_intf_sel)
{
int rmii_clk_from_mac = plat->rmii_clk_from_mac ? MT8195_RMII_CLK_SRC_INTERNAL : 0;
int rmii_rxc = plat->rmii_rxc ? MT8195_RMII_CLK_SRC_RXC : 0;
u32 intf_val = 0;
u32 intf_val = FIELD_PREP(MT8195_ETH_INTF_SEL, phy_intf_sel);
/* select phy interface in top control domain */
switch (plat->phy_mode) {
case PHY_INTERFACE_MODE_MII:
intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL, PHY_INTF_MII);
break;
case PHY_INTERFACE_MODE_RMII:
intf_val |= (rmii_rxc | rmii_clk_from_mac);
intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL, PHY_INTF_RMII);
break;
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_TXID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_ID:
intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL, PHY_INTF_RGMII);
break;
default:
dev_err(plat->dev, "phy interface not supported\n");
return -EINVAL;
if (phy_intf_sel == PHY_INTF_SEL_RMII) {
if (plat->rmii_clk_from_mac)
intf_val |= MT8195_RMII_CLK_SRC_INTERNAL;
if (plat->rmii_rxc)
intf_val |= MT8195_RMII_CLK_SRC_RXC;
}
/* MT8195 only support external PHY */
@@ -527,10 +498,18 @@ static int mediatek_dwmac_init(struct device *dev, void *priv)
{
struct mediatek_dwmac_plat_data *plat = priv;
const struct mediatek_dwmac_variant *variant = plat->variant;
int ret;
int phy_intf_sel, ret;
if (variant->dwmac_set_phy_interface) {
ret = variant->dwmac_set_phy_interface(plat);
phy_intf_sel = stmmac_get_phy_intf_sel(plat->phy_mode);
if (phy_intf_sel != PHY_INTF_SEL_GMII_MII &&
phy_intf_sel != PHY_INTF_SEL_RGMII &&
phy_intf_sel != PHY_INTF_SEL_RMII) {
dev_err(plat->dev, "phy interface not supported\n");
return phy_intf_sel < 0 ? phy_intf_sel : -EINVAL;
}
ret = variant->dwmac_set_phy_interface(plat, phy_intf_sel);
if (ret) {
dev_err(dev, "failed to set phy interface, err = %d\n", ret);
return ret;

View File

@@ -15,8 +15,6 @@
#include "stmmac_platform.h"
#define STARFIVE_DWMAC_PHY_INFT_RGMII 0x1
#define STARFIVE_DWMAC_PHY_INFT_RMII 0x4
#define STARFIVE_DWMAC_PHY_INFT_FIELD 0x7U
#define JH7100_SYSMAIN_REGISTER49_DLYCHAIN 0xc8
@@ -35,25 +33,15 @@ static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat)
struct starfive_dwmac *dwmac = plat_dat->bsp_priv;
struct regmap *regmap;
unsigned int args[2];
unsigned int mode;
int phy_intf_sel;
int err;
switch (plat_dat->phy_interface) {
case PHY_INTERFACE_MODE_RMII:
mode = STARFIVE_DWMAC_PHY_INFT_RMII;
break;
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
break;
default:
phy_intf_sel = stmmac_get_phy_intf_sel(plat_dat->phy_interface);
if (phy_intf_sel != PHY_INTF_SEL_RGMII &&
phy_intf_sel != PHY_INTF_SEL_RMII) {
dev_err(dwmac->dev, "unsupported interface %s\n",
phy_modes(plat_dat->phy_interface));
return -EINVAL;
return phy_intf_sel < 0 ? phy_intf_sel : -EINVAL;
}
regmap = syscon_regmap_lookup_by_phandle_args(dwmac->dev->of_node,
@@ -65,7 +53,7 @@ static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat)
/* args[0]:offset args[1]: shift */
err = regmap_update_bits(regmap, args[0],
STARFIVE_DWMAC_PHY_INFT_FIELD << args[1],
mode << args[1]);
phy_intf_sel << args[1]);
if (err)
return dev_err_probe(dwmac->dev, err, "error setting phy mode\n");

View File

@@ -47,23 +47,18 @@
*------------------------------------------
*/
#define SYSCFG_PMCR_ETH_SEL_MII BIT(20)
#define SYSCFG_PMCR_ETH_SEL_RGMII BIT(21)
#define SYSCFG_PMCR_ETH_SEL_RMII BIT(23)
#define SYSCFG_PMCR_ETH_SEL_GMII 0
#define SYSCFG_PMCR_PHY_INTF_SEL_MASK GENMASK(23, 21)
#define SYSCFG_MCU_ETH_SEL_MII 0
#define SYSCFG_MCU_ETH_SEL_RMII 1
/* STM32MP2 register definitions */
#define SYSCFG_MP2_ETH_MASK GENMASK(31, 0)
#define SYSCFG_ETHCR_ETH_SEL_MASK GENMASK(6, 4)
#define SYSCFG_ETHCR_ETH_PTP_CLK_SEL BIT(2)
#define SYSCFG_ETHCR_ETH_CLK_SEL BIT(1)
#define SYSCFG_ETHCR_ETH_REF_CLK_SEL BIT(0)
#define SYSCFG_ETHCR_ETH_SEL_MII 0
#define SYSCFG_ETHCR_ETH_SEL_RGMII BIT(4)
#define SYSCFG_ETHCR_ETH_SEL_RMII BIT(6)
/* STM32MPx register definitions
*
* Below table summarizes the clock requirement and clock sources for
@@ -232,11 +227,14 @@ static int stm32mp1_validate_ethck_rate(struct plat_stmmacenet_data *plat_dat)
return -EINVAL;
}
static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat,
u8 phy_intf_sel)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
u32 reg = dwmac->mode_reg;
int val = 0;
int val;
val = FIELD_PREP(SYSCFG_PMCR_PHY_INTF_SEL_MASK, phy_intf_sel);
switch (plat_dat->phy_interface) {
case PHY_INTERFACE_MODE_MII:
@@ -250,12 +248,10 @@ static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
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;
@@ -263,7 +259,6 @@ static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
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;
@@ -288,18 +283,20 @@ static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
dwmac->mode_mask, val);
}
static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data *plat_dat)
static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data *plat_dat,
u8 phy_intf_sel)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
u32 reg = dwmac->mode_reg;
int val = 0;
int val;
val = FIELD_PREP(SYSCFG_ETHCR_ETH_SEL_MASK, phy_intf_sel);
switch (plat_dat->phy_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;
@@ -309,8 +306,6 @@ static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data *plat_dat)
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 */
@@ -337,7 +332,7 @@ static int stm32mp2_configure_syscfg(struct plat_stmmacenet_data *plat_dat)
static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
{
struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
int ret;
int phy_intf_sel, ret;
ret = stm32mp1_select_ethck_external(plat_dat);
if (ret)
@@ -347,10 +342,19 @@ static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
if (ret)
return ret;
phy_intf_sel = stmmac_get_phy_intf_sel(plat_dat->phy_interface);
if (phy_intf_sel != PHY_INTF_SEL_GMII_MII &&
phy_intf_sel != PHY_INTF_SEL_RGMII &&
phy_intf_sel != PHY_INTF_SEL_RMII) {
dev_err(dwmac->dev, "Mode %s not supported\n",
phy_modes(plat_dat->phy_interface));
return phy_intf_sel < 0 ? phy_intf_sel : -EINVAL;
}
if (!dwmac->ops->is_mp2)
return stm32mp1_configure_pmcr(plat_dat);
return stm32mp1_configure_pmcr(plat_dat, phy_intf_sel);
else
return stm32mp2_configure_syscfg(plat_dat);
return stm32mp2_configure_syscfg(plat_dat, phy_intf_sel);
}
static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)

View File

@@ -42,10 +42,6 @@
#define ETHER_CLK_SEL_RX_TX_CLK_EN (ETHER_CLK_SEL_RX_CLK_EN | ETHER_CLK_SEL_TX_CLK_EN)
#define ETHER_CONFIG_INTF_MII 0
#define ETHER_CONFIG_INTF_RGMII BIT(0)
#define ETHER_CONFIG_INTF_RMII BIT(2)
struct visconti_eth {
void __iomem *reg;
struct clk *phy_ref_clk;
@@ -150,22 +146,12 @@ static int visconti_eth_init_hw(struct platform_device *pdev, struct plat_stmmac
{
struct visconti_eth *dwmac = plat_dat->bsp_priv;
unsigned int clk_sel_val;
u32 phy_intf_sel;
int phy_intf_sel;
switch (plat_dat->phy_interface) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
phy_intf_sel = ETHER_CONFIG_INTF_RGMII;
break;
case PHY_INTERFACE_MODE_MII:
phy_intf_sel = ETHER_CONFIG_INTF_MII;
break;
case PHY_INTERFACE_MODE_RMII:
phy_intf_sel = ETHER_CONFIG_INTF_RMII;
break;
default:
phy_intf_sel = stmmac_get_phy_intf_sel(plat_dat->phy_interface);
if (phy_intf_sel != PHY_INTF_SEL_GMII_MII &&
phy_intf_sel != PHY_INTF_SEL_RGMII &&
phy_intf_sel != PHY_INTF_SEL_RMII) {
dev_err(&pdev->dev, "Unsupported phy-mode (%d)\n", plat_dat->phy_interface);
return -EOPNOTSUPP;
}