]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
fdt: Add a function to decode a named memory region
authorSimon Glass <sjg@chromium.org>
Fri, 24 Oct 2014 00:58:56 +0000 (18:58 -0600)
committerSimon Glass <sjg@chromium.org>
Fri, 21 Nov 2014 03:43:18 +0000 (04:43 +0100)
Permit decoding of a named memory region from the device tree. This allows
easy run-time configuration of the address of on-chip SRAM, SDRAM, etc.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@ti.com>
include/fdtdec.h
lib/fdtdec.c

index 1a931e845993b73cbb19ad854473ded376f83db9..a7655dc19391378864485af4124890f1e94eb9c2 100644 (file)
@@ -677,4 +677,31 @@ int fdt_get_named_resource(const void *fdt, int node, const char *property,
  */
 int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf);
 
+/**
+ * Decode a named region within a memory bank of a given type.
+ *
+ * This function handles selection of a memory region. The region is
+ * specified as an offset/size within a particular type of memory.
+ *
+ * The properties used are:
+ *
+ *     <mem_type>-memory<suffix> for the name of the memory bank
+ *     <mem_type>-offset<suffix> for the offset in that bank
+ *
+ * The property value must have an offset and a size. The function checks
+ * that the region is entirely within the memory bank.5
+ *
+ * @param blob         FDT blob
+ * @param node         Node containing the properties (-1 for /config)
+ * @param mem_type     Type of memory to use, which is a name, such as
+ *                     "u-boot" or "kernel".
+ * @param suffix       String to append to the memory/offset
+ *                     property names
+ * @param basep                Returns base of region
+ * @param sizep                Returns size of region
+ * @return 0 if OK, -ive on error
+ */
+int fdtdec_decode_memory_region(const void *blob, int node,
+                               const char *mem_type, const char *suffix,
+                               fdt_addr_t *basep, fdt_size_t *sizep);
 #endif
index 4dbd6aee853b8b03ec157d7189882e4f664074e7..9c332ad903ee63608f7ffd97e97bdb2240f97b44 100644 (file)
@@ -793,4 +793,65 @@ int fdtdec_pci_get_bdf(const void *fdt, int node, int *bdf)
 
        return 0;
 }
+
+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;
+}
 #endif