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