diff mbox series

[04/10] lib: fdt: Add fdtdec_setup_mem_size_base_highest

Message ID 20200929141835.38435-5-seanga2@gmail.com
State Superseded
Delegated to: Andes
Headers show
Series riscv: k210: Enable use of AI ram bank | expand

Commit Message

Sean Anderson Sept. 29, 2020, 2:18 p.m. UTC
This is very similar to fdtdec_setup_mem_size_base_lowest, except we pick
the highest ram bank, instead of the lowest. This is helpful for boards
which use separate but contiguous ram banks, as it leaves the most space
for loading programs.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
---

 include/fdtdec.h | 19 ++++++++++++++++++-
 lib/fdtdec.c     | 34 +++++++++++++++++++++++++++++-----
 2 files changed, 47 insertions(+), 6 deletions(-)

Comments

Simon Glass Oct. 12, 2020, 3:34 a.m. UTC | #1
On Tue, 29 Sep 2020 at 08:18, Sean Anderson <seanga2@gmail.com> wrote:
>
> This is very similar to fdtdec_setup_mem_size_base_lowest, except we pick
> the highest ram bank, instead of the lowest. This is helpful for boards
> which use separate but contiguous ram banks, as it leaves the most space
> for loading programs.
>
> Signed-off-by: Sean Anderson <seanga2@gmail.com>
> ---
>
>  include/fdtdec.h | 19 ++++++++++++++++++-
>  lib/fdtdec.c     | 34 +++++++++++++++++++++++++++++-----
>  2 files changed, 47 insertions(+), 6 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>
diff mbox series

Patch

diff --git a/include/fdtdec.h b/include/fdtdec.h
index 152eb07b9e..0ccea1a77d 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -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
  *
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 5f41f58a63..439ab6525c 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1125,7 +1125,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;
@@ -1133,7 +1133,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)) {
@@ -1160,16 +1169,31 @@  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);
+}
 #endif
 
 #if CONFIG_IS_ENABLED(MULTI_DTB_FIT)