/*
 * Copyright (C) 2009 Texas Instruments Incorporated
 *
 * Copyright (C) 2011
 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <common.h>
#include <errno.h>
#include <hush.h>
#include <linux/mtd/nand.h>
#include <nand.h>
#include <miiphy.h>
#include <netdev.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <asm/arch/nand_defs.h>
#include <asm/arch/davinci_misc.h>
#ifdef CONFIG_DAVINCI_MMC
#include <mmc.h>
#include <asm/arch/sdmmc_defs.h>
#endif

DECLARE_GLOBAL_DATA_PTR;

#ifndef CONFIG_SPL_BUILD
static struct davinci_timer *timer =
	(struct davinci_timer *)DAVINCI_TIMER3_BASE;

static unsigned long get_timer_val(void)
{
	unsigned long now = readl(&timer->tim34);

	return now;
}

static int timer_running(void)
{
	return readl(&timer->tcr) &
		(DV_TIMER_TCR_ENAMODE_MASK << DV_TIMER_TCR_ENAMODE34_SHIFT);
}

static void stop_timer(void)
{
	writel(0x0, &timer->tcr);
	return;
}

int checkboard(void)
{
	printf("Board: AIT CAM ENC 4XX\n");
	return 0;
}

int board_init(void)
{
	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;

	return 0;
}

#ifdef CONFIG_DRIVER_TI_EMAC
static int cam_enc_4xx_check_network(void)
{
	char *s;

	s = getenv("ethaddr");
	if (!s)
		return -EINVAL;

	if (!is_valid_ether_addr((const u8 *)s))
		return -EINVAL;

	s = getenv("ipaddr");
	if (!s)
		return -EINVAL;

	s = getenv("netmask");
	if (!s)
		return -EINVAL;

	s = getenv("serverip");
	if (!s)
		return -EINVAL;

	s = getenv("gatewayip");
	if (!s)
		return -EINVAL;

	return 0;
}
int board_eth_init(bd_t *bis)
{
	int ret;

	ret = cam_enc_4xx_check_network();
	if (ret)
		return ret;

	davinci_emac_initialize();

	return 0;
}
#endif

#ifdef CONFIG_NAND_DAVINCI
static int
davinci_std_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
				   uint8_t *buf, int page)
{
	struct nand_chip *this = mtd->priv;
	int i, eccsize = chip->ecc.size;
	int eccbytes = chip->ecc.bytes;
	int eccsteps = chip->ecc.steps;
	uint8_t *p = buf;
	uint8_t *oob = chip->oob_poi;

	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);

	chip->read_buf(mtd, oob, mtd->oobsize);

	chip->cmdfunc(mtd, NAND_CMD_READ0, 0x0, page & this->pagemask);


	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
		int stat;

		chip->ecc.hwctl(mtd, NAND_ECC_READ);
		chip->read_buf(mtd, p, eccsize);
		chip->ecc.hwctl(mtd, NAND_ECC_READSYN);

		if (chip->ecc.prepad)
			oob += chip->ecc.prepad;

		stat = chip->ecc.correct(mtd, p, oob, NULL);

		if (stat == -1)
			mtd->ecc_stats.failed++;
		else
			mtd->ecc_stats.corrected += stat;

		oob += eccbytes;

		if (chip->ecc.postpad)
			oob += chip->ecc.postpad;
	}

	/* Calculate remaining oob bytes */
	i = mtd->oobsize - (oob - chip->oob_poi);
	if (i)
		chip->read_buf(mtd, oob, i);

	return 0;
}

static void davinci_std_write_page_syndrome(struct mtd_info *mtd,
				    struct nand_chip *chip, const uint8_t *buf)
{
	unsigned char davinci_ecc_buf[NAND_MAX_OOBSIZE];
	struct nand_chip *this = mtd->priv;
	int i, eccsize = chip->ecc.size;
	int eccbytes = chip->ecc.bytes;
	int eccsteps = chip->ecc.steps;
	int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
	int offset = 0;
	const uint8_t *p = buf;
	uint8_t *oob = chip->oob_poi;

	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
		chip->write_buf(mtd, p, eccsize);

		/* Calculate ECC without prepad */
		chip->ecc.calculate(mtd, p, oob + chip->ecc.prepad);

