diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk index cfbb3e9..72d5527 100644 --- a/plat/arm/css/common/css_common.mk +++ b/plat/arm/css/common/css_common.mk @@ -28,13 +28,14 @@ ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \ - plat/arm/css/drivers/scpi/css_mhu.c \ + plat/arm/css/drivers/mhu/css_mhu.c \ plat/arm/css/drivers/scpi/css_scpi.c else BL31_SOURCES += plat/arm/css/drivers/scp/css_pm_scmi.c \ plat/arm/css/drivers/scmi/scmi_common.c \ plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c \ - plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c + plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c \ + plat/arm/css/drivers/mhu/css_mhu_doorbell.c endif ifneq (${RESET_TO_BL31},0) @@ -60,11 +61,11 @@ plat/arm/css/drivers/sds/sds.c else BL2U_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \ - plat/arm/css/drivers/scpi/css_mhu.c \ + plat/arm/css/drivers/mhu/css_mhu.c \ plat/arm/css/drivers/scpi/css_scpi.c BL2_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c \ - plat/arm/css/drivers/scpi/css_mhu.c \ + plat/arm/css/drivers/mhu/css_mhu.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 28eb2db..9fb280c 100644 --- a/plat/arm/css/common/sp_min/css_sp_min.mk +++ b/plat/arm/css/common/sp_min/css_sp_min.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -10,11 +10,12 @@ ifeq (${CSS_USE_SCMI_SDS_DRIVER},0) BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scpi.c \ - plat/arm/css/drivers/scpi/css_mhu.c \ + plat/arm/css/drivers/mhu/css_mhu.c \ plat/arm/css/drivers/scpi/css_scpi.c else BL32_SOURCES += plat/arm/css/drivers/scp/css_pm_scmi.c \ plat/arm/css/drivers/scmi/scmi_common.c \ plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c \ - plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c + plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c \ + plat/arm/css/drivers/mhu/css_mhu_doorbell.c endif diff --git a/plat/arm/css/drivers/mhu/css_mhu.c b/plat/arm/css/drivers/mhu/css_mhu.c new file mode 100644 index 0000000..30492a6 --- /dev/null +++ b/plat/arm/css/drivers/mhu/css_mhu.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#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 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 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 new file mode 100644 index 0000000..0fb00c7 --- /dev/null +++ b/plat/arm/css/drivers/mhu/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/plat/arm/css/drivers/mhu/css_mhu_doorbell.c b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c new file mode 100644 index 0000000..b9faf67 --- /dev/null +++ b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include "css_mhu_doorbell.h" +#include "../scmi/scmi.h" + +void mhu_ring_doorbell(scmi_channel_plat_info_t *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(scmi_channel_plat_info_t *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 recevier */ + 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 new file mode 100644 index 0000000..3c94536 --- /dev/null +++ b/plat/arm/css/drivers/mhu/css_mhu_doorbell.h @@ -0,0 +1,43 @@ +/* + * 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/scmi/scmi.h b/plat/arm/css/drivers/scmi/scmi.h index 850402a..cf9ef5e 100644 --- a/plat/arm/css/drivers/scmi/scmi.h +++ b/plat/arm/css/drivers/scmi/scmi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -96,6 +96,10 @@ uint32_t db_preserve_mask; /* The bit mask that need to be set to ring doorbell */ uint32_t db_modify_mask; + /* The handler for ringing doorbell */ + void (*ring_doorbell)(struct scmi_channel_plat_info *plat_info); + /* cookie is unused now. But added for future enhancements. */ + void *cookie; } scmi_channel_plat_info_t; /* diff --git a/plat/arm/css/drivers/scmi/scmi_common.c b/plat/arm/css/drivers/scmi/scmi_common.c index d0051c7..8482d21 100644 --- a/plat/arm/css/drivers/scmi/scmi_common.c +++ b/plat/arm/css/drivers/scmi/scmi_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,9 +39,7 @@ */ dmbst(); - SCMI_RING_DOORBELL(ch->info->db_reg_addr, ch->info->db_modify_mask, - ch->info->db_preserve_mask); - + ch->info->ring_doorbell(ch->info); /* * Ensure that the write to the doorbell register is ordered prior to * checking whether the channel is free. @@ -150,6 +148,7 @@ assert(ch->info->db_reg_addr); assert(ch->info->db_modify_mask); assert(ch->info->db_preserve_mask); + assert(ch->info->ring_doorbell != NULL); assert(ch->lock); diff --git a/plat/arm/css/drivers/scmi/scmi_private.h b/plat/arm/css/drivers/scmi/scmi_private.h index 20e1e9b..a07841e 100644 --- a/plat/arm/css/drivers/scmi/scmi_private.h +++ b/plat/arm/css/drivers/scmi/scmi_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -113,12 +113,6 @@ (val3) = mmio_read_32((uintptr_t)&payld_arr[2]); \ } while (0) -/* Helper macro to ring doorbell */ -#define SCMI_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) - /* * Private data structure for representing the mailbox memory layout. Refer * the SCMI specification for more details. diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c index 08d6fc5..42ed30d 100644 --- a/plat/arm/css/drivers/scp/css_bom_bootloader.c +++ b/plat/arm/css/drivers/scp/css_bom_bootloader.c @@ -10,7 +10,7 @@ #include #include #include -#include "../scpi/css_mhu.h" +#include "../mhu/css_mhu.h" #include "../scpi/css_scpi.h" #include "css_scp.h" diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c index f8bc20c..5f67496 100644 --- a/plat/arm/css/drivers/scp/css_pm_scmi.c +++ b/plat/arm/css/drivers/scp/css_pm_scmi.c @@ -13,6 +13,7 @@ #include #include #include "../scmi/scmi.h" +#include "../mhu/css_mhu_doorbell.h" #include "css_scp.h" /* @@ -302,6 +303,7 @@ .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, .db_preserve_mask = 0xfffffffe, .db_modify_mask = 0x1, + .ring_doorbell = &mhu_ring_doorbell, }; void plat_arm_pwrc_setup(void) diff --git a/plat/arm/css/drivers/scpi/css_mhu.c b/plat/arm/css/drivers/scpi/css_mhu.c deleted file mode 100644 index 500b8df..0000000 --- a/plat/arm/css/drivers/scpi/css_mhu.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#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 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 plat_arm_pwrc_setup(void) -{ - mhu_secure_init(); -} diff --git a/plat/arm/css/drivers/scpi/css_mhu.h b/plat/arm/css/drivers/scpi/css_mhu.h deleted file mode 100644 index 298eee9..0000000 --- a/plat/arm/css/drivers/scpi/css_mhu.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2014-2016, 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/scpi/css_scpi.c b/plat/arm/css/drivers/scpi/css_scpi.c index 3e92c86..2ed5760 100644 --- a/plat/arm/css/drivers/scpi/css_scpi.c +++ b/plat/arm/css/drivers/scpi/css_scpi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ #include #include #include -#include "css_mhu.h" +#include "../mhu/css_mhu.h" #include "css_scpi.h" #define SCPI_SHARED_MEM_SCP_TO_AP PLAT_CSS_SCP_COM_SHARED_MEM_BASE