Adding support functions to run dfu commands Signed-off-by: Ravi Babu <ravib...@ti.com> --- common/spl/Makefile | 1 + common/spl/spl_dfu.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/spl.h | 10 ++++ 3 files changed, 164 insertions(+) create mode 100644 common/spl/spl_dfu.c
diff --git a/common/spl/Makefile b/common/spl/Makefile index 2e0f695..7a34697 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -21,4 +21,5 @@ obj-$(CONFIG_SPL_USB_SUPPORT) += spl_usb.o obj-$(CONFIG_SPL_FAT_SUPPORT) += spl_fat.o obj-$(CONFIG_SPL_EXT_SUPPORT) += spl_ext.o obj-$(CONFIG_SPL_SATA_SUPPORT) += spl_sata.o +obj-$(CONFIG_SPL_DFU) += spl_dfu.o endif diff --git a/common/spl/spl_dfu.c b/common/spl/spl_dfu.c new file mode 100644 index 0000000..8b8432b --- /dev/null +++ b/common/spl/spl_dfu.c @@ -0,0 +1,153 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Ravi B <ravib...@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <dm.h> +#include <spl.h> +#include <linux/compiler.h> +#include <errno.h> +#include <asm/u-boot.h> +#include <errno.h> +#include <mmc.h> +#include <watchdog.h> +#include <console.h> +#include <g_dnl.h> +#include <usb.h> +#include <dfu.h> +#include <environment.h> + +static int run_dfu(int usb_index, char *interface, char *devstring) +{ + int ret; + + ret = dfu_init_env_entities(interface, devstring); + if (ret) + goto done; + + ret = CMD_RET_SUCCESS; + + board_usb_init(usb_index, USB_INIT_DEVICE); + g_dnl_clear_detach(); + g_dnl_register("usb_dnl_dfu"); + + while (1) { + if (ctrlc()) + goto exit; + + if (dfu_get_defer_flush()) { + /* + * Call to usb_gadget_handle_interrupts() is necessary + * to act on ZLP OUT transaction from HOST PC after + * transmitting the whole file. + * + * If this ZLP OUT packet is NAK'ed, the HOST libusb + * function fails after timeout (by default it is set to + * 5 seconds). In such situation the dfu-util program + * exits with error message. + */ + usb_gadget_handle_interrupts(usb_index); + ret = dfu_flush(dfu_get_defer_flush(), NULL, 0, 0); + dfu_set_defer_flush(NULL); + if (ret) { + error("Deferred dfu_flush() failed!"); + goto exit; + } + } + + WATCHDOG_RESET(); + usb_gadget_handle_interrupts(usb_index); + } +exit: + g_dnl_unregister(); + board_usb_cleanup(usb_index, USB_INIT_DEVICE); +done: + dfu_free_entities(); + g_dnl_clear_detach(); + + return ret; +} + +int spl_dfu_cmd(int usbctrl, char *dfu_alt_info, char *interface, char *devstr) +{ + char *str_env; + int ret; + + /* set default environment */ + set_default_env(0); + str_env = getenv(dfu_alt_info); + if (!str_env) { + error("\"dfu_alt_info\" env variable not defined!\n"); + return -EINVAL; + } + + ret = setenv("dfu_alt_info", str_env); + if (ret) { + error("unable to set env variable \"dfu_alt_info\"!\n"); + return -EINVAL; + } + + /* invoke dfu command */ + return run_dfu(usbctrl, interface, devstr); +} + +int spl_dfu_mmc(int usb_index, int mmc_dev, char *dfu_alt_info) +{ + struct mmc *mmcdev; + struct mmc **mmc = &mmcdev; + int device = mmc_dev; + int ret; + + /* initialize the mmc module */ + mmc_initialize(0); + + *mmc = find_mmc_device(device); + if (!*mmc) { + error("failed to find mmc device %d\n", device); + return -ENODEV; + } + + ret = mmc_init(*mmc); + if (ret) { + error("spl: mmc init failed with error: %d\n", ret); + return ret; + } + + return spl_dfu_cmd(usb_index, dfu_alt_info, "mmc", mmc_dev ? "1" : "0"); +} + +ulong spl_fit_ram_read(struct spl_load_info *load, ulong sector, ulong count, + void *buf) +{ + memcpy(buf, (void *)sector, count); + return count; +} + +int spl_dfu_ram_load_image(void) +{ + int err = 0; + struct image_header *header; + unsigned int addr = 0x80200000; + char *filename = (char *)addr; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + memcpy(header, filename, sizeof(struct image_header)); + + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) { + struct spl_load_info load; + debug("Found FIT\n"); + load.priv = NULL; + load.read = spl_fit_ram_read; + + err = spl_load_simple_fit(&load, (ulong)filename, header); + } else { + spl_parse_image_header(header); + } + return err; +} diff --git a/include/spl.h b/include/spl.h index af02a6d..8849678 100644 --- a/include/spl.h +++ b/include/spl.h @@ -139,4 +139,14 @@ void spl_board_init(void); */ bool spl_was_boot_source(void); +/* spl dfu functions */ +/* spl_dfu_mmc - run dfu command with chosen mmc device interface + * @param usb_index - usb controller number + * @param mmc_dev - mmc device nubmer + * + * @return 0 on success, otherwise error code + */ +int spl_dfu_mmc(int usb_index, int mmc_dev, char *dfu_alt_info); +int spl_dfu_cmd(int usbctrl, char *dfu_alt_info, char *interface, char *devstr); +int spl_dfu_ram_load_image(void); #endif -- 1.7.9.5 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot