mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-10-03 18:10:42 +09:00
Merge branch 'master' of git://git.denx.de/u-boot-ppc4xx
This commit is contained in:
commit
311c19ccb5
@ -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!) */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
179
cpu/ppc4xx/ecc.c
179
cpu/ppc4xx/ecc.c
@ -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)... */
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user