dram_init.S
3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
/*
* DRAM/SDRAM initialization - alter with care
* This file is intended to be included from other assembler files
*
* Note: This file may not modify r9 because r9 is used to carry
* information from the decompresser to the kernel
*
* Copyright (C) 2000-2012 Axis Communications AB
*
*/
/* Just to be certain the config file is included, we include it here
* explicitly instead of depending on it being included in the file that
* uses this code.
*/
;; WARNING! The registers r8 and r9 are used as parameters carrying
;; information from the decompressor (if the kernel was compressed).
;; They should not be used in the code below.
move.d CONFIG_ETRAX_DEF_R_WAITSTATES, $r0
move.d $r0, [R_WAITSTATES]
move.d CONFIG_ETRAX_DEF_R_BUS_CONFIG, $r0
move.d $r0, [R_BUS_CONFIG]
#ifndef CONFIG_ETRAX_SDRAM
move.d CONFIG_ETRAX_DEF_R_DRAM_CONFIG, $r0
move.d $r0, [R_DRAM_CONFIG]
move.d CONFIG_ETRAX_DEF_R_DRAM_TIMING, $r0
move.d $r0, [R_DRAM_TIMING]
#else
;; Samsung SDRAMs seem to require to be initialized twice to work properly.
moveq 2, $r6
_sdram_init:
; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization
; Bank configuration
move.d CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, $r0
move.d $r0, [R_SDRAM_CONFIG]
; Calculate value of mrs_data
; CAS latency = 2 && bus_width = 32 => 0x40
; CAS latency = 3 && bus_width = 32 => 0x60
; CAS latency = 2 && bus_width = 16 => 0x20
; CAS latency = 3 && bus_width = 16 => 0x30
; Check if value is already supplied in kernel config
move.d CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r2
and.d 0x00ff0000, $r2
bne _set_timing
lsrq 16, $r2
move.d 0x40, $r2 ; Assume 32 bits and CAS latency = 2
move.d CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1
move.d $r1, $r3
and.d 0x03, $r1 ; Get CAS latency
and.d 0x1000, $r3 ; 50 or 100 MHz?
beq _speed_50
nop
_speed_100:
cmp.d 0x00, $r1 ; CAS latency = 2?
beq _bw_check
nop
or.d 0x20, $r2 ; CAS latency = 3
ba _bw_check
nop
_speed_50:
cmp.d 0x01, $r1 ; CAS latency = 2?
beq _bw_check
nop
or.d 0x20, $r2 ; CAS latency = 3
_bw_check:
move.d CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, $r1
and.d 0x800000, $r1 ; DRAM width is bit 23
bne _set_timing
nop
lsrq 1, $r2 ; 16 bits. Shift down value.
; Set timing parameters. Starts master clock
_set_timing:
move.d CONFIG_ETRAX_DEF_R_SDRAM_TIMING, $r1
and.d 0x8000f9ff, $r1 ; Make sure mrs data and command is 0
or.d 0x80000000, $r1 ; Make sure sdram enable bit is set
move.d $r1, $r5
or.d 0x0000c000, $r1 ; ref = disable
lslq 16, $r2 ; mrs data starts at bit 16
or.d $r2, $r1
move.d $r1, [R_SDRAM_TIMING]
; Wait 200us
move.d 10000, $r2
1: bne 1b
subq 1, $r2
; Issue initialization command sequence
move.d _sdram_commands_start, $r2
and.d 0x000fffff, $r2 ; Make sure commands are read from flash
move.d _sdram_commands_end, $r3
and.d 0x000fffff, $r3
1: clear.d $r4
move.b [$r2+], $r4
lslq 9, $r4 ; Command starts at bit 9
or.d $r1, $r4
move.d $r4, [R_SDRAM_TIMING]
nop ; Wait five nop cycles between each command
nop
nop
nop
nop
cmp.d $r2, $r3
bne 1b
nop
move.d $r5, [R_SDRAM_TIMING]
subq 1, $r6
bne _sdram_init
nop
ba _sdram_commands_end
nop
_sdram_commands_start:
.byte 3 ; Precharge
.byte 0 ; nop
.byte 2 ; refresh
.byte 0 ; nop
.byte 2 ; refresh
.byte 0 ; nop
.byte 2 ; refresh
.byte 0 ; nop
.byte 2 ; refresh
.byte 0 ; nop
.byte 2 ; refresh
.byte 0 ; nop
.byte 2 ; refresh
.byte 0 ; nop
.byte 2 ; refresh
.byte 0 ; nop
.byte 2 ; refresh
.byte 0 ; nop
.byte 1 ; mrs
.byte 0 ; nop
_sdram_commands_end:
#endif