diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/u-boot/board/enbw/enbw_cmc | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/u-boot/board/enbw/enbw_cmc')
| -rw-r--r-- | roms/u-boot/board/enbw/enbw_cmc/Makefile | 10 | ||||
| -rw-r--r-- | roms/u-boot/board/enbw/enbw_cmc/enbw_cmc.c | 893 | 
2 files changed, 903 insertions, 0 deletions
diff --git a/roms/u-boot/board/enbw/enbw_cmc/Makefile b/roms/u-boot/board/enbw/enbw_cmc/Makefile new file mode 100644 index 00000000..054d6e7c --- /dev/null +++ b/roms/u-boot/board/enbw/enbw_cmc/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   := enbw_cmc.o diff --git a/roms/u-boot/board/enbw/enbw_cmc/enbw_cmc.c b/roms/u-boot/board/enbw/enbw_cmc/enbw_cmc.c new file mode 100644 index 00000000..39efe20b --- /dev/null +++ b/roms/u-boot/board/enbw/enbw_cmc/enbw_cmc.c @@ -0,0 +1,893 @@ +/* + * (C) Copyright 2011 + * Heiko Schocher, DENX Software Engineering, hs@denx.de. + * + * Based on: + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * Based on da830evm.c. Original Copyrights follow: + * + * Copyright (C) 2009 Nick Thompson, GE Fanuc, Ltd. <nick.thompson@gefanuc.com> + * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <environment.h> +#include <hwconfig.h> +#include <i2c.h> +#include <malloc.h> +#include <miiphy.h> +#include <mmc.h> +#include <net.h> +#include <netdev.h> +#include <spi.h> +#include <linux/ctype.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/arch/da850_lowlevel.h> +#include <asm/arch/davinci_misc.h> +#include <asm/arch/emif_defs.h> +#include <asm/arch/emac_defs.h> +#include <asm/arch/gpio.h> +#include <asm/arch/pinmux_defs.h> +#include <asm/arch/hardware.h> +#include <asm/arch/sdmmc_defs.h> +#include <asm/arch/timer_defs.h> +#include <asm/davinci_rtc.h> + +DECLARE_GLOBAL_DATA_PTR; + +const struct lpsc_resource lpsc[] = { +	{ DAVINCI_LPSC_AEMIF }, +	{ DAVINCI_LPSC_SPI1 }, +	{ DAVINCI_LPSC_ARM_RAM_ROM }, +	{ DAVINCI_LPSC_UART0 }, +	{ DAVINCI_LPSC_EMAC }, +	{ DAVINCI_LPSC_UART0 }, +	{ DAVINCI_LPSC_GPIO }, +	{ DAVINCI_LPSC_DDR_EMIF }, +	{ DAVINCI_LPSC_UART1 }, +	{ DAVINCI_LPSC_UART2 }, +	{ DAVINCI_LPSC_MMC_SD1 }, +	{ DAVINCI_LPSC_USB20 }, +	{ DAVINCI_LPSC_USB11 }, +}; + +const int lpsc_size = ARRAY_SIZE(lpsc); + +static const struct pinmux_config enbw_pins[] = { +	{ pinmux(0), 8, 0 }, +	{ pinmux(0), 8, 1 }, +	{ pinmux(0), 8, 2 }, +	{ pinmux(0), 8, 3 }, +	{ pinmux(0), 8, 4 }, +	{ pinmux(0), 8, 5 }, +	{ pinmux(1), 4, 0 }, +	{ pinmux(1), 8, 1 }, +	{ pinmux(1), 8, 2 }, +	{ pinmux(1), 8, 3 }, +	{ pinmux(1), 8, 4 }, +	{ pinmux(1), 8, 5 }, +	{ pinmux(1), 8, 6 }, +	{ pinmux(1), 4, 7 }, +	{ pinmux(2), 8, 0 }, +	{ pinmux(5), 1, 0 }, +	{ pinmux(5), 1, 3 }, +	{ pinmux(5), 1, 7 }, +	{ pinmux(5), 1, 5 }, +	{ pinmux(5), 1, 4 }, +	{ pinmux(5), 1, 3 }, +	{ pinmux(5), 1, 2 }, +	{ pinmux(5), 1, 1 }, +	{ pinmux(5), 1, 0 }, +	{ pinmux(6), 8, 0 }, +	{ pinmux(6), 8, 1 }, +	{ pinmux(6), 8, 2 }, +	{ pinmux(6), 8, 3 }, +	{ pinmux(6), 8, 4 }, +	{ pinmux(6), 8, 5 }, +	{ pinmux(6), 1, 7 }, +	{ pinmux(7), 8, 2 }, +	{ pinmux(7), 1, 3 }, +	{ pinmux(7), 8, 6 }, +	{ pinmux(7), 1, 7 }, +	{ pinmux(13), 8, 2 }, +	{ pinmux(13), 8, 3 }, +	{ pinmux(13), 8, 4 }, +	{ pinmux(13), 8, 5 }, +	{ pinmux(13), 8, 6 }, +	{ pinmux(13), 8, 7 }, +	{ pinmux(14), 8, 0 }, +	{ pinmux(14), 8, 1 }, +	{ pinmux(16), 8, 1 }, +	{ pinmux(16), 8, 2 }, +	{ pinmux(16), 8, 3 }, +	{ pinmux(16), 8, 4 }, +	{ pinmux(16), 8, 5 }, +	{ pinmux(16), 8, 6 }, +	{ pinmux(16), 8, 7 }, +	{ pinmux(17), 1, 0 }, +	{ pinmux(17), 1, 1 }, +	{ pinmux(17), 1, 2 }, +	{ pinmux(17), 8, 3 }, +	{ pinmux(17), 8, 4 }, +	{ pinmux(17), 8, 5 }, +	{ pinmux(17), 8, 6 }, +	{ pinmux(17), 8, 7 }, +	{ pinmux(18), 8, 0 }, +	{ pinmux(18), 8, 1 }, +	{ pinmux(18), 2, 2 }, +	{ pinmux(18), 2, 3 }, +	{ pinmux(18), 2, 4 }, +	{ pinmux(18), 8, 6 }, +	{ pinmux(18), 8, 7 }, +	{ pinmux(19), 8, 0 }, +	{ pinmux(19), 2, 1 }, +	{ pinmux(19), 2, 2 }, +	{ pinmux(19), 2, 3 }, +	{ pinmux(19), 2, 4 }, +	{ pinmux(19), 8, 5 }, +	{ pinmux(19), 8, 6 }, +}; + +const struct pinmux_resource pinmuxes[] = { +	PINMUX_ITEM(emac_pins_mii), +	PINMUX_ITEM(emac_pins_mdio), +	PINMUX_ITEM(i2c0_pins), +	PINMUX_ITEM(emifa_pins_cs2), +	PINMUX_ITEM(emifa_pins_cs3), +	PINMUX_ITEM(emifa_pins_cs4), +	PINMUX_ITEM(emifa_pins_nand), +	PINMUX_ITEM(emifa_pins_nor), +	PINMUX_ITEM(spi1_pins_base), +	PINMUX_ITEM(spi1_pins_scs0), +	PINMUX_ITEM(uart1_pins_txrx), +	PINMUX_ITEM(uart2_pins_txrx), +	PINMUX_ITEM(uart2_pins_rtscts), +	PINMUX_ITEM(enbw_pins), +}; + +const int pinmuxes_size = ARRAY_SIZE(pinmuxes); + +struct gpio_config { +	char name[GPIO_NAME_SIZE]; +	unsigned char bank; +	unsigned char gpio; +	unsigned char out; +	unsigned char value; +}; + +static const struct gpio_config enbw_gpio_config_hut[] = { +	{ "RS485 enable",	8, 11, 1, 0 }, +	{ "RS485 iso",		8, 10, 1, 1 }, +	{ "W2HUT RS485 Rx ena",	8,  9, 1, 0 }, +	{ "W2HUT RS485 iso",	8,  8, 1, 1 }, +}; + +static const struct gpio_config enbw_gpio_config_w[] = { +	{ "RS485 enable",	8, 11, 1, 0 }, +	{ "RS485 iso",		8, 10, 1, 0 }, +	{ "W2HUT RS485 Rx ena",	8,  9, 1, 0 }, +	{ "W2HUT RS485 iso",	8,  8, 1, 0 }, +}; + +static const struct gpio_config enbw_gpio_config[] = { +	{ "LAN reset",		7, 15, 1, 1 }, +	{ "ena 11V PLC",	7, 14, 1, 0 }, +	{ "ena 1.5V PLC",	7, 13, 1, 0 }, +	{ "disable VBUS",	7, 12, 1, 1 }, +	{ "PLC reset",		6, 13, 1, 0 }, +	{ "LCM RS",		6, 12, 1, 0 }, +	{ "LCM R/W",		6, 11, 1, 0 }, +	{ "PLC pairing",	6, 10, 1, 1 }, +	{ "PLC MDIO CLK",	6,  9, 1, 0 }, +	{ "HK218",		6,  8, 1, 0 }, +	{ "HK218 Rx",		6,  1, 1, 1 }, +	{ "TPM reset",		6,  0, 1, 0 }, +	{ "Board-Type",		3,  9, 0, 0 }, +	{ "HW-ID0",		2,  7, 0, 0 }, +	{ "HW-ID1",		2,  6, 0, 0 }, +	{ "HW-ID2",		2,  3, 0, 0 }, +	{ "PV-IF RxD ena",	0, 15, 1, 1 }, +	{ "LED1",		1, 15, 1, 1 }, +	{ "LED2",		0,  1, 1, 1 }, +	{ "LED3",		0,  2, 1, 1 }, +	{ "LED4",		0,  3, 1, 1 }, +	{ "LED5",		0,  4, 1, 1 }, +	{ "LED6",		0,  5, 1, 0 }, +	{ "LED7",		0,  6, 1, 0 }, +	{ "LED8",		0, 14, 1, 0 }, +	{ "USER1",		0, 12, 0, 0 }, +	{ "USER2",		0, 13, 0, 0 }, +}; + +#define PHY_POWER	0x0800 + +static void enbw_cmc_switch(int port, int on) +{ +	const char	*devname; +	unsigned char phyaddr = 3; +	unsigned char	reg = 0; +	unsigned short	data; + +	if (port == 1) +		phyaddr = 2; + +	devname = miiphy_get_current_dev(); +	if (!devname) { +		printf("Error: no mii device\n"); +		return; +	} +	if (miiphy_read(devname, phyaddr, reg, &data) != 0) { +		printf("Error reading from the PHY addr=%02x reg=%02x\n", +			phyaddr, reg); +		return; +	} + +	if (on) +		data &= ~PHY_POWER; +	else +		data |= PHY_POWER; + +	if (miiphy_write(devname, phyaddr, reg, data) != 0) { +		printf("Error writing to the PHY addr=%02x reg=%02x\n", +			phyaddr, reg); +		return; +	} +} + +static int enbw_cmc_init_gpio(const struct gpio_config *conf, int sz) +{ +	int i, ret; + +	for (i = 0; i < sz; i++) { +		int gpio = conf[i].bank * 16 + +			conf[i].gpio; + +		ret = gpio_request(gpio, conf[i].name); +		if (ret) { +			printf("%s: Could not get %s gpio\n", __func__, +				conf[i].name); +			return ret; +		} + +		if (conf[i].out) +			gpio_direction_output(gpio, +				conf[i].value); +		else +			gpio_direction_input(gpio); +	} + +	return 0; +} + +int board_init(void) +{ +	int board_type, hw_id; + +#ifndef CONFIG_USE_IRQ +	irq_init(); +#endif +	/* address of boot parameters, not used as booting with DTT */ +	gd->bd->bi_boot_params = 0; + +	enbw_cmc_init_gpio(enbw_gpio_config, ARRAY_SIZE(enbw_gpio_config)); + +	/* detect HW version */ +	board_type = gpio_get_value(CONFIG_ENBW_CMC_BOARD_TYPE); +	hw_id = gpio_get_value(CONFIG_ENBW_CMC_HW_ID_BIT0) + +		(gpio_get_value(CONFIG_ENBW_CMC_HW_ID_BIT1) << 1) + +		(gpio_get_value(CONFIG_ENBW_CMC_HW_ID_BIT2) << 2); +	printf("BOARD: CMC-%s hw id: %d\n", (board_type ? "w2" : "hut"), +		hw_id); +	if (board_type) +		enbw_cmc_init_gpio(enbw_gpio_config_w, +			ARRAY_SIZE(enbw_gpio_config_w)); +	else +		enbw_cmc_init_gpio(enbw_gpio_config_hut, +			ARRAY_SIZE(enbw_gpio_config_hut)); + +	/* setup the SUSPSRC for ARM to control emulation suspend */ +	clrbits_le32(&davinci_syscfg_regs->suspsrc, +		(DAVINCI_SYSCFG_SUSPSRC_EMAC | DAVINCI_SYSCFG_SUSPSRC_I2C | +		DAVINCI_SYSCFG_SUSPSRC_SPI1 | DAVINCI_SYSCFG_SUSPSRC_TIMER0 | +		DAVINCI_SYSCFG_SUSPSRC_UART2)); + +	return 0; +} + +#ifdef CONFIG_DRIVER_TI_EMAC + +#define KSZ_CMD_READ	0x03 +#define KSZ_CMD_WRITE	0x02 +#define KSZ_ID		0x95 + +static int enbw_cmc_switch_read(struct spi_slave *spi, u8 reg, u8 *val) +{ +	unsigned long flags = SPI_XFER_BEGIN; +	int ret; +	int cmd_len; +	u8 cmd[2]; + +	cmd[0] = KSZ_CMD_READ; +	cmd[1] = reg; +	cmd_len = 2; + +	ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags); +	if (ret) { +		debug("Failed to send command (%zu bytes): %d\n", +				cmd_len, ret); +		return -EINVAL; +	} +	flags |= SPI_XFER_END; +	*val = 0; +	cmd_len = 1; +	ret = spi_xfer(spi, cmd_len * 8, NULL, val, flags); +	if (ret) { +		debug("Failed to read (%zu bytes): %d\n", +				cmd_len, ret); +		return -EINVAL; +	} + +	return 0; +} + +static int enbw_cmc_switch_read_ident(struct spi_slave *spi) +{ +	int ret; +	u8 val; + +	ret = enbw_cmc_switch_read(spi, 0, &val); +	if (ret) { +		debug("Failed to read\n"); +		return -EINVAL; +	} + +	if (val != KSZ_ID) +		return -EINVAL; + +	return 0; +} + +static int enbw_cmc_switch_write(struct spi_slave *spi, unsigned long reg, +		unsigned long val) +{ +	unsigned long flags = SPI_XFER_BEGIN; +	int ret; +	int cmd_len; +	u8 cmd[3]; + +	cmd[0] = KSZ_CMD_WRITE; +	cmd[1] = reg; +	cmd[2] = val; +	cmd_len = 3; +	flags |= SPI_XFER_END; + +	ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags); +	if (ret) { +		debug("Failed to send command (%zu bytes): %d\n", +				cmd_len, ret); +		return -EINVAL; +	} + +	udelay(1000); +	ret = enbw_cmc_switch_read(spi, reg, &cmd[0]); +	if (ret) { +		debug("Failed to read\n"); +		return -EINVAL; +	} +	if (val != cmd[0]) +		debug("warning: reg: %lx va: %x soll: %lx\n", +			reg, cmd[0], val); + +	return 0; +} + +static int enbw_cmc_eof(unsigned char *ptr) +{ +	if (*ptr == 0xff) +		return 1; + +	return 0; +} + +static char *enbw_cmc_getnewline(char *ptr) +{ +	while (*ptr != 0x0a) { +		ptr++; +		if (enbw_cmc_eof((unsigned char *)ptr)) +			return NULL; +	} + +	ptr++; +	return ptr; +} + +static char *enbw_cmc_getvalue(char *ptr, int *value) +{ +	int	end = 0; + +	*value = -EINVAL; + +	if (!isxdigit(*ptr)) +		end = 1; + +	while (end) { +		if ((*ptr == '#') || (*ptr == ';')) { +			ptr = enbw_cmc_getnewline(ptr); +			return ptr; +		} +		if (ptr != NULL) { +			if (isxdigit(*ptr)) { +				end = 0; +			} else if (*ptr == 0x0a) { +				ptr++; +				return ptr; +			} else { +				ptr++; +				if (enbw_cmc_eof((unsigned char *)ptr)) +					return NULL; +			} +		} else { +			return NULL; +		} +	} +	*value = (int)simple_strtoul((const char *)ptr, &ptr, 16); +	ptr++; +	return ptr; +} + +static struct spi_slave *enbw_cmc_init_spi(void) +{ +	struct spi_slave *spi; +	int ret; + +	spi = spi_setup_slave(0, 0, 1000000, 0); +	if (!spi) { +		printf("Failed to set up slave\n"); +		return NULL; +	} + +	ret = spi_claim_bus(spi); +	if (ret) { +		debug("Failed to claim SPI bus: %d\n", ret); +		goto err_claim_bus; +	} + +	ret = enbw_cmc_switch_read_ident(spi); +	if (ret) +		goto err_read; + +	return spi; +err_read: +	spi_release_bus(spi); +err_claim_bus: +	spi_free_slave(spi); +	return NULL; +} + +static int enbw_cmc_config_switch(unsigned long addr) +{ +	struct spi_slave *spi; +	char *ptr = (char *)addr; +	int value, reg; +	int ret = 0; + +	debug("configure switch with file on addr: 0x%lx\n", addr); + +	spi = enbw_cmc_init_spi(); +	if (!spi) +		return -EINVAL; + +	while (ptr != NULL) { +		ptr = enbw_cmc_getvalue(ptr, ®); +		if (ptr != NULL) { +			ptr = enbw_cmc_getvalue(ptr, &value); +			if ((ptr != NULL) && (value >= 0)) +				if (enbw_cmc_switch_write(spi, reg, value)) { +					/* error writing to switch */ +					ptr = NULL; +					ret = -EINVAL; +				} +		} +	} + +	spi_release_bus(spi); +	spi_free_slave(spi); +	return ret; +} + +static int do_switch(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ +	unsigned long addr; + +	if (argc < 2) +		return cmd_usage(cmdtp); + +	addr = simple_strtoul(argv[1], NULL, 16); +	enbw_cmc_config_switch(addr); + +	return 0; +} + +U_BOOT_CMD(switch, 3, 1, do_switch, +	"switch addr", +	"[addr]" +); + +/* + * Initializes on-board ethernet controllers. + */ +int board_eth_init(bd_t *bis) +{ +	struct spi_slave *spi; +	const char *s; +	size_t len = 0; +	int config = 1; + +	davinci_emac_mii_mode_sel(0); + +	/* send a config file to the switch */ +	s = hwconfig_subarg("switch", "config", &len); +	if (len) { +		unsigned long addr = simple_strtoul(s, NULL, 16); + +		config = enbw_cmc_config_switch(addr); +	} + +	if (config) { +		/* +		 * no valid config file -> do we have some args in +		 * hwconfig ? +		 */ +		if ((hwconfig_subarg("switch", "lan", &len)) || +		    (hwconfig_subarg("switch", "lmn", &len))) { +			/* If so start switch */ +			spi = enbw_cmc_init_spi(); +			if (spi) { +				if (enbw_cmc_switch_write(spi, 1, 0)) +					config = 0; +				udelay(10000); +				if (enbw_cmc_switch_write(spi, 1, 1)) +					config = 0; +				spi_release_bus(spi); +				spi_free_slave(spi); +			} +		} else { +			config = 0; +		} +	} +	if (!davinci_emac_initialize()) { +		printf("Error: Ethernet init failed!\n"); +		return -1; +	} + +	if (config) { +		if (hwconfig_subarg_cmp("switch", "lan", "on")) +			/* Switch port lan on */ +			enbw_cmc_switch(1, 1); +		else +			enbw_cmc_switch(1, 0); + +		if (hwconfig_subarg_cmp("switch", "lmn", "on")) +			/* Switch port pwl on */ +			enbw_cmc_switch(2, 1); +		else +			enbw_cmc_switch(2, 0); +	} + +	return 0; +} +#endif /* CONFIG_DRIVER_TI_EMAC */ + +#ifdef CONFIG_PREBOOT +static uchar kbd_magic_prefix[]		= "key_magic_"; +static uchar kbd_command_prefix[]	= "key_cmd_"; + +struct kbd_data_t { +	char s1; +}; + +struct kbd_data_t *get_keys(struct kbd_data_t *kbd_data) +{ +	/* read SW1 + SW2 */ +	kbd_data->s1 = gpio_get_value(12) + +		(gpio_get_value(13) << 1); +	return kbd_data; +} + +static int compare_magic(const struct kbd_data_t *kbd_data, char *str) +{ +	char s1 = str[0]; + +	if (s1 >= '0' && s1 <= '9') +		s1 -= '0'; +	else if (s1 >= 'a' && s1 <= 'f') +		s1 = s1 - 'a' + 10; +	else if (s1 >= 'A' && s1 <= 'F') +		s1 = s1 - 'A' + 10; +	else +		return -1; + +	if (s1 != kbd_data->s1) +		return -1; + +	return 0; +} + +static char *key_match(const struct kbd_data_t *kbd_data) +{ +	char magic[sizeof(kbd_magic_prefix) + 1]; +	char *suffix; +	char *kbd_magic_keys; + +	/* +	 * The following string defines the characters that can be appended +	 * to "key_magic" to form the names of environment variables that +	 * hold "magic" key codes, i. e. such key codes that can cause +	 * pre-boot actions. If the string is empty (""), then only +	 * "key_magic" is checked (old behaviour); the string "125" causes +	 * checks for "key_magic1", "key_magic2" and "key_magic5", etc. +	 */ +	kbd_magic_keys = getenv("magic_keys"); +	if (kbd_magic_keys == NULL) +		kbd_magic_keys = ""; + +	/* +	 * loop over all magic keys; +	 * use '\0' suffix in case of empty string +	 */ +	for (suffix = kbd_magic_keys; *suffix || +		suffix == kbd_magic_keys; ++suffix) { +		sprintf(magic, "%s%c", kbd_magic_prefix, *suffix); + +		if (compare_magic(kbd_data, getenv(magic)) == 0) { +			char cmd_name[sizeof(kbd_command_prefix) + 1]; +			char *cmd; + +			sprintf(cmd_name, "%s%c", kbd_command_prefix, *suffix); +			cmd = getenv(cmd_name); + +			return cmd; +		} +	} + +	return NULL; +} +#endif /* CONFIG_PREBOOT */ + +int misc_init_r(void) +{ +	char *s, buf[32]; +#ifdef CONFIG_PREBOOT +	struct kbd_data_t kbd_data; +	/* Decode keys */ +	char *str = strdup(key_match(get_keys(&kbd_data))); +	/* Set or delete definition */ +	setenv("preboot", str); +	free(str); +#endif /* CONFIG_PREBOOT */ + +	/* count all restarts, and save this in an environment var */ +	s = getenv("restartcount"); + +	if (s) +		sprintf(buf, "%ld", simple_strtoul(s, NULL, 10) + 1); +	else +		strcpy(buf, "1"); + +	setenv("restartcount", buf); +	saveenv(); + +#ifdef CONFIG_HW_WATCHDOG +	davinci_hw_watchdog_enable(); +#endif + +	return 0; +} + +struct cmc_led { +	char name[20]; +	unsigned char bank; +	unsigned char gpio; +}; + +struct cmc_led led_table[] = { +	{"led1", 1, 15}, +	{"led2", 0, 1}, +	{"led3", 0, 2}, +	{"led4", 0, 3}, +	{"led5", 0, 4}, +	{"led6", 0, 5}, +	{"led7", 0, 6}, +	{"led8", 0, 14}, +}; + +static int cmc_get_led_state(struct cmc_led *led) +{ +	int value; +	int gpio = led->bank * 16 + led->gpio; + +	value = gpio_get_value(gpio); + +	return value; +} + +static int cmc_set_led_state(struct cmc_led *led, int state) +{ +	int gpio = led->bank * 16 + led->gpio; + +	gpio_set_value(gpio, state); +	return 0; +} + +static int do_led(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ +	struct cmc_led *led; +	int found = 0; +	int i = 0; +	int only_print = 0; +	int len = ARRAY_SIZE(led_table); + +	if (argc < 2) +		return cmd_usage(cmdtp); + +	if (argc < 3) +		only_print = 1; + +	led = led_table; +	while ((!found) && (i < len)) { +		if (strcmp(argv[1], led->name) == 0) { +			found = 1; +		} else { +			led++; +			i++; +		} +	} +	if (!found) +		return cmd_usage(cmdtp); + +	if (only_print) { +		if (cmc_get_led_state(led)) +			printf("on\n"); +		else +			printf("off\n"); + +		return 0; +	} +	if (strcmp(argv[2], "on") == 0) +		cmc_set_led_state(led, 1); +	else +		cmc_set_led_state(led, 0); + +	return 0; +} + +U_BOOT_CMD(led, 3, 1, do_led, +	"switch on/off board led", +	"[name] [on/off]" +); + +#ifdef CONFIG_HW_WATCHDOG +void hw_watchdog_reset(void) +{ +	davinci_hw_watchdog_reset(); +} +#endif + +#if defined(CONFIG_POST) +void arch_memory_failure_handle(void) +{ +	struct davinci_gpio *gpio = davinci_gpio_bank01; +	int state = 1; + +	/* +	 * if memor< failure blink with the LED 1,2 and 3 +	 * as we running from flash, we cannot use the gpio +	 * api here, so access the gpio pin direct through +	 * the gpio register. +	 */ +	while (1) { +		if (state) { +			clrbits_le32(&gpio->out_data, 0x80000006); +			state = 0; +		} else { +			setbits_le32(&gpio->out_data, 0x80000006); +			state = 1; +		} +		udelay(500); +	} +} +#endif + +ulong post_word_load(void) +{ +	struct davinci_rtc *reg = +		(struct davinci_rtc *)CONFIG_SYS_POST_WORD_ADDR; + +	return in_be32(®->scratch2); +} + +void post_word_store(ulong value) +{ +	struct davinci_rtc *reg = +		(struct davinci_rtc *)CONFIG_SYS_POST_WORD_ADDR; + +	/* +	 * write RTC kick register to enable write +	 * for RTC Scratch registers. Cratch0 and 1 are +	 * used for bootcount values. +	 */ +	writel(RTC_KICK0R_WE, ®->kick0r); +	writel(RTC_KICK1R_WE, ®->kick1r); +	out_be32(®->scratch2, value); +} + +void board_gpio_init(void) +{ +	struct davinci_gpio *gpio = davinci_gpio_bank01; + +	/* +	 * set LED (gpio Interface not usable here) +	 * set LED pins to output and state 0 +	 */ +	clrbits_le32(&gpio->dir, 0x8000407e); +	clrbits_le32(&gpio->out_data, 0x8000407e); +	/* set LED 1 - 5 to state on */ +	setbits_le32(&gpio->out_data, 0x8000001e); + +	/* +	 * set some gpio pins to low, this is needed early, +	 * so we have no gpio Interface here +	 * gpios: +	 * 8[8]  Mode PV select  low +	 * 8[9]  Debug Rx Enable low +	 * 8[10] Mode Select PV  low +	 * 8[11] Counter Interface RS485 Rx-Enable low +	 */ +	gpio = davinci_gpio_bank8; +	clrbits_le32(&gpio->dir, 0x00000f00); +	clrbits_le32(&gpio->out_data, 0x0f00); +} + +int board_late_init(void) +{ +	cmc_set_led_state(&led_table[4], 0); + +	return 0; +} + +void show_boot_progress(int val) +{ +	switch (val) { +	case 1: +		cmc_set_led_state(&led_table[4], 1); +		break; +	case 4: +		cmc_set_led_state(&led_table[4], 0); +		break; +	case 15: +		cmc_set_led_state(&led_table[4], 1); +		break; +	} +} + +#ifdef CONFIG_DAVINCI_MMC +static struct davinci_mmc mmc_sd1 = { +	.reg_base	= (struct davinci_mmc_regs *)DAVINCI_MMC_SD1_BASE, +	.input_clk	= 228000000, +	.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) +{ +	mmc_sd1.input_clk = clk_get(DAVINCI_MMC_CLKID); +	/* Add slot-0 to mmc subsystem */ +	return davinci_mmc_init(bis, &mmc_sd1); +} +#endif  | 
