Browse Source

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 <mikael.olsson@arm.com>
Change-Id: I1338341be385cf1891f4809efb7083fae6d928bc
pull/1996/head
Mikael Olsson 2 years ago
committed by Joanna Farley
parent
commit
2a2e3e8770
  1. 15
      drivers/arm/ethosn/ethosn_smc.c
  2. 5
      include/drivers/arm/ethosn.h

15
drivers/arm/ethosn/ethosn_smc.c

@ -43,6 +43,7 @@
#define SEC_DEL_ADDR_EXT_VAL U(0x15) #define SEC_DEL_ADDR_EXT_VAL U(0x15)
#define SEC_SYSCTRL0_REG U(0x0018) #define SEC_SYSCTRL0_REG U(0x0018)
#define SEC_SYSCTRL0_SLEEPING U(1U << 4)
#define SEC_SYSCTRL0_SOFT_RESET U(3U << 29) #define SEC_SYSCTRL0_SOFT_RESET U(3U << 29)
#define SEC_SYSCTRL0_HARD_RESET U(1U << 31) #define SEC_SYSCTRL0_HARD_RESET U(1U << 31)
@ -125,6 +126,15 @@ static int ethosn_is_sec(uintptr_t core_addr)
return 1; 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) static bool ethosn_reset(uintptr_t core_addr, int hard_reset)
{ {
unsigned int timeout; unsigned int timeout;
@ -177,8 +187,7 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid,
x4 &= 0xFFFFFFFF; x4 &= 0xFFFFFFFF;
} }
if (!is_ethosn_fid(smc_fid) || if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) {
(fid < ETHOSN_FNUM_VERSION || fid > ETHOSN_FNUM_SOFT_RESET)) {
WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid); WARN("ETHOSN: Unknown SMC call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK); SMC_RET1(handle, SMC_UNK);
} }
@ -197,6 +206,8 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid,
switch (fid) { switch (fid) {
case ETHOSN_FNUM_IS_SEC: case ETHOSN_FNUM_IS_SEC:
SMC_RET1(handle, ethosn_is_sec(core->addr)); 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 && if (!device->has_reserved_memory &&

5
include/drivers/arm/ethosn.h

@ -14,7 +14,8 @@
#define ETHOSN_FNUM_IS_SEC U(0x51) #define ETHOSN_FNUM_IS_SEC U(0x51)
#define ETHOSN_FNUM_HARD_RESET U(0x52) #define ETHOSN_FNUM_HARD_RESET U(0x52)
#define ETHOSN_FNUM_SOFT_RESET U(0x53) #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 */ /* SMC64 function IDs */
#define ETHOSN_FID_64(func_num) U(0xC2000000 | func_num) #define ETHOSN_FID_64(func_num) U(0xC2000000 | func_num)
@ -39,7 +40,7 @@
/* Service version */ /* Service version */
#define ETHOSN_VERSION_MAJOR U(2) #define ETHOSN_VERSION_MAJOR U(2)
#define ETHOSN_VERSION_MINOR U(1) #define ETHOSN_VERSION_MINOR U(2)
/* Return codes for function calls */ /* Return codes for function calls */
#define ETHOSN_SUCCESS 0 #define ETHOSN_SUCCESS 0

Loading…
Cancel
Save