From f9aa935084d24fbbe5e7b2c62948a8f08b228f18 Mon Sep 17 00:00:00 2001 From: voapilro Date: Mon, 6 May 2024 11:36:47 +0200 Subject: [PATCH 1/3] Fix memory size detection for 1.5GB Orange Pi Zero 3 board --- arch/arm/include/asm/arch-sunxi/dram.h | 1 + arch/arm/mach-sunxi/dram_helpers.c | 20 ++++++++++++++++++++ arch/arm/mach-sunxi/dram_sun50i_h616.c | 9 ++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 682daae6b1a..a1379631d62 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -40,5 +40,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_top(ulong offset); #endif /* _SUNXI_DRAM_H */ diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c index cdf2750f1c5..36fabb3bcd5 100644 --- a/arch/arm/mach-sunxi/dram_helpers.c +++ b/arch/arm/mach-sunxi/dram_helpers.c @@ -40,4 +40,24 @@ bool mctl_mem_matches(u32 offset) return readl(CFG_SYS_SDRAM_BASE) == readl((ulong)CFG_SYS_SDRAM_BASE + offset); } + +/* + * Test if memory at offset matches memory at top of DRAM + */ +bool mctl_mem_matches_top(ulong offset) +{ + static const unsigned value= 0xaa55aa55; + + /* Take last usable memory address */ + offset -= sizeof(unsigned); + dsb(); + /* Set zero at last usable memory address */ + writel(0, (ulong)CONFIG_SYS_SDRAM_BASE + offset); + dsb(); + /* Set other value at last usable memory address */ + writel(value, (ulong)CONFIG_SYS_SDRAM_BASE + offset); + dsb(); + /* Check if the same value is actually observed when reading back */ + return readl((ulong)CONFIG_SYS_SDRAM_BASE + offset) == value; +} #endif diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index c5c1331a4c3..5287ef79c43 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -1350,9 +1350,16 @@ static void mctl_auto_detect_dram_size(const struct dram_para *para, static unsigned long mctl_calc_size(const struct dram_config *config) { u8 width = config->bus_full_width ? 4 : 2; + unsigned long size; /* 8 banks */ - return (1ULL << (config->cols + config->rows + 3)) * width * config->ranks; + size = (1ULL << (config->cols + config->rows + 3)) * width * config->ranks; + + /* Fix size if last usable memory address is not valid */ + if (!mctl_mem_matches_top(size)) + size = (size * 3) / 4; + + return size; } static const struct dram_para para = { From 371388504b9b67459dfd13d2585090961ad51cc5 Mon Sep 17 00:00:00 2001 From: voapilro Date: Mon, 6 May 2024 15:13:29 +0200 Subject: [PATCH 2/3] Added some logs regarding memory size detection --- arch/arm/include/asm/arch-sunxi/dram.h | 1 + arch/arm/mach-sunxi/dram_helpers.c | 10 +++++++++- arch/arm/mach-sunxi/dram_sun50i_h616.c | 10 +++++++++- board/sunxi/board.c | 3 +-- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index a1379631d62..c7543d35698 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -41,5 +41,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_top(ulong offset); +ulong mctl_mem_address(ulong offset); #endif /* _SUNXI_DRAM_H */ diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c index 36fabb3bcd5..5a80159759c 100644 --- a/arch/arm/mach-sunxi/dram_helpers.c +++ b/arch/arm/mach-sunxi/dram_helpers.c @@ -49,7 +49,7 @@ bool mctl_mem_matches_top(ulong offset) static const unsigned value= 0xaa55aa55; /* Take last usable memory address */ - offset -= sizeof(unsigned); + offset -= sizeof(value); dsb(); /* Set zero at last usable memory address */ writel(0, (ulong)CONFIG_SYS_SDRAM_BASE + offset); @@ -60,4 +60,12 @@ bool mctl_mem_matches_top(ulong offset) /* Check if the same value is actually observed when reading back */ return readl((ulong)CONFIG_SYS_SDRAM_BASE + offset) == value; } + +/* + * Get memory address at offset of DRAM + */ +ulong mctl_mem_address(ulong offset) +{ + return (ulong)CONFIG_SYS_SDRAM_BASE + offset; +} #endif diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index 5287ef79c43..6a247ecaa05 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -1355,9 +1355,17 @@ static unsigned long mctl_calc_size(const struct dram_config *config) /* 8 banks */ size = (1ULL << (config->cols + config->rows + 3)) * width * config->ranks; + printf("DRAM base address is defined as 0x%lx\n", mctl_mem_address(0)); + printf("DRAM has %u b/raw, %u b/col, %u B/width, %u #rank and 8 #bank\n", + (unsigned)config->rows, (unsigned)config->cols, + (unsigned)width, (unsigned)config->ranks); + printf("DRAM top address must be less than 0x%lx\n", size); + /* Fix size if last usable memory address is not valid */ - if (!mctl_mem_matches_top(size)) + if (!mctl_mem_matches_top(size)) { size = (size * 3) / 4; + printf("DRAM top address must be less than 0x%lx\n", size); + } return size; } diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 8c12c8deade..62228936774 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -632,9 +632,8 @@ void sunxi_board_init(void) power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON)); #endif #endif /* CONFIG_AXPxxx_POWER */ - printf("DRAM:"); gd->ram_size = sunxi_dram_init(); - printf(" %d MiB\n", (int)(gd->ram_size >> 20)); + printf("DRAM: %d MiB\n", (int)(gd->ram_size >> 20)); if (!gd->ram_size) hang(); From 4b5089810e7adac0801185e82a39c5849bf2bb91 Mon Sep 17 00:00:00 2001 From: voapilro Date: Mon, 6 May 2024 19:36:47 +0200 Subject: [PATCH 3/3] Updated name from CONFIG_SYS_SDRAM_BASE to CFG_SYS_SDRAM_BASE --- arch/arm/mach-sunxi/dram_helpers.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c index 5a80159759c..0d7fbac61bf 100644 --- a/arch/arm/mach-sunxi/dram_helpers.c +++ b/arch/arm/mach-sunxi/dram_helpers.c @@ -52,13 +52,13 @@ bool mctl_mem_matches_top(ulong offset) offset -= sizeof(value); dsb(); /* Set zero at last usable memory address */ - writel(0, (ulong)CONFIG_SYS_SDRAM_BASE + offset); + writel(0, (ulong)CFG_SYS_SDRAM_BASE + offset); dsb(); /* Set other value at last usable memory address */ - writel(value, (ulong)CONFIG_SYS_SDRAM_BASE + offset); + writel(value, (ulong)CFG_SYS_SDRAM_BASE + offset); dsb(); /* Check if the same value is actually observed when reading back */ - return readl((ulong)CONFIG_SYS_SDRAM_BASE + offset) == value; + return readl((ulong)CFG_SYS_SDRAM_BASE + offset) == value; } /* @@ -66,6 +66,6 @@ bool mctl_mem_matches_top(ulong offset) */ ulong mctl_mem_address(ulong offset) { - return (ulong)CONFIG_SYS_SDRAM_BASE + offset; + return (ulong)CFG_SYS_SDRAM_BASE + offset; } #endif