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