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