Commit 58e5e9aff147e8c7e2bc1406bf9384f65f020ffa

Authored by Kumar Gala
Committed by Wolfgang Denk
1 parent f784e32b4b

FSL DDR: Rewrite the FSL mpc8xxx DDR controller setup code.

The main purpose of this rewrite it to be able to share the same
initialization code on all FSL PowerPC products that have DDR
controllers.  (83xx, 85xx, 86xx).

The code is broken up into the following steps:
	GET_SPD
	COMPUTE_DIMM_PARMS
	COMPUTE_COMMON_PARMS
	GATHER_OPTS
	ASSIGN_ADDRESSES
	COMPUTE_REGS
	PROGRAM_REGS

This allows us to share more code an easily allow for board specific code
overrides.

Additionally this code base adds support for >4G of DDR and provides a
foundation for supporting interleaving on processors with more than one
controller.

Signed-off-by: James Yang <James.Yang@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Becky Bruce <becky.bruce@freescale.com>
Signed-off-by: Ed Swarthout <Ed.Swarthout@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>

Showing 13 changed files with 2573 additions and 2 deletions Side-by-side Diff

... ... @@ -236,6 +236,10 @@
236 236 endif
237 237 ifeq ($(CPU),mpc85xx)
238 238 LIBS += drivers/qe/qe.a
  239 +LIBS += cpu/mpc8xxx/ddr/libddr.a
  240 +endif
  241 +ifeq ($(CPU),mpc86xx)
  242 +LIBS += cpu/mpc8xxx/ddr/libddr.a
239 243 endif
240 244 LIBS += drivers/rtc/librtc.a
241 245 LIBS += drivers/serial/libserial.a
cpu/mpc85xx/Makefile
... ... @@ -33,8 +33,17 @@
33 33 SOBJS = $(SOBJS-y)
34 34 COBJS-$(CONFIG_MP) += mp.o
35 35 COBJS-$(CONFIG_OF_LIBFDT) += fdt.o
  36 +
  37 +ifneq ($(CONFIG_FSL_DDR3),y)
  38 +ifneq ($(CONFIG_FSL_DDR2),y)
  39 +ifneq ($(CONFIG_FSL_DDR1),y)
  40 +COBJS-y += spd_sdram.o
  41 +endif
  42 +endif
  43 +endif
  44 +
36 45 COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o tlb.o \
37   - pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o qe_io.o \
  46 + pci.o serial_scc.o commproc.o ether_fcc.o qe_io.o \
38 47 $(COBJS-y)
39 48  
40 49 SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
cpu/mpc86xx/Makefile
... ... @@ -36,9 +36,12 @@
36 36 COBJS-y += cpu_init.o
37 37 COBJS-y += speed.o
38 38 COBJS-y += interrupts.o
39   -COBJS-y += spd_sdram.o
40 39  
41 40 COBJS-$(CONFIG_OF_LIBFDT) += fdt.o
  41 +
  42 +ifneq ($(CONFIG_FSL_DDR2),y)
  43 +COBJS-y += spd_sdram.o
  44 +endif