		if (chip->ecc.prepad) {
			offset = (chip->ecc.steps - eccsteps) * chunk;
			memcpy(&davinci_ecc_buf[offset], oob, chip->ecc.prepad);
			oob += chip->ecc.prepad;
		}

		offset = ((chip->ecc.steps - eccsteps) * chunk) +
				chip->ecc.prepad;
		memcpy(&davinci_ecc_buf[offset], oob, eccbytes);
		oob += eccbytes;

		if (chip->ecc.postpad) {
			offset = ((chip->ecc.steps - eccsteps) * chunk) +
					chip->ecc.prepad + eccbytes;
			memcpy(&davinci_ecc_buf[offset], oob,
				chip->ecc.postpad);
			oob += chip->ecc.postpad;
		}
	}

	/*
	 * Write the sparebytes into the page once
	 * all eccsteps have been covered
	 */
	for (i = 0; i < mtd->oobsize; i++)
		writeb(davinci_ecc_buf[i], this->IO_ADDR_W);

	/* Calculate remaining oob bytes */
	i = mtd->oobsize - (oob - chip->oob_poi);
	if (i)
		chip->write_buf(mtd, oob, i);
}

static int davinci_std_write_oob_syndrome(struct mtd_info *mtd,
				   struct nand_chip *chip, int page)
{
	int pos, status = 0;
	const uint8_t *bufpoi = chip->oob_poi;

	pos = mtd->writesize;

	chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page);

	chip->write_buf(mtd, bufpoi, mtd->oobsize);

	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
	status = chip->waitfunc(mtd, chip);

	return status & NAND_STATUS_FAIL ? -1 : 0;
}

static int davinci_std_read_oob_syndrome(struct mtd_info *mtd,
	struct nand_chip *chip, int page, int sndcmd)
{
	struct nand_chip *this = mtd->priv;
	uint8_t *buf = chip->oob_poi;
	uint8_t *bufpoi = buf;

	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);

	chip->read_buf(mtd, bufpoi, mtd->oobsize);

	return 1;
}

static void nand_dm365evm_select_chip(struct mtd_info *mtd, int chip)
{
	struct nand_chip	*this = mtd->priv;
	unsigned long		wbase = (unsigned long) this->IO_ADDR_W;
	unsigned long		rbase = (unsigned long) this->IO_ADDR_R;

	if (chip == 1) {
		__set_bit(14, &wbase);
		__set_bit(14, &rbase);
	} else {
		__clear_bit(14, &wbase);
		__clear_bit(14, &rbase);
	}
	this->IO_ADDR_W = (void *)wbase;
	this->IO_ADDR_R = (void *)rbase;
}

int board_nand_init(struct nand_chip *nand)
{
	davinci_nand_init(nand);
	nand->select_chip = nand_dm365evm_select_chip;

	return 0;
}

struct nand_ecc_ctrl org_ecc;
static int notsaved = 1;

static int nand_switch_hw_func(int mode)
{
	struct nand_chip *nand;
	struct mtd_info *mtd;

	if (nand_curr_device < 0 ||
	    nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
	    !nand_info[nand_curr_device].name) {
		printf("Error: Can't switch hw functions," \
			" no devices available\n");
		return -1;
	}

	mtd = &nand_info[nand_curr_device];
	nand = mtd->priv;

	if (mode == 0) {
		if (notsaved == 0) {
			printf("switching to uboot hw functions.\n");
			memcpy(&nand->ecc, &org_ecc,
				sizeof(struct nand_ecc_ctrl));
		}
	} else {
		/* RBL */
		printf("switching to RBL hw functions.\n");
		if (notsaved == 1) {
			memcpy(&org_ecc, &nand->ecc,
				sizeof(struct nand_ecc_ctrl));
			notsaved = 0;
		}
		nand->ecc.mode = NAND_ECC_HW_SYNDROME;
		nand->ecc.prepad = 6;
		nand->ecc.read_page = davinci_std_read_page_syndrome;
		nand->ecc.write_page = davinci_std_write_page_syndrome;
		nand->ecc.read_oob = davinci_std_read_oob_syndrome;
		nand->ecc.write_oob = davinci_std_write_oob_syndrome;
	}
	return mode;
}

static int hwmode;

