AM335x DDR PHY register configuration for DDR3 using Software Leveling ver2

This wiki describes how to configure AM335x DDR PHY configuration registers for use with DDR3. These registers need to be configured based on certain circuit board characteristics to ensure proper timing is performed for all DDR transactions. Outlined below is a Software Leveling procedure which should be used as a workaround due to the errata concerning Hardware Leveling in AM335x.

Note: If you are using DDR2 or mDDR, please refer back to the EMIF Configuration Tips (DDR PHY Section) for details on configuration for these types of memories. The procedure below should only be used for DDR3/DDR3L configuration

=AM335x EMIF Tool Spreadsheet= The first step is to complete the [|AM335x EMIF Tool Spreadsheet]. This spreadsheet helps to compile characteristics about your design and timing information from your specific DDR devices to calculate several EMIF configuration registers and provide seed values for the SW leveling algorithm (described below). It is important to fill this spreadsheet out completely and accurately in order to obtain robust register values for EMIF configuration. Once the spreadsheet is complete, the final 2 tabs (EMIF Tool and Registers) will contain the register values needed for SW leveling tool. Some notes are provided in the spreadsheet, but here are some guidelines for filling out each setcion

Step1 System Details Tab
Input the maximum DDR frequency that will be used

Step4 Board Details
Enter the trace length (in inches) of each trace. For DDR_CK, 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 for a 'T' configuration. For fly-by topology, where the trace runs from AM335x to the first memory, and then to the second memory, ensure that you input the total trace length for each byte.

Registers
=Software Leveling=

Files needed for this procedure: Code Composer GEL file: You can use the [[Media:AM335x_forSlaveRatio.zip| AM335x GEL for SlaveRatio calculation]] to start with. Executable CCS .out file: [[Media:DDR3_SlaveRatioSearch_ver2.zip| Software Leveling Algorithm]] 1. Change the following section of the GEL file based on the values calculated in the AM335x EMIF Configuration Tool. Refer to the 'EMIF tool' and 'Registers' tabs of the spreadsheet for the correct values. Check the comments in the excerpt below and change the value accordingly.

//******************************************************************* //DDR3 PHY parameters //*******************************************************************


 * 1) define CMD_PHY_CTRL_SLAVE_RATIO       0x100   //EMIF tool tab: CMDx_PHY_CTRL_SLAVE_RATIO
 * 2) define CMD_PHY_INVERT_CLKOUT          0x1     //EMIF tool tab: Invert Clock


 * 1) define DATA_PHY_RD_DQS_SLAVE_RATIO    0x38    //Don't change.  Value is calculated by the SW leveling algorithm
 * 2) define DATA_PHY_FIFO_WE_SLAVE_RATIO   0xFC    //Don't change.  Value is calculated by the SW leveling algorithm
 * 3) define DATA_PHY_WR_DQS_SLAVE_RATIO    0x78    //Don't change.  Value is calculated by the SW leveling algorithm
 * 4) define DATA_PHY_WR_DATA_SLAVE_RATIO   0xB8    //Don't change.  Value is calculated by the SW leveling algorithm


 * 1) define DDR_IOCTRL_VALUE           (0x18B)     //Registers tab: DDR_CMDx_IOCTRL

//****************************************************************** //EMIF parameters //******************************************************************
 * 1) define ALLOPP_DDR3_READ_LATENCY   0x08       //Registers tab: DDR_PHY_CTRL_1
 * 2) define ALLOPP_DDR3_SDRAM_TIMING1  0x0AAAE4DB //Registers tab: SDRAM_TIM_1
 * 3) define ALLOPP_DDR3_SDRAM_TIMING2  0x266B7FDA //Registers tab: SDRAM_TIM_2
 * 4) define ALLOPP_DDR3_SDRAM_TIMING3  0x501F867F //Registers tab: SDRAM_TIM_3


 * 1) define ALLOPP_DDR3_SDRAM_CONFIG   0x61C051B2  //Registers tab: SDRAM_CONFIG
 * 1) define ALLOPP_DDR3_REF_CTRL       0x00000c30  //Registers tab: SDRAM_REF_CTRL
 * 2) define ALLOPP_DDR3_ZQ_CONFIG      0x50074BE4  //Registers tab: ZQ_CONFIG