42 45  
43 46 SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
44 47 OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
cpu/mpc8xxx/ddr/Makefile
  1 +#
  2 +# Copyright 2008 Freescale Semiconductor, Inc.
  3 +#
  4 +# This program is free software; you can redistribute it and/or
  5 +# modify it under the terms of the GNU General Public License
  6 +# Version 2 as published by the Free Software Foundation.
  7 +#
  8 +
  9 +include $(TOPDIR)/config.mk
  10 +
  11 +LIB = $(obj)libddr.a
  12 +
  13 +COBJS-$(CONFIG_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \
  14 + lc_common_dimm_params.o
  15 +COBJS-$(CONFIG_FSL_DDR1) += ddr1_dimm_params.o
  16 +
  17 +COBJS-$(CONFIG_FSL_DDR2) += main.o util.o ctrl_regs.o options.o \
  18 + lc_common_dimm_params.o
  19 +COBJS-$(CONFIG_FSL_DDR2) += ddr2_dimm_params.o
  20 +
  21 +SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
  22 +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
  23 +
  24 +all: $(obj).depend $(LIB)
  25 +
  26 +$(LIB): $(OBJS)
  27 + $(AR) $(ARFLAGS) $@ $(OBJS)
  28 +
  29 +include $(SRCTREE)/rules.mk
  30 +
  31 +sinclude $(obj).depend
cpu/mpc8xxx/ddr/common_timing_params.h
  1 +/*
  2 + * Copyright 2008 Freescale Semiconductor, Inc.
  3 + *
  4 + * This program is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU General Public License
  6 + * Version 2 as published by the Free Software Foundation.
  7 + */
  8 +
  9 +#ifndef COMMON_TIMING_PARAMS_H
  10 +#define COMMON_TIMING_PARAMS_H
  11 +
  12 +typedef struct {
  13 + /* parameters to constrict */
  14 +
  15 + unsigned int tCKmin_X_ps;
  16 + unsigned int tCKmax_ps;
  17 + unsigned int tCKmax_max_ps;
  18 + unsigned int tRCD_ps;
  19 + unsigned int tRP_ps;
  20 + unsigned int tRAS_ps;
  21 +
  22 + unsigned int tWR_ps; /* maximum = 63750 ps */
  23 + unsigned int tWTR_ps; /* maximum = 63750 ps */
  24 + unsigned int tRFC_ps; /* maximum = 255 ns + 256 ns + .75 ns
  25 + = 511750 ps */
  26 +
  27 + unsigned int tRRD_ps; /* maximum = 63750 ps */
  28 + unsigned int tRC_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
  29 +
  30 + unsigned int refresh_rate_ps;
  31 +
  32 + unsigned int tIS_ps; /* byte 32, spd->ca_setup */
  33 + unsigned int tIH_ps; /* byte 33, spd->ca_hold */
  34 + unsigned int tDS_ps; /* byte 34, spd->data_setup */
  35 + unsigned int tDH_ps; /* byte 35, spd->data_hold */
  36 + unsigned int tRTP_ps; /* byte 38, spd->trtp */
  37 + unsigned int tDQSQ_max_ps; /* byte 44, spd->tdqsq */
  38 + unsigned int tQHS_ps; /* byte 45, spd->tqhs */
  39 +
  40 + unsigned int ndimms_present;
  41 + unsigned int lowest_common_SPD_caslat;
  42 + unsigned int highest_common_derated_caslat;
  43 + unsigned int additive_latency;
  44 + unsigned int all_DIMMs_burst_lengths_bitmask;
  45 + unsigned int all_DIMMs_registered;
  46 + unsigned int all_DIMMs_unbuffered;
  47 + unsigned int all_DIMMs_ECC_capable;
  48 +
  49 + unsigned long long total_mem;
  50 + unsigned long long base_address;
  51 +} common_timing_params_t;
  52 +
  53 +#endif
cpu/mpc8xxx/ddr/ctrl_regs.c
  1 +/*
  2 + * Copyright 2008 Freescale Semiconductor, Inc.
  3 + *
  4 + * This program is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU General Public License
  6 + * Version 2 as published by the Free Software Foundation.
  7 + */
  8 +
  9 +/*
  10 + * Generic driver for Freescale DDR/DDR2/DDR3 memory controller.
  11 + * Based on code from spd_sdram.c
  12 + * Author: James Yang [at freescale.com]
  13 + */
  14 +
  15 +#include <common.h>
  16 +#include <asm/fsl_ddr_sdram.h>
  17 +
  18 +#include "ddr.h"
  19 +
  20 +extern unsigned int picos_to_mclk(unsigned int picos);
  21 +/*
  22 + * Determine Rtt value.
  23 + *
  24 + * This should likely be either board or controller specific.
  25 + *
  26 + * Rtt(nominal):
  27 + * 0 = Rtt disabled
  28 + * 1 = 75 ohm
  29 + * 2 = 150 ohm
  30 + * 3 = 50 ohm
  31 + *
  32 + * FIXME: Apparently 8641 needs a value of 2
  33 + * FIXME: Old code seys if 667 MHz or higher, use 3 on 8572
  34 + *
  35 + * FIXME: There was some effort down this line earlier:
  36 + *
  37 + * unsigned int i;
  38 + * for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL/2; i++) {
  39 + * if (popts->dimmslot[i].num_valid_cs
  40 + * && (popts->cs_local_opts[2*i].odt_rd_cfg
  41 + * || popts->cs_local_opts[2*i].odt_wr_cfg)) {
  42 + * rtt = 2;
  43 + * break;
  44 + * }
  45 + * }
  46 + */
  47 +static inline int fsl_ddr_get_rtt(void)
  48 +{
  49 + int rtt;
  50 +
  51 +#if defined(CONFIG_FSL_DDR1)
  52 + rtt = 0;
  53 +#elif defined(CONFIG_FSL_DDR2)
  54 + rtt = 3;
  55 +#else
  56 +#error "Need Rtt value for DDR3"
  57 +#endif
  58 +
  59 + return rtt;
  60 +}
  61 +
  62 +/* Chip Select Configuration (CSn_CONFIG) */
  63 +static void set_csn_config(int i, fsl_ddr_cfg_regs_t *ddr,
  64 + const memctl_options_t *popts,
  65 + const dimm_params_t *dimm_params)
  66 +{
  67 + unsigned int cs_n_en = 0; /* Chip Select enable */
  68 + unsigned int intlv_en = 0; /* Memory controller interleave enable */
  69 + unsigned int intlv_ctl = 0; /* Interleaving control */
  70 + unsigned int ap_n_en = 0; /* Chip select n auto-precharge enable */
  71 + unsigned int odt_rd_cfg = 0; /* ODT for reads configuration */
  72 + unsigned int odt_wr_cfg = 0; /* ODT for writes configuration */
  73 + unsigned int ba_bits_cs_n = 0; /* Num of bank bits for SDRAM on CSn */
  74 + unsigned int row_bits_cs_n = 0; /* Num of row bits for SDRAM on CSn */
  75 + unsigned int col_bits_cs_n = 0; /* Num of ocl bits for SDRAM on CSn */
  76 +
  77 + /* Compute CS_CONFIG only for existing ranks of each DIMM. */
  78 + if ((((i&1) == 0)
  79 + && (dimm_params[i/2].n_ranks == 1))
  80 + || (dimm_params[i/2].n_ranks == 2)) {
  81 + unsigned int n_banks_per_sdram_device;
  82 + cs_n_en = 1;
  83 + if (i == 0) {
  84 + /* These fields only available in CS0_CONFIG */
  85 + intlv_en = popts->memctl_interleaving;
  86 + intlv_ctl = popts->memctl_interleaving_mode;
  87 + }
  88 + ap_n_en = popts->cs_local_opts[i].auto_precharge;
  89 + odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg;
  90 + odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg;
  91 + n_banks_per_sdram_device
  92 + = dimm_params[i/2].n_banks_per_sdram_device;
  93 + ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2;
  94 + row_bits_cs_n = dimm_params[i/2].n_row_addr - 12;
  95 + col_bits_cs_n = dimm_params[i/2].n_col_addr - 8;
  96 + }
  97 +
  98 + /* FIXME: intlv_en, intlv_ctl only on CS0_CONFIG */
  99 + if (i != 0) {
  100 + intlv_en = 0;
  101 + intlv_ctl = 0;
  102 + }
  103 +
  104 + ddr->cs[i].config = (0
  105 + | ((cs_n_en & 0x1) << 31)
  106 + | ((intlv_en & 0x3) << 29)
  107 + | ((intlv_en & 0xf) << 24)
  108 + | ((ap_n_en & 0x1) << 23)
  109 +
  110 + /* XXX: some implementation only have 1 bit starting at left */
  111 + | ((odt_rd_cfg & 0x7) << 20)
  112 +
  113 + /* XXX: Some implementation only have 1 bit starting at left */
  114 + | ((odt_wr_cfg & 0x7) << 16)
  115 +
  116 + | ((ba_bits_cs_n & 0x3) << 14)
  117 + | ((row_bits_cs_n & 0x7) << 8)
  118 + | ((col_bits_cs_n & 0x7) << 0)
  119 + );
  120 +}
  121 +
  122 +/* Chip Select Configuration 2 (CSn_CONFIG_2) */
  123 +/* FIXME: 8572 */
  124 +static void set_csn_config_2(int i, fsl_ddr_cfg_regs_t *ddr)
  125 +{
  126 + unsigned int pasr_cfg = 0; /* Partial array self refresh config */
  127 +
  128 + ddr->cs[i].config_2 = ((pasr_cfg & 7) << 24);
  129 +}
  130 +
  131 +/* -3E = 667 CL5, -25 = CL6 800, -25E = CL5 800 */
  132 +
  133 +#if defined(CONFIG_FSL_DDR2)
  134 +/*
  135 + * DDR SDRAM Timing Configuration 0 (TIMING_CFG_0)
  136 + *
  137 + * Avoid writing for DDR I. The new PQ38 DDR controller
  138 + * dreams up non-zero default values to be backwards compatible.
  139 + */
  140 +static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr)
  141 +{
  142 + unsigned char trwt_mclk = 0; /* Read-to-write turnaround */
  143 + unsigned char twrt_mclk = 0; /* Write-to-read turnaround */
  144 + /* 7.5 ns on -3E; 0 means WL - CL + BL/2 + 1 */
  145 + unsigned char trrt_mclk = 0; /* Read-to-read turnaround */
  146 + unsigned char twwt_mclk = 0; /* Write-to-write turnaround */
  147 +
  148 + /* Active powerdown exit timing (tXARD and tXARDS). */
  149 + unsigned char act_pd_exit_mclk;
  150 + /* Precharge powerdown exit timing (tXP). */
  151 + unsigned char pre_pd_exit_mclk;
  152 + /* Precharge powerdown exit timing (tAXPD). */
  153 + unsigned char taxpd_mclk;
  154 + /* Mode register set cycle time (tMRD). */
  155 + unsigned char tmrd_mclk;
  156 +
  157 + /* (tXARD and tXARDS). Empirical? */
  158 + act_pd_exit_mclk = 2;
  159 +
  160 + /* XXX: tXARD = 2, tXARDS = 7 - AL. * Empirical? */
  161 + pre_pd_exit_mclk = 6;
  162 +
  163 + /* FIXME: tXP = 2 on Micron 667 MHz DIMM */
  164 + taxpd_mclk = 8;
  165 +
  166 + tmrd_mclk = 2;
  167 +
  168 + ddr->timing_cfg_0 = (0
  169 + | ((trwt_mclk & 0x3) << 30) /* RWT */
  170 + | ((twrt_mclk & 0x3) << 28) /* WRT */
  171 + | ((trrt_mclk & 0x3) << 26) /* RRT */
  172 + | ((twwt_mclk & 0x3) << 24) /* WWT */
  173 + | ((act_pd_exit_mclk & 0x7) << 20) /* ACT_PD_EXIT */
  174 + | ((pre_pd_exit_mclk & 0x7) << 16) /* PRE_PD_EXIT */
  175 + | ((taxpd_mclk & 0xf) << 8) /* ODT_PD_EXIT */
  176 + | ((tmrd_mclk & 0xf) << 0) /* MRS_CYC */
  177 + );
  178 + debug("FSLDDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
  179 +}
  180 +#endif /* defined(CONFIG_FSL_DDR2) */
  181 +
  182 +/* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */
  183 +static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
  184 + const common_timing_params_t *common_dimm)
  185 +{
  186 + /* Extended Activate to precharge interval (tRAS) */
  187 + unsigned int ext_acttopre = 0;
  188 + unsigned int ext_refrec; /* Extended refresh recovery time (tRFC) */
  189 + unsigned int ext_caslat = 0; /* Extended MCAS latency from READ cmd */
  190 + unsigned int cntl_adj = 0; /* Control Adjust */
  191 +
  192 + ext_refrec = (picos_to_mclk(common_dimm->tRFC_ps) - 8) >> 4;
  193 + ddr->timing_cfg_3 = (0
  194 + | ((ext_acttopre & 0x1) << 24)
  195 + | ((ext_refrec & 0x7) << 16)
  196 + | ((ext_caslat & 0x1) << 12)
  197 + | ((cntl_adj & 0x7) << 0)
  198 + );
  199 +}
  200 +
  201 +/* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */
  202 +static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
  203 + const common_timing_params_t *common_dimm,
  204 + unsigned int cas_latency)
  205 +{
  206 + /* Precharge-to-activate interval (tRP) */
  207 + unsigned char pretoact_mclk;
  208 + /* Activate to precharge interval (tRAS) */
  209 + unsigned char acttopre_mclk;
  210 + /* Activate to read/write interval (tRCD) */
  211 + unsigned char acttorw_mclk;
  212 + /* CASLAT */
  213 + unsigned char caslat_ctrl;
  214 + /* Refresh recovery time (tRFC) ; trfc_low */
  215 + unsigned char refrec_ctrl;
  216 + /* Last data to precharge minimum interval (tWR) */
  217 + unsigned char wrrec_mclk;
  218 + /* Activate-to-activate interval (tRRD) */
  219 + unsigned char acttoact_mclk;
  220 + /* Last write data pair to read command issue interval (tWTR) */
  221 + unsigned char wrtord_mclk;
  222 +
  223 + pretoact_mclk = picos_to_mclk(common_dimm->tRP_ps);
  224 + acttopre_mclk = picos_to_mclk(common_dimm->tRAS_ps);
  225 + acttorw_mclk = picos_to_mclk(common_dimm->tRCD_ps);
  226 +
  227 + /*
  228 + * Translate CAS Latency to a DDR controller field value:
  229 + *
  230 + * CAS Lat DDR I DDR II Ctrl
  231 + * Clocks SPD Bit SPD Bit Value
  232 + * ------- ------- ------- -----
  233 + * 1.0 0 0001
  234 + * 1.5 1 0010
  235 + * 2.0 2 2 0011
  236 + * 2.5 3 0100
  237 + * 3.0 4 3 0101
  238 + * 3.5 5 0110
  239 + * 4.0 4 0111
  240 + * 4.5 1000
  241 + * 5.0 5 1001
  242 + */
  243 +#if defined(CONFIG_FSL_DDR1)
  244 + caslat_ctrl = (cas_latency + 1) & 0x07;
  245 +#elif defined(CONFIG_FSL_DDR2)
  246 + caslat_ctrl = 2 * cas_latency - 1;
  247 +#else
  248 +#error "Need CAS Latency help for DDR3 in fsl_ddr_sdram.c"
  249 +#endif
  250 +
  251 + refrec_ctrl = picos_to_mclk(common_dimm->tRFC_ps) - 8;
  252 + wrrec_mclk = picos_to_mclk(common_dimm->tWR_ps);
  253 + acttoact_mclk = picos_to_mclk(common_dimm->tRRD_ps);
  254 + wrtord_mclk = picos_to_mclk(common_dimm->tWTR_ps);
  255 +
  256 + ddr->timing_cfg_1 = (0
  257 + | ((pretoact_mclk & 0x07) << 28)
  258 + | ((acttopre_mclk & 0x0F) << 24)
  259 + | ((acttorw_mclk & 0x7) << 20)
  260 + | ((caslat_ctrl & 0xF) << 16)
  261 + | ((refrec_ctrl & 0xF) << 12)
  262 + | ((wrrec_mclk & 0x07) << 8)
  263 + | ((acttoact_mclk & 0x07) << 4)
  264 + | ((wrtord_mclk & 0x07) << 0)
  265 + );
  266 +}
  267 +
  268 +/* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */
  269 +static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
  270 + const memctl_options_t *popts,
  271 + const common_timing_params_t *common_dimm,
  272 + unsigned int cas_latency,
  273 + unsigned int additive_latency)
  274 +{
  275 + /* Additive latency */
  276 + unsigned char add_lat_mclk;
  277 + /* CAS-to-preamble override */
  278 + unsigned short cpo;
  279 + /* Write latency */
  280 + unsigned char wr_lat;
  281 + /* Read to precharge (tRTP) */
  282 + unsigned char rd_to_pre;
  283 + /* Write command to write data strobe timing adjustment */
  284 + unsigned char wr_data_delay;
  285 + /* Minimum CKE pulse width (tCKE) */
  286 + unsigned char cke_pls;
  287 + /* Window for four activates (tFAW) */
  288 + unsigned short four_act;
  289 +
  290 + /* FIXME add check that this must be less than acttorw_mclk */
  291 + add_lat_mclk = additive_latency;
  292 + cpo = popts->cpo_override;
  293 +
  294 +#if defined(CONFIG_FSL_DDR1)
  295 + /*
  296 + * This is a lie. It should really be 1, but if it is
  297 + * set to 1, bits overlap into the old controller's
  298 + * otherwise unused ACSM field. If we leave it 0, then
  299 + * the HW will magically treat it as 1 for DDR 1. Oh Yea.
  300 + */
  301 + wr_lat = 0;
  302 +#elif defined(CONFIG_FSL_DDR2)
  303 + wr_lat = cas_latency + additive_latency - 1;
  304 +#else
  305 +#error "Fix WR_LAT for DDR3"
  306 +#endif
  307 +
  308 + rd_to_pre = picos_to_mclk(common_dimm->tRTP_ps);
  309 + wr_data_delay = popts->write_data_delay;
  310 + cke_pls = picos_to_mclk(popts->tCKE_clock_pulse_width_ps);
  311 + four_act = picos_to_mclk(popts->tFAW_window_four_activates_ps);
  312 +
  313 + ddr->timing_cfg_2 = (0
  314 + | ((add_lat_mclk & 0x7) << 28)
  315 + | ((cpo & 0x1f) << 23)
  316 + | ((wr_lat & 0x7) << 19)
  317 + | ((rd_to_pre & 0x7) << 13)
  318 + | ((wr_data_delay & 0x7) << 10)
  319 + | ((cke_pls & 0x7) << 6)
  320 + | ((four_act & 0x1f) << 0)
  321 + );
  322 +}
  323 +
  324 +/* DDR SDRAM control configuration (DDR_SDRAM_CFG) */
  325 +static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
  326 + const memctl_options_t *popts,
  327 + const common_timing_params_t *common_dimm)
  328 +{
  329 + unsigned int mem_en; /* DDR SDRAM interface logic enable */
  330 + unsigned int sren; /* Self refresh enable (during sleep) */
  331 + unsigned int ecc_en; /* ECC enable. */
  332 + unsigned int rd_en; /* Registered DIMM enable */
  333 + unsigned int sdram_type; /* Type of SDRAM */
  334 + unsigned int dyn_pwr; /* Dynamic power management mode */
  335 + unsigned int dbw; /* DRAM dta bus width */
  336 + unsigned int eight_be; /* 8-beat burst enable */
  337 + unsigned int ncap = 0; /* Non-concurrent auto-precharge */
  338 + unsigned int threeT_en; /* Enable 3T timing */
  339 + unsigned int twoT_en; /* Enable 2T timing */
  340 + unsigned int ba_intlv_ctl; /* Bank (CS) interleaving control */
  341 + unsigned int x32_en = 0; /* x32 enable */
  342 + unsigned int pchb8 = 0; /* precharge bit 8 enable */
  343 + unsigned int hse; /* Global half strength override */
  344 + unsigned int mem_halt = 0; /* memory controller halt */
  345 + unsigned int bi = 0; /* Bypass initialization */
  346 +
  347 + mem_en = 1;
  348 + sren = popts->self_refresh_in_sleep;
  349 + if (common_dimm->all_DIMMs_ECC_capable) {
  350 + /* Allow setting of ECC only if all DIMMs are ECC. */
  351 + ecc_en = popts->ECC_mode;
  352 + } else {
  353 + ecc_en = 0;
  354 + }
  355 +
  356 + rd_en = (common_dimm->all_DIMMs_registered
  357 + && !common_dimm->all_DIMMs_unbuffered);
  358 +
  359 + sdram_type = CONFIG_FSL_SDRAM_TYPE;
  360 +
  361 + dyn_pwr = popts->dynamic_power;
  362 + dbw = popts->data_bus_width;
  363 + eight_be = 0; /* always 0 for DDR2 */
  364 + threeT_en = popts->threeT_en;
  365 + twoT_en = popts->twoT_en;
  366 + ba_intlv_ctl = popts->ba_intlv_ctl;
  367 + hse = popts->half_strength_driver_enable;
  368 +
  369 + ddr->ddr_sdram_cfg = (0
  370 + | ((mem_en & 0x1) << 31)
  371 + | ((sren & 0x1) << 30)
  372 + | ((ecc_en & 0x1) << 29)
  373 + | ((rd_en & 0x1) << 28)
  374 + | ((sdram_type & 0x7) << 24)
  375 + | ((dyn_pwr & 0x1) << 21)
  376 + | ((dbw & 0x3) << 19)
  377 + | ((eight_be & 0x1) << 18)
  378 + | ((ncap & 0x1) << 17)
  379 + | ((threeT_en & 0x1) << 16)
  380 + | ((twoT_en & 0x1) << 15)
  381 + | ((ba_intlv_ctl & 0x7F) << 8)
  382 + | ((x32_en & 0x1) << 5)
  383 + | ((pchb8 & 0x1) << 4)
  384 + | ((hse & 0x1) << 3)
  385 + | ((mem_halt & 0x1) << 1)
  386 + | ((bi & 0x1) << 0)
  387 + );
  388 +}
  389 +
  390 +/* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */
  391 +static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
  392 + const memctl_options_t *popts)
  393 +{
  394 + unsigned int frc_sr = 0; /* Force self refresh */
  395 + unsigned int sr_ie = 0; /* Self-refresh interrupt enable */
  396 + unsigned int dll_rst_dis; /* DLL reset disable */
  397 + unsigned int dqs_cfg; /* DQS configuration */
  398 + unsigned int odt_cfg; /* ODT configuration */
  399 + unsigned int num_pr; /* Number of posted refreshes */
  400 + unsigned int obc_cfg; /* On-The-Fly Burst Chop Cfg */
  401 + unsigned int ap_en; /* Address Parity Enable */
  402 + unsigned int d_init; /* DRAM data initialization */
  403 + unsigned int rcw_en = 0; /* Register Control Word Enable */
  404 + unsigned int md_en = 0; /* Mirrored DIMM Enable */
  405 +
  406 + dll_rst_dis = 1; /* Make this configurable */
  407 + dqs_cfg = popts->DQS_config;
  408 + if (popts->cs_local_opts[0].odt_rd_cfg
  409 + || popts->cs_local_opts[0].odt_wr_cfg) {
  410 + /* FIXME */
  411 + odt_cfg = 2;
  412 + } else {
  413 + odt_cfg = 0;
  414 + }
  415 +
  416 + num_pr = 1; /* Make this configurable */
  417 +
  418 + /*
  419 + * 8572 manual says
  420 + * {TIMING_CFG_1[PRETOACT]
  421 + * + [DDR_SDRAM_CFG_2[NUM_PR]
  422 + * * ({EXT_REFREC || REFREC} + 8 + 2)]}
  423 + * << DDR_SDRAM_INTERVAL[REFINT]
  424 + */
  425 +
  426 + obc_cfg = 0; /* Make this configurable? */
  427 + ap_en = 0; /* Make this configurable? */
  428 +
  429 +#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
  430 + /* Use the DDR controller to auto initialize memory. */
  431 + d_init = 1;
  432 + ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE;
  433 + debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init);
  434 +#else
  435 + /* Memory will be initialized via DMA, or not at all. */
  436 + d_init = 0;
  437 +#endif
  438 +
  439 + ddr->ddr_sdram_cfg_2 = (0
  440 + | ((frc_sr & 0x1) << 31)
  441 + | ((sr_ie & 0x1) << 30)
  442 + | ((dll_rst_dis & 0x1) << 29)
  443 + | ((dqs_cfg & 0x3) << 26)
  444 + | ((odt_cfg & 0x3) << 21)
  445 + | ((num_pr & 0xf) << 12)
  446 + | ((obc_cfg & 0x1) << 6)
  447 + | ((ap_en & 0x1) << 5)
  448 + | ((d_init & 0x1) << 4)
  449 + | ((rcw_en & 0x1) << 2)
  450 + | ((md_en & 0x1) << 0)
  451 + );
  452 +}
  453 +
  454 +/* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
  455 +static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr)
  456 +{
  457 + unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */
  458 + unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */
  459 +
  460 + ddr->ddr_sdram_mode_2 = (0
  461 + | ((esdmode2 & 0xFFFF) << 16)
  462 + | ((esdmode3 & 0xFFFF) << 0)
  463 + );
  464 +}
  465 +
  466 +/* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */
  467 +static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr,
  468 + const memctl_options_t *popts,
  469 + const common_timing_params_t *common_dimm)
  470 +{
  471 + unsigned int refint; /* Refresh interval */
  472 + unsigned int bstopre; /* Precharge interval */
  473 +
  474 + refint = picos_to_mclk(common_dimm->refresh_rate_ps);
  475 +
  476 + bstopre = popts->bstopre;
  477 +
  478 + /* refint field used 0x3FFF in earlier controllers */
  479 + ddr->ddr_sdram_interval = (0
  480 + | ((refint & 0xFFFF) << 16)
  481 + | ((bstopre & 0x3FFF) << 0)
  482 + );
  483 +}
  484 +
  485 +/* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
  486 +static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
  487 + const memctl_options_t *popts,
  488 + const common_timing_params_t *common_dimm,
  489 + unsigned int cas_latency,
  490 + unsigned int additive_latency)
  491 +{
  492 + unsigned short esdmode; /* Extended SDRAM mode */
  493 + unsigned short sdmode; /* SDRAM mode */
  494 +
  495 + /*
  496 + * FIXME: This ought to be pre-calculated in a
  497 + * technology-specific routine,
  498 + * e.g. compute_DDR2_mode_register(), and then the
  499 + * sdmode and esdmode passed in as part of common_dimm.
  500 + */
  501 +
  502 + /* Extended Mode Register */
  503 + unsigned int mrs = 0; /* Mode Register Set */
  504 + unsigned int outputs = 0; /* 0=Enabled, 1=Disabled */
  505 + unsigned int rdqs_en = 0; /* RDQS Enable: 0=no, 1=yes */
  506 + unsigned int dqs_en = 0; /* DQS# Enable: 0=enable, 1=disable */
  507 + unsigned int ocd = 0; /* 0x0=OCD not supported,
  508 + 0x7=OCD default state */
  509 + unsigned int rtt;
  510 + unsigned int al; /* Posted CAS# additive latency (AL) */
  511 + unsigned int ods = 0; /* Output Drive Strength:
  512 + 0 = Full strength (18ohm)
  513 + 1 = Reduced strength (4ohm) */
  514 + unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal),
  515 + 1=Disable (Test/Debug) */
  516 +
  517 + /* Mode Register (MR) */
  518 + unsigned int mr; /* Mode Register Definition */
  519 + unsigned int pd; /* Power-Down Mode */
  520 + unsigned int wr; /* Write Recovery */
  521 + unsigned int dll_res; /* DLL Reset */
  522 + unsigned int mode; /* Normal=0 or Test=1 */
  523 + unsigned int caslat; /* CAS# latency */
  524 + /* BT: Burst Type (0=Sequential, 1=Interleaved) */
  525 + unsigned int bt;
  526 + unsigned int bl; /* BL: Burst Length */
  527 +
  528 +#if defined(CONFIG_FSL_DDR2)
  529 + const unsigned int mclk_ps = get_memory_clk_period_ps();
  530 +#endif
  531 +
  532 + rtt = fsl_ddr_get_rtt();
  533 +
  534 + al = additive_latency;
  535 +
  536 + esdmode = (0
  537 + | ((mrs & 0x3) << 14)
  538 + | ((outputs & 0x1) << 12)
  539 + | ((rdqs_en & 0x1) << 11)
  540 + | ((dqs_en & 0x1) << 10)
  541 + | ((ocd & 0x7) << 7)
  542 + | ((rtt & 0x2) << 5) /* rtt field is split */
  543 + | ((al & 0x7) << 3)
  544 + | ((rtt & 0x1) << 2) /* rtt field is split */
  545 + | ((ods & 0x1) << 1)
  546 + | ((dll_en & 0x1) << 0)
  547 + );
  548 +
  549 + mr = 0; /* FIXME: CHECKME */
  550 +
  551 + /*
  552 + * 0 = Fast Exit (Normal)
  553 + * 1 = Slow Exit (Low Power)
  554 + */
  555 + pd = 0;
  556 +
  557 +#if defined(CONFIG_FSL_DDR1)
  558 + wr = 0; /* Historical */
  559 +#elif defined(CONFIG_FSL_DDR2)
  560 + wr = (common_dimm->tWR_ps + mclk_ps - 1) / mclk_ps - 1;
  561 +#else
  562 +#error "Write tWR_auto for DDR3"
  563 +#endif
  564 + dll_res = 0;
  565 + mode = 0;
  566 +
  567 +#if defined(CONFIG_FSL_DDR1)
  568 + if (1 <= cas_latency && cas_latency <= 4) {
  569 + unsigned char mode_caslat_table[4] = {
  570 + 0x5, /* 1.5 clocks */
  571 + 0x2, /* 2.0 clocks */
  572 + 0x6, /* 2.5 clocks */
  573 + 0x3 /* 3.0 clocks */
  574 + };
  575 + caslat = mode_caslat_table[cas_latency - 1];
  576 + }
  577 +#elif defined(CONFIG_FSL_DDR2)
  578 + caslat = cas_latency;
  579 +#else
  580 +#error "Fix the mode CAS Latency for DDR3"
  581 +#endif
  582 + bt = 0;
  583 +
  584 + switch (popts->burst_length) {
  585 + case 4:
  586 + bl = 2;
  587 + break;
  588 + case 8:
  589 + bl = 3;
  590 + break;
  591 + default:
  592 + printf("Error: invalid burst length of %u specified. "
  593 + " Defaulting to 4 beats.\n",
  594 + popts->burst_length);
  595 + bl = 2;
  596 + break;
  597 + }
  598 +
  599 + sdmode = (0
  600 + | ((mr & 0x3) << 14)
  601 + | ((pd & 0x1) << 12)
  602 + | ((wr & 0x7) << 9)
  603 + | ((dll_res & 0x1) << 8)
  604 + | ((mode & 0x1) << 7)
  605 + | ((caslat & 0x7) << 4)
  606 + | ((bt & 0x1) << 3)
  607 + | ((bl & 0x7) << 0)
  608 + );
  609 +
  610 + ddr->ddr_sdram_mode = (0
  611 + | ((esdmode & 0xFFFF) << 16)
  612 + | ((sdmode & 0xFFFF) << 0)
  613 + );
  614 +}
  615 +
  616 +
  617 +/* DDR SDRAM Data Initialization (DDR_DATA_INIT) */
  618 +static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr)
  619 +{
  620 + unsigned int init_value; /* Initialization value */
  621 +
  622 + init_value = 0xDEADBEEF;
  623 + ddr->ddr_data_init = init_value;
  624 +}
  625 +
  626 +/*
  627 + * DDR SDRAM Clock Control (DDR_SDRAM_CLK_CNTL)
  628 + * The old controller on the 8540/60 doesn't have this register.
  629 + * Hope it's OK to set it (to 0) anyway.
  630 + */
  631 +static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr,
  632 + const memctl_options_t *popts)
  633 +{
  634 + unsigned int clk_adjust; /* Clock adjust */
  635 +
  636 + clk_adjust = popts->clk_adjust;
  637 + ddr->ddr_sdram_clk_cntl = (clk_adjust & 0xF) << 23;
  638 +}
  639 +
  640 +/* DDR Initialization Address (DDR_INIT_ADDR) */
  641 +static void set_ddr_init_addr(fsl_ddr_cfg_regs_t *ddr)
  642 +{
  643 + unsigned int init_addr = 0; /* Initialization address */
  644 +
  645 + ddr->ddr_init_addr = init_addr;
  646 +}
  647 +
  648 +/* DDR Initialization Address (DDR_INIT_EXT_ADDR) */
  649 +static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr)
  650 +{
  651 + unsigned int uia = 0; /* Use initialization address */
  652 + unsigned int init_ext_addr = 0; /* Initialization address */
  653 +
  654 + ddr->ddr_init_ext_addr = (0
  655 + | ((uia & 0x1) << 31)
  656 + | (init_ext_addr & 0xF)
  657 + );
  658 +}
  659 +
  660 +/* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */
  661 +static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr)
  662 +{
  663 + unsigned int rwt = 0; /* Read-to-write turnaround for same CS */
  664 + unsigned int wrt = 0; /* Write-to-read turnaround for same CS */
  665 + unsigned int rrt = 0; /* Read-to-read turnaround for same CS */
  666 + unsigned int wwt = 0; /* Write-to-write turnaround for same CS */
  667 + unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */
  668 +
  669 + ddr->timing_cfg_4 = (0
  670 + | ((rwt & 0xf) << 28)
  671 + | ((wrt & 0xf) << 24)
  672 + | ((rrt & 0xf) << 20)
  673 + | ((wwt & 0xf) << 16)
  674 + | (dll_lock & 0x3)
  675 + );
  676 +}
  677 +
  678 +/* DDR SDRAM Timing Configuration 5 (TIMING_CFG_5) */
  679 +static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr)
  680 +{
  681 + unsigned int rodt_on = 0; /* Read to ODT on */
  682 + unsigned int rodt_off = 0; /* Read to ODT off */
  683 + unsigned int wodt_on = 0; /* Write to ODT on */
  684 + unsigned int wodt_off = 0; /* Write to ODT off */
  685 +
  686 + ddr->timing_cfg_5 = (0
  687 + | ((rodt_on & 0xf) << 24)
  688 + | ((rodt_off & 0xf) << 20)
  689 + | ((wodt_on & 0xf) << 12)
  690 + | ((wodt_off & 0xf) << 8)
  691 + );
  692 +}
  693 +
  694 +/* DDR ZQ Calibration Control (DDR_ZQ_CNTL) */
  695 +static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr)
  696 +{
  697 + unsigned int zq_en = 0; /* ZQ Calibration Enable */
  698 + unsigned int zqinit = 0;/* POR ZQ Calibration Time (tZQinit) */
  699 + /* Normal Operation Full Calibration Time (tZQoper) */
  700 + unsigned int zqoper = 0;
  701 + /* Normal Operation Short Calibration Time (tZQCS) */
  702 + unsigned int zqcs = 0;
  703 +
  704 + ddr->ddr_zq_cntl = (0
  705 + | ((zq_en & 0x1) << 31)
  706 + | ((zqinit & 0xF) << 24)
  707 + | ((zqoper & 0xF) << 16)
  708 + | ((zqcs & 0xF) << 8)
  709 + );
  710 +}
  711 +
  712 +/* DDR Write Leveling Control (DDR_WRLVL_CNTL) */
  713 +static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr)
  714 +{
  715 + unsigned int wrlvl_en = 0; /* Write Leveling Enable */
  716 + /*
  717 + * First DQS pulse rising edge after margining mode
  718 + * is programmed (tWL_MRD)
  719 + */
  720 + unsigned int wrlvl_mrd = 0;
  721 + /* ODT delay after margining mode is programmed (tWL_ODTEN) */
  722 + unsigned int wrlvl_odten = 0;
  723 + /* DQS/DQS_ delay after margining mode is programmed (tWL_DQSEN) */
  724 + unsigned int wrlvl_dqsen = 0;
  725 + /* WRLVL_SMPL: Write leveling sample time */
  726 + unsigned int wrlvl_smpl = 0;
  727 + /* WRLVL_WLR: Write leveling repeition time */
  728 + unsigned int wrlvl_wlr = 0;
  729 + /* WRLVL_START: Write leveling start time */
  730 + unsigned int wrlvl_start = 0;
  731 +
  732 + ddr->ddr_wrlvl_cntl = (0
  733 + | ((wrlvl_en & 0x1) << 31)
  734 + | ((wrlvl_mrd & 0x7) << 24)
  735 + | ((wrlvl_odten & 0x7) << 20)
  736 + | ((wrlvl_dqsen & 0x7) << 16)
  737 + | ((wrlvl_smpl & 0xf) << 12)
  738 + | ((wrlvl_wlr & 0x7) << 8)
  739 + | ((wrlvl_start & 0xF) << 0)
  740 + );
  741 +}
  742 +
  743 +/* DDR Self Refresh Counter (DDR_SR_CNTR) */
  744 +static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr)
  745 +{
  746 + unsigned int sr_it = 0; /* Self Refresh Idle Threshold */
  747 +
  748 + ddr->ddr_sr_cntr = (sr_it & 0xF) << 16;
  749 +}
  750 +
  751 +/* DDR Pre-Drive Conditioning Control (DDR_PD_CNTL) */
  752 +static void set_ddr_pd_cntl(fsl_ddr_cfg_regs_t *ddr)
  753 +{
  754 + /* Termination value during pre-drive conditioning */
  755 + unsigned int tvpd = 0;
  756 + unsigned int pd_en = 0; /* Pre-Drive Conditioning Enable */
  757 + unsigned int pdar = 0; /* Pre-Drive After Read */
  758 + unsigned int pdaw = 0; /* Pre-Drive After Write */
  759 + unsigned int pd_on = 0; /* Pre-Drive Conditioning On */
  760 + unsigned int pd_off = 0; /* Pre-Drive Conditioning Off */
  761 +
  762 + ddr->ddr_pd_cntl = (0
  763 + | ((pd_en & 0x1) << 31)
  764 + | ((tvpd & 0x7) << 28)
  765 + | ((pdar & 0x7F) << 20)
  766 + | ((pdaw & 0x7F) << 12)
  767 + | ((pd_on & 0x1F) << 6)
  768 + | ((pd_off & 0x1F) << 0)
  769 + );
  770 +}
  771 +
  772 +
  773 +/* DDR SDRAM Register Control Word 1 (DDR_SDRAM_RCW_1) */
  774 +static void set_ddr_sdram_rcw_1(fsl_ddr_cfg_regs_t *ddr)
  775 +{
  776 + unsigned int rcw0 = 0; /* RCW0: Register Control Word 0 */
  777 + unsigned int rcw1 = 0; /* RCW1: Register Control Word 1 */
  778 + unsigned int rcw2 = 0; /* RCW2: Register Control Word 2 */
  779 + unsigned int rcw3 = 0; /* RCW3: Register Control Word 3 */
  780 + unsigned int rcw4 = 0; /* RCW4: Register Control Word 4 */
  781 + unsigned int rcw5 = 0; /* RCW5: Register Control Word 5 */
  782 + unsigned int rcw6 = 0; /* RCW6: Register Control Word 6 */
  783 + unsigned int rcw7 = 0; /* RCW7: Register Control Word 7 */
  784 +
  785 + ddr->ddr_sdram_rcw_1 = (0
  786 + | ((rcw0 & 0xF) << 28)
  787 + | ((rcw1 & 0xF) << 24)
  788 + | ((rcw2 & 0xF) << 20)
  789 + | ((rcw3 & 0xF) << 16)
  790 + | ((rcw4 & 0xF) << 12)
  791 + | ((rcw5 & 0xF) << 8)
  792 + | ((rcw6 & 0xF) << 4)
  793 + | ((rcw7 & 0xF) << 0)
  794 + );
  795 +}
  796 +
  797 +/* DDR SDRAM Register Control Word 2 (DDR_SDRAM_RCW_2) */
  798 +static void set_ddr_sdram_rcw_2(fsl_ddr_cfg_regs_t *ddr)
  799 +{
  800 + unsigned int rcw8 = 0; /* RCW0: Register Control Word 8 */
  801 + unsigned int rcw9 = 0; /* RCW1: Register Control Word 9 */
  802 + unsigned int rcw10 = 0; /* RCW2: Register Control Word 10 */
  803 + unsigned int rcw11 = 0; /* RCW3: Register Control Word 11 */
  804 + unsigned int rcw12 = 0; /* RCW4: Register Control Word 12 */
  805 + unsigned int rcw13 = 0; /* RCW5: Register Control Word 13 */
  806 + unsigned int rcw14 = 0; /* RCW6: Register Control Word 14 */
  807 + unsigned int rcw15 = 0; /* RCW7: Register Control Word 15 */
  808 +
  809 + ddr->ddr_sdram_rcw_2 = (0
  810 + | ((rcw8 & 0xF) << 28)
  811 + | ((rcw9 & 0xF) << 24)
  812 + | ((rcw10 & 0xF) << 20)
  813 + | ((rcw11 & 0xF) << 16)
  814 + | ((rcw12 & 0xF) << 12)
  815 + | ((rcw13 & 0xF) << 8)
  816 + | ((rcw14 & 0xF) << 4)
  817 + | ((rcw15 & 0xF) << 0)
  818 + );
  819 +}
  820 +
  821 +unsigned int
  822 +check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
  823 +{
  824 + unsigned int res = 0;
  825 +
  826 + /*
  827 + * Check that DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] are
  828 + * not set at the same time.
  829 + */
  830 + if (ddr->ddr_sdram_cfg & 0x10000000
  831 + && ddr->ddr_sdram_cfg & 0x00008000) {
  832 + printf("Error: DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] "
  833 + " should not be set at the same time.\n");
  834 + res++;
  835 + }
  836 +
  837 + return res;
  838 +}
  839 +
  840 +unsigned int
  841 +compute_fsl_memctl_config_regs(const memctl_options_t *popts,
  842 + fsl_ddr_cfg_regs_t *ddr,
  843 + const common_timing_params_t *common_dimm,
  844 + const dimm_params_t *dimm_params,
  845 + unsigned int dbw_cap_adj)
  846 +{
  847 + unsigned int i;
  848 + unsigned int cas_latency;
  849 + unsigned int additive_latency;
  850 +
  851 + memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t));
  852 +
  853 + if (common_dimm == NULL) {
  854 + printf("Error: subset DIMM params struct null pointer\n");
  855 + return 1;
  856 + }
  857 +
  858 + /*
  859 + * Process overrides first.
  860 + *
  861 + * FIXME: somehow add dereated caslat to this
  862 + */
  863 + cas_latency = (popts->cas_latency_override)
  864 + ? popts->cas_latency_override_value
  865 + : common_dimm->lowest_common_SPD_caslat;
  866 +
  867 + additive_latency = (popts->additive_latency_override)
  868 + ? popts->additive_latency_override_value
  869 + : common_dimm->additive_latency;
  870 +
  871 + /* Chip Select Memory Bounds (CSn_BNDS) */
  872 + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
  873 + phys_size_t sa = 0;
  874 + phys_size_t ea = 0;
  875 + if (popts->ba_intlv_ctl && i > 0) {
  876 + /* Don't set up boundaries if bank interleaving */
  877 + break;
  878 + }
  879 +
  880 + if (dimm_params[i/2].n_ranks == 0) {
  881 + debug("Skipping setup of CS%u "
  882 + "because n_ranks on DIMM %u is 0\n", i, i/2);
  883 + continue;
  884 + }
  885 + if (popts->memctl_interleaving && popts->ba_intlv_ctl) {
  886 + /*
  887 + * This works superbank 2CS
  888 + * There are 2 memory controllers configured
  889 + * identically, memory is interleaved between them,
  890 + * and each controller uses rank interleaving within
  891 + * itself. Therefore the starting and ending address
  892 + * on each controller is twice the amount present on
  893 + * each controller.
  894 + */
  895 + ea = (2 * common_dimm->total_mem >> dbw_cap_adj) - 1;
  896 + }
  897 + else if (!popts->memctl_interleaving && popts->ba_intlv_ctl) {
  898 + /*
  899 + * If memory interleaving between controllers is NOT
  900 + * enabled, the starting address for each memory
  901 + * controller is distinct. However, because rank
  902 + * interleaving is enabled, the starting and ending
  903 + * addresses of the total memory on that memory
  904 + * controller needs to be programmed into its
  905 + * respective CS0_BNDS.
  906 + */
  907 + sa = common_dimm->base_address;
  908 + ea = sa + (common_dimm->total_mem >> dbw_cap_adj) - 1;
  909 + }
  910 + else if (popts->memctl_interleaving && !popts->ba_intlv_ctl) {
  911 + /*
  912 + * Only the rank on CS0 of each memory controller may
  913 + * be used if memory controller interleaving is used
  914 + * without rank interleaving within each memory
  915 + * controller. However, the ending address programmed
  916 + * into each CS0 must be the sum of the amount of
  917 + * memory in the two CS0 ranks.
  918 + */
  919 + if (i == 0) {
  920 + unsigned long long rank_density
  921 + = dimm_params[0].rank_density;
  922 + ea = (2 * (rank_density >> dbw_cap_adj)) - 1;
  923 + }
  924 +
  925 + }
  926 + else if (!popts->memctl_interleaving && !popts->ba_intlv_ctl) {
  927 + /*
  928 + * No rank interleaving and no memory controller
  929 + * interleaving.
  930 + */
  931 + unsigned long long rank_density
  932 + = dimm_params[i/2].rank_density;
  933 + sa = dimm_params[i/2].base_address;
  934 + ea = sa + (rank_density >> dbw_cap_adj) - 1;
  935 + if (i&1) {
  936 + if ((dimm_params[i/2].n_ranks == 1)) {
  937 + /* Odd chip select, single-rank dimm */
  938 + sa = 0;
  939 + ea = 0;
  940 + } else {
  941 + /* Odd chip select, dual-rank DIMM */
  942 + sa += rank_density >> dbw_cap_adj;
  943 + ea += rank_density >> dbw_cap_adj;
  944 + }
  945 + }
  946 + }
  947 +
  948 + sa >>= 24;
  949 + ea >>= 24;
  950 +
  951 + ddr->cs[i].bnds = (0
  952 + | ((sa & 0xFFF) << 16) /* starting address MSB */
  953 + | ((ea & 0xFFF) << 0) /* ending address MSB */
  954 + );
  955 +
  956 + set_csn_config(i, ddr, popts, dimm_params);
  957 + set_csn_config_2(i, ddr);
  958 + }
  959 +
  960 +#if defined(CONFIG_FSL_DDR2)
  961 + set_timing_cfg_0(ddr);
  962 +#endif
  963 +
  964 + set_timing_cfg_3(ddr, common_dimm);
  965 + set_timing_cfg_1(ddr, common_dimm, cas_latency);
  966 + set_timing_cfg_2(ddr, popts, common_dimm,
  967 + cas_latency, additive_latency);
  968 +
  969 + set_ddr_sdram_cfg(ddr, popts, common_dimm);
  970 +
  971 + set_ddr_sdram_cfg_2(ddr, popts);
  972 + set_ddr_sdram_mode(ddr, popts, common_dimm,
  973 + cas_latency, additive_latency);
  974 + set_ddr_sdram_mode_2(ddr);
  975 + set_ddr_sdram_interval(ddr, popts, common_dimm);
  976 + set_ddr_data_init(ddr);
  977 + set_ddr_sdram_clk_cntl(ddr, popts);
  978 + set_ddr_init_addr(ddr);
  979 + set_ddr_init_ext_addr(ddr);
  980 + set_timing_cfg_4(ddr);
  981 + set_timing_cfg_5(ddr);
  982 +
  983 + set_ddr_zq_cntl(ddr);
  984 + set_ddr_wrlvl_cntl(ddr);
  985 +
  986 + set_ddr_pd_cntl(ddr);
  987 + set_ddr_sr_cntr(ddr);
  988 +
  989 + set_ddr_sdram_rcw_1(ddr);
  990 + set_ddr_sdram_rcw_2(ddr);
  991 +
  992 + return check_fsl_memctl_config_regs(ddr);
  993 +}
cpu/mpc8xxx/ddr/ddr.h
  1 +/*
  2 + * Copyright 2008 Freescale Semiconductor, Inc.
  3 + *
  4 + * This program is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU General Public License
  6 + * Version 2 as published by the Free Software Foundation.
  7 + */
  8 +
  9 +#ifndef FSL_DDR_MAIN_H
  10 +#define FSL_DDR_MAIN_H
  11 +
  12 +#include <asm/fsl_ddr_sdram.h>
  13 +
  14 +#include "ddr1_2_dimm_params.h"
  15 +#include "common_timing_params.h"
  16 +
  17 +/*
  18 + * Bind the main DDR setup driver's generic names
  19 + * to this specific DDR technology.
  20 + */
  21 +static __inline__ int
  22 +compute_dimm_parameters(const generic_spd_eeprom_t *spd,
  23 + dimm_params_t *pdimm,
  24 + unsigned int dimm_number)
  25 +{
  26 + return ddr_compute_dimm_parameters(spd, pdimm, dimm_number);
  27 +}
  28 +
  29 +/*
  30 + * Data Structures
  31 + *
  32 + * All data structures have to be on the stack
  33 + */
  34 +#define CFG_NUM_DDR_CTLRS CONFIG_NUM_DDR_CONTROLLERS
  35 +#define CFG_DIMM_SLOTS_PER_CTLR CONFIG_DIMM_SLOTS_PER_CTLR
  36 +
  37 +typedef struct {
  38 + generic_spd_eeprom_t
  39 + spd_installed_dimms[CFG_NUM_DDR_CTLRS][CFG_DIMM_SLOTS_PER_CTLR];
  40 + struct dimm_params_s
  41 + dimm_params[CFG_NUM_DDR_CTLRS][CFG_DIMM_SLOTS_PER_CTLR];
  42 + memctl_options_t memctl_opts[CFG_NUM_DDR_CTLRS];
  43 + common_timing_params_t common_timing_params[CFG_NUM_DDR_CTLRS];
  44 + fsl_ddr_cfg_regs_t fsl_ddr_config_reg[CFG_NUM_DDR_CTLRS];
  45 +} fsl_ddr_info_t;
  46 +
  47 +/* Compute steps */
  48 +#define STEP_GET_SPD (1 << 0)
  49 +#define STEP_COMPUTE_DIMM_PARMS (1 << 1)
  50 +#define STEP_COMPUTE_COMMON_PARMS (1 << 2)
  51 +#define STEP_GATHER_OPTS (1 << 3)
  52 +#define STEP_ASSIGN_ADDRESSES (1 << 4)
  53 +#define STEP_COMPUTE_REGS (1 << 5)
  54 +#define STEP_PROGRAM_REGS (1 << 6)
  55 +#define STEP_ALL 0xFFF
  56 +
  57 +extern phys_size_t
  58 +fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step);
  59 +
  60 +extern const char * step_to_string(unsigned int step);
  61 +
  62 +extern unsigned int
  63 +compute_fsl_memctl_config_regs(const memctl_options_t *popts,
  64 + fsl_ddr_cfg_regs_t *ddr,
  65 + const common_timing_params_t *common_dimm,
  66 + const dimm_params_t *dimm_parameters,
  67 + unsigned int dbw_capacity_adjust);
  68 +extern unsigned int
  69 +compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
  70 + common_timing_params_t *outpdimm,
  71 + unsigned int number_of_dimms);
  72 +extern unsigned int populate_memctl_options(int all_DIMMs_registered,
  73 + memctl_options_t *popts,
  74 + unsigned int ctrl_num);
  75 +
  76 +extern unsigned int mclk_to_picos(unsigned int mclk);
  77 +extern unsigned int get_memory_clk_period_ps(void);
  78 +extern unsigned int picos_to_mclk(unsigned int picos);
  79 +
  80 +#endif
