xref: /rk3399_ARM-atf/drivers/nxp/ddr/nxp-ddr/ddrc.c (revision 4bd8c929b4bc6e1731c2892b38d4a8c43e8e89dc)
1b35ce0c4SPankaj Gupta /*
2b35ce0c4SPankaj Gupta  * Copyright 2021 NXP
3b35ce0c4SPankaj Gupta  *
4b35ce0c4SPankaj Gupta  * SPDX-License-Identifier: BSD-3-Clause
5b35ce0c4SPankaj Gupta  *
6b35ce0c4SPankaj Gupta  */
7b35ce0c4SPankaj Gupta 
8b35ce0c4SPankaj Gupta #include <errno.h>
9b35ce0c4SPankaj Gupta #include <stdbool.h>
10b35ce0c4SPankaj Gupta #include <stdint.h>
11b35ce0c4SPankaj Gupta #include <stdio.h>
12b35ce0c4SPankaj Gupta #include <stdlib.h>
13b35ce0c4SPankaj Gupta 
14b35ce0c4SPankaj Gupta #include <common/debug.h>
15b35ce0c4SPankaj Gupta #include <ddr.h>
16b35ce0c4SPankaj Gupta #include <drivers/delay_timer.h>
17b35ce0c4SPankaj Gupta #include <immap.h>
18b35ce0c4SPankaj Gupta 
19b35ce0c4SPankaj Gupta #define BIST_CR		0x80060000
20b35ce0c4SPankaj Gupta #define BIST_CR_EN	0x80000000
21b35ce0c4SPankaj Gupta #define BIST_CR_STAT	0x00000001
22b35ce0c4SPankaj Gupta #define CTLR_INTLV_MASK	0x20000000
23b35ce0c4SPankaj Gupta 
24b35ce0c4SPankaj Gupta #pragma weak run_bist
25b35ce0c4SPankaj Gupta 
run_bist(void)26b35ce0c4SPankaj Gupta bool run_bist(void)
27b35ce0c4SPankaj Gupta {
28b35ce0c4SPankaj Gupta #ifdef BIST_EN
29b35ce0c4SPankaj Gupta 	return true;
30b35ce0c4SPankaj Gupta #else
31b35ce0c4SPankaj Gupta 	return false;
32b35ce0c4SPankaj Gupta #endif
33b35ce0c4SPankaj Gupta }
34b35ce0c4SPankaj Gupta 
35b35ce0c4SPankaj Gupta /*
36b35ce0c4SPankaj Gupta  * Perform build-in test on memory
37b35ce0c4SPankaj Gupta  * timeout value in 10ms
38b35ce0c4SPankaj Gupta  */
bist(const struct ccsr_ddr * ddr,int timeout)39b35ce0c4SPankaj Gupta int bist(const struct ccsr_ddr *ddr, int timeout)
40b35ce0c4SPankaj Gupta {
41b35ce0c4SPankaj Gupta 	const unsigned int test_pattern[10] = {
42b35ce0c4SPankaj Gupta 		0xffffffff,
43b35ce0c4SPankaj Gupta 		0x00000000,
44b35ce0c4SPankaj Gupta 		0xaaaaaaaa,
45b35ce0c4SPankaj Gupta 		0x55555555,
46b35ce0c4SPankaj Gupta 		0xcccccccc,
47b35ce0c4SPankaj Gupta 		0x33333333,
48b35ce0c4SPankaj Gupta 		0x12345678,
49b35ce0c4SPankaj Gupta 		0xabcdef01,
50b35ce0c4SPankaj Gupta 		0xaa55aa55,
51b35ce0c4SPankaj Gupta 		0x55aa55aa
52b35ce0c4SPankaj Gupta 	};
53b35ce0c4SPankaj Gupta 	unsigned int mtcr, err_detect, err_sbe;
54b35ce0c4SPankaj Gupta 	unsigned int cs0_config;
55b35ce0c4SPankaj Gupta 	unsigned int csn_bnds[4];
56b35ce0c4SPankaj Gupta 	int ret = 0;
57b35ce0c4SPankaj Gupta 	uint32_t i;
58b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC
59b35ce0c4SPankaj Gupta 	uint32_t dec_9 = ddr_in32(&ddr->dec[9]);
60b35ce0c4SPankaj Gupta 	uint32_t pos = 0U;
61b35ce0c4SPankaj Gupta 	uint32_t map_save = 0U;
62b35ce0c4SPankaj Gupta 	uint32_t temp32 = 0U;
63b35ce0c4SPankaj Gupta 	uint32_t map, shift, highest;
64b35ce0c4SPankaj Gupta #endif
65b35ce0c4SPankaj Gupta 
66b35ce0c4SPankaj Gupta 	cs0_config = ddr_in32(&ddr->csn_cfg[0]);
67b35ce0c4SPankaj Gupta 	if ((cs0_config & CTLR_INTLV_MASK) != 0U) {
68b35ce0c4SPankaj Gupta 		/* set bnds to non-interleaving */
69b35ce0c4SPankaj Gupta 		for (i = 0U; i < 4U; i++) {
70b35ce0c4SPankaj Gupta 			csn_bnds[i] = ddr_in32(&ddr->bnds[i].a);
71b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->bnds[i].a,
72b35ce0c4SPankaj Gupta 				  (csn_bnds[i] & U(0xfffefffe)) >> 1U);
73b35ce0c4SPankaj Gupta 		}
74b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->csn_cfg[0], cs0_config & ~CTLR_INTLV_MASK);
75b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC
76b35ce0c4SPankaj Gupta 		if ((dec_9 & 0x1U) != 0U) {
77b35ce0c4SPankaj Gupta 			highest = (dec_9 >> 26U) == U(0x3F) ? 0U : dec_9 >> 26U;
78b35ce0c4SPankaj Gupta 			pos = 37U;
79b35ce0c4SPankaj Gupta 			for (i = 0U; i < 36U; i++) {      /* Go through all 37 */
80b35ce0c4SPankaj Gupta 				if ((i % 4U) == 0U) {
81b35ce0c4SPankaj Gupta 					temp32 = ddr_in32(&ddr->dec[i >> 2U]);
82b35ce0c4SPankaj Gupta 				}
83b35ce0c4SPankaj Gupta 				shift = (3U - i % 4U) * 8U + 2U;
84b35ce0c4SPankaj Gupta 				map = (temp32 >> shift) & U(0x3F);
85b35ce0c4SPankaj Gupta 				if (map > highest && map != U(0x3F)) {
86b35ce0c4SPankaj Gupta 					highest = map;
87b35ce0c4SPankaj Gupta 					pos = i;
88b35ce0c4SPankaj Gupta 				}
89b35ce0c4SPankaj Gupta 			}
90b35ce0c4SPankaj Gupta 			debug("\nFound highest position %d, mapping to %d, ",
91b35ce0c4SPankaj Gupta 			      pos, highest);
92b35ce0c4SPankaj Gupta 			map_save = ddr_in32(&ddr->dec[pos >> 2]);
93b35ce0c4SPankaj Gupta 			shift = (3U - pos % 4U) * 8U + 2U;
94b35ce0c4SPankaj Gupta 			debug("in dec[%d], bit %d (0x%x)\n",
95b35ce0c4SPankaj Gupta 			      pos >> 2U, shift, map_save);
96b35ce0c4SPankaj Gupta 			temp32 = map_save & ~(U(0x3F) << shift);
97b35ce0c4SPankaj Gupta 			temp32 |= 8U << shift;
98b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->dec[pos >> 2U], temp32);
99b35ce0c4SPankaj Gupta 			timeout <<= 2U;
100b35ce0c4SPankaj Gupta 			debug("Increase wait time to %d ms\n", timeout * 10);
101b35ce0c4SPankaj Gupta 		}
102b35ce0c4SPankaj Gupta #endif
103b35ce0c4SPankaj Gupta 	}
104b35ce0c4SPankaj Gupta 	for (i = 0U; i < 10U; i++) {
105b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->mtp[i], test_pattern[i]);
106b35ce0c4SPankaj Gupta 	}
107b35ce0c4SPankaj Gupta 	mtcr = BIST_CR;
108b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->mtcr, mtcr);
109b35ce0c4SPankaj Gupta 	do {
110b35ce0c4SPankaj Gupta 		mdelay(10);
111b35ce0c4SPankaj Gupta 		mtcr = ddr_in32(&ddr->mtcr);
112b35ce0c4SPankaj Gupta 	} while (timeout-- > 0 && ((mtcr & BIST_CR_EN) != 0));
113b35ce0c4SPankaj Gupta 	if (timeout <= 0) {
114b35ce0c4SPankaj Gupta 		ERROR("Timeout\n");
115b35ce0c4SPankaj Gupta 	} else {
116b35ce0c4SPankaj Gupta 		debug("Timer remains %d\n", timeout);
117b35ce0c4SPankaj Gupta 	}
118b35ce0c4SPankaj Gupta 
119b35ce0c4SPankaj Gupta 	err_detect = ddr_in32(&ddr->err_detect);
120b35ce0c4SPankaj Gupta 	err_sbe = ddr_in32(&ddr->err_sbe);
121b35ce0c4SPankaj Gupta 	if (err_detect != 0U || ((err_sbe & U(0xffff)) != 0U)) {
122b35ce0c4SPankaj Gupta 		ERROR("ECC error detected\n");
123b35ce0c4SPankaj Gupta 		ret = -EIO;
124b35ce0c4SPankaj Gupta 	}
125b35ce0c4SPankaj Gupta 
126b35ce0c4SPankaj Gupta 	if ((cs0_config & CTLR_INTLV_MASK) != 0) {
127b35ce0c4SPankaj Gupta 		for (i = 0U; i < 4U; i++) {
128b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->bnds[i].a, csn_bnds[i]);
129b35ce0c4SPankaj Gupta 		}
130b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->csn_cfg[0], cs0_config);
131b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC
132b35ce0c4SPankaj Gupta 		if ((dec_9 & U(0x1)) != 0U) {
133b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->dec[pos >> 2], map_save);
134b35ce0c4SPankaj Gupta 		}
135b35ce0c4SPankaj Gupta #endif
136b35ce0c4SPankaj Gupta 	}
137b35ce0c4SPankaj Gupta 	if ((mtcr & BIST_CR_STAT) != 0) {
138b35ce0c4SPankaj Gupta 		ERROR("Built-in self test failed\n");
139b35ce0c4SPankaj Gupta 		ret = -EIO;
140b35ce0c4SPankaj Gupta 	} else {
141b35ce0c4SPankaj Gupta 		NOTICE("Build-in self test passed\n");
142b35ce0c4SPankaj Gupta 	}
143b35ce0c4SPankaj Gupta 
144b35ce0c4SPankaj Gupta 	return ret;
145b35ce0c4SPankaj Gupta }
146b35ce0c4SPankaj Gupta 
dump_ddrc(unsigned int * ddr)147b35ce0c4SPankaj Gupta void dump_ddrc(unsigned int *ddr)
148b35ce0c4SPankaj Gupta {
149b35ce0c4SPankaj Gupta #ifdef DDR_DEBUG
150b35ce0c4SPankaj Gupta 	uint32_t i;
151b35ce0c4SPankaj Gupta 	unsigned long val;
152b35ce0c4SPankaj Gupta 
153b35ce0c4SPankaj Gupta 	for (i = 0U; i < U(0x400); i++, ddr++) {
154b35ce0c4SPankaj Gupta 		val = ddr_in32(ddr);
155b35ce0c4SPankaj Gupta 		if (val != 0U) {	/* skip zeros */
156b35ce0c4SPankaj Gupta 			debug("*0x%lx = 0x%lx\n", (unsigned long)ddr, val);
157b35ce0c4SPankaj Gupta 		}
158b35ce0c4SPankaj Gupta 	}
159b35ce0c4SPankaj Gupta #endif
160b35ce0c4SPankaj Gupta }
161b35ce0c4SPankaj Gupta 
162b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009803
set_wait_for_bits_clear(const void * ptr,unsigned int value,unsigned int bits)163b35ce0c4SPankaj Gupta static void set_wait_for_bits_clear(const void *ptr,
164b35ce0c4SPankaj Gupta 				    unsigned int value,
165b35ce0c4SPankaj Gupta 				    unsigned int bits)
166b35ce0c4SPankaj Gupta {
167b35ce0c4SPankaj Gupta 	int timeout = 1000;
168b35ce0c4SPankaj Gupta 
169b35ce0c4SPankaj Gupta 	ddr_out32(ptr, value);
170b35ce0c4SPankaj Gupta 	do {
171b35ce0c4SPankaj Gupta 		udelay(100);
172b35ce0c4SPankaj Gupta 	} while (timeout-- > 0 && ((ddr_in32(ptr) & bits) != 0));
173b35ce0c4SPankaj Gupta 
174b35ce0c4SPankaj Gupta 	if (timeout <= 0) {
175b35ce0c4SPankaj Gupta 		ERROR("wait for clear timeout.\n");
176b35ce0c4SPankaj Gupta 	}
177b35ce0c4SPankaj Gupta }
178b35ce0c4SPankaj Gupta #endif
179b35ce0c4SPankaj Gupta 
180b35ce0c4SPankaj Gupta #if (DDRC_NUM_CS > 4)
181b35ce0c4SPankaj Gupta #error Invalid setting for DDRC_NUM_CS
182b35ce0c4SPankaj Gupta #endif
183b35ce0c4SPankaj Gupta 
184b35ce0c4SPankaj Gupta /*
185b35ce0c4SPankaj Gupta  * If supported by the platform, writing to DDR controller takes two
186b35ce0c4SPankaj Gupta  * passes to deassert DDR reset to comply with JEDEC specs for RDIMMs.
187b35ce0c4SPankaj Gupta  */
ddrc_set_regs(const unsigned long clk,const struct ddr_cfg_regs * regs,const struct ccsr_ddr * ddr,int twopass)188b35ce0c4SPankaj Gupta int ddrc_set_regs(const unsigned long clk,
189b35ce0c4SPankaj Gupta 		  const struct ddr_cfg_regs *regs,
190b35ce0c4SPankaj Gupta 		  const struct ccsr_ddr *ddr,
191b35ce0c4SPankaj Gupta 		  int twopass)
192b35ce0c4SPankaj Gupta {
193b35ce0c4SPankaj Gupta 	unsigned int i, bus_width;
194b35ce0c4SPankaj Gupta 	unsigned int temp_sdram_cfg;
195b35ce0c4SPankaj Gupta 	unsigned int total_mem_per_ctrl, total_mem_per_ctrl_adj;
196b35ce0c4SPankaj Gupta 	const int mod_bnds = regs->cs[0].config & CTLR_INTLV_MASK;
197b35ce0c4SPankaj Gupta 	int timeout;
198b35ce0c4SPankaj Gupta 	int ret = 0;
199b35ce0c4SPankaj Gupta #if defined(ERRATA_DDR_A009942) || defined(ERRATA_DDR_A010165)
200b35ce0c4SPankaj Gupta 	unsigned long ddr_freq;
201b35ce0c4SPankaj Gupta 	unsigned int tmp;
202b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009942
203b35ce0c4SPankaj Gupta 	unsigned int check;
204b35ce0c4SPankaj Gupta 	unsigned int cpo_min = U(0xff);
205b35ce0c4SPankaj Gupta 	unsigned int cpo_max = 0U;
206b35ce0c4SPankaj Gupta #endif
207b35ce0c4SPankaj Gupta #endif
208b35ce0c4SPankaj Gupta 
209b35ce0c4SPankaj Gupta 	if (twopass == 2U) {
210b35ce0c4SPankaj Gupta 		goto after_reset;
211b35ce0c4SPankaj Gupta 	}
212b35ce0c4SPankaj Gupta 
213b35ce0c4SPankaj Gupta 	/* Set cdr1 first in case 0.9v VDD is enabled for some SoCs*/
214b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->ddr_cdr1, regs->cdr[0]);
215b35ce0c4SPankaj Gupta 
216b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_clk_cntl, regs->clk_cntl);
217b35ce0c4SPankaj Gupta 
218b35ce0c4SPankaj Gupta 	for (i = 0U; i < DDRC_NUM_CS; i++) {
219b35ce0c4SPankaj Gupta 		if (mod_bnds != 0U) {
220b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->bnds[i].a,
221b35ce0c4SPankaj Gupta 				  (regs->cs[i].bnds & U(0xfffefffe)) >> 1U);
222b35ce0c4SPankaj Gupta 		} else {
223b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->bnds[i].a, regs->cs[i].bnds);
224b35ce0c4SPankaj Gupta 		}
225b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->csn_cfg_2[i], regs->cs[i].config_2);
226b35ce0c4SPankaj Gupta 	}
227b35ce0c4SPankaj Gupta 
228b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg[0]);
229b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg[1]);
230b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg[2]);
231b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_3, regs->timing_cfg[3]);
232b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg[4]);
233b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg[5]);
234b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_6, regs->timing_cfg[6]);
235b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_7, regs->timing_cfg[7]);
236b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_8, regs->timing_cfg[8]);
237b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->timing_cfg_9, regs->timing_cfg[9]);
238b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->zq_cntl, regs->zq_cntl);
239b35ce0c4SPankaj Gupta 	for (i = 0U; i < 4U; i++) {
240b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->dq_map[i], regs->dq_map[i]);
241b35ce0c4SPankaj Gupta 	}
242b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_cfg_3, regs->sdram_cfg[2]);
243b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode, regs->sdram_mode[0]);
244b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_2, regs->sdram_mode[1]);
245b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_3, regs->sdram_mode[2]);
246b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_4, regs->sdram_mode[3]);
247b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_5, regs->sdram_mode[4]);
248b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_6, regs->sdram_mode[5]);
249b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_7, regs->sdram_mode[6]);
250b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_8, regs->sdram_mode[7]);
251b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_9, regs->sdram_mode[8]);
252b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_10, regs->sdram_mode[9]);
253b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_11, regs->sdram_mode[10]);
254b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_12, regs->sdram_mode[11]);
255b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_13, regs->sdram_mode[12]);
256b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_14, regs->sdram_mode[13]);
257b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_15, regs->sdram_mode[14]);
258b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_mode_16, regs->sdram_mode[15]);
259b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_md_cntl, regs->md_cntl);
260b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009663
261b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_interval,
262b35ce0c4SPankaj Gupta 		  regs->interval & ~SDRAM_INTERVAL_BSTOPRE);
263b35ce0c4SPankaj Gupta #else
264b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_interval, regs->interval);
265b35ce0c4SPankaj Gupta #endif
266b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_data_init, regs->data_init);
267b35ce0c4SPankaj Gupta 	if (regs->eor != 0) {
268b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->eor, regs->eor);
269b35ce0c4SPankaj Gupta 	}
270b35ce0c4SPankaj Gupta 
271b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->wrlvl_cntl, regs->wrlvl_cntl[0]);
272b35ce0c4SPankaj Gupta #ifndef NXP_DDR_EMU
273b35ce0c4SPankaj Gupta 	/*
274b35ce0c4SPankaj Gupta 	 * Skip these two registers if running on emulator
275b35ce0c4SPankaj Gupta 	 * because emulator doesn't have skew between bytes.
276b35ce0c4SPankaj Gupta 	 */
277b35ce0c4SPankaj Gupta 
278b35ce0c4SPankaj Gupta 	if (regs->wrlvl_cntl[1] != 0) {
279b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->ddr_wrlvl_cntl_2, regs->wrlvl_cntl[1]);
280b35ce0c4SPankaj Gupta 	}
281b35ce0c4SPankaj Gupta 	if (regs->wrlvl_cntl[2] != 0) {
282b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->ddr_wrlvl_cntl_3, regs->wrlvl_cntl[2]);
283b35ce0c4SPankaj Gupta 	}
284b35ce0c4SPankaj Gupta #endif
285b35ce0c4SPankaj Gupta 
286b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);
287b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->ddr_sdram_rcw_1, regs->sdram_rcw[0]);
288b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->ddr_sdram_rcw_2, regs->sdram_rcw[1]);
289b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->ddr_sdram_rcw_3, regs->sdram_rcw[2]);
290b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->ddr_sdram_rcw_4, regs->sdram_rcw[3]);
291b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->ddr_sdram_rcw_5, regs->sdram_rcw[4]);
292b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->ddr_sdram_rcw_6, regs->sdram_rcw[5]);
293b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->ddr_cdr2, regs->cdr[1]);
294b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_cfg_2, regs->sdram_cfg[1]);
295b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->init_addr, regs->init_addr);
296b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->init_ext_addr, regs->init_ext_addr);
297b35ce0c4SPankaj Gupta 
298b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009803
299b35ce0c4SPankaj Gupta 	/* part 1 of 2 */
300b35ce0c4SPankaj Gupta 	if ((regs->sdram_cfg[1] & SDRAM_CFG2_AP_EN) != 0) {
301b35ce0c4SPankaj Gupta 		if ((regs->sdram_cfg[0] & SDRAM_CFG_RD_EN) != 0) {
302b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->ddr_sdram_rcw_2,
303b35ce0c4SPankaj Gupta 				  regs->sdram_rcw[1] & ~0xf0);
304b35ce0c4SPankaj Gupta 		}
305b35ce0c4SPankaj Gupta 
306b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->err_disable,
307b35ce0c4SPankaj Gupta 				regs->err_disable | DDR_ERR_DISABLE_APED);
308b35ce0c4SPankaj Gupta 	}
309b35ce0c4SPankaj Gupta #else
310b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->err_disable, regs->err_disable);
311b35ce0c4SPankaj Gupta #endif
312b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->err_int_en, regs->err_int_en);
313b35ce0c4SPankaj Gupta 
314b35ce0c4SPankaj Gupta 	/* For DDRC 5.05 only */
315b35ce0c4SPankaj Gupta 	if (get_ddrc_version(ddr) == 0x50500) {
316b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->tx_cfg[1], 0x1f1f1f1f);
317b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->debug[3], 0x124a02c0);
318b35ce0c4SPankaj Gupta 	}
319b35ce0c4SPankaj Gupta 
320b35ce0c4SPankaj Gupta 	for (i = 0U; i < 4U; i++) {
321b35ce0c4SPankaj Gupta 		if (regs->tx_cfg[i] != 0) {
322b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->tx_cfg[i], regs->tx_cfg[i]);
323b35ce0c4SPankaj Gupta 		}
324b35ce0c4SPankaj Gupta 	}
325b35ce0c4SPankaj Gupta 	for (i = 0U; i < 64U; i++) {
326b35ce0c4SPankaj Gupta 		if (regs->debug[i] != 0) {
327b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009942
328b35ce0c4SPankaj Gupta 			if (i == 28U) {
329b35ce0c4SPankaj Gupta 				continue;
330b35ce0c4SPankaj Gupta 			}
331b35ce0c4SPankaj Gupta #endif
332b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->debug[i], regs->debug[i]);
333b35ce0c4SPankaj Gupta 		}
334b35ce0c4SPankaj Gupta 	}
335b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC
336b35ce0c4SPankaj Gupta 	if ((regs->dec[9] & 1) != 0U) {
337b35ce0c4SPankaj Gupta 		for (i = 0U; i < 10U; i++) {
338b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->dec[i], regs->dec[i]);
339b35ce0c4SPankaj Gupta 		}
340b35ce0c4SPankaj Gupta 		if (mod_bnds != 0) {
341b35ce0c4SPankaj Gupta 			debug("Disable address decoding\n");
342b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->dec[9], 0);
343b35ce0c4SPankaj Gupta 		}
344b35ce0c4SPankaj Gupta 	}
345b35ce0c4SPankaj Gupta #endif
346b35ce0c4SPankaj Gupta 
347b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A008511
348b35ce0c4SPankaj Gupta 	/* Part 1 of 2 */
349*1b491eeaSElyes Haouas 	/* This erraum only applies to version 5.2.1 */
350b35ce0c4SPankaj Gupta 	if (get_ddrc_version(ddr) == 0x50200) {
351b35ce0c4SPankaj Gupta 		ERROR("Unsupported SoC.\n");
352b35ce0c4SPankaj Gupta 	} else if (get_ddrc_version(ddr) == 0x50201) {
353b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->debug[37], (U(1) << 31));
354b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->ddr_cdr2,
355b35ce0c4SPankaj Gupta 			  regs->cdr[1] | DDR_CDR2_VREF_TRAIN_EN);
356b35ce0c4SPankaj Gupta 	} else {
357b35ce0c4SPankaj Gupta 		debug("Erratum A008511 doesn't apply.\n");
358b35ce0c4SPankaj Gupta 	}
359b35ce0c4SPankaj Gupta #endif
360b35ce0c4SPankaj Gupta 
361b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009942
362b35ce0c4SPankaj Gupta 	ddr_freq = clk / 1000000U;
363b35ce0c4SPankaj Gupta 	tmp = ddr_in32(&ddr->debug[28]);
364b35ce0c4SPankaj Gupta 	tmp &= U(0xff0fff00);
365b35ce0c4SPankaj Gupta 	tmp |= ddr_freq <= 1333U ? U(0x0080006a) :
366b35ce0c4SPankaj Gupta 		(ddr_freq <= 1600U ? U(0x0070006f) :
367b35ce0c4SPankaj Gupta 		 (ddr_freq <= 1867U ? U(0x00700076) : U(0x0060007b)));
368b35ce0c4SPankaj Gupta 	if (regs->debug[28] != 0) {
369b35ce0c4SPankaj Gupta 		tmp &= ~0xff;
370b35ce0c4SPankaj Gupta 		tmp |= regs->debug[28] & 0xff;
371b35ce0c4SPankaj Gupta 	} else {
372b35ce0c4SPankaj Gupta 		WARN("Warning: Optimal CPO value not set.\n");
373b35ce0c4SPankaj Gupta 	}
374b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->debug[28], tmp);
375b35ce0c4SPankaj Gupta #endif
376b35ce0c4SPankaj Gupta 
377b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A010165
378b35ce0c4SPankaj Gupta 	ddr_freq = clk / 1000000U;
379b35ce0c4SPankaj Gupta 	if ((ddr_freq > 1900) && (ddr_freq < 2300)) {
380b35ce0c4SPankaj Gupta 		tmp = ddr_in32(&ddr->debug[28]);
381b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->debug[28], tmp | 0x000a0000);
382b35ce0c4SPankaj Gupta 	}
383b35ce0c4SPankaj Gupta #endif
384b35ce0c4SPankaj Gupta 	/*
385b35ce0c4SPankaj Gupta 	 * For RDIMMs, JEDEC spec requires clocks to be stable before reset is
386b35ce0c4SPankaj Gupta 	 * deasserted. Clocks start when any chip select is enabled and clock
387b35ce0c4SPankaj Gupta 	 * control register is set. Because all DDR components are connected to
388b35ce0c4SPankaj Gupta 	 * one reset signal, this needs to be done in two steps. Step 1 is to
389b35ce0c4SPankaj Gupta 	 * get the clocks started. Step 2 resumes after reset signal is
390b35ce0c4SPankaj Gupta 	 * deasserted.
391b35ce0c4SPankaj Gupta 	 */
392b35ce0c4SPankaj Gupta 	if (twopass == 1) {
393b35ce0c4SPankaj Gupta 		udelay(200);
394b35ce0c4SPankaj Gupta 		return 0;
395b35ce0c4SPankaj Gupta 	}
396b35ce0c4SPankaj Gupta 
397b35ce0c4SPankaj Gupta 	/* As per new sequence flow shall be write CSn_CONFIG registers needs to
398b35ce0c4SPankaj Gupta 	 * be set after all the other DDR controller registers are set, then poll
399b35ce0c4SPankaj Gupta 	 * for PHY_INIT_CMPLT = 1 , then wait at least 100us (micro seconds),
400b35ce0c4SPankaj Gupta 	 * then set the MEM_EN = 1
401b35ce0c4SPankaj Gupta 	 */
402b35ce0c4SPankaj Gupta 	for (i = 0U; i < DDRC_NUM_CS; i++) {
403b35ce0c4SPankaj Gupta 		if (mod_bnds != 0U && i == 0U) {
404b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->csn_cfg[i],
405b35ce0c4SPankaj Gupta 					(regs->cs[i].config & ~CTLR_INTLV_MASK));
406b35ce0c4SPankaj Gupta 		} else {
407b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->csn_cfg[i], regs->cs[i].config);
408b35ce0c4SPankaj Gupta 		}
409b35ce0c4SPankaj Gupta 	}
410b35ce0c4SPankaj Gupta 
411b35ce0c4SPankaj Gupta after_reset:
412b35ce0c4SPankaj Gupta 	/* Set, but do not enable the memory */
413b35ce0c4SPankaj Gupta 	temp_sdram_cfg = regs->sdram_cfg[0];
414b35ce0c4SPankaj Gupta 	temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
415b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg);
416b35ce0c4SPankaj Gupta 
417b35ce0c4SPankaj Gupta 	if (get_ddrc_version(ddr) < U(0x50500)) {
418b35ce0c4SPankaj Gupta 		/*
419b35ce0c4SPankaj Gupta 		 * 500 painful micro-seconds must elapse between
420b35ce0c4SPankaj Gupta 		 * the DDR clock setup and the DDR config enable.
421b35ce0c4SPankaj Gupta 		 * DDR2 need 200 us, and DDR3 need 500 us from spec,
422b35ce0c4SPankaj Gupta 		 * we choose the max, that is 500 us for all of case.
423b35ce0c4SPankaj Gupta 		 */
424b35ce0c4SPankaj Gupta 		udelay(500);
425b35ce0c4SPankaj Gupta 		/* applied memory barrier */
426b35ce0c4SPankaj Gupta 		mb();
427b35ce0c4SPankaj Gupta 		isb();
428b35ce0c4SPankaj Gupta 	} else {
429b35ce0c4SPankaj Gupta 		/* wait for PHY complete */
430b35ce0c4SPankaj Gupta 		timeout = 40;
431b35ce0c4SPankaj Gupta 		while (((ddr_in32(&ddr->ddr_dsr2) & 0x4) != 0) &&
432b35ce0c4SPankaj Gupta 		       (timeout > 0)) {
433b35ce0c4SPankaj Gupta 			udelay(500);
434b35ce0c4SPankaj Gupta 			timeout--;
435b35ce0c4SPankaj Gupta 		}
436b35ce0c4SPankaj Gupta 		if (timeout <= 0) {
437b35ce0c4SPankaj Gupta 			printf("PHY handshake timeout, ddr_dsr2 = %x\n",
438b35ce0c4SPankaj Gupta 			       ddr_in32(&ddr->ddr_dsr2));
439b35ce0c4SPankaj Gupta 		} else {
440b35ce0c4SPankaj Gupta 			debug("PHY handshake completed, timer remains %d\n",
441b35ce0c4SPankaj Gupta 			      timeout);
442b35ce0c4SPankaj Gupta 		}
443b35ce0c4SPankaj Gupta 	}
444b35ce0c4SPankaj Gupta 
445b35ce0c4SPankaj Gupta 	temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg);
446b35ce0c4SPankaj Gupta 	/* Let the controller go */
447b35ce0c4SPankaj Gupta 	udelay(100);
448b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
449b35ce0c4SPankaj Gupta 
450b35ce0c4SPankaj Gupta 	/* applied memory barrier */
451b35ce0c4SPankaj Gupta 	mb();
452b35ce0c4SPankaj Gupta 	isb();
453b35ce0c4SPankaj Gupta 
454b35ce0c4SPankaj Gupta 	total_mem_per_ctrl = 0;
455b35ce0c4SPankaj Gupta 	for (i = 0; i < DDRC_NUM_CS; i++) {
456b35ce0c4SPankaj Gupta 		if ((regs->cs[i].config & 0x80000000) == 0) {
457b35ce0c4SPankaj Gupta 			continue;
458b35ce0c4SPankaj Gupta 		}
459b35ce0c4SPankaj Gupta 		total_mem_per_ctrl += 1 << (
460b35ce0c4SPankaj Gupta 			((regs->cs[i].config >> 14) & 0x3) + 2 +
461b35ce0c4SPankaj Gupta 			((regs->cs[i].config >> 8) & 0x7) + 12 +
462b35ce0c4SPankaj Gupta 			((regs->cs[i].config >> 4) & 0x3) + 0 +
463b35ce0c4SPankaj Gupta 			((regs->cs[i].config >> 0) & 0x7) + 8 +
464b35ce0c4SPankaj Gupta 			((regs->sdram_cfg[2] >> 4) & 0x3) +
465b35ce0c4SPankaj Gupta 			3 - ((regs->sdram_cfg[0] >> 19) & 0x3) -
466b35ce0c4SPankaj Gupta 			26);		/* minus 26 (count of 64M) */
467b35ce0c4SPankaj Gupta 	}
468b35ce0c4SPankaj Gupta 	total_mem_per_ctrl_adj = total_mem_per_ctrl;
469b35ce0c4SPankaj Gupta 	/*
470b35ce0c4SPankaj Gupta 	 * total memory / bus width = transactions needed
471b35ce0c4SPankaj Gupta 	 * transactions needed / data rate = seconds
472b35ce0c4SPankaj Gupta 	 * to add plenty of buffer, double the time
473b35ce0c4SPankaj Gupta 	 * For example, 2GB on 666MT/s 64-bit bus takes about 402ms
474b35ce0c4SPankaj Gupta 	 * Let's wait for 800ms
475b35ce0c4SPankaj Gupta 	 */
476b35ce0c4SPankaj Gupta 	bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
477b35ce0c4SPankaj Gupta 			>> SDRAM_CFG_DBW_SHIFT);
478b35ce0c4SPankaj Gupta 	timeout = ((total_mem_per_ctrl_adj << (6 - bus_width)) * 100 /
479b35ce0c4SPankaj Gupta 		   (clk >> 20)) << 2;
480b35ce0c4SPankaj Gupta 	total_mem_per_ctrl_adj >>= 4;	/* shift down to gb size */
481b35ce0c4SPankaj Gupta 	if ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) != 0) {
482b35ce0c4SPankaj Gupta 		debug("total size %d GB\n", total_mem_per_ctrl_adj);
483b35ce0c4SPankaj Gupta 		debug("Need to wait up to %d ms\n", timeout * 10);
484b35ce0c4SPankaj Gupta 
485b35ce0c4SPankaj Gupta 		do {
486b35ce0c4SPankaj Gupta 			mdelay(10);
487b35ce0c4SPankaj Gupta 		} while (timeout-- > 0 &&
488b35ce0c4SPankaj Gupta 			 ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT)) != 0);
489b35ce0c4SPankaj Gupta 
490b35ce0c4SPankaj Gupta 		if (timeout <= 0) {
491b35ce0c4SPankaj Gupta 			if (ddr_in32(&ddr->debug[1]) & 0x3d00) {
492b35ce0c4SPankaj Gupta 				ERROR("Found training error(s): 0x%x\n",
493b35ce0c4SPankaj Gupta 				      ddr_in32(&ddr->debug[1]));
494b35ce0c4SPankaj Gupta 			}
495b35ce0c4SPankaj Gupta 			ERROR("Error: Waiting for D_INIT timeout.\n");
496b35ce0c4SPankaj Gupta 			return -EIO;
497b35ce0c4SPankaj Gupta 		}
498b35ce0c4SPankaj Gupta 	}
499b35ce0c4SPankaj Gupta 
500b35ce0c4SPankaj Gupta 	if (mod_bnds != 0U) {
501b35ce0c4SPankaj Gupta 		debug("Restore original bnds\n");
502b35ce0c4SPankaj Gupta 		for (i = 0U; i < DDRC_NUM_CS; i++) {
503b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->bnds[i].a, regs->cs[i].bnds);
504b35ce0c4SPankaj Gupta 		}
505b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->csn_cfg[0], regs->cs[0].config);
506b35ce0c4SPankaj Gupta #ifdef CONFIG_DDR_ADDR_DEC
507b35ce0c4SPankaj Gupta 		if ((regs->dec[9] & U(0x1)) != 0U) {
508b35ce0c4SPankaj Gupta 			debug("Restore address decoding\n");
509b35ce0c4SPankaj Gupta 			ddr_out32(&ddr->dec[9], regs->dec[9]);
510b35ce0c4SPankaj Gupta 		}
511b35ce0c4SPankaj Gupta #endif
512b35ce0c4SPankaj Gupta 	}
513b35ce0c4SPankaj Gupta 
514b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009803
515b35ce0c4SPankaj Gupta 	/* Part 2 of 2 */
516b35ce0c4SPankaj Gupta 	if ((regs->sdram_cfg[1] & SDRAM_CFG2_AP_EN) != 0) {
517b35ce0c4SPankaj Gupta 		timeout = 400;
518b35ce0c4SPankaj Gupta 		do {
519b35ce0c4SPankaj Gupta 			mdelay(1);
520b35ce0c4SPankaj Gupta 		} while (timeout-- > 0 && ((ddr_in32(&ddr->debug[1]) & 0x2) == 0));
521b35ce0c4SPankaj Gupta 
522b35ce0c4SPankaj Gupta 		if ((regs->sdram_cfg[0] & SDRAM_CFG_RD_EN) != 0) {
523b35ce0c4SPankaj Gupta 			for (i = 0U; i < DDRC_NUM_CS; i++) {
524b35ce0c4SPankaj Gupta 				if ((regs->cs[i].config & SDRAM_CS_CONFIG_EN) == 0) {
525b35ce0c4SPankaj Gupta 					continue;
526b35ce0c4SPankaj Gupta 				}
527b35ce0c4SPankaj Gupta 				set_wait_for_bits_clear(&ddr->sdram_md_cntl,
528b35ce0c4SPankaj Gupta 						MD_CNTL_MD_EN |
529b35ce0c4SPankaj Gupta 						MD_CNTL_CS_SEL(i) |
530b35ce0c4SPankaj Gupta 						0x070000ed,
531b35ce0c4SPankaj Gupta 						MD_CNTL_MD_EN);
532b35ce0c4SPankaj Gupta 				udelay(1);
533b35ce0c4SPankaj Gupta 			}
534b35ce0c4SPankaj Gupta 		}
535b35ce0c4SPankaj Gupta 
536b35ce0c4SPankaj Gupta 		ddr_out32(&ddr->err_disable,
537b35ce0c4SPankaj Gupta 			  regs->err_disable & ~DDR_ERR_DISABLE_APED);
538b35ce0c4SPankaj Gupta 	}
539b35ce0c4SPankaj Gupta #endif
540b35ce0c4SPankaj Gupta 
541b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009663
542b35ce0c4SPankaj Gupta 	ddr_out32(&ddr->sdram_interval, regs->interval);
543b35ce0c4SPankaj Gupta #endif
544b35ce0c4SPankaj Gupta 
545b35ce0c4SPankaj Gupta #ifdef ERRATA_DDR_A009942
546b35ce0c4SPankaj Gupta 	timeout = 400;
547b35ce0c4SPankaj Gupta 	do {
548b35ce0c4SPankaj Gupta 		mdelay(1);
549b35ce0c4SPankaj Gupta 	} while (timeout-- > 0 && ((ddr_in32(&ddr->debug[1]) & 0x2) == 0));
550b35ce0c4SPankaj Gupta 	tmp = (regs->sdram_cfg[0] >> 19) & 0x3;
551b35ce0c4SPankaj Gupta 	check = (tmp == DDR_DBUS_64) ? 4 : ((tmp == DDR_DBUS_32) ? 2 : 1);
552b35ce0c4SPankaj Gupta 	for (i = 0; i < check; i++) {
553b35ce0c4SPankaj Gupta 		tmp = ddr_in32(&ddr->debug[9 + i]);
554b35ce0c4SPankaj Gupta 		debug("Reading debug[%d] as 0x%x\n", i + 9, tmp);
555b35ce0c4SPankaj Gupta 		cpo_min = min(cpo_min,
556b35ce0c4SPankaj Gupta 			      min((tmp >> 24) & 0xff, (tmp >> 8) & 0xff));
557b35ce0c4SPankaj Gupta 		cpo_max = max(cpo_max,
558b35ce0c4SPankaj Gupta 			      max((tmp >> 24) & 0xff, (tmp >> 8) & 0xff));
559b35ce0c4SPankaj Gupta 	}
560b35ce0c4SPankaj Gupta 	if ((regs->sdram_cfg[0] & SDRAM_CFG_ECC_EN) != 0) {
561b35ce0c4SPankaj Gupta 		tmp = ddr_in32(&ddr->debug[13]);
562b35ce0c4SPankaj Gupta 		cpo_min = min(cpo_min, (tmp >> 24) & 0xff);
563b35ce0c4SPankaj Gupta 		cpo_max = max(cpo_max, (tmp >> 24) & 0xff);
564b35ce0c4SPankaj Gupta 	}
565b35ce0c4SPankaj Gupta 	debug("cpo_min 0x%x\n", cpo_min);
566b35ce0c4SPankaj Gupta 	debug("cpo_max 0x%x\n", cpo_max);
567b35ce0c4SPankaj Gupta 	tmp = ddr_in32(&ddr->debug[28]);
568b35ce0c4SPankaj Gupta 	debug("debug[28] 0x%x\n", tmp);
569b35ce0c4SPankaj Gupta 	if ((cpo_min + 0x3B) < (tmp & 0xff)) {
570b35ce0c4SPankaj Gupta 		WARN("Warning: A009942 requires setting cpo_sample to 0x%x\n",
571b35ce0c4SPankaj Gupta 		     (cpo_min + cpo_max) / 2 + 0x27);
572b35ce0c4SPankaj Gupta 	} else {
573b35ce0c4SPankaj Gupta 		debug("Optimal cpo_sample 0x%x\n",
574b35ce0c4SPankaj Gupta 			(cpo_min + cpo_max) / 2 + 0x27);
575b35ce0c4SPankaj Gupta 	}
576b35ce0c4SPankaj Gupta #endif
577b35ce0c4SPankaj Gupta 	if (run_bist() != 0) {
578b35ce0c4SPankaj Gupta 		if ((ddr_in32(&ddr->debug[1]) &
579b35ce0c4SPankaj Gupta 		    ((get_ddrc_version(ddr) == 0x50500) ? 0x3c00 : 0x3d00)) != 0) {
580b35ce0c4SPankaj Gupta 			ERROR("Found training error(s): 0x%x\n",
581b35ce0c4SPankaj Gupta 			     ddr_in32(&ddr->debug[1]));
582b35ce0c4SPankaj Gupta 			return -EIO;
583b35ce0c4SPankaj Gupta 		}
584b35ce0c4SPankaj Gupta 		INFO("Running built-in self test ...\n");
585b35ce0c4SPankaj Gupta 		/* give it 10x time to cover whole memory */
586b35ce0c4SPankaj Gupta 		timeout = ((total_mem_per_ctrl << (6 - bus_width)) *
587b35ce0c4SPankaj Gupta 			   100 / (clk >> 20)) * 10;
588b35ce0c4SPankaj Gupta 		INFO("\tWait up to %d ms\n", timeout * 10);
589b35ce0c4SPankaj Gupta 		ret = bist(ddr, timeout);
590b35ce0c4SPankaj Gupta 	}
591b35ce0c4SPankaj Gupta 	dump_ddrc((void *)ddr);
592b35ce0c4SPankaj Gupta 
593b35ce0c4SPankaj Gupta 	return ret;
594b35ce0c4SPankaj Gupta }
595