diff --git a/drivers/arm/css/mhu/css_mhu.c b/drivers/arm/css/mhu/css_mhu.c new file mode 100644 index 0000000..b7faf7e --- /dev/null +++ b/drivers/arm/css/mhu/css_mhu.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include +#include +#include + +/* SCP MHU secure channel registers */ +#define SCP_INTR_S_STAT 0x200 +#define SCP_INTR_S_SET 0x208 +#define SCP_INTR_S_CLEAR 0x210 + +/* CPU MHU secure channel registers */ +#define CPU_INTR_S_STAT 0x300 +#define CPU_INTR_S_SET 0x308 +#define CPU_INTR_S_CLEAR 0x310 + +ARM_INSTANTIATE_LOCK; + +/* Weak definition may be overridden in specific CSS based platform */ +#pragma weak plat_arm_pwrc_setup + + +/* + * Slot 31 is reserved because the MHU hardware uses this register bit to + * indicate a non-secure access attempt. The total number of available slots is + * therefore 31 [30:0]. + */ +#define MHU_MAX_SLOT_ID 30 + +void mhu_secure_message_start(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + + arm_lock_get(); + + /* Make sure any previous command has finished */ + while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id)) + ; +} + +void mhu_secure_message_send(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id))); + + /* Send command to SCP */ + mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id); +} + +uint32_t mhu_secure_message_wait(void) +{ + /* Wait for response from SCP */ + uint32_t response; + while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT))) + ; + + return response; +} + +void mhu_secure_message_end(unsigned int slot_id) +{ + assert(slot_id <= MHU_MAX_SLOT_ID); + + /* + * Clear any response we got by writing one in the relevant slot bit to + * the CLEAR register + */ + mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id); + + arm_lock_release(); +} + +void __init mhu_secure_init(void) +{ + arm_lock_init(); + + /* + * The STAT register resets to zero. Ensure it is in the expected state, + * as a stale or garbage value would make us think it's a message we've + * already sent. + */ + assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0); +} + +void __init plat_arm_pwrc_setup(void) +{ + mhu_secure_init(); +} diff --git a/drivers/arm/css/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c new file mode 100644 index 0000000..8858742 --- /dev/null +++ b/drivers/arm/css/mhu/css_mhu_doorbell.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info) +{ + MHU_RING_DOORBELL(plat_info->db_reg_addr, + plat_info->db_modify_mask, + plat_info->db_preserve_mask); + return; +} + +void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) +{ + /* wake receiver */ + MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR); + + /* wait for receiver to acknowledge its ready */ + while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0) + ; + + MHU_RING_DOORBELL(plat_info->db_reg_addr, + plat_info->db_modify_mask, + plat_info->db_preserve_mask); + + /* clear the access request for the receiver */ + MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR); + + return; +} diff --git a/include/drivers/arm/css/css_mhu.h b/include/drivers/arm/css/css_mhu.h new file mode 100644 index 0000000..ff04ae4 --- /dev/null +++ b/include/drivers/arm/css/css_mhu.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_MHU_H +#define CSS_MHU_H + +#include + +void mhu_secure_message_start(unsigned int slot_id); +void mhu_secure_message_send(unsigned int slot_id); +uint32_t mhu_secure_message_wait(void); +void mhu_secure_message_end(unsigned int slot_id); + +void mhu_secure_init(void); + +#endif /* CSS_MHU_H */ diff --git a/include/drivers/arm/css/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h new file mode 100644 index 0000000..ecee563 --- /dev/null +++ b/include/drivers/arm/css/css_mhu_doorbell.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CSS_MHU_DOORBELL_H +#define CSS_MHU_DOORBELL_H + +#include + +#include + +/* MHUv2 Base Address */ +#define MHUV2_BASE_ADDR PLAT_CSS_MHU_BASE + +/* MHUv2 Control Registers Offsets */ +#define MHU_V2_MSG_NO_CAP_OFFSET 0xF80 +#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 +#define MHU_V2_ACCESS_READY_OFFSET 0xF8C + +#define SENDER_REG_STAT(_channel) (0x20 * (_channel)) +#define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC) + +/* Helper macro to ring doorbell */ +#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask) do { \ + uint32_t db = mmio_read_32(addr) & (preserve_mask); \ + mmio_write_32(addr, db | (modify_mask)); \ + } while (0) + +#define MHU_V2_ACCESS_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) + +#define MHU_V2_CLEAR_REQUEST(addr) \ + mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) + +#define MHU_V2_IS_ACCESS_READY(addr) \ + (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) + +struct scmi_channel_plat_info; +void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info); +void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info); + +#endif /* CSS_MHU_DOORBELL_H */ diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c index d83bd9a..ca5c344 100644 --- a/plat/arm/board/juno/juno_topology.c +++ b/plat/arm/board/juno/juno_topology.c @@ -4,14 +4,13 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include #include #include -#include "../../css/drivers/mhu/css_mhu_doorbell.h" - #if CSS_USE_SCMI_SDS_DRIVER static scmi_channel_plat_info_t juno_scmi_plat_info = { .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE, diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index a1669b9..18a0dea 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -6,11 +6,10 @@ #include +#include #include #include -#include "../../css/drivers/mhu/css_mhu_doorbell.h" - static scmi_channel_plat_info_t n1sdp_scmi_plat_info = { .scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE, .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk index b8e974f..55303f1 100644 --- a/plat/arm/css/common/css_common.mk +++ b/plat/arm/css/common/css_common.mk @@ -26,16 +26,16 @@ plat/arm/css/common/css_topology.c ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) -BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \ - plat/arm/css/drivers/mhu/css_mhu.c \ +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 else -BL31_SOURCES += drivers/arm/css/scmi/scmi_ap_core_proto.c \ +BL31_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \ + drivers/arm/css/scmi/scmi_ap_core_proto.c \ drivers/arm/css/scmi/scmi_common.c \ drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \ drivers/arm/css/scmi/scmi_sys_pwr_proto.c \ - plat/arm/css/drivers/scp/css_pm_scmi.c \ - plat/arm/css/drivers/mhu/css_mhu_doorbell.c + plat/arm/css/drivers/scp/css_pm_scmi.c endif # Process CSS_LOAD_SCP_IMAGES flag @@ -55,12 +55,12 @@ BL2_SOURCES += plat/arm/css/drivers/scp/css_sds.c \ plat/arm/css/drivers/sds/sds.c else - BL2U_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \ - plat/arm/css/drivers/mhu/css_mhu.c \ + 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 - BL2_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \ - plat/arm/css/drivers/mhu/css_mhu.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 # Enable option to detect whether the SCP ROM firmware in use predates version # 1.7.0 and therefore, is incompatible. 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 7c2dcf5..53daf1b 100644 --- a/plat/arm/css/common/sp_min/css_sp_min.mk +++ b/plat/arm/css/common/sp_min/css_sp_min.mk @@ -9,13 +9,13 @@ plat/arm/css/common/css_topology.c ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) -BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \ - plat/arm/css/drivers/mhu/css_mhu.c \ +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 else -BL32_SOURCES += drivers/arm/css/scmi/scmi_common.c \ +BL32_SOURCES += drivers/arm/css/mhu/css_mhu_doorbell.c \ + drivers/arm/css/scmi/scmi_common.c \ drivers/arm/css/scmi/scmi_pwr_dmn_proto.c \ drivers/arm/css/scmi/scmi_sys_pwr_proto.c \ - plat/arm/css/drivers/scp/css_pm_scmi.c \ - plat/arm/css/drivers/mhu/css_mhu_doorbell.c + plat/arm/css/drivers/scp/css_pm_scmi.c endif diff --git a/plat/arm/css/drivers/mhu/css_mhu.c b/plat/arm/css/drivers/mhu/css_mhu.c deleted file mode 100644 index 65695d8..0000000 --- a/plat/arm/css/drivers/mhu/css_mhu.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include -#include -#include -#include - -#include "css_mhu.h" - -/* SCP MHU secure channel registers */ -#define SCP_INTR_S_STAT 0x200 -#define SCP_INTR_S_SET 0x208 -#define SCP_INTR_S_CLEAR 0x210 - -/* CPU MHU secure channel registers */ -#define CPU_INTR_S_STAT 0x300 -#define CPU_INTR_S_SET 0x308 -#define CPU_INTR_S_CLEAR 0x310 - -ARM_INSTANTIATE_LOCK; - -/* Weak definition may be overridden in specific CSS based platform */ -#pragma weak plat_arm_pwrc_setup - - -/* - * Slot 31 is reserved because the MHU hardware uses this register bit to - * indicate a non-secure access attempt. The total number of available slots is - * therefore 31 [30:0]. - */ -#define MHU_MAX_SLOT_ID 30 - -void mhu_secure_message_start(unsigned int slot_id) -{ - assert(slot_id <= MHU_MAX_SLOT_ID); - - arm_lock_get(); - - /* Make sure any previous command has finished */ - while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & - (1 << slot_id)) - ; -} - -void mhu_secure_message_send(unsigned int slot_id) -{ - assert(slot_id <= MHU_MAX_SLOT_ID); - assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & - (1 << slot_id))); - - /* Send command to SCP */ - mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id); -} - -uint32_t mhu_secure_message_wait(void) -{ - /* Wait for response from SCP */ - uint32_t response; - while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT))) - ; - - return response; -} - -void mhu_secure_message_end(unsigned int slot_id) -{ - assert(slot_id <= MHU_MAX_SLOT_ID); - - /* - * Clear any response we got by writing one in the relevant slot bit to - * the CLEAR register - */ - mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id); - - arm_lock_release(); -} - -void __init mhu_secure_init(void) -{ - arm_lock_init(); - - /* - * The STAT register resets to zero. Ensure it is in the expected state, - * as a stale or garbage value would make us think it's a message we've - * already sent. - */ - assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0); -} - -void __init plat_arm_pwrc_setup(void) -{ - mhu_secure_init(); -} diff --git a/plat/arm/css/drivers/mhu/css_mhu.h b/plat/arm/css/drivers/mhu/css_mhu.h deleted file mode 100644 index ff04ae4..0000000 --- a/plat/arm/css/drivers/mhu/css_mhu.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CSS_MHU_H -#define CSS_MHU_H - -#include - -void mhu_secure_message_start(unsigned int slot_id); -void mhu_secure_message_send(unsigned int slot_id); -uint32_t mhu_secure_message_wait(void); -void mhu_secure_message_end(unsigned int slot_id); - -void mhu_secure_init(void); - -#endif /* CSS_MHU_H */ diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c deleted file mode 100644 index c031efa..0000000 --- a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -#include "css_mhu_doorbell.h" - -void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info) -{ - MHU_RING_DOORBELL(plat_info->db_reg_addr, - plat_info->db_modify_mask, - plat_info->db_preserve_mask); - return; -} - -void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info) -{ - /* wake receiver */ - MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR); - - /* wait for receiver to acknowledge its ready */ - while (MHU_V2_IS_ACCESS_READY(MHUV2_BASE_ADDR) == 0) - ; - - MHU_RING_DOORBELL(plat_info->db_reg_addr, - plat_info->db_modify_mask, - plat_info->db_preserve_mask); - - /* clear the access request for the receiver */ - MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR); - - return; -} diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h deleted file mode 100644 index ecee563..0000000 --- a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CSS_MHU_DOORBELL_H -#define CSS_MHU_DOORBELL_H - -#include - -#include - -/* MHUv2 Base Address */ -#define MHUV2_BASE_ADDR PLAT_CSS_MHU_BASE - -/* MHUv2 Control Registers Offsets */ -#define MHU_V2_MSG_NO_CAP_OFFSET 0xF80 -#define MHU_V2_ACCESS_REQ_OFFSET 0xF88 -#define MHU_V2_ACCESS_READY_OFFSET 0xF8C - -#define SENDER_REG_STAT(_channel) (0x20 * (_channel)) -#define SENDER_REG_SET(_channel) ((0x20 * (_channel)) + 0xC) - -/* Helper macro to ring doorbell */ -#define MHU_RING_DOORBELL(addr, modify_mask, preserve_mask) do { \ - uint32_t db = mmio_read_32(addr) & (preserve_mask); \ - mmio_write_32(addr, db | (modify_mask)); \ - } while (0) - -#define MHU_V2_ACCESS_REQUEST(addr) \ - mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x1) - -#define MHU_V2_CLEAR_REQUEST(addr) \ - mmio_write_32((addr) + MHU_V2_ACCESS_REQ_OFFSET, 0x0) - -#define MHU_V2_IS_ACCESS_READY(addr) \ - (mmio_read_32((addr) + MHU_V2_ACCESS_READY_OFFSET) & 0x1) - -struct scmi_channel_plat_info; -void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info); -void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info); - -#endif /* CSS_MHU_DOORBELL_H */ diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c index ca40c30..5fe268d 100644 --- a/plat/arm/css/drivers/scp/css_bom_bootloader.c +++ b/plat/arm/css/drivers/scp/css_bom_bootloader.c @@ -9,10 +9,10 @@ #include #include +#include #include #include -#include "../mhu/css_mhu.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 index d64bfa2..4965c66 100644 --- a/plat/arm/css/drivers/scpi/css_scpi.c +++ b/plat/arm/css/drivers/scpi/css_scpi.c @@ -9,11 +9,11 @@ #include #include +#include #include #include #include -#include "../mhu/css_mhu.h" #include "css_scpi.h" #define SCPI_SHARED_MEM_SCP_TO_AP PLAT_CSS_SCP_COM_SHARED_MEM_BASE diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c index 82d8fed..bfcb521 100644 --- a/plat/arm/css/sgi/sgi_bl31_setup.c +++ b/plat/arm/css/sgi/sgi_bl31_setup.c @@ -10,14 +10,13 @@ #include #include +#include #include #include #include #include -#include "../../css/drivers/mhu/css_mhu_doorbell.h" - sgi_platform_info_t sgi_plat_info; static scmi_channel_plat_info_t sgi575_scmi_plat_info = { diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c index d9490b1..7e92ac8 100644 --- a/plat/arm/css/sgm/sgm_bl31_setup.c +++ b/plat/arm/css/sgm/sgm_bl31_setup.c @@ -6,11 +6,11 @@ #include #include +#include #include #include #include -#include "../../css/drivers/mhu/css_mhu_doorbell.h" static scmi_channel_plat_info_t sgm775_scmi_plat_info = { .scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,