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
prepare_elog(void)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 
is_crmu_alive(void)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 
bcm_scp_issue_sys_reset(void)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 
plat_bcm_bl2_plat_handle_scp_bl2(image_info_t * scp_bl2_image_info)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