1 /*
2  * Copyright (c) 2021-2023, 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/sds.h>
9 #include <lib/mmio.h>
10 #include <lib/utils.h>
11 #include <plat/arm/common/plat_arm.h>
12 
13 #include "morello_def.h"
14 #include <platform_def.h>
15 
16 #ifdef TARGET_PLATFORM_SOC
17 /*
18  * Morello platform supports RDIMMs with ECC capability. To use the ECC
19  * capability, the entire DDR memory space has to be zeroed out before
20  * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of
21  * memory from SCP is quite time consuming so the following function
22  * is added to zero out the DDR memory from application processor which is
23  * much faster compared to SCP.
24  */
25 
dmc_ecc_setup(struct morello_plat_info * plat_info)26 static void dmc_ecc_setup(struct morello_plat_info *plat_info)
27 {
28 	uint64_t dram2_size;
29 	uint32_t val;
30 	uint64_t tag_mem_base;
31 	uint64_t usable_mem_size;
32 
33 	INFO("Total DIMM size: %uGB\n",
34 			(uint32_t)(plat_info->local_ddr_size / 0x40000000));
35 
36 	assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE);
37 	dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE;
38 
39 	INFO("Zeroing DDR memory range 0x80000000 - 0xFFFFFFFF\n");
40 	zero_normalmem((void *)ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
41 	flush_dcache_range(ARM_DRAM1_BASE, ARM_DRAM1_SIZE);
42 
43 	INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n",
44 		ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size);
45 	zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size);
46 	flush_dcache_range(ARM_DRAM2_BASE, dram2_size);
47 
48 	/* Clear previous ECC errors while zeroing out the memory */
49 	val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG);
50 	mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val);
51 
52 	val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG);
53 	mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val);
54 
55 	/* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
56 	mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
57 	mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG);
58 
59 	while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
60 			MORELLO_DMC_MEMC_STATUS_MASK) !=
61 			MORELLO_DMC_MEMC_CMD_CONFIG) {
62 		continue;
63 	}
64 
65 	while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
66 			MORELLO_DMC_MEMC_STATUS_MASK) !=
67 			MORELLO_DMC_MEMC_CMD_CONFIG) {
68 		continue;
69 	}
70 
71 	/* Configure Bing client/server mode based on SCC configuration */
72 	if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
73 		INFO("Configuring DMC Bing in client mode\n");
74 		usable_mem_size = plat_info->local_ddr_size -
75 			(plat_info->local_ddr_size / 128ULL);
76 
77 		/* Linear DDR address */
78 		tag_mem_base = usable_mem_size;
79 		tag_mem_base = tag_mem_base / 4;
80 
81 		/* Reverse translation */
82 		if (tag_mem_base < ARM_DRAM1_BASE) {
83 			tag_mem_base += ARM_DRAM1_BASE;
84 		} else {
85 			tag_mem_base = tag_mem_base - ARM_DRAM1_BASE +
86 				ARM_DRAM2_BASE;
87 		}
88 
89 		mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1);
90 		mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1);
91 		mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1);
92 		mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1);
93 
94 		if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) {
95 			mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2);
96 			mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2);
97 			INFO("C1 Tag Cache Enabled\n");
98 		}
99 
100 		if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) {
101 			mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4);
102 			mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4);
103 			INFO("C2 Tag Cache Enabled\n");
104 		}
105 
106 		mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL,
107 				(uint32_t)tag_mem_base);
108 		mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL,
109 				(uint32_t)tag_mem_base);
110 		mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2,
111 				(uint32_t)(tag_mem_base >> 32));
112 		mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2,
113 				(uint32_t)(tag_mem_base >> 32));
114 
115 		mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL,
116 				MORELLO_DMC_MEM_ACCESS_DIS);
117 		mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL,
118 				MORELLO_DMC_MEM_ACCESS_DIS);
119 
120 		INFO("Tag base set to 0x%lx\n", tag_mem_base);
121 		plat_info->local_ddr_size = usable_mem_size;
122 	} else {
123 		INFO("Configuring DMC Bing in server mode\n");
124 		mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0);
125 		mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0);
126 	}
127 
128 	INFO("Enabling ECC on DMCs\n");
129 	/* Enable ECC in DMCs */
130 	mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG,
131 		MORELLO_DMC_ERR0CTLR0_ECC_EN);
132 	mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG,
133 		MORELLO_DMC_ERR0CTLR0_ECC_EN);
134 
135 	/* Set DMCs to READY state */
136 	mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
137 	mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY);
138 
139 	while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) &
140 			MORELLO_DMC_MEMC_STATUS_MASK) !=
141 			MORELLO_DMC_MEMC_CMD_READY) {
142 		continue;
143 	}
144 
145 	while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) &
146 			MORELLO_DMC_MEMC_STATUS_MASK) !=
147 			MORELLO_DMC_MEMC_CMD_READY) {
148 		continue;
149 	}
150 }
151 #endif
152 
bl2_platform_setup(void)153 void bl2_platform_setup(void)
154 {
155 	int ret;
156 	struct morello_plat_info plat_info;
157 
158 	ret = sds_init();
159 	if (ret != SDS_OK) {
160 		ERROR("SDS initialization failed. ret:%d\n", ret);
161 		panic();
162 	}
163 
164 	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
165 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
166 				&plat_info,
167 				MORELLO_SDS_PLATFORM_INFO_SIZE,
168 				SDS_ACCESS_MODE_NON_CACHED);
169 	if (ret != SDS_OK) {
170 		ERROR("Error getting platform info from SDS. ret:%d\n", ret);
171 		panic();
172 	}
173 
174 	/* Validate plat_info SDS */
175 #ifdef TARGET_PLATFORM_FVP
176 	if (plat_info.local_ddr_size == 0U) {
177 #else
178 	if ((plat_info.local_ddr_size == 0U)
179 		|| (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
180 		|| (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
181 		|| (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
182 		) {
183 #endif
184 		ERROR("platform info SDS is corrupted\n");
185 		panic();
186 	}
187 
188 #ifdef TARGET_PLATFORM_SOC
189 	dmc_ecc_setup(&plat_info);
190 #endif
191 	arm_bl2_platform_setup();
192 }
193