sixnet.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  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. #include <common.h>
  25. #include <config.h>
  26. #include <mpc8xx.h>
  27. #include <net.h> /* for eth_init() */
  28. #include <rtc.h>
  29. #include "sixnet.h"
  30. #define ORMASK(size) ((-size) & OR_AM_MSK)
  31. static long ram_size(ulong *, long);
  32. /* ------------------------------------------------------------------------- */
  33. /*
  34. * Check Board Identity:
  35. * returns 0 if recognized, -1 if unknown
  36. */
  37. int checkboard (void)
  38. {
  39. puts ("Board: SIXNET SXNI855T\n");
  40. return 0;
  41. }
  42. /* ------------------------------------------------------------------------- */
  43. #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA)
  44. #error "SXNI855T has no PCMCIA port"
  45. #endif /* CFG_CMD_PCMCIA */
  46. /* ------------------------------------------------------------------------- */
  47. #define _not_used_ 0xffffffff
  48. /* UPMB table for dual UART. */
  49. /* this table is for 50MHz operation, it should work at all lower speeds */
  50. const uint duart_table[] =
  51. {
  52. /* single read. (offset 0 in upm RAM) */
  53. 0xfffffc04, 0x0ffffc04, 0x0ff3fc04, 0x0ff3fc04,
  54. 0x0ff3fc00, 0x0ff3fc04, 0xfffffc04, 0xfffffc05,
  55. /* burst read. (offset 8 in upm RAM) */
  56. _not_used_, _not_used_, _not_used_, _not_used_,
  57. _not_used_, _not_used_, _not_used_, _not_used_,
  58. _not_used_, _not_used_, _not_used_, _not_used_,
  59. _not_used_, _not_used_, _not_used_, _not_used_,
  60. /* single write. (offset 18 in upm RAM) */
  61. 0xfffffc04, 0x0ffffc04, 0x00fffc04, 0x00fffc04,
  62. 0x00fffc04, 0x00fffc00, 0xfffffc04, 0xfffffc05,
  63. /* burst write. (offset 20 in upm RAM) */
  64. _not_used_, _not_used_, _not_used_, _not_used_,
  65. _not_used_, _not_used_, _not_used_, _not_used_,
  66. _not_used_, _not_used_, _not_used_, _not_used_,
  67. _not_used_, _not_used_, _not_used_, _not_used_,
  68. /* refresh. (offset 30 in upm RAM) */
  69. _not_used_, _not_used_, _not_used_, _not_used_,
  70. _not_used_, _not_used_, _not_used_, _not_used_,
  71. _not_used_, _not_used_, _not_used_, _not_used_,
  72. /* exception. (offset 3c in upm RAM) */
  73. _not_used_, _not_used_, _not_used_, _not_used_,
  74. };
  75. /* Load FPGA very early in boot sequence, since it must be
  76. * loaded before the 16C2550 serial channels can be used as
  77. * console channels.
  78. *
  79. * Note: Much of the configuration is not complete. The
  80. * stack is in DPRAM since SDRAM has not been initialized,
  81. * so the stack must be kept small. Global variables
  82. * are still in FLASH, so they cannot be written.
  83. * Only the FLASH, DPRAM, immap and FPGA can be addressed,
  84. * the other chip selects may not have been initialized.
  85. * The clocks have been initialized, so udelay() can be
  86. * used.
  87. */
  88. #define FPGA_DONE 0x0080 /* PA8, input, high when FPGA load complete */
  89. #define FPGA_PROGRAM_L 0x0040 /* PA9, output, low to reset, high to start */
  90. #define FPGA_INIT_L 0x0020 /* PA10, input, low indicates not ready */
  91. #define fpga (*(volatile unsigned char *)(CFG_FPGA_PROG)) /* FPGA port */
  92. int board_postclk_init (void)
  93. {
  94. /* the data to load to the XCSxxXL FPGA */
  95. static const unsigned char fpgadata[] = {
  96. # include "fpgadata.c"
  97. };
  98. volatile immap_t *immap = (immap_t *)CFG_IMMR;
  99. volatile memctl8xx_t *memctl = &immap->im_memctl;
  100. #define porta (immap->im_ioport.iop_padat)
  101. const unsigned char* pdata;
  102. /* /INITFPGA and DONEFPGA signals are inputs */
  103. immap->im_ioport.iop_padir &= ~(FPGA_INIT_L | FPGA_DONE);
  104. /* Force output pin to begin at 0, /PROGRAM asserted (0) resets FPGA */
  105. porta &= ~FPGA_PROGRAM_L;
  106. /* Set FPGA as an output */
  107. immap->im_ioport.iop_padir |= FPGA_PROGRAM_L;
  108. /* delay a little to make sure FPGA sees it, really
  109. * only need less than a microsecond.
  110. */
  111. udelay(10);
  112. /* unassert /PROGRAM */
  113. porta |= FPGA_PROGRAM_L;
  114. /* delay while FPGA does last erase, indicated by
  115. * /INITFPGA going high. This should happen within a
  116. * few milliseconds.
  117. */
  118. /* ### FIXME - a timeout check would be good, maybe flash
  119. * the status LED to indicate the error?
  120. */
  121. while ((porta & FPGA_INIT_L) == 0)
  122. ; /* waiting */
  123. /* write program data to FPGA at the programming address
  124. * so extra /CS1 strobes at end of configuration don't actually
  125. * write to any registers.
  126. */
  127. fpga = 0xff; /* first write is ignored */
  128. fpga = 0xff; /* fill byte */
  129. fpga = 0xff; /* fill byte */
  130. fpga = 0x4f; /* preamble code */
  131. fpga = 0x80; fpga = 0xaf; fpga = 0x9b; /* length (ignored) */
  132. fpga = 0x4b; /* field check code */
  133. pdata = fpgadata;
  134. /* while no error write out each of the 28 byte frames */
  135. while ((porta & (FPGA_INIT_L | FPGA_DONE)) == FPGA_INIT_L
  136. && pdata < fpgadata + sizeof(fpgadata)) {
  137. fpga = 0x4f; /* preamble code */
  138. /* 21 bytes of data in a frame */
  139. fpga = *(pdata++); fpga = *(pdata++);
  140. fpga = *(pdata++); fpga = *(pdata++);
  141. fpga = *(pdata++); fpga = *(pdata++);
  142. fpga = *(pdata++); fpga = *(pdata++);
  143. fpga = *(pdata++); fpga = *(pdata++);
  144. fpga = *(pdata++); fpga = *(pdata++);
  145. fpga = *(pdata++); fpga = *(pdata++);
  146. fpga = *(pdata++); fpga = *(pdata++);
  147. fpga = *(pdata++); fpga = *(pdata++);
  148. fpga = *(pdata++); fpga = *(pdata++);
  149. fpga = *(pdata++);
  150. fpga = 0x4b; /* field check code */
  151. fpga = 0xff; /* extended write cycle */
  152. fpga = 0x4b; /* extended write cycle
  153. * (actually 0x4b from bitgen.exe)
  154. */
  155. fpga = 0xff; /* extended write cycle */
  156. fpga = 0xff; /* extended write cycle */
  157. fpga = 0xff; /* extended write cycle */
  158. }
  159. fpga = 0xff; /* startup byte */
  160. fpga = 0xff; /* startup byte */
  161. fpga = 0xff; /* startup byte */
  162. fpga = 0xff; /* startup byte */
  163. #if 0 /* ### FIXME */
  164. /* If didn't load all the data or FPGA_DONE is low the load failed.
  165. * Maybe someday stop here and flash the status LED? The console
  166. * is not configured, so can't print an error message. Can't write
  167. * global variables to set a flag (except gd?).
  168. * For now it must work.
  169. */
  170. #endif
  171. /* Now that the FPGA is loaded, set up the Dual UART chip
  172. * selects. Must be done here since it may be used as the console.
  173. */
  174. upmconfig(UPMB, (uint *)duart_table, sizeof(duart_table)/sizeof(uint));
  175. memctl->memc_mbmr = DUART_MBMR;
  176. memctl->memc_or5 = DUART_OR_VALUE;
  177. memctl->memc_br5 = DUART_BR5_VALUE;
  178. memctl->memc_or6 = DUART_OR_VALUE;
  179. memctl->memc_br6 = DUART_BR6_VALUE;
  180. return (0);
  181. }
  182. /* ------------------------------------------------------------------------- */
  183. /* base address for SRAM, assume 32-bit port, valid */
  184. #define NVRAM_BR_VALUE (CFG_SRAM_BASE | BR_PS_32 | BR_V)
  185. /* up to 64MB - will be adjusted for actual size */
  186. #define NVRAM_OR_PRELIM (ORMASK(CFG_SRAM_SIZE) \
  187. | OR_CSNT_SAM | OR_ACS_DIV4 | OR_BI | OR_SCY_5_CLK | OR_EHTR)
  188. /*
  189. * Miscellaneous platform dependent initializations after running in RAM.
  190. */
  191. int misc_init_r (void)
  192. {
  193. DECLARE_GLOBAL_DATA_PTR;
  194. volatile immap_t *immap = (immap_t *)CFG_IMMR;
  195. volatile memctl8xx_t *memctl = &immap->im_memctl;
  196. bd_t *bd = gd->bd;
  197. memctl->memc_or2 = NVRAM_OR_PRELIM;
  198. memctl->memc_br2 = NVRAM_BR_VALUE;
  199. /* Is there any SRAM? Is it 16 or 32 bits wide? */
  200. /* First look for 32-bit SRAM */
  201. bd->bi_sramsize = ram_size((ulong*)CFG_SRAM_BASE, CFG_SRAM_SIZE);
  202. if (bd->bi_sramsize == 0) {
  203. /* no 32-bit SRAM, but there could be 16-bit SRAM since
  204. * it would report size 0 when configured for 32-bit bus.
  205. * Try again with a 16-bit bus.
  206. */
  207. memctl->memc_br2 |= BR_PS_16;
  208. bd->bi_sramsize = ram_size((ulong*)CFG_SRAM_BASE, CFG_SRAM_SIZE);
  209. }
  210. if (bd->bi_sramsize == 0) {
  211. memctl->memc_br2 = 0; /* disable select since nothing there */
  212. }
  213. else {
  214. /* adjust or2 for actual size of SRAM */
  215. memctl->memc_or2 |= ORMASK(bd->bi_sramsize);
  216. bd->bi_sramstart = CFG_SRAM_BASE;
  217. printf("SRAM: %lu KB\n", bd->bi_sramsize >> 10);
  218. }
  219. /* set standard MPC8xx clock so kernel will see the time
  220. * even if it doesn't have a DS1306 clock driver.
  221. * This helps with experimenting with standard kernels.
  222. */
  223. {
  224. ulong tim;
  225. struct rtc_time tmp;
  226. rtc_get(&tmp); /* get time from DS1306 RTC */
  227. /* convert to seconds since 1970 */
  228. tim = mktime(tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
  229. tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
  230. immap->im_sitk.sitk_rtck = KAPWR_KEY;
  231. immap->im_sit.sit_rtc = tim;
  232. }
  233. #if 0
  234. /* The code below is no longer valid since the prototype of
  235. * eth_init() and eth_halt() have been changed to support
  236. * multi-ethernet feature in U-Boot; the eth_initialize()
  237. * routine should be called before any access to the ethernet
  238. * callbacks.
  239. */
  240. /* FIXME - for now init ethernet to force PHY special mode */
  241. eth_init(bd);
  242. eth_halt();
  243. #endif
  244. return (0);
  245. }
  246. /* ------------------------------------------------------------------------- */
  247. /*
  248. * Check memory range for valid RAM. A simple memory test determines
  249. * the actually available RAM size between addresses `base' and
  250. * `base + maxsize'.
  251. *
  252. * The memory size MUST be a power of 2 for this to work.
  253. *
  254. * The only memory modified is 4 bytes at offset 0. This is important
  255. * since for the SRAM this location is reserved for autosizing, so if
  256. * it is modified and the board is reset before ram_size() completes
  257. * no damage is done. Normally even the memory at 0 is preserved. The
  258. * higher SRAM addresses may contain battery backed RAM disk data which
  259. * must never be corrupted.
  260. */
  261. static long ram_size(ulong *base, long maxsize)
  262. {
  263. volatile long *test_addr;
  264. volatile long *base_addr = base;
  265. volatile long *flash = (volatile long*)CFG_FLASH_BASE;
  266. ulong ofs; /* byte offset from base_addr */
  267. ulong save; /* to make test non-destructive */
  268. ulong junk;
  269. long ramsize = -1; /* size not determined yet */
  270. save = *base_addr; /* save value at 0 so can restore */
  271. /* is any SRAM present? */
  272. *base_addr = 0x5555aaaa;
  273. /* use flash read to modify data bus, since with no SRAM present
  274. * the data bus may retain the value if our code is running
  275. * completely in the cache.
  276. */
  277. junk = *flash;
  278. if (*base_addr != 0x5555aaaa)
  279. ramsize = 0; /* no RAM present, or defective */
  280. else {
  281. *base_addr = 0xaaaa5555;
  282. junk = *flash; /* use flash read to modify data bus */
  283. if (*base_addr != 0xaaaa5555)
  284. ramsize = 0; /* no RAM present, or defective */
  285. }
  286. /* now size it if any is present */
  287. for (ofs = 4; ofs < maxsize && ramsize < 0; ofs <<= 1) {
  288. test_addr = (long*)((long)base_addr + ofs); /* location to test */
  289. *base_addr = ~*test_addr;
  290. if (*base_addr == *test_addr)
  291. ramsize = ofs; /* wrapped back to 0, so this is the size */
  292. }
  293. *base_addr = save; /* restore value at 0 */
  294. return (ramsize);
  295. }
  296. /* ------------------------------------------------------------------------- */
  297. /* sdram table based on the FADS manual */
  298. /* for chip MB811171622A-100 */
  299. /* this table is for 50MHz operation, it should work at all lower speeds */
  300. const uint sdram_table[] =
  301. {
  302. /* single read. (offset 0 in upm RAM) */
  303. 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
  304. 0x1ff77c47,
  305. /* precharge and Mode Register Set initialization (offset 5).
  306. * This is also entered at offset 6 to do Mode Register Set
  307. * without the precharge.
  308. */
  309. 0x1ff77c34, 0xefeabc34, 0x1fb57c35,
  310. /* burst read. (offset 8 in upm RAM) */
  311. 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
  312. 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
  313. _not_used_, _not_used_, _not_used_, _not_used_,
  314. _not_used_, _not_used_, _not_used_, _not_used_,
  315. /* single write. (offset 18 in upm RAM) */
  316. /* FADS had 0x1f27fc04, ...
  317. * but most other boards have 0x1f07fc04, which
  318. * sets GPL0 from A11MPC to 0 1/4 clock earlier,
  319. * like the single read.
  320. * This seems better so I am going with the change.
  321. */
  322. 0x1f07fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
  323. _not_used_, _not_used_, _not_used_, _not_used_,
  324. /* burst write. (offset 20 in upm RAM) */
  325. 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
  326. 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
  327. _not_used_, _not_used_, _not_used_, _not_used_,
  328. _not_used_, _not_used_, _not_used_, _not_used_,
  329. /* refresh. (offset 30 in upm RAM) */
  330. 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
  331. 0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
  332. _not_used_, _not_used_, _not_used_, _not_used_,
  333. /* exception. (offset 3c in upm RAM) */
  334. 0x7ffffc07, _not_used_, _not_used_, _not_used_ };
  335. /* ------------------------------------------------------------------------- */
  336. #define SDRAM_MAX_SIZE 0x10000000 /* max 256 MB SDRAM */
  337. /* precharge and set Mode Register */
  338. #define SDRAM_MCR_PRE (MCR_OP_RUN | MCR_UPM_A | /* select UPM */ \
  339. MCR_MB_CS3 | /* chip select */ \
  340. MCR_MLCF(1) | MCR_MAD(5)) /* 1 time at 0x05 */
  341. /* set Mode Register, no precharge */
  342. #define SDRAM_MCR_MRS (MCR_OP_RUN | MCR_UPM_A | /* select UPM */ \
  343. MCR_MB_CS3 | /* chip select */ \
  344. MCR_MLCF(1) | MCR_MAD(6)) /* 1 time at 0x06 */
  345. /* runs refresh loop twice so get 8 refresh cycles */
  346. #define SDRAM_MCR_REFR (MCR_OP_RUN | MCR_UPM_A | /* select UPM */ \
  347. MCR_MB_CS3 | /* chip select */ \
  348. MCR_MLCF(2) | MCR_MAD(0x30)) /* twice at 0x30 */
  349. /* MAMR values work in either mamr or mbmr */
  350. /* 8 column SDRAM */
  351. #define SDRAM_MAMR_8COL /* refresh at 50MHz */ \
  352. ((195 << MAMR_PTA_SHIFT) | MAMR_PTAE \
  353. | MAMR_AMA_TYPE_0 /* Address MUX 0 */ \
  354. | MAMR_DSA_1_CYCL /* 1 cycle disable */ \
  355. | MAMR_G0CLA_A11 /* GPL0 A11[MPC] */ \
  356. | MAMR_RLFA_1X /* Read loop 1 time */ \
  357. | MAMR_WLFA_1X /* Write loop 1 time */ \
  358. | MAMR_TLFA_4X) /* Timer loop 4 times */
  359. /* 9 column SDRAM */
  360. #define SDRAM_MAMR_9COL ((SDRAM_MAMR_8COL & (~MAMR_G0CLA_A11)) | MAMR_G0CLA_A10)
  361. /* base address 0, 32-bit port, SDRAM UPM, valid */
  362. #define SDRAM_BR_VALUE (BR_PS_32 | BR_MS_UPMA | BR_V)
  363. /* up to 256MB, SAM, G5LS - will be adjusted for actual size */
  364. #define SDRAM_OR_PRELIM (ORMASK(SDRAM_MAX_SIZE) | OR_CSNT_SAM | OR_G5LS)
  365. /* This is the Mode Select Register value for the SDRAM.
  366. * Burst length: 4
  367. * Burst Type: sequential
  368. * CAS Latency: 2
  369. * Write Burst Length: burst
  370. */
  371. #define SDRAM_MODE 0x22 /* CAS latency 2, burst length 4 */
  372. /* ------------------------------------------------------------------------- */
  373. long int initdram(int board_type)
  374. {
  375. volatile immap_t *immap = (immap_t *)CFG_IMMR;
  376. volatile memctl8xx_t *memctl = &immap->im_memctl;
  377. uint size_sdram = 0;
  378. uint size_sdram9 = 0;
  379. uint base = 0; /* SDRAM must start at 0 */
  380. int i;
  381. upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
  382. /* Configure the refresh (mostly). This needs to be
  383. * based upon processor clock speed and optimized to provide
  384. * the highest level of performance.
  385. *
  386. * Preliminary prescaler for refresh.
  387. * This value is selected for four cycles in 31.2 us,
  388. * which gives 8192 cycles in 64 milliseconds.
  389. * This may be too fast, but works for any memory.
  390. * It is adjusted to 4096 cycles in 64 milliseconds if
  391. * possible once we know what memory we have.
  392. *
  393. * We have to be careful changing UPM registers after we
  394. * ask it to run these commands.
  395. *
  396. * PTA - periodic timer period for our design is
  397. * 50 MHz x 31.2us
  398. * --------------- = 195
  399. * 1 x 8 x 1
  400. *
  401. * 50MHz clock
  402. * 31.2us refresh interval
  403. * SCCR[DFBRG] 0
  404. * PTP divide by 8
  405. * 1 chip select
  406. */
  407. memctl->memc_mptpr = MPTPR_PTP_DIV8; /* 0x0800 */
  408. memctl->memc_mamr = SDRAM_MAMR_8COL & (~MAMR_PTAE); /* no refresh yet */
  409. /* The SDRAM Mode Register value is shifted left 2 bits since
  410. * A30 and A31 don't connect to the SDRAM for 32-bit wide memory.
  411. */
  412. memctl->memc_mar = SDRAM_MODE << 2; /* MRS code */
  413. udelay(200); /* SDRAM needs 200uS before set it up */
  414. /* Now run the precharge/nop/mrs commands. */
  415. memctl->memc_mcr = SDRAM_MCR_PRE;
  416. udelay(2);
  417. /* Run 8 refresh cycles (2 sets of 4) */
  418. memctl->memc_mcr = SDRAM_MCR_REFR; /* run refresh twice */
  419. udelay(2);
  420. /* some brands want Mode Register set after the refresh
  421. * cycles. This shouldn't hurt anything for the brands
  422. * that were happy with the first time we set it.
  423. */
  424. memctl->memc_mcr = SDRAM_MCR_MRS;
  425. udelay(2);
  426. memctl->memc_mamr = SDRAM_MAMR_8COL; /* enable refresh */
  427. memctl->memc_or3 = SDRAM_OR_PRELIM;
  428. memctl->memc_br3 = SDRAM_BR_VALUE + base;
  429. /* Some brands need at least 10 DRAM accesses to stabilize.
  430. * It wont hurt the brands that don't.
  431. */
  432. for (i=0; i<10; ++i) {
  433. volatile ulong *addr = (volatile ulong *)base;
  434. ulong val;
  435. val = *(addr + i);
  436. *(addr + i) = val;
  437. }
  438. /* Check SDRAM memory Size in 8 column mode.
  439. * For a 9 column memory we will get half the actual size.
  440. */
  441. size_sdram = ram_size((ulong *)0, SDRAM_MAX_SIZE);
  442. /* Check SDRAM memory Size in 9 column mode.
  443. * For an 8 column memory we will see at most 4 megabytes.
  444. */
  445. memctl->memc_mamr = SDRAM_MAMR_9COL;
  446. size_sdram9 = ram_size((ulong *)0, SDRAM_MAX_SIZE);
  447. if (size_sdram < size_sdram9) /* leave configuration at 9 columns */
  448. size_sdram = size_sdram9;
  449. else /* go back to 8 columns */
  450. memctl->memc_mamr = SDRAM_MAMR_8COL;
  451. /* adjust or3 for actual size of SDRAM
  452. */
  453. memctl->memc_or3 |= ORMASK(size_sdram);
  454. /* Adjust refresh rate depending on SDRAM type.
  455. * For types > 128 MBit (32 Mbyte for 2 x16 devices) leave
  456. * it at the current (fast) rate.
  457. * For 16, 64 and 128 MBit half the rate will do.
  458. */
  459. if (size_sdram <= 32 * 1024 * 1024)
  460. memctl->memc_mptpr = MPTPR_PTP_DIV16; /* 0x0400 */
  461. return (size_sdram);
  462. }