diff mbox series

[v4,07/11] net: ethernet: stmmac: add management of stm32mp13 for stm32

Message ID 20240604143502.154463-8-christophe.roullier@foss.st.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series Series to deliver Ethernet for STM32MP13 | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 901 this patch: 901
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 9 of 9 maintainers
netdev/build_clang fail Errors and warnings before: 905 this patch: 908
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 905 this patch: 905
netdev/checkpatch warning WARNING: networking block comments don't use an empty /* line, use /* Comment...
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Christophe Roullier June 4, 2024, 2:34 p.m. UTC
Add Ethernet support for STM32MP13.
STM32MP13 is STM32 SOC with 2 GMACs instances.
GMAC IP version is SNPS 4.20.
GMAC IP configure with 1 RX and 1 TX queue.
DMA HW capability register supported
RX Checksum Offload Engine supported
TX Checksum insertion supported
Wake-Up On Lan supported
TSO supported

Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 50 +++++++++++++++----
 1 file changed, 40 insertions(+), 10 deletions(-)

Comments

Marek Vasut June 4, 2024, 5:05 p.m. UTC | #1
On 6/4/24 4:34 PM, Christophe Roullier wrote:
> Add Ethernet support for STM32MP13.
> STM32MP13 is STM32 SOC with 2 GMACs instances.
> GMAC IP version is SNPS 4.20.
> GMAC IP configure with 1 RX and 1 TX queue.
> DMA HW capability register supported
> RX Checksum Offload Engine supported
> TX Checksum insertion supported
> Wake-Up On Lan supported
> TSO supported
> 
> Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
> ---
>   .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 50 +++++++++++++++----
>   1 file changed, 40 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> index bed2be129b2d2..e59f8a845e01e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> @@ -84,12 +84,14 @@ struct stm32_dwmac {
>   	struct clk *clk_eth_ck;
>   	struct clk *clk_ethstp;
>   	struct clk *syscfg_clk;
> +	bool is_mp13;
>   	int ext_phyclk;
>   	int enable_eth_ck;
>   	int eth_clk_sel_reg;
>   	int eth_ref_clk_sel_reg;
>   	int irq_pwr_wakeup;
>   	u32 mode_reg;		 /* MAC glue-logic mode register */
> +	u32 mode_mask;
>   	struct regmap *regmap;
>   	u32 speed;
>   	const struct stm32_ops *ops;
> @@ -102,8 +104,8 @@ struct stm32_ops {
>   	void (*resume)(struct stm32_dwmac *dwmac);
>   	int (*parse_data)(struct stm32_dwmac *dwmac,
>   			  struct device *dev);
> -	u32 syscfg_eth_mask;
>   	bool clk_rx_enable_in_suspend;
> +	u32 syscfg_clr_off;
>   };
>   
>   static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume)
> @@ -227,7 +229,14 @@ static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
>   
>   	switch (plat_dat->mac_interface) {
>   	case PHY_INTERFACE_MODE_MII:
> -		val = SYSCFG_PMCR_ETH_SEL_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->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;
> @@ -256,13 +265,16 @@ static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
>   
>   	dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
>   
> +	/* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
> +	val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);
> +
>   	/* Need to update PMCCLRR (clear register) */
> -	regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
> -		     dwmac->ops->syscfg_eth_mask);
> +	regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
> +		     dwmac->mode_mask);
>   
>   	/* Update PMCSETR (set register) */
>   	return regmap_update_bits(dwmac->regmap, reg,
> -				 dwmac->ops->syscfg_eth_mask, val);
> +				 dwmac->mode_mask, val);
>   }
>   
>   static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
> @@ -303,7 +315,7 @@ static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
>   	dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
>   
>   	return regmap_update_bits(dwmac->regmap, reg,
> -				 dwmac->ops->syscfg_eth_mask, val << 23);
> +				 SYSCFG_MCU_ETH_MASK, val << 23);
>   }
>   
>   static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend)
> @@ -348,8 +360,15 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
>   		return PTR_ERR(dwmac->regmap);
>   
>   	err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg);
> -	if (err)
> +	if (err) {
>   		dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);
> +		return err;
> +	}
> +
> +	dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
> +	err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
> +	if (err)
> +		pr_debug("Warning sysconfig register mask not set\n");

