]> git.sur5r.net Git - u-boot/blob - board/tqm5200/tqm5200.c
Rewrite of NAND code based on what is in 2.6.12 Linux kernel
[u-boot] / board / tqm5200 / tqm5200.c
1 /*
2  * (C) Copyright 2003-2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * (C) Copyright 2004
6  * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
7  *
8  * (C) Copyright 2004-2005
9  * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
10  *
11  * See file CREDITS for list of people who contributed to this
12  * project.
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 #include <common.h>
31 #include <mpc5xxx.h>
32 #include <pci.h>
33
34 #ifdef CONFIG_VIDEO_SM501
35 #include <sm501.h>
36 #endif
37
38 #if defined(CONFIG_MPC5200_DDR)
39 #include "mt46v16m16-75.h"
40 #else
41 #include "mt48lc16m16a2-75.h"
42 #endif
43
44 #ifdef CONFIG_PS2MULT
45 void ps2mult_early_init(void);
46 #endif
47
48 #ifndef CFG_RAMBOOT
49 static void sdram_start (int hi_addr)
50 {
51         long hi_addr_bit = hi_addr ? 0x01000000 : 0;
52
53         /* unlock mode register */
54         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 |
55                 hi_addr_bit;
56         __asm__ volatile ("sync");
57
58         /* precharge all banks */
59         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
60                 hi_addr_bit;
61         __asm__ volatile ("sync");
62
63 #if SDRAM_DDR
64         /* set mode register: extended mode */
65         *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
66         __asm__ volatile ("sync");
67
68         /* set mode register: reset DLL */
69         *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
70         __asm__ volatile ("sync");
71 #endif
72
73         /* precharge all banks */
74         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
75                 hi_addr_bit;
76         __asm__ volatile ("sync");
77
78         /* auto refresh */
79         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 |
80                 hi_addr_bit;
81         __asm__ volatile ("sync");
82
83         /* set mode register */
84         *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
85         __asm__ volatile ("sync");
86
87         /* normal operation */
88         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
89         __asm__ volatile ("sync");
90 }
91 #endif
92
93 /*
94  * ATTENTION: Although partially referenced initdram does NOT make real use
95  *            use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE
96  *            is something else than 0x00000000.
97  */
98
99 #if defined(CONFIG_MPC5200)
100 long int initdram (int board_type)
101 {
102         ulong dramsize = 0;
103         ulong dramsize2 = 0;
104 #ifndef CFG_RAMBOOT
105         ulong test1, test2;
106
107         /* setup SDRAM chip selects */
108         *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001c; /* 512MB at 0x0 */
109         *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x40000000; /* disabled */
110         __asm__ volatile ("sync");
111
112         /* setup config registers */
113         *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
114         *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
115         __asm__ volatile ("sync");
116
117 #if SDRAM_DDR
118         /* set tap delay */
119         *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
120         __asm__ volatile ("sync");
121 #endif
122
123         /* find RAM size using SDRAM CS0 only */
124         sdram_start(0);
125         test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x20000000);
126         sdram_start(1);
127         test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x20000000);
128         if (test1 > test2) {
129                 sdram_start(0);
130                 dramsize = test1;
131         } else {
132                 dramsize = test2;
133         }
134
135         /* memory smaller than 1MB is impossible */
136         if (dramsize < (1 << 20)) {
137                 dramsize = 0;
138         }
139
140         /* set SDRAM CS0 size according to the amount of RAM found */
141         if (dramsize > 0) {
142                 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 +
143                         __builtin_ffs(dramsize >> 20) - 1;
144         } else {
145                 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
146         }
147
148         /* let SDRAM CS1 start right after CS0 */
149         *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001c; /* 512MB */
150
151         /* find RAM size using SDRAM CS1 only */
152         sdram_start(0);
153         test1 = get_ram_size((ulong *)(CFG_SDRAM_BASE + dramsize), 0x20000000);
154         sdram_start(1);
155         test2 = get_ram_size((ulong *)(CFG_SDRAM_BASE + dramsize), 0x20000000);
156         if (test1 > test2) {
157                 sdram_start(0);
158                 dramsize2 = test1;
159         } else {
160                 dramsize2 = test2;
161         }
162
163         /* memory smaller than 1MB is impossible */
164         if (dramsize2 < (1 << 20)) {
165                 dramsize2 = 0;
166         }
167
168         /* set SDRAM CS1 size according to the amount of RAM found */
169         if (dramsize2 > 0) {
170                 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize
171                         | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
172         } else {
173                 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
174         }
175
176 #else /* CFG_RAMBOOT */
177
178         /* retrieve size of memory connected to SDRAM CS0 */
179         dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
180         if (dramsize >= 0x13) {
181                 dramsize = (1 << (dramsize - 0x13)) << 20;
182         } else {
183                 dramsize = 0;
184         }
185
186         /* retrieve size of memory connected to SDRAM CS1 */
187         dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
188         if (dramsize2 >= 0x13) {
189                 dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
190         } else {
191                 dramsize2 = 0;
192         }
193
194 #endif /* CFG_RAMBOOT */
195
196 /*      return dramsize + dramsize2; */
197         return dramsize;
198 }
199
200 #elif defined(CONFIG_MGT5100)
201
202 long int initdram (int board_type)
203 {
204         ulong dramsize = 0;
205 #ifndef CFG_RAMBOOT
206         ulong test1, test2;
207
208         /* setup and enable SDRAM chip selects */
209         *(vu_long *)MPC5XXX_SDRAM_START = 0x00000000;
210         *(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */
211         *(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
212         __asm__ volatile ("sync");
213
214         /* setup config registers */
215         *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
216         *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
217
218         /* address select register */
219         *(vu_long *)MPC5XXX_SDRAM_XLBSEL = SDRAM_ADDRSEL;
220         __asm__ volatile ("sync");
221
222         /* find RAM size */
223         sdram_start(0);
224         test1 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
225         sdram_start(1);
226         test2 = get_ram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
227         if (test1 > test2) {
228                 sdram_start(0);
229                 dramsize = test1;
230         } else {
231                 dramsize = test2;
232         }
233
234         /* set SDRAM end address according to size */
235         *(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15);
236
237 #else /* CFG_RAMBOOT */
238
239         /* Retrieve amount of SDRAM available */
240         dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15);
241
242 #endif /* CFG_RAMBOOT */
243
244         return dramsize;
245 }
246
247 #else
248 #error Neither CONFIG_MPC5200 or CONFIG_MGT5100 defined
249 #endif
250
251 int checkboard (void)
252 {
253 #if defined (CONFIG_TQM5200_AA)
254         puts ("Board: TQM5200-AA (TQ-Components GmbH)\n");
255 #elif defined (CONFIG_TQM5200_AB)
256         puts ("Board: TQM5200-AB (TQ-Components GmbH)\n");
257 #elif defined (CONFIG_TQM5200_AC)
258         puts ("Board: TQM5200-AC (TQ-Components GmbH)\n");
259 #elif defined (CONFIG_TQM5200)
260         puts ("Board: TQM5200 (TQ-Components GmbH)\n");
261 #endif
262 #if defined (CONFIG_STK52XX)
263         puts ("       on a STK52XX baseboard\n");
264 #endif
265
266         return 0;
267 }
268
269 void flash_preinit(void)
270 {
271         /*
272          * Now, when we are in RAM, enable flash write
273          * access for detection process.
274          * Note that CS_BOOT cannot be cleared when
275          * executing in flash.
276          */
277 #if defined(CONFIG_MGT5100)
278         *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
279         *(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
280 #endif
281         *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
282 }
283
284
285 #ifdef  CONFIG_PCI
286 static struct pci_controller hose;
287
288 extern void pci_mpc5xxx_init(struct pci_controller *);
289
290 void pci_init_board(void)
291 {
292         pci_mpc5xxx_init(&hose);
293 }
294 #endif
295
296 #if defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET)
297
298 #if defined (CONFIG_MINIFAP)
299 #define SM501_POWER_MODE0_GATE          0x00000040UL
300 #define SM501_POWER_MODE1_GATE          0x00000048UL
301 #define POWER_MODE_GATE_GPIO_PWM_I2C    0x00000040UL
302 #define SM501_GPIO_DATA_DIR_HIGH        0x0001000CUL
303 #define SM501_GPIO_DATA_HIGH            0x00010004UL
304 #define SM501_GPIO_51                   0x00080000UL
305 #else
306 #define GPIO_PSC1_4     0x01000000UL
307 #endif
308
309 void init_ide_reset (void)
310 {
311         debug ("init_ide_reset\n");
312
313 #if defined (CONFIG_MINIFAP)
314         /* Configure GPIO_51 of the SM501 grafic controller as ATA reset */
315
316         /* enable GPIO control (in both power modes) */
317         *(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE0_GATE) |=
318                 POWER_MODE_GATE_GPIO_PWM_I2C;
319         *(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE1_GATE) |=
320                 POWER_MODE_GATE_GPIO_PWM_I2C;
321         /* configure GPIO51 as output */
322         *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_DIR_HIGH) |=
323                 SM501_GPIO_51;
324 #else
325         /* Configure PSC1_4 as GPIO output for ATA reset */
326         *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
327         *(vu_long *) MPC5XXX_WU_GPIO_DIR    |= GPIO_PSC1_4;
328 #endif
329 }
330
331 void ide_set_reset (int idereset)
332 {
333         debug ("ide_reset(%d)\n", idereset);
334
335 #if defined (CONFIG_MINIFAP)
336         if (idereset) {
337                 *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) &=
338                         ~SM501_GPIO_51;
339         } else {
340                 *(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) |=
341                         SM501_GPIO_51;
342         }
343 #else
344         if (idereset) {
345                 *(vu_long *) MPC5XXX_WU_GPIO_DATA &= ~GPIO_PSC1_4;
346         } else {
347                 *(vu_long *) MPC5XXX_WU_GPIO_DATA |=  GPIO_PSC1_4;
348         }
349 #endif
350 }
351 #endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */
352
353 #ifdef CONFIG_POST
354 /*
355  * Reads GPIO pin PSC6_3. A keypress is reported, if PSC6_3 is low. If PSC6_3
356  * is left open, no keypress is detected.
357  */
358 int post_hotkeys_pressed(void)
359 {
360         struct mpc5xxx_gpio *gpio;
361
362         gpio = (struct mpc5xxx_gpio*) MPC5XXX_GPIO;
363
364         /*
365          * Configure PSC6_1 and PSC6_3 as GPIO. PSC6 then couldn't be used in
366          * CODEC or UART mode. Consumer IrDA should still be possible.
367          */
368         gpio->port_config &= ~(0x07000000);
369         gpio->port_config |=   0x03000000;
370
371         /* Enable GPIO for GPIO_IRDA_1 (IR_USB_CLK pin) = PSC6_3 */
372         gpio->simple_gpioe |= 0x20000000;
373
374         /* Configure GPIO_IRDA_1 as input */
375         gpio->simple_ddr &= ~(0x20000000);
376
377         return ((gpio->simple_ival & 0x20000000) ? 0 : 1);
378 }
379 #endif
380
381 #if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
382
383 void post_word_store (ulong a)
384 {
385         volatile ulong *save_addr =
386                 (volatile ulong *)(MPC5XXX_SRAM + MPC5XXX_SRAM_POST_SIZE);
387
388         *save_addr = a;
389 }
390
391 ulong post_word_load (void)
392 {
393         volatile ulong *save_addr =
394                 (volatile ulong *)(MPC5XXX_SRAM + MPC5XXX_SRAM_POST_SIZE);
395
396         return *save_addr;
397 }
398 #endif  /* CONFIG_POST || CONFIG_LOGBUFFER*/
399
400 #ifdef CONFIG_PS2MULT
401 #ifdef CONFIG_BOARD_EARLY_INIT_R
402 int board_early_init_r (void)
403 {
404         ps2mult_early_init();
405         return (0);
406 }
407 #endif
408 #endif /* CONFIG_PS2MULT */
409
410 #if defined(CONFIG_CS_AUTOCONF)
411 int last_stage_init (void)
412 {
413         /*
414          * auto scan for really existing devices and re-set chip select
415          * configuration.
416          */
417         u16 save, tmp;
418         int restore;
419
420         /*
421          * Check for SRAM and SRAM size
422          */
423
424         /* save origianl SRAM content  */
425         save = *(volatile u16 *)CFG_CS2_START;
426         restore = 1;
427
428         /* write test pattern to SRAM */
429         *(volatile u16 *)CFG_CS2_START = 0xA5A5;
430         __asm__ volatile ("sync");
431         /*
432          * Put a different pattern on the data lines: otherwise they may float
433          * long enough to read back what we wrote.
434          */
435         tmp = *(volatile u16 *)CFG_FLASH_BASE;
436         if (tmp == 0xA5A5)
437                 puts ("!! possible error in SRAM detection\n");
438
439         if (*(volatile u16 *)CFG_CS2_START != 0xA5A5) {
440                 /* no SRAM at all, disable cs */
441                 *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 18);
442                 *(vu_long *)MPC5XXX_CS2_START = 0x0000FFFF;
443                 *(vu_long *)MPC5XXX_CS2_STOP = 0x0000FFFF;
444                 restore = 0;
445                 __asm__ volatile ("sync");
446         }
447         else if (*(volatile u16 *)(CFG_CS2_START + (1<<19)) == 0xA5A5) {
448                 /* make sure that we access a mirrored address */
449                 *(volatile u16 *)CFG_CS2_START = 0x1111;
450                 __asm__ volatile ("sync");
451                 if (*(volatile u16 *)(CFG_CS2_START + (1<<19)) == 0x1111) {
452                         /* SRAM size = 512 kByte */
453                         *(vu_long *)MPC5XXX_CS2_STOP = STOP_REG(CFG_CS2_START,
454                                                                 0x80000);
455                         __asm__ volatile ("sync");
456                         puts ("SRAM:  512 kB\n");
457                 }
458                 else
459                         puts ("!! possible error in SRAM detection\n");
460         }
461         else {
462                 puts ("SRAM:  1 MB\n");
463         }
464         /* restore origianl SRAM content  */
465         if (restore) {
466                 *(volatile u16 *)CFG_CS2_START = save;
467                 __asm__ volatile ("sync");
468         }
469
470         /*
471          * Check for Grafic Controller
472          */
473
474         /* save origianl FB content  */
475         save = *(volatile u16 *)CFG_CS1_START;
476         restore = 1;
477
478         /* write test pattern to FB memory */
479         *(volatile u16 *)CFG_CS1_START = 0xA5A5;
480         __asm__ volatile ("sync");
481         /*
482          * Put a different pattern on the data lines: otherwise they may float
483          * long enough to read back what we wrote.
484          */
485         tmp = *(volatile u16 *)CFG_FLASH_BASE;
486         if (tmp == 0xA5A5)
487                 puts ("!! possible error in grafic controller detection\n");
488
489         if (*(volatile u16 *)CFG_CS1_START != 0xA5A5) {
490                 /* no grafic controller at all, disable cs */
491                 *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 17);
492                 *(vu_long *)MPC5XXX_CS1_START = 0x0000FFFF;
493                 *(vu_long *)MPC5XXX_CS1_STOP = 0x0000FFFF;
494                 restore = 0;
495                 __asm__ volatile ("sync");
496         }
497         else {
498                 puts ("VGA:   SMI501 (Voyager) with 8 MB\n");
499         }
500         /* restore origianl FB content  */
501         if (restore) {
502                 *(volatile u16 *)CFG_CS1_START = save;
503                 __asm__ volatile ("sync");
504         }
505
506         return 0;
507 }
508 #endif /* CONFIG_CS_AUTOCONF */
509
510 #ifdef CONFIG_VIDEO_SM501
511
512 #define DISPLAY_WIDTH   640
513 #define DISPLAY_HEIGHT  480
514
515 #ifdef CONFIG_VIDEO_SM501_8BPP
516 #error CONFIG_VIDEO_SM501_8BPP not supported.
517 #endif /* CONFIG_VIDEO_SM501_8BPP */
518
519 #ifdef CONFIG_VIDEO_SM501_16BPP
520 #error CONFIG_VIDEO_SM501_16BPP not supported.
521 #endif /* CONFIG_VIDEO_SM501_16BPP */
522 #ifdef CONFIG_VIDEO_SM501_32BPP
523 static const SMI_REGS init_regs [] =
524 {
525 #if 0 /* CRT only */
526         {0x00004, 0x0},
527         {0x00048, 0x00021807},
528         {0x0004C, 0x10090a01},
529         {0x00054, 0x1},
530         {0x00040, 0x00021807},
531         {0x00044, 0x10090a01},
532         {0x00054, 0x0},
533         {0x80200, 0x00010000},
534         {0x80204, 0x0},
535         {0x80208, 0x0A000A00},
536         {0x8020C, 0x02fa027f},
537         {0x80210, 0x004a028b},
538         {0x80214, 0x020c01df},
539         {0x80218, 0x000201e9},
540         {0x80200, 0x00013306},
541 #else  /* panel + CRT */
542         {0x00004, 0x0},
543         {0x00048, 0x00021807},
544         {0x0004C, 0x091a0a01},
545         {0x00054, 0x1},
546         {0x00040, 0x00021807},
547         {0x00044, 0x091a0a01},
548         {0x00054, 0x0},
549         {0x80000, 0x0f013106},
550         {0x80004, 0xc428bb17},
551         {0x8000C, 0x00000000},
552         {0x80010, 0x0a000a00},
553         {0x80014, 0x02800000},
554         {0x80018, 0x01e00000},
555         {0x8001C, 0x00000000},
556         {0x80020, 0x01e00280},
557         {0x80024, 0x02fa027f},
558         {0x80028, 0x004a028b},
559         {0x8002C, 0x020c01df},
560         {0x80030, 0x000201e9},
561         {0x80200, 0x00010000},
562 #endif
563         {0, 0}
564 };
565 #endif /* CONFIG_VIDEO_SM501_32BPP */
566
567 #ifdef CONFIG_CONSOLE_EXTRA_INFO
568 /*
569  * Return text to be printed besides the logo.
570  */
571 void video_get_info_str (int line_number, char *info)
572 {
573         if (line_number == 1) {
574 #if defined (CONFIG_TQM5200_AA)
575                 strcpy (info, " Board: TQM5200-AA (TQ-Components GmbH)");
576 #elif defined (CONFIG_TQM5200_AB)
577                 strcpy (info, " Board: TQM5200-AB (TQ-Components GmbH)");
578 #elif defined (CONFIG_TQM5200_AC)
579                 strcpy (info, " Board: TQM5200-AC (TQ-Components GmbH)");
580 #elif defined (CONFIG_TQM5200)
581                 strcpy (info, " Board: TQM5200 (TQ-Components GmbH)");
582 #else
583 #error No supported board selected
584 #endif
585 #if defined (CONFIG_STK52XX)
586         } else if (line_number == 2) {
587                 strcpy (info, "        on a STK52XX baseboard");
588 #endif
589         }
590         else {
591                 info [0] = '\0';
592         }
593 }
594 #endif
595
596 /*
597  * Returns SM501 register base address. First thing called in the driver.
598  */
599 unsigned int board_video_init (void)
600 {
601         return SM501_MMIO_BASE;
602 }
603
604 /*
605  * Returns SM501 framebuffer address
606  */
607 unsigned int board_video_get_fb (void)
608 {
609         return SM501_FB_BASE;
610 }
611
612 /*
613  * Called after initializing the SM501 and before clearing the screen.
614  */
615 void board_validate_screen (unsigned int base)
616 {
617 }
618
619 /*
620  * Return a pointer to the initialization sequence.
621  */
622 const SMI_REGS *board_get_regs (void)
623 {
624         return init_regs;
625 }
626
627 int board_get_width (void)
628 {
629         return DISPLAY_WIDTH;
630 }
631
632 int board_get_height (void)
633 {
634         return DISPLAY_HEIGHT;
635 }
636
637 #endif /* CONFIG_VIDEO_SM501 */