[PATCH 1/3] arm: stm32mp2: add multifunction timer support for stm32mp25

Patrice CHOTARD patrice.chotard at foss.st.com
Mon Jul 28 11:03:08 CEST 2025



On 6/20/25 17:49, Cheick Traore wrote:
> Add support for STM32MP25 SoC.
> Identification and hardware configuration registers allow to read the
> timer version and capabilities (counter width, ...).
> So, rework the probe to avoid touching ARR register by simply read the
> counter width when available. This may avoid messing with a possibly
> running timer.
> Also add useful bit fields to stm32-timers header file.
> 
> Signed-off-by: Cheick Traore <cheick.traore at foss.st.com>
> ---
> 
>  arch/arm/mach-stm32mp/include/mach/timers.h |  9 ++++++
>  arch/arm/mach-stm32mp/timers.c              | 34 ++++++++++++++++++++-
>  2 files changed, 42 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-stm32mp/include/mach/timers.h b/arch/arm/mach-stm32mp/include/mach/timers.h
> index a84465bb28e..8209dd84911 100644
> --- a/arch/arm/mach-stm32mp/include/mach/timers.h
> +++ b/arch/arm/mach-stm32mp/include/mach/timers.h
> @@ -29,6 +29,10 @@
>  #define TIM_DMAR	0x4C	/* DMA register for transfer */
>  #define TIM_TISEL	0x68	/* Input Selection         */
>  
> +#define TIM_HWCFGR2	0x3EC	/* hardware configuration 2 Reg (MP25)	*/
> +#define TIM_HWCFGR1	0x3F0	/* hardware configuration 1 Reg (MP25)	*/
> +#define TIM_IPIDR	0x3F8	/* IP identification Reg (MP25)		*/
> +
>  #define TIM_CR1_CEN	BIT(0)	/* Counter Enable	   */
>  #define TIM_CR1_ARPE	BIT(7)
>  #define TIM_CCER_CCXE	(BIT(0) | BIT(4) | BIT(8) | BIT(12))
> @@ -40,11 +44,16 @@
>  #define TIM_CCMR_M1	(BIT(6) | BIT(5))  /* Channel PWM Mode 1 */
>  #define TIM_BDTR_MOE	BIT(15)	/* Main Output Enable      */
>  #define TIM_EGR_UG	BIT(0)	/* Update Generation       */
> +#define TIM_HWCFGR2_CNT_WIDTH	GENMASK(15, 8)	/* Counter width */
> +#define TIM_HWCFGR1_NB_OF_DT	GENMASK(7, 4)	/* Complementary outputs & dead-time generators */
>  
>  #define MAX_TIM_PSC		0xFFFF
>  
> +#define STM32MP25_TIM_IPIDR	0x00120002
> +
>  struct stm32_timers_plat {
>  	void __iomem *base;
> +	u32 ipidr;
>  };
>  
>  struct stm32_timers_priv {
> diff --git a/arch/arm/mach-stm32mp/timers.c b/arch/arm/mach-stm32mp/timers.c
> index a3207895f40..1940ba42f74 100644
> --- a/arch/arm/mach-stm32mp/timers.c
> +++ b/arch/arm/mach-stm32mp/timers.c
> @@ -10,6 +10,7 @@
>  #include <asm/io.h>
>  #include <asm/arch/timers.h>
>  #include <dm/device_compat.h>
> +#include <linux/bitfield.h>
>  
>  static void stm32_timers_get_arr_size(struct udevice *dev)
>  {
> @@ -29,6 +30,33 @@ static void stm32_timers_get_arr_size(struct udevice *dev)
>  	writel(arr, plat->base + TIM_ARR);
>  }
>  
> +static int stm32_timers_probe_hwcfgr(struct udevice *dev)
> +{
> +	struct stm32_timers_plat *plat = dev_get_plat(dev);
> +	struct stm32_timers_priv *priv = dev_get_priv(dev);
> +	u32 val;
> +
> +	if (!plat->ipidr) {
> +		/* fallback to legacy method for probing counter width */
> +		stm32_timers_get_arr_size(dev);
> +		return 0;
> +	}
> +
> +	val = readl(plat->base + TIM_IPIDR);
> +	/* Sanity check on IP identification register */
> +	if (val != plat->ipidr) {
> +		dev_err(dev, "Unexpected identification: %u\n", val);
> +		return -EINVAL;
> +	}
> +
> +	val = readl(plat->base + TIM_HWCFGR2);
> +	/* Counter width in bits, max reload value is BIT(width) - 1 */
> +	priv->max_arr = BIT(FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val)) - 1;
> +	dev_dbg(dev, "TIM width: %ld\n", FIELD_GET(TIM_HWCFGR2_CNT_WIDTH, val));
> +
> +	return 0;
> +}
> +
>  static int stm32_timers_of_to_plat(struct udevice *dev)
>  {
>  	struct stm32_timers_plat *plat = dev_get_plat(dev);
> @@ -38,6 +66,7 @@ static int stm32_timers_of_to_plat(struct udevice *dev)
>  		dev_err(dev, "can't get address\n");
>  		return -ENOENT;
>  	}
> +	plat->ipidr = (u32)dev_get_driver_data(dev);
>  
>  	return 0;
>  }
> @@ -60,13 +89,16 @@ static int stm32_timers_probe(struct udevice *dev)
>  
>  	priv->rate = clk_get_rate(&clk);
>  
> -	stm32_timers_get_arr_size(dev);
> +	ret = stm32_timers_probe_hwcfgr(dev);
> +	if (ret)
> +		clk_disable(&clk);
>  
>  	return ret;
>  }
>  
>  static const struct udevice_id stm32_timers_ids[] = {
>  	{ .compatible = "st,stm32-timers" },
> +	{ .compatible = "st,stm32mp25-timers", .data = STM32MP25_TIM_IPIDR },
>  	{}
>  };
>  
Hi Cheick

Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks


More information about the U-Boot mailing list