1 /* 2 * Copyright (c) 2017-2020, Broadcom 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <string.h> 8 9 #include <arch_helpers.h> 10 #include <common/bl_common.h> 11 #include <common/debug.h> 12 #include <drivers/delay_timer.h> 13 14 #include <bcm_elog_ddr.h> 15 #include <brcm_mhu.h> 16 #include <brcm_scpi.h> 17 #include <chimp.h> 18 #include <cmn_plat_util.h> 19 #include <ddr_init.h> 20 #include <scp.h> 21 #include <scp_cmd.h> 22 #include <scp_utils.h> 23 24 #include "m0_cfg.h" 25 #include "m0_ipc.h" 26 27 #ifdef BCM_ELOG 28 static void prepare_elog(void) 29 { 30 #if (CLEAN_DDR && !defined(MMU_DISABLED)) 31 /* 32 * Now DDR has been initialized. We want to copy all the logs in SRAM 33 * into DDR so we will have much more space to store the logs in the 34 * next boot stage 35 */ 36 bcm_elog_copy_log((void *)BCM_ELOG_BL31_BASE, 37 MIN(BCM_ELOG_BL2_SIZE, BCM_ELOG_BL31_SIZE) 38 ); 39 40 /* 41 * We are almost at the end of BL2, and we can stop log here so we do 42 * not need to add 'bcm_elog_exit' to the standard BL2 code. The 43 * benefit of capturing BL2 logs after this is very minimal in a 44 * production system. 45 */ 46 bcm_elog_exit(); 47 #endif 48 49 /* 50 * Notify CRMU that now it should pull logs from DDR instead of from 51 * FS4 SRAM. 52 */ 53 SCP_WRITE_CFG(flash_log.can_use_ddr, 1); 54 } 55 #endif 56 57 bool is_crmu_alive(void) 58 { 59 return (scp_send_cmd(MCU_IPC_MCU_CMD_NOP, 0, SCP_CMD_DEFAULT_TIMEOUT_US) 60 == 0); 61 } 62 63 bool bcm_scp_issue_sys_reset(void) 64 { 65 return (scp_send_cmd(MCU_IPC_MCU_CMD_L1_RESET, 0, 66 SCP_CMD_DEFAULT_TIMEOUT_US)); 67 } 68 69 /* 70 * Note that this is just a temporary implementation until 71 * channels are introduced 72 */ 73 74 int plat_bcm_bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info) 75 { 76 int scp_patch_activated, scp_patch_version; 77 #ifndef EMULATION_SETUP 78 uint8_t active_ch_bitmap, i; 79 #endif 80 uint32_t reset_state = 0; 81 uint32_t mcu_ap_init_param = 0; 82 83 /* 84 * First check if SCP patch has already been loaded 85 * Send NOP command and see if there is a valid response 86 */ 87 scp_patch_activated = 88 (scp_send_cmd(MCU_IPC_MCU_CMD_NOP, 0, 89 SCP_CMD_DEFAULT_TIMEOUT_US) == 0); 90 if (scp_patch_activated) { 91 INFO("SCP Patch is already active.\n"); 92 93 reset_state = SCP_READ_CFG(board_cfg.reset_state); 94 mcu_ap_init_param = SCP_READ_CFG(board_cfg.mcu_init_param); 95 96 /* Clear reset state, it's been already read */ 97 SCP_WRITE_CFG(board_cfg.reset_state, 0); 98 99 if (mcu_ap_init_param & MCU_PATCH_LOADED_BY_NITRO) { 100 /* 101 * Reset "MCU_PATCH_LOADED_BY_NITRO" flag, but 102 * Preserve any other flags we don't deal with here 103 */ 104 INFO("AP booted by Nitro\n"); 105 SCP_WRITE_CFG( 106 board_cfg.mcu_init_param, 107 mcu_ap_init_param & 108 ~MCU_PATCH_LOADED_BY_NITRO 109 ); 110 } 111 } else { 112 /* 113 * MCU Patch not loaded, so load it. 114 * MCU patch stamps critical points in REG9 (debug test-point) 115 * Display its last content here. This helps to locate 116 * where crash occurred if a CRMU watchdog kicked in. 117 */ 118 int ret; 119 120 INFO("MCU Patch Point: 0x%x\n", 121 mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG9)); 122 123 ret = download_scp_patch((void *)scp_bl2_image_info->image_base, 124 scp_bl2_image_info->image_size); 125 if (ret != 0) 126 return ret; 127 128 VERBOSE("SCP Patch loaded OK.\n"); 129 130 ret = scp_send_cmd(MCU_IPC_MCU_CMD_INIT, 131 MCU_PATCH_LOADED_BY_AP, 132 SCP_CMD_SCP_BOOT_TIMEOUT_US); 133 if (ret) { 134 ERROR("SCP Patch could not initialize; error %d\n", 135 ret); 136 return ret; 137 } 138 139 INFO("SCP Patch successfully initialized.\n"); 140 } 141 142 scp_patch_version = scp_send_cmd(MCU_IPC_MCU_CMD_GET_FW_VERSION, 0, 143 SCP_CMD_DEFAULT_TIMEOUT_US); 144 INFO("SCP Patch version :0x%x\n", scp_patch_version); 145 146 /* Next block just reports current AVS voltages (if applicable) */ 147 { 148 uint16_t vcore_mv, ihost03_mv, ihost12_mv; 149 150 vcore_mv = SCP_READ_CFG16(vcore.millivolts) + 151 SCP_READ_CFG8(vcore.avs_cfg.additive_margin); 152 ihost03_mv = SCP_READ_CFG16(ihost03.millivolts) + 153 SCP_READ_CFG8(ihost03.avs_cfg.additive_margin); 154 ihost12_mv = SCP_READ_CFG16(ihost12.millivolts) + 155 SCP_READ_CFG8(ihost12.avs_cfg.additive_margin); 156 157 if (vcore_mv || ihost03_mv || ihost12_mv) { 158 INFO("AVS voltages from cfg (including margin)\n"); 159 if (vcore_mv > 0) 160 INFO("%s\tVCORE: %dmv\n", 161 SCP_READ_CFG8(vcore.avs_cfg.avs_set) ? 162 "*" : "n/a", vcore_mv); 163 if (ihost03_mv > 0) 164 INFO("%s\tIHOST03: %dmv\n", 165 SCP_READ_CFG8(ihost03.avs_cfg.avs_set) ? 166 "*" : "n/a", ihost03_mv); 167 if (ihost12_mv > 0) 168 INFO("%s\tIHOST12: %dmv\n", 169 SCP_READ_CFG8(ihost12.avs_cfg.avs_set) ? 170 "*" : "n/a", ihost12_mv); 171 } else { 172 INFO("AVS settings not applicable\n"); 173 } 174 } 175 176 #if (CLEAN_DDR && !defined(MMU_DISABLED) && !defined(EMULATION_SETUP)) 177 /* This will clean the DDR and enable ECC if set */ 178 check_ddr_clean(); 179 #endif 180 181 #if (WARMBOOT_DDR_S3_SUPPORT && ELOG_STORE_MEDIA_DDR) 182 elog_init_ddr_log(); 183 #endif 184 185 #ifdef BCM_ELOG 186 /* Prepare ELOG to use DDR */ 187 prepare_elog(); 188 #endif 189 190 #ifndef EMULATION_SETUP 191 /* Ask ddr_init to save obtained DDR information into DDR */ 192 ddr_info_save(); 193 #endif 194 195 /* 196 * Configure TMON DDR address. 197 * This cfg is common for all cases 198 */ 199 SCP_WRITE_CFG(tmon_cfg.ddr_desc, TMON_SHARED_DDR_ADDRESS); 200 201 if (reset_state == SOFT_RESET_L3 && !mcu_ap_init_param) { 202 INFO("SCP configuration after L3 RESET done.\n"); 203 return 0; 204 } 205 206 if (bcm_chimp_is_nic_mode()) 207 /* Configure AP WDT to not reset the NIC interface */ 208 SCP_WRITE_CFG(board_cfg.apwdt_reset_type, SOFT_RESET_L3); 209 210 #if (WARMBOOT_DDR_S3_SUPPORT && ELOG_STORE_MEDIA_DDR) 211 /* When AP WDog triggers perform L3 reset if DDR err logging enabled */ 212 SCP_WRITE_CFG(board_cfg.apwdt_reset_type, SOFT_RESET_L3); 213 #endif 214 215 #ifndef EMULATION_SETUP 216 217 #ifdef DDR_SCRUB_ENA 218 ddr_scrub_enable(); 219 #endif 220 /* Fill the Active channel information */ 221 active_ch_bitmap = get_active_ddr_channel(); 222 for (i = 0; i < MAX_NR_DDR_CH; i++) 223 SCP_WRITE_CFG(ddr_cfg.ddr_cfg[i], 224 (active_ch_bitmap & BIT(i)) ? 1 : 0); 225 #endif 226 return 0; 227 } 228