Merge branch '2022-09-23-4gb-ddr-in-32bit-ppc' into next

To quote the author, for the first 9 patches:
This patch series fixes U-Boot code to correctly handle RAM size larger
than 2 GB and then fixes fsl ddr driver to do not crash U-Boot when 4 GB
DDR module is detected when U-Boot operates in 32-bit mode (as opposite
of the 36-bit mode).

With this patch series it is possible to boot 32-bit U-Boot with 4 GB
SODIMM DDR3 module without crashes. U-Boot will still use just
CONFIG_MAX_MEM_MAPPED amount of RAM, but it is better than crashing due
to the truncating of 4GB value to 32-bit number (which is zero).

I tested this patch series on powerpc P2020 based board but only with
U-Boot v2022.04 because U-Boot master branch is still broken on P2020.

And then the final two patches here are (in my mind at least) related
clean-ups.
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index d115b25..47c0a4f 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -327,7 +327,7 @@
 	}
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	ulong top_addr;
 
diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c
index 238edbe..63f6af5 100644
--- a/arch/arm/mach-mvebu/arm64-common.c
+++ b/arch/arm/mach-mvebu/arm64-common.c
@@ -30,7 +30,7 @@
  */
 #define USABLE_RAM_SIZE		0x80000000ULL
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	unsigned long top = CONFIG_SYS_SDRAM_BASE + min(gd->ram_size, USABLE_RAM_SIZE);
 
diff --git a/arch/arm/mach-rockchip/sdram.c b/arch/arm/mach-rockchip/sdram.c
index 705ec7b..12f1d7e 100644
--- a/arch/arm/mach-rockchip/sdram.c
+++ b/arch/arm/mach-rockchip/sdram.c
@@ -205,7 +205,7 @@
 	return 0;
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	unsigned long top = CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE;
 
diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c
index 920b99b..9346fa8 100644
--- a/arch/arm/mach-stm32mp/dram_init.c
+++ b/arch/arm/mach-stm32mp/dram_init.c
@@ -40,7 +40,7 @@
 	return 0;
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	phys_size_t size;
 	phys_addr_t reg;
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 8f7c894..62bb40b 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -65,7 +65,7 @@
 };
 struct mm_region *mem_map = sunxi_mem_map;
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	/* Some devices (like the EMAC) have a 32-bit DMA limit. */
 	if (gd->ram_top > (1ULL << 32))
diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c
index 8950e67..1994db0 100644
--- a/arch/arm/mach-tegra/board2.c
+++ b/arch/arm/mach-tegra/board2.c
@@ -401,7 +401,7 @@
  * This function is called before dram_init_banksize(), so we can't simply
  * return gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size.
  */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	ulong ram_top;
 
diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c
index fefba12..a57ec78 100644
--- a/arch/mips/mach-jz47xx/jz4780/jz4780.c
+++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c
@@ -76,7 +76,7 @@
 }
 #endif /* CONFIG_SPL_BUILD */
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024);
 }
diff --git a/arch/mips/mach-octeon/dram.c b/arch/mips/mach-octeon/dram.c
index 4679260..9c5789b 100644
--- a/arch/mips/mach-octeon/dram.c
+++ b/arch/mips/mach-octeon/dram.c
@@ -77,7 +77,7 @@
 	return UBOOT_RAM_SIZE_MAX;
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	if (IS_ENABLED(CONFIG_RAM_OCTEON)) {
 		/* Map a maximum of 256MiB - return not size but address */
diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c
index ab61649..e39fe14 100644
--- a/arch/powerpc/cpu/mpc85xx/tlb.c
+++ b/arch/powerpc/cpu/mpc85xx/tlb.c
@@ -312,7 +312,10 @@
 	if (size || memsize > CONFIG_MAX_MEM_MAPPED) {
 		print_size(memsize > CONFIG_MAX_MEM_MAPPED ?
 			   memsize - CONFIG_MAX_MEM_MAPPED + size : size,
-			   " left unmapped\n");
+			   " of DDR memory left unmapped in U-Boot\n");
+#ifndef CONFIG_SPL_BUILD
+		puts("       ");
+#endif
 	}
 
 	return memsize_in_meg;
