Merge branch 'elf_reloc'
[platform/kernel/u-boot.git] / board / sixnet / sixnet.c
1 /*
2  * (C) Copyright 2001, 2002
3  * Dave Ellis, SIXNET, dge@sixnetio.com.
4  *  Based on code by:
5  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
6  * and other contributors to U-Boot. See file CREDITS for list
7  * of people who contributed to this  project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <common.h>
26 #include <config.h>
27 #include <jffs2/jffs2.h>
28 #include <mpc8xx.h>
29 #include <net.h>        /* for eth_init() */
30 #include <rtc.h>
31 #include "sixnet.h"
32 #ifdef CONFIG_SHOW_BOOT_PROGRESS
33 # include <status_led.h>
34 #endif
35
36 DECLARE_GLOBAL_DATA_PTR;
37
38 #define ORMASK(size) ((-size) & OR_AM_MSK)
39
40 static long ram_size(ulong *, long);
41
42 /* ------------------------------------------------------------------------- */
43
44 #ifdef CONFIG_SHOW_BOOT_PROGRESS
45 void show_boot_progress (int status)
46 {
47 #if defined(CONFIG_STATUS_LED)
48 # if defined(STATUS_LED_BOOT)
49         if (status == 15) {
50                 /* ready to transfer to kernel, make sure LED is proper state */
51                 status_led_set(STATUS_LED_BOOT, CONFIG_BOOT_LED_STATE);
52         }
53 # endif /* STATUS_LED_BOOT */
54 #endif /* CONFIG_STATUS_LED */
55 }
56 #endif
57
58 /* ------------------------------------------------------------------------- */
59
60 /*
61  * Check Board Identity:
62  * returns 0 if recognized, -1 if unknown
63  */
64
65 int checkboard (void)
66 {
67         puts ("Board: SIXNET SXNI855T\n");
68         return 0;
69 }
70
71 /* ------------------------------------------------------------------------- */
72
73 #if defined(CONFIG_CMD_PCMCIA)
74 #error "SXNI855T has no PCMCIA port"
75 #endif
76
77 /* ------------------------------------------------------------------------- */
78
79 #define _not_used_ 0xffffffff
80
81 /* UPMB table for dual UART. */
82
83 /* this table is for 50MHz operation, it should work at all lower speeds */
84 const uint duart_table[] =
85 {
86         /* single read. (offset 0 in upm RAM) */
87         0xfffffc04, 0x0ffffc04, 0x0ff3fc04, 0x0ff3fc04,
88         0x0ff3fc00, 0x0ff3fc04, 0xfffffc04, 0xfffffc05,
89
90         /* burst read. (offset 8 in upm RAM) */
91         _not_used_, _not_used_, _not_used_, _not_used_,
92         _not_used_, _not_used_, _not_used_, _not_used_,
93         _not_used_, _not_used_, _not_used_, _not_used_,
94         _not_used_, _not_used_, _not_used_, _not_used_,
95
96         /* single write. (offset 18 in upm RAM) */
97         0xfffffc04, 0x0ffffc04, 0x00fffc04, 0x00fffc04,
98         0x00fffc04, 0x00fffc00, 0xfffffc04, 0xfffffc05,
99
100         /* burst write. (offset 20 in upm RAM) */
101         _not_used_, _not_used_, _not_used_, _not_used_,
102         _not_used_, _not_used_, _not_used_, _not_used_,
103         _not_used_, _not_used_, _not_used_, _not_used_,
104         _not_used_, _not_used_, _not_used_, _not_used_,
105
106         /* refresh. (offset 30 in upm RAM) */
107         _not_used_, _not_used_, _not_used_, _not_used_,
108         _not_used_, _not_used_, _not_used_, _not_used_,
109         _not_used_, _not_used_, _not_used_, _not_used_,
110
111         /* exception. (offset 3c in upm RAM) */
112         _not_used_, _not_used_, _not_used_, _not_used_,
113 };
114
115 /* Load FPGA very early in boot sequence, since it must be
116  * loaded before the 16C2550 serial channels can be used as
117  * console channels.
118  *
119  * Note: Much of the configuration is not complete. The
120  *       stack is in DPRAM since SDRAM has not been initialized,
121  *       so the stack must be kept small. Global variables
122  *       are still in FLASH, so they cannot be written.
123  *       Only the FLASH, DPRAM, immap and FPGA can be addressed,
124  *       the other chip selects may not have been initialized.
125  *       The clocks have been initialized, so udelay() can be
126  *       used.
127  */
128 #define FPGA_DONE       0x0080  /* PA8, input, high when FPGA load complete */
129 #define FPGA_PROGRAM_L  0x0040  /* PA9, output, low to reset, high to start */
130 #define FPGA_INIT_L     0x0020  /* PA10, input, low indicates not ready */
131 #define fpga (*(volatile unsigned char *)(CONFIG_SYS_FPGA_PROG))        /* FPGA port */
132
133 int board_postclk_init (void)
134 {
135
136         /* the data to load to the XCSxxXL FPGA */
137         static const unsigned char fpgadata[] = {
138 # include "fpgadata.c"
139         };
140
141         volatile immap_t     *immap = (immap_t *)CONFIG_SYS_IMMR;
142         volatile memctl8xx_t *memctl = &immap->im_memctl;
143 #define porta (immap->im_ioport.iop_padat)
144         const unsigned char* pdata;
145
146         /* /INITFPGA and DONEFPGA signals are inputs */
147         immap->im_ioport.iop_padir &= ~(FPGA_INIT_L | FPGA_DONE);
148
149         /* Force output pin to begin at 0, /PROGRAM asserted (0) resets FPGA */
150         porta &= ~FPGA_PROGRAM_L;
151
152         /* Set FPGA as an output */
153         immap->im_ioport.iop_padir |= FPGA_PROGRAM_L;
154
155         /* delay a little to make sure FPGA sees it, really
156          * only need less than a microsecond.
157          */
158         udelay(10);
159
160         /* unassert /PROGRAM */
161         porta |= FPGA_PROGRAM_L;
162
163         /* delay while FPGA does last erase, indicated by
164          * /INITFPGA going high. This should happen within a
165          * few milliseconds.
166          */
167         /* ### FIXME - a timeout check would be good, maybe flash
168          * the status LED to indicate the error?
169          */
170         while ((porta & FPGA_INIT_L) == 0)
171                 ; /* waiting */
172
173         /* write program data to FPGA at the programming address
174          * so extra /CS1 strobes at end of configuration don't actually
175          * write to any registers.
176          */
177         fpga = 0xff;            /* first write is ignored       */
178         fpga = 0xff;            /* fill byte                    */
179         fpga = 0xff;            /* fill byte                    */
180         fpga = 0x4f;            /* preamble code                */
181         fpga = 0x80; fpga = 0xaf; fpga = 0x9b; /* length (ignored) */
182         fpga = 0x4b;            /* field check code */
183
184         pdata = fpgadata;
185         /* while no error write out each of the 28 byte frames */
186         while ((porta & (FPGA_INIT_L | FPGA_DONE)) == FPGA_INIT_L
187                && pdata < fpgadata + sizeof(fpgadata)) {
188
189                 fpga = 0x4f;    /* preamble code */
190
191                 /* 21 bytes of data in a frame */
192                 fpga = *(pdata++); fpga = *(pdata++);
193                 fpga = *(pdata++); fpga = *(pdata++);
194                 fpga = *(pdata++); fpga = *(pdata++);
195                 fpga = *(pdata++); fpga = *(pdata++);
196                 fpga = *(pdata++); fpga = *(pdata++);
197                 fpga = *(pdata++); fpga = *(pdata++);
198                 fpga = *(pdata++); fpga = *(pdata++);
199                 fpga = *(pdata++); fpga = *(pdata++);
200                 fpga = *(pdata++); fpga = *(pdata++);
201                 fpga = *(pdata++); fpga = *(pdata++);
202                 fpga = *(pdata++);
203
204                 fpga = 0x4b;    /* field check code             */
205                 fpga = 0xff;    /* extended write cycle         */
206                 fpga = 0x4b;    /* extended write cycle
207                                  * (actually 0x4b from bitgen.exe)
208                                  */
209                 fpga = 0xff;    /* extended write cycle         */
210                 fpga = 0xff;    /* extended write cycle         */
211                 fpga = 0xff;    /* extended write cycle         */
212         }
213
214         fpga = 0xff;            /* startup byte                 */
215         fpga = 0xff;            /* startup byte                 */
216         fpga = 0xff;            /* startup byte                 */
217         fpga = 0xff;            /* startup byte                 */
218
219 #if 0 /* ### FIXME */
220         /* If didn't load all the data or FPGA_DONE is low the load failed.
221          * Maybe someday stop here and flash the status LED? The console
222          * is not configured, so can't print an error message. Can't write
223          * global variables to set a flag (except gd?).
224          * For now it must work.
225          */
226 #endif
227
228         /* Now that the FPGA is loaded, set up the Dual UART chip
229          * selects. Must be done here since it may be used as the console.
230          */
231         upmconfig(UPMB, (uint *)duart_table, sizeof(duart_table)/sizeof(uint));
232
233         memctl->memc_mbmr = DUART_MBMR;
234         memctl->memc_or5 = DUART_OR_VALUE;
235         memctl->memc_br5 = DUART_BR5_VALUE;
236         memctl->memc_or6 = DUART_OR_VALUE;
237         memctl->memc_br6 = DUART_BR6_VALUE;
238
239         return (0);
240 }
241
242 /* ------------------------------------------------------------------------- */
243
244 /* base address for SRAM, assume 32-bit port,  valid */
245 #define NVRAM_BR_VALUE   (CONFIG_SYS_SRAM_BASE | BR_PS_32 | BR_V)
246
247 /*  up to 64MB - will be adjusted for actual size */
248 #define NVRAM_OR_PRELIM  (ORMASK(CONFIG_SYS_SRAM_SIZE) \
249         | OR_CSNT_SAM | OR_ACS_DIV4 | OR_BI | OR_SCY_5_CLK | OR_EHTR)
250 /*
251  * Miscellaneous platform dependent initializations after running in RAM.
252  */
253
254 int misc_init_r (void)
255 {
256         volatile immap_t     *immap = (immap_t *)CONFIG_SYS_IMMR;
257         volatile memctl8xx_t *memctl = &immap->im_memctl;
258         bd_t *bd = gd->bd;
259         uchar enetaddr[6];
260
261         memctl->memc_or2 = NVRAM_OR_PRELIM;
262         memctl->memc_br2 = NVRAM_BR_VALUE;
263
264         /* Is there any SRAM? Is it 16 or 32 bits wide? */
265
266         /* First look for 32-bit SRAM */
267         bd->bi_sramsize = ram_size((ulong*)CONFIG_SYS_SRAM_BASE, CONFIG_SYS_SRAM_SIZE);
268
269         if (bd->bi_sramsize == 0) {
270             /* no 32-bit SRAM, but there could be 16-bit SRAM since
271              * it would report size 0 when configured for 32-bit bus.
272              * Try again with a 16-bit bus.
273              */
274             memctl->memc_br2 |= BR_PS_16;
275             bd->bi_sramsize = ram_size((ulong*)CONFIG_SYS_SRAM_BASE, CONFIG_SYS_SRAM_SIZE);
276         }
277
278         if (bd->bi_sramsize == 0) {
279             memctl->memc_br2 = 0;       /* disable select since nothing there */
280         }
281         else {
282             /* adjust or2 for actual size of SRAM */
283             memctl->memc_or2 |= ORMASK(bd->bi_sramsize);
284             bd->bi_sramstart = CONFIG_SYS_SRAM_BASE;
285             printf("SRAM:  %lu KB\n", bd->bi_sramsize >> 10);
286         }
287
288
289         /* set standard MPC8xx clock so kernel will see the time
290          * even if it doesn't have a DS1306 clock driver.
291          * This helps with experimenting with standard kernels.
292          */
293         {
294             ulong tim;
295             struct rtc_time tmp;
296
297             rtc_get(&tmp);      /* get time from DS1306 RTC */
298
299             /* convert to seconds since 1970 */
300             tim = mktime(tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
301                          tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
302
303             immap->im_sitk.sitk_rtck = KAPWR_KEY;
304             immap->im_sit.sit_rtc = tim;
305         }
306
307         /* set up ethernet address for SCC ethernet. If eth1addr
308          * is present it gets a unique address, otherwise it
309          * shares the FEC address.
310          */
311         if (!eth_getenv_enetaddr("eth1addr", enetaddr)) {
312                 eth_getenv_enetaddr("ethaddr", enetaddr);
313                 eth_setenv_enetaddr("eth1addr", enetaddr);
314         }
315
316         return (0);
317 }
318
319 #if defined(CONFIG_CMD_NAND)
320 void nand_init(void)
321 {
322         unsigned long totlen = nand_probe(CONFIG_SYS_DFLASH_BASE);
323
324         printf ("%4lu MB\n", totlen >> 20);
325 }
326 #endif
327
328 /* ------------------------------------------------------------------------- */
329
330 /*
331  * Check memory range for valid RAM. A simple memory test determines
332  * the actually available RAM size between addresses `base' and
333  * `base + maxsize'.
334  *
335  * The memory size MUST be a power of 2 for this to work.
336  *
337  * The only memory modified is 8 bytes at offset 0. This is important
338  * since for the SRAM this location is reserved for autosizing, so if
339  * it is modified and the board is reset before ram_size() completes
340  * no damage is  done. Normally even the memory at 0 is preserved. The
341  * higher SRAM addresses may contain battery backed RAM disk data which
342  * must never be corrupted.
343  */
344
345 static long ram_size(ulong *base, long maxsize)
346 {
347     volatile long       *test_addr;
348     volatile ulong      *base_addr = base;
349     ulong               ofs;            /* byte offset from base_addr */
350     ulong               save;           /* to make test non-destructive */
351     ulong               save2;          /* to make test non-destructive */
352     long                ramsize = -1;   /* size not determined yet */
353
354     save = *base_addr;          /* save value at 0 so can restore */
355     save2 = *(base_addr+1);     /* save value at 4 so can restore */
356
357     /* is any SRAM present? */
358     *base_addr = 0x5555aaaa;
359
360     /* It is important to drive the data bus with different data so
361      * it doesn't remember the value and look like RAM that isn't there.
362      */
363     *(base_addr + 1) = 0xaaaa5555;      /* use write to modify data bus */
364
365     if (*base_addr != 0x5555aaaa)
366         ramsize = 0;            /* no RAM present, or defective */
367     else {
368         *base_addr = 0xaaaa5555;
369         *(base_addr + 1) = 0x5555aaaa;  /* use write to modify data bus */
370         if (*base_addr != 0xaaaa5555)
371             ramsize = 0;        /* no RAM present, or defective */
372     }
373
374     /* now size it if any is present */
375     for (ofs = 4; ofs < maxsize && ramsize < 0; ofs <<= 1) {
376         test_addr = (long*)((long)base_addr + ofs);     /* location to test */
377
378         *base_addr = ~*test_addr;
379         if (*base_addr == *test_addr)
380             ramsize = ofs;      /* wrapped back to 0, so this is the size */
381     }
382
383     *base_addr = save;          /* restore value at 0 */
384     *(base_addr+1) = save2;     /* restore value at 4 */
385     return (ramsize);
386 }
387
388 /* ------------------------------------------------------------------------- */
389 /* sdram table based on the FADS manual                                      */
390 /* for chip MB811171622A-100                                                 */
391
392 /* this table is for 50MHz operation, it should work at all lower speeds */
393
394 const uint sdram_table[] =
395 {
396         /* single read. (offset 0 in upm RAM) */
397         0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
398         0x1ff77c47,
399
400         /* precharge and Mode Register Set initialization (offset 5).
401          * This is also entered at offset 6 to do Mode Register Set
402          * without the precharge.
403          */
404         0x1ff77c34, 0xefeabc34, 0x1fb57c35,
405
406         /* burst read. (offset 8 in upm RAM) */
407         0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
408         0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
409         _not_used_, _not_used_, _not_used_, _not_used_,
410         _not_used_, _not_used_, _not_used_, _not_used_,
411
412         /* single write. (offset 18 in upm RAM) */
413         /* FADS had 0x1f27fc04, ...
414          * but most other boards have 0x1f07fc04, which
415          * sets GPL0 from A11MPC to 0 1/4 clock earlier,
416          * like the single read.
417          * This seems better so I am going with the change.
418          */
419         0x1f07fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
420         _not_used_, _not_used_, _not_used_, _not_used_,
421
422         /* burst write. (offset 20 in upm RAM) */
423         0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
424         0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
425         _not_used_, _not_used_, _not_used_, _not_used_,
426         _not_used_, _not_used_, _not_used_, _not_used_,
427
428         /* refresh. (offset 30 in upm RAM) */
429         0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
430         0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
431         _not_used_, _not_used_, _not_used_, _not_used_,
432
433         /* exception. (offset 3c in upm RAM) */
434         0x7ffffc07, _not_used_, _not_used_, _not_used_ };
435
436 /* ------------------------------------------------------------------------- */
437
438 #define SDRAM_MAX_SIZE          0x10000000      /* max 256 MB SDRAM */
439
440 /* precharge and set Mode Register */
441 #define SDRAM_MCR_PRE    (MCR_OP_RUN | MCR_UPM_A |      /* select UPM     */ \
442                           MCR_MB_CS3 |                  /* chip select    */ \
443                           MCR_MLCF(1) | MCR_MAD(5))     /* 1 time at 0x05 */
444
445 /* set Mode Register, no precharge */
446 #define SDRAM_MCR_MRS    (MCR_OP_RUN | MCR_UPM_A |      /* select UPM     */ \
447                           MCR_MB_CS3 |                  /* chip select    */ \
448                           MCR_MLCF(1) | MCR_MAD(6))     /* 1 time at 0x06 */
449
450 /* runs refresh loop twice so get 8 refresh cycles */
451 #define SDRAM_MCR_REFR   (MCR_OP_RUN | MCR_UPM_A |      /* select UPM     */ \
452                           MCR_MB_CS3 |                  /* chip select    */ \
453                           MCR_MLCF(2) | MCR_MAD(0x30))  /* twice at 0x30  */
454
455 /* MAMR values work in either mamr or mbmr */
456 #define SDRAM_MAMR_BASE  /* refresh at 50MHz */                           \
457                          ((195 << MAMR_PTA_SHIFT) | MAMR_PTAE             \
458                          | MAMR_DSA_1_CYCL      /* 1 cycle disable */     \
459                          | MAMR_RLFA_1X         /* Read loop 1 time */    \
460                          | MAMR_WLFA_1X         /* Write loop 1 time */   \
461                          | MAMR_TLFA_4X)        /* Timer loop 4 times */
462 /* 8 column SDRAM */
463 #define SDRAM_MAMR_8COL (SDRAM_MAMR_BASE                                  \
464                          | MAMR_AMA_TYPE_0      /* Address MUX 0 */       \
465                          | MAMR_G0CLA_A11)      /* GPL0 A11[MPC] */
466
467 /* 9 column SDRAM */
468 #define SDRAM_MAMR_9COL (SDRAM_MAMR_BASE                                  \
469                          | MAMR_AMA_TYPE_1      /* Address MUX 1 */       \
470                          | MAMR_G0CLA_A10)      /* GPL0 A10[MPC] */
471
472 /* base address 0, 32-bit port, SDRAM UPM, valid */
473 #define SDRAM_BR_VALUE   (BR_PS_32 | BR_MS_UPMA | BR_V)
474
475 /*  up to 256MB, SAM, G5LS - will be adjusted for actual size */
476 #define SDRAM_OR_PRELIM  (ORMASK(SDRAM_MAX_SIZE) | OR_CSNT_SAM | OR_G5LS)
477
478 /* This is the Mode Select Register value for the SDRAM.
479  * Burst length: 4
480  * Burst Type: sequential
481  * CAS Latency: 2
482  * Write Burst Length: burst
483  */
484 #define SDRAM_MODE   0x22       /* CAS latency 2, burst length 4 */
485
486 /* ------------------------------------------------------------------------- */
487
488 phys_size_t initdram(int board_type)
489 {
490         volatile immap_t     *immap = (immap_t *)CONFIG_SYS_IMMR;
491         volatile memctl8xx_t *memctl = &immap->im_memctl;
492         uint size_sdram = 0;
493         uint size_sdram9 = 0;
494         uint base = 0;          /* SDRAM must start at 0 */
495         int i;
496
497         upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
498
499         /* Configure the refresh (mostly).  This needs to be
500          * based upon processor clock speed and optimized to provide
501          * the highest level of performance.
502          *
503          * Preliminary prescaler for refresh.
504          * This value is selected for four cycles in 31.2 us,
505          * which gives 8192 cycles in 64 milliseconds.
506          * This may be too fast, but works for any memory.
507          * It is adjusted to 4096 cycles in 64 milliseconds if
508          * possible once we know what memory we have.
509          *
510          * We have to be careful changing UPM registers after we
511          * ask it to run these commands.
512          *
513          * PTA - periodic timer period for our design is
514          *       50 MHz x 31.2us
515          *       ---------------  = 195
516          *       1 x 8 x 1
517          *
518          *    50MHz clock
519          *    31.2us refresh interval
520          *    SCCR[DFBRG] 0
521          *    PTP divide by 8
522          *    1 chip select
523          */
524         memctl->memc_mptpr = MPTPR_PTP_DIV8;    /* 0x0800 */
525         memctl->memc_mamr = SDRAM_MAMR_8COL & (~MAMR_PTAE); /* no refresh yet */
526
527         /* The SDRAM Mode Register value is shifted left 2 bits since
528          * A30 and A31 don't connect to the SDRAM for 32-bit wide memory.
529          */
530         memctl->memc_mar = SDRAM_MODE << 2;     /* MRS code */
531         udelay(200);            /* SDRAM needs 200uS before set it up */
532
533         /* Now run the precharge/nop/mrs commands. */
534         memctl->memc_mcr = SDRAM_MCR_PRE;
535         udelay(2);
536
537         /* Run 8 refresh cycles (2 sets of 4) */
538         memctl->memc_mcr = SDRAM_MCR_REFR;      /* run refresh twice */
539         udelay(2);
540
541         /* some brands want Mode Register set after the refresh
542          * cycles. This shouldn't hurt anything for the brands
543          * that were happy with the first time we set it.
544          */
545         memctl->memc_mcr = SDRAM_MCR_MRS;
546         udelay(2);
547
548         memctl->memc_mamr = SDRAM_MAMR_8COL;    /* enable refresh */
549         memctl->memc_or3 = SDRAM_OR_PRELIM;
550         memctl->memc_br3 = SDRAM_BR_VALUE + base;
551
552         /* Some brands need at least 10 DRAM accesses to stabilize.
553          * It wont hurt the brands that don't.
554          */
555         for (i=0; i<10; ++i) {
556                 volatile ulong *addr = (volatile ulong *)base;
557                 ulong val;
558
559                 val = *(addr + i);
560                 *(addr + i) = val;
561         }
562
563         /* Check SDRAM memory Size in 8 column mode.
564          * For a 9 column memory we will get half the actual size.
565          */
566         size_sdram = ram_size((ulong *)0, SDRAM_MAX_SIZE);
567
568         /* Check SDRAM memory Size in 9 column mode.
569          * For an 8 column memory we will see at most 4 megabytes.
570          */
571         memctl->memc_mamr = SDRAM_MAMR_9COL;
572         size_sdram9 = ram_size((ulong *)0, SDRAM_MAX_SIZE);
573
574         if (size_sdram < size_sdram9)   /* leave configuration at 9 columns */
575                 size_sdram = size_sdram9;
576         else                            /* go back to 8 columns */
577                 memctl->memc_mamr = SDRAM_MAMR_8COL;
578
579         /* adjust or3 for actual size of SDRAM
580          */
581         memctl->memc_or3 |= ORMASK(size_sdram);
582
583         /* Adjust refresh rate depending on SDRAM type.
584          * For types > 128 MBit (32 Mbyte for 2 x16 devices) leave
585          * it at the current (fast) rate.
586          * For 16, 64 and 128 MBit half the rate will do.
587          */
588         if (size_sdram <= 32 * 1024 * 1024)
589                 memctl->memc_mptpr = MPTPR_PTP_DIV16;   /* 0x0400 */
590
591         return (size_sdram);
592 }