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 #include <asm/io.h> 30 #include <asm/system.h> 31 #include <command.h> 32 #include <common.h> 33 #include <asm/arch/pxa-regs.h> 34 35 /* Flush I/D-cache */ 36 static void cache_flush(void) 37 { 38 unsigned long i = 0; 39 40 asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (i)); 41 } 42 43 int cleanup_before_linux(void) 44 { 45 /* 46 * This function is called just before we call Linux. It prepares 47 * the processor for Linux by just disabling everything that can 48 * disturb booting Linux. 49 */ 50 51 disable_interrupts(); 52 icache_disable(); 53 dcache_disable(); 54 cache_flush(); 55 56 return 0; 57 } 58 59 void pxa_wait_ticks(int ticks) 60 { 61 writel(0, OSCR); 62 while (readl(OSCR) < ticks) 63 asm volatile("" : : : "memory"); 64 } 65 66 inline void writelrb(uint32_t val, uint32_t addr) 67 { 68 writel(val, addr); 69 asm volatile("" : : : "memory"); 70 readl(addr); 71 asm volatile("" : : : "memory"); 72 } 73 74 void pxa2xx_dram_init(void) 75 { 76 uint32_t tmp; 77 int i; 78 /* 79 * 1) Initialize Asynchronous static memory controller 80 */ 81 82 writelrb(CONFIG_SYS_MSC0_VAL, MSC0); 83 writelrb(CONFIG_SYS_MSC1_VAL, MSC1); 84 writelrb(CONFIG_SYS_MSC2_VAL, MSC2); 85 /* 86 * 2) Initialize Card Interface 87 */ 88 89 /* MECR: Memory Expansion Card Register */ 90 writelrb(CONFIG_SYS_MECR_VAL, MECR); 91 /* MCMEM0: Card Interface slot 0 timing */ 92 writelrb(CONFIG_SYS_MCMEM0_VAL, MCMEM0); 93 /* MCMEM1: Card Interface slot 1 timing */ 94 writelrb(CONFIG_SYS_MCMEM1_VAL, MCMEM1); 95 /* MCATT0: Card Interface Attribute Space Timing, slot 0 */ 96 writelrb(CONFIG_SYS_MCATT0_VAL, MCATT0); 97 /* MCATT1: Card Interface Attribute Space Timing, slot 1 */ 98 writelrb(CONFIG_SYS_MCATT1_VAL, MCATT1); 99 /* MCIO0: Card Interface I/O Space Timing, slot 0 */ 100 writelrb(CONFIG_SYS_MCIO0_VAL, MCIO0); 101 /* MCIO1: Card Interface I/O Space Timing, slot 1 */ 102 writelrb(CONFIG_SYS_MCIO1_VAL, MCIO1); 103 104 /* 105 * 3) Configure Fly-By DMA register 106 */ 107 108 writelrb(CONFIG_SYS_FLYCNFG_VAL, FLYCNFG); 109 110 /* 111 * 4) Initialize Timing for Sync Memory (SDCLK0) 112 */ 113 114 /* 115 * Before accessing MDREFR we need a valid DRI field, so we set 116 * this to power on defaults + DRI field. 117 */ 118 119 /* Read current MDREFR config and zero out DRI */ 120 tmp = readl(MDREFR) & ~0xfff; 121 /* Add user-specified DRI */ 122 tmp |= CONFIG_SYS_MDREFR_VAL & 0xfff; 123 /* Configure important bits */ 124 tmp |= MDREFR_K0RUN | MDREFR_SLFRSH; 125 tmp &= ~(MDREFR_APD | MDREFR_E1PIN); 126 127 /* Write MDREFR back */ 128 writelrb(tmp, MDREFR); 129 130 /* 131 * 5) Initialize Synchronous Static Memory (Flash/Peripherals) 132 */ 133 134 /* Initialize SXCNFG register. Assert the enable bits. 135 * 136 * Write SXMRS to cause an MRS command to all enabled banks of 137 * synchronous static memory. Note that SXLCR need not be written 138 * at this time. 139 */ 140 writelrb(CONFIG_SYS_SXCNFG_VAL, SXCNFG); 141 142 /* 143 * 6) Initialize SDRAM 144 */ 145 146 writelrb(CONFIG_SYS_MDREFR_VAL & ~MDREFR_SLFRSH, MDREFR); 147 writelrb(CONFIG_SYS_MDREFR_VAL | MDREFR_E1PIN, MDREFR); 148 149 /* 150 * 7) Write MDCNFG with MDCNFG:DEx deasserted (set to 0), to configure 151 * but not enable each SDRAM partition pair. 152 */ 153 154 writelrb(CONFIG_SYS_MDCNFG_VAL & 155 ~(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3), MDCNFG); 156 /* Wait for the clock to the SDRAMs to stabilize, 100..200 usec. */ 157 pxa_wait_ticks(0x300); 158 159 /* 160 * 8) Trigger a number (usually 8) refresh cycles by attempting 161 * non-burst read or write accesses to disabled SDRAM, as commonly 162 * specified in the power up sequence documented in SDRAM data 163 * sheets. The address(es) used for this purpose must not be 164 * cacheable. 165 */ 166 for (i = 9; i >= 0; i--) { 167 writel(i, 0xa0000000); 168 asm volatile("" : : : "memory"); 169 } 170 /* 171 * 9) Write MDCNFG with enable bits asserted (MDCNFG:DEx set to 1). 172 */ 173 174 tmp = CONFIG_SYS_MDCNFG_VAL & 175 (MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3); 176 tmp |= readl(MDCNFG); 177 writelrb(tmp, MDCNFG); 178 179 /* 180 * 10) Write MDMRS. 181 */ 182 183 writelrb(CONFIG_SYS_MDMRS_VAL, MDMRS); 184 185 /* 186 * 11) Enable APD 187 */ 188 189 if (CONFIG_SYS_MDREFR_VAL & MDREFR_APD) { 190 tmp = readl(MDREFR); 191 tmp |= MDREFR_APD; 192 writelrb(tmp, MDREFR); 193 } 194 } 195 196 void pxa_gpio_setup(void) 197 { 198 writel(CONFIG_SYS_GPSR0_VAL, GPSR0); 199 writel(CONFIG_SYS_GPSR1_VAL, GPSR1); 200 writel(CONFIG_SYS_GPSR2_VAL, GPSR2); 201 #if defined(CONFIG_CPU_PXA27X) 202 writel(CONFIG_SYS_GPSR3_VAL, GPSR3); 203 #endif 204 205 writel(CONFIG_SYS_GPCR0_VAL, GPCR0); 206 writel(CONFIG_SYS_GPCR1_VAL, GPCR1); 207 writel(CONFIG_SYS_GPCR2_VAL, GPCR2); 208 #if defined(CONFIG_CPU_PXA27X) 209 writel(CONFIG_SYS_GPCR3_VAL, GPCR3); 210 #endif 211 212 writel(CONFIG_SYS_GPDR0_VAL, GPDR0); 213 writel(CONFIG_SYS_GPDR1_VAL, GPDR1); 214 writel(CONFIG_SYS_GPDR2_VAL, GPDR2); 215 #if defined(CONFIG_CPU_PXA27X) 216 writel(CONFIG_SYS_GPDR3_VAL, GPDR3); 217 #endif 218 219 writel(CONFIG_SYS_GAFR0_L_VAL, GAFR0_L); 220 writel(CONFIG_SYS_GAFR0_U_VAL, GAFR0_U); 221 writel(CONFIG_SYS_GAFR1_L_VAL, GAFR1_L); 222 writel(CONFIG_SYS_GAFR1_U_VAL, GAFR1_U); 223 writel(CONFIG_SYS_GAFR2_L_VAL, GAFR2_L); 224 writel(CONFIG_SYS_GAFR2_U_VAL, GAFR2_U); 225 #if defined(CONFIG_CPU_PXA27X) 226 writel(CONFIG_SYS_GAFR3_L_VAL, GAFR3_L); 227 writel(CONFIG_SYS_GAFR3_U_VAL, GAFR3_U); 228 #endif 229 230 writel(CONFIG_SYS_PSSR_VAL, PSSR); 231 } 232 233 void pxa_interrupt_setup(void) 234 { 235 writel(0, ICLR); 236 writel(0, ICMR); 237 #if defined(CONFIG_CPU_PXA27X) 238 writel(0, ICLR2); 239 writel(0, ICMR2); 240 #endif 241 } 242 243 void pxa_clock_setup(void) 244 { 245 writel(CONFIG_SYS_CKEN, CKEN); 246 writel(CONFIG_SYS_CCCR, CCCR); 247 asm volatile("mcr p14, 0, %0, c6, c0, 0" : : "r"(0x0b)); 248 249 /* enable the 32Khz oscillator for RTC and PowerManager */ 250 writel(OSCC_OON, OSCC); 251 while (!(readl(OSCC) & OSCC_OOK)) 252 asm volatile("" : : : "memory"); 253 } 254 255 void pxa_wakeup(void) 256 { 257 uint32_t rcsr; 258 259 rcsr = readl(RCSR); 260 writel(rcsr & (RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR), RCSR); 261 262 /* Wakeup */ 263 if (rcsr & RCSR_SMR) { 264 writel(PSSR_PH, PSSR); 265 pxa2xx_dram_init(); 266 icache_disable(); 267 dcache_disable(); 268 asm volatile("mov pc, %0" : : "r"(readl(PSPR))); 269 } 270 } 271 272 int arch_cpu_init(void) 273 { 274 pxa_gpio_setup(); 275 pxa_wakeup(); 276 pxa_interrupt_setup(); 277 pxa_clock_setup(); 278 return 0; 279 } 280 281 void i2c_clk_enable(void) 282 { 283 /* Set the global I2C clock on */ 284 writel(readl(CKEN) | CKEN14_I2C, CKEN); 285 } 286 287 void __attribute__((weak)) reset_cpu(ulong ignored) __attribute__((noreturn)); 288 289 void reset_cpu(ulong ignored) 290 { 291 uint32_t tmp; 292 293 setbits_le32(OWER, OWER_WME); 294 295 tmp = readl(OSCR); 296 tmp += 0x1000; 297 writel(tmp, OSMR3); 298 299 for (;;) 300 ; 301 } 302