xref: /optee_os/core/arch/arm/plat-stm32mp1/scmi_server.c (revision 5118efbe82358fd69fda6e0158a30e59f59ba09d)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2019, STMicroelectronics
4  */
5 #include <assert.h>
6 #include <compiler.h>
7 #include <drivers/scmi-msg.h>
8 #include <drivers/scmi.h>
9 #include <drivers/stm32mp1_pwr.h>
10 #include <dt-bindings/clock/stm32mp1-clks.h>
11 #include <dt-bindings/regulator/st,stm32mp15-regulator.h>
12 #include <dt-bindings/reset/stm32mp1-resets.h>
13 #include <initcall.h>
14 #include <mm/core_memprot.h>
15 #include <mm/core_mmu.h>
16 #include <platform_config.h>
17 #include <stdint.h>
18 #include <speculation_barrier.h>
19 #include <stm32_util.h>
20 #include <string.h>
21 #include <tee_api_defines.h>
22 #include <util.h>
23 
24 #define TIMEOUT_US_1MS		1000
25 
26 #define SCMI_CLOCK_NAME_SIZE	16
27 #define SCMI_RD_NAME_SIZE	16
28 #define SCMI_VOLTD_NAME_SIZE	16
29 
30 /*
31  * struct stm32_scmi_clk - Data for the exposed clock
32  * @clock_id: Clock identifier in RCC clock driver
33  * @name: Clock string ID exposed to agent
34  * @enabled: State of the SCMI clock
35  */
36 struct stm32_scmi_clk {
37 	unsigned long clock_id;
38 	const char *name;
39 	bool enabled;
40 };
41 
42 /*
43  * struct stm32_scmi_rd - Data for the exposed reset controller
44  * @reset_id: Reset identifier in RCC reset driver
45  * @name: Reset string ID exposed to agent
46  */
47 struct stm32_scmi_rd {
48 	unsigned long reset_id;
49 	const char *name;
50 };
51 
52 enum voltd_device {
53 	VOLTD_PWR,
54 };
55 
56 /*
57  * struct stm32_scmi_voltd - Data for the exposed voltage domains
58  * @name: Power regulator string ID exposed to agent
59  * @priv_id: Internal string ID for the regulator
60  * @priv_dev: Internal ID for the device implementing the regulator
61  */
62 struct stm32_scmi_voltd {
63 	const char *name;
64 	const char *priv_id;
65 	enum voltd_device priv_dev;
66 
67 };
68 
69 /* Locate all non-secure SMT message buffers in last page of SYSRAM */
70 #define SMT_BUFFER_BASE		CFG_STM32MP1_SCMI_SHM_BASE
71 #define SMT_BUFFER0_BASE	SMT_BUFFER_BASE
72 #define SMT_BUFFER1_BASE	(SMT_BUFFER_BASE + 0x200)
73 
74 #if (SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE > \
75 	CFG_STM32MP1_SCMI_SHM_BASE + CFG_STM32MP1_SCMI_SHM_SIZE)
76 #error "SCMI shared memory mismatch"
77 #endif
78 
79 register_phys_mem(MEM_AREA_IO_NSEC, CFG_STM32MP1_SCMI_SHM_BASE,
80 		  CFG_STM32MP1_SCMI_SHM_SIZE);
81 
82 static struct scmi_msg_channel scmi_channel[] = {
83 	[0] = {
84 		.agent_name = "stm32mp1-agent-0",
85 		.shm_addr = { .pa = SMT_BUFFER0_BASE, },
86 		.shm_size = SMT_BUF_SLOT_SIZE,
87 	},
88 	[1] = {
89 		.agent_name = "stm32mp1-agent-1",
90 		.shm_addr = { .pa = SMT_BUFFER1_BASE, },
91 		.shm_size = SMT_BUF_SLOT_SIZE,
92 	},
93 };
94 
95 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
96 {
97 	assert(agent_id < ARRAY_SIZE(scmi_channel));
98 
99 	return &scmi_channel[agent_id];
100 }
101 
102 #define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled) \
103 	[_scmi_id] = { \
104 		.clock_id = _id, \
105 		.name = _name, \
106 		.enabled = _init_enabled, \
107 	}
108 
109 struct stm32_scmi_clk stm32_scmi0_clock[] = {
110 	CLOCK_CELL(CK_SCMI0_HSE, CK_HSE, "ck_hse", true),
111 	CLOCK_CELL(CK_SCMI0_HSI, CK_HSI, "ck_hsi", true),
112 	CLOCK_CELL(CK_SCMI0_CSI, CK_CSI, "ck_csi", true),
113 	CLOCK_CELL(CK_SCMI0_LSE, CK_LSE, "ck_lse", true),
114 	CLOCK_CELL(CK_SCMI0_LSI, CK_LSI, "ck_lsi", true),
115 	CLOCK_CELL(CK_SCMI0_PLL2_Q, PLL2_Q, "pll2_q", true),
116 	CLOCK_CELL(CK_SCMI0_PLL2_R, PLL2_R, "pll2_r", true),
117 	CLOCK_CELL(CK_SCMI0_MPU, CK_MPU, "ck_mpu", true),
118 	CLOCK_CELL(CK_SCMI0_AXI, CK_AXI, "ck_axi", true),
119 	CLOCK_CELL(CK_SCMI0_BSEC, BSEC, "bsec", true),
120 	CLOCK_CELL(CK_SCMI0_CRYP1, CRYP1, "cryp1", false),
121 	CLOCK_CELL(CK_SCMI0_GPIOZ, GPIOZ, "gpioz", false),
122 	CLOCK_CELL(CK_SCMI0_HASH1, HASH1, "hash1", false),
123 	CLOCK_CELL(CK_SCMI0_I2C4, I2C4_K, "i2c4_k", false),
124 	CLOCK_CELL(CK_SCMI0_I2C6, I2C6_K, "i2c6_k", false),
125 	CLOCK_CELL(CK_SCMI0_IWDG1, IWDG1, "iwdg1", false),
126 	CLOCK_CELL(CK_SCMI0_RNG1, RNG1_K, "rng1_k", true),
127 	CLOCK_CELL(CK_SCMI0_RTC, RTC, "ck_rtc", true),
128 	CLOCK_CELL(CK_SCMI0_RTCAPB, RTCAPB, "rtcapb", true),
129 	CLOCK_CELL(CK_SCMI0_SPI6, SPI6_K, "spi6_k", false),
130 	CLOCK_CELL(CK_SCMI0_USART1, USART1_K, "usart1_k", false),
131 };
132 
133 struct stm32_scmi_clk stm32_scmi1_clock[] = {
134 	CLOCK_CELL(CK_SCMI1_PLL3_Q, PLL3_Q, "pll3_q", true),
135 	CLOCK_CELL(CK_SCMI1_PLL3_R, PLL3_R, "pll3_r", true),
136 	CLOCK_CELL(CK_SCMI1_MCU, CK_MCU, "ck_mcu", false),
137 };
138 
139 #define RESET_CELL(_scmi_id, _id, _name) \
140 	[_scmi_id] = { \
141 		.reset_id = _id, \
142 		.name = _name, \
143 	}
144 
145 struct stm32_scmi_rd stm32_scmi0_reset_domain[] = {
146 	RESET_CELL(RST_SCMI0_SPI6, SPI6_R, "spi6"),
147 	RESET_CELL(RST_SCMI0_I2C4, I2C4_R, "i2c4"),
148 	RESET_CELL(RST_SCMI0_I2C6, I2C6_R, "i2c6"),
149 	RESET_CELL(RST_SCMI0_USART1, USART1_R, "usart1"),
150 	RESET_CELL(RST_SCMI0_STGEN, STGEN_R, "stgen"),
151 	RESET_CELL(RST_SCMI0_GPIOZ, GPIOZ_R, "gpioz"),
152 	RESET_CELL(RST_SCMI0_CRYP1, CRYP1_R, "cryp1"),
153 	RESET_CELL(RST_SCMI0_HASH1, HASH1_R, "hash1"),
154 	RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"),
155 	RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"),
156 	RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"),
157 	RESET_CELL(RST_SCMI0_MCU_HOLD_BOOT, MCU_HOLD_BOOT_R, "mcu_hold_boot"),
158 };
159 
160 #define VOLTD_CELL(_scmi_id, _dev_id, _priv_id, _name) \
161 	[_scmi_id] = { \
162 		.priv_id = (_priv_id), \
163 		.priv_dev = (_dev_id), \
164 		.name = (_name), \
165 	}
166 
167 #define PWR_REG11_NAME_ID		"0"
168 #define PWR_REG18_NAME_ID		"1"
169 #define PWR_USB33_NAME_ID		"2"
170 
171 struct stm32_scmi_voltd scmi0_voltage_domain[] = {
172 	VOLTD_CELL(VOLTD_SCMI0_REG11, VOLTD_PWR, PWR_REG11_NAME_ID, "reg11"),
173 	VOLTD_CELL(VOLTD_SCMI0_REG18, VOLTD_PWR, PWR_REG18_NAME_ID, "reg18"),
174 	VOLTD_CELL(VOLTD_SCMI0_USB33, VOLTD_PWR, PWR_USB33_NAME_ID, "usb33"),
175 };
176 
177 struct scmi_agent_resources {
178 	struct stm32_scmi_clk *clock;
179 	size_t clock_count;
180 	struct stm32_scmi_rd *rd;
181 	size_t rd_count;
182 	struct stm32_scmi_pd *pd;
183 	size_t pd_count;
184 	struct stm32_scmi_perfs *perfs;
185 	size_t perfs_count;
186 	struct stm32_scmi_voltd *voltd;
187 	size_t voltd_count;
188 };
189 
190 const struct scmi_agent_resources agent_resources[] = {
191 	[0] = {
192 		.clock = stm32_scmi0_clock,
193 		.clock_count = ARRAY_SIZE(stm32_scmi0_clock),
194 		.rd = stm32_scmi0_reset_domain,
195 		.rd_count = ARRAY_SIZE(stm32_scmi0_reset_domain),
196 		.voltd = scmi0_voltage_domain,
197 		.voltd_count = ARRAY_SIZE(scmi0_voltage_domain),
198 	},
199 	[1] = {
200 		.clock = stm32_scmi1_clock,
201 		.clock_count = ARRAY_SIZE(stm32_scmi1_clock),
202 	},
203 };
204 
205 static const struct scmi_agent_resources *find_resource(unsigned int agent_id)
206 {
207 	assert(agent_id < ARRAY_SIZE(agent_resources));
208 
209 	return &agent_resources[agent_id];
210 }
211 
212 static size_t __maybe_unused plat_scmi_protocol_count_paranoid(void)
213 {
214 	unsigned int n = 0;
215 	unsigned int count = 0;
216 	const size_t agent_count = ARRAY_SIZE(agent_resources);
217 
218 	for (n = 0; n < agent_count; n++)
219 		if (agent_resources[n].clock_count)
220 			break;
221 	if (n < agent_count)
222 		count++;
223 
224 	for (n = 0; n < agent_count; n++)
225 		if (agent_resources[n].rd_count)
226 			break;
227 	if (n < agent_count)
228 		count++;
229 
230 	for (n = 0; n < agent_count; n++)
231 		if (agent_resources[n].pd_count)
232 			break;
233 	if (n < agent_count)
234 		count++;
235 
236 	for (n = 0; n < agent_count; n++)
237 		if (agent_resources[n].perfs_count)
238 			break;
239 	if (n < agent_count)
240 		count++;
241 
242 	for (n = 0; n < agent_count; n++)
243 		if (agent_resources[n].voltd_count)
244 			break;
245 	if (n < agent_count)
246 		count++;
247 
248 	return count;
249 }
250 
251 static const char vendor[] = "ST";
252 static const char sub_vendor[] = "";
253 
254 const char *plat_scmi_vendor_name(void)
255 {
256 	return vendor;
257 }
258 
259 const char *plat_scmi_sub_vendor_name(void)
260 {
261 	return sub_vendor;
262 }
263 
264 /* Currently supporting Clocks and Reset Domains */
265 static const uint8_t plat_protocol_list[] = {
266 	SCMI_PROTOCOL_ID_CLOCK,
267 	SCMI_PROTOCOL_ID_RESET_DOMAIN,
268 	SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,
269 	0 /* Null termination */
270 };
271 
272 size_t plat_scmi_protocol_count(void)
273 {
274 	const size_t count = ARRAY_SIZE(plat_protocol_list) - 1;
275 
276 	assert(count == plat_scmi_protocol_count_paranoid());
277 
278 	return count;
279 }
280 
281 const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
282 {
283 	assert(plat_scmi_protocol_count_paranoid() ==
284 	       (ARRAY_SIZE(plat_protocol_list) - 1));
285 
286 	return plat_protocol_list;
287 }
288 
289 /*
290  * Platform SCMI clocks
291  */
292 static struct stm32_scmi_clk *find_clock(unsigned int agent_id,
293 					 unsigned int scmi_id)
294 {
295 	const struct scmi_agent_resources *resource = find_resource(agent_id);
296 	size_t n = 0;
297 
298 	if (resource) {
299 		for (n = 0; n < resource->clock_count; n++)
300 			if (n == scmi_id)
301 				return &resource->clock[n];
302 	}
303 
304 	return NULL;
305 }
306 
307 size_t plat_scmi_clock_count(unsigned int agent_id)
308 {
309 	const struct scmi_agent_resources *resource = find_resource(agent_id);
310 
311 	if (!resource)
312 		return 0;
313 
314 	return resource->clock_count;
315 }
316 
317 const char *plat_scmi_clock_get_name(unsigned int agent_id,
318 				     unsigned int scmi_id)
319 {
320 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
321 
322 	if (!clock || !stm32mp_nsec_can_access_clock(clock->clock_id))
323 		return NULL;
324 
325 	return clock->name;
326 }
327 
328 int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
329 				    size_t start_index, unsigned long *array,
330 				    size_t *nb_elts)
331 {
332 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
333 
334 	if (!clock)
335 		return SCMI_NOT_FOUND;
336 
337 	if (!stm32mp_nsec_can_access_clock(clock->clock_id))
338 		return SCMI_DENIED;
339 
340 	/* Exposed clocks are currently fixed rate clocks */
341 	if (start_index)
342 		return SCMI_INVALID_PARAMETERS;
343 
344 	if (!array)
345 		*nb_elts = 1;
346 	else if (*nb_elts == 1)
347 		*array = stm32_clock_get_rate(clock->clock_id);
348 	else
349 		return SCMI_GENERIC_ERROR;
350 
351 	return SCMI_SUCCESS;
352 }
353 
354 unsigned long plat_scmi_clock_get_rate(unsigned int agent_id,
355 				       unsigned int scmi_id)
356 {
357 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
358 
359 	if (!clock || !stm32mp_nsec_can_access_clock(clock->clock_id))
360 		return 0;
361 
362 	return stm32_clock_get_rate(clock->clock_id);
363 }
364 
365 int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id)
366 {
367 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
368 
369 	if (!clock || !stm32mp_nsec_can_access_clock(clock->clock_id))
370 		return 0;
371 
372 	return (int32_t)clock->enabled;
373 }
374 
375 int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
376 				  bool enable_not_disable)
377 {
378 	struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id);
379 
380 	if (!clock)
381 		return SCMI_NOT_FOUND;
382 
383 	if (!stm32mp_nsec_can_access_clock(clock->clock_id))
384 		return SCMI_DENIED;
385 
386 	if (enable_not_disable) {
387 		if (!clock->enabled) {
388 			DMSG("SCMI clock %u enable", scmi_id);
389 			stm32_clock_enable(clock->clock_id);
390 			clock->enabled = true;
391 		}
392 	} else {
393 		if (clock->enabled) {
394 			DMSG("SCMI clock %u disable", scmi_id);
395 			stm32_clock_disable(clock->clock_id);
396 			clock->enabled = false;
397 		}
398 	}
399 
400 	return SCMI_SUCCESS;
401 }
402 
403 /*
404  * Platform SCMI reset domains
405  */
406 static struct stm32_scmi_rd *find_rd(unsigned int agent_id,
407 				     unsigned int scmi_id)
408 {
409 	const struct scmi_agent_resources *resource = find_resource(agent_id);
410 	size_t n = 0;
411 
412 	if (resource) {
413 		for (n = 0; n < resource->rd_count; n++)
414 			if (n == scmi_id)
415 				return &resource->rd[n];
416 	}
417 
418 	return NULL;
419 }
420 
421 const char *plat_scmi_rd_get_name(unsigned int agent_id, unsigned int scmi_id)
422 {
423 	const struct stm32_scmi_rd *rd = find_rd(agent_id, scmi_id);
424 
425 	if (!rd)
426 		return NULL;
427 
428 	return rd->name;
429 }
430 
431 size_t plat_scmi_rd_count(unsigned int agent_id)
432 {
433 	const struct scmi_agent_resources *resource = find_resource(agent_id);
434 
435 	if (!resource)
436 		return 0;
437 
438 	return resource->rd_count;
439 }
440 
441 int32_t plat_scmi_rd_autonomous(unsigned int agent_id, unsigned int scmi_id,
442 				uint32_t state)
443 {
444 	const struct stm32_scmi_rd *rd = find_rd(agent_id, scmi_id);
445 
446 	if (!rd)
447 		return SCMI_NOT_FOUND;
448 
449 	if (!stm32mp_nsec_can_access_reset(rd->reset_id))
450 		return SCMI_DENIED;
451 
452 	if (rd->reset_id == MCU_HOLD_BOOT_R)
453 		return SCMI_NOT_SUPPORTED;
454 
455 	/* Supports only reset with context loss */
456 	if (state)
457 		return SCMI_NOT_SUPPORTED;
458 
459 	DMSG("SCMI reset %u cycle", scmi_id);
460 
461 	if (stm32_reset_assert(rd->reset_id, TIMEOUT_US_1MS))
462 		return SCMI_HARDWARE_ERROR;
463 
464 	if (stm32_reset_deassert(rd->reset_id, TIMEOUT_US_1MS))
465 		return SCMI_HARDWARE_ERROR;
466 
467 	return SCMI_SUCCESS;
468 }
469 
470 int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id,
471 			       bool assert_not_deassert)
472 {
473 	const struct stm32_scmi_rd *rd = find_rd(agent_id, scmi_id);
474 
475 	if (!rd)
476 		return SCMI_NOT_FOUND;
477 
478 	if (!stm32mp_nsec_can_access_reset(rd->reset_id))
479 		return SCMI_DENIED;
480 
481 	if (rd->reset_id == MCU_HOLD_BOOT_R) {
482 		DMSG("SCMI MCU hold boot %s",
483 		     assert_not_deassert ? "set" : "release");
484 		stm32_reset_assert_deassert_mcu(assert_not_deassert);
485 		return SCMI_SUCCESS;
486 	}
487 
488 	if (assert_not_deassert) {
489 		DMSG("SCMI reset %u set", scmi_id);
490 		stm32_reset_set(rd->reset_id);
491 	} else {
492 		DMSG("SCMI reset %u release", scmi_id);
493 		stm32_reset_release(rd->reset_id);
494 	}
495 
496 	return SCMI_SUCCESS;
497 }
498 
499 /*
500  * Platform SCMI voltage domains
501  */
502 static struct stm32_scmi_voltd *find_voltd(unsigned int agent_id,
503 					   unsigned int scmi_id)
504 {
505 	const struct scmi_agent_resources *resource = find_resource(agent_id);
506 	size_t n = 0;
507 
508 	if (resource) {
509 		for (n = 0; n < resource->voltd_count; n++)
510 			if (n == scmi_id)
511 				return &resource->voltd[n];
512 	}
513 
514 	return NULL;
515 }
516 
517 size_t plat_scmi_voltd_count(unsigned int agent_id)
518 {
519 	const struct scmi_agent_resources *resource = find_resource(agent_id);
520 
521 	if (!resource)
522 		return 0;
523 
524 	return resource->voltd_count;
525 }
526 
527 const char *plat_scmi_voltd_get_name(unsigned int agent_id,
528 				     unsigned int scmi_id)
529 {
530 	struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id);
531 
532 	/* Currently non-secure is allowed to access all PWR regulators */
533 	if (!voltd)
534 		return NULL;
535 
536 	return voltd->name;
537 }
538 
539 static enum pwr_regulator pwr_scmi_to_regu_id(struct stm32_scmi_voltd *voltd)
540 {
541 	if (!strcmp(voltd->priv_id, PWR_REG11_NAME_ID))
542 		return PWR_REG11;
543 	if (!strcmp(voltd->priv_id, PWR_REG18_NAME_ID))
544 		return PWR_REG18;
545 	if (!strcmp(voltd->priv_id, PWR_USB33_NAME_ID))
546 		return PWR_USB33;
547 
548 	panic();
549 }
550 
551 static long pwr_get_level(struct stm32_scmi_voltd *voltd)
552 {
553 	enum pwr_regulator regu_id = pwr_scmi_to_regu_id(voltd);
554 
555 	return (long)stm32mp1_pwr_regulator_mv(regu_id) * 1000;
556 }
557 
558 static int32_t pwr_set_level(struct stm32_scmi_voltd *voltd, long level_uv)
559 {
560 	if (level_uv != pwr_get_level(voltd))
561 		return SCMI_INVALID_PARAMETERS;
562 
563 	return SCMI_SUCCESS;
564 }
565 
566 static int32_t pwr_describe_levels(struct stm32_scmi_voltd *voltd,
567 				   size_t start_index, long *microvolt,
568 				   size_t *nb_elts)
569 {
570 	if (start_index)
571 		return SCMI_INVALID_PARAMETERS;
572 
573 	if (!microvolt) {
574 		*nb_elts = 1;
575 		return SCMI_SUCCESS;
576 	}
577 
578 	if (*nb_elts < 1)
579 		return SCMI_GENERIC_ERROR;
580 
581 	*nb_elts = 1;
582 	*microvolt = pwr_get_level(voltd);
583 
584 	return SCMI_SUCCESS;
585 }
586 
587 static uint32_t pwr_get_state(struct stm32_scmi_voltd *voltd)
588 {
589 	enum pwr_regulator regu_id = pwr_scmi_to_regu_id(voltd);
590 
591 	if (stm32mp1_pwr_regulator_is_enabled(regu_id))
592 		return SCMI_VOLTAGE_DOMAIN_CONFIG_ARCH_ON;
593 
594 	return SCMI_VOLTAGE_DOMAIN_CONFIG_ARCH_OFF;
595 }
596 
597 static void pwr_set_state(struct stm32_scmi_voltd *voltd, bool enable)
598 {
599 	enum pwr_regulator regu_id = pwr_scmi_to_regu_id(voltd);
600 
601 	DMSG("%sable PWR %s (was %s)", enable ? "En" : "Dis", voltd->name,
602 	     stm32mp1_pwr_regulator_is_enabled(regu_id) ? "on" : "off");
603 
604 	stm32mp1_pwr_regulator_set_state(regu_id, enable);
605 }
606 
607 int32_t plat_scmi_voltd_levels_array(unsigned int agent_id,
608 				     unsigned int scmi_id, size_t start_index,
609 				     long *levels, size_t *nb_elts)
610 
611 {
612 	struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id);
613 
614 	if (!voltd)
615 		return SCMI_NOT_FOUND;
616 
617 	switch (voltd->priv_dev) {
618 	case VOLTD_PWR:
619 		return pwr_describe_levels(voltd, start_index, levels, nb_elts);
620 	default:
621 		return SCMI_GENERIC_ERROR;
622 	}
623 }
624 
625 long plat_scmi_voltd_get_level(unsigned int agent_id, unsigned int scmi_id)
626 {
627 	struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id);
628 
629 	if (!voltd)
630 		return 0;
631 
632 	switch (voltd->priv_dev) {
633 	case VOLTD_PWR:
634 		return pwr_get_level(voltd);
635 	default:
636 		panic();
637 	}
638 }
639 
640 int32_t plat_scmi_voltd_set_level(unsigned int agent_id, unsigned int scmi_id,
641 				  long level)
642 {
643 	struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id);
644 
645 	if (!voltd)
646 		return SCMI_NOT_FOUND;
647 
648 	switch (voltd->priv_dev) {
649 	case VOLTD_PWR:
650 		return pwr_set_level(voltd, level);
651 	default:
652 		return SCMI_GENERIC_ERROR;
653 	}
654 }
655 
656 int32_t plat_scmi_voltd_get_config(unsigned int agent_id, unsigned int scmi_id,
657 				   uint32_t *config)
658 {
659 	struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id);
660 
661 	if (!voltd)
662 		return SCMI_NOT_FOUND;
663 
664 	switch (voltd->priv_dev) {
665 	case VOLTD_PWR:
666 		*config = pwr_get_state(voltd);
667 		break;
668 	default:
669 		return SCMI_GENERIC_ERROR;
670 	}
671 
672 	return SCMI_SUCCESS;
673 }
674 
675 int32_t plat_scmi_voltd_set_config(unsigned int agent_id, unsigned int scmi_id,
676 				   uint32_t config)
677 {
678 	struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id);
679 	int32_t rc = SCMI_SUCCESS;
680 
681 	if (!voltd)
682 		return SCMI_NOT_FOUND;
683 
684 	switch (voltd->priv_dev) {
685 	case VOLTD_PWR:
686 		pwr_set_state(voltd, config);
687 		break;
688 	default:
689 		return SCMI_GENERIC_ERROR;
690 	}
691 
692 	return rc;
693 }
694 
695 /*
696  * Initialize platform SCMI resources
697  */
698 static TEE_Result stm32mp1_init_scmi_server(void)
699 {
700 	size_t i = 0;
701 	size_t j = 0;
702 
703 	for (i = 0; i < ARRAY_SIZE(scmi_channel); i++) {
704 		struct scmi_msg_channel *chan = &scmi_channel[i];
705 
706 		/* Enforce non-secure shm mapped as device memory */
707 		chan->shm_addr.va = (vaddr_t)phys_to_virt(chan->shm_addr.pa,
708 							  MEM_AREA_IO_NSEC);
709 		assert(chan->shm_addr.va);
710 
711 		scmi_smt_init_agent_channel(chan);
712 	}
713 
714 	for (i = 0; i < ARRAY_SIZE(agent_resources); i++) {
715 		const struct scmi_agent_resources *res = &agent_resources[i];
716 
717 		for (j = 0; j < res->clock_count; j++) {
718 			struct stm32_scmi_clk *clk = &res->clock[j];
719 
720 			if (!clk->name ||
721 			    strlen(clk->name) >= SCMI_CLOCK_NAME_SIZE)
722 				panic("SCMI clock name invalid");
723 
724 			/* Sync SCMI clocks with their targeted initial state */
725 			if (clk->enabled &&
726 			    stm32mp_nsec_can_access_clock(clk->clock_id))
727 				stm32_clock_enable(clk->clock_id);
728 		}
729 
730 		for (j = 0; j < res->rd_count; j++) {
731 			struct stm32_scmi_rd *rd = &res->rd[j];
732 
733 			if (!rd->name ||
734 			    strlen(rd->name) >= SCMI_RD_NAME_SIZE)
735 				panic("SCMI reset domain name invalid");
736 		}
737 
738 		for (j = 0; j < res->voltd_count; j++) {
739 			struct stm32_scmi_voltd *voltd = &res->voltd[j];
740 
741 			if (!voltd->name ||
742 			    strlen(voltd->name) >= SCMI_VOLTD_NAME_SIZE)
743 				panic("SCMI voltage domain name invalid");
744 		}
745 	}
746 
747 	return TEE_SUCCESS;
748 }
749 
750 driver_init_late(stm32mp1_init_scmi_server);
751