[PATCH] sunxi: dram: detect non-power-of-2 sized DRAM chips
    Andre Przywara 
    andre.przywara at arm.com
       
    Wed Oct 22 22:33:39 CEST 2025
    
    
  
On Wed, 22 Oct 2025 17:48:27 +0200
Jernej Škrabec <jernej.skrabec at gmail.com> wrote:
Hi Jernej,
> Dne sreda, 22. oktober 2025 ob 01:53:34 Srednjeevropski poletni čas je Andre Przywara napisal(a):
> > Some boards feature an "odd" DRAM size, where the total RAM is 1.5GB or
> > 3GB. Our existing DRAM size detection routines can only detect power-of-2
> > sized configuration, and on those boards the DRAM size is overestimated,
> > so this typically breaks the boot quite early.
> > 
> > There doesn't seem to be an easy explicit way to detect those odd-sized
> > chips, but we can test whether the later part of the memory behaves like
> > memory, by verifying that a written pattern can be read back.
> > Experiments show that there is no aliasing effect here, as all locations
> > in the unimplemented range always return some fixed pattern, and cannot
> > be changed.
> > 
> > Also so far all those boards use a factor of 3 of some lower power-of-2
> > number, or 3/4th of some higher number. The size detection routine
> > discovers the higher number, so we can check for some memory cells beyond
> > 75% of the detected size to be legit.
> > 
> > Add a routine the inverts all bits at a given location in memory, and
> > reads that back to prove that the new value was stored.
> > Then test the memory cell at exactly 3/4th of the detected size, and cap
> > the size of the memory to 75% when this test fails.
> > 
> > This enables boards which ship with such odd memory sizes.
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> > Hi,
> > 
> > I don't really have a board with such an odd size to test that, though the
> > function worked on a 12GB A733 board. But that's not supporting the SPL
> > or any kind of DRAM init yet, so was tested out of context.
> > I would be grateful if anyone with a 1.5GB or 3GB board could test this.
> > 
> > Thanks,
> > Andre
> > 
> >  arch/arm/include/asm/arch-sunxi/dram.h |  1 +
> >  arch/arm/mach-sunxi/dram_dw_helpers.c  | 16 +++++++++++++++-
> >  arch/arm/mach-sunxi/dram_helpers.c     | 12 ++++++++++++
> >  3 files changed, 28 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
> > index 0eccb1e6c28..59e2e980bfa 100644
> > --- a/arch/arm/include/asm/arch-sunxi/dram.h
> > +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> > @@ -45,5 +45,6 @@ unsigned long sunxi_dram_init(void);
> >  void mctl_await_completion(u32 *reg, u32 mask, u32 val);
> >  bool mctl_mem_matches(u32 offset);
> >  bool mctl_mem_matches_base(u32 offset, ulong base);
> > +bool mctl_check_memory(phys_addr_t addr);
> >  
> >  #endif /* _SUNXI_DRAM_H */
> > diff --git a/arch/arm/mach-sunxi/dram_dw_helpers.c b/arch/arm/mach-sunxi/dram_dw_helpers.c
> > index 24767354935..14f6b24c30f 100644
> > --- a/arch/arm/mach-sunxi/dram_dw_helpers.c
> > +++ b/arch/arm/mach-sunxi/dram_dw_helpers.c
> > @@ -143,8 +143,22 @@ void mctl_auto_detect_dram_size(const struct dram_para *para,
> >  
> >  unsigned long mctl_calc_size(const struct dram_config *config)
> >  {
> > +	unsigned long size;
> >  	u8 width = config->bus_full_width ? 4 : 2;
> >  
> >  	/* 8 banks */
> > -	return (1ULL << (config->cols + config->rows + 3)) * width * config->ranks;
> > +	size = (1ULL << (config->cols + config->rows + 3)) * width *
> > +		config->ranks;
> > +
> > +	/*
> > +	 * There are boards with non-power-of-2 sized DRAM chips, like 1.5GB
> > +	 * or 3GB. They are detected as the larger power-of-2 (2GB and 4GB),
> > +	 * so test the last quarter for being able to store values.
> > +	 */
> > +	if (!mctl_check_memory(CFG_SYS_SDRAM_BASE + size / 4 * 3)) {
> > +		size = (size / 4) * 3;
> > +		debug("capping memory at %ld MB\n", size >> 20);  
> 
> As I already commented in first version of this change, wouldn't it be good to
> add additional check here, just to be sure there is no misconfiguration? In such
> case it would be better to panic than continue with unstable system.
Mmmh, but what check would that be? I mean this is mctl_calc_size(),
which is only called once, just at the end, before we return from
sunxi_dram_init(). And it just calculates the size, there is no probing
anymore, this has been done earlier, elsewhere.
At this point we assume everything is fine and properly setup, so I
don't understand what additional check we should do here. If we cannot
read back what we have written, we are in deeper trouble anyway, but we
would have missed that before anyway here, and it would have crashed
sooner or later, so I don't see a problem.
Cheers,
Andre
> 
> Best regards,
> Jernej
> 
> > +	}
> > +
> > +	return size;
> >  }
> > diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
> > index 83dbe4ca98f..376b7d14f86 100644
> > --- a/arch/arm/mach-sunxi/dram_helpers.c
> > +++ b/arch/arm/mach-sunxi/dram_helpers.c
> > @@ -62,3 +62,15 @@ bool mctl_mem_matches(u32 offset)
> >  	return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
> >  }
> >  #endif
> > +
> > +bool mctl_check_memory(phys_addr_t addr)
> > +{
> > +	uint32_t orig, val;
> > +
> > +	orig = readl(addr);
> > +	writel(~orig, addr);
> > +	val = readl(addr);
> > +	writel(orig, addr);
> > +
> > +	return ~orig == val;
> > +}
> >   
> 
> 
> 
> 
> 
    
    
More information about the U-Boot
mailing list