|
|
1.1 root 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)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.