On 5/27/25 17:48, Patrice CHOTARD wrote:
> 
> 
> On 5/12/25 19:09, Marek Vasut wrote:
>> Add support for configuring DRAM controller on STM32MP13xx SoC.
>> The DRAM controller is basically identical to the DWC controller
>> on STM32MP15xx SoC, except the bus width is reduced from 32bit to
>> 16bit and a few registers and bits are therefore not present.
>>
>> Handle the difference by factoring these parts out. Use IS_ENABLE()
>> as much as possible to assure code which is not enabled on builds
>> for a single SoC gets compiled out. Handle the different offset of
>> RCC_DDRITFCR register and missing DDRC2 clock the same way.
>>
>> Signed-off-by: Marek Vasut <marek.va...@mailbox.org>
> 
> Reviewed-by: Patrice Chotard <patrice.chot...@foss.st.com>

Applied to u-boot-stm32/next

Thanks
Patrice

> 
> Thanks
> Patrice
> 
>> ---
>> Cc: Patrice Chotard <patrice.chot...@foss.st.com>
>> Cc: Patrick Delaunay <patrick.delau...@foss.st.com>
>> Cc: Simon Glass <s...@chromium.org>
>> Cc: Tom Rini <tr...@konsulko.com>
>> Cc: u-boot@lists.denx.de
>> Cc: uboot-st...@st-md-mailman.stormreply.com
>> ---
>>  drivers/ram/stm32mp1/stm32mp1_ddr.c | 95 +++++++++++++++++++++++------
>>  drivers/ram/stm32mp1/stm32mp1_ddr.h |  6 ++
>>  drivers/ram/stm32mp1/stm32mp1_ram.c |  5 ++
>>  3 files changed, 87 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c 
>> b/drivers/ram/stm32mp1/stm32mp1_ddr.c
>> index 0e37ea93fbc..b275407d4ac 100644
>> --- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
>> +++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
>> @@ -12,6 +12,7 @@
>>  #include <timer.h>
>>  #include <asm/io.h>
>>  #include <asm/arch/ddr.h>
>> +#include <dm/device.h>
>>  #include <linux/bitops.h>
>>  #include <linux/delay.h>
>>  #include <linux/iopoll.h>
>> @@ -19,7 +20,8 @@
>>  #include "stm32mp1_ddr.h"
>>  #include "stm32mp1_ddr_regs.h"
>>  
>> -#define RCC_DDRITFCR                0xD8
>> +#define RCC_DDRITFCR_STM32MP13xx    0x5c0
>> +#define RCC_DDRITFCR_STM32MP15xx    0xd8
>>  
>>  #define RCC_DDRITFCR_DDRCAPBRST             (BIT(14))
>>  #define RCC_DDRITFCR_DDRCAXIRST             (BIT(15))
>> @@ -66,9 +68,19 @@ struct reg_desc {
>>  #define DDRCTL_REG_REG_SIZE 25      /* st,ctl-reg */
>>  #define DDRCTL_REG_TIMING_SIZE      12      /* st,ctl-timing */
>>  #define DDRCTL_REG_MAP_SIZE 9       /* st,ctl-map */
>> -#define DDRCTL_REG_PERF_SIZE        17      /* st,ctl-perf */
>>  
>> -#define DDRPHY_REG_REG_SIZE 11      /* st,phy-reg */
>> +#define DDRCTL_REG_PERF_SIZE_STM32MP13xx    11      /* st,ctl-perf */
>> +#define DDRCTL_REG_PERF_SIZE_STM32MP15xx    17      /* st,ctl-perf */
>> +#define DDRCTL_REG_PERF_SIZE                \
>> +    (IS_ENABLED(CONFIG_STM32MP15X) ? DDRCTL_REG_PERF_SIZE_STM32MP15xx : \
>> +                                     DDRCTL_REG_PERF_SIZE_STM32MP13xx)
>> +
>> +#define DDRPHY_REG_REG_SIZE_STM32MP13xx             9       /* st,phy-reg */
>> +#define DDRPHY_REG_REG_SIZE_STM32MP15xx             11      /* st,phy-reg */
>> +#define DDRPHY_REG_REG_SIZE \
>> +    (IS_ENABLED(CONFIG_STM32MP15X) ? DDRPHY_REG_REG_SIZE_STM32MP15xx : \
>> +                                     DDRPHY_REG_REG_SIZE_STM32MP13xx)
>> +
>>  #define     DDRPHY_REG_TIMING_SIZE  10      /* st,phy-timing */
>>  
>>  #define DDRCTL_REG_REG(x)   DDRCTL_REG(x, stm32mp1_ddrctrl_reg)
>> @@ -142,12 +154,14 @@ static const struct reg_desc 
>> ddr_perf[DDRCTL_REG_PERF_SIZE] = {
>>      DDRCTL_REG_PERF(pcfgqos1_0),
>>      DDRCTL_REG_PERF(pcfgwqos0_0),
>>      DDRCTL_REG_PERF(pcfgwqos1_0),
>> +#if IS_ENABLED(CONFIG_STM32MP15X)
>>      DDRCTL_REG_PERF(pcfgr_1),
>>      DDRCTL_REG_PERF(pcfgw_1),
>>      DDRCTL_REG_PERF(pcfgqos0_1),
>>      DDRCTL_REG_PERF(pcfgqos1_1),
>>      DDRCTL_REG_PERF(pcfgwqos0_1),
>>      DDRCTL_REG_PERF(pcfgwqos1_1),
>> +#endif
>>  };
>>  
>>  #define DDRPHY_REG_REG(x)   DDRPHY_REG(x, stm32mp1_ddrphy_reg)
>> @@ -161,8 +175,10 @@ static const struct reg_desc 
>> ddrphy_reg[DDRPHY_REG_REG_SIZE] = {
>>      DDRPHY_REG_REG(zq0cr1),
>>      DDRPHY_REG_REG(dx0gcr),
>>      DDRPHY_REG_REG(dx1gcr),
>> +#if IS_ENABLED(CONFIG_STM32MP15X)
>>      DDRPHY_REG_REG(dx2gcr),
>>      DDRPHY_REG_REG(dx3gcr),
>> +#endif
>>  };
>>  
>>  #define DDRPHY_REG_TIMING(x)        DDRPHY_REG(x, stm32mp1_ddrphy_timing)
>> @@ -211,6 +227,7 @@ static const struct reg_desc ddrphy_dyn[] = {
>>      DDRPHY_REG_DYN(dx1dllcr),
>>      DDRPHY_REG_DYN(dx1dqtr),
>>      DDRPHY_REG_DYN(dx1dqstr),
>> +#if IS_ENABLED(CONFIG_STM32MP15X)
>>      DDRPHY_REG_DYN(dx2gsr0),
>>      DDRPHY_REG_DYN(dx2gsr1),
>>      DDRPHY_REG_DYN(dx2dllcr),
>> @@ -221,6 +238,7 @@ static const struct reg_desc ddrphy_dyn[] = {
>>      DDRPHY_REG_DYN(dx3dllcr),
>>      DDRPHY_REG_DYN(dx3dqtr),
>>      DDRPHY_REG_DYN(dx3dqstr),
>> +#endif
>>  };
>>  
>>  #define DDRPHY_REG_DYN_SIZE ARRAY_SIZE(ddrphy_dyn)
>> @@ -287,6 +305,24 @@ const char *base_name[] = {
>>      [DDRPHY_BASE] = "phy",
>>  };
>>  
>> +bool is_stm32mp13_ddrc(const struct ddr_info *priv)
>> +{
>> +    if (IS_ENABLED(CONFIG_STM32MP13X) && !IS_ENABLED(CONFIG_STM32MP15X))
>> +            return true;            /* STM32MP13xx only build */
>> +    else if (!IS_ENABLED(CONFIG_STM32MP13X) && 
>> IS_ENABLED(CONFIG_STM32MP15X))
>> +            return false;   /* STM32MP15xx only build */
>> +
>> +    /* Combined STM32MP13xx and STM32MP15xx build */
>> +    return device_is_compatible(priv->dev, "st,stm32mp13-ddr");
>> +}
>> +
>> +static u32 get_rcc_ddritfcr(const struct ddr_info *priv)
>> +{
>> +    return priv->rcc + (is_stm32mp13_ddrc(priv) ?
>> +                        RCC_DDRITFCR_STM32MP13xx :
>> +                        RCC_DDRITFCR_STM32MP15xx);
>> +}
>> +
>>  static u32 get_base_addr(const struct ddr_info *priv, enum base_type base)
>>  {
>>      if (base == DDRPHY_BASE)
>> @@ -295,6 +331,21 @@ static u32 get_base_addr(const struct ddr_info *priv, 
>> enum base_type base)
>>              return (u32)priv->ctl;
>>  }
>>  
>> +static u32 get_type_size(const struct ddr_info *priv, enum reg_type type)
>> +{
>> +    bool is_mp13 = is_stm32mp13_ddrc(priv);
>> +
>> +    if (type == REG_PERF)
>> +            return is_mp13 ? DDRCTL_REG_PERF_SIZE_STM32MP13xx :
>> +                             DDRCTL_REG_PERF_SIZE_STM32MP15xx;
>> +    else if (type == REGPHY_REG)
>> +            return is_mp13 ? DDRPHY_REG_REG_SIZE_STM32MP13xx :
>> +                             DDRPHY_REG_REG_SIZE_STM32MP15xx;
>> +
>> +    /* Everything else is the default size */
>> +    return ddr_registers[type].size;
>> +}
>> +
>>  static void set_reg(const struct ddr_info *priv,
>>                  enum reg_type type,
>>                  const void *param)
>> @@ -304,9 +355,10 @@ static void set_reg(const struct ddr_info *priv,
>>      enum base_type base = ddr_registers[type].base;
>>      u32 base_addr = get_base_addr(priv, base);
>>      const struct reg_desc *desc = ddr_registers[type].desc;
>> +    u32 size = get_type_size(priv, type);
>>  
>>      log_debug("init %s\n", ddr_registers[type].name);
>> -    for (i = 0; i < ddr_registers[type].size; i++) {
>> +    for (i = 0; i < size; i++) {
>>              ptr = (unsigned int *)(base_addr + desc[i].offset);
>>              if (desc[i].par_offset == INVALID_OFFSET) {
>>                      log_err("invalid parameter offset for %s", 
>> desc[i].name);
>> @@ -656,12 +708,13 @@ static void stm32mp1_refresh_restore(struct 
>> stm32mp1_ddrctl *ctl,
>>  static void stm32mp1_asr_enable(struct ddr_info *priv, const u32 pwrctl)
>>  {
>>      struct stm32mp1_ddrctl *ctl = priv->ctl;
>> +    u32 rcc_ddritfcr = get_rcc_ddritfcr(priv);
>>  
>>      /* SSR is the best we can do. */
>>      if (!(pwrctl & DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE))
>>              return;
>>  
>> -    clrsetbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCKMOD_MASK,
>> +    clrsetbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DDRCKMOD_MASK,
>>                      RCC_DDRITFCR_DDRCKMOD_ASR);
>>  
>>      start_sw_done(ctl);
>> @@ -691,6 +744,7 @@ __maybe_unused
>>  void stm32mp1_ddr_init(struct ddr_info *priv,
>>                     const struct stm32mp1_ddr_config *config)
>>  {
>> +    u32 rcc_ddritfcr = get_rcc_ddritfcr(priv);
>>      u32 pir;
>>      int ret = -EINVAL;
>>      char bus_width;
>> @@ -732,12 +786,12 @@ start:
>>   * 1.1 RESETS: presetn, core_ddrc_rstn, aresetn
>>   */
>>      /* Assert All DDR part */
>> -    setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
>> -    setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST);
>> -    setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST);
>> -    setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYAPBRST);
>> -    setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYRST);
>> -    setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYCTLRST);
>> +    setbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAPBRST);
>> +    setbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAXIRST);
>> +    setbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DDRCORERST);
>> +    setbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DPHYAPBRST);
>> +    setbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DPHYRST);
>> +    setbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DPHYCTLRST);
>>  
>>  /* 1.2. start CLOCK */
>>      if (stm32mp1_ddr_clk_enable(priv, config->info.speed))
>> @@ -746,12 +800,12 @@ start:
>>  
>>  /* 1.3. deassert reset */
>>      /* de-assert PHY rstn and ctl_rstn via DPHYRST and DPHYCTLRST */
>> -    clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYRST);
>> -    clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYCTLRST);
>> +    clrbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DPHYRST);
>> +    clrbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DPHYCTLRST);
>>      /* De-assert presetn once the clocks are active
>>       * and stable via DDRCAPBRST bit
>>       */
>> -    clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
>> +    clrbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAPBRST);
>>  
>>  /* 1.4. wait 128 cycles to permit initialization of end logic */
>>      udelay(2);
>> @@ -781,9 +835,9 @@ start:
>>              goto start;
>>  
>>  /*  2. deassert reset signal core_ddrc_rstn, aresetn and presetn */
>> -    clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST);
>> -    clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST);
>> -    clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYAPBRST);
>> +    clrbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DDRCORERST);
>> +    clrbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DDRCAXIRST);
>> +    clrbits_le32(rcc_ddritfcr, RCC_DDRITFCR_DPHYAPBRST);
>>  
>>  /*  3. start PHY init by accessing relevant PUBL registers
>>   *    (DXGCR, DCR, PTR*, MR*, DTPR*)
>> @@ -854,9 +908,12 @@ start:
>>  /* Enable auto-self-refresh, which saves a bit of power at runtime. */
>>      stm32mp1_asr_enable(priv, config->c_reg.pwrctl);
>>  
>> -    /* enable uMCTL2 AXI port 0 and 1 */
>> +    /* enable uMCTL2 AXI port 0 */
>>      setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
>> -    setbits_le32(&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
>> +
>> +    /* enable uMCTL2 AXI port 1 only on STM32MP15xx with 32bit DRAM bus */
>> +    if (!is_stm32mp13_ddrc(priv))
>> +            setbits_le32(&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
>>  
>>      if (INTERACTIVE(STEP_DDR_READY))
>>              goto start;
>> diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.h 
>> b/drivers/ram/stm32mp1/stm32mp1_ddr.h
>> index 861efff92be..3621e6c9a1b 100644
>> --- a/drivers/ram/stm32mp1/stm32mp1_ddr.h
>> +++ b/drivers/ram/stm32mp1/stm32mp1_ddr.h
>> @@ -105,12 +105,14 @@ struct stm32mp1_ddrctrl_perf {
>>      u32 pcfgqos1_0;
>>      u32 pcfgwqos0_0;
>>      u32 pcfgwqos1_0;
>> +#if IS_ENABLED(CONFIG_STM32MP15X)
>>      u32 pcfgr_1;
>>      u32 pcfgw_1;
>>      u32 pcfgqos0_1;
>>      u32 pcfgqos1_1;
>>      u32 pcfgwqos0_1;
>>      u32 pcfgwqos1_1;
>> +#endif
>>  };
>>  
>>  struct stm32mp1_ddrphy_reg {
>> @@ -123,8 +125,10 @@ struct stm32mp1_ddrphy_reg {
>>      u32 zq0cr1;
>>      u32 dx0gcr;
>>      u32 dx1gcr;
>> +#if IS_ENABLED(CONFIG_STM32MP15X)
>>      u32 dx2gcr;
>>      u32 dx3gcr;
>> +#endif
>>  };
>>  
>>  struct stm32mp1_ddrphy_timing {
>> @@ -181,4 +185,6 @@ bool stm32mp1_ddr_interactive(
>>      enum stm32mp1_ddr_interact_step step,
>>      const struct stm32mp1_ddr_config *config);
>>  
>> +bool is_stm32mp13_ddrc(const struct ddr_info *priv);
>> +
>>  #endif
>> diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c 
>> b/drivers/ram/stm32mp1/stm32mp1_ram.c
>> index e9cd6229ec4..5f9b91d50e4 100644
>> --- a/drivers/ram/stm32mp1/stm32mp1_ram.c
>> +++ b/drivers/ram/stm32mp1/stm32mp1_ram.c
>> @@ -33,6 +33,7 @@ static const char *const clkname[] = {
>>  
>>  int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed)
>>  {
>> +    bool is_mp13 = is_stm32mp13_ddrc(priv);
>>      unsigned long ddrphy_clk;
>>      unsigned long ddr_clk;
>>      struct clk clk;
>> @@ -40,6 +41,10 @@ int stm32mp1_ddr_clk_enable(struct ddr_info *priv, 
>> uint32_t mem_speed)
>>      unsigned int idx;
>>  
>>      for (idx = 0; idx < ARRAY_SIZE(clkname); idx++) {
>> +            /* DDRC2 clock are available only on STM32MP15xx */
>> +            if (is_mp13 && !strcmp(clkname[idx], "ddrc2"))
>> +                    continue;
>> +
>>              ret = clk_get_by_name(priv->dev, clkname[idx], &clk);
>>  
>>              if (!ret)

Reply via email to