#include <mapmem.h>
#include <linux/libfdt.h>
#include <serial.h>
+#include <asm/global_data.h>
#include <asm/sections.h>
#include <linux/ctype.h>
#include <linux/lzo.h>
+#include <linux/ioport.h>
DECLARE_GLOBAL_DATA_PTR;
COMPAT(NVIDIA_TEGRA20_NAND, "nvidia,tegra20-nand"),
COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"),
COMPAT(NVIDIA_TEGRA210_XUSB_PADCTL, "nvidia,tegra210-xusb-padctl"),
- COMPAT(SMSC_LAN9215, "smsc,lan9215"),
- COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),
COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
COMPAT(SAMSUNG_EXYNOS5_USB3_PHY, "samsung,exynos5250-usb3-phy"),
COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"),
return fdtdec_get_addr_size(blob, node, prop_name, NULL);
}
-#if CONFIG_IS_ENABLED(PCI) && defined(CONFIG_DM_PCI)
int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device)
{
const char *list, *end;
return -EINVAL;
barnum = (barnum - PCI_BASE_ADDRESS_0) / 4;
+
+ /*
+ * There is a strange toolchain bug with nds32 which complains about
+ * an undefined reference here, even if fdtdec_get_pci_bar32() is never
+ * called. An #ifdef seems to be the only fix!
+ */
+#if !IS_ENABLED(CONFIG_NDS32)
*bar = dm_pci_read_bar32(dev, barnum);
+#endif
+
+ return 0;
+}
+
+int fdtdec_get_pci_bus_range(const void *blob, int node,
+ struct fdt_resource *res)
+{
+ const u32 *values;
+ int len;
+
+ values = fdt_getprop(blob, node, "bus-range", &len);
+ if (!values || len < sizeof(*values) * 2)
+ return -EINVAL;
+
+ res->start = fdt32_to_cpu(*values++);
+ res->end = fdt32_to_cpu(*values);
return 0;
}
-#endif
uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name,
uint64_t default_val)
continue;
/* Get the alias number */
- number = simple_strtoul(path + name_len, NULL, 10);
+ number = dectoul(path + name_len, NULL);
if (number < 0 || number >= maxcount) {
debug("%s: warning: alias '%s' is out of range\n",
__func__, path);
slash = strrchr(prop, '/');
if (strcmp(slash + 1, find_name))
continue;
+
+ /*
+ * Adding an extra check to distinguish DT nodes with
+ * same name
+ */
+ if (IS_ENABLED(CONFIG_PHANDLE_CHECK_SEQ)) {
+ if (fdt_get_phandle(blob, offset) !=
+ fdt_get_phandle(blob, fdt_path_offset(blob, prop)))
+ continue;
+ }
+
val = trailing_strtol(name);
if (val != -1) {
*seqp = val;
#ifdef CONFIG_SPL_BUILD
puts("Missing DTB\n");
#else
- puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");
+ printf("No valid device tree binary found at %p\n",
+ gd->fdt_blob);
# ifdef DEBUG
if (gd->fdt_blob) {
printf("fdt_blob=%p\n", gd->fdt_blob);
if (cells_name || cur_index == index) {
node = fdt_node_offset_by_phandle(blob,
phandle);
- if (!node) {
+ if (node < 0) {
debug("%s: could not find phandle\n",
fdt_get_name(blob, src_node,
NULL));
return cell;
}
-int fdtdec_get_config_int(const void *blob, const char *prop_name,
- int default_val)
-{
- int config_node;
-
- debug("%s: %s\n", __func__, prop_name);
- config_node = fdt_path_offset(blob, "/config");
- if (config_node < 0)
- return default_val;
- return fdtdec_get_int(blob, config_node, prop_name, default_val);
-}
-
-int fdtdec_get_config_bool(const void *blob, const char *prop_name)
-{
- int config_node;
- const void *prop;
-
- debug("%s: %s\n", __func__, prop_name);
- config_node = fdt_path_offset(blob, "/config");
- if (config_node < 0)
- return 0;
- prop = fdt_get_property(blob, config_node, prop_name, NULL);
-
- return prop != NULL;
-}
-
-char *fdtdec_get_config_string(const void *blob, const char *prop_name)
-{
- const char *nodep;
- int nodeoffset;
- int len;
-
- debug("%s: %s\n", __func__, prop_name);
- nodeoffset = fdt_path_offset(blob, "/config");
- if (nodeoffset < 0)
- return NULL;
-
- nodep = fdt_getprop(blob, nodeoffset, prop_name, &len);
- if (!nodep)
- return NULL;
-
- return (char *)nodep;
-}
-
u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
{
u64 number = 0;
while (ptr + na + ns <= end) {
if (i == index) {
- res->start = fdtdec_get_number(ptr, na);
+ if (CONFIG_IS_ENABLED(OF_TRANSLATE))
+ res->start = fdt_translate_address(fdt, node, ptr);
+ else
+ res->start = fdtdec_get_number(ptr, na);
+
res->end = res->start;
res->end += fdtdec_get_number(&ptr[na], ns) - 1;
return 0;
return ret;
}
-int fdtdec_setup_mem_size_base_fdt(const void *blob)
+int fdtdec_setup_mem_size_base(void)
{
- int ret, mem;
- struct fdt_resource res;
+ int ret;
+ ofnode mem;
+ struct resource res;
- mem = fdt_path_offset(blob, "/memory");
- if (mem < 0) {
+ mem = ofnode_path("/memory");
+ if (!ofnode_valid(mem)) {
debug("%s: Missing /memory node\n", __func__);
return -EINVAL;
}
- ret = fdt_get_resource(blob, mem, "reg", 0, &res);
+ ret = ofnode_read_resource(mem, 0, &res);
if (ret != 0) {
debug("%s: Unable to decode first memory bank\n", __func__);
return -EINVAL;
return 0;
}
-int fdtdec_setup_mem_size_base(void)
-{
- return fdtdec_setup_mem_size_base_fdt(gd->fdt_blob);
-}
-
-#if defined(CONFIG_NR_DRAM_BANKS)
-
-static int get_next_memory_node(const void *blob, int mem)
+ofnode get_next_memory_node(ofnode mem)
{
do {
- mem = fdt_node_offset_by_prop_value(blob, mem,
- "device_type", "memory", 7);
- } while (!fdtdec_get_is_enabled(blob, mem));
+ mem = ofnode_by_prop_value(mem, "device_type", "memory", 7);
+ } while (!ofnode_is_available(mem));
return mem;
}
-int fdtdec_setup_memory_banksize_fdt(const void *blob)
+int fdtdec_setup_memory_banksize(void)
{
- int bank, ret, mem, reg = 0;
- struct fdt_resource res;
+ int bank, ret, reg = 0;
+ struct resource res;
+ ofnode mem = ofnode_null();
- mem = get_next_memory_node(blob, -1);
- if (mem < 0) {
+ mem = get_next_memory_node(mem);
+ if (!ofnode_valid(mem)) {
debug("%s: Missing /memory node\n", __func__);
return -EINVAL;
}
for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
- ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
- if (ret == -FDT_ERR_NOTFOUND) {
+ ret = ofnode_read_resource(mem, reg++, &res);
+ if (ret < 0) {
reg = 0;
- mem = get_next_memory_node(blob, mem);
- if (mem == -FDT_ERR_NOTFOUND)
+ mem = get_next_memory_node(mem);
+ if (!ofnode_valid(mem))
break;
- ret = fdt_get_resource(blob, mem, "reg", reg++, &res);
- if (ret == -FDT_ERR_NOTFOUND)
+ ret = ofnode_read_resource(mem, reg++, &res);
+ if (ret < 0)
break;
}
- if (ret != 0) {
+
+ if (ret != 0)
return -EINVAL;
- }
gd->bd->bi_dram[bank].start = (phys_addr_t)res.start;
gd->bd->bi_dram[bank].size =
return 0;
}
-int fdtdec_setup_memory_banksize(void)
+int fdtdec_setup_mem_size_base_lowest(void)
{
- return fdtdec_setup_memory_banksize_fdt(gd->fdt_blob);
+ int bank, ret, reg = 0;
+ struct resource res;
+ unsigned long base;
+ phys_size_t size;
+ ofnode mem = ofnode_null();
+
+ gd->ram_base = (unsigned long)~0;
+
+ mem = get_next_memory_node(mem);
+ if (!ofnode_valid(mem)) {
+ debug("%s: Missing /memory node\n", __func__);
+ return -EINVAL;
+ }
+ for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+ ret = ofnode_read_resource(mem, reg++, &res);
+ if (ret < 0) {
+ reg = 0;
+ mem = get_next_memory_node(mem);
+ if (!ofnode_valid(mem))
+ break;
+
+ ret = ofnode_read_resource(mem, reg++, &res);
+ if (ret < 0)
+ break;
+ }
+
+ if (ret != 0)
+ return -EINVAL;
+
+ base = (unsigned long)res.start;
+ size = (phys_size_t)(res.end - res.start + 1);
+
+ if (gd->ram_base > base && size) {
+ gd->ram_base = base;
+ gd->ram_size = size;
+ debug("%s: Initial DRAM base %lx size %lx\n",
+ __func__, base, (unsigned long)size);
+ }
+ }
+
+ return 0;
}
-#endif
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
# if CONFIG_IS_ENABLED(MULTI_DTB_FIT_GZIP) ||\
int fdtdec_add_reserved_memory(void *blob, const char *basename,
const struct fdt_memory *carveout,
- uint32_t *phandlep)
+ uint32_t *phandlep, bool no_map)
{
fdt32_t cells[4] = {}, *ptr = cells;
uint32_t upper, lower, phandle;
if (err < 0)
return err;
+ if (no_map) {
+ err = fdt_setprop(blob, node, "no-map", NULL, 0);
+ if (err < 0)
+ return err;
+ }
+
/* return the phandle for the new node for the caller to use */
if (phandlep)
*phandlep = phandle;
fdt32_t value;
void *prop;
- err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle);
+ err = fdtdec_add_reserved_memory(blob, name, carveout, &phandle, false);
if (err < 0) {
debug("failed to add reserved memory: %d\n", err);
return err;
return -1;
}
# elif defined(CONFIG_OF_PRIOR_STAGE)
- gd->fdt_blob = (void *)prior_stage_fdt_address;
+ gd->fdt_blob = (void *)(uintptr_t)prior_stage_fdt_address;
# endif
# ifndef CONFIG_SPL_BUILD
/* Allow the early environment to override the fdt address */
}
#endif
-#ifdef CONFIG_NR_DRAM_BANKS
int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id,
- phys_addr_t *basep, phys_size_t *sizep, bd_t *bd)
+ phys_addr_t *basep, phys_size_t *sizep,
+ struct bd_info *bd)
{
int addr_cells, size_cells;
const u32 *cell, *end;
return 0;
}
-#endif /* CONFIG_NR_DRAM_BANKS */
#endif /* !USE_HOSTCC */