diff --git a/arch/riscv/cpu/fu540/dram.c b/arch/riscv/cpu/fu540/dram.c
index 1fdc783..44e11bd 100644
--- a/arch/riscv/cpu/fu540/dram.c
+++ b/arch/riscv/cpu/fu540/dram.c
@@ -21,7 +21,7 @@
 	return fdtdec_setup_memory_banksize();
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	/*
 	 * Ensure that we run from first 4GB so that all
diff --git a/arch/riscv/cpu/fu740/dram.c b/arch/riscv/cpu/fu740/dram.c
index 1dc77ef..d6d4a41 100644
--- a/arch/riscv/cpu/fu740/dram.c
+++ b/arch/riscv/cpu/fu740/dram.c
@@ -20,7 +20,7 @@
 	return fdtdec_setup_memory_banksize();
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 #ifdef CONFIG_64BIT
 	/*
diff --git a/arch/riscv/cpu/generic/dram.c b/arch/riscv/cpu/generic/dram.c
index 1fdc783..44e11bd 100644
--- a/arch/riscv/cpu/generic/dram.c
+++ b/arch/riscv/cpu/generic/dram.c
@@ -21,7 +21,7 @@
 	return fdtdec_setup_memory_banksize();
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	/*
 	 * Ensure that we run from first 4GB so that all
diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c
index c104a84..1295121 100644
--- a/arch/x86/cpu/broadwell/sdram.c
+++ b/arch/x86/cpu/broadwell/sdram.c
@@ -25,7 +25,7 @@
 #include <asm/arch/pei_data.h>
 #include <asm/arch/pm.h>
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	return mrc_common_board_get_usable_ram_top(total_size);
 }
diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c
index 4a256ba..f4ee4cd 100644
--- a/arch/x86/cpu/coreboot/sdram.c
+++ b/arch/x86/cpu/coreboot/sdram.c
@@ -27,7 +27,7 @@
  * address, and how far U-Boot is moved by relocation are set in the global
  * data structure.
  */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	uintptr_t dest_addr = 0;
 	int i;
diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c
index b777856..1c28a43 100644
--- a/arch/x86/cpu/efi/payload.c
+++ b/arch/x86/cpu/efi/payload.c
@@ -27,7 +27,7 @@
  * the relocation address, and how far U-Boot is moved by relocation are
  * set in the global data structure.
  */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	struct efi_mem_desc *desc, *end;
 	struct efi_entry_memmap *map;
diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c
index af65982..f3086db 100644
--- a/arch/x86/cpu/efi/sdram.c
+++ b/arch/x86/cpu/efi/sdram.c
@@ -11,7 +11,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	return (ulong)efi_get_ram_base() + gd->ram_size;
 }
diff --git a/arch/x86/cpu/intel_common/mrc.c b/arch/x86/cpu/intel_common/mrc.c
index a97b0b7..a4918fb 100644
--- a/arch/x86/cpu/intel_common/mrc.c
+++ b/arch/x86/cpu/intel_common/mrc.c
@@ -25,7 +25,7 @@
 	"active"
 };
 
-ulong mrc_common_board_get_usable_ram_top(ulong total_size)
+phys_size_t mrc_common_board_get_usable_ram_top(phys_size_t total_size)
 {
 	struct memory_info *info = &gd->arch.meminfo;
 	uintptr_t dest_addr = 0;
@@ -50,7 +50,7 @@
 
 	dest_addr = largest->start + largest->size;
 
-	return (ulong)dest_addr;
+	return (phys_size_t)dest_addr;
 }
 
 void mrc_common_dram_init_banksize(void)
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index dd6b875..1a0ec43 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -44,7 +44,7 @@
 #define CMOS_OFFSET_MRC_SEED_S3		156
 #define CMOS_OFFSET_MRC_SEED_CHK	160
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	return mrc_common_board_get_usable_ram_top(total_size);
 }
