#include <errno.h>
#include <fdtdec.h>
#include <fdt_support.h>
-#include <inttypes.h>
+#include <mapmem.h>
#include <linux/libfdt.h>
#include <serial.h>
#include <asm/sections.h>
COMPAT(NVIDIA_TEGRA210_XUSB_PADCTL, "nvidia,tegra210-xusb-padctl"),
COMPAT(SMSC_LAN9215, "smsc,lan9215"),
COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),
- COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),
- COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"),
- COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"),
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"),
COMPAT(SAMSUNG_EXYNOS_MIPI_DSI, "samsung,exynos-mipi-dsi"),
COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"),
- COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"),
COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
- COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
- COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
COMPAT(INTEL_MICROCODE, "intel,microcode"),
- COMPAT(AMS_AS3722, "ams,as3722"),
COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
COMPAT(ALTERA_SOCFPGA_DWMAC, "altr,socfpga-stmmac"),
COMPAT(ALTERA_SOCFPGA_DWMMC, "altr,socfpga-dw-mshc"),
debug("%s: %s: ", __func__, prop_name);
- if (na > (sizeof(fdt_addr_t) / sizeof(fdt32_t))) {
- debug("(na too large for fdt_addr_t type)\n");
- return FDT_ADDR_T_NONE;
- }
-
- if (ns > (sizeof(fdt_size_t) / sizeof(fdt32_t))) {
- debug("(ns too large for fdt_size_t type)\n");
- return FDT_ADDR_T_NONE;
- }
-
prop = fdt_getprop(blob, node, prop_name, &len);
if (!prop) {
debug("(not found)\n");
return fdtdec_get_addr_size(blob, node, prop_name, NULL);
}
-#if defined(CONFIG_PCI) && defined(CONFIG_DM_PCI)
+#if CONFIG_IS_ENABLED(PCI) && defined(CONFIG_DM_PCI)
int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
const char *prop_name, struct fdt_pci_addr *addr)
{
return -ENOENT;
}
+int fdtdec_get_alias_highest_id(const void *blob, const char *base)
+{
+ int base_len = strlen(base);
+ int prop_offset;
+ int aliases;
+ int max = -1;
+
+ debug("Looking for highest alias id for '%s'\n", base);
+
+ aliases = fdt_path_offset(blob, "/aliases");
+ for (prop_offset = fdt_first_property_offset(blob, aliases);
+ prop_offset > 0;
+ prop_offset = fdt_next_property_offset(blob, prop_offset)) {
+ const char *prop;
+ const char *name;
+ int len, val;
+
+ prop = fdt_getprop_by_offset(blob, prop_offset, &name, &len);
+ debug(" - %s, %s\n", name, prop);
+ if (*prop != '/' || prop[len - 1] ||
+ strncmp(name, base, base_len))
+ continue;
+
+ val = trailing_strtol(name);
+ if (val > max) {
+ debug("Found seq %d\n", val);
+ max = val;
+ }
+ }
+
+ return max;
+}
+
const char *fdtdec_get_chosen_prop(const void *blob, const char *name)
{
int chosen_node;
return (char *)nodep;
}
-int fdtdec_decode_region(const void *blob, int node, const char *prop_name,
- fdt_addr_t *basep, fdt_size_t *sizep)
-{
- const fdt_addr_t *cell;
- int len;
-
- debug("%s: %s: %s\n", __func__, fdt_get_name(blob, node, NULL),
- prop_name);
- cell = fdt_getprop(blob, node, prop_name, &len);
- if (!cell || (len < sizeof(fdt_addr_t) * 2)) {
- debug("cell=%p, len=%d\n", cell, len);
- return -1;
- }
-
- *basep = fdt_addr_to_cpu(*cell);
- *sizep = fdt_size_to_cpu(cell[1]);
- debug("%s: base=%08lx, size=%lx\n", __func__, (ulong)*basep,
- (ulong)*sizep);
-
- return 0;
-}
-
u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
{
u64 number = 0;
return fdt_get_resource(fdt, node, property, index, res);
}
-int fdtdec_decode_memory_region(const void *blob, int config_node,
- const char *mem_type, const char *suffix,
- fdt_addr_t *basep, fdt_size_t *sizep)
-{
- char prop_name[50];
- const char *mem;
- fdt_size_t size, offset_size;
- fdt_addr_t base, offset;
- int node;
-
- if (config_node == -1) {
- config_node = fdt_path_offset(blob, "/config");
- if (config_node < 0) {
- debug("%s: Cannot find /config node\n", __func__);
- return -ENOENT;
- }
- }
- if (!suffix)
- suffix = "";
-
- snprintf(prop_name, sizeof(prop_name), "%s-memory%s", mem_type,
- suffix);
- mem = fdt_getprop(blob, config_node, prop_name, NULL);
- if (!mem) {
- debug("%s: No memory type for '%s', using /memory\n", __func__,
- prop_name);
- mem = "/memory";
- }
-
- node = fdt_path_offset(blob, mem);
- if (node < 0) {
- debug("%s: Failed to find node '%s': %s\n", __func__, mem,
- fdt_strerror(node));
- return -ENOENT;
- }
-
- /*
- * Not strictly correct - the memory may have multiple banks. We just
- * use the first
- */
- if (fdtdec_decode_region(blob, node, "reg", &base, &size)) {
- debug("%s: Failed to decode memory region %s\n", __func__,
- mem);
- return -EINVAL;
- }
-
- snprintf(prop_name, sizeof(prop_name), "%s-offset%s", mem_type,
- suffix);
- if (fdtdec_decode_region(blob, config_node, prop_name, &offset,
- &offset_size)) {
- debug("%s: Failed to decode memory region '%s'\n", __func__,
- prop_name);
- return -EINVAL;
- }
-
- *basep = base + offset;
- *sizep = offset_size;
-
- return 0;
-}
-
static int decode_timing_property(const void *blob, int node, const char *name,
struct timing_entry *result)
{
#if defined(CONFIG_NR_DRAM_BANKS)
-static int get_next_memory_node(const void *blob, int startoffset)
+static int get_next_memory_node(const void *blob, int mem)
{
- int mem = -1;
-
do {
mem = fdt_node_offset_by_prop_value(gd->fdt_blob, mem,
"device_type", "memory", 7);
# else
static int uncompress_blob(const void *src, ulong sz_src, void **dstp)
{
- return -ENOTSUPP;
+ *dstp = (void *)src;
+ return 0;
}
# endif
#endif
# if CONFIG_IS_ENABLED(OF_PRIOR_STAGE)
gd->fdt_blob = (void *)prior_stage_fdt_address;
# else
- gd->fdt_blob = (void *)env_get_ulong("fdtcontroladdr", 16,
- (uintptr_t)gd->fdt_blob);
+ gd->fdt_blob = map_sysmem
+ (env_get_ulong("fdtcontroladdr", 16,
+ (unsigned long)map_to_sysmem(gd->fdt_blob)), 0);
# endif
# endif
* If so, pick the most relevant
*/
fdt_blob = locate_dtb_in_fit(gd->fdt_blob);
- if (fdt_blob)
+ if (fdt_blob) {
+ gd->multi_dtb_fit = gd->fdt_blob;
gd->fdt_blob = fdt_blob;
+ }
+
# endif
#endif
return fdtdec_prepare_fdt();
}
+#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
+int fdtdec_resetup(int *rescan)
+{
+ void *fdt_blob;
+
+ /*
+ * If the current DTB is part of a compressed FIT image,
+ * try to locate the best match from the uncompressed
+ * FIT image stillpresent there. Save the time and space
+ * required to uncompress it again.
+ */
+ if (gd->multi_dtb_fit) {
+ fdt_blob = locate_dtb_in_fit(gd->multi_dtb_fit);
+
+ if (fdt_blob == gd->fdt_blob) {
+ /*
+ * The best match did not change. no need to tear down
+ * the DM and rescan the fdt.
+ */
+ *rescan = 0;
+ return 0;
+ }
+
+ *rescan = 1;
+ gd->fdt_blob = fdt_blob;
+ return fdtdec_prepare_fdt();
+ }
+
+ /*
+ * If multi_dtb_fit is NULL, it means that blob appended to u-boot is
+ * not a FIT image containings DTB, but a single DTB. There is no need
+ * to teard down DM and rescan the DT in this case.
+ */
+ *rescan = 0;
+ return 0;
+}
+#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)
if (auto_size) {
u64 new_size;
- debug("Auto-sizing %" PRIx64 ", size %" PRIx64 ": ",
- addr, size);
+ debug("Auto-sizing %llx, size %llx: ", addr, size);
new_size = get_ram_size((long *)(uintptr_t)addr, size);
if (new_size == size) {
debug("OK\n");
} else {
- debug("sized to %" PRIx64 "\n", new_size);
+ debug("sized to %llx\n", new_size);
size = new_size;
}
}
total_size += size;
}
- debug("Memory size %" PRIu64 "\n", total_size);
+ debug("Memory size %llu\n", total_size);
if (sizep)
*sizep = (phys_size_t)total_size;