Merge branch 'master' of git://git.denx.de/u-boot-ppc4xx

This commit is contained in:
Wolfgang Denk 2009-10-03 23:40:35 +02:00
commit 311c19ccb5
8 changed files with 347 additions and 357 deletions

View file

@ -23,7 +23,7 @@
#include <asm-ppc/mmu.h>
#include <config.h>
/**************************************************************************
/*
* TLB TABLE
*
* This table is used by the cpu boot code to setup the initial tlb
@ -32,7 +32,7 @@
*
* Pointer to the table is returned in r1
*
*************************************************************************/
*/
.section .bootpg,"ax"
.globl tlbtab
@ -49,12 +49,7 @@ tlbtab:
tlbentry( CONFIG_SYS_NAND_BOOT_SPL_SRC, SZ_4K, CONFIG_SYS_NAND_BOOT_SPL_SRC, 1, AC_R|AC_W|AC_X|SA_G )
#endif
/* TLB-entry for DDR SDRAM (Up to 2GB) */
#ifdef CONFIG_4xx_DCACHE
tlbentry( CONFIG_SYS_SDRAM_BASE, SZ_256M, CONFIG_SYS_SDRAM_BASE, 0, AC_R|AC_W|AC_X|SA_G)
#else
tlbentry( CONFIG_SYS_SDRAM_BASE, SZ_256M, CONFIG_SYS_SDRAM_BASE, 0, AC_R|AC_W|AC_X|SA_G|SA_I )
#endif
/* TLB entries for DDR2 SDRAM are generated dynamically */
#ifdef CONFIG_SYS_INIT_RAM_DCACHE
/* TLB-entry for init-ram in dcache (SA_I must be turned off!) */

View file

@ -1,4 +1,7 @@
/*
* (C) Copyright 2009
* Matthias Fuchs, esd gmbh, matthias.fuchs@esd.eu
*
* (C) Copyright 2006
* Sylvie Gohl, AMCC/IBM, gohl.sylvie@fr.ibm.com
* Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
@ -31,33 +34,30 @@
#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <ppc440.h>
extern int denali_wait_for_dlllock(void);
extern void denali_core_search_data_eye(void);
struct sdram_conf_s {
ulong size;
int rows;
int banks;
};
#if defined(CONFIG_NAND_SPL)
/* Using cpu/ppc4xx/speed.c to calculate the bus frequency is too big
* for the 4k NAND boot image so define bus_frequency to 133MHz here
* which is save for the refresh counter setup.
*/
#define get_bus_freq(val) 133000000
#endif
struct sdram_conf_s sdram_conf[] = {
{(1024 << 20), 14, 8}, /* 1GByte: 4x2GBit, 14x10, 8 banks */
{(512 << 20), 13, 8}, /* 512MByte: 4x1GBit, 13x10, 8 banks */
{(256 << 20), 13, 4}, /* 256MByte: 4x512MBit, 13x10, 4 banks */
};
/*************************************************************************
*
/*
* initdram -- 440EPx's DDR controller is a DENALI Core
*
************************************************************************/
phys_size_t initdram (int board_type)
*/
int initdram_by_rb(int rows, int banks)
{
#if !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)
#if !defined(CONFIG_NAND_SPL)
ulong speed = get_bus_freq(0);
#else
ulong speed = 133333333; /* 133MHz is on the safe side */
#endif
mtsdram(DDR0_02, 0x00000000);
@ -89,21 +89,25 @@ phys_size_t initdram (int board_type)
mtsdram(DDR0_27, 0x0000682B);
mtsdram(DDR0_28, 0x00000000);
mtsdram(DDR0_31, 0x00000000);
mtsdram(DDR0_42, 0x01000006);
mtsdram(DDR0_43, 0x030A0200);
mtsdram(DDR0_42,
DDR0_42_ADDR_PINS_DECODE(14 - rows) |
0x00000006);
mtsdram(DDR0_43,
DDR0_43_EIGHT_BANK_MODE_ENCODE(8 == banks ? 1 : 0) |
0x030A0200);
mtsdram(DDR0_44, 0x00000003);
mtsdram(DDR0_02, 0x00000001);
denali_wait_for_dlllock();
#endif /* #ifndef CONFIG_NAND_U_BOOT */
#ifdef CONFIG_DDR_DATA_EYE
/* -----------------------------------------------------------+
/*
* Perform data eye search if requested.
* ----------------------------------------------------------*/
*/
denali_core_search_data_eye();
#endif
/*
* Clear possible errors resulting from data-eye-search.
* If not done, then we could get an interrupt later on when
@ -111,5 +115,35 @@ phys_size_t initdram (int board_type)
*/
set_mcsr(get_mcsr());
return (CONFIG_SYS_MBYTES_SDRAM << 20);
return 0;
}
phys_size_t initdram(int board_type)
{
phys_size_t size;
int n;
/* go through supported memory configurations */
for (n = 0; n < ARRAY_SIZE(sdram_conf); n++) {
size = sdram_conf[n].size;
/* program TLB entries */
program_tlb(0, CONFIG_SYS_SDRAM_BASE, size,
TLB_WORD2_I_ENABLE);
/*
* setup denali core
*/
initdram_by_rb(sdram_conf[n].rows,
sdram_conf[n].banks);
/* check for suitable configuration */
if (get_ram_size(CONFIG_SYS_SDRAM_BASE, size) == size)
return size;
/* delete TLB entries */
remove_tlb(CONFIG_SYS_SDRAM_BASE, size);
}
return 0;
}

