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