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>
This commit is contained in:
Nathan Rossi 2016-12-19 00:03:34 +10:00 committed by Michal Simek
parent 91d11536da
commit 623f60198b
2 changed files with 90 additions and 0 deletions

View File

@ -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
*/

View File

@ -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)