]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - board/fads/fads.c
Add a common get_ram_size() function and modify the the
[karo-tx-uboot.git] / board / fads / fads.c
1 /*
2  * (C) Copyright 2000-2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * Modified by, Yuli Barcohen, Arabella Software Ltd., yuli@arabellasw.com
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25
26 #include <config.h>
27 #include <common.h>
28 #include <mpc8xx.h>
29
30 #define _NOT_USED_      0xFFFFFFFF
31
32 /* ========================================================================= */
33
34 #ifndef CONFIG_DUET_ADS /* No old DRAM on Duet */
35
36 #if defined(CONFIG_DRAM_50MHZ)
37 /* 50MHz tables */
38 static const uint dram_60ns[] =
39 { 0x8fffec24, 0x0fffec04, 0x0cffec04, 0x00ffec04,
40   0x00ffec00, 0x37ffec47, _NOT_USED_, _NOT_USED_,
41   0x8fffec24, 0x0fffec04, 0x08ffec04, 0x00ffec0c,
42   0x03ffec00, 0x00ffec44, 0x00ffcc08, 0x0cffcc44,
43   0x00ffec0c, 0x03ffec00, 0x00ffec44, 0x00ffcc00,
44   0x3fffc847, _NOT_USED_, _NOT_USED_, _NOT_USED_,
45   0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x11bfcc47,
46   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
47   0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x03afcc4c,
48   0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
49   0x0cafcc00, 0x33bfcc4f, _NOT_USED_, _NOT_USED_,
50   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
51   0xc0ffcc84, 0x00ffcc04, 0x07ffcc04, 0x3fffcc06,
52   0xffffcc85, 0xffffcc05, _NOT_USED_, _NOT_USED_,
53   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
54   0x33ffcc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
55
56 static const uint dram_70ns[] =
57 { 0x8fffcc24, 0x0fffcc04, 0x0cffcc04, 0x00ffcc04,
58   0x00ffcc00, 0x37ffcc47, _NOT_USED_, _NOT_USED_,
59   0x8fffcc24, 0x0fffcc04, 0x0cffcc04, 0x00ffcc04,
60   0x00ffcc08, 0x0cffcc44, 0x00ffec0c, 0x03ffec00,
61   0x00ffec44, 0x00ffcc08, 0x0cffcc44, 0x00ffec04,
62   0x00ffec00, 0x3fffec47, _NOT_USED_, _NOT_USED_,
63   0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x11bfcc47,
64   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
65   0x8fafcc24, 0x0fafcc04, 0x0cafcc00, 0x03afcc4c,
66   0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
67   0x0cafcc00, 0x33bfcc4f, _NOT_USED_, _NOT_USED_,
68   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
69   0xe0ffcc84, 0x00ffcc04, 0x00ffcc04, 0x0fffcc04,
70   0x7fffcc06, 0xffffcc85, 0xffffcc05, _NOT_USED_,
71   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
72   0x33ffcc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
73
74 static const uint edo_60ns[] =
75 { 0x8ffbec24, 0x0ff3ec04, 0x0cf3ec04, 0x00f3ec04,
76   0x00f3ec00, 0x37f7ec47, _NOT_USED_, _NOT_USED_,
77   0x8fffec24, 0x0ffbec04, 0x0cf3ec04, 0x00f3ec0c,
78   0x0cf3ec00, 0x00f3ec4c, 0x0cf3ec00, 0x00f3ec4c,
79   0x0cf3ec00, 0x00f3ec44, 0x03f3ec00, 0x3ff7ec47,
80   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
81   0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x11bfcc47,
82   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
83   0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x03afcc4c,
84   0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
85   0x0cafcc00, 0x33bfcc4f, _NOT_USED_, _NOT_USED_,
86   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
87   0xc0ffcc84, 0x00ffcc04, 0x07ffcc04, 0x3fffcc06,
88   0xffffcc85, 0xffffcc05, _NOT_USED_, _NOT_USED_,
89   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
90   0x33ffcc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
91
92 static const uint edo_70ns[] =
93 { 0x8ffbcc24, 0x0ff3cc04, 0x0cf3cc04, 0x00f3cc04,
94   0x00f3cc00, 0x37f7cc47, _NOT_USED_, _NOT_USED_,
95   0x8fffcc24, 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc0c,
96   0x03f3cc00, 0x00f3cc44, 0x00f3ec0c, 0x0cf3ec00,
97   0x00f3ec4c, 0x03f3ec00, 0x00f3ec44, 0x00f3cc00,
98   0x33f7cc47, _NOT_USED_, _NOT_USED_, _NOT_USED_,
99   0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x11bfcc47,
100   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
101   0x8fffcc24, 0x0fefcc04, 0x0cafcc00, 0x03afcc4c,
102   0x0cafcc00, 0x03afcc4c, 0x0cafcc00, 0x03afcc4c,
103   0x0cafcc00, 0x33bfcc47, _NOT_USED_, _NOT_USED_,
104   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
105   0xe0ffcc84, 0x00ffcc04, 0x00ffcc04, 0x0fffcc04,
106   0x7fffcc04, 0xffffcc86, 0xffffcc05, _NOT_USED_,
107   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
108   0x33ffcc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
109
110 #elif defined(CONFIG_DRAM_25MHZ)
111
112 /* 25MHz tables */
113
114 static const uint dram_60ns[] =
115 { 0x0fffcc04, 0x08ffcc00, 0x33ffcc47, _NOT_USED_,
116   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
117   0x0fffcc24, 0x0fffcc04, 0x08ffcc00, 0x03ffcc4c,
118   0x08ffcc00, 0x03ffcc4c, 0x08ffcc00, 0x03ffcc4c,
119   0x08ffcc00, 0x33ffcc47, _NOT_USED_, _NOT_USED_,
120   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
121   0x0fafcc04, 0x08afcc00, 0x3fbfcc47, _NOT_USED_,
122   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
123   0x0fafcc04, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
124   0x01afcc4c, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
125   0x31bfcc43, _NOT_USED_, _NOT_USED_, _NOT_USED_,
126   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
127   0x80ffcc84, 0x13ffcc04, 0xffffcc87, 0xffffcc05,
128   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
129   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
130   0x33ffcc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
131
132 static const uint dram_70ns[] =
133 { 0x0fffec04, 0x08ffec04, 0x00ffec00, 0x3fffcc47,
134   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
135   0x0fffcc24, 0x0fffcc04, 0x08ffcc00, 0x03ffcc4c,
136   0x08ffcc00, 0x03ffcc4c, 0x08ffcc00, 0x03ffcc4c,
137   0x08ffcc00, 0x33ffcc47, _NOT_USED_, _NOT_USED_,
138   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
139   0x0fafcc04, 0x08afcc00, 0x3fbfcc47, _NOT_USED_,
140   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
141   0x0fafcc04, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
142   0x01afcc4c, 0x0cafcc00, 0x01afcc4c, 0x0cafcc00,
143   0x31bfcc43, _NOT_USED_, _NOT_USED_, _NOT_USED_,
144   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
145   0xc0ffcc84, 0x01ffcc04, 0x7fffcc86, 0xffffcc05,
146   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
147   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
148   0x33ffcc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
149
150 static const uint edo_60ns[] =
151 { 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc00, 0x33f7cc47,
152   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
153   0x0ffbcc04, 0x09f3cc0c, 0x09f3cc0c, 0x09f3cc0c,
154   0x08f3cc00, 0x3ff7cc47, _NOT_USED_, _NOT_USED_,
155   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
156   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
157   0x0fefcc04, 0x08afcc04, 0x00afcc00, 0x3fbfcc47,
158   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
159   0x0fefcc04, 0x08afcc00, 0x07afcc48, 0x08afcc48,
160   0x08afcc48, 0x39bfcc47, _NOT_USED_, _NOT_USED_,
161   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
162   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
163   0x80ffcc84, 0x13ffcc04, 0xffffcc87, 0xffffcc05,
164   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
165   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
166   0x33ffcc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
167
168 static const uint edo_70ns[] =
169 { 0x0ffbcc04, 0x0cf3cc04, 0x00f3cc00, 0x33f7cc47,
170   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
171   0x0ffbec04, 0x08f3ec04, 0x03f3ec48, 0x08f3cc00,
172   0x0ff3cc4c, 0x08f3cc00, 0x0ff3cc4c, 0x08f3cc00,
173   0x3ff7cc47, _NOT_USED_, _NOT_USED_, _NOT_USED_,
174   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
175   0x0fefcc04, 0x08afcc04, 0x00afcc00, 0x3fbfcc47,
176   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
177   0x0fefcc04, 0x08afcc00, 0x07afcc4c, 0x08afcc00,
178   0x07afcc4c, 0x08afcc00, 0x07afcc4c, 0x08afcc00,
179   0x37bfcc47, _NOT_USED_, _NOT_USED_, _NOT_USED_,
180   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
181   0xc0ffcc84, 0x01ffcc04, 0x7fffcc86, 0xffffcc05,
182   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
183   _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
184   0x33ffcc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
185 #else
186 #error dram not correctly defined - use CONFIG_DRAM_25MHZ or CONFIG_DRAM_50MHZ
187 #endif
188
189 /* ------------------------------------------------------------------------- */
190 static int _draminit (uint base, uint noMbytes, uint edo, uint delay)
191 {
192         volatile immap_t *immap = (immap_t *) CFG_IMMR;
193         volatile memctl8xx_t *memctl = &immap->im_memctl;
194
195         /* init upm */
196
197         switch (delay) {
198         case 70:
199                 if (edo) {
200                         upmconfig (UPMA, (uint *) edo_70ns,
201                                    sizeof (edo_70ns) / sizeof (uint));
202                 } else {
203                         upmconfig (UPMA, (uint *) dram_70ns,
204                                    sizeof (dram_70ns) / sizeof (uint));
205                 }
206
207                 break;
208
209         case 60:
210                 if (edo) {
211                         upmconfig (UPMA, (uint *) edo_60ns,
212                                    sizeof (edo_60ns) / sizeof (uint));
213                 } else {
214                         upmconfig (UPMA, (uint *) dram_60ns,
215                                    sizeof (dram_60ns) / sizeof (uint));
216                 }
217
218                 break;
219
220         default:
221                 return -1;
222         }
223
224         memctl->memc_mptpr = 0x0400;    /* divide by 16 */
225
226         switch (noMbytes) {
227         case 4:                         /* 4 Mbyte uses only CS2 */
228 #ifdef CONFIG_ADS
229                 memctl->memc_mamr = 0xc0a21114;
230 #else
231                 memctl->memc_mamr = 0x13a01114; /* PTA 0x13 AMA 010 */
232 #endif
233                 memctl->memc_or2 = 0xffc00800;  /* 4M */
234                 break;
235
236         case 8:                         /* 8 Mbyte uses both CS3 and CS2 */
237                 memctl->memc_mamr = 0x13a01114; /* PTA 0x13 AMA 010 */
238                 memctl->memc_or3 = 0xffc00800;  /* 4M */
239                 memctl->memc_br3 = 0x00400081 + base;
240                 memctl->memc_or2 = 0xffc00800;  /* 4M */
241                 break;
242
243         case 16:                        /* 16 Mbyte uses only CS2 */
244 #ifdef CONFIG_ADS       /* XXX: why PTA=0x60 only in 16M case? - NTL */
245                 memctl->memc_mamr = 0x60b21114; /* PTA 0x60 AMA 011 */
246 #else
247                 memctl->memc_mamr = 0x13b01114; /* PTA 0x13 AMA 011 */
248 #endif
249                 memctl->memc_or2 = 0xff000800;  /* 16M */
250                 break;
251
252         case 32:                        /* 32 Mbyte uses both CS3 and CS2 */
253                 memctl->memc_mamr = 0x13b01114; /* PTA 0x13 AMA 011 */
254                 memctl->memc_or3 = 0xff000800;  /* 16M */
255                 memctl->memc_br3 = 0x01000081 + base;
256                 memctl->memc_or2 = 0xff000800;  /* 16M */
257                 break;
258
259         default:
260                 return -1;
261         }
262
263         memctl->memc_br2 = 0x81 + base; /* use upma */
264
265         *((uint *) BCSR1) &= ~BCSR1_DRAM_EN;    /* enable dram */
266
267         /* if no dimm is inserted, noMbytes is still detected as 8m, so
268          * sanity check top and bottom of memory */
269
270         /* check bytes / 2 because get_ram_size tests at base+bytes, which
271          * is not mapped */
272         if (noMbytes == 8)
273                 if (get_ram_size ((long *) base, noMbytes << 19) != noMbytes << 19) {
274                         *((uint *) BCSR1) |= BCSR1_DRAM_EN;     /* disable dram */
275                         return -1;
276                 }
277
278         return 0;
279 }
280
281 /* ------------------------------------------------------------------------- */
282
283 static void _dramdisable(void)
284 {
285         volatile immap_t     *immap = (immap_t *)CFG_IMMR;
286         volatile memctl8xx_t *memctl = &immap->im_memctl;
287
288         memctl->memc_br2 = 0x00000000;
289         memctl->memc_br3 = 0x00000000;
290
291         /* maybe we should turn off upma here or something */
292 }
293 #endif /* !CONFIG_DUET_ADS */
294
295 /* ========================================================================= */
296
297 #ifdef CONFIG_FADS /* SDRAM exists on FADS and newer boards */
298
299 #if defined(CONFIG_SDRAM_100MHZ)
300
301 /* ------------------------------------------------------------------------- */
302 /* sdram table by Dan Malek                                                  */
303
304 /* This has the stretched early timing so the 50 MHz
305  * processor can make the 100 MHz timing.  This will
306  * work at all processor speeds.
307  */
308
309 #ifdef SDRAM_ALT_INIT_SEQENCE
310 # define SDRAM_MBMRVALUE0 0xc3802114 /* PTx=195,PTxE,AMx=0,DSx=1,A11,RLFx=1,WLFx=1,TLFx=4 */
311 #define SDRAM_MBMRVALUE1 SDRAM_MBMRVALUE0
312 # define SDRAM_MCRVALUE0  0x80808111   /* run upmb cs4 loop 1 addr 0x11 MRS */
313 # define SDRAM_MCRVALUE1  SDRAM_MCRVALUE0  /* ??? why not 0x80808130? */
314 #else
315 # define SDRAM_MxMR_PTx         195
316 # define UPM_MRS_ADDR           0x11
317 # define UPM_REFRESH_ADDR       0x30    /* or 0x11 if we want to be like above? */
318 #endif /* !SDRAM_ALT_INIT_SEQUENCE */
319
320 static const uint sdram_table[] =
321 {
322         /* single read. (offset 0 in upm RAM) */
323         0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x11adfc04,
324         0xefbbbc00, 0x1ff77c45, _NOT_USED_, _NOT_USED_,
325
326         /* burst read. (offset 8 in upm RAM) */
327         0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x10adfc04,
328         0xf0affc00, 0xf0affc00, 0xf1affc00, 0xefbbbc00,
329         0x1ff77c45,
330
331         /* precharge + MRS. (offset 11 in upm RAM) */
332         0xeffbbc04, 0x1ff77c34, 0xefeabc34,
333         0x1fb57c35, _NOT_USED_, _NOT_USED_, _NOT_USED_,
334
335         /* single write. (offset 18 in upm RAM) */
336         0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x01b93c04,
337         0x1ff77c45, _NOT_USED_, _NOT_USED_, _NOT_USED_,
338
339         /* burst write. (offset 20 in upm RAM) */
340         0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x10ad7c00,
341         0xf0affc00, 0xf0affc00, 0xe1bbbc04, 0x1ff77c45,
342         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
343         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
344
345         /* refresh. (offset 30 in upm RAM) */
346         0xeffafc84, 0x1ff5fc04, 0xfffffc04, 0xfffffc04,
347         0xfffffc84, 0xfffffc07, _NOT_USED_, _NOT_USED_,
348         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
349
350         /* exception. (offset 3c in upm RAM) */
351         0xeffffc06, 0x1ffffc07, _NOT_USED_, _NOT_USED_ };
352
353 #elif defined(CONFIG_SDRAM_50MHZ)
354
355 /* ------------------------------------------------------------------------- */
356 /* sdram table stolen from the fads manual                                   */
357 /* for chip MB811171622A-100                                                 */
358
359 /* this table is for 32-50MHz operation */
360 #ifdef SDRAM_ALT_INIT_SEQENCE
361 # define SDRAM_MBMRVALUE0 0x80802114   /* PTx=128,PTxE,AMx=0,DSx=1,A11,RLFx=1,WLFx=1,TLFx=4 */
362 # define SDRAM_MBMRVALUE1 0x80802118   /* PTx=128,PTxE,AMx=0,DSx=1,A11,RLFx=1,WLFx=1,TLFx=8 */
363 # define SDRAM_MCRVALUE0  0x80808105   /* run upmb cs4 loop 1 addr 0x5 MRS */
364 # define SDRAM_MCRVALUE1  0x80808130   /* run upmb cs4 loop 1 addr 0x30 REFRESH */
365 # define SDRAM_MPTRVALUE  0x400
366 #define SDRAM_MARVALUE   0x88
367 #else
368 # define SDRAM_MxMR_PTx         128
369 # define UPM_MRS_ADDR           0x5
370 # define UPM_REFRESH_ADDR       0x30
371 #endif  /* !SDRAM_ALT_INIT_SEQUENCE */
372
373 static const uint sdram_table[] =
374 {
375         /* single read. (offset 0 in upm RAM) */
376         0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
377         0x1ff77c47,
378
379         /* precharge + MRS. (offset 5 in upm RAM) */
380         0x1ff77c34, 0xefeabc34, 0x1fb57c35,
381
382         /* burst read. (offset 8 in upm RAM) */
383         0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
384         0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
385         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
386         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
387
388         /* single write. (offset 18 in upm RAM) */
389         0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
390         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
391
392         /* burst write. (offset 20 in upm RAM) */
393         0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
394         0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _NOT_USED_,
395         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
396         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
397
398         /* refresh. (offset 30 in upm RAM) */
399         0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
400         0xfffffc84, 0xfffffc07, _NOT_USED_, _NOT_USED_,
401         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
402
403         /* exception. (offset 3c in upm RAM) */
404         0x7ffffc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
405
406 /* ------------------------------------------------------------------------- */
407 #else
408 #error SDRAM not correctly configured
409 #endif
410 /* ------------------------------------------------------------------------- */
411
412 /*
413  * Memory Periodic Timer Prescaler
414  */
415
416 #define SDRAM_OR4VALUE   0x00000a00 /* SAM,GL5A/S=01,addr mask or'ed on later */
417 #define SDRAM_BR4VALUE   0x000000c1 /* UPMB,base addr or'ed on later */
418
419 /* ------------------------------------------------------------------------- */
420 #ifdef SDRAM_ALT_INIT_SEQENCE
421 /* ------------------------------------------------------------------------- */
422
423 static int _initsdram(uint base, uint noMbytes)
424 {
425         volatile immap_t     *immap = (immap_t *)CFG_IMMR;
426         volatile memctl8xx_t *memctl = &immap->im_memctl;
427
428         upmconfig(UPMB, (uint *)sdram_table,sizeof(sdram_table)/sizeof(uint));
429
430         memctl->memc_mptpr = SDRAM_MPTPRVALUE;
431
432         /* Configure the refresh (mostly).  This needs to be
433         * based upon processor clock speed and optimized to provide
434         * the highest level of performance.  For multiple banks,
435         * this time has to be divided by the number of banks.
436         * Although it is not clear anywhere, it appears the
437         * refresh steps through the chip selects for this UPM
438         * on each refresh cycle.
439         * We have to be careful changing
440         * UPM registers after we ask it to run these commands.
441         */
442
443         memctl->memc_mbmr = SDRAM_MBMRVALUE0;   /* TLF 4 */
444         memctl->memc_mar = SDRAM_MARVALUE;  /* MRS code */
445
446         udelay(200);
447
448         /* Now run the precharge/nop/mrs commands.
449         */
450
451         memctl->memc_mcr = 0x80808111;   /* run umpb cs4 1 count 1, addr 0x11 ??? (50Mhz) */
452                                          /* run umpb cs4 1 count 1, addr 0x11 precharge+MRS (100Mhz) */
453         udelay(200);
454
455         /* Run 8 refresh cycles */
456
457         memctl->memc_mcr = SDRAM_MCRVALUE0; /* run upmb cs4 loop 1 addr 0x5 precharge+MRS (50 Mhz)*/
458                                             /* run upmb cs4 loop 1 addr 0x11 precharge+MRS (100MHz) */
459
460         udelay(200);
461
462         memctl->memc_mbmr = SDRAM_MBMRVALUE1; /* TLF 4 (100 Mhz) or TLF 8 (50MHz) */
463         memctl->memc_mcr = SDRAM_MCRVALUE1; /* run upmb cs4 loop 1 addr 0x30 refr (50 Mhz) */
464                                             /* run upmb cs4 loop 1 addr 0x11 precharge+MRS ??? (100MHz) */
465
466         udelay(200);
467
468         memctl->memc_mbmr = SDRAM_MBMRVALUE0;   /* TLF 4 */
469
470         memctl->memc_or4 = SDRAM_OR4VALUE | ~((noMbytes<<20)-1);
471         memctl->memc_br4 = SDRAM_BR4VALUE | base;
472
473         return 0;
474 }
475
476 /* ------------------------------------------------------------------------- */
477 #else  /* !SDRAM_ALT_INIT_SEQUENCE */
478 /* ------------------------------------------------------------------------- */
479
480 /* refresh rate 15.6 us (= 64 ms / 4K = 62.4 / quad bursts) for <= 128 MBit     */
481 # define MPTPR_2BK_4K        MPTPR_PTP_DIV16         /* setting for 2 banks  */
482 # define MPTPR_1BK_4K        MPTPR_PTP_DIV32         /* setting for 1 bank   */
483
484 /* refresh rate 7.8 us (= 64 ms / 8K = 31.2 / quad bursts) for 256 MBit         */
485 # define MPTPR_2BK_8K        MPTPR_PTP_DIV8          /* setting for 2 banks  */
486 # define MPTPR_1BK_8K        MPTPR_PTP_DIV16         /* setting for 1 bank   */
487
488 /*
489  * MxMR settings for SDRAM
490  */
491
492 /* 8 column SDRAM */
493 # define SDRAM_MxMR_8COL ((SDRAM_MxMR_PTx << MBMR_PTB_SHIFT)  | MBMR_PTBE  |   \
494                         MBMR_AMB_TYPE_0 | MBMR_DSB_1_CYCL | MBMR_G0CLB_A11 |   \
495                         MBMR_RLFB_1X    | MBMR_WLFB_1X    | MBMR_TLFB_4X)
496 /* 9 column SDRAM */
497 # define SDRAM_MxMR_9COL ((SDRAM_MxMR_PTx << MBMR_PTB_SHIFT)  | MBMR_PTAE  |   \
498                         MBMR_AMB_TYPE_1 | MBMR_DSB_1_CYCL | MBMR_G0CLB_A10 |   \
499                         MBMR_RLFB_1X    | MBMR_WLFB_1X    | MBMR_TLFB_4X)
500
501 static int _initsdram(uint base, uint noMbytes)
502 {
503         volatile immap_t     *immap = (immap_t *)CFG_IMMR;
504         volatile memctl8xx_t *memctl = &immap->im_memctl;
505
506         upmconfig(UPMB, (uint *)sdram_table,sizeof(sdram_table)/sizeof(uint));
507
508         memctl->memc_mptpr = MPTPR_2BK_4K;
509         memctl->memc_mbmr  = SDRAM_MxMR_8COL & (~(MBMR_PTBE)); /* no refresh yet */
510
511         /* map CS 4 */
512         memctl->memc_or4 = SDRAM_OR4VALUE | ~((noMbytes<<20)-1);
513         memctl->memc_br4 = SDRAM_BR4VALUE | base;
514
515         /* Perform SDRAM initilization */
516 # ifdef UPM_NOP_ADDR    /* not currently in UPM table */
517         /* step 1: nop */
518         memctl->memc_mar = 0x00000000;
519         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
520                            MCR_MLCF(0) | UPM_NOP_ADDR;
521 # endif
522
523         /* step 2: delay */
524         udelay(200);
525
526 # ifdef UPM_PRECHARGE_ADDR /* merged with MRS in UPM table */
527         /* step 3: precharge */
528         memctl->memc_mar = 0x00000000;
529         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
530                            MCR_MLCF(4) | UPM_PRECHARGE_ADDR;
531 # endif
532
533         /* step 4: refresh */
534         memctl->memc_mar = 0x00000000;
535         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
536                            MCR_MLCF(2) | UPM_REFRESH_ADDR;
537
538         /*
539          * note: for some reason, the UPM values we are using include
540          * precharge with MRS
541          */
542
543         /* step 5: mrs */
544         memctl->memc_mar = 0x00000088;
545         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
546                            MCR_MLCF(1) | UPM_MRS_ADDR;
547
548 # ifdef UPM_NOP_ADDR
549         memctl->memc_mar = 0x00000000;
550         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
551                            MCR_MLCF(0) | UPM_NOP_ADDR;
552 # endif
553         /*
554          * Enable refresh
555          */
556
557         memctl->memc_mbmr |= MBMR_PTBE;
558         return 0;
559 }
560 #endif  /* !SDRAM_ALT_INIT_SEQUENCE */
561
562 /* ------------------------------------------------------------------------- */
563
564 static void _sdramdisable(void)
565 {
566         volatile immap_t     *immap = (immap_t *)CFG_IMMR;
567         volatile memctl8xx_t *memctl = &immap->im_memctl;
568
569         memctl->memc_br4 = 0x00000000;
570
571         /* maybe we should turn off upmb here or something */
572 }
573
574 /* ------------------------------------------------------------------------- */
575
576 static int initsdram(uint base, uint *noMbytes)
577 {
578         uint m = CFG_SDRAM_SIZE>>20;
579
580         /* _initsdram needs access to sdram */
581         *((uint *)BCSR1) |= BCSR1_SDRAM_EN; /* enable sdram */
582
583         if(!_initsdram(base, m))
584         {
585                 *noMbytes += m;
586                 return 0;
587         }
588         else
589         {
590                 *((uint *)BCSR1) &= ~BCSR1_SDRAM_EN; /* disable sdram */
591
592                 _sdramdisable();
593
594                 return -1;
595         }
596 }
597
598 #endif /* CONFIG_FADS */
599
600 /* ========================================================================= */
601
602 long int initdram (int board_type)
603 {
604         uint sdramsz = 0;       /* size of sdram in Mbytes */
605         uint base = 0;          /* base of dram in bytes */
606         uint m = 0;             /* size of dram in Mbytes */
607 #ifndef CONFIG_DUET_ADS
608         uint k, s;
609 #endif
610
611 #ifdef CONFIG_FADS
612         if (!initsdram (0x00000000, &sdramsz)) {
613                 base = sdramsz << 20;
614                 printf ("(%u MB SDRAM) ", sdramsz);
615         }
616 #endif
617 #ifndef CONFIG_DUET_ADS /* No old DRAM on Duet */
618         k = (*((uint *) BCSR2) >> 23) & 0x0f;
619
620         switch (k & 0x3) {
621                 /* "MCM36100 / MT8D132X" */
622         case 0x00:
623                 m = 4;
624                 break;
625
626                 /* "MCM36800 / MT16D832X" */
627         case 0x01:
628                 m = 32;
629                 break;
630                 /* "MCM36400 / MT8D432X" */
631         case 0x02:
632                 m = 16;
633                 break;
634                 /* "MCM36200 / MT16D832X ?" */
635         case 0x03:
636                 m = 8;
637                 break;
638
639         }
640
641         switch (k >> 2) {
642         case 0x02:
643                 k = 70;
644                 break;
645
646         case 0x03:
647                 k = 60;
648                 break;
649
650         default:
651                 printf ("unknown dramdelay (0x%x) - defaulting to 70 ns", k);
652                 k = 70;
653         }
654
655 #ifdef CONFIG_FADS
656         /* the FADS is missing this bit, all rams treated as non-edo */
657         s = 0;
658 #else
659         s = (*((uint *) BCSR2) >> 27) & 0x01;
660 #endif
661
662         if (!_draminit (base, m, s, k)) {
663                 printf ("%dM %dns %sDRAM: ", m, k, s ? "EDO " : "");
664         } else {
665                 _dramdisable ();
666                 m = 0;
667         }
668 #endif /* !CONFIG_DUET_ADS */
669         m += sdramsz;                           /* add sdram size to total */
670
671         return (m << 20);
672 }
673
674 /* ------------------------------------------------------------------------- */
675
676 int testdram (void)
677 {
678     /* TODO: XXX XXX XXX */
679     printf ("test: 16 MB - ok\n");
680
681     return (0);
682 }
683
684 /* ========================================================================= */
685
686 /*
687  * Check Board Identity:
688  */
689
690 #if defined(CONFIG_FADS) && defined(CFG_DAUGHTERBOARD)
691 static void checkdboard(void)
692 {
693         /* get db type from BCSR 3 */
694         uint k = (*((uint *)BCSR3) >> 24) & 0x3f;
695
696         puts (" with db ");
697
698         switch(k) {
699         case 0x03 :
700                 puts ("MPC823");
701                 break;
702         case 0x20 :
703                 puts ("MPC801");
704                 break;
705         case 0x21 :
706                 puts ("MPC850");
707                 break;
708         case 0x22 :
709                 puts ("MPC821, MPC860 / MPC860SAR / MPC860T");
710                 break;
711         case 0x23 :
712                 puts ("MPC860SAR");
713                 break;
714         case 0x24 :
715         case 0x2A :
716                 puts ("MPC860T");
717                 break;
718         case 0x3F :
719                 puts ("MPC850SAR");
720                 break;
721         default : printf("0x%x", k);
722         }
723 }
724 #endif  /* defined(CONFIG_FADS) && defined(CFG_DAUGHTERBOARD) */
725
726 int checkboard (void)
727 {
728         /* get revision from BCSR 3 */
729         uint r =  (((*((uint *) BCSR3) >> 23) & 1) << 3)
730                 | (((*((uint *) BCSR3) >> 19) & 1) << 2)
731                 | (((*((uint *) BCSR3) >> 16) & 3));
732
733         puts ("Board: ");
734
735 #if defined(CONFIG_MPC86xADS)
736         puts ("MPC86xADS");
737 #elif defined(CONFIG_DUET_ADS)
738         puts ("DUET ADS");
739         r = 0; /* I've got NR (No Revision) board */
740 #elif defined(CONFIG_FADS)
741         puts ("FADS");
742         checkdboard ();
743 #else
744         puts ("ADS");
745 #endif
746         puts (" rev ");
747
748         switch (r) {
749 #if defined(CONFIG_ADS)
750         case 0x00:
751                 puts ("ENG - this board sucks, check the errata, not supported\n");
752                 return -1;
753         case 0x01:
754                 puts ("PILOT - warning, read errata \n");
755                 break;
756         case 0x02:
757                 puts ("A - warning, read errata \n");
758                 break;
759         case 0x03:
760                 puts ("B \n");
761                 break;
762 #elif defined(CONFIG_DUET_ADS)
763         case 0x00:
764                 puts ("NR\n");
765                 break;
766 #else  /* FADS and newer */
767         case 0x00:
768                 puts ("ENG\n");
769                 break;
770         case 0x01:
771                 puts ("PILOT\n");
772                 break;
773 #endif /* CONFIG_ADS */
774         default:
775                 printf ("unknown (0x%x)\n", r);
776                 return -1;
777         }
778
779         return 0;
780 }
781
782 /* ========================================================================= */
783
784 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
785
786 #ifdef CFG_PCMCIA_MEM_ADDR
787 volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR;
788 #endif
789
790 int pcmcia_init(void)
791 {
792         volatile pcmconf8xx_t   *pcmp;
793         uint v, slota, slotb;
794
795         /*
796         ** Enable the PCMCIA for a Flash card.
797         */
798         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
799
800 #if 0
801         pcmp->pcmc_pbr0 = CFG_PCMCIA_MEM_ADDR;
802         pcmp->pcmc_por0 = 0xc00ff05d;
803 #endif
804
805         /* Set all slots to zero by default. */
806         pcmp->pcmc_pgcra = 0;
807         pcmp->pcmc_pgcrb = 0;
808 #ifdef PCMCIA_SLOT_A
809         pcmp->pcmc_pgcra = 0x40;
810 #endif
811 #ifdef PCMCIA_SLOT_B
812         pcmp->pcmc_pgcrb = 0x40;
813 #endif
814
815         /* enable PCMCIA buffers */
816         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
817
818         /* Check if any PCMCIA card is plugged in. */
819
820         slota = (pcmp->pcmc_pipr & 0x18000000) == 0 ;
821         slotb = (pcmp->pcmc_pipr & 0x00001800) == 0 ;
822
823         if (!(slota || slotb)) {
824                 printf("No card present\n");
825 #ifdef PCMCIA_SLOT_A
826                 pcmp->pcmc_pgcra = 0;
827 #endif
828 #ifdef PCMCIA_SLOT_B
829                 pcmp->pcmc_pgcrb = 0;
830 #endif
831                 return -1;
832         }
833         else
834                 printf("Card present (");
835
836         v = 0;
837
838         /* both the ADS and the FADS have a 5V keyed pcmcia connector (?)
839         **
840         ** Paolo - Yes, but i have to insert some 3.3V card in that slot on
841         **         my FADS... :-)
842         */
843
844 #if defined(CONFIG_MPC86x)
845         switch ((pcmp->pcmc_pipr >> 30) & 3)
846 #elif defined(CONFIG_MPC823) || defined(CONFIG_MPC850)
847         switch ((pcmp->pcmc_pipr >> 14) & 3)
848 #endif
849         {
850         case 0x00 :
851                 printf("5V");
852                 v = 5;
853                 break;
854         case 0x01 :
855                 printf("5V and 3V");
856 #ifdef CONFIG_FADS
857                 v = 3; /* User lower voltage if supported! */
858 #else
859                 v = 5;
860 #endif
861                 break;
862         case 0x03 :
863                 printf("5V, 3V and x.xV");
864 #ifdef CONFIG_FADS
865                 v = 3; /* User lower voltage if supported! */
866 #else
867                 v = 5;
868 #endif
869                 break;
870         }
871
872         switch (v) {
873 #ifdef CONFIG_FADS
874         case 3:
875                 printf("; using 3V");
876                 /*
877                 ** Enable 3 volt Vcc.
878                 */
879                 *((uint *)BCSR1) &= ~BCSR1_PCCVCC1;
880                 *((uint *)BCSR1) |= BCSR1_PCCVCC0;
881                 break;
882 #endif
883         case 5:
884                 printf("; using 5V");
885 #ifdef CONFIG_ADS
886                 /*
887                 ** Enable 5 volt Vcc.
888                 */
889                 *((uint *)BCSR1) &= ~BCSR1_PCCVCCON;
890 #endif
891 #ifdef CONFIG_FADS
892                 /*
893                 ** Enable 5 volt Vcc.
894                 */
895                 *((uint *)BCSR1) &= ~BCSR1_PCCVCC0;
896                 *((uint *)BCSR1) |= BCSR1_PCCVCC1;
897 #endif
898                 break;
899
900         default:
901                 *((uint *)BCSR1) |= BCSR1_PCCEN;  /* disable pcmcia */
902
903                 printf("; unknown voltage");
904                 return -1;
905         }
906         printf(")\n");
907         /* disable pcmcia reset after a while */
908
909         udelay(20);
910
911 #ifdef PCMCIA_SLOT_A
912         pcmp->pcmc_pgcra = 0;
913 #elif PCMCIA_SLOT_B
914         pcmp->pcmc_pgcrb = 0;
915 #endif
916
917         /* If you using a real hd you should give a short
918         * spin-up time. */
919 #ifdef CONFIG_DISK_SPINUP_TIME
920         udelay(CONFIG_DISK_SPINUP_TIME);
921 #endif
922
923         return 0;
924 }
925
926 #endif  /* CFG_CMD_PCMCIA */
927
928 /* ========================================================================= */
929
930 #ifdef CFG_PC_IDE_RESET
931
932 void ide_set_reset(int on)
933 {
934         volatile immap_t *immr = (immap_t *)CFG_IMMR;
935
936         /*
937          * Configure PC for IDE Reset Pin
938          */
939         if (on) {               /* assert RESET */
940                 immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET);
941         } else {                /* release RESET */
942                 immr->im_ioport.iop_pcdat |=   CFG_PC_IDE_RESET;
943         }
944
945         /* program port pin as GPIO output */
946         immr->im_ioport.iop_pcpar &= ~(CFG_PC_IDE_RESET);
947         immr->im_ioport.iop_pcso  &= ~(CFG_PC_IDE_RESET);
948         immr->im_ioport.iop_pcdir |=   CFG_PC_IDE_RESET;
949 }
950
951 #endif  /* CFG_PC_IDE_RESET */