mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
Support for DDR with 32-data path. Addotional notes on injecting
multiple-bit errors.
This commit is contained in:
parent
d326f4a242
commit
dc9e499c62
5 changed files with 126 additions and 53 deletions
|
@ -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*/
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue