Commit 311c19cc authored by Wolfgang Denk's avatar Wolfgang Denk
Browse files

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

parents eb4bf4c0 3b4bd2d7
......@@ -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!) */
......
/*
* (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)