]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/manroland/mucmc52/mucmc52.c
63dc2ad5fa9e133cd353d86b0c3703d675257a35
[karo-tx-uboot.git] / board / manroland / mucmc52 / mucmc52.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
9  * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
10  *
11  * (C) Copyright 2008
12  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
13  *
14  * SPDX-License-Identifier:     GPL-2.0+ 
15  */
16
17 #include <common.h>
18 #include <fdt_support.h>
19 #include <mpc5xxx.h>
20 #include <pci.h>
21 #include <malloc.h>
22 #include <asm/processor.h>
23 #include <asm/io.h>
24
25 #ifndef CONFIG_SYS_RAMBOOT
26 static void sdram_start (int hi_addr)
27 {
28         long hi_addr_bit = hi_addr ? 0x01000000 : 0;
29
30         /* unlock mode register */
31         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
32                 (SDRAM_CONTROL | 0x80000000 | hi_addr_bit));
33         __asm__ volatile ("sync");
34
35         /* precharge all banks */
36         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
37                 (SDRAM_CONTROL | 0x80000002 | hi_addr_bit));
38         __asm__ volatile ("sync");
39
40 #if SDRAM_DDR
41         /* set mode register: extended mode */
42         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_MODE, (SDRAM_EMODE));
43         __asm__ volatile ("sync");
44
45         /* set mode register: reset DLL */
46         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_MODE,
47                 (SDRAM_MODE | 0x04000000));
48         __asm__ volatile ("sync");
49 #endif
50
51         /* precharge all banks */
52         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
53                 (SDRAM_CONTROL | 0x80000002 | hi_addr_bit));
54         __asm__ volatile ("sync");
55
56         /* auto refresh */
57         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
58                 (SDRAM_CONTROL | 0x80000004 | hi_addr_bit));
59         __asm__ volatile ("sync");
60
61         /* set mode register */
62         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_MODE, (SDRAM_MODE));
63         __asm__ volatile ("sync");
64
65         /* normal operation */
66         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
67                 (SDRAM_CONTROL | hi_addr_bit));
68         __asm__ volatile ("sync");
69 }
70 #endif
71
72 /*
73  * ATTENTION: Although partially referenced initdram does NOT make real use
74  *            use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE
75  *            is something else than 0x00000000.
76  */
77
78 phys_size_t initdram (int board_type)
79 {
80         ulong dramsize = 0;
81         ulong dramsize2 = 0;
82         uint svr, pvr;
83
84 #ifndef CONFIG_SYS_RAMBOOT
85         ulong test1, test2;
86
87         /* setup SDRAM chip selects */
88         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS0CFG, 0x0000001c); /* 512MB at 0x0 */
89         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG, 0x80000000);/* disabled */
90         __asm__ volatile ("sync");
91
92         /* setup config registers */
93         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CONFIG1, SDRAM_CONFIG1);
94         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CONFIG2, SDRAM_CONFIG2);
95         __asm__ volatile ("sync");
96
97 #if SDRAM_DDR
98         /* set tap delay */
99         out_be32 ((unsigned __iomem *)MPC5XXX_CDM_PORCFG, SDRAM_TAPDELAY);
100         __asm__ volatile ("sync");
101 #endif
102
103         /* find RAM size using SDRAM CS0 only */
104         sdram_start (0);
105         test1 = get_ram_size ((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
106         sdram_start(1);
107         test2 = get_ram_size ((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
108         if (test1 > test2) {
109                 sdram_start (0);
110                 dramsize = test1;
111         } else {
112                 dramsize = test2;
113         }
114
115         /* memory smaller than 1MB is impossible */
116         if (dramsize < (1 << 20)) {
117                 dramsize = 0;
118         }
119
120         /* set SDRAM CS0 size according to the amount of RAM found */
121         if (dramsize > 0) {
122                 out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS0CFG,
123                         (0x13 + __builtin_ffs(dramsize >> 20) - 1));
124         } else {
125                 out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS0CFG, 0); /* disabled */
126         }
127
128         /* let SDRAM CS1 start right after CS0 */
129         out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG, (dramsize + 0x0000001c));/*512MB*/
130
131         /* find RAM size using SDRAM CS1 only */
132         if (!dramsize)
133                 sdram_start (0);
134         test2 = test1 = get_ram_size ((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000);
135         if (!dramsize) {
136                 sdram_start (1);
137                 test2 = get_ram_size ((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000);
138         }
139         if (test1 > test2) {
140                 sdram_start (0);
141                 dramsize2 = test1;
142         } else {
143                 dramsize2 = test2;
144         }
145
146         /* memory smaller than 1MB is impossible */
147         if (dramsize2 < (1 << 20)) {
148                 dramsize2 = 0;
149         }
150
151         /* set SDRAM CS1 size according to the amount of RAM found */
152         if (dramsize2 > 0) {
153                 out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG,
154                         (dramsize | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1)));
155         } else {
156                 out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG, dramsize); /* disabled */
157         }
158
159 #else /* CONFIG_SYS_RAMBOOT */
160
161         /* retrieve size of memory connected to SDRAM CS0 */
162         dramsize = in_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS0CFG) & 0xFF;
163         if (dramsize >= 0x13) {
164                 dramsize = (1 << (dramsize - 0x13)) << 20;
165         } else {
166                 dramsize = 0;
167         }
168
169         /* retrieve size of memory connected to SDRAM CS1 */
170         dramsize2 = in_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG) & 0xFF;
171         if (dramsize2 >= 0x13) {
172                 dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
173         } else {
174                 dramsize2 = 0;
175         }
176
177 #endif /* CONFIG_SYS_RAMBOOT */
178
179          /*
180          * On MPC5200B we need to set the special configuration delay in the
181          * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
182          * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
183          *
184          * "The SDelay should be written to a value of 0x00000004. It is
185          * required to account for changes caused by normal wafer processing
186          * parameters."
187          */
188         svr = get_svr();
189         pvr = get_pvr();
190         if ((SVR_MJREV(svr) >= 2) &&
191             (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
192
193                 out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_SDELAY, 0x04);
194                 __asm__ volatile ("sync");
195         }
196
197         return dramsize + dramsize2;
198 }
199
200 int checkboard (void)
201 {
202         puts ("Board: MUC.MC-52 HW WDT ");
203 #if defined(CONFIG_HW_WATCHDOG)
204         puts ("enabled\n");
205 #else
206         puts ("disabled\n");
207 #endif
208         return 0;
209 }
210
211 #ifdef CONFIG_PREBOOT
212
213 static uchar kbd_magic_prefix[]         = "key_magic";
214 static uchar kbd_command_prefix[]       = "key_cmd";
215
216 #define S1_ROT  0xf0
217 #define S2_Q    0x40
218 #define S2_M    0x20
219
220 struct kbd_data_t {
221         char s1;
222         char s2;
223 };
224
225 struct kbd_data_t* get_keys (struct kbd_data_t *kbd_data)
226 {
227         kbd_data->s1 = in_8 ((volatile uchar*)CONFIG_SYS_STATUS1_BASE);
228         kbd_data->s2 = in_8 ((volatile uchar*)CONFIG_SYS_STATUS2_BASE);
229
230         return kbd_data;
231 }
232
233 static int compare_magic (const struct kbd_data_t *kbd_data, char *str)
234 {
235         char s1 = str[0];
236         char s2;
237
238         if (s1 >= '0' && s1 <= '9')
239                 s1 -= '0';
240         else if (s1 >= 'a' && s1 <= 'f')
241                 s1 = s1 - 'a' + 10;
242         else if (s1 >= 'A' && s1 <= 'F')
243                 s1 = s1 - 'A' + 10;
244         else
245                 return -1;
246
247         if (((S1_ROT & kbd_data->s1) >> 4) != s1)
248                 return -1;
249
250         s2 = (S2_Q | S2_M) & kbd_data->s2;
251
252         switch (str[1]) {
253         case 'q':
254         case 'Q':
255                 if (s2 == S2_Q)
256                         return -1;
257                 break;
258         case 'm':
259         case 'M':
260                 if (s2 == S2_M)
261                         return -1;
262                 break;
263         case '\0':
264                 if (s2 == (S2_Q | S2_M))
265                         return 0;
266         default:
267                 return -1;
268         }
269
270         if (str[2])
271                 return -1;
272
273         return 0;
274 }
275
276 static char *key_match (const struct kbd_data_t *kbd_data)
277 {
278         char magic[sizeof (kbd_magic_prefix) + 1];
279         char *suffix;
280         char *kbd_magic_keys;
281
282         /*
283          * The following string defines the characters that can be appended
284          * to "key_magic" to form the names of environment variables that
285          * hold "magic" key codes, i. e. such key codes that can cause
286          * pre-boot actions. If the string is empty (""), then only
287          * "key_magic" is checked (old behaviour); the string "125" causes
288          * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
289          */
290         if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
291                 kbd_magic_keys = "";
292
293         /* loop over all magic keys;
294          * use '\0' suffix in case of empty string
295          */
296         for (suffix = kbd_magic_keys; *suffix ||
297                      suffix == kbd_magic_keys; ++suffix) {
298                 sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
299
300                 if (compare_magic(kbd_data, getenv(magic)) == 0) {
301                         char cmd_name[sizeof (kbd_command_prefix) + 1];
302                         char *cmd;
303
304                         sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
305                         cmd = getenv (cmd_name);
306
307                         return (cmd);
308                 }
309         }
310
311         return (NULL);
312 }
313
314 #endif /* CONFIG_PREBOOT */
315
316 int misc_init_r (void)
317 {
318 #ifdef CONFIG_PREBOOT
319         struct kbd_data_t kbd_data;
320         /* Decode keys */
321         char *str = strdup (key_match (get_keys (&kbd_data)));
322         /* Set or delete definition */
323         setenv ("preboot", str);
324         free (str);
325 #endif /* CONFIG_PREBOOT */
326
327         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x38), ' ');
328         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x39), ' ');
329         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3A), ' ');
330         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3B), ' ');
331         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3C), ' ');
332         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3D), ' ');
333         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3E), ' ');
334         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3F), ' ');
335
336         return 0;
337 }
338
339 int board_early_init_r (void)
340 {
341         out_be32 ((unsigned __iomem *)MPC5XXX_BOOTCS_CFG, in_be32 ((unsigned __iomem *)MPC5XXX_BOOTCS_CFG) & ~0x1);
342         out_be32 ((unsigned __iomem *)MPC5XXX_BOOTCS_START, START_REG(CONFIG_SYS_FLASH_BASE));
343         out_be32 ((unsigned __iomem *)MPC5XXX_CS0_START, START_REG(CONFIG_SYS_FLASH_BASE));
344         out_be32 ((unsigned __iomem *)MPC5XXX_BOOTCS_STOP,
345                 STOP_REG(CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_SIZE));
346         out_be32 ((unsigned __iomem *)MPC5XXX_CS0_STOP,
347                 STOP_REG(CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_SIZE));
348         return 0;
349 }
350
351 int last_stage_init (void)
352 {
353         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x38), 'M');
354         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x39), 'U');
355         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3A), 'C');
356         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3B), '.');
357         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3C), 'M');
358         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3D), 'C');
359         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3E), '5');
360         out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3F), '2');
361
362         return 0;
363 }
364
365 #if defined(CONFIG_HW_WATCHDOG)
366 #define GPT_OUT_0       0x00000027
367 #define GPT_OUT_1       0x00000037
368 void hw_watchdog_reset (void)
369 {
370         /* Trigger HW Watchdog with TIMER_0 */
371         out_be32 ((unsigned __iomem *)MPC5XXX_GPT0_ENABLE, GPT_OUT_1);
372         out_be32 ((unsigned __iomem *)MPC5XXX_GPT0_ENABLE, GPT_OUT_0);
373 }
374 #endif
375
376 #ifdef  CONFIG_PCI
377 static struct pci_controller hose;
378
379 extern void pci_mpc5xxx_init (struct pci_controller *);
380
381 void pci_init_board (void)
382 {
383         pci_mpc5xxx_init (&hose);
384 }
385 #endif
386
387 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
388 void ft_board_setup(void *blob, bd_t *bd)
389 {
390         ft_cpu_setup(blob, bd);
391 }
392 #endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */