From 2a2e3e87706b56fd1b8e787d3a552cfc12725934 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 4 Nov 2022 15:01:02 +0100 Subject: [PATCH] feat(ethos-n): add NPU sleeping SMC call The non-secure world delegation of the register needed to determine if the Arm(R) Ethos(TM)-N NPU is active or sleeping will be removed in the future. In preparation for the change, a new SMC call has been added to allow the non-secure world to ask the SiP service for the state instead. A minor API version bump has been done with this change to indicate support for the new functionality. Signed-off-by: Mikael Olsson Change-Id: I1338341be385cf1891f4809efb7083fae6d928bc --- drivers/arm/ethosn/ethosn_smc.c | 15 +++++++++++++-- include/drivers/arm/ethosn.h | 5 +++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index c95c22ce5..86459585e 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -43,6 +43,7 @@ #define SEC_DEL_ADDR_EXT_VAL U(0x15) #define SEC_SYSCTRL0_REG U(0x0018) +#define SEC_SYSCTRL0_SLEEPING U(1U << 4) #define SEC_SYSCTRL0_SOFT_RESET U(3U << 29) #define SEC_SYSCTRL0_HARD_RESET U(1U << 31) @@ -125,6 +126,15 @@ static int ethosn_is_sec(uintptr_t core_addr) return 1; } +static int ethosn_core_is_sleeping(uintptr_t core_addr) +{ + const uintptr_t sysctrl0_reg = + ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG); + const uint32_t sleeping_mask = SEC_SYSCTRL0_SLEEPING; + + return ((mmio_read_32(sysctrl0_reg) & sleeping_mask) == sleeping_mask); +} + static bool ethosn_reset(uintptr_t core_addr, int hard_reset) { unsigned int timeout; @@ -177,8 +187,7 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, x4 &= 0xFFFFFFFF; } - if (!is_ethosn_fid(smc_fid) || - (fid < ETHOSN_FNUM_VERSION || fid > ETHOSN_FNUM_SOFT_RESET)) { + if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) { WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid); SMC_RET1(handle, SMC_UNK); } @@ -197,6 +206,8 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, switch (fid) { case ETHOSN_FNUM_IS_SEC: SMC_RET1(handle, ethosn_is_sec(core->addr)); + case ETHOSN_FNUM_IS_SLEEPING: + SMC_RET1(handle, ethosn_core_is_sleeping(core->addr)); } if (!device->has_reserved_memory && diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index ce7b2f30f..95244c71f 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -14,7 +14,8 @@ #define ETHOSN_FNUM_IS_SEC U(0x51) #define ETHOSN_FNUM_HARD_RESET U(0x52) #define ETHOSN_FNUM_SOFT_RESET U(0x53) -/* 0x54-0x5F reserved for future use */ +#define ETHOSN_FNUM_IS_SLEEPING U(0x54) +/* 0x55-0x5F reserved for future use */ /* SMC64 function IDs */ #define ETHOSN_FID_64(func_num) U(0xC2000000 | func_num) @@ -39,7 +40,7 @@ /* Service version */ #define ETHOSN_VERSION_MAJOR U(2) -#define ETHOSN_VERSION_MINOR U(1) +#define ETHOSN_VERSION_MINOR U(2) /* Return codes for function calls */ #define ETHOSN_SUCCESS 0