/*
 * (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") && strcmp(BOARD_NAME, "brezza-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();*/
}
