[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