mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user