[U-Boot-Users] [PATCH V2] PPC4xx: Unify ECC Initialization Routines
Stefan Roese
sr at denx.de
Mon May 19 08:10:12 CEST 2008
On Saturday 17 May 2008, Grant Erickson wrote:
> This patch continues laying the ground work for moving out-of-assembly
> and unifying the SDRAM initialization code for PowerPC 405EX[r]-based
> boards.
>
> To do so, this deduces by one the number of nearly-identical DRAM ECC
> initialization implementations for PowerPC 4xx processors utilizing a
> DDR/DDR2 SDRAM controller by merging two of them into a common, shared
> implementation.
Good idea. Thanks. Please find some comments below.
> The last revision of this patch failed to compile on 440ERX/GPX
> systems, so the appropriate preprocessor wrappers were added to
> address it.
>
> Signed-off-by: Grant Erickson <gerickson at nuovations.com>
> ---
> cpu/ppc4xx/44x_spd_ddr.c | 51 ++------------------
> cpu/ppc4xx/Makefile | 1 +
> cpu/ppc4xx/ecc.c | 119
> ++++++++++++++++++++++++++++++++++++++++++++++ cpu/ppc4xx/ecc.h |
> 42 ++++++++++++++++
> cpu/ppc4xx/sdram.c | 46 +-----------------
> 5 files changed, 170 insertions(+), 89 deletions(-)
> create mode 100644 cpu/ppc4xx/ecc.c
> create mode 100644 cpu/ppc4xx/ecc.h
>
> diff --git a/cpu/ppc4xx/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c
> index b9cf5cb..7f04ca6 100644
> --- a/cpu/ppc4xx/44x_spd_ddr.c
> +++ b/cpu/ppc4xx/44x_spd_ddr.c
> @@ -53,6 +53,10 @@
> #include <ppc4xx.h>
> #include <asm/mmu.h>
>
> +#ifdef CONFIG_DDR_ECC
> +#include "ecc.h"
> +#endif
It should be save to include this header unconditionally. Please remove the
#ifdef here.
> #if defined(CONFIG_SPD_EEPROM) && \
> (defined(CONFIG_440GP) || defined(CONFIG_440GX) || \
> defined(CONFIG_440EP) || defined(CONFIG_440GR))
> @@ -296,10 +300,6 @@ static void program_tr0(unsigned long *dimm_populated,
> unsigned long num_dimm_banks);
> static void program_tr1(void);
>
> -#ifdef CONFIG_DDR_ECC
> -static void program_ecc(unsigned long num_bytes);
> -#endif
> -
> static unsigned long program_bxcr(unsigned long *dimm_populated,
> unsigned char *iic0_dimm_addr,
> unsigned long num_dimm_banks);
> @@ -418,7 +418,7 @@ long int spd_sdram(void) {
> /*
> * If ecc is enabled, initialize the parity bits.
> */
> - program_ecc(total_size);
> + ecc_init(CFG_SDRAM_BASE, total_size);
> #endif
>
> return total_size;
> @@ -1402,45 +1402,4 @@ static unsigned long program_bxcr(unsigned long
> *dimm_populated,
>
> return(bank_base_addr);
> }
> -
> -#ifdef CONFIG_DDR_ECC
> -static void program_ecc(unsigned long num_bytes)
> -{
> - unsigned long bank_base_addr;
> - unsigned long current_address;
> - unsigned long end_address;
> - unsigned long address_increment;
> - unsigned long cfg0;
> -
> - /*
> - * get Memory Controller Options 0 data
> - */
> - mfsdram(mem_cfg0, cfg0);
> -
> - /*
> - * reset the bank_base address
> - */
> - bank_base_addr = CFG_SDRAM_BASE;
> -
> - if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) {
> - mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_GEN);
> -
> - if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32)
> - address_increment = 4;
> - else
> - address_increment = 8;
> -
> - current_address = (unsigned long)(bank_base_addr);
> - end_address = (unsigned long)(bank_base_addr) + num_bytes;
> -
> - while (current_address < end_address) {
> - *((unsigned long*)current_address) = 0x00000000;
> - current_address += address_increment;
> - }
> -
> - mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |
> - SDRAM_CFG0_MCHK_CHK);
> - }
> -}
> -#endif /* CONFIG_DDR_ECC */
> #endif /* CONFIG_SPD_EEPROM */
> diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
> index 178c5c6..800bb41 100644
> --- a/cpu/ppc4xx/Makefile
> +++ b/cpu/ppc4xx/Makefile
> @@ -45,6 +45,7 @@ COBJS += cpu.o
> COBJS += cpu_init.o
> COBJS += denali_data_eye.o
> COBJS += denali_spd_ddr2.o
> +COBJS += ecc.o
> COBJS += fdt.o
> COBJS += gpio.o
> COBJS += i2c.o
> diff --git a/cpu/ppc4xx/ecc.c b/cpu/ppc4xx/ecc.c
> new file mode 100644
> index 0000000..dd45b50
> --- /dev/null
> +++ b/cpu/ppc4xx/ecc.c
> @@ -0,0 +1,119 @@
> +/*
> + * Copyright (c) 2008 Nuovation System Designs, LLC
> + * Grant Erickson <gerickson at nuovations.com>
> + *
> + * Copyright (c) 2005-2007 DENX Software Engineering, GmbH
> + * Stefan Roese <sr at denx.de>
> + *
> + * Copyright (c) 2002 Artesyn Technology
> + * Jun Gu <jung at artesyncp.com>
> + *
> + * Copyright (c) 2001 Wave 7 Optics
> + * Bill Hunter <williamhunter at attbi.com>x
> + *
> + * 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 abe 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
> + *
> + * Description:
> + * This file implements generic DRAM ECC initialization for
> + * PowerPC processors using a SDRAM DDR/DDR2 controller,
> + * including the 405EX(r), 440GP/GX/EP/GR, 440SP(E), and
> + * 460EX/GT.
> + */
> +
> +#include <common.h>
> +#include <ppc4xx.h>
> +#include <ppc_asm.tmpl>
> +#include <ppc_defs.h>
> +#include <asm/processor.h>
> +
> +#include "ecc.h"
> +
> +#if !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
> +#if defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC)
> +/*
> + * void ecc_init()
> + *
> + * Description:
> + * This routine initializes a range of DRAM ECC memory with known
> + * data and enables ECC checking.
> + *
> + * TO DO:
> + * Improve performance by utilizing cache.
Yes. And please add something like this here:
* Make is more generally usable for other 4xx PPC variants (like 440EPx...).
> + *
> + * Input(s):
> + * start - A pointer to the start of memory covered by ECC requiring
> + * initialization.
> + * size - The size, in bytes, of the memory covered by ECC requiring
> + * initialization.
> + *
> + * Output(s):
> + * start - A pointer to the start of memory covered by ECC with
> + * CFG_ECC_PATTERN written to all locations and ECC data
> + * primed.
> + *
> + * Returns:
> + * N/A
> + */
> +void ecc_init(unsigned long * const start, unsigned long size)
> +{
> + const unsigned long pattern = CFG_ECC_PATTERN;
> + unsigned * const end = (unsigned long * const)((long)start + size);
> + unsigned long * current = start;
> + unsigned long mcopt1;
> + long increment;
> +
> + if (start >= end)
> + return;
> +
> + mfsdram(SDRAM_MCOPT1, mcopt1);
> +
> + /* Enable ECC generation without checking or reporting */
> +
> + mtsdram(SDRAM_MCOPT1, ((mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) |
> + SDRAM_MCOPT1_MCHK_GEN));
> +
> + increment = sizeof(u32);
> +
> +#if defined(CONFIG_440)
> + /*
> + * Look at the geometry of SDRAM (data width) to determine whether we
> + * can skip words when writing.
> + */
> +
> + if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) != SDRAM_MCOPT1_DMWD_32)
> + increment = sizeof(u64);
> +#endif /* defined(CONFIG_440) */
> +
> + while (current < end) {
> + *current = pattern;
> + current = (unsigned long *)((long)current + increment);
> + }
> +
> + /* Wait until the writes are finished. */
> +
> + sync();
> + eieio();
Please drop the eieio(). It's not needed since we have the sync().
> + /* Enable ECC generation with checking and no reporting */
> +
> + mtsdram(SDRAM_MCOPT1, ((mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) |
> + SDRAM_MCOPT1_MCHK_CHK));
> +}
> +#endif /* defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) */
> +#endif /* !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX) */
> diff --git a/cpu/ppc4xx/ecc.h b/cpu/ppc4xx/ecc.h
> new file mode 100644
> index 0000000..da1c4fd
> --- /dev/null
> +++ b/cpu/ppc4xx/ecc.h
> @@ -0,0 +1,42 @@
> +/*
> + * Copyright (c) 2008 Nuovation System Designs, LLC
> + * Grant Erickson <gerickson at nuovations.com>
> + *
> + * Copyright (c) 2007 DENX Software Engineering, GmbH
> + * Stefan Roese <sr at 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 abe 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
> + *
> + * Description:
> + * This file implements ECC initialization for PowerPC processors
> + * using the SDRAM DDR2 controller, including the 405EX(r),
> + * 440SP(E), 460EX and 460GT.
> + *
> + */
> +
> +#ifndef _ECC_H_
> +#define _ECC_H_
> +
> +#if !defined(CFG_ECC_PATTERN)
> +#define CFG_ECC_PATTERN 0x00000000
> +#endif /* !defined(CFG_ECC_PATTERN) */
> +
> +extern void ecc_init(unsigned long * const start, unsigned long size);
> +
> +#endif /* _ECC_H_ */
> diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c
> index 2724d91..bd0a827 100644
> --- a/cpu/ppc4xx/sdram.c
> +++ b/cpu/ppc4xx/sdram.c
> @@ -31,6 +31,9 @@
> #include <ppc4xx.h>
> #include <asm/processor.h>
> #include "sdram.h"
> +#ifdef CONFIG_SDRAM_ECC
> +#include "ecc.h"
> +#endif
Again, please make it unconditional.
Thanks a lot.
Best regards,
Stefan
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================
More information about the U-Boot
mailing list