|
@@ -48,8 +48,6 @@
|
|
#include <asm/mmu.h>
|
|
#include <asm/mmu.h>
|
|
#include <asm/cache.h>
|
|
#include <asm/cache.h>
|
|
|
|
|
|
-#include "ecc.h"
|
|
|
|
-
|
|
|
|
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
|
|
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
|
|
|
|
|
|
#define PPC4xx_IBM_DDR2_DUMP_REGISTER(mnemonic) \
|
|
#define PPC4xx_IBM_DDR2_DUMP_REGISTER(mnemonic) \
|
|
@@ -86,8 +84,240 @@
|
|
/* disable caching on SDRAM */
|
|
/* disable caching on SDRAM */
|
|
#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE
|
|
#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE
|
|
#endif /* CONFIG_4xx_DCACHE */
|
|
#endif /* CONFIG_4xx_DCACHE */
|
|
|
|
+
|
|
|
|
+void dcbz_area(u32 start_address, u32 num_bytes);
|
|
#endif /* CONFIG_440 */
|
|
#endif /* CONFIG_440 */
|
|
|
|
|
|
|
|
+#define MAXRANKS 4
|
|
|
|
+#define MAXBXCF 4
|
|
|
|
+
|
|
|
|
+#define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
|
|
|
|
+
|
|
|
|
+static unsigned long is_ecc_enabled(void);
|
|
|
|
+
|
|
|
|
+/*-----------------------------------------------------------------------------+
|
|
|
|
+ * wait_ddr_idle
|
|
|
|
+ *-----------------------------------------------------------------------------*/
|
|
|
|
+static void wait_ddr_idle(void)
|
|
|
|
+{
|
|
|
|
+ u32 val;
|
|
|
|
+
|
|
|
|
+ do {
|
|
|
|
+ mfsdram(SDRAM_MCSTAT, val);
|
|
|
|
+ } while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*-----------------------------------------------------------------------------+
|
|
|
|
+ * 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) {
|
|
|
|
+#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;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*-----------------------------------------------------------------------------+
|
|
|
|
+ * 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_440)
|
|
|
|
+ mfsdr(SDR0_DDR0, val);
|
|
|
|
+ val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1);
|
|
|
|
+#else
|
|
|
|
+ mfsdr(SDR0_SDSTP0, val);
|
|
|
|
+ val = MULDIV64((board_cfg.freqPLB), SDR0_SDSTP0_PLB2xDV0_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);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_DDR_ECC
|
|
|
|
+/*-----------------------------------------------------------------------------+
|
|
|
|
+ * 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);
|
|
|
|
+
|
|
|
|
+#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 = 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]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+#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_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.
|
|
|
|
+ *-----------------------------------------------------------------------------*/
|
|
|
|
+static 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();
|
|
|
|
+
|
|
|
|
+ if (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, memsize, tlb_word2_i_value);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+#endif /* CONFIG_DDR_ECC */
|
|
|
|
+
|
|
#if defined(CONFIG_SPD_EEPROM)
|
|
#if defined(CONFIG_SPD_EEPROM)
|
|
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
/*-----------------------------------------------------------------------------+
|
|
@@ -105,14 +335,10 @@
|
|
#define SDRAM_NONE 0
|
|
#define SDRAM_NONE 0
|
|
|
|
|
|
#define MAXDIMMS 2
|
|
#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 MAX_SPD_BYTES 256 /* Max number of bytes on the DIMM's SPD EEPROM */
|
|
|
|
|
|
#define ONE_BILLION 1000000000
|
|
#define ONE_BILLION 1000000000
|
|
|
|
|
|
-#define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
|
|
|
|
-
|
|
|
|
#define CMD_NOP (7 << 19)
|
|
#define CMD_NOP (7 << 19)
|
|
#define CMD_PRECHARGE (2 << 19)
|
|
#define CMD_PRECHARGE (2 << 19)
|
|
#define CMD_REFRESH (1 << 19)
|
|
#define CMD_REFRESH (1 << 19)
|
|
@@ -257,15 +483,11 @@ static void program_initplr(unsigned long *dimm_populated,
|
|
unsigned long num_dimm_banks,
|
|
unsigned long num_dimm_banks,
|
|
ddr_cas_id_t selected_cas,
|
|
ddr_cas_id_t selected_cas,
|
|
int write_recovery);
|
|
int write_recovery);
|
|
-static unsigned long is_ecc_enabled(void);
|
|
|
|
#ifdef CONFIG_DDR_ECC
|
|
#ifdef CONFIG_DDR_ECC
|
|
static void program_ecc(unsigned long *dimm_populated,
|
|
static void program_ecc(unsigned long *dimm_populated,
|
|
unsigned char *iic0_dimm_addr,
|
|
unsigned char *iic0_dimm_addr,
|
|
unsigned long num_dimm_banks,
|
|
unsigned long num_dimm_banks,
|
|
unsigned long tlb_word2_i_value);
|
|
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
|
|
#endif
|
|
#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
|
|
#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
|
|
static void program_DQS_calibration(unsigned long *dimm_populated,
|
|
static void program_DQS_calibration(unsigned long *dimm_populated,
|
|
@@ -278,7 +500,6 @@ static void DQS_calibration_process(void);
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
|
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)
|
|
static unsigned char spd_read(uchar chip, uint addr)
|
|
{
|
|
{
|
|
@@ -291,79 +512,6 @@ static unsigned char spd_read(uchar chip, uint addr)
|
|
return 0;
|
|
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.
|
|
* 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
|
|
* Note: This routine runs from flash with a stack set up in the chip's
|
|
@@ -643,26 +791,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
|
|
* For the memory DIMMs installed, this routine verifies that they
|
|
@@ -2305,9 +2433,6 @@ static void program_ecc(unsigned long *dimm_populated,
|
|
unsigned long num_dimm_banks,
|
|
unsigned long num_dimm_banks,
|
|
unsigned long tlb_word2_i_value)
|
|
unsigned long tlb_word2_i_value)
|
|
{
|
|
{
|
|
- unsigned long mcopt1;
|
|
|
|
- unsigned long mcopt2;
|
|
|
|
- unsigned long mcstat;
|
|
|
|
unsigned long dimm_num;
|
|
unsigned long dimm_num;
|
|
unsigned long ecc;
|
|
unsigned long ecc;
|
|
|
|
|
|
@@ -2321,105 +2446,7 @@ static void program_ecc(unsigned long *dimm_populated,
|
|
if (ecc == 0)
|
|
if (ecc == 0)
|
|
return;
|
|
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
|
|
#endif
|
|
|
|
|
|
@@ -2962,6 +2989,21 @@ static void test(void)
|
|
|
|
|
|
#else /* CONFIG_SPD_EEPROM */
|
|
#else /* CONFIG_SPD_EEPROM */
|
|
|
|
|
|
|
|
+/*-----------------------------------------------------------------------------+
|
|
|
|
+ * is_ecc_enabled
|
|
|
|
+ *-----------------------------------------------------------------------------*/
|
|
|
|
+static unsigned long is_ecc_enabled(void)
|
|
|
|
+{
|
|
|
|
+ unsigned long ecc;
|
|
|
|
+ unsigned long val;
|
|
|
|
+
|
|
|
|
+ ecc = 0;
|
|
|
|
+ mfsdram(SDRAM_MCOPT1, val);
|
|
|
|
+ ecc = max(ecc, SDRAM_MCOPT1_MCHK_CHK_DECODE(val));
|
|
|
|
+
|
|
|
|
+ return ecc;
|
|
|
|
+}
|
|
|
|
+
|
|
/*-----------------------------------------------------------------------------
|
|
/*-----------------------------------------------------------------------------
|
|
* Function: initdram
|
|
* Function: initdram
|
|
* Description: Configures the PPC4xx IBM DDR1/DDR2 SDRAM memory controller.
|
|
* Description: Configures the PPC4xx IBM DDR1/DDR2 SDRAM memory controller.
|
|
@@ -3106,7 +3148,7 @@ phys_size_t initdram(int board_type)
|
|
#endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
|
|
#endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
|
|
|
|
|
|
#if defined(CONFIG_DDR_ECC)
|
|
#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) */
|
|
#endif /* defined(CONFIG_DDR_ECC) */
|
|
|
|
|
|
#if defined(CONFIG_440)
|
|
#if defined(CONFIG_440)
|