Browse Source

board/rdn1edge: add support for dual-chip configuration

RD-N1-Edge based platforms can operate in dual-chip configuration
wherein two rdn1edge SoCs are connected through a high speed coherent
CCIX link.

This patch adds a function to check if the RD-N1-Edge platform is
operating in multi-chip mode by reading the SID register's NODE_ID
value. If operating in multi-chip mode, initialize GIC-600 multi-chip
operation by overriding the default GICR frames with array of GICR
frames and setting the chip 0 as routing table owner.

The address space of the second RD-N1-Edge chip (chip 1) starts from the
address 4TB. So increase the physical and virtual address space size to
43 bits to accommodate the multi-chip configuration. If the multi-chip
mode configuration is detected, dynamically add mmap entry for the
peripherals memory region of the second RD-N1-Edge SoC. This is required
to let the BL31 platform setup stage to configure the devices in the
second chip.

PLATFORM_CORE_COUNT macro is set to be multiple of CSS_SGI_CHIP_COUNT
and topology changes are added to represent the dual-chip configuration.

In order the build the dual-chip platform, CSS_SGI_CHIP_COUNT macro
should be set to 2:
export CROSS_COMPILE=<path-to-cross-compiler>
make PLAT=rdn1edge CSS_SGI_CHIP_COUNT=2 ARCH=aarch64 all

Change-Id: I576cdaf71f0b0e41b9a9181fa4feb7091f8c7bb4
Signed-off-by: Aditya Angadi <aditya.angadi@arm.com>
Signed-off-by: Vijayenthiran Subramaniam <vijayenthiran.subramaniam@arm.com>
pull/1938/head
Vijayenthiran Subramaniam 5 years ago
parent
commit
2d4b719cc6
  1. 7
      plat/arm/board/rdn1edge/include/platform_def.h
  2. 10
      plat/arm/board/rdn1edge/platform.mk
  3. 67
      plat/arm/board/rdn1edge/rdn1edge_plat.c
  4. 26
      plat/arm/board/rdn1edge/rdn1edge_topology.c
  5. 9
      plat/arm/css/sgi/include/sgi_base_platform_def.h
  6. 44
      plat/arm/css/sgi/sgi_bl31_setup.c

7
plat/arm/board/rdn1edge/include/platform_def.h

@ -26,12 +26,15 @@
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL1
/* Virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
*/
#ifdef __aarch64__
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43)
#else
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)

10
plat/arm/board/rdn1edge/platform.mk

@ -26,6 +26,7 @@ BL31_SOURCES += ${SGI_CPU_SOURCES} \
${RDN1EDGE_BASE}/rdn1edge_plat.c \
${RDN1EDGE_BASE}/rdn1edge_topology.c \
drivers/cfi/v2m/v2m_flash.c \
drivers/arm/gic/v3/gic600_multichip.c \
lib/utils/mem_region.c \
plat/arm/common/arm_nor_psci_mem_protect.c
@ -34,6 +35,9 @@ BL1_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c
BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_trusted_boot.c
endif
# Enable dynamic addition of MMAP regions in BL31
BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
# Add the FDT_SOURCES and options for Dynamic Config
FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_tb_fw_config.dts
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
@ -47,9 +51,9 @@ NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
# Add the NT_FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${NT_FW_CONFIG},--nt-fw-config))
ifneq ($(CSS_SGI_CHIP_COUNT),1)
$(error "Chip count for RDN1Edge should be 1, currently set to \
${CSS_SGI_CHIP_COUNT}.")
ifneq ($(CSS_SGI_CHIP_COUNT),$(filter $(CSS_SGI_CHIP_COUNT),1 2))
$(error "Chip count for RDN1Edge platform should either 1 or 2, currently \
set to ${CSS_SGI_CHIP_COUNT}.")
endif
override CTX_INCLUDE_AARCH32_REGS := 0

67
plat/arm/board/rdn1edge/rdn1edge_plat.c