diff --git a/arch/x86/cpu/qemu/dram.c b/arch/x86/cpu/qemu/dram.c
index c174550..595c397 100644
--- a/arch/x86/cpu/qemu/dram.c
+++ b/arch/x86/cpu/qemu/dram.c
@@ -71,7 +71,7 @@
  * the relocation address, and how far U-Boot is moved by relocation are
  * set in the global data structure.
  */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	return qemu_get_low_memory_size();
 }
diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c
index 2287dce..8b1ee2d 100644
--- a/arch/x86/cpu/quark/dram.c
+++ b/arch/x86/cpu/quark/dram.c
@@ -184,7 +184,7 @@
  * the relocation address, and how far U-Boot is moved by relocation are
  * set in the global data structure.
  */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	return gd->ram_size;
 }
diff --git a/arch/x86/cpu/slimbootloader/sdram.c b/arch/x86/cpu/slimbootloader/sdram.c
index c6f10e2..d748d5c 100644
--- a/arch/x86/cpu/slimbootloader/sdram.c
+++ b/arch/x86/cpu/slimbootloader/sdram.c
@@ -48,7 +48,7 @@
  * @total_size: The memory size that u-boot occupies
  * Return:    : The top available memory address lower than 4GB
  */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	struct sbl_memory_map_info *data;
 	int i;
diff --git a/arch/x86/cpu/tangier/sdram.c b/arch/x86/cpu/tangier/sdram.c
index afb0847..8a4b1c5 100644
--- a/arch/x86/cpu/tangier/sdram.c
+++ b/arch/x86/cpu/tangier/sdram.c
@@ -204,7 +204,7 @@
  * address, and how far U-Boot is moved by relocation are set in the global
  * data structure.
  */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	struct sfi_table_simple *sb;
 	struct sfi_mem_entry *mentry;
diff --git a/arch/x86/include/asm/mrc_common.h b/arch/x86/include/asm/mrc_common.h
index 3d7f00c..a7f260a 100644
--- a/arch/x86/include/asm/mrc_common.h
+++ b/arch/x86/include/asm/mrc_common.h
@@ -47,7 +47,7 @@
  * the relocation address, and how far U-Boot is moved by relocation are
  * set in the global data structure.
  */
-ulong mrc_common_board_get_usable_ram_top(ulong total_size);
+phys_size_t mrc_common_board_get_usable_ram_top(phys_size_t total_size);
 
 void mrc_common_dram_init_banksize(void);
 
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index a1655e1..4cf41e9 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -77,7 +77,7 @@
 void x86_enable_caches(void);
 void x86_disable_caches(void);
 int x86_init_cache(void);
-ulong board_get_usable_ram_top(ulong total_size);
+phys_size_t board_get_usable_ram_top(phys_size_t total_size);
 int default_print_cpuinfo(void);
 
 /* Set up a UART which can be used with printch(), printhex8(), etc. */
diff --git a/arch/x86/lib/fsp1/fsp_dram.c b/arch/x86/lib/fsp1/fsp_dram.c
index cfd9b9f..5825221 100644
--- a/arch/x86/lib/fsp1/fsp_dram.c
+++ b/arch/x86/lib/fsp1/fsp_dram.c
@@ -34,7 +34,7 @@
  * the relocation address, and how far U-Boot is moved by relocation are
  * set in the global data structure.
  */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	return fsp_get_usable_lowmem_top(gd->arch.hob_list);
 }
diff --git a/arch/x86/lib/fsp2/fsp_dram.c b/arch/x86/lib/fsp2/fsp_dram.c
index 42d3892..f9ea1ab 100644
--- a/arch/x86/lib/fsp2/fsp_dram.c
+++ b/arch/x86/lib/fsp2/fsp_dram.c
@@ -77,7 +77,7 @@
 	return 0;
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	if (!ll_boot_init())
 		return gd->ram_size;
diff --git a/board/broadcom/bcmns3/ns3.c b/board/broadcom/bcmns3/ns3.c
index 88036c1..26652e8 100644
--- a/board/broadcom/bcmns3/ns3.c
+++ b/board/broadcom/bcmns3/ns3.c
@@ -183,7 +183,7 @@
 }
 
 /* Limit RAM used by U-Boot to the DDR first bank End region */
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	return BCM_NS3_MEM_END;
 }
diff --git a/board/imgtec/boston/ddr.c b/board/imgtec/boston/ddr.c
index 182f79b..5b245cb 100644
--- a/board/imgtec/boston/ddr.c
+++ b/board/imgtec/boston/ddr.c
@@ -23,7 +23,7 @@
 	return 0;
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	DECLARE_GLOBAL_DATA_PTR;
 
diff --git a/board/menlo/m53menlo/m53menlo.c b/board/menlo/m53menlo/m53menlo.c
index 61ab384..4afc5aa 100644
--- a/board/menlo/m53menlo/m53menlo.c
+++ b/board/menlo/m53menlo/m53menlo.c
@@ -42,7 +42,7 @@
 
 static u32 mx53_dram_size[2];
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	/*
 	 * WARNING: We must override get_effective_memsize() function here
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 17b8108..00afb35 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -335,7 +335,7 @@
 /*
  * Prevent relocation from stomping on a firmware provided FDT blob.
  */
-unsigned long board_get_usable_ram_top(unsigned long total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	if ((gd->ram_top - fw_dtb_pointer) > SZ_64M)
 		return gd->ram_top;
diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c
index 8a0a506..34ec391 100644
--- a/board/ti/am65x/evm.c
+++ b/board/ti/am65x/evm.c
@@ -61,7 +61,7 @@
 	return 0;
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 #ifdef CONFIG_PHYS_64BIT
 	/* Limit RAM used by U-Boot to the DDR low region */
diff --git a/board/ti/j721e/evm.c b/board/ti/j721e/evm.c
index 5d09004..d6e431e 100644
--- a/board/ti/j721e/evm.c
+++ b/board/ti/j721e/evm.c
@@ -57,7 +57,7 @@
 	return 0;
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 #ifdef CONFIG_PHYS_64BIT
 	/* Limit RAM used by U-Boot to the DDR low region */
diff --git a/board/ti/j721s2/evm.c b/board/ti/j721s2/evm.c
index 3c75ecf..e09adc8 100644
--- a/board/ti/j721s2/evm.c
+++ b/board/ti/j721s2/evm.c
@@ -46,7 +46,7 @@
 	return 0;
 }
 
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 #ifdef CONFIG_PHYS_64BIT
 	/* Limit RAM used by U-Boot to the DDR low region */
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index e1f7104..391ce4d 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -631,7 +631,7 @@
 #endif
 
 #if defined(CONFIG_LMB)
-ulong board_get_usable_ram_top(ulong total_size)
+phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 	phys_size_t size;
 	phys_addr_t reg;
diff --git a/common/board_f.c b/common/board_f.c
index f92d7b9..3df4efe 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -57,6 +57,7 @@
 #include <asm/sections.h>
 #include <dm/root.h>
 #include <linux/errno.h>
+#include <linux/log2.h>
 
 /*
  * Pointer to initial global data area
@@ -216,6 +217,36 @@
 	return 0;
 }
 
+/*
+ * From input size calculate its nearest rounded unit scale (multiply of 2^10)
+ * and value in calculated unit scale multiplied by 10 (as fractional fixed
+ * point number with one decimal digit), which is human natural format,
+ * same what uses print_size() function for displaying. Mathematically it is:
+ * round_nearest(val * 2^scale) = size * 10; where: 10 <= val < 10240.
+ *
+ * For example for size=87654321 we calculate scale=20 and val=836 which means
+ * that input has natural human format 83.6 M (mega = 2^20).
+ */
+#define compute_size_scale_val(size, scale, val) do { \
+	scale = ilog2(size) / 10 * 10; \
+	val = (10 * size + ((1ULL << scale) >> 1)) >> scale; \
+	if (val == 10240) { val = 10; scale += 10; } \
+} while (0)
+
+/*
+ * Check if the sizes in their natural units written in decimal format with
+ * one fraction number are same.
+ */
+static int sizes_near(unsigned long long size1, unsigned long long size2)
+{
+	unsigned int size1_scale, size1_val, size2_scale, size2_val;
+
+	compute_size_scale_val(size1, size1_scale, size1_val);
+	compute_size_scale_val(size2, size2_scale, size2_val);
+
+	return size1_scale == size2_scale && size1_val == size2_val;
+}
+
 static int show_dram_config(void)
 {
 	unsigned long long size;
@@ -232,7 +263,11 @@
 	}
 	debug("\nDRAM:  ");
 
-	print_size(size, "");
+	print_size(gd->ram_size, "");
+	if (!sizes_near(gd->ram_size, size)) {
+		printf(" (effective ");
+		print_size(size, ")");
+	}
 	board_add_ram_info(0);
 	putc('\n');
 
@@ -305,7 +340,7 @@
 }
 
 /* Get the top of usable RAM */
-__weak ulong board_get_usable_ram_top(ulong total_size)
+__weak phys_size_t board_get_usable_ram_top(phys_size_t total_size)
 {
 #if defined(CONFIG_SYS_SDRAM_BASE) && CONFIG_SYS_SDRAM_BASE > 0
 	/*
@@ -328,7 +363,7 @@
 	/*
 	 * Ram is setup, size stored in gd !!
 	 */
-	debug("Ram size: %08lX\n", (ulong)gd->ram_size);
+	debug("Ram size: %08llX\n", (unsigned long long)gd->ram_size);
 #if CONFIG_VAL(SYS_MEM_TOP_HIDE)
 	/*
 	 * Subtract specified amount of memory to hide so that it won't
@@ -348,7 +383,7 @@
 	gd->ram_top = gd->ram_base + get_effective_memsize();
 	gd->ram_top = board_get_usable_ram_top(gd->mon_len);
 	gd->relocaddr = gd->ram_top;
-	debug("Ram top: %08lX\n", (ulong)gd->ram_top);
+	debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top);
 #if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
 	/*
 	 * We need to make sure the location we intend to put secondary core
diff --git a/common/memsize.c b/common/memsize.c
index d5d13d5..3c80ad2 100644
--- a/common/memsize.c
+++ b/common/memsize.c
@@ -94,11 +94,23 @@
 
 phys_size_t __weak get_effective_memsize(void)
 {
-#ifndef CONFIG_VERY_BIG_RAM
-	return gd->ram_size;
+	phys_size_t ram_size = gd->ram_size;
+
+	/*
+	 * Check for overflow and limit ram size to some representable value.
+	 * It is required that ram_base + ram_size must be representable by
+	 * phys_size_t type and must be aligned by direct access, therefore
+	 * calculate it from last 4kB sector which should work as alignment
+	 * on any platform.
+	 */
+	if (gd->ram_base + ram_size < gd->ram_base)
+		ram_size = ((phys_size_t)~0xfffULL) - gd->ram_base;
+
+#ifndef CONFIG_MAX_MEM_MAPPED
+	return ram_size;
 #else
 	/* limit stack to what we can reasonable map */
-	return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
-		CONFIG_MAX_MEM_MAPPED : gd->ram_size);
+	return ((ram_size > CONFIG_MAX_MEM_MAPPED) ?
+		CONFIG_MAX_MEM_MAPPED : ram_size);
 #endif
 }
diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c
index d738ae3..5e4ad56 100644
--- a/drivers/ddr/fsl/lc_common_dimm_params.c
+++ b/drivers/ddr/fsl/lc_common_dimm_params.c
@@ -422,6 +422,9 @@
 					dimm_params[i].mpart);
 #endif
 			}
+#ifndef CONFIG_SPL_BUILD
+			puts("       ");
+#endif
 		}
 	}
 
diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c
index 1903562..ed3313a 100644
--- a/drivers/ddr/fsl/main.c
+++ b/drivers/ddr/fsl/main.c
@@ -857,17 +857,32 @@
 	debug("total_memory by %s = %llu\n", __func__, total_memory);
 
 #if !defined(CONFIG_PHYS_64BIT)
-	/* Check for 4G or more.  Bad. */
-	if ((first_ctrl == 0) && (total_memory >= (1ull << 32))) {
+	/*
+	 * Show warning about big DDR moodules. But avoid warning for 4 GB DDR
+	 * modules when U-Boot supports RAM of maximal size 4 GB - 1 byte.
+	 */
+	if ((first_ctrl == 0) && (total_memory - 1 > (phys_size_t)~0ULL)) {
 		puts("Detected ");
 		print_size(total_memory, " of memory\n");
-		printf("       This U-Boot only supports < 4G of DDR\n");
-		printf("       You could rebuild it with CONFIG_PHYS_64BIT\n");
-		printf("       "); /* re-align to match init_dram print */
-		total_memory = CONFIG_MAX_MEM_MAPPED;
+#ifndef CONFIG_SPL_BUILD
+		puts("       "); /* re-align to match init_dram print */
+#endif
+		puts("This U-Boot only supports <= ");
+		print_size((unsigned long long)((phys_size_t)~0ULL)+1, " of DDR\n");
+#ifndef CONFIG_SPL_BUILD
+		puts("       "); /* re-align to match init_dram print */
+#endif
+		puts("You could rebuild it with CONFIG_PHYS_64BIT\n");
+#ifndef CONFIG_SPL_BUILD
+		puts("       "); /* re-align to match init_dram print */
+#endif
 	}
 #endif
 
+	/* Ensure that total_memory does not overflow on return */
+	if (total_memory > (phys_size_t)~0ULL)
+		total_memory = (phys_size_t)~0ULL;
+
 	return total_memory;
 }
 
@@ -941,5 +956,9 @@
 	/* Compute it once normally. */
 	total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1);
 
+	/* Ensure that total_memory does not overflow on return */
+	if (total_memory > (phys_size_t)~0ULL)
+		total_memory = (phys_size_t)~0ULL;
+
 	return total_memory;
 }
diff --git a/include/init.h b/include/init.h
index 02bb4ce..50a8302 100644
--- a/include/init.h
+++ b/include/init.h
@@ -291,7 +291,7 @@
  *
  * @param total_size	Size of U-Boot (unused?)
  */
-ulong board_get_usable_ram_top(ulong total_size);
+phys_size_t board_get_usable_ram_top(phys_size_t total_size);
 
 int board_early_init_f(void);
 
diff --git a/lib/display_options.c b/lib/display_options.c
index 7feb446..80def52 100644
--- a/lib/display_options.c
+++ b/lib/display_options.c
@@ -127,6 +127,12 @@
 		if (m >= 10) {
 			m -= 10;
 			n += 1;
+
+			if (n == 1024 && i > 0) {
+				n = 1;
+				m = 0;
+				c = names[i - 1];
+			}
 		}
 	}
 
diff --git a/test/lib/test_print.c b/test/lib/test_print.c
index a60a5a5..79b67c7 100644
--- a/test/lib/test_print.c
+++ b/test/lib/test_print.c
@@ -68,6 +68,9 @@
 	ut_assertok(test_print_size(uts, 7654321, "7.3 MiB;"));
 	ut_assertok(test_print_size(uts, 87654321, "83.6 MiB;"));
 	ut_assertok(test_print_size(uts, 987654321, "941.9 MiB;"));
+	ut_assertok(test_print_size(uts, 1073689395, "1023.9 MiB;"));
+	ut_assertok(test_print_size(uts, 1073689396, "1 GiB;"));
+	ut_assertok(test_print_size(uts, 1073741824, "1 GiB;"));
 	ut_assertok(test_print_size(uts, 1987654321, "1.9 GiB;"));
 	ut_assertok(test_print_size(uts, 54321987654321, "49.4 TiB;"));
 	return 0;