2. If your board includes VTT termination, ensure the VTT regulator is enabled when running the software leveling algorithm. The GEL file includes function to enable/disable the VTT regulator using a GPIO. If your regulator is GPIO controlled, ensure that the GPIO used by these functions matches the GPIO that is used on your custom board.

3. Connect the board to Code Composer and run the GEL file Scripts->AM335x System Initialization. Load the DDR3_slave_ratio_search_auto_ver2.out file from above. Important: After loading the file, ensure that the processor is in supervisor mode by executing the script Script->default->AM335xStartState. The processor mode will be shown in the lower right corner of the CCS screen

4.Run the code. The console window in CCS will prompt you for some input values. Input each value from the 'EMIF tool' tab of the spreadsheet (input in hex with no leading '0x') corresponding to the prompt. The values will be in sections 3B and 3E of the spreadsheet. The program may take a some time to run (especially if using XDS100), as it may iterate in a loop several times to come up to the optimal values. The console window will show progress and will look something like this:

[CortxA8] Enter the PHY_INVERT_CLKOUT value (0 or 1) from the spreadsheet 1

Enter the Seed RD_DQS_SLAVE_RATIO Value in Hex to search the RD DQS Ratio Window 40

Enter the Seed FIFO_WE_SLAVE_RATIO Value in Hex to search the RD DQS Gate Window 114

Enter the Seed WR_DQS_SLAVE_RATIO Write DQS Ratio Value in Hex to search the Write DQS Ratio Window 87

The Slave Ratio Search Program Values are... PARAMETER                      MAX  |  MIN  | OPTIMUM |  RANGE DATA_PHY_RD_DQS_SLAVE_RATIO   0x06a | 0x007 |  0x038  | 0x063 DATA_PHY_FIFO_WE_SLAVE_RATIO  0x1d3 | 0x04f |  0x111  | 0x184 DATA_PHY_WR_DQS_SLAVE_RATIO   0x0f9 | 0x00d |  0x083  | 0x0ec DATA_PHY_WR_DATA_SLAVE_RATIO  0x139 | 0x04d |  0x0c3  | 0x0ec rd_dqs_range = 38 fifo_we_range = 111 wr_dqs_range = 83 wr_data_range = 0

Optimal values not reached, rerunning program with new values...

The Slave Ratio Search Program Values are... PARAMETER                      MAX  |  MIN  | OPTIMUM |  RANGE DATA_PHY_RD_DQS_SLAVE_RATIO   0x06b | 0x007 |  0x039  | 0x064 DATA_PHY_FIFO_WE_SLAVE_RATIO  0x1cd | 0x048 |  0x10a  | 0x185 DATA_PHY_WR_DQS_SLAVE_RATIO   0x0f9 | 0x00d |  0x083  | 0x0ec DATA_PHY_WR_DATA_SLAVE_RATIO  0x139 | 0x04d |  0x0c3  | 0x0ec rd_dqs_range = 1 fifo_we_range = 7 wr_dqs_range = 0 wr_data_range = 0

Optimal values not reached, rerunning program with new values...

The Slave Ratio Search Program Values are... PARAMETER                      MAX  |  MIN  | OPTIMUM |  RANGE DATA_PHY_RD_DQS_SLAVE_RATIO   0x06b | 0x007 |  0x039  | 0x064 DATA_PHY_FIFO_WE_SLAVE_RATIO  0x1c7 | 0x047 |  0x107  | 0x180 DATA_PHY_WR_DQS_SLAVE_RATIO   0x0f9 | 0x00d |  0x083  | 0x0ec DATA_PHY_WR_DATA_SLAVE_RATIO  0x139 | 0x04d |  0x0c3  | 0x0ec rd_dqs_range = 0 fifo_we_range = 3 wr_dqs_range = 0 wr_data_range = 0

