uboot/post/cpu/ppc4xx/ocm.c
<<
>>
Prefs
   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