RAM 9.04 KB
Newer Older
Jeffrey Lee's avatar
Jeffrey Lee committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
; Copyright 2009 Castle Technology Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
init_ram
        ; Make sure all attached RAM is initialised
        ; Although x-loader will initialise some RAM for us, it might not necessarily use the best settings, and it might not initialise all the RAM that's available (e.g. CS1 on rev C beagleboard)
        ; This code roughly follows the sdrc_init()/dram_init() flow in u-boot

        LDR     v1, =SDRC_Regs
        ; CS0 setup:
        ; - If we're not running from SDRAM, (re)init CS0
        MOV     a1, pc
        CMP     a1, #CS0_SDRAM
        BGE     %FT10
        ; do_sdrc_init(CS0,EARLY_INIT)
        ; First we reset SDRC
        MOV     a1, #2
        STR     a1, [v1, #SDRC_SYSCONFIG] ; SOFTRESET
        MOV     a2, #12*1024*1024
20
        LDR     a1, [v1, #SDRC_SYSSTATUS]
        TST     a1, #1
        BNE     %FT30
        SUBS    a2, a2, #1
        BNE     %BT20
30
        MOV     a1, #0
        STR     a1, [v1, #SDRC_SYSCONFIG]
        ; Setup SDRC to ball mux. Or something.
        MOV     a1, #&100
        STR     a1, [v1, #SDRC_SHARING]
        ; Disable powerdown via CKE
        MOV     a1, #&81
        STR     a1, [v1, #SDRC_POWER_REG]
        ; Enable DLL, 90 degree phase
        MOV     a1, #&A
        STR     a1, [v1, #SDRC_DLLA_CTRL]
        ; Wait for lock (indefinitely?)
20
        LDR     a1, [v1, #SDRC_DLLA_STATUS]
        TST     a1, #4
        BEQ     %BT20

        ; Now initialise CS0
        LDR     a1, =&02584099 ; 128MB, etc.
        STR     a1, [v1, #SDRC_MCFG_0]
        LDR     a1, =&4E201
        STR     a1, [v1, #SDRC_RFR_CTRL_0]
        LDR     a1, =(21 :SHL: 27) :OR: (10 :SHL: 22) :OR: (7 :SHL: 18) :OR: (3 :SHL: 15) :OR: (3 :SHL: 12) :OR: (2 :SHL: 9) :OR: (3 :SHL: 6) :OR: 6
        STR     a1, [v1, #SDRC_ACTIM_CTRLA_0] ; 165MHz timings
        LDR     a1, =(1 :SHL: 12) :OR: 23 :OR: (5 :SHL: 8) :OR: (1 :SHL: 16)
        STR     a1, [v1, #SDRC_ACTIM_CTRLB_0]
        ; NOP, PRECHARGE, AUTOREFRESH, AUTOREFRESH sequence
        MOV     a1, #0
        STR     a1, [v1, #SDRC_MANUAL_0]
        MOV     a1, #1
        STR     a1, [v1, #SDRC_MANUAL_0]
        MOV     a1, #2
        STR     a1, [v1, #SDRC_MANUAL_0]
        STR     a1, [v1, #SDRC_MANUAL_0]
        ; CAS latency, burst length, etc.
        MOV     a1, #&32
        STR     a1, [v1, #SDRC_MR_0]
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
        ; Now check the setup
        ; This is the same technique as mem_ok() in u-boot
        LDR     a1, =CS0_SDRAM
        MOV     a2, #0
        LDR     a3, =&12345678
        STR     a2, [a1, #&400]
        STR     a3, [a1]
        STR     a2, [a1, #4]
        LDR     a2, [a1, #&400]
        LDR     a4, [a1]
        CMP     a2, #0
        CMPEQ   a3, a4
        BEQ     %FT10 ; It's good
        ; Else it's bad and we need to disable CS0
        MOV     a1, #0
        STR     a1, [v1, #SDRC_MCFG_0]
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
10
        ; Check if CS1 is active
        ; If not, and we're a rev C beagleboard, activate it
        LDR     a1, [v1, #SDRC_MCFG_1]
        LDR     a2, =&3FF00
        TST     a1, a2
        BNE     %FT10
        ; Beagleboard rev C check:
        ; Although the manual fails to mention it, apparently GPIO 171 will be low if we're on rev C
        ; Else we're rev A/B
        LDR     a2, =L4_GPIO6
        LDR     a1, [a2, #GPIO_OE]
        ORR     a1, a1, #1:SHL:11
        STR     a1, [a2, #GPIO_OE]
        ; Wait a bit just to make sure the input is up to date
        MOV     a1, #32768
5
        SUBS    a1, a1, #1
        BNE     %BT5
        LDR     a1, [a2, #GPIO_DATAIN]
        TST     a1, #1:SHL:11
        BNE     %FT10

        ; Make CS0 and CS1 contiguous, in case it helps RISC OS a bit (e.g. finding large areas of contiguous physical memory for IO)
        LDR     a1, [v1, #SDRC_MCFG_0]
        LDR     a2, =&3FF<<1
        ANDS    a1, a2, a1, LSR #7 ; CS0 size in MB
        BEQ     %FT5 ; If no CS0, just program offset of 0
        CMP     a1, #32
        MOVLT   a1, #32 ; Min 32MB offset if CS0 present
        ; Round up to power of two
        SUB     a2, a1, #1
        TST     a2, a1
        CLZNE   a2, a1
        MOVNE   a1, #1
        MOVNE   a1, a1, ROR a2
5
        AND     a2, a1, #&60 ; 32MB offset
        MOV     a1, a1, LSR #7 ; 128MB offset
        ORR     a1, a1, a2, LSL #3
        STR     a1, [v1, #SDRC_CS_CFG]

        ; Initialise CS1
        LDR     a1, =&02584099 ; 128MB, etc.
        STR     a1, [v1, #SDRC_MCFG_1]
        LDR     a1, =&4E201
        STR     a1, [v1, #SDRC_RFR_CTRL_1]
        LDR     a1, =(21 :SHL: 27) :OR: (10 :SHL: 22) :OR: (7 :SHL: 18) :OR: (3 :SHL: 15) :OR: (3 :SHL: 12) :OR: (2 :SHL: 9) :OR: (3 :SHL: 6) :OR: 6
        STR     a1, [v1, #SDRC_ACTIM_CTRLA_1] ; 165MHz timings
        LDR     a1, =(1 :SHL: 12) :OR: 23 :OR: (5 :SHL: 8) :OR: (1 :SHL: 16)
        STR     a1, [v1, #SDRC_ACTIM_CTRLB_1]
        ; NOP, PRECHARGE, AUTOREFRESH, AUTOREFRESH sequence
        MOV     a1, #0
        STR     a1, [v1, #SDRC_MANUAL_1]
        MOV     a1, #1
        STR     a1, [v1, #SDRC_MANUAL_1]
        MOV     a1, #2
        STR     a1, [v1, #SDRC_MANUAL_1]
        STR     a1, [v1, #SDRC_MANUAL_1]
        ; CAS latency, burst length, etc.
        MOV     a1, #&32
        STR     a1, [v1, #SDRC_MR_1]
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
        ; Now check the setup
        LDR     a1, =CS0_SDRAM
        LDR     a4, [v1, #SDRC_CS_CFG]
        AND     a3, a4, #7 ; Offset in 128MB units
        ADD     a1, a1, a3, LSL #20+7
        AND     a3, a4, #&300 ; Offset in 32MB units
        ADD     a1, a1, a3, LSL #20+5-8 ; a1 = CS1 start
        MOV     a2, #0
        LDR     a3, =&12345678
        STR     a2, [a1, #&400]
        STR     a3, [a1]
        STR     a2, [a1, #4]
        LDR     a2, [a1, #&400]
        LDR     a4, [a1]
        CMP     a2, #0
        CMPEQ   a3, a4
        BEQ     %FT10 ; It's good
        ; Else it's bad and we need to disable CS1
        MOV     a1, #0
        STR     a1, [v1, #SDRC_MCFG_1]
173 174 175 176 177 178
10
        ; Done!
        MOV     pc, lr



Jeffrey Lee's avatar
Jeffrey Lee committed
179 180 181 182 183 184 185
; a1 <= Highest physical address in RAM +1
get_end_of_ram
        LDR     v1, =SDRC_Regs
        LDR     a3, [v1, #SDRC_MCFG_1]
        LDR     a2, =&3FF00<<13
        ANDS    a3, a2, a3, LSL #13
        BEQ     %FT10
186
        LDR     a2, =CS0_SDRAM
Jeffrey Lee's avatar
Jeffrey Lee committed
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
        LDR     a4, [v1, #SDRC_CS_CFG]
        AND     v2, a4, #7 ; Offset in 128MB units
        ADD     a2, a2, v2, LSL #20+7
        AND     v2, a4, #&300 ; Offset in 32MB units
        ADD     a2, a2, v2, LSL #20+5-8
        ADD     a1, a3, a2
        MOV     pc, lr
10
        ; No RAM in CS1; therefore must be in CS0
        LDR     a3, [v1, #SDRC_MCFG_0]
        LDR     a2, =&3FF00<<13
        AND     a3, a2, a3, LSL #13 ; Get CS0 RAM size
        LDR     a2, =CS0_SDRAM
        ADD     a1, a3, a2
        MOV     pc, lr


204

Jeffrey Lee's avatar
Jeffrey Lee committed
205 206
clear_ram
        ; Clear everything up to a1
207
        ; This relies on the clear areas being multiples of 128 bytes in length
Jeffrey Lee's avatar
Jeffrey Lee committed
208 209 210 211 212 213 214 215 216 217 218
        MOV     v2, a1
        LDR     v1, =SDRC_Regs
        LDR     a3, [v1, #SDRC_MCFG_0]
        LDR     a2, =&3FF00<<13
        ANDS    a3, a2, a3, LSL #13 ; Get CS0 RAM size
        BEQ     %FT10
        LDR     a2, =CS0_SDRAM
        SUB     a1, v2, a2
        CMP     a1, a3
        MOVGT   a1, a3 ; Work out how much we're meant to be clearing
        MOV     a3, #0
219 220 221 222 223 224 225
        MOV     a4, #0
        MOV     v1, #0
        MOV     v3, #0
        MOV     v4, #0
        MOV     v5, #0
        MOV     sp, #0
        MOV     ip, #0
Jeffrey Lee's avatar
Jeffrey Lee committed
226
20
Jeffrey Lee's avatar
Jeffrey Lee committed
227 228 229 230
        STMIA   a2!,{a3,a4,v1,v3,v4,v5,sp,ip} ; 32 bytes
        STMIA   a2!,{a3,a4,v1,v3,v4,v5,sp,ip} ; 64 bytes
        STMIA   a2!,{a3,a4,v1,v3,v4,v5,sp,ip} ; 96 bytes
        STMIA   a2!,{a3,a4,v1,v3,v4,v5,sp,ip} ; 128 bytes
231
        SUBS    a1, a1, #128
Jeffrey Lee's avatar
Jeffrey Lee committed
232 233
        BGT     %BT20
10
234
        LDR     v1, =SDRC_Regs
Jeffrey Lee's avatar
Jeffrey Lee committed
235 236 237 238
        LDR     a3, [v1, #SDRC_MCFG_1]
        LDR     a2, =&3FF00<<13
        ANDS    a3, a2, a3, LSL #13
        BEQ     %FT30
239
        LDR     a2, =CS0_SDRAM
Jeffrey Lee's avatar
Jeffrey Lee committed
240
        LDR     a4, [v1, #SDRC_CS_CFG]
241 242 243 244
        AND     v3, a4, #7 ; Offset in 128MB units
        ADD     a2, a2, v3, LSL #20+7
        AND     v3, a4, #&300 ; Offset in 32MB units
        ADD     a2, a2, v3, LSL #20+5-8
Jeffrey Lee's avatar
Jeffrey Lee committed
245 246 247 248
        SUB     a1, v2, a2
        CMP     a1, a3
        MOVGT   a1, a3 ; Work out how much we're meant to be clearing
        MOV     a3, #0
249 250 251 252 253 254 255
        MOV     a4, #0
        MOV     v1, #0
        MOV     v3, #0
        MOV     v4, #0
        MOV     v5, #0
        MOV     sp, #0
        MOV     ip, #0
Jeffrey Lee's avatar
Jeffrey Lee committed
256
40
Jeffrey Lee's avatar
Jeffrey Lee committed
257 258 259 260
        STMIA   a2!,{a3,a4,v1,v3,v4,v5,sp,ip} ; 32 bytes
        STMIA   a2!,{a3,a4,v1,v3,v4,v5,sp,ip} ; 64 bytes
        STMIA   a2!,{a3,a4,v1,v3,v4,v5,sp,ip} ; 96 bytes
        STMIA   a2!,{a3,a4,v1,v3,v4,v5,sp,ip} ; 128 bytes
261
        SUBS    a1, a1, #128
Jeffrey Lee's avatar
Jeffrey Lee committed
262 263 264 265 266
        BGT     %BT40
30
        MOV     pc, lr

        END