]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(ethos-n): add NPU sleeping SMC call
authorMikael Olsson <mikael.olsson@arm.com>
Fri, 4 Nov 2022 14:01:02 +0000 (15:01 +0100)
committerJoanna Farley <joanna.farley@arm.com>
Tue, 4 Apr 2023 09:35:58 +0000 (11:35 +0200)
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

drivers/arm/ethosn/ethosn_smc.c
include/drivers/arm/ethosn.h

index c95c22ce586410ac7f40d1d0e2fbba49bcd41887..86459585eafec97ab35f284f4690e6ad321b97aa 100644 (file)
@@ -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 &&
index ce7b2f30f6150c5b9aa0339d07a5d39cba4861c8..95244c71fb53948e35f0f06230d80b064cb66b4e 100644 (file)
@@ -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