diff options
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/standalone/.gitignore | 1 | ||||
| -rw-r--r-- | examples/standalone/Makefile | 4 | ||||
| -rw-r--r-- | examples/standalone/atmel_df_pow2.c | 209 | 
3 files changed, 214 insertions, 0 deletions
| diff --git a/examples/standalone/.gitignore b/examples/standalone/.gitignore index 0d1864cc2..7b783fc21 100644 --- a/examples/standalone/.gitignore +++ b/examples/standalone/.gitignore @@ -1,4 +1,5 @@  /82559_eeprom +/atmel_df_pow2  /hello_world  /interrupt  /mem_to_mem_idma2intr diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile index d2e811a8b..9a9b6c38e 100644 --- a/examples/standalone/Makefile +++ b/examples/standalone/Makefile @@ -86,6 +86,10 @@ ELF	= hello_world  SREC	= hello_world.srec  BIN	= hello_world.bin +ELF	+= atmel_df_pow2 +SREC	+= atmel_df_pow2.srec +BIN	+= atmel_df_pow2.bin +  ifeq ($(CPU),mpc8xx)  ELF	+= test_burst  SREC	+= test_burst.srec diff --git a/examples/standalone/atmel_df_pow2.c b/examples/standalone/atmel_df_pow2.c new file mode 100644 index 000000000..db0cd693a --- /dev/null +++ b/examples/standalone/atmel_df_pow2.c @@ -0,0 +1,209 @@ +/* + * atmel_df_pow2.c - convert Atmel Dataflashes to Power of 2 mode + * + * Copyright 2009 Analog Devices Inc. + * + * Licensed under the 2-clause BSD. + */ + +#include <common.h> +#include <exports.h> + +#define CMD_ID    0x9f +#define CMD_STAT  0xd7 +#define CMD_CFG   0x3d + +static int flash_cmd(struct spi_slave *slave, uchar cmd, uchar *buf, int len) +{ +	buf[0] = cmd; +	return spi_xfer(slave, 8 * len, buf, buf, SPI_XFER_BEGIN | SPI_XFER_END); +} + +static int flash_status(struct spi_slave *slave) +{ +	uchar buf[2]; +	if (flash_cmd(slave, CMD_STAT, buf, sizeof(buf))) +		return -1; +	return buf[1]; +} + +static int flash_set_pow2(struct spi_slave *slave) +{ +	int ret; +	uchar buf[4]; + +	buf[1] = 0x2a; +	buf[2] = 0x80; +	buf[3] = 0xa6; + +	ret = flash_cmd(slave, CMD_CFG, buf, sizeof(buf)); +	if (ret) +		return ret; + +	/* wait Tp, or 6 msec */ +	udelay(6000); + +	ret = flash_status(slave); +	if (ret == -1) +		return 1; + +	return ret & 0x1 ? 0 : 1; +} + +static int flash_check(struct spi_slave *slave) +{ +	int ret; +	uchar buf[4]; + +	ret = flash_cmd(slave, CMD_ID, buf, sizeof(buf)); +	if (ret) +		return ret; + +	if (buf[1] != 0x1F) { +		printf("atmel flash not found (id[0] = %#x)\n", buf[1]); +		return 1; +	} + +	if ((buf[2] >> 5) != 0x1) { +		printf("AT45 flash not found (id[0] = %#x)\n", buf[2]); +		return 2; +	} + +	return 0; +} + +static char *getline(void) +{ +	static char buffer[100]; +	char c; +	size_t i; + +	i = 0; +	while (1) { +		buffer[i] = '\0'; + +		c = getc(); + +		switch (c) { +		case '\r':	/* Enter/Return key */ +		case '\n': +			puts("\n"); +			return buffer; + +		case 0x03:	/* ^C - break */ +			return NULL; + +		case 0x5F: +		case 0x08:	/* ^H  - backspace */ +		case 0x7F:	/* DEL - backspace */ +			if (i) { +				puts("\b \b"); +				i--; +			} +			break; + +		default: +			/* Ignore control characters */ +			if (c < 0x20) +				break; +			/* Queue up all other characters */ +			buffer[i++] = c; +			printf("%c", c); +			break; +		} +	} +} + +int atmel_df_pow2(int argc, char *argv[]) +{ +	/* Print the ABI version */ +	app_startup(argv); +	if (XF_VERSION != get_version()) { +		printf("Expects ABI version %d\n", XF_VERSION); +		printf("Actual U-Boot ABI version %lu\n", get_version()); +		printf("Can't run\n\n"); +		return 1; +	} + +	spi_init(); + +	while (1) { +		struct spi_slave *slave; +		char *line, *p; +		int bus, cs, status; + +		puts("\nenter the [BUS:]CS of the SPI flash: "); +		line = getline(); + +		/* CTRL+C */ +		if (!line) +			return 0; +		if (line[0] == '\0') +			continue; + +		bus = cs = simple_strtoul(line, &p, 10); +		if (*p) { +			if (*p == ':') { +				++p; +				cs = simple_strtoul(p, &p, 10); +			} +			if (*p) { +				puts("invalid format, please try again\n"); +				continue; +			} +		} else +			bus = 0; + +		printf("\ngoing to work with dataflash at %i:%i\n", bus, cs); + +		/* use a low speed -- it'll work with all devices, and +		 * speed here doesn't really matter. +		 */ +		slave = spi_setup_slave(bus, cs, 1000, SPI_MODE_3); +		if (!slave) { +			puts("unable to setup slave\n"); +			continue; +		} + +		if (spi_claim_bus(slave)) { +			spi_free_slave(slave); +			continue; +		} + +		if (flash_check(slave)) { +			puts("no flash found\n"); +			goto done; +		} + +		status = flash_status(slave); +		if (status == -1) { +			puts("unable to read status register\n"); +			goto done; +		} +		if (status & 0x1) { +			puts("flash is already in power-of-2 mode!\n"); +			goto done; +		} + +		puts("are you sure you wish to set power-of-2 mode?\n"); +		puts("this operation is permanent and irreversible\n"); +		printf("enter YES to continue: "); +		line = getline(); +		if (!line || strcmp(line, "YES")) +			goto done; + +		if (flash_set_pow2(slave)) { +			puts("setting pow2 mode failed\n"); +			goto done; +		} + +		puts( +			"Configuration should be updated now.  You will have to\n" +			"power cycle the part in order to finish the conversion.\n" +		); + + done: +		spi_release_bus(slave); +		spi_free_slave(slave); +	} +} |