74 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * (C) Copyright 2008 Ilya Yanok, EmCraft Systems, yanok@emcraft.com
 | |
|  *
 | |
|  * Developed for DENX Software Engineering GmbH
 | |
|  *
 | |
|  * SPDX-License-Identifier:	GPL-2.0+
 | |
|  */
 | |
| #include <common.h>
 | |
| 
 | |
| /*
 | |
|  * This test attempts to verify on-chip memory (OCM). Result is written
 | |
|  * to the scratch register and if test succeed it won't be run till next
 | |
|  * power on.
 | |
|  */
 | |
| 
 | |
| #include <post.h>
 | |
| 
 | |
| #include <asm/io.h>
 | |
| 
 | |
| DECLARE_GLOBAL_DATA_PTR;
 | |
| 
 | |
| #define OCM_TEST_PATTERN1	0x55555555
 | |
| #define OCM_TEST_PATTERN2	0xAAAAAAAA
 | |
| 
 | |
| #if CONFIG_POST & CONFIG_SYS_POST_OCM
 | |
| 
 | |
| static uint ocm_status_read(void)
 | |
| {
 | |
| 	return in_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR) &
 | |
| 		CONFIG_SYS_OCM_STATUS_MASK;
 | |
| }
 | |
| 
 | |
| static void ocm_status_write(uint value)
 | |
| {
 | |
| 	out_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR, value |
 | |
| 		(in_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR) &
 | |
| 			~CONFIG_SYS_OCM_STATUS_MASK));
 | |
| }
 | |
| 
 | |
| static inline int ocm_test_word(uint value, uint *address)
 | |
| {
 | |
| 	uint read_value;
 | |
| 
 | |
| 	*address = value;
 | |
| 	sync();
 | |
| 	read_value = *address;
 | |
| 
 | |
| 	return (read_value != value);
 | |
| }
 | |
| 
 | |
| int ocm_post_test(int flags)
 | |
| {
 | |
| 	uint   old_value;
 | |
| 	int    ret = 0;
 | |
| 	uint  *address = (uint*)CONFIG_SYS_OCM_BASE;
 | |
| 
 | |
| 	if (ocm_status_read() == CONFIG_SYS_OCM_STATUS_OK)
 | |
| 		return 0;
 | |
| 	for (; address < (uint*)(CONFIG_SYS_OCM_BASE + CONFIG_SYS_OCM_SIZE); address++) {
 | |
| 		old_value = *address;
 | |
| 		if (ocm_test_word(OCM_TEST_PATTERN1, address) ||
 | |
| 				ocm_test_word(OCM_TEST_PATTERN2, address)) {
 | |
| 			ret = 1;
 | |
| 			*address = old_value;
 | |
| 			printf("OCM POST failed at %p!\n", address);
 | |
| 			break;
 | |
| 		}
 | |
| 		*address = old_value;
 | |
| 	}
 | |
| 	ocm_status_write(ret ? CONFIG_SYS_OCM_STATUS_FAIL : CONFIG_SYS_OCM_STATUS_OK);
 | |
| 	return ret;
 | |
| }
 | |
| #endif /* CONFIG_POST & CONFIG_SYS_POST_OCM */
 |