]>
Commit | Line | Data |
---|---|---|
6dedf3d4 HS |
1 | /* |
2 | * (C) Copyright 2006 | |
3 | * Heiko Schocher, DENX Software Engineering, hs@denx.de. | |
4 | * | |
5 | * (C) Copyright 2003-2004 | |
6 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
7 | * | |
8 | * (C) Copyright 2004 | |
9 | * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. | |
10 | * | |
11 | * (C) Copyright 2004 | |
12 | * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.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 | ||
38 | /* some SIMPLE GPIO Pins */ | |
39 | #define GPIO_USB_8 (31-12) | |
40 | #define GPIO_USB_7 (31-13) | |
41 | #define GPIO_USB_6 (31-14) | |
42 | #define GPIO_USB_0 (31-15) | |
43 | #define GPIO_PSC3_7 (31-18) | |
44 | #define GPIO_PSC3_6 (31-19) | |
45 | #define GPIO_PSC3_1 (31-22) | |
46 | #define GPIO_PSC3_0 (31-23) | |
47 | ||
48 | /* some simple Interrupt GPIO Pins */ | |
49 | #define GPIO_PSC3_8 2 | |
50 | #define GPIO_USB1_9 3 | |
51 | ||
52 | #define GPT_OUT_0 0x00000027 | |
53 | #define GPT_OUT_1 0x00000037 | |
54 | #define GPT_DISABLE 0x00000000 /* GPT pin disabled */ | |
55 | ||
56 | #define GP_SIMP_ENABLE_O(n, v) {pgpio->simple_dvo |= (v << n); \ | |
57 | pgpio->simple_ddr |= (1 << n); \ | |
58 | pgpio->simple_gpioe |= (1 << n); \ | |
59 | } | |
60 | ||
61 | #define GP_SIMP_ENABLE_I(n) { pgpio->simple_ddr |= ~(1 << n); \ | |
62 | pgpio->simple_gpioe |= (1 << n); \ | |
63 | } | |
64 | ||
65 | #define GP_SIMP_SET_O(n, v) (pgpio->simple_dvo = v ? \ | |
66 | (pgpio->simple_dvo | (1 << n)) : \ | |
67 | (pgpio->simple_dvo & ~(1 << n)) ) | |
f11033e7 | 68 | |
6dedf3d4 HS |
69 | #define GP_SIMP_GET_O(n) ((pgpio->simple_dvo >> n) & 1) |
70 | #define GP_SIMP_GET_I(n) ((pgpio->simple_ival >> n) & 1) | |
71 | ||
6dedf3d4 HS |
72 | #define GP_SINT_SET_O(n, v) (pgpio->sint_dvo = v ? \ |
73 | (pgpio->sint_dvo | (1 << n)) : \ | |
74 | (pgpio->sint_dvo & ~(1 << n)) ) | |
75 | ||
76 | #define GP_SINT_ENABLE_O(n, v) {pgpio->sint_ode &= ~(1 << n); \ | |
77 | pgpio->sint_ddr |= (1 << n); \ | |
78 | GP_SINT_SET_O(n, v); \ | |
79 | pgpio->sint_gpioe |= (1 << n); \ | |
80 | } | |
81 | ||
82 | #define GP_SINT_ENABLE_I(n) { pgpio->sint_ddr |= ~(1 << n); \ | |
83 | pgpio->sint_gpioe |= (1 << n); \ | |
84 | } | |
85 | ||
86 | #define GP_SINT_GET_O(n) ((pgpio->sint_ival >> n) & 1) | |
87 | #define GP_SINT_GET_I(n) ((pgpio-ntt_ival >> n) & 1) | |
88 | ||
89 | #define GP_TIMER_ENABLE_O(n, v) ( \ | |
90 | ((volatile struct mpc5xxx_gpt *)(MPC5XXX_GPT + n))->emsr = v ? \ | |
91 | GPT_OUT_1 : \ | |
92 | GPT_OUT_0 ) | |
93 | ||
94 | #define GP_TIMER_SET_O(n, v) GP_TIMER_ENABLE_O(n, v) | |
95 | ||
96 | #define GP_TIMER_GET_O(n, v) ( \ | |
97 | (((volatile struct mpc5xxx_gpt *)(MPC5XXX_GPT + n))->emsr & 0x10) >> 4) | |
98 | ||
99 | #define GP_TIMER_GET_I(n, v) ( \ | |
100 | (((volatile struct mpc5xxx_gpt *)(MPC5XXX_GPT + n))->sr & 0x100) >> 8) | |
101 | ||
6d0f6bcf | 102 | #ifndef CONFIG_SYS_RAMBOOT |
6dedf3d4 HS |
103 | static void sdram_start (int hi_addr) |
104 | { | |
105 | long hi_addr_bit = hi_addr ? 0x01000000 : 0; | |
106 | ||
107 | /* unlock mode register */ | |
108 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit; | |
109 | __asm__ volatile ("sync"); | |
110 | ||
111 | /* precharge all banks */ | |
112 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit; | |
113 | __asm__ volatile ("sync"); | |
114 | ||
115 | #if SDRAM_DDR | |
116 | /* set mode register: extended mode */ | |
117 | *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE; | |
118 | __asm__ volatile ("sync"); | |
119 | ||
120 | /* set mode register: reset DLL */ | |
121 | *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000; | |
122 | __asm__ volatile ("sync"); | |
123 | #endif | |
124 | ||
125 | /* precharge all banks */ | |
126 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit; | |
127 | __asm__ volatile ("sync"); | |
128 | ||
129 | /* auto refresh */ | |
130 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit; | |
131 | __asm__ volatile ("sync"); | |
132 | ||
133 | /* set mode register */ | |
134 | *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE; | |
135 | __asm__ volatile ("sync"); | |
136 | ||
137 | /* normal operation */ | |
138 | *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit; | |
139 | __asm__ volatile ("sync"); | |
140 | } | |
141 | #endif | |
142 | ||
143 | /* | |
144 | * ATTENTION: Although partially referenced initdram does NOT make real use | |
6d0f6bcf | 145 | * use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE |
6dedf3d4 HS |
146 | * is something else than 0x00000000. |
147 | */ | |
148 | ||
9973e3c6 | 149 | phys_size_t initdram (int board_type) |
6dedf3d4 HS |
150 | { |
151 | ulong dramsize = 0; | |
6d0f6bcf | 152 | #ifndef CONFIG_SYS_RAMBOOT |
6dedf3d4 HS |
153 | ulong test1, test2; |
154 | ||
155 | /* setup SDRAM chip selects */ | |
156 | *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001c; /* 512MB at 0x0 */ | |
157 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x40000000; /* disabled */ | |
158 | __asm__ volatile ("sync"); | |
159 | ||
160 | /* setup config registers */ | |
161 | *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1; | |
162 | *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2; | |
163 | __asm__ volatile ("sync"); | |
164 | ||
165 | #if SDRAM_DDR | |
166 | /* set tap delay */ | |
167 | *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY; | |
168 | __asm__ volatile ("sync"); | |
169 | #endif | |
170 | ||
171 | /* find RAM size using SDRAM CS0 only */ | |
172 | sdram_start(0); | |
6d0f6bcf | 173 | test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000); |
6dedf3d4 | 174 | sdram_start(1); |
6d0f6bcf | 175 | test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000); |
6dedf3d4 HS |
176 | if (test1 > test2) { |
177 | sdram_start(0); | |
178 | dramsize = test1; | |
179 | } else { | |
180 | dramsize = test2; | |
181 | } | |
182 | ||
183 | /* memory smaller than 1MB is impossible */ | |
184 | if (dramsize < (1 << 20)) { | |
185 | dramsize = 0; | |
186 | } | |
187 | ||
188 | /* set SDRAM CS0 size according to the amount of RAM found */ | |
189 | if (dramsize > 0) { | |
190 | *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + | |
191 | __builtin_ffs(dramsize >> 20) - 1; | |
192 | } else { | |
193 | *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */ | |
194 | } | |
195 | ||
196 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */ | |
6d0f6bcf | 197 | #else /* CONFIG_SYS_RAMBOOT */ |
6dedf3d4 HS |
198 | |
199 | /* retrieve size of memory connected to SDRAM CS0 */ | |
200 | dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF; | |
201 | if (dramsize >= 0x13) { | |
202 | dramsize = (1 << (dramsize - 0x13)) << 20; | |
203 | } else { | |
204 | dramsize = 0; | |
205 | } | |
206 | ||
207 | /* retrieve size of memory connected to SDRAM CS1 */ | |
208 | dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF; | |
209 | if (dramsize2 >= 0x13) { | |
210 | dramsize2 = (1 << (dramsize2 - 0x13)) << 20; | |
211 | } else { | |
212 | dramsize2 = 0; | |
213 | } | |
214 | ||
6d0f6bcf | 215 | #endif /* CONFIG_SYS_RAMBOOT */ |
6dedf3d4 HS |
216 | |
217 | /* return dramsize + dramsize2; */ | |
218 | return dramsize; | |
219 | } | |
220 | ||
221 | int checkboard (void) | |
222 | { | |
223 | puts ("Board: MAN UC101\n"); | |
37403005 | 224 | /* clear the Display */ |
6d0f6bcf | 225 | *(char *)(CONFIG_SYS_DISP_CWORD) = 0x80; |
6dedf3d4 HS |
226 | return 0; |
227 | } | |
228 | ||
229 | static void init_ports (void) | |
230 | { | |
f11033e7 | 231 | volatile struct mpc5xxx_gpio *pgpio = |
6dedf3d4 HS |
232 | (struct mpc5xxx_gpio *)MPC5XXX_GPIO; |
233 | ||
234 | GP_SIMP_ENABLE_I(GPIO_USB_8); /* HEX Bit 3 */ | |
235 | GP_SIMP_ENABLE_I(GPIO_USB_7); /* HEX Bit 2 */ | |
236 | GP_SIMP_ENABLE_I(GPIO_USB_6); /* HEX Bit 1 */ | |
237 | GP_SIMP_ENABLE_I(GPIO_USB_0); /* HEX Bit 0 */ | |
238 | GP_SIMP_ENABLE_I(GPIO_PSC3_0); /* Switch Menue A */ | |
239 | GP_SIMP_ENABLE_I(GPIO_PSC3_1); /* Switch Menue B */ | |
240 | GP_SIMP_ENABLE_I(GPIO_PSC3_6); /* Switch Cold_Warm */ | |
241 | GP_SIMP_ENABLE_I(GPIO_PSC3_7); /* Switch Restart */ | |
242 | GP_SINT_ENABLE_O(GPIO_PSC3_8, 0); /* LED H2 */ | |
243 | GP_SINT_ENABLE_O(GPIO_USB1_9, 0); /* LED H3 */ | |
244 | GP_TIMER_ENABLE_O(4, 0); /* LED H4 */ | |
245 | GP_TIMER_ENABLE_O(5, 0); /* LED H5 */ | |
246 | GP_TIMER_ENABLE_O(3, 0); /* LED HB */ | |
247 | GP_TIMER_ENABLE_O(1, 0); /* RES_COLDSTART */ | |
248 | } | |
249 | ||
250 | #ifdef CONFIG_PREBOOT | |
251 | ||
252 | static uchar kbd_magic_prefix[] = "key_magic"; | |
253 | static uchar kbd_command_prefix[] = "key_cmd"; | |
254 | ||
255 | struct kbd_data_t { | |
256 | char s1; | |
257 | }; | |
258 | ||
259 | struct kbd_data_t* get_keys (struct kbd_data_t *kbd_data) | |
260 | { | |
261 | volatile struct mpc5xxx_gpio *pgpio = | |
262 | (struct mpc5xxx_gpio *)MPC5XXX_GPIO; | |
263 | ||
264 | kbd_data->s1 = GP_SIMP_GET_I(GPIO_USB_8) << 3 | \ | |
265 | GP_SIMP_GET_I(GPIO_USB_7) << 2 | \ | |
266 | GP_SIMP_GET_I(GPIO_USB_6) << 1 | \ | |
267 | GP_SIMP_GET_I(GPIO_USB_0) << 0; | |
268 | return kbd_data; | |
269 | } | |
270 | ||
39218433 | 271 | static int compare_magic (const struct kbd_data_t *kbd_data, char *str) |
6dedf3d4 HS |
272 | { |
273 | char s1 = str[0]; | |
274 | ||
275 | if (s1 >= '0' && s1 <= '9') | |
276 | s1 -= '0'; | |
277 | else if (s1 >= 'a' && s1 <= 'f') | |
278 | s1 = s1 - 'a' + 10; | |
279 | else if (s1 >= 'A' && s1 <= 'F') | |
280 | s1 = s1 - 'A' + 10; | |
281 | else | |
282 | return -1; | |
283 | ||
284 | if (s1 != kbd_data->s1) return -1; | |
285 | return 0; | |
286 | } | |
287 | ||
39218433 | 288 | static char *key_match (const struct kbd_data_t *kbd_data) |
6dedf3d4 | 289 | { |
39218433 WD |
290 | char magic[sizeof (kbd_magic_prefix) + 1]; |
291 | char *suffix; | |
292 | char *kbd_magic_keys; | |
6dedf3d4 HS |
293 | |
294 | /* | |
295 | * The following string defines the characters that can be appended | |
296 | * to "key_magic" to form the names of environment variables that | |
297 | * hold "magic" key codes, i. e. such key codes that can cause | |
298 | * pre-boot actions. If the string is empty (""), then only | |
299 | * "key_magic" is checked (old behaviour); the string "125" causes | |
300 | * checks for "key_magic1", "key_magic2" and "key_magic5", etc. | |
301 | */ | |
302 | if ((kbd_magic_keys = getenv ("magic_keys")) == NULL) | |
303 | kbd_magic_keys = ""; | |
304 | ||
305 | /* loop over all magic keys; | |
306 | * use '\0' suffix in case of empty string | |
307 | */ | |
308 | for (suffix = kbd_magic_keys; *suffix || | |
309 | suffix == kbd_magic_keys; ++suffix) { | |
310 | sprintf (magic, "%s%c", kbd_magic_prefix, *suffix); | |
311 | ||
312 | if (compare_magic(kbd_data, getenv(magic)) == 0) { | |
39218433 | 313 | char cmd_name[sizeof (kbd_command_prefix) + 1]; |
6dedf3d4 HS |
314 | char *cmd; |
315 | ||
316 | sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix); | |
317 | cmd = getenv (cmd_name); | |
318 | ||
319 | return (cmd); | |
320 | } | |
321 | } | |
322 | ||
323 | return (NULL); | |
324 | } | |
325 | ||
326 | #endif /* CONFIG_PREBOOT */ | |
327 | ||
328 | int misc_init_r (void) | |
329 | { | |
330 | /* Init the I/O ports */ | |
331 | init_ports (); | |
332 | ||
333 | #ifdef CONFIG_PREBOOT | |
334 | struct kbd_data_t kbd_data; | |
335 | /* Decode keys */ | |
39218433 | 336 | char *str = strdup (key_match (get_keys (&kbd_data))); |
6dedf3d4 HS |
337 | /* Set or delete definition */ |
338 | setenv ("preboot", str); | |
339 | free (str); | |
340 | #endif /* CONFIG_PREBOOT */ | |
341 | return 0; | |
342 | } | |
343 | ||
344 | int board_early_init_r (void) | |
345 | { | |
346 | *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */ | |
347 | *(vu_long *)MPC5XXX_BOOTCS_START = | |
6d0f6bcf | 348 | *(vu_long *)MPC5XXX_CS0_START = START_REG(CONFIG_SYS_FLASH_BASE); |
6dedf3d4 | 349 | *(vu_long *)MPC5XXX_BOOTCS_STOP = |
6d0f6bcf | 350 | *(vu_long *)MPC5XXX_CS0_STOP = STOP_REG(CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_SIZE); |
6dedf3d4 HS |
351 | /* Interbus enable it here ?? */ |
352 | *(vu_long *)MPC5XXX_GPT6_ENABLE = GPT_OUT_1; | |
353 | return 0; | |
354 | } | |
355 | #ifdef CONFIG_PCI | |
356 | static struct pci_controller hose; | |
357 | ||
358 | extern void pci_mpc5xxx_init(struct pci_controller *); | |
359 | ||
360 | void pci_init_board(void) | |
361 | { | |
362 | pci_mpc5xxx_init(&hose); | |
363 | } | |
364 | #endif | |
365 | ||
366 | #if defined(CONFIG_HW_WATCHDOG) | |
367 | void hw_watchdog_reset(void) | |
368 | { | |
369 | /* Trigger HW Watchdog with TIMER_0 */ | |
370 | *(vu_long *)MPC5XXX_GPT0_ENABLE = GPT_OUT_1; | |
371 | *(vu_long *)MPC5XXX_GPT0_ENABLE = GPT_OUT_0; | |
372 | } | |
373 | #endif |