arm: K3: Disable ROM configured firewalls

ROM configures certain firewalls based on its usage, which includes
the one in front of boot peripherals. In specific case of boot
peripherals, ROM does not open up the full address space corresponding
to the peripherals. Like in OSPI, ROM only configures the firewall region
for 32 bit address space and mark 64bit address space flash regions
as in-accessible.

When security-cfg is initialized by sysfw, all the non-configured
firewalls are kept in bypass state using a global setting. Since ROM
configured firewalls for certain peripherals, these will not be touched.
So when bootloader touches any of the address space that ROM marked as
in-accessible, system raises a firewall exception causing boot hang.

It would have been ideal if sysfw cleans up the ROM configured boot
peripheral firewalls. Given the memory overhead to store this
information provided by ROM and the boot time increase in re configuring
the firewalls, it is concluded to clean this up in bootloaders.

So disable all the firewalls that ROM doesn't open up the full address
space.

Signed-off-by: Andrew F. Davis <afd@ti.com>
Signed-off-by: Venkateswara Rao Mandela <venkat.mandela@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index e8b7d70..8d15290 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -269,3 +269,33 @@
 	asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr));
 }
 #endif
+
+void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size)
+{
+	struct ti_sci_msg_fwl_region region;
+	struct ti_sci_fwl_ops *fwl_ops;
+	struct ti_sci_handle *ti_sci;
+	size_t i, j;
+
+	ti_sci = get_ti_sci_handle();
+	fwl_ops = &ti_sci->ops.fwl_ops;
+	for (i = 0; i < fwl_data_size; i++) {
+		for (j = 0; j <  fwl_data[i].regions; j++) {
+			region.fwl_id = fwl_data[i].fwl_id;
+			region.region = j;
+			region.n_permission_regs = 3;
+
+			fwl_ops->get_fwl_region(ti_sci, &region);
+
+			if (region.control != 0) {
+				pr_debug("Attempting to disable firewall %5d (%25s)\n",
+					 region.fwl_id, fwl_data[i].name);
+				region.control = 0;
+
+				if (fwl_ops->set_fwl_region(ti_sci, &region))
+					pr_err("Could not disable firewall %5d (%25s)\n",
+					       region.fwl_id, fwl_data[i].name);
+			}
+		}
+	}
+}