I _think_ you need to left-shift the mode mask by 8 for STM32MP13xx 
second GMAC somewhere in here, right ?

>   	return err;
>   }
> @@ -361,6 +380,8 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
>   	struct device_node *np = dev->of_node;
>   	int err = 0;
>   
> +	dwmac->is_mp13 = of_device_is_compatible(np, "st,stm32mp13-dwmac");

You could make is_mp13 part of struct stm32_ops {} just like 
syscfg_clr_off is part of struct stm32_ops {} .

>   	/* Ethernet PHY have no crystal */
>   	dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
>   
> @@ -540,8 +561,7 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
>   	stm32_dwmac_suspend, stm32_dwmac_resume);
>   
>   static struct stm32_ops stm32mcu_dwmac_data = {
> -	.set_mode = stm32mcu_set_mode,
> -	.syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
> +	.set_mode = stm32mcu_set_mode

It is not necessary to remove the trailing comma ','

>   };
>   
>   static struct stm32_ops stm32mp1_dwmac_data = {
> @@ -549,13 +569,23 @@ static struct stm32_ops stm32mp1_dwmac_data = {
>   	.suspend = stm32mp1_suspend,
>   	.resume = stm32mp1_resume,
>   	.parse_data = stm32mp1_parse_data,
> -	.syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
> +	.syscfg_clr_off = 0x44,
> +	.clk_rx_enable_in_suspend = true
> +};
> +
> +static struct stm32_ops stm32mp13_dwmac_data = {
> +	.set_mode = stm32mp1_set_mode,
> +	.suspend = stm32mp1_suspend,
> +	.resume = stm32mp1_resume,
> +	.parse_data = stm32mp1_parse_data,
> +	.syscfg_clr_off = 0x08,
>   	.clk_rx_enable_in_suspend = true
>   };
>   
>   static const struct of_device_id stm32_dwmac_match[] = {
>   	{ .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
>   	{ .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
> +	{ .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data},
>   	{ }
>   };
>   MODULE_DEVICE_TABLE(of, stm32_dwmac_match);

This patch definitely looks MUCH better than what this series started 
with, it is much easier to grasp the MP13 specific changes.

You could possibly improve this further and split the 
dwmac->ops->syscfg_eth_mask to dwmac->mode_mask conversion into separate 
preparatory patch (as a 6.5/11 in context of this series), and then add 
the few MP13 changes on top (as 7/11 patch).
kernel test robot June 4, 2024, 7 p.m. UTC | #2
Hi Christophe,

kernel test robot noticed the following build warnings:

[auto build test WARNING on cd0057ad75116bacf16fea82e48c1db642971136]

url:    https://github.com/intel-lab-lkp/linux/commits/Christophe-Roullier/dt-bindings-net-add-STM32MP13-compatible-in-documentation-for-stm32/20240604-224324
base:   cd0057ad75116bacf16fea82e48c1db642971136
patch link:    https://lore.kernel.org/r/20240604143502.154463-8-christophe.roullier%40foss.st.com
patch subject: [PATCH v4 07/11] net: ethernet: stmmac: add management of stm32mp13 for stm32
config: arm-defconfig (https://download.01.org/0day-ci/archive/20240605/202406050248.rGgTkevY-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240605/202406050248.rGgTkevY-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202406050248.rGgTkevY-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c:239:4: warning: variable 'val' is uninitialized when used here [-Wuninitialized]
                           val |= SYSCFG_PMCR_ETH_SEL_MII;
                           ^~~
   drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c:228:9: note: initialize the variable 'val' to silence this warning
           int val;
                  ^
                   = 0
   1 warning generated.


vim +/val +239 drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c

   223	
   224	static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
   225	{
   226		struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
   227		u32 reg = dwmac->mode_reg;
   228		int val;
   229	
   230		switch (plat_dat->mac_interface) {
   231		case PHY_INTERFACE_MODE_MII:
   232			/*
   233			 * STM32MP15xx supports both MII and GMII, STM32MP13xx MII only.
   234			 * SYSCFG_PMCSETR ETH_SELMII is present only on STM32MP15xx and
   235			 * acts as a selector between 0:GMII and 1:MII. As STM32MP13xx
   236			 * supports only MII, ETH_SELMII is not present.
   237			 */
   238			if (!dwmac->is_mp13)	/* Select MII mode on STM32MP15xx */
 > 239				val |= SYSCFG_PMCR_ETH_SEL_MII;
   240			break;
   241		case PHY_INTERFACE_MODE_GMII:
   242			val = SYSCFG_PMCR_ETH_SEL_GMII;
   243			if (dwmac->enable_eth_ck)
   244				val |= SYSCFG_PMCR_ETH_CLK_SEL;
   245			break;
   246		case PHY_INTERFACE_MODE_RMII:
   247			val = SYSCFG_PMCR_ETH_SEL_RMII;
   248			if (dwmac->enable_eth_ck)
   249				val |= SYSCFG_PMCR_ETH_REF_CLK_SEL;
   250			break;
   251		case PHY_INTERFACE_MODE_RGMII:
   252		case PHY_INTERFACE_MODE_RGMII_ID:
   253		case PHY_INTERFACE_MODE_RGMII_RXID:
   254		case PHY_INTERFACE_MODE_RGMII_TXID:
   255			val = SYSCFG_PMCR_ETH_SEL_RGMII;
   256			if (dwmac->enable_eth_ck)
   257				val |= SYSCFG_PMCR_ETH_CLK_SEL;
   258			break;
   259		default:
   260			dev_err(dwmac->dev, "Mode %s not supported",
   261				phy_modes(plat_dat->mac_interface));
   262			/* Do not manage others interfaces */
   263			return -EINVAL;
   264		}
   265	
   266		dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
   267	
   268		/* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
   269		val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);
   270	
   271		/* Need to update PMCCLRR (clear register) */
   272		regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
   273			     dwmac->mode_mask);
   274	
   275		/* Update PMCSETR (set register) */
   276		return regmap_update_bits(dwmac->regmap, reg,
   277					 dwmac->mode_mask, val);
   278	}
   279
Amit Singh Tomar June 5, 2024, 2:02 p.m. UTC | #3
> Add Ethernet support for STM32MP13.
> STM32MP13 is STM32 SOC with 2 GMACs instances.
> GMAC IP version is SNPS 4.20.
> GMAC IP configure with 1 RX and 1 TX queue.
> DMA HW capability register supported
> RX Checksum Offload Engine supported
> TX Checksum insertion supported
> Wake-Up On Lan supported
> TSO supported
> 
> Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
> ---
>   .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 50 +++++++++++++++----
>   1 file changed, 40 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> index bed2be129b2d2..e59f8a845e01e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
> @@ -84,12 +84,14 @@ struct stm32_dwmac {
>   	struct clk *clk_eth_ck;
>   	struct clk *clk_ethstp;
>   	struct clk *syscfg_clk;
> +	bool is_mp13;
>   	int ext_phyclk;
>   	int enable_eth_ck;
>   	int eth_clk_sel_reg;
>   	int eth_ref_clk_sel_reg;
>   	int irq_pwr_wakeup;
>   	u32 mode_reg;		 /* MAC glue-logic mode register */
> +	u32 mode_mask;
>   	struct regmap *regmap;
>   	u32 speed;
>   	const struct stm32_ops *ops;
> @@ -102,8 +104,8 @@ struct stm32_ops {
>   	void (*resume)(struct stm32_dwmac *dwmac);
>   	int (*parse_data)(struct stm32_dwmac *dwmac,
>   			  struct device *dev);
> -	u32 syscfg_eth_mask;
>   	bool clk_rx_enable_in_suspend;
> +	u32 syscfg_clr_off;
>   };
>   
>   static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume)
> @@ -227,7 +229,14 @@ static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
>   
>   	switch (plat_dat->mac_interface) {
>   	case PHY_INTERFACE_MODE_MII:
> -		val = SYSCFG_PMCR_ETH_SEL_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->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;
> @@ -256,13 +265,16 @@ static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
>   
>   	dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
>   
> +	/* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
> +	val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);
> +
>   	/* Need to update PMCCLRR (clear register) */
> -	regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
> -		     dwmac->ops->syscfg_eth_mask);
> +	regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
> +		     dwmac->mode_mask);
>   
>   	/* Update PMCSETR (set register) */
>   	return regmap_update_bits(dwmac->regmap, reg,
> -				 dwmac->ops->syscfg_eth_mask, val);
> +				 dwmac->mode_mask, val);
>   }
>   
>   static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
> @@ -303,7 +315,7 @@ static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
>   	dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
>   
>   	return regmap_update_bits(dwmac->regmap, reg,
> -				 dwmac->ops->syscfg_eth_mask, val << 23);
> +				 SYSCFG_MCU_ETH_MASK, val << 23);
>   }
>   
>   static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend)
> @@ -348,8 +360,15 @@ static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
>   		return PTR_ERR(dwmac->regmap);
>   
>   	err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg);
> -	if (err)
> +	if (err) {
>   		dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);

