X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=lib%2Ffdtdec.c;h=1b0c430945a937661c791d26fe3d97034606754f;hb=1703fbefd9183fffd76f4744a73f5ca9daef6313;hp=df9d9ae4333a3f82212ab5e84f92f1c7f53a924c;hpb=b79221a7d9132fd7bfd81cad9ebdc37acb39f69e;p=u-boot diff --git a/lib/fdtdec.c b/lib/fdtdec.c index df9d9ae433..1b0c430945 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2011 The Chromium OS Authors. - * SPDX-License-Identifier: GPL-2.0+ */ #ifndef USE_HOSTCC @@ -11,7 +11,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -48,7 +49,6 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_EXYNOS_MIPI_DSI, "samsung,exynos-mipi-dsi"), COMPAT(SAMSUNG_EXYNOS_DWMMC, "samsung,exynos-dwmmc"), COMPAT(SAMSUNG_EXYNOS_MMC, "samsung,exynos-mmc"), - COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686"), COMPAT(GENERIC_SPI_FLASH, "spi-flash"), COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"), COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"), @@ -73,6 +73,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(ALTERA_SOCFPGA_F2SDR2, "altr,socfpga-fpga2sdram2-bridge"), COMPAT(ALTERA_SOCFPGA_FPGA0, "altr,socfpga-a10-fpga-mgr"), COMPAT(ALTERA_SOCFPGA_NOC, "altr,socfpga-a10-noc"), + COMPAT(ALTERA_SOCFPGA_CLK_INIT, "altr,socfpga-a10-clk-init") }; const char *fdtdec_get_compatible(enum fdt_compat_id id) @@ -1323,8 +1324,12 @@ int fdtdec_setup(void) # endif # ifndef CONFIG_SPL_BUILD /* Allow the early environment to override the fdt address */ +# 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); +# endif # endif # if CONFIG_IS_ENABLED(MULTI_DTB_FIT) @@ -1350,4 +1355,112 @@ int fdtdec_setup(void) return fdtdec_prepare_fdt(); } +#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) +{ + int addr_cells, size_cells; + const u32 *cell, *end; + u64 total_size, size, addr; + int node, child; + bool auto_size; + int bank; + int len; + + debug("%s: board_id=%d\n", __func__, board_id); + if (!area) + area = "/memory"; + node = fdt_path_offset(blob, area); + if (node < 0) { + debug("No %s node found\n", area); + return -ENOENT; + } + + cell = fdt_getprop(blob, node, "reg", &len); + if (!cell) { + debug("No reg property found\n"); + return -ENOENT; + } + + addr_cells = fdt_address_cells(blob, node); + size_cells = fdt_size_cells(blob, node); + + /* Check the board id and mask */ + for (child = fdt_first_subnode(blob, node); + child >= 0; + child = fdt_next_subnode(blob, child)) { + int match_mask, match_value; + + match_mask = fdtdec_get_int(blob, child, "match-mask", -1); + match_value = fdtdec_get_int(blob, child, "match-value", -1); + + if (match_value >= 0 && + ((board_id & match_mask) == match_value)) { + /* Found matching mask */ + debug("Found matching mask %d\n", match_mask); + node = child; + cell = fdt_getprop(blob, node, "reg", &len); + if (!cell) { + debug("No memory-banks property found\n"); + return -EINVAL; + } + break; + } + } + /* Note: if no matching subnode was found we use the parent node */ + + if (bd) { + memset(bd->bi_dram, '\0', sizeof(bd->bi_dram[0]) * + CONFIG_NR_DRAM_BANKS); + } + + auto_size = fdtdec_get_bool(blob, node, "auto-size"); + + total_size = 0; + end = cell + len / 4 - addr_cells - size_cells; + debug("cell at %p, end %p\n", cell, end); + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + if (cell > end) + break; + addr = 0; + if (addr_cells == 2) + addr += (u64)fdt32_to_cpu(*cell++) << 32UL; + addr += fdt32_to_cpu(*cell++); + if (bd) + bd->bi_dram[bank].start = addr; + if (basep && !bank) + *basep = (phys_addr_t)addr; + + size = 0; + if (size_cells == 2) + size += (u64)fdt32_to_cpu(*cell++) << 32UL; + size += fdt32_to_cpu(*cell++); + + if (auto_size) { + u64 new_size; + + debug("Auto-sizing %" PRIx64 ", size %" PRIx64 ": ", + 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); + size = new_size; + } + } + + if (bd) + bd->bi_dram[bank].size = size; + total_size += size; + } + + debug("Memory size %" PRIu64 "\n", total_size); + if (sizep) + *sizep = (phys_size_t)total_size; + + return 0; +} +#endif /* CONFIG_NR_DRAM_BANKS */ + #endif /* !USE_HOSTCC */