static int do_switch_ecc(cmd_tbl_t *cmdtp, int flag, int argc,
		char *const argv[])
{
	if (argc != 2)
		goto usage;
	if (strncmp(argv[1], "rbl", 2) == 0)
		hwmode = nand_switch_hw_func(1);
	else if (strncmp(argv[1], "uboot", 2) == 0)
		hwmode = nand_switch_hw_func(0);
	else
		goto usage;

	return 0;

usage:
	printf("Usage: nandrbl %s\n", cmdtp->usage);
	return 1;
}

U_BOOT_CMD(
	nandrbl, 2, 1,	do_switch_ecc,
	"switch between rbl/uboot NAND ECC calculation algorithm",
	"[rbl/uboot] - Switch between rbl/uboot NAND ECC algorithm"
);


#endif /* #ifdef CONFIG_NAND_DAVINCI */

#ifdef CONFIG_DAVINCI_MMC
static struct davinci_mmc mmc_sd0 = {
	.reg_base	= (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE,
	.input_clk	= 121500000,
	.host_caps	= MMC_MODE_4BIT,
	.voltages	= MMC_VDD_32_33 | MMC_VDD_33_34,
	.version	= MMC_CTLR_VERSION_2,
};

int board_mmc_init(bd_t *bis)
{
	int err;

	/* Add slot-0 to mmc subsystem */
	err = davinci_mmc_init(bis, &mmc_sd0);

	return err;
}
#endif

int board_late_init(void)
{
	struct davinci_gpio *gpio = davinci_gpio_bank45;

	/* 24MHz InputClock / 15 prediv -> 1.6 MHz timer running */
	while ((get_timer_val() < CONFIG_AIT_TIMER_TIMEOUT) &&
		timer_running())
		;

	/* 1 sec reached -> stop timer, clear all LED */
	stop_timer();
	clrbits_le32(&gpio->out_data, CONFIG_CAM_ENC_LED_MASK);
	return 0;
}

void reset_phy(void)
{
	char *name = "GENERIC @ 0x00";

	/* reset the phy */
	miiphy_reset(name, 0x0);
}

#else /* #ifndef CONFIG_SPL_BUILD */
static void cam_enc_4xx_set_all_led(void)
{
	struct davinci_gpio *gpio = davinci_gpio_bank45;

	setbits_le32(&gpio->out_data, CONFIG_CAM_ENC_LED_MASK);
}

/*
 * TIMER 0 is used for tick
 */
static struct davinci_timer *timer =
	(struct davinci_timer *)DAVINCI_TIMER3_BASE;

#define TIMER_LOAD_VAL	0xffffffff
#define TIM_CLK_DIV	16

static int cam_enc_4xx_timer_init(void)
{
	/* We are using timer34 in unchained 32-bit mode, full speed */
	writel(0x0, &timer->tcr);
	writel(0x0, &timer->tgcr);
	writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr);
	writel(0x0, &timer->tim34);
	writel(TIMER_LOAD_VAL, &timer->prd34);
	writel(2 << 22, &timer->tcr);
	return 0;
}

void board_gpio_init(void)
{
	struct davinci_gpio *gpio;

	cam_enc_4xx_set_all_led();
	cam_enc_4xx_timer_init();
	gpio = davinci_gpio_bank01;
	clrbits_le32(&gpio->dir, ~0xfdfffffe);
	/* clear LED D14 = GPIO25 */
	clrbits_le32(&gpio->out_data, 0x02000000);
	gpio = davinci_gpio_bank23;
	clrbits_le32(&gpio->dir, ~0x5ff0afef);
	/* set GPIO61 to 1 -> intern UART0 as Console */
	setbits_le32(&gpio->out_data, 0x20000000);
	/*
	 * PHY out of reset GIO 50 = 1
	 * NAND WP off GIO 51 = 1
	 */
	setbits_le32(&gpio->out_data, 0x000c0004);
	gpio = davinci_gpio_bank45;
	clrbits_le32(&gpio->dir, ~(0xdb2fffff) | CONFIG_CAM_ENC_LED_MASK);
	/*
	 * clear LED:
	 * D17 = GPIO86
	 * D11 = GPIO87
	 * GPIO88
	 * GPIO89
	 * D13 = GPIO90
	 * GPIO91
	 */
	clrbits_le32(&gpio->out_data, CONFIG_CAM_ENC_LED_MASK);
	gpio = davinci_gpio_bank67;
	clrbits_le32(&gpio->dir, ~0x000007ff);
}

/*
 * functions for the post memory test.
 */
