1 /* 2 * Copyright (C) 2018 Marvell International Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * https://spdx.org/licenses 6 */ 7 8 #include <assert.h> 9 10 #include <platform_def.h> 11 12 #include <arch_helpers.h> 13 #include <common/debug.h> 14 #include <drivers/delay_timer.h> 15 #include <lib/mmio.h> 16 17 #include <plat_pm_trace.h> 18 #include <mss_scp_bootloader.h> 19 #include <mss_ipc_drv.h> 20 #include <mss_mem.h> 21 #include <mss_scp_bl2_format.h> 22 23 #define MSS_DMA_SRCBR(base) (base + 0xC0) 24 #define MSS_DMA_DSTBR(base) (base + 0xC4) 25 #define MSS_DMA_CTRLR(base) (base + 0xC8) 26 #define MSS_M3_RSTCR(base) (base + 0xFC) 27 28 #define MSS_DMA_CTRLR_SIZE_OFFSET (0) 29 #define MSS_DMA_CTRLR_REQ_OFFSET (15) 30 #define MSS_DMA_CTRLR_REQ_SET (1) 31 #define MSS_DMA_CTRLR_ACK_OFFSET (12) 32 #define MSS_DMA_CTRLR_ACK_MASK (0x1) 33 #define MSS_DMA_CTRLR_ACK_READY (1) 34 #define MSS_M3_RSTCR_RST_OFFSET (0) 35 #define MSS_M3_RSTCR_RST_OFF (1) 36 37 #define MSS_DMA_TIMEOUT 1000 38 #define MSS_EXTERNAL_SPACE 0x50000000 39 #define MSS_EXTERNAL_ADDR_MASK 0xfffffff 40 41 #define DMA_SIZE 128 42 43 #define MSS_HANDSHAKE_TIMEOUT 50 44 45 #define MG_CM3_SRAM_BASE(CP) (MVEBU_CP_REGS_BASE(CP) + 0x100000) 46 47 static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl) 48 { 49 int timeout = MSS_HANDSHAKE_TIMEOUT; 50 51 /* Wait for SCP to signal it's ready */ 52 while ((mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) && 53 (timeout-- > 0)) 54 mdelay(1); 55 56 if (mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) 57 return -1; 58 59 mss_pm_crtl->handshake = HOST_ACKNOWLEDGMENT; 60 61 return 0; 62 } 63 64 static int mg_image_load(uintptr_t src_addr, uint32_t size, uintptr_t mg_regs) 65 { 66 if (size > MG_SRAM_SIZE) { 67 ERROR("image is too big to fit into MG CM3 memory\n"); 68 return 1; 69 } 70 71 NOTICE("Loading MG image from address 0x%lx Size 0x%x to MG at 0x%lx\n", 72 src_addr, size, mg_regs); 73 74 /* Copy image to MG CM3 SRAM */ 75 memcpy((void *)mg_regs, (void *)src_addr, size); 76 77 /* 78 * Don't release MG CM3 from reset - it will be done by next step 79 * bootloader (e.g. U-Boot), when appriopriate device-tree setup (which 80 * has enabeld 802.3. auto-neg) will be choosen. 81 */ 82 83 return 0; 84 } 85 86 static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs) 87 { 88 uint32_t i, loop_num, timeout; 89 90 /* Check if the img size is not bigger than ID-RAM size of MSS CM3 */ 91 if (size > MSS_IDRAM_SIZE) { 92 ERROR("image is too big to fit into MSS CM3 memory\n"); 93 return 1; 94 } 95 96 NOTICE("Loading MSS image from addr. 0x%x Size 0x%x to MSS at 0x%lx\n", 97 src_addr, size, mss_regs); 98 /* load image to MSS RAM using DMA */ 99 loop_num = (size / DMA_SIZE) + (((size & (DMA_SIZE - 1)) == 0) ? 0 : 1); 100 101 for (i = 0; i < loop_num; i++) { 102 /* write destination and source addresses */ 103 mmio_write_32(MSS_DMA_SRCBR(mss_regs), 104 MSS_EXTERNAL_SPACE | 105 ((src_addr & MSS_EXTERNAL_ADDR_MASK) + 106 (i * DMA_SIZE))); 107 mmio_write_32(MSS_DMA_DSTBR(mss_regs), (i * DMA_SIZE)); 108 109 dsb(); /* make sure DMA data is ready before triggering it */ 110 111 /* set the DMA control register */ 112 mmio_write_32(MSS_DMA_CTRLR(mss_regs), ((MSS_DMA_CTRLR_REQ_SET 113 << MSS_DMA_CTRLR_REQ_OFFSET) | 114 (DMA_SIZE << MSS_DMA_CTRLR_SIZE_OFFSET))); 115 116 /* Poll DMA_ACK at MSS_DMACTLR until it is ready */ 117 timeout = MSS_DMA_TIMEOUT; 118 while (timeout) { 119 if ((mmio_read_32(MSS_DMA_CTRLR(mss_regs)) >> 120 MSS_DMA_CTRLR_ACK_OFFSET & MSS_DMA_CTRLR_ACK_MASK) 121 == MSS_DMA_CTRLR_ACK_READY) { 122 break; 123 } 124 125 udelay(50); 126 timeout--; 127 } 128 129 if (timeout == 0) { 130 ERROR("\nDMA failed to load MSS image\n"); 131 return 1; 132 } 133 } 134 135 bl2_plat_configure_mss_windows(mss_regs); 136 137 /* Release M3 from reset */ 138 mmio_write_32(MSS_M3_RSTCR(mss_regs), (MSS_M3_RSTCR_RST_OFF << 139 MSS_M3_RSTCR_RST_OFFSET)); 140 141 NOTICE("Done\n"); 142 143 return 0; 144 } 145 146 /* Load image to MSS AP and do PM related initialization 147 * Note that this routine is different than other CM3 loading routines, because 148 * firmware for AP is dedicated for PM and therefore some additional PM 149 * initialization is required 150 */ 151 static int mss_ap_load_image(uintptr_t single_img, 152 uint32_t image_size, uint32_t ap_idx) 153 { 154 volatile struct mss_pm_ctrl_block *mss_pm_crtl; 155 int ret; 156 157 /* TODO: add PM Control Info from platform */ 158 mss_pm_crtl = (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE; 159 mss_pm_crtl->ipc_version = MV_PM_FW_IPC_VERSION; 160 mss_pm_crtl->num_of_clusters = PLAT_MARVELL_CLUSTER_COUNT; 161 mss_pm_crtl->num_of_cores_per_cluster = 162 PLAT_MARVELL_CLUSTER_CORE_COUNT; 163 mss_pm_crtl->num_of_cores = PLAT_MARVELL_CLUSTER_COUNT * 164 PLAT_MARVELL_CLUSTER_CORE_COUNT; 165 mss_pm_crtl->pm_trace_ctrl_base_address = AP_MSS_ATF_CORE_CTRL_BASE; 166 mss_pm_crtl->pm_trace_info_base_address = AP_MSS_ATF_CORE_INFO_BASE; 167 mss_pm_crtl->pm_trace_info_core_size = AP_MSS_ATF_CORE_INFO_SIZE; 168 VERBOSE("MSS Control Block = 0x%x\n", MSS_SRAM_PM_CONTROL_BASE); 169 VERBOSE("mss_pm_crtl->ipc_version = 0x%x\n", 170 mss_pm_crtl->ipc_version); 171 VERBOSE("mss_pm_crtl->num_of_cores = 0x%x\n", 172 mss_pm_crtl->num_of_cores); 173 VERBOSE("mss_pm_crtl->num_of_clusters = 0x%x\n", 174 mss_pm_crtl->num_of_clusters); 175 VERBOSE("mss_pm_crtl->num_of_cores_per_cluster = 0x%x\n", 176 mss_pm_crtl->num_of_cores_per_cluster); 177 VERBOSE("mss_pm_crtl->pm_trace_ctrl_base_address = 0x%x\n", 178 mss_pm_crtl->pm_trace_ctrl_base_address); 179 VERBOSE("mss_pm_crtl->pm_trace_info_base_address = 0x%x\n", 180 mss_pm_crtl->pm_trace_info_base_address); 181 VERBOSE("mss_pm_crtl->pm_trace_info_core_size = 0x%x\n", 182 mss_pm_crtl->pm_trace_info_core_size); 183 184 /* TODO: add checksum to image */ 185 VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n"); 186 187 ret = mss_image_load(single_img, image_size, 188 bl2_plat_get_ap_mss_regs(ap_idx)); 189 if (ret != 0) { 190 ERROR("SCP Image load failed\n"); 191 return -1; 192 } 193 194 /* check that the image was loaded successfully */ 195 ret = mss_check_image_ready(mss_pm_crtl); 196 if (ret != 0) 197 NOTICE("SCP Image doesn't contain PM firmware\n"); 198 199 return 0; 200 } 201 202 /* Load CM3 image (single_img) to CM3 pointed by cm3_type */ 203 static int load_img_to_cm3(enum cm3_t cm3_type, 204 uintptr_t single_img, uint32_t image_size) 205 { 206 int ret, ap_idx, cp_index; 207 uint32_t ap_count = bl2_plat_get_ap_count(); 208 209 switch (cm3_type) { 210 case MSS_AP: 211 for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { 212 NOTICE("Load image to AP%d MSS\n", ap_idx); 213 ret = mss_ap_load_image(single_img, image_size, ap_idx); 214 if (ret != 0) 215 return ret; 216 } 217 break; 218 case MSS_CP0: 219 case MSS_CP1: 220 case MSS_CP2: 221 case MSS_CP3: 222 /* MSS_AP = 0 223 * MSS_CP1 = 1 224 * . 225 * . 226 * MSS_CP3 = 4 227 * Actual CP index is MSS_CPX - 1 228 */ 229 cp_index = cm3_type - 1; 230 for (ap_idx = 0; ap_idx < ap_count; ap_idx++) { 231 /* Check if we should load this image 232 * according to number of CPs 233 */ 234 if (bl2_plat_get_cp_count(ap_idx) <= cp_index) { 235 NOTICE("Skipping MSS CP%d related image\n", 236 cp_index); 237 break; 238 } 239 240 NOTICE("Load image to CP%d MSS AP%d\n", 241 cp_index, ap_idx); 242 ret = mss_image_load(single_img, image_size, 243 bl2_plat_get_cp_mss_regs( 244 ap_idx, cp_index)); 245 if (ret != 0) { 246 ERROR("SCP Image load failed\n"); 247 return -1; 248 } 249 } 250 break; 251 case MG_CP0: 252 case MG_CP1: 253 case MG_CP2: 254 cp_index = cm3_type - MG_CP0; 255 if (bl2_plat_get_cp_count(0) <= cp_index) { 256 NOTICE("Skipping MG CP%d related image\n", 257 cp_index); 258 break; 259 } 260 NOTICE("Load image to CP%d MG\n", cp_index); 261 ret = mg_image_load(single_img, image_size, 262 MG_CM3_SRAM_BASE(cp_index)); 263 if (ret != 0) { 264 ERROR("SCP Image load failed\n"); 265 return -1; 266 } 267 break; 268 default: 269 ERROR("SCP_BL2 wrong img format (cm3_type=%d)\n", cm3_type); 270 break; 271 } 272 273 return 0; 274 } 275 276 /* The Armada 8K has 5 service CPUs and Armada 7K has 3. Therefore it was 277 * required to provide a method for loading firmware to all of the service CPUs. 278 * To achieve that, the scp_bl2 image in fact is file containing up to 5 279 * concatenated firmwares and this routine splits concatenated image into single 280 * images dedicated for appropriate service CPU and then load them. 281 */ 282 static int split_and_load_bl2_image(void *image) 283 { 284 file_header_t *file_hdr; 285 img_header_t *img_hdr; 286 uintptr_t single_img; 287 int i; 288 289 file_hdr = (file_header_t *)image; 290 291 if (file_hdr->magic != FILE_MAGIC) { 292 ERROR("SCP_BL2 wrong img format\n"); 293 return -1; 294 } 295 296 if (file_hdr->nr_of_imgs > MAX_NR_OF_FILES) { 297 ERROR("SCP_BL2 concatenated image contains too many images\n"); 298 return -1; 299 } 300 301 img_hdr = (img_header_t *)((uintptr_t)image + sizeof(file_header_t)); 302 single_img = (uintptr_t)image + sizeof(file_header_t) + 303 sizeof(img_header_t) * file_hdr->nr_of_imgs; 304 305 NOTICE("SCP_BL2 contains %d concatenated images\n", 306 file_hdr->nr_of_imgs); 307 for (i = 0; i < file_hdr->nr_of_imgs; i++) { 308 309 /* Before loading make sanity check on header */ 310 if (img_hdr->version != HEADER_VERSION) { 311 ERROR("Wrong header, img corrupted exiting\n"); 312 return -1; 313 } 314 315 load_img_to_cm3(img_hdr->type, single_img, img_hdr->length); 316 317 /* Prepare offsets for next run */ 318 single_img += img_hdr->length; 319 img_hdr++; 320 } 321 322 return 0; 323 } 324 325 int scp_bootloader_transfer(void *image, unsigned int image_size) 326 { 327 #ifdef SCP_BL2_BASE 328 assert((uintptr_t) image == SCP_BL2_BASE); 329 #endif 330 331 VERBOSE("Concatenated img size %d\n", image_size); 332 333 if (image_size == 0) { 334 ERROR("SCP_BL2 image size can't be 0 (current size = 0x%x)\n", 335 image_size); 336 return -1; 337 } 338 339 if (split_and_load_bl2_image(image)) 340 return -1; 341 342 return 0; 343 } 344