avionic design with actual uboot and tooling

submodule of avionic design uboot bootloader and with included tools to
get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
2026-03-03 21:46:32 +02:00
parent fe3ba02c96
commit 68d74d3181
11967 changed files with 2221897 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
#
# Copyright 2008-2014 Freescale Semiconductor, Inc.
#
# SPDX-License-Identifier: GPL-2.0
#
obj-$(CONFIG_SYS_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \
lc_common_dimm_params.o
obj-$(CONFIG_SYS_FSL_DDR2) += main.o util.o ctrl_regs.o options.o \
lc_common_dimm_params.o
obj-$(CONFIG_SYS_FSL_DDR3) += main.o util.o ctrl_regs.o options.o \
lc_common_dimm_params.o
obj-$(CONFIG_SYS_FSL_DDR4) += 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_SYS_FSL_DDR1) += ddr1_dimm_params.o
obj-$(CONFIG_SYS_FSL_DDR2) += ddr2_dimm_params.o
obj-$(CONFIG_SYS_FSL_DDR3) += ddr3_dimm_params.o
obj-$(CONFIG_SYS_FSL_DDR4) += ddr4_dimm_params.o
endif
obj-$(CONFIG_FSL_DDR_INTERACTIVE) += interactive.o
obj-$(CONFIG_SYS_FSL_DDRC_GEN1) += mpc85xx_ddr_gen1.o
obj-$(CONFIG_SYS_FSL_DDRC_GEN2) += mpc85xx_ddr_gen2.o
obj-$(CONFIG_SYS_FSL_DDRC_GEN3) += mpc85xx_ddr_gen3.o
obj-$(CONFIG_SYS_FSL_DDR_86XX) += mpc86xx_ddr.o
obj-$(CONFIG_SYS_FSL_DDRC_ARM_GEN3) += arm_ddr_gen3.o
obj-$(CONFIG_SYS_FSL_DDRC_GEN4) += fsl_ddr_gen4.o

View File

@@ -0,0 +1,247 @@
/*
* Copyright 2013 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*
* Derived from mpc85xx_ddr_gen3.c, removed all workarounds
*/
#include <common.h>
#include <asm/io.h>
#include <fsl_ddr_sdram.h>
#include <asm/processor.h>
#include <fsl_immap.h>
#include <fsl_ddr.h>
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
#endif
/*
* regs has the to-be-set values for DDR controller registers
* ctrl_num is the DDR controller number
* step: 0 goes through the initialization in one pass
* 1 sets registers and returns before enabling controller
* 2 resumes from step 1 and continues to initialize
* Dividing the initialization to two steps to deassert DDR reset signal
* to comply with JEDEC specs for RDIMMs.
*/
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num, int step)
{
unsigned int i, bus_width;
struct ccsr_ddr __iomem *ddr;
u32 temp_sdram_cfg;
u32 total_gb_size_per_controller;
int timeout;
switch (ctrl_num) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
break;
#endif
default:
printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
return;
}
if (step == 2)
goto step2;
if (regs->ddr_eor)
ddr_out32(&ddr->eor, regs->ddr_eor);
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (i == 0) {
ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds);
ddr_out32(&ddr->cs0_config, regs->cs[i].config);
ddr_out32(&ddr->cs0_config_2, regs->cs[i].config_2);
} else if (i == 1) {
ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds);
ddr_out32(&ddr->cs1_config, regs->cs[i].config);
ddr_out32(&ddr->cs1_config_2, regs->cs[i].config_2);
} else if (i == 2) {
ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds);
ddr_out32(&ddr->cs2_config, regs->cs[i].config);
ddr_out32(&ddr->cs2_config_2, regs->cs[i].config_2);
} else if (i == 3) {
ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds);
ddr_out32(&ddr->cs3_config, regs->cs[i].config);
ddr_out32(&ddr->cs3_config_2, regs->cs[i].config_2);
}
}
ddr_out32(&ddr->timing_cfg_3, regs->timing_cfg_3);
ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0);
ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1);
ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2);
ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode);
ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
ddr_out32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4);
ddr_out32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5);
ddr_out32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6);
ddr_out32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7);
ddr_out32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8);
ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init);
ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4);
ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5);
ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
#ifndef CONFIG_SYS_FSL_DDR_EMU
/*
* Skip these two registers if running on emulator
* because emulator doesn't have skew between bytes.
*/
if (regs->ddr_wrlvl_cntl_2)
ddr_out32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2);
if (regs->ddr_wrlvl_cntl_3)
ddr_out32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3);
#endif
ddr_out32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);
ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
#ifdef CONFIG_DEEP_SLEEP
if (is_warm_boot()) {
ddr_out32(&ddr->sdram_cfg_2,
regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
ddr_out32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE);
ddr_out32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA);
/* DRAM VRef will not be trained */
ddr_out32(&ddr->ddr_cdr2,
regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN);
} else
#endif
{
ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
ddr_out32(&ddr->init_addr, regs->ddr_init_addr);
ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2);
}
ddr_out32(&ddr->err_disable, regs->err_disable);
ddr_out32(&ddr->err_int_en, regs->err_int_en);
for (i = 0; i < 32; i++) {
if (regs->debug[i]) {
debug("Write to debug_%d as %08x\n", i + 1,
regs->debug[i]);
ddr_out32(&ddr->debug[i], regs->debug[i]);
}
}
/*
* For RDIMMs, JEDEC spec requires clocks to be stable before reset is
* deasserted. Clocks start when any chip select is enabled and clock
* control register is set. Because all DDR components are connected to
* one reset signal, this needs to be done in two steps. Step 1 is to
* get the clocks started. Step 2 resumes after reset signal is
* deasserted.
*/
if (step == 1) {
udelay(200);
return;
}
step2:
/* Set, but do not enable the memory */
temp_sdram_cfg = regs->ddr_sdram_cfg;
temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg);
/*
* 500 painful micro-seconds must elapse between
* the DDR clock setup and the DDR config enable.
* DDR2 need 200 us, and DDR3 need 500 us from spec,
* we choose the max, that is 500 us for all of case.
*/
udelay(500);
asm volatile("dsb sy;isb");
#ifdef CONFIG_DEEP_SLEEP
if (is_warm_boot()) {
/* enter self-refresh */
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
/* do board specific memory setup */
board_mem_sleep_setup();
temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
} else
#endif
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
/* Let the controller go */
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
asm volatile("dsb sy;isb");
total_gb_size_per_controller = 0;
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (!(regs->cs[i].config & 0x80000000))
continue;
total_gb_size_per_controller += 1 << (
((regs->cs[i].config >> 14) & 0x3) + 2 +
((regs->cs[i].config >> 8) & 0x7) + 12 +
((regs->cs[i].config >> 0) & 0x7) + 8 +
3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) -
26); /* minus 26 (count of 64M) */
}
if (regs->cs[0].config & 0x20000000) {
/* 2-way interleaving */
total_gb_size_per_controller <<= 1;
}
/*
* total memory / bus width = transactions needed
* transactions needed / data rate = seconds
* to add plenty of buffer, double the time
* For example, 2GB on 666MT/s 64-bit bus takes about 402ms
* Let's wait for 800ms
*/
bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(ctrl_num) >> 20)) << 1;
total_gb_size_per_controller >>= 4; /* shift down to gb size */
debug("total %d GB\n", total_gb_size_per_controller);
debug("Need to wait up to %d * 10ms\n", timeout);
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
while ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
(timeout >= 0)) {
udelay(10000); /* throttle polling rate */
timeout--;
}
if (timeout <= 0)
printf("Waiting for D_INIT timeout. Memory may not work.\n");
#ifdef CONFIG_DEEP_SLEEP
if (is_warm_boot()) {
/* exit self-refresh */
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
temp_sdram_cfg &= ~SDRAM_CFG2_FRC_SR;
ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
}
#endif
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,341 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <fsl_ddr_sdram.h>
#include <fsl_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 unsigned int ctrl_num,
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(ctrl_num));
/* 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(ctrl_num, 3);
pdimm->twtr_ps = mclk_to_picos(ctrl_num, 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(ctrl_num, 2); /* By the book. */
pdimm->tdqsq_max_ps = spd->tdqsq * 10;
pdimm->tqhs_ps = spd->tqhs * 10;
return 0;
}

View File

