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