diff options
Diffstat (limited to 'arch/ppc/ddr-8xxx')
-rw-r--r-- | arch/ppc/ddr-8xxx/Makefile | 4 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/common_timing_params.h | 46 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/ctrl_regs.c | 778 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/ddr.h | 116 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/ddr2_dimm_params.c | 296 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/ddr3_dimm_params.c | 193 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/ddr_setctrl.c | 90 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/lc_common_dimm_params.c | 255 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/main.c | 246 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/options.c | 147 | ||||
-rw-r--r-- | arch/ppc/ddr-8xxx/util.c | 100 |
11 files changed, 0 insertions, 2271 deletions
diff --git a/arch/ppc/ddr-8xxx/Makefile b/arch/ppc/ddr-8xxx/Makefile deleted file mode 100644 index 43ae3a41df..0000000000 --- a/arch/ppc/ddr-8xxx/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-y += main.o util.o ctrl_regs.o options.o lc_common_dimm_params.o -obj-y += ddr_setctrl.o -obj-$(CONFIG_FSL_DDR2) += ddr2_dimm_params.o -obj-$(CONFIG_FSL_DDR3) += ddr3_dimm_params.o diff --git a/arch/ppc/ddr-8xxx/common_timing_params.h b/arch/ppc/ddr-8xxx/common_timing_params.h deleted file mode 100644 index 85a1e2868f..0000000000 --- a/arch/ppc/ddr-8xxx/common_timing_params.h +++ /dev/null @@ -1,46 +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 - -struct common_timing_params_s { - uint32_t tCKmin_X_ps; - uint32_t tCKmax_ps; - uint32_t tCKmax_max_ps; - uint32_t tRCD_ps; - uint32_t tRP_ps; - uint32_t tRAS_ps; - uint32_t tWR_ps; /* maximum = 63750 ps */ - uint32_t tWTR_ps; /* maximum = 63750 ps */ - uint32_t tRFC_ps; /* maximum = 255 ns + 256 ns + .75 ns - = 511750 ps */ - uint32_t tRRD_ps; /* maximum = 63750 ps */ - uint32_t tRC_ps; /* maximum = 254 ns + .75 ns = 254750 ps */ - uint32_t refresh_rate_ps; - uint32_t extended_op_srt; - uint32_t tIS_ps; /* byte 32, spd->ca_setup */ - uint32_t tIH_ps; /* byte 33, spd->ca_hold */ - uint32_t tDS_ps; /* byte 34, spd->data_setup */ - uint32_t tDH_ps; /* byte 35, spd->data_hold */ - uint32_t tRTP_ps; /* byte 38, spd->trtp */ - uint32_t tDQSQ_max_ps; /* byte 44, spd->tdqsq */ - uint32_t tQHS_ps; /* byte 45, spd->tqhs */ - uint32_t ndimms_present; - uint32_t lowest_common_SPD_caslat; - uint32_t highest_common_derated_caslat; - uint32_t additive_latency; - uint32_t all_DIMMs_burst_lengths_bitmask; - uint32_t all_DIMMs_registered; - uint32_t all_DIMMs_unbuffered; - uint32_t all_DIMMs_ECC_capable; - uint64_t total_mem; - uint64_t base_address; -}; - -#endif diff --git a/arch/ppc/ddr-8xxx/ctrl_regs.c b/arch/ppc/ddr-8xxx/ctrl_regs.c deleted file mode 100644 index e3d43ab09e..0000000000 --- a/arch/ppc/ddr-8xxx/ctrl_regs.c +++ /dev/null @@ -1,778 +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 as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -/* - * Generic driver for Freescale 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" - -static uint32_t compute_cas_write_latency(void) -{ - uint32_t cwl; - const uint32_t 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; - - return cwl; -} - -static void set_csn_config(int dimm_number, int i, - struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct dimm_params_s *dimm) -{ - uint32_t cs_n_en = 0, ap_n_en = 0, odt_rd_cfg = 0, odt_wr_cfg = 0, - ba_bits_cs_n = 0, row_bits_cs_n = 0, col_bits_cs_n = 0, - n_banks_per_sdram_device; - int go_config = 0; - - switch (i) { - case 0: - if (dimm[dimm_number].n_ranks > 0) - go_config = 1; - break; - case 1: - if ((dimm_number == 0 && dimm[0].n_ranks > 1) || - (dimm_number == 1 && dimm[1].n_ranks > 0)) - go_config = 1; - break; - case 2: - if ((dimm_number == 0 && dimm[0].n_ranks > 2) || - (dimm_number >= 1 && dimm[dimm_number].n_ranks > 0)) - go_config = 1; - break; - case 3: - if ((dimm_number == 0 && dimm[0].n_ranks > 3) || - (dimm_number == 1 && dimm[1].n_ranks > 1) || - (dimm_number == 3 && dimm[3].n_ranks > 0)) - go_config = 1; - break; - default: - break; - } - - if (go_config) { - /* Chip Select enable */ - cs_n_en = 1; - /* CSn auto-precharge enable */ - ap_n_en = popts->cs_local_opts[i].auto_precharge; - /* ODT for reads configuration */ - odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg; - /* ODT for writes configuration */ - odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg; - /* Num of bank bits for SDRAM on CSn */ - n_banks_per_sdram_device = - dimm[dimm_number].n_banks_per_sdram_device; - ba_bits_cs_n = __ilog2(n_banks_per_sdram_device) - 2; - /* Num of row bits for SDRAM on CSn */ - row_bits_cs_n = dimm[dimm_number].n_row_addr - 12; - /* Num of ocl bits for SDRAM on CSn */ - col_bits_cs_n = dimm[dimm_number].n_col_addr - 8; - } - - ddr->cs[i].config = (((cs_n_en & 0x1) << 31) - | ((ap_n_en & 0x1) << 23) - | ((odt_rd_cfg & 0x7) << 20) - | ((odt_wr_cfg & 0x7) << 16) - | ((ba_bits_cs_n & 0x3) << 14) - | ((row_bits_cs_n & 0x7) << 8) - | ((col_bits_cs_n & 0x7) << 0)); -} - -static void set_timing_cfg_0(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct dimm_params_s *dimm) -{ - uint32_t trwt_mclk = 0, twrt_mclk = 0, act_pd_exit_mclk, - pre_pd_exit_mclk, taxpd_mclk, tmrd_mclk, txp, - data_rate = fsl_get_ddr_freq(0); - - if (popts->sdram_type == SDRAM_TYPE_DDR2) { - act_pd_exit_mclk = popts->txard; - pre_pd_exit_mclk = popts->txp; - taxpd_mclk = popts->taxpd; - tmrd_mclk = popts->tmrd; - } else { - /* - * tXARD is not part of the DDR3 specification, use the - * parameter txp instead of it. That is: - * txp=max(3nCK, 7.5ns). As well, use tAXPD=1. - */ - txp = max_t(uint32_t, (get_memory_clk_period_ps() * 3), 7500); - data_rate = fsl_get_ddr_freq(0); - tmrd_mclk = 4; - - /* for faster clock, need more time for data setup */ - if (popts->trwt_override) - trwt_mclk = popts->trwt; - else if (data_rate / 1000000 > 1800) - trwt_mclk = 2; - else - trwt_mclk = 0; - - if (data_rate / 1000000 > 1150) - twrt_mclk = 1; - else - twrt_mclk = 0; - - taxpd_mclk = 1; - if (popts->dynamic_power == 0) { - act_pd_exit_mclk = 1; - pre_pd_exit_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; - } - } - - ddr->timing_cfg_0 = (((trwt_mclk & 0x3) << 30) - | ((twrt_mclk & 0x3) << 28) - | ((act_pd_exit_mclk & 0xf) << 20) - | ((pre_pd_exit_mclk & 0xf) << 16) - | ((taxpd_mclk & 0xf) << 8) - | ((tmrd_mclk & 0x1f) << 0) - ); -} - -static void set_timing_cfg_3(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct common_timing_params_s *dimm, - uint32_t cas_latency, uint32_t additive_latency) -{ - uint32_t ext_pretoact, ext_acttopre, ext_acttorw, ext_refrec, ext_wrrec; - - ext_pretoact = picos_to_mclk(dimm->tRP_ps) >> 4; - ext_acttopre = picos_to_mclk(dimm->tRAS_ps) >> 4; - ext_acttorw = picos_to_mclk(dimm->tRCD_ps) >> 4; - cas_latency = ((cas_latency << 1) - 1) >> 4; - additive_latency = additive_latency >> 4; - ext_refrec = (picos_to_mclk(dimm->tRFC_ps) - 8) >> 4; - /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ - ext_wrrec = (picos_to_mclk(dimm->tWR_ps) + - (popts->otf_burst_chop_en ? 2 : 0)) >> 4; - - ddr->timing_cfg_3 = (((ext_pretoact & 0x1) << 28) - | ((ext_acttopre & 0x3) << 24) - | ((ext_acttorw & 0x1) << 22) - | ((ext_refrec & 0x1F) << 16) - | ((cas_latency & 0x3) << 12) - | ((additive_latency & 0x1) << 10) - | ((ext_wrrec & 0x1) << 8) - ); -} - -static void set_timing_cfg_1(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct common_timing_params_s *dimm, - uint32_t cas_latency) -{ - uint32_t pretoact_mclk, acttopre_mclk, acttorw_mclk, refrec_ctrl, - wrrec_mclk, acttoact_mclk, 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(dimm->tRP_ps); - acttopre_mclk = picos_to_mclk(dimm->tRAS_ps); - acttorw_mclk = picos_to_mclk(dimm->tRCD_ps); - - /* - * Translate CAS Latency to a DDR controller field value: - * - * CAS Lat DDR II Ctrl - * Clocks SPD Bit Value - * ------- ------- ------ - * 1.0 0001 - * 1.5 0010 - * 2.0 2 0011 - * 2.5 0100 - * 3.0 3 0101 - * 3.5 0110 - * 4.0 4 0111 - * 4.5 1000 - * 5.0 5 1001 - */ - cas_latency = (cas_latency << 1) - 1; - refrec_ctrl = picos_to_mclk(dimm->tRFC_ps) - 8; - acttoact_mclk = picos_to_mclk(dimm->tRRD_ps); - - wrrec_mclk = picos_to_mclk(dimm->tWR_ps); - if (wrrec_mclk <= 16) - wrrec_mclk = wrrec_table[wrrec_mclk - 1]; - if (popts->otf_burst_chop_en) - wrrec_mclk += 2; - - wrtord_mclk = picos_to_mclk(dimm->tWTR_ps); - if (popts->sdram_type == SDRAM_TYPE_DDR2) { - wrtord_mclk = max_t(uint32_t, wrtord_mclk, 2); - } else { - wrtord_mclk = max_t(uint32_t, wrtord_mclk, 4); - acttoact_mclk = max_t(uint32_t, acttoact_mclk, 4); - } - - if (popts->otf_burst_chop_en) - wrtord_mclk += 2; - - ddr->timing_cfg_1 = (((pretoact_mclk & 0x0F) << 28) - | ((acttopre_mclk & 0x0F) << 24) - | ((acttorw_mclk & 0xF) << 20) - | ((cas_latency & 0xF) << 16) - | ((refrec_ctrl & 0xF) << 12) - | ((wrrec_mclk & 0x0F) << 8) - | ((acttoact_mclk & 0x0F) << 4) - | ((wrtord_mclk & 0x0F) << 0)); -} - -static void set_timing_cfg_2(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct common_timing_params_s *dimm, - uint32_t cas_latency, uint32_t additive_latency) -{ - uint32_t cpo, rd_to_pre, wr_data_delay, cke_pls, four_act; - - cpo = popts->cpo_override; - rd_to_pre = picos_to_mclk(dimm->tRTP_ps); - if (popts->sdram_type == SDRAM_TYPE_DDR2) { - cas_latency = cas_latency - 1; - rd_to_pre = max_t(uint32_t, rd_to_pre, 2); - } else { - cas_latency = compute_cas_write_latency(); - rd_to_pre = max_t(uint32_t, rd_to_pre, 4); - } - - if (popts->otf_burst_chop_en) - rd_to_pre += 2; - - 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 = (((additive_latency & 0xf) << 28) - | ((cpo & 0x1f) << 23) - | ((cas_latency & 0xf) << 19) - | ((rd_to_pre & 7) << 13) - | ((wr_data_delay & 7) << 10) - | ((cke_pls & 0x7) << 6) - | ((four_act & 0x3f) << 0)); -} - -static void set_ddr_sdram_cfg(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct common_timing_params_s *dimm) -{ - uint32_t mem_en, sren, ecc_en, sdram_type, dyn_pwr, dbw, twoT_en, hse, - threet_en, eight_be = 0; - - mem_en = 1; - sren = popts->self_refresh_in_sleep; - if (dimm->all_DIMMs_ECC_capable) - ecc_en = popts->ECC_mode; - else - ecc_en = 0; - - sdram_type = popts->sdram_type; - twoT_en = popts->twoT_en; - dyn_pwr = popts->dynamic_power; - dbw = popts->data_bus_width; - hse = popts->half_strength_driver_enable; - threet_en = popts->threet_en; - - if (sdram_type == SDRAM_TYPE_DDR3) - if ((popts->burst_length == DDR_BL8) || (dbw == 1)) - eight_be = 1; - - ddr->ddr_sdram_cfg = (((mem_en & 0x1) << 31) - | ((sren & 0x1) << 30) - | ((ecc_en & 0x1) << 29) - | ((sdram_type & 0x7) << 24) - | ((dyn_pwr & 0x1) << 21) - | ((dbw & 0x3) << 19) - | ((eight_be & 0x1) << 18) - | ((threet_en & 0x1) << 16) - | ((twoT_en & 0x1) << 15) - | ((hse & 0x1) << 3)); -} - -static void set_ddr_sdram_cfg_2(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts) -{ - struct ddr_board_info_s *bi = popts->board_info; - uint32_t i, dll_rst_dis, dqs_cfg, odt_cfg = 0, num_pr, d_init = 0, - obc_cfg = 0, x4_en, md_en = 0, rcw_en = 0; - - dll_rst_dis = popts->dll_rst_dis; - dqs_cfg = popts->DQS_config; - - /* - * Check for On-Die Termination options and - * assert ODT only during reads to DRAM. - */ - for (i = 0; i < bi->cs_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; - } - - /* Default number of posted refresh */ - num_pr = 1; - - if (popts->ECC_init_using_memctl) { - d_init = 1; - ddr->ddr_data_init = popts->data_init; - } - - if (popts->sdram_type == SDRAM_TYPE_DDR3) { - obc_cfg = popts->otf_burst_chop_en; - md_en = popts->mirrored_dimm; - } - - x4_en = popts->x4_en ? 1 : 0; - - ddr->ddr_sdram_cfg_2 = (((dll_rst_dis & 0x1) << 29) - | ((dqs_cfg & 0x3) << 26) - | ((odt_cfg & 0x3) << 21) - | ((num_pr & 0xf) << 12) - | (x4_en << 10) - | ((obc_cfg & 0x1) << 6) - | ((d_init & 0x1) << 4) - | ((rcw_en & 0x1) << 2) - | ((md_en & 0x1) << 0) - ); -} - -static void set_ddr_sdram_mode_2(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct common_timing_params_s *dimm) -{ - uint16_t esdmode2; - uint32_t rtt_wr, srt = 0, cwl; - - cwl = compute_cas_write_latency() - 5; - - if (popts->rtt_override) - rtt_wr = popts->rtt_wr_override_value; - else - rtt_wr = popts->cs_local_opts[0].odt_rtt_wr; - - if (dimm->extended_op_srt) - srt = dimm->extended_op_srt; - - esdmode2 = (((rtt_wr & 0x3) << 9) - | ((srt & 0x1) << 7) - | ((cwl & 0x7) << 3) - ); - - ddr->ddr_sdram_mode_2 = (esdmode2 & 0xffff) << 16; -} - -static void -set_ddr_sdram_interval(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct common_timing_params_s *dimm) -{ - uint32_t refint, bstopre; - - refint = picos_to_mclk(dimm->refresh_rate_ps); - /* Precharge interval */ - bstopre = popts->bstopre; - - ddr->ddr_sdram_interval = (((refint & 0xFFFF) << 16) - | ((bstopre & 0x3FFF) << 0)); -} -void set_ddr3_sdram_mode(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct common_timing_params_s *dimm, - uint32_t cas_latency, uint32_t additive_latency) -{ - uint16_t esdmode, sdmode; - /* Mode Register - MR1 */ - uint32_t rtt, al; - /* Mode Register - MR0 */ - uint32_t dll_on, wr = 0, dll_rst, mode, caslat = 4, bt, bl, 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}; - uint8_t cas_latency_table[] = { /* From 5 to 16 clocks */ - 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, 0x1, 0x3, 0x5, 0x7, 0x9, - }; - const unsigned int mclk_ps = get_memory_clk_period_ps(); - - 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; - else if (additive_latency == (cas_latency - 2)) - al = 2; - else - al = 0; - - /* - * 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 wrlvl_en is set to 0 here. - */ - esdmode = (((rtt & 0x4) << 7) - | ((rtt & 0x2) << 5) - | ((al & 0x3) << 3) - | ((rtt & 0x1) << 2) - ); - - /* - * DLL control for precharge PD - * 0=slow exit DLL off (tXPDLL) - * 1=fast exit DLL on (tXP) - */ - dll_on = 1; - - wr_mclk = (dimm->tWR_ps + mclk_ps - 1) / mclk_ps; - if (wr_mclk <= 16) - wr = wr_table[wr_mclk - 5]; - - 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) - caslat = cas_latency_table[cas_latency - 5]; - - /* BT: Burst Type (0=Nibble Sequential, 1=Interleaved) */ - bt = 0; - - switch (popts->burst_length) { - case DDR_BL8: - bl = 0; - break; - case DDR_OTF: - bl = 1; - break; - case DDR_BC4: - bl = 2; - break; - default: - bl = 1; - break; - } - - sdmode = (((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 = (((esdmode & 0xffff) << 16) - | ((sdmode & 0xffff) << 0) - ); -} - -void set_ddr2_sdram_mode(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct common_timing_params_s *dimm, - uint32_t cas_latency, uint32_t additive_latency) -{ - uint16_t esdmode, sdmode; - uint32_t dqs_en, rtt, al, wr, bl; - const uint32_t mclk_ps = get_memory_clk_period_ps(); - - /* DQS# Enable: 0=enable, 1=disable */ - dqs_en = !popts->DQS_config; - /* Posted CAS# additive latency (AL) */ - al = additive_latency; - /* Internal Termination Resistor */ - if (popts->rtt_override) - rtt = popts->rtt_override_value; - else - rtt = popts->cs_local_opts[0].odt_rtt_norm; - - /* - * Extended SDRAM mode. - * The variable also selects: - * - OCD set to exit mode - * - all outputs bit i.e DQ, DQS, RDQS output enabled - * - RDQS ball disabled - * - DQS ball enabled - * - DLL enabled - * - Output drive strength: full strength. - */ - esdmode = (((dqs_en & 0x1) << 10) - | ((rtt & 0x2) << 5) - | ((al & 0x7) << 3) - | ((rtt & 0x1) << 2)); - - /* Write recovery */ - wr = ((dimm->tWR_ps + mclk_ps - 1) / mclk_ps) - 1; - - switch (popts->burst_length) { - case DDR_BL4: - bl = 2; - break; - case DDR_BL8: - bl = 3; - break; - default: - bl = 2; - break; - } - - /* SDRAM mode - * The variable also selects: - * - power down mode: fast exit (normal) - * - DLL reset disabled. - * - burst type: sequential - */ - sdmode = (((wr & 0x7) << 9) - | ((cas_latency & 0x7) << 4) - | ((bl & 0x7) << 0)); - - ddr->ddr_sdram_mode = (((esdmode & 0xFFFF) << 16) - | ((sdmode & 0xFFFF) << 0)); -} - -void set_ddrx_sdram_mode(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - const struct common_timing_params_s *dimm, - uint32_t cas_latency, uint32_t additive_latency) -{ - if (popts->sdram_type == SDRAM_TYPE_DDR2) - set_ddr2_sdram_mode(ddr, popts, dimm, cas_latency, - additive_latency); - else - set_ddr3_sdram_mode(ddr, popts, dimm, cas_latency, - additive_latency); -} - -uint32_t check_fsl_memctl_config_regs(const struct fsl_ddr_cfg_regs_s *ddr) -{ - /* - * DDR_SDRAM_CFG[RD_EN] and DDR_SDRAM_CFG[2T_EN should not - * be set at the same time. - */ - if ((ddr->ddr_sdram_cfg & 0x10000000) && - (ddr->ddr_sdram_cfg & 0x00008000)) - return 1; - - return 0; -} - -static void set_timing_cfg_4(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts) -{ - uint32_t rrt = 0, wwt = 0, dll_lock = 1; - - if (popts->burst_length != DDR_BL8) - rrt = wwt = 2; - - ddr->timing_cfg_4 = (((rrt & 0xf) << 20) - | ((wwt & 0xf) << 16) - | (dll_lock & 0x3) - ); -} - -static void set_timing_cfg_5(struct fsl_ddr_cfg_regs_s *ddr, - const struct memctl_options_s *popts, - uint32_t cas_latency) -{ - uint32_t rodt_on, rodt_off = 4, wodt_on = 1, wodt_off = 4; - - /* rodt_on = timing_cfg_1[caslat] - timing_cfg_2[wrlat] + 1 */ - rodt_on = cas_latency - ((ddr->timing_cfg_2 & 0x00780000) >> 19) + 1; - - ddr->timing_cfg_5 = (((rodt_on & 0x1f) << 24) - | ((rodt_off & 0x7) << 20) - | ((wodt_on & 0x1f) << 12) - | ((wodt_off & 0x7) << 8) - ); -} - -static void set_ddr_zq_cntl(struct fsl_ddr_cfg_regs_s *ddr, uint32_t zq_en) -{ - uint32_t zqinit = 0, zqoper = 0, zqcs = 0; - - if (zq_en) { - zqinit = 9; - zqoper = 8; - zqcs = 6; - } - - ddr->ddr_zq_cntl = (((zq_en & 0x1) << 31) - | ((zqinit & 0xf) << 24) - | ((zqoper & 0xf) << 16) - | ((zqcs & 0xf) << 8) - ); -} - -static void set_ddr_wrlvl_cntl(struct fsl_ddr_cfg_regs_s *ddr, - uint32_t wrlvl_en, const struct memctl_options_s *popts) -{ - uint32_t wrlvl_mrd = 0, wrlvl_odten = 0, wrlvl_dqsen = 0, - wrlvl_wlr = 0, wrlvl_start = 0, wrlvl_smpl = 0; - - /* Enable write leveling for DDR3 due to fly-by topology */ - if (wrlvl_en) { - wrlvl_mrd = 0x6; - wrlvl_odten = 0x7; - 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 - * Set it to 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; - if (popts->wrlvl_override) { - wrlvl_smpl = popts->wrlvl_sample; - wrlvl_start = popts->wrlvl_start; - } - } - - ddr->ddr_wrlvl_cntl = (((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) - ); -} - -uint32_t -compute_fsl_memctl_config_regs(const struct memctl_options_s *popts, - struct fsl_ddr_cfg_regs_s *ddr, - const struct common_timing_params_s *dimm, - const struct dimm_params_s *dimmp, - uint32_t dbw_cap_adj) -{ - struct ddr_board_info_s *binfo = popts->board_info; - uint32_t cas_latency, additive_latency, i, cs_per_dimm, - dimm_number, zq_en, wrlvl_en, sr_it = 0; - uint64_t ea, sa, rank_density; - - if (dimm == NULL) - return 1; - - memset(ddr, 0, sizeof(struct fsl_ddr_cfg_regs_s)); - - /* Process overrides first. */ - if (popts->cas_latency_override) - cas_latency = popts->cas_latency_override_value; - else - cas_latency = dimm->lowest_common_SPD_caslat; - - if (popts->additive_latency_override) - additive_latency = popts->additive_latency_override_value; - else - additive_latency = dimm->additive_latency; - - if (popts->auto_self_refresh_en) - sr_it = popts->sr_it; - - /* Chip Select Memory Bounds (CSn_BNDS) */ - for (i = 0; i < binfo->cs_per_ctrl; i++) { - cs_per_dimm = binfo->cs_per_ctrl / binfo->dimm_slots_per_ctrl; - dimm_number = i / cs_per_dimm; - rank_density = - dimmp[dimm_number].rank_density >> dbw_cap_adj; - - if (dimmp[dimm_number].n_ranks == 0) - continue; - - sa = dimmp[dimm_number].base_address; - ea = sa + rank_density - 1; - if (dimmp[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; - } - sa >>= 24; - ea >>= 24; - - ddr->cs[i].bnds = - (((sa & 0xffff) << 16) | ((ea & 0xffff) << 0)); - set_csn_config(dimm_number, i, ddr, popts, dimmp); - } - - set_timing_cfg_0(ddr, popts, dimmp); - set_timing_cfg_3(ddr, popts, dimm, cas_latency, additive_latency); - set_timing_cfg_1(ddr, popts, dimm, cas_latency); - set_timing_cfg_2(ddr, popts, dimm, cas_latency, additive_latency); - - ddr->ddr_cdr1 = popts->ddr_cdr1; - ddr->ddr_cdr1 = popts->ddr_cdr2; - - set_ddr_sdram_cfg(ddr, popts, dimm); - set_ddr_sdram_cfg_2(ddr, popts); - set_ddrx_sdram_mode(ddr, popts, dimm, cas_latency, additive_latency); - if (popts->sdram_type == SDRAM_TYPE_DDR3) { - set_ddr_sdram_mode_2(ddr, popts, dimm); - set_timing_cfg_4(ddr, popts); - set_timing_cfg_5(ddr, popts, cas_latency); - zq_en = (popts->zq_en) ? 1 : 0; - set_ddr_zq_cntl(ddr, zq_en); - wrlvl_en = (popts->wrlvl_en) ? 1 : 0; - set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts); - } - set_ddr_sdram_interval(ddr, popts, dimm); - - ddr->ddr_data_init = popts->data_init; - ddr->ddr_sdram_clk_cntl = (popts->clk_adjust & 0xF) << 23; - - ddr->ddr_sr_cntr = (sr_it & 0xf) << 16; - - return check_fsl_memctl_config_regs(ddr); -} diff --git a/arch/ppc/ddr-8xxx/ddr.h b/arch/ppc/ddr-8xxx/ddr.h deleted file mode 100644 index 2ef87f2776..0000000000 --- a/arch/ppc/ddr-8xxx/ddr.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2013 GE Intelligent Platforms, Inc - * 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 <mach/fsl_i2c.h> -#include <mach/clock.h> -#include "common_timing_params.h" - -#ifdef CONFIG_MPC85xx -#include <mach/immap_85xx.h> -#endif - -/* Record of computed register values. */ -struct fsl_ddr_cfg_regs_s { - struct { - uint32_t bnds; - uint32_t config; - uint32_t config_2; - } cs[MAX_CHIP_SELECTS_PER_CTRL]; - uint32_t timing_cfg_3; - uint32_t timing_cfg_0; - uint32_t timing_cfg_1; - uint32_t timing_cfg_2; - uint32_t ddr_sdram_cfg; - uint32_t ddr_sdram_cfg_2; - uint32_t ddr_sdram_mode; - uint32_t ddr_sdram_mode_2; - uint32_t ddr_sdram_mode_3; - uint32_t ddr_sdram_mode_4; - uint32_t ddr_sdram_mode_5; - uint32_t ddr_sdram_mode_6; - uint32_t ddr_sdram_mode_7; - uint32_t ddr_sdram_mode_8; - uint32_t ddr_sdram_md_cntl; - uint32_t ddr_sdram_interval; - uint32_t ddr_data_init; - uint32_t ddr_sdram_clk_cntl; - uint32_t ddr_init_addr; - uint32_t ddr_init_ext_addr; - uint32_t timing_cfg_4; - uint32_t timing_cfg_5; - uint32_t ddr_zq_cntl; - uint32_t ddr_wrlvl_cntl; - uint32_t ddr_wrlvl_cntl_2; - uint32_t ddr_wrlvl_cntl_3; - uint32_t ddr_sr_cntr; - uint32_t ddr_sdram_rcw_1; - uint32_t ddr_sdram_rcw_2; - uint32_t ddr_cdr1; - uint32_t ddr_cdr2; - uint32_t err_disable; - uint32_t err_int_en; - uint32_t debug[32]; -}; - -/* - * Data Structures - * - * All data structures have to be on the stack - */ -struct fsl_ddr_info_s { - generic_spd_eeprom_t - spd_installed_dimms[MAX_DIMM_SLOTS_PER_CTLR]; - struct dimm_params_s - dimm_params[MAX_DIMM_SLOTS_PER_CTLR]; - struct memctl_options_s memctl_opts; - struct common_timing_params_s common_timing_params; - struct fsl_ddr_cfg_regs_s fsl_ddr_config_reg; - struct ddr_board_info_s board_info; -}; - -uint32_t mclk_to_picos(uint32_t mclk); -uint32_t get_memory_clk_period_ps(void); -uint32_t picos_to_mclk(uint32_t picos); -uint32_t check_fsl_memctl_config_regs(const struct fsl_ddr_cfg_regs_s *ddr); -uint64_t fsl_ddr_compute(struct fsl_ddr_info_s *pinfo); -uint32_t compute_fsl_memctl_config_regs( - const struct memctl_options_s *popts, - struct fsl_ddr_cfg_regs_s *ddr, - const struct common_timing_params_s *common_dimm, - const struct dimm_params_s *dimm_parameters, - uint32_t dbw_capacity_adjust); -uint32_t compute_dimm_parameters( - const generic_spd_eeprom_t *spdin, - struct dimm_params_s *pdimm); -void compute_lowest_common_dimm_parameters( - const struct fsl_ddr_info_s *pinfo, - struct common_timing_params_s *outpdimm, - uint32_t number_of_dimms); -uint32_t populate_memctl_options( - int all_DIMMs_registered, - struct memctl_options_s *popts, - struct dimm_params_s *pdimm); -int fsl_ddr_set_lawbar( - const struct common_timing_params_s *memctl_common_params, - uint32_t memctl_interleaved); -int fsl_ddr_get_spd( - generic_spd_eeprom_t *ctrl_dimms_spd, - struct ddr_board_info_s *binfo); -int fsl_ddr_set_memctl_regs( - const struct fsl_ddr_info_s *info); -void fsl_ddr_board_options( - struct memctl_options_s *popts, - struct dimm_params_s *pdimm); -void fsl_ddr_board_info(struct ddr_board_info_s *info); -#endif diff --git a/arch/ppc/ddr-8xxx/ddr2_dimm_params.c b/arch/ppc/ddr-8xxx/ddr2_dimm_params.c deleted file mode 100644 index 22c05ca6da..0000000000 --- a/arch/ppc/ddr-8xxx/ddr2_dimm_params.c +++ /dev/null @@ -1,296 +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. - * - * Table comes from Byte 31 of JEDEC SPD Spec. - * - * DDR II - * Bit Size Size - * --- ----- - * 7 high 512MB - * 6 256MB - * 5 128MB - * 4 16GB - * 3 8GB - * 2 4GB - * 1 2GB - * 0 low 1GB - * - * Reorder Table to be linear by stripping the bottom - * 2 or 5 bits off and shifting them up to the top. - * - */ -static uint64_t compute_ranksize(uint32_t mem_type, unsigned char row_dens) -{ - uint64_t bsize; - - bsize = ((row_dens >> 5) | ((row_dens & 31) << 3)); - bsize <<= 27ULL; - - return bsize; -} - -/* - * Convert a two-nibble BCD value into a cycle time. - * While the spec calls for nano-seconds, picos are returned. - */ -static uint32_t convert_bcd_tenths_to_cycle_time_ps(uint32_t spd_val) -{ - uint32_t tenths_ps[16] = { - 0, - 100, - 200, - 300, - 400, - 500, - 600, - 700, - 800, - 900, - 250, - 330, - 660, - 750, - 0, - 0 - }; - uint32_t whole_ns = (spd_val & 0xF0) >> 4; - uint32_t tenth_ns = spd_val & 0x0F; - uint32_t ps = (whole_ns * 1000) + tenths_ps[tenth_ns]; - - return ps; -} - -static uint32_t convert_bcd_hundredths_to_cycle_time_ps(uint32_t spd_val) -{ - uint32_t tenth_ns = (spd_val & 0xF0) >> 4; - uint32_t hundredth_ns = spd_val & 0x0F; - uint32_t ps = (tenth_ns * 100) + (hundredth_ns * 10); - - return ps; -} - -static uint32_t byte40_table_ps[8] = { - 0, - 250, - 330, - 500, - 660, - 750, - 0, - 0 -}; - -static uint32_t -compute_trfc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trfc) -{ - uint32_t trfc_ps; - - trfc_ps = (((trctrfc_ext & 0x1) * 256) + trfc) * 1000; - trfc_ps += byte40_table_ps[(trctrfc_ext >> 1) & 0x7]; - - return trfc_ps; -} - -static uint32_t -compute_trc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trc) -{ - uint32_t trc_ps; - - trc_ps = (trc * 1000); - trc_ps += byte40_table_ps[(trctrfc_ext >> 4) & 0x7]; - - return trc_ps; -} - -/* - * Determine Refresh Rate. - * Table from SPD Spec, Byte 12, converted to picoseconds and - * filled in with "default" normal values. - */ -static uint32_t determine_refresh_rate_ps(const uint32_t spd_refresh) -{ - uint32_t 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 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 standard 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 */ -uint16_t ddr2_speed_bins[] = { 0, 5000, 3750, 3000, 2500, 1875 }; - -uint32_t compute_derated_DDR2_CAS_latency(uint32_t mclk_ps) -{ - const uint32_t num_speed_bins = ARRAY_SIZE(ddr2_speed_bins); - uint32_t lowest_tCKmin_found = 0, lowest_tCKmin_CL = 0, i, x; - - for (i = 0; i < num_speed_bins; i++) { - x = ddr2_speed_bins[i]; - if (x && (x <= mclk_ps) && (x >= lowest_tCKmin_found)) { - lowest_tCKmin_found = x; - lowest_tCKmin_CL = i + 2; - } - } - - return lowest_tCKmin_CL; -} - -/* - * compute_dimm_parameters for DDR2 SPD - * - * Compute DIMM parameters based upon the SPD information in SPD. - * Writes the results to the dimm_params_s structure pointed by pdimm. - */ -uint32_t -compute_dimm_parameters(const generic_spd_eeprom_t *spdin, - struct dimm_params_s *pdimm) -{ - const struct ddr2_spd_eeprom *spd = spdin; - int retval; - - if (spd->mem_type != SPD_MEMTYPE_DDR2) - goto error; - - retval = ddr2_spd_check(spd); - if (retval) - goto error; - - /* - * 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: - goto error; - } - - 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)); - pdimm->caslat_lowest_derated - = compute_derated_DDR2_CAS_latency(get_memory_clk_period_ps()); - 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; -error: - return 1; -} diff --git a/arch/ppc/ddr-8xxx/ddr3_dimm_params.c b/arch/ppc/ddr-8xxx/ddr3_dimm_params.c deleted file mode 100644 index 4f44925ab9..0000000000 --- a/arch/ppc/ddr-8xxx/ddr3_dimm_params.c +++ /dev/null @@ -1,193 +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 uint64_t compute_ranksize(const struct ddr3_spd_eeprom *spd) -{ - uint64_t bsize; - int sdram_cap_bsize = 0, prim_bus_width = 0, sdram_width = 0; - - if ((spd->density_banks & 0xf) < 7) - sdram_cap_bsize = (spd->density_banks & 0xf) + 28; - if ((spd->bus_width & 0x7) < 4) - prim_bus_width = (spd->bus_width & 0x7) + 3; - if ((spd->organization & 0x7) < 4) - sdram_width = (spd->organization & 0x7) + 2; - - bsize = 1ULL << (sdram_cap_bsize - 3 + prim_bus_width - sdram_width); - - return bsize; -} - -/* - * compute_dimm_parameters for DDR3 SPD - * - * Compute DIMM parameters based upon the SPD information in spd. - * Writes the results to the dimm_params_s structure pointed by pdimm. - * - */ -uint32_t -compute_dimm_parameters(const generic_spd_eeprom_t *spdin, - struct dimm_params_s *pdimm) -{ - const struct ddr3_spd_eeprom *spd = spdin; - uint32_t mtb_ps; - int retval, ftb_tmp; - - if (spd->mem_type != SPD_MEMTYPE_DDR3) - goto error; - - retval = ddr3_spd_check(spd); - if (retval) - goto error; - - 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->data_width = pdimm->primary_sdram_width + pdimm->ec_sdram_width; - 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->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_UDIMM: - /* Unbuffered DIMMs */ - if (spd->mod_section.unbuffered.addr_mapping & 0x1) - pdimm->mirrored_dimm = 1; - break; - - default: - goto error; - } - - /* 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 does not define an ECC bit. The DIMM is considered - * to have ECC capability if the extension bus exists. - */ - if (pdimm->ec_sdram_width) - pdimm->edc_config = 0x02; - else - pdimm->edc_config = 0x00; - - /* - * The SPD spec does not define the burst length byte. - * but the DDR3 spec defines BL8 and BC4, on bit 3 and - * bit 2. - */ - pdimm->burst_lengths_bitmask = 0x0c; - pdimm->row_density = __ilog2(pdimm->rank_density); - - mtb_ps = (spd->mtb_dividend * 1000) / spd->mtb_divisor; - pdimm->mtb_ps = mtb_ps; - - ftb_tmp = spd->ftb_div & 0xf0; - pdimm->ftb_10th_ps = ((ftb_tmp >> 4) * 10) / ftb_tmp; - - pdimm->tCKmin_X_ps = spd->tck_min * mtb_ps + - (spd->fine_tck_min * ftb_tmp) / 10; - pdimm->caslat_X = ((spd->caslat_msb << 8) | spd->caslat_lsb) << 4; - - pdimm->taa_ps = spd->taa_min * mtb_ps + - (spd->fine_taa_min * ftb_tmp) / 10; - - pdimm->tRCD_ps = spd->trcd_min * mtb_ps + - (spd->fine_trcd_min * ftb_tmp) / 10; - - pdimm->tRP_ps = spd->trp_min * mtb_ps + - (spd->fine_trp_min * ftb_tmp) / 10; - pdimm->tRAS_ps = (((spd->tras_trc_ext & 0xf) << 8) | spd->tras_min_lsb) - * mtb_ps; - pdimm->tWR_ps = spd->twr_min * mtb_ps; - pdimm->tWTR_ps = spd->twtr_min * mtb_ps; - pdimm->tRFC_ps = ((spd->trfc_min_msb << 8) | spd->trfc_min_lsb) - * mtb_ps; - pdimm->tRRD_ps = spd->trrd_min * mtb_ps; - pdimm->tRC_ps = (((spd->tras_trc_ext & 0xf0) << 4) | spd->trc_min_lsb); - pdimm->tRC_ps *= mtb_ps; - pdimm->tRC_ps += (spd->fine_trc_min * ftb_tmp) / 10; - - 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; - } - - pdimm->tfaw_ps = (((spd->tfaw_msb & 0xf) << 8) | spd->tfaw_min) - * mtb_ps; - - return 0; -error: - return 1; -} diff --git a/arch/ppc/ddr-8xxx/ddr_setctrl.c b/arch/ppc/ddr-8xxx/ddr_setctrl.c deleted file mode 100644 index 115fb42070..0000000000 --- a/arch/ppc/ddr-8xxx/ddr_setctrl.c +++ /dev/null @@ -1,90 +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. - */ - -#include <common.h> -#include <config.h> -#include <asm/io.h> -#include <asm/fsl_ddr_sdram.h> -#include <asm/processor.h> -#include <mach/early_udelay.h> -#include "ddr.h" - -int fsl_ddr_set_memctl_regs(const struct fsl_ddr_info_s *info) -{ - uint32_t i, temp_sdram_cfg; - void __iomem *ddr; - const struct fsl_ddr_cfg_regs_s *regs; - - regs = &info->fsl_ddr_config_reg; - ddr = info->board_info.ddr_base; - - if (in_be32(ddr + DDR_OFF(SDRAM_CFG)) & SDRAM_CFG_MEM_EN) - return 0; - - for (i = 0; i < info->board_info.cs_per_ctrl; i++) { - out_be32(ddr + DDR_OFF(CS0_BNDS) + (i << 3), regs->cs[i].bnds); - out_be32(ddr + DDR_OFF(CS0_CONFIG) + (i << 2), - regs->cs[i].config); - if (info->memctl_opts.sdram_type == SDRAM_TYPE_DDR3) - out_be32(ddr + DDR_OFF(CS0_CONFIG_2) + (i << 2), - regs->cs[i].config_2); - } - - out_be32(ddr + DDR_OFF(TIMING_CFG_3), regs->timing_cfg_3); - out_be32(ddr + DDR_OFF(TIMING_CFG_0), regs->timing_cfg_0); - out_be32(ddr + DDR_OFF(TIMING_CFG_1), regs->timing_cfg_1); - out_be32(ddr + DDR_OFF(TIMING_CFG_2), regs->timing_cfg_2); - out_be32(ddr + DDR_OFF(SDRAM_CFG_2), regs->ddr_sdram_cfg_2); - out_be32(ddr + DDR_OFF(SDRAM_MODE), regs->ddr_sdram_mode); - out_be32(ddr + DDR_OFF(SDRAM_MODE_2), regs->ddr_sdram_mode_2); - out_be32(ddr + DDR_OFF(SDRAM_MD_CNTL), regs->ddr_sdram_md_cntl); - out_be32(ddr + DDR_OFF(SDRAM_INTERVAL), regs->ddr_sdram_interval); - out_be32(ddr + DDR_OFF(SDRAM_DATA_INIT), regs->ddr_data_init); - out_be32(ddr + DDR_OFF(SDRAM_CLK_CNTL), regs->ddr_sdram_clk_cntl); - out_be32(ddr + DDR_OFF(SDRAM_INIT_ADDR), regs->ddr_init_addr); - out_be32(ddr + DDR_OFF(SDRAM_INIT_ADDR_EXT), regs->ddr_init_ext_addr); - - if (info->memctl_opts.sdram_type == SDRAM_TYPE_DDR3) { - out_be32(ddr + DDR_OFF(TIMING_CFG_4), regs->timing_cfg_4); - out_be32(ddr + DDR_OFF(TIMING_CFG_5), regs->timing_cfg_5); - out_be32(ddr + DDR_OFF(ZQ_CNTL), regs->ddr_zq_cntl); - out_be32(ddr + DDR_OFF(WRLVL_CNTL), regs->ddr_wrlvl_cntl); - - if (regs->ddr_wrlvl_cntl_2) - out_be32(ddr + DDR_OFF(WRLVL_CNTL_2), - regs->ddr_wrlvl_cntl_2); - if (regs->ddr_wrlvl_cntl_3) - out_be32(ddr + DDR_OFF(WRLVL_CNTL_3), - regs->ddr_wrlvl_cntl_3); - - out_be32(ddr + DDR_OFF(SR_CNTL), regs->ddr_sr_cntr); - out_be32(ddr + DDR_OFF(SDRAM_RCW_1), regs->ddr_sdram_rcw_1); - out_be32(ddr + DDR_OFF(SDRAM_RCW_2), regs->ddr_sdram_rcw_2); - out_be32(ddr + DDR_OFF(DDRCDR1), regs->ddr_cdr1); - out_be32(ddr + DDR_OFF(DDRCDR2), regs->ddr_cdr2); - } - - out_be32(ddr + DDR_OFF(ERR_DISABLE), regs->err_disable); - out_be32(ddr + DDR_OFF(ERR_INT_EN), regs->err_int_en); - - temp_sdram_cfg = regs->ddr_sdram_cfg; - temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN); - out_be32(ddr + DDR_OFF(SDRAM_CFG), temp_sdram_cfg); - - early_udelay(500); - /* Make sure all instructions are completed before enabling memory.*/ - asm volatile("sync;isync"); - temp_sdram_cfg = in_be32(ddr + DDR_OFF(SDRAM_CFG)) & ~SDRAM_CFG_BI; - out_be32(ddr + DDR_OFF(SDRAM_CFG), temp_sdram_cfg | SDRAM_CFG_MEM_EN); - asm volatile("sync;isync"); - - while (in_be32(ddr + DDR_OFF(SDRAM_CFG_2)) & SDRAM_CFG2_D_INIT) - early_udelay(10000); - - return 0; -} diff --git a/arch/ppc/ddr-8xxx/lc_common_dimm_params.c b/arch/ppc/ddr-8xxx/lc_common_dimm_params.c deleted file mode 100644 index 9d90fb76db..0000000000 --- a/arch/ppc/ddr-8xxx/lc_common_dimm_params.c +++ /dev/null @@ -1,255 +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 <config.h> -#include <asm/fsl_ddr_sdram.h> - -#include "ddr.h" - -static uint32_t -compute_cas_latency_ddr3(const struct dimm_params_s *dimm_params, - uint32_t number_of_dimms) -{ - uint32_t i, taamin_ps = 0, tckmin_x_ps = 0, common_caslat, - caslat_actual, retry = 16; - const uint32_t mclk_ps = get_memory_clk_period_ps(); - - /* compute the common CAS latency supported between slots */ - common_caslat = dimm_params[0].caslat_X; - for (i = 1; i < number_of_dimms; i++) { - if (dimm_params[i].n_ranks) - common_caslat &= dimm_params[i].caslat_X; - } - - 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); - } - - 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--; - } - - return caslat_actual; -} - -static unsigned int common_burst_length( - const struct dimm_params_s *dimm_params, - const unsigned int number_of_dimms) -{ - unsigned int i, temp; - - temp = 0xff; - for (i = 0; i < number_of_dimms; i++) - if (dimm_params[i].n_ranks) - temp &= dimm_params[i].burst_lengths_bitmask; - return temp; -} - -/* Compute a CAS latency suitable for all DIMMs */ -static unsigned int compute_lowest_caslat( - const struct dimm_params_s *dimm_params, - const unsigned int number_of_dimms) -{ - uint32_t temp1, temp2, i, not_ok, lowest_good_caslat, - tCKmin_X_minus_1_ps, tCKmin_X_minus_2_ps; - const unsigned int mclk_ps = get_memory_clk_period_ps(); - - /* - * 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 __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); - - 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) - continue; - else - not_ok++; - } - - if (dimm_params[i].caslat_X_minus_1 == temp2) { - tCKmin_X_minus_1_ps = - dimm_params[i].tCKmin_X_minus_1_ps; - if (mclk_ps >= tCKmin_X_minus_1_ps) - continue; - else - not_ok++; - } - - if (dimm_params[i].caslat_X_minus_2 == temp2) { - tCKmin_X_minus_2_ps - = dimm_params[i].tCKmin_X_minus_2_ps; - if (mclk_ps >= tCKmin_X_minus_2_ps) - continue; - else - not_ok++; - } - } - - if (!not_ok) - lowest_good_caslat = temp2; - - temp1 &= ~(1 << temp2); - } - return lowest_good_caslat; -} - -/* - * 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. - */ -void compute_lowest_common_dimm_parameters(const struct fsl_ddr_info_s *pinfo, - struct common_timing_params_s *out, - const unsigned int number_of_dimms) -{ - uint32_t temp1, i; - struct common_timing_params_s tmp = {0}; - const struct dimm_params_s *dimm = pinfo->dimm_params; - const struct memctl_options_s *popts = &pinfo->memctl_opts; - - tmp.tCKmax_ps = 0xFFFFFFFF; - tmp.extended_op_srt = 1; - temp1 = 0; - for (i = 0; i < number_of_dimms; i++) { - if (dimm[i].n_ranks == 0) { - temp1++; - continue; - } - - /* - * Find minimum tCKmax_ps to find fastest slow speed, - * i.e., this is the slowest the whole system can go. - */ - tmp.tCKmax_ps = min(tmp.tCKmax_ps, dimm[i].tCKmax_ps); - - /* Find maximum value to determine slowest speed, delay, etc */ - tmp.tCKmin_X_ps = max(tmp.tCKmin_X_ps, dimm[i].tCKmin_X_ps); - tmp.tCKmax_max_ps = max(tmp.tCKmax_max_ps, dimm[i].tCKmax_ps); - tmp.tRCD_ps = max(tmp.tRCD_ps, dimm[i].tRCD_ps); - tmp.tRP_ps = max(tmp.tRP_ps, dimm[i].tRP_ps); - tmp.tRAS_ps = max(tmp.tRAS_ps, dimm[i].tRAS_ps); - tmp.tWR_ps = max(tmp.tWR_ps, dimm[i].tWR_ps); - tmp.tWTR_ps = max(tmp.tWTR_ps, dimm[i].tWTR_ps); - tmp.tRFC_ps = max(tmp.tRFC_ps, dimm[i].tRFC_ps); - tmp.tRRD_ps = max(tmp.tRRD_ps, dimm[i].tRRD_ps); - tmp.tRC_ps = max(tmp.tRC_ps, dimm[i].tRC_ps); - tmp.tIS_ps = max(tmp.tIS_ps, dimm[i].tIS_ps); - tmp.tIH_ps = max(tmp.tIH_ps, dimm[i].tIH_ps); - tmp.tDS_ps = max(tmp.tDS_ps, dimm[i].tDS_ps); - tmp.tDH_ps = max(tmp.tDH_ps, dimm[i].tDH_ps); - tmp.tRTP_ps = max(tmp.tRTP_ps, dimm[i].tRTP_ps); - tmp.tQHS_ps = max(tmp.tQHS_ps, dimm[i].tQHS_ps); - tmp.refresh_rate_ps = max(tmp.refresh_rate_ps, - dimm[i].refresh_rate_ps); - tmp.extended_op_srt = min(tmp.extended_op_srt, - dimm[i].extended_op_srt); - /* Find maximum tDQSQ_max_ps to find slowest timing. */ - tmp.tDQSQ_max_ps = max(tmp.tDQSQ_max_ps, dimm[i].tDQSQ_max_ps); - } - tmp.ndimms_present = number_of_dimms - temp1; - - if (temp1 == number_of_dimms) - return; - - temp1 = common_burst_length(dimm, number_of_dimms); - tmp.all_DIMMs_burst_lengths_bitmask = temp1; - - /* Support only unbuffered DIMMs */ - tmp.all_DIMMs_registered = 0; - tmp.all_DIMMs_unbuffered = 1; - - if (popts->sdram_type == SDRAM_TYPE_DDR3) { - tmp.lowest_common_SPD_caslat = compute_cas_latency_ddr3(dimm, - number_of_dimms); - } else { - tmp.lowest_common_SPD_caslat = compute_lowest_caslat(dimm, - number_of_dimms); - /* - * Compute a common 'de-rated' CAS latency. - * - * The strategy here is to find the *highest* de-rated cas - * latency with the assumption that all of the DIMMs will - * support a de-rated CAS latency higher than or equal to - * their lowest de-rated value. - */ - temp1 = 0; - for (i = 0; i < number_of_dimms; i++) - temp1 = max(temp1, dimm[i].caslat_lowest_derated); - tmp.highest_common_derated_caslat = temp1; - } - - temp1 = 1; - for (i = 0; i < number_of_dimms; i++) - if (dimm[i].n_ranks && !(dimm[i].edc_config & EDC_ECC)) { - temp1 = 0; - break; - } - tmp.all_DIMMs_ECC_capable = temp1; - - /* - * AL must be less or equal to tRCD. Typically, AL would - * be AL = tRCD - 1; - * - * When ODT read or write is enabled the sum of CAS latency + - * additive latency must be at least 3 cycles. - */ - tmp.additive_latency = 0; - if (popts->sdram_type == SDRAM_TYPE_DDR2) { - if ((tmp.lowest_common_SPD_caslat < 4) && - (picos_to_mclk(tmp.tRCD_ps) > - tmp.lowest_common_SPD_caslat)) - tmp.additive_latency = picos_to_mclk(tmp.tRCD_ps) - - tmp.lowest_common_SPD_caslat; - - if (mclk_to_picos(tmp.additive_latency) > tmp.tRCD_ps) - tmp.additive_latency = picos_to_mclk(tmp.tRCD_ps); - } - - memcpy(out, &tmp, sizeof(struct common_timing_params_s)); -} diff --git a/arch/ppc/ddr-8xxx/main.c b/arch/ppc/ddr-8xxx/main.c deleted file mode 100644 index 99b877b5ca..0000000000 --- a/arch/ppc/ddr-8xxx/main.c +++ /dev/null @@ -1,246 +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 DDR2 memory controller. - * Based on code from spd_sdram.c - * Author: James Yang [at freescale.com] - */ - -#include <common.h> -#include <config.h> -#include <asm/fsl_law.h> -#include <asm/fsl_ddr_sdram.h> -#include "ddr.h" - -static int get_spd(generic_spd_eeprom_t *spd, - struct ddr_board_info_s *bi, u8 i2c_address) -{ - int ret; - - fsl_i2c_init(bi->i2c_base, bi->i2c_speed, bi->i2c_slave); - ret = fsl_i2c_read(bi->i2c_base, i2c_address, 0, 1, (uchar *) spd, - sizeof(generic_spd_eeprom_t)); - fsl_i2c_stop(bi->i2c_base); - - return ret; -} - -int fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, - struct ddr_board_info_s *binfo) -{ - uint32_t i; - uint8_t i2c_address; - - for (i = 0; i < binfo->dimm_slots_per_ctrl; i++) { - if (binfo->spd_i2c_addr == NULL) - goto error; - i2c_address = binfo->spd_i2c_addr[i]; - if (get_spd(&(ctrl_dimms_spd[i]), binfo, i2c_address)) - goto error; - } - - return 0; -error: - return 1; -} - -static uint64_t step_assign_addresses(struct fsl_ddr_info_s *pinfo, - uint32_t dbw_cap_adj) -{ - uint64_t total_mem, current_mem_base, total_ctlr_mem, cap; - uint32_t ndimm, dw, j, found = 0; - - ndimm = pinfo->board_info.dimm_slots_per_ctrl; - /* - * If a reduced data width is requested, but the SPD - * specifies a physically wider device, adjust the - * computed dimm capacities accordingly before - * assigning addresses. - */ - switch (pinfo->memctl_opts.data_bus_width) { - case 2: - /* 16-bit */ - for (j = 0; j < ndimm; j++) { - if (!pinfo->dimm_params[j].n_ranks) - continue; - dw = pinfo->dimm_params[j].primary_sdram_width; - if ((dw == 72 || dw == 64)) { - dbw_cap_adj = 2; - break; - } else if ((dw == 40 || dw == 32)) { - dbw_cap_adj = 1; - break; - } - } - break; - case 1: - /* 32-bit */ - for (j = 0; j < ndimm; j++) { - dw = pinfo->dimm_params[j].data_width; - if (pinfo->dimm_params[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 = 1; - break; - case 0: - /* 64-bit */ - break; - default: - return 1; - } - - current_mem_base = 0ull; - total_mem = 0; - total_ctlr_mem = 0; - pinfo->common_timing_params.base_address = current_mem_base; - - for (j = 0; j < ndimm; j++) { - cap = pinfo->dimm_params[j].capacity >> dbw_cap_adj; - pinfo->dimm_params[j].base_address = current_mem_base; - current_mem_base += cap; - total_ctlr_mem += cap; - - } - - pinfo->common_timing_params.total_mem = total_ctlr_mem; - total_mem += total_ctlr_mem; - - return total_mem; -} - -static uint32_t retrieve_max_size(struct fsl_ddr_cfg_regs_s *ddr_reg, - uint32_t ncs) -{ - uint32_t max_end = 0, end, i; - - for (i = 0; i < ncs; i++) - if (ddr_reg->cs[i].config & 0x80000000) { - end = ddr_reg->cs[i].bnds & 0xFFF; - if (end > max_end) - max_end = end; - } - - return max_end; -} - -static uint32_t compute_dimm_param(struct fsl_ddr_info_s *pinfo, uint32_t ndimm) -{ - struct dimm_params_s *pdimm; - generic_spd_eeprom_t *spd; - uint32_t i, retval; - - spd = &(pinfo->spd_installed_dimms[0]); - if (spd->mem_type == SPD_MEMTYPE_DDR3) - pinfo->memctl_opts.sdram_type = SDRAM_TYPE_DDR3; - else if (spd->mem_type == SPD_MEMTYPE_DDR2) - pinfo->memctl_opts.sdram_type = SDRAM_TYPE_DDR2; - else - return 1; - - for (i = 0; i < ndimm; i++) { - spd = &(pinfo->spd_installed_dimms[i]); - pdimm = &(pinfo->dimm_params[i]); - - retval = compute_dimm_parameters(spd, pdimm); - - if (retval == 2) /* Fatal error */ - return 1; - } - - return 0; -} - -uint64_t fsl_ddr_compute(struct fsl_ddr_info_s *pinfo) -{ - uint64_t total_mem = 0; - uint32_t ncs, ndimm, max_end = 0; - struct fsl_ddr_cfg_regs_s *ddr_reg; - struct common_timing_params_s *timing_params; - /* data bus width capacity adjust shift amount */ - uint32_t dbw_capacity_adjust; - - ddr_reg = &pinfo->fsl_ddr_config_reg; - timing_params = &pinfo->common_timing_params; - ncs = pinfo->board_info.cs_per_ctrl; - ndimm = pinfo->board_info.dimm_slots_per_ctrl; - dbw_capacity_adjust = 0; - pinfo->memctl_opts.board_info = &pinfo->board_info; - - /* STEP 1: Gather all DIMM SPD data */ - if (fsl_ddr_get_spd(pinfo->spd_installed_dimms, - pinfo->memctl_opts.board_info)) - return 0; - - /* STEP 2: Compute DIMM parameters from SPD data */ - if (compute_dimm_param(pinfo, ndimm)) - return 0; - - /* - * STEP 3: Compute a common set of timing parameters - * suitable for all of the DIMMs on each memory controller - */ - compute_lowest_common_dimm_parameters(pinfo, timing_params, ndimm); - - /* STEP 4: Gather configuration requirements from user */ - populate_memctl_options(timing_params->all_DIMMs_registered, - &pinfo->memctl_opts, - pinfo->dimm_params); - - /* STEP 5: Assign addresses to chip selects */ - total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust); - - /* STEP 6: compute controller register values */ - if (timing_params->ndimms_present == 0) - memset(ddr_reg, 0, sizeof(struct fsl_ddr_cfg_regs_s)); - - compute_fsl_memctl_config_regs(&pinfo->memctl_opts, - ddr_reg, timing_params, - pinfo->dimm_params, - dbw_capacity_adjust); - - max_end = retrieve_max_size(ddr_reg, ncs); - total_mem = 1 + (((uint64_t)max_end << 24ULL) | 0xFFFFFFULL); - - return total_mem; -} - -/* - * fsl_ddr_sdram(): - * This is the main function to initialize the memory. - * - * It returns amount of memory configured in bytes. - */ -phys_size_t fsl_ddr_sdram(void) -{ - uint64_t total_memory; - struct fsl_ddr_info_s info; - - memset(&info, 0, sizeof(struct fsl_ddr_info_s)); - /* Gather board information on the memory controller and I2C bus. */ - fsl_ddr_board_info(&info.board_info); - - total_memory = fsl_ddr_compute(&info); - - if (info.common_timing_params.ndimms_present == 0) - return 0; - - fsl_ddr_set_memctl_regs(&info); - fsl_ddr_set_lawbar(&info.common_timing_params, LAW_TRGT_IF_DDR_1); - - return total_memory; -} diff --git a/arch/ppc/ddr-8xxx/options.c b/arch/ppc/ddr-8xxx/options.c deleted file mode 100644 index ccf5d5e9d8..0000000000 --- a/arch/ppc/ddr-8xxx/options.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2008, 2010-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 as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include <common.h> -#include <asm/fsl_ddr_sdram.h> -#include "ddr.h" - -uint32_t populate_memctl_options(int all_DIMMs_registered, - struct memctl_options_s *popts, - struct dimm_params_s *pdimm) -{ - const struct ddr_board_info_s *binfo = popts->board_info; - uint32_t i; - - for (i = 0; i < binfo->cs_per_ctrl; i++) { - popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER; - popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_ALL; - popts->cs_local_opts[i].odt_rtt_norm = DDR2_RTT_50_OHM; - popts->cs_local_opts[i].odt_rtt_wr = DDR2_RTT_OFF; - popts->cs_local_opts[i].auto_precharge = 0; - } - - /* Memory Organization Parameters */ - popts->registered_dimm_en = all_DIMMs_registered; - popts->ECC_mode = 0; /* 0 = disabled, 1 = enabled */ - popts->ECC_init_using_memctl = 1; /* 0 = use DMA, 1 = use memctl */ - - /* Choose DQS config - 1 for DDR2 */ - popts->DQS_config = 1; - - /* 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 - * assuming all dimms are similar - * 0 = 64-bit, 1 = 32-bit, 2 = 16-bit - */ - if (pdimm->n_ranks != 0) { - if (popts->sdram_type == SDRAM_TYPE_DDR3) { - 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 - hang(); - } else { - if ((pdimm->data_width >= 64) && - (pdimm->data_width <= 72)) - popts->data_bus_width = 0; - else if ((pdimm->data_width >= 32) && - (pdimm->data_width <= 40)) - popts->data_bus_width = 1; - else - hang(); - } - } - - if (popts->sdram_type == SDRAM_TYPE_DDR3) { - if (popts->data_bus_width == 0) { - popts->otf_burst_chop_en = 1; - popts->burst_length = DDR_OTF; - } else { - /* 32-bit or 16-bit bus */ - popts->otf_burst_chop_en = 0; - popts->burst_length = DDR_BL8; - } - popts->mirrored_dimm = pdimm[0].mirrored_dimm; - } else { - /* Must be a burst length of 4 for DDR2 */ - popts->burst_length = DDR_BL4; - } - - /* Decide whether to use the computed de-rated latency */ - popts->use_derated_caslat = 0; - - /* - * 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; - - /* - * Default BSTTOPRE precharge interval - * - * Set the parameter to 0 for global auto precharge in - * the board options function. - */ - 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 - * - * Set according to specification for the memory used. - * The default value below would work for x4/x8 wide memory. - * - */ - if (popts->sdram_type == SDRAM_TYPE_DDR2) { - popts->tFAW_window_four_activates_ps = 37500; - } else { - /* - * Due to ddr3 dimm fly-by topology, enable write leveling - * to meet the tQDSS under different loading. - */ - popts->tFAW_window_four_activates_ps = pdimm[0].tfaw_ps; - popts->wrlvl_en = 1; - popts->zq_en = 1; - popts->wrlvl_override = 0; - } - - /* - * Default powerdown exit timings. - * Set according to specifications for the memory used in - * the board options function. - */ - popts->txard = 3; - popts->txp = 3; - popts->taxpd = 11; - - /* Default value for load mode cycle time */ - popts->tmrd = 2; - - /* Specific board override parameters. */ - fsl_ddr_board_options(popts, pdimm); - - return 0; -} diff --git a/arch/ppc/ddr-8xxx/util.c b/arch/ppc/ddr-8xxx/util.c deleted file mode 100644 index 626b5f3f9b..0000000000 --- a/arch/ppc/ddr-8xxx/util.c +++ /dev/null @@ -1,100 +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 <asm-generic/div64.h> -#include <mach/clock.h> -#include "ddr.h" - -#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. - */ -uint32_t get_memory_clk_period_ps(void) -{ - uint32_t result, data_rate = fsl_get_ddr_freq(0); - /* Round to nearest 10ps, being careful about 64-bit multiply/divide */ - uint64_t rem, mclk_ps = ULL_2E12; - - /* Now perform the big divide, the result fits in 32-bits */ - rem = do_div(mclk_ps, data_rate); - if (rem >= (data_rate >> 1)) - result = mclk_ps + 1; - else - result = mclk_ps; - - return result; -} - -/* Convert picoseconds into DRAM clock cycles (rounding up if needed). */ -uint32_t picos_to_mclk(uint32_t picos) -{ - uint64_t clks, clks_rem; - uint32_t data_rate = fsl_get_ddr_freq(0); - - if (!picos) - return 0; - - /* First multiply the time by the data rate (32x32 => 64) */ - clks = picos * (uint64_t)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++; - - if (clks > ULL_8FS) - clks = ULL_8FS; - - return (uint32_t)clks; -} - -uint32_t mclk_to_picos(unsigned int mclk) -{ - return get_memory_clk_period_ps() * mclk; -} - -int fsl_ddr_set_lawbar( - const struct common_timing_params_s *params, - uint32_t law_memctl) -{ - uint64_t base = params->base_address; - uint64_t size = params->total_mem; - - if (!params->ndimms_present) - goto out; - - if (base >= MAX_MEM_MAPPED) - goto error; - - if ((base + size) >= MAX_MEM_MAPPED) - size = MAX_MEM_MAPPED - base; - - if (fsl_set_ddr_laws(base, size, law_memctl) < 0) - goto error; -out: - return 0; -error: - return 1; -} |