cpu.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. /*
  2. * (C) Copyright 2000-2006
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. /*
  24. * CPU specific code
  25. *
  26. * written or collected and sometimes rewritten by
  27. * Magnus Damm <damm@bitsmart.com>
  28. *
  29. * minor modifications by
  30. * Wolfgang Denk <wd@denx.de>
  31. */
  32. #include <common.h>
  33. #include <watchdog.h>
  34. #include <command.h>
  35. #include <asm/cache.h>
  36. #include <ppc4xx.h>
  37. #if !defined(CONFIG_405)
  38. DECLARE_GLOBAL_DATA_PTR;
  39. #endif
  40. #if defined(CONFIG_BOARD_RESET)
  41. void board_reset(void);
  42. #endif
  43. #if defined(CONFIG_440)
  44. #define FREQ_EBC (sys_info.freqEPB)
  45. #else
  46. #define FREQ_EBC (sys_info.freqPLB / sys_info.pllExtBusDiv)
  47. #endif
  48. #if defined(CONFIG_405GP) || \
  49. defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
  50. defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
  51. #define PCI_ASYNC
  52. int pci_async_enabled(void)
  53. {
  54. #if defined(CONFIG_405GP)
  55. return (mfdcr(strap) & PSR_PCI_ASYNC_EN);
  56. #endif
  57. #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
  58. defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
  59. unsigned long val;
  60. mfsdr(sdr_sdstp1, val);
  61. return (val & SDR0_SDSTP1_PAME_MASK);
  62. #endif
  63. }
  64. #endif
  65. #if defined(CONFIG_PCI) && !defined(CONFIG_IOP480) && !defined(CONFIG_405)
  66. int pci_arbiter_enabled(void)
  67. {
  68. #if defined(CONFIG_405GP)
  69. return (mfdcr(strap) & PSR_PCI_ARBIT_EN);
  70. #endif
  71. #if defined(CONFIG_405EP)
  72. return (mfdcr(cpc0_pci) & CPC0_PCI_ARBIT_EN);
  73. #endif
  74. #if defined(CONFIG_440GP)
  75. return (mfdcr(cpc0_strp1) & CPC0_STRP1_PAE_MASK);
  76. #endif
  77. #if defined(CONFIG_440GX) || \
  78. defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
  79. defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
  80. defined(CONFIG_440SP) || defined(CONFIG_440SPE)
  81. unsigned long val;
  82. mfsdr(sdr_sdstp1, val);
  83. return (val & SDR0_SDSTP1_PAE_MASK);
  84. #endif
  85. }
  86. #endif
  87. #if defined(CONFIG_405EP) || defined(CONFIG_440GX) || \
  88. defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
  89. defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
  90. defined(CONFIG_440SP) || defined(CONFIG_440SPE)
  91. #define I2C_BOOTROM
  92. int i2c_bootrom_enabled(void)
  93. {
  94. #if defined(CONFIG_405EP)
  95. return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP);
  96. #else
  97. unsigned long val;
  98. mfsdr(sdr_sdcs, val);
  99. return (val & SDR0_SDCS_SDD);
  100. #endif
  101. }
  102. #if defined(CONFIG_440GX)
  103. #define SDR0_PINSTP_SHIFT 29
  104. static char *bootstrap_str[] = {
  105. "EBC (16 bits)",
  106. "EBC (8 bits)",
  107. "EBC (32 bits)",
  108. "EBC (8 bits)",
  109. "PCI",
  110. "I2C (Addr 0x54)",
  111. "Reserved",
  112. "I2C (Addr 0x50)",
  113. };
  114. #endif
  115. #if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
  116. #define SDR0_PINSTP_SHIFT 30
  117. static char *bootstrap_str[] = {
  118. "EBC (8 bits)",
  119. "PCI",
  120. "I2C (Addr 0x54)",
  121. "I2C (Addr 0x50)",
  122. };
  123. #endif
  124. #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
  125. #define SDR0_PINSTP_SHIFT 29
  126. static char *bootstrap_str[] = {
  127. "EBC (8 bits)",
  128. "PCI",
  129. "NAND (8 bits)",
  130. "EBC (16 bits)",
  131. "EBC (16 bits)",
  132. "I2C (Addr 0x54)",
  133. "PCI",
  134. "I2C (Addr 0x52)",
  135. };
  136. #endif
  137. #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
  138. #define SDR0_PINSTP_SHIFT 29
  139. static char *bootstrap_str[] = {
  140. "EBC (8 bits)",
  141. "EBC (16 bits)",
  142. "EBC (16 bits)",
  143. "NAND (8 bits)",
  144. "PCI",
  145. "I2C (Addr 0x54)",
  146. "PCI",
  147. "I2C (Addr 0x52)",
  148. };
  149. #endif
  150. #if defined(SDR0_PINSTP_SHIFT)
  151. static int bootstrap_option(void)
  152. {
  153. unsigned long val;
  154. mfsdr(sdr_pinstp, val);
  155. return ((val & 0xe0000000) >> SDR0_PINSTP_SHIFT);
  156. }
  157. #endif /* SDR0_PINSTP_SHIFT */
  158. #endif
  159. #if defined(CONFIG_440)
  160. static int do_chip_reset(unsigned long sys0, unsigned long sys1);
  161. #endif
  162. int checkcpu (void)
  163. {
  164. #if !defined(CONFIG_405) /* not used on Xilinx 405 FPGA implementations */
  165. uint pvr = get_pvr();
  166. ulong clock = gd->cpu_clk;
  167. char buf[32];
  168. #if !defined(CONFIG_IOP480)
  169. char addstr[64] = "";
  170. sys_info_t sys_info;
  171. puts ("CPU: ");
  172. get_sys_info(&sys_info);
  173. puts("AMCC PowerPC 4");
  174. #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP)
  175. puts("05");
  176. #endif
  177. #if defined(CONFIG_440)
  178. puts("40");
  179. #endif
  180. switch (pvr) {
  181. case PVR_405GP_RB:
  182. puts("GP Rev. B");
  183. break;
  184. case PVR_405GP_RC:
  185. puts("GP Rev. C");
  186. break;
  187. case PVR_405GP_RD:
  188. puts("GP Rev. D");
  189. break;
  190. #ifdef CONFIG_405GP
  191. case PVR_405GP_RE: /* 405GP rev E and 405CR rev C have same PVR */
  192. puts("GP Rev. E");
  193. break;
  194. #endif
  195. case PVR_405CR_RA:
  196. puts("CR Rev. A");
  197. break;
  198. case PVR_405CR_RB:
  199. puts("CR Rev. B");
  200. break;
  201. #ifdef CONFIG_405CR
  202. case PVR_405CR_RC: /* 405GP rev E and 405CR rev C have same PVR */
  203. puts("CR Rev. C");
  204. break;
  205. #endif
  206. case PVR_405GPR_RB:
  207. puts("GPr Rev. B");
  208. break;
  209. case PVR_405EP_RB:
  210. puts("EP Rev. B");
  211. break;
  212. #if defined(CONFIG_440)
  213. case PVR_440GP_RB:
  214. puts("GP Rev. B");
  215. /* See errata 1.12: CHIP_4 */
  216. if ((mfdcr(cpc0_sys0) != mfdcr(cpc0_strp0)) ||
  217. (mfdcr(cpc0_sys1) != mfdcr(cpc0_strp1)) ){
  218. puts ( "\n\t CPC0_SYSx DCRs corrupted. "
  219. "Resetting chip ...\n");
  220. udelay( 1000 * 1000 ); /* Give time for serial buf to clear */
  221. do_chip_reset ( mfdcr(cpc0_strp0),
  222. mfdcr(cpc0_strp1) );
  223. }
  224. break;
  225. case PVR_440GP_RC:
  226. puts("GP Rev. C");
  227. break;
  228. case PVR_440GX_RA:
  229. puts("GX Rev. A");
  230. break;
  231. case PVR_440GX_RB:
  232. puts("GX Rev. B");
  233. break;
  234. case PVR_440GX_RC:
  235. puts("GX Rev. C");
  236. break;
  237. case PVR_440GX_RF:
  238. puts("GX Rev. F");
  239. break;
  240. case PVR_440EP_RA:
  241. puts("EP Rev. A");
  242. break;
  243. #ifdef CONFIG_440EP
  244. case PVR_440EP_RB: /* 440EP rev B and 440GR rev A have same PVR */
  245. puts("EP Rev. B");
  246. break;
  247. case PVR_440EP_RC: /* 440EP rev C and 440GR rev B have same PVR */
  248. puts("EP Rev. C");
  249. break;
  250. #endif /* CONFIG_440EP */
  251. #ifdef CONFIG_440GR
  252. case PVR_440GR_RA: /* 440EP rev B and 440GR rev A have same PVR */
  253. puts("GR Rev. A");
  254. break;
  255. case PVR_440GR_RB: /* 440EP rev C and 440GR rev B have same PVR */
  256. puts("GR Rev. B");
  257. break;
  258. #endif /* CONFIG_440GR */
  259. #endif /* CONFIG_440 */
  260. case PVR_440EPX1_RA:
  261. puts("EPx Rev. A");
  262. strcpy(addstr, "Security/Kasumi support");
  263. break;
  264. case PVR_440EPX2_RA:
  265. puts("EPx Rev. A");
  266. strcpy(addstr, "No Security/Kasumi support");
  267. break;
  268. case PVR_440GRX1_RA:
  269. puts("GRx Rev. A");
  270. strcpy(addstr, "Security/Kasumi support");
  271. break;
  272. case PVR_440GRX2_RA:
  273. puts("GRx Rev. A");
  274. strcpy(addstr, "No Security/Kasumi support");
  275. break;
  276. case PVR_440SP_RA:
  277. puts("SP Rev. A");
  278. break;
  279. case PVR_440SP_RB:
  280. puts("SP Rev. B");
  281. break;
  282. case PVR_440SPe_RA:
  283. puts("SPe Rev. A");
  284. break;
  285. case PVR_440SPe_RB:
  286. puts("SPe Rev. B");
  287. break;
  288. default:
  289. printf (" UNKNOWN (PVR=%08x)", pvr);
  290. break;
  291. }
  292. printf (" at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf, clock),
  293. sys_info.freqPLB / 1000000,
  294. sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
  295. FREQ_EBC / 1000000);
  296. if (addstr[0] != 0)
  297. printf(" %s\n", addstr);
  298. #if defined(I2C_BOOTROM)
  299. printf (" I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
  300. #if defined(SDR0_PINSTP_SHIFT)
  301. printf (" Bootstrap Option %c - ", (char)bootstrap_option() + 'A');
  302. printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
  303. #endif /* SDR0_PINSTP_SHIFT */
  304. #endif /* I2C_BOOTROM */
  305. #if defined(CONFIG_PCI)
  306. printf (" Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");
  307. #endif
  308. #if defined(PCI_ASYNC)
  309. if (pci_async_enabled()) {
  310. printf (", PCI async ext clock used");
  311. } else {
  312. printf (", PCI sync clock at %lu MHz",
  313. sys_info.freqPLB / sys_info.pllPciDiv / 1000000);
  314. }
  315. #endif
  316. #if defined(CONFIG_PCI)
  317. putc('\n');
  318. #endif
  319. #if defined(CONFIG_405EP)
  320. printf (" 16 kB I-Cache 16 kB D-Cache");
  321. #elif defined(CONFIG_440)
  322. printf (" 32 kB I-Cache 32 kB D-Cache");
  323. #else
  324. printf (" 16 kB I-Cache %d kB D-Cache",
  325. ((pvr | 0x00000001) == PVR_405GPR_RB) ? 16 : 8);
  326. #endif
  327. #endif /* !defined(CONFIG_IOP480) */
  328. #if defined(CONFIG_IOP480)
  329. printf ("PLX IOP480 (PVR=%08x)", pvr);
  330. printf (" at %s MHz:", strmhz(buf, clock));
  331. printf (" %u kB I-Cache", 4);
  332. printf (" %u kB D-Cache", 2);
  333. #endif
  334. #endif /* !defined(CONFIG_405) */
  335. putc ('\n');
  336. return 0;
  337. }
  338. #if defined (CONFIG_440SPE)
  339. int ppc440spe_revB() {
  340. unsigned int pvr;
  341. pvr = get_pvr();
  342. if (pvr == PVR_440SPe_RB)
  343. return 1;
  344. else
  345. return 0;
  346. }
  347. #endif
  348. /* ------------------------------------------------------------------------- */
  349. int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  350. {
  351. #if defined(CONFIG_BOARD_RESET)
  352. board_reset();
  353. #else
  354. #if defined(CFG_4xx_RESET_TYPE)
  355. mtspr(dbcr0, CFG_4xx_RESET_TYPE << 28);
  356. #else
  357. /*
  358. * Initiate system reset in debug control register DBCR
  359. */
  360. mtspr(dbcr0, 0x30000000);
  361. #endif /* defined(CFG_4xx_RESET_TYPE) */
  362. #endif /* defined(CONFIG_BOARD_RESET) */
  363. return 1;
  364. }
  365. #if defined(CONFIG_440)
  366. static int do_chip_reset (unsigned long sys0, unsigned long sys1)
  367. {
  368. /* Changes to cpc0_sys0 and cpc0_sys1 require chip
  369. * reset.
  370. */
  371. mtdcr (cntrl0, mfdcr (cntrl0) | 0x80000000); /* Set SWE */
  372. mtdcr (cpc0_sys0, sys0);
  373. mtdcr (cpc0_sys1, sys1);
  374. mtdcr (cntrl0, mfdcr (cntrl0) & ~0x80000000); /* Clr SWE */
  375. mtspr (dbcr0, 0x20000000); /* Reset the chip */
  376. return 1;
  377. }
  378. #endif
  379. /*
  380. * Get timebase clock frequency
  381. */
  382. unsigned long get_tbclk (void)
  383. {
  384. #if !defined(CONFIG_IOP480)
  385. sys_info_t sys_info;
  386. get_sys_info(&sys_info);
  387. return (sys_info.freqProcessor);
  388. #else
  389. return (66000000);
  390. #endif
  391. }
  392. #if defined(CONFIG_WATCHDOG)
  393. void
  394. watchdog_reset(void)
  395. {
  396. int re_enable = disable_interrupts();
  397. reset_4xx_watchdog();
  398. if (re_enable) enable_interrupts();
  399. }
  400. void
  401. reset_4xx_watchdog(void)
  402. {
  403. /*
  404. * Clear TSR(WIS) bit
  405. */
  406. mtspr(tsr, 0x40000000);
  407. }
  408. #endif /* CONFIG_WATCHDOG */