cpu.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /*
  2. * Copyright 2006 Freescale Semiconductor
  3. * Jeff Brown
  4. * Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * 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 <watchdog.h>
  26. #include <command.h>
  27. #include <asm/cache.h>
  28. #include <asm/mmu.h>
  29. #include <mpc86xx.h>
  30. #include <tsec.h>
  31. #include <asm/fsl_law.h>
  32. int
  33. checkcpu(void)
  34. {
  35. sys_info_t sysinfo;
  36. uint pvr, svr;
  37. uint ver;
  38. uint major, minor;
  39. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  40. volatile ccsr_gur_t *gur = &immap->im_gur;
  41. puts("Freescale PowerPC\n");
  42. pvr = get_pvr();
  43. ver = PVR_VER(pvr);
  44. major = PVR_MAJ(pvr);
  45. minor = PVR_MIN(pvr);
  46. puts("CPU:\n");
  47. puts(" Core: ");
  48. switch (ver) {
  49. case PVR_VER(PVR_86xx):
  50. {
  51. uint msscr0 = mfspr(MSSCR0);
  52. printf("E600 Core %d", (msscr0 & 0x20) ? 1 : 0 );
  53. if (gur->pordevsr & MPC86xx_PORDEVSR_CORE1TE)
  54. puts("\n Core1Translation Enabled");
  55. debug(" (MSSCR0=%x, PORDEVSR=%x)", msscr0, gur->pordevsr);
  56. }
  57. break;
  58. default:
  59. puts("Unknown");
  60. break;
  61. }
  62. printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
  63. svr = get_svr();
  64. ver = SVR_SOC_VER(svr);
  65. major = SVR_MAJ(svr);
  66. minor = SVR_MIN(svr);
  67. puts(" System: ");
  68. switch (ver) {
  69. case SVR_8641:
  70. if (SVR_SUBVER(svr) == 1) {
  71. puts("8641D");
  72. } else {
  73. puts("8641");
  74. }
  75. break;
  76. case SVR_8610:
  77. puts("8610");
  78. break;
  79. default:
  80. puts("Unknown");
  81. break;
  82. }
  83. printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
  84. get_sys_info(&sysinfo);
  85. puts(" Clocks: ");
  86. printf("CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000);
  87. printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000);
  88. printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000);
  89. if (sysinfo.freqLocalBus > LCRR_CLKDIV) {
  90. printf("LBC:%4lu MHz\n", sysinfo.freqLocalBus / 1000000);
  91. } else {
  92. printf("LBC: unknown (LCRR[CLKDIV] = 0x%02x)\n",
  93. sysinfo.freqLocalBus);
  94. }
  95. puts(" L2: ");
  96. if (get_l2cr() & 0x80000000)
  97. puts("Enabled\n");
  98. else
  99. puts("Disabled\n");
  100. return 0;
  101. }
  102. static inline void
  103. soft_restart(unsigned long addr)
  104. {
  105. #if !defined(CONFIG_MPC8641HPCN) && !defined(CONFIG_MPC8610HPCD)
  106. /*
  107. * SRR0 has system reset vector, SRR1 has default MSR value
  108. * rfi restores MSR from SRR1 and sets the PC to the SRR0 value
  109. */
  110. __asm__ __volatile__ ("mtspr 26, %0" :: "r" (addr));
  111. __asm__ __volatile__ ("li 4, (1 << 6)" ::: "r4");
  112. __asm__ __volatile__ ("mtspr 27, 4");
  113. __asm__ __volatile__ ("rfi");
  114. #else /* CONFIG_MPC8641HPCN */
  115. out8(PIXIS_BASE + PIXIS_RST, 0);
  116. #endif /* !CONFIG_MPC8641HPCN */
  117. while (1) ; /* not reached */
  118. }
  119. /*
  120. * No generic way to do board reset. Simply call soft_reset.
  121. */
  122. void
  123. do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  124. {
  125. #if !defined(CONFIG_MPC8641HPCN) && !defined(CONFIG_MPC8610HPCD)
  126. #ifdef CONFIG_SYS_RESET_ADDRESS
  127. ulong addr = CONFIG_SYS_RESET_ADDRESS;
  128. #else
  129. /*
  130. * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address,
  131. * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid
  132. * address. Better pick an address known to be invalid on your
  133. * system and assign it to CONFIG_SYS_RESET_ADDRESS.
  134. */
  135. ulong addr = CONFIG_SYS_MONITOR_BASE - sizeof(ulong);
  136. #endif
  137. /* flush and disable I/D cache */
  138. __asm__ __volatile__ ("mfspr 3, 1008" ::: "r3");
  139. __asm__ __volatile__ ("ori 5, 5, 0xcc00" ::: "r5");
  140. __asm__ __volatile__ ("ori 4, 3, 0xc00" ::: "r4");
  141. __asm__ __volatile__ ("andc 5, 3, 5" ::: "r5");
  142. __asm__ __volatile__ ("sync");
  143. __asm__ __volatile__ ("mtspr 1008, 4");
  144. __asm__ __volatile__ ("isync");
  145. __asm__ __volatile__ ("sync");
  146. __asm__ __volatile__ ("mtspr 1008, 5");
  147. __asm__ __volatile__ ("isync");
  148. __asm__ __volatile__ ("sync");
  149. soft_restart(addr);
  150. #else /* CONFIG_MPC8641HPCN */
  151. out8(PIXIS_BASE + PIXIS_RST, 0);
  152. #endif /* !CONFIG_MPC8641HPCN */
  153. while (1) ; /* not reached */
  154. }
  155. /*
  156. * Get timebase clock frequency
  157. */
  158. unsigned long
  159. get_tbclk(void)
  160. {
  161. sys_info_t sys_info;
  162. get_sys_info(&sys_info);
  163. return (sys_info.freqSystemBus + 3L) / 4L;
  164. }
  165. #if defined(CONFIG_WATCHDOG)
  166. void
  167. watchdog_reset(void)
  168. {
  169. #if defined(CONFIG_MPC8610)
  170. /*
  171. * This actually feed the hard enabled watchdog.
  172. */
  173. volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
  174. volatile ccsr_wdt_t *wdt = &immap->im_wdt;
  175. volatile ccsr_gur_t *gur = &immap->im_gur;
  176. u32 tmp = gur->pordevsr;
  177. if (tmp & 0x4000) {
  178. wdt->swsrr = 0x556c;
  179. wdt->swsrr = 0xaa39;
  180. }
  181. #endif
  182. }
  183. #endif /* CONFIG_WATCHDOG */
  184. #if defined(CONFIG_DDR_ECC)
  185. void
  186. dma_init(void)
  187. {
  188. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  189. volatile ccsr_dma_t *dma = &immap->im_dma;
  190. dma->satr0 = 0x00040000;
  191. dma->datr0 = 0x00040000;
  192. asm("sync; isync");
  193. }
  194. uint
  195. dma_check(void)
  196. {
  197. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  198. volatile ccsr_dma_t *dma = &immap->im_dma;
  199. volatile uint status = dma->sr0;
  200. /* While the channel is busy, spin */
  201. while ((status & 4) == 4) {
  202. status = dma->sr0;
  203. }
  204. if (status != 0) {
  205. printf("DMA Error: status = %x\n", status);
  206. }
  207. return status;
  208. }
  209. int
  210. dma_xfer(void *dest, uint count, void *src)
  211. {
  212. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  213. volatile ccsr_dma_t *dma = &immap->im_dma;
  214. dma->dar0 = (uint) dest;
  215. dma->sar0 = (uint) src;
  216. dma->bcr0 = count;
  217. dma->mr0 = 0xf000004;
  218. asm("sync;isync");
  219. dma->mr0 = 0xf000005;
  220. asm("sync;isync");
  221. return dma_check();
  222. }
  223. #endif /* CONFIG_DDR_ECC */
  224. /*
  225. * Print out the state of various machine registers.
  226. * Currently prints out LAWs, BR0/OR0, and BATs
  227. */
  228. void mpc86xx_reginfo(void)
  229. {
  230. immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
  231. ccsr_lbc_t *lbc = &immap->im_lbc;
  232. print_bats();
  233. print_laws();
  234. printf ("Local Bus Controller Registers\n"
  235. "\tBR0\t0x%08X\tOR0\t0x%08X \n", in_be32(&lbc->br0), in_be32(&lbc->or0));
  236. printf("\tBR1\t0x%08X\tOR1\t0x%08X \n", in_be32(&lbc->br1), in_be32(&lbc->or1));
  237. printf("\tBR2\t0x%08X\tOR2\t0x%08X \n", in_be32(&lbc->br2), in_be32(&lbc->or2));
  238. printf("\tBR3\t0x%08X\tOR3\t0x%08X \n", in_be32(&lbc->br3), in_be32(&lbc->or3));
  239. printf("\tBR4\t0x%08X\tOR4\t0x%08X \n", in_be32(&lbc->br4), in_be32(&lbc->or4));
  240. printf("\tBR5\t0x%08X\tOR5\t0x%08X \n", in_be32(&lbc->br5), in_be32(&lbc->or5));
  241. printf("\tBR6\t0x%08X\tOR6\t0x%08X \n", in_be32(&lbc->br6), in_be32(&lbc->or6));
  242. printf("\tBR7\t0x%08X\tOR7\t0x%08X \n", in_be32(&lbc->br7), in_be32(&lbc->or7));
  243. }
  244. /*
  245. * Initializes on-chip ethernet controllers.
  246. * to override, implement board_eth_init()
  247. */
  248. int cpu_eth_init(bd_t *bis)
  249. {
  250. #if defined(CONFIG_TSEC_ENET)
  251. tsec_standard_init(bis);
  252. #endif
  253. return 0;
  254. }