cpu/mpc8xxx/ddr/ddr1_2_dimm_params.h
  1 +/*
  2 + * Copyright 2008 Freescale Semiconductor, Inc.
  3 + *
  4 + * This program is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU General Public License
  6 + * Version 2 as published by the Free Software Foundation.
  7 + */
  8 +
  9 +#ifndef DDR2_DIMM_PARAMS_H
  10 +#define DDR2_DIMM_PARAMS_H
  11 +
  12 +/* Parameters for a DDR2 dimm computed from the SPD */
  13 +typedef struct dimm_params_s {
  14 +
  15 + /* DIMM organization parameters */
  16 + char mpart[19]; /* guaranteed null terminated */
  17 +
  18 + unsigned int n_ranks;
  19 + unsigned long long rank_density;
  20 + unsigned long long capacity;
  21 + unsigned int data_width;
  22 + unsigned int primary_sdram_width;
  23 + unsigned int ec_sdram_width;
  24 + unsigned int registered_dimm;
  25 +
  26 + /* SDRAM device parameters */
  27 + unsigned int n_row_addr;
  28 + unsigned int n_col_addr;
  29 + unsigned int edc_config; /* 0 = none, 1 = parity, 2 = ECC */
  30 + unsigned int n_banks_per_sdram_device;
  31 + unsigned int burst_lengths_bitmask; /* BL=4 bit 2, BL=8 = bit 3 */
  32 + unsigned int row_density;
  33 +
  34 + /* used in computing base address of DIMMs */
  35 + unsigned long long base_address;
  36 +
  37 + /* DIMM timing parameters */
  38 +
  39 + /*
  40 + * SDRAM clock periods
  41 + * The range for these are 1000-10000 so a short should be sufficient
  42 + */
  43 + unsigned int tCKmin_X_ps;
  44 + unsigned int tCKmin_X_minus_1_ps;
  45 + unsigned int tCKmin_X_minus_2_ps;
  46 + unsigned int tCKmax_ps;
  47 +
  48 + /* SPD-defined CAS latencies */
  49 + unsigned int caslat_X;
  50 + unsigned int caslat_X_minus_1;
  51 + unsigned int caslat_X_minus_2;
  52 +
  53 + unsigned int caslat_lowest_derated; /* Derated CAS latency */
  54 +
  55 + /* basic timing parameters */
  56 + unsigned int tRCD_ps;
  57 + unsigned int tRP_ps;
  58 + unsigned int tRAS_ps;
  59 +
  60 + unsigned int tWR_ps; /* maximum = 63750 ps */
  61 + unsigned int tWTR_ps; /* maximum = 63750 ps */
  62 + unsigned int tRFC_ps; /* max = 255 ns + 256 ns + .75 ns
  63 + = 511750 ps */
  64 +
  65 + unsigned int tRRD_ps; /* maximum = 63750 ps */
  66 + unsigned int tRC_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
  67 +
  68 + unsigned int refresh_rate_ps;
  69 +
  70 + unsigned int tIS_ps; /* byte 32, spd->ca_setup */
  71 + unsigned int tIH_ps; /* byte 33, spd->ca_hold */
  72 + unsigned int tDS_ps; /* byte 34, spd->data_setup */
  73 + unsigned int tDH_ps; /* byte 35, spd->data_hold */
  74 + unsigned int tRTP_ps; /* byte 38, spd->trtp */
  75 + unsigned int tDQSQ_max_ps; /* byte 44, spd->tdqsq */
  76 + unsigned int tQHS_ps; /* byte 45, spd->tqhs */
  77 +} dimm_params_t;
  78 +
  79 +extern unsigned int ddr_compute_dimm_parameters(
  80 + const generic_spd_eeprom_t *spd,
  81 + dimm_params_t *pdimm,
  82 + unsigned int dimm_number);
  83 +
  84 +#endif
