This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM6548: DDR3L Memory write leveling

Part Number: AM6548

Hi,

On our PCB with AM6548 SR2 we have an issue related to DDR3L memory training. We are using Micron memory MT41K64M16TW-107 XIT:J (two memory chips in x32 configuration). We have used TI EMIF tool for AM65xx. TI EMIF AM65xx - AM65x/DRA80xM EMIF Tool Spreadsheet.

We are using TI-RTOS SDK 6.03 (PDK107). Original board configuration file board_ddr.c from the board library was not modified just board_ddr_config.h was updated with timings created with AM65x/DRA80xM EMIF Tool.

On some boards training process finishes successfully on every temperature up to 105C (junction). On some boards DDR memory training process is failing very often. Each time when DDR memory training fails, the write leveling adjustment (function WriteLevelAdjustment() in board_ddr.c) is the step which actually fails. Failing is more often with increasing the temperature. Once the training process is finished, the DDR memory is working properly regardless of the temperature.

In the Technical note from Micron (TN-41-13) I've found out that write leveling is only useful if four or more DRAM devices are placed on the same side of the PCB using daisy-chain topology for the clock. 

So, my question would be: is there any option to skip the write leveling training process and use the hard coded values (that we can obtain from correct board initialization)?

If yes, what would be the procedure for this on AM6548 SR2?

Best regards,

