summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMikael Olsson <mikael.olsson@arm.com>2023-01-27 18:53:48 +0100
committerJoanna Farley <joanna.farley@arm.com>2023-04-04 11:37:25 +0200
commite9812ddca6e72c0501ef1e84753f335dcafb74cd (patch)
treeed017dee7ca913a5954d2ab22b4367ffa43f7907 /drivers
parent18a6b79c50ca88510c013fc5fba5200473152088 (diff)
downloadarm-trusted-firmware-e9812ddca6e72c0501ef1e84753f335dcafb74cd.tar.gz
feat(ethos-n): add SMC call to get FW properties
When the Arm(R) Ethos(TM)-N NPU firmware is loaded by BL2 into protected memory, the Linux kernel NPU driver cannot access the firmware. To still allow the kernel driver to access some information about the firmware, SMC calls have been added so it can check compatibility and get the necessary information to map the firmware into the SMMU for the NPU. The API version has been given a minor version bump with this change to indicate the added functionality. Signed-off-by: Mikael Olsson <mikael.olsson@arm.com> Change-Id: Idb076b7bcf54ed7e8eb39be80114dc1d1c45336d
Diffstat (limited to 'drivers')
-rw-r--r--drivers/arm/ethosn/ethosn_smc.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c
index 124de9243..b5cb0408f 100644
--- a/drivers/arm/ethosn/ethosn_smc.c
+++ b/drivers/arm/ethosn/ethosn_smc.c
@@ -34,6 +34,10 @@
#define ETHOSN_CORE_SEC_REG(core_addr, reg_offset) \
(core_addr + reg_offset)
+#define ETHOSN_FW_VA_BASE 0x20000000UL
+#define ETHOSN_WORKING_DATA_VA_BASE 0x40000000UL
+#define ETHOSN_COMMAND_STREAM_VA_BASE 0x60000000UL
+
/* Reset timeout in us */
#define ETHOSN_RESET_TIMEOUT_US U(10 * 1000 * 1000)
#define ETHOSN_RESET_WAIT_US U(1)
@@ -304,6 +308,38 @@ static uintptr_t ethosn_smc_core_handler(uint32_t fid,
}
}
+static uintptr_t ethosn_smc_fw_prop_handler(u_register_t fw_property,
+ void *handle)
+{
+#if ARM_ETHOSN_NPU_TZMP1
+ switch (fw_property) {
+ case ETHOSN_FW_PROP_VERSION:
+ SMC_RET4(handle, ETHOSN_SUCCESS,
+ big_fw->fw_ver_major,
+ big_fw->fw_ver_minor,
+ big_fw->fw_ver_patch);
+ case ETHOSN_FW_PROP_MEM_INFO:
+ SMC_RET3(handle, ETHOSN_SUCCESS,
+ ((void *)big_fw) + big_fw->offset,
+ big_fw->size);
+ case ETHOSN_FW_PROP_OFFSETS:
+ SMC_RET3(handle, ETHOSN_SUCCESS,
+ big_fw->ple_offset,
+ big_fw->unpriv_stack_offset);
+ case ETHOSN_FW_PROP_VA_MAP:
+ SMC_RET4(handle, ETHOSN_SUCCESS,
+ ETHOSN_FW_VA_BASE,
+ ETHOSN_WORKING_DATA_VA_BASE,
+ ETHOSN_COMMAND_STREAM_VA_BASE);
+ default:
+ WARN("ETHOSN: Unknown firmware property\n");
+ SMC_RET1(handle, ETHOSN_INVALID_PARAMETER);
+ }
+#else
+ SMC_RET1(handle, ETHOSN_NOT_SUPPORTED);
+#endif
+}
+
uintptr_t ethosn_smc_handler(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
@@ -329,13 +365,16 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid,
x4 &= 0xFFFFFFFF;
}
- if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) {
+ if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_GET_FW_PROP)) {
WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
}
- if (fid == ETHOSN_FNUM_VERSION) {
+ switch (fid) {
+ case ETHOSN_FNUM_VERSION:
SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR);
+ case ETHOSN_FNUM_GET_FW_PROP:
+ return ethosn_smc_fw_prop_handler(x1, handle);
}
return ethosn_smc_core_handler(fid, x1, x2, x3, x4, handle);