View file

@ -9,7 +9,7 @@
* Copyright (c) 2008 Nuovation System Designs, LLC
* Grant Erickson <gerickson@nuovations.com>
* (C) Copyright 2007-2008
* (C) Copyright 2007-2009
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* COPYRIGHT AMCC CORPORATION 2004
@ -86,8 +86,133 @@
/* disable caching on SDRAM */
#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE
#endif /* CONFIG_4xx_DCACHE */
void dcbz_area(u32 start_address, u32 num_bytes);
#endif /* CONFIG_440 */
#define MAXRANKS 4
#define MAXBXCF 4
#define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
#if !defined(CONFIG_NAND_SPL)
/*-----------------------------------------------------------------------------+
* sdram_memsize
*-----------------------------------------------------------------------------*/
phys_size_t sdram_memsize(void)
{
phys_size_t mem_size;
unsigned long mcopt2;
unsigned long mcstat;
unsigned long mb0cf;
unsigned long sdsz;
unsigned long i;
mem_size = 0;
mfsdram(SDRAM_MCOPT2, mcopt2);
mfsdram(SDRAM_MCSTAT, mcstat);
/* DDR controller must be enabled and not in self-refresh. */
/* Otherwise memsize is zero. */
if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
&& ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
&& ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
for (i = 0; i < MAXBXCF; i++) {
mfsdram(SDRAM_MB0CF + (i << 2), mb0cf);
/* Banks enabled */
if ((mb0cf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) {
#if defined(CONFIG_440)
sdsz = mfdcr_any(SDRAM_R0BAS + i) & SDRAM_RXBAS_SDSZ_MASK;
#else
sdsz = mb0cf & SDRAM_RXBAS_SDSZ_MASK;
#endif
switch(sdsz) {
case SDRAM_RXBAS_SDSZ_8:
mem_size+=8;
break;
case SDRAM_RXBAS_SDSZ_16:
mem_size+=16;
break;
case SDRAM_RXBAS_SDSZ_32:
mem_size+=32;
break;
case SDRAM_RXBAS_SDSZ_64:
mem_size+=64;
break;
case SDRAM_RXBAS_SDSZ_128:
mem_size+=128;
break;
case SDRAM_RXBAS_SDSZ_256:
mem_size+=256;
break;
case SDRAM_RXBAS_SDSZ_512:
mem_size+=512;
break;
case SDRAM_RXBAS_SDSZ_1024:
mem_size+=1024;
break;
case SDRAM_RXBAS_SDSZ_2048:
mem_size+=2048;
break;
case SDRAM_RXBAS_SDSZ_4096:
mem_size+=4096;
break;
default:
printf("WARNING: Unsupported bank size (SDSZ=0x%lx)!\n"
, sdsz);
mem_size=0;
break;
}
}
}
}
return mem_size << 20;
}
/*-----------------------------------------------------------------------------+
* is_ecc_enabled
*-----------------------------------------------------------------------------*/
static unsigned long is_ecc_enabled(void)
{
unsigned long val;
mfsdram(SDRAM_MCOPT1, val);
return SDRAM_MCOPT1_MCHK_CHK_DECODE(val);
}
/*-----------------------------------------------------------------------------+
* board_add_ram_info
*-----------------------------------------------------------------------------*/
void board_add_ram_info(int use_default)
{
PPC4xx_SYS_INFO board_cfg;
u32 val;
if (is_ecc_enabled())
puts(" (ECC");
else
puts(" (ECC not");
get_sys_info(&board_cfg);
#if defined(CONFIG_405EX)
val = board_cfg.freqPLB;
#else
mfsdr(SDR0_DDR0, val);
val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1);
#endif
printf(" enabled, %d MHz", (val * 2) / 1000000);
mfsdram(SDRAM_MMODE, val);
val = (val & SDRAM_MMODE_DCL_MASK) >> 4;
printf(", CL%d)", val);
}
#endif /* !CONFIG_NAND_SPL */
#if defined(CONFIG_SPD_EEPROM)
/*-----------------------------------------------------------------------------+
@ -105,14 +230,10 @@
#define SDRAM_NONE 0
#define MAXDIMMS 2
#define MAXRANKS 4
#define MAXBXCF 4
#define MAX_SPD_BYTES 256 /* Max number of bytes on the DIMM's SPD EEPROM */
#define ONE_BILLION 1000000000
#define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
#define CMD_NOP (7 << 19)
#define CMD_PRECHARGE (2 << 19)
#define CMD_REFRESH (1 << 19)
@ -213,7 +334,6 @@ typedef enum ddr_cas_id {
/*-----------------------------------------------------------------------------+
* Prototypes
*-----------------------------------------------------------------------------*/
static phys_size_t sdram_memsize(void);
static void get_spd_info(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks);
@ -257,15 +377,11 @@ static void program_initplr(unsigned long *dimm_populated,
unsigned long num_dimm_banks,
ddr_cas_id_t selected_cas,
int write_recovery);
static unsigned long is_ecc_enabled(void);
#ifdef CONFIG_DDR_ECC
static void program_ecc(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks,
unsigned long tlb_word2_i_value);
static void program_ecc_addr(unsigned long start_address,
unsigned long num_bytes,
unsigned long tlb_word2_i_value);
#endif
#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
static void program_DQS_calibration(unsigned long *dimm_populated,
@ -278,7 +394,6 @@ static void DQS_calibration_process(void);
#endif
#endif
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
void dcbz_area(u32 start_address, u32 num_bytes);
static unsigned char spd_read(uchar chip, uint addr)
{
@ -291,79 +406,6 @@ static unsigned char spd_read(uchar chip, uint addr)
return 0;
}
/*-----------------------------------------------------------------------------+
* sdram_memsize
*-----------------------------------------------------------------------------*/
static phys_size_t sdram_memsize(void)
{
phys_size_t mem_size;
unsigned long mcopt2;
unsigned long mcstat;
unsigned long mb0cf;
unsigned long sdsz;
unsigned long i;
mem_size = 0;
mfsdram(SDRAM_MCOPT2, mcopt2);
mfsdram(SDRAM_MCSTAT, mcstat);
/* DDR controller must be enabled and not in self-refresh. */
/* Otherwise memsize is zero. */
if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
&& ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
&& ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
for (i = 0; i < MAXBXCF; i++) {
mfsdram(SDRAM_MB0CF + (i << 2), mb0cf);
/* Banks enabled */
if ((mb0cf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) {
sdsz = mfdcr_any(SDRAM_R0BAS + i) & SDRAM_RXBAS_SDSZ_MASK;
switch(sdsz) {
case SDRAM_RXBAS_SDSZ_8:
mem_size+=8;
break;
case SDRAM_RXBAS_SDSZ_16:
mem_size+=16;
break;
case SDRAM_RXBAS_SDSZ_32:
mem_size+=32;
break;
case SDRAM_RXBAS_SDSZ_64:
mem_size+=64;
break;
case SDRAM_RXBAS_SDSZ_128:
mem_size+=128;
break;
case SDRAM_RXBAS_SDSZ_256:
mem_size+=256;
break;
case SDRAM_RXBAS_SDSZ_512:
mem_size+=512;
break;
case SDRAM_RXBAS_SDSZ_1024:
mem_size+=1024;
break;
case SDRAM_RXBAS_SDSZ_2048:
mem_size+=2048;
break;
case SDRAM_RXBAS_SDSZ_4096:
mem_size+=4096;
break;
default:
printf("WARNING: Unsupported bank size (SDSZ=0x%lx)!\n"
, sdsz);
mem_size=0;
break;
}
}
}
}
return mem_size << 20;
}
/*-----------------------------------------------------------------------------+
* initdram. Initializes the 440SP Memory Queue and DDR SDRAM controller.
* Note: This routine runs from flash with a stack set up in the chip's
@ -643,26 +685,6 @@ static void get_spd_info(unsigned long *dimm_populated,
}
}
void board_add_ram_info(int use_default)
{
PPC4xx_SYS_INFO board_cfg;
u32 val;
if (is_ecc_enabled())
puts(" (ECC");
else
puts(" (ECC not");
get_sys_info(&board_cfg);
mfsdr(SDR0_DDR0, val);
val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1);
printf(" enabled, %d MHz", (val * 2) / 1000000);
mfsdram(SDRAM_MMODE, val);
val = (val & SDRAM_MMODE_DCL_MASK) >> 4;
printf(", CL%d)", val);
}
/*------------------------------------------------------------------
* For the memory DIMMs installed, this routine verifies that they
@ -2277,25 +2299,6 @@ static void program_memory_queue(unsigned long *dimm_populated,
#endif
}
/*-----------------------------------------------------------------------------+
* is_ecc_enabled.
*-----------------------------------------------------------------------------*/
static unsigned long is_ecc_enabled(void)
{
unsigned long dimm_num;
unsigned long ecc;
unsigned long val;
ecc = 0;
/* loop through all the DIMM slots on the board */
for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) {
mfsdram(SDRAM_MCOPT1, val);
ecc = max(ecc, SDRAM_MCOPT1_MCHK_CHK_DECODE(val));
}
return ecc;
}
#ifdef CONFIG_DDR_ECC
/*-----------------------------------------------------------------------------+
* program_ecc.
@ -2305,9 +2308,6 @@ static void program_ecc(unsigned long *dimm_populated,
unsigned long num_dimm_banks,
unsigned long tlb_word2_i_value)
{
unsigned long mcopt1;
unsigned long mcopt2;
unsigned long mcstat;
unsigned long dimm_num;
unsigned long ecc;
@ -2321,105 +2321,7 @@ static void program_ecc(unsigned long *dimm_populated,
if (ecc == 0)
return;
if (sdram_memsize() > CONFIG_MAX_MEM_MAPPED) {
printf("\nWarning: Can't enable ECC on systems with more than 2GB of SDRAM!\n");
return;
}
mfsdram(SDRAM_MCOPT1, mcopt1);
mfsdram(SDRAM_MCOPT2, mcopt2);
if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
/* DDR controller must be enabled and not in self-refresh. */
mfsdram(SDRAM_MCSTAT, mcstat);
if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
&& ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
&& ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
program_ecc_addr(0, sdram_memsize(), tlb_word2_i_value);
}
}
return;
}
static void wait_ddr_idle(void)
{
u32 val;
do {
mfsdram(SDRAM_MCSTAT, val);
} while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
}
/*-----------------------------------------------------------------------------+
* program_ecc_addr.
*-----------------------------------------------------------------------------*/
static void program_ecc_addr(unsigned long start_address,
unsigned long num_bytes,
unsigned long tlb_word2_i_value)
{
unsigned long current_address;
unsigned long end_address;
unsigned long address_increment;
unsigned long mcopt1;
char str[] = "ECC generation -";
char slash[] = "\\|/-\\|/-";
int loop = 0;
int loopi = 0;
current_address = start_address;
mfsdram(SDRAM_MCOPT1, mcopt1);
if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
mtsdram(SDRAM_MCOPT1,
(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_GEN);
sync();
eieio();
wait_ddr_idle();
puts(str);
if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) {
/* ECC bit set method for non-cached memory */
if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32)
address_increment = 4;
else
address_increment = 8;
end_address = current_address + num_bytes;
while (current_address < end_address) {
*((unsigned long *)current_address) = 0x00000000;
current_address += address_increment;
if ((loop++ % (2 << 20)) == 0) {
putc('\b');
putc(slash[loopi++ % 8]);
}
}
} else {
/* ECC bit set method for cached memory */
dcbz_area(start_address, num_bytes);
/* Write modified dcache lines back to memory */
clean_dcache_range(start_address, start_address + num_bytes);
}
blank_string(strlen(str));
sync();
eieio();
wait_ddr_idle();
/* clear ECC error repoting registers */
mtsdram(SDRAM_ECCCR, 0xffffffff);
mtdcr(0x4c, 0xffffffff);
mtsdram(SDRAM_MCOPT1,
(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP);
sync();
eieio();
wait_ddr_idle();
}
do_program_ecc(tlb_word2_i_value);
}
#endif
@ -3106,7 +3008,7 @@ phys_size_t initdram(int board_type)
#endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
#if defined(CONFIG_DDR_ECC)
ecc_init(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20);
do_program_ecc(0);
#endif /* defined(CONFIG_DDR_ECC) */
#if defined(CONFIG_440)
@ -3183,18 +3085,6 @@ void mtdcr_any(u32 dcr, u32 val)
}
}
#endif /* defined(CONFIG_440) */
void blank_string(int size)
{
int i;
for (i = 0; i < size; i++)
putc('\b');
for (i = 0; i < size; i++)
putc(' ');
for (i = 0; i < size; i++)
putc('\b');
}
#endif /* !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) */
inline void ppc4xx_ibm_ddr2_register_dump(void)

