xref: /rk3399_ARM-atf/plat/arm/board/morello/morello_bl31_setup.c (revision 4af53977533bee7b5763d3efad1448545c2ebef7)
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 static scmi_channel_plat_info_t morello_scmi_plat_info = {
41 	.scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE,
42 	.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
43 	.db_preserve_mask = 0xfffffffe,
44 	.db_modify_mask = 0x1,
45 	.ring_doorbell = &mhu_ring_doorbell
46 };
47 
48 scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
49 {
50 	return &morello_scmi_plat_info;
51 }
52 
53 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
54 {
55 	return css_scmi_override_pm_ops(ops);
56 }
57 
58 #ifdef TARGET_PLATFORM_SOC
59 /*
60  * Morello platform supports RDIMMs with ECC capability. To use the ECC
61  * capability, the entire DDR memory space has to be zeroed out before
62  * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
63  * memory from SCP is quite time consuming so the following function
64  * is added to zero out the DDR memory from application processor which is
65  * much faster compared to SCP.
66  */
67 
68 static void dmc_ecc_setup(struct morello_plat_info *plat_info)
69 {
70 	uint64_t dram2_size;
71 	uint32_t val;
72 	uint64_t tag_mem_base;
73 	uint64_t usable_mem_size;
74 
75 	INFO("Total DIMM size: %uGB\n",
76 			(uint32_t)(plat_info->local_ddr_size / 0x40000000));
77 
78 	assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
79 	dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
80 
81 	INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
82 		ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
83 	zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
84 	flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
85 
86 	/* Clear previous ECC errors while zeroing out the memory */
87 	val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
88 	mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
89 
90 	val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
91 	mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
92 
93 	/* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
94 	mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
95 	mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
96 
97 	while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
98 			MORELLO_DMC_MEMC_STATUS_MASK) !=
99 			MORELLO_DMC_MEMC_CMD_CONFIG) {
100 		continue;
101 	}
102 
103 	while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
104 			MORELLO_DMC_MEMC_STATUS_MASK) !=
105 			MORELLO_DMC_MEMC_CMD_CONFIG) {
106 		continue;
107 	}
108 
109 	/* Configure Bing client/server mode based on SCC configuration */
110 	if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
111 		INFO("Configuring DMC Bing in client mode\n");
112 		usable_mem_size = plat_info->local_ddr_size -
113 			(plat_info->local_ddr_size / 128ULL);
114 
115 		/* Linear DDR address */
116 		tag_mem_base = usable_mem_size;
117 		tag_mem_base = tag_mem_base / 4;
118 
119 		/* Reverse translation */
120 		if (tag_mem_base < ARM_DRAM1_BASE) {
121 			tag_mem_base += ARM_DRAM1_BASE;
122 		} else {
123 			tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
124 				ARM_DRAM2_BASE;
125 		}
126 
127 		mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
128 		mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
129 		mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
130 		mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
131 
132 		if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
133 			mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
134 			mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
135 			INFO("C1 Tag Cache Enabled\n");
136 		}
137 
138 		if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
139 			mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
140 			mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
141 			INFO("C2 Tag Cache Enabled\n");
142 		}
143 
144 		mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
145 				(uint32_t)tag_mem_base);
146 		mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
147 				(uint32_t)tag_mem_base);
148 		mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
149 				(uint32_t)(tag_mem_base >> 32));
150 		mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
151 				(uint32_t)(tag_mem_base >> 32));
152 
153 		mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
154 				MORELLO_DMC_MEM_ACCESS_DIS);
155 		mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
156 				MORELLO_DMC_MEM_ACCESS_DIS);
157 
158 		INFO("Tag base set to 0x%lx\n", tag_mem_base);
159 		plat_info->local_ddr_size = usable_mem_size;
160 	} else {
161 		INFO("Configuring DMC Bing in server mode\n");
162 		mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
163 		mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
164 	}
165 
166 	INFO("Enabling ECC on DMCs\n");
167 	/* Enable ECC in DMCs */
168 	mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
169 		MORELLO_DMC_ERR0CTLR0_ECC_EN);
170 	mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
171 		MORELLO_DMC_ERR0CTLR0_ECC_EN);
172 
173 	/* Set DMCs to READY state */
174 	mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
175 	mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
176 
177 	while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
178 			MORELLO_DMC_MEMC_STATUS_MASK) !=
179 			MORELLO_DMC_MEMC_CMD_READY) {
180 		continue;
181 	}
182 
183 	while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
184 			MORELLO_DMC_MEMC_STATUS_MASK) !=
185 			MORELLO_DMC_MEMC_CMD_READY) {
186 		continue;
187 	}
188 }
189 #endif
190 
191 void bl31_platform_setup(void)
192 {
193 	int ret;
194 	struct morello_plat_info plat_info;
195 	struct morello_plat_info *copy_dest;
196 
197 	ret = sds_init();
198 	if (ret != SDS_OK) {
199 		ERROR("SDS initialization failed. ret:%d\n", ret);
200 		panic();
201 	}
202 
203 	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
204 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
205 				&plat_info,
206 				MORELLO_SDS_PLATFORM_INFO_SIZE,
207 				SDS_ACCESS_MODE_NON_CACHED);
208 	if (ret != SDS_OK) {
209 		ERROR("Error getting platform info from SDS. ret:%d\n", ret);
210 		panic();
211 	}
212 
213 	/* Validate plat_info SDS */
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.slave_count > MORELLO_MAX_SLAVE_COUNT)) {
218 		ERROR("platform info SDS is corrupted\n");
219 		panic();
220 	}
221 
222 	arm_bl31_platform_setup();
223 
224 #ifdef TARGET_PLATFORM_SOC
225 	dmc_ecc_setup(&plat_info);
226 #endif
227 
228 	/*
229 	 * Pass platform information to BL33. This method is followed as
230 	 * currently there is no BL1/BL2 involved in boot flow of MORELLO.
231 	 * When TBBR is implemented for MORELLO, this method should be removed
232 	 * and platform information should be passed to BL33 using NT_FW_CONFIG
233 	 * passing mechanism.
234 	 */
235 	copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE;
236 	*copy_dest = plat_info;
237 }
238