How to Check/Validate DDR3 ECC functionality in T2080 Processor Board?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to Check/Validate DDR3 ECC functionality in T2080 Processor Board?

Jump to solution
4,261 Views
karunakaranradh
Contributor IV

Hi,

In our processor board, 4GB DDR3 RAM with ECC chip are connected to CS0 of T2080 Processor DDR controller. Processor are booted fine with ECC enabled on the DDR controller.

I want to know,

     1) How to ensure the ECC functionality are proper?

     2) Is it is possible to generate bit error to validate the ECC functionality in DDR3?

Thanks & Regards

Karunakaran R

1 Solution
2,697 Views
Bulat
NXP Employee
NXP Employee

The DDR controller allows to inject errors into the memory. This feature uses three registers, DDR_DATA_ERR_INJECT_HI, DDR_DATA_ERR_INJECT_LO, DDR_ECC_ERR_INJECT, see the Ref Manual for details. After injection you can test "erroneous" location and check reaction of the DDR controller. For example, if a single bit error was injected, DDR_ERR_SBE[SBEC] will be incremented every time when you read erroneous location. The data should be error free.

Regards,

Bulat

View solution in original post

0 Kudos
Reply
7 Replies
2,698 Views
Bulat
NXP Employee
NXP Employee

The DDR controller allows to inject errors into the memory. This feature uses three registers, DDR_DATA_ERR_INJECT_HI, DDR_DATA_ERR_INJECT_LO, DDR_ECC_ERR_INJECT, see the Ref Manual for details. After injection you can test "erroneous" location and check reaction of the DDR controller. For example, if a single bit error was injected, DDR_ERR_SBE[SBEC] will be incremented every time when you read erroneous location. The data should be error free.

Regards,

Bulat

0 Kudos
Reply
2,697 Views
karunakaranradh
Contributor IV

Hi Bulat,

Thanks for your reply.

I am not able to generate single bit error, The following steps are followed for generate single bit error:

Step 1:

Initialize the SBEC with zero and SBET set to 255 in DDR_ERR_SBE.

Step 2:

Value 0x1 written on DDR_DATA_ERR_INJECT_HI and 0x0 on DDR_DATA_ERR_INJECT_LO.

Step 3:

Enable EIEN bit in DDR_ECC_ERR_INJECT Registers.

Step 4:

write 0x76543210 on some ddr memory location.

Step 5:

Disable EIEN bit in DDR_ECC_ERR_INJECT Registers.

Step 6:

Read the same location

Step 7:

write 0x12345678 on same ddr memory location where the 0x76543210 data written.

Step 8:

Check the SBEC value on DDR_ERR_SBE Register.

The read value of SBEC is zero.

Kindly suggest us, how to generate single bit error.

Thanks & Regards

Karunakaran R

0 Kudos
Reply
2,697 Views
Bulat
NXP Employee
NXP Employee

Make sure that the data cache is disabled for DDR area you are testing.

Regards,

Bulat

0 Kudos
Reply
2,697 Views
karunakaranradh
Contributor IV

Hi Bulat,

After disabled the data cache before doing any read/write operation. still ecc error is not generated by DDR controller.

I am using the below u-boot code to generate the single bit error:

===============================================================================

register u64 *i;

u64 *addr = 0x200000;

u32 count = 0x10;

/*Initilize the ret variable*/

    u64 ret = 0xffffffffffffffffUL;

/* The pattern is written into memory to generate error */

u64 pattern = 0xfedcba9876543210UL;

/* After injecting error, re-initialize the memory with the value */

u64 writeback = 0x0123456789abcdefUL;

/*one bit mask in the higher 32 bit*/

ddr->data_err_inject_hi = 0x1;

/*clear all mask in lower 32bit*/

ddr->data_err_inject_lo = 0x0;

/*Disable the interrupts*/

disable_interrupts();

/*Diabled Data cache*/

dcache_disable();

for (i = addr; i < addr + count; i++) {

        /* enable injects */

        ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;

        /* write memory location injecting errors */

        *((u64 *) i) = pattern;

     

        /* disable injects */

        ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;

        /* read data, this generates ECC error */

        ret = *((u64 *) i);

        /* re-initialize memory, double word write the location again,

         * generates new ECC code this time */

        *((u64 *) i) = writeback;

}

/*Enabled Data cache*/

dcache_enable();

/*Enable the interrupts*/

enable_interrupts();

===============================================================================

Any sequence,I missed?

Regards,

Karunakaran R

0 Kudos
Reply
2,697 Views
Bulat
NXP Employee
NXP Employee

I am not sure that the data cache is really disabled. To get cache-inhibit operations you need to set 'cache-Inhibit' attributes in DDR related MMU pages, i.e. WIMGE =0bx1xxx.

0 Kudos
Reply
2,697 Views
karunakaranradh
Contributor IV

Hi Bulat,

i changed the following the sequence and test more than 1mb data to generate the single bit error.

Step 1:

Initialize the SBEC with zero and SBET set to 255 in DDR_ERR_SBE.

Step 2:

Value 0x1 written on DDR_DATA_ERR_INJECT_HI and 0x0 on DDR_DATA_ERR_INJECT_LO.

Step 3:

Enable EIEN bit in DDR_ECC_ERR_INJECT Registers.

Step 4:

write 0x0123456789abcdef patterns in 1MB of ddr memory location.

Step 5:

Disable EIEN bit in DDR_ECC_ERR_INJECT Registers.

Step 6:

read the same 1MB patterns from the  ddr memory location.

Step7:

Verify the same pattern.whether it is corrected /not

Step 8:

Check the SBEC value on DDR_ERR_SBE Register.

With that above sequence single bit error was generated.

Thanks for your support...:smileyhappy:

Regards

Karunakaran R

2,697 Views
sreeragag
Contributor II

Hi,

I tried single bit ECC for Ls1046ardb board with the step mentioned above. I did not able to get the DDR_ERR_SBE   register value updates. when I access the memory location this has written to the corresponding locations. Is there any other settings to  be done which I might have missed? 

I also tried with DATA_ERR_INJECT_HI = 0x00000000DATA_ERR_INJECT_LO = 0x00000000, DDR_MTCR =0x00000001.

below is the snippet with which I worked.

void do_ecc(){
u32 *i;
puts("ECC checking\n");
u32 *addr = (u32 *)0x80000000;
u32 count = 0x10;
u32 pattern = 0xfedcba98UL;
u32 writeback = 0x89abcdefUL;
u32 ret = 0xffffffffUL;
struct ccsr_ddr *ddr = (struct ccsr_ddr *)0x01080000;
disable_interrupts();
dcache_disable();

ddr->mtcr |= 0x00008001;
ddr->err_sbe |= 0x0000ff00;
ddr->data_err_inject_hi |= 0x00000000;
ddr->data_err_inject_lo |= 0x00000001;
ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;

for (i = addr; i < addr + count; i++) {


*((u32 *) i) = pattern;


ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;


ret = *((u32 *) i);


*((u32 *) i) = writeback;
}
dcache_enable();

enable_interrupts();
}

0 Kudos
Reply