Shouldn't we decrement the refcount of np (‎of_node_put‎) before 
returning from this point?

> +		return err;
> +	}
> +
> +	dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
> +	err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
> +	if (err)
> +		pr_debug("Warning sysconfig register mask not set\n");
>   
>   	return err;
>   }
> @@ -361,6 +380,8 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
>   	struct device_node *np = dev->of_node;
>   	int err = 0;
>   
> +	dwmac->is_mp13 = of_device_is_compatible(np, "st,stm32mp13-dwmac");
> +
>   	/* Ethernet PHY have no crystal */
>   	dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
>   
> @@ -540,8 +561,7 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
>   	stm32_dwmac_suspend, stm32_dwmac_resume);
>   
>   static struct stm32_ops stm32mcu_dwmac_data = {
> -	.set_mode = stm32mcu_set_mode,
> -	.syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
> +	.set_mode = stm32mcu_set_mode
>   };
>   
>   static struct stm32_ops stm32mp1_dwmac_data = {
> @@ -549,13 +569,23 @@ static struct stm32_ops stm32mp1_dwmac_data = {
>   	.suspend = stm32mp1_suspend,
>   	.resume = stm32mp1_resume,
>   	.parse_data = stm32mp1_parse_data,
> -	.syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
> +	.syscfg_clr_off = 0x44,
> +	.clk_rx_enable_in_suspend = true
> +};
> +
> +static struct stm32_ops stm32mp13_dwmac_data = {
> +	.set_mode = stm32mp1_set_mode,
> +	.suspend = stm32mp1_suspend,
> +	.resume = stm32mp1_resume,
> +	.parse_data = stm32mp1_parse_data,
> +	.syscfg_clr_off = 0x08,
>   	.clk_rx_enable_in_suspend = true
>   };
>   
>   static const struct of_device_id stm32_dwmac_match[] = {
>   	{ .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
>   	{ .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
> +	{ .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data},
>   	{ }
>   };
>   MODULE_DEVICE_TABLE(of, stm32_dwmac_match);
Christophe Roullier June 6, 2024, 2:19 p.m. UTC | #4
On 6/4/24 19:05, Marek Vasut wrote:
> On 6/4/24 4:34 PM, Christophe Roullier wrote:
>> Add Ethernet support for STM32MP13.
>> STM32MP13 is STM32 SOC with 2 GMACs instances.
>> GMAC IP version is SNPS 4.20.
>> GMAC IP configure with 1 RX and 1 TX queue.
>> DMA HW capability register supported
>> RX Checksum Offload Engine supported
>> TX Checksum insertion supported
>> Wake-Up On Lan supported
>> TSO supported
>>
>> Signed-off-by: Christophe Roullier <christophe.roullier@foss.st.com>
>> ---
>>   .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 50 +++++++++++++++----
>>   1 file changed, 40 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c 
>> b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
>> index bed2be129b2d2..e59f8a845e01e 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
>> @@ -84,12 +84,14 @@ struct stm32_dwmac {
>>       struct clk *clk_eth_ck;
>>       struct clk *clk_ethstp;
>>       struct clk *syscfg_clk;
>> +    bool is_mp13;
>>       int ext_phyclk;
>>       int enable_eth_ck;
>>       int eth_clk_sel_reg;
>>       int eth_ref_clk_sel_reg;
>>       int irq_pwr_wakeup;
>>       u32 mode_reg;         /* MAC glue-logic mode register */
>> +    u32 mode_mask;
>>       struct regmap *regmap;
>>       u32 speed;
>>       const struct stm32_ops *ops;
>> @@ -102,8 +104,8 @@ struct stm32_ops {
>>       void (*resume)(struct stm32_dwmac *dwmac);
>>       int (*parse_data)(struct stm32_dwmac *dwmac,
>>                 struct device *dev);
>> -    u32 syscfg_eth_mask;
>>       bool clk_rx_enable_in_suspend;
>> +    u32 syscfg_clr_off;
>>   };
>>     static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool 
>> resume)
>> @@ -227,7 +229,14 @@ static int stm32mp1_configure_pmcr(struct 
>> plat_stmmacenet_data *plat_dat)
>>         switch (plat_dat->mac_interface) {
>>       case PHY_INTERFACE_MODE_MII:
>> -        val = SYSCFG_PMCR_ETH_SEL_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->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;
>> @@ -256,13 +265,16 @@ static int stm32mp1_configure_pmcr(struct 
>> plat_stmmacenet_data *plat_dat)
>>         dev_dbg(dwmac->dev, "Mode %s", 
>> phy_modes(plat_dat->mac_interface));
>>   +    /* Shift value at correct ethernet MAC offset in 
>> SYSCFG_PMCSETR */
>> +    val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);
>> +
>>       /* Need to update PMCCLRR (clear register) */
>> -    regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
>> -             dwmac->ops->syscfg_eth_mask);
>> +    regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
>> +             dwmac->mode_mask);
>>         /* Update PMCSETR (set register) */
>>       return regmap_update_bits(dwmac->regmap, reg,
>> -                 dwmac->ops->syscfg_eth_mask, val);
>> +                 dwmac->mode_mask, val);
>>   }
>>     static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
>> @@ -303,7 +315,7 @@ static int stm32mcu_set_mode(struct 
>> plat_stmmacenet_data *plat_dat)
>>       dev_dbg(dwmac->dev, "Mode %s", 
>> phy_modes(plat_dat->mac_interface));
>>         return regmap_update_bits(dwmac->regmap, reg,
>> -                 dwmac->ops->syscfg_eth_mask, val << 23);
>> +                 SYSCFG_MCU_ETH_MASK, val << 23);
>>   }
>>     static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, 
>> bool suspend)
>> @@ -348,8 +360,15 @@ static int stm32_dwmac_parse_data(struct 
>> stm32_dwmac *dwmac,
>>           return PTR_ERR(dwmac->regmap);
>>         err = of_property_read_u32_index(np, "st,syscon", 1, 
>> &dwmac->mode_reg);
>> -    if (err)
>> +    if (err) {
>>           dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);
>> +        return err;
>> +    }
>> +
>> +    dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
>> +    err = of_property_read_u32_index(np, "st,syscon", 2, 
>> &dwmac->mode_mask);
>> +    if (err)
>> +        pr_debug("Warning sysconfig register mask not set\n");
>
> I _think_ you need to left-shift the mode mask by 8 for STM32MP13xx 
> second GMAC somewhere in here, right ?
>
The shift is performed in function stm32mp1_configure_pmcr:

     /* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
     val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);

In case of MP13 Ethernet1 or MP15, shift equal 0

In case of MP13 Ethernet2 , shift equal 8  ;-)

>>       return err;
>>   }
>> @@ -361,6 +380,8 @@ static int stm32mp1_parse_data(struct stm32_dwmac 
>> *dwmac,
>>       struct device_node *np = dev->of_node;
>>       int err = 0;
>>   +    dwmac->is_mp13 = of_device_is_compatible(np, 
>> "st,stm32mp13-dwmac");
>
> You could make is_mp13 part of struct stm32_ops {} just like 
> syscfg_clr_off is part of struct stm32_ops {} .
ok
>
>>       /* Ethernet PHY have no crystal */
>>       dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
>>   @@ -540,8 +561,7 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
>>       stm32_dwmac_suspend, stm32_dwmac_resume);
>>     static struct stm32_ops stm32mcu_dwmac_data = {
>> -    .set_mode = stm32mcu_set_mode,
>> -    .syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
>> +    .set_mode = stm32mcu_set_mode
>
> It is not necessary to remove the trailing comma ','
ok
>
>>   };
>>     static struct stm32_ops stm32mp1_dwmac_data = {
>> @@ -549,13 +569,23 @@ static struct stm32_ops stm32mp1_dwmac_data = {
>>       .suspend = stm32mp1_suspend,
>>       .resume = stm32mp1_resume,
>>       .parse_data = stm32mp1_parse_data,
>> -    .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
>> +    .syscfg_clr_off = 0x44,
>> +    .clk_rx_enable_in_suspend = true
>> +};
>> +
>> +static struct stm32_ops stm32mp13_dwmac_data = {
>> +    .set_mode = stm32mp1_set_mode,
>> +    .suspend = stm32mp1_suspend,
>> +    .resume = stm32mp1_resume,
>> +    .parse_data = stm32mp1_parse_data,
>> +    .syscfg_clr_off = 0x08,
>>       .clk_rx_enable_in_suspend = true
>>   };
>>     static const struct of_device_id stm32_dwmac_match[] = {
>>       { .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
>>       { .compatible = "st,stm32mp1-dwmac", .data = 
>> &stm32mp1_dwmac_data},
>> +    { .compatible = "st,stm32mp13-dwmac", .data = 
>> &stm32mp13_dwmac_data},
>>       { }
>>   };
>>   MODULE_DEVICE_TABLE(of, stm32_dwmac_match);
>
> This patch definitely looks MUCH better than what this series started 
> with, it is much easier to grasp the MP13 specific changes.
>
> You could possibly improve this further and split the 
> dwmac->ops->syscfg_eth_mask to dwmac->mode_mask conversion into 
> separate preparatory patch (as a 6.5/11 in context of this series), 
> and then add the few MP13 changes on top (as 7/11 patch).
ok
Marek Vasut June 6, 2024, 3:47 p.m. UTC | #5
On 6/6/24 4:19 PM, Christophe ROULLIER wrote:

Hi,

>>> @@ -348,8 +360,15 @@ static int stm32_dwmac_parse_data(struct 
>>> stm32_dwmac *dwmac,
>>>           return PTR_ERR(dwmac->regmap);
>>>         err = of_property_read_u32_index(np, "st,syscon", 1, 
>>> &dwmac->mode_reg);
>>> -    if (err)
>>> +    if (err) {
>>>           dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);
>>> +        return err;
>>> +    }
>>> +
>>> +    dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
>>> +    err = of_property_read_u32_index(np, "st,syscon", 2, 
>>> &dwmac->mode_mask);
>>> +    if (err)
>>> +        pr_debug("Warning sysconfig register mask not set\n");
>>
>> I _think_ you need to left-shift the mode mask by 8 for STM32MP13xx 
>> second GMAC somewhere in here, right ?
>>
> The shift is performed in function stm32mp1_configure_pmcr:
> 
>      /* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
>      val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);
> 
> In case of MP13 Ethernet1 or MP15, shift equal 0
> 
> In case of MP13 Ethernet2 , shift equal 8  ;-)

Oh, good, thanks !
diff mbox series

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
index bed2be129b2d2..e59f8a845e01e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
@@ -84,12 +84,14 @@  struct stm32_dwmac {
 	struct clk *clk_eth_ck;
 	struct clk *clk_ethstp;
 	struct clk *syscfg_clk;
+	bool is_mp13;
 	int ext_phyclk;
 	int enable_eth_ck;
 	int eth_clk_sel_reg;
 	int eth_ref_clk_sel_reg;
 	int irq_pwr_wakeup;
 	u32 mode_reg;		 /* MAC glue-logic mode register */
+	u32 mode_mask;
 	struct regmap *regmap;
 	u32 speed;
 	const struct stm32_ops *ops;
@@ -102,8 +104,8 @@  struct stm32_ops {
 	void (*resume)(struct stm32_dwmac *dwmac);
 	int (*parse_data)(struct stm32_dwmac *dwmac,
 			  struct device *dev);
-	u32 syscfg_eth_mask;
 	bool clk_rx_enable_in_suspend;
+	u32 syscfg_clr_off;
 };
 
 static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume)
@@ -227,7 +229,14 @@  static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
 
 	switch (plat_dat->mac_interface) {
 	case PHY_INTERFACE_MODE_MII:
-		val = SYSCFG_PMCR_ETH_SEL_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->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;
@@ -256,13 +265,16 @@  static int stm32mp1_configure_pmcr(struct plat_stmmacenet_data *plat_dat)
 
 	dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
 
+	/* Shift value at correct ethernet MAC offset in SYSCFG_PMCSETR */
+	val <<= ffs(dwmac->mode_mask) - ffs(SYSCFG_MP1_ETH_MASK);
+
 	/* Need to update PMCCLRR (clear register) */
-	regmap_write(dwmac->regmap, reg + SYSCFG_PMCCLRR_OFFSET,
-		     dwmac->ops->syscfg_eth_mask);
+	regmap_write(dwmac->regmap, dwmac->ops->syscfg_clr_off,
+		     dwmac->mode_mask);
 
 	/* Update PMCSETR (set register) */
 	return regmap_update_bits(dwmac->regmap, reg,
-				 dwmac->ops->syscfg_eth_mask, val);
+				 dwmac->mode_mask, val);
 }
 
 static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
