cpu_init.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /*
  2. * (C) Copyright 2000-2007
  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. #include <common.h>
  24. #include <watchdog.h>
  25. #include <ppc4xx_enet.h>
  26. #include <asm/processor.h>
  27. #include <asm/gpio.h>
  28. #include <ppc4xx.h>
  29. #if defined(CONFIG_405GP) || defined(CONFIG_405EP)
  30. DECLARE_GLOBAL_DATA_PTR;
  31. #endif
  32. #ifdef CFG_INIT_DCACHE_CS
  33. # if (CFG_INIT_DCACHE_CS == 0)
  34. # define PBxAP pb0ap
  35. # define PBxCR pb0cr
  36. # if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
  37. # define PBxAP_VAL CFG_EBC_PB0AP
  38. # define PBxCR_VAL CFG_EBC_PB0CR
  39. # endif
  40. # endif
  41. # if (CFG_INIT_DCACHE_CS == 1)
  42. # define PBxAP pb1ap
  43. # define PBxCR pb1cr
  44. # if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR))
  45. # define PBxAP_VAL CFG_EBC_PB1AP
  46. # define PBxCR_VAL CFG_EBC_PB1CR
  47. # endif
  48. # endif
  49. # if (CFG_INIT_DCACHE_CS == 2)
  50. # define PBxAP pb2ap
  51. # define PBxCR pb2cr
  52. # if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR))
  53. # define PBxAP_VAL CFG_EBC_PB2AP
  54. # define PBxCR_VAL CFG_EBC_PB2CR
  55. # endif
  56. # endif
  57. # if (CFG_INIT_DCACHE_CS == 3)
  58. # define PBxAP pb3ap
  59. # define PBxCR pb3cr
  60. # if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR))
  61. # define PBxAP_VAL CFG_EBC_PB3AP
  62. # define PBxCR_VAL CFG_EBC_PB3CR
  63. # endif
  64. # endif
  65. # if (CFG_INIT_DCACHE_CS == 4)
  66. # define PBxAP pb4ap
  67. # define PBxCR pb4cr
  68. # if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR))
  69. # define PBxAP_VAL CFG_EBC_PB4AP
  70. # define PBxCR_VAL CFG_EBC_PB4CR
  71. # endif
  72. # endif
  73. # if (CFG_INIT_DCACHE_CS == 5)
  74. # define PBxAP pb5ap
  75. # define PBxCR pb5cr
  76. # if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR))
  77. # define PBxAP_VAL CFG_EBC_PB5AP
  78. # define PBxCR_VAL CFG_EBC_PB5CR
  79. # endif
  80. # endif
  81. # if (CFG_INIT_DCACHE_CS == 6)
  82. # define PBxAP pb6ap
  83. # define PBxCR pb6cr
  84. # if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR))
  85. # define PBxAP_VAL CFG_EBC_PB6AP
  86. # define PBxCR_VAL CFG_EBC_PB6CR
  87. # endif
  88. # endif
  89. # if (CFG_INIT_DCACHE_CS == 7)
  90. # define PBxAP pb7ap
  91. # define PBxCR pb7cr
  92. # if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR))
  93. # define PBxAP_VAL CFG_EBC_PB7AP
  94. # define PBxCR_VAL CFG_EBC_PB7CR
  95. # endif
  96. # endif
  97. #endif /* CFG_INIT_DCACHE_CS */
  98. #ifndef CFG_PLL_RECONFIG
  99. #define CFG_PLL_RECONFIG 0
  100. #endif
  101. void reconfigure_pll(u32 new_cpu_freq)
  102. {
  103. #if defined(CONFIG_440EPX)
  104. int reset_needed = 0;
  105. u32 reg, temp;
  106. u32 prbdv0, target_prbdv0, /* CLK_PRIMBD */
  107. fwdva, target_fwdva, fwdvb, target_fwdvb, /* CLK_PLLD */
  108. fbdv, target_fbdv, lfbdv, target_lfbdv,
  109. perdv0, target_perdv0, /* CLK_PERD */
  110. spcid0, target_spcid0; /* CLK_SPCID */
  111. /* Reconfigure clocks if necessary.
  112. * See PPC440EPx User's Manual, sections 8.2 and 14 */
  113. if (new_cpu_freq == 667) {
  114. target_prbdv0 = 2;
  115. target_fwdva = 2;
  116. target_fwdvb = 4;
  117. target_fbdv = 20;
  118. target_lfbdv = 1;
  119. target_perdv0 = 4;
  120. target_spcid0 = 4;
  121. mfcpr(clk_primbd, reg);
  122. temp = (reg & PRBDV_MASK) >> 24;
  123. prbdv0 = temp ? temp : 8;
  124. if (prbdv0 != target_prbdv0) {
  125. reg &= ~PRBDV_MASK;
  126. reg |= ((target_prbdv0 == 8 ? 0 : target_prbdv0) << 24);
  127. mtcpr(clk_primbd, reg);
  128. reset_needed = 1;
  129. }
  130. mfcpr(clk_plld, reg);
  131. temp = (reg & PLLD_FWDVA_MASK) >> 16;
  132. fwdva = temp ? temp : 16;
  133. temp = (reg & PLLD_FWDVB_MASK) >> 8;
  134. fwdvb = temp ? temp : 8;
  135. temp = (reg & PLLD_FBDV_MASK) >> 24;
  136. fbdv = temp ? temp : 32;
  137. temp = (reg & PLLD_LFBDV_MASK);
  138. lfbdv = temp ? temp : 64;
  139. if (fwdva != target_fwdva || fbdv != target_fbdv || lfbdv != target_lfbdv) {
  140. reg &= ~(PLLD_FWDVA_MASK | PLLD_FWDVB_MASK |
  141. PLLD_FBDV_MASK | PLLD_LFBDV_MASK);
  142. reg |= ((target_fwdva == 16 ? 0 : target_fwdva) << 16) |
  143. ((target_fwdvb == 8 ? 0 : target_fwdvb) << 8) |
  144. ((target_fbdv == 32 ? 0 : target_fbdv) << 24) |
  145. (target_lfbdv == 64 ? 0 : target_lfbdv);
  146. mtcpr(clk_plld, reg);
  147. reset_needed = 1;
  148. }
  149. mfcpr(clk_perd, reg);
  150. perdv0 = (reg & CPR0_PERD_PERDV0_MASK) >> 24;
  151. if (perdv0 != target_perdv0) {
  152. reg &= ~CPR0_PERD_PERDV0_MASK;
  153. reg |= (target_perdv0 << 24);
  154. mtcpr(clk_perd, reg);
  155. reset_needed = 1;
  156. }
  157. mfcpr(clk_spcid, reg);
  158. temp = (reg & CPR0_SPCID_SPCIDV0_MASK) >> 24;
  159. spcid0 = temp ? temp : 4;
  160. if (spcid0 != target_spcid0) {
  161. reg &= ~CPR0_SPCID_SPCIDV0_MASK;
  162. reg |= ((target_spcid0 == 4 ? 0 : target_spcid0) << 24);
  163. mtcpr(clk_spcid, reg);
  164. reset_needed = 1;
  165. }
  166. /* Set reload inhibit so configuration will persist across
  167. * processor resets */
  168. mfcpr(clk_icfg, reg);
  169. reg &= ~CPR0_ICFG_RLI_MASK;
  170. reg |= 1 << 31;
  171. mtcpr(clk_icfg, reg);
  172. }
  173. /* Reset processor if configuration changed */
  174. if (reset_needed) {
  175. __asm__ __volatile__ ("sync; isync");
  176. mtspr(dbcr0, 0x20000000);
  177. }
  178. #endif
  179. }
  180. /*
  181. * Breath some life into the CPU...
  182. *
  183. * Reconfigure PLL if necessary,
  184. * set up the memory map,
  185. * initialize a bunch of registers
  186. */
  187. void
  188. cpu_init_f (void)
  189. {
  190. #if defined(CONFIG_WATCHDOG)
  191. unsigned long val;
  192. #endif
  193. reconfigure_pll(CFG_PLL_RECONFIG);
  194. #if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && !defined(CFG_4xx_GPIO_TABLE)
  195. /*
  196. * GPIO0 setup (select GPIO or alternate function)
  197. */
  198. #if defined(CFG_GPIO0_OR)
  199. out32(GPIO0_OR, CFG_GPIO0_OR); /* set initial state of output pins */
  200. #endif
  201. #if defined(CFG_GPIO0_ODR)
  202. out32(GPIO0_ODR, CFG_GPIO0_ODR); /* open-drain select */
  203. #endif
  204. out32(GPIO0_OSRH, CFG_GPIO0_OSRH); /* output select */
  205. out32(GPIO0_OSRL, CFG_GPIO0_OSRL);
  206. out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */
  207. out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L);
  208. out32(GPIO0_TSRH, CFG_GPIO0_TSRH); /* three-state select */
  209. out32(GPIO0_TSRL, CFG_GPIO0_TSRL);
  210. #if defined(CFG_GPIO0_ISR2H)
  211. out32(GPIO0_ISR2H, CFG_GPIO0_ISR2H);
  212. out32(GPIO0_ISR2L, CFG_GPIO0_ISR2L);
  213. #endif
  214. #if defined (CFG_GPIO0_TCR)
  215. out32(GPIO0_TCR, CFG_GPIO0_TCR); /* enable output driver for outputs */
  216. #endif
  217. #endif /* CONFIG_405EP ... && !CFG_4xx_GPIO_TABLE */
  218. #if defined (CONFIG_405EP)
  219. /*
  220. * Set EMAC noise filter bits
  221. */
  222. mtdcr(cpc0_epctl, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE);
  223. /*
  224. * Enable the internal PCI arbiter
  225. */
  226. mtdcr(cpc0_pci, mfdcr(cpc0_pci) | CPC0_PCI_HOST_CFG_EN | CPC0_PCI_ARBIT_EN);
  227. #endif /* CONFIG_405EP */
  228. #if defined(CFG_4xx_GPIO_TABLE)
  229. gpio_set_chip_configuration();
  230. #endif /* CFG_4xx_GPIO_TABLE */
  231. /*
  232. * External Bus Controller (EBC) Setup
  233. */
  234. #if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
  235. #if (defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
  236. defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
  237. defined(CONFIG_405EX) || defined(CONFIG_405))
  238. /*
  239. * Move the next instructions into icache, since these modify the flash
  240. * we are running from!
  241. */
  242. asm volatile(" bl 0f" ::: "lr");
  243. asm volatile("0: mflr 3" ::: "r3");
  244. asm volatile(" addi 4, 0, 14" ::: "r4");
  245. asm volatile(" mtctr 4" ::: "ctr");
  246. asm volatile("1: icbt 0, 3");
  247. asm volatile(" addi 3, 3, 32" ::: "r3");
  248. asm volatile(" bdnz 1b" ::: "ctr", "cr0");
  249. asm volatile(" addis 3, 0, 0x0" ::: "r3");
  250. asm volatile(" ori 3, 3, 0xA000" ::: "r3");
  251. asm volatile(" mtctr 3" ::: "ctr");
  252. asm volatile("2: bdnz 2b" ::: "ctr", "cr0");
  253. #endif
  254. mtebc(pb0ap, CFG_EBC_PB0AP);
  255. mtebc(pb0cr, CFG_EBC_PB0CR);
  256. #endif
  257. #if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR) && !(CFG_INIT_DCACHE_CS == 1))
  258. mtebc(pb1ap, CFG_EBC_PB1AP);
  259. mtebc(pb1cr, CFG_EBC_PB1CR);
  260. #endif
  261. #if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR) && !(CFG_INIT_DCACHE_CS == 2))
  262. mtebc(pb2ap, CFG_EBC_PB2AP);
  263. mtebc(pb2cr, CFG_EBC_PB2CR);
  264. #endif
  265. #if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR) && !(CFG_INIT_DCACHE_CS == 3))
  266. mtebc(pb3ap, CFG_EBC_PB3AP);
  267. mtebc(pb3cr, CFG_EBC_PB3CR);
  268. #endif
  269. #if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR) && !(CFG_INIT_DCACHE_CS == 4))
  270. mtebc(pb4ap, CFG_EBC_PB4AP);
  271. mtebc(pb4cr, CFG_EBC_PB4CR);
  272. #endif
  273. #if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR) && !(CFG_INIT_DCACHE_CS == 5))
  274. mtebc(pb5ap, CFG_EBC_PB5AP);
  275. mtebc(pb5cr, CFG_EBC_PB5CR);
  276. #endif
  277. #if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR) && !(CFG_INIT_DCACHE_CS == 6))
  278. mtebc(pb6ap, CFG_EBC_PB6AP);
  279. mtebc(pb6cr, CFG_EBC_PB6CR);
  280. #endif
  281. #if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR) && !(CFG_INIT_DCACHE_CS == 7))
  282. mtebc(pb7ap, CFG_EBC_PB7AP);
  283. mtebc(pb7cr, CFG_EBC_PB7CR);
  284. #endif
  285. #if defined (CFG_EBC_CFG)
  286. mtebc(EBC0_CFG, CFG_EBC_CFG);
  287. #endif
  288. #if defined(CONFIG_WATCHDOG)
  289. val = mfspr(tcr);
  290. #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
  291. val |= 0xb8000000; /* generate system reset after 1.34 seconds */
  292. #elif defined(CONFIG_440EPX)
  293. val |= 0xb0000000; /* generate system reset after 1.34 seconds */
  294. #else
  295. val |= 0xf0000000; /* generate system reset after 2.684 seconds */
  296. #endif
  297. #if defined(CFG_4xx_RESET_TYPE)
  298. val &= ~0x30000000; /* clear WRC bits */
  299. val |= CFG_4xx_RESET_TYPE << 28; /* set board specific WRC type */
  300. #endif
  301. mtspr(tcr, val);
  302. val = mfspr(tsr);
  303. val |= 0x80000000; /* enable watchdog timer */
  304. mtspr(tsr, val);
  305. reset_4xx_watchdog();
  306. #endif /* CONFIG_WATCHDOG */
  307. }
  308. /*
  309. * initialize higher level parts of CPU like time base and timers
  310. */
  311. int cpu_init_r (void)
  312. {
  313. #if defined(CONFIG_405GP) || defined(CONFIG_405EP)
  314. bd_t *bd = gd->bd;
  315. unsigned long reg;
  316. #if defined(CONFIG_405GP)
  317. uint pvr = get_pvr();
  318. #endif
  319. #ifdef CFG_INIT_DCACHE_CS
  320. /*
  321. * Flush and invalidate dcache, then disable CS for temporary stack.
  322. * Afterwards, this CS can be used for other purposes
  323. */
  324. dcache_disable(); /* flush and invalidate dcache */
  325. mtebc(PBxAP, 0);
  326. mtebc(PBxCR, 0); /* disable CS for temporary stack */
  327. #if (defined(PBxAP_VAL) && defined(PBxCR_VAL))
  328. /*
  329. * Write new value into CS register
  330. */
  331. mtebc(PBxAP, PBxAP_VAL);
  332. mtebc(PBxCR, PBxCR_VAL);
  333. #endif
  334. #endif /* CFG_INIT_DCACHE_CS */
  335. /*
  336. * Write Ethernetaddress into on-chip register
  337. */
  338. reg = 0x00000000;
  339. reg |= bd->bi_enetaddr[0]; /* set high address */
  340. reg = reg << 8;
  341. reg |= bd->bi_enetaddr[1];
  342. out32 (EMAC_IAH, reg);
  343. reg = 0x00000000;
  344. reg |= bd->bi_enetaddr[2]; /* set low address */
  345. reg = reg << 8;
  346. reg |= bd->bi_enetaddr[3];
  347. reg = reg << 8;
  348. reg |= bd->bi_enetaddr[4];
  349. reg = reg << 8;
  350. reg |= bd->bi_enetaddr[5];
  351. out32 (EMAC_IAL, reg);
  352. #if defined(CONFIG_405GP)
  353. /*
  354. * Set edge conditioning circuitry on PPC405GPr
  355. * for compatibility to existing PPC405GP designs.
  356. */
  357. if ((pvr & 0xfffffff0) == (PVR_405GPR_RB & 0xfffffff0)) {
  358. mtdcr(ecr, 0x60606000);
  359. }
  360. #endif /* defined(CONFIG_405GP) */
  361. #endif /* defined(CONFIG_405GP) || defined(CONFIG_405EP) */
  362. return (0);
  363. }