xref: /rk3399_ARM-atf/plat/nxp/common/setup/ls_io_storage.c (revision b57d9d6f29d8dcb8d6b5792ea5a2ed313f2d4292)
1b53c2c5fSPankaj Gupta /*
2*b759727fSJiafei Pan  * Copyright 2018-2021 NXP
3b53c2c5fSPankaj Gupta  *
4b53c2c5fSPankaj Gupta  * SPDX-License-Identifier: BSD-3-Clause
5b53c2c5fSPankaj Gupta  *
6b53c2c5fSPankaj Gupta  */
7b53c2c5fSPankaj Gupta 
8b53c2c5fSPankaj Gupta #include <assert.h>
9b53c2c5fSPankaj Gupta #include <endian.h>
10b53c2c5fSPankaj Gupta #include <string.h>
11b53c2c5fSPankaj Gupta 
12b53c2c5fSPankaj Gupta #include <common/debug.h>
13b53c2c5fSPankaj Gupta #include <common/tbbr/tbbr_img_def.h>
14b53c2c5fSPankaj Gupta #include <drivers/io/io_block.h>
15b53c2c5fSPankaj Gupta #include <drivers/io/io_driver.h>
16b53c2c5fSPankaj Gupta #include <drivers/io/io_fip.h>
17b53c2c5fSPankaj Gupta #include <drivers/io/io_memmap.h>
18b53c2c5fSPankaj Gupta #include <drivers/io/io_storage.h>
19b53c2c5fSPankaj Gupta #ifdef FLEXSPI_NOR_BOOT
20b53c2c5fSPankaj Gupta #include <flexspi_nor.h>
21b53c2c5fSPankaj Gupta #endif
22*b759727fSJiafei Pan #if defined(NAND_BOOT)
23*b759727fSJiafei Pan #include <ifc_nand.h>
24*b759727fSJiafei Pan #endif
25*b759727fSJiafei Pan #if defined(NOR_BOOT)
26*b759727fSJiafei Pan #include <ifc_nor.h>
27*b759727fSJiafei Pan #endif
28b53c2c5fSPankaj Gupta #if defined(QSPI_BOOT)
29b53c2c5fSPankaj Gupta #include <qspi.h>
30b53c2c5fSPankaj Gupta #endif
31b53c2c5fSPankaj Gupta #if defined(SD_BOOT) || defined(EMMC_BOOT)
32b53c2c5fSPankaj Gupta #include <sd_mmc.h>
33b53c2c5fSPankaj Gupta #endif
34b53c2c5fSPankaj Gupta #include <tools_share/firmware_image_package.h>
35b53c2c5fSPankaj Gupta 
36b53c2c5fSPankaj Gupta #ifdef CONFIG_DDR_FIP_IMAGE
37b53c2c5fSPankaj Gupta #include <ddr_io_storage.h>
38b53c2c5fSPankaj Gupta #endif
39b53c2c5fSPankaj Gupta #ifdef POLICY_FUSE_PROVISION
40b53c2c5fSPankaj Gupta #include <fuse_io.h>
41b53c2c5fSPankaj Gupta #endif
42b53c2c5fSPankaj Gupta #include "plat_common.h"
43b53c2c5fSPankaj Gupta #include "platform_def.h"
44b53c2c5fSPankaj Gupta 
45b53c2c5fSPankaj Gupta uint32_t fip_device;
46b53c2c5fSPankaj Gupta /* IO devices */
47b53c2c5fSPankaj Gupta uintptr_t backend_dev_handle;
48b53c2c5fSPankaj Gupta 
49b53c2c5fSPankaj Gupta static const io_dev_connector_t *fip_dev_con;
50b53c2c5fSPankaj Gupta static uintptr_t fip_dev_handle;
51b53c2c5fSPankaj Gupta static const io_dev_connector_t *backend_dev_con;
52b53c2c5fSPankaj Gupta 
53b53c2c5fSPankaj Gupta static io_block_spec_t fip_block_spec = {
54b53c2c5fSPankaj Gupta 	.offset = PLAT_FIP_OFFSET,
55b53c2c5fSPankaj Gupta 	.length = PLAT_FIP_MAX_SIZE
56b53c2c5fSPankaj Gupta };
57b53c2c5fSPankaj Gupta 
58b53c2c5fSPankaj Gupta static const io_uuid_spec_t bl2_uuid_spec = {
59b53c2c5fSPankaj Gupta 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
60b53c2c5fSPankaj Gupta };
61b53c2c5fSPankaj Gupta 
62b53c2c5fSPankaj Gupta static const io_uuid_spec_t fuse_bl2_uuid_spec = {
63b53c2c5fSPankaj Gupta 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
64b53c2c5fSPankaj Gupta };
65b53c2c5fSPankaj Gupta 
66b53c2c5fSPankaj Gupta static const io_uuid_spec_t bl31_uuid_spec = {
67b53c2c5fSPankaj Gupta 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
68b53c2c5fSPankaj Gupta };
69b53c2c5fSPankaj Gupta 
70b53c2c5fSPankaj Gupta static const io_uuid_spec_t bl32_uuid_spec = {
71b53c2c5fSPankaj Gupta 	.uuid = UUID_SECURE_PAYLOAD_BL32,
72b53c2c5fSPankaj Gupta };
73b53c2c5fSPankaj Gupta 
74b53c2c5fSPankaj Gupta static const io_uuid_spec_t bl33_uuid_spec = {
75b53c2c5fSPankaj Gupta 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
76b53c2c5fSPankaj Gupta };
77b53c2c5fSPankaj Gupta 
78b53c2c5fSPankaj Gupta static const io_uuid_spec_t tb_fw_config_uuid_spec = {
79b53c2c5fSPankaj Gupta 	.uuid = UUID_TB_FW_CONFIG,
80b53c2c5fSPankaj Gupta };
81b53c2c5fSPankaj Gupta 
82b53c2c5fSPankaj Gupta static const io_uuid_spec_t hw_config_uuid_spec = {
83b53c2c5fSPankaj Gupta 	.uuid = UUID_HW_CONFIG,
84b53c2c5fSPankaj Gupta };
85b53c2c5fSPankaj Gupta 
86b53c2c5fSPankaj Gupta #if TRUSTED_BOARD_BOOT
87b53c2c5fSPankaj Gupta static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
88b53c2c5fSPankaj Gupta 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
89b53c2c5fSPankaj Gupta };
90b53c2c5fSPankaj Gupta 
91b53c2c5fSPankaj Gupta static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
92b53c2c5fSPankaj Gupta 	.uuid = UUID_TRUSTED_KEY_CERT,
93b53c2c5fSPankaj Gupta };
94b53c2c5fSPankaj Gupta 
95b53c2c5fSPankaj Gupta static const io_uuid_spec_t fuse_key_cert_uuid_spec = {
96b53c2c5fSPankaj Gupta 	.uuid = UUID_SCP_FW_KEY_CERT,
97b53c2c5fSPankaj Gupta };
98b53c2c5fSPankaj Gupta 
99b53c2c5fSPankaj Gupta static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
100b53c2c5fSPankaj Gupta 	.uuid = UUID_SOC_FW_KEY_CERT,
101b53c2c5fSPankaj Gupta };
102b53c2c5fSPankaj Gupta 
103b53c2c5fSPankaj Gupta static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
104b53c2c5fSPankaj Gupta 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
105b53c2c5fSPankaj Gupta };
106b53c2c5fSPankaj Gupta 
107b53c2c5fSPankaj Gupta static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
108b53c2c5fSPankaj Gupta 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
109b53c2c5fSPankaj Gupta };
110b53c2c5fSPankaj Gupta 
111b53c2c5fSPankaj Gupta static const io_uuid_spec_t fuse_cert_uuid_spec = {
112b53c2c5fSPankaj Gupta 	.uuid = UUID_SCP_FW_CONTENT_CERT,
113b53c2c5fSPankaj Gupta };
114b53c2c5fSPankaj Gupta 
115b53c2c5fSPankaj Gupta static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
116b53c2c5fSPankaj Gupta 	.uuid = UUID_SOC_FW_CONTENT_CERT,
117b53c2c5fSPankaj Gupta };
118b53c2c5fSPankaj Gupta 
119b53c2c5fSPankaj Gupta static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
120b53c2c5fSPankaj Gupta 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
121b53c2c5fSPankaj Gupta };
122b53c2c5fSPankaj Gupta 
123b53c2c5fSPankaj Gupta static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
124b53c2c5fSPankaj Gupta 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
125b53c2c5fSPankaj Gupta };
126b53c2c5fSPankaj Gupta #endif /* TRUSTED_BOARD_BOOT */
127b53c2c5fSPankaj Gupta 
128b53c2c5fSPankaj Gupta static int open_fip(const uintptr_t spec);
129b53c2c5fSPankaj Gupta 
130b53c2c5fSPankaj Gupta struct plat_io_policy {
131b53c2c5fSPankaj Gupta 	uintptr_t *dev_handle;
132b53c2c5fSPankaj Gupta 	uintptr_t image_spec;
133b53c2c5fSPankaj Gupta 	int (*check)(const uintptr_t spec);
134b53c2c5fSPankaj Gupta };
135b53c2c5fSPankaj Gupta 
136b53c2c5fSPankaj Gupta /* By default, ARM platforms load images from the FIP */
137b53c2c5fSPankaj Gupta static const struct plat_io_policy policies[] = {
138b53c2c5fSPankaj Gupta 	[FIP_IMAGE_ID] = {
139b53c2c5fSPankaj Gupta 		&backend_dev_handle,
140b53c2c5fSPankaj Gupta 		(uintptr_t)&fip_block_spec,
141b53c2c5fSPankaj Gupta 		open_backend
142b53c2c5fSPankaj Gupta 	},
143b53c2c5fSPankaj Gupta 	[BL2_IMAGE_ID] = {
144b53c2c5fSPankaj Gupta 		&fip_dev_handle,
145b53c2c5fSPankaj Gupta 		(uintptr_t)&bl2_uuid_spec,
146b53c2c5fSPankaj Gupta 		open_fip
147b53c2c5fSPankaj Gupta 	},
148b53c2c5fSPankaj Gupta 	[SCP_BL2_IMAGE_ID] = {
149b53c2c5fSPankaj Gupta 		&fip_dev_handle,
150b53c2c5fSPankaj Gupta 		(uintptr_t)&fuse_bl2_uuid_spec,
151b53c2c5fSPankaj Gupta 		open_fip
152b53c2c5fSPankaj Gupta 	},
153b53c2c5fSPankaj Gupta 	[BL31_IMAGE_ID] = {
154b53c2c5fSPankaj Gupta 		&fip_dev_handle,
155b53c2c5fSPankaj Gupta 		(uintptr_t)&bl31_uuid_spec,
156b53c2c5fSPankaj Gupta 		open_fip
157b53c2c5fSPankaj Gupta 	},
158b53c2c5fSPankaj Gupta 	[BL32_IMAGE_ID] = {
159b53c2c5fSPankaj Gupta 		&fip_dev_handle,
160b53c2c5fSPankaj Gupta 		(uintptr_t)&bl32_uuid_spec,
161b53c2c5fSPankaj Gupta 		open_fip
162b53c2c5fSPankaj Gupta 	},
163b53c2c5fSPankaj Gupta 	[BL33_IMAGE_ID] = {
164b53c2c5fSPankaj Gupta 		&fip_dev_handle,
165b53c2c5fSPankaj Gupta 		(uintptr_t)&bl33_uuid_spec,
166b53c2c5fSPankaj Gupta 		open_fip
167b53c2c5fSPankaj Gupta 	},
168b53c2c5fSPankaj Gupta 	[TB_FW_CONFIG_ID] = {
169b53c2c5fSPankaj Gupta 		&fip_dev_handle,
170b53c2c5fSPankaj Gupta 		(uintptr_t)&tb_fw_config_uuid_spec,
171b53c2c5fSPankaj Gupta 		open_fip
172b53c2c5fSPankaj Gupta 	},
173b53c2c5fSPankaj Gupta 	[HW_CONFIG_ID] = {
174b53c2c5fSPankaj Gupta 		&fip_dev_handle,
175b53c2c5fSPankaj Gupta 		(uintptr_t)&hw_config_uuid_spec,
176b53c2c5fSPankaj Gupta 		open_fip
177b53c2c5fSPankaj Gupta 	},
178b53c2c5fSPankaj Gupta #if TRUSTED_BOARD_BOOT
179b53c2c5fSPankaj Gupta 	[TRUSTED_BOOT_FW_CERT_ID] = {
180b53c2c5fSPankaj Gupta 		&fip_dev_handle,
181b53c2c5fSPankaj Gupta 		(uintptr_t)&tb_fw_cert_uuid_spec,
182b53c2c5fSPankaj Gupta 		open_fip
183b53c2c5fSPankaj Gupta 	},
184b53c2c5fSPankaj Gupta 	[TRUSTED_KEY_CERT_ID] = {
185b53c2c5fSPankaj Gupta 		&fip_dev_handle,
186b53c2c5fSPankaj Gupta 		(uintptr_t)&trusted_key_cert_uuid_spec,
187b53c2c5fSPankaj Gupta 		open_fip
188b53c2c5fSPankaj Gupta 	},
189b53c2c5fSPankaj Gupta 	[SCP_FW_KEY_CERT_ID] = {
190b53c2c5fSPankaj Gupta 		&fip_dev_handle,
191b53c2c5fSPankaj Gupta 		(uintptr_t)&fuse_key_cert_uuid_spec,
192b53c2c5fSPankaj Gupta 		open_fip
193b53c2c5fSPankaj Gupta 	},
194b53c2c5fSPankaj Gupta 	[SOC_FW_KEY_CERT_ID] = {
195b53c2c5fSPankaj Gupta 		&fip_dev_handle,
196b53c2c5fSPankaj Gupta 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
197b53c2c5fSPankaj Gupta 		open_fip
198b53c2c5fSPankaj Gupta 	},
199b53c2c5fSPankaj Gupta 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
200b53c2c5fSPankaj Gupta 		&fip_dev_handle,
201b53c2c5fSPankaj Gupta 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
202b53c2c5fSPankaj Gupta 		open_fip
203b53c2c5fSPankaj Gupta 	},
204b53c2c5fSPankaj Gupta 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
205b53c2c5fSPankaj Gupta 		&fip_dev_handle,
206b53c2c5fSPankaj Gupta 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
207b53c2c5fSPankaj Gupta 		open_fip
208b53c2c5fSPankaj Gupta 	},
209b53c2c5fSPankaj Gupta 	[SCP_FW_CONTENT_CERT_ID] = {
210b53c2c5fSPankaj Gupta 		&fip_dev_handle,
211b53c2c5fSPankaj Gupta 		(uintptr_t)&fuse_cert_uuid_spec,
212b53c2c5fSPankaj Gupta 		open_fip
213b53c2c5fSPankaj Gupta 	},
214b53c2c5fSPankaj Gupta 	[SOC_FW_CONTENT_CERT_ID] = {
215b53c2c5fSPankaj Gupta 		&fip_dev_handle,
216b53c2c5fSPankaj Gupta 		(uintptr_t)&soc_fw_cert_uuid_spec,
217b53c2c5fSPankaj Gupta 		open_fip
218b53c2c5fSPankaj Gupta 	},
219b53c2c5fSPankaj Gupta 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
220b53c2c5fSPankaj Gupta 		&fip_dev_handle,
221b53c2c5fSPankaj Gupta 		(uintptr_t)&tos_fw_cert_uuid_spec,
222b53c2c5fSPankaj Gupta 		open_fip
223b53c2c5fSPankaj Gupta 	},
224b53c2c5fSPankaj Gupta 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
225b53c2c5fSPankaj Gupta 		&fip_dev_handle,
226b53c2c5fSPankaj Gupta 		(uintptr_t)&nt_fw_cert_uuid_spec,
227b53c2c5fSPankaj Gupta 		open_fip
228b53c2c5fSPankaj Gupta 	},
229b53c2c5fSPankaj Gupta #endif /* TRUSTED_BOARD_BOOT */
230b53c2c5fSPankaj Gupta };
231b53c2c5fSPankaj Gupta 
232b53c2c5fSPankaj Gupta 
233b53c2c5fSPankaj Gupta /* Weak definitions may be overridden in specific ARM standard platform */
234b53c2c5fSPankaj Gupta #pragma weak plat_io_setup
235b53c2c5fSPankaj Gupta 
236b53c2c5fSPankaj Gupta /*
237b53c2c5fSPankaj Gupta  * Return an IO device handle and specification which can be used to access
238b53c2c5fSPankaj Gupta  */
open_fip(const uintptr_t spec)239b53c2c5fSPankaj Gupta static int open_fip(const uintptr_t spec)
240b53c2c5fSPankaj Gupta {
241b53c2c5fSPankaj Gupta 	int result;
242b53c2c5fSPankaj Gupta 	uintptr_t local_image_handle;
243b53c2c5fSPankaj Gupta 
244b53c2c5fSPankaj Gupta 	/* See if a Firmware Image Package is available */
245b53c2c5fSPankaj Gupta 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
246b53c2c5fSPankaj Gupta 	if (result == 0) {
247b53c2c5fSPankaj Gupta 		result = io_open(fip_dev_handle, spec, &local_image_handle);
248b53c2c5fSPankaj Gupta 		if (result == 0) {
249b53c2c5fSPankaj Gupta 			VERBOSE("Using FIP\n");
250b53c2c5fSPankaj Gupta 			io_close(local_image_handle);
251b53c2c5fSPankaj Gupta 		}
252b53c2c5fSPankaj Gupta 	}
253b53c2c5fSPankaj Gupta 	return result;
254b53c2c5fSPankaj Gupta }
255b53c2c5fSPankaj Gupta 
256b53c2c5fSPankaj Gupta 
open_backend(const uintptr_t spec)257b53c2c5fSPankaj Gupta int open_backend(const uintptr_t spec)
258b53c2c5fSPankaj Gupta {
259b53c2c5fSPankaj Gupta 	int result;
260b53c2c5fSPankaj Gupta 	uintptr_t local_image_handle;
261b53c2c5fSPankaj Gupta 
262b53c2c5fSPankaj Gupta 	result = io_dev_init(backend_dev_handle, (uintptr_t)NULL);
263b53c2c5fSPankaj Gupta 	if (result == 0) {
264b53c2c5fSPankaj Gupta 		result = io_open(backend_dev_handle, spec, &local_image_handle);
265b53c2c5fSPankaj Gupta 		if (result == 0) {
266b53c2c5fSPankaj Gupta 			io_close(local_image_handle);
267b53c2c5fSPankaj Gupta 		}
268b53c2c5fSPankaj Gupta 	}
269b53c2c5fSPankaj Gupta 	return result;
270b53c2c5fSPankaj Gupta }
271b53c2c5fSPankaj Gupta 
272*b759727fSJiafei Pan #if defined(SD_BOOT) || defined(EMMC_BOOT) || defined(NAND_BOOT)
plat_io_block_setup(size_t fip_offset,uintptr_t block_dev_spec)273b53c2c5fSPankaj Gupta static int plat_io_block_setup(size_t fip_offset, uintptr_t block_dev_spec)
274b53c2c5fSPankaj Gupta {
275b53c2c5fSPankaj Gupta 	int io_result;
276b53c2c5fSPankaj Gupta 
277b53c2c5fSPankaj Gupta 	fip_block_spec.offset = fip_offset;
278b53c2c5fSPankaj Gupta 
279b53c2c5fSPankaj Gupta 	io_result = register_io_dev_block(&backend_dev_con);
280b53c2c5fSPankaj Gupta 	assert(io_result == 0);
281b53c2c5fSPankaj Gupta 
282b53c2c5fSPankaj Gupta 	/* Open connections to devices and cache the handles */
283b53c2c5fSPankaj Gupta 	io_result = io_dev_open(backend_dev_con, block_dev_spec,
284b53c2c5fSPankaj Gupta 				&backend_dev_handle);
285b53c2c5fSPankaj Gupta 	assert(io_result == 0);
286b53c2c5fSPankaj Gupta 
287b53c2c5fSPankaj Gupta 	return io_result;
288b53c2c5fSPankaj Gupta }
289b53c2c5fSPankaj Gupta #endif
290b53c2c5fSPankaj Gupta 
291*b759727fSJiafei Pan #if defined(FLEXSPI_NOR_BOOT) || defined(QSPI_BOOT) || defined(NOR_BOOT)
plat_io_memmap_setup(size_t fip_offset)292b53c2c5fSPankaj Gupta static int plat_io_memmap_setup(size_t fip_offset)
293b53c2c5fSPankaj Gupta {
294b53c2c5fSPankaj Gupta 	int io_result;
295b53c2c5fSPankaj Gupta 
296b53c2c5fSPankaj Gupta 	fip_block_spec.offset = fip_offset;
297b53c2c5fSPankaj Gupta 
298b53c2c5fSPankaj Gupta 	io_result = register_io_dev_memmap(&backend_dev_con);
299b53c2c5fSPankaj Gupta 	assert(io_result == 0);
300b53c2c5fSPankaj Gupta 
301b53c2c5fSPankaj Gupta 	/* Open connections to devices and cache the handles */
302b53c2c5fSPankaj Gupta 	io_result = io_dev_open(backend_dev_con, (uintptr_t)NULL,
303b53c2c5fSPankaj Gupta 				&backend_dev_handle);
304b53c2c5fSPankaj Gupta 	assert(io_result == 0);
305b53c2c5fSPankaj Gupta 
306b53c2c5fSPankaj Gupta 	return io_result;
307b53c2c5fSPankaj Gupta }
308b53c2c5fSPankaj Gupta #endif
309b53c2c5fSPankaj Gupta 
ls_io_fip_setup(unsigned int boot_dev)310b53c2c5fSPankaj Gupta static int ls_io_fip_setup(unsigned int boot_dev)
311b53c2c5fSPankaj Gupta {
312b53c2c5fSPankaj Gupta 	int io_result;
313b53c2c5fSPankaj Gupta 
314b53c2c5fSPankaj Gupta 	io_result = register_io_dev_fip(&fip_dev_con);
315b53c2c5fSPankaj Gupta 	assert(io_result == 0);
316b53c2c5fSPankaj Gupta 
317b53c2c5fSPankaj Gupta 	/* Open connections to devices and cache the handles */
318b53c2c5fSPankaj Gupta 	io_result = io_dev_open(fip_dev_con, (uintptr_t)&fip_device,
319b53c2c5fSPankaj Gupta 				&fip_dev_handle);
320b53c2c5fSPankaj Gupta 	assert(io_result == 0);
321b53c2c5fSPankaj Gupta 
322b53c2c5fSPankaj Gupta #ifdef CONFIG_DDR_FIP_IMAGE
323b53c2c5fSPankaj Gupta 	/* Open connection to DDR FIP image if available */
324b53c2c5fSPankaj Gupta 	io_result = ddr_fip_setup(fip_dev_con, boot_dev);
325b53c2c5fSPankaj Gupta 
326b53c2c5fSPankaj Gupta 	assert(io_result == 0);
327b53c2c5fSPankaj Gupta #endif
328b53c2c5fSPankaj Gupta 
329b53c2c5fSPankaj Gupta #ifdef POLICY_FUSE_PROVISION
330b53c2c5fSPankaj Gupta 	/* Open connection to FUSE FIP image if available */
331b53c2c5fSPankaj Gupta 	io_result = fuse_fip_setup(fip_dev_con, boot_dev);
332b53c2c5fSPankaj Gupta 
333b53c2c5fSPankaj Gupta 	assert(io_result == 0);
334b53c2c5fSPankaj Gupta #endif
335b53c2c5fSPankaj Gupta 
336b53c2c5fSPankaj Gupta 	return io_result;
337b53c2c5fSPankaj Gupta }
338b53c2c5fSPankaj Gupta 
ls_qspi_io_setup(void)339b53c2c5fSPankaj Gupta int ls_qspi_io_setup(void)
340b53c2c5fSPankaj Gupta {
341b53c2c5fSPankaj Gupta #ifdef QSPI_BOOT
342b53c2c5fSPankaj Gupta 	qspi_io_setup(NXP_QSPI_FLASH_ADDR,
343b53c2c5fSPankaj Gupta 			NXP_QSPI_FLASH_SIZE,
344b53c2c5fSPankaj Gupta 			PLAT_FIP_OFFSET);
345b53c2c5fSPankaj Gupta 	return plat_io_memmap_setup(NXP_QSPI_FLASH_ADDR + PLAT_FIP_OFFSET);
346b53c2c5fSPankaj Gupta #else
347b53c2c5fSPankaj Gupta 	ERROR("QSPI driver not present. Check your BUILD\n");
348b53c2c5fSPankaj Gupta 
349b53c2c5fSPankaj Gupta 	/* Should never reach here */
350b53c2c5fSPankaj Gupta 	assert(false);
351b53c2c5fSPankaj Gupta 	return -1;
352b53c2c5fSPankaj Gupta #endif
353b53c2c5fSPankaj Gupta }
354b53c2c5fSPankaj Gupta 
emmc_sdhc2_io_setup(void)355b53c2c5fSPankaj Gupta int emmc_sdhc2_io_setup(void)
356b53c2c5fSPankaj Gupta {
357b53c2c5fSPankaj Gupta #if defined(EMMC_BOOT) && defined(NXP_ESDHC2_ADDR)
358b53c2c5fSPankaj Gupta 	uintptr_t block_dev_spec;
359b53c2c5fSPankaj Gupta 	int ret;
360b53c2c5fSPankaj Gupta 
361b53c2c5fSPankaj Gupta 	ret = sd_emmc_init(&block_dev_spec,
362b53c2c5fSPankaj Gupta 			NXP_ESDHC2_ADDR,
363b53c2c5fSPankaj Gupta 			NXP_SD_BLOCK_BUF_ADDR,
364b53c2c5fSPankaj Gupta 			NXP_SD_BLOCK_BUF_SIZE,
365b53c2c5fSPankaj Gupta 			false);
366b53c2c5fSPankaj Gupta 	if (ret != 0) {
367b53c2c5fSPankaj Gupta 		return ret;
368b53c2c5fSPankaj Gupta 	}
369b53c2c5fSPankaj Gupta 
370b53c2c5fSPankaj Gupta 	return plat_io_block_setup(PLAT_FIP_OFFSET, block_dev_spec);
371b53c2c5fSPankaj Gupta #else
372b53c2c5fSPankaj Gupta 	ERROR("EMMC driver not present. Check your BUILD\n");
373b53c2c5fSPankaj Gupta 
374b53c2c5fSPankaj Gupta 	/* Should never reach here */
375b53c2c5fSPankaj Gupta 	assert(false);
376b53c2c5fSPankaj Gupta 	return -1;
377b53c2c5fSPankaj Gupta #endif
378b53c2c5fSPankaj Gupta }
379b53c2c5fSPankaj Gupta 
emmc_io_setup(void)380b53c2c5fSPankaj Gupta int emmc_io_setup(void)
381b53c2c5fSPankaj Gupta {
382b53c2c5fSPankaj Gupta /* On the platforms which only has one ESDHC controller,
383b53c2c5fSPankaj Gupta  * eMMC-boot will use the first ESDHC controller.
384b53c2c5fSPankaj Gupta  */
385b53c2c5fSPankaj Gupta #if defined(SD_BOOT) || defined(EMMC_BOOT)
386b53c2c5fSPankaj Gupta 	uintptr_t block_dev_spec;
387b53c2c5fSPankaj Gupta 	int ret;
388b53c2c5fSPankaj Gupta 
389b53c2c5fSPankaj Gupta 	ret = sd_emmc_init(&block_dev_spec,
390b53c2c5fSPankaj Gupta 			NXP_ESDHC_ADDR,
391b53c2c5fSPankaj Gupta 			NXP_SD_BLOCK_BUF_ADDR,
392b53c2c5fSPankaj Gupta 			NXP_SD_BLOCK_BUF_SIZE,
393b53c2c5fSPankaj Gupta 			true);
394b53c2c5fSPankaj Gupta 	if (ret != 0) {
395b53c2c5fSPankaj Gupta 		return ret;
396b53c2c5fSPankaj Gupta 	}
397b53c2c5fSPankaj Gupta 
398b53c2c5fSPankaj Gupta 	return plat_io_block_setup(PLAT_FIP_OFFSET, block_dev_spec);
399b53c2c5fSPankaj Gupta #else
400b53c2c5fSPankaj Gupta 	ERROR("SD driver not present. Check your BUILD\n");
401b53c2c5fSPankaj Gupta 
402b53c2c5fSPankaj Gupta 	/* Should never reach here */
403b53c2c5fSPankaj Gupta 	assert(false);
404b53c2c5fSPankaj Gupta 	return -1;
405b53c2c5fSPankaj Gupta #endif
406b53c2c5fSPankaj Gupta }
407b53c2c5fSPankaj Gupta 
ifc_nor_io_setup(void)408b53c2c5fSPankaj Gupta int ifc_nor_io_setup(void)
409b53c2c5fSPankaj Gupta {
410*b759727fSJiafei Pan #if defined(NOR_BOOT)
411*b759727fSJiafei Pan 	int ret;
412*b759727fSJiafei Pan 
413*b759727fSJiafei Pan 	ret = ifc_nor_init(NXP_NOR_FLASH_ADDR,
414*b759727fSJiafei Pan 			NXP_NOR_FLASH_SIZE);
415*b759727fSJiafei Pan 
416*b759727fSJiafei Pan 	if (ret != 0) {
417*b759727fSJiafei Pan 		return ret;
418*b759727fSJiafei Pan 	}
419*b759727fSJiafei Pan 
420*b759727fSJiafei Pan 	return plat_io_memmap_setup(NXP_NOR_FLASH_ADDR + PLAT_FIP_OFFSET);
421*b759727fSJiafei Pan #else
422b53c2c5fSPankaj Gupta 	ERROR("NOR driver not present. Check your BUILD\n");
423b53c2c5fSPankaj Gupta 
424b53c2c5fSPankaj Gupta 	/* Should never reach here */
425b53c2c5fSPankaj Gupta 	assert(false);
426b53c2c5fSPankaj Gupta 	return -1;
427*b759727fSJiafei Pan #endif
428b53c2c5fSPankaj Gupta }
429b53c2c5fSPankaj Gupta 
ifc_nand_io_setup(void)430b53c2c5fSPankaj Gupta int ifc_nand_io_setup(void)
431b53c2c5fSPankaj Gupta {
432*b759727fSJiafei Pan #if defined(NAND_BOOT)
433*b759727fSJiafei Pan 	uintptr_t block_dev_spec;
434*b759727fSJiafei Pan 	int ret;
435*b759727fSJiafei Pan 
436*b759727fSJiafei Pan 	ret = ifc_nand_init(&block_dev_spec,
437*b759727fSJiafei Pan 			NXP_IFC_REGION_ADDR,
438*b759727fSJiafei Pan 			NXP_IFC_ADDR,
439*b759727fSJiafei Pan 			NXP_IFC_SRAM_BUFFER_SIZE,
440*b759727fSJiafei Pan 			NXP_SD_BLOCK_BUF_ADDR,
441*b759727fSJiafei Pan 			NXP_SD_BLOCK_BUF_SIZE);
442*b759727fSJiafei Pan 	if (ret != 0) {
443*b759727fSJiafei Pan 		return ret;
444*b759727fSJiafei Pan 	}
445*b759727fSJiafei Pan 
446*b759727fSJiafei Pan 	return plat_io_block_setup(PLAT_FIP_OFFSET, block_dev_spec);
447*b759727fSJiafei Pan #else
448*b759727fSJiafei Pan 
449b53c2c5fSPankaj Gupta 	ERROR("NAND driver not present. Check your BUILD\n");
450b53c2c5fSPankaj Gupta 
451b53c2c5fSPankaj Gupta 	/* Should never reach here */
452b53c2c5fSPankaj Gupta 	assert(false);
453b53c2c5fSPankaj Gupta 	return -1;
454*b759727fSJiafei Pan #endif
455b53c2c5fSPankaj Gupta }
456b53c2c5fSPankaj Gupta 
ls_flexspi_nor_io_setup(void)457b53c2c5fSPankaj Gupta int ls_flexspi_nor_io_setup(void)
458b53c2c5fSPankaj Gupta {
459b53c2c5fSPankaj Gupta #ifdef FLEXSPI_NOR_BOOT
460b53c2c5fSPankaj Gupta 	int ret = 0;
461b53c2c5fSPankaj Gupta 
462b53c2c5fSPankaj Gupta 	ret = flexspi_nor_io_setup(NXP_FLEXSPI_FLASH_ADDR,
463b53c2c5fSPankaj Gupta 				   NXP_FLEXSPI_FLASH_SIZE,
464b53c2c5fSPankaj Gupta 				   NXP_FLEXSPI_ADDR);
465b53c2c5fSPankaj Gupta 
466b53c2c5fSPankaj Gupta 	if (ret != 0) {
467b53c2c5fSPankaj Gupta 		ERROR("FlexSPI NOR driver initialization error.\n");
468b53c2c5fSPankaj Gupta 		/* Should never reach here */
469b53c2c5fSPankaj Gupta 		assert(0);
470b53c2c5fSPankaj Gupta 		panic();
471b53c2c5fSPankaj Gupta 		return -1;
472b53c2c5fSPankaj Gupta 	}
473b53c2c5fSPankaj Gupta 
474b53c2c5fSPankaj Gupta 	return plat_io_memmap_setup(NXP_FLEXSPI_FLASH_ADDR + PLAT_FIP_OFFSET);
475b53c2c5fSPankaj Gupta #else
476b53c2c5fSPankaj Gupta 	ERROR("FlexSPI NOR driver not present. Check your BUILD\n");
477b53c2c5fSPankaj Gupta 
478b53c2c5fSPankaj Gupta 	/* Should never reach here */
479b53c2c5fSPankaj Gupta 	assert(false);
480b53c2c5fSPankaj Gupta 	return -1;
481b53c2c5fSPankaj Gupta #endif
482b53c2c5fSPankaj Gupta }
483b53c2c5fSPankaj Gupta 
484b53c2c5fSPankaj Gupta static int (* const ls_io_setup_table[])(void) = {
485b53c2c5fSPankaj Gupta 	[BOOT_DEVICE_IFC_NOR] = ifc_nor_io_setup,
486b53c2c5fSPankaj Gupta 	[BOOT_DEVICE_IFC_NAND] = ifc_nand_io_setup,
487b53c2c5fSPankaj Gupta 	[BOOT_DEVICE_QSPI] = ls_qspi_io_setup,
488b53c2c5fSPankaj Gupta 	[BOOT_DEVICE_EMMC] = emmc_io_setup,
489b53c2c5fSPankaj Gupta 	[BOOT_DEVICE_SDHC2_EMMC] = emmc_sdhc2_io_setup,
490b53c2c5fSPankaj Gupta 	[BOOT_DEVICE_FLEXSPI_NOR] = ls_flexspi_nor_io_setup,
491b53c2c5fSPankaj Gupta 	[BOOT_DEVICE_FLEXSPI_NAND] = ls_flexspi_nor_io_setup,
492b53c2c5fSPankaj Gupta };
493b53c2c5fSPankaj Gupta 
494b53c2c5fSPankaj Gupta 
plat_io_setup(void)495b53c2c5fSPankaj Gupta int plat_io_setup(void)
496b53c2c5fSPankaj Gupta {
497b53c2c5fSPankaj Gupta 	int (*io_setup)(void);
498b53c2c5fSPankaj Gupta 	unsigned int boot_dev = BOOT_DEVICE_NONE;
499b53c2c5fSPankaj Gupta 	int ret;
500b53c2c5fSPankaj Gupta 
501b53c2c5fSPankaj Gupta 	boot_dev = get_boot_dev();
502b53c2c5fSPankaj Gupta 	if (boot_dev == BOOT_DEVICE_NONE) {
503b53c2c5fSPankaj Gupta 		ERROR("Boot Device detection failed, Check RCW_SRC\n");
504b53c2c5fSPankaj Gupta 		return -EINVAL;
505b53c2c5fSPankaj Gupta 	}
506b53c2c5fSPankaj Gupta 
507b53c2c5fSPankaj Gupta 	io_setup = ls_io_setup_table[boot_dev];
508b53c2c5fSPankaj Gupta 	ret = io_setup();
509b53c2c5fSPankaj Gupta 	if (ret != 0) {
510b53c2c5fSPankaj Gupta 		return ret;
511b53c2c5fSPankaj Gupta 	}
512b53c2c5fSPankaj Gupta 
513b53c2c5fSPankaj Gupta 	ret = ls_io_fip_setup(boot_dev);
514b53c2c5fSPankaj Gupta 	if (ret != 0) {
515b53c2c5fSPankaj Gupta 		return ret;
516b53c2c5fSPankaj Gupta 	}
517b53c2c5fSPankaj Gupta 
518b53c2c5fSPankaj Gupta 	return 0;
519b53c2c5fSPankaj Gupta }
520b53c2c5fSPankaj Gupta 
521b53c2c5fSPankaj Gupta 
522b53c2c5fSPankaj Gupta /* Return an IO device handle and specification which can be used to access
523b53c2c5fSPankaj Gupta  * an image. Use this to enforce platform load policy
524b53c2c5fSPankaj Gupta  */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)525b53c2c5fSPankaj Gupta int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
526b53c2c5fSPankaj Gupta 			  uintptr_t *image_spec)
527b53c2c5fSPankaj Gupta {
528b53c2c5fSPankaj Gupta 	int result = -1;
529b53c2c5fSPankaj Gupta 	const struct plat_io_policy *policy;
530b53c2c5fSPankaj Gupta 
531b53c2c5fSPankaj Gupta 	if (image_id < ARRAY_SIZE(policies)) {
532b53c2c5fSPankaj Gupta 
533b53c2c5fSPankaj Gupta 		policy = &policies[image_id];
534b53c2c5fSPankaj Gupta 		result = policy->check(policy->image_spec);
535b53c2c5fSPankaj Gupta 		if (result == 0) {
536b53c2c5fSPankaj Gupta 			*image_spec = policy->image_spec;
537b53c2c5fSPankaj Gupta 			*dev_handle = *(policy->dev_handle);
538b53c2c5fSPankaj Gupta 		}
539b53c2c5fSPankaj Gupta 	}
540b53c2c5fSPankaj Gupta #ifdef CONFIG_DDR_FIP_IMAGE
541b53c2c5fSPankaj Gupta 	else {
542b53c2c5fSPankaj Gupta 		VERBOSE("Trying alternative IO\n");
543b53c2c5fSPankaj Gupta 		result = plat_get_ddr_fip_image_source(image_id, dev_handle,
544b53c2c5fSPankaj Gupta 						image_spec, open_backend);
545b53c2c5fSPankaj Gupta 	}
546b53c2c5fSPankaj Gupta #endif
547b53c2c5fSPankaj Gupta #ifdef POLICY_FUSE_PROVISION
548b53c2c5fSPankaj Gupta 	if (result != 0) {
549b53c2c5fSPankaj Gupta 		VERBOSE("Trying FUSE IO\n");
550b53c2c5fSPankaj Gupta 		result = plat_get_fuse_image_source(image_id, dev_handle,
551b53c2c5fSPankaj Gupta 						image_spec, open_backend);
552b53c2c5fSPankaj Gupta 	}
553b53c2c5fSPankaj Gupta #endif
554b53c2c5fSPankaj Gupta 
555b53c2c5fSPankaj Gupta 	return result;
556b53c2c5fSPankaj Gupta }
557