e680b7b8ffe5cd0911a283e57c5d0d8cef72a9b1
[platform/kernel/u-boot.git] / board / v38b / v38b.c
1 /*
2  * (C) Copyright 2003-2006
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 <net.h>
14 #include <asm/processor.h>
15
16 DECLARE_GLOBAL_DATA_PTR;
17
18 #ifndef CONFIG_SYS_RAMBOOT
19 static void sdram_start(int hi_addr)
20 {
21         long hi_addr_bit = hi_addr ? 0x01000000 : 0;
22
23         /* unlock mode register */
24         *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit;
25         __asm__ volatile ("sync");
26
27         /* precharge all banks */
28         *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
29         __asm__ volatile ("sync");
30
31 #if SDRAM_DDR
32         /* set mode register: extended mode */
33         *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
34         __asm__ volatile ("sync");
35
36         /* set mode register: reset DLL */
37         *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
38         __asm__ volatile ("sync");
39 #endif /* SDRAM_DDR */
40
41         /* precharge all banks */
42         *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit;
43         __asm__ volatile ("sync");
44
45         /* auto refresh */
46         *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 | hi_addr_bit;
47         __asm__ volatile ("sync");
48
49         /* set mode register */
50         *(vu_long *) MPC5XXX_SDRAM_MODE = SDRAM_MODE;
51         __asm__ volatile ("sync");
52
53         /* normal operation */
54         *(vu_long *) MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
55         __asm__ volatile ("sync");
56 }
57 #endif /* !CONFIG_SYS_RAMBOOT */
58
59
60 int dram_init(void)
61 {
62         ulong dramsize = 0;
63         ulong dramsize2 = 0;
64         uint svr, pvr;
65
66 #ifndef CONFIG_SYS_RAMBOOT
67         ulong test1, test2;
68
69         /* setup SDRAM chip selects */
70         *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0x0000001e; /* 2G at 0x0 */
71         *(vu_long *) MPC5XXX_SDRAM_CS1CFG = 0x80000000; /* disabled */
72         __asm__ volatile ("sync");
73
74         /* setup config registers */
75         *(vu_long *) MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
76         *(vu_long *) MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
77         __asm__ volatile ("sync");
78
79 #if SDRAM_DDR
80         /* set tap delay */
81         *(vu_long *) MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
82         __asm__ volatile ("sync");
83 #endif /* SDRAM_DDR */
84
85         /* find RAM size using SDRAM CS0 only */
86         sdram_start(0);
87         test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
88         sdram_start(1);
89         test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
90         if (test1 > test2) {
91                 sdram_start(0);
92                 dramsize = test1;
93         } else
94                 dramsize = test2;
95
96         /* memory smaller than 1MB is impossible */
97         if (dramsize < (1 << 20))
98                 dramsize = 0;
99
100         /* set SDRAM CS0 size according to the amount of RAM found */
101         if (dramsize > 0)
102                 *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1;
103         else
104                 *(vu_long *) MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
105
106         /* let SDRAM CS1 start right after CS0 */
107         *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */
108
109         /* find RAM size using SDRAM CS1 only */
110         if (!dramsize)
111                 sdram_start(0);
112         test2 = test1 = get_ram_size((long *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
113         if (!dramsize) {
114                 sdram_start(1);
115                 test2 = get_ram_size((long *) (CONFIG_SYS_SDRAM_BASE + dramsize), 0x80000000);
116         }
117         if (test1 > test2) {
118                 sdram_start(0);
119                 dramsize2 = test1;
120         } else
121                 dramsize2 = test2;
122
123         /* memory smaller than 1MB is impossible */
124         if (dramsize2 < (1 << 20))
125                 dramsize2 = 0;
126
127         /* set SDRAM CS1 size according to the amount of RAM found */
128         if (dramsize2 > 0)
129                 *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize
130                         | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
131         else
132                 *(vu_long *) MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
133
134 #else /* CONFIG_SYS_RAMBOOT */
135
136         /* retrieve size of memory connected to SDRAM CS0 */
137         dramsize = *(vu_long *) MPC5XXX_SDRAM_CS0CFG & 0xFF;
138         if (dramsize >= 0x13)
139                 dramsize = (1 << (dramsize - 0x13)) << 20;
140         else
141                 dramsize = 0;
142
143         /* retrieve size of memory connected to SDRAM CS1 */
144         dramsize2 = *(vu_long *) MPC5XXX_SDRAM_CS1CFG & 0xFF;
145         if (dramsize2 >= 0x13)
146                 dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
147         else
148                 dramsize2 = 0;
149
150 #endif /* CONFIG_SYS_RAMBOOT */
151
152         /*
153          * On MPC5200B we need to set the special configuration delay in the
154          * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
155          * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
156          *
157          * "The SDelay should be written to a value of 0x00000004. It is
158          * required to account for changes caused by normal wafer processing
159          * parameters."
160          */
161         svr = get_svr();
162         pvr = get_pvr();
163         if ((SVR_MJREV(svr) >= 2) &&
164                 (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
165
166                 *(vu_long *) MPC5XXX_SDRAM_SDELAY = 0x04;
167                 __asm__ volatile ("sync");
168         }
169
170         gd->ram_size = dramsize + dramsize2;
171
172         return 0;
173 }
174
175
176 int checkboard (void)
177 {
178         puts("Board: MarelV38B\n");
179         return 0;
180 }
181
182 int board_early_init_f(void)
183 {
184 #ifdef CONFIG_HW_WATCHDOG
185         /*
186          * Enable and configure the direction (output) of PSC3_9 - watchdog
187          * reset input. Refer to 7.3.2.2.[1,3,4] of the MPC5200B User's
188          * Manual.
189          */
190         *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC3_9;
191         *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC3_9;
192 #endif /* CONFIG_HW_WATCHDOG */
193         return 0;
194 }
195
196 int board_early_init_r(void)
197 {
198         /*
199          * Now, when we are in RAM, enable flash write access for the
200          * detection process.  Note that CS_BOOT cannot be cleared when
201          * executing in flash.
202          */
203         *(vu_long *) MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
204
205         /*
206          * Enable GPIO_WKUP_7 to "read the status of the actual power
207          * situation". Default direction is input, so no need to set it
208          * explicitly.
209          */
210         *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_WKUP_7;
211         return 0;
212 }
213
214 extern void board_get_enetaddr(uchar *enetaddr);
215 int misc_init_r(void)
216 {
217         uchar enetaddr[6];
218
219         if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
220                 board_get_enetaddr(enetaddr);
221                 eth_setenv_enetaddr("ethaddr", enetaddr);
222         }
223
224         return 0;
225 }
226
227 #if defined(CONFIG_IDE) && defined(CONFIG_IDE_RESET)
228 void init_ide_reset(void)
229 {
230         debug("init_ide_reset\n");
231
232         /* Configure PSC1_4 as GPIO output for ATA reset */
233         *(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
234         *(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4;
235         /* Deassert reset */
236         *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
237 }
238
239
240 void ide_set_reset(int idereset)
241 {
242         debug("ide_reset(%d)\n", idereset);
243
244         if (idereset) {
245                 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4;
246                 /* Make a delay. MPC5200 spec says 25 usec min */
247                 udelay(500000);
248         } else
249                 *(vu_long *) MPC5XXX_WU_GPIO_DATA_O |=  GPIO_PSC1_4;
250 }
251 #endif
252
253
254 #ifdef CONFIG_HW_WATCHDOG
255 void hw_watchdog_reset(void)
256 {
257         /*
258          * MarelV38B has a TPS3705 watchdog. Spec says that to kick the dog
259          * we need a positive or negative transition on WDI i.e., our PSC3_9.
260          */
261         *(vu_long *) MPC5XXX_WU_GPIO_DATA_O ^= GPIO_PSC3_9;
262 }
263 #endif /* CONFIG_HW_WATCHDOG */