xref: /rk3399_ARM-atf/plat/marvell/armada/common/mss/mss_scp_bootloader.c (revision 9935047b2086faa3bf3ccf0b95a76510eb5a160b)
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