cpu/mpc8xxx/ddr/lc_common_dimm_params.c
  1 +/*
  2 + * Copyright 2008 Freescale Semiconductor, Inc.
  3 + *
  4 + * This program is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU General Public License
  6 + * Version 2 as published by the Free Software Foundation.
  7 + */
  8 +
  9 +#include <common.h>
  10 +#include <asm/fsl_ddr_sdram.h>
  11 +
  12 +#include "ddr.h"
  13 +
  14 +/*
  15 + * compute_lowest_common_dimm_parameters()
  16 + *
  17 + * Determine the worst-case DIMM timing parameters from the set of DIMMs
  18 + * whose parameters have been computed into the array pointed to
  19 + * by dimm_params.
  20 + */
  21 +unsigned int
  22 +compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
  23 + common_timing_params_t *outpdimm,
  24 + unsigned int number_of_dimms)
  25 +{
  26 + unsigned int i;
  27 +
  28 + unsigned int tCKmin_X_ps = 0;
  29 + unsigned int tCKmax_ps = 0xFFFFFFFF;
  30 + unsigned int tCKmax_max_ps = 0;
  31 + unsigned int tRCD_ps = 0;
  32 + unsigned int tRP_ps = 0;
  33 + unsigned int tRAS_ps = 0;
  34 + unsigned int tWR_ps = 0;
  35 + unsigned int tWTR_ps = 0;
  36 + unsigned int tRFC_ps = 0;
  37 + unsigned int tRRD_ps = 0;
  38 + unsigned int tRC_ps = 0;
  39 + unsigned int refresh_rate_ps = 0;
  40 + unsigned int tIS_ps = 0;
  41 + unsigned int tIH_ps = 0;
  42 + unsigned int tDS_ps = 0;
  43 + unsigned int tDH_ps = 0;
  44 + unsigned int tRTP_ps = 0;
  45 + unsigned int tDQSQ_max_ps = 0;
  46 + unsigned int tQHS_ps = 0;
  47 +
  48 + unsigned int temp1, temp2;
  49 + unsigned int lowest_good_caslat;
  50 + unsigned int additive_latency = 0;
  51 + const unsigned int mclk_ps = get_memory_clk_period_ps();
  52 + unsigned int not_ok;
  53 +
  54 + debug("using mclk_ps = %u\n", mclk_ps);
  55 +
  56 + temp1 = 0;
  57 + for (i = 0; i < number_of_dimms; i++) {
  58 + /*
  59 + * If there are no ranks on this DIMM,
  60 + * it probably doesn't exist, so skip it.
  61 + */
  62 + if (dimm_params[i].n_ranks == 0) {
  63 + temp1++;
  64 + continue;
  65 + }
  66 +
  67 + /*
  68 + * Find minimum tCKmax_ps to find fastest slow speed,
  69 + * i.e., this is the slowest the whole system can go.
  70 + */
  71 + tCKmax_ps = min(tCKmax_ps, dimm_params[i].tCKmax_ps);
  72 +
  73 + /* Either find maximum value to determine slowest
  74 + * speed, delay, time, period, etc */
  75 + tCKmin_X_ps = max(tCKmin_X_ps, dimm_params[i].tCKmin_X_ps);
  76 + tCKmax_max_ps = max(tCKmax_max_ps, dimm_params[i].tCKmax_ps);
  77 + tRCD_ps = max(tRCD_ps, dimm_params[i].tRCD_ps);
  78 + tRP_ps = max(tRP_ps, dimm_params[i].tRP_ps);
  79 + tRAS_ps = max(tRAS_ps, dimm_params[i].tRAS_ps);
  80 + tWR_ps = max(tWR_ps, dimm_params[i].tWR_ps);
  81 + tWTR_ps = max(tWTR_ps, dimm_params[i].tWTR_ps);
  82 + tRFC_ps = max(tRFC_ps, dimm_params[i].tRFC_ps);
  83 + tRRD_ps = max(tRRD_ps, dimm_params[i].tRRD_ps);
  84 + tRC_ps = max(tRC_ps, dimm_params[i].tRC_ps);
  85 + tIS_ps = max(tIS_ps, dimm_params[i].tIS_ps);
  86 + tIH_ps = max(tIH_ps, dimm_params[i].tIH_ps);
  87 + tDS_ps = max(tDS_ps, dimm_params[i].tDS_ps);
  88 + tDH_ps = max(tDH_ps, dimm_params[i].tDH_ps);
  89 + tRTP_ps = max(tRTP_ps, dimm_params[i].tRTP_ps);
  90 + tQHS_ps = max(tQHS_ps, dimm_params[i].tQHS_ps);
  91 + refresh_rate_ps = max(refresh_rate_ps,
  92 + dimm_params[i].refresh_rate_ps);
  93 +
  94 + /*
  95 + * Find maximum tDQSQ_max_ps to find slowest.
  96 + *
  97 + * FIXME: is finding the slowest value the correct
  98 + * strategy for this parameter?
  99 + */
  100 + tDQSQ_max_ps = max(tDQSQ_max_ps, dimm_params[i].tDQSQ_max_ps);
  101 + }
  102 +
  103 + outpdimm->ndimms_present = number_of_dimms - temp1;
  104 +
  105 + if (temp1 == number_of_dimms) {
  106 + debug("no dimms this memory controller\n");
  107 + return 0;
  108 + }
  109 +
  110 + outpdimm->tCKmin_X_ps = tCKmin_X_ps;
  111 + outpdimm->tCKmax_ps = tCKmax_ps;
  112 + outpdimm->tCKmax_max_ps = tCKmax_max_ps;
  113 + outpdimm->tRCD_ps = tRCD_ps;
  114 + outpdimm->tRP_ps = tRP_ps;
  115 + outpdimm->tRAS_ps = tRAS_ps;
  116 + outpdimm->tWR_ps = tWR_ps;
  117 + outpdimm->tWTR_ps = tWTR_ps;
  118 + outpdimm->tRFC_ps = tRFC_ps;
  119 + outpdimm->tRRD_ps = tRRD_ps;
  120 + outpdimm->tRC_ps = tRC_ps;
  121 + outpdimm->refresh_rate_ps = refresh_rate_ps;
  122 + outpdimm->tIS_ps = tIS_ps;
  123 + outpdimm->tIH_ps = tIH_ps;
  124 + outpdimm->tDS_ps = tDS_ps;
  125 + outpdimm->tDH_ps = tDH_ps;
  126 + outpdimm->tRTP_ps = tRTP_ps;
  127 + outpdimm->tDQSQ_max_ps = tDQSQ_max_ps;
  128 + outpdimm->tQHS_ps = tQHS_ps;
  129 +
  130 + /* Determine common burst length for all DIMMs. */
  131 + temp1 = 0xff;
  132 + for (i = 0; i < number_of_dimms; i++) {
  133 + if (dimm_params[i].n_ranks) {
  134 + temp1 &= dimm_params[i].burst_lengths_bitmask;
  135 + }
  136 + }
  137 + outpdimm->all_DIMMs_burst_lengths_bitmask = temp1;
  138 +
  139 + /* Determine if all DIMMs registered buffered. */
  140 + temp1 = temp2 = 0;
  141 + for (i = 0; i < number_of_dimms; i++) {
  142 + if (dimm_params[i].n_ranks) {
  143 + if (dimm_params[i].registered_dimm)
  144 + temp1 = 1;
  145 + if (!dimm_params[i].registered_dimm)
  146 + temp2 = 1;
  147 + }
  148 + }
  149 +
  150 + outpdimm->all_DIMMs_registered = 0;
  151 + if (temp1 && !temp2) {
  152 + outpdimm->all_DIMMs_registered = 1;
  153 + }
  154 +
  155 + outpdimm->all_DIMMs_unbuffered = 0;
  156 + if (!temp1 && temp2) {
  157 + outpdimm->all_DIMMs_unbuffered = 1;
  158 + }
  159 +
  160 + /* CHECKME: */
  161 + if (!outpdimm->all_DIMMs_registered
  162 + && !outpdimm->all_DIMMs_unbuffered) {
  163 + printf("ERROR: Mix of registered buffered and unbuffered "
  164 + "DIMMs detected!\n");
  165 + }
  166 +
  167 + /*
  168 + * Compute a CAS latency suitable for all DIMMs
  169 + *
  170 + * Strategy for SPD-defined latencies: compute only
  171 + * CAS latency defined by all DIMMs.
  172 + */
  173 +
  174 + /*
  175 + * Step 1: find CAS latency common to all DIMMs using bitwise
  176 + * operation.
  177 + */
  178 + temp1 = 0xFF;
  179 + for (i = 0; i < number_of_dimms; i++) {
  180 + if (dimm_params[i].n_ranks) {
  181 + temp2 = 0;
  182 + temp2 |= 1 << dimm_params[i].caslat_X;
  183 + temp2 |= 1 << dimm_params[i].caslat_X_minus_1;
  184 + temp2 |= 1 << dimm_params[i].caslat_X_minus_2;
  185 + /*
  186 + * FIXME: If there was no entry for X-2 (X-1) in
  187 + * the SPD, then caslat_X_minus_2
  188 + * (caslat_X_minus_1) contains either 255 or
  189 + * 0xFFFFFFFF because that's what the glorious
  190 + * __ilog2 function returns for an input of 0.
  191 + * On 32-bit PowerPC, left shift counts with bit
  192 + * 26 set (that the value of 255 or 0xFFFFFFFF
  193 + * will have), cause the destination register to
  194 + * be 0. That is why this works.
  195 + */
  196 + temp1 &= temp2;
  197 + }
  198 + }
  199 +
  200 + /*
  201 + * Step 2: check each common CAS latency against tCK of each
  202 + * DIMM's SPD.
  203 + */
  204 + lowest_good_caslat = 0;
  205 + temp2 = 0;
  206 + while (temp1) {
  207 + not_ok = 0;
  208 + temp2 = __ilog2(temp1);
  209 + debug("checking common caslat = %u\n", temp2);
  210 +
  211 + /* Check if this CAS latency will work on all DIMMs at tCK. */
  212 + for (i = 0; i < number_of_dimms; i++) {
  213 + if (!dimm_params[i].n_ranks) {
  214 + continue;
  215 + }
  216 + if (dimm_params[i].caslat_X == temp2) {
  217 + if (mclk_ps >= dimm_params[i].tCKmin_X_ps) {
  218 + debug("CL = %u ok on DIMM %u at tCK=%u"
  219 + " ps with its tCKmin_X_ps of %u\n",
  220 + temp2, i, mclk_ps,
  221 + dimm_params[i].tCKmin_X_ps);
  222 + continue;
  223 + } else {
  224 + not_ok++;
  225 + }
  226 + }
  227 +
  228 + if (dimm_params[i].caslat_X_minus_1 == temp2) {
  229 + unsigned int tCKmin_X_minus_1_ps
  230 + = dimm_params[i].tCKmin_X_minus_1_ps;
  231 + if (mclk_ps >= tCKmin_X_minus_1_ps) {
  232 + debug("CL = %u ok on DIMM %u at "
  233 + "tCK=%u ps with its "
  234 + "tCKmin_X_minus_1_ps of %u\n",
  235 + temp2, i, mclk_ps,
  236 + tCKmin_X_minus_1_ps);
  237 + continue;
  238 + } else {
  239 + not_ok++;
  240 + }
  241 + }
  242 +
  243 + if (dimm_params[i].caslat_X_minus_2 == temp2) {
  244 + unsigned int tCKmin_X_minus_2_ps
  245 + = dimm_params[i].tCKmin_X_minus_2_ps;
  246 + if (mclk_ps >= tCKmin_X_minus_2_ps) {
  247 + debug("CL = %u ok on DIMM %u at "
  248 + "tCK=%u ps with its "
  249 + "tCKmin_X_minus_2_ps of %u\n",
  250 + temp2, i, mclk_ps,
  251 + tCKmin_X_minus_2_ps);
  252 + continue;
  253 + } else {
  254 + not_ok++;
  255 + }
  256 + }
  257 + }
  258 +
  259 + if (!not_ok) {
  260 + lowest_good_caslat = temp2;
  261 + }
  262 +
  263 + temp1 &= ~(1 << temp2);
  264 + }
  265 +
  266 + debug("lowest common SPD-defined CAS latency = %u\n",
  267 + lowest_good_caslat);
  268 + outpdimm->lowest_common_SPD_caslat = lowest_good_caslat;
  269 +
  270 +
  271 + /*
  272 + * Compute a common 'de-rated' CAS latency.
  273 + *
  274 + * The strategy here is to find the *highest* dereated cas latency
  275 + * with the assumption that all of the DIMMs will support a dereated
  276 + * CAS latency higher than or equal to their lowest dereated value.
  277 + */
  278 + temp1 = 0;
  279 + for (i = 0; i < number_of_dimms; i++) {
  280 + temp1 = max(temp1, dimm_params[i].caslat_lowest_derated);
  281 + }
  282 + outpdimm->highest_common_derated_caslat = temp1;
  283 + debug("highest common dereated CAS latency = %u\n", temp1);
  284 +
  285 + /* Determine if all DIMMs ECC capable. */
  286 + temp1 = 1;
  287 + for (i = 0; i < number_of_dimms; i++) {
  288 + if (dimm_params[i].n_ranks && dimm_params[i].edc_config != 2) {
  289 + temp1 = 0;
  290 + break;
  291 + }
  292 + }
  293 + if (temp1) {
  294 + debug("all DIMMs ECC capable\n");
  295 + } else {
  296 + debug("Warning: not all DIMMs ECC capable, cant enable ECC\n");
  297 + }
  298 + outpdimm->all_DIMMs_ECC_capable = temp1;
  299 +
  300 +
  301 + /* FIXME: move to somewhere else to validate. */
  302 + if (mclk_ps > tCKmax_max_ps) {
  303 + printf("Warning: some of the installed DIMMs "
  304 + "can not operate this slowly.\n");
  305 + return 1;
  306 + }
  307 +
  308 + /*
  309 + * Compute additive latency.
  310 + *
  311 + * For DDR1, additive latency should be 0.
  312 + *
  313 + * For DDR2, with ODT enabled, use "a value" less than ACTTORW,
  314 + * which comes from Trcd, and also note that:
  315 + * add_lat + caslat must be >= 4
  316 + *
  317 + * For DDR3, FIXME additive latency determination
  318 + *
  319 + * When to use additive latency for DDR2:
  320 + *
  321 + * I. Because you are using CL=3 and need to do ODT on writes and
  322 + * want functionality.
  323 + * 1. Are you going to use ODT? (Does your board not have
  324 + * additional termination circuitry for DQ, DQS, DQS_,
  325 + * DM, RDQS, RDQS_ for x4/x8 configs?)
  326 + * 2. If so, is your lowest supported CL going to be 3?
  327 + * 3. If so, then you must set AL=1 because
  328 + *
  329 + * WL >= 3 for ODT on writes
  330 + * RL = AL + CL
  331 + * WL = RL - 1
  332 + * ->
  333 + * WL = AL + CL - 1
  334 + * AL + CL - 1 >= 3
  335 + * AL + CL >= 4
  336 + * QED
  337 + *
  338 + * RL >= 3 for ODT on reads
  339 + * RL = AL + CL
  340 + *
  341 + * Since CL aren't usually less than 2, AL=0 is a minimum,
  342 + * so the WL-derived AL should be the -- FIXME?
  343 + *
  344 + * II. Because you are using auto-precharge globally and want to
  345 + * use additive latency (posted CAS) to get more bandwidth.
  346 + * 1. Are you going to use auto-precharge mode globally?
  347 + *
  348 + * Use addtivie latency and compute AL to be 1 cycle less than
  349 + * tRCD, i.e. the READ or WRITE command is in the cycle
  350 + * immediately following the ACTIVATE command..
  351 + *
  352 + * III. Because you feel like it or want to do some sort of
  353 + * degraded-performance experiment.
  354 + * 1. Do you just want to use additive latency because you feel
  355 + * like it?
  356 + *
  357 + * Validation: AL is less than tRCD, and within the other
  358 + * read-to-precharge constraints.
  359 + */
  360 +
  361 + additive_latency = 0;
  362 +
  363 +#if defined(CONFIG_FSL_DDR2)
  364 + if (lowest_good_caslat < 4) {
  365 + additive_latency = picos_to_mclk(tRCD_ps) - lowest_good_caslat;
  366 + if (mclk_to_picos(additive_latency) > tRCD_ps) {
  367 + additive_latency = picos_to_mclk(tRCD_ps);
  368 + debug("setting additive_latency to %u because it was "
  369 + " greater than tRCD_ps\n", additive_latency);
  370 + }
  371 + }
  372 +
  373 +#elif defined(CONFIG_FSL_DDR3)
  374 +error "FIXME determine additive latency for DDR3"
  375 +#endif
  376 +
  377 + /*
  378 + * Validate additive latency
  379 + * FIXME: move to somewhere else to validate
  380 + *
  381 + * AL <= tRCD(min)
  382 + */
  383 + if (mclk_to_picos(additive_latency) > tRCD_ps) {
  384 + printf("Error: invalid additive latency exceeds tRCD(min).\n");
  385 + return 1;
  386 + }
  387 +
  388 + /*
  389 + * RL = CL + AL; RL >= 3 for ODT_RD_CFG to be enabled
  390 + * WL = RL - 1; WL >= 3 for ODT_WL_CFG to be enabled
  391 + * ADD_LAT (the register) must be set to a value less
  392 + * than ACTTORW if WL = 1, then AL must be set to 1
  393 + * RD_TO_PRE (the register) must be set to a minimum
  394 + * tRTP + AL if AL is nonzero
  395 + */
  396 +
  397 + /*
  398 + * Additive latency will be applied only if the memctl option to
  399 + * use it.
  400 + */
  401 + outpdimm->additive_latency = additive_latency;
  402 +
  403 + return 0;
  404 +}
