diff options
Diffstat (limited to 'post/board/lwmon5/fpga.c')
| -rw-r--r-- | post/board/lwmon5/fpga.c | 308 | 
1 files changed, 263 insertions, 45 deletions
| diff --git a/post/board/lwmon5/fpga.c b/post/board/lwmon5/fpga.c index 2b842908db2..30675484839 100644 --- a/post/board/lwmon5/fpga.c +++ b/post/board/lwmon5/fpga.c @@ -28,7 +28,7 @@   */  #include <post.h> - +#include <watchdog.h>  #include <asm/io.h>  DECLARE_GLOBAL_DATA_PTR; @@ -38,18 +38,28 @@ DECLARE_GLOBAL_DATA_PTR;  #define FPGA_RAM_START		0xC4200000  #define FPGA_RAM_END		0xC4203FFF  #define FPGA_STAT		0xC400000C +#define FPGA_BUFFER		0x00800000 +#define FPGA_RAM_SIZE		(FPGA_RAM_END - FPGA_RAM_START + 1)  #if CONFIG_POST & CONFIG_SYS_POST_BSPEC3 -/* Testpattern for fpga memorytest */ -static uint pattern[] = { +const static unsigned long pattern[] = { +	0xffffffff, +	0xaaaaaaaa, +	0xcccccccc, +	0xf0f0f0f0, +	0xff00ff00, +	0xffff0000, +	0x0000ffff, +	0x00ff00ff, +	0x0f0f0f0f, +	0x33333333,  	0x55555555, -	0xAAAAAAAA, -	0xAA5555AA, -	0x55AAAA55, -	0x0 +	0x00000000,  }; +const static unsigned long otherpattern = 0x01234567; +  static int one_scratch_test(uint value)  {  	uint read_value; @@ -62,51 +72,226 @@ static int one_scratch_test(uint value)  	read_value = in_be32((void *)FPGA_SCRATCH_REG);  	if (read_value != value) {  		post_log("FPGA SCRATCH test failed write %08X, read %08X\n", -			value, read_value); -		ret = 1; +			 value, read_value); +		ret = -1; +	} + +	return ret; +} + +static int fpga_post_test1(ulong *start, ulong size, ulong val) +{ +	int ret = 0; +	ulong i = 0; +	ulong *mem = start; +	ulong readback; + +	for (i = 0; i < size / sizeof(ulong); i++) { +		mem[i] = val; +		if (i % 1024 == 0) +			WATCHDOG_RESET(); +	} + +	for (i = 0; i < size / sizeof(ulong); i++) { +		readback = mem[i]; +		if (readback != val) { +			post_log("FPGA Memory error at %08x, " +				 "wrote %08x, read %08x !\n", +				 mem + i, val, readback); +			ret = -1; +			break; +		} +		if (i % 1024 == 0) +			WATCHDOG_RESET(); +	} +	return ret; +} + +static int fpga_post_test2(ulong *start, ulong size) +{ +	int ret = 0; +	ulong i = 0; +	ulong *mem = start; +	ulong readback; + +	for (i = 0; i < size / sizeof(ulong); i++) { +		mem[i] = 1 << (i % 32); +		if (i % 1024 == 0) +			WATCHDOG_RESET(); +	} + +	for (i = 0; i < size / sizeof(ulong); i++) { +		readback = mem[i]; +		if (readback != 1 << (i % 32)) { +			post_log("FPGA Memory error at %08x, " +				 "wrote %08x, read %08x !\n", +				 mem + i, 1 << (i % 32), readback); +			ret = -1; +			break; +		} +		if (i % 1024 == 0) +			WATCHDOG_RESET(); +	} + +	return ret; +} + +static int fpga_post_test3(ulong *start, ulong size) +{ +	int ret = 0; +	ulong i = 0; +	ulong *mem = start; +	ulong readback; + +	for (i = 0; i < size / sizeof(ulong); i++) { +		mem[i] = i; +		if (i % 1024 == 0) +			WATCHDOG_RESET(); +	} + +	for (i = 0; i < size / sizeof(ulong); i++) { +		readback = mem[i]; +		if (readback != i) { +			post_log("FPGA Memory error at %08x, " +				 "wrote %08x, read %08x !\n", +				 mem + i, i, readback); +			ret = -1; +			break; +		} +		if (i % 1024 == 0) +			WATCHDOG_RESET(); +	} + +	return ret; +} + +static int fpga_post_test4(ulong *start, ulong size) +{ +	int ret = 0; +	ulong i = 0; +	ulong *mem = start; +	ulong readback; + +	for (i = 0; i < size / sizeof(ulong); i++) { +		mem[i] = ~i; +		if (i % 1024 == 0) +			WATCHDOG_RESET(); +	} + +	for (i = 0; i < size / sizeof(ulong); i++) { +		readback = mem[i]; +		if (readback != ~i) { +			post_log("FPGA Memory error at %08x, " +				 "wrote %08x, read %08x !\n", +				 mem + i, ~i, readback); +			ret = -1; +			break; +		} +		if (i % 1024 == 0) +			WATCHDOG_RESET();  	}  	return ret;  }  /* FPGA Memory-pattern-test */ -static int fpga_mem_test(void * address) +static int fpga_mem_test(void)  { -	int ret = 1; -	uint read_value; -	uint old_value; -	uint i = 0; -	/* save content */ -	old_value = in_be32(address); - -	while (pattern[i] != 0) { -		out_be32(address, pattern[i]); -		/* read other location (protect against data lines capacity) */ -		ret = in_be16((void *)FPGA_VERSION_REG); -		/* verify test pattern */ -		read_value = in_be32(address); - -		if (read_value != pattern[i]) { -			post_log("FPGA Memory test failed."); -			post_log(" write %08X, read %08X at address %08X\n", -				pattern[i], read_value, address); +	int ret = 0; +	ulong* start = (ulong *)FPGA_RAM_START; +	ulong  size  = FPGA_RAM_SIZE; + +	if (ret == 0) +		ret = fpga_post_test1(start, size, 0x00000000); + +	if (ret == 0) +		ret = fpga_post_test1(start, size, 0xffffffff); + +	if (ret == 0) +		ret = fpga_post_test1(start, size, 0x55555555); + +	if (ret == 0) +		ret = fpga_post_test1(start, size, 0xaaaaaaaa); + +	WATCHDOG_RESET(); + +	if (ret == 0) +		ret = fpga_post_test2(start, size); + +	if (ret == 0) +		ret = fpga_post_test3(start, size); + +	if (ret == 0) +		ret = fpga_post_test4(start, size); + +	return ret; +} + + + +/* Verify FPGA addresslines */ +static int fpga_post_addrline(ulong *address, ulong *base, ulong size) +{ +	unsigned long *target; +	unsigned long *end; +	unsigned long readback; +	unsigned long xor; +	int ret = 0; + +	end = (ulong *)((ulong)base + size); +	xor = 0; + +	for (xor = sizeof(ulong); xor > 0; xor <<= 1) { +		target = (ulong*)((ulong)address ^ xor); +		if ((target >= base) && (target < end)) { +			*address = ~*target; +			readback = *target; + +			if (readback == *address) { +				post_log("Memory (address line) error at %08x" +					 "XOR value %08x !\n", +					 address, target, xor); +				ret = -1; +				break; +			} +		} +	} + +	return ret; +} + +/* Verify FPGA addresslines */ +static int fpga_post_dataline(ulong *address) +{ +	unsigned long temp32 = 0; +	int i = 0; +	int ret = 0; + +	for (i = 0; i < ARRAY_SIZE(pattern); i++) { +		*address = pattern[i]; +		/* +		 * Put a different pattern on the data lines: otherwise they +		 * may float long enough to read back what we wrote. +		 */ +		*(address + 1) = otherpattern; +		temp32 = *address; + +		if (temp32 != pattern[i]){ +			post_log("Memory (date line) error at %08x, " +				 "wrote %08x, read %08x !\n", +				 address, pattern[i], temp32);  			ret = 1; -			goto out;  		} -		i++;  	} -	ret = 0; -out: -	out_be32(address, old_value);  	return ret;  } +  /* Verify FPGA, get version & memory size */  int fpga_post_test(int flags)  { -	uint   address;  	uint   old_value; -	ushort version; +	uint   version;  	uint   read_value;  	int    ret = 0; @@ -120,24 +305,57 @@ int fpga_post_test(int flags)  	out_be32((void *)FPGA_SCRATCH_REG, old_value); -	version = in_be16((void *)FPGA_VERSION_REG); -	post_log("FPGA : version %u.%u\n", -		(version >> 8) & 0xFF, version & 0xFF); +	version = in_be32((void *)FPGA_VERSION_REG); +	post_log("FPGA version %u.%u\n", +		 (version >> 8) & 0xFF, version & 0xFF);  	/* Enable write to FPGA RAM */  	out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) | 0x1000); -	read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, 0x4000); -	post_log("FPGA RAM size: %d bytes\n", read_value); +	/* get RAM size */ +	read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, FPGA_RAM_SIZE); +	post_log("FPGA RAM size %d bytes\n", read_value); +	WATCHDOG_RESET(); -	for (address = 0; address < 0x1000; address++) { -		if (fpga_mem_test((void *)(FPGA_RAM_START + 4*address)) == 1) { -			ret = 1; -			goto out; -		} +	/* copy fpga memory to DDR2 RAM*/ +	memcpy((void *)FPGA_BUFFER,(void *)FPGA_RAM_START, FPGA_RAM_SIZE); +	WATCHDOG_RESET(); + +	/* Test datalines */ +	if (fpga_post_dataline((ulong *)FPGA_RAM_START)) { +		ret = 1; +		goto out; +	} +	WATCHDOG_RESET(); + +	/* Test addresslines */ +	if (fpga_post_addrline((ulong *)FPGA_RAM_START, +			       (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) { +		ret = 1; +		goto out;  	} +	WATCHDOG_RESET(); +	if (fpga_post_addrline((ulong *)FPGA_RAM_END - sizeof(long), +			       (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) { +		ret = 1; +		goto out; +	} +	WATCHDOG_RESET(); + +	/* Memory Pattern Test */ +	if (fpga_mem_test()) { +		ret = 1; +		goto out; +	} +	WATCHDOG_RESET(); + +	/* restore memory */ +	memcpy((void *)FPGA_RAM_START,(void *)FPGA_BUFFER, FPGA_RAM_SIZE); +	WATCHDOG_RESET();  out: +	/* Disable write to RAM */ +	out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) & 0xEFFF);  	return ret;  } | 