View file

@ -42,6 +42,8 @@
#include <asm/io.h>
#include <asm/processor.h>
#include "ecc.h"
#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
/*
@ -177,7 +179,7 @@ static u32 *get_membase(int bxcr_num)
static inline void ecc_clear_status_reg(void)
{
mtsdram(SDRAM_ECCCR, 0xffffffff);
mtsdram(SDRAM_ECCES, 0xffffffff);
#if defined(SDRAM_R0BAS)
mtdcr(SDRAM_ERRSTATLL, 0xffffffff);
#endif
@ -210,7 +212,7 @@ static int ecc_check_status_reg(void)
* ecc error, then don't count
* this as a passing value
*/
mfsdram(SDRAM_ECCCR, ecc_status);
mfsdram(SDRAM_ECCES, ecc_status);
if (ecc_status != 0x00000000) {
/* clear on error */
ecc_clear_status_reg();

View file

@ -2,7 +2,7 @@
* Copyright (c) 2008 Nuovation System Designs, LLC
* Grant Erickson <gerickson@nuovations.com>
*
* (C) Copyright 2005-2007
* (C) Copyright 2005-2009
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
@ -42,81 +42,144 @@
#include <ppc_defs.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <asm/cache.h>
#include "ecc.h"
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) || \
defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
#if defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC)
#if defined(CONFIG_405EX)
/*
* 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
* CONFIG_SYS_ECC_PATTERN written to all locations and ECC data
* primed.
*
* Returns:
* N/A
* Currently only 405EX uses 16bit data bus width as an alternative
* option to 32bit data width (SDRAM0_MCOPT1_WDTH)
*/
#define SDRAM_DATA_ALT_WIDTH 2
#else
#define SDRAM_DATA_ALT_WIDTH 8
#endif
static void wait_ddr_idle(void)
{
u32 val;
do {
mfsdram(SDRAM_MCSTAT, val);
} while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
}
static void program_ecc_addr(unsigned long start_address,
unsigned long num_bytes,
unsigned long tlb_word2_i_value)
{
unsigned long current_address;
unsigned long end_address;
unsigned long address_increment;
unsigned long mcopt1;
char str[] = "ECC generation -";
char slash[] = "\\|/-\\|/-";
int loop = 0;
int loopi = 0;
current_address = start_address;
mfsdram(SDRAM_MCOPT1, mcopt1);
if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
mtsdram(SDRAM_MCOPT1,
(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_GEN);
sync();
eieio();
wait_ddr_idle();
puts(str);
#ifdef CONFIG_440
if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) {
#endif
/* ECC bit set method for non-cached memory */
if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32)
address_increment = 4;
else
address_increment = SDRAM_DATA_ALT_WIDTH;
end_address = current_address + num_bytes;
while (current_address < end_address) {
*((unsigned long *)current_address) = 0;
current_address += address_increment;
if ((loop++ % (2 << 20)) == 0) {
putc('\b');
putc(slash[loopi++ % 8]);
}
}
#ifdef CONFIG_440
} else {
/* ECC bit set method for cached memory */
dcbz_area(start_address, num_bytes);
/* Write modified dcache lines back to memory */
clean_dcache_range(start_address, start_address + num_bytes);
}
#endif /* CONFIG_440 */
blank_string(strlen(str));
sync();
eieio();
wait_ddr_idle();
/* clear ECC error repoting registers */
mtsdram(SDRAM_ECCES, 0xffffffff);
mtdcr(0x4c, 0xffffffff);
mtsdram(SDRAM_MCOPT1,
(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP);
sync();
eieio();
wait_ddr_idle();
}
}
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)
void ecc_init(unsigned long * const start, unsigned long size)
{
const unsigned long pattern = CONFIG_SYS_ECC_PATTERN;
unsigned long * const end = (unsigned long * const)((long)start + size);
unsigned long * current = start;
unsigned long mcopt1;
long increment;
if (start >= end)
return;
mfsdram(SDRAM_ECC_CFG, mcopt1);
/* Enable ECC generation without checking or reporting */
mtsdram(SDRAM_ECC_CFG, ((mcopt1 & ~SDRAM_ECC_CFG_MCHK_MASK) |
SDRAM_ECC_CFG_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.
* Init ECC with cache disabled (on PPC's with IBM DDR
* controller (non DDR2), not tested with cache enabled yet
*/
program_ecc_addr((u32)start, size, TLB_WORD2_I_ENABLE);
}
#endif
if ((mcopt1 & SDRAM_ECC_CFG_DMWD_MASK) != SDRAM_ECC_CFG_DMWD_32)
increment = sizeof(u64);
#endif /* defined(CONFIG_440) */
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
void do_program_ecc(unsigned long tlb_word2_i_value)
{
unsigned long mcopt1;
unsigned long mcopt2;
unsigned long mcstat;
phys_size_t memsize = sdram_memsize();
while (current < end) {
*current = pattern;
current = (unsigned long *)((long)current + increment);
if (memsize > CONFIG_MAX_MEM_MAPPED) {
printf("\nWarning: Can't enable ECC on systems with more than 2GB of SDRAM!\n");
return;
}
/* Wait until the writes are finished. */
mfsdram(SDRAM_MCOPT1, mcopt1);
mfsdram(SDRAM_MCOPT2, mcopt2);
sync();
if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
/* DDR controller must be enabled and not in self-refresh. */
mfsdram(SDRAM_MCSTAT, mcstat);
if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
&& ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
&& ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
/* Enable ECC generation with checking and no reporting */
mtsdram(SDRAM_ECC_CFG, ((mcopt1 & ~SDRAM_ECC_CFG_MCHK_MASK) |
SDRAM_ECC_CFG_MCHK_CHK));
program_ecc_addr(0, memsize, tlb_word2_i_value);
}
}
}
#endif
#endif /* defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) */
#endif /* defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)... */

View file

@ -2,7 +2,7 @@
* Copyright (c) 2008 Nuovation System Designs, LLC
* Grant Erickson <gerickson@nuovations.com>
*
* Copyright (c) 2007 DENX Software Engineering, GmbH
* Copyright (c) 2007-2009 DENX Software Engineering, GmbH
* Stefan Roese <sr@denx.de>
*
* See file CREDITS for list of people who contributed to this
@ -25,18 +25,13 @@
*
* Description:
* This file implements ECC initialization for PowerPC processors
* using the SDRAM DDR2 controller, including the 405EX(r),
* 440SP(E), 460EX and 460GT.
* using the IBM SDRAM DDR1 & DDR2 controller.
*
*/
#ifndef _ECC_H_
#define _ECC_H_
#if !defined(CONFIG_SYS_ECC_PATTERN)
#define CONFIG_SYS_ECC_PATTERN 0x00000000
#endif /* !defined(CONFIG_SYS_ECC_PATTERN) */
/*
* Since the IBM DDR controller used on 440GP/GX/EP/GR is not register
* compatible to the IBM DDR/2 controller used on 405EX/440SP/SPe/460EX/GT
@ -46,24 +41,35 @@
/* For 440GP/GX/EP/GR */
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)
#define SDRAM_ECC_CFG SDRAM_CFG0
#define SDRAM_ECC_CFG_MCHK_MASK SDRAM_CFG0_MCHK_MASK
#define SDRAM_ECC_CFG_MCHK_GEN SDRAM_CFG0_MCHK_GEN
#define SDRAM_ECC_CFG_MCHK_CHK SDRAM_CFG0_MCHK_CHK
#define SDRAM_ECC_CFG_DMWD_MASK SDRAM_CFG0_DMWD_MASK
#define SDRAM_ECC_CFG_DMWD_32 SDRAM_CFG0_DMWD_32
#define SDRAM_MCOPT1 SDRAM_CFG0
#define SDRAM_MCOPT1_MCHK_MASK SDRAM_CFG0_MCHK_MASK
#define SDRAM_MCOPT1_MCHK_NON SDRAM_CFG0_MCHK_NON
#define SDRAM_MCOPT1_MCHK_GEN SDRAM_CFG0_MCHK_GEN
#define SDRAM_MCOPT1_MCHK_CHK SDRAM_CFG0_MCHK_CHK
#define SDRAM_MCOPT1_MCHK_CHK_REP SDRAM_CFG0_MCHK_CHK
#define SDRAM_MCOPT1_DMWD_MASK SDRAM_CFG0_DMWD_MASK
#define SDRAM_MCOPT1_DMWD_32 SDRAM_CFG0_DMWD_32
#define SDRAM_MCSTAT SDRAM0_MCSTS
#define SDRAM_MCSTAT_IDLE_MASK SDRAM_MCSTS_CIS
#define SDRAM_MCSTAT_IDLE_NOT SDRAM_MCSTS_IDLE_NOT
#define SDRAM_ECCES SDRAM0_ECCESR
#endif
/* For 405EX/440SP/SPe/460EX/GT */
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
#define SDRAM_ECC_CFG SDRAM_MCOPT1
#define SDRAM_ECC_CFG_MCHK_MASK SDRAM_MCOPT1_MCHK_MASK
#define SDRAM_ECC_CFG_MCHK_GEN SDRAM_MCOPT1_MCHK_GEN
#define SDRAM_ECC_CFG_MCHK_CHK SDRAM_MCOPT1_MCHK_CHK
#define SDRAM_ECC_CFG_DMWD_MASK SDRAM_MCOPT1_DMWD_MASK
#define SDRAM_ECC_CFG_DMWD_32 SDRAM_MCOPT1_DMWD_32
#endif
void ecc_init(unsigned long * const start, unsigned long size);
void do_program_ecc(unsigned long tlb_word2_i_value);
extern void ecc_init(unsigned long * const start, unsigned long size);
static void inline blank_string(int size)
{
int i;
for (i = 0; i < size; i++)
putc('\b');
for (i = 0; i < size; i++)
putc(' ');
for (i = 0; i < size; i++)
putc('\b');
}
#endif /* _ECC_H_ */

View file

@ -117,6 +117,7 @@
#define SDRAM_MCSTS_MRSC 0x80000000
#define SDRAM_MCSTS_SRMS 0x40000000
#define SDRAM_MCSTS_CIS 0x20000000
#define SDRAM_MCSTS_IDLE_NOT 0x00000000 /* Mem contr not idle */
/*
* SDRAM Refresh Timer Register
@ -416,8 +417,7 @@
#define SDRAM_SDTR3 0x87 /* DDR SDRAM timing 3 */
#define SDRAM_MMODE 0x88 /* memory mode */
#define SDRAM_MEMODE 0x89 /* memory extended mode */
#define SDRAM_ECCCR 0x98 /* ECC error status */
#define SDRAM_ECCES SDRAM_ECCCR
#define SDRAM_ECCES 0x98 /* ECC error status */
#define SDRAM_CID 0xA4 /* core ID */
#ifndef CONFIG_405EX
#define SDRAM_RID 0xA8 /* revision ID */
@ -1397,7 +1397,6 @@
/*
* Prototypes
*/
void inline blank_string(int size);
inline void ppc4xx_ibm_ddr2_register_dump(void);
u32 mfdcr_any(u32);
void mtdcr_any(u32, u32);
@ -1405,6 +1404,8 @@ u32 ddr_wrdtr(u32);
u32 ddr_clktr(u32);
void spd_ddr_init_hang(void);
u32 DQS_autocalibration(void);
phys_size_t sdram_memsize(void);
void dcbz_area(u32 start_address, u32 num_bytes);
#endif /* __ASSEMBLY__ */
#endif /* _PPC4xx_SDRAM_H_ */

View file

@ -215,7 +215,6 @@
/*-----------------------------------------------------------------------
* DDR SDRAM
*----------------------------------------------------------------------*/
#define CONFIG_SYS_MBYTES_SDRAM (256) /* 256MB */
#if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
#define CONFIG_DDR_DATA_EYE /* use DDR2 optimization */
#endif