diff mbox series

[v2,08/16] lib: fdt: Add fdtdec_setup_mem_size_base_highest

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

Commit Message

Sean Anderson Oct. 12, 2020, 6:13 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>
Reviewed-by: Simon Glass <sjg@chromium.org>
---

(no changes since v1)

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

Comments

Rick Chen Nov. 3, 2020, 7:14 a.m. UTC | #1
> 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>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>
> (no changes since v1)
>
>  include/fdtdec.h | 19 ++++++++++++++++++-
>  lib/fdtdec.c     | 34 +++++++++++++++++++++++++++++-----
>  2 files changed, 47 insertions(+), 6 deletions(-)
>

Reviewed-by: Rick Chen <rick@andestech.com>
diff mbox series

Patch

diff --git a/include/fdtdec.h b/include/fdtdec.h
index 62d1660973..6a8e235674 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 ee1bd41b08..78b34bf4da 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -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)