]>
Commit | Line | Data |
---|---|---|
16f21704 WD |
1 | /* |
2 | * (C) Copyright 2000 | |
3 | * Wolfgang Denk, DENX Software Engineering, [email protected]. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | #include <common.h> | |
25 | #include <commproc.h> | |
26 | #include <mpc8xx.h> | |
27 | ||
28 | /* ------------------------------------------------------------------------- */ | |
29 | ||
30 | static long int dram_size (long int, long int *, long int); | |
3bac3513 WD |
31 | unsigned long ip860_get_dram_size(void); |
32 | unsigned long ip860_get_clk_freq (void); | |
16f21704 WD |
33 | /* ------------------------------------------------------------------------- */ |
34 | ||
35 | #define _NOT_USED_ 0xFFFFFFFF | |
36 | ||
37 | const uint sdram_table[] = { | |
38 | /* | |
39 | * Single Read. (Offset 0 in UPMA RAM) | |
40 | */ | |
41 | 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00, | |
42 | 0x1ff77c47, /* last */ | |
43 | /* | |
44 | * SDRAM Initialization (offset 5 in UPMA RAM) | |
45 | * | |
46 | * This is no UPM entry point. The following definition uses | |
47 | * the remaining space to establish an initialization | |
48 | * sequence, which is executed by a RUN command. | |
49 | * | |
50 | */ | |
51 | 0x1ff77c34, 0xefeabc34, 0x1fb57c35, /* last */ | |
52 | /* | |
53 | * Burst Read. (Offset 8 in UPMA RAM) | |
54 | */ | |
55 | 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00, | |
56 | 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47, /* last */ | |
57 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
58 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
59 | /* | |
60 | * Single Write. (Offset 18 in UPMA RAM) | |
61 | */ | |
62 | 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47, /* last */ | |
63 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
64 | /* | |
65 | * Burst Write. (Offset 20 in UPMA RAM) | |
66 | */ | |
67 | 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00, | |
68 | 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, /* last */ | |
69 | _NOT_USED_, | |
70 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
71 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
72 | /* | |
73 | * Refresh (Offset 30 in UPMA RAM) | |
74 | */ | |
75 | 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04, | |
76 | 0xfffffc84, 0xfffffc07, /* last */ | |
77 | _NOT_USED_, _NOT_USED_, | |
78 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
79 | /* | |
80 | * Exception. (Offset 3c in UPMA RAM) | |
81 | */ | |
82 | 0x7ffffc07, /* last */ | |
83 | _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
84 | }; | |
85 | ||
3bac3513 | 86 | |
16f21704 | 87 | /* ------------------------------------------------------------------------- */ |
c837dcb1 | 88 | int board_early_init_f(void) |
3bac3513 WD |
89 | { |
90 | volatile immap_t *immap = (immap_t *)CFG_IMMR; | |
91 | volatile memctl8xx_t *memctl = &immap->im_memctl; | |
92 | ||
93 | /* init BCSR chipselect line for ip860_get_clk_freq() and ip860_get_dram_size() */ | |
94 | memctl->memc_or4 = CFG_OR4; | |
95 | memctl->memc_br4 = CFG_BR4; | |
16f21704 | 96 | |
3bac3513 WD |
97 | return 0; |
98 | } | |
99 | ||
100 | ||
101 | /* ------------------------------------------------------------------------- */ | |
16f21704 WD |
102 | |
103 | /* | |
104 | * Check Board Identity: | |
105 | * | |
106 | * Test ID string (IP860...) | |
107 | */ | |
108 | ||
109 | int checkboard (void) | |
110 | { | |
111 | unsigned char *s, *e; | |
112 | unsigned char buf[64]; | |
113 | int i; | |
114 | ||
115 | puts ("Board: "); | |
116 | ||
77ddac94 | 117 | i = getenv_r ("serial#", (char *)buf, sizeof (buf)); |
16f21704 WD |
118 | s = (i > 0) ? buf : NULL; |
119 | ||
77ddac94 | 120 | if (!s || strncmp ((char *)s, "IP860", 5)) { |
16f21704 WD |
121 | puts ("### No HW ID - assuming IP860"); |
122 | } else { | |
123 | for (e = s; *e; ++e) { | |
124 | if (*e == ' ') | |
125 | break; | |
126 | } | |
127 | ||
128 | for (; s < e; ++s) { | |
129 | putc (*s); | |
130 | } | |
131 | } | |
132 | ||
133 | putc ('\n'); | |
134 | ||
135 | return (0); | |
136 | } | |
137 | ||
138 | /* ------------------------------------------------------------------------- */ | |
139 | ||
140 | long int initdram (int board_type) | |
141 | { | |
142 | volatile immap_t *immap = (immap_t *) CFG_IMMR; | |
143 | volatile memctl8xx_t *memctl = &immap->im_memctl; | |
144 | long int size; | |
3bac3513 | 145 | ulong refresh_val; |
16f21704 WD |
146 | |
147 | upmconfig (UPMA, (uint *) sdram_table, | |
148 | sizeof (sdram_table) / sizeof (uint)); | |
149 | ||
150 | /* | |
151 | * Preliminary prescaler for refresh | |
152 | */ | |
3bac3513 WD |
153 | if (ip860_get_clk_freq() == 50000000) |
154 | { | |
155 | memctl->memc_mptpr = 0x0400; | |
156 | refresh_val = 0xC3000000; | |
157 | } | |
158 | else | |
159 | { | |
160 | memctl->memc_mptpr = 0x0200; | |
161 | refresh_val = 0x9C000000; | |
162 | } | |
163 | ||
16f21704 WD |
164 | |
165 | memctl->memc_mar = 0x00000088; | |
166 | ||
167 | /* | |
168 | * Map controller banks 2 to the SDRAM address | |
169 | */ | |
170 | memctl->memc_or2 = CFG_OR2; | |
171 | memctl->memc_br2 = CFG_BR2; | |
172 | ||
173 | /* IP860 boards have only one bank SDRAM */ | |
174 | ||
175 | ||
176 | udelay (200); | |
177 | ||
178 | /* perform SDRAM initializsation sequence */ | |
179 | ||
3bac3513 WD |
180 | memctl->memc_mamr = 0x00804114 | refresh_val; |
181 | memctl->memc_mcr = 0x80004105; /* run precharge pattern from loc 5 */ | |
182 | udelay(1); | |
183 | memctl->memc_mamr = 0x00804118 | refresh_val; | |
184 | memctl->memc_mcr = 0x80004130; /* run refresh pattern 8 times */ | |
185 | ||
16f21704 WD |
186 | |
187 | udelay (1000); | |
188 | ||
189 | /* | |
190 | * Check SDRAM Memory Size | |
191 | */ | |
3bac3513 | 192 | if (ip860_get_dram_size() == 16) |
77ddac94 | 193 | size = dram_size (refresh_val | 0x00804114, SDRAM_BASE, SDRAM_MAX_SIZE); |
3bac3513 | 194 | else |
77ddac94 | 195 | size = dram_size (refresh_val | 0x00906114, SDRAM_BASE, SDRAM_MAX_SIZE); |
16f21704 WD |
196 | |
197 | udelay (1000); | |
198 | ||
199 | memctl->memc_or2 = ((-size) & 0xFFFF0000) | SDRAM_TIMING; | |
200 | memctl->memc_br2 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V; | |
201 | ||
202 | udelay (10000); | |
203 | ||
204 | /* | |
205 | * Also, map other memory to correct position | |
206 | */ | |
207 | ||
208 | #if (defined(CFG_OR1) && defined(CFG_BR1_PRELIM)) | |
209 | memctl->memc_or1 = CFG_OR1; | |
210 | memctl->memc_br1 = CFG_BR1; | |
211 | #endif | |
212 | ||
213 | #if defined(CFG_OR3) && defined(CFG_BR3) | |
214 | memctl->memc_or3 = CFG_OR3; | |
215 | memctl->memc_br3 = CFG_BR3; | |
216 | #endif | |
217 | ||
218 | #if defined(CFG_OR4) && defined(CFG_BR4) | |
219 | memctl->memc_or4 = CFG_OR4; | |
220 | memctl->memc_br4 = CFG_BR4; | |
221 | #endif | |
222 | ||
223 | #if defined(CFG_OR5) && defined(CFG_BR5) | |
224 | memctl->memc_or5 = CFG_OR5; | |
225 | memctl->memc_br5 = CFG_BR5; | |
226 | #endif | |
227 | ||
228 | #if defined(CFG_OR6) && defined(CFG_BR6) | |
229 | memctl->memc_or6 = CFG_OR6; | |
230 | memctl->memc_br6 = CFG_BR6; | |
231 | #endif | |
232 | ||
233 | #if defined(CFG_OR7) && defined(CFG_BR7) | |
234 | memctl->memc_or7 = CFG_OR7; | |
235 | memctl->memc_br7 = CFG_BR7; | |
236 | #endif | |
237 | ||
238 | return (size); | |
239 | } | |
240 | ||
241 | /* ------------------------------------------------------------------------- */ | |
242 | ||
243 | /* | |
244 | * Check memory range for valid RAM. A simple memory test determines | |
245 | * the actually available RAM size between addresses `base' and | |
246 | * `base + maxsize'. Some (not all) hardware errors are detected: | |
247 | * - short between address lines | |
248 | * - short between data lines | |
249 | */ | |
250 | ||
251 | static long int dram_size (long int mamr_value, long int *base, | |
252 | long int maxsize) | |
253 | { | |
254 | volatile immap_t *immap = (immap_t *) CFG_IMMR; | |
255 | volatile memctl8xx_t *memctl = &immap->im_memctl; | |
16f21704 WD |
256 | |
257 | memctl->memc_mamr = mamr_value; | |
258 | ||
c83bf6a2 | 259 | return (get_ram_size(base, maxsize)); |
16f21704 WD |
260 | } |
261 | ||
262 | /* ------------------------------------------------------------------------- */ | |
263 | ||
264 | void reset_phy (void) | |
265 | { | |
266 | volatile immap_t *immr = (immap_t *) CFG_IMMR; | |
267 | ulong mask = PB_ENET_RESET | PB_ENET_JABD; | |
268 | ulong reg; | |
269 | ||
270 | /* Make sure PHY is not in low-power mode */ | |
271 | immr->im_cpm.cp_pbpar &= ~(mask); /* GPIO */ | |
272 | immr->im_cpm.cp_pbodr &= ~(mask); /* active output */ | |
273 | ||
274 | /* Set JABD low (no JABber Disable), | |
275 | * and RESET high (Reset PHY) | |
276 | */ | |
277 | reg = immr->im_cpm.cp_pbdat; | |
278 | reg = (reg & ~PB_ENET_JABD) | PB_ENET_RESET; | |
279 | immr->im_cpm.cp_pbdat = reg; | |
280 | ||
281 | /* now drive outputs */ | |
282 | immr->im_cpm.cp_pbdir |= mask; /* output */ | |
283 | udelay (1000); | |
284 | /* | |
285 | * Release RESET signal | |
286 | */ | |
287 | immr->im_cpm.cp_pbdat &= ~(PB_ENET_RESET); | |
288 | udelay (1000); | |
289 | } | |
290 | ||
291 | /* ------------------------------------------------------------------------- */ | |
3bac3513 WD |
292 | |
293 | unsigned long ip860_get_clk_freq(void) | |
294 | { | |
295 | volatile ip860_bcsr_t *bcsr = (ip860_bcsr_t *)BCSR_BASE; | |
296 | ulong temp; | |
297 | uchar sysclk; | |
298 | ||
299 | if ((bcsr->bd_status & 0x80) == 0x80) /* bd_rev valid ? */ | |
300 | sysclk = (bcsr->bd_rev & 0x18) >> 3; | |
301 | else | |
302 | sysclk = 0x00; | |
303 | ||
304 | switch (sysclk) | |
305 | { | |
306 | case 0x00: | |
307 | temp = 50000000; | |
308 | break; | |
309 | ||
310 | case 0x01: | |
311 | temp = 80000000; | |
312 | break; | |
313 | ||
314 | default: | |
315 | temp = 50000000; | |
316 | break; | |
317 | } | |
318 | ||
319 | return (temp); | |
320 | ||
321 | } | |
322 | ||
323 | ||
324 | /* ------------------------------------------------------------------------- */ | |
325 | ||
326 | unsigned long ip860_get_dram_size(void) | |
327 | { | |
328 | volatile ip860_bcsr_t *bcsr = (ip860_bcsr_t *)BCSR_BASE; | |
329 | ulong temp; | |
330 | uchar dram_size; | |
331 | ||
332 | if ((bcsr->bd_status & 0x80) == 0x80) /* bd_rev valid ? */ | |
333 | dram_size = (bcsr->bd_rev & 0xE0) >> 5; | |
334 | else | |
335 | dram_size = 0x00; /* default is 16 MB */ | |
336 | ||
337 | switch (dram_size) | |
338 | { | |
339 | case 0x00: | |
340 | temp = 16; | |
341 | break; | |
342 | ||
343 | case 0x01: | |
344 | temp = 32; | |
345 | break; | |
346 | ||
347 | default: | |
348 | temp = 16; | |
349 | break; | |
350 | } | |
351 | ||
352 | return (temp); | |
353 | ||
354 | } | |
355 | ||
356 | /* ------------------------------------------------------------------------- */ |