]>
Commit | Line | Data |
---|---|---|
56523f12 | 1 | /* |
45a212c4 | 2 | * (C) Copyright 2003-2006 |
56523f12 WD |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
4 | * | |
5 | * (C) Copyright 2004 | |
6 | * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. | |
7 | * | |
45a212c4 | 8 | * (C) Copyright 2004-2006 |
56523f12 WD |
9 | * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de |
10 | * | |
3765b3e7 | 11 | * SPDX-License-Identifier: GPL-2.0+ |
56523f12 WD |
12 | */ |
13 | ||
14 | #include <common.h> | |
24b852a7 | 15 | #include <console.h> |
56523f12 WD |
16 | #include <mpc5xxx.h> |
17 | #include <pci.h> | |
45a212c4 | 18 | #include <asm/processor.h> |
cf2817a8 | 19 | #include <libfdt.h> |
19403633 | 20 | #include <netdev.h> |
0a6eac84 | 21 | #include <video.h> |
8f8416fa | 22 | |
8f0b7cbe WD |
23 | #ifdef CONFIG_VIDEO_SM501 |
24 | #include <sm501.h> | |
25 | #endif | |
26 | ||
56523f12 WD |
27 | #if defined(CONFIG_MPC5200_DDR) |
28 | #include "mt46v16m16-75.h" | |
29 | #else | |
30 | #include "mt48lc16m16a2-75.h" | |
31 | #endif | |
8f0b7cbe | 32 | |
c313b2c6 MK |
33 | #ifdef CONFIG_OF_LIBFDT |
34 | #include <fdt_support.h> | |
35 | #endif /* CONFIG_OF_LIBFDT */ | |
36 | ||
1218abf1 WD |
37 | DECLARE_GLOBAL_DATA_PTR; |
38 | ||
7e6bf358 WD |
39 | #ifdef CONFIG_PS2MULT |
40 | void ps2mult_early_init(void); | |
41 | #endif | |
56523f12 | 42 | |
42df1e16 WD |
43 | #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) && \ |
44 | defined(CONFIG_VIDEO) | |
98e69567 HS |
45 | /* |
46 | * EDID block has been generated using Phoenix EDID Designer 1.3. | |
47 | * This tool creates a text file containing: | |
48 | * | |
49 | * EDID BYTES: | |
50 | * | |
51 | * 0x 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | |
52 | * ------------------------------------------------ | |
53 | * 00 | 00 FF FF FF FF FF FF 00 04 21 00 00 00 00 00 00 | |
54 | * 10 | 01 00 01 03 00 00 00 00 00 00 00 00 00 00 00 00 | |
55 | * 20 | 00 00 00 21 00 00 01 01 01 01 01 01 01 01 01 01 | |
56 | * 30 | 01 01 01 01 01 01 64 00 00 00 00 00 00 00 00 00 | |
57 | * 40 | 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 | |
58 | * 50 | 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 | |
59 | * 60 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 | |
60 | * 70 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 | |
61 | * | |
62 | * Then this data has been manually converted to the char | |
63 | * array below. | |
64 | */ | |
65 | static unsigned char edid_buf[128] = { | |
66 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, | |
67 | 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
68 | 0x01, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, | |
69 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
70 | 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x01, 0x01, | |
71 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, | |
72 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x64, 0x00, | |
73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
74 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
75 | 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, | |
76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, | |
78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
79 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, | |
80 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
81 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, | |
82 | }; | |
83 | #endif | |
84 | ||
6d0f6bcf | 85 | #ifndef CONFIG_SYS_RAMBOOT |
56523f12 WD |
86 | static void sdram_start (int hi_addr) |
87 | { | |
88 | long hi_addr_bit = hi_addr ? 0x01000000 : 0; | |
89 | ||
90 | /* unlock mode register */ | |
91 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | | |
92 | hi_addr_bit; | |
93 | __asm__ volatile ("sync"); | |
94 | ||
95 | /* precharge all banks */ | |
96 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | | |
97 | hi_addr_bit; | |
98 | __asm__ volatile ("sync"); | |
99 | ||
100 | #if SDRAM_DDR | |
101 | /* set mode register: extended mode */ | |
102 | *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE; | |
103 | __asm__ volatile ("sync"); | |
104 | ||
105 | /* set mode register: reset DLL */ | |
106 | *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000; | |
107 | __asm__ volatile ("sync"); | |
108 | #endif | |
109 | ||
110 | /* precharge all banks */ | |
111 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | | |
112 | hi_addr_bit; | |
113 | __asm__ volatile ("sync"); | |
114 | ||
115 | /* auto refresh */ | |
116 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | | |
117 | hi_addr_bit; | |
118 | __asm__ volatile ("sync"); | |
119 | ||
120 | /* set mode register */ | |
121 | *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE; | |
122 | __asm__ volatile ("sync"); | |
123 | ||
124 | /* normal operation */ | |
125 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit; | |
126 | __asm__ volatile ("sync"); | |
127 | } | |
128 | #endif | |
129 | ||
130 | /* | |
f1683aa7 | 131 | * ATTENTION: Although partially referenced dram_init does NOT make real use |
6d0f6bcf | 132 | * use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE |
81050926 | 133 | * is something else than 0x00000000. |
56523f12 WD |
134 | */ |
135 | ||
f1683aa7 | 136 | int dram_init(void) |
56523f12 WD |
137 | { |
138 | ulong dramsize = 0; | |
139 | ulong dramsize2 = 0; | |
45a212c4 WD |
140 | uint svr, pvr; |
141 | ||
6d0f6bcf | 142 | #ifndef CONFIG_SYS_RAMBOOT |
56523f12 WD |
143 | ulong test1, test2; |
144 | ||
145 | /* setup SDRAM chip selects */ | |
146 | *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001c; /* 512MB at 0x0 */ | |
147 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x40000000; /* disabled */ | |
148 | __asm__ volatile ("sync"); | |
149 | ||
150 | /* setup config registers */ | |
151 | *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1; | |
152 | *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2; | |
153 | __asm__ volatile ("sync"); | |
154 | ||
155 | #if SDRAM_DDR | |
156 | /* set tap delay */ | |
157 | *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY; | |
158 | __asm__ volatile ("sync"); | |
159 | #endif | |
160 | ||
161 | /* find RAM size using SDRAM CS0 only */ | |
162 | sdram_start(0); | |
6d0f6bcf | 163 | test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000); |
56523f12 | 164 | sdram_start(1); |
6d0f6bcf | 165 | test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000); |
56523f12 WD |
166 | if (test1 > test2) { |
167 | sdram_start(0); | |
168 | dramsize = test1; | |
169 | } else { | |
170 | dramsize = test2; | |
171 | } | |
172 | ||
173 | /* memory smaller than 1MB is impossible */ | |
174 | if (dramsize < (1 << 20)) { | |
175 | dramsize = 0; | |
176 | } | |
177 | ||
178 | /* set SDRAM CS0 size according to the amount of RAM found */ | |
179 | if (dramsize > 0) { | |
180 | *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + | |
181 | __builtin_ffs(dramsize >> 20) - 1; | |
182 | } else { | |
183 | *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */ | |
184 | } | |
185 | ||
186 | /* let SDRAM CS1 start right after CS0 */ | |
187 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001c; /* 512MB */ | |
188 | ||
189 | /* find RAM size using SDRAM CS1 only */ | |
f3a329ac MK |
190 | if (!dramsize) |
191 | sdram_start(0); | |
6d0f6bcf | 192 | test2 = test1 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000); |
f3a329ac MK |
193 | if (!dramsize) { |
194 | sdram_start(1); | |
6d0f6bcf | 195 | test2 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000); |
f3a329ac | 196 | } |
56523f12 WD |
197 | if (test1 > test2) { |
198 | sdram_start(0); | |
199 | dramsize2 = test1; | |
200 | } else { | |
201 | dramsize2 = test2; | |
202 | } | |
203 | ||
204 | /* memory smaller than 1MB is impossible */ | |
205 | if (dramsize2 < (1 << 20)) { | |
206 | dramsize2 = 0; | |
207 | } | |
208 | ||
209 | /* set SDRAM CS1 size according to the amount of RAM found */ | |
210 | if (dramsize2 > 0) { | |
211 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize | |
212 | | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1); | |
213 | } else { | |
214 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */ | |
215 | } | |
216 | ||
6d0f6bcf | 217 | #else /* CONFIG_SYS_RAMBOOT */ |
56523f12 WD |
218 | |
219 | /* retrieve size of memory connected to SDRAM CS0 */ | |
220 | dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF; | |
221 | if (dramsize >= 0x13) { | |
222 | dramsize = (1 << (dramsize - 0x13)) << 20; | |
223 | } else { | |
224 | dramsize = 0; | |
225 | } | |
226 | ||
227 | /* retrieve size of memory connected to SDRAM CS1 */ | |
228 | dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF; | |
229 | if (dramsize2 >= 0x13) { | |
230 | dramsize2 = (1 << (dramsize2 - 0x13)) << 20; | |
231 | } else { | |
232 | dramsize2 = 0; | |
233 | } | |
6d0f6bcf | 234 | #endif /* CONFIG_SYS_RAMBOOT */ |
56523f12 | 235 | |
45a212c4 WD |
236 | /* |
237 | * On MPC5200B we need to set the special configuration delay in the | |
238 | * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM | |
239 | * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190: | |
240 | * | |
241 | * "The SDelay should be written to a value of 0x00000004. It is | |
242 | * required to account for changes caused by normal wafer processing | |
243 | * parameters." | |
244 | */ | |
245 | svr = get_svr(); | |
246 | pvr = get_pvr(); | |
247 | if ((SVR_MJREV(svr) >= 2) && | |
248 | (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) { | |
249 | ||
250 | *(vu_long *)MPC5XXX_SDRAM_SDELAY = 0x04; | |
251 | __asm__ volatile ("sync"); | |
252 | } | |
253 | ||
254 | #if defined(CONFIG_TQM5200_B) | |
088454cd | 255 | gd->ram_size = dramsize + dramsize2; |
45a212c4 | 256 | #else |
088454cd | 257 | gd->ram_size = dramsize; |
45a212c4 | 258 | #endif /* CONFIG_TQM5200_B */ |
088454cd SG |
259 | |
260 | return 0; | |
56523f12 WD |
261 | } |
262 | ||
56523f12 WD |
263 | int checkboard (void) |
264 | { | |
5078cce8 WD |
265 | #if defined(CONFIG_TQM5200S) |
266 | # define MODULE_NAME "TQM5200S" | |
45a212c4 | 267 | #else |
5078cce8 | 268 | # define MODULE_NAME "TQM5200" |
7e6bf358 | 269 | #endif |
5078cce8 WD |
270 | |
271 | #if defined(CONFIG_STK52XX) | |
272 | # define CARRIER_NAME "STK52xx" | |
135ae006 | 273 | #elif defined(CONFIG_CAM5200) |
78d620eb | 274 | # define CARRIER_NAME "CAM5200" |
6d3bc9b8 MB |
275 | #elif defined(CONFIG_FO300) |
276 | # define CARRIER_NAME "FO300" | |
98e69567 HS |
277 | #elif defined(CONFIG_CHARON) |
278 | # define CARRIER_NAME "CHARON" | |
5078cce8 | 279 | #else |
5196a7a0 | 280 | # error "UNKNOWN" |
b87dfd28 | 281 | #endif |
7e6bf358 | 282 | |
5078cce8 WD |
283 | puts ( "Board: " MODULE_NAME " (TQ-Components GmbH)\n" |
284 | " on a " CARRIER_NAME " carrier board\n"); | |
285 | ||
56523f12 WD |
286 | return 0; |
287 | } | |
288 | ||
5078cce8 WD |
289 | #undef MODULE_NAME |
290 | #undef CARRIER_NAME | |
291 | ||
56523f12 WD |
292 | void flash_preinit(void) |
293 | { | |
294 | /* | |
295 | * Now, when we are in RAM, enable flash write | |
296 | * access for detection process. | |
297 | * Note that CS_BOOT cannot be cleared when | |
298 | * executing in flash. | |
299 | */ | |
56523f12 WD |
300 | *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */ |
301 | } | |
302 | ||
303 | ||
304 | #ifdef CONFIG_PCI | |
305 | static struct pci_controller hose; | |
306 | ||
307 | extern void pci_mpc5xxx_init(struct pci_controller *); | |
308 | ||
309 | void pci_init_board(void) | |
310 | { | |
311 | pci_mpc5xxx_init(&hose); | |
312 | } | |
313 | #endif | |
314 | ||
fc843a02 | 315 | #if defined(CONFIG_IDE) && defined(CONFIG_IDE_RESET) |
56523f12 WD |
316 | |
317 | #if defined (CONFIG_MINIFAP) | |
318 | #define SM501_POWER_MODE0_GATE 0x00000040UL | |
319 | #define SM501_POWER_MODE1_GATE 0x00000048UL | |
320 | #define POWER_MODE_GATE_GPIO_PWM_I2C 0x00000040UL | |
321 | #define SM501_GPIO_DATA_DIR_HIGH 0x0001000CUL | |
322 | #define SM501_GPIO_DATA_HIGH 0x00010004UL | |
323 | #define SM501_GPIO_51 0x00080000UL | |
dae80f3c | 324 | #endif /* CONFIG MINIFAP */ |
56523f12 WD |
325 | |
326 | void init_ide_reset (void) | |
327 | { | |
328 | debug ("init_ide_reset\n"); | |
329 | ||
330 | #if defined (CONFIG_MINIFAP) | |
331 | /* Configure GPIO_51 of the SM501 grafic controller as ATA reset */ | |
332 | ||
333 | /* enable GPIO control (in both power modes) */ | |
334 | *(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE0_GATE) |= | |
335 | POWER_MODE_GATE_GPIO_PWM_I2C; | |
336 | *(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE1_GATE) |= | |
337 | POWER_MODE_GATE_GPIO_PWM_I2C; | |
338 | /* configure GPIO51 as output */ | |
339 | *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_DIR_HIGH) |= | |
340 | SM501_GPIO_51; | |
341 | #else | |
342 | /* Configure PSC1_4 as GPIO output for ATA reset */ | |
343 | *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4; | |
344 | *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4; | |
8f2a68a0 MK |
345 | |
346 | /* by default the ATA reset is de-asserted */ | |
347 | *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4; | |
56523f12 WD |
348 | #endif |
349 | } | |
350 | ||
351 | void ide_set_reset (int idereset) | |
352 | { | |
353 | debug ("ide_reset(%d)\n", idereset); | |
354 | ||
355 | #if defined (CONFIG_MINIFAP) | |
356 | if (idereset) { | |
357 | *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) &= | |
358 | ~SM501_GPIO_51; | |
359 | } else { | |
360 | *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) |= | |
361 | SM501_GPIO_51; | |
362 | } | |
363 | #else | |
364 | if (idereset) { | |
dae80f3c | 365 | *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4; |
56523f12 | 366 | } else { |
dae80f3c | 367 | *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4; |
56523f12 WD |
368 | } |
369 | #endif | |
370 | } | |
d39b5741 | 371 | #endif |
56523f12 WD |
372 | |
373 | #ifdef CONFIG_POST | |
374 | /* | |
375 | * Reads GPIO pin PSC6_3. A keypress is reported, if PSC6_3 is low. If PSC6_3 | |
376 | * is left open, no keypress is detected. | |
377 | */ | |
378 | int post_hotkeys_pressed(void) | |
379 | { | |
1d92b2e5 | 380 | #ifdef CONFIG_STK52XX |
56523f12 WD |
381 | struct mpc5xxx_gpio *gpio; |
382 | ||
383 | gpio = (struct mpc5xxx_gpio*) MPC5XXX_GPIO; | |
384 | ||
385 | /* | |
95c44ec4 | 386 | * Configure PSC6_0 through PSC6_3 as GPIO. |
81050926 | 387 | */ |
95c44ec4 | 388 | gpio->port_config &= ~(0x00700000); |
56523f12 WD |
389 | |
390 | /* Enable GPIO for GPIO_IRDA_1 (IR_USB_CLK pin) = PSC6_3 */ | |
391 | gpio->simple_gpioe |= 0x20000000; | |
392 | ||
393 | /* Configure GPIO_IRDA_1 as input */ | |
394 | gpio->simple_ddr &= ~(0x20000000); | |
395 | ||
396 | return ((gpio->simple_ival & 0x20000000) ? 0 : 1); | |
1d92b2e5 WD |
397 | #else |
398 | return 0; | |
399 | #endif | |
56523f12 WD |
400 | } |
401 | #endif | |
402 | ||
7e6bf358 WD |
403 | #ifdef CONFIG_BOARD_EARLY_INIT_R |
404 | int board_early_init_r (void) | |
405 | { | |
6a40ef62 | 406 | |
409ecdc0 WD |
407 | extern int usb_cpu_init(void); |
408 | ||
245a362a | 409 | #ifdef CONFIG_PS2MULT |
7e6bf358 | 410 | ps2mult_early_init(); |
245a362a MB |
411 | #endif /* CONFIG_PS2MULT */ |
412 | ||
6d0f6bcf | 413 | #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) |
245a362a MB |
414 | /* Low level USB init, required for proper kernel operation */ |
415 | usb_cpu_init(); | |
416 | #endif | |
417 | ||
7e6bf358 WD |
418 | return (0); |
419 | } | |
420 | #endif | |
7e6bf358 | 421 | |
aeec782b WD |
422 | #ifdef CONFIG_FO300 |
423 | int silent_boot (void) | |
424 | { | |
425 | vu_long timer3_status; | |
426 | ||
427 | /* Configure GPT3 as GPIO input */ | |
428 | *(vu_long *)MPC5XXX_GPT3_ENABLE = 0x00000004; | |
429 | ||
430 | /* Read in TIMER_3 pin status */ | |
431 | timer3_status = *(vu_long *)MPC5XXX_GPT3_STATUS; | |
432 | ||
433 | #ifdef FO300_SILENT_CONSOLE_WHEN_S1_CLOSED | |
434 | /* Force silent console mode if S1 switch | |
435 | * is in closed position (TIMER_3 pin status is LOW). */ | |
436 | if (MPC5XXX_GPT_GPIO_PIN(timer3_status) == 0) | |
437 | return 1; | |
438 | #else | |
439 | /* Force silent console mode if S1 switch | |
440 | * is in open position (TIMER_3 pin status is HIGH). */ | |
441 | if (MPC5XXX_GPT_GPIO_PIN(timer3_status) == 1) | |
442 | return 1; | |
443 | #endif | |
444 | ||
445 | return 0; | |
446 | } | |
447 | ||
448 | int board_early_init_f (void) | |
449 | { | |
aeec782b WD |
450 | if (silent_boot()) |
451 | gd->flags |= GD_FLG_SILENT; | |
452 | ||
453 | return 0; | |
454 | } | |
455 | #endif /* CONFIG_FO300 */ | |
456 | ||
98e69567 HS |
457 | #if defined(CONFIG_CHARON) |
458 | #include <i2c.h> | |
459 | #include <asm/io.h> | |
460 | ||
461 | /* The TFP410 registers */ | |
462 | #define TFP410_REG_VEN_ID_L 0x00 | |
463 | #define TFP410_REG_VEN_ID_H 0x01 | |
464 | #define TFP410_REG_DEV_ID_L 0x02 | |
465 | #define TFP410_REG_DEV_ID_H 0x03 | |
466 | #define TFP410_REG_REV_ID 0x04 | |
467 | ||
468 | #define TFP410_REG_CTL_1_MODE 0x08 | |
469 | #define TFP410_REG_CTL_2_MODE 0x09 | |
470 | #define TFP410_REG_CTL_3_MODE 0x0A | |
471 | ||
472 | #define TFP410_REG_CFG 0x0B | |
473 | ||
474 | #define TFP410_REG_DE_DLY 0x32 | |
475 | #define TFP410_REG_DE_CTL 0x33 | |
476 | #define TFP410_REG_DE_TOP 0x34 | |
477 | #define TFP410_REG_DE_CNT_L 0x36 | |
478 | #define TFP410_REG_DE_CNT_H 0x37 | |
479 | #define TFP410_REG_DE_LIN_L 0x38 | |
480 | #define TFP410_REG_DE_LIN_H 0x39 | |
481 | ||
482 | #define TFP410_REG_H_RES_L 0x3A | |
483 | #define TFP410_REG_H_RES_H 0x3B | |
484 | #define TFP410_REG_V_RES_L 0x3C | |
485 | #define TFP410_REG_V_RES_H 0x3D | |
486 | ||
487 | static int tfp410_read_reg(int reg, uchar *buf) | |
488 | { | |
eb5ba3ae SG |
489 | puts("Error reading the chip.\n"); |
490 | return -ENOSYS; | |
98e69567 HS |
491 | } |
492 | ||
493 | static int tfp410_write_reg(int reg, uchar buf) | |
494 | { | |
eb5ba3ae SG |
495 | puts("Error writing the chip.\n"); |
496 | return -ENOSYS; | |
98e69567 HS |
497 | } |
498 | ||
499 | typedef struct _tfp410_config { | |
500 | int reg; | |
501 | uchar val; | |
502 | }TFP410_CONFIG; | |
503 | ||
504 | static TFP410_CONFIG tfp410_configtbl[] = { | |
505 | {TFP410_REG_CTL_1_MODE, 0x37}, | |
506 | {TFP410_REG_CTL_2_MODE, 0x20}, | |
507 | {TFP410_REG_CTL_3_MODE, 0x80}, | |
508 | {TFP410_REG_DE_DLY, 0x90}, | |
509 | {TFP410_REG_DE_CTL, 0x00}, | |
510 | {TFP410_REG_DE_TOP, 0x23}, | |
511 | {TFP410_REG_DE_CNT_H, 0x02}, | |
512 | {TFP410_REG_DE_CNT_L, 0x80}, | |
513 | {TFP410_REG_DE_LIN_H, 0x01}, | |
514 | {TFP410_REG_DE_LIN_L, 0xe0}, | |
515 | {-1, 0}, | |
516 | }; | |
517 | ||
518 | static int charon_last_stage_init(void) | |
519 | { | |
520 | volatile struct mpc5xxx_lpb *lpb = | |
521 | (struct mpc5xxx_lpb *) MPC5XXX_LPB; | |
98e69567 HS |
522 | uchar buf; |
523 | int i = 0; | |
524 | ||
98e69567 HS |
525 | /* check version */ |
526 | if (tfp410_read_reg(TFP410_REG_DEV_ID_H, &buf) != 0) | |
527 | return -1; | |
528 | if (!(buf & 0x04)) | |
529 | return -1; | |
530 | if (tfp410_read_reg(TFP410_REG_DEV_ID_L, &buf) != 0) | |
531 | return -1; | |
532 | if (!(buf & 0x10)) | |
533 | return -1; | |
534 | /* OK, now init the chip */ | |
535 | while (tfp410_configtbl[i].reg != -1) { | |
536 | int ret; | |
537 | ||
538 | ret = tfp410_write_reg(tfp410_configtbl[i].reg, | |
539 | tfp410_configtbl[i].val); | |
540 | if (ret != 0) | |
541 | return -1; | |
542 | i++; | |
543 | } | |
544 | printf("TFP410 initialized.\n"); | |
98e69567 HS |
545 | |
546 | /* set deadcycle for cs3 to 0 */ | |
547 | setbits_be32(&lpb->cs_deadcycle, 0xffffcfff); | |
548 | return 0; | |
549 | } | |
550 | #endif | |
551 | ||
7e6bf358 WD |
552 | int last_stage_init (void) |
553 | { | |
554 | /* | |
555 | * auto scan for really existing devices and re-set chip select | |
556 | * configuration. | |
557 | */ | |
558 | u16 save, tmp; | |
559 | int restore; | |
560 | ||
561 | /* | |
562 | * Check for SRAM and SRAM size | |
563 | */ | |
564 | ||
e8aa824e | 565 | /* save original SRAM content */ |
6d0f6bcf | 566 | save = *(volatile u16 *)CONFIG_SYS_CS2_START; |
7e6bf358 | 567 | restore = 1; |
efe2a4d5 | 568 | |
7e6bf358 | 569 | /* write test pattern to SRAM */ |
6d0f6bcf | 570 | *(volatile u16 *)CONFIG_SYS_CS2_START = 0xA5A5; |
7e6bf358 WD |
571 | __asm__ volatile ("sync"); |
572 | /* | |
573 | * Put a different pattern on the data lines: otherwise they may float | |
574 | * long enough to read back what we wrote. | |
575 | */ | |
6d0f6bcf | 576 | tmp = *(volatile u16 *)CONFIG_SYS_FLASH_BASE; |
7e6bf358 WD |
577 | if (tmp == 0xA5A5) |
578 | puts ("!! possible error in SRAM detection\n"); | |
efe2a4d5 | 579 | |
6d0f6bcf | 580 | if (*(volatile u16 *)CONFIG_SYS_CS2_START != 0xA5A5) { |
7e6bf358 WD |
581 | /* no SRAM at all, disable cs */ |
582 | *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 18); | |
583 | *(vu_long *)MPC5XXX_CS2_START = 0x0000FFFF; | |
584 | *(vu_long *)MPC5XXX_CS2_STOP = 0x0000FFFF; | |
585 | restore = 0; | |
586 | __asm__ volatile ("sync"); | |
6d0f6bcf | 587 | } else if (*(volatile u16 *)(CONFIG_SYS_CS2_START + (1<<19)) == 0xA5A5) { |
7e6bf358 | 588 | /* make sure that we access a mirrored address */ |
6d0f6bcf | 589 | *(volatile u16 *)CONFIG_SYS_CS2_START = 0x1111; |
7e6bf358 | 590 | __asm__ volatile ("sync"); |
6d0f6bcf | 591 | if (*(volatile u16 *)(CONFIG_SYS_CS2_START + (1<<19)) == 0x1111) { |
7e6bf358 | 592 | /* SRAM size = 512 kByte */ |
6d0f6bcf | 593 | *(vu_long *)MPC5XXX_CS2_STOP = STOP_REG(CONFIG_SYS_CS2_START, |
7e6bf358 WD |
594 | 0x80000); |
595 | __asm__ volatile ("sync"); | |
596 | puts ("SRAM: 512 kB\n"); | |
597 | } | |
598 | else | |
efe2a4d5 | 599 | puts ("!! possible error in SRAM detection\n"); |
e8aa824e | 600 | } else { |
efe2a4d5 | 601 | puts ("SRAM: 1 MB\n"); |
7e6bf358 WD |
602 | } |
603 | /* restore origianl SRAM content */ | |
604 | if (restore) { | |
6d0f6bcf | 605 | *(volatile u16 *)CONFIG_SYS_CS2_START = save; |
7e6bf358 WD |
606 | __asm__ volatile ("sync"); |
607 | } | |
efe2a4d5 | 608 | |
0fc0f91b | 609 | #ifndef CONFIG_TQM5200S /* The TQM5200S has no SM501 grafic controller */ |
efe2a4d5 | 610 | /* |
7e6bf358 WD |
611 | * Check for Grafic Controller |
612 | */ | |
613 | ||
614 | /* save origianl FB content */ | |
6d0f6bcf | 615 | save = *(volatile u16 *)CONFIG_SYS_CS1_START; |
7e6bf358 | 616 | restore = 1; |
efe2a4d5 | 617 | |
7e6bf358 | 618 | /* write test pattern to FB memory */ |
6d0f6bcf | 619 | *(volatile u16 *)CONFIG_SYS_CS1_START = 0xA5A5; |
7e6bf358 WD |
620 | __asm__ volatile ("sync"); |
621 | /* | |
622 | * Put a different pattern on the data lines: otherwise they may float | |
623 | * long enough to read back what we wrote. | |
624 | */ | |
6d0f6bcf | 625 | tmp = *(volatile u16 *)CONFIG_SYS_FLASH_BASE; |
7e6bf358 WD |
626 | if (tmp == 0xA5A5) |
627 | puts ("!! possible error in grafic controller detection\n"); | |
efe2a4d5 | 628 | |
6d0f6bcf | 629 | if (*(volatile u16 *)CONFIG_SYS_CS1_START != 0xA5A5) { |
7e6bf358 WD |
630 | /* no grafic controller at all, disable cs */ |
631 | *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 17); | |
632 | *(vu_long *)MPC5XXX_CS1_START = 0x0000FFFF; | |
633 | *(vu_long *)MPC5XXX_CS1_STOP = 0x0000FFFF; | |
634 | restore = 0; | |
635 | __asm__ volatile ("sync"); | |
e8aa824e | 636 | } else { |
efe2a4d5 | 637 | puts ("VGA: SMI501 (Voyager) with 8 MB\n"); |
7e6bf358 WD |
638 | } |
639 | /* restore origianl FB content */ | |
640 | if (restore) { | |
6d0f6bcf | 641 | *(volatile u16 *)CONFIG_SYS_CS1_START = save; |
7e6bf358 WD |
642 | __asm__ volatile ("sync"); |
643 | } | |
efe2a4d5 | 644 | |
aeec782b WD |
645 | #ifdef CONFIG_FO300 |
646 | if (silent_boot()) { | |
647 | setenv("bootdelay", "0"); | |
648 | disable_ctrlc(1); | |
649 | } | |
650 | #endif | |
409ecdc0 | 651 | #endif /* !CONFIG_TQM5200S */ |
aeec782b | 652 | |
98e69567 HS |
653 | #if defined(CONFIG_CHARON) |
654 | charon_last_stage_init(); | |
655 | #endif | |
7e6bf358 WD |
656 | return 0; |
657 | } | |
8f0b7cbe WD |
658 | |
659 | #ifdef CONFIG_VIDEO_SM501 | |
660 | ||
6d3bc9b8 MB |
661 | #ifdef CONFIG_FO300 |
662 | #define DISPLAY_WIDTH 800 | |
663 | #else | |
8f0b7cbe | 664 | #define DISPLAY_WIDTH 640 |
6d3bc9b8 | 665 | #endif |
8f0b7cbe WD |
666 | #define DISPLAY_HEIGHT 480 |
667 | ||
668 | #ifdef CONFIG_VIDEO_SM501_8BPP | |
669 | #error CONFIG_VIDEO_SM501_8BPP not supported. | |
670 | #endif /* CONFIG_VIDEO_SM501_8BPP */ | |
671 | ||
672 | #ifdef CONFIG_VIDEO_SM501_16BPP | |
673 | #error CONFIG_VIDEO_SM501_16BPP not supported. | |
674 | #endif /* CONFIG_VIDEO_SM501_16BPP */ | |
675 | #ifdef CONFIG_VIDEO_SM501_32BPP | |
676 | static const SMI_REGS init_regs [] = | |
677 | { | |
678 | #if 0 /* CRT only */ | |
679 | {0x00004, 0x0}, | |
680 | {0x00048, 0x00021807}, | |
681 | {0x0004C, 0x10090a01}, | |
682 | {0x00054, 0x1}, | |
683 | {0x00040, 0x00021807}, | |
684 | {0x00044, 0x10090a01}, | |
685 | {0x00054, 0x0}, | |
686 | {0x80200, 0x00010000}, | |
687 | {0x80204, 0x0}, | |
688 | {0x80208, 0x0A000A00}, | |
689 | {0x8020C, 0x02fa027f}, | |
690 | {0x80210, 0x004a028b}, | |
691 | {0x80214, 0x020c01df}, | |
692 | {0x80218, 0x000201e9}, | |
693 | {0x80200, 0x00013306}, | |
694 | #else /* panel + CRT */ | |
6d3bc9b8 MB |
695 | #ifdef CONFIG_FO300 |
696 | {0x00004, 0x0}, | |
697 | {0x00048, 0x00021807}, | |
698 | {0x0004C, 0x301a0a01}, | |
699 | {0x00054, 0x1}, | |
700 | {0x00040, 0x00021807}, | |
701 | {0x00044, 0x091a0a01}, | |
702 | {0x00054, 0x0}, | |
703 | {0x80000, 0x0f013106}, | |
704 | {0x80004, 0xc428bb17}, | |
705 | {0x8000C, 0x00000000}, | |
706 | {0x80010, 0x0C800C80}, | |
707 | {0x80014, 0x03200000}, | |
708 | {0x80018, 0x01e00000}, | |
709 | {0x8001C, 0x00000000}, | |
710 | {0x80020, 0x01e00320}, | |
711 | {0x80024, 0x042a031f}, | |
712 | {0x80028, 0x0086034a}, | |
713 | {0x8002C, 0x020c01df}, | |
714 | {0x80030, 0x000201ea}, | |
715 | {0x80200, 0x00010000}, | |
716 | #else | |
8f0b7cbe WD |
717 | {0x00004, 0x0}, |
718 | {0x00048, 0x00021807}, | |
719 | {0x0004C, 0x091a0a01}, | |
720 | {0x00054, 0x1}, | |
721 | {0x00040, 0x00021807}, | |
722 | {0x00044, 0x091a0a01}, | |
723 | {0x00054, 0x0}, | |
724 | {0x80000, 0x0f013106}, | |
725 | {0x80004, 0xc428bb17}, | |
726 | {0x8000C, 0x00000000}, | |
727 | {0x80010, 0x0a000a00}, | |
728 | {0x80014, 0x02800000}, | |
729 | {0x80018, 0x01e00000}, | |
730 | {0x8001C, 0x00000000}, | |
731 | {0x80020, 0x01e00280}, | |
732 | {0x80024, 0x02fa027f}, | |
733 | {0x80028, 0x004a028b}, | |
734 | {0x8002C, 0x020c01df}, | |
735 | {0x80030, 0x000201e9}, | |
736 | {0x80200, 0x00010000}, | |
6d3bc9b8 | 737 | #endif /* #ifdef CONFIG_FO300 */ |
8f0b7cbe WD |
738 | #endif |
739 | {0, 0} | |
740 | }; | |
741 | #endif /* CONFIG_VIDEO_SM501_32BPP */ | |
742 | ||
743 | #ifdef CONFIG_CONSOLE_EXTRA_INFO | |
744 | /* | |
745 | * Return text to be printed besides the logo. | |
746 | */ | |
747 | void video_get_info_str (int line_number, char *info) | |
748 | { | |
749 | if (line_number == 1) { | |
cd65a3dc | 750 | strcpy (info, " Board: TQM5200 (TQ-Components GmbH)"); |
98e69567 | 751 | #if defined (CONFIG_CHARON) || defined (CONFIG_FO300) || \ |
470ee8b1 | 752 | defined(CONFIG_STK52XX) |
8f0b7cbe | 753 | } else if (line_number == 2) { |
98e69567 HS |
754 | #if defined (CONFIG_CHARON) |
755 | strcpy (info, " on a CHARON carrier board"); | |
756 | #endif | |
b87dfd28 | 757 | #if defined (CONFIG_STK52XX) |
5078cce8 | 758 | strcpy (info, " on a STK52xx carrier board"); |
b87dfd28 | 759 | #endif |
6d3bc9b8 MB |
760 | #if defined (CONFIG_FO300) |
761 | strcpy (info, " on a FO300 carrier board"); | |
762 | #endif | |
8f0b7cbe WD |
763 | #endif |
764 | } | |
765 | else { | |
766 | info [0] = '\0'; | |
767 | } | |
768 | } | |
769 | #endif | |
770 | ||
771 | /* | |
e8aa824e WD |
772 | * Returns SM501 register base address. First thing called in the |
773 | * driver. Checks if SM501 is physically present. | |
8f0b7cbe WD |
774 | */ |
775 | unsigned int board_video_init (void) | |
776 | { | |
e8aa824e WD |
777 | u16 save, tmp; |
778 | int restore, ret; | |
779 | ||
780 | /* | |
781 | * Check for Grafic Controller | |
782 | */ | |
783 | ||
784 | /* save origianl FB content */ | |
6d0f6bcf | 785 | save = *(volatile u16 *)CONFIG_SYS_CS1_START; |
e8aa824e WD |
786 | restore = 1; |
787 | ||
788 | /* write test pattern to FB memory */ | |
6d0f6bcf | 789 | *(volatile u16 *)CONFIG_SYS_CS1_START = 0xA5A5; |
e8aa824e WD |
790 | __asm__ volatile ("sync"); |
791 | /* | |
792 | * Put a different pattern on the data lines: otherwise they may float | |
793 | * long enough to read back what we wrote. | |
794 | */ | |
6d0f6bcf | 795 | tmp = *(volatile u16 *)CONFIG_SYS_FLASH_BASE; |
e8aa824e WD |
796 | if (tmp == 0xA5A5) |
797 | puts ("!! possible error in grafic controller detection\n"); | |
798 | ||
6d0f6bcf | 799 | if (*(volatile u16 *)CONFIG_SYS_CS1_START != 0xA5A5) { |
e8aa824e WD |
800 | /* no grafic controller found */ |
801 | restore = 0; | |
802 | ret = 0; | |
803 | } else { | |
804 | ret = SM501_MMIO_BASE; | |
805 | } | |
806 | ||
807 | if (restore) { | |
6d0f6bcf | 808 | *(volatile u16 *)CONFIG_SYS_CS1_START = save; |
e8aa824e WD |
809 | __asm__ volatile ("sync"); |
810 | } | |
811 | return ret; | |
8f0b7cbe WD |
812 | } |
813 | ||
814 | /* | |
815 | * Returns SM501 framebuffer address | |
816 | */ | |
817 | unsigned int board_video_get_fb (void) | |
818 | { | |
819 | return SM501_FB_BASE; | |
820 | } | |
821 | ||
822 | /* | |
823 | * Called after initializing the SM501 and before clearing the screen. | |
824 | */ | |
825 | void board_validate_screen (unsigned int base) | |
826 | { | |
827 | } | |
828 | ||
829 | /* | |
830 | * Return a pointer to the initialization sequence. | |
831 | */ | |
832 | const SMI_REGS *board_get_regs (void) | |
833 | { | |
834 | return init_regs; | |
835 | } | |
836 | ||
837 | int board_get_width (void) | |
838 | { | |
839 | return DISPLAY_WIDTH; | |
840 | } | |
841 | ||
842 | int board_get_height (void) | |
843 | { | |
844 | return DISPLAY_HEIGHT; | |
845 | } | |
846 | ||
847 | #endif /* CONFIG_VIDEO_SM501 */ | |
8f8416fa | 848 | |
cf2817a8 | 849 | #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) |
e895a4b0 | 850 | int ft_board_setup(void *blob, bd_t *bd) |
8f8416fa BS |
851 | { |
852 | ft_cpu_setup(blob, bd); | |
98e69567 HS |
853 | #if defined(CONFIG_VIDEO) |
854 | fdt_add_edid(blob, "smi,sm501", edid_buf); | |
855 | #endif | |
e895a4b0 SG |
856 | |
857 | return 0; | |
8f8416fa | 858 | } |
cf2817a8 | 859 | #endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */ |
19403633 | 860 | |
98e69567 HS |
861 | #if defined(CONFIG_RESET_PHY_R) |
862 | #include <miiphy.h> | |
863 | ||
864 | void reset_phy(void) | |
865 | { | |
866 | /* init Micrel KSZ8993 PHY */ | |
867 | miiphy_write("FEC", CONFIG_PHY_ADDR, 0x01, 0x09); | |
868 | } | |
869 | #endif | |
870 | ||
19403633 BW |
871 | int board_eth_init(bd_t *bis) |
872 | { | |
e1d7480b | 873 | cpu_eth_init(bis); /* Built in FEC comes first */ |
19403633 BW |
874 | return pci_eth_init(bis); |
875 | } |