arm: k3: Add support for updating msmc dt node
authorLokesh Vutla <lokeshvutla@ti.com>
Fri, 8 Mar 2019 06:17:34 +0000 (11:47 +0530)
committerTom Rini <trini@konsulko.com>
Fri, 12 Apr 2019 12:05:51 +0000 (08:05 -0400)
Certain parts of msmc sram can be used by DMSC or can be
marked as L3 cache. Since the available size can vary, changing
DT every time the size varies might be painful. So, query this
information using TISCI cmd and fixup the DT for kernel.
Fixing up DT does the following:
- Create a sram node if not available
- update the reg property with available size
- update ranges property
- loop through available sub nodes and delete it if:
- mentioned size is out if available range
- subnode represents l3 cache or dmsc usage.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
arch/arm/mach-k3/common.c
arch/arm/mach-k3/include/mach/sys_proto.h

index 23cd37c3c774557883f81a56b631e2bfa1f6a981..03f01d07eacf7c551f234c873a0d8a78a4e3e0ce 100644 (file)
@@ -12,6 +12,7 @@
 #include <dm.h>
 #include <remoteproc.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
+#include <fdt_support.h>
 
 struct ti_sci_handle *get_ti_sci_handle(void)
 {
@@ -55,3 +56,77 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
                asm volatile("wfe");
 }
 #endif
+
+#if defined(CONFIG_OF_LIBFDT)
+int fdt_fixup_msmc_ram(void *blob, char *parent_path, char *node_name)
+{
+       u64 msmc_start = 0, msmc_end = 0, msmc_size, reg[2];
+       struct ti_sci_handle *ti_sci = get_ti_sci_handle();
+       int ret, node, subnode, len, prev_node;
+       u32 range[4], addr, size;
+       const fdt32_t *sub_reg;
+
+       ti_sci->ops.core_ops.query_msmc(ti_sci, &msmc_start, &msmc_end);
+       msmc_size = msmc_end - msmc_start + 1;
+       debug("%s: msmc_start = 0x%llx, msmc_size = 0x%llx\n", __func__,
+             msmc_start, msmc_size);
+
+       /* find or create "msmc_sram node */
+       ret = fdt_path_offset(blob, parent_path);
+       if (ret < 0)
+               return ret;
+
+       node = fdt_find_or_add_subnode(blob, ret, node_name);
+       if (node < 0)
+               return node;
+
+       ret = fdt_setprop_string(blob, node, "compatible", "mmio-sram");
+       if (ret < 0)
+               return ret;
+
+       reg[0] = cpu_to_fdt64(msmc_start);
+       reg[1] = cpu_to_fdt64(msmc_size);
+       ret = fdt_setprop(blob, node, "reg", reg, sizeof(reg));
+       if (ret < 0)
+               return ret;
+
+       fdt_setprop_cell(blob, node, "#address-cells", 1);
+       fdt_setprop_cell(blob, node, "#size-cells", 1);
+
+       range[0] = 0;
+       range[1] = cpu_to_fdt32(msmc_start >> 32);
+       range[2] = cpu_to_fdt32(msmc_start & 0xffffffff);
+       range[3] = cpu_to_fdt32(msmc_size);
+       ret = fdt_setprop(blob, node, "ranges", range, sizeof(range));
+       if (ret < 0)
+               return ret;
+
+       subnode = fdt_first_subnode(blob, node);
+       prev_node = 0;
+
+       /* Look for invalid subnodes and delete them */
+       while (subnode >= 0) {
+               sub_reg = fdt_getprop(blob, subnode, "reg", &len);
+               addr = fdt_read_number(sub_reg, 1);
+               sub_reg++;
+               size = fdt_read_number(sub_reg, 1);
+               debug("%s: subnode = %d, addr = 0x%x. size = 0x%x\n", __func__,
+                     subnode, addr, size);
+               if (addr + size > msmc_size ||
+                   !strncmp(fdt_get_name(blob, subnode, &len), "sysfw", 5) ||
+                   !strncmp(fdt_get_name(blob, subnode, &len), "l3cache", 7)) {
+                       fdt_del_node(blob, subnode);
+                       debug("%s: deleting subnode %d\n", __func__, subnode);
+                       if (!prev_node)
+                               subnode = fdt_first_subnode(blob, node);
+                       else
+                               subnode = fdt_next_subnode(blob, prev_node);
+               } else {
+                       prev_node = subnode;
+                       subnode = fdt_next_subnode(blob, prev_node);
+               }
+       }
+
+       return 0;
+}
+#endif
index 6c773ac7b64d621569ddd08ec64561253a874a21..018725b4d128fbafd46df8317ac52c5be333201c 100644 (file)
@@ -11,5 +11,5 @@ void sdelay(unsigned long loops);
 u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr,
                  u32 bound);
 struct ti_sci_handle *get_ti_sci_handle(void);
-
+int fdt_fixup_msmc_ram(void *blob, char *parent_path, char *node_name);
 #endif