diff options
author | Bryan Brattlof <bb@ti.com> | 2025-04-14 15:20:02 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-04-24 10:45:37 -0600 |
commit | f393beedba7917ef8aaaedd67d143cd7b7440ae2 (patch) | |
tree | 5e46d8c01f119cfd9aebaf7675cce8158c761215 | |
parent | 739ad58dbee874a3ad3bddd116e995212a254e07 (diff) |
arm: mach-k3: support disabling a single firewall region
During boot some firewall regions could contain the R5's code which if
we change the firewalls settings will crash the core. To get around this
issue, define a new function which allows us to specify specific regions
we want unlocked.
Signed-off-by: Bryan Brattlof <bb@ti.com>
-rw-r--r-- | arch/arm/mach-k3/common.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-k3/r5/common.c | 25 |
2 files changed, 26 insertions, 0 deletions
diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h index 7bd72da1de8..2ec60c7879a 100644 --- a/arch/arm/mach-k3/common.h +++ b/arch/arm/mach-k3/common.h @@ -35,6 +35,7 @@ enum k3_device_type { void setup_k3_mpu_regions(void); int early_console_init(void); void disable_linefill_optimization(void); +int remove_fwl_region(struct fwl_data *fwl); void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size); int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr); void k3_sysfw_print_ver(void); diff --git a/arch/arm/mach-k3/r5/common.c b/arch/arm/mach-k3/r5/common.c index 0f6c294f1eb..0d97e7f5537 100644 --- a/arch/arm/mach-k3/r5/common.c +++ b/arch/arm/mach-k3/r5/common.c @@ -253,6 +253,31 @@ void disable_linefill_optimization(void) asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr)); } +int remove_fwl_region(struct fwl_data *fwl) +{ + struct ti_sci_handle *sci = get_ti_sci_handle(); + struct ti_sci_fwl_ops *ops = &sci->ops.fwl_ops; + struct ti_sci_msg_fwl_region region; + int ret; + + region.fwl_id = fwl->fwl_id; + region.region = fwl->regions; + region.n_permission_regs = 3; + + ops->get_fwl_region(sci, ®ion); + + /* zero out the enable field of the firewall */ + region.control = region.control & ~0xF; + + pr_debug("Disabling firewall id: %d region: %d\n", + region.fwl_id, region.region); + + ret = ops->set_fwl_region(sci, ®ion); + if (ret) + pr_err("Could not disable firewall\n"); + return ret; +} + static void remove_fwl_regions(struct fwl_data fwl_data, size_t num_regions, enum k3_firewall_region_type fwl_type) { |