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.

AM5718: EMIF Tools hardware leveling issue

Part Number: AM5718
Other Parts Discussed in Thread: DRA722

Hello,

My customer noticed the EMIF Tools (rev 2.0.0, 28-Mar-2017) generate an init value for the EMIF_DDR_PHY_CONTROL_1 register of 0x0x0824402b. (This could be replicated from the original EMIF Tools Excel file, selecting AM571x in the System Application Details, and leaving all the other fields unchanged.)

This has the effect of masking the read data eye training during the full leveling command as RDLVL_MASK = 1. This is against the TI recommendation of using full hardware leveling for the DDR interface. I heard (see thread notes) this may be due to some marginality in the hardware read leveling process, but I found no further information about this. On the other hand, U-Boot from our latest Processor SDK enables full hardware leveling as it sets EMIF_DDR_PHY_CONTROL_1 = 0x0024400b (file $u-boot_source_dir/board/ti/am57xx/board.c).

Could I get a clear statement about which DDR leveling one should use for AM5718? Thank you.


Regards,
François.

  • The factory team have been notified. They will respond here.
  • Fancois,
    Just to be sure, you are talking about the high reliability part of Catalog Processor part?
  • Hi Rogerio,

    Catalog Processor. Indeed I have an AM5718-EP question I am addressing separately with the HiRel team.

    Thanks,
    François.
  • Francois
    Sorry for the delay in responding to this. The designated expert is out of office this week, so there will be some delays in response.
    I expect to have some further guidance by coming Monday , if not earlier.

    Regards
    Mukul
  • Hello

    Our board uses Sitara AM5718 connected to ISSI DDR3 device (ref IS46TR16256AL-125KBLA2), operating at 532MHz.

    http://www.issi.com/WW/pdf/43-46TR16256A-85120AL.pdf

    The Sitara is configured according to the EMIF tool provided in attachment with the following exceptions:

    - ref_ctrl = 0x200040F1 (SRT activated instead of ASR, because first version of EMIF tool had no extended temp mode)

    - ref_ctrl_final  = 0x2000081A (same reason)

    - sdram_tim3 = 0x409F88A8 (instead of 0x407F88A8) because TCKESR timing was deemed marginal

    - read_idle_ctrl = 0x00090000 (instead of 0x00050000) similar to what was done on TI eval board.

    - emif_ddr_phy_ctlr_1_init = 0x0024400B (instead of 0x0824400B) to have full leveling activated.

    With this configuration we run a standard memory test and observe intermittent memory failures at hot temperature (near 80°C). No issue observed so far at room and cold.

    Can you please provide feedback on this configuration, in particular:

    - Should leveling be disabled as recommended by the EMIF tool or enabled as recommended in datasheet ?

    - Should we rather use ASR mode than SRT for extended temperature range ? Is there a performance impact to use one vs the other ?

    - Is there a particular recommendation for IO slew rate (we use minimal to reduce EMI).

    - Any other recommandation ?

    Thanks for your support

    Mathieu

    Copie de SPRAC36A_EMIF_RegisterConfig.zip

  • Hi Mathieu,

    I have just talked to our expert who will come back to you on the above.

    I see the memory you use is rated at up to 105 degC case temperature. The AM5718 version you are using is rated at 125 degC junction temperature, which should correspond to something close to 105 degC case temperature as well.

    During your memory testing, are you checking the temperature within your system enclosure? What does it look like?


    Thanks,
    François.
  • Tests shows that the board temperature near the Sitara and DDR location is less than 10°C above the external temperature.

    We observed failures above 75°C external, corresponding to 85°C board temperature.

    Note that we have run the same test on Silicon Rev1 device without any issue.

  • Mathieu

    Mathieu Conq said:

    Our board uses Sitara AM5718 connected to ISSI DDR3 device (ref IS46TR16256AL-125KBLA2), operating at 532MHz.

    http://www.issi.com/WW/pdf/43-46TR16256A-85120AL.pdf

    The Sitara is configured according to the EMIF tool provided in attachment with the following exceptions:

    - ref_ctrl = 0x200040F1 (SRT activated instead of ASR, because first version of EMIF tool had no extended temp mode)

    - ref_ctrl_final  = 0x2000081A (same reason)

    The above settings are fine for extended temperature range.
    Mathieu Conq said:

    - sdram_tim3 = 0x409F88A8 (instead of 0x407F88A8) because TCKESR timing was deemed marginal

    Can you elaborate a bit more on this? How did you determine this particular timing parameter is marginal? Do you see memory fails during self-refresh? 

    Mathieu Conq said:

    - read_idle_ctrl = 0x00090000 (instead of 0x00050000) similar to what was done on TI eval board.

    OK.

    Mathieu Conq said:

    - emif_ddr_phy_ctlr_1_init = 0x0024400B (instead of 0x0824400B) to have full leveling activated.

    With this setting, you will have Read data eye training also activated. For AM571x/AM570x, we recommend to disable Read data eye training and use a fixed value as suggested in the tool. Do note that there are PCB skew matching requirements for DQS and Data as noted in the Data sheet. Can you re-try your tests with the tool suggested settings to verify if the fails are related to this setting?

    Mathieu Conq said:

    With this configuration we run a standard memory test and observe intermittent memory failures at hot temperature (near 80°C). No issue observed so far at room and cold.

    Could you help elaborate on the type of fails you see here. For eg. Can you narrow down to READ or WRITE related?

    Do you see fails at a lower frequency say 400MHz?

    Are the fails permanent i.e. when the data appears corrupt does changing the temperature after the fail show any impact on the tests?

    Can you check if the Tcase of the DRAM part and if it is within the operating temperature range of the DRAM?

    Mathieu Conq said:

    Can you please provide feedback on this configuration, in particular:

    - Should leveling be disabled as recommended by the EMIF tool or enabled as recommended in datasheet ?

    I suggest you try with the Read data eye training disabled and see if there is any impact on the results. I don't believe at 533MHz operation, enabling or disabling should have an impact on the fails, but I suggest you try this test

    Mathieu Conq said:

    - Should we rather use ASR mode than SRT for extended temperature range ? Is there a performance impact to use one vs the other ?

    SRT/ASR are required only when the DRAM is in self-refresh at higher temperatures (Tcase > 85C). For normal operation, I see you already have set the refresh rate to 2x normal rate (3.9us). Using SRT and disabling ASR is fine. If you use SRT, the internal DRAM refresh rate is 2x normal rate regardless of the Tc.

    Mathieu Conq said:

    - Is there a particular recommendation for IO slew rate (we use minimal to reduce EMI).

    The recommendation from the tool is based on our TI EVM implementation. If you chose to change the settings, it is recommended to run signal integrity simulations to verify the IO settings

    Mathieu Conq said:

    - Any other recommandation ?

    I see that in your Step3-DDR Timings, some of the timing parameters correspond to DDR3L-1333 and some parameters correspond to 1066 speed grades. Technically, since you are running the DDR3L at 1066 data rate i.e. 533MHz clock, you can use 1066. Is there a specific reason you used a mix of values?

    Please also verify the DDR_VREF, VDDS_DDR to make sure they are within the operating range.

    Please also change the frequency to a lower value to assess if the DRAM failures occurs at high temperature

    Regards, Siva

  • Hi Mathieu

    Did you mean to indicate that the Board Temperature is < Ambient Temperature + 10C? Is it possible for you to also capture the Tcase specifically for the DRAM device?

    Regards, Siva
  • Hello Sivak

    The board is in a sealed unit when I run this test so it's complicated to attach a thermocouple on the DDR case.
    However we ran an instrumented test a while ago which showed that board temperature near the parts would be less than 10°C above the thermal chamber temperature. Our thermal analysis shows that we are still within the temperature range for this part.

    Up to now we tested 3 different configurations:
    - The one identified in first message of the forum: works fine with SR1, failed with SR2 at hot (and became OK after decreasing the temp, failed again after increasing)
    - The same with ASR instead of SRT. A bit better: failed at hot after ~4 hours.
    - The configuration from the EMIF tool (with no deviations) : Failed at hot after few hours.

    Any reason why SR1 would have different behavior than SR2 ?

    Thanks
    Mathieu
  • Hi Mathieu,

    Don't you have any temperature sensor inside your enclosure that tells the actual state of your system? Assuming your test is quite heavy on the DDR memory, its power consumption must be close to 200 mA (page 53 of the DDR datasheet), or 300 mW. As their is no airflow in your sealed system, this corresponds to 10 degC temperature difference between the DDR junction and the ambient air (theta ja ≈ 30, section 3.4 of the DDR datasheet). So if the air in the system enclosure is at the board temperature which is itself 10 degC above your test chamber temperature, the DDR junction temperature is close to 100 degC. That's still within its rated range, but getting close. Also, the temperature is not even in your enclosure and the DDR memories are close to the AM5718 processor. It could be worth having a second look at your thermal simulations if you do not have thermal sensors in your system. By the way, I have used our power estimation tool (link) to estimate the power consumption of the AM5718 processor. With all default settings but 105 degC junction temperature, maximum estimation mode, 532 MHz DDR3L, 10% CPU load / Dhrystone profile, 1 GB/s DDR writes and 1 GB/s DDR reads, we are at 1.55 W.

    If you do not have a temperature sensor in your system, it could be worth running the test with no enclosure in a test chamber that's 10 degrees hotter than when you run a test with an enclosure. This way you could place a temperature probe on the DDR memory package (and AM5718 processor too while you are at it).

    Also, which error do you observe? Is it your test that reports a DDR data error, or does the AM5718 processor become unresponsive? One note: have you ensured your test code always runs from the processor internal memory (L1, L2 or L3 RAM), except of course during its first execution while it is read from DDR to the internal memory? If that's not the case, it will be difficult to tell if the error happens because the DDR memory lost some bits because of the high temperature or because the AM5718 EMIF configuration is incorrect, or even if the AM5718 processor crashed because of a temperature that's too high.

    About your question about SR 1.0 and SR 2.0, that's difficult to tell because if I am correct, you have run tests on a very limited number of systems, so the variations you observe may simply be related to silicon variations if the root cause is the DDR memory losing some bits because of a too high temperature, or the AM5718 processor running at a temperature above its rating. On SR 1.0, have you tried to push the tests above 80 degC to see how much margin you got there?


    Thanks,
    François.

  • Mathieu

    I agree with Francois. We need to have better understanding of the DRAM temperature and if it is within the operating range for the DRAM. I don't see SR1 vs. SR2 contributing here since we know there are not any changes on the DDR interface between the SR1 vs. SR2. However, as Francois also pointed out, there is going to be Silicon process variation across different units. Are you able to make SR1 fail with a higher elevated temperature? If so, what is that temperature? Also, is the DRAM the same between the SR1 and SR2 boards?

    Your observation regarding ASR vs. SRT is not clear to me. Are you saying it is better because it failed after a longer time? If so, does the test with SRT fail consistently after the same duration?

    You may also want to repeat with test with a different memory just to rule out any specific DRAM related issues here.

    Regards, Siva
  • Sivak

    Please find attached the Baseline configuration of the EMIF tool (filled with parameters from the datasheet) and provide feedback.

    SPRAC36A_EMIF_RegisterConfig_baseline.zip

    Thanks

    Mathieu

  • Mathieu

    A few comments here:
    - In Step1-System Details, you set the DDR Data Bus width per EMIF as 16. Did you mean to indicate 32 instead of 16? I thought you are using the full 32 bit bus
    - In Step1-DDR Memory Specifications, since you are running the DRAM at 1066, you can use 1066 instead of 1600. Any reason you set this to 1600? Some of the timing parameters such as tAA, tRCD, tRP, tRAS etc. are dependent on the speed grade selection

    Regards, Siva
  • Hi Mathieu,

    From the Linux prompt, you may read the junction temperature of the AM5718 processor with the following command:

    cat /sys/class/thermal/thermal_zone0/temp

    As you may see in the application report "AM572x Thermal Considerations" (link), Figure 3 shows how much the junction temperature raises above the ambient temperature. Although this application report refers to the AM572x processors, Figure 3 reports data when running code on a single Cortex A15 core, so we could consider it is a good approximation of AM5718.


    Best regards,
    François.

  • Hello

    Attached is the SDRAM.c file from u-boot that highlights a difference between SR1 and SR2 timings.

    Extract of the code:

     case DRA722_ES1_0:

      *regs = dra_ddr3_ext_phy_ctrl_const_base_666MHz;
      *size = ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_666MHz);
      break;
     case DRA722_ES2_0:
      *regs = dra_ddr3_ext_phy_ctrl_const_base_666MHz_es2;
      *size = ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_666MHz_es2);
      break;

    /*
     * Timing and Organization details of the ddr device parts used in OMAP5
     * EVM
     *
     * (C) Copyright 2010
     * Texas Instruments, <www.ti.com>
     *
     * Aneesh V <aneesh@ti.com>
     * Sricharan R <r.sricharan@ti.com>
     *
     * SPDX-License-Identifier:	GPL-2.0+
     */
    
    #include <asm/emif.h>
    #include <asm/arch/sys_proto.h>
    
    /*
     * This file provides details of the LPDDR2 SDRAM parts used on OMAP5
     * EVM. Since the parts used and geometry are identical for
     * evm for a given OMAP5 revision, this information is kept
     * here instead of being in board directory. However the key functions
     * exported are weakly linked so that they can be over-ridden in the board
     * directory if there is a OMAP5 board in the future that uses a different
     * memory device or geometry.
     *
     * For any new board with different memory devices over-ride one or more
     * of the following functions as per the CONFIG flags you intend to enable:
     * - emif_get_reg_dump()
     * - emif_get_dmm_regs()
     * - emif_get_device_details()
     * - emif_get_device_timings()
     */
    
    #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
    const struct emif_regs emif_regs_532_mhz_2cs = {
    	.sdram_config_init		= 0x80800EBA,
    	.sdram_config			= 0x808022BA,
    	.ref_ctrl			= 0x0000081A,
    	.sdram_tim1			= 0x772F6873,
    	.sdram_tim2			= 0x304a129a,
    	.sdram_tim3			= 0x02f7e45f,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x000b3215,
    	.temp_alert_config		= 0x08000a05,
    	.emif_ddr_phy_ctlr_1_init	= 0x0E28420d,
    	.emif_ddr_phy_ctlr_1		= 0x0E28420d,
    	.emif_ddr_ext_phy_ctrl_1	= 0x04020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x28C518A3,
    	.emif_ddr_ext_phy_ctrl_3	= 0x518A3146,
    	.emif_ddr_ext_phy_ctrl_4	= 0x0014628C,
    	.emif_ddr_ext_phy_ctrl_5	= 0x04010040
    };
    
    const struct emif_regs emif_regs_532_mhz_2cs_es2 = {
    	.sdram_config_init		= 0x80800EBA,
    	.sdram_config			= 0x808022BA,
    	.ref_ctrl			= 0x0000081A,
    	.sdram_tim1			= 0x772F6873,
    	.sdram_tim2			= 0x304a129a,
    	.sdram_tim3			= 0x02f7e45f,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x100b3215,
    	.temp_alert_config		= 0x08000a05,
    	.emif_ddr_phy_ctlr_1_init	= 0x0E30400d,
    	.emif_ddr_phy_ctlr_1		= 0x0E30400d,
    	.emif_ddr_ext_phy_ctrl_1	= 0x04020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x28C518A3,
    	.emif_ddr_ext_phy_ctrl_3	= 0x518A3146,
    	.emif_ddr_ext_phy_ctrl_4	= 0x0014628C,
    	.emif_ddr_ext_phy_ctrl_5	= 0xC330CC33,
    };
    
    const struct emif_regs emif_regs_266_mhz_2cs = {
    	.sdram_config_init		= 0x80800EBA,
    	.sdram_config			= 0x808022BA,
    	.ref_ctrl			= 0x0000040D,
    	.sdram_tim1			= 0x2A86B419,
    	.sdram_tim2			= 0x1025094A,
    	.sdram_tim3			= 0x026BA22F,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x000b3215,
    	.temp_alert_config		= 0x08000a05,
    	.emif_ddr_phy_ctlr_1_init	= 0x0E28420d,
    	.emif_ddr_phy_ctlr_1		= 0x0E28420d,
    	.emif_ddr_ext_phy_ctrl_1	= 0x04020080,
    	.emif_ddr_ext_phy_ctrl_2	= 0x0A414829,
    	.emif_ddr_ext_phy_ctrl_3	= 0x14829052,
    	.emif_ddr_ext_phy_ctrl_4	= 0x000520A4,
    	.emif_ddr_ext_phy_ctrl_5	= 0x04010040
    };
    
    const struct emif_regs emif_regs_ddr3_532_mhz_1cs = {
    	.sdram_config_init		= 0x61851B32,
    	.sdram_config			= 0x61851B32,
    	.sdram_config2			= 0x0,
    	.ref_ctrl			= 0x00001035,
    	.sdram_tim1			= 0xCCCF36B3,
    	.sdram_tim2			= 0x308F7FDA,
    	.sdram_tim3			= 0x027F88A8,
    	.read_idle_ctrl			= 0x00050000,
    	.zq_config			= 0x0007190B,
    	.temp_alert_config		= 0x00000000,
    	.emif_ddr_phy_ctlr_1_init	= 0x0020420A,
    	.emif_ddr_phy_ctlr_1		= 0x0024420A,
    	.emif_ddr_ext_phy_ctrl_1	= 0x04040100,
    	.emif_ddr_ext_phy_ctrl_2	= 0x00000000,
    	.emif_ddr_ext_phy_ctrl_3	= 0x00000000,
    	.emif_ddr_ext_phy_ctrl_4	= 0x00000000,
    	.emif_ddr_ext_phy_ctrl_5	= 0x04010040,
    	.emif_rd_wr_lvl_rmp_win		= 0x00000000,
    	.emif_rd_wr_lvl_rmp_ctl		= 0x80000000,
    	.emif_rd_wr_lvl_ctl		= 0x00000000,
    	.emif_rd_wr_exec_thresh		= 0x00000305
    };
    
    const struct emif_regs emif_regs_ddr3_532_mhz_1cs_es2 = {
    	.sdram_config_init              = 0x61851B32,
    	.sdram_config                   = 0x61851B32,
    	.sdram_config2			= 0x0,
    	.ref_ctrl                       = 0x00001035,
    	.sdram_tim1                     = 0xCCCF36B3,
    	.sdram_tim2                     = 0x308F7FDA,
    	.sdram_tim3                     = 0x027F88A8,
    	.read_idle_ctrl                 = 0x00050000,
    	.zq_config                      = 0x1007190B,
    	.temp_alert_config              = 0x00000000,
    	.emif_ddr_phy_ctlr_1_init       = 0x0030400A,
    	.emif_ddr_phy_ctlr_1            = 0x0034400A,
    	.emif_ddr_ext_phy_ctrl_1        = 0x04040100,
    	.emif_ddr_ext_phy_ctrl_2        = 0x00000000,
    	.emif_ddr_ext_phy_ctrl_3        = 0x00000000,
    	.emif_ddr_ext_phy_ctrl_4        = 0x00000000,
    	.emif_ddr_ext_phy_ctrl_5        = 0x4350D435,
    	.emif_rd_wr_lvl_rmp_win         = 0x00000000,
    	.emif_rd_wr_lvl_rmp_ctl         = 0x80000000,
    	.emif_rd_wr_lvl_ctl             = 0x00000000,
    	.emif_rd_wr_exec_thresh         = 0x40000305
    };
    
    const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = {
    	.dmm_lisa_map_0 = 0x0,
    	.dmm_lisa_map_1 = 0x0,
    	.dmm_lisa_map_2 = 0x80740300,
    	.dmm_lisa_map_3 = 0xFF020100,
    	.is_ma_present	= 0x1
    };
    
    static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs)
    {
    	switch (omap_revision()) {
    	case OMAP5430_ES1_0:
    		*regs = &emif_regs_532_mhz_2cs;
    		break;
    	case OMAP5432_ES1_0:
    		*regs = &emif_regs_ddr3_532_mhz_1cs;
    		break;
    	case OMAP5430_ES2_0:
    		*regs = &emif_regs_532_mhz_2cs_es2;
    		break;
    	case OMAP5432_ES2_0:
    	default:
    		*regs = &emif_regs_ddr3_532_mhz_1cs_es2;
    		break;
    	}
    }
    
    void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
    	__attribute__((weak, alias("emif_get_reg_dump_sdp")));
    
    static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs
    						**dmm_lisa_regs)
    {
    	switch (omap_revision()) {
    	case OMAP5430_ES1_0:
    	case OMAP5430_ES2_0:
    	case OMAP5432_ES1_0:
    	case OMAP5432_ES2_0:
    	default:
    		*dmm_lisa_regs = &lisa_map_4G_x_2_x_2;
    		break;
    	}
    
    }
    
    void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
    	__attribute__((weak, alias("emif_get_dmm_regs_sdp")));
    #else
    
    static const struct lpddr2_device_details dev_4G_S4_details = {
    	.type		= LPDDR2_TYPE_S4,
    	.density	= LPDDR2_DENSITY_4Gb,
    	.io_width	= LPDDR2_IO_WIDTH_32,
    	.manufacturer	= LPDDR2_MANUFACTURER_SAMSUNG
    };
    
    static void emif_get_device_details_sdp(u32 emif_nr,
    		struct lpddr2_device_details *cs0_device_details,
    		struct lpddr2_device_details *cs1_device_details)
    {
    	/* EMIF1 & EMIF2 have identical configuration */
    	*cs0_device_details = dev_4G_S4_details;
    	*cs1_device_details = dev_4G_S4_details;
    }
    
    void emif_get_device_details(u32 emif_nr,
    		struct lpddr2_device_details *cs0_device_details,
    		struct lpddr2_device_details *cs1_device_details)
    	__attribute__((weak, alias("emif_get_device_details_sdp")));
    
    #endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
    
    const u32 ext_phy_ctrl_const_base[] = {
    	0x01004010,
    	0x00001004,
    	0x04010040,
    	0x01004010,
    	0x00001004,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x80080080,
    	0x00800800,
    	0x08102040,
    	0x00000001,
    	0x540A8150,
    	0xA81502a0,
    	0x002A0540,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000077,
    	0x0
    };
    
    const u32 ddr3_ext_phy_ctrl_const_base_es1[] = {
    	0x01004010,
    	0x00001004,
    	0x04010040,
    	0x01004010,
    	0x00001004,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x80080080,
    	0x00800800,
    	0x08102040,
    	0x00000002,
    	0x0,
    	0x0,
    	0x0,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000057,
    	0x0
    };
    
    const u32 ddr3_ext_phy_ctrl_const_base_es2[] = {
    	0x50D4350D,
    	0x00000D43,
    	0x04010040,
    	0x01004010,
    	0x00001004,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x80080080,
    	0x00800800,
    	0x08102040,
    	0x00000002,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000000,
    	0x00000057,
    	0x0
    };
    
    /* Ext phy ctrl 1-35 regs */
    const u32
    dra_ddr3_ext_phy_ctrl_const_base_es1_emif1[] = {
    	0x10040100,
    	0x00910091,
    	0x00950095,
    	0x009B009B,
    	0x009E009E,
    	0x00980098,
    	0x00340034,
    	0x00350035,
    	0x00340034,
    	0x00310031,
    	0x00340034,
    	0x007F007F,
    	0x007F007F,
    	0x007F007F,
    	0x007F007F,
    	0x007F007F,
    	0x00480048,
    	0x004A004A,
    	0x00520052,
    	0x00550055,
    	0x00500050,
    	0x00000000,
    	0x00600020,
    	0x40011080,
    	0x08102040,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0
    };
    
    /* Ext phy ctrl 1-35 regs */
    const u32
    dra_ddr3_ext_phy_ctrl_const_base_es1_emif2[] = {
    	0x10040100,
    	0x00910091,
    	0x00950095,
    	0x009B009B,
    	0x009E009E,
    	0x00980098,
    	0x00330033,
    	0x00330033,
    	0x002F002F,
    	0x00320032,
    	0x00310031,
    	0x007F007F,
    	0x007F007F,
    	0x007F007F,
    	0x007F007F,
    	0x007F007F,
    	0x00520052,
    	0x00520052,
    	0x00470047,
    	0x00490049,
    	0x00500050,
    	0x00000000,
    	0x00600020,
    	0x40011080,
    	0x08102040,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0
    };
    
    /* Ext phy ctrl 1-35 regs */
    const u32
    dra_ddr3_ext_phy_ctrl_const_base_666MHz[] = {
    	0x10040100,
    	0x00A400A4,
    	0x00A900A9,
    	0x00B000B0,
    	0x00B000B0,
    	0x00A400A4,
    	0x00390039,
    	0x00320032,
    	0x00320032,
    	0x00320032,
    	0x00440044,
    	0x00550055,
    	0x00550055,
    	0x00550055,
    	0x00550055,
    	0x007F007F,
    	0x004D004D,
    	0x00430043,
    	0x00560056,
    	0x00540054,
    	0x00600060,
    	0x0,
    	0x00600020,
    	0x40010080,
    	0x08102040,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0,
    	0x0
    };
    
    const u32 dra_ddr3_ext_phy_ctrl_const_base_666MHz_es2[] = {
    	0x04040100,
    	0x006B009F,
    	0x006B00A2,
    	0x006B00A8,
    	0x006B00A8,
    	0x006B00B2,
    	0x002F002F,
    	0x002F002F,
    	0x002F002F,
    	0x002F002F,
    	0x002F002F,
    	0x00600073,
    	0x00600071,
    	0x0060007C,
    	0x0060007E,
    	0x00600084,
    	0x00400053,
    	0x00400051,
    	0x0040005C,
    	0x0040005E,
    	0x00400064,
    	0x00800080,
    	0x00800080,
    	0x40010080,
    	0x08102040,
    	0x005B008F,
    	0x005B0092,
    	0x005B0098,
    	0x005B0098,
    	0x005B00A2,
    	0x00300043,
    	0x00300041,
    	0x0030004C,
    	0x0030004E,
    	0x00300054,
    	0x00000077
    };
    
    const struct lpddr2_mr_regs mr_regs = {
    	.mr1	= MR1_BL_8_BT_SEQ_WRAP_EN_NWR_8,
    	.mr2	= 0x6,
    	.mr3	= 0x1,
    	.mr10	= MR10_ZQ_ZQINIT,
    	.mr16	= MR16_REF_FULL_ARRAY
    };
    
    void __weak emif_get_ext_phy_ctrl_const_regs(u32 emif_nr,
    					     const u32 **regs,
    					     u32 *size)
    {
    	switch (omap_revision()) {
    	case OMAP5430_ES1_0:
    	case OMAP5430_ES2_0:
    		*regs = ext_phy_ctrl_const_base;
    		*size = ARRAY_SIZE(ext_phy_ctrl_const_base);
    		break;
    	case OMAP5432_ES1_0:
    		*regs = ddr3_ext_phy_ctrl_const_base_es1;
    		*size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es1);
    		break;
    	case OMAP5432_ES2_0:
    		*regs = ddr3_ext_phy_ctrl_const_base_es2;
    		*size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es2);
    		break;
    	case DRA752_ES1_0:
    	case DRA752_ES1_1:
    	case DRA752_ES2_0:
    		if (emif_nr == 1) {
    			*regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif1;
    			*size =
    			ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_es1_emif1);
    		} else {
    			*regs = dra_ddr3_ext_phy_ctrl_const_base_es1_emif2;
    			*size =
    			ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_es1_emif2);
    		}
    		break;
    	case DRA722_ES1_0:
    		*regs = dra_ddr3_ext_phy_ctrl_const_base_666MHz;
    		*size = ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_666MHz);
    		break;
    	case DRA722_ES2_0:
    		*regs = dra_ddr3_ext_phy_ctrl_const_base_666MHz_es2;
    		*size = ARRAY_SIZE(dra_ddr3_ext_phy_ctrl_const_base_666MHz_es2);
    		break;
    	default:
    		*regs = ddr3_ext_phy_ctrl_const_base_es2;
    		*size = ARRAY_SIZE(ddr3_ext_phy_ctrl_const_base_es2);
    
    	}
    }
    
    void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs)
    {
    	*regs = &mr_regs;
    }
    
    static void do_ext_phy_settings_omap5(u32 base, const struct emif_regs *regs)
    {
    	u32 *ext_phy_ctrl_base = 0;
    	u32 *emif_ext_phy_ctrl_base = 0;
    	u32 emif_nr;
    	const u32 *ext_phy_ctrl_const_regs;
    	u32 i = 0;
    	u32 size;
    
    	emif_nr = (base == EMIF1_BASE) ? 1 : 2;
    
    	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
    
    	ext_phy_ctrl_base = (u32 *) &(regs->emif_ddr_ext_phy_ctrl_1);
    	emif_ext_phy_ctrl_base = (u32 *) &(emif->emif_ddr_ext_phy_ctrl_1);
    
    	/* Configure external phy control timing registers */
    	for (i = 0; i < EMIF_EXT_PHY_CTRL_TIMING_REG; i++) {
    		writel(*ext_phy_ctrl_base, emif_ext_phy_ctrl_base++);
    		/* Update shadow registers */
    		writel(*ext_phy_ctrl_base++, emif_ext_phy_ctrl_base++);
    	}
    
    	/*
    	 * external phy 6-24 registers do not change with
    	 * ddr frequency
    	 */
    	emif_get_ext_phy_ctrl_const_regs(emif_nr,
    					 &ext_phy_ctrl_const_regs, &size);
    
    	for (i = 0; i < size; i++) {
    		writel(ext_phy_ctrl_const_regs[i],
    		       emif_ext_phy_ctrl_base++);
    		/* Update shadow registers */
    		writel(ext_phy_ctrl_const_regs[i],
    		       emif_ext_phy_ctrl_base++);
    	}
    }
    
    static void do_ext_phy_settings_dra7(u32 base, const struct emif_regs *regs)
    {
    	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
    	u32 *emif_ext_phy_ctrl_base = 0;
    	u32 emif_nr;
    	const u32 *ext_phy_ctrl_const_regs;
    	u32 i, hw_leveling, size, phy;
    
    	emif_nr = (base == EMIF1_BASE) ? 1 : 2;
    
    	hw_leveling = regs->emif_rd_wr_lvl_rmp_ctl >> EMIF_REG_RDWRLVL_EN_SHIFT;
    	phy = regs->emif_ddr_phy_ctlr_1_init;
    
    	emif_ext_phy_ctrl_base = (u32 *)&(emif->emif_ddr_ext_phy_ctrl_1);
    
    	emif_get_ext_phy_ctrl_const_regs(emif_nr,
    					 &ext_phy_ctrl_const_regs, &size);
    
    	writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[0]);
    	writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[1]);
    
    	/*
    	 * Copy the predefined PHY register values
    	 * if leveling is disabled.
    	 */
    	if (phy & EMIF_DDR_PHY_CTRL_1_RDLVLGATE_MASK_MASK)
    		for (i = 1; i < 6; i++) {
    			writel(ext_phy_ctrl_const_regs[i],
    			       &emif_ext_phy_ctrl_base[i * 2]);
    			writel(ext_phy_ctrl_const_regs[i],
    			       &emif_ext_phy_ctrl_base[i * 2 + 1]);
    		}
    
    	if (phy & EMIF_DDR_PHY_CTRL_1_RDLVL_MASK_MASK)
    		for (i = 6; i < 11; i++) {
    			writel(ext_phy_ctrl_const_regs[i],
    			       &emif_ext_phy_ctrl_base[i * 2]);
    			writel(ext_phy_ctrl_const_regs[i],
    			       &emif_ext_phy_ctrl_base[i * 2 + 1]);
    		}
    
    	if (phy & EMIF_DDR_PHY_CTRL_1_WRLVL_MASK_MASK)
    		for (i = 11; i < 25; i++) {
    			writel(ext_phy_ctrl_const_regs[i],
    			       &emif_ext_phy_ctrl_base[i * 2]);
    			writel(ext_phy_ctrl_const_regs[i],
    			       &emif_ext_phy_ctrl_base[i * 2 + 1]);
    		}
    
    	if (hw_leveling) {
    		/*
    		 * Write the init value for HW levling to occur
    		 */
    		for (i = 21; i < 35; i++) {
    			writel(ext_phy_ctrl_const_regs[i],
    			       &emif_ext_phy_ctrl_base[i * 2]);
    			writel(ext_phy_ctrl_const_regs[i],
    			       &emif_ext_phy_ctrl_base[i * 2 + 1]);
    		}
    	}
    }
    
    void do_ext_phy_settings(u32 base, const struct emif_regs *regs)
    {
    	if (is_omap54xx())
    		do_ext_phy_settings_omap5(base, regs);
    	else
    		do_ext_phy_settings_dra7(base, regs);
    }
    
    #ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
    static const struct lpddr2_ac_timings timings_jedec_532_mhz = {
    	.max_freq	= 532000000,
    	.RL		= 8,
    	.tRPab		= 21,
    	.tRCD		= 18,
    	.tWR		= 15,
    	.tRASmin	= 42,
    	.tRRD		= 10,
    	.tWTRx2		= 15,
    	.tXSR		= 140,
    	.tXPx2		= 15,
    	.tRFCab		= 130,
    	.tRTPx2		= 15,
    	.tCKE		= 3,
    	.tCKESR		= 15,
    	.tZQCS		= 90,
    	.tZQCL		= 360,
    	.tZQINIT	= 1000,
    	.tDQSCKMAXx2	= 11,
    	.tRASmax	= 70,
    	.tFAW		= 50
    };
    
    static const struct lpddr2_min_tck min_tck = {
    	.tRL		= 3,
    	.tRP_AB		= 3,
    	.tRCD		= 3,
    	.tWR		= 3,
    	.tRAS_MIN	= 3,
    	.tRRD		= 2,
    	.tWTR		= 2,
    	.tXP		= 2,
    	.tRTP		= 2,
    	.tCKE		= 3,
    	.tCKESR		= 3,
    	.tFAW		= 8
    };
    
    static const struct lpddr2_ac_timings *ac_timings[MAX_NUM_SPEEDBINS] = {
    	&timings_jedec_532_mhz
    };
    
    static const struct lpddr2_device_timings dev_4G_S4_timings = {
    	.ac_timings	= ac_timings,
    	.min_tck	= &min_tck,
    };
    
    /*
     * List of status registers to be controlled back to control registers
     * after initial leveling
     * readreg, writereg
     */
    const struct read_write_regs omap5_bug_00339_regs[] = {
    	{ 8,  5 },
    	{ 9,  6 },
    	{ 10, 7 },
    	{ 14, 8 },
    	{ 15, 9 },
    	{ 16, 10 },
    	{ 11, 2 },
    	{ 12, 3 },
    	{ 13, 4 },
    	{ 17, 11 },
    	{ 18, 12 },
    	{ 19, 13 },
    };
    
    const struct read_write_regs dra_bug_00339_regs[] = {
    	{ 7,  7 },
    	{ 8,  8 },
    	{ 9,  9 },
    	{ 10, 10 },
    	{ 11, 11 },
    	{ 12, 2 },
    	{ 13, 3 },
    	{ 14, 4 },
    	{ 15, 5 },
    	{ 16, 6 },
    	{ 17, 12 },
    	{ 18, 13 },
    	{ 19, 14 },
    	{ 20, 15 },
    	{ 21, 16 },
    	{ 22, 17 },
    	{ 23, 18 },
    	{ 24, 19 },
    	{ 25, 20 },
    	{ 26, 21}
    };
    
    const struct read_write_regs *get_bug_regs(u32 *iterations)
    {
    	const struct read_write_regs *bug_00339_regs_ptr = NULL;
    
    	switch (omap_revision()) {
    	case OMAP5430_ES1_0:
    	case OMAP5430_ES2_0:
    	case OMAP5432_ES1_0:
    	case OMAP5432_ES2_0:
    		bug_00339_regs_ptr = omap5_bug_00339_regs;
    		*iterations = sizeof(omap5_bug_00339_regs)/
    			     sizeof(omap5_bug_00339_regs[0]);
    		break;
    	case DRA752_ES1_0:
    	case DRA752_ES1_1:
    	case DRA752_ES2_0:
    	case DRA722_ES1_0:
    	case DRA722_ES2_0:
    		bug_00339_regs_ptr = dra_bug_00339_regs;
    		*iterations = sizeof(dra_bug_00339_regs)/
    			     sizeof(dra_bug_00339_regs[0]);
    		break;
    	default:
    		printf("\n Error: UnKnown SOC");
    	}
    
    	return bug_00339_regs_ptr;
    }
    
    void emif_get_device_timings_sdp(u32 emif_nr,
    		const struct lpddr2_device_timings **cs0_device_timings,
    		const struct lpddr2_device_timings **cs1_device_timings)
    {
    	/* Identical devices on EMIF1 & EMIF2 */
    	*cs0_device_timings = &dev_4G_S4_timings;
    	*cs1_device_timings = &dev_4G_S4_timings;
    }
    
    void emif_get_device_timings(u32 emif_nr,
    		const struct lpddr2_device_timings **cs0_device_timings,
    		const struct lpddr2_device_timings **cs1_device_timings)
    	__attribute__((weak, alias("emif_get_device_timings_sdp")));
    
    #endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
    

    Can you please provide feedback on why this changed ? 

    Thanks
    Mathieu

  • Hi Mathieu,

    Thank you. We will give you feedback on these changes.

    I'd like to clarify one thing: your colleague Antoine mentioned the U-Boot version you used was 02.00.00.00 which does not include the above code as this version supports SR 1.0 only. So which U-Boot are you using? It is a 02.00.00.00 baseline with additions of a more recent version?

    Also, do you have the results of your test with the latest EMIF configuration that includes the proper DDR3-1066 settings?


    Thanks,
    François.
  • I noticed that this is a weak alias
    void __weak emif_get_ext_phy_ctrl_const_regs(u32 emif_nr,
    const u32 **regs,
    u32 *size)

    It is not used for AM57xx. In board/ti/am57xx/board.c we have
    void emif_get_ext_phy_ctrl_const_regs(u32 emif_nr, const u32 **regs, u32 *size)

    Which does not distinguish between es1.0/2.0.

    Steve K.