]>
Commit | Line | Data |
---|---|---|
04386f65 SR |
1 | /* |
2 | * (C) Copyright 2006 | |
3 | * Sylvie Gohl, AMCC/IBM, gohl.sylvie@fr.ibm.com | |
4 | * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com | |
5 | * Thierry Roman, AMCC/IBM, thierry_roman@fr.ibm.com | |
6 | * Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com | |
7 | * Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.com | |
8 | * | |
9 | * (C) Copyright 2007-2013 | |
10 | * Stefan Roese, DENX Software Engineering, sr@denx.de. | |
11 | * | |
12 | * SPDX-License-Identifier: GPL-2.0+ | |
13 | */ | |
14 | ||
15 | /* define DEBUG for debugging output (obviously ;-)) */ | |
16 | #if 0 | |
17 | #define DEBUG | |
18 | #endif | |
19 | ||
20 | #include <common.h> | |
21 | #include <asm/processor.h> | |
22 | #include <asm/mmu.h> | |
23 | #include <asm/io.h> | |
24 | #include <asm/cache.h> | |
25 | #include <asm/ppc440.h> | |
26 | #include <watchdog.h> | |
27 | ||
088454cd SG |
28 | DECLARE_GLOBAL_DATA_PTR; |
29 | ||
04386f65 SR |
30 | /* |
31 | * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory | |
32 | * region. Right now the cache should still be disabled in U-Boot because of the | |
33 | * EMAC driver, that need it's buffer descriptor to be located in non cached | |
34 | * memory. | |
35 | * | |
36 | * If at some time this restriction doesn't apply anymore, just define | |
37 | * CONFIG_4xx_DCACHE in the board config file and this code should setup | |
38 | * everything correctly. | |
39 | */ | |
40 | #ifdef CONFIG_4xx_DCACHE | |
41 | #define MY_TLB_WORD2_I_ENABLE 0 /* enable caching on SDRAM */ | |
42 | #else | |
43 | #define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */ | |
44 | #endif | |
45 | ||
46 | /*-----------------------------------------------------------------------------+ | |
47 | * Prototypes | |
48 | *-----------------------------------------------------------------------------*/ | |
49 | extern int denali_wait_for_dlllock(void); | |
50 | extern void denali_core_search_data_eye(void); | |
51 | extern void dcbz_area(u32 start_address, u32 num_bytes); | |
52 | ||
53 | static u32 is_ecc_enabled(void) | |
54 | { | |
55 | u32 val; | |
56 | ||
57 | mfsdram(DDR0_22, val); | |
58 | val &= DDR0_22_CTRL_RAW_MASK; | |
59 | if (val) | |
60 | return 1; | |
61 | else | |
62 | return 0; | |
63 | } | |
64 | ||
65 | void board_add_ram_info(int use_default) | |
66 | { | |
67 | PPC4xx_SYS_INFO board_cfg; | |
68 | u32 val; | |
69 | ||
70 | if (is_ecc_enabled()) | |
71 | puts(" (ECC"); | |
72 | else | |
73 | puts(" (ECC not"); | |
74 | ||
75 | get_sys_info(&board_cfg); | |
76 | printf(" enabled, %ld MHz", (board_cfg.freqPLB * 2) / 1000000); | |
77 | ||
78 | mfsdram(DDR0_03, val); | |
79 | val = DDR0_03_CASLAT_DECODE(val); | |
80 | printf(", CL%d)", val); | |
81 | } | |
82 | ||
83 | #ifdef CONFIG_DDR_ECC | |
84 | static void wait_ddr_idle(void) | |
85 | { | |
86 | /* | |
87 | * Controller idle status cannot be determined for Denali | |
88 | * DDR2 code. Just return here. | |
89 | */ | |
90 | } | |
91 | ||
92 | static void program_ecc(u32 start_address, | |
93 | u32 num_bytes, | |
94 | u32 tlb_word2_i_value) | |
95 | { | |
96 | u32 val; | |
97 | u32 current_addr = start_address; | |
98 | u32 size; | |
99 | int bytes_remaining; | |
100 | ||
101 | sync(); | |
102 | wait_ddr_idle(); | |
103 | ||
104 | /* | |
105 | * Because of 440EPx errata CHIP 11, we don't touch the last 256 | |
106 | * bytes of SDRAM. | |
107 | */ | |
108 | bytes_remaining = num_bytes - CONFIG_SYS_MEM_TOP_HIDE; | |
109 | ||
110 | /* | |
111 | * We have to write the ECC bytes by zeroing and flushing in smaller | |
112 | * steps, since the whole 256MByte takes too long for the external | |
113 | * watchdog. | |
114 | */ | |
115 | while (bytes_remaining > 0) { | |
116 | size = min((64 << 20), bytes_remaining); | |
117 | ||
118 | /* Write zero's to SDRAM */ | |
119 | dcbz_area(current_addr, size); | |
120 | ||
121 | /* Write modified dcache lines back to memory */ | |
122 | clean_dcache_range(current_addr, current_addr + size); | |
123 | ||
124 | current_addr += 64 << 20; | |
125 | bytes_remaining -= 64 << 20; | |
126 | WATCHDOG_RESET(); | |
127 | } | |
128 | ||
129 | sync(); | |
130 | wait_ddr_idle(); | |
131 | ||
132 | /* Clear error status */ | |
133 | mfsdram(DDR0_00, val); | |
134 | mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL); | |
135 | ||
136 | /* Set 'int_mask' parameter to functionnal value */ | |
137 | mfsdram(DDR0_01, val); | |
138 | mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | DDR0_01_INT_MASK_ALL_OFF)); | |
139 | ||
140 | sync(); | |
141 | wait_ddr_idle(); | |
142 | } | |
143 | #endif | |
144 | ||
145 | /************************************************************************* | |
146 | * | |
f1683aa7 | 147 | * dram_init -- 440EPx's DDR controller is a DENALI Core |
04386f65 SR |
148 | * |
149 | ************************************************************************/ | |
f1683aa7 | 150 | int dram_init(void) |
04386f65 | 151 | { |
04386f65 SR |
152 | /* CL=4 */ |
153 | mtsdram(DDR0_02, 0x00000000); | |
154 | ||
155 | mtsdram(DDR0_00, 0x0000190A); | |
156 | mtsdram(DDR0_01, 0x01000000); | |
157 | mtsdram(DDR0_03, 0x02040803); /* A suitable burst length was taken. CAS is right for our board */ | |
158 | ||
159 | mtsdram(DDR0_04, 0x0B030300); | |
160 | mtsdram(DDR0_05, 0x02020308); | |
161 | mtsdram(DDR0_06, 0x0003C812); | |
162 | mtsdram(DDR0_07, 0x00090100); | |
163 | mtsdram(DDR0_08, 0x03c80001); | |
164 | mtsdram(DDR0_09, 0x00011D5F); | |
165 | mtsdram(DDR0_10, 0x00000100); | |
166 | mtsdram(DDR0_11, 0x000CC800); | |
167 | mtsdram(DDR0_12, 0x00000003); | |
168 | mtsdram(DDR0_14, 0x00000000); | |
169 | mtsdram(DDR0_17, 0x1e000000); | |
170 | mtsdram(DDR0_18, 0x1e1e1e1e); | |
171 | mtsdram(DDR0_19, 0x1e1e1e1e); | |
172 | mtsdram(DDR0_20, 0x0B0B0B0B); | |
173 | mtsdram(DDR0_21, 0x0B0B0B0B); | |
174 | #ifdef CONFIG_DDR_ECC | |
175 | mtsdram(DDR0_22, 0x00267F0B | DDR0_22_CTRL_RAW_ECC_ENABLE); /* enable ECC */ | |
176 | #else | |
177 | mtsdram(DDR0_22, 0x00267F0B); | |
178 | #endif | |
179 | ||
180 | mtsdram(DDR0_23, 0x01000000); | |
181 | mtsdram(DDR0_24, 0x01010001); | |
182 | ||
183 | mtsdram(DDR0_26, 0x2D93028A); | |
184 | mtsdram(DDR0_27, 0x0784682B); | |
185 | ||
186 | mtsdram(DDR0_28, 0x00000080); | |
187 | mtsdram(DDR0_31, 0x00000000); | |
188 | mtsdram(DDR0_42, 0x01000008); | |
189 | ||
190 | mtsdram(DDR0_43, 0x050A0200); | |
191 | mtsdram(DDR0_44, 0x00000005); | |
192 | mtsdram(DDR0_02, 0x00000001); /* Activate the denali core */ | |
193 | ||
194 | denali_wait_for_dlllock(); | |
195 | ||
196 | #if defined(CONFIG_DDR_DATA_EYE) | |
197 | /* -----------------------------------------------------------+ | |
198 | * Perform data eye search if requested. | |
199 | * ----------------------------------------------------------*/ | |
200 | program_tlb(0, CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20, | |
201 | TLB_WORD2_I_ENABLE); | |
202 | denali_core_search_data_eye(); | |
203 | remove_tlb(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20); | |
204 | #endif | |
205 | ||
206 | /* | |
207 | * Program tlb entries for this size (dynamic) | |
208 | */ | |
209 | program_tlb(0, CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20, | |
210 | MY_TLB_WORD2_I_ENABLE); | |
211 | ||
212 | #if defined(CONFIG_DDR_ECC) | |
213 | #if defined(CONFIG_4xx_DCACHE) | |
214 | /* | |
215 | * If ECC is enabled, initialize the parity bits. | |
216 | */ | |
217 | program_ecc(0, CONFIG_SYS_MBYTES_SDRAM << 20, 0); | |
218 | #else /* CONFIG_4xx_DCACHE */ | |
219 | /* | |
220 | * Setup 2nd TLB with same physical address but different virtual address | |
221 | * with cache enabled. This is done for fast ECC generation. | |
222 | */ | |
223 | program_tlb(0, CONFIG_SYS_DDR_CACHED_ADDR, CONFIG_SYS_MBYTES_SDRAM << 20, 0); | |
224 | ||
225 | /* | |
226 | * If ECC is enabled, initialize the parity bits. | |
227 | */ | |
228 | program_ecc(CONFIG_SYS_DDR_CACHED_ADDR, CONFIG_SYS_MBYTES_SDRAM << 20, 0); | |
229 | ||
230 | /* | |
231 | * Now after initialization (auto-calibration and ECC generation) | |
232 | * remove the TLB entries with caches enabled and program again with | |
233 | * desired cache functionality | |
234 | */ | |
235 | remove_tlb(CONFIG_SYS_DDR_CACHED_ADDR, CONFIG_SYS_MBYTES_SDRAM << 20); | |
236 | #endif /* CONFIG_4xx_DCACHE */ | |
237 | #endif /* CONFIG_DDR_ECC */ | |
238 | ||
239 | /* | |
240 | * Clear possible errors resulting from data-eye-search. | |
241 | * If not done, then we could get an interrupt later on when | |
242 | * exceptions are enabled. | |
243 | */ | |
244 | set_mcsr(get_mcsr()); | |
04386f65 | 245 | |
088454cd SG |
246 | gd->ram_size = CONFIG_SYS_MBYTES_SDRAM << 20; |
247 | ||
248 | return 0; | |
04386f65 | 249 | } |