diff mbox series

[U-Boot,1/3] ARM: uniphier: do not use RAM that exceeds 32 bit address range

Message ID 1515247166-20516-2-git-send-email-yamada.masahiro@socionext.com
State Accepted
Commit be893a5c09dca715df2dadafcae1365ed3826a39
Delegated to: Masahiro Yamada
Headers show
Series ARM: uniphier: updates for v2017.03 MW | expand

Commit Message

Masahiro Yamada Jan. 6, 2018, 1:59 p.m. UTC
LD20 / PXs3 boards are equipped with a large amount of memory beyond
the 32 bit address range.  U-Boot relocates itself to the end of the
available RAM.

This is a problem for DMA engines that only support 32 bit physical
address, like the SDMA of SDHCI controllers.

In fact, U-Boot does not need to run at the very end of RAM.  It is
rather troublesome for drivers with DMA engines because U-Boot does
not have API like dma_set_mask(), so DMA silently fails, making the
driver debugging difficult.

Hide the memory region that exceeds the 32 bit address range.  It can
be done by simply carving out gd->ram_size.  It would also possible to
override get_effective_memsize() or to define CONFIG_MAX_MEM_MAPPED,
but dram_init() is a good enough place to do this job.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

 arch/arm/mach-uniphier/dram_init.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
diff mbox series

Patch

diff --git a/arch/arm/mach-uniphier/dram_init.c b/arch/arm/mach-uniphier/dram_init.c
index e9672d2..cb35dab 100644
--- a/arch/arm/mach-uniphier/dram_init.c
+++ b/arch/arm/mach-uniphier/dram_init.c
@@ -205,6 +205,7 @@  int dram_init(void)
 		return ret;
 
 	for (i = 0; i < ARRAY_SIZE(dram_map); i++) {
+		unsigned long max_size;
 
 		if (!dram_map[i].size)
 			break;
@@ -218,6 +219,22 @@  int dram_init(void)
 							dram_map[i].base)
 			break;
 
+		/*
+		 * Do not use memory that exceeds 32bit address range.  U-Boot
+		 * relocates itself to the end of the effectively available RAM.
+		 * This could be a problem for DMA engines that do not support
+		 * 64bit address (SDMA of SDHCI, UniPhier AV-ether, etc.)
+		 */
+		if (dram_map[i].base >= 1ULL << 32)
+			break;
+
+		max_size = (1ULL << 32) - dram_map[i].base;
+
+		if (dram_map[i].size > max_size) {
+			gd->ram_size += max_size;
+			break;
+		}
+
 		gd->ram_size += dram_map[i].size;
 	}