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