* Fix problems caused by Robert Schwebel's cramfs patch
[kernel/u-boot.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 long int dram_size (long int *base, long int maxsize)
191 {
192         volatile long int *addr=base;
193         ulong cnt, val;
194         ulong save[32];                         /* to make test non-destructive */
195         unsigned char i = 0;
196
197         for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
198                 addr = base + cnt;              /* pointer arith! */
199
200                 save[i++] = *addr;
201                 *addr = ~cnt;
202         }
203
204         /* write 0 to base address */
205         addr = base;
206         save[i] = *addr;
207         *addr = 0;
208
209         /* check at base address */
210         if ((val = *addr) != 0) {
211                 *addr = save[i];
212                 return (0);
213         }
214
215         for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
216                 addr = base + cnt;              /* pointer arith! */
217
218                 val = *addr;
219                 *addr = save[--i];
220
221                 if (val != (~cnt)) {
222                         return (cnt * sizeof (long));
223                 }
224         }
225         return (maxsize);
226 }
227
228 /* ------------------------------------------------------------------------- */
229 static int _draminit (uint base, uint noMbytes, uint edo, uint delay)
230 {
231         volatile immap_t *immap = (immap_t *) CFG_IMMR;
232         volatile memctl8xx_t *memctl = &immap->im_memctl;
233
234         /* init upm */
235
236         switch (delay) {
237         case 70:
238                 if (edo) {
239                         upmconfig (UPMA, (uint *) edo_70ns,
240                                    sizeof (edo_70ns) / sizeof (uint));
241                 } else {
242                         upmconfig (UPMA, (uint *) dram_70ns,
243                                    sizeof (dram_70ns) / sizeof (uint));
244                 }
245
246                 break;
247
248         case 60:
249                 if (edo) {
250                         upmconfig (UPMA, (uint *) edo_60ns,
251                                    sizeof (edo_60ns) / sizeof (uint));
252                 } else {
253                         upmconfig (UPMA, (uint *) dram_60ns,
254                                    sizeof (dram_60ns) / sizeof (uint));
255                 }
256
257                 break;
258
259         default:
260                 return -1;
261         }
262
263         memctl->memc_mptpr = 0x0400;    /* divide by 16 */
264
265         switch (noMbytes) {
266         case 4:                         /* 4 Mbyte uses only CS2 */
267 #ifdef CONFIG_ADS
268                 memctl->memc_mamr = 0xc0a21114;
269 #else
270                 memctl->memc_mamr = 0x13a01114; /* PTA 0x13 AMA 010 */
271 #endif
272                 memctl->memc_or2 = 0xffc00800;  /* 4M */
273                 break;
274
275         case 8:                         /* 8 Mbyte uses both CS3 and CS2 */
276                 memctl->memc_mamr = 0x13a01114; /* PTA 0x13 AMA 010 */
277                 memctl->memc_or3 = 0xffc00800;  /* 4M */
278                 memctl->memc_br3 = 0x00400081 + base;
279                 memctl->memc_or2 = 0xffc00800;  /* 4M */
280                 break;
281
282         case 16:                        /* 16 Mbyte uses only CS2 */
283 #ifdef CONFIG_ADS       /* XXX: why PTA=0x60 only in 16M case? - NTL */
284                 memctl->memc_mamr = 0x60b21114; /* PTA 0x60 AMA 011 */
285 #else
286                 memctl->memc_mamr = 0x13b01114; /* PTA 0x13 AMA 011 */
287 #endif
288                 memctl->memc_or2 = 0xff000800;  /* 16M */
289                 break;
290
291         case 32:                        /* 32 Mbyte uses both CS3 and CS2 */
292                 memctl->memc_mamr = 0x13b01114; /* PTA 0x13 AMA 011 */
293                 memctl->memc_or3 = 0xff000800;  /* 16M */
294                 memctl->memc_br3 = 0x01000081 + base;
295                 memctl->memc_or2 = 0xff000800;  /* 16M */
296                 break;
297
298         default:
299                 return -1;
300         }
301
302         memctl->memc_br2 = 0x81 + base; /* use upma */
303
304         *((uint *) BCSR1) &= ~BCSR1_DRAM_EN;    /* enable dram */
305
306         /* if no dimm is inserted, noMbytes is still detected as 8m, so
307          * sanity check top and bottom of memory */
308
309         /* check bytes / 2 because dram_size tests at base+bytes, which
310          * is not mapped */
311         if (noMbytes == 8)
312                 if (dram_size ((long *) base, noMbytes << 19) != noMbytes << 19) {
313                         *((uint *) BCSR1) |= BCSR1_DRAM_EN;     /* disable dram */
314                         return -1;
315                 }
316
317         return 0;
318 }
319
320 /* ------------------------------------------------------------------------- */
321
322 static void _dramdisable(void)
323 {
324         volatile immap_t     *immap = (immap_t *)CFG_IMMR;
325         volatile memctl8xx_t *memctl = &immap->im_memctl;
326
327         memctl->memc_br2 = 0x00000000;
328         memctl->memc_br3 = 0x00000000;
329
330         /* maybe we should turn off upma here or something */
331 }
332 #endif /* !CONFIG_DUET_ADS */
333
334 /* ========================================================================= */
335
336 #ifdef CONFIG_FADS /* SDRAM exists on FADS and newer boards */
337
338 #if defined(CONFIG_SDRAM_100MHZ)
339
340 /* ------------------------------------------------------------------------- */
341 /* sdram table by Dan Malek                                                  */
342
343 /* This has the stretched early timing so the 50 MHz
344  * processor can make the 100 MHz timing.  This will
345  * work at all processor speeds.
346  */
347
348 #ifdef SDRAM_ALT_INIT_SEQENCE
349 # define SDRAM_MBMRVALUE0 0xc3802114 /* PTx=195,PTxE,AMx=0,DSx=1,A11,RLFx=1,WLFx=1,TLFx=4 */
350 #define SDRAM_MBMRVALUE1 SDRAM_MBMRVALUE0
351 # define SDRAM_MCRVALUE0  0x80808111   /* run upmb cs4 loop 1 addr 0x11 MRS */
352 # define SDRAM_MCRVALUE1  SDRAM_MCRVALUE0  /* ??? why not 0x80808130? */
353 #else
354 # define SDRAM_MxMR_PTx         195
355 # define UPM_MRS_ADDR           0x11
356 # define UPM_REFRESH_ADDR       0x30    /* or 0x11 if we want to be like above? */
357 #endif /* !SDRAM_ALT_INIT_SEQUENCE */
358
359 static const uint sdram_table[] =
360 {
361         /* single read. (offset 0 in upm RAM) */
362         0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x11adfc04,
363         0xefbbbc00, 0x1ff77c45, _NOT_USED_, _NOT_USED_,
364
365         /* burst read. (offset 8 in upm RAM) */
366         0xefebfc24, 0x1f07fc24, 0xeeaefc04, 0x10adfc04,
367         0xf0affc00, 0xf0affc00, 0xf1affc00, 0xefbbbc00,
368         0x1ff77c45,
369
370         /* precharge + MRS. (offset 11 in upm RAM) */
371         0xeffbbc04, 0x1ff77c34, 0xefeabc34,
372         0x1fb57c35, _NOT_USED_, _NOT_USED_, _NOT_USED_,
373
374         /* single write. (offset 18 in upm RAM) */
375         0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x01b93c04,
376         0x1ff77c45, _NOT_USED_, _NOT_USED_, _NOT_USED_,
377
378         /* burst write. (offset 20 in upm RAM) */
379         0xefebfc24, 0x1f07fc24, 0xeeaebc00, 0x10ad7c00,
380         0xf0affc00, 0xf0affc00, 0xe1bbbc04, 0x1ff77c45,
381         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
382         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
383
384         /* refresh. (offset 30 in upm RAM) */
385         0xeffafc84, 0x1ff5fc04, 0xfffffc04, 0xfffffc04,
386         0xfffffc84, 0xfffffc07, _NOT_USED_, _NOT_USED_,
387         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
388
389         /* exception. (offset 3c in upm RAM) */
390         0xeffffc06, 0x1ffffc07, _NOT_USED_, _NOT_USED_ };
391
392 #elif defined(CONFIG_SDRAM_50MHZ)
393
394 /* ------------------------------------------------------------------------- */
395 /* sdram table stolen from the fads manual                                   */
396 /* for chip MB811171622A-100                                                 */
397
398 /* this table is for 32-50MHz operation */
399 #ifdef SDRAM_ALT_INIT_SEQENCE
400 # define SDRAM_MBMRVALUE0 0x80802114   /* PTx=128,PTxE,AMx=0,DSx=1,A11,RLFx=1,WLFx=1,TLFx=4 */
401 # define SDRAM_MBMRVALUE1 0x80802118   /* PTx=128,PTxE,AMx=0,DSx=1,A11,RLFx=1,WLFx=1,TLFx=8 */
402 # define SDRAM_MCRVALUE0  0x80808105   /* run upmb cs4 loop 1 addr 0x5 MRS */
403 # define SDRAM_MCRVALUE1  0x80808130   /* run upmb cs4 loop 1 addr 0x30 REFRESH */
404 # define SDRAM_MPTRVALUE  0x400
405 #define SDRAM_MARVALUE   0x88
406 #else
407 # define SDRAM_MxMR_PTx         128
408 # define UPM_MRS_ADDR           0x5
409 # define UPM_REFRESH_ADDR       0x30
410 #endif  /* !SDRAM_ALT_INIT_SEQUENCE */
411
412 static const uint sdram_table[] =
413 {
414         /* single read. (offset 0 in upm RAM) */
415         0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
416         0x1ff77c47,
417
418         /* precharge + MRS. (offset 5 in upm RAM) */
419         0x1ff77c34, 0xefeabc34, 0x1fb57c35,
420
421         /* burst read. (offset 8 in upm RAM) */
422         0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
423         0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
424         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
425         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
426
427         /* single write. (offset 18 in upm RAM) */
428         0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
429         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
430
431         /* burst write. (offset 20 in upm RAM) */
432         0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
433         0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _NOT_USED_,
434         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
435         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
436
437         /* refresh. (offset 30 in upm RAM) */
438         0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
439         0xfffffc84, 0xfffffc07, _NOT_USED_, _NOT_USED_,
440         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
441
442         /* exception. (offset 3c in upm RAM) */
443         0x7ffffc07, _NOT_USED_, _NOT_USED_, _NOT_USED_ };
444
445 /* ------------------------------------------------------------------------- */
446 #else
447 #error SDRAM not correctly configured
448 #endif
449 /* ------------------------------------------------------------------------- */
450
451 /*
452  * Memory Periodic Timer Prescaler
453  */
454
455 #define SDRAM_OR4VALUE   0x00000a00 /* SAM,GL5A/S=01,addr mask or'ed on later */
456 #define SDRAM_BR4VALUE   0x000000c1 /* UPMB,base addr or'ed on later */
457
458 /* ------------------------------------------------------------------------- */
459 #ifdef SDRAM_ALT_INIT_SEQENCE
460 /* ------------------------------------------------------------------------- */
461
462 static int _initsdram(uint base, uint noMbytes)
463 {
464         volatile immap_t     *immap = (immap_t *)CFG_IMMR;
465         volatile memctl8xx_t *memctl = &immap->im_memctl;
466
467         upmconfig(UPMB, (uint *)sdram_table,sizeof(sdram_table)/sizeof(uint));
468
469         memctl->memc_mptpr = SDRAM_MPTPRVALUE;
470
471         /* Configure the refresh (mostly).  This needs to be
472         * based upon processor clock speed and optimized to provide
473         * the highest level of performance.  For multiple banks,
474         * this time has to be divided by the number of banks.
475         * Although it is not clear anywhere, it appears the
476         * refresh steps through the chip selects for this UPM
477         * on each refresh cycle.
478         * We have to be careful changing
479         * UPM registers after we ask it to run these commands.
480         */
481
482         memctl->memc_mbmr = SDRAM_MBMRVALUE0;   /* TLF 4 */
483         memctl->memc_mar = SDRAM_MARVALUE;  /* MRS code */
484
485         udelay(200);
486
487         /* Now run the precharge/nop/mrs commands.
488         */
489
490         memctl->memc_mcr = 0x80808111;   /* run umpb cs4 1 count 1, addr 0x11 ??? (50Mhz) */
491                                          /* run umpb cs4 1 count 1, addr 0x11 precharge+MRS (100Mhz) */
492         udelay(200);
493
494         /* Run 8 refresh cycles */
495
496         memctl->memc_mcr = SDRAM_MCRVALUE0; /* run upmb cs4 loop 1 addr 0x5 precharge+MRS (50 Mhz)*/
497                                             /* run upmb cs4 loop 1 addr 0x11 precharge+MRS (100MHz) */
498
499         udelay(200);
500
501         memctl->memc_mbmr = SDRAM_MBMRVALUE1; /* TLF 4 (100 Mhz) or TLF 8 (50MHz) */
502         memctl->memc_mcr = SDRAM_MCRVALUE1; /* run upmb cs4 loop 1 addr 0x30 refr (50 Mhz) */
503                                             /* run upmb cs4 loop 1 addr 0x11 precharge+MRS ??? (100MHz) */
504
505         udelay(200);
506
507         memctl->memc_mbmr = SDRAM_MBMRVALUE0;   /* TLF 4 */
508
509         memctl->memc_or4 = SDRAM_OR4VALUE | ~((noMbytes<<20)-1);
510         memctl->memc_br4 = SDRAM_BR4VALUE | base;
511
512         return 0;
513 }
514
515 /* ------------------------------------------------------------------------- */
516 #else  /* !SDRAM_ALT_INIT_SEQUENCE */
517 /* ------------------------------------------------------------------------- */
518
519 /* refresh rate 15.6 us (= 64 ms / 4K = 62.4 / quad bursts) for <= 128 MBit     */
520 # define MPTPR_2BK_4K        MPTPR_PTP_DIV16         /* setting for 2 banks  */
521 # define MPTPR_1BK_4K        MPTPR_PTP_DIV32         /* setting for 1 bank   */
522
523 /* refresh rate 7.8 us (= 64 ms / 8K = 31.2 / quad bursts) for 256 MBit         */
524 # define MPTPR_2BK_8K        MPTPR_PTP_DIV8          /* setting for 2 banks  */
525 # define MPTPR_1BK_8K        MPTPR_PTP_DIV16         /* setting for 1 bank   */
526
527 /*
528  * MxMR settings for SDRAM
529  */
530
531 /* 8 column SDRAM */
532 # define SDRAM_MxMR_8COL ((SDRAM_MxMR_PTx << MBMR_PTB_SHIFT)  | MBMR_PTBE  |   \
533                         MBMR_AMB_TYPE_0 | MBMR_DSB_1_CYCL | MBMR_G0CLB_A11 |   \
534                         MBMR_RLFB_1X    | MBMR_WLFB_1X    | MBMR_TLFB_4X)
535 /* 9 column SDRAM */
536 # define SDRAM_MxMR_9COL ((SDRAM_MxMR_PTx << MBMR_PTB_SHIFT)  | MBMR_PTAE  |   \
537                         MBMR_AMB_TYPE_1 | MBMR_DSB_1_CYCL | MBMR_G0CLB_A10 |   \
538                         MBMR_RLFB_1X    | MBMR_WLFB_1X    | MBMR_TLFB_4X)
539
540 static int _initsdram(uint base, uint noMbytes)
541 {
542         volatile immap_t     *immap = (immap_t *)CFG_IMMR;
543         volatile memctl8xx_t *memctl = &immap->im_memctl;
544
545         upmconfig(UPMB, (uint *)sdram_table,sizeof(sdram_table)/sizeof(uint));
546
547         memctl->memc_mptpr = MPTPR_2BK_4K;
548         memctl->memc_mbmr  = SDRAM_MxMR_8COL & (~(MBMR_PTBE)); /* no refresh yet */
549
550         /* map CS 4 */
551         memctl->memc_or4 = SDRAM_OR4VALUE | ~((noMbytes<<20)-1);
552         memctl->memc_br4 = SDRAM_BR4VALUE | base;
553
554         /* Perform SDRAM initilization */
555 # ifdef UPM_NOP_ADDR    /* not currently in UPM table */
556         /* step 1: nop */
557         memctl->memc_mar = 0x00000000;
558         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
559                            MCR_MLCF(0) | UPM_NOP_ADDR;
560 # endif
561
562         /* step 2: delay */
563         udelay(200);
564
565 # ifdef UPM_PRECHARGE_ADDR /* merged with MRS in UPM table */
566         /* step 3: precharge */
567         memctl->memc_mar = 0x00000000;
568         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
569                            MCR_MLCF(4) | UPM_PRECHARGE_ADDR;
570 # endif
571
572         /* step 4: refresh */
573         memctl->memc_mar = 0x00000000;
574         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
575                            MCR_MLCF(2) | UPM_REFRESH_ADDR;
576
577         /*
578          * note: for some reason, the UPM values we are using include
579          * precharge with MRS
580          */
581
582         /* step 5: mrs */
583         memctl->memc_mar = 0x00000088;
584         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
585                            MCR_MLCF(1) | UPM_MRS_ADDR;
586
587 # ifdef UPM_NOP_ADDR
588         memctl->memc_mar = 0x00000000;
589         memctl->memc_mcr = MCR_UPM_B | MCR_OP_RUN | MCR_MB_CS4 |
590                            MCR_MLCF(0) | UPM_NOP_ADDR;
591 # endif
592         /*
593          * Enable refresh
594          */
595
596         memctl->memc_mbmr |= MBMR_PTBE;
597         return 0;
598 }
599 #endif  /* !SDRAM_ALT_INIT_SEQUENCE */
600
601 /* ------------------------------------------------------------------------- */
602
603 static void _sdramdisable(void)
604 {
605         volatile immap_t     *immap = (immap_t *)CFG_IMMR;
606         volatile memctl8xx_t *memctl = &immap->im_memctl;
607
608         memctl->memc_br4 = 0x00000000;
609
610         /* maybe we should turn off upmb here or something */
611 }
612
613 /* ------------------------------------------------------------------------- */
614
615 static int initsdram(uint base, uint *noMbytes)
616 {
617         uint m = CFG_SDRAM_SIZE>>20;
618
619         /* _initsdram needs access to sdram */
620         *((uint *)BCSR1) |= BCSR1_SDRAM_EN; /* enable sdram */
621
622         if(!_initsdram(base, m))
623         {
624                 *noMbytes += m;
625                 return 0;
626         }
627         else
628         {
629                 *((uint *)BCSR1) &= ~BCSR1_SDRAM_EN; /* disable sdram */
630
631                 _sdramdisable();
632
633                 return -1;
634         }
635 }
636
637 #endif /* CONFIG_FADS */
638
639 /* ========================================================================= */
640
641 long int initdram (int board_type)
642 {
643         uint sdramsz = 0;       /* size of sdram in Mbytes */
644         uint base = 0;          /* base of dram in bytes */
645         uint m = 0;             /* size of dram in Mbytes */
646 #ifndef CONFIG_DUET_ADS
647         uint k, s;
648 #endif
649
650 #ifdef CONFIG_FADS
651         if (!initsdram (0x00000000, &sdramsz)) {
652                 base = sdramsz << 20;
653                 printf ("(%u MB SDRAM) ", sdramsz);
654         }
655 #endif
656 #ifndef CONFIG_DUET_ADS /* No old DRAM on Duet */
657         k = (*((uint *) BCSR2) >> 23) & 0x0f;
658
659         switch (k & 0x3) {
660                 /* "MCM36100 / MT8D132X" */
661         case 0x00:
662                 m = 4;
663                 break;
664
665                 /* "MCM36800 / MT16D832X" */
666         case 0x01:
667                 m = 32;
668                 break;
669                 /* "MCM36400 / MT8D432X" */
670         case 0x02:
671                 m = 16;
672                 break;
673                 /* "MCM36200 / MT16D832X ?" */
674         case 0x03:
675                 m = 8;
676                 break;
677
678         }
679
680         switch (k >> 2) {
681         case 0x02:
682                 k = 70;
683                 break;
684
685         case 0x03:
686                 k = 60;
687                 break;
688
689         default:
690                 printf ("unknown dramdelay (0x%x) - defaulting to 70 ns", k);
691                 k = 70;
692         }
693
694 #ifdef CONFIG_FADS
695         /* the FADS is missing this bit, all rams treated as non-edo */
696         s = 0;
697 #else
698         s = (*((uint *) BCSR2) >> 27) & 0x01;
699 #endif
700
701         if (!_draminit (base, m, s, k)) {
702                 printf ("%dM %dns %sDRAM: ", m, k, s ? "EDO " : "");
703         } else {
704                 _dramdisable ();
705                 m = 0;
706         }
707 #endif /* !CONFIG_DUET_ADS */
708         m += sdramsz;                           /* add sdram size to total */
709
710         return (m << 20);
711 }
712
713 /* ------------------------------------------------------------------------- */
714
715 int testdram (void)
716 {
717     /* TODO: XXX XXX XXX */
718     printf ("test: 16 MB - ok\n");
719
720     return (0);
721 }
722
723 /* ========================================================================= */
724
725 /*
726  * Check Board Identity:
727  */
728
729 #if defined(CONFIG_FADS) && defined(CFG_DAUGHTERBOARD)
730 static void checkdboard(void)
731 {
732         /* get db type from BCSR 3 */
733         uint k = (*((uint *)BCSR3) >> 24) & 0x3f;
734
735         puts (" with db ");
736
737         switch(k) {
738         case 0x03 :
739                 puts ("MPC823");
740                 break;
741         case 0x20 :
742                 puts ("MPC801");
743                 break;
744         case 0x21 :
745                 puts ("MPC850");
746                 break;
747         case 0x22 :
748                 puts ("MPC821, MPC860 / MPC860SAR / MPC860T");
749                 break;
750         case 0x23 :
751                 puts ("MPC860SAR");
752                 break;
753         case 0x24 :
754         case 0x2A :
755                 puts ("MPC860T");
756                 break;
757         case 0x3F :
758                 puts ("MPC850SAR");
759                 break;
760         default : printf("0x%x", k);
761         }
762 }
763 #endif  /* defined(CONFIG_FADS) && defined(CFG_DAUGHTERBOARD) */
764
765 int checkboard (void)
766 {
767         /* get revision from BCSR 3 */
768         uint r =  (((*((uint *) BCSR3) >> 23) & 1) << 3)
769                 | (((*((uint *) BCSR3) >> 19) & 1) << 2)
770                 | (((*((uint *) BCSR3) >> 16) & 3));
771
772         puts ("Board: ");
773
774 #if defined(CONFIG_MPC86xADS)
775         puts ("MPC86xADS");
776 #elif defined(CONFIG_DUET_ADS)
777         puts ("DUET ADS");
778         r = 0; /* I've got NR (No Revision) board */
779 #elif defined(CONFIG_FADS)
780         puts ("FADS");
781         checkdboard ();
782 #else
783         puts ("ADS");
784 #endif
785         puts (" rev ");
786
787         switch (r) {
788 #if defined(CONFIG_ADS)
789         case 0x00:
790                 puts ("ENG - this board sucks, check the errata, not supported\n");
791                 return -1;
792         case 0x01:
793                 puts ("PILOT - warning, read errata \n");
794                 break;
795         case 0x02:
796                 puts ("A - warning, read errata \n");
797                 break;
798         case 0x03:
799                 puts ("B \n");
800                 break;
801 #elif defined(CONFIG_DUET_ADS)
802         case 0x00:
803                 puts ("NR\n");
804                 break;
805 #else  /* FADS and newer */
806         case 0x00:
807                 puts ("ENG\n");
808                 break;
809         case 0x01:
810                 puts ("PILOT\n");
811                 break;
812 #endif /* CONFIG_ADS */
813         default:
814                 printf ("unknown (0x%x)\n", r);
815                 return -1;
816         }
817
818         return 0;
819 }
820
821 /* ========================================================================= */
822
823 #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
824
825 #ifdef CFG_PCMCIA_MEM_ADDR
826 volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR;
827 #endif
828
829 int pcmcia_init(void)
830 {
831         volatile pcmconf8xx_t   *pcmp;
832         uint v, slota, slotb;
833
834         /*
835         ** Enable the PCMCIA for a Flash card.
836         */
837         pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia));
838
839 #if 0
840         pcmp->pcmc_pbr0 = CFG_PCMCIA_MEM_ADDR;
841         pcmp->pcmc_por0 = 0xc00ff05d;
842 #endif
843
844         /* Set all slots to zero by default. */
845         pcmp->pcmc_pgcra = 0;
846         pcmp->pcmc_pgcrb = 0;
847 #ifdef PCMCIA_SLOT_A
848         pcmp->pcmc_pgcra = 0x40;
849 #endif
850 #ifdef PCMCIA_SLOT_B
851         pcmp->pcmc_pgcrb = 0x40;
852 #endif
853
854         /* enable PCMCIA buffers */
855         *((uint *)BCSR1) &= ~BCSR1_PCCEN;
856
857         /* Check if any PCMCIA card is plugged in. */
858
859         slota = (pcmp->pcmc_pipr & 0x18000000) == 0 ;
860         slotb = (pcmp->pcmc_pipr & 0x00001800) == 0 ;
861
862         if (!(slota || slotb)) {
863                 printf("No card present\n");
864 #ifdef PCMCIA_SLOT_A
865                 pcmp->pcmc_pgcra = 0;
866 #endif
867 #ifdef PCMCIA_SLOT_B
868                 pcmp->pcmc_pgcrb = 0;
869 #endif
870                 return -1;
871         }
872         else
873                 printf("Card present (");
874
875         v = 0;
876
877         /* both the ADS and the FADS have a 5V keyed pcmcia connector (?)
878         **
879         ** Paolo - Yes, but i have to insert some 3.3V card in that slot on
880         **         my FADS... :-)
881         */
882
883 #if defined(CONFIG_MPC86x)
884         switch ((pcmp->pcmc_pipr >> 30) & 3)
885 #elif defined(CONFIG_MPC823) || defined(CONFIG_MPC850)
886         switch ((pcmp->pcmc_pipr >> 14) & 3)
887 #endif
888         {
889         case 0x00 :
890                 printf("5V");
891                 v = 5;
892                 break;
893         case 0x01 :
894                 printf("5V and 3V");
895 #ifdef CONFIG_FADS
896                 v = 3; /* User lower voltage if supported! */
897 #else
898                 v = 5;
899 #endif
900                 break;
901         case 0x03 :
902                 printf("5V, 3V and x.xV");
903 #ifdef CONFIG_FADS
904                 v = 3; /* User lower voltage if supported! */
905 #else
906                 v = 5;
907 #endif
908                 break;
909         }
910
911         switch (v) {
912 #ifdef CONFIG_FADS
913         case 3:
914                 printf("; using 3V");
915                 /*
916                 ** Enable 3 volt Vcc.
917                 */
918                 *((uint *)BCSR1) &= ~BCSR1_PCCVCC1;
919                 *((uint *)BCSR1) |= BCSR1_PCCVCC0;
920                 break;
921 #endif
922         case 5:
923                 printf("; using 5V");
924 #ifdef CONFIG_ADS
925                 /*
926                 ** Enable 5 volt Vcc.
927                 */
928                 *((uint *)BCSR1) &= ~BCSR1_PCCVCCON;
929 #endif
930 #ifdef CONFIG_FADS
931                 /*
932                 ** Enable 5 volt Vcc.
933                 */
934                 *((uint *)BCSR1) &= ~BCSR1_PCCVCC0;
935                 *((uint *)BCSR1) |= BCSR1_PCCVCC1;
936 #endif
937                 break;
938
939         default:
940                 *((uint *)BCSR1) |= BCSR1_PCCEN;  /* disable pcmcia */
941
942                 printf("; unknown voltage");
943                 return -1;
944         }
945         printf(")\n");
946         /* disable pcmcia reset after a while */
947
948         udelay(20);
949
950 #ifdef PCMCIA_SLOT_A
951         pcmp->pcmc_pgcra = 0;
952 #elif PCMCIA_SLOT_B
953         pcmp->pcmc_pgcrb = 0;
954 #endif
955
956         /* If you using a real hd you should give a short
957         * spin-up time. */
958 #ifdef CONFIG_DISK_SPINUP_TIME
959         udelay(CONFIG_DISK_SPINUP_TIME);
960 #endif
961
962         return 0;
963 }
964
965 #endif  /* CFG_CMD_PCMCIA */
966
967 /* ========================================================================= */
968
969 #ifdef CFG_PC_IDE_RESET
970
971 void ide_set_reset(int on)
972 {
973         volatile immap_t *immr = (immap_t *)CFG_IMMR;
974
975         /*
976          * Configure PC for IDE Reset Pin
977          */
978         if (on) {               /* assert RESET */
979                 immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET);
980         } else {                /* release RESET */
981                 immr->im_ioport.iop_pcdat |=   CFG_PC_IDE_RESET;
982         }
983
984         /* program port pin as GPIO output */
985         immr->im_ioport.iop_pcpar &= ~(CFG_PC_IDE_RESET);
986         immr->im_ioport.iop_pcso  &= ~(CFG_PC_IDE_RESET);
987         immr->im_ioport.iop_pcdir |=   CFG_PC_IDE_RESET;
988 }
989
990 #endif  /* CFG_PC_IDE_RESET */