diff options
author | Nathan Rossi <nathan@nathanrossi.com> | 2016-12-19 00:03:34 +1000 |
---|---|---|
committer | Michal Simek <michal.simek@xilinx.com> | 2016-12-20 09:15:28 +0100 |
commit | 623f60198b38c4fdae596038cd5956e44b6224a4 (patch) | |
tree | 4c1868e61c4dc1ea970aec32a0c0a7a5e3200379 | |
parent | 91d11536da7c34a88db34d6dee20cc6ea6e06bdc (diff) | |
download | u-boot-imx-623f60198b38c4fdae596038cd5956e44b6224a4.zip u-boot-imx-623f60198b38c4fdae596038cd5956e44b6224a4.tar.gz u-boot-imx-623f60198b38c4fdae596038cd5956e44b6224a4.tar.bz2 |
fdt: add memory bank decoding functions for board setup
Add two functions for use by board implementations to decode the memory
banks of the /memory node so as to populate the global data with
ram_size and board info for memory banks.
The fdtdec_setup_memory_size() function decodes the first memory bank
and sets up the gd->ram_size with the size of the memory bank. This
function should be called from the boards dram_init().
The fdtdec_setup_memory_banksize() function decode the memory banks
(up to the CONFIG_NR_DRAM_BANKS) and populates the base address and size
into the gd->bd->bi_dram array of banks. This function should be called
from the boards dram_init_banksize().
Signed-off-by: Nathan Rossi <nathan@nathanrossi.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Michal Simek <monstr@monstr.eu>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
-rw-r--r-- | include/fdtdec.h | 34 | ||||
-rw-r--r-- | lib/fdtdec.c | 56 |
2 files changed, 90 insertions, 0 deletions
diff --git a/include/fdtdec.h b/include/fdtdec.h index 27887c8..d074478 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -976,6 +976,40 @@ struct display_timing { */ int fdtdec_decode_display_timing(const void *blob, int node, int index, struct display_timing *config); + +/** + * fdtdec_setup_memory_size() - decode and setup gd->ram_size + * + * Decode the /memory 'reg' property to determine the size of the first memory + * bank, populate the global data with the size of the first bank of memory. + * + * This function should be called from a boards dram_init(). This helper + * function allows for boards to query the device tree for DRAM size instead of + * hard coding the value in the case where the memory size cannot be detected + * automatically. + * + * @return 0 if OK, -EINVAL if the /memory node or reg property is missing or + * invalid + */ +int fdtdec_setup_memory_size(void); + +/** + * fdtdec_setup_memory_banksize() - decode and populate gd->bd->bi_dram + * + * Decode the /memory 'reg' property to determine the address and size of the + * memory banks. Use this data to populate the global data board info with the + * phys address and size of memory banks. + * + * This function should be called from a boards dram_init_banksize(). This + * helper function allows for boards to query the device tree for memory bank + * information instead of hard coding the information in cases where it cannot + * be detected automatically. + * + * @return 0 if OK, -EINVAL if the /memory node or reg property is missing or + * invalid + */ +int fdtdec_setup_memory_banksize(void); + /** * Set up the device tree ready for use */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 4e619c4..81f47ef 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1174,6 +1174,62 @@ int fdtdec_decode_display_timing(const void *blob, int parent, int index, return ret; } +int fdtdec_setup_memory_size(void) +{ + int ret, mem; + struct fdt_resource res; + + mem = fdt_path_offset(gd->fdt_blob, "/memory"); + if (mem < 0) { + debug("%s: Missing /memory node\n", __func__); + return -EINVAL; + } + + ret = fdt_get_resource(gd->fdt_blob, mem, "reg", 0, &res); + if (ret != 0) { + debug("%s: Unable to decode first memory bank\n", __func__); + return -EINVAL; + } + + gd->ram_size = (phys_size_t)(res.end - res.start + 1); + debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size); + + return 0; +} + +#if defined(CONFIG_NR_DRAM_BANKS) +int fdtdec_setup_memory_banksize(void) +{ + int bank, ret, mem; + struct fdt_resource res; + + mem = fdt_path_offset(gd->fdt_blob, "/memory"); + if (mem < 0) { + debug("%s: Missing /memory node\n", __func__); + return -EINVAL; + } + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + ret = fdt_get_resource(gd->fdt_blob, mem, "reg", bank, &res); + if (ret == -FDT_ERR_NOTFOUND) + break; + if (ret != 0) + return -EINVAL; + + gd->bd->bi_dram[bank].start = (phys_addr_t)res.start; + gd->bd->bi_dram[bank].size = + (phys_size_t)(res.end - res.start + 1); + + debug("%s: DRAM Bank #%d: start = 0x%llx, size = 0x%llx\n", + __func__, bank, + (unsigned long long)gd->bd->bi_dram[bank].start, + (unsigned long long)gd->bd->bi_dram[bank].size); + } + + return 0; +} +#endif + int fdtdec_setup(void) { #if CONFIG_IS_ENABLED(OF_CONTROL) |