1 /* 2 * Copyright (c) 2020-2021, 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/css_mhu_doorbell.h> 9 #include <drivers/arm/css/scmi.h> 10 #include <drivers/arm/css/sds.h> 11 #include <lib/cassert.h> 12 #include <lib/utils.h> 13 #include <plat/arm/common/plat_arm.h> 14 15 #include "morello_def.h" 16 #include <platform_def.h> 17 18 #ifdef TARGET_PLATFORM_FVP 19 /* 20 * Platform information structure stored in SDS. 21 * This structure holds information about platform's DDR 22 * size 23 * - Local DDR size in bytes, DDR memory in main board 24 */ 25 struct morello_plat_info { 26 uint64_t local_ddr_size; 27 } __packed; 28 #else 29 /* 30 * Platform information structure stored in SDS. 31 * This structure holds information about platform's DDR 32 * size which is an information about multichip setup 33 * - Local DDR size in bytes, DDR memory in main board 34 * - Remote DDR size in bytes, DDR memory in remote board 35 * - remote_chip_count 36 * - multichip mode 37 * - scc configuration 38 */ 39 struct morello_plat_info { 40 uint64_t local_ddr_size; 41 uint64_t remote_ddr_size; 42 uint8_t remote_chip_count; 43 bool multichip_mode; 44 uint32_t scc_config; 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 static scmi_channel_plat_info_t morello_scmi_plat_info = { 53 .scmi_mbx_mem = MORELLO_SCMI_PAYLOAD_BASE, 54 .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, 55 .db_preserve_mask = 0xfffffffe, 56 .db_modify_mask = 0x1, 57 .ring_doorbell = &mhu_ring_doorbell 58 }; 59 60 scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) 61 { 62 return &morello_scmi_plat_info; 63 } 64 65 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) 66 { 67 return css_scmi_override_pm_ops(ops); 68 } 69 70 #ifdef TARGET_PLATFORM_SOC 71 /* 72 * Morello platform supports RDIMMs with ECC capability. To use the ECC 73 * capability, the entire DDR memory space has to be zeroed out before 74 * enabling the ECC bits in DMC-Bing. Zeroing out several gigabytes of 75 * memory from SCP is quite time consuming so the following function 76 * is added to zero out the DDR memory from application processor which is 77 * much faster compared to SCP. 78 */ 79 80 static void dmc_ecc_setup(struct morello_plat_info *plat_info) 81 { 82 uint64_t dram2_size; 83 uint32_t val; 84 uint64_t tag_mem_base; 85 uint64_t usable_mem_size; 86 87 INFO("Total DIMM size: %uGB\n", 88 (uint32_t)(plat_info->local_ddr_size / 0x40000000)); 89 90 assert(plat_info->local_ddr_size > ARM_DRAM1_SIZE); 91 dram2_size = plat_info->local_ddr_size - ARM_DRAM1_SIZE; 92 93 INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n", 94 ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size); 95 zero_normalmem((void *)ARM_DRAM2_BASE, dram2_size); 96 flush_dcache_range(ARM_DRAM2_BASE, dram2_size); 97 98 /* Clear previous ECC errors while zeroing out the memory */ 99 val = mmio_read_32(MORELLO_DMC0_ERR2STATUS_REG); 100 mmio_write_32(MORELLO_DMC0_ERR2STATUS_REG, val); 101 102 val = mmio_read_32(MORELLO_DMC1_ERR2STATUS_REG); 103 mmio_write_32(MORELLO_DMC1_ERR2STATUS_REG, val); 104 105 /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */ 106 mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG); 107 mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_CONFIG); 108 109 while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) & 110 MORELLO_DMC_MEMC_STATUS_MASK) != 111 MORELLO_DMC_MEMC_CMD_CONFIG) { 112 continue; 113 } 114 115 while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) & 116 MORELLO_DMC_MEMC_STATUS_MASK) != 117 MORELLO_DMC_MEMC_CMD_CONFIG) { 118 continue; 119 } 120 121 /* Configure Bing client/server mode based on SCC configuration */ 122 if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) { 123 INFO("Configuring DMC Bing in client mode\n"); 124 usable_mem_size = plat_info->local_ddr_size - 125 (plat_info->local_ddr_size / 128ULL); 126 127 /* Linear DDR address */ 128 tag_mem_base = usable_mem_size; 129 tag_mem_base = tag_mem_base / 4; 130 131 /* Reverse translation */ 132 if (tag_mem_base < ARM_DRAM1_BASE) { 133 tag_mem_base += ARM_DRAM1_BASE; 134 } else { 135 tag_mem_base = tag_mem_base - ARM_DRAM1_BASE + 136 ARM_DRAM2_BASE; 137 } 138 139 mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x1); 140 mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x1); 141 mmio_write_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x1); 142 mmio_write_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x1); 143 144 if (plat_info->scc_config & MORELLO_SCC_C1_TAG_CACHE_EN_MASK) { 145 mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x2); 146 mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x2); 147 INFO("C1 Tag Cache Enabled\n"); 148 } 149 150 if (plat_info->scc_config & MORELLO_SCC_C2_TAG_CACHE_EN_MASK) { 151 mmio_setbits_32(MORELLO_DMC0_TAG_CACHE_CFG, 0x4); 152 mmio_setbits_32(MORELLO_DMC1_TAG_CACHE_CFG, 0x4); 153 INFO("C2 Tag Cache Enabled\n"); 154 } 155 156 mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL, 157 (uint32_t)tag_mem_base); 158 mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL, 159 (uint32_t)tag_mem_base); 160 mmio_write_32(MORELLO_DMC0_MEM_ADDR_CTL2, 161 (uint32_t)(tag_mem_base >> 32)); 162 mmio_write_32(MORELLO_DMC1_MEM_ADDR_CTL2, 163 (uint32_t)(tag_mem_base >> 32)); 164 165 mmio_setbits_32(MORELLO_DMC0_MEM_ACCESS_CTL, 166 MORELLO_DMC_MEM_ACCESS_DIS); 167 mmio_setbits_32(MORELLO_DMC1_MEM_ACCESS_CTL, 168 MORELLO_DMC_MEM_ACCESS_DIS); 169 170 INFO("Tag base set to 0x%lx\n", tag_mem_base); 171 plat_info->local_ddr_size = usable_mem_size; 172 } else { 173 INFO("Configuring DMC Bing in server mode\n"); 174 mmio_write_32(MORELLO_DMC0_CAP_CTRL_REG, 0x0); 175 mmio_write_32(MORELLO_DMC1_CAP_CTRL_REG, 0x0); 176 } 177 178 INFO("Enabling ECC on DMCs\n"); 179 /* Enable ECC in DMCs */ 180 mmio_setbits_32(MORELLO_DMC0_ERR0CTLR0_REG, 181 MORELLO_DMC_ERR0CTLR0_ECC_EN); 182 mmio_setbits_32(MORELLO_DMC1_ERR0CTLR0_REG, 183 MORELLO_DMC_ERR0CTLR0_ECC_EN); 184 185 /* Set DMCs to READY state */ 186 mmio_write_32(MORELLO_DMC0_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY); 187 mmio_write_32(MORELLO_DMC1_MEMC_CMD_REG, MORELLO_DMC_MEMC_CMD_READY); 188 189 while ((mmio_read_32(MORELLO_DMC0_MEMC_STATUS_REG) & 190 MORELLO_DMC_MEMC_STATUS_MASK) != 191 MORELLO_DMC_MEMC_CMD_READY) { 192 continue; 193 } 194 195 while ((mmio_read_32(MORELLO_DMC1_MEMC_STATUS_REG) & 196 MORELLO_DMC_MEMC_STATUS_MASK) != 197 MORELLO_DMC_MEMC_CMD_READY) { 198 continue; 199 } 200 } 201 #endif 202 203 void bl31_platform_setup(void) 204 { 205 int ret; 206 struct morello_plat_info plat_info; 207 208 ret = sds_init(); 209 if (ret != SDS_OK) { 210 ERROR("SDS initialization failed. ret:%d\n", ret); 211 panic(); 212 } 213 214 ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID, 215 MORELLO_SDS_PLATFORM_INFO_OFFSET, 216 &plat_info, 217 MORELLO_SDS_PLATFORM_INFO_SIZE, 218 SDS_ACCESS_MODE_NON_CACHED); 219 if (ret != SDS_OK) { 220 ERROR("Error getting platform info from SDS. ret:%d\n", ret); 221 panic(); 222 } 223 224 /* Validate plat_info SDS */ 225 #ifdef TARGET_PLATFORM_FVP 226 if (plat_info.local_ddr_size == 0U) { 227 #else 228 if ((plat_info.local_ddr_size == 0U) 229 || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY) 230 || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY) 231 || (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT) 232 ) { 233 #endif 234 ERROR("platform info SDS is corrupted\n"); 235 panic(); 236 } 237 238 arm_bl31_platform_setup(); 239 240 #ifdef TARGET_PLATFORM_SOC 241 dmc_ecc_setup(&plat_info); 242 #endif 243 } 244