feat(ethos-n): add support to set up NSAID

For the TZC to allow the Arm(R) Ethos(TM)-N NPU to access the buffers
allocated in a protected memory region, it must include the correct
NSAID for that region in its transactions to the memory.  This change
updates the SiP service to configure the NSAIDs specified by a platform
define. When doing a protected access the SiP service now configures the
NSAIDs specified by the platform define. For unprotected access the
NSAID is set to zero.

Signed-off-by: Rajasekaran Kalidoss <rajasekaran.kalidoss@arm.com>
Signed-off-by: Rob Hughes <robert.hughes@arm.com>
Signed-off-by: Mikael Olsson <mikael.olsson@arm.com>
Change-Id: I3360ef33705162aba5c67670386922420869e331
diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c
index 8645958..7604b8b 100644
--- a/drivers/arm/ethosn/ethosn_smc.c
+++ b/drivers/arm/ethosn/ethosn_smc.c
@@ -15,6 +15,8 @@
 #include <lib/utils_def.h>
 #include <plat/arm/common/fconf_ethosn_getter.h>
 
+#include <platform_def.h>
+
 /*
  * Number of Arm(R) Ethos(TM)-N NPU (NPU) devices available
  */
@@ -47,9 +49,16 @@
 #define SEC_SYSCTRL0_SOFT_RESET		U(3U << 29)
 #define SEC_SYSCTRL0_HARD_RESET		U(1U << 31)
 
+#define SEC_NSAID_REG_BASE		U(0x3004)
+#define SEC_NSAID_OFFSET		U(0x1000)
+
 #define SEC_MMUSID_REG_BASE		U(0x3008)
 #define SEC_MMUSID_OFFSET		U(0x1000)
 
+#define INPUT_STREAM_INDEX              U(0x6)
+#define INTERMEDIATE_STREAM_INDEX       U(0x7)
+#define OUTPUT_STREAM_INDEX             U(0x8)
+
 static bool ethosn_get_device_and_core(uintptr_t core_addr,
 				       const struct ethosn_device_t **dev_match,
 				       const struct ethosn_core_t **core_match)
@@ -75,6 +84,29 @@
 	return false;
 }
 
+#if ARM_ETHOSN_NPU_TZMP1
+static void ethosn_configure_stream_nsaid(const struct ethosn_core_t *core,
+					  bool is_protected)
+{
+	size_t i;
+	uint32_t streams[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+	if (is_protected) {
+		streams[INPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_DATA_NSAID;
+		streams[INTERMEDIATE_STREAM_INDEX] =
+			ARM_ETHOSN_NPU_PROT_DATA_NSAID;
+		streams[OUTPUT_STREAM_INDEX] = ARM_ETHOSN_NPU_PROT_DATA_NSAID;
+	}
+
+	for (i = 0U; i < ARRAY_SIZE(streams); ++i) {
+		const uintptr_t reg_addr = SEC_NSAID_REG_BASE +
+			(SEC_NSAID_OFFSET * i);
+		mmio_write_32(ETHOSN_CORE_SEC_REG(core->addr, reg_addr),
+			      streams[i]);
+	}
+}
+#endif
+
 static void ethosn_configure_smmu_streams(const struct ethosn_device_t *device,
 					  const struct ethosn_core_t *core,
 					  uint32_t asset_alloc_idx)
@@ -163,7 +195,7 @@
 			     u_register_t core_addr,
 			     u_register_t asset_alloc_idx,
 			     u_register_t reset_type,
-			     u_register_t x4,
+			     u_register_t is_protected,
 			     void *cookie,
 			     void *handle,
 			     u_register_t flags)
@@ -184,7 +216,7 @@
 		core_addr &= 0xFFFFFFFF;
 		asset_alloc_idx &= 0xFFFFFFFF;
 		reset_type &= 0xFFFFFFFF;
-		x4 &= 0xFFFFFFFF;
+		is_protected &= 0xFFFFFFFF;
 	}
 
 	if (!is_ethosn_fid(smc_fid) || (fid > ETHOSN_FNUM_IS_SLEEPING)) {
@@ -238,6 +270,11 @@
 			if (!device->has_reserved_memory) {
 				ethosn_configure_smmu_streams(device, core,
 							asset_alloc_idx);
+
+				#if ARM_ETHOSN_NPU_TZMP1
+				ethosn_configure_stream_nsaid(core,
+							      is_protected);
+				#endif
 			}
 
 			ethosn_delegate_to_ns(core->addr);