AM335x EMIF Configuration tips

= Introduction =

The following information describes how to set the EMIF registers in the AM335x EMIF module depending on the DDR memory that you are using (LPDDR, DDR2, or DDR3).

= EMIF General Configuration Registers  =


 * SDRAM_CONFIG (@0x4C000008)- The values in this register will depend a lot on your memory configuration, and are used to configure the memory during initialization. They are eventually written to the mode registers of the memory device. Here are some tips to configure each value:
 * REG_SDRAM_TYPE - LPDDR1 (mDDR) = 1, DDR2 = 2, DDR3 = 3
 * REG_IBANK_POS - This register sets up the internal bank position. Please see "Address Mapping" section of the TRM for more information. This is typically left at 0 to allow for maximum number of banks to be open and to allow interleaving between them.
 * REG_DDR_TERM - DDR2 and DDR3 termination resistor value. Refer to the TRM for proper values. This sets the termination on the memory side for ODT (On Die Termaination). Refer to the ODT section  below for more information.
 * REG_DDR2_DDQS - DDR2 differential DQS enable. Set to 0 when using LPDDR (mDDR) for single ended DQS. Set to 1 when using DDR2/DDR3 for differential DQS.
 * REG_DYN_ODT -  These bits are only used in DDR3 mode. These bits enable/disable the dynamic ODT feature of the DDR3 memory, which allows the memory to apply a different ODT termination value during write cycles (nominal ODT value is determined by REG_DDR_TERM) .  Please refer to the DDR3 memory datasheet for more information about this operation.
 * REG_DDR_DISABLE_DLL - Set to 0 for normal operation
 * REG_SDRAM_DRIVE - SDRAM drive strength. For LPDDR1, typically you would set this to 1 for half drive strength. Some boards with LPDDR may require full drive strength depending on board size and trace impedances. For DDR2, set to 0 for full drive strength.
 * REG_CWL - CAS Write Latency. These bits are only used in DDR3 mode (For other device types, this can be set to 0). The value of this field defines the CAS write latency to be used when accessing connected DDR3 devices. Use the lowest supported value for the best performance.  This value should come directly from the DDR3 datasheet.  Typically there are speed bin tables in the datasheet depending on the device you have selected.  Each table will have several different CWL values based on tCK.  For AM335x, choose 3.3ns max (for 303MHz), and select the CWL associated with this frequency.  Note the value mappings in the TRM:
 * CAS Write Latency of 5: Set REG_CWL = 0
 * CAS Write Latency of 6: Set REG_CWL = 1
 * CAS Write Latency of 7: Set REG_CWL = 2
 * CAS Write Latency of 8: Set REG_CWL = 3
 * REG_NARROW_MODE -  AM335x only supports 16-bit data bus, so this must always be set to 1 for 16-bit mode.
 * REG_CL - CAS Latency. The value of this field defines the CAS latency to be used when accessing connected SDRAM devices. This value should come directly from the DDR datasheet. Be sure to use the CAS latency defined for the frequency you are clocking the DDR. Refer to the TRM for proper values.
 * REG_ROWSIZE - This field is only used when reg_ibank_pos field in SDRAM Configuration register is set to 1, 2, or 3, OR when reg_ebank_pos=1. Should be set to the number of row address bits defined in the DDR datasheet.


 * REG_IBANK - Internal Bank setup. Defines number of banks inside connected SDRAM devices. Set to 0 for 1 bank, set to 1 for 2 banks, set to 2 for 4 banks, and set to 3 for 8 banks. All other values are reserved. Refer to the memory datasheet for number of banks.  Most memories will use 8 banks
 * REG_EBANK - External chip select setup. Defines whether SDRAM accesses will use 1 or 2 chip select lines. Since AM335x only has one CS, always set this bit to 0.
 * REG_PAGESIZE - Page Size. Defines the internal page size of connected SDRAM devices. Should be set to the number of column address bits defined in the DDR datasheet.

= DDR PHY Control Register =


 * DDR_PHY_CTRL_1 (@0x4C0000E4)
 * REG_PHY_ENABLE_DYNAMIC_PWRDN - Recommended as 1 for power savings.
 * REG_PHY_RST_N - Set to 0 for normal operation.
 * REG_PHY_IDLE_LOCAL_ODT - This value defines the AM335x side termination during idle mode (ie, when REG_PHY_ENABLE_DYNAMIC_PWRDN is asserted). Typically you would set this to 00 to save power during idle.
 * REG_PHY_WR_LOCAL_ODT - This value defines the AM335x side termination during writes. Termination is typically not needed for writes, so this value should be set to 0.
 * REG_PHY_RD_LOCAL_ODT - This value defines the AM335x side termination during reads. Use the values below:
 * 00: ODT off
 * 01: ODT off
 * 10: Full thevenin load
 * 11: Half thevenin load
 * REG_READ_LATENCY - This value accounts for the round trip delays in the device and circuit board. At a minimum, the latency must be CAS Latency plus two (CL+2). Note that this is a "minus 1" register, so the actual value written to the register should correspodingly be a minimum of CL+1. Furthermore, if PHY_INVERT_CLKOUT=1 you should add one additional cycle to this value, i.e. program it with a minimum value equal to CL+2.
 * For example: Let's take a case latency of 6. In this case you would program SDRAM_CONFIG.REG_CL = 4. then set REG_READ_LATENCY = 5, which corresponds to a read latency of 6 (CAS latency plus 2).
 * For PHY_INVERT_CLKOUT=0 -> PHY_INVERT_CLKOUT = CL+1 = 7
 * For PHY_INVERT_CLKOUT=1 -> PHY_INVERT_CLKOUT = CL+2 = 8

= DDR PHY Registers =

(@0x44E12000 - 0x44E123FF)

There are many DDR PHY registers which allows for maximum flexibility in configuring the PHY for many different modes and timing scenarios. Each DDR type has a different procedure for determining these values. Please refer to the section below for your DDR type. Refer to the TRM for an explanation of these registers. '''Note: due to a bug in the device, these registers are not readable. They are write only registers.'''

DDR PHY Registers for DDR2 and LPDDR (mDDR)
A summary of the DDR PHY registers that need to be configured is listed below. All other DDR PHY registers that are not listed can be left in their default state. For CMDx, x is 0,1,2 as described above. For DATAx, x is 0 or 1 as described above. In all cases, program the same value for each iteration of the macro.


 * CMDx_PHY_INVERT_CLKOUT - In addition to programming these registers with 0 or 1 as defined below, plug this value into the spreadsheet to get the proper values for other registers
 * If (DDR_CK length) < (DDR_DQS length), program these registers to 1
 * If (DDR_CK length) > (DDR_DQS length), program these registers to 0


 * DATAx_PHY_RD_DQS_SLAVE_RATIO - use the Ratio Seed spreadsheet to determine the value for these registers
 * DATAx_PHY_FIFO_WE_SLAVE_RATIO - use the Ratio Seed spreadsheet to determine the value for these registers
 * DATAx_PHY_WR_DQS_SLAVE_RATIO - use the Ratio Seed spreadsheet to determine the value for these registers
 * DATAx_PHY_WR_DATA_SLAVE_RATIO - use the Ratio Seed spreadsheet to determine the value for these registers
 * CMDx_PHY_CTRL_SLAVE_RATIO    - use the Ratio Seed spreadsheet to determine the value for these registers

Using the Ratio Seed spreadsheet for DDR2 and LPDDR
[[Media:RatioSeed_AM335x_boards.zip|Ratio Seed Spreadsheet]] To use the Ratio Seed spreadsheet for DDR2 and LPDDR, choose the 'DDR2' or 'mDDR' tab at the bottom of the spreadsheet. Input the maximum DDR frequency that will be used, enter 0 or 1 for PHY_INVERT_CLKOUT as described above, and then enter the trace length (in inches) of each trace. For DDR_CLK, this trace is typically in a 'T' configuration for designs with two x8 memories. Ensure that you input the trace length from AM335x to each memory. These lengths should be close to equal if correct design guidelines were met. After inputting the correct information, the values for the registers will be automatically calculated in the spreadsheet.

