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