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