uboot/board/freescale/p2041rdb/ddr.c
<<
>>
Prefs
   1/*
   2 * Copyright 2011 Freescale Semiconductor, Inc.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0
   5 */
   6
   7#include <common.h>
   8#include <i2c.h>
   9#include <hwconfig.h>
  10#include <asm/mmu.h>
  11#include <fsl_ddr_sdram.h>
  12#include <fsl_ddr_dimm_params.h>
  13#include <asm/fsl_law.h>
  14
  15struct board_specific_parameters {
  16        u32 n_ranks;
  17        u32 datarate_mhz_high;
  18        u32 clk_adjust;
  19        u32 wrlvl_start;
  20        u32 cpo;
  21        u32 write_data_delay;
  22        u32 force_2t;
  23};
  24
  25/*
  26 * This table contains all valid speeds we want to override with board
  27 * specific parameters. datarate_mhz_high values need to be in ascending order
  28 * for each n_ranks group.
  29 *
  30 * ranges for parameters:
  31 *  wr_data_delay = 0-6
  32 *  clk adjust = 0-8
  33 *  cpo 2-0x1E (30)
  34 */
  35static const struct board_specific_parameters dimm0[] = {
  36        /*
  37         * memory controller 0
  38         *   num|  hi|  clk| wrlvl | cpo  |wrdata|2T
  39         * ranks| mhz|adjst| start | delay|
  40         */
  41        {2,   750,    3,     5,   0xff,    2,  0},
  42        {2,  1250,    4,     6,   0xff,    2,  0},
  43        {2,  1350,    5,     7,   0xff,    2,  0},
  44        {2,  1666,    5,     8,   0xff,    2,  0},
  45        {}
  46};
  47
  48void fsl_ddr_board_options(memctl_options_t *popts,
  49                                dimm_params_t *pdimm,
  50                                unsigned int ctrl_num)
  51{
  52        const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
  53        ulong ddr_freq;
  54
  55        if (ctrl_num) {
  56                printf("Wrong parameter for controller number %d", ctrl_num);
  57                return;
  58        }
  59        if (!pdimm->n_ranks)
  60                return;
  61
  62        pbsp = dimm0;
  63
  64        /*
  65         * Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
  66         * freqency and n_banks specified in board_specific_parameters table.
  67         */
  68        ddr_freq = get_ddr_freq(0) / 1000000;
  69        while (pbsp->datarate_mhz_high) {
  70                if (pbsp->n_ranks == pdimm->n_ranks) {
  71                        if (ddr_freq <= pbsp->datarate_mhz_high) {
  72                                popts->cpo_override = pbsp->cpo;
  73                                popts->write_data_delay =
  74                                        pbsp->write_data_delay;
  75                                popts->clk_adjust = pbsp->clk_adjust;
  76                                popts->wrlvl_start = pbsp->wrlvl_start;
  77                                popts->twot_en = pbsp->force_2t;
  78                                goto found;
  79                        }
  80                        pbsp_highest = pbsp;
  81                }
  82                pbsp++;
  83        }
  84
  85        if (pbsp_highest) {
  86                printf("Error: board specific timing not found "
  87                        "for data rate %lu MT/s!\n"
  88                        "Trying to use the highest speed (%u) parameters\n",
  89                        ddr_freq, pbsp_highest->datarate_mhz_high);
  90                popts->cpo_override = pbsp_highest->cpo;
  91                popts->write_data_delay = pbsp_highest->write_data_delay;
  92                popts->clk_adjust = pbsp_highest->clk_adjust;
  93                popts->wrlvl_start = pbsp_highest->wrlvl_start;
  94                popts->twot_en = pbsp_highest->force_2t;
  95        } else {
  96                panic("DIMM is not supported by this board");
  97        }
  98
  99found:
 100        /*
 101         * Factors to consider for half-strength driver enable:
 102         *      - number of DIMMs installed
 103         */
 104        popts->half_strength_driver_enable = 0;
 105        /* Write leveling override */
 106        popts->wrlvl_override = 1;
 107        popts->wrlvl_sample = 0xf;
 108
 109        /* Rtt and Rtt_WR override */
 110        popts->rtt_override = 0;
 111
 112        /* Enable ZQ calibration */
 113        popts->zq_en = 1;
 114
 115        /* DHC_EN =1, ODT = 60 Ohm */
 116        popts->ddr_cdr1 = DDR_CDR1_DHC_EN;
 117}
 118
 119phys_size_t initdram(int board_type)
 120{
 121        phys_size_t dram_size = 0;
 122
 123        puts("Initializing....");
 124
 125        if (fsl_use_spd()) {
 126                puts("using SPD\n");
 127                dram_size = fsl_ddr_sdram();
 128        } else {
 129                puts("no SPD and fixed parameters\n");
 130                return dram_size;
 131        }
 132
 133        dram_size = setup_ddr_tlbs(dram_size / 0x100000);
 134        dram_size *= 0x100000;
 135
 136        debug("    DDR: ");
 137        return dram_size;
 138}
 139