Commit 68fa5b09 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

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: default avatarJakub Kicinski <kuba@kernel.org>
parents 9c577f09 ccb4ff9f
Loading
Loading
Loading
Loading
+6 −12
Original line number Diff line number Diff line
@@ -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;
+28 −49
Original line number Diff line number Diff line
@@ -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;
+6 −18
Original line number Diff line number Diff line
@@ -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");

+24 −20
Original line number Diff line number Diff line
@@ -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)
+6 −20
Original line number Diff line number Diff line
@@ -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;

	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:
	int phy_intf_sel;

	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;
	}