cpu.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
  4. */
  5. /*
  6. * CPU specific code for the MPC83xx family.
  7. *
  8. * Derived from the MPC8260 and MPC85xx.
  9. */
  10. #include <common.h>
  11. #include <cpu_func.h>
  12. #include <irq_func.h>
  13. #include <net.h>
  14. #include <time.h>
  15. #include <vsprintf.h>
  16. #include <watchdog.h>
  17. #include <command.h>
  18. #include <mpc83xx.h>
  19. #include <asm/processor.h>
  20. #include <linux/libfdt.h>
  21. #include <tsec.h>
  22. #include <netdev.h>
  23. #include <fsl_esdhc.h>
  24. #if defined(CONFIG_BOOTCOUNT_LIMIT) && !defined(CONFIG_ARCH_MPC831X)
  25. #include <linux/immap_qe.h>
  26. #include <asm/io.h>
  27. #endif
  28. DECLARE_GLOBAL_DATA_PTR;
  29. #ifndef CONFIG_CPU_MPC83XX
  30. int checkcpu(void)
  31. {
  32. volatile immap_t *immr;
  33. ulong clock = gd->cpu_clk;
  34. u32 pvr = get_pvr();
  35. u32 spridr;
  36. char buf[32];
  37. int ret;
  38. int i;
  39. const struct cpu_type {
  40. char name[15];
  41. u32 partid;
  42. } cpu_type_list [] = {
  43. CPU_TYPE_ENTRY(8308),
  44. CPU_TYPE_ENTRY(8309),
  45. CPU_TYPE_ENTRY(8311),
  46. CPU_TYPE_ENTRY(8313),
  47. CPU_TYPE_ENTRY(8314),
  48. CPU_TYPE_ENTRY(8315),
  49. CPU_TYPE_ENTRY(8321),
  50. CPU_TYPE_ENTRY(8323),
  51. CPU_TYPE_ENTRY(8343),
  52. CPU_TYPE_ENTRY(8347_TBGA_),
  53. CPU_TYPE_ENTRY(8347_PBGA_),
  54. CPU_TYPE_ENTRY(8349),
  55. CPU_TYPE_ENTRY(8358_TBGA_),
  56. CPU_TYPE_ENTRY(8358_PBGA_),
  57. CPU_TYPE_ENTRY(8360),
  58. CPU_TYPE_ENTRY(8377),
  59. CPU_TYPE_ENTRY(8378),
  60. CPU_TYPE_ENTRY(8379),
  61. };
  62. immr = (immap_t *)CONFIG_SYS_IMMR;
  63. ret = prt_83xx_rsr();
  64. if (ret)
  65. return ret;
  66. puts("CPU: ");
  67. switch (pvr & 0xffff0000) {
  68. case PVR_E300C1:
  69. printf("e300c1, ");
  70. break;
  71. case PVR_E300C2:
  72. printf("e300c2, ");
  73. break;
  74. case PVR_E300C3:
  75. printf("e300c3, ");
  76. break;
  77. case PVR_E300C4:
  78. printf("e300c4, ");
  79. break;
  80. default:
  81. printf("Unknown core, ");
  82. }
  83. spridr = immr->sysconf.spridr;
  84. for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
  85. if (cpu_type_list[i].partid == PARTID_NO_E(spridr)) {
  86. puts("MPC");
  87. puts(cpu_type_list[i].name);
  88. if (IS_E_PROCESSOR(spridr))
  89. puts("E");
  90. if ((SPR_FAMILY(spridr) == SPR_834X_FAMILY ||
  91. SPR_FAMILY(spridr) == SPR_836X_FAMILY) &&
  92. REVID_MAJOR(spridr) >= 2)
  93. puts("A");
  94. printf(", Rev: %d.%d", REVID_MAJOR(spridr),
  95. REVID_MINOR(spridr));
  96. break;
  97. }
  98. if (i == ARRAY_SIZE(cpu_type_list))
  99. printf("(SPRIDR %08x unknown), ", spridr);
  100. printf(" at %s MHz, ", strmhz(buf, clock));
  101. printf("CSB: %s MHz\n", strmhz(buf, gd->arch.csb_clk));
  102. return 0;
  103. }
  104. #endif
  105. #ifndef CONFIG_SYSRESET
  106. int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
  107. {
  108. ulong msr;
  109. #ifndef MPC83xx_RESET
  110. ulong addr;
  111. #endif
  112. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  113. puts("Resetting the board.\n");
  114. #ifdef MPC83xx_RESET
  115. /* Interrupts and MMU off */
  116. msr = mfmsr();
  117. msr &= ~(MSR_EE | MSR_IR | MSR_DR);
  118. mtmsr(msr);
  119. /* enable Reset Control Reg */
  120. immap->reset.rpr = 0x52535445;
  121. sync();
  122. isync();
  123. /* confirm Reset Control Reg is enabled */
  124. while(!((immap->reset.rcer) & RCER_CRE))
  125. ;
  126. udelay(200);
  127. /* perform reset, only one bit */
  128. immap->reset.rcr = RCR_SWHR;
  129. #else /* ! MPC83xx_RESET */
  130. immap->reset.rmr = RMR_CSRE; /* Checkstop Reset enable */
  131. /* Interrupts and MMU off */
  132. msr = mfmsr();
  133. msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR);
  134. mtmsr(msr);
  135. /*
  136. * Trying to execute the next instruction at a non-existing address
  137. * should cause a machine check, resulting in reset
  138. */
  139. addr = CONFIG_SYS_RESET_ADDRESS;
  140. ((void (*)(void)) addr) ();
  141. #endif /* MPC83xx_RESET */
  142. return 1;
  143. }
  144. #endif
  145. /*
  146. * Get timebase clock frequency (like cpu_clk in Hz)
  147. */
  148. #ifndef CONFIG_TIMER
  149. unsigned long get_tbclk(void)
  150. {
  151. return (gd->bus_clk + 3L) / 4L;
  152. }
  153. #endif
  154. #if defined(CONFIG_WATCHDOG)
  155. void watchdog_reset (void)
  156. {
  157. int re_enable = disable_interrupts();
  158. /* Reset the 83xx watchdog */
  159. volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
  160. immr->wdt.swsrr = 0x556c;
  161. immr->wdt.swsrr = 0xaa39;
  162. if (re_enable)
  163. enable_interrupts();
  164. }
  165. #endif
  166. #ifndef CONFIG_DM_ETH
  167. /*
  168. * Initializes on-chip ethernet controllers.
  169. * to override, implement board_eth_init()
  170. */
  171. int cpu_eth_init(bd_t *bis)
  172. {
  173. #if defined(CONFIG_UEC_ETH)
  174. uec_standard_init(bis);
  175. #endif
  176. #if defined(CONFIG_TSEC_ENET)
  177. tsec_standard_init(bis);
  178. #endif
  179. return 0;
  180. }
  181. #endif /* !CONFIG_DM_ETH */
  182. /*
  183. * Initializes on-chip MMC controllers.
  184. * to override, implement board_mmc_init()
  185. */
  186. int cpu_mmc_init(bd_t *bis)
  187. {
  188. #ifdef CONFIG_FSL_ESDHC
  189. return fsl_esdhc_mmc_init(bis);
  190. #else
  191. return 0;
  192. #endif
  193. }
  194. void ppcDWstore(unsigned int *addr, unsigned int *value)
  195. {
  196. asm("lfd 1, 0(%1)\n\t"
  197. "stfd 1, 0(%0)"
  198. :
  199. : "r" (addr), "r" (value)
  200. : "memory");
  201. }
  202. void ppcDWload(unsigned int *addr, unsigned int *ret)
  203. {
  204. asm("lfd 1, 0(%0)\n\t"
  205. "stfd 1, 0(%1)"
  206. :
  207. : "r" (addr), "r" (ret)
  208. : "memory");
  209. }