blob: 05a6f4b9b5f49baac1c89e597098d59882b20af8 [file] [log] [blame]
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +05301/*
Manoj Kumarb19e62a2021-08-26 10:49:02 +05302 * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +05303 *
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>
Manoj Kumar4ca42b82021-01-20 17:57:31 +053011#include <lib/cassert.h>
Manoj Kumarb19e62a2021-08-26 10:49:02 +053012#include <lib/utils.h>
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +053013#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
Manoj Kumar4ca42b82021-01-20 17:57:31 +053022 * - 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
Chandni Cherukuridff7f6c2021-11-30 20:35:35 +053026 * - scc configuration
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +053027 */
28struct morello_plat_info {
Manoj Kumar4ca42b82021-01-20 17:57:31 +053029 uint64_t local_ddr_size;
30 uint64_t remote_ddr_size;
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +053031 uint8_t slave_count;
Manoj Kumar4ca42b82021-01-20 17:57:31 +053032 bool multichip_mode;
Chandni Cherukuridff7f6c2021-11-30 20:35:35 +053033 uint32_t scc_config;
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +053034} __packed;
35
Manoj Kumar4ca42b82021-01-20 17:57:31 +053036/* Compile time assertion to ensure the size of structure is 18 bytes */
37CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
38 assert_invalid_plat_info_size);
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +053039/*
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 */
44struct morello_bl33_info {
45 uint32_t bl33_src_addr;
46 uint32_t bl33_dst_addr;
47 uint32_t bl33_size;
48};
49
50static 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
Chandni Cherukuric5a0c372020-10-01 10:11:44 +053058scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +053059{
60 return &morello_scmi_plat_info;
61}
62
63const 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
Manoj Kumarb19e62a2021-08-26 10:49:02 +053068#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
80static void dmc_ecc_setup(struct morello_plat_info *plat_info)
81{
82 uint64_t dram2_size;
83 uint32_t val;
Chandni Cherukuridff7f6c2021-11-30 20:35:35 +053084 uint64_t tag_mem_base;
85 uint64_t usable_mem_size;
Manoj Kumarb19e62a2021-08-26 10:49:02 +053086
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
Chandni Cherukuridff7f6c2021-11-30 20:35:35 +0530122 /* 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
Manoj Kumarb19e62a2021-08-26 10:49:02 +0530179 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
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530204static 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
221void bl31_platform_setup(void)
222{
223 int ret;
224 struct morello_plat_info plat_info;
225 struct morello_bl33_info bl33_info;
Manoj Kumar4ca42b82021-01-20 17:57:31 +0530226 struct morello_plat_info *copy_dest;
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530227
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)
Manoj Kumar4ca42b82021-01-20 17:57:31 +0530246 || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
247 || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530248 || (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
Manoj Kumarb19e62a2021-08-26 10:49:02 +0530255#ifdef TARGET_PLATFORM_SOC
256 dmc_ecc_setup(&plat_info);
257#endif
258
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530259 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 */
Manoj Kumar4ca42b82021-01-20 17:57:31 +0530278 copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE;
279 *copy_dest = plat_info;
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530280}