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