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 23cd37c..03f01d0 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 6c773ac..018725b 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