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