xref: /arm-trusted-firmware/plat/arm/board/morello/morello_bl2_setup.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2021-2023, 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 #include <plat/arm/common/plat_arm.h>
12*91f16700Schasinglulu 
13*91f16700Schasinglulu #include "morello_def.h"
14*91f16700Schasinglulu #include <platform_def.h>
15*91f16700Schasinglulu 
16*91f16700Schasinglulu #ifdef TARGET_PLATFORM_SOC
17*91f16700Schasinglulu /*
18*91f16700Schasinglulu  * Morello platform supports RDIMMs with ECC capability. To use the ECC
19*91f16700Schasinglulu  * capability, the entire DDR memory space has to be zeroed out before
20*91f16700Schasinglulu  * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
21*91f16700Schasinglulu  * memory from SCP is quite time consuming so the following function
22*91f16700Schasinglulu  * is added to zero out the DDR memory from application processor which is
23*91f16700Schasinglulu  * much faster compared to SCP.
24*91f16700Schasinglulu  */
25*91f16700Schasinglulu 
26*91f16700Schasinglulu static void dmc_ecc_setup(struct morello_plat_info *plat_info)
27*91f16700Schasinglulu {
28*91f16700Schasinglulu 	uint64_t dram2_size;
29*91f16700Schasinglulu 	uint32_t val;
30*91f16700Schasinglulu 	uint64_t tag_mem_base;
31*91f16700Schasinglulu 	uint64_t usable_mem_size;
32*91f16700Schasinglulu 
33*91f16700Schasinglulu 	INFO("Total DIMM size: %uGB\n",
34*91f16700Schasinglulu 			(uint32_t)(plat_info->local_ddr_size / 0x40000000));
35*91f16700Schasinglulu 
36*91f16700Schasinglulu 	assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
37*91f16700Schasinglulu 	dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
38*91f16700Schasinglulu 
39*91f16700Schasinglulu 	INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n");
40*91f16700Schasinglulu 	zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
41*91f16700Schasinglulu 	flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
42*91f16700Schasinglulu 
43*91f16700Schasinglulu 	INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
44*91f16700Schasinglulu 		ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
45*91f16700Schasinglulu 	zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
46*91f16700Schasinglulu 	flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
47*91f16700Schasinglulu 
48*91f16700Schasinglulu 	/* Clear previous ECC errors while zeroing out the memory */
49*91f16700Schasinglulu 	val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
50*91f16700Schasinglulu 	mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
51*91f16700Schasinglulu 
52*91f16700Schasinglulu 	val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
53*91f16700Schasinglulu 	mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
54*91f16700Schasinglulu 
55*91f16700Schasinglulu 	/* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
56*91f16700Schasinglulu 	mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
57*91f16700Schasinglulu 	mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
58*91f16700Schasinglulu 
59*91f16700Schasinglulu 	while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
60*91f16700Schasinglulu 			MORELLO_DMC_MEMC_STATUS_MASK) !=
61*91f16700Schasinglulu 			MORELLO_DMC_MEMC_CMD_CONFIG) {
62*91f16700Schasinglulu 		continue;
63*91f16700Schasinglulu 	}
64*91f16700Schasinglulu 
65*91f16700Schasinglulu 	while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
66*91f16700Schasinglulu 			MORELLO_DMC_MEMC_STATUS_MASK) !=
67*91f16700Schasinglulu 			MORELLO_DMC_MEMC_CMD_CONFIG) {
68*91f16700Schasinglulu 		continue;
69*91f16700Schasinglulu 	}
70*91f16700Schasinglulu 
71*91f16700Schasinglulu 	/* Configure Bing client/server mode based on SCC configuration */
72*91f16700Schasinglulu 	if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
73*91f16700Schasinglulu 		INFO("Configuring DMC Bing in client mode\n");
74*91f16700Schasinglulu 		usable_mem_size = plat_info->local_ddr_size -
75*91f16700Schasinglulu 			(plat_info->local_ddr_size / 128ULL);
76*91f16700Schasinglulu 
77*91f16700Schasinglulu 		/* Linear DDR address */
78*91f16700Schasinglulu 		tag_mem_base = usable_mem_size;
79*91f16700Schasinglulu 		tag_mem_base = tag_mem_base / 4;
80*91f16700Schasinglulu 
81*91f16700Schasinglulu 		/* Reverse translation */
82*91f16700Schasinglulu 		if (tag_mem_base < ARM_DRAM1_BASE) {
83*91f16700Schasinglulu 			tag_mem_base += ARM_DRAM1_BASE;
84*91f16700Schasinglulu 		} else {
85*91f16700Schasinglulu 			tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
86*91f16700Schasinglulu 				ARM_DRAM2_BASE;
87*91f16700Schasinglulu 		}
88*91f16700Schasinglulu 
89*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
90*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
91*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
92*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
93*91f16700Schasinglulu 
94*91f16700Schasinglulu 		if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
95*91f16700Schasinglulu 			mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
96*91f16700Schasinglulu 			mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
97*91f16700Schasinglulu 			INFO("C1 Tag Cache Enabled\n");
98*91f16700Schasinglulu 		}
99*91f16700Schasinglulu 
100*91f16700Schasinglulu 		if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
101*91f16700Schasinglulu 			mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
102*91f16700Schasinglulu 			mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
103*91f16700Schasinglulu 			INFO("C2 Tag Cache Enabled\n");
104*91f16700Schasinglulu 		}
105*91f16700Schasinglulu 
106*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
107*91f16700Schasinglulu 				(uint32_t)tag_mem_base);
108*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
109*91f16700Schasinglulu 				(uint32_t)tag_mem_base);
110*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
111*91f16700Schasinglulu 				(uint32_t)(tag_mem_base >> 32));
112*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
113*91f16700Schasinglulu 				(uint32_t)(tag_mem_base >> 32));
114*91f16700Schasinglulu 
115*91f16700Schasinglulu 		mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
116*91f16700Schasinglulu 				MORELLO_DMC_MEM_ACCESS_DIS);
117*91f16700Schasinglulu 		mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
118*91f16700Schasinglulu 				MORELLO_DMC_MEM_ACCESS_DIS);
119*91f16700Schasinglulu 
120*91f16700Schasinglulu 		INFO("Tag base set to 0x%lx\n", tag_mem_base);
121*91f16700Schasinglulu 		plat_info->local_ddr_size = usable_mem_size;
122*91f16700Schasinglulu 	} else {
123*91f16700Schasinglulu 		INFO("Configuring DMC Bing in server mode\n");
124*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
125*91f16700Schasinglulu 		mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
126*91f16700Schasinglulu 	}
127*91f16700Schasinglulu 
128*91f16700Schasinglulu 	INFO("Enabling ECC on DMCs\n");
129*91f16700Schasinglulu 	/* Enable ECC in DMCs */
130*91f16700Schasinglulu 	mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
131*91f16700Schasinglulu 		MORELLO_DMC_ERR0CTLR0_ECC_EN);
132*91f16700Schasinglulu 	mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
133*91f16700Schasinglulu 		MORELLO_DMC_ERR0CTLR0_ECC_EN);
134*91f16700Schasinglulu 
135*91f16700Schasinglulu 	/* Set DMCs to READY state */
136*91f16700Schasinglulu 	mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
137*91f16700Schasinglulu 	mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
138*91f16700Schasinglulu 
139*91f16700Schasinglulu 	while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
140*91f16700Schasinglulu 			MORELLO_DMC_MEMC_STATUS_MASK) !=
141*91f16700Schasinglulu 			MORELLO_DMC_MEMC_CMD_READY) {
142*91f16700Schasinglulu 		continue;
143*91f16700Schasinglulu 	}
144*91f16700Schasinglulu 
145*91f16700Schasinglulu 	while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
146*91f16700Schasinglulu 			MORELLO_DMC_MEMC_STATUS_MASK) !=
147*91f16700Schasinglulu 			MORELLO_DMC_MEMC_CMD_READY) {
148*91f16700Schasinglulu 		continue;
149*91f16700Schasinglulu 	}
150*91f16700Schasinglulu }
151*91f16700Schasinglulu #endif
152*91f16700Schasinglulu 
153*91f16700Schasinglulu void bl2_platform_setup(void)
154*91f16700Schasinglulu {
155*91f16700Schasinglulu 	int ret;
156*91f16700Schasinglulu 	struct morello_plat_info plat_info;
157*91f16700Schasinglulu 
158*91f16700Schasinglulu 	ret = sds_init();
159*91f16700Schasinglulu 	if (ret != SDS_OK) {
160*91f16700Schasinglulu 		ERROR("SDS initialization failed. ret:%d\n", ret);
161*91f16700Schasinglulu 		panic();
162*91f16700Schasinglulu 	}
163*91f16700Schasinglulu 
164*91f16700Schasinglulu 	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
165*91f16700Schasinglulu 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
166*91f16700Schasinglulu 				&plat_info,
167*91f16700Schasinglulu 				MORELLO_SDS_PLATFORM_INFO_SIZE,
168*91f16700Schasinglulu 				SDS_ACCESS_MODE_NON_CACHED);
169*91f16700Schasinglulu 	if (ret != SDS_OK) {
170*91f16700Schasinglulu 		ERROR("Error getting platform info from SDS. ret:%d\n", ret);
171*91f16700Schasinglulu 		panic();
172*91f16700Schasinglulu 	}
173*91f16700Schasinglulu 
174*91f16700Schasinglulu 	/* Validate plat_info SDS */
175*91f16700Schasinglulu #ifdef TARGET_PLATFORM_FVP
176*91f16700Schasinglulu 	if (plat_info.local_ddr_size == 0U) {
177*91f16700Schasinglulu #else
178*91f16700Schasinglulu 	if ((plat_info.local_ddr_size == 0U)
179*91f16700Schasinglulu 		|| (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
180*91f16700Schasinglulu 		|| (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
181*91f16700Schasinglulu 		|| (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
182*91f16700Schasinglulu 		) {
183*91f16700Schasinglulu #endif
184*91f16700Schasinglulu 		ERROR("platform info SDS is corrupted\n");
185*91f16700Schasinglulu 		panic();
186*91f16700Schasinglulu 	}
187*91f16700Schasinglulu 
188*91f16700Schasinglulu #ifdef TARGET_PLATFORM_SOC
189*91f16700Schasinglulu 	dmc_ecc_setup(&plat_info);
190*91f16700Schasinglulu #endif
191*91f16700Schasinglulu 	arm_bl2_platform_setup();
192*91f16700Schasinglulu }
193