aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnurag Koul <anurag.koul@arm.com>2020-09-10 18:50:20 +0100
committerjimqui01 <54316584+jimqui01@users.noreply.github.com>2020-09-15 17:03:53 +0100
commit6dfbd253de223961505d989077678dc732ba351f (patch)
treea67c69fdc8b0382ddc90ceff7293eb9f72f6d5da
parent4097f3510f8d5d9b91c64f3e4c967a1ec7031f15 (diff)
morello/module: add scmi_management module
Add a protocol type module for facilitating SCMI communication between MCP and SCP. Signed-off-by: Anurag Koul <anurag.koul@arm.com> Change-Id: Ie62493f90af6b29674b45a74f3e1dbe3e8f0c5ca
-rw-r--r--product/morello/include/morello_mcp_scmi.h17
-rw-r--r--product/morello/module/scmi_management/include/mod_scmi_management.h77
-rw-r--r--product/morello/module/scmi_management/src/Makefile11
-rw-r--r--product/morello/module/scmi_management/src/mod_scmi_management.c323
-rw-r--r--product/morello/scp_ramfw_fvp/config_scmi_management.c11
-rw-r--r--product/morello/scp_ramfw_fvp/firmware.mk2
6 files changed, 441 insertions, 0 deletions
diff --git a/product/morello/include/morello_mcp_scmi.h b/product/morello/include/morello_mcp_scmi.h
new file mode 100644
index 00000000..b7124088
--- /dev/null
+++ b/product/morello/include/morello_mcp_scmi.h
@@ -0,0 +1,17 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MORELLO_MCP_SCMI_H
+#define MORELLO_MCP_SCMI_H
+
+/* SCMI agent identifiers */
+enum mcp_morello_scmi_agent_idx {
+ MCP_MORELLO_SCMI_AGENT_IDX_MANAGEMENT,
+ MCP_MORELLO_SCMI_AGENT_IDX_COUNT,
+};
+
+#endif /* MORELLO_MCP_SCMI_H */
diff --git a/product/morello/module/scmi_management/include/mod_scmi_management.h b/product/morello/module/scmi_management/include/mod_scmi_management.h
new file mode 100644
index 00000000..3de45193
--- /dev/null
+++ b/product/morello/module/scmi_management/include/mod_scmi_management.h
@@ -0,0 +1,77 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * SCMI Management Protocol Support.
+ */
+
+#ifndef MOD_SCMI_MANAGEMENT_H
+#define MOD_SCMI_MANAGEMENT_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+/*!
+ * \addtogroup GroupMORELLOModule MORELLO Product Modules
+ * @{
+ */
+
+/*!
+ * \defgroup GroupMORELLOSCMI_MANAGEMENT SCMI Management Protocol
+ * @{
+ */
+
+/*!
+ * \brief Macro defining the SCMI Management Protocol's ID.
+ */
+#define SCMI_PROTOCOL_ID_MANAGEMENT UINT32_C(0x89)
+
+/*!
+ * \brief Macro defining the SCMI Management Protocol's version.
+ */
+#define SCMI_PROTOCOL_VERSION_MANAGEMENT UINT32_C(0x10000)
+
+/*!
+ * \brief Identifiers of the SCMI Management Protocol commands.
+ */
+enum scmi_management_command_id {
+ /*! Command ID for getting clock status */
+ SCMI_MANAGEMENT_CLOCK_STATUS_GET = 0x3,
+ /*! Commmand ID for chip ID information */
+ SCMI_MANAGEMENT_CHIPID_INFO_GET = 0x4,
+};
+
+/*!
+ * \brief Protocol handler for getting clock status from SCP.
+ */
+struct scmi_management_clock_status_get_p2a {
+ /*! SCMI status */
+ int32_t status;
+ /*! Clock status */
+ uint32_t clock_status;
+};
+
+/*!
+ * \brief Protocol handler for chip ID information.
+ */
+struct scmi_management_chipid_info_get_p2a {
+ /*! SCMI status */
+ int32_t status;
+ /*! Multi chip mode identifier */
+ uint32_t multi_chip_mode;
+ /*! Chip ID of the chip if multi_chip_mode is set */
+ uint32_t chipid;
+};
+
+/*!
+ * @}
+ */
+
+/*!
+ * @}
+ */
+
+#endif /* MOD_SCMI_MANAGEMENT_H */
diff --git a/product/morello/module/scmi_management/src/Makefile b/product/morello/module/scmi_management/src/Makefile
new file mode 100644
index 00000000..313077a5
--- /dev/null
+++ b/product/morello/module/scmi_management/src/Makefile
@@ -0,0 +1,11 @@
+#
+# Arm SCP/MCP Software
+# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BS_LIB_NAME := SCMI Management Protocol
+BS_LIB_SOURCES := mod_scmi_management.c
+
+include $(BS_DIR)/lib.mk
diff --git a/product/morello/module/scmi_management/src/mod_scmi_management.c b/product/morello/module/scmi_management/src/mod_scmi_management.c
new file mode 100644
index 00000000..9e781343
--- /dev/null
+++ b/product/morello/module/scmi_management/src/mod_scmi_management.c
@@ -0,0 +1,323 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Description:
+ * SCMI Management Protocol Support.
+ */
+
+#include "morello_scc_reg.h"
+#include "morello_scp_pik.h"
+
+#include <internal/scmi.h>
+
+#include <mod_scmi.h>
+#include <mod_scmi_management.h>
+
+#include <fwk_assert.h>
+#include <fwk_id.h>
+#include <fwk_macros.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <fwk_status.h>
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct scmi_management_ctx {
+ /* SCMI module API */
+ const struct mod_scmi_from_protocol_api *scmi_api;
+};
+
+static int scmi_management_protocol_version_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload);
+static int scmi_management_protocol_attributes_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload);
+static int scmi_management_protocol_message_attributes_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload);
+static int scmi_management_clock_status_get_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload);
+static int scmi_management_chipid_info_get_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload);
+
+/*
+ * Internal variables.
+ */
+static struct scmi_management_ctx scmi_management_ctx;
+
+static int (*const handler_table[])(fwk_id_t, const uint32_t *) = {
+ [MOD_SCMI_PROTOCOL_VERSION] = scmi_management_protocol_version_handler,
+ [MOD_SCMI_PROTOCOL_ATTRIBUTES] =
+ scmi_management_protocol_attributes_handler,
+ [MOD_SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] =
+ scmi_management_protocol_message_attributes_handler,
+ [SCMI_MANAGEMENT_CLOCK_STATUS_GET] =
+ scmi_management_clock_status_get_handler,
+ [SCMI_MANAGEMENT_CHIPID_INFO_GET] = scmi_management_chipid_info_get_handler,
+};
+
+static const unsigned int payload_size_table[] = {
+ [MOD_SCMI_PROTOCOL_VERSION] = 0,
+ [MOD_SCMI_PROTOCOL_ATTRIBUTES] = 0,
+ [MOD_SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = 0,
+ [SCMI_MANAGEMENT_CLOCK_STATUS_GET] = 0,
+ [SCMI_MANAGEMENT_CHIPID_INFO_GET] = 0,
+};
+
+/*
+ * Protocol Version
+ */
+static int scmi_management_protocol_version_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload)
+{
+ struct scmi_protocol_version_p2a return_values = {
+ .status = SCMI_SUCCESS,
+ .version = SCMI_PROTOCOL_VERSION_MANAGEMENT,
+ };
+
+ scmi_management_ctx.scmi_api->respond(
+ service_id, &return_values, sizeof(return_values));
+ return FWK_SUCCESS;
+}
+
+/*
+ * Protocol Attributes
+ */
+static int scmi_management_protocol_attributes_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload)
+{
+ struct scmi_protocol_attributes_p2a return_values = {
+ .status = SCMI_SUCCESS,
+ .attributes = 0,
+ };
+
+ scmi_management_ctx.scmi_api->respond(
+ service_id, &return_values, sizeof(return_values));
+
+ return FWK_SUCCESS;
+}
+
+/*
+ * Protocol Message Attributes
+ */
+static int scmi_management_protocol_message_attributes_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload)
+{
+ size_t response_size;
+ const struct scmi_protocol_message_attributes_a2p *parameters;
+ unsigned int message_id;
+ struct scmi_protocol_message_attributes_p2a return_values = {
+ .status = SCMI_SUCCESS,
+ .attributes = 0,
+ };
+
+ parameters = (const struct scmi_protocol_message_attributes_a2p *)payload;
+ message_id = parameters->message_id;
+
+ if ((message_id >= FWK_ARRAY_SIZE(handler_table)) ||
+ (handler_table[message_id] == NULL))
+ return_values.status = SCMI_NOT_FOUND;
+
+ response_size = (return_values.status == SCMI_SUCCESS) ?
+ sizeof(return_values) :
+ sizeof(return_values.status);
+
+ scmi_management_ctx.scmi_api->respond(
+ service_id, &return_values, response_size);
+
+ return FWK_SUCCESS;
+}
+
+/*
+ * Clock Status Get
+ */
+static int scmi_management_clock_status_get_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload)
+{
+ int status;
+ unsigned int agent_id;
+ enum scmi_agent_type agent_type;
+ struct scmi_management_clock_status_get_p2a return_values = {
+ .status = SCMI_GENERIC_ERROR,
+ };
+
+ status = scmi_management_ctx.scmi_api->get_agent_id(service_id, &agent_id);
+ if (status != FWK_SUCCESS)
+ goto exit;
+
+ status =
+ scmi_management_ctx.scmi_api->get_agent_type(agent_id, &agent_type);
+ if (status != FWK_SUCCESS)
+ goto exit;
+
+ /* Only the Management agent may get the clock status */
+ if (agent_type != SCMI_AGENT_TYPE_MANAGEMENT) {
+ return_values.status = SCMI_DENIED;
+ status = FWK_E_ACCESS;
+ goto exit;
+ }
+
+ return_values.status = SCMI_SUCCESS;
+ return_values.clock_status = 1;
+
+exit:
+ scmi_management_ctx.scmi_api->respond(
+ service_id, &return_values, sizeof(return_values));
+ return status;
+}
+
+/*
+ * CHIP ID Information Get
+ */
+static int scmi_management_chipid_info_get_handler(
+ fwk_id_t service_id,
+ const uint32_t *payload)
+{
+ int status;
+ uint32_t chip_info;
+ unsigned int agent_id;
+ enum scmi_agent_type agent_type;
+ struct scmi_management_chipid_info_get_p2a return_values = {
+ .status = SCMI_GENERIC_ERROR,
+ };
+
+ status = scmi_management_ctx.scmi_api->get_agent_id(service_id, &agent_id);
+ if (status != FWK_SUCCESS)
+ goto exit;
+
+ status =
+ scmi_management_ctx.scmi_api->get_agent_type(agent_id, &agent_type);
+ if (status != FWK_SUCCESS)
+ goto exit;
+
+ /* Only the Management agent may get the CHIP ID information */
+ if (agent_type != SCMI_AGENT_TYPE_MANAGEMENT) {
+ return_values.status = SCMI_DENIED;
+ status = FWK_E_ACCESS;
+ goto exit;
+ }
+
+ chip_info = SCC->PLATFORM_CTRL;
+ return_values.status = SCMI_SUCCESS;
+ return_values.multi_chip_mode =
+ ((chip_info & SCC_PLATFORM_CTRL_MULTI_CHIP_MODE_MASK) >>
+ SCC_PLATFORM_CTRL_MULTI_CHIP_MODE_POS);
+ return_values.chipid =
+ ((chip_info & SCC_PLATFORM_CTRL_CHIPID_MASK) >>
+ SCC_PLATFORM_CTRL_CHIPID_POS);
+
+exit:
+ scmi_management_ctx.scmi_api->respond(
+ service_id, &return_values, sizeof(return_values));
+ return status;
+}
+
+/*
+ * SCMI module -> SCMI Management module interface
+ */
+static int scmi_management_get_scmi_protocol_id(
+ fwk_id_t protocol_id,
+ uint8_t *scmi_protocol_id)
+{
+ *scmi_protocol_id = SCMI_PROTOCOL_ID_MANAGEMENT;
+
+ return FWK_SUCCESS;
+}
+
+static int scmi_management_message_handler(
+ fwk_id_t protocol_id,
+ fwk_id_t service_id,
+ const uint32_t *payload,
+ size_t payload_size,
+ unsigned int message_id)
+{
+ int32_t return_value;
+
+ static_assert(
+ FWK_ARRAY_SIZE(handler_table) == FWK_ARRAY_SIZE(payload_size_table),
+ "[SCMI] Management protocol table sizes not consistent");
+ assert(payload != NULL);
+
+ if (message_id >= FWK_ARRAY_SIZE(handler_table)) {
+ return_value = SCMI_NOT_FOUND;
+ goto error;
+ }
+
+ if (payload_size != payload_size_table[message_id]) {
+ return_value = SCMI_PROTOCOL_ERROR;
+ goto error;
+ }
+
+ return handler_table[message_id](service_id, payload);
+
+error:
+ scmi_management_ctx.scmi_api->respond(
+ service_id, &return_value, sizeof(return_value));
+
+ return FWK_SUCCESS;
+}
+
+static struct mod_scmi_to_protocol_api
+ scmi_management_mod_scmi_to_protocol_api = {
+ .get_scmi_protocol_id = scmi_management_get_scmi_protocol_id,
+ .message_handler = scmi_management_message_handler
+ };
+
+/*
+ * Framework handlers
+ */
+
+static int scmi_management_init(
+ fwk_id_t module_id,
+ unsigned int unused,
+ const void *data)
+{
+ return FWK_SUCCESS;
+}
+
+static int scmi_management_bind(fwk_id_t id, unsigned int round)
+{
+ if (round == 1)
+ return FWK_SUCCESS;
+
+ /* Bind to the SCMI module, storing an API pointer for later use. */
+ return fwk_module_bind(
+ FWK_ID_MODULE(FWK_MODULE_IDX_SCMI),
+ FWK_ID_API(FWK_MODULE_IDX_SCMI, MOD_SCMI_API_IDX_PROTOCOL),
+ &scmi_management_ctx.scmi_api);
+}
+
+static int scmi_management_process_bind_request(
+ fwk_id_t source_id,
+ fwk_id_t target_id,
+ fwk_id_t api_id,
+ const void **api)
+{
+ /* Only accept binding requests from the SCMI module. */
+ if (!fwk_id_is_equal(source_id, FWK_ID_MODULE(FWK_MODULE_IDX_SCMI)))
+ return FWK_E_ACCESS;
+
+ *api = &scmi_management_mod_scmi_to_protocol_api;
+
+ return FWK_SUCCESS;
+}
+
+const struct fwk_module module_scmi_management = {
+ .name = "SCMI Management Protocol",
+ .api_count = 1,
+ .type = FWK_MODULE_TYPE_PROTOCOL,
+ .init = scmi_management_init,
+ .bind = scmi_management_bind,
+ .process_bind_request = scmi_management_process_bind_request,
+};
diff --git a/product/morello/scp_ramfw_fvp/config_scmi_management.c b/product/morello/scp_ramfw_fvp/config_scmi_management.c
new file mode 100644
index 00000000..87862581
--- /dev/null
+++ b/product/morello/scp_ramfw_fvp/config_scmi_management.c
@@ -0,0 +1,11 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <fwk_module.h>
+
+/* No elements, no module configuration data */
+struct fwk_module_config config_scmi_management = { 0 };
diff --git a/product/morello/scp_ramfw_fvp/firmware.mk b/product/morello/scp_ramfw_fvp/firmware.mk
index 754226f3..6f54ed8b 100644
--- a/product/morello/scp_ramfw_fvp/firmware.mk
+++ b/product/morello/scp_ramfw_fvp/firmware.mk
@@ -35,6 +35,7 @@ BS_FIRMWARE_MODULES := \
timer \
scmi_power_domain \
scmi_system_power \
+ scmi_management \
fip \
ssc \
system_info \
@@ -60,6 +61,7 @@ BS_FIRMWARE_SOURCES := \
config_scmi_system_power.c \
config_scmi_power_domain.c \
config_pl011.c \
+ config_scmi_management.c \
config_morello_pll.c \
config_pik_clock.c \
config_css_clock.c \