xref: /arm-trusted-firmware/plat/st/stm32mp1/stm32mp1_scmi.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu #include <assert.h>
7*91f16700Schasinglulu #include <stdint.h>
8*91f16700Schasinglulu 
9*91f16700Schasinglulu #include <platform_def.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include <drivers/clk.h>
12*91f16700Schasinglulu #include <drivers/scmi-msg.h>
13*91f16700Schasinglulu #include <drivers/scmi.h>
14*91f16700Schasinglulu #include <drivers/st/stm32mp1_clk.h>
15*91f16700Schasinglulu #include <drivers/st/stm32mp_reset.h>
16*91f16700Schasinglulu #include <dt-bindings/clock/stm32mp1-clks.h>
17*91f16700Schasinglulu #include <dt-bindings/reset/stm32mp1-resets.h>
18*91f16700Schasinglulu 
19*91f16700Schasinglulu #define TIMEOUT_US_1MS		1000U
20*91f16700Schasinglulu 
21*91f16700Schasinglulu #define SCMI_CLOCK_NAME_SIZE	16U
22*91f16700Schasinglulu #define SCMI_RSTD_NAME_SIZE	16U
23*91f16700Schasinglulu 
24*91f16700Schasinglulu /*
25*91f16700Schasinglulu  * struct stm32_scmi_clk - Data for the exposed clock
26*91f16700Schasinglulu  * @clock_id: Clock identifier in RCC clock driver
27*91f16700Schasinglulu  * @name: Clock string ID exposed to agent
28*91f16700Schasinglulu  * @enabled: State of the SCMI clock
29*91f16700Schasinglulu  */
30*91f16700Schasinglulu struct stm32_scmi_clk {
31*91f16700Schasinglulu 	unsigned long clock_id;
32*91f16700Schasinglulu 	const char *name;
33*91f16700Schasinglulu 	bool enabled;
34*91f16700Schasinglulu };
35*91f16700Schasinglulu 
36*91f16700Schasinglulu /*
37*91f16700Schasinglulu  * struct stm32_scmi_rstd - Data for the exposed reset controller
38*91f16700Schasinglulu  * @reset_id: Reset identifier in RCC reset driver
39*91f16700Schasinglulu  * @name: Reset string ID exposed to agent
40*91f16700Schasinglulu  */
41*91f16700Schasinglulu struct stm32_scmi_rstd {
42*91f16700Schasinglulu 	unsigned long reset_id;
43*91f16700Schasinglulu 	const char *name;
44*91f16700Schasinglulu };
45*91f16700Schasinglulu 
46*91f16700Schasinglulu /* Locate all non-secure SMT message buffers in last page of SYSRAM */
47*91f16700Schasinglulu #define SMT_BUFFER_BASE		STM32MP_SCMI_NS_SHM_BASE
48*91f16700Schasinglulu #define SMT_BUFFER0_BASE	SMT_BUFFER_BASE
49*91f16700Schasinglulu #define SMT_BUFFER1_BASE	(SMT_BUFFER_BASE + 0x200)
50*91f16700Schasinglulu 
51*91f16700Schasinglulu CASSERT((STM32MP_SCMI_NS_SHM_BASE + STM32MP_SCMI_NS_SHM_SIZE) >=
52*91f16700Schasinglulu 	(SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE),
53*91f16700Schasinglulu 	assert_scmi_non_secure_shm_fits_scmi_overall_buffer_size);
54*91f16700Schasinglulu 
55*91f16700Schasinglulu static struct scmi_msg_channel scmi_channel[] = {
56*91f16700Schasinglulu 	[0] = {
57*91f16700Schasinglulu 		.shm_addr = SMT_BUFFER0_BASE,
58*91f16700Schasinglulu 		.shm_size = SMT_BUF_SLOT_SIZE,
59*91f16700Schasinglulu 	},
60*91f16700Schasinglulu 	[1] = {
61*91f16700Schasinglulu 		.shm_addr = SMT_BUFFER1_BASE,
62*91f16700Schasinglulu 		.shm_size = SMT_BUF_SLOT_SIZE,
63*91f16700Schasinglulu 	},
64*91f16700Schasinglulu };
65*91f16700Schasinglulu 
66*91f16700Schasinglulu struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
67*91f16700Schasinglulu {
68*91f16700Schasinglulu 	assert(agent_id < ARRAY_SIZE(scmi_channel));
69*91f16700Schasinglulu 
70*91f16700Schasinglulu 	return &scmi_channel[agent_id];
71*91f16700Schasinglulu }
72*91f16700Schasinglulu 
73*91f16700Schasinglulu #define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled) \
74*91f16700Schasinglulu 	[_scmi_id] = { \
75*91f16700Schasinglulu 		.clock_id = _id, \
76*91f16700Schasinglulu 		.name = _name, \
77*91f16700Schasinglulu 		.enabled = _init_enabled, \
78*91f16700Schasinglulu 	}
79*91f16700Schasinglulu 
80*91f16700Schasinglulu static struct stm32_scmi_clk stm32_scmi0_clock[] = {
81*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_HSE, CK_HSE, "ck_hse", true),
82*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_HSI, CK_HSI, "ck_hsi", true),
83*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_CSI, CK_CSI, "ck_csi", true),
84*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_LSE, CK_LSE, "ck_lse", true),
85*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_LSI, CK_LSI, "ck_lsi", true),
86*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_PLL2_Q, PLL2_Q, "pll2_q", true),
87*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_PLL2_R, PLL2_R, "pll2_r", true),
88*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_MPU, CK_MPU, "ck_mpu", true),
89*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_AXI, CK_AXI, "ck_axi", true),
90*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_BSEC, BSEC, "bsec", true),
91*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_CRYP1, CRYP1, "cryp1", false),
92*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_GPIOZ, GPIOZ, "gpioz", false),
93*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_HASH1, HASH1, "hash1", false),
94*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_I2C4, I2C4_K, "i2c4_k", false),
95*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_I2C6, I2C6_K, "i2c6_k", false),
96*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_IWDG1, IWDG1, "iwdg1", false),
97*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_RNG1, RNG1_K, "rng1_k", true),
98*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_RTC, RTC, "ck_rtc", true),
99*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_RTCAPB, RTCAPB, "rtcapb", true),
100*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_SPI6, SPI6_K, "spi6_k", false),
101*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI0_USART1, USART1_K, "usart1_k", false),
102*91f16700Schasinglulu };
103*91f16700Schasinglulu 
104*91f16700Schasinglulu static struct stm32_scmi_clk stm32_scmi1_clock[] = {
105*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI1_PLL3_Q, PLL3_Q, "pll3_q", true),
106*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI1_PLL3_R, PLL3_R, "pll3_r", true),
107*91f16700Schasinglulu 	CLOCK_CELL(CK_SCMI1_MCU, CK_MCU, "ck_mcu", false),
108*91f16700Schasinglulu };
109*91f16700Schasinglulu 
110*91f16700Schasinglulu #define RESET_CELL(_scmi_id, _id, _name) \
111*91f16700Schasinglulu 	[_scmi_id] = { \
112*91f16700Schasinglulu 		.reset_id = _id, \
113*91f16700Schasinglulu 		.name = _name, \
114*91f16700Schasinglulu 	}
115*91f16700Schasinglulu 
116*91f16700Schasinglulu static struct stm32_scmi_rstd stm32_scmi0_reset_domain[] = {
117*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_SPI6, SPI6_R, "spi6"),
118*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_I2C4, I2C4_R, "i2c4"),
119*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_I2C6, I2C6_R, "i2c6"),
120*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_USART1, USART1_R, "usart1"),
121*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_STGEN, STGEN_R, "stgen"),
122*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_GPIOZ, GPIOZ_R, "gpioz"),
123*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_CRYP1, CRYP1_R, "cryp1"),
124*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_HASH1, HASH1_R, "hash1"),
125*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"),
126*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"),
127*91f16700Schasinglulu 	RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"),
128*91f16700Schasinglulu };
129*91f16700Schasinglulu 
130*91f16700Schasinglulu struct scmi_agent_resources {
131*91f16700Schasinglulu 	struct stm32_scmi_clk *clock;
132*91f16700Schasinglulu 	size_t clock_count;
133*91f16700Schasinglulu 	struct stm32_scmi_rstd *rstd;
134*91f16700Schasinglulu 	size_t rstd_count;
135*91f16700Schasinglulu };
136*91f16700Schasinglulu 
137*91f16700Schasinglulu static const struct scmi_agent_resources agent_resources[] = {
138*91f16700Schasinglulu 	[0] = {
139*91f16700Schasinglulu 		.clock = stm32_scmi0_clock,
140*91f16700Schasinglulu 		.clock_count = ARRAY_SIZE(stm32_scmi0_clock),
141*91f16700Schasinglulu 		.rstd = stm32_scmi0_reset_domain,
142*91f16700Schasinglulu 		.rstd_count = ARRAY_SIZE(stm32_scmi0_reset_domain),
143*91f16700Schasinglulu 	},
144*91f16700Schasinglulu 	[1] = {
145*91f16700Schasinglulu 		.clock = stm32_scmi1_clock,
146*91f16700Schasinglulu 		.clock_count = ARRAY_SIZE(stm32_scmi1_clock),
147*91f16700Schasinglulu 	},
148*91f16700Schasinglulu };
149*91f16700Schasinglulu 
150*91f16700Schasinglulu static const struct scmi_agent_resources *find_resource(unsigned int agent_id)
151*91f16700Schasinglulu {
152*91f16700Schasinglulu 	assert(agent_id < ARRAY_SIZE(agent_resources));
153*91f16700Schasinglulu 
154*91f16700Schasinglulu 	return &agent_resources[agent_id];
155*91f16700Schasinglulu }
156*91f16700Schasinglulu 
157*91f16700Schasinglulu #if ENABLE_ASSERTIONS
158*91f16700Schasinglulu static size_t plat_scmi_protocol_count_paranoid(void)
159*91f16700Schasinglulu {
160*91f16700Schasinglulu 	unsigned int n = 0U;
161*91f16700Schasinglulu 	unsigned int count = 0U;
162*91f16700Schasinglulu 
163*91f16700Schasinglulu 	for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) {
164*91f16700Schasinglulu 		if (agent_resources[n].clock_count) {
165*91f16700Schasinglulu 			count++;
166*91f16700Schasinglulu 			break;
167*91f16700Schasinglulu 		}
168*91f16700Schasinglulu 	}
169*91f16700Schasinglulu 
170*91f16700Schasinglulu 	for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) {
171*91f16700Schasinglulu 		if (agent_resources[n].rstd_count) {
172*91f16700Schasinglulu 			count++;
173*91f16700Schasinglulu 			break;
174*91f16700Schasinglulu 		}
175*91f16700Schasinglulu 	}
176*91f16700Schasinglulu 
177*91f16700Schasinglulu 	return count;
178*91f16700Schasinglulu }
179*91f16700Schasinglulu #endif
180*91f16700Schasinglulu 
181*91f16700Schasinglulu static const char vendor[] = "ST";
182*91f16700Schasinglulu static const char sub_vendor[] = "";
183*91f16700Schasinglulu 
184*91f16700Schasinglulu const char *plat_scmi_vendor_name(void)
185*91f16700Schasinglulu {
186*91f16700Schasinglulu 	return vendor;
187*91f16700Schasinglulu }
188*91f16700Schasinglulu 
189*91f16700Schasinglulu const char *plat_scmi_sub_vendor_name(void)
190*91f16700Schasinglulu {
191*91f16700Schasinglulu 	return sub_vendor;
192*91f16700Schasinglulu }
193*91f16700Schasinglulu 
194*91f16700Schasinglulu /* Currently supporting Clocks and Reset Domains */
195*91f16700Schasinglulu static const uint8_t plat_protocol_list[] = {
196*91f16700Schasinglulu 	SCMI_PROTOCOL_ID_CLOCK,
197*91f16700Schasinglulu 	SCMI_PROTOCOL_ID_RESET_DOMAIN,
198*91f16700Schasinglulu 	0U /* Null termination */
199*91f16700Schasinglulu };
200*91f16700Schasinglulu 
201*91f16700Schasinglulu size_t plat_scmi_protocol_count(void)
202*91f16700Schasinglulu {
203*91f16700Schasinglulu 	const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U;
204*91f16700Schasinglulu 
205*91f16700Schasinglulu 	assert(count == plat_scmi_protocol_count_paranoid());
206*91f16700Schasinglulu 
207*91f16700Schasinglulu 	return count;
208*91f16700Schasinglulu }
209*91f16700Schasinglulu 
210*91f16700Schasinglulu const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
211*91f16700Schasinglulu {
212*91f16700Schasinglulu 	assert(plat_scmi_protocol_count_paranoid() ==
213*91f16700Schasinglulu 	       (ARRAY_SIZE(plat_protocol_list) - 1U));
214*91f16700Schasinglulu 
215*91f16700Schasinglulu 	return plat_protocol_list;
216*91f16700Schasinglulu }
217*91f16700Schasinglulu 
218*91f16700Schasinglulu /*
219*91f16700Schasinglulu  * Platform SCMI clocks
220*91f16700Schasinglulu  */
221*91f16700Schasinglulu static struct stm32_scmi_clk *find_clock(unsigned int agent_id,
222*91f16700Schasinglulu 					 unsigned int scmi_id)
223*91f16700Schasinglulu {
224*91f16700Schasinglulu 	const struct scmi_agent_resources *resource = find_resource(agent_id);
225*91f16700Schasinglulu 	size_t n = 0U;
226*91f16700Schasinglulu 
227*91f16700Schasinglulu 	if (resource != NULL) {
228*91f16700Schasinglulu 		for (n = 0U; n < resource->clock_count; n++) {
229*91f16700Schasinglulu 			if (n == scmi_id) {
230*91f16700Schasinglulu 				return &resource->clock[n];
231*91f16700Schasinglulu 			}
232*91f16700Schasinglulu 		}
233*91f16700Schasinglulu 	}
234*91f16700Schasinglulu 
235*91f16700Schasinglulu 	return NULL;
236*91f16700Schasinglulu }
237*91f16700Schasinglulu 
238*91f16700Schasinglulu size_t plat_scmi_clock_count(unsigned int agent_id)
239*91f16700Schasinglulu {
240*91f16700Schasinglulu 	const struct scmi_agent_resources *resource = find_resource(agent_id);
241*91f16700Schasinglulu 
242*91f16700Schasinglulu 	if (resource == NULL) {
243*91f16700Schasinglulu 		return 0U;
244*91f16700Schasinglulu 	}
245*91f16700Schasinglulu 
246*91f16700Schasinglulu 	return resource->clock_count;
247*91f16700Schasinglulu }
248*91f16700Schasinglulu 
249*91f16700Schasinglulu const char *plat_scmi_clock_get_name(unsigned int agent_id,
250*91f16700Schasinglulu 				     unsigned int scmi_id)
251*91f16700Schasinglulu {
252*91f16700Schasinglulu 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
253*91f16700Schasinglulu 
254*91f16700Schasinglulu 	if ((clock == NULL) ||
255*91f16700Schasinglulu 	    !stm32mp_nsec_can_access_clock(clock->clock_id)) {
256*91f16700Schasinglulu 		return NULL;
257*91f16700Schasinglulu 	}
258*91f16700Schasinglulu 
259*91f16700Schasinglulu 	return clock->name;
260*91f16700Schasinglulu }
261*91f16700Schasinglulu 
262*91f16700Schasinglulu int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
263*91f16700Schasinglulu 				    unsigned long *array, size_t *nb_elts,
264*91f16700Schasinglulu 				    uint32_t start_idx)
265*91f16700Schasinglulu {
266*91f16700Schasinglulu 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
267*91f16700Schasinglulu 
268*91f16700Schasinglulu 	if (clock == NULL) {
269*91f16700Schasinglulu 		return SCMI_NOT_FOUND;
270*91f16700Schasinglulu 	}
271*91f16700Schasinglulu 
272*91f16700Schasinglulu 	if (!stm32mp_nsec_can_access_clock(clock->clock_id)) {
273*91f16700Schasinglulu 		return SCMI_DENIED;
274*91f16700Schasinglulu 	}
275*91f16700Schasinglulu 
276*91f16700Schasinglulu 	if (start_idx > 0) {
277*91f16700Schasinglulu 		return SCMI_OUT_OF_RANGE;
278*91f16700Schasinglulu 	}
279*91f16700Schasinglulu 
280*91f16700Schasinglulu 	if (array == NULL) {
281*91f16700Schasinglulu 		*nb_elts = 1U;
282*91f16700Schasinglulu 	} else if (*nb_elts == 1U) {
283*91f16700Schasinglulu 		*array = clk_get_rate(clock->clock_id);
284*91f16700Schasinglulu 	} else {
285*91f16700Schasinglulu 		return SCMI_GENERIC_ERROR;
286*91f16700Schasinglulu 	}
287*91f16700Schasinglulu 
288*91f16700Schasinglulu 	return SCMI_SUCCESS;
289*91f16700Schasinglulu }
290*91f16700Schasinglulu 
291*91f16700Schasinglulu unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
292*91f16700Schasinglulu 				       unsigned int scmi_id)
293*91f16700Schasinglulu {
294*91f16700Schasinglulu 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
295*91f16700Schasinglulu 
296*91f16700Schasinglulu 	if ((clock == NULL) ||
297*91f16700Schasinglulu 	    !stm32mp_nsec_can_access_clock(clock->clock_id)) {
298*91f16700Schasinglulu 		return 0U;
299*91f16700Schasinglulu 	}
300*91f16700Schasinglulu 
301*91f16700Schasinglulu 	return clk_get_rate(clock->clock_id);
302*91f16700Schasinglulu }
303*91f16700Schasinglulu 
304*91f16700Schasinglulu int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id)
305*91f16700Schasinglulu {
306*91f16700Schasinglulu 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
307*91f16700Schasinglulu 
308*91f16700Schasinglulu 	if ((clock == NULL) ||
309*91f16700Schasinglulu 	    !stm32mp_nsec_can_access_clock(clock->clock_id)) {
310*91f16700Schasinglulu 		return 0U;
311*91f16700Schasinglulu 	}
312*91f16700Schasinglulu 
313*91f16700Schasinglulu 	return (int32_t)clock->enabled;
314*91f16700Schasinglulu }
315*91f16700Schasinglulu 
316*91f16700Schasinglulu int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
317*91f16700Schasinglulu 				  bool enable_not_disable)
318*91f16700Schasinglulu {
319*91f16700Schasinglulu 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
320*91f16700Schasinglulu 
321*91f16700Schasinglulu 	if (clock == NULL) {
322*91f16700Schasinglulu 		return SCMI_NOT_FOUND;
323*91f16700Schasinglulu 	}
324*91f16700Schasinglulu 
325*91f16700Schasinglulu 	if (!stm32mp_nsec_can_access_clock(clock->clock_id)) {
326*91f16700Schasinglulu 		return SCMI_DENIED;
327*91f16700Schasinglulu 	}
328*91f16700Schasinglulu 
329*91f16700Schasinglulu 	if (enable_not_disable) {
330*91f16700Schasinglulu 		if (!clock->enabled) {
331*91f16700Schasinglulu 			VERBOSE("SCMI clock %u enable\n", scmi_id);
332*91f16700Schasinglulu 			clk_enable(clock->clock_id);
333*91f16700Schasinglulu 			clock->enabled = true;
334*91f16700Schasinglulu 		}
335*91f16700Schasinglulu 	} else {
336*91f16700Schasinglulu 		if (clock->enabled) {
337*91f16700Schasinglulu 			VERBOSE("SCMI clock %u disable\n", scmi_id);
338*91f16700Schasinglulu 			clk_disable(clock->clock_id);
339*91f16700Schasinglulu 			clock->enabled = false;
340*91f16700Schasinglulu 		}
341*91f16700Schasinglulu 	}
342*91f16700Schasinglulu 
343*91f16700Schasinglulu 	return SCMI_SUCCESS;
344*91f16700Schasinglulu }
345*91f16700Schasinglulu 
346*91f16700Schasinglulu /*
347*91f16700Schasinglulu  * Platform SCMI reset domains
348*91f16700Schasinglulu  */
349*91f16700Schasinglulu static struct stm32_scmi_rstd *find_rstd(unsigned int agent_id,
350*91f16700Schasinglulu 					 unsigned int scmi_id)
351*91f16700Schasinglulu {
352*91f16700Schasinglulu 	const struct scmi_agent_resources *resource = find_resource(agent_id);
353*91f16700Schasinglulu 	size_t n;
354*91f16700Schasinglulu 
355*91f16700Schasinglulu 	if (resource != NULL) {
356*91f16700Schasinglulu 		for (n = 0U; n < resource->rstd_count; n++) {
357*91f16700Schasinglulu 			if (n == scmi_id) {
358*91f16700Schasinglulu 				return &resource->rstd[n];
359*91f16700Schasinglulu 			}
360*91f16700Schasinglulu 		}
361*91f16700Schasinglulu 	}
362*91f16700Schasinglulu 
363*91f16700Schasinglulu 	return NULL;
364*91f16700Schasinglulu }
365*91f16700Schasinglulu 
366*91f16700Schasinglulu const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id)
367*91f16700Schasinglulu {
368*91f16700Schasinglulu 	const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id);
369*91f16700Schasinglulu 
370*91f16700Schasinglulu 	if (rstd == NULL) {
371*91f16700Schasinglulu 		return NULL;
372*91f16700Schasinglulu 	}
373*91f16700Schasinglulu 
374*91f16700Schasinglulu 	return rstd->name;
375*91f16700Schasinglulu }
376*91f16700Schasinglulu 
377*91f16700Schasinglulu size_t plat_scmi_rstd_count(unsigned int agent_id)
378*91f16700Schasinglulu {
379*91f16700Schasinglulu 	const struct scmi_agent_resources *resource = find_resource(agent_id);
380*91f16700Schasinglulu 
381*91f16700Schasinglulu 	if (resource == NULL) {
382*91f16700Schasinglulu 		return 0U;
383*91f16700Schasinglulu 	}
384*91f16700Schasinglulu 
385*91f16700Schasinglulu 	return resource->rstd_count;
386*91f16700Schasinglulu }
387*91f16700Schasinglulu 
388*91f16700Schasinglulu int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id,
389*91f16700Schasinglulu 				uint32_t state)
390*91f16700Schasinglulu {
391*91f16700Schasinglulu 	const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id);
392*91f16700Schasinglulu 
393*91f16700Schasinglulu 	if (rstd == NULL) {
394*91f16700Schasinglulu 		return SCMI_NOT_FOUND;
395*91f16700Schasinglulu 	}
396*91f16700Schasinglulu 
397*91f16700Schasinglulu 	if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) {
398*91f16700Schasinglulu 		return SCMI_DENIED;
399*91f16700Schasinglulu 	}
400*91f16700Schasinglulu 
401*91f16700Schasinglulu 	/* Supports only reset with context loss */
402*91f16700Schasinglulu 	if (state != 0U) {
403*91f16700Schasinglulu 		return SCMI_NOT_SUPPORTED;
404*91f16700Schasinglulu 	}
405*91f16700Schasinglulu 
406*91f16700Schasinglulu 	VERBOSE("SCMI reset %lu cycle\n", rstd->reset_id);
407*91f16700Schasinglulu 
408*91f16700Schasinglulu 	if (stm32mp_reset_assert(rstd->reset_id, TIMEOUT_US_1MS)) {
409*91f16700Schasinglulu 		return SCMI_HARDWARE_ERROR;
410*91f16700Schasinglulu 	}
411*91f16700Schasinglulu 
412*91f16700Schasinglulu 	if (stm32mp_reset_deassert(rstd->reset_id, TIMEOUT_US_1MS)) {
413*91f16700Schasinglulu 		return SCMI_HARDWARE_ERROR;
414*91f16700Schasinglulu 	}
415*91f16700Schasinglulu 
416*91f16700Schasinglulu 	return SCMI_SUCCESS;
417*91f16700Schasinglulu }
418*91f16700Schasinglulu 
419*91f16700Schasinglulu int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id,
420*91f16700Schasinglulu 				 bool assert_not_deassert)
421*91f16700Schasinglulu {
422*91f16700Schasinglulu 	const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id);
423*91f16700Schasinglulu 
424*91f16700Schasinglulu 	if (rstd == NULL) {
425*91f16700Schasinglulu 		return SCMI_NOT_FOUND;
426*91f16700Schasinglulu 	}
427*91f16700Schasinglulu 
428*91f16700Schasinglulu 	if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) {
429*91f16700Schasinglulu 		return SCMI_DENIED;
430*91f16700Schasinglulu 	}
431*91f16700Schasinglulu 
432*91f16700Schasinglulu 	if (assert_not_deassert) {
433*91f16700Schasinglulu 		VERBOSE("SCMI reset %lu set\n", rstd->reset_id);
434*91f16700Schasinglulu 		stm32mp_reset_set(rstd->reset_id);
435*91f16700Schasinglulu 	} else {
436*91f16700Schasinglulu 		VERBOSE("SCMI reset %lu release\n", rstd->reset_id);
437*91f16700Schasinglulu 		stm32mp_reset_release(rstd->reset_id);
438*91f16700Schasinglulu 	}
439*91f16700Schasinglulu 
440*91f16700Schasinglulu 	return SCMI_SUCCESS;
441*91f16700Schasinglulu }
442*91f16700Schasinglulu 
443*91f16700Schasinglulu /*
444*91f16700Schasinglulu  * Initialize platform SCMI resources
445*91f16700Schasinglulu  */
446*91f16700Schasinglulu void stm32mp1_init_scmi_server(void)
447*91f16700Schasinglulu {
448*91f16700Schasinglulu 	size_t i;
449*91f16700Schasinglulu 
450*91f16700Schasinglulu 	for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) {
451*91f16700Schasinglulu 		scmi_smt_init_agent_channel(&scmi_channel[i]);
452*91f16700Schasinglulu 	}
453*91f16700Schasinglulu 
454*91f16700Schasinglulu 	for (i = 0U; i < ARRAY_SIZE(agent_resources); i++) {
455*91f16700Schasinglulu 		const struct scmi_agent_resources *res = &agent_resources[i];
456*91f16700Schasinglulu 		size_t j;
457*91f16700Schasinglulu 
458*91f16700Schasinglulu 		for (j = 0U; j < res->clock_count; j++) {
459*91f16700Schasinglulu 			struct stm32_scmi_clk *clk = &res->clock[j];
460*91f16700Schasinglulu 
461*91f16700Schasinglulu 			if ((clk->name == NULL) ||
462*91f16700Schasinglulu 			    (strlen(clk->name) >= SCMI_CLOCK_NAME_SIZE)) {
463*91f16700Schasinglulu 				ERROR("Invalid SCMI clock name\n");
464*91f16700Schasinglulu 				panic();
465*91f16700Schasinglulu 			}
466*91f16700Schasinglulu 
467*91f16700Schasinglulu 			/* Sync SCMI clocks with their targeted initial state */
468*91f16700Schasinglulu 			if (clk->enabled &&
469*91f16700Schasinglulu 			    stm32mp_nsec_can_access_clock(clk->clock_id)) {
470*91f16700Schasinglulu 				clk_enable(clk->clock_id);
471*91f16700Schasinglulu 			}
472*91f16700Schasinglulu 		}
473*91f16700Schasinglulu 
474*91f16700Schasinglulu 		for (j = 0U; j < res->rstd_count; j++) {
475*91f16700Schasinglulu 			struct stm32_scmi_rstd *rstd = &res->rstd[j];
476*91f16700Schasinglulu 
477*91f16700Schasinglulu 			if ((rstd->name == NULL) ||
478*91f16700Schasinglulu 			    (strlen(rstd->name) >= SCMI_RSTD_NAME_SIZE)) {
479*91f16700Schasinglulu 				ERROR("Invalid SCMI reset domain name\n");
480*91f16700Schasinglulu 				panic();
481*91f16700Schasinglulu 			}
482*91f16700Schasinglulu 		}
483*91f16700Schasinglulu 	}
484*91f16700Schasinglulu }
485