diff options
author | York Sun <yorksun@freescale.com> | 2013-09-30 09:22:09 -0700 |
---|---|---|
committer | York Sun <yorksun@freescale.com> | 2013-11-25 11:43:43 -0800 |
commit | 5614e71b4956c579cd4419b958b33fa6316eaa92 (patch) | |
tree | f75d1d531814dbbe0ff9d65f28cc050a73a8f7de /arch/powerpc/cpu/mpc8xxx | |
parent | ac6880782d8f369b7121488e8407ae6ddcf2b9ff (diff) | |
download | u-boot-imx-5614e71b4956c579cd4419b958b33fa6316eaa92.zip u-boot-imx-5614e71b4956c579cd4419b958b33fa6316eaa92.tar.gz u-boot-imx-5614e71b4956c579cd4419b958b33fa6316eaa92.tar.bz2 |
Driver/DDR: Moving Freescale DDR driver to a common driver
Freescale DDR driver has been used for mpc83xx, mpc85xx, mpc86xx SoCs.
The similar DDR controllers will be used for ARM-based SoCs.
Signed-off-by: York Sun <yorksun@freescale.com>
Diffstat (limited to 'arch/powerpc/cpu/mpc8xxx')
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/Makefile | 6 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/Makefile | 29 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h | 57 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 1656 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/ddr.h | 105 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/ddr1_dimm_params.c | 343 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/ddr2_dimm_params.c | 342 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c | 341 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/interactive.c | 1870 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c | 526 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/main.c | 718 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/options.c | 1147 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc8xxx/ddr/util.c | 264 |
13 files changed, 0 insertions, 7404 deletions
diff --git a/arch/powerpc/cpu/mpc8xxx/Makefile b/arch/powerpc/cpu/mpc8xxx/Makefile index 1d083bf..395fed1 100644 --- a/arch/powerpc/cpu/mpc8xxx/Makefile +++ b/arch/powerpc/cpu/mpc8xxx/Makefile @@ -31,9 +31,3 @@ obj-$(CONFIG_SYS_SRIO) += srio.o obj-$(CONFIG_FSL_LAW) += law.o endif - -ifdef CONFIG_SPL_BUILD -obj-$(CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/ -else -obj-y += ddr/ -endif diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/Makefile b/arch/powerpc/cpu/mpc8xxx/ddr/Makefile deleted file mode 100644 index 8cbc06c..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright 2008-2011 Freescale Semiconductor, Inc. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# Version 2 as published by the Free Software Foundation. -# - -obj-$(CONFIG_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \ - lc_common_dimm_params.o - -obj-$(CONFIG_FSL_DDR2) += main.o util.o ctrl_regs.o options.o \ - lc_common_dimm_params.o - -obj-$(CONFIG_FSL_DDR3) += main.o util.o ctrl_regs.o options.o \ - lc_common_dimm_params.o -ifdef CONFIG_DDR_SPD -SPD := y -endif -ifdef CONFIG_SPD_EEPROM -SPD := y -endif -ifdef SPD -obj-$(CONFIG_FSL_DDR1) += ddr1_dimm_params.o -obj-$(CONFIG_FSL_DDR2) += ddr2_dimm_params.o -obj-$(CONFIG_FSL_DDR3) += ddr3_dimm_params.o -endif - -obj-$(CONFIG_FSL_DDR_INTERACTIVE) += interactive.o diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h b/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h deleted file mode 100644 index 76338d4..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/common_timing_params.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2008 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -#ifndef COMMON_TIMING_PARAMS_H -#define COMMON_TIMING_PARAMS_H - -typedef struct { - /* parameters to constrict */ - - unsigned int tckmin_x_ps; - unsigned int tckmax_ps; - unsigned int tckmax_max_ps; - unsigned int trcd_ps; - unsigned int trp_ps; - unsigned int tras_ps; - - unsigned int twr_ps; /* maximum = 63750 ps */ - unsigned int twtr_ps; /* maximum = 63750 ps */ - unsigned int trfc_ps; /* maximum = 255 ns + 256 ns + .75 ns - = 511750 ps */ - - unsigned int trrd_ps; /* maximum = 63750 ps */ - unsigned int trc_ps; /* maximum = 254 ns + .75 ns = 254750 ps */ - - unsigned int refresh_rate_ps; - unsigned int extended_op_srt; - - unsigned int tis_ps; /* byte 32, spd->ca_setup */ - unsigned int tih_ps; /* byte 33, spd->ca_hold */ - unsigned int tds_ps; /* byte 34, spd->data_setup */ - unsigned int tdh_ps; /* byte 35, spd->data_hold */ - unsigned int trtp_ps; /* byte 38, spd->trtp */ - unsigned int tdqsq_max_ps; /* byte 44, spd->tdqsq */ - unsigned int tqhs_ps; /* byte 45, spd->tqhs */ - - unsigned int ndimms_present; - unsigned int lowest_common_SPD_caslat; - unsigned int highest_common_derated_caslat; - unsigned int additive_latency; - unsigned int all_dimms_burst_lengths_bitmask; - unsigned int all_dimms_registered; - unsigned int all_dimms_unbuffered; - unsigned int all_dimms_ecc_capable; - - unsigned long long total_mem; - unsigned long long base_address; - - /* DDR3 RDIMM */ - unsigned char rcw[16]; /* Register Control Word 0-15 */ -} common_timing_params_t; - -#endif diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c deleted file mode 100644 index dcfc48a..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ /dev/null @@ -1,1656 +0,0 @@ -/* - * Copyright 2008-2012 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Generic driver for Freescale DDR/DDR2/DDR3 memory controller. - * Based on code from spd_sdram.c - * Author: James Yang [at freescale.com] - */ - -#include <common.h> -#include <asm/fsl_ddr_sdram.h> - -#include "ddr.h" - -#define _DDR_ADDR CONFIG_SYS_MPC8xxx_DDR_ADDR - -static u32 fsl_ddr_get_version(void) -{ - ccsr_ddr_t *ddr; - u32 ver_major_minor_errata; - - ddr = (void *)_DDR_ADDR; - ver_major_minor_errata = (in_be32(&ddr->ip_rev1) & 0xFFFF) << 8; - ver_major_minor_errata |= (in_be32(&ddr->ip_rev2) & 0xFF00) >> 8; - - return ver_major_minor_errata; -} - -unsigned int picos_to_mclk(unsigned int picos); - -/* - * Determine Rtt value. - * - * This should likely be either board or controller specific. - * - * Rtt(nominal) - DDR2: - * 0 = Rtt disabled - * 1 = 75 ohm - * 2 = 150 ohm - * 3 = 50 ohm - * Rtt(nominal) - DDR3: - * 0 = Rtt disabled - * 1 = 60 ohm - * 2 = 120 ohm - * 3 = 40 ohm - * 4 = 20 ohm - * 5 = 30 ohm - * - * FIXME: Apparently 8641 needs a value of 2 - * FIXME: Old code seys if 667 MHz or higher, use 3 on 8572 - * - * FIXME: There was some effort down this line earlier: - * - * unsigned int i; - * for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL/2; i++) { - * if (popts->dimmslot[i].num_valid_cs - * && (popts->cs_local_opts[2*i].odt_rd_cfg - * || popts->cs_local_opts[2*i].odt_wr_cfg)) { - * rtt = 2; - * break; - * } - * } - */ -static inline int fsl_ddr_get_rtt(void) -{ - int rtt; - -#if defined(CONFIG_FSL_DDR1) - rtt = 0; -#elif defined(CONFIG_FSL_DDR2) - rtt = 3; -#else - rtt = 0; -#endif - - return rtt; -} - -/* - * compute the CAS write latency according to DDR3 spec - * CWL = 5 if tCK >= 2.5ns - * 6 if 2.5ns > tCK >= 1.875ns - * 7 if 1.875ns > tCK >= 1.5ns - * 8 if 1.5ns > tCK >= 1.25ns - * 9 if 1.25ns > tCK >= 1.07ns - * 10 if 1.07ns > tCK >= 0.935ns - * 11 if 0.935ns > tCK >= 0.833ns - * 12 if 0.833ns > tCK >= 0.75ns - */ -static inline unsigned int compute_cas_write_latency(void) -{ - unsigned int cwl; - const unsigned int mclk_ps = get_memory_clk_period_ps(); - - if (mclk_ps >= 2500) - cwl = 5; - else if (mclk_ps >= 1875) - cwl = 6; - else if (mclk_ps >= 1500) - cwl = 7; - else if (mclk_ps >= 1250) - cwl = 8; - else if (mclk_ps >= 1070) - cwl = 9; - else if (mclk_ps >= 935) - cwl = 10; - else if (mclk_ps >= 833) - cwl = 11; - else if (mclk_ps >= 750) - cwl = 12; - else { - cwl = 12; - printf("Warning: CWL is out of range\n"); - } - return cwl; -} - -/* Chip Select Configuration (CSn_CONFIG) */ -static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const dimm_params_t *dimm_params) -{ - unsigned int cs_n_en = 0; /* Chip Select enable */ - unsigned int intlv_en = 0; /* Memory controller interleave enable */ - unsigned int intlv_ctl = 0; /* Interleaving control */ - unsigned int ap_n_en = 0; /* Chip select n auto-precharge enable */ - unsigned int odt_rd_cfg = 0; /* ODT for reads configuration */ - unsigned int odt_wr_cfg = 0; /* ODT for writes configuration */ - unsigned int ba_bits_cs_n = 0; /* Num of bank bits for SDRAM on CSn */ - unsigned int row_bits_cs_n = 0; /* Num of row bits for SDRAM on CSn */ - unsigned int col_bits_cs_n = 0; /* Num of ocl bits for SDRAM on CSn */ - int go_config = 0; - - /* Compute CS_CONFIG only for existing ranks of each DIMM. */ - switch (i) { - case 0: - if (dimm_params[dimm_number].n_ranks > 0) { - go_config = 1; - /* These fields only available in CS0_CONFIG */ - if (!popts->memctl_interleaving) - break; - switch (popts->memctl_interleaving_mode) { - case FSL_DDR_CACHE_LINE_INTERLEAVING: - case FSL_DDR_PAGE_INTERLEAVING: - case FSL_DDR_BANK_INTERLEAVING: - case FSL_DDR_SUPERBANK_INTERLEAVING: - intlv_en = popts->memctl_interleaving; - intlv_ctl = popts->memctl_interleaving_mode; - break; - default: - break; - } - } - break; - case 1: - if ((dimm_number == 0 && dimm_params[0].n_ranks > 1) || \ - (dimm_number == 1 && dimm_params[1].n_ranks > 0)) - go_config = 1; - break; - case 2: - if ((dimm_number == 0 && dimm_params[0].n_ranks > 2) || \ - (dimm_number >= 1 && dimm_params[dimm_number].n_ranks > 0)) - go_config = 1; - break; - case 3: - if ((dimm_number == 0 && dimm_params[0].n_ranks > 3) || \ - (dimm_number == 1 && dimm_params[1].n_ranks > 1) || \ - (dimm_number == 3 && dimm_params[3].n_ranks > 0)) - go_config = 1; - break; - default: - break; - } - if (go_config) { - unsigned int n_banks_per_sdram_device; - cs_n_en = 1; - ap_n_en = popts->cs_local_opts[i].auto_precharge; - odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg; - odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg; - n_banks_per_sdram_device - = dimm_params[dimm_number].n_banks_per_sdram_device; - ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2; - row_bits_cs_n = dimm_params[dimm_number].n_row_addr - 12; - col_bits_cs_n = dimm_params[dimm_number].n_col_addr - 8; - } - ddr->cs[i].config = (0 - | ((cs_n_en & 0x1) << 31) - | ((intlv_en & 0x3) << 29) - | ((intlv_ctl & 0xf) << 24) - | ((ap_n_en & 0x1) << 23) - - /* XXX: some implementation only have 1 bit starting at left */ - | ((odt_rd_cfg & 0x7) << 20) - - /* XXX: Some implementation only have 1 bit starting at left */ - | ((odt_wr_cfg & 0x7) << 16) - - | ((ba_bits_cs_n & 0x3) << 14) - | ((row_bits_cs_n & 0x7) << 8) - | ((col_bits_cs_n & 0x7) << 0) - ); - debug("FSLDDR: cs[%d]_config = 0x%08x\n", i,ddr->cs[i].config); -} - -/* Chip Select Configuration 2 (CSn_CONFIG_2) */ -/* FIXME: 8572 */ -static void set_csn_config_2(int i, fsl_ddr_cfg_regs_t *ddr) -{ - unsigned int pasr_cfg = 0; /* Partial array self refresh config */ - - ddr->cs[i].config_2 = ((pasr_cfg & 7) << 24); - debug("FSLDDR: cs[%d]_config_2 = 0x%08x\n", i, ddr->cs[i].config_2); -} - -/* -3E = 667 CL5, -25 = CL6 800, -25E = CL5 800 */ - -#if !defined(CONFIG_FSL_DDR1) -static inline int avoid_odt_overlap(const dimm_params_t *dimm_params) -{ -#if CONFIG_DIMM_SLOTS_PER_CTLR == 1 - if (dimm_params[0].n_ranks == 4) - return 1; -#endif - -#if CONFIG_DIMM_SLOTS_PER_CTLR == 2 - if ((dimm_params[0].n_ranks == 2) && - (dimm_params[1].n_ranks == 2)) - return 1; - -#ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE - if (dimm_params[0].n_ranks == 4) - return 1; -#endif -#endif - return 0; -} - -/* - * DDR SDRAM Timing Configuration 0 (TIMING_CFG_0) - * - * Avoid writing for DDR I. The new PQ38 DDR controller - * dreams up non-zero default values to be backwards compatible. - */ -static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const dimm_params_t *dimm_params) -{ - unsigned char trwt_mclk = 0; /* Read-to-write turnaround */ - unsigned char twrt_mclk = 0; /* Write-to-read turnaround */ - /* 7.5 ns on -3E; 0 means WL - CL + BL/2 + 1 */ - unsigned char trrt_mclk = 0; /* Read-to-read turnaround */ - unsigned char twwt_mclk = 0; /* Write-to-write turnaround */ - - /* Active powerdown exit timing (tXARD and tXARDS). */ - unsigned char act_pd_exit_mclk; - /* Precharge powerdown exit timing (tXP). */ - unsigned char pre_pd_exit_mclk; - /* ODT powerdown exit timing (tAXPD). */ - unsigned char taxpd_mclk; - /* Mode register set cycle time (tMRD). */ - unsigned char tmrd_mclk; - -#ifdef CONFIG_FSL_DDR3 - /* - * (tXARD and tXARDS). Empirical? - * The DDR3 spec has not tXARD, - * we use the tXP instead of it. - * tXP=max(3nCK, 7.5ns) for DDR3. - * spec has not the tAXPD, we use - * tAXPD=1, need design to confirm. - */ - int tXP = max((get_memory_clk_period_ps() * 3), 7500); /* unit=ps */ - unsigned int data_rate = get_ddr_freq(0); - tmrd_mclk = 4; - /* set the turnaround time */ - - /* - * for single quad-rank DIMM and two dual-rank DIMMs - * to avoid ODT overlap - */ - if (avoid_odt_overlap(dimm_params)) { - twwt_mclk = 2; - trrt_mclk = 1; - } - /* for faster clock, need more time for data setup */ - trwt_mclk = (data_rate/1000000 > 1800) ? 2 : 1; - - if ((data_rate/1000000 > 1150) || (popts->memctl_interleaving)) - twrt_mclk = 1; - - if (popts->dynamic_power == 0) { /* powerdown is not used */ - act_pd_exit_mclk = 1; - pre_pd_exit_mclk = 1; - taxpd_mclk = 1; - } else { - /* act_pd_exit_mclk = tXARD, see above */ - act_pd_exit_mclk = picos_to_mclk(tXP); - /* Mode register MR0[A12] is '1' - fast exit */ - pre_pd_exit_mclk = act_pd_exit_mclk; - taxpd_mclk = 1; - } -#else /* CONFIG_FSL_DDR2 */ - /* - * (tXARD and tXARDS). Empirical? - * tXARD = 2 for DDR2 - * tXP=2 - * tAXPD=8 - */ - act_pd_exit_mclk = 2; - pre_pd_exit_mclk = 2; - taxpd_mclk = 8; - tmrd_mclk = 2; -#endif - - if (popts->trwt_override) - trwt_mclk = popts->trwt; - - ddr->timing_cfg_0 = (0 - | ((trwt_mclk & 0x3) << 30) /* RWT */ - | ((twrt_mclk & 0x3) << 28) /* WRT */ - | ((trrt_mclk & 0x3) << 26) /* RRT */ - | ((twwt_mclk & 0x3) << 24) /* WWT */ - | ((act_pd_exit_mclk & 0x7) << 20) /* ACT_PD_EXIT */ - | ((pre_pd_exit_mclk & 0xF) << 16) /* PRE_PD_EXIT */ - | ((taxpd_mclk & 0xf) << 8) /* ODT_PD_EXIT */ - | ((tmrd_mclk & 0xf) << 0) /* MRS_CYC */ - ); - debug("FSLDDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0); -} -#endif /* defined(CONFIG_FSL_DDR2) */ - -/* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ -static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm, - unsigned int cas_latency) -{ - /* Extended precharge to activate interval (tRP) */ - unsigned int ext_pretoact = 0; - /* Extended Activate to precharge interval (tRAS) */ - unsigned int ext_acttopre = 0; - /* Extended activate to read/write interval (tRCD) */ - unsigned int ext_acttorw = 0; - /* Extended refresh recovery time (tRFC) */ - unsigned int ext_refrec; - /* Extended MCAS latency from READ cmd */ - unsigned int ext_caslat = 0; - /* Extended last data to precharge interval (tWR) */ - unsigned int ext_wrrec = 0; - /* Control Adjust */ - unsigned int cntl_adj = 0; - - ext_pretoact = picos_to_mclk(common_dimm->trp_ps) >> 4; - ext_acttopre = picos_to_mclk(common_dimm->tras_ps) >> 4; - ext_acttorw = picos_to_mclk(common_dimm->trcd_ps) >> 4; - ext_caslat = (2 * cas_latency - 1) >> 4; - ext_refrec = (picos_to_mclk(common_dimm->trfc_ps) - 8) >> 4; - /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ - ext_wrrec = (picos_to_mclk(common_dimm->twr_ps) + - (popts->otf_burst_chop_en ? 2 : 0)) >> 4; - - ddr->timing_cfg_3 = (0 - | ((ext_pretoact & 0x1) << 28) - | ((ext_acttopre & 0x3) << 24) - | ((ext_acttorw & 0x1) << 22) - | ((ext_refrec & 0x1F) << 16) - | ((ext_caslat & 0x3) << 12) - | ((ext_wrrec & 0x1) << 8) - | ((cntl_adj & 0x7) << 0) - ); - debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3); -} - -/* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */ -static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm, - unsigned int cas_latency) -{ - /* Precharge-to-activate interval (tRP) */ - unsigned char pretoact_mclk; - /* Activate to precharge interval (tRAS) */ - unsigned char acttopre_mclk; - /* Activate to read/write interval (tRCD) */ - unsigned char acttorw_mclk; - /* CASLAT */ - unsigned char caslat_ctrl; - /* Refresh recovery time (tRFC) ; trfc_low */ - unsigned char refrec_ctrl; - /* Last data to precharge minimum interval (tWR) */ - unsigned char wrrec_mclk; - /* Activate-to-activate interval (tRRD) */ - unsigned char acttoact_mclk; - /* Last write data pair to read command issue interval (tWTR) */ - unsigned char wrtord_mclk; - /* DDR_SDRAM_MODE doesn't support 9,11,13,15 */ - static const u8 wrrec_table[] = { - 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0}; - - pretoact_mclk = picos_to_mclk(common_dimm->trp_ps); - acttopre_mclk = picos_to_mclk(common_dimm->tras_ps); - acttorw_mclk = picos_to_mclk(common_dimm->trcd_ps); - - /* - * Translate CAS Latency to a DDR controller field value: - * - * CAS Lat DDR I DDR II Ctrl - * Clocks SPD Bit SPD Bit Value - * ------- ------- ------- ----- - * 1.0 0 0001 - * 1.5 1 0010 - * 2.0 2 2 0011 - * 2.5 3 0100 - * 3.0 4 3 0101 - * 3.5 5 0110 - * 4.0 4 0111 - * 4.5 1000 - * 5.0 5 1001 - */ -#if defined(CONFIG_FSL_DDR1) - caslat_ctrl = (cas_latency + 1) & 0x07; -#elif defined(CONFIG_FSL_DDR2) - caslat_ctrl = 2 * cas_latency - 1; -#else - /* - * if the CAS latency more than 8 cycle, - * we need set extend bit for it at - * TIMING_CFG_3[EXT_CASLAT] - */ - caslat_ctrl = 2 * cas_latency - 1; -#endif - - refrec_ctrl = picos_to_mclk(common_dimm->trfc_ps) - 8; - wrrec_mclk = picos_to_mclk(common_dimm->twr_ps); - - if (wrrec_mclk > 16) - printf("Error: WRREC doesn't support more than 16 clocks\n"); - else - wrrec_mclk = wrrec_table[wrrec_mclk - 1]; - if (popts->otf_burst_chop_en) - wrrec_mclk += 2; - - acttoact_mclk = picos_to_mclk(common_dimm->trrd_ps); - /* - * JEDEC has min requirement for tRRD - */ -#if defined(CONFIG_FSL_DDR3) - if (acttoact_mclk < 4) - acttoact_mclk = 4; -#endif - wrtord_mclk = picos_to_mclk(common_dimm->twtr_ps); - /* - * JEDEC has some min requirements for tWTR - */ -#if defined(CONFIG_FSL_DDR2) - if (wrtord_mclk < 2) - wrtord_mclk = 2; -#elif defined(CONFIG_FSL_DDR3) - if (wrtord_mclk < 4) - wrtord_mclk = 4; -#endif - if (popts->otf_burst_chop_en) - wrtord_mclk += 2; - - ddr->timing_cfg_1 = (0 - | ((pretoact_mclk & 0x0F) << 28) - | ((acttopre_mclk & 0x0F) << 24) - | ((acttorw_mclk & 0xF) << 20) - | ((caslat_ctrl & 0xF) << 16) - | ((refrec_ctrl & 0xF) << 12) - | ((wrrec_mclk & 0x0F) << 8) - | ((acttoact_mclk & 0x0F) << 4) - | ((wrtord_mclk & 0x0F) << 0) - ); - debug("FSLDDR: timing_cfg_1 = 0x%08x\n", ddr->timing_cfg_1); -} - -/* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */ -static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm, - unsigned int cas_latency, - unsigned int additive_latency) -{ - /* Additive latency */ - unsigned char add_lat_mclk; - /* CAS-to-preamble override */ - unsigned short cpo; - /* Write latency */ - unsigned char wr_lat; - /* Read to precharge (tRTP) */ - unsigned char rd_to_pre; - /* Write command to write data strobe timing adjustment */ - unsigned char wr_data_delay; - /* Minimum CKE pulse width (tCKE) */ - unsigned char cke_pls; - /* Window for four activates (tFAW) */ - unsigned short four_act; - - /* FIXME add check that this must be less than acttorw_mclk */ - add_lat_mclk = additive_latency; - cpo = popts->cpo_override; - -#if defined(CONFIG_FSL_DDR1) - /* - * This is a lie. It should really be 1, but if it is - * set to 1, bits overlap into the old controller's - * otherwise unused ACSM field. If we leave it 0, then - * the HW will magically treat it as 1 for DDR 1. Oh Yea. - */ - wr_lat = 0; -#elif defined(CONFIG_FSL_DDR2) - wr_lat = cas_latency - 1; -#else - wr_lat = compute_cas_write_latency(); -#endif - - rd_to_pre = picos_to_mclk(common_dimm->trtp_ps); - /* - * JEDEC has some min requirements for tRTP - */ -#if defined(CONFIG_FSL_DDR2) - if (rd_to_pre < 2) - rd_to_pre = 2; -#elif defined(CONFIG_FSL_DDR3) - if (rd_to_pre < 4) - rd_to_pre = 4; -#endif - if (additive_latency) - rd_to_pre += additive_latency; - if (popts->otf_burst_chop_en) - rd_to_pre += 2; /* according to UM */ - - wr_data_delay = popts->write_data_delay; - cke_pls = picos_to_mclk(popts->tcke_clock_pulse_width_ps); - four_act = picos_to_mclk(popts->tfaw_window_four_activates_ps); - - ddr->timing_cfg_2 = (0 - | ((add_lat_mclk & 0xf) << 28) - | ((cpo & 0x1f) << 23) - | ((wr_lat & 0xf) << 19) - | ((rd_to_pre & RD_TO_PRE_MASK) << RD_TO_PRE_SHIFT) - | ((wr_data_delay & WR_DATA_DELAY_MASK) << WR_DATA_DELAY_SHIFT) - | ((cke_pls & 0x7) << 6) - | ((four_act & 0x3f) << 0) - ); - debug("FSLDDR: timing_cfg_2 = 0x%08x\n", ddr->timing_cfg_2); -} - -/* DDR SDRAM Register Control Word */ -static void set_ddr_sdram_rcw(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm) -{ - if (common_dimm->all_dimms_registered && - !common_dimm->all_dimms_unbuffered) { - if (popts->rcw_override) { - ddr->ddr_sdram_rcw_1 = popts->rcw_1; - ddr->ddr_sdram_rcw_2 = popts->rcw_2; - } else { - ddr->ddr_sdram_rcw_1 = - common_dimm->rcw[0] << 28 | \ - common_dimm->rcw[1] << 24 | \ - common_dimm->rcw[2] << 20 | \ - common_dimm->rcw[3] << 16 | \ - common_dimm->rcw[4] << 12 | \ - common_dimm->rcw[5] << 8 | \ - common_dimm->rcw[6] << 4 | \ - common_dimm->rcw[7]; - ddr->ddr_sdram_rcw_2 = - common_dimm->rcw[8] << 28 | \ - common_dimm->rcw[9] << 24 | \ - common_dimm->rcw[10] << 20 | \ - common_dimm->rcw[11] << 16 | \ - common_dimm->rcw[12] << 12 | \ - common_dimm->rcw[13] << 8 | \ - common_dimm->rcw[14] << 4 | \ - common_dimm->rcw[15]; - } - debug("FSLDDR: ddr_sdram_rcw_1 = 0x%08x\n", ddr->ddr_sdram_rcw_1); - debug("FSLDDR: ddr_sdram_rcw_2 = 0x%08x\n", ddr->ddr_sdram_rcw_2); - } -} - -/* DDR SDRAM control configuration (DDR_SDRAM_CFG) */ -static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm) -{ - unsigned int mem_en; /* DDR SDRAM interface logic enable */ - unsigned int sren; /* Self refresh enable (during sleep) */ - unsigned int ecc_en; /* ECC enable. */ - unsigned int rd_en; /* Registered DIMM enable */ - unsigned int sdram_type; /* Type of SDRAM */ - unsigned int dyn_pwr; /* Dynamic power management mode */ - unsigned int dbw; /* DRAM dta bus width */ - unsigned int eight_be = 0; /* 8-beat burst enable, DDR2 is zero */ - unsigned int ncap = 0; /* Non-concurrent auto-precharge */ - unsigned int threet_en; /* Enable 3T timing */ - unsigned int twot_en; /* Enable 2T timing */ - unsigned int ba_intlv_ctl; /* Bank (CS) interleaving control */ - unsigned int x32_en = 0; /* x32 enable */ - unsigned int pchb8 = 0; /* precharge bit 8 enable */ - unsigned int hse; /* Global half strength override */ - unsigned int mem_halt = 0; /* memory controller halt */ - unsigned int bi = 0; /* Bypass initialization */ - - mem_en = 1; - sren = popts->self_refresh_in_sleep; - if (common_dimm->all_dimms_ecc_capable) { - /* Allow setting of ECC only if all DIMMs are ECC. */ - ecc_en = popts->ecc_mode; - } else { - ecc_en = 0; - } - - if (common_dimm->all_dimms_registered && - !common_dimm->all_dimms_unbuffered) { - rd_en = 1; - twot_en = 0; - } else { - rd_en = 0; - twot_en = popts->twot_en; - } - - sdram_type = CONFIG_FSL_SDRAM_TYPE; - - dyn_pwr = popts->dynamic_power; - dbw = popts->data_bus_width; - /* 8-beat burst enable DDR-III case - * we must clear it when use the on-the-fly mode, - * must set it when use the 32-bits bus mode. - */ - if (sdram_type == SDRAM_TYPE_DDR3) { - if (popts->burst_length == DDR_BL8) - eight_be = 1; - if (popts->burst_length == DDR_OTF) - eight_be = 0; - if (dbw == 0x1) - eight_be = 1; - } - - threet_en = popts->threet_en; - ba_intlv_ctl = popts->ba_intlv_ctl; - hse = popts->half_strength_driver_enable; - - ddr->ddr_sdram_cfg = (0 - | ((mem_en & 0x1) << 31) - | ((sren & 0x1) << 30) - | ((ecc_en & 0x1) << 29) - | ((rd_en & 0x1) << 28) - | ((sdram_type & 0x7) << 24) - | ((dyn_pwr & 0x1) << 21) - | ((dbw & 0x3) << 19) - | ((eight_be & 0x1) << 18) - | ((ncap & 0x1) << 17) - | ((threet_en & 0x1) << 16) - | ((twot_en & 0x1) << 15) - | ((ba_intlv_ctl & 0x7F) << 8) - | ((x32_en & 0x1) << 5) - | ((pchb8 & 0x1) << 4) - | ((hse & 0x1) << 3) - | ((mem_halt & 0x1) << 1) - | ((bi & 0x1) << 0) - ); - debug("FSLDDR: ddr_sdram_cfg = 0x%08x\n", ddr->ddr_sdram_cfg); -} - -/* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */ -static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const unsigned int unq_mrs_en) -{ - unsigned int frc_sr = 0; /* Force self refresh */ - unsigned int sr_ie = 0; /* Self-refresh interrupt enable */ - unsigned int dll_rst_dis; /* DLL reset disable */ - unsigned int dqs_cfg; /* DQS configuration */ - unsigned int odt_cfg = 0; /* ODT configuration */ - unsigned int num_pr; /* Number of posted refreshes */ - unsigned int slow = 0; /* DDR will be run less than 1250 */ - unsigned int x4_en = 0; /* x4 DRAM enable */ - unsigned int obc_cfg; /* On-The-Fly Burst Chop Cfg */ - unsigned int ap_en; /* Address Parity Enable */ - unsigned int d_init; /* DRAM data initialization */ - unsigned int rcw_en = 0; /* Register Control Word Enable */ - unsigned int md_en = 0; /* Mirrored DIMM Enable */ - unsigned int qd_en = 0; /* quad-rank DIMM Enable */ - int i; - - dll_rst_dis = 1; /* Make this configurable */ - dqs_cfg = popts->dqs_config; - for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { - if (popts->cs_local_opts[i].odt_rd_cfg - || popts->cs_local_opts[i].odt_wr_cfg) { - odt_cfg = SDRAM_CFG2_ODT_ONLY_READ; - break; - } - } - - num_pr = 1; /* Make this configurable */ - - /* - * 8572 manual says - * {TIMING_CFG_1[PRETOACT] - * + [DDR_SDRAM_CFG_2[NUM_PR] - * * ({EXT_REFREC || REFREC} + 8 + 2)]} - * << DDR_SDRAM_INTERVAL[REFINT] - */ -#if defined(CONFIG_FSL_DDR3) - obc_cfg = popts->otf_burst_chop_en; -#else - obc_cfg = 0; -#endif - -#if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7) - slow = get_ddr_freq(0) < 1249000000; -#endif - - if (popts->registered_dimm_en) { - rcw_en = 1; - ap_en = popts->ap_en; - } else { - ap_en = 0; - } - - x4_en = popts->x4_en ? 1 : 0; - -#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) - /* Use the DDR controller to auto initialize memory. */ - d_init = popts->ecc_init_using_memctl; - ddr->ddr_data_init = CONFIG_MEM_INIT_VALUE; - debug("DDR: ddr_data_init = 0x%08x\n", ddr->ddr_data_init); -#else - /* Memory will be initialized via DMA, or not at all. */ - d_init = 0; -#endif - -#if defined(CONFIG_FSL_DDR3) - md_en = popts->mirrored_dimm; -#endif - qd_en = popts->quad_rank_present ? 1 : 0; - ddr->ddr_sdram_cfg_2 = (0 - | ((frc_sr & 0x1) << 31) - | ((sr_ie & 0x1) << 30) - | ((dll_rst_dis & 0x1) << 29) - | ((dqs_cfg & 0x3) << 26) - | ((odt_cfg & 0x3) << 21) - | ((num_pr & 0xf) << 12) - | ((slow & 1) << 11) - | (x4_en << 10) - | (qd_en << 9) - | (unq_mrs_en << 8) - | ((obc_cfg & 0x1) << 6) - | ((ap_en & 0x1) << 5) - | ((d_init & 0x1) << 4) - | ((rcw_en & 0x1) << 2) - | ((md_en & 0x1) << 0) - ); - debug("FSLDDR: ddr_sdram_cfg_2 = 0x%08x\n", ddr->ddr_sdram_cfg_2); -} - -/* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ -static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm, - const unsigned int unq_mrs_en) -{ - unsigned short esdmode2 = 0; /* Extended SDRAM mode 2 */ - unsigned short esdmode3 = 0; /* Extended SDRAM mode 3 */ - -#if defined(CONFIG_FSL_DDR3) - int i; - unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ - unsigned int srt = 0; /* self-refresh temerature, normal range */ - unsigned int asr = 0; /* auto self-refresh disable */ - unsigned int cwl = compute_cas_write_latency() - 5; - unsigned int pasr = 0; /* partial array self refresh disable */ - - if (popts->rtt_override) - rtt_wr = popts->rtt_wr_override_value; - else - rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; - - if (common_dimm->extended_op_srt) - srt = common_dimm->extended_op_srt; - - esdmode2 = (0 - | ((rtt_wr & 0x3) << 9) - | ((srt & 0x1) << 7) - | ((asr & 0x1) << 6) - | ((cwl & 0x7) << 3) - | ((pasr & 0x7) << 0)); -#endif - ddr->ddr_sdram_mode_2 = (0 - | ((esdmode2 & 0xFFFF) << 16) - | ((esdmode3 & 0xFFFF) << 0) - ); - debug("FSLDDR: ddr_sdram_mode_2 = 0x%08x\n", ddr->ddr_sdram_mode_2); - -#ifdef CONFIG_FSL_DDR3 - if (unq_mrs_en) { /* unique mode registers are supported */ - for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { - if (popts->rtt_override) - rtt_wr = popts->rtt_wr_override_value; - else - rtt_wr = popts->cs_local_opts[i].odt_rtt_wr; - - esdmode2 &= 0xF9FF; /* clear bit 10, 9 */ - esdmode2 |= (rtt_wr & 0x3) << 9; - switch (i) { - case 1: - ddr->ddr_sdram_mode_4 = (0 - | ((esdmode2 & 0xFFFF) << 16) - | ((esdmode3 & 0xFFFF) << 0) - ); - break; - case 2: - ddr->ddr_sdram_mode_6 = (0 - | ((esdmode2 & 0xFFFF) << 16) - | ((esdmode3 & 0xFFFF) << 0) - ); - break; - case 3: - ddr->ddr_sdram_mode_8 = (0 - | ((esdmode2 & 0xFFFF) << 16) - | ((esdmode3 & 0xFFFF) << 0) - ); - break; - } - } - debug("FSLDDR: ddr_sdram_mode_4 = 0x%08x\n", - ddr->ddr_sdram_mode_4); - debug("FSLDDR: ddr_sdram_mode_6 = 0x%08x\n", - ddr->ddr_sdram_mode_6); - debug("FSLDDR: ddr_sdram_mode_8 = 0x%08x\n", - ddr->ddr_sdram_mode_8); - } -#endif -} - -/* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */ -static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm) -{ - unsigned int refint; /* Refresh interval */ - unsigned int bstopre; /* Precharge interval */ - - refint = picos_to_mclk(common_dimm->refresh_rate_ps); - - bstopre = popts->bstopre; - - /* refint field used 0x3FFF in earlier controllers */ - ddr->ddr_sdram_interval = (0 - | ((refint & 0xFFFF) << 16) - | ((bstopre & 0x3FFF) << 0) - ); - debug("FSLDDR: ddr_sdram_interval = 0x%08x\n", ddr->ddr_sdram_interval); -} - -#if defined(CONFIG_FSL_DDR3) -/* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ -static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm, - unsigned int cas_latency, - unsigned int additive_latency, - const unsigned int unq_mrs_en) -{ - unsigned short esdmode; /* Extended SDRAM mode */ - unsigned short sdmode; /* SDRAM mode */ - - /* Mode Register - MR1 */ - unsigned int qoff = 0; /* Output buffer enable 0=yes, 1=no */ - unsigned int tdqs_en = 0; /* TDQS Enable: 0=no, 1=yes */ - unsigned int rtt; - unsigned int wrlvl_en = 0; /* Write level enable: 0=no, 1=yes */ - unsigned int al = 0; /* Posted CAS# additive latency (AL) */ - unsigned int dic = 0; /* Output driver impedance, 40ohm */ - unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), - 1=Disable (Test/Debug) */ - - /* Mode Register - MR0 */ - unsigned int dll_on; /* DLL control for precharge PD, 0=off, 1=on */ - unsigned int wr = 0; /* Write Recovery */ - unsigned int dll_rst; /* DLL Reset */ - unsigned int mode; /* Normal=0 or Test=1 */ - unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ - /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ - unsigned int bt; - unsigned int bl; /* BL: Burst Length */ - - unsigned int wr_mclk; - /* - * DDR_SDRAM_MODE doesn't support 9,11,13,15 - * Please refer JEDEC Standard No. 79-3E for Mode Register MR0 - * for this table - */ - static const u8 wr_table[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0}; - - const unsigned int mclk_ps = get_memory_clk_period_ps(); - int i; - - if (popts->rtt_override) - rtt = popts->rtt_override_value; - else - rtt = popts->cs_local_opts[0].odt_rtt_norm; - - if (additive_latency == (cas_latency - 1)) - al = 1; - if (additive_latency == (cas_latency - 2)) - al = 2; - - if (popts->quad_rank_present) - dic = 1; /* output driver impedance 240/7 ohm */ - - /* - * The esdmode value will also be used for writing - * MR1 during write leveling for DDR3, although the - * bits specifically related to the write leveling - * scheme will be handled automatically by the DDR - * controller. so we set the wrlvl_en = 0 here. - */ - esdmode = (0 - | ((qoff & 0x1) << 12) - | ((tdqs_en & 0x1) << 11) - | ((rtt & 0x4) << 7) /* rtt field is split */ - | ((wrlvl_en & 0x1) << 7) - | ((rtt & 0x2) << 5) /* rtt field is split */ - | ((dic & 0x2) << 4) /* DIC field is split */ - | ((al & 0x3) << 3) - | ((rtt & 0x1) << 2) /* rtt field is split */ - | ((dic & 0x1) << 1) /* DIC field is split */ - | ((dll_en & 0x1) << 0) - ); - - /* - * DLL control for precharge PD - * 0=slow exit DLL off (tXPDLL) - * 1=fast exit DLL on (tXP) - */ - dll_on = 1; - - wr_mclk = (common_dimm->twr_ps + mclk_ps - 1) / mclk_ps; - if (wr_mclk <= 16) { - wr = wr_table[wr_mclk - 5]; - } else { - printf("Error: unsupported write recovery for mode register " - "wr_mclk = %d\n", wr_mclk); - } - - dll_rst = 0; /* dll no reset */ - mode = 0; /* normal mode */ - - /* look up table to get the cas latency bits */ - if (cas_latency >= 5 && cas_latency <= 16) { - unsigned char cas_latency_table[] = { - 0x2, /* 5 clocks */ - 0x4, /* 6 clocks */ - 0x6, /* 7 clocks */ - 0x8, /* 8 clocks */ - 0xa, /* 9 clocks */ - 0xc, /* 10 clocks */ - 0xe, /* 11 clocks */ - 0x1, /* 12 clocks */ - 0x3, /* 13 clocks */ - 0x5, /* 14 clocks */ - 0x7, /* 15 clocks */ - 0x9, /* 16 clocks */ - }; - caslat = cas_latency_table[cas_latency - 5]; - } else { - printf("Error: unsupported cas latency for mode register\n"); - } - - bt = 0; /* Nibble sequential */ - - switch (popts->burst_length) { - case DDR_BL8: - bl = 0; - break; - case DDR_OTF: - bl = 1; - break; - case DDR_BC4: - bl = 2; - break; - default: - printf("Error: invalid burst length of %u specified. " - " Defaulting to on-the-fly BC4 or BL8 beats.\n", - popts->burst_length); - bl = 1; - break; - } - - sdmode = (0 - | ((dll_on & 0x1) << 12) - | ((wr & 0x7) << 9) - | ((dll_rst & 0x1) << 8) - | ((mode & 0x1) << 7) - | (((caslat >> 1) & 0x7) << 4) - | ((bt & 0x1) << 3) - | ((caslat & 1) << 2) - | ((bl & 0x3) << 0) - ); - - ddr->ddr_sdram_mode = (0 - | ((esdmode & 0xFFFF) << 16) - | ((sdmode & 0xFFFF) << 0) - ); - - debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); - - if (unq_mrs_en) { /* unique mode registers are supported */ - for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { - if (popts->rtt_override) - rtt = popts->rtt_override_value; - else - rtt = popts->cs_local_opts[i].odt_rtt_norm; - - esdmode &= 0xFDBB; /* clear bit 9,6,2 */ - esdmode |= (0 - | ((rtt & 0x4) << 7) /* rtt field is split */ - | ((rtt & 0x2) << 5) /* rtt field is split */ - | ((rtt & 0x1) << 2) /* rtt field is split */ - ); - switch (i) { - case 1: - ddr->ddr_sdram_mode_3 = (0 - | ((esdmode & 0xFFFF) << 16) - | ((sdmode & 0xFFFF) << 0) - ); - break; - case 2: - ddr->ddr_sdram_mode_5 = (0 - | ((esdmode & 0xFFFF) << 16) - | ((sdmode & 0xFFFF) << 0) - ); - break; - case 3: - ddr->ddr_sdram_mode_7 = (0 - | ((esdmode & 0xFFFF) << 16) - | ((sdmode & 0xFFFF) << 0) - ); - break; - } - } - debug("FSLDDR: ddr_sdram_mode_3 = 0x%08x\n", - ddr->ddr_sdram_mode_3); - debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", - ddr->ddr_sdram_mode_5); - debug("FSLDDR: ddr_sdram_mode_5 = 0x%08x\n", - ddr->ddr_sdram_mode_5); - } -} - -#else /* !CONFIG_FSL_DDR3 */ - -/* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ -static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm, - unsigned int cas_latency, - unsigned int additive_latency, - const unsigned int unq_mrs_en) -{ - unsigned short esdmode; /* Extended SDRAM mode */ - unsigned short sdmode; /* SDRAM mode */ - - /* - * FIXME: This ought to be pre-calculated in a - * technology-specific routine, - * e.g. compute_DDR2_mode_register(), and then the - * sdmode and esdmode passed in as part of common_dimm. - */ - - /* Extended Mode Register */ - unsigned int mrs = 0; /* Mode Register Set */ - unsigned int outputs = 0; /* 0=Enabled, 1=Disabled */ - unsigned int rdqs_en = 0; /* RDQS Enable: 0=no, 1=yes */ - unsigned int dqs_en = 0; /* DQS# Enable: 0=enable, 1=disable */ - unsigned int ocd = 0; /* 0x0=OCD not supported, - 0x7=OCD default state */ - unsigned int rtt; - unsigned int al; /* Posted CAS# additive latency (AL) */ - unsigned int ods = 0; /* Output Drive Strength: - 0 = Full strength (18ohm) - 1 = Reduced strength (4ohm) */ - unsigned int dll_en = 0; /* DLL Enable 0=Enable (Normal), - 1=Disable (Test/Debug) */ - - /* Mode Register (MR) */ - unsigned int mr; /* Mode Register Definition */ - unsigned int pd; /* Power-Down Mode */ - unsigned int wr; /* Write Recovery */ - unsigned int dll_res; /* DLL Reset */ - unsigned int mode; /* Normal=0 or Test=1 */ - unsigned int caslat = 0;/* CAS# latency */ - /* BT: Burst Type (0=Sequential, 1=Interleaved) */ - unsigned int bt; - unsigned int bl; /* BL: Burst Length */ - -#if defined(CONFIG_FSL_DDR2) - const unsigned int mclk_ps = get_memory_clk_period_ps(); -#endif - dqs_en = !popts->dqs_config; - rtt = fsl_ddr_get_rtt(); - - al = additive_latency; - - esdmode = (0 - | ((mrs & 0x3) << 14) - | ((outputs & 0x1) << 12) - | ((rdqs_en & 0x1) << 11) - | ((dqs_en & 0x1) << 10) - | ((ocd & 0x7) << 7) - | ((rtt & 0x2) << 5) /* rtt field is split */ - | ((al & 0x7) << 3) - | ((rtt & 0x1) << 2) /* rtt field is split */ - | ((ods & 0x1) << 1) - | ((dll_en & 0x1) << 0) - ); - - mr = 0; /* FIXME: CHECKME */ - - /* - * 0 = Fast Exit (Normal) - * 1 = Slow Exit (Low Power) - */ - pd = 0; - -#if defined(CONFIG_FSL_DDR1) - wr = 0; /* Historical */ -#elif defined(CONFIG_FSL_DDR2) - wr = (common_dimm->twr_ps + mclk_ps - 1) / mclk_ps - 1; -#endif - dll_res = 0; - mode = 0; - -#if defined(CONFIG_FSL_DDR1) - if (1 <= cas_latency && cas_latency <= 4) { - unsigned char mode_caslat_table[4] = { - 0x5, /* 1.5 clocks */ - 0x2, /* 2.0 clocks */ - 0x6, /* 2.5 clocks */ - 0x3 /* 3.0 clocks */ - }; - caslat = mode_caslat_table[cas_latency - 1]; - } else { - printf("Warning: unknown cas_latency %d\n", cas_latency); - } -#elif defined(CONFIG_FSL_DDR2) - caslat = cas_latency; -#endif - bt = 0; - - switch (popts->burst_length) { - case DDR_BL4: - bl = 2; - break; - case DDR_BL8: - bl = 3; - break; - default: - printf("Error: invalid burst length of %u specified. " - " Defaulting to 4 beats.\n", - popts->burst_length); - bl = 2; - break; - } - - sdmode = (0 - | ((mr & 0x3) << 14) - | ((pd & 0x1) << 12) - | ((wr & 0x7) << 9) - | ((dll_res & 0x1) << 8) - | ((mode & 0x1) << 7) - | ((caslat & 0x7) << 4) - | ((bt & 0x1) << 3) - | ((bl & 0x7) << 0) - ); - - ddr->ddr_sdram_mode = (0 - | ((esdmode & 0xFFFF) << 16) - | ((sdmode & 0xFFFF) << 0) - ); - debug("FSLDDR: ddr_sdram_mode = 0x%08x\n", ddr->ddr_sdram_mode); -} -#endif - -/* DDR SDRAM Data Initialization (DDR_DATA_INIT) */ -static void set_ddr_data_init(fsl_ddr_cfg_regs_t *ddr) -{ - unsigned int init_value; /* Initialization value */ - -#ifdef CONFIG_MEM_INIT_VALUE - init_value = CONFIG_MEM_INIT_VALUE; -#else - init_value = 0xDEADBEEF; -#endif - ddr->ddr_data_init = init_value; -} - -/* - * DDR SDRAM Clock Control (DDR_SDRAM_CLK_CNTL) - * The old controller on the 8540/60 doesn't have this register. - * Hope it's OK to set it (to 0) anyway. - */ -static void set_ddr_sdram_clk_cntl(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts) -{ - unsigned int clk_adjust; /* Clock adjust */ - - clk_adjust = popts->clk_adjust; - ddr->ddr_sdram_clk_cntl = (clk_adjust & 0xF) << 23; - debug("FSLDDR: clk_cntl = 0x%08x\n", ddr->ddr_sdram_clk_cntl); -} - -/* DDR Initialization Address (DDR_INIT_ADDR) */ -static void set_ddr_init_addr(fsl_ddr_cfg_regs_t *ddr) -{ - unsigned int init_addr = 0; /* Initialization address */ - - ddr->ddr_init_addr = init_addr; -} - -/* DDR Initialization Address (DDR_INIT_EXT_ADDR) */ -static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr) -{ - unsigned int uia = 0; /* Use initialization address */ - unsigned int init_ext_addr = 0; /* Initialization address */ - - ddr->ddr_init_ext_addr = (0 - | ((uia & 0x1) << 31) - | (init_ext_addr & 0xF) - ); -} - -/* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */ -static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts) -{ - unsigned int rwt = 0; /* Read-to-write turnaround for same CS */ - unsigned int wrt = 0; /* Write-to-read turnaround for same CS */ - unsigned int rrt = 0; /* Read-to-read turnaround for same CS */ - unsigned int wwt = 0; /* Write-to-write turnaround for same CS */ - unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */ - -#if defined(CONFIG_FSL_DDR3) - if (popts->burst_length == DDR_BL8) { - /* We set BL/2 for fixed BL8 */ - rrt = 0; /* BL/2 clocks */ - wwt = 0; /* BL/2 clocks */ - } else { - /* We need to set BL/2 + 2 to BC4 and OTF */ - rrt = 2; /* BL/2 + 2 clocks */ - wwt = 2; /* BL/2 + 2 clocks */ - } - dll_lock = 1; /* tDLLK = 512 clocks from spec */ -#endif - ddr->timing_cfg_4 = (0 - | ((rwt & 0xf) << 28) - | ((wrt & 0xf) << 24) - | ((rrt & 0xf) << 20) - | ((wwt & 0xf) << 16) - | (dll_lock & 0x3) - ); - debug("FSLDDR: timing_cfg_4 = 0x%08x\n", ddr->timing_cfg_4); -} - -/* DDR SDRAM Timing Configuration 5 (TIMING_CFG_5) */ -static void set_timing_cfg_5(fsl_ddr_cfg_regs_t *ddr, unsigned int cas_latency) -{ - unsigned int rodt_on = 0; /* Read to ODT on */ - unsigned int rodt_off = 0; /* Read to ODT off */ - unsigned int wodt_on = 0; /* Write to ODT on */ - unsigned int wodt_off = 0; /* Write to ODT off */ - -#if defined(CONFIG_FSL_DDR3) - /* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */ - rodt_on = cas_latency - ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 1; - rodt_off = 4; /* 4 clocks */ - wodt_on = 1; /* 1 clocks */ - wodt_off = 4; /* 4 clocks */ -#endif - - ddr->timing_cfg_5 = (0 - | ((rodt_on & 0x1f) << 24) - | ((rodt_off & 0x7) << 20) - | ((wodt_on & 0x1f) << 12) - | ((wodt_off & 0x7) << 8) - ); - debug("FSLDDR: timing_cfg_5 = 0x%08x\n", ddr->timing_cfg_5); -} - -/* DDR ZQ Calibration Control (DDR_ZQ_CNTL) */ -static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en) -{ - unsigned int zqinit = 0;/* POR ZQ Calibration Time (tZQinit) */ - /* Normal Operation Full Calibration Time (tZQoper) */ - unsigned int zqoper = 0; - /* Normal Operation Short Calibration Time (tZQCS) */ - unsigned int zqcs = 0; - - if (zq_en) { - zqinit = 9; /* 512 clocks */ - zqoper = 8; /* 256 clocks */ - zqcs = 6; /* 64 clocks */ - } - - ddr->ddr_zq_cntl = (0 - | ((zq_en & 0x1) << 31) - | ((zqinit & 0xF) << 24) - | ((zqoper & 0xF) << 16) - | ((zqcs & 0xF) << 8) - ); - debug("FSLDDR: zq_cntl = 0x%08x\n", ddr->ddr_zq_cntl); -} - -/* DDR Write Leveling Control (DDR_WRLVL_CNTL) */ -static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en, - const memctl_options_t *popts) -{ - /* - * First DQS pulse rising edge after margining mode - * is programmed (tWL_MRD) - */ - unsigned int wrlvl_mrd = 0; - /* ODT delay after margining mode is programmed (tWL_ODTEN) */ - unsigned int wrlvl_odten = 0; - /* DQS/DQS_ delay after margining mode is programmed (tWL_DQSEN) */ - unsigned int wrlvl_dqsen = 0; - /* WRLVL_SMPL: Write leveling sample time */ - unsigned int wrlvl_smpl = 0; - /* WRLVL_WLR: Write leveling repeition time */ - unsigned int wrlvl_wlr = 0; - /* WRLVL_START: Write leveling start time */ - unsigned int wrlvl_start = 0; - - /* suggest enable write leveling for DDR3 due to fly-by topology */ - if (wrlvl_en) { - /* tWL_MRD min = 40 nCK, we set it 64 */ - wrlvl_mrd = 0x6; - /* tWL_ODTEN 128 */ - wrlvl_odten = 0x7; - /* tWL_DQSEN min = 25 nCK, we set it 32 */ - wrlvl_dqsen = 0x5; - /* - * Write leveling sample time at least need 6 clocks - * higher than tWLO to allow enough time for progagation - * delay and sampling the prime data bits. - */ - wrlvl_smpl = 0xf; - /* - * Write leveling repetition time - * at least tWLO + 6 clocks clocks - * we set it 64 - */ - wrlvl_wlr = 0x6; - /* - * Write leveling start time - * The value use for the DQS_ADJUST for the first sample - * when write leveling is enabled. It probably needs to be - * overriden per platform. - */ - wrlvl_start = 0x8; - /* - * Override the write leveling sample and start time - * according to specific board - */ - if (popts->wrlvl_override) { - wrlvl_smpl = popts->wrlvl_sample; - wrlvl_start = popts->wrlvl_start; - } - } - - ddr->ddr_wrlvl_cntl = (0 - | ((wrlvl_en & 0x1) << 31) - | ((wrlvl_mrd & 0x7) << 24) - | ((wrlvl_odten & 0x7) << 20) - | ((wrlvl_dqsen & 0x7) << 16) - | ((wrlvl_smpl & 0xf) << 12) - | ((wrlvl_wlr & 0x7) << 8) - | ((wrlvl_start & 0x1F) << 0) - ); - debug("FSLDDR: wrlvl_cntl = 0x%08x\n", ddr->ddr_wrlvl_cntl); - ddr->ddr_wrlvl_cntl_2 = popts->wrlvl_ctl_2; - debug("FSLDDR: wrlvl_cntl_2 = 0x%08x\n", ddr->ddr_wrlvl_cntl_2); - ddr->ddr_wrlvl_cntl_3 = popts->wrlvl_ctl_3; - debug("FSLDDR: wrlvl_cntl_3 = 0x%08x\n", ddr->ddr_wrlvl_cntl_3); - -} - -/* DDR Self Refresh Counter (DDR_SR_CNTR) */ -static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it) -{ - /* Self Refresh Idle Threshold */ - ddr->ddr_sr_cntr = (sr_it & 0xF) << 16; -} - -static void set_ddr_eor(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) -{ - if (popts->addr_hash) { - ddr->ddr_eor = 0x40000000; /* address hash enable */ - puts("Address hashing enabled.\n"); - } -} - -static void set_ddr_cdr1(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) -{ - ddr->ddr_cdr1 = popts->ddr_cdr1; - debug("FSLDDR: ddr_cdr1 = 0x%08x\n", ddr->ddr_cdr1); -} - -static void set_ddr_cdr2(fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts) -{ - ddr->ddr_cdr2 = popts->ddr_cdr2; - debug("FSLDDR: ddr_cdr2 = 0x%08x\n", ddr->ddr_cdr2); -} - -unsigned int -check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) -{ - unsigned int res = 0; - - /* - * Check that DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] are - * not set at the same time. - */ - if (ddr->ddr_sdram_cfg & 0x10000000 - && ddr->ddr_sdram_cfg & 0x00008000) { - printf("Error: DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN] " - " should not be set at the same time.\n"); - res++; - } - - return res; -} - -unsigned int -compute_fsl_memctl_config_regs(const memctl_options_t *popts, - fsl_ddr_cfg_regs_t *ddr, - const common_timing_params_t *common_dimm, - const dimm_params_t *dimm_params, - unsigned int dbw_cap_adj, - unsigned int size_only) -{ - unsigned int i; - unsigned int cas_latency; - unsigned int additive_latency; - unsigned int sr_it; - unsigned int zq_en; - unsigned int wrlvl_en; - unsigned int ip_rev = 0; - unsigned int unq_mrs_en = 0; - int cs_en = 1; - - memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t)); - - if (common_dimm == NULL) { - printf("Error: subset DIMM params struct null pointer\n"); - return 1; - } - - /* - * Process overrides first. - * - * FIXME: somehow add dereated caslat to this - */ - cas_latency = (popts->cas_latency_override) - ? popts->cas_latency_override_value - : common_dimm->lowest_common_SPD_caslat; - - additive_latency = (popts->additive_latency_override) - ? popts->additive_latency_override_value - : common_dimm->additive_latency; - - sr_it = (popts->auto_self_refresh_en) - ? popts->sr_it - : 0; - /* ZQ calibration */ - zq_en = (popts->zq_en) ? 1 : 0; - /* write leveling */ - wrlvl_en = (popts->wrlvl_en) ? 1 : 0; - - /* Chip Select Memory Bounds (CSn_BNDS) */ - for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { - unsigned long long ea, sa; - unsigned int cs_per_dimm - = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; - unsigned int dimm_number - = i / cs_per_dimm; - unsigned long long rank_density - = dimm_params[dimm_number].rank_density >> dbw_cap_adj; - - if (dimm_params[dimm_number].n_ranks == 0) { - debug("Skipping setup of CS%u " - "because n_ranks on DIMM %u is 0\n", i, dimm_number); - continue; - } - if (popts->memctl_interleaving) { - switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { - case FSL_DDR_CS0_CS1_CS2_CS3: - break; - case FSL_DDR_CS0_CS1: - case FSL_DDR_CS0_CS1_AND_CS2_CS3: - if (i > 1) - cs_en = 0; - break; - case FSL_DDR_CS2_CS3: - default: - if (i > 0) - cs_en = 0; - break; - } - sa = common_dimm->base_address; - ea = sa + common_dimm->total_mem - 1; - } else if (!popts->memctl_interleaving) { - /* - * If memory interleaving between controllers is NOT - * enabled, the starting address for each memory - * controller is distinct. However, because rank - * interleaving is enabled, the starting and ending - * addresses of the total memory on that memory - * controller needs to be programmed into its - * respective CS0_BNDS. - */ - switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { - case FSL_DDR_CS0_CS1_CS2_CS3: - sa = common_dimm->base_address; - ea = sa + common_dimm->total_mem - 1; - break; - case FSL_DDR_CS0_CS1_AND_CS2_CS3: - if ((i >= 2) && (dimm_number == 0)) { - sa = dimm_params[dimm_number].base_address + - 2 * rank_density; - ea = sa + 2 * rank_density - 1; - } else { - sa = dimm_params[dimm_number].base_address; - ea = sa + 2 * rank_density - 1; - } - break; - case FSL_DDR_CS0_CS1: - if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { - sa = dimm_params[dimm_number].base_address; - ea = sa + rank_density - 1; - if (i != 1) - sa += (i % cs_per_dimm) * rank_density; - ea += (i % cs_per_dimm) * rank_density; - } else { - sa = 0; - ea = 0; - } - if (i == 0) - ea += rank_density; - break; - case FSL_DDR_CS2_CS3: - if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { - sa = dimm_params[dimm_number].base_address; - ea = sa + rank_density - 1; - if (i != 3) - sa += (i % cs_per_dimm) * rank_density; - ea += (i % cs_per_dimm) * rank_density; - } else { - sa = 0; - ea = 0; - } - if (i == 2) - ea += (rank_density >> dbw_cap_adj); - break; - default: /* No bank(chip-select) interleaving */ - sa = dimm_params[dimm_number].base_address; - ea = sa + rank_density - 1; - if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { - sa += (i % cs_per_dimm) * rank_density; - ea += (i % cs_per_dimm) * rank_density; - } else { - sa = 0; - ea = 0; - } - break; - } - } - - sa >>= 24; - ea >>= 24; - - if (cs_en) { - ddr->cs[i].bnds = (0 - | ((sa & 0xFFF) << 16)/* starting address MSB */ - | ((ea & 0xFFF) << 0) /* ending address MSB */ - ); - } else { - /* setting bnds to 0xffffffff for inactive CS */ - ddr->cs[i].bnds = 0xffffffff; - } - - debug("FSLDDR: cs[%d]_bnds = 0x%08x\n", i, ddr->cs[i].bnds); - set_csn_config(dimm_number, i, ddr, popts, dimm_params); - set_csn_config_2(i, ddr); - } - - /* - * In the case we only need to compute the ddr sdram size, we only need - * to set csn registers, so return from here. - */ - if (size_only) - return 0; - - set_ddr_eor(ddr, popts); - -#if !defined(CONFIG_FSL_DDR1) - set_timing_cfg_0(ddr, popts, dimm_params); -#endif - - set_timing_cfg_3(ddr, popts, common_dimm, cas_latency); - set_timing_cfg_1(ddr, popts, common_dimm, cas_latency); - set_timing_cfg_2(ddr, popts, common_dimm, - cas_latency, additive_latency); - - set_ddr_cdr1(ddr, popts); - set_ddr_cdr2(ddr, popts); - set_ddr_sdram_cfg(ddr, popts, common_dimm); - ip_rev = fsl_ddr_get_version(); - if (ip_rev > 0x40400) - unq_mrs_en = 1; - - set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en); - set_ddr_sdram_mode(ddr, popts, common_dimm, - cas_latency, additive_latency, unq_mrs_en); - set_ddr_sdram_mode_2(ddr, popts, common_dimm, unq_mrs_en); - set_ddr_sdram_interval(ddr, popts, common_dimm); - set_ddr_data_init(ddr); - set_ddr_sdram_clk_cntl(ddr, popts); - set_ddr_init_addr(ddr); - set_ddr_init_ext_addr(ddr); - set_timing_cfg_4(ddr, popts); - set_timing_cfg_5(ddr, cas_latency); - - set_ddr_zq_cntl(ddr, zq_en); - set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts); - - set_ddr_sr_cntr(ddr, sr_it); - - set_ddr_sdram_rcw(ddr, popts, common_dimm); - -#ifdef CONFIG_SYS_FSL_DDR_EMU - /* disble DDR training for emulator */ - ddr->debug[2] = 0x00000400; - ddr->debug[4] = 0xff800000; -#endif - return check_fsl_memctl_config_regs(ddr); -} diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h b/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h deleted file mode 100644 index e3b414e..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2008-2011 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -#ifndef FSL_DDR_MAIN_H -#define FSL_DDR_MAIN_H - -#include <asm/fsl_ddr_sdram.h> -#include <asm/fsl_ddr_dimm_params.h> - -#include "common_timing_params.h" - -#if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM) -/* - * Bind the main DDR setup driver's generic names - * to this specific DDR technology. - */ -static __inline__ int -compute_dimm_parameters(const generic_spd_eeprom_t *spd, - dimm_params_t *pdimm, - unsigned int dimm_number) -{ - return ddr_compute_dimm_parameters(spd, pdimm, dimm_number); -} -#endif - -/* - * Data Structures - * - * All data structures have to be on the stack - */ -#define CONFIG_SYS_NUM_DDR_CTLRS CONFIG_NUM_DDR_CONTROLLERS -#define CONFIG_SYS_DIMM_SLOTS_PER_CTLR CONFIG_DIMM_SLOTS_PER_CTLR - -typedef struct { - generic_spd_eeprom_t - spd_installed_dimms[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_SYS_DIMM_SLOTS_PER_CTLR]; - struct dimm_params_s - dimm_params[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_SYS_DIMM_SLOTS_PER_CTLR]; - memctl_options_t memctl_opts[CONFIG_SYS_NUM_DDR_CTLRS]; - common_timing_params_t common_timing_params[CONFIG_SYS_NUM_DDR_CTLRS]; - fsl_ddr_cfg_regs_t fsl_ddr_config_reg[CONFIG_SYS_NUM_DDR_CTLRS]; -} fsl_ddr_info_t; - -/* Compute steps */ -#define STEP_GET_SPD (1 << 0) -#define STEP_COMPUTE_DIMM_PARMS (1 << 1) -#define STEP_COMPUTE_COMMON_PARMS (1 << 2) -#define STEP_GATHER_OPTS (1 << 3) -#define STEP_ASSIGN_ADDRESSES (1 << 4) -#define STEP_COMPUTE_REGS (1 << 5) -#define STEP_PROGRAM_REGS (1 << 6) -#define STEP_ALL 0xFFF - -unsigned long long -fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, - unsigned int size_only); - -const char *step_to_string(unsigned int step); - -unsigned int compute_fsl_memctl_config_regs(const memctl_options_t *popts, - fsl_ddr_cfg_regs_t *ddr, - const common_timing_params_t *common_dimm, - const dimm_params_t *dimm_parameters, - unsigned int dbw_capacity_adjust, - unsigned int size_only); -unsigned int compute_lowest_common_dimm_parameters( - const dimm_params_t *dimm_params, - common_timing_params_t *outpdimm, - unsigned int number_of_dimms); -unsigned int populate_memctl_options(int all_dimms_registered, - memctl_options_t *popts, - dimm_params_t *pdimm, - unsigned int ctrl_num); -void check_interleaving_options(fsl_ddr_info_t *pinfo); - -unsigned int mclk_to_picos(unsigned int mclk); -unsigned int get_memory_clk_period_ps(void); -unsigned int picos_to_mclk(unsigned int picos); -void fsl_ddr_set_lawbar( - const common_timing_params_t *memctl_common_params, - unsigned int memctl_interleaved, - unsigned int ctrl_num); - -int fsl_ddr_interactive_env_var_exists(void); -unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set); -void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, - unsigned int ctrl_num); - -int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); -unsigned int check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr); - -/* processor specific function */ -void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, - unsigned int ctrl_num, int step); - -/* board specific function */ -int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, - unsigned int controller_number, - unsigned int dimm_number); -#endif diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr1_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr1_dimm_params.c deleted file mode 100644 index f137fce..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr1_dimm_params.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright 2008 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -#include <common.h> -#include <asm/fsl_ddr_sdram.h> - -#include "ddr.h" - -/* - * Calculate the Density of each Physical Rank. - * Returned size is in bytes. - * - * Study these table from Byte 31 of JEDEC SPD Spec. - * - * DDR I DDR II - * Bit Size Size - * --- ----- ------ - * 7 high 512MB 512MB - * 6 256MB 256MB - * 5 128MB 128MB - * 4 64MB 16GB - * 3 32MB 8GB - * 2 16MB 4GB - * 1 2GB 2GB - * 0 low 1GB 1GB - * - * Reorder Table to be linear by stripping the bottom - * 2 or 5 bits off and shifting them up to the top. - */ - -static unsigned long long -compute_ranksize(unsigned int mem_type, unsigned char row_dens) -{ - unsigned long long bsize; - - /* Bottom 2 bits up to the top. */ - bsize = ((row_dens >> 2) | ((row_dens & 3) << 6)); - bsize <<= 24ULL; - debug("DDR: DDR I rank density = 0x%16llx\n", bsize); - - return bsize; -} - -/* - * Convert a two-nibble BCD value into a cycle time. - * While the spec calls for nano-seconds, picos are returned. - * - * This implements the tables for bytes 9, 23 and 25 for both - * DDR I and II. No allowance for distinguishing the invalid - * fields absent for DDR I yet present in DDR II is made. - * (That is, cycle times of .25, .33, .66 and .75 ns are - * allowed for both DDR II and I.) - */ -static unsigned int -convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) -{ - /* Table look up the lower nibble, allow DDR I & II. */ - unsigned int tenths_ps[16] = { - 0, - 100, - 200, - 300, - 400, - 500, - 600, - 700, - 800, - 900, - 250, /* This and the next 3 entries valid ... */ - 330, /* ... only for tCK calculations. */ - 660, - 750, - 0, /* undefined */ - 0 /* undefined */ - }; - - unsigned int whole_ns = (spd_val & 0xF0) >> 4; - unsigned int tenth_ns = spd_val & 0x0F; - unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns]; - - return ps; -} - -static unsigned int -convert_bcd_hundredths_to_cycle_time_ps(unsigned int spd_val) -{ - unsigned int tenth_ns = (spd_val & 0xF0) >> 4; - unsigned int hundredth_ns = spd_val & 0x0F; - unsigned int ps = tenth_ns * 100 + hundredth_ns * 10; - - return ps; -} - -static unsigned int byte40_table_ps[8] = { - 0, - 250, - 330, - 500, - 660, - 750, - 0, /* supposed to be RFC, but not sure what that means */ - 0 /* Undefined */ -}; - -static unsigned int -compute_trfc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trfc) -{ - unsigned int trfc_ps; - - trfc_ps = (((trctrfc_ext & 0x1) * 256) + trfc) * 1000 - + byte40_table_ps[(trctrfc_ext >> 1) & 0x7]; - - return trfc_ps; -} - -static unsigned int -compute_trc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trc) -{ - unsigned int trc_ps; - - trc_ps = trc * 1000 + byte40_table_ps[(trctrfc_ext >> 4) & 0x7]; - - return trc_ps; -} - -/* - * tCKmax from DDR I SPD Byte 43 - * - * Bits 7:2 == whole ns - * Bits 1:0 == quarter ns - * 00 == 0.00 ns - * 01 == 0.25 ns - * 10 == 0.50 ns - * 11 == 0.75 ns - * - * Returns picoseconds. - */ -static unsigned int -compute_tckmax_from_spd_ps(unsigned int byte43) -{ - return (byte43 >> 2) * 1000 + (byte43 & 0x3) * 250; -} - -/* - * Determine Refresh Rate. Ignore self refresh bit on DDR I. - * Table from SPD Spec, Byte 12, converted to picoseconds and - * filled in with "default" normal values. - */ -static unsigned int -determine_refresh_rate_ps(const unsigned int spd_refresh) -{ - unsigned int refresh_time_ps[8] = { - 15625000, /* 0 Normal 1.00x */ - 3900000, /* 1 Reduced .25x */ - 7800000, /* 2 Extended .50x */ - 31300000, /* 3 Extended 2.00x */ - 62500000, /* 4 Extended 4.00x */ - 125000000, /* 5 Extended 8.00x */ - 15625000, /* 6 Normal 1.00x filler */ - 15625000, /* 7 Normal 1.00x filler */ - }; - - return refresh_time_ps[spd_refresh & 0x7]; -} - -/* - * The purpose of this function is to compute a suitable - * CAS latency given the DRAM clock period. The SPD only - * defines at most 3 CAS latencies. Typically the slower in - * frequency the DIMM runs at, the shorter its CAS latency can be. - * If the DIMM is operating at a sufficiently low frequency, - * it may be able to run at a CAS latency shorter than the - * shortest SPD-defined CAS latency. - * - * If a CAS latency is not found, 0 is returned. - * - * Do this by finding in the standard speed bin table the longest - * tCKmin that doesn't exceed the value of mclk_ps (tCK). - * - * An assumption made is that the SDRAM device allows the - * CL to be programmed for a value that is lower than those - * advertised by the SPD. This is not always the case, - * as those modes not defined in the SPD are optional. - * - * CAS latency de-rating based upon values JEDEC Standard No. 79-E - * Table 11. - * - * ordinal 2, ddr1_speed_bins[1] contains tCK for CL=2 - */ - /* CL2.0 CL2.5 CL3.0 */ -unsigned short ddr1_speed_bins[] = {0, 7500, 6000, 5000 }; - -unsigned int -compute_derated_DDR1_CAS_latency(unsigned int mclk_ps) -{ - const unsigned int num_speed_bins = ARRAY_SIZE(ddr1_speed_bins); - unsigned int lowest_tCKmin_found = 0; - unsigned int lowest_tCKmin_CL = 0; - unsigned int i; - - debug("mclk_ps = %u\n", mclk_ps); - - for (i = 0; i < num_speed_bins; i++) { - unsigned int x = ddr1_speed_bins[i]; - debug("i=%u, x = %u, lowest_tCKmin_found = %u\n", - i, x, lowest_tCKmin_found); - if (x && lowest_tCKmin_found <= x && x <= mclk_ps) { - lowest_tCKmin_found = x; - lowest_tCKmin_CL = i + 1; - } - } - - debug("lowest_tCKmin_CL = %u\n", lowest_tCKmin_CL); - - return lowest_tCKmin_CL; -} - -/* - * ddr_compute_dimm_parameters for DDR1 SPD - * - * Compute DIMM parameters based upon the SPD information in spd. - * Writes the results to the dimm_params_t structure pointed by pdimm. - * - * FIXME: use #define for the retvals - */ -unsigned int -ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd, - dimm_params_t *pdimm, - unsigned int dimm_number) -{ - unsigned int retval; - - if (spd->mem_type) { - if (spd->mem_type != SPD_MEMTYPE_DDR) { - printf("DIMM %u: is not a DDR1 SPD.\n", dimm_number); - return 1; - } - } else { - memset(pdimm, 0, sizeof(dimm_params_t)); - return 1; - } - - retval = ddr1_spd_check(spd); - if (retval) { - printf("DIMM %u: failed checksum\n", dimm_number); - return 2; - } - - /* - * The part name in ASCII in the SPD EEPROM is not null terminated. - * Guarantee null termination here by presetting all bytes to 0 - * and copying the part name in ASCII from the SPD onto it - */ - memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); - memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1); - - /* DIMM organization parameters */ - pdimm->n_ranks = spd->nrows; - pdimm->rank_density = compute_ranksize(spd->mem_type, spd->bank_dens); - pdimm->capacity = pdimm->n_ranks * pdimm->rank_density; - pdimm->data_width = spd->dataw_lsb; - pdimm->primary_sdram_width = spd->primw; - pdimm->ec_sdram_width = spd->ecw; - - /* - * FIXME: Need to determine registered_dimm status. - * 1 == register buffered - * 0 == unbuffered - */ - pdimm->registered_dimm = 0; /* unbuffered */ - - /* SDRAM device parameters */ - pdimm->n_row_addr = spd->nrow_addr; - pdimm->n_col_addr = spd->ncol_addr; - pdimm->n_banks_per_sdram_device = spd->nbanks; - pdimm->edc_config = spd->config; - pdimm->burst_lengths_bitmask = spd->burstl; - pdimm->row_density = spd->bank_dens; - - /* - * Calculate the Maximum Data Rate based on the Minimum Cycle time. - * The SPD clk_cycle field (tCKmin) is measured in tenths of - * nanoseconds and represented as BCD. - */ - pdimm->tckmin_x_ps - = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle); - pdimm->tckmin_x_minus_1_ps - = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle2); - pdimm->tckmin_x_minus_2_ps - = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle3); - - pdimm->tckmax_ps = compute_tckmax_from_spd_ps(spd->tckmax); - - /* - * Compute CAS latencies defined by SPD - * The SPD caslat_x should have at least 1 and at most 3 bits set. - * - * If cas_lat after masking is 0, the __ilog2 function returns - * 255 into the variable. This behavior is abused once. - */ - pdimm->caslat_x = __ilog2(spd->cas_lat); - pdimm->caslat_x_minus_1 = __ilog2(spd->cas_lat - & ~(1 << pdimm->caslat_x)); - pdimm->caslat_x_minus_2 = __ilog2(spd->cas_lat - & ~(1 << pdimm->caslat_x) - & ~(1 << pdimm->caslat_x_minus_1)); - - /* Compute CAS latencies below that defined by SPD */ - pdimm->caslat_lowest_derated - = compute_derated_DDR1_CAS_latency(get_memory_clk_period_ps()); - - /* Compute timing parameters */ - pdimm->trcd_ps = spd->trcd * 250; - pdimm->trp_ps = spd->trp * 250; - pdimm->tras_ps = spd->tras * 1000; - - pdimm->twr_ps = mclk_to_picos(3); - pdimm->twtr_ps = mclk_to_picos(1); - pdimm->trfc_ps = compute_trfc_ps_from_spd(0, spd->trfc); - - pdimm->trrd_ps = spd->trrd * 250; - pdimm->trc_ps = compute_trc_ps_from_spd(0, spd->trc); - - pdimm->refresh_rate_ps = determine_refresh_rate_ps(spd->refresh); - - pdimm->tis_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_setup); - pdimm->tih_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_hold); - pdimm->tds_ps - = convert_bcd_hundredths_to_cycle_time_ps(spd->data_setup); - pdimm->tdh_ps - = convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold); - - pdimm->trtp_ps = mclk_to_picos(2); /* By the book. */ - pdimm->tdqsq_max_ps = spd->tdqsq * 10; - pdimm->tqhs_ps = spd->tqhs * 10; - - return 0; -} diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr2_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr2_dimm_params.c deleted file mode 100644 index e4d02e8..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr2_dimm_params.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright 2008 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -#include <common.h> -#include <asm/fsl_ddr_sdram.h> - -#include "ddr.h" -/* - * Calculate the Density of each Physical Rank. - * Returned size is in bytes. - * - * Study these table from Byte 31 of JEDEC SPD Spec. - * - * DDR I DDR II - * Bit Size Size - * --- ----- ------ - * 7 high 512MB 512MB - * 6 256MB 256MB - * 5 128MB 128MB - * 4 64MB 16GB - * 3 32MB 8GB - * 2 16MB 4GB - * 1 2GB 2GB - * 0 low 1GB 1GB - * - * Reorder Table to be linear by stripping the bottom - * 2 or 5 bits off and shifting them up to the top. - * - */ -static unsigned long long -compute_ranksize(unsigned int mem_type, unsigned char row_dens) -{ - unsigned long long bsize; - - /* Bottom 5 bits up to the top. */ - bsize = ((row_dens >> 5) | ((row_dens & 31) << 3)); - bsize <<= 27ULL; - debug("DDR: DDR II rank density = 0x%16llx\n", bsize); - - return bsize; -} - -/* - * Convert a two-nibble BCD value into a cycle time. - * While the spec calls for nano-seconds, picos are returned. - * - * This implements the tables for bytes 9, 23 and 25 for both - * DDR I and II. No allowance for distinguishing the invalid - * fields absent for DDR I yet present in DDR II is made. - * (That is, cycle times of .25, .33, .66 and .75 ns are - * allowed for both DDR II and I.) - */ -static unsigned int -convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val) -{ - /* Table look up the lower nibble, allow DDR I & II. */ - unsigned int tenths_ps[16] = { - 0, - 100, - 200, - 300, - 400, - 500, - 600, - 700, - 800, - 900, - 250, /* This and the next 3 entries valid ... */ - 330, /* ... only for tCK calculations. */ - 660, - 750, - 0, /* undefined */ - 0 /* undefined */ - }; - - unsigned int whole_ns = (spd_val & 0xF0) >> 4; - unsigned int tenth_ns = spd_val & 0x0F; - unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns]; - - return ps; -} - -static unsigned int -convert_bcd_hundredths_to_cycle_time_ps(unsigned int spd_val) -{ - unsigned int tenth_ns = (spd_val & 0xF0) >> 4; - unsigned int hundredth_ns = spd_val & 0x0F; - unsigned int ps = tenth_ns * 100 + hundredth_ns * 10; - - return ps; -} - -static unsigned int byte40_table_ps[8] = { - 0, - 250, - 330, - 500, - 660, - 750, - 0, /* supposed to be RFC, but not sure what that means */ - 0 /* Undefined */ -}; - -static unsigned int -compute_trfc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trfc) -{ - unsigned int trfc_ps; - - trfc_ps = (((trctrfc_ext & 0x1) * 256) + trfc) * 1000 - + byte40_table_ps[(trctrfc_ext >> 1) & 0x7]; - - return trfc_ps; -} - -static unsigned int -compute_trc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trc) -{ - unsigned int trc_ps; - - trc_ps = trc * 1000 + byte40_table_ps[(trctrfc_ext >> 4) & 0x7]; - - return trc_ps; -} - -/* - * Determine Refresh Rate. Ignore self refresh bit on DDR I. - * Table from SPD Spec, Byte 12, converted to picoseconds and - * filled in with "default" normal values. - */ -static unsigned int -determine_refresh_rate_ps(const unsigned int spd_refresh) -{ - unsigned int refresh_time_ps[8] = { - 15625000, /* 0 Normal 1.00x */ - 3900000, /* 1 Reduced .25x */ - 7800000, /* 2 Extended .50x */ - 31300000, /* 3 Extended 2.00x */ - 62500000, /* 4 Extended 4.00x */ - 125000000, /* 5 Extended 8.00x */ - 15625000, /* 6 Normal 1.00x filler */ - 15625000, /* 7 Normal 1.00x filler */ - }; - - return refresh_time_ps[spd_refresh & 0x7]; -} - -/* - * The purpose of this function is to compute a suitable - * CAS latency given the DRAM clock period. The SPD only - * defines at most 3 CAS latencies. Typically the slower in - * frequency the DIMM runs at, the shorter its CAS latency can. - * be. If the DIMM is operating at a sufficiently low frequency, - * it may be able to run at a CAS latency shorter than the - * shortest SPD-defined CAS latency. - * - * If a CAS latency is not found, 0 is returned. - * - * Do this by finding in the standard speed bin table the longest - * tCKmin that doesn't exceed the value of mclk_ps (tCK). - * - * An assumption made is that the SDRAM device allows the - * CL to be programmed for a value that is lower than those - * advertised by the SPD. This is not always the case, - * as those modes not defined in the SPD are optional. - * - * CAS latency de-rating based upon values JEDEC Standard No. 79-2C - * Table 40, "DDR2 SDRAM stanadard speed bins and tCK, tRCD, tRP, tRAS, - * and tRC for corresponding bin" - * - * ordinal 2, ddr2_speed_bins[1] contains tCK for CL=3 - * Not certain if any good value exists for CL=2 - */ - /* CL2 CL3 CL4 CL5 CL6 CL7*/ -unsigned short ddr2_speed_bins[] = { 0, 5000, 3750, 3000, 2500, 1875 }; - -unsigned int -compute_derated_DDR2_CAS_latency(unsigned int mclk_ps) -{ - const unsigned int num_speed_bins = ARRAY_SIZE(ddr2_speed_bins); - unsigned int lowest_tCKmin_found = 0; - unsigned int lowest_tCKmin_CL = 0; - unsigned int i; - - debug("mclk_ps = %u\n", mclk_ps); - - for (i = 0; i < num_speed_bins; i++) { - unsigned int x = ddr2_speed_bins[i]; - debug("i=%u, x = %u, lowest_tCKmin_found = %u\n", - i, x, lowest_tCKmin_found); - if (x && x <= mclk_ps && x >= lowest_tCKmin_found ) { - lowest_tCKmin_found = x; - lowest_tCKmin_CL = i + 2; - } - } - - debug("lowest_tCKmin_CL = %u\n", lowest_tCKmin_CL); - - return lowest_tCKmin_CL; -} - -/* - * ddr_compute_dimm_parameters for DDR2 SPD - * - * Compute DIMM parameters based upon the SPD information in spd. - * Writes the results to the dimm_params_t structure pointed by pdimm. - * - * FIXME: use #define for the retvals - */ -unsigned int -ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd, - dimm_params_t *pdimm, - unsigned int dimm_number) -{ - unsigned int retval; - - if (spd->mem_type) { - if (spd->mem_type != SPD_MEMTYPE_DDR2) { - printf("DIMM %u: is not a DDR2 SPD.\n", dimm_number); - return 1; - } - } else { - memset(pdimm, 0, sizeof(dimm_params_t)); - return 1; - } - - retval = ddr2_spd_check(spd); - if (retval) { - printf("DIMM %u: failed checksum\n", dimm_number); - return 2; - } - - /* - * The part name in ASCII in the SPD EEPROM is not null terminated. - * Guarantee null termination here by presetting all bytes to 0 - * and copying the part name in ASCII from the SPD onto it - */ - memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); - memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1); - - /* DIMM organization parameters */ - pdimm->n_ranks = (spd->mod_ranks & 0x7) + 1; - pdimm->rank_density = compute_ranksize(spd->mem_type, spd->rank_dens); - pdimm->capacity = pdimm->n_ranks * pdimm->rank_density; - pdimm->data_width = spd->dataw; - pdimm->primary_sdram_width = spd->primw; - pdimm->ec_sdram_width = spd->ecw; - - /* These are all the types defined by the JEDEC DDR2 SPD 1.3 spec */ - switch (spd->dimm_type) { - case DDR2_SPD_DIMMTYPE_RDIMM: - case DDR2_SPD_DIMMTYPE_72B_SO_RDIMM: - case DDR2_SPD_DIMMTYPE_MINI_RDIMM: - /* Registered/buffered DIMMs */ - pdimm->registered_dimm = 1; - break; - - case DDR2_SPD_DIMMTYPE_UDIMM: - case DDR2_SPD_DIMMTYPE_SO_DIMM: - case DDR2_SPD_DIMMTYPE_MICRO_DIMM: - case DDR2_SPD_DIMMTYPE_MINI_UDIMM: - /* Unbuffered DIMMs */ - pdimm->registered_dimm = 0; - break; - - case DDR2_SPD_DIMMTYPE_72B_SO_CDIMM: - default: - printf("unknown dimm_type 0x%02X\n", spd->dimm_type); - return 1; - } - - /* SDRAM device parameters */ - pdimm->n_row_addr = spd->nrow_addr; - pdimm->n_col_addr = spd->ncol_addr; - pdimm->n_banks_per_sdram_device = spd->nbanks; - pdimm->edc_config = spd->config; - pdimm->burst_lengths_bitmask = spd->burstl; - pdimm->row_density = spd->rank_dens; - - /* - * Calculate the Maximum Data Rate based on the Minimum Cycle time. - * The SPD clk_cycle field (tCKmin) is measured in tenths of - * nanoseconds and represented as BCD. - */ - pdimm->tckmin_x_ps - = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle); - pdimm->tckmin_x_minus_1_ps - = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle2); - pdimm->tckmin_x_minus_2_ps - = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle3); - - pdimm->tckmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd->tckmax); - - /* - * Compute CAS latencies defined by SPD - * The SPD caslat_x should have at least 1 and at most 3 bits set. - * - * If cas_lat after masking is 0, the __ilog2 function returns - * 255 into the variable. This behavior is abused once. - */ - pdimm->caslat_x = __ilog2(spd->cas_lat); - pdimm->caslat_x_minus_1 = __ilog2(spd->cas_lat - & ~(1 << pdimm->caslat_x)); - pdimm->caslat_x_minus_2 = __ilog2(spd->cas_lat - & ~(1 << pdimm->caslat_x) - & ~(1 << pdimm->caslat_x_minus_1)); - - /* Compute CAS latencies below that defined by SPD */ - pdimm->caslat_lowest_derated - = compute_derated_DDR2_CAS_latency(get_memory_clk_period_ps()); - - /* Compute timing parameters */ - pdimm->trcd_ps = spd->trcd * 250; - pdimm->trp_ps = spd->trp * 250; - pdimm->tras_ps = spd->tras * 1000; - - pdimm->twr_ps = spd->twr * 250; - pdimm->twtr_ps = spd->twtr * 250; - pdimm->trfc_ps = compute_trfc_ps_from_spd(spd->trctrfc_ext, spd->trfc); - - pdimm->trrd_ps = spd->trrd * 250; - pdimm->trc_ps = compute_trc_ps_from_spd(spd->trctrfc_ext, spd->trc); - - pdimm->refresh_rate_ps = determine_refresh_rate_ps(spd->refresh); - - pdimm->tis_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_setup); - pdimm->tih_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_hold); - pdimm->tds_ps - = convert_bcd_hundredths_to_cycle_time_ps(spd->data_setup); - pdimm->tdh_ps - = convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold); - - pdimm->trtp_ps = spd->trtp * 250; - pdimm->tdqsq_max_ps = spd->tdqsq * 10; - pdimm->tqhs_ps = spd->tqhs * 10; - - return 0; -} diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c deleted file mode 100644 index 4c8645d..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright 2008-2012 Freescale Semiconductor, Inc. - * Dave Liu <daveliu@freescale.com> - * - * calculate the organization and timing parameter - * from ddr3 spd, please refer to the spec - * JEDEC standard No.21-C 4_01_02_11R18.pdf - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -#include <common.h> -#include <asm/fsl_ddr_sdram.h> - -#include "ddr.h" - -/* - * Calculate the Density of each Physical Rank. - * Returned size is in bytes. - * - * each rank size = - * sdram capacity(bit) / 8 * primary bus width / sdram width - * - * where: sdram capacity = spd byte4[3:0] - * primary bus width = spd byte8[2:0] - * sdram width = spd byte7[2:0] - * - * SPD byte4 - sdram density and banks - * bit[3:0] size(bit) size(byte) - * 0000 256Mb 32MB - * 0001 512Mb 64MB - * 0010 1Gb 128MB - * 0011 2Gb 256MB - * 0100 4Gb 512MB - * 0101 8Gb 1GB - * 0110 16Gb 2GB - * - * SPD byte8 - module memory bus width - * bit[2:0] primary bus width - * 000 8bits - * 001 16bits - * 010 32bits - * 011 64bits - * - * SPD byte7 - module organiztion - * bit[2:0] sdram device width - * 000 4bits - * 001 8bits - * 010 16bits - * 011 32bits - * - */ -static unsigned long long -compute_ranksize(const ddr3_spd_eeprom_t *spd) -{ - unsigned long long bsize; - - int nbit_sdram_cap_bsize = 0; - int nbit_primary_bus_width = 0; - int nbit_sdram_width = 0; - - if ((spd->density_banks & 0xf) < 7) - nbit_sdram_cap_bsize = (spd->density_banks & 0xf) + 28; - if ((spd->bus_width & 0x7) < 4) - nbit_primary_bus_width = (spd->bus_width & 0x7) + 3; - if ((spd->organization & 0x7) < 4) - nbit_sdram_width = (spd->organization & 0x7) + 2; - - bsize = 1ULL << (nbit_sdram_cap_bsize - 3 - + nbit_primary_bus_width - nbit_sdram_width); - - debug("DDR: DDR III rank density = 0x%16llx\n", bsize); - - return bsize; -} - -/* - * ddr_compute_dimm_parameters for DDR3 SPD - * - * Compute DIMM parameters based upon the SPD information in spd. - * Writes the results to the dimm_params_t structure pointed by pdimm. - * - */ -unsigned int -ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, - dimm_params_t *pdimm, - unsigned int dimm_number) -{ - unsigned int retval; - unsigned int mtb_ps; - int ftb_10th_ps; - int i; - - if (spd->mem_type) { - if (spd->mem_type != SPD_MEMTYPE_DDR3) { - printf("DIMM %u: is not a DDR3 SPD.\n", dimm_number); - return 1; - } - } else { - memset(pdimm, 0, sizeof(dimm_params_t)); - return 1; - } - - retval = ddr3_spd_check(spd); - if (retval) { - printf("DIMM %u: failed checksum\n", dimm_number); - return 2; - } - - /* - * The part name in ASCII in the SPD EEPROM is not null terminated. - * Guarantee null termination here by presetting all bytes to 0 - * and copying the part name in ASCII from the SPD onto it - */ - memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); - if ((spd->info_size_crc & 0xF) > 1) - memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1); - - /* DIMM organization parameters */ - pdimm->n_ranks = ((spd->organization >> 3) & 0x7) + 1; - pdimm->rank_density = compute_ranksize(spd); - pdimm->capacity = pdimm->n_ranks * pdimm->rank_density; - pdimm->primary_sdram_width = 1 << (3 + (spd->bus_width & 0x7)); - if ((spd->bus_width >> 3) & 0x3) - pdimm->ec_sdram_width = 8; - else - pdimm->ec_sdram_width = 0; - pdimm->data_width = pdimm->primary_sdram_width - + pdimm->ec_sdram_width; - pdimm->device_width = 1 << ((spd->organization & 0x7) + 2); - - /* These are the types defined by the JEDEC DDR3 SPD spec */ - pdimm->mirrored_dimm = 0; - pdimm->registered_dimm = 0; - switch (spd->module_type & DDR3_SPD_MODULETYPE_MASK) { - case DDR3_SPD_MODULETYPE_RDIMM: - case DDR3_SPD_MODULETYPE_MINI_RDIMM: - case DDR3_SPD_MODULETYPE_72B_SO_RDIMM: - /* Registered/buffered DIMMs */ - pdimm->registered_dimm = 1; - for (i = 0; i < 16; i += 2) { - u8 rcw = spd->mod_section.registered.rcw[i/2]; - pdimm->rcw[i] = (rcw >> 0) & 0x0F; - pdimm->rcw[i+1] = (rcw >> 4) & 0x0F; - } - break; - - case DDR3_SPD_MODULETYPE_UDIMM: - case DDR3_SPD_MODULETYPE_SO_DIMM: - case DDR3_SPD_MODULETYPE_MICRO_DIMM: - case DDR3_SPD_MODULETYPE_MINI_UDIMM: - case DDR3_SPD_MODULETYPE_MINI_CDIMM: - case DDR3_SPD_MODULETYPE_72B_SO_UDIMM: - case DDR3_SPD_MODULETYPE_72B_SO_CDIMM: - case DDR3_SPD_MODULETYPE_LRDIMM: - case DDR3_SPD_MODULETYPE_16B_SO_DIMM: - case DDR3_SPD_MODULETYPE_32B_SO_DIMM: - /* Unbuffered DIMMs */ - if (spd->mod_section.unbuffered.addr_mapping & 0x1) - pdimm->mirrored_dimm = 1; - break; - - default: - printf("unknown module_type 0x%02X\n", spd->module_type); - return 1; - } - - /* SDRAM device parameters */ - pdimm->n_row_addr = ((spd->addressing >> 3) & 0x7) + 12; - pdimm->n_col_addr = (spd->addressing & 0x7) + 9; - pdimm->n_banks_per_sdram_device = 8 << ((spd->density_banks >> 4) & 0x7); - - /* - * The SPD spec has not the ECC bit, - * We consider the DIMM as ECC capability - * when the extension bus exist - */ - if (pdimm->ec_sdram_width) - pdimm->edc_config = 0x02; - else - pdimm->edc_config = 0x00; - - /* - * The SPD spec has not the burst length byte - * but DDR3 spec has nature BL8 and BC4, - * BL8 -bit3, BC4 -bit2 - */ - pdimm->burst_lengths_bitmask = 0x0c; - pdimm->row_density = __ilog2(pdimm->rank_density); - - /* MTB - medium timebase - * The unit in the SPD spec is ns, - * We convert it to ps. - * eg: MTB = 0.125ns (125ps) - */ - mtb_ps = (spd->mtb_dividend * 1000) /spd->mtb_divisor; - pdimm->mtb_ps = mtb_ps; - - /* - * FTB - fine timebase - * use 1/10th of ps as our unit to avoid floating point - * eg, 10 for 1ps, 25 for 2.5ps, 50 for 5ps - */ - ftb_10th_ps = - ((spd->ftb_div & 0xf0) >> 4) * 10 / (spd->ftb_div & 0x0f); - pdimm->ftb_10th_ps = ftb_10th_ps; - /* - * sdram minimum cycle time - * we assume the MTB is 0.125ns - * eg: - * tck_min=15 MTB (1.875ns) ->DDR3-1066 - * =12 MTB (1.5ns) ->DDR3-1333 - * =10 MTB (1.25ns) ->DDR3-1600 - */ - pdimm->tckmin_x_ps = spd->tck_min * mtb_ps + - (spd->fine_tck_min * ftb_10th_ps) / 10; - - /* - * CAS latency supported - * bit4 - CL4 - * bit5 - CL5 - * bit18 - CL18 - */ - pdimm->caslat_x = ((spd->caslat_msb << 8) | spd->caslat_lsb) << 4; - - /* - * min CAS latency time - * eg: taa_min = - * DDR3-800D 100 MTB (12.5ns) - * DDR3-1066F 105 MTB (13.125ns) - * DDR3-1333H 108 MTB (13.5ns) - * DDR3-1600H 90 MTB (11.25ns) - */ - pdimm->taa_ps = spd->taa_min * mtb_ps + - (spd->fine_taa_min * ftb_10th_ps) / 10; - - /* - * min write recovery time - * eg: - * twr_min = 120 MTB (15ns) -> all speed grades. - */ - pdimm->twr_ps = spd->twr_min * mtb_ps; - - /* - * min RAS to CAS delay time - * eg: trcd_min = - * DDR3-800 100 MTB (12.5ns) - * DDR3-1066F 105 MTB (13.125ns) - * DDR3-1333H 108 MTB (13.5ns) - * DDR3-1600H 90 MTB (11.25) - */ - pdimm->trcd_ps = spd->trcd_min * mtb_ps + - (spd->fine_trcd_min * ftb_10th_ps) / 10; - - /* - * min row active to row active delay time - * eg: trrd_min = - * DDR3-800(1KB page) 80 MTB (10ns) - * DDR3-1333(1KB page) 48 MTB (6ns) - */ - pdimm->trrd_ps = spd->trrd_min * mtb_ps; - - /* - * min row precharge delay time - * eg: trp_min = - * DDR3-800D 100 MTB (12.5ns) - * DDR3-1066F 105 MTB (13.125ns) - * DDR3-1333H 108 MTB (13.5ns) - * DDR3-1600H 90 MTB (11.25ns) - */ - pdimm->trp_ps = spd->trp_min * mtb_ps + - (spd->fine_trp_min * ftb_10th_ps) / 10; - - /* min active to precharge delay time - * eg: tRAS_min = - * DDR3-800D 300 MTB (37.5ns) - * DDR3-1066F 300 MTB (37.5ns) - * DDR3-1333H 288 MTB (36ns) - * DDR3-1600H 280 MTB (35ns) - */ - pdimm->tras_ps = (((spd->tras_trc_ext & 0xf) << 8) | spd->tras_min_lsb) - * mtb_ps; - /* - * min active to actice/refresh delay time - * eg: tRC_min = - * DDR3-800D 400 MTB (50ns) - * DDR3-1066F 405 MTB (50.625ns) - * DDR3-1333H 396 MTB (49.5ns) - * DDR3-1600H 370 MTB (46.25ns) - */ - pdimm->trc_ps = (((spd->tras_trc_ext & 0xf0) << 4) | spd->trc_min_lsb) - * mtb_ps + (spd->fine_trc_min * ftb_10th_ps) / 10; - /* - * min refresh recovery delay time - * eg: tRFC_min = - * 512Mb 720 MTB (90ns) - * 1Gb 880 MTB (110ns) - * 2Gb 1280 MTB (160ns) - */ - pdimm->trfc_ps = ((spd->trfc_min_msb << 8) | spd->trfc_min_lsb) - * mtb_ps; - /* - * min internal write to read command delay time - * eg: twtr_min = 40 MTB (7.5ns) - all speed bins. - * tWRT is at least 4 mclk independent of operating freq. - */ - pdimm->twtr_ps = spd->twtr_min * mtb_ps; - - /* - * min internal read to precharge command delay time - * eg: trtp_min = 40 MTB (7.5ns) - all speed bins. - * tRTP is at least 4 mclk independent of operating freq. - */ - pdimm->trtp_ps = spd->trtp_min * mtb_ps; - - /* - * Average periodic refresh interval - * tREFI = 7.8 us at normal temperature range - * = 3.9 us at ext temperature range - */ - pdimm->refresh_rate_ps = 7800000; - if ((spd->therm_ref_opt & 0x1) && !(spd->therm_ref_opt & 0x2)) { - pdimm->refresh_rate_ps = 3900000; - pdimm->extended_op_srt = 1; - } - - /* - * min four active window delay time - * eg: tfaw_min = - * DDR3-800(1KB page) 320 MTB (40ns) - * DDR3-1066(1KB page) 300 MTB (37.5ns) - * DDR3-1333(1KB page) 240 MTB (30ns) - * DDR3-1600(1KB page) 240 MTB (30ns) - */ - pdimm->tfaw_ps = (((spd->tfaw_msb & 0xf) << 8) | spd->tfaw_min) - * mtb_ps; - - return 0; -} diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c deleted file mode 100644 index 3b66112..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c +++ /dev/null @@ -1,1870 +0,0 @@ -/* - * Copyright 2010-2012 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Generic driver for Freescale DDR/DDR2/DDR3 memory controller. - * Based on code from spd_sdram.c - * Author: James Yang [at freescale.com] - * York Sun [at freescale.com] - */ - -#include <common.h> -#include <linux/ctype.h> -#include <asm/types.h> - -#include <asm/fsl_ddr_sdram.h> -#include "ddr.h" - -/* Option parameter Structures */ -struct options_string { - const char *option_name; - size_t offset; - unsigned int size; - const char printhex; -}; - -static unsigned int picos_to_mhz(unsigned int picos) -{ - return 1000000 / picos; -} - -static void print_option_table(const struct options_string *table, - int table_size, - const void *base) -{ - unsigned int i; - unsigned int *ptr; - unsigned long long *ptr_l; - - for (i = 0; i < table_size; i++) { - switch (table[i].size) { - case 4: - ptr = (unsigned int *) (base + table[i].offset); - if (table[i].printhex) { - printf("%s = 0x%08X\n", - table[i].option_name, *ptr); - } else { - printf("%s = %u\n", - table[i].option_name, *ptr); - } - break; - case 8: - ptr_l = (unsigned long long *) (base + table[i].offset); - printf("%s = %llu\n", - table[i].option_name, *ptr_l); - break; - default: - printf("Unrecognized size!\n"); - break; - } - } -} - -static int handle_option_table(const struct options_string *table, - int table_size, - void *base, - const char *opt, - const char *val) -{ - unsigned int i; - unsigned int value, *ptr; - unsigned long long value_l, *ptr_l; - - for (i = 0; i < table_size; i++) { - if (strcmp(table[i].option_name, opt) != 0) - continue; - switch (table[i].size) { - case 4: - value = simple_strtoul(val, NULL, 0); - ptr = base + table[i].offset; - *ptr = value; - break; - case 8: - value_l = simple_strtoull(val, NULL, 0); - ptr_l = base + table[i].offset; - *ptr_l = value_l; - break; - default: - printf("Unrecognized size!\n"); - break; - } - return 1; - } - - return 0; -} - -static void fsl_ddr_generic_edit(void *pdata, - void *pend, - unsigned int element_size, - unsigned int element_num, - unsigned int value) -{ - char *pcdata = (char *)pdata; /* BIG ENDIAN ONLY */ - - pcdata += element_num * element_size; - if ((pcdata + element_size) > (char *) pend) { - printf("trying to write past end of data\n"); - return; - } - - switch (element_size) { - case 1: - __raw_writeb(value, pcdata); - break; - case 2: - __raw_writew(value, pcdata); - break; - case 4: - __raw_writel(value, pcdata); - break; - default: - printf("unexpected element size %u\n", element_size); - break; - } -} - -static void fsl_ddr_spd_edit(fsl_ddr_info_t *pinfo, - unsigned int ctrl_num, - unsigned int dimm_num, - unsigned int element_num, - unsigned int value) -{ - generic_spd_eeprom_t *pspd; - - pspd = &(pinfo->spd_installed_dimms[ctrl_num][dimm_num]); - fsl_ddr_generic_edit(pspd, pspd + 1, 1, element_num, value); -} - -#define COMMON_TIMING(x) {#x, offsetof(common_timing_params_t, x), \ - sizeof((common_timing_params_t *)0)->x, 0} - -static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo, - unsigned int ctrl_num, - const char *optname_str, - const char *value_str) -{ - common_timing_params_t *p = &pinfo->common_timing_params[ctrl_num]; - - static const struct options_string options[] = { - COMMON_TIMING(tckmin_x_ps), - COMMON_TIMING(tckmax_ps), - COMMON_TIMING(tckmax_max_ps), - COMMON_TIMING(trcd_ps), - COMMON_TIMING(trp_ps), - COMMON_TIMING(tras_ps), - COMMON_TIMING(twr_ps), - COMMON_TIMING(twtr_ps), - COMMON_TIMING(trfc_ps), - COMMON_TIMING(trrd_ps), - COMMON_TIMING(trc_ps), - COMMON_TIMING(refresh_rate_ps), - COMMON_TIMING(tis_ps), - COMMON_TIMING(tih_ps), - COMMON_TIMING(tds_ps), - COMMON_TIMING(tdh_ps), - COMMON_TIMING(trtp_ps), - COMMON_TIMING(tdqsq_max_ps), - COMMON_TIMING(tqhs_ps), - COMMON_TIMING(ndimms_present), - COMMON_TIMING(lowest_common_SPD_caslat), - COMMON_TIMING(highest_common_derated_caslat), - COMMON_TIMING(additive_latency), - COMMON_TIMING(all_dimms_burst_lengths_bitmask), - COMMON_TIMING(all_dimms_registered), - COMMON_TIMING(all_dimms_unbuffered), - COMMON_TIMING(all_dimms_ecc_capable), - COMMON_TIMING(total_mem), - COMMON_TIMING(base_address), - }; - static const unsigned int n_opts = ARRAY_SIZE(options); - - if (handle_option_table(options, n_opts, p, optname_str, value_str)) - return; - - printf("Error: couldn't find option string %s\n", optname_str); -} - -#define DIMM_PARM(x) {#x, offsetof(dimm_params_t, x), \ - sizeof((dimm_params_t *)0)->x, 0} - -static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, - unsigned int ctrl_num, - unsigned int dimm_num, - const char *optname_str, - const char *value_str) -{ - dimm_params_t *p = &(pinfo->dimm_params[ctrl_num][dimm_num]); - - static const struct options_string options[] = { - DIMM_PARM(n_ranks), - DIMM_PARM(data_width), - DIMM_PARM(primary_sdram_width), - DIMM_PARM(ec_sdram_width), - DIMM_PARM(registered_dimm), - DIMM_PARM(device_width), - - DIMM_PARM(n_row_addr), - DIMM_PARM(n_col_addr), - DIMM_PARM(edc_config), - DIMM_PARM(n_banks_per_sdram_device), - DIMM_PARM(burst_lengths_bitmask), - DIMM_PARM(row_density), - - DIMM_PARM(tckmin_x_ps), - DIMM_PARM(tckmin_x_minus_1_ps), - DIMM_PARM(tckmin_x_minus_2_ps), - DIMM_PARM(tckmax_ps), - - DIMM_PARM(caslat_x), - DIMM_PARM(caslat_x_minus_1), - DIMM_PARM(caslat_x_minus_2), - - DIMM_PARM(caslat_lowest_derated), - - DIMM_PARM(trcd_ps), - DIMM_PARM(trp_ps), - DIMM_PARM(tras_ps), - DIMM_PARM(twr_ps), - DIMM_PARM(twtr_ps), - DIMM_PARM(trfc_ps), - DIMM_PARM(trrd_ps), - DIMM_PARM(trc_ps), - DIMM_PARM(refresh_rate_ps), - - DIMM_PARM(tis_ps), - DIMM_PARM(tih_ps), - DIMM_PARM(tds_ps), - DIMM_PARM(tdh_ps), - DIMM_PARM(trtp_ps), - DIMM_PARM(tdqsq_max_ps), - DIMM_PARM(tqhs_ps), - - DIMM_PARM(rank_density), - DIMM_PARM(capacity), - DIMM_PARM(base_address), - }; - - static const unsigned int n_opts = ARRAY_SIZE(options); - - if (handle_option_table(options, n_opts, p, optname_str, value_str)) - return; - - printf("couldn't find option string %s\n", optname_str); -} - -static void print_dimm_parameters(const dimm_params_t *pdimm) -{ - static const struct options_string options[] = { - DIMM_PARM(n_ranks), - DIMM_PARM(data_width), - DIMM_PARM(primary_sdram_width), - DIMM_PARM(ec_sdram_width), - DIMM_PARM(registered_dimm), - DIMM_PARM(device_width), - - DIMM_PARM(n_row_addr), - DIMM_PARM(n_col_addr), - DIMM_PARM(edc_config), - DIMM_PARM(n_banks_per_sdram_device), - - DIMM_PARM(tckmin_x_ps), - DIMM_PARM(tckmin_x_minus_1_ps), - DIMM_PARM(tckmin_x_minus_2_ps), - DIMM_PARM(tckmax_ps), - - DIMM_PARM(caslat_x), - DIMM_PARM(taa_ps), - DIMM_PARM(caslat_x_minus_1), - DIMM_PARM(caslat_x_minus_2), - DIMM_PARM(caslat_lowest_derated), - - DIMM_PARM(trcd_ps), - DIMM_PARM(trp_ps), - DIMM_PARM(tras_ps), - DIMM_PARM(twr_ps), - DIMM_PARM(twtr_ps), - DIMM_PARM(trfc_ps), - DIMM_PARM(trrd_ps), - DIMM_PARM(trc_ps), - DIMM_PARM(refresh_rate_ps), - - DIMM_PARM(tis_ps), - DIMM_PARM(tih_ps), - DIMM_PARM(tds_ps), - DIMM_PARM(tdh_ps), - DIMM_PARM(trtp_ps), - DIMM_PARM(tdqsq_max_ps), - DIMM_PARM(tqhs_ps), - }; - static const unsigned int n_opts = ARRAY_SIZE(options); - - if (pdimm->n_ranks == 0) { - printf("DIMM not present\n"); - return; - } - printf("DIMM organization parameters:\n"); - printf("module part name = %s\n", pdimm->mpart); - printf("rank_density = %llu bytes (%llu megabytes)\n", - pdimm->rank_density, pdimm->rank_density / 0x100000); - printf("capacity = %llu bytes (%llu megabytes)\n", - pdimm->capacity, pdimm->capacity / 0x100000); - printf("burst_lengths_bitmask = %02X\n", - pdimm->burst_lengths_bitmask); - printf("base_addresss = %llu (%08llX %08llX)\n", - pdimm->base_address, - (pdimm->base_address >> 32), - pdimm->base_address & 0xFFFFFFFF); - print_option_table(options, n_opts, pdimm); -} - -static void print_lowest_common_dimm_parameters( - const common_timing_params_t *plcd_dimm_params) -{ - static const struct options_string options[] = { - COMMON_TIMING(tckmax_max_ps), - COMMON_TIMING(trcd_ps), - COMMON_TIMING(trp_ps), - COMMON_TIMING(tras_ps), - COMMON_TIMING(twr_ps), - COMMON_TIMING(twtr_ps), - COMMON_TIMING(trfc_ps), - COMMON_TIMING(trrd_ps), - COMMON_TIMING(trc_ps), - COMMON_TIMING(refresh_rate_ps), - COMMON_TIMING(tis_ps), - COMMON_TIMING(tds_ps), - COMMON_TIMING(tdh_ps), - COMMON_TIMING(trtp_ps), - COMMON_TIMING(tdqsq_max_ps), - COMMON_TIMING(tqhs_ps), - COMMON_TIMING(lowest_common_SPD_caslat), - COMMON_TIMING(highest_common_derated_caslat), - COMMON_TIMING(additive_latency), - COMMON_TIMING(ndimms_present), - COMMON_TIMING(all_dimms_registered), - COMMON_TIMING(all_dimms_unbuffered), - COMMON_TIMING(all_dimms_ecc_capable), - }; - static const unsigned int n_opts = ARRAY_SIZE(options); - - /* Clock frequencies */ - printf("tckmin_x_ps = %u (%u MHz)\n", - plcd_dimm_params->tckmin_x_ps, - picos_to_mhz(plcd_dimm_params->tckmin_x_ps)); - printf("tckmax_ps = %u (%u MHz)\n", - plcd_dimm_params->tckmax_ps, - picos_to_mhz(plcd_dimm_params->tckmax_ps)); - printf("all_dimms_burst_lengths_bitmask = %02X\n", - plcd_dimm_params->all_dimms_burst_lengths_bitmask); - - print_option_table(options, n_opts, plcd_dimm_params); - - printf("total_mem = %llu (%llu megabytes)\n", - plcd_dimm_params->total_mem, - plcd_dimm_params->total_mem / 0x100000); - printf("base_address = %llu (%llu megabytes)\n", - plcd_dimm_params->base_address, - plcd_dimm_params->base_address / 0x100000); -} - -#define CTRL_OPTIONS(x) {#x, offsetof(memctl_options_t, x), \ - sizeof((memctl_options_t *)0)->x, 0} -#define CTRL_OPTIONS_CS(x, y) {"cs" #x "_" #y, \ - offsetof(memctl_options_t, cs_local_opts[x].y), \ - sizeof((memctl_options_t *)0)->cs_local_opts[x].y, 0} - -static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo, - unsigned int ctl_num, - const char *optname_str, - const char *value_str) -{ - memctl_options_t *p = &(pinfo->memctl_opts[ctl_num]); - /* - * This array all on the stack and *computed* each time this - * function is rung. - */ - static const struct options_string options[] = { - CTRL_OPTIONS_CS(0, odt_rd_cfg), - CTRL_OPTIONS_CS(0, odt_wr_cfg), -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) - CTRL_OPTIONS_CS(1, odt_rd_cfg), - CTRL_OPTIONS_CS(1, odt_wr_cfg), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) - CTRL_OPTIONS_CS(2, odt_rd_cfg), - CTRL_OPTIONS_CS(2, odt_wr_cfg), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) - CTRL_OPTIONS_CS(3, odt_rd_cfg), - CTRL_OPTIONS_CS(3, odt_wr_cfg), -#endif -#if defined(CONFIG_FSL_DDR3) - CTRL_OPTIONS_CS(0, odt_rtt_norm), - CTRL_OPTIONS_CS(0, odt_rtt_wr), -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) - CTRL_OPTIONS_CS(1, odt_rtt_norm), - CTRL_OPTIONS_CS(1, odt_rtt_wr), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) - CTRL_OPTIONS_CS(2, odt_rtt_norm), - CTRL_OPTIONS_CS(2, odt_rtt_wr), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) - CTRL_OPTIONS_CS(3, odt_rtt_norm), - CTRL_OPTIONS_CS(3, odt_rtt_wr), -#endif -#endif - CTRL_OPTIONS(memctl_interleaving), - CTRL_OPTIONS(memctl_interleaving_mode), - CTRL_OPTIONS(ba_intlv_ctl), - CTRL_OPTIONS(ecc_mode), - CTRL_OPTIONS(ecc_init_using_memctl), - CTRL_OPTIONS(dqs_config), - CTRL_OPTIONS(self_refresh_in_sleep), - CTRL_OPTIONS(dynamic_power), - CTRL_OPTIONS(data_bus_width), - CTRL_OPTIONS(burst_length), - CTRL_OPTIONS(cas_latency_override), - CTRL_OPTIONS(cas_latency_override_value), - CTRL_OPTIONS(use_derated_caslat), - CTRL_OPTIONS(additive_latency_override), - CTRL_OPTIONS(additive_latency_override_value), - CTRL_OPTIONS(clk_adjust), - CTRL_OPTIONS(cpo_override), - CTRL_OPTIONS(write_data_delay), - CTRL_OPTIONS(half_strength_driver_enable), - - /* - * These can probably be changed to 2T_EN and 3T_EN - * (using a leading numerical character) without problem - */ - CTRL_OPTIONS(twot_en), - CTRL_OPTIONS(threet_en), - CTRL_OPTIONS(ap_en), - CTRL_OPTIONS(x4_en), - CTRL_OPTIONS(bstopre), - CTRL_OPTIONS(wrlvl_override), - CTRL_OPTIONS(wrlvl_sample), - CTRL_OPTIONS(wrlvl_start), - CTRL_OPTIONS(rcw_override), - CTRL_OPTIONS(rcw_1), - CTRL_OPTIONS(rcw_2), - CTRL_OPTIONS(ddr_cdr1), - CTRL_OPTIONS(ddr_cdr2), - CTRL_OPTIONS(tcke_clock_pulse_width_ps), - CTRL_OPTIONS(tfaw_window_four_activates_ps), - CTRL_OPTIONS(trwt_override), - CTRL_OPTIONS(trwt), - }; - - static const unsigned int n_opts = ARRAY_SIZE(options); - - if (handle_option_table(options, n_opts, p, - optname_str, value_str)) - return; - - printf("couldn't find option string %s\n", optname_str); -} - -#define CFG_REGS(x) {#x, offsetof(fsl_ddr_cfg_regs_t, x), \ - sizeof((fsl_ddr_cfg_regs_t *)0)->x, 1} -#define CFG_REGS_CS(x, y) {"cs" #x "_" #y, \ - offsetof(fsl_ddr_cfg_regs_t, cs[x].y), \ - sizeof((fsl_ddr_cfg_regs_t *)0)->cs[x].y, 1} - -static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) -{ - unsigned int i; - static const struct options_string options[] = { - CFG_REGS_CS(0, bnds), - CFG_REGS_CS(0, config), - CFG_REGS_CS(0, config_2), -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) - CFG_REGS_CS(1, bnds), - CFG_REGS_CS(1, config), - CFG_REGS_CS(1, config_2), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) - CFG_REGS_CS(2, bnds), - CFG_REGS_CS(2, config), - CFG_REGS_CS(2, config_2), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) - CFG_REGS_CS(3, bnds), - CFG_REGS_CS(3, config), - CFG_REGS_CS(3, config_2), -#endif - CFG_REGS(timing_cfg_3), - CFG_REGS(timing_cfg_0), - CFG_REGS(timing_cfg_1), - CFG_REGS(timing_cfg_2), - CFG_REGS(ddr_sdram_cfg), - CFG_REGS(ddr_sdram_cfg_2), - CFG_REGS(ddr_sdram_mode), - CFG_REGS(ddr_sdram_mode_2), - CFG_REGS(ddr_sdram_mode_3), - CFG_REGS(ddr_sdram_mode_4), - CFG_REGS(ddr_sdram_mode_5), - CFG_REGS(ddr_sdram_mode_6), - CFG_REGS(ddr_sdram_mode_7), - CFG_REGS(ddr_sdram_mode_8), - CFG_REGS(ddr_sdram_interval), - CFG_REGS(ddr_data_init), - CFG_REGS(ddr_sdram_clk_cntl), - CFG_REGS(ddr_init_addr), - CFG_REGS(ddr_init_ext_addr), - CFG_REGS(timing_cfg_4), - CFG_REGS(timing_cfg_5), - CFG_REGS(ddr_zq_cntl), - CFG_REGS(ddr_wrlvl_cntl), - CFG_REGS(ddr_wrlvl_cntl_2), - CFG_REGS(ddr_wrlvl_cntl_3), - CFG_REGS(ddr_sr_cntr), - CFG_REGS(ddr_sdram_rcw_1), - CFG_REGS(ddr_sdram_rcw_2), - CFG_REGS(ddr_cdr1), - CFG_REGS(ddr_cdr2), - CFG_REGS(err_disable), - CFG_REGS(err_int_en), - CFG_REGS(ddr_eor), - }; - static const unsigned int n_opts = ARRAY_SIZE(options); - - print_option_table(options, n_opts, ddr); - - for (i = 0; i < 32; i++) - printf("debug_%02d = 0x%08X\n", i+1, ddr->debug[i]); -} - -static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, - unsigned int ctrl_num, - const char *regname, - const char *value_str) -{ - unsigned int i; - fsl_ddr_cfg_regs_t *ddr; - char buf[20]; - static const struct options_string options[] = { - CFG_REGS_CS(0, bnds), - CFG_REGS_CS(0, config), - CFG_REGS_CS(0, config_2), -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) - CFG_REGS_CS(1, bnds), - CFG_REGS_CS(1, config), - CFG_REGS_CS(1, config_2), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) - CFG_REGS_CS(2, bnds), - CFG_REGS_CS(2, config), - CFG_REGS_CS(2, config_2), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 3) - CFG_REGS_CS(3, bnds), - CFG_REGS_CS(3, config), - CFG_REGS_CS(3, config_2), -#endif - CFG_REGS(timing_cfg_3), - CFG_REGS(timing_cfg_0), - CFG_REGS(timing_cfg_1), - CFG_REGS(timing_cfg_2), - CFG_REGS(ddr_sdram_cfg), - CFG_REGS(ddr_sdram_cfg_2), - CFG_REGS(ddr_sdram_mode), - CFG_REGS(ddr_sdram_mode_2), - CFG_REGS(ddr_sdram_mode_3), - CFG_REGS(ddr_sdram_mode_4), - CFG_REGS(ddr_sdram_mode_5), - CFG_REGS(ddr_sdram_mode_6), - CFG_REGS(ddr_sdram_mode_7), - CFG_REGS(ddr_sdram_mode_8), - CFG_REGS(ddr_sdram_interval), - CFG_REGS(ddr_data_init), - CFG_REGS(ddr_sdram_clk_cntl), - CFG_REGS(ddr_init_addr), - CFG_REGS(ddr_init_ext_addr), - CFG_REGS(timing_cfg_4), - CFG_REGS(timing_cfg_5), - CFG_REGS(ddr_zq_cntl), - CFG_REGS(ddr_wrlvl_cntl), - CFG_REGS(ddr_wrlvl_cntl_2), - CFG_REGS(ddr_wrlvl_cntl_3), - CFG_REGS(ddr_sr_cntr), - CFG_REGS(ddr_sdram_rcw_1), - CFG_REGS(ddr_sdram_rcw_2), - CFG_REGS(ddr_cdr1), - CFG_REGS(ddr_cdr2), - CFG_REGS(err_disable), - CFG_REGS(err_int_en), - CFG_REGS(ddr_sdram_rcw_2), - CFG_REGS(ddr_sdram_rcw_2), - CFG_REGS(ddr_eor), - }; - static const unsigned int n_opts = ARRAY_SIZE(options); - - debug("fsl_ddr_regs_edit: ctrl_num = %u, " - "regname = %s, value = %s\n", - ctrl_num, regname, value_str); - if (ctrl_num > CONFIG_NUM_DDR_CONTROLLERS) - return; - - ddr = &(pinfo->fsl_ddr_config_reg[ctrl_num]); - - if (handle_option_table(options, n_opts, ddr, regname, value_str)) - return; - - for (i = 0; i < 32; i++) { - unsigned int value = simple_strtoul(value_str, NULL, 0); - sprintf(buf, "debug_%u", i + 1); - if (strcmp(buf, regname) == 0) { - ddr->debug[i] = value; - return; - } - } - printf("Error: couldn't find register string %s\n", regname); -} - -#define CTRL_OPTIONS_HEX(x) {#x, offsetof(memctl_options_t, x), \ - sizeof((memctl_options_t *)0)->x, 1} - -static void print_memctl_options(const memctl_options_t *popts) -{ - static const struct options_string options[] = { - CTRL_OPTIONS_CS(0, odt_rd_cfg), - CTRL_OPTIONS_CS(0, odt_wr_cfg), -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) - CTRL_OPTIONS_CS(1, odt_rd_cfg), - CTRL_OPTIONS_CS(1, odt_wr_cfg), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) - CTRL_OPTIONS_CS(2, odt_rd_cfg), - CTRL_OPTIONS_CS(2, odt_wr_cfg), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 3) - CTRL_OPTIONS_CS(3, odt_rd_cfg), - CTRL_OPTIONS_CS(3, odt_wr_cfg), -#endif -#if defined(CONFIG_FSL_DDR3) - CTRL_OPTIONS_CS(0, odt_rtt_norm), - CTRL_OPTIONS_CS(0, odt_rtt_wr), -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) - CTRL_OPTIONS_CS(1, odt_rtt_norm), - CTRL_OPTIONS_CS(1, odt_rtt_wr), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) - CTRL_OPTIONS_CS(2, odt_rtt_norm), - CTRL_OPTIONS_CS(2, odt_rtt_wr), -#endif -#if (CONFIG_CHIP_SELECTS_PER_CTRL > 3) - CTRL_OPTIONS_CS(3, odt_rtt_norm), - CTRL_OPTIONS_CS(3, odt_rtt_wr), -#endif -#endif - CTRL_OPTIONS(memctl_interleaving), - CTRL_OPTIONS(memctl_interleaving_mode), - CTRL_OPTIONS_HEX(ba_intlv_ctl), - CTRL_OPTIONS(ecc_mode), - CTRL_OPTIONS(ecc_init_using_memctl), - CTRL_OPTIONS(dqs_config), - CTRL_OPTIONS(self_refresh_in_sleep), - CTRL_OPTIONS(dynamic_power), - CTRL_OPTIONS(data_bus_width), - CTRL_OPTIONS(burst_length), - CTRL_OPTIONS(cas_latency_override), - CTRL_OPTIONS(cas_latency_override_value), - CTRL_OPTIONS(use_derated_caslat), - CTRL_OPTIONS(additive_latency_override), - CTRL_OPTIONS(additive_latency_override_value), - CTRL_OPTIONS(clk_adjust), - CTRL_OPTIONS(cpo_override), - CTRL_OPTIONS(write_data_delay), - CTRL_OPTIONS(half_strength_driver_enable), - /* - * These can probably be changed to 2T_EN and 3T_EN - * (using a leading numerical character) without problem - */ - CTRL_OPTIONS(twot_en), - CTRL_OPTIONS(threet_en), - CTRL_OPTIONS(registered_dimm_en), - CTRL_OPTIONS(ap_en), - CTRL_OPTIONS(x4_en), - CTRL_OPTIONS(bstopre), - CTRL_OPTIONS(wrlvl_override), - CTRL_OPTIONS(wrlvl_sample), - CTRL_OPTIONS(wrlvl_start), - CTRL_OPTIONS(rcw_override), - CTRL_OPTIONS(rcw_1), - CTRL_OPTIONS(rcw_2), - CTRL_OPTIONS_HEX(ddr_cdr1), - CTRL_OPTIONS_HEX(ddr_cdr2), - CTRL_OPTIONS(tcke_clock_pulse_width_ps), - CTRL_OPTIONS(tfaw_window_four_activates_ps), - CTRL_OPTIONS(trwt_override), - CTRL_OPTIONS(trwt), - }; - static const unsigned int n_opts = ARRAY_SIZE(options); - - print_option_table(options, n_opts, popts); -} - -#ifdef CONFIG_FSL_DDR1 -void ddr1_spd_dump(const ddr1_spd_eeprom_t *spd) -{ - unsigned int i; - - printf("%-3d : %02x %s\n", 0, spd->info_size, - " spd->info_size, * 0 # bytes written into serial memory *"); - printf("%-3d : %02x %s\n", 1, spd->chip_size, - " spd->chip_size, * 1 Total # bytes of SPD memory device *"); - printf("%-3d : %02x %s\n", 2, spd->mem_type, - " spd->mem_type, * 2 Fundamental memory type *"); - printf("%-3d : %02x %s\n", 3, spd->nrow_addr, - " spd->nrow_addr, * 3 # of Row Addresses on this assembly *"); - printf("%-3d : %02x %s\n", 4, spd->ncol_addr, - " spd->ncol_addr, * 4 # of Column Addrs on this assembly *"); - printf("%-3d : %02x %s\n", 5, spd->nrows, - " spd->nrows * 5 # of DIMM Banks *"); - printf("%-3d : %02x %s\n", 6, spd->dataw_lsb, - " spd->dataw_lsb, * 6 Data Width lsb of this assembly *"); - printf("%-3d : %02x %s\n", 7, spd->dataw_msb, - " spd->dataw_msb, * 7 Data Width msb of this assembly *"); - printf("%-3d : %02x %s\n", 8, spd->voltage, - " spd->voltage, * 8 Voltage intf std of this assembly *"); - printf("%-3d : %02x %s\n", 9, spd->clk_cycle, - " spd->clk_cycle, * 9 SDRAM Cycle time at CL=X *"); - printf("%-3d : %02x %s\n", 10, spd->clk_access, - " spd->clk_access, * 10 SDRAM Access from Clock at CL=X *"); - printf("%-3d : %02x %s\n", 11, spd->config, - " spd->config, * 11 DIMM Configuration type *"); - printf("%-3d : %02x %s\n", 12, spd->refresh, - " spd->refresh, * 12 Refresh Rate/Type *"); - printf("%-3d : %02x %s\n", 13, spd->primw, - " spd->primw, * 13 Primary SDRAM Width *"); - printf("%-3d : %02x %s\n", 14, spd->ecw, - " spd->ecw, * 14 Error Checking SDRAM width *"); - printf("%-3d : %02x %s\n", 15, spd->min_delay, - " spd->min_delay, * 15 Back to Back Random Access *"); - printf("%-3d : %02x %s\n", 16, spd->burstl, - " spd->burstl, * 16 Burst Lengths Supported *"); - printf("%-3d : %02x %s\n", 17, spd->nbanks, - " spd->nbanks, * 17 # of Banks on Each SDRAM Device *"); - printf("%-3d : %02x %s\n", 18, spd->cas_lat, - " spd->cas_lat, * 18 CAS# Latencies Supported *"); - printf("%-3d : %02x %s\n", 19, spd->cs_lat, - " spd->cs_lat, * 19 Chip Select Latency *"); - printf("%-3d : %02x %s\n", 20, spd->write_lat, - " spd->write_lat, * 20 Write Latency/Recovery *"); - printf("%-3d : %02x %s\n", 21, spd->mod_attr, - " spd->mod_attr, * 21 SDRAM Module Attributes *"); - printf("%-3d : %02x %s\n", 22, spd->dev_attr, - " spd->dev_attr, * 22 SDRAM Device Attributes *"); - printf("%-3d : %02x %s\n", 23, spd->clk_cycle2, - " spd->clk_cycle2, * 23 Min SDRAM Cycle time at CL=X-1 *"); - printf("%-3d : %02x %s\n", 24, spd->clk_access2, - " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *"); - printf("%-3d : %02x %s\n", 25, spd->clk_cycle3, - " spd->clk_cycle3, * 25 Min SDRAM Cycle time at CL=X-2 *"); - printf("%-3d : %02x %s\n", 26, spd->clk_access3, - " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *"); - printf("%-3d : %02x %s\n", 27, spd->trp, - " spd->trp, * 27 Min Row Precharge Time (tRP)*"); - printf("%-3d : %02x %s\n", 28, spd->trrd, - " spd->trrd, * 28 Min Row Active to Row Active (tRRD) *"); - printf("%-3d : %02x %s\n", 29, spd->trcd, - " spd->trcd, * 29 Min RAS to CAS Delay (tRCD) *"); - printf("%-3d : %02x %s\n", 30, spd->tras, - " spd->tras, * 30 Minimum RAS Pulse Width (tRAS) *"); - printf("%-3d : %02x %s\n", 31, spd->bank_dens, - " spd->bank_dens, * 31 Density of each bank on module *"); - printf("%-3d : %02x %s\n", 32, spd->ca_setup, - " spd->ca_setup, * 32 Cmd + Addr signal input setup time *"); - printf("%-3d : %02x %s\n", 33, spd->ca_hold, - " spd->ca_hold, * 33 Cmd and Addr signal input hold time *"); - printf("%-3d : %02x %s\n", 34, spd->data_setup, - " spd->data_setup, * 34 Data signal input setup time *"); - printf("%-3d : %02x %s\n", 35, spd->data_hold, - " spd->data_hold, * 35 Data signal input hold time *"); - printf("%-3d : %02x %s\n", 36, spd->res_36_40[0], - " spd->res_36_40[0], * 36 Reserved / tWR *"); - printf("%-3d : %02x %s\n", 37, spd->res_36_40[1], - " spd->res_36_40[1], * 37 Reserved / tWTR *"); - printf("%-3d : %02x %s\n", 38, spd->res_36_40[2], - " spd->res_36_40[2], * 38 Reserved / tRTP *"); - printf("%-3d : %02x %s\n", 39, spd->res_36_40[3], - " spd->res_36_40[3], * 39 Reserved / mem_probe *"); - printf("%-3d : %02x %s\n", 40, spd->res_36_40[4], - " spd->res_36_40[4], * 40 Reserved / trc,trfc extensions *"); - printf("%-3d : %02x %s\n", 41, spd->trc, - " spd->trc, * 41 Min Active to Auto refresh time tRC *"); - printf("%-3d : %02x %s\n", 42, spd->trfc, - " spd->trfc, * 42 Min Auto to Active period tRFC *"); - printf("%-3d : %02x %s\n", 43, spd->tckmax, - " spd->tckmax, * 43 Max device cycle time tCKmax *"); - printf("%-3d : %02x %s\n", 44, spd->tdqsq, - " spd->tdqsq, * 44 Max DQS to DQ skew *"); - printf("%-3d : %02x %s\n", 45, spd->tqhs, - " spd->tqhs, * 45 Max Read DataHold skew tQHS *"); - printf("%-3d : %02x %s\n", 46, spd->res_46, - " spd->res_46, * 46 Reserved/ PLL Relock time *"); - printf("%-3d : %02x %s\n", 47, spd->dimm_height, - " spd->dimm_height * 47 SDRAM DIMM Height *"); - - printf("%-3d-%3d: ", 48, 61); - - for (i = 0; i < 14; i++) - printf("%02x", spd->res_48_61[i]); - - printf(" * 48-61 IDD in SPD and Reserved space *\n"); - - printf("%-3d : %02x %s\n", 62, spd->spd_rev, - " spd->spd_rev, * 62 SPD Data Revision Code *"); - printf("%-3d : %02x %s\n", 63, spd->cksum, - " spd->cksum, * 63 Checksum for bytes 0-62 *"); - printf("%-3d-%3d: ", 64, 71); - - for (i = 0; i < 8; i++) - printf("%02x", spd->mid[i]); - - printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n"); - printf("%-3d : %02x %s\n", 72, spd->mloc, - " spd->mloc, * 72 Manufacturing Location *"); - - printf("%-3d-%3d: >>", 73, 90); - - for (i = 0; i < 18; i++) - printf("%c", spd->mpart[i]); - - printf("<<* 73 Manufacturer's Part Number *\n"); - - printf("%-3d-%3d: %02x %02x %s\n", 91, 92, spd->rev[0], spd->rev[1], - "* 91 Revision Code *"); - printf("%-3d-%3d: %02x %02x %s\n", 93, 94, spd->mdate[0], spd->mdate[1], - "* 93 Manufacturing Date *"); - printf("%-3d-%3d: ", 95, 98); - - for (i = 0; i < 4; i++) - printf("%02x", spd->sernum[i]); - - printf("* 95 Assembly Serial Number *\n"); - - printf("%-3d-%3d: ", 99, 127); - - for (i = 0; i < 27; i++) - printf("%02x", spd->mspec[i]); - - printf("* 99 Manufacturer Specific Data *\n"); -} -#endif - -#ifdef CONFIG_FSL_DDR2 -void ddr2_spd_dump(const ddr2_spd_eeprom_t *spd) -{ - unsigned int i; - - printf("%-3d : %02x %s\n", 0, spd->info_size, - " spd->info_size, * 0 # bytes written into serial memory *"); - printf("%-3d : %02x %s\n", 1, spd->chip_size, - " spd->chip_size, * 1 Total # bytes of SPD memory device *"); - printf("%-3d : %02x %s\n", 2, spd->mem_type, - " spd->mem_type, * 2 Fundamental memory type *"); - printf("%-3d : %02x %s\n", 3, spd->nrow_addr, - " spd->nrow_addr, * 3 # of Row Addresses on this assembly *"); - printf("%-3d : %02x %s\n", 4, spd->ncol_addr, - " spd->ncol_addr, * 4 # of Column Addrs on this assembly *"); - printf("%-3d : %02x %s\n", 5, spd->mod_ranks, - " spd->mod_ranks * 5 # of Module Rows on this assembly *"); - printf("%-3d : %02x %s\n", 6, spd->dataw, - " spd->dataw, * 6 Data Width of this assembly *"); - printf("%-3d : %02x %s\n", 7, spd->res_7, - " spd->res_7, * 7 Reserved *"); - printf("%-3d : %02x %s\n", 8, spd->voltage, - " spd->voltage, * 8 Voltage intf std of this assembly *"); - printf("%-3d : %02x %s\n", 9, spd->clk_cycle, - " spd->clk_cycle, * 9 SDRAM Cycle time at CL=X *"); - printf("%-3d : %02x %s\n", 10, spd->clk_access, - " spd->clk_access, * 10 SDRAM Access from Clock at CL=X *"); - printf("%-3d : %02x %s\n", 11, spd->config, - " spd->config, * 11 DIMM Configuration type *"); - printf("%-3d : %02x %s\n", 12, spd->refresh, - " spd->refresh, * 12 Refresh Rate/Type *"); - printf("%-3d : %02x %s\n", 13, spd->primw, - " spd->primw, * 13 Primary SDRAM Width *"); - printf("%-3d : %02x %s\n", 14, spd->ecw, - " spd->ecw, * 14 Error Checking SDRAM width *"); - printf("%-3d : %02x %s\n", 15, spd->res_15, - " spd->res_15, * 15 Reserved *"); - printf("%-3d : %02x %s\n", 16, spd->burstl, - " spd->burstl, * 16 Burst Lengths Supported *"); - printf("%-3d : %02x %s\n", 17, spd->nbanks, - " spd->nbanks, * 17 # of Banks on Each SDRAM Device *"); - printf("%-3d : %02x %s\n", 18, spd->cas_lat, - " spd->cas_lat, * 18 CAS# Latencies Supported *"); - printf("%-3d : %02x %s\n", 19, spd->mech_char, - " spd->mech_char, * 19 Mechanical Characteristics *"); - printf("%-3d : %02x %s\n", 20, spd->dimm_type, - " spd->dimm_type, * 20 DIMM type *"); - printf("%-3d : %02x %s\n", 21, spd->mod_attr, - " spd->mod_attr, * 21 SDRAM Module Attributes *"); - printf("%-3d : %02x %s\n", 22, spd->dev_attr, - " spd->dev_attr, * 22 SDRAM Device Attributes *"); - printf("%-3d : %02x %s\n", 23, spd->clk_cycle2, - " spd->clk_cycle2, * 23 Min SDRAM Cycle time at CL=X-1 *"); - printf("%-3d : %02x %s\n", 24, spd->clk_access2, - " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *"); - printf("%-3d : %02x %s\n", 25, spd->clk_cycle3, - " spd->clk_cycle3, * 25 Min SDRAM Cycle time at CL=X-2 *"); - printf("%-3d : %02x %s\n", 26, spd->clk_access3, - " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *"); - printf("%-3d : %02x %s\n", 27, spd->trp, - " spd->trp, * 27 Min Row Precharge Time (tRP)*"); - printf("%-3d : %02x %s\n", 28, spd->trrd, - " spd->trrd, * 28 Min Row Active to Row Active (tRRD) *"); - printf("%-3d : %02x %s\n", 29, spd->trcd, - " spd->trcd, * 29 Min RAS to CAS Delay (tRCD) *"); - printf("%-3d : %02x %s\n", 30, spd->tras, - " spd->tras, * 30 Minimum RAS Pulse Width (tRAS) *"); - printf("%-3d : %02x %s\n", 31, spd->rank_dens, - " spd->rank_dens, * 31 Density of each rank on module *"); - printf("%-3d : %02x %s\n", 32, spd->ca_setup, - " spd->ca_setup, * 32 Cmd + Addr signal input setup time *"); - printf("%-3d : %02x %s\n", 33, spd->ca_hold, - " spd->ca_hold, * 33 Cmd and Addr signal input hold time *"); - printf("%-3d : %02x %s\n", 34, spd->data_setup, - " spd->data_setup, * 34 Data signal input setup time *"); - printf("%-3d : %02x %s\n", 35, spd->data_hold, - " spd->data_hold, * 35 Data signal input hold time *"); - printf("%-3d : %02x %s\n", 36, spd->twr, - " spd->twr, * 36 Write Recovery time tWR *"); - printf("%-3d : %02x %s\n", 37, spd->twtr, - " spd->twtr, * 37 Int write to read delay tWTR *"); - printf("%-3d : %02x %s\n", 38, spd->trtp, - " spd->trtp, * 38 Int read to precharge delay tRTP *"); - printf("%-3d : %02x %s\n", 39, spd->mem_probe, - " spd->mem_probe, * 39 Mem analysis probe characteristics *"); - printf("%-3d : %02x %s\n", 40, spd->trctrfc_ext, - " spd->trctrfc_ext, * 40 Extensions to trc and trfc *"); - printf("%-3d : %02x %s\n", 41, spd->trc, - " spd->trc, * 41 Min Active to Auto refresh time tRC *"); - printf("%-3d : %02x %s\n", 42, spd->trfc, - " spd->trfc, * 42 Min Auto to Active period tRFC *"); - printf("%-3d : %02x %s\n", 43, spd->tckmax, - " spd->tckmax, * 43 Max device cycle time tCKmax *"); - printf("%-3d : %02x %s\n", 44, spd->tdqsq, - " spd->tdqsq, * 44 Max DQS to DQ skew *"); - printf("%-3d : %02x %s\n", 45, spd->tqhs, - " spd->tqhs, * 45 Max Read DataHold skew tQHS *"); - printf("%-3d : %02x %s\n", 46, spd->pll_relock, - " spd->pll_relock, * 46 PLL Relock time *"); - printf("%-3d : %02x %s\n", 47, spd->t_casemax, - " spd->t_casemax, * 47 t_casemax *"); - printf("%-3d : %02x %s\n", 48, spd->psi_ta_dram, - " spd->psi_ta_dram, * 48 Thermal Resistance of DRAM Package " - "from Top (Case) to Ambient (Psi T-A DRAM) *"); - printf("%-3d : %02x %s\n", 49, spd->dt0_mode, - " spd->dt0_mode, * 49 DRAM Case Temperature Rise from " - "Ambient due to Activate-Precharge/Mode Bits " - "(DT0/Mode Bits) *)"); - printf("%-3d : %02x %s\n", 50, spd->dt2n_dt2q, - " spd->dt2n_dt2q, * 50 DRAM Case Temperature Rise from " - "Ambient due to Precharge/Quiet Standby " - "(DT2N/DT2Q) *"); - printf("%-3d : %02x %s\n", 51, spd->dt2p, - " spd->dt2p, * 51 DRAM Case Temperature Rise from " - "Ambient due to Precharge Power-Down (DT2P) *"); - printf("%-3d : %02x %s\n", 52, spd->dt3n, - " spd->dt3n, * 52 DRAM Case Temperature Rise from " - "Ambient due to Active Standby (DT3N) *"); - printf("%-3d : %02x %s\n", 53, spd->dt3pfast, - " spd->dt3pfast, * 53 DRAM Case Temperature Rise from " - "Ambient due to Active Power-Down with Fast PDN Exit " - "(DT3Pfast) *"); - printf("%-3d : %02x %s\n", 54, spd->dt3pslow, - " spd->dt3pslow, * 54 DRAM Case Temperature Rise from " - "Ambient due to Active Power-Down with Slow PDN Exit " - "(DT3Pslow) *"); - printf("%-3d : %02x %s\n", 55, spd->dt4r_dt4r4w, - " spd->dt4r_dt4r4w, * 55 DRAM Case Temperature Rise from " - "Ambient due to Page Open Burst Read/DT4R4W Mode Bit " - "(DT4R/DT4R4W Mode Bit) *"); - printf("%-3d : %02x %s\n", 56, spd->dt5b, - " spd->dt5b, * 56 DRAM Case Temperature Rise from " - "Ambient due to Burst Refresh (DT5B) *"); - printf("%-3d : %02x %s\n", 57, spd->dt7, - " spd->dt7, * 57 DRAM Case Temperature Rise from " - "Ambient due to Bank Interleave Reads with " - "Auto-Precharge (DT7) *"); - printf("%-3d : %02x %s\n", 58, spd->psi_ta_pll, - " spd->psi_ta_pll, * 58 Thermal Resistance of PLL Package form" - " Top (Case) to Ambient (Psi T-A PLL) *"); - printf("%-3d : %02x %s\n", 59, spd->psi_ta_reg, - " spd->psi_ta_reg, * 59 Thermal Reisitance of Register Package" - " from Top (Case) to Ambient (Psi T-A Register) *"); - printf("%-3d : %02x %s\n", 60, spd->dtpllactive, - " spd->dtpllactive, * 60 PLL Case Temperature Rise from " - "Ambient due to PLL Active (DT PLL Active) *"); - printf("%-3d : %02x %s\n", 61, spd->dtregact, - " spd->dtregact, " - "* 61 Register Case Temperature Rise from Ambient due to " - "Register Active/Mode Bit (DT Register Active/Mode Bit) *"); - printf("%-3d : %02x %s\n", 62, spd->spd_rev, - " spd->spd_rev, * 62 SPD Data Revision Code *"); - printf("%-3d : %02x %s\n", 63, spd->cksum, - " spd->cksum, * 63 Checksum for bytes 0-62 *"); - - printf("%-3d-%3d: ", 64, 71); - - for (i = 0; i < 8; i++) - printf("%02x", spd->mid[i]); - - printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n"); - - printf("%-3d : %02x %s\n", 72, spd->mloc, - " spd->mloc, * 72 Manufacturing Location *"); - - printf("%-3d-%3d: >>", 73, 90); - for (i = 0; i < 18; i++) - printf("%c", spd->mpart[i]); - - - printf("<<* 73 Manufacturer's Part Number *\n"); - - printf("%-3d-%3d: %02x %02x %s\n", 91, 92, spd->rev[0], spd->rev[1], - "* 91 Revision Code *"); - printf("%-3d-%3d: %02x %02x %s\n", 93, 94, spd->mdate[0], spd->mdate[1], - "* 93 Manufacturing Date *"); - printf("%-3d-%3d: ", 95, 98); - - for (i = 0; i < 4; i++) - printf("%02x", spd->sernum[i]); - - printf("* 95 Assembly Serial Number *\n"); - - printf("%-3d-%3d: ", 99, 127); - for (i = 0; i < 27; i++) - printf("%02x", spd->mspec[i]); - - - printf("* 99 Manufacturer Specific Data *\n"); -} -#endif - -#ifdef CONFIG_FSL_DDR3 -void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) -{ - unsigned int i; - - /* General Section: Bytes 0-59 */ - -#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y); -#define PRINT_NNXXS(n0, n1, x0, x1, s) \ - printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1); - - PRINT_NXS(0, spd->info_size_crc, - "info_size_crc bytes written into serial memory, " - "CRC coverage"); - PRINT_NXS(1, spd->spd_rev, - "spd_rev SPD Revision"); - PRINT_NXS(2, spd->mem_type, - "mem_type Key Byte / DRAM Device Type"); - PRINT_NXS(3, spd->module_type, - "module_type Key Byte / Module Type"); - PRINT_NXS(4, spd->density_banks, - "density_banks SDRAM Density and Banks"); - PRINT_NXS(5, spd->addressing, - "addressing SDRAM Addressing"); - PRINT_NXS(6, spd->module_vdd, - "module_vdd Module Nominal Voltage, VDD"); - PRINT_NXS(7, spd->organization, - "organization Module Organization"); - PRINT_NXS(8, spd->bus_width, - "bus_width Module Memory Bus Width"); - PRINT_NXS(9, spd->ftb_div, - "ftb_div Fine Timebase (FTB) Dividend / Divisor"); - PRINT_NXS(10, spd->mtb_dividend, - "mtb_dividend Medium Timebase (MTB) Dividend"); - PRINT_NXS(11, spd->mtb_divisor, - "mtb_divisor Medium Timebase (MTB) Divisor"); - PRINT_NXS(12, spd->tck_min, - "tck_min SDRAM Minimum Cycle Time"); - PRINT_NXS(13, spd->res_13, - "res_13 Reserved"); - PRINT_NXS(14, spd->caslat_lsb, - "caslat_lsb CAS Latencies Supported, LSB"); - PRINT_NXS(15, spd->caslat_msb, - "caslat_msb CAS Latencies Supported, MSB"); - PRINT_NXS(16, spd->taa_min, - "taa_min Min CAS Latency Time"); - PRINT_NXS(17, spd->twr_min, - "twr_min Min Write REcovery Time"); - PRINT_NXS(18, spd->trcd_min, - "trcd_min Min RAS# to CAS# Delay Time"); - PRINT_NXS(19, spd->trrd_min, - "trrd_min Min Row Active to Row Active Delay Time"); - PRINT_NXS(20, spd->trp_min, - "trp_min Min Row Precharge Delay Time"); - PRINT_NXS(21, spd->tras_trc_ext, - "tras_trc_ext Upper Nibbles for tRAS and tRC"); - PRINT_NXS(22, spd->tras_min_lsb, - "tras_min_lsb Min Active to Precharge Delay Time, LSB"); - PRINT_NXS(23, spd->trc_min_lsb, - "trc_min_lsb Min Active to Active/Refresh Delay Time, LSB"); - PRINT_NXS(24, spd->trfc_min_lsb, - "trfc_min_lsb Min Refresh Recovery Delay Time LSB"); - PRINT_NXS(25, spd->trfc_min_msb, - "trfc_min_msb Min Refresh Recovery Delay Time MSB"); - PRINT_NXS(26, spd->twtr_min, - "twtr_min Min Internal Write to Read Command Delay Time"); - PRINT_NXS(27, spd->trtp_min, - "trtp_min " - "Min Internal Read to Precharge Command Delay Time"); - PRINT_NXS(28, spd->tfaw_msb, - "tfaw_msb Upper Nibble for tFAW"); - PRINT_NXS(29, spd->tfaw_min, - "tfaw_min Min Four Activate Window Delay Time"); - PRINT_NXS(30, spd->opt_features, - "opt_features SDRAM Optional Features"); - PRINT_NXS(31, spd->therm_ref_opt, - "therm_ref_opt SDRAM Thermal and Refresh Opts"); - PRINT_NXS(32, spd->therm_sensor, - "therm_sensor SDRAM Thermal Sensor"); - PRINT_NXS(33, spd->device_type, - "device_type SDRAM Device Type"); - PRINT_NXS(34, spd->fine_tck_min, - "fine_tck_min Fine offset for tCKmin"); - PRINT_NXS(35, spd->fine_taa_min, - "fine_taa_min Fine offset for tAAmin"); - PRINT_NXS(36, spd->fine_trcd_min, - "fine_trcd_min Fine offset for tRCDmin"); - PRINT_NXS(37, spd->fine_trp_min, - "fine_trp_min Fine offset for tRPmin"); - PRINT_NXS(38, spd->fine_trc_min, - "fine_trc_min Fine offset for tRCmin"); - - printf("%-3d-%3d: ", 39, 59); /* Reserved, General Section */ - - for (i = 39; i <= 59; i++) - printf("%02x ", spd->res_39_59[i - 39]); - - puts("\n"); - - switch (spd->module_type) { - case 0x02: /* UDIMM */ - case 0x03: /* SO-DIMM */ - case 0x04: /* Micro-DIMM */ - case 0x06: /* Mini-UDIMM */ - PRINT_NXS(60, spd->mod_section.unbuffered.mod_height, - "mod_height (Unbuffered) Module Nominal Height"); - PRINT_NXS(61, spd->mod_section.unbuffered.mod_thickness, - "mod_thickness (Unbuffered) Module Maximum Thickness"); - PRINT_NXS(62, spd->mod_section.unbuffered.ref_raw_card, - "ref_raw_card (Unbuffered) Reference Raw Card Used"); - PRINT_NXS(63, spd->mod_section.unbuffered.addr_mapping, - "addr_mapping (Unbuffered) Address mapping from " - "Edge Connector to DRAM"); - break; - case 0x01: /* RDIMM */ - case 0x05: /* Mini-RDIMM */ - PRINT_NXS(60, spd->mod_section.registered.mod_height, - "mod_height (Registered) Module Nominal Height"); - PRINT_NXS(61, spd->mod_section.registered.mod_thickness, - "mod_thickness (Registered) Module Maximum Thickness"); - PRINT_NXS(62, spd->mod_section.registered.ref_raw_card, - "ref_raw_card (Registered) Reference Raw Card Used"); - PRINT_NXS(63, spd->mod_section.registered.modu_attr, - "modu_attr (Registered) DIMM Module Attributes"); - PRINT_NXS(64, spd->mod_section.registered.thermal, - "thermal (Registered) Thermal Heat " - "Spreader Solution"); - PRINT_NXS(65, spd->mod_section.registered.reg_id_lo, - "reg_id_lo (Registered) Register Manufacturer ID " - "Code, LSB"); - PRINT_NXS(66, spd->mod_section.registered.reg_id_hi, - "reg_id_hi (Registered) Register Manufacturer ID " - "Code, MSB"); - PRINT_NXS(67, spd->mod_section.registered.reg_rev, - "reg_rev (Registered) Register " - "Revision Number"); - PRINT_NXS(68, spd->mod_section.registered.reg_type, - "reg_type (Registered) Register Type"); - for (i = 69; i <= 76; i++) { - printf("%-3d : %02x rcw[%d]\n", i, - spd->mod_section.registered.rcw[i-69], i-69); - } - break; - default: - /* Module-specific Section, Unsupported Module Type */ - printf("%-3d-%3d: ", 60, 116); - - for (i = 60; i <= 116; i++) - printf("%02x", spd->mod_section.uc[i - 60]); - - break; - } - - /* Unique Module ID: Bytes 117-125 */ - PRINT_NXS(117, spd->mmid_lsb, "Module MfgID Code LSB - JEP-106"); - PRINT_NXS(118, spd->mmid_msb, "Module MfgID Code MSB - JEP-106"); - PRINT_NXS(119, spd->mloc, "Mfg Location"); - PRINT_NNXXS(120, 121, spd->mdate[0], spd->mdate[1], "Mfg Date"); - - printf("%-3d-%3d: ", 122, 125); - - for (i = 122; i <= 125; i++) - printf("%02x ", spd->sernum[i - 122]); - printf(" Module Serial Number\n"); - - /* CRC: Bytes 126-127 */ - PRINT_NNXXS(126, 127, spd->crc[0], spd->crc[1], " SPD CRC"); - - /* Other Manufacturer Fields and User Space: Bytes 128-255 */ - printf("%-3d-%3d: ", 128, 145); - for (i = 128; i <= 145; i++) - printf("%02x ", spd->mpart[i - 128]); - printf(" Mfg's Module Part Number\n"); - - PRINT_NNXXS(146, 147, spd->mrev[0], spd->mrev[1], - "Module Revision code"); - - PRINT_NXS(148, spd->dmid_lsb, "DRAM MfgID Code LSB - JEP-106"); - PRINT_NXS(149, spd->dmid_msb, "DRAM MfgID Code MSB - JEP-106"); - - printf("%-3d-%3d: ", 150, 175); - for (i = 150; i <= 175; i++) - printf("%02x ", spd->msd[i - 150]); - printf(" Mfg's Specific Data\n"); - - printf("%-3d-%3d: ", 176, 255); - for (i = 176; i <= 255; i++) - printf("%02x", spd->cust[i - 176]); - printf(" Mfg's Specific Data\n"); - -} -#endif - -static inline void generic_spd_dump(const generic_spd_eeprom_t *spd) -{ -#if defined(CONFIG_FSL_DDR1) - ddr1_spd_dump(spd); -#elif defined(CONFIG_FSL_DDR2) - ddr2_spd_dump(spd); -#elif defined(CONFIG_FSL_DDR3) - ddr3_spd_dump(spd); -#endif -} - -static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo, - unsigned int ctrl_mask, - unsigned int dimm_mask, - unsigned int do_mask) -{ - unsigned int i, j, retval; - - /* STEP 1: DIMM SPD data */ - if (do_mask & STEP_GET_SPD) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (!(ctrl_mask & (1 << i))) - continue; - - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - if (!(dimm_mask & (1 << j))) - continue; - - printf("SPD info: Controller=%u " - "DIMM=%u\n", i, j); - generic_spd_dump( - &(pinfo->spd_installed_dimms[i][j])); - printf("\n"); - } - printf("\n"); - } - printf("\n"); - } - - /* STEP 2: DIMM Parameters */ - if (do_mask & STEP_COMPUTE_DIMM_PARMS) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (!(ctrl_mask & (1 << i))) - continue; - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - if (!(dimm_mask & (1 << j))) - continue; - printf("DIMM parameters: Controller=%u " - "DIMM=%u\n", i, j); - print_dimm_parameters( - &(pinfo->dimm_params[i][j])); - printf("\n"); - } - printf("\n"); - } - printf("\n"); - } - - /* STEP 3: Common Parameters */ - if (do_mask & STEP_COMPUTE_COMMON_PARMS) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (!(ctrl_mask & (1 << i))) - continue; - printf("\"lowest common\" DIMM parameters: " - "Controller=%u\n", i); - print_lowest_common_dimm_parameters( - &pinfo->common_timing_params[i]); - printf("\n"); - } - printf("\n"); - } - - /* STEP 4: User Configuration Options */ - if (do_mask & STEP_GATHER_OPTS) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (!(ctrl_mask & (1 << i))) - continue; - printf("User Config Options: Controller=%u\n", i); - print_memctl_options(&pinfo->memctl_opts[i]); - printf("\n"); - } - printf("\n"); - } - - /* STEP 5: Address assignment */ - if (do_mask & STEP_ASSIGN_ADDRESSES) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (!(ctrl_mask & (1 << i))) - continue; - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - printf("Address Assignment: Controller=%u " - "DIMM=%u\n", i, j); - printf("Don't have this functionality yet\n"); - } - printf("\n"); - } - printf("\n"); - } - - /* STEP 6: computed controller register values */ - if (do_mask & STEP_COMPUTE_REGS) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (!(ctrl_mask & (1 << i))) - continue; - printf("Computed Register Values: Controller=%u\n", i); - print_fsl_memctl_config_regs( - &pinfo->fsl_ddr_config_reg[i]); - retval = check_fsl_memctl_config_regs( - &pinfo->fsl_ddr_config_reg[i]); - if (retval) { - printf("check_fsl_memctl_config_regs " - "result = %u\n", retval); - } - printf("\n"); - } - printf("\n"); - } -} - -struct data_strings { - const char *data_name; - unsigned int step_mask; - unsigned int dimm_number_required; -}; - -#define DATA_OPTIONS(name, step, dimm) {#name, step, dimm} - -static unsigned int fsl_ddr_parse_interactive_cmd( - char **argv, - int argc, - unsigned int *pstep_mask, - unsigned int *pctlr_mask, - unsigned int *pdimm_mask, - unsigned int *pdimm_number_required - ) { - - static const struct data_strings options[] = { - DATA_OPTIONS(spd, STEP_GET_SPD, 1), - DATA_OPTIONS(dimmparms, STEP_COMPUTE_DIMM_PARMS, 1), - DATA_OPTIONS(commonparms, STEP_COMPUTE_COMMON_PARMS, 0), - DATA_OPTIONS(opts, STEP_GATHER_OPTS, 0), - DATA_OPTIONS(addresses, STEP_ASSIGN_ADDRESSES, 0), - DATA_OPTIONS(regs, STEP_COMPUTE_REGS, 0), - }; - static const unsigned int n_opts = ARRAY_SIZE(options); - - unsigned int i, j; - unsigned int error = 0; - - for (i = 1; i < argc; i++) { - unsigned int matched = 0; - - for (j = 0; j < n_opts; j++) { - if (strcmp(options[j].data_name, argv[i]) != 0) - continue; - *pstep_mask |= options[j].step_mask; - *pdimm_number_required = - options[j].dimm_number_required; - matched = 1; - break; - } - - if (matched) - continue; - - if (argv[i][0] == 'c') { - char c = argv[i][1]; - if (isdigit(c)) - *pctlr_mask |= 1 << (c - '0'); - continue; - } - - if (argv[i][0] == 'd') { - char c = argv[i][1]; - if (isdigit(c)) - *pdimm_mask |= 1 << (c - '0'); - continue; - } - - printf("unknown arg %s\n", argv[i]); - *pstep_mask = 0; - error = 1; - break; - } - - return error; -} - -int fsl_ddr_interactive_env_var_exists(void) -{ - char buffer[CONFIG_SYS_CBSIZE]; - - if (getenv_f("ddr_interactive", buffer, CONFIG_SYS_CBSIZE) >= 0) - return 1; - - return 0; -} - -unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set) -{ - unsigned long long ddrsize; - const char *prompt = "FSL DDR>"; - char buffer[CONFIG_SYS_CBSIZE]; - char buffer2[CONFIG_SYS_CBSIZE]; - char *p = NULL; - char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ - int argc; - unsigned int next_step = STEP_GET_SPD; - const char *usage = { - "commands:\n" - "print print SPD and intermediate computed data\n" - "reset reboot machine\n" - "recompute reload SPD and options to default and recompute regs\n" - "edit modify spd, parameter, or option\n" - "compute recompute registers from current next_step to end\n" - "copy copy parameters\n" - "next_step shows current next_step\n" - "help this message\n" - "go program the memory controller and continue with u-boot\n" - }; - - if (var_is_set) { - if (getenv_f("ddr_interactive", buffer2, CONFIG_SYS_CBSIZE) > 0) { - p = buffer2; - } else { - var_is_set = 0; - } - } - - /* - * The strategy for next_step is that it points to the next - * step in the computation process that needs to be done. - */ - while (1) { - if (var_is_set) { - char *pend = strchr(p, ';'); - if (pend) { - /* found command separator, copy sub-command */ - *pend = '\0'; - strcpy(buffer, p); - p = pend + 1; - } else { - /* separator not found, copy whole string */ - strcpy(buffer, p); - p = NULL; - var_is_set = 0; - } - } else { - /* - * No need to worry for buffer overflow here in - * this function; readline() maxes out at CFG_CBSIZE - */ - readline_into_buffer(prompt, buffer, 0); - } - argc = parse_line(buffer, argv); - if (argc == 0) - continue; - - - if (strcmp(argv[0], "help") == 0) { - puts(usage); - continue; - } - - if (strcmp(argv[0], "next_step") == 0) { - printf("next_step = 0x%02X (%s)\n", - next_step, - step_to_string(next_step)); - continue; - } - - if (strcmp(argv[0], "copy") == 0) { - unsigned int error = 0; - unsigned int step_mask = 0; - unsigned int src_ctlr_mask = 0; - unsigned int src_dimm_mask = 0; - unsigned int dimm_number_required = 0; - unsigned int src_ctlr_num = 0; - unsigned int src_dimm_num = 0; - unsigned int dst_ctlr_num = -1; - unsigned int dst_dimm_num = -1; - unsigned int i, num_dest_parms; - - if (argc == 1) { - printf("copy <src c#> <src d#> <spd|dimmparms|commonparms|opts|addresses|regs> <dst c#> <dst d#>\n"); - continue; - } - - error = fsl_ddr_parse_interactive_cmd( - argv, argc, - &step_mask, - &src_ctlr_mask, - &src_dimm_mask, - &dimm_number_required - ); - - /* XXX: only dimm_number_required and step_mask will - be used by this function. Parse the controller and - DIMM number separately because it is easier. */ - - if (error) - continue; - - /* parse source destination controller / DIMM */ - - num_dest_parms = dimm_number_required ? 2 : 1; - - for (i = 0; i < argc; i++) { - if (argv[i][0] == 'c') { - char c = argv[i][1]; - if (isdigit(c)) { - src_ctlr_num = (c - '0'); - break; - } - } - } - - for (i = 0; i < argc; i++) { - if (argv[i][0] == 'd') { - char c = argv[i][1]; - if (isdigit(c)) { - src_dimm_num = (c - '0'); - break; - } - } - } - - /* parse destination controller / DIMM */ - - for (i = argc - 1; i >= argc - num_dest_parms; i--) { - if (argv[i][0] == 'c') { - char c = argv[i][1]; - if (isdigit(c)) { - dst_ctlr_num = (c - '0'); - break; - } - } - } - - for (i = argc - 1; i >= argc - num_dest_parms; i--) { - if (argv[i][0] == 'd') { - char c = argv[i][1]; - if (isdigit(c)) { - dst_dimm_num = (c - '0'); - break; - } - } - } - - /* TODO: validate inputs */ - - debug("src_ctlr_num = %u, src_dimm_num = %u, dst_ctlr_num = %u, dst_dimm_num = %u, step_mask = %x\n", - src_ctlr_num, src_dimm_num, dst_ctlr_num, dst_dimm_num, step_mask); - - - switch (step_mask) { - - case STEP_GET_SPD: - memcpy(&(pinfo->spd_installed_dimms[dst_ctlr_num][dst_dimm_num]), - &(pinfo->spd_installed_dimms[src_ctlr_num][src_dimm_num]), - sizeof(pinfo->spd_installed_dimms[0][0])); - break; - - case STEP_COMPUTE_DIMM_PARMS: - memcpy(&(pinfo->dimm_params[dst_ctlr_num][dst_dimm_num]), - &(pinfo->dimm_params[src_ctlr_num][src_dimm_num]), - sizeof(pinfo->dimm_params[0][0])); - break; - - case STEP_COMPUTE_COMMON_PARMS: - memcpy(&(pinfo->common_timing_params[dst_ctlr_num]), - &(pinfo->common_timing_params[src_ctlr_num]), - sizeof(pinfo->common_timing_params[0])); - break; - - case STEP_GATHER_OPTS: - memcpy(&(pinfo->memctl_opts[dst_ctlr_num]), - &(pinfo->memctl_opts[src_ctlr_num]), - sizeof(pinfo->memctl_opts[0])); - break; - - /* someday be able to have addresses to copy addresses... */ - - case STEP_COMPUTE_REGS: - memcpy(&(pinfo->fsl_ddr_config_reg[dst_ctlr_num]), - &(pinfo->fsl_ddr_config_reg[src_ctlr_num]), - sizeof(pinfo->memctl_opts[0])); - break; - - default: - printf("unexpected step_mask value\n"); - } - - continue; - - } - - if (strcmp(argv[0], "edit") == 0) { - unsigned int error = 0; - unsigned int step_mask = 0; - unsigned int ctlr_mask = 0; - unsigned int dimm_mask = 0; - char *p_element = NULL; - char *p_value = NULL; - unsigned int dimm_number_required = 0; - unsigned int ctrl_num; - unsigned int dimm_num; - - if (argc == 1) { - /* Only the element and value must be last */ - printf("edit <c#> <d#> " - "<spd|dimmparms|commonparms|opts|" - "addresses|regs> <element> <value>\n"); - printf("for spd, specify byte number for " - "element\n"); - continue; - } - - error = fsl_ddr_parse_interactive_cmd( - argv, argc - 2, - &step_mask, - &ctlr_mask, - &dimm_mask, - &dimm_number_required - ); - - if (error) - continue; - - - /* Check arguments */ - - /* ERROR: If no steps were found */ - if (step_mask == 0) { - printf("Error: No valid steps were specified " - "in argument.\n"); - continue; - } - - /* ERROR: If multiple steps were found */ - if (step_mask & (step_mask - 1)) { - printf("Error: Multiple steps specified in " - "argument.\n"); - continue; - } - - /* ERROR: Controller not specified */ - if (ctlr_mask == 0) { - printf("Error: controller number not " - "specified or no element and " - "value specified\n"); - continue; - } - - if (ctlr_mask & (ctlr_mask - 1)) { - printf("Error: multiple controllers " - "specified, %X\n", ctlr_mask); - continue; - } - - /* ERROR: DIMM number not specified */ - if (dimm_number_required && dimm_mask == 0) { - printf("Error: DIMM number number not " - "specified or no element and " - "value specified\n"); - continue; - } - - if (dimm_mask & (dimm_mask - 1)) { - printf("Error: multipled DIMMs specified\n"); - continue; - } - - p_element = argv[argc - 2]; - p_value = argv[argc - 1]; - - ctrl_num = __ilog2(ctlr_mask); - dimm_num = __ilog2(dimm_mask); - - switch (step_mask) { - case STEP_GET_SPD: - { - unsigned int element_num; - unsigned int value; - - element_num = simple_strtoul(p_element, - NULL, 0); - value = simple_strtoul(p_value, - NULL, 0); - fsl_ddr_spd_edit(pinfo, - ctrl_num, - dimm_num, - element_num, - value); - next_step = STEP_COMPUTE_DIMM_PARMS; - } - break; - - case STEP_COMPUTE_DIMM_PARMS: - fsl_ddr_dimm_parameters_edit( - pinfo, ctrl_num, dimm_num, - p_element, p_value); - next_step = STEP_COMPUTE_COMMON_PARMS; - break; - - case STEP_COMPUTE_COMMON_PARMS: - lowest_common_dimm_parameters_edit(pinfo, - ctrl_num, p_element, p_value); - next_step = STEP_GATHER_OPTS; - break; - - case STEP_GATHER_OPTS: - fsl_ddr_options_edit(pinfo, ctrl_num, - p_element, p_value); - next_step = STEP_ASSIGN_ADDRESSES; - break; - - case STEP_ASSIGN_ADDRESSES: - printf("editing of address assignment " - "not yet implemented\n"); - break; - - case STEP_COMPUTE_REGS: - { - fsl_ddr_regs_edit(pinfo, - ctrl_num, - p_element, - p_value); - next_step = STEP_PROGRAM_REGS; - } - break; - - default: - printf("programming error\n"); - while (1) - ; - break; - } - continue; - } - - if (strcmp(argv[0], "reset") == 0) { - /* - * Reboot machine. - * Args don't seem to matter because this - * doesn't return - */ - do_reset(NULL, 0, 0, NULL); - printf("Reset didn't work\n"); - } - - if (strcmp(argv[0], "recompute") == 0) { - /* - * Recalculate everything, starting with - * loading SPD EEPROM from DIMMs - */ - next_step = STEP_GET_SPD; - ddrsize = fsl_ddr_compute(pinfo, next_step, 0); - continue; - } - - if (strcmp(argv[0], "compute") == 0) { - /* - * Compute rest of steps starting at - * the current next_step/ - */ - ddrsize = fsl_ddr_compute(pinfo, next_step, 0); - continue; - } - - if (strcmp(argv[0], "print") == 0) { - unsigned int error = 0; - unsigned int step_mask = 0; - unsigned int ctlr_mask = 0; - unsigned int dimm_mask = 0; - unsigned int dimm_number_required = 0; - - if (argc == 1) { - printf("print [c<n>] [d<n>] [spd] [dimmparms] " - "[commonparms] [opts] [addresses] [regs]\n"); - continue; - } - - error = fsl_ddr_parse_interactive_cmd( - argv, argc, - &step_mask, - &ctlr_mask, - &dimm_mask, - &dimm_number_required - ); - - if (error) - continue; - - /* If no particular controller was found, print all */ - if (ctlr_mask == 0) - ctlr_mask = 0xFF; - - /* If no particular dimm was found, print all dimms. */ - if (dimm_mask == 0) - dimm_mask = 0xFF; - - /* If no steps were found, print all steps. */ - if (step_mask == 0) - step_mask = STEP_ALL; - - fsl_ddr_printinfo(pinfo, ctlr_mask, - dimm_mask, step_mask); - continue; - } - - if (strcmp(argv[0], "go") == 0) { - if (next_step) - ddrsize = fsl_ddr_compute(pinfo, next_step, 0); - break; - } - - printf("unknown command %s\n", argv[0]); - } - - debug("end of memory = %llu\n", (u64)ddrsize); - - return ddrsize; -} diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c deleted file mode 100644 index 332fe25..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright 2008-2012 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -#include <common.h> -#include <asm/fsl_ddr_sdram.h> - -#include "ddr.h" - -#if defined(CONFIG_FSL_DDR3) -static unsigned int -compute_cas_latency_ddr3(const dimm_params_t *dimm_params, - common_timing_params_t *outpdimm, - unsigned int number_of_dimms) -{ - unsigned int i; - unsigned int taamin_ps = 0; - unsigned int tckmin_x_ps = 0; - unsigned int common_caslat; - unsigned int caslat_actual; - unsigned int retry = 16; - unsigned int tmp; - const unsigned int mclk_ps = get_memory_clk_period_ps(); - - /* compute the common CAS latency supported between slots */ - tmp = dimm_params[0].caslat_x; - for (i = 1; i < number_of_dimms; i++) { - if (dimm_params[i].n_ranks) - tmp &= dimm_params[i].caslat_x; - } - common_caslat = tmp; - - /* compute the max tAAmin tCKmin between slots */ - for (i = 0; i < number_of_dimms; i++) { - taamin_ps = max(taamin_ps, dimm_params[i].taa_ps); - tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps); - } - /* validate if the memory clk is in the range of dimms */ - if (mclk_ps < tckmin_x_ps) { - printf("DDR clock (MCLK cycle %u ps) is faster than " - "the slowest DIMM(s) (tCKmin %u ps) can support.\n", - mclk_ps, tckmin_x_ps); - } - /* determine the acutal cas latency */ - caslat_actual = (taamin_ps + mclk_ps - 1) / mclk_ps; - /* check if the dimms support the CAS latency */ - while (!(common_caslat & (1 << caslat_actual)) && retry > 0) { - caslat_actual++; - retry--; - } - /* once the caculation of caslat_actual is completed - * we must verify that this CAS latency value does not - * exceed tAAmax, which is 20 ns for all DDR3 speed grades - */ - if (caslat_actual * mclk_ps > 20000) { - printf("The choosen cas latency %d is too large\n", - caslat_actual); - } - outpdimm->lowest_common_SPD_caslat = caslat_actual; - - return 0; -} -#endif - -/* - * compute_lowest_common_dimm_parameters() - * - * Determine the worst-case DIMM timing parameters from the set of DIMMs - * whose parameters have been computed into the array pointed to - * by dimm_params. - */ -unsigned int -compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, - common_timing_params_t *outpdimm, - const unsigned int number_of_dimms) -{ - unsigned int i, j; - - unsigned int tckmin_x_ps = 0; - unsigned int tckmax_ps = 0xFFFFFFFF; - unsigned int tckmax_max_ps = 0; - unsigned int trcd_ps = 0; - unsigned int trp_ps = 0; - unsigned int tras_ps = 0; - unsigned int twr_ps = 0; - unsigned int twtr_ps = 0; - unsigned int trfc_ps = 0; - unsigned int trrd_ps = 0; - unsigned int trc_ps = 0; - unsigned int refresh_rate_ps = 0; - unsigned int extended_op_srt = 1; - unsigned int tis_ps = 0; - unsigned int tih_ps = 0; - unsigned int tds_ps = 0; - unsigned int tdh_ps = 0; - unsigned int trtp_ps = 0; - unsigned int tdqsq_max_ps = 0; - unsigned int tqhs_ps = 0; - - unsigned int temp1, temp2; - unsigned int additive_latency = 0; -#if !defined(CONFIG_FSL_DDR3) - const unsigned int mclk_ps = get_memory_clk_period_ps(); - unsigned int lowest_good_caslat; - unsigned int not_ok; - - debug("using mclk_ps = %u\n", mclk_ps); -#endif - - temp1 = 0; - for (i = 0; i < number_of_dimms; i++) { - /* - * If there are no ranks on this DIMM, - * it probably doesn't exist, so skip it. - */ - if (dimm_params[i].n_ranks == 0) { - temp1++; - continue; - } - if (dimm_params[i].n_ranks == 4 && i != 0) { - printf("Found Quad-rank DIMM in wrong bank, ignored." - " Software may not run as expected.\n"); - temp1++; - continue; - } - - /* - * check if quad-rank DIMM is plugged if - * CONFIG_CHIP_SELECT_QUAD_CAPABLE is not defined - * Only the board with proper design is capable - */ -#ifndef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE - if (dimm_params[i].n_ranks == 4 && \ - CONFIG_CHIP_SELECTS_PER_CTRL/CONFIG_DIMM_SLOTS_PER_CTLR < 4) { - printf("Found Quad-rank DIMM, not able to support."); - temp1++; - continue; - } -#endif - /* - * Find minimum tckmax_ps to find fastest slow speed, - * i.e., this is the slowest the whole system can go. - */ - tckmax_ps = min(tckmax_ps, dimm_params[i].tckmax_ps); - - /* Either find maximum value to determine slowest - * speed, delay, time, period, etc */ - tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps); - tckmax_max_ps = max(tckmax_max_ps, dimm_params[i].tckmax_ps); - trcd_ps = max(trcd_ps, dimm_params[i].trcd_ps); - trp_ps = max(trp_ps, dimm_params[i].trp_ps); - tras_ps = max(tras_ps, dimm_params[i].tras_ps); - twr_ps = max(twr_ps, dimm_params[i].twr_ps); - twtr_ps = max(twtr_ps, dimm_params[i].twtr_ps); - trfc_ps = max(trfc_ps, dimm_params[i].trfc_ps); - trrd_ps = max(trrd_ps, dimm_params[i].trrd_ps); - trc_ps = max(trc_ps, dimm_params[i].trc_ps); - tis_ps = max(tis_ps, dimm_params[i].tis_ps); - tih_ps = max(tih_ps, dimm_params[i].tih_ps); - tds_ps = max(tds_ps, dimm_params[i].tds_ps); - tdh_ps = max(tdh_ps, dimm_params[i].tdh_ps); - trtp_ps = max(trtp_ps, dimm_params[i].trtp_ps); - tqhs_ps = max(tqhs_ps, dimm_params[i].tqhs_ps); - refresh_rate_ps = max(refresh_rate_ps, - dimm_params[i].refresh_rate_ps); - /* extended_op_srt is either 0 or 1, 0 having priority */ - extended_op_srt = min(extended_op_srt, - dimm_params[i].extended_op_srt); - - /* - * Find maximum tdqsq_max_ps to find slowest. - * - * FIXME: is finding the slowest value the correct - * strategy for this parameter? - */ - tdqsq_max_ps = max(tdqsq_max_ps, dimm_params[i].tdqsq_max_ps); - } - - outpdimm->ndimms_present = number_of_dimms - temp1; - - if (temp1 == number_of_dimms) { - debug("no dimms this memory controller\n"); - return 0; - } - - outpdimm->tckmin_x_ps = tckmin_x_ps; - outpdimm->tckmax_ps = tckmax_ps; - outpdimm->tckmax_max_ps = tckmax_max_ps; - outpdimm->trcd_ps = trcd_ps; - outpdimm->trp_ps = trp_ps; - outpdimm->tras_ps = tras_ps; - outpdimm->twr_ps = twr_ps; - outpdimm->twtr_ps = twtr_ps; - outpdimm->trfc_ps = trfc_ps; - outpdimm->trrd_ps = trrd_ps; - outpdimm->trc_ps = trc_ps; - outpdimm->refresh_rate_ps = refresh_rate_ps; - outpdimm->extended_op_srt = extended_op_srt; - outpdimm->tis_ps = tis_ps; - outpdimm->tih_ps = tih_ps; - outpdimm->tds_ps = tds_ps; - outpdimm->tdh_ps = tdh_ps; - outpdimm->trtp_ps = trtp_ps; - outpdimm->tdqsq_max_ps = tdqsq_max_ps; - outpdimm->tqhs_ps = tqhs_ps; - - /* Determine common burst length for all DIMMs. */ - temp1 = 0xff; - for (i = 0; i < number_of_dimms; i++) { - if (dimm_params[i].n_ranks) { - temp1 &= dimm_params[i].burst_lengths_bitmask; - } - } - outpdimm->all_dimms_burst_lengths_bitmask = temp1; - - /* Determine if all DIMMs registered buffered. */ - temp1 = temp2 = 0; - for (i = 0; i < number_of_dimms; i++) { - if (dimm_params[i].n_ranks) { - if (dimm_params[i].registered_dimm) { - temp1 = 1; -#ifndef CONFIG_SPL_BUILD - printf("Detected RDIMM %s\n", - dimm_params[i].mpart); -#endif - } else { - temp2 = 1; -#ifndef CONFIG_SPL_BUILD - printf("Detected UDIMM %s\n", - dimm_params[i].mpart); -#endif - } - } - } - - outpdimm->all_dimms_registered = 0; - outpdimm->all_dimms_unbuffered = 0; - if (temp1 && !temp2) { - outpdimm->all_dimms_registered = 1; - } else if (!temp1 && temp2) { - outpdimm->all_dimms_unbuffered = 1; - } else { - printf("ERROR: Mix of registered buffered and unbuffered " - "DIMMs detected!\n"); - } - - temp1 = 0; - if (outpdimm->all_dimms_registered) - for (j = 0; j < 16; j++) { - outpdimm->rcw[j] = dimm_params[0].rcw[j]; - for (i = 1; i < number_of_dimms; i++) { - if (!dimm_params[i].n_ranks) - continue; - if (dimm_params[i].rcw[j] != dimm_params[0].rcw[j]) { - temp1 = 1; - break; - } - } - } - - if (temp1 != 0) - printf("ERROR: Mix different RDIMM detected!\n"); - -#if defined(CONFIG_FSL_DDR3) - if (compute_cas_latency_ddr3(dimm_params, outpdimm, number_of_dimms)) - return 1; -#else - /* - * Compute a CAS latency suitable for all DIMMs - * - * Strategy for SPD-defined latencies: compute only - * CAS latency defined by all DIMMs. - */ - - /* - * Step 1: find CAS latency common to all DIMMs using bitwise - * operation. - */ - temp1 = 0xFF; - for (i = 0; i < number_of_dimms; i++) { - if (dimm_params[i].n_ranks) { - temp2 = 0; - temp2 |= 1 << dimm_params[i].caslat_x; - temp2 |= 1 << dimm_params[i].caslat_x_minus_1; - temp2 |= 1 << dimm_params[i].caslat_x_minus_2; - /* - * FIXME: If there was no entry for X-2 (X-1) in - * the SPD, then caslat_x_minus_2 - * (caslat_x_minus_1) contains either 255 or - * 0xFFFFFFFF because that's what the glorious - * __ilog2 function returns for an input of 0. - * On 32-bit PowerPC, left shift counts with bit - * 26 set (that the value of 255 or 0xFFFFFFFF - * will have), cause the destination register to - * be 0. That is why this works. - */ - temp1 &= temp2; - } - } - - /* - * Step 2: check each common CAS latency against tCK of each - * DIMM's SPD. - */ - lowest_good_caslat = 0; - temp2 = 0; - while (temp1) { - not_ok = 0; - temp2 = __ilog2(temp1); - debug("checking common caslat = %u\n", temp2); - - /* Check if this CAS latency will work on all DIMMs at tCK. */ - for (i = 0; i < number_of_dimms; i++) { - if (!dimm_params[i].n_ranks) { - continue; - } - if (dimm_params[i].caslat_x == temp2) { - if (mclk_ps >= dimm_params[i].tckmin_x_ps) { - debug("CL = %u ok on DIMM %u at tCK=%u" - " ps with its tCKmin_X_ps of %u\n", - temp2, i, mclk_ps, - dimm_params[i].tckmin_x_ps); - continue; - } else { - not_ok++; - } - } - - if (dimm_params[i].caslat_x_minus_1 == temp2) { - unsigned int tckmin_x_minus_1_ps - = dimm_params[i].tckmin_x_minus_1_ps; - if (mclk_ps >= tckmin_x_minus_1_ps) { - debug("CL = %u ok on DIMM %u at " - "tCK=%u ps with its " - "tckmin_x_minus_1_ps of %u\n", - temp2, i, mclk_ps, - tckmin_x_minus_1_ps); - continue; - } else { - not_ok++; - } - } - - if (dimm_params[i].caslat_x_minus_2 == temp2) { - unsigned int tckmin_x_minus_2_ps - = dimm_params[i].tckmin_x_minus_2_ps; - if (mclk_ps >= tckmin_x_minus_2_ps) { - debug("CL = %u ok on DIMM %u at " - "tCK=%u ps with its " - "tckmin_x_minus_2_ps of %u\n", - temp2, i, mclk_ps, - tckmin_x_minus_2_ps); - continue; - } else { - not_ok++; - } - } - } - - if (!not_ok) { - lowest_good_caslat = temp2; - } - - temp1 &= ~(1 << temp2); - } - - debug("lowest common SPD-defined CAS latency = %u\n", - lowest_good_caslat); - outpdimm->lowest_common_SPD_caslat = lowest_good_caslat; - - - /* - * Compute a common 'de-rated' CAS latency. - * - * The strategy here is to find the *highest* dereated cas latency - * with the assumption that all of the DIMMs will support a dereated - * CAS latency higher than or equal to their lowest dereated value. - */ - temp1 = 0; - for (i = 0; i < number_of_dimms; i++) { - temp1 = max(temp1, dimm_params[i].caslat_lowest_derated); - } - outpdimm->highest_common_derated_caslat = temp1; - debug("highest common dereated CAS latency = %u\n", temp1); -#endif /* #if defined(CONFIG_FSL_DDR3) */ - - /* Determine if all DIMMs ECC capable. */ - temp1 = 1; - for (i = 0; i < number_of_dimms; i++) { - if (dimm_params[i].n_ranks && - !(dimm_params[i].edc_config & EDC_ECC)) { - temp1 = 0; - break; - } - } - if (temp1) { - debug("all DIMMs ECC capable\n"); - } else { - debug("Warning: not all DIMMs ECC capable, cant enable ECC\n"); - } - outpdimm->all_dimms_ecc_capable = temp1; - -#ifndef CONFIG_FSL_DDR3 - /* FIXME: move to somewhere else to validate. */ - if (mclk_ps > tckmax_max_ps) { - printf("Warning: some of the installed DIMMs " - "can not operate this slowly.\n"); - return 1; - } -#endif - /* - * Compute additive latency. - * - * For DDR1, additive latency should be 0. - * - * For DDR2, with ODT enabled, use "a value" less than ACTTORW, - * which comes from Trcd, and also note that: - * add_lat + caslat must be >= 4 - * - * For DDR3, we use the AL=0 - * - * When to use additive latency for DDR2: - * - * I. Because you are using CL=3 and need to do ODT on writes and - * want functionality. - * 1. Are you going to use ODT? (Does your board not have - * additional termination circuitry for DQ, DQS, DQS_, - * DM, RDQS, RDQS_ for x4/x8 configs?) - * 2. If so, is your lowest supported CL going to be 3? - * 3. If so, then you must set AL=1 because - * - * WL >= 3 for ODT on writes - * RL = AL + CL - * WL = RL - 1 - * -> - * WL = AL + CL - 1 - * AL + CL - 1 >= 3 - * AL + CL >= 4 - * QED - * - * RL >= 3 for ODT on reads - * RL = AL + CL - * - * Since CL aren't usually less than 2, AL=0 is a minimum, - * so the WL-derived AL should be the -- FIXME? - * - * II. Because you are using auto-precharge globally and want to - * use additive latency (posted CAS) to get more bandwidth. - * 1. Are you going to use auto-precharge mode globally? - * - * Use addtivie latency and compute AL to be 1 cycle less than - * tRCD, i.e. the READ or WRITE command is in the cycle - * immediately following the ACTIVATE command.. - * - * III. Because you feel like it or want to do some sort of - * degraded-performance experiment. - * 1. Do you just want to use additive latency because you feel - * like it? - * - * Validation: AL is less than tRCD, and within the other - * read-to-precharge constraints. - */ - - additive_latency = 0; - -#if defined(CONFIG_FSL_DDR2) - if (lowest_good_caslat < 4) { - additive_latency = (picos_to_mclk(trcd_ps) > lowest_good_caslat) - ? picos_to_mclk(trcd_ps) - lowest_good_caslat : 0; - if (mclk_to_picos(additive_latency) > trcd_ps) { - additive_latency = picos_to_mclk(trcd_ps); - debug("setting additive_latency to %u because it was " - " greater than tRCD_ps\n", additive_latency); - } - } - -#elif defined(CONFIG_FSL_DDR3) - /* - * The system will not use the global auto-precharge mode. - * However, it uses the page mode, so we set AL=0 - */ - additive_latency = 0; -#endif - - /* - * Validate additive latency - * FIXME: move to somewhere else to validate - * - * AL <= tRCD(min) - */ - if (mclk_to_picos(additive_latency) > trcd_ps) { - printf("Error: invalid additive latency exceeds tRCD(min).\n"); - return 1; - } - - /* - * RL = CL + AL; RL >= 3 for ODT_RD_CFG to be enabled - * WL = RL - 1; WL >= 3 for ODT_WL_CFG to be enabled - * ADD_LAT (the register) must be set to a value less - * than ACTTORW if WL = 1, then AL must be set to 1 - * RD_TO_PRE (the register) must be set to a minimum - * tRTP + AL if AL is nonzero - */ - - /* - * Additive latency will be applied only if the memctl option to - * use it. - */ - outpdimm->additive_latency = additive_latency; - - debug("tCKmin_ps = %u\n", outpdimm->tckmin_x_ps); - debug("trcd_ps = %u\n", outpdimm->trcd_ps); - debug("trp_ps = %u\n", outpdimm->trp_ps); - debug("tras_ps = %u\n", outpdimm->tras_ps); - debug("twr_ps = %u\n", outpdimm->twr_ps); - debug("twtr_ps = %u\n", outpdimm->twtr_ps); - debug("trfc_ps = %u\n", outpdimm->trfc_ps); - debug("trrd_ps = %u\n", outpdimm->trrd_ps); - debug("trc_ps = %u\n", outpdimm->trc_ps); - - return 0; -} diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c deleted file mode 100644 index 34d8bc3a..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - * Copyright 2008-2012 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -/* - * Generic driver for Freescale DDR/DDR2/DDR3 memory controller. - * Based on code from spd_sdram.c - * Author: James Yang [at freescale.com] - */ - -#include <common.h> -#include <i2c.h> -#include <asm/fsl_ddr_sdram.h> -#include <asm/fsl_law.h> - -#include "ddr.h" - -void fsl_ddr_set_lawbar( - const common_timing_params_t *memctl_common_params, - unsigned int memctl_interleaved, - unsigned int ctrl_num); -void fsl_ddr_set_intl3r(const unsigned int granule_size); - -#if defined(SPD_EEPROM_ADDRESS) || \ - defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \ - defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4) -#if (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS, -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ - [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ - [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ - [2][0] = SPD_EEPROM_ADDRESS3, /* controller 3 */ -}; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { - [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ - [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ - [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ - [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ - [2][0] = SPD_EEPROM_ADDRESS5, /* controller 3 */ - [2][1] = SPD_EEPROM_ADDRESS6, /* controller 3 */ -}; - -#endif - -static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) -{ - int ret; - - i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM); - - ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, - sizeof(generic_spd_eeprom_t)); - - if (ret) { - if (i2c_address == -#ifdef SPD_EEPROM_ADDRESS - SPD_EEPROM_ADDRESS -#elif defined(SPD_EEPROM_ADDRESS1) - SPD_EEPROM_ADDRESS1 -#endif - ) { - printf("DDR: failed to read SPD from address %u\n", - i2c_address); - } else { - debug("DDR: failed to read SPD from address %u\n", - i2c_address); - } - memset(spd, 0, sizeof(generic_spd_eeprom_t)); - } -} - -__attribute__((weak, alias("__get_spd"))) -void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address); - -void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, - unsigned int ctrl_num) -{ - unsigned int i; - unsigned int i2c_address = 0; - - if (ctrl_num >= CONFIG_NUM_DDR_CONTROLLERS) { - printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num); - return; - } - - for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { - i2c_address = spd_i2c_addr[ctrl_num][i]; - get_spd(&(ctrl_dimms_spd[i]), i2c_address); - } -} -#else -void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, - unsigned int ctrl_num) -{ -} -#endif /* SPD_EEPROM_ADDRESSx */ - -/* - * ASSUMPTIONS: - * - Same number of CONFIG_DIMM_SLOTS_PER_CTLR on each controller - * - Same memory data bus width on all controllers - * - * NOTES: - * - * The memory controller and associated documentation use confusing - * terminology when referring to the orgranization of DRAM. - * - * Here is a terminology translation table: - * - * memory controller/documention |industry |this code |signals - * -------------------------------|-----------|-----------|----------------- - * physical bank/bank |rank |rank |chip select (CS) - * logical bank/sub-bank |bank |bank |bank address (BA) - * page/row |row |page |row address - * ??? |column |column |column address - * - * The naming confusion is further exacerbated by the descriptions of the - * memory controller interleaving feature, where accesses are interleaved - * _BETWEEN_ two seperate memory controllers. This is configured only in - * CS0_CONFIG[INTLV_CTL] of each memory controller. - * - * memory controller documentation | number of chip selects - * | per memory controller supported - * --------------------------------|----------------------------------------- - * cache line interleaving | 1 (CS0 only) - * page interleaving | 1 (CS0 only) - * bank interleaving | 1 (CS0 only) - * superbank interleraving | depends on bank (chip select) - * | interleraving [rank interleaving] - * | mode used on every memory controller - * - * Even further confusing is the existence of the interleaving feature - * _WITHIN_ each memory controller. The feature is referred to in - * documentation as chip select interleaving or bank interleaving, - * although it is configured in the DDR_SDRAM_CFG field. - * - * Name of field | documentation name | this code - * -----------------------------|-----------------------|------------------ - * DDR_SDRAM_CFG[BA_INTLV_CTL] | Bank (chip select) | rank interleaving - * | interleaving - */ - -const char *step_string_tbl[] = { - "STEP_GET_SPD", - "STEP_COMPUTE_DIMM_PARMS", - "STEP_COMPUTE_COMMON_PARMS", - "STEP_GATHER_OPTS", - "STEP_ASSIGN_ADDRESSES", - "STEP_COMPUTE_REGS", - "STEP_PROGRAM_REGS", - "STEP_ALL" -}; - -const char * step_to_string(unsigned int step) { - - unsigned int s = __ilog2(step); - - if ((1 << s) != step) - return step_string_tbl[7]; - - return step_string_tbl[s]; -} - -static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo, - unsigned int dbw_cap_adj[]) -{ - int i, j; - unsigned long long total_mem, current_mem_base, total_ctlr_mem; - unsigned long long rank_density, ctlr_density = 0; - - /* - * If a reduced data width is requested, but the SPD - * specifies a physically wider device, adjust the - * computed dimm capacities accordingly before - * assigning addresses. - */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - unsigned int found = 0; - - switch (pinfo->memctl_opts[i].data_bus_width) { - case 2: - /* 16-bit */ - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned int dw; - if (!pinfo->dimm_params[i][j].n_ranks) - continue; - dw = pinfo->dimm_params[i][j].primary_sdram_width; - if ((dw == 72 || dw == 64)) { - dbw_cap_adj[i] = 2; - break; - } else if ((dw == 40 || dw == 32)) { - dbw_cap_adj[i] = 1; - break; - } - } - break; - - case 1: - /* 32-bit */ - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned int dw; - dw = pinfo->dimm_params[i][j].data_width; - if (pinfo->dimm_params[i][j].n_ranks - && (dw == 72 || dw == 64)) { - /* - * FIXME: can't really do it - * like this because this just - * further reduces the memory - */ - found = 1; - break; - } - } - if (found) { - dbw_cap_adj[i] = 1; - } - break; - - case 0: - /* 64-bit */ - break; - - default: - printf("unexpected data bus width " - "specified controller %u\n", i); - return 1; - } - debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]); - } - - current_mem_base = 0ull; - total_mem = 0; - if (pinfo->memctl_opts[0].memctl_interleaving) { - rank_density = pinfo->dimm_params[0][0].rank_density >> - dbw_cap_adj[0]; - switch (pinfo->memctl_opts[0].ba_intlv_ctl & - FSL_DDR_CS0_CS1_CS2_CS3) { - case FSL_DDR_CS0_CS1_CS2_CS3: - ctlr_density = 4 * rank_density; - break; - case FSL_DDR_CS0_CS1: - case FSL_DDR_CS0_CS1_AND_CS2_CS3: - ctlr_density = 2 * rank_density; - break; - case FSL_DDR_CS2_CS3: - default: - ctlr_density = rank_density; - break; - } - debug("rank density is 0x%llx, ctlr density is 0x%llx\n", - rank_density, ctlr_density); - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (pinfo->memctl_opts[i].memctl_interleaving) { - switch (pinfo->memctl_opts[i].memctl_interleaving_mode) { - case FSL_DDR_CACHE_LINE_INTERLEAVING: - case FSL_DDR_PAGE_INTERLEAVING: - case FSL_DDR_BANK_INTERLEAVING: - case FSL_DDR_SUPERBANK_INTERLEAVING: - total_ctlr_mem = 2 * ctlr_density; - break; - case FSL_DDR_3WAY_1KB_INTERLEAVING: - case FSL_DDR_3WAY_4KB_INTERLEAVING: - case FSL_DDR_3WAY_8KB_INTERLEAVING: - total_ctlr_mem = 3 * ctlr_density; - break; - case FSL_DDR_4WAY_1KB_INTERLEAVING: - case FSL_DDR_4WAY_4KB_INTERLEAVING: - case FSL_DDR_4WAY_8KB_INTERLEAVING: - total_ctlr_mem = 4 * ctlr_density; - break; - default: - panic("Unknown interleaving mode"); - } - pinfo->common_timing_params[i].base_address = - current_mem_base; - pinfo->common_timing_params[i].total_mem = - total_ctlr_mem; - total_mem = current_mem_base + total_ctlr_mem; - debug("ctrl %d base 0x%llx\n", i, current_mem_base); - debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); - } else { - /* when 3rd controller not interleaved */ - current_mem_base = total_mem; - total_ctlr_mem = 0; - pinfo->common_timing_params[i].base_address = - current_mem_base; - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned long long cap = - pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; - pinfo->dimm_params[i][j].base_address = - current_mem_base; - debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); - current_mem_base += cap; - total_ctlr_mem += cap; - } - debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); - pinfo->common_timing_params[i].total_mem = - total_ctlr_mem; - total_mem += total_ctlr_mem; - } - } - } else { - /* - * Simple linear assignment if memory - * controllers are not interleaved. - */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - total_ctlr_mem = 0; - pinfo->common_timing_params[i].base_address = - current_mem_base; - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - /* Compute DIMM base addresses. */ - unsigned long long cap = - pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; - pinfo->dimm_params[i][j].base_address = - current_mem_base; - debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); - current_mem_base += cap; - total_ctlr_mem += cap; - } - debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); - pinfo->common_timing_params[i].total_mem = - total_ctlr_mem; - total_mem += total_ctlr_mem; - } - } - debug("Total mem by %s is 0x%llx\n", __func__, total_mem); - - return total_mem; -} - -/* Use weak function to allow board file to override the address assignment */ -__attribute__((weak, alias("__step_assign_addresses"))) -unsigned long long step_assign_addresses(fsl_ddr_info_t *pinfo, - unsigned int dbw_cap_adj[]); - -unsigned long long -fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, - unsigned int size_only) -{ - unsigned int i, j; - unsigned long long total_mem = 0; - int assert_reset; - - fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg; - common_timing_params_t *timing_params = pinfo->common_timing_params; - assert_reset = board_need_mem_reset(); - - /* data bus width capacity adjust shift amount */ - unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS]; - - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - dbw_capacity_adjust[i] = 0; - } - - debug("starting at step %u (%s)\n", - start_step, step_to_string(start_step)); - - switch (start_step) { - case STEP_GET_SPD: -#if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM) - /* STEP 1: Gather all DIMM SPD data */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i); - } - - case STEP_COMPUTE_DIMM_PARMS: - /* STEP 2: Compute DIMM parameters from SPD data */ - - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned int retval; - generic_spd_eeprom_t *spd = - &(pinfo->spd_installed_dimms[i][j]); - dimm_params_t *pdimm = - &(pinfo->dimm_params[i][j]); - - retval = compute_dimm_parameters(spd, pdimm, i); -#ifdef CONFIG_SYS_DDR_RAW_TIMING - if (!i && !j && retval) { - printf("SPD error on controller %d! " - "Trying fallback to raw timing " - "calculation\n", i); - fsl_ddr_get_dimm_params(pdimm, i, j); - } -#else - if (retval == 2) { - printf("Error: compute_dimm_parameters" - " non-zero returned FATAL value " - "for memctl=%u dimm=%u\n", i, j); - return 0; - } -#endif - if (retval) { - debug("Warning: compute_dimm_parameters" - " non-zero return value for memctl=%u " - "dimm=%u\n", i, j); - } - } - } - -#elif defined(CONFIG_SYS_DDR_RAW_TIMING) - case STEP_COMPUTE_DIMM_PARMS: - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - dimm_params_t *pdimm = - &(pinfo->dimm_params[i][j]); - fsl_ddr_get_dimm_params(pdimm, i, j); - } - } - debug("Filling dimm parameters from board specific file\n"); -#endif - case STEP_COMPUTE_COMMON_PARMS: - /* - * STEP 3: Compute a common set of timing parameters - * suitable for all of the DIMMs on each memory controller - */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - debug("Computing lowest common DIMM" - " parameters for memctl=%u\n", i); - compute_lowest_common_dimm_parameters( - pinfo->dimm_params[i], - &timing_params[i], - CONFIG_DIMM_SLOTS_PER_CTLR); - } - - case STEP_GATHER_OPTS: - /* STEP 4: Gather configuration requirements from user */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - debug("Reloading memory controller " - "configuration options for memctl=%u\n", i); - /* - * This "reloads" the memory controller options - * to defaults. If the user "edits" an option, - * next_step points to the step after this, - * which is currently STEP_ASSIGN_ADDRESSES. - */ - populate_memctl_options( - timing_params[i].all_dimms_registered, - &pinfo->memctl_opts[i], - pinfo->dimm_params[i], i); - /* - * For RDIMMs, JEDEC spec requires clocks to be stable - * before reset signal is deasserted. For the boards - * using fixed parameters, this function should be - * be called from board init file. - */ - if (timing_params[i].all_dimms_registered) - assert_reset = 1; - } - if (assert_reset) { - debug("Asserting mem reset\n"); - board_assert_mem_reset(); - } - - case STEP_ASSIGN_ADDRESSES: - /* STEP 5: Assign addresses to chip selects */ - check_interleaving_options(pinfo); - total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust); - - case STEP_COMPUTE_REGS: - /* STEP 6: compute controller register values */ - debug("FSL Memory ctrl register computation\n"); - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (timing_params[i].ndimms_present == 0) { - memset(&ddr_reg[i], 0, - sizeof(fsl_ddr_cfg_regs_t)); - continue; - } - - compute_fsl_memctl_config_regs( - &pinfo->memctl_opts[i], - &ddr_reg[i], &timing_params[i], - pinfo->dimm_params[i], - dbw_capacity_adjust[i], - size_only); - } - - default: - break; - } - - { - /* - * Compute the amount of memory available just by - * looking for the highest valid CSn_BNDS value. - * This allows us to also experiment with using - * only CS0 when using dual-rank DIMMs. - */ - unsigned int max_end = 0; - - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - for (j = 0; j < CONFIG_CHIP_SELECTS_PER_CTRL; j++) { - fsl_ddr_cfg_regs_t *reg = &ddr_reg[i]; - if (reg->cs[j].config & 0x80000000) { - unsigned int end; - /* - * 0xfffffff is a special value we put - * for unused bnds - */ - if (reg->cs[j].bnds == 0xffffffff) - continue; - end = reg->cs[j].bnds & 0xffff; - if (end > max_end) { - max_end = end; - } - } - } - } - - total_mem = 1 + (((unsigned long long)max_end << 24ULL) - | 0xFFFFFFULL); - } - - return total_mem; -} - -/* - * fsl_ddr_sdram() -- this is the main function to be called by - * initdram() in the board file. - * - * It returns amount of memory configured in bytes. - */ -phys_size_t fsl_ddr_sdram(void) -{ - unsigned int i; - unsigned int law_memctl = LAW_TRGT_IF_DDR_1; - unsigned long long total_memory; - fsl_ddr_info_t info; - int deassert_reset; - - /* Reset info structure. */ - memset(&info, 0, sizeof(fsl_ddr_info_t)); - - /* Compute it once normally. */ -#ifdef CONFIG_FSL_DDR_INTERACTIVE - if (tstc() && (getc() == 'd')) { /* we got a key press of 'd' */ - total_memory = fsl_ddr_interactive(&info, 0); - } else if (fsl_ddr_interactive_env_var_exists()) { - total_memory = fsl_ddr_interactive(&info, 1); - } else -#endif - total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0); - - /* setup 3-way interleaving before enabling DDRC */ - if (info.memctl_opts[0].memctl_interleaving) { - switch (info.memctl_opts[0].memctl_interleaving_mode) { - case FSL_DDR_3WAY_1KB_INTERLEAVING: - case FSL_DDR_3WAY_4KB_INTERLEAVING: - case FSL_DDR_3WAY_8KB_INTERLEAVING: - fsl_ddr_set_intl3r( - info.memctl_opts[0].memctl_interleaving_mode); - break; - default: - break; - } - } - - /* - * Program configuration registers. - * JEDEC specs requires clocks to be stable before deasserting reset - * for RDIMMs. Clocks start after chip select is enabled and clock - * control register is set. During step 1, all controllers have their - * registers set but not enabled. Step 2 proceeds after deasserting - * reset through board FPGA or GPIO. - * For non-registered DIMMs, initialization can go through but it is - * also OK to follow the same flow. - */ - deassert_reset = board_need_mem_reset(); - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (info.common_timing_params[i].all_dimms_registered) - deassert_reset = 1; - } - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - debug("Programming controller %u\n", i); - if (info.common_timing_params[i].ndimms_present == 0) { - debug("No dimms present on controller %u; " - "skipping programming\n", i); - continue; - } - /* - * The following call with step = 1 returns before enabling - * the controller. It has to finish with step = 2 later. - */ - fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i, - deassert_reset ? 1 : 0); - } - if (deassert_reset) { - /* Use board FPGA or GPIO to deassert reset signal */ - debug("Deasserting mem reset\n"); - board_deassert_mem_reset(); - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - /* Call with step = 2 to continue initialization */ - fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), - i, 2); - } - } - - /* program LAWs */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if (info.memctl_opts[i].memctl_interleaving) { - switch (info.memctl_opts[i].memctl_interleaving_mode) { - case FSL_DDR_CACHE_LINE_INTERLEAVING: - case FSL_DDR_PAGE_INTERLEAVING: - case FSL_DDR_BANK_INTERLEAVING: - case FSL_DDR_SUPERBANK_INTERLEAVING: - if (i == 0) { - law_memctl = LAW_TRGT_IF_DDR_INTRLV; - fsl_ddr_set_lawbar(&info.common_timing_params[i], - law_memctl, i); - } else if (i == 2) { - law_memctl = LAW_TRGT_IF_DDR_INTLV_34; - fsl_ddr_set_lawbar(&info.common_timing_params[i], - law_memctl, i); - } - break; - case FSL_DDR_3WAY_1KB_INTERLEAVING: - case FSL_DDR_3WAY_4KB_INTERLEAVING: - case FSL_DDR_3WAY_8KB_INTERLEAVING: - law_memctl = LAW_TRGT_IF_DDR_INTLV_123; - if (i == 0) { - fsl_ddr_set_lawbar(&info.common_timing_params[i], - law_memctl, i); - } - break; - case FSL_DDR_4WAY_1KB_INTERLEAVING: - case FSL_DDR_4WAY_4KB_INTERLEAVING: - case FSL_DDR_4WAY_8KB_INTERLEAVING: - law_memctl = LAW_TRGT_IF_DDR_INTLV_1234; - if (i == 0) - fsl_ddr_set_lawbar(&info.common_timing_params[i], - law_memctl, i); - /* place holder for future 4-way interleaving */ - break; - default: - break; - } - } else { - switch (i) { - case 0: - law_memctl = LAW_TRGT_IF_DDR_1; - break; - case 1: - law_memctl = LAW_TRGT_IF_DDR_2; - break; - case 2: - law_memctl = LAW_TRGT_IF_DDR_3; - break; - case 3: - law_memctl = LAW_TRGT_IF_DDR_4; - break; - default: - break; - } - fsl_ddr_set_lawbar(&info.common_timing_params[i], - law_memctl, i); - } - } - - debug("total_memory by %s = %llu\n", __func__, total_memory); - -#if !defined(CONFIG_PHYS_64BIT) - /* Check for 4G or more. Bad. */ - if (total_memory >= (1ull << 32)) { - puts("Detected "); - print_size(total_memory, " of memory\n"); - printf(" This U-Boot only supports < 4G of DDR\n"); - printf(" You could rebuild it with CONFIG_PHYS_64BIT\n"); - printf(" "); /* re-align to match init_func_ram print */ - total_memory = CONFIG_MAX_MEM_MAPPED; - } -#endif - - return total_memory; -} - -/* - * fsl_ddr_sdram_size() - This function only returns the size of the total - * memory without setting ddr control registers. - */ -phys_size_t -fsl_ddr_sdram_size(void) -{ - fsl_ddr_info_t info; - unsigned long long total_memory = 0; - - memset(&info, 0 , sizeof(fsl_ddr_info_t)); - - /* Compute it once normally. */ - total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1); - - return total_memory; -} diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c deleted file mode 100644 index 1297845..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c +++ /dev/null @@ -1,1147 +0,0 @@ -/* - * Copyright 2008, 2010-2012 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <hwconfig.h> -#include <asm/fsl_ddr_sdram.h> - -#include "ddr.h" - -/* - * Use our own stack based buffer before relocation to allow accessing longer - * hwconfig strings that might be in the environment before we've relocated. - * This is pretty fragile on both the use of stack and if the buffer is big - * enough. However we will get a warning from getenv_f for the later. - */ - -/* Board-specific functions defined in each board's ddr.c */ -extern void fsl_ddr_board_options(memctl_options_t *popts, - dimm_params_t *pdimm, - unsigned int ctrl_num); - -struct dynamic_odt { - unsigned int odt_rd_cfg; - unsigned int odt_wr_cfg; - unsigned int odt_rtt_norm; - unsigned int odt_rtt_wr; -}; - -#ifdef CONFIG_FSL_DDR3 -static const struct dynamic_odt single_Q[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS_AND_OTHER_DIMM, - DDR3_RTT_20_OHM, - DDR3_RTT_120_OHM - }, - { /* cs1 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, /* tied high */ - DDR3_RTT_OFF, - DDR3_RTT_120_OHM - }, - { /* cs2 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS_AND_OTHER_DIMM, - DDR3_RTT_20_OHM, - DDR3_RTT_120_OHM - }, - { /* cs3 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, /* tied high */ - DDR3_RTT_OFF, - DDR3_RTT_120_OHM - } -}; - -static const struct dynamic_odt single_D[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_ALL, - DDR3_RTT_40_OHM, - DDR3_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR3_RTT_OFF, - DDR3_RTT_OFF - }, - {0, 0, 0, 0}, - {0, 0, 0, 0} -}; - -static const struct dynamic_odt single_S[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_ALL, - DDR3_RTT_40_OHM, - DDR3_RTT_OFF - }, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, -}; - -static const struct dynamic_odt dual_DD[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_SAME_DIMM, - DDR3_RTT_120_OHM, - DDR3_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR3_RTT_30_OHM, - DDR3_RTT_OFF - }, - { /* cs2 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_SAME_DIMM, - DDR3_RTT_120_OHM, - DDR3_RTT_OFF - }, - { /* cs3 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR3_RTT_30_OHM, - DDR3_RTT_OFF - } -}; - -static const struct dynamic_odt dual_DS[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_SAME_DIMM, - DDR3_RTT_120_OHM, - DDR3_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR3_RTT_30_OHM, - DDR3_RTT_OFF - }, - { /* cs2 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_ALL, - DDR3_RTT_20_OHM, - DDR3_RTT_120_OHM - }, - {0, 0, 0, 0} -}; -static const struct dynamic_odt dual_SD[4] = { - { /* cs0 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_ALL, - DDR3_RTT_20_OHM, - DDR3_RTT_120_OHM - }, - {0, 0, 0, 0}, - { /* cs2 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_SAME_DIMM, - DDR3_RTT_120_OHM, - DDR3_RTT_OFF - }, - { /* cs3 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR3_RTT_20_OHM, - DDR3_RTT_OFF - } -}; - -static const struct dynamic_odt dual_SS[4] = { - { /* cs0 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_ALL, - DDR3_RTT_30_OHM, - DDR3_RTT_120_OHM - }, - {0, 0, 0, 0}, - { /* cs2 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_ALL, - DDR3_RTT_30_OHM, - DDR3_RTT_120_OHM - }, - {0, 0, 0, 0} -}; - -static const struct dynamic_odt dual_D0[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_SAME_DIMM, - DDR3_RTT_40_OHM, - DDR3_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR3_RTT_OFF, - DDR3_RTT_OFF - }, - {0, 0, 0, 0}, - {0, 0, 0, 0} -}; - -static const struct dynamic_odt dual_0D[4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - { /* cs2 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_SAME_DIMM, - DDR3_RTT_40_OHM, - DDR3_RTT_OFF - }, - { /* cs3 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR3_RTT_OFF, - DDR3_RTT_OFF - } -}; - -static const struct dynamic_odt dual_S0[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR3_RTT_40_OHM, - DDR3_RTT_OFF - }, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} - -}; - -static const struct dynamic_odt dual_0S[4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - { /* cs2 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR3_RTT_40_OHM, - DDR3_RTT_OFF - }, - {0, 0, 0, 0} - -}; - -static const struct dynamic_odt odt_unknown[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR3_RTT_120_OHM, - DDR3_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR3_RTT_120_OHM, - DDR3_RTT_OFF - }, - { /* cs2 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR3_RTT_120_OHM, - DDR3_RTT_OFF - }, - { /* cs3 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR3_RTT_120_OHM, - DDR3_RTT_OFF - } -}; -#else /* CONFIG_FSL_DDR3 */ -static const struct dynamic_odt single_Q[4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} -}; - -static const struct dynamic_odt single_D[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_ALL, - DDR2_RTT_150_OHM, - DDR2_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR2_RTT_OFF, - DDR2_RTT_OFF - }, - {0, 0, 0, 0}, - {0, 0, 0, 0} -}; - -static const struct dynamic_odt single_S[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_ALL, - DDR2_RTT_150_OHM, - DDR2_RTT_OFF - }, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, -}; - -static const struct dynamic_odt dual_DD[4] = { - { /* cs0 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR2_RTT_OFF, - DDR2_RTT_OFF - }, - { /* cs2 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - { /* cs3 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR2_RTT_OFF, - DDR2_RTT_OFF - } -}; - -static const struct dynamic_odt dual_DS[4] = { - { /* cs0 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR2_RTT_OFF, - DDR2_RTT_OFF - }, - { /* cs2 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - {0, 0, 0, 0} -}; - -static const struct dynamic_odt dual_SD[4] = { - { /* cs0 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - {0, 0, 0, 0}, - { /* cs2 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - { /* cs3 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR2_RTT_OFF, - DDR2_RTT_OFF - } -}; - -static const struct dynamic_odt dual_SS[4] = { - { /* cs0 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - {0, 0, 0, 0}, - { /* cs2 */ - FSL_DDR_ODT_OTHER_DIMM, - FSL_DDR_ODT_OTHER_DIMM, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - {0, 0, 0, 0} -}; - -static const struct dynamic_odt dual_D0[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_ALL, - DDR2_RTT_150_OHM, - DDR2_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR2_RTT_OFF, - DDR2_RTT_OFF - }, - {0, 0, 0, 0}, - {0, 0, 0, 0} -}; - -static const struct dynamic_odt dual_0D[4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - { /* cs2 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_ALL, - DDR2_RTT_150_OHM, - DDR2_RTT_OFF - }, - { /* cs3 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR2_RTT_OFF, - DDR2_RTT_OFF - } -}; - -static const struct dynamic_odt dual_S0[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR2_RTT_150_OHM, - DDR2_RTT_OFF - }, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} - -}; - -static const struct dynamic_odt dual_0S[4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - { /* cs2 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR2_RTT_150_OHM, - DDR2_RTT_OFF - }, - {0, 0, 0, 0} - -}; - -static const struct dynamic_odt odt_unknown[4] = { - { /* cs0 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - { /* cs1 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR2_RTT_OFF, - DDR2_RTT_OFF - }, - { /* cs2 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_CS, - DDR2_RTT_75_OHM, - DDR2_RTT_OFF - }, - { /* cs3 */ - FSL_DDR_ODT_NEVER, - FSL_DDR_ODT_NEVER, - DDR2_RTT_OFF, - DDR2_RTT_OFF - } -}; -#endif - -/* - * Automatically seleect bank interleaving mode based on DIMMs - * in this order: cs0_cs1_cs2_cs3, cs0_cs1, null. - * This function only deal with one or two slots per controller. - */ -static inline unsigned int auto_bank_intlv(dimm_params_t *pdimm) -{ -#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) - if (pdimm[0].n_ranks == 4) - return FSL_DDR_CS0_CS1_CS2_CS3; - else if (pdimm[0].n_ranks == 2) - return FSL_DDR_CS0_CS1; -#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -#ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE - if (pdimm[0].n_ranks == 4) - return FSL_DDR_CS0_CS1_CS2_CS3; -#endif - if (pdimm[0].n_ranks == 2) { - if (pdimm[1].n_ranks == 2) - return FSL_DDR_CS0_CS1_CS2_CS3; - else - return FSL_DDR_CS0_CS1; - } -#endif - return 0; -} - -unsigned int populate_memctl_options(int all_dimms_registered, - memctl_options_t *popts, - dimm_params_t *pdimm, - unsigned int ctrl_num) -{ - unsigned int i; - char buffer[HWCONFIG_BUFFER_SIZE]; - char *buf = NULL; -#if defined(CONFIG_FSL_DDR3) || defined(CONFIG_FSL_DDR2) - const struct dynamic_odt *pdodt = odt_unknown; -#endif - ulong ddr_freq; - - /* - * Extract hwconfig from environment since we have not properly setup - * the environment but need it for ddr config params - */ - if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0) - buf = buffer; - -#if defined(CONFIG_FSL_DDR3) || defined(CONFIG_FSL_DDR2) - /* Chip select options. */ - if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) { - switch (pdimm[0].n_ranks) { - case 1: - pdodt = single_S; - break; - case 2: - pdodt = single_D; - break; - case 4: - pdodt = single_Q; - break; - } - } else if (CONFIG_DIMM_SLOTS_PER_CTLR == 2) { - switch (pdimm[0].n_ranks) { -#ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE - case 4: - pdodt = single_Q; - if (pdimm[1].n_ranks) - printf("Error: Quad- and Dual-rank DIMMs " - "cannot be used together\n"); - break; -#endif - case 2: - switch (pdimm[1].n_ranks) { - case 2: - pdodt = dual_DD; - break; - case 1: - pdodt = dual_DS; - break; - case 0: - pdodt = dual_D0; - break; - } - break; - case 1: - switch (pdimm[1].n_ranks) { - case 2: - pdodt = dual_SD; - break; - case 1: - pdodt = dual_SS; - break; - case 0: - pdodt = dual_S0; - break; - } - break; - case 0: - switch (pdimm[1].n_ranks) { - case 2: - pdodt = dual_0D; - break; - case 1: - pdodt = dual_0S; - break; - } - break; - } - } -#endif - - /* Pick chip-select local options. */ - for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { -#if defined(CONFIG_FSL_DDR3) || defined(CONFIG_FSL_DDR2) - popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg; - popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg; - popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm; - popts->cs_local_opts[i].odt_rtt_wr = pdodt[i].odt_rtt_wr; -#else - popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER; - popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS; -#endif - popts->cs_local_opts[i].auto_precharge = 0; - } - - /* Pick interleaving mode. */ - - /* - * 0 = no interleaving - * 1 = interleaving between 2 controllers - */ - popts->memctl_interleaving = 0; - - /* - * 0 = cacheline - * 1 = page - * 2 = (logical) bank - * 3 = superbank (only if CS interleaving is enabled) - */ - popts->memctl_interleaving_mode = 0; - - /* - * 0: cacheline: bit 30 of the 36-bit physical addr selects the memctl - * 1: page: bit to the left of the column bits selects the memctl - * 2: bank: bit to the left of the bank bits selects the memctl - * 3: superbank: bit to the left of the chip select selects the memctl - * - * NOTE: ba_intlv (rank interleaving) is independent of memory - * controller interleaving; it is only within a memory controller. - * Must use superbank interleaving if rank interleaving is used and - * memory controller interleaving is enabled. - */ - - /* - * 0 = no - * 0x40 = CS0,CS1 - * 0x20 = CS2,CS3 - * 0x60 = CS0,CS1 + CS2,CS3 - * 0x04 = CS0,CS1,CS2,CS3 - */ - popts->ba_intlv_ctl = 0; - - /* Memory Organization Parameters */ - popts->registered_dimm_en = all_dimms_registered; - - /* Operational Mode Paramters */ - - /* Pick ECC modes */ - popts->ecc_mode = 0; /* 0 = disabled, 1 = enabled */ -#ifdef CONFIG_DDR_ECC - if (hwconfig_sub_f("fsl_ddr", "ecc", buf)) { - if (hwconfig_subarg_cmp_f("fsl_ddr", "ecc", "on", buf)) - popts->ecc_mode = 1; - } else - popts->ecc_mode = 1; -#endif - popts->ecc_init_using_memctl = 1; /* 0 = use DMA, 1 = use memctl */ - - /* - * Choose DQS config - * 0 for DDR1 - * 1 for DDR2 - */ -#if defined(CONFIG_FSL_DDR1) - popts->dqs_config = 0; -#elif defined(CONFIG_FSL_DDR2) || defined(CONFIG_FSL_DDR3) - popts->dqs_config = 1; -#endif - - /* Choose self-refresh during sleep. */ - popts->self_refresh_in_sleep = 1; - - /* Choose dynamic power management mode. */ - popts->dynamic_power = 0; - - /* - * check first dimm for primary sdram width - * presuming all dimms are similar - * 0 = 64-bit, 1 = 32-bit, 2 = 16-bit - */ -#if defined(CONFIG_FSL_DDR1) || defined(CONFIG_FSL_DDR2) - if (pdimm[0].n_ranks != 0) { - if ((pdimm[0].data_width >= 64) && \ - (pdimm[0].data_width <= 72)) - popts->data_bus_width = 0; - else if ((pdimm[0].data_width >= 32) || \ - (pdimm[0].data_width <= 40)) - popts->data_bus_width = 1; - else { - panic("Error: data width %u is invalid!\n", - pdimm[0].data_width); - } - } -#else - if (pdimm[0].n_ranks != 0) { - if (pdimm[0].primary_sdram_width == 64) - popts->data_bus_width = 0; - else if (pdimm[0].primary_sdram_width == 32) - popts->data_bus_width = 1; - else if (pdimm[0].primary_sdram_width == 16) - popts->data_bus_width = 2; - else { - panic("Error: primary sdram width %u is invalid!\n", - pdimm[0].primary_sdram_width); - } - } -#endif - - popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0; - - /* Choose burst length. */ -#if defined(CONFIG_FSL_DDR3) -#if defined(CONFIG_E500MC) - popts->otf_burst_chop_en = 0; /* on-the-fly burst chop disable */ - popts->burst_length = DDR_BL8; /* Fixed 8-beat burst len */ -#else - if ((popts->data_bus_width == 1) || (popts->data_bus_width == 2)) { - /* 32-bit or 16-bit bus */ - popts->otf_burst_chop_en = 0; - popts->burst_length = DDR_BL8; - } else { - popts->otf_burst_chop_en = 1; /* on-the-fly burst chop */ - popts->burst_length = DDR_OTF; /* on-the-fly BC4 and BL8 */ - } -#endif -#else - popts->burst_length = DDR_BL4; /* has to be 4 for DDR2 */ -#endif - - /* Choose ddr controller address mirror mode */ -#if defined(CONFIG_FSL_DDR3) - popts->mirrored_dimm = pdimm[0].mirrored_dimm; -#endif - - /* Global Timing Parameters. */ - debug("mclk_ps = %u ps\n", get_memory_clk_period_ps()); - - /* Pick a caslat override. */ - popts->cas_latency_override = 0; - popts->cas_latency_override_value = 3; - if (popts->cas_latency_override) { - debug("using caslat override value = %u\n", - popts->cas_latency_override_value); - } - - /* Decide whether to use the computed derated latency */ - popts->use_derated_caslat = 0; - - /* Choose an additive latency. */ - popts->additive_latency_override = 0; - popts->additive_latency_override_value = 3; - if (popts->additive_latency_override) { - debug("using additive latency override value = %u\n", - popts->additive_latency_override_value); - } - - /* - * 2T_EN setting - * - * Factors to consider for 2T_EN: - * - number of DIMMs installed - * - number of components, number of active ranks - * - how much time you want to spend playing around - */ - popts->twot_en = 0; - popts->threet_en = 0; - - /* for RDIMM, address parity enable */ - popts->ap_en = 1; - - /* - * BSTTOPRE precharge interval - * - * Set this to 0 for global auto precharge - * - * FIXME: Should this be configured in picoseconds? - * Why it should be in ps: better understanding of this - * relative to actual DRAM timing parameters such as tRAS. - * e.g. tRAS(min) = 40 ns - */ - popts->bstopre = 0x100; - - /* Minimum CKE pulse width -- tCKE(MIN) */ - popts->tcke_clock_pulse_width_ps - = mclk_to_picos(FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR); - - /* - * Window for four activates -- tFAW - * - * FIXME: UM: applies only to DDR2/DDR3 with eight logical banks only - * FIXME: varies depending upon number of column addresses or data - * FIXME: width, was considering looking at pdimm->primary_sdram_width - */ -#if defined(CONFIG_FSL_DDR1) - popts->tfaw_window_four_activates_ps = mclk_to_picos(1); - -#elif defined(CONFIG_FSL_DDR2) - /* - * x4/x8; some datasheets have 35000 - * x16 wide columns only? Use 50000? - */ - popts->tfaw_window_four_activates_ps = 37500; - -#elif defined(CONFIG_FSL_DDR3) - popts->tfaw_window_four_activates_ps = pdimm[0].tfaw_ps; -#endif - popts->zq_en = 0; - popts->wrlvl_en = 0; -#if defined(CONFIG_FSL_DDR3) - /* - * due to ddr3 dimm is fly-by topology - * we suggest to enable write leveling to - * meet the tQDSS under different loading. - */ - popts->wrlvl_en = 1; - popts->zq_en = 1; - popts->wrlvl_override = 0; -#endif - - /* - * Check interleaving configuration from environment. - * Please refer to doc/README.fsl-ddr for the detail. - * - * If memory controller interleaving is enabled, then the data - * bus widths must be programmed identically for all memory controllers. - * - * XXX: Attempt to set all controllers to the same chip select - * interleaving mode. It will do a best effort to get the - * requested ranks interleaved together such that the result - * should be a subset of the requested configuration. - */ -#if (CONFIG_NUM_DDR_CONTROLLERS > 1) - if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) - goto done; - - if (pdimm[0].n_ranks == 0) { - printf("There is no rank on CS0 for controller %d.\n", ctrl_num); - popts->memctl_interleaving = 0; - goto done; - } - popts->memctl_interleaving = 1; - /* - * test null first. if CONFIG_HWCONFIG is not defined - * hwconfig_arg_cmp returns non-zero - */ - if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "null", buf)) { - popts->memctl_interleaving = 0; - debug("memory controller interleaving disabled.\n"); - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "cacheline", buf)) { - popts->memctl_interleaving_mode = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? - 0 : FSL_DDR_CACHE_LINE_INTERLEAVING; - popts->memctl_interleaving = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? - 0 : 1; - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "page", buf)) { - popts->memctl_interleaving_mode = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? - 0 : FSL_DDR_PAGE_INTERLEAVING; - popts->memctl_interleaving = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? - 0 : 1; - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "bank", buf)) { - popts->memctl_interleaving_mode = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? - 0 : FSL_DDR_BANK_INTERLEAVING; - popts->memctl_interleaving = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? - 0 : 1; - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "superbank", buf)) { - popts->memctl_interleaving_mode = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? - 0 : FSL_DDR_SUPERBANK_INTERLEAVING; - popts->memctl_interleaving = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? - 0 : 1; -#if (CONFIG_NUM_DDR_CONTROLLERS == 3) - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "3way_1KB", buf)) { - popts->memctl_interleaving_mode = - FSL_DDR_3WAY_1KB_INTERLEAVING; - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "3way_4KB", buf)) { - popts->memctl_interleaving_mode = - FSL_DDR_3WAY_4KB_INTERLEAVING; - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "3way_8KB", buf)) { - popts->memctl_interleaving_mode = - FSL_DDR_3WAY_8KB_INTERLEAVING; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 4) - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "4way_1KB", buf)) { - popts->memctl_interleaving_mode = - FSL_DDR_4WAY_1KB_INTERLEAVING; - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "4way_4KB", buf)) { - popts->memctl_interleaving_mode = - FSL_DDR_4WAY_4KB_INTERLEAVING; - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "4way_8KB", buf)) { - popts->memctl_interleaving_mode = - FSL_DDR_4WAY_8KB_INTERLEAVING; -#endif - } else { - popts->memctl_interleaving = 0; - printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); - } -done: -#endif - if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) && - (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) { - /* test null first. if CONFIG_HWCONFIG is not defined, - * hwconfig_subarg_cmp_f returns non-zero */ - if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", - "null", buf)) - debug("bank interleaving disabled.\n"); - else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", - "cs0_cs1", buf)) - popts->ba_intlv_ctl = FSL_DDR_CS0_CS1; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", - "cs2_cs3", buf)) - popts->ba_intlv_ctl = FSL_DDR_CS2_CS3; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", - "cs0_cs1_and_cs2_cs3", buf)) - popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_AND_CS2_CS3; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", - "cs0_cs1_cs2_cs3", buf)) - popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv", - "auto", buf)) - popts->ba_intlv_ctl = auto_bank_intlv(pdimm); - else - printf("hwconfig has unrecognized parameter for bank_intlv.\n"); - switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { - case FSL_DDR_CS0_CS1_CS2_CS3: -#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) - if (pdimm[0].n_ranks < 4) { - popts->ba_intlv_ctl = 0; - printf("Not enough bank(chip-select) for " - "CS0+CS1+CS2+CS3 on controller %d, " - "interleaving disabled!\n", ctrl_num); - } -#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -#ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE - if (pdimm[0].n_ranks == 4) - break; -#endif - if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) { - popts->ba_intlv_ctl = 0; - printf("Not enough bank(chip-select) for " - "CS0+CS1+CS2+CS3 on controller %d, " - "interleaving disabled!\n", ctrl_num); - } - if (pdimm[0].capacity != pdimm[1].capacity) { - popts->ba_intlv_ctl = 0; - printf("Not identical DIMM size for " - "CS0+CS1+CS2+CS3 on controller %d, " - "interleaving disabled!\n", ctrl_num); - } -#endif - break; - case FSL_DDR_CS0_CS1: - if (pdimm[0].n_ranks < 2) { - popts->ba_intlv_ctl = 0; - printf("Not enough bank(chip-select) for " - "CS0+CS1 on controller %d, " - "interleaving disabled!\n", ctrl_num); - } - break; - case FSL_DDR_CS2_CS3: -#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) - if (pdimm[0].n_ranks < 4) { - popts->ba_intlv_ctl = 0; - printf("Not enough bank(chip-select) for CS2+CS3 " - "on controller %d, interleaving disabled!\n", ctrl_num); - } -#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) - if (pdimm[1].n_ranks < 2) { - popts->ba_intlv_ctl = 0; - printf("Not enough bank(chip-select) for CS2+CS3 " - "on controller %d, interleaving disabled!\n", ctrl_num); - } -#endif - break; - case FSL_DDR_CS0_CS1_AND_CS2_CS3: -#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) - if (pdimm[0].n_ranks < 4) { - popts->ba_intlv_ctl = 0; - printf("Not enough bank(CS) for CS0+CS1 and " - "CS2+CS3 on controller %d, " - "interleaving disabled!\n", ctrl_num); - } -#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) - if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) { - popts->ba_intlv_ctl = 0; - printf("Not enough bank(CS) for CS0+CS1 and " - "CS2+CS3 on controller %d, " - "interleaving disabled!\n", ctrl_num); - } -#endif - break; - default: - popts->ba_intlv_ctl = 0; - break; - } - } - - if (hwconfig_sub_f("fsl_ddr", "addr_hash", buf)) { - if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash", "null", buf)) - popts->addr_hash = 0; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash", - "true", buf)) - popts->addr_hash = 1; - } - - if (pdimm[0].n_ranks == 4) - popts->quad_rank_present = 1; - - ddr_freq = get_ddr_freq(0) / 1000000; - if (popts->registered_dimm_en) { - popts->rcw_override = 1; - popts->rcw_1 = 0x000a5a00; - if (ddr_freq <= 800) - popts->rcw_2 = 0x00000000; - else if (ddr_freq <= 1066) - popts->rcw_2 = 0x00100000; - else if (ddr_freq <= 1333) - popts->rcw_2 = 0x00200000; - else - popts->rcw_2 = 0x00300000; - } - - fsl_ddr_board_options(popts, pdimm, ctrl_num); - - return 0; -} - -void check_interleaving_options(fsl_ddr_info_t *pinfo) -{ - int i, j, k, check_n_ranks, intlv_invalid = 0; - unsigned int check_intlv, check_n_row_addr, check_n_col_addr; - unsigned long long check_rank_density; - struct dimm_params_s *dimm; - /* - * Check if all controllers are configured for memory - * controller interleaving. Identical dimms are recommended. At least - * the size, row and col address should be checked. - */ - j = 0; - check_n_ranks = pinfo->dimm_params[0][0].n_ranks; - check_rank_density = pinfo->dimm_params[0][0].rank_density; - check_n_row_addr = pinfo->dimm_params[0][0].n_row_addr; - check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr; - check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - dimm = &pinfo->dimm_params[i][0]; - if (!pinfo->memctl_opts[i].memctl_interleaving) { - continue; - } else if (((check_rank_density != dimm->rank_density) || - (check_n_ranks != dimm->n_ranks) || - (check_n_row_addr != dimm->n_row_addr) || - (check_n_col_addr != dimm->n_col_addr) || - (check_intlv != - pinfo->memctl_opts[i].memctl_interleaving_mode))){ - intlv_invalid = 1; - break; - } else { - j++; - } - - } - if (intlv_invalid) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - pinfo->memctl_opts[i].memctl_interleaving = 0; - printf("Not all DIMMs are identical. " - "Memory controller interleaving disabled.\n"); - } else { - switch (check_intlv) { - case FSL_DDR_CACHE_LINE_INTERLEAVING: - case FSL_DDR_PAGE_INTERLEAVING: - case FSL_DDR_BANK_INTERLEAVING: - case FSL_DDR_SUPERBANK_INTERLEAVING: - if (3 == CONFIG_NUM_DDR_CONTROLLERS) - k = 2; - else - k = CONFIG_NUM_DDR_CONTROLLERS; - break; - case FSL_DDR_3WAY_1KB_INTERLEAVING: - case FSL_DDR_3WAY_4KB_INTERLEAVING: - case FSL_DDR_3WAY_8KB_INTERLEAVING: - case FSL_DDR_4WAY_1KB_INTERLEAVING: - case FSL_DDR_4WAY_4KB_INTERLEAVING: - case FSL_DDR_4WAY_8KB_INTERLEAVING: - default: - k = CONFIG_NUM_DDR_CONTROLLERS; - break; - } - debug("%d of %d controllers are interleaving.\n", j, k); - if (j && (j != k)) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - pinfo->memctl_opts[i].memctl_interleaving = 0; - printf("Not all controllers have compatible " - "interleaving mode. All disabled.\n"); - } - } - debug("Checking interleaving options completed\n"); -} - -int fsl_use_spd(void) -{ - int use_spd = 0; - -#ifdef CONFIG_DDR_SPD - char buffer[HWCONFIG_BUFFER_SIZE]; - char *buf = NULL; - - /* - * Extract hwconfig from environment since we have not properly setup - * the environment but need it for ddr config params - */ - if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0) - buf = buffer; - - /* if hwconfig is not enabled, or "sdram" is not defined, use spd */ - if (hwconfig_sub_f("fsl_ddr", "sdram", buf)) { - if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram", "spd", buf)) - use_spd = 1; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram", - "fixed", buf)) - use_spd = 0; - else - use_spd = 1; - } else - use_spd = 1; -#endif - - return use_spd; -} diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/util.c b/arch/powerpc/cpu/mpc8xxx/ddr/util.c deleted file mode 100644 index acfe1f0..0000000 --- a/arch/powerpc/cpu/mpc8xxx/ddr/util.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2008-2012 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -#include <common.h> -#include <asm/fsl_law.h> -#include <div64.h> - -#include "ddr.h" - -/* To avoid 64-bit full-divides, we factor this here */ -#define ULL_2E12 2000000000000ULL -#define UL_5POW12 244140625UL -#define UL_2POW13 (1UL << 13) - -#define ULL_8FS 0xFFFFFFFFULL - -/* - * Round up mclk_ps to nearest 1 ps in memory controller code - * if the error is 0.5ps or more. - * - * If an imprecise data rate is too high due to rounding error - * propagation, compute a suitably rounded mclk_ps to compute - * a working memory controller configuration. - */ -unsigned int get_memory_clk_period_ps(void) -{ - unsigned int data_rate = get_ddr_freq(0); - unsigned int result; - - /* Round to nearest 10ps, being careful about 64-bit multiply/divide */ - unsigned long long rem, mclk_ps = ULL_2E12; - - /* Now perform the big divide, the result fits in 32-bits */ - rem = do_div(mclk_ps, data_rate); - result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps; - - return result; -} - -/* Convert picoseconds into DRAM clock cycles (rounding up if needed). */ -unsigned int picos_to_mclk(unsigned int picos) -{ - unsigned long long clks, clks_rem; - unsigned long data_rate = get_ddr_freq(0); - - /* Short circuit for zero picos */ - if (!picos) - return 0; - - /* First multiply the time by the data rate (32x32 => 64) */ - clks = picos * (unsigned long long)data_rate; - /* - * Now divide by 5^12 and track the 32-bit remainder, then divide - * by 2*(2^12) using shifts (and updating the remainder). - */ - clks_rem = do_div(clks, UL_5POW12); - clks_rem += (clks & (UL_2POW13-1)) * UL_5POW12; - clks >>= 13; - - /* If we had a remainder greater than the 1ps error, then round up */ - if (clks_rem > data_rate) - clks++; - - /* Clamp to the maximum representable value */ - if (clks > ULL_8FS) - clks = ULL_8FS; - return (unsigned int) clks; -} - -unsigned int mclk_to_picos(unsigned int mclk) -{ - return get_memory_clk_period_ps() * mclk; -} - -void -__fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, - unsigned int law_memctl, - unsigned int ctrl_num) -{ - unsigned long long base = memctl_common_params->base_address; - unsigned long long size = memctl_common_params->total_mem; - - /* - * If no DIMMs on this controller, do not proceed any further. - */ - if (!memctl_common_params->ndimms_present) { - return; - } - -#if !defined(CONFIG_PHYS_64BIT) - if (base >= CONFIG_MAX_MEM_MAPPED) - return; - if ((base + size) >= CONFIG_MAX_MEM_MAPPED) - size = CONFIG_MAX_MEM_MAPPED - base; -#endif - if (set_ddr_laws(base, size, law_memctl) < 0) { - printf("%s: ERROR (ctrl #%d, TRGT ID=%x)\n", __func__, ctrl_num, - law_memctl); - return ; - } - debug("setup ddr law base = 0x%llx, size 0x%llx, TRGT_ID 0x%x\n", - base, size, law_memctl); -} - -__attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void -fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, - unsigned int memctl_interleaved, - unsigned int ctrl_num); - -void fsl_ddr_set_intl3r(const unsigned int granule_size) -{ -#ifdef CONFIG_E6500 - u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); - *mcintl3r = 0x80000000 | (granule_size & 0x1f); - debug("Enable MCINTL3R with granule size 0x%x\n", granule_size); -#endif -} - -u32 fsl_ddr_get_intl3r(void) -{ - u32 val = 0; -#ifdef CONFIG_E6500 - u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); - val = *mcintl3r; -#endif - return val; -} - -void board_add_ram_info(int use_default) -{ - ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC8xxx_DDR_ADDR); - -#if defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3) - u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); -#endif -#if (CONFIG_NUM_DDR_CONTROLLERS > 1) - uint32_t cs0_config = in_be32(&ddr->cs0_config); -#endif - uint32_t sdram_cfg = in_be32(&ddr->sdram_cfg); - int cas_lat; - -#if CONFIG_NUM_DDR_CONTROLLERS >= 2 - if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) { - ddr = (void __iomem *)CONFIG_SYS_MPC8xxx_DDR2_ADDR; - sdram_cfg = in_be32(&ddr->sdram_cfg); - } -#endif -#if CONFIG_NUM_DDR_CONTROLLERS >= 3 - if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) { - ddr = (void __iomem *)CONFIG_SYS_MPC8xxx_DDR3_ADDR; - sdram_cfg = in_be32(&ddr->sdram_cfg); - } -#endif - puts(" (DDR"); - switch ((sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >> - SDRAM_CFG_SDRAM_TYPE_SHIFT) { - case SDRAM_TYPE_DDR1: - puts("1"); - break; - case SDRAM_TYPE_DDR2: - puts("2"); - break; - case SDRAM_TYPE_DDR3: - puts("3"); - break; - default: - puts("?"); - break; - } - - if (sdram_cfg & SDRAM_CFG_32_BE) - puts(", 32-bit"); - else if (sdram_cfg & SDRAM_CFG_16_BE) - puts(", 16-bit"); - else - puts(", 64-bit"); - - /* Calculate CAS latency based on timing cfg values */ - cas_lat = ((in_be32(&ddr->timing_cfg_1) >> 16) & 0xf) + 1; - if ((in_be32(&ddr->timing_cfg_3) >> 12) & 1) - cas_lat += (8 << 1); - printf(", CL=%d", cas_lat >> 1); - if (cas_lat & 0x1) - puts(".5"); - - if (sdram_cfg & SDRAM_CFG_ECC_EN) - puts(", ECC on)"); - else - puts(", ECC off)"); - -#if (CONFIG_NUM_DDR_CONTROLLERS == 3) -#ifdef CONFIG_E6500 - if (*mcintl3r & 0x80000000) { - puts("\n"); - puts(" DDR Controller Interleaving Mode: "); - switch (*mcintl3r & 0x1f) { - case FSL_DDR_3WAY_1KB_INTERLEAVING: - puts("3-way 1KB"); - break; - case FSL_DDR_3WAY_4KB_INTERLEAVING: - puts("3-way 4KB"); - break; - case FSL_DDR_3WAY_8KB_INTERLEAVING: - puts("3-way 8KB"); - break; - default: - puts("3-way UNKNOWN"); - break; - } - } -#endif -#endif -#if (CONFIG_NUM_DDR_CONTROLLERS >= 2) - if (cs0_config & 0x20000000) { - puts("\n"); - puts(" DDR Controller Interleaving Mode: "); - - switch ((cs0_config >> 24) & 0xf) { - case FSL_DDR_CACHE_LINE_INTERLEAVING: - puts("cache line"); - break; - case FSL_DDR_PAGE_INTERLEAVING: - puts("page"); - break; - case FSL_DDR_BANK_INTERLEAVING: - puts("bank"); - break; - case FSL_DDR_SUPERBANK_INTERLEAVING: - puts("super-bank"); - break; - default: - puts("invalid"); - break; - } - } -#endif - - if ((sdram_cfg >> 8) & 0x7f) { - puts("\n"); - puts(" DDR Chip-Select Interleaving Mode: "); - switch(sdram_cfg >> 8 & 0x7f) { - case FSL_DDR_CS0_CS1_CS2_CS3: - puts("CS0+CS1+CS2+CS3"); - break; - case FSL_DDR_CS0_CS1: - puts("CS0+CS1"); - break; - case FSL_DDR_CS2_CS3: - puts("CS2+CS3"); - break; - case FSL_DDR_CS0_CS1_AND_CS2_CS3: - puts("CS0+CS1 and CS2+CS3"); - break; - default: - puts("invalid"); - break; - } - } -} |