* Re: [PATCH] Fix detection of odd memory configurations on sunxi
[not found] <56f44755-fca8-4364-905e-685e79fd1aea@rudi-horn.de>
@ 2025-08-11 15:25 ` Jernej Škrabec
2025-08-16 12:18 ` Rudi Horn
2025-10-05 0:40 ` Andre Przywara
1 sibling, 1 reply; 9+ messages in thread
From: Jernej Škrabec @ 2025-08-11 15:25 UTC (permalink / raw)
To: Rudi Horn; +Cc: u-boot, Andre Przywara, Jagan Teki, linux-sunxi
Hi,
CC: Andre, Jagan, linux-sunxi (maintainers and customary linux-sunxi ML)
Dne ponedeljek, 11. avgust 2025 ob 09:35:19 Srednjeevropski poletni čas je Rudi Horn napisal(a):
> Hello,
>
> I encountered a bug where u-boot detects that my OrangePI zero 3 (with
> 1.5GB)
> has 2GB and crashes.
This is known missing feature, but you can also call it a bug. Anyway...
> The orangepi u-boot source code contains an additional
> modification in the `mctl_calc_size` which removes a quarter of the
> memory the
> calculated last address cannot be written to:
>
> https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_sun50i_h616.c#L1365-L1368
>
> I'm not entirely sure if there is some specific logic that applies to this
> modifier, but it does fix the issue on my system.
>
> I propose the following patch, but am open to any further suggestions.
This is pretty neat solution. Please send proper submission according to rules
with fixes below.
>
> Thanks,
> Rudi Horn
>
> Note: Submitted in my personal capacity and is not affiliated with my
> employer.
>
>
> From 2199f3b28e5fc853ed1921586358c33f3f1502d3 Mon Sep 17 00:00:00 2001
> From: Rudi Horn <dyn-git@rudi-horn.de>
> Date: Mon, 11 Aug 2025 08:58:34 +0200
> Subject: [PATCH] arch: arm: mach-sonxi: Fix detection of odd memory
> configurations
sonxi -> sunxi
However, better prefix would be "sunxi: H616: dram:" (based on git log.)
>
> Fix detection of odd memory configurations. Previously 1.5GB devices were
> incorrectly detected as 2GB devices, causing u-boot to crash.
>
> Signed-off-by: Rudi Horn <dyn-git@rudi-horn.de>
> ---
> arch/arm/include/asm/arch-sunxi/dram.h | 1 +
> arch/arm/mach-sunxi/dram_dw_helpers.c | 10 +++++++++-
> arch/arm/mach-sunxi/dram_helpers.c | 8 ++++++++
> 3 files changed, 18 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..7580421ca77 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> @@ -44,6 +44,7 @@
> 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_upto(u32 offset);
I don't see a benefit for public function here, since it's unlikely to be
used anywhere else. Just mark it static. Compiler can optimize it better.
> bool mctl_mem_matches_base(u32 offset, ulong base);
>
> #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..5bcd2672465 100644
> --- a/arch/arm/mach-sunxi/dram_dw_helpers.c
> +++ b/arch/arm/mach-sunxi/dram_dw_helpers.c
> @@ -146,5 +146,13 @@ unsigned long mctl_calc_size(const struct
> dram_config *config)
> u8 width = config->bus_full_width ? 4 : 2;
>
> /* 8 banks */
> - return (1ULL << (config->cols + config->rows + 3)) * width *
> config->ranks;
> + unsigned long size = (1ULL << (config->cols + config->rows + 3))
> * width * config->ranks;
> +
> + /* some memory configurations such as 1.5GB rely on this to
> compute the correct size */
> + if (!mctl_mem_matches_upto(size)) {
> + size = (size * 3) / 4;
> + debug("capping memory at 0x%lx\n", size);
Maybe test again? It seems to me a bit dangerous to just assume that it
will work. If it fails, panic() should be called.
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..68c75fa07a6 100644
> --- a/arch/arm/mach-sunxi/dram_helpers.c
> +++ b/arch/arm/mach-sunxi/dram_helpers.c
> @@ -61,4 +61,12 @@ bool mctl_mem_matches(u32 offset)
> {
> return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
> }
> +
> +/*
> + * Test if memory at offset matches memory at end of DRAM
> + */
> +bool mctl_mem_matches_upto(u32 offset)
> +{
> + return mctl_mem_matches_base(offset - sizeof(u32),
> CFG_SYS_SDRAM_BASE);
> +}
> #endif
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Re: [PATCH] Fix detection of odd memory configurations on sunxi
2025-08-11 15:25 ` [PATCH] Fix detection of odd memory configurations on sunxi Jernej Škrabec
@ 2025-08-16 12:18 ` Rudi Horn
2025-09-08 14:11 ` Jernej Škrabec
0 siblings, 1 reply; 9+ messages in thread
From: Rudi Horn @ 2025-08-16 12:18 UTC (permalink / raw)
To: Jernej Škrabec; +Cc: u-boot, Andre Przywara, Jagan Teki, linux-sunxi
Hi Jernej,
thanks for the comments on the patch.
> I don't see a benefit for public function here, since it's unlikely
to be > used anywhere else. Just mark it static. Compiler can optimize
it better.
My motivation for this was that the implementation relies on subtracting
`sizeof(u32)` from the address. This is an implementation detail that relies
on the internals of `mctl_mem_matches_base`, and so I wanted to place
it in the same file as `mctl_mem_matches_base`, preventing it from being
static. It will only be called twice, so I don't think optimization is
too much
of an issue. However I don't feel strongly on this if you would still prefer
it in the same file.
Once this is resolved, I will submit another patch with all of the other
comments addressed.
Thanks,
Rudi
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Fix detection of odd memory configurations on sunxi
2025-08-16 12:18 ` Rudi Horn
@ 2025-09-08 14:11 ` Jernej Škrabec
0 siblings, 0 replies; 9+ messages in thread
From: Jernej Škrabec @ 2025-09-08 14:11 UTC (permalink / raw)
To: Rudi Horn; +Cc: u-boot, Andre Przywara, Jagan Teki, linux-sunxi
Dne sobota, 16. avgust 2025 ob 14:18:44 Srednjeevropski poletni čas je Rudi Horn napisal(a):
> Hi Jernej,
>
> thanks for the comments on the patch.
>
> > I don't see a benefit for public function here, since it's unlikely
> to be > used anywhere else. Just mark it static. Compiler can optimize
> it better.
>
> My motivation for this was that the implementation relies on subtracting
> `sizeof(u32)` from the address. This is an implementation detail that relies
> on the internals of `mctl_mem_matches_base`, and so I wanted to place
> it in the same file as `mctl_mem_matches_base`, preventing it from being
> static. It will only be called twice, so I don't think optimization is
> too much
> of an issue. However I don't feel strongly on this if you would still prefer
> it in the same file.
>
> Once this is resolved, I will submit another patch with all of the other
> comments addressed.
Ah, right. You can leave as it is.
Best regards,
Jernej
>
> Thanks,
> Rudi
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Fix detection of odd memory configurations on sunxi
[not found] <56f44755-fca8-4364-905e-685e79fd1aea@rudi-horn.de>
2025-08-11 15:25 ` [PATCH] Fix detection of odd memory configurations on sunxi Jernej Škrabec
@ 2025-10-05 0:40 ` Andre Przywara
2025-10-05 6:10 ` Jernej Škrabec
1 sibling, 1 reply; 9+ messages in thread
From: Andre Przywara @ 2025-10-05 0:40 UTC (permalink / raw)
To: Rudi Horn; +Cc: u-boot, jernej.skrabec, linux-sunxi
On Mon, 11 Aug 2025 09:35:19 +0200
Rudi Horn <dyn-git@rudi-horn.de> wrote:
Hi Rudi,
thanks for sending a patch to address this long-standing issue!
But ... ;-)
> I encountered a bug where u-boot detects that my OrangePI zero 3 (with
> 1.5GB) has 2GB and crashes.
As Jernej already said, this is a known limitation: we simply don't
support not-power-of-2 DRAM sizes at the moment.
> The orangepi u-boot source code contains an additional
> modification in the `mctl_calc_size` which removes a quarter of the
> memory the
> calculated last address cannot be written to:
>
> https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_sun50i_h616.c#L1365-L1368
>
> I'm not entirely sure if there is some specific logic that applies to this
> modifier, but it does fix the issue on my system.
So can someone shed some light on how this is supposed to work? If I
understand the code correctly, it checks for *aliasing* between the
first and the last word of DRAM, which doesn't make much sense to me: I
would expect a simple write/verify to see if the last quarter of DRAM
is for real, or to check for a known aliasing pattern with this "odd"
setup (as in: last quarter is aliased to first or third quarter or
something), but checking those two words for aliasing seems wrong.
And indeed the code also fires on a board with 512MB and 4GB, capping
the memory there as well (resulting in 384 MB and 3GB, respectively).
This is somewhat expected, as we never would expect aliasing between
those two particular words, I'd say.
So since I don't have a board with an "uneven" DRAM size, can you
please test some ideas to detect this RAM setup?
- Read the content of the first word to not exist (@1.5GB), then write
something else there, and see if you can read this back? Don't forget
a write barrier (dsb();) when doing so.
- Write some test pattern to some known good DRAM locations, like the
beginning of DRAM, @512MB, @1GB, and see if any of those values pop
up @1.5GB, to see if there is an aliasing pattern?
- Can you post the exact label on that DRAM chip, so that we can see if
we find a datasheet? I'd be curious about the actual organisation of
the DRAM array.
Jernej, do you happen to know how those DRAM chips are organised? Do
they just feature a non-power-of-2 number of rows or columns?
Oh, and also this patch was heavily malformed - line breaks and spaces
instead of tabs. Please try to fix this. Simplest is probably "git
format-patch", then sending this via "git send-email". Your email
server seems to be postfix, so you could just give the SMTP details and
credentials to git.
Cheers,
Andre
>
> I propose the following patch, but am open to any further suggestions.
>
> Thanks,
> Rudi Horn
>
> Note: Submitted in my personal capacity and is not affiliated with my
> employer.
>
>
> From 2199f3b28e5fc853ed1921586358c33f3f1502d3 Mon Sep 17 00:00:00 2001
> From: Rudi Horn <dyn-git@rudi-horn.de>
> Date: Mon, 11 Aug 2025 08:58:34 +0200
> Subject: [PATCH] arch: arm: mach-sonxi: Fix detection of odd memory
> configurations
>
> Fix detection of odd memory configurations. Previously 1.5GB devices were
> incorrectly detected as 2GB devices, causing u-boot to crash.
>
> Signed-off-by: Rudi Horn <dyn-git@rudi-horn.de>
> ---
> arch/arm/include/asm/arch-sunxi/dram.h | 1 +
> arch/arm/mach-sunxi/dram_dw_helpers.c | 10 +++++++++-
> arch/arm/mach-sunxi/dram_helpers.c | 8 ++++++++
> 3 files changed, 18 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..7580421ca77 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> @@ -44,6 +44,7 @@
> 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_upto(u32 offset);
> bool mctl_mem_matches_base(u32 offset, ulong base);
>
> #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..5bcd2672465 100644
> --- a/arch/arm/mach-sunxi/dram_dw_helpers.c
> +++ b/arch/arm/mach-sunxi/dram_dw_helpers.c
> @@ -146,5 +146,13 @@ unsigned long mctl_calc_size(const struct
> dram_config *config)
> u8 width = config->bus_full_width ? 4 : 2;
>
> /* 8 banks */
> - return (1ULL << (config->cols + config->rows + 3)) * width *
> config->ranks;
> + unsigned long size = (1ULL << (config->cols + config->rows + 3))
> * width * config->ranks;
> +
> + /* some memory configurations such as 1.5GB rely on this to
> compute the correct size */
> + if (!mctl_mem_matches_upto(size)) {
> + size = (size * 3) / 4;
> + debug("capping memory at 0x%lx\n", size);
> + }
> +
> + return size;
> }
> diff --git a/arch/arm/mach-sunxi/dram_helpers.c
> b/arch/arm/mach-sunxi/dram_helpers.c
> index 83dbe4ca98f..68c75fa07a6 100644
> --- a/arch/arm/mach-sunxi/dram_helpers.c
> +++ b/arch/arm/mach-sunxi/dram_helpers.c
> @@ -61,4 +61,12 @@ bool mctl_mem_matches(u32 offset)
> {
> return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
> }
> +
> +/*
> + * Test if memory at offset matches memory at end of DRAM
> + */
> +bool mctl_mem_matches_upto(u32 offset)
> +{
> + return mctl_mem_matches_base(offset - sizeof(u32),
> CFG_SYS_SDRAM_BASE);
> +}
> #endif
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Fix detection of odd memory configurations on sunxi
2025-10-05 0:40 ` Andre Przywara
@ 2025-10-05 6:10 ` Jernej Škrabec
2025-10-05 6:38 ` Jernej Škrabec
2025-10-05 16:16 ` Andre Przywara
0 siblings, 2 replies; 9+ messages in thread
From: Jernej Škrabec @ 2025-10-05 6:10 UTC (permalink / raw)
To: Rudi Horn, Andre Przywara; +Cc: u-boot, linux-sunxi
Hi Andre!
Dne nedelja, 5. oktober 2025 ob 02:40:21 Srednjeevropski poletni čas je Andre Przywara napisal(a):
> On Mon, 11 Aug 2025 09:35:19 +0200
> Rudi Horn <dyn-git@rudi-horn.de> wrote:
>
> Hi Rudi,
>
> thanks for sending a patch to address this long-standing issue!
>
> But ... ;-)
>
> > I encountered a bug where u-boot detects that my OrangePI zero 3 (with
> > 1.5GB) has 2GB and crashes.
>
> As Jernej already said, this is a known limitation: we simply don't
> support not-power-of-2 DRAM sizes at the moment.
>
> > The orangepi u-boot source code contains an additional
> > modification in the `mctl_calc_size` which removes a quarter of the
> > memory the
> > calculated last address cannot be written to:
> >
> > https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_sun50i_h616.c#L1365-L1368
> >
> > I'm not entirely sure if there is some specific logic that applies to this
> > modifier, but it does fix the issue on my system.
>
> So can someone shed some light on how this is supposed to work? If I
> understand the code correctly, it checks for *aliasing* between the
> first and the last word of DRAM, which doesn't make much sense to me: I
> would expect a simple write/verify to see if the last quarter of DRAM
> is for real, or to check for a known aliasing pattern with this "odd"
> setup (as in: last quarter is aliased to first or third quarter or
> something), but checking those two words for aliasing seems wrong.
Hm... I've never tested this patch on HW, so you might have a point. Still,
I think testing for aliasing makes sense. Just writing and reading might
not be enough due to possible caching (not necessarily in CPU).
I should have some board with non-power-of-2 RAM size somewhere. I'll try
to find it and test this.
>
> And indeed the code also fires on a board with 512MB and 4GB, capping
> the memory there as well (resulting in 384 MB and 3GB, respectively).
> This is somewhat expected, as we never would expect aliasing between
> those two particular words, I'd say.
>
> So since I don't have a board with an "uneven" DRAM size, can you
> please test some ideas to detect this RAM setup?
> - Read the content of the first word to not exist (@1.5GB), then write
> something else there, and see if you can read this back? Don't forget
> a write barrier (dsb();) when doing so.
> - Write some test pattern to some known good DRAM locations, like the
> beginning of DRAM, @512MB, @1GB, and see if any of those values pop
> up @1.5GB, to see if there is an aliasing pattern?
> - Can you post the exact label on that DRAM chip, so that we can see if
> we find a datasheet? I'd be curious about the actual organisation of
> the DRAM array.
>
> Jernej, do you happen to know how those DRAM chips are organised? Do
> they just feature a non-power-of-2 number of rows or columns?
I don't know details how such chips are organized internally. However,
number of rows and columns was never power-of-2.
Btw, I think I saw 3 GB DRAM boards too somewhere, but not sure where.
Quick search confirms that 24 Gb DRAM chips also exists, so I would leave
this check as general 3/4 size fixup, not limited to any capacity.
>
> Oh, and also this patch was heavily malformed - line breaks and spaces
> instead of tabs. Please try to fix this. Simplest is probably "git
> format-patch", then sending this via "git send-email". Your email
> server seems to be postfix, so you could just give the SMTP details and
> credentials to git.
>
> Cheers,
> Andre
>
>
> >
> > I propose the following patch, but am open to any further suggestions.
> >
> > Thanks,
> > Rudi Horn
> >
> > Note: Submitted in my personal capacity and is not affiliated with my
> > employer.
> >
> >
> > From 2199f3b28e5fc853ed1921586358c33f3f1502d3 Mon Sep 17 00:00:00 2001
> > From: Rudi Horn <dyn-git@rudi-horn.de>
> > Date: Mon, 11 Aug 2025 08:58:34 +0200
> > Subject: [PATCH] arch: arm: mach-sonxi: Fix detection of odd memory
> > configurations
> >
> > Fix detection of odd memory configurations. Previously 1.5GB devices were
> > incorrectly detected as 2GB devices, causing u-boot to crash.
> >
> > Signed-off-by: Rudi Horn <dyn-git@rudi-horn.de>
> > ---
> > arch/arm/include/asm/arch-sunxi/dram.h | 1 +
> > arch/arm/mach-sunxi/dram_dw_helpers.c | 10 +++++++++-
> > arch/arm/mach-sunxi/dram_helpers.c | 8 ++++++++
> > 3 files changed, 18 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..7580421ca77 100644
> > --- a/arch/arm/include/asm/arch-sunxi/dram.h
> > +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> > @@ -44,6 +44,7 @@
> > 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_upto(u32 offset);
> > bool mctl_mem_matches_base(u32 offset, ulong base);
> >
> > #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..5bcd2672465 100644
> > --- a/arch/arm/mach-sunxi/dram_dw_helpers.c
> > +++ b/arch/arm/mach-sunxi/dram_dw_helpers.c
> > @@ -146,5 +146,13 @@ unsigned long mctl_calc_size(const struct
> > dram_config *config)
> > u8 width = config->bus_full_width ? 4 : 2;
> >
> > /* 8 banks */
> > - return (1ULL << (config->cols + config->rows + 3)) * width *
> > config->ranks;
> > + unsigned long size = (1ULL << (config->cols + config->rows + 3))
> > * width * config->ranks;
> > +
> > + /* some memory configurations such as 1.5GB rely on this to
> > compute the correct size */
> > + if (!mctl_mem_matches_upto(size)) {
> > + size = (size * 3) / 4;
> > + debug("capping memory at 0x%lx\n", size);
> > + }
> > +
> > + return size;
> > }
> > diff --git a/arch/arm/mach-sunxi/dram_helpers.c
> > b/arch/arm/mach-sunxi/dram_helpers.c
> > index 83dbe4ca98f..68c75fa07a6 100644
> > --- a/arch/arm/mach-sunxi/dram_helpers.c
> > +++ b/arch/arm/mach-sunxi/dram_helpers.c
> > @@ -61,4 +61,12 @@ bool mctl_mem_matches(u32 offset)
> > {
> > return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
> > }
> > +
> > +/*
> > + * Test if memory at offset matches memory at end of DRAM
> > + */
> > +bool mctl_mem_matches_upto(u32 offset)
> > +{
> > + return mctl_mem_matches_base(offset - sizeof(u32),
> > CFG_SYS_SDRAM_BASE);
> > +}
> > #endif
> > --
> > 2.43.0
> >
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Fix detection of odd memory configurations on sunxi
2025-10-05 6:10 ` Jernej Škrabec
@ 2025-10-05 6:38 ` Jernej Škrabec
2025-10-05 16:30 ` Andre Przywara
2025-10-05 16:16 ` Andre Przywara
1 sibling, 1 reply; 9+ messages in thread
From: Jernej Škrabec @ 2025-10-05 6:38 UTC (permalink / raw)
To: Rudi Horn, Andre Przywara; +Cc: u-boot, linux-sunxi
Dne nedelja, 5. oktober 2025 ob 08:10:27 Srednjeevropski poletni čas je Jernej Škrabec napisal(a):
> Hi Andre!
>
> Dne nedelja, 5. oktober 2025 ob 02:40:21 Srednjeevropski poletni čas je Andre Przywara napisal(a):
> > On Mon, 11 Aug 2025 09:35:19 +0200
> > Rudi Horn <dyn-git@rudi-horn.de> wrote:
> >
> > Hi Rudi,
> >
> > thanks for sending a patch to address this long-standing issue!
> >
> > But ... ;-)
> >
> > > I encountered a bug where u-boot detects that my OrangePI zero 3 (with
> > > 1.5GB) has 2GB and crashes.
> >
> > As Jernej already said, this is a known limitation: we simply don't
> > support not-power-of-2 DRAM sizes at the moment.
> >
> > > The orangepi u-boot source code contains an additional
> > > modification in the `mctl_calc_size` which removes a quarter of the
> > > memory the
> > > calculated last address cannot be written to:
> > >
> > > https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_sun50i_h616.c#L1365-L1368
> > >
> > > I'm not entirely sure if there is some specific logic that applies to this
> > > modifier, but it does fix the issue on my system.
> >
> > So can someone shed some light on how this is supposed to work? If I
> > understand the code correctly, it checks for *aliasing* between the
> > first and the last word of DRAM, which doesn't make much sense to me: I
> > would expect a simple write/verify to see if the last quarter of DRAM
> > is for real, or to check for a known aliasing pattern with this "odd"
> > setup (as in: last quarter is aliased to first or third quarter or
> > something), but checking those two words for aliasing seems wrong.
>
> Hm... I've never tested this patch on HW, so you might have a point. Still,
> I think testing for aliasing makes sense. Just writing and reading might
> not be enough due to possible caching (not necessarily in CPU).
I see where the confusion comes from. Rudi tried to replicate OrangePi code
but inadvertently used function for aliasing check instead of write/verify
as noticed by Andre.
While probably using OrangePi approach [1] would work fine, I learned to
distrust simple write/verify checks, especially when size is only 1 word.
I would be still more confortable to use current aliasing check, which uses
16 words check.
Best regards,
Jernej
[1] https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_helpers.c#L48-L63
>
> I should have some board with non-power-of-2 RAM size somewhere. I'll try
> to find it and test this.
>
> >
> > And indeed the code also fires on a board with 512MB and 4GB, capping
> > the memory there as well (resulting in 384 MB and 3GB, respectively).
> > This is somewhat expected, as we never would expect aliasing between
> > those two particular words, I'd say.
> >
> > So since I don't have a board with an "uneven" DRAM size, can you
> > please test some ideas to detect this RAM setup?
> > - Read the content of the first word to not exist (@1.5GB), then write
> > something else there, and see if you can read this back? Don't forget
> > a write barrier (dsb();) when doing so.
> > - Write some test pattern to some known good DRAM locations, like the
> > beginning of DRAM, @512MB, @1GB, and see if any of those values pop
> > up @1.5GB, to see if there is an aliasing pattern?
> > - Can you post the exact label on that DRAM chip, so that we can see if
> > we find a datasheet? I'd be curious about the actual organisation of
> > the DRAM array.
> >
> > Jernej, do you happen to know how those DRAM chips are organised? Do
> > they just feature a non-power-of-2 number of rows or columns?
>
> I don't know details how such chips are organized internally. However,
> number of rows and columns was never power-of-2.
>
> Btw, I think I saw 3 GB DRAM boards too somewhere, but not sure where.
> Quick search confirms that 24 Gb DRAM chips also exists, so I would leave
> this check as general 3/4 size fixup, not limited to any capacity.
>
> >
> > Oh, and also this patch was heavily malformed - line breaks and spaces
> > instead of tabs. Please try to fix this. Simplest is probably "git
> > format-patch", then sending this via "git send-email". Your email
> > server seems to be postfix, so you could just give the SMTP details and
> > credentials to git.
> >
> > Cheers,
> > Andre
> >
> >
> > >
> > > I propose the following patch, but am open to any further suggestions.
> > >
> > > Thanks,
> > > Rudi Horn
> > >
> > > Note: Submitted in my personal capacity and is not affiliated with my
> > > employer.
> > >
> > >
> > > From 2199f3b28e5fc853ed1921586358c33f3f1502d3 Mon Sep 17 00:00:00 2001
> > > From: Rudi Horn <dyn-git@rudi-horn.de>
> > > Date: Mon, 11 Aug 2025 08:58:34 +0200
> > > Subject: [PATCH] arch: arm: mach-sonxi: Fix detection of odd memory
> > > configurations
> > >
> > > Fix detection of odd memory configurations. Previously 1.5GB devices were
> > > incorrectly detected as 2GB devices, causing u-boot to crash.
> > >
> > > Signed-off-by: Rudi Horn <dyn-git@rudi-horn.de>
> > > ---
> > > arch/arm/include/asm/arch-sunxi/dram.h | 1 +
> > > arch/arm/mach-sunxi/dram_dw_helpers.c | 10 +++++++++-
> > > arch/arm/mach-sunxi/dram_helpers.c | 8 ++++++++
> > > 3 files changed, 18 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..7580421ca77 100644
> > > --- a/arch/arm/include/asm/arch-sunxi/dram.h
> > > +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> > > @@ -44,6 +44,7 @@
> > > 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_upto(u32 offset);
> > > bool mctl_mem_matches_base(u32 offset, ulong base);
> > >
> > > #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..5bcd2672465 100644
> > > --- a/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > +++ b/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > @@ -146,5 +146,13 @@ unsigned long mctl_calc_size(const struct
> > > dram_config *config)
> > > u8 width = config->bus_full_width ? 4 : 2;
> > >
> > > /* 8 banks */
> > > - return (1ULL << (config->cols + config->rows + 3)) * width *
> > > config->ranks;
> > > + unsigned long size = (1ULL << (config->cols + config->rows + 3))
> > > * width * config->ranks;
> > > +
> > > + /* some memory configurations such as 1.5GB rely on this to
> > > compute the correct size */
> > > + if (!mctl_mem_matches_upto(size)) {
> > > + size = (size * 3) / 4;
> > > + debug("capping memory at 0x%lx\n", size);
> > > + }
> > > +
> > > + return size;
> > > }
> > > diff --git a/arch/arm/mach-sunxi/dram_helpers.c
> > > b/arch/arm/mach-sunxi/dram_helpers.c
> > > index 83dbe4ca98f..68c75fa07a6 100644
> > > --- a/arch/arm/mach-sunxi/dram_helpers.c
> > > +++ b/arch/arm/mach-sunxi/dram_helpers.c
> > > @@ -61,4 +61,12 @@ bool mctl_mem_matches(u32 offset)
> > > {
> > > return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
> > > }
> > > +
> > > +/*
> > > + * Test if memory at offset matches memory at end of DRAM
> > > + */
> > > +bool mctl_mem_matches_upto(u32 offset)
> > > +{
> > > + return mctl_mem_matches_base(offset - sizeof(u32),
> > > CFG_SYS_SDRAM_BASE);
> > > +}
> > > #endif
> > > --
> > > 2.43.0
> > >
> >
> >
>
>
>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Fix detection of odd memory configurations on sunxi
2025-10-05 6:10 ` Jernej Škrabec
2025-10-05 6:38 ` Jernej Škrabec
@ 2025-10-05 16:16 ` Andre Przywara
2025-10-06 23:09 ` Andre Przywara
1 sibling, 1 reply; 9+ messages in thread
From: Andre Przywara @ 2025-10-05 16:16 UTC (permalink / raw)
To: Jernej Škrabec; +Cc: Rudi Horn, u-boot, linux-sunxi
On Sun, 05 Oct 2025 08:10:27 +0200
Jernej Škrabec <jernej.skrabec@gmail.com> wrote:
Hi,
> Dne nedelja, 5. oktober 2025 ob 02:40:21 Srednjeevropski poletni čas je Andre Przywara napisal(a):
> > On Mon, 11 Aug 2025 09:35:19 +0200
> > Rudi Horn <dyn-git@rudi-horn.de> wrote:
> >
> > Hi Rudi,
> >
> > thanks for sending a patch to address this long-standing issue!
> >
> > But ... ;-)
> >
> > > I encountered a bug where u-boot detects that my OrangePI zero 3 (with
> > > 1.5GB) has 2GB and crashes.
> >
> > As Jernej already said, this is a known limitation: we simply don't
> > support not-power-of-2 DRAM sizes at the moment.
> >
> > > The orangepi u-boot source code contains an additional
> > > modification in the `mctl_calc_size` which removes a quarter of the
> > > memory the
> > > calculated last address cannot be written to:
> > >
> > > https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_sun50i_h616.c#L1365-L1368
> > >
> > > I'm not entirely sure if there is some specific logic that applies to this
> > > modifier, but it does fix the issue on my system.
> >
> > So can someone shed some light on how this is supposed to work? If I
> > understand the code correctly, it checks for *aliasing* between the
> > first and the last word of DRAM, which doesn't make much sense to me: I
> > would expect a simple write/verify to see if the last quarter of DRAM
> > is for real, or to check for a known aliasing pattern with this "odd"
> > setup (as in: last quarter is aliased to first or third quarter or
> > something), but checking those two words for aliasing seems wrong.
>
> Hm... I've never tested this patch on HW, so you might have a point. Still,
> I think testing for aliasing makes sense. Just writing and reading might
> not be enough due to possible caching (not necessarily in CPU).
Sure, aliasing trumps verifying, but it might be easier to test the
latter?
> I should have some board with non-power-of-2 RAM size somewhere. I'll try
> to find it and test this.
I just realised that my Cubie A7A has 12GB(!) of DRAM, so I can actually do
some experiments here, in U-Boot proper, after boot0 has initialised the DRAM:
[5912]DRAM SIZE =12288 MBytes, para1 = a11a, para2 = 30001001, dram_tpr13 = 10065
> > And indeed the code also fires on a board with 512MB and 4GB, capping
> > the memory there as well (resulting in 384 MB and 3GB, respectively).
> > This is somewhat expected, as we never would expect aliasing between
> > those two particular words, I'd say.
> >
> > So since I don't have a board with an "uneven" DRAM size, can you
> > please test some ideas to detect this RAM setup?
> > - Read the content of the first word to not exist (@1.5GB), then write
> > something else there, and see if you can read this back? Don't forget
> > a write barrier (dsb();) when doing so.
> > - Write some test pattern to some known good DRAM locations, like the
> > beginning of DRAM, @512MB, @1GB, and see if any of those values pop
> > up @1.5GB, to see if there is an aliasing pattern?
> > - Can you post the exact label on that DRAM chip, so that we can see if
> > we find a datasheet? I'd be curious about the actual organisation of
> > the DRAM array.
> >
> > Jernej, do you happen to know how those DRAM chips are organised? Do
> > they just feature a non-power-of-2 number of rows or columns?
>
> I don't know details how such chips are organized internally. However,
> number of rows and columns was never power-of-2.
Ah right, brain fart on my end, those are of course the exponents in the
calculation, so result in the eventual power-of-2 number. I then wonder
where the factor of 3 comes in, are there 6 banks, or 3 ranks (doubt
that)? I could not find a datasheet of one of those 12Gbit Samsung
chips yet.
> Btw, I think I saw 3 GB DRAM boards too somewhere, but not sure where.
> Quick search confirms that 24 Gb DRAM chips also exists, so I would leave
> this check as general 3/4 size fixup, not limited to any capacity.
Oh, definitely, the only constant here would be the 3/4th. So the plan
would be to detect some oddity (either through aliasing or because of
missing DRAM cells at the end), then assume it's 3/4 of the detected
capacity.
Cheers,
Andre
>
> >
> > Oh, and also this patch was heavily malformed - line breaks and spaces
> > instead of tabs. Please try to fix this. Simplest is probably "git
> > format-patch", then sending this via "git send-email". Your email
> > server seems to be postfix, so you could just give the SMTP details and
> > credentials to git.
> >
> > Cheers,
> > Andre
> >
> >
> > >
> > > I propose the following patch, but am open to any further suggestions.
> > >
> > > Thanks,
> > > Rudi Horn
> > >
> > > Note: Submitted in my personal capacity and is not affiliated with my
> > > employer.
> > >
> > >
> > > From 2199f3b28e5fc853ed1921586358c33f3f1502d3 Mon Sep 17 00:00:00 2001
> > > From: Rudi Horn <dyn-git@rudi-horn.de>
> > > Date: Mon, 11 Aug 2025 08:58:34 +0200
> > > Subject: [PATCH] arch: arm: mach-sonxi: Fix detection of odd memory
> > > configurations
> > >
> > > Fix detection of odd memory configurations. Previously 1.5GB devices were
> > > incorrectly detected as 2GB devices, causing u-boot to crash.
> > >
> > > Signed-off-by: Rudi Horn <dyn-git@rudi-horn.de>
> > > ---
> > > arch/arm/include/asm/arch-sunxi/dram.h | 1 +
> > > arch/arm/mach-sunxi/dram_dw_helpers.c | 10 +++++++++-
> > > arch/arm/mach-sunxi/dram_helpers.c | 8 ++++++++
> > > 3 files changed, 18 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..7580421ca77 100644
> > > --- a/arch/arm/include/asm/arch-sunxi/dram.h
> > > +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> > > @@ -44,6 +44,7 @@
> > > 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_upto(u32 offset);
> > > bool mctl_mem_matches_base(u32 offset, ulong base);
> > >
> > > #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..5bcd2672465 100644
> > > --- a/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > +++ b/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > @@ -146,5 +146,13 @@ unsigned long mctl_calc_size(const struct
> > > dram_config *config)
> > > u8 width = config->bus_full_width ? 4 : 2;
> > >
> > > /* 8 banks */
> > > - return (1ULL << (config->cols + config->rows + 3)) * width *
> > > config->ranks;
> > > + unsigned long size = (1ULL << (config->cols + config->rows + 3))
> > > * width * config->ranks;
> > > +
> > > + /* some memory configurations such as 1.5GB rely on this to
> > > compute the correct size */
> > > + if (!mctl_mem_matches_upto(size)) {
> > > + size = (size * 3) / 4;
> > > + debug("capping memory at 0x%lx\n", size);
> > > + }
> > > +
> > > + return size;
> > > }
> > > diff --git a/arch/arm/mach-sunxi/dram_helpers.c
> > > b/arch/arm/mach-sunxi/dram_helpers.c
> > > index 83dbe4ca98f..68c75fa07a6 100644
> > > --- a/arch/arm/mach-sunxi/dram_helpers.c
> > > +++ b/arch/arm/mach-sunxi/dram_helpers.c
> > > @@ -61,4 +61,12 @@ bool mctl_mem_matches(u32 offset)
> > > {
> > > return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
> > > }
> > > +
> > > +/*
> > > + * Test if memory at offset matches memory at end of DRAM
> > > + */
> > > +bool mctl_mem_matches_upto(u32 offset)
> > > +{
> > > + return mctl_mem_matches_base(offset - sizeof(u32),
> > > CFG_SYS_SDRAM_BASE);
> > > +}
> > > #endif
> > > --
> > > 2.43.0
> > >
> >
> >
>
>
>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Fix detection of odd memory configurations on sunxi
2025-10-05 6:38 ` Jernej Škrabec
@ 2025-10-05 16:30 ` Andre Przywara
0 siblings, 0 replies; 9+ messages in thread
From: Andre Przywara @ 2025-10-05 16:30 UTC (permalink / raw)
To: Jernej Škrabec; +Cc: Rudi Horn, u-boot, linux-sunxi
On Sun, 05 Oct 2025 08:38:32 +0200
Jernej Škrabec <jernej.skrabec@gmail.com> wrote:
Hi,
> Dne nedelja, 5. oktober 2025 ob 08:10:27 Srednjeevropski poletni čas je Jernej Škrabec napisal(a):
> > Hi Andre!
> >
> > Dne nedelja, 5. oktober 2025 ob 02:40:21 Srednjeevropski poletni čas je Andre Przywara napisal(a):
> > > On Mon, 11 Aug 2025 09:35:19 +0200
> > > Rudi Horn <dyn-git@rudi-horn.de> wrote:
> > >
> > > Hi Rudi,
> > >
> > > thanks for sending a patch to address this long-standing issue!
> > >
> > > But ... ;-)
> > >
> > > > I encountered a bug where u-boot detects that my OrangePI zero 3 (with
> > > > 1.5GB) has 2GB and crashes.
> > >
> > > As Jernej already said, this is a known limitation: we simply don't
> > > support not-power-of-2 DRAM sizes at the moment.
> > >
> > > > The orangepi u-boot source code contains an additional
> > > > modification in the `mctl_calc_size` which removes a quarter of the
> > > > memory the
> > > > calculated last address cannot be written to:
> > > >
> > > > https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_sun50i_h616.c#L1365-L1368
> > > >
> > > > I'm not entirely sure if there is some specific logic that applies to this
> > > > modifier, but it does fix the issue on my system.
> > >
> > > So can someone shed some light on how this is supposed to work? If I
> > > understand the code correctly, it checks for *aliasing* between the
> > > first and the last word of DRAM, which doesn't make much sense to me: I
> > > would expect a simple write/verify to see if the last quarter of DRAM
> > > is for real, or to check for a known aliasing pattern with this "odd"
> > > setup (as in: last quarter is aliased to first or third quarter or
> > > something), but checking those two words for aliasing seems wrong.
> >
> > Hm... I've never tested this patch on HW, so you might have a point. Still,
> > I think testing for aliasing makes sense. Just writing and reading might
> > not be enough due to possible caching (not necessarily in CPU).
>
> I see where the confusion comes from. Rudi tried to replicate OrangePi code
> but inadvertently used function for aliasing check instead of write/verify
> as noticed by Andre.
Right, I found this as well shortly after hitting Send ...
> While probably using OrangePi approach [1] would work fine, I learned to
Well, their algorithm is rubbish. For a start, they don't save the
original value, so may corrupt some other location. But more
importantly they don't try to write something surely different.
We could read the value at said location, invert it, write it, and
then read it back, to verify we read the inverted value. Then we restore
the original value. That should be pretty safe and reliable, I think,
also easy to do, given that writing to non-existing DRAM cells doesn't
hang the bus or DRAM controller.
> distrust simple write/verify checks, especially when size is only 1 word.
> I would be still more confortable to use current aliasing check, which uses
> 16 words check.
Well, when we have something, we could of course do multiple rounds of
it, if that proves more reliable.
Cheers,
Andre
> Best regards,
> Jernej
>
> [1] https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_helpers.c#L48-L63
>
> >
> > I should have some board with non-power-of-2 RAM size somewhere. I'll try
> > to find it and test this.
> >
> > >
> > > And indeed the code also fires on a board with 512MB and 4GB, capping
> > > the memory there as well (resulting in 384 MB and 3GB, respectively).
> > > This is somewhat expected, as we never would expect aliasing between
> > > those two particular words, I'd say.
> > >
> > > So since I don't have a board with an "uneven" DRAM size, can you
> > > please test some ideas to detect this RAM setup?
> > > - Read the content of the first word to not exist (@1.5GB), then write
> > > something else there, and see if you can read this back? Don't forget
> > > a write barrier (dsb();) when doing so.
> > > - Write some test pattern to some known good DRAM locations, like the
> > > beginning of DRAM, @512MB, @1GB, and see if any of those values pop
> > > up @1.5GB, to see if there is an aliasing pattern?
> > > - Can you post the exact label on that DRAM chip, so that we can see if
> > > we find a datasheet? I'd be curious about the actual organisation of
> > > the DRAM array.
> > >
> > > Jernej, do you happen to know how those DRAM chips are organised? Do
> > > they just feature a non-power-of-2 number of rows or columns?
> >
> > I don't know details how such chips are organized internally. However,
> > number of rows and columns was never power-of-2.
> >
> > Btw, I think I saw 3 GB DRAM boards too somewhere, but not sure where.
> > Quick search confirms that 24 Gb DRAM chips also exists, so I would leave
> > this check as general 3/4 size fixup, not limited to any capacity.
> >
> > >
> > > Oh, and also this patch was heavily malformed - line breaks and spaces
> > > instead of tabs. Please try to fix this. Simplest is probably "git
> > > format-patch", then sending this via "git send-email". Your email
> > > server seems to be postfix, so you could just give the SMTP details and
> > > credentials to git.
> > >
> > > Cheers,
> > > Andre
> > >
> > >
> > > >
> > > > I propose the following patch, but am open to any further suggestions.
> > > >
> > > > Thanks,
> > > > Rudi Horn
> > > >
> > > > Note: Submitted in my personal capacity and is not affiliated with my
> > > > employer.
> > > >
> > > >
> > > > From 2199f3b28e5fc853ed1921586358c33f3f1502d3 Mon Sep 17 00:00:00 2001
> > > > From: Rudi Horn <dyn-git@rudi-horn.de>
> > > > Date: Mon, 11 Aug 2025 08:58:34 +0200
> > > > Subject: [PATCH] arch: arm: mach-sonxi: Fix detection of odd memory
> > > > configurations
> > > >
> > > > Fix detection of odd memory configurations. Previously 1.5GB devices were
> > > > incorrectly detected as 2GB devices, causing u-boot to crash.
> > > >
> > > > Signed-off-by: Rudi Horn <dyn-git@rudi-horn.de>
> > > > ---
> > > > arch/arm/include/asm/arch-sunxi/dram.h | 1 +
> > > > arch/arm/mach-sunxi/dram_dw_helpers.c | 10 +++++++++-
> > > > arch/arm/mach-sunxi/dram_helpers.c | 8 ++++++++
> > > > 3 files changed, 18 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..7580421ca77 100644
> > > > --- a/arch/arm/include/asm/arch-sunxi/dram.h
> > > > +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> > > > @@ -44,6 +44,7 @@
> > > > 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_upto(u32 offset);
> > > > bool mctl_mem_matches_base(u32 offset, ulong base);
> > > >
> > > > #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..5bcd2672465 100644
> > > > --- a/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > > +++ b/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > > @@ -146,5 +146,13 @@ unsigned long mctl_calc_size(const struct
> > > > dram_config *config)
> > > > u8 width = config->bus_full_width ? 4 : 2;
> > > >
> > > > /* 8 banks */
> > > > - return (1ULL << (config->cols + config->rows + 3)) * width *
> > > > config->ranks;
> > > > + unsigned long size = (1ULL << (config->cols + config->rows + 3))
> > > > * width * config->ranks;
> > > > +
> > > > + /* some memory configurations such as 1.5GB rely on this to
> > > > compute the correct size */
> > > > + if (!mctl_mem_matches_upto(size)) {
> > > > + size = (size * 3) / 4;
> > > > + debug("capping memory at 0x%lx\n", size);
> > > > + }
> > > > +
> > > > + return size;
> > > > }
> > > > diff --git a/arch/arm/mach-sunxi/dram_helpers.c
> > > > b/arch/arm/mach-sunxi/dram_helpers.c
> > > > index 83dbe4ca98f..68c75fa07a6 100644
> > > > --- a/arch/arm/mach-sunxi/dram_helpers.c
> > > > +++ b/arch/arm/mach-sunxi/dram_helpers.c
> > > > @@ -61,4 +61,12 @@ bool mctl_mem_matches(u32 offset)
> > > > {
> > > > return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
> > > > }
> > > > +
> > > > +/*
> > > > + * Test if memory at offset matches memory at end of DRAM
> > > > + */
> > > > +bool mctl_mem_matches_upto(u32 offset)
> > > > +{
> > > > + return mctl_mem_matches_base(offset - sizeof(u32),
> > > > CFG_SYS_SDRAM_BASE);
> > > > +}
> > > > #endif
> > > > --
> > > > 2.43.0
> > > >
> > >
> > >
> >
> >
> >
> >
> >
>
>
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Fix detection of odd memory configurations on sunxi
2025-10-05 16:16 ` Andre Przywara
@ 2025-10-06 23:09 ` Andre Przywara
0 siblings, 0 replies; 9+ messages in thread
From: Andre Przywara @ 2025-10-06 23:09 UTC (permalink / raw)
To: Jernej Škrabec; +Cc: Rudi Horn, u-boot, linux-sunxi
On Sun, 5 Oct 2025 17:16:35 +0100
Andre Przywara <andre.przywara@arm.com> wrote:
Hi,
> On Sun, 05 Oct 2025 08:10:27 +0200
> Jernej Škrabec <jernej.skrabec@gmail.com> wrote:
>
> Hi,
>
> > Dne nedelja, 5. oktober 2025 ob 02:40:21 Srednjeevropski poletni čas je Andre Przywara napisal(a):
> > > On Mon, 11 Aug 2025 09:35:19 +0200
> > > Rudi Horn <dyn-git@rudi-horn.de> wrote:
> > >
> > > Hi Rudi,
> > >
> > > thanks for sending a patch to address this long-standing issue!
> > >
> > > But ... ;-)
> > >
> > > > I encountered a bug where u-boot detects that my OrangePI zero 3 (with
> > > > 1.5GB) has 2GB and crashes.
> > >
> > > As Jernej already said, this is a known limitation: we simply don't
> > > support not-power-of-2 DRAM sizes at the moment.
> > >
> > > > The orangepi u-boot source code contains an additional
> > > > modification in the `mctl_calc_size` which removes a quarter of the
> > > > memory the
> > > > calculated last address cannot be written to:
> > > >
> > > > https://github.com/orangepi-xunlong/u-boot-orangepi/blob/v2024.01/arch/arm/mach-sunxi/dram_sun50i_h616.c#L1365-L1368
> > > >
> > > > I'm not entirely sure if there is some specific logic that applies to this
> > > > modifier, but it does fix the issue on my system.
> > >
> > > So can someone shed some light on how this is supposed to work? If I
> > > understand the code correctly, it checks for *aliasing* between the
> > > first and the last word of DRAM, which doesn't make much sense to me: I
> > > would expect a simple write/verify to see if the last quarter of DRAM
> > > is for real, or to check for a known aliasing pattern with this "odd"
> > > setup (as in: last quarter is aliased to first or third quarter or
> > > something), but checking those two words for aliasing seems wrong.
> >
> > Hm... I've never tested this patch on HW, so you might have a point. Still,
> > I think testing for aliasing makes sense. Just writing and reading might
> > not be enough due to possible caching (not necessarily in CPU).
>
> Sure, aliasing trumps verifying, but it might be easier to test the
> latter?
>
> > I should have some board with non-power-of-2 RAM size somewhere. I'll try
> > to find it and test this.
>
> I just realised that my Cubie A7A has 12GB(!) of DRAM, so I can actually do
> some experiments here, in U-Boot proper, after boot0 has initialised the DRAM:
> [5912]DRAM SIZE =12288 MBytes, para1 = a11a, para2 = 30001001, dram_tpr13 = 10065
So I did some experiments on my board:
I booted boot0 from SD card, to let it initialise all 12GB of DRAM,
then to go to FEL. After that I loaded U-Boot into DRAM and started it.
I hacked U-Boot to assume 16GB of DRAM, and mapped all memory above 4GB
as device (non-cacheable). The observations are:
- Memory beyond the 12GB real DRAM contains one of two distinct 32
byte long patterns, which alternate every 512MB:
35fffffc0: 66666666 66666666 66666666 66666666 ffffffffffffffff
35fffffd0: 66666666 66666666 66666666 66662626 ffffffffffff&&ff
35fffffe0: 66666666 66666666 66666666 66666666 ffffffffffffffff
35ffffff0: 66666666 66666666 66666666 66662626 ffffffffffff&&ff
360000000: 99999999 99999999 99999999 99999999 ................
360000010: 99999999 99999999 99999999 9b9b9999 ................
360000020: 99999999 99999999 99999999 99999999 ................
360000030: 99999999 99999999 99999999 9b9b9999 ................
- values written there are ignored, the content stays at this initial pattern
- with caches enabled, writes seem to stick, but that's in the cache only
- this pattern does not appear anywhere else in DRAM
So this means any aliasing test wouldn't work, but we can do an
accessibility test, I think the algorithm should be:
bool test_last_quarter(size_t size)
{
uintptr_t addr = CFG_SYS_SDRAM_BASE + size / 4 * 3;
uint32_t orig, val;
orig = readl(addr);
writel(~orig, addr);
val = readl(addr);
writel(orig, addr);
return ~orig == val;
}
This would be SPL code, so with the MMU and thus caches off, and since
all accesses go to the same memory address on the same core, we
shouldn't need extra barriers (I think even the _relaxed versions
should work).
Can someone test this on a board with an "odd" memory size? It worked
on a normal 4GB board (passing the test), and failed on my 12GB board,
albeit running only in U-Boot proper.
If this works, I will send a proper patch.
Cheers,
Andre
>
> > > And indeed the code also fires on a board with 512MB and 4GB, capping
> > > the memory there as well (resulting in 384 MB and 3GB, respectively).
> > > This is somewhat expected, as we never would expect aliasing between
> > > those two particular words, I'd say.
> > >
> > > So since I don't have a board with an "uneven" DRAM size, can you
> > > please test some ideas to detect this RAM setup?
> > > - Read the content of the first word to not exist (@1.5GB), then write
> > > something else there, and see if you can read this back? Don't forget
> > > a write barrier (dsb();) when doing so.
> > > - Write some test pattern to some known good DRAM locations, like the
> > > beginning of DRAM, @512MB, @1GB, and see if any of those values pop
> > > up @1.5GB, to see if there is an aliasing pattern?
> > > - Can you post the exact label on that DRAM chip, so that we can see if
> > > we find a datasheet? I'd be curious about the actual organisation of
> > > the DRAM array.
> > >
> > > Jernej, do you happen to know how those DRAM chips are organised? Do
> > > they just feature a non-power-of-2 number of rows or columns?
> >
> > I don't know details how such chips are organized internally. However,
> > number of rows and columns was never power-of-2.
>
> Ah right, brain fart on my end, those are of course the exponents in the
> calculation, so result in the eventual power-of-2 number. I then wonder
> where the factor of 3 comes in, are there 6 banks, or 3 ranks (doubt
> that)? I could not find a datasheet of one of those 12Gbit Samsung
> chips yet.
>
> > Btw, I think I saw 3 GB DRAM boards too somewhere, but not sure where.
> > Quick search confirms that 24 Gb DRAM chips also exists, so I would leave
> > this check as general 3/4 size fixup, not limited to any capacity.
>
> Oh, definitely, the only constant here would be the 3/4th. So the plan
> would be to detect some oddity (either through aliasing or because of
> missing DRAM cells at the end), then assume it's 3/4 of the detected
> capacity.
>
> Cheers,
> Andre
>
> >
> > >
> > > Oh, and also this patch was heavily malformed - line breaks and spaces
> > > instead of tabs. Please try to fix this. Simplest is probably "git
> > > format-patch", then sending this via "git send-email". Your email
> > > server seems to be postfix, so you could just give the SMTP details and
> > > credentials to git.
> > >
> > > Cheers,
> > > Andre
> > >
> > >
> > > >
> > > > I propose the following patch, but am open to any further suggestions.
> > > >
> > > > Thanks,
> > > > Rudi Horn
> > > >
> > > > Note: Submitted in my personal capacity and is not affiliated with my
> > > > employer.
> > > >
> > > >
> > > > From 2199f3b28e5fc853ed1921586358c33f3f1502d3 Mon Sep 17 00:00:00 2001
> > > > From: Rudi Horn <dyn-git@rudi-horn.de>
> > > > Date: Mon, 11 Aug 2025 08:58:34 +0200
> > > > Subject: [PATCH] arch: arm: mach-sonxi: Fix detection of odd memory
> > > > configurations
> > > >
> > > > Fix detection of odd memory configurations. Previously 1.5GB devices were
> > > > incorrectly detected as 2GB devices, causing u-boot to crash.
> > > >
> > > > Signed-off-by: Rudi Horn <dyn-git@rudi-horn.de>
> > > > ---
> > > > arch/arm/include/asm/arch-sunxi/dram.h | 1 +
> > > > arch/arm/mach-sunxi/dram_dw_helpers.c | 10 +++++++++-
> > > > arch/arm/mach-sunxi/dram_helpers.c | 8 ++++++++
> > > > 3 files changed, 18 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..7580421ca77 100644
> > > > --- a/arch/arm/include/asm/arch-sunxi/dram.h
> > > > +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> > > > @@ -44,6 +44,7 @@
> > > > 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_upto(u32 offset);
> > > > bool mctl_mem_matches_base(u32 offset, ulong base);
> > > >
> > > > #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..5bcd2672465 100644
> > > > --- a/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > > +++ b/arch/arm/mach-sunxi/dram_dw_helpers.c
> > > > @@ -146,5 +146,13 @@ unsigned long mctl_calc_size(const struct
> > > > dram_config *config)
> > > > u8 width = config->bus_full_width ? 4 : 2;
> > > >
> > > > /* 8 banks */
> > > > - return (1ULL << (config->cols + config->rows + 3)) * width *
> > > > config->ranks;
> > > > + unsigned long size = (1ULL << (config->cols + config->rows + 3))
> > > > * width * config->ranks;
> > > > +
> > > > + /* some memory configurations such as 1.5GB rely on this to
> > > > compute the correct size */
> > > > + if (!mctl_mem_matches_upto(size)) {
> > > > + size = (size * 3) / 4;
> > > > + debug("capping memory at 0x%lx\n", size);
> > > > + }
> > > > +
> > > > + return size;
> > > > }
> > > > diff --git a/arch/arm/mach-sunxi/dram_helpers.c
> > > > b/arch/arm/mach-sunxi/dram_helpers.c
> > > > index 83dbe4ca98f..68c75fa07a6 100644
> > > > --- a/arch/arm/mach-sunxi/dram_helpers.c
> > > > +++ b/arch/arm/mach-sunxi/dram_helpers.c
> > > > @@ -61,4 +61,12 @@ bool mctl_mem_matches(u32 offset)
> > > > {
> > > > return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
> > > > }
> > > > +
> > > > +/*
> > > > + * Test if memory at offset matches memory at end of DRAM
> > > > + */
> > > > +bool mctl_mem_matches_upto(u32 offset)
> > > > +{
> > > > + return mctl_mem_matches_base(offset - sizeof(u32),
> > > > CFG_SYS_SDRAM_BASE);
> > > > +}
> > > > #endif
> > > > --
> > > > 2.43.0
> > > >
> > >
> > >
> >
> >
> >
> >
> >
>
>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-10-06 23:09 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <56f44755-fca8-4364-905e-685e79fd1aea@rudi-horn.de>
2025-08-11 15:25 ` [PATCH] Fix detection of odd memory configurations on sunxi Jernej Škrabec
2025-08-16 12:18 ` Rudi Horn
2025-09-08 14:11 ` Jernej Škrabec
2025-10-05 0:40 ` Andre Przywara
2025-10-05 6:10 ` Jernej Škrabec
2025-10-05 6:38 ` Jernej Škrabec
2025-10-05 16:30 ` Andre Przywara
2025-10-05 16:16 ` Andre Przywara
2025-10-06 23:09 ` Andre Przywara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox