@@ -944,7 +944,7 @@ int fdtdec_setup_mem_size_base(void);
* gd->ram_start by lowest available memory base
*
* Decode the /memory 'reg' property to determine the lowest start of the memory
- * bank bank and populate the global data with it.
+ * bank and populate the global data with it.
*
* This function should be called from a boards dram_init(). This helper
* function allows for boards to query the device tree for DRAM size and start
@@ -956,6 +956,23 @@ int fdtdec_setup_mem_size_base(void);
*/
int fdtdec_setup_mem_size_base_lowest(void);
+/**
+ * fdtdec_setup_mem_size_base_highest() - decode and setup gd->ram_size and
+ * gd->ram_start by highest available memory top
+ *
+ * Decode the /memory 'reg' property to determine the highest end of the memory
+ * bank and populate the global data with it.
+ *
+ * This function should be called from a boards dram_init(). This helper
+ * function allows for boards to query the device tree for DRAM size and start
+ * address instead of hard coding the value in the case where the memory size
+ * and start address cannot be detected automatically.
+ *
+ * @return 0 if OK, -EINVAL if the /memory node or reg property is missing or
+ * invalid
+ */
+int fdtdec_setup_mem_size_base_highest(void);
+
/**
* fdtdec_setup_memory_banksize() - decode and populate gd->bd->bi_dram
*
@@ -1123,7 +1123,7 @@ int fdtdec_setup_memory_banksize(void)
return 0;
}
-int fdtdec_setup_mem_size_base_lowest(void)
+static int fdtdec_setup_mem_size_base_superlative(bool lowest)
{
int bank, ret, reg = 0;
struct resource res;
@@ -1131,7 +1131,16 @@ int fdtdec_setup_mem_size_base_lowest(void)
phys_size_t size;
ofnode mem = ofnode_null();
- gd->ram_base = (unsigned long)~0;
+ /*
+ * Size must be 1 so we don't underflow when doing the subtraction below
+ * when lowest = false. Hopefully any real ram banks will have a greater
+ * size :)
+ */
+ gd->ram_size = 1;
+ if (lowest)
+ gd->ram_base = (unsigned long)~0;
+ else
+ gd->ram_base = 0;
mem = get_next_memory_node(mem);
if (!ofnode_valid(mem)) {
@@ -1158,17 +1167,32 @@ int fdtdec_setup_mem_size_base_lowest(void)
base = (unsigned long)res.start;
size = (phys_size_t)(res.end - res.start + 1);
- if (gd->ram_base > base && size) {
+ if (!size)
+ continue;
+
+ if ((lowest && gd->ram_base > base) ||
+ (!lowest && gd->ram_base + gd->ram_size - 1 < res.end)) {
gd->ram_base = base;
gd->ram_size = size;
- debug("%s: Initial DRAM base %lx size %lx\n",
- __func__, base, (unsigned long)size);
}
}
+ if (gd->ram_size)
+ debug("%s: Initial DRAM base %lx size %lx\n", __func__,
+ gd->ram_base, (unsigned long)gd->ram_size);
return 0;
}
+int fdtdec_setup_mem_size_base_lowest(void)
+{
+ return fdtdec_setup_mem_size_base_superlative(true);
+}
+
+int fdtdec_setup_mem_size_base_highest(void)
+{
+ return fdtdec_setup_mem_size_base_superlative(false);
+}
+
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP) ||\
CONFIG_IS_ENABLED(MULTI_DTB_FIT_LZO)