Commit 623f60198b38c4fdae596038cd5956e44b6224a4
Committed by
Michal Simek
1 parent
91d11536da
Exists in
v2017.01-smarct4x
and in
25 other branches
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>
Showing 2 changed files with 90 additions and 0 deletions Side-by-side Diff
include/fdtdec.h
... | ... | @@ -976,6 +976,40 @@ |
976 | 976 | */ |
977 | 977 | int fdtdec_decode_display_timing(const void *blob, int node, int index, |
978 | 978 | struct display_timing *config); |
979 | + | |
980 | +/** | |
981 | + * fdtdec_setup_memory_size() - decode and setup gd->ram_size | |
982 | + * | |
983 | + * Decode the /memory 'reg' property to determine the size of the first memory | |
984 | + * bank, populate the global data with the size of the first bank of memory. | |
985 | + * | |
986 | + * This function should be called from a boards dram_init(). This helper | |
987 | + * function allows for boards to query the device tree for DRAM size instead of | |
988 | + * hard coding the value in the case where the memory size cannot be detected | |
989 | + * automatically. | |
990 | + * | |
991 | + * @return 0 if OK, -EINVAL if the /memory node or reg property is missing or | |
992 | + * invalid | |
993 | + */ | |
994 | +int fdtdec_setup_memory_size(void); | |
995 | + | |
996 | +/** | |
997 | + * fdtdec_setup_memory_banksize() - decode and populate gd->bd->bi_dram | |
998 | + * | |
999 | + * Decode the /memory 'reg' property to determine the address and size of the | |
1000 | + * memory banks. Use this data to populate the global data board info with the | |
1001 | + * phys address and size of memory banks. | |
1002 | + * | |
1003 | + * This function should be called from a boards dram_init_banksize(). This | |
1004 | + * helper function allows for boards to query the device tree for memory bank | |
1005 | + * information instead of hard coding the information in cases where it cannot | |
1006 | + * be detected automatically. | |
1007 | + * | |
1008 | + * @return 0 if OK, -EINVAL if the /memory node or reg property is missing or | |
1009 | + * invalid | |
1010 | + */ | |
1011 | +int fdtdec_setup_memory_banksize(void); | |
1012 | + | |
979 | 1013 | /** |
980 | 1014 | * Set up the device tree ready for use |
981 | 1015 | */ |
lib/fdtdec.c
... | ... | @@ -1174,6 +1174,62 @@ |
1174 | 1174 | return ret; |
1175 | 1175 | } |
1176 | 1176 | |
1177 | +int fdtdec_setup_memory_size(void) | |
1178 | +{ | |
1179 | + int ret, mem; | |
1180 | + struct fdt_resource res; | |
1181 | + | |
1182 | + mem = fdt_path_offset(gd->fdt_blob, "/memory"); | |
1183 | + if (mem < 0) { | |
1184 | + debug("%s: Missing /memory node\n", __func__); | |
1185 | + return -EINVAL; | |
1186 | + } | |
1187 | + | |
1188 | + ret = fdt_get_resource(gd->fdt_blob, mem, "reg", 0, &res); | |
1189 | + if (ret != 0) { | |
1190 | + debug("%s: Unable to decode first memory bank\n", __func__); | |
1191 | + return -EINVAL; | |
1192 | + } | |
1193 | + | |
1194 | + gd->ram_size = (phys_size_t)(res.end - res.start + 1); | |
1195 | + debug("%s: Initial DRAM size %llx\n", __func__, (u64)gd->ram_size); | |
1196 | + | |
1197 | + return 0; | |
1198 | +} | |
1199 | + | |
1200 | +#if defined(CONFIG_NR_DRAM_BANKS) | |
1201 | +int fdtdec_setup_memory_banksize(void) | |
1202 | +{ | |
1203 | + int bank, ret, mem; | |
1204 | + struct fdt_resource res; | |
1205 | + | |
1206 | + mem = fdt_path_offset(gd->fdt_blob, "/memory"); | |
1207 | + if (mem < 0) { | |
1208 | + debug("%s: Missing /memory node\n", __func__); | |
1209 | + return -EINVAL; | |
1210 | + } | |
1211 | + | |
1212 | + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { | |
1213 | + ret = fdt_get_resource(gd->fdt_blob, mem, "reg", bank, &res); | |
1214 | + if (ret == -FDT_ERR_NOTFOUND) | |
1215 | + break; | |
1216 | + if (ret != 0) | |
1217 | + return -EINVAL; | |
1218 | + | |
1219 | + gd->bd->bi_dram[bank].start = (phys_addr_t)res.start; | |
1220 | + gd->bd->bi_dram[bank].size = | |
1221 | + (phys_size_t)(res.end - res.start + 1); | |
1222 | + | |
1223 | + debug("%s: DRAM Bank #%d: start = 0x%llx, size = 0x%llx\n", | |
1224 | + __func__, bank, | |
1225 | + (unsigned long long)gd->bd->bi_dram[bank].start, | |
1226 | + (unsigned long long)gd->bd->bi_dram[bank].size); | |
1227 | + } | |
1228 | + | |
1229 | + return 0; | |
1230 | +} | |
1231 | +#endif | |
1232 | + | |
1177 | 1233 | int fdtdec_setup(void) |
1178 | 1234 | { |
1179 | 1235 | #if CONFIG_IS_ENABLED(OF_CONTROL) |