int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
{
	*vstart = CONFIG_SYS_SDRAM_BASE;
	*size = PHYS_SDRAM_1_SIZE;
	*phys_offset = 0;
	return 0;
}

void arch_memory_failure_handle(void)
{
	cam_enc_4xx_set_all_led();
	puts("mem failure\n");
	while (1)
		;
}
#endif
#if defined(CONFIG_MENU)
#include "menu.h"

#define MENU_EXIT		-1
#define MENU_EXIT_BOOTCMD	-2
#define MENU_STAY		0
#define MENU_MAIN		1
#define MENU_UPDATE		2
#define MENU_NETWORK		3
#define MENU_LOAD		4

static int menu_start;

#define FIT_SUBTYPE_UNKNOWN		0
#define FIT_SUBTYPE_UBL_HEADER		1
#define FIT_SUBTYPE_SPL_IMAGE		2
#define FIT_SUBTYPE_UBOOT_IMAGE		3
#define FIT_SUBTYPE_DF_ENV_IMAGE	4
#define FIT_SUBTYPE_RAMDISK_IMAGE	5

struct fit_images_info {
	u_int8_t type;
	int subtype;
	char desc[200];
	const void *data;
	size_t size;
};

static struct fit_images_info imgs[10];

struct menu_display {
	char	title[50];
	int	timeout; /* in sec */
	int	id; /* MENU_* */
	char	**menulist;
	int (*menu_evaluate)(char *choice);
};

char *menu_main[] = {
	"(1) Boot",
	"(2) Update Software",
	"(3) Reset to default setting and boot",
	"(4) Enter U-Boot console",
	NULL
};

char *menu_update[] = {
	"(1) Network settings",
	"(2) load image",
	"(3) back to main",
	NULL
};

char *menu_load[] = {
	"(1) install image",
	"(2) cancel",
	NULL
};

char *menu_network[] = {
	"(1) ipaddr   ",
	"(2) netmask  ",
	"(3) serverip ",
	"(4) gatewayip",
	"(5) tftp image name",
	"(6) back to update software",
	NULL
};

static void ait_menu_print(void *data)
{
	printf("%s\n", (char *)data);
	return;
}

static char *menu_handle(struct menu_display *display)
{
	struct menu *m;
	int i;
	void *choice = NULL;
	char key[2];
	int ret;
	char *s;
	char temp[6][200];

	m = menu_create(display->title, display->timeout, 1, ait_menu_print);

	for (i = 0; display->menulist[i]; i++) {
		sprintf(key, "%d", i + 1);
		if (display->id == MENU_NETWORK) {
			switch (i) {
			case 0:
				s = getenv("ipaddr");
				break;
			case 1:
				s = getenv("netmask");
				break;
			case 2:
				s = getenv("serverip");
				break;
			case 3:
				s = getenv("gatewayip");
				break;
			case 4:
				s = getenv("img_file");
				break;
			default:
				s = NULL;
				break;
			}
			if (s) {
				sprintf(temp[i], "%s: %s",
					display->menulist[i], s);
				ret = menu_item_add(m, key, temp[i]);
			} else {
				ret = menu_item_add(m, key,
					display->menulist[i]);
			}
		} else {
			ret = menu_item_add(m, key, display->menulist[i]);
		}

		if (ret != 1) {
			printf("failed to add item!");
			menu_destroy(m);
			return NULL;
		}
	}
	sprintf(key, "%d", 1);
	menu_default_set(m, key);

	if (menu_get_choice(m, &choice) != 1)
		debug("Problem picking a choice!\n");

	menu_destroy(m);

	return choice;
}

static int ait_menu_show(struct menu_display *display, int bootdelay)
{
	int end = MENU_STAY;
	char *choice;

	if ((menu_start == 0) && (display->id == MENU_MAIN))
		display->timeout = bootdelay;
	else
		display->timeout = 0;

	while (end == MENU_STAY) {
		choice = menu_handle(display);
		if (choice)
			end = display->menu_evaluate(choice);

		if (end == display->id)
			end = MENU_STAY;
		if (display->id == MENU_MAIN) {
			if (menu_start == 0)
				end = MENU_EXIT_BOOTCMD;
			else
				display->timeout = 0;
		}
	}
	return end;
}

