Commit eb118807a4c1778bda6294c36e379711cb08e198
Committed by
York Sun
1 parent
5e8e27b743
Exists in
v2017.01-smarct4x
and in
29 other branches
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
doc/README.fsl-ddr
... | ... | @@ -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 */ |