Support for DDR with 32-data path. Addotional notes on injecting

multiple-bit errors.
This commit is contained in:
Rafal Jaworowski 2006-03-16 17:46:46 +01:00
parent d326f4a242
commit dc9e499c62
5 changed files with 126 additions and 53 deletions

View file

@ -63,11 +63,12 @@ long int initdram (int board_type)
if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im)
return -1;
puts("Initializing\n");
/* DDR SDRAM - Main SODIMM */
im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
#if defined(CONFIG_SPD_EEPROM)
msize = spd_sdram(0);
msize = spd_sdram();
#else
msize = fixed_sdram();
#endif
@ -106,45 +107,40 @@ int fixed_sdram(void)
return -1;
}
}
im->sysconf.ddrlaw[0].bar = ((CFG_DDR_SDRAM_BASE>>12) & 0xfffff);
im->sysconf.ddrlaw[0].ar = LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
#if (CFG_DDR_SIZE != 256)
#warning Currenly any ddr size other than 256 is not supported
#endif
im->ddr.csbnds[0].csbnds = 0x00100017;
im->ddr.csbnds[1].csbnds = 0x0018001f;
im->ddr.csbnds[2].csbnds = 0x00000007;
im->ddr.csbnds[3].csbnds = 0x0008000f;
im->ddr.cs_config[0] = CFG_DDR_CONFIG;
im->ddr.cs_config[1] = CFG_DDR_CONFIG;
im->ddr.csbnds[2].csbnds = 0x0000000f;
im->ddr.cs_config[2] = CFG_DDR_CONFIG;
im->ddr.cs_config[3] = CFG_DDR_CONFIG;
im->ddr.timing_cfg_1 =
3 << TIMING_CFG1_PRETOACT_SHIFT |
7 << TIMING_CFG1_ACTTOPRE_SHIFT |
3 << TIMING_CFG1_ACTTORW_SHIFT |
4 << TIMING_CFG1_CASLAT_SHIFT |
3 << TIMING_CFG1_REFREC_SHIFT |
3 << TIMING_CFG1_WRREC_SHIFT |
2 << TIMING_CFG1_ACTTOACT_SHIFT |
1 << TIMING_CFG1_WRTORD_SHIFT;
im->ddr.timing_cfg_2 = 2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT;
/* currently we use only one CS, so disable the other banks */
im->ddr.cs_config[0] = 0;
im->ddr.cs_config[1] = 0;
im->ddr.cs_config[3] = 0;
im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;
im->ddr.sdram_cfg =
SDRAM_CFG_SREN
#if defined(CONFIG_DDR_2T_TIMING)
| SDRAM_CFG_2T_EN
#endif
| 2 << SDRAM_CFG_SDRAM_TYPE_SHIFT;
im->ddr.sdram_mode =
0x2000 << SDRAM_MODE_ESD_SHIFT |
0x0162 << SDRAM_MODE_SD_SHIFT;
#if defined (CONFIG_DDR_32BIT)
/* for 32-bit mode burst length is 8 */
im->ddr.sdram_cfg |= (SDRAM_CFG_32_BE | SDRAM_CFG_8_BE);
#endif
im->ddr.sdram_mode = CFG_DDR_MODE;
im->ddr.sdram_interval = 0x045B << SDRAM_INTERVAL_REFINT_SHIFT |
0x0100 << SDRAM_INTERVAL_BSTOPRE_SHIFT;
im->ddr.sdram_interval = CFG_DDR_INTERVAL;
udelay(200);
/* enable DDR controller */
im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
return msize;
}
#endif/*!CFG_SPD_EEPROM*/

View file

@ -1,4 +1,7 @@
/*
* (C) Copyright 2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Copyright 2004 Freescale Semiconductor.
* (C) Copyright 2003 Motorola Inc.
* Xianghua Xiao (X.Xiao@motorola.com)
@ -73,7 +76,32 @@ int read_spd(uint addr)
return ((int) addr);
}
long int spd_sdram(int(read_spd)(uint addr))
#undef SPD_DEBUG
#ifdef SPD_DEBUG
static void spd_debug(spd_eeprom_t *spd)
{
printf ("\nDIMM type: %-18.18s\n", spd->mpart);
printf ("SPD size: %d\n", spd->info_size);
printf ("EEPROM size: %d\n", 1 << spd->chip_size);
printf ("Memory type: %d\n", spd->mem_type);
printf ("Row addr: %d\n", spd->nrow_addr);
printf ("Column addr: %d\n", spd->ncol_addr);
printf ("# of rows: %d\n", spd->nrows);
printf ("Row density: %d\n", spd->row_dens);
printf ("# of banks: %d\n", spd->nbanks);
printf ("Data width: %d\n",
256 * spd->dataw_msb + spd->dataw_lsb);
printf ("Chip width: %d\n", spd->primw);
printf ("Refresh rate: %02X\n", spd->refresh);
printf ("CAS latencies: %02X\n", spd->cas_lat);
printf ("Write latencies: %02X\n", spd->write_lat);
printf ("tRP: %d\n", spd->trp);
printf ("tRCD: %d\n", spd->trcd);
printf ("\n");
}
#endif /* SPD_DEBUG */
long int spd_sdram()
{
volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
volatile ddr8349_t *ddr = &immap->ddr;
@ -85,10 +113,10 @@ long int spd_sdram(int(read_spd)(uint addr))
unsigned char caslat;
unsigned int trfc, trfc_clk, trfc_low;
#warning Current spd_sdram does not fit its usage... adjust implementation or API...
CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
#ifdef SPD_DEBUG
spd_debug(&spd);
#endif
if (spd.nrows > 2) {
puts("DDR:Only two chip selects are supported on ADS.\n");
return 0;
@ -223,25 +251,31 @@ long int spd_sdram(int(read_spd)(uint addr))
* Only DDR I is supported
* DDR I and II have different mode-register-set definition
*/
/* burst length is always 4 */
switch(caslat) {
case 2:
ddr->sdram_mode = 0x52; /* 1.5 */
tmp = 0x50; /* 1.5 */
break;
case 3:
ddr->sdram_mode = 0x22; /* 2.0 */
tmp = 0x20; /* 2.0 */
break;
case 4:
ddr->sdram_mode = 0x62; /* 2.5 */
tmp = 0x60; /* 2.5 */
break;
case 5:
ddr->sdram_mode = 0x32; /* 3.0 */
tmp = 0x30; /* 3.0 */
break;
default:
puts("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 is supported.\n");
return 0;
}
#if defined (CONFIG_DDR_32BIT)
/* set burst length to 8 for 32-bit data path */
tmp |= 0x03;
#else
/* set burst length to 4 - default for 64-bit data path */
tmp |= 0x02;
#endif
ddr->sdram_mode = tmp;
debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode);
switch(spd.refresh) {
@ -321,6 +355,10 @@ long int spd_sdram(int(read_spd)(uint addr))
*/
tmp = 0xc2000000;
#if defined (CONFIG_DDR_32BIT)
/* in 32-Bit mode burst len is 8 beats */
tmp |= (SDRAM_CFG_32_BE | SDRAM_CFG_8_BE);
#endif
/*
* sdram_cfg[3] = RD_EN - registered DIMM enable
* A value of 0x26 indicates micron registered DIMMS (micron.com)
@ -350,8 +388,7 @@ long int spd_sdram(int(read_spd)(uint addr))
udelay(500);
debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg);
return memsize;/*in MBytes*/
return memsize; /*in MBytes*/
}
#endif /* CONFIG_SPD_EEPROM */

View file

@ -1,3 +1,24 @@
Overview
========
The overall usage pattern for ECC diagnostic commands is the following:
* (injecting errors is initially disabled)
* define inject mask (which tells the DDR controller what type of errors
we'll be injecting: single/multiple bit etc.)
* enable injecting errors - from now on the controller injects errors as
indicated in the inject mask
IMPORTANT NOTICE: enabling injecting multiple-bit errors is potentially
dangerous as such errors are NOT corrected by the controller. Therefore caution
should be taken when enabling the injection of multiple-bit errors: it is only
safe when used on a carefully selected memory area and used under control of
the 'ecc test' command (see example 'Injecting Multiple-Bit Errors' below). In
particular, when you simply set the multiple-bit errors in inject mask and
enable injection, U-Boot is very likely to hang quickly as the errors will be
injected when it accesses its code, data etc.
Use cases for DDR 'ecc' command:

View file

@ -73,27 +73,46 @@
#define CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */
#define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/
/*
* 32-bit data path mode.
*
* Please note that using this mode for devices with the real density of 64-bit
* effectively reduces the amount of available memory due to the effect of
* wrapping around while translating address to row/columns, for example in the
* 256MB module the upper 128MB get aliased with contents of the lower
* 128MB); normally this define should be used for devices with real 32-bit
* data path.
*/
#undef CONFIG_DDR_32BIT
#define CFG_DDR_BASE 0x00000000 /* DDR is system memory*/
#define CFG_SDRAM_BASE CFG_DDR_BASE
#define CFG_DDR_SDRAM_BASE CFG_DDR_BASE
#undef CONFIG_DDR_2T_TIMING
#if defined(CONFIG_SPD_EEPROM)
/*
* Determine DDR configuration from I2C interface.
*/
#define SPD_EEPROM_ADDRESS 0x51 /* DDR DIMM */
/*
* Determine DDR configuration from I2C interface.
*/
#define SPD_EEPROM_ADDRESS 0x51 /* DDR DIMM */
#else
/*
* Manually set up DDR parameters
*/
#define CFG_DDR_SIZE 128 /* Mb */
#define CFG_DDR_CONFIG (CSCONFIG_EN | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_9)
#define CFG_DDR_TIMING_1 0x37344321
#define CFG_DDR_TIMING_2 0x00000800 /* P9-45,may need tuning */
#define CFG_DDR_CONTROL 0xc2000000 /* unbuffered,no DYN_PWR */
#define CFG_DDR_MODE 0x00000062 /* DLL,normal,seq,4/2.5 */
#define CFG_DDR_INTERVAL 0x05200100 /* autocharge,no open page */
/*
* Manually set up DDR parameters
*/
#define CFG_DDR_SIZE 256 /* MB */
#define CFG_DDR_CONFIG (CSCONFIG_EN | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_10)
#define CFG_DDR_TIMING_1 0x36332321
#define CFG_DDR_TIMING_2 0x00000800 /* P9-45,may need tuning */
#define CFG_DDR_CONTROL 0xc2000000 /* unbuffered,no DYN_PWR */
#define CFG_DDR_INTERVAL 0x04060100 /* autocharge,no open page */
#if defined(CONFIG_DDR_32BIT)
/* set burst length to 8 for 32-bit data path */
#define CFG_DDR_MODE 0x00000023 /* DLL,normal,seq,4/2.5, 8 burst len */
#else
/* the default burst length is 4 - for 64-bit data path */
#define CFG_DDR_MODE 0x00000022 /* DLL,normal,seq,4/2.5, 4 burst len */
#endif
#endif
/*

View file

@ -1,6 +1,6 @@
#ifndef _SPD_SDRAM_H_
#define _SPD_SDRAM_H_
long int spd_sdram(int(read_spd)(uint addr));
long int spd_sdram(void);
#endif