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 /* 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 22 * - 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 26 * - scc configuration 27 */ 28 struct morello_plat_info { 29 uint64_t local_ddr_size; 30 uint64_t remote_ddr_size; 31 uint8_t slave_count; 32 bool multichip_mode; 33 uint32_t scc_config; 34 } __packed; 35 36 /* Compile time assertion to ensure the size of structure is 18 bytes */ 37 CASSERT(sizeof(struct morello_plat_info) == MORELLO_SDS_PLATFORM_INFO_SIZE, 38 assert_invalid_plat_info_size); 39 40 static 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 48 scmi_channel_plat_info_t *plat_css_get_scmi_info(int channel_id) 49 { 50 return &morello_scmi_plat_info; 51 } 52 53 const 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 58 #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 65 * much faster compared to SCP. 66 */ 67 68 static void dmc_ecc_setup(struct morello_plat_info *plat_info) 69 { 70 uint64_t dram2_size; 71 uint32_t val; 72 uint64_t tag_mem_base; 73 uint64_t usable_mem_size; 74 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 81 INFO("Zeroing DDR memory range 0x%llx - 0x%llx\n", 82 ARM_DRAM2_BASE, ARM_DRAM2_BASE + dram2_size); 83 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 109 /* 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 166 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 191 void bl31_platform_setup(void) 192 { 193 int ret; 194 struct morello_plat_info plat_info; 195 struct morello_plat_info *copy_dest; 196 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) 215 || (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY) 216 || (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY) 217 || (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 224 #ifdef TARGET_PLATFORM_SOC 225 dmc_ecc_setup(&plat_info); 226 #endif 227 228 /* 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 */ 235 copy_dest = (struct morello_plat_info *)MORELLO_PLATFORM_INFO_BASE; 236 *copy_dest = plat_info; 237 } 238