@ -4,9 +4,42 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#include <drivers/arm/gic600_multichip.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <sgi_base_platform_def.h>
#include <sgi_plat.h>
#if defined(IMAGE_BL31)
static const mmap_region_t rdn1edge_dynamic_mmap[] = {
ARM_MAP_SHARED_RAM_REMOTE_CHIP(1),
CSS_SGI_MAP_DEVICE_REMOTE_CHIP(1),
SOC_CSS_MAP_DEVICE_REMOTE_CHIP(1)
};
static struct gic600_multichip_data rdn1e1_multichip_data __init = {
.rt_owner_base = PLAT_ARM_GICD_BASE,
.rt_owner = 0,
.chip_count = CSS_SGI_CHIP_COUNT,
.chip_addrs = {
PLAT_ARM_GICD_BASE >> 16,
(PLAT_ARM_GICD_BASE + CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1)) >> 16
},
.spi_ids = {
{32, 255},
{0, 0}
}
};
static uintptr_t rdn1e1_multichip_gicr_frames[] = {
PLAT_ARM_GICR_BASE, /* Chip 0's GICR Base */
PLAT_ARM_GICR_BASE +
CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1), /* Chip 1's GICR BASE */
UL(0) /* Zero Termination */
};
#endif /* IMAGE_BL31 */
unsigned int plat_arm_sgi_get_platform_id(void)
{
return mmio_read_32(SID_REG_BASE + SID_SYSTEM_ID_OFFSET)
@ -24,7 +57,41 @@ unsigned int plat_arm_sgi_get_multi_chip_mode(void)
SID_MULTI_CHIP_MODE_MASK) >> SID_MULTI_CHIP_MODE_SHIFT;
}
/*
* IMAGE_BL31 macro is added to build bl31_platform_setup function only for BL31
* because PLAT_XLAT_TABLES_DYNAMIC macro is set to build only for BL31 and not
* for other stages.
*/
#if defined(IMAGE_BL31)
void bl31_platform_setup(void)
{
int i, ret;
if (plat_arm_sgi_get_multi_chip_mode() == 0 && CSS_SGI_CHIP_COUNT > 1) {
ERROR("Chip Count is set to %d but multi-chip mode not enabled\n",
CSS_SGI_CHIP_COUNT);
panic();
} else if (plat_arm_sgi_get_multi_chip_mode() == 1 &&
CSS_SGI_CHIP_COUNT > 1) {
INFO("Enabling support for multi-chip in RD-N1-Edge\n");
for (i = 0; i < ARRAY_SIZE(rdn1edge_dynamic_mmap); i++) {
ret = mmap_add_dynamic_region(
rdn1edge_dynamic_mmap[i].base_pa,
rdn1edge_dynamic_mmap[i].base_va,
rdn1edge_dynamic_mmap[i].size,
rdn1edge_dynamic_mmap[i].attr
);
if (ret != 0) {
ERROR("Failed to add dynamic mmap entry\n");
panic();
}
}
plat_arm_override_gicr_frames(rdn1e1_multichip_gicr_frames);
gic600_multichip_init(&rdn1e1_multichip_data);
}
sgi_bl31_common_platform_setup();
}
#endif /* IMAGE_BL31 */

26
plat/arm/board/rdn1edge/rdn1edge_topology.c

@ -5,14 +5,19 @@
*/
#include <plat/arm/common/plat_arm.h>
#include <plat/arm/css/common/css_pm.h>
/******************************************************************************
* The power domain tree descriptor.
******************************************************************************/
static const unsigned char rdn1edge_pd_tree_desc[] = {
PLAT_ARM_CLUSTER_COUNT,
(PLAT_ARM_CLUSTER_COUNT) * (CSS_SGI_CHIP_COUNT),
CSS_SGI_MAX_CPUS_PER_CLUSTER,
CSS_SGI_MAX_CPUS_PER_CLUSTER,
#if (CSS_SGI_CHIP_COUNT > 1)
CSS_SGI_MAX_CPUS_PER_CLUSTER,
CSS_SGI_MAX_CPUS_PER_CLUSTER
#endif
};
/*******************************************************************************
@ -28,5 +33,22 @@ const unsigned char *plat_get_power_domain_tree_desc(void)
* to the SCMI power domain ID implemented by SCP.
******************************************************************************/
const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = {
0, 1, 2, 3, 4, 5, 6, 7
(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x0)),
(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x1)),
(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x2)),
(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x3)),
(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x4)),
(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x5)),
(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x6)),
(SET_SCMI_CHANNEL_ID(0x0) | SET_SCMI_DOMAIN_ID(0x7)),
#if (CSS_SGI_CHIP_COUNT > 1)
(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x0)),
(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x1)),
(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x2)),
(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x3)),
(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x4)),
(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x5)),
(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x6)),
(SET_SCMI_CHANNEL_ID(0x1) | SET_SCMI_DOMAIN_ID(0x7)),
#endif
};

