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