1 /* 2 * Copyright (c) 2022-2024, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <common/debug.h> 8 #include <drivers/arm/css/sds.h> 9 #include <lib/mmio.h> 10 #include <lib/utils.h> 11 12 #include "n1sdp_def.h" 13 #include <plat/arm/common/plat_arm.h> 14 #include <platform_def.h> 15 16 struct n1sdp_plat_info { 17 bool multichip_mode; 18 uint8_t secondary_count; 19 uint8_t local_ddr_size; 20 uint8_t remote_ddr_size; 21 } __packed; 22 23 /* 24 * N1SDP platform supports RDIMMs with ECC capability. To use the ECC 25 * capability, the entire DDR memory space has to be zeroed out before 26 * enabling the ECC bits in DMC620. Zeroing out several gigabytes of 27 * memory from SCP is quite time consuming so the following function 28 * is added to zero out the DDR memory from application processor which is 29 * much faster compared to SCP. 30 */ 31 32 void dmc_ecc_setup(uint8_t ddr_size_gb) 33 { 34 uint64_t dram2_size; 35 36 dram2_size = (ddr_size_gb * 1024UL * 1024UL * 1024UL) - 37 ARM_DRAM1_SIZE; 38 39 INFO("Zeroing DDR memories\n"); 40 zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE); 41 flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE); 42 zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size); 43 flush_dcache_range(ARM_DRAM2_BASE, dram2_size); 44 45 INFO("Enabling ECC on DMCs\n"); 46 /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */ 47 mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG); 48 mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_CONFIG); 49 50 /* Enable ECC in DMCs */ 51 mmio_setbits_32(N1SDP_DMC0_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN); 52 mmio_setbits_32(N1SDP_DMC1_ERR0CTLR0_REG, N1SDP_DMC_ERR0CTLR0_ECC_EN); 53 54 /* Set DMCs to READY state */ 55 mmio_write_32(N1SDP_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY); 56 mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY); 57 } 58 59 void bl2_platform_setup(void) 60 { 61 int ret; 62 struct n1sdp_plat_info plat_info; 63 64 ret = sds_init(SDS_SCP_AP_REGION_ID); 65 if (ret != SDS_OK) { 66 ERROR("SDS initialization failed\n"); 67 panic(); 68 } 69 70 ret = sds_struct_read(SDS_SCP_AP_REGION_ID, 71 N1SDP_SDS_PLATFORM_INFO_STRUCT_ID, 72 N1SDP_SDS_PLATFORM_INFO_OFFSET, 73 &plat_info, 74 N1SDP_SDS_PLATFORM_INFO_SIZE, 75 SDS_ACCESS_MODE_NON_CACHED); 76 if (ret != SDS_OK) { 77 ERROR("Error getting platform info from SDS\n"); 78 panic(); 79 } 80 /* Validate plat_info SDS */ 81 if ((plat_info.local_ddr_size == 0) 82 || (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB) 83 || (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB) 84 || (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT)) { 85 ERROR("platform info SDS is corrupted\n"); 86 panic(); 87 } 88 89 dmc_ecc_setup(plat_info.local_ddr_size); 90 arm_bl2_platform_setup(); 91 } 92