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_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 */ 23 struct 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 * - silicon revision 37 */ 38 struct 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; 44 uint32_t silicon_revision; 45 } __packed; 46 #endif 47 48 /* Compile time assertion to ensure the size of structure is 18 bytes */ 49 CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE, 50 assert_invalid_plat_info_size); 51 52 #ifdef TARGET_PLATFORM_SOC 53 /* 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 62 static 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 75 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); 78 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 189 void 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); 226 #endif 227 arm_bl2_platform_setup(); 228 } 229