1/* 2 * (C) Copyright 2008 Ilya Yanok, EmCraft Systems, yanok@emcraft.com 3 * 4 * Developed for DENX Software Engineering GmbH 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8#include <common.h> 9 10/* 11 * This test attempts to verify on-chip memory (OCM). Result is written 12 * to the scratch register and if test succeed it won't be run till next 13 * power on. 14 */ 15 16#include <post.h> 17 18#include <asm/io.h> 19 20DECLARE_GLOBAL_DATA_PTR; 21 22#define OCM_TEST_PATTERN1 0x55555555 23#define OCM_TEST_PATTERN2 0xAAAAAAAA 24 25#if CONFIG_POST & CONFIG_SYS_POST_OCM 26 27static uint ocm_status_read(void) 28{ 29 return in_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR) & 30 CONFIG_SYS_OCM_STATUS_MASK; 31} 32 33static void ocm_status_write(uint value) 34{ 35 out_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR, value | 36 (in_be32((void *)CONFIG_SYS_OCM_STATUS_ADDR) & 37 ~CONFIG_SYS_OCM_STATUS_MASK)); 38} 39 40static inline int ocm_test_word(uint value, uint *address) 41{ 42 uint read_value; 43 44 *address = value; 45 sync(); 46 read_value = *address; 47 48 return (read_value != value); 49} 50 51int ocm_post_test(int flags) 52{ 53 uint old_value; 54 int ret = 0; 55 uint *address = (uint*)CONFIG_SYS_OCM_BASE; 56 57 if (ocm_status_read() == CONFIG_SYS_OCM_STATUS_OK) 58 return 0; 59 for (; address < (uint*)(CONFIG_SYS_OCM_BASE + CONFIG_SYS_OCM_SIZE); address++) { 60 old_value = *address; 61 if (ocm_test_word(OCM_TEST_PATTERN1, address) || 62 ocm_test_word(OCM_TEST_PATTERN2, address)) { 63 ret = 1; 64 *address = old_value; 65 printf("OCM POST failed at %p!\n", address); 66 break; 67 } 68 *address = old_value; 69 } 70 ocm_status_write(ret ? CONFIG_SYS_OCM_STATUS_FAIL : CONFIG_SYS_OCM_STATUS_OK); 71 return ret; 72} 73#endif /* CONFIG_POST & CONFIG_SYS_POST_OCM */ 74