Support for DDR with 32-data path. Addotional notes on injecting
authorRafal Jaworowski <raj@pollux.denx.de>
Thu, 16 Mar 2006 16:46:46 +0000 (17:46 +0100)
committerRafal Jaworowski <raj@pollux.denx.de>
Thu, 16 Mar 2006 16:46:46 +0000 (17:46 +0100)
multiple-bit errors.

board/mpc8349emds/mpc8349emds.c
cpu/mpc83xx/spd_sdram.c
doc/README.mpc8349emds.ddrecc
include/configs/MPC8349EMDS.h
include/spd_sdram.h

index a468c5a7b5ef6b3f448f3f16fbaca36f57a79292..73a33f68cec4ae73b0c6b101e91ee1acbe5a4035 100644 (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*/
index 06a7da8f063f7b6970a90aa220f88b0f36271db6..b4012a8ddfc0c30c2fbe11f1293b3c86dafc57e5 100644 (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 */
 
index d8edada5654c13c9abc39ac3a8faaf32a65f2893..401c0b687dab692c19031606578fb53ec189aa46 100644 (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:
index c2bd0f5cea007d1cffab907e9368435fb8b6bccf..39e3d95c3004e0990579824da16881051be5bae6 100644 (file)
 #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
 
 /*
index 4e754ec9e335af9383af02a32f7067c78a2480d7..a2be96c1aa1e993627dbf126a39b7348460c95f6 100644 (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