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>
master
York Sun 10 years ago
parent 8d451a7129
commit 34e026f9b1
  1. 13
      README
  2. 17
      arch/powerpc/include/asm/config_mpc85xx.h
  3. 45
      common/ddr_spd.c
  4. 19
      drivers/ddr/fsl/Makefile
  5. 739
      drivers/ddr/fsl/ctrl_regs.c
  6. 300
      drivers/ddr/fsl/ddr4_dimm_params.c
  7. 234
      drivers/ddr/fsl/fsl_ddr_gen4.c
  8. 391
      drivers/ddr/fsl/interactive.c
  9. 407
      drivers/ddr/fsl/lc_common_dimm_params.c
  10. 25
      drivers/ddr/fsl/main.c
  11. 34
      drivers/ddr/fsl/options.c
  12. 26
      drivers/ddr/fsl/util.c
  13. 23
      include/common_timing_params.h
  14. 226
      include/ddr_spd.h
  15. 7
      include/fsl_ddr.h
  16. 77
      include/fsl_ddr_dimm_params.h
  17. 63
      include/fsl_ddr_sdram.h
  18. 18
      include/fsl_ddrc_version.h
  19. 35
      include/fsl_immap.h

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

@ -19,8 +19,8 @@
*/ */
#define CONFIG_PPC_SPINTABLE_COMPATIBLE #define CONFIG_PPC_SPINTABLE_COMPATIBLE
#define FSL_DDR_VER_4_7 47 #include <fsl_ddrc_version.h>
#define FSL_DDR_VER_5_0 50 #define CONFIG_SYS_FSL_DDR_BE
/* IP endianness */ /* IP endianness */
#define CONFIG_SYS_FSL_IFC_BE #define CONFIG_SYS_FSL_IFC_BE
@ -401,6 +401,7 @@
#define CONFIG_SYS_NUM_FM1_DTSEC 5 #define CONFIG_SYS_NUM_FM1_DTSEC 5
#define CONFIG_SYS_NUM_FM1_10GEC 1 #define CONFIG_SYS_NUM_FM1_10GEC 1
#define CONFIG_NUM_DDR_CONTROLLERS 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_FM_MURAM_SIZE 0x28000
#define CONFIG_SYS_FSL_TBCLK_DIV 32 #define CONFIG_SYS_FSL_TBCLK_DIV 32
#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" #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_FM1_10GEC 1
#define CONFIG_SYS_NUM_FM2_10GEC 1 #define CONFIG_SYS_NUM_FM2_10GEC 1
#define CONFIG_NUM_DDR_CONTROLLERS 2 #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_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 #define CONFIG_SYS_FM_MURAM_SIZE 0x28000
#define CONFIG_SYS_FSL_TBCLK_DIV 16 #define CONFIG_SYS_FSL_TBCLK_DIV 16
@ -490,6 +492,7 @@
#define CONFIG_SYS_NUM_FM1_DTSEC 5 #define CONFIG_SYS_NUM_FM1_DTSEC 5
#define CONFIG_SYS_NUM_FM1_10GEC 1 #define CONFIG_SYS_NUM_FM1_10GEC 1
#define CONFIG_NUM_DDR_CONTROLLERS 2 #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_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 #define CONFIG_SYS_FM_MURAM_SIZE 0x28000
#define CONFIG_SYS_FSL_TBCLK_DIV 32 #define CONFIG_SYS_FSL_TBCLK_DIV 32
@ -527,6 +530,7 @@
#define CONFIG_SYS_NUM_FM2_DTSEC 5 #define CONFIG_SYS_NUM_FM2_DTSEC 5
#define CONFIG_SYS_NUM_FM2_10GEC 1 #define CONFIG_SYS_NUM_FM2_10GEC 1
#define CONFIG_NUM_DDR_CONTROLLERS 2 #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_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 #define CONFIG_SYS_FM_MURAM_SIZE 0x28000
#define CONFIG_SYS_FSL_TBCLK_DIV 16 #define CONFIG_SYS_FSL_TBCLK_DIV 16
@ -553,6 +557,7 @@
#define CONFIG_TSECV2 #define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 4 #define CONFIG_SYS_FSL_SEC_COMPAT 4
#define CONFIG_NUM_DDR_CONTROLLERS 1 #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_USB_MAX_CONTROLLER_COUNT 1
#define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR 0xb0000000 #define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR 0xb0000000
#define CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT 0xff600000 #define CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT 0xff600000
@ -571,6 +576,7 @@
#define CONFIG_TSECV2 #define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 4 #define CONFIG_SYS_FSL_SEC_COMPAT 4
#define CONFIG_NUM_DDR_CONTROLLERS 2 #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_USB_MAX_CONTROLLER_COUNT 1
#define CONFIG_SYS_FSL_DSP_DDR_ADDR 0x40000000 #define CONFIG_SYS_FSL_DSP_DDR_ADDR 0x40000000
#define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR 0xb0000000 #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_QORIQ_CHASSIS2 /* Freescale Chassis generation 2 */
#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 1 #define CONFIG_SYS_FSL_CORES_PER_CLUSTER 1
#define CONFIG_SYS_FSL_QMAN_V3 /* QMAN version 3 */ #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) #if defined(CONFIG_PPC_T1040) || defined(CONFIG_PPC_T1042)
#define CONFIG_MAX_CPUS 4 #define CONFIG_MAX_CPUS 4
#elif defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) #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_SEC_COMPAT 6
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
#define CONFIG_NUM_DDR_CONTROLLERS 1 #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_FSL_IFC_BANK_COUNT 8
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
#define CONFIG_SYS_FSL_ERRATUM_A005125 #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) && \ #if !defined(CONFIG_SYS_FSL_DDRC_GEN1) && \
!defined(CONFIG_SYS_FSL_DDRC_GEN2) && \ !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 #define CONFIG_SYS_FSL_DDRC_GEN3
#endif #endif

