blob: 296099843421a0e489e47ffd843b75840b4d07fe [file] [log] [blame]
wdenk945af8d2003-07-16 21:53:01 +00001/*
2 * (C) Copyright 2003
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
wdenke35745b2004-04-18 23:32:11 +00005 * (C) Copyright 2004
6 * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
7 *
wdenk945af8d2003-07-16 21:53:01 +00008 * See file CREDITS for list of people who contributed to this
9 * project.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 * MA 02111-1307 USA
25 */
26
27#include <common.h>
28#include <mpc5xxx.h>
wdenk96e48cf2003-08-05 18:22:44 +000029#include <pci.h>
Rafal Jaworowskib66a9382006-03-29 13:17:09 +020030#include <asm/processor.h>
wdenk945af8d2003-07-16 21:53:01 +000031
Stefan Roesee59581c2006-11-28 17:55:49 +010032#if defined(CONFIG_OF_FLAT_TREE)
33#include <ft_build.h>
34#endif
35
Wolfgang Denk09e4b0c2006-03-17 11:42:53 +010036#if defined(CONFIG_LITE5200B)
37#include "mt46v32m16.h"
wdenke35745b2004-04-18 23:32:11 +000038#else
Wolfgang Denk09e4b0c2006-03-17 11:42:53 +010039# if defined(CONFIG_MPC5200_DDR)
40# include "mt46v16m16-75.h"
41# else
wdenke35745b2004-04-18 23:32:11 +000042#include "mt48lc16m16a2-75.h"
Wolfgang Denk09e4b0c2006-03-17 11:42:53 +010043# endif
wdenke35745b2004-04-18 23:32:11 +000044#endif
Domen Puncerd3832e82007-04-16 14:00:13 +020045
46#ifdef CONFIG_LITE5200B_PM
47/* u-boot part of low-power mode implementation */
48#define SAVED_ADDR (*(void **)0x00000000)
49#define PSC2_4 0x02
50
51void lite5200b_wakeup(void)
52{
53 unsigned char wakeup_pin;
54 void (*linux_wakeup)(void);
55
56 /* check PSC2_4, if it's down "QT" is signaling we have a wakeup
57 * from low power mode */
58 *(vu_char *)MPC5XXX_WU_GPIO_ENABLE = PSC2_4;
59 __asm__ volatile ("sync");
60
61 wakeup_pin = *(vu_char *)MPC5XXX_WU_GPIO_DATA_I;
62 if (wakeup_pin & PSC2_4)
63 return;
64
65 /* acknowledge to "QT"
66 * by holding pin at 1 for 10 uS */
67 *(vu_char *)MPC5XXX_WU_GPIO_DIR = PSC2_4;
68 __asm__ volatile ("sync");
69 *(vu_char *)MPC5XXX_WU_GPIO_DATA_O = PSC2_4;
70 __asm__ volatile ("sync");
71 udelay(10);
72
73 /* put ram out of self-refresh */
74 *(vu_long *)MPC5XXX_SDRAM_CTRL |= 0x80000000; /* mode_en */
75 __asm__ volatile ("sync");
76 *(vu_long *)MPC5XXX_SDRAM_CTRL |= 0x50000000; /* cke ref_en */
77 __asm__ volatile ("sync");
78 *(vu_long *)MPC5XXX_SDRAM_CTRL &= ~0x80000000; /* !mode_en */
79 __asm__ volatile ("sync");
80 udelay(10); /* wait a bit */
81
82 /* jump back to linux kernel code */
83 linux_wakeup = SAVED_ADDR;
84 printf("\n\nLooks like we just woke, transferring control to 0x%08lx\n",
85 linux_wakeup);
86 linux_wakeup();
87}
88#else
89#define lite5200b_wakeup()
90#endif
91
wdenkd94f92c2003-08-28 09:41:22 +000092#ifndef CFG_RAMBOOT
wdenke0ac62d2003-08-17 18:55:18 +000093static void sdram_start (int hi_addr)
94{
95 long hi_addr_bit = hi_addr ? 0x01000000 : 0;
96
wdenkb2001f22003-12-20 22:45:10 +000097 /* unlock mode register */
wdenke35745b2004-04-18 23:32:11 +000098 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
99 __asm__ volatile ("sync");
wdenk5cf91d62004-04-23 20:32:05 +0000100
wdenkb2001f22003-12-20 22:45:10 +0000101 /* precharge all banks */
wdenke35745b2004-04-18 23:32:11 +0000102 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
103 __asm__ volatile ("sync");
104
105#if SDRAM_DDR
wdenkb2001f22003-12-20 22:45:10 +0000106 /* set mode register: extended mode */
wdenke35745b2004-04-18 23:32:11 +0000107 *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
108 __asm__ volatile ("sync");
109
wdenkb2001f22003-12-20 22:45:10 +0000110 /* set mode register: reset DLL */
wdenke35745b2004-04-18 23:32:11 +0000111 *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
112 __asm__ volatile ("sync");
wdenke0ac62d2003-08-17 18:55:18 +0000113#endif
wdenke35745b2004-04-18 23:32:11 +0000114
115 /* precharge all banks */
116 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
117 __asm__ volatile ("sync");
118
wdenkf8d813e2004-03-02 14:05:39 +0000119 /* auto refresh */
wdenke35745b2004-04-18 23:32:11 +0000120 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
121 __asm__ volatile ("sync");
122
wdenke0ac62d2003-08-17 18:55:18 +0000123 /* set mode register */
wdenke35745b2004-04-18 23:32:11 +0000124 *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
125 __asm__ volatile ("sync");
wdenk5cf91d62004-04-23 20:32:05 +0000126
wdenke0ac62d2003-08-17 18:55:18 +0000127 /* normal operation */
wdenke35745b2004-04-18 23:32:11 +0000128 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
129 __asm__ volatile ("sync");
wdenke0ac62d2003-08-17 18:55:18 +0000130}
wdenkd94f92c2003-08-28 09:41:22 +0000131#endif
wdenke0ac62d2003-08-17 18:55:18 +0000132
wdenke35745b2004-04-18 23:32:11 +0000133/*
134 * ATTENTION: Although partially referenced initdram does NOT make real use
135 * use of CFG_SDRAM_BASE. The code does not work if CFG_SDRAM_BASE
136 * is something else than 0x00000000.
137 */
138
139#if defined(CONFIG_MPC5200)
wdenk945af8d2003-07-16 21:53:01 +0000140long int initdram (int board_type)
141{
wdenkd94f92c2003-08-28 09:41:22 +0000142 ulong dramsize = 0;
wdenkb2001f22003-12-20 22:45:10 +0000143 ulong dramsize2 = 0;
Rafal Jaworowskib66a9382006-03-29 13:17:09 +0200144 uint svr, pvr;
145
wdenk945af8d2003-07-16 21:53:01 +0000146#ifndef CFG_RAMBOOT
wdenkd94f92c2003-08-28 09:41:22 +0000147 ulong test1, test2;
wdenk5cf91d62004-04-23 20:32:05 +0000148
wdenke35745b2004-04-18 23:32:11 +0000149 /* setup SDRAM chip selects */
wdenke0ac62d2003-08-17 18:55:18 +0000150 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */
151 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */
wdenke35745b2004-04-18 23:32:11 +0000152 __asm__ volatile ("sync");
wdenk945af8d2003-07-16 21:53:01 +0000153
wdenkb2001f22003-12-20 22:45:10 +0000154 /* setup config registers */
wdenke35745b2004-04-18 23:32:11 +0000155 *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
156 *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
157 __asm__ volatile ("sync");
wdenkd4ca31c2004-01-02 14:00:00 +0000158
wdenke35745b2004-04-18 23:32:11 +0000159#if SDRAM_DDR
160 /* set tap delay */
161 *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
162 __asm__ volatile ("sync");
wdenkb2001f22003-12-20 22:45:10 +0000163#endif
wdenk945af8d2003-07-16 21:53:01 +0000164
wdenke35745b2004-04-18 23:32:11 +0000165 /* find RAM size using SDRAM CS0 only */
wdenke0ac62d2003-08-17 18:55:18 +0000166 sdram_start(0);
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200167 test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000);
wdenke0ac62d2003-08-17 18:55:18 +0000168 sdram_start(1);
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200169 test2 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000);
wdenke0ac62d2003-08-17 18:55:18 +0000170 if (test1 > test2) {
171 sdram_start(0);
172 dramsize = test1;
173 } else {
174 dramsize = test2;
175 }
wdenke35745b2004-04-18 23:32:11 +0000176
177 /* memory smaller than 1MB is impossible */
178 if (dramsize < (1 << 20)) {
179 dramsize = 0;
180 }
wdenk5cf91d62004-04-23 20:32:05 +0000181
wdenke35745b2004-04-18 23:32:11 +0000182 /* set SDRAM CS0 size according to the amount of RAM found */
183 if (dramsize > 0) {
184 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1;
185 } else {
186 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
187 }
188
wdenke35745b2004-04-18 23:32:11 +0000189 /* let SDRAM CS1 start right after CS0 */
wdenkb2001f22003-12-20 22:45:10 +0000190 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */
wdenke35745b2004-04-18 23:32:11 +0000191
192 /* find RAM size using SDRAM CS1 only */
wdenk07cc0992005-05-05 00:04:14 +0000193 if (!dramsize)
wdenka6310922005-04-21 21:10:22 +0000194 sdram_start(0);
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200195 test2 = test1 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x80000000);
wdenka6310922005-04-21 21:10:22 +0000196 if (!dramsize) {
197 sdram_start(1);
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200198 test2 = get_ram_size((long *)(CFG_SDRAM_BASE + dramsize), 0x80000000);
wdenka6310922005-04-21 21:10:22 +0000199 }
wdenkb2001f22003-12-20 22:45:10 +0000200 if (test1 > test2) {
201 sdram_start(0);
202 dramsize2 = test1;
203 } else {
204 dramsize2 = test2;
205 }
wdenk5cf91d62004-04-23 20:32:05 +0000206
wdenke35745b2004-04-18 23:32:11 +0000207 /* memory smaller than 1MB is impossible */
208 if (dramsize2 < (1 << 20)) {
209 dramsize2 = 0;
210 }
wdenk5cf91d62004-04-23 20:32:05 +0000211
wdenke35745b2004-04-18 23:32:11 +0000212 /* set SDRAM CS1 size according to the amount of RAM found */
213 if (dramsize2 > 0) {
214 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize
215 | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
216 } else {
217 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
218 }
wdenke0ac62d2003-08-17 18:55:18 +0000219
wdenke35745b2004-04-18 23:32:11 +0000220#else /* CFG_RAMBOOT */
221
222 /* retrieve size of memory connected to SDRAM CS0 */
223 dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
224 if (dramsize >= 0x13) {
225 dramsize = (1 << (dramsize - 0x13)) << 20;
226 } else {
227 dramsize = 0;
228 }
229
230 /* retrieve size of memory connected to SDRAM CS1 */
231 dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
232 if (dramsize2 >= 0x13) {
233 dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
234 } else {
235 dramsize2 = 0;
236 }
237
wdenkd94f92c2003-08-28 09:41:22 +0000238#endif /* CFG_RAMBOOT */
wdenkb2001f22003-12-20 22:45:10 +0000239
Rafal Jaworowskib66a9382006-03-29 13:17:09 +0200240 /*
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200241 * On MPC5200B we need to set the special configuration delay in the
242 * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
Rafal Jaworowskib66a9382006-03-29 13:17:09 +0200243 * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
244 *
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200245 * "The SDelay should be written to a value of 0x00000004. It is
246 * required to account for changes caused by normal wafer processing
Rafal Jaworowskib66a9382006-03-29 13:17:09 +0200247 * parameters."
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200248 */
Rafal Jaworowskib66a9382006-03-29 13:17:09 +0200249 svr = get_svr();
250 pvr = get_pvr();
Wolfgang Denkcf48eb92006-04-16 10:51:58 +0200251 if ((SVR_MJREV(svr) >= 2) &&
Rafal Jaworowskib66a9382006-03-29 13:17:09 +0200252 (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
253
254 *(vu_long *)MPC5XXX_SDRAM_SDELAY = 0x04;
255 __asm__ volatile ("sync");
256 }
257
Domen Puncerd3832e82007-04-16 14:00:13 +0200258 lite5200b_wakeup();
259
wdenke35745b2004-04-18 23:32:11 +0000260 return dramsize + dramsize2;
261}
262
263#elif defined(CONFIG_MGT5100)
264
265long int initdram (int board_type)
266{
267 ulong dramsize = 0;
268#ifndef CFG_RAMBOOT
269 ulong test1, test2;
wdenk5cf91d62004-04-23 20:32:05 +0000270
wdenke35745b2004-04-18 23:32:11 +0000271 /* setup and enable SDRAM chip selects */
272 *(vu_long *)MPC5XXX_SDRAM_START = 0x00000000;
273 *(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */
274 *(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
275 __asm__ volatile ("sync");
276
277 /* setup config registers */
278 *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
279 *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
280
281 /* address select register */
282 *(vu_long *)MPC5XXX_SDRAM_XLBSEL = SDRAM_ADDRSEL;
283 __asm__ volatile ("sync");
284
285 /* find RAM size */
286 sdram_start(0);
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200287 test1 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000);
wdenke35745b2004-04-18 23:32:11 +0000288 sdram_start(1);
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200289 test2 = get_ram_size((long *)CFG_SDRAM_BASE, 0x80000000);
wdenke35745b2004-04-18 23:32:11 +0000290 if (test1 > test2) {
291 sdram_start(0);
292 dramsize = test1;
293 } else {
294 dramsize = test2;
295 }
296
297 /* set SDRAM end address according to size */
298 *(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15);
wdenk5cf91d62004-04-23 20:32:05 +0000299
wdenke35745b2004-04-18 23:32:11 +0000300#else /* CFG_RAMBOOT */
301
302 /* Retrieve amount of SDRAM available */
303 dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15);
304
305#endif /* CFG_RAMBOOT */
306
wdenke0ac62d2003-08-17 18:55:18 +0000307 return dramsize;
wdenk945af8d2003-07-16 21:53:01 +0000308}
309
wdenke35745b2004-04-18 23:32:11 +0000310#else
311#error Neither CONFIG_MPC5200 or CONFIG_MGT5100 defined
312#endif
313
wdenk945af8d2003-07-16 21:53:01 +0000314int checkboard (void)
315{
Wolfgang Denk09e4b0c2006-03-17 11:42:53 +0100316#if defined (CONFIG_LITE5200B)
317 puts ("Board: Freescale Lite5200B\n");
318#elif defined(CONFIG_MPC5200)
wdenk945af8d2003-07-16 21:53:01 +0000319 puts ("Board: Motorola MPC5200 (IceCube)\n");
320#elif defined(CONFIG_MGT5100)
321 puts ("Board: Motorola MGT5100 (IceCube)\n");
322#endif
323 return 0;
324}
325
326void flash_preinit(void)
327{
328 /*
329 * Now, when we are in RAM, enable flash write
330 * access for detection process.
331 * Note that CS_BOOT cannot be cleared when
332 * executing in flash.
333 */
334#if defined(CONFIG_MGT5100)
335 *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
336 *(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
337#endif
338 *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
339}
wdenk96e48cf2003-08-05 18:22:44 +0000340
wdenk7152b1d2003-09-05 23:19:14 +0000341void flash_afterinit(ulong size)
342{
343 if (size == 0x800000) { /* adjust mapping */
wdenk42d1f032003-10-15 23:53:47 +0000344 *(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START =
wdenk7152b1d2003-09-05 23:19:14 +0000345 START_REG(CFG_BOOTCS_START | size);
wdenk42d1f032003-10-15 23:53:47 +0000346 *(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP =
wdenk7152b1d2003-09-05 23:19:14 +0000347 STOP_REG(CFG_BOOTCS_START | size, size);
348 }
349}
350
wdenk96e48cf2003-08-05 18:22:44 +0000351#ifdef CONFIG_PCI
352static struct pci_controller hose;
353
354extern void pci_mpc5xxx_init(struct pci_controller *);
355
356void pci_init_board(void)
357{
358 pci_mpc5xxx_init(&hose);
359}
360#endif
wdenkc3f9d492004-03-14 00:59:59 +0000361
362#if defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET)
363
wdenkc3f9d492004-03-14 00:59:59 +0000364void init_ide_reset (void)
365{
wdenk4d13cba2004-03-14 14:09:05 +0000366 debug ("init_ide_reset\n");
wdenk42dfe7a2004-03-14 22:25:36 +0000367
Wolfgang Denkdd520bf2006-11-30 18:02:20 +0100368 /* Configure PSC1_4 as GPIO output for ATA reset */
wdenkc3f9d492004-03-14 00:59:59 +0000369 *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
wdenk4d13cba2004-03-14 14:09:05 +0000370 *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4;
wdenk64f70be2004-09-28 20:34:50 +0000371 /* Deassert reset */
Bartlomiej Siekadae80f32006-11-01 01:38:16 +0100372 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
wdenkc3f9d492004-03-14 00:59:59 +0000373}
374
375void ide_set_reset (int idereset)
376{
wdenk4d13cba2004-03-14 14:09:05 +0000377 debug ("ide_reset(%d)\n", idereset);
378
wdenkc3f9d492004-03-14 00:59:59 +0000379 if (idereset) {
Bartlomiej Siekadae80f32006-11-01 01:38:16 +0100380 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4;
wdenk64f70be2004-09-28 20:34:50 +0000381 /* Make a delay. MPC5200 spec says 25 usec min */
382 udelay(500000);
wdenkc3f9d492004-03-14 00:59:59 +0000383 } else {
Bartlomiej Siekadae80f32006-11-01 01:38:16 +0100384 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
wdenkc3f9d492004-03-14 00:59:59 +0000385 }
386}
387#endif /* defined (CFG_CMD_IDE) && defined (CONFIG_IDE_RESET) */
Stefan Roesee59581c2006-11-28 17:55:49 +0100388
389#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
390void
391ft_board_setup(void *blob, bd_t *bd)
392{
393 ft_cpu_setup(blob, bd);
394}
395#endif