diff options
Diffstat (limited to 'roms/u-boot/board/ait')
| -rw-r--r-- | roms/u-boot/board/ait/cam_enc_4xx/Makefile | 10 | ||||
| -rw-r--r-- | roms/u-boot/board/ait/cam_enc_4xx/cam_enc_4xx.c | 1106 | ||||
| -rw-r--r-- | roms/u-boot/board/ait/cam_enc_4xx/config.mk | 20 | ||||
| -rw-r--r-- | roms/u-boot/board/ait/cam_enc_4xx/u-boot-spl.lds | 56 | ||||
| -rw-r--r-- | roms/u-boot/board/ait/cam_enc_4xx/ublimage.cfg | 31 | 
5 files changed, 1223 insertions, 0 deletions
diff --git a/roms/u-boot/board/ait/cam_enc_4xx/Makefile b/roms/u-boot/board/ait/cam_enc_4xx/Makefile new file mode 100644 index 00000000..0d03ce00 --- /dev/null +++ b/roms/u-boot/board/ait/cam_enc_4xx/Makefile @@ -0,0 +1,10 @@ +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	:= cam_enc_4xx.o diff --git a/roms/u-boot/board/ait/cam_enc_4xx/cam_enc_4xx.c b/roms/u-boot/board/ait/cam_enc_4xx/cam_enc_4xx.c new file mode 100644 index 00000000..7e1b16ac --- /dev/null +++ b/roms/u-boot/board/ait/cam_enc_4xx/cam_enc_4xx.c @@ -0,0 +1,1106 @@ +/* + * Copyright (C) 2009 Texas Instruments Incorporated + * + * Copyright (C) 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#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 oob_required, 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 int davinci_std_write_page_syndrome(struct mtd_info *mtd, +				    struct nand_chip *chip, const uint8_t *buf, +				    int oob_required) +{ +	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); +	return 0; +} + +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) +{ +	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 0; +} + +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, +			NULL, NULL); + +	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 diff --git a/roms/u-boot/board/ait/cam_enc_4xx/config.mk b/roms/u-boot/board/ait/cam_enc_4xx/config.mk new file mode 100644 index 00000000..20221513 --- /dev/null +++ b/roms/u-boot/board/ait/cam_enc_4xx/config.mk @@ -0,0 +1,20 @@ +# +# 	AIT cam_enc_4xx board +#	cam_enc_4xx board has 1 bank of 256 MB DDR RAM +#	Physical Address: 8000'0000 to 9000'0000 +# +# Linux Kernel is expected to be at 8000'8000, entry 8000'8000 +# (mem base + reserved) +# + +UBL_CONFIG = $(srctree)/board/$(BOARDDIR)/ublimage.cfg +ifndef CONFIG_SPL_BUILD +ALL-y += u-boot.ubl +else +# as SPL_TEXT_BASE is not page-aligned, we need for some +# linkers the -n flag (Do not page align data), to prevent +# the following error message: +# arm-linux-ld: u-boot-spl: Not enough room for program headers, try linking +# with -N +LDFLAGS_u-boot-spl += -n +endif diff --git a/roms/u-boot/board/ait/cam_enc_4xx/u-boot-spl.lds b/roms/u-boot/board/ait/cam_enc_4xx/u-boot-spl.lds new file mode 100644 index 00000000..c0d09adf --- /dev/null +++ b/roms/u-boot/board/ait/cam_enc_4xx/u-boot-spl.lds @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\ +		LENGTH = CONFIG_SPL_MAX_FOOTPRINT } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ +	. = CONFIG_SPL_TEXT_BASE; + +	. = ALIGN(4); +	.text      : +	{ +	__start = .; +	  arch/arm/cpu/arm926ejs/start.o	(.text*) +	  *(.text*) +	} >.sram + +	. = ALIGN(4); +	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram + +	. = ALIGN(4); +	.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram +	. = ALIGN(4); +	.rel.dyn : { +		__rel_dyn_start = .; +		*(.rel*) +		__rel_dyn_end = .; +	} >.sram + +	.bss : +	{ +		. = ALIGN(4); +		__bss_start = .; +		*(.bss*) +		. = ALIGN(4); +		__bss_end = .; +	} >.sram + +	__image_copy_end = .; + +	.end : +	{ +		*(.__end) +	} +} diff --git a/roms/u-boot/board/ait/cam_enc_4xx/ublimage.cfg b/roms/u-boot/board/ait/cam_enc_4xx/ublimage.cfg new file mode 100644 index 00000000..d4fe705b --- /dev/null +++ b/roms/u-boot/board/ait/cam_enc_4xx/ublimage.cfg @@ -0,0 +1,31 @@ +# +# (C Copyright 2011 +# Heiko Schocher DENX Software Engineering hs@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# +# Refer doc/README.ublimage for more details about how-to configure +# and create ublimage boot image +# +# The syntax is taken as close as possible with the kwbimage + +# UBL special mode : one of +# safe (the board has no nand neither onenand) +MODE	safe + +# Entry point address for the user bootloader (absolute address) +# nand spl TEXT_BASE = 0x20 !! +ENTRY	0x00000020 + +# Number of pages (size of user bootloader in number of pages) +# @ nand spl 6 pages +PAGES	6 + +# Block number where user bootloader is present +START_BLOCK	0 + +# Page number where user bootloader is present +# Page 0 is always UBL header +START_PAGE	0 + +LD_ADDR		0x20  | 
