ARM: tam3517-common: fix nand spl boot
[platform/kernel/u-boot.git] / board / icecube / icecube.c
1 /*
2  * (C) Copyright 2003
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  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <mpc5xxx.h>
13 #include <pci.h>
14 #include <asm/processor.h>
15 #include <libfdt.h>
16 #include <netdev.h>
17
18 #if defined(CONFIG_LITE5200B)
19 #include "mt46v32m16.h"
20 #else
21 # if defined(CONFIG_MPC5200_DDR)
22 #  include "mt46v16m16-75.h"
23 # else
24 #include "mt48lc16m16a2-75.h"
25 # endif
26 #endif
27
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
33 void 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",
67                         (unsigned long)linux_wakeup);
68         linux_wakeup();
69 }
70 #else
71 #define lite5200b_wakeup()
72 #endif
73
74 #ifndef CONFIG_SYS_RAMBOOT
75 static void sdram_start (int hi_addr)
76 {
77         long hi_addr_bit = hi_addr ? 0x01000000 : 0;
78
79         /* unlock mode register */
80         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
81         __asm__ volatile ("sync");
82
83         /* precharge all banks */
84         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
85         __asm__ volatile ("sync");
86
87 #if SDRAM_DDR
88         /* set mode register: extended mode */
89         *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
90         __asm__ volatile ("sync");
91
92         /* set mode register: reset DLL */
93         *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
94         __asm__ volatile ("sync");
95 #endif
96
97         /* precharge all banks */
98         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
99         __asm__ volatile ("sync");
100
101         /* auto refresh */
102         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
103         __asm__ volatile ("sync");
104
105         /* set mode register */
106         *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
107         __asm__ volatile ("sync");
108
109         /* normal operation */
110         *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
111         __asm__ volatile ("sync");
112 }
113 #endif
114
115 /*
116  * ATTENTION: Although partially referenced initdram does NOT make real use
117  *            use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE
118  *            is something else than 0x00000000.
119  */
120
121 phys_size_t initdram (int board_type)
122 {
123         ulong dramsize = 0;
124         ulong dramsize2 = 0;
125         uint svr, pvr;
126
127 #ifndef CONFIG_SYS_RAMBOOT
128         ulong test1, test2;
129
130         /* setup SDRAM chip selects */
131         *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */
132         *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */
133         __asm__ volatile ("sync");
134
135         /* setup config registers */
136         *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
137         *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
138         __asm__ volatile ("sync");
139
140 #if SDRAM_DDR
141         /* set tap delay */
142         *(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
143         __asm__ volatile ("sync");
144 #endif
145
146         /* find RAM size using SDRAM CS0 only */
147         sdram_start(0);
148         test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
149         sdram_start(1);
150         test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
151         if (test1 > test2) {
152                 sdram_start(0);
153                 dramsize = test1;
154         } else {
155                 dramsize = test2;
156         }
157
158         /* memory smaller than 1MB is impossible */
159         if (dramsize < (1 << 20)) {
160                 dramsize = 0;
161         }
162
163         /* 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
170         /* let SDRAM CS1 start right after CS0 */
171         *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */
172
173         /* find RAM size using SDRAM CS1 only */
174         if (!dramsize)
175                 sdram_start(0);
176         test2 = test1 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
177         if (!dramsize) {
178                 sdram_start(1);
179                 test2 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
180         }
181         if (test1 > test2) {
182                 sdram_start(0);
183                 dramsize2 = test1;
184         } else {
185                 dramsize2 = test2;
186         }
187
188         /* memory smaller than 1MB is impossible */
189         if (dramsize2 < (1 << 20)) {
190                 dramsize2 = 0;
191         }
192
193         /* 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
201 #else /* CONFIG_SYS_RAMBOOT */
202
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
219 #endif /* CONFIG_SYS_RAMBOOT */
220
221         /*
222          * On MPC5200B we need to set the special configuration delay in the
223          * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
224          * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
225          *
226          * "The SDelay should be written to a value of 0x00000004. It is
227          * required to account for changes caused by normal wafer processing
228          * parameters."
229          */
230         svr = get_svr();
231         pvr = get_pvr();
232         if ((SVR_MJREV(svr) >= 2) &&
233             (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
234
235                 *(vu_long *)MPC5XXX_SDRAM_SDELAY = 0x04;
236                 __asm__ volatile ("sync");
237         }
238
239         lite5200b_wakeup();
240
241         return dramsize + dramsize2;
242 }
243
244 int checkboard (void)
245 {
246 #if defined (CONFIG_LITE5200B)
247         puts ("Board: Freescale Lite5200B\n");
248 #else
249         puts ("Board: Motorola MPC5200 (IceCube)\n");
250 #endif
251         return 0;
252 }
253
254 void 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          */
262         *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
263 }
264
265 void flash_afterinit(ulong size)
266 {
267         if (size == 0x800000) { /* adjust mapping */
268                 *(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START =
269                         START_REG(CONFIG_SYS_BOOTCS_START | size);
270                 *(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP =
271                         STOP_REG(CONFIG_SYS_BOOTCS_START | size, size);
272         }
273 }
274
275 #ifdef  CONFIG_PCI
276 static struct pci_controller hose;
277
278 extern void pci_mpc5xxx_init(struct pci_controller *);
279
280 void pci_init_board(void)
281 {
282         pci_mpc5xxx_init(&hose);
283 }
284 #endif
285
286 #if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET)
287
288 void init_ide_reset (void)
289 {
290         debug ("init_ide_reset\n");
291
292         /* Configure PSC1_4 as GPIO output for ATA reset */
293         *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
294         *(vu_long *) MPC5XXX_WU_GPIO_DIR    |= GPIO_PSC1_4;
295         /* Deassert reset */
296         *(vu_long *) MPC5XXX_WU_GPIO_DATA_O   |= GPIO_PSC1_4;
297 }
298
299 void ide_set_reset (int idereset)
300 {
301         debug ("ide_reset(%d)\n", idereset);
302
303         if (idereset) {
304                 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4;
305                 /* Make a delay. MPC5200 spec says 25 usec min */
306                 udelay(500000);
307         } else {
308                 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |=  GPIO_PSC1_4;
309         }
310 }
311 #endif
312
313 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
314 void
315 ft_board_setup(void *blob, bd_t *bd)
316 {
317         ft_cpu_setup(blob, bd);
318 }
319 #endif
320
321 int board_eth_init(bd_t *bis)
322 {
323         cpu_eth_init(bis); /* Built in FEC comes first */
324         return pci_eth_init(bis);
325 }