blob: ec87a8e3e60c0a3dd063305028a359801ae61ae3 [file] [log] [blame]
Manoj Kumar58876122021-01-10 16:12:24 +00001/*
Chandni Cherukuric873efc2023-02-16 20:22:32 +05302 * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
Manoj Kumar58876122021-01-10 16:12:24 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <common/debug.h>
Manoj Kumar91162752022-06-23 12:30:37 +01008#include <drivers/arm/css/sds.h>
9#include <lib/mmio.h>
Manoj Kumar58876122021-01-10 16:12:24 +000010#include <lib/utils.h>
11#include <plat/arm/common/plat_arm.h>
12
Manoj Kumar91162752022-06-23 12:30:37 +010013#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 */
23struct 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
Chandni Cherukuric873efc2023-02-16 20:22:32 +053036 * - silicon revision
Manoj Kumar91162752022-06-23 12:30:37 +010037 */
38struct 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;
Chandni Cherukuric873efc2023-02-16 20:22:32 +053044 uint32_t silicon_revision;
Manoj Kumar91162752022-06-23 12:30:37 +010045} __packed;
46#endif
47
48/* Compile time assertion to ensure the size of structure is 18 bytes */
49CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
50 assert_invalid_plat_info_size);
51
Manoj Kumar58876122021-01-10 16:12:24 +000052#ifdef TARGET_PLATFORM_SOC
Manoj Kumar91162752022-06-23 12:30:37 +010053/*
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
62static 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
Manoj Kumar58876122021-01-10 16:12:24 +000075 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);
Manoj Kumar91162752022-06-23 12:30:37 +010078
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
189void 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);
Manoj Kumar58876122021-01-10 16:12:24 +0000226#endif
227 arm_bl2_platform_setup();
228}