static int ait_writeublheader(void)
{
	char s[20];
	unsigned long i;
	int ret;

	for (i = CONFIG_SYS_NAND_BLOCK_SIZE;
		i < CONFIG_SYS_NAND_U_BOOT_OFFS;
		i += CONFIG_SYS_NAND_BLOCK_SIZE) {
		sprintf(s, "%lx", i);
		ret = setenv("header_addr", s);
		if (ret == 0)
			ret = run_command("run img_writeheader", 0);
		if (ret != 0)
			break;
	}
	return ret;
}

static int ait_menu_install_images(void)
{
	int ret = 0;
	int count = 0;
	char s[100];
	char *t;

	/*
	 * possible image types:
	 * FIT_SUBTYPE_UNKNOWN
	 * FIT_SUBTYPE_UBL_HEADER
	 * FIT_SUBTYPE_SPL_IMAGE
	 * FIT_SUBTYPE_UBOOT_IMAGE
	 * FIT_SUBTYPE_DF_ENV_IMAGE
	 * FIT_SUBTYPE_RAMDISK_IMAGE
	 *
	 * use Envvariables:
	 * img_addr_r: image start addr
	 * header_addr: addr where to write to UBL header
	 * img_writeheader: write ubl header to nand
	 * img_writespl: write spl to nand
	 * img_writeuboot: write uboot to nand
	 * img_writedfenv: write default environment to ubi volume
	 * img_volume: which ubi volume should be updated with img_writeramdisk
	 * filesize: size of data for updating ubi volume
	 * img_writeramdisk: write ramdisk to ubi volume
	 */

	while (imgs[count].type != IH_TYPE_INVALID) {
		printf("Installing %s\n",
			genimg_get_type_name(imgs[count].type));
		sprintf(s, "%p", imgs[count].data);
		setenv("img_addr_r", s);
		sprintf(s, "%lx", (unsigned long)imgs[count].size);
		setenv("filesize", s);
		switch (imgs[count].subtype) {
		case FIT_SUBTYPE_DF_ENV_IMAGE:
			ret = run_command("run img_writedfenv", 0);
			break;
		case FIT_SUBTYPE_RAMDISK_IMAGE:
			t = getenv("img_volume");
			if (!t) {
				ret = setenv("img_volume", "rootfs1");
			} else {
				/* switch to other volume */
				if (strncmp(t, "rootfs1", 7) == 0)
					ret = setenv("img_volume", "rootfs2");
				else
					ret = setenv("img_volume", "rootfs1");
			}
			if (ret != 0)
				break;

			ret = run_command("run img_writeramdisk", 0);
			break;
		case FIT_SUBTYPE_SPL_IMAGE:
			ret = run_command("run img_writespl", 0);
			break;
		case FIT_SUBTYPE_UBL_HEADER:
			ret = ait_writeublheader();
			break;
		case FIT_SUBTYPE_UBOOT_IMAGE:
			ret = run_command("run img_writeuboot", 0);
			break;
		default:
			/* not supported type */
			break;
		}
		count++;
	}
	/* now save dvn_* and img_volume env vars to new values */
	if (ret == 0) {
		t = getenv("x_dvn_boot_vers");
		if (t)
			setenv("dvn_boot_vers", t);

		t = getenv("x_dvn_app_vers");
		if (t)
			setenv("dvn_boot_vers", t);

		setenv("x_dvn_boot_vers", NULL);
		setenv("x_dvn_app_vers", NULL);
		ret = run_command("run savenewvers", 0);
	}

	return ret;
}

static int ait_menu_evaluate_load(char *choice)
{
	if (!choice)
		return -1;

	switch (choice[1]) {
	case '1':
		/* install image */
		ait_menu_install_images();
		break;
	case '2':
		/* cancel, back to main */
		setenv("x_dvn_boot_vers", NULL);
		setenv("x_dvn_app_vers", NULL);
		break;
	}

	return MENU_MAIN;
}

struct menu_display ait_load = {
	.title = "AIT load image",
	.timeout = 0,
	.id = MENU_LOAD,
	.menulist = menu_load,
	.menu_evaluate = ait_menu_evaluate_load,
};

static void ait_menu_read_env(char *name)
{
	char output[CONFIG_SYS_CBSIZE];
	char cbuf[CONFIG_SYS_CBSIZE];
	int readret;
	int ret;

	sprintf(output, "%s old: %s value: ", name, getenv(name));
	memset(cbuf, 0, CONFIG_SYS_CBSIZE);
	readret = readline_into_buffer(output, cbuf, 0);

	if (readret >= 0) {
		ret = setenv(name, cbuf);
		if (ret) {
			printf("Error setting %s\n", name);
			return;
		}
	}
	return;
}

