uboot/board/xes/xpedite517x/ddr.c
<<
>>
Prefs
   1/*
   2 * Copyright 2009 Extreme Engineering Solutions, Inc.
   3 * Copyright 2007-2008 Freescale Semiconductor, Inc.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <i2c.h>
  10#include <fsl_ddr_sdram.h>
  11#include <fsl_ddr_dimm_params.h>
  12
  13void get_spd(ddr2_spd_eeprom_t *spd, u8 i2c_address)
  14{
  15        i2c_read(i2c_address, SPD_EEPROM_OFFSET, 2, (uchar *)spd,
  16                sizeof(ddr2_spd_eeprom_t));
  17}
  18
  19/*
  20 * There are four board-specific SDRAM timing parameters which must be
  21 * calculated based on the particular PCB artwork.  These are:
  22 *   1.) CPO (Read Capture Delay)
  23 *           - TIMING_CFG_2 register
  24 *           Source: Calculation based on board trace lengths and
  25 *                   chip-specific internal delays.
  26 *   2.) WR_DATA_DELAY (Write Command to Data Strobe Delay)
  27 *           - TIMING_CFG_2 register
  28 *           Source: Calculation based on board trace lengths.
  29 *                   Unless clock and DQ lanes are very different
  30 *                   lengths (>2"), this should be set to the nominal value
  31 *                   of 1/2 clock delay.
  32 *   3.) CLK_ADJUST (Clock and Addr/Cmd alignment control)
  33 *           - DDR_SDRAM_CLK_CNTL register
  34 *           Source: Signal Integrity Simulations
  35 *   4.) 2T Timing on Addr/Ctl
  36 *           - TIMING_CFG_2 register
  37 *           Source: Signal Integrity Simulations
  38 *           Usually only needed with heavy load/very high speed (>DDR2-800)
  39 *
  40 *     PCB routing on the XPedite5170 is nearly identical to the XPedite5370
  41 *     so we use the XPedite5370 settings as a basis for the XPedite5170.
  42 */
  43
  44typedef struct board_memctl_options {
  45        uint16_t datarate_mhz_low;
  46        uint16_t datarate_mhz_high;
  47        uint8_t clk_adjust;
  48        uint8_t cpo_override;
  49        uint8_t write_data_delay;
  50} board_memctl_options_t;
  51
  52static struct board_memctl_options bopts_ctrl[][2] = {
  53        {
  54                /* Controller 0 */
  55                {
  56                        /* DDR2 600/667 */
  57                        .datarate_mhz_low       = 500,
  58                        .datarate_mhz_high      = 750,
  59                        .clk_adjust             = 5,
  60                        .cpo_override           = 8,
  61                        .write_data_delay       = 2,
  62                },
  63                {
  64                        /* DDR2 800 */
  65                        .datarate_mhz_low       = 750,
  66                        .datarate_mhz_high      = 850,
  67                        .clk_adjust             = 5,
  68                        .cpo_override           = 9,
  69                        .write_data_delay       = 2,
  70                },
  71        },
  72        {
  73                /* Controller 1 */
  74                {
  75                        /* DDR2 600/667 */
  76                        .datarate_mhz_low       = 500,
  77                        .datarate_mhz_high      = 750,
  78                        .clk_adjust             = 5,
  79                        .cpo_override           = 7,
  80                        .write_data_delay       = 2,
  81                },
  82                {
  83                        /* DDR2 800 */
  84                        .datarate_mhz_low       = 750,
  85                        .datarate_mhz_high      = 850,
  86                        .clk_adjust             = 5,
  87                        .cpo_override           = 8,
  88                        .write_data_delay       = 2,
  89                },
  90        },
  91};
  92
  93void fsl_ddr_board_options(memctl_options_t *popts,
  94                        dimm_params_t *pdimm,
  95                        unsigned int ctrl_num)
  96{
  97        struct board_memctl_options *bopts = bopts_ctrl[ctrl_num];
  98        sys_info_t sysinfo;
  99        int i;
 100        unsigned int datarate;
 101
 102        get_sys_info(&sysinfo);
 103        datarate = get_ddr_freq(0) / 1000000;
 104
 105        for (i = 0; i < ARRAY_SIZE(bopts_ctrl[ctrl_num]); i++) {
 106                if ((bopts[i].datarate_mhz_low <= datarate) &&
 107                    (bopts[i].datarate_mhz_high >= datarate)) {
 108                        debug("controller %d:\n", ctrl_num);
 109                        debug(" clk_adjust = %d\n", bopts[i].clk_adjust);
 110                        debug(" cpo = %d\n", bopts[i].cpo_override);
 111                        debug(" write_data_delay = %d\n",
 112                                bopts[i].write_data_delay);
 113                        popts->clk_adjust = bopts[i].clk_adjust;
 114                        popts->cpo_override = bopts[i].cpo_override;
 115                        popts->write_data_delay = bopts[i].write_data_delay;
 116                }
 117        }
 118
 119        /*
 120         * Factors to consider for half-strength driver enable:
 121         *      - number of DIMMs installed
 122         */
 123        popts->half_strength_driver_enable = 0;
 124}
 125