elpt860.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*
  2. **=====================================================================
  3. **
  4. ** Copyright (C) 2000, 2001, 2002, 2003
  5. ** The LEOX team <team@leox.org>, http://www.leox.org
  6. **
  7. ** LEOX.org is about the development of free hardware and software resources
  8. ** for system on chip.
  9. **
  10. ** Description: U-Boot port on the LEOX's ELPT860 CPU board
  11. ** ~~~~~~~~~~~
  12. **
  13. **=====================================================================
  14. **
  15. ** This program is free software; you can redistribute it and/or
  16. ** modify it under the terms of the GNU General Public License as
  17. ** published by the Free Software Foundation; either version 2 of
  18. ** the License, or (at your option) any later version.
  19. **
  20. ** This program is distributed in the hope that it will be useful,
  21. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. ** GNU General Public License for more details.
  24. **
  25. ** You should have received a copy of the GNU General Public License
  26. ** along with this program; if not, write to the Free Software
  27. ** Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  28. ** MA 02111-1307 USA
  29. **
  30. **=====================================================================
  31. */
  32. /*
  33. ** Note 1: In this file, you have to provide the following functions:
  34. ** ------
  35. ** int board_early_init_f(void)
  36. ** int checkboard(void)
  37. ** phys_size_t initdram(int board_type)
  38. ** called from 'board_init_f()' into 'common/board.c'
  39. **
  40. ** void reset_phy(void)
  41. ** called from 'board_init_r()' into 'common/board.c'
  42. */
  43. #include <common.h>
  44. #include <mpc8xx.h>
  45. /* ------------------------------------------------------------------------- */
  46. static long int dram_size (long int, long int *, long int);
  47. /* ------------------------------------------------------------------------- */
  48. #define _NOT_USED_ 0xFFFFFFFF
  49. const uint init_sdram_table[] = {
  50. /*
  51. * Single Read. (Offset 0 in UPMA RAM)
  52. */
  53. 0x0FFCCC04, 0xFFFFFC04, 0x0FFC3C04, 0xFFFFFC04,
  54. 0xFFFFFC04, /* last */
  55. /*
  56. * SDRAM Initialization (offset 5 in UPMA RAM)
  57. *
  58. * This is no UPM entry point. The following definition uses
  59. * the remaining space to establish an initialization
  60. * sequence, which is executed by a RUN command.
  61. *
  62. */
  63. 0xFFFFFC04, 0xFFFFFC04, 0x0FFC3C04, /* last */
  64. /*
  65. * Burst Read. (Offset 8 in UPMA RAM)
  66. */
  67. 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
  68. 0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
  69. 0xFFFFFC04, 0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04,
  70. 0xFFFFFC04, 0xFFFFFC04, 0x0FFC3C04, 0xFFFFFC04, /* last */
  71. /*
  72. * Single Write. (Offset 18 in UPMA RAM)
  73. */
  74. 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, 0x0FFC3C04,
  75. 0xFFFFFC04, 0xFFFFFC04, 0x0FFFFC04, 0xFFFFFC04, /* last */
  76. /*
  77. * Burst Write. (Offset 20 in UPMA RAM)
  78. */
  79. 0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
  80. 0xFFFFFC04, 0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04,
  81. 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC34, 0x0FAC0C34,
  82. 0xFFFFFC05, 0xFFFFFC04, 0x0FFCFC04, 0xFFFFFC05, /* last */
  83. };
  84. const uint sdram_table[] = {
  85. /*
  86. * Single Read. (Offset 0 in UPMA RAM)
  87. */
  88. 0x0F0FFC24, 0x0F0CFC04, 0xFF0FFC04, 0x00AF3C04,
  89. 0xFF0FFC00, /* last */
  90. /*
  91. * SDRAM Initialization (offset 5 in UPMA RAM)
  92. *
  93. * This is no UPM entry point. The following definition uses
  94. * the remaining space to establish an initialization
  95. * sequence, which is executed by a RUN command.
  96. *
  97. */
  98. 0x0FFCCC04, 0xFFAFFC05, 0xFFAFFC05, /* last */
  99. /*
  100. * Burst Read. (Offset 8 in UPMA RAM)
  101. */
  102. 0x0F0FFC24, 0x0F0CFC04, 0xFF0FFC04, 0x00AF3C04,
  103. 0xF00FFC00, 0xF00FFC00, 0xF00FFC00, 0xFF0FFC00,
  104. 0x0FFCCC04, 0xFFAFFC05, 0xFFAFFC04, 0xFFAFFC04,
  105. 0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, /* last */
  106. /*
  107. * Single Write. (Offset 18 in UPMA RAM)
  108. */
  109. 0x0F0FFC24, 0x0F0CFC04, 0xFF0FFC04, 0x00AF0C00,
  110. 0xFF0FFC04, 0x0FFCCC04, 0xFFAFFC05, /* last */
  111. _NOT_USED_,
  112. /*
  113. * Burst Write. (Offset 20 in UPMA RAM)
  114. */
  115. 0x0F0FFC24, 0x0F0CFC04, 0xFF0FFC00, 0x00AF0C00,
  116. 0xF00FFC00, 0xF00FFC00, 0xF00FFC04, 0x0FFCCC04,
  117. 0xFFAFFC04, 0xFFAFFC05, 0xFFAFFC04, 0xFFAFFC04,
  118. 0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, /* last */
  119. /*
  120. * Refresh (Offset 30 in UPMA RAM)
  121. */
  122. 0x0FFC3C04, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
  123. 0xFFFFFC05, 0xFFFFFC04, 0xFFFFFC05, _NOT_USED_,
  124. 0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, 0xFFAFFC04, /* last */
  125. /*
  126. * Exception. (Offset 3c in UPMA RAM)
  127. */
  128. 0x0FFFFC34, 0x0FAC0C34, 0xFFFFFC05, 0xFFAFFC04, /* last */
  129. };
  130. /* ------------------------------------------------------------------------- */
  131. #define CONFIG_SYS_PC4 0x0800
  132. #define CONFIG_SYS_DS1 CONFIG_SYS_PC4
  133. /*
  134. * Very early board init code (fpga boot, etc.)
  135. */
  136. int board_early_init_f (void)
  137. {
  138. volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
  139. /*
  140. * Light up the red led on ELPT860 pcb (DS1) (PCDAT)
  141. */
  142. immr->im_ioport.iop_pcdat &= ~CONFIG_SYS_DS1; /* PCDAT (DS1 = 0) */
  143. immr->im_ioport.iop_pcpar &= ~CONFIG_SYS_DS1; /* PCPAR (0=general purpose I/O) */
  144. immr->im_ioport.iop_pcdir |= CONFIG_SYS_DS1; /* PCDIR (I/O: 0=input, 1=output) */
  145. return (0); /* success */
  146. }
  147. /*
  148. * Check Board Identity:
  149. *
  150. * Test ELPT860 ID string
  151. *
  152. * Return 1 if no second DRAM bank, otherwise returns 0
  153. */
  154. int checkboard (void)
  155. {
  156. char buf[64];
  157. int i = getenv_f("serial#", buf, sizeof(buf));
  158. if ((i < 0) || strncmp(buf, "ELPT860", 7))
  159. printf ("### No HW ID - assuming ELPT860\n");
  160. return (0); /* success */
  161. }
  162. /* ------------------------------------------------------------------------- */
  163. phys_size_t initdram (int board_type)
  164. {
  165. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  166. volatile memctl8xx_t *memctl = &immap->im_memctl;
  167. long int size8, size9;
  168. long int size_b0 = 0;
  169. /*
  170. * This sequence initializes SDRAM chips on ELPT860 board
  171. */
  172. upmconfig (UPMA, (uint *) init_sdram_table,
  173. sizeof (init_sdram_table) / sizeof (uint));
  174. memctl->memc_mptpr = 0x0200;
  175. memctl->memc_mamr = 0x18002111;
  176. memctl->memc_mar = 0x00000088;
  177. memctl->memc_mcr = 0x80002000; /* CS1: SDRAM bank 0 */
  178. upmconfig (UPMA, (uint *) sdram_table,
  179. sizeof (sdram_table) / sizeof (uint));
  180. /*
  181. * Preliminary prescaler for refresh (depends on number of
  182. * banks): This value is selected for four cycles every 62.4 us
  183. * with two SDRAM banks or four cycles every 31.2 us with one
  184. * bank. It will be adjusted after memory sizing.
  185. */
  186. memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_8K;
  187. /*
  188. * The following value is used as an address (i.e. opcode) for
  189. * the LOAD MODE REGISTER COMMAND during SDRAM initialisation. If
  190. * the port size is 32bit the SDRAM does NOT "see" the lower two
  191. * address lines, i.e. mar=0x00000088 -> opcode=0x00000022 for
  192. * MICRON SDRAMs:
  193. * -> 0 00 010 0 010
  194. * | | | | +- Burst Length = 4
  195. * | | | +----- Burst Type = Sequential
  196. * | | +------- CAS Latency = 2
  197. * | +----------- Operating Mode = Standard
  198. * +-------------- Write Burst Mode = Programmed Burst Length
  199. */
  200. memctl->memc_mar = 0x00000088;
  201. /*
  202. * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
  203. * preliminary addresses - these have to be modified after the
  204. * SDRAM size has been determined.
  205. */
  206. memctl->memc_or1 = CONFIG_SYS_OR1_PRELIM;
  207. memctl->memc_br1 = CONFIG_SYS_BR1_PRELIM;
  208. memctl->memc_mamr = CONFIG_SYS_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
  209. udelay (200);
  210. /* perform SDRAM initializsation sequence */
  211. memctl->memc_mcr = 0x80002105; /* CS1: SDRAM bank 0 */
  212. udelay (1);
  213. memctl->memc_mcr = 0x80002230; /* CS1: SDRAM bank 0 - execute twice */
  214. udelay (1);
  215. memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
  216. udelay (1000);
  217. /*
  218. * Check Bank 0 Memory Size for re-configuration
  219. *
  220. * try 8 column mode
  221. */
  222. size8 = dram_size (CONFIG_SYS_MAMR_8COL,
  223. SDRAM_BASE1_PRELIM, SDRAM_MAX_SIZE);
  224. udelay (1000);
  225. /*
  226. * try 9 column mode
  227. */
  228. size9 = dram_size (CONFIG_SYS_MAMR_9COL,
  229. SDRAM_BASE1_PRELIM, SDRAM_MAX_SIZE);
  230. if (size8 < size9) { /* leave configuration at 9 columns */
  231. size_b0 = size9;
  232. /* debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20); */
  233. } else { /* back to 8 columns */
  234. size_b0 = size8;
  235. memctl->memc_mamr = CONFIG_SYS_MAMR_8COL;
  236. udelay (500);
  237. /* debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20); */
  238. }
  239. udelay (1000);
  240. /*
  241. * Adjust refresh rate depending on SDRAM type, both banks
  242. * For types > 128 MBit leave it at the current (fast) rate
  243. */
  244. if (size_b0 < 0x02000000) {
  245. /* reduce to 15.6 us (62.4 us / quad) */
  246. memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_4K;
  247. udelay (1000);
  248. }
  249. /*
  250. * Final mapping: map bigger bank first
  251. */
  252. memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
  253. memctl->memc_br1 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
  254. {
  255. unsigned long reg;
  256. /* adjust refresh rate depending on SDRAM type, one bank */
  257. reg = memctl->memc_mptpr;
  258. reg >>= 1; /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */
  259. memctl->memc_mptpr = reg;
  260. }
  261. udelay (10000);
  262. return (size_b0);
  263. }
  264. /* ------------------------------------------------------------------------- */
  265. /*
  266. * Check memory range for valid RAM. A simple memory test determines
  267. * the actually available RAM size between addresses `base' and
  268. * `base + maxsize'. Some (not all) hardware errors are detected:
  269. * - short between address lines
  270. * - short between data lines
  271. */
  272. static long int
  273. dram_size (long int mamr_value, long int *base, long int maxsize)
  274. {
  275. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  276. volatile memctl8xx_t *memctl = &immap->im_memctl;
  277. memctl->memc_mamr = mamr_value;
  278. return (get_ram_size (base, maxsize));
  279. }
  280. /* ------------------------------------------------------------------------- */
  281. #define CONFIG_SYS_PA1 0x4000
  282. #define CONFIG_SYS_PA2 0x2000
  283. #define CONFIG_SYS_LBKs (CONFIG_SYS_PA2 | CONFIG_SYS_PA1)
  284. void reset_phy (void)
  285. {
  286. volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
  287. /*
  288. * Ensure LBK LXT901 ethernet 1 & 2 = 0 ... for normal loopback in effect
  289. * and no AUI loopback
  290. */
  291. immr->im_ioport.iop_padat &= ~CONFIG_SYS_LBKs; /* PADAT (LBK eth 1&2 = 0) */
  292. immr->im_ioport.iop_papar &= ~CONFIG_SYS_LBKs; /* PAPAR (0=general purpose I/O) */
  293. immr->im_ioport.iop_padir |= CONFIG_SYS_LBKs; /* PADIR (I/O: 0=input, 1=output) */
  294. }