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