Optimal values not reached, rerunning program with new values...

The Slave Ratio Search Program Values are... PARAMETER                      MAX  |  MIN  | OPTIMUM |  RANGE DATA_PHY_RD_DQS_SLAVE_RATIO   0x06b | 0x007 |  0x039  | 0x064 DATA_PHY_FIFO_WE_SLAVE_RATIO  0x1cb | 0x047 |  0x109  | 0x184 DATA_PHY_WR_DQS_SLAVE_RATIO   0x0f8 | 0x00d |  0x082  | 0x0eb DATA_PHY_WR_DATA_SLAVE_RATIO  0x138 | 0x04d |  0x0c2  | 0x0eb rd_dqs_range = 0 fifo_we_range = 2 wr_dqs_range = 1 wr_data_range = 0

Optimal values have been found!!

The Slave Ratio Search Program Values are... PARAMETER                      MAX  |  MIN  | OPTIMUM |  RANGE DATA_PHY_RD_DQS_SLAVE_RATIO   0x06b | 0x007 |  0x039  | 0x064 DATA_PHY_FIFO_WE_SLAVE_RATIO  0x1cb | 0x047 |  0x109  | 0x184 DATA_PHY_WR_DQS_SLAVE_RATIO   0x0f8 | 0x00d |  0x082  | 0x0eb DATA_PHY_WR_DATA_SLAVE_RATIO  0x138 | 0x04d |  0x0c2  | 0x0eb

END OF TEST
4. Once the program has finished running, use the 4 optimal values (in the OPTIMUM column) to program the appropriate DDR PHY slave ratio register values. You can start by replacing the ones in the GEL:

//******************************************************************* //DDR3 PHY parameters //*******************************************************************


 * 1) define DATA_PHY_RD_DQS_SLAVE_RATIO    0x3A  //replace with optimum value from SW leveling algorithm
 * 2) define DATA_PHY_FIFO_WE_SLAVE_RATIO   0x11B //replace with optimum value from SW leveling algorithm
 * 3) define DATA_PHY_WR_DQS_SLAVE_RATIO    0xA8  //replace with optimum value from SW leveling algorithm
 * 4) define DATA_PHY_WR_DATA_SLAVE_RATIO   0xE1  //replace with optimum value from SW leveling algorithm

Save the GEL after changing the optimum values. Then terminate the debug session and power cycle the board.

6. Connect to the board again in CCS. The initialization script should automatically run. To test the results, open up a memory window in DDR space (0x80000000), and see if you can read/write values successfully. There are also a couple of DDR test scripts in the GEL which you can run (Scripts->AM335x DDR Tests). If the results look stable, then you have finished. These values should be programmed during your DDR initialization routine in your boot code (for example, in your linux bootloader).

Further notes: Ensure to disable any HW leveling by setting REG_RDWRLVL_EN = 0 in the Read-Write Leveling Ramp Control Register in the EMIF.

Procedural notes
Here are some notes on this procedure:
 * If you rerun this program on the same board, you may get slightly different results. But these values could also be used.  The program tries to find the proper timing window for reads and writes, and then chooses the middle of that window to allow for maximum timing margin.  So these optimal values may be a little different with each run of this test program.
 * The program defines the following ranges to determine when to stop looking for optimal values. These values were chosen based on multiple runs with different boards we tested.
 * 1) define RD_DQS_OPTIMAL_RANGE 2
 * 2) define WR_DQS_OPTIMAL_RANGE 3
 * 3) define FIFO_WE_OPTIMAL_RANGE 2
 * 4) define WR_DATA_OPTIMAL_RANGE 3
 * If the program results in all zeros for values, then something has gone wrong and it was not able to converge on optimal values. Double check the values obtained in the spreadsheet and the values input while running the program in CCS.  Also insure you run the algorithm with the ARM processor in Supervisor mode (review Step 3 above)