
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.
Signed-off-by: Grant Erickson gerickson@nuovations.com --- cpu/ppc4xx/44x_spd_ddr.c | 51 ++------------------ cpu/ppc4xx/Makefile | 1 + cpu/ppc4xx/ecc.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++ cpu/ppc4xx/ecc.h | 42 ++++++++++++++++ cpu/ppc4xx/sdram.c | 46 +----------------- 5 files changed, 168 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 + #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..a7755bf --- /dev/null +++ b/cpu/ppc4xx/ecc.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2008 Nuovation System Designs, LLC + * Grant Erickson gerickson@nuovations.com + * + * Copyright (c) 2005-2007 DENX Software Engineering, GmbH + * Stefan Roese sr@denx.de + * + * Copyright (c) 2002 Artesyn Technology + * Jun Gu jung@artesyncp.com + * + * Copyright (c) 2001 Wave 7 Optics + * Bill Hunter williamhunter@attbi.comx + * + * 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_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. + * + * 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(); + + /* 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) */ 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@nuovations.com + * + * Copyright (c) 2007 DENX Software Engineering, GmbH + * Stefan Roese sr@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
#ifdef CONFIG_SDRAM_BANK0
@@ -332,49 +335,6 @@ static void sdram_tr1_set(int ram_address, int* tr1_value) *tr1_value = (first_good + last_bad) / 2; }
-#ifdef CONFIG_SDRAM_ECC -static void ecc_init(ulong start, ulong size) -{ - ulong current_addr; /* current byte address */ - ulong end_addr; /* end of memory region */ - ulong addr_inc; /* address skip between writes */ - ulong cfg0_reg; /* for restoring ECC state */ - - /* - * TODO: Enable dcache before running this test (speedup) - */ - - mfsdram(mem_cfg0, cfg0_reg); - mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_GEN); - - /* - * look at geometry of SDRAM (data width) to determine whether we - * can skip words when writing - */ - if ((cfg0_reg & SDRAM_CFG0_DRAMWDTH) == SDRAM_CFG0_DRAMWDTH_32) - addr_inc = 4; - else - addr_inc = 8; - - current_addr = start; - end_addr = start + size; - - while (current_addr < end_addr) { - *((ulong *)current_addr) = 0x00000000; - current_addr += addr_inc; - } - - /* - * TODO: Flush dcache and disable it again - */ - - /* - * Enable ecc checking and parity errors - */ - mtsdram(mem_cfg0, (cfg0_reg & ~SDRAM_CFG0_MEMCHK) | SDRAM_CFG0_MEMCHK_CHK); -} -#endif - /* * Autodetect onboard DDR SDRAM on 440 platforms *

In message 1210980273-13569-1-git-send-email-gerickson@nuovations.com you 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.
Signed-off-by: Grant Erickson gerickson@nuovations.com
No subject given.
Please keep in mind that the subject of the patch will be the key line of the resulting commit in the repository. Therefor a useful subject line is absolutely mandatory.
Best regards,
Wolfgang Denk
participants (2)
-
Grant Erickson
-
Wolfgang Denk