Zoran Dukic

 

  • Hi,

    We do not support bypassing the training and hard coding values.

    If you swap the SOC between a passing board and a failing board, does the issue follow the SOC or the PCB?

    Thanks,
    Kevin

  • Hello Kevin,

    Thank you on the reply.
    I am also working with Zoran on this issue. We did not try replacing the SoC as this is somewhat tricky for us.
    However, I did further testing and discovered something interesting.

    We have one board in particular that fails DDR initialization every time when core temperature (measured by Sitara's internal sensor) reaches 70 deg C. I modified Secondary bootloader sbl_main.c so that Board_init(BOARD_INIT_DDR); is retried for 8 times.
    Sometimes on lower temperatures DDR init is successful after few iterations. But if temperature is over 70 deg C it falis in all 8 iterations all the time.

    However, if I connect via JTAG and use CCS gel files for Sitara initalization I have no problem with DDR initialization (Sitara's temperature is also over 70 dec C ). GEL files that we use are based on CCS ver 8.3 am65xx gels. Here only M4_R5orA53_Startup.gel was modified in OnTargetConnect() to use DDR3_800MHz_Initialization(); instead of DDR4.
    Also, file M4_DDR_Config.gel was obtained via TI AM65x/DRA80xM EMIF Tool.

    The same tool was used to generate board_ddr_config.h in PDK107 board library.
    Also, in board_ddr.c file I removed Board_enableVTTRegulator(); (I understod that it was used only for DDR4 and it was not present in DDR4_EVM.gel - DDR3_800MHz_Initialization()

    But this configuration of board library causes DDR init to fail on WriteLevelAdjustment() in board_ddr.c.

    When I further compared GEL files and board library I noticed that in DDR4_EVM.gel none of the training steps checks for the training error in DDRSS_DDRPHY_PGSR0 register. Also, I noticed that after each read of DDRSS_DDRPHY_PGSR0 register delay of 32 ctl_clk cycles is inserted.

    Thus I tried to insert the boardDDRDelay(); in all relevant training functions in board_ddr.c after reading of CSL_EMIF_PHYCFG_PGSR0.

    This improved situation significantly and now on the same board and in the same conditions (temp over 70 deg C) DDR init via SBL mostly succeds after few iterations. 

    Also memory test based on TI's mem_test.c in board\diag never reports any errors if DDR init is successful.

    Can you give me some hints on this?
    Should I further increase this delay after accessing CSL_EMIF_PHYCFG_PGSR0 register in board_ddr.c?

    Best regards,
    Milan

  • Hello Kevin,

    I did additional testing by adding more delay after accessing DDRSS_DDRPHY_PGSR0 register.
    I inserted triple boardDDRDelay() in all relevant training functions in board_ddr.c after reading of CSL_EMIF_PHYCFG_PGSR0.
    This improved the results even more.

    Now it rarely happens that DDR init fails on Write leveling steps on 1 out of 20 boots.
    However, second try in executing DDR init almost always succeeds. In the worst case (1 of more that 100 boots) on the third attempt DDR successfully pases all of the the Write leveling steps.
    I never experienced that DDR init fails in all eight trys (I did at least 300 tests on above mentioned problematic board on high temperatures- above 75 deg C).

    Inserting additional boardDDRDelay() delays (up to 6) makes no difference as it still can happen that sometimes DDR init fails in the first try.

    Do you know why we need this delay afte accessing DDRSS_DDRPHY_PGSR0 register?
    Is there something else we can try to address this problem?

    Best regards,
    Milan

  • Hi,

    >>Thus I tried to insert the boardDDRDelay(); in all relevant training functions in board_ddr.c after reading of CSL_EMIF_PHYCFG_PGSR0.

    I apologize for the delay. After discussing with a colleague, my understanding is that delays are required when accessing the PHY registers.

    Can you comment more on the statement above? Were delays not already included in the board_ddr.c file? For instance, are the following delays not already included? It appears that the "HW_WR_DDRPHY_REG32" / "HW_RD_DDRPHY_REG32" functions should also call the boardDDRDelay function.

    Does increasing BOARD_DDR_DELAY from 1000 to something larger have any impact? When compiling, are optimizations used? If so, can you try setting optimizations to 0 to see if this has any impact?

    Thanks,
    Kevin

        /************** WriteLevelAdjustment *************/
    
    static uint8_t WriteLevelAdjustment()
    {
        uint32_t regVal;
        /* PHY Initialization Register */
        HW_WR_DDRPHY_REG32(CSL_EMIF_PHYCFG_PIR, 0x0000801);
    
        /* must wait 10 clock cycles before polling for init done */
        boardDDRDelay();
    
        /* wait for training to be done */
        while((HW_RD_DDRPHY_REG32(CSL_EMIF_PHYCFG_PGSR0) & 0x80U) != 0x80U);
    
        /* wait another 32 ctl_clk cycles before resuming further traffic  */
        boardDDRDelay();
    
        regVal = HW_RD_DDRPHY_REG32(CSL_EMIF_PHYCFG_PGSR0);
        if(regVal & 0x800000)
    	return 0;
        else
    	return 1;
    }

  • Hello Kevin,

    Thank you on the reply and advices.
    In WriteLevelAdjustment() function there is no delay after the last read of  CSL_EMIF_PHYCFG_PGSR0 register.

    So I added one there and tried but only after adding two boardDDRDelay(); calls beavior improved significantly.
    Here is the final modification of WriteLevelAdjustment() function that we used:

        /************** WriteLevelAdjustment *************/
    
    static uint8_t WriteLevelAdjustment()
    {
        uint8_t status=1;
    
        /* PHY Initialization Register */
        HW_WR_DDRPHY_REG32(CSL_EMIF_PHYCFG_PIR, 0x0000801);
    
        /* must wait 10 clock cycles before polling for init done */
        boardDDRDelay();
        boardDDRDelay();
        boardDDRDelay();
        boardDDRDelay();
    
        /* wait for training to be done */
        while((HW_RD_DDRPHY_REG32(CSL_EMIF_PHYCFG_PGSR0) & 0x80U) != 0x80U);
    
        /* wait another 32 ctl_clk cycles before resuming further traffic  */
        boardDDRDelay();
        boardDDRDelay();
        boardDDRDelay();
        boardDDRDelay();
    
        if(HW_RD_DDRPHY_REG32(CSL_EMIF_PHYCFG_PGSR0) & 0x800000)
            status = 0;
    
        boardDDRDelay();
        boardDDRDelay();
        boardDDRDelay();
        boardDDRDelay();
        boardDDRDelay();
        boardDDRDelay();
    
    	return status;
    }

    This may look excessive but only after adding more than three boardDDRDelay(); we do not see any improvements in Write Leveling Adjustment failing.
    We tested this modificetion on one board we had most serious problems and on which Write leveling failed 50% of the times we powerd up the board on ambient temperature of 55 deg C (DDR init was retried up to 8 times on each boot). 
    Now of 500 boot tries DDR init was succesfull 468 times on the first try and 30 on the second and 2 times on the third try. In the end all 500 times board booted successfully in the end and run the application from DDR memory.
    So this seems to work for us now.

    Can we keep this modification or this number of added  boardDDRDelay() calls can cause some other problems that we missed?

    Regarding optimization I did not change default values for building board library (-O2?).
    I will try this as soon as I find enough time.

    Best regards,
    Milan

  • Milan, Do you have an update on this?

    Thanks,

    Kyle

  • Hello Kyle,

    Sorry for the late answer.
    We are using the change in board library  described above and currently it seems to work for us.
    Currently around 70 boards work without problems with DDR initialization.

    Best regards,
    Milan