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