]>
Commit | Line | Data |
---|---|---|
945af8d7 WD |
1 | /* |
2 | * (C) Copyright 2003 | |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | #include <common.h> | |
25 | #include <mpc5xxx.h> | |
96e48cf6 | 26 | #include <pci.h> |
945af8d7 | 27 | |
d94f92cb | 28 | #ifndef CFG_RAMBOOT |
e0ac62d7 | 29 | static long int dram_size(long int *base, long int maxsize) |
945af8d7 | 30 | { |
e0ac62d7 WD |
31 | volatile long int *addr; |
32 | ulong cnt, val; | |
33 | ulong save[32]; /* to make test non-destructive */ | |
34 | unsigned char i = 0; | |
945af8d7 | 35 | |
e0ac62d7 WD |
36 | for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) { |
37 | addr = base + cnt; /* pointer arith! */ | |
38 | ||
39 | save[i++] = *addr; | |
40 | *addr = ~cnt; | |
41 | } | |
42 | ||
43 | /* write 0 to base address */ | |
44 | addr = base; | |
45 | save[i] = *addr; | |
46 | *addr = 0; | |
47 | ||
48 | /* check at base address */ | |
49 | if ((val = *addr) != 0) { | |
50 | *addr = save[i]; | |
51 | return (0); | |
52 | } | |
53 | ||
54 | for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) { | |
55 | addr = base + cnt; /* pointer arith! */ | |
56 | ||
57 | val = *addr; | |
58 | *addr = save[--i]; | |
59 | ||
60 | if (val != (~cnt)) { | |
61 | return (cnt * sizeof (long)); | |
62 | } | |
63 | } | |
64 | return (maxsize); | |
65 | } | |
66 | ||
67 | static void sdram_start (int hi_addr) | |
68 | { | |
69 | long hi_addr_bit = hi_addr ? 0x01000000 : 0; | |
945af8d7 | 70 | |
b2001f27 WD |
71 | #ifdef CONFIG_MPC5200_DDR |
72 | /* unlock mode register */ | |
73 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xf05f0f00 | hi_addr_bit; | |
74 | /* precharge all banks */ | |
75 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xf05f0f02 | hi_addr_bit; | |
76 | /* set mode register: extended mode */ | |
77 | *(vu_long *)MPC5XXX_SDRAM_MODE = 0x40090000; | |
78 | /* set mode register: reset DLL */ | |
79 | *(vu_long *)MPC5XXX_SDRAM_MODE = 0x058d0000; | |
80 | /* precharge all banks */ | |
81 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xf05f0f02 | hi_addr_bit; | |
82 | /* auto refresh */ | |
83 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xf05f0f04 | hi_addr_bit; | |
84 | /* set mode register */ | |
85 | *(vu_long *)MPC5XXX_SDRAM_MODE = 0x018d0000; | |
86 | /* normal operation */ | |
87 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0x705f0f00 | hi_addr_bit; | |
88 | #else | |
945af8d7 | 89 | /* unlock mode register */ |
e0ac62d7 | 90 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0000 | hi_addr_bit; |
945af8d7 | 91 | /* precharge all banks */ |
e0ac62d7 | 92 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit; |
945af8d7 | 93 | /* set mode register */ |
e0ac62d7 | 94 | #if defined(CONFIG_MPC5200) |
945af8d7 | 95 | *(vu_long *)MPC5XXX_SDRAM_MODE = 0x408d0000; |
e0ac62d7 WD |
96 | #elif defined(CONFIG_MGT5100) |
97 | *(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000; | |
98 | #endif | |
945af8d7 | 99 | /* precharge all banks */ |
e0ac62d7 | 100 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit; |
945af8d7 | 101 | /* auto refresh */ |
e0ac62d7 | 102 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004 | hi_addr_bit; |
945af8d7 WD |
103 | /* set mode register */ |
104 | *(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000; | |
105 | /* normal operation */ | |
e0ac62d7 | 106 | *(vu_long *)MPC5XXX_SDRAM_CTRL = 0x504f0000 | hi_addr_bit; |
b2001f27 | 107 | #endif |
e0ac62d7 | 108 | } |
d94f92cb | 109 | #endif |
e0ac62d7 WD |
110 | |
111 | long int initdram (int board_type) | |
112 | { | |
d94f92cb | 113 | ulong dramsize = 0; |
b2001f27 WD |
114 | #ifdef CONFIG_MPC5200_DDR |
115 | ulong dramsize2 = 0; | |
116 | #endif | |
e0ac62d7 | 117 | #ifndef CFG_RAMBOOT |
d94f92cb WD |
118 | ulong test1, test2; |
119 | ||
e0ac62d7 WD |
120 | /* configure SDRAM start/end */ |
121 | #if defined(CONFIG_MPC5200) | |
122 | *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */ | |
123 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */ | |
124 | ||
b2001f27 WD |
125 | #ifdef CONFIG_MPC5200_DDR |
126 | /* setup config registers */ | |
127 | *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0x73722930; | |
128 | *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x47770000; | |
129 | ||
130 | /* set tap delay to 0x10 */ | |
131 | *(vu_long *)MPC5XXX_CDM_PORCFG = 0x10000000; | |
132 | #else | |
e0ac62d7 WD |
133 | /* setup config registers */ |
134 | *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2233a00; | |
135 | *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004; | |
b2001f27 | 136 | #endif |
e0ac62d7 | 137 | |
945af8d7 WD |
138 | #elif defined(CONFIG_MGT5100) |
139 | *(vu_long *)MPC5XXX_SDRAM_START = 0x00000000; | |
e0ac62d7 | 140 | *(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */ |
945af8d7 WD |
141 | *(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */ |
142 | ||
143 | /* setup config registers */ | |
144 | *(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2222600; | |
145 | *(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004; | |
146 | ||
147 | /* address select register */ | |
148 | *(vu_long *)MPC5XXX_SDRAM_XLBSEL = 0x03000000; | |
945af8d7 | 149 | #endif |
e0ac62d7 WD |
150 | sdram_start(0); |
151 | test1 = dram_size((ulong *)CFG_SDRAM_BASE, 0x80000000); | |
152 | sdram_start(1); | |
153 | test2 = dram_size((ulong *)CFG_SDRAM_BASE, 0x80000000); | |
154 | if (test1 > test2) { | |
155 | sdram_start(0); | |
156 | dramsize = test1; | |
157 | } else { | |
158 | dramsize = test2; | |
159 | } | |
160 | #if defined(CONFIG_MPC5200) | |
161 | *(vu_long *)MPC5XXX_SDRAM_CS0CFG = | |
162 | (0x13 + __builtin_ffs(dramsize >> 20) - 1); | |
b2001f27 WD |
163 | #ifdef CONFIG_MPC5200_DDR |
164 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */ | |
165 | sdram_start(0); | |
166 | test1 = dram_size((ulong *)(CFG_SDRAM_BASE + dramsize), 0x80000000); | |
167 | sdram_start(1); | |
168 | test2 = dram_size((ulong *)(CFG_SDRAM_BASE + dramsize), 0x80000000); | |
169 | if (test1 > test2) { | |
170 | sdram_start(0); | |
171 | dramsize2 = test1; | |
172 | } else { | |
173 | dramsize2 = test2; | |
174 | } | |
175 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = | |
176 | dramsize + (0x13 + __builtin_ffs(dramsize2 >> 20) - 1); | |
177 | #else | |
e0ac62d7 | 178 | *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */ |
b2001f27 | 179 | #endif |
e0ac62d7 WD |
180 | #elif defined(CONFIG_MGT5100) |
181 | *(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15); | |
182 | #endif | |
183 | ||
5cf9da48 | 184 | #else /* CFG_RAMBOOT */ |
945af8d7 WD |
185 | #ifdef CONFIG_MGT5100 |
186 | *(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */ | |
d94f92cb WD |
187 | dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15); |
188 | #else | |
189 | dramsize = ((1 << (*(vu_long *)MPC5XXX_SDRAM_CS0CFG - 0x13)) << 20); | |
b2001f27 WD |
190 | #ifdef CONFIG_MPC5200_DDR |
191 | dramsize2 = ((1 << (*(vu_long *)MPC5XXX_SDRAM_CS1CFG - 0x13)) << 20); | |
192 | #endif | |
945af8d7 | 193 | #endif |
d94f92cb | 194 | #endif /* CFG_RAMBOOT */ |
b2001f27 WD |
195 | |
196 | #ifdef CONFIG_MPC5200_DDR | |
197 | dramsize += dramsize2; | |
198 | #endif | |
945af8d7 | 199 | /* return total ram size */ |
e0ac62d7 | 200 | return dramsize; |
945af8d7 WD |
201 | } |
202 | ||
203 | int checkboard (void) | |
204 | { | |
205 | #if defined(CONFIG_MPC5200) | |
206 | puts ("Board: Motorola MPC5200 (IceCube)\n"); | |
207 | #elif defined(CONFIG_MGT5100) | |
208 | puts ("Board: Motorola MGT5100 (IceCube)\n"); | |
209 | #endif | |
210 | return 0; | |
211 | } | |
212 | ||
213 | void flash_preinit(void) | |
214 | { | |
215 | /* | |
216 | * Now, when we are in RAM, enable flash write | |
217 | * access for detection process. | |
218 | * Note that CS_BOOT cannot be cleared when | |
219 | * executing in flash. | |
220 | */ | |
221 | #if defined(CONFIG_MGT5100) | |
222 | *(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */ | |
223 | *(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */ | |
224 | #endif | |
225 | *(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */ | |
226 | } | |
96e48cf6 | 227 | |
7152b1d0 WD |
228 | void flash_afterinit(ulong size) |
229 | { | |
230 | if (size == 0x800000) { /* adjust mapping */ | |
42d1f039 | 231 | *(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START = |
7152b1d0 | 232 | START_REG(CFG_BOOTCS_START | size); |
42d1f039 | 233 | *(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP = |
7152b1d0 WD |
234 | STOP_REG(CFG_BOOTCS_START | size, size); |
235 | } | |
236 | } | |
237 | ||
96e48cf6 WD |
238 | #ifdef CONFIG_PCI |
239 | static struct pci_controller hose; | |
240 | ||
241 | extern void pci_mpc5xxx_init(struct pci_controller *); | |
242 | ||
243 | void pci_init_board(void) | |
244 | { | |
245 | pci_mpc5xxx_init(&hose); | |
246 | } | |
247 | #endif |