9
plat/arm/css/sgi/include/sgi_base_platform_def.h

@ -17,8 +17,9 @@
#include <plat/arm/soc/common/soc_css_def.h>
#include <plat/common/common_def.h>
#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
CSS_SGI_MAX_CPUS_PER_CLUSTER * \
#define PLATFORM_CORE_COUNT (CSS_SGI_CHIP_COUNT * \
PLAT_ARM_CLUSTER_COUNT * \
CSS_SGI_MAX_CPUS_PER_CLUSTER * \
CSS_SGI_MAX_PE_PER_CPU)
#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */
@ -38,14 +39,14 @@
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
# define PLAT_ARM_MMAP_ENTRIES 8
# define MAX_XLAT_TABLES 5
# define MAX_XLAT_TABLES 8
# endif
#elif defined(IMAGE_BL32)
# define PLAT_ARM_MMAP_ENTRIES 8
# define MAX_XLAT_TABLES 5
#elif !USE_ROMLIB
# define PLAT_ARM_MMAP_ENTRIES 11
# define MAX_XLAT_TABLES 5
# define MAX_XLAT_TABLES 7
#else
# define PLAT_ARM_MMAP_ENTRIES 12
# define MAX_XLAT_TABLES 6

44
plat/arm/css/sgi/sgi_bl31_setup.c

@ -28,18 +28,56 @@ static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
.ring_doorbell = &mhu_ring_doorbell,
};
static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info = {
static scmi_channel_plat_info_t rd_n1e1_edge_scmi_plat_info[] = {
{
.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
.db_reg_addr = PLAT_CSS_MHU_BASE + SENDER_REG_SET(0),
.db_preserve_mask = 0xfffffffe,
.db_modify_mask = 0x1,
.ring_doorbell = &mhuv2_ring_doorbell,
},
#if (CSS_SGI_CHIP_COUNT > 1)
{
.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1),
.db_reg_addr = PLAT_CSS_MHU_BASE
+ CSS_SGI_REMOTE_CHIP_MEM_OFFSET(1) + SENDER_REG_SET(0),
.db_preserve_mask = 0xfffffffe,
.db_modify_mask = 0x1,
.ring_doorbell = &mhuv2_ring_doorbell,
},
#endif
#if (CSS_SGI_CHIP_COUNT > 2)
{
.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2),
.db_reg_addr = PLAT_CSS_MHU_BASE +
CSS_SGI_REMOTE_CHIP_MEM_OFFSET(2) + SENDER_REG_SET(0),
.db_preserve_mask = 0xfffffffe,
.db_modify_mask = 0x1,
.ring_doorbell = &mhuv2_ring_doorbell,
},
#endif
#if (CSS_SGI_CHIP_COUNT > 3)
{
.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE +
CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3),
.db_reg_addr = PLAT_CSS_MHU_BASE +
CSS_SGI_REMOTE_CHIP_MEM_OFFSET(3) + SENDER_REG_SET(0),
.db_preserve_mask = 0xfffffffe,
.db_modify_mask = 0x1,
.ring_doorbell = &mhuv2_ring_doorbell,
},
#endif
};
scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
{
if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM)
return &rd_n1e1_edge_scmi_plat_info;
if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM) {
if (channel_id >= sizeof(rd_n1e1_edge_scmi_plat_info))
panic();
return &rd_n1e1_edge_scmi_plat_info[channel_id];
}
else if (sgi_plat_info.platform_id == SGI575_SSC_VER_PART_NUM)
return &sgi575_scmi_plat_info;
else

Loading…
Cancel
Save