]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/pxa/pxa2xx.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / arch / arm / cpu / pxa / pxa2xx.c
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"(2));
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 }