From c821b5f120bedf73867513466412587c6912a8f8 Mon Sep 17 00:00:00 2001 From: Grant Erickson Date: Thu, 22 May 2008 14:44:14 -0700 Subject: ppc4xx: Enable Primordial Stack for 40x and Unify ECC Handling This patch (Part 1 of 2): * Rolls up a suite of changes to enable correct primordial stack and global data handling when the data cache is used for such a purpose for PPC40x-variants (i.e. CFG_INIT_DCACHE_CS). * Related to the first, unifies DDR2 SDRAM and ECC initialization by eliminating redundant ECC initialization implementations and moving redundant SDRAM initialization out of board code into shared 4xx code. * Enables MCSR visibility on the 405EX(r). * Enables the use of the data cache for initial RAM on both AMCC's Kilauea and Makalu and removes a redundant CFG_POST_MEMORY flag from each board's CONFIG_POST value. - Removed, per Stefan Roese's request, defunct memory.c file for Makalu and rolled sdram_init from it into makalu.c. With respect to the 4xx DDR initialization and ECC unification, there is certainly more work that can and should be done (file renaming, etc.). However, that can be handled at a later date on a second or third pass. As it stands, this patch moves things forward in an incremental yet positive way for those platforms that utilize this code and the features associated with it. Signed-off-by: Grant Erickson Signed-off-by: Stefan Roese --- cpu/ppc4xx/ecc.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 cpu/ppc4xx/ecc.c (limited to 'cpu/ppc4xx/ecc.c') diff --git a/cpu/ppc4xx/ecc.c b/cpu/ppc4xx/ecc.c new file mode 100644 index 0000000000..95b941dabb --- /dev/null +++ b/cpu/ppc4xx/ecc.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2008 Nuovation System Designs, LLC + * Grant Erickson + * + * (C) Copyright 2005-2007 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * (C) Copyright 2002 + * Jun Gu, Artesyn Technology, jung@artesyncp.com + * + * (C) Copyright 2001 + * Bill Hunter, Wave 7 Optics, williamhunter@attbi.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 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 +#include +#include +#include +#include +#include + +#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. + * - Further generalize to make usable by other 4xx variants (e.g. + * 440EPx, et al). + * + * 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(); + + /* 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) */ -- cgit