cpu/mpc8xxx/ddr/main.c
  1 +/*
  2 + * Copyright 2008 Freescale Semiconductor, Inc.
  3 + *
  4 + * This program is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU General Public License
  6 + * Version 2 as published by the Free Software Foundation.
  7 + */
  8 +
  9 +/*
  10 + * Generic driver for Freescale DDR/DDR2/DDR3 memory controller.
  11 + * Based on code from spd_sdram.c
  12 + * Author: James Yang [at freescale.com]
  13 + */
  14 +
  15 +#include <common.h>
  16 +#include <asm/fsl_ddr_sdram.h>
  17 +
  18 +#include "ddr.h"
  19 +
  20 +extern void fsl_ddr_set_lawbar(
  21 + const common_timing_params_t *memctl_common_params,
  22 + unsigned int memctl_interleaved,
  23 + unsigned int ctrl_num);
  24 +
  25 +/* processor specific function */
  26 +extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
  27 + unsigned int ctrl_num);
  28 +
  29 +/* Board-specific functions defined in each board's ddr.c */
  30 +extern void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
  31 + unsigned int ctrl_num);
  32 +
  33 +/*
  34 + * ASSUMPTIONS:
  35 + * - Same number of CONFIG_DIMM_SLOTS_PER_CTLR on each controller
  36 + * - Same memory data bus width on all controllers
  37 + *
  38 + * NOTES:
  39 + *
  40 + * The memory controller and associated documentation use confusing
  41 + * terminology when referring to the orgranization of DRAM.
  42 + *
  43 + * Here is a terminology translation table:
  44 + *
  45 + * memory controller/documention |industry |this code |signals
  46 + * -------------------------------|-----------|-----------|-----------------
  47 + * physical bank/bank |rank |rank |chip select (CS)
  48 + * logical bank/sub-bank |bank |bank |bank address (BA)
  49 + * page/row |row |page |row address
  50 + * ??? |column |column |column address
  51 + *
  52 + * The naming confusion is further exacerbated by the descriptions of the
  53 + * memory controller interleaving feature, where accesses are interleaved
  54 + * _BETWEEN_ two seperate memory controllers. This is configured only in
  55 + * CS0_CONFIG[INTLV_CTL] of each memory controller.
  56 + *
  57 + * memory controller documentation | number of chip selects
  58 + * | per memory controller supported
  59 + * --------------------------------|-----------------------------------------
  60 + * cache line interleaving | 1 (CS0 only)
  61 + * page interleaving | 1 (CS0 only)
  62 + * bank interleaving | 1 (CS0 only)
  63 + * superbank interleraving | depends on bank (chip select)
  64 + * | interleraving [rank interleaving]
  65 + * | mode used on every memory controller
  66 + *
  67 + * Even further confusing is the existence of the interleaving feature
  68 + * _WITHIN_ each memory controller. The feature is referred to in
  69 + * documentation as chip select interleaving or bank interleaving,
  70 + * although it is configured in the DDR_SDRAM_CFG field.
  71 + *
  72 + * Name of field | documentation name | this code
  73 + * -----------------------------|-----------------------|------------------
  74 + * DDR_SDRAM_CFG[BA_INTLV_CTL] | Bank (chip select) | rank interleaving
  75 + * | interleaving
  76 + */
  77 +
  78 +#ifdef DEBUG
  79 +const char *step_string_tbl[] = {
  80 + "STEP_GET_SPD",
  81 + "STEP_COMPUTE_DIMM_PARMS",
  82 + "STEP_COMPUTE_COMMON_PARMS",
  83 + "STEP_GATHER_OPTS",
  84 + "STEP_ASSIGN_ADDRESSES",
  85 + "STEP_COMPUTE_REGS",
  86 + "STEP_PROGRAM_REGS",
  87 + "STEP_ALL"
  88 +};
  89 +
  90 +const char * step_to_string(unsigned int step) {
  91 +
  92 + unsigned int s = __ilog2(step);
  93 +
  94 + if ((1 << s) != step)
  95 + return step_string_tbl[7];
  96 +
  97 + return step_string_tbl[s];
  98 +}
  99 +#endif
  100 +
  101 +int step_assign_addresses(fsl_ddr_info_t *pinfo,
  102 + unsigned int dbw_cap_adj[],
  103 + unsigned int *memctl_interleaving,
  104 + unsigned int *rank_interleaving)
  105 +{
  106 + int i, j;
  107 +
  108 + /*
  109 + * If a reduced data width is requested, but the SPD
  110 + * specifies a physically wider device, adjust the
  111 + * computed dimm capacities accordingly before
  112 + * assigning addresses.
  113 + */
  114 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  115 + unsigned int found = 0;
  116 +
  117 + switch (pinfo->memctl_opts[i].data_bus_width) {
  118 + case 2:
  119 + /* 16-bit */
  120 + printf("can't handle 16-bit mode yet\n");
  121 + break;
  122 +
  123 + case 1:
  124 + /* 32-bit */
  125 + for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
  126 + unsigned int dw;
  127 + dw = pinfo->dimm_params[i][j].data_width;
  128 + if (pinfo->dimm_params[i][j].n_ranks
  129 + && (dw == 72 || dw == 64)) {
  130 + /*
  131 + * FIXME: can't really do it
  132 + * like this because this just
  133 + * further reduces the memory
  134 + */
  135 + found = 1;
  136 + break;
  137 + }
  138 + }
  139 + if (found) {
  140 + dbw_cap_adj[i] = 1;
  141 + }
  142 + break;
  143 +
  144 + case 0:
  145 + /* 64-bit */
  146 + break;
  147 +
  148 + default:
  149 + printf("unexpected data bus width "
  150 + "specified controller %u\n", i);
  151 + return 1;
  152 + }
  153 + }
  154 +
  155 + /*
  156 + * Check if all controllers are configured for memory
  157 + * controller interleaving.
  158 + */
  159 + j = 0;
  160 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  161 + if (pinfo->memctl_opts[i].memctl_interleaving) {
  162 + j++;
  163 + }
  164 + }
  165 + if (j == 2) {
  166 + *memctl_interleaving = 1;
  167 + }
  168 +
  169 + /* Check that all controllers are rank interleaving. */
  170 + j = 0;
  171 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  172 + if (pinfo->memctl_opts[i].ba_intlv_ctl) {
  173 + j++;
  174 + }
  175 + }
  176 + if (j == 2) {
  177 + *rank_interleaving = 1;
  178 + }
  179 +
  180 + if (*memctl_interleaving) {
  181 + phys_addr_t addr;
  182 +
  183 + /*
  184 + * If interleaving between memory controllers,
  185 + * make each controller start at a base address
  186 + * of 0.
  187 + *
  188 + * Also, if bank interleaving (chip select
  189 + * interleaving) is enabled on each memory
  190 + * controller, CS0 needs to be programmed to
  191 + * cover the entire memory range on that memory
  192 + * controller
  193 + *
  194 + * Bank interleaving also implies that each
  195 + * addressed chip select is identical in size.
  196 + */
  197 +
  198 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  199 + addr = 0;
  200 + for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
  201 + unsigned long long cap
  202 + = pinfo->dimm_params[i][j].capacity;
  203 +
  204 + pinfo->dimm_params[i][j].base_address = addr;
  205 + addr += (phys_addr_t)(cap >> dbw_cap_adj[i]);
  206 + }
  207 + }
  208 + } else {
  209 + /*
  210 + * Simple linear assignment if memory
  211 + * controllers are not interleaved.
  212 + */
  213 + phys_size_t cur_memsize = 0;
  214 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  215 + phys_size_t total_mem_per_ctlr = 0;
  216 + pinfo->common_timing_params[i].base_address =
  217 + (phys_addr_t)cur_memsize;
  218 + for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
  219 + /* Compute DIMM base addresses. */
  220 + unsigned long long cap =
  221 + pinfo->dimm_params[i][j].capacity;
  222 +
  223 + pinfo->dimm_params[i][j].base_address =
  224 + (phys_addr_t)cur_memsize;
  225 + cur_memsize += cap >> dbw_cap_adj[i];
  226 + total_mem_per_ctlr += cap >> dbw_cap_adj[i];
  227 + }
  228 + pinfo->common_timing_params[i].total_mem =
  229 + total_mem_per_ctlr;
  230 + }
  231 + }
  232 +
  233 + return 0;
  234 +}
  235 +
  236 +phys_size_t
  237 +fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step)
  238 +{
  239 + unsigned int i, j;
  240 + unsigned int all_controllers_memctl_interleaving = 0;
  241 + unsigned int all_controllers_rank_interleaving = 0;
  242 + phys_size_t total_mem = 0;
  243 +
  244 + fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
  245 + common_timing_params_t *timing_params = pinfo->common_timing_params;
  246 +
  247 + /* data bus width capacity adjust shift amount */
  248 + unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS];
  249 +
  250 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  251 + dbw_capacity_adjust[i] = 0;
  252 + }
  253 +
  254 + debug("starting at step %u (%s)\n",
  255 + start_step, step_to_string(start_step));
  256 +
  257 + switch (start_step) {
  258 + case STEP_GET_SPD:
  259 + /* STEP 1: Gather all DIMM SPD data */
  260 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  261 + fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i);
  262 + }
  263 +
  264 + case STEP_COMPUTE_DIMM_PARMS:
  265 + /* STEP 2: Compute DIMM parameters from SPD data */
  266 +
  267 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  268 + for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
  269 + unsigned int retval;
  270 + generic_spd_eeprom_t *spd =
  271 + &(pinfo->spd_installed_dimms[i][j]);
  272 + dimm_params_t *pdimm =
  273 + &(pinfo->dimm_params[i][j]);
  274 +
  275 + retval = compute_dimm_parameters(spd, pdimm, i);
  276 + if (retval == 2) {
  277 + printf("Error: compute_dimm_parameters"
  278 + " non-zero returned FATAL value "
  279 + "for memctl=%u dimm=%u\n", i, j);
  280 + return 0;
  281 + }
  282 + if (retval) {
  283 + debug("Warning: compute_dimm_parameters"
  284 + " non-zero return value for memctl=%u "
  285 + "dimm=%u\n", i, j);
  286 + }
  287 + }
  288 + }
  289 +
  290 + case STEP_COMPUTE_COMMON_PARMS:
  291 + /*
  292 + * STEP 3: Compute a common set of timing parameters
  293 + * suitable for all of the DIMMs on each memory controller
  294 + */
  295 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  296 + debug("Computing lowest common DIMM"
  297 + " parameters for memctl=%u\n", i);
  298 + compute_lowest_common_dimm_parameters(
  299 + pinfo->dimm_params[i],
  300 + &timing_params[i],
  301 + CONFIG_DIMM_SLOTS_PER_CTLR);
  302 + }
  303 +
  304 + case STEP_GATHER_OPTS:
  305 + /* STEP 4: Gather configuration requirements from user */
  306 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  307 + debug("Reloading memory controller "
  308 + "configuration options for memctl=%u\n", i);
  309 + /*
  310 + * This "reloads" the memory controller options
  311 + * to defaults. If the user "edits" an option,
  312 + * next_step points to the step after this,
  313 + * which is currently STEP_ASSIGN_ADDRESSES.
  314 + */
  315 + populate_memctl_options(
  316 + timing_params[i].all_DIMMs_registered,
  317 + &pinfo->memctl_opts[i], i);
  318 + }
  319 +
  320 + case STEP_ASSIGN_ADDRESSES:
  321 + /* STEP 5: Assign addresses to chip selects */
  322 + step_assign_addresses(pinfo,
  323 + dbw_capacity_adjust,
  324 + &all_controllers_memctl_interleaving,
  325 + &all_controllers_rank_interleaving);
  326 +
  327 + case STEP_COMPUTE_REGS:
  328 + /* STEP 6: compute controller register values */
  329 + debug("FSL Memory ctrl cg register computation\n");
  330 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  331 + if (timing_params[i].ndimms_present == 0) {
  332 + memset(&ddr_reg[i], 0,
  333 + sizeof(fsl_ddr_cfg_regs_t));
  334 + continue;
  335 + }
  336 +
  337 + compute_fsl_memctl_config_regs(
  338 + &pinfo->memctl_opts[i],
  339 + &ddr_reg[i], &timing_params[i],
  340 + pinfo->dimm_params[i],
  341 + dbw_capacity_adjust[i]);
  342 + }
  343 +
  344 + default:
  345 + break;
  346 + }
  347 +
  348 + /* Compute the total amount of memory. */
  349 +
  350 + /*
  351 + * If bank interleaving but NOT memory controller interleaving
  352 + * CS_BNDS describe the quantity of memory on each memory
  353 + * controller, so the total is the sum across.
  354 + */
  355 + if (!all_controllers_memctl_interleaving
  356 + && all_controllers_rank_interleaving) {
  357 + total_mem = 0;
  358 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  359 + total_mem += timing_params[i].total_mem;
  360 + }
  361 +
  362 + } else {
  363 + /*
  364 + * Compute the amount of memory available just by
  365 + * looking for the highest valid CSn_BNDS value.
  366 + * This allows us to also experiment with using
  367 + * only CS0 when using dual-rank DIMMs.
  368 + */
  369 + unsigned int max_end = 0;
  370 +
  371 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  372 + for (j = 0; j < CONFIG_CHIP_SELECTS_PER_CTRL; j++) {
  373 + fsl_ddr_cfg_regs_t *reg = &ddr_reg[i];
  374 + if (reg->cs[j].config & 0x80000000) {
  375 + unsigned int end;
  376 + end = reg->cs[j].bnds & 0xFFF;
  377 + if (end > max_end) {
  378 + max_end = end;
  379 + }
  380 + }
  381 + }
  382 + }
  383 +
  384 +#if !defined(CONFIG_PHYS_64BIT)
  385 + /* Check for 4G or more with a 32-bit phys_addr_t. Bad. */
  386 + if (max_end >= 0xff) {
  387 + printf("This U-Boot only supports < 4G of DDR\n");
  388 + printf("You could rebuild it with CONFIG_PHYS_64BIT\n");
  389 + return 0; /* Ensure DDR setup failure. */
  390 + }
  391 +#endif
  392 +
  393 + total_mem = 1 + (((unsigned long long)max_end << 24ULL)
  394 + | 0xFFFFFFULL);
  395 + }
  396 +
  397 + return total_mem;
  398 +}
  399 +
  400 +/*
  401 + * fsl_ddr_sdram() -- this is the main function to be called by
  402 + * initdram() in the board file.
  403 + *
  404 + * It returns amount of memory configured in bytes.
  405 + */
  406 +phys_size_t fsl_ddr_sdram(void)
  407 +{
  408 + unsigned int i;
  409 + unsigned int memctl_interleaved;
  410 + phys_size_t total_memory;
  411 + fsl_ddr_info_t info;
  412 +
  413 + /* Reset info structure. */
  414 + memset(&info, 0, sizeof(fsl_ddr_info_t));
  415 +
  416 + /* Compute it once normally. */
  417 + total_memory = fsl_ddr_compute(&info, STEP_GET_SPD);
  418 +
  419 + /* Check for memory controller interleaving. */
  420 + memctl_interleaved = 0;
  421 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  422 + memctl_interleaved +=
  423 + info.memctl_opts[i].memctl_interleaving;
  424 + }
  425 +
  426 + if (memctl_interleaved) {
  427 + if (memctl_interleaved == CONFIG_NUM_DDR_CONTROLLERS) {
  428 + debug("memctl interleaving\n");
  429 + /*
  430 + * Change the meaning of memctl_interleaved
  431 + * to be "boolean".
  432 + */
  433 + memctl_interleaved = 1;
  434 + } else {
  435 + printf("Error: memctl interleaving not "
  436 + "properly configured on all controllers\n");
  437 + while (1);
  438 + }
  439 + }
  440 +
  441 + /* Program configuration registers. */
  442 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  443 + debug("Programming controller %u\n", i);
  444 + if (info.common_timing_params[i].ndimms_present == 0) {
  445 + debug("No dimms present on controller %u; "
  446 + "skipping programming\n", i);
  447 + continue;
  448 + }
  449 +
  450 + fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i);
  451 + }
  452 +
  453 + if (memctl_interleaved) {
  454 + const unsigned int ctrl_num = 0;
  455 +
  456 + /* Only set LAWBAR1 if memory controller interleaving is on. */
  457 + fsl_ddr_set_lawbar(&info.common_timing_params[0],
  458 + memctl_interleaved, ctrl_num);
  459 + } else {
  460 + /*
  461 + * Memory controller interleaving is NOT on;
  462 + * set each lawbar individually.
  463 + */
  464 + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
  465 + fsl_ddr_set_lawbar(&info.common_timing_params[i],
  466 + 0, i);
  467 + }
  468 + }
  469 +
  470 + debug("total_memory = %llu\n", (u64)total_memory);
  471 +
  472 + return total_memory;
  473 +}
