diff mbox series

[U-Boot,3/5] arm: k3: Add support for updating msmc dt node

Message ID 20190308061736.30700-4-lokeshvutla@ti.com
State Accepted
Commit a9a84480f4ccba1eb75c5ca6eb1ff33e8e25fdc4
Delegated to: Tom Rini
Headers show
Series arm: k3: Fixup msmc dt node | expand

Commit Message

Lokesh Vutla March 8, 2019, 6:17 a.m. UTC
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                 | 75 +++++++++++++++++++++++
 arch/arm/mach-k3/include/mach/sys_proto.h |  2 +-
 2 files changed, 76 insertions(+), 1 deletion(-)

Comments

Tom Rini April 12, 2019, 4:31 p.m. UTC | #1
On Fri, Mar 08, 2019 at 11:47:34AM +0530, Lokesh Vutla wrote:

> 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>

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 23cd37c3c7..03f01d07ea 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -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
diff --git a/arch/arm/mach-k3/include/mach/sys_proto.h b/arch/arm/mach-k3/include/mach/sys_proto.h
index 6c773ac7b6..018725b4d1 100644
--- a/arch/arm/mach-k3/include/mach/sys_proto.h
+++ b/arch/arm/mach-k3/include/mach/sys_proto.h
@@ -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