diff options
| author | wdenk <wdenk> | 2002-10-26 15:22:42 +0000 | 
|---|---|---|
| committer | wdenk <wdenk> | 2002-10-26 15:22:42 +0000 | 
| commit | 81a8824f2e751f31249bc23e166c09d82e287887 (patch) | |
| tree | be441bff64ae4be6e6373ebd9a90a33b6fbd6b72 | |
| parent | 1775979a2847f940b49d59e7c453819317735d0b (diff) | |
| download | olio-uboot-2014.01-81a8824f2e751f31249bc23e166c09d82e287887.tar.xz olio-uboot-2014.01-81a8824f2e751f31249bc23e166c09d82e287887.zip | |
Initial revision
| -rw-r--r-- | common/cmd_i2c.c | 868 | ||||
| -rw-r--r-- | include/configs/smdk2410.h | 173 | 
2 files changed, 1041 insertions, 0 deletions
| diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c new file mode 100644 index 000000000..fe5841e6b --- /dev/null +++ b/common/cmd_i2c.c @@ -0,0 +1,868 @@ +/* + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * I2C Functions similar to the standard memory functions. + * + * There are several parameters in many of the commands that bear further + * explanations: + * + * Two of the commands (imm and imw) take a byte/word/long modifier + * (e.g. imm.w specifies the word-length modifier).  This was done to + * allow manipulating word-length registers.  It was not done on any other + * commands because it was not deemed useful. + * + * {i2c_chip} is the I2C chip address (the first byte sent on the bus). + *   Each I2C chip on the bus has a unique address.  On the I2C data bus, + *   the address is the upper seven bits and the LSB is the "read/write" + *   bit.  Note that the {i2c_chip} address specified on the command + *   line is not shifted up: e.g. a typical EEPROM memory chip may have + *   an I2C address of 0x50, but the data put on the bus will be 0xA0 + *   for write and 0xA1 for read.  This "non shifted" address notation + *   matches at least half of the data sheets :-/. + * + * {addr} is the address (or offset) within the chip.  Small memory + *   chips have 8 bit addresses.  Large memory chips have 16 bit + *   addresses.  Other memory chips have 9, 10, or 11 bit addresses. + *   Many non-memory chips have multiple registers and {addr} is used + *   as the register index.  Some non-memory chips have only one register + *   and therefore don't need any {addr} parameter. + * + *   The default {addr} parameter is one byte (.1) which works well for + *   memories and registers with 8 bits of address space. + * + *   You can specify the length of the {addr} field with the optional .0, + *   .1, or .2 modifier (similar to the .b, .w, .l modifier).  If you are + *   manipulating a single register device which doesn't use an address + *   field, use "0.0" for the address and the ".0" length field will + *   suppress the address in the I2C data stream.  This also works for + *   successive reads using the I2C auto-incrementing memory pointer. + * + *   If you are manipulating a large memory with 2-byte addresses, use + *   the .2 address modifier, e.g. 210.2 addresses location 528 (decimal). + * + *   Then there are the unfortunate memory chips that spill the most + *   significant 1, 2, or 3 bits of address into the chip address byte. + *   This effectively makes one chip (logically) look like 2, 4, or + *   8 chips.  This is handled (awkwardly) by #defining + *   CFG_I2C_EEPROM_ADDR_OVERFLOW and using the .1 modifier on the + *   {addr} field (since .1 is the default, it doesn't actually have to + *   be specified).  Examples: given a memory chip at I2C chip address + *   0x50, the following would happen... + *     imd 50 0 10      display 16 bytes starting at 0x000 + *                      On the bus: <S> A0 00 <E> <S> A1 <rd> ... <rd> + *     imd 50 100 10    display 16 bytes starting at 0x100 + *                      On the bus: <S> A2 00 <E> <S> A3 <rd> ... <rd> + *     imd 50 210 10    display 16 bytes starting at 0x210 + *                      On the bus: <S> A4 10 <E> <S> A5 <rd> ... <rd> + *   This is awfully ugly.  It would be nice if someone would think up + *   a better way of handling this. + * + * Adapted from cmd_mem.c which is copyright Wolfgang Denk (wd@denx.de). + */ + +#include <common.h> +#include <command.h> +#include <cmd_i2c.h> +#include <i2c.h> +#include <asm/byteorder.h> + +#if (CONFIG_COMMANDS & CFG_CMD_I2C) + + +/* Display values from last command. + * Memory modify remembered values are different from display memory. + */ +static uchar	i2c_dp_last_chip; +static uint	i2c_dp_last_addr; +static uint	i2c_dp_last_alen; +static uint	i2c_dp_last_length = 0x10; + +static uchar	i2c_mm_last_chip; +static uint	i2c_mm_last_addr; +static uint	i2c_mm_last_alen; + +#if defined(CFG_I2C_NOPROBES) +static uchar i2c_no_probes[] = CFG_I2C_NOPROBES; +#endif + +static int +mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]); +extern int cmd_get_data_size(char* arg, int default_size); + +/* + * Syntax: + *	imd {i2c_chip} {addr}{.0, .1, .2} {len} + */ +#define DISP_LINE_LEN	16 + +int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	u_char	chip; +	uint	addr, alen, length; +	int	j, nbytes, linebytes; + +	/* We use the last specified parameters, unless new ones are +	 * entered. +	 */ +	chip   = i2c_dp_last_chip; +	addr   = i2c_dp_last_addr; +	alen   = i2c_dp_last_alen; +	length = i2c_dp_last_length; + +	if (argc < 3) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	if ((flag & CMD_FLAG_REPEAT) == 0) { +		/* +		 * New command specified. +		 */ +		alen = 1; + +		/* +		 * I2C chip address +		 */ +		chip = simple_strtoul(argv[1], NULL, 16); + +		/* +		 * I2C data address within the chip.  This can be 1 or +		 * 2 bytes long.  Some day it might be 3 bytes long :-). +		 */ +		addr = simple_strtoul(argv[2], NULL, 16); +		alen = 1; +		for(j = 0; j < 8; j++) { +			if (argv[2][j] == '.') { +				alen = argv[2][j+1] - '0'; +				if (alen > 4) { +					printf ("Usage:\n%s\n", cmdtp->usage); +					return 1; +				} +				break; +			} else if (argv[2][j] == '\0') { +				break; +			} +		} + +		/* +		 * If another parameter, it is the length to display. +		 * Length is the number of objects, not number of bytes. +		 */ +		if (argc > 3) +			length = simple_strtoul(argv[3], NULL, 16); +	} + +	/* +	 * Print the lines. +	 * +	 * We buffer all read data, so we can make sure data is read only +	 * once. +	 */ +	nbytes = length; +	do { +		unsigned char	linebuf[DISP_LINE_LEN]; +		unsigned char	*cp; + +		linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; + +		if(i2c_read(chip, addr, alen, linebuf, linebytes) != 0) { +			printf("Error reading the chip.\n"); +		} else { +			printf("%04x:", addr); +			cp = linebuf; +			for (j=0; j<linebytes; j++) { +				printf(" %02x", *cp++); +				addr++; +			} +			printf("    "); +			cp = linebuf; +			for (j=0; j<linebytes; j++) { +				if ((*cp < 0x20) || (*cp > 0x7e)) +					printf("."); +				else +					printf("%c", *cp); +				cp++; +			} +			printf("\n"); +		} +		nbytes -= linebytes; +	} while (nbytes > 0); + +	i2c_dp_last_chip   = chip; +	i2c_dp_last_addr   = addr; +	i2c_dp_last_alen   = alen; +	i2c_dp_last_length = length; + +	return 0; +} + +int do_i2c_mm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	return mod_i2c_mem (cmdtp, 1, flag, argc, argv); +} + + +int do_i2c_nm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	return mod_i2c_mem (cmdtp, 0, flag, argc, argv); +} + +/* Write (fill) memory + * + * Syntax: + *	imw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}] + */ +int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	uchar	chip; +	ulong	addr; +	uint	alen; +	uchar	byte; +	int	count; +	int	j; + +	if ((argc < 4) || (argc > 5)) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	/* + 	 * Chip is always specified. + 	 */ +	chip = simple_strtoul(argv[1], NULL, 16); + +	/* +	 * Address is always specified. +	 */ +	addr = simple_strtoul(argv[2], NULL, 16); +	alen = 1; +	for(j = 0; j < 8; j++) { +		if (argv[2][j] == '.') { +			alen = argv[2][j+1] - '0'; +			if(alen > 4) { +				printf ("Usage:\n%s\n", cmdtp->usage); +				return 1; +			} +			break; +		} else if (argv[2][j] == '\0') { +			break; +		} +	} + +	/* +	 * Value to write is always specified. +	 */ +	byte = simple_strtoul(argv[3], NULL, 16); + +	/* +	 * Optional count +	 */ +	if(argc == 5) { +		count = simple_strtoul(argv[4], NULL, 16); +	} else { +		count = 1; +	} + +	while (count-- > 0) { +		if(i2c_write(chip, addr++, alen, &byte, 1) != 0) { +			printf("Error writing the chip.\n"); +		} +		/* +		 * Wait for the write to complete.  The write can take +		 * up to 10mSec (we allow a little more time). +		 * +		 * On some chips, while the write is in progress, the +		 * chip doesn't respond.  This apparently isn't a +		 * universal feature so we don't take advantage of it. +		 */ +		udelay(11000); +#if 0 +		for(timeout = 0; timeout < 10; timeout++) { +			udelay(2000); +			if(i2c_probe(chip) == 0) +				break; +		} +#endif +	} + +	return (0); +} + + +/* Calculate a CRC on memory + * + * Syntax: + *	icrc32 {i2c_chip} {addr}{.0, .1, .2} {count} + */ +int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	uchar	chip; +	ulong	addr; +	uint	alen; +	int	count; +	uchar	byte; +	ulong	crc; +	ulong	err; +	int	j; + +	if (argc < 4) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	/* + 	 * Chip is always specified. + 	 */ +	chip = simple_strtoul(argv[1], NULL, 16); + +	/* +	 * Address is always specified. +	 */ +	addr = simple_strtoul(argv[2], NULL, 16); +	alen = 1; +	for(j = 0; j < 8; j++) { +		if (argv[2][j] == '.') { +			alen = argv[2][j+1] - '0'; +			if(alen > 4) { +				printf ("Usage:\n%s\n", cmdtp->usage); +				return 1; +			} +			break; +		} else if (argv[2][j] == '\0') { +			break; +		} +	} + +	/* +	 * Count is always specified +	 */ +	count = simple_strtoul(argv[3], NULL, 16); + +	printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1); +	/* +	 * CRC a byte at a time.  This is going to be slooow, but hey, the +	 * memories are small and slow too so hopefully nobody notices. +	 */ +	crc = 0; +	err = 0; +	while(count-- > 0) { +		if(i2c_read(chip, addr, alen, &byte, 1) != 0) { +			err++; +		} +		crc = crc32 (crc, &byte, 1); +		addr++; +	} +	if(err > 0) +	{ +		printf("Error reading the chip,\n"); +	} else { +		printf ("%08lx\n", crc); +	} + +	return 0; +} + + +/* Modify memory. + * + * Syntax: + *	imm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} + *	inm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} + */ + +static int +mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]) +{ +	uchar	chip; +	ulong	addr; +	uint	alen; +	ulong	data; +	int	size = 1; +	int	nbytes; +	int	j; +	extern char console_buffer[]; + +	if (argc != 3) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +#ifdef CONFIG_BOOT_RETRY_TIME +	reset_cmd_timeout();	/* got a good command to get here */ +#endif +	/* +	 * We use the last specified parameters, unless new ones are +	 * entered. +	 */ +	chip = i2c_mm_last_chip; +	addr = i2c_mm_last_addr; +	alen = i2c_mm_last_alen; + +	if ((flag & CMD_FLAG_REPEAT) == 0) { +		/* +		 * New command specified.  Check for a size specification. +		 * Defaults to byte if no or incorrect specification. +		 */ +		size = cmd_get_data_size(argv[0], 1); + +		/* +	 	 * Chip is always specified. +	 	 */ +		chip = simple_strtoul(argv[1], NULL, 16); + +		/* +		 * Address is always specified. +		 */ +		addr = simple_strtoul(argv[2], NULL, 16); +		alen = 1; +		for(j = 0; j < 8; j++) { +			if (argv[2][j] == '.') { +				alen = argv[2][j+1] - '0'; +				if(alen > 4) { +					printf ("Usage:\n%s\n", cmdtp->usage); +					return 1; +				} +				break; +			} else if (argv[2][j] == '\0') { +				break; +			} +		} +	} + +	/* +	 * Print the address, followed by value.  Then accept input for +	 * the next value.  A non-converted value exits. +	 */ +	do { +		printf("%08lx:", addr); +		if(i2c_read(chip, addr, alen, (char *)&data, size) != 0) { +			printf("\nError reading the chip,\n"); +		} else { +			data = cpu_to_be32(data); +			if(size == 1) { +				printf(" %02lx", (data >> 24) & 0x000000FF); +			} else if(size == 2) { +				printf(" %04lx", (data >> 16) & 0x0000FFFF); +			} else { +				printf(" %08lx", data); +			} +		} + +		nbytes = readline (" ? "); +		if (nbytes == 0) { +			/* +			 * <CR> pressed as only input, don't modify current +			 * location and move to next. +			 */ +			if (incrflag) +				addr += size; +			nbytes = size; +#ifdef CONFIG_BOOT_RETRY_TIME +			reset_cmd_timeout(); /* good enough to not time out */ +#endif +		} +#ifdef CONFIG_BOOT_RETRY_TIME +		else if (nbytes == -2) { +			break;	/* timed out, exit the command	*/ +		} +#endif +		else { +			char *endp; + +			data = simple_strtoul(console_buffer, &endp, 16); +			if(size == 1) { +				data = data << 24; +			} else if(size == 2) { +				data = data << 16; +			} +			data = be32_to_cpu(data); +			nbytes = endp - console_buffer; +			if (nbytes) { +#ifdef CONFIG_BOOT_RETRY_TIME +				/* +				 * good enough to not time out +				 */ +				reset_cmd_timeout(); +#endif +				if(i2c_write(chip, addr, alen, (char *)&data, size) != 0) { +					printf("Error writing the chip.\n"); +				} +				if (incrflag) +					addr += size; +			} +		} +	} while (nbytes); + +	chip = i2c_mm_last_chip; +	addr = i2c_mm_last_addr; +	alen = i2c_mm_last_alen; + +	return 0; +} + +/* + * Syntax: + *	iprobe {addr}{.0, .1, .2} + */ +int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	int j; +#if defined(CFG_I2C_NOPROBES) +	int k, skip; +#endif + +	printf("Valid chip addresses:"); +	for(j = 0; j < 128; j++) { +#if defined(CFG_I2C_NOPROBES) +		skip = 0; +		for (k = 0; k < sizeof(i2c_no_probes); k++){ +			if (j == i2c_no_probes[k]){ +				skip = 1; +				break; +			} +		} +		if (skip) +			continue; +#endif +		if(i2c_probe(j) == 0) { +			printf(" %02X", j); +		} +	} +	printf("\n"); + +#if defined(CFG_I2C_NOPROBES) +	puts ("Excluded chip addresses:"); +	for( k = 0; k < sizeof(i2c_no_probes); k++ ) +		printf(" %02X", i2c_no_probes[k] ); +	puts ("\n"); +#endif + +	return 0; +} + + +/* + * Syntax: + *	iloop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}] + *	{length} - Number of bytes to read + *	{delay}  - A DECIMAL number and defaults to 1000 uSec + */ +int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	u_char	chip; +	ulong	alen; +	uint	addr; +	uint	length; +	u_char	bytes[16]; +	int	delay; +	int	j; + +	if (argc < 3) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	/* +	 * Chip is always specified. +	 */ +	chip = simple_strtoul(argv[1], NULL, 16); + +	/* +	 * Address is always specified. +	 */ +	addr = simple_strtoul(argv[2], NULL, 16); +	alen = 1; +	for(j = 0; j < 8; j++) { +		if (argv[2][j] == '.') { +			alen = argv[2][j+1] - '0'; +			if (alen > 4) { +				printf ("Usage:\n%s\n", cmdtp->usage); +				return 1; +			} +			break; +		} else if (argv[2][j] == '\0') { +			break; +		} +	} + +	/* +	 * Length is the number of objects, not number of bytes. +	 */ +	length = 1; +	length = simple_strtoul(argv[3], NULL, 16); +	if(length > sizeof(bytes)) { +		length = sizeof(bytes); +	} + +	/* +	 * The delay time (uSec) is optional. +	 */ +	delay = 1000; +	if (argc > 3) { +		delay = simple_strtoul(argv[4], NULL, 10); +	} +	/* +	 * Run the loop... +	 */ +	while(1) { +		if(i2c_read(chip, addr, alen, bytes, length) != 0) { +			printf("Error reading the chip.\n"); +		} +		udelay(delay); +	} + +	/* NOTREACHED */ +	return 0; +} + + +/* + * The SDRAM command is separately configured because many + * (most?) embedded boards don't use SDRAM DIMMs. + */ +#if (CONFIG_COMMANDS & CFG_CMD_SDRAM) + +/* + * Syntax: + *	sdram {i2c_chip} + */ +int do_sdram  ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	u_char	chip; +	u_char	data[128]; +	u_char	cksum; +	int	j; + +	if (argc < 2) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} +	/* +	 * Chip is always specified. + 	 */ +	chip = simple_strtoul(argv[1], NULL, 16); + +	if(i2c_read(chip, 0, 1, data, sizeof(data)) != 0) { +		printf("No SDRAM Serial Presence Detect found.\n"); +		return 1; +	} + +	cksum = 0; +	for (j = 0; j < 63; j++) { +		cksum += data[j]; +	} +	if(cksum != data[63]) { +		printf ("WARNING: Configuration data checksum failure:\n" +			"  is 0x%02x, calculated 0x%02x\n", +			data[63], cksum); +	} +	printf("SPD data revision            %d.%d\n", +		(data[62] >> 4) & 0x0F, data[62] & 0x0F); +	printf("Bytes used                   0x%02X\n", data[0]); +	printf("Serial memory size           0x%02X\n", 1 << data[1]); +	printf("Memory type                  "); +	switch(data[2]) { +		case 2:  printf("EDO\n");	break; +		case 4:  printf("SDRAM\n");	break; +		default: printf("unknown\n");	break; +	} +	printf("Row address bits             "); +	if((data[3] & 0x00F0) == 0) { +		printf("%d\n", data[3] & 0x0F); +	} else { +		printf("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F); +	} +	printf("Column address bits          "); +	if((data[4] & 0x00F0) == 0) { +		printf("%d\n", data[4] & 0x0F); +	} else { +		printf("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F); +	} +	printf("Module rows                  %d\n", data[5]); +	printf("Module data width            %d bits\n", (data[7] << 8) | data[6]); +	printf("Interface signal levels      "); +	switch(data[8]) { +		case 0:  printf("5.0v/TTL\n");	break; +		case 1:  printf("LVTTL\n");	break; +		case 2:  printf("HSTL 1.5\n");	break; +		case 3:  printf("SSTL 3.3\n");	break; +		case 4:  printf("SSTL 2.5\n");	break; +		default: printf("unknown\n");	break; +	} +	printf("SDRAM cycle time             %d.%d nS\n", +		(data[9] >> 4) & 0x0F, data[9] & 0x0F); +	printf("SDRAM access time            %d.%d nS\n", +		(data[10] >> 4) & 0x0F, data[10] & 0x0F); +	printf("EDC configuration            "); +	switch(data[11]) { +		case 0:  printf("None\n");	break; +		case 1:  printf("Parity\n");	break; +		case 2:  printf("ECC\n");	break; +		default: printf("unknown\n");	break; +	} +	if((data[12] & 0x80) == 0) { +		printf("No self refresh, rate        "); +	} else { +		printf("Self refresh, rate           "); +	} +	switch(data[12] & 0x7F) { +		case 0:  printf("15.625uS\n");	break; +		case 1:  printf("3.9uS\n");	break; +		case 2:  printf("7.8uS\n");	break; +		case 3:  printf("31.3uS\n");	break; +		case 4:  printf("62.5uS\n");	break; +		case 5:  printf("125uS\n");	break; +		default: printf("unknown\n");	break; +	} +	printf("SDRAM width (primary)        %d\n", data[13] & 0x7F); +	if((data[13] & 0x80) != 0) { +		printf("  (second bank)              %d\n", +			2 * (data[13] & 0x7F)); +	} +	if(data[14] != 0) { +		printf("EDC width                    %d\n", +			data[14] & 0x7F); +		if((data[14] & 0x80) != 0) { +			printf("  (second bank)              %d\n", +				2 * (data[14] & 0x7F)); +		} +	} +	printf("Min clock delay, back-to-back random column addresses %d\n", +		data[15]); +	printf("Burst length(s)             "); +	if(data[16] & 0x80) printf(" Page"); +	if(data[16] & 0x08) printf(" 8"); +	if(data[16] & 0x04) printf(" 4"); +	if(data[16] & 0x02) printf(" 2"); +	if(data[16] & 0x01) printf(" 1"); +	printf("\n"); +	printf("Number of banks              %d\n", data[17]); +	printf("CAS latency(s)              "); +	if(data[18] & 0x80) printf(" TBD"); +	if(data[18] & 0x40) printf(" 7"); +	if(data[18] & 0x20) printf(" 6"); +	if(data[18] & 0x10) printf(" 5"); +	if(data[18] & 0x08) printf(" 4"); +	if(data[18] & 0x04) printf(" 3"); +	if(data[18] & 0x02) printf(" 2"); +	if(data[18] & 0x01) printf(" 1"); +	printf("\n"); +	printf("CS latency(s)               "); +	if(data[19] & 0x80) printf(" TBD"); +	if(data[19] & 0x40) printf(" 6"); +	if(data[19] & 0x20) printf(" 5"); +	if(data[19] & 0x10) printf(" 4"); +	if(data[19] & 0x08) printf(" 3"); +	if(data[19] & 0x04) printf(" 2"); +	if(data[19] & 0x02) printf(" 1"); +	if(data[19] & 0x01) printf(" 0"); +	printf("\n"); +	printf("WE latency(s)               "); +	if(data[20] & 0x80) printf(" TBD"); +	if(data[20] & 0x40) printf(" 6"); +	if(data[20] & 0x20) printf(" 5"); +	if(data[20] & 0x10) printf(" 4"); +	if(data[20] & 0x08) printf(" 3"); +	if(data[20] & 0x04) printf(" 2"); +	if(data[20] & 0x02) printf(" 1"); +	if(data[20] & 0x01) printf(" 0"); +	printf("\n"); +	printf("Module attributes:\n"); +	if(!data[21])       printf("  (none)\n"); +	if(data[21] & 0x80) printf("  TBD (bit 7)\n"); +	if(data[21] & 0x40) printf("  Redundant row address\n"); +	if(data[21] & 0x20) printf("  Differential clock input\n"); +	if(data[21] & 0x10) printf("  Registerd DQMB inputs\n"); +	if(data[21] & 0x08) printf("  Buffered DQMB inputs\n"); +	if(data[21] & 0x04) printf("  On-card PLL\n"); +	if(data[21] & 0x02) printf("  Registered address/control lines\n"); +	if(data[21] & 0x01) printf("  Buffered address/control lines\n"); +	printf("Device attributes:\n"); +	if(data[22] & 0x80) printf("  TBD (bit 7)\n"); +	if(data[22] & 0x40) printf("  TBD (bit 6)\n"); +	if(data[22] & 0x20) printf("  Upper Vcc tolerance 5%%\n"); +	else                printf("  Upper Vcc tolerance 10%%\n"); +	if(data[22] & 0x10) printf("  Lower Vcc tolerance 5%%\n"); +	else                printf("  Lower Vcc tolerance 10%%\n"); +	if(data[22] & 0x08) printf("  Supports write1/read burst\n"); +	if(data[22] & 0x04) printf("  Supports precharge all\n"); +	if(data[22] & 0x02) printf("  Supports auto precharge\n"); +	if(data[22] & 0x01) printf("  Supports early RAS# precharge\n"); +	printf("SDRAM cycle time (2nd highest CAS latency)        %d.%d nS\n", +		(data[23] >> 4) & 0x0F, data[23] & 0x0F); +	printf("SDRAM access from clock (2nd highest CAS latency) %d.%d nS\n", +		(data[24] >> 4) & 0x0F, data[24] & 0x0F); +	printf("SDRAM cycle time (3rd highest CAS latency)        %d.%d nS\n", +		(data[25] >> 4) & 0x0F, data[25] & 0x0F); +	printf("SDRAM access from clock (3rd highest CAS latency) %d.%d nS\n", +		(data[26] >> 4) & 0x0F, data[26] & 0x0F); +	printf("Minimum row precharge        %d nS\n", data[27]); +	printf("Row active to row active min %d nS\n", data[28]); +	printf("RAS to CAS delay min         %d nS\n", data[29]); +	printf("Minimum RAS pulse width      %d nS\n", data[30]); +	printf("Density of each row         "); +	if(data[31] & 0x80) printf(" 512MByte"); +	if(data[31] & 0x40) printf(" 256MByte"); +	if(data[31] & 0x20) printf(" 128MByte"); +	if(data[31] & 0x10) printf(" 64MByte"); +	if(data[31] & 0x08) printf(" 32MByte"); +	if(data[31] & 0x04) printf(" 16MByte"); +	if(data[31] & 0x02) printf(" 8MByte"); +	if(data[31] & 0x01) printf(" 4MByte"); +	printf("\n"); +	printf("Command and Address setup    %c%d.%d nS\n", +		(data[32] & 0x80) ? '-' : '+', +		(data[32] >> 4) & 0x07, data[32] & 0x0F); +	printf("Command and Address hold     %c%d.%d nS\n", +		(data[33] & 0x80) ? '-' : '+', +		(data[33] >> 4) & 0x07, data[33] & 0x0F); +	printf("Data signal input setup      %c%d.%d nS\n", +		(data[34] & 0x80) ? '-' : '+', +		(data[34] >> 4) & 0x07, data[34] & 0x0F); +	printf("Data signal input hold       %c%d.%d nS\n", +		(data[35] & 0x80) ? '-' : '+', +		(data[35] >> 4) & 0x07, data[35] & 0x0F); +	printf("Manufacturer's JEDEC ID      "); +	for(j = 64; j <= 71; j++) +		printf("%02X ", data[j]); +	printf("\n"); +	printf("Manufacturing Location       %02X\n", data[72]); +	printf("Manufacturer's Part Number   "); +	for(j = 73; j <= 90; j++) +		printf("%02X ", data[j]); +	printf("\n"); +	printf("Revision Code                %02X %02X\n", data[91], data[92]); +	printf("Manufacturing Date           %02X %02X\n", data[93], data[94]); +	printf("Assembly Serial Number       "); +	for(j = 95; j <= 98; j++) +		printf("%02X ", data[j]); +	printf("\n"); +	printf("Speed rating                 PC%d\n", +		data[126] == 0x66 ? 66 : data[126]); + +	return 0; +} +#endif	/* CFG_CMD_SDRAM */ + +#endif	/* CFG_CMD_I2C */ diff --git a/include/configs/smdk2410.h b/include/configs/smdk2410.h new file mode 100644 index 000000000..8cebbec1f --- /dev/null +++ b/include/configs/smdk2410.h @@ -0,0 +1,173 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * Gary Jennejohn <gj@denx.de> + * David Mueller <d.mueller@elsoft.ch> + * + * Configuation settings for the SAMSUNG SMDK2410 board. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * If we are developing, we might want to start armboot from ram + * so we MUST NOT initialize critical regs like mem-timing ... + */ +#define CONFIG_INIT_CRITICAL		/* undef for developing */ + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_ARM920T		1	/* This is an ARM920T Core	*/ +#define	CONFIG_S3C2410		1	/* in a SAMSUNG S3C2410 SoC     */ +#define CONFIG_SMDK2410		1	/* on a SAMSUNG SMDK2410 Board  */ + +/* input clock of PLL */ +#define CONFIG_PLL_INPUT_FREQ	12000000/* the SMDK2410 has 12MHz input clock */ + + +#define USE_920T_MMU		1 +#undef CONFIG_USE_IRQ			/* we don't need IRQ/FIQ stuff */ + +/* + * Size of malloc() pool + */ +#define CONFIG_MALLOC_SIZE	(CFG_ENV_SIZE + 128*1024) + +/* + * Hardware drivers + */ +#define CONFIG_DRIVER_CS8900	1	/* we have a CS8900 on-board */ +#define CS8900_BASE		0x19000300 +#define CS8900_BUS16		1 /* the Linux driver does accesses as shorts */ + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL1          1	/* we use SERIAL 1 on SMDK2410 */ + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BAUDRATE		115200 + +#ifndef USE_920T_MMU +#define CONFIG_COMMANDS		(CONFIG_CMD_DFL & ~CFG_CMD_CACHE) +#else +#define CONFIG_COMMANDS		(CONFIG_CMD_DFL) +#endif + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +#define CONFIG_BOOTDELAY	3 +/*#define CONFIG_BOOTARGS    	"root=ramfs devfs=mount console=ttySA0,9600" */ +/*#define CONFIG_ETHADDR	08:00:3e:26:0a:5b */ +#define CONFIG_NETMASK          255.255.255.0 +#define CONFIG_IPADDR		10.0.0.110 +#define CONFIG_SERVERIP		10.0.0.1 +/*#define CONFIG_BOOTFILE	"elinos-lart" */ +/*#define CONFIG_BOOTCOMMAND	"tftp; bootm" */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE	115200		/* speed to run kgdb serial port */ +/* what's this ? it's not used anywhere */ +#define CONFIG_KGDB_SER_INDEX	1		/* which serial port to use */ +#endif + +/* + * Miscellaneous configurable options + */ +#define	CFG_LONGHELP				/* undef to save memory		*/ +#define	CFG_PROMPT		"SMDK2410 # "	/* Monitor Command Prompt	*/ +#define	CFG_CBSIZE		256		/* Console I/O Buffer Size	*/ +#define	CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define	CFG_MAXARGS		16		/* max number of command args	*/ +#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size	*/ + +#define CFG_MEMTEST_START	0x30000000	/* memtest works on	*/ +#define CFG_MEMTEST_END		0x33F00000	/* 63 MB in DRAM	*/ + +#undef  CFG_CLKS_IN_HZ		/* everything, incl board info, in Hz */ + +#define	CFG_LOAD_ADDR		0x33000000	/* default load address	*/ + +/* the PWM TImer 4 uses a counter of 15625 for 10 ms, so we need */ +/* it to wrap 100 times (total 1562500) to get 1 sec. */ +#define	CFG_HZ			1562500 + +/* valid baudrates */ +#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 } + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE	(128*1024)	/* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ	(4*1024)	/* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ	(4*1024)	/* FIQ stack */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS	1	   /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1		0x30000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE	0x04000000 /* 64 MB */ + +#define PHYS_FLASH_1		0x00000000 /* Flash Bank #1 */ + +#define CFG_FLASH_BASE		PHYS_FLASH_1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ + +#define CONFIG_AMD_LV400	1	/* uncomment this if you have a LV400 flash */ +#if 0 +#define CONFIG_AMD_LV800	1	/* uncomment this if you have a LV800 flash */ +#endif + +#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks */ +#ifdef CONFIG_AMD_LV800 +#define PHYS_FLASH_SIZE		0x00100000 /* 1MB */ +#define CFG_MAX_FLASH_SECT	(19)	/* max number of sectors on one chip */ +#define CFG_ENV_ADDR		(CFG_FLASH_BASE + 0x0F0000) /* addr of environment */ +#endif +#ifdef CONFIG_AMD_LV400 +#define PHYS_FLASH_SIZE		0x00080000 /* 512KB */ +#define CFG_MAX_FLASH_SECT	(11)	/* max number of sectors on one chip */ +#define CFG_ENV_ADDR		(CFG_FLASH_BASE + 0x070000) /* addr of environment */ +#endif + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT	(5*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT	(5*CFG_HZ) /* Timeout for Flash Write */ + +#define	CFG_ENV_IS_IN_FLASH	1 +#define CFG_ENV_SIZE		0x10000	/* Total Size of Environment Sector */ + +#endif	/* __CONFIG_H */ |