xref: /openbmc/u-boot/arch/arm/cpu/pxa/pxa2xx.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
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