cpu.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * (C) Copyright 2002
  3. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  4. * Marius Groeger <mgroeger@sysgo.de>
  5. *
  6. * (C) Copyright 2002
  7. * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  8. * Alex Zuepke <azu@sysgo.de>
  9. *
  10. * See file CREDITS for list of people who contributed to this
  11. * project.
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License as
  15. * published by the Free Software Foundation; either version 2 of
  16. * the License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  26. * MA 02111-1307 USA
  27. */
  28. /*
  29. * CPU specific code
  30. */
  31. #include <asm/io.h>
  32. #include <asm/system.h>
  33. #include <command.h>
  34. #include <common.h>
  35. #include <asm/arch/pxa-regs.h>
  36. static void cache_flush(void);
  37. int cleanup_before_linux (void)
  38. {
  39. /*
  40. * this function is called just before we call linux
  41. * it prepares the processor for linux
  42. *
  43. * just disable everything that can disturb booting linux
  44. */
  45. disable_interrupts ();
  46. /* turn off I-cache */
  47. icache_disable();
  48. dcache_disable();
  49. /* flush I-cache */
  50. cache_flush();
  51. return (0);
  52. }
  53. /* flush I/D-cache */
  54. static void cache_flush (void)
  55. {
  56. unsigned long i = 0;
  57. asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i));
  58. }
  59. #ifndef CONFIG_CPU_MONAHANS
  60. void set_GPIO_mode(int gpio_mode)
  61. {
  62. int gpio = gpio_mode & GPIO_MD_MASK_NR;
  63. int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
  64. int val;
  65. /* This below changes direction setting of GPIO "gpio" */
  66. val = readl(GPDR(gpio));
  67. if (gpio_mode & GPIO_MD_MASK_DIR)
  68. val |= GPIO_bit(gpio);
  69. else
  70. val &= ~GPIO_bit(gpio);
  71. writel(val, GPDR(gpio));
  72. /* This below updates only AF of GPIO "gpio" */
  73. val = readl(GAFR(gpio));
  74. val &= ~(0x3 << (((gpio) & 0xf) * 2));
  75. val |= fn << (((gpio) & 0xf) * 2);
  76. writel(val, GAFR(gpio));
  77. }
  78. #endif /* CONFIG_CPU_MONAHANS */
  79. void pxa_wait_ticks(int ticks)
  80. {
  81. writel(0, OSCR);
  82. while (readl(OSCR) < ticks)
  83. asm volatile("":::"memory");
  84. }
  85. inline void writelrb(uint32_t val, uint32_t addr)
  86. {
  87. writel(val, addr);
  88. asm volatile("":::"memory");
  89. readl(addr);
  90. asm volatile("":::"memory");
  91. }
  92. void pxa_dram_init(void)
  93. {
  94. uint32_t tmp;
  95. int i;
  96. /*
  97. * 1) Initialize Asynchronous static memory controller
  98. */
  99. writelrb(CONFIG_SYS_MSC0_VAL, MSC0);
  100. writelrb(CONFIG_SYS_MSC1_VAL, MSC1);
  101. writelrb(CONFIG_SYS_MSC2_VAL, MSC2);
  102. /*
  103. * 2) Initialize Card Interface
  104. */
  105. /* MECR: Memory Expansion Card Register */
  106. writelrb(CONFIG_SYS_MECR_VAL, MECR);
  107. /* MCMEM0: Card Interface slot 0 timing */
  108. writelrb(CONFIG_SYS_MCMEM0_VAL, MCMEM0);
  109. /* MCMEM1: Card Interface slot 1 timing */
  110. writelrb(CONFIG_SYS_MCMEM1_VAL, MCMEM1);
  111. /* MCATT0: Card Interface Attribute Space Timing, slot 0 */
  112. writelrb(CONFIG_SYS_MCATT0_VAL, MCATT0);
  113. /* MCATT1: Card Interface Attribute Space Timing, slot 1 */
  114. writelrb(CONFIG_SYS_MCATT1_VAL, MCATT1);
  115. /* MCIO0: Card Interface I/O Space Timing, slot 0 */
  116. writelrb(CONFIG_SYS_MCIO0_VAL, MCIO0);
  117. /* MCIO1: Card Interface I/O Space Timing, slot 1 */
  118. writelrb(CONFIG_SYS_MCIO1_VAL, MCIO1);
  119. /*
  120. * 3) Configure Fly-By DMA register
  121. */
  122. writelrb(CONFIG_SYS_FLYCNFG_VAL, FLYCNFG);
  123. /*
  124. * 4) Initialize Timing for Sync Memory (SDCLK0)
  125. */
  126. /*
  127. * Before accessing MDREFR we need a valid DRI field, so we set
  128. * this to power on defaults + DRI field.
  129. */
  130. /* Read current MDREFR config and zero out DRI */
  131. tmp = readl(MDREFR) & ~0xfff;
  132. /* Add user-specified DRI */
  133. tmp |= CONFIG_SYS_MDREFR_VAL & 0xfff;
  134. /* Configure important bits */
  135. tmp |= MDREFR_K0RUN | MDREFR_SLFRSH;
  136. tmp &= ~(MDREFR_APD | MDREFR_E1PIN);
  137. /* Write MDREFR back */
  138. writelrb(tmp, MDREFR);
  139. /*
  140. * 5) Initialize Synchronous Static Memory (Flash/Peripherals)
  141. */
  142. /* Initialize SXCNFG register. Assert the enable bits.
  143. *
  144. * Write SXMRS to cause an MRS command to all enabled banks of
  145. * synchronous static memory. Note that SXLCR need not be written
  146. * at this time.
  147. */
  148. writelrb(CONFIG_SYS_SXCNFG_VAL, SXCNFG);
  149. /*
  150. * 6) Initialize SDRAM
  151. */
  152. writelrb(CONFIG_SYS_MDREFR_VAL & ~MDREFR_SLFRSH, MDREFR);
  153. writelrb(CONFIG_SYS_MDREFR_VAL | MDREFR_E1PIN, MDREFR);
  154. /*
  155. * 7) Write MDCNFG with MDCNFG:DEx deasserted (set to 0), to configure
  156. * but not enable each SDRAM partition pair.
  157. */
  158. writelrb(CONFIG_SYS_MDCNFG_VAL &
  159. ~(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3), MDCNFG);
  160. /* Wait for the clock to the SDRAMs to stabilize, 100..200 usec. */
  161. pxa_wait_ticks(0x300);
  162. /*
  163. * 8) Trigger a number (usually 8) refresh cycles by attempting
  164. * non-burst read or write accesses to disabled SDRAM, as commonly
  165. * specified in the power up sequence documented in SDRAM data
  166. * sheets. The address(es) used for this purpose must not be
  167. * cacheable.
  168. */
  169. for (i = 9; i >= 0; i--) {
  170. writel(i, 0xa0000000);
  171. asm volatile("":::"memory");
  172. }
  173. /*
  174. * 9) Write MDCNFG with enable bits asserted (MDCNFG:DEx set to 1).
  175. */
  176. tmp = CONFIG_SYS_MDCNFG_VAL &
  177. (MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3);
  178. tmp |= readl(MDCNFG);
  179. writelrb(tmp, MDCNFG);
  180. /*
  181. * 10) Write MDMRS.
  182. */
  183. writelrb(CONFIG_SYS_MDMRS_VAL, MDMRS);
  184. /*
  185. * 11) Enable APD
  186. */
  187. if (CONFIG_SYS_MDREFR_VAL & MDREFR_APD) {
  188. tmp = readl(MDREFR);
  189. tmp |= MDREFR_APD;
  190. writelrb(tmp, MDREFR);
  191. }
  192. }
  193. void pxa_gpio_setup(void)
  194. {
  195. writel(CONFIG_SYS_GPSR0_VAL, GPSR0);
  196. writel(CONFIG_SYS_GPSR1_VAL, GPSR1);
  197. writel(CONFIG_SYS_GPSR2_VAL, GPSR2);
  198. #if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
  199. writel(CONFIG_SYS_GPSR3_VAL, GPSR3);
  200. #endif
  201. writel(CONFIG_SYS_GPCR0_VAL, GPCR0);
  202. writel(CONFIG_SYS_GPCR1_VAL, GPCR1);
  203. writel(CONFIG_SYS_GPCR2_VAL, GPCR2);
  204. #if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
  205. writel(CONFIG_SYS_GPCR3_VAL, GPCR3);
  206. #endif
  207. writel(CONFIG_SYS_GPDR0_VAL, GPDR0);
  208. writel(CONFIG_SYS_GPDR1_VAL, GPDR1);
  209. writel(CONFIG_SYS_GPDR2_VAL, GPDR2);
  210. #if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
  211. writel(CONFIG_SYS_GPDR3_VAL, GPDR3);
  212. #endif
  213. writel(CONFIG_SYS_GAFR0_L_VAL, GAFR0_L);
  214. writel(CONFIG_SYS_GAFR0_U_VAL, GAFR0_U);
  215. writel(CONFIG_SYS_GAFR1_L_VAL, GAFR1_L);
  216. writel(CONFIG_SYS_GAFR1_U_VAL, GAFR1_U);
  217. writel(CONFIG_SYS_GAFR2_L_VAL, GAFR2_L);
  218. writel(CONFIG_SYS_GAFR2_U_VAL, GAFR2_U);
  219. #if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
  220. writel(CONFIG_SYS_GAFR3_L_VAL, GAFR3_L);
  221. writel(CONFIG_SYS_GAFR3_U_VAL, GAFR3_U);
  222. #endif
  223. writel(CONFIG_SYS_PSSR_VAL, PSSR);
  224. }
  225. void pxa_interrupt_setup(void)
  226. {
  227. writel(0, ICLR);
  228. writel(0, ICMR);
  229. #if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS)
  230. writel(0, ICLR2);
  231. writel(0, ICMR2);
  232. #endif
  233. }
  234. void pxa_clock_setup(void)
  235. {
  236. #ifndef CONFIG_CPU_MONAHANS
  237. writel(CONFIG_SYS_CKEN, CKEN);
  238. writel(CONFIG_SYS_CCCR, CCCR);
  239. asm volatile("mcr p14, 0, %0, c6, c0, 0"::"r"(2));
  240. #else
  241. /* Set CKENA/CKENB/ACCR for MH */
  242. #endif
  243. /* enable the 32Khz oscillator for RTC and PowerManager */
  244. writel(OSCC_OON, OSCC);
  245. while(!(readl(OSCC) & OSCC_OOK))
  246. asm volatile("":::"memory");
  247. }
  248. void pxa_wakeup(void)
  249. {
  250. uint32_t rcsr;
  251. rcsr = readl(RCSR);
  252. writel(rcsr & (RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR), RCSR);
  253. /* Wakeup */
  254. if (rcsr & RCSR_SMR) {
  255. writel(PSSR_PH, PSSR);
  256. pxa_dram_init();
  257. icache_disable();
  258. dcache_disable();
  259. asm volatile("mov pc, %0"::"r"(readl(PSSR)));
  260. }
  261. }
  262. int arch_cpu_init(void)
  263. {
  264. pxa_gpio_setup();
  265. /* pxa_wait_ticks(0x8000); */
  266. pxa_wakeup();
  267. pxa_interrupt_setup();
  268. pxa_clock_setup();
  269. return 0;
  270. }
  271. void i2c_clk_enable(void)
  272. {
  273. /* set the global I2C clock on */
  274. #ifdef CONFIG_CPU_MONAHANS
  275. writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
  276. #else
  277. writel(readl(CKEN) | CKEN14_I2C, CKEN);
  278. #endif
  279. }