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