uboot/board/xes/xpedite517x/ddr.c
<<
>>
Prefs
   1/*
   2 * Copyright 2009 Extreme Engineering Solutions, Inc.
   3 * Copyright 2007-2008 Freescale Semiconductor, Inc.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24#include <common.h>
  25#include <i2c.h>
  26#include <asm/fsl_ddr_sdram.h>
  27#include <asm/fsl_ddr_dimm_params.h>
  28
  29void get_spd(ddr2_spd_eeprom_t *spd, u8 i2c_address)
  30{
  31        i2c_read(i2c_address, SPD_EEPROM_OFFSET, 2, (uchar *)spd,
  32                sizeof(ddr2_spd_eeprom_t));
  33}
  34
  35/*
  36 * There are four board-specific SDRAM timing parameters which must be
  37 * calculated based on the particular PCB artwork.  These are:
  38 *   1.) CPO (Read Capture Delay)
  39 *           - TIMING_CFG_2 register
  40 *           Source: Calculation based on board trace lengths and
  41 *                   chip-specific internal delays.
  42 *   2.) WR_DATA_DELAY (Write Command to Data Strobe Delay)
  43 *           - TIMING_CFG_2 register
  44 *           Source: Calculation based on board trace lengths.
  45 *                   Unless clock and DQ lanes are very different
  46 *                   lengths (>2"), this should be set to the nominal value
  47 *                   of 1/2 clock delay.
  48 *   3.) CLK_ADJUST (Clock and Addr/Cmd alignment control)
  49 *           - DDR_SDRAM_CLK_CNTL register
  50 *           Source: Signal Integrity Simulations
  51 *   4.) 2T Timing on Addr/Ctl
  52 *           - TIMING_CFG_2 register
  53 *           Source: Signal Integrity Simulations
  54 *           Usually only needed with heavy load/very high speed (>DDR2-800)
  55 *
  56 *     PCB routing on the XPedite5170 is nearly identical to the XPedite5370
  57 *     so we use the XPedite5370 settings as a basis for the XPedite5170.
  58 */
  59
  60typedef struct board_memctl_options {
  61        uint16_t datarate_mhz_low;
  62        uint16_t datarate_mhz_high;
  63        uint8_t clk_adjust;
  64        uint8_t cpo_override;
  65        uint8_t write_data_delay;
  66} board_memctl_options_t;
  67
  68static struct board_memctl_options bopts_ctrl[][2] = {
  69        {
  70                /* Controller 0 */
  71                {
  72                        /* DDR2 600/667 */
  73                        .datarate_mhz_low       = 500,
  74                        .datarate_mhz_high      = 750,
  75                        .clk_adjust             = 5,
  76                        .cpo_override           = 8,
  77                        .write_data_delay       = 2,
  78                },
  79                {
  80                        /* DDR2 800 */
  81                        .datarate_mhz_low       = 750,
  82                        .datarate_mhz_high      = 850,
  83                        .clk_adjust             = 5,
  84                        .cpo_override           = 9,
  85                        .write_data_delay       = 2,
  86                },
  87        },
  88        {
  89                /* Controller 1 */
  90                {
  91                        /* DDR2 600/667 */
  92                        .datarate_mhz_low       = 500,
  93                        .datarate_mhz_high      = 750,
  94                        .clk_adjust             = 5,
  95                        .cpo_override           = 7,
  96                        .write_data_delay       = 2,
  97                },
  98                {
  99                        /* DDR2 800 */
 100                        .datarate_mhz_low       = 750,
 101                        .datarate_mhz_high      = 850,
 102                        .clk_adjust             = 5,
 103                        .cpo_override           = 8,
 104                        .write_data_delay       = 2,
 105                },
 106        },
 107};
 108
 109void fsl_ddr_board_options(memctl_options_t *popts,
 110                        dimm_params_t *pdimm,
 111                        unsigned int ctrl_num)
 112{
 113        struct board_memctl_options *bopts = bopts_ctrl[ctrl_num];
 114        sys_info_t sysinfo;
 115        int i;
 116        unsigned int datarate;
 117
 118        get_sys_info(&sysinfo);
 119        datarate = get_ddr_freq(0) / 1000000;
 120
 121        for (i = 0; i < ARRAY_SIZE(bopts_ctrl[ctrl_num]); i++) {
 122                if ((bopts[i].datarate_mhz_low <= datarate) &&
 123                    (bopts[i].datarate_mhz_high >= datarate)) {
 124                        debug("controller %d:\n", ctrl_num);
 125                        debug(" clk_adjust = %d\n", bopts[i].clk_adjust);
 126                        debug(" cpo = %d\n", bopts[i].cpo_override);
 127                        debug(" write_data_delay = %d\n",
 128                                bopts[i].write_data_delay);
 129                        popts->clk_adjust = bopts[i].clk_adjust;
 130                        popts->cpo_override = bopts[i].cpo_override;
 131                        popts->write_data_delay = bopts[i].write_data_delay;
 132                }
 133        }
 134
 135        /*
 136         * Factors to consider for half-strength driver enable:
 137         *      - number of DIMMs installed
 138         */
 139        popts->half_strength_driver_enable = 0;
 140}
 141