xref: /rk3399_ARM-atf/drivers/scmi-msg/entry.c (revision 0dc9f52a2a9f0b9686c65dd60c84e0bcca552144)
1b4734308SPeng Fan // SPDX-License-Identifier: BSD-3-Clause
2b4734308SPeng Fan /*
3*0dc9f52aSYann Gautier  * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
4b4734308SPeng Fan  * Copyright (c) 2019-2020, Linaro Limited
5b4734308SPeng Fan  */
6b4734308SPeng Fan 
7b4734308SPeng Fan #include <assert.h>
8b4734308SPeng Fan 
9b4734308SPeng Fan #include <drivers/scmi-msg.h>
10b4734308SPeng Fan #include <drivers/scmi.h>
11b4734308SPeng Fan 
12b4734308SPeng Fan #include "common.h"
13b4734308SPeng Fan 
14b3c8fd5dSPeng Fan #pragma weak scmi_msg_get_clock_handler
15b3c8fd5dSPeng Fan #pragma weak scmi_msg_get_rstd_handler
16b3c8fd5dSPeng Fan #pragma weak scmi_msg_get_pd_handler
17b3c8fd5dSPeng Fan #pragma weak scmi_msg_get_voltage_handler
18b3c8fd5dSPeng Fan 
19b3c8fd5dSPeng Fan scmi_msg_handler_t scmi_msg_get_clock_handler(struct scmi_msg *msg __unused)
20b3c8fd5dSPeng Fan {
21b3c8fd5dSPeng Fan 	return NULL;
22b3c8fd5dSPeng Fan }
23b3c8fd5dSPeng Fan 
24b3c8fd5dSPeng Fan scmi_msg_handler_t scmi_msg_get_rstd_handler(struct scmi_msg *msg __unused)
25b3c8fd5dSPeng Fan {
26b3c8fd5dSPeng Fan 	return NULL;
27b3c8fd5dSPeng Fan }
28b3c8fd5dSPeng Fan 
29b3c8fd5dSPeng Fan scmi_msg_handler_t scmi_msg_get_pd_handler(struct scmi_msg *msg __unused)
30b3c8fd5dSPeng Fan {
31b3c8fd5dSPeng Fan 	return NULL;
32b3c8fd5dSPeng Fan }
33b3c8fd5dSPeng Fan 
34b3c8fd5dSPeng Fan scmi_msg_handler_t scmi_msg_get_voltage_handler(struct scmi_msg *msg __unused)
35b3c8fd5dSPeng Fan {
36b3c8fd5dSPeng Fan 	return NULL;
37b3c8fd5dSPeng Fan }
38b3c8fd5dSPeng Fan 
39b4734308SPeng Fan void scmi_status_response(struct scmi_msg *msg, int32_t status)
40b4734308SPeng Fan {
41b4734308SPeng Fan 	assert(msg->out && msg->out_size >= sizeof(int32_t));
42b4734308SPeng Fan 
43b4734308SPeng Fan 	memcpy(msg->out, &status, sizeof(int32_t));
44b4734308SPeng Fan 	msg->out_size_out = sizeof(int32_t);
45b4734308SPeng Fan }
46b4734308SPeng Fan 
47b4734308SPeng Fan void scmi_write_response(struct scmi_msg *msg, void *payload, size_t size)
48b4734308SPeng Fan {
49b4734308SPeng Fan 	/*
50b4734308SPeng Fan 	 * Output payload shall be at least the size of the status
51b4734308SPeng Fan 	 * Output buffer shall be at least be the size of the status
52b4734308SPeng Fan 	 * Output paylaod shall fit in output buffer
53b4734308SPeng Fan 	 */
54b4734308SPeng Fan 	assert(payload && size >= sizeof(int32_t) && size <= msg->out_size &&
55b4734308SPeng Fan 	       msg->out && msg->out_size >= sizeof(int32_t));
56b4734308SPeng Fan 
57b4734308SPeng Fan 	memcpy(msg->out, payload, size);
58b4734308SPeng Fan 	msg->out_size_out = size;
59b4734308SPeng Fan }
60b4734308SPeng Fan 
61b4734308SPeng Fan void scmi_process_message(struct scmi_msg *msg)
62b4734308SPeng Fan {
63b4734308SPeng Fan 	scmi_msg_handler_t handler = NULL;
64b4734308SPeng Fan 
65b4734308SPeng Fan 	switch (msg->protocol_id) {
66b4734308SPeng Fan 	case SCMI_PROTOCOL_ID_BASE:
67b4734308SPeng Fan 		handler = scmi_msg_get_base_handler(msg);
68b4734308SPeng Fan 		break;
69b4734308SPeng Fan 	case SCMI_PROTOCOL_ID_CLOCK:
70b4734308SPeng Fan 		handler = scmi_msg_get_clock_handler(msg);
71b4734308SPeng Fan 		break;
72b4734308SPeng Fan 	case SCMI_PROTOCOL_ID_RESET_DOMAIN:
73b4734308SPeng Fan 		handler = scmi_msg_get_rstd_handler(msg);
74b4734308SPeng Fan 		break;
757e4833cdSPeng Fan 	case SCMI_PROTOCOL_ID_POWER_DOMAIN:
767e4833cdSPeng Fan 		handler = scmi_msg_get_pd_handler(msg);
777e4833cdSPeng Fan 		break;
78b4734308SPeng Fan 	default:
79b4734308SPeng Fan 		break;
80b4734308SPeng Fan 	}
81b4734308SPeng Fan 
82b4734308SPeng Fan 	if (handler) {
83b4734308SPeng Fan 		handler(msg);
84b4734308SPeng Fan 		return;
85b4734308SPeng Fan 	}
86b4734308SPeng Fan 
87*0dc9f52aSYann Gautier 	ERROR("Agent %u Protocol 0x%x Message 0x%x: not supported\n",
88b4734308SPeng Fan 	      msg->agent_id, msg->protocol_id, msg->message_id);
89b4734308SPeng Fan 
90b4734308SPeng Fan 	scmi_status_response(msg, SCMI_NOT_SUPPORTED);
91b4734308SPeng Fan }
92