From a427785c8316a2e0400e9be3ab765db36f65f25f Mon Sep 17 00:00:00 2001 From: Samarth Parikh Date: Thu, 23 Nov 2017 14:23:21 +0530 Subject: [PATCH] plat/arm: Add MHUv2 support to SCMI driver Currently the SCMI driver supports MHUv1, but Arm platforms may have varied versions of MHU driver, with MHUv2 controllers being in the latest Arm platforms. This patch updates the SCMI driver to support MHUv2, specifically that the sender must send the wake-up to the receiver before initiating any data transfer. Also, the existing mhu driver files, css_mhu.c and css_mhu.h, have been moved from the scpi directory to a new directory, css/drivers/mhu. Change-Id: I9b46b492a3e1d9e26db12d83a9773958a8c8402f Signed-off-by: Samarth Parikh --- plat/arm/css/common/css_common.mk | 9 ++-- plat/arm/css/common/sp_min/css_sp_min.mk | 7 +-- plat/arm/css/drivers/{scpi => mhu}/css_mhu.c | 2 +- plat/arm/css/drivers/{scpi => mhu}/css_mhu.h | 2 +- plat/arm/css/drivers/mhu/css_mhu_doorbell.c | 37 ++++++++++++++++ plat/arm/css/drivers/mhu/css_mhu_doorbell.h | 43 +++++++++++++++++++ plat/arm/css/drivers/scmi/scmi.h | 6 ++- plat/arm/css/drivers/scmi/scmi_common.c | 7 ++- plat/arm/css/drivers/scmi/scmi_private.h | 8 +--- plat/arm/css/drivers/scp/css_bom_bootloader.c | 2 +- plat/arm/css/drivers/scp/css_pm_scmi.c | 2 + plat/arm/css/drivers/scpi/css_scpi.c | 4 +- 12 files changed, 105 insertions(+), 24 deletions(-) rename plat/arm/css/drivers/{scpi => mhu}/css_mhu.c (97%) rename plat/arm/css/drivers/{scpi => mhu}/css_mhu.h (85%) create mode 100644 plat/arm/css/drivers/mhu/css_mhu_doorbell.c create mode 100644 plat/arm/css/drivers/mhu/css_mhu_doorbell.h diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk index cfbb3e92c..72d5527b6 100644 --- a/plat/arm/css/common/css_common.mk +++ b/plat/arm/css/common/css_common.mk @@ -28,13 +28,14 @@ BL31_SOURCES += plat/arm/css/common/css_pm.c \ 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 @@ ifeq (${CSS_LOAD_SCP_IMAGES},1) 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 28eb2dbda..9fb280c86 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 @@ BL32_SOURCES += plat/arm/css/common/css_pm.c \ 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/scpi/css_mhu.c b/plat/arm/css/drivers/mhu/css_mhu.c similarity index 97% rename from plat/arm/css/drivers/scpi/css_mhu.c rename to plat/arm/css/drivers/mhu/css_mhu.c index 500b8df91..30492a695 100644 --- a/plat/arm/css/drivers/scpi/css_mhu.c +++ b/plat/arm/css/drivers/mhu/css_mhu.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 */ diff --git a/plat/arm/css/drivers/scpi/css_mhu.h b/plat/arm/css/drivers/mhu/css_mhu.h similarity index 85% rename from plat/arm/css/drivers/scpi/css_mhu.h rename to plat/arm/css/drivers/mhu/css_mhu.h index 298eee90c..0fb00c76e 100644 --- a/plat/arm/css/drivers/scpi/css_mhu.h +++ b/plat/arm/css/drivers/mhu/css_mhu.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ 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 000000000..b9faf679b --- /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 000000000..3c9453688 --- /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 850402a54..cf9ef5e9a 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 @@ typedef struct scmi_channel_plat_info { 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 d0051c7a6..8482d219c 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 @@ void scmi_send_sync_command(scmi_channel_t *ch) */ 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 @@ void *scmi_init(scmi_channel_t *ch) 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 20e1e9b8a..a07841ee3 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 08d6fc58f..42ed30d3d 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 f8bc20c30..5f6749696 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 @@ scmi_channel_plat_info_t plat_css_scmi_plat_info = { .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_scpi.c b/plat/arm/css/drivers/scpi/css_scpi.c index 3e92c86cb..2ed576011 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