]>
Commit | Line | Data |
---|---|---|
34e026f9 | 1 | /* |
9f9f0093 | 2 | * Copyright 2014-2015 Freescale Semiconductor, Inc. |
34e026f9 YS |
3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <asm/io.h> | |
9 | #include <fsl_ddr_sdram.h> | |
10 | #include <asm/processor.h> | |
8340e7ac | 11 | #include <fsl_immap.h> |
34e026f9 | 12 | #include <fsl_ddr.h> |
a46b1852 | 13 | #include <fsl_errata.h> |
457e51cf SG |
14 | #if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \ |
15 | defined(CONFIG_ARM) | |
6e2941d7 SG |
16 | #include <asm/arch/clock.h> |
17 | #endif | |
34e026f9 | 18 | |
dd8e740c SL |
19 | #if defined(CONFIG_SYS_FSL_ERRATUM_A008511) | \ |
20 | defined(CONFIG_SYS_FSL_ERRATUM_A009803) | |
9f9f0093 YS |
21 | static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits) |
22 | { | |
23 | int timeout = 1000; | |
24 | ||
25 | ddr_out32(ptr, value); | |
26 | ||
27 | while (ddr_in32(ptr) & bits) { | |
28 | udelay(100); | |
29 | timeout--; | |
30 | } | |
31 | if (timeout <= 0) | |
dd8e740c | 32 | puts("Error: wait for clear timeout.\n"); |
9f9f0093 | 33 | } |
dd8e740c | 34 | #endif |
9f9f0093 | 35 | |
34e026f9 YS |
36 | #if (CONFIG_CHIP_SELECTS_PER_CTRL > 4) |
37 | #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL | |
38 | #endif | |
39 | ||
40 | /* | |
41 | * regs has the to-be-set values for DDR controller registers | |
42 | * ctrl_num is the DDR controller number | |
43 | * step: 0 goes through the initialization in one pass | |
44 | * 1 sets registers and returns before enabling controller | |
45 | * 2 resumes from step 1 and continues to initialize | |
46 | * Dividing the initialization to two steps to deassert DDR reset signal | |
47 | * to comply with JEDEC specs for RDIMMs. | |
48 | */ | |
49 | void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, | |
50 | unsigned int ctrl_num, int step) | |
51 | { | |
52 | unsigned int i, bus_width; | |
53 | struct ccsr_ddr __iomem *ddr; | |
5a17b8b5 | 54 | u32 temp32; |
34e026f9 YS |
55 | u32 total_gb_size_per_controller; |
56 | int timeout; | |
2f0dcf2d | 57 | |
9f9f0093 | 58 | #ifdef CONFIG_SYS_FSL_ERRATUM_A008511 |
2f0dcf2d | 59 | u32 mr6; |
7cc07998 YS |
60 | u32 vref_seq1[3] = {0x80, 0x96, 0x16}; /* for range 1 */ |
61 | u32 vref_seq2[3] = {0xc0, 0xf0, 0x70}; /* for range 2 */ | |
62 | u32 *vref_seq = vref_seq1; | |
9f9f0093 | 63 | #endif |
4516ff81 YS |
64 | #ifdef CONFIG_FSL_DDR_BIST |
65 | u32 mtcr, err_detect, err_sbe; | |
66 | u32 cs0_bnds, cs1_bnds, cs2_bnds, cs3_bnds, cs0_config; | |
67 | #endif | |
68 | #ifdef CONFIG_FSL_DDR_BIST | |
69 | char buffer[CONFIG_SYS_CBSIZE]; | |
5a17b8b5 | 70 | #endif |
34e026f9 YS |
71 | switch (ctrl_num) { |
72 | case 0: | |
73 | ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; | |
74 | break; | |
51370d56 | 75 | #if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1) |
34e026f9 YS |
76 | case 1: |
77 | ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; | |
78 | break; | |
79 | #endif | |
51370d56 | 80 | #if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2) |
34e026f9 YS |
81 | case 2: |
82 | ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; | |
83 | break; | |
84 | #endif | |
51370d56 | 85 | #if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3) |
34e026f9 YS |
86 | case 3: |
87 | ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; | |
88 | break; | |
89 | #endif | |
90 | default: | |
91 | printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num); | |
92 | return; | |
93 | } | |
94 | ||
95 | if (step == 2) | |
96 | goto step2; | |
97 | ||
98 | if (regs->ddr_eor) | |
99 | ddr_out32(&ddr->eor, regs->ddr_eor); | |
100 | ||
101 | ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl); | |
102 | ||
103 | for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { | |
104 | if (i == 0) { | |
105 | ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds); | |
106 | ddr_out32(&ddr->cs0_config, regs->cs[i].config); | |
107 | ddr_out32(&ddr->cs0_config_2, regs->cs[i].config_2); | |
108 | ||
109 | } else if (i == 1) { | |
110 | ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds); | |
111 | ddr_out32(&ddr->cs1_config, regs->cs[i].config); | |
112 | ddr_out32(&ddr->cs1_config_2, regs->cs[i].config_2); | |
113 | ||
114 | } else if (i == 2) { | |
115 | ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds); | |
116 | ddr_out32(&ddr->cs2_config, regs->cs[i].config); | |
117 | ddr_out32(&ddr->cs2_config_2, regs->cs[i].config_2); | |
118 | ||
119 | } else if (i == 3) { | |
120 | ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds); | |
121 | ddr_out32(&ddr->cs3_config, regs->cs[i].config); | |
122 | ddr_out32(&ddr->cs3_config_2, regs->cs[i].config_2); | |
123 | } | |
124 | } | |
125 | ||
126 | ddr_out32(&ddr->timing_cfg_3, regs->timing_cfg_3); | |
127 | ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0); | |
128 | ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1); | |
129 | ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2); | |
130 | ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4); | |
131 | ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5); | |
132 | ddr_out32(&ddr->timing_cfg_6, regs->timing_cfg_6); | |
133 | ddr_out32(&ddr->timing_cfg_7, regs->timing_cfg_7); | |
134 | ddr_out32(&ddr->timing_cfg_8, regs->timing_cfg_8); | |
135 | ddr_out32(&ddr->timing_cfg_9, regs->timing_cfg_9); | |
136 | ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl); | |
137 | ddr_out32(&ddr->dq_map_0, regs->dq_map_0); | |
138 | ddr_out32(&ddr->dq_map_1, regs->dq_map_1); | |
139 | ddr_out32(&ddr->dq_map_2, regs->dq_map_2); | |
140 | ddr_out32(&ddr->dq_map_3, regs->dq_map_3); | |
34e026f9 YS |
141 | ddr_out32(&ddr->sdram_cfg_3, regs->ddr_sdram_cfg_3); |
142 | ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode); | |
143 | ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2); | |
144 | ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3); | |
145 | ddr_out32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4); | |
146 | ddr_out32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5); | |
147 | ddr_out32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6); | |
148 | ddr_out32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7); | |
149 | ddr_out32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8); | |
150 | ddr_out32(&ddr->sdram_mode_9, regs->ddr_sdram_mode_9); | |
151 | ddr_out32(&ddr->sdram_mode_10, regs->ddr_sdram_mode_10); | |
152 | ddr_out32(&ddr->sdram_mode_11, regs->ddr_sdram_mode_11); | |
153 | ddr_out32(&ddr->sdram_mode_12, regs->ddr_sdram_mode_12); | |
154 | ddr_out32(&ddr->sdram_mode_13, regs->ddr_sdram_mode_13); | |
155 | ddr_out32(&ddr->sdram_mode_14, regs->ddr_sdram_mode_14); | |
156 | ddr_out32(&ddr->sdram_mode_15, regs->ddr_sdram_mode_15); | |
157 | ddr_out32(&ddr->sdram_mode_16, regs->ddr_sdram_mode_16); | |
158 | ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl); | |
a994b3de SL |
159 | #ifdef CONFIG_SYS_FSL_ERRATUM_A009663 |
160 | ddr_out32(&ddr->sdram_interval, | |
161 | regs->ddr_sdram_interval & ~SDRAM_INTERVAL_BSTOPRE); | |
162 | #else | |
34e026f9 | 163 | ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval); |
a994b3de | 164 | #endif |
34e026f9 | 165 | ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init); |
34e026f9 YS |
166 | ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl); |
167 | #ifndef CONFIG_SYS_FSL_DDR_EMU | |
168 | /* | |
169 | * Skip these two registers if running on emulator | |
170 | * because emulator doesn't have skew between bytes. | |
171 | */ | |
172 | ||
173 | if (regs->ddr_wrlvl_cntl_2) | |
174 | ddr_out32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2); | |
175 | if (regs->ddr_wrlvl_cntl_3) | |
176 | ddr_out32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3); | |
177 | #endif | |
178 | ||
179 | ddr_out32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr); | |
180 | ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1); | |
181 | ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2); | |
182 | ddr_out32(&ddr->ddr_sdram_rcw_3, regs->ddr_sdram_rcw_3); | |
183 | ddr_out32(&ddr->ddr_sdram_rcw_4, regs->ddr_sdram_rcw_4); | |
184 | ddr_out32(&ddr->ddr_sdram_rcw_5, regs->ddr_sdram_rcw_5); | |
185 | ddr_out32(&ddr->ddr_sdram_rcw_6, regs->ddr_sdram_rcw_6); | |
186 | ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1); | |
a7787b78 TY |
187 | #ifdef CONFIG_DEEP_SLEEP |
188 | if (is_warm_boot()) { | |
189 | ddr_out32(&ddr->sdram_cfg_2, | |
190 | regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); | |
191 | ddr_out32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE); | |
192 | ddr_out32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA); | |
193 | ||
194 | /* DRAM VRef will not be trained */ | |
195 | ddr_out32(&ddr->ddr_cdr2, | |
196 | regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN); | |
197 | } else | |
198 | #endif | |
199 | { | |
200 | ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); | |
201 | ddr_out32(&ddr->init_addr, regs->ddr_init_addr); | |
202 | ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); | |
203 | ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2); | |
204 | } | |
dd8e740c SL |
205 | |
206 | #ifdef CONFIG_SYS_FSL_ERRATUM_A009803 | |
207 | /* part 1 of 2 */ | |
d3674046 SL |
208 | if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { |
209 | if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) { /* for RDIMM */ | |
210 | ddr_out32(&ddr->ddr_sdram_rcw_2, | |
211 | regs->ddr_sdram_rcw_2 & ~0x0f000000); | |
212 | } | |
213 | ddr_out32(&ddr->err_disable, regs->err_disable | | |
214 | DDR_ERR_DISABLE_APED); | |
dd8e740c | 215 | } |
dd8e740c | 216 | #else |
34e026f9 | 217 | ddr_out32(&ddr->err_disable, regs->err_disable); |
dd8e740c | 218 | #endif |
34e026f9 | 219 | ddr_out32(&ddr->err_int_en, regs->err_int_en); |
b406731a | 220 | for (i = 0; i < 64; i++) { |
34e026f9 YS |
221 | if (regs->debug[i]) { |
222 | debug("Write to debug_%d as %08x\n", | |
223 | i+1, regs->debug[i]); | |
224 | ddr_out32(&ddr->debug[i], regs->debug[i]); | |
225 | } | |
226 | } | |
227 | ||
9f9f0093 YS |
228 | #ifdef CONFIG_SYS_FSL_ERRATUM_A008511 |
229 | /* Part 1 of 2 */ | |
9f9f0093 YS |
230 | if (fsl_ddr_get_version(ctrl_num) == 0x50200) { |
231 | /* Disable DRAM VRef training */ | |
232 | ddr_out32(&ddr->ddr_cdr2, | |
233 | regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN); | |
4a68489e SL |
234 | /* disable transmit bit deskew */ |
235 | temp32 = ddr_in32(&ddr->debug[28]); | |
236 | temp32 |= DDR_TX_BD_DIS; | |
237 | ddr_out32(&ddr->debug[28], temp32); | |
9f9f0093 | 238 | ddr_out32(&ddr->debug[25], 0x9000); |
4baa38c5 YS |
239 | } else if (fsl_ddr_get_version(ctrl_num) == 0x50201) { |
240 | /* Output enable forced off */ | |
241 | ddr_out32(&ddr->debug[37], 1 << 31); | |
242 | /* Enable Vref training */ | |
243 | ddr_out32(&ddr->ddr_cdr2, | |
244 | regs->ddr_cdr2 | DDR_CDR2_VREF_TRAIN_EN); | |
245 | } else { | |
246 | debug("Erratum A008511 doesn't apply.\n"); | |
9f9f0093 YS |
247 | } |
248 | #endif | |
0d3972cf | 249 | |
4baa38c5 YS |
250 | #if defined(CONFIG_SYS_FSL_ERRATUM_A009803) || \ |
251 | defined(CONFIG_SYS_FSL_ERRATUM_A008511) | |
252 | /* Disable D_INIT */ | |
253 | ddr_out32(&ddr->sdram_cfg_2, | |
254 | regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); | |
255 | #endif | |
256 | ||
5fc62fe5 SL |
257 | #ifdef CONFIG_SYS_FSL_ERRATUM_A009801 |
258 | temp32 = ddr_in32(&ddr->debug[25]); | |
259 | temp32 &= ~DDR_CAS_TO_PRE_SUB_MASK; | |
260 | temp32 |= 9 << DDR_CAS_TO_PRE_SUB_SHIFT; | |
261 | ddr_out32(&ddr->debug[25], temp32); | |
262 | #endif | |
263 | ||
019a147b | 264 | #ifdef CONFIG_SYS_FSL_ERRATUM_A010165 |
5a17b8b5 SL |
265 | temp32 = get_ddr_freq(ctrl_num) / 1000000; |
266 | if ((temp32 > 1900) && (temp32 < 2300)) { | |
267 | temp32 = ddr_in32(&ddr->debug[28]); | |
268 | ddr_out32(&ddr->debug[28], temp32 | 0x000a0000); | |
019a147b SL |
269 | } |
270 | #endif | |
34e026f9 YS |
271 | /* |
272 | * For RDIMMs, JEDEC spec requires clocks to be stable before reset is | |
273 | * deasserted. Clocks start when any chip select is enabled and clock | |
274 | * control register is set. Because all DDR components are connected to | |
275 | * one reset signal, this needs to be done in two steps. Step 1 is to | |
276 | * get the clocks started. Step 2 resumes after reset signal is | |
277 | * deasserted. | |
278 | */ | |
279 | if (step == 1) { | |
280 | udelay(200); | |
281 | return; | |
282 | } | |
283 | ||
284 | step2: | |
285 | /* Set, but do not enable the memory */ | |
5a17b8b5 SL |
286 | temp32 = regs->ddr_sdram_cfg; |
287 | temp32 &= ~(SDRAM_CFG_MEM_EN); | |
288 | ddr_out32(&ddr->sdram_cfg, temp32); | |
34e026f9 YS |
289 | |
290 | /* | |
291 | * 500 painful micro-seconds must elapse between | |
292 | * the DDR clock setup and the DDR config enable. | |
293 | * DDR2 need 200 us, and DDR3 need 500 us from spec, | |
294 | * we choose the max, that is 500 us for all of case. | |
295 | */ | |
296 | udelay(500); | |
8340e7ac YS |
297 | mb(); |
298 | isb(); | |
34e026f9 | 299 | |
a7787b78 TY |
300 | #ifdef CONFIG_DEEP_SLEEP |
301 | if (is_warm_boot()) { | |
302 | /* enter self-refresh */ | |
5a17b8b5 SL |
303 | temp32 = ddr_in32(&ddr->sdram_cfg_2); |
304 | temp32 |= SDRAM_CFG2_FRC_SR; | |
305 | ddr_out32(&ddr->sdram_cfg_2, temp32); | |
a7787b78 TY |
306 | /* do board specific memory setup */ |
307 | board_mem_sleep_setup(); | |
308 | ||
5a17b8b5 | 309 | temp32 = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI); |
a7787b78 TY |
310 | } else |
311 | #endif | |
5a17b8b5 | 312 | temp32 = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; |
34e026f9 | 313 | /* Let the controller go */ |
5a17b8b5 | 314 | ddr_out32(&ddr->sdram_cfg, temp32 | SDRAM_CFG_MEM_EN); |
8340e7ac YS |
315 | mb(); |
316 | isb(); | |
34e026f9 | 317 | |
dd8e740c SL |
318 | #if defined(CONFIG_SYS_FSL_ERRATUM_A008511) || \ |
319 | defined(CONFIG_SYS_FSL_ERRATUM_A009803) | |
9f9f0093 | 320 | /* Part 2 of 2 */ |
4baa38c5 YS |
321 | timeout = 40; |
322 | /* Wait for idle. D_INIT needs to be cleared earlier, or timeout */ | |
323 | while (!(ddr_in32(&ddr->debug[1]) & 0x2) && | |
324 | (timeout > 0)) { | |
325 | udelay(1000); | |
326 | timeout--; | |
327 | } | |
328 | if (timeout <= 0) { | |
329 | printf("Controler %d timeout, debug_2 = %x\n", | |
330 | ctrl_num, ddr_in32(&ddr->debug[1])); | |
331 | } | |
7cc07998 | 332 | |
dd8e740c | 333 | #ifdef CONFIG_SYS_FSL_ERRATUM_A008511 |
4baa38c5 YS |
334 | /* This erraum only applies to verion 5.2.0 */ |
335 | if (fsl_ddr_get_version(ctrl_num) == 0x50200) { | |
7cc07998 YS |
336 | /* The vref setting sequence is different for range 2 */ |
337 | if (regs->ddr_cdr2 & DDR_CDR2_VREF_RANGE_2) | |
338 | vref_seq = vref_seq2; | |
339 | ||
9f9f0093 YS |
340 | /* Set VREF */ |
341 | for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { | |
342 | if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN)) | |
343 | continue; | |
344 | ||
345 | mr6 = (regs->ddr_sdram_mode_10 >> 16) | | |
346 | MD_CNTL_MD_EN | | |
347 | MD_CNTL_CS_SEL(i) | | |
348 | MD_CNTL_MD_SEL(6) | | |
349 | 0x00200000; | |
7cc07998 | 350 | temp32 = mr6 | vref_seq[0]; |
9f9f0093 YS |
351 | set_wait_for_bits_clear(&ddr->sdram_md_cntl, |
352 | temp32, MD_CNTL_MD_EN); | |
353 | udelay(1); | |
354 | debug("MR6 = 0x%08x\n", temp32); | |
7cc07998 | 355 | temp32 = mr6 | vref_seq[1]; |
9f9f0093 YS |
356 | set_wait_for_bits_clear(&ddr->sdram_md_cntl, |
357 | temp32, MD_CNTL_MD_EN); | |
358 | udelay(1); | |
359 | debug("MR6 = 0x%08x\n", temp32); | |
7cc07998 | 360 | temp32 = mr6 | vref_seq[2]; |
9f9f0093 YS |
361 | set_wait_for_bits_clear(&ddr->sdram_md_cntl, |
362 | temp32, MD_CNTL_MD_EN); | |
363 | udelay(1); | |
364 | debug("MR6 = 0x%08x\n", temp32); | |
365 | } | |
366 | ddr_out32(&ddr->sdram_md_cntl, 0); | |
4a68489e SL |
367 | temp32 = ddr_in32(&ddr->debug[28]); |
368 | temp32 &= ~DDR_TX_BD_DIS; /* Enable deskew */ | |
369 | ddr_out32(&ddr->debug[28], temp32); | |
9f9f0093 YS |
370 | ddr_out32(&ddr->debug[1], 0x400); /* restart deskew */ |
371 | /* wait for idle */ | |
7cc07998 | 372 | timeout = 40; |
9f9f0093 YS |
373 | while (!(ddr_in32(&ddr->debug[1]) & 0x2) && |
374 | (timeout > 0)) { | |
7cc07998 | 375 | udelay(1000); |
9f9f0093 YS |
376 | timeout--; |
377 | } | |
378 | if (timeout <= 0) { | |
379 | printf("Controler %d timeout, debug_2 = %x\n", | |
380 | ctrl_num, ddr_in32(&ddr->debug[1])); | |
381 | } | |
4baa38c5 | 382 | } |
9f9f0093 YS |
383 | #endif /* CONFIG_SYS_FSL_ERRATUM_A008511 */ |
384 | ||
dd8e740c | 385 | #ifdef CONFIG_SYS_FSL_ERRATUM_A009803 |
4baa38c5 YS |
386 | if (regs->ddr_sdram_cfg_2 & SDRAM_CFG2_AP_EN) { |
387 | /* if it's RDIMM */ | |
388 | if (regs->ddr_sdram_cfg & SDRAM_CFG_RD_EN) { | |
389 | for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { | |
390 | if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN)) | |
391 | continue; | |
392 | set_wait_for_bits_clear(&ddr->sdram_md_cntl, | |
393 | MD_CNTL_MD_EN | | |
394 | MD_CNTL_CS_SEL(i) | | |
395 | 0x070000ed, | |
396 | MD_CNTL_MD_EN); | |
397 | udelay(1); | |
dd8e740c | 398 | } |
d3674046 | 399 | } |
4baa38c5 YS |
400 | |
401 | ddr_out32(&ddr->err_disable, | |
402 | regs->err_disable & ~DDR_ERR_DISABLE_APED); | |
dd8e740c SL |
403 | } |
404 | #endif | |
4baa38c5 YS |
405 | /* Restore D_INIT */ |
406 | ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); | |
407 | #endif | |
dd8e740c | 408 | |
34e026f9 YS |
409 | total_gb_size_per_controller = 0; |
410 | for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { | |
411 | if (!(regs->cs[i].config & 0x80000000)) | |
412 | continue; | |
413 | total_gb_size_per_controller += 1 << ( | |
414 | ((regs->cs[i].config >> 14) & 0x3) + 2 + | |
415 | ((regs->cs[i].config >> 8) & 0x7) + 12 + | |
416 | ((regs->cs[i].config >> 4) & 0x3) + 0 + | |
417 | ((regs->cs[i].config >> 0) & 0x7) + 8 + | |
418 | 3 - ((regs->ddr_sdram_cfg >> 19) & 0x3) - | |
419 | 26); /* minus 26 (count of 64M) */ | |
420 | } | |
421 | if (fsl_ddr_get_intl3r() & 0x80000000) /* 3-way interleaving */ | |
422 | total_gb_size_per_controller *= 3; | |
423 | else if (regs->cs[0].config & 0x20000000) /* 2-way interleaving */ | |
424 | total_gb_size_per_controller <<= 1; | |
425 | /* | |
426 | * total memory / bus width = transactions needed | |
427 | * transactions needed / data rate = seconds | |
428 | * to add plenty of buffer, double the time | |
429 | * For example, 2GB on 666MT/s 64-bit bus takes about 402ms | |
430 | * Let's wait for 800ms | |
431 | */ | |
f80d6472 | 432 | bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK) |
34e026f9 YS |
433 | >> SDRAM_CFG_DBW_SHIFT); |
434 | timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 / | |
03e664d8 | 435 | (get_ddr_freq(ctrl_num) >> 20)) << 2; |
34e026f9 YS |
436 | total_gb_size_per_controller >>= 4; /* shift down to gb size */ |
437 | debug("total %d GB\n", total_gb_size_per_controller); | |
438 | debug("Need to wait up to %d * 10ms\n", timeout); | |
439 | ||
440 | /* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done. */ | |
441 | while ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) && | |
442 | (timeout >= 0)) { | |
443 | udelay(10000); /* throttle polling rate */ | |
444 | timeout--; | |
445 | } | |
446 | ||
447 | if (timeout <= 0) | |
448 | printf("Waiting for D_INIT timeout. Memory may not work.\n"); | |
a994b3de SL |
449 | |
450 | #ifdef CONFIG_SYS_FSL_ERRATUM_A009663 | |
451 | ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval); | |
452 | #endif | |
453 | ||
a7787b78 TY |
454 | #ifdef CONFIG_DEEP_SLEEP |
455 | if (is_warm_boot()) { | |
456 | /* exit self-refresh */ | |
5a17b8b5 SL |
457 | temp32 = ddr_in32(&ddr->sdram_cfg_2); |
458 | temp32 &= ~SDRAM_CFG2_FRC_SR; | |
459 | ddr_out32(&ddr->sdram_cfg_2, temp32); | |
a7787b78 TY |
460 | } |
461 | #endif | |
4516ff81 YS |
462 | |
463 | #ifdef CONFIG_FSL_DDR_BIST | |
464 | #define BIST_PATTERN1 0xFFFFFFFF | |
465 | #define BIST_PATTERN2 0x0 | |
466 | #define BIST_CR 0x80010000 | |
467 | #define BIST_CR_EN 0x80000000 | |
468 | #define BIST_CR_STAT 0x00000001 | |
469 | #define CTLR_INTLV_MASK 0x20000000 | |
470 | /* Perform build-in test on memory. Three-way interleaving is not yet | |
471 | * supported by this code. */ | |
00caae6d | 472 | if (env_get_f("ddr_bist", buffer, CONFIG_SYS_CBSIZE) >= 0) { |
4516ff81 YS |
473 | puts("Running BIST test. This will take a while..."); |
474 | cs0_config = ddr_in32(&ddr->cs0_config); | |
da305b9f YS |
475 | cs0_bnds = ddr_in32(&ddr->cs0_bnds); |
476 | cs1_bnds = ddr_in32(&ddr->cs1_bnds); | |
477 | cs2_bnds = ddr_in32(&ddr->cs2_bnds); | |
478 | cs3_bnds = ddr_in32(&ddr->cs3_bnds); | |
4516ff81 | 479 | if (cs0_config & CTLR_INTLV_MASK) { |
4516ff81 | 480 | /* set bnds to non-interleaving */ |
da305b9f YS |
481 | ddr_out32(&ddr->cs0_bnds, (cs0_bnds & 0xfffefffe) >> 1); |
482 | ddr_out32(&ddr->cs1_bnds, (cs1_bnds & 0xfffefffe) >> 1); | |
483 | ddr_out32(&ddr->cs2_bnds, (cs2_bnds & 0xfffefffe) >> 1); | |
484 | ddr_out32(&ddr->cs3_bnds, (cs3_bnds & 0xfffefffe) >> 1); | |
4516ff81 YS |
485 | } |
486 | ddr_out32(&ddr->mtp1, BIST_PATTERN1); | |
487 | ddr_out32(&ddr->mtp2, BIST_PATTERN1); | |
488 | ddr_out32(&ddr->mtp3, BIST_PATTERN2); | |
489 | ddr_out32(&ddr->mtp4, BIST_PATTERN2); | |
490 | ddr_out32(&ddr->mtp5, BIST_PATTERN1); | |
491 | ddr_out32(&ddr->mtp6, BIST_PATTERN1); | |
492 | ddr_out32(&ddr->mtp7, BIST_PATTERN2); | |
493 | ddr_out32(&ddr->mtp8, BIST_PATTERN2); | |
494 | ddr_out32(&ddr->mtp9, BIST_PATTERN1); | |
495 | ddr_out32(&ddr->mtp10, BIST_PATTERN2); | |
496 | mtcr = BIST_CR; | |
497 | ddr_out32(&ddr->mtcr, mtcr); | |
498 | timeout = 100; | |
499 | while (timeout > 0 && (mtcr & BIST_CR_EN)) { | |
500 | mdelay(1000); | |
501 | timeout--; | |
502 | mtcr = ddr_in32(&ddr->mtcr); | |
503 | } | |
504 | if (timeout <= 0) | |
505 | puts("Timeout\n"); | |
506 | else | |
507 | puts("Done\n"); | |
508 | err_detect = ddr_in32(&ddr->err_detect); | |
509 | err_sbe = ddr_in32(&ddr->err_sbe); | |
510 | if (mtcr & BIST_CR_STAT) { | |
511 | printf("BIST test failed on controller %d.\n", | |
512 | ctrl_num); | |
513 | } | |
514 | if (err_detect || (err_sbe & 0xffff)) { | |
515 | printf("ECC error detected on controller %d.\n", | |
516 | ctrl_num); | |
517 | } | |
518 | ||
519 | if (cs0_config & CTLR_INTLV_MASK) { | |
520 | /* restore bnds registers */ | |
da305b9f YS |
521 | ddr_out32(&ddr->cs0_bnds, cs0_bnds); |
522 | ddr_out32(&ddr->cs1_bnds, cs1_bnds); | |
523 | ddr_out32(&ddr->cs2_bnds, cs2_bnds); | |
524 | ddr_out32(&ddr->cs3_bnds, cs3_bnds); | |
4516ff81 YS |
525 | } |
526 | } | |
527 | #endif | |
34e026f9 | 528 | } |