diff options
author | Antonio Nino Diaz <antonio.ninodiaz@arm.com> | 2019-01-25 14:23:49 +0000 |
---|---|---|
committer | Antonio Nino Diaz <antonio.ninodiaz@arm.com> | 2019-01-25 16:04:11 +0000 |
commit | 0387aa42ac2f0a6b3c294917d7b37545e13a2e5f (patch) | |
tree | 20dd30a2d34ffecf44e768bf2206e0c3b904fa6f /plat/arm | |
parent | c411396e5547ab591cab0165e20458c0424fcc79 (diff) |
plat/arm: scpi: Move to drivers/ folder
Change-Id: Icc59cdaf2b56f6936e9847f1894594c671db2e94
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Diffstat (limited to 'plat/arm')
-rw-r--r-- | plat/arm/css/common/css_common.mk | 16 | ||||
-rw-r--r-- | plat/arm/css/common/sp_min/css_sp_min.mk | 4 | ||||
-rw-r--r-- | plat/arm/css/drivers/scp/css_bom_bootloader.c | 2 | ||||
-rw-r--r-- | plat/arm/css/drivers/scp/css_pm_scpi.c | 2 | ||||
-rw-r--r-- | plat/arm/css/drivers/scpi/css_scpi.c | 263 | ||||
-rw-r--r-- | plat/arm/css/drivers/scpi/css_scpi.h | 109 |
6 files changed, 12 insertions, 384 deletions
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk index 55303f11..36da7320 100644 --- a/plat/arm/css/common/css_common.mk +++ b/plat/arm/css/common/css_common.mk @@ -27,8 +27,8 @@ BL31_SOURCES += plat/arm/css/common/css_pm.c \ ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) BL31_SOURCES += drivers/arm/css/mhu/css_mhu.c \ - plat/arm/css/drivers/scp/css_pm_scpi.c \ - plat/arm/css/drivers/scpi/css_scpi.c + drivers/arm/css/scpi/css_scpi.c \ + plat/arm/css/drivers/scp/css_pm_scpi.c else BL31_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \ drivers/arm/css/scmi/scmi_ap_core_proto.c \ @@ -55,13 +55,13 @@ ifeq (${CSS_LOAD_SCP_IMAGES},1) BL2_SOURCES += plat/arm/css/drivers/scp/css_sds.c \ plat/arm/css/drivers/sds/sds.c else - BL2U_SOURCES += drivers/arm/css/mhu/css_mhu.c \ - plat/arm/css/drivers/scp/css_bom_bootloader.c \ - plat/arm/css/drivers/scpi/css_scpi.c + BL2U_SOURCES += drivers/arm/css/mhu/css_mhu.c \ + drivers/arm/css/scpi/css_scpi.c \ + plat/arm/css/drivers/scp/css_bom_bootloader.c - BL2_SOURCES += drivers/arm/css/mhu/css_mhu.c \ - plat/arm/css/drivers/scp/css_bom_bootloader.c \ - plat/arm/css/drivers/scpi/css_scpi.c + BL2_SOURCES += drivers/arm/css/mhu/css_mhu.c \ + drivers/arm/css/scpi/css_scpi.c \ + plat/arm/css/drivers/scp/css_bom_bootloader.c # Enable option to detect whether the SCP ROM firmware in use predates version # 1.7.0 and therefore, is incompatible. CSS_DETECT_PRE_1_7_0_SCP := 1 diff --git a/plat/arm/css/common/sp_min/css_sp_min.mk b/plat/arm/css/common/sp_min/css_sp_min.mk index 53daf1b9..a7c61be8 100644 --- a/plat/arm/css/common/sp_min/css_sp_min.mk +++ b/plat/arm/css/common/sp_min/css_sp_min.mk @@ -10,8 +10,8 @@ BL32_SOURCES += plat/arm/css/common/css_pm.c \ ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) BL32_SOURCES += drivers/arm/css/mhu/css_mhu.c \ - plat/arm/css/drivers/scp/css_pm_scpi.c \ - plat/arm/css/drivers/scpi/css_scpi.c + drivers/arm/css/scpi/css_scpi.c \ + plat/arm/css/drivers/scp/css_pm_scpi.c else BL32_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \ drivers/arm/css/scmi/scmi_common.c \ diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c index 5fe268d6..40880da2 100644 --- a/plat/arm/css/drivers/scp/css_bom_bootloader.c +++ b/plat/arm/css/drivers/scp/css_bom_bootloader.c @@ -10,10 +10,10 @@ #include <arch_helpers.h> #include <common/debug.h> #include <drivers/arm/css/css_mhu.h> +#include <drivers/arm/css/css_scpi.h> #include <plat/common/platform.h> #include <platform_def.h> -#include "../scpi/css_scpi.h" #include "css_scp.h" /* ID of the MHU slot used for the BOM protocol */ diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/plat/arm/css/drivers/scp/css_pm_scpi.c index 04c5f9b4..7e228169 100644 --- a/plat/arm/css/drivers/scp/css_pm_scpi.c +++ b/plat/arm/css/drivers/scp/css_pm_scpi.c @@ -8,10 +8,10 @@ #include <arch_helpers.h> #include <common/debug.h> +#include <drivers/arm/css/css_scpi.h> #include <plat/arm/common/plat_arm.h> #include <plat/arm/css/common/css_pm.h> -#include "../scpi/css_scpi.h" #include "css_scp.h" /* diff --git a/plat/arm/css/drivers/scpi/css_scpi.c b/plat/arm/css/drivers/scpi/css_scpi.c deleted file mode 100644 index 4965c660..00000000 --- a/plat/arm/css/drivers/scpi/css_scpi.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <assert.h> -#include <string.h> - -#include <arch_helpers.h> -#include <common/debug.h> -#include <drivers/arm/css/css_mhu.h> -#include <lib/utils.h> -#include <plat/common/platform.h> -#include <platform_def.h> - -#include "css_scpi.h" - -#define SCPI_SHARED_MEM_SCP_TO_AP PLAT_CSS_SCP_COM_SHARED_MEM_BASE -#define SCPI_SHARED_MEM_AP_TO_SCP (PLAT_CSS_SCP_COM_SHARED_MEM_BASE \ - + 0x100) - -/* Header and payload addresses for commands from AP to SCP */ -#define SCPI_CMD_HEADER_AP_TO_SCP \ - ((scpi_cmd_t *) SCPI_SHARED_MEM_AP_TO_SCP) -#define SCPI_CMD_PAYLOAD_AP_TO_SCP \ - ((void *) (SCPI_SHARED_MEM_AP_TO_SCP + sizeof(scpi_cmd_t))) - -/* Header and payload addresses for responses from SCP to AP */ -#define SCPI_RES_HEADER_SCP_TO_AP \ - ((scpi_cmd_t *) SCPI_SHARED_MEM_SCP_TO_AP) -#define SCPI_RES_PAYLOAD_SCP_TO_AP \ - ((void *) (SCPI_SHARED_MEM_SCP_TO_AP + sizeof(scpi_cmd_t))) - -/* ID of the MHU slot used for the SCPI protocol */ -#define SCPI_MHU_SLOT_ID 0 - -static void scpi_secure_message_start(void) -{ - mhu_secure_message_start(SCPI_MHU_SLOT_ID); -} - -static void scpi_secure_message_send(size_t payload_size) -{ - /* - * Ensure that any write to the SCPI payload area is seen by SCP before - * we write to the MHU register. If these 2 writes were reordered by - * the CPU then SCP would read stale payload data - */ - dmbst(); - - mhu_secure_message_send(SCPI_MHU_SLOT_ID); -} - -static void scpi_secure_message_receive(scpi_cmd_t *cmd) -{ - uint32_t mhu_status; - - assert(cmd != NULL); - - mhu_status = mhu_secure_message_wait(); - - /* Expect an SCPI message, reject any other protocol */ - if (mhu_status != (1 << SCPI_MHU_SLOT_ID)) { - ERROR("MHU: Unexpected protocol (MHU status: 0x%x)\n", - mhu_status); - panic(); - } - - /* - * Ensure that any read to the SCPI payload area is done after reading - * the MHU register. If these 2 reads were reordered then the CPU would - * read invalid payload data - */ - dmbld(); - - memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd)); -} - -static void scpi_secure_message_end(void) -{ - mhu_secure_message_end(SCPI_MHU_SLOT_ID); -} - -int scpi_wait_ready(void) -{ - scpi_cmd_t scpi_cmd; - - VERBOSE("Waiting for SCP_READY command...\n"); - - /* Get a message from the SCP */ - scpi_secure_message_start(); - scpi_secure_message_receive(&scpi_cmd); - scpi_secure_message_end(); - - /* We are expecting 'SCP Ready', produce correct error if it's not */ - scpi_status_t status = SCP_OK; - if (scpi_cmd.id != SCPI_CMD_SCP_READY) { - ERROR("Unexpected SCP command: expected command #%u, got command #%u\n", - SCPI_CMD_SCP_READY, scpi_cmd.id); - status = SCP_E_SUPPORT; - } else if (scpi_cmd.size != 0) { - ERROR("SCP_READY command has incorrect size: expected 0, got %u\n", - scpi_cmd.size); - status = SCP_E_SIZE; - } - - VERBOSE("Sending response for SCP_READY command\n"); - - /* - * Send our response back to SCP. - * We are using the same SCPI header, just update the status field. - */ - scpi_cmd.status = status; - scpi_secure_message_start(); - memcpy((void *) SCPI_SHARED_MEM_AP_TO_SCP, &scpi_cmd, sizeof(scpi_cmd)); - scpi_secure_message_send(0); - scpi_secure_message_end(); - - return status == SCP_OK ? 0 : -1; -} - -void scpi_set_css_power_state(unsigned int mpidr, - scpi_power_state_t cpu_state, scpi_power_state_t cluster_state, - scpi_power_state_t css_state) -{ - scpi_cmd_t *cmd; - uint32_t state = 0; - uint32_t *payload_addr; - -#if ARM_PLAT_MT - /* - * The current SCPI driver only caters for single-threaded platforms. - * Hence we ignore the thread ID (which is always 0) for such platforms. - */ - state |= (mpidr >> MPIDR_AFF1_SHIFT) & 0x0f; /* CPU ID */ - state |= ((mpidr >> MPIDR_AFF2_SHIFT) & 0x0f) << 4; /* Cluster ID */ -#else - state |= mpidr & 0x0f; /* CPU ID */ - state |= (mpidr & 0xf00) >> 4; /* Cluster ID */ -#endif /* ARM_PLAT_MT */ - - state |= cpu_state << 8; - state |= cluster_state << 12; - state |= css_state << 16; - - scpi_secure_message_start(); - - /* Populate the command header */ - cmd = SCPI_CMD_HEADER_AP_TO_SCP; - cmd->id = SCPI_CMD_SET_CSS_POWER_STATE; - cmd->set = SCPI_SET_NORMAL; - cmd->sender = 0; - cmd->size = sizeof(state); - /* Populate the command payload */ - payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; - *payload_addr = state; - scpi_secure_message_send(sizeof(state)); - /* - * SCP does not reply to this command in order to avoid MHU interrupts - * from the sender, which could interfere with its power state request. - */ - - scpi_secure_message_end(); -} - -/* - * Query and obtain CSS power state from SCP. - * - * In response to the query, SCP returns power states of all CPUs in all - * clusters of the system. The returned response is then filtered based on the - * supplied MPIDR. Power states of requested cluster and CPUs within are updated - * via. supplied non-NULL pointer arguments. - * - * Returns 0 on success, or -1 on errors. - */ -int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p, - unsigned int *cluster_state_p) -{ - scpi_cmd_t *cmd; - scpi_cmd_t response; - int power_state, cpu, cluster, rc = -1; - - /* - * Extract CPU and cluster membership of the given MPIDR. SCPI caters - * for only up to 0xf clusters, and 8 CPUs per cluster - */ -#if ARM_PLAT_MT - /* - * The current SCPI driver only caters for single-threaded platforms. - * Hence we ignore the thread ID (which is always 0) for such platforms. - */ - cpu = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; - cluster = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK; -#else - cpu = mpidr & MPIDR_AFFLVL_MASK; - cluster = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; -#endif /* ARM_PLAT_MT */ - if (cpu >= 8 || cluster >= 0xf) - return -1; - - scpi_secure_message_start(); - - /* Populate request headers */ - zeromem(SCPI_CMD_HEADER_AP_TO_SCP, sizeof(*cmd)); - cmd = SCPI_CMD_HEADER_AP_TO_SCP; - cmd->id = SCPI_CMD_GET_CSS_POWER_STATE; - - /* - * Send message and wait for SCP's response - */ - scpi_secure_message_send(0); - scpi_secure_message_receive(&response); - - if (response.status != SCP_OK) - goto exit; - - /* Validate SCP response */ - if (!CHECK_RESPONSE(response, cluster)) - goto exit; - - /* Extract power states for required cluster */ - power_state = *(((uint16_t *) SCPI_RES_PAYLOAD_SCP_TO_AP) + cluster); - if (CLUSTER_ID(power_state) != cluster) - goto exit; - - /* Update power state via. pointers */ - if (cluster_state_p) - *cluster_state_p = CLUSTER_POWER_STATE(power_state); - if (cpu_state_p) - *cpu_state_p = CPU_POWER_STATE(power_state); - rc = 0; - -exit: - scpi_secure_message_end(); - return rc; -} - -uint32_t scpi_sys_power_state(scpi_system_state_t system_state) -{ - scpi_cmd_t *cmd; - uint8_t *payload_addr; - scpi_cmd_t response; - - scpi_secure_message_start(); - - /* Populate the command header */ - cmd = SCPI_CMD_HEADER_AP_TO_SCP; - cmd->id = SCPI_CMD_SYS_POWER_STATE; - cmd->set = 0; - cmd->sender = 0; - cmd->size = sizeof(*payload_addr); - /* Populate the command payload */ - payload_addr = SCPI_CMD_PAYLOAD_AP_TO_SCP; - *payload_addr = system_state & 0xff; - scpi_secure_message_send(sizeof(*payload_addr)); - - scpi_secure_message_receive(&response); - - scpi_secure_message_end(); - - return response.status; -} diff --git a/plat/arm/css/drivers/scpi/css_scpi.h b/plat/arm/css/drivers/scpi/css_scpi.h deleted file mode 100644 index 68fc60a6..00000000 --- a/plat/arm/css/drivers/scpi/css_scpi.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CSS_SCPI_H -#define CSS_SCPI_H - -#include <stddef.h> -#include <stdint.h> - -/* - * An SCPI command consists of a header and a payload. - * The following structure describes the header. It is 64-bit long. - */ -typedef struct { - /* Command ID */ - uint32_t id : 7; - /* Set ID. Identifies whether this is a standard or extended command. */ - uint32_t set : 1; - /* Sender ID to match a reply. The value is sender specific. */ - uint32_t sender : 8; - /* Size of the payload in bytes (0 - 511) */ - uint32_t size : 9; - uint32_t reserved : 7; - /* - * Status indicating the success of a command. - * See the enum below. - */ - uint32_t status; -} scpi_cmd_t; - -typedef enum { - SCPI_SET_NORMAL = 0, /* Normal SCPI commands */ - SCPI_SET_EXTENDED /* Extended SCPI commands */ -} scpi_set_t; - -enum { - SCP_OK = 0, /* Success */ - SCP_E_PARAM, /* Invalid parameter(s) */ - SCP_E_ALIGN, /* Invalid alignment */ - SCP_E_SIZE, /* Invalid size */ - SCP_E_HANDLER, /* Invalid handler or callback */ - SCP_E_ACCESS, /* Invalid access or permission denied */ - SCP_E_RANGE, /* Value out of range */ - SCP_E_TIMEOUT, /* Time out has ocurred */ - SCP_E_NOMEM, /* Invalid memory area or pointer */ - SCP_E_PWRSTATE, /* Invalid power state */ - SCP_E_SUPPORT, /* Feature not supported or disabled */ - SCPI_E_DEVICE, /* Device error */ - SCPI_E_BUSY, /* Device is busy */ -}; - -typedef uint32_t scpi_status_t; - -typedef enum { - SCPI_CMD_SCP_READY = 0x01, - SCPI_CMD_SET_CSS_POWER_STATE = 0x03, - SCPI_CMD_GET_CSS_POWER_STATE = 0x04, - SCPI_CMD_SYS_POWER_STATE = 0x05 -} scpi_command_t; - -/* - * Macros to parse SCP response to GET_CSS_POWER_STATE command - * - * [3:0] : cluster ID - * [7:4] : cluster state: 0 = on; 3 = off; rest are reserved - * [15:8]: on/off state for individual CPUs in the cluster - * - * Payload is in little-endian - */ -#define CLUSTER_ID(_resp) ((_resp) & 0xf) -#define CLUSTER_POWER_STATE(_resp) (((_resp) >> 4) & 0xf) - -/* Result is a bit mask of CPU on/off states in the cluster */ -#define CPU_POWER_STATE(_resp) (((_resp) >> 8) & 0xff) - -/* - * For GET_CSS_POWER_STATE, SCP returns the power states of every cluster. The - * size of response depends on the number of clusters in the system. The - * SCP-to-AP payload contains 2 bytes per cluster. Make sure the response is - * large enough to contain power states of a given cluster - */ -#define CHECK_RESPONSE(_resp, _clus) \ - (_resp.size >= (((_clus) + 1) * 2)) - -typedef enum { - scpi_power_on = 0, - scpi_power_retention = 1, - scpi_power_off = 3, -} scpi_power_state_t; - -typedef enum { - scpi_system_shutdown = 0, - scpi_system_reboot = 1, - scpi_system_reset = 2 -} scpi_system_state_t; - -int scpi_wait_ready(void); -void scpi_set_css_power_state(unsigned int mpidr, - scpi_power_state_t cpu_state, - scpi_power_state_t cluster_state, - scpi_power_state_t css_state); -int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p, - unsigned int *cluster_state_p); -uint32_t scpi_sys_power_state(scpi_system_state_t system_state); - -#endif /* CSS_SCPI_H */ |