blob: 5a1abe72963d8324c236ca1e219bbcc0c67e602a [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
40static 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
Chandni Cherukuric5a0c372020-10-01 10:11:44 +053048scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id)
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +053049{
50 return &morello_scmi_plat_info;
51}
52
53const 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
Manoj Kumarb19e62a2021-08-26 10:49:02 +053058#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
Manoj Kumar58876122021-01-10 16:12:24 +000065 * much faster compared to SCP.
Manoj Kumarb19e62a2021-08-26 10:49:02 +053066 */
67
68static void dmc_ecc_setup(struct morello_plat_info *plat_info)
69{
70 uint64_t dram2_size;
71 uint32_t val;
Chandni Cherukuridff7f6c2021-11-30 20:35:35 +053072 uint64_t tag_mem_base;
73 uint64_t usable_mem_size;
Manoj Kumarb19e62a2021-08-26 10:49:02 +053074
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
Manoj Kumar58876122021-01-10 16:12:24 +000081 INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
82 ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
Manoj Kumarb19e62a2021-08-26 10:49:02 +053083 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
Chandni Cherukuridff7f6c2021-11-30 20:35:35 +0530109 /* 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
Manoj Kumarb19e62a2021-08-26 10:49:02 +0530166 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
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530191void bl31_platform_setup(void)
192{
193 int ret;
194 struct morello_plat_info plat_info;
Manoj Kumar4ca42b82021-01-20 17:57:31 +0530195 struct morello_plat_info *copy_dest;
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530196
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)
Manoj Kumar4ca42b82021-01-20 17:57:31 +0530215 || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
216 || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530217 || (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
Manoj Kumarb19e62a2021-08-26 10:49:02 +0530224#ifdef TARGET_PLATFORM_SOC
225 dmc_ecc_setup(&plat_info);
226#endif
227
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530228 /*
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 */
Manoj Kumar4ca42b82021-01-20 17:57:31 +0530235 copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE;
236 *copy_dest = plat_info;
Chandni Cherukurif3a6cab2020-09-22 18:56:25 +0530237}