u-boot/arch/arm/mach-imx
Marek Vasut 14eeb683a8 ARM: mx6: ddr: Add write leveling correction code
When the DDR calibration is enabled, a situation may happen that it
will fail on a few select boards out of a whole production lot. In
particular, after the first write leveling stage, the MPWLDECTRLx
registers will contain a value 0x1nn , for nn usually being 0x7f or
slightly lower.

What this means is that the HW write leveling detected that the DQS
rising edge on one or more bundles arrives slightly _after_ CLK and
therefore when the DDR DRAM samples CLK on the DQS rising edge, the
CLK signal is already high (cfr. AN4467 rev2 Figure 7 on page 18).

The HW write leveling then ends up adding almost an entire cycle (thus
the 0x17f) to the DQS delay, which indeed aligns it, but also triggers
subsequent calibration failure in DQS gating due to this massive offset.

There are two observations here:
- If the MPWLDECTRLx value is corrected from 0x17f to 0x0 , then the
  DQS gating passes, the entire calibration passes as well and the
  DRAM is perfectly stable even under massive load.
- When using the NXP DRAM calibrator for iMX6/7, the value 0x17f or so
  in MPWLDECTRx register is not there, but it is replaced by 0x0 as one
  would expect.

Someone from NXP finally explains why, quoting [1]:

    "
    Having said all that, the DDR Stress Test does something that we
    do not advertise to the users. The Stress Test iself looks at the
    values of the MPWLDECTRL0/1 fields before reporting results, and
    if it sees any filed with a value greater than 200/256 delay
    (reported as half-cycle = 0x1 and ABS_OFFSET > 0x48), the DDR
    Stress test will reset the Write Leveling delay for this lane
    to 0x000 and not report it in the log.

    The reason that the DDR Stress test does this is because a delay
    of more than 78% a clock cycle means that the DQS edge is arriving
    within the JEDEC tolerence of 25% of the clock edge. In most cases,
    DQS is arriving < 5% tCK of the SDCLK edge in the early case, and
    it does not make sense to delay the DQS strobe almost a full clock
    cycle and add extra latency to each Write burst just to make the
    two edges align exactly. In this case, we are guilty of making a
    decision for the customer without telling them we are doing it so
    that we don't have to provide the above explanation to every customer.
    They don't need to know it.
    "

This patch adds the correction described above, that is if the MPWLDECTRx
value is over 0x148, the value is corrected back to 0x0.

[1] https://community.nxp.com/thread/456246

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Stefano Babic <sbabic@denx.de>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Reviewed-by: Eric Nelson <eric@nelint.com>
Reviewed-by: Stefano Babic <sbabic@denx.de>
2018-04-15 11:39:23 +02:00
..
mx2 mx25: Select the ESDHC_A001 erratum 2017-11-07 10:13:00 +01:00
mx5 arm: imx: mx53loco: remove usage of mx53_dram_size 2018-02-04 12:00:58 +01:00
mx6 ARM: mx6: ddr: Add write leveling correction code 2018-04-15 11:39:23 +02:00
mx7 imx: mx7: run sec_init for CAAM RNG 2018-02-04 12:14:11 +01:00
mx7ulp arm: imx: Rework i.MX specific commands to be excluded from SPL 2018-01-12 14:28:04 +01:00
mx8m imx: mx8m: add soc related settings and files 2018-02-04 12:00:58 +01:00
mxs arm: imx: mx28: Move MX28 selection to Kconfig 2018-02-08 10:17:17 -05:00
cache.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
cmd_bmode.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
cmd_dek.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
cmd_hdmidet.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
cpu.c imx: cpu: support get_boot_device for i.MX8M 2018-02-04 12:00:58 +01:00
ddrmc-vf610.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
hab.c arm: imx: hab: Define HAB_RVT_BASE according to the processor version 2018-02-22 14:36:06 +01:00
i2c-mxv7.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
imx_bootaux.c imx: bootaux: support i.MX8M 2018-02-04 12:00:58 +01:00
init.c imx: Remove boolean parameter from wdog powerdown function 2017-11-27 10:34:49 +01:00
iomux-v3.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
Kconfig imx: introduce CONFIG_GPT_TIMER 2018-01-08 17:33:06 +01:00
mac.c imx: refactor imx_get_mac_from_fuse 2018-02-04 12:00:58 +01:00
Makefile imx: makefile: compile files for i.MX8M 2018-02-04 12:00:58 +01:00
misc.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
mmc_env.c imx: mx7: move mmc env code to mmc_env.c 2018-02-04 12:00:58 +01:00
rdc-sema.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
sata.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
sip.c imx: add sip function 2018-02-04 12:00:58 +01:00
speed.c imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
spl.c imx7: spl: Check for Serial Downloader in spl_boot_device 2018-03-29 17:33:12 +02:00
spl_sd.cfg imx: reorganize IMX code as other SOCs 2017-07-12 10:17:44 +02:00
syscounter.c imx: syscounter: make sure asm is volatile 2018-03-09 13:06:14 +01:00
timer.c imx: timer: don't clear the GPT control register multiple times 2017-08-29 09:47:28 +02:00
video.c env: Rename getenv/_f() to env_get() 2017-08-16 08:30:24 -04:00