= Control Module Registers= Some DDR configuration involves Control Module registers which are outside of the DDR controller and DDR PHY modules. Here is a summary of their configuration.


 * DDR_IO_CTRL (@0x44E10E04) - Controls the I/O mode for the DDR I/Os.
 * MDDR_SEL - this puts the I/Os in CMOS mode (for LPDDR operation, set to 1) or STL mode (for DDR2/DDR3 operation, set to 0)
 * VTP_CTRL (@0x44E10E0C) - controls the VTP (Voltage-Temperature-Process) compensation for the DDR I/Os. VTP calibration should occur after the DDR PLL is setup, but before any other DDR controller or DDR PHY configuration is performed.  VTP calibration should be performed at power up and each time the DDR controller is re-initialized.  Here are the steps to perform VTP Calibration:
 * Set ENABLE to 1 to enable VTP
 * Clear CLRZ to 0 to clear out flops and start count again
 * Set CLRZ to 1 to complete the toggle of CLRZ
 * Check for VTP ready bit. If 1, the training sequence is complete


 * VREF_CTRL (@0x44E10E14) - controls various parameters for VREF
 * Normally this would remain at its reset value 0x00000000. This assumes the reference is being supplied externally through the DDR_VREF pin using a resistor divider as shown in the data manual.


 * DDR_CKE_CTRL (@0x44E1131C)
 * DDR_CKE_CTRL - for normal operation, set this bit to 1 to allow the CKE signals to be controlled from the PHY.

These registers control the parameters of the I/O buffers for the command and data macros. Refer to the TRM to determine which group of signals are affected by each register. For programming purposes, each of these registers should be set to the same value.
 * DDR_CMD0_IOCTRL (@0x44E11404) - set to 0x18B
 * DDR_CMD1_IOCTRL (@0x44E11408) - set to 0x18B
 * DDR_CMD2_IOCTRL (@0x44E1140C) - set to 0x18B
 * DDR_DATA0_IOCTRL (@0x44E11440) - set to 0x18B
 * DDR_DATA1_IOCTRL (@0x44E11444) - set to 0x18B

= AC timing registers =


 * SDRAM_TIM_1, SDRAM_TIM_2, and SDRAM_TIM_3

This spreadsheet will help you determine the optimal values for the AC timing registers. Be sure you select the correct tab in the spreadsheet based on the memory you are using (mDDR, DDR2, DDR3):

[[Media:AM335x_DDR_register_calc_tool.zip | AM335x DDR Calculation tool (.zip)]]

The values in yellow need to be changed based on the datasheet values for your memory. Ensure that you enter the correct values for the speed grade of your device. The tCK value should represent the speed at which you will be running the device (not necessarily the minimum value in the datasheet). The register values for the AM335x AC timing registers will be calculated based on these inputs. For more conservative values, you can use the +1 non-optimal values in case you suspect a timing issue (You can unhide the rows to see these). Ultimately, the optimal values should work.

= Setting Refresh rate =


 * SDRAM_REF_CTRL (@0x4C000010) - To set the refresh rate, get the Periodic Refresh interval tREFI from the memory datasheet. Note that this value is typcially in the us range.  Some datasheets may refer to a "Refresh Interval time" in the millisecond range (64ms, for example), however, this value needs to be divided by the number of refresh cycles needed (typically 8000).
 * REG_REFRESH_RATE - the number of clock cycles required to cause a refresh interval of 7.8 us or 15.7 us for the appropriate SDRAM used. This field is not byte writable, i.e., all 16 bits of this field need to be written simultaneously. Here are some examples:
 * For 400 MHz memory system with 7.8us refresh rate: 400 * 7.8us = 3120.0 or 0xC30
 * For 303 MHz memory system with 7.8us refresh rate: 303 * 7.8us = 2363.4 or 0x93B
 * For 266 MHz memory system with 7.8us refresh rate: 266 * 7.8us = 2074.8 or 0x81A

= Power Management Control Register =

If you are not implementing any power management, set this register to 0x00000000. There are 3 levels of power management that you can set with this register: clock stop, self-refresh, and power-down. The register also gives you the flexibility to set timers that monitor EMIF idle time. When they expire, then the EMIF will put the external memory in the mode that is designated. Some power modes are only supported by certain memories.

For more details on these registers, please refer to the AM335x TRM.


 * PWR_MGMT_CTRL (@0x4C000038)
 * REG_PD_TIM - Power Management Timer. Number of clock cycles to wait after EMIF is idle before going into power saving mode.  Valid when REG_LP_MODE = 4.
 * REG_DPD_EN -  This bit simply enables deep power down mode available in LPDDR devices.
 * REG_LP_MODE - Auto Power management enable. 0 = disable auto pwr mgmt; 1 = clock stop; 2 = Self Refresh; 4 = Power-Down
 * REG_SR_TIM - Power Management Timer for Self-Refresh mode. This is the number of clock cycles to wait after EMIF is idle before going into self-refresh mode.  Valid when REG_LP_MODE = 2.
 * REG_CS_TIM - Power Management Timer for Clock Stop mode. This is the number of clock cycles to wait after EMIF is idle before going into clock stop mode.  Valid when REG_LP_MODE = 1.

