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