@@ -0,0 +1,340 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <fsl_ddr_sdram.h>
#include <fsl_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 unsigned int ctrl_num,
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(ctrl_num));
/* 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;
}

View File

@@ -0,0 +1,339 @@
/*
* 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
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <fsl_ddr_sdram.h>
#include <fsl_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 unsigned int ctrl_num,
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;
}

View File

@@ -0,0 +1,323 @@
/*
* Copyright 2014 Freescale Semiconductor, Inc.
*
* calculate the organization and timing parameter
* from ddr3 spd, please refer to the spec
* JEDEC standard No.21-C 4_01_02_12R23A.pdf
*
*
*/
#include <common.h>
#include <fsl_ddr_sdram.h>
#include <fsl_ddr.h>
/*
* Calculate the Density of each Physical Rank.
* Returned size is in bytes.
*
* Total DIMM size =
* sdram capacity(bit) / 8 * primary bus width / sdram width
* * Logical Ranks per DIMM
*
* where: sdram capacity = spd byte4[3:0]
* primary bus width = spd byte13[2:0]
* sdram width = spd byte12[2:0]
* Logical Ranks per DIMM = spd byte12[5:3] for SDP, DDP, QDP
* spd byte12{5:3] * spd byte6[6:4] for 3DS
*
* To simplify each rank size = total DIMM size / Number of Package Ranks
* where Number of Package Ranks = spd byte12[5:3]
*
* 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
* 0111 32Gb 4GB
*
* SPD byte13 - module memory bus width
* bit[2:0] primary bus width
* 000 8bits
* 001 16bits
* 010 32bits
* 011 64bits
*
* SPD byte12 - module organization
* bit[2:0] sdram device width
* 000 4bits
* 001 8bits
* 010 16bits
* 011 32bits
*
* SPD byte12 - module organization
* bit[5:3] number of package ranks per DIMM
* 000 1
* 001 2
* 010 3
* 011 4
*
* SPD byte6 - SDRAM package type
* bit[6:4] Die count
* 000 1
* 001 2
* 010 3
* 011 4
* 100 5
* 101 6
* 110 7
* 111 8
*
* SPD byte6 - SRAM package type
* bit[1:0] Signal loading
* 00 Not specified
* 01 Multi load stack
* 10 Sigle load stack (3DS)
* 11 Reserved
*/
static unsigned long long
compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
{
unsigned long long bsize;
int nbit_sdram_cap_bsize = 0;
int nbit_primary_bus_width = 0;
int nbit_sdram_width = 0;
int die_count = 0;
bool package_3ds;
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;
package_3ds = (spd->package_type & 0x3) == 0x2;
if (package_3ds)
die_count = (spd->package_type >> 4) & 0x7;
bsize = 1ULL << (nbit_sdram_cap_bsize - 3 +
nbit_primary_bus_width - nbit_sdram_width +
die_count);
debug("DDR: DDR III rank density = 0x%16llx\n", bsize);
return bsize;
}
#define spd_to_ps(mtb, ftb) \
(mtb * pdimm->mtb_ps + (ftb * pdimm->ftb_10th_ps) / 10)
/*
* ddr_compute_dimm_parameters for DDR4 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 unsigned int ctrl_num,
const generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
int i;
const u8 udimm_rc_e_dq[18] = {
0x0c, 0x2c, 0x15, 0x35, 0x15, 0x35, 0x0b, 0x2c, 0x15,
0x35, 0x0b, 0x35, 0x0b, 0x2c, 0x0b, 0x35, 0x15, 0x36
};
int spd_error = 0;
u8 *ptr;
if (spd->mem_type) {
if (spd->mem_type != SPD_MEMTYPE_DDR4) {
printf("Ctrl %u DIMM %u: is not a DDR4 SPD.\n",
ctrl_num, dimm_number);
return 1;
}
} else {
memset(pdimm, 0, sizeof(dimm_params_t));
return 1;
}
retval = ddr4_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) > 2)
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 SPD spec */
pdimm->mirrored_dimm = 0;
pdimm->registered_dimm = 0;
switch (spd->module_type & DDR4_SPD_MODULETYPE_MASK) {
case DDR4_SPD_MODULETYPE_RDIMM:
/* Registered/buffered DIMMs */
pdimm->registered_dimm = 1;
break;
case DDR4_SPD_MODULETYPE_UDIMM:
case DDR4_SPD_MODULETYPE_SO_DIMM:
/* Unbuffered DIMMs */
if (spd->mod_section.unbuffered.addr_mapping & 0x1)
pdimm->mirrored_dimm = 1;
if ((spd->mod_section.unbuffered.mod_height & 0xe0) == 0 &&
(spd->mod_section.unbuffered.ref_raw_card == 0x04)) {
/* Fix SPD error found on DIMMs with raw card E0 */
for (i = 0; i < 18; i++) {
if (spd->mapping[i] == udimm_rc_e_dq[i])
continue;
spd_error = 1;
debug("SPD byte %d: 0x%x, should be 0x%x\n",
60 + i, spd->mapping[i],
udimm_rc_e_dq[i]);
ptr = (u8 *)&spd->mapping[i];
*ptr = udimm_rc_e_dq[i];
}
if (spd_error)
puts("SPD DQ mapping error fixed\n");
}
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->bank_addr_bits = (spd->density_banks >> 4) & 0x3;
pdimm->bank_group_bits = (spd->density_banks >> 6) & 0x3;
/*
* 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 DDR4 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 MTB in the SPD spec is 125ps,
*
* 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
*/
if ((spd->timebases & 0xf) == 0x0) {
pdimm->mtb_ps = 125;
pdimm->ftb_10th_ps = 10;
} else {
printf("Unknown Timebases\n");
}
/* sdram minimum cycle time */
pdimm->tckmin_x_ps = spd_to_ps(spd->tck_min, spd->fine_tck_min);
/* sdram max cycle time */
pdimm->tckmax_ps = spd_to_ps(spd->tck_max, spd->fine_tck_max);
/*
* CAS latency supported
* bit0 - CL7
* bit4 - CL11
* bit8 - CL15
* bit12- CL19
* bit16- CL23
*/
pdimm->caslat_x = (spd->caslat_b1 << 7) |
(spd->caslat_b2 << 15) |
(spd->caslat_b3 << 23);
BUG_ON(spd->caslat_b4 != 0);
/*
* min CAS latency time
*/
pdimm->taa_ps = spd_to_ps(spd->taa_min, spd->fine_taa_min);
/*
* min RAS to CAS delay time
*/
pdimm->trcd_ps = spd_to_ps(spd->trcd_min, spd->fine_trcd_min);
/*
* Min Row Precharge Delay Time
*/
pdimm->trp_ps = spd_to_ps(spd->trp_min, spd->fine_trp_min);
/* min active to precharge delay time */
pdimm->tras_ps = (((spd->tras_trc_ext & 0xf) << 8) +
spd->tras_min_lsb) * pdimm->mtb_ps;
/* min active to actice/refresh delay time */
pdimm->trc_ps = spd_to_ps((((spd->tras_trc_ext & 0xf0) << 4) +
spd->trc_min_lsb), spd->fine_trc_min);
/* Min Refresh Recovery Delay Time */
pdimm->trfc1_ps = ((spd->trfc1_min_msb << 8) | (spd->trfc1_min_lsb)) *
pdimm->mtb_ps;
pdimm->trfc2_ps = ((spd->trfc2_min_msb << 8) | (spd->trfc2_min_lsb)) *
pdimm->mtb_ps;
pdimm->trfc4_ps = ((spd->trfc4_min_msb << 8) | (spd->trfc4_min_lsb)) *
pdimm->mtb_ps;
/* min four active window delay time */
pdimm->tfaw_ps = (((spd->tfaw_msb & 0xf) << 8) | spd->tfaw_min) *
pdimm->mtb_ps;
/* min row active to row active delay time, different bank group */
pdimm->trrds_ps = spd_to_ps(spd->trrds_min, spd->fine_trrds_min);
/* min row active to row active delay time, same bank group */
pdimm->trrdl_ps = spd_to_ps(spd->trrdl_min, spd->fine_trrdl_min);
/* min CAS to CAS Delay Time (tCCD_Lmin), same bank group */
pdimm->tccdl_ps = spd_to_ps(spd->tccdl_min, spd->fine_tccdl_min);
/*
* Average periodic refresh interval
* tREFI = 7.8 us at normal temperature range
*/
pdimm->refresh_rate_ps = 7800000;
for (i = 0; i < 18; i++)
pdimm->dq_mapping[i] = spd->mapping[i];
pdimm->dq_mapping_ors = ((spd->mapping[0] >> 6) & 0x3) == 0 ? 1 : 0;
return 0;
}

View File

@@ -0,0 +1,541 @@
/*
* Copyright 2014-2015 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
#include <fsl_ddr_sdram.h>
#include <asm/processor.h>
#include <fsl_immap.h>
#include <fsl_ddr.h>
#include <fsl_errata.h>
#if defined(CONFIG_SYS_FSL_ERRATUM_A008511) | \
defined(CONFIG_SYS_FSL_ERRATUM_A009803)
static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits)
{
int timeout = 1000;
ddr_out32(ptr, value);
while (ddr_in32(ptr) & bits) {
udelay(100);
timeout--;
}
if (timeout <= 0)
puts("Error: wait for clear timeout.\n");
}
#endif
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
#endif
/*
* regs has the to-be-set values for DDR controller registers
* ctrl_num is the DDR controller number
* step: 0 goes through the initialization in one pass
* 1 sets registers and returns before enabling controller
* 2 resumes from step 1 and continues to initialize
* Dividing the initialization to two steps to deassert DDR reset signal
* to comply with JEDEC specs for RDIMMs.
*/
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num, int step)
{
unsigned int i, bus_width;
struct ccsr_ddr __iomem *ddr;
u32 temp_sdram_cfg;
u32 total_gb_size_per_controller;
int timeout;
#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
u32 temp32, mr6;
u32 vref_seq1[3] = {0x80, 0x96, 0x16}; /* for range 1 */
u32 vref_seq2[3] = {0xc0, 0xf0, 0x70}; /* for range 2 */
u32 *vref_seq = vref_seq1;
#endif
#if defined(CONFIG_SYS_FSL_ERRATUM_A009942) | \
defined(CONFIG_SYS_FSL_ERRATUM_A010165)
ulong ddr_freq;
u32 tmp;
#endif
#ifdef CONFIG_FSL_DDR_BIST
u32 mtcr, err_detect, err_sbe;
u32 cs0_bnds, cs1_bnds, cs2_bnds, cs3_bnds, cs0_config;
#endif
#ifdef CONFIG_FSL_DDR_BIST
char buffer[CONFIG_SYS_CBSIZE];
#endif
switch (ctrl_num) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
break;
#endif
default:
printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
return;
}
if (step == 2)
goto step2;
if (regs->ddr_eor)
ddr_out32(&ddr->eor, regs->ddr_eor);
ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (i == 0) {
ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds);
ddr_out32(&ddr->cs0_config, regs->cs[i].config);
ddr_out32(&ddr->cs0_config_2, regs->cs[i].config_2);
} else if (i == 1) {
ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds);
ddr_out32(&ddr->cs1_config, regs->cs[i].config);
ddr_out32(&ddr->cs1_config_2, regs->cs[i].config_2);
} else if (i == 2) {
ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds);
ddr_out32(&ddr->cs2_config, regs->cs[i].config);
ddr_out32(&ddr->cs2_config_2, regs->cs[i].config_2);
} else if (i == 3) {
ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds);
ddr_out32(&ddr->cs3_config, regs->cs[i].config);
ddr_out32(&ddr->cs3_config_2, regs->cs[i].config_2);
}
}
ddr_out32(&ddr->timing_cfg_3, regs->timing_cfg_3);
ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0);
ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1);
ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2);
ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4);
ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5);
ddr_out32(&ddr->timing_cfg_6, regs->timing_cfg_6);
ddr_out32(&ddr->timing_cfg_7, regs->timing_cfg_7);
ddr_out32(&ddr->timing_cfg_8, regs->timing_cfg_8);
ddr_out32(&ddr->timing_cfg_9, regs->timing_cfg_9);
ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
ddr_out32(&ddr->dq_map_0, regs->dq_map_0);
ddr_out32(&ddr->dq_map_1, regs->dq_map_1);
ddr_out32(&ddr->dq_map_2, regs->dq_map_2);
ddr_out32(&ddr->dq_map_3, regs->dq_map_3);
ddr_out32(&ddr->sdram_cfg_3, regs->ddr_sdram_cfg_3);
ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode);
ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
ddr_out32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4);
ddr_out32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5);
ddr_out32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6);
ddr_out32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7);
ddr_out32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8);
ddr_out32(&ddr->sdram_mode_9, regs->ddr_sdram_mode_9);
ddr_out32(&ddr->sdram_mode_10, regs->ddr_sdram_mode_10);
ddr_out32(&ddr->sdram_mode_11, regs->ddr_sdram_mode_11);
ddr_out32(&ddr->sdram_mode_12, regs->ddr_sdram_mode_12);
ddr_out32(&ddr->sdram_mode_13, regs->ddr_sdram_mode_13);
ddr_out32(&ddr->sdram_mode_14, regs->ddr_sdram_mode_14);
ddr_out32(&ddr->sdram_mode_15, regs->ddr_sdram_mode_15);
ddr_out32(&ddr->sdram_mode_16, regs->ddr_sdram_mode_16);
ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
#ifdef CONFIG_SYS_FSL_ERRATUM_A009663
ddr_out32(&ddr->sdram_interval,
regs->ddr_sdram_interval & ~SDRAM_INTERVAL_BSTOPRE);
#else
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
#endif
ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init);
ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
#ifndef CONFIG_SYS_FSL_DDR_EMU
/*
* Skip these two registers if running on emulator
* because emulator doesn't have skew between bytes.
*/
if (regs->ddr_wrlvl_cntl_2)
ddr_out32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2);
if (regs->ddr_wrlvl_cntl_3)
ddr_out32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3);
#endif
ddr_out32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);
ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
ddr_out32(&ddr->ddr_sdram_rcw_3, regs->ddr_sdram_rcw_3);
ddr_out32(&ddr->ddr_sdram_rcw_4, regs->ddr_sdram_rcw_4);
ddr_out32(&ddr->ddr_sdram_rcw_5, regs->ddr_sdram_rcw_5);
ddr_out32(&ddr->ddr_sdram_rcw_6, regs->ddr_sdram_rcw_6);
ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
#ifdef CONFIG_DEEP_SLEEP
if (is_warm_boot()) {
ddr_out32(&ddr->sdram_cfg_2,
regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
ddr_out32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE);
ddr_out32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA);
/* DRAM VRef will not be trained */
ddr_out32(&ddr->ddr_cdr2,
regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN);
} else
#endif
{
ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
ddr_out32(&ddr->init_addr, regs->ddr_init_addr);
ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2);
}
#ifdef CONFIG_SYS_FSL_ERRATUM_A009803
/* part 1 of 2 */
if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) { /* for RDIMM */
ddr_out32(&ddr->ddr_sdram_rcw_2,
regs->ddr_sdram_rcw_2 & ~0x0f000000);
}
ddr_out32(&ddr->err_disable, regs->err_disable |
DDR_ERR_DISABLE_APED);
}
#else
ddr_out32(&ddr->err_disable, regs->err_disable);
#endif
ddr_out32(&ddr->err_int_en, regs->err_int_en);
for (i = 0; i < 32; i++) {
if (regs->debug[i]) {
debug("Write to debug_%d as %08x\n",
i+1, regs->debug[i]);
ddr_out32(&ddr->debug[i], regs->debug[i]);
}
}
#ifdef CONFIG_SYS_FSL_ERRATUM_A008378
/* Erratum applies when accumulated ECC is used, or DBI is enabled */
#define IS_ACC_ECC_EN(v) ((v) & 0x4)
#define IS_DBI(v) ((((v) >> 12) & 0x3) == 0x2)
if (has_erratum_a008378()) {
if (IS_ACC_ECC_EN(regs->ddr_sdram_cfg) ||
IS_DBI(regs->ddr_sdram_cfg_3))
ddr_setbits32(&ddr->debug[28], 0x9 << 20);
}
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
/* Part 1 of 2 */
/* This erraum only applies to verion 5.2.0 */
if (fsl_ddr_get_version(ctrl_num) == 0x50200) {
/* Disable DRAM VRef training */
ddr_out32(&ddr->ddr_cdr2,
regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN);
/* disable transmit bit deskew */
temp32 = ddr_in32(&ddr->debug[28]);
temp32 |= DDR_TX_BD_DIS;
ddr_out32(&ddr->debug[28], temp32);
/* Disable D_INIT */
ddr_out32(&ddr->sdram_cfg_2,
regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
ddr_out32(&ddr->debug[25], 0x9000);
}
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A009801
temp32 = ddr_in32(&ddr->debug[25]);
temp32 &= ~DDR_CAS_TO_PRE_SUB_MASK;
temp32 |= 9 << DDR_CAS_TO_PRE_SUB_SHIFT;
ddr_out32(&ddr->debug[25], temp32);
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A009942
ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
tmp = ddr_in32(&ddr->debug[28]);
if (ddr_freq <= 1333)
ddr_out32(&ddr->debug[28], tmp | 0x0080006a);
else if (ddr_freq <= 1600)
ddr_out32(&ddr->debug[28], tmp | 0x0070006f);
else if (ddr_freq <= 1867)
ddr_out32(&ddr->debug[28], tmp | 0x00700076);
else if (ddr_freq <= 2133)
ddr_out32(&ddr->debug[28], tmp | 0x0060007b);
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A010165
ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
if ((ddr_freq > 1900) && (ddr_freq < 2300)) {
tmp = ddr_in32(&ddr->debug[28]);
ddr_out32(&ddr->debug[28], tmp | 0x000a0000);
}
#endif
/*
* For RDIMMs, JEDEC spec requires clocks to be stable before reset is
* deasserted. Clocks start when any chip select is enabled and clock
* control register is set. Because all DDR components are connected to
* one reset signal, this needs to be done in two steps. Step 1 is to
* get the clocks started. Step 2 resumes after reset signal is
* deasserted.
*/
if (step == 1) {
udelay(200);
return;
}
step2:
/* Set, but do not enable the memory */
temp_sdram_cfg = regs->ddr_sdram_cfg;
temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg);
/*
* 500 painful micro-seconds must elapse between
* the DDR clock setup and the DDR config enable.
* DDR2 need 200 us, and DDR3 need 500 us from spec,
* we choose the max, that is 500 us for all of case.
*/
udelay(500);
mb();
isb();
#ifdef CONFIG_DEEP_SLEEP
if (is_warm_boot()) {
/* enter self-refresh */
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
temp_sdram_cfg |= SDRAM_CFG2_FRC_SR;
ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
/* do board specific memory setup */
board_mem_sleep_setup();
temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
} else
#endif
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
/* Let the controller go */
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
mb();
isb();
#if defined(CONFIG_SYS_FSL_ERRATUM_A008511) || \
defined(CONFIG_SYS_FSL_ERRATUM_A009803)
/* Part 2 of 2 */
/* This erraum only applies to verion 5.2.0 */
if (fsl_ddr_get_version(ctrl_num) == 0x50200) {
/* Wait for idle */
timeout = 40;
while (!(ddr_in32(&ddr->debug[1]) & 0x2) &&
(timeout > 0)) {
udelay(1000);
timeout--;
}
if (timeout <= 0) {
printf("Controler %d timeout, debug_2 = %x\n",
ctrl_num, ddr_in32(&ddr->debug[1]));
}
#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
/* The vref setting sequence is different for range 2 */
if (regs->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2)
vref_seq = vref_seq2;
/* Set VREF */
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN))
continue;
mr6 = (regs->ddr_sdram_mode_10 >> 16) |
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL(i) |
MD_CNTL_MD_SEL(6) |
0x00200000;
temp32 = mr6 | vref_seq[0];
set_wait_for_bits_clear(&ddr->sdram_md_cntl,
temp32, MD_CNTL_MD_EN);
udelay(1);
debug("MR6 = 0x%08x\n", temp32);
temp32 = mr6 | vref_seq[1];
set_wait_for_bits_clear(&ddr->sdram_md_cntl,
temp32, MD_CNTL_MD_EN);
udelay(1);
debug("MR6 = 0x%08x\n", temp32);
temp32 = mr6 | vref_seq[2];
set_wait_for_bits_clear(&ddr->sdram_md_cntl,
temp32, MD_CNTL_MD_EN);
udelay(1);
debug("MR6 = 0x%08x\n", temp32);
}
ddr_out32(&ddr->sdram_md_cntl, 0);
temp32 = ddr_in32(&ddr->debug[28]);
temp32 &= ~DDR_TX_BD_DIS; /* Enable deskew */
ddr_out32(&ddr->debug[28], temp32);
ddr_out32(&ddr->debug[1], 0x400); /* restart deskew */
/* wait for idle */
timeout = 40;
while (!(ddr_in32(&ddr->debug[1]) & 0x2) &&
(timeout > 0)) {
udelay(1000);
timeout--;
}
if (timeout <= 0) {
printf("Controler %d timeout, debug_2 = %x\n",
ctrl_num, ddr_in32(&ddr->debug[1]));
}
/* Restore D_INIT */
ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
#endif /* CONFIG_SYS_FSL_ERRATUM_A008511 */
#ifdef CONFIG_SYS_FSL_ERRATUM_A009803
if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
/* if it's RDIMM */
if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) {
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN))
continue;
set_wait_for_bits_clear(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL(i) |
0x070000ed,
MD_CNTL_MD_EN);
udelay(1);
}
}
ddr_out32(&ddr->err_disable,
regs->err_disable & ~DDR_ERR_DISABLE_APED);
}
#endif
}
#endif
total_gb_size_per_controller = 0;
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (!(regs->cs[i].config & 0x80000000))
continue;
total_gb_size_per_controller += 1 << (
((regs->cs[i].config >> 14) & 0x3) + 2 +
((regs->cs[i].config >> 8) & 0x7) + 12 +
((regs->cs[i].config >> 4) & 0x3) + 0 +
((regs->cs[i].config >> 0) & 0x7) + 8 +
3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) -
26); /* minus 26 (count of 64M) */
}
if (fsl_ddr_get_intl3r() & 0x80000000) /* 3-way interleaving */
total_gb_size_per_controller *= 3;
else if (regs->cs[0].config & 0x20000000) /* 2-way interleaving */
total_gb_size_per_controller <<= 1;
/*
* total memory / bus width = transactions needed
* transactions needed / data rate = seconds
* to add plenty of buffer, double the time
* For example, 2GB on 666MT/s 64-bit bus takes about 402ms
* Let's wait for 800ms
*/
bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(ctrl_num) >> 20)) << 2;
total_gb_size_per_controller >>= 4; /* shift down to gb size */
debug("total %d GB\n", total_gb_size_per_controller);
debug("Need to wait up to %d * 10ms\n", timeout);
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
while ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
(timeout >= 0)) {
udelay(10000); /* throttle polling rate */
timeout--;
}
if (timeout <= 0)
printf("Waiting for D_INIT timeout. Memory may not work.\n");
#ifdef CONFIG_SYS_FSL_ERRATUM_A009663
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
#endif
#ifdef CONFIG_DEEP_SLEEP
if (is_warm_boot()) {
/* exit self-refresh */
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2);
temp_sdram_cfg &= ~SDRAM_CFG2_FRC_SR;
ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
}
#endif
#ifdef CONFIG_FSL_DDR_BIST
#define BIST_PATTERN1 0xFFFFFFFF
#define BIST_PATTERN2 0x0
#define BIST_CR 0x80010000
#define BIST_CR_EN 0x80000000
#define BIST_CR_STAT 0x00000001
#define CTLR_INTLV_MASK 0x20000000
/* Perform build-in test on memory. Three-way interleaving is not yet
* supported by this code. */
if (getenv_f("ddr_bist", buffer, CONFIG_SYS_CBSIZE) >= 0) {
puts("Running BIST test. This will take a while...");
cs0_config = ddr_in32(&ddr->cs0_config);
cs0_bnds = ddr_in32(&ddr->cs0_bnds);
cs1_bnds = ddr_in32(&ddr->cs1_bnds);
cs2_bnds = ddr_in32(&ddr->cs2_bnds);
cs3_bnds = ddr_in32(&ddr->cs3_bnds);
if (cs0_config & CTLR_INTLV_MASK) {
/* set bnds to non-interleaving */
ddr_out32(&ddr->cs0_bnds, (cs0_bnds & 0xfffefffe) >> 1);
ddr_out32(&ddr->cs1_bnds, (cs1_bnds & 0xfffefffe) >> 1);
ddr_out32(&ddr->cs2_bnds, (cs2_bnds & 0xfffefffe) >> 1);
ddr_out32(&ddr->cs3_bnds, (cs3_bnds & 0xfffefffe) >> 1);
}
ddr_out32(&ddr->mtp1, BIST_PATTERN1);
ddr_out32(&ddr->mtp2, BIST_PATTERN1);
ddr_out32(&ddr->mtp3, BIST_PATTERN2);
ddr_out32(&ddr->mtp4, BIST_PATTERN2);
ddr_out32(&ddr->mtp5, BIST_PATTERN1);
ddr_out32(&ddr->mtp6, BIST_PATTERN1);
ddr_out32(&ddr->mtp7, BIST_PATTERN2);
ddr_out32(&ddr->mtp8, BIST_PATTERN2);
ddr_out32(&ddr->mtp9, BIST_PATTERN1);
ddr_out32(&ddr->mtp10, BIST_PATTERN2);
mtcr = BIST_CR;
ddr_out32(&ddr->mtcr, mtcr);
timeout = 100;
while (timeout > 0 && (mtcr & BIST_CR_EN)) {
mdelay(1000);
timeout--;
mtcr = ddr_in32(&ddr->mtcr);
}
if (timeout <= 0)
puts("Timeout\n");
else
puts("Done\n");
err_detect = ddr_in32(&ddr->err_detect);
err_sbe = ddr_in32(&ddr->err_sbe);
if (mtcr & BIST_CR_STAT) {
printf("BIST test failed on controller %d.\n",
ctrl_num);
}
if (err_detect || (err_sbe & 0xffff)) {
printf("ECC error detected on controller %d.\n",
ctrl_num);
}
if (cs0_config & CTLR_INTLV_MASK) {
/* restore bnds registers */
ddr_out32(&ddr->cs0_bnds, cs0_bnds);
ddr_out32(&ddr->cs1_bnds, cs1_bnds);
ddr_out32(&ddr->cs2_bnds, cs2_bnds);
ddr_out32(&ddr->cs3_bnds, cs3_bnds);
}
}
#endif
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,579 @@
/*
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <fsl_ddr_sdram.h>
#include <fsl_ddr.h>
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
static unsigned int
compute_cas_latency(const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
{
unsigned int i;
unsigned int common_caslat;
unsigned int caslat_actual;
unsigned int retry = 16;
unsigned int tmp = ~0;
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#ifdef CONFIG_SYS_FSL_DDR3
const unsigned int taamax = 20000;
#else
const unsigned int taamax = 18000;
#endif
/* compute the common CAS latency supported between slots */
for (i = 0; i < number_of_dimms; i++) {
if (dimm_params[i].n_ranks)
tmp &= dimm_params[i].caslat_x;
}
common_caslat = tmp;
/* validate if the memory clk is in the range of dimms */
if (mclk_ps < outpdimm->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, outpdimm->tckmin_x_ps);
}
#ifdef CONFIG_SYS_FSL_DDR4
if (mclk_ps > outpdimm->tckmax_ps) {
printf("DDR clock (MCLK cycle %u ps) is slower than DIMM(s) (tCKmax %u ps) can support.\n",
mclk_ps, outpdimm->tckmax_ps);
}
#endif
/* determine the acutal cas latency */
caslat_actual = (outpdimm->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,
* 18ns for all DDR4 speed grades.
*/
if (caslat_actual * mclk_ps > taamax) {
printf("The chosen cas latency %d is too large\n",
caslat_actual);
}
outpdimm->lowest_common_spd_caslat = caslat_actual;
debug("lowest_common_spd_caslat is 0x%x\n", caslat_actual);
return 0;
}
#else /* for DDR1 and DDR2 */
static unsigned int
compute_cas_latency(const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
{
int i;
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
unsigned int lowest_good_caslat;
unsigned int not_ok;
unsigned int temp1, temp2;
debug("using mclk_ps = %u\n", mclk_ps);
if (mclk_ps > outpdimm->tckmax_ps) {
printf("Warning: DDR clock (%u ps) is slower than DIMM(s) (tCKmax %u ps)\n",
mclk_ps, outpdimm->tckmax_ps);
}
/*
* 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;
/*
* 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 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 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 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);
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 unsigned int ctrl_num,
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 trcd_ps = 0;
unsigned int trp_ps = 0;
unsigned int tras_ps = 0;
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
unsigned int taamin_ps = 0;
#endif
#ifdef CONFIG_SYS_FSL_DDR4
unsigned int twr_ps = 15000;
unsigned int trfc1_ps = 0;
unsigned int trfc2_ps = 0;
unsigned int trfc4_ps = 0;
unsigned int trrds_ps = 0;
unsigned int trrdl_ps = 0;
unsigned int tccdl_ps = 0;
#else
unsigned int twr_ps = 0;
unsigned int twtr_ps = 0;
unsigned int trfc_ps = 0;
unsigned int trrd_ps = 0;
unsigned int trtp_ps = 0;
#endif
unsigned int trc_ps = 0;
unsigned int refresh_rate_ps = 0;
unsigned int extended_op_srt = 1;
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
unsigned int tis_ps = 0;
unsigned int tih_ps = 0;
unsigned int tds_ps = 0;
unsigned int tdh_ps = 0;
unsigned int tdqsq_max_ps = 0;
unsigned int tqhs_ps = 0;
#endif
unsigned int temp1, temp2;
unsigned int additive_latency = 0;
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,
(unsigned int)dimm_params[i].tckmax_ps);
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
taamin_ps = max(taamin_ps,
(unsigned int)dimm_params[i].taa_ps);
#endif
tckmin_x_ps = max(tckmin_x_ps,
(unsigned int)dimm_params[i].tckmin_x_ps);
trcd_ps = max(trcd_ps, (unsigned int)dimm_params[i].trcd_ps);
trp_ps = max(trp_ps, (unsigned int)dimm_params[i].trp_ps);
tras_ps = max(tras_ps, (unsigned int)dimm_params[i].tras_ps);
#ifdef CONFIG_SYS_FSL_DDR4
trfc1_ps = max(trfc1_ps,
(unsigned int)dimm_params[i].trfc1_ps);
trfc2_ps = max(trfc2_ps,
(unsigned int)dimm_params[i].trfc2_ps);
trfc4_ps = max(trfc4_ps,
(unsigned int)dimm_params[i].trfc4_ps);
trrds_ps = max(trrds_ps,
(unsigned int)dimm_params[i].trrds_ps);
trrdl_ps = max(trrdl_ps,
(unsigned int)dimm_params[i].trrdl_ps);
tccdl_ps = max(tccdl_ps,
(unsigned int)dimm_params[i].tccdl_ps);
#else
twr_ps = max(twr_ps, (unsigned int)dimm_params[i].twr_ps);
twtr_ps = max(twtr_ps, (unsigned int)dimm_params[i].twtr_ps);
trfc_ps = max(trfc_ps, (unsigned int)dimm_params[i].trfc_ps);
trrd_ps = max(trrd_ps, (unsigned int)dimm_params[i].trrd_ps);
trtp_ps = max(trtp_ps, (unsigned int)dimm_params[i].trtp_ps);
#endif
trc_ps = max(trc_ps, (unsigned int)dimm_params[i].trc_ps);
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
tis_ps = max(tis_ps, (unsigned int)dimm_params[i].tis_ps);
tih_ps = max(tih_ps, (unsigned int)dimm_params[i].tih_ps);
tds_ps = max(tds_ps, (unsigned int)dimm_params[i].tds_ps);
tdh_ps = max(tdh_ps, (unsigned int)dimm_params[i].tdh_ps);
tqhs_ps = max(tqhs_ps, (unsigned int)dimm_params[i].tqhs_ps);
/*
* 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,
(unsigned int)dimm_params[i].tdqsq_max_ps);
#endif
refresh_rate_ps = max(refresh_rate_ps,
(unsigned int)dimm_params[i].refresh_rate_ps);
/* extended_op_srt is either 0 or 1, 0 having priority */
extended_op_srt = min(extended_op_srt,
(unsigned int)dimm_params[i].extended_op_srt);
}
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;
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
outpdimm->taamin_ps = taamin_ps;
#endif
outpdimm->trcd_ps = trcd_ps;
outpdimm->trp_ps = trp_ps;
outpdimm->tras_ps = tras_ps;
#ifdef CONFIG_SYS_FSL_DDR4
outpdimm->trfc1_ps = trfc1_ps;
outpdimm->trfc2_ps = trfc2_ps;
outpdimm->trfc4_ps = trfc4_ps;
outpdimm->trrds_ps = trrds_ps;
outpdimm->trrdl_ps = trrdl_ps;
outpdimm->tccdl_ps = tccdl_ps;
#else
outpdimm->twtr_ps = twtr_ps;
outpdimm->trfc_ps = trfc_ps;
outpdimm->trrd_ps = trrd_ps;
outpdimm->trtp_ps = trtp_ps;
#endif
outpdimm->twr_ps = twr_ps;
outpdimm->trc_ps = trc_ps;
outpdimm->refresh_rate_ps = refresh_rate_ps;
outpdimm->extended_op_srt = extended_op_srt;
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
outpdimm->tis_ps = tis_ps;
outpdimm->tih_ps = tih_ps;
outpdimm->tds_ps = tds_ps;
outpdimm->tdh_ps = tdh_ps;
outpdimm->tdqsq_max_ps = tdqsq_max_ps;
outpdimm->tqhs_ps = tqhs_ps;
#endif
/* 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");
/* calculate cas latency for all DDR types */
if (compute_cas_latency(ctrl_num, dimm_params,
outpdimm, number_of_dimms))
return 1;
/* 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;
/*
* 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_SYS_FSL_DDR2)
if ((outpdimm->lowest_common_spd_caslat < 4) &&
(picos_to_mclk(ctrl_num, trcd_ps) >
outpdimm->lowest_common_spd_caslat)) {
additive_latency = picos_to_mclk(ctrl_num, trcd_ps) -
outpdimm->lowest_common_spd_caslat;
if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
additive_latency = picos_to_mclk(ctrl_num, trcd_ps);
debug("setting additive_latency to %u because it was "
" greater than tRCD_ps\n", additive_latency);
}
}
#endif
/*
* Validate additive latency
*
* AL <= tRCD(min)
*/
if (mclk_to_picos(ctrl_num, 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);
#ifdef CONFIG_SYS_FSL_DDR4
debug("trfc1_ps = %u\n", trfc1_ps);
debug("trfc2_ps = %u\n", trfc2_ps);
debug("trfc4_ps = %u\n", trfc4_ps);
debug("trrds_ps = %u\n", trrds_ps);
debug("trrdl_ps = %u\n", trrdl_ps);
debug("tccdl_ps = %u\n", tccdl_ps);
#else
debug("twtr_ps = %u\n", outpdimm->twtr_ps);
debug("trfc_ps = %u\n", outpdimm->trfc_ps);
debug("trrd_ps = %u\n", outpdimm->trrd_ps);
#endif
debug("twr_ps = %u\n", outpdimm->twr_ps);
debug("trc_ps = %u\n", outpdimm->trc_ps);
return 0;
}

View File

@@ -0,0 +1,866 @@
/*
* Copyright 2008-2014 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 <i2c.h>
#include <fsl_ddr_sdram.h>
#include <fsl_ddr.h>
/*
* CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY is the physical address from the view
* of DDR controllers. It is the same as CONFIG_SYS_DDR_SDRAM_BASE for
* all Power SoCs. But it could be different for ARM SoCs. For example,
* fsl_lsch3 has a mapping mechanism to map DDR memory to ranges (in order) of
* 0x00_8000_0000 ~ 0x00_ffff_ffff
* 0x80_8000_0000 ~ 0xff_ffff_ffff
*/
#ifndef CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY
#define CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY CONFIG_SYS_DDR_SDRAM_BASE
#endif
#ifdef CONFIG_PPC
#include <asm/fsl_law.h>
void fsl_ddr_set_lawbar(
const common_timing_params_t *memctl_common_params,
unsigned int memctl_interleaved,
unsigned int ctrl_num);
#endif
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
#define SPD_SPA0_ADDRESS 0x36
#define SPD_SPA1_ADDRESS 0x37
static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
{
int ret;
#ifdef CONFIG_SYS_FSL_DDR4
uint8_t dummy = 0;
#endif
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
#ifdef CONFIG_SYS_FSL_DDR4
/*
* DDR4 SPD has 384 to 512 bytes
* To access the lower 256 bytes, we need to set EE page address to 0
* To access the upper 256 bytes, we need to set EE page address to 1
* See Jedec standar No. 21-C for detail
*/
i2c_write(SPD_SPA0_ADDRESS, 0, 1, &dummy, 1);
ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, 256);
if (!ret) {
i2c_write(SPD_SPA1_ADDRESS, 0, 1, &dummy, 1);
ret = i2c_read(i2c_address, 0, 1,
(uchar *)((ulong)spd + 256),
min(256,
(int)sizeof(generic_spd_eeprom_t) - 256));
}
#else
ret = i2c_read(i2c_address, 0, 1, (uchar *)spd,
sizeof(generic_spd_eeprom_t));
#endif
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);
/* This function allows boards to update SPD address */
__weak void update_spd_address(unsigned int ctrl_num,
unsigned int slot,
unsigned int *addr)
{
}
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl)
{
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 < dimm_slots_per_ctrl; i++) {
i2c_address = spd_i2c_addr[ctrl_num][i];
update_spd_address(ctrl_num, i, &i2c_address);
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, unsigned int dimm_slots_per_ctrl)
{
}
#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];
if (s >= ARRAY_SIZE(step_string_tbl)) {
printf("Error for the step in %s\n", __func__);
s = 0;
}
return step_string_tbl[s];
}
static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo,
unsigned int dbw_cap_adj[])
{
unsigned int i, j;
unsigned long long total_mem, current_mem_base, total_ctlr_mem;
unsigned long long rank_density, ctlr_density = 0;
unsigned int first_ctrl = pinfo->first_ctrl;
unsigned int last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
/*
* 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 = first_ctrl; i <= last_ctrl; 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 = pinfo->mem_base;
total_mem = 0;
if (pinfo->memctl_opts[first_ctrl].memctl_interleaving) {
rank_density = pinfo->dimm_params[first_ctrl][0].rank_density >>
dbw_cap_adj[first_ctrl];
switch (pinfo->memctl_opts[first_ctrl].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 = first_ctrl; i <= last_ctrl; i++) {
if (pinfo->memctl_opts[i].memctl_interleaving) {
switch (pinfo->memctl_opts[i].memctl_interleaving_mode) {
case FSL_DDR_256B_INTERLEAVING:
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 = first_ctrl; i <= last_ctrl; 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 = 0;
unsigned int first_ctrl = pinfo->first_ctrl;
unsigned int last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
__maybe_unused int retval;
__maybe_unused bool goodspd = false;
__maybe_unused int dimm_slots_per_ctrl = pinfo->dimm_slots_per_ctrl;
fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
common_timing_params_t *timing_params = pinfo->common_timing_params;
if (pinfo->board_need_mem_reset)
assert_reset = pinfo->board_need_mem_reset();
/* data bus width capacity adjust shift amount */
unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS];
for (i = first_ctrl; i <= last_ctrl; 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 = first_ctrl; i <= last_ctrl; i++) {
fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i,
dimm_slots_per_ctrl);
}
case STEP_COMPUTE_DIMM_PARMS:
/* STEP 2: Compute DIMM parameters from SPD data */
for (i = first_ctrl; i <= last_ctrl; i++) {
for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
generic_spd_eeprom_t *spd =
&(pinfo->spd_installed_dimms[i][j]);
dimm_params_t *pdimm =
&(pinfo->dimm_params[i][j]);
retval = compute_dimm_parameters(
i, spd, pdimm, j);
#ifdef CONFIG_SYS_DDR_RAW_TIMING
if (!j && retval) {
printf("SPD error on controller %d! "
"Trying fallback to raw timing "
"calculation\n", i);
retval = 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);
} else {
goodspd = true;
}
}
}
if (!goodspd) {
/*
* No valid SPD found
* Throw an error if this is for main memory, i.e.
* first_ctrl == 0. Otherwise, siliently return 0
* as the memory size.
*/
if (first_ctrl == 0)
printf("Error: No valid SPD detected.\n");
return 0;
}
#elif defined(CONFIG_SYS_DDR_RAW_TIMING)
case STEP_COMPUTE_DIMM_PARMS:
for (i = first_ctrl; i <= last_ctrl; 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 = first_ctrl; i <= last_ctrl; i++) {
debug("Computing lowest common DIMM"
" parameters for memctl=%u\n", i);
compute_lowest_common_dimm_parameters
(i,
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 = first_ctrl; i <= last_ctrl; 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],
&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 && !size_only) {
if (pinfo->board_mem_reset) {
debug("Asserting mem reset\n");
pinfo->board_mem_reset();
} else {
debug("Asserting mem reset missing\n");
}
}
case STEP_ASSIGN_ADDRESSES:
/* STEP 5: Assign addresses to chip selects */
check_interleaving_options(pinfo);
total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust);
debug("Total mem %llu assigned\n", total_mem);
case STEP_COMPUTE_REGS:
/* STEP 6: compute controller register values */
debug("FSL Memory ctrl register computation\n");
for (i = first_ctrl; i <= last_ctrl; 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
(i,
&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 = first_ctrl; i <= last_ctrl; 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) - pinfo->mem_base;
}
return total_mem;
}
phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo)
{
unsigned int i, first_ctrl, last_ctrl;
#ifdef CONFIG_PPC
unsigned int law_memctl = LAW_TRGT_IF_DDR_1;
#endif
unsigned long long total_memory;
int deassert_reset = 0;
first_ctrl = pinfo->first_ctrl;
last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
/* 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(pinfo, 0);
} else if (fsl_ddr_interactive_env_var_exists()) {
total_memory = fsl_ddr_interactive(pinfo, 1);
} else
#endif
total_memory = fsl_ddr_compute(pinfo, STEP_GET_SPD, 0);
/* setup 3-way interleaving before enabling DDRC */
switch (pinfo->memctl_opts[first_ctrl].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(
pinfo->memctl_opts[first_ctrl].
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.
*/
if (pinfo->board_need_mem_reset)
deassert_reset = pinfo->board_need_mem_reset();
for (i = first_ctrl; i <= last_ctrl; i++) {
if (pinfo->common_timing_params[i].all_dimms_registered)
deassert_reset = 1;
}
for (i = first_ctrl; i <= last_ctrl; i++) {
debug("Programming controller %u\n", i);
if (pinfo->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(&(pinfo->fsl_ddr_config_reg[i]), i,
deassert_reset ? 1 : 0);
}
if (deassert_reset) {
/* Use board FPGA or GPIO to deassert reset signal */
if (pinfo->board_mem_de_reset) {
debug("Deasserting mem reset\n");
pinfo->board_mem_de_reset();
} else {
debug("Deasserting mem reset missing\n");
}
for (i = first_ctrl; i <= last_ctrl; i++) {
/* Call with step = 2 to continue initialization */
fsl_ddr_set_memctl_regs(&(pinfo->fsl_ddr_config_reg[i]),
i, 2);
}
}
#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
fsl_ddr_sync_memctl_refresh(first_ctrl, last_ctrl);
#endif
#ifdef CONFIG_PPC
/* program LAWs */
for (i = first_ctrl; i <= last_ctrl; 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:
if (i % 2)
break;
if (i == 0) {
law_memctl = LAW_TRGT_IF_DDR_INTRLV;
fsl_ddr_set_lawbar(
&pinfo->common_timing_params[i],
law_memctl, i);
}
#if CONFIG_NUM_DDR_CONTROLLERS > 3
else if (i == 2) {
law_memctl = LAW_TRGT_IF_DDR_INTLV_34;
fsl_ddr_set_lawbar(
&pinfo->common_timing_params[i],
law_memctl, i);
}
#endif
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(
&pinfo->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(
&pinfo->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(&pinfo->common_timing_params[i],
law_memctl, i);
}
}
#endif
debug("total_memory by %s = %llu\n", __func__, total_memory);
#if !defined(CONFIG_PHYS_64BIT)
/* Check for 4G or more. Bad. */
if ((first_ctrl == 0) && (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(void) -- 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)
{
fsl_ddr_info_t info;
/* Reset info structure. */
memset(&info, 0, sizeof(fsl_ddr_info_t));
info.mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY;
info.first_ctrl = 0;
info.num_ctrls = CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS;
info.dimm_slots_per_ctrl = CONFIG_DIMM_SLOTS_PER_CTLR;
info.board_need_mem_reset = board_need_mem_reset;
info.board_mem_reset = board_assert_mem_reset;
info.board_mem_de_reset = board_deassert_mem_reset;
remove_unused_controllers(&info);
return __fsl_ddr_sdram(&info);
}
#ifdef CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS
phys_size_t fsl_other_ddr_sdram(unsigned long long base,
unsigned int first_ctrl,
unsigned int num_ctrls,
unsigned int dimm_slots_per_ctrl,
int (*board_need_reset)(void),
void (*board_reset)(void),
void (*board_de_reset)(void))
{
fsl_ddr_info_t info;
/* Reset info structure. */
memset(&info, 0, sizeof(fsl_ddr_info_t));
info.mem_base = base;
info.first_ctrl = first_ctrl;
info.num_ctrls = num_ctrls;
info.dimm_slots_per_ctrl = dimm_slots_per_ctrl;
info.board_need_mem_reset = board_need_reset;
info.board_mem_reset = board_reset;
info.board_mem_de_reset = board_de_reset;
return __fsl_ddr_sdram(&info);
}
#endif
/*
* fsl_ddr_sdram_size(first_ctrl, last_intlv) - 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));
info.mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY;
info.first_ctrl = 0;
info.num_ctrls = CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS;
info.dimm_slots_per_ctrl = CONFIG_DIMM_SLOTS_PER_CTLR;
info.board_need_mem_reset = NULL;
remove_unused_controllers(&info);
/* Compute it once normally. */
total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1);
return total_memory;
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/io.h>
#include <fsl_ddr_sdram.h>
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
#endif
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num, int step)
{
unsigned int i;
struct ccsr_ddr __iomem *ddr =
(struct ccsr_ddr __iomem *)CONFIG_SYS_FSL_DDR_ADDR;
if (ctrl_num != 0) {
printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
return;
}
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (i == 0) {
out_be32(&ddr->cs0_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs0_config, regs->cs[i].config);
} else if (i == 1) {
out_be32(&ddr->cs1_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs1_config, regs->cs[i].config);
} else if (i == 2) {
out_be32(&ddr->cs2_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs2_config, regs->cs[i].config);
} else if (i == 3) {
out_be32(&ddr->cs3_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs3_config, regs->cs[i].config);
}
}
out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
#if defined(CONFIG_MPC8555) || defined(CONFIG_MPC8541)
out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
#endif
/*
* 200 painful micro-seconds must elapse between
* the DDR clock setup and the DDR config enable.
*/
udelay(200);
asm volatile("sync;isync");
out_be32(&ddr->sdram_cfg, regs->ddr_sdram_cfg);
asm("sync;isync;msync");
udelay(500);
}
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
/*
* Initialize all of memory for ECC, then enable errors.
*/
void
ddr_enable_ecc(unsigned int dram_size)
{
struct ccsr_ddr __iomem *ddr =
(struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_DDR_ADDR);
dma_meminit(CONFIG_MEM_INIT_VALUE, dram_size);
/*
* Enable errors for ECC.
*/
debug("DMA DDR: err_disable = 0x%08x\n", ddr->err_disable);
ddr->err_disable = 0x00000000;
asm("sync;isync;msync");
debug("DMA DDR: err_disable = 0x%08x\n", ddr->err_disable);
}
#endif /* CONFIG_DDR_ECC && ! CONFIG_ECC_INIT_VIA_DDRCONTROLLER */

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <fsl_ddr_sdram.h>
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
#endif
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num, int step)
{
unsigned int i;
struct ccsr_ddr __iomem *ddr =
(struct ccsr_ddr __iomem *)CONFIG_SYS_FSL_DDR_ADDR;
#if defined(CONFIG_SYS_FSL_ERRATUM_NMG_DDR120) && defined(CONFIG_MPC85xx)
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
uint svr;
#endif
if (ctrl_num) {
printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
return;
}
#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120
/*
* Set the DDR IO receiver to an acceptable bias point.
* Fixed in Rev 2.1.
*/
svr = get_svr();
if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) {
if ((regs->ddr_sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) ==
SDRAM_CFG_SDRAM_TYPE_DDR2)
out_be32(&gur->ddrioovcr, 0x90000000);
else
out_be32(&gur->ddrioovcr, 0xA8000000);
}
#endif
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (i == 0) {
out_be32(&ddr->cs0_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs0_config, regs->cs[i].config);
} else if (i == 1) {
out_be32(&ddr->cs1_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs1_config, regs->cs[i].config);
} else if (i == 2) {
out_be32(&ddr->cs2_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs2_config, regs->cs[i].config);
} else if (i == 3) {
out_be32(&ddr->cs3_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs3_config, regs->cs[i].config);
}
}
out_be32(&ddr->timing_cfg_3, regs->timing_cfg_3);
out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0);
out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
out_be32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
out_be32(&ddr->init_addr, regs->ddr_init_addr);
out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
/*
* 200 painful micro-seconds must elapse between
* the DDR clock setup and the DDR config enable.
*/
udelay(200);
asm volatile("sync;isync");
out_be32(&ddr->sdram_cfg, regs->ddr_sdram_cfg);
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
while (in_be32(&ddr->sdram_cfg_2) & 0x10) {
udelay(10000); /* throttle polling rate */
}
}

View File

@@ -0,0 +1,556 @@
/*
* Copyright 2008-2012 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/io.h>
#include <fsl_ddr_sdram.h>
#include <asm/processor.h>
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
#endif
/*
* regs has the to-be-set values for DDR controller registers
* ctrl_num is the DDR controller number
* step: 0 goes through the initialization in one pass
* 1 sets registers and returns before enabling controller
* 2 resumes from step 1 and continues to initialize
* Dividing the initialization to two steps to deassert DDR reset signal
* to comply with JEDEC specs for RDIMMs.
*/
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num, int step)
{
unsigned int i, bus_width;
struct ccsr_ddr __iomem *ddr;
u32 temp_sdram_cfg;
u32 total_gb_size_per_controller;
int timeout;
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
int timeout_save;
volatile ccsr_local_ecm_t *ecm = (void *)CONFIG_SYS_MPC85xx_ECM_ADDR;
unsigned int csn_bnds_backup = 0, cs_sa, cs_ea, *csn_bnds_t;
int csn = -1;
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003
u32 save1, save2;
#endif
switch (ctrl_num) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
break;
#endif
default:
printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
return;
}
if (step == 2)
goto step2;
if (regs->ddr_eor)
out_be32(&ddr->eor, regs->ddr_eor);
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
debug("Workaround for ERRATUM_DDR111_DDR134\n");
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
cs_sa = (regs->cs[i].bnds >> 16) & 0xfff;
cs_ea = regs->cs[i].bnds & 0xfff;
if ((cs_sa <= 0xff) && (cs_ea >= 0xff)) {
csn = i;
csn_bnds_backup = regs->cs[i].bnds;
csn_bnds_t = (unsigned int *) &regs->cs[i].bnds;
if (cs_ea > 0xeff)
*csn_bnds_t = regs->cs[i].bnds + 0x01000000;
else
*csn_bnds_t = regs->cs[i].bnds + 0x01000100;
debug("Found cs%d_bns (0x%08x) covering 0xff000000, "
"change it to 0x%x\n",
csn, csn_bnds_backup, regs->cs[i].bnds);
break;
}
}
#endif
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (i == 0) {
out_be32(&ddr->cs0_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs0_config, regs->cs[i].config);
out_be32(&ddr->cs0_config_2, regs->cs[i].config_2);
} else if (i == 1) {
out_be32(&ddr->cs1_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs1_config, regs->cs[i].config);
out_be32(&ddr->cs1_config_2, regs->cs[i].config_2);
} else if (i == 2) {
out_be32(&ddr->cs2_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs2_config, regs->cs[i].config);
out_be32(&ddr->cs2_config_2, regs->cs[i].config_2);
} else if (i == 3) {
out_be32(&ddr->cs3_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs3_config, regs->cs[i].config);
out_be32(&ddr->cs3_config_2, regs->cs[i].config_2);
}
}
out_be32(&ddr->timing_cfg_3, regs->timing_cfg_3);
out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0);
out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
out_be32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4);
out_be32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5);
out_be32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6);
out_be32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7);
out_be32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8);
out_be32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4);
out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);
out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
#ifndef CONFIG_SYS_FSL_DDR_EMU
/*
* Skip these two registers if running on emulator
* because emulator doesn't have skew between bytes.
*/
if (regs->ddr_wrlvl_cntl_2)
out_be32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2);
if (regs->ddr_wrlvl_cntl_3)
out_be32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3);
#endif
out_be32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);
out_be32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
out_be32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
out_be32(&ddr->ddr_cdr1, regs->ddr_cdr1);
#ifdef CONFIG_DEEP_SLEEP
if (is_warm_boot()) {
out_be32(&ddr->sdram_cfg_2,
regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
out_be32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE);
out_be32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA);
/* DRAM VRef will not be trained */
out_be32(&ddr->ddr_cdr2,
regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN);
} else
#endif
{
out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
out_be32(&ddr->init_addr, regs->ddr_init_addr);
out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2);
}
out_be32(&ddr->err_disable, regs->err_disable);
out_be32(&ddr->err_int_en, regs->err_int_en);
for (i = 0; i < 32; i++) {
if (regs->debug[i]) {
debug("Write to debug_%d as %08x\n", i+1, regs->debug[i]);
out_be32(&ddr->debug[i], regs->debug[i]);
}
}
#ifdef CONFIG_SYS_FSL_ERRATUM_A_004934
out_be32(&ddr->debug[28], 0x30003000);
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003474
out_be32(&ddr->debug[12], 0x00000015);
out_be32(&ddr->debug[21], 0x24000000);
#endif /* CONFIG_SYS_FSL_ERRATUM_DDR_A003474 */
/*
* For RDIMMs, JEDEC spec requires clocks to be stable before reset is
* deasserted. Clocks start when any chip select is enabled and clock
* control register is set. Because all DDR components are connected to
* one reset signal, this needs to be done in two steps. Step 1 is to
* get the clocks started. Step 2 resumes after reset signal is
* deasserted.
*/
if (step == 1) {
udelay(200);
return;
}
step2:
/* Set, but do not enable the memory */
temp_sdram_cfg = regs->ddr_sdram_cfg;
temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
out_be32(&ddr->sdram_cfg, temp_sdram_cfg);
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003
debug("Workaround for ERRATUM_DDR_A003\n");
if (regs->ddr_sdram_rcw_2 & 0x00f00000) {
out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2 & 0xf07fffff);
out_be32(&ddr->debug[2], 0x00000400);
out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl & 0x7fffffff);
out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl & 0x7fffffff);
out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2 & 0xffffffeb);
out_be32(&ddr->mtcr, 0);
save1 = in_be32(&ddr->debug[12]);
save2 = in_be32(&ddr->debug[21]);
out_be32(&ddr->debug[12], 0x00000015);
out_be32(&ddr->debug[21], 0x24000000);
out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval & 0xffff);
out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_BI | SDRAM_CFG_MEM_EN);
asm volatile("sync;isync");
while (!(in_be32(&ddr->debug[1]) & 0x2))
;
switch (regs->ddr_sdram_rcw_2 & 0x00f00000) {
case 0x00000000:
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS0_CS1 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x02));
#if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
break;
while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
;
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS2_CS3 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x02));
#endif
break;
case 0x00100000:
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS0_CS1 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x0a));
#if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
break;
while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
;
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS2_CS3 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x0a));
#endif
break;
case 0x00200000:
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS0_CS1 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x12));
#if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
break;
while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
;
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS2_CS3 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x12));
#endif
break;
case 0x00300000:
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS0_CS1 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x1a));
#if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
break;
while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
;
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS2_CS3 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x1a));
#endif
break;
default:
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS0_CS1 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x02));
#if (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
if (!(regs->cs[2].config & SDRAM_CS_CONFIG_EN))
break;
while (in_be32(&ddr->sdram_md_cntl) & MD_CNTL_MD_EN)
;
out_be32(&ddr->sdram_md_cntl,
MD_CNTL_MD_EN |
MD_CNTL_CS_SEL_CS2_CS3 |
0x04000000 |
MD_CNTL_WRCW |
MD_CNTL_MD_VALUE(0x02));
#endif
printf("Unsupported RC10\n");
break;
}
while (in_be32(&ddr->sdram_md_cntl) & 0x80000000)
;
udelay(6);
out_be32(&ddr->sdram_cfg, temp_sdram_cfg);
out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
out_be32(&ddr->debug[2], 0x0);
out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
out_be32(&ddr->debug[12], save1);
out_be32(&ddr->debug[21], save2);
out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
}
#endif
/*
* For 8572 DDR1 erratum - DDR controller may enter illegal state
* when operatiing in 32-bit bus mode with 4-beat bursts,
* This erratum does not affect DDR3 mode, only for DDR2 mode.
*/
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR_115
debug("Workaround for ERRATUM_DDR_115\n");
if ((((in_be32(&ddr->sdram_cfg) >> 24) & 0x7) == SDRAM_TYPE_DDR2)
&& in_be32(&ddr->sdram_cfg) & 0x80000) {
/* set DEBUG_1[31] */
setbits_be32(&ddr->debug[0], 1);
}
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
debug("Workaround for ERRATUM_DDR111_DDR134\n");
/*
* This is the combined workaround for DDR111 and DDR134
* following the published errata for MPC8572
*/
/* 1. Set EEBACR[3] */
setbits_be32(&ecm->eebacr, 0x10000000);
debug("Setting EEBACR[3] to 0x%08x\n", in_be32(&ecm->eebacr));
/* 2. Set DINIT in SDRAM_CFG_2*/
setbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_D_INIT);
debug("Setting sdram_cfg_2[D_INIT] to 0x%08x\n",
in_be32(&ddr->sdram_cfg_2));
/* 3. Set DEBUG_3[21] */
setbits_be32(&ddr->debug[2], 0x400);
debug("Setting DEBUG_3[21] to 0x%08x\n", in_be32(&ddr->debug[2]));
#endif /* part 1 of the workaound */
/*
* 500 painful micro-seconds must elapse between
* the DDR clock setup and the DDR config enable.
* DDR2 need 200 us, and DDR3 need 500 us from spec,
* we choose the max, that is 500 us for all of case.
*/
udelay(500);
asm volatile("sync;isync");
#ifdef CONFIG_DEEP_SLEEP
if (is_warm_boot()) {
/* enter self-refresh */
setbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR);
/* do board specific memory setup */
board_mem_sleep_setup();
temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI);
} else
#endif
temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI);
/* Let the controller go */
out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
asm volatile("sync;isync");
total_gb_size_per_controller = 0;
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (!(regs->cs[i].config & 0x80000000))
continue;
total_gb_size_per_controller += 1 << (
((regs->cs[i].config >> 14) & 0x3) + 2 +
((regs->cs[i].config >> 8) & 0x7) + 12 +
((regs->cs[i].config >> 0) & 0x7) + 8 +
3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) -
26); /* minus 26 (count of 64M) */
}
if (fsl_ddr_get_intl3r() & 0x80000000) /* 3-way interleaving */
total_gb_size_per_controller *= 3;
else if (regs->cs[0].config & 0x20000000) /* 2-way interleaving */
total_gb_size_per_controller <<= 1;
/*
* total memory / bus width = transactions needed
* transactions needed / data rate = seconds
* to add plenty of buffer, double the time
* For example, 2GB on 666MT/s 64-bit bus takes about 402ms
* Let's wait for 800ms
*/
bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(ctrl_num) >> 20)) << 1;
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
timeout_save = timeout;
#endif
total_gb_size_per_controller >>= 4; /* shift down to gb size */
debug("total %d GB\n", total_gb_size_per_controller);
debug("Need to wait up to %d * 10ms\n", timeout);
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
while ((in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
(timeout >= 0)) {
udelay(10000); /* throttle polling rate */
timeout--;
}
if (timeout <= 0)
printf("Waiting for D_INIT timeout. Memory may not work.\n");
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
/* continue this workaround */
/* 4. Clear DEBUG3[21] */
clrbits_be32(&ddr->debug[2], 0x400);
debug("Clearing D3[21] to 0x%08x\n", in_be32(&ddr->debug[2]));
/* DDR134 workaround starts */
/* A: Clear sdram_cfg_2[odt_cfg] */
clrbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_ODT_CFG_MASK);
debug("Clearing SDRAM_CFG2[ODT_CFG] to 0x%08x\n",
in_be32(&ddr->sdram_cfg_2));
/* B: Set DEBUG1[15] */
setbits_be32(&ddr->debug[0], 0x10000);
debug("Setting D1[15] to 0x%08x\n", in_be32(&ddr->debug[0]));
/* C: Set timing_cfg_2[cpo] to 0b11111 */
setbits_be32(&ddr->timing_cfg_2, TIMING_CFG_2_CPO_MASK);
debug("Setting TMING_CFG_2[CPO] to 0x%08x\n",
in_be32(&ddr->timing_cfg_2));
/* D: Set D6 to 0x9f9f9f9f */
out_be32(&ddr->debug[5], 0x9f9f9f9f);
debug("Setting D6 to 0x%08x\n", in_be32(&ddr->debug[5]));
/* E: Set D7 to 0x9f9f9f9f */
out_be32(&ddr->debug[6], 0x9f9f9f9f);
debug("Setting D7 to 0x%08x\n", in_be32(&ddr->debug[6]));
/* F: Set D2[20] */
setbits_be32(&ddr->debug[1], 0x800);
debug("Setting D2[20] to 0x%08x\n", in_be32(&ddr->debug[1]));
/* G: Poll on D2[20] until cleared */
while (in_be32(&ddr->debug[1]) & 0x800)
udelay(10000); /* throttle polling rate */
/* H: Clear D1[15] */
clrbits_be32(&ddr->debug[0], 0x10000);
debug("Setting D1[15] to 0x%08x\n", in_be32(&ddr->debug[0]));
/* I: Set sdram_cfg_2[odt_cfg] */
setbits_be32(&ddr->sdram_cfg_2,
regs->ddr_sdram_cfg_2 & SDRAM_CFG2_ODT_CFG_MASK);
debug("Setting sdram_cfg_2 to 0x%08x\n", in_be32(&ddr->sdram_cfg_2));
/* Continuing with the DDR111 workaround */
/* 5. Set D2[21] */
setbits_be32(&ddr->debug[1], 0x400);
debug("Setting D2[21] to 0x%08x\n", in_be32(&ddr->debug[1]));
/* 6. Poll D2[21] until its cleared */
while (in_be32(&ddr->debug[1]) & 0x400)
udelay(10000); /* throttle polling rate */
/* 7. Wait for state machine 2nd run, roughly 400ms/GB */
debug("Wait for %d * 10ms\n", timeout_save);
udelay(timeout_save * 10000);
/* 8. Set sdram_cfg_2[dinit] if options requires */
setbits_be32(&ddr->sdram_cfg_2,
regs->ddr_sdram_cfg_2 & SDRAM_CFG2_D_INIT);
debug("Setting sdram_cfg_2 to 0x%08x\n", in_be32(&ddr->sdram_cfg_2));
/* 9. Poll until dinit is cleared */
timeout = timeout_save;
debug("Need to wait up to %d * 10ms\n", timeout);
while ((in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
(timeout >= 0)) {
udelay(10000); /* throttle polling rate */
timeout--;
}
if (timeout <= 0)
printf("Waiting for D_INIT timeout. Memory may not work.\n");
/* 10. Clear EEBACR[3] */
clrbits_be32(&ecm->eebacr, 10000000);
debug("Clearing EEBACR[3] to 0x%08x\n", in_be32(&ecm->eebacr));
if (csn != -1) {
csn_bnds_t = (unsigned int *) &regs->cs[csn].bnds;
*csn_bnds_t = csn_bnds_backup;
debug("Change cs%d_bnds back to 0x%08x\n",
csn, regs->cs[csn].bnds);
setbits_be32(&ddr->sdram_cfg, 0x2); /* MEM_HALT */
switch (csn) {
case 0:
out_be32(&ddr->cs0_bnds, regs->cs[csn].bnds);
break;
case 1:
out_be32(&ddr->cs1_bnds, regs->cs[csn].bnds);
break;
#if CONFIG_CHIP_SELECTS_PER_CTRL > 2
case 2:
out_be32(&ddr->cs2_bnds, regs->cs[csn].bnds);
break;
case 3:
out_be32(&ddr->cs3_bnds, regs->cs[csn].bnds);
break;
#endif
}
clrbits_be32(&ddr->sdram_cfg, 0x2);
}
#endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */
#ifdef CONFIG_DEEP_SLEEP
if (is_warm_boot())
/* exit self-refresh */
clrbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR);
#endif
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <asm/io.h>
#include <fsl_ddr_sdram.h>
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
#endif
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num, int step)
{
unsigned int i;
struct ccsr_ddr __iomem *ddr;
switch (ctrl_num) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
break;
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
break;
default:
printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
return;
}
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (i == 0) {
out_be32(&ddr->cs0_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs0_config, regs->cs[i].config);
} else if (i == 1) {
out_be32(&ddr->cs1_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs1_config, regs->cs[i].config);
} else if (i == 2) {
out_be32(&ddr->cs2_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs2_config, regs->cs[i].config);
} else if (i == 3) {
out_be32(&ddr->cs3_bnds, regs->cs[i].bnds);
out_be32(&ddr->cs3_config, regs->cs[i].config);
}
}
out_be32(&ddr->timing_cfg_3, regs->timing_cfg_3);
out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0);
out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
out_be32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
out_be32(&ddr->init_addr, regs->ddr_init_addr);
out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
debug("before go\n");
/*
* 200 painful micro-seconds must elapse between
* the DDR clock setup and the DDR config enable.
*/
udelay(200);
asm volatile("sync;isync");
out_be32(&ddr->sdram_cfg, regs->ddr_sdram_cfg);
/*
* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done
*/
while (in_be32(&ddr->sdram_cfg_2) & 0x10) {
udelay(10000); /* throttle polling rate */
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,425 @@
/*
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#ifdef CONFIG_PPC
#include <asm/fsl_law.h>
#endif
#include <div64.h>
#include <fsl_ddr.h>
#include <fsl_immap.h>
#include <asm/io.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
u32 fsl_ddr_get_version(unsigned int ctrl_num)
{
struct ccsr_ddr __iomem *ddr;
u32 ver_major_minor_errata;
switch (ctrl_num) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
break;
#endif
default:
printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
return 0;
}
ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;
return ver_major_minor_errata;
}
/*
* 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(const unsigned int ctrl_num)
{
unsigned int data_rate = get_ddr_freq(ctrl_num);
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(const unsigned int ctrl_num, unsigned int picos)
{
unsigned long long clks, clks_rem;
unsigned long data_rate = get_ddr_freq(ctrl_num);
/* 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(const unsigned int ctrl_num, unsigned int mclk)
{
return get_memory_clk_period_ps(ctrl_num) * mclk;
}
#ifdef CONFIG_PPC
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);
#endif
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 print_ddr_info(unsigned int start_ctrl)
{
struct ccsr_ddr __iomem *ddr =
(struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_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 = ddr_in32(&ddr->cs0_config);
#endif
uint32_t sdram_cfg = ddr_in32(&ddr->sdram_cfg);
int cas_lat;
#if CONFIG_NUM_DDR_CONTROLLERS >= 2
if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
(start_ctrl == 1)) {
ddr = (void __iomem *)CONFIG_SYS_FSL_DDR2_ADDR;
sdram_cfg = ddr_in32(&ddr->sdram_cfg);
}
#endif
#if CONFIG_NUM_DDR_CONTROLLERS >= 3
if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
(start_ctrl == 2)) {
ddr = (void __iomem *)CONFIG_SYS_FSL_DDR3_ADDR;
sdram_cfg = ddr_in32(&ddr->sdram_cfg);
}
#endif
if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
puts(" (DDR not enabled)\n");
return;
}
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;
case SDRAM_TYPE_DDR4:
puts("4");
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 = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
if (fsl_ddr_get_version(0) <= 0x40400)
cas_lat += 1;
else
cas_lat += 2;
cas_lat += ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 3) << 4;
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) && (start_ctrl == 0)) {
puts("\n");
puts(" DDR Controller Interleaving Mode: ");
switch ((cs0_config >> 24) & 0xf) {
case FSL_DDR_256B_INTERLEAVING:
puts("256B");
break;
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;
}
}
}
void __weak detail_board_ddr_info(void)
{
print_ddr_info(0);
}
void board_add_ram_info(int use_default)
{
detail_board_ddr_info();
}
#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
#define DDRC_DEBUG20_INIT_DONE 0x80000000
#define DDRC_DEBUG2_RF 0x00000040
void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
unsigned int last_ctrl)
{
unsigned int i;
u32 ddrc_debug20;
u32 ddrc_debug2[CONFIG_NUM_DDR_CONTROLLERS] = {};
u32 *ddrc_debug2_p[CONFIG_NUM_DDR_CONTROLLERS] = {};
struct ccsr_ddr __iomem *ddr;
for (i = first_ctrl; i <= last_ctrl; i++) {
switch (i) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
break;
#endif
default:
printf("%s unexpected ctrl = %u\n", __func__, i);
return;
}
ddrc_debug20 = ddr_in32(&ddr->debug[19]);
ddrc_debug2_p[i] = &ddr->debug[1];
while (!(ddrc_debug20 & DDRC_DEBUG20_INIT_DONE)) {
/* keep polling until DDRC init is done */
udelay(100);
ddrc_debug20 = ddr_in32(&ddr->debug[19]);
}
ddrc_debug2[i] = ddr_in32(&ddr->debug[1]) | DDRC_DEBUG2_RF;
}
/*
* Sync refresh
* This is put together to make sure the refresh reqeusts are sent
* closely to each other.
*/
for (i = first_ctrl; i <= last_ctrl; i++)
ddr_out32(ddrc_debug2_p[i], ddrc_debug2[i]);
}
#endif /* CONFIG_FSL_DDR_SYNC_REFRESH */
void remove_unused_controllers(fsl_ddr_info_t *info)
{
#ifdef CONFIG_FSL_LSCH3
int i;
u64 nodeid;
void *hnf_sam_ctrl = (void *)(CCI_HN_F_0_BASE + CCN_HN_F_SAM_CTL);
bool ddr0_used = false;
bool ddr1_used = false;
for (i = 0; i < 8; i++) {
nodeid = in_le64(hnf_sam_ctrl) & CCN_HN_F_SAM_NODEID_MASK;
if (nodeid == CCN_HN_F_SAM_NODEID_DDR0) {
ddr0_used = true;
} else if (nodeid == CCN_HN_F_SAM_NODEID_DDR1) {
ddr1_used = true;
} else {
printf("Unknown nodeid in HN-F SAM control: 0x%llx\n",
nodeid);
}
hnf_sam_ctrl += (CCI_HN_F_1_BASE - CCI_HN_F_0_BASE);
}
if (!ddr0_used && !ddr1_used) {
printf("Invalid configuration in HN-F SAM control\n");
return;
}
if (!ddr0_used && info->first_ctrl == 0) {
info->first_ctrl = 1;
info->num_ctrls = 1;
debug("First DDR controller disabled\n");
return;
}
if (!ddr1_used && info->first_ctrl + info->num_ctrls > 1) {
info->num_ctrls = 1;
debug("Second DDR controller disabled\n");
}
#endif
}