1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * Board specific setup info 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * (C) Copyright 2004, ARM Ltd. 5*4882a593Smuzhiyun * Philippe Robin, <philippe.robin@arm.com> 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun#include <config.h> 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun /* Reset using CM control register */ 13*4882a593Smuzhiyun.global reset_cpu 14*4882a593Smuzhiyunreset_cpu: 15*4882a593Smuzhiyun mov r0, #CM_BASE 16*4882a593Smuzhiyun ldr r1,[r0,#OS_CTRL] 17*4882a593Smuzhiyun orr r1,r1,#CMMASK_RESET 18*4882a593Smuzhiyun str r1,[r0,#OS_CTRL] 19*4882a593Smuzhiyun 20*4882a593Smuzhiyunreset_failed: 21*4882a593Smuzhiyun b reset_failed 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun/* Set up the platform, once the cpu has been initialized */ 24*4882a593Smuzhiyun.globl lowlevel_init 25*4882a593Smuzhiyunlowlevel_init: 26*4882a593Smuzhiyun /* If U-Boot has been run after the ARM boot monitor 27*4882a593Smuzhiyun * then all the necessary actions have been done 28*4882a593Smuzhiyun * otherwise we are running from user flash mapped to 0x00000000 29*4882a593Smuzhiyun * --- DO NOT REMAP BEFORE THE CODE HAS BEEN RELOCATED -- 30*4882a593Smuzhiyun * Changes to the (possibly soft) reset defaults of the processor 31*4882a593Smuzhiyun * itself should be performed in cpu/arm<>/start.S 32*4882a593Smuzhiyun * This function affects only the core module or board settings 33*4882a593Smuzhiyun */ 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun#ifdef CONFIG_CM_INIT 36*4882a593Smuzhiyun /* CM has an initialization register 37*4882a593Smuzhiyun * - bits in it are wired into test-chip pins to force 38*4882a593Smuzhiyun * reset defaults 39*4882a593Smuzhiyun * - may need to change its contents for U-Boot 40*4882a593Smuzhiyun */ 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /* set the desired CM specific value */ 43*4882a593Smuzhiyun mov r2,#CMMASK_LOWVEC /* Vectors at 0x00000000 for all */ 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun#if defined (CONFIG_CM10200E) || defined (CONFIG_CM10220E) 46*4882a593Smuzhiyun orr r2,r2,#CMMASK_INIT_102 47*4882a593Smuzhiyun#else 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun#if !defined (CONFIG_CM920T) && !defined (CONFIG_CM920T_ETM) && \ 50*4882a593Smuzhiyun !defined (CONFIG_CM940T) 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun#ifdef CONFIG_CM_MULTIPLE_SSRAM 53*4882a593Smuzhiyun /* set simple mapping */ 54*4882a593Smuzhiyun and r2,r2,#CMMASK_MAP_SIMPLE 55*4882a593Smuzhiyun#endif /* #ifdef CONFIG_CM_MULTIPLE_SSRAM */ 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun#ifdef CONFIG_CM_TCRAM 58*4882a593Smuzhiyun /* disable TCRAM */ 59*4882a593Smuzhiyun and r2,r2,#CMMASK_TCRAM_DISABLE 60*4882a593Smuzhiyun#endif /* #ifdef CONFIG_CM_TCRAM */ 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun#if defined (CONFIG_CM926EJ_S) || defined (CONFIG_CM1026EJ_S) || \ 63*4882a593Smuzhiyun defined (CONFIG_CM1136JF_S) 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun and r2,r2,#CMMASK_LE 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun#endif /* cpu with little endian initialization */ 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun orr r2,r2,#CMMASK_CMxx6_COMMON 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun#endif /* CMxx6 code */ 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun#endif /* ARM102xxE value */ 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun /* read CM_INIT */ 76*4882a593Smuzhiyun mov r0, #CM_BASE 77*4882a593Smuzhiyun ldr r1, [r0, #OS_INIT] 78*4882a593Smuzhiyun /* check against desired bit setting */ 79*4882a593Smuzhiyun and r3,r1,r2 80*4882a593Smuzhiyun cmp r3,r2 81*4882a593Smuzhiyun beq init_reg_OK 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun /* lock for change */ 84*4882a593Smuzhiyun mov r3, #CMVAL_LOCK1 85*4882a593Smuzhiyun add r3,r3,#CMVAL_LOCK2 86*4882a593Smuzhiyun str r3, [r0, #OS_LOCK] 87*4882a593Smuzhiyun /* set desired value */ 88*4882a593Smuzhiyun orr r1,r1,r2 89*4882a593Smuzhiyun /* write & relock CM_INIT */ 90*4882a593Smuzhiyun str r1, [r0, #OS_INIT] 91*4882a593Smuzhiyun mov r1, #CMVAL_UNLOCK 92*4882a593Smuzhiyun str r1, [r0, #OS_LOCK] 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun /* soft reset so new values used */ 95*4882a593Smuzhiyun b reset_cpu 96*4882a593Smuzhiyun 97*4882a593Smuzhiyuninit_reg_OK: 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun#endif /* CONFIG_CM_INIT */ 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun mov pc, lr 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun#ifdef CONFIG_CM_SPD_DETECT 104*4882a593Smuzhiyun /* Fast memory is available for the DRAM data 105*4882a593Smuzhiyun * - ensure it has been transferred, then summarize the data 106*4882a593Smuzhiyun * into a CM register 107*4882a593Smuzhiyun */ 108*4882a593Smuzhiyun.globl dram_query 109*4882a593Smuzhiyundram_query: 110*4882a593Smuzhiyun stmfd r13!,{r4-r6,lr} 111*4882a593Smuzhiyun /* set up SDRAM info */ 112*4882a593Smuzhiyun /* - based on example code from the CM User Guide */ 113*4882a593Smuzhiyun mov r0, #CM_BASE 114*4882a593Smuzhiyun 115*4882a593Smuzhiyunreadspdbit: 116*4882a593Smuzhiyun ldr r1, [r0, #OS_SDRAM] /* read the SDRAM register */ 117*4882a593Smuzhiyun and r1, r1, #0x20 /* mask SPD bit (5) */ 118*4882a593Smuzhiyun cmp r1, #0x20 /* test if set */ 119*4882a593Smuzhiyun bne readspdbit 120*4882a593Smuzhiyun 121*4882a593Smuzhiyunsetupsdram: 122*4882a593Smuzhiyun add r0, r0, #OS_SPD /* address the copy of the SDP data */ 123*4882a593Smuzhiyun ldrb r1, [r0, #3] /* number of row address lines */ 124*4882a593Smuzhiyun ldrb r2, [r0, #4] /* number of column address lines */ 125*4882a593Smuzhiyun ldrb r3, [r0, #5] /* number of banks */ 126*4882a593Smuzhiyun ldrb r4, [r0, #31] /* module bank density */ 127*4882a593Smuzhiyun mul r5, r4, r3 /* size of SDRAM (MB divided by 4) */ 128*4882a593Smuzhiyun mov r5, r5, ASL#2 /* size in MB */ 129*4882a593Smuzhiyun mov r0, #CM_BASE /* reload for later code */ 130*4882a593Smuzhiyun cmp r5, #0x10 /* is it 16MB? */ 131*4882a593Smuzhiyun bne not16 132*4882a593Smuzhiyun mov r6, #0x2 /* store size and CAS latency of 2 */ 133*4882a593Smuzhiyun b writesize 134*4882a593Smuzhiyun 135*4882a593Smuzhiyunnot16: 136*4882a593Smuzhiyun cmp r5, #0x20 /* is it 32MB? */ 137*4882a593Smuzhiyun bne not32 138*4882a593Smuzhiyun mov r6, #0x6 139*4882a593Smuzhiyun b writesize 140*4882a593Smuzhiyun 141*4882a593Smuzhiyunnot32: 142*4882a593Smuzhiyun cmp r5, #0x40 /* is it 64MB? */ 143*4882a593Smuzhiyun bne not64 144*4882a593Smuzhiyun mov r6, #0xa 145*4882a593Smuzhiyun b writesize 146*4882a593Smuzhiyun 147*4882a593Smuzhiyunnot64: 148*4882a593Smuzhiyun cmp r5, #0x80 /* is it 128MB? */ 149*4882a593Smuzhiyun bne not128 150*4882a593Smuzhiyun mov r6, #0xe 151*4882a593Smuzhiyun b writesize 152*4882a593Smuzhiyun 153*4882a593Smuzhiyunnot128: 154*4882a593Smuzhiyun /* if it is none of these sizes then it is either 256MB, or 155*4882a593Smuzhiyun * there is no SDRAM fitted so default to 256MB 156*4882a593Smuzhiyun */ 157*4882a593Smuzhiyun mov r6, #0x12 158*4882a593Smuzhiyun 159*4882a593Smuzhiyunwritesize: 160*4882a593Smuzhiyun mov r1, r1, ASL#8 /* row addr lines from SDRAM reg */ 161*4882a593Smuzhiyun orr r2, r1, r2, ASL#12 /* OR in column address lines */ 162*4882a593Smuzhiyun orr r3, r2, r3, ASL#16 /* OR in number of banks */ 163*4882a593Smuzhiyun orr r6, r6, r3 /* OR in size and CAS latency */ 164*4882a593Smuzhiyun str r6, [r0, #OS_SDRAM] /* store SDRAM parameters */ 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun#endif /* #ifdef CONFIG_CM_SPD_DETECT */ 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun ldmfd r13!,{r4-r6,pc} /* back to caller */ 169*4882a593Smuzhiyun 170*4882a593Smuzhiyun#ifdef CONFIG_CM_REMAP 171*4882a593Smuzhiyun /* CM remap bit is operational 172*4882a593Smuzhiyun * - use it to map writeable memory at 0x00000000, in place of flash 173*4882a593Smuzhiyun */ 174*4882a593Smuzhiyun.globl cm_remap 175*4882a593Smuzhiyuncm_remap: 176*4882a593Smuzhiyun stmfd r13!,{r4-r10,lr} 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun mov r0, #CM_BASE 179*4882a593Smuzhiyun ldr r1, [r0, #OS_CTRL] 180*4882a593Smuzhiyun orr r1, r1, #CMMASK_REMAP /* set remap and led bits */ 181*4882a593Smuzhiyun str r1, [r0, #OS_CTRL] 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun /* Now 0x00000000 is writeable, replace the vectors */ 184*4882a593Smuzhiyun ldr r0, =_start /* r0 <- start of vectors */ 185*4882a593Smuzhiyun add r2, r0, #64 /* r2 <- past vectors */ 186*4882a593Smuzhiyun sub r1,r1,r1 /* destination 0x00000000 */ 187*4882a593Smuzhiyun 188*4882a593Smuzhiyuncopy_vec: 189*4882a593Smuzhiyun ldmia r0!, {r3-r10} /* copy from source address [r0] */ 190*4882a593Smuzhiyun stmia r1!, {r3-r10} /* copy to target address [r1] */ 191*4882a593Smuzhiyun cmp r0, r2 /* until source end address [r2] */ 192*4882a593Smuzhiyun ble copy_vec 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun ldmfd r13!,{r4-r10,pc} /* back to caller */ 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun#endif /* #ifdef CONFIG_CM_REMAP */ 197