diff --git a/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S index c03185a..3da55b6 100644 --- a/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S +++ b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S @@ -17,19 +17,20 @@ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) * * Helper function to calculate the core position. - * (ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER * N1SDP_MAX_PE_PER_CPU) + - * (CPUId * N1SDP_MAX_PE_PER_CPU) + - * ThreadId + * ((ChipId * N1SDP_MAX_CLUSTERS_PER_CHIP + ClusterId) * + * N1SDP_MAX_CPUS_PER_CLUSTER * N1SDP_MAX_PE_PER_CPU) + + * (CPUId * N1SDP_MAX_PE_PER_CPU) + ThreadId * * which can be simplified as: * - * ((ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER + CPUId) * - * N1SDP_MAX_PE_PER_CPU) + ThreadId + * (((ChipId * N1SDP_MAX_CLUSTERS_PER_CHIP + ClusterId) * + * N1SDP_MAX_CPUS_PER_CLUSTER + CPUId) * N1SDP_MAX_PE_PER_CPU) + + * ThreadId * ------------------------------------------------------ */ func plat_arm_calc_core_pos - mov x3, x0 + mov x4, x0 /* * The MT bit in MPIDR is always set for n1sdp and the @@ -37,15 +38,18 @@ */ /* Extract individual affinity fields from MPIDR */ - ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS /* Compute linear position */ + mov x4, #N1SDP_MAX_CLUSTERS_PER_CHIP + madd x2, x3, x4, x2 mov x4, #N1SDP_MAX_CPUS_PER_CLUSTER madd x1, x2, x4, x1 - mov x5, #N1SDP_MAX_PE_PER_CPU - madd x0, x1, x5, x0 + mov x4, #N1SDP_MAX_PE_PER_CPU + madd x0, x1, x4, x0 ret endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index 7348bf5..6a309e8 100644 --- a/plat/arm/board/n1sdp/include/platform_def.h +++ b/plat/arm/board/n1sdp/include/platform_def.h @@ -27,16 +27,27 @@ #define PLAT_ARM_DRAM2_BASE ULL(0x8080000000) #define PLAT_ARM_DRAM2_SIZE ULL(0xF80000000) +/* N1SDP remote chip at 4 TB offset */ +#define PLAT_ARM_REMOTE_CHIP_OFFSET (ULL(1) << 42) + +#define N1SDP_REMOTE_DRAM1_BASE ARM_DRAM1_BASE + \ + PLAT_ARM_REMOTE_CHIP_OFFSET +#define N1SDP_REMOTE_DRAM1_SIZE ARM_DRAM1_SIZE + +#define N1SDP_REMOTE_DRAM2_BASE PLAT_ARM_DRAM2_BASE + \ + PLAT_ARM_REMOTE_CHIP_OFFSET +#define N1SDP_REMOTE_DRAM2_SIZE PLAT_ARM_DRAM2_SIZE + /* * N1SDP platform supports RDIMMs with ECC capability. To use the ECC * capability, the entire DDR memory space has to be zeroed out before - * enabling the ECC bits in DMC620. The access the complete DDR memory - * space the physical & virtual address space limits are extended to - * 40-bits. + * enabling the ECC bits in DMC620. To access the complete DDR memory + * along with remote chip's DDR memory, which is at 4 TB offset, physical + * and virtual address space limits are extended to 43-bits. */ #ifdef __aarch64__ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 40) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 40) +#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) @@ -51,34 +62,36 @@ #define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */ #define PLAT_ARM_MAX_BL31_SIZE 0X20000 - /******************************************************************************* * N1SDP topology related constants ******************************************************************************/ -#define N1SDP_MAX_CPUS_PER_CLUSTER 2 -#define PLAT_ARM_CLUSTER_COUNT 2 -#define N1SDP_MAX_PE_PER_CPU 1 +#define N1SDP_MAX_CPUS_PER_CLUSTER U(2) +#define PLAT_ARM_CLUSTER_COUNT U(2) +#define PLAT_N1SDP_CHIP_COUNT U(2) +#define N1SDP_MAX_CLUSTERS_PER_CHIP U(2) +#define N1SDP_MAX_PE_PER_CPU U(1) -#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ +#define PLATFORM_CORE_COUNT (PLAT_N1SDP_CHIP_COUNT * \ + PLAT_ARM_CLUSTER_COUNT * \ N1SDP_MAX_CPUS_PER_CLUSTER * \ N1SDP_MAX_PE_PER_CPU) /* System power domain level */ -#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL3 /* * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the * plat_arm_mmap array defined for each BL stage. */ -#define PLAT_ARM_MMAP_ENTRIES 6 -#define MAX_XLAT_TABLES 7 +#define PLAT_ARM_MMAP_ENTRIES 9 +#define MAX_XLAT_TABLES 10 #define PLATFORM_STACK_SIZE 0x400 #define PLAT_ARM_NSTIMER_FRAME_ID 0 #define PLAT_CSS_MHU_BASE 0x45000000 #define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE -#define PLAT_MAX_PWR_LVL 1 +#define PLAT_MAX_PWR_LVL 2 #define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \ CSS_IRQ_MHU @@ -88,17 +101,36 @@ #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) -#define N1SDP_DEVICE_BASE (0x08000000) -#define N1SDP_DEVICE_SIZE (0x48000000) -#define N1SDP_MAP_DEVICE MAP_REGION_FLAT( \ - N1SDP_DEVICE_BASE, \ - N1SDP_DEVICE_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) +#define N1SDP_DEVICE_BASE ULL(0x08000000) +#define N1SDP_DEVICE_SIZE ULL(0x48000000) +#define N1SDP_REMOTE_DEVICE_BASE N1SDP_DEVICE_BASE + \ + PLAT_ARM_REMOTE_CHIP_OFFSET +#define N1SDP_REMOTE_DEVICE_SIZE N1SDP_DEVICE_SIZE -#define ARM_MAP_DRAM1 MAP_REGION_FLAT( \ - ARM_DRAM1_BASE, \ - ARM_DRAM1_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) +#define N1SDP_MAP_DEVICE MAP_REGION_FLAT( \ + N1SDP_DEVICE_BASE, \ + N1SDP_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define ARM_MAP_DRAM1 MAP_REGION_FLAT( \ + ARM_DRAM1_BASE, \ + ARM_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define N1SDP_MAP_REMOTE_DEVICE MAP_REGION_FLAT( \ + N1SDP_REMOTE_DEVICE_BASE, \ + N1SDP_REMOTE_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define N1SDP_MAP_REMOTE_DRAM1 MAP_REGION_FLAT( \ + N1SDP_REMOTE_DRAM1_BASE, \ + N1SDP_REMOTE_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define N1SDP_MAP_REMOTE_DRAM2 MAP_REGION_FLAT( \ + N1SDP_REMOTE_DRAM2_BASE, \ + N1SDP_REMOTE_DRAM2_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) /* GIC related constants */ #define PLAT_ARM_GICD_BASE 0x30000000 diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index 632af7b..79a0a79 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,14 +17,22 @@ #include "n1sdp_def.h" /* - * Memory information structure stored in SDS. - * This structure holds the total DDR memory size which will be - * used when zeroing out the entire DDR memory before enabling - * the ECC capability in DMCs. + * Platform information structure stored in SDS. + * This structure holds information about platform's DDR + * size which will be used to zero out the memory before + * enabling the ECC capability as well as information + * about multichip setup + * - multichip mode + * - slave_count + * - Local DDR size in GB, DDR memory in master board + * - Remote DDR size in GB, DDR memory in slave board */ -struct n1sdp_mem_info { - uint32_t ddr_size_gb; -}; +struct n1sdp_plat_info { + bool multichip_mode; + uint8_t slave_count; + uint8_t local_ddr_size; + uint8_t remote_ddr_size; +} __packed; /* * BL33 image information structure stored in SDS. @@ -38,11 +46,11 @@ }; 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, - .db_preserve_mask = 0xfffffffe, - .db_modify_mask = 0x1, - .ring_doorbell = &mhu_ring_doorbell, + .scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE, + .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 }; scmi_channel_plat_info_t *plat_css_get_scmi_info() @@ -66,7 +74,7 @@ * from IOFPGA-DDR3 memory to main DDR4 memory. */ -void dmc_ecc_setup(uint32_t ddr_size_gb) +void dmc_ecc_setup(uint8_t ddr_size_gb) { uint64_t dram2_size; @@ -93,6 +101,38 @@ mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY); } +void remote_dmc_ecc_setup(uint8_t remote_ddr_size) +{ + uint64_t remote_dram2_size; + + remote_dram2_size = (remote_ddr_size * 1024UL * 1024UL * 1024UL) - + N1SDP_REMOTE_DRAM1_SIZE; + /* multichip setup */ + INFO("Zeroing remote DDR memories\n"); + zero_normalmem((void *)N1SDP_REMOTE_DRAM1_BASE, + N1SDP_REMOTE_DRAM1_SIZE); + flush_dcache_range(N1SDP_REMOTE_DRAM1_BASE, N1SDP_REMOTE_DRAM1_SIZE); + zero_normalmem((void *)N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size); + flush_dcache_range(N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size); + + INFO("Enabling ECC on remote DMCs\n"); + /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */ + mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG, + N1SDP_DMC_MEMC_CMD_CONFIG); + mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG, + N1SDP_DMC_MEMC_CMD_CONFIG); + + /* Enable ECC in DMCs */ + mmio_setbits_32(N1SDP_REMOTE_DMC0_ERR0CTLR0_REG, + N1SDP_DMC_ERR0CTLR0_ECC_EN); + mmio_setbits_32(N1SDP_REMOTE_DMC1_ERR0CTLR0_REG, + N1SDP_DMC_ERR0CTLR0_ECC_EN); + + /* Set DMCs to READY state */ + mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY); + mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY); +} + void copy_bl33(uint32_t src, uint32_t dst, uint32_t size) { uint32_t i; @@ -112,7 +152,7 @@ void bl31_platform_setup(void) { int ret; - struct n1sdp_mem_info mem_info; + struct n1sdp_plat_info plat_info; struct n1sdp_bl33_info bl33_info; arm_bl31_platform_setup(); @@ -123,16 +163,29 @@ panic(); } - ret = sds_struct_read(N1SDP_SDS_MEM_INFO_STRUCT_ID, - N1SDP_SDS_MEM_INFO_OFFSET, - &mem_info, - N1SDP_SDS_MEM_INFO_SIZE, + ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID, + N1SDP_SDS_PLATFORM_INFO_OFFSET, + &plat_info, + N1SDP_SDS_PLATFORM_INFO_SIZE, SDS_ACCESS_MODE_NON_CACHED); if (ret != SDS_OK) { - ERROR("Error getting memory info from SDS\n"); + ERROR("Error getting platform info from SDS\n"); panic(); } - dmc_ecc_setup(mem_info.ddr_size_gb); + /* Validate plat_info SDS */ + if ((plat_info.local_ddr_size == 0) + || (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB) + || (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB) + || (plat_info.slave_count > N1SDP_MAX_SLAVE_COUNT)) { + ERROR("platform info SDS is corrupted\n"); + panic(); + } + + dmc_ecc_setup(plat_info.local_ddr_size); + + /* Check if remote memory is present */ + if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0)) + remote_dmc_ecc_setup(plat_info.remote_ddr_size); ret = sds_struct_read(N1SDP_SDS_BL33_INFO_STRUCT_ID, N1SDP_SDS_BL33_INFO_OFFSET, @@ -147,11 +200,11 @@ bl33_info.bl33_dst_addr, bl33_info.bl33_size); /* - * Pass DDR memory size info to BL33. This method is followed as + * Pass platform information to BL33. This method is followed as * currently there is no BL1/BL2 involved in boot flow of N1SDP. * When TBBR is implemented for N1SDP, this method should be removed - * and DDR memory size shoule be passed to BL33 using NT_FW_CONFIG + * and platform information should be passed to BL33 using NT_FW_CONFIG * passing mechanism. */ - mmio_write_32(N1SDP_DDR_MEM_INFO_BASE, mem_info.ddr_size_gb); + mmio_write_32(N1SDP_PLATFORM_INFO_BASE, *(uint32_t *)&plat_info); } diff --git a/plat/arm/board/n1sdp/n1sdp_def.h b/plat/arm/board/n1sdp/n1sdp_def.h index d43c5a4..30e29a7 100644 --- a/plat/arm/board/n1sdp/n1sdp_def.h +++ b/plat/arm/board/n1sdp/n1sdp_def.h @@ -15,10 +15,12 @@ N1SDP_NS_SRAM_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -/* SDS memory information defines */ -#define N1SDP_SDS_MEM_INFO_STRUCT_ID 8 -#define N1SDP_SDS_MEM_INFO_OFFSET 0 -#define N1SDP_SDS_MEM_INFO_SIZE 4 +/* SDS Platform information defines */ +#define N1SDP_SDS_PLATFORM_INFO_STRUCT_ID 8 +#define N1SDP_SDS_PLATFORM_INFO_OFFSET 0 +#define N1SDP_SDS_PLATFORM_INFO_SIZE 4 +#define N1SDP_MAX_DDR_CAPACITY_GB 64 +#define N1SDP_MAX_SLAVE_COUNT 16 /* SDS BL33 image information defines */ #define N1SDP_SDS_BL33_INFO_STRUCT_ID 9 @@ -33,6 +35,18 @@ #define N1SDP_DMC0_ERR0CTLR0_REG 0x4E000708 #define N1SDP_DMC1_ERR0CTLR0_REG 0x4E100708 +/* Remote DMC memory command registers */ +#define N1SDP_REMOTE_DMC0_MEMC_CMD_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\ + N1SDP_DMC0_MEMC_CMD_REG +#define N1SDP_REMOTE_DMC1_MEMC_CMD_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\ + N1SDP_DMC1_MEMC_CMD_REG + +/* Remote DMC ERR0CTLR0 registers */ +#define N1SDP_REMOTE_DMC0_ERR0CTLR0_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\ + N1SDP_DMC0_ERR0CTLR0_REG +#define N1SDP_REMOTE_DMC1_ERR0CTLR0_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\ + N1SDP_DMC1_ERR0CTLR0_REG + /* DMC memory commands */ #define N1SDP_DMC_MEMC_CMD_CONFIG 0 #define N1SDP_DMC_MEMC_CMD_READY 3 @@ -40,7 +54,7 @@ /* DMC ECC enable bit in ERR0CTLR0 register */ #define N1SDP_DMC_ERR0CTLR0_ECC_EN 0x1 -/* Base address of non-secure SRAM where DDR memory size will be filled */ -#define N1SDP_DDR_MEM_INFO_BASE 0x06008000 +/* Base address of non-secure SRAM where Platform information will be filled */ +#define N1SDP_PLATFORM_INFO_BASE 0x06008000 #endif /* N1SDP_DEF_H */ diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c index a32ca72..951a562 100644 --- a/plat/arm/board/n1sdp/n1sdp_plat.c +++ b/plat/arm/board/n1sdp/n1sdp_plat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,6 +25,9 @@ N1SDP_MAP_NS_SRAM, ARM_MAP_DRAM1, ARM_MAP_DRAM2, + N1SDP_MAP_REMOTE_DEVICE, + N1SDP_MAP_REMOTE_DRAM1, + N1SDP_MAP_REMOTE_DRAM2, {0} }; diff --git a/plat/arm/board/n1sdp/n1sdp_topology.c b/plat/arm/board/n1sdp/n1sdp_topology.c index edf1170..5c2db71 100644 --- a/plat/arm/board/n1sdp/n1sdp_topology.c +++ b/plat/arm/board/n1sdp/n1sdp_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,7 +19,11 @@ * indices returned by plat_core_pos_by_mpidr(). */ const unsigned char n1sdp_pd_tree_desc[] = { + PLAT_N1SDP_CHIP_COUNT, PLAT_ARM_CLUSTER_COUNT, + PLAT_ARM_CLUSTER_COUNT, + N1SDP_MAX_CPUS_PER_CLUSTER, + N1SDP_MAX_CPUS_PER_CLUSTER, N1SDP_MAX_CPUS_PER_CLUSTER, N1SDP_MAX_CPUS_PER_CLUSTER }; @@ -52,4 +56,4 @@ * to the SCMI power domain ID implemented by SCP. ******************************************************************************/ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = { - 0, 1, 2, 3}; + 0, 1, 2, 3, 4, 5, 6, 7};