cpu/mpc8xxx/ddr/options.c
  1 +/*
  2 + * Copyright 2008 Freescale Semiconductor, Inc.
  3 + *
  4 + * This program is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU General Public License
  6 + * Version 2 as published by the Free Software Foundation.
  7 + */
  8 +
  9 +#include <common.h>
  10 +#include <asm/fsl_ddr_sdram.h>
  11 +
  12 +#include "ddr.h"
  13 +
  14 +/* Board-specific functions defined in each board's ddr.c */
  15 +extern void fsl_ddr_board_options(memctl_options_t *popts,
  16 + unsigned int ctrl_num);
  17 +
  18 +unsigned int populate_memctl_options(int all_DIMMs_registered,
  19 + memctl_options_t *popts,
  20 + unsigned int ctrl_num)
  21 +{
  22 + unsigned int i;
  23 +
  24 + /* Chip select options. */
  25 +
  26 + /* Pick chip-select local options. */
  27 + for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
  28 + /* If not DDR2, odt_rd_cfg and odt_wr_cfg need to be 0. */
  29 +
  30 + /* only for single CS? */
  31 + popts->cs_local_opts[i].odt_rd_cfg = 0;
  32 +
  33 + popts->cs_local_opts[i].odt_wr_cfg = 1;
  34 + popts->cs_local_opts[i].auto_precharge = 0;
  35 + }
  36 +
  37 + /* Pick interleaving mode. */
  38 +
  39 + /*
  40 + * 0 = no interleaving
  41 + * 1 = interleaving between 2 controllers
  42 + */
  43 + popts->memctl_interleaving = 0;
  44 +
  45 + /*
  46 + * 0 = cacheline
  47 + * 1 = page
  48 + * 2 = (logical) bank
  49 + * 3 = superbank (only if CS interleaving is enabled)
  50 + */
  51 + popts->memctl_interleaving_mode = 0;
  52 +
  53 + /*
  54 + * 0: cacheline: bit 30 of the 36-bit physical addr selects the memctl
  55 + * 1: page: bit to the left of the column bits selects the memctl
  56 + * 2: bank: bit to the left of the bank bits selects the memctl
  57 + * 3: superbank: bit to the left of the chip select selects the memctl
  58 + *
  59 + * NOTE: ba_intlv (rank interleaving) is independent of memory
  60 + * controller interleaving; it is only within a memory controller.
  61 + * Must use superbank interleaving if rank interleaving is used and
  62 + * memory controller interleaving is enabled.
  63 + */
  64 +
  65 + /*
  66 + * 0 = no
  67 + * 0x40 = CS0,CS1
  68 + * 0x20 = CS2,CS3
  69 + * 0x60 = CS0,CS1 + CS2,CS3
  70 + * 0x04 = CS0,CS1,CS2,CS3
  71 + */
  72 + popts->ba_intlv_ctl = 0;
  73 +
  74 + /* Memory Organization Parameters */
  75 + popts->registered_dimm_en = all_DIMMs_registered;
  76 +
  77 + /* Operational Mode Paramters */
  78 +
  79 + /* Pick ECC modes */
  80 +#ifdef CONFIG_DDR_ECC
  81 + popts->ECC_mode = 1; /* 0 = disabled, 1 = enabled */
  82 +#else
  83 + popts->ECC_mode = 0; /* 0 = disabled, 1 = enabled */
  84 +#endif
  85 + popts->ECC_init_using_memctl = 1; /* 0 = use DMA, 1 = use memctl */
  86 +
  87 + /*
  88 + * Choose DQS config
  89 + * 0 for DDR1
  90 + * 1 for DDR2
  91 + */
  92 +#if defined(CONFIG_FSL_DDR1)
  93 + popts->DQS_config = 0;
  94 +#elif defined(CONFIG_FSL_DDR2)
  95 + popts->DQS_config = 1;
  96 +#else
  97 +#error "Fix DQS for DDR3"
  98 +#endif
  99 +
  100 + /* Choose self-refresh during sleep. */
  101 + popts->self_refresh_in_sleep = 1;
  102 +
  103 + /* Choose dynamic power management mode. */
  104 + popts->dynamic_power = 0;
  105 +
  106 + /* 0 = 64-bit, 1 = 32-bit, 2 = 16-bit */
  107 + popts->data_bus_width = 0;
  108 +
  109 + /* Choose burst length. */
  110 + popts->burst_length = 4; /* has to be 4 for DDR2 */
  111 +
  112 + /* Global Timing Parameters. */
  113 + debug("mclk_ps = %u ps\n", get_memory_clk_period_ps());
  114 +
  115 + /* Pick a caslat override. */
  116 + popts->cas_latency_override = 0;
  117 + popts->cas_latency_override_value = 3;
  118 + if (popts->cas_latency_override) {
  119 + debug("using caslat override value = %u\n",
  120 + popts->cas_latency_override_value);
  121 + }
  122 +
  123 + /* Decide whether to use the computed derated latency */
  124 + popts->use_derated_caslat = 0;
  125 +
  126 + /* Choose an additive latency. */
  127 + popts->additive_latency_override = 0;
  128 + popts->additive_latency_override_value = 3;
  129 + if (popts->additive_latency_override) {
  130 + debug("using additive latency override value = %u\n",
  131 + popts->additive_latency_override_value);
  132 + }
  133 +
  134 + /*
  135 + * 2T_EN setting
  136 + *
  137 + * Factors to consider for 2T_EN:
  138 + * - number of DIMMs installed
  139 + * - number of components, number of active ranks
  140 + * - how much time you want to spend playing around
  141 + */
  142 + popts->twoT_en = 1;
  143 + popts->threeT_en = 0;
  144 +
  145 + /*
  146 + * BSTTOPRE precharge interval
  147 + *
  148 + * Set this to 0 for global auto precharge
  149 + *
  150 + * FIXME: Should this be configured in picoseconds?
  151 + * Why it should be in ps: better understanding of this
  152 + * relative to actual DRAM timing parameters such as tRAS.
  153 + * e.g. tRAS(min) = 40 ns
  154 + */
  155 + popts->bstopre = 0x100;
  156 +
  157 + /* Minimum CKE pulse width -- tCKE(MIN) */
  158 + popts->tCKE_clock_pulse_width_ps
  159 + = mclk_to_picos(FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR);
  160 +
  161 + /*
  162 + * Window for four activates -- tFAW
  163 + *
  164 + * FIXME: UM: applies only to DDR2/DDR3 with eight logical banks only
  165 + * FIXME: varies depending upon number of column addresses or data
  166 + * FIXME: width, was considering looking at pdimm->primary_sdram_width
  167 + */
  168 +#if defined(CONFIG_FSL_DDR1)
  169 + popts->tFAW_window_four_activates_ps = mclk_to_picos(1);
  170 +
  171 +#elif defined(CONFIG_FSL_DDR2)
  172 + /*
  173 + * x4/x8; some datasheets have 35000
  174 + * x16 wide columns only? Use 50000?
  175 + */
  176 + popts->tFAW_window_four_activates_ps = 37500;
  177 +
  178 +#elif defined(CONFIG_FSL_DDR3)
  179 +#error "FIXME determine four activates for DDR3"
  180 +#endif
  181 +
  182 + /* ODT should only be used for DDR2 */
  183 +
  184 + /* FIXME? */
  185 +
  186 + /*
  187 + * Interleaving checks.
  188 + *
  189 + * If memory controller interleaving is enabled, then the data
  190 + * bus widths must be programmed identically for the 2 memory
  191 + * controllers.
  192 + */
  193 +
  194 + fsl_ddr_board_options(popts, ctrl_num);
  195 +
  196 + return 0;
  197 +}
