i.MX 6/7 Family DDR Stress Test
i.MX6/7 DDR Stress Test Tool is a PC-based software to fine-tune DDR parameters and verify the DDR performance on a non-OS, single-task environment(it is a light-weight test tool to test DDR performance). It performs write leveling, DQS gating and read/write delay calibration features.
There are three options to run the DDR Stress test. Each of these options are provided in the attached zip files. The following is a high-level overview of each option along with the naming convention of the associated zip file:
Option 1 GUI based:
Run the GUI executable and connect your board to the host PC via USB
- Archive file: ddr_stress_tester_vX.xx.zip
- The tool will first need to run a DDR initialization script for the specified i.MX SoC (refer to Load Init Script in the GUI tool). Example initialization scripts based on NXP's development boards can be found in this zip file under the script folder. Note, these scripts may need to be modified for your custom board and memory.
Option 2 DDR Stress Tester: JTAG Interface
A hardware debugger connected to the board via the JTAG interface is used to download an elf file into the i.MX SoC OCRAM (internal RAM) and then begin execution. Results are shown on the UART serial port (115200-8-n-1).
- Archive file: ddr_stress_tester_jtag_vX.xx.zip
- As with the GUI tool, the JTAG/debugger option will first need to run a DDR initialization script for the specified i.MX SoC. Refer to the GUI tool description above for the location of the example scripts (which are found in the ddr_stress_tester_vX.xx.zip file).
- Note that the scripts are available either in the RealView ICE format (.inc file) or the DS-5 DSTERAM format (.ds). For other debuggers, the user will have to modify the script's command syntax for their specific debugger. This is also true if converting from a RealView Ice (.inc) format to a DS-5 DSTREAM (.ds) format and vice versa.
- The DDR Stress Tester executable (starting with V2.20) has an auto UART detection feature. If a different UART port for the serial console has been chosen than used on the NXP development tool (EVK, SABRE) specific commands can be added to the DDR initialization script that allows you to configure for the specific UART and then load and run the elf executable. Refer to the FAQ section of this community post and the txt file found in the JTAG archive file for instructions.
Option 3 U-Boot:
The boot loader u-boot is running and commands in u-boot are used to download the bin file into SoC OCRAM and begin execution. Results are shown on the UART serial port (115200-8-n-1)
- Archive file: ddr_stress_tester_uboot_vX.xx.zip
- When downloading the DDR Stress Tool by u-boot, please copy the ddr-test-uboot-jtag-mxxxx.bin to SD card and load it to IRAM using the 'fatload' u-boot command. For i.MX6, please load the binary to 0x00907000. For i.MX7D, please load the binary to 0x00910000. It is imperative to first disable the I and D cache in u-boot as shown below as the DDR Stress Test re-configures and re-enables the cache and MMU page table.
- The following is an example of downloading and running the DDR stress test from u-boot:
u-boot> dcache off
u-boot> icache off
u-boot> fatload mmc 0:1 0x00907000 ddr-test-uboot-jtag-mx6ul.bin
u-boot> go 0x00907000
|Stress Test Revision||Features||Comments|
Add i.MX 7ULP support in the GUI version
Known issues: USB connection is unstable when under USB HUB or some PC environments
Minor correction with write leveling calibration code error check to avoid a corner case of flagging an error when none have occurred.
Resolved issue with write leveling calibration code where a race condition in the code may result in the calibration routine not being able to find any delay values.
|Only applies to MX6 series SoCs that support DDR3.|
Reserve write delay line register (MMDC_MPWRDLCTL) configuration as DDR script does when do write calibration. In previous releases, MMDC_MPWRDLCTL would be changed to 0x40404040 by default.
* Further details available in the release notes
Q. I see an error message that states "ERROR: DCD addr is out of valid range.", why is this and how do I resolve?
A. Sometimes, when using the register programming aid, there are registers writes that are not supported in the DCD range. Try looking for the following items and comment them out from the DDR initialization script:
wait = on
setmem /16 0x020bc000 = 0x30 // disable watchdog (note the address for this may be different between i.MX6x devices)
Q. How do I select the "DDR Density" pull-down menu and what is the purpose of this?
A. The DDR Density pull-down menu gives the user the option of testing a DDR density smaller than what they actually have on their board. The advantage of doing this is to speed up test time to allow the user to perform a "quick test" of their system. IMPORTANT: it is imperative that the user not set this value higher than the supported density on their board, doing so will cause the stress test to fail and/or lock up.
The DDR Density has a different meaning depending on the memory type being tested (DDR3 or LPDDR2):
For DDR3, this is the density per CHIP SELECT. So if your board has two chip selects, and each chip select has 512MB, you would simply select 512MB or lower. The default setting will simply set this to the detected density per chip select.
For LPDDR2, this is the density per CHANNEL. This is only relevant for MX6 devices that support 2 channel LPDDR2 memories (MX6DQ, MX6DL). For other MX6 devices that support only one LPDDR2 channel, then this is the total density (for the maximum setting) for that channel. Note that for LPDDR2, the number of chip selects (per channel) is irrelevant when selecting the density to test as the stress test combines both chip-selects into one combined density per channel. For example, lets say you have a 2GB LPDDR2 device, which 2 channels and 2 chip-selects per channel. That means you have 512MB per chip select, per channel. Or, it also means you have 1GB per channel when combining both chip selects per channel. In this case, you would choose (a maximum setting of) 1GB in the DDR Density drop down menu. However, this is also the same setting as the default setting (which you are welcome to still choose 1GB to convince yourself that 1GB per channel is indeed being tested).
Now let's assume you have only one channel (LPDDR2) and one chip select, with a density of 128MB; in this case, the maximum DDR Density you can select is 128MB.
Let's assume you have one channel and two chip selects, each chip select is 128MB; in this case, the maximum DDR Density you can select is 256MB (a combination of both chip selects).
Note, for the MX7D, an actual density needs to be entered. For the MX6x series, simply leaving this field as Default will cause the DDR stress test to ascertain the supported density from the DDR init script. As the MX7D DDR controller is different, this feature is not supported, hence it is required for the user to enter an actual density (for more details regarding MX7D usage of density and number of chip-selects, see the next FAQ on the DDR CS setting).
Q. What is the purpose of the "DDR CS" pull-down option?
A. The answer depends on which processor you are testing:
For the i.MX 6x series:
This pull down menu gives you the option of testing one chip select (CS0) or ALL (both) chip selects *IF* you have a two-chip select configuration. If you have a two-chip select configuration, then this allows you to test only one chip select for faster test time; else you can choose to test both chip selects. Note that if you have a one-chip select configuration and you choose "ALL", the stress test will return an error.
For the iMX 7D:
Because the MX7D DDR controller is different, the DDR stress test will need the user to supply the entire supported density found on their board. The chip select field should be left as is (0) as the test will naturally test one chip select to the next. For example, let’s assume you are using two chip selects, with each chip select being 512MB. In this case, you would enter 1GB for the DDR Density field ensuring that both chip selects will be tested. The user is allowed to enter a density less than the density found on their board (for quicker testing), but keeping in mind both chip selects may not be tested in this case.
Q. I run DDR calibration using the DDR Stress Test Tool to obtain the calibration results. Are these calibration parameters are written to the uboot flash_header.S automatically or manually?
A. The calibration values obtained from the DDR Stress Test Tool will need to be manually updated in the flash_header.S file or any other DDR initialization script.
Q. When running the DDR stress test on MX7D and I try to perform calibration, I get an error stating that calibration is not supported, is this expected?
A. Yes, calibration is not supported or needed when using MX7. The reason is, MX7 uses a different memory controller than the MX6 series. The MX6 series memory controller has built-in support for calibration where the MX7 memory controller does not.
Q. When running the GUI version of the DDR stress test, on MX7 and I leave DDR Density as default, I get an error in the tool stating I must supply a density. Why is this?
A. This is due to the fact that MX7 uses a different memory controller than the MX6 series. In the MX6 series, it was possible to calculate the memory density from the memory controller register settings. The MX7 memory controller is different and does not lend itself to easily calculate the supported density based on the register settings. Instead, the user should verify the density on their board and selected this value in the DDR Density pull-down menu.
Q. I noticed that when I run write-leveling calibration I sometimes see a note that due to the write-leveling calibration value being greater than 1/8 clock cycle that WALAT must be set to 1. What does this mean?
A. In the MMDC chapter of the reference manual for the specific i.MX 6 device, the need to set WALAT is described in the MDMISC register as follows:
"The purpose of WALAT is to add time delay at the end of a burst write operation to ensure that the JEDEC time specification for Write Post Amble Delay (tWPST) is met (DQS strobe is held low at the end of a write burst for > 30% a clock cycle before it is released). If the value of any of the WL_DL_ABS_OFFSETn register fields are greater than ‘1F’, WALAT should be set to ‘1’ (cycle additional delay). WALAT should be further increased for any full-cycle delays added by the WL_CYC_DELn register fields."
Therefore, if the write-leveling calibration routine detects any write-leveling delay value greater than 0x1F, it will note to the user that WALAT must be set and the user should update their DDR3 init script to ensure WALAT is set. Sometimes, a user may find that the write-leveling delay value may fluctuate from one run to the next, which is quite normal. If it is found that this delay is "borderline" meaning sometimes it is greater than 0x1F and sometimes it might be slightly less, then it is ok to go ahead and set WALAT permanently in your init script as there is no harm in doing so and will ensure you will stay within JEDEC's tWPST.
Q. I sometimes see that after running write-leveling calibration that delay values being reported back are zero'd out (0x00), and then at times I see a non-zero value being reported, why is this?
A. It is quite normal to see slight variations in the delay value between write-leveling calibration runs. The write-leveling calibration routine assumes a majority of users have designed their board such that the DDR3 memories are placed close to the i.MX 6 SoC. There’s a mechanism in NXP’s DDR Stress test write leveling calibration code that checks the returned write leveling value. If the write-leveling calibration routine detects that the returned delay value is greater than ¾ of a clock cycle, it will "zero out" the delay value. It does this because it assumes that such a large delay result is due to the fact that the DQS signal is already delayed relative to the SDCLK, and to align DQS with SDCLK requires the calibration routine to delay DQS even further to align it to the next SDCLK edge, something we ideally would like to avoid. JEDEC specs that the DQS edge must be within 25% of a SDCLK cycle with respect to the SDCLK edge, so having DQS initially slightly delayed from SDCLK is actually ok, hence why the calibration routine “zero’s” this out when the returned value exceeds ¾ of a clock cycle. In cases like this, the DQS edge and SDCLK edge are so close together that in some calibration runs, the DQS edge may slightly precede SDCLK (resulting in a very small write-leveling delay value) and other runs, it may be slightly delayed relative to the SDCLK (resulting in a very large write-leveling delay value that will try to align DQS to the next SDCLK edge, hence needs to be zero’d out).
Q. When using the JTAG version of the DDR stress test, how can I select a different UART port for my serial port?
A. Under the folder ddr_stress_tester_jtag_v2.52, there's a text file that describes how to add a different UART port by adding a few additional commands to your DDR init script. The following is an outline of these commands:
1. Ungate UART module clocks (most NXP scripts ungate all of the peripheral clocks at the beginning of the script, so this part is already done)
2. Configure the IOMUX options for the pins you wish the UART to use (normally an IOMUX option for UART_TX and UART_RX, and a daisy chain option for the UART_RX input)
3. Enable the desired UART module via the register UCR1, bit UART_EN
4. Disable other UART modules (UCR1[UART_EN] = 0). Normally disabling UART1 should be sufficient, but it doesn't hurt to disable all of the other un-used UART options for the purpose of the stress test.
Here's an example in the .ds file vernacular of a set up as follows: MX6DQ, UART4 on KEY_COL0 and KEY_ROW0 (assume clock is ungated to all peripherals):
mem set 0x020E01F8 32 0x00000004 #// config_pad_mode(KEY_COL0, ALT4)
mem set 0x020E01FC 32 0x00000004 #// config_pad_mode(KEY_ROW0, ALT4);
mem set 0x020E0938 32 0x00000001 #// Pad KEY_ROW0 is involved in Daisy Chain.
mem set 0x02020080 32 0x00000000 #//disable UART1 in UART1_UCR1 (Note, you can disable other UART modules as well)
mem set 0x021F0080 32 0x00000001 #//enable UART4 in UART4_UCR1
Here's another example in the .inc file vernacular of a set up as follows: MX6SX, UART5 on SD4_DATA4 abd SD4_DATA5 (assume clock is ungated to all peripherals):
setmem /32 0x020E0294 = 0x2 //IOMUXC_SW_MUX_CTL_PAD_SD4_DATA5, ALT2; UART5_TX_DATA
setmem /32 0x020E0290 = 0x2 //IOMUXC_SW_MUX_CTL_PAD_SD4_DATA4, ALT2; UART5_RX_DATA
setmem /32 0x020E0850 = 0x00000000 // IOMUXC_UART5_IPP_UART_RXD_MUX_SELECT_INPUT, daisy chain for UART5_RX input to use SD4_DATA4
setmem /32 0x021F4080 = 0x00000001 // Enable UART_EN in UCR1 of UART5
// Disable UART_EN in UCR1 of UART1, UART2, UART3, and UART4
setmem /32 0x02020080 = 0x00000000 // UART1
setmem /32 0x021F0080 = 0x00000000 // UART2
setmem /32 0x021EC080 = 0x00000000 // UART3
setmem /32 0x021E8080 = 0x00000000 // UART4