--- post/cpu/mpc83xx/Makefile | 30 +++++++++ post/cpu/mpc83xx/ecc.c | 160 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 0 deletions(-) create mode 100644 post/cpu/mpc83xx/Makefile create mode 100644 post/cpu/mpc83xx/ecc.c
diff --git a/post/cpu/mpc83xx/Makefile b/post/cpu/mpc83xx/Makefile new file mode 100644 index 0000000..86d8784 --- /dev/null +++ b/post/cpu/mpc83xx/Makefile @@ -0,0 +1,30 @@ +# +# (C) Copyright 2002-2007 +# Wolfgang Denk, DENX Software Engineering, w...@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +include $(OBJTREE)/include/autoconf.mk + +LIB = libpostmpc83xx.a + +AOBJS-$(CONFIG_HAS_POST) += +COBJS-$(CONFIG_HAS_POST) += ecc.o + +include $(TOPDIR)/post/rules.mk diff --git a/post/cpu/mpc83xx/ecc.c b/post/cpu/mpc83xx/ecc.c new file mode 100644 index 0000000..83dfcf6 --- /dev/null +++ b/post/cpu/mpc83xx/ecc.c @@ -0,0 +1,160 @@ +/* + * (C) Copyright 2010 + * Eastman Kodak Company, <www.kodak.com> + * Michael Zaidman, <michael.zaid...@kodak.com> + * + * The code is based on the cpu/mpc83xx/ecc.c written by + * Dave Liu <dave...@freescale.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <mpc83xx.h> +#include <post.h> +#include <watchdog.h> + +#if CONFIG_POST & CONFIG_SYS_POST_ECC + +inline static void ecc_clear(volatile ddr83xx_t *ddr) +{ + /* clear capture registers */ + ddr->capture_address = 0; + ddr->capture_data_hi = 0; + ddr->capture_data_lo = 0; + ddr->capture_ecc = 0; + ddr->capture_attributes = 0; + + /* Clear SBEC and set SBET to 1 */ + ddr->err_sbe = (1 << ECC_ERROR_MAN_SBET_SHIFT); + + /* Clear Error Detect register */ + ddr->err_detect = (ECC_ERROR_DETECT_MME | + ECC_ERROR_DETECT_MBE | + ECC_ERROR_DETECT_SBE | + ECC_ERROR_DETECT_MSE); + + __asm__ __volatile__("sync"); + __asm__ __volatile__("isync"); +} + +int ecc_post_test(int flags) +{ + int ret = 0; + int int_state; + int errbit; + u32 pattern[2], writeback[2], retval[2]; + volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; + volatile ddr83xx_t *ddr = &immap->ddr; + volatile u64 * addr = (u64 *)CONFIG_SYS_POST_ECC_START_ADDR; + + /* The pattern is written into memory to generate error */ + pattern[0] = 0xfedcba98UL; + pattern[1] = 0x76543210UL; + + /* After injecting error, re-initialize the memory with the value */ + writeback[0] = ~pattern[0]; + writeback[1] = ~pattern[1]; + + /* Check if ECC is enabled */ + if (ddr->err_disable & ECC_ERROR_ENABLE) { + debug("DDR's ECC is not enabled, skipping the ECC POST.\n"); + return 0; + } + + int_state = disable_interrupts(); + + icache_enable(); + +#ifdef CONFIG_DDR_32BIT + /* It seems like no one really uses the CONFIG_DDR_32BIT mode */ +#error "Add the ECC POST support for CONFIG_DDR_32BIT here." +#else + for (addr = (u64 *)CONFIG_SYS_POST_ECC_START_ADDR, errbit = 0; + addr < (u64 *)CONFIG_SYS_POST_ECC_STOP_ADDR; addr++, errbit++) { + + WATCHDOG_RESET(); + + /* Test for correctable error by creating a one-bit error */ + ecc_clear(ddr); + + /* enable injects */ + ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN; + + /* Inject single bit error */ + if (errbit < 32) { + ddr->data_err_inject_lo = 1 << errbit; + ddr->data_err_inject_hi = 0; + } + else { + ddr->data_err_inject_lo = 0; + ddr->data_err_inject_hi = 1 << (errbit-32); + } + __asm__ __volatile__("sync"); + __asm__ __volatile__("isync"); + + /* write memory location injecting error */ + ppcDWstore((u32*)addr, pattern); + __asm__ __volatile__("sync"); + + /* disable injects */ + ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN; + __asm__ __volatile__("sync"); + __asm__ __volatile__("isync"); + + /* read data, this generates ECC error */ + ppcDWload((u32*)addr, retval); + __asm__ __volatile__("sync"); + + if (!(ddr->err_detect & ECC_ERROR_DETECT_SBE) || + ((pattern[0] ^ ddr->capture_data_hi) != + ddr->data_err_inject_hi) || + ((pattern[1] ^ ddr->capture_data_lo) != + ddr->data_err_inject_lo)) { + + post_log("ECC failed to detect SBE error at %08x, " + "SBE injection mask %08x-%08x, " + "wrote %08x-%08x, read %08x-%08x\n", addr, + ddr->data_err_inject_hi, ddr->data_err_inject_lo, + pattern[0], pattern[1], retval[0], retval[1]); + debug("ERR_DETECT Reg: %08x\n", ddr->err_detect); + debug("ECC CAPTURE_DATA Reg: %08x-%08x\n", + ddr->capture_data_hi, ddr->capture_data_lo); + ret = 1; + break; + } + + /* re-initialize the ECC memory */ + ppcDWstore((u32*)addr, writeback); + __asm__ __volatile__("sync"); + + errbit %= 63; + } +#endif /* !CONFIG_DDR_32BIT */ + + ecc_clear(ddr); + + icache_disable(); + + if (int_state) + enable_interrupts(); + + return ret; +} +#endif -- 1.6.3.3 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot