1
0
Fork 0

driver/ddr/fsl: Add DDR4 support to Freescale DDR driver

Mostly reusing DDR3 driver, this patch adds DDR4 SPD handling, register
calculation and programming.

Signed-off-by: York Sun <yorksun@freescale.com>
utp
York Sun 2014-03-27 17:54:47 -07:00
parent 8d451a7129
commit 34e026f9b1
19 changed files with 2378 additions and 321 deletions

13
README
View File

@ -458,6 +458,9 @@ The following options need to be configured:
CONFIG_SYS_FSL_DDRC_GEN3
Freescale DDR3 controller.
CONFIG_SYS_FSL_DDRC_GEN4
Freescale DDR4 controller.
CONFIG_SYS_FSL_DDRC_ARM_GEN3
Freescale DDR3 controller for ARM-based SoCs.
@ -473,7 +476,15 @@ The following options need to be configured:
CONFIG_SYS_FSL_DDR3
Board config to use DDR3. It can be enabled for SoCs with
Freescale DDR3 controllers.
Freescale DDR3 or DDR3L controllers.
CONFIG_SYS_FSL_DDR3L
Board config to use DDR3L. It can be enabled for SoCs with
DDR3L controllers.
CONFIG_SYS_FSL_DDR4
Board config to use DDR4. It can be enabled for SoCs with
DDR4 controllers.
CONFIG_SYS_FSL_IFC_BE
Defines the IFC controller register space as Big Endian

View File

@ -19,8 +19,8 @@
*/
#define CONFIG_PPC_SPINTABLE_COMPATIBLE
#define FSL_DDR_VER_4_7 47
#define FSL_DDR_VER_5_0 50
#include <fsl_ddrc_version.h>
#define CONFIG_SYS_FSL_DDR_BE
/* IP endianness */
#define CONFIG_SYS_FSL_IFC_BE
@ -401,6 +401,7 @@
#define CONFIG_SYS_NUM_FM1_DTSEC 5
#define CONFIG_SYS_NUM_FM1_10GEC 1
#define CONFIG_NUM_DDR_CONTROLLERS 1
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_5
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000
#define CONFIG_SYS_FSL_TBCLK_DIV 32
#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2"
@ -442,6 +443,7 @@
#define CONFIG_SYS_NUM_FM1_10GEC 1
#define CONFIG_SYS_NUM_FM2_10GEC 1
#define CONFIG_NUM_DDR_CONTROLLERS 2
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_4
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000
#define CONFIG_SYS_FSL_TBCLK_DIV 16
@ -490,6 +492,7 @@
#define CONFIG_SYS_NUM_FM1_DTSEC 5
#define CONFIG_SYS_NUM_FM1_10GEC 1
#define CONFIG_NUM_DDR_CONTROLLERS 2
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_4
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000
#define CONFIG_SYS_FSL_TBCLK_DIV 32
@ -527,6 +530,7 @@
#define CONFIG_SYS_NUM_FM2_DTSEC 5
#define CONFIG_SYS_NUM_FM2_10GEC 1
#define CONFIG_NUM_DDR_CONTROLLERS 2
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_4
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000
#define CONFIG_SYS_FSL_TBCLK_DIV 16
@ -553,6 +557,7 @@
#define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 4
#define CONFIG_NUM_DDR_CONTROLLERS 1
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_4
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR 0xb0000000
#define CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT 0xff600000
@ -571,6 +576,7 @@
#define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 4
#define CONFIG_NUM_DDR_CONTROLLERS 2
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_6
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#define CONFIG_SYS_FSL_DSP_DDR_ADDR 0x40000000
#define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR 0xb0000000
@ -704,6 +710,9 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
#define CONFIG_SYS_FSL_QORIQ_CHASSIS2 /* Freescale Chassis generation 2 */
#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 1
#define CONFIG_SYS_FSL_QMAN_V3 /* QMAN version 3 */
#ifdef CONFIG_SYS_FSL_DDR4
#define CONFIG_SYS_FSL_DDRC_GEN4
#endif
#if defined(CONFIG_PPC_T1040) || defined(CONFIG_PPC_T1042)
#define CONFIG_MAX_CPUS 4
#elif defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
@ -796,6 +805,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
#define CONFIG_SYS_FSL_SEC_COMPAT 6
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
#define CONFIG_NUM_DDR_CONTROLLERS 1
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_6
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 8
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
#define CONFIG_SYS_FSL_ERRATUM_A005125
@ -820,7 +830,8 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
#if !defined(CONFIG_SYS_FSL_DDRC_GEN1) && \
!defined(CONFIG_SYS_FSL_DDRC_GEN2) && \
!defined(CONFIG_SYS_FSL_DDRC_GEN3)
!defined(CONFIG_SYS_FSL_DDRC_GEN3) && \
!defined(CONFIG_SYS_FSL_DDRC_GEN4)
#define CONFIG_SYS_FSL_DDRC_GEN3
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -116,3 +116,46 @@ ddr3_spd_check(const ddr3_spd_eeprom_t *spd)
return 1;
}
}
unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s *spd)
{
char *p = (char *)spd;
int csum16;
int len;
char crc_lsb; /* byte 126 */
char crc_msb; /* byte 127 */
len = 126;
csum16 = crc16(p, len);
crc_lsb = (char) (csum16 & 0xff);
crc_msb = (char) (csum16 >> 8);
if (spd->crc[0] != crc_lsb || spd->crc[1] != crc_msb) {
printf("SPD checksum unexpected.\n"
"Checksum lsb in SPD = %02X, computed SPD = %02X\n"
"Checksum msb in SPD = %02X, computed SPD = %02X\n",
spd->crc[0], crc_lsb, spd->crc[1], crc_msb);
return 1;
}
p = (char *)((ulong)spd + 128);
len = 126;
csum16 = crc16(p, len);
crc_lsb = (char) (csum16 & 0xff);
crc_msb = (char) (csum16 >> 8);
if (spd->mod_section.uc[126] != crc_lsb ||
spd->mod_section.uc[127] != crc_msb) {
printf("SPD checksum unexpected.\n"
"Checksum lsb in SPD = %02X, computed SPD = %02X\n"
"Checksum msb in SPD = %02X, computed SPD = %02X\n",
spd->mod_section.uc[126],
crc_lsb, spd->mod_section.uc[127],
crc_msb);
return 1;
}
return 0;
}

View File

@ -1,19 +1,20 @@
#
# Copyright 2008-2011 Freescale Semiconductor, Inc.
# Copyright 2008-2014 Freescale Semiconductor, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# Version 2 as published by the Free Software Foundation.
#
obj-$(CONFIG_SYS_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \
lc_common_dimm_params.o
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
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
ifdef CONFIG_DDR_SPD
SPD := y
endif
@ -24,6 +25,7 @@ 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
@ -32,3 +34,4 @@ 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,300 @@
/*
* 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 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 generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
int i;
if (spd->mem_type) {
if (spd->mem_type != SPD_MEMTYPE_DDR4) {
printf("DIMM %u: is not a DDR4 SPD.\n", 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 DDR3 SPD spec */
pdimm->mirrored_dimm = 0;
pdimm->registered_dimm = 0;
switch (spd->module_type & DDR3_SPD_MODULETYPE_MASK) {
case DDR3_SPD_MODULETYPE_RDIMM:
/* Registered/buffered DIMMs */
pdimm->registered_dimm = 1;
break;
case DDR3_SPD_MODULETYPE_UDIMM:
case DDR3_SPD_MODULETYPE_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->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,234 @@
/*
* Copyright 2014 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_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);
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_2, regs->ddr_sdram_cfg_2);
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);
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init);
ddr_out32(&ddr->init_addr, regs->ddr_init_addr);
ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
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);
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("sync;isync");
/* Let the controller go */
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
ddr_out32(&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 >> 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->sdram_cfg & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(0) >> 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");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2010-2012 Freescale Semiconductor, Inc.
* Copyright 2010-2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@ -153,25 +153,38 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
static const struct options_string options[] = {
COMMON_TIMING(tckmin_x_ps),
COMMON_TIMING(tckmax_ps),
COMMON_TIMING(tckmax_max_ps),
COMMON_TIMING(taamin_ps),
COMMON_TIMING(trcd_ps),
COMMON_TIMING(trp_ps),
COMMON_TIMING(tras_ps),
COMMON_TIMING(twr_ps),
#ifdef CONFIG_SYS_FSL_DDR4
COMMON_TIMING(trfc1_ps),
COMMON_TIMING(trfc2_ps),
COMMON_TIMING(trfc4_ps),
COMMON_TIMING(trrds_ps),
COMMON_TIMING(trrdl_ps),
COMMON_TIMING(tccdl_ps),
#else
COMMON_TIMING(twtr_ps),
COMMON_TIMING(trfc_ps),
COMMON_TIMING(trrd_ps),
COMMON_TIMING(trtp_ps),
#endif
COMMON_TIMING(twr_ps),
COMMON_TIMING(trc_ps),
COMMON_TIMING(refresh_rate_ps),
COMMON_TIMING(extended_op_srt),
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
COMMON_TIMING(tis_ps),
COMMON_TIMING(tih_ps),
COMMON_TIMING(tds_ps),
COMMON_TIMING(tdh_ps),
COMMON_TIMING(trtp_ps),
COMMON_TIMING(tdqsq_max_ps),
COMMON_TIMING(tqhs_ps),
#endif
COMMON_TIMING(ndimms_present),
COMMON_TIMING(lowest_common_SPD_caslat),
COMMON_TIMING(lowest_common_spd_caslat),
COMMON_TIMING(highest_common_derated_caslat),
COMMON_TIMING(additive_latency),
COMMON_TIMING(all_dimms_burst_lengths_bitmask),
@ -211,7 +224,12 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
DIMM_PARM(n_row_addr),
DIMM_PARM(n_col_addr),
DIMM_PARM(edc_config),
#ifdef CONFIG_SYS_FSL_DDR4
DIMM_PARM(bank_addr_bits),
DIMM_PARM(bank_group_bits),
#else
DIMM_PARM(n_banks_per_sdram_device),
#endif
DIMM_PARM(burst_lengths_bitmask),
DIMM_PARM(row_density),
@ -229,20 +247,32 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
DIMM_PARM(trcd_ps),
DIMM_PARM(trp_ps),
DIMM_PARM(tras_ps),
#ifdef CONFIG_SYS_FSL_DDR4
DIMM_PARM(trfc1_ps),
DIMM_PARM(trfc2_ps),
DIMM_PARM(trfc4_ps),
DIMM_PARM(trrds_ps),
DIMM_PARM(trrdl_ps),
DIMM_PARM(tccdl_ps),
#else
DIMM_PARM(twr_ps),
DIMM_PARM(twtr_ps),
DIMM_PARM(trfc_ps),
DIMM_PARM(trrd_ps),
DIMM_PARM(trtp_ps),
#endif
DIMM_PARM(trc_ps),
DIMM_PARM(refresh_rate_ps),
DIMM_PARM(extended_op_srt),
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
DIMM_PARM(tis_ps),
DIMM_PARM(tih_ps),
DIMM_PARM(tds_ps),
DIMM_PARM(tdh_ps),
DIMM_PARM(trtp_ps),
DIMM_PARM(tdqsq_max_ps),
DIMM_PARM(tqhs_ps),
#endif
DIMM_PARM(rank_density),
DIMM_PARM(capacity),
@ -270,7 +300,12 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(n_row_addr),
DIMM_PARM(n_col_addr),
DIMM_PARM(edc_config),
#ifdef CONFIG_SYS_FSL_DDR4
DIMM_PARM(bank_addr_bits),
DIMM_PARM(bank_group_bits),
#else
DIMM_PARM(n_banks_per_sdram_device),
#endif
DIMM_PARM(tckmin_x_ps),
DIMM_PARM(tckmin_x_minus_1_ps),
@ -286,20 +321,31 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(trcd_ps),
DIMM_PARM(trp_ps),
DIMM_PARM(tras_ps),
#ifdef CONFIG_SYS_FSL_DDR4
DIMM_PARM(trfc1_ps),
DIMM_PARM(trfc2_ps),
DIMM_PARM(trfc4_ps),
DIMM_PARM(trrds_ps),
DIMM_PARM(trrdl_ps),
DIMM_PARM(tccdl_ps),
#else
DIMM_PARM(twr_ps),
DIMM_PARM(twtr_ps),
DIMM_PARM(trfc_ps),
DIMM_PARM(trrd_ps),
DIMM_PARM(trtp_ps),
#endif
DIMM_PARM(trc_ps),
DIMM_PARM(refresh_rate_ps),
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
DIMM_PARM(tis_ps),
DIMM_PARM(tih_ps),
DIMM_PARM(tds_ps),
DIMM_PARM(tdh_ps),
DIMM_PARM(trtp_ps),
DIMM_PARM(tdqsq_max_ps),
DIMM_PARM(tqhs_ps),
#endif
};
static const unsigned int n_opts = ARRAY_SIZE(options);
@ -326,23 +372,36 @@ static void print_lowest_common_dimm_parameters(
const common_timing_params_t *plcd_dimm_params)
{
static const struct options_string options[] = {
COMMON_TIMING(tckmax_max_ps),
COMMON_TIMING(taamin_ps),
COMMON_TIMING(trcd_ps),
COMMON_TIMING(trp_ps),
COMMON_TIMING(tras_ps),
COMMON_TIMING(twr_ps),
#ifdef CONFIG_SYS_FSL_DDR4
COMMON_TIMING(trfc1_ps),
COMMON_TIMING(trfc2_ps),
COMMON_TIMING(trfc4_ps),
COMMON_TIMING(trrds_ps),
COMMON_TIMING(trrdl_ps),
COMMON_TIMING(tccdl_ps),
#else
COMMON_TIMING(twtr_ps),
COMMON_TIMING(trfc_ps),
COMMON_TIMING(trrd_ps),
COMMON_TIMING(trtp_ps),
#endif
COMMON_TIMING(twr_ps),
COMMON_TIMING(trc_ps),
COMMON_TIMING(refresh_rate_ps),
COMMON_TIMING(extended_op_srt),
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
COMMON_TIMING(tis_ps),
COMMON_TIMING(tih_ps),
COMMON_TIMING(tds_ps),
COMMON_TIMING(tdh_ps),
COMMON_TIMING(trtp_ps),
COMMON_TIMING(tdqsq_max_ps),
COMMON_TIMING(tqhs_ps),
COMMON_TIMING(lowest_common_SPD_caslat),
#endif
COMMON_TIMING(lowest_common_spd_caslat),
COMMON_TIMING(highest_common_derated_caslat),
COMMON_TIMING(additive_latency),
COMMON_TIMING(ndimms_present),
@ -460,6 +519,9 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
CTRL_OPTIONS(tfaw_window_four_activates_ps),
CTRL_OPTIONS(trwt_override),
CTRL_OPTIONS(trwt),
CTRL_OPTIONS(rtt_override),
CTRL_OPTIONS(rtt_override_value),
CTRL_OPTIONS(rtt_wr_override_value),
};
static const unsigned int n_opts = ARRAY_SIZE(options);
@ -505,6 +567,7 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
CFG_REGS(timing_cfg_2),
CFG_REGS(ddr_sdram_cfg),
CFG_REGS(ddr_sdram_cfg_2),
CFG_REGS(ddr_sdram_cfg_3),
CFG_REGS(ddr_sdram_mode),
CFG_REGS(ddr_sdram_mode_2),
CFG_REGS(ddr_sdram_mode_3),
@ -513,6 +576,16 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
CFG_REGS(ddr_sdram_mode_6),
CFG_REGS(ddr_sdram_mode_7),
CFG_REGS(ddr_sdram_mode_8),
#ifdef CONFIG_SYS_FSL_DDR4
CFG_REGS(ddr_sdram_mode_9),
CFG_REGS(ddr_sdram_mode_10),
CFG_REGS(ddr_sdram_mode_11),
CFG_REGS(ddr_sdram_mode_12),
CFG_REGS(ddr_sdram_mode_13),
CFG_REGS(ddr_sdram_mode_14),
CFG_REGS(ddr_sdram_mode_15),
CFG_REGS(ddr_sdram_mode_16),
#endif
CFG_REGS(ddr_sdram_interval),
CFG_REGS(ddr_data_init),
CFG_REGS(ddr_sdram_clk_cntl),
@ -520,6 +593,12 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
CFG_REGS(ddr_init_ext_addr),
CFG_REGS(timing_cfg_4),
CFG_REGS(timing_cfg_5),
#ifdef CONFIG_SYS_FSL_DDR4
CFG_REGS(timing_cfg_6),
CFG_REGS(timing_cfg_7),
CFG_REGS(timing_cfg_8),
CFG_REGS(timing_cfg_9),
#endif
CFG_REGS(ddr_zq_cntl),
CFG_REGS(ddr_wrlvl_cntl),
CFG_REGS(ddr_wrlvl_cntl_2),
@ -529,6 +608,10 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
CFG_REGS(ddr_sdram_rcw_2),
CFG_REGS(ddr_cdr1),
CFG_REGS(ddr_cdr2),
CFG_REGS(dq_map_0),
CFG_REGS(dq_map_1),
CFG_REGS(dq_map_2),
CFG_REGS(dq_map_3),
CFG_REGS(err_disable),
CFG_REGS(err_int_en),
CFG_REGS(ddr_eor),
@ -574,6 +657,7 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
CFG_REGS(timing_cfg_2),
CFG_REGS(ddr_sdram_cfg),
CFG_REGS(ddr_sdram_cfg_2),
CFG_REGS(ddr_sdram_cfg_3),
CFG_REGS(ddr_sdram_mode),
CFG_REGS(ddr_sdram_mode_2),
CFG_REGS(ddr_sdram_mode_3),
@ -582,6 +666,16 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
CFG_REGS(ddr_sdram_mode_6),
CFG_REGS(ddr_sdram_mode_7),
CFG_REGS(ddr_sdram_mode_8),
#ifdef CONFIG_SYS_FSL_DDR4
CFG_REGS(ddr_sdram_mode_9),
CFG_REGS(ddr_sdram_mode_10),
CFG_REGS(ddr_sdram_mode_11),
CFG_REGS(ddr_sdram_mode_12),
CFG_REGS(ddr_sdram_mode_13),
CFG_REGS(ddr_sdram_mode_14),
CFG_REGS(ddr_sdram_mode_15),
CFG_REGS(ddr_sdram_mode_16),
#endif
CFG_REGS(ddr_sdram_interval),
CFG_REGS(ddr_data_init),
CFG_REGS(ddr_sdram_clk_cntl),
@ -589,6 +683,12 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
CFG_REGS(ddr_init_ext_addr),
CFG_REGS(timing_cfg_4),
CFG_REGS(timing_cfg_5),
#ifdef CONFIG_SYS_FSL_DDR4
CFG_REGS(timing_cfg_6),
CFG_REGS(timing_cfg_7),
CFG_REGS(timing_cfg_8),
CFG_REGS(timing_cfg_9),
#endif
CFG_REGS(ddr_zq_cntl),
CFG_REGS(ddr_wrlvl_cntl),
CFG_REGS(ddr_wrlvl_cntl_2),
@ -598,6 +698,10 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
CFG_REGS(ddr_sdram_rcw_2),
CFG_REGS(ddr_cdr1),
CFG_REGS(ddr_cdr2),
CFG_REGS(dq_map_0),
CFG_REGS(dq_map_1),
CFG_REGS(dq_map_2),
CFG_REGS(dq_map_3),
CFG_REGS(err_disable),
CFG_REGS(err_int_en),
CFG_REGS(ddr_sdram_rcw_2),
@ -705,6 +809,9 @@ static void print_memctl_options(const memctl_options_t *popts)
CTRL_OPTIONS(tfaw_window_four_activates_ps),
CTRL_OPTIONS(trwt_override),
CTRL_OPTIONS(trwt),
CTRL_OPTIONS(rtt_override),
CTRL_OPTIONS(rtt_override_value),
CTRL_OPTIONS(rtt_wr_override_value),
};
static const unsigned int n_opts = ARRAY_SIZE(options);
@ -1245,6 +1352,266 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd)
}
#endif
#ifdef CONFIG_SYS_FSL_DDR4
void ddr4_spd_dump(const struct ddr4_spd_eeprom_s *spd)
{
unsigned int i;
/* General Section: Bytes 0-127 */
#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y);
#define PRINT_NNXXS(n0, n1, x0, x1, s) \
printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1);
PRINT_NXS(0, spd->info_size_crc,
"info_size_crc bytes written into serial memory, CRC coverage");
PRINT_NXS(1, spd->spd_rev,
"spd_rev SPD Revision");
PRINT_NXS(2, spd->mem_type,
"mem_type Key Byte / DRAM Device Type");
PRINT_NXS(3, spd->module_type,
"module_type Key Byte / Module Type");
PRINT_NXS(4, spd->density_banks,
"density_banks SDRAM Density and Banks");
PRINT_NXS(5, spd->addressing,
"addressing SDRAM Addressing");
PRINT_NXS(6, spd->package_type,
"package_type Package type");
PRINT_NXS(7, spd->opt_feature,
"opt_feature Optional features");
PRINT_NXS(8, spd->thermal_ref,
"thermal_ref Thermal and Refresh options");
PRINT_NXS(9, spd->oth_opt_features,
"oth_opt_features Other SDRAM optional features");
PRINT_NXS(10, spd->res_10,
"res_10 Reserved");
PRINT_NXS(11, spd->module_vdd,
"module_vdd Module Nominal Voltage, VDD");
PRINT_NXS(12, spd->organization,
"organization Module Organization");
PRINT_NXS(13, spd->bus_width,
"bus_width Module Memory Bus Width");
PRINT_NXS(14, spd->therm_sensor,
"therm_sensor Module Thermal Sensor");
PRINT_NXS(15, spd->ext_type,
"ext_type Extended module type");
PRINT_NXS(16, spd->res_16,
"res_16 Reserved");
PRINT_NXS(17, spd->timebases,
"timebases MTb and FTB");
PRINT_NXS(18, spd->tck_min,
"tck_min tCKAVGmin");
PRINT_NXS(19, spd->tck_max,
"tck_max TCKAVGmax");
PRINT_NXS(20, spd->caslat_b1,
"caslat_b1 CAS latencies, 1st byte");
PRINT_NXS(21, spd->caslat_b2,
"caslat_b2 CAS latencies, 2nd byte");
PRINT_NXS(22, spd->caslat_b3,
"caslat_b3 CAS latencies, 3rd byte ");
PRINT_NXS(23, spd->caslat_b4,
"caslat_b4 CAS latencies, 4th byte");
PRINT_NXS(24, spd->taa_min,
"taa_min Min CAS Latency Time");
PRINT_NXS(25, spd->trcd_min,
"trcd_min Min RAS# to CAS# Delay Time");
PRINT_NXS(26, spd->trp_min,
"trp_min Min Row Precharge Delay Time");
PRINT_NXS(27, spd->tras_trc_ext,
"tras_trc_ext Upper Nibbles for tRAS and tRC");
PRINT_NXS(28, spd->tras_min_lsb,
"tras_min_lsb tRASmin, lsb");
PRINT_NXS(29, spd->trc_min_lsb,
"trc_min_lsb tRCmin, lsb");
PRINT_NXS(30, spd->trfc1_min_lsb,
"trfc1_min_lsb Min Refresh Recovery Delay Time, LSB");
PRINT_NXS(31, spd->trfc1_min_msb,
"trfc1_min_msb Min Refresh Recovery Delay Time, MSB ");
PRINT_NXS(32, spd->trfc2_min_lsb,
"trfc2_min_lsb Min Refresh Recovery Delay Time, LSB");
PRINT_NXS(33, spd->trfc2_min_msb,
"trfc2_min_msb Min Refresh Recovery Delay Time, MSB");
PRINT_NXS(34, spd->trfc4_min_lsb,
"trfc4_min_lsb Min Refresh Recovery Delay Time, LSB");
PRINT_NXS(35, spd->trfc4_min_msb,
"trfc4_min_msb Min Refresh Recovery Delay Time, MSB");
PRINT_NXS(36, spd->tfaw_msb,
"tfaw_msb Upper Nibble for tFAW");
PRINT_NXS(37, spd->tfaw_min,
"tfaw_min tFAW, lsb");
PRINT_NXS(38, spd->trrds_min,
"trrds_min tRRD_Smin, MTB");
PRINT_NXS(39, spd->trrdl_min,
"trrdl_min tRRD_Lmin, MTB");
PRINT_NXS(40, spd->tccdl_min,
"tccdl_min tCCS_Lmin, MTB");
printf("%-3d-%3d: ", 41, 59); /* Reserved, General Section */
for (i = 41; i <= 59; i++)
printf("%02x ", spd->res_41[i - 41]);
puts("\n");
printf("%-3d-%3d: ", 60, 77);
for (i = 60; i <= 77; i++)
printf("%02x ", spd->mapping[i - 60]);
puts(" mapping[] Connector to SDRAM bit map\n");
PRINT_NXS(117, spd->fine_tccdl_min,
"fine_tccdl_min Fine offset for tCCD_Lmin");
PRINT_NXS(118, spd->fine_trrdl_min,
"fine_trrdl_min Fine offset for tRRD_Lmin");
PRINT_NXS(119, spd->fine_trrds_min,
"fine_trrds_min Fine offset for tRRD_Smin");
PRINT_NXS(120, spd->fine_trc_min,
"fine_trc_min Fine offset for tRCmin");
PRINT_NXS(121, spd->fine_trp_min,
"fine_trp_min Fine offset for tRPmin");
PRINT_NXS(122, spd->fine_trcd_min,
"fine_trcd_min Fine offset for tRCDmin");
PRINT_NXS(123, spd->fine_taa_min,
"fine_taa_min Fine offset for tAAmin");
PRINT_NXS(124, spd->fine_tck_max,
"fine_tck_max Fine offset for tCKAVGmax");
PRINT_NXS(125, spd->fine_tck_min,
"fine_tck_min Fine offset for tCKAVGmin");
/* CRC: Bytes 126-127 */
PRINT_NNXXS(126, 127, spd->crc[0], spd->crc[1], " SPD CRC");
switch (spd->module_type) {
case 0x02: /* UDIMM */
case 0x03: /* SO-DIMM */
PRINT_NXS(128, spd->mod_section.unbuffered.mod_height,
"mod_height (Unbuffered) Module Nominal Height");
PRINT_NXS(129, spd->mod_section.unbuffered.mod_thickness,
"mod_thickness (Unbuffered) Module Maximum Thickness");
PRINT_NXS(130, spd->mod_section.unbuffered.ref_raw_card,
"ref_raw_card (Unbuffered) Reference Raw Card Used");
PRINT_NXS(131, spd->mod_section.unbuffered.addr_mapping,
"addr_mapping (Unbuffered) Address mapping from Edge Connector to DRAM");
PRINT_NNXXS(254, 255, spd->mod_section.unbuffered.crc[0],
spd->mod_section.unbuffered.crc[1], " Module CRC");
break;
case 0x01: /* RDIMM */
PRINT_NXS(128, spd->mod_section.registered.mod_height,
"mod_height (Registered) Module Nominal Height");
PRINT_NXS(129, spd->mod_section.registered.mod_thickness,
"mod_thickness (Registered) Module Maximum Thickness");
PRINT_NXS(130, spd->mod_section.registered.ref_raw_card,
"ref_raw_card (Registered) Reference Raw Card Used");
PRINT_NXS(131, spd->mod_section.registered.modu_attr,
"modu_attr (Registered) DIMM Module Attributes");
PRINT_NXS(132, spd->mod_section.registered.thermal,
"thermal (Registered) Thermal Heat Spreader Solution");
PRINT_NXS(133, spd->mod_section.registered.reg_id_lo,
"reg_id_lo (Registered) Register Manufacturer ID Code, LSB");
PRINT_NXS(134, spd->mod_section.registered.reg_id_hi,
"reg_id_hi (Registered) Register Manufacturer ID Code, MSB");
PRINT_NXS(135, spd->mod_section.registered.reg_rev,
"reg_rev (Registered) Register Revision Number");
PRINT_NXS(136, spd->mod_section.registered.reg_map,
"reg_map (Registered) Address mapping");
PRINT_NNXXS(254, 255, spd->mod_section.registered.crc[0],
spd->mod_section.registered.crc[1], " Module CRC");
break;
case 0x04: /* LRDIMM */
PRINT_NXS(128, spd->mod_section.loadreduced.mod_height,
"mod_height (Loadreduced) Module Nominal Height");
PRINT_NXS(129, spd->mod_section.loadreduced.mod_thickness,
"mod_thickness (Loadreduced) Module Maximum Thickness");
PRINT_NXS(130, spd->mod_section.loadreduced.ref_raw_card,
"ref_raw_card (Loadreduced) Reference Raw Card Used");
PRINT_NXS(131, spd->mod_section.loadreduced.modu_attr,
"modu_attr (Loadreduced) DIMM Module Attributes");
PRINT_NXS(132, spd->mod_section.loadreduced.thermal,
"thermal (Loadreduced) Thermal Heat Spreader Solution");
PRINT_NXS(133, spd->mod_section.loadreduced.reg_id_lo,
"reg_id_lo (Loadreduced) Register Manufacturer ID Code, LSB");
PRINT_NXS(134, spd->mod_section.loadreduced.reg_id_hi,
"reg_id_hi (Loadreduced) Register Manufacturer ID Code, MSB");
PRINT_NXS(135, spd->mod_section.loadreduced.reg_rev,
"reg_rev (Loadreduced) Register Revision Number");
PRINT_NXS(136, spd->mod_section.loadreduced.reg_map,
"reg_map (Loadreduced) Address mapping");
PRINT_NXS(137, spd->mod_section.loadreduced.reg_drv,
"reg_drv (Loadreduced) Reg output drive strength");
PRINT_NXS(138, spd->mod_section.loadreduced.reg_drv_ck,
"reg_drv_ck (Loadreduced) Reg output drive strength for CK");
PRINT_NXS(139, spd->mod_section.loadreduced.data_buf_rev,
"data_buf_rev (Loadreduced) Data Buffer Revision Numbe");
PRINT_NXS(140, spd->mod_section.loadreduced.vrefqe_r0,
"vrefqe_r0 (Loadreduced) DRAM VrefDQ for Package Rank 0");
PRINT_NXS(141, spd->mod_section.loadreduced.vrefqe_r1,
"vrefqe_r1 (Loadreduced) DRAM VrefDQ for Package Rank 1");
PRINT_NXS(142, spd->mod_section.loadreduced.vrefqe_r2,
"vrefqe_r2 (Loadreduced) DRAM VrefDQ for Package Rank 2");
PRINT_NXS(143, spd->mod_section.loadreduced.vrefqe_r3,
"vrefqe_r3 (Loadreduced) DRAM VrefDQ for Package Rank 3");
PRINT_NXS(144, spd->mod_section.loadreduced.data_intf,
"data_intf (Loadreduced) Data Buffer VrefDQ for DRAM Interface");
PRINT_NXS(145, spd->mod_section.loadreduced.data_drv_1866,
"data_drv_1866 (Loadreduced) Data Buffer MDQ Drive Strength and RTT");
PRINT_NXS(146, spd->mod_section.loadreduced.data_drv_2400,
"data_drv_2400 (Loadreduced) Data Buffer MDQ Drive Strength and RTT");
PRINT_NXS(147, spd->mod_section.loadreduced.data_drv_3200,
"data_drv_3200 (Loadreduced) Data Buffer MDQ Drive Strength and RTT");
PRINT_NXS(148, spd->mod_section.loadreduced.dram_drv,
"dram_drv (Loadreduced) DRAM Drive Strength");
PRINT_NXS(149, spd->mod_section.loadreduced.dram_odt_1866,
"dram_odt_1866 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)");
PRINT_NXS(150, spd->mod_section.loadreduced.dram_odt_2400,
"dram_odt_2400 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)");
PRINT_NXS(151, spd->mod_section.loadreduced.dram_odt_3200,
"dram_odt_3200 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)");
PRINT_NXS(152, spd->mod_section.loadreduced.dram_odt_park_1866,
"dram_odt_park_1866 (Loadreduced) DRAM ODT (RTT_PARK)");
PRINT_NXS(153, spd->mod_section.loadreduced.dram_odt_park_2400,
"dram_odt_park_2400 (Loadreduced) DRAM ODT (RTT_PARK)");
PRINT_NXS(154, spd->mod_section.loadreduced.dram_odt_park_3200,
"dram_odt_park_3200 (Loadreduced) DRAM ODT (RTT_PARK)");
PRINT_NNXXS(254, 255, spd->mod_section.loadreduced.crc[0],
spd->mod_section.loadreduced.crc[1],
" Module CRC");
break;
default:
/* Module-specific Section, Unsupported Module Type */
printf("%-3d-%3d: ", 128, 255);
for (i = 128; i <= 255; i++)
printf("%02x", spd->mod_section.uc[i - 60]);
break;
}
/* Unique Module ID: Bytes 320-383 */
PRINT_NXS(320, spd->mmid_lsb, "Module MfgID Code LSB - JEP-106");
PRINT_NXS(321, spd->mmid_msb, "Module MfgID Code MSB - JEP-106");
PRINT_NXS(322, spd->mloc, "Mfg Location");
PRINT_NNXXS(323, 324, spd->mdate[0], spd->mdate[1], "Mfg Date");
printf("%-3d-%3d: ", 325, 328);
for (i = 325; i <= 328; i++)
printf("%02x ", spd->sernum[i - 325]);
printf(" Module Serial Number\n");
printf("%-3d-%3d: ", 329, 348);
for (i = 329; i <= 348; i++)
printf("%02x ", spd->mpart[i - 329]);
printf(" Mfg's Module Part Number\n");
PRINT_NXS(349, spd->mrev, "Module Revision code");
PRINT_NXS(350, spd->dmid_lsb, "DRAM MfgID Code LSB - JEP-106");
PRINT_NXS(351, spd->dmid_msb, "DRAM MfgID Code MSB - JEP-106");
PRINT_NXS(352, spd->stepping, "DRAM stepping");
printf("%-3d-%3d: ", 353, 381);
for (i = 353; i <= 381; i++)
printf("%02x ", spd->msd[i - 353]);
printf(" Mfg's Specific Data\n");
}
#endif
static inline void generic_spd_dump(const generic_spd_eeprom_t *spd)
{
#if defined(CONFIG_SYS_FSL_DDR1)
@ -1253,6 +1620,8 @@ static inline void generic_spd_dump(const generic_spd_eeprom_t *spd)
ddr2_spd_dump(spd);
#elif defined(CONFIG_SYS_FSL_DDR3)
ddr3_spd_dump(spd);
#elif defined(CONFIG_SYS_FSL_DDR4)
ddr4_spd_dump(spd);
#endif
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008-2012 Freescale Semiconductor, Inc.
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -11,20 +11,23 @@
#include <fsl_ddr.h>
#if defined(CONFIG_SYS_FSL_DDR3)
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
static unsigned int
compute_cas_latency_ddr3(const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
compute_cas_latency(const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
{
unsigned int i;
unsigned int taamin_ps = 0;
unsigned int tckmin_x_ps = 0;
unsigned int common_caslat;
unsigned int caslat_actual;
unsigned int retry = 16;
unsigned int tmp;
const unsigned int mclk_ps = get_memory_clk_period_ps();
#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 */
tmp = dimm_params[0].caslat_x;
@ -34,19 +37,20 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params,
}
common_caslat = tmp;
/* compute the max tAAmin tCKmin between slots */
for (i = 0; i < number_of_dimms; i++) {
taamin_ps = max(taamin_ps, dimm_params[i].taa_ps);
tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps);
}
/* validate if the memory clk is in the range of dimms */
if (mclk_ps < tckmin_x_ps) {
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, tckmin_x_ps);
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 = (taamin_ps + mclk_ps - 1) / mclk_ps;
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++;
@ -54,13 +58,147 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params,
}
/* 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
* exceed tAAmax, which is 20 ns for all DDR3 speed grades,
* 18ns for all DDR4 speed grades.
*/
if (caslat_actual * mclk_ps > 20000) {
if (caslat_actual * mclk_ps > taamax) {
printf("The choosen cas latency %d is too large\n",
caslat_actual);
}
outpdimm->lowest_common_SPD_caslat = 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 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();
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;
}
@ -82,34 +220,40 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
unsigned int tckmin_x_ps = 0;
unsigned int tckmax_ps = 0xFFFFFFFF;
unsigned int tckmax_max_ps = 0;
unsigned int trcd_ps = 0;
unsigned int trp_ps = 0;
unsigned int tras_ps = 0;
#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 trtp_ps = 0;
unsigned int tdqsq_max_ps = 0;
unsigned int tqhs_ps = 0;
#endif
unsigned int temp1, temp2;
unsigned int additive_latency = 0;
#if !defined(CONFIG_SYS_FSL_DDR3)
const unsigned int mclk_ps = get_memory_clk_period_ps();
unsigned int lowest_good_caslat;
unsigned int not_ok;
debug("using mclk_ps = %u\n", mclk_ps);
#endif
temp1 = 0;
for (i = 0; i < number_of_dimms; i++) {
@ -146,31 +290,34 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
* i.e., this is the slowest the whole system can go.
*/
tckmax_ps = min(tckmax_ps, dimm_params[i].tckmax_ps);
/* Either find maximum value to determine slowest
* speed, delay, time, period, etc */
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
taamin_ps = max(taamin_ps, dimm_params[i].taa_ps);
#endif
tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps);
tckmax_max_ps = max(tckmax_max_ps, dimm_params[i].tckmax_ps);
trcd_ps = max(trcd_ps, dimm_params[i].trcd_ps);
trp_ps = max(trp_ps, dimm_params[i].trp_ps);
tras_ps = max(tras_ps, dimm_params[i].tras_ps);
#ifdef CONFIG_SYS_FSL_DDR4
trfc1_ps = max(trfc1_ps, dimm_params[i].trfc1_ps);
trfc2_ps = max(trfc2_ps, dimm_params[i].trfc2_ps);
trfc4_ps = max(trfc4_ps, dimm_params[i].trfc4_ps);
trrds_ps = max(trrds_ps, dimm_params[i].trrds_ps);
trrdl_ps = max(trrdl_ps, dimm_params[i].trrdl_ps);
tccdl_ps = max(tccdl_ps, dimm_params[i].tccdl_ps);
#else
twr_ps = max(twr_ps, dimm_params[i].twr_ps);
twtr_ps = max(twtr_ps, dimm_params[i].twtr_ps);
trfc_ps = max(trfc_ps, dimm_params[i].trfc_ps);
trrd_ps = max(trrd_ps, dimm_params[i].trrd_ps);
trtp_ps = max(trtp_ps, dimm_params[i].trtp_ps);
#endif
trc_ps = max(trc_ps, dimm_params[i].trc_ps);
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
tis_ps = max(tis_ps, dimm_params[i].tis_ps);
tih_ps = max(tih_ps, dimm_params[i].tih_ps);
tds_ps = max(tds_ps, dimm_params[i].tds_ps);
tdh_ps = max(tdh_ps, dimm_params[i].tdh_ps);
trtp_ps = max(trtp_ps, dimm_params[i].trtp_ps);
tqhs_ps = max(tqhs_ps, dimm_params[i].tqhs_ps);
refresh_rate_ps = max(refresh_rate_ps,
dimm_params[i].refresh_rate_ps);
/* extended_op_srt is either 0 or 1, 0 having priority */
extended_op_srt = min(extended_op_srt,
dimm_params[i].extended_op_srt);
/*
* Find maximum tdqsq_max_ps to find slowest.
*
@ -178,6 +325,12 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
* strategy for this parameter?
*/
tdqsq_max_ps = max(tdqsq_max_ps, dimm_params[i].tdqsq_max_ps);
#endif
refresh_rate_ps = max(refresh_rate_ps,
dimm_params[i].refresh_rate_ps);
/* extended_op_srt is either 0 or 1, 0 having priority */
extended_op_srt = min(extended_op_srt,
dimm_params[i].extended_op_srt);
}
outpdimm->ndimms_present = number_of_dimms - temp1;
@ -189,24 +342,37 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
outpdimm->tckmin_x_ps = tckmin_x_ps;
outpdimm->tckmax_ps = tckmax_ps;
outpdimm->tckmax_max_ps = tckmax_max_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;
outpdimm->twr_ps = twr_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->trtp_ps = trtp_ps;
outpdimm->tdqsq_max_ps = tdqsq_max_ps;
outpdimm->tqhs_ps = tqhs_ps;
#endif
/* Determine common burst length for all DIMMs. */
temp1 = 0xff;
@ -265,128 +431,9 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
if (temp1 != 0)
printf("ERROR: Mix different RDIMM detected!\n");
#if defined(CONFIG_SYS_FSL_DDR3)
if (compute_cas_latency_ddr3(dimm_params, outpdimm, number_of_dimms))
/* calculate cas latency for all DDR types */
if (compute_cas_latency(dimm_params, outpdimm, number_of_dimms))
return 1;
#else
/*
* Compute a CAS latency suitable for all DIMMs
*
* Strategy for SPD-defined latencies: compute only
* CAS latency defined by all DIMMs.
*/
/*
* Step 1: find CAS latency common to all DIMMs using bitwise
* operation.
*/
temp1 = 0xFF;
for (i = 0; i < number_of_dimms; i++) {
if (dimm_params[i].n_ranks) {
temp2 = 0;
temp2 |= 1 << dimm_params[i].caslat_x;
temp2 |= 1 << dimm_params[i].caslat_x_minus_1;
temp2 |= 1 << dimm_params[i].caslat_x_minus_2;
/*
* FIXME: If there was no entry for X-2 (X-1) in
* the SPD, then caslat_x_minus_2
* (caslat_x_minus_1) contains either 255 or
* 0xFFFFFFFF because that's what the glorious
* __ilog2 function returns for an input of 0.
* On 32-bit PowerPC, left shift counts with bit
* 26 set (that the value of 255 or 0xFFFFFFFF
* will have), cause the destination register to
* be 0. That is why this works.
*/
temp1 &= temp2;
}
}
/*
* Step 2: check each common CAS latency against tCK of each
* DIMM's SPD.
*/
lowest_good_caslat = 0;
temp2 = 0;
while (temp1) {
not_ok = 0;
temp2 = __ilog2(temp1);
debug("checking common caslat = %u\n", temp2);
/* Check if this CAS latency will work on all DIMMs at tCK. */
for (i = 0; i < number_of_dimms; i++) {
if (!dimm_params[i].n_ranks) {
continue;
}
if (dimm_params[i].caslat_x == temp2) {
if (mclk_ps >= dimm_params[i].tckmin_x_ps) {
debug("CL = %u ok on DIMM %u at tCK=%u"
" ps with its tCKmin_X_ps of %u\n",
temp2, i, mclk_ps,
dimm_params[i].tckmin_x_ps);
continue;
} else {
not_ok++;
}
}
if (dimm_params[i].caslat_x_minus_1 == temp2) {
unsigned int tckmin_x_minus_1_ps
= dimm_params[i].tckmin_x_minus_1_ps;
if (mclk_ps >= tckmin_x_minus_1_ps) {
debug("CL = %u ok on DIMM %u at "
"tCK=%u ps with its "
"tckmin_x_minus_1_ps of %u\n",
temp2, i, mclk_ps,
tckmin_x_minus_1_ps);
continue;
} else {
not_ok++;
}
}
if (dimm_params[i].caslat_x_minus_2 == temp2) {
unsigned int tckmin_x_minus_2_ps
= dimm_params[i].tckmin_x_minus_2_ps;
if (mclk_ps >= tckmin_x_minus_2_ps) {
debug("CL = %u ok on DIMM %u at "
"tCK=%u ps with its "
"tckmin_x_minus_2_ps of %u\n",
temp2, i, mclk_ps,
tckmin_x_minus_2_ps);
continue;
} else {
not_ok++;
}
}
}
if (!not_ok) {
lowest_good_caslat = temp2;
}
temp1 &= ~(1 << temp2);
}
debug("lowest common SPD-defined CAS latency = %u\n",
lowest_good_caslat);
outpdimm->lowest_common_SPD_caslat = lowest_good_caslat;
/*
* Compute a common 'de-rated' CAS latency.
*
* The strategy here is to find the *highest* dereated cas latency
* with the assumption that all of the DIMMs will support a dereated
* CAS latency higher than or equal to their lowest dereated value.
*/
temp1 = 0;
for (i = 0; i < number_of_dimms; i++) {
temp1 = max(temp1, dimm_params[i].caslat_lowest_derated);
}
outpdimm->highest_common_derated_caslat = temp1;
debug("highest common dereated CAS latency = %u\n", temp1);
#endif /* #if defined(CONFIG_SYS_FSL_DDR3) */
/* Determine if all DIMMs ECC capable. */
temp1 = 1;
@ -404,14 +451,6 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
}
outpdimm->all_dimms_ecc_capable = temp1;
#ifndef CONFIG_SYS_FSL_DDR3
/* FIXME: move to somewhere else to validate. */
if (mclk_ps > tckmax_max_ps) {
printf("Warning: some of the installed DIMMs "
"can not operate this slowly.\n");
return 1;
}
#endif
/*
* Compute additive latency.
*
@ -468,27 +507,20 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
additive_latency = 0;
#if defined(CONFIG_SYS_FSL_DDR2)
if (lowest_good_caslat < 4) {
additive_latency = (picos_to_mclk(trcd_ps) > lowest_good_caslat)
? picos_to_mclk(trcd_ps) - lowest_good_caslat : 0;
if ((outpdimm->lowest_common_spd_caslat < 4) &&
(picos_to_mclk(trcd_ps) > outpdimm->lowest_common_spd_caslat)) {
additive_latency = picos_to_mclk(trcd_ps) -
outpdimm->lowest_common_spd_caslat;
if (mclk_to_picos(additive_latency) > trcd_ps) {
additive_latency = picos_to_mclk(trcd_ps);
debug("setting additive_latency to %u because it was "
" greater than tRCD_ps\n", additive_latency);
}
}
#elif defined(CONFIG_SYS_FSL_DDR3)
/*
* The system will not use the global auto-precharge mode.
* However, it uses the page mode, so we set AL=0
*/
additive_latency = 0;
#endif
/*
* Validate additive latency
* FIXME: move to somewhere else to validate
*
* AL <= tRCD(min)
*/
@ -516,10 +548,19 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
debug("trcd_ps = %u\n", outpdimm->trcd_ps);
debug("trp_ps = %u\n", outpdimm->trp_ps);
debug("tras_ps = %u\n", outpdimm->tras_ps);
debug("twr_ps = %u\n", outpdimm->twr_ps);
#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

