1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2014
4 * Texas Instruments, <www.ti.com>
5 *
6 * Dan Murphy <dmurphy@ti.com>
7 *
8 * Derived work from spl_mmc.c
9 */
10
11#include <common.h>
12#include <log.h>
13#include <spl.h>
14#include <asm/u-boot.h>
15#include <errno.h>
16#include <usb.h>
17#include <fat.h>
18
19static int usb_stor_curr_dev = -1; /* current device */
20
21int spl_usb_load(struct spl_image_info *spl_image,
22		 struct spl_boot_device *bootdev, int partition,
23		 const char *filename)
24{
25	int err = 0;
26	struct blk_desc *stor_dev;
27	static bool usb_init_pending = true;
28
29	if (usb_init_pending) {
30		usb_stop();
31		err = usb_init();
32		usb_init_pending = false;
33	}
34
35	if (err) {
36#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
37		printf("%s: usb init failed: err - %d\n", __func__, err);
38#endif
39		return err;
40	}
41
42	/* try to recognize storage devices immediately */
43	usb_stor_curr_dev = usb_stor_scan(1);
44	stor_dev = blk_get_devnum_by_uclass_id(UCLASS_USB, usb_stor_curr_dev);
45	if (!stor_dev)
46		return -ENODEV;
47
48	debug("boot mode - FAT\n");
49
50#if CONFIG_IS_ENABLED(OS_BOOT)
51	if (spl_start_uboot() ||
52	    spl_load_image_fat_os(spl_image, bootdev, stor_dev, partition))
53#endif
54	{
55		err = spl_load_image_fat(spl_image, bootdev, stor_dev, partition, filename);
56	}
57
58	if (err) {
59		puts("Error loading from USB device\n");
60		return err;
61	}
62
63	return 0;
64}
65
66static int spl_usb_load_image(struct spl_image_info *spl_image,
67			      struct spl_boot_device *bootdev)
68{
69	return spl_usb_load(spl_image, bootdev,
70			    CONFIG_SYS_USB_FAT_BOOT_PARTITION,
71			    CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
72}
73SPL_LOAD_IMAGE_METHOD("USB", 0, BOOT_DEVICE_USB, spl_usb_load_image);
74