[U-Boot] [PATCH 1/3] fdt: add memory bank decoding functions for board setup
Simon Glass
sjg at chromium.org
Sun Dec 11 21:27:54 CET 2016
Hi Nathan,
On 11 December 2016 at 08:58, Nathan Rossi <nathan at nathanrossi.com> wrote:
> 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 at nathanrossi.com>
> Cc: Simon Glass <sjg at chromium.org>
> Cc: Michal Simek <monstr at monstr.eu>
> ---
> This implementation of decoding has been tested on zynq and zynqmp
> boards with address/size cells of (1, 1), (1, 2), (2, 1), (2, 2) and
> up to 2 memory banks.
> ---
> include/fdtdec.h | 25 +++++++++++++++++++++++++
> lib/fdtdec.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 79 insertions(+)
Reviewed-by: Simon Glass <sjg at chromium.org>
Please see nit below.
>
> diff --git a/include/fdtdec.h b/include/fdtdec.h
> index 27887c8c21..59a204b571 100644
> --- a/include/fdtdec.h
> +++ b/include/fdtdec.h
> @@ -976,6 +976,31 @@ 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 the boards dram_init().
> + *
> + * @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
> + * the boards dram_init_banksize().
> + *
> + * @return 0 if OK, negative on error
Good to be specific, if e.g. it can only return -EINVAL.
> + */
> +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 4e619c49a2..bc3be017b6 100644
> --- a/lib/fdtdec.c
> +++ b/lib/fdtdec.c
> @@ -1174,6 +1174,60 @@ 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;
> +}
> +
> +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 ret;
The return above return -EINVAL, but this one returns a -FDT_ERR_...
which is different. So my suggestion here would be to return -EINVAL
here, unless you want to change the function to always return an FDT
error (although fdtdec_decode_memory_region() returns an errno error
so perhaps it is better to be consistent with that).
> +
> + 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;
> +}
> +
> int fdtdec_setup(void)
> {
> #if CONFIG_IS_ENABLED(OF_CONTROL)
> --
> 2.10.2
>
Regards,
Simon
More information about the U-Boot
mailing list