123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- /*
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Alex Zuepke <azu@sysgo.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
- #include <asm/io.h>
- #include <asm/system.h>
- #include <command.h>
- #include <common.h>
- #include <asm/arch/pxa-regs.h>
- /* Flush I/D-cache */
- static void cache_flush(void)
- {
- unsigned long i = 0;
- asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (i));
- }
- int cleanup_before_linux(void)
- {
- /*
- * This function is called just before we call Linux. It prepares
- * the processor for Linux by just disabling everything that can
- * disturb booting Linux.
- */
- disable_interrupts();
- icache_disable();
- dcache_disable();
- cache_flush();
- return 0;
- }
- void pxa_wait_ticks(int ticks)
- {
- writel(0, OSCR);
- while (readl(OSCR) < ticks)
- asm volatile("" : : : "memory");
- }
- inline void writelrb(uint32_t val, uint32_t addr)
- {
- writel(val, addr);
- asm volatile("" : : : "memory");
- readl(addr);
- asm volatile("" : : : "memory");
- }
- void pxa2xx_dram_init(void)
- {
- uint32_t tmp;
- int i;
- /*
- * 1) Initialize Asynchronous static memory controller
- */
- writelrb(CONFIG_SYS_MSC0_VAL, MSC0);
- writelrb(CONFIG_SYS_MSC1_VAL, MSC1);
- writelrb(CONFIG_SYS_MSC2_VAL, MSC2);
- /*
- * 2) Initialize Card Interface
- */
- /* MECR: Memory Expansion Card Register */
- writelrb(CONFIG_SYS_MECR_VAL, MECR);
- /* MCMEM0: Card Interface slot 0 timing */
- writelrb(CONFIG_SYS_MCMEM0_VAL, MCMEM0);
- /* MCMEM1: Card Interface slot 1 timing */
- writelrb(CONFIG_SYS_MCMEM1_VAL, MCMEM1);
- /* MCATT0: Card Interface Attribute Space Timing, slot 0 */
- writelrb(CONFIG_SYS_MCATT0_VAL, MCATT0);
- /* MCATT1: Card Interface Attribute Space Timing, slot 1 */
- writelrb(CONFIG_SYS_MCATT1_VAL, MCATT1);
- /* MCIO0: Card Interface I/O Space Timing, slot 0 */
- writelrb(CONFIG_SYS_MCIO0_VAL, MCIO0);
- /* MCIO1: Card Interface I/O Space Timing, slot 1 */
- writelrb(CONFIG_SYS_MCIO1_VAL, MCIO1);
- /*
- * 3) Configure Fly-By DMA register
- */
- writelrb(CONFIG_SYS_FLYCNFG_VAL, FLYCNFG);
- /*
- * 4) Initialize Timing for Sync Memory (SDCLK0)
- */
- /*
- * Before accessing MDREFR we need a valid DRI field, so we set
- * this to power on defaults + DRI field.
- */
- /* Read current MDREFR config and zero out DRI */
- tmp = readl(MDREFR) & ~0xfff;
- /* Add user-specified DRI */
- tmp |= CONFIG_SYS_MDREFR_VAL & 0xfff;
- /* Configure important bits */
- tmp |= MDREFR_K0RUN | MDREFR_SLFRSH;
- tmp &= ~(MDREFR_APD | MDREFR_E1PIN);
- /* Write MDREFR back */
- writelrb(tmp, MDREFR);
- /*
- * 5) Initialize Synchronous Static Memory (Flash/Peripherals)
- */
- /* Initialize SXCNFG register. Assert the enable bits.
- *
- * Write SXMRS to cause an MRS command to all enabled banks of
- * synchronous static memory. Note that SXLCR need not be written
- * at this time.
- */
- writelrb(CONFIG_SYS_SXCNFG_VAL, SXCNFG);
- /*
- * 6) Initialize SDRAM
- */
- writelrb(CONFIG_SYS_MDREFR_VAL & ~MDREFR_SLFRSH, MDREFR);
- writelrb(CONFIG_SYS_MDREFR_VAL | MDREFR_E1PIN, MDREFR);
- /*
- * 7) Write MDCNFG with MDCNFG:DEx deasserted (set to 0), to configure
- * but not enable each SDRAM partition pair.
- */
- writelrb(CONFIG_SYS_MDCNFG_VAL &
- ~(MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3), MDCNFG);
- /* Wait for the clock to the SDRAMs to stabilize, 100..200 usec. */
- pxa_wait_ticks(0x300);
- /*
- * 8) Trigger a number (usually 8) refresh cycles by attempting
- * non-burst read or write accesses to disabled SDRAM, as commonly
- * specified in the power up sequence documented in SDRAM data
- * sheets. The address(es) used for this purpose must not be
- * cacheable.
- */
- for (i = 9; i >= 0; i--) {
- writel(i, 0xa0000000);
- asm volatile("" : : : "memory");
- }
- /*
- * 9) Write MDCNFG with enable bits asserted (MDCNFG:DEx set to 1).
- */
- tmp = CONFIG_SYS_MDCNFG_VAL &
- (MDCNFG_DE0 | MDCNFG_DE1 | MDCNFG_DE2 | MDCNFG_DE3);
- tmp |= readl(MDCNFG);
- writelrb(tmp, MDCNFG);
- /*
- * 10) Write MDMRS.
- */
- writelrb(CONFIG_SYS_MDMRS_VAL, MDMRS);
- /*
- * 11) Enable APD
- */
- if (CONFIG_SYS_MDREFR_VAL & MDREFR_APD) {
- tmp = readl(MDREFR);
- tmp |= MDREFR_APD;
- writelrb(tmp, MDREFR);
- }
- }
- void pxa_gpio_setup(void)
- {
- writel(CONFIG_SYS_GPSR0_VAL, GPSR0);
- writel(CONFIG_SYS_GPSR1_VAL, GPSR1);
- writel(CONFIG_SYS_GPSR2_VAL, GPSR2);
- #if defined(CONFIG_CPU_PXA27X)
- writel(CONFIG_SYS_GPSR3_VAL, GPSR3);
- #endif
- writel(CONFIG_SYS_GPCR0_VAL, GPCR0);
- writel(CONFIG_SYS_GPCR1_VAL, GPCR1);
- writel(CONFIG_SYS_GPCR2_VAL, GPCR2);
- #if defined(CONFIG_CPU_PXA27X)
- writel(CONFIG_SYS_GPCR3_VAL, GPCR3);
- #endif
- writel(CONFIG_SYS_GPDR0_VAL, GPDR0);
- writel(CONFIG_SYS_GPDR1_VAL, GPDR1);
- writel(CONFIG_SYS_GPDR2_VAL, GPDR2);
- #if defined(CONFIG_CPU_PXA27X)
- writel(CONFIG_SYS_GPDR3_VAL, GPDR3);
- #endif
- writel(CONFIG_SYS_GAFR0_L_VAL, GAFR0_L);
- writel(CONFIG_SYS_GAFR0_U_VAL, GAFR0_U);
- writel(CONFIG_SYS_GAFR1_L_VAL, GAFR1_L);
- writel(CONFIG_SYS_GAFR1_U_VAL, GAFR1_U);
- writel(CONFIG_SYS_GAFR2_L_VAL, GAFR2_L);
- writel(CONFIG_SYS_GAFR2_U_VAL, GAFR2_U);
- #if defined(CONFIG_CPU_PXA27X)
- writel(CONFIG_SYS_GAFR3_L_VAL, GAFR3_L);
- writel(CONFIG_SYS_GAFR3_U_VAL, GAFR3_U);
- #endif
- writel(CONFIG_SYS_PSSR_VAL, PSSR);
- }
- void pxa_interrupt_setup(void)
- {
- writel(0, ICLR);
- writel(0, ICMR);
- #if defined(CONFIG_CPU_PXA27X)
- writel(0, ICLR2);
- writel(0, ICMR2);
- #endif
- }
- void pxa_clock_setup(void)
- {
- writel(CONFIG_SYS_CKEN, CKEN);
- writel(CONFIG_SYS_CCCR, CCCR);
- asm volatile("mcr p14, 0, %0, c6, c0, 0" : : "r"(2));
- /* enable the 32Khz oscillator for RTC and PowerManager */
- writel(OSCC_OON, OSCC);
- while (!(readl(OSCC) & OSCC_OOK))
- asm volatile("" : : : "memory");
- }
- void pxa_wakeup(void)
- {
- uint32_t rcsr;
- rcsr = readl(RCSR);
- writel(rcsr & (RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR), RCSR);
- /* Wakeup */
- if (rcsr & RCSR_SMR) {
- writel(PSSR_PH, PSSR);
- pxa2xx_dram_init();
- icache_disable();
- dcache_disable();
- asm volatile("mov pc, %0" : : "r"(readl(PSPR)));
- }
- }
- int arch_cpu_init(void)
- {
- pxa_gpio_setup();
- pxa_wakeup();
- pxa_interrupt_setup();
- pxa_clock_setup();
- return 0;
- }
- void i2c_clk_enable(void)
- {
- /* Set the global I2C clock on */
- writel(readl(CKEN) | CKEN14_I2C, CKEN);
- }
- void reset_cpu(ulong ignored) __attribute__((noreturn));
- void reset_cpu(ulong ignored)
- {
- uint32_t tmp;
- setbits_le32(OWER, OWER_WME);
- tmp = readl(OSCR);
- tmp += 0x1000;
- writel(tmp, OSMR3);
- for (;;)
- ;
- }
|