xref: /rk3399_ARM-atf/plat/st/common/bl2_io_storage.c (revision 35efe7a4cea4b3c55b661aac49ef1a85ca8feaa9)
1 /*
2  * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <string.h>
9 
10 #include <arch_helpers.h>
11 #include <common/debug.h>
12 #include <common/desc_image_load.h>
13 #include <drivers/io/io_block.h>
14 #include <drivers/io/io_driver.h>
15 #include <drivers/io/io_fip.h>
16 #include <drivers/io/io_mtd.h>
17 #include <drivers/io/io_storage.h>
18 #include <drivers/mmc.h>
19 #include <drivers/partition/partition.h>
20 #include <drivers/raw_nand.h>
21 #include <drivers/spi_nand.h>
22 #include <drivers/spi_nor.h>
23 #include <drivers/st/io_mmc.h>
24 #include <drivers/st/stm32_fmc2_nand.h>
25 #include <drivers/st/stm32_qspi.h>
26 #include <drivers/st/stm32_sdmmc2.h>
27 #include <lib/fconf/fconf.h>
28 #include <lib/mmio.h>
29 #include <lib/utils.h>
30 #include <plat/common/platform.h>
31 #include <tools_share/firmware_image_package.h>
32 
33 #include <platform_def.h>
34 #include <stm32mp_fconf_getter.h>
35 
36 /* IO devices */
37 uintptr_t fip_dev_handle;
38 uintptr_t storage_dev_handle;
39 
40 static const io_dev_connector_t *fip_dev_con;
41 
42 #if STM32MP_SDMMC || STM32MP_EMMC
43 static struct mmc_device_info mmc_info;
44 
45 static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
46 
47 static io_block_dev_spec_t mmc_block_dev_spec = {
48 	/* It's used as temp buffer in block driver */
49 	.buffer = {
50 		.offset = (size_t)&block_buffer,
51 		.length = MMC_BLOCK_SIZE,
52 	},
53 	.ops = {
54 		.read = mmc_read_blocks,
55 		.write = NULL,
56 	},
57 	.block_size = MMC_BLOCK_SIZE,
58 };
59 
60 static const io_dev_connector_t *mmc_dev_con;
61 #endif /* STM32MP_SDMMC || STM32MP_EMMC */
62 
63 #if STM32MP_SPI_NOR
64 static io_mtd_dev_spec_t spi_nor_dev_spec = {
65 	.ops = {
66 		.init = spi_nor_init,
67 		.read = spi_nor_read,
68 	},
69 };
70 #endif
71 
72 #if STM32MP_RAW_NAND
73 static io_mtd_dev_spec_t nand_dev_spec = {
74 	.ops = {
75 		.init = nand_raw_init,
76 		.read = nand_read,
77 		.seek = nand_seek_bb
78 	},
79 };
80 
81 static const io_dev_connector_t *nand_dev_con;
82 #endif
83 
84 #if STM32MP_SPI_NAND
85 static io_mtd_dev_spec_t spi_nand_dev_spec = {
86 	.ops = {
87 		.init = spi_nand_init,
88 		.read = nand_read,
89 		.seek = nand_seek_bb
90 	},
91 };
92 #endif
93 
94 #if STM32MP_SPI_NAND || STM32MP_SPI_NOR
95 static const io_dev_connector_t *spi_dev_con;
96 #endif
97 
98 io_block_spec_t image_block_spec = {
99 	.offset = 0U,
100 	.length = 0U,
101 };
102 
103 int open_fip(const uintptr_t spec)
104 {
105 	return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
106 }
107 
108 int open_storage(const uintptr_t spec)
109 {
110 	return io_dev_init(storage_dev_handle, 0);
111 }
112 
113 static void print_boot_device(boot_api_context_t *boot_context)
114 {
115 	switch (boot_context->boot_interface_selected) {
116 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
117 		INFO("Using SDMMC\n");
118 		break;
119 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
120 		INFO("Using EMMC\n");
121 		break;
122 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
123 		INFO("Using QSPI NOR\n");
124 		break;
125 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
126 		INFO("Using FMC NAND\n");
127 		break;
128 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
129 		INFO("Using SPI NAND\n");
130 		break;
131 	default:
132 		ERROR("Boot interface %u not found\n",
133 		      boot_context->boot_interface_selected);
134 		panic();
135 		break;
136 	}
137 
138 	if (boot_context->boot_interface_instance != 0U) {
139 		INFO("  Instance %d\n", boot_context->boot_interface_instance);
140 	}
141 }
142 
143 #if STM32MP_SDMMC || STM32MP_EMMC
144 static void boot_mmc(enum mmc_device_type mmc_dev_type,
145 		     uint16_t boot_interface_instance)
146 {
147 	int io_result __unused;
148 	struct stm32_sdmmc2_params params;
149 
150 	zeromem(&params, sizeof(struct stm32_sdmmc2_params));
151 
152 	mmc_info.mmc_dev_type = mmc_dev_type;
153 
154 	switch (boot_interface_instance) {
155 	case 1:
156 		params.reg_base = STM32MP_SDMMC1_BASE;
157 		break;
158 	case 2:
159 		params.reg_base = STM32MP_SDMMC2_BASE;
160 		break;
161 	case 3:
162 		params.reg_base = STM32MP_SDMMC3_BASE;
163 		break;
164 	default:
165 		WARN("SDMMC instance not found, using default\n");
166 		if (mmc_dev_type == MMC_IS_SD) {
167 			params.reg_base = STM32MP_SDMMC1_BASE;
168 		} else {
169 			params.reg_base = STM32MP_SDMMC2_BASE;
170 		}
171 		break;
172 	}
173 
174 	params.device_info = &mmc_info;
175 	if (stm32_sdmmc2_mmc_init(&params) != 0) {
176 		ERROR("SDMMC%u init failed\n", boot_interface_instance);
177 		panic();
178 	}
179 
180 	/* Open MMC as a block device to read GPT table */
181 	io_result = register_io_dev_block(&mmc_dev_con);
182 	if (io_result != 0) {
183 		panic();
184 	}
185 
186 	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
187 				&storage_dev_handle);
188 	assert(io_result == 0);
189 }
190 #endif /* STM32MP_SDMMC || STM32MP_EMMC */
191 
192 #if STM32MP_SPI_NOR
193 static void boot_spi_nor(boot_api_context_t *boot_context)
194 {
195 	int io_result __unused;
196 
197 	io_result = stm32_qspi_init();
198 	assert(io_result == 0);
199 
200 	io_result = register_io_dev_mtd(&spi_dev_con);
201 	assert(io_result == 0);
202 
203 	/* Open connections to device */
204 	io_result = io_dev_open(spi_dev_con,
205 				(uintptr_t)&spi_nor_dev_spec,
206 				&storage_dev_handle);
207 	assert(io_result == 0);
208 }
209 #endif /* STM32MP_SPI_NOR */
210 
211 #if STM32MP_RAW_NAND
212 static void boot_fmc2_nand(boot_api_context_t *boot_context)
213 {
214 	int io_result __unused;
215 
216 	io_result = stm32_fmc2_init();
217 	assert(io_result == 0);
218 
219 	/* Register the IO device on this platform */
220 	io_result = register_io_dev_mtd(&nand_dev_con);
221 	assert(io_result == 0);
222 
223 	/* Open connections to device */
224 	io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
225 				&storage_dev_handle);
226 	assert(io_result == 0);
227 }
228 #endif /* STM32MP_RAW_NAND */
229 
230 #if STM32MP_SPI_NAND
231 static void boot_spi_nand(boot_api_context_t *boot_context)
232 {
233 	int io_result __unused;
234 
235 	io_result = stm32_qspi_init();
236 	assert(io_result == 0);
237 
238 	io_result = register_io_dev_mtd(&spi_dev_con);
239 	assert(io_result == 0);
240 
241 	/* Open connections to device */
242 	io_result = io_dev_open(spi_dev_con,
243 				(uintptr_t)&spi_nand_dev_spec,
244 				&storage_dev_handle);
245 	assert(io_result == 0);
246 }
247 #endif /* STM32MP_SPI_NAND */
248 
249 void stm32mp_io_setup(void)
250 {
251 	int io_result __unused;
252 	boot_api_context_t *boot_context =
253 		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
254 
255 	print_boot_device(boot_context);
256 
257 	if ((boot_context->boot_partition_used_toboot == 1U) ||
258 	    (boot_context->boot_partition_used_toboot == 2U)) {
259 		INFO("Boot used partition fsbl%u\n",
260 		     boot_context->boot_partition_used_toboot);
261 	}
262 
263 	io_result = register_io_dev_fip(&fip_dev_con);
264 	assert(io_result == 0);
265 
266 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
267 				&fip_dev_handle);
268 
269 	switch (boot_context->boot_interface_selected) {
270 #if STM32MP_SDMMC
271 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
272 		dmbsy();
273 		boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
274 		break;
275 #endif
276 #if STM32MP_EMMC
277 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
278 		dmbsy();
279 		boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
280 		break;
281 #endif
282 #if STM32MP_SPI_NOR
283 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
284 		dmbsy();
285 		boot_spi_nor(boot_context);
286 		break;
287 #endif
288 #if STM32MP_RAW_NAND
289 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
290 		dmbsy();
291 		boot_fmc2_nand(boot_context);
292 		break;
293 #endif
294 #if STM32MP_SPI_NAND
295 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
296 		dmbsy();
297 		boot_spi_nand(boot_context);
298 		break;
299 #endif
300 
301 	default:
302 		ERROR("Boot interface %d not supported\n",
303 		      boot_context->boot_interface_selected);
304 		panic();
305 		break;
306 	}
307 }
308 
309 int bl2_plat_handle_pre_image_load(unsigned int image_id)
310 {
311 	static bool gpt_init_done __unused;
312 	uint16_t boot_itf = stm32mp_get_boot_itf_selected();
313 
314 	switch (boot_itf) {
315 #if STM32MP_SDMMC || STM32MP_EMMC
316 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
317 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
318 		if (!gpt_init_done) {
319 			const partition_entry_t *entry;
320 
321 			partition_init(GPT_IMAGE_ID);
322 			entry = get_partition_entry(FIP_IMAGE_NAME);
323 			if (entry == NULL) {
324 				ERROR("Could NOT find the %s partition!\n",
325 				      FIP_IMAGE_NAME);
326 				return -ENOENT;
327 			}
328 
329 			image_block_spec.offset = entry->start;
330 			image_block_spec.length = entry->length;
331 
332 			gpt_init_done = true;
333 		} else {
334 			bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
335 
336 			mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base;
337 			mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size;
338 		}
339 
340 		break;
341 #endif
342 
343 #if STM32MP_RAW_NAND || STM32MP_SPI_NAND
344 #if STM32MP_RAW_NAND
345 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
346 #endif
347 #if STM32MP_SPI_NAND
348 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
349 #endif
350 		image_block_spec.offset = STM32MP_NAND_FIP_OFFSET;
351 		break;
352 #endif
353 
354 #if STM32MP_SPI_NOR
355 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
356 		image_block_spec.offset = STM32MP_NOR_FIP_OFFSET;
357 		break;
358 #endif
359 
360 	default:
361 		ERROR("FIP Not found\n");
362 		panic();
363 	}
364 
365 	return 0;
366 }
367 
368 /*
369  * Return an IO device handle and specification which can be used to access
370  * an image. Use this to enforce platform load policy.
371  */
372 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
373 			  uintptr_t *image_spec)
374 {
375 	int rc;
376 	const struct plat_io_policy *policy;
377 
378 	policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id);
379 	rc = policy->check(policy->image_spec);
380 	if (rc == 0) {
381 		*image_spec = policy->image_spec;
382 		*dev_handle = *(policy->dev_handle);
383 	}
384 
385 	return rc;
386 }
387