@@ -303,7 +315,7 @@  static int stm32mcu_set_mode(struct plat_stmmacenet_data *plat_dat)
 	dev_dbg(dwmac->dev, "Mode %s", phy_modes(plat_dat->mac_interface));
 
 	return regmap_update_bits(dwmac->regmap, reg,
-				 dwmac->ops->syscfg_eth_mask, val << 23);
+				 SYSCFG_MCU_ETH_MASK, val << 23);
 }
 
 static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend)
@@ -348,8 +360,15 @@  static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
 		return PTR_ERR(dwmac->regmap);
 
 	err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg);
-	if (err)
+	if (err) {
 		dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err);
+		return err;
+	}
+
+	dwmac->mode_mask = SYSCFG_MP1_ETH_MASK;
+	err = of_property_read_u32_index(np, "st,syscon", 2, &dwmac->mode_mask);
+	if (err)
+		pr_debug("Warning sysconfig register mask not set\n");
 
 	return err;
 }
@@ -361,6 +380,8 @@  static int stm32mp1_parse_data(struct stm32_dwmac *dwmac,
 	struct device_node *np = dev->of_node;
 	int err = 0;
 
+	dwmac->is_mp13 = of_device_is_compatible(np, "st,stm32mp13-dwmac");
+
 	/* Ethernet PHY have no crystal */
 	dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
 
@@ -540,8 +561,7 @@  static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops,
 	stm32_dwmac_suspend, stm32_dwmac_resume);
 
 static struct stm32_ops stm32mcu_dwmac_data = {
-	.set_mode = stm32mcu_set_mode,
-	.syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
+	.set_mode = stm32mcu_set_mode
 };
 
 static struct stm32_ops stm32mp1_dwmac_data = {
@@ -549,13 +569,23 @@  static struct stm32_ops stm32mp1_dwmac_data = {
 	.suspend = stm32mp1_suspend,
 	.resume = stm32mp1_resume,
 	.parse_data = stm32mp1_parse_data,
-	.syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
+	.syscfg_clr_off = 0x44,
+	.clk_rx_enable_in_suspend = true
+};
+
+static struct stm32_ops stm32mp13_dwmac_data = {
+	.set_mode = stm32mp1_set_mode,
+	.suspend = stm32mp1_suspend,
+	.resume = stm32mp1_resume,
+	.parse_data = stm32mp1_parse_data,
+	.syscfg_clr_off = 0x08,
 	.clk_rx_enable_in_suspend = true
 };
 
 static const struct of_device_id stm32_dwmac_match[] = {
 	{ .compatible = "st,stm32-dwmac", .data = &stm32mcu_dwmac_data},
 	{ .compatible = "st,stm32mp1-dwmac", .data = &stm32mp1_dwmac_data},
+	{ .compatible = "st,stm32mp13-dwmac", .data = &stm32mp13_dwmac_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, stm32_dwmac_match);