@ -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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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; 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;
}

@ -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 # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
# Version 2 as published by the Free Software Foundation. # Version 2 as published by the Free Software Foundation.
# #
obj-$(CONFIG_SYS_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \ obj-$(CONFIG_SYS_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \
lc_common_dimm_params.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 ifdef CONFIG_DDR_SPD
SPD := y SPD := y
endif endif
@ -24,6 +25,7 @@ ifdef SPD
obj-$(CONFIG_SYS_FSL_DDR1) += ddr1_dimm_params.o obj-$(CONFIG_SYS_FSL_DDR1) += ddr1_dimm_params.o
obj-$(CONFIG_SYS_FSL_DDR2) += ddr2_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_DDR3) += ddr3_dimm_params.o
obj-$(CONFIG_SYS_FSL_DDR4) += ddr4_dimm_params.o
endif endif
obj-$(CONFIG_FSL_DDR_INTERACTIVE) += interactive.o 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_DDRC_GEN3) += mpc85xx_ddr_gen3.o
obj-$(CONFIG_SYS_FSL_DDR_86XX) += mpc86xx_ddr.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_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

@ -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;
}

@ -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");
}

@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2012 Freescale Semiconductor, Inc. * Copyright 2010-2014 Freescale Semiconductor, Inc.
* *
* SPDX-License-Identifier: GPL-2.0+ * 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[] = { static const struct options_string options[] = {
COMMON_TIMING(tckmin_x_ps), COMMON_TIMING(tckmin_x_ps),
COMMON_TIMING(tckmax_ps), COMMON_TIMING(tckmax_ps),
COMMON_TIMING(tckmax_max_ps), COMMON_TIMING(taamin_ps),
COMMON_TIMING(trcd_ps), COMMON_TIMING(trcd_ps),
COMMON_TIMING(trp_ps), COMMON_TIMING(trp_ps),
COMMON_TIMING(tras_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(twtr_ps),
COMMON_TIMING(trfc_ps), COMMON_TIMING(trfc_ps),
COMMON_TIMING(trrd_ps), COMMON_TIMING(trrd_ps),
COMMON_TIMING(trtp_ps),
#endif
COMMON_TIMING(twr_ps),
COMMON_TIMING(trc_ps), COMMON_TIMING(trc_ps),
COMMON_TIMING(refresh_rate_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(tis_ps),
COMMON_TIMING(tih_ps), COMMON_TIMING(tih_ps),
COMMON_TIMING(tds_ps), COMMON_TIMING(tds_ps),
COMMON_TIMING(tdh_ps), COMMON_TIMING(tdh_ps),
COMMON_TIMING(trtp_ps),
COMMON_TIMING(tdqsq_max_ps), COMMON_TIMING(tdqsq_max_ps),
COMMON_TIMING(tqhs_ps), COMMON_TIMING(tqhs_ps),
#endif
COMMON_TIMING(ndimms_present), COMMON_TIMING(ndimms_present),
COMMON_TIMING(lowest_common_SPD_caslat), COMMON_TIMING(lowest_common_spd_caslat),
COMMON_TIMING(highest_common_derated_caslat), COMMON_TIMING(highest_common_derated_caslat),
COMMON_TIMING(additive_latency), COMMON_TIMING(additive_latency),
COMMON_TIMING(all_dimms_burst_lengths_bitmask), 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_row_addr),
DIMM_PARM(n_col_addr), DIMM_PARM(n_col_addr),
DIMM_PARM(edc_config), 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), DIMM_PARM(n_banks_per_sdram_device),
#endif
DIMM_PARM(burst_lengths_bitmask), DIMM_PARM(burst_lengths_bitmask),
DIMM_PARM(row_density), 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(trcd_ps),
DIMM_PARM(trp_ps), DIMM_PARM(trp_ps),
DIMM_PARM(tras_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(twr_ps),
DIMM_PARM(twtr_ps), DIMM_PARM(twtr_ps),
DIMM_PARM(trfc_ps), DIMM_PARM(trfc_ps),
DIMM_PARM(trrd_ps), DIMM_PARM(trrd_ps),
DIMM_PARM(trtp_ps),
#endif
DIMM_PARM(trc_ps), DIMM_PARM(trc_ps),
DIMM_PARM(refresh_rate_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(tis_ps),
DIMM_PARM(tih_ps), DIMM_PARM(tih_ps),
DIMM_PARM(tds_ps), DIMM_PARM(tds_ps),
DIMM_PARM(tdh_ps), DIMM_PARM(tdh_ps),
DIMM_PARM(trtp_ps),
DIMM_PARM(tdqsq_max_ps), DIMM_PARM(tdqsq_max_ps),
DIMM_PARM(tqhs_ps), DIMM_PARM(tqhs_ps),
#endif
DIMM_PARM(rank_density), DIMM_PARM(rank_density),
DIMM_PARM(capacity), 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_row_addr),
DIMM_PARM(n_col_addr), DIMM_PARM(n_col_addr),
DIMM_PARM(edc_config), 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), DIMM_PARM(n_banks_per_sdram_device),
#endif
DIMM_PARM(tckmin_x_ps), DIMM_PARM(tckmin_x_ps),
DIMM_PARM(tckmin_x_minus_1_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(trcd_ps),
DIMM_PARM(trp_ps), DIMM_PARM(trp_ps),
DIMM_PARM(tras_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(twr_ps),
DIMM_PARM(twtr_ps), DIMM_PARM(twtr_ps),
DIMM_PARM(trfc_ps), DIMM_PARM(trfc_ps),
DIMM_PARM(trrd_ps), DIMM_PARM(trrd_ps),
DIMM_PARM(trtp_ps),
#endif
DIMM_PARM(trc_ps), DIMM_PARM(trc_ps),
DIMM_PARM(refresh_rate_ps), DIMM_PARM(refresh_rate_ps),
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
DIMM_PARM(tis_ps), DIMM_PARM(tis_ps),
DIMM_PARM(tih_ps), DIMM_PARM(tih_ps),
DIMM_PARM(tds_ps), DIMM_PARM(tds_ps),
DIMM_PARM(tdh_ps), DIMM_PARM(tdh_ps),
DIMM_PARM(trtp_ps),
DIMM_PARM(tdqsq_max_ps), DIMM_PARM(tdqsq_max_ps),
DIMM_PARM(tqhs_ps), DIMM_PARM(tqhs_ps),
#endif
}; };
static const unsigned int n_opts = ARRAY_SIZE(options); 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) const common_timing_params_t *plcd_dimm_params)
{ {
static const struct options_string options[] = { static const struct options_string options[] = {
COMMON_TIMING(tckmax_max_ps), COMMON_TIMING(taamin_ps),
COMMON_TIMING(trcd_ps), COMMON_TIMING(trcd_ps),
COMMON_TIMING(trp_ps), COMMON_TIMING(trp_ps),
COMMON_TIMING(tras_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(twtr_ps),
COMMON_TIMING(trfc_ps), COMMON_TIMING(trfc_ps),
COMMON_TIMING(trrd_ps), COMMON_TIMING(trrd_ps),
COMMON_TIMING(trtp_ps),
#endif
COMMON_TIMING(twr_ps),
COMMON_TIMING(trc_ps), COMMON_TIMING(trc_ps),
COMMON_TIMING(refresh_rate_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(tis_ps),
COMMON_TIMING(tih_ps),
COMMON_TIMING(tds_ps), COMMON_TIMING(tds_ps),
COMMON_TIMING(tdh_ps), COMMON_TIMING(tdh_ps),
COMMON_TIMING(trtp_ps),
COMMON_TIMING(tdqsq_max_ps), COMMON_TIMING(tdqsq_max_ps),
COMMON_TIMING(tqhs_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(highest_common_derated_caslat),
COMMON_TIMING(additive_latency), COMMON_TIMING(additive_latency),
COMMON_TIMING(ndimms_present), 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(tfaw_window_four_activates_ps),
CTRL_OPTIONS(trwt_override), CTRL_OPTIONS(trwt_override),
CTRL_OPTIONS(trwt), 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); 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(timing_cfg_2),
CFG_REGS(ddr_sdram_cfg), CFG_REGS(ddr_sdram_cfg),
CFG_REGS(ddr_sdram_cfg_2), CFG_REGS(ddr_sdram_cfg_2),
CFG_REGS(ddr_sdram_cfg_3),
CFG_REGS(ddr_sdram_mode), CFG_REGS(ddr_sdram_mode),
CFG_REGS(ddr_sdram_mode_2), CFG_REGS(ddr_sdram_mode_2),
CFG_REGS(ddr_sdram_mode_3), 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_6),
CFG_REGS(ddr_sdram_mode_7), CFG_REGS(ddr_sdram_mode_7),
CFG_REGS(ddr_sdram_mode_8), 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_sdram_interval),
CFG_REGS(ddr_data_init), CFG_REGS(ddr_data_init),
CFG_REGS(ddr_sdram_clk_cntl), 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(ddr_init_ext_addr),
CFG_REGS(timing_cfg_4), CFG_REGS(timing_cfg_4),
CFG_REGS(timing_cfg_5), 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_zq_cntl),
CFG_REGS(ddr_wrlvl_cntl), CFG_REGS(ddr_wrlvl_cntl),
CFG_REGS(ddr_wrlvl_cntl_2), 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_sdram_rcw_2),
CFG_REGS(ddr_cdr1), CFG_REGS(ddr_cdr1),
CFG_REGS(ddr_cdr2), 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_disable),
CFG_REGS(err_int_en), CFG_REGS(err_int_en),
CFG_REGS(ddr_eor), 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(timing_cfg_2),
CFG_REGS(ddr_sdram_cfg), CFG_REGS(ddr_sdram_cfg),
CFG_REGS(ddr_sdram_cfg_2), CFG_REGS(ddr_sdram_cfg_2),
CFG_REGS(ddr_sdram_cfg_3),
CFG_REGS(ddr_sdram_mode), CFG_REGS(ddr_sdram_mode),
CFG_REGS(ddr_sdram_mode_2), CFG_REGS(ddr_sdram_mode_2),
CFG_REGS(ddr_sdram_mode_3), 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_6),
CFG_REGS(ddr_sdram_mode_7), CFG_REGS(ddr_sdram_mode_7),
CFG_REGS(ddr_sdram_mode_8), 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_sdram_interval),
CFG_REGS(ddr_data_init), CFG_REGS(ddr_data_init),
CFG_REGS(ddr_sdram_clk_cntl), 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(ddr_init_ext_addr),
CFG_REGS(timing_cfg_4), CFG_REGS(timing_cfg_4),
CFG_REGS(timing_cfg_5), 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_zq_cntl),
CFG_REGS(ddr_wrlvl_cntl), CFG_REGS(ddr_wrlvl_cntl),
CFG_REGS(ddr_wrlvl_cntl_2), 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_sdram_rcw_2),
CFG_REGS(ddr_cdr1), CFG_REGS(ddr_cdr1),
CFG_REGS(ddr_cdr2), 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_disable),
CFG_REGS(err_int_en), CFG_REGS(err_int_en),
CFG_REGS(ddr_sdram_rcw_2), 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(tfaw_window_four_activates_ps),
CTRL_OPTIONS(trwt_override), CTRL_OPTIONS(trwt_override),
CTRL_OPTIONS(trwt), 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); static const unsigned int n_opts = ARRAY_SIZE(options);
@ -1245,6 +1352,266 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd)
} }
#endif #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) static inline void generic_spd_dump(const generic_spd_eeprom_t *spd)
{ {
#if defined(CONFIG_SYS_FSL_DDR1) #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); ddr2_spd_dump(spd);
#elif defined(CONFIG_SYS_FSL_DDR3) #elif defined(CONFIG_SYS_FSL_DDR3)
ddr3_spd_dump(spd); ddr3_spd_dump(spd);
#elif defined(CONFIG_SYS_FSL_DDR4)
ddr4_spd_dump(spd);
#endif #endif
} }

