Enabling ECC for layerscape ls1020a memory controllers

Showing results for 
Search instead for 
Did you mean: 

Enabling ECC for layerscape ls1020a memory controllers

Contributor I


We have a target board that is based on ls1020A. The DDR utilizes a 32 bit data word, with 4 ECC syndrome bits, for a total of 36 bits of data.  The DDR is non ECC  from Micron P/N MT41K128M16JT-125.

Normal DDR init sequence works just fine. When I try to enable the ECC of the memory controller by setting DDR_SDRAM_CFG[ECC_EN] = 1, getting the Automatic calibration Error ( DDR_ERROR_DETECT[ACE]  and DDR_ERROR_DETECT[MBE]  set.

Not sure what I am doing wrong. Can somebody help me on this?   Also if there is any application note, please point me towards that.

Following is the code snippet from the u-boot, memory initialization.

void ddrmc_init(void)


                struct ccsr_ddr *ddr = (struct ccsr_ddr *)CONFIG_SYS_FSL_DDR_ADDR;

                u32 temp_sdram_cfg, tmp;

                uint d_init;


                out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG);


                out_be32(&ddr->cs0_bnds, DDR_CS0_BNDS);

                out_be32(&ddr->cs0_config, DDR_CS0_CONFIG);


                out_be32(&ddr->timing_cfg_0, DDR_TIMING_CFG_0);

                out_be32(&ddr->timing_cfg_1, DDR_TIMING_CFG_1);

                out_be32(&ddr->timing_cfg_2, DDR_TIMING_CFG_2);

                out_be32(&ddr->timing_cfg_3, DDR_TIMING_CFG_3);

                out_be32(&ddr->timing_cfg_4, DDR_TIMING_CFG_4);

                out_be32(&ddr->timing_cfg_5, DDR_TIMING_CFG_5);



                out_be32(&ddr->sdram_cfg_2, DDR_SDRAM_CFG_2);

                out_be32(&ddr->ddr_cdr2, DDR_DDR_CDR2);



                out_be32(&ddr->sdram_mode, DDR_SDRAM_MODE);

                out_be32(&ddr->sdram_mode_2, DDR_SDRAM_MODE_2);


                out_be32(&ddr->sdram_data_init, CONFIG_SYS_DDR_DATA_INIT);


                out_be32(&ddr->sdram_interval, DDR_SDRAM_INTERVAL);


                out_be32(&ddr->ddr_wrlvl_cntl, DDR_DDR_WRLVL_CNTL);


                out_be32(&ddr->ddr_wrlvl_cntl_2, DDR_DDR_WRLVL_CNTL_2);

                out_be32(&ddr->ddr_wrlvl_cntl_3, DDR_DDR_WRLVL_CNTL_3);


                out_be32(&ddr->ddr_cdr1, DDR_DDR_CDR1);


                out_be32(&ddr->sdram_clk_cntl, DDR_SDRAM_CLK_CNTL);

                out_be32(&ddr->ddr_zq_cntl, DDR_DDR_ZQ_CNTL);


                out_be32(&ddr->cs0_config_2, DDR_CS0_CONFIG_2);


                /* DDR erratum A-009942 */

                tmp = in_be32(&ddr->debug[28]);

                out_be32(&ddr->debug[28], tmp | 0x0070006f);




#if defined (CONFIG_DDR_ECC)

                out_be32(&ddr->err_int_en, CONFIG_SYS_DDR_ERR_INT_EN);

                out_be32(&ddr->err_disable, CONFIG_SYS_DDR_ERR_DIS);

                out_be32(&ddr->err_sbe, CONFIG_SYS_DDR_SBE);




                d_init = 1;


                 * Poll until memory is initialized.

                 * 512 Meg at 400 might hit this 200 times or so.


                while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0) {



                debug("DDR: memory initialized\n\n");




                temp_sdram_cfg = (DDR_SDRAM_CFG_MEM_EN & ~SDRAM_CFG_BI);

#if defined (CONFIG_DDR_ECC)

                out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG_ECC_EN | DDR_SDRAM_CFG | temp_sdram_cfg);


out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG | temp_sdram_cfg);





#if defined (CONFIG_DDR_ECC)

                out_be32(&ddr->err_int_en, CONFIG_SYS_DDR_ERR_INT_EN);

                out_be32(&ddr->err_disable, CONFIG_SYS_DDR_ERR_DIS);

                out_be32(&ddr->err_sbe, CONFIG_SYS_DDR_SBE);



Following are the macro definitions.

#define DDR_SDRAM_CFG                                           0x470c0008

#define DDR_CS0_BNDS                                               0x008000bf

#define DDR_CS0_CONFIG                                          0x80014302

#define DDR_TIMING_CFG_0                      0x50550004

#define DDR_TIMING_CFG_1                      0xbcb38c56

#define DDR_TIMING_CFG_2                      0x0040d120

#define DDR_TIMING_CFG_3                      0x010e1000

#define DDR_TIMING_CFG_4                      0x00000001

#define DDR_TIMING_CFG_5                      0x03401400

#define DDR_SDRAM_CFG_2                                      0x00401010

#define DDR_SDRAM_MODE                                      0x00061c60

#define DDR_SDRAM_MODE_2                 0x00180000

#define DDR_SDRAM_INTERVAL                               0x18600618

#define DDR_DDR_WRLVL_CNTL                              0x8655f605

#define DDR_DDR_WRLVL_CNTL_2                          0x05060607

#define DDR_DDR_WRLVL_CNTL_3                          0x05050505

#define DDR_DDR_CDR1                                              0x80040000

#define DDR_DDR_CDR2                                              0x00000001

#define DDR_SDRAM_CLK_CNTL                               0x02000000

#define DDR_DDR_ZQ_CNTL                                       0x89080600

#define DDR_CS0_CONFIG_2                      0

#define DDR_SDRAM_CFG_MEM_EN                      0x80000000

#define DDR_SDRAM_CFG_ECC_EN                         0x20000000

#define SDRAM_CFG2_D_INIT                   0x00000010

#define DDR_CDR2_VREF_TRAIN_EN                      0x00000080

#define SDRAM_CFG2_FRC_SR                  0x80000000

#define SDRAM_CFG_BI                                               0x00000001


/*ECC Related configuration*/

#define CONFIG_SYS_DDR_ERR_INT_EN               0x0000000F

#define CONFIG_SYS_DDR_ERR_DIS                        0xFFFFFFF0

#define CONFIG_SYS_DDR_SBE                 0x00010000

#define CONFIG_SYS_DDR_DATA_INIT        0xdeadbeef

0 Kudos
1 Reply

Contributor I

Hi Senthilganpathy,

I have a question which is unrelated to you question :-)
Can you tell me how to find out what is the ODT values you are setting from this code and what part of code should be modified to change those ODT values.

Thank you.

0 Kudos