blob: da1f7ae10068197dd7aa1c3c551ae164df4e5a6a [file] [log] [blame]
Manoj Kumar58876122021-01-10 16:12:24 +00001/*
Manoj Kumar91162752022-06-23 12:30:37 +01002 * Copyright (c) 2021-2022, 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
36 */
37struct morello_plat_info {
38 uint64_t local_ddr_size;
39 uint64_t remote_ddr_size;
40 uint8_t remote_chip_count;
41 bool multichip_mode;
42 uint32_t scc_config;
43} __packed;
44#endif
45
46/* Compile time assertion to ensure the size of structure is 18 bytes */
47CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE,
48 assert_invalid_plat_info_size);
49
Manoj Kumar58876122021-01-10 16:12:24 +000050#ifdef TARGET_PLATFORM_SOC
Manoj Kumar91162752022-06-23 12:30:37 +010051/*
52 * Morello platform supports RDIMMs with ECC capability. To use the ECC
53 * capability, the entire DDR memory space has to be zeroed out before
54 * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
55 * memory from SCP is quite time consuming so the following function
56 * is added to zero out the DDR memory from application processor which is
57 * much faster compared to SCP.
58 */
59
60static void dmc_ecc_setup(struct morello_plat_info *plat_info)
61{
62 uint64_t dram2_size;
63 uint32_t val;
64 uint64_t tag_mem_base;
65 uint64_t usable_mem_size;
66
67 INFO("Total DIMM size: %uGB\n",
68 (uint32_t)(plat_info->local_ddr_size / 0x40000000));
69
70 assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
71 dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
72
Manoj Kumar58876122021-01-10 16:12:24 +000073 INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n");
74 zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
75 flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
Manoj Kumar91162752022-06-23 12:30:37 +010076
77 INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
78 ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
79 zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
80 flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
81
82 /* Clear previous ECC errors while zeroing out the memory */
83 val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
84 mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
85
86 val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
87 mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
88
89 /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
90 mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
91 mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
92
93 while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
94 MORELLO_DMC_MEMC_STATUS_MASK) !=
95 MORELLO_DMC_MEMC_CMD_CONFIG) {
96 continue;
97 }
98
99 while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
100 MORELLO_DMC_MEMC_STATUS_MASK) !=
101 MORELLO_DMC_MEMC_CMD_CONFIG) {
102 continue;
103 }
104
105 /* Configure Bing client/server mode based on SCC configuration */
106 if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
107 INFO("Configuring DMC Bing in client mode\n");
108 usable_mem_size = plat_info->local_ddr_size -
109 (plat_info->local_ddr_size / 128ULL);
110
111 /* Linear DDR address */
112 tag_mem_base = usable_mem_size;
113 tag_mem_base = tag_mem_base / 4;
114
115 /* Reverse translation */
116 if (tag_mem_base < ARM_DRAM1_BASE) {
117 tag_mem_base += ARM_DRAM1_BASE;
118 } else {
119 tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
120 ARM_DRAM2_BASE;
121 }
122
123 mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
124 mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
125 mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
126 mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
127
128 if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
129 mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
130 mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
131 INFO("C1 Tag Cache Enabled\n");
132 }
133
134 if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
135 mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
136 mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
137 INFO("C2 Tag Cache Enabled\n");
138 }
139
140 mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
141 (uint32_t)tag_mem_base);
142 mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
143 (uint32_t)tag_mem_base);
144 mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
145 (uint32_t)(tag_mem_base >> 32));
146 mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
147 (uint32_t)(tag_mem_base >> 32));
148
149 mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
150 MORELLO_DMC_MEM_ACCESS_DIS);
151 mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
152 MORELLO_DMC_MEM_ACCESS_DIS);
153
154 INFO("Tag base set to 0x%lx\n", tag_mem_base);
155 plat_info->local_ddr_size = usable_mem_size;
156 } else {
157 INFO("Configuring DMC Bing in server mode\n");
158 mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
159 mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
160 }
161
162 INFO("Enabling ECC on DMCs\n");
163 /* Enable ECC in DMCs */
164 mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
165 MORELLO_DMC_ERR0CTLR0_ECC_EN);
166 mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
167 MORELLO_DMC_ERR0CTLR0_ECC_EN);
168
169 /* Set DMCs to READY state */
170 mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
171 mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
172
173 while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
174 MORELLO_DMC_MEMC_STATUS_MASK) !=
175 MORELLO_DMC_MEMC_CMD_READY) {
176 continue;
177 }
178
179 while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
180 MORELLO_DMC_MEMC_STATUS_MASK) !=
181 MORELLO_DMC_MEMC_CMD_READY) {
182 continue;
183 }
184}
185#endif
186
187void bl2_platform_setup(void)
188{
189 int ret;
190 struct morello_plat_info plat_info;
191
192 ret = sds_init();
193 if (ret != SDS_OK) {
194 ERROR("SDS initialization failed. ret:%d\n", ret);
195 panic();
196 }
197
198 ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
199 MORELLO_SDS_PLATFORM_INFO_OFFSET,
200 &plat_info,
201 MORELLO_SDS_PLATFORM_INFO_SIZE,
202 SDS_ACCESS_MODE_NON_CACHED);
203 if (ret != SDS_OK) {
204 ERROR("Error getting platform info from SDS. ret:%d\n", ret);
205 panic();
206 }
207
208 /* Validate plat_info SDS */
209#ifdef TARGET_PLATFORM_FVP
210 if (plat_info.local_ddr_size == 0U) {
211#else
212 if ((plat_info.local_ddr_size == 0U)
213 || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
214 || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
215 || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
216 ) {
217#endif
218 ERROR("platform info SDS is corrupted\n");
219 panic();
220 }
221
222#ifdef TARGET_PLATFORM_SOC
223 dmc_ecc_setup(&plat_info);
Manoj Kumar58876122021-01-10 16:12:24 +0000224#endif
225 arm_bl2_platform_setup();
226}