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>
This commit is contained in:
parent
8d451a7129
commit
34e026f9b1
13
README
13
README
@ -458,6 +458,9 @@ The following options need to be configured:
|
||||
CONFIG_SYS_FSL_DDRC_GEN3
|
||||
Freescale DDR3 controller.
|
||||
|
||||
CONFIG_SYS_FSL_DDRC_GEN4
|
||||
Freescale DDR4 controller.
|
||||
|
||||
CONFIG_SYS_FSL_DDRC_ARM_GEN3
|
||||
Freescale DDR3 controller for ARM-based SoCs.
|
||||
|
||||
@ -473,7 +476,15 @@ The following options need to be configured:
|
||||
|
||||
CONFIG_SYS_FSL_DDR3
|
||||
Board config to use DDR3. It can be enabled for SoCs with
|
||||
Freescale DDR3 controllers.
|
||||
Freescale DDR3 or DDR3L controllers.
|
||||
|
||||
CONFIG_SYS_FSL_DDR3L
|
||||
Board config to use DDR3L. It can be enabled for SoCs with
|
||||
DDR3L controllers.
|
||||
|
||||
CONFIG_SYS_FSL_DDR4
|
||||
Board config to use DDR4. It can be enabled for SoCs with
|
||||
DDR4 controllers.
|
||||
|
||||
CONFIG_SYS_FSL_IFC_BE
|
||||
Defines the IFC controller register space as Big Endian
|
||||
|
@ -19,8 +19,8 @@
|
||||
*/
|
||||
#define CONFIG_PPC_SPINTABLE_COMPATIBLE
|
||||
|
||||
#define FSL_DDR_VER_4_7 47
|
||||
#define FSL_DDR_VER_5_0 50
|
||||
#include <fsl_ddrc_version.h>
|
||||
#define CONFIG_SYS_FSL_DDR_BE
|
||||
|
||||
/* IP endianness */
|
||||
#define CONFIG_SYS_FSL_IFC_BE
|
||||
@ -401,6 +401,7 @@
|
||||
#define CONFIG_SYS_NUM_FM1_DTSEC 5
|
||||
#define CONFIG_SYS_NUM_FM1_10GEC 1
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 1
|
||||
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_5
|
||||
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000
|
||||
#define CONFIG_SYS_FSL_TBCLK_DIV 32
|
||||
#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2"
|
||||
@ -442,6 +443,7 @@
|
||||
#define CONFIG_SYS_NUM_FM1_10GEC 1
|
||||
#define CONFIG_SYS_NUM_FM2_10GEC 1
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 2
|
||||
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_4
|
||||
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
|
||||
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000
|
||||
#define CONFIG_SYS_FSL_TBCLK_DIV 16
|
||||
@ -490,6 +492,7 @@
|
||||
#define CONFIG_SYS_NUM_FM1_DTSEC 5
|
||||
#define CONFIG_SYS_NUM_FM1_10GEC 1
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 2
|
||||
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_4
|
||||
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
|
||||
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000
|
||||
#define CONFIG_SYS_FSL_TBCLK_DIV 32
|
||||
@ -527,6 +530,7 @@
|
||||
#define CONFIG_SYS_NUM_FM2_DTSEC 5
|
||||
#define CONFIG_SYS_NUM_FM2_10GEC 1
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 2
|
||||
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_4
|
||||
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
|
||||
#define CONFIG_SYS_FM_MURAM_SIZE 0x28000
|
||||
#define CONFIG_SYS_FSL_TBCLK_DIV 16
|
||||
@ -553,6 +557,7 @@
|
||||
#define CONFIG_TSECV2
|
||||
#define CONFIG_SYS_FSL_SEC_COMPAT 4
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 1
|
||||
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_4
|
||||
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
|
||||
#define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR 0xb0000000
|
||||
#define CONFIG_SYS_FSL_DSP_CCSRBAR_DEFAULT 0xff600000
|
||||
@ -571,6 +576,7 @@
|
||||
#define CONFIG_TSECV2
|
||||
#define CONFIG_SYS_FSL_SEC_COMPAT 4
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 2
|
||||
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_6
|
||||
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
|
||||
#define CONFIG_SYS_FSL_DSP_DDR_ADDR 0x40000000
|
||||
#define CONFIG_SYS_FSL_DSP_M2_RAM_ADDR 0xb0000000
|
||||
@ -704,6 +710,9 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
|
||||
#define CONFIG_SYS_FSL_QORIQ_CHASSIS2 /* Freescale Chassis generation 2 */
|
||||
#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 1
|
||||
#define CONFIG_SYS_FSL_QMAN_V3 /* QMAN version 3 */
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
#define CONFIG_SYS_FSL_DDRC_GEN4
|
||||
#endif
|
||||
#if defined(CONFIG_PPC_T1040) || defined(CONFIG_PPC_T1042)
|
||||
#define CONFIG_MAX_CPUS 4
|
||||
#elif defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
|
||||
@ -796,6 +805,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
|
||||
#define CONFIG_SYS_FSL_SEC_COMPAT 6
|
||||
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 1
|
||||
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_6
|
||||
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 8
|
||||
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
|
||||
#define CONFIG_SYS_FSL_ERRATUM_A005125
|
||||
@ -820,7 +830,8 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
|
||||
|
||||
#if !defined(CONFIG_SYS_FSL_DDRC_GEN1) && \
|
||||
!defined(CONFIG_SYS_FSL_DDRC_GEN2) && \
|
||||
!defined(CONFIG_SYS_FSL_DDRC_GEN3)
|
||||
!defined(CONFIG_SYS_FSL_DDRC_GEN3) && \
|
||||
!defined(CONFIG_SYS_FSL_DDRC_GEN4)
|
||||
#define CONFIG_SYS_FSL_DDRC_GEN3
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -116,3 +116,46 @@ ddr3_spd_check(const ddr3_spd_eeprom_t *spd)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s *spd)
|
||||
{
|
||||
char *p = (char *)spd;
|
||||
int csum16;
|
||||
int len;
|
||||
char crc_lsb; /* byte 126 */
|
||||
char crc_msb; /* byte 127 */
|
||||
|
||||
len = 126;
|
||||
csum16 = crc16(p, len);
|
||||
|
||||
crc_lsb = (char) (csum16 & 0xff);
|
||||
crc_msb = (char) (csum16 >> 8);
|
||||
|
||||
if (spd->crc[0] != crc_lsb || spd->crc[1] != crc_msb) {
|
||||
printf("SPD checksum unexpected.\n"
|
||||
"Checksum lsb in SPD = %02X, computed SPD = %02X\n"
|
||||
"Checksum msb in SPD = %02X, computed SPD = %02X\n",
|
||||
spd->crc[0], crc_lsb, spd->crc[1], crc_msb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = (char *)((ulong)spd + 128);
|
||||
len = 126;
|
||||
csum16 = crc16(p, len);
|
||||
|
||||
crc_lsb = (char) (csum16 & 0xff);
|
||||
crc_msb = (char) (csum16 >> 8);
|
||||
|
||||
if (spd->mod_section.uc[126] != crc_lsb ||
|
||||
spd->mod_section.uc[127] != crc_msb) {
|
||||
printf("SPD checksum unexpected.\n"
|
||||
"Checksum lsb in SPD = %02X, computed SPD = %02X\n"
|
||||
"Checksum msb in SPD = %02X, computed SPD = %02X\n",
|
||||
spd->mod_section.uc[126],
|
||||
crc_lsb, spd->mod_section.uc[127],
|
||||
crc_msb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,19 +1,20 @@
|
||||
#
|
||||
# Copyright 2008-2011 Freescale Semiconductor, Inc.
|
||||
# Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# Version 2 as published by the Free Software Foundation.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_SYS_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \
|
||||
lc_common_dimm_params.o
|
||||
obj-$(CONFIG_SYS_FSL_DDR1) += main.o util.o ctrl_regs.o options.o \
|
||||
lc_common_dimm_params.o
|
||||
obj-$(CONFIG_SYS_FSL_DDR2) += main.o util.o ctrl_regs.o options.o \
|
||||
lc_common_dimm_params.o
|
||||
obj-$(CONFIG_SYS_FSL_DDR3) += main.o util.o ctrl_regs.o options.o \
|
||||
lc_common_dimm_params.o
|
||||
obj-$(CONFIG_SYS_FSL_DDR4) += main.o util.o ctrl_regs.o options.o \
|
||||
lc_common_dimm_params.o
|
||||
|
||||
obj-$(CONFIG_SYS_FSL_DDR2) += main.o util.o ctrl_regs.o options.o \
|
||||
lc_common_dimm_params.o
|
||||
|
||||
obj-$(CONFIG_SYS_FSL_DDR3) += main.o util.o ctrl_regs.o options.o \
|
||||
lc_common_dimm_params.o
|
||||
ifdef CONFIG_DDR_SPD
|
||||
SPD := y
|
||||
endif
|
||||
@ -24,6 +25,7 @@ ifdef SPD
|
||||
obj-$(CONFIG_SYS_FSL_DDR1) += ddr1_dimm_params.o
|
||||
obj-$(CONFIG_SYS_FSL_DDR2) += ddr2_dimm_params.o
|
||||
obj-$(CONFIG_SYS_FSL_DDR3) += ddr3_dimm_params.o
|
||||
obj-$(CONFIG_SYS_FSL_DDR4) += ddr4_dimm_params.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_FSL_DDR_INTERACTIVE) += interactive.o
|
||||
@ -32,3 +34,4 @@ obj-$(CONFIG_SYS_FSL_DDRC_GEN2) += mpc85xx_ddr_gen2.o
|
||||
obj-$(CONFIG_SYS_FSL_DDRC_GEN3) += mpc85xx_ddr_gen3.o
|
||||
obj-$(CONFIG_SYS_FSL_DDR_86XX) += mpc86xx_ddr.o
|
||||
obj-$(CONFIG_SYS_FSL_DDRC_ARM_GEN3) += arm_ddr_gen3.o
|
||||
obj-$(CONFIG_SYS_FSL_DDRC_GEN4) += fsl_ddr_gen4.o
|
||||
|
File diff suppressed because it is too large
Load Diff
300
drivers/ddr/fsl/ddr4_dimm_params.c
Normal file
300
drivers/ddr/fsl/ddr4_dimm_params.c
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* calculate the organization and timing parameter
|
||||
* from ddr3 spd, please refer to the spec
|
||||
* JEDEC standard No.21-C 4_01_02_12R23A.pdf
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
|
||||
#include <fsl_ddr.h>
|
||||
|
||||
/*
|
||||
* Calculate the Density of each Physical Rank.
|
||||
* Returned size is in bytes.
|
||||
*
|
||||
* Total DIMM size =
|
||||
* sdram capacity(bit) / 8 * primary bus width / sdram width
|
||||
* * Logical Ranks per DIMM
|
||||
*
|
||||
* where: sdram capacity = spd byte4[3:0]
|
||||
* primary bus width = spd byte13[2:0]
|
||||
* sdram width = spd byte12[2:0]
|
||||
* Logical Ranks per DIMM = spd byte12[5:3] for SDP, DDP, QDP
|
||||
* spd byte12{5:3] * spd byte6[6:4] for 3DS
|
||||
*
|
||||
* To simplify each rank size = total DIMM size / Number of Package Ranks
|
||||
* where Number of Package Ranks = spd byte12[5:3]
|
||||
*
|
||||
* SPD byte4 - sdram density and banks
|
||||
* bit[3:0] size(bit) size(byte)
|
||||
* 0000 256Mb 32MB
|
||||
* 0001 512Mb 64MB
|
||||
* 0010 1Gb 128MB
|
||||
* 0011 2Gb 256MB
|
||||
* 0100 4Gb 512MB
|
||||
* 0101 8Gb 1GB
|
||||
* 0110 16Gb 2GB
|
||||
* 0111 32Gb 4GB
|
||||
*
|
||||
* SPD byte13 - module memory bus width
|
||||
* bit[2:0] primary bus width
|
||||
* 000 8bits
|
||||
* 001 16bits
|
||||
* 010 32bits
|
||||
* 011 64bits
|
||||
*
|
||||
* SPD byte12 - module organization
|
||||
* bit[2:0] sdram device width
|
||||
* 000 4bits
|
||||
* 001 8bits
|
||||
* 010 16bits
|
||||
* 011 32bits
|
||||
*
|
||||
* SPD byte12 - module organization
|
||||
* bit[5:3] number of package ranks per DIMM
|
||||
* 000 1
|
||||
* 001 2
|
||||
* 010 3
|
||||
* 011 4
|
||||
*
|
||||
* SPD byte6 - SDRAM package type
|
||||
* bit[6:4] Die count
|
||||
* 000 1
|
||||
* 001 2
|
||||
* 010 3
|
||||
* 011 4
|
||||
* 100 5
|
||||
* 101 6
|
||||
* 110 7
|
||||
* 111 8
|
||||
*
|
||||
* SPD byte6 - SRAM package type
|
||||
* bit[1:0] Signal loading
|
||||
* 00 Not specified
|
||||
* 01 Multi load stack
|
||||
* 10 Sigle load stack (3DS)
|
||||
* 11 Reserved
|
||||
*/
|
||||
static unsigned long long
|
||||
compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
|
||||
{
|
||||
unsigned long long bsize;
|
||||
|
||||
int nbit_sdram_cap_bsize = 0;
|
||||
int nbit_primary_bus_width = 0;
|
||||
int nbit_sdram_width = 0;
|
||||
int die_count = 0;
|
||||
bool package_3ds;
|
||||
|
||||
if ((spd->density_banks & 0xf) <= 7)
|
||||
nbit_sdram_cap_bsize = (spd->density_banks & 0xf) + 28;
|
||||
if ((spd->bus_width & 0x7) < 4)
|
||||
nbit_primary_bus_width = (spd->bus_width & 0x7) + 3;
|
||||
if ((spd->organization & 0x7) < 4)
|
||||
nbit_sdram_width = (spd->organization & 0x7) + 2;
|
||||
package_3ds = (spd->package_type & 0x3) == 0x2;
|
||||
if (package_3ds)
|
||||
die_count = (spd->package_type >> 4) & 0x7;
|
||||
|
||||
bsize = 1ULL << (nbit_sdram_cap_bsize - 3 +
|
||||
nbit_primary_bus_width - nbit_sdram_width +
|
||||
die_count);
|
||||
|
||||
debug("DDR: DDR III rank density = 0x%16llx\n", bsize);
|
||||
|
||||
return bsize;
|
||||
}
|
||||
|
||||
#define spd_to_ps(mtb, ftb) \
|
||||
(mtb * pdimm->mtb_ps + (ftb * pdimm->ftb_10th_ps) / 10)
|
||||
/*
|
||||
* ddr_compute_dimm_parameters for DDR3 SPD
|
||||
*
|
||||
* Compute DIMM parameters based upon the SPD information in spd.
|
||||
* Writes the results to the dimm_params_t structure pointed by pdimm.
|
||||
*
|
||||
*/
|
||||
unsigned int
|
||||
ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd,
|
||||
dimm_params_t *pdimm,
|
||||
unsigned int dimm_number)
|
||||
{
|
||||
unsigned int retval;
|
||||
int i;
|
||||
|
||||
if (spd->mem_type) {
|
||||
if (spd->mem_type != SPD_MEMTYPE_DDR4) {
|
||||
printf("DIMM %u: is not a DDR4 SPD.\n", dimm_number);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
memset(pdimm, 0, sizeof(dimm_params_t));
|
||||
return 1;
|
||||
}
|
||||
|
||||
retval = ddr4_spd_check(spd);
|
||||
if (retval) {
|
||||
printf("DIMM %u: failed checksum\n", dimm_number);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* The part name in ASCII in the SPD EEPROM is not null terminated.
|
||||
* Guarantee null termination here by presetting all bytes to 0
|
||||
* and copying the part name in ASCII from the SPD onto it
|
||||
*/
|
||||
memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
|
||||
if ((spd->info_size_crc & 0xF) > 2)
|
||||
memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1);
|
||||
|
||||
/* DIMM organization parameters */
|
||||
pdimm->n_ranks = ((spd->organization >> 3) & 0x7) + 1;
|
||||
pdimm->rank_density = compute_ranksize(spd);
|
||||
pdimm->capacity = pdimm->n_ranks * pdimm->rank_density;
|
||||
pdimm->primary_sdram_width = 1 << (3 + (spd->bus_width & 0x7));
|
||||
if ((spd->bus_width >> 3) & 0x3)
|
||||
pdimm->ec_sdram_width = 8;
|
||||
else
|
||||
pdimm->ec_sdram_width = 0;
|
||||
pdimm->data_width = pdimm->primary_sdram_width
|
||||
+ pdimm->ec_sdram_width;
|
||||
pdimm->device_width = 1 << ((spd->organization & 0x7) + 2);
|
||||
|
||||
/* These are the types defined by the JEDEC DDR3 SPD spec */
|
||||
pdimm->mirrored_dimm = 0;
|
||||
pdimm->registered_dimm = 0;
|
||||
switch (spd->module_type & DDR3_SPD_MODULETYPE_MASK) {
|
||||
case DDR3_SPD_MODULETYPE_RDIMM:
|
||||
/* Registered/buffered DIMMs */
|
||||
pdimm->registered_dimm = 1;
|
||||
break;
|
||||
|
||||
case DDR3_SPD_MODULETYPE_UDIMM:
|
||||
case DDR3_SPD_MODULETYPE_SO_DIMM:
|
||||
/* Unbuffered DIMMs */
|
||||
if (spd->mod_section.unbuffered.addr_mapping & 0x1)
|
||||
pdimm->mirrored_dimm = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unknown module_type 0x%02X\n", spd->module_type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* SDRAM device parameters */
|
||||
pdimm->n_row_addr = ((spd->addressing >> 3) & 0x7) + 12;
|
||||
pdimm->n_col_addr = (spd->addressing & 0x7) + 9;
|
||||
pdimm->bank_addr_bits = (spd->density_banks >> 4) & 0x3;
|
||||
pdimm->bank_group_bits = (spd->density_banks >> 6) & 0x3;
|
||||
|
||||
/*
|
||||
* The SPD spec has not the ECC bit,
|
||||
* We consider the DIMM as ECC capability
|
||||
* when the extension bus exist
|
||||
*/
|
||||
if (pdimm->ec_sdram_width)
|
||||
pdimm->edc_config = 0x02;
|
||||
else
|
||||
pdimm->edc_config = 0x00;
|
||||
|
||||
/*
|
||||
* The SPD spec has not the burst length byte
|
||||
* but DDR4 spec has nature BL8 and BC4,
|
||||
* BL8 -bit3, BC4 -bit2
|
||||
*/
|
||||
pdimm->burst_lengths_bitmask = 0x0c;
|
||||
pdimm->row_density = __ilog2(pdimm->rank_density);
|
||||
|
||||
/* MTB - medium timebase
|
||||
* The MTB in the SPD spec is 125ps,
|
||||
*
|
||||
* FTB - fine timebase
|
||||
* use 1/10th of ps as our unit to avoid floating point
|
||||
* eg, 10 for 1ps, 25 for 2.5ps, 50 for 5ps
|
||||
*/
|
||||
if ((spd->timebases & 0xf) == 0x0) {
|
||||
pdimm->mtb_ps = 125;
|
||||
pdimm->ftb_10th_ps = 10;
|
||||
|
||||
} else {
|
||||
printf("Unknown Timebases\n");
|
||||
}
|
||||
|
||||
/* sdram minimum cycle time */
|
||||
pdimm->tckmin_x_ps = spd_to_ps(spd->tck_min, spd->fine_tck_min);
|
||||
|
||||
/* sdram max cycle time */
|
||||
pdimm->tckmax_ps = spd_to_ps(spd->tck_max, spd->fine_tck_max);
|
||||
|
||||
/*
|
||||
* CAS latency supported
|
||||
* bit0 - CL7
|
||||
* bit4 - CL11
|
||||
* bit8 - CL15
|
||||
* bit12- CL19
|
||||
* bit16- CL23
|
||||
*/
|
||||
pdimm->caslat_x = (spd->caslat_b1 << 7) |
|
||||
(spd->caslat_b2 << 15) |
|
||||
(spd->caslat_b3 << 23);
|
||||
|
||||
BUG_ON(spd->caslat_b4 != 0);
|
||||
|
||||
/*
|
||||
* min CAS latency time
|
||||
*/
|
||||
pdimm->taa_ps = spd_to_ps(spd->taa_min, spd->fine_taa_min);
|
||||
|
||||
/*
|
||||
* min RAS to CAS delay time
|
||||
*/
|
||||
pdimm->trcd_ps = spd_to_ps(spd->trcd_min, spd->fine_trcd_min);
|
||||
|
||||
/*
|
||||
* Min Row Precharge Delay Time
|
||||
*/
|
||||
pdimm->trp_ps = spd_to_ps(spd->trp_min, spd->fine_trp_min);
|
||||
|
||||
/* min active to precharge delay time */
|
||||
pdimm->tras_ps = (((spd->tras_trc_ext & 0xf) << 8) +
|
||||
spd->tras_min_lsb) * pdimm->mtb_ps;
|
||||
|
||||
/* min active to actice/refresh delay time */
|
||||
pdimm->trc_ps = spd_to_ps((((spd->tras_trc_ext & 0xf0) << 4) +
|
||||
spd->trc_min_lsb), spd->fine_trc_min);
|
||||
/* Min Refresh Recovery Delay Time */
|
||||
pdimm->trfc1_ps = ((spd->trfc1_min_msb << 8) | (spd->trfc1_min_lsb)) *
|
||||
pdimm->mtb_ps;
|
||||
pdimm->trfc2_ps = ((spd->trfc2_min_msb << 8) | (spd->trfc2_min_lsb)) *
|
||||
pdimm->mtb_ps;
|
||||
pdimm->trfc4_ps = ((spd->trfc4_min_msb << 8) | (spd->trfc4_min_lsb)) *
|
||||
pdimm->mtb_ps;
|
||||
/* min four active window delay time */
|
||||
pdimm->tfaw_ps = (((spd->tfaw_msb & 0xf) << 8) | spd->tfaw_min) *
|
||||
pdimm->mtb_ps;
|
||||
|
||||
/* min row active to row active delay time, different bank group */
|
||||
pdimm->trrds_ps = spd_to_ps(spd->trrds_min, spd->fine_trrds_min);
|
||||
/* min row active to row active delay time, same bank group */
|
||||
pdimm->trrdl_ps = spd_to_ps(spd->trrdl_min, spd->fine_trrdl_min);
|
||||
/* min CAS to CAS Delay Time (tCCD_Lmin), same bank group */
|
||||
pdimm->tccdl_ps = spd_to_ps(spd->tccdl_min, spd->fine_tccdl_min);
|
||||
|
||||
/*
|
||||
* Average periodic refresh interval
|
||||
* tREFI = 7.8 us at normal temperature range
|
||||
*/
|
||||
pdimm->refresh_rate_ps = 7800000;
|
||||
|
||||
for (i = 0; i < 18; i++)
|
||||
pdimm->dq_mapping[i] = spd->mapping[i];
|
||||
|
||||
pdimm->dq_mapping_ors = ((spd->mapping[0] >> 6) & 0x3) == 0 ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
234
drivers/ddr/fsl/fsl_ddr_gen4.c
Normal file
234
drivers/ddr/fsl/fsl_ddr_gen4.c
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <asm/processor.h>
|
||||
#include <fsl_ddr.h>
|
||||
|
||||
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
|
||||
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* regs has the to-be-set values for DDR controller registers
|
||||
* ctrl_num is the DDR controller number
|
||||
* step: 0 goes through the initialization in one pass
|
||||
* 1 sets registers and returns before enabling controller
|
||||
* 2 resumes from step 1 and continues to initialize
|
||||
* Dividing the initialization to two steps to deassert DDR reset signal
|
||||
* to comply with JEDEC specs for RDIMMs.
|
||||
*/
|
||||
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||
unsigned int ctrl_num, int step)
|
||||
{
|
||||
unsigned int i, bus_width;
|
||||
struct ccsr_ddr __iomem *ddr;
|
||||
u32 temp_sdram_cfg;
|
||||
u32 total_gb_size_per_controller;
|
||||
int timeout;
|
||||
|
||||
switch (ctrl_num) {
|
||||
case 0:
|
||||
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
|
||||
break;
|
||||
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
|
||||
case 1:
|
||||
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
|
||||
case 2:
|
||||
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
|
||||
case 3:
|
||||
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
|
||||
return;
|
||||
}
|
||||
|
||||
if (step == 2)
|
||||
goto step2;
|
||||
|
||||
if (regs->ddr_eor)
|
||||
ddr_out32(&ddr->eor, regs->ddr_eor);
|
||||
|
||||
ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
|
||||
|
||||
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
||||
if (i == 0) {
|
||||
ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds);
|
||||
ddr_out32(&ddr->cs0_config, regs->cs[i].config);
|
||||
ddr_out32(&ddr->cs0_config_2, regs->cs[i].config_2);
|
||||
|
||||
} else if (i == 1) {
|
||||
ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds);
|
||||
ddr_out32(&ddr->cs1_config, regs->cs[i].config);
|
||||
ddr_out32(&ddr->cs1_config_2, regs->cs[i].config_2);
|
||||
|
||||
} else if (i == 2) {
|
||||
ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds);
|
||||
ddr_out32(&ddr->cs2_config, regs->cs[i].config);
|
||||
ddr_out32(&ddr->cs2_config_2, regs->cs[i].config_2);
|
||||
|
||||
} else if (i == 3) {
|
||||
ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds);
|
||||
ddr_out32(&ddr->cs3_config, regs->cs[i].config);
|
||||
ddr_out32(&ddr->cs3_config_2, regs->cs[i].config_2);
|
||||
}
|
||||
}
|
||||
|
||||
ddr_out32(&ddr->timing_cfg_3, regs->timing_cfg_3);
|
||||
ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0);
|
||||
ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1);
|
||||
ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2);
|
||||
ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4);
|
||||
ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5);
|
||||
ddr_out32(&ddr->timing_cfg_6, regs->timing_cfg_6);
|
||||
ddr_out32(&ddr->timing_cfg_7, regs->timing_cfg_7);
|
||||
ddr_out32(&ddr->timing_cfg_8, regs->timing_cfg_8);
|
||||
ddr_out32(&ddr->timing_cfg_9, regs->timing_cfg_9);
|
||||
ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
|
||||
ddr_out32(&ddr->dq_map_0, regs->dq_map_0);
|
||||
ddr_out32(&ddr->dq_map_1, regs->dq_map_1);
|
||||
ddr_out32(&ddr->dq_map_2, regs->dq_map_2);
|
||||
ddr_out32(&ddr->dq_map_3, regs->dq_map_3);
|
||||
ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
|
||||
ddr_out32(&ddr->sdram_cfg_3, regs->ddr_sdram_cfg_3);
|
||||
ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode);
|
||||
ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
|
||||
ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
|
||||
ddr_out32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4);
|
||||
ddr_out32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5);
|
||||
ddr_out32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6);
|
||||
ddr_out32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7);
|
||||
ddr_out32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8);
|
||||
ddr_out32(&ddr->sdram_mode_9, regs->ddr_sdram_mode_9);
|
||||
ddr_out32(&ddr->sdram_mode_10, regs->ddr_sdram_mode_10);
|
||||
ddr_out32(&ddr->sdram_mode_11, regs->ddr_sdram_mode_11);
|
||||
ddr_out32(&ddr->sdram_mode_12, regs->ddr_sdram_mode_12);
|
||||
ddr_out32(&ddr->sdram_mode_13, regs->ddr_sdram_mode_13);
|
||||
ddr_out32(&ddr->sdram_mode_14, regs->ddr_sdram_mode_14);
|
||||
ddr_out32(&ddr->sdram_mode_15, regs->ddr_sdram_mode_15);
|
||||
ddr_out32(&ddr->sdram_mode_16, regs->ddr_sdram_mode_16);
|
||||
ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
|
||||
ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
|
||||
ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init);
|
||||
ddr_out32(&ddr->init_addr, regs->ddr_init_addr);
|
||||
ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
|
||||
ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
|
||||
#ifndef CONFIG_SYS_FSL_DDR_EMU
|
||||
/*
|
||||
* Skip these two registers if running on emulator
|
||||
* because emulator doesn't have skew between bytes.
|
||||
*/
|
||||
|
||||
if (regs->ddr_wrlvl_cntl_2)
|
||||
ddr_out32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2);
|
||||
if (regs->ddr_wrlvl_cntl_3)
|
||||
ddr_out32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3);
|
||||
#endif
|
||||
|
||||
ddr_out32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);
|
||||
ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
|
||||
ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
|
||||
ddr_out32(&ddr->ddr_sdram_rcw_3, regs->ddr_sdram_rcw_3);
|
||||
ddr_out32(&ddr->ddr_sdram_rcw_4, regs->ddr_sdram_rcw_4);
|
||||
ddr_out32(&ddr->ddr_sdram_rcw_5, regs->ddr_sdram_rcw_5);
|
||||
ddr_out32(&ddr->ddr_sdram_rcw_6, regs->ddr_sdram_rcw_6);
|
||||
ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
|
||||
ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2);
|
||||
ddr_out32(&ddr->err_disable, regs->err_disable);
|
||||
ddr_out32(&ddr->err_int_en, regs->err_int_en);
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (regs->debug[i]) {
|
||||
debug("Write to debug_%d as %08x\n",
|
||||
i+1, regs->debug[i]);
|
||||
ddr_out32(&ddr->debug[i], regs->debug[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For RDIMMs, JEDEC spec requires clocks to be stable before reset is
|
||||
* deasserted. Clocks start when any chip select is enabled and clock
|
||||
* control register is set. Because all DDR components are connected to
|
||||
* one reset signal, this needs to be done in two steps. Step 1 is to
|
||||
* get the clocks started. Step 2 resumes after reset signal is
|
||||
* deasserted.
|
||||
*/
|
||||
if (step == 1) {
|
||||
udelay(200);
|
||||
return;
|
||||
}
|
||||
|
||||
step2:
|
||||
/* Set, but do not enable the memory */
|
||||
temp_sdram_cfg = regs->ddr_sdram_cfg;
|
||||
temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
|
||||
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg);
|
||||
|
||||
/*
|
||||
* 500 painful micro-seconds must elapse between
|
||||
* the DDR clock setup and the DDR config enable.
|
||||
* DDR2 need 200 us, and DDR3 need 500 us from spec,
|
||||
* we choose the max, that is 500 us for all of case.
|
||||
*/
|
||||
udelay(500);
|
||||
asm volatile("sync;isync");
|
||||
|
||||
/* Let the controller go */
|
||||
temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
|
||||
ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
|
||||
asm volatile("sync;isync");
|
||||
|
||||
total_gb_size_per_controller = 0;
|
||||
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
||||
if (!(regs->cs[i].config & 0x80000000))
|
||||
continue;
|
||||
total_gb_size_per_controller += 1 << (
|
||||
((regs->cs[i].config >> 14) & 0x3) + 2 +
|
||||
((regs->cs[i].config >> 8) & 0x7) + 12 +
|
||||
((regs->cs[i].config >> 4) & 0x3) + 0 +
|
||||
((regs->cs[i].config >> 0) & 0x7) + 8 +
|
||||
3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) -
|
||||
26); /* minus 26 (count of 64M) */
|
||||
}
|
||||
if (fsl_ddr_get_intl3r() & 0x80000000) /* 3-way interleaving */
|
||||
total_gb_size_per_controller *= 3;
|
||||
else if (regs->cs[0].config & 0x20000000) /* 2-way interleaving */
|
||||
total_gb_size_per_controller <<= 1;
|
||||
/*
|
||||
* total memory / bus width = transactions needed
|
||||
* transactions needed / data rate = seconds
|
||||
* to add plenty of buffer, double the time
|
||||
* For example, 2GB on 666MT/s 64-bit bus takes about 402ms
|
||||
* Let's wait for 800ms
|
||||
*/
|
||||
bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
|
||||
>> SDRAM_CFG_DBW_SHIFT);
|
||||
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
|
||||
(get_ddr_freq(0) >> 20)) << 2;
|
||||
total_gb_size_per_controller >>= 4; /* shift down to gb size */
|
||||
debug("total %d GB\n", total_gb_size_per_controller);
|
||||
debug("Need to wait up to %d * 10ms\n", timeout);
|
||||
|
||||
/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */
|
||||
while ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
|
||||
(timeout >= 0)) {
|
||||
udelay(10000); /* throttle polling rate */
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if (timeout <= 0)
|
||||
printf("Waiting for D_INIT timeout. Memory may not work.\n");
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2012 Freescale Semiconductor, Inc.
|
||||
* Copyright 2010-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
@ -153,25 +153,38 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
|
||||
static const struct options_string options[] = {
|
||||
COMMON_TIMING(tckmin_x_ps),
|
||||
COMMON_TIMING(tckmax_ps),
|
||||
COMMON_TIMING(tckmax_max_ps),
|
||||
COMMON_TIMING(taamin_ps),
|
||||
COMMON_TIMING(trcd_ps),
|
||||
COMMON_TIMING(trp_ps),
|
||||
COMMON_TIMING(tras_ps),
|
||||
COMMON_TIMING(twr_ps),
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
COMMON_TIMING(trfc1_ps),
|
||||
COMMON_TIMING(trfc2_ps),
|
||||
COMMON_TIMING(trfc4_ps),
|
||||
COMMON_TIMING(trrds_ps),
|
||||
COMMON_TIMING(trrdl_ps),
|
||||
COMMON_TIMING(tccdl_ps),
|
||||
#else
|
||||
COMMON_TIMING(twtr_ps),
|
||||
COMMON_TIMING(trfc_ps),
|
||||
COMMON_TIMING(trrd_ps),
|
||||
COMMON_TIMING(trtp_ps),
|
||||
#endif
|
||||
COMMON_TIMING(twr_ps),
|
||||
COMMON_TIMING(trc_ps),
|
||||
COMMON_TIMING(refresh_rate_ps),
|
||||
COMMON_TIMING(extended_op_srt),
|
||||
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
COMMON_TIMING(tis_ps),
|
||||
COMMON_TIMING(tih_ps),
|
||||
COMMON_TIMING(tds_ps),
|
||||
COMMON_TIMING(tdh_ps),
|
||||
COMMON_TIMING(trtp_ps),
|
||||
COMMON_TIMING(tdqsq_max_ps),
|
||||
COMMON_TIMING(tqhs_ps),
|
||||
#endif
|
||||
COMMON_TIMING(ndimms_present),
|
||||
COMMON_TIMING(lowest_common_SPD_caslat),
|
||||
COMMON_TIMING(lowest_common_spd_caslat),
|
||||
COMMON_TIMING(highest_common_derated_caslat),
|
||||
COMMON_TIMING(additive_latency),
|
||||
COMMON_TIMING(all_dimms_burst_lengths_bitmask),
|
||||
@ -211,7 +224,12 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
|
||||
DIMM_PARM(n_row_addr),
|
||||
DIMM_PARM(n_col_addr),
|
||||
DIMM_PARM(edc_config),
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
DIMM_PARM(bank_addr_bits),
|
||||
DIMM_PARM(bank_group_bits),
|
||||
#else
|
||||
DIMM_PARM(n_banks_per_sdram_device),
|
||||
#endif
|
||||
DIMM_PARM(burst_lengths_bitmask),
|
||||
DIMM_PARM(row_density),
|
||||
|
||||
@ -229,20 +247,32 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
|
||||
DIMM_PARM(trcd_ps),
|
||||
DIMM_PARM(trp_ps),
|
||||
DIMM_PARM(tras_ps),
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
DIMM_PARM(trfc1_ps),
|
||||
DIMM_PARM(trfc2_ps),
|
||||
DIMM_PARM(trfc4_ps),
|
||||
DIMM_PARM(trrds_ps),
|
||||
DIMM_PARM(trrdl_ps),
|
||||
DIMM_PARM(tccdl_ps),
|
||||
#else
|
||||
DIMM_PARM(twr_ps),
|
||||
DIMM_PARM(twtr_ps),
|
||||
DIMM_PARM(trfc_ps),
|
||||
DIMM_PARM(trrd_ps),
|
||||
DIMM_PARM(trtp_ps),
|
||||
#endif
|
||||
DIMM_PARM(trc_ps),
|
||||
DIMM_PARM(refresh_rate_ps),
|
||||
DIMM_PARM(extended_op_srt),
|
||||
|
||||
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
DIMM_PARM(tis_ps),
|
||||
DIMM_PARM(tih_ps),
|
||||
DIMM_PARM(tds_ps),
|
||||
DIMM_PARM(tdh_ps),
|
||||
DIMM_PARM(trtp_ps),
|
||||
DIMM_PARM(tdqsq_max_ps),
|
||||
DIMM_PARM(tqhs_ps),
|
||||
#endif
|
||||
|
||||
DIMM_PARM(rank_density),
|
||||
DIMM_PARM(capacity),
|
||||
@ -270,7 +300,12 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
|
||||
DIMM_PARM(n_row_addr),
|
||||
DIMM_PARM(n_col_addr),
|
||||
DIMM_PARM(edc_config),
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
DIMM_PARM(bank_addr_bits),
|
||||
DIMM_PARM(bank_group_bits),
|
||||
#else
|
||||
DIMM_PARM(n_banks_per_sdram_device),
|
||||
#endif
|
||||
|
||||
DIMM_PARM(tckmin_x_ps),
|
||||
DIMM_PARM(tckmin_x_minus_1_ps),
|
||||
@ -286,20 +321,31 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
|
||||
DIMM_PARM(trcd_ps),
|
||||
DIMM_PARM(trp_ps),
|
||||
DIMM_PARM(tras_ps),
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
DIMM_PARM(trfc1_ps),
|
||||
DIMM_PARM(trfc2_ps),
|
||||
DIMM_PARM(trfc4_ps),
|
||||
DIMM_PARM(trrds_ps),
|
||||
DIMM_PARM(trrdl_ps),
|
||||
DIMM_PARM(tccdl_ps),
|
||||
#else
|
||||
DIMM_PARM(twr_ps),
|
||||
DIMM_PARM(twtr_ps),
|
||||
DIMM_PARM(trfc_ps),
|
||||
DIMM_PARM(trrd_ps),
|
||||
DIMM_PARM(trtp_ps),
|
||||
#endif
|
||||
DIMM_PARM(trc_ps),
|
||||
DIMM_PARM(refresh_rate_ps),
|
||||
|
||||
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
DIMM_PARM(tis_ps),
|
||||
DIMM_PARM(tih_ps),
|
||||
DIMM_PARM(tds_ps),
|
||||
DIMM_PARM(tdh_ps),
|
||||
DIMM_PARM(trtp_ps),
|
||||
DIMM_PARM(tdqsq_max_ps),
|
||||
DIMM_PARM(tqhs_ps),
|
||||
#endif
|
||||
};
|
||||
static const unsigned int n_opts = ARRAY_SIZE(options);
|
||||
|
||||
@ -326,23 +372,36 @@ static void print_lowest_common_dimm_parameters(
|
||||
const common_timing_params_t *plcd_dimm_params)
|
||||
{
|
||||
static const struct options_string options[] = {
|
||||
COMMON_TIMING(tckmax_max_ps),
|
||||
COMMON_TIMING(taamin_ps),
|
||||
COMMON_TIMING(trcd_ps),
|
||||
COMMON_TIMING(trp_ps),
|
||||
COMMON_TIMING(tras_ps),
|
||||
COMMON_TIMING(twr_ps),
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
COMMON_TIMING(trfc1_ps),
|
||||
COMMON_TIMING(trfc2_ps),
|
||||
COMMON_TIMING(trfc4_ps),
|
||||
COMMON_TIMING(trrds_ps),
|
||||
COMMON_TIMING(trrdl_ps),
|
||||
COMMON_TIMING(tccdl_ps),
|
||||
#else
|
||||
COMMON_TIMING(twtr_ps),
|
||||
COMMON_TIMING(trfc_ps),
|
||||
COMMON_TIMING(trrd_ps),
|
||||
COMMON_TIMING(trtp_ps),
|
||||
#endif
|
||||
COMMON_TIMING(twr_ps),
|
||||
COMMON_TIMING(trc_ps),
|
||||
COMMON_TIMING(refresh_rate_ps),
|
||||
COMMON_TIMING(extended_op_srt),
|
||||
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
COMMON_TIMING(tis_ps),
|
||||
COMMON_TIMING(tih_ps),
|
||||
COMMON_TIMING(tds_ps),
|
||||
COMMON_TIMING(tdh_ps),
|
||||
COMMON_TIMING(trtp_ps),
|
||||
COMMON_TIMING(tdqsq_max_ps),
|
||||
COMMON_TIMING(tqhs_ps),
|
||||
COMMON_TIMING(lowest_common_SPD_caslat),
|
||||
#endif
|
||||
COMMON_TIMING(lowest_common_spd_caslat),
|
||||
COMMON_TIMING(highest_common_derated_caslat),
|
||||
COMMON_TIMING(additive_latency),
|
||||
COMMON_TIMING(ndimms_present),
|
||||
@ -460,6 +519,9 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
|
||||
CTRL_OPTIONS(tfaw_window_four_activates_ps),
|
||||
CTRL_OPTIONS(trwt_override),
|
||||
CTRL_OPTIONS(trwt),
|
||||
CTRL_OPTIONS(rtt_override),
|
||||
CTRL_OPTIONS(rtt_override_value),
|
||||
CTRL_OPTIONS(rtt_wr_override_value),
|
||||
};
|
||||
|
||||
static const unsigned int n_opts = ARRAY_SIZE(options);
|
||||
@ -505,6 +567,7 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
|
||||
CFG_REGS(timing_cfg_2),
|
||||
CFG_REGS(ddr_sdram_cfg),
|
||||
CFG_REGS(ddr_sdram_cfg_2),
|
||||
CFG_REGS(ddr_sdram_cfg_3),
|
||||
CFG_REGS(ddr_sdram_mode),
|
||||
CFG_REGS(ddr_sdram_mode_2),
|
||||
CFG_REGS(ddr_sdram_mode_3),
|
||||
@ -513,6 +576,16 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
|
||||
CFG_REGS(ddr_sdram_mode_6),
|
||||
CFG_REGS(ddr_sdram_mode_7),
|
||||
CFG_REGS(ddr_sdram_mode_8),
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
CFG_REGS(ddr_sdram_mode_9),
|
||||
CFG_REGS(ddr_sdram_mode_10),
|
||||
CFG_REGS(ddr_sdram_mode_11),
|
||||
CFG_REGS(ddr_sdram_mode_12),
|
||||
CFG_REGS(ddr_sdram_mode_13),
|
||||
CFG_REGS(ddr_sdram_mode_14),
|
||||
CFG_REGS(ddr_sdram_mode_15),
|
||||
CFG_REGS(ddr_sdram_mode_16),
|
||||
#endif
|
||||
CFG_REGS(ddr_sdram_interval),
|
||||
CFG_REGS(ddr_data_init),
|
||||
CFG_REGS(ddr_sdram_clk_cntl),
|
||||
@ -520,6 +593,12 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
|
||||
CFG_REGS(ddr_init_ext_addr),
|
||||
CFG_REGS(timing_cfg_4),
|
||||
CFG_REGS(timing_cfg_5),
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
CFG_REGS(timing_cfg_6),
|
||||
CFG_REGS(timing_cfg_7),
|
||||
CFG_REGS(timing_cfg_8),
|
||||
CFG_REGS(timing_cfg_9),
|
||||
#endif
|
||||
CFG_REGS(ddr_zq_cntl),
|
||||
CFG_REGS(ddr_wrlvl_cntl),
|
||||
CFG_REGS(ddr_wrlvl_cntl_2),
|
||||
@ -529,6 +608,10 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
|
||||
CFG_REGS(ddr_sdram_rcw_2),
|
||||
CFG_REGS(ddr_cdr1),
|
||||
CFG_REGS(ddr_cdr2),
|
||||
CFG_REGS(dq_map_0),
|
||||
CFG_REGS(dq_map_1),
|
||||
CFG_REGS(dq_map_2),
|
||||
CFG_REGS(dq_map_3),
|
||||
CFG_REGS(err_disable),
|
||||
CFG_REGS(err_int_en),
|
||||
CFG_REGS(ddr_eor),
|
||||
@ -574,6 +657,7 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
|
||||
CFG_REGS(timing_cfg_2),
|
||||
CFG_REGS(ddr_sdram_cfg),
|
||||
CFG_REGS(ddr_sdram_cfg_2),
|
||||
CFG_REGS(ddr_sdram_cfg_3),
|
||||
CFG_REGS(ddr_sdram_mode),
|
||||
CFG_REGS(ddr_sdram_mode_2),
|
||||
CFG_REGS(ddr_sdram_mode_3),
|
||||
@ -582,6 +666,16 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
|
||||
CFG_REGS(ddr_sdram_mode_6),
|
||||
CFG_REGS(ddr_sdram_mode_7),
|
||||
CFG_REGS(ddr_sdram_mode_8),
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
CFG_REGS(ddr_sdram_mode_9),
|
||||
CFG_REGS(ddr_sdram_mode_10),
|
||||
CFG_REGS(ddr_sdram_mode_11),
|
||||
CFG_REGS(ddr_sdram_mode_12),
|
||||
CFG_REGS(ddr_sdram_mode_13),
|
||||
CFG_REGS(ddr_sdram_mode_14),
|
||||
CFG_REGS(ddr_sdram_mode_15),
|
||||
CFG_REGS(ddr_sdram_mode_16),
|
||||
#endif
|
||||
CFG_REGS(ddr_sdram_interval),
|
||||
CFG_REGS(ddr_data_init),
|
||||
CFG_REGS(ddr_sdram_clk_cntl),
|
||||
@ -589,6 +683,12 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
|
||||
CFG_REGS(ddr_init_ext_addr),
|
||||
CFG_REGS(timing_cfg_4),
|
||||
CFG_REGS(timing_cfg_5),
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
CFG_REGS(timing_cfg_6),
|
||||
CFG_REGS(timing_cfg_7),
|
||||
CFG_REGS(timing_cfg_8),
|
||||
CFG_REGS(timing_cfg_9),
|
||||
#endif
|
||||
CFG_REGS(ddr_zq_cntl),
|
||||
CFG_REGS(ddr_wrlvl_cntl),
|
||||
CFG_REGS(ddr_wrlvl_cntl_2),
|
||||
@ -598,6 +698,10 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
|
||||
CFG_REGS(ddr_sdram_rcw_2),
|
||||
CFG_REGS(ddr_cdr1),
|
||||
CFG_REGS(ddr_cdr2),
|
||||
CFG_REGS(dq_map_0),
|
||||
CFG_REGS(dq_map_1),
|
||||
CFG_REGS(dq_map_2),
|
||||
CFG_REGS(dq_map_3),
|
||||
CFG_REGS(err_disable),
|
||||
CFG_REGS(err_int_en),
|
||||
CFG_REGS(ddr_sdram_rcw_2),
|
||||
@ -705,6 +809,9 @@ static void print_memctl_options(const memctl_options_t *popts)
|
||||
CTRL_OPTIONS(tfaw_window_four_activates_ps),
|
||||
CTRL_OPTIONS(trwt_override),
|
||||
CTRL_OPTIONS(trwt),
|
||||
CTRL_OPTIONS(rtt_override),
|
||||
CTRL_OPTIONS(rtt_override_value),
|
||||
CTRL_OPTIONS(rtt_wr_override_value),
|
||||
};
|
||||
static const unsigned int n_opts = ARRAY_SIZE(options);
|
||||
|
||||
@ -1245,6 +1352,266 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
void ddr4_spd_dump(const struct ddr4_spd_eeprom_s *spd)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* General Section: Bytes 0-127 */
|
||||
|
||||
#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y);
|
||||
#define PRINT_NNXXS(n0, n1, x0, x1, s) \
|
||||
printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1);
|
||||
|
||||
PRINT_NXS(0, spd->info_size_crc,
|
||||
"info_size_crc bytes written into serial memory, CRC coverage");
|
||||
PRINT_NXS(1, spd->spd_rev,
|
||||
"spd_rev SPD Revision");
|
||||
PRINT_NXS(2, spd->mem_type,
|
||||
"mem_type Key Byte / DRAM Device Type");
|
||||
PRINT_NXS(3, spd->module_type,
|
||||
"module_type Key Byte / Module Type");
|
||||
PRINT_NXS(4, spd->density_banks,
|
||||
"density_banks SDRAM Density and Banks");
|
||||
PRINT_NXS(5, spd->addressing,
|
||||
"addressing SDRAM Addressing");
|
||||
PRINT_NXS(6, spd->package_type,
|
||||
"package_type Package type");
|
||||
PRINT_NXS(7, spd->opt_feature,
|
||||
"opt_feature Optional features");
|
||||
PRINT_NXS(8, spd->thermal_ref,
|
||||
"thermal_ref Thermal and Refresh options");
|
||||
PRINT_NXS(9, spd->oth_opt_features,
|
||||
"oth_opt_features Other SDRAM optional features");
|
||||
PRINT_NXS(10, spd->res_10,
|
||||
"res_10 Reserved");
|
||||
PRINT_NXS(11, spd->module_vdd,
|
||||
"module_vdd Module Nominal Voltage, VDD");
|
||||
PRINT_NXS(12, spd->organization,
|
||||
"organization Module Organization");
|
||||
PRINT_NXS(13, spd->bus_width,
|
||||
"bus_width Module Memory Bus Width");
|
||||
PRINT_NXS(14, spd->therm_sensor,
|
||||
"therm_sensor Module Thermal Sensor");
|
||||
PRINT_NXS(15, spd->ext_type,
|
||||
"ext_type Extended module type");
|
||||
PRINT_NXS(16, spd->res_16,
|
||||
"res_16 Reserved");
|
||||
PRINT_NXS(17, spd->timebases,
|
||||
"timebases MTb and FTB");
|
||||
PRINT_NXS(18, spd->tck_min,
|
||||
"tck_min tCKAVGmin");
|
||||
PRINT_NXS(19, spd->tck_max,
|
||||
"tck_max TCKAVGmax");
|
||||
PRINT_NXS(20, spd->caslat_b1,
|
||||
"caslat_b1 CAS latencies, 1st byte");
|
||||
PRINT_NXS(21, spd->caslat_b2,
|
||||
"caslat_b2 CAS latencies, 2nd byte");
|
||||
PRINT_NXS(22, spd->caslat_b3,
|
||||
"caslat_b3 CAS latencies, 3rd byte ");
|
||||
PRINT_NXS(23, spd->caslat_b4,
|
||||
"caslat_b4 CAS latencies, 4th byte");
|
||||
PRINT_NXS(24, spd->taa_min,
|
||||
"taa_min Min CAS Latency Time");
|
||||
PRINT_NXS(25, spd->trcd_min,
|
||||
"trcd_min Min RAS# to CAS# Delay Time");
|
||||
PRINT_NXS(26, spd->trp_min,
|
||||
"trp_min Min Row Precharge Delay Time");
|
||||
PRINT_NXS(27, spd->tras_trc_ext,
|
||||
"tras_trc_ext Upper Nibbles for tRAS and tRC");
|
||||
PRINT_NXS(28, spd->tras_min_lsb,
|
||||
"tras_min_lsb tRASmin, lsb");
|
||||
PRINT_NXS(29, spd->trc_min_lsb,
|
||||
"trc_min_lsb tRCmin, lsb");
|
||||
PRINT_NXS(30, spd->trfc1_min_lsb,
|
||||
"trfc1_min_lsb Min Refresh Recovery Delay Time, LSB");
|
||||
PRINT_NXS(31, spd->trfc1_min_msb,
|
||||
"trfc1_min_msb Min Refresh Recovery Delay Time, MSB ");
|
||||
PRINT_NXS(32, spd->trfc2_min_lsb,
|
||||
"trfc2_min_lsb Min Refresh Recovery Delay Time, LSB");
|
||||
PRINT_NXS(33, spd->trfc2_min_msb,
|
||||
"trfc2_min_msb Min Refresh Recovery Delay Time, MSB");
|
||||
PRINT_NXS(34, spd->trfc4_min_lsb,
|
||||
"trfc4_min_lsb Min Refresh Recovery Delay Time, LSB");
|
||||
PRINT_NXS(35, spd->trfc4_min_msb,
|
||||
"trfc4_min_msb Min Refresh Recovery Delay Time, MSB");
|
||||
PRINT_NXS(36, spd->tfaw_msb,
|
||||
"tfaw_msb Upper Nibble for tFAW");
|
||||
PRINT_NXS(37, spd->tfaw_min,
|
||||
"tfaw_min tFAW, lsb");
|
||||
PRINT_NXS(38, spd->trrds_min,
|
||||
"trrds_min tRRD_Smin, MTB");
|
||||
PRINT_NXS(39, spd->trrdl_min,
|
||||
"trrdl_min tRRD_Lmin, MTB");
|
||||
PRINT_NXS(40, spd->tccdl_min,
|
||||
"tccdl_min tCCS_Lmin, MTB");
|
||||
|
||||
printf("%-3d-%3d: ", 41, 59); /* Reserved, General Section */
|
||||
for (i = 41; i <= 59; i++)
|
||||
printf("%02x ", spd->res_41[i - 41]);
|
||||
|
||||
puts("\n");
|
||||
printf("%-3d-%3d: ", 60, 77);
|
||||
for (i = 60; i <= 77; i++)
|
||||
printf("%02x ", spd->mapping[i - 60]);
|
||||
puts(" mapping[] Connector to SDRAM bit map\n");
|
||||
|
||||
PRINT_NXS(117, spd->fine_tccdl_min,
|
||||
"fine_tccdl_min Fine offset for tCCD_Lmin");
|
||||
PRINT_NXS(118, spd->fine_trrdl_min,
|
||||
"fine_trrdl_min Fine offset for tRRD_Lmin");
|
||||
PRINT_NXS(119, spd->fine_trrds_min,
|
||||
"fine_trrds_min Fine offset for tRRD_Smin");
|
||||
PRINT_NXS(120, spd->fine_trc_min,
|
||||
"fine_trc_min Fine offset for tRCmin");
|
||||
PRINT_NXS(121, spd->fine_trp_min,
|
||||
"fine_trp_min Fine offset for tRPmin");
|
||||
PRINT_NXS(122, spd->fine_trcd_min,
|
||||
"fine_trcd_min Fine offset for tRCDmin");
|
||||
PRINT_NXS(123, spd->fine_taa_min,
|
||||
"fine_taa_min Fine offset for tAAmin");
|
||||
PRINT_NXS(124, spd->fine_tck_max,
|
||||
"fine_tck_max Fine offset for tCKAVGmax");
|
||||
PRINT_NXS(125, spd->fine_tck_min,
|
||||
"fine_tck_min Fine offset for tCKAVGmin");
|
||||
|
||||
/* CRC: Bytes 126-127 */
|
||||
PRINT_NNXXS(126, 127, spd->crc[0], spd->crc[1], " SPD CRC");
|
||||
|
||||
switch (spd->module_type) {
|
||||
case 0x02: /* UDIMM */
|
||||
case 0x03: /* SO-DIMM */
|
||||
PRINT_NXS(128, spd->mod_section.unbuffered.mod_height,
|
||||
"mod_height (Unbuffered) Module Nominal Height");
|
||||
PRINT_NXS(129, spd->mod_section.unbuffered.mod_thickness,
|
||||
"mod_thickness (Unbuffered) Module Maximum Thickness");
|
||||
PRINT_NXS(130, spd->mod_section.unbuffered.ref_raw_card,
|
||||
"ref_raw_card (Unbuffered) Reference Raw Card Used");
|
||||
PRINT_NXS(131, spd->mod_section.unbuffered.addr_mapping,
|
||||
"addr_mapping (Unbuffered) Address mapping from Edge Connector to DRAM");
|
||||
PRINT_NNXXS(254, 255, spd->mod_section.unbuffered.crc[0],
|
||||
spd->mod_section.unbuffered.crc[1], " Module CRC");
|
||||
break;
|
||||
case 0x01: /* RDIMM */
|
||||
PRINT_NXS(128, spd->mod_section.registered.mod_height,
|
||||
"mod_height (Registered) Module Nominal Height");
|
||||
PRINT_NXS(129, spd->mod_section.registered.mod_thickness,
|
||||
"mod_thickness (Registered) Module Maximum Thickness");
|
||||
PRINT_NXS(130, spd->mod_section.registered.ref_raw_card,
|
||||
"ref_raw_card (Registered) Reference Raw Card Used");
|
||||
PRINT_NXS(131, spd->mod_section.registered.modu_attr,
|
||||
"modu_attr (Registered) DIMM Module Attributes");
|
||||
PRINT_NXS(132, spd->mod_section.registered.thermal,
|
||||
"thermal (Registered) Thermal Heat Spreader Solution");
|
||||
PRINT_NXS(133, spd->mod_section.registered.reg_id_lo,
|
||||
"reg_id_lo (Registered) Register Manufacturer ID Code, LSB");
|
||||
PRINT_NXS(134, spd->mod_section.registered.reg_id_hi,
|
||||
"reg_id_hi (Registered) Register Manufacturer ID Code, MSB");
|
||||
PRINT_NXS(135, spd->mod_section.registered.reg_rev,
|
||||
"reg_rev (Registered) Register Revision Number");
|
||||
PRINT_NXS(136, spd->mod_section.registered.reg_map,
|
||||
"reg_map (Registered) Address mapping");
|
||||
PRINT_NNXXS(254, 255, spd->mod_section.registered.crc[0],
|
||||
spd->mod_section.registered.crc[1], " Module CRC");
|
||||
break;
|
||||
case 0x04: /* LRDIMM */
|
||||
PRINT_NXS(128, spd->mod_section.loadreduced.mod_height,
|
||||
"mod_height (Loadreduced) Module Nominal Height");
|
||||
PRINT_NXS(129, spd->mod_section.loadreduced.mod_thickness,
|
||||
"mod_thickness (Loadreduced) Module Maximum Thickness");
|
||||
PRINT_NXS(130, spd->mod_section.loadreduced.ref_raw_card,
|
||||
"ref_raw_card (Loadreduced) Reference Raw Card Used");
|
||||
PRINT_NXS(131, spd->mod_section.loadreduced.modu_attr,
|
||||
"modu_attr (Loadreduced) DIMM Module Attributes");
|
||||
PRINT_NXS(132, spd->mod_section.loadreduced.thermal,
|
||||
"thermal (Loadreduced) Thermal Heat Spreader Solution");
|
||||
PRINT_NXS(133, spd->mod_section.loadreduced.reg_id_lo,
|
||||
"reg_id_lo (Loadreduced) Register Manufacturer ID Code, LSB");
|
||||
PRINT_NXS(134, spd->mod_section.loadreduced.reg_id_hi,
|
||||
"reg_id_hi (Loadreduced) Register Manufacturer ID Code, MSB");
|
||||
PRINT_NXS(135, spd->mod_section.loadreduced.reg_rev,
|
||||
"reg_rev (Loadreduced) Register Revision Number");
|
||||
PRINT_NXS(136, spd->mod_section.loadreduced.reg_map,
|
||||
"reg_map (Loadreduced) Address mapping");
|
||||
PRINT_NXS(137, spd->mod_section.loadreduced.reg_drv,
|
||||
"reg_drv (Loadreduced) Reg output drive strength");
|
||||
PRINT_NXS(138, spd->mod_section.loadreduced.reg_drv_ck,
|
||||
"reg_drv_ck (Loadreduced) Reg output drive strength for CK");
|
||||
PRINT_NXS(139, spd->mod_section.loadreduced.data_buf_rev,
|
||||
"data_buf_rev (Loadreduced) Data Buffer Revision Numbe");
|
||||
PRINT_NXS(140, spd->mod_section.loadreduced.vrefqe_r0,
|
||||
"vrefqe_r0 (Loadreduced) DRAM VrefDQ for Package Rank 0");
|
||||
PRINT_NXS(141, spd->mod_section.loadreduced.vrefqe_r1,
|
||||
"vrefqe_r1 (Loadreduced) DRAM VrefDQ for Package Rank 1");
|
||||
PRINT_NXS(142, spd->mod_section.loadreduced.vrefqe_r2,
|
||||
"vrefqe_r2 (Loadreduced) DRAM VrefDQ for Package Rank 2");
|
||||
PRINT_NXS(143, spd->mod_section.loadreduced.vrefqe_r3,
|
||||
"vrefqe_r3 (Loadreduced) DRAM VrefDQ for Package Rank 3");
|
||||
PRINT_NXS(144, spd->mod_section.loadreduced.data_intf,
|
||||
"data_intf (Loadreduced) Data Buffer VrefDQ for DRAM Interface");
|
||||
PRINT_NXS(145, spd->mod_section.loadreduced.data_drv_1866,
|
||||
"data_drv_1866 (Loadreduced) Data Buffer MDQ Drive Strength and RTT");
|
||||
PRINT_NXS(146, spd->mod_section.loadreduced.data_drv_2400,
|
||||
"data_drv_2400 (Loadreduced) Data Buffer MDQ Drive Strength and RTT");
|
||||
PRINT_NXS(147, spd->mod_section.loadreduced.data_drv_3200,
|
||||
"data_drv_3200 (Loadreduced) Data Buffer MDQ Drive Strength and RTT");
|
||||
PRINT_NXS(148, spd->mod_section.loadreduced.dram_drv,
|
||||
"dram_drv (Loadreduced) DRAM Drive Strength");
|
||||
PRINT_NXS(149, spd->mod_section.loadreduced.dram_odt_1866,
|
||||
"dram_odt_1866 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)");
|
||||
PRINT_NXS(150, spd->mod_section.loadreduced.dram_odt_2400,
|
||||
"dram_odt_2400 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)");
|
||||
PRINT_NXS(151, spd->mod_section.loadreduced.dram_odt_3200,
|
||||
"dram_odt_3200 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)");
|
||||
PRINT_NXS(152, spd->mod_section.loadreduced.dram_odt_park_1866,
|
||||
"dram_odt_park_1866 (Loadreduced) DRAM ODT (RTT_PARK)");
|
||||
PRINT_NXS(153, spd->mod_section.loadreduced.dram_odt_park_2400,
|
||||
"dram_odt_park_2400 (Loadreduced) DRAM ODT (RTT_PARK)");
|
||||
PRINT_NXS(154, spd->mod_section.loadreduced.dram_odt_park_3200,
|
||||
"dram_odt_park_3200 (Loadreduced) DRAM ODT (RTT_PARK)");
|
||||
PRINT_NNXXS(254, 255, spd->mod_section.loadreduced.crc[0],
|
||||
spd->mod_section.loadreduced.crc[1],
|
||||
" Module CRC");
|
||||
break;
|
||||
default:
|
||||
/* Module-specific Section, Unsupported Module Type */
|
||||
printf("%-3d-%3d: ", 128, 255);
|
||||
|
||||
for (i = 128; i <= 255; i++)
|
||||
printf("%02x", spd->mod_section.uc[i - 60]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unique Module ID: Bytes 320-383 */
|
||||
PRINT_NXS(320, spd->mmid_lsb, "Module MfgID Code LSB - JEP-106");
|
||||
PRINT_NXS(321, spd->mmid_msb, "Module MfgID Code MSB - JEP-106");
|
||||
PRINT_NXS(322, spd->mloc, "Mfg Location");
|
||||
PRINT_NNXXS(323, 324, spd->mdate[0], spd->mdate[1], "Mfg Date");
|
||||
|
||||
printf("%-3d-%3d: ", 325, 328);
|
||||
|
||||
for (i = 325; i <= 328; i++)
|
||||
printf("%02x ", spd->sernum[i - 325]);
|
||||
printf(" Module Serial Number\n");
|
||||
|
||||
printf("%-3d-%3d: ", 329, 348);
|
||||
for (i = 329; i <= 348; i++)
|
||||
printf("%02x ", spd->mpart[i - 329]);
|
||||
printf(" Mfg's Module Part Number\n");
|
||||
|
||||
PRINT_NXS(349, spd->mrev, "Module Revision code");
|
||||
PRINT_NXS(350, spd->dmid_lsb, "DRAM MfgID Code LSB - JEP-106");
|
||||
PRINT_NXS(351, spd->dmid_msb, "DRAM MfgID Code MSB - JEP-106");
|
||||
PRINT_NXS(352, spd->stepping, "DRAM stepping");
|
||||
|
||||
printf("%-3d-%3d: ", 353, 381);
|
||||
for (i = 353; i <= 381; i++)
|
||||
printf("%02x ", spd->msd[i - 353]);
|
||||
printf(" Mfg's Specific Data\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void generic_spd_dump(const generic_spd_eeprom_t *spd)
|
||||
{
|
||||
#if defined(CONFIG_SYS_FSL_DDR1)
|
||||
@ -1253,6 +1620,8 @@ static inline void generic_spd_dump(const generic_spd_eeprom_t *spd)
|
||||
ddr2_spd_dump(spd);
|
||||
#elif defined(CONFIG_SYS_FSL_DDR3)
|
||||
ddr3_spd_dump(spd);
|
||||
#elif defined(CONFIG_SYS_FSL_DDR4)
|
||||
ddr4_spd_dump(spd);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2012 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -11,20 +11,23 @@
|
||||
|
||||
#include <fsl_ddr.h>
|
||||
|
||||
#if defined(CONFIG_SYS_FSL_DDR3)
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
|
||||
static unsigned int
|
||||
compute_cas_latency_ddr3(const dimm_params_t *dimm_params,
|
||||
common_timing_params_t *outpdimm,
|
||||
unsigned int number_of_dimms)
|
||||
compute_cas_latency(const dimm_params_t *dimm_params,
|
||||
common_timing_params_t *outpdimm,
|
||||
unsigned int number_of_dimms)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int taamin_ps = 0;
|
||||
unsigned int tckmin_x_ps = 0;
|
||||
unsigned int common_caslat;
|
||||
unsigned int caslat_actual;
|
||||
unsigned int retry = 16;
|
||||
unsigned int tmp;
|
||||
const unsigned int mclk_ps = get_memory_clk_period_ps();
|
||||
#ifdef CONFIG_SYS_FSL_DDR3
|
||||
const unsigned int taamax = 20000;
|
||||
#else
|
||||
const unsigned int taamax = 18000;
|
||||
#endif
|
||||
|
||||
/* compute the common CAS latency supported between slots */
|
||||
tmp = dimm_params[0].caslat_x;
|
||||
@ -34,19 +37,20 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params,
|
||||
}
|
||||
common_caslat = tmp;
|
||||
|
||||
/* compute the max tAAmin tCKmin between slots */
|
||||
for (i = 0; i < number_of_dimms; i++) {
|
||||
taamin_ps = max(taamin_ps, dimm_params[i].taa_ps);
|
||||
tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps);
|
||||
}
|
||||
/* validate if the memory clk is in the range of dimms */
|
||||
if (mclk_ps < tckmin_x_ps) {
|
||||
if (mclk_ps < outpdimm->tckmin_x_ps) {
|
||||
printf("DDR clock (MCLK cycle %u ps) is faster than "
|
||||
"the slowest DIMM(s) (tCKmin %u ps) can support.\n",
|
||||
mclk_ps, tckmin_x_ps);
|
||||
mclk_ps, outpdimm->tckmin_x_ps);
|
||||
}
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
if (mclk_ps > outpdimm->tckmax_ps) {
|
||||
printf("DDR clock (MCLK cycle %u ps) is slower than DIMM(s) (tCKmax %u ps) can support.\n",
|
||||
mclk_ps, outpdimm->tckmax_ps);
|
||||
}
|
||||
#endif
|
||||
/* determine the acutal cas latency */
|
||||
caslat_actual = (taamin_ps + mclk_ps - 1) / mclk_ps;
|
||||
caslat_actual = (outpdimm->taamin_ps + mclk_ps - 1) / mclk_ps;
|
||||
/* check if the dimms support the CAS latency */
|
||||
while (!(common_caslat & (1 << caslat_actual)) && retry > 0) {
|
||||
caslat_actual++;
|
||||
@ -54,13 +58,147 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params,
|
||||
}
|
||||
/* once the caculation of caslat_actual is completed
|
||||
* we must verify that this CAS latency value does not
|
||||
* exceed tAAmax, which is 20 ns for all DDR3 speed grades
|
||||
* exceed tAAmax, which is 20 ns for all DDR3 speed grades,
|
||||
* 18ns for all DDR4 speed grades.
|
||||
*/
|
||||
if (caslat_actual * mclk_ps > 20000) {
|
||||
if (caslat_actual * mclk_ps > taamax) {
|
||||
printf("The choosen cas latency %d is too large\n",
|
||||
caslat_actual);
|
||||
}
|
||||
outpdimm->lowest_common_SPD_caslat = caslat_actual;
|
||||
outpdimm->lowest_common_spd_caslat = caslat_actual;
|
||||
debug("lowest_common_spd_caslat is 0x%x\n", caslat_actual);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* for DDR1 and DDR2 */
|
||||
static unsigned int
|
||||
compute_cas_latency(const dimm_params_t *dimm_params,
|
||||
common_timing_params_t *outpdimm,
|
||||
unsigned int number_of_dimms)
|
||||
{
|
||||
int i;
|
||||
const unsigned int mclk_ps = get_memory_clk_period_ps();
|
||||
unsigned int lowest_good_caslat;
|
||||
unsigned int not_ok;
|
||||
unsigned int temp1, temp2;
|
||||
|
||||
debug("using mclk_ps = %u\n", mclk_ps);
|
||||
if (mclk_ps > outpdimm->tckmax_ps) {
|
||||
printf("Warning: DDR clock (%u ps) is slower than DIMM(s) (tCKmax %u ps)\n",
|
||||
mclk_ps, outpdimm->tckmax_ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute a CAS latency suitable for all DIMMs
|
||||
*
|
||||
* Strategy for SPD-defined latencies: compute only
|
||||
* CAS latency defined by all DIMMs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 1: find CAS latency common to all DIMMs using bitwise
|
||||
* operation.
|
||||
*/
|
||||
temp1 = 0xFF;
|
||||
for (i = 0; i < number_of_dimms; i++) {
|
||||
if (dimm_params[i].n_ranks) {
|
||||
temp2 = 0;
|
||||
temp2 |= 1 << dimm_params[i].caslat_x;
|
||||
temp2 |= 1 << dimm_params[i].caslat_x_minus_1;
|
||||
temp2 |= 1 << dimm_params[i].caslat_x_minus_2;
|
||||
/*
|
||||
* If there was no entry for X-2 (X-1) in
|
||||
* the SPD, then caslat_x_minus_2
|
||||
* (caslat_x_minus_1) contains either 255 or
|
||||
* 0xFFFFFFFF because that's what the glorious
|
||||
* __ilog2 function returns for an input of 0.
|
||||
* On 32-bit PowerPC, left shift counts with bit
|
||||
* 26 set (that the value of 255 or 0xFFFFFFFF
|
||||
* will have), cause the destination register to
|
||||
* be 0. That is why this works.
|
||||
*/
|
||||
temp1 &= temp2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 2: check each common CAS latency against tCK of each
|
||||
* DIMM's SPD.
|
||||
*/
|
||||
lowest_good_caslat = 0;
|
||||
temp2 = 0;
|
||||
while (temp1) {
|
||||
not_ok = 0;
|
||||
temp2 = __ilog2(temp1);
|
||||
debug("checking common caslat = %u\n", temp2);
|
||||
|
||||
/* Check if this CAS latency will work on all DIMMs at tCK. */
|
||||
for (i = 0; i < number_of_dimms; i++) {
|
||||
if (!dimm_params[i].n_ranks)
|
||||
continue;
|
||||
|
||||
if (dimm_params[i].caslat_x == temp2) {
|
||||
if (mclk_ps >= dimm_params[i].tckmin_x_ps) {
|
||||
debug("CL = %u ok on DIMM %u at tCK=%u ps with tCKmin_X_ps of %u\n",
|
||||
temp2, i, mclk_ps,
|
||||
dimm_params[i].tckmin_x_ps);
|
||||
continue;
|
||||
} else {
|
||||
not_ok++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dimm_params[i].caslat_x_minus_1 == temp2) {
|
||||
unsigned int tckmin_x_minus_1_ps
|
||||
= dimm_params[i].tckmin_x_minus_1_ps;
|
||||
if (mclk_ps >= tckmin_x_minus_1_ps) {
|
||||
debug("CL = %u ok on DIMM %u at tCK=%u ps with tckmin_x_minus_1_ps of %u\n",
|
||||
temp2, i, mclk_ps,
|
||||
tckmin_x_minus_1_ps);
|
||||
continue;
|
||||
} else {
|
||||
not_ok++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dimm_params[i].caslat_x_minus_2 == temp2) {
|
||||
unsigned int tckmin_x_minus_2_ps
|
||||
= dimm_params[i].tckmin_x_minus_2_ps;
|
||||
if (mclk_ps >= tckmin_x_minus_2_ps) {
|
||||
debug("CL = %u ok on DIMM %u at tCK=%u ps with tckmin_x_minus_2_ps of %u\n",
|
||||
temp2, i, mclk_ps,
|
||||
tckmin_x_minus_2_ps);
|
||||
continue;
|
||||
} else {
|
||||
not_ok++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!not_ok)
|
||||
lowest_good_caslat = temp2;
|
||||
|
||||
temp1 &= ~(1 << temp2);
|
||||
}
|
||||
|
||||
debug("lowest common SPD-defined CAS latency = %u\n",
|
||||
lowest_good_caslat);
|
||||
outpdimm->lowest_common_spd_caslat = lowest_good_caslat;
|
||||
|
||||
|
||||
/*
|
||||
* Compute a common 'de-rated' CAS latency.
|
||||
*
|
||||
* The strategy here is to find the *highest* dereated cas latency
|
||||
* with the assumption that all of the DIMMs will support a dereated
|
||||
* CAS latency higher than or equal to their lowest dereated value.
|
||||
*/
|
||||
temp1 = 0;
|
||||
for (i = 0; i < number_of_dimms; i++)
|
||||
temp1 = max(temp1, dimm_params[i].caslat_lowest_derated);
|
||||
|
||||
outpdimm->highest_common_derated_caslat = temp1;
|
||||
debug("highest common dereated CAS latency = %u\n", temp1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -82,34 +220,40 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
|
||||
|
||||
unsigned int tckmin_x_ps = 0;
|
||||
unsigned int tckmax_ps = 0xFFFFFFFF;
|
||||
unsigned int tckmax_max_ps = 0;
|
||||
unsigned int trcd_ps = 0;
|
||||
unsigned int trp_ps = 0;
|
||||
unsigned int tras_ps = 0;
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
|
||||
unsigned int taamin_ps = 0;
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
unsigned int twr_ps = 15000;
|
||||
unsigned int trfc1_ps = 0;
|
||||
unsigned int trfc2_ps = 0;
|
||||
unsigned int trfc4_ps = 0;
|
||||
unsigned int trrds_ps = 0;
|
||||
unsigned int trrdl_ps = 0;
|
||||
unsigned int tccdl_ps = 0;
|
||||
#else
|
||||
unsigned int twr_ps = 0;
|
||||
unsigned int twtr_ps = 0;
|
||||
unsigned int trfc_ps = 0;
|
||||
unsigned int trrd_ps = 0;
|
||||
unsigned int trtp_ps = 0;
|
||||
#endif
|
||||
unsigned int trc_ps = 0;
|
||||
unsigned int refresh_rate_ps = 0;
|
||||
unsigned int extended_op_srt = 1;
|
||||
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
unsigned int tis_ps = 0;
|
||||
unsigned int tih_ps = 0;
|
||||
unsigned int tds_ps = 0;
|
||||
unsigned int tdh_ps = 0;
|
||||
unsigned int trtp_ps = 0;
|
||||
unsigned int tdqsq_max_ps = 0;
|
||||
unsigned int tqhs_ps = 0;
|
||||
|
||||
#endif
|
||||
unsigned int temp1, temp2;
|
||||
unsigned int additive_latency = 0;
|
||||
#if !defined(CONFIG_SYS_FSL_DDR3)
|
||||
const unsigned int mclk_ps = get_memory_clk_period_ps();
|
||||
unsigned int lowest_good_caslat;
|
||||
unsigned int not_ok;
|
||||
|
||||
debug("using mclk_ps = %u\n", mclk_ps);
|
||||
#endif
|
||||
|
||||
temp1 = 0;
|
||||
for (i = 0; i < number_of_dimms; i++) {
|
||||
@ -146,31 +290,34 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
|
||||
* i.e., this is the slowest the whole system can go.
|
||||
*/
|
||||
tckmax_ps = min(tckmax_ps, dimm_params[i].tckmax_ps);
|
||||
|
||||
/* Either find maximum value to determine slowest
|
||||
* speed, delay, time, period, etc */
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
|
||||
taamin_ps = max(taamin_ps, dimm_params[i].taa_ps);
|
||||
#endif
|
||||
tckmin_x_ps = max(tckmin_x_ps, dimm_params[i].tckmin_x_ps);
|
||||
tckmax_max_ps = max(tckmax_max_ps, dimm_params[i].tckmax_ps);
|
||||
trcd_ps = max(trcd_ps, dimm_params[i].trcd_ps);
|
||||
trp_ps = max(trp_ps, dimm_params[i].trp_ps);
|
||||
tras_ps = max(tras_ps, dimm_params[i].tras_ps);
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
trfc1_ps = max(trfc1_ps, dimm_params[i].trfc1_ps);
|
||||
trfc2_ps = max(trfc2_ps, dimm_params[i].trfc2_ps);
|
||||
trfc4_ps = max(trfc4_ps, dimm_params[i].trfc4_ps);
|
||||
trrds_ps = max(trrds_ps, dimm_params[i].trrds_ps);
|
||||
trrdl_ps = max(trrdl_ps, dimm_params[i].trrdl_ps);
|
||||
tccdl_ps = max(tccdl_ps, dimm_params[i].tccdl_ps);
|
||||
#else
|
||||
twr_ps = max(twr_ps, dimm_params[i].twr_ps);
|
||||
twtr_ps = max(twtr_ps, dimm_params[i].twtr_ps);
|
||||
trfc_ps = max(trfc_ps, dimm_params[i].trfc_ps);
|
||||
trrd_ps = max(trrd_ps, dimm_params[i].trrd_ps);
|
||||
trtp_ps = max(trtp_ps, dimm_params[i].trtp_ps);
|
||||
#endif
|
||||
trc_ps = max(trc_ps, dimm_params[i].trc_ps);
|
||||
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
tis_ps = max(tis_ps, dimm_params[i].tis_ps);
|
||||
tih_ps = max(tih_ps, dimm_params[i].tih_ps);
|
||||
tds_ps = max(tds_ps, dimm_params[i].tds_ps);
|
||||
tdh_ps = max(tdh_ps, dimm_params[i].tdh_ps);
|
||||
trtp_ps = max(trtp_ps, dimm_params[i].trtp_ps);
|
||||
tqhs_ps = max(tqhs_ps, dimm_params[i].tqhs_ps);
|
||||
refresh_rate_ps = max(refresh_rate_ps,
|
||||
dimm_params[i].refresh_rate_ps);
|
||||
/* extended_op_srt is either 0 or 1, 0 having priority */
|
||||
extended_op_srt = min(extended_op_srt,
|
||||
dimm_params[i].extended_op_srt);
|
||||
|
||||
/*
|
||||
* Find maximum tdqsq_max_ps to find slowest.
|
||||
*
|
||||
@ -178,6 +325,12 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
|
||||
* strategy for this parameter?
|
||||
*/
|
||||
tdqsq_max_ps = max(tdqsq_max_ps, dimm_params[i].tdqsq_max_ps);
|
||||
#endif
|
||||
refresh_rate_ps = max(refresh_rate_ps,
|
||||
dimm_params[i].refresh_rate_ps);
|
||||
/* extended_op_srt is either 0 or 1, 0 having priority */
|
||||
extended_op_srt = min(extended_op_srt,
|
||||
dimm_params[i].extended_op_srt);
|
||||
}
|
||||
|
||||
outpdimm->ndimms_present = number_of_dimms - temp1;
|
||||
@ -189,24 +342,37 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
|
||||
|
||||
outpdimm->tckmin_x_ps = tckmin_x_ps;
|
||||
outpdimm->tckmax_ps = tckmax_ps;
|
||||
outpdimm->tckmax_max_ps = tckmax_max_ps;
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
|
||||
outpdimm->taamin_ps = taamin_ps;
|
||||
#endif
|
||||
outpdimm->trcd_ps = trcd_ps;
|
||||
outpdimm->trp_ps = trp_ps;
|
||||
outpdimm->tras_ps = tras_ps;
|
||||
outpdimm->twr_ps = twr_ps;
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
outpdimm->trfc1_ps = trfc1_ps;
|
||||
outpdimm->trfc2_ps = trfc2_ps;
|
||||
outpdimm->trfc4_ps = trfc4_ps;
|
||||
outpdimm->trrds_ps = trrds_ps;
|
||||
outpdimm->trrdl_ps = trrdl_ps;
|
||||
outpdimm->tccdl_ps = tccdl_ps;
|
||||
#else
|
||||
outpdimm->twtr_ps = twtr_ps;
|
||||
outpdimm->trfc_ps = trfc_ps;
|
||||
outpdimm->trrd_ps = trrd_ps;
|
||||
outpdimm->trtp_ps = trtp_ps;
|
||||
#endif
|
||||
outpdimm->twr_ps = twr_ps;
|
||||
outpdimm->trc_ps = trc_ps;
|
||||
outpdimm->refresh_rate_ps = refresh_rate_ps;
|
||||
outpdimm->extended_op_srt = extended_op_srt;
|
||||
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
outpdimm->tis_ps = tis_ps;
|
||||
outpdimm->tih_ps = tih_ps;
|
||||
outpdimm->tds_ps = tds_ps;
|
||||
outpdimm->tdh_ps = tdh_ps;
|
||||
outpdimm->trtp_ps = trtp_ps;
|
||||
outpdimm->tdqsq_max_ps = tdqsq_max_ps;
|
||||
outpdimm->tqhs_ps = tqhs_ps;
|
||||
#endif
|
||||
|
||||
/* Determine common burst length for all DIMMs. */
|
||||
temp1 = 0xff;
|
||||
@ -265,128 +431,9 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
|
||||
if (temp1 != 0)
|
||||
printf("ERROR: Mix different RDIMM detected!\n");
|
||||
|
||||
#if defined(CONFIG_SYS_FSL_DDR3)
|
||||
if (compute_cas_latency_ddr3(dimm_params, outpdimm, number_of_dimms))
|
||||
/* calculate cas latency for all DDR types */
|
||||
if (compute_cas_latency(dimm_params, outpdimm, number_of_dimms))
|
||||
return 1;
|
||||
#else
|
||||
/*
|
||||
* Compute a CAS latency suitable for all DIMMs
|
||||
*
|
||||
* Strategy for SPD-defined latencies: compute only
|
||||
* CAS latency defined by all DIMMs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Step 1: find CAS latency common to all DIMMs using bitwise
|
||||
* operation.
|
||||
*/
|
||||
temp1 = 0xFF;
|
||||
for (i = 0; i < number_of_dimms; i++) {
|
||||
if (dimm_params[i].n_ranks) {
|
||||
temp2 = 0;
|
||||
temp2 |= 1 << dimm_params[i].caslat_x;
|
||||
temp2 |= 1 << dimm_params[i].caslat_x_minus_1;
|
||||
temp2 |= 1 << dimm_params[i].caslat_x_minus_2;
|
||||
/*
|
||||
* FIXME: If there was no entry for X-2 (X-1) in
|
||||
* the SPD, then caslat_x_minus_2
|
||||
* (caslat_x_minus_1) contains either 255 or
|
||||
* 0xFFFFFFFF because that's what the glorious
|
||||
* __ilog2 function returns for an input of 0.
|
||||
* On 32-bit PowerPC, left shift counts with bit
|
||||
* 26 set (that the value of 255 or 0xFFFFFFFF
|
||||
* will have), cause the destination register to
|
||||
* be 0. That is why this works.
|
||||
*/
|
||||
temp1 &= temp2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 2: check each common CAS latency against tCK of each
|
||||
* DIMM's SPD.
|
||||
*/
|
||||
lowest_good_caslat = 0;
|
||||
temp2 = 0;
|
||||
while (temp1) {
|
||||
not_ok = 0;
|
||||
temp2 = __ilog2(temp1);
|
||||
debug("checking common caslat = %u\n", temp2);
|
||||
|
||||
/* Check if this CAS latency will work on all DIMMs at tCK. */
|
||||
for (i = 0; i < number_of_dimms; i++) {
|
||||
if (!dimm_params[i].n_ranks) {
|
||||
continue;
|
||||
}
|
||||
if (dimm_params[i].caslat_x == temp2) {
|
||||
if (mclk_ps >= dimm_params[i].tckmin_x_ps) {
|
||||
debug("CL = %u ok on DIMM %u at tCK=%u"
|
||||
" ps with its tCKmin_X_ps of %u\n",
|
||||
temp2, i, mclk_ps,
|
||||
dimm_params[i].tckmin_x_ps);
|
||||
continue;
|
||||
} else {
|
||||
not_ok++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dimm_params[i].caslat_x_minus_1 == temp2) {
|
||||
unsigned int tckmin_x_minus_1_ps
|
||||
= dimm_params[i].tckmin_x_minus_1_ps;
|
||||
if (mclk_ps >= tckmin_x_minus_1_ps) {
|
||||
debug("CL = %u ok on DIMM %u at "
|
||||
"tCK=%u ps with its "
|
||||
"tckmin_x_minus_1_ps of %u\n",
|
||||
temp2, i, mclk_ps,
|
||||
tckmin_x_minus_1_ps);
|
||||
continue;
|
||||
} else {
|
||||
not_ok++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dimm_params[i].caslat_x_minus_2 == temp2) {
|
||||
unsigned int tckmin_x_minus_2_ps
|
||||
= dimm_params[i].tckmin_x_minus_2_ps;
|
||||
if (mclk_ps >= tckmin_x_minus_2_ps) {
|
||||
debug("CL = %u ok on DIMM %u at "
|
||||
"tCK=%u ps with its "
|
||||
"tckmin_x_minus_2_ps of %u\n",
|
||||
temp2, i, mclk_ps,
|
||||
tckmin_x_minus_2_ps);
|
||||
continue;
|
||||
} else {
|
||||
not_ok++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!not_ok) {
|
||||
lowest_good_caslat = temp2;
|
||||
}
|
||||
|
||||
temp1 &= ~(1 << temp2);
|
||||
}
|
||||
|
||||
debug("lowest common SPD-defined CAS latency = %u\n",
|
||||
lowest_good_caslat);
|
||||
outpdimm->lowest_common_SPD_caslat = lowest_good_caslat;
|
||||
|
||||
|
||||
/*
|
||||
* Compute a common 'de-rated' CAS latency.
|
||||
*
|
||||
* The strategy here is to find the *highest* dereated cas latency
|
||||
* with the assumption that all of the DIMMs will support a dereated
|
||||
* CAS latency higher than or equal to their lowest dereated value.
|
||||
*/
|
||||
temp1 = 0;
|
||||
for (i = 0; i < number_of_dimms; i++) {
|
||||
temp1 = max(temp1, dimm_params[i].caslat_lowest_derated);
|
||||
}
|
||||
outpdimm->highest_common_derated_caslat = temp1;
|
||||
debug("highest common dereated CAS latency = %u\n", temp1);
|
||||
#endif /* #if defined(CONFIG_SYS_FSL_DDR3) */
|
||||
|
||||
/* Determine if all DIMMs ECC capable. */
|
||||
temp1 = 1;
|
||||
@ -404,14 +451,6 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
|
||||
}
|
||||
outpdimm->all_dimms_ecc_capable = temp1;
|
||||
|
||||
#ifndef CONFIG_SYS_FSL_DDR3
|
||||
/* FIXME: move to somewhere else to validate. */
|
||||
if (mclk_ps > tckmax_max_ps) {
|
||||
printf("Warning: some of the installed DIMMs "
|
||||
"can not operate this slowly.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Compute additive latency.
|
||||
*
|
||||
@ -468,27 +507,20 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
|
||||
additive_latency = 0;
|
||||
|
||||
#if defined(CONFIG_SYS_FSL_DDR2)
|
||||
if (lowest_good_caslat < 4) {
|
||||
additive_latency = (picos_to_mclk(trcd_ps) > lowest_good_caslat)
|
||||
? picos_to_mclk(trcd_ps) - lowest_good_caslat : 0;
|
||||
if ((outpdimm->lowest_common_spd_caslat < 4) &&
|
||||
(picos_to_mclk(trcd_ps) > outpdimm->lowest_common_spd_caslat)) {
|
||||
additive_latency = picos_to_mclk(trcd_ps) -
|
||||
outpdimm->lowest_common_spd_caslat;
|
||||
if (mclk_to_picos(additive_latency) > trcd_ps) {
|
||||
additive_latency = picos_to_mclk(trcd_ps);
|
||||
debug("setting additive_latency to %u because it was "
|
||||
" greater than tRCD_ps\n", additive_latency);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_SYS_FSL_DDR3)
|
||||
/*
|
||||
* The system will not use the global auto-precharge mode.
|
||||
* However, it uses the page mode, so we set AL=0
|
||||
*/
|
||||
additive_latency = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Validate additive latency
|
||||
* FIXME: move to somewhere else to validate
|
||||
*
|
||||
* AL <= tRCD(min)
|
||||
*/
|
||||
@ -516,10 +548,19 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
|
||||
debug("trcd_ps = %u\n", outpdimm->trcd_ps);
|
||||
debug("trp_ps = %u\n", outpdimm->trp_ps);
|
||||
debug("tras_ps = %u\n", outpdimm->tras_ps);
|
||||
debug("twr_ps = %u\n", outpdimm->twr_ps);
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
debug("trfc1_ps = %u\n", trfc1_ps);
|
||||
debug("trfc2_ps = %u\n", trfc2_ps);
|
||||
debug("trfc4_ps = %u\n", trfc4_ps);
|
||||
debug("trrds_ps = %u\n", trrds_ps);
|
||||
debug("trrdl_ps = %u\n", trrdl_ps);
|
||||
debug("tccdl_ps = %u\n", tccdl_ps);
|
||||
#else
|
||||
debug("twtr_ps = %u\n", outpdimm->twtr_ps);
|
||||
debug("trfc_ps = %u\n", outpdimm->trfc_ps);
|
||||
debug("trrd_ps = %u\n", outpdimm->trrd_ps);
|
||||
#endif
|
||||
debug("twr_ps = %u\n", outpdimm->twr_ps);
|
||||
debug("trc_ps = %u\n", outpdimm->trc_ps);
|
||||
|
||||
return 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2012 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -81,14 +81,37 @@ u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
|
||||
|
||||
#endif
|
||||
|
||||
#define SPD_SPA0_ADDRESS 0x36
|
||||
#define SPD_SPA1_ADDRESS 0x37
|
||||
|
||||
static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
|
||||
{
|
||||
int ret;
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
uint8_t dummy = 0;
|
||||
#endif
|
||||
|
||||
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
/*
|
||||
* DDR4 SPD has 384 to 512 bytes
|
||||
* To access the lower 256 bytes, we need to set EE page address to 0
|
||||
* To access the upper 256 bytes, we need to set EE page address to 1
|
||||
* See Jedec standar No. 21-C for detail
|
||||
*/
|
||||
i2c_write(SPD_SPA0_ADDRESS, 0, 1, &dummy, 1);
|
||||
ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, 256);
|
||||
if (!ret) {
|
||||
i2c_write(SPD_SPA1_ADDRESS, 0, 1, &dummy, 1);
|
||||
ret = i2c_read(i2c_address, 0, 1,
|
||||
(uchar *)((ulong)spd + 256),
|
||||
min(256, sizeof(generic_spd_eeprom_t) - 256));
|
||||
}
|
||||
#else
|
||||
ret = i2c_read(i2c_address, 0, 1, (uchar *)spd,
|
||||
sizeof(generic_spd_eeprom_t));
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
if (i2c_address ==
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008, 2010-2012 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008, 2010-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
@ -29,7 +29,7 @@ struct dynamic_odt {
|
||||
unsigned int odt_rtt_wr;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DDR3
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
|
||||
static const struct dynamic_odt single_Q[4] = {
|
||||
{ /* cs0 */
|
||||
FSL_DDR_ODT_NEVER,
|
||||
@ -259,7 +259,7 @@ static const struct dynamic_odt odt_unknown[4] = {
|
||||
DDR3_RTT_OFF
|
||||
}
|
||||
};
|
||||
#else /* CONFIG_SYS_FSL_DDR3 */
|
||||
#else /* CONFIG_SYS_FSL_DDR3 || CONFIG_SYS_FSL_DDR4 */
|
||||
static const struct dynamic_odt single_Q[4] = {
|
||||
{0, 0, 0, 0},
|
||||
{0, 0, 0, 0},
|
||||
@ -507,7 +507,9 @@ unsigned int populate_memctl_options(int all_dimms_registered,
|
||||
unsigned int i;
|
||||
char buffer[HWCONFIG_BUFFER_SIZE];
|
||||
char *buf = NULL;
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || \
|
||||
defined(CONFIG_SYS_FSL_DDR2) || \
|
||||
defined(CONFIG_SYS_FSL_DDR4)
|
||||
const struct dynamic_odt *pdodt = odt_unknown;
|
||||
#endif
|
||||
ulong ddr_freq;
|
||||
@ -519,7 +521,9 @@ unsigned int populate_memctl_options(int all_dimms_registered,
|
||||
if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
|
||||
buf = buffer;
|
||||
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || \
|
||||
defined(CONFIG_SYS_FSL_DDR2) || \
|
||||
defined(CONFIG_SYS_FSL_DDR4)
|
||||
/* Chip select options. */
|
||||
if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) {
|
||||
switch (pdimm[0].n_ranks) {
|
||||
@ -585,7 +589,9 @@ unsigned int populate_memctl_options(int all_dimms_registered,
|
||||
|
||||
/* Pick chip-select local options. */
|
||||
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || \
|
||||
defined(CONFIG_SYS_FSL_DDR2) || \
|
||||
defined(CONFIG_SYS_FSL_DDR4)
|
||||
popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg;
|
||||
popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg;
|
||||
popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm;
|
||||
@ -703,7 +709,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
|
||||
popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0;
|
||||
|
||||
/* Choose burst length. */
|
||||
#if defined(CONFIG_SYS_FSL_DDR3)
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
|
||||
#if defined(CONFIG_E500MC)
|
||||
popts->otf_burst_chop_en = 0; /* on-the-fly burst chop disable */
|
||||
popts->burst_length = DDR_BL8; /* Fixed 8-beat burst len */
|
||||
@ -722,7 +728,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
|
||||
#endif
|
||||
|
||||
/* Choose ddr controller address mirror mode */
|
||||
#if defined(CONFIG_SYS_FSL_DDR3)
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
|
||||
popts->mirrored_dimm = pdimm[0].mirrored_dimm;
|
||||
#endif
|
||||
|
||||
@ -766,11 +772,9 @@ unsigned int populate_memctl_options(int all_dimms_registered,
|
||||
* BSTTOPRE precharge interval
|
||||
*
|
||||
* Set this to 0 for global auto precharge
|
||||
*
|
||||
* FIXME: Should this be configured in picoseconds?
|
||||
* Why it should be in ps: better understanding of this
|
||||
* relative to actual DRAM timing parameters such as tRAS.
|
||||
* e.g. tRAS(min) = 40 ns
|
||||
* The value of 0x100 has been used for DDR1, DDR2, DDR3.
|
||||
* It is not wrong. Any value should be OK. The performance depends on
|
||||
* applications. There is no one good value for all.
|
||||
*/
|
||||
popts->bstopre = 0x100;
|
||||
|
||||
@ -795,12 +799,12 @@ unsigned int populate_memctl_options(int all_dimms_registered,
|
||||
*/
|
||||
popts->tfaw_window_four_activates_ps = 37500;
|
||||
|
||||
#elif defined(CONFIG_SYS_FSL_DDR3)
|
||||
#else
|
||||
popts->tfaw_window_four_activates_ps = pdimm[0].tfaw_ps;
|
||||
#endif
|
||||
popts->zq_en = 0;
|
||||
popts->wrlvl_en = 0;
|
||||
#if defined(CONFIG_SYS_FSL_DDR3)
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
|
||||
/*
|
||||
* due to ddr3 dimm is fly-by topology
|
||||
* we suggest to enable write leveling to
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2012 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -23,6 +23,18 @@
|
||||
|
||||
#define ULL_8FS 0xFFFFFFFFULL
|
||||
|
||||
u32 fsl_ddr_get_version(void)
|
||||
{
|
||||
struct ccsr_ddr __iomem *ddr;
|
||||
u32 ver_major_minor_errata;
|
||||
|
||||
ddr = (void *)_DDR_ADDR;
|
||||
ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
|
||||
ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;
|
||||
|
||||
return ver_major_minor_errata;
|
||||
}
|
||||
|
||||
/*
|
||||
* Round up mclk_ps to nearest 1 ps in memory controller code
|
||||
* if the error is 0.5ps or more.
|
||||
@ -175,6 +187,9 @@ void board_add_ram_info(int use_default)
|
||||
case SDRAM_TYPE_DDR3:
|
||||
puts("3");
|
||||
break;
|
||||
case SDRAM_TYPE_DDR4:
|
||||
puts("4");
|
||||
break;
|
||||
default:
|
||||
puts("?");
|
||||
break;
|
||||
@ -188,9 +203,12 @@ void board_add_ram_info(int use_default)
|
||||
puts(", 64-bit");
|
||||
|
||||
/* Calculate CAS latency based on timing cfg values */
|
||||
cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf) + 1;
|
||||
if ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 1)
|
||||
cas_lat += (8 << 1);
|
||||
cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
|
||||
if (fsl_ddr_get_version() <= 0x40400)
|
||||
cas_lat += 1;
|
||||
else
|
||||
cas_lat += 2;
|
||||
cas_lat += ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 3) << 4;
|
||||
printf(", CL=%d", cas_lat >> 1);
|
||||
if (cas_lat & 0x1)
|
||||
puts(".5");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -14,32 +14,45 @@ typedef struct {
|
||||
|
||||
unsigned int tckmin_x_ps;
|
||||
unsigned int tckmax_ps;
|
||||
unsigned int tckmax_max_ps;
|
||||
unsigned int trcd_ps;
|
||||
unsigned int trp_ps;
|
||||
unsigned int tras_ps;
|
||||
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
|
||||
unsigned int taamin_ps;
|
||||
#endif
|
||||
|
||||
unsigned int twr_ps; /* maximum = 63750 ps */
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
unsigned int trfc1_ps;
|
||||
unsigned int trfc2_ps;
|
||||
unsigned int trfc4_ps;
|
||||
unsigned int trrds_ps;
|
||||
unsigned int trrdl_ps;
|
||||
unsigned int tccdl_ps;
|
||||
#else
|
||||
unsigned int twtr_ps; /* maximum = 63750 ps */
|
||||
unsigned int trfc_ps; /* maximum = 255 ns + 256 ns + .75 ns
|
||||
= 511750 ps */
|
||||
|
||||
unsigned int trrd_ps; /* maximum = 63750 ps */
|
||||
unsigned int trtp_ps; /* byte 38, spd->trtp */
|
||||
#endif
|
||||
unsigned int twr_ps; /* maximum = 63750 ps */
|
||||
unsigned int trc_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
|
||||
|
||||
unsigned int refresh_rate_ps;
|
||||
unsigned int extended_op_srt;
|
||||
|
||||
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
unsigned int tis_ps; /* byte 32, spd->ca_setup */
|
||||
unsigned int tih_ps; /* byte 33, spd->ca_hold */
|
||||
unsigned int tds_ps; /* byte 34, spd->data_setup */
|
||||
unsigned int tdh_ps; /* byte 35, spd->data_hold */
|
||||
unsigned int trtp_ps; /* byte 38, spd->trtp */
|
||||
unsigned int tdqsq_max_ps; /* byte 44, spd->tdqsq */
|
||||
unsigned int tqhs_ps; /* byte 45, spd->tqhs */
|
||||
#endif
|
||||
|
||||
unsigned int ndimms_present;
|
||||
unsigned int lowest_common_SPD_caslat;
|
||||
unsigned int lowest_common_spd_caslat;
|
||||
unsigned int highest_common_derated_caslat;
|
||||
unsigned int additive_latency;
|
||||
unsigned int all_dimms_burst_lengths_bitmask;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -290,11 +290,220 @@ typedef struct ddr3_spd_eeprom_s {
|
||||
|
||||
} ddr3_spd_eeprom_t;
|
||||
|
||||
/* From JEEC Standard No. 21-C release 23A */
|
||||
struct ddr4_spd_eeprom_s {
|
||||
/* General Section: Bytes 0-127 */
|
||||
uint8_t info_size_crc; /* 0 # bytes */
|
||||
uint8_t spd_rev; /* 1 Total # bytes of SPD */
|
||||
uint8_t mem_type; /* 2 Key Byte / mem type */
|
||||
uint8_t module_type; /* 3 Key Byte / Module Type */
|
||||
uint8_t density_banks; /* 4 Density and Banks */
|
||||
uint8_t addressing; /* 5 Addressing */
|
||||
uint8_t package_type; /* 6 Package type */
|
||||
uint8_t opt_feature; /* 7 Optional features */
|
||||
uint8_t thermal_ref; /* 8 Thermal and refresh */
|
||||
uint8_t oth_opt_features; /* 9 Other optional features */
|
||||
uint8_t res_10; /* 10 Reserved */
|
||||
uint8_t module_vdd; /* 11 Module nominal voltage */
|
||||
uint8_t organization; /* 12 Module Organization */
|
||||
uint8_t bus_width; /* 13 Module Memory Bus Width */
|
||||
uint8_t therm_sensor; /* 14 Module Thermal Sensor */
|
||||
uint8_t ext_type; /* 15 Extended module type */
|
||||
uint8_t res_16;
|
||||
uint8_t timebases; /* 17 MTb and FTB */
|
||||
uint8_t tck_min; /* 18 tCKAVGmin */
|
||||
uint8_t tck_max; /* 19 TCKAVGmax */
|
||||
uint8_t caslat_b1; /* 20 CAS latencies, 1st byte */
|
||||
uint8_t caslat_b2; /* 21 CAS latencies, 2nd byte */
|
||||
uint8_t caslat_b3; /* 22 CAS latencies, 3rd byte */
|
||||
uint8_t caslat_b4; /* 23 CAS latencies, 4th byte */
|
||||
uint8_t taa_min; /* 24 Min CAS Latency Time */
|
||||
uint8_t trcd_min; /* 25 Min RAS# to CAS# Delay Time */
|
||||
uint8_t trp_min; /* 26 Min Row Precharge Delay Time */
|
||||
uint8_t tras_trc_ext; /* 27 Upper Nibbles for tRAS and tRC */
|
||||
uint8_t tras_min_lsb; /* 28 tRASmin, lsb */
|
||||
uint8_t trc_min_lsb; /* 29 tRCmin, lsb */
|
||||
uint8_t trfc1_min_lsb; /* 30 Min Refresh Recovery Delay Time */
|
||||
uint8_t trfc1_min_msb; /* 31 Min Refresh Recovery Delay Time */
|
||||
uint8_t trfc2_min_lsb; /* 32 Min Refresh Recovery Delay Time */
|
||||
uint8_t trfc2_min_msb; /* 33 Min Refresh Recovery Delay Time */
|
||||
uint8_t trfc4_min_lsb; /* 34 Min Refresh Recovery Delay Time */
|
||||
uint8_t trfc4_min_msb; /* 35 Min Refresh Recovery Delay Time */
|
||||
uint8_t tfaw_msb; /* 36 Upper Nibble for tFAW */
|
||||
uint8_t tfaw_min; /* 37 tFAW, lsb */
|
||||
uint8_t trrds_min; /* 38 tRRD_Smin, MTB */
|
||||
uint8_t trrdl_min; /* 39 tRRD_Lmin, MTB */
|
||||
uint8_t tccdl_min; /* 40 tCCS_Lmin, MTB */
|
||||
uint8_t res_41[60-41]; /* 41 Rserved */
|
||||
uint8_t mapping[78-60]; /* 60~77 Connector to SDRAM bit map */
|
||||
uint8_t res_78[117-78]; /* 78~116, Reserved */
|
||||
int8_t fine_tccdl_min; /* 117 Fine offset for tCCD_Lmin */
|
||||
int8_t fine_trrdl_min; /* 118 Fine offset for tRRD_Lmin */
|
||||
int8_t fine_trrds_min; /* 119 Fine offset for tRRD_Smin */
|
||||
int8_t fine_trc_min; /* 120 Fine offset for tRCmin */
|
||||
int8_t fine_trp_min; /* 121 Fine offset for tRPmin */
|
||||
int8_t fine_trcd_min; /* 122 Fine offset for tRCDmin */
|
||||
int8_t fine_taa_min; /* 123 Fine offset for tAAmin */
|
||||
int8_t fine_tck_max; /* 124 Fine offset for tCKAVGmax */
|
||||
int8_t fine_tck_min; /* 125 Fine offset for tCKAVGmin */
|
||||
/* CRC: Bytes 126-127 */
|
||||
uint8_t crc[2]; /* 126-127 SPD CRC */
|
||||
|
||||
/* Module-Specific Section: Bytes 128-255 */
|
||||
union {
|
||||
struct {
|
||||
/* 128 (Unbuffered) Module Nominal Height */
|
||||
uint8_t mod_height;
|
||||
/* 129 (Unbuffered) Module Maximum Thickness */
|
||||
uint8_t mod_thickness;
|
||||
/* 130 (Unbuffered) Reference Raw Card Used */
|
||||
uint8_t ref_raw_card;
|
||||
/* 131 (Unbuffered) Address Mapping from
|
||||
Edge Connector to DRAM */
|
||||
uint8_t addr_mapping;
|
||||
/* 132~253 (Unbuffered) Reserved */
|
||||
uint8_t res_132[254-132];
|
||||
/* 254~255 CRC */
|
||||
uint8_t crc[2];
|
||||
} unbuffered;
|
||||
struct {
|
||||
/* 128 (Registered) Module Nominal Height */
|
||||
uint8_t mod_height;
|
||||
/* 129 (Registered) Module Maximum Thickness */
|
||||
uint8_t mod_thickness;
|
||||
/* 130 (Registered) Reference Raw Card Used */
|
||||
uint8_t ref_raw_card;
|
||||
/* 131 DIMM Module Attributes */
|
||||
uint8_t modu_attr;
|
||||
/* 132 RDIMM Thermal Heat Spreader Solution */
|
||||
uint8_t thermal;
|
||||
/* 133 Register Manufacturer ID Code, LSB */
|
||||
uint8_t reg_id_lo;
|
||||
/* 134 Register Manufacturer ID Code, MSB */
|
||||
uint8_t reg_id_hi;
|
||||
/* 135 Register Revision Number */
|
||||
uint8_t reg_rev;
|
||||
/* 136 Address mapping from register to DRAM */
|
||||
uint8_t reg_map;
|
||||
/* 137~253 Reserved */
|
||||
uint8_t res_137[254-137];
|
||||
/* 254~255 CRC */
|
||||
uint8_t crc[2];
|
||||
} registered;
|
||||
struct {
|
||||
/* 128 (Loadreduced) Module Nominal Height */
|
||||
uint8_t mod_height;
|
||||
/* 129 (Loadreduced) Module Maximum Thickness */
|
||||
uint8_t mod_thickness;
|
||||
/* 130 (Loadreduced) Reference Raw Card Used */
|
||||
uint8_t ref_raw_card;
|
||||
/* 131 DIMM Module Attributes */
|
||||
uint8_t modu_attr;
|
||||
/* 132 RDIMM Thermal Heat Spreader Solution */
|
||||
uint8_t thermal;
|
||||
/* 133 Register Manufacturer ID Code, LSB */
|
||||
uint8_t reg_id_lo;
|
||||
/* 134 Register Manufacturer ID Code, MSB */
|
||||
uint8_t reg_id_hi;
|
||||
/* 135 Register Revision Number */
|
||||
uint8_t reg_rev;
|
||||
/* 136 Address mapping from register to DRAM */
|
||||
uint8_t reg_map;
|
||||
/* 137 Register Output Drive Strength for CMD/Add*/
|
||||
uint8_t reg_drv;
|
||||
/* 138 Register Output Drive Strength for CK */
|
||||
uint8_t reg_drv_ck;
|
||||
/* 139 Data Buffer Revision Number */
|
||||
uint8_t data_buf_rev;
|
||||
/* 140 DRAM VrefDQ for Package Rank 0 */
|
||||
uint8_t vrefqe_r0;
|
||||
/* 141 DRAM VrefDQ for Package Rank 1 */
|
||||
uint8_t vrefqe_r1;
|
||||
/* 142 DRAM VrefDQ for Package Rank 2 */
|
||||
uint8_t vrefqe_r2;
|
||||
/* 143 DRAM VrefDQ for Package Rank 3 */
|
||||
uint8_t vrefqe_r3;
|
||||
/* 144 Data Buffer VrefDQ for DRAM Interface */
|
||||
uint8_t data_intf;
|
||||
/*
|
||||
* 145 Data Buffer MDQ Drive Strength and RTT
|
||||
* for data rate <= 1866
|
||||
*/
|
||||
uint8_t data_drv_1866;
|
||||
/*
|
||||
* 146 Data Buffer MDQ Drive Strength and RTT
|
||||
* for 1866 < data rate <= 2400
|
||||
*/
|
||||
uint8_t data_drv_2400;
|
||||
/*
|
||||
* 147 Data Buffer MDQ Drive Strength and RTT
|
||||
* for 2400 < data rate <= 3200
|
||||
*/
|
||||
uint8_t data_drv_3200;
|
||||
/* 148 DRAM Drive Strength */
|
||||
uint8_t dram_drv;
|
||||
/*
|
||||
* 149 DRAM ODT (RTT_WR, RTT_NOM)
|
||||
* for data rate <= 1866
|
||||
*/
|
||||
uint8_t dram_odt_1866;
|
||||
/*
|
||||
* 150 DRAM ODT (RTT_WR, RTT_NOM)
|
||||
* for 1866 < data rate <= 2400
|
||||
*/
|
||||
uint8_t dram_odt_2400;
|
||||
/*
|
||||
* 151 DRAM ODT (RTT_WR, RTT_NOM)
|
||||
* for 2400 < data rate <= 3200
|
||||
*/
|
||||
uint8_t dram_odt_3200;
|
||||
/*
|
||||
* 152 DRAM ODT (RTT_PARK)
|
||||
* for data rate <= 1866
|
||||
*/
|
||||
uint8_t dram_odt_park_1866;
|
||||
/*
|
||||
* 153 DRAM ODT (RTT_PARK)
|
||||
* for 1866 < data rate <= 2400
|
||||
*/
|
||||
uint8_t dram_odt_park_2400;
|
||||
/*
|
||||
* 154 DRAM ODT (RTT_PARK)
|
||||
* for 2400 < data rate <= 3200
|
||||
*/
|
||||
uint8_t dram_odt_park_3200;
|
||||
uint8_t res_155[254-155]; /* Reserved */
|
||||
/* 254~255 CRC */
|
||||
uint8_t crc[2];
|
||||
} loadreduced;
|
||||
uint8_t uc[128]; /* 128-255 Module-Specific Section */
|
||||
} mod_section;
|
||||
|
||||
uint8_t res_256[320-256]; /* 256~319 Reserved */
|
||||
|
||||
/* Module supplier's data: Byte 320~383 */
|
||||
uint8_t mmid_lsb; /* 320 Module MfgID Code LSB */
|
||||
uint8_t mmid_msb; /* 321 Module MfgID Code MSB */
|
||||
uint8_t mloc; /* 322 Mfg Location */
|
||||
uint8_t mdate[2]; /* 323~324 Mfg Date */
|
||||
uint8_t sernum[4]; /* 325~328 Module Serial Number */
|
||||
uint8_t mpart[20]; /* 329~348 Mfg's Module Part Number */
|
||||
uint8_t mrev; /* 349 Module Revision Code */
|
||||
uint8_t dmid_lsb; /* 350 DRAM MfgID Code LSB */
|
||||
uint8_t dmid_msb; /* 351 DRAM MfgID Code MSB */
|
||||
uint8_t stepping; /* 352 DRAM stepping */
|
||||
uint8_t msd[29]; /* 353~381 Mfg's Specific Data */
|
||||
uint8_t res_382[2]; /* 382~383 Reserved */
|
||||
|
||||
uint8_t user[512-384]; /* 384~511 End User Programmable */
|
||||
};
|
||||
|
||||
extern unsigned int ddr1_spd_check(const ddr1_spd_eeprom_t *spd);
|
||||
extern void ddr1_spd_dump(const ddr1_spd_eeprom_t *spd);
|
||||
extern unsigned int ddr2_spd_check(const ddr2_spd_eeprom_t *spd);
|
||||
extern void ddr2_spd_dump(const ddr2_spd_eeprom_t *spd);
|
||||
extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd);
|
||||
unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s *spd);
|
||||
|
||||
/*
|
||||
* Byte 2 Fundamental Memory Types.
|
||||
@ -310,6 +519,7 @@ extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd);
|
||||
#define SPD_MEMTYPE_DDR2_FBDIMM (0x09)
|
||||
#define SPD_MEMTYPE_DDR2_FBDIMM_PROBE (0x0A)
|
||||
#define SPD_MEMTYPE_DDR3 (0x0B)
|
||||
#define SPD_MEMTYPE_DDR4 (0x0C)
|
||||
|
||||
/* DIMM Type for DDR2 SPD (according to v1.3) */
|
||||
#define DDR2_SPD_DIMMTYPE_UNDEFINED (0x00)
|
||||
@ -338,4 +548,18 @@ extern unsigned int ddr3_spd_check(const ddr3_spd_eeprom_t *spd);
|
||||
#define DDR3_SPD_MODULETYPE_16B_SO_DIMM (0x0C)
|
||||
#define DDR3_SPD_MODULETYPE_32B_SO_DIMM (0x0D)
|
||||
|
||||
/* DIMM Type for DDR4 SPD */
|
||||
#define DDR4_SPD_MODULETYPE_MASK (0x0f)
|
||||
#define DDR4_SPD_MODULETYPE_EXT (0x00)
|
||||
#define DDR4_SPD_MODULETYPE_RDIMM (0x01)
|
||||
#define DDR4_SPD_MODULETYPE_UDIMM (0x02)
|
||||
#define DDR4_SPD_MODULETYPE_SO_DIMM (0x03)
|
||||
#define DDR4_SPD_MODULETYPE_LRDIMM (0x04)
|
||||
#define DDR4_SPD_MODULETYPE_MINI_RDIMM (0x05)
|
||||
#define DDR4_SPD_MODULETYPE_MINI_UDIMM (0x06)
|
||||
#define DDR4_SPD_MODULETYPE_72B_SO_UDIMM (0x08)
|
||||
#define DDR4_SPD_MODULETYPE_72B_SO_RDIMM (0x09)
|
||||
#define DDR4_SPD_MODULETYPE_16B_SO_DIMM (0x0C)
|
||||
#define DDR4_SPD_MODULETYPE_32B_SO_DIMM (0x0D)
|
||||
|
||||
#endif /* _DDR_SPD_H_ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2011 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -9,6 +9,7 @@
|
||||
#ifndef FSL_DDR_MAIN_H
|
||||
#define FSL_DDR_MAIN_H
|
||||
|
||||
#include <fsl_ddrc_version.h>
|
||||
#include <fsl_ddr_sdram.h>
|
||||
#include <fsl_ddr_dimm_params.h>
|
||||
|
||||
@ -22,6 +23,10 @@
|
||||
#define ddr_out32(a, v) out_be32(a, v)
|
||||
#endif
|
||||
|
||||
#define _DDR_ADDR CONFIG_SYS_FSL_DDR_ADDR
|
||||
|
||||
u32 fsl_ddr_get_version(void);
|
||||
|
||||
#if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM)
|
||||
/*
|
||||
* Bind the main DDR setup driver's generic names
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -13,7 +13,7 @@
|
||||
#define EDC_ECC 2
|
||||
#define EDC_AC_PARITY 4
|
||||
|
||||
/* Parameters for a DDR2 dimm computed from the SPD */
|
||||
/* Parameters for a DDR dimm computed from the SPD */
|
||||
typedef struct dimm_params_s {
|
||||
|
||||
/* DIMM organization parameters */
|
||||
@ -32,7 +32,12 @@ typedef struct dimm_params_s {
|
||||
unsigned int n_row_addr;
|
||||
unsigned int n_col_addr;
|
||||
unsigned int edc_config; /* 0 = none, 1 = parity, 2 = ECC */
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
unsigned int bank_addr_bits;
|
||||
unsigned int bank_group_bits;
|
||||
#else
|
||||
unsigned int n_banks_per_sdram_device;
|
||||
#endif
|
||||
unsigned int burst_lengths_bitmask; /* BL=4 bit 2, BL=8 = bit 3 */
|
||||
unsigned int row_density;
|
||||
|
||||
@ -43,19 +48,19 @@ typedef struct dimm_params_s {
|
||||
|
||||
/* DIMM timing parameters */
|
||||
|
||||
unsigned int mtb_ps; /* medium timebase ps, only for ddr3 */
|
||||
unsigned int ftb_10th_ps; /* fine timebase, in 1/10 ps, only for ddr3 */
|
||||
unsigned int taa_ps; /* minimum CAS latency time, only for ddr3 */
|
||||
unsigned int tfaw_ps; /* four active window delay, only for ddr3 */
|
||||
int mtb_ps; /* medium timebase ps */
|
||||
int ftb_10th_ps; /* fine timebase, in 1/10 ps */
|
||||
int taa_ps; /* minimum CAS latency time */
|
||||
int tfaw_ps; /* four active window delay */
|
||||
|
||||
/*
|
||||
* SDRAM clock periods
|
||||
* The range for these are 1000-10000 so a short should be sufficient
|
||||
*/
|
||||
unsigned int tckmin_x_ps;
|
||||
unsigned int tckmin_x_minus_1_ps;
|
||||
unsigned int tckmin_x_minus_2_ps;
|
||||
unsigned int tckmax_ps;
|
||||
int tckmin_x_ps;
|
||||
int tckmin_x_minus_1_ps;
|
||||
int tckmin_x_minus_2_ps;
|
||||
int tckmax_ps;
|
||||
|
||||
/* SPD-defined CAS latencies */
|
||||
unsigned int caslat_x;
|
||||
@ -65,32 +70,46 @@ typedef struct dimm_params_s {
|
||||
unsigned int caslat_lowest_derated; /* Derated CAS latency */
|
||||
|
||||
/* basic timing parameters */
|
||||
unsigned int trcd_ps;
|
||||
unsigned int trp_ps;
|
||||
unsigned int tras_ps;
|
||||
int trcd_ps;
|
||||
int trp_ps;
|
||||
int tras_ps;
|
||||
|
||||
unsigned int twr_ps; /* maximum = 63750 ps */
|
||||
unsigned int twtr_ps; /* maximum = 63750 ps */
|
||||
unsigned int trfc_ps; /* max = 255 ns + 256 ns + .75 ns
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
int trfc1_ps;
|
||||
int trfc2_ps;
|
||||
int trfc4_ps;
|
||||
int trrds_ps;
|
||||
int trrdl_ps;
|
||||
int tccdl_ps;
|
||||
#else
|
||||
int twr_ps; /* maximum = 63750 ps */
|
||||
int trfc_ps; /* max = 255 ns + 256 ns + .75 ns
|
||||
= 511750 ps */
|
||||
int trrd_ps; /* maximum = 63750 ps */
|
||||
int twtr_ps; /* maximum = 63750 ps */
|
||||
int trtp_ps; /* byte 38, spd->trtp */
|
||||
#endif
|
||||
|
||||
unsigned int trrd_ps; /* maximum = 63750 ps */
|
||||
unsigned int trc_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
|
||||
int trc_ps; /* maximum = 254 ns + .75 ns = 254750 ps */
|
||||
|
||||
unsigned int refresh_rate_ps;
|
||||
unsigned int extended_op_srt;
|
||||
int refresh_rate_ps;
|
||||
int extended_op_srt;
|
||||
|
||||
/* DDR3 doesn't need these as below */
|
||||
unsigned int tis_ps; /* byte 32, spd->ca_setup */
|
||||
unsigned int tih_ps; /* byte 33, spd->ca_hold */
|
||||
unsigned int tds_ps; /* byte 34, spd->data_setup */
|
||||
unsigned int tdh_ps; /* byte 35, spd->data_hold */
|
||||
unsigned int trtp_ps; /* byte 38, spd->trtp */
|
||||
unsigned int tdqsq_max_ps; /* byte 44, spd->tdqsq */
|
||||
unsigned int tqhs_ps; /* byte 45, spd->tqhs */
|
||||
#if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
|
||||
int tis_ps; /* byte 32, spd->ca_setup */
|
||||
int tih_ps; /* byte 33, spd->ca_hold */
|
||||
int tds_ps; /* byte 34, spd->data_setup */
|
||||
int tdh_ps; /* byte 35, spd->data_hold */
|
||||
int tdqsq_max_ps; /* byte 44, spd->tdqsq */
|
||||
int tqhs_ps; /* byte 45, spd->tqhs */
|
||||
#endif
|
||||
|
||||
/* DDR3 RDIMM */
|
||||
unsigned char rcw[16]; /* Register Control Word 0-15 */
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
unsigned int dq_mapping[18];
|
||||
unsigned int dq_mapping_ors;
|
||||
#endif
|
||||
} dimm_params_t;
|
||||
|
||||
extern unsigned int ddr_compute_dimm_parameters(
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2011 Freescale Semiconductor, Inc.
|
||||
* Copyright 2008-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -13,11 +13,13 @@
|
||||
* Pick a basic DDR Technology.
|
||||
*/
|
||||
#include <ddr_spd.h>
|
||||
#include <fsl_ddrc_version.h>
|
||||
|
||||
#define SDRAM_TYPE_DDR1 2
|
||||
#define SDRAM_TYPE_DDR2 3
|
||||
#define SDRAM_TYPE_LPDDR1 6
|
||||
#define SDRAM_TYPE_DDR3 7
|
||||
#define SDRAM_TYPE_DDR1 2
|
||||
#define SDRAM_TYPE_DDR2 3
|
||||
#define SDRAM_TYPE_LPDDR1 6
|
||||
#define SDRAM_TYPE_DDR3 7
|
||||
#define SDRAM_TYPE_DDR4 5
|
||||
|
||||
#define DDR_BL4 4 /* burst length 4 */
|
||||
#define DDR_BC4 DDR_BL4 /* burst chop for ddr3 */
|
||||
@ -54,6 +56,12 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
|
||||
#ifndef CONFIG_FSL_SDRAM_TYPE
|
||||
#define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR3
|
||||
#endif
|
||||
#elif defined(CONFIG_SYS_FSL_DDR4)
|
||||
#define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR (3) /* FIXME */
|
||||
typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t;
|
||||
#ifndef CONFIG_FSL_SDRAM_TYPE
|
||||
#define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR4
|
||||
#endif
|
||||
#endif /* #if defined(CONFIG_SYS_FSL_DDR1) */
|
||||
|
||||
#define FSL_DDR_ODT_NEVER 0x0
|
||||
@ -116,7 +124,8 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
|
||||
|
||||
#define TIMING_CFG_2_CPO_MASK 0x0F800000
|
||||
|
||||
#if defined(CONFIG_P4080)
|
||||
#if defined(CONFIG_SYS_FSL_DDR_VER) && \
|
||||
(CONFIG_SYS_FSL_DDR_VER > FSL_DDR_VER_4_4)
|
||||
#define RD_TO_PRE_MASK 0xf
|
||||
#define RD_TO_PRE_SHIFT 13
|
||||
#define WR_DATA_DELAY_MASK 0xf
|
||||
@ -154,9 +163,27 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
|
||||
#define DDR_CDR2_ODT_MASK 0x1
|
||||
#define DDR_CDR1_ODT(x) ((x & DDR_CDR1_ODT_MASK) << DDR_CDR1_ODT_SHIFT)
|
||||
#define DDR_CDR2_ODT(x) (x & DDR_CDR2_ODT_MASK)
|
||||
#define DDR_CDR2_VREF_OVRD(x) (0x00008080 | ((((x) - 37) & 0x3F) << 8))
|
||||
|
||||
#if (defined(CONFIG_SYS_FSL_DDR_VER) && \
|
||||
(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7))
|
||||
#ifdef CONFIG_SYS_FSL_DDR3L
|
||||
#define DDR_CDR_ODT_OFF 0x0
|
||||
#define DDR_CDR_ODT_120ohm 0x1
|
||||
#define DDR_CDR_ODT_200ohm 0x2
|
||||
#define DDR_CDR_ODT_75ohm 0x3
|
||||
#define DDR_CDR_ODT_60ohm 0x5
|
||||
#define DDR_CDR_ODT_46ohm 0x7
|
||||
#elif defined(CONFIG_SYS_FSL_DDR4)
|
||||
#define DDR_CDR_ODT_OFF 0x0
|
||||
#define DDR_CDR_ODT_100ohm 0x1
|
||||
#define DDR_CDR_ODT_120OHM 0x2
|
||||
#define DDR_CDR_ODT_80ohm 0x3
|
||||
#define DDR_CDR_ODT_60ohm 0x4
|
||||
#define DDR_CDR_ODT_40ohm 0x5
|
||||
#define DDR_CDR_ODT_50ohm 0x6
|
||||
#define DDR_CDR_ODT_30ohm 0x7
|
||||
#else
|
||||
#define DDR_CDR_ODT_OFF 0x0
|
||||
#define DDR_CDR_ODT_120ohm 0x1
|
||||
#define DDR_CDR_ODT_180ohm 0x2
|
||||
@ -165,6 +192,7 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
|
||||
#define DDR_CDR_ODT_60hm 0x5
|
||||
#define DDR_CDR_ODT_70ohm 0x6
|
||||
#define DDR_CDR_ODT_47ohm 0x7
|
||||
#endif /* DDR3L */
|
||||
#else
|
||||
#define DDR_CDR_ODT_75ohm 0x0
|
||||
#define DDR_CDR_ODT_55ohm 0x1
|
||||
@ -188,6 +216,7 @@ typedef struct fsl_ddr_cfg_regs_s {
|
||||
unsigned int timing_cfg_2;
|
||||
unsigned int ddr_sdram_cfg;
|
||||
unsigned int ddr_sdram_cfg_2;
|
||||
unsigned int ddr_sdram_cfg_3;
|
||||
unsigned int ddr_sdram_mode;
|
||||
unsigned int ddr_sdram_mode_2;
|
||||
unsigned int ddr_sdram_mode_3;
|
||||
@ -196,6 +225,14 @@ typedef struct fsl_ddr_cfg_regs_s {
|
||||
unsigned int ddr_sdram_mode_6;
|
||||
unsigned int ddr_sdram_mode_7;
|
||||
unsigned int ddr_sdram_mode_8;
|
||||
unsigned int ddr_sdram_mode_9;
|
||||
unsigned int ddr_sdram_mode_10;
|
||||
unsigned int ddr_sdram_mode_11;
|
||||
unsigned int ddr_sdram_mode_12;
|
||||
unsigned int ddr_sdram_mode_13;
|
||||
unsigned int ddr_sdram_mode_14;
|
||||
unsigned int ddr_sdram_mode_15;
|
||||
unsigned int ddr_sdram_mode_16;
|
||||
unsigned int ddr_sdram_md_cntl;
|
||||
unsigned int ddr_sdram_interval;
|
||||
unsigned int ddr_data_init;
|
||||
@ -204,6 +241,10 @@ typedef struct fsl_ddr_cfg_regs_s {
|
||||
unsigned int ddr_init_ext_addr;
|
||||
unsigned int timing_cfg_4;
|
||||
unsigned int timing_cfg_5;
|
||||
unsigned int timing_cfg_6;
|
||||
unsigned int timing_cfg_7;
|
||||
unsigned int timing_cfg_8;
|
||||
unsigned int timing_cfg_9;
|
||||
unsigned int ddr_zq_cntl;
|
||||
unsigned int ddr_wrlvl_cntl;
|
||||
unsigned int ddr_wrlvl_cntl_2;
|
||||
@ -211,6 +252,14 @@ typedef struct fsl_ddr_cfg_regs_s {
|
||||
unsigned int ddr_sr_cntr;
|
||||
unsigned int ddr_sdram_rcw_1;
|
||||
unsigned int ddr_sdram_rcw_2;
|
||||
unsigned int ddr_sdram_rcw_3;
|
||||
unsigned int ddr_sdram_rcw_4;
|
||||
unsigned int ddr_sdram_rcw_5;
|
||||
unsigned int ddr_sdram_rcw_6;
|
||||
unsigned int dq_map_0;
|
||||
unsigned int dq_map_1;
|
||||
unsigned int dq_map_2;
|
||||
unsigned int dq_map_3;
|
||||
unsigned int ddr_eor;
|
||||
unsigned int ddr_cdr1;
|
||||
unsigned int ddr_cdr2;
|
||||
@ -225,7 +274,7 @@ typedef struct memctl_options_partial_s {
|
||||
unsigned int all_dimms_burst_lengths_bitmask;
|
||||
unsigned int all_dimms_registered;
|
||||
unsigned int all_dimms_unbuffered;
|
||||
/* unsigned int lowest_common_SPD_caslat; */
|
||||
/* unsigned int lowest_common_spd_caslat; */
|
||||
unsigned int all_dimms_minimum_trcd_ps;
|
||||
} memctl_options_partial_t;
|
||||
|
||||
|
18
include/fsl_ddrc_version.h
Normal file
18
include/fsl_ddrc_version.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __FSL_DDRC_VER_H
|
||||
#define __FSL_DDRC_VER_H
|
||||
|
||||
/*
|
||||
* Only the versions with distinct features or registers are listed here.
|
||||
*/
|
||||
#define FSL_DDR_VER_4_4 44
|
||||
#define FSL_DDR_VER_4_6 46
|
||||
#define FSL_DDR_VER_4_7 47
|
||||
#define FSL_DDR_VER_5_0 50
|
||||
|
||||
#endif /* __FSL_DDRC_VER_H */
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Common internal memory map for some Freescale SoCs
|
||||
*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
* Copyright 2013-2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
@ -50,7 +50,8 @@ struct ccsr_ddr {
|
||||
u8 res_150[16];
|
||||
u32 timing_cfg_4; /* SDRAM Timing Configuration 4 */
|
||||
u32 timing_cfg_5; /* SDRAM Timing Configuration 5 */
|
||||
u8 reg_168[8];
|
||||
u32 timing_cfg_6; /* SDRAM Timing Configuration 6 */
|
||||
u32 timing_cfg_7; /* SDRAM Timing Configuration 7 */
|
||||
u32 ddr_zq_cntl; /* ZQ calibration control*/
|
||||
u32 ddr_wrlvl_cntl; /* write leveling control*/
|
||||
u8 reg_178[4];
|
||||
@ -60,14 +61,40 @@ struct ccsr_ddr {
|
||||
u8 reg_188[8];
|
||||
u32 ddr_wrlvl_cntl_2; /* write leveling control 2 */
|
||||
u32 ddr_wrlvl_cntl_3; /* write leveling control 3 */
|
||||
u8 res_198[104];
|
||||
u8 res_198[0x1a0-0x198];
|
||||
u32 ddr_sdram_rcw_3;
|
||||
u32 ddr_sdram_rcw_4;
|
||||
u32 ddr_sdram_rcw_5;
|
||||
u32 ddr_sdram_rcw_6;
|
||||
u8 res_1b0[0x200-0x1b0];
|
||||
u32 sdram_mode_3; /* SDRAM Mode Configuration 3 */
|
||||
u32 sdram_mode_4; /* SDRAM Mode Configuration 4 */
|
||||
u32 sdram_mode_5; /* SDRAM Mode Configuration 5 */
|
||||
u32 sdram_mode_6; /* SDRAM Mode Configuration 6 */
|
||||
u32 sdram_mode_7; /* SDRAM Mode Configuration 7 */
|
||||
u32 sdram_mode_8; /* SDRAM Mode Configuration 8 */
|
||||
u8 res_218[0x908];
|
||||
u8 res_218[0x220-0x218];
|
||||
u32 sdram_mode_9; /* SDRAM Mode Configuration 9 */
|
||||
u32 sdram_mode_10; /* SDRAM Mode Configuration 10 */
|
||||
u32 sdram_mode_11; /* SDRAM Mode Configuration 11 */
|
||||
u32 sdram_mode_12; /* SDRAM Mode Configuration 12 */
|
||||
u32 sdram_mode_13; /* SDRAM Mode Configuration 13 */
|
||||
u32 sdram_mode_14; /* SDRAM Mode Configuration 14 */
|
||||
u32 sdram_mode_15; /* SDRAM Mode Configuration 15 */
|
||||
u32 sdram_mode_16; /* SDRAM Mode Configuration 16 */
|
||||
u8 res_240[0x250-0x240];
|
||||
u32 timing_cfg_8; /* SDRAM Timing Configuration 8 */
|
||||
u32 timing_cfg_9; /* SDRAM Timing Configuration 9 */
|
||||
u8 res_258[0x260-0x258];
|
||||
u32 sdram_cfg_3;
|
||||
u8 res_264[0x2a0-0x264];
|
||||
u32 deskew_cntl;
|
||||
u8 res_2a4[0x400-0x2a4];
|
||||
u32 dq_map_0;
|
||||
u32 dq_map_1;
|
||||
u32 dq_map_2;
|
||||
u32 dq_map_3;
|
||||
u8 res_410[0xb20-0x410];
|
||||
u32 ddr_dsr1; /* Debug Status 1 */
|
||||
u32 ddr_dsr2; /* Debug Status 2 */
|
||||
u32 ddr_cdr1; /* Control Driver 1 */
|
||||
|
Loading…
Reference in New Issue
Block a user