xref: /rk3399_ARM-atf/plat/arm/board/morello/morello_bl31_setup.c (revision 9b8c431e2b2d656da7f8c4158e3d32e104446fec)
1 /*
2  * Copyright (c) 2020-2021, 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/css_mhu_doorbell.h>
9 #include <drivers/arm/css/scmi.h>
10 #include <drivers/arm/css/sds.h>
11 #include <lib/cassert.h>
12 #include <lib/utils.h>
13 #include <plat/arm/common/plat_arm.h>
14 
15 #include "morello_def.h"
16 #include <platform_def.h>
17 
18 /*
19  * Platform information structure stored in SDS.
20  * This structure holds information about platform's DDR
21  * size which is an information about multichip setup
22  *	- Local DDR size in bytes, DDR memory in master board
23  *	- Remote DDR size in bytes, DDR memory in slave board
24  *	- slave_count
25  *	- multichip mode
26  *	- scc configuration
27  */
28 struct morello_plat_info {
29 	uint64_t local_ddr_size;
30 	uint64_t remote_ddr_size;
31 	uint8_t slave_count;
32 	bool multichip_mode;
33 	uint32_t scc_config;
34 } __packed;
35 
36 /* Compile time assertion to ensure the size of structure is 18 bytes */
37 CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
38 		assert_invalid_plat_info_size);
39 /*
40  * BL33 image information structure stored in SDS.
41  * This structure holds the source & destination addresses and
42  * the size of the BL33 image which will be loaded by BL31.
43  */
44 struct morello_bl33_info {
45 	uint32_t bl33_src_addr;
46 	uint32_t bl33_dst_addr;
47 	uint32_t bl33_size;
48 };
49 
50 static scmi_channel_plat_info_t morello_scmi_plat_info = {
51 	.scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE,
52 	.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
53 	.db_preserve_mask = 0xfffffffe,
54 	.db_modify_mask = 0x1,
55 	.ring_doorbell = &mhu_ring_doorbell
56 };
57 
58 scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
59 {
60 	return &morello_scmi_plat_info;
61 }
62 
63 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
64 {
65 	return css_scmi_override_pm_ops(ops);
66 }
67 
68 #ifdef TARGET_PLATFORM_SOC
69 /*
70  * Morello platform supports RDIMMs with ECC capability. To use the ECC
71  * capability, the entire DDR memory space has to be zeroed out before
72  * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
73  * memory from SCP is quite time consuming so the following function
74  * is added to zero out the DDR memory from application processor which is
75  * much faster compared to SCP. BL33 binary cannot be copied to DDR memory
76  * before enabling ECC so copy_bl33 function is added to copy BL33 binary
77  * from IOFPGA-DDR3 memory to main DDR4 memory.
78  */
79 
80 static void dmc_ecc_setup(struct morello_plat_info *plat_info)
81 {
82 	uint64_t dram2_size;
83 	uint32_t val;
84 	uint64_t tag_mem_base;
85 	uint64_t usable_mem_size;
86 
87 	INFO("Total DIMM size: %uGB\n",
88 			(uint32_t)(plat_info->local_ddr_size / 0x40000000));
89 
90 	assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
91 	dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
92 
93 	VERBOSE("Zeroing DDR memories\n");
94 	zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
95 	flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
96 	zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
97 	flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
98 
99 	/* Clear previous ECC errors while zeroing out the memory */
100 	val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
101 	mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
102 
103 	val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
104 	mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
105 
106 	/* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
107 	mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
108 	mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
109 
110 	while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
111 			MORELLO_DMC_MEMC_STATUS_MASK) !=
112 			MORELLO_DMC_MEMC_CMD_CONFIG) {
113 		continue;
114 	}
115 
116 	while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
117 			MORELLO_DMC_MEMC_STATUS_MASK) !=
118 			MORELLO_DMC_MEMC_CMD_CONFIG) {
119 		continue;
120 	}
121 
122 	/* Configure Bing client/server mode based on SCC configuration */
123 	if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
124 		INFO("Configuring DMC Bing in client mode\n");
125 		usable_mem_size = plat_info->local_ddr_size -
126 			(plat_info->local_ddr_size / 128ULL);
127 
128 		/* Linear DDR address */
129 		tag_mem_base = usable_mem_size;
130 		tag_mem_base = tag_mem_base / 4;
131 
132 		/* Reverse translation */
133 		if (tag_mem_base < ARM_DRAM1_BASE) {
134 			tag_mem_base += ARM_DRAM1_BASE;
135 		} else {
136 			tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
137 				ARM_DRAM2_BASE;
138 		}
139 
140 		mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
141 		mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
142 		mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
143 		mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
144 
145 		if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
146 			mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
147 			mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
148 			INFO("C1 Tag Cache Enabled\n");
149 		}
150 
151 		if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
152 			mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
153 			mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
154 			INFO("C2 Tag Cache Enabled\n");
155 		}
156 
157 		mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
158 				(uint32_t)tag_mem_base);
159 		mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
160 				(uint32_t)tag_mem_base);
161 		mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
162 				(uint32_t)(tag_mem_base >> 32));
163 		mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
164 				(uint32_t)(tag_mem_base >> 32));
165 
166 		mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
167 				MORELLO_DMC_MEM_ACCESS_DIS);
168 		mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
169 				MORELLO_DMC_MEM_ACCESS_DIS);
170 
171 		INFO("Tag base set to 0x%lx\n", tag_mem_base);
172 		plat_info->local_ddr_size = usable_mem_size;
173 	} else {
174 		INFO("Configuring DMC Bing in server mode\n");
175 		mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
176 		mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
177 	}
178 
179 	INFO("Enabling ECC on DMCs\n");
180 	/* Enable ECC in DMCs */
181 	mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
182 		MORELLO_DMC_ERR0CTLR0_ECC_EN);
183 	mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
184 		MORELLO_DMC_ERR0CTLR0_ECC_EN);
185 
186 	/* Set DMCs to READY state */
187 	mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
188 	mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
189 
190 	while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
191 			MORELLO_DMC_MEMC_STATUS_MASK) !=
192 			MORELLO_DMC_MEMC_CMD_READY) {
193 		continue;
194 	}
195 
196 	while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
197 			MORELLO_DMC_MEMC_STATUS_MASK) !=
198 			MORELLO_DMC_MEMC_CMD_READY) {
199 		continue;
200 	}
201 }
202 #endif
203 
204 static void copy_bl33(uint32_t src, uint32_t dst, uint32_t size)
205 {
206 	unsigned int i;
207 
208 	INFO("Copying BL33 to DDR memory...\n");
209 	for (i = 0U; i < size; (i = i + 8U))
210 		mmio_write_64((dst + i), mmio_read_64(src + i));
211 
212 	for (i = 0U; i < size; (i = i + 8U)) {
213 		if (mmio_read_64(src + i) != mmio_read_64(dst + i)) {
214 			ERROR("Copy failed!\n");
215 			panic();
216 		}
217 	}
218 	INFO("done\n");
219 }
220 
221 void bl31_platform_setup(void)
222 {
223 	int ret;
224 	struct morello_plat_info plat_info;
225 	struct morello_bl33_info bl33_info;
226 	struct morello_plat_info *copy_dest;
227 
228 	ret = sds_init();
229 	if (ret != SDS_OK) {
230 		ERROR("SDS initialization failed. ret:%d\n", ret);
231 		panic();
232 	}
233 
234 	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
235 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
236 				&plat_info,
237 				MORELLO_SDS_PLATFORM_INFO_SIZE,
238 				SDS_ACCESS_MODE_NON_CACHED);
239 	if (ret != SDS_OK) {
240 		ERROR("Error getting platform info from SDS. ret:%d\n", ret);
241 		panic();
242 	}
243 
244 	/* Validate plat_info SDS */
245 	if ((plat_info.local_ddr_size == 0U)
246 		|| (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
247 		|| (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
248 		|| (plat_info.slave_count > MORELLO_MAX_SLAVE_COUNT)) {
249 		ERROR("platform info SDS is corrupted\n");
250 		panic();
251 	}
252 
253 	arm_bl31_platform_setup();
254 
255 #ifdef TARGET_PLATFORM_SOC
256 	dmc_ecc_setup(&plat_info);
257 #endif
258 
259 	ret = sds_struct_read(MORELLO_SDS_BL33_INFO_STRUCT_ID,
260 				MORELLO_SDS_BL33_INFO_OFFSET,
261 				&bl33_info,
262 				MORELLO_SDS_BL33_INFO_SIZE,
263 				SDS_ACCESS_MODE_NON_CACHED);
264 	if (ret != SDS_OK) {
265 		ERROR("Error getting BL33 info from SDS. ret:%d\n", ret);
266 		panic();
267 	}
268 	copy_bl33(bl33_info.bl33_src_addr,
269 			bl33_info.bl33_dst_addr,
270 			bl33_info.bl33_size);
271 	/*
272 	 * Pass platform information to BL33. This method is followed as
273 	 * currently there is no BL1/BL2 involved in boot flow of MORELLO.
274 	 * When TBBR is implemented for MORELLO, this method should be removed
275 	 * and platform information should be passed to BL33 using NT_FW_CONFIG
276 	 * passing mechanism.
277 	 */
278 	copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE;
279 	*copy_dest = plat_info;
280 }
281