1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * armboot - Startup Code for XScale CPU-core 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> 5*4882a593Smuzhiyun * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> 6*4882a593Smuzhiyun * Copyright (C) 2000 Wolfgang Denk <wd@denx.de> 7*4882a593Smuzhiyun * Copyright (C) 2001 Alex Zuepke <azu@sysgo.de> 8*4882a593Smuzhiyun * Copyright (C) 2001 Marius Groger <mag@sysgo.de> 9*4882a593Smuzhiyun * Copyright (C) 2002 Alex Zupke <azu@sysgo.de> 10*4882a593Smuzhiyun * Copyright (C) 2002 Gary Jennejohn <garyj@denx.de> 11*4882a593Smuzhiyun * Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net> 12*4882a593Smuzhiyun * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de> 13*4882a593Smuzhiyun * Copyright (C) 2003 Kshitij <kshitij@ti.com> 14*4882a593Smuzhiyun * Copyright (C) 2003 Richard Woodruff <r-woodruff2@ti.com> 15*4882a593Smuzhiyun * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de> 16*4882a593Smuzhiyun * Copyright (C) 2004 Texas Instruments <r-woodruff2@ti.com> 17*4882a593Smuzhiyun * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> 18*4882a593Smuzhiyun * 19*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 20*4882a593Smuzhiyun */ 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun#include <asm-offsets.h> 23*4882a593Smuzhiyun#include <config.h> 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun/* 26*4882a593Smuzhiyun ************************************************************************* 27*4882a593Smuzhiyun * 28*4882a593Smuzhiyun * Startup Code (reset vector) 29*4882a593Smuzhiyun * 30*4882a593Smuzhiyun * do important init only if we don't start from memory! 31*4882a593Smuzhiyun * setup Memory and board specific bits prior to relocation. 32*4882a593Smuzhiyun * relocate armboot to ram 33*4882a593Smuzhiyun * setup stack 34*4882a593Smuzhiyun * 35*4882a593Smuzhiyun ************************************************************************* 36*4882a593Smuzhiyun */ 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun .globl reset 39*4882a593Smuzhiyun 40*4882a593Smuzhiyunreset: 41*4882a593Smuzhiyun /* 42*4882a593Smuzhiyun * set the cpu to SVC32 mode 43*4882a593Smuzhiyun */ 44*4882a593Smuzhiyun mrs r0,cpsr 45*4882a593Smuzhiyun bic r0,r0,#0x1f 46*4882a593Smuzhiyun orr r0,r0,#0xd3 47*4882a593Smuzhiyun msr cpsr,r0 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun#ifndef CONFIG_SKIP_LOWLEVEL_INIT 50*4882a593Smuzhiyun bl cpu_init_crit 51*4882a593Smuzhiyun#endif 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun#ifdef CONFIG_CPU_PXA25X 54*4882a593Smuzhiyun bl lock_cache_for_stack 55*4882a593Smuzhiyun#endif 56*4882a593Smuzhiyun#ifdef CONFIG_CPU_PXA27X 57*4882a593Smuzhiyun /* 58*4882a593Smuzhiyun * enable clock for SRAM 59*4882a593Smuzhiyun */ 60*4882a593Smuzhiyun ldr r0,=CKEN 61*4882a593Smuzhiyun ldr r1,[r0] 62*4882a593Smuzhiyun orr r1,r1,#(1 << 20) 63*4882a593Smuzhiyun str r1,[r0] 64*4882a593Smuzhiyun#endif 65*4882a593Smuzhiyun bl _main 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun/*------------------------------------------------------------------------------*/ 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun .globl c_runtime_cpu_setup 70*4882a593Smuzhiyunc_runtime_cpu_setup: 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun#ifdef CONFIG_CPU_PXA25X 73*4882a593Smuzhiyun /* 74*4882a593Smuzhiyun * Unlock (actually, disable) the cache now that board_init_f 75*4882a593Smuzhiyun * is done. We could do this earlier but we would need to add 76*4882a593Smuzhiyun * a new C runtime hook, whereas c_runtime_cpu_setup already 77*4882a593Smuzhiyun * exists. 78*4882a593Smuzhiyun * As this routine is just a call to cpu_init_crit, let us 79*4882a593Smuzhiyun * tail-optimize and do a simple branch here. 80*4882a593Smuzhiyun */ 81*4882a593Smuzhiyun b cpu_init_crit 82*4882a593Smuzhiyun#else 83*4882a593Smuzhiyun bx lr 84*4882a593Smuzhiyun#endif 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun/* 87*4882a593Smuzhiyun ************************************************************************* 88*4882a593Smuzhiyun * 89*4882a593Smuzhiyun * CPU_init_critical registers 90*4882a593Smuzhiyun * 91*4882a593Smuzhiyun * setup important registers 92*4882a593Smuzhiyun * setup memory timing 93*4882a593Smuzhiyun * 94*4882a593Smuzhiyun ************************************************************************* 95*4882a593Smuzhiyun */ 96*4882a593Smuzhiyun#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_CPU_PXA25X) 97*4882a593Smuzhiyuncpu_init_crit: 98*4882a593Smuzhiyun /* 99*4882a593Smuzhiyun * flush v4 I/D caches 100*4882a593Smuzhiyun */ 101*4882a593Smuzhiyun mov r0, #0 102*4882a593Smuzhiyun mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */ 103*4882a593Smuzhiyun mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified TLB */ 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun /* 106*4882a593Smuzhiyun * disable MMU stuff and caches 107*4882a593Smuzhiyun */ 108*4882a593Smuzhiyun mrc p15, 0, r0, c1, c0, 0 109*4882a593Smuzhiyun bic r0, r0, #0x00003300 @ clear bits 13:12, 9:8 (--VI --RS) 110*4882a593Smuzhiyun bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) 111*4882a593Smuzhiyun orr r0, r0, #0x00000002 @ set bit 1 (A) Align 112*4882a593Smuzhiyun mcr p15, 0, r0, c1, c0, 0 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun mov pc, lr /* back to my caller */ 115*4882a593Smuzhiyun#endif /* !CONFIG_SKIP_LOWLEVEL_INIT || CONFIG_CPU_PXA25X */ 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun/* 118*4882a593Smuzhiyun * Enable MMU to use DCache as DRAM. 119*4882a593Smuzhiyun * 120*4882a593Smuzhiyun * This is useful on PXA25x and PXA26x in early bootstages, where there is no 121*4882a593Smuzhiyun * other possible memory available to hold stack. 122*4882a593Smuzhiyun */ 123*4882a593Smuzhiyun#ifdef CONFIG_CPU_PXA25X 124*4882a593Smuzhiyun.macro CPWAIT reg 125*4882a593Smuzhiyun mrc p15, 0, \reg, c2, c0, 0 126*4882a593Smuzhiyun mov \reg, \reg 127*4882a593Smuzhiyun sub pc, pc, #4 128*4882a593Smuzhiyun.endm 129*4882a593Smuzhiyunlock_cache_for_stack: 130*4882a593Smuzhiyun /* Domain access -- enable for all CPs */ 131*4882a593Smuzhiyun ldr r0, =0x0000ffff 132*4882a593Smuzhiyun mcr p15, 0, r0, c3, c0, 0 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun /* Point TTBR to MMU table */ 135*4882a593Smuzhiyun ldr r0, =mmutable 136*4882a593Smuzhiyun mcr p15, 0, r0, c2, c0, 0 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun /* Kick in MMU, ICache, DCache, BTB */ 139*4882a593Smuzhiyun mrc p15, 0, r0, c1, c0, 0 140*4882a593Smuzhiyun bic r0, #0x1b00 141*4882a593Smuzhiyun bic r0, #0x0087 142*4882a593Smuzhiyun orr r0, #0x1800 143*4882a593Smuzhiyun orr r0, #0x0005 144*4882a593Smuzhiyun mcr p15, 0, r0, c1, c0, 0 145*4882a593Smuzhiyun CPWAIT r0 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun /* Unlock Icache, Dcache */ 148*4882a593Smuzhiyun mcr p15, 0, r0, c9, c1, 1 149*4882a593Smuzhiyun mcr p15, 0, r0, c9, c2, 1 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun /* Flush Icache, Dcache, BTB */ 152*4882a593Smuzhiyun mcr p15, 0, r0, c7, c7, 0 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun /* Unlock I-TLB, D-TLB */ 155*4882a593Smuzhiyun mcr p15, 0, r0, c10, c4, 1 156*4882a593Smuzhiyun mcr p15, 0, r0, c10, c8, 1 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun /* Flush TLB */ 159*4882a593Smuzhiyun mcr p15, 0, r0, c8, c7, 0 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun /* Allocate 4096 bytes of Dcache as RAM */ 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun /* Drain pending loads and stores */ 164*4882a593Smuzhiyun mcr p15, 0, r0, c7, c10, 4 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun mov r4, #0x00 167*4882a593Smuzhiyun mov r5, #0x00 168*4882a593Smuzhiyun mov r2, #0x01 169*4882a593Smuzhiyun mcr p15, 0, r0, c9, c2, 0 170*4882a593Smuzhiyun CPWAIT r0 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun /* 128 lines reserved (128 x 32bytes = 4096 bytes total) */ 173*4882a593Smuzhiyun mov r0, #128 174*4882a593Smuzhiyun ldr r1, =0xfffff000 175*4882a593Smuzhiyun 176*4882a593Smuzhiyunalloc: 177*4882a593Smuzhiyun mcr p15, 0, r1, c7, c2, 5 178*4882a593Smuzhiyun /* Drain pending loads and stores */ 179*4882a593Smuzhiyun mcr p15, 0, r0, c7, c10, 4 180*4882a593Smuzhiyun strd r4, [r1], #8 181*4882a593Smuzhiyun strd r4, [r1], #8 182*4882a593Smuzhiyun strd r4, [r1], #8 183*4882a593Smuzhiyun strd r4, [r1], #8 184*4882a593Smuzhiyun subs r0, #0x01 185*4882a593Smuzhiyun bne alloc 186*4882a593Smuzhiyun /* Drain pending loads and stores */ 187*4882a593Smuzhiyun mcr p15, 0, r0, c7, c10, 4 188*4882a593Smuzhiyun mov r2, #0x00 189*4882a593Smuzhiyun mcr p15, 0, r2, c9, c2, 0 190*4882a593Smuzhiyun CPWAIT r0 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun mov pc, lr 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun.section .mmutable, "a" 195*4882a593Smuzhiyunmmutable: 196*4882a593Smuzhiyun .align 14 197*4882a593Smuzhiyun /* 0x00000000 - 0xffe00000 : 1:1, uncached mapping */ 198*4882a593Smuzhiyun .set __base, 0 199*4882a593Smuzhiyun .rept 0xfff 200*4882a593Smuzhiyun .word (__base << 20) | 0xc12 201*4882a593Smuzhiyun .set __base, __base + 1 202*4882a593Smuzhiyun .endr 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun /* 0xfff00000 : 1:1, cached mapping */ 205*4882a593Smuzhiyun .word (0xfff << 20) | 0x1c1e 206*4882a593Smuzhiyun#endif /* CONFIG_CPU_PXA25X */ 207