static int ait_menu_evaluate_network(char *choice)
{
	if (!choice)
		return MENU_MAIN;

	switch (choice[1]) {
	case '1':
		ait_menu_read_env("ipaddr");
		break;
	case '2':
		ait_menu_read_env("netmask");
		break;
	case '3':
		ait_menu_read_env("serverip");
		break;
	case '4':
		ait_menu_read_env("gatewayip");
		break;
	case '5':
		ait_menu_read_env("img_file");
		break;
	case '6':
		return MENU_UPDATE;
		break;
	}

	return MENU_STAY;
}

struct menu_display ait_network = {
	.title = "AIT network settings",
	.timeout = 0,
	.id = MENU_NETWORK,
	.menulist = menu_network,
	.menu_evaluate = ait_menu_evaluate_network,
};

static int fit_get_subtype(const void *fit, int noffset, char **subtype)
{
	int len;

	*subtype = (char *)fdt_getprop(fit, noffset, "subtype", &len);
	if (*subtype == NULL)
		return -1;

	return 0;
}

static int ait_subtype_nr(char *subtype)
{
	int ret = FIT_SUBTYPE_UNKNOWN;

	if (!strncmp("ublheader", subtype, strlen("ublheader")))
		return FIT_SUBTYPE_UBL_HEADER;
	if (!strncmp("splimage", subtype, strlen("splimage")))
		return FIT_SUBTYPE_SPL_IMAGE;
	if (!strncmp("ubootimage", subtype, strlen("ubootimage")))
		return FIT_SUBTYPE_UBOOT_IMAGE;
	if (!strncmp("dfenvimage", subtype, strlen("dfenvimage")))
		return FIT_SUBTYPE_DF_ENV_IMAGE;

	return ret;
}

static int ait_menu_check_image(void)
{
	char *s;
	unsigned long fit_addr;
	void *addr;
	int format;
	char *desc;
	char *subtype;
	int images_noffset;
	int noffset;
	int ndepth;
	int count = 0;
	int ret;
	int i;
	int found_uboot = -1;
	int found_ramdisk = -1;

	memset(imgs, 0, sizeof(imgs));
	s = getenv("fit_addr_r");
	fit_addr = s ? (unsigned long)simple_strtol(s, NULL, 16) : \
			CONFIG_BOARD_IMG_ADDR_R;

	addr = (void *)fit_addr;
	/* check if it is a FIT image */
	format = genimg_get_format(addr);
	if (format != IMAGE_FORMAT_FIT)
		return -EINVAL;

	if (!fit_check_format(addr))
		return -EINVAL;

	/* print the FIT description */
	ret = fit_get_desc(addr, 0, &desc);
	printf("FIT description: ");
	if (ret)
		printf("unavailable\n");
	else
		printf("%s\n", desc);

	/* find images */
	images_noffset = fdt_path_offset(addr, FIT_IMAGES_PATH);
	if (images_noffset < 0) {
		printf("Can't find images parent node '%s' (%s)\n",
			FIT_IMAGES_PATH, fdt_strerror(images_noffset));
		return -EINVAL;
	}

	/* Process its subnodes, print out component images details */
	for (ndepth = 0, count = 0,
		noffset = fdt_next_node(addr, images_noffset, &ndepth);
		(noffset >= 0) && (ndepth > 0);
		noffset = fdt_next_node(addr, noffset, &ndepth)) {
		if (ndepth == 1) {
			/*
			 * Direct child node of the images parent node,
			 * i.e. component image node.
			 */
			printf("Image %u (%s)\n", count,
					fit_get_name(addr, noffset, NULL));

			fit_image_print(addr, noffset, "");

			fit_image_get_type(addr, noffset,
				&imgs[count].type);
			/* Mandatory properties */
			ret = fit_get_desc(addr, noffset, &desc);
			printf("Description:  ");
			if (ret)
				printf("unavailable\n");
			else
				printf("%s\n", desc);

			ret = fit_get_subtype(addr, noffset, &subtype);
			printf("Subtype:  ");
			if (ret) {
				printf("unavailable\n");
			} else {
				imgs[count].subtype = ait_subtype_nr(subtype);
				printf("%s %d\n", subtype,
					imgs[count].subtype);
			}

			sprintf(imgs[count].desc, "%s", desc);

			ret = fit_image_get_data(addr, noffset,
				&imgs[count].data,
				&imgs[count].size);

			printf("Data Size:    ");
			if (ret)
				printf("unavailable\n");
			else
				genimg_print_size(imgs[count].size);
			printf("Data @ %p\n", imgs[count].data);
			count++;
		}
	}

	for (i = 0; i < count; i++) {
		if (imgs[i].subtype == FIT_SUBTYPE_UBOOT_IMAGE)
			found_uboot = i;
		if (imgs[i].type == IH_TYPE_RAMDISK) {
			found_ramdisk = i;
			imgs[i].subtype = FIT_SUBTYPE_RAMDISK_IMAGE;
		}
	}

	/* dvn_* env var update, if the FIT descriptors are different */
	if (found_uboot >= 0) {
		s = getenv("dvn_boot_vers");
		if (s) {
			ret = strcmp(s, imgs[found_uboot].desc);
			if (ret != 0) {
				setenv("x_dvn_boot_vers",
					imgs[found_uboot].desc);
			} else {
				found_uboot = -1;
				printf("no new uboot version\n");
			}
		} else {
			setenv("dvn_boot_vers", imgs[found_uboot].desc);
		}
	}
	if (found_ramdisk >= 0) {
		s = getenv("dvn_app_vers");
		if (s) {
			ret = strcmp(s, imgs[found_ramdisk].desc);
			if (ret != 0) {
				setenv("x_dvn_app_vers",
					imgs[found_ramdisk].desc);
			} else {
				found_ramdisk = -1;
				printf("no new ramdisk version\n");
			}
		} else {
			setenv("dvn_app_vers", imgs[found_ramdisk].desc);
		}
	}
	if ((found_uboot == -1) && (found_ramdisk == -1))
		return -EINVAL;

	return 0;
}

