Commit eb118807a4c1778bda6294c36e379711cb08e198

Authored by Shengzhou Liu
Committed by York Sun
1 parent 5e8e27b743

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>

Showing 4 changed files with 82 additions and 8 deletions Side-by-side Diff

... ... @@ -123,6 +123,14 @@
123 123 Syntax is
124 124 hwconfig=fsl_ddr:ecc=off
125 125  
  126 +
  127 +Memory address parity on/off
  128 +============================
  129 +address parity can be turned on/off by hwconfig.
  130 +Syntax is:
  131 +hwconfig=fsl_ddr:parity=on
  132 +
  133 +
126 134 Memory testing options for mpc85xx
127 135 ==================================
128 136 1. Memory test can be done once U-Boot prompt comes up using mtest, or
... ... @@ -142,6 +150,7 @@
142 150 platform
143 151  
144 152 hwconfig=fsl_ddr:addr_hash=true,ctlr_intlv=cacheline,bank_intlv=cs0_cs1_cs2_cs3,ecc=on
  153 +
145 154  
146 155 Table for dynamic ODT for DDR3
147 156 ==============================
drivers/ddr/fsl/ctrl_regs.c
... ... @@ -895,11 +895,15 @@
895 895 slow = get_ddr_freq(ctrl_num) < 1249000000;
896 896 #endif
897 897  
898   - if (popts->registered_dimm_en) {
  898 + if (popts->registered_dimm_en)
899 899 rcw_en = 1;
900   - ap_en = popts->ap_en;
901   - } else {
  900 +
  901 + /* DDR4 can have address parity for UDIMM and discrete */
  902 + if ((CONFIG_FSL_SDRAM_TYPE != SDRAM_TYPE_DDR4) &&
  903 + (!popts->registered_dimm_en)) {
902 904 ap_en = 0;
  905 + } else {
  906 + ap_en = popts->ap_en;
903 907 }
904 908  
905 909 x4_en = popts->x4_en ? 1 : 0;
... ... @@ -1135,6 +1139,7 @@
1135 1139 unsigned short esdmode5; /* Extended SDRAM mode 5 */
1136 1140 int rtt_park = 0;
1137 1141 bool four_cs = false;
  1142 + const unsigned int mclk_ps = get_memory_clk_period_ps(0);
1138 1143  
1139 1144 #if CONFIG_CHIP_SELECTS_PER_CTRL == 4
1140 1145 if ((ddr->cs[0].config & SDRAM_CS_CONFIG_EN) &&
... ... @@ -1150,6 +1155,19 @@
1150 1155 esdmode5 = 0x00000400; /* Data mask enabled */
1151 1156 }
1152 1157  
  1158 + /* set command/address parity latency */
  1159 + if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
  1160 + if (mclk_ps >= 935) {
  1161 + /* for DDR4-1600/1866/2133 */
  1162 + esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK;
  1163 + } else if (mclk_ps >= 833) {
  1164 + /* for DDR4-2400 */
  1165 + esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK;
  1166 + } else {
  1167 + printf("parity: mclk_ps = %d not supported\n", mclk_ps);
  1168 + }
  1169 + }
  1170 +
1153 1171 ddr->ddr_sdram_mode_9 = (0
1154 1172 | ((esdmode4 & 0xffff) << 16)
1155 1173 | ((esdmode5 & 0xffff) << 0)
... ... @@ -1170,6 +1188,20 @@
1170 1188 } else {
1171 1189 esdmode5 = 0x00000400;
1172 1190 }
  1191 +
  1192 + if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
  1193 + if (mclk_ps >= 935) {
  1194 + /* for DDR4-1600/1866/2133 */
  1195 + esdmode5 |= DDR_MR5_CA_PARITY_LAT_4_CLK;
  1196 + } else if (mclk_ps >= 833) {
  1197 + /* for DDR4-2400 */
  1198 + esdmode5 |= DDR_MR5_CA_PARITY_LAT_5_CLK;
  1199 + } else {
  1200 + printf("parity: mclk_ps = %d not supported\n",
  1201 + mclk_ps);
  1202 + }
  1203 + }
  1204 +
