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