summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Olsson <mikael.olsson@arm.com>2023-02-10 11:36:19 +0100
committerJoanna Farley <joanna.farley@arm.com>2023-04-04 11:37:32 +0200
commit7820777fa3c8ca454ab40d5d8a8ba0e311bbb6f9 (patch)
treebcc4416f8fc1b1ad5cf70bd9e909df733d6fbce4
parente9812ddca6e72c0501ef1e84753f335dcafb74cd (diff)
downloadarm-trusted-firmware-7820777fa3c8ca454ab40d5d8a8ba0e311bbb6f9.tar.gz
feat(ethos-n): add event and aux control support
The SiP service for the Arm(R) Ethos(TM)-N NPU driver will now handle setting up the NPU's event and aux control registers during the SMC reset call. The aux control register will no longer be accessible by the non-secure world. The API version has been given a minor bump with this change to indicate the added functionality. Signed-off-by: Mikael Olsson <mikael.olsson@arm.com> Change-Id: I5b099e25978aa4089c384eb17c5060c5b4eaf373
-rw-r--r--drivers/arm/ethosn/ethosn_big_fw.c2
-rw-r--r--drivers/arm/ethosn/ethosn_smc.c61
-rw-r--r--include/drivers/arm/ethosn.h3
3 files changed, 60 insertions, 6 deletions
diff --git a/drivers/arm/ethosn/ethosn_big_fw.c b/drivers/arm/ethosn/ethosn_big_fw.c
index 9bb33eac8..3a53e0e60 100644
--- a/drivers/arm/ethosn/ethosn_big_fw.c
+++ b/drivers/arm/ethosn/ethosn_big_fw.c
@@ -12,7 +12,7 @@
#define ETHOSN_BIG_FW_MAGIC ('E' | ('N' << 8) | ('F' << 16) | ('W' << 24))
/* Supported big firmware version */
-#define ETHOSN_BIG_FW_VERSION_MAJOR 9
+#define ETHOSN_BIG_FW_VERSION_MAJOR 10
#define ETHOSN_ARCH_VER_MAJOR_MASK U(0xF000)
#define ETHOSN_ARCH_VER_MAJOR_SHIFT U(0xC)
diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c
index b5cb0408f..4a71e81b9 100644
--- a/drivers/arm/ethosn/ethosn_smc.c
+++ b/drivers/arm/ethosn/ethosn_smc.c
@@ -42,8 +42,16 @@
#define ETHOSN_RESET_TIMEOUT_US U(10 * 1000 * 1000)
#define ETHOSN_RESET_WAIT_US U(1)
+#define ETHOSN_AUX_FEAT_LEVEL_IRQ U(0x1)
+#define ETHOSN_AUX_FEAT_STASHING U(0x2)
+
+#define SEC_AUXCTLR_REG U(0x0024)
+#define SEC_AUXCTLR_VAL U(0x80)
+#define SEC_AUXCTLR_LEVEL_IRQ_VAL U(0x04)
+#define SEC_AUXCTLR_STASHING_VAL U(0xA5000000)
+
#define SEC_DEL_REG U(0x0004)
-#define SEC_DEL_VAL U(0x81C)
+#define SEC_DEL_VAL U(0x80C)
#define SEC_DEL_EXCC_MASK U(0x20)
#define SEC_SECCTLR_REG U(0x0010)
@@ -58,6 +66,9 @@
#define SEC_SYSCTRL0_SOFT_RESET U(3U << 29)
#define SEC_SYSCTRL0_HARD_RESET U(1U << 31)
+#define SEC_SYSCTRL1_REG U(0x001C)
+#define SEC_SYSCTRL1_VAL U(0x180110)
+
#define SEC_NSAID_REG_BASE U(0x3004)
#define SEC_NSAID_OFFSET U(0x1000)
@@ -132,6 +143,35 @@ static void ethosn_configure_stream_nsaid(const struct ethosn_core_t *core,
}
#endif
+static void ethosn_configure_events(uintptr_t core_addr)
+{
+ mmio_write_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL1_REG), SEC_SYSCTRL1_VAL);
+}
+
+static bool ethosn_configure_aux_features(const struct ethosn_device_t *device,
+ uintptr_t core_addr,
+ uint32_t features)
+{
+ uint32_t val = SEC_AUXCTLR_VAL;
+
+ if (features & ETHOSN_AUX_FEAT_LEVEL_IRQ) {
+ val |= SEC_AUXCTLR_LEVEL_IRQ_VAL;
+ }
+
+ if (features & ETHOSN_AUX_FEAT_STASHING) {
+ /* Stashing can't be used with reserved memory */
+ if (device->has_reserved_memory) {
+ return false;
+ }
+
+ val |= SEC_AUXCTLR_STASHING_VAL;
+ }
+
+ mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_AUXCTLR_REG), val);
+
+ return true;
+}
+
static void ethosn_configure_smmu_streams(const struct ethosn_device_t *device,
const struct ethosn_core_t *core,
uint32_t asset_alloc_idx)
@@ -220,7 +260,8 @@ static int ethosn_core_full_reset(const struct ethosn_device_t *device,
const struct ethosn_core_t *core,
bool hard_reset,
u_register_t asset_alloc_idx,
- u_register_t is_protected)
+ u_register_t is_protected,
+ u_register_t aux_features)
{
if (!device->has_reserved_memory &&
asset_alloc_idx >= device->num_allocators) {
@@ -232,6 +273,12 @@ static int ethosn_core_full_reset(const struct ethosn_device_t *device,
return ETHOSN_FAILURE;
}
+ if (!ethosn_configure_aux_features(device, core->addr, aux_features)) {
+ return ETHOSN_INVALID_CONFIGURATION;
+ }
+
+ ethosn_configure_events(core->addr);
+
if (!device->has_reserved_memory) {
ethosn_configure_smmu_streams(device, core, asset_alloc_idx);
@@ -251,6 +298,7 @@ static uintptr_t ethosn_smc_core_reset_handler(const struct ethosn_device_t *dev
u_register_t asset_alloc_idx,
u_register_t reset_type,
u_register_t is_protected,
+ u_register_t aux_features,
void *handle)
{
int ret;
@@ -258,7 +306,8 @@ static uintptr_t ethosn_smc_core_reset_handler(const struct ethosn_device_t *dev
switch (reset_type) {
case ETHOSN_RESET_TYPE_FULL:
ret = ethosn_core_full_reset(device, core, hard_reset,
- asset_alloc_idx, is_protected);
+ asset_alloc_idx, is_protected,
+ aux_features);
break;
case ETHOSN_RESET_TYPE_HALT:
ret = ethosn_core_reset(core->addr, hard_reset) ? ETHOSN_SUCCESS : ETHOSN_FAILURE;
@@ -277,6 +326,7 @@ static uintptr_t ethosn_smc_core_handler(uint32_t fid,
u_register_t asset_alloc_idx,
u_register_t reset_type,
u_register_t is_protected,
+ u_register_t aux_features,
void *handle)
{
bool hard_reset = false;
@@ -301,6 +351,7 @@ static uintptr_t ethosn_smc_core_handler(uint32_t fid,
asset_alloc_idx,
reset_type,
is_protected,
+ aux_features,
handle);
default:
WARN("ETHOSN: Unimplemented SMC call: 0x%x\n", fid);
@@ -377,7 +428,9 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid,
return ethosn_smc_fw_prop_handler(x1, handle);
}
- return ethosn_smc_core_handler(fid, x1, x2, x3, x4, handle);
+ return ethosn_smc_core_handler(fid, x1, x2, x3, x4,
+ SMC_GET_GP(handle, CTX_GPREG_X5),
+ handle);
}
int ethosn_smc_setup(void)
diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h
index cfdad8ec4..c8e2df07c 100644
--- a/include/drivers/arm/ethosn.h
+++ b/include/drivers/arm/ethosn.h
@@ -47,7 +47,7 @@
/* Service version */
#define ETHOSN_VERSION_MAJOR U(2)
-#define ETHOSN_VERSION_MINOR U(4)
+#define ETHOSN_VERSION_MINOR U(5)
/* Return codes for function calls */
#define ETHOSN_SUCCESS 0
@@ -57,6 +57,7 @@
#define ETHOSN_FAILURE -4
#define ETHOSN_UNKNOWN_CORE_ADDRESS -5
#define ETHOSN_UNKNOWN_ALLOCATOR_IDX -6
+#define ETHOSN_INVALID_CONFIGURATION -7
/*
* Argument types for soft and hard resets to indicate whether to reset