xref: /rk3399_ARM-atf/drivers/arm/ethosn/ethosn_smc.c (revision 76a21174d2a2f1750b13b2680461b6b80a654848)
1*76a21174SMikael Olsson /*
2*76a21174SMikael Olsson  * Copyright (c) 2021, Arm Limited. All rights reserved.
3*76a21174SMikael Olsson  *
4*76a21174SMikael Olsson  * SPDX-License-Identifier: BSD-3-Clause
5*76a21174SMikael Olsson  */
6*76a21174SMikael Olsson 
7*76a21174SMikael Olsson #include <stdint.h>
8*76a21174SMikael Olsson #include <stdbool.h>
9*76a21174SMikael Olsson 
10*76a21174SMikael Olsson #include <common/debug.h>
11*76a21174SMikael Olsson #include <common/runtime_svc.h>
12*76a21174SMikael Olsson #include <drivers/arm/ethosn.h>
13*76a21174SMikael Olsson #include <drivers/delay_timer.h>
14*76a21174SMikael Olsson #include <lib/mmio.h>
15*76a21174SMikael Olsson #include <plat/arm/common/fconf_ethosn_getter.h>
16*76a21174SMikael Olsson 
17*76a21174SMikael Olsson /* Arm Ethos-N NPU (NPU) status */
18*76a21174SMikael Olsson #define ETHOSN_STATUS \
19*76a21174SMikael Olsson 	FCONF_GET_PROPERTY(hw_config, ethosn_config, status)
20*76a21174SMikael Olsson 
21*76a21174SMikael Olsson /* Number of NPU cores available */
22*76a21174SMikael Olsson #define ETHOSN_NUM_CORES \
23*76a21174SMikael Olsson 	FCONF_GET_PROPERTY(hw_config, ethosn_config, num_cores)
24*76a21174SMikael Olsson 
25*76a21174SMikael Olsson /* Address to an NPU core  */
26*76a21174SMikael Olsson #define ETHOSN_CORE_ADDR(core_idx) \
27*76a21174SMikael Olsson 	FCONF_GET_PROPERTY(hw_config, ethosn_core_addr, core_idx)
28*76a21174SMikael Olsson 
29*76a21174SMikael Olsson /* NPU core sec registry address */
30*76a21174SMikael Olsson #define ETHOSN_CORE_SEC_REG(core_addr, reg_offset) \
31*76a21174SMikael Olsson 	(core_addr + reg_offset)
32*76a21174SMikael Olsson 
33*76a21174SMikael Olsson /* Reset timeout in us */
34*76a21174SMikael Olsson #define ETHOSN_RESET_TIMEOUT_US		U(10 * 1000 * 1000)
35*76a21174SMikael Olsson #define ETHOSN_RESET_WAIT_US		U(1)
36*76a21174SMikael Olsson 
37*76a21174SMikael Olsson #define SEC_DEL_REG			U(0x0004)
38*76a21174SMikael Olsson #define SEC_DEL_VAL			U(0x81C)
39*76a21174SMikael Olsson #define SEC_DEL_EXCC_MASK		U(0x20)
40*76a21174SMikael Olsson 
41*76a21174SMikael Olsson #define SEC_SECCTLR_REG			U(0x0010)
42*76a21174SMikael Olsson #define SEC_SECCTLR_VAL			U(0x3)
43*76a21174SMikael Olsson 
44*76a21174SMikael Olsson #define SEC_DEL_MMUSID_REG		U(0x2008)
45*76a21174SMikael Olsson #define SEC_DEL_MMUSID_VAL		U(0x3FFFF)
46*76a21174SMikael Olsson 
47*76a21174SMikael Olsson #define SEC_DEL_ADDR_EXT_REG		U(0x201C)
48*76a21174SMikael Olsson #define SEC_DEL_ADDR_EXT_VAL		U(0x15)
49*76a21174SMikael Olsson 
50*76a21174SMikael Olsson #define SEC_SYSCTRL0_REG		U(0x0018)
51*76a21174SMikael Olsson #define SEC_SYSCTRL0_SOFT_RESET		U(3U << 29)
52*76a21174SMikael Olsson #define SEC_SYSCTRL0_HARD_RESET		U(1U << 31)
53*76a21174SMikael Olsson 
54*76a21174SMikael Olsson static void ethosn_delegate_to_ns(uintptr_t core_addr)
55*76a21174SMikael Olsson {
56*76a21174SMikael Olsson 	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SECCTLR_REG),
57*76a21174SMikael Olsson 			SEC_SECCTLR_VAL);
58*76a21174SMikael Olsson 
59*76a21174SMikael Olsson 	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_DEL_REG),
60*76a21174SMikael Olsson 			SEC_DEL_VAL);
61*76a21174SMikael Olsson 
62*76a21174SMikael Olsson 	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_DEL_MMUSID_REG),
63*76a21174SMikael Olsson 			SEC_DEL_MMUSID_VAL);
64*76a21174SMikael Olsson 
65*76a21174SMikael Olsson 	mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_DEL_ADDR_EXT_REG),
66*76a21174SMikael Olsson 			SEC_DEL_ADDR_EXT_VAL);
67*76a21174SMikael Olsson }
68*76a21174SMikael Olsson 
69*76a21174SMikael Olsson static int ethosn_is_sec(void)
70*76a21174SMikael Olsson {
71*76a21174SMikael Olsson 	if ((mmio_read_32(ETHOSN_CORE_SEC_REG(ETHOSN_CORE_ADDR(0), SEC_DEL_REG))
72*76a21174SMikael Olsson 		& SEC_DEL_EXCC_MASK) != 0U) {
73*76a21174SMikael Olsson 		return 0;
74*76a21174SMikael Olsson 	}
75*76a21174SMikael Olsson 
76*76a21174SMikael Olsson 	return 1;
77*76a21174SMikael Olsson }
78*76a21174SMikael Olsson 
79*76a21174SMikael Olsson static bool ethosn_reset(uintptr_t core_addr, int hard_reset)
80*76a21174SMikael Olsson {
81*76a21174SMikael Olsson 	unsigned int timeout;
82*76a21174SMikael Olsson 	const uintptr_t sysctrl0_reg =
83*76a21174SMikael Olsson 		ETHOSN_CORE_SEC_REG(core_addr, SEC_SYSCTRL0_REG);
84*76a21174SMikael Olsson 	const uint32_t reset_val = (hard_reset != 0) ? SEC_SYSCTRL0_HARD_RESET
85*76a21174SMikael Olsson 						    : SEC_SYSCTRL0_SOFT_RESET;
86*76a21174SMikael Olsson 
87*76a21174SMikael Olsson 	mmio_write_32(sysctrl0_reg, reset_val);
88*76a21174SMikael Olsson 
89*76a21174SMikael Olsson 	/* Wait for reset to complete */
90*76a21174SMikael Olsson 	for (timeout = 0U; timeout < ETHOSN_RESET_TIMEOUT_US;
91*76a21174SMikael Olsson 			   timeout += ETHOSN_RESET_WAIT_US) {
92*76a21174SMikael Olsson 
93*76a21174SMikael Olsson 		if ((mmio_read_32(sysctrl0_reg) & reset_val) == 0U) {
94*76a21174SMikael Olsson 			break;
95*76a21174SMikael Olsson 		}
96*76a21174SMikael Olsson 
97*76a21174SMikael Olsson 		udelay(ETHOSN_RESET_WAIT_US);
98*76a21174SMikael Olsson 	}
99*76a21174SMikael Olsson 
100*76a21174SMikael Olsson 	return timeout < ETHOSN_RESET_TIMEOUT_US;
101*76a21174SMikael Olsson }
102*76a21174SMikael Olsson 
103*76a21174SMikael Olsson uintptr_t ethosn_smc_handler(uint32_t smc_fid,
104*76a21174SMikael Olsson 			     u_register_t core_idx,
105*76a21174SMikael Olsson 			     u_register_t x2,
106*76a21174SMikael Olsson 			     u_register_t x3,
107*76a21174SMikael Olsson 			     u_register_t x4,
108*76a21174SMikael Olsson 			     void *cookie,
109*76a21174SMikael Olsson 			     void *handle,
110*76a21174SMikael Olsson 			     u_register_t flags)
111*76a21174SMikael Olsson {
112*76a21174SMikael Olsson 	uintptr_t core_addr;
113*76a21174SMikael Olsson 	int hard_reset = 0;
114*76a21174SMikael Olsson 
115*76a21174SMikael Olsson 	/* Only SiP fast calls are expected */
116*76a21174SMikael Olsson 	if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) ||
117*76a21174SMikael Olsson 		(GET_SMC_OEN(smc_fid) != OEN_SIP_START)) {
118*76a21174SMikael Olsson 		SMC_RET1(handle, SMC_UNK);
119*76a21174SMikael Olsson 	}
120*76a21174SMikael Olsson 
121*76a21174SMikael Olsson 	/* Truncate parameters to 32-bits for SMC32 */
122*76a21174SMikael Olsson 	if (GET_SMC_CC(smc_fid) == SMC_32) {
123*76a21174SMikael Olsson 		core_idx &= 0xFFFFFFFF;
124*76a21174SMikael Olsson 		x2 &= 0xFFFFFFFF;
125*76a21174SMikael Olsson 		x3 &= 0xFFFFFFFF;
126*76a21174SMikael Olsson 		x4 &= 0xFFFFFFFF;
127*76a21174SMikael Olsson 	}
128*76a21174SMikael Olsson 
129*76a21174SMikael Olsson 	if (!is_ethosn_fid(smc_fid)) {
130*76a21174SMikael Olsson 		SMC_RET1(handle, SMC_UNK);
131*76a21174SMikael Olsson 	}
132*76a21174SMikael Olsson 
133*76a21174SMikael Olsson 	if (ETHOSN_STATUS == ETHOSN_STATUS_DISABLED) {
134*76a21174SMikael Olsson 		WARN("ETHOSN: Arm Ethos-N NPU not available\n");
135*76a21174SMikael Olsson 		SMC_RET1(handle, ETHOSN_NOT_SUPPORTED);
136*76a21174SMikael Olsson 	}
137*76a21174SMikael Olsson 
138*76a21174SMikael Olsson 	switch (smc_fid & FUNCID_NUM_MASK) {
139*76a21174SMikael Olsson 	case ETHOSN_FNUM_VERSION:
140*76a21174SMikael Olsson 		SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR);
141*76a21174SMikael Olsson 	case ETHOSN_FNUM_IS_SEC:
142*76a21174SMikael Olsson 		SMC_RET1(handle, ethosn_is_sec());
143*76a21174SMikael Olsson 	case ETHOSN_FNUM_HARD_RESET:
144*76a21174SMikael Olsson 		hard_reset = 1;
145*76a21174SMikael Olsson 		/* Fallthrough */
146*76a21174SMikael Olsson 	case ETHOSN_FNUM_SOFT_RESET:
147*76a21174SMikael Olsson 		if (core_idx >= ETHOSN_NUM_CORES) {
148*76a21174SMikael Olsson 			WARN("ETHOSN: core index out of range\n");
149*76a21174SMikael Olsson 			SMC_RET1(handle, ETHOSN_CORE_IDX_OUT_OF_RANGE);
150*76a21174SMikael Olsson 		}
151*76a21174SMikael Olsson 
152*76a21174SMikael Olsson 		core_addr = ETHOSN_CORE_ADDR(core_idx);
153*76a21174SMikael Olsson 
154*76a21174SMikael Olsson 		if (!ethosn_reset(core_addr, hard_reset)) {
155*76a21174SMikael Olsson 			SMC_RET1(handle, ETHOSN_FAILURE);
156*76a21174SMikael Olsson 		}
157*76a21174SMikael Olsson 
158*76a21174SMikael Olsson 		ethosn_delegate_to_ns(core_addr);
159*76a21174SMikael Olsson 
160*76a21174SMikael Olsson 		SMC_RET1(handle, ETHOSN_SUCCESS);
161*76a21174SMikael Olsson 	default:
162*76a21174SMikael Olsson 		SMC_RET1(handle, SMC_UNK);
163*76a21174SMikael Olsson 	}
164*76a21174SMikael Olsson }
165