1 /* 2 * Copyright (c) 2021-2024, 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 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 153 void bl2_platform_setup(void) 154 { 155 int ret; 156 struct morello_plat_info plat_info; 157 158 ret = sds_init(SDS_SCP_AP_REGION_ID); 159 if (ret != SDS_OK) { 160 ERROR("SDS initialization failed. ret:%d\n", ret); 161 panic(); 162 } 163 164 ret = sds_struct_read(SDS_SCP_AP_REGION_ID, 165 MORELLO_SDS_PLATFORM_INFO_STRUCT_ID, 166 MORELLO_SDS_PLATFORM_INFO_OFFSET, 167 &plat_info, 168 MORELLO_SDS_PLATFORM_INFO_SIZE, 169 SDS_ACCESS_MODE_NON_CACHED); 170 if (ret != SDS_OK) { 171 ERROR("Error getting platform info from SDS. ret:%d\n", ret); 172 panic(); 173 } 174 175 /* Validate plat_info SDS */ 176 #ifdef TARGET_PLATFORM_FVP 177 if (plat_info.local_ddr_size == 0U) { 178 #else 179 if ((plat_info.local_ddr_size == 0U) 180 || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY) 181 || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY) 182 || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT) 183 ) { 184 #endif 185 ERROR("platform info SDS is corrupted\n"); 186 panic(); 187 } 188 189 #ifdef TARGET_PLATFORM_SOC 190 dmc_ecc_setup(&plat_info); 191 #endif 192 arm_bl2_platform_setup(); 193 } 194