1/* 2 * (C) Copyright 2008 Ilya Yanok, EmCraft Systems, yanok@emcraft.com 3 * 4 * Developed for DENX Software Engineering GmbH 5 * 6 * See file CREDITS for list of people who contributed to this 7 * project. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of 12 * the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22 * MA 02111-1307 USA 23 */ 24#include <common.h> 25 26/* 27 * This test attempts to verify on-chip memory (OCM). Result is written 28 * to the scratch register and if test succeed it won't be run till next 29 * power on. 30 */ 31 32#include <post.h> 33 34#include <asm/io.h> 35 36DECLARE_GLOBAL_DATA_PTR; 37 38#define OCM_TEST_PATTERN1 0x55555555 39#define OCM_TEST_PATTERN2 0xAAAAAAAA 40 41#if CONFIG_POST & CONFIG_SYS_POST_OCM 42 43static uint ocm_status_read(void) 44{ 45 return in_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR) & 46 CONFIG_SYS_OCM_STATUS_MASK; 47} 48 49static void ocm_status_write(uint value) 50{ 51 out_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR, value | 52 (in_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR) & 53 ~CONFIG_SYS_OCM_STATUS_MASK)); 54} 55 56static inline int ocm_test_word(uint value, uint *address) 57{ 58 uint read_value; 59 60 *address = value; 61 sync(); 62 read_value = *address; 63 64 return (read_value != value); 65} 66 67int ocm_post_test(int flags) 68{ 69 uint old_value; 70 int ret = 0; 71 uint *address = (uint*)CONFIG_SYS_OCM_BASE; 72 73 if (ocm_status_read() == CONFIG_SYS_OCM_STATUS_OK) 74 return 0; 75 for (; address < (uint*)(CONFIG_SYS_OCM_BASE + CONFIG_SYS_OCM_SIZE); address++) { 76 old_value = *address; 77 if (ocm_test_word(OCM_TEST_PATTERN1, address) || 78 ocm_test_word(OCM_TEST_PATTERN2, address)) { 79 ret = 1; 80 *address = old_value; 81 printf("OCM POST failed at %p!\n", address); 82 break; 83 } 84 *address = old_value; 85 } 86 ocm_status_write(ret ? CONFIG_SYS_OCM_STATUS_FAIL : CONFIG_SYS_OCM_STATUS_OK); 87 return ret; 88} 89#endif /* CONFIG_POST & CONFIG_SYS_POST_OCM */ 90