driver/ddr/fsl: Add address parity support for DDR4 UDIMM/discrete
Add support of address parity for DDR4 UDIMM or discrete memory. It requires to configurate corresponding MR5[2:0] and TIMING_CFG_7[PAR_LAT]. Parity can be turned on by hwconfig, e.g. hwconfig=fsl_ddr:parity=on. Signed-off-by: Shengzhou Liu <Shengzhou.Liu@nxp.com> Reviewed-by: York Sun <york.sun@nxp.com>
This commit is contained in:
parent
5e8e27b743
commit
eb118807a4
@ -123,6 +123,14 @@ ECC can be turned on/off by hwconfig.
|
|||||||
Syntax is
|
Syntax is
|
||||||
hwconfig=fsl_ddr:ecc=off
|
hwconfig=fsl_ddr:ecc=off
|
||||||
|
|
||||||
|
|
||||||
|
Memory address parity on/off
|
||||||
|
============================
|
||||||
|
address parity can be turned on/off by hwconfig.
|
||||||
|
Syntax is:
|
||||||
|
hwconfig=fsl_ddr:parity=on
|
||||||
|
|
||||||
|
|
||||||
Memory testing options for mpc85xx
|
Memory testing options for mpc85xx
|
||||||
==================================
|
==================================
|
||||||
1. Memory test can be done once U-Boot prompt comes up using mtest, or
|
1. Memory test can be done once U-Boot prompt comes up using mtest, or
|
||||||
@ -143,6 +151,7 @@ platform
|
|||||||
|
|
||||||
hwconfig=fsl_ddr:addr_hash=true,ctlr_intlv=cacheline,bank_intlv=cs0_cs1_cs2_cs3,ecc=on
|
hwconfig=fsl_ddr:addr_hash=true,ctlr_intlv=cacheline,bank_intlv=cs0_cs1_cs2_cs3,ecc=on
|
||||||
|
|
||||||
|
|
||||||
Table for dynamic ODT for DDR3
|
Table for dynamic ODT for DDR3
|
||||||
==============================
|
==============================
|
||||||
For single-slot system with quad-rank DIMM and dual-slot system, dynamic ODT may
|
For single-slot system with quad-rank DIMM and dual-slot system, dynamic ODT may
|
||||||
|
@ -895,11 +895,15 @@ static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num,
|
|||||||
slow = get_ddr_freq(ctrl_num) < 1249000000;
|
slow = get_ddr_freq(ctrl_num) < 1249000000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (popts->registered_dimm_en) {
|
if (popts->registered_dimm_en)
|
||||||
rcw_en = 1;
|
rcw_en = 1;
|
||||||
ap_en = popts->ap_en;
|
|
||||||
} else {
|
/* DDR4 can have address parity for UDIMM and discrete */
|
||||||
|
if ((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) &&
|
||||||
|
(!popts->registered_dimm_en)) {
|
||||||
ap_en = 0;
|
ap_en = 0;
|
||||||
|
} else {
|
||||||
|
ap_en = popts->ap_en;
|
||||||
}
|
}
|
||||||
|
|
||||||
x4_en = popts->x4_en ? 1 : 0;
|
x4_en = popts->x4_en ? 1 : 0;
|
||||||
@ -1135,6 +1139,7 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
|
|||||||
unsigned short esdmode5; /* Extended SDRAM mode 5 */
|
unsigned short esdmode5; /* Extended SDRAM mode 5 */
|
||||||
int rtt_park = 0;
|
int rtt_park = 0;
|
||||||
bool four_cs = false;
|
bool four_cs = false;
|
||||||
|
const unsigned int mclk_ps = get_memory_clk_period_ps(0);
|
||||||
|
|
||||||
#if CONFIG_CHIP_SELECTS_PER_CTRL == 4
|
#if CONFIG_CHIP_SELECTS_PER_CTRL == 4
|
||||||
if ((ddr->cs[0].config & SDRAM_CS_CONFIG_EN) &&
|
if ((ddr->cs[0].config & SDRAM_CS_CONFIG_EN) &&
|
||||||
@ -1150,6 +1155,19 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
|
|||||||
esdmode5 = 0x00000400; /* Data mask enabled */
|
esdmode5 = 0x00000400; /* Data mask enabled */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set command/address parity latency */
|
||||||
|
if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
|
||||||
|
if (mclk_ps >= 935) {
|
||||||
|
/* for DDR4-1600/1866/2133 */
|
||||||
|
esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK;
|
||||||
|
} else if (mclk_ps >= 833) {
|
||||||
|
/* for DDR4-2400 */
|
||||||
|
esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK;
|
||||||
|
} else {
|
||||||
|
printf("parity: mclk_ps = %d not supported\n", mclk_ps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ddr->ddr_sdram_mode_9 = (0
|
ddr->ddr_sdram_mode_9 = (0
|
||||||
| ((esdmode4 & 0xffff) << 16)
|
| ((esdmode4 & 0xffff) << 16)
|
||||||
| ((esdmode5 & 0xffff) << 0)
|
| ((esdmode5 & 0xffff) << 0)
|
||||||
@ -1170,6 +1188,20 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
|
|||||||
} else {
|
} else {
|
||||||
esdmode5 = 0x00000400;
|
esdmode5 = 0x00000400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
|
||||||
|
if (mclk_ps >= 935) {
|
||||||
|
/* for DDR4-1600/1866/2133 */
|
||||||
|
esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK;
|
||||||
|
} else if (mclk_ps >= 833) {
|
||||||
|
/* for DDR4-2400 */
|
||||||
|
esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK;
|
||||||
|
} else {
|
||||||
|
printf("parity: mclk_ps = %d not supported\n",
|
||||||
|
mclk_ps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 1:
|
case 1:
|
||||||
ddr->ddr_sdram_mode_11 = (0
|
ddr->ddr_sdram_mode_11 = (0
|
||||||
@ -1925,12 +1957,25 @@ static void set_timing_cfg_7(const unsigned int ctrl_num,
|
|||||||
const common_timing_params_t *common_dimm)
|
const common_timing_params_t *common_dimm)
|
||||||
{
|
{
|
||||||
unsigned int txpr, tcksre, tcksrx;
|
unsigned int txpr, tcksre, tcksrx;
|
||||||
unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd;
|
unsigned int cke_rst, cksre, cksrx, par_lat = 0, cs_to_cmd;
|
||||||
|
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
|
||||||
|
|
||||||
txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000));
|
txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000));
|
||||||
tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
|
tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
|
||||||
tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
|
tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
|
||||||
par_lat = 0;
|
|
||||||
|
if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
|
||||||
|
if (mclk_ps >= 935) {
|
||||||
|
/* parity latency 4 clocks in case of 1600/1866/2133 */
|
||||||
|
par_lat = 4;
|
||||||
|
} else if (mclk_ps >= 833) {
|
||||||
|
/* parity latency 5 clocks for DDR4-2400 */
|
||||||
|
par_lat = 5;
|
||||||
|
} else {
|
||||||
|
printf("parity: mclk_ps = %d not supported\n", mclk_ps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cs_to_cmd = 0;
|
cs_to_cmd = 0;
|
||||||
|
|
||||||
if (txpr <= 200)
|
if (txpr <= 200)
|
||||||
|
@ -1002,8 +1002,19 @@ unsigned int populate_memctl_options(const common_timing_params_t *common_dimm,
|
|||||||
popts->twot_en = 0;
|
popts->twot_en = 0;
|
||||||
popts->threet_en = 0;
|
popts->threet_en = 0;
|
||||||
|
|
||||||
/* for RDIMM, address parity enable */
|
/* for RDIMM and DDR4 UDIMM/discrete memory, address parity enable */
|
||||||
popts->ap_en = 1;
|
if (popts->registered_dimm_en)
|
||||||
|
popts->ap_en = 1; /* 0 = disable, 1 = enable */
|
||||||
|
else
|
||||||
|
popts->ap_en = 0; /* disabled for DDR4 UDIMM/discrete default */
|
||||||
|
|
||||||
|
if (hwconfig_sub_f("fsl_ddr", "parity", buf)) {
|
||||||
|
if (hwconfig_subarg_cmp_f("fsl_ddr", "parity", "on", buf)) {
|
||||||
|
if (popts->registered_dimm_en ||
|
||||||
|
(CONFIG_FSL_SDRAM_TYPE == SDRAM_TYPE_DDR4))
|
||||||
|
popts->ap_en = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BSTTOPRE precharge interval
|
* BSTTOPRE precharge interval
|
||||||
|
@ -123,6 +123,7 @@ typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t;
|
|||||||
|
|
||||||
#define SDRAM_CFG2_FRC_SR 0x80000000
|
#define SDRAM_CFG2_FRC_SR 0x80000000
|
||||||
#define SDRAM_CFG2_D_INIT 0x00000010
|
#define SDRAM_CFG2_D_INIT 0x00000010
|
||||||
|
#define SDRAM_CFG2_AP_EN 0x00000020
|
||||||
#define SDRAM_CFG2_ODT_CFG_MASK 0x00600000
|
#define SDRAM_CFG2_ODT_CFG_MASK 0x00600000
|
||||||
#define SDRAM_CFG2_ODT_NEVER 0
|
#define SDRAM_CFG2_ODT_NEVER 0
|
||||||
#define SDRAM_CFG2_ODT_ONLY_WRITE 1
|
#define SDRAM_CFG2_ODT_ONLY_WRITE 1
|
||||||
@ -177,6 +178,14 @@ typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t;
|
|||||||
#define DDR_CDR2_VREF_TRAIN_EN 0x00000080
|
#define DDR_CDR2_VREF_TRAIN_EN 0x00000080
|
||||||
#define DDR_CDR2_VREF_RANGE_2 0x00000040
|
#define DDR_CDR2_VREF_RANGE_2 0x00000040
|
||||||
|
|
||||||
|
/* DDR ERR_DISABLE */
|
||||||
|
#define DDR_ERR_DISABLE_APED (1 << 8) /* Address parity error disable */
|
||||||
|
|
||||||
|
/* Mode Registers */
|
||||||
|
#define DDR_MR5_CA_PARITY_LAT_4_CLK 0x1 /* for DDR4-1600/1866/2133 */
|
||||||
|
#define DDR_MR5_CA_PARITY_LAT_5_CLK 0x2 /* for DDR4-2400 */
|
||||||
|
|
||||||
|
|
||||||
#if (defined(CONFIG_SYS_FSL_DDR_VER) && \
|
#if (defined(CONFIG_SYS_FSL_DDR_VER) && \
|
||||||
(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7))
|
(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7))
|
||||||
#ifdef CONFIG_SYS_FSL_DDR3L
|
#ifdef CONFIG_SYS_FSL_DDR3L
|
||||||
@ -343,7 +352,7 @@ typedef struct memctl_options_s {
|
|||||||
/* mirrior DIMMs for DDR3 */
|
/* mirrior DIMMs for DDR3 */
|
||||||
unsigned int mirrored_dimm;
|
unsigned int mirrored_dimm;
|
||||||
unsigned int quad_rank_present;
|
unsigned int quad_rank_present;
|
||||||
unsigned int ap_en; /* address parity enable for RDIMM */
|
unsigned int ap_en; /* address parity enable for RDIMM/DDR4-UDIMM */
|
||||||
unsigned int x4_en; /* enable x4 devices */
|
unsigned int x4_en; /* enable x4 devices */
|
||||||
|
|
||||||
/* Global Timing Parameters */
|
/* Global Timing Parameters */
|
||||||
|
Loading…
Reference in New Issue
Block a user