xref: /arm-trusted-firmware/plat/arm/board/n1sdp/n1sdp_bl2_setup.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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