1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2020, Linaro Limited
4 */
5
6#define LOG_CATEGORY UCLASS_SCMI_AGENT
7
8#include <common.h>
9#include <dm.h>
10#include <malloc.h>
11#include <scmi_agent.h>
12#include <scmi_agent-uclass.h>
13#include <scmi_protocols.h>
14#include <asm/io.h>
15#include <asm/scmi_test.h>
16#include <dm/device_compat.h>
17#include <linux/bitfield.h>
18#include <linux/kernel.h>
19
20/*
21 * The sandbox SCMI agent driver simulates to some extend a SCMI message
22 * processing. It simulates few of the SCMI services for some of the
23 * SCMI protocols embedded in U-Boot. Currently:
24 * - SCMI base protocol
25 * - SCMI clock protocol emulates an agent exposing 2 clocks
26 * - SCMI reset protocol emulates an agent exposing a reset controller
27 * - SCMI voltage domain protocol emulates an agent exposing 2 regulators
28 *
29 * As per DT bindings, the device node name shall be scmi.
30 *
31 * All clocks and regulators are default disabled and reset controller down.
32 *
33 * This driver exports sandbox_scmi_service_ctx() for the test sequence to
34 * get the state of the simulated services (clock state, rate, ...) and
35 * check back-end device state reflects the request send through the
36 * various uclass devices, as clocks and reset controllers.
37 */
38
39#define SANDBOX_SCMI_BASE_PROTOCOL_VERSION SCMI_BASE_PROTOCOL_VERSION
40#define SANDBOX_SCMI_VENDOR "U-Boot"
41#define SANDBOX_SCMI_SUB_VENDOR "Sandbox"
42#define SANDBOX_SCMI_IMPL_VERSION 0x1
43#define SANDBOX_SCMI_AGENT_NAME "OSPM"
44#define SANDBOX_SCMI_PLATFORM_NAME "platform"
45
46#define SANDBOX_SCMI_PWD_PROTOCOL_VERSION SCMI_PWD_PROTOCOL_VERSION
47
48/**
49 * struct sandbox_channel - Description of sandbox transport
50 * @channel_id:		Channel identifier
51 *
52 * Dummy channel. This will be used to test if a protocol-specific
53 * channel is properly used.
54 * Id 0 means a channel for the sandbox agent.
55 */
56struct sandbox_channel {
57	unsigned int channel_id;
58};
59
60/**
61 * struct scmi_channel - Channel instance referenced in SCMI drivers
62 * @ref: Reference to local channel instance
63 **/
64struct scmi_channel {
65	struct sandbox_channel ref;
66};
67
68static u8 protocols[] = {
69	CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN, (SCMI_PROTOCOL_ID_POWER_DOMAIN,))
70	CONFIG_IS_ENABLED(CLK_SCMI, (SCMI_PROTOCOL_ID_CLOCK,))
71	CONFIG_IS_ENABLED(RESET_SCMI, (SCMI_PROTOCOL_ID_RESET_DOMAIN,))
72	CONFIG_IS_ENABLED(DM_REGULATOR_SCMI, (SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,))
73};
74
75#define NUM_PROTOCOLS ARRAY_SIZE(protocols)
76
77static struct sandbox_scmi_pwd scmi_pwdom[] = {
78	{ .id = 0 },
79	{ .id = 1 },
80	{ .id = 2 },
81};
82
83static struct sandbox_scmi_clk scmi_clk[] = {
84	{ .rate = 333 },
85	{ .rate = 200 },
86	{ .rate = 1000 },
87};
88
89static struct sandbox_scmi_reset scmi_reset[] = {
90	{ .id = 3 },
91};
92
93static struct sandbox_scmi_voltd scmi_voltd[] = {
94	{ .id = 0, .voltage_uv = 3300000 },
95	{ .id = 1, .voltage_uv = 1800000 },
96};
97
98struct sandbox_scmi_agent *sandbox_scmi_agent_ctx(struct udevice *dev)
99{
100	return dev_get_priv(dev);
101}
102
103static void debug_print_agent_state(struct udevice *dev, char *str)
104{
105	struct sandbox_scmi_agent *agent = dev_get_priv(dev);
106
107	dev_dbg(dev, "Dump sandbox_scmi_agent: %s\n", str);
108	dev_dbg(dev, " scmi_clk   (%zu): %d/%ld, %d/%ld, %d/%ld, ...\n",
109		agent->clk_count,
110		agent->clk_count ? agent->clk[0].enabled : -1,
111		agent->clk_count ? agent->clk[0].rate : -1,
112		agent->clk_count > 1 ? agent->clk[1].enabled : -1,
113		agent->clk_count > 1 ? agent->clk[1].rate : -1,
114		agent->clk_count > 2 ? agent->clk[2].enabled : -1,
115		agent->clk_count > 2 ? agent->clk[2].rate : -1);
116	dev_dbg(dev, " scmi_reset (%zu): %d, %d, ...\n",
117		agent->reset_count,
118		agent->reset_count ? agent->reset[0].asserted : -1,
119		agent->reset_count > 1 ? agent->reset[1].asserted : -1);
120	dev_dbg(dev, " scmi_voltd (%zu): %u/%d, %u/%d, ...\n",
121		agent->voltd_count,
122		agent->voltd_count ? agent->voltd[0].enabled : -1,
123		agent->voltd_count ? agent->voltd[0].voltage_uv : -1,
124		agent->voltd_count ? agent->voltd[1].enabled : -1,
125		agent->voltd_count ? agent->voltd[1].voltage_uv : -1);
126};
127
128static struct sandbox_scmi_clk *get_scmi_clk_state(uint clock_id)
129{
130	if (clock_id < ARRAY_SIZE(scmi_clk))
131		return scmi_clk + clock_id;
132
133	return NULL;
134}
135
136static struct sandbox_scmi_reset *get_scmi_reset_state(uint reset_id)
137{
138	size_t n;
139
140	for (n = 0; n < ARRAY_SIZE(scmi_reset); n++)
141		if (scmi_reset[n].id == reset_id)
142			return scmi_reset + n;
143
144	return NULL;
145}
146
147static struct sandbox_scmi_voltd *get_scmi_voltd_state(uint domain_id)
148{
149	size_t n;
150
151	for (n = 0; n < ARRAY_SIZE(scmi_voltd); n++)
152		if (scmi_voltd[n].id == domain_id)
153			return scmi_voltd + n;
154
155	return NULL;
156}
157
158/*
159 * Sandbox SCMI agent ops
160 */
161
162/* Base Protocol */
163
164/**
165 * sandbox_scmi_base_protocol_version - implement SCMI_BASE_PROTOCOL_VERSION
166 * @dev:	SCMI device
167 * @msg:	SCMI message
168 *
169 * Implement SCMI_BASE_PROTOCOL_VERSION command.
170 */
171static int sandbox_scmi_base_protocol_version(struct udevice *dev,
172					      struct scmi_msg *msg)
173{
174	struct scmi_protocol_version_out *out = NULL;
175
176	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
177		return -EINVAL;
178
179	out = (struct scmi_protocol_version_out *)msg->out_msg;
180	out->version = SANDBOX_SCMI_BASE_PROTOCOL_VERSION;
181	out->status = SCMI_SUCCESS;
182
183	return 0;
184}
185
186/**
187 * sandbox_scmi_base_protocol_attrs - implement SCMI_BASE_PROTOCOL_ATTRIBUTES
188 * @dev:	SCMI device
189 * @msg:	SCMI message
190 *
191 * Implement SCMI_BASE_PROTOCOL_ATTRIBUTES command.
192 */
193static int sandbox_scmi_base_protocol_attrs(struct udevice *dev,
194					    struct scmi_msg *msg)
195{
196	struct scmi_protocol_attrs_out *out = NULL;
197
198	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
199		return -EINVAL;
200
201	out = (struct scmi_protocol_attrs_out *)msg->out_msg;
202	out->attributes = FIELD_PREP(0xff00, 2) | NUM_PROTOCOLS;
203	out->status = SCMI_SUCCESS;
204
205	return 0;
206}
207
208/**
209 * sandbox_scmi_base_message_attrs - implement
210 *					SCMI_BASE_PROTOCOL_MESSAGE_ATTRIBUTES
211 * @dev:	SCMI device
212 * @msg:	SCMI message
213 *
214 * Implement SCMI_BASE_PROTOCOL_MESSAGE_ATTRIBUTES command.
215 */
216static int sandbox_scmi_base_message_attrs(struct udevice *dev,
217					   struct scmi_msg *msg)
218{
219	u32 message_id;
220	struct scmi_protocol_msg_attrs_out *out = NULL;
221
222	if (!msg->in_msg || msg->in_msg_sz < sizeof(message_id) ||
223	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
224		return -EINVAL;
225
226	message_id = *(u32 *)msg->in_msg;
227	out = (struct scmi_protocol_msg_attrs_out *)msg->out_msg;
228
229	if (message_id >= SCMI_PROTOCOL_VERSION &&
230	    message_id <= SCMI_BASE_RESET_AGENT_CONFIGURATION &&
231	    message_id != SCMI_BASE_NOTIFY_ERRORS) {
232		out->attributes = 0;
233		out->status = SCMI_SUCCESS;
234	} else {
235		out->status = SCMI_NOT_FOUND;
236	}
237
238		return 0;
239}
240
241/**
242 * sandbox_scmi_base_discover_vendor - implement SCMI_BASE_DISCOVER_VENDOR
243 * @dev:	SCMI device
244 * @msg:	SCMI message
245 *
246 * Implement SCMI_BASE_DISCOVER_VENDOR command
247 */
248static int sandbox_scmi_base_discover_vendor(struct udevice *dev,
249					     struct scmi_msg *msg)
250{
251	struct scmi_base_discover_vendor_out *out = NULL;
252
253	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
254		return -EINVAL;
255
256	out = (struct scmi_base_discover_vendor_out *)msg->out_msg;
257	strcpy(out->vendor_identifier, SANDBOX_SCMI_VENDOR);
258	out->status = SCMI_SUCCESS;
259
260	return 0;
261}
262
263/**
264 * sandbox_scmi_base_discover_sub_vendor - implement
265 *						SCMI_BASE_DISCOVER_SUB_VENDOR
266 * @dev:	SCMI device
267 * @msg:	SCMI message
268 *
269 * Implement SCMI_BASE_DISCOVER_SUB_VENDOR command
270 */
271static int sandbox_scmi_base_discover_sub_vendor(struct udevice *dev,
272						 struct scmi_msg *msg)
273{
274	struct scmi_base_discover_vendor_out *out = NULL;
275
276	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
277		return -EINVAL;
278
279	out = (struct scmi_base_discover_vendor_out *)msg->out_msg;
280	strcpy(out->vendor_identifier, SANDBOX_SCMI_SUB_VENDOR);
281	out->status = SCMI_SUCCESS;
282
283	return 0;
284}
285
286/**
287 * sandbox_scmi_base_discover_impl_version - implement
288 *				SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION
289 * @dev:	SCMI device
290 * @msg:	SCMI message
291 *
292 * Implement SCMI_BASE_DISCOVER_IMPLEMENTATION_VERSION command
293 */
294static int sandbox_scmi_base_discover_impl_version(struct udevice *dev,
295						   struct scmi_msg *msg)
296{
297	struct scmi_base_discover_impl_version_out *out = NULL;
298
299	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
300		return -EINVAL;
301
302	out = (struct scmi_base_discover_impl_version_out *)msg->out_msg;
303	out->impl_version = SANDBOX_SCMI_IMPL_VERSION;
304	out->status = SCMI_SUCCESS;
305
306	return 0;
307}
308
309/**
310 * sandbox_scmi_base_discover_list_protocols - implement
311 *					SCMI_BASE_DISCOVER_LIST_PROTOCOLS
312 * @dev:	SCMI device
313 * @msg:	SCMI message
314 *
315 * Implement SCMI_BASE_DISCOVER_LIST_PROTOCOLS command
316 */
317static int sandbox_scmi_base_discover_list_protocols(struct udevice *dev,
318						     struct scmi_msg *msg)
319{
320	struct scmi_base_discover_list_protocols_out *out = NULL;
321
322	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
323		return -EINVAL;
324
325	out = (struct scmi_base_discover_list_protocols_out *)msg->out_msg;
326	memcpy(out->protocols, protocols, sizeof(protocols));
327	out->num_protocols = NUM_PROTOCOLS;
328	out->status = SCMI_SUCCESS;
329
330	return 0;
331}
332
333/**
334 * sandbox_scmi_base_discover_agent - implement SCMI_BASE_DISCOVER_AGENT
335 * @dev:	SCMI device
336 * @msg:	SCMI message
337 *
338 * Implement SCMI_BASE_DISCOVER_AGENT command
339 */
340static int sandbox_scmi_base_discover_agent(struct udevice *dev,
341					    struct scmi_msg *msg)
342{
343	u32 agent_id;
344	struct scmi_base_discover_agent_out *out = NULL;
345
346	if (!msg->in_msg || msg->in_msg_sz < sizeof(agent_id) ||
347	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
348		return -EINVAL;
349
350	agent_id = *(u32 *)msg->in_msg;
351	out = (struct scmi_base_discover_agent_out *)msg->out_msg;
352	out->status = SCMI_SUCCESS;
353	if (agent_id == 0xffffffff || agent_id == 1) {
354		out->agent_id = 1;
355		strcpy(out->name, SANDBOX_SCMI_AGENT_NAME);
356	} else if (!agent_id) {
357		out->agent_id = agent_id;
358		strcpy(out->name, SANDBOX_SCMI_PLATFORM_NAME);
359	} else {
360		out->status = SCMI_NOT_FOUND;
361	}
362
363	return 0;
364}
365
366/**
367 * sandbox_scmi_base_set_device_permissions - implement
368 *						SCMI_BASE_SET_DEVICE_PERMISSIONS
369 * @dev:	SCMI device
370 * @msg:	SCMI message
371 *
372 * Implement SCMI_BASE_SET_DEVICE_PERMISSIONS command
373 */
374static int sandbox_scmi_base_set_device_permissions(struct udevice *dev,
375						    struct scmi_msg *msg)
376{
377	struct scmi_base_set_device_permissions_in *in = NULL;
378	u32 *status;
379
380	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
381	    !msg->out_msg || msg->out_msg_sz < sizeof(*status))
382		return -EINVAL;
383
384	in = (struct scmi_base_set_device_permissions_in *)msg->in_msg;
385	status = (u32 *)msg->out_msg;
386
387	if (in->agent_id != 1 || in->device_id != 0)
388		*status = SCMI_NOT_FOUND;
389	else if (in->flags & ~SCMI_BASE_SET_DEVICE_PERMISSIONS_ACCESS)
390		*status = SCMI_INVALID_PARAMETERS;
391	else if (in->flags & SCMI_BASE_SET_DEVICE_PERMISSIONS_ACCESS)
392		*status = SCMI_SUCCESS;
393	else
394		/* unset not allowed */
395		*status = SCMI_DENIED;
396
397	return 0;
398}
399
400/**
401 * sandbox_scmi_base_set_protocol_permissions - implement
402 *					SCMI_BASE_SET_PROTOCOL_PERMISSIONS
403 * @dev:	SCMI device
404 * @msg:	SCMI message
405 *
406 * Implement SCMI_BASE_SET_PROTOCOL_PERMISSIONS command
407 */
408static int sandbox_scmi_base_set_protocol_permissions(struct udevice *dev,
409						      struct scmi_msg *msg)
410{
411	struct scmi_base_set_protocol_permissions_in *in = NULL;
412	u32 *status;
413	int i;
414
415	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
416	    !msg->out_msg || msg->out_msg_sz < sizeof(*status))
417		return -EINVAL;
418
419	in = (struct scmi_base_set_protocol_permissions_in *)msg->in_msg;
420	status = (u32 *)msg->out_msg;
421
422	for (i = 0; i < ARRAY_SIZE(protocols); i++)
423		if (protocols[i] == in->command_id)
424			break;
425	if (in->agent_id != 1 || in->device_id != 0 ||
426	    i == ARRAY_SIZE(protocols))
427		*status = SCMI_NOT_FOUND;
428	else if (in->flags & ~SCMI_BASE_SET_PROTOCOL_PERMISSIONS_ACCESS)
429		*status = SCMI_INVALID_PARAMETERS;
430	else if (in->flags & SCMI_BASE_SET_PROTOCOL_PERMISSIONS_ACCESS)
431		*status = SCMI_SUCCESS;
432	else
433		/* unset not allowed */
434		*status = SCMI_DENIED;
435
436	return 0;
437}
438
439/**
440 * sandbox_scmi_base_reset_agent_configuration - implement
441 *					SCMI_BASE_RESET_AGENT_CONFIGURATION
442 * @dev:	SCMI device
443 * @msg:	SCMI message
444 *
445 * Implement SCMI_BASE_RESET_AGENT_CONFIGURATION command
446 */
447static int sandbox_scmi_base_reset_agent_configuration(struct udevice *dev,
448						       struct scmi_msg *msg)
449{
450	struct scmi_base_reset_agent_configuration_in *in = NULL;
451	u32 *status;
452
453	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
454	    !msg->out_msg || msg->out_msg_sz < sizeof(*status))
455		return -EINVAL;
456
457	in = (struct scmi_base_reset_agent_configuration_in *)msg->in_msg;
458	status = (u32 *)msg->out_msg;
459
460	if (in->agent_id != 1)
461		*status = SCMI_NOT_FOUND;
462	else if (in->flags & ~SCMI_BASE_RESET_ALL_ACCESS_PERMISSIONS)
463		*status = SCMI_INVALID_PARAMETERS;
464	else
465		*status = SCMI_DENIED;
466
467	return 0;
468}
469
470/* Power Domain Management Protocol */
471
472/**
473 * sandbox_scmi_pwd_protocol_version - implement SCMI_PROTOCOL_VERSION
474 * @dev:	SCMI device
475 * @msg:	SCMI message
476 *
477 * Implement SCMI_PROTOCOL_VERSION command.
478 *
479 * Return:	0 on success, error code on failure
480 */
481static int sandbox_scmi_pwd_protocol_version(struct udevice *dev,
482					     struct scmi_msg *msg)
483{
484	struct scmi_protocol_version_out *out = NULL;
485
486	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
487		return -EINVAL;
488
489	out = (struct scmi_protocol_version_out *)msg->out_msg;
490	out->version = SANDBOX_SCMI_PWD_PROTOCOL_VERSION;
491	out->status = SCMI_SUCCESS;
492
493	return 0;
494}
495
496/**
497 * sandbox_scmi_pwd_protocol_attribs - implement SCMI_PWD_PROTOCOL_ATTRS
498 * @dev:	SCMI device
499 * @msg:	SCMI message
500 *
501 * Implement SCMI_PWD_PROTOCOL_ATTRS command.
502 *
503 * Return:	0 on success, error code on failure
504 */
505static int sandbox_scmi_pwd_protocol_attribs(struct udevice *dev,
506					     struct scmi_msg *msg)
507{
508	struct scmi_pwd_protocol_attrs_out *out;
509
510	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
511		return -EINVAL;
512
513	out = (struct scmi_pwd_protocol_attrs_out *)msg->out_msg;
514
515	out->attributes = ARRAY_SIZE(scmi_pwdom);
516	out->stats_addr_low = 0;
517	out->stats_addr_high = 0;
518	out->stats_len = 0;
519	out->status = SCMI_SUCCESS;
520
521	return 0;
522}
523
524/**
525 * sandbox_scmi_pwd_protocol_msg_attribs - implement
526					SCMI_PWD_PROTOCOL_MESSAGE_ATTRS
527 * @dev:	SCMI device
528 * @msg:	SCMI message
529 *
530 * Implement SCMI_PWD_PROTOCOL_MESSAGE_ATTRS command.
531 *
532 * Return:	0 on success, error code on failure
533 */
534static int sandbox_scmi_pwd_protocol_msg_attribs(struct udevice *dev,
535						 struct scmi_msg *msg)
536{
537	u32 message_id;
538	struct scmi_pwd_protocol_msg_attrs_out *out;
539
540	if (!msg->in_msg || msg->in_msg_sz < sizeof(message_id) ||
541	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
542		return -EINVAL;
543
544	message_id = *(u32 *)msg->in_msg;
545
546	out = (struct scmi_pwd_protocol_msg_attrs_out *)msg->out_msg;
547	if (message_id <= SCMI_PWD_STATE_GET ||
548	    message_id == SCMI_PWD_NAME_GET) {
549		out->attributes = 0;
550		out->status = SCMI_SUCCESS;
551	} else {
552		out->status = SCMI_NOT_FOUND;
553	}
554
555	return 0;
556}
557
558/**
559 * sandbox_scmi_pwd_attribs - implement SCMI_PWD_ATTRS
560 * @dev:	SCMI device
561 * @msg:	SCMI message
562 *
563 * Implement SCMI_PWD_ATTRS command.
564 *
565 * Return:	0 on success, error code on failure
566 */
567static int sandbox_scmi_pwd_attribs(struct udevice *dev, struct scmi_msg *msg)
568{
569	u32 domain_id;
570	struct scmi_pwd_attrs_out *out;
571
572	if (!msg->in_msg || msg->in_msg_sz < sizeof(domain_id) ||
573	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
574		return -EINVAL;
575
576	domain_id = *(u32 *)msg->in_msg;
577	out = (struct scmi_pwd_attrs_out *)msg->out_msg;
578
579	if (domain_id >= ARRAY_SIZE(scmi_pwdom)) {
580		out->status = SCMI_NOT_FOUND;
581
582		return 0;
583	}
584
585	out->attributes =
586		SCMI_PWD_ATTR_PSTATE_SYNC | SCMI_PWD_ATTR_EXTENDED_NAME;
587	/* just 15-char + NULL */
588	snprintf(out->name, SCMI_PWD_NAME_LENGTH_MAX, "power-domain--%d",
589		 domain_id);
590	out->status = SCMI_SUCCESS;
591
592	return 0;
593}
594
595/**
596 * sandbox_scmi_pwd_state_set - implement SCMI_PWD_STATE_SET
597 * @dev:	SCMI device
598 * @msg:	SCMI message
599 *
600 * Implement SCMI_PWD_STATE_SET command.
601 *
602 * Return:	0 on success, error code on failure
603 */
604static int sandbox_scmi_pwd_state_set(struct udevice *dev, struct scmi_msg *msg)
605{
606	struct scmi_pwd_state_set_in *in;
607	s32 *status;
608
609	if (!msg->in_msg || msg->in_msg_sz < sizeof(in) ||
610	    !msg->out_msg || msg->out_msg_sz < sizeof(*status))
611		return -EINVAL;
612
613	in = (struct scmi_pwd_state_set_in *)msg->in_msg;
614	status = (s32 *)msg->out_msg;
615
616	if (in->domain_id >= ARRAY_SIZE(scmi_pwdom)) {
617		*status = SCMI_NOT_FOUND;
618
619		return 0;
620	}
621
622	if ((in->flags & SCMI_PWD_SET_FLAGS_ASYNC) ||
623	    (in->pstate != SCMI_PWD_PSTATE_TYPE_LOST && in->pstate)) {
624		*status = SCMI_INVALID_PARAMETERS;
625
626		return 0;
627	}
628
629	scmi_pwdom[in->domain_id].pstate = in->pstate;
630	*status = SCMI_SUCCESS;
631
632	return 0;
633}
634
635/**
636 * sandbox_scmi_pwd_state_get - implement SCMI_PWD_STATE_GET
637 * @dev:	SCMI device
638 * @msg:	SCMI message
639 *
640 * Implement SCMI_PWD_STATE_GET command.
641 *
642 * Return:	0 on success, error code on failure
643 */
644static int sandbox_scmi_pwd_state_get(struct udevice *dev, struct scmi_msg *msg)
645{
646	u32 domain_id;
647	struct scmi_pwd_state_get_out *out;
648
649	if (!msg->in_msg || msg->in_msg_sz < sizeof(domain_id) ||
650	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
651		return -EINVAL;
652
653	domain_id = *(u32 *)msg->in_msg;
654	out = (struct scmi_pwd_state_get_out *)msg->out_msg;
655
656	if (domain_id >= ARRAY_SIZE(scmi_pwdom)) {
657		out->status = SCMI_NOT_FOUND;
658
659		return 0;
660	}
661
662	out->pstate = scmi_pwdom[domain_id].pstate;
663	out->status = SCMI_SUCCESS;
664
665	return 0;
666}
667
668/**
669 * sandbox_scmi_pwd_name_get - implement SCMI_PWD_NAME_GET
670 * @dev:	SCMI device
671 * @msg:	SCMI message
672 *
673 * Implement SCMI_PWD_NAME_GET command.
674 *
675 * Return:	0 on success, error code on failure
676 */
677static int sandbox_scmi_pwd_name_get(struct udevice *dev, struct scmi_msg *msg)
678{
679	u32 domain_id;
680	struct scmi_pwd_name_get_out *out;
681
682	if (!msg->in_msg || msg->in_msg_sz < sizeof(domain_id) ||
683	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
684		return -EINVAL;
685
686	domain_id = *(u32 *)msg->in_msg;
687	out = (struct scmi_pwd_name_get_out *)msg->out_msg;
688
689	if (domain_id >= ARRAY_SIZE(scmi_pwdom)) {
690		out->status = SCMI_NOT_FOUND;
691
692		return 0;
693	}
694
695	snprintf(out->extended_name, SCMI_PWD_EXTENDED_NAME_MAX,
696		 "power-domain--%d-extended", domain_id);
697	out->status = SCMI_SUCCESS;
698
699	return 0;
700}
701
702/* Clock Protocol */
703
704static int sandbox_scmi_clock_protocol_attribs(struct udevice *dev,
705					       struct scmi_msg *msg)
706{
707	struct scmi_clk_protocol_attr_out *out = NULL;
708
709	if (!msg->out_msg || msg->out_msg_sz < sizeof(*out))
710		return -EINVAL;
711
712	out = (struct scmi_clk_protocol_attr_out *)msg->out_msg;
713	out->attributes = ARRAY_SIZE(scmi_clk);
714	out->status = SCMI_SUCCESS;
715
716	return 0;
717}
718
719static int sandbox_scmi_clock_attribs(struct udevice *dev, struct scmi_msg *msg)
720{
721	struct scmi_clk_attribute_in *in = NULL;
722	struct scmi_clk_attribute_out *out = NULL;
723	struct sandbox_scmi_clk *clk_state = NULL;
724	int ret;
725
726	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
727	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
728		return -EINVAL;
729
730	in = (struct scmi_clk_attribute_in *)msg->in_msg;
731	out = (struct scmi_clk_attribute_out *)msg->out_msg;
732
733	clk_state = get_scmi_clk_state(in->clock_id);
734	if (!clk_state) {
735		dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
736
737		out->status = SCMI_NOT_FOUND;
738	} else {
739		memset(out, 0, sizeof(*out));
740
741		if (clk_state->enabled)
742			out->attributes = 1;
743
744		ret = snprintf(out->clock_name, sizeof(out->clock_name),
745			       "clk%u", in->clock_id);
746		assert(ret > 0 && ret < sizeof(out->clock_name));
747
748		out->status = SCMI_SUCCESS;
749	}
750
751	return 0;
752}
753static int sandbox_scmi_clock_rate_set(struct udevice *dev,
754				       struct scmi_msg *msg)
755{
756	struct scmi_clk_rate_set_in *in = NULL;
757	struct scmi_clk_rate_set_out *out = NULL;
758	struct sandbox_scmi_clk *clk_state = NULL;
759
760	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
761	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
762		return -EINVAL;
763
764	in = (struct scmi_clk_rate_set_in *)msg->in_msg;
765	out = (struct scmi_clk_rate_set_out *)msg->out_msg;
766
767	clk_state = get_scmi_clk_state(in->clock_id);
768	if (!clk_state) {
769		dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
770
771		out->status = SCMI_NOT_FOUND;
772	} else {
773		u64 rate = ((u64)in->rate_msb << 32) + in->rate_lsb;
774
775		clk_state->rate = (ulong)rate;
776
777		out->status = SCMI_SUCCESS;
778	}
779
780	return 0;
781}
782
783static int sandbox_scmi_clock_rate_get(struct udevice *dev,
784				       struct scmi_msg *msg)
785{
786	struct scmi_clk_rate_get_in *in = NULL;
787	struct scmi_clk_rate_get_out *out = NULL;
788	struct sandbox_scmi_clk *clk_state = NULL;
789
790	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
791	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
792		return -EINVAL;
793
794	in = (struct scmi_clk_rate_get_in *)msg->in_msg;
795	out = (struct scmi_clk_rate_get_out *)msg->out_msg;
796
797	clk_state = get_scmi_clk_state(in->clock_id);
798	if (!clk_state) {
799		dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
800
801		out->status = SCMI_NOT_FOUND;
802	} else {
803		out->rate_msb = (u32)((u64)clk_state->rate >> 32);
804		out->rate_lsb = (u32)clk_state->rate;
805
806		out->status = SCMI_SUCCESS;
807	}
808
809	return 0;
810}
811
812static int sandbox_scmi_clock_gate(struct udevice *dev, struct scmi_msg *msg)
813{
814	struct scmi_clk_state_in *in = NULL;
815	struct scmi_clk_state_out *out = NULL;
816	struct sandbox_scmi_clk *clk_state = NULL;
817
818	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
819	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
820		return -EINVAL;
821
822	in = (struct scmi_clk_state_in *)msg->in_msg;
823	out = (struct scmi_clk_state_out *)msg->out_msg;
824
825	clk_state = get_scmi_clk_state(in->clock_id);
826	if (!clk_state) {
827		dev_err(dev, "Unexpected clock ID %u\n", in->clock_id);
828
829		out->status = SCMI_NOT_FOUND;
830	} else if (in->attributes > 1) {
831		out->status = SCMI_PROTOCOL_ERROR;
832	} else {
833		clk_state->enabled = in->attributes;
834
835		out->status = SCMI_SUCCESS;
836	}
837
838	return 0;
839}
840
841static int sandbox_scmi_rd_attribs(struct udevice *dev, struct scmi_msg *msg)
842{
843	struct scmi_rd_attr_in *in = NULL;
844	struct scmi_rd_attr_out *out = NULL;
845	struct sandbox_scmi_reset *reset_state = NULL;
846
847	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
848	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
849		return -EINVAL;
850
851	in = (struct scmi_rd_attr_in *)msg->in_msg;
852	out = (struct scmi_rd_attr_out *)msg->out_msg;
853
854	reset_state = get_scmi_reset_state(in->domain_id);
855	if (!reset_state) {
856		dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id);
857
858		out->status = SCMI_NOT_FOUND;
859	} else {
860		memset(out, 0, sizeof(*out));
861		snprintf(out->name, sizeof(out->name), "rd%u", in->domain_id);
862
863		out->status = SCMI_SUCCESS;
864	}
865
866	return 0;
867}
868
869static int sandbox_scmi_rd_reset(struct udevice *dev, struct scmi_msg *msg)
870{
871	struct scmi_rd_reset_in *in = NULL;
872	struct scmi_rd_reset_out *out = NULL;
873	struct sandbox_scmi_reset *reset_state = NULL;
874
875	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
876	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
877		return -EINVAL;
878
879	in = (struct scmi_rd_reset_in *)msg->in_msg;
880	out = (struct scmi_rd_reset_out *)msg->out_msg;
881
882	reset_state = get_scmi_reset_state(in->domain_id);
883	if (!reset_state) {
884		dev_err(dev, "Unexpected reset domain ID %u\n", in->domain_id);
885
886		out->status = SCMI_NOT_FOUND;
887	} else if (in->reset_state > 1) {
888		dev_err(dev, "Invalid reset domain input attribute value\n");
889
890		out->status = SCMI_INVALID_PARAMETERS;
891	} else {
892		if (in->flags & SCMI_RD_RESET_FLAG_CYCLE) {
893			if (in->flags & SCMI_RD_RESET_FLAG_ASYNC) {
894				out->status = SCMI_NOT_SUPPORTED;
895			} else {
896				/* Ends deasserted whatever current state */
897				reset_state->asserted = false;
898				out->status = SCMI_SUCCESS;
899			}
900		} else {
901			reset_state->asserted = in->flags &
902						SCMI_RD_RESET_FLAG_ASSERT;
903
904			out->status = SCMI_SUCCESS;
905		}
906	}
907
908	return 0;
909}
910
911static int sandbox_scmi_voltd_attribs(struct udevice *dev, struct scmi_msg *msg)
912{
913	struct scmi_voltd_attr_in *in = NULL;
914	struct scmi_voltd_attr_out *out = NULL;
915	struct sandbox_scmi_voltd *voltd_state = NULL;
916
917	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
918	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
919		return -EINVAL;
920
921	in = (struct scmi_voltd_attr_in *)msg->in_msg;
922	out = (struct scmi_voltd_attr_out *)msg->out_msg;
923
924	voltd_state = get_scmi_voltd_state(in->domain_id);
925	if (!voltd_state) {
926		dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
927
928		out->status = SCMI_NOT_FOUND;
929	} else {
930		memset(out, 0, sizeof(*out));
931		snprintf(out->name, sizeof(out->name), "regu%u", in->domain_id);
932
933		out->status = SCMI_SUCCESS;
934	}
935
936	return 0;
937}
938
939static int sandbox_scmi_voltd_config_set(struct udevice *dev,
940					 struct scmi_msg *msg)
941{
942	struct scmi_voltd_config_set_in *in = NULL;
943	struct scmi_voltd_config_set_out *out = NULL;
944	struct sandbox_scmi_voltd *voltd_state = NULL;
945
946	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
947	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
948		return -EINVAL;
949
950	in = (struct scmi_voltd_config_set_in *)msg->in_msg;
951	out = (struct scmi_voltd_config_set_out *)msg->out_msg;
952
953	voltd_state = get_scmi_voltd_state(in->domain_id);
954	if (!voltd_state) {
955		dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
956
957		out->status = SCMI_NOT_FOUND;
958	} else if (in->config & ~SCMI_VOLTD_CONFIG_MASK) {
959		dev_err(dev, "Invalid config value 0x%x\n", in->config);
960
961		out->status = SCMI_INVALID_PARAMETERS;
962	} else if (in->config != SCMI_VOLTD_CONFIG_ON &&
963		   in->config != SCMI_VOLTD_CONFIG_OFF) {
964		dev_err(dev, "Unexpected custom value 0x%x\n", in->config);
965
966		out->status = SCMI_INVALID_PARAMETERS;
967	} else {
968		voltd_state->enabled = in->config == SCMI_VOLTD_CONFIG_ON;
969		out->status = SCMI_SUCCESS;
970	}
971
972	return 0;
973}
974
975static int sandbox_scmi_voltd_config_get(struct udevice *dev,
976					 struct scmi_msg *msg)
977{
978	struct scmi_voltd_config_get_in *in = NULL;
979	struct scmi_voltd_config_get_out *out = NULL;
980	struct sandbox_scmi_voltd *voltd_state = NULL;
981
982	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
983	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
984		return -EINVAL;
985
986	in = (struct scmi_voltd_config_get_in *)msg->in_msg;
987	out = (struct scmi_voltd_config_get_out *)msg->out_msg;
988
989	voltd_state = get_scmi_voltd_state(in->domain_id);
990	if (!voltd_state) {
991		dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
992
993		out->status = SCMI_NOT_FOUND;
994	} else {
995		if (voltd_state->enabled)
996			out->config = SCMI_VOLTD_CONFIG_ON;
997		else
998			out->config = SCMI_VOLTD_CONFIG_OFF;
999
1000		out->status = SCMI_SUCCESS;
1001	}
1002
1003	return 0;
1004}
1005
1006static int sandbox_scmi_voltd_level_set(struct udevice *dev,
1007					 struct scmi_msg *msg)
1008{
1009	struct scmi_voltd_level_set_in *in = NULL;
1010	struct scmi_voltd_level_set_out *out = NULL;
1011	struct sandbox_scmi_voltd *voltd_state = NULL;
1012
1013	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
1014	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
1015		return -EINVAL;
1016
1017	in = (struct scmi_voltd_level_set_in *)msg->in_msg;
1018	out = (struct scmi_voltd_level_set_out *)msg->out_msg;
1019
1020	voltd_state = get_scmi_voltd_state(in->domain_id);
1021	if (!voltd_state) {
1022		dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
1023
1024		out->status = SCMI_NOT_FOUND;
1025	} else {
1026		voltd_state->voltage_uv = in->voltage_level;
1027		out->status = SCMI_SUCCESS;
1028	}
1029
1030	return 0;
1031}
1032
1033static int sandbox_scmi_voltd_level_get(struct udevice *dev,
1034					struct scmi_msg *msg)
1035{
1036	struct scmi_voltd_level_get_in *in = NULL;
1037	struct scmi_voltd_level_get_out *out = NULL;
1038	struct sandbox_scmi_voltd *voltd_state = NULL;
1039
1040	if (!msg->in_msg || msg->in_msg_sz < sizeof(*in) ||
1041	    !msg->out_msg || msg->out_msg_sz < sizeof(*out))
1042		return -EINVAL;
1043
1044	in = (struct scmi_voltd_level_get_in *)msg->in_msg;
1045	out = (struct scmi_voltd_level_get_out *)msg->out_msg;
1046
1047	voltd_state = get_scmi_voltd_state(in->domain_id);
1048	if (!voltd_state) {
1049		dev_err(dev, "Unexpected domain ID %u\n", in->domain_id);
1050
1051		out->status = SCMI_NOT_FOUND;
1052	} else {
1053		out->voltage_level = voltd_state->voltage_uv;
1054		out->status = SCMI_SUCCESS;
1055	}
1056
1057	return 0;
1058}
1059
1060/**
1061 * sandbox_scmi_of_get_channel - assigne a channel
1062 * @dev:	SCMI agent device
1063 * @protocol:	SCMI protocol device
1064 * @channel:	Pointer to channel info
1065 *
1066 * Assign a channel for the protocol, @protocol, in @channel,
1067 * based on a device tree's property.
1068 *
1069 * Return: 0 on success, error code on failure
1070 */
1071static int sandbox_scmi_of_get_channel(struct udevice *dev,
1072				       struct udevice *protocol,
1073				       struct scmi_channel **channel)
1074{
1075	struct sandbox_channel *agent_chan = dev_get_plat(dev);
1076	struct sandbox_channel *chan;
1077	u32 channel_id;
1078
1079	if (dev_read_u32(protocol, "linaro,sandbox-channel-id", &channel_id)) {
1080		/* Uses agent channel */
1081		*channel = container_of(agent_chan, struct scmi_channel, ref);
1082
1083		return 0;
1084	}
1085
1086	/* Setup a dedicated channel */
1087	chan = calloc(1, sizeof(*chan));
1088	if (!chan)
1089		return -ENOMEM;
1090
1091	chan->channel_id = channel_id;
1092
1093	*channel = container_of(chan, struct scmi_channel, ref);
1094
1095	return 0;
1096}
1097
1098/**
1099 * sandbox_scmi_of_to_plat - assigne a channel to agent
1100 * @dev:	SCMI agent device
1101 *
1102 * Assign a channel for the agent, @protocol.
1103 *
1104 * Return: always 0
1105 */
1106static int sandbox_scmi_of_to_plat(struct udevice *dev)
1107{
1108	struct sandbox_channel *chan = dev_get_plat(dev);
1109
1110	/* The channel for agent is always 0 */
1111	chan->channel_id = 0;
1112
1113	return 0;
1114}
1115
1116unsigned int sandbox_scmi_channel_id(struct udevice *dev)
1117{
1118	struct scmi_agent_proto_priv *priv;
1119	struct sandbox_channel *chan;
1120
1121	priv = dev_get_parent_priv(dev);
1122	chan = (struct sandbox_channel *)&priv->channel->ref;
1123
1124	return chan->channel_id;
1125}
1126
1127static int sandbox_proto_not_supported(struct scmi_msg *msg)
1128{
1129	*(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED;
1130
1131	return 0;
1132}
1133
1134static int sandbox_scmi_test_process_msg(struct udevice *dev,
1135					 struct scmi_channel *channel,
1136					 struct scmi_msg *msg)
1137{
1138	switch (msg->protocol_id) {
1139	case SCMI_PROTOCOL_ID_BASE:
1140		switch (msg->message_id) {
1141		case SCMI_PROTOCOL_VERSION:
1142			return sandbox_scmi_base_protocol_version(dev, msg);
1143		case SCMI_PROTOCOL_ATTRIBUTES:
1144			return sandbox_scmi_base_protocol_attrs(dev, msg);
1145		case SCMI_PROTOCOL_MESSAGE_ATTRIBUTES:
1146			return sandbox_scmi_base_message_attrs(dev, msg);
1147		case SCMI_BASE_DISCOVER_VENDOR:
1148			return sandbox_scmi_base_discover_vendor(dev, msg);
1149		case SCMI_BASE_DISCOVER_SUB_VENDOR:
1150			return sandbox_scmi_base_discover_sub_vendor(dev, msg);
1151		case SCMI_BASE_DISCOVER_IMPL_VERSION:
1152			return sandbox_scmi_base_discover_impl_version(dev, msg);
1153		case SCMI_BASE_DISCOVER_LIST_PROTOCOLS:
1154			return sandbox_scmi_base_discover_list_protocols(dev, msg);
1155		case SCMI_BASE_DISCOVER_AGENT:
1156			return sandbox_scmi_base_discover_agent(dev, msg);
1157		case SCMI_BASE_NOTIFY_ERRORS:
1158			break;
1159		case SCMI_BASE_SET_DEVICE_PERMISSIONS:
1160			return sandbox_scmi_base_set_device_permissions(dev, msg);
1161		case SCMI_BASE_SET_PROTOCOL_PERMISSIONS:
1162			return sandbox_scmi_base_set_protocol_permissions(dev, msg);
1163		case SCMI_BASE_RESET_AGENT_CONFIGURATION:
1164			return sandbox_scmi_base_reset_agent_configuration(dev, msg);
1165		default:
1166			break;
1167		}
1168		break;
1169	case SCMI_PROTOCOL_ID_POWER_DOMAIN:
1170		if (!CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN))
1171			return sandbox_proto_not_supported(msg);
1172
1173		switch (msg->message_id) {
1174		case SCMI_PROTOCOL_VERSION:
1175			return sandbox_scmi_pwd_protocol_version(dev, msg);
1176		case SCMI_PROTOCOL_ATTRIBUTES:
1177			return sandbox_scmi_pwd_protocol_attribs(dev, msg);
1178		case SCMI_PROTOCOL_MESSAGE_ATTRIBUTES:
1179			return sandbox_scmi_pwd_protocol_msg_attribs(dev, msg);
1180		case SCMI_PWD_ATTRIBUTES:
1181			return sandbox_scmi_pwd_attribs(dev, msg);
1182		case SCMI_PWD_STATE_SET:
1183			return sandbox_scmi_pwd_state_set(dev, msg);
1184		case SCMI_PWD_STATE_GET:
1185			return sandbox_scmi_pwd_state_get(dev, msg);
1186		case SCMI_PWD_NAME_GET:
1187			return sandbox_scmi_pwd_name_get(dev, msg);
1188		default:
1189			break;
1190		}
1191		break;
1192	case SCMI_PROTOCOL_ID_CLOCK:
1193		if (!CONFIG_IS_ENABLED(CLK_SCMI))
1194			return sandbox_proto_not_supported(msg);
1195
1196		switch (msg->message_id) {
1197		case SCMI_PROTOCOL_ATTRIBUTES:
1198			return sandbox_scmi_clock_protocol_attribs(dev, msg);
1199		case SCMI_CLOCK_ATTRIBUTES:
1200			return sandbox_scmi_clock_attribs(dev, msg);
1201		case SCMI_CLOCK_RATE_SET:
1202			return sandbox_scmi_clock_rate_set(dev, msg);
1203		case SCMI_CLOCK_RATE_GET:
1204			return sandbox_scmi_clock_rate_get(dev, msg);
1205		case SCMI_CLOCK_CONFIG_SET:
1206			return sandbox_scmi_clock_gate(dev, msg);
1207		default:
1208			break;
1209		}
1210		break;
1211	case SCMI_PROTOCOL_ID_RESET_DOMAIN:
1212		if (!CONFIG_IS_ENABLED(RESET_SCMI))
1213			return sandbox_proto_not_supported(msg);
1214
1215		switch (msg->message_id) {
1216		case SCMI_RESET_DOMAIN_ATTRIBUTES:
1217			return sandbox_scmi_rd_attribs(dev, msg);
1218		case SCMI_RESET_DOMAIN_RESET:
1219			return sandbox_scmi_rd_reset(dev, msg);
1220		default:
1221			break;
1222		}
1223		break;
1224	case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
1225		if (!CONFIG_IS_ENABLED(DM_REGULATOR_SCMI))
1226			return sandbox_proto_not_supported(msg);
1227
1228		switch (msg->message_id) {
1229		case SCMI_VOLTAGE_DOMAIN_ATTRIBUTES:
1230			return sandbox_scmi_voltd_attribs(dev, msg);
1231		case SCMI_VOLTAGE_DOMAIN_CONFIG_SET:
1232			return sandbox_scmi_voltd_config_set(dev, msg);
1233		case SCMI_VOLTAGE_DOMAIN_CONFIG_GET:
1234			return sandbox_scmi_voltd_config_get(dev, msg);
1235		case SCMI_VOLTAGE_DOMAIN_LEVEL_SET:
1236			return sandbox_scmi_voltd_level_set(dev, msg);
1237		case SCMI_VOLTAGE_DOMAIN_LEVEL_GET:
1238			return sandbox_scmi_voltd_level_get(dev, msg);
1239		default:
1240			break;
1241		}
1242		break;
1243	case SCMI_PROTOCOL_ID_SYSTEM:
1244	case SCMI_PROTOCOL_ID_PERF:
1245	case SCMI_PROTOCOL_ID_SENSOR:
1246		return sandbox_proto_not_supported(msg);
1247	default:
1248		break;
1249	}
1250
1251	dev_err(dev, "%s(%s): Unhandled protocol_id %#x/message_id %#x\n",
1252		__func__, dev->name, msg->protocol_id, msg->message_id);
1253
1254	if (msg->out_msg_sz < sizeof(u32))
1255		return -EINVAL;
1256
1257	/* Intentionnaly report unhandled IDs through the SCMI return code */
1258	*(u32 *)msg->out_msg = SCMI_PROTOCOL_ERROR;
1259	return 0;
1260}
1261
1262static int sandbox_scmi_test_remove(struct udevice *dev)
1263{
1264	debug_print_agent_state(dev, "removed");
1265
1266	return 0;
1267}
1268
1269static int sandbox_scmi_test_probe(struct udevice *dev)
1270{
1271	struct sandbox_scmi_agent *agent = dev_get_priv(dev);
1272
1273	*agent = (struct sandbox_scmi_agent){
1274		.pwdom_version = SANDBOX_SCMI_PWD_PROTOCOL_VERSION,
1275		.pwdom = scmi_pwdom,
1276		.pwdom_count = ARRAY_SIZE(scmi_pwdom),
1277		.clk = scmi_clk,
1278		.clk_count = ARRAY_SIZE(scmi_clk),
1279		.reset = scmi_reset,
1280		.reset_count = ARRAY_SIZE(scmi_reset),
1281		.voltd = scmi_voltd,
1282		.voltd_count = ARRAY_SIZE(scmi_voltd),
1283	};
1284
1285	debug_print_agent_state(dev, "probed");
1286
1287	return 0;
1288};
1289
1290static const struct udevice_id sandbox_scmi_test_ids[] = {
1291	{ .compatible = "sandbox,scmi-agent" },
1292	{ }
1293};
1294
1295struct scmi_agent_ops sandbox_scmi_test_ops = {
1296	.of_get_channel = sandbox_scmi_of_get_channel,
1297	.process_msg = sandbox_scmi_test_process_msg,
1298};
1299
1300U_BOOT_DRIVER(sandbox_scmi_agent) = {
1301	.name = "sandbox-scmi_agent",
1302	.id = UCLASS_SCMI_AGENT,
1303	.of_match = sandbox_scmi_test_ids,
1304	.priv_auto	= sizeof(struct sandbox_scmi_agent),
1305	.plat_auto	= sizeof(struct sandbox_channel),
1306	.of_to_plat	= sandbox_scmi_of_to_plat,
1307	.probe = sandbox_scmi_test_probe,
1308	.remove = sandbox_scmi_test_remove,
1309	.ops = &sandbox_scmi_test_ops,
1310};
1311