]>
Commit | Line | Data |
---|---|---|
f8cac651 | 1 | /* |
7c803be2 | 2 | * (C) Copyright 2000-2008 |
f8cac651 WD |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
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 <mpc8xx.h> | |
1c43771b WD |
26 | #ifdef CONFIG_PS2MULT |
27 | #include <ps2mult.h> | |
28 | #endif | |
f8cac651 | 29 | |
7c803be2 WD |
30 | extern flash_info_t flash_info[]; /* FLASH chips info */ |
31 | ||
d87080b7 | 32 | DECLARE_GLOBAL_DATA_PTR; |
f8cac651 WD |
33 | |
34 | static long int dram_size (long int, long int *, long int); | |
35 | ||
f8cac651 WD |
36 | #define _NOT_USED_ 0xFFFFFFFF |
37 | ||
22d1a56c | 38 | /* UPM initialization table for SDRAM: 40, 50, 66 MHz CLKOUT @ CAS latency 2, tWR=2 */ |
f8cac651 WD |
39 | const uint sdram_table[] = |
40 | { | |
41 | /* | |
42 | * Single Read. (Offset 0 in UPMA RAM) | |
43 | */ | |
44 | 0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00, | |
45 | 0x1FF5FC47, /* last */ | |
46 | /* | |
47 | * SDRAM Initialization (offset 5 in UPMA RAM) | |
48 | * | |
49 | * This is no UPM entry point. The following definition uses | |
50 | * the remaining space to establish an initialization | |
51 | * sequence, which is executed by a RUN command. | |
52 | * | |
53 | */ | |
54 | 0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */ | |
55 | /* | |
56 | * Burst Read. (Offset 8 in UPMA RAM) | |
57 | */ | |
58 | 0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00, | |
59 | 0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */ | |
60 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
61 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
62 | /* | |
63 | * Single Write. (Offset 18 in UPMA RAM) | |
64 | */ | |
22d1a56c JG |
65 | 0x1F0DFC04, 0xEEABBC00, 0x11B77C04, 0xEFFAFC44, |
66 | 0x1FF5FC47, /* last */ | |
67 | _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
f8cac651 WD |
68 | /* |
69 | * Burst Write. (Offset 20 in UPMA RAM) | |
70 | */ | |
71 | 0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00, | |
22d1a56c | 72 | 0xF0AFFC00, 0xF0AFFC04, 0xE1BAFC44, 0x1FF5FC47, /* last */ |
f8cac651 WD |
73 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, |
74 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
75 | /* | |
76 | * Refresh (Offset 30 in UPMA RAM) | |
77 | */ | |
78 | 0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, | |
79 | 0xFFFFFC84, 0xFFFFFC07, /* last */ | |
80 | _NOT_USED_, _NOT_USED_, | |
81 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
82 | /* | |
83 | * Exception. (Offset 3c in UPMA RAM) | |
84 | */ | |
22d1a56c | 85 | 0xFFFFFC07, /* last */ |
f8cac651 WD |
86 | _NOT_USED_, _NOT_USED_, _NOT_USED_, |
87 | }; | |
88 | ||
89 | /* ------------------------------------------------------------------------- */ | |
90 | ||
91 | ||
92 | /* | |
93 | * Check Board Identity: | |
94 | * | |
95 | * Test TQ ID string (TQM8xx...) | |
96 | * If present, check for "L" type (no second DRAM bank), | |
97 | * otherwise "L" type is assumed as default. | |
98 | * | |
d4ca31c4 | 99 | * Set board_type to 'L' for "L" type, 'M' for "M" type, 0 else. |
f8cac651 WD |
100 | */ |
101 | ||
102 | int checkboard (void) | |
103 | { | |
77ddac94 | 104 | char *s = getenv ("serial#"); |
f8cac651 WD |
105 | |
106 | puts ("Board: "); | |
107 | ||
108 | if (!s || strncmp (s, "TQM8", 4)) { | |
109 | puts ("### No HW ID - assuming TQM8xxL\n"); | |
110 | return (0); | |
111 | } | |
112 | ||
113 | if ((*(s + 6) == 'L')) { /* a TQM8xxL type */ | |
114 | gd->board_type = 'L'; | |
115 | } | |
116 | ||
d4ca31c4 WD |
117 | if ((*(s + 6) == 'M')) { /* a TQM8xxM type */ |
118 | gd->board_type = 'M'; | |
119 | } | |
120 | ||
090eb735 MK |
121 | if ((*(s + 6) == 'D')) { /* a TQM885D type */ |
122 | gd->board_type = 'D'; | |
123 | } | |
124 | ||
f8cac651 WD |
125 | for (; *s; ++s) { |
126 | if (*s == ' ') | |
127 | break; | |
128 | putc (*s); | |
129 | } | |
8cba090c WD |
130 | #ifdef CONFIG_VIRTLAB2 |
131 | puts (" (Virtlab2)"); | |
132 | #endif | |
f8cac651 WD |
133 | putc ('\n'); |
134 | ||
135 | return (0); | |
136 | } | |
137 | ||
138 | /* ------------------------------------------------------------------------- */ | |
139 | ||
9973e3c6 | 140 | phys_size_t initdram (int board_type) |
f8cac651 | 141 | { |
6d0f6bcf | 142 | volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; |
f8cac651 | 143 | volatile memctl8xx_t *memctl = &immap->im_memctl; |
c178d3da | 144 | long int size8, size9, size10; |
f8cac651 WD |
145 | long int size_b0 = 0; |
146 | long int size_b1 = 0; | |
147 | ||
148 | upmconfig (UPMA, (uint *) sdram_table, | |
149 | sizeof (sdram_table) / sizeof (uint)); | |
150 | ||
151 | /* | |
152 | * Preliminary prescaler for refresh (depends on number of | |
153 | * banks): This value is selected for four cycles every 62.4 us | |
154 | * with two SDRAM banks or four cycles every 31.2 us with one | |
155 | * bank. It will be adjusted after memory sizing. | |
156 | */ | |
6d0f6bcf | 157 | memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_8K; |
f8cac651 WD |
158 | |
159 | /* | |
160 | * The following value is used as an address (i.e. opcode) for | |
161 | * the LOAD MODE REGISTER COMMAND during SDRAM initialisation. If | |
162 | * the port size is 32bit the SDRAM does NOT "see" the lower two | |
163 | * address lines, i.e. mar=0x00000088 -> opcode=0x00000022 for | |
164 | * MICRON SDRAMs: | |
165 | * -> 0 00 010 0 010 | |
166 | * | | | | +- Burst Length = 4 | |
167 | * | | | +----- Burst Type = Sequential | |
168 | * | | +------- CAS Latency = 2 | |
169 | * | +----------- Operating Mode = Standard | |
170 | * +-------------- Write Burst Mode = Programmed Burst Length | |
171 | */ | |
172 | memctl->memc_mar = 0x00000088; | |
173 | ||
174 | /* | |
175 | * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at | |
176 | * preliminary addresses - these have to be modified after the | |
177 | * SDRAM size has been determined. | |
178 | */ | |
6d0f6bcf JCPV |
179 | memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM; |
180 | memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM; | |
f8cac651 WD |
181 | |
182 | #ifndef CONFIG_CAN_DRIVER | |
d4ca31c4 | 183 | if ((board_type != 'L') && |
090eb735 | 184 | (board_type != 'M') && |
11d9eec4 | 185 | (board_type != 'D') ) { /* only one SDRAM bank on L, M and D modules */ |
6d0f6bcf JCPV |
186 | memctl->memc_or3 = CONFIG_SYS_OR3_PRELIM; |
187 | memctl->memc_br3 = CONFIG_SYS_BR3_PRELIM; | |
f8cac651 WD |
188 | } |
189 | #endif /* CONFIG_CAN_DRIVER */ | |
190 | ||
6d0f6bcf | 191 | memctl->memc_mamr = CONFIG_SYS_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */ |
f8cac651 WD |
192 | |
193 | udelay (200); | |
194 | ||
195 | /* perform SDRAM initializsation sequence */ | |
196 | ||
197 | memctl->memc_mcr = 0x80004105; /* SDRAM bank 0 */ | |
198 | udelay (1); | |
199 | memctl->memc_mcr = 0x80004230; /* SDRAM bank 0 - execute twice */ | |
200 | udelay (1); | |
201 | ||
202 | #ifndef CONFIG_CAN_DRIVER | |
d4ca31c4 | 203 | if ((board_type != 'L') && |
090eb735 | 204 | (board_type != 'M') && |
fc1840e8 | 205 | (board_type != 'D') ) { /* only one SDRAM bank on L, M and D modules */ |
f8cac651 WD |
206 | memctl->memc_mcr = 0x80006105; /* SDRAM bank 1 */ |
207 | udelay (1); | |
208 | memctl->memc_mcr = 0x80006230; /* SDRAM bank 1 - execute twice */ | |
209 | udelay (1); | |
210 | } | |
211 | #endif /* CONFIG_CAN_DRIVER */ | |
212 | ||
213 | memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */ | |
214 | ||
215 | udelay (1000); | |
216 | ||
217 | /* | |
218 | * Check Bank 0 Memory Size for re-configuration | |
219 | * | |
220 | * try 8 column mode | |
221 | */ | |
6d0f6bcf | 222 | size8 = dram_size (CONFIG_SYS_MAMR_8COL, SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE); |
d4ca31c4 | 223 | debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size8 >> 20); |
f8cac651 WD |
224 | |
225 | udelay (1000); | |
226 | ||
227 | /* | |
228 | * try 9 column mode | |
229 | */ | |
6d0f6bcf | 230 | size9 = dram_size (CONFIG_SYS_MAMR_9COL, SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE); |
d4ca31c4 | 231 | debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size9 >> 20); |
f8cac651 | 232 | |
c178d3da WD |
233 | udelay(1000); |
234 | ||
6d0f6bcf | 235 | #if defined(CONFIG_SYS_MAMR_10COL) |
c178d3da WD |
236 | /* |
237 | * try 10 column mode | |
238 | */ | |
6d0f6bcf | 239 | size10 = dram_size (CONFIG_SYS_MAMR_10COL, SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE); |
c178d3da WD |
240 | debug ("SDRAM Bank 0 in 10 column mode: %ld MB\n", size10 >> 20); |
241 | #else | |
242 | size10 = 0; | |
6d0f6bcf | 243 | #endif /* CONFIG_SYS_MAMR_10COL */ |
c178d3da WD |
244 | |
245 | if ((size8 < size10) && (size9 < size10)) { | |
246 | size_b0 = size10; | |
247 | } else if ((size8 < size9) && (size10 < size9)) { | |
f8cac651 | 248 | size_b0 = size9; |
6d0f6bcf | 249 | memctl->memc_mamr = CONFIG_SYS_MAMR_9COL; |
c178d3da WD |
250 | udelay (500); |
251 | } else { | |
f8cac651 | 252 | size_b0 = size8; |
6d0f6bcf | 253 | memctl->memc_mamr = CONFIG_SYS_MAMR_8COL; |
f8cac651 | 254 | udelay (500); |
f8cac651 | 255 | } |
d4ca31c4 | 256 | debug ("SDRAM Bank 0: %ld MB\n", size_b0 >> 20); |
f8cac651 WD |
257 | |
258 | #ifndef CONFIG_CAN_DRIVER | |
d4ca31c4 | 259 | if ((board_type != 'L') && |
090eb735 | 260 | (board_type != 'M') && |
11d9eec4 | 261 | (board_type != 'D') ) { /* only one SDRAM bank on L, M and D modules */ |
f8cac651 WD |
262 | /* |
263 | * Check Bank 1 Memory Size | |
264 | * use current column settings | |
265 | * [9 column SDRAM may also be used in 8 column mode, | |
266 | * but then only half the real size will be used.] | |
267 | */ | |
77ddac94 | 268 | size_b1 = dram_size (memctl->memc_mamr, (long int *)SDRAM_BASE3_PRELIM, |
d4ca31c4 WD |
269 | SDRAM_MAX_SIZE); |
270 | debug ("SDRAM Bank 1: %ld MB\n", size_b1 >> 20); | |
f8cac651 WD |
271 | } else { |
272 | size_b1 = 0; | |
273 | } | |
d4ca31c4 | 274 | #endif /* CONFIG_CAN_DRIVER */ |
f8cac651 WD |
275 | |
276 | udelay (1000); | |
277 | ||
278 | /* | |
279 | * Adjust refresh rate depending on SDRAM type, both banks | |
280 | * For types > 128 MBit leave it at the current (fast) rate | |
281 | */ | |
282 | if ((size_b0 < 0x02000000) && (size_b1 < 0x02000000)) { | |
283 | /* reduce to 15.6 us (62.4 us / quad) */ | |
6d0f6bcf | 284 | memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_4K; |
f8cac651 WD |
285 | udelay (1000); |
286 | } | |
287 | ||
288 | /* | |
289 | * Final mapping: map bigger bank first | |
290 | */ | |
291 | if (size_b1 > size_b0) { /* SDRAM Bank 1 is bigger - map first */ | |
292 | ||
6d0f6bcf JCPV |
293 | memctl->memc_or3 = ((-size_b1) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM; |
294 | memctl->memc_br3 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V; | |
f8cac651 WD |
295 | |
296 | if (size_b0 > 0) { | |
297 | /* | |
298 | * Position Bank 0 immediately above Bank 1 | |
299 | */ | |
6d0f6bcf JCPV |
300 | memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM; |
301 | memctl->memc_br2 = ((CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V) | |
c178d3da | 302 | + size_b1; |
f8cac651 WD |
303 | } else { |
304 | unsigned long reg; | |
305 | ||
306 | /* | |
307 | * No bank 0 | |
308 | * | |
309 | * invalidate bank | |
310 | */ | |
311 | memctl->memc_br2 = 0; | |
312 | ||
313 | /* adjust refresh rate depending on SDRAM type, one bank */ | |
314 | reg = memctl->memc_mptpr; | |
6d0f6bcf | 315 | reg >>= 1; /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */ |
f8cac651 WD |
316 | memctl->memc_mptpr = reg; |
317 | } | |
318 | ||
319 | } else { /* SDRAM Bank 0 is bigger - map first */ | |
320 | ||
6d0f6bcf | 321 | memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM; |
f8cac651 | 322 | memctl->memc_br2 = |
6d0f6bcf | 323 | (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V; |
f8cac651 WD |
324 | |
325 | if (size_b1 > 0) { | |
326 | /* | |
327 | * Position Bank 1 immediately above Bank 0 | |
328 | */ | |
329 | memctl->memc_or3 = | |
6d0f6bcf | 330 | ((-size_b1) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM; |
f8cac651 | 331 | memctl->memc_br3 = |
6d0f6bcf | 332 | ((CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V) |
f8cac651 WD |
333 | + size_b0; |
334 | } else { | |
335 | unsigned long reg; | |
336 | ||
337 | #ifndef CONFIG_CAN_DRIVER | |
338 | /* | |
339 | * No bank 1 | |
340 | * | |
341 | * invalidate bank | |
342 | */ | |
343 | memctl->memc_br3 = 0; | |
344 | #endif /* CONFIG_CAN_DRIVER */ | |
345 | ||
346 | /* adjust refresh rate depending on SDRAM type, one bank */ | |
347 | reg = memctl->memc_mptpr; | |
6d0f6bcf | 348 | reg >>= 1; /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */ |
f8cac651 WD |
349 | memctl->memc_mptpr = reg; |
350 | } | |
351 | } | |
352 | ||
353 | udelay (10000); | |
354 | ||
355 | #ifdef CONFIG_CAN_DRIVER | |
9d29250e JG |
356 | /* UPM initialization for CAN @ CLKOUT <= 66 MHz */ |
357 | ||
f8cac651 | 358 | /* Initialize OR3 / BR3 */ |
6d0f6bcf JCPV |
359 | memctl->memc_or3 = CONFIG_SYS_OR3_CAN; |
360 | memctl->memc_br3 = CONFIG_SYS_BR3_CAN; | |
f8cac651 WD |
361 | |
362 | /* Initialize MBMR */ | |
fd3103bb | 363 | memctl->memc_mbmr = MBMR_GPL_B4DIS; /* GPL_B4 ouput line Disable */ |
f8cac651 WD |
364 | |
365 | /* Initialize UPMB for CAN: single read */ | |
9d29250e | 366 | memctl->memc_mdr = 0xFFFFCC04; |
f8cac651 WD |
367 | memctl->memc_mcr = 0x0100 | UPMB; |
368 | ||
369 | memctl->memc_mdr = 0x0FFFD004; | |
370 | memctl->memc_mcr = 0x0101 | UPMB; | |
371 | ||
372 | memctl->memc_mdr = 0x0FFFC000; | |
373 | memctl->memc_mcr = 0x0102 | UPMB; | |
374 | ||
375 | memctl->memc_mdr = 0x3FFFC004; | |
376 | memctl->memc_mcr = 0x0103 | UPMB; | |
377 | ||
9d29250e | 378 | memctl->memc_mdr = 0xFFFFDC07; |
f8cac651 WD |
379 | memctl->memc_mcr = 0x0104 | UPMB; |
380 | ||
381 | /* Initialize UPMB for CAN: single write */ | |
9d29250e | 382 | memctl->memc_mdr = 0xFFFCCC04; |
f8cac651 WD |
383 | memctl->memc_mcr = 0x0118 | UPMB; |
384 | ||
9d29250e | 385 | memctl->memc_mdr = 0xCFFCDC04; |
f8cac651 WD |
386 | memctl->memc_mcr = 0x0119 | UPMB; |
387 | ||
9d29250e | 388 | memctl->memc_mdr = 0x3FFCC000; |
f8cac651 WD |
389 | memctl->memc_mcr = 0x011A | UPMB; |
390 | ||
9d29250e | 391 | memctl->memc_mdr = 0xFFFCC004; |
f8cac651 WD |
392 | memctl->memc_mcr = 0x011B | UPMB; |
393 | ||
9d29250e | 394 | memctl->memc_mdr = 0xFFFDC405; |
f8cac651 WD |
395 | memctl->memc_mcr = 0x011C | UPMB; |
396 | #endif /* CONFIG_CAN_DRIVER */ | |
397 | ||
bdccc4fe WD |
398 | #ifdef CONFIG_ISP1362_USB |
399 | /* Initialize OR5 / BR5 */ | |
6d0f6bcf JCPV |
400 | memctl->memc_or5 = CONFIG_SYS_OR5_ISP1362; |
401 | memctl->memc_br5 = CONFIG_SYS_BR5_ISP1362; | |
bdccc4fe | 402 | #endif /* CONFIG_ISP1362_USB */ |
f8cac651 WD |
403 | return (size_b0 + size_b1); |
404 | } | |
405 | ||
406 | /* ------------------------------------------------------------------------- */ | |
407 | ||
408 | /* | |
409 | * Check memory range for valid RAM. A simple memory test determines | |
410 | * the actually available RAM size between addresses `base' and | |
411 | * `base + maxsize'. Some (not all) hardware errors are detected: | |
412 | * - short between address lines | |
413 | * - short between data lines | |
414 | */ | |
415 | ||
d4ca31c4 | 416 | static long int dram_size (long int mamr_value, long int *base, long int maxsize) |
f8cac651 | 417 | { |
6d0f6bcf | 418 | volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; |
f8cac651 | 419 | volatile memctl8xx_t *memctl = &immap->im_memctl; |
f8cac651 WD |
420 | |
421 | memctl->memc_mamr = mamr_value; | |
422 | ||
c83bf6a2 | 423 | return (get_ram_size(base, maxsize)); |
f8cac651 WD |
424 | } |
425 | ||
426 | /* ------------------------------------------------------------------------- */ | |
1c43771b WD |
427 | |
428 | #ifdef CONFIG_PS2MULT | |
429 | ||
c40b2956 | 430 | #ifdef CONFIG_HMI10 |
1c43771b WD |
431 | #define BASE_BAUD ( 1843200 / 16 ) |
432 | struct serial_state rs_table[] = { | |
433 | { BASE_BAUD, 4, (void*)0xec140000 }, | |
434 | { BASE_BAUD, 2, (void*)0xec150000 }, | |
435 | { BASE_BAUD, 6, (void*)0xec160000 }, | |
436 | { BASE_BAUD, 10, (void*)0xec170000 }, | |
437 | }; | |
c837dcb1 WD |
438 | |
439 | #ifdef CONFIG_BOARD_EARLY_INIT_R | |
440 | int board_early_init_r (void) | |
441 | { | |
442 | ps2mult_early_init(); | |
443 | return (0); | |
444 | } | |
445 | #endif | |
c40b2956 | 446 | #endif /* CONFIG_HMI10 */ |
1c43771b WD |
447 | |
448 | #endif /* CONFIG_PS2MULT */ | |
449 | ||
1c43771b | 450 | |
7c803be2 | 451 | #ifdef CONFIG_MISC_INIT_R |
1c43771b WD |
452 | int misc_init_r (void) |
453 | { | |
6d0f6bcf | 454 | volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; |
7c803be2 WD |
455 | volatile memctl8xx_t *memctl = &immap->im_memctl; |
456 | ||
6d0f6bcf | 457 | #ifdef CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ |
7c803be2 WD |
458 | int scy, trlx, flash_or_timing, clk_diff; |
459 | ||
6d0f6bcf JCPV |
460 | scy = (CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ & OR_SCY_MSK) >> 4; |
461 | if (CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ & OR_TRLX) { | |
7c803be2 WD |
462 | trlx = OR_TRLX; |
463 | scy *= 2; | |
87b4ef56 | 464 | } else { |
7c803be2 | 465 | trlx = 0; |
87b4ef56 | 466 | } |
7c803be2 | 467 | |
87b4ef56 WD |
468 | /* |
469 | * We assume that each 10MHz of bus clock require 1-clk SCY | |
470 | * adjustment. | |
471 | */ | |
7c803be2 WD |
472 | clk_diff = (gd->bus_clk / 1000000) - 50; |
473 | ||
87b4ef56 WD |
474 | /* |
475 | * We need proper rounding here. This is what the "+5" and "-5" | |
476 | * are here for. | |
477 | */ | |
7c803be2 WD |
478 | if (clk_diff >= 0) |
479 | scy += (clk_diff + 5) / 10; | |
480 | else | |
481 | scy += (clk_diff - 5) / 10; | |
482 | ||
87b4ef56 WD |
483 | /* |
484 | * For bus frequencies above 50MHz, we want to use relaxed timing | |
485 | * (OR_TRLX). | |
486 | */ | |
7c803be2 WD |
487 | if (gd->bus_clk >= 50000000) |
488 | trlx = OR_TRLX; | |
489 | else | |
490 | trlx = 0; | |
491 | ||
492 | if (trlx) | |
493 | scy /= 2; | |
494 | ||
495 | if (scy > 0xf) | |
496 | scy = 0xf; | |
497 | if (scy < 1) | |
498 | scy = 1; | |
499 | ||
500 | flash_or_timing = (scy << 4) | trlx | | |
6d0f6bcf | 501 | (CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ & ~(OR_TRLX | OR_SCY_MSK)); |
7c803be2 | 502 | |
87b4ef56 WD |
503 | memctl->memc_or0 = |
504 | flash_or_timing | (-flash_info[0].size & OR_AM_MSK); | |
7c803be2 | 505 | #else |
87b4ef56 | 506 | memctl->memc_or0 = |
6d0f6bcf | 507 | CONFIG_SYS_OR_TIMING_FLASH | (-flash_info[0].size & OR_AM_MSK); |
7c803be2 | 508 | #endif |
6d0f6bcf | 509 | memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V; |
7c803be2 WD |
510 | |
511 | debug ("## BR0: 0x%08x OR0: 0x%08x\n", | |
87b4ef56 | 512 | memctl->memc_br0, memctl->memc_or0); |
1c43771b | 513 | |
7c803be2 | 514 | if (flash_info[1].size) { |
6d0f6bcf | 515 | #ifdef CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ |
7c803be2 | 516 | memctl->memc_or1 = flash_or_timing | |
87b4ef56 | 517 | (-flash_info[1].size & 0xFFFF8000); |
7c803be2 | 518 | #else |
6d0f6bcf | 519 | memctl->memc_or1 = CONFIG_SYS_OR_TIMING_FLASH | |
87b4ef56 | 520 | (-flash_info[1].size & 0xFFFF8000); |
7c803be2 | 521 | #endif |
87b4ef56 | 522 | memctl->memc_br1 = |
6d0f6bcf | 523 | ((CONFIG_SYS_FLASH_BASE + |
87b4ef56 WD |
524 | flash_info[0]. |
525 | size) & BR_BA_MSK) | BR_MS_GPCM | BR_V; | |
7c803be2 WD |
526 | |
527 | debug ("## BR1: 0x%08x OR1: 0x%08x\n", | |
87b4ef56 | 528 | memctl->memc_br1, memctl->memc_or1); |
7c803be2 | 529 | } else { |
87b4ef56 | 530 | memctl->memc_br1 = 0; /* invalidate bank */ |
7c803be2 WD |
531 | |
532 | debug ("## DISABLE BR1: 0x%08x OR1: 0x%08x\n", | |
87b4ef56 | 533 | memctl->memc_br1, memctl->memc_or1); |
7c803be2 WD |
534 | } |
535 | ||
536 | # ifdef CONFIG_IDE_LED | |
1c43771b WD |
537 | /* Configure PA15 as output port */ |
538 | immap->im_ioport.iop_padir |= 0x0001; | |
539 | immap->im_ioport.iop_paodr |= 0x0001; | |
540 | immap->im_ioport.iop_papar &= ~0x0001; | |
541 | immap->im_ioport.iop_padat &= ~0x0001; /* turn it off */ | |
cfca5e60 | 542 | # endif |
7c803be2 WD |
543 | |
544 | #ifdef CONFIG_NSCU | |
545 | /* wake up ethernet module */ | |
87b4ef56 WD |
546 | immap->im_ioport.iop_pcpar &= ~0x0004; /* GPIO pin */ |
547 | immap->im_ioport.iop_pcdir |= 0x0004; /* output */ | |
548 | immap->im_ioport.iop_pcso &= ~0x0004; /* for clarity */ | |
549 | immap->im_ioport.iop_pcdat |= 0x0004; /* enable */ | |
550 | #endif /* CONFIG_NSCU */ | |
7c803be2 | 551 | |
1c43771b WD |
552 | return (0); |
553 | } | |
7c803be2 WD |
554 | #endif /* CONFIG_MISC_INIT_R */ |
555 | ||
1c43771b | 556 | |
cfca5e60 | 557 | # ifdef CONFIG_IDE_LED |
1c43771b WD |
558 | void ide_led (uchar led, uchar status) |
559 | { | |
6d0f6bcf | 560 | volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; |
1c43771b WD |
561 | |
562 | /* We have one led for both pcmcia slots */ | |
563 | if (status) { /* led on */ | |
564 | immap->im_ioport.iop_padat |= 0x0001; | |
565 | } else { | |
566 | immap->im_ioport.iop_padat &= ~0x0001; | |
567 | } | |
568 | } | |
cfca5e60 | 569 | # endif |
1c43771b | 570 | |
efc6f447 GL |
571 | /* ---------------------------------------------------------------------------- */ |
572 | /* TK885D specific initializaion */ | |
573 | /* ---------------------------------------------------------------------------- */ | |
574 | #ifdef CONFIG_TK885D | |
575 | #include <miiphy.h> | |
576 | int last_stage_init(void) | |
577 | { | |
578 | const unsigned char phy[] = {CONFIG_FEC1_PHY, CONFIG_FEC2_PHY}; | |
579 | unsigned short reg; | |
580 | int ret, i = 100; | |
581 | char *s; | |
582 | ||
583 | mii_init(); | |
584 | /* Without this delay 0xff is read from the UART buffer later in | |
585 | * abortboot() and autoboot is aborted */ | |
586 | udelay(10000); | |
587 | while (tstc() && i--) | |
588 | (void)getc(); | |
589 | ||
590 | /* Check if auto-negotiation is prohibited */ | |
591 | s = getenv("phy_auto_nego"); | |
592 | ||
593 | if (!s || !strcmp(s, "on")) | |
594 | /* Nothing to do - autonegotiation by default */ | |
595 | return 0; | |
596 | ||
597 | for (i = 0; i < 2; i++) { | |
598 | ret = miiphy_read("FEC ETHERNET", phy[i], PHY_BMCR, ®); | |
599 | if (ret) { | |
600 | printf("Cannot read BMCR on PHY %d\n", phy[i]); | |
601 | return 0; | |
602 | } | |
603 | /* Auto-negotiation off, hard set full duplex, 100Mbps */ | |
604 | ret = miiphy_write("FEC ETHERNET", phy[i], | |
605 | PHY_BMCR, (reg | PHY_BMCR_100MB | | |
606 | PHY_BMCR_DPLX) & ~PHY_BMCR_AUTON); | |
607 | if (ret) { | |
608 | printf("Cannot write BMCR on PHY %d\n", phy[i]); | |
609 | return 0; | |
610 | } | |
611 | } | |
612 | ||
613 | return 0; | |
614 | } | |
efc6f447 | 615 | #endif |