1173 1205 switch (i) {
1174 1206 case 1:
1175 1207 ddr->ddr_sdram_mode_11 = (0
1176 1208  
... ... @@ -1925,12 +1957,25 @@
1925 1957 const common_timing_params_t *common_dimm)
1926 1958 {
1927 1959 unsigned int txpr, tcksre, tcksrx;
1928   - unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd;
  1960 + unsigned int cke_rst, cksre, cksrx, par_lat = 0, cs_to_cmd;
  1961 + const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
1929 1962  
1930 1963 txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000));
1931 1964 tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
1932 1965 tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
1933   - par_lat = 0;
  1966 +
  1967 + if (ddr->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) {
  1968 + if (mclk_ps >= 935) {
  1969 + /* parity latency 4 clocks in case of 1600/1866/2133 */
  1970 + par_lat = 4;
  1971 + } else if (mclk_ps >= 833) {
  1972 + /* parity latency 5 clocks for DDR4-2400 */
  1973 + par_lat = 5;
  1974 + } else {
  1975 + printf("parity: mclk_ps = %d not supported\n", mclk_ps);
  1976 + }
  1977 + }
  1978 +
1934 1979 cs_to_cmd = 0;
1935 1980  
1936 1981 if (txpr <= 200)
drivers/ddr/fsl/options.c
... ... @@ -1002,8 +1002,19 @@
1002 1002 popts->twot_en = 0;
1003 1003 popts->threet_en = 0;
1004 1004  
1005   - /* for RDIMM, address parity enable */
1006   - popts->ap_en = 1;
  1005 + /* for RDIMM and DDR4 UDIMM/discrete memory, address parity enable */
  1006 + if (popts->registered_dimm_en)
  1007 + popts->ap_en = 1; /* 0 = disable, 1 = enable */
  1008 + else
  1009 + popts->ap_en = 0; /* disabled for DDR4 UDIMM/discrete default */
  1010 +
  1011 + if (hwconfig_sub_f("fsl_ddr", "parity", buf)) {
  1012 + if (hwconfig_subarg_cmp_f("fsl_ddr", "parity", "on", buf)) {
  1013 + if (popts->registered_dimm_en ||
  1014 + (CONFIG_FSL_SDRAM_TYPE == SDRAM_TYPE_DDR4))
  1015 + popts->ap_en = 1;
  1016 + }
  1017 + }
1007 1018  
1008 1019 /*
1009 1020 * BSTTOPRE precharge interval
include/fsl_ddr_sdram.h
... ... @@ -123,6 +123,7 @@
123 123  
124 124 #define SDRAM_CFG2_FRC_SR 0x80000000
125 125 #define SDRAM_CFG2_D_INIT 0x00000010
  126 +#define SDRAM_CFG2_AP_EN 0x00000020
126 127 #define SDRAM_CFG2_ODT_CFG_MASK 0x00600000
127 128 #define SDRAM_CFG2_ODT_NEVER 0
128 129 #define SDRAM_CFG2_ODT_ONLY_WRITE 1
... ... @@ -177,6 +178,14 @@
177 178 #define DDR_CDR2_VREF_TRAIN_EN 0x00000080
178 179 #define DDR_CDR2_VREF_RANGE_2 0x00000040
179 180  
  181 +/* DDR ERR_DISABLE */
  182 +#define DDR_ERR_DISABLE_APED (1 << 8) /* Address parity error disable */
  183 +
  184 +/* Mode Registers */
  185 +#define DDR_MR5_CA_PARITY_LAT_4_CLK 0x1 /* for DDR4-1600/1866/2133 */
  186 +#define DDR_MR5_CA_PARITY_LAT_5_CLK 0x2 /* for DDR4-2400 */
  187 +
  188 +
180 189 #if (defined(CONFIG_SYS_FSL_DDR_VER) && \
181 190 (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7))
182 191 #ifdef CONFIG_SYS_FSL_DDR3L
... ... @@ -343,7 +352,7 @@
343 352 /* mirrior DIMMs for DDR3 */
344 353 unsigned int mirrored_dimm;
345 354 unsigned int quad_rank_present;
346   - unsigned int ap_en; /* address parity enable for RDIMM */
  355 + unsigned int ap_en; /* address parity enable for RDIMM/DDR4-UDIMM */
347 356 unsigned int x4_en; /* enable x4 devices */
348 357  
349 358 /* Global Timing Parameters */