@ -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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -11,20 +11,23 @@
#include <fsl_ddr.h> #include <fsl_ddr.h>
#if defined(CONFIG_SYS_FSL_DDR3) #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
static unsigned int static unsigned int
compute_cas_latency_ddr3(const dimm_params_t *dimm_params, compute_cas_latency(const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm, common_timing_params_t *outpdimm,
unsigned int number_of_dimms) unsigned int number_of_dimms)
{ {
unsigned int i; unsigned int i;
unsigned int taamin_ps = 0;
unsigned int tckmin_x_ps = 0;
unsigned int common_caslat; unsigned int common_caslat;
unsigned int caslat_actual; unsigned int caslat_actual;
unsigned int retry = 16; unsigned int retry = 16;
unsigned int tmp; unsigned int tmp;
const unsigned int mclk_ps = get_memory_clk_period_ps(); 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 */ /* compute the common CAS latency supported between slots */
tmp = dimm_params[0].caslat_x; tmp = dimm_params[0].caslat_x;
@ -34,19 +37,20 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params,
} }
common_caslat = tmp; 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 */ /* 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 " printf("DDR clock (MCLK cycle %u ps) is faster than "
"the slowest DIMM(s) (tCKmin %u ps) can support.\n", "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 */ /* 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 */ /* check if the dimms support the CAS latency */
while (!(common_caslat & (1 << caslat_actual)) && retry > 0) { while (!(common_caslat & (1 << caslat_actual)) && retry > 0) {
caslat_actual++; caslat_actual++;
@ -54,13 +58,147 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params,
} }
/* once the caculation of caslat_actual is completed /* once the caculation of caslat_actual is completed
* we must verify that this CAS latency value does not * 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", printf("The choosen cas latency %d is too large\n",
caslat_actual); 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; 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 tckmin_x_ps = 0;
unsigned int tckmax_ps = 0xFFFFFFFF; unsigned int tckmax_ps = 0xFFFFFFFF;
unsigned int tckmax_max_ps = 0;
unsigned int trcd_ps = 0; unsigned int trcd_ps = 0;
unsigned int trp_ps = 0; unsigned int trp_ps = 0;
unsigned int tras_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 twr_ps = 0;
unsigned int twtr_ps = 0; unsigned int twtr_ps = 0;
unsigned int trfc_ps = 0; unsigned int trfc_ps = 0;
unsigned int trrd_ps = 0; unsigned int trrd_ps = 0;
unsigned int trtp_ps = 0;
#endif
unsigned int trc_ps = 0; unsigned int trc_ps = 0;
unsigned int refresh_rate_ps = 0; unsigned int refresh_rate_ps = 0;
unsigned int extended_op_srt = 1; unsigned int extended_op_srt = 1;
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
unsigned int tis_ps = 0; unsigned int tis_ps = 0;
unsigned int tih_ps = 0; unsigned int tih_ps = 0;
unsigned int tds_ps = 0; unsigned int tds_ps = 0;
unsigned int tdh_ps = 0; unsigned int tdh_ps = 0;
unsigned int trtp_ps = 0;
unsigned int tdqsq_max_ps = 0; unsigned int tdqsq_max_ps = 0;
unsigned int tqhs_ps = 0; unsigned int tqhs_ps = 0;
#endif
unsigned int temp1, temp2; unsigned int temp1, temp2;
unsigned int additive_latency = 0; 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; temp1 = 0;
for (i = 0; i < number_of_dimms; i++) { 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. * i.e., this is the slowest the whole system can go.
*/ */
tckmax_ps = min(tckmax_ps, dimm_params[i].tckmax_ps); tckmax_ps = min(tckmax_ps, dimm_params[i].tckmax_ps);
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
/* Either find maximum value to determine slowest taamin_ps = max(taamin_ps, dimm_params[i].taa_ps);
* speed, delay, time, period, etc */ #endif
tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps); 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); trcd_ps = max(trcd_ps, dimm_params[i].trcd_ps);
trp_ps = max(trp_ps, dimm_params[i].trp_ps); trp_ps = max(trp_ps, dimm_params[i].trp_ps);
tras_ps = max(tras_ps, dimm_params[i].tras_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); twr_ps = max(twr_ps, dimm_params[i].twr_ps);
twtr_ps = max(twtr_ps, dimm_params[i].twtr_ps); twtr_ps = max(twtr_ps, dimm_params[i].twtr_ps);
trfc_ps = max(trfc_ps, dimm_params[i].trfc_ps); trfc_ps = max(trfc_ps, dimm_params[i].trfc_ps);
trrd_ps = max(trrd_ps, dimm_params[i].trrd_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); 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); tis_ps = max(tis_ps, dimm_params[i].tis_ps);
tih_ps = max(tih_ps, dimm_params[i].tih_ps); tih_ps = max(tih_ps, dimm_params[i].tih_ps);
tds_ps = max(tds_ps, dimm_params[i].tds_ps); tds_ps = max(tds_ps, dimm_params[i].tds_ps);
tdh_ps = max(tdh_ps, dimm_params[i].tdh_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); 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. * 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? * strategy for this parameter?
*/ */
tdqsq_max_ps = max(tdqsq_max_ps, dimm_params[i].tdqsq_max_ps); 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; 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->tckmin_x_ps = tckmin_x_ps;
outpdimm->tckmax_ps = tckmax_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->trcd_ps = trcd_ps;
outpdimm->trp_ps = trp_ps; outpdimm->trp_ps = trp_ps;
outpdimm->tras_ps = tras_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->twtr_ps = twtr_ps;
outpdimm->trfc_ps = trfc_ps; outpdimm->trfc_ps = trfc_ps;
outpdimm->trrd_ps = trrd_ps; outpdimm->trrd_ps = trrd_ps;
outpdimm->trtp_ps = trtp_ps;
#endif
outpdimm->twr_ps = twr_ps;
outpdimm->trc_ps = trc_ps; outpdimm->trc_ps = trc_ps;
outpdimm->refresh_rate_ps = refresh_rate_ps; outpdimm->refresh_rate_ps = refresh_rate_ps;
outpdimm->extended_op_srt = extended_op_srt; outpdimm->extended_op_srt = extended_op_srt;
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
outpdimm->tis_ps = tis_ps; outpdimm->tis_ps = tis_ps;
outpdimm->tih_ps = tih_ps; outpdimm->tih_ps = tih_ps;
outpdimm->tds_ps = tds_ps; outpdimm->tds_ps = tds_ps;
outpdimm->tdh_ps = tdh_ps; outpdimm->tdh_ps = tdh_ps;
outpdimm->trtp_ps = trtp_ps;
outpdimm->tdqsq_max_ps = tdqsq_max_ps; outpdimm->tdqsq_max_ps = tdqsq_max_ps;
outpdimm->tqhs_ps = tqhs_ps; outpdimm->tqhs_ps = tqhs_ps;
#endif
/* Determine common burst length for all DIMMs. */ /* Determine common burst length for all DIMMs. */
temp1 = 0xff; temp1 = 0xff;
@ -265,128 +431,9 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
if (temp1 != 0) if (temp1 != 0)
printf("ERROR: Mix different RDIMM detected!\n"); printf("ERROR: Mix different RDIMM detected!\n");
#if defined(CONFIG_SYS_FSL_DDR3) /* calculate cas latency for all DDR types */
if (compute_cas_latency_ddr3(dimm_params, outpdimm, number_of_dimms)) if (compute_cas_latency(dimm_params, outpdimm, number_of_dimms))
return 1; 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. */ /* Determine if all DIMMs ECC capable. */
temp1 = 1; temp1 = 1;
@ -404,14 +451,6 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
} }
outpdimm->all_dimms_ecc_capable = temp1; 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. * Compute additive latency.
* *
@ -468,27 +507,20 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
additive_latency = 0; additive_latency = 0;
#if defined(CONFIG_SYS_FSL_DDR2) #if defined(CONFIG_SYS_FSL_DDR2)
if (lowest_good_caslat < 4) { if ((outpdimm->lowest_common_spd_caslat < 4) &&
additive_latency = (picos_to_mclk(trcd_ps) > lowest_good_caslat) (picos_to_mclk(trcd_ps) > outpdimm->lowest_common_spd_caslat)) {
? picos_to_mclk(trcd_ps) - lowest_good_caslat : 0; additive_latency = picos_to_mclk(trcd_ps) -
outpdimm->lowest_common_spd_caslat;
if (mclk_to_picos(additive_latency) > trcd_ps) { if (mclk_to_picos(additive_latency) > trcd_ps) {
additive_latency = picos_to_mclk(trcd_ps); additive_latency = picos_to_mclk(trcd_ps);
debug("setting additive_latency to %u because it was " debug("setting additive_latency to %u because it was "
" greater than tRCD_ps\n", additive_latency); " 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 #endif
/* /*
* Validate additive latency * Validate additive latency
* FIXME: move to somewhere else to validate
* *
* AL <= tRCD(min) * 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("trcd_ps = %u\n", outpdimm->trcd_ps);
debug("trp_ps = %u\n", outpdimm->trp_ps); debug("trp_ps = %u\n", outpdimm->trp_ps);
debug("tras_ps = %u\n", outpdimm->tras_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("twtr_ps = %u\n", outpdimm->twtr_ps);
debug("trfc_ps = %u\n", outpdimm->trfc_ps); debug("trfc_ps = %u\n", outpdimm->trfc_ps);
debug("trrd_ps = %u\n", outpdimm->trrd_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); debug("trc_ps = %u\n", outpdimm->trc_ps);
return 0; return 0;

@ -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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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 #endif
#define SPD_SPA0_ADDRESS 0x36
#define SPD_SPA1_ADDRESS 0x37
static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
{ {
int ret; int ret;
#ifdef CONFIG_SYS_FSL_DDR4
uint8_t dummy = 0;
#endif
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM); 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, ret = i2c_read(i2c_address, 0, 1, (uchar *)spd,
sizeof(generic_spd_eeprom_t)); sizeof(generic_spd_eeprom_t));
#endif
if (ret) { if (ret) {
if (i2c_address == if (i2c_address ==

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

@ -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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -23,6 +23,18 @@
#define ULL_8FS 0xFFFFFFFFULL #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 * Round up mclk_ps to nearest 1 ps in memory controller code
* if the error is 0.5ps or more. * if the error is 0.5ps or more.
@ -175,6 +187,9 @@ void board_add_ram_info(int use_default)
case SDRAM_TYPE_DDR3: case SDRAM_TYPE_DDR3:
puts("3"); puts("3");
break; break;
case SDRAM_TYPE_DDR4:
puts("4");
break;
default: default:
puts("?"); puts("?");
break; break;
@ -188,9 +203,12 @@ void board_add_ram_info(int use_default)
puts(", 64-bit"); puts(", 64-bit");
/* Calculate CAS latency based on timing cfg values */ /* Calculate CAS latency based on timing cfg values */
cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf) + 1; cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
if ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 1) if (fsl_ddr_get_version() <= 0x40400)
cas_lat += (8 << 1); cas_lat += 1;
else
cas_lat += 2;
cas_lat += ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 3) << 4;
printf(", CL=%d", cas_lat >> 1); printf(", CL=%d", cas_lat >> 1);
if (cas_lat & 0x1) if (cas_lat & 0x1)
puts(".5"); puts(".5");

@ -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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -14,32 +14,45 @@ typedef struct {
unsigned int tckmin_x_ps; unsigned int tckmin_x_ps;
unsigned int tckmax_ps; unsigned int tckmax_ps;
unsigned int tckmax_max_ps;
unsigned int trcd_ps; unsigned int trcd_ps;
unsigned int trp_ps; unsigned int trp_ps;
unsigned int tras_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 twtr_ps; /* maximum = 63750 ps */
unsigned int trfc_ps; /* maximum = 255 ns + 256 ns + .75 ns unsigned int trfc_ps; /* maximum = 255 ns + 256 ns + .75 ns
= 511750 ps */ = 511750 ps */
unsigned int trrd_ps; /* maximum = 63750 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 trc_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
unsigned int refresh_rate_ps; unsigned int refresh_rate_ps;
unsigned int extended_op_srt; 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 tis_ps; /* byte 32, spd->ca_setup */
unsigned int tih_ps; /* byte 33, spd->ca_hold */ unsigned int tih_ps; /* byte 33, spd->ca_hold */
unsigned int tds_ps; /* byte 34, spd->data_setup */ unsigned int tds_ps; /* byte 34, spd->data_setup */
unsigned int tdh_ps; /* byte 35, spd->data_hold */ 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 tdqsq_max_ps; /* byte 44, spd->tdqsq */
unsigned int tqhs_ps; /* byte 45, spd->tqhs */ unsigned int tqhs_ps; /* byte 45, spd->tqhs */
#endif
unsigned int ndimms_present; unsigned int ndimms_present;
unsigned int lowest_common_SPD_caslat; unsigned int lowest_common_spd_caslat;
unsigned int highest_common_derated_caslat; unsigned int highest_common_derated_caslat;
unsigned int additive_latency; unsigned int additive_latency;
unsigned int all_dimms_burst_lengths_bitmask; unsigned int all_dimms_burst_lengths_bitmask;

@ -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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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; } 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 unsigned int ddr1_spd_check(const ddr1_spd_eeprom_t *spd);
extern void ddr1_spd_dump(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 unsigned int ddr2_spd_check(const ddr2_spd_eeprom_t *spd);
extern void ddr2_spd_dump(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); 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. * 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 (0x09)
#define SPD_MEMTYPE_DDR2_FBDIMM_PROBE (0x0A) #define SPD_MEMTYPE_DDR2_FBDIMM_PROBE (0x0A)
#define SPD_MEMTYPE_DDR3 (0x0B) #define SPD_MEMTYPE_DDR3 (0x0B)
#define SPD_MEMTYPE_DDR4 (0x0C)
/* DIMM Type for DDR2 SPD (according to v1.3) */ /* DIMM Type for DDR2 SPD (according to v1.3) */
#define DDR2_SPD_DIMMTYPE_UNDEFINED (0x00) #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_16B_SO_DIMM (0x0C)
#define DDR3_SPD_MODULETYPE_32B_SO_DIMM (0x0D) #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_ */ #endif /* _DDR_SPD_H_ */

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

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

@ -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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -13,11 +13,13 @@
* Pick a basic DDR Technology. * Pick a basic DDR Technology.
*/ */
#include <ddr_spd.h> #include <ddr_spd.h>
#include <fsl_ddrc_version.h>
#define SDRAM_TYPE_DDR1 2 #define SDRAM_TYPE_DDR1 2
#define SDRAM_TYPE_DDR2 3 #define SDRAM_TYPE_DDR2 3
#define SDRAM_TYPE_LPDDR1 6 #define SDRAM_TYPE_LPDDR1 6
#define SDRAM_TYPE_DDR3 7 #define SDRAM_TYPE_DDR3 7
#define SDRAM_TYPE_DDR4 5
#define DDR_BL4 4 /* burst length 4 */ #define DDR_BL4 4 /* burst length 4 */
#define DDR_BC4 DDR_BL4 /* burst chop for ddr3 */ #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 #ifndef CONFIG_FSL_SDRAM_TYPE
#define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR3 #define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR3
#endif #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) */ #endif /* #if defined(CONFIG_SYS_FSL_DDR1) */
#define FSL_DDR_ODT_NEVER 0x0 #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 #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_MASK 0xf
#define RD_TO_PRE_SHIFT 13 #define RD_TO_PRE_SHIFT 13
#define WR_DATA_DELAY_MASK 0xf #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_CDR2_ODT_MASK 0x1
#define DDR_CDR1_ODT(x) ((x & DDR_CDR1_ODT_MASK) << DDR_CDR1_ODT_SHIFT) #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_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) && \ #if (defined(CONFIG_SYS_FSL_DDR_VER) && \
(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)) (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_OFF 0x0
#define DDR_CDR_ODT_120ohm 0x1 #define DDR_CDR_ODT_120ohm 0x1
#define DDR_CDR_ODT_180ohm 0x2 #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_60hm 0x5
#define DDR_CDR_ODT_70ohm 0x6 #define DDR_CDR_ODT_70ohm 0x6
#define DDR_CDR_ODT_47ohm 0x7 #define DDR_CDR_ODT_47ohm 0x7
#endif /* DDR3L */
#else #else
#define DDR_CDR_ODT_75ohm 0x0 #define DDR_CDR_ODT_75ohm 0x0
#define DDR_CDR_ODT_55ohm 0x1 #define DDR_CDR_ODT_55ohm 0x1
@ -188,6 +216,7 @@ typedef struct fsl_ddr_cfg_regs_s {
unsigned int timing_cfg_2; unsigned int timing_cfg_2;
unsigned int ddr_sdram_cfg; unsigned int ddr_sdram_cfg;
unsigned int ddr_sdram_cfg_2; unsigned int ddr_sdram_cfg_2;
unsigned int ddr_sdram_cfg_3;
unsigned int ddr_sdram_mode; unsigned int ddr_sdram_mode;
unsigned int ddr_sdram_mode_2; unsigned int ddr_sdram_mode_2;
unsigned int ddr_sdram_mode_3; 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_6;
unsigned int ddr_sdram_mode_7; unsigned int ddr_sdram_mode_7;
unsigned int ddr_sdram_mode_8; 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_md_cntl;
unsigned int ddr_sdram_interval; unsigned int ddr_sdram_interval;
unsigned int ddr_data_init; unsigned int ddr_data_init;
@ -204,6 +241,10 @@ typedef struct fsl_ddr_cfg_regs_s {
unsigned int ddr_init_ext_addr; unsigned int ddr_init_ext_addr;
unsigned int timing_cfg_4; unsigned int timing_cfg_4;
unsigned int timing_cfg_5; 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_zq_cntl;
unsigned int ddr_wrlvl_cntl; unsigned int ddr_wrlvl_cntl;
unsigned int ddr_wrlvl_cntl_2; 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_sr_cntr;
unsigned int ddr_sdram_rcw_1; unsigned int ddr_sdram_rcw_1;
unsigned int ddr_sdram_rcw_2; 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_eor;
unsigned int ddr_cdr1; unsigned int ddr_cdr1;
unsigned int ddr_cdr2; 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_burst_lengths_bitmask;
unsigned int all_dimms_registered; unsigned int all_dimms_registered;
unsigned int all_dimms_unbuffered; unsigned int all_dimms_unbuffered;
/* unsigned int lowest_common_SPD_caslat; */ /* unsigned int lowest_common_spd_caslat; */
unsigned int all_dimms_minimum_trcd_ps; unsigned int all_dimms_minimum_trcd_ps;
} memctl_options_partial_t; } memctl_options_partial_t;

@ -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 */

@ -1,7 +1,7 @@
/* /*
* Common internal memory map for some Freescale SoCs * 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+ * SPDX-License-Identifier: GPL-2.0+
*/ */
@ -50,7 +50,8 @@ struct ccsr_ddr {
u8 res_150[16]; u8 res_150[16];
u32 timing_cfg_4; /* SDRAM Timing Configuration 4 */ u32 timing_cfg_4; /* SDRAM Timing Configuration 4 */
u32 timing_cfg_5; /* SDRAM Timing Configuration 5 */ 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_zq_cntl; /* ZQ calibration control*/
u32 ddr_wrlvl_cntl; /* write leveling control*/ u32 ddr_wrlvl_cntl; /* write leveling control*/
u8 reg_178[4]; u8 reg_178[4];
@ -60,14 +61,40 @@ struct ccsr_ddr {
u8 reg_188[8]; u8 reg_188[8];
u32 ddr_wrlvl_cntl_2; /* write leveling control 2 */ u32 ddr_wrlvl_cntl_2; /* write leveling control 2 */
u32 ddr_wrlvl_cntl_3; /* write leveling control 3 */ 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_3; /* SDRAM Mode Configuration 3 */
u32 sdram_mode_4; /* SDRAM Mode Configuration 4 */ u32 sdram_mode_4; /* SDRAM Mode Configuration 4 */
u32 sdram_mode_5; /* SDRAM Mode Configuration 5 */ u32 sdram_mode_5; /* SDRAM Mode Configuration 5 */
u32 sdram_mode_6; /* SDRAM Mode Configuration 6 */ u32 sdram_mode_6; /* SDRAM Mode Configuration 6 */
u32 sdram_mode_7; /* SDRAM Mode Configuration 7 */ u32 sdram_mode_7; /* SDRAM Mode Configuration 7 */
u32 sdram_mode_8; /* SDRAM Mode Configuration 8 */ 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_dsr1; /* Debug Status 1 */
u32 ddr_dsr2; /* Debug Status 2 */ u32 ddr_dsr2; /* Debug Status 2 */
u32 ddr_cdr1; /* Control Driver 1 */ u32 ddr_cdr1; /* Control Driver 1 */

Loading…
Cancel
Save