= Shadow Registers =

The AM335x devices support smart idle mode for power conservation. Upon returning from smart idle mode, the shadow registers are loaded into the EMIF registers.


 * SDRAM_REF_CTRL_SHDW - Refresh Control Shadow Register. Ensure that this register is written with the same value as SDRAM_REF_CTRL register.
 * SDRAM_TIM_1_SHDW - SDRAM Timing 1 Shadow Register. Ensure that this register is written with the same value as SDRAM_TIM_1 register.
 * SDRAM_TIM_2_SHDW - SDRAM Timing 2 Shadow Register. Ensure that this register is written with the same value as SDRAM_TIM_2 register.
 * SDRAM_TIM_3_SHDW - SDRAM Timing 3 Shadow Register. Ensure that this register is written with the same value as SDRAM_TIM_3 register.
 * PWR_MGMT_CTRL_SHDW - Power Management Control Shadow Register. Ensure that this register is written with the same value as PWR_MGMT_CTRL register.
 * DDR_PHY_CTRL_1_SHDW - DDR PHY Control 1 Shadow Register. Ensure that this register is written with the same value as DDR_PHY_CTRL_1.

=Initialization Sequence=
 * The best source for proper initialization sequence is the SPL source code, which can be found from TI's Linux Processor SDK for AM335x.

= On Die Termination (ODT) control of the DDR Device =


 * AM335x configures On Die Termination of the DDR device through its SDRAM_CONFIG register. DDR memories typically have configurable On Die Termination internally which helps improve signal integrity. REG_DDR_TERM is used to configure the nominal ODT on the memory (The value from these register bits get written to the memory's MR1 register during AM335x DDR initialization).  These bits determine the ODT value applied on the memory side.  The AM335x ODT output signal is then used by the memory to turn on/off the ODT termination (this signal is controlled by the AM335x EMIF controller).  Typically ODT is turned off during reads and self refresh states, and turned on during writes.
 * DDR3 memories have an additional feature called dynamic ODT. This allows the memory to apply a different ODT value from the nominal value described above.  This ODT value is only applied by the memory during write cycles.
 * When to use nominal vs. dynamic ODT on DDR3? Typically, only dynamic ODT should be enabled for DDR3.  This will apply ODT during writes and turn off ODT for all other states, which will optimize power consumption.  Only a subset of termination values are available for dynamic ODT (RZQ/2 and RZQ/4), so if a different value is required, you will need to use nominal ODT.  Another scenario might be if you require a different ODT termination value for writes vs. non-write states, then you can enable both and configure different termination values.
 * ODT is supported for DDR2 and DDR3. DDR2 does not support dynamic ODT.  mDDR does not support any ODT.
 * External signal (DDR_ODT) is driven from AM335x and controls the parallel termination implemented in the DDR2/DDR3 memory. The termination value is defined in SDRAM_CONFIG.REG_DDR_TERM.
 * ODT (registered HIGH) turns on the termination resistance internal to the DDR2/DDR3 memory. When enabled, ODT is applied to each DQ, DQS, DQSn, DM signals.
 * SDRAM_TIM_2 [27-25]: Minimum number of m_clk cycles from ODT enable to write data driven for DDR2/DDR3. (see TRM)
 * The DDR2 EMRS (MR1 for DDR3) register is programmed via the value in SDRAM_CONFIG.REG_DDR_TERM. DDR3 MR2 register is programmed via the value in the SDRAM_CONFIG.REG_DYN_ODT
 * SDRAM_CONFIG.REG_DDR_TERM (these values should correspond to DDR datasheet)
 * Set to 0 to disable nominal ODT.
 * For DDR2
 * 1 = 75 ohm
 * 2 = 150 ohm
 * 3 = 50 ohm
 * For DDR3
 * 1 = RZQ/4 (60ohm)
 * 2 = RZQ/2 (120ohm)
 * 3 = RZQ/6 (40ohm)
 * 4 = RZQ/12 (20ohm)
 * 5 = RZQ/8 (30ohm)
 * SDRAM_CONFIG.REG_DYN_ODT (applicable for DDR3 only)
 * Set to 0 to disable dynamic ODT
 * 1 = RZQ/4 (60ohm)
 * 2 = RZQ/2 (120ohm)


 * Note: lower termination resistance may provide better signal integrity but at the cost of higher power consumption when ODT is turned on.