On 7/28/25 11:03, Patrice CHOTARD wrote:
> 
> 
> 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.tra...@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.chot...@foss.st.com>
> 
> Thanks

Applied to u-boot-stm32/master

Thanks
Patrice

Reply via email to