static int ait_menu_evaluate_update(char *choice)
{
	int ret;

	if (!choice)
		return MENU_MAIN;

	switch (choice[1]) {
	case '1':
		return ait_menu_show(&ait_network, 0);
		break;
	case '2':
		/* load image */
		ret = run_command("run load_img", 0);
		printf("ret: %d\n", ret);
		if (ret)
			return MENU_UPDATE;

		ret = ait_menu_check_image();
		if (ret)
			return MENU_UPDATE;

		return ait_menu_show(&ait_load, 0);
		break;
	case '3':
		return MENU_MAIN;
		break;

	}

	return MENU_MAIN;
}

struct menu_display ait_update = {
	.title = "AIT Update Software",
	.timeout = 0,
	.id = MENU_UPDATE,
	.menulist = menu_update,
	.menu_evaluate = ait_menu_evaluate_update,
};

static int ait_menu_evaluate_main(char *choice)
{
	if (!choice)
		return MENU_STAY;

	menu_start = 1;
	switch (choice[1]) {
	case '1':
		/* run bootcmd */
		return MENU_EXIT_BOOTCMD;
		break;
	case '2':
		return ait_menu_show(&ait_update, 0);
		break;
	case '3':
		/* reset to default settings */
		setenv("app_reset", "yes");
		return MENU_EXIT_BOOTCMD;
		break;
	case '4':
		/* u-boot shell */
		return MENU_EXIT;
		break;
	}

	return MENU_EXIT;
}

struct menu_display ait_main = {
	.title = "AIT Main",
	.timeout = CONFIG_BOOTDELAY,
	.id = MENU_MAIN,
	.menulist = menu_main,
	.menu_evaluate = ait_menu_evaluate_main,
};

int menu_show(int bootdelay)
{
	int ret;

	run_command("run saveparms", 0);
	ret = ait_menu_show(&ait_main, bootdelay);
	run_command("run restoreparms", 0);

	if (ret == MENU_EXIT_BOOTCMD)
		return 0;

	return MENU_EXIT;
}

void menu_display_statusline(struct menu *m)
{
	char *s1, *s2;

	s1 = getenv("x_dvn_boot_vers");
	if (!s1)
		s1 = getenv("dvn_boot_vers");

	s2 = getenv("x_dvn_app_vers");
	if (!s2)
		s2 = getenv("dvn_app_vers");

	printf("State: dvn_boot_vers: %s dvn_app_vers: %s\n", s1, s2);
	return;
}
#endif
