/*
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/* #define	DEBUG	*/

#include <common.h>
#include <autoboot.h>
#include <cli.h>
#include <console.h>
#include <version.h>
#include <fdtdec.h>
#include <asm/arch-qca-common/smem.h>

DECLARE_GLOBAL_DATA_PTR;

extern int usb_max_dev_avail(void);
extern block_dev_desc_t *usb_stor_get_dev(int index);

/*
 * Board-specific Platform code can reimplement show_boot_progress () if needed
 */
__weak void show_boot_progress(int val) {}

static void modem_init(void)
{
#ifdef CONFIG_MODEM_SUPPORT
	debug("DEBUG: main_loop:   gd->do_mdm_init=%lu\n", gd->do_mdm_init);
	if (gd->do_mdm_init) {
		char *str = getenv("mdm_cmd");

		setenv("preboot", str);  /* set or delete definition */
		mdm_init(); /* wait for modem connection */
	}
#endif  /* CONFIG_MODEM_SUPPORT */
}

static void run_preboot_environment_command(void)
{
#ifdef CONFIG_PREBOOT
	char *p;

	p = getenv("preboot");
	if (p != NULL) {
# ifdef CONFIG_AUTOBOOT_KEYED
		int prev = disable_ctrlc(1);	/* disable Control C checking */
# endif

		run_command_list(p, -1, 0);

# ifdef CONFIG_AUTOBOOT_KEYED
		disable_ctrlc(prev);	/* restore Control C checking */
# endif
	}
#endif /* CONFIG_PREBOOT */
}

static bool is_production_board(void)
{
    bool ret = true;

#if defined(BOARD_NAME)
    if (strcmp(BOARD_NAME, "sirocco-b4"))
        ret = false;
#endif
    return ret;
}

/* We come here after U-Boot is initialised and ready to process commands */
void main_loop(void)
{
	const char *s;
	const char *image;
	const void *blob = gd->fdt_blob;
	char runcmd[128] = {0};
	int node;
	int gpio;
	int ret;
	int nusb;
        int storage_found = 0;

	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");

#ifndef CONFIG_SYS_GENERIC_BOARD
	puts("Warning: Your board does not use generic board. Please read\n");
	puts("doc/README.generic-board and take action. Boards not\n");
	puts("upgraded by the late 2014 may break or be removed.\n");
#endif

	modem_init();
#ifdef CONFIG_VERSION_VARIABLE
	setenv("ver", version_string);  /* set version variable */
#endif /* CONFIG_VERSION_VARIABLE */

	cli_init();

	run_preboot_environment_command();

#if defined(CONFIG_UPDATE_TFTP)
	update_tftp(0UL, NULL, NULL);
#endif /* CONFIG_UPDATE_TFTP */

	s = bootdelay_process();
	if (cli_process_fdt(&s))
		cli_secure_boot_cmd(s);

	node = fdt_path_offset(blob, "/boot_mode");
	if (node >= 0) {
		qca_gpio_init(node);
		gpio = fdtdec_get_int(blob, node, "ngpio", 0);
		if (gpio >= 0) {
			ret = gpio_get_value(gpio);
			if (ret) {
				ret = run_command("usb start", 0);
				if (ret == CMD_RET_SUCCESS) {
					nusb = usb_max_dev_avail();
					while(nusb >= 0) {
						storage_found = usb_stor_get_dev(nusb)
								? 1 : 0;
						if (storage_found)
							break;
						--nusb;
					}
				}

				if (storage_found) {
					image = fdt_getprop(blob, node, "image",
									NULL);
					if (!image) {
						debug("node %s has no image\n",
						fdt_get_name(blob, node, NULL));
					}

					snprintf(runcmd, sizeof(runcmd),
						"bootipq usb %d %s", nusb, image);
					s = runcmd;
                                        /* clear autoboot delay if boot from USB
                                         * stick */
                                        clear_bootdelay();
				} else if (!is_production_board()) {
					snprintf(runcmd, sizeof(runcmd),
						"usb stop; fastboot %d", nusb);
					run_command(runcmd, 0);
                                }
			}
		}
	}

        if (is_production_board()) {
              /* clear autoboot delay for production build */
              clear_bootdelay();
        }

	autoboot_command(s);

	/* don't enter console as a fallback */
	/* uncomment only for developing */
	/*cli_loop();*/
}
