]>
Commit | Line | Data |
---|---|---|
157cda4d NG |
1 | /* |
2 | * (C) Copyright 2007 | |
3 | * Niklaus Giger (Niklaus.Giger@netstal.com) | |
4 | * (C) Copyright 2006 | |
5 | * Sylvie Gohl, AMCC/IBM, gohl.sylvie@fr.ibm.com | |
6 | * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com | |
7 | * Thierry Roman, AMCC/IBM, thierry_roman@fr.ibm.com | |
8 | * Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com | |
9 | * Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.com | |
10 | * | |
11 | * (C) Copyright 2006 | |
12 | * Stefan Roese, DENX Software Engineering, sr@denx.de. | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or | |
15 | * modify it under the terms of the GNU General Public License as | |
16 | * published by the Free Software Foundation; either version 2 of | |
17 | * the License, or (at your option) any later version. | |
18 | * | |
19 | * This program is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU General Public License | |
25 | * along with this program; if not, write to the Free Software | |
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
27 | * MA 02111-1307 USA | |
28 | */ | |
29 | ||
30 | /* define DEBUG for debug output */ | |
31 | #undef DEBUG | |
32 | ||
33 | #include <common.h> | |
34 | #include <asm/processor.h> | |
35 | #include <asm/io.h> | |
36 | #include <asm/mmu.h> | |
85ad184b | 37 | #include <asm/cache.h> |
157cda4d NG |
38 | #include <ppc440.h> |
39 | ||
1e6b07c6 | 40 | void hcu_led_set(u32 value); |
157cda4d | 41 | void dcbz_area(u32 start_address, u32 num_bytes); |
157cda4d | 42 | |
ba52be3d SR |
43 | #define ECC_RAM 0x03267F0B |
44 | #define NO_ECC_RAM 0x00267F0B | |
45 | ||
46 | #define HCU_HW_SDRAM_CONFIG_MASK 0x7 | |
47 | ||
efeff538 NG |
48 | #define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE |
49 | /* disable caching on DDR2 */ | |
157cda4d | 50 | |
157cda4d NG |
51 | void board_add_ram_info(int use_default) |
52 | { | |
087dfdb7 | 53 | PPC4xx_SYS_INFO board_cfg; |
157cda4d | 54 | u32 val; |
ba52be3d | 55 | |
157cda4d NG |
56 | mfsdram(DDR0_22, val); |
57 | val &= DDR0_22_CTRL_RAW_MASK; | |
58 | switch (val) { | |
59 | case DDR0_22_CTRL_RAW_ECC_DISABLE: | |
60 | puts(" (ECC disabled"); | |
61 | break; | |
62 | case DDR0_22_CTRL_RAW_ECC_CHECK_ONLY: | |
63 | puts(" (ECC check only"); | |
64 | break; | |
65 | case DDR0_22_CTRL_RAW_NO_ECC_RAM: | |
66 | puts(" (no ECC ram"); | |
67 | break; | |
68 | case DDR0_22_CTRL_RAW_ECC_ENABLE: | |
69 | puts(" (ECC enabled"); | |
70 | break; | |
71 | } | |
72 | ||
73 | get_sys_info(&board_cfg); | |
bde63587 | 74 | printf(", %lu MHz", (board_cfg.freqPLB * 2) / 1000000); |
157cda4d NG |
75 | |
76 | mfsdram(DDR0_03, val); | |
77 | val = DDR0_03_CASLAT_DECODE(val); | |
78 | printf(", CL%d)", val); | |
79 | } | |
157cda4d NG |
80 | |
81 | /*-------------------------------------------------------------------- | |
82 | * wait_for_dlllock. | |
83 | *--------------------------------------------------------------------*/ | |
84 | static int wait_for_dlllock(void) | |
85 | { | |
86 | unsigned long val; | |
87 | int wait = 0; | |
88 | ||
89 | /* -----------------------------------------------------------+ | |
90 | * Wait for the DCC master delay line to finish calibration | |
91 | * ----------------------------------------------------------*/ | |
bbeff30c | 92 | mtdcr(memcfga, DDR0_17); |
157cda4d NG |
93 | val = DDR0_17_DLLLOCKREG_UNLOCKED; |
94 | ||
95 | while (wait != 0xffff) { | |
bbeff30c | 96 | val = mfdcr(memcfgd); |
157cda4d NG |
97 | if ((val & DDR0_17_DLLLOCKREG_MASK) == |
98 | DDR0_17_DLLLOCKREG_LOCKED) | |
99 | /* dlllockreg bit on */ | |
100 | return 0; | |
101 | else | |
102 | wait++; | |
103 | } | |
104 | debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val); | |
105 | debug("Waiting for dlllockreg bit to raise\n"); | |
106 | ||
107 | return -1; | |
108 | } | |
109 | ||
110 | /*********************************************************************** | |
111 | * | |
112 | * sdram_panic -- Panic if we cannot configure the sdram correctly | |
113 | * | |
114 | ************************************************************************/ | |
115 | void sdram_panic(const char *reason) | |
116 | { | |
117 | printf("\n%s: reason %s", __FUNCTION__, reason); | |
1e6b07c6 | 118 | hcu_led_set(0xff); |
157cda4d NG |
119 | while (1) { |
120 | } | |
121 | /* Never return */ | |
122 | } | |
123 | ||
124 | #ifdef CONFIG_DDR_ECC | |
5ff88934 | 125 | void blank_string(int size) |
157cda4d NG |
126 | { |
127 | int i; | |
128 | ||
129 | for (i=0; i<size; i++) | |
130 | putc('\b'); | |
131 | for (i=0; i<size; i++) | |
132 | putc(' '); | |
133 | for (i=0; i<size; i++) | |
134 | putc('\b'); | |
135 | } | |
136 | /*---------------------------------------------------------------------------+ | |
137 | * program_ecc. | |
138 | *---------------------------------------------------------------------------*/ | |
efeff538 | 139 | static void program_ecc(unsigned long start_address, unsigned long num_bytes) |
157cda4d | 140 | { |
157cda4d | 141 | u32 val; |
157cda4d | 142 | char str[] = "ECC generation -"; |
efeff538 | 143 | #if defined(CONFIG_PRAM) |
74973126 NG |
144 | u32 *magicPtr; |
145 | u32 magic; | |
146 | ||
147 | if ((mfspr(dbcr0) & 0x80000000) == 0) { | |
148 | /* only if no external debugger is alive! | |
149 | * Check whether vxWorks is using EDR logging, if yes zero | |
150 | * also PostMortem and user reserved memory | |
151 | */ | |
152 | magicPtr = (u32 *)(start_address + num_bytes - | |
153 | (CONFIG_PRAM*1024) + sizeof(u32)); | |
154 | magic = in_be32(magicPtr); | |
155 | debug("%s: CONFIG_PRAM %d kB magic 0x%x 0x%p\n", | |
156 | __FUNCTION__, CONFIG_PRAM, | |
157 | magicPtr, magic); | |
158 | if (magic == 0xbeefbabe) { | |
159 | printf("%s: preserving at %p\n", __FUNCTION__, magicPtr); | |
160 | num_bytes -= (CONFIG_PRAM*1024) - PM_RESERVED_MEM; | |
161 | } | |
162 | } | |
efeff538 NG |
163 | #endif |
164 | ||
157cda4d | 165 | sync(); |
157cda4d NG |
166 | |
167 | puts(str); | |
168 | ||
efeff538 NG |
169 | /* ECC bit set method for cached memory */ |
170 | /* Fast method, no noticeable delay */ | |
171 | dcbz_area(start_address, num_bytes); | |
85ad184b SR |
172 | /* Write modified dcache lines back to memory */ |
173 | clean_dcache_range(start_address, start_address + num_bytes); | |
157cda4d NG |
174 | blank_string(strlen(str)); |
175 | ||
176 | /* Clear error status */ | |
177 | mfsdram(DDR0_00, val); | |
178 | mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL); | |
179 | ||
1e6b07c6 | 180 | /* |
efeff538 | 181 | * Clear possible ECC errors |
1e6b07c6 NG |
182 | * If not done, then we could get an interrupt later on when |
183 | * exceptions are enabled. | |
184 | */ | |
185 | mtspr(mcsr, mfspr(mcsr)); | |
186 | ||
157cda4d NG |
187 | /* Set 'int_mask' parameter to functionnal value */ |
188 | mfsdram(DDR0_01, val); | |
189 | mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) | | |
190 | DDR0_01_INT_MASK_ALL_OFF)); | |
191 | ||
192 | return; | |
193 | } | |
157cda4d NG |
194 | #endif |
195 | ||
efeff538 | 196 | |
157cda4d NG |
197 | /*********************************************************************** |
198 | * | |
199 | * initdram -- 440EPx's DDR controller is a DENALI Core | |
200 | * | |
201 | ************************************************************************/ | |
9973e3c6 | 202 | phys_size_t initdram (int board_type) |
157cda4d | 203 | { |
35d22f95 SR |
204 | unsigned int dram_size = 0; |
205 | ||
157cda4d NG |
206 | mtsdram(DDR0_02, 0x00000000); |
207 | ||
208 | /* Values must be kept in sync with Excel-table <<A0001492.>> ! */ | |
209 | mtsdram(DDR0_00, 0x0000190A); | |
210 | mtsdram(DDR0_01, 0x01000000); | |
211 | mtsdram(DDR0_03, 0x02030602); | |
212 | mtsdram(DDR0_04, 0x0A020200); | |
213 | mtsdram(DDR0_05, 0x02020307); | |
ba52be3d | 214 | switch (in_be16((u16 *)HCU_HW_VERSION_REGISTER) & HCU_HW_SDRAM_CONFIG_MASK) { |
157cda4d NG |
215 | case 1: |
216 | dram_size = 256 * 1024 * 1024 ; | |
35d22f95 SR |
217 | mtsdram(DDR0_06, 0x0102C812); /* 256MB RAM */ |
218 | mtsdram(DDR0_11, 0x0014C800); /* 256MB RAM */ | |
219 | mtsdram(DDR0_43, 0x030A0200); /* 256MB RAM */ | |
157cda4d | 220 | break; |
efeff538 | 221 | case 0: |
157cda4d | 222 | default: |
efeff538 NG |
223 | dram_size = 128 * 1024 * 1024 ; |
224 | mtsdram(DDR0_06, 0x0102C80D); /* 128MB RAM */ | |
225 | mtsdram(DDR0_11, 0x000FC800); /* 128MB RAM */ | |
226 | mtsdram(DDR0_43, 0x030A0300); /* 128MB RAM */ | |
157cda4d NG |
227 | break; |
228 | } | |
157cda4d | 229 | mtsdram(DDR0_07, 0x00090100); |
efeff538 | 230 | |
35d22f95 SR |
231 | /* |
232 | * TCPD=200 cycles of clock input is required to lock the DLL. | |
233 | * CKE must be HIGH the entire time.mtsdram(DDR0_08, 0x02C80001); | |
234 | */ | |
157cda4d NG |
235 | mtsdram(DDR0_08, 0x02C80001); |
236 | mtsdram(DDR0_09, 0x00011D5F); | |
237 | mtsdram(DDR0_10, 0x00000100); | |
238 | mtsdram(DDR0_12, 0x00000003); | |
239 | mtsdram(DDR0_14, 0x00000000); | |
240 | mtsdram(DDR0_17, 0x1D000000); | |
241 | mtsdram(DDR0_18, 0x1D1D1D1D); | |
242 | mtsdram(DDR0_19, 0x1D1D1D1D); | |
243 | mtsdram(DDR0_20, 0x0B0B0B0B); | |
244 | mtsdram(DDR0_21, 0x0B0B0B0B); | |
157cda4d NG |
245 | #ifdef CONFIG_DDR_ECC |
246 | mtsdram(DDR0_22, ECC_RAM); | |
247 | #else | |
248 | mtsdram(DDR0_22, NO_ECC_RAM); | |
249 | #endif | |
250 | ||
251 | mtsdram(DDR0_23, 0x00000000); | |
252 | mtsdram(DDR0_24, 0x01020001); | |
253 | mtsdram(DDR0_26, 0x2D930517); | |
254 | mtsdram(DDR0_27, 0x00008236); | |
255 | mtsdram(DDR0_28, 0x00000000); | |
256 | mtsdram(DDR0_31, 0x00000000); | |
257 | mtsdram(DDR0_42, 0x01000006); | |
258 | mtsdram(DDR0_44, 0x00000003); | |
259 | mtsdram(DDR0_02, 0x00000001); | |
260 | wait_for_dlllock(); | |
261 | mtsdram(DDR0_00, 0x40000000); /* Zero init bit */ | |
262 | ||
263 | /* | |
264 | * Program tlb entries for this size (dynamic) | |
265 | */ | |
6d0f6bcf | 266 | remove_tlb(CONFIG_SYS_SDRAM_BASE, 256 << 20); |
efeff538 | 267 | program_tlb(0, 0, dram_size, TLB_WORD2_W_ENABLE | TLB_WORD2_I_ENABLE); |
157cda4d NG |
268 | |
269 | /* | |
270 | * Setup 2nd TLB with same physical address but different virtual | |
271 | * address with cache enabled. This is done for fast ECC generation. | |
272 | */ | |
6d0f6bcf | 273 | program_tlb(0, CONFIG_SYS_DDR_CACHED_ADDR, dram_size, 0); |
157cda4d NG |
274 | |
275 | #ifdef CONFIG_DDR_ECC | |
276 | /* | |
277 | * If ECC is enabled, initialize the parity bits. | |
278 | */ | |
6d0f6bcf | 279 | program_ecc(CONFIG_SYS_DDR_CACHED_ADDR, dram_size); |
157cda4d NG |
280 | #endif |
281 | ||
282 | return (dram_size); | |
283 | } |