uboot/board/freescale/mpc8572ds/ddr.c
<<
>>
Prefs
   1/*
   2 * Copyright 2008 Freescale Semiconductor, Inc.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0
   5 */
   6
   7#include <common.h>
   8
   9#include <fsl_ddr_sdram.h>
  10#include <fsl_ddr_dimm_params.h>
  11
  12struct board_specific_parameters {
  13        u32 n_ranks;
  14        u32 datarate_mhz_high;
  15        u32 clk_adjust;
  16        u32 cpo;
  17        u32 write_data_delay;
  18        u32 force_2t;
  19};
  20
  21/*
  22 * This table contains all valid speeds we want to override with board
  23 * specific parameters. datarate_mhz_high values need to be in ascending order
  24 * for each n_ranks group.
  25 *
  26 * For DDR2 DIMM, all combinations of clk_adjust and write_data_delay have been
  27 * tested. For RDIMM, clk_adjust = 4 and write_data_delay = 3 is optimized for
  28 * all clocks from 400MT/s to 800MT/s, verified with Kingston KVR800D2D8P6/2G.
  29 * For UDIMM, clk_adjust = 8 and write_delay = 5 is optimized for all clocks
  30 * from 400MT/s to 800MT/s, verified with Micron MT18HTF25672AY-800E1.
  31 *
  32 * CPO value doesn't matter if workaround for errata 111 and 134 enabled.
  33 */
  34static const struct board_specific_parameters udimm0[] = {
  35        /*
  36         * memory controller 0
  37         *   num|  hi|  clk| cpo|wrdata|2T
  38         * ranks| mhz|adjst|    | delay|
  39         */
  40        {2,  333,    8,   7,    5,  0},
  41        {2,  400,    8,   9,    5,  0},
  42        {2,  549,    8,  11,    5,  0},
  43        {2,  680,    8,  10,    5,  0},
  44        {2,  850,    8,  12,    5,  1},
  45        {1,  333,    6,   7,    3,  0},
  46        {1,  400,    6,   9,    3,  0},
  47        {1,  549,    6,  11,    3,  0},
  48        {1,  680,    1,  10,    5,  0},
  49        {1,  850,    1,  12,    5,  0},
  50        {}
  51};
  52
  53static const struct board_specific_parameters udimm1[] = {
  54        /*
  55         * memory controller 1
  56         *   num|  hi|  clk| cpo|wrdata|2T
  57         * ranks| mhz|adjst|    | delay|
  58         */
  59        {2,  333,    8,  7,    5,  0},
  60        {2,  400,    8,  9,    5,  0},
  61        {2,  549,    8, 11,    5,  0},
  62        {2,  680,    8, 11,    5,  0},
  63        {2,  850,    8, 13,    5,  1},
  64        {1,  333,    6,  7,    3,  0},
  65        {1,  400,    6,  9,    3,  0},
  66        {1,  549,    6, 11,    3,  0},
  67        {1,  680,    1, 11,    6,  0},
  68        {1,  850,    1, 13,    6,  0},
  69        {}
  70};
  71
  72static const struct board_specific_parameters *udimms[] = {
  73        udimm0,
  74        udimm1,
  75};
  76
  77static const struct board_specific_parameters rdimm0[] = {
  78        /*
  79         * memory controller 0
  80         *   num|  hi|  clk| cpo|wrdata|2T
  81         * ranks| mhz|adjst|    | delay|
  82         */
  83        {2,  333,    4,   7,    3,  0},
  84        {2,  400,    4,   9,    3,  0},
  85        {2,  549,    4,  11,    3,  0},
  86        {2,  680,    4,  10,    3,  0},
  87        {2,  850,    4,  12,    3,  1},
  88        {}
  89};
  90
  91static const struct board_specific_parameters rdimm1[] = {
  92        /*
  93         * memory controller 1
  94         *   num|  hi|  clk| cpo|wrdata|2T
  95         * ranks| mhz|adjst|    | delay|
  96         */
  97        {2,  333,     4,  7,    3,  0},
  98        {2,  400,     4,  9,    3,  0},
  99        {2,  549,     4, 11,    3,  0},
 100        {2,  680,     4, 11,    3,  0},
 101        {2,  850,     4, 13,    3,  1},
 102        {}
 103};
 104
 105static const struct board_specific_parameters *rdimms[] = {
 106        rdimm0,
 107        rdimm1,
 108};
 109
 110void fsl_ddr_board_options(memctl_options_t *popts,
 111                                dimm_params_t *pdimm,
 112                                unsigned int ctrl_num)
 113{
 114        const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
 115        ulong ddr_freq;
 116
 117        if (ctrl_num > 1) {
 118                printf("Wrong parameter for controller number %d", ctrl_num);
 119                return;
 120        }
 121        if (!pdimm->n_ranks)
 122                return;
 123
 124        if (popts->registered_dimm_en)
 125                pbsp = rdimms[ctrl_num];
 126        else
 127                pbsp = udimms[ctrl_num];
 128
 129        /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
 130         * freqency and n_banks specified in board_specific_parameters table.
 131         */
 132        ddr_freq = get_ddr_freq(0) / 1000000;
 133        while (pbsp->datarate_mhz_high) {
 134                if (pbsp->n_ranks == pdimm->n_ranks) {
 135                        if (ddr_freq <= pbsp->datarate_mhz_high) {
 136                                popts->clk_adjust = pbsp->clk_adjust;
 137                                popts->cpo_override = pbsp->cpo;
 138                                popts->write_data_delay =
 139                                        pbsp->write_data_delay;
 140                                popts->twot_en = pbsp->force_2t;
 141                                goto found;
 142                        }
 143                        pbsp_highest = pbsp;
 144                }
 145                pbsp++;
 146        }
 147
 148        if (pbsp_highest) {
 149                printf("Error: board specific timing not found "
 150                        "for data rate %lu MT/s!\n"
 151                        "Trying to use the highest speed (%u) parameters\n",
 152                        ddr_freq, pbsp_highest->datarate_mhz_high);
 153                popts->clk_adjust = pbsp->clk_adjust;
 154                popts->cpo_override = pbsp->cpo;
 155                popts->write_data_delay = pbsp->write_data_delay;
 156                popts->twot_en = pbsp->force_2t;
 157        } else {
 158                panic("DIMM is not supported by this board");
 159        }
 160
 161found:
 162        /*
 163         * Factors to consider for half-strength driver enable:
 164         *      - number of DIMMs installed
 165         */
 166        popts->half_strength_driver_enable = 0;
 167}
 168