blob: f0af24ad9bd7d36ab054cdf38ed8fa5907823f94 [file] [log] [blame]
wdenk21136db2003-07-16 21:53:01 +00001/*
2 * (C) Copyright 2003
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
wdenke44b9112004-04-18 23:32:11 +00005 * (C) Copyright 2004
6 * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
7 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
wdenk21136db2003-07-16 21:53:01 +00009 */
10
11#include <common.h>
12#include <mpc5xxx.h>
wdenk02379022003-08-05 18:22:44 +000013#include <pci.h>
Rafal Jaworowski0b892e82006-03-29 13:17:09 +020014#include <asm/processor.h>
Grant Likely8d1e6e72007-09-06 09:46:23 -060015#include <libfdt.h>
Ben Warrenf2c1acb2008-08-31 10:03:22 -070016#include <netdev.h>
Stefan Roesefb347872006-11-28 17:55:49 +010017
Wolfgang Denk315b46a2006-03-17 11:42:53 +010018#if defined(CONFIG_LITE5200B)
19#include "mt46v32m16.h"
wdenke44b9112004-04-18 23:32:11 +000020#else
Wolfgang Denk315b46a2006-03-17 11:42:53 +010021# if defined(CONFIG_MPC5200_DDR)
22# include "mt46v16m16-75.h"
23# else
wdenke44b9112004-04-18 23:32:11 +000024#include "mt48lc16m16a2-75.h"
Wolfgang Denk315b46a2006-03-17 11:42:53 +010025# endif
wdenke44b9112004-04-18 23:32:11 +000026#endif
Domen Puncer64b89ae2007-04-16 14:00:13 +020027
28#ifdef CONFIG_LITE5200B_PM
29/* u-boot part of low-power mode implementation */
30#define SAVED_ADDR (*(void **)0x00000000)
31#define PSC2_4 0x02
32
33void lite5200b_wakeup(void)
34{
35 unsigned char wakeup_pin;
36 void (*linux_wakeup)(void);
37
38 /* check PSC2_4, if it's down "QT" is signaling we have a wakeup
39 * from low power mode */
40 *(vu_char *)MPC5XXX_WU_GPIO_ENABLE = PSC2_4;
41 __asm__ volatile ("sync");
42
43 wakeup_pin = *(vu_char *)MPC5XXX_WU_GPIO_DATA_I;
44 if (wakeup_pin & PSC2_4)
45 return;
46
47 /* acknowledge to "QT"
48 * by holding pin at 1 for 10 uS */
49 *(vu_char *)MPC5XXX_WU_GPIO_DIR = PSC2_4;
50 __asm__ volatile ("sync");
51 *(vu_char *)MPC5XXX_WU_GPIO_DATA_O = PSC2_4;
52 __asm__ volatile ("sync");
53 udelay(10);
54
55 /* put ram out of self-refresh */
56 *(vu_long *)MPC5XXX_SDRAM_CTRL |= 0x80000000; /* mode_en */
57 __asm__ volatile ("sync");
58 *(vu_long *)MPC5XXX_SDRAM_CTRL |= 0x50000000; /* cke ref_en */
59 __asm__ volatile ("sync");
60 *(vu_long *)MPC5XXX_SDRAM_CTRL &= ~0x80000000; /* !mode_en */
61 __asm__ volatile ("sync");
62 udelay(10); /* wait a bit */
63
64 /* jump back to linux kernel code */
65 linux_wakeup = SAVED_ADDR;
66 printf("\n\nLooks like we just woke, transferring control to 0x%08lx\n",
Wolfgang Denk8196e3a2010-10-24 15:37:12 +020067 (unsigned long)linux_wakeup);
Domen Puncer64b89ae2007-04-16 14:00:13 +020068 linux_wakeup();
69}
70#else
71#define lite5200b_wakeup()
72#endif
73
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020074#ifndef CONFIG_SYS_RAMBOOT
wdenk5d841732003-08-17 18:55:18 +000075static void sdram_start (int hi_addr)
76{
77 long hi_addr_bit = hi_addr ? 0x01000000 : 0;
wdenk21136db2003-07-16 21:53:01 +000078
wdenk236d3fc2003-12-20 22:45:10 +000079 /* unlock mode register */
wdenke44b9112004-04-18 23:32:11 +000080 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
81 __asm__ volatile ("sync");
wdenk20c98a62004-04-23 20:32:05 +000082
wdenk236d3fc2003-12-20 22:45:10 +000083 /* precharge all banks */
wdenke44b9112004-04-18 23:32:11 +000084 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
85 __asm__ volatile ("sync");
86
87#if SDRAM_DDR
wdenk236d3fc2003-12-20 22:45:10 +000088 /* set mode register: extended mode */
wdenke44b9112004-04-18 23:32:11 +000089 *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
90 __asm__ volatile ("sync");
91
wdenk236d3fc2003-12-20 22:45:10 +000092 /* set mode register: reset DLL */
wdenke44b9112004-04-18 23:32:11 +000093 *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
94 __asm__ volatile ("sync");
wdenk5d841732003-08-17 18:55:18 +000095#endif
wdenke44b9112004-04-18 23:32:11 +000096
97 /* precharge all banks */
98 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
99 __asm__ volatile ("sync");
100
wdenk0e2874cb2004-03-02 14:05:39 +0000101 /* auto refresh */
wdenke44b9112004-04-18 23:32:11 +0000102 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
103 __asm__ volatile ("sync");
104
wdenk21136db2003-07-16 21:53:01 +0000105 /* set mode register */
wdenke44b9112004-04-18 23:32:11 +0000106 *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
107 __asm__ volatile ("sync");
wdenk20c98a62004-04-23 20:32:05 +0000108
wdenk21136db2003-07-16 21:53:01 +0000109 /* normal operation */
wdenke44b9112004-04-18 23:32:11 +0000110 *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
111 __asm__ volatile ("sync");
wdenk5d841732003-08-17 18:55:18 +0000112}
wdenkb10ba6b2003-08-28 09:41:22 +0000113#endif
wdenk5d841732003-08-17 18:55:18 +0000114
wdenke44b9112004-04-18 23:32:11 +0000115/*
116 * ATTENTION: Although partially referenced initdram does NOT make real use
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200117 * use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE
wdenke44b9112004-04-18 23:32:11 +0000118 * is something else than 0x00000000.
119 */
120
Becky Brucebd99ae72008-06-09 16:03:40 -0500121phys_size_t initdram (int board_type)
wdenk5d841732003-08-17 18:55:18 +0000122{
wdenkb10ba6b2003-08-28 09:41:22 +0000123 ulong dramsize = 0;
wdenk236d3fc2003-12-20 22:45:10 +0000124 ulong dramsize2 = 0;
Rafal Jaworowski0b892e82006-03-29 13:17:09 +0200125 uint svr, pvr;
126
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200127#ifndef CONFIG_SYS_RAMBOOT
wdenkb10ba6b2003-08-28 09:41:22 +0000128 ulong test1, test2;
wdenk20c98a62004-04-23 20:32:05 +0000129
wdenke44b9112004-04-18 23:32:11 +0000130 /* setup SDRAM chip selects */
wdenk5d841732003-08-17 18:55:18 +0000131 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */
132 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */
wdenke44b9112004-04-18 23:32:11 +0000133 __asm__ volatile ("sync");
wdenk5d841732003-08-17 18:55:18 +0000134
wdenk236d3fc2003-12-20 22:45:10 +0000135 /* setup config registers */
wdenke44b9112004-04-18 23:32:11 +0000136 *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
137 *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
138 __asm__ volatile ("sync");
wdenk1ebf41e2004-01-02 14:00:00 +0000139
wdenke44b9112004-04-18 23:32:11 +0000140#if SDRAM_DDR
141 /* set tap delay */
142 *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
143 __asm__ volatile ("sync");
wdenk236d3fc2003-12-20 22:45:10 +0000144#endif
wdenk5d841732003-08-17 18:55:18 +0000145
wdenke44b9112004-04-18 23:32:11 +0000146 /* find RAM size using SDRAM CS0 only */
wdenk5d841732003-08-17 18:55:18 +0000147 sdram_start(0);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200148 test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
wdenk5d841732003-08-17 18:55:18 +0000149 sdram_start(1);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200150 test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
wdenk5d841732003-08-17 18:55:18 +0000151 if (test1 > test2) {
152 sdram_start(0);
153 dramsize = test1;
154 } else {
155 dramsize = test2;
156 }
wdenke44b9112004-04-18 23:32:11 +0000157
158 /* memory smaller than 1MB is impossible */
159 if (dramsize < (1 << 20)) {
160 dramsize = 0;
161 }
wdenk20c98a62004-04-23 20:32:05 +0000162
wdenke44b9112004-04-18 23:32:11 +0000163 /* set SDRAM CS0 size according to the amount of RAM found */
164 if (dramsize > 0) {
165 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1;
166 } else {
167 *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
168 }
169
wdenke44b9112004-04-18 23:32:11 +0000170 /* let SDRAM CS1 start right after CS0 */
wdenk236d3fc2003-12-20 22:45:10 +0000171 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */
wdenke44b9112004-04-18 23:32:11 +0000172
173 /* find RAM size using SDRAM CS1 only */
wdenke84ec902005-05-05 00:04:14 +0000174 if (!dramsize)
wdenkfaaa6022005-04-21 21:10:22 +0000175 sdram_start(0);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200176 test2 = test1 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
wdenkfaaa6022005-04-21 21:10:22 +0000177 if (!dramsize) {
178 sdram_start(1);
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200179 test2 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
wdenkfaaa6022005-04-21 21:10:22 +0000180 }
wdenk236d3fc2003-12-20 22:45:10 +0000181 if (test1 > test2) {
182 sdram_start(0);
183 dramsize2 = test1;
184 } else {
185 dramsize2 = test2;
186 }
wdenk20c98a62004-04-23 20:32:05 +0000187
wdenke44b9112004-04-18 23:32:11 +0000188 /* memory smaller than 1MB is impossible */
189 if (dramsize2 < (1 << 20)) {
190 dramsize2 = 0;
191 }
wdenk20c98a62004-04-23 20:32:05 +0000192
wdenke44b9112004-04-18 23:32:11 +0000193 /* set SDRAM CS1 size according to the amount of RAM found */
194 if (dramsize2 > 0) {
195 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize
196 | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
197 } else {
198 *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
199 }
200
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200201#else /* CONFIG_SYS_RAMBOOT */
wdenke44b9112004-04-18 23:32:11 +0000202
203 /* retrieve size of memory connected to SDRAM CS0 */
204 dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
205 if (dramsize >= 0x13) {
206 dramsize = (1 << (dramsize - 0x13)) << 20;
207 } else {
208 dramsize = 0;
209 }
210
211 /* retrieve size of memory connected to SDRAM CS1 */
212 dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
213 if (dramsize2 >= 0x13) {
214 dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
215 } else {
216 dramsize2 = 0;
217 }
218
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200219#endif /* CONFIG_SYS_RAMBOOT */
wdenke44b9112004-04-18 23:32:11 +0000220
Rafal Jaworowski0b892e82006-03-29 13:17:09 +0200221 /*
Wolfgang Denkebd3deb2006-04-16 10:51:58 +0200222 * On MPC5200B we need to set the special configuration delay in the
223 * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
Rafal Jaworowski0b892e82006-03-29 13:17:09 +0200224 * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
225 *
Wolfgang Denkebd3deb2006-04-16 10:51:58 +0200226 * "The SDelay should be written to a value of 0x00000004. It is
227 * required to account for changes caused by normal wafer processing
Rafal Jaworowski0b892e82006-03-29 13:17:09 +0200228 * parameters."
Wolfgang Denkebd3deb2006-04-16 10:51:58 +0200229 */
Rafal Jaworowski0b892e82006-03-29 13:17:09 +0200230 svr = get_svr();
231 pvr = get_pvr();
Wolfgang Denkebd3deb2006-04-16 10:51:58 +0200232 if ((SVR_MJREV(svr) >= 2) &&
Rafal Jaworowski0b892e82006-03-29 13:17:09 +0200233 (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
234
235 *(vu_long *)MPC5XXX_SDRAM_SDELAY = 0x04;
236 __asm__ volatile ("sync");
237 }
238
Domen Puncer64b89ae2007-04-16 14:00:13 +0200239 lite5200b_wakeup();
240
wdenke44b9112004-04-18 23:32:11 +0000241 return dramsize + dramsize2;
242}
243
wdenk21136db2003-07-16 21:53:01 +0000244int checkboard (void)
245{
Wolfgang Denk315b46a2006-03-17 11:42:53 +0100246#if defined (CONFIG_LITE5200B)
247 puts ("Board: Freescale Lite5200B\n");
Detlev Zundela414c7a2010-03-12 10:01:12 +0100248#else
wdenk21136db2003-07-16 21:53:01 +0000249 puts ("Board: Motorola MPC5200 (IceCube)\n");
wdenk21136db2003-07-16 21:53:01 +0000250#endif
251 return 0;
252}
253
254void flash_preinit(void)
255{
256 /*
257 * Now, when we are in RAM, enable flash write
258 * access for detection process.
259 * Note that CS_BOOT cannot be cleared when
260 * executing in flash.
261 */
wdenk21136db2003-07-16 21:53:01 +0000262 *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
263}
wdenk02379022003-08-05 18:22:44 +0000264
wdenkeb20ad32003-09-05 23:19:14 +0000265void flash_afterinit(ulong size)
266{
267 if (size == 0x800000) { /* adjust mapping */
wdenk9c53f402003-10-15 23:53:47 +0000268 *(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START =
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200269 START_REG(CONFIG_SYS_BOOTCS_START | size);
wdenk9c53f402003-10-15 23:53:47 +0000270 *(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP =
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200271 STOP_REG(CONFIG_SYS_BOOTCS_START | size, size);
wdenkeb20ad32003-09-05 23:19:14 +0000272 }
273}
274
wdenk02379022003-08-05 18:22:44 +0000275#ifdef CONFIG_PCI
276static struct pci_controller hose;
277
278extern void pci_mpc5xxx_init(struct pci_controller *);
279
280void pci_init_board(void)
281{
282 pci_mpc5xxx_init(&hose);
283}
284#endif
wdenkacd9b102004-03-14 00:59:59 +0000285
Jon Loeliger13f75992007-07-10 10:39:10 -0500286#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET)
wdenkacd9b102004-03-14 00:59:59 +0000287
wdenkacd9b102004-03-14 00:59:59 +0000288void init_ide_reset (void)
289{
wdenk369d43d2004-03-14 14:09:05 +0000290 debug ("init_ide_reset\n");
wdenkc35ba4e2004-03-14 22:25:36 +0000291
Wolfgang Denk87b3d4b2006-11-30 18:02:20 +0100292 /* Configure PSC1_4 as GPIO output for ATA reset */
wdenkacd9b102004-03-14 00:59:59 +0000293 *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
wdenk369d43d2004-03-14 14:09:05 +0000294 *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4;
wdenke2d6d742004-09-28 20:34:50 +0000295 /* Deassert reset */
Bartlomiej Sieka79eecbfb2006-11-01 01:38:16 +0100296 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
wdenkacd9b102004-03-14 00:59:59 +0000297}
298
299void ide_set_reset (int idereset)
300{
wdenk369d43d2004-03-14 14:09:05 +0000301 debug ("ide_reset(%d)\n", idereset);
302
wdenkacd9b102004-03-14 00:59:59 +0000303 if (idereset) {
Bartlomiej Sieka79eecbfb2006-11-01 01:38:16 +0100304 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4;
wdenke2d6d742004-09-28 20:34:50 +0000305 /* Make a delay. MPC5200 spec says 25 usec min */
306 udelay(500000);
wdenkacd9b102004-03-14 00:59:59 +0000307 } else {
Bartlomiej Sieka79eecbfb2006-11-01 01:38:16 +0100308 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
wdenkacd9b102004-03-14 00:59:59 +0000309 }
310}
Jon Loeliger13f75992007-07-10 10:39:10 -0500311#endif
Stefan Roesefb347872006-11-28 17:55:49 +0100312
Grant Likely8d1e6e72007-09-06 09:46:23 -0600313#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
Simon Glass2aec3cc2014-10-23 18:58:47 -0600314int ft_board_setup(void *blob, bd_t *bd)
Stefan Roesefb347872006-11-28 17:55:49 +0100315{
316 ft_cpu_setup(blob, bd);
Simon Glass2aec3cc2014-10-23 18:58:47 -0600317
318 return 0;
Stefan Roesefb347872006-11-28 17:55:49 +0100319}
320#endif
Ben Warrenf2c1acb2008-08-31 10:03:22 -0700321
322int board_eth_init(bd_t *bis)
323{
Ben Warrencba88512008-08-31 10:39:12 -0700324 cpu_eth_init(bis); /* Built in FEC comes first */
Ben Warrenf2c1acb2008-08-31 10:03:22 -0700325 return pci_eth_init(bis);
326}