Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / board-js2x / slof / u4-mem.fs
1 \ *****************************************************************************
2 \ * Copyright (c) 2004, 2008 IBM Corporation
3 \ * All rights reserved.
4 \ * This program and the accompanying materials
5 \ * are made available under the terms of the BSD License
6 \ * which accompanies this distribution, and is available at
7 \ * http://www.opensource.org/licenses/bsd-license.php
8 \ *
9 \ * Contributors:
10 \ *     IBM Corporation - initial implementation
11 \ ****************************************************************************/
12
13
14 \ U4 DDR2 memory controller.
15
16 cr .( Setting up memory controller...)
17
18
19 \ First, I2C access to the SPDs.
20
21 : >i2c  f8001000 + ;
22 : i2c@  >i2c rl@ ;
23 : i2c!  >i2c rl! ;
24
25 : .i2c  80 0 DO i i2c@ . 10 +LOOP ;
26
27 : i2c-addr ( addr -- )  50 i2c!  2 10 i2c!  BEGIN 30 i2c@ 2 and UNTIL ;
28 : i2c-addr-subaddr ( addr suba -- )  60 i2c! i2c-addr ;
29 : i2c-stop ( -- )  BEGIN 30 i2c@ dup 30 i2c! 4 and UNTIL ;
30 : i2c-nak? ( -- failed? )  20 i2c@ 2 and 0= dup IF i2c-stop THEN ;
31 : i2c-short? ( -- failed? )  30 i2c@ 4 and 0<> dup IF 0 10 i2c! i2c-stop THEN ;
32 : i2c-aak-if-more ( n -- )  1 <> 1 and 10 i2c! ;
33
34 : i2c-sub-read ( buf len addr suba -- error? )
35   c 0 i2c!  >r 1 or r> i2c-addr-subaddr  i2c-nak? IF 2drop true EXIT THEN
36   dup i2c-aak-if-more  2 30 i2c!
37   BEGIN
38   30 i2c@ 1 and IF
39     1- >r 70 i2c@ over c! char+ r>
40     dup 0= IF i2c-stop 2drop false EXIT THEN
41     dup i2c-aak-if-more 1 30 i2c! THEN
42   i2c-short? IF 2drop true EXIT THEN
43   AGAIN ;
44
45
46 \ What slots are filled with working memory (bitmask).
47
48 f VALUE dimms-valid
49 : dimm-invalid  1 swap lshift invert dimms-valid and to dimms-valid ;
50 : dimm-invalid  dup dimm-invalid 2 xor dimm-invalid ; \ DIMMs are paired
51 : dimm-valid?  1 swap lshift dimms-valid and ;
52 : dimm(  +comp postpone 4 postpone 0 postpone DO
53                postpone i postpone dimm-valid? postpone IF ; immediate
54 : )dimm  postpone THEN postpone LOOP -comp ; immediate
55
56
57 \ The data from the SPDs.
58
59 CREATE spds 100 allot
60 : spd@ ( dimm# off -- value ) swap 40 * + spds + c@ ;
61
62 CREATE addresses a0 c, a4 c, a2 c, a6 c,
63 dimm( spds i 40 * + 40 addresses i + c@ 0 i2c-sub-read IF i dimm-invalid THEN )dimm
64
65
66 \ Accessors.
67
68 : spd>rows  3 spd@ ;
69 : spd>cols  4 spd@ ;
70 : spd>ranks 5 spd@ 7 and 1+ ;
71 : spd>width d spd@ ;
72 : spd>banks 11 spd@ ;
73 : spd>cas   12 spd@ ; \ bit mask of allowable CAS latencies
74 : spd>trp   1b spd@ ; \ in units of 0.25 ns
75 : spd>trrd  1c spd@ ; \ in units of 0.25 ns
76 : spd>trcd  1d spd@ ; \ in units of 0.25 ns
77 : spd>tras  1e spd@ ; \ in units of 1 ns
78 : spd>twr   24 spd@ ; \ in units of 0.25 ns
79 : spd>twtr  25 spd@ ; \ in units of 0.25 ns
80 : spd>trtp  26 spd@ ; \ in units of 0.25 ns
81 : spd>trc   29 spd@ ; \ in units of 1 ns  XXX: should also look at byte 28
82 : spd>trfc  2a spd@ ; \ in units of 1 ns  XXX: should also look at byte 28
83
84 cr .( rows cols ranks width banks trp trrd trcd tras twr twtr trtp trc trfc)
85 cr .( =====================================================================)
86 decimal
87 dimm( cr
88 i spd>rows  4 .r  i spd>cols  5 .r  i spd>ranks 6 .r  i spd>width 6 .r
89 i spd>banks 6 .r  i spd>trp   4 .r  i spd>trrd  5 .r  i spd>trcd  5 .r
90 i spd>tras  5 .r  i spd>twr   4 .r  i spd>twtr  5 .r  i spd>trtp  5 .r
91 i spd>trc   4 .r  i spd>trfc  5 .r
92 )dimm
93 hex
94
95 ff dimm( i spd>cas and )dimm CONSTANT cl-supported
96 : max-cl  -1 swap 8 0 DO dup 1 and IF nip i swap THEN u2/ LOOP drop ;
97 cl-supported max-cl VALUE cl
98
99 : tck>60*ns dup f and swap 4 rshift a * over + 6 * swap CASE
100             a OF 2d - ENDOF b OF 2e - ENDOF c OF 20 - ENDOF d OF 21 - ENDOF
101             ENDCASE ;
102 : cl>tck  0 spd>cas max-cl swap -
103           CASE 0 OF 9 ENDOF 1 OF 17 ENDOF 2 OF 19 ENDOF
104           true ABORT" No supported CAS latency for this DIMM" ENDCASE
105           0 swap spd@ tck>60*ns ;
106
107 : spd>min-tck  dup spd>cas max-cl cl -
108                CASE 0 OF 9 ENDOF 1 OF 17 ENDOF 2 OF 19 ENDOF
109                true ABORT" No supported CAS latency for this DIMM" ENDCASE
110                spd@ tck>60*ns ;
111 : spd>max-tck  2b spd@ tck>60*ns ;
112
113 : .tck  base @ >r decimal dup d# 60 / 0 .r [char] . emit
114         d# 60 mod d# 1000 * d# 60 / 3 0.r ." ns" r> base ! ;
115
116 cr .( CAS latencies supported: )
117 8 0 DO cl-supported 1 i lshift and IF i . THEN LOOP
118
119 \ Find the lowest CL at the highest tCK.
120 8 0 DO cl-supported 1 i lshift and IF cl cl>tck i cl>tck = IF
121        i to cl LEAVE THEN THEN LOOP
122
123 .( -- using ) cl .
124
125
126 0 dimm( i spd>min-tck max )dimm  CONSTANT tck
127 dimm( i spd>max-tck tck < IF i dimm-invalid THEN )dimm
128 cr .( tCK is ) tck .tck
129
130
131 0 CONSTANT al
132 cl al + CONSTANT rl
133 rl 1- CONSTANT wl
134
135 : //  dup >r 1- + r> / ; \ round up
136 0 spd>tras d# 60 * tck // CONSTANT tras
137 0 spd>trtp d# 15 * tck // CONSTANT trtp
138 0 spd>twr  d# 15 * tck // CONSTANT twr
139 0 spd>trp  d# 15 * tck // CONSTANT trp
140 0 spd>trrd d# 15 * tck // CONSTANT trrd
141 0 spd>trrd d# 60 * tck // CONSTANT 4*trrd
142 0 spd>trcd d# 15 * tck // CONSTANT trcd
143 0 spd>trc  d# 60 * tck // CONSTANT trc
144 0 spd>twtr d# 15 * tck // CONSTANT twtr
145
146 : spd>memmd
147   >r r@ spd>rows r@ spd>cols +
148   r@ spd>banks 2log + 4 * r> spd>width 2log 3 * + 6c - ;
149 : dimm-group-size ( dimm# -- size )
150   >r r@ spd>rows r@ spd>cols + 1 swap lshift
151   r@ spd>banks * r> spd>ranks * 10 * ;
152 VARIABLE start-address
153 VARIABLE was-prev-big
154 : assign-dimm-group ( dimm# -- config-value )
155   dup dimm-valid? 0= IF drop 0 EXIT THEN
156   \ MemMd, enable, single-sided or not
157   dup spd>memmd c lshift 1 or over spd>ranks 1 = IF 2 or THEN 
158 cr ." ---> " dup .
159 >r
160   dimm-group-size start-address @ 2dup + rot ( start end size )
161   80000000 > IF
162     dup 1000000000 < IF dup 4 rshift ELSE 08000000 THEN r> or >r \ Add2G
163     over 0<>        IF over c rshift ELSE 00080000 THEN r> or >r \ Sub2G
164     was-prev-big on
165   ELSE
166     was-prev-big @ IF 80000000 + swap 80000000 + swap THEN r> 08080000 or >r
167     was-prev-big off
168   THEN
169   swap 18 rshift r> or >r \ start address
170   dup 80000000 = IF drop 100000000 THEN start-address ! r> ;
171
172
173 \ Now set the frequency in the memory controller
174 d# 1800 tck / 4 - 12 lshift 33c or f8000800 rl!
175 f8000860 rl@ 80000000 or f8000860 rl!  10000 0 DO LOOP
176
177 : mc!  f8002000 + rl! ;
178 : mc@  f8002000 + rl@ ;
179
180
181 \ memory timing regs (state machine)
182
183 tras 2-
184 5 lshift al trtp + 2- or
185 5 lshift wl twr + or
186 5 lshift trp 2- or
187 5 lshift trp 2- 0 spd>banks 8 = IF 1+ THEN or
188 7 lshift 030 mc!
189
190 al trtp + trp + 2-
191 5 lshift cl al + twr + trp + 1- or
192 5 lshift trrd 2- or
193 5 lshift trc 2- or
194 5 lshift trcd 2- or
195 5 lshift 4*trrd or
196 2 lshift 040 mc!
197
198 0
199 5 lshift 1 or
200 5 lshift 1 or
201 5 lshift cl 1- twtr + or
202 5 lshift 1 or
203 5 lshift 1 or
204 2 lshift 050 mc!
205
206 0
207 5 lshift 1 or
208 5 lshift 1 or
209 5 lshift 2 or
210 5 lshift 2 or
211 5 lshift 2 or
212 2 lshift 060 mc! \ XXX joerg has different setting
213
214 cl 3 = IF 30801800 ( 30800d00 ) 070 mc! \ XXX memory refresh
215 ELSE 41002000 070 mc! THEN
216
217 \ memory size regs
218
219 1 dimm-group-size 0 dimm-group-size > 1 0 rot IF swap THEN \ biggest first
220 assign-dimm-group 200 mc!
221 assign-dimm-group 210 mc!
222 0 220 mc! 0 230 mc!
223
224
225
226
227
228 \ arbiter tunables
229 \ 40041040 270 mc!
230 04041040 270 mc!
231 50000000 280 mc!
232 \ a0a00000 290 mc! \ a0000000 might be faster
233 00000000 290 mc!
234 \ 20020820 2a0 mc!
235 04020822 2a0 mc!
236 00000000 2b0 mc!
237 \ 30413cc7 2c0 mc! \ have to calculate the low five bits
238 30413dc5 2c0 mc!
239 \ cl 3 = IF 76000050 2d0 mc!  70000000 2e0 mc! ELSE
240 cl 3 = IF 75000050 2d0 mc!  70000000 2e0 mc! ELSE
241     b8002080 2d0 mc!  b0000000 2e0 mc! THEN
242 \ Should test for something else really
243
244
245
246 cl 3 = IF 00006000 890 mc!  00006000 8a0 mc! ELSE
247           00006500 890 mc!  00006500 8a0 mc! THEN
248
249 cl 3 = IF 1e008a8a ELSE 31000000 THEN
250 dup 800 mc! dup 810 mc! dup 820 mc! dup 830 mc!
251 dup 900 mc! dup 910 mc! dup 920 mc! dup 930 mc! dup 980 mc!
252 dup a00 mc! dup a10 mc! dup a20 mc! dup a30 mc!
253 dup b00 mc! dup b10 mc! dup b20 mc! dup b30 mc!     b80 mc!
254
255 \ 0 8d0 mc!  0 9d0 mc!  0 ad0 mc!  0 bd0 mc!
256 61630000 8d0 mc!
257 61630000 9d0 mc!
258 52510000 ad0 mc!
259 434e0000 bd0 mc!
260
261 a0200400 100 mc!
262 80020000 110 mc!
263 80030000 120 mc!
264 80010404 130 mc!
265 cl 3 = IF
266 8000153a 140 mc! ELSE
267 8000174a 140 mc! THEN
268 a0200400 150 mc!
269 \ 92000000 160 mc!
270 \ 92000000 170 mc!
271 \ 91300000 160 mc!
272 \ 91300000 170 mc!
273 91800000 160 mc!
274 91800000 170 mc!
275 cl 3 = IF
276 8ff0143a 180 mc! ELSE
277 8ff0164a 180 mc! THEN
278 80010784 190 mc!
279 80010404 1a0 mc!
280 0 1b0 mc!  0 1c0 mc!  0 1d0 mc!  0 1e0 mc!  0 1f0 mc!
281
282 cl 3 = IF
283 143a 0c0 mc! ELSE
284 164a 0c0 mc! THEN
285 0404 0d0 mc!
286
287 \ after this point, setup is common for all speeds and sizes of dimms (sort of)
288
289 60000000 3a0 mc!
290
291 0 840 mc!  0 850 mc!  0 860 mc!  0 870 mc!
292 0 940 mc!  0 950 mc!  0 960 mc!  0 970 mc!  0 990 mc!
293 0 a40 mc!  0 a50 mc!  0 a60 mc!  0 a70 mc!
294 0 b40 mc!  0 b50 mc!  0 b60 mc!  0 b70 mc!  0 b90 mc!
295
296 0 880 mc!
297
298 001a4000 9a0 mc!
299
300 84800000 500 mc!
301
302 10000 0 DO LOOP
303
304 80000000 b0 mc!  BEGIN b0 mc@ 40000000 and UNTIL
305
306 0 300 mc!  0 310 mc!
307
308 80000000 440 mc!
309 0 410 mc!  27fffffc 420 mc!
310 fedcba98 430 mc!
311 c0000000 400 mc!  BEGIN 400 mc@ c0000000 and 0= UNTIL
312
313 cr .( mem done)