@ -1,5 +1,5 @@
/*
* Copyright 2008-2012 Freescale Semiconductor, Inc.
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -81,14 +81,37 @@ u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
#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, 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 ==

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008, 2010-2012 Freescale Semiconductor, Inc.
* Copyright 2008, 2010-2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@ -29,7 +29,7 @@ struct dynamic_odt {
unsigned int odt_rtt_wr;
};
#ifdef CONFIG_SYS_FSL_DDR3
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
static const struct dynamic_odt single_Q[4] = {
{ /* cs0 */
FSL_DDR_ODT_NEVER,
@ -259,7 +259,7 @@ static const struct dynamic_odt odt_unknown[4] = {
DDR3_RTT_OFF
}
};
#else /* CONFIG_SYS_FSL_DDR3 */
#else /* CONFIG_SYS_FSL_DDR3 || CONFIG_SYS_FSL_DDR4 */
static const struct dynamic_odt single_Q[4] = {
{0, 0, 0, 0},
{0, 0, 0, 0},
@ -507,7 +507,9 @@ unsigned int populate_memctl_options(int all_dimms_registered,
unsigned int i;
char buffer[HWCONFIG_BUFFER_SIZE];
char *buf = NULL;
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR2)
#if defined(CONFIG_SYS_FSL_DDR3) || \
defined(CONFIG_SYS_FSL_DDR2) || \
defined(CONFIG_SYS_FSL_DDR4)
const struct dynamic_odt *pdodt = odt_unknown;
#endif
ulong ddr_freq;
@ -519,7 +521,9 @@ unsigned int populate_memctl_options(int all_dimms_registered,
if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
buf = buffer;
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR2)
#if defined(CONFIG_SYS_FSL_DDR3) || \
defined(CONFIG_SYS_FSL_DDR2) || \
defined(CONFIG_SYS_FSL_DDR4)
/* Chip select options. */
if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) {
switch (pdimm[0].n_ranks) {
@ -585,7 +589,9 @@ unsigned int populate_memctl_options(int all_dimms_registered,
/* Pick chip-select local options. */
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR2)
#if defined(CONFIG_SYS_FSL_DDR3) || \
defined(CONFIG_SYS_FSL_DDR2) || \
defined(CONFIG_SYS_FSL_DDR4)
popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg;
popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg;
popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm;
@ -703,7 +709,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0;
/* Choose burst length. */
#if defined(CONFIG_SYS_FSL_DDR3)
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
#if defined(CONFIG_E500MC)
popts->otf_burst_chop_en = 0; /* on-the-fly burst chop disable */
popts->burst_length = DDR_BL8; /* Fixed 8-beat burst len */
@ -722,7 +728,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
#endif
/* Choose ddr controller address mirror mode */
#if defined(CONFIG_SYS_FSL_DDR3)
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
popts->mirrored_dimm = pdimm[0].mirrored_dimm;
#endif
@ -766,11 +772,9 @@ unsigned int populate_memctl_options(int all_dimms_registered,
* BSTTOPRE precharge interval
*
* Set this to 0 for global auto precharge
*
* FIXME: Should this be configured in picoseconds?
* Why it should be in ps: better understanding of this
* relative to actual DRAM timing parameters such as tRAS.
* e.g. tRAS(min) = 40 ns
* The value of 0x100 has been used for DDR1, DDR2, DDR3.
* It is not wrong. Any value should be OK. The performance depends on
* applications. There is no one good value for all.
*/
popts->bstopre = 0x100;
@ -795,12 +799,12 @@ unsigned int populate_memctl_options(int all_dimms_registered,
*/
popts->tfaw_window_four_activates_ps = 37500;
#elif defined(CONFIG_SYS_FSL_DDR3)
#else
popts->tfaw_window_four_activates_ps = pdimm[0].tfaw_ps;
#endif
popts->zq_en = 0;
popts->wrlvl_en = 0;
#if defined(CONFIG_SYS_FSL_DDR3)
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
/*
* due to ddr3 dimm is fly-by topology
* we suggest to enable write leveling to

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008-2012 Freescale Semiconductor, Inc.
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,6 +23,18 @@
#define ULL_8FS 0xFFFFFFFFULL
u32 fsl_ddr_get_version(void)
{
struct ccsr_ddr __iomem *ddr;
u32 ver_major_minor_errata;
ddr = (void *)_DDR_ADDR;
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.
@ -175,6 +187,9 @@ void board_add_ram_info(int use_default)
case SDRAM_TYPE_DDR3:
puts("3");
break;
case SDRAM_TYPE_DDR4:
puts("4");
break;
default:
puts("?");
break;
@ -188,9 +203,12 @@ void board_add_ram_info(int use_default)
puts(", 64-bit");
/* Calculate CAS latency based on timing cfg values */
cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf) + 1;
if ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 1)
cas_lat += (8 << 1);
cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
if (fsl_ddr_get_version() <= 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");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -14,32 +14,45 @@ typedef struct {
unsigned int tckmin_x_ps;
unsigned int tckmax_ps;
unsigned int tckmax_max_ps;
unsigned int trcd_ps;
unsigned int trp_ps;
unsigned int tras_ps;
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
unsigned int taamin_ps;
#endif
unsigned int twr_ps; /* maximum = 63750 ps */
#ifdef CONFIG_SYS_FSL_DDR4
unsigned int trfc1_ps;
unsigned int trfc2_ps;
unsigned int trfc4_ps;
unsigned int trrds_ps;
unsigned int trrdl_ps;
unsigned int tccdl_ps;
#else
unsigned int twtr_ps; /* maximum = 63750 ps */
unsigned int trfc_ps; /* maximum = 255 ns + 256 ns + .75 ns
= 511750 ps */
unsigned int trrd_ps; /* maximum = 63750 ps */
unsigned int trtp_ps; /* byte 38, spd->trtp */
#endif
unsigned int twr_ps; /* maximum = 63750 ps */
unsigned int trc_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
unsigned int refresh_rate_ps;
unsigned int extended_op_srt;
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
unsigned int tis_ps; /* byte 32, spd->ca_setup */
unsigned int tih_ps; /* byte 33, spd->ca_hold */
unsigned int tds_ps; /* byte 34, spd->data_setup */
unsigned int tdh_ps; /* byte 35, spd->data_hold */
unsigned int trtp_ps; /* byte 38, spd->trtp */
unsigned int tdqsq_max_ps; /* byte 44, spd->tdqsq */
unsigned int tqhs_ps; /* byte 45, spd->tqhs */
#endif
unsigned int ndimms_present;
unsigned int lowest_common_SPD_caslat;
unsigned int lowest_common_spd_caslat;
unsigned int highest_common_derated_caslat;
unsigned int additive_latency;
unsigned int all_dimms_burst_lengths_bitmask;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -290,11 +290,220 @@ typedef struct ddr3_spd_eeprom_s {
} ddr3_spd_eeprom_t;
/* From JEEC Standard No. 21-C release 23A */
struct ddr4_spd_eeprom_s {
/* General Section: Bytes 0-127 */
uint8_t info_size_crc; /* 0 # bytes */
uint8_t spd_rev; /* 1 Total # bytes of SPD */
uint8_t mem_type; /* 2 Key Byte / mem type */
uint8_t module_type; /* 3 Key Byte / Module Type */
uint8_t density_banks; /* 4 Density and Banks */
uint8_t addressing; /* 5 Addressing */
uint8_t package_type; /* 6 Package type */
uint8_t opt_feature; /* 7 Optional features */
uint8_t thermal_ref; /* 8 Thermal and refresh */
uint8_t oth_opt_features; /* 9 Other optional features */
uint8_t res_10; /* 10 Reserved */
uint8_t module_vdd; /* 11 Module nominal voltage */
uint8_t organization; /* 12 Module Organization */
uint8_t bus_width; /* 13 Module Memory Bus Width */
uint8_t therm_sensor; /* 14 Module Thermal Sensor */
uint8_t ext_type; /* 15 Extended module type */
uint8_t res_16;
uint8_t timebases; /* 17 MTb and FTB */
uint8_t tck_min; /* 18 tCKAVGmin */
uint8_t tck_max; /* 19 TCKAVGmax */
uint8_t caslat_b1; /* 20 CAS latencies, 1st byte */
uint8_t caslat_b2; /* 21 CAS latencies, 2nd byte */
uint8_t caslat_b3; /* 22 CAS latencies, 3rd byte */
uint8_t caslat_b4; /* 23 CAS latencies, 4th byte */
uint8_t taa_min; /* 24 Min CAS Latency Time */
uint8_t trcd_min; /* 25 Min RAS# to CAS# Delay Time */
uint8_t trp_min; /* 26 Min Row Precharge Delay Time */
uint8_t tras_trc_ext; /* 27 Upper Nibbles for tRAS and tRC */
uint8_t tras_min_lsb; /* 28 tRASmin, lsb */
uint8_t trc_min_lsb; /* 29 tRCmin, lsb */
uint8_t trfc1_min_lsb; /* 30 Min Refresh Recovery Delay Time */
uint8_t trfc1_min_msb; /* 31 Min Refresh Recovery Delay Time */
uint8_t trfc2_min_lsb; /* 32 Min Refresh Recovery Delay Time */
uint8_t trfc2_min_msb; /* 33 Min Refresh Recovery Delay Time */
uint8_t trfc4_min_lsb; /* 34 Min Refresh Recovery Delay Time */
uint8_t trfc4_min_msb; /* 35 Min Refresh Recovery Delay Time */
uint8_t tfaw_msb; /* 36 Upper Nibble for tFAW */
uint8_t tfaw_min; /* 37 tFAW, lsb */
uint8_t trrds_min; /* 38 tRRD_Smin, MTB */
uint8_t trrdl_min; /* 39 tRRD_Lmin, MTB */
uint8_t tccdl_min; /* 40 tCCS_Lmin, MTB */
uint8_t res_41[60-41]; /* 41 Rserved */
uint8_t mapping[78-60]; /* 60~77 Connector to SDRAM bit map */
uint8_t res_78[117-78]; /* 78~116, Reserved */
int8_t fine_tccdl_min; /* 117 Fine offset for tCCD_Lmin */
int8_t fine_trrdl_min; /* 118 Fine offset for tRRD_Lmin */
int8_t fine_trrds_min; /* 119 Fine offset for tRRD_Smin */
int8_t fine_trc_min; /* 120 Fine offset for tRCmin */
int8_t fine_trp_min; /* 121 Fine offset for tRPmin */
int8_t fine_trcd_min; /* 122 Fine offset for tRCDmin */
int8_t fine_taa_min; /* 123 Fine offset for tAAmin */
int8_t fine_tck_max; /* 124 Fine offset for tCKAVGmax */
int8_t fine_tck_min; /* 125 Fine offset for tCKAVGmin */
/* CRC: Bytes 126-127 */
uint8_t crc[2]; /* 126-127 SPD CRC */
/* Module-Specific Section: Bytes 128-255 */
union {
struct {
/* 128 (Unbuffered) Module Nominal Height */
uint8_t mod_height;
/* 129 (Unbuffered) Module Maximum Thickness */
uint8_t mod_thickness;
/* 130 (Unbuffered) Reference Raw Card Used */
uint8_t ref_raw_card;
/* 131 (Unbuffered) Address Mapping from
Edge Connector to DRAM */
uint8_t addr_mapping;
/* 132~253 (Unbuffered) Reserved */
uint8_t res_132[254-132];
/* 254~255 CRC */
uint8_t crc[2];
} unbuffered;
struct {
/* 128 (Registered) Module Nominal Height */
uint8_t mod_height;
/* 129 (Registered) Module Maximum Thickness */
uint8_t mod_thickness;
/* 130 (Registered) Reference Raw Card Used */
uint8_t ref_raw_card;
/* 131 DIMM Module Attributes */
uint8_t modu_attr;
/* 132 RDIMM Thermal Heat Spreader Solution */
uint8_t thermal;
/* 133 Register Manufacturer ID Code, LSB */
uint8_t reg_id_lo;
/* 134 Register Manufacturer ID Code, MSB */
uint8_t reg_id_hi;
/* 135 Register Revision Number */
uint8_t reg_rev;
/* 136 Address mapping from register to DRAM */
uint8_t reg_map;
/* 137~253 Reserved */
uint8_t res_137[254-137];
/* 254~255 CRC */
uint8_t crc[2];
} registered;
struct {
/* 128 (Loadreduced) Module Nominal Height */
uint8_t mod_height;
/* 129 (Loadreduced) Module Maximum Thickness */
uint8_t mod_thickness;
/* 130 (Loadreduced) Reference Raw Card Used */
uint8_t ref_raw_card;
/* 131 DIMM Module Attributes */
uint8_t modu_attr;
/* 132 RDIMM Thermal Heat Spreader Solution */
uint8_t thermal;
/* 133 Register Manufacturer ID Code, LSB */
uint8_t reg_id_lo;
/* 134 Register Manufacturer ID Code, MSB */
uint8_t reg_id_hi;
/* 135 Register Revision Number */
uint8_t reg_rev;
/* 136 Address mapping from register to DRAM */
uint8_t reg_map;
/* 137 Register Output Drive Strength for CMD/Add*/
uint8_t reg_drv;
/* 138 Register Output Drive Strength for CK */
uint8_t reg_drv_ck;
/* 139 Data Buffer Revision Number */
uint8_t data_buf_rev;
/* 140 DRAM VrefDQ for Package Rank 0 */
uint8_t vrefqe_r0;
/* 141 DRAM VrefDQ for Package Rank 1 */
uint8_t vrefqe_r1;
/* 142 DRAM VrefDQ for Package Rank 2 */
uint8_t vrefqe_r2;
/* 143 DRAM VrefDQ for Package Rank 3 */
uint8_t vrefqe_r3;
/* 144 Data Buffer VrefDQ for DRAM Interface */
uint8_t data_intf;
/*
* 145 Data Buffer MDQ Drive Strength and RTT
* for data rate <= 1866
*/
uint8_t data_drv_1866;
/*
* 146 Data Buffer MDQ Drive Strength and RTT
* for 1866 < data rate <= 2400
*/
uint8_t data_drv_2400;
/*
* 147 Data Buffer MDQ Drive Strength and RTT
* for 2400 < data rate <= 3200
*/
uint8_t data_drv_3200;
/* 148 DRAM Drive Strength */
uint8_t dram_drv;
/*
* 149 DRAM ODT (RTT_WR, RTT_NOM)
* for data rate <= 1866
*/
uint8_t dram_odt_1866;
/*
* 150 DRAM ODT (RTT_WR, RTT_NOM)
* for 1866 < data rate <= 2400
*/
uint8_t dram_odt_2400;
/*
* 151 DRAM ODT (RTT_WR, RTT_NOM)
* for 2400 < data rate <= 3200
*/
uint8_t dram_odt_3200;
/*
* 152 DRAM ODT (RTT_PARK)
* for data rate <= 1866
*/
uint8_t dram_odt_park_1866;
/*
* 153 DRAM ODT (RTT_PARK)
* for 1866 < data rate <= 2400
*/
uint8_t dram_odt_park_2400;
/*
* 154 DRAM ODT (RTT_PARK)
* for 2400 < data rate <= 3200
*/
uint8_t dram_odt_park_3200;
uint8_t res_155[254-155]; /* Reserved */
/* 254~255 CRC */
uint8_t crc[2];
} loadreduced;
uint8_t uc[128]; /* 128-255 Module-Specific Section */
} mod_section;
uint8_t res_256[320-256]; /* 256~319 Reserved */
/* Module supplier's data: Byte 320~383 */
uint8_t mmid_lsb; /* 320 Module MfgID Code LSB */
uint8_t mmid_msb; /* 321 Module MfgID Code MSB */
uint8_t mloc; /* 322 Mfg Location */
uint8_t mdate[2]; /* 323~324 Mfg Date */
uint8_t sernum[4]; /* 325~328 Module Serial Number */
uint8_t mpart[20]; /* 329~348 Mfg's Module Part Number */
uint8_t mrev; /* 349 Module Revision Code */
uint8_t dmid_lsb; /* 350 DRAM MfgID Code LSB */
uint8_t dmid_msb; /* 351 DRAM MfgID Code MSB */
uint8_t stepping; /* 352 DRAM stepping */
uint8_t msd[29]; /* 353~381 Mfg's Specific Data */
uint8_t res_382[2]; /* 382~383 Reserved */
uint8_t user[512-384]; /* 384~511 End User Programmable */
};
extern unsigned int ddr1_spd_check(const ddr1_spd_eeprom_t *spd);
extern void ddr1_spd_dump(const ddr1_spd_eeprom_t *spd);
extern unsigned int ddr2_spd_check(const ddr2_spd_eeprom_t *spd);
extern void ddr2_spd_dump(const ddr2_spd_eeprom_t *spd);
extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd);
unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s *spd);
/*
* Byte 2 Fundamental Memory Types.
@ -310,6 +519,7 @@ extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd);
#define SPD_MEMTYPE_DDR2_FBDIMM (0x09)
#define SPD_MEMTYPE_DDR2_FBDIMM_PROBE (0x0A)
#define SPD_MEMTYPE_DDR3 (0x0B)
#define SPD_MEMTYPE_DDR4 (0x0C)
/* DIMM Type for DDR2 SPD (according to v1.3) */
#define DDR2_SPD_DIMMTYPE_UNDEFINED (0x00)
@ -338,4 +548,18 @@ extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd);
#define DDR3_SPD_MODULETYPE_16B_SO_DIMM (0x0C)
#define DDR3_SPD_MODULETYPE_32B_SO_DIMM (0x0D)
/* DIMM Type for DDR4 SPD */
#define DDR4_SPD_MODULETYPE_MASK (0x0f)
#define DDR4_SPD_MODULETYPE_EXT (0x00)
#define DDR4_SPD_MODULETYPE_RDIMM (0x01)
#define DDR4_SPD_MODULETYPE_UDIMM (0x02)
#define DDR4_SPD_MODULETYPE_SO_DIMM (0x03)
#define DDR4_SPD_MODULETYPE_LRDIMM (0x04)
#define DDR4_SPD_MODULETYPE_MINI_RDIMM (0x05)
#define DDR4_SPD_MODULETYPE_MINI_UDIMM (0x06)
#define DDR4_SPD_MODULETYPE_72B_SO_UDIMM (0x08)
#define DDR4_SPD_MODULETYPE_72B_SO_RDIMM (0x09)
#define DDR4_SPD_MODULETYPE_16B_SO_DIMM (0x0C)
#define DDR4_SPD_MODULETYPE_32B_SO_DIMM (0x0D)
#endif /* _DDR_SPD_H_ */

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -9,6 +9,7 @@
#ifndef FSL_DDR_MAIN_H
#define FSL_DDR_MAIN_H
#include <fsl_ddrc_version.h>
#include <fsl_ddr_sdram.h>
#include <fsl_ddr_dimm_params.h>
@ -22,6 +23,10 @@
#define ddr_out32(a, v) out_be32(a, v)
#endif
#define _DDR_ADDR CONFIG_SYS_FSL_DDR_ADDR
u32 fsl_ddr_get_version(void);
#if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM)
/*
* Bind the main DDR setup driver's generic names

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008 Freescale Semiconductor, Inc.
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -13,7 +13,7 @@
#define EDC_ECC 2
#define EDC_AC_PARITY 4
/* Parameters for a DDR2 dimm computed from the SPD */
/* Parameters for a DDR dimm computed from the SPD */
typedef struct dimm_params_s {
/* DIMM organization parameters */
@ -32,7 +32,12 @@ typedef struct dimm_params_s {
unsigned int n_row_addr;
unsigned int n_col_addr;
unsigned int edc_config; /* 0 = none, 1 = parity, 2 = ECC */
#ifdef CONFIG_SYS_FSL_DDR4
unsigned int bank_addr_bits;
unsigned int bank_group_bits;
#else
unsigned int n_banks_per_sdram_device;
#endif
unsigned int burst_lengths_bitmask; /* BL=4 bit 2, BL=8 = bit 3 */
unsigned int row_density;
@ -43,19 +48,19 @@ typedef struct dimm_params_s {
/* DIMM timing parameters */
unsigned int mtb_ps; /* medium timebase ps, only for ddr3 */
unsigned int ftb_10th_ps; /* fine timebase, in 1/10 ps, only for ddr3 */
unsigned int taa_ps; /* minimum CAS latency time, only for ddr3 */
unsigned int tfaw_ps; /* four active window delay, only for ddr3 */
int mtb_ps; /* medium timebase ps */
int ftb_10th_ps; /* fine timebase, in 1/10 ps */
int taa_ps; /* minimum CAS latency time */
int tfaw_ps; /* four active window delay */
/*
* SDRAM clock periods
* The range for these are 1000-10000 so a short should be sufficient
*/
unsigned int tckmin_x_ps;
unsigned int tckmin_x_minus_1_ps;
unsigned int tckmin_x_minus_2_ps;
unsigned int tckmax_ps;
int tckmin_x_ps;
int tckmin_x_minus_1_ps;
int tckmin_x_minus_2_ps;
int tckmax_ps;
/* SPD-defined CAS latencies */
unsigned int caslat_x;
@ -65,32 +70,46 @@ typedef struct dimm_params_s {
unsigned int caslat_lowest_derated; /* Derated CAS latency */
/* basic timing parameters */
unsigned int trcd_ps;
unsigned int trp_ps;
unsigned int tras_ps;
int trcd_ps;
int trp_ps;
int tras_ps;
unsigned int twr_ps; /* maximum = 63750 ps */
unsigned int twtr_ps; /* maximum = 63750 ps */
unsigned int trfc_ps; /* max = 255 ns + 256 ns + .75 ns
#ifdef CONFIG_SYS_FSL_DDR4
int trfc1_ps;
int trfc2_ps;
int trfc4_ps;
int trrds_ps;
int trrdl_ps;
int tccdl_ps;
#else
int twr_ps; /* maximum = 63750 ps */
int trfc_ps; /* max = 255 ns + 256 ns + .75 ns
= 511750 ps */
int trrd_ps; /* maximum = 63750 ps */
int twtr_ps; /* maximum = 63750 ps */
int trtp_ps; /* byte 38, spd->trtp */
#endif
unsigned int trrd_ps; /* maximum = 63750 ps */
unsigned int trc_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
int trc_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
unsigned int refresh_rate_ps;
unsigned int extended_op_srt;
int refresh_rate_ps;
int extended_op_srt;
/* DDR3 doesn't need these as below */
unsigned int tis_ps; /* byte 32, spd->ca_setup */
unsigned int tih_ps; /* byte 33, spd->ca_hold */
unsigned int tds_ps; /* byte 34, spd->data_setup */
unsigned int tdh_ps; /* byte 35, spd->data_hold */
unsigned int trtp_ps; /* byte 38, spd->trtp */
unsigned int tdqsq_max_ps; /* byte 44, spd->tdqsq */
unsigned int tqhs_ps; /* byte 45, spd->tqhs */
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
int tis_ps; /* byte 32, spd->ca_setup */
int tih_ps; /* byte 33, spd->ca_hold */
int tds_ps; /* byte 34, spd->data_setup */
int tdh_ps; /* byte 35, spd->data_hold */
int tdqsq_max_ps; /* byte 44, spd->tdqsq */
int tqhs_ps; /* byte 45, spd->tqhs */
#endif
/* DDR3 RDIMM */
unsigned char rcw[16]; /* Register Control Word 0-15 */
#ifdef CONFIG_SYS_FSL_DDR4
unsigned int dq_mapping[18];
unsigned int dq_mapping_ors;
#endif
} dimm_params_t;
extern unsigned int ddr_compute_dimm_parameters(

View File

@ -1,5 +1,5 @@
/*
* Copyright 2008-2011 Freescale Semiconductor, Inc.
* Copyright 2008-2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -13,11 +13,13 @@
* Pick a basic DDR Technology.
*/
#include <ddr_spd.h>
#include <fsl_ddrc_version.h>
#define SDRAM_TYPE_DDR1 2
#define SDRAM_TYPE_DDR2 3
#define SDRAM_TYPE_LPDDR1 6
#define SDRAM_TYPE_DDR3 7
#define SDRAM_TYPE_DDR1 2
#define SDRAM_TYPE_DDR2 3
#define SDRAM_TYPE_LPDDR1 6
#define SDRAM_TYPE_DDR3 7
#define SDRAM_TYPE_DDR4 5
#define DDR_BL4 4 /* burst length 4 */
#define DDR_BC4 DDR_BL4 /* burst chop for ddr3 */
@ -54,6 +56,12 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
#ifndef CONFIG_FSL_SDRAM_TYPE
#define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR3
#endif
#elif defined(CONFIG_SYS_FSL_DDR4)
#define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR (3) /* FIXME */
typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t;
#ifndef CONFIG_FSL_SDRAM_TYPE
#define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR4
#endif
#endif /* #if defined(CONFIG_SYS_FSL_DDR1) */
#define FSL_DDR_ODT_NEVER 0x0
@ -116,7 +124,8 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
#define TIMING_CFG_2_CPO_MASK 0x0F800000
#if defined(CONFIG_P4080)
#if defined(CONFIG_SYS_FSL_DDR_VER) && \
(CONFIG_SYS_FSL_DDR_VER > FSL_DDR_VER_4_4)
#define RD_TO_PRE_MASK 0xf
#define RD_TO_PRE_SHIFT 13
#define WR_DATA_DELAY_MASK 0xf
@ -154,9 +163,27 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
#define DDR_CDR2_ODT_MASK 0x1
#define DDR_CDR1_ODT(x) ((x & DDR_CDR1_ODT_MASK) << DDR_CDR1_ODT_SHIFT)
#define DDR_CDR2_ODT(x) (x & DDR_CDR2_ODT_MASK)
#define DDR_CDR2_VREF_OVRD(x) (0x00008080 | ((((x) - 37) & 0x3F) << 8))
#if (defined(CONFIG_SYS_FSL_DDR_VER) && \
(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7))
#ifdef CONFIG_SYS_FSL_DDR3L
#define DDR_CDR_ODT_OFF 0x0
#define DDR_CDR_ODT_120ohm 0x1
#define DDR_CDR_ODT_200ohm 0x2
#define DDR_CDR_ODT_75ohm 0x3
#define DDR_CDR_ODT_60ohm 0x5
#define DDR_CDR_ODT_46ohm 0x7
#elif defined(CONFIG_SYS_FSL_DDR4)
#define DDR_CDR_ODT_OFF 0x0
#define DDR_CDR_ODT_100ohm 0x1
#define DDR_CDR_ODT_120OHM 0x2
#define DDR_CDR_ODT_80ohm 0x3
#define DDR_CDR_ODT_60ohm 0x4
#define DDR_CDR_ODT_40ohm 0x5
#define DDR_CDR_ODT_50ohm 0x6
#define DDR_CDR_ODT_30ohm 0x7
#else
#define DDR_CDR_ODT_OFF 0x0
#define DDR_CDR_ODT_120ohm 0x1
#define DDR_CDR_ODT_180ohm 0x2
@ -165,6 +192,7 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
#define DDR_CDR_ODT_60hm 0x5
#define DDR_CDR_ODT_70ohm 0x6
#define DDR_CDR_ODT_47ohm 0x7
#endif /* DDR3L */
#else
#define DDR_CDR_ODT_75ohm 0x0
#define DDR_CDR_ODT_55ohm 0x1
@ -188,6 +216,7 @@ typedef struct fsl_ddr_cfg_regs_s {
unsigned int timing_cfg_2;
unsigned int ddr_sdram_cfg;
unsigned int ddr_sdram_cfg_2;
unsigned int ddr_sdram_cfg_3;
unsigned int ddr_sdram_mode;
unsigned int ddr_sdram_mode_2;
unsigned int ddr_sdram_mode_3;
@ -196,6 +225,14 @@ typedef struct fsl_ddr_cfg_regs_s {
unsigned int ddr_sdram_mode_6;
unsigned int ddr_sdram_mode_7;
unsigned int ddr_sdram_mode_8;
unsigned int ddr_sdram_mode_9;
unsigned int ddr_sdram_mode_10;
unsigned int ddr_sdram_mode_11;
unsigned int ddr_sdram_mode_12;
unsigned int ddr_sdram_mode_13;
unsigned int ddr_sdram_mode_14;
unsigned int ddr_sdram_mode_15;
unsigned int ddr_sdram_mode_16;
unsigned int ddr_sdram_md_cntl;
unsigned int ddr_sdram_interval;
unsigned int ddr_data_init;
@ -204,6 +241,10 @@ typedef struct fsl_ddr_cfg_regs_s {
unsigned int ddr_init_ext_addr;
unsigned int timing_cfg_4;
unsigned int timing_cfg_5;
unsigned int timing_cfg_6;
unsigned int timing_cfg_7;
unsigned int timing_cfg_8;
unsigned int timing_cfg_9;
unsigned int ddr_zq_cntl;
unsigned int ddr_wrlvl_cntl;
unsigned int ddr_wrlvl_cntl_2;
@ -211,6 +252,14 @@ typedef struct fsl_ddr_cfg_regs_s {
unsigned int ddr_sr_cntr;
unsigned int ddr_sdram_rcw_1;
unsigned int ddr_sdram_rcw_2;
unsigned int ddr_sdram_rcw_3;
unsigned int ddr_sdram_rcw_4;
unsigned int ddr_sdram_rcw_5;
unsigned int ddr_sdram_rcw_6;
unsigned int dq_map_0;
unsigned int dq_map_1;
unsigned int dq_map_2;
unsigned int dq_map_3;
unsigned int ddr_eor;
unsigned int ddr_cdr1;
unsigned int ddr_cdr2;
@ -225,7 +274,7 @@ typedef struct memctl_options_partial_s {
unsigned int all_dimms_burst_lengths_bitmask;
unsigned int all_dimms_registered;
unsigned int all_dimms_unbuffered;
/* unsigned int lowest_common_SPD_caslat; */
/* unsigned int lowest_common_spd_caslat; */
unsigned int all_dimms_minimum_trcd_ps;
} memctl_options_partial_t;

View File

@ -0,0 +1,18 @@
/*
* Copyright 2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __FSL_DDRC_VER_H
#define __FSL_DDRC_VER_H
/*
* Only the versions with distinct features or registers are listed here.
*/
#define FSL_DDR_VER_4_4 44
#define FSL_DDR_VER_4_6 46
#define FSL_DDR_VER_4_7 47
#define FSL_DDR_VER_5_0 50
#endif /* __FSL_DDRC_VER_H */

View File

@ -1,7 +1,7 @@
/*
* Common internal memory map for some Freescale SoCs
*
* Copyright 2013 Freescale Semiconductor, Inc.
* Copyright 2013-2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@ -50,7 +50,8 @@ struct ccsr_ddr {
u8 res_150[16];
u32 timing_cfg_4; /* SDRAM Timing Configuration 4 */
u32 timing_cfg_5; /* SDRAM Timing Configuration 5 */
u8 reg_168[8];
u32 timing_cfg_6; /* SDRAM Timing Configuration 6 */
u32 timing_cfg_7; /* SDRAM Timing Configuration 7 */
u32 ddr_zq_cntl; /* ZQ calibration control*/
u32 ddr_wrlvl_cntl; /* write leveling control*/
u8 reg_178[4];
@ -60,14 +61,40 @@ struct ccsr_ddr {
u8 reg_188[8];
u32 ddr_wrlvl_cntl_2; /* write leveling control 2 */
u32 ddr_wrlvl_cntl_3; /* write leveling control 3 */
u8 res_198[104];
u8 res_198[0x1a0-0x198];
u32 ddr_sdram_rcw_3;
u32 ddr_sdram_rcw_4;
u32 ddr_sdram_rcw_5;
u32 ddr_sdram_rcw_6;
u8 res_1b0[0x200-0x1b0];
u32 sdram_mode_3; /* SDRAM Mode Configuration 3 */
u32 sdram_mode_4; /* SDRAM Mode Configuration 4 */
u32 sdram_mode_5; /* SDRAM Mode Configuration 5 */
u32 sdram_mode_6; /* SDRAM Mode Configuration 6 */
u32 sdram_mode_7; /* SDRAM Mode Configuration 7 */
u32 sdram_mode_8; /* SDRAM Mode Configuration 8 */
u8 res_218[0x908];
u8 res_218[0x220-0x218];
u32 sdram_mode_9; /* SDRAM Mode Configuration 9 */
u32 sdram_mode_10; /* SDRAM Mode Configuration 10 */
u32 sdram_mode_11; /* SDRAM Mode Configuration 11 */
u32 sdram_mode_12; /* SDRAM Mode Configuration 12 */
u32 sdram_mode_13; /* SDRAM Mode Configuration 13 */
u32 sdram_mode_14; /* SDRAM Mode Configuration 14 */
u32 sdram_mode_15; /* SDRAM Mode Configuration 15 */
u32 sdram_mode_16; /* SDRAM Mode Configuration 16 */
u8 res_240[0x250-0x240];
u32 timing_cfg_8; /* SDRAM Timing Configuration 8 */
u32 timing_cfg_9; /* SDRAM Timing Configuration 9 */
u8 res_258[0x260-0x258];
u32 sdram_cfg_3;
u8 res_264[0x2a0-0x264];
u32 deskew_cntl;
u8 res_2a4[0x400-0x2a4];
u32 dq_map_0;
u32 dq_map_1;
u32 dq_map_2;
u32 dq_map_3;
u8 res_410[0xb20-0x410];
u32 ddr_dsr1; /* Debug Status 1 */
u32 ddr_dsr2; /* Debug Status 2 */
u32 ddr_cdr1; /* Control Driver 1 */