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