cpu/mpc8xxx/ddr/util.c
  1 +/*
  2 + * Copyright 2008 Freescale Semiconductor, Inc.
  3 + *
  4 + * This program is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU General Public License
  6 + * Version 2 as published by the Free Software Foundation.
  7 + */
  8 +
  9 +#include <common.h>
  10 +#include <asm/fsl_law.h>
  11 +
  12 +#include "ddr.h"
  13 +
  14 +unsigned int fsl_ddr_get_mem_data_rate(void);
  15 +
  16 +/*
  17 + * Round mclk_ps to nearest 10 ps in memory controller code.
  18 + *
  19 + * If an imprecise data rate is too high due to rounding error
  20 + * propagation, compute a suitably rounded mclk_ps to compute
  21 + * a working memory controller configuration.
  22 + */
  23 +unsigned int get_memory_clk_period_ps(void)
  24 +{
  25 + unsigned int mclk_ps;
  26 +
  27 + mclk_ps = 2000000000000ULL / fsl_ddr_get_mem_data_rate();
  28 + /* round to nearest 10 ps */
  29 + return 10 * ((mclk_ps + 5) / 10);
  30 +}
  31 +
  32 +/* Convert picoseconds into DRAM clock cycles (rounding up if needed). */
  33 +unsigned int picos_to_mclk(unsigned int picos)
  34 +{
  35 + const unsigned long long ULL_2e12 = 2000000000000ULL;
  36 + const unsigned long long ULL_8Fs = 0xFFFFFFFFULL;
  37 + unsigned long long clks;
  38 + unsigned long long clks_temp;
  39 +
  40 + if (!picos)
  41 + return 0;
  42 +
  43 + clks = fsl_ddr_get_mem_data_rate() * (unsigned long long) picos;
  44 + clks_temp = clks;
  45 + clks = clks / ULL_2e12;
  46 + if (clks_temp % ULL_2e12) {
  47 + clks++;
  48 + }
  49 +
  50 + if (clks > ULL_8Fs) {
  51 + clks = ULL_8Fs;
  52 + }
  53 +
  54 + return (unsigned int) clks;
  55 +}
  56 +
  57 +unsigned int mclk_to_picos(unsigned int mclk)
  58 +{
  59 + return get_memory_clk_period_ps() * mclk;
  60 +}
  61 +
  62 +void
  63 +__fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
  64 + unsigned int memctl_interleaved,
  65 + unsigned int ctrl_num)
  66 +{
  67 + /*
  68 + * If no DIMMs on this controller, do not proceed any further.
  69 + */
  70 + if (!memctl_common_params->ndimms_present) {
  71 + return;
  72 + }
  73 +
  74 + if (ctrl_num == 0) {
  75 + /*
  76 + * Set up LAW for DDR controller 1 space.
  77 + */
  78 + unsigned int lawbar1_target_id = memctl_interleaved
  79 + ? LAW_TRGT_IF_DDR_INTRLV : LAW_TRGT_IF_DDR_1;
  80 +
  81 + if (set_ddr_laws(memctl_common_params->base_address,
  82 + memctl_common_params->total_mem,
  83 + lawbar1_target_id) < 0) {
  84 + printf("ERROR\n");
  85 + return ;
  86 + }
  87 + } else if (ctrl_num == 1) {
  88 + if (set_ddr_laws(memctl_common_params->base_address,
  89 + memctl_common_params->total_mem,
  90 + LAW_TRGT_IF_DDR_2) < 0) {
  91 + printf("ERROR\n");
  92 + return ;
  93 + }
  94 + } else {
  95 + printf("unexpected controller number %u in %s\n",
  96 + ctrl_num, __FUNCTION__);
  97 + }
  98 +}
  99 +
  100 +__attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void
  101 +fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
  102 + unsigned int memctl_interleaved,
  103 + unsigned int ctrl_num);
include/asm-ppc/fsl_ddr_sdram.h
  1 +/*
  2 + * Copyright 2008 Freescale Semiconductor, Inc.
  3 + *
  4 + * This program is free software; you can redistribute it and/or
  5 + * modify it under the terms of the GNU General Public License
  6 + * Version 2 as published by the Free Software Foundation.
  7 + */
  8 +
  9 +#ifndef FSL_DDR_MEMCTL_H
  10 +#define FSL_DDR_MEMCTL_H
  11 +
  12 +/*
  13 + * Pick a basic DDR Technology.
  14 + */
  15 +#include <ddr_spd.h>
  16 +
  17 +#define SDRAM_TYPE_DDR1 2
  18 +#define SDRAM_TYPE_DDR2 3
  19 +#define SDRAM_TYPE_LPDDR1 6
  20 +#define SDRAM_TYPE_DDR3 7
  21 +
  22 +#if defined(CONFIG_FSL_DDR1)
  23 +#define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR (1)
  24 +typedef ddr1_spd_eeprom_t generic_spd_eeprom_t;
  25 +#ifndef CONFIG_FSL_SDRAM_TYPE
  26 +#define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR1
  27 +#endif
  28 +#elif defined(CONFIG_FSL_DDR2)
  29 +#define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR (3)
  30 +typedef ddr2_spd_eeprom_t generic_spd_eeprom_t;
  31 +#ifndef CONFIG_FSL_SDRAM_TYPE
  32 +#define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR2
  33 +#endif
  34 +#elif defined(CONFIG_FSL_DDR3)
  35 +#define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR (3) /* FIXME */
  36 +typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
  37 +#endif
  38 +
  39 +/* Record of register values computed */
  40 +typedef struct fsl_ddr_cfg_regs_s {
  41 + struct {
  42 + unsigned int bnds;
  43 + unsigned int config;
  44 + unsigned int config_2;
  45 + } cs[CONFIG_CHIP_SELECTS_PER_CTRL];
  46 + unsigned int timing_cfg_3;
  47 + unsigned int timing_cfg_0;
  48 + unsigned int timing_cfg_1;
  49 + unsigned int timing_cfg_2;
  50 + unsigned int ddr_sdram_cfg;
  51 + unsigned int ddr_sdram_cfg_2;
  52 + unsigned int ddr_sdram_mode;
  53 + unsigned int ddr_sdram_mode_2;
  54 + unsigned int ddr_sdram_md_cntl;
  55 + unsigned int ddr_sdram_interval;
  56 + unsigned int ddr_data_init;
  57 + unsigned int ddr_sdram_clk_cntl;
  58 + unsigned int ddr_init_addr;
  59 + unsigned int ddr_init_ext_addr;
  60 + unsigned int timing_cfg_4;
  61 + unsigned int timing_cfg_5;
  62 + unsigned int ddr_zq_cntl;
  63 + unsigned int ddr_wrlvl_cntl;
  64 + unsigned int ddr_pd_cntl;
  65 + unsigned int ddr_sr_cntr;
  66 + unsigned int ddr_sdram_rcw_1;
  67 + unsigned int ddr_sdram_rcw_2;
  68 +} fsl_ddr_cfg_regs_t;
  69 +
  70 +typedef struct memctl_options_partial_s {
  71 + unsigned int all_DIMMs_ECC_capable;
  72 + unsigned int all_DIMMs_tCKmax_ps;
  73 + unsigned int all_DIMMs_burst_lengths_bitmask;
  74 + unsigned int all_DIMMs_registered;
  75 + unsigned int all_DIMMs_unbuffered;
  76 + /* unsigned int lowest_common_SPD_caslat; */
  77 + unsigned int all_DIMMs_minimum_tRCD_ps;
  78 +} memctl_options_partial_t;
  79 +
  80 +/*
  81 + * Generalized parameters for memory controller configuration,
  82 + * might be a little specific to the FSL memory controller
  83 + */
  84 +typedef struct memctl_options_s {
  85 + /*
  86 + * Memory organization parameters
  87 + *
  88 + * if DIMM is present in the system
  89 + * where DIMMs are with respect to chip select
  90 + * where chip selects are with respect to memory boundaries
  91 + */
  92 + unsigned int registered_dimm_en; /* use registered DIMM support */
  93 +
  94 + /* Options local to a Chip Select */
  95 + struct cs_local_opts_s {
  96 + unsigned int auto_precharge;
  97 + unsigned int odt_rd_cfg;
  98 + unsigned int odt_wr_cfg;
  99 + } cs_local_opts[CONFIG_CHIP_SELECTS_PER_CTRL];
  100 +
  101 + /* Special configurations for chip select */
  102 + unsigned int memctl_interleaving;
  103 + unsigned int memctl_interleaving_mode;
  104 + unsigned int ba_intlv_ctl;
  105 +
  106 + /* Operational mode parameters */
  107 + unsigned int ECC_mode; /* Use ECC? */
  108 + /* Initialize ECC using memory controller? */
  109 + unsigned int ECC_init_using_memctl;
  110 + unsigned int DQS_config; /* Use DQS? maybe only with DDR2? */
  111 + /* SREN - self-refresh during sleep */
  112 + unsigned int self_refresh_in_sleep;
  113 + unsigned int dynamic_power; /* DYN_PWR */
  114 + /* memory data width to use (16-bit, 32-bit, 64-bit) */
  115 + unsigned int data_bus_width;
  116 + unsigned int burst_length; /* 4, 8 */
  117 +
  118 + /* Global Timing Parameters */
  119 + unsigned int cas_latency_override;
  120 + unsigned int cas_latency_override_value;
  121 + unsigned int use_derated_caslat;
  122 + unsigned int additive_latency_override;
  123 + unsigned int additive_latency_override_value;
  124 +
  125 + unsigned int clk_adjust; /* */
  126 + unsigned int cpo_override;
  127 + unsigned int write_data_delay; /* DQS adjust */
  128 + unsigned int half_strength_driver_enable;
  129 + unsigned int twoT_en;
  130 + unsigned int threeT_en;
  131 + unsigned int bstopre;
  132 + unsigned int tCKE_clock_pulse_width_ps; /* tCKE */
  133 + unsigned int tFAW_window_four_activates_ps; /* tFAW -- FOUR_ACT */
  134 +} memctl_options_t;
  135 +
  136 +extern phys_size_t fsl_ddr_sdram(void);
  137 +#endif